@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
@@ -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;
@@ -100,20 +101,19 @@ export interface EvictUser extends DistributedMessage {
100
101
  export interface UserRemove extends DistributedMessage {
101
102
  type: DistributedMessageType.USER_REMOVE;
102
103
  userId: string;
103
- reason: string;
104
104
  }
105
105
  export interface UserGetRequest extends DistributedMessage {
106
106
  type: DistributedMessageType.USER_GET_REQUEST;
107
107
  userId: string;
108
- lookupRequestId: string;
108
+ requestId: string;
109
+ fromNode: string;
109
110
  }
110
111
  export interface UserGetResponse extends DistributedMessage {
111
112
  type: DistributedMessageType.USER_GET_RESPONSE;
112
- lookupRequestId: string;
113
113
  userId: string;
114
- found: boolean;
115
- assigns?: PondAssigns;
116
- presence?: PondPresence;
114
+ requestId: string;
115
+ assigns: PondAssigns;
116
+ presence: PondPresence;
117
117
  }
118
118
  export interface NodeHeartbeat extends DistributedMessage {
119
119
  type: DistributedMessageType.NODE_HEARTBEAT;
@@ -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
  */
@@ -51,4 +51,12 @@ export declare class Channel<Schema extends AnyPondSchema = AnyPondSchema> {
51
51
  * Updates a user's assigns
52
52
  */
53
53
  updateAssigns(userId: string, assigns: Partial<AssignsOf<Schema>>): this;
54
+ /**
55
+ * Resolves a user's data from any node in the distributed cluster
56
+ */
57
+ getUserAcrossNodes(userId: string, timeoutMs?: number): Promise<UserData<PresenceOf<Schema>, AssignsOf<Schema>> | null>;
58
+ /**
59
+ * Requests removal of a user across all nodes in the distributed cluster
60
+ */
61
+ requestUserRemoval(userId: string): this;
54
62
  }
@@ -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
  /**
@@ -101,6 +104,19 @@ class Channel {
101
104
  __classPrivateFieldGet(this, _Channel_engine, "f").updateAssigns(userId, assigns);
102
105
  return this;
103
106
  }
107
+ /**
108
+ * Resolves a user's data from any node in the distributed cluster
109
+ */
110
+ getUserAcrossNodes(userId, timeoutMs) {
111
+ return __classPrivateFieldGet(this, _Channel_engine, "f").getUserAcrossNodes(userId, timeoutMs);
112
+ }
113
+ /**
114
+ * Requests removal of a user across all nodes in the distributed cluster
115
+ */
116
+ requestUserRemoval(userId) {
117
+ __classPrivateFieldGet(this, _Channel_engine, "f").requestUserRemoval(userId);
118
+ return this;
119
+ }
104
120
  }
105
121
  exports.Channel = Channel;
106
122
  _Channel_engine = new WeakMap();
@@ -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
  }
package/package.json CHANGED
@@ -1,80 +1,65 @@
1
1
  {
2
2
  "name": "@eleven-am/pondsocket",
3
- "version": "0.1.217",
4
- "description": "PondSocket is a fast simple socket server",
3
+ "version": "0.1.219",
4
+ "description": "Typed WebSocket and SSE server with presence and distributed messaging.",
5
5
  "keywords": [
6
- "socket",
7
- "server",
8
- "ws",
6
+ "pondsocket",
9
7
  "websocket",
10
- "pubsub",
11
- "presence",
8
+ "sse",
12
9
  "realtime",
13
- "realtime server"
10
+ "presence",
11
+ "pubsub",
12
+ "redis"
14
13
  ],
15
- "publishConfig": {
16
- "access": "public"
17
- },
18
- "scripts": {
19
- "test": "jest --coverage --verbose --forceExit --detectOpenHandles --runInBand --bail",
20
- "build": "rimraf dist && tsc --project tsconfig.build.json && rm -rf dist/tests",
21
- "lint": "eslint --ext .ts src",
22
- "lint:fix": "eslint --fix --ext .ts src",
23
- "copy": "cp package.json dist && cp README.md dist && cp LICENSE dist",
24
- "push": "npm version patch && npm run copy && cd dist && npm publish && cd ..",
25
- "pipeline": "npm run lint:fix && npm run lint && npm run test && npm run build && npm run push"
26
- },
27
14
  "author": "Roy OSSAI",
28
15
  "license": "GPL-3.0",
29
- "main": "./index.js",
30
- "types": "./index.d.ts",
16
+ "homepage": "https://github.com/eleven-am/pondsocket#readme",
17
+ "bugs": {
18
+ "url": "https://github.com/eleven-am/pondsocket/issues"
19
+ },
20
+ "repository": {
21
+ "type": "git",
22
+ "url": "git+https://github.com/eleven-am/pondsocket.git",
23
+ "directory": "javascript/core"
24
+ },
25
+ "engines": {
26
+ "node": ">=20"
27
+ },
28
+ "type": "commonjs",
29
+ "main": "./dist/index.js",
30
+ "types": "./dist/index.d.ts",
31
31
  "exports": {
32
32
  ".": {
33
- "types": "./index.d.ts",
34
- "default": "./index.js"
33
+ "types": "./dist/index.d.ts",
34
+ "require": "./dist/index.js",
35
+ "default": "./dist/index.js"
35
36
  },
36
37
  "./types": {
37
- "types": "./index.d.ts",
38
- "default": "./index.js"
38
+ "types": "./dist/index.d.ts",
39
+ "require": "./dist/index.js",
40
+ "default": "./dist/index.js"
39
41
  }
40
42
  },
41
- "repository": {
42
- "type": "git",
43
- "url": "git+https://github.com/Eleven-am/pondSocket.git"
43
+ "files": [
44
+ "dist"
45
+ ],
46
+ "publishConfig": {
47
+ "access": "public",
48
+ "registry": "https://registry.npmjs.org"
44
49
  },
45
- "dependencies": {
46
- "@eleven-am/pondsocket-common": "^0.0.39",
47
- "@types/node": "^25.3.3",
48
- "@types/ws": "^8.18.1",
49
- "redis": "^5.12.1",
50
- "ws": "^8.20.1"
50
+ "scripts": {
51
+ "clean": "rimraf dist",
52
+ "build": "npm run clean && tsc --project tsconfig.build.json",
53
+ "test": "jest --coverage --verbose --detectOpenHandles --runInBand --bail",
54
+ "lint": "eslint src --max-warnings=0",
55
+ "prepack": "npm run build"
51
56
  },
52
- "devDependencies": {
53
- "@eslint/compat": "^1.4.0",
54
- "@eslint/eslintrc": "^3.3.4",
55
- "@eslint/js": "^9.39.4",
56
- "@stylistic/eslint-plugin-ts": "^4.4.1",
57
- "@types/jest": "^30.0.0",
58
- "@types/node": "^25.3.3",
57
+ "dependencies": {
58
+ "@eleven-am/pondsocket-common": "^0.0.41",
59
+ "@types/node": "^20.19.43",
59
60
  "@types/ws": "^8.18.1",
60
- "@typescript-eslint/eslint-plugin": "^8.59.4",
61
- "@typescript-eslint/parser": "^8.59.4",
62
- "eslint": "^9.39.4",
63
- "eslint-config-prettier": "^10.1.8",
64
- "eslint-import-resolver-node": "^0.3.9",
65
- "eslint-plugin-file-progress": "^3.0.2",
66
- "eslint-plugin-import": "^2.32.0",
67
- "eslint-plugin-prettier": "^5.5.5",
68
- "globals": "^16.4.0",
69
- "jest": "^30.2.0",
70
- "prettier": "^3.8.3",
71
- "source-map-support": "^0.5.21",
72
- "supertest": "^7.2.2",
73
- "ts-jest": "^29.4.11",
74
- "ts-loader": "^9.5.7",
75
- "ts-node": "^10.9.2",
76
- "tsconfig-paths": "^4.2.0",
77
- "typescript": "^5.9.3"
61
+ "redis": "^6.1.0",
62
+ "ws": "^8.21.0"
78
63
  },
79
64
  "jest": {
80
65
  "moduleFileExtensions": [
@@ -85,7 +70,7 @@
85
70
  "rootDir": "src",
86
71
  "testRegex": ".*\\.test\\.ts$",
87
72
  "transform": {
88
- "^.+\\.(t|j)s$": [
73
+ "^.+\\.ts$": [
89
74
  "ts-jest",
90
75
  {
91
76
  "diagnostics": false
@@ -93,15 +78,14 @@
93
78
  ]
94
79
  },
95
80
  "collectCoverageFrom": [
96
- "**/*.(t|j)s",
81
+ "**/*.ts",
97
82
  "!**/*.test.ts",
98
83
  "!**/*.d.ts",
99
84
  "!**/index.ts",
100
85
  "!**/tests/**",
101
- "!**/types.d.ts",
102
86
  "!**/abstracts/distributor.ts"
103
87
  ],
104
- "coverageDirectory": "../coverage",
88
+ "coverageDirectory": "../coverage/core",
105
89
  "testEnvironment": "node",
106
90
  "moduleNameMapper": {
107
91
  "^@eleven-am/pondsocket-common$": "<rootDir>/../../comnon/dist"
@@ -1,28 +0,0 @@
1
- import { ChannelReceivers, AnyPondSchema, Event, EventParams, EventPayload, EventsOf, PondObject } from '@eleven-am/pondsocket-common';
2
- import { BaseContext } from './baseContext';
3
- import { ChannelEngine } from '../engines/channelEngine';
4
- export declare class OutgoingContext<Path extends string, Schema extends AnyPondSchema = AnyPondSchema, EventName extends Extract<keyof EventsOf<Schema>, string> = Extract<keyof EventsOf<Schema>, string>> extends BaseContext<Path, Schema, EventName, EventPayload<EventsOf<Schema>, EventName>> {
5
- #private;
6
- constructor(event: Event, params: EventParams<Path>, engine: ChannelEngine, userid: string);
7
- get payload(): EventPayload<EventsOf<Schema>, EventName>;
8
- /**
9
- * Blocks the outgoing context, preventing further processing of the event.
10
- */
11
- block(): this;
12
- /**
13
- * Checks if the outgoing context is blocked.
14
- * @returns {boolean} - True if blocked, false otherwise.
15
- */
16
- isBlocked(): boolean;
17
- /**
18
- * Transforms the outgoing context with a new payload.
19
- * @param payload - The new payload to set for the context.
20
- */
21
- transform(payload: EventPayload<EventsOf<Schema>, EventName>): this;
22
- /**
23
- * Updates the parameters of the outgoing context.
24
- * @param params - The new parameters to set for the context.
25
- */
26
- updateParams(params: EventParams<Path>): void;
27
- protected _sendMessageToRecipients(_recipient: ChannelReceivers, _event: string, _payload: PondObject): void;
28
- }