Files
galaxy-game/ui/docs/pwa-strategy.md
T
Ilia Denisov e31fb2c17a
Tests · UI / test (push) Failing after 9m28s
docs(ui): sync docs to the app-shell; fix stale nav comments
Rewrite ui/docs (navigation, order-composer, auth-flow, pwa-strategy,
game-state + secondary topic docs) and ui/README for the single-URL
app-shell (in-memory screens/views, Back→lobby via shallow routing,
sessionStorage restore + validation, return-to-lobby). ui/PLAN.md gets a
Phase-10 supersede note (implemented; standalone-compatible). Fix stale
code comments (session-store auth gate, report-sections spec contract).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-23 21:04:11 +02:00

57 lines
3.0 KiB
Markdown

# PWA strategy
The web client is an installable, offline-tolerant PWA. It uses
SvelteKit's native service worker (no Workbox) so there is no extra
build dependency and the cache logic stays explicit.
The single-URL app-shell (see [`navigation.md`](navigation.md)) makes
the offline story simpler: the whole game UI lives at one route
(`${base}/`, i.e. `/game/` under the single-origin deployment), so
there is exactly one navigation target to precache and fall back to —
no per-screen routes to enumerate. The service-worker scope and the
manifest are unchanged by that refactor; both were already base-aware
(the SW keys everything off `$service-worker`'s `base`, and the
manifest uses relative `./` `start_url` / `scope`).
## Pieces
- [`src/service-worker.ts`](../frontend/src/service-worker.ts) — the
worker. SvelteKit registers it automatically in the production build.
It precaches the app shell (`${base}/`), the build artefacts (JS/CSS
+ `core.wasm`), and the static files under a **version-keyed** cache
(`galaxy-cache-<version>`, `version` from `$service-worker`). On
`activate` it deletes every other cache, so a new deploy never serves
stale code. Strategy: cache-first for the version-keyed build/files;
network-first with cache fallback for everything else; the cached
shell answers navigations when fully offline. The gateway (cross-
origin) is never intercepted — it is always live network.
- [`static/manifest.webmanifest`](../frontend/static/manifest.webmanifest)
— name, `standalone` display, relative `./` `start_url`/`scope` (so
it resolves under whatever `base` the build is deployed at), dark
`theme_color`/`background_color`, and the icon set.
- [`static/icons/`](../frontend/static/icons/) — `192`/`512` (`any`),
a `512` `maskable`, and a `180` apple-touch icon. They are placeholder
artwork generated from `static/favicon.svg` by
[`scripts/gen-pwa-icons.mjs`](../frontend/scripts/gen-pwa-icons.mjs)
(a dependency-free pure-Node PNG encoder); swap in real artwork at the
same paths and the manifest is unchanged.
- [`src/app.html`](../frontend/src/app.html) — the manifest link, the
apple-touch-icon link, and light/dark `theme-color` metas matching the
design tokens.
## Testing
PWA behaviour is gated by Playwright against a **production preview**
build ([`playwright.pwa.config.ts`](../frontend/playwright.pwa.config.ts)
+ [`tests/pwa/pwa.spec.ts`](../frontend/tests/pwa/pwa.spec.ts), run by
`pnpm test:pwa` in CI): the manifest is linked with installable icons,
the service worker registers and controls the page under exactly one
version-keyed cache, and the app shell loads offline from that cache.
The spec needs a real build because `$service-worker`'s `build` list is
empty under `vite dev`.
Lighthouse is intentionally **not** used: its PWA category was removed
in Lighthouse 12 (the current line is 13.x), so "Lighthouse PWA ≥ 90" is
no longer a meaningful gate. The Playwright checks above verify the same
install/offline behaviour directly.