playsocketjs 3.1.1 → 4.0.0

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.
@@ -0,0 +1,142 @@
1
+ import CRDTManager from "../universal/crdtManager.js";
2
+ export declare const RECONNECT_GRACE_PERIOD = 5000;
3
+ export type HttpServer = import("node:http").Server;
4
+ export type PropertyUpdateType = import("../universal/crdtManager.js").PropertyUpdateType;
5
+ export type PropertyUpdate = import("../universal/crdtManager.js").PropertyUpdate;
6
+ export type CRDTState = import("../universal/crdtManager.js").CRDTState;
7
+ export type WebSocket = import("ws").WebSocket;
8
+ export type ClientMessage = {
9
+ /**
10
+ * - Message type
11
+ */
12
+ type: string;
13
+ };
14
+ export type RateLimit = {
15
+ points: number;
16
+ lastReset: number;
17
+ };
18
+ export type Room = {
19
+ /**
20
+ * - Client IDs of the room participants
21
+ */
22
+ participants: string[];
23
+ /**
24
+ * - Client ID of the room host ("server" for server-owned rooms, null if the room currently has no host)
25
+ */
26
+ host: string | null;
27
+ /**
28
+ * - Max. number of participants
29
+ */
30
+ size: number;
31
+ /**
32
+ * - CRDT manager holding the room storage
33
+ */
34
+ crdtManager: CRDTManager;
35
+ };
36
+ /**
37
+ * @typedef {import("node:http").Server} HttpServer
38
+ * @typedef {import("../universal/crdtManager.js").PropertyUpdateType} PropertyUpdateType
39
+ * @typedef {import("../universal/crdtManager.js").PropertyUpdate} PropertyUpdate
40
+ * @typedef {import("../universal/crdtManager.js").CRDTState} CRDTState
41
+ */
42
+ /** @typedef {import("ws").WebSocket} WebSocket */ /**
43
+ * @typedef {object} ClientMessage
44
+ * @property {string} type - Message type
45
+ */
46
+ /** @typedef {{ points: number, lastReset: number }} RateLimit */
47
+ /**
48
+ * @typedef {object} Room
49
+ * @property {string[]} participants - Client IDs of the room participants
50
+ * @property {string | null} host - Client ID of the room host ("server" for server-owned rooms, null if the room currently has no host)
51
+ * @property {number} size - Max. number of participants
52
+ * @property {CRDTManager} crdtManager - CRDT manager holding the room storage
53
+ */
54
+ /**
55
+ * PlaySocket Server
56
+ */
57
+ export default class PlaySocketServer {
58
+ #private;
59
+ /**
60
+ * Create a new PlaySocketServer instance
61
+ * @param {object} options - Server configuration options
62
+ * @param {HttpServer} [options.server] - Existing http server
63
+ * @param {number} [options.port=3000] - Port to listen on (if no server provided)
64
+ * @param {string} [options.path='/'] - WebSocket endpoint path
65
+ * @param {boolean} [options.debug=false] - Enable debug logging
66
+ * @param {number} [options.rateLimit=20] - Maximum number of operations per second per client
67
+ * @param {import("ws").ServerOptions["verifyClient"]} [options.verifyClient] - Optional callback to verify client connections before upgrade. Receives (info, callback) where info contains { req, origin } and callback is (verified, code?, message?) => void
68
+ */
69
+ constructor(options?: {
70
+ server?: HttpServer;
71
+ port?: number;
72
+ path?: string;
73
+ debug?: boolean;
74
+ rateLimit?: number;
75
+ verifyClient?: import("ws").ServerOptions["verifyClient"];
76
+ });
77
+ /**
78
+ * Register an event callback
79
+ * @param {string} event - Event name
80
+ * @param {Function} callback - Callback function
81
+ * @returns {Function} - Unsubscribe
82
+ */
83
+ onEvent(event: string, callback: Function): Function;
84
+ /**
85
+ * Kick a client from the server
86
+ * @param {string} clientId - Client ID
87
+ * @param {string} [reason] - Optional reason
88
+ */
89
+ kick(clientId: string, reason?: string): void;
90
+ /**
91
+ * Move client into a different room
92
+ * @param {string} clientId - Client ID
93
+ * @param {string} roomId - Room ID (Target)
94
+ */
95
+ move(clientId: string, roomId: string): void;
96
+ /**
97
+ * Get snapshot of a room's storage
98
+ * @param {string} roomId - ID of the room to get the storage from
99
+ * @returns {Record<string, any> | undefined} - Storage object or undefined if the room doesn't exist
100
+ */
101
+ getRoomStorage(roomId: string): Record<string, any> | undefined;
102
+ /**
103
+ * Get the operation details from a storage update (e.g. in the "storageUpdateRequested" event)
104
+ * @param {PropertyUpdate} update - Property update
105
+ * @returns {{type: PropertyUpdateType | undefined, value: *, secondValue: *}} - Operation details
106
+ */
107
+ getUpdateDetails(update: PropertyUpdate): {
108
+ type: PropertyUpdateType | undefined;
109
+ value: any;
110
+ secondValue: any;
111
+ };
112
+ /**
113
+ * Update a value in a room's storage
114
+ * @param {string} roomId - Room ID
115
+ * @param {string} key - Storage key
116
+ * @param {PropertyUpdateType} type - Operation type
117
+ * @param {*} value - Value
118
+ * @param {*} [secondValue] - Second value (needed for some operations)
119
+ */
120
+ updateRoomStorage(roomId: string, key: string, type: PropertyUpdateType, value: any, secondValue?: any): void;
121
+ /**
122
+ * Create a room
123
+ * @param {object} [initialStorage] - Optional initial storage object
124
+ * @param {number} [size] - Max. room size, up to 500
125
+ * @param {string} [host] - Host ID, defaults to "server" (when set to "server", room will not be deleted if all clients leave)
126
+ * @returns {{ state: CRDTState, id: string }} Object containing room state and room ID
127
+ */
128
+ createRoom(initialStorage?: object, size?: number, host?: string): {
129
+ state: CRDTState;
130
+ id: string;
131
+ };
132
+ /**
133
+ * Destroy a room
134
+ * @param {string} roomId - Room ID
135
+ */
136
+ destroyRoom(roomId: string): void;
137
+ /**
138
+ * Close all client connections, then close the websocket and http server
139
+ */
140
+ stop(): void;
141
+ get rooms(): Record<string, Room>;
142
+ }
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Heartbeat ping interval in milliseconds
3
+ * Also used as the minimum age for CRDT garbage collection - operations are
4
+ * retained for at least one heartbeat cycle to ensure even slow clients can never
5
+ * be desynced as a result of gc
6
+ */
7
+ export declare const HEARTBEAT_INTERVAL = 5000;
@@ -0,0 +1,146 @@
1
+ export type PropertyUpdateType = "set" | "number-increment" | "array-add" | "array-add-unique" | "array-remove-matching" | "array-update-matching" | "object-set-key" | "object-remove-key";
2
+ export type VectorClockEntries = [string, number][];
3
+ export type OperationData = {
4
+ /**
5
+ * - Operation type
6
+ */
7
+ type: PropertyUpdateType;
8
+ /**
9
+ * - Value
10
+ */
11
+ value: any;
12
+ /**
13
+ * - Second value (needed for some operations)
14
+ */
15
+ secondValue?: any;
16
+ };
17
+ export type Operation = {
18
+ /**
19
+ * - Operation data
20
+ */
21
+ data: OperationData;
22
+ /**
23
+ * - Vector clock entries at creation time
24
+ */
25
+ vectorClock: VectorClockEntries;
26
+ /**
27
+ * - ID of the replica that created the operation
28
+ */
29
+ source: string;
30
+ /**
31
+ * - Unique operation ID
32
+ */
33
+ uuid: string;
34
+ };
35
+ export type PropertyUpdate = {
36
+ /**
37
+ * - Storage key
38
+ */
39
+ key: string;
40
+ /**
41
+ * - New operation
42
+ */
43
+ operation: Operation;
44
+ /**
45
+ * - Vector clock entries of the replica
46
+ */
47
+ vectorClock: VectorClockEntries;
48
+ };
49
+ export type CRDTState = {
50
+ /**
51
+ * - Operations per storage key
52
+ */
53
+ keyOperations: [string, Operation[]][];
54
+ /**
55
+ * - Vector clock entries
56
+ */
57
+ vectorClock: VectorClockEntries;
58
+ };
59
+ /** @typedef {"set" | "number-increment" | "array-add" | "array-add-unique" | "array-remove-matching" | "array-update-matching" | "object-set-key" | "object-remove-key"} PropertyUpdateType */
60
+ /** @typedef {[string, number][]} VectorClockEntries */
61
+ /**
62
+ * @typedef {object} OperationData
63
+ * @property {PropertyUpdateType} type - Operation type
64
+ * @property {*} value - Value
65
+ * @property {*} [secondValue] - Second value (needed for some operations)
66
+ */
67
+ /**
68
+ * @typedef {object} Operation
69
+ * @property {OperationData} data - Operation data
70
+ * @property {VectorClockEntries} vectorClock - Vector clock entries at creation time
71
+ * @property {string} source - ID of the replica that created the operation
72
+ * @property {string} uuid - Unique operation ID
73
+ */
74
+ /**
75
+ * @typedef {object} PropertyUpdate
76
+ * @property {string} key - Storage key
77
+ * @property {Operation} operation - New operation
78
+ * @property {VectorClockEntries} vectorClock - Vector clock entries of the replica
79
+ */
80
+ /**
81
+ * @typedef {object} CRDTState
82
+ * @property {[string, Operation[]][]} keyOperations - Operations per storage key
83
+ * @property {VectorClockEntries} vectorClock - Vector clock entries
84
+ */
85
+ /**
86
+ * CRDT Manager
87
+ * Custom conflict-free replicated data type system with vector clocks
88
+ */
89
+ export default class CRDTManager {
90
+ #private;
91
+ /**
92
+ * Create a new instance
93
+ * @param {boolean} [debug=false] - Enable debug logging
94
+ */
95
+ constructor(debug?: boolean);
96
+ /**
97
+ * Import the entire state of the CRDT manager (this overwrites the old state)
98
+ * @param {CRDTState} state - Full state of the CRDT manager
99
+ */
100
+ importState(state: CRDTState): void;
101
+ /**
102
+ * Import property update
103
+ * @param {PropertyUpdate} update - Property update
104
+ */
105
+ importPropertyUpdate(update: PropertyUpdate): void;
106
+ /**
107
+ * Revert a local property update by removing the operation and recomputing the affected key
108
+ * Should NOT be used on the server or for synced ops, only for reverting local optimistic updates
109
+ * @param {PropertyUpdate} update - Property update
110
+ */
111
+ revertPropertyUpdate(update: PropertyUpdate): void;
112
+ /**
113
+ * Update a property
114
+ * @param {string} key - Storage key
115
+ * @param {PropertyUpdateType} type - Operation type
116
+ * @param {*} value - Value
117
+ * @param {*} [secondValue] - Second value (needed for some operations)
118
+ * @returns {PropertyUpdate | undefined} - Returns the property update
119
+ */
120
+ updateProperty(key: string, type: PropertyUpdateType, value: any, secondValue?: any): PropertyUpdate | undefined;
121
+ /**
122
+ * Get property store
123
+ * @returns {Record<string, any>} - Object with key value pairs
124
+ */
125
+ get propertyStore(): Record<string, any>;
126
+ /**
127
+ * Check for changes in the local property store
128
+ * @returns {boolean} - Check if any values changed going from the last to the current property update
129
+ */
130
+ get didPropertiesChange(): boolean;
131
+ /**
132
+ * Export state (can be imported using importState, converts the maps to arrays for serialization)
133
+ * @returns {CRDTState} - State
134
+ */
135
+ get state(): CRDTState;
136
+ }
137
+ /**
138
+ * Get the operation details from a property update
139
+ * @param {PropertyUpdate} update - Property update
140
+ * @returns {{type: PropertyUpdateType | undefined, value: *, secondValue: *}} - Operation details
141
+ */
142
+ export declare function getUpdateDetails(update: PropertyUpdate): {
143
+ type: PropertyUpdateType | undefined;
144
+ value: any;
145
+ secondValue: any;
146
+ };