boardweaver/react reference
Every hook and helper a client can import from boardweaver/react. How to use them together is in The React client. Every hook throws outside a match.
Hooks
| Hook | Returns |
|---|---|
useMatch() |
{ ready: boolean; status: "waiting" | "in_progress" | "finished" | "locked" | null; viewer: PlayerId | null; isGameOver: boolean; online: boolean }. ready is false until the match, the seat's saved draft and the first page of the steps the seat has not seen have arrived. |
useBoard() |
State | null: the seat's view with its draft and its decision on its way applied. |
useOffers() |
Offer[]: the seat's offers on that board. |
useAct() |
(action: Action | Action[]) => Outcome: takes one step on the board of this render, or a list of steps from one event. |
useDraft() |
DraftView: { steps: { action, intent, lines }[]; reopenedSteps: number }. |
useUndo() |
{ available: "draft" | "server" | "none"; undo: () => Outcome }. |
usePending() |
{ pending: PendingView | null; deferred: string[] }. PendingView is { id; kind: "decision" | "undo"; predicted: boolean; historyId? }. deferred lists ids whose result the connection lost. |
useFailures() |
{ failures: CoreFailure[]; dismiss: (id: string) => void }. |
useLastChange() |
LastChange: { actorPlayerId?; own: boolean; coalesced: boolean; direction: "forward" | "back"; steps: WasmStepView[]; undo?: WasmLastUndo | null }. |
usePlayback(options?) |
options is { ownControls?: boolean }: true hides Boardweaver's return card, the bubble with each step's log lines, and the step controls while the component is mounted. Returns { status: "now" | "playing" | "paused"; behind: number; more: boolean; fetching: boolean; canStepBack: boolean; speed: PlaybackSpeed; setSpeed; play; pause; stepForward; stepBack; skipToNow }, where PlaybackSpeed is 0.5 | 1 | 2 | 4 | 8. Boardweaver's bar plays at 1, and a finished match's replay page offers 1 to 8. behind counts the steps read after the one on the board, and more is true when steps past those are not read yet. See Other players' steps. |
useStepDuration(duration) |
void. duration is milliseconds per change at 1x, a number or (change: LastChange) => number, while the component is mounted. When several components set one, the one mounted last applies. The default is 600 ms per step. |
useScores() |
Scores: Record<string, { publicPoints: number[]; privatePoints: number[] }>, keyed by player id as a string. |
useSelf() |
{ playerId: PlayerId; isActive: boolean } | null. null for a spectator. |
usePlayers() |
PlayerProfile[]: { id: number; name: string; avatarUrl?: string | null; bot?: { id: string; difficulty?: "easy" | "standard" | "hard" }; abandoned?: boolean }, in the order of the state's players. id is the seat's player id. name is the person's username or the bot's name, and bot is set only on a bot's seat. abandoned is true on a seat whose player left the match. A player leaving ends the match, so the match can be over while useMatch().isGameOver is still false. |
useImage(key) |
string | undefined: the URL of the game's art key. |
useSounds() |
Sounds: { play(key: string, options: PlaySoundOptions): SoundHandle; stopAll(type?: SoundType): void }, the same object for the whole match. PlaySoundOptions is { type: "music" | "effect"; loop?: boolean; volume?: number } and SoundHandle is { stop(): void }. play throws for a key the game has no sound for. See Sounds. |
useAudioSettings() |
AudioSettings: { music: boolean; effects: boolean }, what the player hears now. useSounds() already applies it. |
useGameTheme() |
GameTheme: the game's /theme.json. |
useColorMode() |
"light" | "dark", following the player's setting. |
useViewport() |
Viewport: { width: number; height: number }, the size of the client's area in CSS pixels. It changes when that area is resized. See Layout. |
useMatchEnd() |
{ startsNextMatch: boolean; nextMatchPending: boolean; nextMatch: () => void; returnToGames: () => void }. For GameOver. |
lineText(line: LogLine): string is a log line's text with its links' text, as one string: "plays the Fireball". Boardweaver's bubble and step bar read lines with it too.
apiVersion is the module's version, "2.3.0". The module only grows: a later version adds hooks and fields and never removes them.
Types
Import any of these with import type { ... } from "boardweaver/react".
The board: State, Player, Space, Piece, Arrangement, PlayerId, Score, Scores.
type State = { activePlayerIds: number[]; players: Player[]; spaces: Space[]; metaData?: Record<string, unknown> };
type Space = { spaceId: string; kind: string; owner?: number; arrangement?: "ordered" | "collection"; pieces?: Piece[]; publicState?: Record<string, unknown>; privateState?: Record<string, unknown> };
type Piece = { publicKind: string; privateKind?: string; owner?: number; publicState?: Record<string, unknown>; privateState?: Record<string, unknown> };
Moves: Action, Offer, Intent, Input, InputValue, Outcome.
type Action =
| { type: "SpaceClick"; spaceId: string }
| { type: "PieceClick"; spaceId: string; index: number }
| { type: "Command"; name: string; value?: string | number | null };
type Offer = { action: Action; intent: "choice" | "confirm" | "cancel"; label?: string; input?: Input | null; reveals?: boolean };
type Input = { type: "Text"; maxLen: number; suggestions: string[] } | { type: "Integer"; min: number; max: number; step?: number };
Outcome from act and undo is { id, type: "applied" }, { id, type: "sent" }, { id, type: "undone" } or { id, type: "failed", reason: FailureReason, applied? }, where applied counts the steps of a list that joined before one failed. The type also has committed and deferred, which act and undo never answer.
Changes: LastChange, Direction, PlaybackStatus, PlaybackView, PlaybackSpeed, WasmStepView ({ actorPlayerId?; intent?; lines: LogLine[]; movements: ViewedMovement[] }), LogLine, LinePlayer, LogSegment, WasmLastUndo, ViewedMovement, Spot.
type LogLine = { player: LinePlayer; kind?: string | null; segments: LogSegment[] };
type LinePlayer = "actor" | "none" | { seat: number };
type LogSegment = string | { key: string; text: string };
type Spot = { type: "At"; spaceId: string; index: number } | { type: "Hidden"; spaceId: string };
type ViewedMovement =
| { type: "Moved"; from: Spot; to: Spot; piece: Piece }
| { type: "Added"; at: Spot; piece: Piece }
| { type: "Removed"; from: Spot; piece: Piece }
| { type: "Flipped"; at: Spot; piece: Piece }
| { type: "Shuffled"; spaceId: string };
Drafts and failures: DraftView, DraftStepView, PendingView, PendingKind, UndoAvailable, CoreFailure, FailureReason, Refusal, Unresolved, AbandonedStep, AbandonReason, HistoryId, Timestamp.
FailureReason.code is one of:
| Code | Means |
|---|---|
NOT_PLAYING |
This client is a spectator, or the match takes no moves. |
LOADING |
The match has not loaded yet. |
WAITING |
Another decision or undo is on its way. |
STALE |
The step was made on a board the player no longer sees. |
PLAYING |
The board shows an earlier step, not now. Skip to now first. |
UNPREDICTABLE |
The step cannot show before Boardweaver applies it. |
DRAFT_FULL |
The decision already has 200 steps. |
NOTHING_TO_UNDO |
Undo has nothing to take back. |
REFUSED |
The game logic refused the step. refusal says how. |
MODULE_FAILED |
The game logic failed while showing the step. message says how. |
SERVER_REFUSED |
Boardweaver refused the decision. Carries status, message, the dropped steps and maybe a refusal. |
NOT_APPLIED |
The decision was not applied. Carries the dropped steps. |
DRAFT_DROPPED |
Draft steps no longer fit the board and were dropped. Carries the dropped steps. |
DRAFT_LOAD_FAILED |
The saved draft did not load. Carries status and message. |
Refusal.code is NOT_OFFERED, INPUT_DOES_NOT_FIT, GAME (with the game logic's reason), NEEDS_SERVER, ENDS_DECISION, DECISION_OPEN or UNRESOLVED.
Platform: PlaybackOptions, PlayerProfile, MatchStatus, ColorMode, GameTheme, Sounds, SoundType, PlaySoundOptions, SoundHandle, AudioSettings.