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.
@@ -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
- const updatedArray = this.#handleArrayUpdate(key, operation, value, updateValue);
452
- if (JSON.stringify(this.#storage[key]) === JSON.stringify(updatedArray)) return; // Prevent updates without changes
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(updateRoomId, ws.clientId, data.key, data.timestamp);
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] = data.timestamp;
231
- this.#syncRoomStorageOperation(arrayRoomId, ws.clientId, data.key, data.operation, data.value, data.updateValue, data.timestamp);
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 {string} roomId
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(roomId, requesterId, key, timestamp) {
293
- const room = this.#rooms[roomId];
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.storage[key],
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
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "playsocketjs",
3
- "version": "1.0.9",
3
+ "version": "1.0.11",
4
4
  "description": "WebSocket wrapper for creating simple multiplayer systems with ease.",
5
5
  "module": "dist/playsocket-client.js",
6
6
  "exports": {