import type { GameContext } from "./gameContext.js"; import type { InputFrame } from "./hostedGameRunner.js"; import type { HostedWorldSession } from "./hostedWorldSession.js"; import { type WorldDiff } from "./worldReplication.js"; import type { WorldSnapshot } from "./worldSnapshot.js"; /** Host→client frame: the full baseline a joiner needs, then per-tick diffs. What a transport marshals downstream. */ export type WorldServerFrame = { t: "baseline"; revision: number; snapshot: WorldSnapshot; } | { t: "diff"; diff: WorldDiff; }; /** Client→host frame: a player's session verbs. What a transport marshals upstream. */ export type WorldClientFrame = { t: "join"; isNew: boolean; } | { t: "leave"; } | { t: "command"; name: string; input: unknown; } | { t: "input"; frame: InputFrame; }; /** One client's link on the host side: routes its upstream frames into the shared session, pushes it sync frames. */ export interface WorldHostConnection { receive(frame: WorldClientFrame): void; push(): void; close(): void; } /** * The transport-agnostic host: fans one {@link HostedWorldSession} out to many connections, each tracking its own * revision cursor so a joiner gets a baseline and everyone else gets diffs. A ws server, a Convex function, or an * in-process loopback all drive the same shape — decode a frame → `connection.receive`; after `session.tick` → * `broadcast`. No wire format is assumed; frames are plain data a transport serializes however it likes. */ export interface WorldHost { connect(userId: string, send: (frame: WorldServerFrame) => void): WorldHostConnection; broadcast(): void; session(): HostedWorldSession; } /** Build a {@link WorldHost} fanning one {@link HostedWorldSession} out to many cursor-tracked connections. * @internal */ export declare function createWorldHost(session: HostedWorldSession): WorldHost; /** The client end of a {@link WorldHost} connection: applies server frames to a local `ctx`, sends session verbs upstream. */ export interface WorldClientLink { receive(frame: WorldServerFrame): void; join(isNew: boolean): void; leave(): void; command(name: string, input: unknown): void; input(frame: InputFrame): void; revision(): number; } /** Build a {@link WorldClientLink} — the client end that mirrors host frames into `ctx` and sends session verbs upstream. * @internal */ export declare function createWorldClientLink(ctx: Pick, send: (frame: WorldClientFrame) => void): WorldClientLink;