Store an offline game durably and reconstruct it — the offline counterpart of the
server's replay rehydration. Builds on the engine (#191); not wired into the UI yet
(Phase B3).
- serialize.ts: a LocalGameRecord (seed + rules + seat metadata + the alphabet-index
move journal) and replayGame() — reconstruct a live LocalGame by seeding a fresh
engine identically and replaying the journal. The board/bag/racks are not stored; they
are deterministic from the seed and the replayed operations, so the record stays small.
The journal is dictionary-independent (alphabet-index space, stable per variant).
- store.ts: an IndexedDB store for local games (save/get/list/delete), mirroring
lib/dict/store.ts — its own database, best-effort, guarded when IndexedDB is absent.
- engine.ts: record the swapped tiles on an exchange (needed for exact replay) and expose
the game's rule config.
- serialize.test.ts: a round-trip — reconstruct a mid-game and a finished game by replay
and assert the state (board/racks/bag/scores/turn/log) is identical.
Pure additive library code; no runtime behavior change (bundle unchanged).