feat(offline): app-shell precache service worker (vite-plugin-pwa) [C1] #197
Reference in New Issue
Block a user
Delete Branch "feature/offline-pwa-precache"
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?
Part of the PWA offline mode (Phase C). C1 of the C1→C6 stack — precache first, so a cold offline launch actually loads the app (per your ordering choice).
What
Migrate the former install-only
public/sw.jsto a custom (injectManifest) service worker built fromui/src/sw.tsby vite-plugin-pwa. It precaches the app shell + hashed assets (Workbox — 21 entries, ~684 KiB) so an installed web PWA cold-launches with no network, and falls in-scope navigations back to the precached shell (the hash router resolves the route client-side).injectRegister:false;pwa.svelte.tsskips the mock build + Telegram/VK Mini Apps). The plugin is disabled entirely in the mock build, so Playwright is unperturbed./_gm); the landing page + the conditional polyfill bundle are excluded from the precache.public/sw.js; the served path (dist/sw.jsat/app/) is unchanged, so the gateway serving + the existing registration are untouched.Flags for review
vite-plugin-pwa+workbox-{core,precaching,routing}— dev-only (not in the app bundle), butworkbox-builddrags ~320 transitive packages into the lockfile. That's the cost of the Workbox route you chose in round-3. A hand-rolled ~30-line vite plugin (like the existingemitPolyfills) injecting the asset list into a plain SW would add zero deps, at the cost of reimplementing Workbox's precache-revisioning/cleanup. Flagging in case the dep weight changes your mind — I went with your Workbox choice.Tests
Go: gateway
webui(the/app/sw.js-served-as-JS test) unaffected. UI:check(0 errors), unit (470), e2e (196, Chromium + WebKit),build(generatesdist/sw.js, 21 precache entries; the mock build emits no SW), bundle gate 112.0 / 113.Next: C6 (offline lobby — network gating + reuse NewGame gated to vs_ai+offline for creation + list local games + disable online affordances) stacks on this.
Migrate the former install-only public/sw.js to a custom (injectManifest) service worker built from ui/src/sw.ts by vite-plugin-pwa. It precaches the app shell + hashed assets (Workbox) so an installed web PWA cold-launches with no network, and falls in-scope navigations back to the precached shell (the hash router resolves the route client-side). This is the C1 prerequisite for a usable offline mode: without it a cold offline launch cannot load the bundle. - ui/src/sw.ts: skipWaiting + clientsClaim + cleanupOutdatedCaches + precacheAndRoute(__WB_MANIFEST) + a NavigationRoute fallback to index.html, deny-listing the RPC path and /_gm. The Connect stream and API POSTs are never precached nor intercepted. - vite.config.ts: VitePWA(injectManifest); manifest:false (we ship our own), injectRegister:false (registration stays manual + web-only in pwa.svelte.ts), disabled in the mock build (Playwright unperturbed); landing + polyfills excluded from the precache. - Removed public/sw.js; the registration path (dist/sw.js at /app/) is unchanged. - New dev deps: vite-plugin-pwa + workbox-{core,precaching,routing}. Docs: ARCHITECTURE + gateway/README. Offline cold-launch is contour-verified (the mock e2e harness disables the SW).