playsocketjs 3.1.1 → 3.1.2

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.
@@ -2298,7 +2298,6 @@ class PlaySocketServer {
2298
2298
  if (formerRoom) {
2299
2299
  // If the room has no host (they were the only one and disconnected), restore them as host
2300
2300
  if (formerRoom.host === null) formerRoom.host = data.id;
2301
-
2302
2301
  if (this.#debug) console.log(`State sent for reconnection for room ${formerRoomId}:`, formerRoom.crdtManager.state);
2303
2302
  roomData = {
2304
2303
  state: formerRoom.crdtManager.state,
@@ -2334,7 +2333,7 @@ class PlaySocketServer {
2334
2333
 
2335
2334
  const newRoom = this.createRoom(data.initialStorage, data.size, ws.clientId); // Create room
2336
2335
 
2337
- // Check if client/creator is still connected and abort if not
2336
+ // Verify client is still connected and abort if not
2338
2337
  if (!this.#clients.has(ws.clientId)) {
2339
2338
  this.destroyRoom(newRoom.id);
2340
2339
  if (this.#debug) console.log(`Room creation cancelled - client ${ws.clientId} disconnected during event callback.`);
@@ -2363,6 +2362,12 @@ class PlaySocketServer {
2363
2362
  const joinAllowed = await this.#triggerEvent("clientJoinRequested", ws.clientId, roomId);
2364
2363
  if (joinAllowed === false || typeof joinAllowed === 'string') return rejectJoin(typeof joinAllowed === 'string' ? joinAllowed : 'Denied.');
2365
2364
 
2365
+ // Verify client is still connected and abort if not
2366
+ if (!this.#clients.has(ws.clientId)) {
2367
+ if (this.#debug) console.log(`Room join cancelled - client ${ws.clientId} disconnected during event callback.`);
2368
+ return;
2369
+ }
2370
+
2366
2371
  try {
2367
2372
  this.#joinRoom(ws.clientId, roomId);
2368
2373
  } catch (error) {
@@ -2578,7 +2583,7 @@ class PlaySocketServer {
2578
2583
  const oldRoomId = this.#clientRooms.get(clientId);
2579
2584
  const oldRoom = this.#rooms[oldRoomId];
2580
2585
  const targetRoom = this.#rooms[roomId];
2581
- if (!client) throw new Error("Client not found.");
2586
+ if (!client && !this.#pendingDisconnects.has(clientId)) throw new Error("Client not found.");
2582
2587
  if (!oldRoomId) throw new Error("Client is not in a room.");
2583
2588
  if (!oldRoom) throw new Error("Client room not found.");
2584
2589
  if (oldRoomId === roomId) throw new Error("Client is already in target room.");
@@ -2698,33 +2703,37 @@ class PlaySocketServer {
2698
2703
  const room = this.#rooms[roomId];
2699
2704
  const client = this.#clients.get(clientId);
2700
2705
  if (!room) throw new Error("Room not found.");
2701
- if (!client) throw new Error("Client not found.");
2706
+ if (!client && !this.#pendingDisconnects.has(clientId)) throw new Error("Client not found.");
2702
2707
  if (this.#clientRooms.get(clientId)) throw new Error("Already in a room.");
2703
2708
  if (room.participants.length >= room.size) throw new Error("Room full.");
2704
2709
 
2705
2710
  room.participants.push(clientId);
2706
2711
  this.#clientRooms.set(clientId, roomId);
2707
2712
 
2708
- // Notify joiner with initial storage
2709
- if (this.#debug) console.log("Room state sent for join:", room.crdtManager.state);
2710
- client.send(encode({
2711
- type: 'join_accepted',
2712
- roomId,
2713
- state: room.crdtManager.state,
2714
- participantCount: room.participants.length,
2715
- host: room.host,
2716
- version: this.#roomVersions.get(roomId)
2717
- }), { binary: true });
2713
+ // Notify joiner with initial storage (only if connected - pending disconnect clients get state on reconnect)
2714
+ if (client) {
2715
+ if (this.#debug) console.log("Room state sent for join:", room.crdtManager.state);
2716
+ client.send(encode({
2717
+ type: 'join_accepted',
2718
+ roomId,
2719
+ state: room.crdtManager.state,
2720
+ participantCount: room.participants.length,
2721
+ host: room.host,
2722
+ version: this.#roomVersions.get(roomId)
2723
+ }), { binary: true });
2724
+ }
2718
2725
 
2719
2726
  // If the room has no host (previous host disconnected and was the only participant), make joiner the host
2720
- // Since the room had to be empty, only the joiner needs to be notified
2727
+ // Set new host after join_accepted so hostMigrated event fires correctly on client
2721
2728
  const becameHost = room.host === null;
2722
2729
  if (becameHost) {
2723
- room.host = clientId;
2724
- client.send(encode({
2725
- type: 'host_migrated',
2726
- newHost: room.host,
2727
- }), { binary: true });
2730
+ room.host = clientId; // Change host
2731
+ if (client) {
2732
+ client.send(encode({
2733
+ type: 'host_migrated',
2734
+ newHost: room.host,
2735
+ }), { binary: true });
2736
+ }
2728
2737
  }
2729
2738
 
2730
2739
  // Notify existing participants
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "playsocketjs",
3
- "version": "3.1.1",
3
+ "version": "3.1.2",
4
4
  "description": "WebSocket wrapper for creating simple multiplayer systems with ease.",
5
5
  "type": "module",
6
6
  "module": "dist/playsocket-client.js",