feat: on-device move preview (local eval) with network fallback #154
Reference in New Issue
Block a user
Delete Branch "feature/local-eval"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
On-device move preview: score/validate a tentative move locally instead of a per-arrangement network round trip. The dawg reader + validate/score/direction slice of scrabble-solver are ported to TS (ui/src/lib/dict), pinned byte-for-byte to the Go engine by the
conformanceCI job. Server stays authoritative (submit_play re-validates); network evaluate is the fallback.The dictionary loads on game open (low priority, aborted at a 5s cap or on leaving the game), cached in IndexedDB (self-healing on a rejected blob), reused across sessions; a warm-up overlay covers a cold load. A bad-connection breaker + in-flight-preview cancellation keep it graceful on slow links. Telemetry (adoption counters) is a follow-up PR.
Score and validate a tentative move on-device instead of a per-arrangement network round trip. The dawg reader and the validate/score/direction slice of the scrabble-solver engine are ported to TypeScript (ui/src/lib/dict), pinned byte-for-byte to the Go engine by a `conformance` CI job (full-dictionary reader parity plus a battery of plays across every variant and both cross-word rules, including the inferred orientation). The server stays authoritative — submit_play re-validates — so the local result is an advisory accelerator only. - backend: Registry.DictBytes + an authed GET /api/v1/user/dict/{variant}/{version} (immutable) streaming the pinned per-game dawg; caddy routes /dict to the gateway. - gateway: a session-gated /dict edge route proxying it; fetchDict on the transport. - client: the dictionary loads on game open (low priority so it never starves the game on a slow link; aborted at a 5s cap or when leaving the game), is cached in IndexedDB (best-effort, self-healing on a rejected blob) and reused across sessions; a warm-up overlay covers a cold load, then the network preview is the fallback; a bad-connection breaker stops warming after repeated misses; the move preview cancels its in-flight request when the tiles change. - parity generators backend/cmd/{dictgen,validategen} + gated Vitest suites, run in CI against the release dictionaries. A hidden debug readout lists the cached dictionaries + breaker state, and its reset clears the cache. - docs: ARCHITECTURE §5, TESTING, UI_DESIGN, FUNCTIONAL (+ru).38644f2a59to5689f7f6a3New commits pushed, approval review dismissed automatically according to repository settings
feat(ui): on-device move preview (local eval) with network fallbackto feat: on-device move preview (local eval) with network fallback