Skip to content

v0.109.0 — PWA: foundations

Shipped 2026-10-01 — built on version/0.109.0; the merge hash and tag are in the changelog. PWA.11's checks that need a deployed alpha and real phones carry into v0.110.0 as PWO.0.

Part one of the Progressive Web App: foundations. Moved ahead of the wiki's hosting and across-roots releases on 2026-10-01, which now follow the PWA's three releases (v0.112.0 and v0.113.0). No module release.

  • [x] PWA.1 — the manifest, per environment (PWA-D5), generated at build time into manifest.webmanifest; the CRA stub and public/index.html deleted
  • [x] PWA.2 — the head: manifest link, theme-color light and dark, the apple-* tags, viewport-fit=cover without disabling pinch zoom
  • [x] PWA.3 — the deploy's headers: sw.js, registerSW.js and manifest.webmanifest uploaded no-cache in all three deploy jobs; a missing /sw.js is a 404, not HTML; a guard test reads the workflows
    • Done: the three jobs exclude the stable names from the immutable sync and upload them no-cache with explicit types (pwaDeploy.guard.test.ts). Checked: CloudFront answers a missing /sw.js with index.html and a 200 — its SPA error responses are distribution-wide, so a true 404 needs an infra change (a viewer-request function in place of custom_error_response). Left as is: a browser refuses a worker served as text/html, so a missing sw.js fails an update exactly as a 404 would, and the installed worker stays.
  • [x] PWA.4 — the worker (PWA-D1): vite-plugin-pwa in injectManifest mode, source in apps/web/src/sw/; precache the hashed build, navigations network-first; Sentry source-map deletion still after the precache list
  • [x] PWA.5 — the API is never the worker's: other origins and /api, /images, /socket.io pass through; a unit test drives the handler, a guard fails a registerRoute naming the API
  • [x] PWA.6 — the segmentation runtime cached on first use (PWA-D2): /ort/*, /mediapipe/*, /models/mediapipe/* cache-first in a versioned cache, old ones deleted on activate; SAM2's own cache left alone
  • [x] PWA.7 — "a new version is ready" (PWA-D3): notify() with Reload outside /play, a quiet play-bar badge inside it; never reloads on its own; a cold launch takes the new one
    • Done: a waiting worker found in the launch's first ten seconds is taken at once (the cold launch); later, appUpdateStore holds it — a persistent toast with Reload off the map, a quiet badge in the play bar's right column on it, and only those clicks apply it. On a phone the map has no play bar, so on /play a phone gets the new version at its next cold launch; navigations are network first, so that is never a stale page.
  • [x] PWA.8 — the kill switch: a build flag shipping a worker that unregisters itself, deletes every cache and reloads its clients once; tested; a runbook entry
  • [x] PWA.9 — standalone layout: safe-area insets on the mobile play shell's top bar, bottom tabs and drawers; overscroll-behavior: none on the map; display-mode: standalone where browser chrome was allowed for
    • Done: safe-area tokens; the footer takes the bottom inset inside --vtt-footer-height, so the mobile bar, drawers and tab bodies clear the home indicator without each knowing; tab bodies and the phone's nub start below the status bar; the bar, footer and tab bodies clear the notch in landscape; the map and the root (while a map is mounted) are overscroll-behavior: none. No display-mode: standalone query was needed: nothing in the app allowed for the browser's own chrome.
  • [x] PWA.10 — install: an "Install app" item in the account menu (beforeinstallprompt, or the iOS Share → Add to Home Screen explanation); never a banner
  • [ ] PWA.11 — verified: Lighthouse installability clean on alpha; the smoke suite asserts the manifest type and the worker registering; a device pass on iPhone and Android through a deploy
    • Done here: e2e/pwa.spec.ts in the smoke suite — the manifest served as application/manifest+json with every icon it names, the head's links, the worker registering, activating and controlling the page, no API response in any cache, and a missing .js never served as JavaScript. pnpm verify --e2e green.
    • Blocked on a deploy and devices (needs version/0.109.0 on alpha): Lighthouse's installability audit on alpha; the kill switch deployed to alpha (ALPHA_PWA_KILL_SWITCH=1) and seen to leave an installed client with no worker and no caches, then unset; a device pass on an iPhone and an Android phone, installed, through two deploys (the update prompt and the cold-launch update seen for real).