playsocketjs 1.1.3 → 1.1.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/playsocket-client.js +9 -65
- package/dist/playsocket-server.js +6 -19
- package/package.json +1 -1
|
@@ -1731,9 +1731,9 @@ function requireCrdtManager () {
|
|
|
1731
1731
|
this.#propertyStore = {};
|
|
1732
1732
|
this.#lastPropertyStore = {};
|
|
1733
1733
|
|
|
1734
|
-
this.#keyOperations = new Map(keyOperations); // Rebuild the map
|
|
1735
|
-
this.#vectorClock = new Map(vectorClock); //
|
|
1736
|
-
if (!this.#vectorClock.has(this.#replicaId)) this.#vectorClock.set(this.#replicaId, 0); //
|
|
1734
|
+
this.#keyOperations = new Map(keyOperations); // Rebuild the operations map
|
|
1735
|
+
this.#vectorClock = new Map(vectorClock); // Rebuild the vector clock map
|
|
1736
|
+
if (!this.#vectorClock.has(this.#replicaId)) this.#vectorClock.set(this.#replicaId, 0); // Add own vector clock if it wasn't present in the imported state
|
|
1737
1737
|
|
|
1738
1738
|
// Map operation uuids to timestamp
|
|
1739
1739
|
this.#keyOperations.forEach((value, key) => {
|
|
@@ -2065,7 +2065,6 @@ class PlaySocket {
|
|
|
2065
2065
|
#connectionCount = 0;
|
|
2066
2066
|
#crdtManager;
|
|
2067
2067
|
#roomVersion = 0; // Update version (used to compare local vs. remote state to detect package loss)
|
|
2068
|
-
#sentUpdates = new Set(); // Contains update uuids
|
|
2069
2068
|
|
|
2070
2069
|
// Event handling
|
|
2071
2070
|
#callbacks = new Map(); // Event callbacks
|
|
@@ -2076,7 +2075,6 @@ class PlaySocket {
|
|
|
2076
2075
|
#pendingRegistration;
|
|
2077
2076
|
#pendingConnect;
|
|
2078
2077
|
#pendingReconnect;
|
|
2079
|
-
#pendingStateRequest;
|
|
2080
2078
|
|
|
2081
2079
|
// Timeouts or intervals
|
|
2082
2080
|
#reconnectTimeout;
|
|
@@ -2281,26 +2279,14 @@ class PlaySocket {
|
|
|
2281
2279
|
}
|
|
2282
2280
|
break;
|
|
2283
2281
|
|
|
2284
|
-
case 'state_sync':
|
|
2285
|
-
if (this.#pendingStateRequest) {
|
|
2286
|
-
if (this.#debug) console.log(LOG_PREFIX + "State received following state request:", message.state);
|
|
2287
|
-
this.#roomVersion = message.version;
|
|
2288
|
-
this.#crdtManager.importState(message.state);
|
|
2289
|
-
this.#triggerEvent("storageUpdated", this.getStorage);
|
|
2290
|
-
this.#triggerEvent("status", "State synchronized.");
|
|
2291
|
-
this.#pendingStateRequest.resolve();
|
|
2292
|
-
}
|
|
2293
|
-
break;
|
|
2294
|
-
|
|
2295
2282
|
case 'property_update':
|
|
2296
2283
|
this.#roomVersion++; // Increment room version
|
|
2297
2284
|
if (this.#debug) console.log(LOG_PREFIX + "Property update received:", message.update);
|
|
2298
|
-
this.#sentUpdates.delete(message.uuid); // If this is our sent update, delete it so that timeout check knows it was received
|
|
2299
2285
|
this.#crdtManager.importPropertyUpdate(message.update);
|
|
2300
2286
|
if (this.#crdtManager.didPropertiesChange) this.#triggerEvent("storageUpdated", this.getStorage);
|
|
2301
|
-
if (this.#roomVersion != message.version) {
|
|
2302
|
-
this.#triggerEvent("error", "Detected
|
|
2303
|
-
this.#
|
|
2287
|
+
if (this.#roomVersion != message.version && this.#initialized && this.#socket?.readyState === WebSocket.OPEN) {
|
|
2288
|
+
this.#triggerEvent("error", "Detected skipped update – forcing reconnect.");
|
|
2289
|
+
this.#socket?.close();
|
|
2304
2290
|
}
|
|
2305
2291
|
break;
|
|
2306
2292
|
|
|
@@ -2371,28 +2357,6 @@ class PlaySocket {
|
|
|
2371
2357
|
}
|
|
2372
2358
|
}
|
|
2373
2359
|
|
|
2374
|
-
/**
|
|
2375
|
-
* If the local state is out of sync, request the room state
|
|
2376
|
-
*/
|
|
2377
|
-
async #requestStateSync() {
|
|
2378
|
-
if (this.#pendingStateRequest) return; // Return if already requested
|
|
2379
|
-
try {
|
|
2380
|
-
await Promise.race([
|
|
2381
|
-
new Promise(async (resolve, reject) => {
|
|
2382
|
-
this.#pendingStateRequest = { resolve, reject };
|
|
2383
|
-
this.#sendToServer({ type: 'request_state' });
|
|
2384
|
-
}),
|
|
2385
|
-
this.#createTimeout("State request")
|
|
2386
|
-
]).finally(() => {
|
|
2387
|
-
this.#pendingStateRequest = null;
|
|
2388
|
-
});
|
|
2389
|
-
} catch (error) {
|
|
2390
|
-
if (!this.#initialized) return;
|
|
2391
|
-
this.#triggerEvent("error", "Failed to re-sync state: " + error.message);
|
|
2392
|
-
this.destroy();
|
|
2393
|
-
}
|
|
2394
|
-
}
|
|
2395
|
-
|
|
2396
2360
|
/**
|
|
2397
2361
|
* Update the host in case a new one was chosen
|
|
2398
2362
|
* @param {string} hostId - Client id of new host
|
|
@@ -2410,7 +2374,7 @@ class PlaySocket {
|
|
|
2410
2374
|
* @private
|
|
2411
2375
|
*/
|
|
2412
2376
|
#sendToServer(data) {
|
|
2413
|
-
if (!this.#socket || this.#socket
|
|
2377
|
+
if (!this.#socket || this.#socket?.readyState !== WebSocket.OPEN) {
|
|
2414
2378
|
return console.warn(WARNING_PREFIX + "Cannot send message - not connected.");
|
|
2415
2379
|
}
|
|
2416
2380
|
try {
|
|
@@ -2491,20 +2455,11 @@ class PlaySocket {
|
|
|
2491
2455
|
updateStorage(key, value) {
|
|
2492
2456
|
if (this.#debug) console.log(LOG_PREFIX + "Property set update for key '" + key + "':", value);
|
|
2493
2457
|
const propUpdate = this.#crdtManager.updateProperty(key, "set", value);
|
|
2494
|
-
const updateUuid = crypto.randomUUID();
|
|
2495
|
-
this.#sentUpdates.add(updateUuid);
|
|
2496
2458
|
this.#sendToServer({
|
|
2497
2459
|
type: 'property_update',
|
|
2498
2460
|
key,
|
|
2499
|
-
update: propUpdate
|
|
2500
|
-
uuid: updateUuid
|
|
2461
|
+
update: propUpdate
|
|
2501
2462
|
});
|
|
2502
|
-
setTimeout(() => {
|
|
2503
|
-
if (this.#initialized && this.#sentUpdates.has(updateUuid)) {
|
|
2504
|
-
this.#triggerEvent("error", "Sent update did not go through – requesting state.");
|
|
2505
|
-
this.#requestStateSync();
|
|
2506
|
-
}
|
|
2507
|
-
}, TIMEOUT_MS);
|
|
2508
2463
|
if (this.#crdtManager.didPropertiesChange) this.#triggerEvent("storageUpdated", this.getStorage); // Always trigger callback after send in case msgs are sent in the callback (which would break the order)
|
|
2509
2464
|
}
|
|
2510
2465
|
|
|
@@ -2518,20 +2473,11 @@ class PlaySocket {
|
|
|
2518
2473
|
updateStorageArray(key, operation, value, updateValue) {
|
|
2519
2474
|
if (this.#debug) console.log(LOG_PREFIX + `Property array update for key '${key}', operation '${operation}', value '${value}' and updateValue '${updateValue}'.`);
|
|
2520
2475
|
const propUpdate = this.#crdtManager.updateProperty(key, "array-" + operation, value, updateValue);
|
|
2521
|
-
const updateUuid = crypto.randomUUID();
|
|
2522
|
-
this.#sentUpdates.add(updateUuid);
|
|
2523
2476
|
this.#sendToServer({
|
|
2524
2477
|
type: 'property_update',
|
|
2525
2478
|
key,
|
|
2526
|
-
update: propUpdate
|
|
2527
|
-
uuid: updateUuid
|
|
2479
|
+
update: propUpdate
|
|
2528
2480
|
});
|
|
2529
|
-
setTimeout(() => {
|
|
2530
|
-
if (this.#initialized && this.#sentUpdates.has(updateUuid)) {
|
|
2531
|
-
this.#triggerEvent("error", "Sent update did not go through – requesting state.");
|
|
2532
|
-
this.#requestStateSync();
|
|
2533
|
-
}
|
|
2534
|
-
}, TIMEOUT_MS);
|
|
2535
2481
|
if (this.#crdtManager.didPropertiesChange) this.#triggerEvent("storageUpdated", this.getStorage);
|
|
2536
2482
|
}
|
|
2537
2483
|
|
|
@@ -2560,7 +2506,6 @@ class PlaySocket {
|
|
|
2560
2506
|
this.#isReconnecting = false;
|
|
2561
2507
|
this.#reconnectCount = 0;
|
|
2562
2508
|
this.#roomVersion = 0;
|
|
2563
|
-
this.#sentUpdates.clear();
|
|
2564
2509
|
|
|
2565
2510
|
// Reject timeouts if currently active
|
|
2566
2511
|
if (this.#pendingJoin) this.#pendingJoin.reject();
|
|
@@ -2568,7 +2513,6 @@ class PlaySocket {
|
|
|
2568
2513
|
if (this.#pendingRegistration) this.#pendingRegistration.reject();
|
|
2569
2514
|
if (this.#pendingConnect) this.#pendingConnect.reject();
|
|
2570
2515
|
if (this.#pendingReconnect) this.#pendingReconnect.reject();
|
|
2571
|
-
if (this.#pendingStateRequest) this.#pendingStateRequest.reject();
|
|
2572
2516
|
}
|
|
2573
2517
|
|
|
2574
2518
|
// Public getters
|
|
@@ -1857,9 +1857,9 @@ function requireCrdtManager () {
|
|
|
1857
1857
|
this.#propertyStore = {};
|
|
1858
1858
|
this.#lastPropertyStore = {};
|
|
1859
1859
|
|
|
1860
|
-
this.#keyOperations = new Map(keyOperations); // Rebuild the map
|
|
1861
|
-
this.#vectorClock = new Map(vectorClock); //
|
|
1862
|
-
if (!this.#vectorClock.has(this.#replicaId)) this.#vectorClock.set(this.#replicaId, 0); //
|
|
1860
|
+
this.#keyOperations = new Map(keyOperations); // Rebuild the operations map
|
|
1861
|
+
this.#vectorClock = new Map(vectorClock); // Rebuild the vector clock map
|
|
1862
|
+
if (!this.#vectorClock.has(this.#replicaId)) this.#vectorClock.set(this.#replicaId, 0); // Add own vector clock if it wasn't present in the imported state
|
|
1863
1863
|
|
|
1864
1864
|
// Map operation uuids to timestamp
|
|
1865
1865
|
this.#keyOperations.forEach((value, key) => {
|
|
@@ -2239,7 +2239,7 @@ function requireServer () {
|
|
|
2239
2239
|
ws.isAlive = false;
|
|
2240
2240
|
ws.ping();
|
|
2241
2241
|
});
|
|
2242
|
-
},
|
|
2242
|
+
}, 15000);
|
|
2243
2243
|
}
|
|
2244
2244
|
|
|
2245
2245
|
/**
|
|
@@ -2309,18 +2309,6 @@ function requireServer () {
|
|
|
2309
2309
|
}
|
|
2310
2310
|
break;
|
|
2311
2311
|
|
|
2312
|
-
case 'request_state':
|
|
2313
|
-
const stateRoomId = this.#clientRooms.get(ws.clientId);
|
|
2314
|
-
const stateRoom = stateRoomId ? this.#rooms[stateRoomId] : null;
|
|
2315
|
-
if (stateRoom) {
|
|
2316
|
-
ws.send(encode({
|
|
2317
|
-
type: 'state_sync',
|
|
2318
|
-
state: stateRoom.crdtManager.getState,
|
|
2319
|
-
version: this.#roomVersions.get(stateRoomId)
|
|
2320
|
-
}), { binary: true });
|
|
2321
|
-
}
|
|
2322
|
-
break;
|
|
2323
|
-
|
|
2324
2312
|
case 'create_room':
|
|
2325
2313
|
if (!ws.clientId) return;
|
|
2326
2314
|
const newRoomId = ws.clientId;
|
|
@@ -2400,7 +2388,7 @@ function requireServer () {
|
|
|
2400
2388
|
const updateRoomId = this.#clientRooms.get(ws.clientId);
|
|
2401
2389
|
const updateRoom = updateRoomId ? this.#rooms[updateRoomId] : null;
|
|
2402
2390
|
|
|
2403
|
-
if (updateRoom && data.key && data.update
|
|
2391
|
+
if (updateRoom && data.key && data.update) {
|
|
2404
2392
|
updateRoom.crdtManager.importPropertyUpdate(data.update);
|
|
2405
2393
|
|
|
2406
2394
|
// Increment version for this room
|
|
@@ -2414,8 +2402,7 @@ function requireServer () {
|
|
|
2414
2402
|
client.send(encode({
|
|
2415
2403
|
type: 'property_update',
|
|
2416
2404
|
update: data.update,
|
|
2417
|
-
version: currentVersion
|
|
2418
|
-
uuid: data.uuid
|
|
2405
|
+
version: currentVersion
|
|
2419
2406
|
}), { binary: true });
|
|
2420
2407
|
}
|
|
2421
2408
|
});
|