Skip to content

Commit f0bd4e5

Browse files
mohitpubnubarepubnub-release-bot
authored
eventEngine (#334)
* feat: cucumber refactor * feat: add more steps * feat: current progress * refactor event-engine(from draft PR) * event-engine: update to latest description, added some missing transitions * prettier! * take: fix hanging tests due to retry intro * update as per latest event engine specs * * cucumber tsflow * prettier! * fix: test and version mismatch from branch merge * fix: version * add: reconnection configuration * lint/prettier * fix: test. destroy() not required * fix: naming convention and removed unnecessary effect dispatch * WIP: presence event engine * organised files and directories for presence * fix: paths * fix: lint * presence and subscribe event engine states * event engine effects and events * retry policy configuration * event engines tests * updated stateless utilities * updated PubNub with configurations * lib and dist * take-1 fix lint * fix: elint config * sync: package-lock * fix: package-lock * WIP take-1(non-status events): Listener compatibility with eventEngine * take-2: (presence) listener structs backward compatibility. * lib and dist * lint * event engine: naming, missing transitions, handling `reconnect` and `restore` all applicable states, removed old definitions for events * event engine: receiving state as per specifications * refined naming for event engine events and effects * retryConfiguration behaviour updates * presence eventengine: removed unnecessary emitStatus events as per specifications * config naming convention, eventengine initialisation updates as per new updated naming conventions * updated tests * dist, lib and lint fixes * package-lock dependabot suggestion, fix test * removed duplicate file * fix: prevent duplicate listener to be added. * dist/lib files * retry delay can be override by retry after value * handled cursor across the states * manage cursor from event struct * dist and lib * refactor: reconnect event handling * getSubscribedChannels and channelGroups binding when eventEngine is enabled * refactor: retry policy delay calculation * handshake* states: handling cursor value across state and defaulting to 0 for region when context/event has undefined * receiv* states: handling cursor across states * lib/dist * addressed review comments : handling cursor value from context from handshake and receiveFailed * revert test file changes * fix: lint * sync package-lock * removed flow_interfaces reference * PubNub SDK v7.5.0 release. --------- Co-authored-by: Artur Wojciechowski <[email protected]> Co-authored-by: PubNub Release Bot <[email protected]>
1 parent 76bc504 commit f0bd4e5

File tree

194 files changed

+6349
-8834
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

194 files changed

+6349
-8834
lines changed

.eslintrc.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ module.exports = {
1717
'class-methods-use-this': 0,
1818
'no-prototype-builtins': 1,
1919
'prefer-destructuring': 0,
20+
'no-unused-vars': 0,
21+
'@typescript-eslint/no-unused-vars': 0,
2022
'@typescript-eslint/explicit-module-boundary-types': 'off',
2123
},
2224
};

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ dist/titanium/stats.json
1515
dist/contract
1616
dist/cucumber
1717
upload
18+
test/specs
1819

1920
# GitHub Actions #
2021
##################

.pubnub.yml

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,14 @@
11
---
22
changelog:
3+
- date: 2024-01-16
4+
version: v7.5.0
5+
changes:
6+
- type: feature
7+
text: "Added `enableEventEngine`, `maintainPresenceState` flags and `retryConfiguration` for retry policy configuration."
8+
- type: bug
9+
text: "Fixes issue of allowing duplicate listener registration."
10+
- type: bug
11+
text: "Fixes file name conflict in lib directory."
312
- date: 2023-11-28
413
version: v7.4.5
514
changes:
@@ -929,7 +938,7 @@ supported-platforms:
929938
- 'Ubuntu 14.04 and up'
930939
- 'Windows 7 and up'
931940
version: 'Pubnub Javascript for Node'
932-
version: '7.4.5'
941+
version: '7.5.0'
933942
sdks:
934943
- full-name: PubNub Javascript SDK
935944
short-name: Javascript
@@ -945,7 +954,7 @@ sdks:
945954
- distribution-type: source
946955
distribution-repository: GitHub release
947956
package-name: pubnub.js
948-
location: https://github.com/pubnub/javascript/archive/refs/tags/v7.4.5.zip
957+
location: https://github.com/pubnub/javascript/archive/refs/tags/v7.5.0.zip
949958
requires:
950959
- name: 'agentkeepalive'
951960
min-version: '3.5.2'
@@ -1616,7 +1625,7 @@ sdks:
16161625
- distribution-type: library
16171626
distribution-repository: GitHub release
16181627
package-name: pubnub.js
1619-
location: https://github.com/pubnub/javascript/releases/download/v7.4.5/pubnub.7.4.5.js
1628+
location: https://github.com/pubnub/javascript/releases/download/v7.5.0/pubnub.7.5.0.js
16201629
requires:
16211630
- name: 'agentkeepalive'
16221631
min-version: '3.5.2'

CHANGELOG.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,13 @@
1+
## v7.5.0
2+
January 16 2024
3+
4+
#### Added
5+
- Added `enableEventEngine`, `maintainPresenceState` flags and `retryConfiguration` for retry policy configuration.
6+
7+
#### Fixed
8+
- Fixes issue of allowing duplicate listener registration.
9+
- Fixes file name conflict in lib directory. Fixed the following issues reported by [@priyanshu102002](https://github.com/priyanshu102002): [#355](https://github.com/pubnub/javascript/issues/355).
10+
111
## v7.4.5
212
November 28 2023
313

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,8 @@ Watch [Getting Started with PubNub JS SDK](https://app.dashcam.io/replay/64ee0d2
2828
npm install pubnub
2929
```
3030
* or download one of our builds from our CDN:
31-
* https://cdn.pubnub.com/sdk/javascript/pubnub.7.4.5.js
32-
* https://cdn.pubnub.com/sdk/javascript/pubnub.7.4.5.min.js
31+
* https://cdn.pubnub.com/sdk/javascript/pubnub.7.5.0.js
32+
* https://cdn.pubnub.com/sdk/javascript/pubnub.7.5.0.min.js
3333
3434
2. Configure your keys:
3535

cucumber.js

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
module.exports = {
2+
default: [
3+
'test/specs/features/**/*.feature',
4+
'--require test/contract/setup.js',
5+
'--require test/contract/definitions/**/*.ts',
6+
'--require test/contract/shared/**/*.ts',
7+
'--format summary',
8+
'--format progress-bar',
9+
// '--format @cucumber/pretty-formatter',
10+
'--publish-quiet',
11+
].join(' '),
12+
};

dist/web/pubnub.js

Lines changed: 1132 additions & 139 deletions
Large diffs are not rendered by default.

dist/web/pubnub.min.js

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

lib/core/components/_endpoint.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
"use strict";
2+
Object.defineProperty(exports, "__esModule", { value: true });

lib/core/components/config.js

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ var makeDefaultOrigins = function () { return Array.from({ length: 20 }, functio
1212
var default_1 = /** @class */ (function () {
1313
function default_1(_a) {
1414
var setup = _a.setup;
15-
var _b, _c, _d;
15+
var _b, _c, _d, _e;
1616
this._PNSDKSuffix = {};
1717
this.instanceId = "pn-".concat(uuid_1.default.createUUID());
1818
this.secretKey = setup.secretKey || setup.secret_key;
@@ -40,8 +40,8 @@ var default_1 = /** @class */ (function () {
4040
this.customDecrypt = setup.customDecrypt;
4141
this.fileUploadPublishRetryLimit = (_b = setup.fileUploadPublishRetryLimit) !== null && _b !== void 0 ? _b : 5;
4242
this.useRandomIVs = (_c = setup.useRandomIVs) !== null && _c !== void 0 ? _c : true;
43-
// flag for beta subscribe feature enablement
44-
this.enableSubscribeBeta = (_d = setup.enableSubscribeBeta) !== null && _d !== void 0 ? _d : false;
43+
this.enableEventEngine = (_d = setup.enableEventEngine) !== null && _d !== void 0 ? _d : false;
44+
this.maintainPresenceState = (_e = setup.maintainPresenceState) !== null && _e !== void 0 ? _e : true;
4545
// if location config exist and we are in https, force secure to true.
4646
if (typeof location !== 'undefined' && location.protocol === 'https:') {
4747
this.secure = true;
@@ -53,6 +53,9 @@ var default_1 = /** @class */ (function () {
5353
this.useInstanceId = setup.useInstanceId || false;
5454
this.useRequestId = setup.useRequestId || false;
5555
this.requestMessageCountThreshold = setup.requestMessageCountThreshold;
56+
if (setup.retryConfiguration) {
57+
this._setRetryConfiguration(setup.retryConfiguration);
58+
}
5659
// set timeout to how long a transaction request will wait for the server (default 15 seconds)
5760
this.setTransactionTimeout(setup.transactionalRequestTimeout || 15 * 1000);
5861
// set timeout to how long a subscribe event loop will run (default 310 seconds)
@@ -177,7 +180,22 @@ var default_1 = /** @class */ (function () {
177180
return this;
178181
};
179182
default_1.prototype.getVersion = function () {
180-
return '7.4.5';
183+
return '7.5.0';
184+
};
185+
default_1.prototype._setRetryConfiguration = function (configuration) {
186+
if (configuration.minimumdelay < 2) {
187+
throw new Error('Minimum delay can not be set less than 2 seconds for retry');
188+
}
189+
if (configuration.maximumDelay > 150) {
190+
throw new Error('Maximum delay can not be set more than 150 seconds for retry');
191+
}
192+
if (configuration.maximumDelay && maximumRetry > 6) {
193+
throw new Error('Maximum retry for exponential retry policy can not be more than 6');
194+
}
195+
else if (configuration.maximumRetry > 10) {
196+
throw new Error('Maximum retry for linear retry policy can not be more than 10');
197+
}
198+
this.retryConfiguration = configuration;
181199
};
182200
default_1.prototype._addPnsdkSuffix = function (name, suffix) {
183201
this._PNSDKSuffix[name] = suffix;

lib/core/components/eventEmitter.js

Lines changed: 212 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,212 @@
1+
"use strict";
2+
var __assign = (this && this.__assign) || function () {
3+
__assign = Object.assign || function(t) {
4+
for (var s, i = 1, n = arguments.length; i < n; i++) {
5+
s = arguments[i];
6+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
7+
t[p] = s[p];
8+
}
9+
return t;
10+
};
11+
return __assign.apply(this, arguments);
12+
};
13+
var __rest = (this && this.__rest) || function (s, e) {
14+
var t = {};
15+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
16+
t[p] = s[p];
17+
if (s != null && typeof Object.getOwnPropertySymbols === "function")
18+
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
19+
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
20+
t[p[i]] = s[p[i]];
21+
}
22+
return t;
23+
};
24+
Object.defineProperty(exports, "__esModule", { value: true });
25+
var EventEmitter = /** @class */ (function () {
26+
function EventEmitter(_a) {
27+
var modules = _a.modules, listenerManager = _a.listenerManager, getFileUrl = _a.getFileUrl;
28+
this.modules = modules;
29+
this.listenerManager = listenerManager;
30+
this.getFileUrl = getFileUrl;
31+
if (modules.cryptoModule)
32+
this._decoder = new TextDecoder();
33+
}
34+
EventEmitter.prototype.emitEvent = function (e) {
35+
var channel = e.channel, publishMetaData = e.publishMetaData;
36+
var subscriptionMatch = e.subscriptionMatch;
37+
if (channel === subscriptionMatch) {
38+
subscriptionMatch = null;
39+
}
40+
if (e.channel.endsWith('-pnpres')) {
41+
var announce = {};
42+
announce.channel = null;
43+
announce.subscription = null;
44+
if (channel) {
45+
announce.channel = channel.substring(0, channel.lastIndexOf('-pnpres'));
46+
}
47+
if (subscriptionMatch) {
48+
announce.subscription = subscriptionMatch.substring(0, subscriptionMatch.lastIndexOf('-pnpres'));
49+
}
50+
announce.action = e.payload.action;
51+
announce.state = e.payload.data;
52+
announce.timetoken = publishMetaData.publishTimetoken;
53+
announce.occupancy = e.payload.occupancy;
54+
announce.uuid = e.payload.uuid;
55+
announce.timestamp = e.payload.timestamp;
56+
if (e.payload.join) {
57+
announce.join = e.payload.join;
58+
}
59+
if (e.payload.leave) {
60+
announce.leave = e.payload.leave;
61+
}
62+
if (e.payload.timeout) {
63+
announce.timeout = e.payload.timeout;
64+
}
65+
this.listenerManager.announcePresence(announce);
66+
}
67+
else if (e.messageType === 1) {
68+
var announce = {};
69+
announce.channel = null;
70+
announce.subscription = null;
71+
announce.channel = channel;
72+
announce.subscription = subscriptionMatch;
73+
announce.timetoken = publishMetaData.publishTimetoken;
74+
announce.publisher = e.issuingClientId;
75+
if (e.userMetadata) {
76+
announce.userMetadata = e.userMetadata;
77+
}
78+
announce.message = e.payload;
79+
this.listenerManager.announceSignal(announce);
80+
}
81+
else if (e.messageType === 2) {
82+
var announce = {};
83+
announce.channel = null;
84+
announce.subscription = null;
85+
announce.channel = channel;
86+
announce.subscription = subscriptionMatch;
87+
announce.timetoken = publishMetaData.publishTimetoken;
88+
announce.publisher = e.issuingClientId;
89+
if (e.userMetadata) {
90+
announce.userMetadata = e.userMetadata;
91+
}
92+
announce.message = {
93+
event: e.payload.event,
94+
type: e.payload.type,
95+
data: e.payload.data,
96+
};
97+
this.listenerManager.announceObjects(announce);
98+
if (e.payload.type === 'uuid') {
99+
var eventData = this._renameChannelField(announce);
100+
this.listenerManager.announceUser(__assign(__assign({}, eventData), { message: __assign(__assign({}, eventData.message), { event: this._renameEvent(eventData.message.event), type: 'user' }) }));
101+
}
102+
else if (message.payload.type === 'channel') {
103+
var eventData = this._renameChannelField(announce);
104+
this.listenerManager.announceSpace(__assign(__assign({}, eventData), { message: __assign(__assign({}, eventData.message), { event: this._renameEvent(eventData.message.event), type: 'space' }) }));
105+
}
106+
else if (message.payload.type === 'membership') {
107+
var eventData = this._renameChannelField(announce);
108+
var _a = eventData.message.data, user = _a.uuid, space = _a.channel, membershipData = __rest(_a, ["uuid", "channel"]);
109+
membershipData.user = user;
110+
membershipData.space = space;
111+
this.listenerManager.announceMembership(__assign(__assign({}, eventData), { message: __assign(__assign({}, eventData.message), { event: this._renameEvent(eventData.message.event), data: membershipData }) }));
112+
}
113+
}
114+
else if (e.messageType === 3) {
115+
var announce = {};
116+
announce.channel = channel;
117+
announce.subscription = subscriptionMatch;
118+
announce.timetoken = publishMetaData.publishTimetoken;
119+
announce.publisher = e.issuingClientId;
120+
announce.data = {
121+
messageTimetoken: e.payload.data.messageTimetoken,
122+
actionTimetoken: e.payload.data.actionTimetoken,
123+
type: e.payload.data.type,
124+
uuid: e.issuingClientId,
125+
value: e.payload.data.value,
126+
};
127+
announce.event = e.payload.event;
128+
this.listenerManager.announceMessageAction(announce);
129+
}
130+
else if (e.messageType === 4) {
131+
var announce = {};
132+
announce.channel = channel;
133+
announce.subscription = subscriptionMatch;
134+
announce.timetoken = publishMetaData.publishTimetoken;
135+
announce.publisher = e.issuingClientId;
136+
var msgPayload = e.payload;
137+
if (this.modules.cryptoModule) {
138+
var decryptedPayload = void 0;
139+
try {
140+
var decryptedData = this.modules.cryptoModule.decrypt(e.payload);
141+
decryptedPayload =
142+
decryptedData instanceof ArrayBuffer ? JSON.parse(this._decoder.decode(decryptedData)) : decryptedData;
143+
}
144+
catch (e) {
145+
decryptedPayload = null;
146+
announce.error = "Error while decrypting message content: ".concat(e.message);
147+
}
148+
if (decryptedPayload !== null) {
149+
msgPayload = decryptedPayload;
150+
}
151+
}
152+
if (e.userMetadata) {
153+
announce.userMetadata = e.userMetadata;
154+
}
155+
announce.message = msgPayload.message;
156+
announce.file = {
157+
id: msgPayload.file.id,
158+
name: msgPayload.file.name,
159+
url: this.getFileUrl({
160+
id: msgPayload.file.id,
161+
name: msgPayload.file.name,
162+
channel: channel,
163+
}),
164+
};
165+
this.listenerManager.announceFile(announce);
166+
}
167+
else {
168+
var announce = {};
169+
announce.channel = null;
170+
announce.subscription = null;
171+
announce.channel = channel;
172+
announce.subscription = subscriptionMatch;
173+
announce.timetoken = publishMetaData.publishTimetoken;
174+
announce.publisher = e.issuingClientId;
175+
if (e.userMetadata) {
176+
announce.userMetadata = e.userMetadata;
177+
}
178+
if (this.modules.cryptoModule) {
179+
var decryptedPayload = void 0;
180+
try {
181+
var decryptedData = this.modules.cryptoModule.decrypt(e.payload);
182+
decryptedPayload =
183+
decryptedData instanceof ArrayBuffer ? JSON.parse(this._decoder.decode(decryptedData)) : decryptedData;
184+
}
185+
catch (e) {
186+
decryptedPayload = null;
187+
announce.error = "Error while decrypting message content: ".concat(e.message);
188+
}
189+
if (decryptedPayload != null) {
190+
announce.message = decryptedPayload;
191+
}
192+
else {
193+
announce.message = e.payload;
194+
}
195+
}
196+
else {
197+
announce.message = e.payload;
198+
}
199+
this.listenerManager.announceMessage(announce);
200+
}
201+
};
202+
EventEmitter.prototype._renameEvent = function (e) {
203+
return e === 'set' ? 'updated' : 'removed';
204+
};
205+
EventEmitter.prototype._renameChannelField = function (announce) {
206+
var channel = announce.channel, eventData = __rest(announce, ["channel"]);
207+
eventData.spaceId = channel;
208+
return eventData;
209+
};
210+
return EventEmitter;
211+
}());
212+
exports.default = EventEmitter;

lib/core/components/listener_manager.js

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,11 @@ var default_1 = /** @class */ (function () {
88
function default_1() {
99
this._listeners = [];
1010
}
11-
default_1.prototype.addListener = function (newListeners) {
12-
this._listeners.push(newListeners);
11+
default_1.prototype.addListener = function (newListener) {
12+
if (this._listeners.includes(newListener)) {
13+
return;
14+
}
15+
this._listeners.push(newListener);
1316
};
1417
default_1.prototype.removeListener = function (deprecatedListener) {
1518
var newListeners = [];

lib/core/components/push_payload.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
"use strict";
2+
/* */
3+
/* eslint max-classes-per-file: ["error", 5] */
24
var __extends = (this && this.__extends) || (function () {
35
var extendStatics = function (d, b) {
46
extendStatics = Object.setPrototypeOf ||

lib/core/constants/categories.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,4 +20,7 @@ exports.default = {
2020
PNReconnectedCategory: 'PNReconnectedCategory',
2121
PNConnectedCategory: 'PNConnectedCategory',
2222
PNRequestMessageCountExceededCategory: 'PNRequestMessageCountExceededCategory',
23+
PNDisconnectedCategory: 'PNDisconnectedCategory',
24+
PNConnectionErrorCategory: 'PNConnectionErrorCategory',
25+
PNDisconnectedUnexpectedlyCategory: 'PNDisconnectedUnexpectedlyCategory',
2326
};

0 commit comments

Comments
 (0)