Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 10 additions & 3 deletions .pubnub.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
---
changelog:
- date: 2025-04-22
version: v9.5.2
changes:
- type: bug
text: "Fixed issue because of which client retried for both bad request and access denied."
- type: improvement
text: "Add current list of channels and groups to connected status."
- date: 2025-04-15
version: v9.5.1
changes:
Expand Down Expand Up @@ -1229,7 +1236,7 @@ supported-platforms:
- 'Ubuntu 14.04 and up'
- 'Windows 7 and up'
version: 'Pubnub Javascript for Node'
version: '9.5.1'
version: '9.5.2'
sdks:
- full-name: PubNub Javascript SDK
short-name: Javascript
Expand All @@ -1245,7 +1252,7 @@ sdks:
- distribution-type: source
distribution-repository: GitHub release
package-name: pubnub.js
location: https://github.com/pubnub/javascript/archive/refs/tags/v9.5.1.zip
location: https://github.com/pubnub/javascript/archive/refs/tags/v9.5.2.zip
requires:
- name: 'agentkeepalive'
min-version: '3.5.2'
Expand Down Expand Up @@ -1916,7 +1923,7 @@ sdks:
- distribution-type: library
distribution-repository: GitHub release
package-name: pubnub.js
location: https://github.com/pubnub/javascript/releases/download/v9.5.1/pubnub.9.5.1.js
location: https://github.com/pubnub/javascript/releases/download/v9.5.2/pubnub.9.5.2.js
requires:
- name: 'agentkeepalive'
min-version: '3.5.2'
Expand Down
9 changes: 9 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,12 @@
## v9.5.2
April 22 2025

#### Fixed
- Fixed issue because of which client retried for both bad request and access denied.

#### Modified
- Add current list of channels and groups to connected status.

## v9.5.1
April 15 2025

Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@ Watch [Getting Started with PubNub JS SDK](https://app.dashcam.io/replay/64ee0d2
npm install pubnub
```
* or download one of our builds from our CDN:
* https://cdn.pubnub.com/sdk/javascript/pubnub.9.5.1.js
* https://cdn.pubnub.com/sdk/javascript/pubnub.9.5.1.min.js
* https://cdn.pubnub.com/sdk/javascript/pubnub.9.5.2.js
* https://cdn.pubnub.com/sdk/javascript/pubnub.9.5.2.min.js

2. Configure your keys:

Expand Down
177 changes: 122 additions & 55 deletions dist/web/pubnub.js

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions dist/web/pubnub.min.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion lib/core/components/configuration.js
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ const makeConfiguration = (base, setupCryptoModule) => {
return base.PubNubFile;
},
get version() {
return '9.5.1';
return '9.5.2';
},
getVersion() {
return this.version;
Expand Down
10 changes: 7 additions & 3 deletions lib/core/components/retryPolicy.js
Original file line number Diff line number Diff line change
Expand Up @@ -203,9 +203,13 @@ exports.RetryPolicy = RetryPolicy;
* @internal
*/
const isRetriableRequest = (req, res, errorCategory, retryAttempt, maximumRetry, excluded) => {
if (errorCategory && errorCategory === categories_1.default.PNCancelledCategory)
return false;
else if (isExcludedRequest(req, excluded))
if (errorCategory) {
if (errorCategory === categories_1.default.PNCancelledCategory ||
errorCategory === categories_1.default.PNBadRequestCategory ||
errorCategory === categories_1.default.PNAccessDeniedCategory)
return false;
}
if (isExcludedRequest(req, excluded))
return false;
else if (retryAttempt > maximumRetry)
return false;
Expand Down
16 changes: 8 additions & 8 deletions lib/core/pubnub-common.js
Original file line number Diff line number Diff line change
Expand Up @@ -636,11 +636,11 @@ class PubNubCore {
this.subscriptionManager.disconnect();
}
else if (this.eventEngine)
this.eventEngine.dispose();
if (process.env.PRESENCE_MODULE !== 'disabled') {
if (this.presenceEventEngine)
this.presenceEventEngine.dispose();
}
this.eventEngine.unsubscribeAll(isOffline);
}
if (process.env.PRESENCE_MODULE !== 'disabled') {
if (this.presenceEventEngine)
this.presenceEventEngine.leaveAll(isOffline);
}
}
/**
Expand Down Expand Up @@ -1417,11 +1417,11 @@ class PubNubCore {
*
* @param parameters - List of channels and groups where `leave` event should be sent.
*/
leaveAll(parameters) {
leaveAll(parameters = {}) {
if (process.env.PRESENCE_MODULE !== 'disabled') {
if (this.presenceEventEngine)
this.presenceEventEngine.leaveAll();
else
this.presenceEventEngine.leaveAll(parameters.isOffline);
else if (!parameters.isOffline)
this.makeUnsubscribe({ channels: parameters.channels, channelGroups: parameters.groups }, () => { });
}
else
Expand Down
3 changes: 2 additions & 1 deletion lib/event-engine/events.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,10 @@ const core_1 = require("./core");
*
* @internal
*/
exports.subscriptionChange = (0, core_1.createEvent)('SUBSCRIPTION_CHANGED', (channels, groups) => ({
exports.subscriptionChange = (0, core_1.createEvent)('SUBSCRIPTION_CHANGED', (channels, groups, isOffline) => ({
channels,
groups,
isOffline,
}));
/**
* Subscription loop restore.
Expand Down
6 changes: 3 additions & 3 deletions lib/event-engine/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ class EventEngine {
}
}
}
unsubscribeAll() {
unsubscribeAll(isOffline) {
const channelGroups = this.getSubscribedChannels();
const channels = this.getSubscribedChannels();
this.channels = [];
Expand All @@ -124,9 +124,9 @@ class EventEngine {
delete this.dependencies.presenceState[objectName];
});
}
this.engine.transition(events.subscriptionChange(this.channels.slice(0), this.groups.slice(0)));
this.engine.transition(events.subscriptionChange(this.channels.slice(0), this.groups.slice(0), isOffline));
if (this.dependencies.leaveAll)
this.dependencies.leaveAll({ channels, groups: channelGroups });
this.dependencies.leaveAll({ channels, groups: channelGroups, isOffline });
}
reconnect({ timetoken, region }) {
const channelGroups = this.getSubscribedChannels();
Expand Down
2 changes: 1 addition & 1 deletion lib/event-engine/presence/events.js
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ exports.left = (0, core_1.createEvent)('LEFT', (channels, groups) => ({
*
* @internal
*/
exports.leftAll = (0, core_1.createEvent)('LEFT_ALL', () => ({}));
exports.leftAll = (0, core_1.createEvent)('LEFT_ALL', (isOffline) => ({ isOffline }));
/**
* Presence heartbeat success event.
*
Expand Down
4 changes: 2 additions & 2 deletions lib/event-engine/presence/presence.js
Original file line number Diff line number Diff line change
Expand Up @@ -77,8 +77,8 @@ class PresenceEventEngine {
}
this.engine.transition(events.left(channels !== null && channels !== void 0 ? channels : [], groups !== null && groups !== void 0 ? groups : []));
}
leaveAll() {
this.engine.transition(events.leftAll());
leaveAll(isOffline) {
this.engine.transition(events.leftAll(isOffline));
}
reconnect() {
this.engine.transition(events.reconnect());
Expand Down
4 changes: 3 additions & 1 deletion lib/event-engine/presence/states/heartbeat_cooldown.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,4 +37,6 @@ exports.HeartbeatCooldownState.on(events_1.left.type, (context, event) => heartb
exports.HeartbeatCooldownState.on(events_1.disconnect.type, (context, event) => heartbeat_stopped_1.HeartbeatStoppedState.with({ channels: context.channels, groups: context.groups }, [
...(!event.payload.isOffline ? [(0, effects_1.leave)(context.channels, context.groups)] : []),
]));
exports.HeartbeatCooldownState.on(events_1.leftAll.type, (context, _) => heartbeat_inactive_1.HeartbeatInactiveState.with(undefined, [(0, effects_1.leave)(context.channels, context.groups)]));
exports.HeartbeatCooldownState.on(events_1.leftAll.type, (context, event) => heartbeat_inactive_1.HeartbeatInactiveState.with(undefined, [
...(!event.payload.isOffline ? [(0, effects_1.leave)(context.channels, context.groups)] : []),
]));
4 changes: 3 additions & 1 deletion lib/event-engine/presence/states/heartbeat_failed.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,4 +36,6 @@ exports.HeartbeatFailedState.on(events_1.reconnect.type, (context, _) => heartbe
exports.HeartbeatFailedState.on(events_1.disconnect.type, (context, event) => heartbeat_stopped_1.HeartbeatStoppedState.with({ channels: context.channels, groups: context.groups }, [
...(!event.payload.isOffline ? [(0, effects_1.leave)(context.channels, context.groups)] : []),
]));
exports.HeartbeatFailedState.on(events_1.leftAll.type, (context, _) => heartbeat_inactive_1.HeartbeatInactiveState.with(undefined, [(0, effects_1.leave)(context.channels, context.groups)]));
exports.HeartbeatFailedState.on(events_1.leftAll.type, (context, event) => heartbeat_inactive_1.HeartbeatInactiveState.with(undefined, [
...(!event.payload.isOffline ? [(0, effects_1.leave)(context.channels, context.groups)] : []),
]));
4 changes: 3 additions & 1 deletion lib/event-engine/presence/states/heartbeating.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,4 +42,6 @@ exports.HeartbeatingState.on(events_1.heartbeatFailure.type, (context, event) =>
exports.HeartbeatingState.on(events_1.disconnect.type, (context, event) => heartbeat_stopped_1.HeartbeatStoppedState.with({ channels: context.channels, groups: context.groups }, [
...(!event.payload.isOffline ? [(0, effects_1.leave)(context.channels, context.groups)] : []),
]));
exports.HeartbeatingState.on(events_1.leftAll.type, (context, _) => heartbeat_inactive_1.HeartbeatInactiveState.with(undefined, [(0, effects_1.leave)(context.channels, context.groups)]));
exports.HeartbeatingState.on(events_1.leftAll.type, (context, event) => heartbeat_inactive_1.HeartbeatInactiveState.with(undefined, [
...(!event.payload.isOffline ? [(0, effects_1.leave)(context.channels, context.groups)] : []),
]));
8 changes: 7 additions & 1 deletion lib/event-engine/states/handshake_failed.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,20 @@ const unsubscribed_1 = require("./unsubscribed");
* @internal
*/
exports.HandshakeFailedState = new state_1.State('HANDSHAKE_FAILED');
exports.HandshakeFailedState.on(events_1.subscriptionChange.type, (context, { payload }) => handshaking_1.HandshakingState.with({ channels: payload.channels, groups: payload.groups, cursor: context.cursor }));
exports.HandshakeFailedState.on(events_1.subscriptionChange.type, (context, { payload }) => {
if (payload.channels.length === 0 && payload.groups.length === 0)
return unsubscribed_1.UnsubscribedState.with(undefined);
return handshaking_1.HandshakingState.with({ channels: payload.channels, groups: payload.groups, cursor: context.cursor });
});
exports.HandshakeFailedState.on(events_1.reconnect.type, (context, { payload }) => handshaking_1.HandshakingState.with({
channels: context.channels,
groups: context.groups,
cursor: payload.cursor || context.cursor,
}));
exports.HandshakeFailedState.on(events_1.restore.type, (context, { payload }) => {
var _a, _b;
if (payload.channels.length === 0 && payload.groups.length === 0)
return unsubscribed_1.UnsubscribedState.with(undefined);
return handshaking_1.HandshakingState.with({
channels: payload.channels,
groups: payload.groups,
Expand Down
8 changes: 7 additions & 1 deletion lib/event-engine/states/handshake_stopped.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,16 @@ const unsubscribed_1 = require("./unsubscribed");
* @internal
*/
exports.HandshakeStoppedState = new state_1.State('HANDSHAKE_STOPPED');
exports.HandshakeStoppedState.on(events_1.subscriptionChange.type, (context, { payload }) => exports.HandshakeStoppedState.with({ channels: payload.channels, groups: payload.groups, cursor: context.cursor }));
exports.HandshakeStoppedState.on(events_1.subscriptionChange.type, (context, { payload }) => {
if (payload.channels.length === 0 && payload.groups.length === 0)
return unsubscribed_1.UnsubscribedState.with(undefined);
return exports.HandshakeStoppedState.with({ channels: payload.channels, groups: payload.groups, cursor: context.cursor });
});
exports.HandshakeStoppedState.on(events_1.reconnect.type, (context, { payload }) => handshaking_1.HandshakingState.with(Object.assign(Object.assign({}, context), { cursor: payload.cursor || context.cursor })));
exports.HandshakeStoppedState.on(events_1.restore.type, (context, { payload }) => {
var _a;
if (payload.channels.length === 0 && payload.groups.length === 0)
return unsubscribed_1.UnsubscribedState.with(undefined);
return exports.HandshakeStoppedState.with({
channels: payload.channels,
groups: payload.groups,
Expand Down
13 changes: 11 additions & 2 deletions lib/event-engine/states/handshaking.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,15 +36,22 @@ exports.HandshakingState.on(events_1.subscriptionChange.type, (context, { payloa
return exports.HandshakingState.with({ channels: payload.channels, groups: payload.groups, cursor: context.cursor });
});
exports.HandshakingState.on(events_1.handshakeSuccess.type, (context, { payload }) => {
var _a, _b;
var _a, _b, _c, _d;
return receiving_1.ReceivingState.with({
channels: context.channels,
groups: context.groups,
cursor: {
timetoken: !!((_a = context.cursor) === null || _a === void 0 ? void 0 : _a.timetoken) ? (_b = context.cursor) === null || _b === void 0 ? void 0 : _b.timetoken : payload.timetoken,
region: payload.region,
},
}, [(0, effects_1.emitStatus)({ category: categories_1.default.PNConnectedCategory })]);
}, [
(0, effects_1.emitStatus)({
category: categories_1.default.PNConnectedCategory,
affectedChannels: context.channels.slice(0),
affectedChannelGroups: context.groups.slice(0),
currentTimetoken: !!((_c = context.cursor) === null || _c === void 0 ? void 0 : _c.timetoken) ? (_d = context.cursor) === null || _d === void 0 ? void 0 : _d.timetoken : payload.timetoken,
}),
]);
});
exports.HandshakingState.on(events_1.handshakeFailure.type, (context, event) => {
var _a;
Expand All @@ -71,6 +78,8 @@ exports.HandshakingState.on(events_1.disconnect.type, (context, event) => {
});
exports.HandshakingState.on(events_1.restore.type, (context, { payload }) => {
var _a;
if (payload.channels.length === 0 && payload.groups.length === 0)
return unsubscribed_1.UnsubscribedState.with(undefined);
return exports.HandshakingState.with({
channels: payload.channels,
groups: payload.groups,
Expand Down
20 changes: 14 additions & 6 deletions lib/event-engine/states/receive_failed.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,18 @@ exports.ReceiveFailedState.on(events_1.reconnect.type, (context, { payload }) =>
},
});
});
exports.ReceiveFailedState.on(events_1.subscriptionChange.type, (context, { payload }) => handshaking_1.HandshakingState.with({ channels: payload.channels, groups: payload.groups, cursor: context.cursor }));
exports.ReceiveFailedState.on(events_1.restore.type, (context, { payload }) => handshaking_1.HandshakingState.with({
channels: payload.channels,
groups: payload.groups,
cursor: { timetoken: payload.cursor.timetoken, region: payload.cursor.region || context.cursor.region },
}));
exports.ReceiveFailedState.on(events_1.subscriptionChange.type, (context, { payload }) => {
if (payload.channels.length === 0 && payload.groups.length === 0)
return unsubscribed_1.UnsubscribedState.with(undefined);
return handshaking_1.HandshakingState.with({ channels: payload.channels, groups: payload.groups, cursor: context.cursor });
});
exports.ReceiveFailedState.on(events_1.restore.type, (context, { payload }) => {
if (payload.channels.length === 0 && payload.groups.length === 0)
return unsubscribed_1.UnsubscribedState.with(undefined);
return handshaking_1.HandshakingState.with({
channels: payload.channels,
groups: payload.groups,
cursor: { timetoken: payload.cursor.timetoken, region: payload.cursor.region || context.cursor.region },
});
});
exports.ReceiveFailedState.on(events_1.unsubscribeAll.type, (_) => unsubscribed_1.UnsubscribedState.with(undefined));
20 changes: 14 additions & 6 deletions lib/event-engine/states/receive_stopped.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,20 @@ const unsubscribed_1 = require("./unsubscribed");
* @internal
*/
exports.ReceiveStoppedState = new state_1.State('RECEIVE_STOPPED');
exports.ReceiveStoppedState.on(events_1.subscriptionChange.type, (context, { payload }) => exports.ReceiveStoppedState.with({ channels: payload.channels, groups: payload.groups, cursor: context.cursor }));
exports.ReceiveStoppedState.on(events_1.restore.type, (context, { payload }) => exports.ReceiveStoppedState.with({
channels: payload.channels,
groups: payload.groups,
cursor: { timetoken: payload.cursor.timetoken, region: payload.cursor.region || context.cursor.region },
}));
exports.ReceiveStoppedState.on(events_1.subscriptionChange.type, (context, { payload }) => {
if (payload.channels.length === 0 && payload.groups.length === 0)
return unsubscribed_1.UnsubscribedState.with(undefined);
return exports.ReceiveStoppedState.with({ channels: payload.channels, groups: payload.groups, cursor: context.cursor });
});
exports.ReceiveStoppedState.on(events_1.restore.type, (context, { payload }) => {
if (payload.channels.length === 0 && payload.groups.length === 0)
return unsubscribed_1.UnsubscribedState.with(undefined);
return exports.ReceiveStoppedState.with({
channels: payload.channels,
groups: payload.groups,
cursor: { timetoken: payload.cursor.timetoken, region: payload.cursor.region || context.cursor.region },
});
});
exports.ReceiveStoppedState.on(events_1.reconnect.type, (context, { payload }) => {
var _a;
return handshaking_1.HandshakingState.with({
Expand Down
Loading
Loading