import type { GamePayload } from '@game-hub/kernel/client'; export interface TransportOptions { /** * Prefix for every platform API path — `''` when the backend serves the UI, `'/api'` behind a dev * proxy. No trailing slash; paths passed to `apiUrl` start with `/`. */ readonly baseUrl: string; } /** * Point the game-facing REST helpers at this host's API. **The host calls this once at boot**, before * anything renders (`ui/src/main.tsx`); a game package must never call it. */ export declare function configureTransport({ baseUrl }: TransportOptions): void; /** Absolute-from-origin URL for a platform API path (`/games/:id/…`), honouring the configured base. */ export declare function apiUrl(path: string): string; /** The one header every JSON POST here sends. Exported so a game's own routes stay consistent. */ export declare const JSON_HEADERS: { 'content-type': string; }; /** Throw an Error carrying the server's message (used for any non-2xx response). */ export declare function fail(response: Response): Promise; /** * Turn a state-returning response into a `GamePayload`, defaulting the fields a lean server reply may * omit. The server sends a per-viewer projection (opponents' secret cards are redacted), so what comes * back is already only what this client may see. */ export declare function unwrap(response: Response): Promise>; /** * Fetch a game's current state by id. `viewer` is a comma-separated list of your seat ids (see only * those seats' hidden info); `''` is a spectator (no cards); omit it to follow the active player. */ export declare function getGame(gameId: string, viewer?: string): Promise>; /** * Apply an action for a player and return the updated state. * * `action` is opaque: the server delegates all validation to the game's own module, so the shape is * the game's business. `viewer` (your seat ids) projects the response for your own seats so the reply * never reveals another player's card; omit for hotseat. * * `expectedVersion` is optimistic concurrency (REVIEW §4.2): pass the version of the state you acted * against and the server refuses (`409 STALE_VERSION`) if the game has since moved on. Rather than * surface that as an error, we **refetch and return the current state** — a double-click or a second * device that lost the race should feel like the board catching up, not a failure. Omit it to apply * unconditionally (the old behaviour). */ export declare function applyAction(gameId: string, playerId: string, action: unknown, viewer?: string, expectedVersion?: number): Promise>;