@eleven-am/pondsocket-client 0.0.14 → 0.0.15
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/browser/client.js +13 -2
- package/core/channel.js +113 -124
- package/core/channel.test.js +207 -228
- package/dist.d.ts +24 -45
- package/package.json +1 -1
package/browser/client.js
CHANGED
|
@@ -10,7 +10,7 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
|
|
|
10
10
|
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
11
11
|
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
12
12
|
};
|
|
13
|
-
var _PondClient_instances, _PondClient_channels, _PondClient_createPublisher;
|
|
13
|
+
var _PondClient_instances, _PondClient_channels, _PondClient_createPublisher, _PondClient_handleAcknowledge, _PondClient_init;
|
|
14
14
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
15
|
const pondsocket_common_1 = require("@eleven-am/pondsocket-common");
|
|
16
16
|
const channel_1 = require("../core/channel");
|
|
@@ -36,6 +36,7 @@ class PondClient {
|
|
|
36
36
|
__classPrivateFieldSet(this, _PondClient_channels, {}, "f");
|
|
37
37
|
this._broadcaster = new pondsocket_common_1.Subject();
|
|
38
38
|
this._connectionState = new pondsocket_common_1.BehaviorSubject(false);
|
|
39
|
+
__classPrivateFieldGet(this, _PondClient_instances, "m", _PondClient_init).call(this);
|
|
39
40
|
}
|
|
40
41
|
/**
|
|
41
42
|
* @desc Connects to the server and returns the socket.
|
|
@@ -83,7 +84,7 @@ class PondClient {
|
|
|
83
84
|
return __classPrivateFieldGet(this, _PondClient_channels, "f")[name];
|
|
84
85
|
}
|
|
85
86
|
const publisher = __classPrivateFieldGet(this, _PondClient_instances, "m", _PondClient_createPublisher).call(this);
|
|
86
|
-
const channel = new channel_1.Channel(publisher, this._connectionState, name,
|
|
87
|
+
const channel = new channel_1.Channel(publisher, this._connectionState, name, params || {});
|
|
87
88
|
__classPrivateFieldGet(this, _PondClient_channels, "f")[name] = channel;
|
|
88
89
|
return channel;
|
|
89
90
|
}
|
|
@@ -101,5 +102,15 @@ _PondClient_channels = new WeakMap(), _PondClient_instances = new WeakSet(), _Po
|
|
|
101
102
|
this._socket.send(JSON.stringify(message));
|
|
102
103
|
}
|
|
103
104
|
};
|
|
105
|
+
}, _PondClient_handleAcknowledge = function _PondClient_handleAcknowledge(message) {
|
|
106
|
+
var _a;
|
|
107
|
+
const channel = (_a = __classPrivateFieldGet(this, _PondClient_channels, "f")[message.channelName]) !== null && _a !== void 0 ? _a : new channel_1.Channel(__classPrivateFieldGet(this, _PondClient_instances, "m", _PondClient_createPublisher).call(this), this._connectionState, message.channelName, {});
|
|
108
|
+
channel.acknowledge(this._broadcaster);
|
|
109
|
+
}, _PondClient_init = function _PondClient_init() {
|
|
110
|
+
this._broadcaster.subscribe((message) => {
|
|
111
|
+
if (message.event === pondsocket_common_1.Events.ACKNOWLEDGE) {
|
|
112
|
+
__classPrivateFieldGet(this, _PondClient_instances, "m", _PondClient_handleAcknowledge).call(this, message);
|
|
113
|
+
}
|
|
114
|
+
});
|
|
104
115
|
};
|
|
105
116
|
exports.default = PondClient;
|
package/core/channel.js
CHANGED
|
@@ -10,19 +10,19 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
|
|
|
10
10
|
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
11
11
|
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
12
12
|
};
|
|
13
|
-
var _Channel_instances, _Channel_name, _Channel_queue, _Channel_presence, _Channel_publisher, _Channel_joinParams,
|
|
13
|
+
var _Channel_instances, _Channel_name, _Channel_queue, _Channel_presence, _Channel_presenceSub, _Channel_publisher, _Channel_joinParams, _Channel_receiver, _Channel_clientState, _Channel_joinState, _Channel_emptyQueue, _Channel_init, _Channel_onMessage, _Channel_publish, _Channel_subscribeToPresence;
|
|
14
14
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
15
|
exports.Channel = void 0;
|
|
16
16
|
const pondsocket_common_1 = require("@eleven-am/pondsocket-common");
|
|
17
17
|
class Channel {
|
|
18
|
-
constructor(publisher, clientState, name,
|
|
18
|
+
constructor(publisher, clientState, name, params) {
|
|
19
19
|
_Channel_instances.add(this);
|
|
20
20
|
_Channel_name.set(this, void 0);
|
|
21
21
|
_Channel_queue.set(this, void 0);
|
|
22
22
|
_Channel_presence.set(this, void 0);
|
|
23
|
+
_Channel_presenceSub.set(this, void 0);
|
|
23
24
|
_Channel_publisher.set(this, void 0);
|
|
24
25
|
_Channel_joinParams.set(this, void 0);
|
|
25
|
-
_Channel_presenceSub.set(this, void 0);
|
|
26
26
|
_Channel_receiver.set(this, void 0);
|
|
27
27
|
_Channel_clientState.set(this, void 0);
|
|
28
28
|
_Channel_joinState.set(this, void 0);
|
|
@@ -34,7 +34,9 @@ class Channel {
|
|
|
34
34
|
__classPrivateFieldSet(this, _Channel_clientState, clientState, "f");
|
|
35
35
|
__classPrivateFieldSet(this, _Channel_receiver, new pondsocket_common_1.Subject(), "f");
|
|
36
36
|
__classPrivateFieldSet(this, _Channel_joinState, new pondsocket_common_1.BehaviorSubject(pondsocket_common_1.ChannelState.IDLE), "f");
|
|
37
|
-
__classPrivateFieldSet(this, _Channel_presenceSub,
|
|
37
|
+
__classPrivateFieldSet(this, _Channel_presenceSub, () => {
|
|
38
|
+
// do nothing
|
|
39
|
+
}, "f");
|
|
38
40
|
}
|
|
39
41
|
/**
|
|
40
42
|
* @desc Gets the current connection state of the channel.
|
|
@@ -42,58 +44,65 @@ class Channel {
|
|
|
42
44
|
get channelState() {
|
|
43
45
|
return __classPrivateFieldGet(this, _Channel_joinState, "f").value;
|
|
44
46
|
}
|
|
47
|
+
/**
|
|
48
|
+
* @desc Gets the current presence of the channel.
|
|
49
|
+
*/
|
|
50
|
+
get presence() {
|
|
51
|
+
return __classPrivateFieldGet(this, _Channel_presence, "f");
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* @desc Acknowledges the channel has been joined on the server.
|
|
55
|
+
* @param receiver - The receiver to subscribe to.
|
|
56
|
+
*/
|
|
57
|
+
acknowledge(receiver) {
|
|
58
|
+
__classPrivateFieldGet(this, _Channel_joinState, "f").publish(pondsocket_common_1.ChannelState.JOINED);
|
|
59
|
+
__classPrivateFieldGet(this, _Channel_instances, "m", _Channel_init).call(this, receiver);
|
|
60
|
+
__classPrivateFieldGet(this, _Channel_instances, "m", _Channel_emptyQueue).call(this);
|
|
61
|
+
}
|
|
45
62
|
/**
|
|
46
63
|
* @desc Connects to the channel.
|
|
47
64
|
*/
|
|
48
65
|
join() {
|
|
49
|
-
|
|
50
|
-
|
|
66
|
+
const message = {
|
|
67
|
+
action: pondsocket_common_1.ClientActions.JOIN_CHANNEL,
|
|
68
|
+
event: pondsocket_common_1.ClientActions.JOIN_CHANNEL,
|
|
69
|
+
payload: __classPrivateFieldGet(this, _Channel_joinParams, "f"),
|
|
70
|
+
channelName: __classPrivateFieldGet(this, _Channel_name, "f"),
|
|
71
|
+
requestId: (0, pondsocket_common_1.uuid)(),
|
|
72
|
+
};
|
|
73
|
+
if (__classPrivateFieldGet(this, _Channel_joinState, "f").value === pondsocket_common_1.ChannelState.JOINED) {
|
|
74
|
+
return;
|
|
51
75
|
}
|
|
52
|
-
const joinMessage = __classPrivateFieldGet(this, _Channel_instances, "m", _Channel_buildJoinMessage).call(this);
|
|
53
76
|
__classPrivateFieldGet(this, _Channel_joinState, "f").publish(pondsocket_common_1.ChannelState.JOINING);
|
|
54
77
|
if (__classPrivateFieldGet(this, _Channel_clientState, "f").value) {
|
|
55
|
-
__classPrivateFieldGet(this, _Channel_publisher, "f").call(this,
|
|
78
|
+
__classPrivateFieldGet(this, _Channel_publisher, "f").call(this, message);
|
|
56
79
|
}
|
|
57
80
|
else {
|
|
58
|
-
__classPrivateFieldGet(this,
|
|
81
|
+
const unsubscribe = __classPrivateFieldGet(this, _Channel_clientState, "f").subscribe((state) => {
|
|
82
|
+
if (state) {
|
|
83
|
+
unsubscribe();
|
|
84
|
+
if (__classPrivateFieldGet(this, _Channel_joinState, "f").value === pondsocket_common_1.ChannelState.JOINING) {
|
|
85
|
+
__classPrivateFieldGet(this, _Channel_publisher, "f").call(this, message);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
});
|
|
59
89
|
}
|
|
60
90
|
}
|
|
61
91
|
/**
|
|
62
92
|
* @desc Disconnects from the channel.
|
|
63
93
|
*/
|
|
64
94
|
leave() {
|
|
65
|
-
const
|
|
95
|
+
const message = {
|
|
66
96
|
action: pondsocket_common_1.ClientActions.LEAVE_CHANNEL,
|
|
67
97
|
event: pondsocket_common_1.ClientActions.LEAVE_CHANNEL,
|
|
68
98
|
channelName: __classPrivateFieldGet(this, _Channel_name, "f"),
|
|
69
99
|
requestId: (0, pondsocket_common_1.uuid)(),
|
|
70
100
|
payload: {},
|
|
71
101
|
};
|
|
72
|
-
__classPrivateFieldGet(this, _Channel_instances, "m", _Channel_publish).call(this,
|
|
102
|
+
__classPrivateFieldGet(this, _Channel_instances, "m", _Channel_publish).call(this, message);
|
|
73
103
|
__classPrivateFieldGet(this, _Channel_joinState, "f").publish(pondsocket_common_1.ChannelState.CLOSED);
|
|
74
104
|
__classPrivateFieldGet(this, _Channel_presenceSub, "f").call(this);
|
|
75
105
|
}
|
|
76
|
-
/**
|
|
77
|
-
* @desc Monitors the channel for messages.
|
|
78
|
-
* @param callback - The callback to call when a message is received.
|
|
79
|
-
*/
|
|
80
|
-
onMessage(callback) {
|
|
81
|
-
return __classPrivateFieldGet(this, _Channel_instances, "m", _Channel_onMessage).call(this, (event, message) => {
|
|
82
|
-
callback(event, message);
|
|
83
|
-
});
|
|
84
|
-
}
|
|
85
|
-
/**
|
|
86
|
-
* @desc Monitors the channel for messages.
|
|
87
|
-
* @param event - The event to monitor.
|
|
88
|
-
* @param callback - The callback to call when a message is received.
|
|
89
|
-
*/
|
|
90
|
-
onMessageEvent(event, callback) {
|
|
91
|
-
return this.onMessage((eventReceived, message) => {
|
|
92
|
-
if (eventReceived === event) {
|
|
93
|
-
return callback(message);
|
|
94
|
-
}
|
|
95
|
-
});
|
|
96
|
-
}
|
|
97
106
|
/**
|
|
98
107
|
* @desc Monitors the channel state of the channel.
|
|
99
108
|
* @param callback - The callback to call when the connection state changes.
|
|
@@ -125,6 +134,27 @@ class Channel {
|
|
|
125
134
|
}
|
|
126
135
|
});
|
|
127
136
|
}
|
|
137
|
+
/**
|
|
138
|
+
* @desc Monitors the channel for messages.
|
|
139
|
+
* @param callback - The callback to call when a message is received.
|
|
140
|
+
*/
|
|
141
|
+
onMessage(callback) {
|
|
142
|
+
return __classPrivateFieldGet(this, _Channel_instances, "m", _Channel_onMessage).call(this, (event, message) => {
|
|
143
|
+
callback(event, message);
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* @desc Monitors the channel for messages.
|
|
148
|
+
* @param event - The event to monitor.
|
|
149
|
+
* @param callback - The callback to call when a message is received.
|
|
150
|
+
*/
|
|
151
|
+
onMessageEvent(event, callback) {
|
|
152
|
+
return this.onMessage((eventReceived, message) => {
|
|
153
|
+
if (eventReceived === event) {
|
|
154
|
+
return callback(message);
|
|
155
|
+
}
|
|
156
|
+
});
|
|
157
|
+
}
|
|
128
158
|
/**
|
|
129
159
|
* @desc Detects when clients change their presence in the channel.
|
|
130
160
|
* @param callback - The callback to call when a client changes their presence in the channel.
|
|
@@ -136,6 +166,13 @@ class Channel {
|
|
|
136
166
|
}
|
|
137
167
|
});
|
|
138
168
|
}
|
|
169
|
+
/**
|
|
170
|
+
* @desc Monitors the presence of the channel.
|
|
171
|
+
* @param callback - The callback to call when the presence changes.
|
|
172
|
+
*/
|
|
173
|
+
onUsersChange(callback) {
|
|
174
|
+
return __classPrivateFieldGet(this, _Channel_instances, "m", _Channel_subscribeToPresence).call(this, (_event, payload) => callback(payload.presence));
|
|
175
|
+
}
|
|
139
176
|
/**
|
|
140
177
|
* @desc Sends a message to specific clients in the channel.
|
|
141
178
|
* @param event - The event to send.
|
|
@@ -143,7 +180,14 @@ class Channel {
|
|
|
143
180
|
*/
|
|
144
181
|
sendMessage(event, payload) {
|
|
145
182
|
const requestId = (0, pondsocket_common_1.uuid)();
|
|
146
|
-
|
|
183
|
+
const message = {
|
|
184
|
+
action: pondsocket_common_1.ClientActions.BROADCAST,
|
|
185
|
+
channelName: __classPrivateFieldGet(this, _Channel_name, "f"),
|
|
186
|
+
requestId,
|
|
187
|
+
event,
|
|
188
|
+
payload,
|
|
189
|
+
};
|
|
190
|
+
__classPrivateFieldGet(this, _Channel_instances, "m", _Channel_publish).call(this, message);
|
|
147
191
|
}
|
|
148
192
|
/**
|
|
149
193
|
* @desc Sends a message to the server and waits for a response.
|
|
@@ -159,90 +203,39 @@ class Channel {
|
|
|
159
203
|
unsub();
|
|
160
204
|
}
|
|
161
205
|
});
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
}
|
|
171
|
-
/**
|
|
172
|
-
* @desc Monitors the presence of the channel.
|
|
173
|
-
* @param callback - The callback to call when the presence changes.
|
|
174
|
-
*/
|
|
175
|
-
onUsersChange(callback) {
|
|
176
|
-
return __classPrivateFieldGet(this, _Channel_instances, "m", _Channel_subscribeToPresence).call(this, (_event, payload) => callback(payload.presence));
|
|
177
|
-
}
|
|
178
|
-
/**
|
|
179
|
-
* @desc Checks if the channel is connected.
|
|
180
|
-
*/
|
|
181
|
-
isConnected() {
|
|
182
|
-
return __classPrivateFieldGet(this, _Channel_joinState, "f").value === pondsocket_common_1.ChannelState.JOINED || __classPrivateFieldGet(this, _Channel_joinState, "f").value === pondsocket_common_1.ChannelState.STALLED;
|
|
183
|
-
}
|
|
184
|
-
/**
|
|
185
|
-
* @desc Checks if the channel is stalled.
|
|
186
|
-
*/
|
|
187
|
-
isStalled() {
|
|
188
|
-
return __classPrivateFieldGet(this, _Channel_joinState, "f").value === pondsocket_common_1.ChannelState.STALLED;
|
|
189
|
-
}
|
|
190
|
-
/**
|
|
191
|
-
* @desc Checks if the channel is closed.
|
|
192
|
-
*/
|
|
193
|
-
isClosed() {
|
|
194
|
-
return __classPrivateFieldGet(this, _Channel_joinState, "f").value === pondsocket_common_1.ChannelState.CLOSED;
|
|
195
|
-
}
|
|
196
|
-
/**
|
|
197
|
-
* @desc Monitors the connection state of the channel.
|
|
198
|
-
* @param callback - The callback to call when the connection state changes.
|
|
199
|
-
*/
|
|
200
|
-
onConnectionChange(callback) {
|
|
201
|
-
return this.onChannelStateChange((state) => {
|
|
202
|
-
callback(state === pondsocket_common_1.ChannelState.JOINED || state === pondsocket_common_1.ChannelState.STALLED);
|
|
206
|
+
const message = {
|
|
207
|
+
action: pondsocket_common_1.ClientActions.BROADCAST,
|
|
208
|
+
channelName: __classPrivateFieldGet(this, _Channel_name, "f"),
|
|
209
|
+
requestId,
|
|
210
|
+
event: sentEvent,
|
|
211
|
+
payload,
|
|
212
|
+
};
|
|
213
|
+
__classPrivateFieldGet(this, _Channel_instances, "m", _Channel_publish).call(this, message);
|
|
203
214
|
});
|
|
204
215
|
}
|
|
205
216
|
}
|
|
206
217
|
exports.Channel = Channel;
|
|
207
|
-
_Channel_name = new WeakMap(), _Channel_queue = new WeakMap(), _Channel_presence = new WeakMap(),
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
requestId,
|
|
212
|
-
event,
|
|
213
|
-
payload,
|
|
214
|
-
};
|
|
215
|
-
__classPrivateFieldGet(this, _Channel_instances, "m", _Channel_publish).call(this, message);
|
|
216
|
-
}, _Channel_publish = function _Channel_publish(data) {
|
|
217
|
-
if (__classPrivateFieldGet(this, _Channel_clientState, "f").value) {
|
|
218
|
-
if (__classPrivateFieldGet(this, _Channel_joinState, "f").value === pondsocket_common_1.ChannelState.JOINED) {
|
|
219
|
-
__classPrivateFieldGet(this, _Channel_publisher, "f").call(this, data);
|
|
220
|
-
}
|
|
221
|
-
return;
|
|
222
|
-
}
|
|
223
|
-
__classPrivateFieldGet(this, _Channel_queue, "f").push(data);
|
|
224
|
-
}, _Channel_subscribeToPresence = function _Channel_subscribeToPresence(callback) {
|
|
225
|
-
return __classPrivateFieldGet(this, _Channel_receiver, "f").subscribe((data) => {
|
|
226
|
-
if (data.action === pondsocket_common_1.ServerActions.PRESENCE) {
|
|
227
|
-
return callback(data.event, data.payload);
|
|
228
|
-
}
|
|
229
|
-
});
|
|
218
|
+
_Channel_name = new WeakMap(), _Channel_queue = new WeakMap(), _Channel_presence = new WeakMap(), _Channel_presenceSub = new WeakMap(), _Channel_publisher = new WeakMap(), _Channel_joinParams = new WeakMap(), _Channel_receiver = new WeakMap(), _Channel_clientState = new WeakMap(), _Channel_joinState = new WeakMap(), _Channel_instances = new WeakSet(), _Channel_emptyQueue = function _Channel_emptyQueue() {
|
|
219
|
+
__classPrivateFieldGet(this, _Channel_queue, "f")
|
|
220
|
+
.forEach((message) => __classPrivateFieldGet(this, _Channel_publisher, "f").call(this, message));
|
|
221
|
+
__classPrivateFieldSet(this, _Channel_queue, [], "f");
|
|
230
222
|
}, _Channel_init = function _Channel_init(receiver) {
|
|
223
|
+
__classPrivateFieldGet(this, _Channel_presenceSub, "f").call(this);
|
|
231
224
|
const unsubMessages = receiver.subscribe((data) => {
|
|
232
|
-
if (data.channelName === __classPrivateFieldGet(this, _Channel_name, "f")) {
|
|
233
|
-
|
|
234
|
-
__classPrivateFieldGet(this, _Channel_joinState, "f").publish(pondsocket_common_1.ChannelState.JOINED);
|
|
235
|
-
__classPrivateFieldGet(this, _Channel_instances, "m", _Channel_emptyQueue).call(this);
|
|
236
|
-
}
|
|
237
|
-
else {
|
|
238
|
-
__classPrivateFieldGet(this, _Channel_receiver, "f").publish(data);
|
|
239
|
-
}
|
|
225
|
+
if (data.channelName === __classPrivateFieldGet(this, _Channel_name, "f") && this.channelState === pondsocket_common_1.ChannelState.JOINED) {
|
|
226
|
+
__classPrivateFieldGet(this, _Channel_receiver, "f").publish(data);
|
|
240
227
|
}
|
|
241
228
|
});
|
|
242
229
|
const unsubStateChange = __classPrivateFieldGet(this, _Channel_clientState, "f").subscribe((state) => {
|
|
243
230
|
if (state && __classPrivateFieldGet(this, _Channel_joinState, "f").value === pondsocket_common_1.ChannelState.STALLED) {
|
|
244
|
-
const
|
|
245
|
-
|
|
231
|
+
const message = {
|
|
232
|
+
action: pondsocket_common_1.ClientActions.JOIN_CHANNEL,
|
|
233
|
+
event: pondsocket_common_1.ClientActions.JOIN_CHANNEL,
|
|
234
|
+
payload: __classPrivateFieldGet(this, _Channel_joinParams, "f"),
|
|
235
|
+
channelName: __classPrivateFieldGet(this, _Channel_name, "f"),
|
|
236
|
+
requestId: (0, pondsocket_common_1.uuid)(),
|
|
237
|
+
};
|
|
238
|
+
__classPrivateFieldGet(this, _Channel_publisher, "f").call(this, message);
|
|
246
239
|
}
|
|
247
240
|
else if (!state && __classPrivateFieldGet(this, _Channel_joinState, "f").value === pondsocket_common_1.ChannelState.JOINED) {
|
|
248
241
|
__classPrivateFieldGet(this, _Channel_joinState, "f").publish(pondsocket_common_1.ChannelState.STALLED);
|
|
@@ -251,30 +244,26 @@ _Channel_name = new WeakMap(), _Channel_queue = new WeakMap(), _Channel_presence
|
|
|
251
244
|
const unsubPresence = __classPrivateFieldGet(this, _Channel_instances, "m", _Channel_subscribeToPresence).call(this, (_, payload) => {
|
|
252
245
|
__classPrivateFieldSet(this, _Channel_presence, payload.presence, "f");
|
|
253
246
|
});
|
|
254
|
-
|
|
247
|
+
__classPrivateFieldSet(this, _Channel_presenceSub, () => {
|
|
255
248
|
unsubMessages();
|
|
256
249
|
unsubStateChange();
|
|
257
250
|
unsubPresence();
|
|
258
|
-
};
|
|
259
|
-
}, _Channel_emptyQueue = function _Channel_emptyQueue() {
|
|
260
|
-
__classPrivateFieldGet(this, _Channel_queue, "f")
|
|
261
|
-
.filter((message) => message.action !== pondsocket_common_1.ClientActions.JOIN_CHANNEL)
|
|
262
|
-
.forEach((message) => {
|
|
263
|
-
__classPrivateFieldGet(this, _Channel_publisher, "f").call(this, message);
|
|
264
|
-
});
|
|
265
|
-
__classPrivateFieldSet(this, _Channel_queue, [], "f");
|
|
266
|
-
}, _Channel_buildJoinMessage = function _Channel_buildJoinMessage() {
|
|
267
|
-
return {
|
|
268
|
-
action: pondsocket_common_1.ClientActions.JOIN_CHANNEL,
|
|
269
|
-
event: pondsocket_common_1.ClientActions.JOIN_CHANNEL,
|
|
270
|
-
payload: __classPrivateFieldGet(this, _Channel_joinParams, "f"),
|
|
271
|
-
channelName: __classPrivateFieldGet(this, _Channel_name, "f"),
|
|
272
|
-
requestId: (0, pondsocket_common_1.uuid)(),
|
|
273
|
-
};
|
|
251
|
+
}, "f");
|
|
274
252
|
}, _Channel_onMessage = function _Channel_onMessage(callback) {
|
|
275
253
|
return __classPrivateFieldGet(this, _Channel_receiver, "f").subscribe((data) => {
|
|
276
254
|
if (data.action !== pondsocket_common_1.ServerActions.PRESENCE) {
|
|
277
255
|
return callback(data.event, data.payload, data.requestId);
|
|
278
256
|
}
|
|
279
257
|
});
|
|
258
|
+
}, _Channel_publish = function _Channel_publish(data) {
|
|
259
|
+
if (__classPrivateFieldGet(this, _Channel_joinState, "f").value === pondsocket_common_1.ChannelState.JOINED) {
|
|
260
|
+
return __classPrivateFieldGet(this, _Channel_publisher, "f").call(this, data);
|
|
261
|
+
}
|
|
262
|
+
__classPrivateFieldGet(this, _Channel_queue, "f").push(data);
|
|
263
|
+
}, _Channel_subscribeToPresence = function _Channel_subscribeToPresence(callback) {
|
|
264
|
+
return __classPrivateFieldGet(this, _Channel_receiver, "f").subscribe((data) => {
|
|
265
|
+
if (data.action === pondsocket_common_1.ServerActions.PRESENCE) {
|
|
266
|
+
return callback(data.event, data.payload);
|
|
267
|
+
}
|
|
268
|
+
});
|
|
280
269
|
};
|
package/core/channel.test.js
CHANGED
|
@@ -15,7 +15,7 @@ const createChannel = (params = {}) => {
|
|
|
15
15
|
const publisher = jest.fn();
|
|
16
16
|
const state = new pondsocket_common_1.BehaviorSubject(true);
|
|
17
17
|
const receiver = new pondsocket_common_1.Subject();
|
|
18
|
-
const channel = new channel_1.Channel(publisher, state, 'test',
|
|
18
|
+
const channel = new channel_1.Channel(publisher, state, 'test', params);
|
|
19
19
|
return {
|
|
20
20
|
channel,
|
|
21
21
|
publisher,
|
|
@@ -24,213 +24,132 @@ const createChannel = (params = {}) => {
|
|
|
24
24
|
};
|
|
25
25
|
};
|
|
26
26
|
describe('Channel', () => {
|
|
27
|
-
it('should correctly
|
|
28
|
-
const { channel, publisher, state } = createChannel();
|
|
29
|
-
|
|
30
|
-
expect(
|
|
27
|
+
it('should correctly perform the join process', () => {
|
|
28
|
+
const { channel, publisher, state, receiver } = createChannel();
|
|
29
|
+
// the channel should be in the idle state when it is created
|
|
30
|
+
expect(channel.channelState).toBe(pondsocket_common_1.ChannelState.IDLE);
|
|
31
|
+
// if the socket is not connected the channel should not post a join message
|
|
32
|
+
state.publish(false);
|
|
31
33
|
channel.join();
|
|
34
|
+
expect(publisher).not.toHaveBeenCalled();
|
|
35
|
+
expect(channel.channelState).toBe(pondsocket_common_1.ChannelState.JOINING);
|
|
36
|
+
// once the socket is connected, the channel should attempt to join
|
|
37
|
+
state.publish(true);
|
|
38
|
+
expect(channel.channelState).toBe(pondsocket_common_1.ChannelState.JOINING);
|
|
32
39
|
expect(publisher).toHaveBeenCalledWith(expect.objectContaining({
|
|
33
40
|
action: pondsocket_common_1.ClientActions.JOIN_CHANNEL,
|
|
34
41
|
channelName: 'test',
|
|
35
42
|
event: pondsocket_common_1.ClientActions.JOIN_CHANNEL,
|
|
36
43
|
payload: {},
|
|
37
44
|
}));
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
expect(
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
expect(
|
|
44
|
-
|
|
45
|
-
|
|
45
|
+
// once the server responds with an ack, the channel state should be joined
|
|
46
|
+
channel.acknowledge(receiver);
|
|
47
|
+
expect(channel.channelState).toBe(pondsocket_common_1.ChannelState.JOINED);
|
|
48
|
+
// if the socket is disconnected, the channel should be stalled
|
|
49
|
+
state.publish(false);
|
|
50
|
+
expect(channel.channelState).toBe(pondsocket_common_1.ChannelState.STALLED);
|
|
51
|
+
// once the socket is reconnected, a join message should be sent
|
|
52
|
+
publisher.mockClear();
|
|
53
|
+
state.publish(true);
|
|
54
|
+
expect(channel.channelState).toBe(pondsocket_common_1.ChannelState.STALLED);
|
|
55
|
+
expect(publisher).toHaveBeenCalledWith(expect.objectContaining({
|
|
46
56
|
action: pondsocket_common_1.ClientActions.JOIN_CHANNEL,
|
|
47
57
|
channelName: 'test',
|
|
48
58
|
event: pondsocket_common_1.ClientActions.JOIN_CHANNEL,
|
|
49
59
|
payload: {},
|
|
50
60
|
}));
|
|
51
|
-
const { channel: channel3 } = createChannel();
|
|
52
|
-
channel3.leave();
|
|
53
|
-
expect(() => channel3.join())
|
|
54
|
-
.toThrow('This channel has been closed');
|
|
55
|
-
});
|
|
56
|
-
it('should correctly send a leave message', () => {
|
|
57
|
-
const { channel, publisher, receiver } = createChannel();
|
|
58
|
-
expect(channel.channelState).toBe(pondsocket_common_1.ChannelState.IDLE);
|
|
59
|
-
channel.join();
|
|
60
|
-
expect(channel.channelState).toBe(pondsocket_common_1.ChannelState.JOINING);
|
|
61
|
-
receiver.publish({
|
|
62
|
-
requestId: 'test',
|
|
63
|
-
action: pondsocket_common_1.ServerActions.SYSTEM,
|
|
64
|
-
channelName: 'test',
|
|
65
|
-
event: 'SYSTEM',
|
|
66
|
-
payload: {
|
|
67
|
-
event: 'JOIN',
|
|
68
|
-
},
|
|
69
|
-
});
|
|
70
|
-
expect(channel.channelState).toBe(pondsocket_common_1.ChannelState.JOINING);
|
|
71
61
|
// once the server responds with an ack, the channel state should be joined
|
|
72
|
-
|
|
73
|
-
requestId: 'test',
|
|
74
|
-
action: pondsocket_common_1.ServerActions.SYSTEM,
|
|
75
|
-
channelName: 'test',
|
|
76
|
-
event: pondsocket_common_1.Events.ACKNOWLEDGE,
|
|
77
|
-
payload: {
|
|
78
|
-
event: 'JOIN',
|
|
79
|
-
},
|
|
80
|
-
});
|
|
62
|
+
channel.acknowledge(receiver);
|
|
81
63
|
expect(channel.channelState).toBe(pondsocket_common_1.ChannelState.JOINED);
|
|
64
|
+
// if the channel is closed, the channel should be closed
|
|
82
65
|
channel.leave();
|
|
83
66
|
expect(channel.channelState).toBe(pondsocket_common_1.ChannelState.CLOSED);
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
67
|
+
publisher.mockClear();
|
|
68
|
+
// if the socket closes, while the channel is closed, the channel should not attempt to join when the socket reconnects
|
|
69
|
+
state.publish(false);
|
|
70
|
+
state.publish(true);
|
|
71
|
+
expect(publisher).not.toHaveBeenCalled();
|
|
72
|
+
// if the channel is closed, during a join process, the channel should not attempt to join when the socket reconnects
|
|
73
|
+
const { channel: channel2, publisher: publisher2, state: state2 } = createChannel();
|
|
74
|
+
state2.publish(false);
|
|
75
|
+
channel2.join();
|
|
76
|
+
expect(publisher2).not.toHaveBeenCalled();
|
|
77
|
+
expect(channel2.channelState).toBe(pondsocket_common_1.ChannelState.JOINING);
|
|
78
|
+
channel2.leave();
|
|
79
|
+
state2.publish(true);
|
|
80
|
+
expect(publisher2).not.toHaveBeenCalled();
|
|
81
|
+
// if for some reason the server responds with an ack, the channel should still join, (The server is the source of truth)
|
|
82
|
+
channel2.acknowledge(receiver);
|
|
83
|
+
expect(channel2.channelState).toBe(pondsocket_common_1.ChannelState.JOINED);
|
|
90
84
|
});
|
|
91
85
|
it('should notify subscribers when the channel state changes', () => {
|
|
92
|
-
const { channel, receiver } = createChannel();
|
|
86
|
+
const { channel, receiver, state } = createChannel();
|
|
93
87
|
const stateListener = jest.fn();
|
|
94
88
|
channel.onChannelStateChange(stateListener);
|
|
95
89
|
expect(stateListener).toHaveBeenCalledWith(pondsocket_common_1.ChannelState.IDLE);
|
|
96
90
|
channel.join();
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
action: 'SYSTEM',
|
|
100
|
-
channelName: 'test',
|
|
101
|
-
event: pondsocket_common_1.Events.ACKNOWLEDGE,
|
|
102
|
-
payload: {
|
|
103
|
-
event: 'JOIN',
|
|
104
|
-
},
|
|
105
|
-
});
|
|
91
|
+
expect(stateListener).toHaveBeenCalledWith(pondsocket_common_1.ChannelState.JOINING);
|
|
92
|
+
channel.acknowledge(receiver);
|
|
106
93
|
expect(stateListener).toHaveBeenCalledWith(pondsocket_common_1.ChannelState.JOINED);
|
|
107
|
-
channel.leave();
|
|
108
|
-
expect(stateListener).toHaveBeenCalledWith(pondsocket_common_1.ChannelState.CLOSED);
|
|
109
|
-
});
|
|
110
|
-
it('should notify subscribers when state changes BOOLEAN', () => {
|
|
111
|
-
const { channel, receiver, state, publisher } = createChannel();
|
|
112
|
-
const stateListener = jest.fn();
|
|
113
|
-
expect(channel.isClosed()).toBe(false);
|
|
114
|
-
expect(channel.isConnected()).toBe(false);
|
|
115
|
-
expect(channel.isStalled()).toBe(false);
|
|
116
|
-
channel.onConnectionChange(stateListener);
|
|
117
|
-
expect(stateListener).toHaveBeenCalledWith(false);
|
|
118
|
-
expect(channel.isClosed()).toBe(false);
|
|
119
|
-
expect(channel.isConnected()).toBe(false);
|
|
120
|
-
expect(channel.isStalled()).toBe(false);
|
|
121
|
-
channel.join();
|
|
122
|
-
expect(channel.isConnected()).toBe(false);
|
|
123
|
-
expect(channel.isStalled()).toBe(false);
|
|
124
|
-
receiver.publish({
|
|
125
|
-
requestId: 'test',
|
|
126
|
-
action: 'SYSTEM',
|
|
127
|
-
channelName: 'test',
|
|
128
|
-
event: pondsocket_common_1.Events.ACKNOWLEDGE,
|
|
129
|
-
payload: {
|
|
130
|
-
event: 'JOIN',
|
|
131
|
-
},
|
|
132
|
-
});
|
|
133
|
-
expect(stateListener).toHaveBeenCalledWith(true);
|
|
134
|
-
expect(channel.isConnected()).toBe(true);
|
|
135
|
-
expect(channel.isStalled()).toBe(false);
|
|
136
|
-
publisher.mockClear();
|
|
137
94
|
state.publish(false);
|
|
138
|
-
expect(
|
|
139
|
-
expect(channel.isStalled()).toBe(true);
|
|
140
|
-
expect(channel.isConnected()).toBe(true);
|
|
141
|
-
state.publish(true);
|
|
142
|
-
expect(publisher).toHaveBeenCalledTimes(1);
|
|
143
|
-
receiver.publish({
|
|
144
|
-
requestId: 'test',
|
|
145
|
-
action: 'SYSTEM',
|
|
146
|
-
channelName: 'test',
|
|
147
|
-
event: pondsocket_common_1.Events.ACKNOWLEDGE,
|
|
148
|
-
payload: {
|
|
149
|
-
event: 'JOIN',
|
|
150
|
-
},
|
|
151
|
-
});
|
|
152
|
-
expect(channel.isStalled()).toBe(false);
|
|
153
|
-
expect(channel.isConnected()).toBe(true);
|
|
95
|
+
expect(stateListener).toHaveBeenCalledWith(pondsocket_common_1.ChannelState.STALLED);
|
|
154
96
|
channel.leave();
|
|
155
|
-
expect(
|
|
156
|
-
expect(channel.isConnected()).toBe(false);
|
|
157
|
-
expect(channel.isStalled()).toBe(false);
|
|
158
|
-
expect(stateListener).toHaveBeenCalledWith(false);
|
|
97
|
+
expect(stateListener).toHaveBeenCalledWith(pondsocket_common_1.ChannelState.CLOSED);
|
|
159
98
|
});
|
|
160
99
|
it('should correctly send a message', () => {
|
|
161
|
-
const { channel, publisher,
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
100
|
+
const { channel, publisher, receiver, state } = createChannel();
|
|
101
|
+
// the channel should not send a message if it is not joined, the message should be queued
|
|
102
|
+
channel.sendMessage('test', {
|
|
103
|
+
test: 'test',
|
|
104
|
+
});
|
|
166
105
|
expect(publisher).not.toHaveBeenCalled();
|
|
106
|
+
// however, if the channel is joined, the queued message should be sent
|
|
167
107
|
channel.join();
|
|
168
108
|
publisher.mockClear();
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
action: 'SYSTEM',
|
|
172
|
-
channelName: 'test',
|
|
173
|
-
event: pondsocket_common_1.Events.ACKNOWLEDGE,
|
|
174
|
-
payload: {
|
|
175
|
-
event: 'JOIN',
|
|
176
|
-
},
|
|
177
|
-
});
|
|
178
|
-
// however once the channel is joined, the message should be sent
|
|
179
|
-
channel.sendMessage('test', { test: true });
|
|
109
|
+
// acknowledge the join
|
|
110
|
+
channel.acknowledge(receiver);
|
|
180
111
|
expect(publisher).toHaveBeenCalledWith(expect.objectContaining({
|
|
181
112
|
action: pondsocket_common_1.ClientActions.BROADCAST,
|
|
182
113
|
channelName: 'test',
|
|
183
114
|
event: 'test',
|
|
184
115
|
payload: {
|
|
185
|
-
test:
|
|
116
|
+
test: 'test',
|
|
186
117
|
},
|
|
187
118
|
}));
|
|
188
|
-
// if for some reason the socket is disconnected, the message should be queued
|
|
189
119
|
publisher.mockClear();
|
|
120
|
+
// if the channel stalls and rejoins the previous message should not be sent again
|
|
190
121
|
state.publish(false);
|
|
191
|
-
expect(state.value).toBe(false);
|
|
192
|
-
channel.sendMessage('test', { test: true });
|
|
193
|
-
expect(publisher).not.toHaveBeenCalled();
|
|
194
|
-
// once the socket is reconnected, a join message should be sent and the queued messages should be sent
|
|
195
|
-
publisher.mockClear();
|
|
196
122
|
state.publish(true);
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
}));
|
|
203
|
-
// until it receives an ack message the queued messages should not be sent
|
|
204
|
-
expect(publisher).toHaveBeenCalledTimes(1);
|
|
205
|
-
receiver.publish({
|
|
206
|
-
requestId: 'test',
|
|
207
|
-
action: 'SYSTEM',
|
|
123
|
+
// acknowledge the join
|
|
124
|
+
channel.acknowledge(receiver);
|
|
125
|
+
expect(publisher).toHaveBeenCalledTimes(1); // The join message
|
|
126
|
+
expect(publisher).not.toHaveBeenCalledWith(expect.objectContaining({
|
|
127
|
+
action: pondsocket_common_1.ClientActions.BROADCAST,
|
|
208
128
|
channelName: 'test',
|
|
209
|
-
event:
|
|
129
|
+
event: 'test',
|
|
210
130
|
payload: {
|
|
211
|
-
|
|
131
|
+
test: 'test',
|
|
212
132
|
},
|
|
133
|
+
}));
|
|
134
|
+
publisher.mockClear();
|
|
135
|
+
// if a message is sent while the channel is stalled, it should be queued
|
|
136
|
+
state.publish(false);
|
|
137
|
+
channel.sendMessage('test', {
|
|
138
|
+
test: 'test stalling',
|
|
213
139
|
});
|
|
140
|
+
expect(publisher).not.toHaveBeenCalled();
|
|
141
|
+
state.publish(true);
|
|
142
|
+
publisher.mockClear(); // The join message
|
|
143
|
+
// acknowledge the join
|
|
144
|
+
channel.acknowledge(receiver);
|
|
214
145
|
expect(publisher).toHaveBeenCalledWith(expect.objectContaining({
|
|
215
146
|
action: pondsocket_common_1.ClientActions.BROADCAST,
|
|
216
147
|
channelName: 'test',
|
|
217
148
|
event: 'test',
|
|
218
149
|
payload: {
|
|
219
|
-
test:
|
|
150
|
+
test: 'test stalling',
|
|
220
151
|
},
|
|
221
152
|
}));
|
|
222
|
-
// if the channel is closed, the message should not be sent, and should not be queued
|
|
223
|
-
publisher.mockClear();
|
|
224
|
-
channel.leave();
|
|
225
|
-
// the leave message should be sent
|
|
226
|
-
expect(publisher).toHaveBeenCalledWith(expect.objectContaining({
|
|
227
|
-
action: pondsocket_common_1.ClientActions.LEAVE_CHANNEL,
|
|
228
|
-
channelName: 'test',
|
|
229
|
-
event: pondsocket_common_1.ClientActions.LEAVE_CHANNEL,
|
|
230
|
-
payload: {},
|
|
231
|
-
}));
|
|
232
|
-
expect(channel.channelState).toBe(pondsocket_common_1.ChannelState.CLOSED);
|
|
233
|
-
channel.sendMessage('test', { test: true });
|
|
234
153
|
expect(publisher).toHaveBeenCalledTimes(1);
|
|
235
154
|
});
|
|
236
155
|
// The presence system tests
|
|
@@ -239,8 +158,8 @@ describe('Channel', () => {
|
|
|
239
158
|
const presenceListener = jest.fn();
|
|
240
159
|
channel.onJoin(presenceListener);
|
|
241
160
|
expect(presenceListener).not.toHaveBeenCalled();
|
|
242
|
-
//
|
|
243
|
-
|
|
161
|
+
// acknowledge the join
|
|
162
|
+
channel.acknowledge(receiver);
|
|
244
163
|
receiver.publish({
|
|
245
164
|
requestId: 'test',
|
|
246
165
|
action: pondsocket_common_1.ServerActions.PRESENCE,
|
|
@@ -321,8 +240,8 @@ describe('Channel', () => {
|
|
|
321
240
|
const presenceListener = jest.fn();
|
|
322
241
|
channel.onLeave(presenceListener);
|
|
323
242
|
expect(presenceListener).not.toHaveBeenCalled();
|
|
324
|
-
//
|
|
325
|
-
|
|
243
|
+
// acknowledge the join
|
|
244
|
+
channel.acknowledge(receiver);
|
|
326
245
|
receiver.publish({
|
|
327
246
|
requestId: 'test',
|
|
328
247
|
action: pondsocket_common_1.ServerActions.PRESENCE,
|
|
@@ -403,8 +322,8 @@ describe('Channel', () => {
|
|
|
403
322
|
const presenceListener = jest.fn();
|
|
404
323
|
channel.onUsersChange(presenceListener);
|
|
405
324
|
expect(presenceListener).not.toHaveBeenCalled();
|
|
406
|
-
//
|
|
407
|
-
|
|
325
|
+
// acknowledge the join
|
|
326
|
+
channel.acknowledge(receiver);
|
|
408
327
|
receiver.publish({
|
|
409
328
|
requestId: 'test',
|
|
410
329
|
action: pondsocket_common_1.ServerActions.PRESENCE,
|
|
@@ -437,7 +356,7 @@ describe('Channel', () => {
|
|
|
437
356
|
status: 'online',
|
|
438
357
|
},
|
|
439
358
|
]);
|
|
440
|
-
expect(channel.
|
|
359
|
+
expect(channel.presence).toBe(presenceListener.mock.calls[0][0]);
|
|
441
360
|
presenceListener.mockClear();
|
|
442
361
|
// if we receive a leave or join event, it should be sent to the listener
|
|
443
362
|
// this is because we are listening for all presence events
|
|
@@ -465,7 +384,7 @@ describe('Channel', () => {
|
|
|
465
384
|
status: 'online',
|
|
466
385
|
},
|
|
467
386
|
]);
|
|
468
|
-
expect(channel.
|
|
387
|
+
expect(channel.presence).toBe(presenceListener.mock.calls[0][0]);
|
|
469
388
|
presenceListener.mockClear();
|
|
470
389
|
// also, if a presence event is received for a different channel, it should not be sent to the listener
|
|
471
390
|
receiver.publish({
|
|
@@ -524,15 +443,15 @@ describe('Channel', () => {
|
|
|
524
443
|
status: 'online',
|
|
525
444
|
},
|
|
526
445
|
]);
|
|
527
|
-
expect(channel.
|
|
446
|
+
expect(channel.presence).toBe(presenceListener.mock.calls[0][0]);
|
|
528
447
|
});
|
|
529
448
|
it('should notify subscribers when any presence event occurs', () => {
|
|
530
|
-
const { channel, receiver } = createChannel();
|
|
449
|
+
const { channel, receiver, state } = createChannel();
|
|
531
450
|
const presenceListener = jest.fn();
|
|
532
451
|
channel.onPresenceChange(presenceListener);
|
|
533
452
|
expect(presenceListener).not.toHaveBeenCalled();
|
|
534
|
-
//
|
|
535
|
-
|
|
453
|
+
// acknowledge the join
|
|
454
|
+
channel.acknowledge(receiver);
|
|
536
455
|
receiver.publish({
|
|
537
456
|
requestId: 'test',
|
|
538
457
|
action: pondsocket_common_1.ServerActions.PRESENCE,
|
|
@@ -571,11 +490,115 @@ describe('Channel', () => {
|
|
|
571
490
|
},
|
|
572
491
|
],
|
|
573
492
|
});
|
|
493
|
+
// messages for other channels should not be sent to the listener
|
|
494
|
+
// since the other presence events listeners rely on this function we don't need to test this on those tests
|
|
495
|
+
presenceListener.mockClear();
|
|
496
|
+
receiver.publish({
|
|
497
|
+
requestId: 'test',
|
|
498
|
+
action: pondsocket_common_1.ServerActions.PRESENCE,
|
|
499
|
+
event: pondsocket_common_1.PresenceEventTypes.UPDATE,
|
|
500
|
+
channelName: 'test2',
|
|
501
|
+
payload: {
|
|
502
|
+
changed: {
|
|
503
|
+
id: 'test',
|
|
504
|
+
status: 'online',
|
|
505
|
+
},
|
|
506
|
+
presence: [
|
|
507
|
+
{
|
|
508
|
+
id: 'test',
|
|
509
|
+
status: 'online',
|
|
510
|
+
},
|
|
511
|
+
{
|
|
512
|
+
id: 'test2',
|
|
513
|
+
status: 'online',
|
|
514
|
+
},
|
|
515
|
+
],
|
|
516
|
+
},
|
|
517
|
+
});
|
|
518
|
+
expect(presenceListener).not.toHaveBeenCalled();
|
|
519
|
+
// if the channel is stalled, the presence event should not be sent to the listener
|
|
520
|
+
state.publish(false);
|
|
521
|
+
expect(channel.channelState).toBe(pondsocket_common_1.ChannelState.STALLED);
|
|
522
|
+
receiver.publish({
|
|
523
|
+
requestId: 'test',
|
|
524
|
+
action: pondsocket_common_1.ServerActions.PRESENCE,
|
|
525
|
+
event: pondsocket_common_1.PresenceEventTypes.UPDATE,
|
|
526
|
+
channelName: 'test',
|
|
527
|
+
payload: {
|
|
528
|
+
changed: {
|
|
529
|
+
id: 'test',
|
|
530
|
+
status: 'online',
|
|
531
|
+
},
|
|
532
|
+
presence: [
|
|
533
|
+
{
|
|
534
|
+
id: 'test',
|
|
535
|
+
status: 'online',
|
|
536
|
+
},
|
|
537
|
+
{
|
|
538
|
+
id: 'test2',
|
|
539
|
+
status: 'online',
|
|
540
|
+
},
|
|
541
|
+
],
|
|
542
|
+
},
|
|
543
|
+
});
|
|
544
|
+
expect(presenceListener).not.toHaveBeenCalled();
|
|
545
|
+
state.publish(true);
|
|
546
|
+
expect(channel.channelState).toBe(pondsocket_common_1.ChannelState.STALLED);
|
|
547
|
+
receiver.publish({
|
|
548
|
+
requestId: 'test',
|
|
549
|
+
action: pondsocket_common_1.ServerActions.PRESENCE,
|
|
550
|
+
event: pondsocket_common_1.PresenceEventTypes.UPDATE,
|
|
551
|
+
channelName: 'test',
|
|
552
|
+
payload: {
|
|
553
|
+
changed: {
|
|
554
|
+
id: 'test',
|
|
555
|
+
status: 'online',
|
|
556
|
+
},
|
|
557
|
+
presence: [
|
|
558
|
+
{
|
|
559
|
+
id: 'test',
|
|
560
|
+
status: 'online',
|
|
561
|
+
},
|
|
562
|
+
{
|
|
563
|
+
id: 'test2',
|
|
564
|
+
status: 'online',
|
|
565
|
+
},
|
|
566
|
+
],
|
|
567
|
+
},
|
|
568
|
+
});
|
|
569
|
+
expect(presenceListener).not.toHaveBeenCalled();
|
|
570
|
+
// if the channel is closed, the presence event should not be sent to the listener
|
|
571
|
+
channel.acknowledge(receiver);
|
|
572
|
+
channel.leave();
|
|
573
|
+
receiver.publish({
|
|
574
|
+
requestId: 'test',
|
|
575
|
+
action: pondsocket_common_1.ServerActions.PRESENCE,
|
|
576
|
+
event: pondsocket_common_1.PresenceEventTypes.UPDATE,
|
|
577
|
+
channelName: 'test',
|
|
578
|
+
payload: {
|
|
579
|
+
changed: {
|
|
580
|
+
id: 'test',
|
|
581
|
+
status: 'online',
|
|
582
|
+
},
|
|
583
|
+
presence: [
|
|
584
|
+
{
|
|
585
|
+
id: 'test',
|
|
586
|
+
status: 'online',
|
|
587
|
+
},
|
|
588
|
+
{
|
|
589
|
+
id: 'test2',
|
|
590
|
+
status: 'online',
|
|
591
|
+
},
|
|
592
|
+
],
|
|
593
|
+
},
|
|
594
|
+
});
|
|
595
|
+
expect(presenceListener).not.toHaveBeenCalled();
|
|
574
596
|
});
|
|
575
597
|
// message events
|
|
576
598
|
it('should notify subscribers when a message is received', () => {
|
|
577
599
|
const { channel, receiver } = createChannel();
|
|
578
600
|
const messageListener = jest.fn();
|
|
601
|
+
channel.join();
|
|
579
602
|
channel.onMessage(messageListener);
|
|
580
603
|
expect(messageListener).not.toHaveBeenCalled();
|
|
581
604
|
receiver.publish({
|
|
@@ -588,6 +611,19 @@ describe('Channel', () => {
|
|
|
588
611
|
message: 'test',
|
|
589
612
|
},
|
|
590
613
|
});
|
|
614
|
+
expect(messageListener).not.toHaveBeenCalled(); // the server should acknowledge the join first
|
|
615
|
+
// acknowledge the join
|
|
616
|
+
channel.acknowledge(receiver);
|
|
617
|
+
receiver.publish({
|
|
618
|
+
requestId: 'test',
|
|
619
|
+
action: pondsocket_common_1.ServerActions.BROADCAST,
|
|
620
|
+
event: 'message',
|
|
621
|
+
channelName: 'test',
|
|
622
|
+
payload: {
|
|
623
|
+
id: 'test',
|
|
624
|
+
message: 'test',
|
|
625
|
+
},
|
|
626
|
+
});
|
|
591
627
|
expect(messageListener).toHaveBeenCalledWith('message', {
|
|
592
628
|
id: 'test',
|
|
593
629
|
message: 'test',
|
|
@@ -648,55 +684,6 @@ describe('Channel', () => {
|
|
|
648
684
|
});
|
|
649
685
|
expect(specificMessageListener).not.toHaveBeenCalled();
|
|
650
686
|
});
|
|
651
|
-
it('should be able to broadcast a message', () => {
|
|
652
|
-
const { channel, receiver, publisher } = createChannel();
|
|
653
|
-
channel.join();
|
|
654
|
-
publisher.mockClear();
|
|
655
|
-
receiver.publish({
|
|
656
|
-
requestId: 'test',
|
|
657
|
-
action: 'SYSTEM',
|
|
658
|
-
channelName: 'test',
|
|
659
|
-
event: pondsocket_common_1.Events.ACKNOWLEDGE,
|
|
660
|
-
payload: {
|
|
661
|
-
event: 'JOIN',
|
|
662
|
-
},
|
|
663
|
-
});
|
|
664
|
-
channel.sendMessage('test', {
|
|
665
|
-
test: 'test',
|
|
666
|
-
});
|
|
667
|
-
expect(publisher).toHaveBeenCalledWith(expect.objectContaining({
|
|
668
|
-
action: pondsocket_common_1.ClientActions.BROADCAST,
|
|
669
|
-
channelName: 'test',
|
|
670
|
-
event: 'test',
|
|
671
|
-
payload: {
|
|
672
|
-
test: 'test',
|
|
673
|
-
},
|
|
674
|
-
}));
|
|
675
|
-
publisher.mockClear();
|
|
676
|
-
channel.sendMessage('test', {
|
|
677
|
-
test: 'test',
|
|
678
|
-
});
|
|
679
|
-
expect(publisher).toHaveBeenCalledWith(expect.objectContaining({
|
|
680
|
-
action: pondsocket_common_1.ClientActions.BROADCAST,
|
|
681
|
-
channelName: 'test',
|
|
682
|
-
event: 'test',
|
|
683
|
-
payload: {
|
|
684
|
-
test: 'test',
|
|
685
|
-
},
|
|
686
|
-
}));
|
|
687
|
-
publisher.mockClear();
|
|
688
|
-
channel.sendMessage('test', {
|
|
689
|
-
test: 'test',
|
|
690
|
-
});
|
|
691
|
-
expect(publisher).toHaveBeenCalledWith(expect.objectContaining({
|
|
692
|
-
action: pondsocket_common_1.ClientActions.BROADCAST,
|
|
693
|
-
channelName: 'test',
|
|
694
|
-
event: 'test',
|
|
695
|
-
payload: {
|
|
696
|
-
test: 'test',
|
|
697
|
-
},
|
|
698
|
-
}));
|
|
699
|
-
});
|
|
700
687
|
it('should be able to wait for a message', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
701
688
|
const state = new pondsocket_common_1.BehaviorSubject(true);
|
|
702
689
|
const receiver = new pondsocket_common_1.Subject();
|
|
@@ -727,17 +714,9 @@ describe('Channel', () => {
|
|
|
727
714
|
});
|
|
728
715
|
}
|
|
729
716
|
};
|
|
730
|
-
const channel = new channel_1.Channel(publisher, state, 'test',
|
|
717
|
+
const channel = new channel_1.Channel(publisher, state, 'test', params);
|
|
731
718
|
channel.join();
|
|
732
|
-
|
|
733
|
-
requestId: 'test',
|
|
734
|
-
action: 'SYSTEM',
|
|
735
|
-
channelName: 'test',
|
|
736
|
-
event: pondsocket_common_1.Events.ACKNOWLEDGE,
|
|
737
|
-
payload: {
|
|
738
|
-
event: 'JOIN',
|
|
739
|
-
},
|
|
740
|
-
});
|
|
719
|
+
channel.acknowledge(receiver);
|
|
741
720
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
742
721
|
// @ts-expect-error - this is a test
|
|
743
722
|
const response = yield channel.sendForResponse('WAITING', {
|
package/dist.d.ts
CHANGED
|
@@ -16,6 +16,11 @@ declare class Channel<EventMap extends PondEventMap = PondEventMap, Presence ext
|
|
|
16
16
|
*/
|
|
17
17
|
channelState: ChannelState;
|
|
18
18
|
|
|
19
|
+
/**
|
|
20
|
+
* @desc Gets the current presence of the channel.
|
|
21
|
+
*/
|
|
22
|
+
presence (): Presence[];
|
|
23
|
+
|
|
19
24
|
/**
|
|
20
25
|
* @desc Connects to the channel.
|
|
21
26
|
*/
|
|
@@ -26,19 +31,6 @@ declare class Channel<EventMap extends PondEventMap = PondEventMap, Presence ext
|
|
|
26
31
|
*/
|
|
27
32
|
leave (): void;
|
|
28
33
|
|
|
29
|
-
/**
|
|
30
|
-
* @desc Monitors the channel for messages.
|
|
31
|
-
* @param callback - The callback to call when a message is received.
|
|
32
|
-
*/
|
|
33
|
-
onMessage<Event extends keyof EventMap> (callback: (event: Event, message: EventMap[Event]) => void): Unsubscribe;
|
|
34
|
-
|
|
35
|
-
/**
|
|
36
|
-
* @desc Monitors the channel for messages.
|
|
37
|
-
* @param event - The event to monitor.
|
|
38
|
-
* @param callback - The callback to call when a message is received.
|
|
39
|
-
*/
|
|
40
|
-
onMessageEvent<Event extends keyof EventMap> (event: Event, callback: (message: EventMap[Event]) => void): Unsubscribe;
|
|
41
|
-
|
|
42
34
|
/**
|
|
43
35
|
* @desc Monitors the channel state of the channel.
|
|
44
36
|
* @param callback - The callback to call when the connection state changes.
|
|
@@ -58,29 +50,23 @@ declare class Channel<EventMap extends PondEventMap = PondEventMap, Presence ext
|
|
|
58
50
|
onLeave (callback: (presence: Presence) => void): Unsubscribe;
|
|
59
51
|
|
|
60
52
|
/**
|
|
61
|
-
* @desc
|
|
62
|
-
* @param callback - The callback to call when a
|
|
63
|
-
*/
|
|
64
|
-
onPresenceChange (callback: (presence: PresencePayload<Presence>) => void): Unsubscribe;
|
|
65
|
-
|
|
66
|
-
/**
|
|
67
|
-
* @desc Sends a message to specific clients in the channel.
|
|
68
|
-
* @param event - The event to send.
|
|
69
|
-
* @param payload - The message to send.
|
|
53
|
+
* @desc Monitors the channel for messages.
|
|
54
|
+
* @param callback - The callback to call when a message is received.
|
|
70
55
|
*/
|
|
71
|
-
|
|
56
|
+
onMessage<Event extends keyof EventMap> (callback: (event: Event, message: EventMap[Event]) => void): Unsubscribe;
|
|
72
57
|
|
|
73
58
|
/**
|
|
74
|
-
* @desc
|
|
75
|
-
* @param
|
|
76
|
-
* @param
|
|
59
|
+
* @desc Monitors the channel for messages.
|
|
60
|
+
* @param event - The event to monitor.
|
|
61
|
+
* @param callback - The callback to call when a message is received.
|
|
77
62
|
*/
|
|
78
|
-
|
|
63
|
+
onMessageEvent<Event extends keyof EventMap> (event: Event, callback: (message: EventMap[Event]) => void): Unsubscribe;
|
|
79
64
|
|
|
80
65
|
/**
|
|
81
|
-
* @desc
|
|
66
|
+
* @desc Detects when clients change their presence in the channel.
|
|
67
|
+
* @param callback - The callback to call when a client changes their presence in the channel.
|
|
82
68
|
*/
|
|
83
|
-
|
|
69
|
+
onPresenceChange (callback: (presence: PresencePayload<Presence>) => void): Unsubscribe;
|
|
84
70
|
|
|
85
71
|
/**
|
|
86
72
|
* @desc Monitors the presence of the channel.
|
|
@@ -89,25 +75,18 @@ declare class Channel<EventMap extends PondEventMap = PondEventMap, Presence ext
|
|
|
89
75
|
onUsersChange (callback: (users: Presence[]) => void): Unsubscribe;
|
|
90
76
|
|
|
91
77
|
/**
|
|
92
|
-
* @desc
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
/**
|
|
97
|
-
* @desc Checks if the channel is stalled.
|
|
98
|
-
*/
|
|
99
|
-
isStalled (): boolean;
|
|
100
|
-
|
|
101
|
-
/**
|
|
102
|
-
* @desc Checks if the channel is closed.
|
|
78
|
+
* @desc Sends a message to specific clients in the channel.
|
|
79
|
+
* @param event - The event to send.
|
|
80
|
+
* @param payload - The message to send.
|
|
103
81
|
*/
|
|
104
|
-
|
|
82
|
+
sendMessage<Event extends keyof EventMap> (event: Event, payload: EventMap[Event]): void;
|
|
105
83
|
|
|
106
84
|
/**
|
|
107
|
-
* @desc
|
|
108
|
-
* @param
|
|
85
|
+
* @desc Sends a message to the server and waits for a response.
|
|
86
|
+
* @param sentEvent - The event to send.
|
|
87
|
+
* @param payload - The message to send.
|
|
109
88
|
*/
|
|
110
|
-
|
|
89
|
+
sendForResponse<Event extends EventWithResponse<EventMap>> (sentEvent: Event, payload: PayloadForResponse<EventMap, Event>): Promise<ResponseForEvent<EventMap, Event>>;
|
|
111
90
|
}
|
|
112
91
|
|
|
113
92
|
declare class PondClient {
|
|
@@ -116,7 +95,7 @@ declare class PondClient {
|
|
|
116
95
|
/**
|
|
117
96
|
* @desc Connects to the server and returns the socket.
|
|
118
97
|
*/
|
|
119
|
-
connect (
|
|
98
|
+
connect (): void;
|
|
120
99
|
|
|
121
100
|
/**
|
|
122
101
|
* @desc Returns the current state of the socket.
|