playsocketjs 1.0.10 → 1.0.12

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.
@@ -17,11 +17,9 @@ class PlaySocket {
17
17
 
18
18
  // Room properties
19
19
  #storage = {}; // Shared storage object
20
- #storageTimestamps = {}; // Tracks update timestamps per key to ensure that not-yet synced updates don't get overwritten
21
20
  #roomHost;
22
21
  #roomId; // ID of the host (client only)
23
22
  #connectionCount = 0;
24
- #serverTimeOffset = 0; // Offset between server time and local time
25
23
 
26
24
  // Event handling
27
25
  #callbacks = new Map(); // Event callbacks
@@ -61,14 +59,6 @@ class PlaySocket {
61
59
  );
62
60
  }
63
61
 
64
- /**
65
- * Get synchronized timestamp
66
- * @private
67
- */
68
- #getTimestamp() {
69
- return Date.now() + this.#serverTimeOffset;
70
- }
71
-
72
62
  /**
73
63
  * Register an event callback
74
64
  * @param {string} event - Event name
@@ -119,8 +109,7 @@ class PlaySocket {
119
109
  this.#sendToServer({
120
110
  type: 'register',
121
111
  id: this.#id,
122
- customData: this.#customData || undefined,
123
- clientTime: Date.now()
112
+ customData: this.#customData || undefined
124
113
  });
125
114
  }),
126
115
  this.#createTimeout("Registration")
@@ -163,7 +152,6 @@ class PlaySocket {
163
152
  // Connected to room
164
153
  if (this.#pendingJoin) {
165
154
  this.#storage = message.storage;
166
- this.#storageTimestamps = message.storageTimestamps;
167
155
  this.#connectionCount = message.participantCount - 1; // Counted without the user themselves
168
156
  this.#roomHost = message.host;
169
157
  this.#triggerEvent("status", `Connected to room.`);
@@ -187,7 +175,6 @@ class PlaySocket {
187
175
  this.#reconnectCount = 0;
188
176
  if (message.roomData) {
189
177
  this.#storage = message.roomData.storage;
190
- this.#storageTimestamps = message.roomData.storageTimestamps;
191
178
  this.#connectionCount = message.roomData.participantCount - 1; // Counted without the user themselves
192
179
  this.#setHost(message.roomData.host);
193
180
  this.#triggerEvent("storageUpdated", { ...this.#storage });
@@ -233,9 +220,6 @@ class PlaySocket {
233
220
 
234
221
  case 'registered':
235
222
  if (this.#pendingRegistration) {
236
- const roundTripTime = Date.now() - message.clientTime;
237
- const serverTimeAtClientNow = message.serverTime + (roundTripTime / 2);
238
- this.#serverTimeOffset = serverTimeAtClientNow - Date.now();
239
223
  this.#sessionToken = message.sessionToken;
240
224
  this.#initialized = true;
241
225
  this.#pendingRegistration.resolve();
@@ -245,10 +229,8 @@ class PlaySocket {
245
229
 
246
230
  case 'storage_sync':
247
231
  if (message.key) {
248
- const localTimestamp = this.#storageTimestamps[message.key] || 0;
249
- if (message.timestamp > localTimestamp && JSON.stringify(this.#storage[message.key]) !== JSON.stringify(message.value)) {
232
+ if (JSON.stringify(this.#storage[message.key]) !== JSON.stringify(message.value)) {
250
233
  this.#storage[message.key] = message.value;
251
- this.#storageTimestamps[message.key] = message.timestamp;
252
234
  this.#triggerEvent("storageUpdated", { ...this.#storage });
253
235
  }
254
236
  }
@@ -417,16 +399,13 @@ class PlaySocket {
417
399
  */
418
400
  updateStorage(key, value) {
419
401
  if (JSON.stringify(this.#storage[key]) === JSON.stringify(value)) return; // Prevent updates without changes
420
- const timestamp = this.#getTimestamp();
421
402
  this.#sendToServer({
422
403
  type: 'room_storage_update',
423
404
  key,
424
- value,
425
- timestamp
405
+ value
426
406
  });
427
407
  // Optimistic update for regular storage updates
428
408
  this.#storage[key] = value;
429
- this.#storageTimestamps[key] = timestamp;
430
409
  this.#triggerEvent("storageUpdated", { ...this.#storage });
431
410
  }
432
411
 
@@ -440,14 +419,12 @@ class PlaySocket {
440
419
  updateStorageArray(key, operation, value, updateValue) {
441
420
  // Send operation to server (no optimistic update – we can't guarantee that it is correct)
442
421
  // If another client has sent an update to the server that is processed first, the end result will differ.
443
- const timestamp = this.#getTimestamp();
444
422
  this.#sendToServer({
445
423
  type: 'room_storage_array_update',
446
424
  key,
447
425
  operation,
448
426
  value,
449
- updateValue,
450
- timestamp
427
+ updateValue
451
428
  });
452
429
  }
453
430
 
@@ -472,8 +449,6 @@ class PlaySocket {
472
449
  clearTimeout(this.#reconnectTimeout);
473
450
  this.#roomHost = null;
474
451
  this.#storage = {};
475
- this.#storageTimestamps = {};
476
- this.#serverTimeOffset = 0;
477
452
  this.#roomId = null;
478
453
  this.#connectionCount = 0;
479
454
  this.#isReconnecting = false;
@@ -102,7 +102,7 @@ function requireServer () {
102
102
  this.#clients.set(data.id, ws);
103
103
  const sessionToken = this.#generateSessionToken();
104
104
  this.#clientTokens.set(data.id, sessionToken); // Token is used when reconnecting to prevent impersonation attacks
105
- ws.send(JSON.stringify({ type: 'registered', sessionToken, serverTime: Date.now(), clientTime: data.clientTime }));
105
+ ws.send(JSON.stringify({ type: 'registered', sessionToken }));
106
106
  this.#triggerEvent("clientRegistered", data.id, data.customData);
107
107
  break;
108
108
 
@@ -127,7 +127,6 @@ function requireServer () {
127
127
  if (formerRoom) {
128
128
  roomData = {
129
129
  storage: formerRoom.storage,
130
- storageTimestamps: formerRoom.storageTimestamps,
131
130
  participantCount: formerRoom.participants.length,
132
131
  host: formerRoom.participants[0]
133
132
  };
@@ -153,8 +152,7 @@ function requireServer () {
153
152
  this.#rooms[newRoomId] = {
154
153
  participants: [ws.clientId],
155
154
  maxSize: data.size || null,
156
- storage: data.storage || {},
157
- storageTimestamps: {},
155
+ storage: data.storage || {}
158
156
  };
159
157
 
160
158
  this.#clientRooms.set(ws.clientId, newRoomId);
@@ -186,7 +184,6 @@ function requireServer () {
186
184
  ws.send(JSON.stringify({
187
185
  type: 'join_accepted',
188
186
  storage: room.storage,
189
- storageTimestamps: room.storageTimestamps,
190
187
  participantCount: room.participants.length,
191
188
  host: room.participants[0]
192
189
  }));
@@ -210,11 +207,9 @@ function requireServer () {
210
207
  const updateRoomId = this.#clientRooms.get(ws.clientId);
211
208
  const updateRoom = updateRoomId ? this.#rooms[updateRoomId] : null;
212
209
  if (updateRoom && data.key) {
213
- const existingTimestamp = updateRoom.storageTimestamps[data.key] || 0;
214
- if (data.timestamp > existingTimestamp && JSON.stringify(updateRoom.storage[data.key]) !== JSON.stringify(data.value)) {
210
+ if (JSON.stringify(updateRoom.storage[data.key]) !== JSON.stringify(data.value)) {
215
211
  updateRoom.storage[data.key] = data.value;
216
- updateRoom.storageTimestamps[data.key] = data.timestamp;
217
- this.#syncRoomStorageKey(updateRoom, data.key, data.timestamp);
212
+ this.#syncRoomStorageKey(updateRoom, data.key, ws.clientId);
218
213
  }
219
214
  }
220
215
  break;
@@ -223,12 +218,10 @@ function requireServer () {
223
218
  const arrayRoomId = this.#clientRooms.get(ws.clientId);
224
219
  const arrayRoom = arrayRoomId ? this.#rooms[arrayRoomId] : null;
225
220
  if (arrayRoom && data.key) {
226
- // No timestamp check for array operations as they are designed to work unordered
227
221
  const updatedArray = this.#arrayUpdate(arrayRoom.storage, data.key, data.operation, data.value, data.updateValue);
228
222
  if (JSON.stringify(arrayRoom.storage[data.key]) !== JSON.stringify(updatedArray)) {
229
223
  arrayRoom.storage[data.key] = updatedArray;
230
- arrayRoom.storageTimestamps[data.key] = data.timestamp;
231
- this.#syncRoomStorageKey(arrayRoom, data.key, data.timestamp);
224
+ this.#syncRoomStorageKey(arrayRoom, data.key);
232
225
  }
233
226
  }
234
227
  break;
@@ -286,17 +279,17 @@ function requireServer () {
286
279
  * @private
287
280
  * @param {Object} room
288
281
  * @param {string} key
289
- * @param {number} timestamp - In milliseconds
282
+ * @param {string} exclude
290
283
  */
291
- #syncRoomStorageKey(room, key, timestamp) {
284
+ #syncRoomStorageKey(room, key, exclude) {
292
285
  room?.participants?.forEach(p => {
286
+ if (p === exclude) return;
293
287
  const client = this.#clients.get(p);
294
288
  if (client) {
295
289
  client.send(JSON.stringify({
296
290
  type: 'storage_sync',
297
291
  key,
298
- value: room?.storage?.[key],
299
- timestamp
292
+ value: room?.storage?.[key]
300
293
  }));
301
294
  }
302
295
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "playsocketjs",
3
- "version": "1.0.10",
3
+ "version": "1.0.12",
4
4
  "description": "WebSocket wrapper for creating simple multiplayer systems with ease.",
5
5
  "module": "dist/playsocket-client.js",
6
6
  "exports": {