/* ihasmail service worker: app-shell caching for installability & fast loads. API requests are never cached. */ const VERSION = "ihasmail-v2"; const SHELL = ["/", "/manifest.webmanifest", "/img/logo.png", "/img/icon-192.png", "/favicon.ico"]; self.addEventListener("install", (event) => { event.waitUntil(caches.open(VERSION).then((c) => c.addAll(SHELL)).then(() => self.skipWaiting())); }); self.addEventListener("activate", (event) => { event.waitUntil( caches.keys().then((keys) => Promise.all(keys.filter((k) => k !== VERSION).map((k) => caches.delete(k)))).then(() => self.clients.claim()) ); }); self.addEventListener("fetch", (event) => { const req = event.request; if (req.method !== "GET") return; const url = new URL(req.url); if (url.origin !== self.location.origin) return; if (url.pathname.startsWith("/api/")) return; // Hashed build assets: cache-first. if (url.pathname.startsWith("/assets/")) { event.respondWith( caches.match(req).then((hit) => hit || fetch(req).then((res) => { const copy = res.clone(); caches.open(VERSION).then((c) => c.put(req, copy)); return res; })) ); return; } // Navigations & everything else: network-first, fall back to cached shell. if (req.mode === "navigate") { event.respondWith(fetch(req).catch(() => caches.match("/"))); return; } event.respondWith(fetch(req).catch(() => caches.match(req))); });