@eleven-am/pondsocket 0.1.217 → 0.1.219

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 (44) hide show
  1. package/README.md +84 -164
  2. package/{abstracts → dist/abstracts}/types.d.ts +3 -3
  3. package/{contexts → dist/contexts}/baseContext.d.ts +3 -1
  4. package/{contexts → dist/contexts}/baseContext.js +6 -0
  5. package/{contexts → dist/contexts}/eventContext.d.ts +2 -2
  6. package/{contexts → dist/contexts}/joinContext.js +8 -2
  7. package/dist/contexts/outgoingContext.d.ts +36 -0
  8. package/{contexts → dist/contexts}/outgoingContext.js +12 -6
  9. package/{engines → dist/engines}/channelEngine.d.ts +3 -1
  10. package/{engines → dist/engines}/channelEngine.js +103 -13
  11. package/{engines → dist/engines}/endpointEngine.d.ts +2 -1
  12. package/{engines → dist/engines}/endpointEngine.js +29 -11
  13. package/{engines → dist/engines}/lobbyEngine.js +14 -9
  14. package/{index.d.ts → dist/index.d.ts} +1 -0
  15. package/dist/matcher/matcher.js +17 -0
  16. package/{server → dist/server}/server.d.ts +8 -4
  17. package/{server → dist/server}/server.js +112 -33
  18. package/{types.d.ts → dist/types.d.ts} +6 -6
  19. package/{wrappers → dist/wrappers}/channel.d.ts +13 -5
  20. package/{wrappers → dist/wrappers}/channel.js +22 -6
  21. package/{wrappers → dist/wrappers}/endpoint.d.ts +4 -2
  22. package/{wrappers → dist/wrappers}/pondChannel.d.ts +4 -4
  23. package/{wrappers → dist/wrappers}/pondChannel.js +6 -6
  24. package/package.json +48 -64
  25. package/contexts/outgoingContext.d.ts +0 -28
  26. package/matcher/matcher.js +0 -74
  27. /package/{abstracts → dist/abstracts}/distributor.d.ts +0 -0
  28. /package/{abstracts → dist/abstracts}/distributor.js +0 -0
  29. /package/{abstracts → dist/abstracts}/middleware.d.ts +0 -0
  30. /package/{abstracts → dist/abstracts}/middleware.js +0 -0
  31. /package/{abstracts → dist/abstracts}/types.js +0 -0
  32. /package/{contexts → dist/contexts}/connectionContext.d.ts +0 -0
  33. /package/{contexts → dist/contexts}/connectionContext.js +0 -0
  34. /package/{contexts → dist/contexts}/eventContext.js +0 -0
  35. /package/{contexts → dist/contexts}/joinContext.d.ts +0 -0
  36. /package/{engines → dist/engines}/lobbyEngine.d.ts +0 -0
  37. /package/{engines → dist/engines}/presenceEngine.d.ts +0 -0
  38. /package/{engines → dist/engines}/presenceEngine.js +0 -0
  39. /package/{errors → dist/errors}/httpError.d.ts +0 -0
  40. /package/{errors → dist/errors}/httpError.js +0 -0
  41. /package/{index.js → dist/index.js} +0 -0
  42. /package/{matcher → dist/matcher}/matcher.d.ts +0 -0
  43. /package/{types.js → dist/types.js} +0 -0
  44. /package/{wrappers → dist/wrappers}/endpoint.js +0 -0
@@ -30,7 +30,7 @@ var __rest = (this && this.__rest) || function (s, e) {
30
30
  }
31
31
  return t;
32
32
  };
33
- var _ChannelEngine_instances, _ChannelEngine_endpointId, _ChannelEngine_backend, _ChannelEngine_nodeId, _ChannelEngine_presenceEngine, _ChannelEngine_assignsCache, _ChannelEngine_userSubscriptions, _ChannelEngine_publisher, _ChannelEngine_distributedSubscription, _ChannelEngine_heartbeatSubscription, _ChannelEngine_nodeLastSeen, _ChannelEngine_nodeUsers, _ChannelEngine_staleNodeTimer, _ChannelEngine_name, _ChannelEngine_closed, _ChannelEngine_distributedReady, _ChannelEngine_safeRemovePresence, _ChannelEngine_buildSubscriber, _ChannelEngine_getOrCreatePresenceEngine, _ChannelEngine_getUsersFromRecipients, _ChannelEngine_setupDistributedSubscription, _ChannelEngine_afterDistributedReady, _ChannelEngine_handleDistributedMessage, _ChannelEngine_requestChannelState, _ChannelEngine_handleStateRequest, _ChannelEngine_handleStateResponse, _ChannelEngine_handleRemoteUserJoined, _ChannelEngine_handleRemoteUserLeft, _ChannelEngine_handleRemoteMessage, _ChannelEngine_handleRemotePresenceUpdate, _ChannelEngine_handleRemotePresenceRemoved, _ChannelEngine_handleRemoteAssignsUpdate, _ChannelEngine_handleRemoteEvictUser, _ChannelEngine_setupHeartbeatTracking, _ChannelEngine_cleanupStaleNodes, _ChannelEngine_trackNodeUser, _ChannelEngine_untrackNodeUser, _ChannelEngine_broadcastToNodes;
33
+ var _ChannelEngine_instances, _ChannelEngine_endpointId, _ChannelEngine_backend, _ChannelEngine_nodeId, _ChannelEngine_presenceEngine, _ChannelEngine_assignsCache, _ChannelEngine_userSubscriptions, _ChannelEngine_publisher, _ChannelEngine_distributedSubscription, _ChannelEngine_heartbeatSubscription, _ChannelEngine_nodeLastSeen, _ChannelEngine_nodeUsers, _ChannelEngine_pendingUserGets, _ChannelEngine_staleNodeTimer, _ChannelEngine_name, _ChannelEngine_closed, _ChannelEngine_distributedReady, _ChannelEngine_safeRemovePresence, _ChannelEngine_buildSubscriber, _ChannelEngine_getOrCreatePresenceEngine, _ChannelEngine_getUsersFromRecipients, _ChannelEngine_setupDistributedSubscription, _ChannelEngine_afterDistributedReady, _ChannelEngine_handleDistributedMessage, _ChannelEngine_requestChannelState, _ChannelEngine_handleStateRequest, _ChannelEngine_handleStateResponse, _ChannelEngine_handleRemoteUserJoined, _ChannelEngine_handleRemoteUserLeft, _ChannelEngine_handleRemoteMessage, _ChannelEngine_handleRemotePresenceUpdate, _ChannelEngine_handleRemotePresenceRemoved, _ChannelEngine_handleRemoteAssignsUpdate, _ChannelEngine_handleRemoteEvictUser, _ChannelEngine_handleRemoteUserRemove, _ChannelEngine_handleRemoteUserGetRequest, _ChannelEngine_handleRemoteUserGetResponse, _ChannelEngine_setupHeartbeatTracking, _ChannelEngine_cleanupStaleNodes, _ChannelEngine_trackNodeUser, _ChannelEngine_untrackNodeUser, _ChannelEngine_broadcastToNodes;
34
34
  Object.defineProperty(exports, "__esModule", { value: true });
35
35
  exports.ChannelEngine = void 0;
36
36
  const pondsocket_common_1 = require("@eleven-am/pondsocket-common");
@@ -59,6 +59,7 @@ class ChannelEngine {
59
59
  _ChannelEngine_heartbeatSubscription.set(this, null);
60
60
  _ChannelEngine_nodeLastSeen.set(this, new Map());
61
61
  _ChannelEngine_nodeUsers.set(this, new Map());
62
+ _ChannelEngine_pendingUserGets.set(this, new Map());
62
63
  _ChannelEngine_staleNodeTimer.set(this, null);
63
64
  _ChannelEngine_name.set(this, void 0);
64
65
  _ChannelEngine_closed.set(this, false);
@@ -78,7 +79,7 @@ class ChannelEngine {
78
79
  get users() {
79
80
  return new Set(__classPrivateFieldGet(this, _ChannelEngine_assignsCache, "f").keys());
80
81
  }
81
- addUser(userId, assigns, onMessage) {
82
+ addUser(userId, assigns, onMessage, requestId = (0, pondsocket_common_1.uuid)()) {
82
83
  if (this.users.has(userId)) {
83
84
  const message = `ChannelEngine: User with id ${userId} already exists in channel ${this.name}`;
84
85
  throw new httpError_1.HttpError(400, message);
@@ -86,7 +87,7 @@ class ChannelEngine {
86
87
  const isFirstUser = this.users.size === 0;
87
88
  onMessage({
88
89
  channelName: __classPrivateFieldGet(this, _ChannelEngine_name, "f"),
89
- requestId: (0, pondsocket_common_1.uuid)(),
90
+ requestId,
90
91
  action: pondsocket_common_1.ServerActions.SYSTEM,
91
92
  event: pondsocket_common_1.Events.ACKNOWLEDGE,
92
93
  payload: {},
@@ -222,6 +223,38 @@ class ChannelEngine {
222
223
  });
223
224
  this.removeUser(userId, true);
224
225
  }
226
+ requestUserRemoval(userId) {
227
+ __classPrivateFieldGet(this, _ChannelEngine_instances, "m", _ChannelEngine_broadcastToNodes).call(this, {
228
+ type: types_1.DistributedMessageType.USER_REMOVE,
229
+ endpointName: __classPrivateFieldGet(this, _ChannelEngine_endpointId, "f"),
230
+ channelName: __classPrivateFieldGet(this, _ChannelEngine_name, "f"),
231
+ userId,
232
+ });
233
+ }
234
+ getUserAcrossNodes(userId, timeoutMs = 5000) {
235
+ if (!__classPrivateFieldGet(this, _ChannelEngine_backend, "f")) {
236
+ return Promise.resolve(null);
237
+ }
238
+ const requestId = (0, pondsocket_common_1.uuid)();
239
+ return new Promise((resolve) => {
240
+ const timer = setTimeout(() => {
241
+ __classPrivateFieldGet(this, _ChannelEngine_pendingUserGets, "f").delete(requestId);
242
+ resolve(null);
243
+ }, timeoutMs);
244
+ __classPrivateFieldGet(this, _ChannelEngine_pendingUserGets, "f").set(requestId, {
245
+ resolve,
246
+ timer,
247
+ });
248
+ __classPrivateFieldGet(this, _ChannelEngine_instances, "m", _ChannelEngine_broadcastToNodes).call(this, {
249
+ type: types_1.DistributedMessageType.USER_GET_REQUEST,
250
+ endpointName: __classPrivateFieldGet(this, _ChannelEngine_endpointId, "f"),
251
+ channelName: __classPrivateFieldGet(this, _ChannelEngine_name, "f"),
252
+ userId,
253
+ requestId,
254
+ fromNode: __classPrivateFieldGet(this, _ChannelEngine_nodeId, "f"),
255
+ });
256
+ });
257
+ }
225
258
  getAssigns() {
226
259
  return mapToObject(__classPrivateFieldGet(this, _ChannelEngine_assignsCache, "f"));
227
260
  }
@@ -238,9 +271,15 @@ class ChannelEngine {
238
271
  this.close();
239
272
  }
240
273
  removeUser(userId, skipDistributedBroadcast = false) {
274
+ let userData;
275
+ try {
276
+ userData = this.getUserData(userId);
277
+ }
278
+ catch (_a) {
279
+ return;
280
+ }
281
+ const unsubscribe = __classPrivateFieldGet(this, _ChannelEngine_userSubscriptions, "f").get(userId);
241
282
  try {
242
- const userData = this.getUserData(userId);
243
- const unsubscribe = __classPrivateFieldGet(this, _ChannelEngine_userSubscriptions, "f").get(userId);
244
283
  __classPrivateFieldGet(this, _ChannelEngine_assignsCache, "f").delete(userId);
245
284
  __classPrivateFieldGet(this, _ChannelEngine_instances, "m", _ChannelEngine_safeRemovePresence).call(this, userId);
246
285
  if (unsubscribe) {
@@ -255,19 +294,25 @@ class ChannelEngine {
255
294
  userId,
256
295
  });
257
296
  }
258
- if (this.parent.leaveCallback) {
259
- this.parent.leaveCallback({
297
+ }
298
+ catch (_) {
299
+ void 0;
300
+ }
301
+ if (this.users.size === 0) {
302
+ this.close();
303
+ }
304
+ if (this.parent.leaveCallback) {
305
+ try {
306
+ const result = this.parent.leaveCallback({
260
307
  user: userData,
261
308
  channel: this.parent.wrapChannel(this),
262
309
  });
310
+ void Promise.resolve(result).catch(() => { });
263
311
  }
264
- if (this.users.size === 0) {
265
- this.close();
312
+ catch (_) {
313
+ void 0;
266
314
  }
267
315
  }
268
- catch (_) {
269
- void 0;
270
- }
271
316
  }
272
317
  getUserData(userId) {
273
318
  var _a;
@@ -304,6 +349,8 @@ class ChannelEngine {
304
349
  clearInterval(__classPrivateFieldGet(this, _ChannelEngine_staleNodeTimer, "f"));
305
350
  __classPrivateFieldSet(this, _ChannelEngine_staleNodeTimer, null, "f");
306
351
  }
352
+ __classPrivateFieldGet(this, _ChannelEngine_pendingUserGets, "f").forEach((pending) => clearTimeout(pending.timer));
353
+ __classPrivateFieldGet(this, _ChannelEngine_pendingUserGets, "f").clear();
307
354
  __classPrivateFieldGet(this, _ChannelEngine_nodeLastSeen, "f").clear();
308
355
  __classPrivateFieldGet(this, _ChannelEngine_nodeUsers, "f").clear();
309
356
  __classPrivateFieldGet(this, _ChannelEngine_publisher, "f").close();
@@ -311,7 +358,7 @@ class ChannelEngine {
311
358
  }
312
359
  }
313
360
  exports.ChannelEngine = ChannelEngine;
314
- _ChannelEngine_endpointId = new WeakMap(), _ChannelEngine_backend = new WeakMap(), _ChannelEngine_nodeId = new WeakMap(), _ChannelEngine_presenceEngine = new WeakMap(), _ChannelEngine_assignsCache = new WeakMap(), _ChannelEngine_userSubscriptions = new WeakMap(), _ChannelEngine_publisher = new WeakMap(), _ChannelEngine_distributedSubscription = new WeakMap(), _ChannelEngine_heartbeatSubscription = new WeakMap(), _ChannelEngine_nodeLastSeen = new WeakMap(), _ChannelEngine_nodeUsers = new WeakMap(), _ChannelEngine_staleNodeTimer = new WeakMap(), _ChannelEngine_name = new WeakMap(), _ChannelEngine_closed = new WeakMap(), _ChannelEngine_distributedReady = new WeakMap(), _ChannelEngine_instances = new WeakSet(), _ChannelEngine_safeRemovePresence = function _ChannelEngine_safeRemovePresence(userId) {
361
+ _ChannelEngine_endpointId = new WeakMap(), _ChannelEngine_backend = new WeakMap(), _ChannelEngine_nodeId = new WeakMap(), _ChannelEngine_presenceEngine = new WeakMap(), _ChannelEngine_assignsCache = new WeakMap(), _ChannelEngine_userSubscriptions = new WeakMap(), _ChannelEngine_publisher = new WeakMap(), _ChannelEngine_distributedSubscription = new WeakMap(), _ChannelEngine_heartbeatSubscription = new WeakMap(), _ChannelEngine_nodeLastSeen = new WeakMap(), _ChannelEngine_nodeUsers = new WeakMap(), _ChannelEngine_pendingUserGets = new WeakMap(), _ChannelEngine_staleNodeTimer = new WeakMap(), _ChannelEngine_name = new WeakMap(), _ChannelEngine_closed = new WeakMap(), _ChannelEngine_distributedReady = new WeakMap(), _ChannelEngine_instances = new WeakSet(), _ChannelEngine_safeRemovePresence = function _ChannelEngine_safeRemovePresence(userId) {
315
362
  if (__classPrivateFieldGet(this, _ChannelEngine_presenceEngine, "f")) {
316
363
  try {
317
364
  __classPrivateFieldGet(this, _ChannelEngine_presenceEngine, "f").removePresence(userId);
@@ -421,6 +468,15 @@ _ChannelEngine_endpointId = new WeakMap(), _ChannelEngine_backend = new WeakMap(
421
468
  case types_1.DistributedMessageType.EVICT_USER:
422
469
  __classPrivateFieldGet(this, _ChannelEngine_instances, "m", _ChannelEngine_handleRemoteEvictUser).call(this, message);
423
470
  break;
471
+ case types_1.DistributedMessageType.USER_REMOVE:
472
+ __classPrivateFieldGet(this, _ChannelEngine_instances, "m", _ChannelEngine_handleRemoteUserRemove).call(this, message);
473
+ break;
474
+ case types_1.DistributedMessageType.USER_GET_REQUEST:
475
+ __classPrivateFieldGet(this, _ChannelEngine_instances, "m", _ChannelEngine_handleRemoteUserGetRequest).call(this, message);
476
+ break;
477
+ case types_1.DistributedMessageType.USER_GET_RESPONSE:
478
+ __classPrivateFieldGet(this, _ChannelEngine_instances, "m", _ChannelEngine_handleRemoteUserGetResponse).call(this, message);
479
+ break;
424
480
  case types_1.DistributedMessageType.NODE_HEARTBEAT:
425
481
  break;
426
482
  default:
@@ -545,6 +601,40 @@ _ChannelEngine_endpointId = new WeakMap(), _ChannelEngine_backend = new WeakMap(
545
601
  unsubscribe();
546
602
  __classPrivateFieldGet(this, _ChannelEngine_userSubscriptions, "f").delete(message.userId);
547
603
  }
604
+ }, _ChannelEngine_handleRemoteUserRemove = function _ChannelEngine_handleRemoteUserRemove(message) {
605
+ if (__classPrivateFieldGet(this, _ChannelEngine_userSubscriptions, "f").has(message.userId)) {
606
+ this.removeUser(message.userId);
607
+ return;
608
+ }
609
+ __classPrivateFieldGet(this, _ChannelEngine_assignsCache, "f").delete(message.userId);
610
+ __classPrivateFieldGet(this, _ChannelEngine_instances, "m", _ChannelEngine_safeRemovePresence).call(this, message.userId);
611
+ __classPrivateFieldGet(this, _ChannelEngine_instances, "m", _ChannelEngine_untrackNodeUser).call(this, message.sourceNodeId, message.userId);
612
+ }, _ChannelEngine_handleRemoteUserGetRequest = function _ChannelEngine_handleRemoteUserGetRequest(message) {
613
+ var _a;
614
+ if (!__classPrivateFieldGet(this, _ChannelEngine_userSubscriptions, "f").has(message.userId)) {
615
+ return;
616
+ }
617
+ __classPrivateFieldGet(this, _ChannelEngine_instances, "m", _ChannelEngine_broadcastToNodes).call(this, {
618
+ type: types_1.DistributedMessageType.USER_GET_RESPONSE,
619
+ endpointName: __classPrivateFieldGet(this, _ChannelEngine_endpointId, "f"),
620
+ channelName: __classPrivateFieldGet(this, _ChannelEngine_name, "f"),
621
+ userId: message.userId,
622
+ requestId: message.requestId,
623
+ assigns: __classPrivateFieldGet(this, _ChannelEngine_assignsCache, "f").get(message.userId) || {},
624
+ presence: ((_a = __classPrivateFieldGet(this, _ChannelEngine_presenceEngine, "f")) === null || _a === void 0 ? void 0 : _a.getPresence(message.userId)) || {},
625
+ });
626
+ }, _ChannelEngine_handleRemoteUserGetResponse = function _ChannelEngine_handleRemoteUserGetResponse(message) {
627
+ const pending = __classPrivateFieldGet(this, _ChannelEngine_pendingUserGets, "f").get(message.requestId);
628
+ if (!pending) {
629
+ return;
630
+ }
631
+ clearTimeout(pending.timer);
632
+ __classPrivateFieldGet(this, _ChannelEngine_pendingUserGets, "f").delete(message.requestId);
633
+ pending.resolve({
634
+ id: message.userId,
635
+ assigns: message.assigns || {},
636
+ presence: message.presence || {},
637
+ });
548
638
  }, _ChannelEngine_setupHeartbeatTracking = function _ChannelEngine_setupHeartbeatTracking() {
549
639
  if (!__classPrivateFieldGet(this, _ChannelEngine_backend, "f")) {
550
640
  return;
@@ -1,4 +1,4 @@
1
- import { ChannelEvent, AnyPondSchema, PondPath } from '@eleven-am/pondsocket-common';
1
+ import { ChannelEvent, AnyPondChannelDefinition, AnyPondSchema, PathOf, PondPath, SchemaOf } from '@eleven-am/pondsocket-common';
2
2
  import { WebSocket } from 'ws';
3
3
  import { AuthorizationHandler, SocketCache } from '../abstracts/types';
4
4
  import { IDistributedBackend } from '../types';
@@ -10,6 +10,7 @@ export declare class EndpointEngine {
10
10
  /**
11
11
  * Creates a new channel on a specified path
12
12
  */
13
+ createChannel<Definition extends AnyPondChannelDefinition>(definition: Definition, handler: AuthorizationHandler<PathOf<Definition>, SchemaOf<Definition>>): PondChannel<SchemaOf<Definition>>;
13
14
  createChannel<Path extends string, Schema extends AnyPondSchema = AnyPondSchema>(path: PondPath<Path>, handler: AuthorizationHandler<Path, Schema>): PondChannel<Schema>;
14
15
  /**
15
16
  * Gets all connected clients
@@ -36,10 +36,14 @@ class EndpointEngine {
36
36
  __classPrivateFieldSet(this, _EndpointEngine_backend, backend || null, "f");
37
37
  __classPrivateFieldSet(this, _EndpointEngine_maxMessageSize, maxMessageSize, "f");
38
38
  }
39
- /**
40
- * Creates a new channel on a specified path
41
- */
42
- createChannel(path, handler) {
39
+ createChannel(pathOrDefinition, handler) {
40
+ const path = (0, pondsocket_common_1.isPondChannelDefinition)(pathOrDefinition) ? pathOrDefinition.path : pathOrDefinition;
41
+ if (typeof path === 'string') {
42
+ (0, pondsocket_common_1.compilePondRoute)(path);
43
+ }
44
+ if (__classPrivateFieldGet(this, _EndpointEngine_lobbyEngines, "f").has(path)) {
45
+ throw new httpError_1.HttpError(409, `GatewayEngine: Channel pattern ${String(path)} is already registered`);
46
+ }
43
47
  const lobbyEngine = new lobbyEngine_1.LobbyEngine(this, __classPrivateFieldGet(this, _EndpointEngine_backend, "f"));
44
48
  __classPrivateFieldGet(this, _EndpointEngine_middleware, "f").use((user, joinParams, next) => {
45
49
  const event = (0, matcher_1.parseAddress)(path, user.channelName);
@@ -52,7 +56,16 @@ class EndpointEngine {
52
56
  };
53
57
  const channel = lobbyEngine.getOrCreateChannel(user.channelName);
54
58
  const context = new joinContext_1.JoinContext(options, channel, user);
55
- return Promise.resolve(handler(context, next)).then(() => undefined);
59
+ let delegated = false;
60
+ const delegate = (error) => {
61
+ delegated = true;
62
+ return next(error);
63
+ };
64
+ return Promise.resolve(handler(context, delegate)).then(() => {
65
+ if (!delegated && !context.hasResponded) {
66
+ context.decline('Join handler completed without accepting or declining the request', 500);
67
+ }
68
+ });
56
69
  }
57
70
  next();
58
71
  });
@@ -141,8 +154,9 @@ _EndpointEngine_sockets = new WeakMap(), _EndpointEngine_backend = new WeakMap()
141
154
  }, _EndpointEngine_joinChannel = function _EndpointEngine_joinChannel(channel, socket, joinParams, requestId) {
142
155
  const cache = Object.assign(Object.assign({}, socket), { requestId, channelName: channel });
143
156
  __classPrivateFieldGet(this, _EndpointEngine_middleware, "f").run(cache, joinParams, (error) => {
144
- error = error || new httpError_1.HttpError(404, `GatewayEngine: Channel ${channel} does not exist`);
145
- throw error;
157
+ const requestError = error || new httpError_1.HttpError(404, `GatewayEngine: Channel ${channel} does not exist`);
158
+ const errorType = error ? pondsocket_common_1.ErrorTypes.CHANNEL_ERROR : pondsocket_common_1.ErrorTypes.CHANNEL_NOT_FOUND;
159
+ this.sendMessage(socket.socket, __classPrivateFieldGet(this, _EndpointEngine_instances, "m", _EndpointEngine_buildError).call(this, requestError, errorType, channel, requestId));
146
160
  });
147
161
  }, _EndpointEngine_leaveChannel = function _EndpointEngine_leaveChannel(channel, socket) {
148
162
  var _a;
@@ -161,7 +175,7 @@ _EndpointEngine_sockets = new WeakMap(), _EndpointEngine_backend = new WeakMap()
161
175
  }
162
176
  }
163
177
  throw new httpError_1.HttpError(404, `GatewayEngine: Channel ${channel} does not exist`);
164
- }, _EndpointEngine_buildError = function _EndpointEngine_buildError(error) {
178
+ }, _EndpointEngine_buildError = function _EndpointEngine_buildError(error, errorType = pondsocket_common_1.ErrorTypes.INVALID_MESSAGE, channelName = pondsocket_common_1.SystemSender.ENDPOINT, requestId = (0, pondsocket_common_1.uuid)()) {
165
179
  let message;
166
180
  let status;
167
181
  if (error instanceof httpError_1.HttpError) {
@@ -177,11 +191,15 @@ _EndpointEngine_sockets = new WeakMap(), _EndpointEngine_backend = new WeakMap()
177
191
  status = 500;
178
192
  }
179
193
  const event = {
180
- event: pondsocket_common_1.ErrorTypes.INVALID_MESSAGE,
194
+ event: errorType,
181
195
  action: pondsocket_common_1.ServerActions.ERROR,
182
- channelName: pondsocket_common_1.SystemSender.ENDPOINT,
183
- requestId: (0, pondsocket_common_1.uuid)(),
196
+ channelName,
197
+ requestId,
184
198
  payload: {
199
+ code: errorType,
200
+ message,
201
+ status,
202
+ statusCode: status,
185
203
  error: {
186
204
  message,
187
205
  status,
@@ -22,6 +22,7 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
22
22
  var _LobbyEngine_instances, _LobbyEngine_backend, _LobbyEngine_channels, _LobbyEngine_getChannel, _LobbyEngine_createChannel;
23
23
  Object.defineProperty(exports, "__esModule", { value: true });
24
24
  exports.LobbyEngine = void 0;
25
+ const pondsocket_common_1 = require("@eleven-am/pondsocket-common");
25
26
  const channelEngine_1 = require("./channelEngine");
26
27
  const middleware_1 = require("../abstracts/middleware");
27
28
  const eventContext_1 = require("../contexts/eventContext");
@@ -50,6 +51,9 @@ class LobbyEngine {
50
51
  * Attaches a handler for a specific event pattern
51
52
  */
52
53
  onEvent(event, handler) {
54
+ if (typeof event === 'string') {
55
+ (0, pondsocket_common_1.compilePondRoute)(event);
56
+ }
53
57
  this.middleware.use((requestEvent, channel, next) => {
54
58
  const params = (0, matcher_1.parseAddress)(event, requestEvent.event);
55
59
  if (!params) {
@@ -63,18 +67,17 @@ class LobbyEngine {
63
67
  * Attaches a handler for outgoing events
64
68
  */
65
69
  handleOutgoingEvent(event, handler) {
70
+ if (typeof event === 'string') {
71
+ (0, pondsocket_common_1.compilePondRoute)(event);
72
+ }
66
73
  this.outgoing.use((context, chEvent, next) => __awaiter(this, void 0, void 0, function* () {
67
74
  const params = (0, matcher_1.parseAddress)(event, chEvent.event);
68
75
  if (!params || context.isBlocked()) {
69
76
  return next();
70
77
  }
71
- context.updateParams(params);
72
- const payload = yield handler(context, next);
73
- if (payload === undefined || payload === null) {
74
- return;
75
- }
76
- context.transform(payload);
77
- return next();
78
+ const typedContext = context;
79
+ typedContext.updateParams(params);
80
+ yield handler(typedContext);
78
81
  }));
79
82
  }
80
83
  /**
@@ -88,8 +91,10 @@ class LobbyEngine {
88
91
  return __awaiter(this, void 0, void 0, function* () {
89
92
  const params = (0, matcher_1.parseAddress)('*', event.event);
90
93
  const context = new outgoingContext_1.OutgoingContext(event, params, engine, userId);
91
- yield this.outgoing.runAsync(context, event, () => {
92
- // no-op
94
+ yield this.outgoing.runAsync(context, event, (error) => {
95
+ if (error) {
96
+ context.block();
97
+ }
93
98
  });
94
99
  if (context.isBlocked()) {
95
100
  return;
@@ -8,6 +8,7 @@ export { BaseContext } from './contexts/baseContext';
8
8
  export { JoinContext } from './contexts/joinContext';
9
9
  export { EventContext } from './contexts/eventContext';
10
10
  export { OutgoingContext } from './contexts/outgoingContext';
11
+ export type { OutgoingHandlerContext, OutgoingPayload } from './contexts/outgoingContext';
11
12
  export { HttpError } from './errors/httpError';
12
13
  export type { ConnectionHandler, AuthorizationHandler, EventHandler, OutgoingEventHandler, LeaveCallback, LeaveEvent, NextFunction, } from './abstracts/types';
13
14
  export * from './types';
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.parseAddress = parseAddress;
4
+ const pondsocket_common_1 = require("@eleven-am/pondsocket-common");
5
+ function parseAddress(route, address) {
6
+ if (route instanceof RegExp) {
7
+ const match = address.match(route);
8
+ if (!match) {
9
+ return null;
10
+ }
11
+ return {
12
+ params: {},
13
+ query: {},
14
+ };
15
+ }
16
+ return (0, pondsocket_common_1.parsePondRoute)(route, address);
17
+ }
@@ -1,21 +1,25 @@
1
1
  import { IncomingMessage, Server as HTTPServer } from 'http';
2
- import { PondPath } from '@eleven-am/pondsocket-common';
2
+ import { PondEndpointDefinition, PondPath } from '@eleven-am/pondsocket-common';
3
3
  import { ConnectionHandler } from '../abstracts/types';
4
4
  import { PondSocketOptions } from '../types';
5
5
  import { Endpoint } from '../wrappers/endpoint';
6
6
  export declare class PondSocket {
7
7
  #private;
8
- constructor({ server, socketServer, exclusiveServer, distributedBackend, maxMessageSize, heartbeatInterval, }?: PondSocketOptions);
8
+ constructor({ server, socketServer, closeHttpServerOnShutdown, exclusiveServer, distributedBackend, maxMessageSize, heartbeatInterval, }?: PondSocketOptions);
9
9
  /**
10
10
  * Start listening for connections
11
11
  */
12
- listen(...args: any[]): HTTPServer<typeof IncomingMessage, typeof import("node:http").ServerResponse>;
12
+ listen(...args: any[]): HTTPServer<typeof IncomingMessage, typeof import("http").ServerResponse>;
13
13
  /**
14
14
  * Close the server
15
15
  */
16
- close(callback?: (err?: Error) => void, timeout?: number): HTTPServer<typeof IncomingMessage, typeof import("node:http").ServerResponse>;
16
+ close(callback?: (err?: Error) => void, timeout?: number): HTTPServer<typeof IncomingMessage, typeof import("http").ServerResponse>;
17
+ closeAsync(timeout?: number): Promise<void>;
18
+ ready(): Promise<void>;
19
+ isHealthy(): boolean;
17
20
  /**
18
21
  * Create a new endpoint
19
22
  */
23
+ createEndpoint<Path extends string>(definition: PondEndpointDefinition<Path>, handler: ConnectionHandler<Path>): Endpoint;
20
24
  createEndpoint<Path extends string>(path: PondPath<Path>, handler: ConnectionHandler<Path>): Endpoint;
21
25
  }