const VERSION = 'pawplay-web-1.0.0'; const ROOT = new URL('./', self.location.href).href; const SHELL = new URL('index.html', ROOT).href; const ASSETS = ['index.html', 'game.js?v=1.0.0', 'style.css?v=1.0.0', 'manifest.webmanifest', 'icon.svg', 'apple-touch-icon.png', 'icon-512.png'].map(path => new URL(path, ROOT).href); self.addEventListener('install', event => { event.waitUntil((async () => { const cache = await caches.open(VERSION); try { await cache.addAll(ASSETS); } catch (error) { await caches.delete(VERSION); throw error; } })()); }); // A new version waits until existing game windows close, keeping one complete // shell/version per session. Never force-activate over an in-progress game. self.addEventListener('activate', event => { event.waitUntil((async () => { for (const key of await caches.keys()) { if (key.startsWith('pawplay-web-') && key !== VERSION) await caches.delete(key); } await self.clients.claim(); })()); }); self.addEventListener('fetch', event => { if (event.request.method !== 'GET') return; const url = new URL(event.request.url); if (!url.href.startsWith(ROOT)) return; if (event.request.mode === 'navigate') { event.respondWith((async () => (await (await caches.open(VERSION)).match(SHELL)) || fetch(event.request))()); } else if (ASSETS.includes(url.href)) { event.respondWith((async () => (await (await caches.open(VERSION)).match(event.request)) || fetch(event.request))()); } });