playsocketjs 1.0.9 → 1.0.11
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 +6 -55
- package/dist/playsocket-server.js +7 -41
- package/package.json +1 -1
|
@@ -254,17 +254,6 @@ class PlaySocket {
|
|
|
254
254
|
}
|
|
255
255
|
break;
|
|
256
256
|
|
|
257
|
-
case 'storage_operation':
|
|
258
|
-
if (message.key) {
|
|
259
|
-
const updatedArray = this.#handleArrayUpdate(message.key, message.operation, message.value, message.updateValue);
|
|
260
|
-
if (JSON.stringify(this.#storage[message.key]) !== JSON.stringify(updatedArray)) {
|
|
261
|
-
this.#storage[message.key] = updatedArray;
|
|
262
|
-
this.#storageTimestamps[message.key] = message.timestamp;
|
|
263
|
-
this.#triggerEvent("storageUpdated", { ...this.#storage });
|
|
264
|
-
}
|
|
265
|
-
}
|
|
266
|
-
break;
|
|
267
|
-
|
|
268
257
|
case 'client_disconnected':
|
|
269
258
|
this.#connectionCount = message.participantCount - 1; // Counted without the user themselves
|
|
270
259
|
this.#setHost(message.host);
|
|
@@ -366,7 +355,7 @@ class PlaySocket {
|
|
|
366
355
|
* @param {number} maxSize - Max number of participants
|
|
367
356
|
* @returns {Promise} Resolves with room ID
|
|
368
357
|
*/
|
|
369
|
-
createRoom(initialStorage = {}, maxSize) {
|
|
358
|
+
async createRoom(initialStorage = {}, maxSize) {
|
|
370
359
|
if (!this.#initialized) {
|
|
371
360
|
this.#triggerEvent("error", "Cannot create room - not initialized");
|
|
372
361
|
return Promise.reject(new Error("Not initialized"));
|
|
@@ -397,7 +386,7 @@ class PlaySocket {
|
|
|
397
386
|
* @param {string} roomId - ID of the room
|
|
398
387
|
* @returns {Promise} Resolves when connected
|
|
399
388
|
*/
|
|
400
|
-
joinRoom(roomId) {
|
|
389
|
+
async joinRoom(roomId) {
|
|
401
390
|
if (!this.#initialized) {
|
|
402
391
|
this.#triggerEvent("error", "Cannot join room - not initialized");
|
|
403
392
|
return Promise.reject(new Error("Not initialized"));
|
|
@@ -435,6 +424,7 @@ class PlaySocket {
|
|
|
435
424
|
value,
|
|
436
425
|
timestamp
|
|
437
426
|
});
|
|
427
|
+
// Optimistic update for regular storage updates
|
|
438
428
|
this.#storage[key] = value;
|
|
439
429
|
this.#storageTimestamps[key] = timestamp;
|
|
440
430
|
this.#triggerEvent("storageUpdated", { ...this.#storage });
|
|
@@ -448,54 +438,15 @@ class PlaySocket {
|
|
|
448
438
|
* @param {*} updateValue - New value for update-matching
|
|
449
439
|
*/
|
|
450
440
|
updateStorageArray(key, operation, value, updateValue) {
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
const timestamp = this.#getTimestamp();
|
|
441
|
+
// Send operation to server (no optimistic update – we can't guarantee that it is correct)
|
|
442
|
+
// If another client has sent an update to the server that is processed first, the end result will differ.
|
|
454
443
|
this.#sendToServer({
|
|
455
444
|
type: 'room_storage_array_update',
|
|
456
445
|
key,
|
|
457
446
|
operation,
|
|
458
447
|
value,
|
|
459
|
-
updateValue
|
|
460
|
-
timestamp
|
|
448
|
+
updateValue
|
|
461
449
|
});
|
|
462
|
-
this.#storage[key] = updatedArray;
|
|
463
|
-
this.#storageTimestamps[key] = timestamp;
|
|
464
|
-
this.#triggerEvent("storageUpdated", { ...this.#storage });
|
|
465
|
-
}
|
|
466
|
-
|
|
467
|
-
/**
|
|
468
|
-
* Handle array operations client-side
|
|
469
|
-
* @private
|
|
470
|
-
*/
|
|
471
|
-
#handleArrayUpdate(key, operation, value, updateValue) {
|
|
472
|
-
let array = (!this.#storage[key] || !Array.isArray(this.#storage[key])) ? [] : [...this.#storage[key]];
|
|
473
|
-
const isObject = typeof value === 'object' && value !== null;
|
|
474
|
-
const compare = (item) => isObject ? JSON.stringify(item) === JSON.stringify(value) : item === value;
|
|
475
|
-
|
|
476
|
-
switch (operation) {
|
|
477
|
-
case 'add':
|
|
478
|
-
array.push(value);
|
|
479
|
-
break;
|
|
480
|
-
|
|
481
|
-
case 'add-unique':
|
|
482
|
-
if (!array.some(compare)) array.push(value);
|
|
483
|
-
break;
|
|
484
|
-
|
|
485
|
-
case 'remove-matching':
|
|
486
|
-
array = array.filter(item => !compare(item));
|
|
487
|
-
break;
|
|
488
|
-
|
|
489
|
-
case 'update-matching':
|
|
490
|
-
const index = array.findIndex(compare);
|
|
491
|
-
if (index !== -1) array[index] = updateValue;
|
|
492
|
-
break;
|
|
493
|
-
|
|
494
|
-
default:
|
|
495
|
-
console.error(ERROR_PREFIX + `Unknown array operation: ${operation}`);
|
|
496
|
-
}
|
|
497
|
-
|
|
498
|
-
return array;
|
|
499
450
|
}
|
|
500
451
|
|
|
501
452
|
/**
|
|
@@ -214,7 +214,7 @@ function requireServer () {
|
|
|
214
214
|
if (data.timestamp > existingTimestamp && JSON.stringify(updateRoom.storage[data.key]) !== JSON.stringify(data.value)) {
|
|
215
215
|
updateRoom.storage[data.key] = data.value;
|
|
216
216
|
updateRoom.storageTimestamps[data.key] = data.timestamp;
|
|
217
|
-
this.#syncRoomStorageKey(
|
|
217
|
+
this.#syncRoomStorageKey(updateRoom, data.key, data.timestamp);
|
|
218
218
|
}
|
|
219
219
|
}
|
|
220
220
|
break;
|
|
@@ -227,8 +227,8 @@ function requireServer () {
|
|
|
227
227
|
const updatedArray = this.#arrayUpdate(arrayRoom.storage, data.key, data.operation, data.value, data.updateValue);
|
|
228
228
|
if (JSON.stringify(arrayRoom.storage[data.key]) !== JSON.stringify(updatedArray)) {
|
|
229
229
|
arrayRoom.storage[data.key] = updatedArray;
|
|
230
|
-
arrayRoom.storageTimestamps[data.key] =
|
|
231
|
-
this.#
|
|
230
|
+
arrayRoom.storageTimestamps[data.key] = Date.now();
|
|
231
|
+
this.#syncRoomStorageKey(arrayRoom, data.key, Date.now());
|
|
232
232
|
}
|
|
233
233
|
}
|
|
234
234
|
break;
|
|
@@ -284,52 +284,18 @@ function requireServer () {
|
|
|
284
284
|
/**
|
|
285
285
|
* Sync storage key with all clients in room
|
|
286
286
|
* @private
|
|
287
|
-
* @param {
|
|
288
|
-
* @param {string} requesterId - Client id of whom initiated the operation
|
|
287
|
+
* @param {Object} room
|
|
289
288
|
* @param {string} key
|
|
290
289
|
* @param {number} timestamp - In milliseconds
|
|
291
290
|
*/
|
|
292
|
-
#syncRoomStorageKey(
|
|
293
|
-
|
|
294
|
-
if (!room) return;
|
|
295
|
-
room.participants.forEach(p => {
|
|
296
|
-
if (p == requesterId) return; // Don't sync with the requester
|
|
291
|
+
#syncRoomStorageKey(room, key, timestamp) {
|
|
292
|
+
room?.participants?.forEach(p => {
|
|
297
293
|
const client = this.#clients.get(p);
|
|
298
294
|
if (client) {
|
|
299
295
|
client.send(JSON.stringify({
|
|
300
296
|
type: 'storage_sync',
|
|
301
297
|
key,
|
|
302
|
-
value: room
|
|
303
|
-
timestamp
|
|
304
|
-
}));
|
|
305
|
-
}
|
|
306
|
-
});
|
|
307
|
-
}
|
|
308
|
-
|
|
309
|
-
/**
|
|
310
|
-
* Sync storage operations with all clients in room
|
|
311
|
-
* @private
|
|
312
|
-
* @param {string} roomId
|
|
313
|
-
* @param {string} requesterId - Client id of whom initiated the operation
|
|
314
|
-
* @param {string} key
|
|
315
|
-
* @param {string} operation
|
|
316
|
-
* @param {*} value
|
|
317
|
-
* @param {*} updateValue
|
|
318
|
-
* @param {number} timestamp - In milliseconds
|
|
319
|
-
*/
|
|
320
|
-
#syncRoomStorageOperation(roomId, requesterId, key, operation, value, updateValue, timestamp) {
|
|
321
|
-
const room = this.#rooms[roomId];
|
|
322
|
-
if (!room) return;
|
|
323
|
-
room.participants.forEach(p => {
|
|
324
|
-
if (p == requesterId) return; // Don't send the operation to the requester
|
|
325
|
-
const client = this.#clients.get(p);
|
|
326
|
-
if (client) {
|
|
327
|
-
client.send(JSON.stringify({
|
|
328
|
-
type: 'storage_operation',
|
|
329
|
-
key,
|
|
330
|
-
operation,
|
|
331
|
-
value,
|
|
332
|
-
updateValue,
|
|
298
|
+
value: room?.storage?.[key],
|
|
333
299
|
timestamp
|
|
334
300
|
}));
|
|
335
301
|
}
|