playsocketjs 2.6.2 → 2.6.4

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 CHANGED
@@ -226,7 +226,7 @@ new PlaySocket(options: PlaySocketServerOptions)
226
226
  | `onEvent()` | `event: string, callback: Function` | `void` | Register a server-side event callback |
227
227
  | `getRoomStorage()` | `roomId: string` | `object` | Get a snapshot of the current room storage |
228
228
  | `updateRoomStorage()` | `roomId: string, key: string, type: 'set' \| 'array-add' \| 'array-add-unique' \| 'array-remove-matching' \| 'array-update-matching', value: any, updateValue?: any` | `void` | Update a key in the shared room storage from the server |
229
- | `createRoom()` | `initialStorage?: object, size?: number, host?: string` | `Promise<object>` | Create a room (returns object containing room ID and state) – Rooms created with a non-player host like "server" (default) will not be deleted when the last participant leaves |
229
+ | `createRoom()` | `initialStorage?: object, size?: number, host?: string` | `object` | Create a room (returns object containing room ID and state) – Rooms created with a non-player host like "server" (default) will not be deleted when the last participant leaves |
230
230
  | `destroyRoom()` | `roomId: string` | `void` | Destroy a room & kick all participants |
231
231
 
232
232
  ### Event types
@@ -2257,6 +2257,9 @@ class PlaySocketServer {
2257
2257
  const formerRoomId = this.#clientRooms.get(data.id);
2258
2258
  const formerRoom = this.#rooms[formerRoomId];
2259
2259
  if (formerRoom) {
2260
+ // If the room has no host (they were the only one and disconnected), restore them as host
2261
+ if (formerRoom.host === null) formerRoom.host = data.id;
2262
+
2260
2263
  if (this.#debug) console.log(`State sent for reconnection for room ${formerRoomId}:`, formerRoom.crdtManager.getState);
2261
2264
  roomData = {
2262
2265
  state: formerRoom.crdtManager.getState,
@@ -2285,7 +2288,12 @@ class PlaySocketServer {
2285
2288
  }
2286
2289
 
2287
2290
  try {
2288
- const newRoom = await this.createRoom(data.initialStorage, data.size, ws.clientId);
2291
+ // Event callback with potential initial storage modifications
2292
+ const reviewedStorage = await this.#triggerEvent("roomCreationRequested", { clientId: ws.clientId, initialStorage: structuredClone({ ...data.initialStorage }) });
2293
+ if (typeof reviewedStorage === 'object') data.initialStorage = reviewedStorage;
2294
+ if (reviewedStorage === false) throw new Error("Room creation request denied.");
2295
+
2296
+ const newRoom = this.createRoom(data.initialStorage, data.size, ws.clientId); // Create room
2289
2297
 
2290
2298
  // Check if client/creator is still connected - abort if not
2291
2299
  if (!this.#clients.has(ws.clientId)) {
@@ -2334,6 +2342,17 @@ class PlaySocketServer {
2334
2342
  version: this.#roomVersions.get(roomId)
2335
2343
  }), { binary: true });
2336
2344
 
2345
+ // If the room has no host (previous host disconnected and was the only participant), make joiner the host
2346
+ // Since the room had to be empty, only the joiner needs to be notified
2347
+ const becameHost = room.host === null;
2348
+ if (becameHost) {
2349
+ room.host = ws.clientId;
2350
+ ws.send(encode({
2351
+ type: 'host_migrated',
2352
+ newHost: room.host,
2353
+ }), { binary: true });
2354
+ }
2355
+
2337
2356
  // Notify existing participants
2338
2357
  room.participants.forEach(p => {
2339
2358
  if (p === ws.clientId) return;
@@ -2422,18 +2441,21 @@ class PlaySocketServer {
2422
2441
  */
2423
2442
  #changeHostIfDisconnected(roomId, clientId) {
2424
2443
  const room = this.#rooms[roomId];
2425
- if (room && room.host === clientId && room.participants.length > 1) {
2444
+ if (room && room.host === clientId) {
2426
2445
  const participantsWithoutClient = room.participants.filter((e) => e !== clientId);
2427
- room.host = participantsWithoutClient[0]; // Set new host
2428
2446
 
2429
- // Inform all participants about the new host
2430
- participantsWithoutClient.forEach(p => {
2431
- const client = this.#clients.get(p);
2432
- if (client) client.send(encode({
2433
- type: 'host_migrated',
2434
- newHost: room.host,
2435
- }), { binary: true });
2436
- });
2447
+ if (participantsWithoutClient.length >= 1) {
2448
+ room.host = participantsWithoutClient[0]; // Set new host
2449
+
2450
+ // Inform all participants about the new host
2451
+ participantsWithoutClient.forEach(p => {
2452
+ const client = this.#clients.get(p);
2453
+ if (client) client.send(encode({
2454
+ type: 'host_migrated',
2455
+ newHost: room.host,
2456
+ }), { binary: true });
2457
+ });
2458
+ } else room.host = null; // The next person to join will become the host
2437
2459
  }
2438
2460
  }
2439
2461
 
@@ -2631,18 +2653,12 @@ class PlaySocketServer {
2631
2653
 
2632
2654
  /**
2633
2655
  * Create a room from the server
2634
- * @async
2635
2656
  * @param {object} [initialStorage] - Optional initial storage object
2636
2657
  * @param {number} [size] - Max. room size, up to 500
2637
2658
  * @param {string} [host] - Host ID, defaults to "server" (when set to "server", room will not be deleted if all clients leave)
2638
- * @returns {Promise<object>} Object containing room state and room ID
2659
+ * @returns {object} Object containing room state and room ID
2639
2660
  */
2640
- async createRoom(initialStorage, size, host = "server") {
2641
- // Event callback with potential initial storage modifications
2642
- const reviewedStorage = await this.#triggerEvent("roomCreationRequested", { clientId: host, initialStorage: structuredClone({ ...initialStorage }) });
2643
- if (typeof reviewedStorage === 'object') initialStorage = reviewedStorage;
2644
- if (reviewedStorage === false) throw new Error("Room creation denied.");
2645
-
2661
+ createRoom(initialStorage, size, host = "server") {
2646
2662
  let newRoomId;
2647
2663
 
2648
2664
  for (let i = 0; i < 100; i++) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "playsocketjs",
3
- "version": "2.6.2",
3
+ "version": "2.6.4",
4
4
  "description": "WebSocket wrapper for creating simple multiplayer systems with ease.",
5
5
  "type": "module",
6
6
  "module": "dist/playsocket-client.js",