{"version":3,"file":"debug-channel.mjs","sources":["../src/debug-channel.ts"],"sourcesContent":["/**\n * Debug channel — the order-independent handshake between the SDK core and the\n * optional `@colyseus/sdk/debug` overlay.\n *\n * Publishers (a joined room in {@link Client}, a `Predict` instance) call\n * {@link publishDebug} whenever there's something the overlay could surface. If\n * the overlay is already loaded it renders immediately; if it loads LATER — the\n * usual dev-only `import(\"@colyseus/sdk/debug\")` races the first room join — a\n * lightweight buffering stub captures the publishes so the overlay REPLAYS them\n * on install. No app-side ordering (awaiting the import) is required, and a\n * publisher that fires before the overlay loads is never dropped.\n *\n * Production (overlay never imported) stays effectively free: the stub is created\n * only on first publish, holds WeakRefs so nothing is pinned, and is bounded — an\n * app that never loads the overlay leaks neither memory nor room references.\n */\n\n/** The receiver `@colyseus/sdk/debug` installs on `globalThis.__colyseusDebug`. */\nexport interface ColyseusDebugRegistry {\n    publish(channel: string, handle: object): void;\n}\n\ninterface WeakRefLike { deref(): object | undefined; }\n\n// The pre-load buffer stub carries `__buffer`; the overlay's live receiver does\n// NOT. That absence is the discriminator {@link debugOverlayActive} keys on — a\n// buffered-but-unwatched publish must not read as a live overlay (else prod-only\n// diagnostics like reconciler drift bookkeeping would switch on without one).\ninterface BufferStub extends ColyseusDebugRegistry {\n    readonly __buffer: Array<[string, WeakRefLike]>;\n}\n\ntype DebugGlobal = { __colyseusDebug?: ColyseusDebugRegistry & Partial<BufferStub> };\n\n// Old embedded runtimes (some Cocos/Construct targets) lack WeakRef; fall back to\n// a strong ref there — still bounded, so the worst case is a few pinned handles in\n// a debug-less session, never an unbounded leak.\nconst makeRef: (h: object) => WeakRefLike =\n    typeof WeakRef !== \"undefined\" ? (h) => new WeakRef(h) : (h) => ({ deref: () => h });\n\n// A handful of rooms/Predict handles is plenty of replay depth; the bound keeps a\n// debug-less prod session from growing the buffer without limit.\nconst MAX_BUFFERED = 64;\n\n/**\n * Publish a `handle` to the overlay `channel` (`\"room\"` | `\"predict\"` | …).\n * Prod fast path: one property read, then either a live `publish` (overlay\n * loaded) or a bounded WeakRef append (buffered for replay on install).\n */\nexport function publishDebug(channel: string, handle: object): void {\n    const g = globalThis as DebugGlobal;\n    let reg = g.__colyseusDebug;\n    if (!reg) {\n        const buffer: Array<[string, WeakRefLike]> = [];\n        reg = g.__colyseusDebug = {\n            __buffer: buffer,\n            publish(ch: string, h: object) {\n                buffer.push([ch, makeRef(h)]);\n                if (buffer.length > MAX_BUFFERED) { buffer.shift(); }\n            },\n        };\n    }\n    reg.publish(channel, handle);\n}\n\n/**\n * True only when the overlay installed its LIVE receiver — NOT when\n * {@link publishDebug} merely created the pre-load buffer. Diagnostics that must\n * stay free in production (reconciler drift bookkeeping) gate on this.\n */\nexport function debugOverlayActive(): boolean {\n    if (typeof globalThis === \"undefined\") { return false; }\n    const reg = (globalThis as DebugGlobal).__colyseusDebug;\n    return reg != null && reg.__buffer === undefined;\n}\n"],"names":[],"mappings":";;;;;;AAAA;;;;;;;;;;;;;;;AAeG;AAmBH;AACA;AACA;AACA,MAAM,OAAO,GACT,OAAO,OAAO,KAAK,WAAW,GAAG,CAAC,CAAC,KAAK,IAAI,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,KAAK,EAAE,MAAM,CAAC,EAAE,CAAC;AAExF;AACA;AACA,MAAM,YAAY,GAAG,EAAE;AAEvB;;;;AAIG;AACG,SAAU,YAAY,CAAC,OAAe,EAAE,MAAc,EAAA;IACxD,MAAM,CAAC,GAAG,UAAyB;AACnC,IAAA,IAAI,GAAG,GAAG,CAAC,CAAC,eAAe;IAC3B,IAAI,CAAC,GAAG,EAAE;QACN,MAAM,MAAM,GAAiC,EAAE;AAC/C,QAAA,GAAG,GAAG,CAAC,CAAC,eAAe,GAAG;AACtB,YAAA,QAAQ,EAAE,MAAM;YAChB,OAAO,CAAC,EAAU,EAAE,CAAS,EAAA;AACzB,gBAAA,MAAM,CAAC,IAAI,CAAC,CAAC,EAAE,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC;AAC7B,gBAAA,IAAI,MAAM,CAAC,MAAM,GAAG,YAAY,EAAE;oBAAE,MAAM,CAAC,KAAK,EAAE;gBAAE;YACxD,CAAC;SACJ;IACL;AACA,IAAA,GAAG,CAAC,OAAO,CAAC,OAAO,EAAE,MAAM,CAAC;AAChC;AAEA;;;;AAIG;SACa,kBAAkB,GAAA;AAC9B,IAAA,IAAI,OAAO,UAAU,KAAK,WAAW,EAAE;AAAE,QAAA,OAAO,KAAK;IAAE;AACvD,IAAA,MAAM,GAAG,GAAI,UAA0B,CAAC,eAAe;IACvD,OAAO,GAAG,IAAI,IAAI,IAAI,GAAG,CAAC,QAAQ,KAAK,SAAS;AACpD;;;;"}