onelobby 0.6.0 → 0.7.0

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.
Files changed (45) hide show
  1. package/README.md +2 -2
  2. package/dist/direct/hub.d.ts +2 -0
  3. package/dist/direct/hub.js +20 -1
  4. package/dist/direct/hub.js.map +1 -1
  5. package/dist/friendly.d.ts +1 -0
  6. package/dist/friendly.js +2 -0
  7. package/dist/friendly.js.map +1 -1
  8. package/dist/index.d.ts +0 -2
  9. package/dist/index.js +0 -2
  10. package/dist/index.js.map +1 -1
  11. package/dist/lobby.d.ts +29 -1
  12. package/dist/lobby.js +26 -6
  13. package/dist/lobby.js.map +1 -1
  14. package/dist/nostr/limits.d.ts +2 -0
  15. package/dist/nostr/limits.js +2 -0
  16. package/dist/nostr/limits.js.map +1 -1
  17. package/dist/nostr/relays.js +11 -1
  18. package/dist/nostr/relays.js.map +1 -1
  19. package/dist/onelobby.bundle.js +10 -10
  20. package/dist/onelobby.bundle.js.map +4 -4
  21. package/dist/onelobby.bundle.mjs +10 -10
  22. package/dist/onelobby.bundle.mjs.map +4 -4
  23. package/dist/onelobby.d.ts +1 -1
  24. package/dist/onelobby.global.js +79 -19
  25. package/dist/onelobby.global.js.map +3 -3
  26. package/dist/onelobby.global.min.js +10 -10
  27. package/dist/onelobby.global.min.js.map +4 -4
  28. package/dist/onelobby.js +10 -1
  29. package/dist/onelobby.js.map +1 -1
  30. package/dist/signaling.d.ts +2 -0
  31. package/dist/signaling.js.map +1 -1
  32. package/dist/socket.d.ts +15 -6
  33. package/dist/socket.js.map +1 -1
  34. package/dist/testing.d.ts +2 -0
  35. package/dist/testing.js +18 -2
  36. package/dist/testing.js.map +1 -1
  37. package/dist/transport.d.ts +2 -0
  38. package/dist/transport.js.map +1 -1
  39. package/dist/webrtc.d.ts +5 -0
  40. package/dist/webrtc.js +21 -2
  41. package/dist/webrtc.js.map +1 -1
  42. package/package.json +1 -1
  43. package/dist/deprecated.d.ts +0 -18
  44. package/dist/deprecated.js +0 -11
  45. package/dist/deprecated.js.map +0 -1
package/dist/lobby.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"lobby.js","sourceRoot":"","sources":["../src/lobby.ts"],"names":[],"mappings":"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","sourcesContent":["import { Chat } from \"./chat.js\";\nimport type { IpCodeKind, JoinCodeKind } from \"./join-code-kind.js\";\nimport type { Clock } from \"./clock.js\";\nimport {\n CodecError,\n MAX_FRAME_BYTES,\n MODE_LOCKSTEP,\n MODE_RAW,\n PROTO,\n decodeMessage,\n encodeMessage,\n type Message,\n} from \"./codec.js\";\nimport { Reassembler, splitChunks } from \"./chunking.js\";\nimport { Emitter } from \"./emitter.js\";\nimport type { Hub } from \"./hub.js\";\nimport { Lockstep } from \"./lockstep.js\";\nimport { claimWinsWrapped, pickNewHost } from \"./migration.js\";\nimport { Pause } from \"./pause.js\";\nimport { OneLobbyError, type LobbyState, type PeerInfo, type SignalingClient, type ServerMsg } from \"./signaling.js\";\nimport type { ChannelName, IceServer, LinkFactory, PeerLink, SignalPayload } from \"./transport.js\";\nimport { Voice, type VoiceDeps } from \"./voice.js\";\nimport { hostConnections, joinerSocket, type LobbySocket, type LobbySocketOptions } from \"./socket.js\";\n\nexport type Phase = \"lobby\" | \"in_game\";\n/** The close code and reason a host chose with `kick()` / `disconnect()`, passed to the removed player's sockets. */\nexport interface CloseInfo {\n code?: number;\n reason?: string;\n}\n/** Options for `lobby.kick()`. */\nexport interface KickOptions {\n /** Default true: the player's address cannot rejoin this lobby while it lasts. false = `disconnect()`. */\n ban?: boolean;\n /** Close code for the player's `asWebSocket()` onclose: 1000 or 3000-4999. */\n code?: number;\n /** Close reason for that onclose, at most 120 characters. */\n reason?: string;\n}\nexport type Peer = PeerInfo;\n\n/** What a direct host's `joinCode` is: see {@link Lobby.joinCodeKind}. */\nexport type { JoinCodeKind };\n\nexport type LobbyEvents = {\n peerJoined: [Peer];\n /** The peer's data channels are open and the handshake is done: reliable sends reach it now (earlier ones were queued and flushed). */\n peerReady: [Peer];\n /** Joiner: the link to the host is open (the host itself is ready from the start). Also available as `lobby.ready`. */\n ready: [];\n /** reason \"left\", \"kicked\", \"disconnected\" (kick with ban false), \"timeout\", ...; `close` when the host gave one. */\n peerLeft: [Peer, reason: string, close?: CloseInfo];\n /**\n * Host only: a joiner never got its link to the host open (\"a friend could not connect\"). reason \"timeout\" when it is\n * not ready `readyTimeoutMs` after joining (it may still connect: `peerReady` then fires as usual), else the\n * `peerLeft` reason when it leaves before it was ready (a joiner's own `ice_failed` ends that way). Fires at most once\n * per peer, just before that `peerLeft`; not for peers the host kicks or disconnects.\n */\n peerFailed: [Peer, reason: string];\n joinRequested: [Peer];\n hostChanged: [hostId: number];\n phase: [Phase];\n message: [from: number, bytes: Uint8Array, channel: ChannelName];\n /** `close` is the code and reason the host gave when it removed this player (`kick()` / `disconnect()`). */\n sessionEnded: [reason: string, close?: CloseInfo];\n /** The signaling server went away. The game continues on the data channels (s.9). */\n serverLost: [];\n metaChanged: [Record<string, string>];\n /**\n * Direct-IP host only: the join code changed after `hostDirect` resolved, e.g. the router answered a later port-mapping\n * retry and the code went from \"same_network\" to \"internet\". Show the new code (and `joinUrl`).\n */\n joinCodeChanged: [code: string, kind: JoinCodeKind];\n /**\n * Browser host only (`kit.hostNostr`): the host tab went hidden (`true`) or visible again (`false`). Browsers throttle\n * timers in hidden tabs, so joiners may see lag or drop; ask the host to keep the tab visible.\n */\n hostHiddenChanged: [hidden: boolean];\n};\n\nexport interface LobbyConfig {\n signaling: SignalingClient;\n state: LobbyState;\n ice: IceServer[];\n links: LinkFactory;\n clock: Clock;\n wall: () => number;\n hashEveryTicks: number;\n relayOnly: boolean;\n voice: VoiceDeps;\n displayName: string;\n /**\n * Joiner: give up on reaching the host after this many ms (0 or absent: wait forever). When the ICE list has a\n * TURN server and the lobby is not relay-only already, the second half of the budget is a relay-only retry.\n * On failure `ready` rejects with OneLobbyError(\"ice_failed\"), the error is reported and the lobby is left.\n */\n readyTimeoutMs?: number;\n /**\n * Direct IP (docs/design/direct-ip.md): the hub lives in the host, so there is no migration. A joiner that loses the host\n * (link, peer_left, a host_changed from the hub as it shuts down, or the signaling socket) ends with \"host_left\".\n */\n direct?: boolean;\n /**\n * Treat a peer as gone after this many ms without hearing anything from it (0 or absent: off, and a silent peer\n * surfaces only when its link or signaling socket times out, about 30 s). Joiners ping the host every 2 s and the\n * host answers, so the host drops a silent joiner (`peerLeft`, \"timeout\") and a joiner handles a silent host as\n * lost (a direct lobby ends with \"host_left\"). Values under 6000 are raised to 6000.\n */\n peerTimeoutMs?: number;\n /** Host: per-peer cap on incoming raw messages; the excess is dropped before `message` fires or is relayed. */\n rateLimit?: RateLimit;\n}\n\n/** At most `messages` raw messages per peer in any `perMs` window (a fixed window, reset every `perMs`). */\nexport interface RateLimit {\n messages: number;\n perMs: number;\n}\n\n/** The smallest `peerTimeoutMs` honoured: three missed pings. */\nexport const MIN_PEER_TIMEOUT_MS = 6000;\n/** Host: how long a kicked / disconnected peer's link stays open for the hub's notice to reach it first. */\nexport const KICK_LINGER_MS = 3000;\n/** How long an offer held during a possible migration stays answerable. */\nconst HELD_OFFER_MS = 20_000;\n\n/** The name shown for a peer that chose none: \"Player N\", N = its seat (peer id, join order). */\nexport function seatName(p: PeerInfo): PeerInfo {\n const n = typeof p.name === \"string\" ? p.name.trim() : \"\";\n // \"Player\" is onelobby-server's stand-in for an empty name\n if (n && n !== \"Player\") return p;\n return { ...p, name: `Player ${p.peerId}` };\n}\n\nfunction hasRelay(ice: IceServer[]): boolean {\n return ice.some((s) => (Array.isArray(s.urls) ? s.urls : [s.urls]).some((u) => /^turns?:/i.test(String(u))));\n}\n\nconst HOST_WATCHDOG_MS = 250;\nconst PING_EVERY_MS = 2000;\n\n/** One joined lobby: roster, star of peer links, and the lockstep/chat/voice engines riding on them. */\nexport class Lobby extends Emitter<LobbyEvents> {\n readonly code: string;\n readonly mode: \"lockstep\" | \"raw\";\n readonly tickRate: number;\n readonly lockstep: Lockstep;\n readonly chat: Chat;\n /** The shared co-op pause (docs/recipes/pause.md). */\n readonly pause: Pause;\n readonly voice: Voice;\n\n localPeerId: number;\n hostPeerId: number;\n phase: Phase;\n meta: Record<string, string>;\n /** The lobby's name as the server keeps it (host()'s `name`, sanitised); \"\" if the server sends none. */\n name: string;\n resumeToken: string;\n /** Last measured round trip to the host in ms (joiners), or 0. */\n rtt = 0;\n /**\n * Direct-IP host only (onelobby/direct): the code friends paste to join, e.g. \"6B01-RGFE-P2B\" (docs/design/direct-ip.md\n * s.2a). Show it with joinCodeKind. Empty when the machine has no IPv4 address, and on joiners.\n */\n joinCode = \"\";\n /**\n * \"nostr\": a version 1 code that works through public Nostr relays (spec/nostr-signaling.md; the default for a direct\n * host). \"internet\": the router forwarded the port and the code carries its public address; \"same_network\": the LAN\n * address. \"none\": no code.\n */\n joinCodeKind: JoinCodeKind = \"none\";\n /**\n * Direct-IP host only: the IP code (address and port, version 0), with `directCodeKind` \"internet\" or \"same_network\".\n * Equal to `joinCode` when Nostr is off; otherwise the code to hand out for LAN play or when the router port is open.\n */\n directCode = \"\";\n directCodeKind: IpCodeKind = \"none\";\n /** Direct-IP host only: this machine's addresses with the port, for an \"Advanced\" fold-out. */\n directAddresses: string[] = [];\n /** Direct-IP host only: how the router port-open went (\"UPnP\", \"no UPnP gateway answered; ...\", \"off\"). */\n portMapping = \"\";\n /** Direct-IP host only: the one startup line (bound port, join code, port mapping); see `formatHostLog` in onelobby/direct. */\n directHostLog = \"\";\n\n /** Browser host only (`kit.hostNostr`): true while the host tab is hidden (see the `hostHiddenChanged` event). */\n hostHidden = false;\n\n /** @internal kit.hostNostr: the tab's visibility changed. */\n setHostHidden(hidden: boolean): void {\n if (this.hostHidden === hidden) return;\n this.hostHidden = hidden;\n this.emit(\"hostHiddenChanged\", hidden);\n }\n\n /** @internal onelobby/direct: fires `joinCodeChanged` with the current code. */\n notifyJoinCodeChanged(): void {\n this.emit(\"joinCodeChanged\", this.joinCode, this.joinCodeKind);\n }\n\n private signaling: SignalingClient;\n private cfg: LobbyConfig;\n private roster = new Map<number, Peer>();\n private links = new Map<number, PeerLink>();\n /** ICE from a peer that has no link yet: its candidates can overtake its offer (node-datachannel). */\n private earlyIce = new Map<number, SignalPayload[]>();\n /** Offers from roster members that arrived while the host link was open (see offerVerdict), by sender. */\n private heldOffers = new Map<number, { payload: SignalPayload; at: number }>();\n private connected = new Set<number>(); // host: peers that said hi\n private hiSentTo = new Set<PeerLink>();\n private epoch = 0;\n private ended = false;\n private serverUp = true;\n private cancelWatchdog: (() => void) | null = null;\n private cancelPing: (() => void) | null = null;\n private pingN = 0;\n private chunkId = 1;\n private reassemblers = new Map<number, Reassembler>();\n private hub: Hub;\n private outbox = new Map<number, { msg: Message; route: number; channel?: ChannelName }[]>();\n private markReady: () => void = () => {};\n private failReady: (e: Error) => void = () => {};\n private isReady = false;\n private cancelReadyTimer: (() => void) | null = null;\n private relayRetry = false;\n /** clock.now() of the last frame from each peer (peerTimeoutMs). */\n private lastHeard = new Map<number, number>();\n /** Host: links of kicked / disconnected peers, kept open briefly (removePeer `linger`). */\n private readonly lingering = new Set<PeerLink>();\n /** Host: joiners that joined but are not ready yet, with the cancel of their readyTimeoutMs timer (peerFailed). */\n private notReady = new Map<number, () => void>();\n /** Host: per-peer fixed window for rateLimit. */\n private rate = new Map<number, { start: number; n: number }>();\n /**\n * Resolves when this peer can exchange data: immediately for the host, once the link to the host is open for a\n * joiner. Rejects with OneLobbyError(\"ice_failed\") when the joiner cannot reach the host in `readyTimeoutMs`\n * (or with \"closed\"/\"kicked\" when the lobby ends first; \"closed\" also when the host disconnected it).\n */\n readonly ready: Promise<void> = new Promise<void>((res, rej) => {\n this.markReady = () => {\n if (this.isReady) return;\n this.isReady = true;\n this.cancelReadyTimer?.();\n this.cancelReadyTimer = null;\n res();\n };\n this.failReady = rej;\n });\n\n constructor(cfg: LobbyConfig) {\n super();\n this.cfg = cfg;\n this.signaling = cfg.signaling;\n const st = cfg.state;\n this.code = st.code;\n this.mode = st.mode;\n this.tickRate = st.tickRate;\n this.localPeerId = st.you;\n this.hostPeerId = st.hostId;\n this.phase = st.phase;\n this.meta = { ...st.meta };\n this.name = st.name ?? \"\";\n this.resumeToken = st.resumeToken;\n for (const p of st.peers) this.roster.set(p.peerId, seatName(p));\n this.ready.catch(() => {}); // a rejection is also reported through errorSink; awaiting `ready` stays optional\n\n const self = this;\n this.hub = {\n get clock() { return self.cfg.clock; },\n get localPeerId() { return self.localPeerId; },\n get hostPeerId() { return self.hostPeerId; },\n get isHost() { return self.isHost; },\n get tickRate() { return self.tickRate; },\n connectedPeers: () => self.connectedPeerIds(),\n sendTo: (peerId, msg, route, channel) => self.sendTo(peerId, msg, route ?? 0, channel),\n sendToHost: (msg, route, channel) => {\n if (!self.isHost) self.sendTo(self.hostPeerId, msg, route ?? 0, channel);\n },\n dropPeer: (peerId, reason) => self.dropPeer(peerId, reason),\n reportError: (e) => self.reportError(e),\n nextChunkId: () => self.chunkId++ >>> 0,\n };\n\n this.lockstep = new Lockstep(this.hub, { hashEveryTicks: cfg.hashEveryTicks });\n this.chat = new Chat(this.hub, cfg.wall, (id) => this.voice.isMutedPeer(id));\n this.voice = new Voice(this.hub, cfg.voice);\n this.pause = new Pause(this.hub, {\n phase: () => this.phase,\n hold: (held) => this.lockstep.hold(held),\n hasPeer: (id) => this.roster.has(id),\n });\n this.lockstep.on(\"started\", () => this.setPhase(\"in_game\"));\n this.lockstep.on(\"error\", (e) => this.reportError(e));\n\n this.signaling.onMessage = (m) => this.onSignaling(m);\n this.signaling.onClose = () => this.onServerClosed();\n\n if (this.isHost) this.markReady();\n else this.armReadyTimer();\n if (this.isHost && this.mode === \"lockstep\") {\n if (this.phase === \"in_game\") this.lockstep.hostStart();\n else this.lockstep.hostIdle();\n }\n this.cancelWatchdog = cfg.clock.setInterval(() => this.watchdog(), HOST_WATCHDOG_MS);\n this.cancelPing = cfg.clock.setInterval(() => this.pingHost(), PING_EVERY_MS);\n }\n\n // ---- state -----------------------------------------------------------------------------------------------------\n\n get isHost(): boolean {\n return this.localPeerId === this.hostPeerId;\n }\n get peers(): Peer[] {\n return [...this.roster.values()].sort((a, b) => a.peerId - b.peerId);\n }\n peer(peerId: number): Peer | undefined {\n return this.roster.get(peerId);\n }\n /** Peers whose link is open and handshake done (host: the ready joiners; joiner: the host once ready). */\n get connectedPeers(): number[] {\n return this.connectedPeerIds();\n }\n\n /**\n * Joiner: the link to the host as a WebSocket-shaped object (text by default), so WebSocket client code runs\n * unchanged. It opens when `ready` resolves and closes when the session ends (`host_left` gives code 1001).\n */\n asWebSocket(opts?: LobbySocketOptions): LobbySocket {\n return joinerSocket(this, opts);\n }\n\n /** Host: `handler(conn)` once per joiner (a WebSocket-shaped connection), the server-side mirror of asWebSocket(). */\n onConnection(handler: (conn: LobbySocket) => void, opts?: LobbySocketOptions): () => void {\n return hostConnections(this, handler, opts);\n }\n\n set snapshotChunkSize(n: number) {\n this.lockstep.chunkSize = n;\n }\n\n /** Current migration epoch (0 until the first host change). */\n get hostEpoch(): number {\n return this.epoch;\n }\n\n /** @internal Host role: create the link to `peerId` and start negotiating (adapters and tests). */\n _offer(peerId: number): PeerLink {\n this.offerTo(peerId);\n return this.links.get(peerId)!;\n }\n\n /** @internal Joiner role: create the answering link to `peerId` (adapters and tests). */\n _answer(peerId: number): PeerLink {\n return this.makeLink(peerId);\n }\n\n /** @internal Called by OneLobby right after construction: the host waits for joiners, a joiner waits for the host's offer. */\n _begin(): void {\n /* joiners are passive until the host offers; hosts create links on peer_joined */\n }\n\n // ---- game-facing actions ---------------------------------------------------------------------------------------\n\n async start(): Promise<void> {\n if (!this.isHost) throw new Error(\"only the host can start the game\");\n if (this.phase === \"in_game\") return;\n this.signaling.send({ t: \"phase\", phase: \"in_game\" });\n this.setPhase(\"in_game\");\n if (this.mode === \"lockstep\") this.lockstep.hostStart();\n }\n\n async setMeta(meta: Record<string, string>): Promise<void> {\n if (!this.isHost) throw new Error(\"only the host can set metadata\");\n this.meta = { ...meta };\n this.signaling.send({ t: \"meta\", meta });\n this.emit(\"metaChanged\", this.meta);\n }\n\n /**\n * Host: removes a player. By default it is a ban: the hub refuses that player's address for the rest of this lobby\n * (a new tab or a reload included). `{ ban: false }` is `disconnect()`. `code` / `reason` reach the player's\n * `asWebSocket()` onclose (and `sessionEnded`'s second argument); without them its socket closes with 4000 \"kicked\".\n */\n async kick(peerId: number, opts: KickOptions = {}): Promise<void> {\n if (!this.isHost) throw new Error(\"only the host can kick\");\n const { ban = true, code, reason } = opts;\n if (code !== undefined && !(code === 1000 || (Number.isInteger(code) && code >= 3000 && code <= 4999)))\n throw new RangeError(\"close code must be 1000 or 3000-4999\");\n if (reason !== undefined && reason.length > 120) throw new RangeError(\"close reason must be at most 120 characters\");\n const msg: Record<string, unknown> = { t: \"kick\", peerId };\n if (!ban) msg.ban = false;\n if (code !== undefined) msg.closeCode = code;\n if (reason !== undefined) msg.closeReason = reason;\n this.signaling.send(msg as { t: \"kick\"; peerId: number });\n const close: CloseInfo | undefined = code !== undefined || reason !== undefined ? { code, reason } : undefined;\n this.removePeer(peerId, ban ? \"kicked\" : \"disconnected\", close, true);\n }\n\n /**\n * Host: ends one player's connection without a ban, like a server closing one WebSocket. The player's\n * `asWebSocket()` gets onclose with `code` (default 1000) and `reason` (default \"disconnected\"), its lobby ends with\n * `sessionEnded(\"disconnected\")`, and it may join again (a new tab, a reload). Same as `kick(peerId, { ban: false, code, reason })`.\n */\n disconnect(peerId: number, code?: number, reason?: string): Promise<void> {\n return this.kick(peerId, { ban: false, code, reason });\n }\n\n async approve(peerId: number, ok: boolean): Promise<void> {\n if (!this.isHost) throw new Error(\"only the host can approve joins\");\n this.signaling.send({ t: \"approve\", peerId, ok });\n }\n\n async leave(): Promise<void> {\n if (this.ended) return;\n this.signaling.send({ t: \"leave\" });\n this.teardown(\"left\");\n }\n\n /** raw mode (and any extra game data): to one peer. */\n send(peerId: number, bytes: Uint8Array, opts: { channel?: \"reliable\" | \"fast\" } = {}): void {\n const channel = opts.channel ?? \"reliable\";\n if (this.isHost) this.sendTo(peerId, { type: \"raw\", bytes }, this.localPeerId, channel);\n else this.sendTo(this.hostPeerId, { type: \"raw\", bytes }, peerId, channel);\n }\n\n /** To everyone else in the lobby. */\n broadcast(bytes: Uint8Array, opts: { channel?: \"reliable\" | \"fast\" } = {}): void {\n const channel = opts.channel ?? \"reliable\";\n if (this.isHost) {\n // peers whose channels are not open yet get reliable broadcasts queued and flushed in order\n for (const p of this.roster.keys()) if (p !== this.localPeerId) this.sendTo(p, { type: \"raw\", bytes }, this.localPeerId, channel);\n } else {\n this.sendTo(this.hostPeerId, { type: \"raw\", bytes }, 0, channel);\n }\n }\n\n // ---- sending ---------------------------------------------------------------------------------------------------\n\n private channelFor(msg: Message): ChannelName {\n if (msg.type === \"voice\") return \"voice\";\n if (msg.type === \"ping\" || msg.type === \"pong\") return \"fast\";\n return \"reliable\";\n }\n\n private sendTo(peerId: number, msg: Message, route: number, channel?: ChannelName): void {\n const link = this.links.get(peerId);\n const ch0 = channel ?? this.channelFor(msg);\n const queueable = msg.type === \"raw\" || msg.type === \"chat\" || msg.type === \"cmd\";\n // game data to a host-side peer waits for its `hi`; protocol messages only need the link\n const ready = !!link?.isOpen && (!queueable || !this.isHost || this.connected.has(peerId));\n if (!ready) {\n // Reliable game data for a peer that is in the roster (or is the host) but not connected yet waits for its handshake.\n const known = this.roster.has(peerId) || peerId === this.hostPeerId;\n if (queueable && ch0 === \"reliable\" && known && !this.ended) {\n let q = this.outbox.get(peerId);\n if (!q) this.outbox.set(peerId, (q = []));\n if (q.length >= 1000) q.shift();\n q.push({ msg, route, channel });\n }\n return;\n }\n if (!link) return;\n try {\n const ch = ch0;\n let bytes: Uint8Array;\n try {\n bytes = encodeMessage(msg, route);\n } catch (e) {\n if (!(e instanceof CodecError) || e.code !== \"too_long\") throw e;\n bytes = encodeMessage(msg, route, true);\n }\n if (bytes.length > MAX_FRAME_BYTES) {\n // Oversized frame: send the whole inner frame as a chunk set (spec/binary.md \"Large non-snapshot frames\").\n for (const c of splitChunks(this.chunkId++ >>> 0, bytes)) link.send(ch, encodeMessage(c, route));\n } else {\n link.send(ch, bytes);\n }\n } catch (e) {\n this.reportError(e instanceof Error ? e : new Error(String(e)));\n }\n }\n\n private connectedPeerIds(): number[] {\n if (this.isHost) return [...this.connected].filter((id) => this.links.get(id)?.isOpen).sort((a, b) => a - b);\n const l = this.links.get(this.hostPeerId);\n return l?.isOpen ? [this.hostPeerId] : [];\n }\n\n private reportError(e: Error): void {\n this.errorSink?.(e);\n }\n /** @internal set by OneLobby so lobby errors reach `kit.on(\"error\")`. */\n errorSink: ((e: Error) => void) | null = null;\n /** @internal set by OneLobby: the server issued a new resume token (rememberSeat). */\n seatSink: ((token: string) => void) | null = null;\n\n // ---- joiner connect timeout -------------------------------------------------------------------------------------\n\n private armReadyTimer(): void {\n const total = this.cfg.readyTimeoutMs ?? 0;\n if (!(total > 0)) return;\n const canRelay = !this.cfg.relayOnly && hasRelay(this.cfg.ice);\n const first = canRelay ? Math.ceil(total / 2) : total;\n this.cancelReadyTimer = this.cfg.clock.setTimeout(() => {\n if (this.isReady || this.ended) return;\n if (canRelay) this.retryRelayed(total - first);\n else this.giveUpConnecting();\n }, first);\n }\n\n /** The direct attempt stalled: dial the host ourselves through the TURN relay (a host answers any offer). */\n private retryRelayed(budget: number): void {\n this.relayRetry = true;\n const link = this.makeLink(this.hostPeerId, true);\n link.startOffer();\n this.cancelReadyTimer = this.cfg.clock.setTimeout(() => {\n if (!this.isReady && !this.ended) this.giveUpConnecting();\n }, budget);\n }\n\n private giveUpConnecting(): void {\n const err = new OneLobbyError(\"ice_failed\", `could not open a connection to the host${this.relayRetry ? \" (direct or relayed)\" : \"\"}`);\n this.failReady(err);\n this.reportError(err);\n if (this.ended) return;\n this.signaling.send({ t: \"leave\" });\n this.teardown(\"ice_failed\");\n }\n\n // ---- links -----------------------------------------------------------------------------------------------------\n\n /** @internal A direct host's hub learns where each joiner's link comes from (Nostr kick bans the address too). */\n linkAddressSink: ((peerId: number, ip: string) => void) | null = null;\n\n private makeLink(peerId: number, relayOnly = this.cfg.relayOnly): PeerLink {\n const old = this.links.get(peerId);\n if (old) {\n old.onClose = null;\n old.onMessage = null;\n old.close();\n }\n const link = this.cfg.links.create({ remoteId: peerId, iceServers: this.cfg.ice, relayOnly });\n this.links.set(peerId, link);\n link.onSignal = (s) => this.signaling.send({ t: \"signal\", to: peerId, ...s });\n link.onOpen = () => this.onLinkOpen(peerId, link);\n link.onClose = (reason) => this.onLinkClosed(peerId, link, reason);\n link.onMessage = (ch, bytes) => this.onData(peerId, ch, bytes);\n link.onPath = (path) => this.signaling.send({ t: \"path\", path });\n link.onRemoteAddress = (ip) => this.linkAddressSink?.(peerId, ip);\n return link;\n }\n\n /** Host side: offer to a joiner. */\n private offerTo(peerId: number): void {\n const link = this.makeLink(peerId);\n link.startOffer();\n }\n\n private onLinkOpen(peerId: number, link: PeerLink): void {\n if (this.isHost) {\n // Joiner speaks first (`hi`). After a migration the new host announces itself so the joiner knows who won.\n if (this.epoch > 0) this.sendTo(peerId, { type: \"host_claim\", epoch: this.epoch, hostId: this.localPeerId, tick: this.lockstep.lastTick }, 0);\n return;\n }\n if (peerId === this.hostPeerId) this.sendHi(link);\n // else: an unexpected offerer; wait for its host_claim before trusting it\n }\n\n private sendHi(link: PeerLink): void {\n if (this.hiSentTo.has(link)) return;\n this.hiSentTo.add(link);\n this.lockstep.touch();\n link.send(\"reliable\", encodeMessage(this.lockstep.hiMessage(this.localPeerId)));\n this.markReady();\n this.emit(\"ready\");\n this.emit(\"peerReady\", this.roster.get(link.remoteId) ?? { peerId: link.remoteId, name: \"\" });\n this.flush(link.remoteId);\n }\n\n private onLinkClosed(peerId: number, link: PeerLink, _reason: string): void {\n if (this.links.get(peerId) !== link) return; // replaced\n this.links.delete(peerId);\n this.hiSentTo.delete(link);\n if (this.ended) return;\n if (this.isHost) {\n this.connected.delete(peerId);\n this.lockstep.onPeerLeft(peerId);\n this.voice.onPeerLeft(peerId);\n // The server announces the departure; if it is gone, drop the peer ourselves.\n if (!this.serverUp && this.roster.has(peerId)) this.removePeer(peerId, \"timeout\");\n } else if (peerId === this.hostPeerId) {\n // Never connected yet (ICE failed): not a host loss. The ready timer retries over the relay or gives up.\n if (!this.isReady && this.cancelReadyTimer) return;\n this.handleHostLost(\"link closed\");\n }\n }\n\n // ---- data channel dispatch -------------------------------------------------------------------------------------\n\n private onData(from: number, channel: ChannelName, bytes: Uint8Array, reassembled = false): void {\n let d;\n try {\n d = decodeMessage(bytes, reassembled);\n } catch (e) {\n this.reportError(e instanceof Error ? e : new Error(String(e)));\n return;\n }\n if (!d) return;\n // The topology is a star: a joiner hears only its host. Anything else over some other link (a peer that offered to\n // us, or a member that dialled us) is not host traffic and must not reach raw / lockstep / pause / chat handling.\n if (!this.isHost && from !== this.hostPeerId && d.msg.type !== \"host_claim\") return;\n if (!reassembled) this.lastHeard.set(from, this.cfg.clock.now());\n const { msg, route } = d;\n switch (msg.type) {\n case \"hi\":\n if (this.isHost) this.onHi(from, msg.lastTick);\n break;\n case \"welcome_dc\":\n if (!this.isHost) {\n if (msg.hostId !== this.hostPeerId) this.setHost(msg.hostId);\n this.lockstep.touch();\n }\n break;\n case \"cmd\": case \"frame\": case \"hash\": case \"desync\":\n case \"snapshot_req\": case \"snapshot\":\n if (from === this.hostPeerId || this.isHost) this.lockstep.handle(from, msg);\n break;\n case \"chunk\": {\n if (reassembled) break; // a chunk set never nests another\n let r = this.reassemblers.get(from);\n if (!r) this.reassemblers.set(from, (r = new Reassembler()));\n let whole;\n try {\n whole = r.push(msg);\n } catch (e) {\n this.reportError(e instanceof Error ? e : new Error(String(e)));\n break;\n }\n if (!whole) break;\n if (this.lockstep.snapshotPending && from === this.hostPeerId) this.lockstep.onSnapshotPayload(whole);\n else this.onData(from, channel, whole, true); // an oversized inner frame\n break;\n }\n case \"chat\": case \"chat_history\": case \"chat_reject\":\n this.chat.handle(from, route, msg);\n break;\n case \"pause_request\": case \"pause_state\": case \"pause_refuse\":\n this.pause.handle(from, msg);\n break;\n case \"voice\":\n if (channel === \"voice\") this.voice.handle(from, route, msg); // a voice frame on another channel is ignored\n break;\n case \"raw\":\n this.onRaw(from, route, msg.bytes, channel);\n break;\n case \"ping\":\n this.sendTo(from, { type: \"pong\", n: msg.n, t: msg.t }, 0, \"fast\");\n break;\n case \"pong\":\n this.rtt = Math.max(0, (this.cfg.clock.now() >>> 0) - msg.t);\n break;\n case \"host_claim\":\n this.onHostClaim(from, msg.epoch, msg.hostId);\n break;\n }\n }\n\n private onHi(from: number, lastTick: number): void {\n this.connected.add(from);\n this.notReady.get(from)?.();\n this.notReady.delete(from);\n this.sendTo(from, {\n type: \"welcome_dc\",\n // the tick the snapshot will carry (the game's applied tick), so welcome_dc.tick == snapshot.tick even when\n // the game loop has not yet consumed every emitted frame; 0 before the game starts\n tick: this.mode === \"lockstep\" ? this.lockstep.currentTick : 0,\n tickRate: this.tickRate,\n mode: this.mode === \"lockstep\" ? MODE_LOCKSTEP : MODE_RAW,\n hostId: this.localPeerId,\n }, 0);\n this.chat.sendHistory(from);\n this.pause.sendState(from);\n if (this.mode === \"lockstep\") this.lockstep.onPeerHi(from, lastTick);\n this.emit(\"peerReady\", this.roster.get(from) ?? { peerId: from, name: \"\" });\n this.flush(from);\n }\n\n private flush(peerId: number): void {\n const q = this.outbox.get(peerId);\n if (!q) return;\n this.outbox.delete(peerId);\n for (const m of q) this.sendTo(peerId, m.msg, m.route, m.channel);\n }\n\n private onRaw(from: number, route: number, bytes: Uint8Array, channel: ChannelName): void {\n if (!this.isHost) {\n this.emit(\"message\", route, bytes, channel);\n return;\n }\n if (!this.allowRaw(from)) return;\n if (route === 0 || route === this.localPeerId) {\n this.emit(\"message\", from, bytes, channel);\n }\n if (route === 0) {\n for (const p of this.connectedPeerIds()) if (p !== from) this.sendTo(p, { type: \"raw\", bytes }, from, channel);\n } else if (route !== this.localPeerId) {\n this.sendTo(route, { type: \"raw\", bytes }, from, channel);\n }\n }\n\n private allowRaw(from: number): boolean {\n const lim = this.cfg.rateLimit;\n if (!lim || !(lim.messages > 0) || !(lim.perMs > 0)) return true;\n const now = this.cfg.clock.now();\n let w = this.rate.get(from);\n if (!w || now - w.start >= lim.perMs) this.rate.set(from, (w = { start: now, n: 0 }));\n return ++w.n <= lim.messages;\n }\n\n // ---- migration -------------------------------------------------------------------------------------------------\n\n private setHost(hostId: number): void {\n if (hostId === this.hostPeerId) return;\n this.hostPeerId = hostId;\n this.emit(\"hostChanged\", hostId);\n const held = this.heldOffers.get(hostId);\n if (held) {\n this.heldOffers.delete(hostId);\n if (this.cfg.clock.now() - held.at <= HELD_OFFER_MS) void this.acceptOffer(hostId, held.payload);\n }\n }\n\n /** The host is gone (link closed, no frames for 3 s, or the server said so): run the s.9 rule. */\n private handleHostLost(reason: string): void {\n if (this.isHost || this.ended) return;\n if (this.cfg.direct) {\n this.teardown(\"host_left\");\n return;\n }\n const failed = this.hostPeerId;\n const gone = this.roster.get(failed);\n if (gone) {\n this.roster.delete(failed);\n this.emit(\"peerLeft\", gone, reason === \"link closed\" ? \"timeout\" : reason);\n }\n const old = this.links.get(failed);\n if (old) {\n old.onClose = null;\n old.onMessage = null;\n old.close();\n this.links.delete(failed);\n this.hiSentTo.delete(old);\n }\n const candidate = pickNewHost([...this.roster.keys(), this.localPeerId], failed) ?? this.localPeerId;\n if (candidate === this.localPeerId) this.becomeHost();\n // else: wait for the candidate's host_claim (or the server's host_changed); it offers to us and we answer with hi\n this.replayHeldOffers();\n }\n\n /** Offers that came from roster members while the host link was still open: now the host is lost, answer them. */\n private replayHeldOffers(): void {\n const now = this.cfg.clock.now();\n for (const [from, held] of [...this.heldOffers]) {\n this.heldOffers.delete(from);\n if (now - held.at <= HELD_OFFER_MS && this.roster.has(from)) void this.acceptOffer(from, held.payload);\n }\n }\n\n private becomeHost(): void {\n this.epoch = (this.epoch + 1) & 0xffff;\n this.hostPeerId = this.localPeerId;\n this.markReady();\n this.connected.clear();\n this.hiSentTo.clear();\n this.lastHeard.clear(); // joiners spoke to the old host; their clocks start when they say hi to us\n this.lockstep.becomeHost();\n this.pause.onBecameHost();\n this.emit(\"hostChanged\", this.localPeerId);\n if (this.serverUp) this.signaling.send({ t: \"host_changed\", hostId: this.localPeerId, epoch: this.epoch });\n for (const p of this.roster.keys()) {\n if (p !== this.localPeerId) this.offerTo(p);\n }\n }\n\n private onHostClaim(from: number, epoch: number, hostId: number): void {\n if (hostId !== from) return; // a claim is a peer claiming itself; nobody claims for someone else\n const mine = { epoch: this.epoch, hostId: this.hostPeerId };\n const theirs = { epoch, hostId };\n if (hostId === this.hostPeerId && epoch === this.epoch && !this.isHost) {\n const l = this.links.get(from);\n if (l) this.sendHi(l);\n return;\n }\n if (!claimWinsWrapped(theirs, mine)) return; // we hold the better claim\n const wasHost = this.isHost;\n this.epoch = epoch;\n if (wasHost) {\n // We lose: demote. Everyone else will be offered to by the winner.\n for (const [id, l] of this.links) {\n if (id === from) continue;\n l.onClose = null;\n l.onMessage = null;\n l.close();\n this.links.delete(id);\n }\n this.connected.clear();\n this.lockstep.becomeJoiner();\n }\n this.setHost(hostId);\n const link = this.links.get(from);\n if (link && from === hostId) this.sendHi(link);\n }\n\n // ---- signaling -------------------------------------------------------------------------------------------------\n\n private onSignaling(m: ServerMsg): void {\n switch (m.t) {\n case \"peer_joined\": {\n if (!m.peer || this.roster.has((m.peer as Peer).peerId)) return;\n const peer = seatName(m.peer as Peer);\n this.roster.set(peer.peerId, peer);\n this.emit(\"peerJoined\", peer);\n if (this.isHost) {\n this.watchReady(peer.peerId);\n this.offerTo(peer.peerId);\n }\n break;\n }\n case \"peer_left\":\n this.removePeer(Number(m.peerId), String(m.reason ?? \"left\"));\n break;\n case \"host_changed\": {\n if (this.cfg.direct) {\n // the hub promotes a joiner as the host leaves; in direct mode the hub is going with it\n if (!this.isHost) this.teardown(\"host_left\");\n break;\n }\n const id = Number(m.hostId);\n if (typeof m.epoch === \"number\" && m.epoch > this.epoch) this.epoch = m.epoch & 0xffff;\n if (id === this.hostPeerId) break;\n if (id === this.localPeerId && !this.isHost) {\n const failed = this.hostPeerId;\n this.roster.delete(failed);\n this.becomeHost();\n } else {\n this.setHost(id);\n }\n break;\n }\n case \"join_request\":\n this.emit(\"joinRequested\", seatName(m.peer as Peer));\n break;\n case \"lobby\": {\n const st = m as unknown as LobbyState;\n this.meta = { ...st.meta };\n if (st.name) this.name = st.name;\n if (st.resumeToken && st.resumeToken !== this.resumeToken) {\n this.resumeToken = st.resumeToken;\n this.seatSink?.(this.resumeToken);\n }\n this.roster = new Map(st.peers.map((p) => [p.peerId, seatName(p)]));\n if (st.hostId !== this.hostPeerId && !this.isHost) this.setHost(st.hostId);\n this.setPhase(st.phase);\n break;\n }\n case \"meta\":\n this.meta = { ...(m.meta as Record<string, string>) };\n this.emit(\"metaChanged\", this.meta);\n break;\n case \"phase\":\n this.setPhase(m.phase as Phase);\n break;\n case \"signal\":\n void this.onSignal(Number(m.from), m as unknown as SignalPayload);\n break;\n case \"error\":\n if (m.code === \"kicked\") {\n const d = (m.data ?? {}) as { ban?: unknown; closeCode?: unknown; closeReason?: unknown };\n const close: CloseInfo = {};\n if (typeof d.closeCode === \"number\") close.code = d.closeCode;\n if (typeof d.closeReason === \"string\") close.reason = d.closeReason;\n this.teardown(d.ban === false ? \"disconnected\" : \"kicked\", close.code !== undefined || close.reason !== undefined ? close : undefined);\n }\n else this.reportError(new OneLobbyError(String(m.code), String(m.msg ?? \"\"), m.data as Record<string, unknown> | undefined));\n break;\n }\n }\n\n private async onSignal(from: number, s: SignalPayload): Promise<void> {\n let link = this.links.get(from);\n const payload: SignalPayload = {};\n if (s.sdp) payload.sdp = s.sdp;\n if (s.ice) payload.ice = s.ice;\n if (s.sdp?.type === \"offer\") {\n // We are the answerer. An offer comes from the (new) host, so a peer may dial us only as that rule allows.\n const verdict = this.offerVerdict(from);\n if (verdict === \"hold\") {\n if (this.heldOffers.size < 64 || this.heldOffers.has(from)) this.heldOffers.set(from, { payload, at: this.cfg.clock.now() });\n } else if (verdict === \"accept\") await this.acceptOffer(from, payload);\n return;\n }\n if (!link) {\n if (!payload.ice || this.ended || !this.roster.has(from)) return;\n if (this.cfg.direct && from !== this.hostPeerId) return;\n const q = this.earlyIce.get(from) ?? [];\n if (q.length < 64) q.push(payload);\n this.earlyIce.set(from, q);\n return;\n }\n await link.handleSignal(payload);\n }\n\n /**\n * Whether an SDP offer from `from` may be answered. The host (or a joiner's host) always may. Direct lobbies have no\n * migration, so nobody else. In a server lobby a roster member may dial us when we are the host (a claim race decides\n * who wins) or when our own link to the host is gone (the migration window); while that link is open the offer is\n * held, to be answered if the host turns out to be lost a moment later.\n */\n private offerVerdict(from: number): \"accept\" | \"hold\" | \"drop\" {\n if (this.ended || from === this.localPeerId) return \"drop\";\n if (!this.isHost && from === this.hostPeerId) return \"accept\";\n if (this.cfg.direct || !this.roster.has(from)) return \"drop\";\n if (this.isHost) return \"accept\";\n if (!this.isReady) return \"drop\"; // still joining: only the host's own offer is expected\n return this.links.get(this.hostPeerId)?.isOpen ? \"hold\" : \"accept\";\n }\n\n private async acceptOffer(from: number, payload: SignalPayload): Promise<void> {\n const link = this.makeLink(from);\n const early = this.earlyIce.get(from) ?? [];\n this.earlyIce.delete(from);\n // the link holds candidates until the offer is set, so hand them over right behind it\n const done = link.handleSignal(payload);\n for (const e of early) void link.handleSignal(e);\n await done;\n }\n\n /**\n * `linger` (host kick / disconnect): stop using the peer's link at once but leave it open until that peer closes it\n * or KICK_LINGER_MS pass. The hub tells the peer over its WebSocket; closing the data link first would make it look\n * like the host vanished (a migration and a 1001 instead of the host's close code).\n */\n private removePeer(peerId: number, reason: string, close?: CloseInfo, linger = false): void {\n const peer = this.roster.get(peerId);\n if (peerId === this.localPeerId) {\n this.teardown(reason === \"kicked\" ? \"kicked\" : reason);\n return;\n }\n if (peer) this.roster.delete(peerId);\n this.earlyIce.delete(peerId);\n const cancelWatch = this.notReady.get(peerId);\n if (cancelWatch) {\n cancelWatch();\n this.notReady.delete(peerId);\n if (peer && reason !== \"kicked\" && reason !== \"disconnected\") this.emit(\"peerFailed\", peer, reason);\n }\n const link = this.links.get(peerId);\n if (link && peerId !== this.hostPeerId) {\n link.onMessage = null;\n this.links.delete(peerId);\n this.hiSentTo.delete(link);\n if (linger) {\n this.lingering.add(link);\n const done = () => {\n if (!this.lingering.delete(link)) return;\n cancel();\n link.onClose = null;\n link.close();\n };\n const cancel = this.cfg.clock.setTimeout(done, KICK_LINGER_MS);\n link.onClose = done;\n } else {\n link.onClose = null;\n link.close();\n }\n }\n this.connected.delete(peerId);\n this.outbox.delete(peerId);\n this.lastHeard.delete(peerId);\n this.rate.delete(peerId);\n this.lockstep.onPeerLeft(peerId);\n this.chat.onPeerLeft(peerId);\n this.voice.onPeerLeft(peerId);\n this.pause.onPeerLeft(peerId);\n if (peer) this.emit(\"peerLeft\", peer, reason, close);\n if (peerId === this.hostPeerId && !this.isHost) {\n this.handleHostLost(reason);\n }\n }\n\n /** Lockstep drops (stalled, desynced): removed without a ban, so the player can come back (a rejoin resyncs). */\n private dropPeer(peerId: number, reason: string): void {\n this.signaling.send({ t: \"kick\", peerId, ban: false, closeReason: reason } as { t: \"kick\"; peerId: number });\n this.removePeer(peerId, reason, undefined, true);\n }\n\n private setPhase(p: Phase): void {\n if (p !== \"lobby\" && p !== \"in_game\") return;\n if (this.phase === p) return;\n this.phase = p;\n if (p === \"lobby\") this.pause.onLobbyPhase();\n if (p === \"in_game\" && !this.lockstep.started) this.lockstep.markStarted();\n this.emit(\"phase\", p);\n }\n\n private onServerClosed(): void {\n if (this.ended) return;\n if (this.cfg.direct && !this.isHost) {\n this.teardown(\"host_left\");\n return;\n }\n this.serverUp = false;\n this.emit(\"serverLost\");\n // Alone with no peers: nothing keeps this session alive.\n if (this.links.size === 0 && this.roster.size <= 1) this.teardown(\"server_lost\");\n }\n\n // ---- housekeeping ----------------------------------------------------------------------------------------------\n\n private watchdog(): void {\n if (this.ended) return;\n const timeout = this.cfg.peerTimeoutMs ?? 0;\n if (timeout > 0) this.dropSilent(Math.max(timeout, MIN_PEER_TIMEOUT_MS));\n if (this.ended || this.isHost) return;\n if (this.mode === \"lockstep\" && this.lockstep.hostSilent()) {\n this.lockstep.touch();\n this.lockstep.pokeHost(); // a live-but-stalled host answers with a snapshot; a dead one is replaced below\n this.handleHostLost(\"timeout\");\n }\n }\n\n /** peerTimeoutMs: the host drops joiners it has not heard from; a joiner handles a silent host as lost. */\n private dropSilent(timeout: number): void {\n const now = this.cfg.clock.now();\n if (this.isHost) {\n for (const id of [...this.connected]) {\n const last = this.lastHeard.get(id);\n if (last !== undefined && now - last > timeout) this.removePeer(id, \"timeout\");\n }\n } else if (this.isReady) {\n const last = this.lastHeard.get(this.hostPeerId);\n if (last !== undefined && now - last > timeout) {\n this.lastHeard.delete(this.hostPeerId);\n this.handleHostLost(\"timeout\");\n }\n }\n }\n\n private pingHost(): void {\n if (this.ended || this.isHost) return;\n this.sendTo(this.hostPeerId, { type: \"ping\", n: ++this.pingN, t: this.cfg.clock.now() >>> 0 }, 0, \"fast\");\n }\n\n /** Host: report a joiner that is not ready `readyTimeoutMs` after joining as peerFailed(\"timeout\"), once. */\n private watchReady(peerId: number): void {\n const ms = this.cfg.readyTimeoutMs ?? 0;\n let cancel = () => {};\n if (ms > 0) {\n cancel = this.cfg.clock.setTimeout(() => {\n if (!this.notReady.delete(peerId)) return;\n const peer = this.roster.get(peerId);\n if (peer) this.emit(\"peerFailed\", peer, \"timeout\");\n }, ms);\n }\n this.notReady.set(peerId, cancel);\n }\n\n private teardown(reason: string, close?: CloseInfo): void {\n if (this.ended) return;\n this.ended = true;\n this.cancelReadyTimer?.();\n for (const cancel of this.notReady.values()) cancel();\n this.notReady.clear();\n if (!this.isReady) {\n const code = reason === \"ice_failed\" || reason === \"kicked\" ? reason : \"closed\";\n this.failReady(new OneLobbyError(code, `the lobby ended before connecting (${reason})`));\n }\n this.cancelWatchdog?.();\n this.cancelPing?.();\n this.lockstep.stop();\n this.voice.close();\n for (const l of [...this.links.values(), ...this.lingering]) {\n l.onClose = null;\n l.onMessage = null;\n l.close();\n }\n this.links.clear();\n this.earlyIce.clear();\n this.heldOffers.clear();\n this.lingering.clear();\n this.signaling.onClose = null;\n this.signaling.onMessage = null;\n this.signaling.close();\n this.emit(\"sessionEnded\", reason, close);\n }\n\n /** Total in-flight links (diagnostics and tests). */\n get linkCount(): number {\n return this.links.size;\n }\n}\n\nexport { PROTO };\n"]}
1
+ {"version":3,"file":"lobby.js","sourceRoot":"","sources":["../src/lobby.ts"],"names":[],"mappings":"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","sourcesContent":["import { Chat } from \"./chat.js\";\nimport type { IpCodeKind, JoinCodeKind } from \"./join-code-kind.js\";\nimport type { Clock } from \"./clock.js\";\nimport {\n CodecError,\n MAX_FRAME_BYTES,\n MODE_LOCKSTEP,\n MODE_RAW,\n PROTO,\n decodeMessage,\n encodeMessage,\n type Message,\n} from \"./codec.js\";\nimport { Reassembler, splitChunks } from \"./chunking.js\";\nimport { Emitter } from \"./emitter.js\";\nimport type { Hub } from \"./hub.js\";\nimport { Lockstep } from \"./lockstep.js\";\nimport { claimWinsWrapped, pickNewHost } from \"./migration.js\";\nimport { Pause } from \"./pause.js\";\nimport { OneLobbyError, type LobbyState, type PeerInfo, type SignalingClient, type ServerMsg } from \"./signaling.js\";\nimport type { ChannelName, IceServer, LinkFactory, PeerLink, SignalPayload } from \"./transport.js\";\nimport { Voice, type VoiceDeps } from \"./voice.js\";\nimport { hostConnections, joinerSocket, type LobbySocket, type LobbySocketOptions } from \"./socket.js\";\n\nexport type Phase = \"lobby\" | \"in_game\";\n/** The close code and reason a host chose with `kick()` / `disconnect()`, passed to the removed player's sockets. */\nexport interface CloseInfo {\n code?: number;\n reason?: string;\n}\n/** Options for `lobby.kick()`. */\nexport interface KickOptions {\n /** Default true: the player's address cannot rejoin this lobby while it lasts. false = `disconnect()`. */\n ban?: boolean;\n /** Close code for the player's `asWebSocket()` onclose: 1000 or 3000-4999. */\n code?: number;\n /** Close reason for that onclose, at most 120 characters. */\n reason?: string;\n}\nexport type Peer = PeerInfo;\n\n/** What a direct host's `joinCode` is: see {@link Lobby.joinCodeKind}. */\nexport type { JoinCodeKind };\n\nexport type LobbyEvents = {\n peerJoined: [Peer];\n /** The peer's data channels are open and the handshake is done: reliable sends reach it now (earlier ones were queued and flushed). */\n peerReady: [Peer];\n /** Joiner: the link to the host is open (the host itself is ready from the start). Also available as `lobby.ready`. */\n ready: [];\n /** reason \"left\", \"kicked\", \"disconnected\" (kick with ban false), \"timeout\", ...; `close` when the host gave one. */\n peerLeft: [Peer, reason: string, close?: CloseInfo];\n /**\n * Host only: a joiner never got its link to the host open (\"a friend could not connect\"). reason \"timeout\" when it is\n * not ready `readyTimeoutMs` after joining (it may still connect: `peerReady` then fires as usual), else the\n * `peerLeft` reason when it leaves before it was ready (a joiner's own `ice_failed` ends that way). Fires at most once\n * per peer, just before that `peerLeft`; not for peers the host kicks or disconnects.\n */\n peerFailed: [Peer, reason: string];\n joinRequested: [Peer];\n hostChanged: [hostId: number];\n /** A member (you included) changed its display name mid-session (`rename`): the peer with its new name, and the old name. */\n peerRenamed: [Peer, oldName: string];\n phase: [Phase];\n message: [from: number, bytes: Uint8Array, channel: ChannelName];\n /** `close` is the code and reason the host gave when it removed this player (`kick()` / `disconnect()`). */\n sessionEnded: [reason: string, close?: CloseInfo];\n /** The signaling server went away. The game continues on the data channels (s.9). */\n serverLost: [];\n metaChanged: [Record<string, string>];\n /**\n * Direct-IP host only: the join code changed after `hostDirect` resolved, e.g. the router answered a later port-mapping\n * retry and the code went from \"same_network\" to \"internet\". Show the new code (and `joinUrl`).\n */\n joinCodeChanged: [code: string, kind: JoinCodeKind];\n /**\n * Browser host only (`kit.hostNostr`): the host tab went hidden (`true`) or visible again (`false`). Browsers throttle\n * timers in hidden tabs, so joiners may see lag or drop; ask the host to keep the tab visible.\n */\n hostHiddenChanged: [hidden: boolean];\n};\n\nexport interface LobbyConfig {\n signaling: SignalingClient;\n state: LobbyState;\n ice: IceServer[];\n /** `welcome.features` of the hub (e.g. \"set_name\"); absent = none. */\n features?: string[];\n links: LinkFactory;\n clock: Clock;\n wall: () => number;\n hashEveryTicks: number;\n relayOnly: boolean;\n voice: VoiceDeps;\n displayName: string;\n /**\n * Joiner: give up on reaching the host after this many ms (0 or absent: wait forever). When the ICE list has a\n * TURN server and the lobby is not relay-only already, the second half of the budget is a relay-only retry.\n * On failure `ready` rejects with OneLobbyError(\"ice_failed\"), the error is reported and the lobby is left.\n */\n readyTimeoutMs?: number;\n /**\n * Direct IP (docs/design/direct-ip.md): the hub lives in the host, so there is no migration. A joiner that loses the host\n * (link, peer_left, a host_changed from the hub as it shuts down, or the signaling socket) ends with \"host_left\".\n */\n direct?: boolean;\n /**\n * Treat a peer as gone after this many ms without hearing anything from it (0 or absent: off, and a silent peer\n * surfaces only when its link or signaling socket times out, about 30 s). Joiners ping the host every 2 s and the\n * host answers, so the host drops a silent joiner (`peerLeft`, \"timeout\") and a joiner handles a silent host as\n * lost (a direct lobby ends with \"host_left\"). Values under 6000 are raised to 6000.\n */\n peerTimeoutMs?: number;\n /** Host: per-peer cap on incoming raw messages; the excess is dropped before `message` fires or is relayed. */\n rateLimit?: RateLimit;\n}\n\n/** At most `messages` raw messages per peer in any `perMs` window (a fixed window, reset every `perMs`). */\nexport interface RateLimit {\n messages: number;\n perMs: number;\n}\n\n/** The smallest `peerTimeoutMs` honoured: three missed pings. */\nexport const MIN_PEER_TIMEOUT_MS = 6000;\n/** Host: how long a kicked / disconnected peer's link stays open for the hub's notice to reach it first. */\nexport const KICK_LINGER_MS = 3000;\n/** How long an offer held during a possible migration stays answerable. */\nconst HELD_OFFER_MS = 20_000;\n\n/** The name shown for a peer that chose none: \"Player N\", N = its seat (peer id, join order). */\nexport function seatName(p: PeerInfo): PeerInfo {\n const n = typeof p.name === \"string\" ? p.name.trim() : \"\";\n // \"Player\" is onelobby-server's stand-in for an empty name\n if (n && n !== \"Player\") return p;\n return { ...p, name: `Player ${p.peerId}` };\n}\n\nfunction hasRelay(ice: IceServer[]): boolean {\n return ice.some((s) => (Array.isArray(s.urls) ? s.urls : [s.urls]).some((u) => /^turns?:/i.test(String(u))));\n}\n\nconst HOST_WATCHDOG_MS = 250;\nconst PING_EVERY_MS = 2000;\n\n/** One joined lobby: roster, star of peer links, and the lockstep/chat/voice engines riding on them. */\nexport class Lobby extends Emitter<LobbyEvents> {\n readonly code: string;\n readonly mode: \"lockstep\" | \"raw\";\n readonly tickRate: number;\n readonly lockstep: Lockstep;\n readonly chat: Chat;\n /** The shared co-op pause (docs/recipes/pause.md). */\n readonly pause: Pause;\n readonly voice: Voice;\n\n localPeerId: number;\n hostPeerId: number;\n phase: Phase;\n meta: Record<string, string>;\n /** The lobby's name as the server keeps it (host()'s `name`, sanitised); \"\" if the server sends none. */\n name: string;\n resumeToken: string;\n /** Last measured round trip to the host in ms (joiners), or 0. */\n rtt = 0;\n /**\n * Direct-IP host only (onelobby/direct): the code friends paste to join, e.g. \"6B01-RGFE-P2B\" (docs/design/direct-ip.md\n * s.2a). Show it with joinCodeKind. Empty when the machine has no IPv4 address, and on joiners.\n */\n joinCode = \"\";\n /**\n * \"nostr\": a version 1 code that works through public Nostr relays (spec/nostr-signaling.md; the default for a direct\n * host). \"internet\": the router forwarded the port and the code carries its public address; \"same_network\": the LAN\n * address. \"none\": no code.\n */\n joinCodeKind: JoinCodeKind = \"none\";\n /**\n * Direct-IP host only: the IP code (address and port, version 0), with `directCodeKind` \"internet\" or \"same_network\".\n * Equal to `joinCode` when Nostr is off; otherwise the code to hand out for LAN play or when the router port is open.\n */\n directCode = \"\";\n directCodeKind: IpCodeKind = \"none\";\n /** Direct-IP host only: this machine's addresses with the port, for an \"Advanced\" fold-out. */\n directAddresses: string[] = [];\n /** Direct-IP host only: how the router port-open went (\"UPnP\", \"no UPnP gateway answered; ...\", \"off\"). */\n portMapping = \"\";\n /** Direct-IP host only: the one startup line (bound port, join code, port mapping); see `formatHostLog` in onelobby/direct. */\n directHostLog = \"\";\n\n /** Browser host only (`kit.hostNostr`): true while the host tab is hidden (see the `hostHiddenChanged` event). */\n hostHidden = false;\n\n /** @internal kit.hostNostr: the tab's visibility changed. */\n setHostHidden(hidden: boolean): void {\n if (this.hostHidden === hidden) return;\n this.hostHidden = hidden;\n this.emit(\"hostHiddenChanged\", hidden);\n }\n\n /** @internal onelobby/direct: fires `joinCodeChanged` with the current code. */\n notifyJoinCodeChanged(): void {\n this.emit(\"joinCodeChanged\", this.joinCode, this.joinCodeKind);\n }\n\n private signaling: SignalingClient;\n private cfg: LobbyConfig;\n private roster = new Map<number, Peer>();\n private links = new Map<number, PeerLink>();\n /** ICE from a peer that has no link yet: its candidates can overtake its offer (node-datachannel). */\n private earlyIce = new Map<number, SignalPayload[]>();\n /** Offers from roster members that arrived while the host link was open (see offerVerdict), by sender. */\n private heldOffers = new Map<number, { payload: SignalPayload; at: number }>();\n private connected = new Set<number>(); // host: peers that said hi\n private hiSentTo = new Set<PeerLink>();\n private epoch = 0;\n private ended = false;\n private serverUp = true;\n private cancelWatchdog: (() => void) | null = null;\n private cancelPing: (() => void) | null = null;\n private pingN = 0;\n private chunkId = 1;\n private reassemblers = new Map<number, Reassembler>();\n private hub: Hub;\n private outbox = new Map<number, { msg: Message; route: number; channel?: ChannelName }[]>();\n private markReady: () => void = () => {};\n private failReady: (e: Error) => void = () => {};\n private isReady = false;\n private cancelReadyTimer: (() => void) | null = null;\n private relayRetry = false;\n /** clock.now() of the last frame from each peer (peerTimeoutMs). */\n private lastHeard = new Map<number, number>();\n /** Host: links of kicked / disconnected peers, kept open briefly (removePeer `linger`). */\n private readonly lingering = new Set<PeerLink>();\n /** Host: joiners that joined but are not ready yet, with the cancel of their readyTimeoutMs timer (peerFailed). */\n private notReady = new Map<number, () => void>();\n /** Host: per-peer fixed window for rateLimit. */\n private rate = new Map<number, { start: number; n: number }>();\n /**\n * Resolves when this peer can exchange data: immediately for the host, once the link to the host is open for a\n * joiner. Rejects with OneLobbyError(\"ice_failed\") when the joiner cannot reach the host in `readyTimeoutMs`\n * (or with \"closed\"/\"kicked\" when the lobby ends first; \"closed\" also when the host disconnected it).\n */\n readonly ready: Promise<void> = new Promise<void>((res, rej) => {\n this.markReady = () => {\n if (this.isReady) return;\n this.isReady = true;\n this.cancelReadyTimer?.();\n this.cancelReadyTimer = null;\n res();\n };\n this.failReady = rej;\n });\n\n constructor(cfg: LobbyConfig) {\n super();\n this.cfg = cfg;\n this.signaling = cfg.signaling;\n const st = cfg.state;\n this.code = st.code;\n this.mode = st.mode;\n this.tickRate = st.tickRate;\n this.localPeerId = st.you;\n this.hostPeerId = st.hostId;\n this.phase = st.phase;\n this.meta = { ...st.meta };\n this.name = st.name ?? \"\";\n this.resumeToken = st.resumeToken;\n for (const p of st.peers) this.roster.set(p.peerId, seatName(p));\n this.ready.catch(() => {}); // a rejection is also reported through errorSink; awaiting `ready` stays optional\n\n const self = this;\n this.hub = {\n get clock() { return self.cfg.clock; },\n get localPeerId() { return self.localPeerId; },\n get hostPeerId() { return self.hostPeerId; },\n get isHost() { return self.isHost; },\n get tickRate() { return self.tickRate; },\n connectedPeers: () => self.connectedPeerIds(),\n sendTo: (peerId, msg, route, channel) => self.sendTo(peerId, msg, route ?? 0, channel),\n sendToHost: (msg, route, channel) => {\n if (!self.isHost) self.sendTo(self.hostPeerId, msg, route ?? 0, channel);\n },\n dropPeer: (peerId, reason) => self.dropPeer(peerId, reason),\n reportError: (e) => self.reportError(e),\n nextChunkId: () => self.chunkId++ >>> 0,\n };\n\n this.lockstep = new Lockstep(this.hub, { hashEveryTicks: cfg.hashEveryTicks });\n this.chat = new Chat(this.hub, cfg.wall, (id) => this.voice.isMutedPeer(id));\n this.voice = new Voice(this.hub, cfg.voice);\n this.pause = new Pause(this.hub, {\n phase: () => this.phase,\n hold: (held) => this.lockstep.hold(held),\n hasPeer: (id) => this.roster.has(id),\n });\n this.lockstep.on(\"started\", () => this.setPhase(\"in_game\"));\n this.lockstep.on(\"error\", (e) => this.reportError(e));\n\n this.signaling.onMessage = (m) => this.onSignaling(m);\n this.signaling.onClose = () => this.onServerClosed();\n\n if (this.isHost) this.markReady();\n else this.armReadyTimer();\n if (this.isHost && this.mode === \"lockstep\") {\n if (this.phase === \"in_game\") this.lockstep.hostStart();\n else this.lockstep.hostIdle();\n }\n this.cancelWatchdog = cfg.clock.setInterval(() => this.watchdog(), HOST_WATCHDOG_MS);\n this.cancelPing = cfg.clock.setInterval(() => this.pingHost(), PING_EVERY_MS);\n }\n\n // ---- state -----------------------------------------------------------------------------------------------------\n\n get isHost(): boolean {\n return this.localPeerId === this.hostPeerId;\n }\n get peers(): Peer[] {\n return [...this.roster.values()].sort((a, b) => a.peerId - b.peerId);\n }\n peer(peerId: number): Peer | undefined {\n return this.roster.get(peerId);\n }\n /** Peers whose link is open and handshake done (host: the ready joiners; joiner: the host once ready). */\n get connectedPeers(): number[] {\n return this.connectedPeerIds();\n }\n\n /**\n * Joiner: the link to the host as a WebSocket-shaped object (text by default), so WebSocket client code runs\n * unchanged. It opens when `ready` resolves and closes when the session ends (`host_left` gives code 1001).\n */\n asWebSocket(opts: LobbySocketOptions & { binary: true }): LobbySocket<Uint8Array>;\n asWebSocket(opts?: LobbySocketOptions & { binary?: false }): LobbySocket<string>;\n asWebSocket(opts?: LobbySocketOptions): LobbySocket;\n asWebSocket(opts?: LobbySocketOptions): LobbySocket {\n return joinerSocket(this, opts);\n }\n\n /**\n * Host: `handler(conn)` once per joiner (a WebSocket-shaped connection), the server-side mirror of asWebSocket().\n * With `{ binary: true }` every `conn.onmessage` gets a Uint8Array.\n */\n onConnection(handler: (conn: LobbySocket<Uint8Array>) => void, opts: LobbySocketOptions & { binary: true }): () => void;\n onConnection(handler: (conn: LobbySocket<string>) => void, opts?: LobbySocketOptions & { binary?: false }): () => void;\n onConnection(handler: (conn: LobbySocket) => void, opts?: LobbySocketOptions): () => void;\n onConnection(handler: (conn: LobbySocket) => void, opts?: LobbySocketOptions): () => void {\n return hostConnections(this, handler, opts);\n }\n\n set snapshotChunkSize(n: number) {\n this.lockstep.chunkSize = n;\n }\n\n /** Current migration epoch (0 until the first host change). */\n get hostEpoch(): number {\n return this.epoch;\n }\n\n /** @internal Host role: create the link to `peerId` and start negotiating (adapters and tests). */\n _offer(peerId: number): PeerLink {\n this.offerTo(peerId);\n return this.links.get(peerId)!;\n }\n\n /** @internal Joiner role: create the answering link to `peerId` (adapters and tests). */\n _answer(peerId: number): PeerLink {\n return this.makeLink(peerId);\n }\n\n /** @internal Called by OneLobby right after construction: the host waits for joiners, a joiner waits for the host's offer. */\n _begin(): void {\n /* joiners are passive until the host offers; hosts create links on peer_joined */\n }\n\n // ---- game-facing actions ---------------------------------------------------------------------------------------\n\n async start(): Promise<void> {\n if (!this.isHost) throw new Error(\"only the host can start the game\");\n if (this.phase === \"in_game\") return;\n this.signaling.send({ t: \"phase\", phase: \"in_game\" });\n this.setPhase(\"in_game\");\n if (this.mode === \"lockstep\") this.lockstep.hostStart();\n }\n\n /**\n * Changes your display name mid-session. The hub sanitises it (as at hello, at most 24 characters) and every member,\n * you included, gets `peerRenamed`. Names need not be unique. At most one rename per second; a refusal\n * (`bad_request` for an empty name, `rate_limited`) arrives on the kit's `error` event. Throws `unsupported` when\n * the hub is too old to rename.\n */\n async rename(name: string): Promise<void> {\n if (!(this.cfg.features ?? []).includes(\"set_name\")) throw new OneLobbyError(\"unsupported\", \"this lobby's hub cannot rename players (update it)\");\n this.signaling.send({ t: \"set_name\", name: String(name ?? \"\") });\n }\n\n async setMeta(meta: Record<string, string>): Promise<void> {\n if (!this.isHost) throw new Error(\"only the host can set metadata\");\n this.meta = { ...meta };\n this.signaling.send({ t: \"meta\", meta });\n this.emit(\"metaChanged\", this.meta);\n }\n\n /**\n * Host: removes a player. By default it is a ban: the hub refuses that player's address for the rest of this lobby\n * (a new tab or a reload included). `{ ban: false }` is `disconnect()`. `code` / `reason` reach the player's\n * `asWebSocket()` onclose (and `sessionEnded`'s second argument); without them its socket closes with 4000 \"kicked\".\n */\n async kick(peerId: number, opts: KickOptions = {}): Promise<void> {\n if (!this.isHost) throw new Error(\"only the host can kick\");\n const { ban = true, code, reason } = opts;\n if (code !== undefined && !(code === 1000 || (Number.isInteger(code) && code >= 3000 && code <= 4999)))\n throw new RangeError(\"close code must be 1000 or 3000-4999\");\n if (reason !== undefined && reason.length > 120) throw new RangeError(\"close reason must be at most 120 characters\");\n const msg: Record<string, unknown> = { t: \"kick\", peerId };\n if (!ban) msg.ban = false;\n if (code !== undefined) msg.closeCode = code;\n if (reason !== undefined) msg.closeReason = reason;\n this.signaling.send(msg as { t: \"kick\"; peerId: number });\n const close: CloseInfo | undefined = code !== undefined || reason !== undefined ? { code, reason } : undefined;\n this.removePeer(peerId, ban ? \"kicked\" : \"disconnected\", close, true);\n }\n\n /**\n * Host: ends one player's connection without a ban, like a server closing one WebSocket. The player's\n * `asWebSocket()` gets onclose with `code` (default 1000) and `reason` (default \"disconnected\"), its lobby ends with\n * `sessionEnded(\"disconnected\")`, and it may join again (a new tab, a reload). Same as `kick(peerId, { ban: false, code, reason })`.\n */\n disconnect(peerId: number, code?: number, reason?: string): Promise<void> {\n return this.kick(peerId, { ban: false, code, reason });\n }\n\n async approve(peerId: number, ok: boolean): Promise<void> {\n if (!this.isHost) throw new Error(\"only the host can approve joins\");\n this.signaling.send({ t: \"approve\", peerId, ok });\n }\n\n async leave(): Promise<void> {\n if (this.ended) return;\n this.signaling.send({ t: \"leave\" });\n this.teardown(\"left\");\n }\n\n /** raw mode (and any extra game data): to one peer. */\n send(peerId: number, bytes: Uint8Array, opts: { channel?: \"reliable\" | \"fast\" } = {}): void {\n const channel = opts.channel ?? \"reliable\";\n if (this.isHost) this.sendTo(peerId, { type: \"raw\", bytes }, this.localPeerId, channel);\n else this.sendTo(this.hostPeerId, { type: \"raw\", bytes }, peerId, channel);\n }\n\n /** To everyone else in the lobby. */\n broadcast(bytes: Uint8Array, opts: { channel?: \"reliable\" | \"fast\" } = {}): void {\n const channel = opts.channel ?? \"reliable\";\n if (this.isHost) {\n // peers whose channels are not open yet get reliable broadcasts queued and flushed in order\n for (const p of this.roster.keys()) if (p !== this.localPeerId) this.sendTo(p, { type: \"raw\", bytes }, this.localPeerId, channel);\n } else {\n this.sendTo(this.hostPeerId, { type: \"raw\", bytes }, 0, channel);\n }\n }\n\n // ---- sending ---------------------------------------------------------------------------------------------------\n\n private channelFor(msg: Message): ChannelName {\n if (msg.type === \"voice\") return \"voice\";\n if (msg.type === \"ping\" || msg.type === \"pong\") return \"fast\";\n return \"reliable\";\n }\n\n private sendTo(peerId: number, msg: Message, route: number, channel?: ChannelName): void {\n const link = this.links.get(peerId);\n const ch0 = channel ?? this.channelFor(msg);\n const queueable = msg.type === \"raw\" || msg.type === \"chat\" || msg.type === \"cmd\";\n // game data to a host-side peer waits for its `hi`; protocol messages only need the link\n const ready = !!link?.isOpen && (!queueable || !this.isHost || this.connected.has(peerId));\n if (!ready) {\n // Reliable game data for a peer that is in the roster (or is the host) but not connected yet waits for its handshake.\n const known = this.roster.has(peerId) || peerId === this.hostPeerId;\n if (queueable && ch0 === \"reliable\" && known && !this.ended) {\n let q = this.outbox.get(peerId);\n if (!q) this.outbox.set(peerId, (q = []));\n if (q.length >= 1000) q.shift();\n q.push({ msg, route, channel });\n }\n return;\n }\n if (!link) return;\n try {\n const ch = ch0;\n let bytes: Uint8Array;\n try {\n bytes = encodeMessage(msg, route);\n } catch (e) {\n if (!(e instanceof CodecError) || e.code !== \"too_long\") throw e;\n bytes = encodeMessage(msg, route, true);\n }\n if (bytes.length > MAX_FRAME_BYTES) {\n // Oversized frame: send the whole inner frame as a chunk set (spec/binary.md \"Large non-snapshot frames\").\n for (const c of splitChunks(this.chunkId++ >>> 0, bytes)) link.send(ch, encodeMessage(c, route));\n } else {\n link.send(ch, bytes);\n }\n } catch (e) {\n this.reportError(e instanceof Error ? e : new Error(String(e)));\n }\n }\n\n private connectedPeerIds(): number[] {\n if (this.isHost) return [...this.connected].filter((id) => this.links.get(id)?.isOpen).sort((a, b) => a - b);\n const l = this.links.get(this.hostPeerId);\n return l?.isOpen ? [this.hostPeerId] : [];\n }\n\n private reportError(e: Error): void {\n this.errorSink?.(e);\n }\n /** @internal set by OneLobby so lobby errors reach `kit.on(\"error\")`. */\n errorSink: ((e: Error) => void) | null = null;\n /** @internal set by OneLobby: the server issued a new resume token (rememberSeat). */\n seatSink: ((token: string) => void) | null = null;\n\n // ---- joiner connect timeout -------------------------------------------------------------------------------------\n\n private armReadyTimer(): void {\n const total = this.cfg.readyTimeoutMs ?? 0;\n if (!(total > 0)) return;\n const canRelay = !this.cfg.relayOnly && hasRelay(this.cfg.ice);\n const first = canRelay ? Math.ceil(total / 2) : total;\n this.cancelReadyTimer = this.cfg.clock.setTimeout(() => {\n if (this.isReady || this.ended) return;\n if (canRelay) this.retryRelayed(total - first);\n else this.giveUpConnecting();\n }, first);\n }\n\n /** The direct attempt stalled: dial the host ourselves through the TURN relay (a host answers any offer). */\n private retryRelayed(budget: number): void {\n this.relayRetry = true;\n const link = this.makeLink(this.hostPeerId, true);\n link.startOffer();\n this.cancelReadyTimer = this.cfg.clock.setTimeout(() => {\n if (!this.isReady && !this.ended) this.giveUpConnecting();\n }, budget);\n }\n\n private giveUpConnecting(): void {\n // what the host link saw (states, signals, timings), so a test log of a failed connect says where it stalled\n const hostLink = this.links.get(this.hostPeerId);\n const diagnostics = hostLink ? hostLink.diagnostics?.() : (this.lastHostLinkEnd ?? \"no offer from the host ever arrived\");\n // the trace holds ICE candidates (local addresses): keep it in data, out of the message a game may show\n const err = new OneLobbyError(\"ice_failed\", `could not open a connection to the host${this.relayRetry ? \" (direct or relayed)\" : \"\"}`, diagnostics ? { diagnostics } : undefined);\n this.failReady(err);\n this.reportError(err);\n if (this.ended) return;\n this.signaling.send({ t: \"leave\" });\n this.teardown(\"ice_failed\");\n }\n\n // ---- links -----------------------------------------------------------------------------------------------------\n\n /** @internal A direct host's hub learns where each joiner's link comes from (Nostr kick bans the address too). */\n linkAddressSink: ((peerId: number, ip: string) => void) | null = null;\n\n private makeLink(peerId: number, relayOnly = this.cfg.relayOnly): PeerLink {\n const old = this.links.get(peerId);\n if (old) {\n old.onClose = null;\n old.onMessage = null;\n old.close();\n }\n const link = this.cfg.links.create({ remoteId: peerId, iceServers: this.cfg.ice, relayOnly });\n this.links.set(peerId, link);\n link.onSignal = (s) => this.signaling.send({ t: \"signal\", to: peerId, ...s });\n link.onOpen = () => this.onLinkOpen(peerId, link);\n link.onClose = (reason) => this.onLinkClosed(peerId, link, reason);\n link.onMessage = (ch, bytes) => this.onData(peerId, ch, bytes);\n link.onPath = (path) => this.signaling.send({ t: \"path\", path });\n link.onRemoteAddress = (ip) => this.linkAddressSink?.(peerId, ip);\n return link;\n }\n\n /** Host side: offer to a joiner. */\n private offerTo(peerId: number): void {\n const link = this.makeLink(peerId);\n link.startOffer();\n }\n\n private onLinkOpen(peerId: number, link: PeerLink): void {\n if (this.isHost) {\n // Joiner speaks first (`hi`). After a migration the new host announces itself so the joiner knows who won.\n if (this.epoch > 0) this.sendTo(peerId, { type: \"host_claim\", epoch: this.epoch, hostId: this.localPeerId, tick: this.lockstep.lastTick }, 0);\n return;\n }\n if (peerId === this.hostPeerId) this.sendHi(link);\n // else: an unexpected offerer; wait for its host_claim before trusting it\n }\n\n private sendHi(link: PeerLink): void {\n if (this.hiSentTo.has(link)) return;\n this.hiSentTo.add(link);\n this.lockstep.touch();\n link.send(\"reliable\", encodeMessage(this.lockstep.hiMessage(this.localPeerId)));\n this.markReady();\n this.emit(\"ready\");\n this.emit(\"peerReady\", this.roster.get(link.remoteId) ?? { peerId: link.remoteId, name: \"\" });\n this.flush(link.remoteId);\n }\n\n /** Why and how the joiner's last link to the host ended (shown when the join gives up). */\n private lastHostLinkEnd: string | null = null;\n\n private onLinkClosed(peerId: number, link: PeerLink, _reason: string): void {\n if (this.links.get(peerId) !== link) return; // replaced\n if (!this.isHost && peerId === this.hostPeerId) this.lastHostLinkEnd = `link ended (${_reason}): ${link.diagnostics?.() ?? \"\"}`;\n this.links.delete(peerId);\n this.hiSentTo.delete(link);\n if (this.ended) return;\n if (this.isHost) {\n this.connected.delete(peerId);\n this.lockstep.onPeerLeft(peerId);\n this.voice.onPeerLeft(peerId);\n // The server announces the departure; if it is gone, drop the peer ourselves.\n if (!this.serverUp && this.roster.has(peerId)) this.removePeer(peerId, \"timeout\");\n } else if (peerId === this.hostPeerId) {\n // Never connected yet (ICE failed): not a host loss. The ready timer retries over the relay or gives up.\n if (!this.isReady && this.cancelReadyTimer) return;\n this.handleHostLost(\"link closed\");\n }\n }\n\n // ---- data channel dispatch -------------------------------------------------------------------------------------\n\n private onData(from: number, channel: ChannelName, bytes: Uint8Array, reassembled = false): void {\n let d;\n try {\n d = decodeMessage(bytes, reassembled);\n } catch (e) {\n this.reportError(e instanceof Error ? e : new Error(String(e)));\n return;\n }\n if (!d) return;\n // The topology is a star: a joiner hears only its host. Anything else over some other link (a peer that offered to\n // us, or a member that dialled us) is not host traffic and must not reach raw / lockstep / pause / chat handling.\n if (!this.isHost && from !== this.hostPeerId && d.msg.type !== \"host_claim\") return;\n if (!reassembled) this.lastHeard.set(from, this.cfg.clock.now());\n const { msg, route } = d;\n switch (msg.type) {\n case \"hi\":\n if (this.isHost) this.onHi(from, msg.lastTick);\n break;\n case \"welcome_dc\":\n if (!this.isHost) {\n if (msg.hostId !== this.hostPeerId) this.setHost(msg.hostId);\n this.lockstep.touch();\n }\n break;\n case \"cmd\": case \"frame\": case \"hash\": case \"desync\":\n case \"snapshot_req\": case \"snapshot\":\n if (from === this.hostPeerId || this.isHost) this.lockstep.handle(from, msg);\n break;\n case \"chunk\": {\n if (reassembled) break; // a chunk set never nests another\n let r = this.reassemblers.get(from);\n if (!r) this.reassemblers.set(from, (r = new Reassembler()));\n let whole;\n try {\n whole = r.push(msg);\n } catch (e) {\n this.reportError(e instanceof Error ? e : new Error(String(e)));\n break;\n }\n if (!whole) break;\n if (this.lockstep.snapshotPending && from === this.hostPeerId) this.lockstep.onSnapshotPayload(whole);\n else this.onData(from, channel, whole, true); // an oversized inner frame\n break;\n }\n case \"chat\": case \"chat_history\": case \"chat_reject\":\n this.chat.handle(from, route, msg);\n break;\n case \"pause_request\": case \"pause_state\": case \"pause_refuse\":\n this.pause.handle(from, msg);\n break;\n case \"voice\":\n if (channel === \"voice\") this.voice.handle(from, route, msg); // a voice frame on another channel is ignored\n break;\n case \"raw\":\n this.onRaw(from, route, msg.bytes, channel);\n break;\n case \"ping\":\n this.sendTo(from, { type: \"pong\", n: msg.n, t: msg.t }, 0, \"fast\");\n break;\n case \"pong\":\n this.rtt = Math.max(0, (this.cfg.clock.now() >>> 0) - msg.t);\n break;\n case \"host_claim\":\n this.onHostClaim(from, msg.epoch, msg.hostId);\n break;\n }\n }\n\n private onHi(from: number, lastTick: number): void {\n this.connected.add(from);\n this.notReady.get(from)?.();\n this.notReady.delete(from);\n this.sendTo(from, {\n type: \"welcome_dc\",\n // the tick the snapshot will carry (the game's applied tick), so welcome_dc.tick == snapshot.tick even when\n // the game loop has not yet consumed every emitted frame; 0 before the game starts\n tick: this.mode === \"lockstep\" ? this.lockstep.currentTick : 0,\n tickRate: this.tickRate,\n mode: this.mode === \"lockstep\" ? MODE_LOCKSTEP : MODE_RAW,\n hostId: this.localPeerId,\n }, 0);\n this.chat.sendHistory(from);\n this.pause.sendState(from);\n if (this.mode === \"lockstep\") this.lockstep.onPeerHi(from, lastTick);\n this.emit(\"peerReady\", this.roster.get(from) ?? { peerId: from, name: \"\" });\n this.flush(from);\n }\n\n private flush(peerId: number): void {\n const q = this.outbox.get(peerId);\n if (!q) return;\n this.outbox.delete(peerId);\n for (const m of q) this.sendTo(peerId, m.msg, m.route, m.channel);\n }\n\n private onRaw(from: number, route: number, bytes: Uint8Array, channel: ChannelName): void {\n if (!this.isHost) {\n this.emit(\"message\", route, bytes, channel);\n return;\n }\n if (!this.allowRaw(from)) return;\n if (route === 0 || route === this.localPeerId) {\n this.emit(\"message\", from, bytes, channel);\n }\n if (route === 0) {\n for (const p of this.connectedPeerIds()) if (p !== from) this.sendTo(p, { type: \"raw\", bytes }, from, channel);\n } else if (route !== this.localPeerId) {\n this.sendTo(route, { type: \"raw\", bytes }, from, channel);\n }\n }\n\n private allowRaw(from: number): boolean {\n const lim = this.cfg.rateLimit;\n if (!lim || !(lim.messages > 0) || !(lim.perMs > 0)) return true;\n const now = this.cfg.clock.now();\n let w = this.rate.get(from);\n if (!w || now - w.start >= lim.perMs) this.rate.set(from, (w = { start: now, n: 0 }));\n return ++w.n <= lim.messages;\n }\n\n // ---- migration -------------------------------------------------------------------------------------------------\n\n private setHost(hostId: number): void {\n if (hostId === this.hostPeerId) return;\n this.hostPeerId = hostId;\n this.emit(\"hostChanged\", hostId);\n const held = this.heldOffers.get(hostId);\n if (held) {\n this.heldOffers.delete(hostId);\n if (this.cfg.clock.now() - held.at <= HELD_OFFER_MS) void this.acceptOffer(hostId, held.payload);\n }\n }\n\n /** The host is gone (link closed, no frames for 3 s, or the server said so): run the s.9 rule. */\n private handleHostLost(reason: string): void {\n if (this.isHost || this.ended) return;\n if (this.cfg.direct) {\n this.teardown(\"host_left\");\n return;\n }\n const failed = this.hostPeerId;\n const gone = this.roster.get(failed);\n if (gone) {\n this.roster.delete(failed);\n this.emit(\"peerLeft\", gone, reason === \"link closed\" ? \"timeout\" : reason);\n }\n const old = this.links.get(failed);\n if (old) {\n old.onClose = null;\n old.onMessage = null;\n old.close();\n this.links.delete(failed);\n this.hiSentTo.delete(old);\n }\n const candidate = pickNewHost([...this.roster.keys(), this.localPeerId], failed) ?? this.localPeerId;\n if (candidate === this.localPeerId) this.becomeHost();\n // else: wait for the candidate's host_claim (or the server's host_changed); it offers to us and we answer with hi\n this.replayHeldOffers();\n }\n\n /** Offers that came from roster members while the host link was still open: now the host is lost, answer them. */\n private replayHeldOffers(): void {\n const now = this.cfg.clock.now();\n for (const [from, held] of [...this.heldOffers]) {\n this.heldOffers.delete(from);\n if (now - held.at <= HELD_OFFER_MS && this.roster.has(from)) void this.acceptOffer(from, held.payload);\n }\n }\n\n private becomeHost(): void {\n this.epoch = (this.epoch + 1) & 0xffff;\n this.hostPeerId = this.localPeerId;\n this.markReady();\n this.connected.clear();\n this.hiSentTo.clear();\n this.lastHeard.clear(); // joiners spoke to the old host; their clocks start when they say hi to us\n this.lockstep.becomeHost();\n this.pause.onBecameHost();\n this.emit(\"hostChanged\", this.localPeerId);\n if (this.serverUp) this.signaling.send({ t: \"host_changed\", hostId: this.localPeerId, epoch: this.epoch });\n for (const p of this.roster.keys()) {\n if (p !== this.localPeerId) this.offerTo(p);\n }\n }\n\n private onHostClaim(from: number, epoch: number, hostId: number): void {\n if (hostId !== from) return; // a claim is a peer claiming itself; nobody claims for someone else\n const mine = { epoch: this.epoch, hostId: this.hostPeerId };\n const theirs = { epoch, hostId };\n if (hostId === this.hostPeerId && epoch === this.epoch && !this.isHost) {\n const l = this.links.get(from);\n if (l) this.sendHi(l);\n return;\n }\n if (!claimWinsWrapped(theirs, mine)) return; // we hold the better claim\n const wasHost = this.isHost;\n this.epoch = epoch;\n if (wasHost) {\n // We lose: demote. Everyone else will be offered to by the winner.\n for (const [id, l] of this.links) {\n if (id === from) continue;\n l.onClose = null;\n l.onMessage = null;\n l.close();\n this.links.delete(id);\n }\n this.connected.clear();\n this.lockstep.becomeJoiner();\n }\n this.setHost(hostId);\n const link = this.links.get(from);\n if (link && from === hostId) this.sendHi(link);\n }\n\n // ---- signaling -------------------------------------------------------------------------------------------------\n\n private onSignaling(m: ServerMsg): void {\n switch (m.t) {\n case \"peer_joined\": {\n if (!m.peer || this.roster.has((m.peer as Peer).peerId)) return;\n const peer = seatName(m.peer as Peer);\n this.roster.set(peer.peerId, peer);\n this.emit(\"peerJoined\", peer);\n if (this.isHost) {\n this.watchReady(peer.peerId);\n this.offerTo(peer.peerId);\n }\n break;\n }\n case \"peer_left\":\n this.removePeer(Number(m.peerId), String(m.reason ?? \"left\"));\n break;\n case \"host_changed\": {\n if (this.cfg.direct) {\n // the hub promotes a joiner as the host leaves; in direct mode the hub is going with it\n if (!this.isHost) this.teardown(\"host_left\");\n break;\n }\n const id = Number(m.hostId);\n if (typeof m.epoch === \"number\" && m.epoch > this.epoch) this.epoch = m.epoch & 0xffff;\n if (id === this.hostPeerId) break;\n if (id === this.localPeerId && !this.isHost) {\n const failed = this.hostPeerId;\n this.roster.delete(failed);\n this.becomeHost();\n } else {\n this.setHost(id);\n }\n break;\n }\n case \"join_request\":\n this.emit(\"joinRequested\", seatName(m.peer as Peer));\n break;\n case \"lobby\": {\n const st = m as unknown as LobbyState;\n this.meta = { ...st.meta };\n if (st.name) this.name = st.name;\n if (st.resumeToken && st.resumeToken !== this.resumeToken) {\n this.resumeToken = st.resumeToken;\n this.seatSink?.(this.resumeToken);\n }\n const before = this.roster;\n this.roster = new Map(st.peers.map((p) => [p.peerId, seatName(p)]));\n for (const [id, p] of this.roster) {\n const old = before.get(id);\n if (old && old.name !== p.name) this.emit(\"peerRenamed\", p, old.name);\n }\n if (st.hostId !== this.hostPeerId && !this.isHost) this.setHost(st.hostId);\n this.setPhase(st.phase);\n break;\n }\n case \"meta\":\n this.meta = { ...(m.meta as Record<string, string>) };\n this.emit(\"metaChanged\", this.meta);\n break;\n case \"phase\":\n this.setPhase(m.phase as Phase);\n break;\n case \"signal\":\n void this.onSignal(Number(m.from), m as unknown as SignalPayload);\n break;\n case \"error\":\n if (m.code === \"kicked\") {\n const d = (m.data ?? {}) as { ban?: unknown; closeCode?: unknown; closeReason?: unknown };\n const close: CloseInfo = {};\n if (typeof d.closeCode === \"number\") close.code = d.closeCode;\n if (typeof d.closeReason === \"string\") close.reason = d.closeReason;\n this.teardown(d.ban === false ? \"disconnected\" : \"kicked\", close.code !== undefined || close.reason !== undefined ? close : undefined);\n }\n else this.reportError(new OneLobbyError(String(m.code), String(m.msg ?? \"\"), m.data as Record<string, unknown> | undefined));\n break;\n }\n }\n\n private async onSignal(from: number, s: SignalPayload): Promise<void> {\n let link = this.links.get(from);\n const payload: SignalPayload = {};\n if (s.sdp) payload.sdp = s.sdp;\n if (s.ice) payload.ice = s.ice;\n if (s.sdp?.type === \"offer\") {\n // We are the answerer. An offer comes from the (new) host, so a peer may dial us only as that rule allows.\n const verdict = this.offerVerdict(from);\n if (verdict === \"hold\") {\n if (this.heldOffers.size < 64 || this.heldOffers.has(from)) this.heldOffers.set(from, { payload, at: this.cfg.clock.now() });\n } else if (verdict === \"accept\") await this.acceptOffer(from, payload);\n return;\n }\n if (!link) {\n if (!payload.ice || this.ended || !this.roster.has(from)) return;\n if (this.cfg.direct && from !== this.hostPeerId) return;\n const q = this.earlyIce.get(from) ?? [];\n if (q.length < 64) q.push(payload);\n this.earlyIce.set(from, q);\n return;\n }\n await link.handleSignal(payload);\n }\n\n /**\n * Whether an SDP offer from `from` may be answered. The host (or a joiner's host) always may. Direct lobbies have no\n * migration, so nobody else. In a server lobby a roster member may dial us when we are the host (a claim race decides\n * who wins) or when our own link to the host is gone (the migration window); while that link is open the offer is\n * held, to be answered if the host turns out to be lost a moment later.\n */\n private offerVerdict(from: number): \"accept\" | \"hold\" | \"drop\" {\n if (this.ended || from === this.localPeerId) return \"drop\";\n if (!this.isHost && from === this.hostPeerId) return \"accept\";\n if (this.cfg.direct || !this.roster.has(from)) return \"drop\";\n if (this.isHost) return \"accept\";\n if (!this.isReady) return \"drop\"; // still joining: only the host's own offer is expected\n return this.links.get(this.hostPeerId)?.isOpen ? \"hold\" : \"accept\";\n }\n\n private async acceptOffer(from: number, payload: SignalPayload): Promise<void> {\n const link = this.makeLink(from);\n const early = this.earlyIce.get(from) ?? [];\n this.earlyIce.delete(from);\n // the link holds candidates until the offer is set, so hand them over right behind it\n const done = link.handleSignal(payload);\n for (const e of early) void link.handleSignal(e);\n await done;\n }\n\n /**\n * `linger` (host kick / disconnect): stop using the peer's link at once but leave it open until that peer closes it\n * or KICK_LINGER_MS pass. The hub tells the peer over its WebSocket; closing the data link first would make it look\n * like the host vanished (a migration and a 1001 instead of the host's close code).\n */\n private removePeer(peerId: number, reason: string, close?: CloseInfo, linger = false): void {\n const peer = this.roster.get(peerId);\n if (peerId === this.localPeerId) {\n this.teardown(reason === \"kicked\" ? \"kicked\" : reason);\n return;\n }\n if (peer) this.roster.delete(peerId);\n this.earlyIce.delete(peerId);\n const cancelWatch = this.notReady.get(peerId);\n if (cancelWatch) {\n cancelWatch();\n this.notReady.delete(peerId);\n if (peer && reason !== \"kicked\" && reason !== \"disconnected\") this.emit(\"peerFailed\", peer, reason);\n }\n const link = this.links.get(peerId);\n if (link && peerId !== this.hostPeerId) {\n link.onMessage = null;\n this.links.delete(peerId);\n this.hiSentTo.delete(link);\n if (linger) {\n this.lingering.add(link);\n const done = () => {\n if (!this.lingering.delete(link)) return;\n cancel();\n link.onClose = null;\n link.close();\n };\n const cancel = this.cfg.clock.setTimeout(done, KICK_LINGER_MS);\n link.onClose = done;\n } else {\n link.onClose = null;\n link.close();\n }\n }\n this.connected.delete(peerId);\n this.outbox.delete(peerId);\n this.lastHeard.delete(peerId);\n this.rate.delete(peerId);\n this.lockstep.onPeerLeft(peerId);\n this.chat.onPeerLeft(peerId);\n this.voice.onPeerLeft(peerId);\n this.pause.onPeerLeft(peerId);\n if (peer) this.emit(\"peerLeft\", peer, reason, close);\n if (peerId === this.hostPeerId && !this.isHost) {\n this.handleHostLost(reason);\n }\n }\n\n /** Lockstep drops (stalled, desynced): removed without a ban, so the player can come back (a rejoin resyncs). */\n private dropPeer(peerId: number, reason: string): void {\n this.signaling.send({ t: \"kick\", peerId, ban: false, closeReason: reason } as { t: \"kick\"; peerId: number });\n this.removePeer(peerId, reason, undefined, true);\n }\n\n private setPhase(p: Phase): void {\n if (p !== \"lobby\" && p !== \"in_game\") return;\n if (this.phase === p) return;\n this.phase = p;\n if (p === \"lobby\") this.pause.onLobbyPhase();\n if (p === \"in_game\" && !this.lockstep.started) this.lockstep.markStarted();\n this.emit(\"phase\", p);\n }\n\n private onServerClosed(): void {\n if (this.ended) return;\n if (this.cfg.direct && !this.isHost) {\n this.teardown(\"host_left\");\n return;\n }\n this.serverUp = false;\n this.emit(\"serverLost\");\n // Alone with no peers: nothing keeps this session alive.\n if (this.links.size === 0 && this.roster.size <= 1) this.teardown(\"server_lost\");\n }\n\n // ---- housekeeping ----------------------------------------------------------------------------------------------\n\n private watchdog(): void {\n if (this.ended) return;\n const timeout = this.cfg.peerTimeoutMs ?? 0;\n if (timeout > 0) this.dropSilent(Math.max(timeout, MIN_PEER_TIMEOUT_MS));\n if (this.ended || this.isHost) return;\n if (this.mode === \"lockstep\" && this.lockstep.hostSilent()) {\n this.lockstep.touch();\n this.lockstep.pokeHost(); // a live-but-stalled host answers with a snapshot; a dead one is replaced below\n this.handleHostLost(\"timeout\");\n }\n }\n\n /** peerTimeoutMs: the host drops joiners it has not heard from; a joiner handles a silent host as lost. */\n private dropSilent(timeout: number): void {\n const now = this.cfg.clock.now();\n if (this.isHost) {\n for (const id of [...this.connected]) {\n const last = this.lastHeard.get(id);\n if (last !== undefined && now - last > timeout) this.removePeer(id, \"timeout\");\n }\n } else if (this.isReady) {\n const last = this.lastHeard.get(this.hostPeerId);\n if (last !== undefined && now - last > timeout) {\n this.lastHeard.delete(this.hostPeerId);\n this.handleHostLost(\"timeout\");\n }\n }\n }\n\n private pingHost(): void {\n if (this.ended || this.isHost) return;\n this.sendTo(this.hostPeerId, { type: \"ping\", n: ++this.pingN, t: this.cfg.clock.now() >>> 0 }, 0, \"fast\");\n }\n\n /** Host: report a joiner that is not ready `readyTimeoutMs` after joining as peerFailed(\"timeout\"), once. */\n private watchReady(peerId: number): void {\n const ms = this.cfg.readyTimeoutMs ?? 0;\n let cancel = () => {};\n if (ms > 0) {\n cancel = this.cfg.clock.setTimeout(() => {\n if (!this.notReady.delete(peerId)) return;\n const peer = this.roster.get(peerId);\n if (peer) this.emit(\"peerFailed\", peer, \"timeout\");\n }, ms);\n }\n this.notReady.set(peerId, cancel);\n }\n\n private teardown(reason: string, close?: CloseInfo): void {\n if (this.ended) return;\n this.ended = true;\n this.cancelReadyTimer?.();\n for (const cancel of this.notReady.values()) cancel();\n this.notReady.clear();\n if (!this.isReady) {\n const code = reason === \"ice_failed\" || reason === \"kicked\" ? reason : \"closed\";\n this.failReady(new OneLobbyError(code, `the lobby ended before connecting (${reason})`));\n }\n this.cancelWatchdog?.();\n this.cancelPing?.();\n this.lockstep.stop();\n this.voice.close();\n for (const l of [...this.links.values(), ...this.lingering]) {\n l.onClose = null;\n l.onMessage = null;\n l.close();\n }\n this.links.clear();\n this.earlyIce.clear();\n this.heldOffers.clear();\n this.lingering.clear();\n this.signaling.onClose = null;\n this.signaling.onMessage = null;\n this.signaling.close();\n this.emit(\"sessionEnded\", reason, close);\n }\n\n /** Total in-flight links (diagnostics and tests). */\n get linkCount(): number {\n return this.links.size;\n }\n}\n\nexport { PROTO };\n"]}
@@ -29,3 +29,5 @@ export declare const JOINER_FIRST_RELAY_MS = 10000;
29
29
  /** After the first relay: at most this long for the rest of the list; ends at once when every relay has answered. */
30
30
  export declare const RELAY_REST_WAIT_MS = 1500;
31
31
  export declare const RELAY_REST_POLL_MS = 50;
32
+ /** A relay that never connected this session is skipped after this many failed dials in a row, while another relay is up. */
33
+ export declare const DEAD_RELAY_DIALS = 4;
@@ -33,4 +33,6 @@ export const JOINER_FIRST_RELAY_MS = 10_000;
33
33
  /** After the first relay: at most this long for the rest of the list; ends at once when every relay has answered. */
34
34
  export const RELAY_REST_WAIT_MS = 1500;
35
35
  export const RELAY_REST_POLL_MS = 50;
36
+ /** A relay that never connected this session is skipped after this many failed dials in a row, while another relay is up. */
37
+ export const DEAD_RELAY_DIALS = 4;
36
38
  //# sourceMappingURL=limits.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"limits.js","sourceRoot":"","sources":["../../src/nostr/limits.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,2BAA2B;AAC3B,MAAM,CAAC,MAAM,QAAQ,GAAG,EAAE,CAAC;AAC3B,MAAM,CAAC,MAAM,SAAS,GAAG,IAAI,CAAC;AAC9B,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,CAAC;AAC7B,MAAM,CAAC,MAAM,OAAO,GAAG,MAAM,CAAC;AAC9B,MAAM,CAAC,MAAM,UAAU,GAAG,MAAM,CAAC;AACjC,MAAM,CAAC,MAAM,QAAQ,GAAG,EAAE,CAAC;AAC3B,uHAAuH;AACvH,MAAM,CAAC,MAAM,cAAc,GAAG,GAAG,CAAC;AAClC,MAAM,CAAC,MAAM,aAAa,GAAG,GAAG,GAAG,IAAI,CAAC;AACxC,MAAM,CAAC,MAAM,eAAe,GAAG,MAAM,CAAC,CAAC,6DAA6D;AACpG,MAAM,CAAC,MAAM,OAAO,GAAG,GAAG,CAAC;AAE3B,kDAAkD;AAClD,MAAM,CAAC,MAAM,iBAAiB,GAAG,EAAE,CAAC;AACpC,MAAM,CAAC,MAAM,iBAAiB,GAAG,EAAE,CAAC;AACpC,MAAM,CAAC,MAAM,qBAAqB,GAAG,KAAK,CAAC;AAC3C,MAAM,CAAC,MAAM,WAAW,GAAG,EAAE,CAAC;AAC9B,MAAM,CAAC,MAAM,gBAAgB,GAAG,KAAK,CAAC;AAEtC,2BAA2B;AAC3B,MAAM,CAAC,MAAM,aAAa,GAAG,IAAI,CAAC;AAClC,MAAM,CAAC,MAAM,UAAU,GAAG,MAAM,CAAC;AAEjC,yBAAyB;AACzB,8IAA8I;AAC9I,MAAM,CAAC,MAAM,mBAAmB,GAAG,KAAK,CAAC;AACzC,oGAAoG;AACpG,MAAM,CAAC,MAAM,yBAAyB,GAAG,MAAM,CAAC;AAChD,4EAA4E;AAC5E,MAAM,CAAC,MAAM,qBAAqB,GAAG,MAAM,CAAC;AAC5C,qHAAqH;AACrH,MAAM,CAAC,MAAM,kBAAkB,GAAG,IAAI,CAAC;AACvC,MAAM,CAAC,MAAM,kBAAkB,GAAG,EAAE,CAAC","sourcesContent":["/**\n * Every Nostr limit and timer shared with the C# client. Pinned by `spec/vectors/nostr-limits.json` (test/nostr.test.ts);\n * C# mirror: OneLobby.Direct/Nostr/NostrLimits.cs. Change a number in all three.\n */\n\n// Reliable link (spec s.4)\nexport const BATCH_MS = 30;\nexport const RESEND_MS = 3000;\nexport const MAX_RESENDS = 5;\nexport const BEAT_MS = 10_000;\nexport const SILENCE_MS = 30_000;\nexport const MAX_HELD = 64;\n/** Outbound: queued texts plus unacknowledged frames, at most this many frames and bytes; excess texts are dropped. */\nexport const MAX_OUT_FRAMES = 128;\nexport const MAX_OUT_BYTES = 256 * 1024;\nexport const MAX_FRAME_BYTES = 30_000; // under the 32 KiB content limit, room for the JSON envelope\nexport const TICK_MS = 250;\n\n// Host bridge: new joiner token bucket (spec s.4)\nexport const NEW_SESSION_BURST = 16;\nexport const MAX_SESSION_BURST = 64;\nexport const NEW_SESSION_REFILL_MS = 1_000;\nexport const WAITING_MAX = 64;\nexport const WAITING_STALE_MS = 5_000;\n\n// Joiner socket (spec s.4)\nexport const OPEN_EVERY_MS = 2000;\nexport const GIVE_UP_MS = 15_000;\n\n// Relay waits (spec s.6)\n/** `hostDirect`: how long to wait for a first relay before hosting by IP alone (the IP code shows first, the Nostr code takes over later). */\nexport const HOST_FIRST_RELAY_MS = 3_000;\n/** `hostNostr` (no IP fallback): how long to wait for a first relay before `direct_unreachable`. */\nexport const HOST_NOSTR_FIRST_RELAY_MS = 10_000;\n/** A joiner: how long to wait for a first relay before `connect_failed`. */\nexport const JOINER_FIRST_RELAY_MS = 10_000;\n/** After the first relay: at most this long for the rest of the list; ends at once when every relay has answered. */\nexport const RELAY_REST_WAIT_MS = 1500;\nexport const RELAY_REST_POLL_MS = 50;\n"]}
1
+ {"version":3,"file":"limits.js","sourceRoot":"","sources":["../../src/nostr/limits.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,2BAA2B;AAC3B,MAAM,CAAC,MAAM,QAAQ,GAAG,EAAE,CAAC;AAC3B,MAAM,CAAC,MAAM,SAAS,GAAG,IAAI,CAAC;AAC9B,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,CAAC;AAC7B,MAAM,CAAC,MAAM,OAAO,GAAG,MAAM,CAAC;AAC9B,MAAM,CAAC,MAAM,UAAU,GAAG,MAAM,CAAC;AACjC,MAAM,CAAC,MAAM,QAAQ,GAAG,EAAE,CAAC;AAC3B,uHAAuH;AACvH,MAAM,CAAC,MAAM,cAAc,GAAG,GAAG,CAAC;AAClC,MAAM,CAAC,MAAM,aAAa,GAAG,GAAG,GAAG,IAAI,CAAC;AACxC,MAAM,CAAC,MAAM,eAAe,GAAG,MAAM,CAAC,CAAC,6DAA6D;AACpG,MAAM,CAAC,MAAM,OAAO,GAAG,GAAG,CAAC;AAE3B,kDAAkD;AAClD,MAAM,CAAC,MAAM,iBAAiB,GAAG,EAAE,CAAC;AACpC,MAAM,CAAC,MAAM,iBAAiB,GAAG,EAAE,CAAC;AACpC,MAAM,CAAC,MAAM,qBAAqB,GAAG,KAAK,CAAC;AAC3C,MAAM,CAAC,MAAM,WAAW,GAAG,EAAE,CAAC;AAC9B,MAAM,CAAC,MAAM,gBAAgB,GAAG,KAAK,CAAC;AAEtC,2BAA2B;AAC3B,MAAM,CAAC,MAAM,aAAa,GAAG,IAAI,CAAC;AAClC,MAAM,CAAC,MAAM,UAAU,GAAG,MAAM,CAAC;AAEjC,yBAAyB;AACzB,8IAA8I;AAC9I,MAAM,CAAC,MAAM,mBAAmB,GAAG,KAAK,CAAC;AACzC,oGAAoG;AACpG,MAAM,CAAC,MAAM,yBAAyB,GAAG,MAAM,CAAC;AAChD,4EAA4E;AAC5E,MAAM,CAAC,MAAM,qBAAqB,GAAG,MAAM,CAAC;AAC5C,qHAAqH;AACrH,MAAM,CAAC,MAAM,kBAAkB,GAAG,IAAI,CAAC;AACvC,MAAM,CAAC,MAAM,kBAAkB,GAAG,EAAE,CAAC;AACrC,6HAA6H;AAC7H,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,CAAC","sourcesContent":["/**\n * Every Nostr limit and timer shared with the C# client. Pinned by `spec/vectors/nostr-limits.json` (test/nostr.test.ts);\n * C# mirror: OneLobby.Direct/Nostr/NostrLimits.cs. Change a number in all three.\n */\n\n// Reliable link (spec s.4)\nexport const BATCH_MS = 30;\nexport const RESEND_MS = 3000;\nexport const MAX_RESENDS = 5;\nexport const BEAT_MS = 10_000;\nexport const SILENCE_MS = 30_000;\nexport const MAX_HELD = 64;\n/** Outbound: queued texts plus unacknowledged frames, at most this many frames and bytes; excess texts are dropped. */\nexport const MAX_OUT_FRAMES = 128;\nexport const MAX_OUT_BYTES = 256 * 1024;\nexport const MAX_FRAME_BYTES = 30_000; // under the 32 KiB content limit, room for the JSON envelope\nexport const TICK_MS = 250;\n\n// Host bridge: new joiner token bucket (spec s.4)\nexport const NEW_SESSION_BURST = 16;\nexport const MAX_SESSION_BURST = 64;\nexport const NEW_SESSION_REFILL_MS = 1_000;\nexport const WAITING_MAX = 64;\nexport const WAITING_STALE_MS = 5_000;\n\n// Joiner socket (spec s.4)\nexport const OPEN_EVERY_MS = 2000;\nexport const GIVE_UP_MS = 15_000;\n\n// Relay waits (spec s.6)\n/** `hostDirect`: how long to wait for a first relay before hosting by IP alone (the IP code shows first, the Nostr code takes over later). */\nexport const HOST_FIRST_RELAY_MS = 3_000;\n/** `hostNostr` (no IP fallback): how long to wait for a first relay before `direct_unreachable`. */\nexport const HOST_NOSTR_FIRST_RELAY_MS = 10_000;\n/** A joiner: how long to wait for a first relay before `connect_failed`. */\nexport const JOINER_FIRST_RELAY_MS = 10_000;\n/** After the first relay: at most this long for the rest of the list; ends at once when every relay has answered. */\nexport const RELAY_REST_WAIT_MS = 1500;\nexport const RELAY_REST_POLL_MS = 50;\n/** A relay that never connected this session is skipped after this many failed dials in a row, while another relay is up. */\nexport const DEAD_RELAY_DIALS = 4;\n"]}
@@ -1,5 +1,6 @@
1
1
  import { sha256, toHex, fromHex } from "./crypto.js";
2
2
  import { schnorrPublicKey, schnorrSign } from "./secp256k1.js";
3
+ import { DEAD_RELAY_DIALS } from "./limits.js";
3
4
  export const NOSTR_KIND = 25050;
4
5
  /** NIP-01 event id: SHA-256 of `[0, pubkey, created_at, kind, tags, content]` serialised without whitespace. */
5
6
  export async function eventId(pubkey, createdAt, kind, tags, content) {
@@ -31,7 +32,7 @@ export class RelayPool {
31
32
  waiters = [];
32
33
  constructor(o) {
33
34
  this.o = o;
34
- this.relays = o.urls.map((url) => ({ url, ws: null, open: false, attempted: false, skipped: false, backoff: 1000, cancelRetry: null }));
35
+ this.relays = o.urls.map((url) => ({ url, ws: null, open: false, attempted: false, skipped: false, everOpen: false, fails: 0, backoff: 1000, cancelRetry: null }));
35
36
  }
36
37
  get total() {
37
38
  return this.relays.length;
@@ -114,6 +115,8 @@ export class RelayPool {
114
115
  return;
115
116
  r.open = true;
116
117
  r.attempted = true;
118
+ r.everOpen = true;
119
+ r.fails = 0;
117
120
  r.backoff = 1000;
118
121
  const since = Math.floor(this.o.wall() / 1000) - SINCE_SLACK_S;
119
122
  this.trySend(r, JSON.stringify(["REQ", this.sub, { kinds: [NOSTR_KIND], "#t": [this.o.topic], since }]));
@@ -156,6 +159,13 @@ export class RelayPool {
156
159
  retryLater(r) {
157
160
  if (this.closed || r.skipped || r.cancelRetry)
158
161
  return;
162
+ if (!r.everOpen)
163
+ r.fails++;
164
+ // a relay that is down (never connected, e.g. HTTP 503) is dropped once another relay carries the session
165
+ if (!r.everOpen && r.fails >= DEAD_RELAY_DIALS && this.connected > 0) {
166
+ this.skip(r);
167
+ return;
168
+ }
159
169
  const wait = r.backoff;
160
170
  r.backoff = Math.min(30_000, r.backoff * 2);
161
171
  r.cancelRetry = this.o.clock.setTimeout(() => {