Skip to content

Commit b1a9f06

Browse files
authored
Fix subscription reference timetoken (#464)
fix(subscription): fix subscription reference timetime Fix incorrect subscription reference timetoken (used by listeners to filter old messages) caused by the server returning timetoken older than previous one because of MX. fix(subscription-set): fix event handling by subscription Fix the issue because of which all subscriptions of the subscription set have been requested to handle the received event. refactor(shared-worker): use `addEventListener` instead of `onpagehide` Replace the `onpagehide` listener assignment with `addEventListener` to ensure that the listener won't be replaced.
1 parent 8bf3d6f commit b1a9f06

File tree

21 files changed

+190
-47
lines changed

21 files changed

+190
-47
lines changed

.pubnub.yml

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,12 @@
11
---
22
changelog:
3+
- date: 2025-07-15
4+
version: v9.8.1
5+
changes:
6+
- type: bug
7+
text: "Fix incorrect subscription reference timetoken (used by listeners to filter old messages) caused by the server returning timetoken older than the previous one because of MX."
8+
- type: bug
9+
text: "Fix the issue because of which all subscriptions of the subscription set have been requested to handle the received event."
310
- date: 2025-07-11
411
version: v9.8.0
512
changes:
@@ -1291,7 +1298,7 @@ supported-platforms:
12911298
- 'Ubuntu 14.04 and up'
12921299
- 'Windows 7 and up'
12931300
version: 'Pubnub Javascript for Node'
1294-
version: '9.8.0'
1301+
version: '9.8.1'
12951302
sdks:
12961303
- full-name: PubNub Javascript SDK
12971304
short-name: Javascript
@@ -1307,7 +1314,7 @@ sdks:
13071314
- distribution-type: source
13081315
distribution-repository: GitHub release
13091316
package-name: pubnub.js
1310-
location: https://github.com/pubnub/javascript/archive/refs/tags/v9.8.0.zip
1317+
location: https://github.com/pubnub/javascript/archive/refs/tags/v9.8.1.zip
13111318
requires:
13121319
- name: 'agentkeepalive'
13131320
min-version: '3.5.2'
@@ -1978,7 +1985,7 @@ sdks:
19781985
- distribution-type: library
19791986
distribution-repository: GitHub release
19801987
package-name: pubnub.js
1981-
location: https://github.com/pubnub/javascript/releases/download/v9.8.0/pubnub.9.8.0.js
1988+
location: https://github.com/pubnub/javascript/releases/download/v9.8.1/pubnub.9.8.1.js
19821989
requires:
19831990
- name: 'agentkeepalive'
19841991
min-version: '3.5.2'

CHANGELOG.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,10 @@
1+
## v9.8.1
2+
July 15 2025
3+
4+
#### Fixed
5+
- Fix incorrect subscription reference timetoken (used by listeners to filter old messages) caused by the server returning timetoken older than the previous one because of MX.
6+
- Fix the issue because of which all subscriptions of the subscription set have been requested to handle the received event.
7+
18
## v9.8.0
29
July 11 2025
310

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

dist/web/pubnub.js

Lines changed: 23 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -4394,6 +4394,10 @@
43944394
*/
43954395
const adjustedTimetokenBy = (timetoken, value, increment) => {
43964396
// Normalize value to the PubNub's high-precision time format.
4397+
if (value.startsWith('-')) {
4398+
value = value.replace('-', '');
4399+
increment = false;
4400+
}
43974401
value = value.padStart(17, '0');
43984402
const secA = timetoken.slice(0, 10);
43994403
const tickA = timetoken.slice(10, 17);
@@ -4415,6 +4419,10 @@
44154419
else if (seconds < 0)
44164420
ticks *= -1;
44174421
}
4422+
else if (seconds < 0 && ticks > 0) {
4423+
seconds += 1;
4424+
ticks = 10000000 - ticks;
4425+
}
44184426
return seconds !== 0 ? `${seconds}${`${ticks}`.padStart(7, '0')}` : `${ticks}`;
44194427
};
44204428
/**
@@ -5325,7 +5333,7 @@
53255333
return base.PubNubFile;
53265334
},
53275335
get version() {
5328-
return '9.8.0';
5336+
return '9.8.1';
53295337
},
53305338
getVersion() {
53315339
return this.version;
@@ -10795,25 +10803,24 @@
1079510803
* @internal
1079610804
*/
1079710805
handleEvent(cursor, event) {
10798-
var _a;
10799-
if (!this.state.isSubscribed)
10806+
var _a, _b;
10807+
if (!this.state.isSubscribed ||
10808+
!this.state.subscriptionInput.contains((_a = event.data.subscription) !== null && _a !== void 0 ? _a : event.data.channel))
1080010809
return;
1080110810
if (this.parentSetsCount > 0) {
1080210811
// Creating from whole payload (not only for published messages).
1080310812
const fingerprint = messageFingerprint(event.data);
1080410813
if (this.handledUpdates.includes(fingerprint)) {
10805-
this.state.client.logger.trace(this.subscriptionType, `Message (${fingerprint}) already handled by ${this.id}. Ignoring.`);
10814+
this.state.client.logger.trace(this.subscriptionType, `Event (${fingerprint}) already handled by ${this.id}. Ignoring.`);
1080610815
return;
1080710816
}
10808-
else
10809-
console.log(`${this.id} handled (${fingerprint})`);
1081010817
// Update a list of tracked messages and shrink it if too big.
1081110818
this.handledUpdates.push(fingerprint);
1081210819
if (this.handledUpdates.length > 10)
1081310820
this.handledUpdates.shift();
1081410821
}
1081510822
// Check whether an event is not designated for this subscription set.
10816-
if (!this.state.subscriptionInput.contains((_a = event.data.subscription) !== null && _a !== void 0 ? _a : event.data.channel))
10823+
if (!this.state.subscriptionInput.contains((_b = event.data.subscription) !== null && _b !== void 0 ? _b : event.data.channel))
1081710824
return;
1081810825
super.handleEvent(cursor, event);
1081910826
}
@@ -16233,7 +16240,7 @@
1623316240
*/
1623416241
disconnect(isOffline = false) {
1623516242
{
16236-
this.logger.debug('PubNub', `Disconnect (while offline? ${!!isOffline ? 'yes' : 'no'}`);
16243+
this.logger.debug('PubNub', `Disconnect (while offline? ${!!isOffline ? 'yes' : 'no'})`);
1623716244
if (this.subscriptionManager)
1623816245
this.subscriptionManager.disconnect();
1623916246
else if (this.eventEngine)
@@ -17694,7 +17701,8 @@
1769417701
this._globalSubscriptionSet.handleEvent(cursor, event);
1769517702
(_a = this.eventDispatcher) === null || _a === void 0 ? void 0 : _a.handleEvent(event);
1769617703
Object.values(this.eventHandleCapable).forEach((eventHandleCapable) => {
17697-
eventHandleCapable.handleEvent(cursor, event);
17704+
if (eventHandleCapable !== this._globalSubscriptionSet)
17705+
eventHandleCapable.handleEvent(cursor, event);
1769817706
});
1769917707
}
1770017708
}
@@ -18103,10 +18111,12 @@
1810318111
authenticationChangeHandler = (auth) => middleware.onTokenChange(auth);
1810418112
userIdChangeHandler = (userId) => middleware.onUserIdChange(userId);
1810518113
transport = middleware;
18106-
window.onpagehide = (event) => {
18107-
if (!event.persisted)
18108-
middleware.terminate();
18109-
};
18114+
if (configurationCopy.subscriptionWorkerUnsubscribeOfflineClients) {
18115+
window.addEventListener('pagehide', (event) => {
18116+
if (!event.persisted)
18117+
middleware.terminate();
18118+
}, { once: true });
18119+
}
1811018120
}
1811118121
catch (e) {
1811218122
clientConfiguration.logger().error('PubNub', () => ({

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
@@ -164,7 +164,7 @@ const makeConfiguration = (base, setupCryptoModule) => {
164164
return base.PubNubFile;
165165
},
166166
get version() {
167-
return '9.8.0';
167+
return '9.8.1';
168168
},
169169
getVersion() {
170170
return this.version;

lib/core/pubnub-common.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1319,7 +1319,7 @@ class PubNubCore {
13191319
*/
13201320
disconnect(isOffline = false) {
13211321
if (process.env.SUBSCRIBE_MODULE !== 'disabled') {
1322-
this.logger.debug('PubNub', `Disconnect (while offline? ${!!isOffline ? 'yes' : 'no'}`);
1322+
this.logger.debug('PubNub', `Disconnect (while offline? ${!!isOffline ? 'yes' : 'no'})`);
13231323
if (this.subscriptionManager)
13241324
this.subscriptionManager.disconnect();
13251325
else if (this.eventEngine)
@@ -2960,7 +2960,8 @@ class PubNubCore {
29602960
this._globalSubscriptionSet.handleEvent(cursor, event);
29612961
(_a = this.eventDispatcher) === null || _a === void 0 ? void 0 : _a.handleEvent(event);
29622962
Object.values(this.eventHandleCapable).forEach((eventHandleCapable) => {
2963-
eventHandleCapable.handleEvent(cursor, event);
2963+
if (eventHandleCapable !== this._globalSubscriptionSet)
2964+
eventHandleCapable.handleEvent(cursor, event);
29642965
});
29652966
}
29662967
}

lib/core/utils.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,10 @@ exports.referenceSubscribeTimetoken = referenceSubscribeTimetoken;
131131
*/
132132
const adjustedTimetokenBy = (timetoken, value, increment) => {
133133
// Normalize value to the PubNub's high-precision time format.
134+
if (value.startsWith('-')) {
135+
value = value.replace('-', '');
136+
increment = false;
137+
}
134138
value = value.padStart(17, '0');
135139
const secA = timetoken.slice(0, 10);
136140
const tickA = timetoken.slice(10, 17);
@@ -152,6 +156,10 @@ const adjustedTimetokenBy = (timetoken, value, increment) => {
152156
else if (seconds < 0)
153157
ticks *= -1;
154158
}
159+
else if (seconds < 0 && ticks > 0) {
160+
seconds += 1;
161+
ticks = 10000000 - ticks;
162+
}
155163
return seconds !== 0 ? `${seconds}${`${ticks}`.padStart(7, '0')}` : `${ticks}`;
156164
};
157165
exports.adjustedTimetokenBy = adjustedTimetokenBy;

lib/entities/subscription.js

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -112,25 +112,24 @@ class Subscription extends subscription_base_1.SubscriptionBase {
112112
* @internal
113113
*/
114114
handleEvent(cursor, event) {
115-
var _a;
116-
if (!this.state.isSubscribed)
115+
var _a, _b;
116+
if (!this.state.isSubscribed ||
117+
!this.state.subscriptionInput.contains((_a = event.data.subscription) !== null && _a !== void 0 ? _a : event.data.channel))
117118
return;
118119
if (this.parentSetsCount > 0) {
119120
// Creating from whole payload (not only for published messages).
120121
const fingerprint = (0, utils_1.messageFingerprint)(event.data);
121122
if (this.handledUpdates.includes(fingerprint)) {
122-
this.state.client.logger.trace(this.subscriptionType, `Message (${fingerprint}) already handled by ${this.id}. Ignoring.`);
123+
this.state.client.logger.trace(this.subscriptionType, `Event (${fingerprint}) already handled by ${this.id}. Ignoring.`);
123124
return;
124125
}
125-
else
126-
console.log(`${this.id} handled (${fingerprint})`);
127126
// Update a list of tracked messages and shrink it if too big.
128127
this.handledUpdates.push(fingerprint);
129128
if (this.handledUpdates.length > 10)
130129
this.handledUpdates.shift();
131130
}
132131
// Check whether an event is not designated for this subscription set.
133-
if (!this.state.subscriptionInput.contains((_a = event.data.subscription) !== null && _a !== void 0 ? _a : event.data.channel))
132+
if (!this.state.subscriptionInput.contains((_b = event.data.subscription) !== null && _b !== void 0 ? _b : event.data.channel))
134133
return;
135134
super.handleEvent(cursor, event);
136135
}

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "pubnub",
3-
"version": "9.8.0",
3+
"version": "9.8.1",
44
"author": "PubNub <support@pubnub.com>",
55
"description": "Publish & Subscribe Real-time Messaging with PubNub",
66
"scripts": {

0 commit comments

Comments
 (0)