@mesh-kit/server 2.0.0 → 2.0.1
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.
- package/dist/index.d.mts +1129 -0
- package/dist/index.d.ts +1129 -0
- package/dist/index.js +56 -0
- package/dist/index.mjs +56 -0
- package/package.json +4 -1
- package/tsconfig.json +0 -19
- package/tsup.config.ts +0 -11
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,1129 @@
|
|
|
1
|
+
import { ServerOptions, WebSocket, WebSocketServer } from 'ws';
|
|
2
|
+
export { ServerOptions } from 'ws';
|
|
3
|
+
import { LogLevel, Status, Command } from '@mesh-kit/shared';
|
|
4
|
+
import { EventEmitter } from 'node:events';
|
|
5
|
+
import { IncomingMessage } from 'node:http';
|
|
6
|
+
import Redis, { RedisOptions, Redis as Redis$1 } from 'ioredis';
|
|
7
|
+
import { Operation } from 'fast-json-patch';
|
|
8
|
+
import { EventEmitter as EventEmitter$1 } from 'events';
|
|
9
|
+
|
|
10
|
+
declare class Latency {
|
|
11
|
+
start: number;
|
|
12
|
+
end: number;
|
|
13
|
+
ms: number;
|
|
14
|
+
interval?: ReturnType<typeof setTimeout>;
|
|
15
|
+
onRequest(): void;
|
|
16
|
+
onResponse(): void;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
declare class Ping {
|
|
20
|
+
interval?: ReturnType<typeof setTimeout>;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
declare class MeshContext<T = any> {
|
|
24
|
+
server: MeshServer;
|
|
25
|
+
command: string;
|
|
26
|
+
connection: Connection;
|
|
27
|
+
payload: T;
|
|
28
|
+
constructor(server: MeshServer, command: string, connection: Connection, payload: T);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
interface PersistenceAdapter {
|
|
32
|
+
initialize(): Promise<void>;
|
|
33
|
+
storeMessages(messages: PersistedMessage[]): Promise<void>;
|
|
34
|
+
getMessages(channel: string, since?: string | number, limit?: number): Promise<PersistedMessage[]>;
|
|
35
|
+
storeRecords?(records: PersistedRecord[]): Promise<void>;
|
|
36
|
+
getRecords?(pattern: string): Promise<PersistedRecord[]>;
|
|
37
|
+
close(): Promise<void>;
|
|
38
|
+
}
|
|
39
|
+
interface PersistedMessage {
|
|
40
|
+
id: string;
|
|
41
|
+
channel: string;
|
|
42
|
+
message: string;
|
|
43
|
+
instanceId: string;
|
|
44
|
+
timestamp: number;
|
|
45
|
+
metadata?: Record<string, any>;
|
|
46
|
+
}
|
|
47
|
+
interface ChannelPersistenceOptions {
|
|
48
|
+
/**
|
|
49
|
+
* Maximum number of messages to retain per channel
|
|
50
|
+
* @default 50
|
|
51
|
+
*/
|
|
52
|
+
historyLimit?: number;
|
|
53
|
+
/**
|
|
54
|
+
* Function to filter messages for persistence
|
|
55
|
+
* Return false to skip persistence for a specific message
|
|
56
|
+
*/
|
|
57
|
+
filter?: (message: string, channel: string) => boolean;
|
|
58
|
+
/**
|
|
59
|
+
* Optional adapter override for this pattern
|
|
60
|
+
*/
|
|
61
|
+
adapter?: PersistenceAdapter;
|
|
62
|
+
/**
|
|
63
|
+
* How often (in ms) to flush buffered messages to the database
|
|
64
|
+
* @default 500
|
|
65
|
+
*/
|
|
66
|
+
flushInterval?: number;
|
|
67
|
+
/**
|
|
68
|
+
* Maximum number of messages to hold in memory per channel
|
|
69
|
+
* If this limit is reached, the buffer is flushed immediately
|
|
70
|
+
* @default 100
|
|
71
|
+
*/
|
|
72
|
+
maxBufferSize?: number;
|
|
73
|
+
}
|
|
74
|
+
interface RecordPersistenceOptions {
|
|
75
|
+
/**
|
|
76
|
+
* Optional adapter override for this pattern
|
|
77
|
+
*/
|
|
78
|
+
adapter?: PersistenceAdapter;
|
|
79
|
+
/**
|
|
80
|
+
* How often (in ms) to flush buffered records to the database
|
|
81
|
+
* @default 500
|
|
82
|
+
*/
|
|
83
|
+
flushInterval?: number;
|
|
84
|
+
/**
|
|
85
|
+
* Maximum number of records to hold in memory before flushing
|
|
86
|
+
* If this limit is reached, the buffer is flushed immediately
|
|
87
|
+
* @default 100
|
|
88
|
+
*/
|
|
89
|
+
maxBufferSize?: number;
|
|
90
|
+
}
|
|
91
|
+
interface PersistedRecord {
|
|
92
|
+
recordId: string;
|
|
93
|
+
version: number;
|
|
94
|
+
value: string;
|
|
95
|
+
timestamp: number;
|
|
96
|
+
}
|
|
97
|
+
interface PersistenceAdapterOptions {
|
|
98
|
+
/**
|
|
99
|
+
* Database file path for file-based adapters
|
|
100
|
+
* @default ":memory:"
|
|
101
|
+
*/
|
|
102
|
+
filename?: string;
|
|
103
|
+
}
|
|
104
|
+
interface PostgreSQLAdapterOptions extends PersistenceAdapterOptions {
|
|
105
|
+
connectionString?: string;
|
|
106
|
+
host?: string;
|
|
107
|
+
port?: number;
|
|
108
|
+
database?: string;
|
|
109
|
+
user?: string;
|
|
110
|
+
password?: string;
|
|
111
|
+
ssl?: boolean;
|
|
112
|
+
max?: number;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
type SocketMiddleware = (context: MeshContext<any>) => any | Promise<any>;
|
|
116
|
+
interface MeshServerOptions extends ServerOptions {
|
|
117
|
+
/**
|
|
118
|
+
* The interval at which to send ping messages to the client.
|
|
119
|
+
*
|
|
120
|
+
* @default 30000
|
|
121
|
+
*/
|
|
122
|
+
pingInterval?: number;
|
|
123
|
+
/**
|
|
124
|
+
* The interval at which to send both latency requests and updates to the client.
|
|
125
|
+
*
|
|
126
|
+
* @default 5000
|
|
127
|
+
*/
|
|
128
|
+
latencyInterval?: number;
|
|
129
|
+
redisOptions: RedisOptions;
|
|
130
|
+
/**
|
|
131
|
+
* Whether to enable Redis keyspace notifications for presence expiration.
|
|
132
|
+
* When enabled, connections will be automatically marked as offline when their presence TTL expires.
|
|
133
|
+
*
|
|
134
|
+
* @default true
|
|
135
|
+
*/
|
|
136
|
+
enablePresenceExpirationEvents?: boolean;
|
|
137
|
+
/**
|
|
138
|
+
* The maximum number of consecutive ping intervals the server will wait
|
|
139
|
+
* for a pong response before considering the client disconnected.
|
|
140
|
+
* A value of 1 means the client must respond within roughly 2 * pingInterval
|
|
141
|
+
* before being disconnected. Setting it to 0 is not recommended as it will
|
|
142
|
+
* immediately disconnect the client if it doesn't respond to the first ping in
|
|
143
|
+
* exactly `pingInterval` milliseconds, which doesn't provide wiggle room for
|
|
144
|
+
* network latency.
|
|
145
|
+
*
|
|
146
|
+
* @see pingInterval
|
|
147
|
+
* @default 1
|
|
148
|
+
*/
|
|
149
|
+
maxMissedPongs?: number;
|
|
150
|
+
/**
|
|
151
|
+
* The log level for server-side logs.
|
|
152
|
+
* Controls which messages are displayed in the console.
|
|
153
|
+
*
|
|
154
|
+
* @default LogLevel.ERROR
|
|
155
|
+
*/
|
|
156
|
+
logLevel?: LogLevel;
|
|
157
|
+
/**
|
|
158
|
+
* Options for the persistence layer.
|
|
159
|
+
* By default, persistence uses an in-memory SQLite database.
|
|
160
|
+
* To persist data across restarts, specify a file path.
|
|
161
|
+
*
|
|
162
|
+
* @example
|
|
163
|
+
* ```
|
|
164
|
+
* persistenceOptions: {
|
|
165
|
+
* filename: "./data/channels.db"
|
|
166
|
+
* }
|
|
167
|
+
* ```
|
|
168
|
+
*/
|
|
169
|
+
persistenceOptions?: PersistenceAdapterOptions | PostgreSQLAdapterOptions;
|
|
170
|
+
/**
|
|
171
|
+
* Adapter type for persistence layer.
|
|
172
|
+
* @default "sqlite"
|
|
173
|
+
*/
|
|
174
|
+
persistenceAdapter?: "sqlite" | "postgres";
|
|
175
|
+
}
|
|
176
|
+
type ChannelPattern$1 = string | RegExp;
|
|
177
|
+
|
|
178
|
+
declare class Connection extends EventEmitter {
|
|
179
|
+
id: string;
|
|
180
|
+
socket: WebSocket;
|
|
181
|
+
alive: boolean;
|
|
182
|
+
missedPongs: number;
|
|
183
|
+
latency: Latency;
|
|
184
|
+
ping: Ping;
|
|
185
|
+
remoteAddress: string;
|
|
186
|
+
connectionOptions: MeshServerOptions;
|
|
187
|
+
status: Status;
|
|
188
|
+
server: MeshServer;
|
|
189
|
+
constructor(socket: WebSocket, req: IncomingMessage, options: MeshServerOptions, server: MeshServer);
|
|
190
|
+
get isDead(): boolean;
|
|
191
|
+
private startIntervals;
|
|
192
|
+
stopIntervals(): void;
|
|
193
|
+
private applyListeners;
|
|
194
|
+
send(cmd: Command): boolean;
|
|
195
|
+
close(): Promise<boolean>;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
declare class RoomManager {
|
|
199
|
+
private redis;
|
|
200
|
+
constructor(options: {
|
|
201
|
+
redis: Redis;
|
|
202
|
+
});
|
|
203
|
+
private roomKey;
|
|
204
|
+
private connectionsRoomKey;
|
|
205
|
+
private roomMetadataKey;
|
|
206
|
+
/**
|
|
207
|
+
* Retrieves all connection IDs associated with the specified room.
|
|
208
|
+
*
|
|
209
|
+
* @param {string} roomName - The name of the room for which to fetch connection IDs.
|
|
210
|
+
* @returns {Promise<string[]>} A promise that resolves to an array of connection IDs in the room.
|
|
211
|
+
* @throws {Error} If there is an issue communicating with Redis or retrieving the data, the promise will be rejected with an error.
|
|
212
|
+
*/
|
|
213
|
+
getRoomConnectionIds(roomName: string): Promise<string[]>;
|
|
214
|
+
/**
|
|
215
|
+
* Checks whether a given connection (by object or ID) is a member of a specified room.
|
|
216
|
+
*
|
|
217
|
+
* @param {string} roomName - The name of the room to check for membership.
|
|
218
|
+
* @param {Connection | string} connection - The connection object or connection ID to check.
|
|
219
|
+
* @returns {Promise<boolean>} A promise that resolves to true if the connection is in the room, false otherwise.
|
|
220
|
+
* @throws {Error} If there is an issue communicating with Redis or processing the request, the promise may be rejected with an error.
|
|
221
|
+
*/
|
|
222
|
+
connectionIsInRoom(roomName: string, connection: Connection | string): Promise<boolean>;
|
|
223
|
+
/**
|
|
224
|
+
* Adds a connection to a specified room, associating the connection ID with the room name
|
|
225
|
+
* in Redis. Supports both `Connection` objects and connection IDs as strings.
|
|
226
|
+
*
|
|
227
|
+
* @param {string} roomName - The name of the room to add the connection to.
|
|
228
|
+
* @param {Connection | string} connection - The connection object or connection ID to add to the room.
|
|
229
|
+
* @returns {Promise<void>} A promise that resolves when the operation is complete.
|
|
230
|
+
* @throws {Error} If an error occurs while updating Redis, the promise will be rejected with the error.
|
|
231
|
+
*/
|
|
232
|
+
addToRoom(roomName: string, connection: Connection | string): Promise<void>;
|
|
233
|
+
/**
|
|
234
|
+
* Retrieves a list of rooms that the specified connection is currently a member of.
|
|
235
|
+
*
|
|
236
|
+
* @param {Connection | string} connection - The connection object or connection ID for which to retrieve room memberships.
|
|
237
|
+
* @returns {Promise<string[]>} A promise that resolves to an array of room names associated with the connection.
|
|
238
|
+
* @throws {Error} If the underlying Redis operation fails, the promise will be rejected with an error.
|
|
239
|
+
*/
|
|
240
|
+
getRoomsForConnection(connection: Connection | string): Promise<string[]>;
|
|
241
|
+
/**
|
|
242
|
+
* Retrieves all room names from Redis.
|
|
243
|
+
*
|
|
244
|
+
* @returns {Promise<string[]>} A promise that resolves to an array of all room names.
|
|
245
|
+
* @throws {Error} If there is an issue communicating with Redis, the promise will be rejected with an error.
|
|
246
|
+
*/
|
|
247
|
+
getAllRooms(): Promise<string[]>;
|
|
248
|
+
/**
|
|
249
|
+
* Removes a connection from a specified room and updates Redis accordingly.
|
|
250
|
+
* Accepts either a Connection object or a string representing the connection ID.
|
|
251
|
+
* Updates both the room's set of connections and the connection's set of rooms in Redis.
|
|
252
|
+
*
|
|
253
|
+
* @param {string} roomName - The name of the room from which to remove the connection.
|
|
254
|
+
* @param {Connection | string} connection - The connection to be removed, specified as either a Connection object or a connection ID string.
|
|
255
|
+
* @returns {Promise<void>} A promise that resolves when the removal is complete.
|
|
256
|
+
* @throws {Error} If there is an error executing the Redis pipeline, the promise will be rejected with the error.
|
|
257
|
+
*/
|
|
258
|
+
removeFromRoom(roomName: string, connection: Connection | string): Promise<void>;
|
|
259
|
+
/**
|
|
260
|
+
* Removes the specified connection from all rooms it is a member of and deletes its room membership record.
|
|
261
|
+
*
|
|
262
|
+
* @param {Connection | string} connection - The connection object or its unique identifier to be removed from all rooms.
|
|
263
|
+
* @returns {Promise<void>} A promise that resolves once the removal from all rooms is complete.
|
|
264
|
+
* @throws {Error} If an error occurs during Redis operations, the promise will be rejected with the error.
|
|
265
|
+
*/
|
|
266
|
+
removeFromAllRooms(connection: Connection | string): Promise<void>;
|
|
267
|
+
/**
|
|
268
|
+
* Removes all connections from the specified room but preserves room metadata.
|
|
269
|
+
* This clears the room occupants without destroying the room's configuration.
|
|
270
|
+
*
|
|
271
|
+
* @param {string} roomName - The name of the room to be cleared of occupants.
|
|
272
|
+
* @returns {Promise<void>} A promise that resolves when all occupants have been removed from the room.
|
|
273
|
+
* @throws {Error} If an error occurs while interacting with Redis, the promise will be rejected with the error.
|
|
274
|
+
*/
|
|
275
|
+
clearRoom(roomName: string): Promise<void>;
|
|
276
|
+
/**
|
|
277
|
+
* Completely deletes the specified room, removing all occupants and destroying
|
|
278
|
+
* all associated room metadata. This permanently removes the room from the system.
|
|
279
|
+
*
|
|
280
|
+
* @param {string} roomName - The name of the room to be completely deleted.
|
|
281
|
+
* @returns {Promise<void>} A promise that resolves when the room has been completely deleted.
|
|
282
|
+
* @throws {Error} If an error occurs while interacting with Redis, the promise will be rejected with the error.
|
|
283
|
+
*/
|
|
284
|
+
deleteRoom(roomName: string): Promise<void>;
|
|
285
|
+
/**
|
|
286
|
+
* Cleans up all Redis references for a given connection by removing the connection
|
|
287
|
+
* from all rooms it is associated with and deleting the connection's room key.
|
|
288
|
+
*
|
|
289
|
+
* @param {Connection} connection - The connection object whose references should be cleaned up.
|
|
290
|
+
* @returns {Promise<void>} A promise that resolves when the cleanup is complete.
|
|
291
|
+
* @throws {Error} If an error occurs while interacting with Redis, the promise will be rejected with the error.
|
|
292
|
+
*/
|
|
293
|
+
cleanupConnection(connection: Connection): Promise<void>;
|
|
294
|
+
/**
|
|
295
|
+
* Sets the metadata for a given room by storing the serialized metadata
|
|
296
|
+
* object in Redis under the room's metadata key.
|
|
297
|
+
*
|
|
298
|
+
* @param {string} roomName - The unique name of the room whose metadata is being set.
|
|
299
|
+
* @param {any} metadata - The metadata object to associate with the room, or partial metadata when using merge strategy.
|
|
300
|
+
* @param {{ strategy?: "replace" | "merge" | "deepMerge" }} [options] - Update options: strategy defaults to "replace" which replaces the entire metadata, "merge" merges with existing metadata properties, "deepMerge" recursively merges nested objects.
|
|
301
|
+
* @returns {Promise<void>} A promise that resolves when the metadata has been successfully set.
|
|
302
|
+
* @throws {Error} If an error occurs while storing metadata in Redis, the promise will be rejected with the error.
|
|
303
|
+
*/
|
|
304
|
+
setMetadata(roomName: string, metadata: any, options?: {
|
|
305
|
+
strategy?: "replace" | "merge" | "deepMerge";
|
|
306
|
+
}): Promise<void>;
|
|
307
|
+
/**
|
|
308
|
+
* Retrieves and parses metadata associated with the specified room from Redis storage.
|
|
309
|
+
*
|
|
310
|
+
* @param {string} roomName - The name of the room whose metadata is to be retrieved.
|
|
311
|
+
* @returns {Promise<any | null>} A promise that resolves to the parsed metadata object if found,
|
|
312
|
+
* or null if no metadata exists for the given room.
|
|
313
|
+
* @throws {SyntaxError} If the retrieved data is not valid JSON and cannot be parsed.
|
|
314
|
+
* @throws {Error} If there is an issue communicating with Redis.
|
|
315
|
+
*/
|
|
316
|
+
getMetadata(roomName: string): Promise<any | null>;
|
|
317
|
+
/**
|
|
318
|
+
* Retrieves and returns all room metadata stored in Redis.
|
|
319
|
+
* Fetches all keys matching the pattern "mesh:roommeta:*", retrieves their "data" fields,
|
|
320
|
+
* parses them as JSON, and returns an array of room objects with id and metadata.
|
|
321
|
+
*
|
|
322
|
+
* @returns {Promise<Array<{ id: string, metadata: any }>>} A promise that resolves to an array of room objects.
|
|
323
|
+
* @throws {SyntaxError} If the stored metadata cannot be parsed as JSON, an error is logged and the room is omitted from the result.
|
|
324
|
+
*/
|
|
325
|
+
getAllMetadata(): Promise<Array<{
|
|
326
|
+
id: string;
|
|
327
|
+
metadata: any;
|
|
328
|
+
}>>;
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
declare class ConnectionManager {
|
|
332
|
+
private redis;
|
|
333
|
+
private instanceId;
|
|
334
|
+
private localConnections;
|
|
335
|
+
private roomManager;
|
|
336
|
+
constructor(options: {
|
|
337
|
+
redis: Redis;
|
|
338
|
+
instanceId: string;
|
|
339
|
+
roomManager: RoomManager;
|
|
340
|
+
});
|
|
341
|
+
getLocalConnections(): Connection[];
|
|
342
|
+
getLocalConnection(id: string): Connection | null;
|
|
343
|
+
registerConnection(connection: Connection): Promise<void>;
|
|
344
|
+
private getInstanceConnectionsKey;
|
|
345
|
+
private deregisterConnection;
|
|
346
|
+
private getInstanceIdForConnection;
|
|
347
|
+
getInstanceIdsForConnections(connectionIds: string[]): Promise<{
|
|
348
|
+
[connectionId: string]: string | null;
|
|
349
|
+
}>;
|
|
350
|
+
getAllConnectionIds(): Promise<string[]>;
|
|
351
|
+
getLocalConnectionIds(): Promise<string[]>;
|
|
352
|
+
/**
|
|
353
|
+
* Sets metadata for a given connection in the Redis hash.
|
|
354
|
+
* Serializes the metadata as a JSON string and stores it under the connection's ID.
|
|
355
|
+
*
|
|
356
|
+
* @param {Connection} connection - The connection object whose metadata is being set.
|
|
357
|
+
* @param {any} metadata - The metadata to associate with the connection, or partial metadata when using merge strategy.
|
|
358
|
+
* @param {{ strategy?: "replace" | "merge" | "deepMerge" }} [options] - Update options: strategy defaults to "replace" which replaces the entire metadata, "merge" merges with existing metadata properties, "deepMerge" recursively merges nested objects.
|
|
359
|
+
* @returns {Promise<void>} A promise that resolves when the metadata has been successfully set.
|
|
360
|
+
* @throws {Error} If an error occurs while executing the Redis pipeline.
|
|
361
|
+
*/
|
|
362
|
+
setMetadata(connection: Connection, metadata: any, options?: {
|
|
363
|
+
strategy?: "replace" | "merge" | "deepMerge";
|
|
364
|
+
}): Promise<void>;
|
|
365
|
+
/**
|
|
366
|
+
* Retrieves and parses metadata for the given connection from Redis.
|
|
367
|
+
*
|
|
368
|
+
* @param {Connection} connection - The connection object whose metadata is to be retrieved.
|
|
369
|
+
* @returns {Promise<any|null>} A promise that resolves to the parsed metadata object if found, or null if no metadata exists.
|
|
370
|
+
* @throws {SyntaxError} If the stored metadata is not valid JSON and fails to parse.
|
|
371
|
+
* @throws {Error} If a Redis error occurs during retrieval.
|
|
372
|
+
*/
|
|
373
|
+
getMetadata(connection: Connection): Promise<any | null>;
|
|
374
|
+
/**
|
|
375
|
+
* Retrieves metadata for all available connections by fetching all connection IDs,
|
|
376
|
+
* obtaining their associated metadata, and parsing the metadata as JSON.
|
|
377
|
+
*
|
|
378
|
+
* @returns {Promise<Array<{ id: string, metadata: any }>>}
|
|
379
|
+
* A promise that resolves to an array of connection objects with id and metadata properties.
|
|
380
|
+
* @throws {Error} If an error occurs while fetching connection IDs, retrieving metadata, or parsing JSON.
|
|
381
|
+
*/
|
|
382
|
+
getAllMetadata(): Promise<Array<{
|
|
383
|
+
id: string;
|
|
384
|
+
metadata: any;
|
|
385
|
+
}>>;
|
|
386
|
+
/**
|
|
387
|
+
* Retrieves all metadata objects for each connection in the specified room.
|
|
388
|
+
* Returns an array of connection objects with id and metadata properties.
|
|
389
|
+
* If no metadata is found for a connection, the metadata value is set to null.
|
|
390
|
+
*
|
|
391
|
+
* @param {string} roomName - The name of the room for which to retrieve connection metadata.
|
|
392
|
+
* @returns {Promise<Array<{ id: string, metadata: any }>>} A promise that resolves to an array of
|
|
393
|
+
* connection objects with id and metadata properties (metadata is null if not available).
|
|
394
|
+
* @throws {Error} If there is an error retrieving connection IDs or metadata, the promise will be rejected with the error.
|
|
395
|
+
*/
|
|
396
|
+
getAllMetadataForRoom(roomName: string): Promise<Array<{
|
|
397
|
+
id: string;
|
|
398
|
+
metadata: any;
|
|
399
|
+
}>>;
|
|
400
|
+
cleanupConnection(connection: Connection): Promise<void>;
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
declare class RedisManager {
|
|
404
|
+
private _redis;
|
|
405
|
+
private _pubClient;
|
|
406
|
+
private _subClient;
|
|
407
|
+
private _isShuttingDown;
|
|
408
|
+
/**
|
|
409
|
+
* Initializes Redis connections with the provided options
|
|
410
|
+
*
|
|
411
|
+
* @param options - Redis connection options
|
|
412
|
+
* @param onError - Error handler callback
|
|
413
|
+
*/
|
|
414
|
+
initialize(options: RedisOptions, onError: (err: Error) => void): void;
|
|
415
|
+
/**
|
|
416
|
+
* Gets the main Redis client
|
|
417
|
+
*
|
|
418
|
+
* @returns The Redis client
|
|
419
|
+
* @throws Error if Redis is not initialized
|
|
420
|
+
*/
|
|
421
|
+
get redis(): Redis$1;
|
|
422
|
+
/**
|
|
423
|
+
* Gets the Redis client for publishing
|
|
424
|
+
*
|
|
425
|
+
* @returns The publishing Redis client
|
|
426
|
+
* @throws Error if Redis is not initialized
|
|
427
|
+
*/
|
|
428
|
+
get pubClient(): Redis$1;
|
|
429
|
+
/**
|
|
430
|
+
* Gets the Redis client for subscribing
|
|
431
|
+
*
|
|
432
|
+
* @returns The subscribing Redis client
|
|
433
|
+
* @throws Error if Redis is not initialized
|
|
434
|
+
*/
|
|
435
|
+
get subClient(): Redis$1;
|
|
436
|
+
/**
|
|
437
|
+
* Disconnects all Redis clients
|
|
438
|
+
*/
|
|
439
|
+
disconnect(): void;
|
|
440
|
+
/**
|
|
441
|
+
* Checks if Redis is shutting down
|
|
442
|
+
*
|
|
443
|
+
* @returns true if Redis is shutting down, false otherwise
|
|
444
|
+
*/
|
|
445
|
+
get isShuttingDown(): boolean;
|
|
446
|
+
/**
|
|
447
|
+
* Sets the shutting down state
|
|
448
|
+
*
|
|
449
|
+
* @param value - The new shutting down state
|
|
450
|
+
*/
|
|
451
|
+
set isShuttingDown(value: boolean);
|
|
452
|
+
/**
|
|
453
|
+
* Enables Redis keyspace notifications for expired events by updating the
|
|
454
|
+
* "notify-keyspace-events" configuration. Ensures that both keyevent ('E')
|
|
455
|
+
* and expired event ('x') notifications are enabled. If they are not already
|
|
456
|
+
* present, the method appends them to the current configuration.
|
|
457
|
+
*
|
|
458
|
+
* @returns {Promise<void>} A promise that resolves when the configuration has been updated.
|
|
459
|
+
* @throws {Error} If the Redis CONFIG commands fail or the connection encounters an error.
|
|
460
|
+
*/
|
|
461
|
+
enableKeyspaceNotifications(): Promise<void>;
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
type ChannelPattern = string | RegExp;
|
|
465
|
+
declare class PresenceManager {
|
|
466
|
+
private redis;
|
|
467
|
+
private roomManager;
|
|
468
|
+
private redisManager;
|
|
469
|
+
private presenceExpirationEventsEnabled;
|
|
470
|
+
private getExpiredEventsPattern;
|
|
471
|
+
private readonly PRESENCE_KEY_PATTERN;
|
|
472
|
+
private readonly PRESENCE_STATE_KEY_PATTERN;
|
|
473
|
+
private trackedRooms;
|
|
474
|
+
private roomGuards;
|
|
475
|
+
private roomTTLs;
|
|
476
|
+
private defaultTTL;
|
|
477
|
+
constructor(options: {
|
|
478
|
+
redis: Redis$1;
|
|
479
|
+
roomManager: RoomManager;
|
|
480
|
+
redisManager: RedisManager;
|
|
481
|
+
enableExpirationEvents?: boolean;
|
|
482
|
+
});
|
|
483
|
+
/**
|
|
484
|
+
* Subscribes to Redis keyspace notifications for expired presence keys
|
|
485
|
+
*/
|
|
486
|
+
private subscribeToExpirationEvents;
|
|
487
|
+
/**
|
|
488
|
+
* Handles an expired key notification
|
|
489
|
+
*/
|
|
490
|
+
private handleExpiredKey;
|
|
491
|
+
trackRoom(roomPattern: ChannelPattern, guardOrOptions?: ((connection: Connection, roomName: string) => Promise<boolean> | boolean) | {
|
|
492
|
+
ttl?: number;
|
|
493
|
+
guard?: (connection: Connection, roomName: string) => Promise<boolean> | boolean;
|
|
494
|
+
}): void;
|
|
495
|
+
isRoomTracked(roomName: string, connection?: Connection): Promise<boolean>;
|
|
496
|
+
getRoomTTL(roomName: string): number;
|
|
497
|
+
private presenceRoomKey;
|
|
498
|
+
private presenceConnectionKey;
|
|
499
|
+
private presenceStateKey;
|
|
500
|
+
markOnline(connectionId: string, roomName: string): Promise<void>;
|
|
501
|
+
markOffline(connectionId: string, roomName: string): Promise<void>;
|
|
502
|
+
refreshPresence(connectionId: string, roomName: string): Promise<void>;
|
|
503
|
+
getPresentConnections(roomName: string): Promise<string[]>;
|
|
504
|
+
private publishPresenceUpdate;
|
|
505
|
+
/**
|
|
506
|
+
* Publishes a presence state for a connection in a room
|
|
507
|
+
*
|
|
508
|
+
* @param connectionId The ID of the connection
|
|
509
|
+
* @param roomName The name of the room
|
|
510
|
+
* @param state The state object to publish
|
|
511
|
+
* @param expireAfter Optional TTL in milliseconds
|
|
512
|
+
*/
|
|
513
|
+
publishPresenceState(connectionId: string, roomName: string, state: Record<string, any>, expireAfter?: number, silent?: boolean): Promise<void>;
|
|
514
|
+
/**
|
|
515
|
+
* Clears the presence state for a connection in a room
|
|
516
|
+
*
|
|
517
|
+
* @param connectionId The ID of the connection
|
|
518
|
+
* @param roomName The name of the room
|
|
519
|
+
*/
|
|
520
|
+
clearPresenceState(connectionId: string, roomName: string): Promise<void>;
|
|
521
|
+
/**
|
|
522
|
+
* Gets the current presence state for a connection in a room
|
|
523
|
+
*
|
|
524
|
+
* @param connectionId The ID of the connection
|
|
525
|
+
* @param roomName The name of the room
|
|
526
|
+
* @returns The presence state or null if not found
|
|
527
|
+
*/
|
|
528
|
+
getPresenceState(connectionId: string, roomName: string): Promise<Record<string, any> | null>;
|
|
529
|
+
/**
|
|
530
|
+
* Gets all presence states for a room
|
|
531
|
+
*
|
|
532
|
+
* @param roomName The name of the room
|
|
533
|
+
* @returns A map of connection IDs to their presence states
|
|
534
|
+
*/
|
|
535
|
+
getAllPresenceStates(roomName: string): Promise<Map<string, Record<string, any>>>;
|
|
536
|
+
/**
|
|
537
|
+
* Publishes a presence state update to Redis
|
|
538
|
+
*
|
|
539
|
+
* @param roomName The name of the room
|
|
540
|
+
* @param connectionId The ID of the connection
|
|
541
|
+
* @param state The state object or null
|
|
542
|
+
*/
|
|
543
|
+
private publishPresenceStateUpdate;
|
|
544
|
+
cleanupConnection(connection: Connection): Promise<void>;
|
|
545
|
+
/**
|
|
546
|
+
* Cleans up Redis subscriptions when the PresenceManager is being destroyed.
|
|
547
|
+
*/
|
|
548
|
+
cleanup(): Promise<void>;
|
|
549
|
+
}
|
|
550
|
+
|
|
551
|
+
declare class RecordManager {
|
|
552
|
+
private redis;
|
|
553
|
+
private recordUpdateCallbacks;
|
|
554
|
+
private recordRemovedCallbacks;
|
|
555
|
+
private server;
|
|
556
|
+
constructor(options: {
|
|
557
|
+
redis: Redis$1;
|
|
558
|
+
server: MeshServer;
|
|
559
|
+
});
|
|
560
|
+
/**
|
|
561
|
+
* Gets the server instance associated with this record manager
|
|
562
|
+
*/
|
|
563
|
+
getServer(): MeshServer;
|
|
564
|
+
/**
|
|
565
|
+
* Gets the Redis instance used by this record manager
|
|
566
|
+
* This is used by the persistence manager to restore records
|
|
567
|
+
*/
|
|
568
|
+
getRedis(): Redis$1;
|
|
569
|
+
recordKey(recordId: string): string;
|
|
570
|
+
recordVersionKey(recordId: string): string;
|
|
571
|
+
/**
|
|
572
|
+
* Retrieves a record from Redis by its unique identifier. Attempts to parse
|
|
573
|
+
* the stored data as JSON before returning. If the record does not exist,
|
|
574
|
+
* returns null.
|
|
575
|
+
*
|
|
576
|
+
* @param {string} recordId - The unique identifier of the record to retrieve.
|
|
577
|
+
* @returns {Promise<any | null>} A promise that resolves to the parsed record object,
|
|
578
|
+
* or null if the record does not exist.
|
|
579
|
+
* @throws {SyntaxError} If the stored data is not valid JSON and cannot be parsed.
|
|
580
|
+
* @throws {Error} If an error occurs during the Redis operation.
|
|
581
|
+
*/
|
|
582
|
+
getRecord(recordId: string): Promise<any | null>;
|
|
583
|
+
/**
|
|
584
|
+
* Retrieves the version number associated with the specified record ID from Redis.
|
|
585
|
+
* If no version is found, returns 0.
|
|
586
|
+
*
|
|
587
|
+
* @param {string} recordId - The unique identifier for the record whose version is to be retrieved.
|
|
588
|
+
* @returns {Promise<number>} A promise that resolves to the version number of the record. Returns 0 if not found.
|
|
589
|
+
* @throws {Error} If there is an issue communicating with Redis or parsing the version.
|
|
590
|
+
*/
|
|
591
|
+
getVersion(recordId: string): Promise<number>;
|
|
592
|
+
/**
|
|
593
|
+
* Retrieves a record and its associated version from Redis.
|
|
594
|
+
* Fetches both the record data and its version by their respective keys.
|
|
595
|
+
*
|
|
596
|
+
* @param {string} recordId - The unique identifier for the record to retrieve.
|
|
597
|
+
* @returns {Promise<{ record: any | null; version: number }>}
|
|
598
|
+
* A promise that resolves to an object containing the parsed record (or null if not found)
|
|
599
|
+
* and its version number (0 if version data is not found or invalid).
|
|
600
|
+
* @throws {Error} If there is a Redis error or if JSON parsing fails for the record data.
|
|
601
|
+
*/
|
|
602
|
+
getRecordAndVersion(recordId: string): Promise<{
|
|
603
|
+
record: any | null;
|
|
604
|
+
version: number;
|
|
605
|
+
}>;
|
|
606
|
+
/**
|
|
607
|
+
* Publishes an update to a record by computing and applying a JSON Patch,
|
|
608
|
+
* incrementing the version, and persisting the updated value and version in Redis.
|
|
609
|
+
* If there are no changes between the old and new value, returns null.
|
|
610
|
+
*
|
|
611
|
+
* @param {string} recordId - The unique identifier of the record to update.
|
|
612
|
+
* @param {any} newValue - The new value to set for the record, or partial value when using merge strategy.
|
|
613
|
+
* @param {"replace" | "merge" | "deepMerge"} [strategy="replace"] - Update strategy: "replace" (default) replaces the entire record, "merge" merges with existing object properties, "deepMerge" recursively merges nested objects.
|
|
614
|
+
* @returns {Promise<{ patch: Operation[]; version: number; finalValue: any } | null>}
|
|
615
|
+
* A promise resolving to an object containing the JSON Patch operations, new version number, and final merged value,
|
|
616
|
+
* or null if there were no changes to publish.
|
|
617
|
+
* @throws {Error} If there is a failure reading or writing to Redis, or during patch computation, the promise will be rejected with the error.
|
|
618
|
+
*/
|
|
619
|
+
publishUpdate(recordId: string, newValue: any, strategy?: "replace" | "merge" | "deepMerge"): Promise<{
|
|
620
|
+
patch: Operation[];
|
|
621
|
+
version: number;
|
|
622
|
+
finalValue: any;
|
|
623
|
+
} | null>;
|
|
624
|
+
/**
|
|
625
|
+
* Deletes a record and its associated version from Redis storage.
|
|
626
|
+
*
|
|
627
|
+
* @param {string} recordId - The unique identifier of the record to be deleted.
|
|
628
|
+
* @returns {Promise<{ version: number }|null>} A promise that resolves to the final version of the deleted record, or null if the record didn't exist.
|
|
629
|
+
* @throws {Error} If an error occurs during the Redis pipeline execution, the promise will be rejected with the error.
|
|
630
|
+
*/
|
|
631
|
+
deleteRecord(recordId: string): Promise<{
|
|
632
|
+
version: number;
|
|
633
|
+
} | null>;
|
|
634
|
+
/**
|
|
635
|
+
* Registers a callback function to be called when a record is updated.
|
|
636
|
+
*
|
|
637
|
+
* @param {(data: { recordId: string; value: any }) => Promise<void> | void} callback - The callback function to execute when a record is updated.
|
|
638
|
+
* @returns {() => void} A function that, when called, will unregister the callback.
|
|
639
|
+
*/
|
|
640
|
+
onRecordUpdate(callback: (data: {
|
|
641
|
+
recordId: string;
|
|
642
|
+
value: any;
|
|
643
|
+
}) => Promise<void> | void): () => void;
|
|
644
|
+
/**
|
|
645
|
+
* Registers a callback function to be called when a record is removed.
|
|
646
|
+
*
|
|
647
|
+
* @param {(data: { recordId: string; value: any }) => Promise<void> | void} callback - The callback function to execute when a record is removed.
|
|
648
|
+
* @returns {() => void} A function that, when called, will unregister the callback.
|
|
649
|
+
*/
|
|
650
|
+
onRecordRemoved(callback: (data: {
|
|
651
|
+
recordId: string;
|
|
652
|
+
value: any;
|
|
653
|
+
}) => Promise<void> | void): () => void;
|
|
654
|
+
}
|
|
655
|
+
|
|
656
|
+
declare class MeshServer extends WebSocketServer {
|
|
657
|
+
readonly instanceId: string;
|
|
658
|
+
private redisManager;
|
|
659
|
+
private instanceManager;
|
|
660
|
+
private commandManager;
|
|
661
|
+
private channelManager;
|
|
662
|
+
private pubSubManager;
|
|
663
|
+
private recordSubscriptionManager;
|
|
664
|
+
private collectionManager;
|
|
665
|
+
private broadcastManager;
|
|
666
|
+
private persistenceManager;
|
|
667
|
+
roomManager: RoomManager;
|
|
668
|
+
recordManager: RecordManager;
|
|
669
|
+
connectionManager: ConnectionManager;
|
|
670
|
+
presenceManager: PresenceManager;
|
|
671
|
+
serverOptions: MeshServerOptions;
|
|
672
|
+
status: Status;
|
|
673
|
+
private _listening;
|
|
674
|
+
get listening(): boolean;
|
|
675
|
+
set listening(value: boolean);
|
|
676
|
+
get port(): number;
|
|
677
|
+
constructor(opts: MeshServerOptions);
|
|
678
|
+
/**
|
|
679
|
+
* Waits until the service is ready by ensuring it is listening, the instance channel subscription is established,
|
|
680
|
+
* and the persistence manager is fully initialized.
|
|
681
|
+
*
|
|
682
|
+
* @returns {Promise<void>} A promise that resolves when the service is fully ready.
|
|
683
|
+
* @throws {Error} If the readiness process fails or if any awaited promise rejects.
|
|
684
|
+
*/
|
|
685
|
+
ready(): Promise<void>;
|
|
686
|
+
private applyListeners;
|
|
687
|
+
/**
|
|
688
|
+
* Registers a command with an associated callback and optional middleware.
|
|
689
|
+
*
|
|
690
|
+
* @template T The type for `MeshContext.payload`. Defaults to `any`.
|
|
691
|
+
* @template U The command's return value type. Defaults to `any`.
|
|
692
|
+
* @param {string} command - The unique identifier for the command to register.
|
|
693
|
+
* @param {(context: MeshContext<T>) => Promise<U> | U} callback - The function to execute when the command is invoked. It receives a `MeshContext` of type `T` and may return a value of type `U` or a `Promise` resolving to `U`.
|
|
694
|
+
* @param {SocketMiddleware[]} [middlewares=[]] - An optional array of middleware functions to apply to the command. Defaults to an empty array.
|
|
695
|
+
* @throws {Error} May throw an error if the command registration or middleware addition fails.
|
|
696
|
+
*/
|
|
697
|
+
exposeCommand<T = any, U = any>(command: string, callback: (context: MeshContext<T>) => Promise<U> | U, middlewares?: SocketMiddleware[]): void;
|
|
698
|
+
/**
|
|
699
|
+
* Adds one or more middleware functions to the global middleware stack.
|
|
700
|
+
*
|
|
701
|
+
* @param {SocketMiddleware[]} middlewares - An array of middleware functions to be added. Each middleware
|
|
702
|
+
* is expected to conform to the `SocketMiddleware` type.
|
|
703
|
+
* @returns {void}
|
|
704
|
+
* @throws {Error} If the provided middlewares are not valid or fail validation (if applicable).
|
|
705
|
+
*/
|
|
706
|
+
useMiddleware(...middlewares: SocketMiddleware[]): void;
|
|
707
|
+
/**
|
|
708
|
+
* Adds an array of middleware functions to a specific command.
|
|
709
|
+
*
|
|
710
|
+
* @param {string} command - The name of the command to associate the middleware with.
|
|
711
|
+
* @param {SocketMiddleware[]} middlewares - An array of middleware functions to be added to the command.
|
|
712
|
+
* @returns {void}
|
|
713
|
+
*/
|
|
714
|
+
useMiddlewareWithCommand(command: string, middlewares: SocketMiddleware[]): void;
|
|
715
|
+
/**
|
|
716
|
+
* Exposes a channel for external access and optionally associates a guard function
|
|
717
|
+
* to control access to that channel. The guard function determines whether a given
|
|
718
|
+
* connection is permitted to access the channel.
|
|
719
|
+
*
|
|
720
|
+
* @param {ChannelPattern} channel - The channel or pattern to expose.
|
|
721
|
+
* @param {(connection: Connection, channel: string) => Promise<boolean> | boolean} [guard] -
|
|
722
|
+
* Optional guard function that receives the connection and channel name, returning
|
|
723
|
+
* a boolean or a promise that resolves to a boolean indicating whether access is allowed.
|
|
724
|
+
* @returns {void}
|
|
725
|
+
*/
|
|
726
|
+
exposeChannel(channel: ChannelPattern$1, guard?: (connection: Connection, channel: string) => Promise<boolean> | boolean): void;
|
|
727
|
+
/**
|
|
728
|
+
* Publishes a message to a specified channel and optionally maintains a history of messages.
|
|
729
|
+
*
|
|
730
|
+
* @param {string} channel - The name of the channel to which the message will be published.
|
|
731
|
+
* @param {any} message - The message to be published. Will not be stringified automatically for you. You need to do that yourself.
|
|
732
|
+
* @param {number} [history=0] - The number of historical messages to retain for the channel. Defaults to 0, meaning no history is retained.
|
|
733
|
+
* If greater than 0, the message will be added to the channel's history and the history will be trimmed to the specified size.
|
|
734
|
+
* @returns {Promise<void>} A Promise that resolves once the message has been published and, if applicable, the history has been updated.
|
|
735
|
+
* @throws {Error} This function may throw an error if the underlying `pubClient` operations (e.g., `lpush`, `ltrim`, `publish`) fail.
|
|
736
|
+
*/
|
|
737
|
+
writeChannel(channel: string, message: any, history?: number): Promise<void>;
|
|
738
|
+
/**
|
|
739
|
+
* Enables persistence for channels matching the specified pattern.
|
|
740
|
+
*
|
|
741
|
+
* @param {ChannelPattern} pattern - The channel pattern to enable persistence for.
|
|
742
|
+
* @param {ChannelPersistenceOptions} [options] - Options for persistence.
|
|
743
|
+
* @throws {Error} If persistence is not enabled for this server instance.
|
|
744
|
+
*/
|
|
745
|
+
enableChannelPersistence(pattern: ChannelPattern$1, options?: ChannelPersistenceOptions): void;
|
|
746
|
+
/**
|
|
747
|
+
* Enables persistence for records matching the specified pattern.
|
|
748
|
+
*
|
|
749
|
+
* @param {ChannelPattern} pattern - The record ID pattern to enable persistence for.
|
|
750
|
+
* @param {RecordPersistenceOptions} [options] - Options for persistence.
|
|
751
|
+
* @throws {Error} If persistence is not enabled for this server instance.
|
|
752
|
+
*/
|
|
753
|
+
enableRecordPersistence(pattern: ChannelPattern$1, options?: RecordPersistenceOptions): void;
|
|
754
|
+
/**
|
|
755
|
+
* Exposes a record or pattern for client subscriptions, optionally adding a guard function.
|
|
756
|
+
*
|
|
757
|
+
* @param {ChannelPattern} recordPattern - The record ID or pattern to expose.
|
|
758
|
+
* @param {(connection: Connection, recordId: string) => Promise<boolean> | boolean} [guard] - Optional guard function.
|
|
759
|
+
*/
|
|
760
|
+
exposeRecord(recordPattern: ChannelPattern$1, guard?: (connection: Connection, recordId: string) => Promise<boolean> | boolean): void;
|
|
761
|
+
/**
|
|
762
|
+
* Exposes a record or pattern for client writes, optionally adding a guard function.
|
|
763
|
+
*
|
|
764
|
+
* @param {ChannelPattern} recordPattern - The record ID or pattern to expose as writable.
|
|
765
|
+
* @param {(connection: Connection, recordId: string) => Promise<boolean> | boolean} [guard] - Optional guard function.
|
|
766
|
+
*/
|
|
767
|
+
exposeWritableRecord(recordPattern: ChannelPattern$1, guard?: (connection: Connection, recordId: string) => Promise<boolean> | boolean): void;
|
|
768
|
+
/**
|
|
769
|
+
* Updates a record, persists it to Redis, increments its version, computes a patch,
|
|
770
|
+
* and publishes the update via Redis pub/sub.
|
|
771
|
+
*
|
|
772
|
+
* @param {string} recordId - The ID of the record to update.
|
|
773
|
+
* @param {any} newValue - The new value for the record, or partial value when using merge strategy.
|
|
774
|
+
* @param {{ strategy?: "replace" | "merge" | "deepMerge" }} [options] - Update options: strategy defaults to "replace" which replaces the entire record, "merge" merges with existing object properties, "deepMerge" recursively merges nested objects.
|
|
775
|
+
* @returns {Promise<void>}
|
|
776
|
+
* @throws {Error} If the update fails.
|
|
777
|
+
*
|
|
778
|
+
* @example
|
|
779
|
+
* // Replace strategy (default) - replaces entire record
|
|
780
|
+
* await server.writeRecord("user:123", { name: "John", age: 30 });
|
|
781
|
+
*
|
|
782
|
+
* // Merge strategy - merges with existing record
|
|
783
|
+
* // If record currently contains: { name: "old name", age: 30, city: "NYC" }
|
|
784
|
+
* await server.writeRecord("user:123", { name: "new name" }, { strategy: "merge" });
|
|
785
|
+
* // Result: { name: "new name", age: 30, city: "NYC" }
|
|
786
|
+
*
|
|
787
|
+
* // Deep merge strategy - recursively merges nested objects
|
|
788
|
+
* // If record currently contains: { name: "John", profile: { age: 30, city: "NYC", preferences: { theme: "dark" } } }
|
|
789
|
+
* await server.writeRecord("user:123", { profile: { age: 31 } }, { strategy: "deepMerge" });
|
|
790
|
+
* // Result: { name: "John", profile: { age: 31, city: "NYC", preferences: { theme: "dark" } } }
|
|
791
|
+
*/
|
|
792
|
+
writeRecord(recordId: string, newValue: any, options?: {
|
|
793
|
+
strategy?: "replace" | "merge" | "deepMerge";
|
|
794
|
+
}): Promise<void>;
|
|
795
|
+
/**
|
|
796
|
+
* Retrieves the value of a record by its ID.
|
|
797
|
+
*
|
|
798
|
+
* @param {string} recordId - The ID of the record to retrieve.
|
|
799
|
+
* @returns {Promise<any>} A promise that resolves to the value of the record, or null if not found.
|
|
800
|
+
*/
|
|
801
|
+
getRecord(recordId: string): Promise<any>;
|
|
802
|
+
deleteRecord(recordId: string): Promise<void>;
|
|
803
|
+
/**
|
|
804
|
+
* Lists and processes records matching a pattern. Designed for use in collection resolvers.
|
|
805
|
+
* Returns transformed records that will be sent to subscribed clients.
|
|
806
|
+
*
|
|
807
|
+
* @param {string} pattern - Redis glob pattern to match record IDs against (e.g., "user:*", "post:?", "[abc]*").
|
|
808
|
+
* @param {Object} [options] - Processing options.
|
|
809
|
+
* @param {Function} [options.map] - Transform each record before sorting/slicing.
|
|
810
|
+
* @param {Function} [options.sort] - Sort function for the records.
|
|
811
|
+
* @param {Object} [options.slice] - Pagination slice.
|
|
812
|
+
* @param {number} [options.slice.start] - Start index.
|
|
813
|
+
* @param {number} [options.slice.count] - Number of records to return.
|
|
814
|
+
* @returns {Promise<any[]>} The processed records to send to clients.
|
|
815
|
+
*/
|
|
816
|
+
listRecordsMatching(pattern: string, options?: {
|
|
817
|
+
map?: (record: any) => any;
|
|
818
|
+
sort?: (a: any, b: any) => number;
|
|
819
|
+
slice?: {
|
|
820
|
+
start: number;
|
|
821
|
+
count: number;
|
|
822
|
+
};
|
|
823
|
+
}): Promise<any[]>;
|
|
824
|
+
/**
|
|
825
|
+
* Exposes a collection pattern for client subscriptions with a resolver function
|
|
826
|
+
* that determines which records belong to the collection.
|
|
827
|
+
*
|
|
828
|
+
* @param {ChannelPattern} pattern - The collection ID or pattern to expose.
|
|
829
|
+
* @param {(connection: Connection, collectionId: string) => Promise<any[]> | any[]} resolver -
|
|
830
|
+
* Function that resolves which records belong to the collection.
|
|
831
|
+
*/
|
|
832
|
+
exposeCollection(pattern: ChannelPattern$1, resolver: (connection: Connection, collectionId: string) => Promise<any[]> | any[]): void;
|
|
833
|
+
isInRoom(roomName: string, connection: Connection | string): Promise<boolean>;
|
|
834
|
+
addToRoom(roomName: string, connection: Connection | string): Promise<void>;
|
|
835
|
+
removeFromRoom(roomName: string, connection: Connection | string): Promise<void>;
|
|
836
|
+
removeFromAllRooms(connection: Connection | string): Promise<void>;
|
|
837
|
+
clearRoom(roomName: string): Promise<void>;
|
|
838
|
+
deleteRoom(roomName: string): Promise<void>;
|
|
839
|
+
getRoomMembers(roomName: string): Promise<string[]>;
|
|
840
|
+
getRoomMembersWithMetadata(roomName: string): Promise<Array<{
|
|
841
|
+
id: string;
|
|
842
|
+
metadata: any;
|
|
843
|
+
}>>;
|
|
844
|
+
getAllRooms(): Promise<string[]>;
|
|
845
|
+
/**
|
|
846
|
+
* Broadcasts a command and payload to a set of connections or all available connections.
|
|
847
|
+
*
|
|
848
|
+
* @param {string} command - The command to be broadcasted.
|
|
849
|
+
* @param {any} payload - The data associated with the command.
|
|
850
|
+
* @param {Connection[]=} connections - (Optional) A specific list of connections to broadcast to. If not provided, the command will be sent to all connections.
|
|
851
|
+
*
|
|
852
|
+
* @throws {Error} Emits an "error" event if broadcasting fails.
|
|
853
|
+
*/
|
|
854
|
+
broadcast(command: string, payload: any, connections?: Connection[]): Promise<void>;
|
|
855
|
+
/**
|
|
856
|
+
* Broadcasts a command and associated payload to all active connections within the specified room.
|
|
857
|
+
*
|
|
858
|
+
* @param {string} roomName - The name of the room whose connections will receive the broadcast.
|
|
859
|
+
* @param {string} command - The command to be broadcasted to the connections.
|
|
860
|
+
* @param {unknown} payload - The data payload associated with the command.
|
|
861
|
+
* @returns {Promise<void>} A promise that resolves when the broadcast operation is complete.
|
|
862
|
+
* @throws {Error} If the broadcast operation fails, an error is thrown and the promise is rejected.
|
|
863
|
+
*/
|
|
864
|
+
broadcastRoom(roomName: string, command: string, payload: any): Promise<void>;
|
|
865
|
+
/**
|
|
866
|
+
* Broadcasts a command and payload to all active connections except for the specified one(s).
|
|
867
|
+
* Excludes the provided connection(s) from receiving the broadcast.
|
|
868
|
+
*
|
|
869
|
+
* @param {string} command - The command to broadcast to connections.
|
|
870
|
+
* @param {any} payload - The payload to send along with the command.
|
|
871
|
+
* @param {Connection | Connection[]} exclude - A single connection or an array of connections to exclude from the broadcast.
|
|
872
|
+
* @returns {Promise<void>} A promise that resolves when the broadcast is complete.
|
|
873
|
+
* @emits {Error} Emits an "error" event if broadcasting the command fails.
|
|
874
|
+
*/
|
|
875
|
+
broadcastExclude(command: string, payload: any, exclude: Connection | Connection[]): Promise<void>;
|
|
876
|
+
/**
|
|
877
|
+
* Broadcasts a command with a payload to all connections in a specified room,
|
|
878
|
+
* excluding one or more given connections. If the broadcast fails, emits an error event.
|
|
879
|
+
*
|
|
880
|
+
* @param {string} roomName - The name of the room to broadcast to.
|
|
881
|
+
* @param {string} command - The command to broadcast.
|
|
882
|
+
* @param {any} payload - The payload to send with the command.
|
|
883
|
+
* @param {Connection | Connection[]} exclude - A connection or array of connections to exclude from the broadcast.
|
|
884
|
+
* @returns {Promise<void>} A promise that resolves when the broadcast is complete.
|
|
885
|
+
* @emits {Error} Emits an error event if broadcasting fails.
|
|
886
|
+
*/
|
|
887
|
+
broadcastRoomExclude(roomName: string, command: string, payload: any, exclude: Connection | Connection[]): Promise<void>;
|
|
888
|
+
trackPresence(roomPattern: string | RegExp, guardOrOptions?: ((connection: Connection, roomName: string) => Promise<boolean> | boolean) | {
|
|
889
|
+
ttl?: number;
|
|
890
|
+
guard?: (connection: Connection, roomName: string) => Promise<boolean> | boolean;
|
|
891
|
+
}): void;
|
|
892
|
+
private registerBuiltinCommands;
|
|
893
|
+
private registerRecordCommands;
|
|
894
|
+
cleanupConnection(connection: Connection): Promise<void>;
|
|
895
|
+
/**
|
|
896
|
+
* Gracefully closes all active connections, cleans up resources,
|
|
897
|
+
* and shuts down the service. Optionally accepts a callback function
|
|
898
|
+
* that will be invoked once shutdown is complete or if an error occurs.
|
|
899
|
+
*
|
|
900
|
+
* @param {((err?: Error) => void)=} callback - Optional callback to be invoked when closing is complete or if an error occurs.
|
|
901
|
+
* @returns {Promise<void>} A promise that resolves when shutdown is complete.
|
|
902
|
+
* @throws {Error} If an error occurs during shutdown, the promise will be rejected with the error.
|
|
903
|
+
*/
|
|
904
|
+
close(callback?: (err?: Error) => void): Promise<void>;
|
|
905
|
+
/**
|
|
906
|
+
* Registers a callback function to be executed when a new connection is established.
|
|
907
|
+
*
|
|
908
|
+
* @param {(connection: Connection) => Promise<void> | void} callback - The function to execute when a new connection is established.
|
|
909
|
+
* @returns {MeshServer} The server instance for method chaining.
|
|
910
|
+
*/
|
|
911
|
+
onConnection(callback: (connection: Connection) => Promise<void> | void): MeshServer;
|
|
912
|
+
/**
|
|
913
|
+
* Registers a callback function to be executed when a connection is closed.
|
|
914
|
+
*
|
|
915
|
+
* @param {(connection: Connection) => Promise<void> | void} callback - The function to execute when a connection is closed.
|
|
916
|
+
* @returns {MeshServer} The server instance for method chaining.
|
|
917
|
+
*/
|
|
918
|
+
onDisconnection(callback: (connection: Connection) => Promise<void> | void): MeshServer;
|
|
919
|
+
/**
|
|
920
|
+
* Registers a callback function to be executed when a record is updated.
|
|
921
|
+
*
|
|
922
|
+
* @param {(data: { recordId: string; value: any }) => Promise<void> | void} callback - The function to execute when a record is updated.
|
|
923
|
+
* @returns {() => void} A function that, when called, will unregister the callback.
|
|
924
|
+
*/
|
|
925
|
+
onRecordUpdate(callback: (data: {
|
|
926
|
+
recordId: string;
|
|
927
|
+
value: any;
|
|
928
|
+
}) => Promise<void> | void): () => void;
|
|
929
|
+
/**
|
|
930
|
+
* Registers a callback function to be executed when a record is removed.
|
|
931
|
+
*
|
|
932
|
+
* @param {(data: { recordId: string; value: any }) => Promise<void> | void} callback - The function to execute when a record is removed.
|
|
933
|
+
* @returns {() => void} A function that, when called, will unregister the callback.
|
|
934
|
+
*/
|
|
935
|
+
onRecordRemoved(callback: (data: {
|
|
936
|
+
recordId: string;
|
|
937
|
+
value: any;
|
|
938
|
+
}) => Promise<void> | void): () => void;
|
|
939
|
+
}
|
|
940
|
+
|
|
941
|
+
declare class SQLitePersistenceAdapter implements PersistenceAdapter {
|
|
942
|
+
private db;
|
|
943
|
+
private options;
|
|
944
|
+
private initialized;
|
|
945
|
+
constructor(options?: PersistenceAdapterOptions);
|
|
946
|
+
initialize(): Promise<void>;
|
|
947
|
+
private createTables;
|
|
948
|
+
storeMessages(messages: PersistedMessage[]): Promise<void>;
|
|
949
|
+
getMessages(channel: string, since?: string | number, limit?: number): Promise<PersistedMessage[]>;
|
|
950
|
+
close(): Promise<void>;
|
|
951
|
+
/**
|
|
952
|
+
* Store records in the database
|
|
953
|
+
* @param records Array of records to store
|
|
954
|
+
*/
|
|
955
|
+
storeRecords(records: PersistedRecord[]): Promise<void>;
|
|
956
|
+
/**
|
|
957
|
+
* Get records matching a pattern
|
|
958
|
+
* @param pattern Pattern to match record IDs against
|
|
959
|
+
* @returns Array of matching records
|
|
960
|
+
*/
|
|
961
|
+
getRecords(pattern: string): Promise<PersistedRecord[]>;
|
|
962
|
+
}
|
|
963
|
+
|
|
964
|
+
declare class PostgreSQLPersistenceAdapter implements PersistenceAdapter {
|
|
965
|
+
private pool;
|
|
966
|
+
private options;
|
|
967
|
+
private initialized;
|
|
968
|
+
constructor(options?: PostgreSQLAdapterOptions);
|
|
969
|
+
initialize(): Promise<void>;
|
|
970
|
+
private createTables;
|
|
971
|
+
storeMessages(messages: PersistedMessage[]): Promise<void>;
|
|
972
|
+
getMessages(channel: string, since?: string | number, limit?: number): Promise<PersistedMessage[]>;
|
|
973
|
+
storeRecords(records: PersistedRecord[]): Promise<void>;
|
|
974
|
+
getRecords(pattern: string): Promise<PersistedRecord[]>;
|
|
975
|
+
close(): Promise<void>;
|
|
976
|
+
}
|
|
977
|
+
|
|
978
|
+
/**
|
|
979
|
+
* MessageStream provides a unified internal event stream for channel messages.
|
|
980
|
+
* It decouples channel message delivery from persistence.
|
|
981
|
+
*/
|
|
982
|
+
declare class MessageStream extends EventEmitter$1 {
|
|
983
|
+
private static instance;
|
|
984
|
+
/**
|
|
985
|
+
* Get the MessageStream singleton
|
|
986
|
+
*/
|
|
987
|
+
static getInstance(): MessageStream;
|
|
988
|
+
private constructor();
|
|
989
|
+
/**
|
|
990
|
+
* Publish a message to the stream
|
|
991
|
+
* @param channel The channel the message was published to
|
|
992
|
+
* @param message The message content
|
|
993
|
+
* @param instanceId ID of the server instance
|
|
994
|
+
*/
|
|
995
|
+
publishMessage(channel: string, message: string, instanceId: string): void;
|
|
996
|
+
/**
|
|
997
|
+
* Subscribe to all messages in the stream
|
|
998
|
+
* @param callback Function to call for each message
|
|
999
|
+
*/
|
|
1000
|
+
subscribeToMessages(callback: (message: {
|
|
1001
|
+
channel: string;
|
|
1002
|
+
message: string;
|
|
1003
|
+
instanceId: string;
|
|
1004
|
+
timestamp: number;
|
|
1005
|
+
}) => void): void;
|
|
1006
|
+
/**
|
|
1007
|
+
* Unsubscribe from messages
|
|
1008
|
+
* @param callback The callback function to remove
|
|
1009
|
+
*/
|
|
1010
|
+
unsubscribeFromMessages(callback: (message: {
|
|
1011
|
+
channel: string;
|
|
1012
|
+
message: string;
|
|
1013
|
+
instanceId: string;
|
|
1014
|
+
timestamp: number;
|
|
1015
|
+
}) => void): void;
|
|
1016
|
+
}
|
|
1017
|
+
|
|
1018
|
+
declare class PersistenceManager extends EventEmitter$1 {
|
|
1019
|
+
private defaultAdapter;
|
|
1020
|
+
private channelPatterns;
|
|
1021
|
+
private recordPatterns;
|
|
1022
|
+
private messageBuffer;
|
|
1023
|
+
private recordBuffer;
|
|
1024
|
+
private flushTimers;
|
|
1025
|
+
private recordFlushTimer;
|
|
1026
|
+
private isShuttingDown;
|
|
1027
|
+
private initialized;
|
|
1028
|
+
private recordManager;
|
|
1029
|
+
private pendingRecordUpdates;
|
|
1030
|
+
private messageStream;
|
|
1031
|
+
constructor(options: {
|
|
1032
|
+
defaultAdapterOptions?: any;
|
|
1033
|
+
adapterType?: "sqlite" | "postgres";
|
|
1034
|
+
});
|
|
1035
|
+
/**
|
|
1036
|
+
* Sets the record manager reference for record restoration
|
|
1037
|
+
* @param recordManager The record manager instance
|
|
1038
|
+
*/
|
|
1039
|
+
setRecordManager(recordManager: RecordManager): void;
|
|
1040
|
+
/**
|
|
1041
|
+
* Waits until the persistence manager is fully ready and initialized.
|
|
1042
|
+
*
|
|
1043
|
+
* @returns {Promise<void>} A promise that resolves when persistence is ready.
|
|
1044
|
+
*/
|
|
1045
|
+
ready(): Promise<void>;
|
|
1046
|
+
/**
|
|
1047
|
+
* Processes any record updates that were buffered during initialization
|
|
1048
|
+
*/
|
|
1049
|
+
private processPendingRecordUpdates;
|
|
1050
|
+
initialize(): Promise<void>;
|
|
1051
|
+
/**
|
|
1052
|
+
* Restores persisted records from storage into Redis on startup
|
|
1053
|
+
*/
|
|
1054
|
+
private restorePersistedRecords;
|
|
1055
|
+
/**
|
|
1056
|
+
* Handle a message received from the internal message stream.
|
|
1057
|
+
*/
|
|
1058
|
+
private handleStreamMessage;
|
|
1059
|
+
/**
|
|
1060
|
+
* Enable persistence for channels matching the given pattern.
|
|
1061
|
+
* @param pattern string or regexp pattern to match channel names
|
|
1062
|
+
* @param options persistence options
|
|
1063
|
+
*/
|
|
1064
|
+
enableChannelPersistence(pattern: string | RegExp, options?: ChannelPersistenceOptions): void;
|
|
1065
|
+
/**
|
|
1066
|
+
* Enable persistence for records matching the given pattern.
|
|
1067
|
+
* @param pattern string or regexp pattern to match record IDs
|
|
1068
|
+
* @param options persistence options
|
|
1069
|
+
*/
|
|
1070
|
+
enableRecordPersistence(pattern: string | RegExp, options?: RecordPersistenceOptions): void;
|
|
1071
|
+
/**
|
|
1072
|
+
* Check if a channel has persistence enabled and return its options.
|
|
1073
|
+
* @param channel channel name to check
|
|
1074
|
+
* @returns the persistence options if enabled, undefined otherwise
|
|
1075
|
+
*/
|
|
1076
|
+
getChannelPersistenceOptions(channel: string): Required<ChannelPersistenceOptions> | undefined;
|
|
1077
|
+
/**
|
|
1078
|
+
* Check if a record has persistence enabled and return its options.
|
|
1079
|
+
* @param recordId record ID to check
|
|
1080
|
+
* @returns the persistence options if enabled, undefined otherwise
|
|
1081
|
+
*/
|
|
1082
|
+
getRecordPersistenceOptions(recordId: string): Required<RecordPersistenceOptions> | undefined;
|
|
1083
|
+
/**
|
|
1084
|
+
* Handle an incoming message for potential persistence.
|
|
1085
|
+
* @param channel channel the message was published to
|
|
1086
|
+
* @param message the message content
|
|
1087
|
+
* @param instanceId id of the server instance
|
|
1088
|
+
*/
|
|
1089
|
+
handleChannelMessage(channel: string, message: string, instanceId: string, timestamp?: number): void;
|
|
1090
|
+
/**
|
|
1091
|
+
* Flush buffered messages for a specific channel to its adapter.
|
|
1092
|
+
* @param channel channel to flush
|
|
1093
|
+
*/
|
|
1094
|
+
private flushChannel;
|
|
1095
|
+
/**
|
|
1096
|
+
* Flush all buffered messages across all channels.
|
|
1097
|
+
*/
|
|
1098
|
+
flushAll(): Promise<void>;
|
|
1099
|
+
/**
|
|
1100
|
+
* Get persisted messages for a channel.
|
|
1101
|
+
* @param channel channel to get messages for
|
|
1102
|
+
* @param since optional cursor (timestamp or message id) to retrieve messages after
|
|
1103
|
+
* @param limit maximum number of messages to retrieve
|
|
1104
|
+
*/
|
|
1105
|
+
getMessages(channel: string, since?: string | number, limit?: number): Promise<PersistedMessage[]>;
|
|
1106
|
+
/**
|
|
1107
|
+
* Handles a record update for potential persistence
|
|
1108
|
+
* @param recordId ID of the record
|
|
1109
|
+
* @param value record value (will be stringified)
|
|
1110
|
+
* @param version record version
|
|
1111
|
+
*/
|
|
1112
|
+
handleRecordUpdate(recordId: string, value: any, version: number): void;
|
|
1113
|
+
/**
|
|
1114
|
+
* Flush all buffered records to storage
|
|
1115
|
+
*/
|
|
1116
|
+
flushRecords(): Promise<void>;
|
|
1117
|
+
/**
|
|
1118
|
+
* Retrieve persisted records matching a pattern
|
|
1119
|
+
* @param pattern pattern to match record IDs
|
|
1120
|
+
* @returns array of persisted records
|
|
1121
|
+
*/
|
|
1122
|
+
getPersistedRecords(pattern: string): Promise<PersistedRecord[]>;
|
|
1123
|
+
/**
|
|
1124
|
+
* Shutdown the persistence manager, flushing pending messages and closing adapters.
|
|
1125
|
+
*/
|
|
1126
|
+
shutdown(): Promise<void>;
|
|
1127
|
+
}
|
|
1128
|
+
|
|
1129
|
+
export { type ChannelPattern$1 as ChannelPattern, Connection, ConnectionManager, MeshContext, MeshServer, type MeshServerOptions, MessageStream, type PersistenceAdapter, type PersistenceAdapterOptions, PersistenceManager, type PostgreSQLAdapterOptions, PostgreSQLPersistenceAdapter, PresenceManager, RecordManager, RoomManager, SQLitePersistenceAdapter, type SocketMiddleware };
|