Summary
The PWA service worker (sw.js) has three real problems: it calls localStorage inside the service worker scope (which throws), its cache-first strategy means deployed updates never reach returning users, and its precache list is missing most of the app.
Bugs
1. localStorage does not exist in a service worker (sw.js:77-83)
async function getPendingAnalytics() {
return JSON.parse(localStorage.getItem('spellbloc_pending_analytics') || '[]');
}
Service workers have no localStorage — this throws ReferenceError: localStorage is not defined whenever the analytics-sync background sync fires (sw.js:49-53). The sync silently fails forever. These functions must use IndexedDB (the comment even says "IndexedDB operations" — the implementation just never happened).
2. Cache-first with a static cache name = permanently stale app (sw.js:23-31)
return response || fetch(event.request);
Every cached file is served from cache unconditionally, and CACHE_NAME is hardcoded to spellbloc-v1.0.0 (sw.js:2). Unless someone remembers to bump the version string on every deploy, users keep running old game.js/styles.css forever. Suggested: stale-while-revalidate (or network-first for HTML), plus self.skipWaiting() / clients.claim() for clean activation.
3. Precache list doesn't match the app (sw.js:3-10)
Cached: /, /index.html, /styles.css, /game.js, /advanced-systems.js, /manifest.json.
Not cached but required: game.html, login.html, auth-manager.js, ai-agent.js, email-integration.js, minipay-integration.js, etc. Offline mode therefore breaks as soon as the user navigates past the landing page. Also, cache.addAll() rejects entirely if any single URL fails, which disables precaching wholesale.
Bonus: the push notification handler (sw.js:86-109) references /icon-192x192.png, /badge-72x72.png, /play-icon.png, /dismiss-icon.png — none of these files exist in the repo (icons were removed in commit 773a807).
Acceptance criteria
Summary
The PWA service worker (
sw.js) has three real problems: it callslocalStorageinside the service worker scope (which throws), its cache-first strategy means deployed updates never reach returning users, and its precache list is missing most of the app.Bugs
1.
localStoragedoes not exist in a service worker (sw.js:77-83)Service workers have no
localStorage— this throwsReferenceError: localStorage is not definedwhenever theanalytics-syncbackground sync fires (sw.js:49-53). The sync silently fails forever. These functions must use IndexedDB (the comment even says "IndexedDB operations" — the implementation just never happened).2. Cache-first with a static cache name = permanently stale app (
sw.js:23-31)Every cached file is served from cache unconditionally, and
CACHE_NAMEis hardcoded tospellbloc-v1.0.0(sw.js:2). Unless someone remembers to bump the version string on every deploy, users keep running oldgame.js/styles.cssforever. Suggested: stale-while-revalidate (or network-first for HTML), plusself.skipWaiting()/clients.claim()for clean activation.3. Precache list doesn't match the app (
sw.js:3-10)Cached:
/,/index.html,/styles.css,/game.js,/advanced-systems.js,/manifest.json.Not cached but required:
game.html,login.html,auth-manager.js,ai-agent.js,email-integration.js,minipay-integration.js, etc. Offline mode therefore breaks as soon as the user navigates past the landing page. Also,cache.addAll()rejects entirely if any single URL fails, which disables precaching wholesale.Bonus: the push notification handler (
sw.js:86-109) references/icon-192x192.png,/badge-72x72.png,/play-icon.png,/dismiss-icon.png— none of these files exist in the repo (icons were removed in commit773a807).Acceptance criteria
game.jsreaches users on next load without manually bumping a version string