Skip to content

Commit f1397e8

Browse files
authored
Fix issue with presence events (#448)
fix(subscription-loop): fix issue with presence events Fix missing `heartbeat` and `leave` REST API calls when the event engine is enabled and `presenceTimeout` or `heartbeatInterval` not set.
1 parent c51bb05 commit f1397e8

File tree

25 files changed

+2365
-1839
lines changed

25 files changed

+2365
-1839
lines changed

.pubnub.yml

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
---
22
changelog:
3+
- date: 2025-03-31
4+
version: v9.3.2
5+
changes:
6+
- type: bug
7+
text: "Fix missing `heartbeat` and `leave` REST API calls when the event engine is enabled and `presenceTimeout` or `heartbeatInterval` not set."
38
- date: 2025-03-25
49
version: v9.3.1
510
changes:
@@ -1197,7 +1202,7 @@ supported-platforms:
11971202
- 'Ubuntu 14.04 and up'
11981203
- 'Windows 7 and up'
11991204
version: 'Pubnub Javascript for Node'
1200-
version: '9.3.1'
1205+
version: '9.3.2'
12011206
sdks:
12021207
- full-name: PubNub Javascript SDK
12031208
short-name: Javascript
@@ -1213,7 +1218,7 @@ sdks:
12131218
- distribution-type: source
12141219
distribution-repository: GitHub release
12151220
package-name: pubnub.js
1216-
location: https://github.com/pubnub/javascript/archive/refs/tags/v9.3.1.zip
1221+
location: https://github.com/pubnub/javascript/archive/refs/tags/v9.3.2.zip
12171222
requires:
12181223
- name: 'agentkeepalive'
12191224
min-version: '3.5.2'
@@ -1884,7 +1889,7 @@ sdks:
18841889
- distribution-type: library
18851890
distribution-repository: GitHub release
18861891
package-name: pubnub.js
1887-
location: https://github.com/pubnub/javascript/releases/download/v9.3.1/pubnub.9.3.1.js
1892+
location: https://github.com/pubnub/javascript/releases/download/v9.3.2/pubnub.9.3.2.js
18881893
requires:
18891894
- name: 'agentkeepalive'
18901895
min-version: '3.5.2'

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
## v9.3.2
2+
March 31 2025
3+
4+
#### Fixed
5+
- Fix missing `heartbeat` and `leave` REST API calls when the event engine is enabled and `presenceTimeout` or `heartbeatInterval` not set.
6+
17
## v9.3.1
28
March 25 2025
39

README.md

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

dist/web/pubnub.js

Lines changed: 31 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3939,7 +3939,7 @@
39393939
return base.PubNubFile;
39403940
},
39413941
get version() {
3942-
return '9.3.1';
3942+
return '9.3.2';
39433943
},
39443944
getVersion() {
39453945
return this.version;
@@ -8641,6 +8641,8 @@
86418641
}
86428642
}
86438643
unsubscribeAll() {
8644+
const channelGroups = this.getSubscribedChannels();
8645+
const channels = this.getSubscribedChannels();
86448646
this.channels = [];
86458647
this.groups = [];
86468648
if (this.dependencies.presenceState) {
@@ -8649,18 +8651,18 @@
86498651
});
86508652
}
86518653
this.engine.transition(subscriptionChange(this.channels.slice(0), this.groups.slice(0)));
8652-
if (this.dependencies.leaveAll) {
8653-
this.dependencies.leaveAll();
8654-
}
8654+
if (this.dependencies.leaveAll)
8655+
this.dependencies.leaveAll({ channels, groups: channelGroups });
86558656
}
86568657
reconnect({ timetoken, region }) {
86578658
this.engine.transition(reconnect(timetoken, region));
86588659
}
86598660
disconnect() {
8661+
const channelGroups = this.getSubscribedChannels();
8662+
const channels = this.getSubscribedChannels();
86608663
this.engine.transition(disconnect());
8661-
if (this.dependencies.leaveAll) {
8662-
this.dependencies.leaveAll();
8663-
}
8664+
if (this.dependencies.leaveAll)
8665+
this.dependencies.leaveAll({ channels, groups: channelGroups });
86648666
}
86658667
getSubscribedChannels() {
86668668
return Array.from(new Set(this.channels.slice(0)));
@@ -14024,8 +14026,13 @@
1402414026
* @param parameters - List of channels and groups where `join` event should be sent.
1402514027
*/
1402614028
join(parameters) {
14027-
var _a;
14028-
(_a = this.presenceEventEngine) === null || _a === void 0 ? void 0 : _a.join(parameters);
14029+
{
14030+
if (this.presenceEventEngine)
14031+
this.presenceEventEngine.join(parameters);
14032+
else {
14033+
this.heartbeat(Object.assign(Object.assign({ channels: parameters.channels, channelGroups: parameters.groups }, (this._configuration.maintainPresenceState && { state: this.presenceState })), { heartbeat: this._configuration.getPresenceTimeout() }), () => { });
14034+
}
14035+
}
1402914036
}
1403014037
// endregion
1403114038
// region Leave
@@ -14038,16 +14045,27 @@
1403814045
*/
1403914046
leave(parameters) {
1404014047
var _a;
14041-
(_a = this.presenceEventEngine) === null || _a === void 0 ? void 0 : _a.leave(parameters);
14048+
{
14049+
if (this.presenceEventEngine)
14050+
(_a = this.presenceEventEngine) === null || _a === void 0 ? void 0 : _a.leave(parameters);
14051+
else
14052+
this.makeUnsubscribe({ channels: parameters.channels, channelGroups: parameters.groups }, () => { });
14053+
}
1404214054
}
1404314055
/**
1404414056
* Announce user `leave` on all subscribed channels.
1404514057
*
1404614058
* @internal
14059+
*
14060+
* @param parameters - List of channels and groups where `leave` event should be sent.
1404714061
*/
14048-
leaveAll() {
14049-
var _a;
14050-
(_a = this.presenceEventEngine) === null || _a === void 0 ? void 0 : _a.leaveAll();
14062+
leaveAll(parameters) {
14063+
{
14064+
if (this.presenceEventEngine)
14065+
this.presenceEventEngine.leaveAll();
14066+
else
14067+
this.makeUnsubscribe({ channels: parameters.channels, channelGroups: parameters.groups }, () => { });
14068+
}
1405114069
}
1405214070
/**
1405314071
* Grant token permission.

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/configuration.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ const makeConfiguration = (base, setupCryptoModule) => {
124124
return base.PubNubFile;
125125
},
126126
get version() {
127-
return '9.3.1';
127+
return '9.3.2';
128128
},
129129
getVersion() {
130130
return this.version;

lib/core/endpoints/fetch_messages.js

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -20,13 +20,23 @@ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (
2020
}) : function(o, v) {
2121
o["default"] = v;
2222
});
23-
var __importStar = (this && this.__importStar) || function (mod) {
24-
if (mod && mod.__esModule) return mod;
25-
var result = {};
26-
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
27-
__setModuleDefault(result, mod);
28-
return result;
29-
};
23+
var __importStar = (this && this.__importStar) || (function () {
24+
var ownKeys = function(o) {
25+
ownKeys = Object.getOwnPropertyNames || function (o) {
26+
var ar = [];
27+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
28+
return ar;
29+
};
30+
return ownKeys(o);
31+
};
32+
return function (mod) {
33+
if (mod && mod.__esModule) return mod;
34+
var result = {};
35+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
36+
__setModuleDefault(result, mod);
37+
return result;
38+
};
39+
})();
3040
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3141
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3242
return new (P || (P = Promise))(function (resolve, reject) {

lib/core/pubnub-common.js

Lines changed: 39 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,23 @@ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (
1818
}) : function(o, v) {
1919
o["default"] = v;
2020
});
21-
var __importStar = (this && this.__importStar) || function (mod) {
22-
if (mod && mod.__esModule) return mod;
23-
var result = {};
24-
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
25-
__setModuleDefault(result, mod);
26-
return result;
27-
};
21+
var __importStar = (this && this.__importStar) || (function () {
22+
var ownKeys = function(o) {
23+
ownKeys = Object.getOwnPropertyNames || function (o) {
24+
var ar = [];
25+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
26+
return ar;
27+
};
28+
return ownKeys(o);
29+
};
30+
return function (mod) {
31+
if (mod && mod.__esModule) return mod;
32+
var result = {};
33+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
34+
__setModuleDefault(result, mod);
35+
return result;
36+
};
37+
})();
2838
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2939
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3040
return new (P || (P = Promise))(function (resolve, reject) {
@@ -1343,9 +1353,13 @@ class PubNubCore {
13431353
* @param parameters - List of channels and groups where `join` event should be sent.
13441354
*/
13451355
join(parameters) {
1346-
var _a;
1347-
if (process.env.PRESENCE_MODULE !== 'disabled')
1348-
(_a = this.presenceEventEngine) === null || _a === void 0 ? void 0 : _a.join(parameters);
1356+
if (process.env.PRESENCE_MODULE !== 'disabled') {
1357+
if (this.presenceEventEngine)
1358+
this.presenceEventEngine.join(parameters);
1359+
else {
1360+
this.heartbeat(Object.assign(Object.assign({ channels: parameters.channels, channelGroups: parameters.groups }, (this._configuration.maintainPresenceState && { state: this.presenceState })), { heartbeat: this._configuration.getPresenceTimeout() }), () => { });
1361+
}
1362+
}
13491363
else
13501364
throw new Error('Announce UUID Presence error: presence module disabled');
13511365
}
@@ -1360,20 +1374,29 @@ class PubNubCore {
13601374
*/
13611375
leave(parameters) {
13621376
var _a;
1363-
if (process.env.PRESENCE_MODULE !== 'disabled')
1364-
(_a = this.presenceEventEngine) === null || _a === void 0 ? void 0 : _a.leave(parameters);
1377+
if (process.env.PRESENCE_MODULE !== 'disabled') {
1378+
if (this.presenceEventEngine)
1379+
(_a = this.presenceEventEngine) === null || _a === void 0 ? void 0 : _a.leave(parameters);
1380+
else
1381+
this.makeUnsubscribe({ channels: parameters.channels, channelGroups: parameters.groups }, () => { });
1382+
}
13651383
else
13661384
throw new Error('Announce UUID Leave error: presence module disabled');
13671385
}
13681386
/**
13691387
* Announce user `leave` on all subscribed channels.
13701388
*
13711389
* @internal
1390+
*
1391+
* @param parameters - List of channels and groups where `leave` event should be sent.
13721392
*/
1373-
leaveAll() {
1374-
var _a;
1375-
if (process.env.PRESENCE_MODULE !== 'disabled')
1376-
(_a = this.presenceEventEngine) === null || _a === void 0 ? void 0 : _a.leaveAll();
1393+
leaveAll(parameters) {
1394+
if (process.env.PRESENCE_MODULE !== 'disabled') {
1395+
if (this.presenceEventEngine)
1396+
this.presenceEventEngine.leaveAll();
1397+
else
1398+
this.makeUnsubscribe({ channels: parameters.channels, channelGroups: parameters.groups }, () => { });
1399+
}
13771400
else
13781401
throw new Error('Announce UUID Leave error: presence module disabled');
13791402
}

lib/crypto/modules/NodeCryptoModule/aesCbcCryptor.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ class AesCbcCryptor {
8181
let data = stream.stream.read();
8282
while (data !== null) {
8383
if (data) {
84-
const bChunk = Buffer.from(data);
84+
const bChunk = typeof data === 'string' ? Buffer.from(data) : data;
8585
const sliceLen = stream.metadataLength - bIv.byteLength;
8686
if (bChunk.byteLength < sliceLen) {
8787
bIv = Buffer.concat([bIv, bChunk]);

lib/event-engine/dispatcher.js

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -20,13 +20,23 @@ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (
2020
}) : function(o, v) {
2121
o["default"] = v;
2222
});
23-
var __importStar = (this && this.__importStar) || function (mod) {
24-
if (mod && mod.__esModule) return mod;
25-
var result = {};
26-
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
27-
__setModuleDefault(result, mod);
28-
return result;
29-
};
23+
var __importStar = (this && this.__importStar) || (function () {
24+
var ownKeys = function(o) {
25+
ownKeys = Object.getOwnPropertyNames || function (o) {
26+
var ar = [];
27+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
28+
return ar;
29+
};
30+
return ownKeys(o);
31+
};
32+
return function (mod) {
33+
if (mod && mod.__esModule) return mod;
34+
var result = {};
35+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
36+
__setModuleDefault(result, mod);
37+
return result;
38+
};
39+
})();
3040
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3141
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3242
return new (P || (P = Promise))(function (resolve, reject) {

lib/event-engine/index.js

Lines changed: 25 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -20,13 +20,23 @@ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (
2020
}) : function(o, v) {
2121
o["default"] = v;
2222
});
23-
var __importStar = (this && this.__importStar) || function (mod) {
24-
if (mod && mod.__esModule) return mod;
25-
var result = {};
26-
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
27-
__setModuleDefault(result, mod);
28-
return result;
29-
};
23+
var __importStar = (this && this.__importStar) || (function () {
24+
var ownKeys = function(o) {
25+
ownKeys = Object.getOwnPropertyNames || function (o) {
26+
var ar = [];
27+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
28+
return ar;
29+
};
30+
return ownKeys(o);
31+
};
32+
return function (mod) {
33+
if (mod && mod.__esModule) return mod;
34+
var result = {};
35+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
36+
__setModuleDefault(result, mod);
37+
return result;
38+
};
39+
})();
3040
Object.defineProperty(exports, "__esModule", { value: true });
3141
exports.EventEngine = void 0;
3242
const core_1 = require("./core");
@@ -105,6 +115,8 @@ class EventEngine {
105115
}
106116
}
107117
unsubscribeAll() {
118+
const channelGroups = this.getSubscribedChannels();
119+
const channels = this.getSubscribedChannels();
108120
this.channels = [];
109121
this.groups = [];
110122
if (this.dependencies.presenceState) {
@@ -113,18 +125,18 @@ class EventEngine {
113125
});
114126
}
115127
this.engine.transition(events.subscriptionChange(this.channels.slice(0), this.groups.slice(0)));
116-
if (this.dependencies.leaveAll) {
117-
this.dependencies.leaveAll();
118-
}
128+
if (this.dependencies.leaveAll)
129+
this.dependencies.leaveAll({ channels, groups: channelGroups });
119130
}
120131
reconnect({ timetoken, region }) {
121132
this.engine.transition(events.reconnect(timetoken, region));
122133
}
123134
disconnect() {
135+
const channelGroups = this.getSubscribedChannels();
136+
const channels = this.getSubscribedChannels();
124137
this.engine.transition(events.disconnect());
125-
if (this.dependencies.leaveAll) {
126-
this.dependencies.leaveAll();
127-
}
138+
if (this.dependencies.leaveAll)
139+
this.dependencies.leaveAll({ channels, groups: channelGroups });
128140
}
129141
getSubscribedChannels() {
130142
return Array.from(new Set(this.channels.slice(0)));

0 commit comments

Comments
 (0)