@eleven-am/pondsocket 0.1.218 → 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 +1 -1
  10. package/{engines → dist/engines}/channelEngine.js +23 -11
  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 +12 -8
  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} +1 -0
  19. package/{wrappers → dist/wrappers}/channel.d.ts +5 -5
  20. package/{wrappers → dist/wrappers}/channel.js +9 -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
@@ -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,6 +67,9 @@ 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()) {
@@ -70,12 +77,7 @@ class LobbyEngine {
70
77
  }
71
78
  const typedContext = context;
72
79
  typedContext.updateParams(params);
73
- const payload = yield handler(typedContext, next);
74
- if (payload === undefined || payload === null) {
75
- return;
76
- }
77
- typedContext.transform(payload);
78
- return next();
80
+ yield handler(typedContext);
79
81
  }));
80
82
  }
81
83
  /**
@@ -89,8 +91,10 @@ class LobbyEngine {
89
91
  return __awaiter(this, void 0, void 0, function* () {
90
92
  const params = (0, matcher_1.parseAddress)('*', event.event);
91
93
  const context = new outgoingContext_1.OutgoingContext(event, params, engine, userId);
92
- yield this.outgoing.runAsync(context, event, () => {
93
- // no-op
94
+ yield this.outgoing.runAsync(context, event, (error) => {
95
+ if (error) {
96
+ context.block();
97
+ }
94
98
  });
95
99
  if (context.isBlocked()) {
96
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
  }
@@ -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");
@@ -10,7 +19,7 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
10
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");
11
20
  return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
12
21
  };
13
- var _PondSocket_instances, _PondSocket_server, _PondSocket_exclusiveServer, _PondSocket_socketServer, _PondSocket_backend, _PondSocket_middleware, _PondSocket_maxMessageSize, _PondSocket_heartbeatMs, _PondSocket_heartbeatTimer, _PondSocket_backendReady, _PondSocket_handleUpgrade, _PondSocket_manageHeartbeat, _PondSocket_init, _PondSocket_getCookies;
22
+ var _PondSocket_instances, _PondSocket_server, _PondSocket_exclusiveServer, _PondSocket_socketServer, _PondSocket_backend, _PondSocket_middleware, _PondSocket_maxMessageSize, _PondSocket_heartbeatMs, _PondSocket_closeHttpServerOnShutdown, _PondSocket_upgradeHandler, _PondSocket_heartbeatTimer, _PondSocket_backendReady, _PondSocket_backendError, _PondSocket_serverError, _PondSocket_shutdownPromise, _PondSocket_shutdown, _PondSocket_handleUpgrade, _PondSocket_manageHeartbeat, _PondSocket_init, _PondSocket_getCookies;
14
23
  Object.defineProperty(exports, "__esModule", { value: true });
15
24
  exports.PondSocket = void 0;
16
25
  const http_1 = require("http");
@@ -22,7 +31,7 @@ const endpointEngine_1 = require("../engines/endpointEngine");
22
31
  const matcher_1 = require("../matcher/matcher");
23
32
  const endpoint_1 = require("../wrappers/endpoint");
24
33
  class PondSocket {
25
- constructor({ server, socketServer, exclusiveServer = true, distributedBackend, maxMessageSize = 1024 * 1024, heartbeatInterval = 30000, } = {}) {
34
+ constructor({ server, socketServer, closeHttpServerOnShutdown = true, exclusiveServer = true, distributedBackend, maxMessageSize = 1024 * 1024, heartbeatInterval = 30000, } = {}) {
26
35
  _PondSocket_instances.add(this);
27
36
  _PondSocket_server.set(this, void 0);
28
37
  _PondSocket_exclusiveServer.set(this, void 0);
@@ -31,15 +40,22 @@ class PondSocket {
31
40
  _PondSocket_middleware.set(this, void 0);
32
41
  _PondSocket_maxMessageSize.set(this, void 0);
33
42
  _PondSocket_heartbeatMs.set(this, void 0);
43
+ _PondSocket_closeHttpServerOnShutdown.set(this, void 0);
44
+ _PondSocket_upgradeHandler.set(this, void 0);
34
45
  _PondSocket_heartbeatTimer.set(this, null);
35
46
  _PondSocket_backendReady.set(this, null);
47
+ _PondSocket_backendError.set(this, null);
48
+ _PondSocket_serverError.set(this, null);
49
+ _PondSocket_shutdownPromise.set(this, null);
36
50
  __classPrivateFieldSet(this, _PondSocket_middleware, new middleware_1.Middleware(), "f");
37
51
  __classPrivateFieldSet(this, _PondSocket_exclusiveServer, exclusiveServer, "f");
38
52
  __classPrivateFieldSet(this, _PondSocket_server, server !== null && server !== void 0 ? server : new http_1.Server(), "f");
39
53
  __classPrivateFieldSet(this, _PondSocket_backend, distributedBackend !== null && distributedBackend !== void 0 ? distributedBackend : null, "f");
40
54
  __classPrivateFieldSet(this, _PondSocket_maxMessageSize, maxMessageSize, "f");
41
55
  __classPrivateFieldSet(this, _PondSocket_heartbeatMs, heartbeatInterval, "f");
56
+ __classPrivateFieldSet(this, _PondSocket_closeHttpServerOnShutdown, closeHttpServerOnShutdown, "f");
42
57
  __classPrivateFieldSet(this, _PondSocket_socketServer, socketServer !== null && socketServer !== void 0 ? socketServer : new ws_1.WebSocketServer({ noServer: true }), "f");
58
+ __classPrivateFieldSet(this, _PondSocket_upgradeHandler, __classPrivateFieldGet(this, _PondSocket_instances, "m", _PondSocket_handleUpgrade).bind(this), "f");
43
59
  __classPrivateFieldGet(this, _PondSocket_instances, "m", _PondSocket_init).call(this);
44
60
  }
45
61
  /**
@@ -52,34 +68,35 @@ class PondSocket {
52
68
  * Close the server
53
69
  */
54
70
  close(callback, timeout = 5000) {
55
- var _a, _b;
56
- if (__classPrivateFieldGet(this, _PondSocket_heartbeatTimer, "f")) {
57
- clearInterval(__classPrivateFieldGet(this, _PondSocket_heartbeatTimer, "f"));
58
- __classPrivateFieldSet(this, _PondSocket_heartbeatTimer, null, "f");
71
+ this.closeAsync(timeout)
72
+ .then(() => callback === null || callback === void 0 ? void 0 : callback())
73
+ .catch((error) => callback === null || callback === void 0 ? void 0 : callback(error instanceof Error ? error : new Error(String(error))));
74
+ return __classPrivateFieldGet(this, _PondSocket_server, "f");
75
+ }
76
+ closeAsync(timeout = 5000) {
77
+ if (__classPrivateFieldGet(this, _PondSocket_shutdownPromise, "f")) {
78
+ return __classPrivateFieldGet(this, _PondSocket_shutdownPromise, "f");
59
79
  }
60
- __classPrivateFieldGet(this, _PondSocket_socketServer, "f").clients.forEach((socket) => {
61
- if (socket.readyState === ws_1.WebSocket.OPEN) {
62
- socket.close(1001, 'Server shutting down');
80
+ __classPrivateFieldSet(this, _PondSocket_shutdownPromise, __classPrivateFieldGet(this, _PondSocket_instances, "m", _PondSocket_shutdown).call(this, timeout), "f");
81
+ return __classPrivateFieldGet(this, _PondSocket_shutdownPromise, "f");
82
+ }
83
+ ready() {
84
+ return __awaiter(this, void 0, void 0, function* () {
85
+ var _a;
86
+ yield ((_a = __classPrivateFieldGet(this, _PondSocket_backendReady, "f")) !== null && _a !== void 0 ? _a : Promise.resolve());
87
+ if (__classPrivateFieldGet(this, _PondSocket_backendError, "f")) {
88
+ throw __classPrivateFieldGet(this, _PondSocket_backendError, "f");
63
89
  }
64
90
  });
65
- const forceClose = setTimeout(() => {
66
- __classPrivateFieldGet(this, _PondSocket_socketServer, "f").clients.forEach((socket) => {
67
- if (socket.readyState !== ws_1.WebSocket.CLOSED) {
68
- socket.terminate();
69
- }
70
- });
71
- __classPrivateFieldGet(this, _PondSocket_socketServer, "f").close();
72
- }, timeout);
73
- __classPrivateFieldGet(this, _PondSocket_socketServer, "f").close(() => {
74
- clearTimeout(forceClose);
75
- });
76
- __classPrivateFieldSet(this, _PondSocket_backendReady, (_b = (_a = __classPrivateFieldGet(this, _PondSocket_backendReady, "f")) === null || _a === void 0 ? void 0 : _a.catch(() => { }).then(() => { var _a; return (_a = __classPrivateFieldGet(this, _PondSocket_backend, "f")) === null || _a === void 0 ? void 0 : _a.cleanup(); }).catch(() => { })) !== null && _b !== void 0 ? _b : null, "f");
77
- return __classPrivateFieldGet(this, _PondSocket_server, "f").close(callback);
78
91
  }
79
- /**
80
- * Create a new endpoint
81
- */
82
- createEndpoint(path, handler) {
92
+ isHealthy() {
93
+ return __classPrivateFieldGet(this, _PondSocket_backendError, "f") === null && __classPrivateFieldGet(this, _PondSocket_serverError, "f") === null && __classPrivateFieldGet(this, _PondSocket_shutdownPromise, "f") === null;
94
+ }
95
+ createEndpoint(pathOrDefinition, handler) {
96
+ const path = (0, pondsocket_common_1.isPondEndpointDefinition)(pathOrDefinition) ? pathOrDefinition.path : pathOrDefinition;
97
+ if (typeof path === 'string') {
98
+ (0, pondsocket_common_1.compilePondRoute)(path);
99
+ }
83
100
  const endpoint = new endpointEngine_1.EndpointEngine(String(path), __classPrivateFieldGet(this, _PondSocket_backend, "f"), __classPrivateFieldGet(this, _PondSocket_maxMessageSize, "f"));
84
101
  __classPrivateFieldGet(this, _PondSocket_middleware, "f").use((req, params, next) => {
85
102
  const event = (0, matcher_1.parseAddress)(path, req.address);
@@ -93,13 +110,67 @@ class PondSocket {
93
110
  webSocketServer: __classPrivateFieldGet(this, _PondSocket_socketServer, "f"),
94
111
  };
95
112
  const context = new connectionContext_1.ConnectionContext(request, newParams);
96
- return Promise.resolve(handler(context, next)).then(() => undefined);
113
+ let delegated = false;
114
+ const delegate = (error) => {
115
+ delegated = true;
116
+ return next(error);
117
+ };
118
+ return Promise.resolve(handler(context, delegate)).then(() => {
119
+ if (!delegated && !context.hasResponded) {
120
+ context.decline('Connection handler completed without accepting or declining the request', 500);
121
+ }
122
+ });
97
123
  });
98
124
  return new endpoint_1.Endpoint(endpoint);
99
125
  }
100
126
  }
101
127
  exports.PondSocket = PondSocket;
102
- _PondSocket_server = new WeakMap(), _PondSocket_exclusiveServer = new WeakMap(), _PondSocket_socketServer = new WeakMap(), _PondSocket_backend = new WeakMap(), _PondSocket_middleware = new WeakMap(), _PondSocket_maxMessageSize = new WeakMap(), _PondSocket_heartbeatMs = new WeakMap(), _PondSocket_heartbeatTimer = new WeakMap(), _PondSocket_backendReady = new WeakMap(), _PondSocket_instances = new WeakSet(), _PondSocket_handleUpgrade = function _PondSocket_handleUpgrade(req, socket, head) {
128
+ _PondSocket_server = new WeakMap(), _PondSocket_exclusiveServer = new WeakMap(), _PondSocket_socketServer = new WeakMap(), _PondSocket_backend = new WeakMap(), _PondSocket_middleware = new WeakMap(), _PondSocket_maxMessageSize = new WeakMap(), _PondSocket_heartbeatMs = new WeakMap(), _PondSocket_closeHttpServerOnShutdown = new WeakMap(), _PondSocket_upgradeHandler = new WeakMap(), _PondSocket_heartbeatTimer = new WeakMap(), _PondSocket_backendReady = new WeakMap(), _PondSocket_backendError = new WeakMap(), _PondSocket_serverError = new WeakMap(), _PondSocket_shutdownPromise = new WeakMap(), _PondSocket_instances = new WeakSet(), _PondSocket_shutdown = function _PondSocket_shutdown(timeout) {
129
+ return __awaiter(this, void 0, void 0, function* () {
130
+ var _a;
131
+ if (__classPrivateFieldGet(this, _PondSocket_heartbeatTimer, "f")) {
132
+ clearInterval(__classPrivateFieldGet(this, _PondSocket_heartbeatTimer, "f"));
133
+ __classPrivateFieldSet(this, _PondSocket_heartbeatTimer, null, "f");
134
+ }
135
+ __classPrivateFieldGet(this, _PondSocket_server, "f").off('upgrade', __classPrivateFieldGet(this, _PondSocket_upgradeHandler, "f"));
136
+ __classPrivateFieldGet(this, _PondSocket_socketServer, "f").clients.forEach((socket) => {
137
+ if (socket.readyState === ws_1.WebSocket.OPEN) {
138
+ socket.close(1001, 'Server shutting down');
139
+ }
140
+ });
141
+ const closeSockets = new Promise((resolve) => {
142
+ var _a;
143
+ const forceClose = setTimeout(() => {
144
+ __classPrivateFieldGet(this, _PondSocket_socketServer, "f").clients.forEach((socket) => {
145
+ if (socket.readyState !== ws_1.WebSocket.CLOSED) {
146
+ socket.terminate();
147
+ }
148
+ });
149
+ resolve();
150
+ }, timeout);
151
+ (_a = forceClose.unref) === null || _a === void 0 ? void 0 : _a.call(forceClose);
152
+ try {
153
+ __classPrivateFieldGet(this, _PondSocket_socketServer, "f").close(() => {
154
+ clearTimeout(forceClose);
155
+ resolve();
156
+ });
157
+ }
158
+ catch (_b) {
159
+ clearTimeout(forceClose);
160
+ resolve();
161
+ }
162
+ });
163
+ const cleanupBackend = ((_a = __classPrivateFieldGet(this, _PondSocket_backendReady, "f")) !== null && _a !== void 0 ? _a : Promise.resolve())
164
+ .catch(() => { })
165
+ .then(() => { var _a; return (_a = __classPrivateFieldGet(this, _PondSocket_backend, "f")) === null || _a === void 0 ? void 0 : _a.cleanup(); });
166
+ const closeHttpServer = __classPrivateFieldGet(this, _PondSocket_closeHttpServerOnShutdown, "f") && __classPrivateFieldGet(this, _PondSocket_server, "f").listening
167
+ ? new Promise((resolve, reject) => {
168
+ __classPrivateFieldGet(this, _PondSocket_server, "f").close((error) => error ? reject(error) : resolve());
169
+ })
170
+ : Promise.resolve();
171
+ yield Promise.all([closeSockets, cleanupBackend, closeHttpServer]);
172
+ });
173
+ }, _PondSocket_handleUpgrade = function _PondSocket_handleUpgrade(req, socket, head) {
103
174
  const clientId = (0, pondsocket_common_1.uuid)();
104
175
  const request = {
105
176
  id: clientId,
@@ -125,12 +196,13 @@ _PondSocket_server = new WeakMap(), _PondSocket_exclusiveServer = new WeakMap(),
125
196
  }
126
197
  });
127
198
  }, _PondSocket_manageHeartbeat = function _PondSocket_manageHeartbeat() {
199
+ var _a;
128
200
  __classPrivateFieldGet(this, _PondSocket_socketServer, "f").on('connection', (socket) => {
129
201
  socket.on('pong', () => {
130
202
  socket.isAlive = true;
131
203
  });
132
204
  });
133
- return setInterval(() => {
205
+ const timer = setInterval(() => {
134
206
  __classPrivateFieldGet(this, _PondSocket_socketServer, "f").clients.forEach((socket) => {
135
207
  if (socket.isAlive === false) {
136
208
  return socket.terminate();
@@ -139,18 +211,20 @@ _PondSocket_server = new WeakMap(), _PondSocket_exclusiveServer = new WeakMap(),
139
211
  socket.ping();
140
212
  });
141
213
  }, __classPrivateFieldGet(this, _PondSocket_heartbeatMs, "f"));
214
+ (_a = timer.unref) === null || _a === void 0 ? void 0 : _a.call(timer);
215
+ return timer;
142
216
  }, _PondSocket_init = function _PondSocket_init() {
143
217
  var _a, _b;
144
218
  __classPrivateFieldSet(this, _PondSocket_heartbeatTimer, __classPrivateFieldGet(this, _PondSocket_instances, "m", _PondSocket_manageHeartbeat).call(this), "f");
145
219
  __classPrivateFieldSet(this, _PondSocket_backendReady, (_b = (_a = __classPrivateFieldGet(this, _PondSocket_backend, "f")) === null || _a === void 0 ? void 0 : _a.initialize().catch((error) => {
146
- __classPrivateFieldGet(this, _PondSocket_server, "f").emit('error', error);
220
+ __classPrivateFieldSet(this, _PondSocket_backendError, error instanceof Error ? error : new Error(String(error)), "f");
147
221
  })) !== null && _b !== void 0 ? _b : null, "f");
148
222
  __classPrivateFieldGet(this, _PondSocket_server, "f").on('error', (error) => {
223
+ __classPrivateFieldSet(this, _PondSocket_serverError, error, "f");
149
224
  if (__classPrivateFieldGet(this, _PondSocket_heartbeatTimer, "f")) {
150
225
  clearInterval(__classPrivateFieldGet(this, _PondSocket_heartbeatTimer, "f"));
151
226
  __classPrivateFieldSet(this, _PondSocket_heartbeatTimer, null, "f");
152
227
  }
153
- throw new Error(error.message);
154
228
  });
155
229
  __classPrivateFieldGet(this, _PondSocket_server, "f").on('close', () => {
156
230
  if (__classPrivateFieldGet(this, _PondSocket_heartbeatTimer, "f")) {
@@ -158,7 +232,7 @@ _PondSocket_server = new WeakMap(), _PondSocket_exclusiveServer = new WeakMap(),
158
232
  __classPrivateFieldSet(this, _PondSocket_heartbeatTimer, null, "f");
159
233
  }
160
234
  });
161
- __classPrivateFieldGet(this, _PondSocket_server, "f").on('upgrade', __classPrivateFieldGet(this, _PondSocket_instances, "m", _PondSocket_handleUpgrade).bind(this));
235
+ __classPrivateFieldGet(this, _PondSocket_server, "f").on('upgrade', __classPrivateFieldGet(this, _PondSocket_upgradeHandler, "f"));
162
236
  }, _PondSocket_getCookies = function _PondSocket_getCookies(headers) {
163
237
  const cookieHeader = headers.cookie;
164
238
  if (!cookieHeader) {
@@ -173,7 +247,12 @@ _PondSocket_server = new WeakMap(), _PondSocket_exclusiveServer = new WeakMap(),
173
247
  }
174
248
  const name = trimmed.slice(0, eqIndex);
175
249
  const value = trimmed.slice(eqIndex + 1);
176
- cookies[name] = decodeURIComponent(value);
250
+ try {
251
+ cookies[name] = decodeURIComponent(value);
252
+ }
253
+ catch (_a) {
254
+ cookies[name] = value;
255
+ }
177
256
  return cookies;
178
257
  }, {});
179
258
  };
@@ -14,6 +14,7 @@ export interface RedisDistributedBackendOptions {
14
14
  onError?: (error: Error) => void;
15
15
  }
16
16
  export interface PondSocketOptions {
17
+ closeHttpServerOnShutdown?: boolean;
17
18
  server?: HTTPServer;
18
19
  socketServer?: WebSocketServer;
19
20
  exclusiveServer?: boolean;
@@ -1,4 +1,4 @@
1
- import { AnyPondSchema, AssignsOf, EventsOf, EventPayload, PresenceOf, UserData, UserAssigns, UserPresences } from '@eleven-am/pondsocket-common';
1
+ import { AnyPondSchema, AssignsOf, EventsOf, EventPayload, PresenceOf, RouteParamsArguments, UserData, UserAssigns, UserPresences } from '@eleven-am/pondsocket-common';
2
2
  import { ChannelEngine } from '../engines/channelEngine';
3
3
  export declare class Channel<Schema extends AnyPondSchema = AnyPondSchema> {
4
4
  #private;
@@ -6,7 +6,7 @@ export declare class Channel<Schema extends AnyPondSchema = AnyPondSchema> {
6
6
  /**
7
7
  * Gets a user's data
8
8
  */
9
- getUserData(userId: string): UserData<PresenceOf<Schema>, AssignsOf<Schema>> | null;
9
+ getUserData(userId: string): UserData<PresenceOf<Schema>, AssignsOf<Schema>>;
10
10
  /**
11
11
  * Gets all presence data
12
12
  */
@@ -18,15 +18,15 @@ export declare class Channel<Schema extends AnyPondSchema = AnyPondSchema> {
18
18
  /**
19
19
  * Broadcasts a message to all users
20
20
  */
21
- broadcast<Event extends Extract<keyof EventsOf<Schema>, string>>(event: Event, payload: EventPayload<EventsOf<Schema>, Event>): this;
21
+ broadcast<Event extends Extract<keyof EventsOf<Schema>, string>>(event: Event, payload: EventPayload<EventsOf<Schema>, Event>, ...args: RouteParamsArguments<Event>): this;
22
22
  /**
23
23
  * Broadcasts a message from a specific user to all others
24
24
  */
25
- broadcastFrom<Event extends Extract<keyof EventsOf<Schema>, string>>(userId: string, event: Event, payload: EventPayload<EventsOf<Schema>, Event>): this;
25
+ broadcastFrom<Event extends Extract<keyof EventsOf<Schema>, string>>(userId: string, event: Event, payload: EventPayload<EventsOf<Schema>, Event>, ...args: RouteParamsArguments<Event>): this;
26
26
  /**
27
27
  * Broadcasts a message to specific users
28
28
  */
29
- broadcastTo<Event extends Extract<keyof EventsOf<Schema>, string>>(userIds: string | string[], event: Event, payload: EventPayload<EventsOf<Schema>, Event>): this;
29
+ broadcastTo<Event extends Extract<keyof EventsOf<Schema>, string>>(userIds: string | string[], event: Event, payload: EventPayload<EventsOf<Schema>, Event>, ...args: RouteParamsArguments<Event>): this;
30
30
  /**
31
31
  * Kicks a user from the channel
32
32
  */
@@ -40,23 +40,26 @@ class Channel {
40
40
  /**
41
41
  * Broadcasts a message to all users
42
42
  */
43
- broadcast(event, payload) {
44
- __classPrivateFieldGet(this, _Channel_engine, "f").sendMessage(pondsocket_common_1.SystemSender.CHANNEL, pondsocket_common_1.ChannelReceiver.ALL_USERS, pondsocket_common_1.ServerActions.BROADCAST, event, payload);
43
+ broadcast(event, payload, ...args) {
44
+ var _a;
45
+ __classPrivateFieldGet(this, _Channel_engine, "f").sendMessage(pondsocket_common_1.SystemSender.CHANNEL, pondsocket_common_1.ChannelReceiver.ALL_USERS, pondsocket_common_1.ServerActions.BROADCAST, (0, pondsocket_common_1.buildPondRoute)(event, (_a = args[0]) !== null && _a !== void 0 ? _a : {}), payload);
45
46
  return this;
46
47
  }
47
48
  /**
48
49
  * Broadcasts a message from a specific user to all others
49
50
  */
50
- broadcastFrom(userId, event, payload) {
51
- __classPrivateFieldGet(this, _Channel_engine, "f").sendMessage(userId, pondsocket_common_1.ChannelReceiver.ALL_EXCEPT_SENDER, pondsocket_common_1.ServerActions.BROADCAST, event, payload);
51
+ broadcastFrom(userId, event, payload, ...args) {
52
+ var _a;
53
+ __classPrivateFieldGet(this, _Channel_engine, "f").sendMessage(userId, pondsocket_common_1.ChannelReceiver.ALL_EXCEPT_SENDER, pondsocket_common_1.ServerActions.BROADCAST, (0, pondsocket_common_1.buildPondRoute)(event, (_a = args[0]) !== null && _a !== void 0 ? _a : {}), payload);
52
54
  return this;
53
55
  }
54
56
  /**
55
57
  * Broadcasts a message to specific users
56
58
  */
57
- broadcastTo(userIds, event, payload) {
59
+ broadcastTo(userIds, event, payload, ...args) {
60
+ var _a;
58
61
  const users = Array.isArray(userIds) ? userIds : [userIds];
59
- __classPrivateFieldGet(this, _Channel_engine, "f").sendMessage(pondsocket_common_1.SystemSender.CHANNEL, users, pondsocket_common_1.ServerActions.BROADCAST, event, payload);
62
+ __classPrivateFieldGet(this, _Channel_engine, "f").sendMessage(pondsocket_common_1.SystemSender.CHANNEL, users, pondsocket_common_1.ServerActions.BROADCAST, (0, pondsocket_common_1.buildPondRoute)(event, (_a = args[0]) !== null && _a !== void 0 ? _a : {}), payload);
60
63
  return this;
61
64
  }
62
65
  /**
@@ -1,10 +1,12 @@
1
- import { AnyPondSchema, PondPath } from '@eleven-am/pondsocket-common';
1
+ import { AnyPondChannelDefinition, AnyPondSchema, PathOf, PondPath, SchemaOf } from '@eleven-am/pondsocket-common';
2
+ import { PondChannel } from './pondChannel';
2
3
  import { AuthorizationHandler } from '../abstracts/types';
3
4
  import { EndpointEngine } from '../engines/endpointEngine';
4
5
  export declare class Endpoint {
5
6
  #private;
6
7
  constructor(engine: EndpointEngine);
7
- createChannel<Path extends string, Schema extends AnyPondSchema = AnyPondSchema>(path: PondPath<Path>, handler: AuthorizationHandler<Path, Schema>): import("./pondChannel").PondChannel<Schema>;
8
+ createChannel<Definition extends AnyPondChannelDefinition>(definition: Definition, handler: AuthorizationHandler<PathOf<Definition>, SchemaOf<Definition>>): PondChannel<SchemaOf<Definition>>;
9
+ createChannel<Path extends string, Schema extends AnyPondSchema = AnyPondSchema>(path: PondPath<Path>, handler: AuthorizationHandler<Path, Schema>): PondChannel<Schema>;
8
10
  closeConnection(clientIds: string | string[]): void;
9
11
  getClients(): import("ws").WebSocket[];
10
12
  }
@@ -1,4 +1,4 @@
1
- import { AnyPondSchema, EventPayload, EventsOf, PondPath } from '@eleven-am/pondsocket-common';
1
+ import { AnyPondSchema, EventPayload, EventsOf, PondPath, RouteParamsArguments } from '@eleven-am/pondsocket-common';
2
2
  import { Channel } from './channel';
3
3
  import { EventHandler, LeaveCallback, OutgoingEventHandler } from '../abstracts/types';
4
4
  import { LobbyEngine } from '../engines/lobbyEngine';
@@ -9,7 +9,7 @@ export declare class PondChannel<Schema extends AnyPondSchema = AnyPondSchema> {
9
9
  onLeave(callback: LeaveCallback): PondChannel<Schema>;
10
10
  handleOutgoingEvent<Event extends Extract<keyof EventsOf<Schema>, string>>(event: PondPath<Event>, handler: OutgoingEventHandler<Event, Schema, Event>): this;
11
11
  getChannel(channelName: string): Channel<Schema> | null;
12
- broadcast<Event extends Extract<keyof EventsOf<Schema>, string>>(channelName: string, event: Event, payload: EventPayload<EventsOf<Schema>, Event>): PondChannel<Schema>;
13
- broadcastFrom<Event extends Extract<keyof EventsOf<Schema>, string>>(channelName: string, userId: string, event: Event, payload: EventPayload<EventsOf<Schema>, Event>): PondChannel<Schema>;
14
- broadcastTo<Event extends Extract<keyof EventsOf<Schema>, string>>(channelName: string, userIds: string | string[], event: Event, payload: EventPayload<EventsOf<Schema>, Event>): PondChannel<Schema>;
12
+ broadcast<Event extends Extract<keyof EventsOf<Schema>, string>>(channelName: string, event: Event, payload: EventPayload<EventsOf<Schema>, Event>, ...args: RouteParamsArguments<Event>): PondChannel<Schema>;
13
+ broadcastFrom<Event extends Extract<keyof EventsOf<Schema>, string>>(channelName: string, userId: string, event: Event, payload: EventPayload<EventsOf<Schema>, Event>, ...args: RouteParamsArguments<Event>): PondChannel<Schema>;
14
+ broadcastTo<Event extends Extract<keyof EventsOf<Schema>, string>>(channelName: string, userIds: string | string[], event: Event, payload: EventPayload<EventsOf<Schema>, Event>, ...args: RouteParamsArguments<Event>): PondChannel<Schema>;
15
15
  }
@@ -40,16 +40,16 @@ class PondChannel {
40
40
  return null;
41
41
  }
42
42
  }
43
- broadcast(channelName, event, payload) {
44
- __classPrivateFieldGet(this, _PondChannel_instances, "m", _PondChannel_getChannel).call(this, channelName).broadcast(event, payload);
43
+ broadcast(channelName, event, payload, ...args) {
44
+ __classPrivateFieldGet(this, _PondChannel_instances, "m", _PondChannel_getChannel).call(this, channelName).broadcast(event, payload, ...args);
45
45
  return this;
46
46
  }
47
- broadcastFrom(channelName, userId, event, payload) {
48
- __classPrivateFieldGet(this, _PondChannel_instances, "m", _PondChannel_getChannel).call(this, channelName).broadcastFrom(userId, event, payload);
47
+ broadcastFrom(channelName, userId, event, payload, ...args) {
48
+ __classPrivateFieldGet(this, _PondChannel_instances, "m", _PondChannel_getChannel).call(this, channelName).broadcastFrom(userId, event, payload, ...args);
49
49
  return this;
50
50
  }
51
- broadcastTo(channelName, userIds, event, payload) {
52
- __classPrivateFieldGet(this, _PondChannel_instances, "m", _PondChannel_getChannel).call(this, channelName).broadcastTo(userIds, event, payload);
51
+ broadcastTo(channelName, userIds, event, payload, ...args) {
52
+ __classPrivateFieldGet(this, _PondChannel_instances, "m", _PondChannel_getChannel).call(this, channelName).broadcastTo(userIds, event, payload, ...args);
53
53
  return this;
54
54
  }
55
55
  }