Browser-targeted. Owns the single protocol that connects a game iframe to the shell that hosts it: the URL-fragment handshake, the postMessage message set, and the shell-controls registry that lets the host render save / load / reset / lobby chrome around the game from a manifest-driven catalog.Documentation Index
Fetch the complete documentation index at: https://openturn.io/docs/llms.txt
Use this file to discover all available pages before exploring further.
Install
The wire
A host mounts a game iframe with a#openturn-bridge=<base64-json> fragment. Inside the iframe, the game side decodes it with createGameBridge(); the host side uses createBridgeHost() to manage the iframe lifecycle. Both sides talk exclusively via namespaced postMessage messages defined in this package.
Game side (inside the iframe)
createGameBridge(options?)
Resolve the bridge for this iframe. Reads the fragment from the URL (override with options.readInit) and returns the handle.
BridgeUnavailableError if the fragment is missing.
GameBridge
The game-side handle. Exposes the decoded init, the live token getter, a HostedConnectionDescriptor for the WebSocket client, a shell-control event channel, a lifecycle event emitter, and a token refresher. Read room/user/scope/websocketURL off bridge.init.* — prior builds mirrored those fields onto the bridge directly; that mirror was removed in favor of a single source of truth.
Additional methods:
bridge.lifecycle.on(event, listener)— subscribe to host-driven"pause" | "resume" | "close"lifecycle events. Returns an unsubscribe.bridge.shellControl.on(listener)— subscribe to shell-control activations from the host (reset,returnToLobby, …). Each click firesphase: "before"thenphase: "after". SeeBridgeShellControlChannelbelow.bridge.registerBatchSource(source: BatchSourceHandle | null)— register an initial-snapshot + ongoing-batch source so the host can request a live inspector stream. Most recent registration wins; passnullto clear.bridge.allowBatchStreaming(allow: boolean)— author-side opt-out. Whenfalse, host-initiated stream requests resolve to"denied-by-game". Defaults totrue.bridge.setMatchActive(active: boolean)— announce whether a match is currently live. The shell uses this to enable/disable match-only controls (e.g. Reset). Coalesces duplicates.bridge.getRoomToken()— alias ofrefreshToken()that plugs into transport clients expecting agetRoomToken()function.bridge.dispose()— release the message listener and clear shell-control listeners.
CreateGameBridgeOptions
BatchSourceHandle<TInitial, TBatch>
BridgeShellControlChannel / BridgeShellControlEvent
Shell controls are host-driven, not game-advertised: the deployment manifest declares which controls render, the host adapter implements them, and the bridge notifies the game around each invocation so it can react (e.g. clear local UI on reset).
phase: "before" immediately before the host runs the corresponding adapter method, and phase: "after" once it settles. The wire control is intentionally an open string — narrow it with isKnownShellControl before switching so unknown ids from a newer host are handled explicitly.
BridgeLifecycle / BridgeLifecycleEvent
pause/resume when the iframe leaves and re-enters the foreground; close fires before the host detaches the iframe.
Host side (in the shell)
createBridgeHost(options)
BridgeHost
Shell-side handle with:
src: string— iframesrcwith the fragment baked in.matchActive: boolean— current match-active state. Defaults toinit.scope === "game"; updated viamatch-state-changedevents.emitShellControl(control, phase)— notify the game that a shell control was activated. Call once with"before"immediately before invoking the corresponding adapter method, and once with"after"afterwards.pause()/resume()/close()— lifecycle control.on(event, listener)— subscribe toBridgeHostEvents. Returns an unsubscribe function.requestBatchStream(timeoutMs?)— ask the game to start streaming initial snapshot + batches. Resolves to aBatchStreamStatus("allowed" | "denied-by-game" | "no-source").stopBatchStream()— ask the game to stop streaming. Safe to call when idle.onBatch(listener)— subscribe to streamed batches. Immediately replays the last-seen snapshot/batch. Returns an unsubscribe function.dispose()— release the window listener and clear pending stream requests.
BridgeHostEvent / BridgeHostEventMap
The events a BridgeHost emits via host.on(...):
BridgeHostTokenContext / BridgeHostTokenRefreshResult
Passed to / returned from BridgeHostOptions.refreshToken:
Batch-stream types
Schema
BridgeInit
The decoded fragment payload. Carries roomID, userID, scope, token, tokenExpiresAt, websocketURL, playerID?, the player range (minPlayers, maxPlayers, targetCapacity), and host info (isHost, hostUserID). Zod-validated on both sides.
targetCapacity is the room’s effective seat count (host-mutable in [minPlayers, maxPlayers]); maxPlayers equals the manifest’s players.length. For fixed-size games the three numbers are equal.
BridgeMessage
Discriminated union of all postMessage payloads: ready, token-refresh-request / token-refresh-response, shell-control, lifecycle-pause / lifecycle-resume / lifecycle-close, batch-stream-start / batch-stream-stop / batch-stream-response, initial-snapshot / batch-applied, and match-state (all under the openturn:bridge:* namespace).
BRIDGE_FRAGMENT_KEY
The URL hash key under which BridgeInit is stored: openturn-bridge.
BridgeScope
"lobby" | "game" — matches RoomTokenClaims["scope"]. Determines whether the bridge exposes a connection descriptor.
BridgeShellControl
The wire type for a shell-control id. Intentionally an open string (validated as min(1).max(64)) so a newer host can introduce new ids without bumping the schema or breaking older games. Use isKnownShellControl to narrow it to the canonical OpenturnShellControl union before switching.
Shell-controls registry
Single source of truth binding eachOpenturnShellControl id (declared in @openturn/manifest) to its runtime metadata. The registry is what the shell, the manifest schema, and the runtime gating helper all derive from. Games never register shell controls — the manifest decides which controls render and the host adapter implements them.
SHELL_CONTROLS
ShellControlMeta
isShellControlEnabled(adapter, id)
Resolve a single control. Returns true when the adapter implements the backing method (or the control is shell-only) AND the manifest hasn’t explicitly opted out via false. undefined in the manifest means “default-on if supported”.
isKnownShellControl(id)
Runtime narrowing helper. Returns true when the wire id matches one of the canonical SHELL_CONTROL_IDS.
TrailShellControl
Type-level helper for compile-time exhaustiveness. Only includes the control ids whose placement is "toolbar-trail" — used by toolbar implementations to require a handler for every trail control.
OpenturnShellControl
Re-exported from @openturn/manifest for convenience. The canonical union of known shell-control ids.
encodeBridgeFragment(init) / decodeBridgeFragment(hash)
Lossless round-trip between BridgeInit and the URL-fragment string.
readBridgeFragmentFromLocation()
Decodes the BridgeInit from window.location.hash (returns null when running outside a browser or when no fragment is present). This is the default readInit for createGameBridge; export it for custom bootstraps that want the same fallback.
BRIDGE_MESSAGE_NAMESPACE
Prefix used by every bridge postMessage type (openturn:bridge:*). Filter on this before schema validation when sharing a window with other postMessage traffic.
Play-shell adapter
The play shell (cloud/play and the local CLI dev shell) is a bridge-host shell that renders shell controls (save, load, reset, return-to-lobby, public rooms, …) around any embedded game. The adapter is the host-side contract that the shell calls into when those controls are activated; the bridge package owns its types so both shells can be implemented against the same surface and the shell-controls registry can gate rendering on adapter[meta.adapterMethod].
PlayShellAdapter
isShellControlEnabled.
Adapter and room types
PlayShellAdapterMeta— what the adapter advertises about itself:shellControls?: OpenturnShellControlsConfig(from the manifest), invite affordances, etc.PlayMultiplayerConfig— config the play shell hands the adapter at construction.PlayRoomSnapshot,PlayRoomStatus,PlayRoomVisibility,PlayRoomResult— room state shapes.PresenceSeat,PresenceSnapshot— per-seat presence rows.PublicRoomSummary— entries returned bylistPublicRooms.RoomActionResult,SaveRoomResult,SetVisibilityResult— result shapes for the shell-control adapter methods.
Helpers
describeRoomStatus(status)— render aPlayRoomStatusas a human-readable string for shell UI.extractRoomID(value)— pull the room id out of a free-form invite string or URL; returnsnullwhen no id is present.snapshotToBridgeInit(snapshot)— convert aPlayRoomSnapshotinto theBridgeInitbaked into the iframe fragment. Shared between both play shells.
Re-exports
HostedConnectionDescriptor(from@openturn/client)
See also
- Reference: react for the hooks that build on this package.
- How-to: run a local hosted stack for the dev transport context.