@eleven-am/pondsocket 0.1.11 → 0.1.12

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.
Files changed (90) hide show
  1. package/dist/client/channel.js +200 -0
  2. package/dist/client/index.d.ts +122 -0
  3. package/{pondClient/socket.js → dist/client/index.js} +30 -44
  4. package/dist/express/index.d.ts +36 -0
  5. package/dist/express/index.js +16 -0
  6. package/dist/index.d.ts +340 -0
  7. package/dist/index.js +4 -0
  8. package/dist/server/abstracts/abstractRequest.js +40 -0
  9. package/dist/server/abstracts/abstractRequest.test.js +41 -0
  10. package/dist/server/abstracts/abstractResponse.js +6 -0
  11. package/dist/server/abstracts/middleware.js +38 -0
  12. package/dist/server/abstracts/middleware.test.js +70 -0
  13. package/dist/server/channel/channelEngine.js +279 -0
  14. package/dist/server/channel/channelEngine.test.js +377 -0
  15. package/dist/server/channel/channelRequest.test.js +29 -0
  16. package/dist/server/channel/channelResponse.test.js +134 -0
  17. package/dist/server/channel/eventRequest.js +18 -0
  18. package/dist/server/channel/eventResponse.js +141 -0
  19. package/dist/server/endpoint/connectionResponse.js +50 -0
  20. package/dist/server/endpoint/endpoint.js +269 -0
  21. package/dist/server/endpoint/endpoint.test.js +406 -0
  22. package/dist/server/endpoint/endpointResponse.test.js +43 -0
  23. package/dist/server/pondChannel/joinRequest.js +29 -0
  24. package/dist/server/pondChannel/joinResponse.js +96 -0
  25. package/dist/server/pondChannel/pondChannel.js +161 -0
  26. package/dist/server/pondChannel/pondChannelResponse.test.js +108 -0
  27. package/dist/server/presence/presenceEngine.js +112 -0
  28. package/dist/server/presence/presenceEngine.test.js +104 -0
  29. package/dist/server/server/pondSocket.js +122 -0
  30. package/{pondSocket → dist/server/server}/server.test.js +7 -21
  31. package/{pondBase/baseClass.js → dist/server/utils/matchPattern.js} +33 -43
  32. package/{pondBase/baseClass.test.js → dist/server/utils/matchPattern.test.js} +16 -25
  33. package/dist/server/utils/subjectUtils.js +68 -0
  34. package/package.json +28 -12
  35. package/.eslintrc.js +0 -28
  36. package/base.d.ts +0 -1
  37. package/base.js +0 -17
  38. package/client.d.ts +0 -1
  39. package/client.js +0 -17
  40. package/index.d.ts +0 -1
  41. package/index.js +0 -17
  42. package/jest.config.js +0 -11
  43. package/pondBase/baseClass.d.ts +0 -55
  44. package/pondBase/enums.d.ts +0 -9
  45. package/pondBase/enums.js +0 -14
  46. package/pondBase/index.d.ts +0 -6
  47. package/pondBase/index.js +0 -22
  48. package/pondBase/pondBase.d.ts +0 -41
  49. package/pondBase/pondBase.js +0 -60
  50. package/pondBase/pondBase.test.js +0 -101
  51. package/pondBase/pubSub.d.ts +0 -82
  52. package/pondBase/pubSub.js +0 -158
  53. package/pondBase/pubSub.test.js +0 -332
  54. package/pondBase/simpleBase.d.ts +0 -126
  55. package/pondBase/simpleBase.js +0 -211
  56. package/pondBase/simpleBase.test.js +0 -153
  57. package/pondBase/types.d.ts +0 -2
  58. package/pondBase/types.js +0 -2
  59. package/pondClient/channel.d.ts +0 -77
  60. package/pondClient/channel.js +0 -167
  61. package/pondClient/index.d.ts +0 -2
  62. package/pondClient/index.js +0 -18
  63. package/pondClient/socket.d.ts +0 -41
  64. package/pondSocket/channel.d.ts +0 -129
  65. package/pondSocket/channel.js +0 -287
  66. package/pondSocket/channel.test.js +0 -377
  67. package/pondSocket/channelMiddleWare.d.ts +0 -28
  68. package/pondSocket/channelMiddleWare.js +0 -36
  69. package/pondSocket/endpoint.d.ts +0 -90
  70. package/pondSocket/endpoint.js +0 -320
  71. package/pondSocket/endpoint.test.js +0 -490
  72. package/pondSocket/enums.d.ts +0 -19
  73. package/pondSocket/enums.js +0 -25
  74. package/pondSocket/index.d.ts +0 -7
  75. package/pondSocket/index.js +0 -23
  76. package/pondSocket/pondChannel.d.ts +0 -79
  77. package/pondSocket/pondChannel.js +0 -211
  78. package/pondSocket/pondChannel.test.js +0 -430
  79. package/pondSocket/pondResponse.d.ts +0 -25
  80. package/pondSocket/pondResponse.js +0 -120
  81. package/pondSocket/pondSocket.d.ts +0 -47
  82. package/pondSocket/pondSocket.js +0 -94
  83. package/pondSocket/socketMiddleWare.d.ts +0 -6
  84. package/pondSocket/socketMiddleWare.js +0 -32
  85. package/pondSocket/types.d.ts +0 -74
  86. package/pondSocket/types.js +0 -2
  87. package/socket.d.ts +0 -1
  88. package/socket.js +0 -17
  89. package/tsconfig.eslint.json +0 -5
  90. package/tsconfig.json +0 -90
@@ -0,0 +1,279 @@
1
+ "use strict";
2
+ var __rest = (this && this.__rest) || function (s, e) {
3
+ var t = {};
4
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
5
+ t[p] = s[p];
6
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
7
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
8
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
9
+ t[p[i]] = s[p[i]];
10
+ }
11
+ return t;
12
+ };
13
+ Object.defineProperty(exports, "__esModule", { value: true });
14
+ exports.ChannelEngine = exports.ServerActions = void 0;
15
+ const eventRequest_1 = require("./eventRequest");
16
+ const eventResponse_1 = require("./eventResponse");
17
+ const presenceEngine_1 = require("../presence/presenceEngine");
18
+ const subjectUtils_1 = require("../utils/subjectUtils");
19
+ var ServerActions;
20
+ (function (ServerActions) {
21
+ ServerActions["PRESENCE"] = "PRESENCE";
22
+ ServerActions["SYSTEM"] = "SYSTEM";
23
+ ServerActions["BROADCAST"] = "BROADCAST";
24
+ ServerActions["ERROR"] = "ERROR";
25
+ })(ServerActions = exports.ServerActions || (exports.ServerActions = {}));
26
+ class ChannelEngine {
27
+ constructor(name, parent) {
28
+ this.name = name;
29
+ this._receiver = new subjectUtils_1.Subject();
30
+ this._users = new Map();
31
+ this._parentEngine = parent;
32
+ }
33
+ /**
34
+ * @desc Adds a user to the channel
35
+ * @param userId - The id of the user to add
36
+ * @param assigns - The assigns to add to the user
37
+ * @param onMessage - The callback to call when a message is received
38
+ */
39
+ addUser(userId, assigns, onMessage) {
40
+ const oldUser = this._users.get(userId);
41
+ if (oldUser) {
42
+ throw new Error(`ChannelEngine: User with id ${userId} already exists in channel ${this.name}`);
43
+ }
44
+ this._users.set(userId, assigns);
45
+ return this._subscribe(userId, onMessage);
46
+ }
47
+ /**
48
+ * @desc Removes a user from the channel
49
+ * @param userId - The id of the user to remove
50
+ * @param isPond - Whether the user is a pond or not
51
+ */
52
+ removeUser(userId, isPond = false) {
53
+ const user = this._users.get(userId);
54
+ if (user) {
55
+ this._users.delete(userId);
56
+ this.unTrackPresence(userId, true);
57
+ this._receiver.unsubscribe(userId);
58
+ if (this._users.size === 0) {
59
+ this._parentEngine.destroyChannel();
60
+ }
61
+ }
62
+ else if (!isPond) {
63
+ throw new Error(`ChannelEngine: User with id ${userId} does not exist in channel ${this.name}`);
64
+ }
65
+ }
66
+ /**
67
+ * @desc Kicks a user from the channel
68
+ * @param userId - The id of the user to kick
69
+ * @param reason - The reason for kicking the user
70
+ */
71
+ kickUser(userId, reason) {
72
+ this.sendMessage('channel', [userId], ServerActions.SYSTEM, 'kicked_out', {
73
+ message: 'You have been kicked out of the channel',
74
+ reason,
75
+ });
76
+ this.removeUser(userId);
77
+ this.sendMessage('channel', 'all_users', ServerActions.SYSTEM, 'kicked', {
78
+ userId,
79
+ reason,
80
+ });
81
+ }
82
+ /**
83
+ * @desc Self destructs the channel
84
+ * @param reason - The reason for self-destructing the channel
85
+ */
86
+ destroy(reason) {
87
+ this.sendMessage('channel', 'all_users', ServerActions.ERROR, 'destroyed', {
88
+ message: 'Channel has been destroyed',
89
+ reason,
90
+ });
91
+ this._parentEngine.destroyChannel();
92
+ this._users.forEach((_, userId) => this._receiver.unsubscribe(userId));
93
+ }
94
+ /**
95
+ * @desc Begins tracking a user's presence
96
+ * @param userId - The id of the user to track
97
+ * @param presence - The initial presence of the user
98
+ */
99
+ trackPresence(userId, presence) {
100
+ this._presenceEngine = this._presenceEngine || new presenceEngine_1.PresenceEngine();
101
+ if (!this._users.has(userId)) {
102
+ throw new Error(`ChannelEngine: User with id ${userId} does not exist in channel ${this.name}`);
103
+ }
104
+ if (this._presenceEngine.getUserPresence(userId)) {
105
+ throw new Error(`ChannelEngine: User with id ${userId} already has a presence subscription in channel ${this.name}`);
106
+ }
107
+ this._presenceEngine.trackPresence(userId, presence, (change) => {
108
+ const { type } = change, rest = __rest(change, ["type"]);
109
+ this.sendMessage('channel', [userId], ServerActions.PRESENCE, type, rest);
110
+ });
111
+ }
112
+ /**
113
+ * @desc Updates a user's presence
114
+ * @param userId - The id of the user to update
115
+ * @param presence - The new presence of the user
116
+ */
117
+ updatePresence(userId, presence) {
118
+ if (!this._users.has(userId)) {
119
+ throw new Error(`ChannelEngine: User with id ${userId} does not exist in channel ${this.name}`);
120
+ }
121
+ if (this._presenceEngine) {
122
+ this._presenceEngine.updatePresence(userId, presence);
123
+ }
124
+ else {
125
+ throw new Error('ChannelEngine: Presence engine is not initialized');
126
+ }
127
+ }
128
+ /**
129
+ * @desc Updates a user's assigns
130
+ * @param userId - The id of the user to update
131
+ * @param assigns - The new assigns of the user
132
+ */
133
+ updateAssigns(userId, assigns) {
134
+ const user = this._users.get(userId);
135
+ if (user) {
136
+ this._users.set(userId, Object.assign(Object.assign({}, user), assigns));
137
+ }
138
+ else {
139
+ throw new Error(`ChannelEngine: User with id ${userId} does not exist in channel ${this.name}`);
140
+ }
141
+ }
142
+ /**
143
+ * @desc Gets the data of a user
144
+ * @param userId - The id of the user to get
145
+ */
146
+ getUserData(userId) {
147
+ const presence = this._presenceEngine ? this._presenceEngine.getUserPresence(userId) : {};
148
+ if (this._users.has(userId)) {
149
+ return {
150
+ id: userId,
151
+ assigns: this._users.get(userId),
152
+ presence: presence || {},
153
+ };
154
+ }
155
+ return undefined;
156
+ }
157
+ /**
158
+ * @desc Gets the assign data of all users
159
+ */
160
+ getAssigns() {
161
+ const assigns = {};
162
+ this._users.forEach((value, key) => {
163
+ assigns[key] = value;
164
+ });
165
+ return assigns;
166
+ }
167
+ /**
168
+ * @desc Gets the presence data of all users
169
+ */
170
+ getPresence() {
171
+ if (this._presenceEngine) {
172
+ return this._presenceEngine.getPresence();
173
+ }
174
+ return {};
175
+ }
176
+ /**
177
+ * @desc Stops tracking a user's presence
178
+ * @param userId - The id of the user to be untracked
179
+ * @param isPond - Whether the user is a pond
180
+ */
181
+ unTrackPresence(userId, isPond = false) {
182
+ if (this._presenceEngine) {
183
+ if (isPond && this._presenceEngine.getUserPresence(userId)) {
184
+ this._presenceEngine.removePresence(userId);
185
+ }
186
+ else if (!isPond) {
187
+ this._presenceEngine.removePresence(userId);
188
+ }
189
+ }
190
+ }
191
+ /**
192
+ * @desc Sends a message to a specified set of users, from a specified sender
193
+ * @param sender - The sender of the message
194
+ * @param recipient - The users to send the message to
195
+ * @param action - The action of the message
196
+ * @param event - The event name
197
+ * @param payload - The payload of the message
198
+ * @private
199
+ */
200
+ sendMessage(sender, recipient, action, event, payload) {
201
+ if (!this._users.has(sender) && sender !== 'channel') {
202
+ throw new Error(`ChannelEngine: User with id ${sender} does not exist in channel ${this.name}`);
203
+ }
204
+ this._receiver.next({
205
+ sender,
206
+ recipients: this._getUsersFromRecipients(recipient, sender),
207
+ action,
208
+ payload,
209
+ event,
210
+ });
211
+ }
212
+ /**
213
+ * @desc Handles a message from a user
214
+ * @param userId - The id of the user who sent the message
215
+ * @param message - The message received
216
+ */
217
+ broadcastMessage(userId, message) {
218
+ if (!this._users.has(userId)) {
219
+ throw new Error(`ChannelEngine: User with id ${userId} does not exist in channel ${this.name}`);
220
+ }
221
+ const responseEvent = {
222
+ event: message.event,
223
+ payload: message.payload,
224
+ action: ServerActions.BROADCAST,
225
+ sender: userId,
226
+ recipients: this._getUsersFromRecipients(message.addresses || 'all_users', userId),
227
+ };
228
+ const request = new eventRequest_1.EventRequest(responseEvent, this);
229
+ const response = new eventResponse_1.EventResponse(responseEvent, this);
230
+ this._parentEngine.execute(request, response, () => {
231
+ this.sendMessage('channel', [userId], ServerActions.ERROR, 'error_no_handler', {
232
+ message: 'A handler did not respond to the event',
233
+ code: 404,
234
+ });
235
+ });
236
+ }
237
+ /**
238
+ * @desc Subscribes to a user's messages
239
+ * @param userId - The id of the user to subscribe to
240
+ * @param onMessage - The callback to call when a message is received
241
+ * @private
242
+ */
243
+ _subscribe(userId, onMessage) {
244
+ this._receiver.subscribe(userId, (event) => {
245
+ if (event.recipients.includes(userId)) {
246
+ onMessage({
247
+ action: event.action,
248
+ event: event.event,
249
+ payload: event.payload,
250
+ channelName: this.name,
251
+ });
252
+ }
253
+ });
254
+ }
255
+ _getUsersFromRecipients(recipients, sender) {
256
+ const allUsers = Array.from(this._users.keys());
257
+ let users;
258
+ switch (recipients) {
259
+ case 'all_users':
260
+ users = allUsers;
261
+ break;
262
+ case 'all_except_sender':
263
+ if (sender === 'channel') {
264
+ throw new Error('ChannelEngine: Cannot send to all users except sender when sender is channel');
265
+ }
266
+ users = allUsers.filter((user) => user !== sender);
267
+ break;
268
+ default:
269
+ const absentUsers = recipients.filter((user) => !allUsers.includes(user));
270
+ if (absentUsers.length > 0) {
271
+ throw new Error(`ChannelEngine: Users ${absentUsers.join(', ')} are not in channel ${this.name}`);
272
+ }
273
+ users = recipients;
274
+ break;
275
+ }
276
+ return users;
277
+ }
278
+ }
279
+ exports.ChannelEngine = ChannelEngine;
@@ -0,0 +1,377 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createParentEngine = void 0;
4
+ const channelEngine_1 = require("./channelEngine");
5
+ const presenceEngine_1 = require("../presence/presenceEngine");
6
+ const createParentEngine = () => {
7
+ const parentEngine = {
8
+ destroyChannel: jest.fn(),
9
+ execute: jest.fn(),
10
+ };
11
+ return parentEngine;
12
+ };
13
+ exports.createParentEngine = createParentEngine;
14
+ describe('ChannelEngine', () => {
15
+ it('should add user to channel', () => {
16
+ const onMessage = jest.fn();
17
+ const parentEngine = (0, exports.createParentEngine)();
18
+ const channelEngine = new channelEngine_1.ChannelEngine('test', parentEngine);
19
+ expect(channelEngine['_users'].size).toEqual(0);
20
+ expect(channelEngine.getUserData('test')).not.toBeDefined();
21
+ channelEngine.addUser('test', { test: 1 }, onMessage);
22
+ expect(channelEngine['_users'].size).toEqual(1);
23
+ expect(channelEngine['_users'].get('test')).toEqual({ test: 1 });
24
+ expect(channelEngine.getUserData('test')).toEqual({
25
+ assigns: { test: 1 },
26
+ presence: {},
27
+ id: 'test',
28
+ });
29
+ });
30
+ it('should throw error if user is already in channel', () => {
31
+ const onMessage = jest.fn();
32
+ const parentEngine = (0, exports.createParentEngine)();
33
+ const channelEngine = new channelEngine_1.ChannelEngine('testChannel', parentEngine);
34
+ channelEngine.addUser('test', { test: 1 }, onMessage);
35
+ expect(() => {
36
+ channelEngine.addUser('test', { test: 1 }, onMessage);
37
+ }).toThrow('ChannelEngine: User with id test already exists in channel testChannel');
38
+ });
39
+ it('should update a users assigns', () => {
40
+ const onMessage = jest.fn();
41
+ const parentEngine = (0, exports.createParentEngine)();
42
+ const channelEngine = new channelEngine_1.ChannelEngine('test', parentEngine);
43
+ channelEngine.addUser('test', { test: 1 }, onMessage);
44
+ expect(channelEngine.getUserData('test')).toEqual({
45
+ assigns: { test: 1 },
46
+ presence: {},
47
+ id: 'test',
48
+ });
49
+ channelEngine.updateAssigns('test', { test: 2 });
50
+ expect(channelEngine.getUserData('test')).toEqual({
51
+ assigns: { test: 2 },
52
+ presence: {},
53
+ id: 'test',
54
+ });
55
+ });
56
+ it('should throw error if user is not in channel', () => {
57
+ const parentEngine = (0, exports.createParentEngine)();
58
+ const channelEngine = new channelEngine_1.ChannelEngine('testChannel', parentEngine);
59
+ expect(() => {
60
+ channelEngine.updateAssigns('test', { test: 2 });
61
+ }).toThrow('ChannelEngine: User with id test does not exist in channel testChannel');
62
+ });
63
+ it('should be able to get users assigns in the channel', () => {
64
+ const onMessage = jest.fn();
65
+ const parentEngine = (0, exports.createParentEngine)();
66
+ const channelEngine = new channelEngine_1.ChannelEngine('test', parentEngine);
67
+ expect(channelEngine.getAssigns()).toEqual({});
68
+ channelEngine.addUser('test', { test: 1 }, onMessage);
69
+ expect(channelEngine.getAssigns()).toEqual({
70
+ test: { test: 1 },
71
+ });
72
+ channelEngine.addUser('test2', { test: 2 }, onMessage);
73
+ expect(channelEngine.getAssigns()).toEqual({
74
+ test: { test: 1 },
75
+ test2: { test: 2 },
76
+ });
77
+ });
78
+ it('should be able to track presence', () => {
79
+ const onMessage = jest.fn();
80
+ const parentEngine = (0, exports.createParentEngine)();
81
+ const channelEngine = new channelEngine_1.ChannelEngine('test', parentEngine);
82
+ channelEngine.addUser('test', { test: 1 }, onMessage);
83
+ expect(channelEngine.getUserData('test')).toEqual({
84
+ assigns: { test: 1 },
85
+ presence: {},
86
+ id: 'test',
87
+ });
88
+ expect(channelEngine['_presenceEngine']).not.toBeDefined();
89
+ channelEngine.trackPresence('test', { test: 2 });
90
+ expect(channelEngine['_presenceEngine']).toBeDefined();
91
+ expect(channelEngine.getUserData('test')).toEqual({
92
+ assigns: { test: 1 },
93
+ presence: { test: 2 },
94
+ id: 'test',
95
+ });
96
+ });
97
+ it('should throw error if user is not in channel', () => {
98
+ const parentEngine = (0, exports.createParentEngine)();
99
+ const channelEngine = new channelEngine_1.ChannelEngine('testChannel', parentEngine);
100
+ expect(() => {
101
+ channelEngine.trackPresence('test', { test: 2 });
102
+ }).toThrow('ChannelEngine: User with id test does not exist in channel testChannel');
103
+ });
104
+ it('should throw error if channel is already tracking the users presence', () => {
105
+ const onMessage = jest.fn();
106
+ const parentEngine = (0, exports.createParentEngine)();
107
+ const channelEngine = new channelEngine_1.ChannelEngine('test', parentEngine);
108
+ channelEngine.addUser('test', { test: 1 }, onMessage);
109
+ channelEngine.trackPresence('test', { test: 2 });
110
+ expect(() => {
111
+ channelEngine.trackPresence('test', { test: 2 });
112
+ }).toThrow('ChannelEngine: User with id test already has a presence subscription in channel test');
113
+ });
114
+ it('should be able to list presence', () => {
115
+ const onMessage = jest.fn();
116
+ const parentEngine = (0, exports.createParentEngine)();
117
+ const channelEngine = new channelEngine_1.ChannelEngine('test', parentEngine);
118
+ expect(channelEngine.getPresence()).toEqual({});
119
+ channelEngine.addUser('test', { test: 1 }, onMessage);
120
+ channelEngine.addUser('test2', { test: 2 }, onMessage);
121
+ channelEngine.trackPresence('test', { test: 2 });
122
+ expect(onMessage).toHaveBeenCalledWith({
123
+ channelName: 'test',
124
+ action: channelEngine_1.ServerActions.PRESENCE,
125
+ event: presenceEngine_1.PresenceEventTypes.JOIN,
126
+ payload: {
127
+ presence: [{ test: 2 }],
128
+ changed: {
129
+ test: 2,
130
+ },
131
+ },
132
+ });
133
+ channelEngine.trackPresence('test2', { test: 3 });
134
+ expect(channelEngine.getPresence()).toEqual({
135
+ test: { test: 2 },
136
+ test2: { test: 3 },
137
+ });
138
+ expect(onMessage).toHaveBeenCalledTimes(3);
139
+ });
140
+ it('should update a users presence', () => {
141
+ const onMessage = jest.fn();
142
+ const parentEngine = (0, exports.createParentEngine)();
143
+ const channelEngine = new channelEngine_1.ChannelEngine('test', parentEngine);
144
+ channelEngine.addUser('test', { test: 1 }, onMessage);
145
+ channelEngine.trackPresence('test', { test: 2 });
146
+ expect(channelEngine.getUserData('test')).toEqual({
147
+ assigns: { test: 1 },
148
+ presence: { test: 2 },
149
+ id: 'test',
150
+ });
151
+ channelEngine.updatePresence('test', { test: 3 });
152
+ expect(channelEngine.getUserData('test')).toEqual({
153
+ assigns: { test: 1 },
154
+ presence: { test: 3 },
155
+ id: 'test',
156
+ });
157
+ });
158
+ it('should throw error if user is not in channel', () => {
159
+ const parentEngine = (0, exports.createParentEngine)();
160
+ const channelEngine = new channelEngine_1.ChannelEngine('testChannel', parentEngine);
161
+ expect(() => {
162
+ channelEngine.updatePresence('test', { test: 2 });
163
+ }).toThrow('ChannelEngine: User with id test does not exist in channel testChannel');
164
+ });
165
+ it('should throw error if user is not tracking presence', () => {
166
+ const onMessage = jest.fn();
167
+ const parentEngine = (0, exports.createParentEngine)();
168
+ const channelEngine = new channelEngine_1.ChannelEngine('test', parentEngine);
169
+ channelEngine.addUser('test', { test: 1 }, onMessage);
170
+ expect(() => {
171
+ channelEngine.updatePresence('test', { test: 2 });
172
+ }).toThrow('ChannelEngine: Presence engine is not initialized');
173
+ });
174
+ it('should remove user from channel', () => {
175
+ const onMessage = jest.fn();
176
+ const parentEngine = (0, exports.createParentEngine)();
177
+ const channelEngine = new channelEngine_1.ChannelEngine('test', parentEngine);
178
+ channelEngine.addUser('test', { test: 1 }, onMessage);
179
+ expect(channelEngine['_users'].size).toEqual(1);
180
+ expect(channelEngine.getUserData('test')).toBeDefined();
181
+ channelEngine.removeUser('test');
182
+ expect(channelEngine['_users'].size).toEqual(0);
183
+ expect(channelEngine.getUserData('test')).not.toBeDefined();
184
+ });
185
+ it('should throw error if user is not in channel', () => {
186
+ const parentEngine = (0, exports.createParentEngine)();
187
+ const channelEngine = new channelEngine_1.ChannelEngine('testChannel', parentEngine);
188
+ expect(() => {
189
+ channelEngine.removeUser('test');
190
+ }).toThrow('ChannelEngine: User with id test does not exist in channel testChannel');
191
+ });
192
+ it('should untrack presence when user is removed', () => {
193
+ const onMessage = jest.fn();
194
+ const parentEngine = (0, exports.createParentEngine)();
195
+ const channelEngine = new channelEngine_1.ChannelEngine('test', parentEngine);
196
+ channelEngine.addUser('test', { test: 1 }, onMessage);
197
+ channelEngine.trackPresence('test', { test: 2 });
198
+ channelEngine.addUser('test2', { test: 1 }, onMessage);
199
+ channelEngine.trackPresence('test2', { test: 2 });
200
+ expect(channelEngine.getPresence()).toEqual({
201
+ test: { test: 2 },
202
+ test2: { test: 2 },
203
+ });
204
+ onMessage.mockClear();
205
+ channelEngine.removeUser('test');
206
+ expect(channelEngine.getPresence()).toEqual({
207
+ test2: { test: 2 },
208
+ });
209
+ expect(onMessage).toHaveBeenCalledWith({
210
+ channelName: 'test',
211
+ event: presenceEngine_1.PresenceEventTypes.LEAVE,
212
+ action: channelEngine_1.ServerActions.PRESENCE,
213
+ payload: {
214
+ presence: [{ test: 2 }],
215
+ changed: {
216
+ test: 2,
217
+ },
218
+ },
219
+ });
220
+ });
221
+ it('should throw error if user is not in channel and isPond is false', () => {
222
+ const parentEngine = (0, exports.createParentEngine)();
223
+ const channelEngine = new channelEngine_1.ChannelEngine('testChannel', parentEngine);
224
+ // add a user to the channel
225
+ channelEngine.addUser('test', { test: 1 }, jest.fn());
226
+ // track the added user's presence
227
+ channelEngine.trackPresence('test', { test: 2 });
228
+ // we do this because we want to initialize the presence engine
229
+ // the engine is not initialized by default when a channel is created
230
+ expect(() => {
231
+ // now we try to untrack the presence of a user that is not in the channel
232
+ channelEngine.unTrackPresence('test1', false);
233
+ }).toThrow('PresenceEngine: Presence with key test1 does not exist');
234
+ });
235
+ it('should not throw error if user is not in channel and isPond is true', () => {
236
+ const parentEngine = (0, exports.createParentEngine)();
237
+ const channelEngine = new channelEngine_1.ChannelEngine('testChannel', parentEngine);
238
+ // add a user to the channel
239
+ channelEngine.addUser('test', { test: 1 }, jest.fn());
240
+ // track the added user's presence
241
+ channelEngine.trackPresence('test', { test: 2 });
242
+ // we do this because we want to initialize the presence engine
243
+ // the engine is not initialized by default when a xhannel is created
244
+ expect(() => {
245
+ // now we try to untrack the presence of a user that is not in the channel
246
+ channelEngine.unTrackPresence('test', true);
247
+ }).not.toThrow();
248
+ });
249
+ it('should be able to kick a user from the channel', () => {
250
+ const onMessage = jest.fn();
251
+ const parentEngine = (0, exports.createParentEngine)();
252
+ const channelEngine = new channelEngine_1.ChannelEngine('test', parentEngine);
253
+ channelEngine.addUser('test', { test: 1 }, onMessage);
254
+ channelEngine.addUser('test2', { test: 1 }, onMessage);
255
+ channelEngine.kickUser('test2', 'test reason');
256
+ expect(channelEngine['_users'].size).toEqual(1);
257
+ expect(channelEngine.getUserData('test2')).not.toBeDefined();
258
+ expect(onMessage.mock.calls[0][0]).toStrictEqual({
259
+ action: channelEngine_1.ServerActions.SYSTEM,
260
+ channelName: 'test',
261
+ event: 'kicked_out',
262
+ payload: {
263
+ reason: 'test reason',
264
+ message: 'You have been kicked out of the channel',
265
+ },
266
+ });
267
+ expect(onMessage.mock.calls[1][0]).toStrictEqual({
268
+ action: channelEngine_1.ServerActions.SYSTEM,
269
+ channelName: 'test',
270
+ event: 'kicked',
271
+ payload: {
272
+ reason: 'test reason',
273
+ userId: 'test2',
274
+ },
275
+ });
276
+ expect(onMessage).toHaveBeenCalledTimes(2);
277
+ });
278
+ it('should call destroy on parent engine', () => {
279
+ const parentEngine = (0, exports.createParentEngine)();
280
+ const channelEngine = new channelEngine_1.ChannelEngine('test', parentEngine);
281
+ channelEngine.destroy('test');
282
+ expect(parentEngine.destroyChannel).toHaveBeenCalled();
283
+ });
284
+ it('should broadcast a message to all users', () => {
285
+ const onMessage = jest.fn();
286
+ const parentEngine = (0, exports.createParentEngine)();
287
+ parentEngine.execute = (_, res) => {
288
+ res.accept();
289
+ };
290
+ const channelEngine = new channelEngine_1.ChannelEngine('test', parentEngine);
291
+ channelEngine.addUser('test', { test: 1 }, onMessage);
292
+ channelEngine.addUser('test2', { test: 1 }, onMessage);
293
+ channelEngine.sendMessage('channel', 'all_users', channelEngine_1.ServerActions.BROADCAST, 'test', { test: 2 });
294
+ expect(onMessage.mock.calls[0][0]).toStrictEqual({
295
+ action: channelEngine_1.ServerActions.BROADCAST,
296
+ channelName: 'test',
297
+ event: 'test',
298
+ payload: {
299
+ test: 2,
300
+ },
301
+ });
302
+ expect(onMessage).toHaveBeenCalledTimes(2);
303
+ onMessage.mockClear();
304
+ channelEngine.sendMessage('test2', 'all_except_sender', channelEngine_1.ServerActions.BROADCAST, 'test', { test: 3 });
305
+ expect(onMessage).toHaveBeenCalledTimes(1);
306
+ onMessage.mockClear();
307
+ // when user is not in channel it throws an error
308
+ expect(() => {
309
+ channelEngine.sendMessage('test3', 'all_except_sender', channelEngine_1.ServerActions.BROADCAST, 'test', { test: 3 });
310
+ }).toThrow('ChannelEngine: User with id test3 does not exist in channel test');
311
+ });
312
+ it('should broadcast a message to all users except sender', () => {
313
+ const onMessage = jest.fn();
314
+ const parentEngine = (0, exports.createParentEngine)();
315
+ parentEngine.execute = (_, res) => {
316
+ res.accept();
317
+ };
318
+ const channelEngine = new channelEngine_1.ChannelEngine('test', parentEngine);
319
+ channelEngine.addUser('test', { test: 1 }, onMessage);
320
+ channelEngine.addUser('test2', { test: 1 }, onMessage);
321
+ channelEngine.sendMessage('test2', 'all_except_sender', channelEngine_1.ServerActions.BROADCAST, 'test', { test: 2 });
322
+ expect(onMessage.mock.calls[0][0]).toStrictEqual({
323
+ action: channelEngine_1.ServerActions.BROADCAST,
324
+ channelName: 'test',
325
+ event: 'test',
326
+ payload: {
327
+ test: 2,
328
+ },
329
+ });
330
+ expect(onMessage).toHaveBeenCalledTimes(1);
331
+ // when user is not in channel it throws an error
332
+ expect(() => {
333
+ channelEngine.sendMessage('test3', 'all_except_sender', channelEngine_1.ServerActions.BROADCAST, 'test', { test: 3 });
334
+ }).toThrow('ChannelEngine: User with id test3 does not exist in channel test');
335
+ // when sender is channel itself it throws an error
336
+ expect(() => {
337
+ channelEngine.sendMessage('channel', 'all_except_sender', channelEngine_1.ServerActions.BROADCAST, 'test', { test: 3 });
338
+ }).toThrow('ChannelEngine: Cannot send to all users except sender when sender is channel');
339
+ });
340
+ it('should broadcast a message to specific users', () => {
341
+ const onMessage = jest.fn();
342
+ const parentEngine = (0, exports.createParentEngine)();
343
+ parentEngine.execute = (_, res) => {
344
+ res.accept();
345
+ };
346
+ const channelEngine = new channelEngine_1.ChannelEngine('test', parentEngine);
347
+ channelEngine.addUser('test', { test: 1 }, onMessage);
348
+ channelEngine.addUser('test2', { test: 1 }, onMessage);
349
+ channelEngine.addUser('test3', { test: 1 }, onMessage);
350
+ channelEngine.sendMessage('test2', ['test', 'test3'], channelEngine_1.ServerActions.BROADCAST, 'test', { test: 2 });
351
+ expect(onMessage.mock.calls[0][0]).toStrictEqual({
352
+ action: channelEngine_1.ServerActions.BROADCAST,
353
+ channelName: 'test',
354
+ event: 'test',
355
+ payload: {
356
+ test: 2,
357
+ },
358
+ });
359
+ expect(onMessage.mock.calls[1][0]).toStrictEqual({
360
+ action: channelEngine_1.ServerActions.BROADCAST,
361
+ channelName: 'test',
362
+ event: 'test',
363
+ payload: {
364
+ test: 2,
365
+ },
366
+ });
367
+ expect(onMessage).toHaveBeenCalledTimes(2);
368
+ // when recipient is not in channel it throws an error
369
+ expect(() => {
370
+ channelEngine.sendMessage('test3', ['test', 'test3', 'test4'], channelEngine_1.ServerActions.BROADCAST, 'test', { test: 3 });
371
+ }).toThrow('ChannelEngine: Users test4 are not in channel test');
372
+ // when sender is not in channel it throws an error
373
+ expect(() => {
374
+ channelEngine.sendMessage('test4', ['test', 'test3'], channelEngine_1.ServerActions.BROADCAST, 'test', { test: 3 });
375
+ }).toThrow('ChannelEngine: User with id test4 does not exist in channel test');
376
+ });
377
+ });
@@ -0,0 +1,29 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const channelResponse_test_1 = require("./channelResponse.test");
4
+ const eventRequest_1 = require("./eventRequest");
5
+ describe('ChannelRequest', () => {
6
+ it('should create a new ChannelRequest', () => {
7
+ const channelEngine = (0, channelResponse_test_1.createChannelEngine)();
8
+ const event = (0, channelResponse_test_1.createChannelEvent)();
9
+ const channelRequest = new eventRequest_1.EventRequest(event, channelEngine);
10
+ expect(channelRequest).toBeDefined();
11
+ });
12
+ it('should return the payload', () => {
13
+ const channelEngine = (0, channelResponse_test_1.createChannelEngine)();
14
+ const event = (0, channelResponse_test_1.createChannelEvent)();
15
+ const channelRequest = new eventRequest_1.EventRequest(event, channelEngine);
16
+ expect(channelRequest.event.payload).toEqual(event.payload);
17
+ });
18
+ it('should return the user', () => {
19
+ const channelEngine = (0, channelResponse_test_1.createChannelEngine)();
20
+ const event = (0, channelResponse_test_1.createChannelEvent)();
21
+ const channelRequest = new eventRequest_1.EventRequest(event, channelEngine);
22
+ // because the user in the event does not exist in the channel, this should throw an error
23
+ expect(() => channelRequest.user).toThrow();
24
+ // add the user to the channel
25
+ channelEngine.addUser(event.sender, { assign: 'assign' }, () => { });
26
+ // now the user should be returned
27
+ expect(channelRequest.user).toEqual(channelEngine.getUserData(event.sender));
28
+ });
29
+ });