Skip to content

Commit 9032b02

Browse files
mohitpubnubMohit Tejanipubnub-release-bot
authored
refactor: avoid re subscribe for already subscribed entities (#486)
* refactor: prevent event engine state transition when subsequent subscribe request contain existing channels or groups * lib/dist updates * refactor: remove filter for presence channels from subscriptionChanged status event in re-subscribe scenario * PubNub SDK v10.2.4 release. --------- Co-authored-by: Mohit Tejani <mohit.tejani@Mohits-MacBook-Pro.local> Co-authored-by: PubNub Release Bot <120067856+pubnub-release-bot@users.noreply.github.com>
1 parent 762e185 commit 9032b02

File tree

12 files changed

+251
-21
lines changed

12 files changed

+251
-21
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-12-04
4+
version: v10.2.4
5+
changes:
6+
- type: improvement
7+
text: "Prevent resubscribe to previously subscribed entities."
38
- date: 2025-11-20
49
version: v10.2.3
510
changes:
@@ -1369,7 +1374,7 @@ supported-platforms:
13691374
- 'Ubuntu 14.04 and up'
13701375
- 'Windows 7 and up'
13711376
version: 'Pubnub Javascript for Node'
1372-
version: '10.2.3'
1377+
version: '10.2.4'
13731378
sdks:
13741379
- full-name: PubNub Javascript SDK
13751380
short-name: Javascript
@@ -1385,7 +1390,7 @@ sdks:
13851390
- distribution-type: source
13861391
distribution-repository: GitHub release
13871392
package-name: pubnub.js
1388-
location: https://github.com/pubnub/javascript/archive/refs/tags/v10.2.3.zip
1393+
location: https://github.com/pubnub/javascript/archive/refs/tags/v10.2.4.zip
13891394
requires:
13901395
- name: 'agentkeepalive'
13911396
min-version: '3.5.2'
@@ -2056,7 +2061,7 @@ sdks:
20562061
- distribution-type: library
20572062
distribution-repository: GitHub release
20582063
package-name: pubnub.js
2059-
location: https://github.com/pubnub/javascript/releases/download/v10.2.3/pubnub.10.2.3.js
2064+
location: https://github.com/pubnub/javascript/releases/download/v10.2.4/pubnub.10.2.4.js
20602065
requires:
20612066
- name: 'agentkeepalive'
20622067
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+
## v10.2.4
2+
December 04 2025
3+
4+
#### Modified
5+
- Prevent resubscribe to previously subscribed entities.
6+
17
## v10.2.3
28
November 20 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.10.2.3.js
31-
* https://cdn.pubnub.com/sdk/javascript/pubnub.10.2.3.min.js
30+
* https://cdn.pubnub.com/sdk/javascript/pubnub.10.2.4.js
31+
* https://cdn.pubnub.com/sdk/javascript/pubnub.10.2.4.min.js
3232
3333
2. Configure your keys:
3434

dist/web/pubnub.js

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5436,7 +5436,7 @@
54365436
return base.PubNubFile;
54375437
},
54385438
get version() {
5439-
return '10.2.3';
5439+
return '10.2.4';
54405440
},
54415441
getVersion() {
54425442
return this.version;
@@ -9566,6 +9566,11 @@
95669566
return subscriptionTimetokenFromReference(currentTimetoken, referenceTimetoken !== null && referenceTimetoken !== void 0 ? referenceTimetoken : '0');
95679567
}
95689568
subscribe({ channels, channelGroups, timetoken, withPresence, }) {
9569+
var _a;
9570+
// check if the channels and groups are already subscribed
9571+
const hasNewChannels = channels === null || channels === void 0 ? void 0 : channels.some((channel) => !this.channels.includes(channel));
9572+
const hasNewGroups = channelGroups === null || channelGroups === void 0 ? void 0 : channelGroups.some((group) => !this.groups.includes(group));
9573+
const hasNewSubscriptions = hasNewChannels || hasNewGroups;
95699574
this.channels = [...this.channels, ...(channels !== null && channels !== void 0 ? channels : [])];
95709575
this.groups = [...this.groups, ...(channelGroups !== null && channelGroups !== void 0 ? channelGroups : [])];
95719576
if (withPresence) {
@@ -9576,7 +9581,29 @@
95769581
this.engine.transition(restore(Array.from(new Set([...this.channels, ...(channels !== null && channels !== void 0 ? channels : [])])), Array.from(new Set([...this.groups, ...(channelGroups !== null && channelGroups !== void 0 ? channelGroups : [])])), timetoken));
95779582
}
95789583
else {
9579-
this.engine.transition(subscriptionChange(Array.from(new Set([...this.channels, ...(channels !== null && channels !== void 0 ? channels : [])])), Array.from(new Set([...this.groups, ...(channelGroups !== null && channelGroups !== void 0 ? channelGroups : [])]))));
9584+
if (hasNewSubscriptions) {
9585+
this.engine.transition(subscriptionChange(Array.from(new Set([...this.channels, ...(channels !== null && channels !== void 0 ? channels : [])])), Array.from(new Set([...this.groups, ...(channelGroups !== null && channelGroups !== void 0 ? channelGroups : [])]))));
9586+
}
9587+
else {
9588+
this.dependencies.config
9589+
.logger()
9590+
.debug('EventEngine', 'Skipping state transition - all channels/groups already subscribed. Emitting SubscriptionChanged event.');
9591+
// Get current timetoken from state context
9592+
const currentState = this.engine.currentState;
9593+
const currentContext = this.engine.currentContext;
9594+
let currentTimetoken = '0';
9595+
if ((currentState === null || currentState === void 0 ? void 0 : currentState.label) === ReceivingState.label && currentContext) {
9596+
const receivingContext = currentContext;
9597+
currentTimetoken = (_a = receivingContext.cursor) === null || _a === void 0 ? void 0 : _a.timetoken;
9598+
}
9599+
// Manually emit SubscriptionChanged status event
9600+
this.dependencies.emitStatus({
9601+
category: StatusCategory$1.PNSubscriptionChangedCategory,
9602+
affectedChannels: Array.from(new Set(this.channels)),
9603+
affectedChannelGroups: Array.from(new Set(this.groups)),
9604+
currentTimetoken,
9605+
});
9606+
}
95809607
}
95819608
if (this.dependencies.join) {
95829609
this.dependencies.join({

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
@@ -168,7 +168,7 @@ const makeConfiguration = (base, setupCryptoModule) => {
168168
return base.PubNubFile;
169169
},
170170
get version() {
171-
return '10.2.3';
171+
return '10.2.4';
172172
},
173173
getVersion() {
174174
return this.version;

lib/event-engine/index.js

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,13 +37,17 @@ var __importStar = (this && this.__importStar) || (function () {
3737
return result;
3838
};
3939
})();
40+
var __importDefault = (this && this.__importDefault) || function (mod) {
41+
return (mod && mod.__esModule) ? mod : { "default": mod };
42+
};
4043
Object.defineProperty(exports, "__esModule", { value: true });
4144
exports.EventEngine = void 0;
4245
const receiving_1 = require("./states/receiving");
4346
const dispatcher_1 = require("./dispatcher");
4447
const utils_1 = require("../core/utils");
4548
const unsubscribed_1 = require("./states/unsubscribed");
4649
const core_1 = require("./core");
50+
const categories_1 = __importDefault(require("../core/constants/categories"));
4751
const utils = __importStar(require("../core/utils"));
4852
const events = __importStar(require("./events"));
4953
/**
@@ -88,6 +92,11 @@ class EventEngine {
8892
return (0, utils_1.subscriptionTimetokenFromReference)(currentTimetoken, referenceTimetoken !== null && referenceTimetoken !== void 0 ? referenceTimetoken : '0');
8993
}
9094
subscribe({ channels, channelGroups, timetoken, withPresence, }) {
95+
var _a;
96+
// check if the channels and groups are already subscribed
97+
const hasNewChannels = channels === null || channels === void 0 ? void 0 : channels.some((channel) => !this.channels.includes(channel));
98+
const hasNewGroups = channelGroups === null || channelGroups === void 0 ? void 0 : channelGroups.some((group) => !this.groups.includes(group));
99+
const hasNewSubscriptions = hasNewChannels || hasNewGroups;
91100
this.channels = [...this.channels, ...(channels !== null && channels !== void 0 ? channels : [])];
92101
this.groups = [...this.groups, ...(channelGroups !== null && channelGroups !== void 0 ? channelGroups : [])];
93102
if (withPresence) {
@@ -98,7 +107,29 @@ class EventEngine {
98107
this.engine.transition(events.restore(Array.from(new Set([...this.channels, ...(channels !== null && channels !== void 0 ? channels : [])])), Array.from(new Set([...this.groups, ...(channelGroups !== null && channelGroups !== void 0 ? channelGroups : [])])), timetoken));
99108
}
100109
else {
101-
this.engine.transition(events.subscriptionChange(Array.from(new Set([...this.channels, ...(channels !== null && channels !== void 0 ? channels : [])])), Array.from(new Set([...this.groups, ...(channelGroups !== null && channelGroups !== void 0 ? channelGroups : [])]))));
110+
if (hasNewSubscriptions) {
111+
this.engine.transition(events.subscriptionChange(Array.from(new Set([...this.channels, ...(channels !== null && channels !== void 0 ? channels : [])])), Array.from(new Set([...this.groups, ...(channelGroups !== null && channelGroups !== void 0 ? channelGroups : [])]))));
112+
}
113+
else {
114+
this.dependencies.config
115+
.logger()
116+
.debug('EventEngine', 'Skipping state transition - all channels/groups already subscribed. Emitting SubscriptionChanged event.');
117+
// Get current timetoken from state context
118+
const currentState = this.engine.currentState;
119+
const currentContext = this.engine.currentContext;
120+
let currentTimetoken = '0';
121+
if ((currentState === null || currentState === void 0 ? void 0 : currentState.label) === receiving_1.ReceivingState.label && currentContext) {
122+
const receivingContext = currentContext;
123+
currentTimetoken = (_a = receivingContext.cursor) === null || _a === void 0 ? void 0 : _a.timetoken;
124+
}
125+
// Manually emit SubscriptionChanged status event
126+
this.dependencies.emitStatus({
127+
category: categories_1.default.PNSubscriptionChangedCategory,
128+
affectedChannels: Array.from(new Set(this.channels)),
129+
affectedChannelGroups: Array.from(new Set(this.groups)),
130+
currentTimetoken,
131+
});
132+
}
102133
}
103134
if (this.dependencies.join) {
104135
this.dependencies.join({

package-lock.json

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

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": "10.2.3",
3+
"version": "10.2.4",
44
"author": "PubNub <support@pubnub.com>",
55
"description": "Publish & Subscribe Real-time Messaging with PubNub",
66
"scripts": {

src/core/components/configuration.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -236,7 +236,7 @@ export const makeConfiguration = (
236236
return base.PubNubFile;
237237
},
238238
get version(): string {
239-
return '10.2.3';
239+
return '10.2.4';
240240
},
241241
getVersion(): string {
242242
return this.version;

0 commit comments

Comments
 (0)