Skip to content

Commit d44662b

Browse files
authored
Fix entity usage issue (#460)
fix(subscription-flow): fix `heartbeat` cancellation failure Fix issue because of which in new flow `heartbeat` request not cancelled properly when issued in burst. fix(cbor): fix issue with resource name as integer Fix issue because resource names, which consist only of integers, have been decoded as Unicode characters. fix(subscription): fix issue with unsubscription on entity with a similar name Fix issue because the entity that has been created with `-pnpres` suffix has been removed from subscription loop during unsubscribe from entity with presence listening capability. feat(shared-worker): start backup heartbeat timer Launch a backup heartbeat timer per registered PubNub instance in SharedWorker context to protect against browsers throttling of background (hidden) tabs. refactor(logger): use explicit names of classes instead of constructor Use string names of classes for locations instead of dynamic access to constructor names because it affect how logs looks like after minification.
1 parent 8bf31a4 commit d44662b

File tree

88 files changed

+4290
-3862
lines changed

Some content is hidden

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

88 files changed

+4290
-3862
lines changed

.pubnub.yml

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,18 @@
11
---
22
changelog:
3+
- date: 2025-06-30
4+
version: v9.7.0
5+
changes:
6+
- type: feature
7+
text: "Launch a backup heartbeat timer per registered PubNub instance in SharedWorker context to protect against browsers throttling of background (hidden) tabs."
8+
- type: bug
9+
text: "Fix issue because of which in new flow `heartbeat` request not cancelled properly when issued in burst."
10+
- type: bug
11+
text: "Fix issue because resource names, which consist only of integers, have been decoded as Unicode characters."
12+
- type: bug
13+
text: "Fix issue because the entity that has been created with `-pnpres` suffix has been removed from subscription loop during unsubscribe from entity with presence listening capability."
14+
- type: improvement
15+
text: "Use string names of classes for locations instead of dynamic access to constructor names because it affect how logs looks like after minification."
316
- date: 2025-06-30
417
version: v9.6.2
518
changes:
@@ -1263,7 +1276,7 @@ supported-platforms:
12631276
- 'Ubuntu 14.04 and up'
12641277
- 'Windows 7 and up'
12651278
version: 'Pubnub Javascript for Node'
1266-
version: '9.6.2'
1279+
version: '9.7.0'
12671280
sdks:
12681281
- full-name: PubNub Javascript SDK
12691282
short-name: Javascript
@@ -1279,7 +1292,7 @@ sdks:
12791292
- distribution-type: source
12801293
distribution-repository: GitHub release
12811294
package-name: pubnub.js
1282-
location: https://github.com/pubnub/javascript/archive/refs/tags/v9.6.2.zip
1295+
location: https://github.com/pubnub/javascript/archive/refs/tags/v9.7.0.zip
12831296
requires:
12841297
- name: 'agentkeepalive'
12851298
min-version: '3.5.2'
@@ -1950,7 +1963,7 @@ sdks:
19501963
- distribution-type: library
19511964
distribution-repository: GitHub release
19521965
package-name: pubnub.js
1953-
location: https://github.com/pubnub/javascript/releases/download/v9.6.2/pubnub.9.6.2.js
1966+
location: https://github.com/pubnub/javascript/releases/download/v9.7.0/pubnub.9.7.0.js
19541967
requires:
19551968
- name: 'agentkeepalive'
19561969
min-version: '3.5.2'

CHANGELOG.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,17 @@
1+
## v9.7.0
2+
June 30 2025
3+
4+
#### Added
5+
- Launch a backup heartbeat timer per registered PubNub instance in SharedWorker context to protect against browsers throttling of background (hidden) tabs.
6+
7+
#### Fixed
8+
- Fix issue because of which in new flow `heartbeat` request not cancelled properly when issued in burst.
9+
- Fix issue because resource names, which consist only of integers, have been decoded as Unicode characters.
10+
- Fix issue because the entity that has been created with `-pnpres` suffix has been removed from subscription loop during unsubscribe from entity with presence listening capability.
11+
12+
#### Modified
13+
- Use string names of classes for locations instead of dynamic access to constructor names because it affect how logs looks like after minification.
14+
115
## v9.6.2
216
June 30 2025
317

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.6.2.js
31-
* https://cdn.pubnub.com/sdk/javascript/pubnub.9.6.2.min.js
30+
* https://cdn.pubnub.com/sdk/javascript/pubnub.9.7.0.js
31+
* https://cdn.pubnub.com/sdk/javascript/pubnub.9.7.0.min.js
3232
3333
2. Configure your keys:
3434

dist/web/pubnub.js

Lines changed: 3407 additions & 3207 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.

dist/web/pubnub.worker.js

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -465,6 +465,11 @@
465465
if (hbRequestsBySubscriptionKey[heartbeatRequestKey] &&
466466
hbRequestsBySubscriptionKey[heartbeatRequestKey].clientIdentifier === client.clientIdentifier)
467467
delete hbRequestsBySubscriptionKey[heartbeatRequestKey].clientIdentifier;
468+
if (heartbeat.timer) {
469+
clearInterval(heartbeat.timer);
470+
delete heartbeat.heartbeatEvent;
471+
delete heartbeat.timer;
472+
}
468473
}
469474
}
470475
if (!request) {
@@ -1242,20 +1247,23 @@
12421247
* Use information from request to populate list of channels and other useful information.
12431248
*
12441249
* @param event - Send request.
1250+
* @returns `true` if channels / groups list has been changed. May return `undefined` because `client` is missing.
12451251
*/
12461252
const updateClientSubscribeStateIfRequired = (event) => {
12471253
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l;
12481254
var _m, _o, _p, _q, _r, _s, _t, _u, _v;
12491255
const query = event.request.queryParameters;
12501256
const { clientIdentifier } = event;
12511257
const client = pubNubClients[clientIdentifier];
1258+
let changed = false;
12521259
// This should never happen.
12531260
if (!client)
12541261
return;
12551262
const channelGroupQuery = ((_a = query['channel-group']) !== null && _a !== void 0 ? _a : '');
12561263
const state = ((_b = query.state) !== null && _b !== void 0 ? _b : '');
12571264
let subscription = client.subscription;
12581265
if (!subscription) {
1266+
changed = true;
12591267
subscription = {
12601268
path: '',
12611269
channelGroupQuery: '',
@@ -1294,11 +1302,17 @@
12941302
}
12951303
if (subscription.path !== event.request.path) {
12961304
subscription.path = event.request.path;
1297-
subscription.channels = channelsFromRequest(event.request);
1305+
const _channelsFromRequest = channelsFromRequest(event.request);
1306+
if (!changed)
1307+
changed = includesStrings(subscription.channels, _channelsFromRequest);
1308+
subscription.channels = _channelsFromRequest;
12981309
}
12991310
if (subscription.channelGroupQuery !== channelGroupQuery) {
13001311
subscription.channelGroupQuery = channelGroupQuery;
1301-
subscription.channelGroups = channelGroupsFromRequest(event.request);
1312+
const _channelGroupsFromRequest = channelGroupsFromRequest(event.request);
1313+
if (!changed)
1314+
changed = includesStrings(subscription.channelGroups, _channelGroupsFromRequest);
1315+
subscription.channelGroups = _channelGroupsFromRequest;
13021316
}
13031317
let { authKey } = client;
13041318
const { userId } = client;
@@ -1326,7 +1340,8 @@
13261340
*/
13271341
const updateClientHeartbeatState = (event) => {
13281342
var _a, _b;
1329-
const client = pubNubClients[event.clientIdentifier];
1343+
const { clientIdentifier } = event;
1344+
const client = pubNubClients[clientIdentifier];
13301345
const { request } = event;
13311346
// This should never happen.
13321347
if (!client)
@@ -1335,6 +1350,16 @@
13351350
channels: [],
13361351
channelGroups: [],
13371352
}));
1353+
_clientHeartbeat.heartbeatEvent = Object.assign({}, event);
1354+
if (!_clientHeartbeat.timer) {
1355+
_clientHeartbeat.timer = setInterval(() => {
1356+
const client = pubNubClients[clientIdentifier];
1357+
// This should never happen.
1358+
if (!client || !client.heartbeat || !client.heartbeat.heartbeatEvent)
1359+
return;
1360+
handleHeartbeatRequestEvent(client.heartbeat.heartbeatEvent);
1361+
}, client.heartbeatInterval * 1000);
1362+
}
13381363
// Update presence heartbeat information about client.
13391364
_clientHeartbeat.channelGroups = channelGroupsFromRequest(request).filter((group) => !group.endsWith('-pnpres'));
13401365
_clientHeartbeat.channels = channelsFromRequest(request).filter((channel) => !channel.endsWith('-pnpres'));
@@ -1396,6 +1421,9 @@
13961421
if (serviceRequestId)
13971422
cancelRequest(serviceRequestId);
13981423
}
1424+
// Make sure to stop heartbeat timer.
1425+
if (invalidatedClient.heartbeat && invalidatedClient.heartbeat.timer)
1426+
clearInterval(invalidatedClient.heartbeat.timer);
13991427
if (serviceHeartbeatRequests[subscriptionKey]) {
14001428
const hbRequestsBySubscriptionKey = ((_a = serviceHeartbeatRequests[subscriptionKey]) !== null && _a !== void 0 ? _a : (serviceHeartbeatRequests[subscriptionKey] = {}));
14011429
const heartbeatRequestKey = `${invalidatedClient.userId}_${(_b = clientAggregateAuthKey(invalidatedClient)) !== null && _b !== void 0 ? _b : ''}`;

dist/web/pubnub.worker.min.js

Lines changed: 1 addition & 1 deletion
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: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,11 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
99
};
1010
Object.defineProperty(exports, "__esModule", { value: true });
1111
exports.makeConfiguration = void 0;
12+
const console_logger_1 = require("../../loggers/console-logger");
1213
const retry_policy_1 = require("./retry-policy");
13-
const uuid_1 = __importDefault(require("./uuid"));
1414
const logger_1 = require("../interfaces/logger");
1515
const logger_manager_1 = require("./logger-manager");
16-
const console_logger_1 = require("../../loggers/console-logger");
16+
const uuid_1 = __importDefault(require("./uuid"));
1717
// --------------------------------------------------------
1818
// ----------------------- Defaults -----------------------
1919
// --------------------------------------------------------
@@ -164,7 +164,7 @@ const makeConfiguration = (base, setupCryptoModule) => {
164164
return base.PubNubFile;
165165
},
166166
get version() {
167-
return '9.6.2';
167+
return '9.7.0';
168168
},
169169
getVersion() {
170170
return this.version;

lib/core/components/cryptography/index.js

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ class default_1 {
123123
encrypt(data, customCipherKey, options) {
124124
if (this.configuration.customEncrypt) {
125125
if (this.logger)
126-
this.logger.warn(this.constructor.name, "'customEncrypt' is deprecated. Consult docs for better alternative.");
126+
this.logger.warn('Crypto', "'customEncrypt' is deprecated. Consult docs for better alternative.");
127127
return this.configuration.customEncrypt(data);
128128
}
129129
return this.pnEncrypt(data, customCipherKey, options);
@@ -140,7 +140,7 @@ class default_1 {
140140
decrypt(data, customCipherKey, options) {
141141
if (this.configuration.customDecrypt) {
142142
if (this.logger)
143-
this.logger.warn(this.constructor.name, "'customDecrypt' is deprecated. Consult docs for better alternative.");
143+
this.logger.warn('Crypto', "'customDecrypt' is deprecated. Consult docs for better alternative.");
144144
return this.configuration.customDecrypt(data);
145145
}
146146
return this.pnDecrypt(data, customCipherKey, options);
@@ -159,7 +159,7 @@ class default_1 {
159159
if (!decidedCipherKey)
160160
return data;
161161
if (this.logger) {
162-
this.logger.debug(this.constructor.name, () => ({
162+
this.logger.debug('Crypto', () => ({
163163
messageType: 'object',
164164
message: Object.assign({ data, cipherKey: decidedCipherKey }, (options !== null && options !== void 0 ? options : {})),
165165
details: 'Encrypt with parameters:',
@@ -196,7 +196,7 @@ class default_1 {
196196
if (!decidedCipherKey)
197197
return data;
198198
if (this.logger) {
199-
this.logger.debug(this.constructor.name, () => ({
199+
this.logger.debug('Crypto', () => ({
200200
messageType: 'object',
201201
message: Object.assign({ data, cipherKey: decidedCipherKey }, (options !== null && options !== void 0 ? options : {})),
202202
details: 'Decrypt with parameters:',
@@ -218,7 +218,7 @@ class default_1 {
218218
}
219219
catch (e) {
220220
if (this.logger)
221-
this.logger.error(this.constructor.name, () => ({ messageType: 'error', message: e }));
221+
this.logger.error('Crypto', () => ({ messageType: 'error', message: e }));
222222
return null;
223223
}
224224
}
@@ -233,7 +233,7 @@ class default_1 {
233233
}
234234
catch (e) {
235235
if (this.logger)
236-
this.logger.error(this.constructor.name, () => ({ messageType: 'error', message: e }));
236+
this.logger.error('Crypto', () => ({ messageType: 'error', message: e }));
237237
return null;
238238
}
239239
}

lib/core/components/deduping_manager.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ class DedupingManager {
1919
*/
2020
constructor(config) {
2121
this.config = config;
22-
config.logger().debug(this.constructor.name, () => ({
22+
config.logger().debug('DedupingManager', () => ({
2323
messageType: 'object',
2424
message: { maximumCacheSize: config.maximumCacheSize },
2525
details: 'Create with configuration:',

0 commit comments

Comments
 (0)