@mesh-kit/server 2.0.4 → 2.0.5

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 CHANGED
@@ -3,9 +3,9 @@ export { ServerOptions } from 'ws';
3
3
  import { LogLevel, Status, Command } from '@mesh-kit/shared';
4
4
  import { EventEmitter } from 'node:events';
5
5
  import { IncomingMessage } from 'node:http';
6
- import Redis, { RedisOptions, Redis as Redis$1 } from 'ioredis';
7
- import { Operation } from 'fast-json-patch';
6
+ import Redis$1, { RedisOptions, Redis } from 'ioredis';
8
7
  import { EventEmitter as EventEmitter$1 } from 'events';
8
+ import { Operation } from 'fast-json-patch';
9
9
 
10
10
  declare class Latency {
11
11
  start: number;
@@ -195,10 +195,230 @@ declare class Connection extends EventEmitter {
195
195
  close(): Promise<boolean>;
196
196
  }
197
197
 
198
- declare class RoomManager {
198
+ declare class RecordManager {
199
199
  private redis;
200
+ private recordUpdateCallbacks;
201
+ private recordRemovedCallbacks;
202
+ private server;
200
203
  constructor(options: {
201
204
  redis: Redis;
205
+ server: MeshServer;
206
+ });
207
+ /**
208
+ * Gets the server instance associated with this record manager
209
+ */
210
+ getServer(): MeshServer;
211
+ /**
212
+ * Gets the Redis instance used by this record manager
213
+ * This is used by the persistence manager to restore records
214
+ */
215
+ getRedis(): Redis;
216
+ recordKey(recordId: string): string;
217
+ recordVersionKey(recordId: string): string;
218
+ /**
219
+ * Retrieves a record from Redis by its unique identifier. Attempts to parse
220
+ * the stored data as JSON before returning. If the record does not exist,
221
+ * returns null.
222
+ *
223
+ * @param {string} recordId - The unique identifier of the record to retrieve.
224
+ * @returns {Promise<any | null>} A promise that resolves to the parsed record object,
225
+ * or null if the record does not exist.
226
+ * @throws {SyntaxError} If the stored data is not valid JSON and cannot be parsed.
227
+ * @throws {Error} If an error occurs during the Redis operation.
228
+ */
229
+ getRecord(recordId: string): Promise<any | null>;
230
+ /**
231
+ * Retrieves the version number associated with the specified record ID from Redis.
232
+ * If no version is found, returns 0.
233
+ *
234
+ * @param {string} recordId - The unique identifier for the record whose version is to be retrieved.
235
+ * @returns {Promise<number>} A promise that resolves to the version number of the record. Returns 0 if not found.
236
+ * @throws {Error} If there is an issue communicating with Redis or parsing the version.
237
+ */
238
+ getVersion(recordId: string): Promise<number>;
239
+ /**
240
+ * Retrieves a record and its associated version from Redis.
241
+ * Fetches both the record data and its version by their respective keys.
242
+ *
243
+ * @param {string} recordId - The unique identifier for the record to retrieve.
244
+ * @returns {Promise<{ record: any | null; version: number }>}
245
+ * A promise that resolves to an object containing the parsed record (or null if not found)
246
+ * and its version number (0 if version data is not found or invalid).
247
+ * @throws {Error} If there is a Redis error or if JSON parsing fails for the record data.
248
+ */
249
+ getRecordAndVersion(recordId: string): Promise<{
250
+ record: any | null;
251
+ version: number;
252
+ }>;
253
+ /**
254
+ * Publishes an update to a record by computing and applying a JSON Patch,
255
+ * incrementing the version, and persisting the updated value and version in Redis.
256
+ * If there are no changes between the old and new value, returns null.
257
+ *
258
+ * @param {string} recordId - The unique identifier of the record to update.
259
+ * @param {any} newValue - The new value to set for the record, or partial value when using merge strategy.
260
+ * @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.
261
+ * @returns {Promise<{ patch: Operation[]; version: number; finalValue: any } | null>}
262
+ * A promise resolving to an object containing the JSON Patch operations, new version number, and final merged value,
263
+ * or null if there were no changes to publish.
264
+ * @throws {Error} If there is a failure reading or writing to Redis, or during patch computation, the promise will be rejected with the error.
265
+ */
266
+ publishUpdate(recordId: string, newValue: any, strategy?: "replace" | "merge" | "deepMerge"): Promise<{
267
+ patch: Operation[];
268
+ version: number;
269
+ finalValue: any;
270
+ } | null>;
271
+ /**
272
+ * Deletes a record and its associated version from Redis storage.
273
+ *
274
+ * @param {string} recordId - The unique identifier of the record to be deleted.
275
+ * @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.
276
+ * @throws {Error} If an error occurs during the Redis pipeline execution, the promise will be rejected with the error.
277
+ */
278
+ deleteRecord(recordId: string): Promise<{
279
+ version: number;
280
+ } | null>;
281
+ /**
282
+ * Registers a callback function to be called when a record is updated.
283
+ *
284
+ * @param {(data: { recordId: string; value: any }) => Promise<void> | void} callback - The callback function to execute when a record is updated.
285
+ * @returns {() => void} A function that, when called, will unregister the callback.
286
+ */
287
+ onRecordUpdate(callback: (data: {
288
+ recordId: string;
289
+ value: any;
290
+ }) => Promise<void> | void): () => void;
291
+ /**
292
+ * Registers a callback function to be called when a record is removed.
293
+ *
294
+ * @param {(data: { recordId: string; value: any }) => Promise<void> | void} callback - The callback function to execute when a record is removed.
295
+ * @returns {() => void} A function that, when called, will unregister the callback.
296
+ */
297
+ onRecordRemoved(callback: (data: {
298
+ recordId: string;
299
+ value: any;
300
+ }) => Promise<void> | void): () => void;
301
+ }
302
+
303
+ type RecordPersistencePattern = string | RegExp | {
304
+ writePattern: string | RegExp;
305
+ restorePattern: string | RegExp;
306
+ };
307
+ declare class PersistenceManager extends EventEmitter$1 {
308
+ private defaultAdapter;
309
+ private channelPatterns;
310
+ private recordPatterns;
311
+ private messageBuffer;
312
+ private recordBuffer;
313
+ private flushTimers;
314
+ private recordFlushTimer;
315
+ private isShuttingDown;
316
+ private initialized;
317
+ private recordManager;
318
+ private pendingRecordUpdates;
319
+ private messageStream;
320
+ constructor(options: {
321
+ defaultAdapterOptions?: any;
322
+ adapterType?: "sqlite" | "postgres";
323
+ });
324
+ /**
325
+ * Sets the record manager reference for record restoration
326
+ * @param recordManager The record manager instance
327
+ */
328
+ setRecordManager(recordManager: RecordManager): void;
329
+ /**
330
+ * Waits until the persistence manager is fully ready and initialized.
331
+ *
332
+ * @returns {Promise<void>} A promise that resolves when persistence is ready.
333
+ */
334
+ ready(): Promise<void>;
335
+ /**
336
+ * Processes any record updates that were buffered during initialization
337
+ */
338
+ private processPendingRecordUpdates;
339
+ initialize(): Promise<void>;
340
+ /**
341
+ * Restores persisted records from storage into Redis on startup
342
+ */
343
+ restorePersistedRecords(): Promise<void>;
344
+ /**
345
+ * Handle a message received from the internal message stream.
346
+ */
347
+ private handleStreamMessage;
348
+ /**
349
+ * Enable persistence for channels matching the given pattern.
350
+ * @param pattern string or regexp pattern to match channel names
351
+ * @param options persistence options
352
+ */
353
+ enableChannelPersistence(pattern: string | RegExp, options?: ChannelPersistenceOptions): void;
354
+ /**
355
+ * Enable persistence for records matching the given pattern.
356
+ * @param pattern string, regexp, or object with writePattern/restorePattern
357
+ * @param options persistence options
358
+ */
359
+ enableRecordPersistence(pattern: RecordPersistencePattern, options?: RecordPersistenceOptions): void;
360
+ /**
361
+ * Check if a channel has persistence enabled and return its options.
362
+ * @param channel channel name to check
363
+ * @returns the persistence options if enabled, undefined otherwise
364
+ */
365
+ getChannelPersistenceOptions(channel: string): Required<ChannelPersistenceOptions> | undefined;
366
+ /**
367
+ * Check if a record has persistence enabled and return its options.
368
+ * @param recordId record ID to check
369
+ * @returns the persistence options if enabled, undefined otherwise
370
+ */
371
+ getRecordPersistenceOptions(recordId: string): Required<RecordPersistenceOptions> | undefined;
372
+ /**
373
+ * Handle an incoming message for potential persistence.
374
+ * @param channel channel the message was published to
375
+ * @param message the message content
376
+ * @param instanceId id of the server instance
377
+ */
378
+ handleChannelMessage(channel: string, message: string, instanceId: string, timestamp?: number): void;
379
+ /**
380
+ * Flush buffered messages for a specific channel to its adapter.
381
+ * @param channel channel to flush
382
+ */
383
+ private flushChannel;
384
+ /**
385
+ * Flush all buffered messages across all channels.
386
+ */
387
+ flushAll(): Promise<void>;
388
+ /**
389
+ * Get persisted messages for a channel.
390
+ * @param channel channel to get messages for
391
+ * @param since optional cursor (timestamp or message id) to retrieve messages after
392
+ * @param limit maximum number of messages to retrieve
393
+ */
394
+ getMessages(channel: string, since?: string | number, limit?: number): Promise<PersistedMessage[]>;
395
+ /**
396
+ * Handles a record update for potential persistence
397
+ * @param recordId ID of the record
398
+ * @param value record value (will be stringified)
399
+ * @param version record version
400
+ */
401
+ handleRecordUpdate(recordId: string, value: any, version: number): void;
402
+ /**
403
+ * Flush all buffered records to storage
404
+ */
405
+ flushRecords(): Promise<void>;
406
+ /**
407
+ * Retrieve persisted records matching a pattern
408
+ * @param pattern pattern to match record IDs
409
+ * @returns array of persisted records
410
+ */
411
+ getPersistedRecords(pattern: string): Promise<PersistedRecord[]>;
412
+ /**
413
+ * Shutdown the persistence manager, flushing pending messages and closing adapters.
414
+ */
415
+ shutdown(): Promise<void>;
416
+ }
417
+
418
+ declare class RoomManager {
419
+ private redis;
420
+ constructor(options: {
421
+ redis: Redis$1;
202
422
  });
203
423
  private roomKey;
204
424
  private connectionsRoomKey;
@@ -334,7 +554,7 @@ declare class ConnectionManager {
334
554
  private localConnections;
335
555
  private roomManager;
336
556
  constructor(options: {
337
- redis: Redis;
557
+ redis: Redis$1;
338
558
  instanceId: string;
339
559
  roomManager: RoomManager;
340
560
  });
@@ -418,21 +638,21 @@ declare class RedisManager {
418
638
  * @returns The Redis client
419
639
  * @throws Error if Redis is not initialized
420
640
  */
421
- get redis(): Redis$1;
641
+ get redis(): Redis;
422
642
  /**
423
643
  * Gets the Redis client for publishing
424
644
  *
425
645
  * @returns The publishing Redis client
426
646
  * @throws Error if Redis is not initialized
427
647
  */
428
- get pubClient(): Redis$1;
648
+ get pubClient(): Redis;
429
649
  /**
430
650
  * Gets the Redis client for subscribing
431
651
  *
432
652
  * @returns The subscribing Redis client
433
653
  * @throws Error if Redis is not initialized
434
654
  */
435
- get subClient(): Redis$1;
655
+ get subClient(): Redis;
436
656
  /**
437
657
  * Disconnects all Redis clients
438
658
  */
@@ -475,7 +695,7 @@ declare class PresenceManager {
475
695
  private roomTTLs;
476
696
  private defaultTTL;
477
697
  constructor(options: {
478
- redis: Redis$1;
698
+ redis: Redis;
479
699
  roomManager: RoomManager;
480
700
  redisManager: RedisManager;
481
701
  enableExpirationEvents?: boolean;
@@ -548,111 +768,6 @@ declare class PresenceManager {
548
768
  cleanup(): Promise<void>;
549
769
  }
550
770
 
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
771
  declare class MeshServer extends WebSocketServer {
657
772
  readonly instanceId: string;
658
773
  private redisManager;
@@ -746,11 +861,11 @@ declare class MeshServer extends WebSocketServer {
746
861
  /**
747
862
  * Enables persistence for records matching the specified pattern.
748
863
  *
749
- * @param {ChannelPattern} pattern - The record ID pattern to enable persistence for.
864
+ * @param {RecordPersistencePattern} pattern - The record ID pattern to enable persistence for.
750
865
  * @param {RecordPersistenceOptions} [options] - Options for persistence.
751
866
  * @throws {Error} If persistence is not enabled for this server instance.
752
867
  */
753
- enableRecordPersistence(pattern: ChannelPattern$1, options?: RecordPersistenceOptions): void;
868
+ enableRecordPersistence(pattern: RecordPersistencePattern, options?: RecordPersistenceOptions): void;
754
869
  /**
755
870
  * Exposes a record or pattern for client subscriptions, optionally adding a guard function.
756
871
  *
@@ -1015,115 +1130,4 @@ declare class MessageStream extends EventEmitter$1 {
1015
1130
  }) => void): void;
1016
1131
  }
1017
1132
 
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
- restorePersistedRecords(): Promise<void>;
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 };
1133
+ export { type ChannelPattern$1 as ChannelPattern, Connection, ConnectionManager, MeshContext, MeshServer, type MeshServerOptions, MessageStream, type PersistenceAdapter, type PersistenceAdapterOptions, PersistenceManager, type PostgreSQLAdapterOptions, PostgreSQLPersistenceAdapter, PresenceManager, RecordManager, type RecordPersistencePattern, RoomManager, SQLitePersistenceAdapter, type SocketMiddleware };