@smoregg/sdk 2.1.0 → 2.2.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.
@@ -1 +1 @@
1
- {"version":3,"file":"smore-sdk.umd.js","sources":["../../src/transport/protocol.ts","../../src/transport/PostMessageTransport.ts","../../src/errors.ts","../../src/events.ts","../../src/logger.ts","../../src/shared.ts","../../src/screen.ts","../../src/controller.ts","../../src/types.ts"],"sourcesContent":["/**\n * postMessage protocol types for iframe ↔ parent communication.\n *\n * Uses `_bridge:` prefix to clearly distinguish from `smore:*` socket events.\n * - `_bridge:*` = internal iframe postMessage protocol (never on socket)\n * - `smore:*` = platform service events (socket-level, e.g. smore:player-joined)\n */\n\n/**\n * Cross-reference: `CharacterAppearance` (SDK type) has an identical shape to\n * `CharacterDTO` (server type in game-project/types/src/types.ts).\n * If either type changes, the other must be updated to stay in sync.\n */\nimport type { CharacterAppearance } from '../types';\n\nexport const BRIDGE_MSG_PREFIX = '_bridge:' as const;\n\n/** Current SDK protocol version. Incremented on breaking protocol changes. */\nexport const PROTOCOL_VERSION = 1;\n\nexport interface BridgeReadyMessage {\n type: '_bridge:ready';\n protocolVersion?: number;\n}\n\n/**\n * BridgeInitMessage contains player data sent from the platform to the game iframe.\n *\n * **Field naming convention:**\n * The server uses `name` and `character` fields (matching server/Player model naming).\n * SDK code may reference fallback fields like `nickname` and `appearance` for defensive\n * compatibility with potential future field name changes, but currently the server\n * always sends `name` and `character`.\n */\nexport interface BridgeInitMessage {\n type: '_bridge:init';\n payload: {\n // 'host' = screen side, 'player' = controller side (legacy naming)\n side: 'host' | 'player';\n roomCode: string;\n players: Array<{\n playerIndex: number;\n name: string;\n connected: boolean;\n character: CharacterAppearance | null;\n }>;\n myIndex?: number;\n protocolVersion?: number;\n };\n}\n\nexport interface BridgeEmitMessage {\n type: '_bridge:emit';\n payload: {\n event: string;\n data?: unknown;\n ackId?: string;\n };\n}\n\nexport interface BridgeEventMessage {\n type: '_bridge:event';\n payload: {\n event: string;\n data?: unknown;\n };\n}\n\nexport interface BridgeAckMessage {\n type: '_bridge:ack';\n payload: {\n ackId: string;\n data?: unknown;\n };\n}\n\nexport interface BridgeUpdateMessage {\n type: '_bridge:update';\n payload: {\n players?: Array<{\n playerIndex: number;\n name: string;\n connected: boolean;\n character: CharacterAppearance | null;\n }>;\n };\n}\n\nexport type BridgeMessage =\n | BridgeReadyMessage\n | BridgeInitMessage\n | BridgeEmitMessage\n | BridgeEventMessage\n | BridgeAckMessage\n | BridgeUpdateMessage;\n\nexport function isBridgeMessage(data: unknown): data is BridgeMessage {\n return (\n data !== null &&\n typeof data === 'object' &&\n 'type' in data &&\n typeof data.type === 'string' &&\n data.type.startsWith(BRIDGE_MSG_PREFIX)\n );\n}\n\n/**\n * Validates the structure of a _bridge:init payload.\n *\n * Performs runtime validation to ensure the payload contains all required fields\n * with correct types. This provides early error detection if the parent frame\n * sends malformed initialization data.\n *\n * @param payload - The payload to validate\n * @returns true if payload is valid\n * @throws {Error} if validation fails with a descriptive error message\n *\n * @example\n * ```ts\n * try {\n * validateInitPayload(msg.payload);\n * // proceed with initialization\n * } catch (err) {\n * console.error('Invalid init payload:', err.message);\n * }\n * ```\n */\nexport function validateInitPayload(payload: unknown): payload is BridgeInitMessage['payload'] {\n if (!payload || typeof payload !== 'object') {\n throw new Error('[SDK] _bridge:init payload must be an object');\n }\n\n const p = payload as Record<string, unknown>;\n\n // Required: side\n if (typeof p.side !== 'string' || !['host', 'player'].includes(p.side)) {\n throw new Error(`[SDK] _bridge:init payload.side must be \"host\" or \"player\", got: ${p.side}`);\n }\n\n // Required: roomCode\n if (typeof p.roomCode !== 'string' || p.roomCode.length === 0) {\n throw new Error('[SDK] _bridge:init payload.roomCode must be a non-empty string');\n }\n\n // Required: players (array)\n if (!Array.isArray(p.players)) {\n throw new Error('[SDK] _bridge:init payload.players must be an array');\n }\n\n // Optional but validated if present: myIndex (controller-side only)\n if (p.myIndex !== undefined && typeof p.myIndex !== 'number') {\n throw new Error('[SDK] _bridge:init payload.myIndex must be a number if provided');\n }\n\n return true;\n}\n","/**\n * PostMessageTransport - Transport over window.postMessage for iframe-hosted games.\n *\n * Used inside an iframe. Sends `_bridge:emit` to parent and listens for `_bridge:event` from parent.\n */\n\nimport type { Transport, TransportEventHandler } from './types';\nimport type { BridgeEventMessage, BridgeAckMessage } from './protocol';\nimport { isBridgeMessage } from './protocol';\n\n/**\n * PostMessage-based transport for iframe-hosted games.\n *\n * Handles bi-directional communication between iframe game and parent platform using _bridge:* protocol.\n * - Outbound: `_bridge:emit` messages sent to parent\n * - Inbound: `_bridge:event` messages received from parent\n * - Acknowledgment: `_bridge:ack` pattern for request-response flows\n *\n * @example\n * ```ts\n * const transport = new PostMessageTransport('https://smore.gg');\n * transport.on('game-start', (data) => console.log('Game started', data));\n * transport.emit('player-ready', { playerIndex: 0 });\n * ```\n */\nexport class PostMessageTransport implements Transport {\n private static readonly ACK_TIMEOUT = 30000; // 30 seconds\n private handlers = new Map<string, Set<TransportEventHandler>>();\n private ackCallbacks = new Map<string, (...args: unknown[]) => void>();\n private ackCounter = 0;\n private parentOrigin: string;\n private boundMessageHandler: (e: MessageEvent) => void;\n\n constructor(parentOrigin: string = '*') {\n this.parentOrigin = parentOrigin;\n this.boundMessageHandler = this.handleMessage.bind(this);\n window.addEventListener('message', this.boundMessageHandler);\n }\n\n emit(event: string, ...args: unknown[]): void {\n // Detect if last arg is a callback (ack pattern)\n let data: unknown = args[0];\n let ackId: string | undefined;\n\n // Branch 1: emit('event', callback) shorthand — no data, callback only\n // Callback will be invoked when parent sends _bridge:ack with matching ackId\n if (args.length === 1 && typeof args[0] === 'function') {\n data = undefined;\n const callback = args[0] as (...cbArgs: unknown[]) => void;\n ackId = `ack_${++this.ackCounter}`;\n this.ackCallbacks.set(ackId, callback);\n setTimeout(() => {\n if (this.ackCallbacks.has(ackId!)) {\n this.ackCallbacks.delete(ackId!);\n }\n }, PostMessageTransport.ACK_TIMEOUT);\n }\n // Branch 2: emit('event', data, callback) — data + callback (request-response pattern)\n // Parent receives event with data and can send _bridge:ack response\n else if (args.length >= 2 && typeof args[args.length - 1] === 'function') {\n data = args[0];\n const callback = args[args.length - 1] as (...cbArgs: unknown[]) => void;\n ackId = `ack_${++this.ackCounter}`;\n this.ackCallbacks.set(ackId, callback);\n setTimeout(() => {\n if (this.ackCallbacks.has(ackId!)) {\n this.ackCallbacks.delete(ackId!);\n }\n }, PostMessageTransport.ACK_TIMEOUT);\n }\n\n window.parent.postMessage(\n { type: '_bridge:emit', payload: { event, data, ackId } },\n this.parentOrigin,\n );\n }\n\n on(event: string, handler: TransportEventHandler): void {\n let set = this.handlers.get(event);\n if (!set) {\n set = new Set();\n this.handlers.set(event, set);\n }\n set.add(handler);\n }\n\n off(event: string, handler?: TransportEventHandler): void {\n if (!handler) {\n this.handlers.delete(event);\n return;\n }\n this.handlers.get(event)?.delete(handler);\n }\n\n destroy(): void {\n window.removeEventListener('message', this.boundMessageHandler);\n this.handlers.clear();\n this.ackCallbacks.clear();\n }\n\n private handleMessage(e: MessageEvent): void {\n // Origin validation: only accept messages from the expected parent\n if (this.parentOrigin !== '*' && e.origin !== this.parentOrigin) return;\n\n const msg = e.data;\n if (!isBridgeMessage(msg)) return;\n\n // Branch 1: _bridge:event — state sync from bridge (server → bridge → game)\n // Parent relays socket events to iframe via this type. Game subscribes with on().\n if (msg.type === '_bridge:event') {\n const { event, data } = (msg as BridgeEventMessage).payload;\n const set = this.handlers.get(event);\n if (set) {\n set.forEach((handler) => handler(data));\n }\n }\n // Branch 2: _bridge:ack — response to emit with callback (request-response flow)\n // Fires the callback that was passed to emit('event', data, callback).\n // Edge case: In postMessage environment, callbacks cannot be truly serialized,\n // so only data types that survive JSON serialization roundtrip will work.\n else if (msg.type === '_bridge:ack') {\n const { ackId, data } = (msg as BridgeAckMessage).payload;\n const cb = this.ackCallbacks.get(ackId);\n if (cb) {\n this.ackCallbacks.delete(ackId);\n cb(data);\n }\n }\n }\n}\n","import type { SmoreError, SmoreErrorCode } from './types';\n\n/**\n * Base error class for SDK-specific errors with structured metadata.\n *\n * Provides error codes, optional cause chaining, and custom details for debugging.\n * Use this instead of generic Error for all SDK-thrown errors.\n *\n * @example\n * ```ts\n * throw new SmoreSDKError('INVALID_EVENT', 'Event name must not contain \":\"', {\n * details: { event: 'foo:bar' }\n * });\n * ```\n *\n * @example With cause\n * ```ts\n * try {\n * JSON.parse(data);\n * } catch (err) {\n * throw new SmoreSDKError('UNKNOWN', 'Invalid JSON payload', {\n * cause: err as Error,\n * details: { rawData: data }\n * });\n * }\n * ```\n */\nexport class SmoreSDKError extends Error {\n readonly code: SmoreErrorCode;\n /**\n * The original error that caused this error.\n *\n * **Note:** This field intentionally shadows the native `Error.cause` (ES2022).\n * Both this class field and the native property (set via `super()` options bag)\n * are assigned the same value, so there is no behavioral difference.\n * The explicit field provides TypeScript type narrowing to `Error` instead of `unknown`.\n */\n readonly cause?: Error;\n readonly details?: Record<string, unknown>;\n\n constructor(\n code: SmoreErrorCode,\n message: string,\n options?: { cause?: Error; details?: Record<string, unknown> }\n ) {\n super(message, options?.cause ? { cause: options.cause } : undefined);\n this.name = 'SmoreSDKError';\n this.code = code;\n this.cause = options?.cause;\n this.details = options?.details;\n\n const ErrorWithCapture = Error as typeof Error & {\n captureStackTrace?: (target: object, constructor?: Function) => void;\n };\n if (typeof ErrorWithCapture.captureStackTrace === 'function') {\n ErrorWithCapture.captureStackTrace(this, SmoreSDKError);\n }\n }\n\n toSmoreError(): SmoreError {\n return {\n code: this.code,\n message: this.message,\n cause: this.cause,\n details: this.details,\n };\n }\n}\n","/**\n * SDK system event constants (socket level)\n *\n * smore:* prefix = platform service events\n * User events are validated to prevent ':' usage via validateEventName()\n *\n * Note: iframe ↔ parent internal communication uses _bridge:* prefix (transport/protocol.ts)\n */\n\nimport { SmoreSDKError } from './errors';\n\n/**\n * Platform system event names (internal use only).\n *\n * These events are reserved by the S'MORE platform and cannot be used by game code.\n * All platform events use the `smore:` prefix to avoid conflicts with user events.\n *\n * User-defined events are validated to prevent `:` usage via validateEventName().\n *\n * @internal Not part of the public SDK API. Do not import directly.\n */\nexport const SMORE_EVENTS = {\n // Game lifecycle\n GAME_OVER: 'smore:game-over',\n\n // Player management\n PLAYER_JOINED: 'smore:player-joined',\n PLAYER_LEFT: 'smore:player-left',\n PLAYER_DISCONNECTED: 'smore:player-disconnected',\n PLAYER_RECONNECTED: 'smore:player-reconnected',\n\n // Character change\n PLAYER_CHARACTER_UPDATED: 'smore:player-character-updated',\n\n // Rate limiting\n RATE_LIMITED: 'smore:rate-limited',\n\n // Game ready sync\n GAME_READY: 'smore:game-ready',\n ALL_READY: 'smore:all-ready',\n\n // Connection status (self)\n SELF_DISCONNECTED: 'smore:self-disconnected',\n SELF_RECONNECTED: 'smore:self-reconnected',\n\n // Send to specific player (internal use)\n SEND_TO_PLAYER: 'smore:send-to-player', // Used internally by platform, not handled by SDK\n} as const;\n\nexport type SmoreEvent = typeof SMORE_EVENTS[keyof typeof SMORE_EVENTS];\n\nexport const SYSTEM_EVENTS: ReadonlySet<string> = new Set(\n Object.values(SMORE_EVENTS)\n);\n\n\nexport const EVENT_NAME_REGEX = /^[a-zA-Z]([a-zA-Z0-9_-]*[a-zA-Z0-9])?$/;\n\nexport const EVENT_NAME_MAX_LENGTH = 128;\n\n/**\n * Validate a user-defined event name.\n *\n * Enforces naming rules to prevent conflicts with platform system events:\n * - Must start with a letter\n * - Can contain letters, numbers, hyphens, underscores\n * - Must end with a letter or number\n * - Cannot contain `:` (reserved for platform events like `smore:*`)\n * - Maximum length: 128 characters\n *\n * @throws {SmoreSDKError} INVALID_EVENT if validation fails\n *\n * @example\n * ```ts\n * validateEventName('player-ready'); // OK\n * validateEventName('score_update'); // OK\n * validateEventName('tap123'); // OK\n * validateEventName('smore:internal'); // Throws: colon not allowed\n * validateEventName('123start'); // Throws: must start with letter\n * ```\n */\nexport function validateEventName(event: string): void {\n if (!event || typeof event !== 'string') {\n throw new SmoreSDKError('INVALID_EVENT', 'Event name must be a non-empty string');\n }\n if (event.length > EVENT_NAME_MAX_LENGTH) {\n throw new SmoreSDKError(\n 'INVALID_EVENT',\n `Event name exceeds maximum length of ${EVENT_NAME_MAX_LENGTH} characters (got ${event.length}).`,\n { details: { event: event.slice(0, 50) + '...' } }\n );\n }\n if (!EVENT_NAME_REGEX.test(event)) {\n throw new SmoreSDKError(\n 'INVALID_EVENT',\n `Invalid event name \"${event}\". Event names must start with a letter, ` +\n `contain only letters, numbers, hyphens, or underscores, and end with a letter or number.`,\n { details: { event } }\n );\n }\n}\n\n/**\n * Check if an event name is a system event.\n *\n * System events use the `smore:` prefix and are reserved for platform use.\n * Prefix-based check is intentional for forward-compatibility with new system events.\n *\n * @param event - Event name to check\n * @returns true if the event is a system event\n */\nexport function isSystemEvent(event: string): boolean {\n return event.startsWith('smore:');\n}\n\n/**\n * Set of valid Screen lifecycle event names (used for $-prefix routing).\n */\nexport const SCREEN_LIFECYCLE_EVENTS: ReadonlySet<string> = new Set([\n '$all-ready',\n '$controller-join',\n '$controller-leave',\n '$controller-disconnect',\n '$controller-reconnect',\n '$character-updated',\n '$error',\n '$connection-change',\n]);\n\n/**\n * Set of valid Controller lifecycle event names (used for $-prefix routing).\n */\nexport const CONTROLLER_LIFECYCLE_EVENTS: ReadonlySet<string> = new Set([\n ...SCREEN_LIFECYCLE_EVENTS,\n '$game-over',\n]);\n","import type { DebugOptions, LogLevel } from './types';\n\n/**\n * Internal debug logger with configurable verbosity levels.\n *\n * Maps SDK log levels (debug/info/warn/error) to console methods.\n * Can be toggled per-instance with granular control over send/receive/lifecycle logs.\n *\n * @example\n * ```ts\n * const logger = new DebugLogger({ enabled: true, level: 'info' });\n * logger.info('Game initialized');\n * logger.send('player-ready', { index: 0 }); // Shows as debug\n * ```\n */\nexport class DebugLogger {\n private enabled: boolean;\n private level: LogLevel;\n private prefix: string;\n private logSend: boolean;\n private logReceive: boolean;\n private logLifecycle: boolean;\n private customLogger?: (level: LogLevel, message: string, data?: unknown) => void;\n\n private static levelOrder: Record<LogLevel, number> = {\n debug: 0,\n info: 1,\n warn: 2,\n error: 3,\n };\n\n constructor(options?: boolean | DebugOptions, defaultPrefix = '[Smore]') {\n const opts = typeof options === 'boolean' ? { enabled: options } : options;\n this.enabled = opts?.enabled ?? false;\n this.level = opts?.level ?? 'debug';\n this.prefix = opts?.prefix ?? defaultPrefix;\n this.logSend = opts?.logSend ?? true;\n this.logReceive = opts?.logReceive ?? true;\n this.logLifecycle = opts?.logLifecycle ?? true;\n this.customLogger = opts?.logger;\n }\n\n private shouldLog(level: LogLevel): boolean {\n return this.enabled && DebugLogger.levelOrder[level] >= DebugLogger.levelOrder[this.level];\n }\n\n private log(level: LogLevel, message: string, data?: unknown): void {\n if (!this.shouldLog(level)) return;\n\n if (this.customLogger) {\n this.customLogger(level, `${this.prefix} ${message}`, data);\n return;\n }\n\n const consoleMethod = level === 'error' ? 'error' : level === 'warn' ? 'warn' : level === 'debug' ? 'debug' : 'info';\n if (data !== undefined) {\n console[consoleMethod](`${this.prefix} ${message}`, data);\n } else {\n console[consoleMethod](`${this.prefix} ${message}`);\n }\n }\n\n debug(message: string, data?: unknown): void {\n this.log('debug', message, data);\n }\n\n info(message: string, data?: unknown): void {\n this.log('info', message, data);\n }\n\n warn(message: string, data?: unknown): void {\n this.log('warn', message, data);\n }\n\n error(message: string, data?: unknown): void {\n this.log('error', message, data);\n }\n\n send(event: string, data?: unknown): void {\n if (!this.enabled) return;\n if (this.logSend) {\n this.debug(`-> SEND: ${event}`, data);\n }\n }\n\n receive(event: string, data?: unknown): void {\n if (!this.enabled) return;\n if (this.logReceive) {\n this.debug(`<- RECV: ${event}`, data);\n }\n }\n\n lifecycle(message: string, data?: unknown): void {\n if (this.logLifecycle) {\n this.info(`[Lifecycle] ${message}`, data);\n }\n }\n}\n","/**\n * Shared utilities for Screen and Controller implementations.\n * Centralizes common logic to eliminate duplication.\n */\n\nimport type { ControllerInfo } from './types';\nimport { SmoreSDKError } from './errors';\n\n/** Maximum payload size in bytes (64KB). Server silently drops larger payloads. */\nexport const MAX_PAYLOAD_SIZE = 65536;\n\n/**\n * Map raw player data from server/bridge to ControllerInfo.\n * Centralizes the name->nickname and character->appearance field mapping.\n *\n * Server sends: { playerIndex, name, connected, character }\n * SDK exposes: { playerIndex, nickname, connected, appearance }\n */\nexport function mapPlayerDTO(raw: Record<string, unknown>, fallbackIndex: number): ControllerInfo {\n return {\n playerIndex: (raw.playerIndex as number) ?? fallbackIndex,\n nickname: (raw.nickname as string) || (raw.name as string) || `Player ${((raw.playerIndex as number) ?? fallbackIndex) + 1}`,\n connected: raw.connected !== false,\n appearance: (raw.appearance ?? raw.character) as ControllerInfo['appearance'],\n };\n}\n\n/**\n * Validate that event payload does not exceed the 64KB server limit.\n * Throws PAYLOAD_TOO_LARGE error if exceeded.\n */\nexport function validatePayloadSize(data: unknown): void {\n if (data === undefined || data === null) return;\n\n try {\n const serialized = JSON.stringify(data);\n const byteLength = new TextEncoder().encode(serialized).byteLength;\n if (byteLength > MAX_PAYLOAD_SIZE) {\n throw new SmoreSDKError(\n 'PAYLOAD_TOO_LARGE',\n `Event payload exceeds maximum size of ${MAX_PAYLOAD_SIZE} bytes (got ${byteLength} bytes). The server will silently drop this event.`,\n { details: { size: byteLength, limit: MAX_PAYLOAD_SIZE } }\n );\n }\n } catch (err) {\n if (err instanceof SmoreSDKError) throw err;\n // If JSON.stringify fails, the data can't be sent anyway\n }\n}\n","/**\n * createScreen - Factory function for Screen instances (Host/TV side)\n *\n * Synchronous factory with event emitter pattern. Returns a Screen instance\n * immediately. Use `.ready` to await full initialization, and `.on()` /\n * lifecycle methods to register handlers (can be called before ready).\n *\n * @example\n * ```ts\n * interface MyEvents {\n * tap: { x: number; y: number };\n * 'phase-update': { phase: 'lobby' | 'playing' | 'results' };\n * }\n *\n * const screen = createScreen<MyEvents>({ debug: true });\n *\n * screen.on('tap', (playerIndex, data) => {\n * console.log(`Player ${playerIndex} tapped at`, data.x, data.y);\n * });\n *\n * screen.onAllReady(() => startGame());\n * screen.onControllerJoin((playerIndex, info) => addPlayer(playerIndex, info));\n *\n * await screen.ready;\n * screen.broadcast('phase-update', { phase: 'playing' });\n * ```\n */\n\nimport type {\n EventMap,\n EventNames,\n EventData,\n Screen,\n ScreenConfig,\n ScreenEventHandler,\n ControllerInfo,\n PlayerIndex,\n RoomCode,\n GameResults,\n SmoreError,\n CharacterAppearance,\n} from './types';\nimport type { Transport, TransportEventHandler } from './transport/types';\nimport { PostMessageTransport } from './transport/PostMessageTransport';\nimport { isBridgeMessage, validateInitPayload, PROTOCOL_VERSION, type BridgeInitMessage, type BridgeUpdateMessage } from './transport/protocol';\nimport { SmoreSDKError } from './errors';\nimport { SMORE_EVENTS, validateEventName, SCREEN_LIFECYCLE_EVENTS } from './events';\nimport { DebugLogger } from './logger';\nimport { mapPlayerDTO, validatePayloadSize } from './shared';\n\n// =============================================================================\n// CONSTANTS\n// =============================================================================\n\nconst DEFAULT_TIMEOUT = 10000;\n\n// =============================================================================\n// VALIDATION\n// =============================================================================\n\nfunction validatePlayerIndex(playerIndex: PlayerIndex, controllers: readonly ControllerInfo[]): void {\n if (typeof playerIndex !== 'number' || !Number.isInteger(playerIndex)) {\n throw new SmoreSDKError('INVALID_PLAYER', 'Player index must be an integer');\n }\n if (!controllers.some(c => c.playerIndex === playerIndex)) {\n throw new SmoreSDKError(\n 'INVALID_PLAYER',\n `No controller found with player index ${playerIndex}`,\n { details: { playerIndex } }\n );\n }\n}\n\n// =============================================================================\n// SCREEN IMPLEMENTATION\n// =============================================================================\n\nclass ScreenImpl<TEvents extends EventMap> implements Screen<TEvents> {\n private transport: Transport | null = null;\n private config: ScreenConfig;\n private logger: DebugLogger;\n\n private _controllers: ControllerInfo[] = [];\n private _roomCode: RoomCode = '';\n private _isReady = false;\n private _isDestroyed = false;\n private _initTimeoutId: ReturnType<typeof setTimeout> | null = null;\n\n private eventHandlers = new Map<string, Set<ScreenEventHandler<unknown>>>();\n private registeredTransportHandlers: Array<{ event: string; handler: TransportEventHandler }> = [];\n private boundMessageHandler: ((e: MessageEvent) => void) | null = null;\n // Maps user-facing handler -> transport wrappedHandler for proper cleanup in on()/off()\n private handlerToTransport = new Map<Function, { event: string; transportHandler: TransportEventHandler }>();\n\n // Pending handlers registered via on() before transport is ready\n private _pendingHandlers: Array<{ event: string; handler: ScreenEventHandler<unknown> }> = [];\n\n // Unified lifecycle listener map (supports both onXxx() and on('$xxx') patterns)\n private _lifecycleListeners = new Map<string, Set<Function>>();\n\n // Outbound message buffer (messages sent before ready)\n private _outboundBuffer: Array<{ method: string; args: unknown[] }> = [];\n\n // Whether all-ready has fired\n private _allReadyFired = false;\n\n // Self-connection awareness\n private _isConnected = false;\n\n // Protocol versioning\n private _protocolVersion: number = PROTOCOL_VERSION;\n\n // Ready promise\n private _readyResolve!: () => void;\n private _readyReject!: (err: Error) => void;\n readonly ready: Promise<void>;\n\n constructor(config: ScreenConfig = {}) {\n this.config = config;\n this.logger = new DebugLogger(config.debug, '[SmoreScreen]');\n\n // Create ready promise\n this.ready = new Promise<void>((resolve, reject) => {\n this._readyResolve = resolve;\n this._readyReject = reject;\n });\n\n // Start initialization immediately\n this.startInitialization();\n }\n\n // ---------------------------------------------------------------------------\n // Initialization (called in constructor)\n // ---------------------------------------------------------------------------\n\n private startInitialization(): void {\n this.logger.lifecycle('Initializing screen...');\n\n const parentOrigin = this.config.parentOrigin ?? '*';\n const timeout = this.config.timeout ?? DEFAULT_TIMEOUT;\n\n this._initTimeoutId = setTimeout(() => {\n this.cleanup();\n const error = new SmoreSDKError(\n 'TIMEOUT',\n `Screen initialization timed out after ${timeout}ms. ` +\n `Make sure the parent frame sends _bridge:init. ` +\n `Check that the iframe has correct sandbox attributes (allow-scripts required) and same-origin/cross-origin settings. ` +\n `Create a new Screen instance to retry (this instance has been cleaned up).`,\n { details: { timeout } }\n );\n this.handleError(error);\n this._readyReject(error);\n }, timeout);\n\n this.boundMessageHandler = (e: MessageEvent) => {\n if (parentOrigin !== '*' && e.origin !== parentOrigin) return;\n\n const msg = e.data;\n if (!isBridgeMessage(msg)) return;\n\n if (msg.type === '_bridge:init') {\n clearTimeout(this._initTimeoutId!);\n const initPayload = (msg as BridgeInitMessage).payload;\n\n // MIN-A1-1: Runtime validation of _bridge:init payload structure\n try {\n validateInitPayload(initPayload);\n } catch (err) {\n const error = new SmoreSDKError(\n 'INIT_FAILED',\n `Invalid _bridge:init payload: ${err instanceof Error ? err.message : String(err)}`,\n { details: { payload: initPayload } }\n );\n this.logger.warn('_bridge:init validation failed', error);\n this.handleError(error);\n this._readyReject(error);\n return;\n }\n\n const initData = initPayload;\n\n if (initData.side !== 'host') {\n const error = new SmoreSDKError(\n 'INIT_FAILED',\n `Received init for wrong side: ${initData.side}. Expected \"host\".`,\n { details: { side: initData.side } }\n );\n this.handleError(error);\n this._readyReject(error);\n return;\n }\n\n // Initialize transport\n this.transport = this.config.transport ?? new PostMessageTransport(parentOrigin);\n this._roomCode = initData.roomCode;\n\n // Protocol version negotiation\n const serverProtocolVersion = initData.protocolVersion;\n if (serverProtocolVersion !== undefined) {\n this._protocolVersion = serverProtocolVersion;\n if (serverProtocolVersion !== PROTOCOL_VERSION) {\n this.logger.warn(\n `Protocol version mismatch: SDK v${PROTOCOL_VERSION}, server v${serverProtocolVersion}. ` +\n `Some features may not work correctly.`\n );\n }\n }\n\n this._controllers = this.mapControllersFromInit(initData.players);\n\n // MIN-14: Warn if initialized with zero controllers\n if (this._controllers.length === 0) {\n this.logger.warn('Screen initialized with zero controllers');\n }\n\n this.setupEventHandlers();\n\n // Register all pending user event handlers\n for (const { event, handler } of this._pendingHandlers) {\n this.setupUserEventHandler(event, handler);\n }\n this._pendingHandlers = [];\n\n this._isConnected = true;\n this._isReady = true;\n\n // Flush buffered outbound messages\n for (const buffered of this._outboundBuffer) {\n try {\n switch (buffered.method) {\n case 'broadcast':\n this.broadcast(buffered.args[0] as any, buffered.args[1] as any);\n break;\n case 'sendToController':\n this.sendToController(buffered.args[0] as any, buffered.args[1] as any, buffered.args[2] as any);\n break;\n }\n } catch (err) {\n this.handleError(err instanceof SmoreSDKError ? err : new SmoreSDKError('UNKNOWN', 'Failed to flush buffered message'));\n }\n }\n this._outboundBuffer = [];\n\n this.logger.lifecycle('Screen ready', {\n roomCode: this._roomCode,\n controllers: this._controllers.length,\n });\n\n // Auto-signal ready unless explicitly disabled via config\n if (this.config.autoReady !== false) {\n this.logger.lifecycle('Auto-signaling ready (autoReady enabled)');\n this.signalReady();\n }\n\n this._readyResolve();\n } else if (msg.type === '_bridge:update') {\n if (!this._isReady) {\n this.logger.debug('Ignoring _bridge:update before init completes');\n return;\n }\n const updateData = (msg as BridgeUpdateMessage).payload;\n\n if (updateData.players && Array.isArray(updateData.players)) {\n const oldControllers = this._controllers;\n const newControllers = this.mapControllersFromInit(updateData.players);\n this._controllers = newControllers;\n\n // NOTE: _bridge:update is only delivered during initialization or when GameOverlay\n // re-renders (rare). Mid-game player updates are handled by transport events\n // (smore:player-joined, smore:player-left, etc.) which bypass _bridge:update entirely.\n // The join/leave detection below is a defensive fallback, not the primary update path.\n\n // Detect joins\n for (const nc of newControllers) {\n if (!oldControllers.some(oc => oc.playerIndex === nc.playerIndex)) {\n this.logger.lifecycle('Controller joined (via update)', { playerIndex: nc.playerIndex });\n this._emitLifecycle('$controller-join', nc.playerIndex, nc);\n }\n }\n\n // Detect leaves\n for (const oc of oldControllers) {\n if (!newControllers.some(nc => nc.playerIndex === oc.playerIndex)) {\n this.logger.lifecycle('Controller left (via update)', { playerIndex: oc.playerIndex });\n this._emitLifecycle('$controller-leave', oc.playerIndex);\n }\n }\n }\n this.logger.lifecycle('Room updated', {\n controllers: this._controllers.length,\n });\n }\n };\n\n window.addEventListener('message', this.boundMessageHandler);\n\n // Signal ready to parent\n window.parent.postMessage({ type: '_bridge:ready', protocolVersion: PROTOCOL_VERSION }, parentOrigin);\n this.logger.lifecycle('Sent _bridge:ready to parent');\n }\n\n private mapControllersFromInit(players: unknown[]): ControllerInfo[] {\n return (players as Record<string, unknown>[]).map((p, index) => mapPlayerDTO(p, index));\n }\n\n\n private setupEventHandlers(): void {\n if (!this.transport) return;\n\n // System events: player join/leave/reconnect\n // These smore:* events are forwarded by IframeGameBridge's GAME_FACING_EVENTS allowlist.\n // Each handler updates _controllers to stay consistent and prevent duplicate\n // callbacks if _bridge:update also fires with the same data.\n this.registerTransportHandler(SMORE_EVENTS.PLAYER_JOINED, (data: unknown) => {\n const payload = data as { player?: Record<string, unknown> };\n const playerData = payload?.player;\n if (playerData && typeof playerData.playerIndex === 'number') {\n const controllerInfo = mapPlayerDTO(playerData, playerData.playerIndex as number);\n if (this._controllers.some(c => c.playerIndex === controllerInfo.playerIndex)) return;\n this._controllers = [...this._controllers, controllerInfo];\n this.logger.lifecycle('Controller joined', { playerIndex: controllerInfo.playerIndex });\n this._emitLifecycle('$controller-join', controllerInfo.playerIndex, controllerInfo);\n }\n });\n\n this.registerTransportHandler(SMORE_EVENTS.PLAYER_LEFT, (data: unknown) => {\n const payload = data as { player?: { playerIndex?: number }; playerIndex?: number };\n const playerIndex = payload?.player?.playerIndex ?? payload?.playerIndex;\n if (typeof playerIndex === 'number') {\n if (!this._controllers.some(c => c.playerIndex === playerIndex)) return;\n this._controllers = this._controllers.filter(c => c.playerIndex !== playerIndex);\n this.logger.lifecycle('Controller left', { playerIndex });\n this._emitLifecycle('$controller-leave', playerIndex);\n }\n });\n\n this.registerTransportHandler(SMORE_EVENTS.PLAYER_DISCONNECTED, (data: unknown) => {\n const payload = data as { player?: { playerIndex?: number }; playerIndex?: number };\n const playerIndex = payload?.player?.playerIndex ?? payload?.playerIndex;\n if (typeof playerIndex === 'number') {\n this._controllers = this._controllers.map(c =>\n c.playerIndex === playerIndex ? { ...c, connected: false } : c\n );\n this.logger.lifecycle('Controller disconnected', { playerIndex });\n this._emitLifecycle('$controller-disconnect', playerIndex);\n }\n });\n\n this.registerTransportHandler(SMORE_EVENTS.PLAYER_RECONNECTED, (data: unknown) => {\n const payload = data as { player?: Record<string, unknown> };\n const playerData = payload?.player;\n if (playerData && typeof playerData.playerIndex === 'number') {\n const controllerInfo = mapPlayerDTO(playerData, playerData.playerIndex as number);\n this._controllers = this._controllers.map(c =>\n c.playerIndex === controllerInfo.playerIndex ? controllerInfo : c\n );\n this.logger.lifecycle('Controller reconnected', { playerIndex: controllerInfo.playerIndex });\n this._emitLifecycle('$controller-reconnect', controllerInfo.playerIndex, controllerInfo);\n }\n });\n\n // Character updated: update appearance in _controllers\n // Server emits { player: player.toDTO(), room: room.toDTO() }\n this.registerTransportHandler(SMORE_EVENTS.PLAYER_CHARACTER_UPDATED, (data: unknown) => {\n const payload = data as { player?: { playerIndex?: number; character?: Record<string, unknown> | null; name?: string; nickname?: string } };\n const playerData = payload?.player;\n if (playerData && typeof playerData.playerIndex === 'number') {\n const pi = playerData.playerIndex;\n const appearance = (playerData.character ?? null) as ControllerInfo['appearance'];\n this._controllers = this._controllers.map(c =>\n c.playerIndex === pi ? { ...c, appearance } : c\n );\n this.logger.lifecycle('Player character updated', { playerIndex: pi });\n this._emitLifecycle('$character-updated', pi, appearance ?? null);\n }\n });\n\n // Rate limited: route through error handling\n this.registerTransportHandler(SMORE_EVENTS.RATE_LIMITED, (data: unknown) => {\n const payload = data as { event?: string };\n const eventName = payload?.event ?? 'unknown';\n this.handleError(\n new SmoreSDKError('RATE_LIMITED', `Server rate-limited event: ${eventName}`, {\n details: { event: eventName },\n })\n );\n });\n\n // All ready: all participants have signaled ready\n this.registerTransportHandler(SMORE_EVENTS.ALL_READY, () => {\n this.logger.lifecycle('All participants ready');\n this._allReadyFired = true;\n this._emitLifecycle('$all-ready');\n });\n\n // Self connection status\n this.registerTransportHandler(SMORE_EVENTS.SELF_DISCONNECTED, () => {\n this._isConnected = false;\n this.logger.lifecycle('Connection lost');\n this._emitLifecycle('$connection-change', false);\n });\n\n this.registerTransportHandler(SMORE_EVENTS.SELF_RECONNECTED, () => {\n this._isConnected = true;\n this.logger.lifecycle('Connection restored');\n this._emitLifecycle('$connection-change', true);\n });\n }\n\n /**\n * Sets up a user event handler with playerIndex extraction.\n *\n * Events received from controllers are dropped if they lack a playerIndex field.\n * This is a security measure to prevent controller impersonation - the relay server\n * automatically attaches playerIndex based on the sender's authenticated session,\n * ensuring controllers cannot forge events as other players.\n *\n * Note: `playerIndex` is a reserved field name in event payloads.\n * It is automatically extracted by the SDK and passed as the first argument\n * to Screen event handlers. Game developers must NOT use `playerIndex` as\n * a custom data field name -- it will be stripped from the data object.\n */\n private setupUserEventHandler(event: string, handler: ScreenEventHandler<unknown>): void {\n const wrappedHandler = (data: unknown) => {\n this.logger.receive(event, data);\n const payload = data as { playerIndex?: number };\n // `playerIndex` is a reserved field injected by the relay server.\n // It is extracted here and passed as the first argument to the handler.\n const { playerIndex, ...rest } = payload as { playerIndex?: number; [key: string]: unknown };\n if (typeof playerIndex === 'number') {\n try {\n handler(playerIndex, rest);\n } catch (err) {\n this.handleError(\n new SmoreSDKError('UNKNOWN', `Error in handler for event \"${event}\"`, {\n cause: err instanceof Error ? err : undefined,\n details: { event, playerIndex },\n })\n );\n }\n } else {\n // Drop events without playerIndex to prevent impersonation.\n // The relay server attaches playerIndex automatically based on sender's session.\n this.logger.debug(`Dropping event \"${event}\" without playerIndex`, data);\n }\n };\n\n this.registerTransportHandler(event, wrappedHandler);\n\n // Also store in eventHandlers for on/off management\n let handlers = this.eventHandlers.get(event);\n if (!handlers) {\n handlers = new Set();\n this.eventHandlers.set(event, handlers);\n }\n handlers.add(handler);\n\n // Map user handler to transport handler for cleanup\n this.handlerToTransport.set(handler as Function, { event, transportHandler: wrappedHandler });\n }\n\n private registerTransportHandler(event: string, handler: TransportEventHandler): void {\n if (!this.transport) return;\n this.transport.on(event, handler);\n this.registeredTransportHandlers.push({ event, handler });\n }\n\n // ---------------------------------------------------------------------------\n // Properties (readonly)\n // ---------------------------------------------------------------------------\n\n /**\n * Returns a new shallow copy of the controllers array on every access.\n * Cache the result if accessing repeatedly in the same frame/tick.\n */\n get controllers(): readonly ControllerInfo[] {\n return [...this._controllers];\n }\n\n get roomCode(): RoomCode {\n return this._roomCode;\n }\n\n get isReady(): boolean {\n return this._isReady;\n }\n\n get isDestroyed(): boolean {\n return this._isDestroyed;\n }\n\n get isConnected(): boolean {\n return this._isConnected;\n }\n\n get protocolVersion(): number {\n return this._protocolVersion;\n }\n\n // ---------------------------------------------------------------------------\n // Lifecycle Listener Helpers\n // ---------------------------------------------------------------------------\n\n private _addLifecycleListener(event: string, listener: Function): () => void {\n let set = this._lifecycleListeners.get(event);\n if (!set) {\n set = new Set();\n this._lifecycleListeners.set(event, set);\n }\n set.add(listener);\n return () => {\n set!.delete(listener);\n if (set!.size === 0) this._lifecycleListeners.delete(event);\n };\n }\n\n private _emitLifecycle(event: string, ...args: unknown[]): void {\n this._lifecycleListeners.get(event)?.forEach(cb => {\n try {\n (cb as Function)(...args);\n } catch (err) {\n this.handleError(\n new SmoreSDKError('UNKNOWN', `Error in lifecycle handler for \"${event}\"`, {\n cause: err instanceof Error ? err : undefined,\n details: { event },\n })\n );\n }\n });\n }\n\n private _hasLifecycleListeners(event: string): boolean {\n const set = this._lifecycleListeners.get(event);\n return set !== undefined && set.size > 0;\n }\n\n // ---------------------------------------------------------------------------\n // Lifecycle Methods\n // ---------------------------------------------------------------------------\n\n onAllReady(callback: () => void): () => void {\n if (this._allReadyFired) {\n callback();\n }\n return this._addLifecycleListener('$all-ready', callback);\n }\n\n onControllerJoin(callback: (playerIndex: PlayerIndex, info: ControllerInfo) => void): () => void {\n return this._addLifecycleListener('$controller-join', callback);\n }\n\n onControllerLeave(callback: (playerIndex: PlayerIndex) => void): () => void {\n return this._addLifecycleListener('$controller-leave', callback);\n }\n\n onControllerDisconnect(callback: (playerIndex: PlayerIndex) => void): () => void {\n return this._addLifecycleListener('$controller-disconnect', callback);\n }\n\n onControllerReconnect(callback: (playerIndex: PlayerIndex, info: ControllerInfo) => void): () => void {\n return this._addLifecycleListener('$controller-reconnect', callback);\n }\n\n onCharacterUpdated(callback: (playerIndex: PlayerIndex, appearance: CharacterAppearance | null) => void): () => void {\n return this._addLifecycleListener('$character-updated', callback);\n }\n\n onError(callback: (error: SmoreError) => void): () => void {\n return this._addLifecycleListener('$error', callback);\n }\n\n onConnectionChange(callback: (connected: boolean) => void): () => void {\n return this._addLifecycleListener('$connection-change', callback);\n }\n\n // ---------------------------------------------------------------------------\n // Communication Methods\n // ---------------------------------------------------------------------------\n\n /**\n * Send type-safe events to all controllers.\n *\n * Uses EventMap generic for compile-time type checking of event names and data payloads.\n *\n * @note Data should be an object. Primitive values will be wrapped as `{ data: value }` by the relay server.\n * @note Maximum payload size is 64KB. Data exceeding this limit will be silently dropped by the server.\n * @note Fire-and-forget sends (no callback) will silently fail if rate-limited.\n * Use the onError callback or smore:rate-limited event to detect rate limiting.\n *\n * Warning: Avoid sending primitive values directly (string, number, boolean).\n * Wrap in an object: broadcast('event', { value: 42 }) instead of broadcast('event', 42)\n */\n broadcast<K extends EventNames<TEvents>>(event: K, data: EventData<TEvents, K>): void {\n if (this._isDestroyed) {\n throw new SmoreSDKError('DESTROYED', 'Cannot call broadcast() after destroy()');\n }\n if (!this._isReady || !this.transport) {\n this._outboundBuffer.push({ method: 'broadcast', args: [event, data] });\n this.logger.debug(`Buffered broadcast \"${event}\" (screen not ready yet)`);\n return;\n }\n validateEventName(event);\n validatePayloadSize(data);\n this.logger.send(event, data);\n this.transport!.emit(event, data);\n }\n\n /**\n * Send an event to a specific controller.\n *\n * **Reserved field:** `targetPlayerIndex` is automatically merged into the data payload\n * to route the event to the specified controller. Game developers should avoid using\n * `targetPlayerIndex` as a custom data field name to prevent conflicts.\n *\n * @note Data should be an object. Primitive values will be wrapped as `{ data: value }` by the relay server.\n * @note Maximum payload size is 64KB. Data exceeding this limit will be silently dropped by the server.\n *\n * @param playerIndex - Target controller's player index\n * @param event - Event name\n * @param data - Event data payload\n */\n sendToController<K extends EventNames<TEvents>>(\n playerIndex: PlayerIndex,\n event: K,\n data: EventData<TEvents, K>\n ): void {\n if (this._isDestroyed) {\n throw new SmoreSDKError('DESTROYED', 'Cannot call sendToController() after destroy()');\n }\n if (!this._isReady || !this.transport) {\n this._outboundBuffer.push({ method: 'sendToController', args: [playerIndex, event, data] });\n this.logger.debug(`Buffered sendToController \"${event}\" -> Player ${playerIndex} (screen not ready yet)`);\n return;\n }\n validateEventName(event);\n validatePlayerIndex(playerIndex, this._controllers);\n validatePayloadSize(data);\n\n // MIN-A2-2: Warn if targetPlayerIndex already exists in data (reserved field)\n if (data && typeof data === 'object' && 'targetPlayerIndex' in data) {\n this.logger.warn(\n `Event \"${event}\" data contains reserved field \"targetPlayerIndex\" which will be overwritten for routing.`\n );\n }\n\n this.logger.send(`${event} -> Player ${playerIndex}`, data);\n this.transport!.emit(event, {\n targetPlayerIndex: playerIndex,\n ...(data && typeof data === 'object' ? data : { data }),\n });\n }\n\n // ---------------------------------------------------------------------------\n // Game Lifecycle\n // ---------------------------------------------------------------------------\n\n gameOver(results?: GameResults): void {\n this.ensureReady('gameOver');\n this.logger.lifecycle('Game over', results);\n this.transport!.emit(SMORE_EVENTS.GAME_OVER, { results });\n }\n\n signalReady(): void {\n this.ensureReady('signalReady');\n this.logger.lifecycle('Signaling ready');\n this.transport!.emit(SMORE_EVENTS.GAME_READY, {});\n }\n\n // ---------------------------------------------------------------------------\n // Event Subscription\n // ---------------------------------------------------------------------------\n\n /**\n * Register an event handler for messages from controllers.\n *\n * Can be called before the Screen is ready. Handlers registered before ready\n * are queued and activated when the transport becomes available.\n */\n on<K extends EventNames<TEvents>>(\n event: K,\n handler: ScreenEventHandler<EventData<TEvents, K>>\n ): () => void {\n // Route lifecycle events ($-prefixed)\n if (typeof event === 'string' && (event as string).startsWith('$')) {\n const validEvents = SCREEN_LIFECYCLE_EVENTS;\n if (!validEvents.has(event as string)) {\n throw new SmoreSDKError('INVALID_EVENT', `Unknown lifecycle event: \"${event}\". Valid lifecycle events: ${Array.from(validEvents).join(', ')}`);\n }\n // Special handling for $all-ready: fire immediately if already happened\n if (event === '$all-ready' && this._allReadyFired) {\n (handler as unknown as () => void)();\n }\n return this._addLifecycleListener(event as string, handler as Function);\n }\n\n validateEventName(event);\n\n let handlers = this.eventHandlers.get(event);\n if (!handlers) {\n handlers = new Set();\n this.eventHandlers.set(event, handlers);\n }\n handlers.add(handler as ScreenEventHandler<unknown>);\n\n // If transport ready, register immediately\n if (this.transport) {\n const wrappedHandler = (data: unknown) => {\n this.logger.receive(event, data);\n const payload = data as { playerIndex?: number };\n const { playerIndex, ...rest } = payload as { playerIndex?: number; [key: string]: unknown };\n if (typeof playerIndex === 'number') {\n try {\n handler(playerIndex, rest as EventData<TEvents, K>);\n } catch (err) {\n this.handleError(\n new SmoreSDKError('UNKNOWN', `Error in handler for event \"${event}\"`, {\n cause: err instanceof Error ? err : undefined,\n })\n );\n }\n } else {\n this.logger.debug(`Dropping event \"${event}\" without playerIndex`, data);\n }\n };\n this.registerTransportHandler(event, wrappedHandler);\n this.handlerToTransport.set(handler as Function, { event, transportHandler: wrappedHandler });\n } else {\n // Store for later registration when transport becomes available\n this._pendingHandlers.push({ event: event as string, handler: handler as ScreenEventHandler<unknown> });\n }\n\n // Return unsubscribe function\n return () => {\n handlers?.delete(handler as ScreenEventHandler<unknown>);\n if (handlers?.size === 0) {\n this.eventHandlers.delete(event);\n }\n\n // Remove from pending if not yet registered\n this._pendingHandlers = this._pendingHandlers.filter(\n p => !(p.event === event && p.handler === handler)\n );\n\n // Remove from transport if registered\n const entry = this.handlerToTransport.get(handler as Function);\n if (entry) {\n this.transport?.off(event, entry.transportHandler);\n this.registeredTransportHandlers = this.registeredTransportHandlers.filter(\n h => h.handler !== entry.transportHandler\n );\n this.handlerToTransport.delete(handler as Function);\n }\n };\n }\n\n /**\n * Register an event handler that will be called only once.\n *\n * The handler is automatically removed after the first invocation.\n *\n * **Important:** The wrapped handler cannot be removed via `off(event, originalHandler)`.\n * Use the returned unsubscribe function instead.\n *\n * @param event - Event name to listen for\n * @param handler - Handler function to call once\n * @returns Unsubscribe function to remove the handler before it fires\n */\n once<K extends EventNames<TEvents>>(\n event: K,\n handler: ScreenEventHandler<EventData<TEvents, K>>\n ): () => void {\n if (typeof event === 'string' && (event as string).startsWith('$')) {\n const validEvents = SCREEN_LIFECYCLE_EVENTS;\n if (!validEvents.has(event as string)) {\n throw new SmoreSDKError('INVALID_EVENT', `Unknown lifecycle event: \"${event}\"`);\n }\n if (event === '$all-ready' && this._allReadyFired) {\n (handler as unknown as () => void)();\n return () => {};\n }\n const wrapper = (...args: unknown[]) => {\n unsub();\n (handler as Function)(...args);\n };\n const unsub = this._addLifecycleListener(event as string, wrapper);\n return unsub;\n }\n\n const wrappedHandler: ScreenEventHandler<EventData<TEvents, K>> = (playerIndex, data) => {\n unsubscribe();\n handler(playerIndex, data);\n };\n const unsubscribe = this.on(event, wrappedHandler);\n return unsubscribe;\n }\n\n off<K extends EventNames<TEvents>>(\n event: K,\n handler?: ScreenEventHandler<EventData<TEvents, K>>\n ): void {\n if (typeof event === 'string' && (event as string).startsWith('$')) {\n if (!handler) {\n this._lifecycleListeners.delete(event as string);\n } else {\n this._lifecycleListeners.get(event as string)?.delete(handler as Function);\n }\n return;\n }\n\n if (!handler) {\n // Remove all handlers for this event\n this.eventHandlers.delete(event);\n this.transport?.off(event);\n this.registeredTransportHandlers = this.registeredTransportHandlers.filter(h => h.event !== event);\n for (const [key, val] of this.handlerToTransport) {\n if (val.event === event) this.handlerToTransport.delete(key);\n }\n // Remove from pending\n this._pendingHandlers = this._pendingHandlers.filter(p => p.event !== event);\n } else {\n const handlers = this.eventHandlers.get(event);\n handlers?.delete(handler as ScreenEventHandler<unknown>);\n if (handlers?.size === 0) {\n this.eventHandlers.delete(event);\n }\n // Remove specific transport handler\n const entry = this.handlerToTransport.get(handler as Function);\n if (entry) {\n this.transport?.off(event, entry.transportHandler);\n this.registeredTransportHandlers = this.registeredTransportHandlers.filter(\n h => h.handler !== entry.transportHandler\n );\n this.handlerToTransport.delete(handler as Function);\n }\n // Remove from pending\n this._pendingHandlers = this._pendingHandlers.filter(\n p => !(p.event === event && p.handler === handler)\n );\n }\n }\n\n removeAllListeners(event?: string): void {\n if (event) {\n // Remove all handlers for specific event\n this.eventHandlers.delete(event);\n this.transport?.off(event);\n this.registeredTransportHandlers = this.registeredTransportHandlers.filter(h => h.event !== event);\n for (const [key, val] of this.handlerToTransport) {\n if (val.event === event) this.handlerToTransport.delete(key);\n }\n this._pendingHandlers = this._pendingHandlers.filter(p => p.event !== event);\n } else {\n // Remove all user event handlers\n for (const evt of [...this.eventHandlers.keys()]) {\n this.removeAllListeners(evt);\n }\n }\n }\n\n // ---------------------------------------------------------------------------\n // Utilities\n // ---------------------------------------------------------------------------\n\n getController(playerIndex: PlayerIndex): ControllerInfo | undefined {\n return this._controllers.find((c) => c.playerIndex === playerIndex);\n }\n\n getControllerCount(): number {\n return this._controllers.filter((c) => c.connected).length;\n }\n\n // ---------------------------------------------------------------------------\n // Cleanup\n // ---------------------------------------------------------------------------\n\n destroy(): void {\n if (this._isDestroyed) return;\n\n this.logger.lifecycle('Destroying screen...');\n this._isDestroyed = true;\n this._isReady = false;\n\n this.cleanup();\n this.logger.lifecycle('Screen destroyed');\n }\n\n private cleanup(): void {\n // Clear init timeout if still pending\n if (this._initTimeoutId) {\n clearTimeout(this._initTimeoutId);\n this._initTimeoutId = null;\n }\n\n // Remove all registered transport handlers\n for (const { event, handler } of this.registeredTransportHandlers) {\n this.transport?.off(event, handler);\n }\n this.registeredTransportHandlers = [];\n\n // Clear event handlers\n this.eventHandlers.clear();\n this.handlerToTransport.clear();\n this._pendingHandlers = [];\n\n // Clear lifecycle callbacks\n this._lifecycleListeners.clear();\n this._isConnected = false;\n this._outboundBuffer = [];\n\n // Destroy transport\n if (this.transport instanceof PostMessageTransport) {\n this.transport.destroy();\n }\n this.transport = null;\n\n // Remove message listener\n if (this.boundMessageHandler) {\n window.removeEventListener('message', this.boundMessageHandler);\n this.boundMessageHandler = null;\n }\n }\n\n // ---------------------------------------------------------------------------\n // Error Handling\n // ---------------------------------------------------------------------------\n\n private handleError(error: SmoreSDKError): void {\n // Always log at warn level so errors are never completely silent\n this.logger.warn(`Error in handler: ${error.message}`);\n const smoreError = error.toSmoreError();\n if (this._hasLifecycleListeners('$error')) {\n this._emitLifecycle('$error', smoreError);\n } else {\n this.logger.error(error.message, error.details);\n }\n }\n\n private ensureReady(method: string): void {\n if (this._isDestroyed) {\n throw new SmoreSDKError(\n 'DESTROYED',\n `Cannot call ${method}() after destroy()`,\n { details: { method } }\n );\n }\n if (!this._isReady || !this.transport) {\n throw new SmoreSDKError(\n 'NOT_READY',\n `Cannot call ${method}() before screen is ready. Use await screen.ready.`,\n { details: { method } }\n );\n }\n }\n}\n\n// =============================================================================\n// FACTORY FUNCTION\n// =============================================================================\n\n/**\n * Create a Screen instance for the host/TV side of your game.\n *\n * Returns a Screen instance synchronously. The screen begins listening\n * for the bridge init message immediately. Register event handlers and\n * lifecycle callbacks on the instance, then await `.ready` if needed.\n *\n * @template TEvents - Event map type for type-safe events\n * @param config - Screen configuration (debug, parentOrigin, timeout)\n * @returns Screen instance\n *\n * @example\n * ```ts\n * const screen = createScreen<MyEvents>({ debug: true });\n *\n * screen.on('tap', (playerIndex, data) => {\n * screen.broadcast('round-result', { winner: playerIndex });\n * });\n *\n * screen.onAllReady(() => startGame());\n * screen.onControllerJoin((playerIndex, info) => addPlayer(playerIndex, info));\n *\n * await screen.ready;\n * ```\n */\nexport function createScreen<TEvents extends EventMap = EventMap>(\n config?: ScreenConfig\n): Screen<TEvents> {\n return new ScreenImpl<TEvents>(config);\n}\n","/**\n * createController - Factory function for creating a Controller instance.\n *\n * Returns a Controller instance synchronously. The controller begins listening\n * for the bridge init message immediately. Use `.ready` to await full\n * initialization, and `.on()` / lifecycle methods to register handlers\n * (can be called before ready).\n *\n * @example\n * ```ts\n * const controller = createController<MyEvents>({ debug: true });\n *\n * controller.on('phase-update', (data) => setPhase(data.phase));\n * controller.onAllReady(() => console.log('Ready!'));\n *\n * await controller.ready;\n * controller.send('tap', { x: 100, y: 200 });\n * ```\n */\n\nimport type {\n Controller,\n ControllerConfig,\n ControllerEventHandler,\n ControllerInfo,\n EventData,\n EventMap,\n EventNames,\n PlayerIndex,\n RoomCode,\n SmoreError,\n GameResults,\n CharacterAppearance,\n} from './types';\nimport { PostMessageTransport } from './transport/PostMessageTransport';\nimport type { Transport, TransportEventHandler } from './transport/types';\nimport {\n isBridgeMessage,\n validateInitPayload,\n PROTOCOL_VERSION,\n type BridgeInitMessage,\n type BridgeUpdateMessage,\n} from './transport/protocol';\nimport { SmoreSDKError } from './errors';\nimport { SMORE_EVENTS, validateEventName, CONTROLLER_LIFECYCLE_EVENTS } from './events';\nimport { DebugLogger } from './logger';\nimport { mapPlayerDTO, validatePayloadSize } from './shared';\n\n// =============================================================================\n// CONSTANTS\n// =============================================================================\n\nconst DEFAULT_TIMEOUT = 10000;\n\n// =============================================================================\n// CONTROLLER IMPLEMENTATION\n// =============================================================================\n\nclass ControllerImpl<TEvents extends EventMap> implements Controller<TEvents> {\n private transport: Transport | null = null;\n private config: ControllerConfig;\n private logger: DebugLogger;\n private _roomCode: RoomCode = '';\n private _myPlayerIndex: PlayerIndex = -1;\n private _isReady: boolean = false;\n private _isDestroyed: boolean = false;\n private _initTimeoutId: ReturnType<typeof setTimeout> | null = null;\n private boundMessageHandler: ((e: MessageEvent) => void) | null = null;\n private registeredHandlers: Array<{ event: string; handler: TransportEventHandler }> = [];\n private eventListeners = new Map<string, Set<ControllerEventHandler<unknown>>>();\n // Maps user-facing handler -> transport wrappedHandler for proper cleanup in on()/off()\n private handlerToTransport = new Map<Function, { event: string; transportHandler: TransportEventHandler }>();\n private _controllers: ControllerInfo[] = [];\n\n // Pending handlers registered via on() before transport is ready\n private _pendingHandlers: Array<{ event: string; handler: ControllerEventHandler<unknown> }> = [];\n\n // Unified lifecycle listener map (supports both onXxx() and on('$xxx') patterns)\n private _lifecycleListeners = new Map<string, Set<Function>>();\n\n // Outbound message buffer (messages sent before ready)\n private _outboundBuffer: Array<{ method: string; args: unknown[] }> = [];\n\n // Whether all-ready has fired\n private _allReadyFired = false;\n\n // Self-connection awareness\n private _isConnected = false;\n\n // Protocol versioning\n private _protocolVersion: number = PROTOCOL_VERSION;\n\n // Ready promise\n private _readyResolve!: () => void;\n private _readyReject!: (err: Error) => void;\n readonly ready: Promise<void>;\n\n constructor(config: ControllerConfig = {}) {\n this.config = config;\n this.logger = new DebugLogger(config.debug, '[SmoreController]');\n\n // Create ready promise\n this.ready = new Promise<void>((resolve, reject) => {\n this._readyResolve = resolve;\n this._readyReject = reject;\n });\n\n // Start initialization immediately\n this.startInitialization();\n }\n\n // ---------------------------------------------------------------------------\n // Properties (readonly)\n // ---------------------------------------------------------------------------\n\n get myPlayerIndex(): PlayerIndex {\n return this._myPlayerIndex;\n }\n\n get roomCode(): RoomCode {\n return this._roomCode;\n }\n\n get isReady(): boolean {\n return this._isReady;\n }\n\n get isDestroyed(): boolean {\n return this._isDestroyed;\n }\n\n get isConnected(): boolean {\n return this._isConnected;\n }\n\n get protocolVersion(): number {\n return this._protocolVersion;\n }\n\n /**\n * Read-only list of all known controllers (players) in the room.\n * Returns full ControllerInfo including playerIndex, nickname, connected status, and appearance.\n *\n * Returns a new shallow copy on every access. Cache the result if accessing\n * repeatedly in the same frame/tick.\n */\n get controllers(): readonly ControllerInfo[] {\n return [...this._controllers];\n }\n\n /**\n * Returns the number of currently connected players.\n */\n getControllerCount(): number {\n return this._controllers.filter(c => c.connected).length;\n }\n\n getController(playerIndex: PlayerIndex): ControllerInfo | undefined {\n return this._controllers.find((c) => c.playerIndex === playerIndex);\n }\n\n // ---------------------------------------------------------------------------\n // Initialization\n // ---------------------------------------------------------------------------\n\n private startInitialization(): void {\n const parentOrigin = this.config.parentOrigin ?? '*';\n const timeout = this.config.timeout ?? DEFAULT_TIMEOUT;\n\n this.logger.lifecycle('Initializing controller...', { parentOrigin, timeout });\n\n this._initTimeoutId = setTimeout(() => {\n this.cleanup();\n const error = new SmoreSDKError(\n 'TIMEOUT',\n `Controller initialization timed out after ${timeout}ms. ` +\n `Make sure the parent window sends _bridge:init message. ` +\n `Check that the iframe has correct sandbox attributes (allow-scripts required) and same-origin/cross-origin settings. ` +\n `Create a new Controller instance to retry (this instance has been cleaned up).`,\n { details: { timeout } },\n );\n this.handleError(error);\n this._readyReject(error);\n }, timeout);\n\n // Listen for init message from parent\n this.boundMessageHandler = (e: MessageEvent) => {\n if (parentOrigin !== '*' && e.origin !== parentOrigin) return;\n\n const msg = e.data;\n if (!isBridgeMessage(msg)) return;\n\n if (msg.type === '_bridge:init') {\n clearTimeout(this._initTimeoutId!);\n this.handleInit(msg as BridgeInitMessage, parentOrigin);\n } else if (msg.type === '_bridge:update') {\n this.handleUpdate(msg as BridgeUpdateMessage);\n }\n };\n\n window.addEventListener('message', this.boundMessageHandler);\n\n // Signal ready to parent\n this.logger.lifecycle('Sending _bridge:ready to parent');\n window.parent.postMessage({ type: '_bridge:ready', protocolVersion: PROTOCOL_VERSION }, parentOrigin);\n }\n\n private handleInit(\n msg: BridgeInitMessage,\n parentOrigin: string,\n ): void {\n const initPayload = msg.payload;\n\n this.logger.debug('Received _bridge:init', initPayload);\n\n // MIN-A1-1: Runtime validation of _bridge:init payload structure\n try {\n validateInitPayload(initPayload);\n } catch (err) {\n const error = new SmoreSDKError(\n 'INIT_FAILED',\n `Invalid _bridge:init payload: ${err instanceof Error ? err.message : String(err)}`,\n { details: { payload: initPayload } }\n );\n this.logger.warn('_bridge:init validation failed', error);\n this.handleError(error);\n this._readyReject(error);\n return;\n }\n\n const initData = initPayload;\n\n if (initData.side !== 'player') {\n const error = new SmoreSDKError(\n 'INIT_FAILED',\n `Controller received init for wrong side: ${initData.side}`,\n { details: { side: initData.side } },\n );\n this.handleError(error);\n this._readyReject(error);\n return;\n }\n\n if (initData.myIndex === undefined) {\n const error = new SmoreSDKError(\n 'INIT_FAILED',\n 'Missing myIndex in init payload',\n { details: initData },\n );\n this.handleError(error);\n this._readyReject(error);\n return;\n }\n\n // Initialize transport\n this.transport = this.config.transport ?? new PostMessageTransport(parentOrigin);\n this._roomCode = initData.roomCode;\n\n // Protocol version negotiation\n const serverProtocolVersion = initData.protocolVersion;\n if (serverProtocolVersion !== undefined) {\n this._protocolVersion = serverProtocolVersion;\n if (serverProtocolVersion !== PROTOCOL_VERSION) {\n this.logger.warn(\n `Protocol version mismatch: SDK v${PROTOCOL_VERSION}, server v${serverProtocolVersion}. ` +\n `Some features may not work correctly.`\n );\n }\n }\n\n this._myPlayerIndex = initData.myIndex;\n\n // Track known players for join/leave detection (full ControllerInfo)\n const initPlayers = initData.players as Record<string, unknown>[];\n this._controllers = initPlayers\n .filter(p => typeof p.playerIndex === 'number')\n .map((p, index) => mapPlayerDTO(p, index));\n\n this.setupEventHandlers();\n\n // Register all pending user event handlers\n for (const { event, handler } of this._pendingHandlers) {\n this.setupUserEventHandler(event, handler);\n }\n this._pendingHandlers = [];\n\n this._isConnected = true;\n this._isReady = true;\n\n // Flush buffered outbound messages\n for (const buffered of this._outboundBuffer) {\n try {\n switch (buffered.method) {\n case 'send':\n this.send(buffered.args[0] as any, buffered.args[1] as any);\n break;\n }\n } catch (err) {\n this.handleError(err instanceof SmoreSDKError ? err : new SmoreSDKError('UNKNOWN', 'Failed to flush buffered message'));\n }\n }\n this._outboundBuffer = [];\n\n this.logger.lifecycle('Controller ready', {\n roomCode: this._roomCode,\n myIndex: this._myPlayerIndex,\n });\n\n // Auto-signal ready unless explicitly disabled via config\n if (this.config.autoReady !== false) {\n this.logger.lifecycle('Auto-signaling ready (autoReady enabled)');\n this.signalReady();\n }\n\n this._readyResolve();\n }\n\n private handleUpdate(msg: BridgeUpdateMessage): void {\n if (!this._isReady) {\n this.logger.debug('Ignoring _bridge:update before init completes');\n return;\n }\n const updateData = msg.payload;\n this.logger.debug('Received _bridge:update', updateData);\n\n if (updateData.players && Array.isArray(updateData.players)) {\n const players = updateData.players as Record<string, unknown>[];\n const newControllers: ControllerInfo[] = players\n .filter(p => typeof p.playerIndex === 'number')\n .map((p, index) => mapPlayerDTO(p, index));\n\n const oldControllers = this._controllers;\n\n // Detect joins\n for (const nc of newControllers) {\n if (!oldControllers.some(oc => oc.playerIndex === nc.playerIndex)) {\n this._emitLifecycle('$controller-join', nc.playerIndex, nc);\n }\n }\n\n // Detect leaves\n for (const oc of oldControllers) {\n if (!newControllers.some(nc => nc.playerIndex === oc.playerIndex)) {\n this._emitLifecycle('$controller-leave', oc.playerIndex);\n }\n }\n\n // Update connected state for existing players and fire disconnect/reconnect callbacks\n for (const nc of newControllers) {\n const oc = oldControllers.find(c => c.playerIndex === nc.playerIndex);\n if (oc) {\n // Detect disconnect (was connected, now not)\n if (oc.connected && !nc.connected) {\n this.logger.debug('Player disconnected (via update)', { playerIndex: nc.playerIndex });\n this._emitLifecycle('$controller-disconnect', nc.playerIndex);\n }\n // Detect reconnect (was disconnected, now connected)\n if (!oc.connected && nc.connected) {\n this.logger.debug('Player reconnected (via update)', { playerIndex: nc.playerIndex });\n this._emitLifecycle('$controller-reconnect', nc.playerIndex, nc);\n }\n }\n }\n\n this._controllers = newControllers;\n }\n }\n\n private setupEventHandlers(): void {\n if (!this.transport) return;\n\n // System events: player join/leave\n // These smore:* events are forwarded by IframeGameBridge's GAME_FACING_EVENTS allowlist.\n // Each handler updates _controllers to stay consistent and prevent duplicate\n // callbacks if _bridge:update also fires with the same data.\n this.registerHandler(SMORE_EVENTS.PLAYER_JOINED, (raw: unknown) => {\n const data = raw as { player?: Record<string, unknown>; playerIndex?: number };\n const playerInfo = data.player as Record<string, unknown> | undefined;\n const playerIndex = playerInfo?.playerIndex as number | undefined ?? data.playerIndex;\n if (playerIndex !== undefined) {\n if (this._controllers.some(c => c.playerIndex === playerIndex)) return;\n const controllerInfo = playerInfo\n ? mapPlayerDTO(playerInfo, playerIndex)\n : mapPlayerDTO({ playerIndex, connected: true }, playerIndex);\n this._controllers = [...this._controllers, controllerInfo];\n this.logger.debug('Player joined', { playerIndex });\n this._emitLifecycle('$controller-join', playerIndex, controllerInfo);\n }\n });\n\n this.registerHandler(SMORE_EVENTS.PLAYER_LEFT, (raw: unknown) => {\n const data = raw as { player?: { playerIndex?: number }; playerIndex?: number };\n const playerIndex = data.player?.playerIndex ?? data.playerIndex;\n if (playerIndex !== undefined) {\n if (!this._controllers.some(c => c.playerIndex === playerIndex)) return;\n this._controllers = this._controllers.filter(c => c.playerIndex !== playerIndex);\n this.logger.debug('Player left', { playerIndex });\n this._emitLifecycle('$controller-leave', playerIndex);\n }\n });\n\n this.registerHandler(SMORE_EVENTS.PLAYER_DISCONNECTED, (raw: unknown) => {\n const data = raw as { player?: Record<string, unknown>; playerIndex?: number };\n const playerData = data.player;\n const playerIndex = (playerData?.playerIndex as number | undefined) ?? data.playerIndex;\n if (playerIndex !== undefined) {\n // Update connected state in _controllers\n this._controllers = this._controllers.map(c =>\n c.playerIndex === playerIndex ? { ...c, connected: false } : c\n );\n this.logger.debug('Player disconnected', { playerIndex });\n this._emitLifecycle('$controller-disconnect', playerIndex);\n }\n });\n\n this.registerHandler(SMORE_EVENTS.PLAYER_RECONNECTED, (raw: unknown) => {\n const data = raw as { player?: Record<string, unknown>; playerIndex?: number };\n const playerData = data.player;\n const playerIndex = (playerData?.playerIndex as number | undefined) ?? data.playerIndex;\n if (playerIndex !== undefined) {\n // Build ControllerInfo to match Screen SDK behavior\n const controllerInfo = playerData\n ? mapPlayerDTO(playerData, playerIndex)\n : mapPlayerDTO({ playerIndex, connected: true }, playerIndex);\n // Update full ControllerInfo in _controllers (reconnect may carry updated data)\n this._controllers = this._controllers.map(c =>\n c.playerIndex === playerIndex ? controllerInfo : c\n );\n this.logger.debug('Player reconnected', { playerIndex });\n this._emitLifecycle('$controller-reconnect', playerIndex, controllerInfo);\n }\n });\n\n // Character updated: update appearance in _controllers\n // Server emits { player: player.toDTO(), room: room.toDTO() }\n this.registerHandler(SMORE_EVENTS.PLAYER_CHARACTER_UPDATED, (raw: unknown) => {\n const payload = raw as { player?: { playerIndex?: number; character?: Record<string, unknown> | null; name?: string; nickname?: string } };\n const playerData = payload?.player;\n if (playerData && typeof playerData.playerIndex === 'number') {\n const pi = playerData.playerIndex;\n const appearance = (playerData.character ?? null) as ControllerInfo['appearance'];\n this._controllers = this._controllers.map(c =>\n c.playerIndex === pi ? { ...c, appearance } : c\n );\n this.logger.debug('Player character updated', { playerIndex: pi });\n this._emitLifecycle('$character-updated', pi, appearance ?? null);\n }\n });\n\n // Rate limited: route through error handling\n this.registerHandler(SMORE_EVENTS.RATE_LIMITED, (raw: unknown) => {\n const data = raw as { event?: string };\n const eventName = data?.event ?? 'unknown';\n this.handleError(\n new SmoreSDKError('RATE_LIMITED', `Server rate-limited event: ${eventName}`, {\n details: { event: eventName },\n })\n );\n });\n\n // Game over: game has ended\n this.registerHandler(SMORE_EVENTS.GAME_OVER, (raw: unknown) => {\n const data = raw as { results?: GameResults };\n this.logger.lifecycle('Game over', data?.results);\n this._emitLifecycle('$game-over', data?.results);\n });\n\n // All ready: all participants have signaled ready\n this.registerHandler(SMORE_EVENTS.ALL_READY, () => {\n this.logger.lifecycle('All participants ready');\n this._allReadyFired = true;\n this._emitLifecycle('$all-ready');\n });\n\n // Self connection status\n this.registerHandler(SMORE_EVENTS.SELF_DISCONNECTED, () => {\n this._isConnected = false;\n this.logger.lifecycle('Connection lost');\n this._emitLifecycle('$connection-change', false);\n });\n\n this.registerHandler(SMORE_EVENTS.SELF_RECONNECTED, () => {\n this._isConnected = true;\n this.logger.lifecycle('Connection restored');\n this._emitLifecycle('$connection-change', true);\n });\n }\n\n /**\n * Sets up a user event handler for controller events.\n * Used for registering pending handlers after transport becomes available.\n */\n private setupUserEventHandler(event: string, handler: ControllerEventHandler<unknown>): void {\n const transportHandler: TransportEventHandler = (data: unknown) => {\n this.logReceive(event, data);\n try {\n handler(data);\n } catch (err) {\n this.handleError(\n new SmoreSDKError('UNKNOWN', `Error in handler for event \"${event}\"`, {\n cause: err instanceof Error ? err : undefined,\n details: { event },\n })\n );\n }\n };\n\n if (this.transport) {\n this.transport.on(event, transportHandler);\n this.registeredHandlers.push({ event, handler: transportHandler });\n this.handlerToTransport.set(handler as Function, { event, transportHandler });\n }\n\n // Also store in eventListeners for on/off management\n let listeners = this.eventListeners.get(event);\n if (!listeners) {\n listeners = new Set();\n this.eventListeners.set(event, listeners);\n }\n listeners.add(handler);\n }\n\n private registerHandler(event: string, handler: TransportEventHandler): void {\n if (!this.transport) return;\n this.transport.on(event, handler);\n this.registeredHandlers.push({ event, handler });\n }\n\n // ---------------------------------------------------------------------------\n // Lifecycle Listener Helpers\n // ---------------------------------------------------------------------------\n\n private _addLifecycleListener(event: string, listener: Function): () => void {\n let set = this._lifecycleListeners.get(event);\n if (!set) {\n set = new Set();\n this._lifecycleListeners.set(event, set);\n }\n set.add(listener);\n return () => {\n set!.delete(listener);\n if (set!.size === 0) this._lifecycleListeners.delete(event);\n };\n }\n\n private _emitLifecycle(event: string, ...args: unknown[]): void {\n this._lifecycleListeners.get(event)?.forEach(cb => {\n try {\n (cb as Function)(...args);\n } catch (err) {\n this.handleError(\n new SmoreSDKError('UNKNOWN', `Error in lifecycle handler for \"${event}\"`, {\n cause: err instanceof Error ? err : undefined,\n details: { event },\n })\n );\n }\n });\n }\n\n private _hasLifecycleListeners(event: string): boolean {\n const set = this._lifecycleListeners.get(event);\n return set !== undefined && set.size > 0;\n }\n\n // ---------------------------------------------------------------------------\n // Lifecycle Methods\n // ---------------------------------------------------------------------------\n\n onAllReady(callback: () => void): () => void {\n if (this._allReadyFired) {\n callback();\n }\n return this._addLifecycleListener('$all-ready', callback);\n }\n\n onControllerJoin(callback: (playerIndex: PlayerIndex, info: ControllerInfo) => void): () => void {\n return this._addLifecycleListener('$controller-join', callback);\n }\n\n onControllerLeave(callback: (playerIndex: PlayerIndex) => void): () => void {\n return this._addLifecycleListener('$controller-leave', callback);\n }\n\n onControllerDisconnect(callback: (playerIndex: PlayerIndex) => void): () => void {\n return this._addLifecycleListener('$controller-disconnect', callback);\n }\n\n onControllerReconnect(callback: (playerIndex: PlayerIndex, info: ControllerInfo) => void): () => void {\n return this._addLifecycleListener('$controller-reconnect', callback);\n }\n\n onCharacterUpdated(callback: (playerIndex: PlayerIndex, appearance: CharacterAppearance | null) => void): () => void {\n return this._addLifecycleListener('$character-updated', callback);\n }\n\n onError(callback: (error: SmoreError) => void): () => void {\n return this._addLifecycleListener('$error', callback);\n }\n\n onConnectionChange(callback: (connected: boolean) => void): () => void {\n return this._addLifecycleListener('$connection-change', callback);\n }\n\n onGameOver(callback: (results?: GameResults) => void): () => void {\n return this._addLifecycleListener('$game-over', callback);\n }\n\n // ---------------------------------------------------------------------------\n // Communication Methods\n // ---------------------------------------------------------------------------\n\n /**\n * Send an event to the Screen. Controller-to-Controller direct communication\n * is not supported; all messages must go through the Screen.\n *\n * Data is sent to the Screen only (not to other controllers). For Screen->Controller communication,\n * Screen uses broadcast() or sendToController().\n *\n * @note Fire-and-forget sends (no callback) will silently fail if rate-limited.\n * Use the onError callback or smore:rate-limited event to detect rate limiting.\n */\n send<K extends EventNames<TEvents>>(event: K, data: EventData<TEvents, K>): void {\n if (this._isDestroyed) {\n throw new SmoreSDKError('DESTROYED', 'Cannot call send() after destroy()');\n }\n if (!this._isReady || !this.transport) {\n this._outboundBuffer.push({ method: 'send', args: [event, data] });\n this.logger.debug(`Buffered send \"${event}\" (controller not ready yet)`);\n return;\n }\n validateEventName(event);\n validatePayloadSize(data);\n\n if (typeof data !== 'object' || data === null) {\n this.logger.warn(\n 'Event data should be an object. Primitive values will be wrapped as { data: value } by the relay server. ' +\n 'To avoid confusion, wrap explicitly: send(\"event\", { value: 42 }) instead of send(\"event\", 42).'\n );\n }\n\n this.logSend(event, data);\n this.transport!.emit(event, data);\n }\n\n signalReady(): void {\n this.ensureReady('signalReady');\n this.logSend(SMORE_EVENTS.GAME_READY, {});\n this.transport!.emit(SMORE_EVENTS.GAME_READY, {});\n }\n\n // ---------------------------------------------------------------------------\n // Event Subscription\n // ---------------------------------------------------------------------------\n\n /**\n * Register a handler for custom events.\n *\n * Can be called before the Controller is ready. Handlers registered before ready\n * are queued and activated when the transport becomes available.\n *\n * When receiving events from Screen's `broadcast()`:\n * handler receives `(data)` -- no playerIndex included.\n *\n * When receiving events from Screen's `sendToController()`:\n * handler receives `(data)` -- targeted to this specific controller.\n */\n on<K extends EventNames<TEvents>>(\n event: K,\n handler: ControllerEventHandler<EventData<TEvents, K>>,\n ): () => void {\n // Route lifecycle events ($-prefixed)\n if (typeof event === 'string' && (event as string).startsWith('$')) {\n const validEvents = CONTROLLER_LIFECYCLE_EVENTS;\n if (!validEvents.has(event as string)) {\n throw new SmoreSDKError('INVALID_EVENT', `Unknown lifecycle event: \"${event}\". Valid lifecycle events: ${Array.from(validEvents).join(', ')}`);\n }\n // Special handling for $all-ready: fire immediately if already happened\n if (event === '$all-ready' && this._allReadyFired) {\n (handler as unknown as () => void)();\n }\n return this._addLifecycleListener(event as string, handler as Function);\n }\n\n validateEventName(event);\n\n // Add to local listeners map\n let listeners = this.eventListeners.get(event);\n if (!listeners) {\n listeners = new Set();\n this.eventListeners.set(event, listeners);\n }\n listeners.add(handler as ControllerEventHandler<unknown>);\n\n if (this.transport) {\n // Register with transport immediately\n const transportHandler: TransportEventHandler = (data: unknown) => {\n this.logReceive(event, data);\n try {\n (handler as ControllerEventHandler<unknown>)(data);\n } catch (err) {\n this.handleError(\n new SmoreSDKError('UNKNOWN', `Error in handler for event \"${event}\"`, {\n cause: err instanceof Error ? err : undefined,\n details: { event },\n })\n );\n }\n };\n\n this.transport.on(event, transportHandler);\n this.registeredHandlers.push({ event, handler: transportHandler });\n this.handlerToTransport.set(handler as Function, { event, transportHandler });\n } else {\n // Store for later registration when transport becomes available\n this._pendingHandlers.push({ event: event as string, handler: handler as ControllerEventHandler<unknown> });\n }\n\n // Return unsubscribe function\n return () => {\n listeners?.delete(handler as ControllerEventHandler<unknown>);\n if (listeners?.size === 0) {\n this.eventListeners.delete(event);\n }\n\n // Remove from pending if not yet registered\n this._pendingHandlers = this._pendingHandlers.filter(\n p => !(p.event === event && p.handler === handler)\n );\n\n // Remove from transport if registered\n const entry = this.handlerToTransport.get(handler as Function);\n if (entry) {\n this.transport?.off(event, entry.transportHandler);\n this.registeredHandlers = this.registeredHandlers.filter(\n (h) => h.handler !== entry.transportHandler,\n );\n this.handlerToTransport.delete(handler as Function);\n }\n };\n }\n\n /**\n * Add a one-time listener that auto-removes after first call.\n *\n * @note The handler is internally wrapped, so it cannot be removed via\n * `off(event, originalHandler)`. Use the returned unsubscribe function instead.\n */\n once<K extends EventNames<TEvents>>(\n event: K,\n handler: ControllerEventHandler<EventData<TEvents, K>>,\n ): () => void {\n if (typeof event === 'string' && (event as string).startsWith('$')) {\n const validEvents = CONTROLLER_LIFECYCLE_EVENTS;\n if (!validEvents.has(event as string)) {\n throw new SmoreSDKError('INVALID_EVENT', `Unknown lifecycle event: \"${event}\"`);\n }\n if (event === '$all-ready' && this._allReadyFired) {\n (handler as unknown as () => void)();\n return () => {};\n }\n const wrapper = (...args: unknown[]) => {\n unsub();\n (handler as Function)(...args);\n };\n const unsub = this._addLifecycleListener(event as string, wrapper);\n return unsub;\n }\n\n const unsubscribe = this.on(event, ((data: EventData<TEvents, K>) => {\n unsubscribe();\n handler(data);\n }) as ControllerEventHandler<EventData<TEvents, K>>);\n return unsubscribe;\n }\n\n off<K extends EventNames<TEvents>>(\n event: K,\n handler?: ControllerEventHandler<EventData<TEvents, K>>,\n ): void {\n if (typeof event === 'string' && (event as string).startsWith('$')) {\n if (!handler) {\n this._lifecycleListeners.delete(event as string);\n } else {\n this._lifecycleListeners.get(event as string)?.delete(handler as Function);\n }\n return;\n }\n\n if (!handler) {\n // Remove all handlers for this event\n this.eventListeners.delete(event);\n this.transport?.off(event);\n this.registeredHandlers = this.registeredHandlers.filter((h) => h.event !== event);\n for (const [key, val] of this.handlerToTransport) {\n if (val.event === event) this.handlerToTransport.delete(key);\n }\n // Remove from pending\n this._pendingHandlers = this._pendingHandlers.filter(p => p.event !== event);\n } else {\n // Remove specific handler\n const listeners = this.eventListeners.get(event);\n listeners?.delete(handler as ControllerEventHandler<unknown>);\n if (listeners?.size === 0) {\n this.eventListeners.delete(event);\n }\n // Remove specific transport handler via handlerToTransport map\n const entry = this.handlerToTransport.get(handler as Function);\n if (entry) {\n this.transport?.off(event, entry.transportHandler);\n this.registeredHandlers = this.registeredHandlers.filter(\n (h) => h.handler !== entry.transportHandler,\n );\n this.handlerToTransport.delete(handler as Function);\n }\n // Remove from pending\n this._pendingHandlers = this._pendingHandlers.filter(\n p => !(p.event === event && p.handler === handler)\n );\n }\n }\n\n removeAllListeners(event?: string): void {\n if (event) {\n // Remove all handlers for specific event\n this.eventListeners.delete(event);\n this.transport?.off(event);\n this.registeredHandlers = this.registeredHandlers.filter(h => h.event !== event);\n for (const [key, val] of this.handlerToTransport) {\n if (val.event === event) this.handlerToTransport.delete(key);\n }\n this._pendingHandlers = this._pendingHandlers.filter(p => p.event !== event);\n } else {\n // Remove all user event handlers\n for (const evt of [...this.eventListeners.keys()]) {\n this.removeAllListeners(evt);\n }\n }\n }\n\n // ---------------------------------------------------------------------------\n // Cleanup\n // ---------------------------------------------------------------------------\n\n destroy(): void {\n if (this._isDestroyed) return;\n\n this.logger.lifecycle('Destroying controller');\n this._isDestroyed = true;\n this._isReady = false;\n this.cleanup();\n }\n\n private cleanup(): void {\n // Clear init timeout if still pending\n if (this._initTimeoutId) {\n clearTimeout(this._initTimeoutId);\n this._initTimeoutId = null;\n }\n\n this._isReady = false;\n\n // Remove all registered handlers\n for (const { event, handler } of this.registeredHandlers) {\n this.transport?.off(event, handler);\n }\n this.registeredHandlers = [];\n\n // Clear event listeners\n this.eventListeners.clear();\n this.handlerToTransport.clear();\n this._pendingHandlers = [];\n\n // Clear lifecycle callbacks\n this._lifecycleListeners.clear();\n this._isConnected = false;\n this._outboundBuffer = [];\n\n // Destroy transport\n if (this.transport) {\n this.transport.destroy();\n this.transport = null;\n }\n\n // Remove message listener\n if (this.boundMessageHandler) {\n window.removeEventListener('message', this.boundMessageHandler);\n this.boundMessageHandler = null;\n }\n }\n\n // ---------------------------------------------------------------------------\n // Private Helpers\n // ---------------------------------------------------------------------------\n\n private ensureReady(method: string): void {\n if (this._isDestroyed) {\n throw new SmoreSDKError(\n 'DESTROYED',\n `Cannot call ${method}() after destroy()`,\n { details: { method } },\n );\n }\n if (!this._isReady || !this.transport) {\n throw new SmoreSDKError(\n 'NOT_READY',\n `Cannot call ${method}() before controller is ready. ` +\n `Use await controller.ready.`,\n { details: { method, isReady: this._isReady } },\n );\n }\n }\n\n private handleError(error: SmoreSDKError): void {\n // Always log at warn level so errors are never completely silent\n this.logger.warn(`Error in handler: ${error.message}`);\n const smoreError = error.toSmoreError();\n if (this._hasLifecycleListeners('$error')) {\n this._emitLifecycle('$error', smoreError);\n } else {\n this.logger.error(error.message, error.details);\n }\n }\n\n private logSend(event: string, data?: unknown): void {\n this.logger.send(event, data);\n }\n\n private logReceive(event: string, data?: unknown): void {\n this.logger.receive(event, data);\n }\n}\n\n// =============================================================================\n// FACTORY FUNCTION\n// =============================================================================\n\n/**\n * Create a Controller instance for the player/phone side of your game.\n *\n * Returns a Controller instance synchronously. The controller begins listening\n * for the bridge init message immediately. Register event handlers and\n * lifecycle callbacks on the instance, then await `.ready` if needed.\n *\n * @template TEvents - Event map type for type-safe events\n * @param config - Controller configuration (debug, parentOrigin, timeout)\n * @returns Controller instance\n *\n * @example\n * ```ts\n * const controller = createController<MyEvents>({ debug: true });\n *\n * controller.on('phase-update', (data) => setPhase(data.phase));\n * controller.onAllReady(() => console.log('Ready!'));\n *\n * await controller.ready;\n * controller.send('tap', { x: 100, y: 200 });\n * ```\n */\nexport function createController<TEvents extends EventMap = EventMap>(\n config?: ControllerConfig,\n): Controller<TEvents> {\n return new ControllerImpl<TEvents>(config ?? {});\n}\n","/**\n * @smoregg/sdk - World-Class Party Game SDK\n *\n * Type definitions for building multiplayer party games with type-safe events,\n * factory pattern initialization, and comprehensive error handling.\n *\n * @packageDocumentation\n */\n\n// =============================================================================\n// CORE PRIMITIVES\n// =============================================================================\n\n/**\n * Unique identifier for a player (0-indexed integer).\n * Used consistently across all SDK methods.\n */\nexport type PlayerIndex = number;\n\n/**\n * Room code for joining a game session (e.g., \"ABCD\").\n */\nexport type RoomCode = string;\n\n// =============================================================================\n// EVENT SYSTEM - TYPE-SAFE EVENTS\n// =============================================================================\n\n/**\n * Base event map type. Extend this to define your game's events.\n *\n * **Important:** Event data values must be plain objects, not primitives.\n * Primitive values (string, number, boolean) will be automatically wrapped\n * as `{ data: <value> }` by the relay server, which breaks type safety.\n *\n * **Payload Size Limit:** Maximum payload size per event is 64KB. This limit\n * is enforced by the server's genericRelay handler. Payloads exceeding this\n * limit will be silently dropped by the server without error notification.\n *\n * **Reserved Fields:** The field names `playerIndex` and `targetPlayerIndex` are reserved\n * by the SDK for internal routing. Using these as custom data field names will cause\n * a compile-time error. The SDK automatically extracts `playerIndex` to identify the sender\n * and uses `targetPlayerIndex` for targeted message delivery.\n *\n * **Type Safety Note:** Without providing an explicit generic type parameter,\n * `createScreen()` and `createController()` default to the empty `EventMap`,\n * which means `send()`, `broadcast()`, and `on()` accept any string as an event\n * name and `unknown` as data -- effectively losing compile-time type checking.\n * Always define and pass your game's event map for full type safety.\n *\n * @example Defining events for type safety\n * ```ts\n * interface MyGameEvents {\n * // Screen receives from Controller\n * 'tap': { x: number; y: number };\n * 'answer': { choice: number };\n *\n * // Controller receives from Screen\n * 'phase-update': { phase: 'lobby' | 'playing' | 'results' };\n * 'your-turn': { timeLimit: number };\n * }\n *\n * // With explicit generic -- full type safety\n * const screen = createScreen<MyGameEvents>({ debug: true });\n * screen.on('tap', (playerIndex, data) => { ... });\n * await screen.ready;\n *\n * // Without generic -- no type safety (not recommended)\n * const screen = createScreen();\n * ```\n *\n * @example Event naming conventions\n * ```ts\n * // Define your game's event map for type safety:\n * type MyEvents = {\n * 'player-move': { x: number; y: number };\n * 'game-action': { action: string; value: number };\n * };\n * // Event names: use kebab-case, no colons (:), no 'smore:' prefix\n * ```\n */\nexport interface EventMap {\n [key: string]: Record<string, unknown> & { playerIndex?: never; targetPlayerIndex?: never };\n}\n\n/**\n * Extract event names from an event map.\n */\nexport type EventNames<TEvents extends EventMap> = keyof TEvents & string;\n\n/**\n * Extract event data type for a specific event.\n */\nexport type EventData<\n TEvents extends EventMap,\n TEvent extends EventNames<TEvents>,\n> = TEvents[TEvent];\n\n// =============================================================================\n// CONTROLLER INFO - PLAYER INFORMATION\n// =============================================================================\n\n/**\n * Character appearance data for player avatars.\n *\n * This type matches the server's CharacterDTO structure to ensure\n * type consistency across the platform.\n *\n * @property id - Unique character identifier\n * @property seed - Random seed for generating the character\n * @property style - Character style preset identifier\n * @property options - Additional character customization options\n */\nexport interface CharacterAppearance {\n /** Unique character identifier */\n id: string;\n /** Random seed for generating the character */\n seed: string;\n /** Character style preset identifier */\n style: string;\n /** Additional character customization options */\n options: Record<string, unknown>;\n}\n\n/**\n * Information about a connected controller (player).\n * Used by Screen to identify and manage players.\n */\nexport interface ControllerInfo {\n /** Player's unique index (0, 1, 2, ...) */\n readonly playerIndex: PlayerIndex;\n /**\n * Player's chosen display name.\n *\n * Maps to `PlayerDTO.name` on the server side. The SDK exposes it as\n * \"nickname\" for semantic clarity in game code.\n * The mapping (`name` -> `nickname`) is handled automatically during\n * player data deserialization in the transport layer.\n *\n * @see PlayerDTO.name (server) -- same value, different field name\n */\n readonly nickname: string;\n /** Whether the player is currently connected */\n readonly connected: boolean;\n /**\n * Optional character appearance data.\n *\n * Note: The server sends this as \"character\" in PlayerDTO.\n * The SDK maps it to \"appearance\" for semantic clarity.\n * The server may send `null` when no character is set.\n */\n readonly appearance?: CharacterAppearance | null;\n}\n\n// =============================================================================\n// TRANSPORT\n// =============================================================================\n\n/**\n * Transport interface for custom communication implementations.\n * Implement this to use a custom transport instead of the default PostMessageTransport.\n */\nexport interface Transport {\n emit(event: string, ...args: unknown[]): void;\n on(event: string, handler: (...args: unknown[]) => void): void;\n off(event: string, handler?: (...args: unknown[]) => void): void;\n destroy(): void;\n}\n\n// =============================================================================\n// ERROR HANDLING\n// =============================================================================\n\n/**\n * Error codes for SDK errors.\n */\nexport type SmoreErrorCode =\n | 'TIMEOUT' // Connection or operation timeout\n | 'NOT_READY' // Operation called before ready\n | 'DESTROYED' // Operation called after destroy\n | 'INVALID_EVENT' // Invalid event name\n | 'INVALID_PLAYER' // Invalid player index\n | 'CONNECTION_LOST' // Lost connection to server\n | 'INIT_FAILED' // Failed to initialize\n | 'RATE_LIMITED' // Server rate-limited an event\n | 'PAYLOAD_TOO_LARGE' // Payload exceeds 64KB limit\n | 'UNKNOWN'; // Unknown error\n\n/**\n * Structured error type for SDK errors.\n */\nexport interface SmoreError {\n /** Error code for programmatic handling */\n code: SmoreErrorCode;\n /** Human-readable error message */\n message: string;\n /** Original error if available */\n cause?: Error;\n /** Additional context */\n details?: Record<string, unknown>;\n}\n\n// =============================================================================\n// GAME RESULTS\n// =============================================================================\n\n/**\n * Game results structure for gameOver().\n * Flexible to accommodate different game types.\n */\nexport interface GameResults {\n /** Player scores indexed by player index */\n scores?: Record<PlayerIndex, number>;\n /** Winner's player index (or -1 for no winner/tie) */\n winner?: PlayerIndex;\n /** Ranked player indices from first to last */\n rankings?: PlayerIndex[];\n /** Additional custom game-specific data */\n custom?: Record<string, unknown>;\n}\n\n// =============================================================================\n// LIFECYCLE EVENTS — UNIFIED EVENT SYSTEM\n// =============================================================================\n\n/**\n * Lifecycle event names for subscribing via `on()`.\n *\n * These `$`-prefixed event names allow lifecycle events to be registered\n * through the same `on()` method used for game events. The `$` prefix is\n * reserved by the SDK and cannot be used for user-defined events.\n *\n * @example\n * ```ts\n * // These are equivalent:\n * screen.onControllerJoin((pi, info) => { ... });\n * screen.on(LifecycleEvent.CONTROLLER_JOIN, (pi, info) => { ... });\n * ```\n */\nexport const LifecycleEvent = {\n ALL_READY: '$all-ready',\n CONTROLLER_JOIN: '$controller-join',\n CONTROLLER_LEAVE: '$controller-leave',\n CONTROLLER_DISCONNECT: '$controller-disconnect',\n CONTROLLER_RECONNECT: '$controller-reconnect',\n CHARACTER_UPDATED: '$character-updated',\n ERROR: '$error',\n GAME_OVER: '$game-over',\n CONNECTION_CHANGE: '$connection-change',\n} as const;\n\n/** Union of all lifecycle event name strings. */\nexport type LifecycleEventName = typeof LifecycleEvent[keyof typeof LifecycleEvent];\n\n/**\n * Handler signatures for Screen lifecycle events.\n * Used by `on()` overloads to provide type-safe lifecycle event subscription.\n */\nexport interface ScreenLifecycleHandlers {\n '$all-ready': () => void;\n '$controller-join': (playerIndex: PlayerIndex, info: ControllerInfo) => void;\n '$controller-leave': (playerIndex: PlayerIndex) => void;\n '$controller-disconnect': (playerIndex: PlayerIndex) => void;\n '$controller-reconnect': (playerIndex: PlayerIndex, info: ControllerInfo) => void;\n '$character-updated': (playerIndex: PlayerIndex, appearance: CharacterAppearance | null) => void;\n '$error': (error: SmoreError) => void;\n '$connection-change': (connected: boolean) => void;\n}\n\n/** Screen lifecycle event name union. */\nexport type ScreenLifecycleEvent = keyof ScreenLifecycleHandlers;\n\n/**\n * Handler signatures for Controller lifecycle events.\n * Extends Screen lifecycle events with Controller-specific events.\n */\nexport interface ControllerLifecycleHandlers extends ScreenLifecycleHandlers {\n '$game-over': (results?: GameResults) => void;\n}\n\n/** Controller lifecycle event name union. */\nexport type ControllerLifecycleEvent = keyof ControllerLifecycleHandlers;\n\n// =============================================================================\n// SCREEN TYPES - HOST/TV SIDE\n// =============================================================================\n\n/**\n * Handler for events received from controllers.\n * Receives the player index and event data.\n */\nexport type ScreenEventHandler<TData = unknown> = (\n playerIndex: PlayerIndex,\n data: TData,\n) => void;\n\n/**\n * Configuration options for creating a Screen instance.\n *\n * In the event emitter pattern, only static options are passed via config.\n * All lifecycle callbacks and event listeners are registered via methods\n * on the returned Screen instance.\n *\n * @template TEvents - Event map type for type-safe events\n *\n * @example\n * ```ts\n * const screen = createScreen<MyEvents>({ debug: true });\n *\n * screen.on('tap', (playerIndex, data) => handleTap(playerIndex, data));\n * screen.onAllReady(() => startCountdown());\n * screen.onControllerJoin((playerIndex, info) => console.log('Joined:', playerIndex));\n *\n * await screen.ready;\n * ```\n */\nexport interface ScreenConfig {\n // === Debug Options ===\n\n /**\n * Enable debug mode for verbose logging.\n * @default false\n */\n debug?: boolean | DebugOptions;\n\n // === Advanced Options ===\n\n /**\n * Parent window origin for postMessage validation (iframe games).\n * Use '*' to accept messages from any origin (not recommended for production).\n * @default '*'\n */\n parentOrigin?: string;\n\n /**\n * Connection timeout in milliseconds.\n * @default 10000\n */\n timeout?: number;\n\n /**\n * Automatically signal ready after initialization.\n * When true (default), the SDK calls signalReady() automatically after init completes.\n * Set to false if your game needs to load resources before signaling ready.\n * @default true\n */\n autoReady?: boolean;\n\n /**\n * Custom transport implementation.\n * If provided, uses this instead of the default PostMessageTransport.\n * The bridge handshake (_bridge:init) still occurs via postMessage.\n */\n transport?: Transport;\n\n}\n\n/**\n * Screen instance - the main interface for the host/TV side of your game.\n *\n * Uses an event emitter pattern: lifecycle callbacks and event listeners\n * are registered via methods on the instance, not via config.\n *\n * @template TEvents - Event map type for type-safe events\n *\n * @example\n * ```ts\n * const screen = createScreen<MyEvents>({ debug: true });\n *\n * screen.on('tap', (playerIndex, data) => handleTap(playerIndex, data));\n * screen.onAllReady(() => startGame());\n * screen.onControllerJoin((playerIndex, info) => addPlayer(playerIndex, info));\n *\n * await screen.ready;\n * screen.broadcast('phase-update', { phase: 'playing' });\n * screen.gameOver({ scores: { 0: 100, 1: 75 } });\n * ```\n */\nexport interface Screen<TEvents extends EventMap = EventMap> {\n // === Properties (readonly) ===\n\n /**\n * All connected controllers. Returns a new shallow copy on every access.\n *\n * **Performance note:** Each access creates a new array via spread.\n * Avoid calling this in tight loops; cache the result in a local variable\n * if you need to access it repeatedly within the same frame/tick.\n */\n readonly controllers: readonly ControllerInfo[];\n\n /** The room code for this game session. */\n readonly roomCode: RoomCode;\n\n /** Whether the screen is initialized and ready. */\n readonly isReady: boolean;\n\n /** Whether the screen has been destroyed. */\n readonly isDestroyed: boolean;\n\n /** Whether the connection to the server is active. */\n readonly isConnected: boolean;\n\n /** Protocol version negotiated with the parent frame. */\n readonly protocolVersion: number;\n\n /**\n * A Promise that resolves when the screen is initialized and ready.\n * Use this to await readiness after creating a screen synchronously.\n *\n * @example\n * ```ts\n * const screen = createScreen<MyEvents>();\n * screen.on('tap', handler);\n * await screen.ready;\n * screen.broadcast('start', {});\n * ```\n */\n readonly ready: Promise<void>;\n\n // === Lifecycle Methods ===\n\n /**\n * Register a callback for when all participants are ready (all-ready event).\n * If the all-ready event has already fired when called, the callback fires immediately.\n *\n * @param callback - Called when all participants signal ready\n * @returns Unsubscribe function to remove the callback\n */\n onAllReady(callback: () => void): () => void;\n\n /**\n * Register a callback for when a controller (player) joins the room.\n *\n * @param callback - Called with player index and controller info\n * @returns Unsubscribe function to remove the callback\n */\n onControllerJoin(callback: (playerIndex: PlayerIndex, info: ControllerInfo) => void): () => void;\n\n /**\n * Register a callback for when a controller (player) leaves the room.\n *\n * @param callback - Called with the leaving player's index\n * @returns Unsubscribe function to remove the callback\n */\n onControllerLeave(callback: (playerIndex: PlayerIndex) => void): () => void;\n\n /**\n * Register a callback for when a controller temporarily disconnects.\n *\n * @param callback - Called with the disconnected player's index\n * @returns Unsubscribe function to remove the callback\n */\n onControllerDisconnect(callback: (playerIndex: PlayerIndex) => void): () => void;\n\n /**\n * Register a callback for when a controller reconnects after a disconnect.\n *\n * @param callback - Called with player index and updated controller info\n * @returns Unsubscribe function to remove the callback\n */\n onControllerReconnect(callback: (playerIndex: PlayerIndex, info: ControllerInfo) => void): () => void;\n\n /**\n * Register a callback for when a player's character appearance is updated.\n *\n * @param callback - Called with player index and new appearance (or null if reset)\n * @returns Unsubscribe function to remove the callback\n */\n onCharacterUpdated(callback: (playerIndex: PlayerIndex, appearance: CharacterAppearance | null) => void): () => void;\n\n /**\n * Register a callback for when an error occurs.\n * If no error callback is registered, errors are logged to console in debug mode.\n *\n * @param callback - Called with the error object\n * @returns Unsubscribe function to remove the callback\n */\n onError(callback: (error: SmoreError) => void): () => void;\n\n /**\n * Register a callback for when the connection status changes.\n * Called when the connection to the server is lost or restored.\n *\n * @param callback - Called with true (connected) or false (disconnected)\n * @returns Unsubscribe function to remove the callback\n */\n onConnectionChange(callback: (connected: boolean) => void): () => void;\n\n // === Communication Methods ===\n\n /**\n * Broadcast an event to all connected controllers.\n *\n * @param event - Event name (must match TEvents keys)\n * @param data - Event data (type-safe based on event name)\n * @note Data should be an object. Primitive values will be wrapped as `{ data: value }` by the relay server.\n * @note Maximum payload size is 64KB. Payloads exceeding this limit will be silently dropped by the server.\n *\n * @example\n * ```ts\n * screen.broadcast('phase-update', { phase: 'playing' });\n * ```\n */\n broadcast<K extends EventNames<TEvents>>(\n event: K,\n data: EventData<TEvents, K>,\n ): void;\n\n /**\n * Send an event to a specific controller.\n *\n * Screen -> Controller direction only. For Controller -> Screen, see `send()`.\n *\n * @param playerIndex - Target controller's player index\n * @param event - Event name (must match TEvents keys)\n * @param data - Event data (type-safe based on event name)\n * @note Data should be an object. Primitive values will be wrapped as `{ data: value }` by the relay server.\n * @note Maximum payload size is 64KB. Payloads exceeding this limit will be silently dropped by the server.\n *\n * @example\n * ```ts\n * screen.sendToController(0, 'your-turn', { timeLimit: 30 });\n * ```\n */\n sendToController<K extends EventNames<TEvents>>(\n playerIndex: PlayerIndex,\n event: K,\n data: EventData<TEvents, K>,\n ): void;\n\n // === Game Lifecycle ===\n\n /**\n * Signal that the game is over and send results.\n * This will broadcast a game-over event to all controllers.\n *\n * @param results - Game results (scores, rankings, etc.)\n *\n * @example\n * ```ts\n * screen.gameOver({\n * scores: { 0: 100, 1: 75, 2: 50 },\n * winner: 0,\n * rankings: [0, 1, 2],\n * });\n * ```\n */\n gameOver(results?: GameResults): void;\n\n /**\n * Signal that this screen has finished loading resources and is ready to start.\n *\n * Call this after all game resources (Phaser assets, images, sounds, etc.) are loaded.\n * The server will wait until all participants (screen + all connected controllers)\n * have signaled ready, then broadcast an all-ready event to everyone.\n *\n * @example\n * ```ts\n * // After Phaser scene loads all assets:\n * screen.signalReady();\n * ```\n */\n signalReady(): void;\n\n // === Event Subscription ===\n\n /**\n * Subscribe to a lifecycle event or a user-defined game event.\n *\n * Lifecycle events use `$`-prefixed names. Use `LifecycleEvent` constants\n * for type-safe subscription:\n * ```ts\n * screen.on(LifecycleEvent.CONTROLLER_JOIN, (pi, info) => { ... });\n * screen.on('tap', (pi, data) => { ... }); // user event\n * ```\n */\n on<K extends ScreenLifecycleEvent>(event: K, handler: ScreenLifecycleHandlers[K]): () => void;\n /**\n * Add a listener for a specific event after construction.\n * Can be called before the screen is ready -- handlers are queued\n * and activated when the transport becomes available.\n *\n * @param event - Event name\n * @param handler - Handler function (playerIndex, data) => void\n * @returns Cleanup function to remove the listener\n *\n * @example\n * ```ts\n * const unsubscribe = screen.on('tap', (playerIndex, data) => {\n * console.log(`Player ${playerIndex} tapped at`, data.x, data.y);\n * });\n *\n * // Later: remove listener\n * unsubscribe();\n * ```\n */\n on<K extends EventNames<TEvents>>(\n event: K,\n handler: ScreenEventHandler<EventData<TEvents, K>>,\n ): () => void;\n\n once<K extends ScreenLifecycleEvent>(event: K, handler: ScreenLifecycleHandlers[K]): () => void;\n /**\n * Add a one-time listener that auto-removes after first call.\n *\n * @note The handler is internally wrapped, so it cannot be removed via\n * `off(event, originalHandler)`. Use the returned unsubscribe function instead.\n */\n once<K extends EventNames<TEvents>>(\n event: K,\n handler: ScreenEventHandler<EventData<TEvents, K>>,\n ): () => void;\n\n off<K extends ScreenLifecycleEvent>(event: K, handler?: ScreenLifecycleHandlers[K]): void;\n /**\n * Remove a specific listener or all listeners for an event.\n */\n off<K extends EventNames<TEvents>>(\n event: K,\n handler?: ScreenEventHandler<EventData<TEvents, K>>,\n ): void;\n\n /**\n * Remove all event listeners, or all listeners for a specific event.\n * Only removes user event listeners registered via on()/once().\n * Lifecycle callbacks (onControllerJoin, onAllReady, etc.) are not affected.\n *\n * @param event - Optional event name. If omitted, removes ALL user event listeners.\n */\n removeAllListeners(event?: string): void;\n\n // === Utilities ===\n\n /**\n * Get a specific controller by player index.\n * Returns undefined if not found.\n */\n getController(playerIndex: PlayerIndex): ControllerInfo | undefined;\n\n /**\n * Get the number of connected controllers.\n */\n getControllerCount(): number;\n\n // === Cleanup ===\n\n /**\n * Clean up all resources and disconnect.\n * Call this when unmounting/destroying your game.\n */\n destroy(): void;\n}\n\n// =============================================================================\n// CONTROLLER TYPES - PLAYER/PHONE SIDE\n// =============================================================================\n\n/**\n * Handler for events received from the screen.\n * Receives only the event data (no player index needed).\n */\nexport type ControllerEventHandler<TData = unknown> = (data: TData) => void;\n\n/**\n * Configuration options for creating a Controller instance.\n *\n * In the event emitter pattern, only static options are passed via config.\n * All lifecycle callbacks and event listeners are registered via methods\n * on the returned Controller instance.\n *\n * @template TEvents - Event map type for type-safe events\n *\n * @example\n * ```ts\n * const controller = createController<MyEvents>({ debug: true });\n *\n * controller.on('phase-update', (data) => handlePhase(data.phase));\n * controller.onAllReady(() => console.log('Ready!'));\n *\n * await controller.ready;\n * controller.send('tap', { x: 100, y: 200 });\n * ```\n */\nexport interface ControllerConfig {\n // === Debug Options ===\n\n /**\n * Enable debug mode for verbose logging.\n * @default false\n */\n debug?: boolean | DebugOptions;\n\n // === Advanced Options ===\n\n /**\n * Parent window origin for postMessage validation (iframe games).\n * @default '*'\n */\n parentOrigin?: string;\n\n /**\n * Connection timeout in milliseconds.\n * @default 10000\n */\n timeout?: number;\n\n /**\n * Automatically signal ready after initialization.\n * When true (default), the SDK calls signalReady() automatically after init completes.\n * Set to false if your game needs to load resources before signaling ready.\n * @default true\n */\n autoReady?: boolean;\n\n /**\n * Custom transport implementation.\n * If provided, uses this instead of the default PostMessageTransport.\n * The bridge handshake (_bridge:init) still occurs via postMessage.\n */\n transport?: Transport;\n\n}\n\n/**\n * Controller instance - the main interface for the player/phone side.\n *\n * Uses an event emitter pattern: lifecycle callbacks and event listeners\n * are registered via methods on the instance, not via config.\n *\n * @template TEvents - Event map type for type-safe events\n *\n * @example\n * ```ts\n * const controller = createController<MyEvents>({ debug: true });\n *\n * controller.on('phase-update', (data) => setPhase(data.phase));\n * controller.onAllReady(() => console.log('Game starting!'));\n *\n * await controller.ready;\n * controller.send('tap', { x: 100, y: 200 });\n * ```\n *\n * ## Controller API Design Note:\n *\n * Controller only has `send()` (no `broadcast()` or `gameOver()`).\n * This is intentional: Controller-to-Controller (C2C) communication is not supported.\n * All coordination between controllers must go through the Screen.\n *\n * Flow: Controller.send() -> Screen receives -> Screen.broadcast() or Screen.sendToController()\n */\nexport interface Controller<TEvents extends EventMap = EventMap> {\n // === Properties (readonly) ===\n\n /** My player index (0, 1, 2, ...). */\n readonly myPlayerIndex: PlayerIndex;\n\n /** The room code for this game session. */\n readonly roomCode: RoomCode;\n\n /** Whether the controller is initialized and ready. */\n readonly isReady: boolean;\n\n /** Whether the controller has been destroyed. */\n readonly isDestroyed: boolean;\n\n /** Whether the connection to the server is active. */\n readonly isConnected: boolean;\n\n /** Protocol version negotiated with the parent frame. */\n readonly protocolVersion: number;\n\n /**\n * Read-only list of all known controllers (players) in the room.\n * Returns full ControllerInfo including playerIndex, nickname, connected status, and appearance.\n * Consistent with Screen's `controllers` property.\n *\n * **Performance note:** Each access creates a new shallow copy array.\n * Cache the result in a local variable if you need to access it repeatedly.\n */\n readonly controllers: readonly ControllerInfo[];\n\n /**\n * A Promise that resolves when the controller is initialized and ready.\n * Use this to await readiness after creating a controller synchronously.\n *\n * @example\n * ```ts\n * const controller = createController<MyEvents>();\n * controller.on('phase-update', handler);\n * await controller.ready;\n * controller.send('tap', { x: 0, y: 0 });\n * ```\n */\n readonly ready: Promise<void>;\n\n // === Lifecycle Methods ===\n\n /**\n * Register a callback for when all participants are ready (all-ready event).\n * If the all-ready event has already fired when called, the callback fires immediately.\n *\n * @param callback - Called when all participants signal ready\n * @returns Unsubscribe function to remove the callback\n */\n onAllReady(callback: () => void): () => void;\n\n /**\n * Register a callback for when another player joins the room.\n *\n * @param callback - Called with player index and controller info\n * @returns Unsubscribe function to remove the callback\n */\n onControllerJoin(callback: (playerIndex: PlayerIndex, info: ControllerInfo) => void): () => void;\n\n /**\n * Register a callback for when another player leaves the room.\n *\n * @param callback - Called with the leaving player's index\n * @returns Unsubscribe function to remove the callback\n */\n onControllerLeave(callback: (playerIndex: PlayerIndex) => void): () => void;\n\n /**\n * Register a callback for when another player temporarily disconnects.\n *\n * @param callback - Called with the disconnected player's index\n * @returns Unsubscribe function to remove the callback\n */\n onControllerDisconnect(callback: (playerIndex: PlayerIndex) => void): () => void;\n\n /**\n * Register a callback for when another player reconnects after a disconnect.\n *\n * @param callback - Called with player index and updated controller info\n * @returns Unsubscribe function to remove the callback\n */\n onControllerReconnect(callback: (playerIndex: PlayerIndex, info: ControllerInfo) => void): () => void;\n\n /**\n * Register a callback for when a player's character appearance is updated.\n *\n * @param callback - Called with player index and new appearance (or null if reset)\n * @returns Unsubscribe function to remove the callback\n */\n onCharacterUpdated(callback: (playerIndex: PlayerIndex, appearance: CharacterAppearance | null) => void): () => void;\n\n /**\n * Register a callback for when an error occurs.\n * If no error callback is registered, errors are logged to console in debug mode.\n *\n * @param callback - Called with the error object\n * @returns Unsubscribe function to remove the callback\n */\n onError(callback: (error: SmoreError) => void): () => void;\n\n /**\n * Register a callback for when the game ends.\n * Called when the Screen calls gameOver().\n *\n * @param callback - Called with optional game results\n * @returns Unsubscribe function to remove the callback\n */\n onGameOver(callback: (results?: GameResults) => void): () => void;\n\n /**\n * Register a callback for when the connection status changes.\n * Called when the connection to the server is lost or restored.\n *\n * @param callback - Called with true (connected) or false (disconnected)\n * @returns Unsubscribe function to remove the callback\n */\n onConnectionChange(callback: (connected: boolean) => void): () => void;\n\n /**\n * Returns the number of currently connected players.\n */\n getControllerCount(): number;\n\n /**\n * Get a specific controller by player index.\n * Returns undefined if not found.\n */\n getController(playerIndex: PlayerIndex): ControllerInfo | undefined;\n\n // === Communication Methods ===\n\n /**\n * Send an event to the screen.\n *\n * Controller -> Screen direction only. For Screen -> Controller, see `sendToController()`.\n *\n * @param event - Event name (must match TEvents keys)\n * @param data - Event data (type-safe based on event name)\n * @note Maximum payload size is 64KB. Payloads exceeding this limit will be silently dropped by the server.\n *\n * @example\n * ```ts\n * controller.send('tap', { x: 100, y: 200 });\n * controller.send('answer', { choice: 2 });\n * ```\n */\n send<K extends EventNames<TEvents>>(\n event: K,\n data: EventData<TEvents, K>,\n ): void;\n\n /**\n * Signal that this controller has finished loading resources and is ready to start.\n *\n * Call this after all game resources are loaded.\n * The server will wait until all participants have signaled ready,\n * then broadcast an all-ready event to everyone.\n *\n * @example\n * ```ts\n * // After loading completes:\n * controller.signalReady();\n * ```\n */\n signalReady(): void;\n\n // === Event Subscription ===\n\n /**\n * Subscribe to a lifecycle event or a user-defined game event.\n *\n * Lifecycle events use `$`-prefixed names. Use `LifecycleEvent` constants\n * for type-safe subscription:\n * ```ts\n * controller.on(LifecycleEvent.CONTROLLER_JOIN, (pi, info) => { ... });\n * controller.on('phase-update', (data) => { ... }); // user event\n * ```\n */\n on<K extends ControllerLifecycleEvent>(event: K, handler: ControllerLifecycleHandlers[K]): () => void;\n /**\n * Add a listener for a specific event after construction.\n * Can be called before the controller is ready -- handlers are queued\n * and activated when the transport becomes available.\n *\n * @param event - Event name\n * @param handler - Handler function (data) => void\n * @returns Cleanup function to remove the listener\n *\n * @note Events from screen.broadcast() do not include playerIndex.\n * The handler signature is `(data: D)` without playerIndex context.\n * If you need to know which player triggered the broadcast, include\n * that information in the data object from the Screen side.\n *\n * @example\n * ```ts\n * const unsubscribe = controller.on('phase-update', (data) => {\n * console.log('New phase:', data.phase);\n * });\n *\n * // Later: remove listener\n * unsubscribe();\n * ```\n */\n on<K extends EventNames<TEvents>>(\n event: K,\n handler: ControllerEventHandler<EventData<TEvents, K>>,\n ): () => void;\n\n once<K extends ControllerLifecycleEvent>(event: K, handler: ControllerLifecycleHandlers[K]): () => void;\n /**\n * Add a one-time listener that auto-removes after first call.\n *\n * @note The handler is internally wrapped, so it cannot be removed via\n * `off(event, originalHandler)`. Use the returned unsubscribe function instead.\n */\n once<K extends EventNames<TEvents>>(\n event: K,\n handler: ControllerEventHandler<EventData<TEvents, K>>,\n ): () => void;\n\n off<K extends ControllerLifecycleEvent>(event: K, handler?: ControllerLifecycleHandlers[K]): void;\n /**\n * Remove a specific listener or all listeners for an event.\n */\n off<K extends EventNames<TEvents>>(\n event: K,\n handler?: ControllerEventHandler<EventData<TEvents, K>>,\n ): void;\n\n /**\n * Remove all event listeners, or all listeners for a specific event.\n * Only removes user event listeners registered via on()/once().\n * Lifecycle callbacks (onControllerJoin, onAllReady, etc.) are not affected.\n *\n * @param event - Optional event name. If omitted, removes ALL user event listeners.\n */\n removeAllListeners(event?: string): void;\n\n // === Cleanup ===\n\n /**\n * Clean up all resources and disconnect.\n * Call this when unmounting/destroying your game.\n */\n destroy(): void;\n}\n\n// =============================================================================\n// DEBUG OPTIONS\n// =============================================================================\n\n/**\n * Log levels for debug output.\n */\nexport type LogLevel = 'debug' | 'info' | 'warn' | 'error';\n\n/**\n * Debug configuration options.\n */\nexport interface DebugOptions {\n /** Enable debug logging */\n enabled?: boolean;\n\n /** Minimum log level to output */\n level?: LogLevel;\n\n /** Prefix for log messages */\n prefix?: string;\n\n /** Log events being sent */\n logSend?: boolean;\n\n /** Log events being received */\n logReceive?: boolean;\n\n /** Log lifecycle events (ready, destroy, etc.) */\n logLifecycle?: boolean;\n\n /** Custom logger function */\n logger?: (level: LogLevel, message: string, data?: unknown) => void;\n}\n"],"names":["DEFAULT_TIMEOUT"],"mappings":"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"}
1
+ {"version":3,"file":"smore-sdk.umd.js","sources":["../../src/transport/protocol.ts","../../src/transport/PostMessageTransport.ts","../../src/errors.ts","../../src/events.ts","../../src/logger.ts","../../src/shared.ts","../../src/screen.ts","../../src/controller.ts","../../src/types.ts"],"sourcesContent":["/**\n * postMessage protocol types for iframe ↔ parent communication.\n *\n * Uses `_bridge:` prefix to clearly distinguish from `smore:*` socket events.\n * - `_bridge:*` = internal iframe postMessage protocol (never on socket)\n * - `smore:*` = platform service events (socket-level, e.g. smore:player-joined)\n */\n\n/**\n * Cross-reference: `CharacterAppearance` (SDK type) has an identical shape to\n * `CharacterDTO` (server type in game-project/types/src/types.ts).\n * If either type changes, the other must be updated to stay in sync.\n */\nimport type { CharacterAppearance } from '../types';\n\nexport const BRIDGE_MSG_PREFIX = '_bridge:' as const;\n\n/** Current SDK protocol version. Incremented on breaking protocol changes. */\nexport const PROTOCOL_VERSION = 1;\n\nexport interface BridgeReadyMessage {\n type: '_bridge:ready';\n protocolVersion?: number;\n}\n\n/**\n * BridgeInitMessage contains player data sent from the platform to the game iframe.\n *\n * **Field naming convention:**\n * The server uses `name` and `character` fields (matching server/Player model naming).\n * SDK code may reference fallback fields like `nickname` and `appearance` for defensive\n * compatibility with potential future field name changes, but currently the server\n * always sends `name` and `character`.\n */\nexport interface BridgeInitMessage {\n type: '_bridge:init';\n payload: {\n // 'host' = screen side, 'player' = controller side (legacy naming)\n side: 'host' | 'player';\n roomCode: string;\n players: Array<{\n playerIndex: number;\n name: string;\n connected: boolean;\n character: CharacterAppearance | null;\n }>;\n myIndex?: number;\n protocolVersion?: number;\n gameInProgress?: boolean;\n };\n}\n\nexport interface BridgeEmitMessage {\n type: '_bridge:emit';\n payload: {\n event: string;\n data?: unknown;\n ackId?: string;\n };\n}\n\nexport interface BridgeEventMessage {\n type: '_bridge:event';\n payload: {\n event: string;\n data?: unknown;\n };\n}\n\nexport interface BridgeAckMessage {\n type: '_bridge:ack';\n payload: {\n ackId: string;\n data?: unknown;\n };\n}\n\nexport interface BridgeUpdateMessage {\n type: '_bridge:update';\n payload: {\n players?: Array<{\n playerIndex: number;\n name: string;\n connected: boolean;\n character: CharacterAppearance | null;\n }>;\n };\n}\n\nexport type BridgeMessage =\n | BridgeReadyMessage\n | BridgeInitMessage\n | BridgeEmitMessage\n | BridgeEventMessage\n | BridgeAckMessage\n | BridgeUpdateMessage;\n\nexport function isBridgeMessage(data: unknown): data is BridgeMessage {\n return (\n data !== null &&\n typeof data === 'object' &&\n 'type' in data &&\n typeof data.type === 'string' &&\n data.type.startsWith(BRIDGE_MSG_PREFIX)\n );\n}\n\n/**\n * Validates the structure of a _bridge:init payload.\n *\n * Performs runtime validation to ensure the payload contains all required fields\n * with correct types. This provides early error detection if the parent frame\n * sends malformed initialization data.\n *\n * @param payload - The payload to validate\n * @returns true if payload is valid\n * @throws {Error} if validation fails with a descriptive error message\n *\n * @example\n * ```ts\n * try {\n * validateInitPayload(msg.payload);\n * // proceed with initialization\n * } catch (err) {\n * console.error('Invalid init payload:', err.message);\n * }\n * ```\n */\nexport function validateInitPayload(payload: unknown): payload is BridgeInitMessage['payload'] {\n if (!payload || typeof payload !== 'object') {\n throw new Error('[SDK] _bridge:init payload must be an object');\n }\n\n const p = payload as Record<string, unknown>;\n\n // Required: side\n if (typeof p.side !== 'string' || !['host', 'player'].includes(p.side)) {\n throw new Error(`[SDK] _bridge:init payload.side must be \"host\" or \"player\", got: ${p.side}`);\n }\n\n // Required: roomCode\n if (typeof p.roomCode !== 'string' || p.roomCode.length === 0) {\n throw new Error('[SDK] _bridge:init payload.roomCode must be a non-empty string');\n }\n\n // Required: players (array)\n if (!Array.isArray(p.players)) {\n throw new Error('[SDK] _bridge:init payload.players must be an array');\n }\n\n // Optional but validated if present: myIndex (controller-side only)\n if (p.myIndex !== undefined && typeof p.myIndex !== 'number') {\n throw new Error('[SDK] _bridge:init payload.myIndex must be a number if provided');\n }\n\n return true;\n}\n","/**\n * PostMessageTransport - Transport over window.postMessage for iframe-hosted games.\n *\n * Used inside an iframe. Sends `_bridge:emit` to parent and listens for `_bridge:event` from parent.\n */\n\nimport type { Transport, TransportEventHandler } from './types';\nimport type { BridgeEventMessage, BridgeAckMessage } from './protocol';\nimport { isBridgeMessage } from './protocol';\n\n/**\n * PostMessage-based transport for iframe-hosted games.\n *\n * Handles bi-directional communication between iframe game and parent platform using _bridge:* protocol.\n * - Outbound: `_bridge:emit` messages sent to parent\n * - Inbound: `_bridge:event` messages received from parent\n * - Acknowledgment: `_bridge:ack` pattern for request-response flows\n *\n * @example\n * ```ts\n * const transport = new PostMessageTransport('https://smore.gg');\n * transport.on('game-start', (data) => console.log('Game started', data));\n * transport.emit('player-ready', { playerIndex: 0 });\n * ```\n */\nexport class PostMessageTransport implements Transport {\n private static readonly ACK_TIMEOUT = 30000; // 30 seconds\n private handlers = new Map<string, Set<TransportEventHandler>>();\n private ackCallbacks = new Map<string, (...args: unknown[]) => void>();\n private ackCounter = 0;\n private parentOrigin: string;\n private boundMessageHandler: (e: MessageEvent) => void;\n\n constructor(parentOrigin: string = '*') {\n this.parentOrigin = parentOrigin;\n this.boundMessageHandler = this.handleMessage.bind(this);\n window.addEventListener('message', this.boundMessageHandler);\n }\n\n emit(event: string, ...args: unknown[]): void {\n // Detect if last arg is a callback (ack pattern)\n let data: unknown = args[0];\n let ackId: string | undefined;\n\n // Branch 1: emit('event', callback) shorthand — no data, callback only\n // Callback will be invoked when parent sends _bridge:ack with matching ackId\n if (args.length === 1 && typeof args[0] === 'function') {\n data = undefined;\n const callback = args[0] as (...cbArgs: unknown[]) => void;\n ackId = `ack_${++this.ackCounter}`;\n this.ackCallbacks.set(ackId, callback);\n setTimeout(() => {\n if (this.ackCallbacks.has(ackId!)) {\n this.ackCallbacks.delete(ackId!);\n }\n }, PostMessageTransport.ACK_TIMEOUT);\n }\n // Branch 2: emit('event', data, callback) — data + callback (request-response pattern)\n // Parent receives event with data and can send _bridge:ack response\n else if (args.length >= 2 && typeof args[args.length - 1] === 'function') {\n data = args[0];\n const callback = args[args.length - 1] as (...cbArgs: unknown[]) => void;\n ackId = `ack_${++this.ackCounter}`;\n this.ackCallbacks.set(ackId, callback);\n setTimeout(() => {\n if (this.ackCallbacks.has(ackId!)) {\n this.ackCallbacks.delete(ackId!);\n }\n }, PostMessageTransport.ACK_TIMEOUT);\n }\n\n window.parent.postMessage(\n { type: '_bridge:emit', payload: { event, data, ackId } },\n this.parentOrigin,\n );\n }\n\n on(event: string, handler: TransportEventHandler): void {\n let set = this.handlers.get(event);\n if (!set) {\n set = new Set();\n this.handlers.set(event, set);\n }\n set.add(handler);\n }\n\n off(event: string, handler?: TransportEventHandler): void {\n if (!handler) {\n this.handlers.delete(event);\n return;\n }\n this.handlers.get(event)?.delete(handler);\n }\n\n destroy(): void {\n window.removeEventListener('message', this.boundMessageHandler);\n this.handlers.clear();\n this.ackCallbacks.clear();\n }\n\n private handleMessage(e: MessageEvent): void {\n // Origin validation: only accept messages from the expected parent\n if (this.parentOrigin !== '*' && e.origin !== this.parentOrigin) return;\n\n const msg = e.data;\n if (!isBridgeMessage(msg)) return;\n\n // Branch 1: _bridge:event — state sync from bridge (server → bridge → game)\n // Parent relays socket events to iframe via this type. Game subscribes with on().\n if (msg.type === '_bridge:event') {\n const { event, data } = (msg as BridgeEventMessage).payload;\n const set = this.handlers.get(event);\n if (set) {\n set.forEach((handler) => handler(data));\n }\n }\n // Branch 2: _bridge:ack — response to emit with callback (request-response flow)\n // Fires the callback that was passed to emit('event', data, callback).\n // Edge case: In postMessage environment, callbacks cannot be truly serialized,\n // so only data types that survive JSON serialization roundtrip will work.\n else if (msg.type === '_bridge:ack') {\n const { ackId, data } = (msg as BridgeAckMessage).payload;\n const cb = this.ackCallbacks.get(ackId);\n if (cb) {\n this.ackCallbacks.delete(ackId);\n cb(data);\n }\n }\n }\n}\n","import type { SmoreError, SmoreErrorCode } from './types';\n\n/**\n * Base error class for SDK-specific errors with structured metadata.\n *\n * Provides error codes, optional cause chaining, and custom details for debugging.\n * Use this instead of generic Error for all SDK-thrown errors.\n *\n * @example\n * ```ts\n * throw new SmoreSDKError('INVALID_EVENT', 'Event name must not contain \":\"', {\n * details: { event: 'foo:bar' }\n * });\n * ```\n *\n * @example With cause\n * ```ts\n * try {\n * JSON.parse(data);\n * } catch (err) {\n * throw new SmoreSDKError('UNKNOWN', 'Invalid JSON payload', {\n * cause: err as Error,\n * details: { rawData: data }\n * });\n * }\n * ```\n */\nexport class SmoreSDKError extends Error {\n readonly code: SmoreErrorCode;\n /**\n * The original error that caused this error.\n *\n * **Note:** This field intentionally shadows the native `Error.cause` (ES2022).\n * Both this class field and the native property (set via `super()` options bag)\n * are assigned the same value, so there is no behavioral difference.\n * The explicit field provides TypeScript type narrowing to `Error` instead of `unknown`.\n */\n readonly cause?: Error;\n readonly details?: Record<string, unknown>;\n\n constructor(\n code: SmoreErrorCode,\n message: string,\n options?: { cause?: Error; details?: Record<string, unknown> }\n ) {\n super(message, options?.cause ? { cause: options.cause } : undefined);\n this.name = 'SmoreSDKError';\n this.code = code;\n this.cause = options?.cause;\n this.details = options?.details;\n\n const ErrorWithCapture = Error as typeof Error & {\n captureStackTrace?: (target: object, constructor?: Function) => void;\n };\n if (typeof ErrorWithCapture.captureStackTrace === 'function') {\n ErrorWithCapture.captureStackTrace(this, SmoreSDKError);\n }\n }\n\n toSmoreError(): SmoreError {\n return {\n code: this.code,\n message: this.message,\n cause: this.cause,\n details: this.details,\n };\n }\n}\n","/**\n * SDK system event constants (socket level)\n *\n * smore:* prefix = platform service events\n * User events are validated to prevent ':' usage via validateEventName()\n *\n * Note: iframe ↔ parent internal communication uses _bridge:* prefix (transport/protocol.ts)\n */\n\nimport { SmoreSDKError } from './errors';\n\n/**\n * Platform system event names (internal use only).\n *\n * These events are reserved by the S'MORE platform and cannot be used by game code.\n * All platform events use the `smore:` prefix to avoid conflicts with user events.\n *\n * User-defined events are validated to prevent `:` usage via validateEventName().\n *\n * @internal Not part of the public SDK API. Do not import directly.\n */\nexport const SMORE_EVENTS = {\n // Game lifecycle\n GAME_OVER: 'smore:game-over',\n\n // Player management\n PLAYER_JOINED: 'smore:player-joined',\n PLAYER_LEFT: 'smore:player-left',\n PLAYER_DISCONNECTED: 'smore:player-disconnected',\n PLAYER_RECONNECTED: 'smore:player-reconnected',\n\n // Character change\n PLAYER_CHARACTER_UPDATED: 'smore:player-character-updated',\n\n // Rate limiting\n RATE_LIMITED: 'smore:rate-limited',\n\n // Game ready sync\n GAME_READY: 'smore:game-ready',\n ALL_READY: 'smore:all-ready',\n\n // Connection status (self)\n SELF_DISCONNECTED: 'smore:self-disconnected',\n SELF_RECONNECTED: 'smore:self-reconnected',\n\n // Send to specific player (internal use)\n SEND_TO_PLAYER: 'smore:send-to-player', // Used internally by platform, not handled by SDK\n\n // Custom state management\n STATE_SET: 'smore:set-custom-state',\n STATE_CHANGED: 'smore:custom-state-changed',\n STATE_GET_ALL: 'smore:get-custom-states',\n STATE_ALL: 'smore:custom-states',\n} as const;\n\nexport type SmoreEvent = typeof SMORE_EVENTS[keyof typeof SMORE_EVENTS];\n\nexport const SYSTEM_EVENTS: ReadonlySet<string> = new Set(\n Object.values(SMORE_EVENTS)\n);\n\n\nexport const EVENT_NAME_REGEX = /^[a-zA-Z]([a-zA-Z0-9_-]*[a-zA-Z0-9])?$/;\n\nexport const EVENT_NAME_MAX_LENGTH = 128;\n\n/**\n * Validate a user-defined event name.\n *\n * Enforces naming rules to prevent conflicts with platform system events:\n * - Must start with a letter\n * - Can contain letters, numbers, hyphens, underscores\n * - Must end with a letter or number\n * - Cannot contain `:` (reserved for platform events like `smore:*`)\n * - Maximum length: 128 characters\n *\n * @throws {SmoreSDKError} INVALID_EVENT if validation fails\n *\n * @example\n * ```ts\n * validateEventName('player-ready'); // OK\n * validateEventName('score_update'); // OK\n * validateEventName('tap123'); // OK\n * validateEventName('smore:internal'); // Throws: colon not allowed\n * validateEventName('123start'); // Throws: must start with letter\n * ```\n */\nexport function validateEventName(event: string): void {\n if (!event || typeof event !== 'string') {\n throw new SmoreSDKError('INVALID_EVENT', 'Event name must be a non-empty string');\n }\n if (event.length > EVENT_NAME_MAX_LENGTH) {\n throw new SmoreSDKError(\n 'INVALID_EVENT',\n `Event name exceeds maximum length of ${EVENT_NAME_MAX_LENGTH} characters (got ${event.length}).`,\n { details: { event: event.slice(0, 50) + '...' } }\n );\n }\n if (!EVENT_NAME_REGEX.test(event)) {\n throw new SmoreSDKError(\n 'INVALID_EVENT',\n `Invalid event name \"${event}\". Event names must start with a letter, ` +\n `contain only letters, numbers, hyphens, or underscores, and end with a letter or number.`,\n { details: { event } }\n );\n }\n}\n\n/**\n * Check if an event name is a system event.\n *\n * System events use the `smore:` prefix and are reserved for platform use.\n * Prefix-based check is intentional for forward-compatibility with new system events.\n *\n * @param event - Event name to check\n * @returns true if the event is a system event\n */\nexport function isSystemEvent(event: string): boolean {\n return event.startsWith('smore:');\n}\n\n/**\n * Set of valid Screen lifecycle event names (used for $-prefix routing).\n */\nexport const SCREEN_LIFECYCLE_EVENTS: ReadonlySet<string> = new Set([\n '$all-ready',\n '$controller-join',\n '$controller-leave',\n '$controller-disconnect',\n '$controller-reconnect',\n '$character-updated',\n '$error',\n '$connection-change',\n]);\n\n/**\n * Set of valid Controller lifecycle event names (used for $-prefix routing).\n */\nexport const CONTROLLER_LIFECYCLE_EVENTS: ReadonlySet<string> = new Set([\n ...SCREEN_LIFECYCLE_EVENTS,\n '$game-over',\n '$state-recovery',\n]);\n","import type { DebugOptions, LogLevel } from './types';\n\n/**\n * Internal debug logger with configurable verbosity levels.\n *\n * Maps SDK log levels (debug/info/warn/error) to console methods.\n * Can be toggled per-instance with granular control over send/receive/lifecycle logs.\n *\n * @example\n * ```ts\n * const logger = new DebugLogger({ enabled: true, level: 'info' });\n * logger.info('Game initialized');\n * logger.send('player-ready', { index: 0 }); // Shows as debug\n * ```\n */\nexport class DebugLogger {\n private enabled: boolean;\n private level: LogLevel;\n private prefix: string;\n private logSend: boolean;\n private logReceive: boolean;\n private logLifecycle: boolean;\n private customLogger?: (level: LogLevel, message: string, data?: unknown) => void;\n\n private static levelOrder: Record<LogLevel, number> = {\n debug: 0,\n info: 1,\n warn: 2,\n error: 3,\n };\n\n constructor(options?: boolean | DebugOptions, defaultPrefix = '[Smore]') {\n const opts = typeof options === 'boolean' ? { enabled: options } : options;\n this.enabled = opts?.enabled ?? false;\n this.level = opts?.level ?? 'debug';\n this.prefix = opts?.prefix ?? defaultPrefix;\n this.logSend = opts?.logSend ?? true;\n this.logReceive = opts?.logReceive ?? true;\n this.logLifecycle = opts?.logLifecycle ?? true;\n this.customLogger = opts?.logger;\n }\n\n private shouldLog(level: LogLevel): boolean {\n return this.enabled && DebugLogger.levelOrder[level] >= DebugLogger.levelOrder[this.level];\n }\n\n private log(level: LogLevel, message: string, data?: unknown): void {\n if (!this.shouldLog(level)) return;\n\n if (this.customLogger) {\n this.customLogger(level, `${this.prefix} ${message}`, data);\n return;\n }\n\n const consoleMethod = level === 'error' ? 'error' : level === 'warn' ? 'warn' : level === 'debug' ? 'debug' : 'info';\n if (data !== undefined) {\n console[consoleMethod](`${this.prefix} ${message}`, data);\n } else {\n console[consoleMethod](`${this.prefix} ${message}`);\n }\n }\n\n debug(message: string, data?: unknown): void {\n this.log('debug', message, data);\n }\n\n info(message: string, data?: unknown): void {\n this.log('info', message, data);\n }\n\n warn(message: string, data?: unknown): void {\n this.log('warn', message, data);\n }\n\n error(message: string, data?: unknown): void {\n this.log('error', message, data);\n }\n\n send(event: string, data?: unknown): void {\n if (!this.enabled) return;\n if (this.logSend) {\n this.debug(`-> SEND: ${event}`, data);\n }\n }\n\n receive(event: string, data?: unknown): void {\n if (!this.enabled) return;\n if (this.logReceive) {\n this.debug(`<- RECV: ${event}`, data);\n }\n }\n\n lifecycle(message: string, data?: unknown): void {\n if (this.logLifecycle) {\n this.info(`[Lifecycle] ${message}`, data);\n }\n }\n}\n","/**\n * Shared utilities for Screen and Controller implementations.\n * Centralizes common logic to eliminate duplication.\n */\n\nimport type { ControllerInfo } from './types';\nimport { SmoreSDKError } from './errors';\n\n/** Maximum payload size in bytes (64KB). Server silently drops larger payloads. */\nexport const MAX_PAYLOAD_SIZE = 65536;\n\n/**\n * Map raw player data from server/bridge to ControllerInfo.\n * Centralizes the name->nickname and character->appearance field mapping.\n *\n * Server sends: { playerIndex, name, connected, character }\n * SDK exposes: { playerIndex, nickname, connected, appearance }\n */\nexport function mapPlayerDTO(raw: Record<string, unknown>, fallbackIndex: number): ControllerInfo {\n return {\n playerIndex: (raw.playerIndex as number) ?? fallbackIndex,\n nickname: (raw.nickname as string) || (raw.name as string) || `Player ${((raw.playerIndex as number) ?? fallbackIndex) + 1}`,\n connected: raw.connected !== false,\n appearance: (raw.appearance ?? raw.character) as ControllerInfo['appearance'],\n };\n}\n\n/**\n * Validate that event payload does not exceed the 64KB server limit.\n * Throws PAYLOAD_TOO_LARGE error if exceeded.\n */\nexport function validatePayloadSize(data: unknown): void {\n if (data === undefined || data === null) return;\n\n try {\n const serialized = JSON.stringify(data);\n const byteLength = new TextEncoder().encode(serialized).byteLength;\n if (byteLength > MAX_PAYLOAD_SIZE) {\n throw new SmoreSDKError(\n 'PAYLOAD_TOO_LARGE',\n `Event payload exceeds maximum size of ${MAX_PAYLOAD_SIZE} bytes (got ${byteLength} bytes). The server will silently drop this event.`,\n { details: { size: byteLength, limit: MAX_PAYLOAD_SIZE } }\n );\n }\n } catch (err) {\n if (err instanceof SmoreSDKError) throw err;\n // If JSON.stringify fails, the data can't be sent anyway\n }\n}\n","/**\n * createScreen - Factory function for Screen instances (Host/TV side)\n *\n * Synchronous factory with event emitter pattern. Returns a Screen instance\n * immediately. Use `.ready` to await full initialization, and `.on()` /\n * lifecycle methods to register handlers (can be called before ready).\n *\n * @example\n * ```ts\n * interface MyEvents {\n * tap: { x: number; y: number };\n * 'phase-update': { phase: 'lobby' | 'playing' | 'results' };\n * }\n *\n * const screen = createScreen<MyEvents>({ debug: true });\n *\n * screen.on('tap', (playerIndex, data) => {\n * console.log(`Player ${playerIndex} tapped at`, data.x, data.y);\n * });\n *\n * screen.onAllReady(() => startGame());\n * screen.onControllerJoin((playerIndex, info) => addPlayer(playerIndex, info));\n *\n * await screen.ready;\n * screen.broadcast('phase-update', { phase: 'playing' });\n * ```\n */\n\nimport type {\n EventMap,\n EventNames,\n EventData,\n Screen,\n ScreenConfig,\n ScreenEventHandler,\n ControllerInfo,\n PlayerIndex,\n RoomCode,\n GameResults,\n SmoreError,\n CharacterAppearance,\n} from './types';\nimport type { Transport, TransportEventHandler } from './transport/types';\nimport { PostMessageTransport } from './transport/PostMessageTransport';\nimport { isBridgeMessage, validateInitPayload, PROTOCOL_VERSION, type BridgeInitMessage, type BridgeUpdateMessage } from './transport/protocol';\nimport { SmoreSDKError } from './errors';\nimport { SMORE_EVENTS, validateEventName, SCREEN_LIFECYCLE_EVENTS } from './events';\nimport { DebugLogger } from './logger';\nimport { mapPlayerDTO, validatePayloadSize } from './shared';\n\n// =============================================================================\n// CONSTANTS\n// =============================================================================\n\nconst DEFAULT_TIMEOUT = 10000;\n\n// =============================================================================\n// VALIDATION\n// =============================================================================\n\nfunction validatePlayerIndex(playerIndex: PlayerIndex, controllers: readonly ControllerInfo[]): void {\n if (typeof playerIndex !== 'number' || !Number.isInteger(playerIndex)) {\n throw new SmoreSDKError('INVALID_PLAYER', 'Player index must be an integer');\n }\n if (!controllers.some(c => c.playerIndex === playerIndex)) {\n throw new SmoreSDKError(\n 'INVALID_PLAYER',\n `No controller found with player index ${playerIndex}`,\n { details: { playerIndex } }\n );\n }\n}\n\n// =============================================================================\n// SCREEN IMPLEMENTATION\n// =============================================================================\n\nclass ScreenImpl<TEvents extends EventMap> implements Screen<TEvents> {\n private transport: Transport | null = null;\n private config: ScreenConfig;\n private logger: DebugLogger;\n\n private _controllers: ControllerInfo[] = [];\n private _roomCode: RoomCode = '';\n private _isReady = false;\n private _isDestroyed = false;\n private _initTimeoutId: ReturnType<typeof setTimeout> | null = null;\n\n private eventHandlers = new Map<string, Set<ScreenEventHandler<unknown>>>();\n private registeredTransportHandlers: Array<{ event: string; handler: TransportEventHandler }> = [];\n private boundMessageHandler: ((e: MessageEvent) => void) | null = null;\n // Maps user-facing handler -> transport wrappedHandler for proper cleanup in on()/off()\n private handlerToTransport = new Map<Function, { event: string; transportHandler: TransportEventHandler }>();\n\n // Pending handlers registered via on() before transport is ready\n private _pendingHandlers: Array<{ event: string; handler: ScreenEventHandler<unknown> }> = [];\n\n // Unified lifecycle listener map (supports both onXxx() and on('$xxx') patterns)\n private _lifecycleListeners = new Map<string, Set<Function>>();\n\n // Outbound message buffer (messages sent before ready)\n private _outboundBuffer: Array<{ method: string; args: unknown[] }> = [];\n\n // Whether all-ready has fired\n private _allReadyFired = false;\n\n // Self-connection awareness\n private _isConnected = false;\n\n // Custom state management\n private _customStates = new Map<number, Record<string, any>>();\n private _stateChangeListeners = new Set<(playerIndex: number, state: Record<string, any>) => void>();\n\n // Protocol versioning\n private _protocolVersion: number = PROTOCOL_VERSION;\n\n // Ready promise\n private _readyResolve!: () => void;\n private _readyReject!: (err: Error) => void;\n readonly ready: Promise<void>;\n\n constructor(config: ScreenConfig = {}) {\n this.config = config;\n this.logger = new DebugLogger(config.debug, '[SmoreScreen]');\n\n // Create ready promise\n this.ready = new Promise<void>((resolve, reject) => {\n this._readyResolve = resolve;\n this._readyReject = reject;\n });\n\n // Start initialization immediately\n this.startInitialization();\n }\n\n // ---------------------------------------------------------------------------\n // Initialization (called in constructor)\n // ---------------------------------------------------------------------------\n\n private startInitialization(): void {\n this.logger.lifecycle('Initializing screen...');\n\n const parentOrigin = this.config.parentOrigin ?? '*';\n const timeout = this.config.timeout ?? DEFAULT_TIMEOUT;\n\n this._initTimeoutId = setTimeout(() => {\n this.cleanup();\n const error = new SmoreSDKError(\n 'TIMEOUT',\n `Screen initialization timed out after ${timeout}ms. ` +\n `Make sure the parent frame sends _bridge:init. ` +\n `Check that the iframe has correct sandbox attributes (allow-scripts required) and same-origin/cross-origin settings. ` +\n `Create a new Screen instance to retry (this instance has been cleaned up).`,\n { details: { timeout } }\n );\n this.handleError(error);\n this._readyReject(error);\n }, timeout);\n\n this.boundMessageHandler = (e: MessageEvent) => {\n if (parentOrigin !== '*' && e.origin !== parentOrigin) return;\n\n const msg = e.data;\n if (!isBridgeMessage(msg)) return;\n\n if (msg.type === '_bridge:init') {\n clearTimeout(this._initTimeoutId!);\n const initPayload = (msg as BridgeInitMessage).payload;\n\n // MIN-A1-1: Runtime validation of _bridge:init payload structure\n try {\n validateInitPayload(initPayload);\n } catch (err) {\n const error = new SmoreSDKError(\n 'INIT_FAILED',\n `Invalid _bridge:init payload: ${err instanceof Error ? err.message : String(err)}`,\n { details: { payload: initPayload } }\n );\n this.logger.warn('_bridge:init validation failed', error);\n this.handleError(error);\n this._readyReject(error);\n return;\n }\n\n const initData = initPayload;\n\n if (initData.side !== 'host') {\n const error = new SmoreSDKError(\n 'INIT_FAILED',\n `Received init for wrong side: ${initData.side}. Expected \"host\".`,\n { details: { side: initData.side } }\n );\n this.handleError(error);\n this._readyReject(error);\n return;\n }\n\n // Initialize transport\n this.transport = this.config.transport ?? new PostMessageTransport(parentOrigin);\n this._roomCode = initData.roomCode;\n\n // Protocol version negotiation\n const serverProtocolVersion = initData.protocolVersion;\n if (serverProtocolVersion !== undefined) {\n this._protocolVersion = serverProtocolVersion;\n if (serverProtocolVersion !== PROTOCOL_VERSION) {\n this.logger.warn(\n `Protocol version mismatch: SDK v${PROTOCOL_VERSION}, server v${serverProtocolVersion}. ` +\n `Some features may not work correctly.`\n );\n }\n }\n\n this._controllers = this.mapControllersFromInit(initData.players);\n\n // MIN-14: Warn if initialized with zero controllers\n if (this._controllers.length === 0) {\n this.logger.warn('Screen initialized with zero controllers');\n }\n\n this.setupEventHandlers();\n\n // Register all pending user event handlers\n for (const { event, handler } of this._pendingHandlers) {\n this.setupUserEventHandler(event, handler);\n }\n this._pendingHandlers = [];\n\n this._isConnected = true;\n this._isReady = true;\n\n // Flush buffered outbound messages\n for (const buffered of this._outboundBuffer) {\n try {\n switch (buffered.method) {\n case 'broadcast':\n this.broadcast(buffered.args[0] as any, buffered.args[1] as any);\n break;\n case 'sendToController':\n this.sendToController(buffered.args[0] as any, buffered.args[1] as any, buffered.args[2] as any);\n break;\n }\n } catch (err) {\n this.handleError(err instanceof SmoreSDKError ? err : new SmoreSDKError('UNKNOWN', 'Failed to flush buffered message'));\n }\n }\n this._outboundBuffer = [];\n\n this.logger.lifecycle('Screen ready', {\n roomCode: this._roomCode,\n controllers: this._controllers.length,\n });\n\n // Auto-signal ready unless explicitly disabled via config\n if (this.config.autoReady !== false) {\n this.logger.lifecycle('Auto-signaling ready (autoReady enabled)');\n this.signalReady();\n }\n\n this._readyResolve();\n } else if (msg.type === '_bridge:update') {\n if (!this._isReady) {\n this.logger.debug('Ignoring _bridge:update before init completes');\n return;\n }\n const updateData = (msg as BridgeUpdateMessage).payload;\n\n if (updateData.players && Array.isArray(updateData.players)) {\n const oldControllers = this._controllers;\n const newControllers = this.mapControllersFromInit(updateData.players);\n this._controllers = newControllers;\n\n // NOTE: _bridge:update is only delivered during initialization or when GameOverlay\n // re-renders (rare). Mid-game player updates are handled by transport events\n // (smore:player-joined, smore:player-left, etc.) which bypass _bridge:update entirely.\n // The join/leave detection below is a defensive fallback, not the primary update path.\n\n // Detect joins\n for (const nc of newControllers) {\n if (!oldControllers.some(oc => oc.playerIndex === nc.playerIndex)) {\n this.logger.lifecycle('Controller joined (via update)', { playerIndex: nc.playerIndex });\n this._emitLifecycle('$controller-join', nc.playerIndex, nc);\n }\n }\n\n // Detect leaves\n for (const oc of oldControllers) {\n if (!newControllers.some(nc => nc.playerIndex === oc.playerIndex)) {\n this.logger.lifecycle('Controller left (via update)', { playerIndex: oc.playerIndex });\n this._emitLifecycle('$controller-leave', oc.playerIndex);\n }\n }\n }\n this.logger.lifecycle('Room updated', {\n controllers: this._controllers.length,\n });\n }\n };\n\n window.addEventListener('message', this.boundMessageHandler);\n\n // Signal ready to parent\n window.parent.postMessage({ type: '_bridge:ready', protocolVersion: PROTOCOL_VERSION }, parentOrigin);\n this.logger.lifecycle('Sent _bridge:ready to parent');\n }\n\n private mapControllersFromInit(players: unknown[]): ControllerInfo[] {\n return (players as Record<string, unknown>[]).map((p, index) => mapPlayerDTO(p, index));\n }\n\n\n private setupEventHandlers(): void {\n if (!this.transport) return;\n\n // System events: player join/leave/reconnect\n // These smore:* events are forwarded by IframeGameBridge's GAME_FACING_EVENTS allowlist.\n // Each handler updates _controllers to stay consistent and prevent duplicate\n // callbacks if _bridge:update also fires with the same data.\n this.registerTransportHandler(SMORE_EVENTS.PLAYER_JOINED, (data: unknown) => {\n const payload = data as { player?: Record<string, unknown> };\n const playerData = payload?.player;\n if (playerData && typeof playerData.playerIndex === 'number') {\n const controllerInfo = mapPlayerDTO(playerData, playerData.playerIndex as number);\n if (this._controllers.some(c => c.playerIndex === controllerInfo.playerIndex)) return;\n this._controllers = [...this._controllers, controllerInfo];\n this.logger.lifecycle('Controller joined', { playerIndex: controllerInfo.playerIndex });\n this._emitLifecycle('$controller-join', controllerInfo.playerIndex, controllerInfo);\n }\n });\n\n this.registerTransportHandler(SMORE_EVENTS.PLAYER_LEFT, (data: unknown) => {\n const payload = data as { player?: { playerIndex?: number }; playerIndex?: number };\n const playerIndex = payload?.player?.playerIndex ?? payload?.playerIndex;\n if (typeof playerIndex === 'number') {\n if (!this._controllers.some(c => c.playerIndex === playerIndex)) return;\n this._controllers = this._controllers.filter(c => c.playerIndex !== playerIndex);\n this.logger.lifecycle('Controller left', { playerIndex });\n this._emitLifecycle('$controller-leave', playerIndex);\n }\n });\n\n this.registerTransportHandler(SMORE_EVENTS.PLAYER_DISCONNECTED, (data: unknown) => {\n const payload = data as { player?: { playerIndex?: number }; playerIndex?: number };\n const playerIndex = payload?.player?.playerIndex ?? payload?.playerIndex;\n if (typeof playerIndex === 'number') {\n this._controllers = this._controllers.map(c =>\n c.playerIndex === playerIndex ? { ...c, connected: false } : c\n );\n this.logger.lifecycle('Controller disconnected', { playerIndex });\n this._emitLifecycle('$controller-disconnect', playerIndex);\n }\n });\n\n this.registerTransportHandler(SMORE_EVENTS.PLAYER_RECONNECTED, (data: unknown) => {\n const payload = data as { player?: Record<string, unknown> };\n const playerData = payload?.player;\n if (playerData && typeof playerData.playerIndex === 'number') {\n const controllerInfo = mapPlayerDTO(playerData, playerData.playerIndex as number);\n this._controllers = this._controllers.map(c =>\n c.playerIndex === controllerInfo.playerIndex ? controllerInfo : c\n );\n this.logger.lifecycle('Controller reconnected', { playerIndex: controllerInfo.playerIndex });\n this._emitLifecycle('$controller-reconnect', controllerInfo.playerIndex, controllerInfo);\n }\n });\n\n // Character updated: update appearance in _controllers\n // Server emits { player: player.toDTO(), room: room.toDTO() }\n this.registerTransportHandler(SMORE_EVENTS.PLAYER_CHARACTER_UPDATED, (data: unknown) => {\n const payload = data as { player?: { playerIndex?: number; character?: Record<string, unknown> | null; name?: string; nickname?: string } };\n const playerData = payload?.player;\n if (playerData && typeof playerData.playerIndex === 'number') {\n const pi = playerData.playerIndex;\n const appearance = (playerData.character ?? null) as ControllerInfo['appearance'];\n this._controllers = this._controllers.map(c =>\n c.playerIndex === pi ? { ...c, appearance } : c\n );\n this.logger.lifecycle('Player character updated', { playerIndex: pi });\n this._emitLifecycle('$character-updated', pi, appearance ?? null);\n }\n });\n\n // Rate limited: route through error handling\n this.registerTransportHandler(SMORE_EVENTS.RATE_LIMITED, (data: unknown) => {\n const payload = data as { event?: string };\n const eventName = payload?.event ?? 'unknown';\n this.handleError(\n new SmoreSDKError('RATE_LIMITED', `Server rate-limited event: ${eventName}`, {\n details: { event: eventName },\n })\n );\n });\n\n // All ready: all participants have signaled ready\n this.registerTransportHandler(SMORE_EVENTS.ALL_READY, () => {\n this.logger.lifecycle('All participants ready');\n this._allReadyFired = true;\n this._emitLifecycle('$all-ready');\n });\n\n // Self connection status\n this.registerTransportHandler(SMORE_EVENTS.SELF_DISCONNECTED, () => {\n this._isConnected = false;\n this.logger.lifecycle('Connection lost');\n this._emitLifecycle('$connection-change', false);\n });\n\n this.registerTransportHandler(SMORE_EVENTS.SELF_RECONNECTED, () => {\n this._isConnected = true;\n this.logger.lifecycle('Connection restored');\n this._emitLifecycle('$connection-change', true);\n });\n\n // Custom state changed: a controller's custom state was updated\n this.registerTransportHandler(SMORE_EVENTS.STATE_CHANGED, (raw: unknown) => {\n const data = raw as { playerIndex?: number; state?: Record<string, any> };\n if (typeof data?.playerIndex === 'number' && data.state) {\n this._customStates.set(data.playerIndex, data.state);\n this._stateChangeListeners.forEach(cb => {\n try {\n cb(data.playerIndex!, data.state!);\n } catch (err) {\n this.handleError(\n new SmoreSDKError('UNKNOWN', 'Error in custom state change listener', {\n cause: err instanceof Error ? err : undefined,\n })\n );\n }\n });\n }\n });\n\n // All custom states: bulk state update\n this.registerTransportHandler(SMORE_EVENTS.STATE_ALL, (raw: unknown) => {\n const data = raw as { states?: Record<number, Record<string, any>> };\n if (data?.states) {\n for (const [key, value] of Object.entries(data.states)) {\n const pi = Number(key);\n this._customStates.set(pi, value);\n this._stateChangeListeners.forEach(cb => {\n try {\n cb(pi, value);\n } catch (err) {\n this.handleError(\n new SmoreSDKError('UNKNOWN', 'Error in custom state change listener', {\n cause: err instanceof Error ? err : undefined,\n })\n );\n }\n });\n }\n }\n });\n }\n\n /**\n * Sets up a user event handler with playerIndex extraction.\n *\n * Events received from controllers are dropped if they lack a playerIndex field.\n * This is a security measure to prevent controller impersonation - the relay server\n * automatically attaches playerIndex based on the sender's authenticated session,\n * ensuring controllers cannot forge events as other players.\n *\n * Note: `playerIndex` is a reserved field name in event payloads.\n * It is automatically extracted by the SDK and passed as the first argument\n * to Screen event handlers. Game developers must NOT use `playerIndex` as\n * a custom data field name -- it will be stripped from the data object.\n */\n private setupUserEventHandler(event: string, handler: ScreenEventHandler<unknown>): void {\n const wrappedHandler = (data: unknown) => {\n this.logger.receive(event, data);\n const payload = data as { playerIndex?: number };\n // `playerIndex` is a reserved field injected by the relay server.\n // It is extracted here and passed as the first argument to the handler.\n const { playerIndex, ...rest } = payload as { playerIndex?: number; [key: string]: unknown };\n if (typeof playerIndex === 'number') {\n try {\n handler(playerIndex, rest);\n } catch (err) {\n this.handleError(\n new SmoreSDKError('UNKNOWN', `Error in handler for event \"${event}\"`, {\n cause: err instanceof Error ? err : undefined,\n details: { event, playerIndex },\n })\n );\n }\n } else {\n // Drop events without playerIndex to prevent impersonation.\n // The relay server attaches playerIndex automatically based on sender's session.\n this.logger.debug(`Dropping event \"${event}\" without playerIndex`, data);\n }\n };\n\n this.registerTransportHandler(event, wrappedHandler);\n\n // Also store in eventHandlers for on/off management\n let handlers = this.eventHandlers.get(event);\n if (!handlers) {\n handlers = new Set();\n this.eventHandlers.set(event, handlers);\n }\n handlers.add(handler);\n\n // Map user handler to transport handler for cleanup\n this.handlerToTransport.set(handler as Function, { event, transportHandler: wrappedHandler });\n }\n\n private registerTransportHandler(event: string, handler: TransportEventHandler): void {\n if (!this.transport) return;\n this.transport.on(event, handler);\n this.registeredTransportHandlers.push({ event, handler });\n }\n\n // ---------------------------------------------------------------------------\n // Properties (readonly)\n // ---------------------------------------------------------------------------\n\n /**\n * Returns a new shallow copy of the controllers array on every access.\n * Cache the result if accessing repeatedly in the same frame/tick.\n */\n get controllers(): readonly ControllerInfo[] {\n return [...this._controllers];\n }\n\n get roomCode(): RoomCode {\n return this._roomCode;\n }\n\n get isReady(): boolean {\n return this._isReady;\n }\n\n get isDestroyed(): boolean {\n return this._isDestroyed;\n }\n\n get isConnected(): boolean {\n return this._isConnected;\n }\n\n get protocolVersion(): number {\n return this._protocolVersion;\n }\n\n // ---------------------------------------------------------------------------\n // Lifecycle Listener Helpers\n // ---------------------------------------------------------------------------\n\n private _addLifecycleListener(event: string, listener: Function): () => void {\n let set = this._lifecycleListeners.get(event);\n if (!set) {\n set = new Set();\n this._lifecycleListeners.set(event, set);\n }\n set.add(listener);\n return () => {\n set!.delete(listener);\n if (set!.size === 0) this._lifecycleListeners.delete(event);\n };\n }\n\n private _emitLifecycle(event: string, ...args: unknown[]): void {\n this._lifecycleListeners.get(event)?.forEach(cb => {\n try {\n (cb as Function)(...args);\n } catch (err) {\n this.handleError(\n new SmoreSDKError('UNKNOWN', `Error in lifecycle handler for \"${event}\"`, {\n cause: err instanceof Error ? err : undefined,\n details: { event },\n })\n );\n }\n });\n }\n\n private _hasLifecycleListeners(event: string): boolean {\n const set = this._lifecycleListeners.get(event);\n return set !== undefined && set.size > 0;\n }\n\n // ---------------------------------------------------------------------------\n // Lifecycle Methods\n // ---------------------------------------------------------------------------\n\n onAllReady(callback: () => void): () => void {\n if (this._allReadyFired) {\n callback();\n }\n return this._addLifecycleListener('$all-ready', callback);\n }\n\n onControllerJoin(callback: (playerIndex: PlayerIndex, info: ControllerInfo) => void): () => void {\n return this._addLifecycleListener('$controller-join', callback);\n }\n\n onControllerLeave(callback: (playerIndex: PlayerIndex) => void): () => void {\n return this._addLifecycleListener('$controller-leave', callback);\n }\n\n onControllerDisconnect(callback: (playerIndex: PlayerIndex) => void): () => void {\n return this._addLifecycleListener('$controller-disconnect', callback);\n }\n\n onControllerReconnect(callback: (playerIndex: PlayerIndex, info: ControllerInfo) => void): () => void {\n return this._addLifecycleListener('$controller-reconnect', callback);\n }\n\n onCharacterUpdated(callback: (playerIndex: PlayerIndex, appearance: CharacterAppearance | null) => void): () => void {\n return this._addLifecycleListener('$character-updated', callback);\n }\n\n onError(callback: (error: SmoreError) => void): () => void {\n return this._addLifecycleListener('$error', callback);\n }\n\n onConnectionChange(callback: (connected: boolean) => void): () => void {\n return this._addLifecycleListener('$connection-change', callback);\n }\n\n // ---------------------------------------------------------------------------\n // Custom State Methods\n // ---------------------------------------------------------------------------\n\n getControllerState(playerIndex: number): Record<string, any> | undefined {\n return this._customStates.get(playerIndex);\n }\n\n getAllControllerStates(): Record<number, Record<string, any>> {\n const result: Record<number, Record<string, any>> = {};\n for (const [key, value] of this._customStates) {\n result[key] = value;\n }\n return result;\n }\n\n onCustomStateChange(listener: (playerIndex: number, state: Record<string, any>) => void): () => void {\n this._stateChangeListeners.add(listener);\n return () => {\n this._stateChangeListeners.delete(listener);\n };\n }\n\n // ---------------------------------------------------------------------------\n // Communication Methods\n // ---------------------------------------------------------------------------\n\n /**\n * Send type-safe events to all controllers.\n *\n * Uses EventMap generic for compile-time type checking of event names and data payloads.\n *\n * @note Data should be an object. Primitive values will be wrapped as `{ data: value }` by the relay server.\n * @note Maximum payload size is 64KB. Data exceeding this limit will be silently dropped by the server.\n * @note Fire-and-forget sends (no callback) will silently fail if rate-limited.\n * Use the onError callback or smore:rate-limited event to detect rate limiting.\n *\n * Warning: Avoid sending primitive values directly (string, number, boolean).\n * Wrap in an object: broadcast('event', { value: 42 }) instead of broadcast('event', 42)\n */\n broadcast<K extends EventNames<TEvents>>(event: K, data: EventData<TEvents, K>): void {\n if (this._isDestroyed) {\n throw new SmoreSDKError('DESTROYED', 'Cannot call broadcast() after destroy()');\n }\n if (!this._isReady || !this.transport) {\n this._outboundBuffer.push({ method: 'broadcast', args: [event, data] });\n this.logger.debug(`Buffered broadcast \"${event}\" (screen not ready yet)`);\n return;\n }\n validateEventName(event);\n validatePayloadSize(data);\n this.logger.send(event, data);\n this.transport!.emit(event, data);\n }\n\n /**\n * Send an event to a specific controller.\n *\n * **Reserved field:** `targetPlayerIndex` is automatically merged into the data payload\n * to route the event to the specified controller. Game developers should avoid using\n * `targetPlayerIndex` as a custom data field name to prevent conflicts.\n *\n * @note Data should be an object. Primitive values will be wrapped as `{ data: value }` by the relay server.\n * @note Maximum payload size is 64KB. Data exceeding this limit will be silently dropped by the server.\n *\n * @param playerIndex - Target controller's player index\n * @param event - Event name\n * @param data - Event data payload\n */\n sendToController<K extends EventNames<TEvents>>(\n playerIndex: PlayerIndex,\n event: K,\n data: EventData<TEvents, K>\n ): void {\n if (this._isDestroyed) {\n throw new SmoreSDKError('DESTROYED', 'Cannot call sendToController() after destroy()');\n }\n if (!this._isReady || !this.transport) {\n this._outboundBuffer.push({ method: 'sendToController', args: [playerIndex, event, data] });\n this.logger.debug(`Buffered sendToController \"${event}\" -> Player ${playerIndex} (screen not ready yet)`);\n return;\n }\n validateEventName(event);\n validatePlayerIndex(playerIndex, this._controllers);\n validatePayloadSize(data);\n\n // MIN-A2-2: Warn if targetPlayerIndex already exists in data (reserved field)\n if (data && typeof data === 'object' && 'targetPlayerIndex' in data) {\n this.logger.warn(\n `Event \"${event}\" data contains reserved field \"targetPlayerIndex\" which will be overwritten for routing.`\n );\n }\n\n this.logger.send(`${event} -> Player ${playerIndex}`, data);\n this.transport!.emit(event, {\n targetPlayerIndex: playerIndex,\n ...(data && typeof data === 'object' ? data : { data }),\n });\n }\n\n // ---------------------------------------------------------------------------\n // Game Lifecycle\n // ---------------------------------------------------------------------------\n\n gameOver(results?: GameResults): void {\n this.ensureReady('gameOver');\n this.logger.lifecycle('Game over', results);\n this.transport!.emit(SMORE_EVENTS.GAME_OVER, { results });\n }\n\n signalReady(): void {\n this.ensureReady('signalReady');\n this.logger.lifecycle('Signaling ready');\n this.transport!.emit(SMORE_EVENTS.GAME_READY, {});\n }\n\n // ---------------------------------------------------------------------------\n // Event Subscription\n // ---------------------------------------------------------------------------\n\n /**\n * Register an event handler for messages from controllers.\n *\n * Can be called before the Screen is ready. Handlers registered before ready\n * are queued and activated when the transport becomes available.\n */\n on<K extends EventNames<TEvents>>(\n event: K,\n handler: ScreenEventHandler<EventData<TEvents, K>>\n ): () => void {\n // Route lifecycle events ($-prefixed)\n if (typeof event === 'string' && (event as string).startsWith('$')) {\n const validEvents = SCREEN_LIFECYCLE_EVENTS;\n if (!validEvents.has(event as string)) {\n throw new SmoreSDKError('INVALID_EVENT', `Unknown lifecycle event: \"${event}\". Valid lifecycle events: ${Array.from(validEvents).join(', ')}`);\n }\n // Special handling for $all-ready: fire immediately if already happened\n if (event === '$all-ready' && this._allReadyFired) {\n (handler as unknown as () => void)();\n }\n return this._addLifecycleListener(event as string, handler as Function);\n }\n\n validateEventName(event);\n\n let handlers = this.eventHandlers.get(event);\n if (!handlers) {\n handlers = new Set();\n this.eventHandlers.set(event, handlers);\n }\n handlers.add(handler as ScreenEventHandler<unknown>);\n\n // If transport ready, register immediately\n if (this.transport) {\n const wrappedHandler = (data: unknown) => {\n this.logger.receive(event, data);\n const payload = data as { playerIndex?: number };\n const { playerIndex, ...rest } = payload as { playerIndex?: number; [key: string]: unknown };\n if (typeof playerIndex === 'number') {\n try {\n handler(playerIndex, rest as EventData<TEvents, K>);\n } catch (err) {\n this.handleError(\n new SmoreSDKError('UNKNOWN', `Error in handler for event \"${event}\"`, {\n cause: err instanceof Error ? err : undefined,\n })\n );\n }\n } else {\n this.logger.debug(`Dropping event \"${event}\" without playerIndex`, data);\n }\n };\n this.registerTransportHandler(event, wrappedHandler);\n this.handlerToTransport.set(handler as Function, { event, transportHandler: wrappedHandler });\n } else {\n // Store for later registration when transport becomes available\n this._pendingHandlers.push({ event: event as string, handler: handler as ScreenEventHandler<unknown> });\n }\n\n // Return unsubscribe function\n return () => {\n handlers?.delete(handler as ScreenEventHandler<unknown>);\n if (handlers?.size === 0) {\n this.eventHandlers.delete(event);\n }\n\n // Remove from pending if not yet registered\n this._pendingHandlers = this._pendingHandlers.filter(\n p => !(p.event === event && p.handler === handler)\n );\n\n // Remove from transport if registered\n const entry = this.handlerToTransport.get(handler as Function);\n if (entry) {\n this.transport?.off(event, entry.transportHandler);\n this.registeredTransportHandlers = this.registeredTransportHandlers.filter(\n h => h.handler !== entry.transportHandler\n );\n this.handlerToTransport.delete(handler as Function);\n }\n };\n }\n\n /**\n * Register an event handler that will be called only once.\n *\n * The handler is automatically removed after the first invocation.\n *\n * **Important:** The wrapped handler cannot be removed via `off(event, originalHandler)`.\n * Use the returned unsubscribe function instead.\n *\n * @param event - Event name to listen for\n * @param handler - Handler function to call once\n * @returns Unsubscribe function to remove the handler before it fires\n */\n once<K extends EventNames<TEvents>>(\n event: K,\n handler: ScreenEventHandler<EventData<TEvents, K>>\n ): () => void {\n if (typeof event === 'string' && (event as string).startsWith('$')) {\n const validEvents = SCREEN_LIFECYCLE_EVENTS;\n if (!validEvents.has(event as string)) {\n throw new SmoreSDKError('INVALID_EVENT', `Unknown lifecycle event: \"${event}\"`);\n }\n if (event === '$all-ready' && this._allReadyFired) {\n (handler as unknown as () => void)();\n return () => {};\n }\n const wrapper = (...args: unknown[]) => {\n unsub();\n (handler as Function)(...args);\n };\n const unsub = this._addLifecycleListener(event as string, wrapper);\n return unsub;\n }\n\n const wrappedHandler: ScreenEventHandler<EventData<TEvents, K>> = (playerIndex, data) => {\n unsubscribe();\n handler(playerIndex, data);\n };\n const unsubscribe = this.on(event, wrappedHandler);\n return unsubscribe;\n }\n\n off<K extends EventNames<TEvents>>(\n event: K,\n handler?: ScreenEventHandler<EventData<TEvents, K>>\n ): void {\n if (typeof event === 'string' && (event as string).startsWith('$')) {\n if (!handler) {\n this._lifecycleListeners.delete(event as string);\n } else {\n this._lifecycleListeners.get(event as string)?.delete(handler as Function);\n }\n return;\n }\n\n if (!handler) {\n // Remove all handlers for this event\n this.eventHandlers.delete(event);\n this.transport?.off(event);\n this.registeredTransportHandlers = this.registeredTransportHandlers.filter(h => h.event !== event);\n for (const [key, val] of this.handlerToTransport) {\n if (val.event === event) this.handlerToTransport.delete(key);\n }\n // Remove from pending\n this._pendingHandlers = this._pendingHandlers.filter(p => p.event !== event);\n } else {\n const handlers = this.eventHandlers.get(event);\n handlers?.delete(handler as ScreenEventHandler<unknown>);\n if (handlers?.size === 0) {\n this.eventHandlers.delete(event);\n }\n // Remove specific transport handler\n const entry = this.handlerToTransport.get(handler as Function);\n if (entry) {\n this.transport?.off(event, entry.transportHandler);\n this.registeredTransportHandlers = this.registeredTransportHandlers.filter(\n h => h.handler !== entry.transportHandler\n );\n this.handlerToTransport.delete(handler as Function);\n }\n // Remove from pending\n this._pendingHandlers = this._pendingHandlers.filter(\n p => !(p.event === event && p.handler === handler)\n );\n }\n }\n\n removeAllListeners(event?: string): void {\n if (event) {\n // Remove all handlers for specific event\n this.eventHandlers.delete(event);\n this.transport?.off(event);\n this.registeredTransportHandlers = this.registeredTransportHandlers.filter(h => h.event !== event);\n for (const [key, val] of this.handlerToTransport) {\n if (val.event === event) this.handlerToTransport.delete(key);\n }\n this._pendingHandlers = this._pendingHandlers.filter(p => p.event !== event);\n } else {\n // Remove all user event handlers\n for (const evt of [...this.eventHandlers.keys()]) {\n this.removeAllListeners(evt);\n }\n }\n }\n\n // ---------------------------------------------------------------------------\n // Utilities\n // ---------------------------------------------------------------------------\n\n getController(playerIndex: PlayerIndex): ControllerInfo | undefined {\n return this._controllers.find((c) => c.playerIndex === playerIndex);\n }\n\n getControllerCount(): number {\n return this._controllers.filter((c) => c.connected).length;\n }\n\n // ---------------------------------------------------------------------------\n // Cleanup\n // ---------------------------------------------------------------------------\n\n destroy(): void {\n if (this._isDestroyed) return;\n\n this.logger.lifecycle('Destroying screen...');\n this._isDestroyed = true;\n this._isReady = false;\n\n this.cleanup();\n this.logger.lifecycle('Screen destroyed');\n }\n\n private cleanup(): void {\n // Clear init timeout if still pending\n if (this._initTimeoutId) {\n clearTimeout(this._initTimeoutId);\n this._initTimeoutId = null;\n }\n\n // Remove all registered transport handlers\n for (const { event, handler } of this.registeredTransportHandlers) {\n this.transport?.off(event, handler);\n }\n this.registeredTransportHandlers = [];\n\n // Clear event handlers\n this.eventHandlers.clear();\n this.handlerToTransport.clear();\n this._pendingHandlers = [];\n\n // Clear lifecycle callbacks\n this._lifecycleListeners.clear();\n this._customStates.clear();\n this._stateChangeListeners.clear();\n this._isConnected = false;\n this._outboundBuffer = [];\n\n // Destroy transport\n if (this.transport instanceof PostMessageTransport) {\n this.transport.destroy();\n }\n this.transport = null;\n\n // Remove message listener\n if (this.boundMessageHandler) {\n window.removeEventListener('message', this.boundMessageHandler);\n this.boundMessageHandler = null;\n }\n }\n\n // ---------------------------------------------------------------------------\n // Error Handling\n // ---------------------------------------------------------------------------\n\n private handleError(error: SmoreSDKError): void {\n // Always log at warn level so errors are never completely silent\n this.logger.warn(`Error in handler: ${error.message}`);\n const smoreError = error.toSmoreError();\n if (this._hasLifecycleListeners('$error')) {\n this._emitLifecycle('$error', smoreError);\n } else {\n this.logger.error(error.message, error.details);\n }\n }\n\n private ensureReady(method: string): void {\n if (this._isDestroyed) {\n throw new SmoreSDKError(\n 'DESTROYED',\n `Cannot call ${method}() after destroy()`,\n { details: { method } }\n );\n }\n if (!this._isReady || !this.transport) {\n throw new SmoreSDKError(\n 'NOT_READY',\n `Cannot call ${method}() before screen is ready. Use await screen.ready.`,\n { details: { method } }\n );\n }\n }\n}\n\n// =============================================================================\n// FACTORY FUNCTION\n// =============================================================================\n\n/**\n * Create a Screen instance for the host/TV side of your game.\n *\n * Returns a Screen instance synchronously. The screen begins listening\n * for the bridge init message immediately. Register event handlers and\n * lifecycle callbacks on the instance, then await `.ready` if needed.\n *\n * @template TEvents - Event map type for type-safe events\n * @param config - Screen configuration (debug, parentOrigin, timeout)\n * @returns Screen instance\n *\n * @example\n * ```ts\n * const screen = createScreen<MyEvents>({ debug: true });\n *\n * screen.on('tap', (playerIndex, data) => {\n * screen.broadcast('round-result', { winner: playerIndex });\n * });\n *\n * screen.onAllReady(() => startGame());\n * screen.onControllerJoin((playerIndex, info) => addPlayer(playerIndex, info));\n *\n * await screen.ready;\n * ```\n */\nexport function createScreen<TEvents extends EventMap = EventMap>(\n config?: ScreenConfig\n): Screen<TEvents> {\n return new ScreenImpl<TEvents>(config);\n}\n","/**\n * createController - Factory function for creating a Controller instance.\n *\n * Returns a Controller instance synchronously. The controller begins listening\n * for the bridge init message immediately. Use `.ready` to await full\n * initialization, and `.on()` / lifecycle methods to register handlers\n * (can be called before ready).\n *\n * @example\n * ```ts\n * const controller = createController<MyEvents>({ debug: true });\n *\n * controller.on('phase-update', (data) => setPhase(data.phase));\n * controller.onAllReady(() => console.log('Ready!'));\n *\n * await controller.ready;\n * controller.send('tap', { x: 100, y: 200 });\n * ```\n */\n\nimport type {\n Controller,\n ControllerConfig,\n ControllerEventHandler,\n ControllerInfo,\n EventData,\n EventMap,\n EventNames,\n PlayerIndex,\n RoomCode,\n SmoreError,\n GameResults,\n CharacterAppearance,\n} from './types';\nimport { PostMessageTransport } from './transport/PostMessageTransport';\nimport type { Transport, TransportEventHandler } from './transport/types';\nimport {\n isBridgeMessage,\n validateInitPayload,\n PROTOCOL_VERSION,\n type BridgeInitMessage,\n type BridgeUpdateMessage,\n} from './transport/protocol';\nimport { SmoreSDKError } from './errors';\nimport { SMORE_EVENTS, validateEventName, CONTROLLER_LIFECYCLE_EVENTS } from './events';\nimport { DebugLogger } from './logger';\nimport { mapPlayerDTO, validatePayloadSize } from './shared';\n\n// =============================================================================\n// CONSTANTS\n// =============================================================================\n\nconst DEFAULT_TIMEOUT = 10000;\n\n// =============================================================================\n// CONTROLLER IMPLEMENTATION\n// =============================================================================\n\nclass ControllerImpl<TEvents extends EventMap> implements Controller<TEvents> {\n private transport: Transport | null = null;\n private config: ControllerConfig;\n private logger: DebugLogger;\n private _roomCode: RoomCode = '';\n private _myPlayerIndex: PlayerIndex = -1;\n private _isReady: boolean = false;\n private _isDestroyed: boolean = false;\n private _initTimeoutId: ReturnType<typeof setTimeout> | null = null;\n private boundMessageHandler: ((e: MessageEvent) => void) | null = null;\n private registeredHandlers: Array<{ event: string; handler: TransportEventHandler }> = [];\n private eventListeners = new Map<string, Set<ControllerEventHandler<unknown>>>();\n // Maps user-facing handler -> transport wrappedHandler for proper cleanup in on()/off()\n private handlerToTransport = new Map<Function, { event: string; transportHandler: TransportEventHandler }>();\n private _controllers: ControllerInfo[] = [];\n private _customStates = new Map<number, Record<string, any>>();\n private _stateChangeListeners = new Set<(playerIndex: number, state: Record<string, any>) => void>();\n\n // Pending handlers registered via on() before transport is ready\n private _pendingHandlers: Array<{ event: string; handler: ControllerEventHandler<unknown> }> = [];\n\n // Unified lifecycle listener map (supports both onXxx() and on('$xxx') patterns)\n private _lifecycleListeners = new Map<string, Set<Function>>();\n\n // Outbound message buffer (messages sent before ready)\n private _outboundBuffer: Array<{ method: string; args: unknown[] }> = [];\n\n // Whether all-ready has fired\n private _allReadyFired = false;\n\n // Self-connection awareness\n private _isConnected = false;\n\n // Protocol versioning\n private _protocolVersion: number = PROTOCOL_VERSION;\n\n // Ready promise\n private _readyResolve!: () => void;\n private _readyReject!: (err: Error) => void;\n readonly ready: Promise<void>;\n\n constructor(config: ControllerConfig = {}) {\n this.config = config;\n this.logger = new DebugLogger(config.debug, '[SmoreController]');\n\n // Create ready promise\n this.ready = new Promise<void>((resolve, reject) => {\n this._readyResolve = resolve;\n this._readyReject = reject;\n });\n\n // Start initialization immediately\n this.startInitialization();\n }\n\n // ---------------------------------------------------------------------------\n // Properties (readonly)\n // ---------------------------------------------------------------------------\n\n get myPlayerIndex(): PlayerIndex {\n return this._myPlayerIndex;\n }\n\n get roomCode(): RoomCode {\n return this._roomCode;\n }\n\n get isReady(): boolean {\n return this._isReady;\n }\n\n get isDestroyed(): boolean {\n return this._isDestroyed;\n }\n\n get isConnected(): boolean {\n return this._isConnected;\n }\n\n get protocolVersion(): number {\n return this._protocolVersion;\n }\n\n /**\n * Read-only list of all known controllers (players) in the room.\n * Returns full ControllerInfo including playerIndex, nickname, connected status, and appearance.\n *\n * Returns a new shallow copy on every access. Cache the result if accessing\n * repeatedly in the same frame/tick.\n */\n get controllers(): readonly ControllerInfo[] {\n return [...this._controllers];\n }\n\n get me(): ControllerInfo | undefined {\n return this._controllers.find(c => c.playerIndex === this._myPlayerIndex);\n }\n\n /**\n * Returns the number of currently connected players.\n */\n getControllerCount(): number {\n return this._controllers.filter(c => c.connected).length;\n }\n\n getController(playerIndex: PlayerIndex): ControllerInfo | undefined {\n return this._controllers.find((c) => c.playerIndex === playerIndex);\n }\n\n // ---------------------------------------------------------------------------\n // Initialization\n // ---------------------------------------------------------------------------\n\n private startInitialization(): void {\n const parentOrigin = this.config.parentOrigin ?? '*';\n const timeout = this.config.timeout ?? DEFAULT_TIMEOUT;\n\n this.logger.lifecycle('Initializing controller...', { parentOrigin, timeout });\n\n this._initTimeoutId = setTimeout(() => {\n this.cleanup();\n const error = new SmoreSDKError(\n 'TIMEOUT',\n `Controller initialization timed out after ${timeout}ms. ` +\n `Make sure the parent window sends _bridge:init message. ` +\n `Check that the iframe has correct sandbox attributes (allow-scripts required) and same-origin/cross-origin settings. ` +\n `Create a new Controller instance to retry (this instance has been cleaned up).`,\n { details: { timeout } },\n );\n this.handleError(error);\n this._readyReject(error);\n }, timeout);\n\n // Listen for init message from parent\n this.boundMessageHandler = (e: MessageEvent) => {\n if (parentOrigin !== '*' && e.origin !== parentOrigin) return;\n\n const msg = e.data;\n if (!isBridgeMessage(msg)) return;\n\n if (msg.type === '_bridge:init') {\n clearTimeout(this._initTimeoutId!);\n this.handleInit(msg as BridgeInitMessage, parentOrigin);\n } else if (msg.type === '_bridge:update') {\n this.handleUpdate(msg as BridgeUpdateMessage);\n }\n };\n\n window.addEventListener('message', this.boundMessageHandler);\n\n // Signal ready to parent\n this.logger.lifecycle('Sending _bridge:ready to parent');\n window.parent.postMessage({ type: '_bridge:ready', protocolVersion: PROTOCOL_VERSION }, parentOrigin);\n }\n\n private handleInit(\n msg: BridgeInitMessage,\n parentOrigin: string,\n ): void {\n const initPayload = msg.payload;\n\n this.logger.debug('Received _bridge:init', initPayload);\n\n // MIN-A1-1: Runtime validation of _bridge:init payload structure\n try {\n validateInitPayload(initPayload);\n } catch (err) {\n const error = new SmoreSDKError(\n 'INIT_FAILED',\n `Invalid _bridge:init payload: ${err instanceof Error ? err.message : String(err)}`,\n { details: { payload: initPayload } }\n );\n this.logger.warn('_bridge:init validation failed', error);\n this.handleError(error);\n this._readyReject(error);\n return;\n }\n\n const initData = initPayload;\n\n if (initData.side !== 'player') {\n const error = new SmoreSDKError(\n 'INIT_FAILED',\n `Controller received init for wrong side: ${initData.side}`,\n { details: { side: initData.side } },\n );\n this.handleError(error);\n this._readyReject(error);\n return;\n }\n\n if (initData.myIndex === undefined) {\n const error = new SmoreSDKError(\n 'INIT_FAILED',\n 'Missing myIndex in init payload',\n { details: initData },\n );\n this.handleError(error);\n this._readyReject(error);\n return;\n }\n\n // Initialize transport\n this.transport = this.config.transport ?? new PostMessageTransport(parentOrigin);\n this._roomCode = initData.roomCode;\n\n // Protocol version negotiation\n const serverProtocolVersion = initData.protocolVersion;\n if (serverProtocolVersion !== undefined) {\n this._protocolVersion = serverProtocolVersion;\n if (serverProtocolVersion !== PROTOCOL_VERSION) {\n this.logger.warn(\n `Protocol version mismatch: SDK v${PROTOCOL_VERSION}, server v${serverProtocolVersion}. ` +\n `Some features may not work correctly.`\n );\n }\n }\n\n this._myPlayerIndex = initData.myIndex;\n\n // Track known players for join/leave detection (full ControllerInfo)\n const initPlayers = initData.players as Record<string, unknown>[];\n this._controllers = initPlayers\n .filter(p => typeof p.playerIndex === 'number')\n .map((p, index) => mapPlayerDTO(p, index));\n\n this.setupEventHandlers();\n\n // Register all pending user event handlers\n for (const { event, handler } of this._pendingHandlers) {\n this.setupUserEventHandler(event, handler);\n }\n this._pendingHandlers = [];\n\n this._isConnected = true;\n this._isReady = true;\n\n // Request state recovery if reconnecting to a game in progress\n if (initData.gameInProgress && this.transport) {\n this.logger.lifecycle('Game in progress detected, requesting state recovery');\n this.transport.emit(SMORE_EVENTS.STATE_GET_ALL, {});\n }\n\n // Flush buffered outbound messages\n for (const buffered of this._outboundBuffer) {\n try {\n switch (buffered.method) {\n case 'send':\n this.send(buffered.args[0] as any, buffered.args[1] as any);\n break;\n }\n } catch (err) {\n this.handleError(err instanceof SmoreSDKError ? err : new SmoreSDKError('UNKNOWN', 'Failed to flush buffered message'));\n }\n }\n this._outboundBuffer = [];\n\n this.logger.lifecycle('Controller ready', {\n roomCode: this._roomCode,\n myIndex: this._myPlayerIndex,\n });\n\n // Auto-signal ready unless explicitly disabled via config\n if (this.config.autoReady !== false) {\n this.logger.lifecycle('Auto-signaling ready (autoReady enabled)');\n this.signalReady();\n }\n\n this._readyResolve();\n }\n\n private handleUpdate(msg: BridgeUpdateMessage): void {\n if (!this._isReady) {\n this.logger.debug('Ignoring _bridge:update before init completes');\n return;\n }\n const updateData = msg.payload;\n this.logger.debug('Received _bridge:update', updateData);\n\n if (updateData.players && Array.isArray(updateData.players)) {\n const players = updateData.players as Record<string, unknown>[];\n const newControllers: ControllerInfo[] = players\n .filter(p => typeof p.playerIndex === 'number')\n .map((p, index) => mapPlayerDTO(p, index));\n\n const oldControllers = this._controllers;\n\n // Detect joins\n for (const nc of newControllers) {\n if (!oldControllers.some(oc => oc.playerIndex === nc.playerIndex)) {\n this._emitLifecycle('$controller-join', nc.playerIndex, nc);\n }\n }\n\n // Detect leaves\n for (const oc of oldControllers) {\n if (!newControllers.some(nc => nc.playerIndex === oc.playerIndex)) {\n this._emitLifecycle('$controller-leave', oc.playerIndex);\n }\n }\n\n // Update connected state for existing players and fire disconnect/reconnect callbacks\n for (const nc of newControllers) {\n const oc = oldControllers.find(c => c.playerIndex === nc.playerIndex);\n if (oc) {\n // Detect disconnect (was connected, now not)\n if (oc.connected && !nc.connected) {\n this.logger.debug('Player disconnected (via update)', { playerIndex: nc.playerIndex });\n this._emitLifecycle('$controller-disconnect', nc.playerIndex);\n }\n // Detect reconnect (was disconnected, now connected)\n if (!oc.connected && nc.connected) {\n this.logger.debug('Player reconnected (via update)', { playerIndex: nc.playerIndex });\n this._emitLifecycle('$controller-reconnect', nc.playerIndex, nc);\n }\n }\n }\n\n this._controllers = newControllers;\n }\n }\n\n private setupEventHandlers(): void {\n if (!this.transport) return;\n\n // System events: player join/leave\n // These smore:* events are forwarded by IframeGameBridge's GAME_FACING_EVENTS allowlist.\n // Each handler updates _controllers to stay consistent and prevent duplicate\n // callbacks if _bridge:update also fires with the same data.\n this.registerHandler(SMORE_EVENTS.PLAYER_JOINED, (raw: unknown) => {\n const data = raw as { player?: Record<string, unknown>; playerIndex?: number };\n const playerInfo = data.player as Record<string, unknown> | undefined;\n const playerIndex = playerInfo?.playerIndex as number | undefined ?? data.playerIndex;\n if (playerIndex !== undefined) {\n if (this._controllers.some(c => c.playerIndex === playerIndex)) return;\n const controllerInfo = playerInfo\n ? mapPlayerDTO(playerInfo, playerIndex)\n : mapPlayerDTO({ playerIndex, connected: true }, playerIndex);\n this._controllers = [...this._controllers, controllerInfo];\n this.logger.debug('Player joined', { playerIndex });\n this._emitLifecycle('$controller-join', playerIndex, controllerInfo);\n }\n });\n\n this.registerHandler(SMORE_EVENTS.PLAYER_LEFT, (raw: unknown) => {\n const data = raw as { player?: { playerIndex?: number }; playerIndex?: number };\n const playerIndex = data.player?.playerIndex ?? data.playerIndex;\n if (playerIndex !== undefined) {\n if (!this._controllers.some(c => c.playerIndex === playerIndex)) return;\n this._controllers = this._controllers.filter(c => c.playerIndex !== playerIndex);\n this.logger.debug('Player left', { playerIndex });\n this._emitLifecycle('$controller-leave', playerIndex);\n }\n });\n\n this.registerHandler(SMORE_EVENTS.PLAYER_DISCONNECTED, (raw: unknown) => {\n const data = raw as { player?: Record<string, unknown>; playerIndex?: number };\n const playerData = data.player;\n const playerIndex = (playerData?.playerIndex as number | undefined) ?? data.playerIndex;\n if (playerIndex !== undefined) {\n // Update connected state in _controllers\n this._controllers = this._controllers.map(c =>\n c.playerIndex === playerIndex ? { ...c, connected: false } : c\n );\n this.logger.debug('Player disconnected', { playerIndex });\n this._emitLifecycle('$controller-disconnect', playerIndex);\n }\n });\n\n this.registerHandler(SMORE_EVENTS.PLAYER_RECONNECTED, (raw: unknown) => {\n const data = raw as { player?: Record<string, unknown>; playerIndex?: number };\n const playerData = data.player;\n const playerIndex = (playerData?.playerIndex as number | undefined) ?? data.playerIndex;\n if (playerIndex !== undefined) {\n // Build ControllerInfo to match Screen SDK behavior\n const controllerInfo = playerData\n ? mapPlayerDTO(playerData, playerIndex)\n : mapPlayerDTO({ playerIndex, connected: true }, playerIndex);\n // Update full ControllerInfo in _controllers (reconnect may carry updated data)\n this._controllers = this._controllers.map(c =>\n c.playerIndex === playerIndex ? controllerInfo : c\n );\n this.logger.debug('Player reconnected', { playerIndex });\n this._emitLifecycle('$controller-reconnect', playerIndex, controllerInfo);\n }\n });\n\n // Character updated: update appearance in _controllers\n // Server emits { player: player.toDTO(), room: room.toDTO() }\n this.registerHandler(SMORE_EVENTS.PLAYER_CHARACTER_UPDATED, (raw: unknown) => {\n const payload = raw as { player?: { playerIndex?: number; character?: Record<string, unknown> | null; name?: string; nickname?: string } };\n const playerData = payload?.player;\n if (playerData && typeof playerData.playerIndex === 'number') {\n const pi = playerData.playerIndex;\n const appearance = (playerData.character ?? null) as ControllerInfo['appearance'];\n this._controllers = this._controllers.map(c =>\n c.playerIndex === pi ? { ...c, appearance } : c\n );\n this.logger.debug('Player character updated', { playerIndex: pi });\n this._emitLifecycle('$character-updated', pi, appearance ?? null);\n }\n });\n\n // Rate limited: route through error handling\n this.registerHandler(SMORE_EVENTS.RATE_LIMITED, (raw: unknown) => {\n const data = raw as { event?: string };\n const eventName = data?.event ?? 'unknown';\n this.handleError(\n new SmoreSDKError('RATE_LIMITED', `Server rate-limited event: ${eventName}`, {\n details: { event: eventName },\n })\n );\n });\n\n // Game over: game has ended\n this.registerHandler(SMORE_EVENTS.GAME_OVER, (raw: unknown) => {\n const data = raw as { results?: GameResults };\n this.logger.lifecycle('Game over', data?.results);\n this._emitLifecycle('$game-over', data?.results);\n });\n\n // All ready: all participants have signaled ready\n this.registerHandler(SMORE_EVENTS.ALL_READY, () => {\n this.logger.lifecycle('All participants ready');\n this._allReadyFired = true;\n this._emitLifecycle('$all-ready');\n });\n\n // Self connection status\n this.registerHandler(SMORE_EVENTS.SELF_DISCONNECTED, () => {\n this._isConnected = false;\n this.logger.lifecycle('Connection lost');\n this._emitLifecycle('$connection-change', false);\n });\n\n this.registerHandler(SMORE_EVENTS.SELF_RECONNECTED, () => {\n this._isConnected = true;\n this.logger.lifecycle('Connection restored');\n this._emitLifecycle('$connection-change', true);\n });\n\n // Custom state changed: a controller's custom state was updated\n this.registerHandler(SMORE_EVENTS.STATE_CHANGED, (raw: unknown) => {\n const data = raw as { playerIndex?: number; state?: Record<string, any> };\n if (typeof data?.playerIndex === 'number' && data.state) {\n this._customStates.set(data.playerIndex, data.state);\n this._stateChangeListeners.forEach(cb => {\n try {\n cb(data.playerIndex!, data.state!);\n } catch (err) {\n this.handleError(\n new SmoreSDKError('UNKNOWN', 'Error in custom state change listener', {\n cause: err instanceof Error ? err : undefined,\n })\n );\n }\n });\n }\n });\n\n // All custom states: bulk state update (used for reconnection recovery)\n this.registerHandler(SMORE_EVENTS.STATE_ALL, (raw: unknown) => {\n const data = raw as { states?: Record<number, Record<string, any>> };\n if (data?.states) {\n for (const [key, value] of Object.entries(data.states)) {\n const pi = Number(key);\n this._customStates.set(pi, value);\n this._stateChangeListeners.forEach(cb => {\n try {\n cb(pi, value);\n } catch (err) {\n this.handleError(\n new SmoreSDKError('UNKNOWN', 'Error in custom state change listener', {\n cause: err instanceof Error ? err : undefined,\n })\n );\n }\n });\n }\n this._emitLifecycle('$state-recovery', data.states);\n }\n });\n }\n\n /**\n * Sets up a user event handler for controller events.\n * Used for registering pending handlers after transport becomes available.\n */\n private setupUserEventHandler(event: string, handler: ControllerEventHandler<unknown>): void {\n const transportHandler: TransportEventHandler = (data: unknown) => {\n this.logReceive(event, data);\n try {\n handler(data);\n } catch (err) {\n this.handleError(\n new SmoreSDKError('UNKNOWN', `Error in handler for event \"${event}\"`, {\n cause: err instanceof Error ? err : undefined,\n details: { event },\n })\n );\n }\n };\n\n if (this.transport) {\n this.transport.on(event, transportHandler);\n this.registeredHandlers.push({ event, handler: transportHandler });\n this.handlerToTransport.set(handler as Function, { event, transportHandler });\n }\n\n // Also store in eventListeners for on/off management\n let listeners = this.eventListeners.get(event);\n if (!listeners) {\n listeners = new Set();\n this.eventListeners.set(event, listeners);\n }\n listeners.add(handler);\n }\n\n private registerHandler(event: string, handler: TransportEventHandler): void {\n if (!this.transport) return;\n this.transport.on(event, handler);\n this.registeredHandlers.push({ event, handler });\n }\n\n // ---------------------------------------------------------------------------\n // Lifecycle Listener Helpers\n // ---------------------------------------------------------------------------\n\n private _addLifecycleListener(event: string, listener: Function): () => void {\n let set = this._lifecycleListeners.get(event);\n if (!set) {\n set = new Set();\n this._lifecycleListeners.set(event, set);\n }\n set.add(listener);\n return () => {\n set!.delete(listener);\n if (set!.size === 0) this._lifecycleListeners.delete(event);\n };\n }\n\n private _emitLifecycle(event: string, ...args: unknown[]): void {\n this._lifecycleListeners.get(event)?.forEach(cb => {\n try {\n (cb as Function)(...args);\n } catch (err) {\n this.handleError(\n new SmoreSDKError('UNKNOWN', `Error in lifecycle handler for \"${event}\"`, {\n cause: err instanceof Error ? err : undefined,\n details: { event },\n })\n );\n }\n });\n }\n\n private _hasLifecycleListeners(event: string): boolean {\n const set = this._lifecycleListeners.get(event);\n return set !== undefined && set.size > 0;\n }\n\n // ---------------------------------------------------------------------------\n // Lifecycle Methods\n // ---------------------------------------------------------------------------\n\n onAllReady(callback: () => void): () => void {\n if (this._allReadyFired) {\n callback();\n }\n return this._addLifecycleListener('$all-ready', callback);\n }\n\n onControllerJoin(callback: (playerIndex: PlayerIndex, info: ControllerInfo) => void): () => void {\n return this._addLifecycleListener('$controller-join', callback);\n }\n\n onControllerLeave(callback: (playerIndex: PlayerIndex) => void): () => void {\n return this._addLifecycleListener('$controller-leave', callback);\n }\n\n onControllerDisconnect(callback: (playerIndex: PlayerIndex) => void): () => void {\n return this._addLifecycleListener('$controller-disconnect', callback);\n }\n\n onControllerReconnect(callback: (playerIndex: PlayerIndex, info: ControllerInfo) => void): () => void {\n return this._addLifecycleListener('$controller-reconnect', callback);\n }\n\n onCharacterUpdated(callback: (playerIndex: PlayerIndex, appearance: CharacterAppearance | null) => void): () => void {\n return this._addLifecycleListener('$character-updated', callback);\n }\n\n onError(callback: (error: SmoreError) => void): () => void {\n return this._addLifecycleListener('$error', callback);\n }\n\n onConnectionChange(callback: (connected: boolean) => void): () => void {\n return this._addLifecycleListener('$connection-change', callback);\n }\n\n onGameOver(callback: (results?: GameResults) => void): () => void {\n return this._addLifecycleListener('$game-over', callback);\n }\n\n // ---------------------------------------------------------------------------\n // Custom State Methods\n // ---------------------------------------------------------------------------\n\n setState(state: Record<string, any>): void {\n const current = this._customStates.get(this._myPlayerIndex) ?? {};\n const merged = { ...current, ...state };\n this._customStates.set(this._myPlayerIndex, merged);\n if (this.transport) {\n this.transport.emit(SMORE_EVENTS.STATE_SET, { state });\n }\n }\n\n getMyState(): Record<string, any> | undefined {\n return this._customStates.get(this._myPlayerIndex);\n }\n\n onCustomStateChange(listener: (playerIndex: number, state: Record<string, any>) => void): () => void {\n this._stateChangeListeners.add(listener);\n return () => {\n this._stateChangeListeners.delete(listener);\n };\n }\n\n // ---------------------------------------------------------------------------\n // Communication Methods\n // ---------------------------------------------------------------------------\n\n /**\n * Send an event to the Screen. Controller-to-Controller direct communication\n * is not supported; all messages must go through the Screen.\n *\n * Data is sent to the Screen only (not to other controllers). For Screen->Controller communication,\n * Screen uses broadcast() or sendToController().\n *\n * @note Fire-and-forget sends (no callback) will silently fail if rate-limited.\n * Use the onError callback or smore:rate-limited event to detect rate limiting.\n */\n send<K extends EventNames<TEvents>>(event: K, data: EventData<TEvents, K>): void {\n if (this._isDestroyed) {\n throw new SmoreSDKError('DESTROYED', 'Cannot call send() after destroy()');\n }\n if (!this._isReady || !this.transport) {\n this._outboundBuffer.push({ method: 'send', args: [event, data] });\n this.logger.debug(`Buffered send \"${event}\" (controller not ready yet)`);\n return;\n }\n validateEventName(event);\n validatePayloadSize(data);\n\n if (typeof data !== 'object' || data === null) {\n this.logger.warn(\n 'Event data should be an object. Primitive values will be wrapped as { data: value } by the relay server. ' +\n 'To avoid confusion, wrap explicitly: send(\"event\", { value: 42 }) instead of send(\"event\", 42).'\n );\n }\n\n this.logSend(event, data);\n this.transport!.emit(event, data);\n }\n\n signalReady(): void {\n this.ensureReady('signalReady');\n this.logSend(SMORE_EVENTS.GAME_READY, {});\n this.transport!.emit(SMORE_EVENTS.GAME_READY, {});\n }\n\n // ---------------------------------------------------------------------------\n // Event Subscription\n // ---------------------------------------------------------------------------\n\n /**\n * Register a handler for custom events.\n *\n * Can be called before the Controller is ready. Handlers registered before ready\n * are queued and activated when the transport becomes available.\n *\n * When receiving events from Screen's `broadcast()`:\n * handler receives `(data)` -- no playerIndex included.\n *\n * When receiving events from Screen's `sendToController()`:\n * handler receives `(data)` -- targeted to this specific controller.\n */\n on<K extends EventNames<TEvents>>(\n event: K,\n handler: ControllerEventHandler<EventData<TEvents, K>>,\n ): () => void {\n // Route lifecycle events ($-prefixed)\n if (typeof event === 'string' && (event as string).startsWith('$')) {\n const validEvents = CONTROLLER_LIFECYCLE_EVENTS;\n if (!validEvents.has(event as string)) {\n throw new SmoreSDKError('INVALID_EVENT', `Unknown lifecycle event: \"${event}\". Valid lifecycle events: ${Array.from(validEvents).join(', ')}`);\n }\n // Special handling for $all-ready: fire immediately if already happened\n if (event === '$all-ready' && this._allReadyFired) {\n (handler as unknown as () => void)();\n }\n return this._addLifecycleListener(event as string, handler as Function);\n }\n\n validateEventName(event);\n\n // Add to local listeners map\n let listeners = this.eventListeners.get(event);\n if (!listeners) {\n listeners = new Set();\n this.eventListeners.set(event, listeners);\n }\n listeners.add(handler as ControllerEventHandler<unknown>);\n\n if (this.transport) {\n // Register with transport immediately\n const transportHandler: TransportEventHandler = (data: unknown) => {\n this.logReceive(event, data);\n try {\n (handler as ControllerEventHandler<unknown>)(data);\n } catch (err) {\n this.handleError(\n new SmoreSDKError('UNKNOWN', `Error in handler for event \"${event}\"`, {\n cause: err instanceof Error ? err : undefined,\n details: { event },\n })\n );\n }\n };\n\n this.transport.on(event, transportHandler);\n this.registeredHandlers.push({ event, handler: transportHandler });\n this.handlerToTransport.set(handler as Function, { event, transportHandler });\n } else {\n // Store for later registration when transport becomes available\n this._pendingHandlers.push({ event: event as string, handler: handler as ControllerEventHandler<unknown> });\n }\n\n // Return unsubscribe function\n return () => {\n listeners?.delete(handler as ControllerEventHandler<unknown>);\n if (listeners?.size === 0) {\n this.eventListeners.delete(event);\n }\n\n // Remove from pending if not yet registered\n this._pendingHandlers = this._pendingHandlers.filter(\n p => !(p.event === event && p.handler === handler)\n );\n\n // Remove from transport if registered\n const entry = this.handlerToTransport.get(handler as Function);\n if (entry) {\n this.transport?.off(event, entry.transportHandler);\n this.registeredHandlers = this.registeredHandlers.filter(\n (h) => h.handler !== entry.transportHandler,\n );\n this.handlerToTransport.delete(handler as Function);\n }\n };\n }\n\n /**\n * Add a one-time listener that auto-removes after first call.\n *\n * @note The handler is internally wrapped, so it cannot be removed via\n * `off(event, originalHandler)`. Use the returned unsubscribe function instead.\n */\n once<K extends EventNames<TEvents>>(\n event: K,\n handler: ControllerEventHandler<EventData<TEvents, K>>,\n ): () => void {\n if (typeof event === 'string' && (event as string).startsWith('$')) {\n const validEvents = CONTROLLER_LIFECYCLE_EVENTS;\n if (!validEvents.has(event as string)) {\n throw new SmoreSDKError('INVALID_EVENT', `Unknown lifecycle event: \"${event}\"`);\n }\n if (event === '$all-ready' && this._allReadyFired) {\n (handler as unknown as () => void)();\n return () => {};\n }\n const wrapper = (...args: unknown[]) => {\n unsub();\n (handler as Function)(...args);\n };\n const unsub = this._addLifecycleListener(event as string, wrapper);\n return unsub;\n }\n\n const unsubscribe = this.on(event, ((data: EventData<TEvents, K>) => {\n unsubscribe();\n handler(data);\n }) as ControllerEventHandler<EventData<TEvents, K>>);\n return unsubscribe;\n }\n\n off<K extends EventNames<TEvents>>(\n event: K,\n handler?: ControllerEventHandler<EventData<TEvents, K>>,\n ): void {\n if (typeof event === 'string' && (event as string).startsWith('$')) {\n if (!handler) {\n this._lifecycleListeners.delete(event as string);\n } else {\n this._lifecycleListeners.get(event as string)?.delete(handler as Function);\n }\n return;\n }\n\n if (!handler) {\n // Remove all handlers for this event\n this.eventListeners.delete(event);\n this.transport?.off(event);\n this.registeredHandlers = this.registeredHandlers.filter((h) => h.event !== event);\n for (const [key, val] of this.handlerToTransport) {\n if (val.event === event) this.handlerToTransport.delete(key);\n }\n // Remove from pending\n this._pendingHandlers = this._pendingHandlers.filter(p => p.event !== event);\n } else {\n // Remove specific handler\n const listeners = this.eventListeners.get(event);\n listeners?.delete(handler as ControllerEventHandler<unknown>);\n if (listeners?.size === 0) {\n this.eventListeners.delete(event);\n }\n // Remove specific transport handler via handlerToTransport map\n const entry = this.handlerToTransport.get(handler as Function);\n if (entry) {\n this.transport?.off(event, entry.transportHandler);\n this.registeredHandlers = this.registeredHandlers.filter(\n (h) => h.handler !== entry.transportHandler,\n );\n this.handlerToTransport.delete(handler as Function);\n }\n // Remove from pending\n this._pendingHandlers = this._pendingHandlers.filter(\n p => !(p.event === event && p.handler === handler)\n );\n }\n }\n\n removeAllListeners(event?: string): void {\n if (event) {\n // Remove all handlers for specific event\n this.eventListeners.delete(event);\n this.transport?.off(event);\n this.registeredHandlers = this.registeredHandlers.filter(h => h.event !== event);\n for (const [key, val] of this.handlerToTransport) {\n if (val.event === event) this.handlerToTransport.delete(key);\n }\n this._pendingHandlers = this._pendingHandlers.filter(p => p.event !== event);\n } else {\n // Remove all user event handlers\n for (const evt of [...this.eventListeners.keys()]) {\n this.removeAllListeners(evt);\n }\n }\n }\n\n // ---------------------------------------------------------------------------\n // Cleanup\n // ---------------------------------------------------------------------------\n\n destroy(): void {\n if (this._isDestroyed) return;\n\n this.logger.lifecycle('Destroying controller');\n this._isDestroyed = true;\n this._isReady = false;\n this.cleanup();\n }\n\n private cleanup(): void {\n // Clear init timeout if still pending\n if (this._initTimeoutId) {\n clearTimeout(this._initTimeoutId);\n this._initTimeoutId = null;\n }\n\n this._isReady = false;\n\n // Remove all registered handlers\n for (const { event, handler } of this.registeredHandlers) {\n this.transport?.off(event, handler);\n }\n this.registeredHandlers = [];\n\n // Clear event listeners\n this.eventListeners.clear();\n this.handlerToTransport.clear();\n this._pendingHandlers = [];\n\n // Clear lifecycle callbacks\n this._lifecycleListeners.clear();\n this._customStates.clear();\n this._stateChangeListeners.clear();\n this._isConnected = false;\n this._outboundBuffer = [];\n\n // Destroy transport\n if (this.transport) {\n this.transport.destroy();\n this.transport = null;\n }\n\n // Remove message listener\n if (this.boundMessageHandler) {\n window.removeEventListener('message', this.boundMessageHandler);\n this.boundMessageHandler = null;\n }\n }\n\n // ---------------------------------------------------------------------------\n // Private Helpers\n // ---------------------------------------------------------------------------\n\n private ensureReady(method: string): void {\n if (this._isDestroyed) {\n throw new SmoreSDKError(\n 'DESTROYED',\n `Cannot call ${method}() after destroy()`,\n { details: { method } },\n );\n }\n if (!this._isReady || !this.transport) {\n throw new SmoreSDKError(\n 'NOT_READY',\n `Cannot call ${method}() before controller is ready. ` +\n `Use await controller.ready.`,\n { details: { method, isReady: this._isReady } },\n );\n }\n }\n\n private handleError(error: SmoreSDKError): void {\n // Always log at warn level so errors are never completely silent\n this.logger.warn(`Error in handler: ${error.message}`);\n const smoreError = error.toSmoreError();\n if (this._hasLifecycleListeners('$error')) {\n this._emitLifecycle('$error', smoreError);\n } else {\n this.logger.error(error.message, error.details);\n }\n }\n\n private logSend(event: string, data?: unknown): void {\n this.logger.send(event, data);\n }\n\n private logReceive(event: string, data?: unknown): void {\n this.logger.receive(event, data);\n }\n}\n\n// =============================================================================\n// FACTORY FUNCTION\n// =============================================================================\n\n/**\n * Create a Controller instance for the player/phone side of your game.\n *\n * Returns a Controller instance synchronously. The controller begins listening\n * for the bridge init message immediately. Register event handlers and\n * lifecycle callbacks on the instance, then await `.ready` if needed.\n *\n * @template TEvents - Event map type for type-safe events\n * @param config - Controller configuration (debug, parentOrigin, timeout)\n * @returns Controller instance\n *\n * @example\n * ```ts\n * const controller = createController<MyEvents>({ debug: true });\n *\n * controller.on('phase-update', (data) => setPhase(data.phase));\n * controller.onAllReady(() => console.log('Ready!'));\n *\n * await controller.ready;\n * controller.send('tap', { x: 100, y: 200 });\n * ```\n */\nexport function createController<TEvents extends EventMap = EventMap>(\n config?: ControllerConfig,\n): Controller<TEvents> {\n return new ControllerImpl<TEvents>(config ?? {});\n}\n","/**\n * @smoregg/sdk - World-Class Party Game SDK\n *\n * Type definitions for building multiplayer party games with type-safe events,\n * factory pattern initialization, and comprehensive error handling.\n *\n * @packageDocumentation\n */\n\n// =============================================================================\n// CORE PRIMITIVES\n// =============================================================================\n\n/**\n * Unique identifier for a player (0-indexed integer).\n * Used consistently across all SDK methods.\n */\nexport type PlayerIndex = number;\n\n/**\n * Room code for joining a game session (e.g., \"ABCD\").\n */\nexport type RoomCode = string;\n\n// =============================================================================\n// EVENT SYSTEM - TYPE-SAFE EVENTS\n// =============================================================================\n\n/**\n * Base event map type. Extend this to define your game's events.\n *\n * **Important:** Event data values must be plain objects, not primitives.\n * Primitive values (string, number, boolean) will be automatically wrapped\n * as `{ data: <value> }` by the relay server, which breaks type safety.\n *\n * **Payload Size Limit:** Maximum payload size per event is 64KB. This limit\n * is enforced by the server's genericRelay handler. Payloads exceeding this\n * limit will be silently dropped by the server without error notification.\n *\n * **Reserved Fields:** The field names `playerIndex` and `targetPlayerIndex` are reserved\n * by the SDK for internal routing. Using these as custom data field names will cause\n * a compile-time error. The SDK automatically extracts `playerIndex` to identify the sender\n * and uses `targetPlayerIndex` for targeted message delivery.\n *\n * **Type Safety Note:** Without providing an explicit generic type parameter,\n * `createScreen()` and `createController()` default to the empty `EventMap`,\n * which means `send()`, `broadcast()`, and `on()` accept any string as an event\n * name and `unknown` as data -- effectively losing compile-time type checking.\n * Always define and pass your game's event map for full type safety.\n *\n * @example Defining events for type safety\n * ```ts\n * interface MyGameEvents {\n * // Screen receives from Controller\n * 'tap': { x: number; y: number };\n * 'answer': { choice: number };\n *\n * // Controller receives from Screen\n * 'phase-update': { phase: 'lobby' | 'playing' | 'results' };\n * 'your-turn': { timeLimit: number };\n * }\n *\n * // With explicit generic -- full type safety\n * const screen = createScreen<MyGameEvents>({ debug: true });\n * screen.on('tap', (playerIndex, data) => { ... });\n * await screen.ready;\n *\n * // Without generic -- no type safety (not recommended)\n * const screen = createScreen();\n * ```\n *\n * @example Event naming conventions\n * ```ts\n * // Define your game's event map for type safety:\n * type MyEvents = {\n * 'player-move': { x: number; y: number };\n * 'game-action': { action: string; value: number };\n * };\n * // Event names: use kebab-case, no colons (:), no 'smore:' prefix\n * ```\n */\nexport interface EventMap {\n [key: string]: Record<string, unknown> & { playerIndex?: never; targetPlayerIndex?: never };\n}\n\n/**\n * Extract event names from an event map.\n */\nexport type EventNames<TEvents extends EventMap> = keyof TEvents & string;\n\n/**\n * Extract event data type for a specific event.\n */\nexport type EventData<\n TEvents extends EventMap,\n TEvent extends EventNames<TEvents>,\n> = TEvents[TEvent];\n\n// =============================================================================\n// CONTROLLER INFO - PLAYER INFORMATION\n// =============================================================================\n\n/**\n * Character appearance data for player avatars.\n *\n * This type matches the server's CharacterDTO structure to ensure\n * type consistency across the platform.\n *\n * @property id - Unique character identifier\n * @property seed - Random seed for generating the character\n * @property style - Character style preset identifier\n * @property options - Additional character customization options\n */\nexport interface CharacterAppearance {\n /** Unique character identifier */\n id: string;\n /** Random seed for generating the character */\n seed: string;\n /** Character style preset identifier */\n style: string;\n /** Additional character customization options */\n options: Record<string, unknown>;\n}\n\n/**\n * Information about a connected controller (player).\n * Used by Screen to identify and manage players.\n */\nexport interface ControllerInfo {\n /** Player's unique index (0, 1, 2, ...) */\n readonly playerIndex: PlayerIndex;\n /**\n * Player's chosen display name.\n *\n * Maps to `PlayerDTO.name` on the server side. The SDK exposes it as\n * \"nickname\" for semantic clarity in game code.\n * The mapping (`name` -> `nickname`) is handled automatically during\n * player data deserialization in the transport layer.\n *\n * @see PlayerDTO.name (server) -- same value, different field name\n */\n readonly nickname: string;\n /** Whether the player is currently connected */\n readonly connected: boolean;\n /**\n * Optional character appearance data.\n *\n * Note: The server sends this as \"character\" in PlayerDTO.\n * The SDK maps it to \"appearance\" for semantic clarity.\n * The server may send `null` when no character is set.\n */\n readonly appearance?: CharacterAppearance | null;\n}\n\n// =============================================================================\n// TRANSPORT\n// =============================================================================\n\n/**\n * Transport interface for custom communication implementations.\n * Implement this to use a custom transport instead of the default PostMessageTransport.\n */\nexport interface Transport {\n emit(event: string, ...args: unknown[]): void;\n on(event: string, handler: (...args: unknown[]) => void): void;\n off(event: string, handler?: (...args: unknown[]) => void): void;\n destroy(): void;\n}\n\n// =============================================================================\n// ERROR HANDLING\n// =============================================================================\n\n/**\n * Error codes for SDK errors.\n */\nexport type SmoreErrorCode =\n | 'TIMEOUT' // Connection or operation timeout\n | 'NOT_READY' // Operation called before ready\n | 'DESTROYED' // Operation called after destroy\n | 'INVALID_EVENT' // Invalid event name\n | 'INVALID_PLAYER' // Invalid player index\n | 'CONNECTION_LOST' // Lost connection to server\n | 'INIT_FAILED' // Failed to initialize\n | 'RATE_LIMITED' // Server rate-limited an event\n | 'PAYLOAD_TOO_LARGE' // Payload exceeds 64KB limit\n | 'UNKNOWN'; // Unknown error\n\n/**\n * Structured error type for SDK errors.\n */\nexport interface SmoreError {\n /** Error code for programmatic handling */\n code: SmoreErrorCode;\n /** Human-readable error message */\n message: string;\n /** Original error if available */\n cause?: Error;\n /** Additional context */\n details?: Record<string, unknown>;\n}\n\n// =============================================================================\n// GAME RESULTS\n// =============================================================================\n\n/**\n * Game results structure for gameOver().\n * Flexible to accommodate different game types.\n */\nexport interface GameResults {\n /** Player scores indexed by player index */\n scores?: Record<PlayerIndex, number>;\n /** Winner's player index (or -1 for no winner/tie) */\n winner?: PlayerIndex;\n /** Ranked player indices from first to last */\n rankings?: PlayerIndex[];\n /** Additional custom game-specific data */\n custom?: Record<string, unknown>;\n}\n\n// =============================================================================\n// LIFECYCLE EVENTS — UNIFIED EVENT SYSTEM\n// =============================================================================\n\n/**\n * Lifecycle event names for subscribing via `on()`.\n *\n * These `$`-prefixed event names allow lifecycle events to be registered\n * through the same `on()` method used for game events. The `$` prefix is\n * reserved by the SDK and cannot be used for user-defined events.\n *\n * @example\n * ```ts\n * // These are equivalent:\n * screen.onControllerJoin((pi, info) => { ... });\n * screen.on(LifecycleEvent.CONTROLLER_JOIN, (pi, info) => { ... });\n * ```\n */\nexport const LifecycleEvent = {\n ALL_READY: '$all-ready',\n CONTROLLER_JOIN: '$controller-join',\n CONTROLLER_LEAVE: '$controller-leave',\n CONTROLLER_DISCONNECT: '$controller-disconnect',\n CONTROLLER_RECONNECT: '$controller-reconnect',\n CHARACTER_UPDATED: '$character-updated',\n ERROR: '$error',\n GAME_OVER: '$game-over',\n CONNECTION_CHANGE: '$connection-change',\n} as const;\n\n/** Union of all lifecycle event name strings. */\nexport type LifecycleEventName = typeof LifecycleEvent[keyof typeof LifecycleEvent];\n\n/**\n * Handler signatures for Screen lifecycle events.\n * Used by `on()` overloads to provide type-safe lifecycle event subscription.\n */\nexport interface ScreenLifecycleHandlers {\n '$all-ready': () => void;\n '$controller-join': (playerIndex: PlayerIndex, info: ControllerInfo) => void;\n '$controller-leave': (playerIndex: PlayerIndex) => void;\n '$controller-disconnect': (playerIndex: PlayerIndex) => void;\n '$controller-reconnect': (playerIndex: PlayerIndex, info: ControllerInfo) => void;\n '$character-updated': (playerIndex: PlayerIndex, appearance: CharacterAppearance | null) => void;\n '$error': (error: SmoreError) => void;\n '$connection-change': (connected: boolean) => void;\n}\n\n/** Screen lifecycle event name union. */\nexport type ScreenLifecycleEvent = keyof ScreenLifecycleHandlers;\n\n/**\n * Handler signatures for Controller lifecycle events.\n * Extends Screen lifecycle events with Controller-specific events.\n */\nexport interface ControllerLifecycleHandlers extends ScreenLifecycleHandlers {\n '$game-over': (results?: GameResults) => void;\n '$state-recovery': (states: Record<number, Record<string, any>>) => void;\n}\n\n/** Controller lifecycle event name union. */\nexport type ControllerLifecycleEvent = keyof ControllerLifecycleHandlers;\n\n// =============================================================================\n// SCREEN TYPES - HOST/TV SIDE\n// =============================================================================\n\n/**\n * Handler for events received from controllers.\n * Receives the player index and event data.\n */\nexport type ScreenEventHandler<TData = unknown> = (\n playerIndex: PlayerIndex,\n data: TData,\n) => void;\n\n/**\n * Configuration options for creating a Screen instance.\n *\n * In the event emitter pattern, only static options are passed via config.\n * All lifecycle callbacks and event listeners are registered via methods\n * on the returned Screen instance.\n *\n * @template TEvents - Event map type for type-safe events\n *\n * @example\n * ```ts\n * const screen = createScreen<MyEvents>({ debug: true });\n *\n * screen.on('tap', (playerIndex, data) => handleTap(playerIndex, data));\n * screen.onAllReady(() => startCountdown());\n * screen.onControllerJoin((playerIndex, info) => console.log('Joined:', playerIndex));\n *\n * await screen.ready;\n * ```\n */\nexport interface ScreenConfig {\n // === Debug Options ===\n\n /**\n * Enable debug mode for verbose logging.\n * @default false\n */\n debug?: boolean | DebugOptions;\n\n // === Advanced Options ===\n\n /**\n * Parent window origin for postMessage validation (iframe games).\n * Use '*' to accept messages from any origin (not recommended for production).\n * @default '*'\n */\n parentOrigin?: string;\n\n /**\n * Connection timeout in milliseconds.\n * @default 10000\n */\n timeout?: number;\n\n /**\n * Automatically signal ready after initialization.\n * When true (default), the SDK calls signalReady() automatically after init completes.\n * Set to false if your game needs to load resources before signaling ready.\n * @default true\n */\n autoReady?: boolean;\n\n /**\n * Custom transport implementation.\n * If provided, uses this instead of the default PostMessageTransport.\n * The bridge handshake (_bridge:init) still occurs via postMessage.\n */\n transport?: Transport;\n\n}\n\n/**\n * Screen instance - the main interface for the host/TV side of your game.\n *\n * Uses an event emitter pattern: lifecycle callbacks and event listeners\n * are registered via methods on the instance, not via config.\n *\n * @template TEvents - Event map type for type-safe events\n *\n * @example\n * ```ts\n * const screen = createScreen<MyEvents>({ debug: true });\n *\n * screen.on('tap', (playerIndex, data) => handleTap(playerIndex, data));\n * screen.onAllReady(() => startGame());\n * screen.onControllerJoin((playerIndex, info) => addPlayer(playerIndex, info));\n *\n * await screen.ready;\n * screen.broadcast('phase-update', { phase: 'playing' });\n * screen.gameOver({ scores: { 0: 100, 1: 75 } });\n * ```\n */\nexport interface Screen<TEvents extends EventMap = EventMap> {\n // === Properties (readonly) ===\n\n /**\n * All connected controllers. Returns a new shallow copy on every access.\n *\n * **Performance note:** Each access creates a new array via spread.\n * Avoid calling this in tight loops; cache the result in a local variable\n * if you need to access it repeatedly within the same frame/tick.\n */\n readonly controllers: readonly ControllerInfo[];\n\n /** The room code for this game session. */\n readonly roomCode: RoomCode;\n\n /** Whether the screen is initialized and ready. */\n readonly isReady: boolean;\n\n /** Whether the screen has been destroyed. */\n readonly isDestroyed: boolean;\n\n /** Whether the connection to the server is active. */\n readonly isConnected: boolean;\n\n /** Protocol version negotiated with the parent frame. */\n readonly protocolVersion: number;\n\n /**\n * A Promise that resolves when the screen is initialized and ready.\n * Use this to await readiness after creating a screen synchronously.\n *\n * @example\n * ```ts\n * const screen = createScreen<MyEvents>();\n * screen.on('tap', handler);\n * await screen.ready;\n * screen.broadcast('start', {});\n * ```\n */\n readonly ready: Promise<void>;\n\n // === Lifecycle Methods ===\n\n /**\n * Register a callback for when all participants are ready (all-ready event).\n * If the all-ready event has already fired when called, the callback fires immediately.\n *\n * @param callback - Called when all participants signal ready\n * @returns Unsubscribe function to remove the callback\n */\n onAllReady(callback: () => void): () => void;\n\n /**\n * Register a callback for when a controller (player) joins the room.\n *\n * @param callback - Called with player index and controller info\n * @returns Unsubscribe function to remove the callback\n */\n onControllerJoin(callback: (playerIndex: PlayerIndex, info: ControllerInfo) => void): () => void;\n\n /**\n * Register a callback for when a controller (player) leaves the room.\n *\n * @param callback - Called with the leaving player's index\n * @returns Unsubscribe function to remove the callback\n */\n onControllerLeave(callback: (playerIndex: PlayerIndex) => void): () => void;\n\n /**\n * Register a callback for when a controller temporarily disconnects.\n *\n * @param callback - Called with the disconnected player's index\n * @returns Unsubscribe function to remove the callback\n */\n onControllerDisconnect(callback: (playerIndex: PlayerIndex) => void): () => void;\n\n /**\n * Register a callback for when a controller reconnects after a disconnect.\n *\n * @param callback - Called with player index and updated controller info\n * @returns Unsubscribe function to remove the callback\n */\n onControllerReconnect(callback: (playerIndex: PlayerIndex, info: ControllerInfo) => void): () => void;\n\n /**\n * Register a callback for when a player's character appearance is updated.\n *\n * @param callback - Called with player index and new appearance (or null if reset)\n * @returns Unsubscribe function to remove the callback\n */\n onCharacterUpdated(callback: (playerIndex: PlayerIndex, appearance: CharacterAppearance | null) => void): () => void;\n\n /**\n * Register a callback for when an error occurs.\n * If no error callback is registered, errors are logged to console in debug mode.\n *\n * @param callback - Called with the error object\n * @returns Unsubscribe function to remove the callback\n */\n onError(callback: (error: SmoreError) => void): () => void;\n\n /**\n * Register a callback for when the connection status changes.\n * Called when the connection to the server is lost or restored.\n *\n * @param callback - Called with true (connected) or false (disconnected)\n * @returns Unsubscribe function to remove the callback\n */\n onConnectionChange(callback: (connected: boolean) => void): () => void;\n\n // === Communication Methods ===\n\n /**\n * Broadcast an event to all connected controllers.\n *\n * @param event - Event name (must match TEvents keys)\n * @param data - Event data (type-safe based on event name)\n * @note Data should be an object. Primitive values will be wrapped as `{ data: value }` by the relay server.\n * @note Maximum payload size is 64KB. Payloads exceeding this limit will be silently dropped by the server.\n *\n * @example\n * ```ts\n * screen.broadcast('phase-update', { phase: 'playing' });\n * ```\n */\n broadcast<K extends EventNames<TEvents>>(\n event: K,\n data: EventData<TEvents, K>,\n ): void;\n\n /**\n * Send an event to a specific controller.\n *\n * Screen -> Controller direction only. For Controller -> Screen, see `send()`.\n *\n * @param playerIndex - Target controller's player index\n * @param event - Event name (must match TEvents keys)\n * @param data - Event data (type-safe based on event name)\n * @note Data should be an object. Primitive values will be wrapped as `{ data: value }` by the relay server.\n * @note Maximum payload size is 64KB. Payloads exceeding this limit will be silently dropped by the server.\n *\n * @example\n * ```ts\n * screen.sendToController(0, 'your-turn', { timeLimit: 30 });\n * ```\n */\n sendToController<K extends EventNames<TEvents>>(\n playerIndex: PlayerIndex,\n event: K,\n data: EventData<TEvents, K>,\n ): void;\n\n // === Custom State Methods ===\n\n /**\n * Get a specific controller's cached custom state.\n * Returns undefined if no state has been set for this controller.\n *\n * @param playerIndex - The controller's player index\n */\n getControllerState(playerIndex: number): Record<string, any> | undefined;\n\n /**\n * Get all controllers' cached custom states.\n * Returns a record mapping player index to state.\n */\n getAllControllerStates(): Record<number, Record<string, any>>;\n\n /**\n * Register a listener for custom state changes from any controller.\n *\n * @param listener - Called with the player index and the new state\n * @returns Unsubscribe function\n */\n onCustomStateChange(listener: (playerIndex: number, state: Record<string, any>) => void): () => void;\n\n // === Game Lifecycle ===\n\n /**\n * Signal that the game is over and send results.\n * This will broadcast a game-over event to all controllers.\n *\n * @param results - Game results (scores, rankings, etc.)\n *\n * @example\n * ```ts\n * screen.gameOver({\n * scores: { 0: 100, 1: 75, 2: 50 },\n * winner: 0,\n * rankings: [0, 1, 2],\n * });\n * ```\n */\n gameOver(results?: GameResults): void;\n\n /**\n * Signal that this screen has finished loading resources and is ready to start.\n *\n * Call this after all game resources (Phaser assets, images, sounds, etc.) are loaded.\n * The server will wait until all participants (screen + all connected controllers)\n * have signaled ready, then broadcast an all-ready event to everyone.\n *\n * @example\n * ```ts\n * // After Phaser scene loads all assets:\n * screen.signalReady();\n * ```\n */\n signalReady(): void;\n\n // === Event Subscription ===\n\n /**\n * Subscribe to a lifecycle event or a user-defined game event.\n *\n * Lifecycle events use `$`-prefixed names. Use `LifecycleEvent` constants\n * for type-safe subscription:\n * ```ts\n * screen.on(LifecycleEvent.CONTROLLER_JOIN, (pi, info) => { ... });\n * screen.on('tap', (pi, data) => { ... }); // user event\n * ```\n */\n on<K extends ScreenLifecycleEvent>(event: K, handler: ScreenLifecycleHandlers[K]): () => void;\n /**\n * Add a listener for a specific event after construction.\n * Can be called before the screen is ready -- handlers are queued\n * and activated when the transport becomes available.\n *\n * @param event - Event name\n * @param handler - Handler function (playerIndex, data) => void\n * @returns Cleanup function to remove the listener\n *\n * @example\n * ```ts\n * const unsubscribe = screen.on('tap', (playerIndex, data) => {\n * console.log(`Player ${playerIndex} tapped at`, data.x, data.y);\n * });\n *\n * // Later: remove listener\n * unsubscribe();\n * ```\n */\n on<K extends EventNames<TEvents>>(\n event: K,\n handler: ScreenEventHandler<EventData<TEvents, K>>,\n ): () => void;\n\n once<K extends ScreenLifecycleEvent>(event: K, handler: ScreenLifecycleHandlers[K]): () => void;\n /**\n * Add a one-time listener that auto-removes after first call.\n *\n * @note The handler is internally wrapped, so it cannot be removed via\n * `off(event, originalHandler)`. Use the returned unsubscribe function instead.\n */\n once<K extends EventNames<TEvents>>(\n event: K,\n handler: ScreenEventHandler<EventData<TEvents, K>>,\n ): () => void;\n\n off<K extends ScreenLifecycleEvent>(event: K, handler?: ScreenLifecycleHandlers[K]): void;\n /**\n * Remove a specific listener or all listeners for an event.\n */\n off<K extends EventNames<TEvents>>(\n event: K,\n handler?: ScreenEventHandler<EventData<TEvents, K>>,\n ): void;\n\n /**\n * Remove all event listeners, or all listeners for a specific event.\n * Only removes user event listeners registered via on()/once().\n * Lifecycle callbacks (onControllerJoin, onAllReady, etc.) are not affected.\n *\n * @param event - Optional event name. If omitted, removes ALL user event listeners.\n */\n removeAllListeners(event?: string): void;\n\n // === Utilities ===\n\n /**\n * Get a specific controller by player index.\n * Returns undefined if not found.\n */\n getController(playerIndex: PlayerIndex): ControllerInfo | undefined;\n\n /**\n * Get the number of connected controllers.\n */\n getControllerCount(): number;\n\n // === Cleanup ===\n\n /**\n * Clean up all resources and disconnect.\n * Call this when unmounting/destroying your game.\n */\n destroy(): void;\n}\n\n// =============================================================================\n// CONTROLLER TYPES - PLAYER/PHONE SIDE\n// =============================================================================\n\n/**\n * Handler for events received from the screen.\n * Receives only the event data (no player index needed).\n */\nexport type ControllerEventHandler<TData = unknown> = (data: TData) => void;\n\n/**\n * Configuration options for creating a Controller instance.\n *\n * In the event emitter pattern, only static options are passed via config.\n * All lifecycle callbacks and event listeners are registered via methods\n * on the returned Controller instance.\n *\n * @template TEvents - Event map type for type-safe events\n *\n * @example\n * ```ts\n * const controller = createController<MyEvents>({ debug: true });\n *\n * controller.on('phase-update', (data) => handlePhase(data.phase));\n * controller.onAllReady(() => console.log('Ready!'));\n *\n * await controller.ready;\n * controller.send('tap', { x: 100, y: 200 });\n * ```\n */\nexport interface ControllerConfig {\n // === Debug Options ===\n\n /**\n * Enable debug mode for verbose logging.\n * @default false\n */\n debug?: boolean | DebugOptions;\n\n // === Advanced Options ===\n\n /**\n * Parent window origin for postMessage validation (iframe games).\n * @default '*'\n */\n parentOrigin?: string;\n\n /**\n * Connection timeout in milliseconds.\n * @default 10000\n */\n timeout?: number;\n\n /**\n * Automatically signal ready after initialization.\n * When true (default), the SDK calls signalReady() automatically after init completes.\n * Set to false if your game needs to load resources before signaling ready.\n * @default true\n */\n autoReady?: boolean;\n\n /**\n * Custom transport implementation.\n * If provided, uses this instead of the default PostMessageTransport.\n * The bridge handshake (_bridge:init) still occurs via postMessage.\n */\n transport?: Transport;\n\n}\n\n/**\n * Controller instance - the main interface for the player/phone side.\n *\n * Uses an event emitter pattern: lifecycle callbacks and event listeners\n * are registered via methods on the instance, not via config.\n *\n * @template TEvents - Event map type for type-safe events\n *\n * @example\n * ```ts\n * const controller = createController<MyEvents>({ debug: true });\n *\n * controller.on('phase-update', (data) => setPhase(data.phase));\n * controller.onAllReady(() => console.log('Game starting!'));\n *\n * await controller.ready;\n * controller.send('tap', { x: 100, y: 200 });\n * ```\n *\n * ## Controller API Design Note:\n *\n * Controller only has `send()` (no `broadcast()` or `gameOver()`).\n * This is intentional: Controller-to-Controller (C2C) communication is not supported.\n * All coordination between controllers must go through the Screen.\n *\n * Flow: Controller.send() -> Screen receives -> Screen.broadcast() or Screen.sendToController()\n */\nexport interface Controller<TEvents extends EventMap = EventMap> {\n // === Properties (readonly) ===\n\n /** My player index (0, 1, 2, ...). */\n readonly myPlayerIndex: PlayerIndex;\n\n /** My own controller info. undefined before initialization. */\n readonly me: ControllerInfo | undefined;\n\n /** The room code for this game session. */\n readonly roomCode: RoomCode;\n\n /** Whether the controller is initialized and ready. */\n readonly isReady: boolean;\n\n /** Whether the controller has been destroyed. */\n readonly isDestroyed: boolean;\n\n /** Whether the connection to the server is active. */\n readonly isConnected: boolean;\n\n /** Protocol version negotiated with the parent frame. */\n readonly protocolVersion: number;\n\n /**\n * Read-only list of all known controllers (players) in the room.\n * Returns full ControllerInfo including playerIndex, nickname, connected status, and appearance.\n * Consistent with Screen's `controllers` property.\n *\n * **Performance note:** Each access creates a new shallow copy array.\n * Cache the result in a local variable if you need to access it repeatedly.\n */\n readonly controllers: readonly ControllerInfo[];\n\n /**\n * A Promise that resolves when the controller is initialized and ready.\n * Use this to await readiness after creating a controller synchronously.\n *\n * @example\n * ```ts\n * const controller = createController<MyEvents>();\n * controller.on('phase-update', handler);\n * await controller.ready;\n * controller.send('tap', { x: 0, y: 0 });\n * ```\n */\n readonly ready: Promise<void>;\n\n // === Lifecycle Methods ===\n\n /**\n * Register a callback for when all participants are ready (all-ready event).\n * If the all-ready event has already fired when called, the callback fires immediately.\n *\n * @param callback - Called when all participants signal ready\n * @returns Unsubscribe function to remove the callback\n */\n onAllReady(callback: () => void): () => void;\n\n /**\n * Register a callback for when another player joins the room.\n *\n * @param callback - Called with player index and controller info\n * @returns Unsubscribe function to remove the callback\n */\n onControllerJoin(callback: (playerIndex: PlayerIndex, info: ControllerInfo) => void): () => void;\n\n /**\n * Register a callback for when another player leaves the room.\n *\n * @param callback - Called with the leaving player's index\n * @returns Unsubscribe function to remove the callback\n */\n onControllerLeave(callback: (playerIndex: PlayerIndex) => void): () => void;\n\n /**\n * Register a callback for when another player temporarily disconnects.\n *\n * @param callback - Called with the disconnected player's index\n * @returns Unsubscribe function to remove the callback\n */\n onControllerDisconnect(callback: (playerIndex: PlayerIndex) => void): () => void;\n\n /**\n * Register a callback for when another player reconnects after a disconnect.\n *\n * @param callback - Called with player index and updated controller info\n * @returns Unsubscribe function to remove the callback\n */\n onControllerReconnect(callback: (playerIndex: PlayerIndex, info: ControllerInfo) => void): () => void;\n\n /**\n * Register a callback for when a player's character appearance is updated.\n *\n * @param callback - Called with player index and new appearance (or null if reset)\n * @returns Unsubscribe function to remove the callback\n */\n onCharacterUpdated(callback: (playerIndex: PlayerIndex, appearance: CharacterAppearance | null) => void): () => void;\n\n /**\n * Register a callback for when an error occurs.\n * If no error callback is registered, errors are logged to console in debug mode.\n *\n * @param callback - Called with the error object\n * @returns Unsubscribe function to remove the callback\n */\n onError(callback: (error: SmoreError) => void): () => void;\n\n /**\n * Register a callback for when the game ends.\n * Called when the Screen calls gameOver().\n *\n * @param callback - Called with optional game results\n * @returns Unsubscribe function to remove the callback\n */\n onGameOver(callback: (results?: GameResults) => void): () => void;\n\n /**\n * Register a callback for when the connection status changes.\n * Called when the connection to the server is lost or restored.\n *\n * @param callback - Called with true (connected) or false (disconnected)\n * @returns Unsubscribe function to remove the callback\n */\n onConnectionChange(callback: (connected: boolean) => void): () => void;\n\n /**\n * Returns the number of currently connected players.\n */\n getControllerCount(): number;\n\n /**\n * Get a specific controller by player index.\n * Returns undefined if not found.\n */\n getController(playerIndex: PlayerIndex): ControllerInfo | undefined;\n\n // === Custom State Methods ===\n\n /**\n * Set custom state for this controller. State is merged with existing state on the server.\n * State persists only for the duration of the game session.\n *\n * @param state - Key-value state to merge\n */\n setState(state: Record<string, any>): void;\n\n /**\n * Get this controller's cached custom state.\n * Returns undefined if no state has been set.\n */\n getMyState(): Record<string, any> | undefined;\n\n /**\n * Register a listener for custom state changes from any controller.\n *\n * @param listener - Called with the player index and the new state\n * @returns Unsubscribe function\n */\n onCustomStateChange(listener: (playerIndex: number, state: Record<string, any>) => void): () => void;\n\n // === Communication Methods ===\n\n /**\n * Send an event to the screen.\n *\n * Controller -> Screen direction only. For Screen -> Controller, see `sendToController()`.\n *\n * @param event - Event name (must match TEvents keys)\n * @param data - Event data (type-safe based on event name)\n * @note Maximum payload size is 64KB. Payloads exceeding this limit will be silently dropped by the server.\n *\n * @example\n * ```ts\n * controller.send('tap', { x: 100, y: 200 });\n * controller.send('answer', { choice: 2 });\n * ```\n */\n send<K extends EventNames<TEvents>>(\n event: K,\n data: EventData<TEvents, K>,\n ): void;\n\n /**\n * Signal that this controller has finished loading resources and is ready to start.\n *\n * Call this after all game resources are loaded.\n * The server will wait until all participants have signaled ready,\n * then broadcast an all-ready event to everyone.\n *\n * @example\n * ```ts\n * // After loading completes:\n * controller.signalReady();\n * ```\n */\n signalReady(): void;\n\n // === Event Subscription ===\n\n /**\n * Subscribe to a lifecycle event or a user-defined game event.\n *\n * Lifecycle events use `$`-prefixed names. Use `LifecycleEvent` constants\n * for type-safe subscription:\n * ```ts\n * controller.on(LifecycleEvent.CONTROLLER_JOIN, (pi, info) => { ... });\n * controller.on('phase-update', (data) => { ... }); // user event\n * ```\n */\n on<K extends ControllerLifecycleEvent>(event: K, handler: ControllerLifecycleHandlers[K]): () => void;\n /**\n * Add a listener for a specific event after construction.\n * Can be called before the controller is ready -- handlers are queued\n * and activated when the transport becomes available.\n *\n * @param event - Event name\n * @param handler - Handler function (data) => void\n * @returns Cleanup function to remove the listener\n *\n * @note Events from screen.broadcast() do not include playerIndex.\n * The handler signature is `(data: D)` without playerIndex context.\n * If you need to know which player triggered the broadcast, include\n * that information in the data object from the Screen side.\n *\n * @example\n * ```ts\n * const unsubscribe = controller.on('phase-update', (data) => {\n * console.log('New phase:', data.phase);\n * });\n *\n * // Later: remove listener\n * unsubscribe();\n * ```\n */\n on<K extends EventNames<TEvents>>(\n event: K,\n handler: ControllerEventHandler<EventData<TEvents, K>>,\n ): () => void;\n\n once<K extends ControllerLifecycleEvent>(event: K, handler: ControllerLifecycleHandlers[K]): () => void;\n /**\n * Add a one-time listener that auto-removes after first call.\n *\n * @note The handler is internally wrapped, so it cannot be removed via\n * `off(event, originalHandler)`. Use the returned unsubscribe function instead.\n */\n once<K extends EventNames<TEvents>>(\n event: K,\n handler: ControllerEventHandler<EventData<TEvents, K>>,\n ): () => void;\n\n off<K extends ControllerLifecycleEvent>(event: K, handler?: ControllerLifecycleHandlers[K]): void;\n /**\n * Remove a specific listener or all listeners for an event.\n */\n off<K extends EventNames<TEvents>>(\n event: K,\n handler?: ControllerEventHandler<EventData<TEvents, K>>,\n ): void;\n\n /**\n * Remove all event listeners, or all listeners for a specific event.\n * Only removes user event listeners registered via on()/once().\n * Lifecycle callbacks (onControllerJoin, onAllReady, etc.) are not affected.\n *\n * @param event - Optional event name. If omitted, removes ALL user event listeners.\n */\n removeAllListeners(event?: string): void;\n\n // === Cleanup ===\n\n /**\n * Clean up all resources and disconnect.\n * Call this when unmounting/destroying your game.\n */\n destroy(): void;\n}\n\n// =============================================================================\n// DEBUG OPTIONS\n// =============================================================================\n\n/**\n * Log levels for debug output.\n */\nexport type LogLevel = 'debug' | 'info' | 'warn' | 'error';\n\n/**\n * Debug configuration options.\n */\nexport interface DebugOptions {\n /** Enable debug logging */\n enabled?: boolean;\n\n /** Minimum log level to output */\n level?: LogLevel;\n\n /** Prefix for log messages */\n prefix?: string;\n\n /** Log events being sent */\n logSend?: boolean;\n\n /** Log events being received */\n logReceive?: boolean;\n\n /** Log lifecycle events (ready, destroy, etc.) */\n logLifecycle?: boolean;\n\n /** Custom logger function */\n logger?: (level: LogLevel, message: string, data?: unknown) => void;\n}\n"],"names":["DEFAULT_TIMEOUT"],"mappings":"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"}