playsocketjs 2.1.1 → 2.2.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.
- package/README.md +9 -1
- package/dist/playsocket-client.js +16 -16
- package/dist/playsocket-server.js +15 -7
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -72,6 +72,11 @@ socket.updateStorage('players', 'array-add-unique', { username: 'Player4', level
|
|
|
72
72
|
socket.updateStorage('latestPlayer', 'set', 'Player4'); // Regular synced storage update
|
|
73
73
|
```
|
|
74
74
|
|
|
75
|
+
Sending traditional requests to the server:
|
|
76
|
+
```javascript
|
|
77
|
+
socket.sendRequest('chosen-request-name', { fact: "You can build server-authoritative logic using this!" })
|
|
78
|
+
```
|
|
79
|
+
|
|
75
80
|
## API Reference
|
|
76
81
|
|
|
77
82
|
### Constructor
|
|
@@ -95,6 +100,7 @@ new PlaySocket(id?: string, options: PlaySocketOptions)
|
|
|
95
100
|
- `joinRoom(hostId: string)`: Join an existing room – Returns Promise (async)
|
|
96
101
|
- `destroy()`: Use this to leave a room and close the connection
|
|
97
102
|
- `updateStorage(key: string, type: 'set' | 'array-add' | 'array-add-unique' | 'array-remove-matching' | 'array-update-matching', value: any, updateValue?: any)`: Update the shared storage. Safely update arrays in storage by adding, removing, or updating items. UpdateValue is only required for the 'array-update-matching' operation type
|
|
103
|
+
- `sendRequest(name: string, data?: any)`: Send requests to the server with optional custom data (handle these in the `requestReceived` server event)
|
|
98
104
|
- `onEvent(event: string, callback: Function)`: Register an event callback
|
|
99
105
|
|
|
100
106
|
#### Event types
|
|
@@ -111,7 +117,7 @@ new PlaySocket(id?: string, options: PlaySocketOptions)
|
|
|
111
117
|
|
|
112
118
|
- `id`: Client's unique identifier on the WebSocket server
|
|
113
119
|
- `isHost`: If this user is currently assigned the host role
|
|
114
|
-
- `connectionCount`: Number of active client connections in room (without
|
|
120
|
+
- `connectionCount`: Number of active client connections in room (without yourself)
|
|
115
121
|
- `getStorage`: Retrieve storage object
|
|
116
122
|
|
|
117
123
|
|
|
@@ -210,12 +216,14 @@ Creates a new PlaySocket Server instance with configuration options.
|
|
|
210
216
|
#### Event types
|
|
211
217
|
|
|
212
218
|
- `clientRegistered`: Client registered with the server (returns the client's ID `string`, customData `object`)
|
|
219
|
+
- `clientRegistrationRequested`: Client requests to register (returns the client's ID `string`, customData `object`) – return `false` or a rejection reason `string` to block the registration
|
|
213
220
|
- `clientDisconnected`: Client disconnected from the server (returns the client's ID `string`)
|
|
214
221
|
- `clientJoinedRoom`: Client joined a room – note that clients can only leave by disconnecting (returns the client's ID `string`, room ID `string`)
|
|
215
222
|
- `roomCreated`: Client created a room (returns room ID `string`)
|
|
216
223
|
- `roomDestroyed`: Room was destroyed, this happens when all participants leave (returns room ID `string`)
|
|
217
224
|
- `roomCreationRequested`: Room creation requested by client (returns `object` containing the client's ID `string`, room ID `string` and the initialStorage `object`) – if you return an `object` in the callback, it will take that as the initial storage instead
|
|
218
225
|
- `storageUpdateRequested`: Room storage property update requested by client (returns `object` containing the client's ID `string`, room ID `string` and the update `object`) – if you return `false` in the callback, the update will be blocked
|
|
226
|
+
- `requestReceived`: Request from client was received by the server (returns `object` containing client's ID `string`, if in room – room ID `string`, request name `string` and optional passed data of type `any`)
|
|
219
227
|
|
|
220
228
|
### Properties (Read-only)
|
|
221
229
|
|
|
@@ -2227,6 +2227,22 @@ class PlaySocket {
|
|
|
2227
2227
|
if (!message.type) return;
|
|
2228
2228
|
|
|
2229
2229
|
switch (message.type) {
|
|
2230
|
+
case 'registration_failed':
|
|
2231
|
+
if (this.#pendingRegistration) {
|
|
2232
|
+
this.#pendingRegistration.reject(new Error("Failed to register: " + message.reason));
|
|
2233
|
+
this.#triggerEvent("error", "Failed to register: " + message.reason);
|
|
2234
|
+
}
|
|
2235
|
+
break;
|
|
2236
|
+
|
|
2237
|
+
case 'registered':
|
|
2238
|
+
if (this.#pendingRegistration) {
|
|
2239
|
+
this.#sessionToken = message.sessionToken;
|
|
2240
|
+
this.#initialized = true;
|
|
2241
|
+
this.#pendingRegistration.resolve(message.id);
|
|
2242
|
+
this.#triggerEvent("status", "Connected to server.");
|
|
2243
|
+
}
|
|
2244
|
+
break;
|
|
2245
|
+
|
|
2230
2246
|
case 'join_accepted':
|
|
2231
2247
|
// Connected to room
|
|
2232
2248
|
if (this.#pendingJoin) {
|
|
@@ -2293,22 +2309,6 @@ class PlaySocket {
|
|
|
2293
2309
|
}
|
|
2294
2310
|
break;
|
|
2295
2311
|
|
|
2296
|
-
case 'id_taken':
|
|
2297
|
-
if (this.#pendingRegistration) {
|
|
2298
|
-
this.#pendingRegistration.reject(new Error("This id is already in use"));
|
|
2299
|
-
this.#triggerEvent("error", "This id is taken.");
|
|
2300
|
-
}
|
|
2301
|
-
break;
|
|
2302
|
-
|
|
2303
|
-
case 'registered':
|
|
2304
|
-
if (this.#pendingRegistration) {
|
|
2305
|
-
this.#sessionToken = message.sessionToken;
|
|
2306
|
-
this.#initialized = true;
|
|
2307
|
-
this.#pendingRegistration.resolve(message.id);
|
|
2308
|
-
this.#triggerEvent("status", "Connected to server.");
|
|
2309
|
-
}
|
|
2310
|
-
break;
|
|
2311
|
-
|
|
2312
2312
|
case 'property_updated':
|
|
2313
2313
|
this.#roomVersion++; // Increment room version
|
|
2314
2314
|
if (this.#debug) console.log(LOG_PREFIX + "Property update received:", message.update);
|
|
@@ -2299,7 +2299,7 @@ function requireServer () {
|
|
|
2299
2299
|
case 'register':
|
|
2300
2300
|
// Register client ID if provided & check for a duplicate
|
|
2301
2301
|
if (data.id && this.#clients.get(data.id)) {
|
|
2302
|
-
ws.send(encode({ type: '
|
|
2302
|
+
ws.send(encode({ type: 'registration_failed', reason: 'ID is taken.' }), { binary: true });
|
|
2303
2303
|
return;
|
|
2304
2304
|
}
|
|
2305
2305
|
|
|
@@ -2315,11 +2315,20 @@ function requireServer () {
|
|
|
2315
2315
|
}
|
|
2316
2316
|
}
|
|
2317
2317
|
if (!data.id) {
|
|
2318
|
-
ws.send(encode({ type: '
|
|
2318
|
+
ws.send(encode({ type: 'registration_failed', reason: 'No available ID found.' }), { binary: true });
|
|
2319
2319
|
throw new Error('Failed to generate unique ID!');
|
|
2320
2320
|
}
|
|
2321
2321
|
}
|
|
2322
2322
|
|
|
2323
|
+
// Event callback
|
|
2324
|
+
const registrationAllowed = await this.#triggerEvent("clientRegistrationRequested", data.id, data.customData);
|
|
2325
|
+
if (registrationAllowed === false || typeof registrationAllowed === 'string') {
|
|
2326
|
+
ws.send(encode({
|
|
2327
|
+
type: 'registration_failed',
|
|
2328
|
+
reason: typeof registrationAllowed === 'string' ? registrationAllowed : 'Denied.'
|
|
2329
|
+
}), { binary: true });
|
|
2330
|
+
return;
|
|
2331
|
+
}
|
|
2323
2332
|
|
|
2324
2333
|
ws.clientId = data.id; // Adds the provided id to the ws object as clientId
|
|
2325
2334
|
this.#clients.set(data.id, ws);
|
|
@@ -2464,8 +2473,8 @@ function requireServer () {
|
|
|
2464
2473
|
|
|
2465
2474
|
if (updateRoom && data.update) {
|
|
2466
2475
|
// Check if update is allowed via event callback (provide clone to ensure update integrity)
|
|
2467
|
-
const
|
|
2468
|
-
if (
|
|
2476
|
+
const updateAllowed = await this.#triggerEvent("storageUpdateRequested", { roomId: updateRoomId, clientId: ws.clientId, update: structuredClone(data.update) });
|
|
2477
|
+
if (updateAllowed === false) {
|
|
2469
2478
|
ws.send(encode({
|
|
2470
2479
|
type: 'property_update_rejected',
|
|
2471
2480
|
state: updateRoom.crdtManager.getState
|
|
@@ -2638,7 +2647,7 @@ function requireServer () {
|
|
|
2638
2647
|
* @param {Function} callback - Callback function
|
|
2639
2648
|
*/
|
|
2640
2649
|
onEvent(event, callback) {
|
|
2641
|
-
const validEvents = ["clientRegistered", "clientDisconnected", "clientJoinedRoom", "roomCreationRequested", "requestReceived", "roomCreated", "storageUpdateRequested", "roomDestroyed"];
|
|
2650
|
+
const validEvents = ["clientRegistered", "clientRegistrationRequested", "clientDisconnected", "clientJoinedRoom", "roomCreationRequested", "requestReceived", "roomCreated", "storageUpdateRequested", "roomDestroyed"];
|
|
2642
2651
|
if (!validEvents.includes(event)) return console.warn(`Invalid PlaySocket event type "${event}"`);
|
|
2643
2652
|
if (!this.#callbacks.has(event)) this.#callbacks.set(event, []);
|
|
2644
2653
|
this.#callbacks.get(event).push(callback);
|
|
@@ -2669,8 +2678,7 @@ function requireServer () {
|
|
|
2669
2678
|
for (const callback of callbacks) {
|
|
2670
2679
|
try {
|
|
2671
2680
|
const result = await callback(...args);
|
|
2672
|
-
if (result
|
|
2673
|
-
if (typeof result === 'object') return result; // If response object is provided -> pass on
|
|
2681
|
+
if (result != null) return result; // Return any non-null/undefined result
|
|
2674
2682
|
} catch (error) {
|
|
2675
2683
|
console.error(`PlaySocket ${event} callback error:`, error);
|
|
2676
2684
|
}
|