The C1 service worker served the precached shell for every navigation, even
online, so a new deploy only reached a client after the worker updated its
precache in the background (a one-launch lag): a cold online start showed the
old version until then, and only a reinstall forced it fresh.
- sw.ts: navigations are now network-first — fetch the fresh (no-cache) shell
from the server on each online launch (it references the new hashed assets,
fetched fresh), with a 3s timeout falling back to the precached shell when the
network is unreachable or too slow. Only the tiny HTML is re-fetched; the
immutable hashed assets stay cache-first and re-download only when their hash
(the version) changes. Offline cold-launch still works via the fallback.
- webui.go: serve sw.js with Cache-Control: no-cache so the browser reliably
detects a new deploy's worker (regression-tested).
Online launch is contour-verified (the mock e2e disables the SW); e2e 196.
No new deps — the network-first handler is hand-written (~12 lines).
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).