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. |
useLogLinks(handler) |
void. While the component is mounted, handler gets a LogLinkEvent, { type: "enter" | "leave" | "click"; key: string }, each time a player's pointer or focus first reaches a link in Boardweaver's game log (enter), both have left it (leave) or the player clicks it (click). key is the link's key from .link(key, text). See Links in the log. |
useHistory(options?) |
options is { ownPanel?: boolean }: true hides Boardweaver's game log panel while the component is mounted, and Boardweaver's history button then opens and closes the game's log. Returns { entries: HistoryItem[]; more: boolean; open: boolean; setOpen: (open: boolean) => void }. entries is the match's log, oldest first, read from the opening to now and then each new row. more is true while earlier rows are still to be read. open is the game's log's state, always false while no mounted component passes ownPanel: true. See The log in the game. |
<History style? kindStyles? renderLink? /> draws the match's log with Boardweaver's own log component: style is a CSSProperties over the list, kindStyles a Record<string, CSSProperties> over each line by its kind, and renderLink(link: LogLink): ReactNode draws a link's content, where LogLink is { key: string; text: string }. A tap on a row moves the board there, and its links reach useLogLinks.
type HistoryLine = { playerId: PlayerId | null; kind: string | null; segments: LogSegment[] };
type HistoryItemStep = { index: number; lines: HistoryLine[]; position: number | null };
type HistoryItem =
| { kind: "opening"; historyId: HistoryId; lines: HistoryLine[]; position: number | null }
| { kind: "decision"; historyId: HistoryId; actorPlayerId: PlayerId | null; createdAt: Timestamp; steps: HistoryItemStep[] }
| { kind: "undo"; historyId: HistoryId; actorPlayerId: PlayerId | null; createdAt: Timestamp; undoes: UndoneStep; position: number | null };
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.5.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, HistoryOptions, HistoryControl, HistoryItem, HistoryItemStep, HistoryLine, HistoryProps, LogLink, LogLinkEvent, PlayerProfile, MatchStatus, ColorMode, GameTheme, Sounds, SoundType, PlaySoundOptions, SoundHandle, AudioSettings.