{
  "version": 3,
  "sources": ["../../src/matchmaker/Lobby.ts"],
  "sourcesContent": ["import * as matchMaker from '../MatchMaker.ts';\n\nimport type { Room } from '../Room.ts';\nimport type { IRoomCache } from './driver.ts';\n\nconst LOBBY_CHANNEL = '$lobby';\n\n/*\n * TODO: refactor this on 1.0\n *\n * Some users might be relying on \"1\" = \"removed\" from the lobby due to this workaround: https://github.com/colyseus/colyseus/issues/617\n * Though, for consistency, we should invert as \"0\" = \"invisible\" and \"1\" = \"visible\".\n *\n * - rename \"removed\" to \"isVisible\" and swap the logic\n * - emit \"visibility-change\" with inverted value (isVisible)\n * - update \"subscribeLobby\" to check \"1\" as \"isVisible\" instead of \"removed\"\n */\n\nexport function updateLobby<T extends Room>(room: T, removed: boolean = false) {\n  const listing = room['_listing'];\n\n  if (listing.unlisted || !listing.roomId) {\n    return;\n  }\n\n  if (removed) {\n    matchMaker.presence.publish(LOBBY_CHANNEL, `${listing.roomId},1`);\n  } else if (!listing.private) {\n    matchMaker.presence.publish(LOBBY_CHANNEL, `${listing.roomId},0`);\n  }\n}\n\nexport async function subscribeLobby(callback: (roomId: string, roomListing: IRoomCache) => void) {\n  // Track removed roomIds to prevent race conditions where pending queries\n  // complete after a room has been removed\n  const removedRoomIds = new Set<string>();\n\n  const cb = async (message: string) => {\n    const [roomId, isRemove] = message.split(',');\n\n    if (isRemove === '1') {\n      // Mark as removed and process immediately\n      removedRoomIds.add(roomId);\n      callback(roomId, null);\n\n      // Clean up after a short timeout to prevent memory leaks\n      setTimeout(() => removedRoomIds.delete(roomId), 2000);\n\n    } else {\n      // Clear removed status - room might be coming back (e.g., visibility change)\n      removedRoomIds.delete(roomId);\n\n      const room = (await matchMaker.query({ roomId }))[0];\n\n      // Check if room was removed while we were querying\n      // See \"updating metadata should not cause race condition\" test in LobbyRoom.test.ts\n      if (removedRoomIds.has(roomId)) {\n        return;\n      }\n\n      callback(roomId, room);\n    }\n  };\n\n  await matchMaker.presence.subscribe(LOBBY_CHANNEL, cb);\n\n  return () => matchMaker.presence.unsubscribe(LOBBY_CHANNEL, cb);\n}\n"],
  "mappings": ";AAAA,YAAY,gBAAgB;AAK5B,IAAM,gBAAgB;AAaf,SAAS,YAA4B,MAAS,UAAmB,OAAO;AAC7E,QAAM,UAAU,KAAK,UAAU;AAE/B,MAAI,QAAQ,YAAY,CAAC,QAAQ,QAAQ;AACvC;AAAA,EACF;AAEA,MAAI,SAAS;AACX,IAAW,oBAAS,QAAQ,eAAe,GAAG,QAAQ,MAAM,IAAI;AAAA,EAClE,WAAW,CAAC,QAAQ,SAAS;AAC3B,IAAW,oBAAS,QAAQ,eAAe,GAAG,QAAQ,MAAM,IAAI;AAAA,EAClE;AACF;AAEA,eAAsB,eAAe,UAA6D;AAGhG,QAAM,iBAAiB,oBAAI,IAAY;AAEvC,QAAM,KAAK,OAAO,YAAoB;AACpC,UAAM,CAAC,QAAQ,QAAQ,IAAI,QAAQ,MAAM,GAAG;AAE5C,QAAI,aAAa,KAAK;AAEpB,qBAAe,IAAI,MAAM;AACzB,eAAS,QAAQ,IAAI;AAGrB,iBAAW,MAAM,eAAe,OAAO,MAAM,GAAG,GAAI;AAAA,IAEtD,OAAO;AAEL,qBAAe,OAAO,MAAM;AAE5B,YAAM,QAAQ,MAAiB,iBAAM,EAAE,OAAO,CAAC,GAAG,CAAC;AAInD,UAAI,eAAe,IAAI,MAAM,GAAG;AAC9B;AAAA,MACF;AAEA,eAAS,QAAQ,IAAI;AAAA,IACvB;AAAA,EACF;AAEA,QAAiB,oBAAS,UAAU,eAAe,EAAE;AAErD,SAAO,MAAiB,oBAAS,YAAY,eAAe,EAAE;AAChE;",
  "names": []
}
