/** * Parent-frame multiplayer router for embedded apps. * * Decides how to handle a child iframe's multiplayer message: * - Remote active: forward via parent's MSM → adapter sends to server * - Offline/demo: apply against localStorage and echo the server-style response * * For a full overview of how embedded parent helpers compose together, * see `createEmbeddedHost` in `embeddedHost.ts`. */ import { NoyaManager } from "../NoyaManager"; import { ClientToServerMessage } from "../multiplayer"; import { ParentToEmbeddedMessage } from "./parentFrameMessages"; import { applyServerMessage } from "./syncUtils"; import { processLocalStorageMessage } from "./localStorageServer"; export type RouteEmbeddedMultiplayerOptions = { /** * When true, forwards through the active sync adapter (e.g., websocket). * When false, falls back to localStorage processing. */ isRemoteActive: boolean; /** * Optional remote sender used to forward child messages directly to the server. * Required when isRemoteActive=true. */ sendRemoteMessage?: (message: ClientToServerMessage) => void; /** * Local storage key for demo/offline mode. Required when isRemoteActive=false. */ localStorageKey?: string; /** * Sends a message from parent to child frame. */ sendToChild: (message: ParentToEmbeddedMessage) => void; }; /** * Route a child "multiplayer.message" to either the active sync adapter * (remote) or to localStorage (demo/offline), and forward any server-to-client * responses to the child. */ export async function routeEmbeddedMultiplayerMessage< S, M extends object, E extends object, MenuT extends string, I extends Record = Record, >( noyaManager: NoyaManager, payload: ClientToServerMessage, { isRemoteActive, sendRemoteMessage, localStorageKey, sendToChild, }: RouteEmbeddedMultiplayerOptions ) { if (isRemoteActive) { if (!sendRemoteMessage) { console.warn( "[routeEmbeddedMultiplayerMessage] Remote active but no sendRemoteMessage provided" ); return; } sendRemoteMessage(payload); return; } if (!localStorageKey) return; const response = await processLocalStorageMessage(localStorageKey, payload); if (response) { applyServerMessage(response, noyaManager); sendToChild(response); } }