@eleven-am/pondsocket 0.1.158 → 0.1.161

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.
@@ -1,4 +1,13 @@
1
1
  "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
2
11
  var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
3
12
  if (kind === "m") throw new TypeError("Private method is not writable");
4
13
  if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
@@ -41,8 +50,12 @@ class AbstractRequest {
41
50
  get assigns() {
42
51
  return this._engine.getAssigns();
43
52
  }
44
- get presence() {
45
- return this._engine.presenceEngine.getPresence();
53
+ getPresence() {
54
+ return __awaiter(this, void 0, void 0, function* () {
55
+ const external = yield this._engine.getPubSubPresence();
56
+ const internal = this._engine.presenceEngine.getPresence();
57
+ return Object.assign(Object.assign({}, internal), external);
58
+ });
46
59
  }
47
60
  /**
48
61
  * @desc Parses the event and returns true if the event matches the path
@@ -1,16 +1,25 @@
1
1
  "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
2
11
  Object.defineProperty(exports, "__esModule", { value: true });
3
12
  const abstractRequest_1 = require("./abstractRequest");
4
13
  const eventResponse_test_1 = require("../channel/eventResponse.test");
5
14
  const createMockChannelEngine = () => (0, eventResponse_test_1.createChannelEngine)().channelEngine;
6
15
  describe('AbstractRequest', () => {
7
- it('should be able to be instantiated', () => {
16
+ it('should be able to be instantiated', () => __awaiter(void 0, void 0, void 0, function* () {
8
17
  const request = new abstractRequest_1.AbstractRequest('/test', createMockChannelEngine(), {});
9
18
  expect(request).toBeTruthy();
10
19
  expect(request.channelName).toBe('test');
11
20
  expect(request.assigns).toEqual({});
12
- expect(request.presence).toEqual({});
13
- });
21
+ expect(yield request.getPresence()).toEqual({});
22
+ }));
14
23
  it('should be able to parse queries', () => {
15
24
  const request = new abstractRequest_1.AbstractRequest('/1234?choke=balls', createMockChannelEngine(), {});
16
25
  expect(() => request.event).toThrowError('Event was not parsed');
@@ -1,4 +1,13 @@
1
1
  "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
2
11
  var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
3
12
  if (kind === "m") throw new TypeError("Private method is not writable");
4
13
  if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
@@ -21,7 +30,7 @@ var __rest = (this && this.__rest) || function (s, e) {
21
30
  }
22
31
  return t;
23
32
  };
24
- var _ChannelEngine_instances, _ChannelEngine_receiver, _ChannelEngine_presenceEngine, _ChannelEngine_users, _ChannelEngine_parentEngine, _ChannelEngine_subscribe, _ChannelEngine_getUsersFromRecipients, _ChannelEngine_buildSubscription, _ChannelEngine_removeUser, _Channel_engine;
33
+ var _ChannelEngine_instances, _ChannelEngine_receiver, _ChannelEngine_pubSubCLient, _ChannelEngine_presenceEngine, _ChannelEngine_users, _ChannelEngine_parentEngine, _ChannelEngine_subscribe, _ChannelEngine_getUsersFromRecipients, _ChannelEngine_buildSubscription, _ChannelEngine_removeUser, _ChannelEngine_initPubSub, _Channel_engine;
25
34
  Object.defineProperty(exports, "__esModule", { value: true });
26
35
  exports.Channel = exports.ChannelEngine = void 0;
27
36
  const pondsocket_common_1 = require("@eleven-am/pondsocket-common");
@@ -33,13 +42,16 @@ class ChannelEngine {
33
42
  constructor(name, parent) {
34
43
  _ChannelEngine_instances.add(this);
35
44
  _ChannelEngine_receiver.set(this, void 0);
45
+ _ChannelEngine_pubSubCLient.set(this, void 0);
36
46
  _ChannelEngine_presenceEngine.set(this, void 0);
37
47
  _ChannelEngine_users.set(this, void 0);
38
48
  _ChannelEngine_parentEngine.set(this, void 0);
39
49
  this.name = name;
40
- __classPrivateFieldSet(this, _ChannelEngine_receiver, new pondsocket_common_1.Subject(), "f");
41
- __classPrivateFieldSet(this, _ChannelEngine_users, new Map(), "f");
42
50
  __classPrivateFieldSet(this, _ChannelEngine_parentEngine, parent, "f");
51
+ __classPrivateFieldSet(this, _ChannelEngine_users, new Map(), "f");
52
+ __classPrivateFieldSet(this, _ChannelEngine_receiver, new pondsocket_common_1.Subject(), "f");
53
+ __classPrivateFieldSet(this, _ChannelEngine_pubSubCLient, parent.parent.getPubSubClient(), "f");
54
+ __classPrivateFieldGet(this, _ChannelEngine_instances, "m", _ChannelEngine_initPubSub).call(this);
43
55
  }
44
56
  /**
45
57
  * @desc Gets the presence engine for the channel
@@ -160,15 +172,16 @@ class ChannelEngine {
160
172
  if (!__classPrivateFieldGet(this, _ChannelEngine_users, "f").has(sender) && sender !== pondsocket_common_1.SystemSender.CHANNEL) {
161
173
  throw new pondError_1.ChannelError(`ChannelEngine: User with id ${sender} does not exist in channel ${this.name}`, 404, this.name);
162
174
  }
163
- const eventMessage = {
164
- recipients: __classPrivateFieldGet(this, _ChannelEngine_instances, "m", _ChannelEngine_getUsersFromRecipients).call(this, recipient, sender),
175
+ const channelEvent = {
165
176
  channelName: this.name,
166
177
  requestId,
167
178
  action,
168
- payload,
169
179
  event,
180
+ payload,
170
181
  };
171
- __classPrivateFieldGet(this, _ChannelEngine_receiver, "f").publish(eventMessage);
182
+ __classPrivateFieldGet(this, _ChannelEngine_pubSubCLient, "f").publish(recipient, channelEvent);
183
+ const recipients = __classPrivateFieldGet(this, _ChannelEngine_instances, "m", _ChannelEngine_getUsersFromRecipients).call(this, recipient, sender);
184
+ __classPrivateFieldGet(this, _ChannelEngine_receiver, "f").publish(Object.assign(Object.assign({}, channelEvent), { recipients }));
172
185
  }
173
186
  /**
174
187
  * @desc Handles a message from a user
@@ -212,9 +225,18 @@ class ChannelEngine {
212
225
  unsubscribeFrom(userId, channel) {
213
226
  __classPrivateFieldGet(this, _ChannelEngine_parentEngine, "f").parent.unsubscribeFrom(userId, channel);
214
227
  }
228
+ /**
229
+ * @desc Gets the presence from the pubSub client
230
+ */
231
+ getPubSubPresence() {
232
+ return __awaiter(this, void 0, void 0, function* () {
233
+ const presence = yield __classPrivateFieldGet(this, _ChannelEngine_pubSubCLient, "f").getPresence(this.name);
234
+ return presence.reduce((acc, value) => Object.assign(acc, value), {});
235
+ });
236
+ }
215
237
  }
216
238
  exports.ChannelEngine = ChannelEngine;
217
- _ChannelEngine_receiver = new WeakMap(), _ChannelEngine_presenceEngine = new WeakMap(), _ChannelEngine_users = new WeakMap(), _ChannelEngine_parentEngine = new WeakMap(), _ChannelEngine_instances = new WeakSet(), _ChannelEngine_subscribe = function _ChannelEngine_subscribe(userId, onMessage) {
239
+ _ChannelEngine_receiver = new WeakMap(), _ChannelEngine_pubSubCLient = new WeakMap(), _ChannelEngine_presenceEngine = new WeakMap(), _ChannelEngine_users = new WeakMap(), _ChannelEngine_parentEngine = new WeakMap(), _ChannelEngine_instances = new WeakSet(), _ChannelEngine_subscribe = function _ChannelEngine_subscribe(userId, onMessage) {
218
240
  const unsubscribe = __classPrivateFieldGet(this, _ChannelEngine_receiver, "f").subscribe((_a) => {
219
241
  var { recipients } = _a, event = __rest(_a, ["recipients"]);
220
242
  if (recipients.includes(userId)) {
@@ -254,7 +276,7 @@ _ChannelEngine_receiver = new WeakMap(), _ChannelEngine_presenceEngine = new Wea
254
276
  }
255
277
  unsubscribe();
256
278
  __classPrivateFieldGet(this, _ChannelEngine_users, "f").delete(userId);
257
- const userPresence = (_a = __classPrivateFieldGet(this, _ChannelEngine_presenceEngine, "f")) === null || _a === void 0 ? void 0 : _a.removePresence(userId);
279
+ const userPresence = (_a = __classPrivateFieldGet(this, _ChannelEngine_presenceEngine, "f")) === null || _a === void 0 ? void 0 : _a.removePresence(userId, true);
258
280
  if (__classPrivateFieldGet(this, _ChannelEngine_parentEngine, "f").leaveCallback) {
259
281
  __classPrivateFieldGet(this, _ChannelEngine_parentEngine, "f").leaveCallback({
260
282
  // eslint-disable-next-line @typescript-eslint/no-use-before-define
@@ -277,6 +299,16 @@ _ChannelEngine_receiver = new WeakMap(), _ChannelEngine_presenceEngine = new Wea
277
299
  }
278
300
  unsubscribe();
279
301
  cachedUser.subscriptions.delete(this.name);
302
+ }, _ChannelEngine_initPubSub = function _ChannelEngine_initPubSub() {
303
+ __classPrivateFieldGet(this, _ChannelEngine_pubSubCLient, "f").subscribeToPresence(this.name, () => {
304
+ if (__classPrivateFieldGet(this, _ChannelEngine_presenceEngine, "f")) {
305
+ return __classPrivateFieldGet(this, _ChannelEngine_presenceEngine, "f").getPresence();
306
+ }
307
+ return {};
308
+ });
309
+ __classPrivateFieldGet(this, _ChannelEngine_pubSubCLient, "f").subscribe(this.name, (recipients, data) => {
310
+ this.sendMessage(pondsocket_common_1.SystemSender.CHANNEL, recipients, data.action, data.event, data.payload, data.requestId);
311
+ });
280
312
  };
281
313
  class Channel {
282
314
  constructor(engine) {
@@ -290,7 +322,11 @@ class Channel {
290
322
  return __classPrivateFieldGet(this, _Channel_engine, "f").getAssigns();
291
323
  }
292
324
  getPresences() {
293
- return __classPrivateFieldGet(this, _Channel_engine, "f").presenceEngine.getPresence();
325
+ return __awaiter(this, void 0, void 0, function* () {
326
+ const external = yield __classPrivateFieldGet(this, _Channel_engine, "f").getPubSubPresence();
327
+ const internal = __classPrivateFieldGet(this, _Channel_engine, "f").presenceEngine.getPresence();
328
+ return Object.assign(Object.assign({}, internal), external);
329
+ });
294
330
  }
295
331
  getUserData(userId) {
296
332
  return __classPrivateFieldGet(this, _Channel_engine, "f").getUserData(userId);
@@ -77,7 +77,7 @@ describe('ChannelEngine', () => {
77
77
  });
78
78
  it('should update a users assigns', () => {
79
79
  const onMessage = jest.fn();
80
- const { parentEngine, socket } = (0, exports.createParentEngine)();
80
+ const { parentEngine } = (0, exports.createParentEngine)();
81
81
  const channelEngine = new channel_1.ChannelEngine('test', parentEngine);
82
82
  channelEngine.addUser('test', { test: 1 }, onMessage);
83
83
  expect(channelEngine.getUserData('test')).toEqual({
@@ -293,9 +293,6 @@ describe('ChannelEngine', () => {
293
293
  it('should broadcast a message to all users', () => {
294
294
  const onMessage = jest.fn();
295
295
  const { parentEngine } = (0, exports.createParentEngine)();
296
- parentEngine.middleware.run = (_, res) => {
297
- // res.accept();
298
- };
299
296
  const channelEngine = new channel_1.ChannelEngine('test', parentEngine);
300
297
  channelEngine.addUser('test', { test: 1 }, onMessage);
301
298
  channelEngine.addUser('test2', { test: 1 }, onMessage);
@@ -322,9 +319,6 @@ describe('ChannelEngine', () => {
322
319
  it('should broadcast a message to all users except sender', () => {
323
320
  const onMessage = jest.fn();
324
321
  const { parentEngine } = (0, exports.createParentEngine)();
325
- parentEngine.middleware.run = (_, res) => {
326
- // res.accept();
327
- };
328
322
  const channelEngine = new channel_1.ChannelEngine('test', parentEngine);
329
323
  channelEngine.addUser('test', { test: 1 }, onMessage);
330
324
  channelEngine.addUser('test2', { test: 1 }, onMessage);
@@ -351,9 +345,6 @@ describe('ChannelEngine', () => {
351
345
  it('should broadcast a message to specific users', () => {
352
346
  const onMessage = jest.fn();
353
347
  const { parentEngine } = (0, exports.createParentEngine)();
354
- parentEngine.middleware.run = (_, res) => {
355
- // res.accept();
356
- };
357
348
  const channelEngine = new channel_1.ChannelEngine('test', parentEngine);
358
349
  channelEngine.addUser('test', { test: 1 }, onMessage);
359
350
  channelEngine.addUser('test2', { test: 1 }, onMessage);
@@ -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 _EndpointEngine_instances, _EndpointEngine_middleware, _EndpointEngine_channels, _EndpointEngine_sockets, _EndpointEngine_parentEngine, _EndpointEngine_joinChannel, _EndpointEngine_execute, _EndpointEngine_retrieveChannel, _EndpointEngine_handleMessage, _EndpointEngine_readMessage, _EndpointEngine_buildError, _EndpointEngine_leaveChannel, _Endpoint_engine;
13
+ var _EndpointEngine_instances, _EndpointEngine_middleware, _EndpointEngine_lobbyEngines, _EndpointEngine_channels, _EndpointEngine_sockets, _EndpointEngine_parentEngine, _EndpointEngine_client, _EndpointEngine_joinChannel, _EndpointEngine_broadcastMessage, _EndpointEngine_retrieveChannel, _EndpointEngine_handleMessage, _EndpointEngine_readMessage, _EndpointEngine_buildError, _EndpointEngine_leaveChannel, _Endpoint_engine;
14
14
  Object.defineProperty(exports, "__esModule", { value: true });
15
15
  exports.Endpoint = exports.EndpointEngine = void 0;
16
16
  const pondsocket_common_1 = require("@eleven-am/pondsocket-common");
@@ -22,16 +22,20 @@ const joinResponse_1 = require("../lobby/joinResponse");
22
22
  const lobby_1 = require("../lobby/lobby");
23
23
  const matcher_1 = require("../matcher/matcher");
24
24
  class EndpointEngine {
25
- constructor(parent) {
25
+ constructor(parent, client) {
26
26
  _EndpointEngine_instances.add(this);
27
27
  _EndpointEngine_middleware.set(this, void 0);
28
+ _EndpointEngine_lobbyEngines.set(this, void 0);
28
29
  _EndpointEngine_channels.set(this, void 0);
29
30
  _EndpointEngine_sockets.set(this, void 0);
30
31
  _EndpointEngine_parentEngine.set(this, void 0);
32
+ _EndpointEngine_client.set(this, void 0);
31
33
  __classPrivateFieldSet(this, _EndpointEngine_sockets, new Map(), "f");
32
34
  __classPrivateFieldSet(this, _EndpointEngine_middleware, new middleware_1.Middleware(), "f");
33
- __classPrivateFieldSet(this, _EndpointEngine_channels, new Map(), "f");
35
+ __classPrivateFieldSet(this, _EndpointEngine_lobbyEngines, new Map(), "f");
34
36
  __classPrivateFieldSet(this, _EndpointEngine_parentEngine, parent, "f");
37
+ __classPrivateFieldSet(this, _EndpointEngine_channels, new Map(), "f");
38
+ __classPrivateFieldSet(this, _EndpointEngine_client, client, "f");
35
39
  }
36
40
  get parent() {
37
41
  return __classPrivateFieldGet(this, _EndpointEngine_parentEngine, "f");
@@ -47,7 +51,7 @@ class EndpointEngine {
47
51
  * response.accept();
48
52
  *
49
53
  * else
50
- * response.reject('You are not an admin', 403);
54
+ * response.decline('You are not an admin', 403);
51
55
  * });
52
56
  */
53
57
  createChannel(path, handler) {
@@ -55,16 +59,16 @@ class EndpointEngine {
55
59
  __classPrivateFieldGet(this, _EndpointEngine_middleware, "f").use((user, joinParams, next) => {
56
60
  const event = (0, matcher_1.parseAddress)(path, user.channelName);
57
61
  if (event) {
58
- const newChannel = pondChannel.getChannel(user.channelName) || pondChannel.createChannel(user.channelName);
59
- const request = new joinRequest_1.JoinRequest(user, joinParams, newChannel);
60
- const response = new joinResponse_1.JoinResponse(user, newChannel);
61
- if (request._parseQueries(path)) {
62
- return handler(request, response);
63
- }
62
+ const channel = pondChannel.getChannel(user.channelName) || pondChannel.createChannel(user.channelName);
63
+ const request = new joinRequest_1.JoinRequest(user, joinParams, channel);
64
+ const response = new joinResponse_1.JoinResponse(user, channel);
65
+ request._parseQueries(path);
66
+ __classPrivateFieldGet(this, _EndpointEngine_channels, "f").set(user.channelName, channel);
67
+ return handler(request, response);
64
68
  }
65
69
  next();
66
70
  });
67
- __classPrivateFieldGet(this, _EndpointEngine_channels, "f").set(path, pondChannel);
71
+ __classPrivateFieldGet(this, _EndpointEngine_lobbyEngines, "f").set(path, pondChannel);
68
72
  return new lobby_1.PondChannel(pondChannel);
69
73
  }
70
74
  /**
@@ -73,23 +77,6 @@ class EndpointEngine {
73
77
  getClients() {
74
78
  return [...__classPrivateFieldGet(this, _EndpointEngine_sockets, "f").values()];
75
79
  }
76
- /**
77
- * @desc Broadcasts a message to all clients connected to this endpoint
78
- * @param event - The event to broadcast
79
- * @param payload - The payload to broadcast
80
- */
81
- broadcast(event, payload) {
82
- __classPrivateFieldGet(this, _EndpointEngine_sockets, "f").forEach(({ socket }) => {
83
- const message = {
84
- event,
85
- payload,
86
- requestId: (0, pondsocket_common_1.uuid)(),
87
- action: pondsocket_common_1.ServerActions.BROADCAST,
88
- channelName: pondsocket_common_1.SystemSender.ENDPOINT,
89
- };
90
- this.sendMessage(socket, message);
91
- });
92
- }
93
80
  /**
94
81
  * @desc Closes specific clients connected to this endpoint
95
82
  * @param clientIds - The id for the client / clients to close
@@ -121,6 +108,14 @@ class EndpointEngine {
121
108
  __classPrivateFieldGet(this, _EndpointEngine_sockets, "f").delete(cache.clientId);
122
109
  cache.subscriptions.forEach((unsubscribe) => unsubscribe());
123
110
  });
111
+ const event = {
112
+ event: pondsocket_common_1.Events.CONNECTION,
113
+ action: pondsocket_common_1.ServerActions.CONNECT,
114
+ channelName: pondsocket_common_1.SystemSender.ENDPOINT,
115
+ requestId: (0, pondsocket_common_1.uuid)(),
116
+ payload: {},
117
+ };
118
+ this.sendMessage(socket, event);
124
119
  }
125
120
  /**
126
121
  * @desc Retrieves a user from the endpoint
@@ -169,23 +164,28 @@ class EndpointEngine {
169
164
  sendMessage(socket, message) {
170
165
  socket.send(JSON.stringify(message));
171
166
  }
167
+ /**
168
+ * @desc Gets the PubSubClient for this endpoint
169
+ */
170
+ getPubSubClient() {
171
+ return __classPrivateFieldGet(this, _EndpointEngine_client, "f");
172
+ }
172
173
  }
173
174
  exports.EndpointEngine = EndpointEngine;
174
- _EndpointEngine_middleware = new WeakMap(), _EndpointEngine_channels = new WeakMap(), _EndpointEngine_sockets = new WeakMap(), _EndpointEngine_parentEngine = new WeakMap(), _EndpointEngine_instances = new WeakSet(), _EndpointEngine_joinChannel = function _EndpointEngine_joinChannel(channel, socket, joinParams, requestId) {
175
+ _EndpointEngine_middleware = new WeakMap(), _EndpointEngine_lobbyEngines = new WeakMap(), _EndpointEngine_channels = new WeakMap(), _EndpointEngine_sockets = new WeakMap(), _EndpointEngine_parentEngine = new WeakMap(), _EndpointEngine_client = new WeakMap(), _EndpointEngine_instances = new WeakSet(), _EndpointEngine_joinChannel = function _EndpointEngine_joinChannel(channel, socket, joinParams, requestId) {
175
176
  const cache = Object.assign(Object.assign({}, socket), { requestId, channelName: channel });
176
177
  __classPrivateFieldGet(this, _EndpointEngine_middleware, "f").run(cache, joinParams, () => {
177
178
  throw new pondError_1.EndpointError(`GatewayEngine: Channel ${channel} does not exist`, 404);
178
179
  });
179
- }, _EndpointEngine_execute = function _EndpointEngine_execute(channel, handler) {
180
- for (const [path, manager] of __classPrivateFieldGet(this, _EndpointEngine_channels, "f")) {
181
- const event = (0, matcher_1.parseAddress)(path, channel);
182
- if (event) {
183
- return manager.execute(channel, handler);
184
- }
180
+ }, _EndpointEngine_broadcastMessage = function _EndpointEngine_broadcastMessage(cache, message) {
181
+ const engine = __classPrivateFieldGet(this, _EndpointEngine_channels, "f").get(message.channelName);
182
+ if (!engine) {
183
+ throw new pondError_1.EndpointError(`GatewayEngine: Channel ${message.channelName} does not exist`, 404);
185
184
  }
185
+ engine.broadcastMessage(cache.clientId, message);
186
186
  }, _EndpointEngine_retrieveChannel = function _EndpointEngine_retrieveChannel(channel) {
187
187
  let channelEngine;
188
- for (const [path, manager] of __classPrivateFieldGet(this, _EndpointEngine_channels, "f")) {
188
+ for (const [path, manager] of __classPrivateFieldGet(this, _EndpointEngine_lobbyEngines, "f")) {
189
189
  const event = (0, matcher_1.parseAddress)(path, channel);
190
190
  if (event) {
191
191
  channelEngine = manager.getChannel(channel) || manager.createChannel(channel);
@@ -205,9 +205,7 @@ _EndpointEngine_middleware = new WeakMap(), _EndpointEngine_channels = new WeakM
205
205
  __classPrivateFieldGet(this, _EndpointEngine_instances, "m", _EndpointEngine_leaveChannel).call(this, message.channelName, cache);
206
206
  break;
207
207
  case pondsocket_common_1.ClientActions.BROADCAST:
208
- __classPrivateFieldGet(this, _EndpointEngine_instances, "m", _EndpointEngine_execute).call(this, message.channelName, (channel) => {
209
- channel.broadcastMessage(cache.clientId, message);
210
- });
208
+ __classPrivateFieldGet(this, _EndpointEngine_instances, "m", _EndpointEngine_broadcastMessage).call(this, cache, message);
211
209
  break;
212
210
  default:
213
211
  throw new Error(`GatewayEngine: Action ${message.action} does not exist`);
@@ -298,9 +296,6 @@ class Endpoint {
298
296
  createChannel(path, handler) {
299
297
  return __classPrivateFieldGet(this, _Endpoint_engine, "f").createChannel(path, handler);
300
298
  }
301
- broadcast(event, payload) {
302
- __classPrivateFieldGet(this, _Endpoint_engine, "f").broadcast(event, payload);
303
- }
304
299
  closeConnection(clientIds) {
305
300
  __classPrivateFieldGet(this, _Endpoint_engine, "f").closeConnection(clientIds);
306
301
  }
@@ -28,6 +28,12 @@ const createEndpointEngine = (socket) => ({
28
28
  subscribeTo: jest.fn(),
29
29
  unsubscribeFrom: jest.fn(),
30
30
  sendMessage: (socket, msg) => socket.send(JSON.stringify(msg)),
31
+ getPubSubClient: () => ({
32
+ publish: jest.fn(),
33
+ subscribeToPresence: jest.fn(),
34
+ subscribe: jest.fn(),
35
+ getPresence: () => new Promise((resolve) => setTimeout(() => resolve([]), 100)),
36
+ }),
31
37
  });
32
38
  exports.createEndpointEngine = createEndpointEngine;
33
39
  describe('endpoint', () => {
@@ -102,30 +108,6 @@ describe('endpoint', () => {
102
108
  .expectClosed();
103
109
  expect(count).toBe(1);
104
110
  }));
105
- it('should be able to send a message to all connection', () => __awaiter(void 0, void 0, void 0, function* () {
106
- const endpoint = socket.createEndpoint('/api/:room', (req, res) => {
107
- if (req.params.room === 'socket') {
108
- res.accept();
109
- const connections = endpoint.getClients();
110
- expect(connections).toHaveLength(1);
111
- endpoint.broadcast('TEST', { test: 'test' });
112
- }
113
- else {
114
- res.decline();
115
- }
116
- });
117
- yield (0, superwstest_1.default)(server)
118
- .ws('/api/socket')
119
- .expectUpgrade((res) => expect(res.statusCode).toBe(101))
120
- .expectMessage(expect.objectContaining({
121
- event: 'TEST',
122
- action: pondsocket_common_1.ServerActions.BROADCAST,
123
- channelName: pondsocket_common_1.SystemSender.ENDPOINT,
124
- payload: {
125
- test: 'test',
126
- },
127
- }));
128
- }));
129
111
  it('should be able to accept connections on this handler', () => __awaiter(void 0, void 0, void 0, function* () {
130
112
  const message = {
131
113
  action: pondsocket_common_1.ClientActions.JOIN_CHANNEL,
@@ -228,12 +210,13 @@ describe('endpoint', () => {
228
210
  }))
229
211
  .close();
230
212
  }));
231
- it('should throw an error if accept, reject / send is called more than once', () => __awaiter(void 0, void 0, void 0, function* () {
213
+ it('should throw an error if accept, reject is called more than once', () => __awaiter(void 0, void 0, void 0, function* () {
232
214
  socket.createEndpoint('/api/:room', (_, res) => {
233
215
  res.reply('hello', {
234
216
  test: 'test',
235
217
  });
236
- expect(() => res.accept()).toThrowError('Cannot execute response more than once');
218
+ res.accept();
219
+ expect(() => res.decline()).toThrowError('Cannot execute response more than once');
237
220
  });
238
221
  yield (0, superwstest_1.default)(server)
239
222
  .ws('/api/socket')
@@ -265,7 +248,9 @@ describe('endpoint', () => {
265
248
  res.reply('echo', req.event.payload);
266
249
  });
267
250
  channel.onEvent('broadcast', (req) => {
268
- channel.broadcast('broadcast', Object.assign(Object.assign({}, req.event.payload), { broadcast: true }));
251
+ const internal = channel.getChannel('/test/socket');
252
+ expect(internal).toBeDefined();
253
+ internal.broadcast('broadcast', Object.assign(Object.assign({}, req.event.payload), { broadcast: true }));
269
254
  });
270
255
  yield (0, superwstest_1.default)(server)
271
256
  .ws('/api/socket')
@@ -14,6 +14,7 @@ var _ConnectionResponse_instances, _ConnectionResponse_webSocket, _ConnectionRes
14
14
  Object.defineProperty(exports, "__esModule", { value: true });
15
15
  exports.ConnectionResponse = void 0;
16
16
  const pondsocket_common_1 = require("@eleven-am/pondsocket-common");
17
+ const ws_1 = require("ws");
17
18
  const pondError_1 = require("../errors/pondError");
18
19
  class ConnectionResponse {
19
20
  constructor(webSocket, engine, clientId) {
@@ -85,7 +86,9 @@ class ConnectionResponse {
85
86
  * @param payload - the payload to send
86
87
  */
87
88
  reply(event, payload) {
88
- __classPrivateFieldGet(this, _ConnectionResponse_instances, "m", _ConnectionResponse_performChecks).call(this);
89
+ if (__classPrivateFieldGet(this, _ConnectionResponse_webSocket, "f").readyState !== ws_1.WebSocket.OPEN) {
90
+ throw new pondError_1.EndpointError('Socket is not open', 400);
91
+ }
89
92
  __classPrivateFieldGet(this, _ConnectionResponse_instances, "m", _ConnectionResponse_sendMessage).call(this, pondsocket_common_1.ServerActions.BROADCAST, event, payload);
90
93
  return this;
91
94
  }
package/lobby/lobby.js CHANGED
@@ -13,7 +13,6 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
13
13
  var _LobbyEngine_channels, _LobbyEngine_middleware, _LobbyEngine_leaveCallback, _LobbyEngine_parentEngine, _PondChannel_lobby;
14
14
  Object.defineProperty(exports, "__esModule", { value: true });
15
15
  exports.PondChannel = exports.LobbyEngine = void 0;
16
- const pondsocket_common_1 = require("@eleven-am/pondsocket-common");
17
16
  const middleware_1 = require("../abstracts/middleware");
18
17
  const channel_1 = require("../channel/channel");
19
18
  class LobbyEngine {
@@ -70,45 +69,6 @@ class LobbyEngine {
70
69
  onLeave(callback) {
71
70
  __classPrivateFieldSet(this, _LobbyEngine_leaveCallback, callback, "f");
72
71
  }
73
- /**
74
- * @desc Broadcasts a message to all users in a channel
75
- * @param event - The event to broadcast
76
- * @param payload - The payload to send
77
- * @param channelName - The channel to broadcast to (if not specified, broadcast to all channels)
78
- * @example
79
- * pond.broadcast('echo', {
80
- * message: 'Hello World',
81
- * timestamp: Date.now(),
82
- * channel: 'my_channel',
83
- *});
84
- */
85
- broadcast(event, payload, channelName) {
86
- if (channelName) {
87
- const channel = this.getChannel(channelName);
88
- if (!channel) {
89
- throw new Error(`GatewayEngine: Channel ${channelName} does not exist`);
90
- }
91
- channel.sendMessage(pondsocket_common_1.SystemSender.CHANNEL, pondsocket_common_1.ChannelReceiver.ALL_USERS, pondsocket_common_1.ServerActions.SYSTEM, event, payload);
92
- }
93
- else {
94
- __classPrivateFieldGet(this, _LobbyEngine_channels, "f").forEach((channel) => {
95
- channel.sendMessage(pondsocket_common_1.SystemSender.CHANNEL, pondsocket_common_1.ChannelReceiver.ALL_USERS, pondsocket_common_1.ServerActions.SYSTEM, event, payload);
96
- });
97
- }
98
- }
99
- /**
100
- * @desc Executes a function on a channel
101
- * @param channelName - The name of the channel to execute the function on
102
- * @param handler - The function to execute
103
- * @private
104
- */
105
- execute(channelName, handler) {
106
- const newChannel = this.getChannel(channelName);
107
- if (newChannel) {
108
- return handler(newChannel);
109
- }
110
- throw new Error(`GatewayEngine: Channel ${channelName} does not exist`);
111
- }
112
72
  /**
113
73
  * @desc Gets a channel by name
114
74
  * @param channelName - The name of the channel to get
@@ -150,9 +110,6 @@ class PondChannel {
150
110
  onEvent(event, handler) {
151
111
  __classPrivateFieldGet(this, _PondChannel_lobby, "f").onEvent(event, handler);
152
112
  }
153
- broadcast(event, payload, channelName) {
154
- __classPrivateFieldGet(this, _PondChannel_lobby, "f").broadcast(event, payload, channelName);
155
- }
156
113
  onLeave(callback) {
157
114
  __classPrivateFieldGet(this, _PondChannel_lobby, "f").onLeave(callback);
158
115
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@eleven-am/pondsocket",
3
- "version": "0.1.158",
3
+ "version": "0.1.161",
4
4
  "description": "PondSocket is a fast simple socket server",
5
5
  "keywords": [
6
6
  "socket",
@@ -34,12 +34,13 @@
34
34
  "url": "git+https://github.com/Eleven-am/pondSocket.git"
35
35
  },
36
36
  "dependencies": {
37
- "@eleven-am/pondsocket-common": "^0.0.18",
38
- "ws": "^8.17.1"
37
+ "@eleven-am/pondsocket-common": "^0.0.23",
38
+ "ioredis": "^5.4.1",
39
+ "ws": "^8.18.0"
39
40
  },
40
41
  "devDependencies": {
41
42
  "@types/jest": "^29.5.12",
42
- "@types/node": "^20.14.9",
43
+ "@types/node": "^20.14.10",
43
44
  "@types/websocket": "^1.0.10",
44
45
  "@types/ws": "^8.5.10",
45
46
  "@typescript-eslint/eslint-plugin": "^7.1.0",
@@ -47,10 +48,10 @@
47
48
  "eslint-plugin-file-progress": "^1.3.0",
48
49
  "eslint-plugin-import": "^2.29.1",
49
50
  "jest": "^29.7.0",
50
- "superwstest": "^2.0.3",
51
+ "superwstest": "^2.0.4",
51
52
  "ts-jest": "^29.1.5",
52
53
  "ts-node": "^10.9.2",
53
- "typescript": "^5.5.2"
54
+ "typescript": "^5.5.3"
54
55
  },
55
56
  "jest": {
56
57
  "moduleFileExtensions": [
@@ -62,8 +62,9 @@ class PresenceEngine {
62
62
  /**
63
63
  * @desc Removes a presence from the presence engine
64
64
  * @param presenceKey - The key of the presence
65
+ * @param safe - If true, it will not throw an error if the presence does not exist
65
66
  */
66
- removePresence(presenceKey) {
67
+ removePresence(presenceKey, safe = false) {
67
68
  const presence = __classPrivateFieldGet(this, _PresenceEngine_presenceMap, "f").get(presenceKey);
68
69
  if (presence) {
69
70
  __classPrivateFieldGet(this, _PresenceEngine_presenceMap, "f").delete(presenceKey);
@@ -72,7 +73,7 @@ class PresenceEngine {
72
73
  presence: Array.from(__classPrivateFieldGet(this, _PresenceEngine_presenceMap, "f").values()),
73
74
  });
74
75
  }
75
- else {
76
+ else if (!safe) {
76
77
  const code = 404;
77
78
  const message = `PresenceEngine: Presence with key ${presenceKey} does not exist`;
78
79
  throw new pondError_1.PresenceError(message, code, __classPrivateFieldGet(this, _PresenceEngine_channel, "f").name, pondsocket_common_1.PresenceEventTypes.LEAVE);
@@ -114,6 +114,9 @@ describe('PresenceEngine', () => {
114
114
  it('should throw an error if the presence does not exist', () => {
115
115
  expect(() => presenceEngine.removePresence(presenceKey)).toThrowError(`PresenceEngine: Presence with key ${presenceKey} does not exist`);
116
116
  });
117
+ it('should not throw an error if the safe flag is true', () => {
118
+ expect(() => presenceEngine.removePresence(presenceKey, true)).not.toThrow();
119
+ });
117
120
  });
118
121
  describe('getPresence', () => {
119
122
  it('should return the presence', () => {
@@ -0,0 +1,150 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
12
+ if (kind === "m") throw new TypeError("Private method is not writable");
13
+ if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
14
+ if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
15
+ return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
16
+ };
17
+ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
18
+ if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
19
+ 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");
20
+ return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
21
+ };
22
+ var __importDefault = (this && this.__importDefault) || function (mod) {
23
+ return (mod && mod.__esModule) ? mod : { "default": mod };
24
+ };
25
+ var _PubSubEngine_instances, _PubSubEngine_subscriber, _PubSubEngine_redis, _PubSubEngine_pubSub, _PubSubEngine_id, _PubSubEngine_expirationTime, _PubSubEngine_heartbeatInterval, _PubSubEngine_interval, _PubSubEngine_getPresence, _PubSubEngine_registerInstance, _PubSubEngine_getActiveInstances, _PubSubEngine_subscribeToChannel, _PubSubEngine_getPresenceFromInstance, _PubSubEngine_subscribeToPresence, _PubSubEngine_subscribe, _PubSubEngine_publish;
26
+ Object.defineProperty(exports, "__esModule", { value: true });
27
+ exports.PubSubEngine = void 0;
28
+ const pondsocket_common_1 = require("@eleven-am/pondsocket-common");
29
+ const ioredis_1 = __importDefault(require("ioredis"));
30
+ class PubSubEngine {
31
+ constructor(options = null) {
32
+ _PubSubEngine_instances.add(this);
33
+ _PubSubEngine_subscriber.set(this, void 0);
34
+ _PubSubEngine_redis.set(this, void 0);
35
+ _PubSubEngine_pubSub.set(this, void 0);
36
+ _PubSubEngine_id.set(this, (0, pondsocket_common_1.uuid)());
37
+ _PubSubEngine_expirationTime.set(this, 60);
38
+ _PubSubEngine_heartbeatInterval.set(this, 5000);
39
+ _PubSubEngine_interval.set(this, void 0);
40
+ __classPrivateFieldSet(this, _PubSubEngine_subscriber, new pondsocket_common_1.Subject(), "f");
41
+ __classPrivateFieldSet(this, _PubSubEngine_redis, options ? new ioredis_1.default(options.redisUrl, { db: options.db }) : null, "f");
42
+ __classPrivateFieldSet(this, _PubSubEngine_pubSub, options ? new ioredis_1.default(options.redisUrl, { db: options.db }) : null, "f");
43
+ __classPrivateFieldGet(this, _PubSubEngine_instances, "m", _PubSubEngine_subscribeToChannel).call(this);
44
+ __classPrivateFieldSet(this, _PubSubEngine_interval, setInterval(() => __classPrivateFieldGet(this, _PubSubEngine_instances, "m", _PubSubEngine_registerInstance).call(this), __classPrivateFieldGet(this, _PubSubEngine_heartbeatInterval, "f")), "f");
45
+ }
46
+ /**
47
+ * @desc Builds a client for the given endpoint
48
+ * @param endpoint - the endpoint to build the client for
49
+ */
50
+ buildClient(endpoint) {
51
+ const subscribeToPresence = __classPrivateFieldGet(this, _PubSubEngine_instances, "m", _PubSubEngine_subscribeToPresence).bind(this, endpoint);
52
+ const getPresence = __classPrivateFieldGet(this, _PubSubEngine_instances, "m", _PubSubEngine_getPresence).bind(this, endpoint);
53
+ const subscribe = __classPrivateFieldGet(this, _PubSubEngine_instances, "m", _PubSubEngine_subscribe).bind(this, endpoint);
54
+ const publish = __classPrivateFieldGet(this, _PubSubEngine_instances, "m", _PubSubEngine_publish).bind(this, endpoint);
55
+ const client = {
56
+ getPresence,
57
+ publish,
58
+ subscribeToPresence,
59
+ subscribe,
60
+ };
61
+ return client;
62
+ }
63
+ /**
64
+ * @desc Closes the connection
65
+ */
66
+ close() {
67
+ var _a, _b;
68
+ clearInterval(__classPrivateFieldGet(this, _PubSubEngine_interval, "f"));
69
+ (_a = __classPrivateFieldGet(this, _PubSubEngine_redis, "f")) === null || _a === void 0 ? void 0 : _a.quit();
70
+ (_b = __classPrivateFieldGet(this, _PubSubEngine_pubSub, "f")) === null || _b === void 0 ? void 0 : _b.quit();
71
+ }
72
+ }
73
+ exports.PubSubEngine = PubSubEngine;
74
+ _PubSubEngine_subscriber = new WeakMap(), _PubSubEngine_redis = new WeakMap(), _PubSubEngine_pubSub = new WeakMap(), _PubSubEngine_id = new WeakMap(), _PubSubEngine_expirationTime = new WeakMap(), _PubSubEngine_heartbeatInterval = new WeakMap(), _PubSubEngine_interval = new WeakMap(), _PubSubEngine_instances = new WeakSet(), _PubSubEngine_getPresence = function _PubSubEngine_getPresence(endpoint, channel) {
75
+ return __awaiter(this, void 0, void 0, function* () {
76
+ const instances = yield __classPrivateFieldGet(this, _PubSubEngine_instances, "m", _PubSubEngine_getActiveInstances).call(this);
77
+ return Promise.all(instances.map((instance) => __classPrivateFieldGet(this, _PubSubEngine_instances, "m", _PubSubEngine_getPresenceFromInstance).call(this, endpoint, channel, instance)));
78
+ });
79
+ }, _PubSubEngine_registerInstance = function _PubSubEngine_registerInstance() {
80
+ if (!__classPrivateFieldGet(this, _PubSubEngine_redis, "f")) {
81
+ return;
82
+ }
83
+ __classPrivateFieldGet(this, _PubSubEngine_redis, "f").setex(`app:instance:${__classPrivateFieldGet(this, _PubSubEngine_id, "f")}`, __classPrivateFieldGet(this, _PubSubEngine_expirationTime, "f"), 'active');
84
+ }, _PubSubEngine_getActiveInstances = function _PubSubEngine_getActiveInstances() {
85
+ return __awaiter(this, void 0, void 0, function* () {
86
+ if (!__classPrivateFieldGet(this, _PubSubEngine_redis, "f")) {
87
+ return [];
88
+ }
89
+ const keys = yield __classPrivateFieldGet(this, _PubSubEngine_redis, "f").keys('app:instance:*');
90
+ return keys.map((key) => key.replace('app:instance:', ''))
91
+ .filter((key) => key !== __classPrivateFieldGet(this, _PubSubEngine_id, "f"));
92
+ });
93
+ }, _PubSubEngine_subscribeToChannel = function _PubSubEngine_subscribeToChannel() {
94
+ if (!__classPrivateFieldGet(this, _PubSubEngine_pubSub, "f")) {
95
+ return;
96
+ }
97
+ __classPrivateFieldGet(this, _PubSubEngine_pubSub, "f").subscribe('app:messages', (err) => {
98
+ if (err) {
99
+ console.error('Failed to subscribe: ', err);
100
+ }
101
+ });
102
+ __classPrivateFieldGet(this, _PubSubEngine_pubSub, "f").on('message', (channel, message) => {
103
+ const data = pondsocket_common_1.pubSubEventSchema.parse(JSON.parse(message));
104
+ if (data.pubSubId === __classPrivateFieldGet(this, _PubSubEngine_id, "f")) {
105
+ return;
106
+ }
107
+ __classPrivateFieldGet(this, _PubSubEngine_subscriber, "f").publish(data);
108
+ });
109
+ }, _PubSubEngine_getPresenceFromInstance = function _PubSubEngine_getPresenceFromInstance(endpoint, channel, instance) {
110
+ return new Promise((resolve) => {
111
+ const unsubscribe = __classPrivateFieldGet(this, _PubSubEngine_subscriber, "f").subscribe((data) => {
112
+ if (data.endpoint === endpoint && data.channel === channel && data.event === pondsocket_common_1.PubSubEvents.PRESENCE && data.pubSubId === instance) {
113
+ resolve(data.presence);
114
+ unsubscribe();
115
+ }
116
+ });
117
+ });
118
+ }, _PubSubEngine_subscribeToPresence = function _PubSubEngine_subscribeToPresence(endpoint, channel, handler) {
119
+ return __classPrivateFieldGet(this, _PubSubEngine_subscriber, "f").subscribe((data) => {
120
+ var _a;
121
+ if (data.endpoint === endpoint && data.channel === channel && data.event === pondsocket_common_1.PubSubEvents.GET_PRESENCE) {
122
+ const presence = handler();
123
+ const message = {
124
+ event: pondsocket_common_1.PubSubEvents.PRESENCE,
125
+ pubSubId: __classPrivateFieldGet(this, _PubSubEngine_id, "f"),
126
+ endpoint,
127
+ channel,
128
+ presence,
129
+ };
130
+ (_a = __classPrivateFieldGet(this, _PubSubEngine_pubSub, "f")) === null || _a === void 0 ? void 0 : _a.publish('app:messages', JSON.stringify(message));
131
+ }
132
+ });
133
+ }, _PubSubEngine_subscribe = function _PubSubEngine_subscribe(endpoint, channel, handler) {
134
+ return __classPrivateFieldGet(this, _PubSubEngine_subscriber, "f").subscribe((data) => {
135
+ if (data.endpoint === endpoint && data.channel === channel && data.event === pondsocket_common_1.PubSubEvents.MESSAGE) {
136
+ handler(data.recipient, data.message);
137
+ }
138
+ });
139
+ }, _PubSubEngine_publish = function _PubSubEngine_publish(endpoint, recipients, data) {
140
+ var _a;
141
+ const message = {
142
+ event: pondsocket_common_1.PubSubEvents.MESSAGE,
143
+ pubSubId: __classPrivateFieldGet(this, _PubSubEngine_id, "f"),
144
+ endpoint,
145
+ channel: data.channelName,
146
+ message: data,
147
+ recipient: recipients,
148
+ };
149
+ (_a = __classPrivateFieldGet(this, _PubSubEngine_pubSub, "f")) === null || _a === void 0 ? void 0 : _a.publish('app:messages', JSON.stringify(message));
150
+ };
@@ -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 _PondSocket_instances, _PondSocket_server, _PondSocket_socketServer, _PondSocket_middleware, _PondSocket_manageHeartbeat, _PondSocket_init;
13
+ var _PondSocket_instances, _PondSocket_server, _PondSocket_pubSubEngine, _PondSocket_socketServer, _PondSocket_middleware, _PondSocket_manageHeartbeat, _PondSocket_init;
14
14
  Object.defineProperty(exports, "__esModule", { value: true });
15
15
  exports.PondSocket = void 0;
16
16
  const http_1 = require("http");
@@ -20,15 +20,26 @@ const middleware_1 = require("../abstracts/middleware");
20
20
  const endpoint_1 = require("../endpoint/endpoint");
21
21
  const response_1 = require("../endpoint/response");
22
22
  const matcher_1 = require("../matcher/matcher");
23
+ const pubSubEngine_1 = require("../pubSub/pubSubEngine");
23
24
  class PondSocket {
24
- constructor(server, socketServer) {
25
+ constructor({ server, socketServer, db, redisUrl } = {}) {
25
26
  _PondSocket_instances.add(this);
26
27
  _PondSocket_server.set(this, void 0);
28
+ _PondSocket_pubSubEngine.set(this, void 0);
27
29
  _PondSocket_socketServer.set(this, void 0);
28
30
  _PondSocket_middleware.set(this, void 0);
29
31
  __classPrivateFieldSet(this, _PondSocket_server, server !== null && server !== void 0 ? server : new http_1.Server(), "f");
30
32
  __classPrivateFieldSet(this, _PondSocket_socketServer, socketServer !== null && socketServer !== void 0 ? socketServer : new ws_1.WebSocketServer({ noServer: true }), "f");
31
33
  __classPrivateFieldSet(this, _PondSocket_middleware, new middleware_1.Middleware(), "f");
34
+ if (redisUrl && db) {
35
+ __classPrivateFieldSet(this, _PondSocket_pubSubEngine, new pubSubEngine_1.PubSubEngine({
36
+ redisUrl,
37
+ db,
38
+ }), "f");
39
+ }
40
+ else {
41
+ __classPrivateFieldSet(this, _PondSocket_pubSubEngine, new pubSubEngine_1.PubSubEngine(), "f");
42
+ }
32
43
  __classPrivateFieldGet(this, _PondSocket_instances, "m", _PondSocket_init).call(this);
33
44
  }
34
45
  /**
@@ -62,7 +73,8 @@ class PondSocket {
62
73
  * })
63
74
  */
64
75
  createEndpoint(path, handler) {
65
- const endpoint = new endpoint_1.EndpointEngine(this);
76
+ const client = __classPrivateFieldGet(this, _PondSocket_pubSubEngine, "f").buildClient(path);
77
+ const endpoint = new endpoint_1.EndpointEngine(this, client);
66
78
  __classPrivateFieldGet(this, _PondSocket_middleware, "f").use((req, socket, next) => {
67
79
  const event = (0, matcher_1.parseAddress)(path, req.address);
68
80
  if (event) {
@@ -76,7 +88,7 @@ class PondSocket {
76
88
  }
77
89
  }
78
90
  exports.PondSocket = PondSocket;
79
- _PondSocket_server = new WeakMap(), _PondSocket_socketServer = new WeakMap(), _PondSocket_middleware = new WeakMap(), _PondSocket_instances = new WeakSet(), _PondSocket_manageHeartbeat = function _PondSocket_manageHeartbeat() {
91
+ _PondSocket_server = new WeakMap(), _PondSocket_pubSubEngine = new WeakMap(), _PondSocket_socketServer = new WeakMap(), _PondSocket_middleware = new WeakMap(), _PondSocket_instances = new WeakSet(), _PondSocket_manageHeartbeat = function _PondSocket_manageHeartbeat() {
80
92
  __classPrivateFieldGet(this, _PondSocket_socketServer, "f").on('connection', (socket) => {
81
93
  socket.on('pong', () => {
82
94
  socket.isAlive = true;
@@ -95,10 +107,12 @@ _PondSocket_server = new WeakMap(), _PondSocket_socketServer = new WeakMap(), _P
95
107
  const timeout = __classPrivateFieldGet(this, _PondSocket_instances, "m", _PondSocket_manageHeartbeat).call(this);
96
108
  __classPrivateFieldGet(this, _PondSocket_server, "f").on('error', (error) => {
97
109
  clearInterval(timeout);
110
+ __classPrivateFieldGet(this, _PondSocket_pubSubEngine, "f").close();
98
111
  throw new Error(error.message);
99
112
  });
100
113
  __classPrivateFieldGet(this, _PondSocket_server, "f").on('close', () => {
101
114
  clearInterval(timeout);
115
+ __classPrivateFieldGet(this, _PondSocket_pubSubEngine, "f").close();
102
116
  });
103
117
  __classPrivateFieldGet(this, _PondSocket_server, "f").on('upgrade', (req, socket, head) => {
104
118
  const clientId = req.headers['sec-websocket-key'];
package/types.d.ts CHANGED
@@ -24,8 +24,15 @@ export type LeaveCallback<EventTypes extends PondEventMap = PondEventMap, Presen
24
24
 
25
25
  export type RequestHandler<Request, Response> = (request: Request, response: Response) => void | Promise<void>;
26
26
 
27
+ export interface PondSocketOptions {
28
+ server?: HTTPServer;
29
+ socketServer?: WebSocketServer;
30
+ redisUrl?: string;
31
+ db?: number;
32
+ }
33
+
27
34
  export declare class PondSocket {
28
- constructor(server?: HTTPServer, socketServer?: WebSocketServer);
35
+ constructor(options?: PondSocketOptions);
29
36
 
30
37
  /**
31
38
  * @desc Specifies the port to listen on
@@ -158,7 +165,7 @@ export declare class Channel<EventType extends PondEventMap = PondEventMap, Pres
158
165
  /**
159
166
  * @desc Gets the current presence data for the channel.
160
167
  */
161
- getPresences(): Record<string, PresenceType>;
168
+ getPresences(): Promise<Record<string, PresenceType>>;
162
169
 
163
170
  /**
164
171
  * @desc Gets the assign date for a specific user.
@@ -252,7 +259,7 @@ export declare class AbstractRequest<Path extends string, PresenceType extends P
252
259
 
253
260
  assigns: Record<string, AssignType>;
254
261
 
255
- presence: Record<string, PresenceType>;
262
+ getPresence(): Promise<Record<string, PresenceType>>;
256
263
  }
257
264
 
258
265
  export declare class JoinRequest<Path extends string, PresenceType extends PondPresence = PondPresence, AssignType extends PondAssigns = PondAssigns> extends AbstractRequest<Path, PresenceType, AssignType> {