Skip to content

Commit

Permalink
Fix missing presence events on subscription (#419)
Browse files Browse the repository at this point in the history
fix(event-engine): fix missing presence events on subscription

Fix issue because of which presence events not delivered to the `Subscription` and
`SubscriptionSet` objects (only global listeners).
  • Loading branch information
parfeon authored Nov 18, 2024
1 parent 2b523b2 commit cf5aa71
Show file tree
Hide file tree
Showing 23 changed files with 83 additions and 58 deletions.
11 changes: 8 additions & 3 deletions .pubnub.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
---
changelog:
- date: 2024-11-18
version: v8.3.1
changes:
- type: bug
text: "Fix issue because of which presence events not delivered to the `Subscription` and `SubscriptionSet` objects (only global listeners)."
- date: 2024-11-14
version: v8.3.0
changes:
Expand Down Expand Up @@ -1067,7 +1072,7 @@ supported-platforms:
- 'Ubuntu 14.04 and up'
- 'Windows 7 and up'
version: 'Pubnub Javascript for Node'
version: '8.3.0'
version: '8.3.1'
sdks:
- full-name: PubNub Javascript SDK
short-name: Javascript
Expand All @@ -1083,7 +1088,7 @@ sdks:
- distribution-type: source
distribution-repository: GitHub release
package-name: pubnub.js
location: https://github.com/pubnub/javascript/archive/refs/tags/v8.3.0.zip
location: https://github.com/pubnub/javascript/archive/refs/tags/v8.3.1.zip
requires:
- name: 'agentkeepalive'
min-version: '3.5.2'
Expand Down Expand Up @@ -1754,7 +1759,7 @@ sdks:
- distribution-type: library
distribution-repository: GitHub release
package-name: pubnub.js
location: https://github.com/pubnub/javascript/releases/download/v8.3.0/pubnub.8.3.0.js
location: https://github.com/pubnub/javascript/releases/download/v8.3.1/pubnub.8.3.1.js
requires:
- name: 'agentkeepalive'
min-version: '3.5.2'
Expand Down
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
## v8.3.1
November 18 2024

#### Fixed
- Fix issue because of which presence events not delivered to the `Subscription` and `SubscriptionSet` objects (only global listeners).

## v8.3.0
November 14 2024

Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,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.8.3.0.js
* https://cdn.pubnub.com/sdk/javascript/pubnub.8.3.0.min.js
* https://cdn.pubnub.com/sdk/javascript/pubnub.8.3.1.js
* https://cdn.pubnub.com/sdk/javascript/pubnub.8.3.1.min.js
2. Configure your keys:
Expand Down
21 changes: 14 additions & 7 deletions dist/web/pubnub.js
Original file line number Diff line number Diff line change
Expand Up @@ -3948,7 +3948,7 @@
return base.PubNubFile;
},
get version() {
return '8.3.0';
return '8.3.1';
},
getVersion() {
return this.version;
Expand Down Expand Up @@ -6403,6 +6403,7 @@
* @param event - Received real-time event.
*/
emitEvent(event) {
var _a;
if (event.type === PubNubEventType.Message) {
this.listenerManager.announceMessage(event.data);
this.announce('message', event.data, event.data.channel, event.data.subscription);
Expand All @@ -6413,7 +6414,7 @@
}
else if (event.type === PubNubEventType.Presence) {
this.listenerManager.announcePresence(event.data);
this.announce('presence', event.data, event.data.channel, event.data.subscription);
this.announce('presence', event.data, (_a = event.data.subscription) !== null && _a !== void 0 ? _a : event.data.channel, event.data.subscription);
}
else if (event.type === PubNubEventType.AppContext) {
const { data: objectEvent } = event;
Expand Down Expand Up @@ -9963,7 +9964,7 @@
* types of events.
*/
addListener(listener) {
this.eventEmitter.addListener(listener, this.channelNames.filter((c) => !c.endsWith('-pnpres')), this.groupNames.filter((cg) => !cg.endsWith('-pnpres')));
this.eventEmitter.addListener(listener, this.channelNames, this.groupNames);
}
/**
* Remove events handler.
Expand Down Expand Up @@ -10065,7 +10066,7 @@
this.subscriptionList.push(subscription);
});
this.listener = {};
eventEmitter.addListener(this.listener, this.channelNames.filter((c) => !c.endsWith('-pnpres')), this.groupNames.filter((cg) => !cg.endsWith('-pnpres')));
eventEmitter.addListener(this.listener, this.channelNames, this.groupNames);
}
/**
* Add additional entity's subscription to the subscription set.
Expand Down Expand Up @@ -10187,7 +10188,7 @@
this.pubnub = pubnub;
this.eventEmitter = eventEmitter;
this.listener = {};
eventEmitter.addListener(this.listener, this.channelNames.filter((c) => !c.endsWith('-pnpres')), this.groupNames.filter((cg) => !cg.endsWith('-pnpres')));
eventEmitter.addListener(this.listener, this.channelNames, this.groupNames);
}
/**
* Merge entities' subscription objects into subscription set.
Expand Down Expand Up @@ -10283,9 +10284,12 @@
*/
subscription(subscriptionOptions) {
{
const channelGroups = [this.name];
if ((subscriptionOptions === null || subscriptionOptions === void 0 ? void 0 : subscriptionOptions.receivePresenceEvents) && !this.name.endsWith('-pnpres'))
channelGroups.push(`${this.name}-pnpres`);
return new Subscription({
channels: [],
channelGroups: (subscriptionOptions === null || subscriptionOptions === void 0 ? void 0 : subscriptionOptions.receivePresenceEvents) ? [this.name, `${this.name}-pnpres`] : [this.name],
channelGroups,
subscriptionOptions: subscriptionOptions,
eventEmitter: this.eventEmitter,
pubnub: this.pubnub,
Expand Down Expand Up @@ -10370,8 +10374,11 @@
*/
subscription(subscriptionOptions) {
{
const channels = [this.name];
if ((subscriptionOptions === null || subscriptionOptions === void 0 ? void 0 : subscriptionOptions.receivePresenceEvents) && !this.name.endsWith('-pnpres'))
channels.push(`${this.name}-pnpres`);
return new Subscription({
channels: (subscriptionOptions === null || subscriptionOptions === void 0 ? void 0 : subscriptionOptions.receivePresenceEvents) ? [this.name, `${this.name}-pnpres`] : [this.name],
channels,
channelGroups: [],
subscriptionOptions: subscriptionOptions,
eventEmitter: this.eventEmitter,
Expand Down
2 changes: 1 addition & 1 deletion 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 @@ -112,7 +112,7 @@ const makeConfiguration = (base, setupCryptoModule) => {
return base.PubNubFile;
},
get version() {
return '8.3.0';
return '8.3.1';
},
getVersion() {
return this.version;
Expand Down
3 changes: 2 additions & 1 deletion lib/core/components/eventEmitter.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ class EventEmitter {
* @param event - Received real-time event.
*/
emitEvent(event) {
var _a;
if (event.type === subscribe_1.PubNubEventType.Message) {
this.listenerManager.announceMessage(event.data);
this.announce('message', event.data, event.data.channel, event.data.subscription);
Expand All @@ -55,7 +56,7 @@ class EventEmitter {
}
else if (event.type === subscribe_1.PubNubEventType.Presence) {
this.listenerManager.announcePresence(event.data);
this.announce('presence', event.data, event.data.channel, event.data.subscription);
this.announce('presence', event.data, (_a = event.data.subscription) !== null && _a !== void 0 ? _a : event.data.channel, event.data.subscription);
}
else if (event.type === subscribe_1.PubNubEventType.AppContext) {
const { data: objectEvent } = event;
Expand Down
5 changes: 4 additions & 1 deletion lib/entities/Channel.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,11 @@ class Channel {
*/
subscription(subscriptionOptions) {
if (process.env.SUBSCRIBE_EVENT_ENGINE_MODULE !== 'disabled') {
const channels = [this.name];
if ((subscriptionOptions === null || subscriptionOptions === void 0 ? void 0 : subscriptionOptions.receivePresenceEvents) && !this.name.endsWith('-pnpres'))
channels.push(`${this.name}-pnpres`);
return new Subscription_1.Subscription({
channels: (subscriptionOptions === null || subscriptionOptions === void 0 ? void 0 : subscriptionOptions.receivePresenceEvents) ? [this.name, `${this.name}-pnpres`] : [this.name],
channels,
channelGroups: [],
subscriptionOptions: subscriptionOptions,
eventEmitter: this.eventEmitter,
Expand Down
5 changes: 4 additions & 1 deletion lib/entities/ChannelGroup.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,12 @@ class ChannelGroup {
*/
subscription(subscriptionOptions) {
if (process.env.SUBSCRIBE_EVENT_ENGINE_MODULE !== 'disabled') {
const channelGroups = [this.name];
if ((subscriptionOptions === null || subscriptionOptions === void 0 ? void 0 : subscriptionOptions.receivePresenceEvents) && !this.name.endsWith('-pnpres'))
channelGroups.push(`${this.name}-pnpres`);
return new Subscription_1.Subscription({
channels: [],
channelGroups: (subscriptionOptions === null || subscriptionOptions === void 0 ? void 0 : subscriptionOptions.receivePresenceEvents) ? [this.name, `${this.name}-pnpres`] : [this.name],
channelGroups,
subscriptionOptions: subscriptionOptions,
eventEmitter: this.eventEmitter,
pubnub: this.pubnub,
Expand Down
2 changes: 1 addition & 1 deletion lib/entities/SubscribeCapable.js
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ class SubscribeCapable {
* types of events.
*/
addListener(listener) {
this.eventEmitter.addListener(listener, this.channelNames.filter((c) => !c.endsWith('-pnpres')), this.groupNames.filter((cg) => !cg.endsWith('-pnpres')));
this.eventEmitter.addListener(listener, this.channelNames, this.groupNames);
}
/**
* Remove events handler.
Expand Down
2 changes: 1 addition & 1 deletion lib/entities/Subscription.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ class Subscription extends SubscribeCapable_1.SubscribeCapable {
this.pubnub = pubnub;
this.eventEmitter = eventEmitter;
this.listener = {};
eventEmitter.addListener(this.listener, this.channelNames.filter((c) => !c.endsWith('-pnpres')), this.groupNames.filter((cg) => !cg.endsWith('-pnpres')));
eventEmitter.addListener(this.listener, this.channelNames, this.groupNames);
}
/**
* Merge entities' subscription objects into subscription set.
Expand Down
2 changes: 1 addition & 1 deletion lib/entities/SubscriptionSet.js
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ class SubscriptionSet extends SubscribeCapable_1.SubscribeCapable {
this.subscriptionList.push(subscription);
});
this.listener = {};
eventEmitter.addListener(this.listener, this.channelNames.filter((c) => !c.endsWith('-pnpres')), this.groupNames.filter((cg) => !cg.endsWith('-pnpres')));
eventEmitter.addListener(this.listener, this.channelNames, this.groupNames);
}
/**
* Add additional entity's subscription to the subscription set.
Expand Down
6 changes: 3 additions & 3 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "pubnub",
"version": "8.3.0",
"version": "8.3.1",
"author": "PubNub <support@pubnub.com>",
"description": "Publish & Subscribe Real-time Messaging with PubNub",
"scripts": {
Expand Down
2 changes: 1 addition & 1 deletion src/core/components/configuration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ export const makeConfiguration = (
return base.PubNubFile;
},
get version(): string {
return '8.3.0';
return '8.3.1';
},
getVersion(): string {
return this.version;
Expand Down
2 changes: 1 addition & 1 deletion src/core/components/eventEmitter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ export default class EventEmitter {
this.announce('signal', event.data, event.data.channel, event.data.subscription);
} else if (event.type === PubNubEventType.Presence) {
this.listenerManager.announcePresence(event.data);
this.announce('presence', event.data, event.data.channel, event.data.subscription);
this.announce('presence', event.data, event.data.subscription ?? event.data.channel, event.data.subscription);
} else if (event.type === PubNubEventType.AppContext) {
const { data: objectEvent } = event;
const { message: object } = objectEvent;
Expand Down
6 changes: 5 additions & 1 deletion src/entities/Channel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,12 @@ export class Channel {
*/
subscription(subscriptionOptions?: SubscriptionOptions) {
if (process.env.SUBSCRIBE_EVENT_ENGINE_MODULE !== 'disabled') {
const channels = [this.name];
if (subscriptionOptions?.receivePresenceEvents && !this.name.endsWith('-pnpres'))
channels.push(`${this.name}-pnpres`);

return new Subscription({
channels: subscriptionOptions?.receivePresenceEvents ? [this.name, `${this.name}-pnpres`] : [this.name],
channels,
channelGroups: [],
subscriptionOptions: subscriptionOptions,
eventEmitter: this.eventEmitter,
Expand Down
6 changes: 5 additions & 1 deletion src/entities/ChannelGroup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,9 +59,13 @@ export class ChannelGroup {
*/
subscription(subscriptionOptions?: SubscriptionOptions) {
if (process.env.SUBSCRIBE_EVENT_ENGINE_MODULE !== 'disabled') {
const channelGroups = [this.name];
if (subscriptionOptions?.receivePresenceEvents && !this.name.endsWith('-pnpres'))
channelGroups.push(`${this.name}-pnpres`);

return new Subscription({
channels: [],
channelGroups: subscriptionOptions?.receivePresenceEvents ? [this.name, `${this.name}-pnpres`] : [this.name],
channelGroups,
subscriptionOptions: subscriptionOptions,
eventEmitter: this.eventEmitter,
pubnub: this.pubnub,
Expand Down
6 changes: 1 addition & 5 deletions src/entities/SubscribeCapable.ts
Original file line number Diff line number Diff line change
Expand Up @@ -141,11 +141,7 @@ export abstract class SubscribeCapable {
* types of events.
*/
addListener(listener: Listener) {
this.eventEmitter.addListener(
listener,
this.channelNames.filter((c) => !c.endsWith('-pnpres')),
this.groupNames.filter((cg) => !cg.endsWith('-pnpres')),
);
this.eventEmitter.addListener(listener, this.channelNames, this.groupNames);
}

/**
Expand Down
6 changes: 1 addition & 5 deletions src/entities/Subscription.ts
Original file line number Diff line number Diff line change
Expand Up @@ -99,11 +99,7 @@ export class Subscription extends SubscribeCapable {
this.pubnub = pubnub;
this.eventEmitter = eventEmitter;
this.listener = {};
eventEmitter.addListener(
this.listener,
this.channelNames.filter((c) => !c.endsWith('-pnpres')),
this.groupNames.filter((cg) => !cg.endsWith('-pnpres')),
);
eventEmitter.addListener(this.listener, this.channelNames, this.groupNames);
}

/**
Expand Down
6 changes: 1 addition & 5 deletions src/entities/SubscriptionSet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -123,11 +123,7 @@ export class SubscriptionSet extends SubscribeCapable {
this.subscriptionList.push(subscription);
});
this.listener = {};
eventEmitter.addListener(
this.listener,
this.channelNames.filter((c) => !c.endsWith('-pnpres')),
this.groupNames.filter((cg) => !cg.endsWith('-pnpres')),
);
eventEmitter.addListener(this.listener, this.channelNames, this.groupNames);
}

/**
Expand Down
4 changes: 3 additions & 1 deletion test/integration/endpoints/fetch_messages.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -355,14 +355,16 @@ describe('fetch messages endpoints', () => {
assert(errorCatched);
});

it.only('supports custom message type', (done) => {
it('supports custom message type', (done) => {
const channel = PubNub.generateUUID();
const expectedMessagesCount = 2;

publishMessagesToChannel(pubnub, expectedMessagesCount, channel, 'test-message-type', (messages) => {
const messageTimetokens = messages.map((message) => message.timetoken);

pubnub.fetchMessages({ channels: [channel], includeCustomMessageType: true }, (status, response) => {
assert.equal(status.error, false, `Fetch messages error: ${JSON.stringify(status.errorData)}`);

try {
assert.equal(status.error, false);
assert(response !== null);
Expand Down
30 changes: 16 additions & 14 deletions test/integration/endpoints/publish.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,7 @@ describe('publish endpoints', () => {
});
});

it('supports customMessageType', (done) => {
it.only('supports customMessageType', (done) => {
const scope = utils
.createNock()
.get('/publish/myPublishKey/mySubKey/0/ch1/0/%7B%22such%22%3A%22object%22%7D')
Expand All @@ -219,22 +219,24 @@ describe('publish endpoints', () => {
uuid: 'myUUID',
auth: 'myAuthKey',
store: '0',
custom_message_type: 'test-message-type',
})
.reply(200, '[1,"Sent","14647523059145592"]', { 'content-type': 'text/javascript' });

pubnub.setCipherKey('myCipherKey');

pubnub.publish({ message: { such: 'object' }, channel: 'ch1', storeInHistory: false }, (status, response) => {
try {
assert.equal(status.error, false);
assert(response !== null);
assert.deepEqual(response.timetoken, '14647523059145592');
assert.equal(scope.isDone(), true);
done();
} catch (error) {
done(error);
}
});
pubnub.publish(
{ message: { such: 'object' }, channel: 'ch1', storeInHistory: false, customMessageType: 'test-message-type' },
(status, response) => {
try {
assert.equal(status.error, false, `Message publish error: ${JSON.stringify(status.errorData)}`);
assert(response !== null);
assert.deepEqual(response.timetoken, '14647523059145592');
assert.equal(scope.isDone(), true);
done();
} catch (error) {
done(error);
}
},
);
});

it('publishes a complex object via POST', (done) => {
Expand Down

0 comments on commit cf5aa71

Please sign in to comment.