const CACHE_PREFIX = "office-tools-shell-"; const CACHE_NAME = `${CACHE_PREFIX}0.2.0`; const CORE = ["./", "./manifest.webmanifest", "./favicon.svg"]; self.addEventListener("install", (event) => { event.waitUntil( caches.open(CACHE_NAME).then(async (cache) => { await cache.addAll(CORE); const response = await fetch("./"); const html = await response.text(); const assets = [...html.matchAll(/(?:src|href)="(\.\/assets\/[^"]+)"/g)] .map((match) => match[1]) .filter(Boolean); await cache.addAll(assets); }), ); self.skipWaiting(); }); self.addEventListener("activate", (event) => { event.waitUntil( caches .keys() .then((keys) => Promise.all( keys .filter((key) => key.startsWith(CACHE_PREFIX) && key !== CACHE_NAME) .map((key) => caches.delete(key)), ), ) .then(() => self.clients.claim()), ); }); self.addEventListener("fetch", (event) => { if (event.request.method !== "GET") return; const url = new URL(event.request.url); if (url.origin !== self.location.origin) return; const scope = new URL(self.registration.scope); if (!url.pathname.startsWith(scope.pathname)) return; if (event.request.mode === "navigate") { event.respondWith( fetch(event.request) .then((response) => { if (response.ok) { const copy = response.clone(); void caches .open(CACHE_NAME) .then((cache) => cache.put(event.request, copy)); } return response; }) .catch(async () => { const cached = await caches.match(event.request); if (cached) return cached; const shellUrl = new URL("./", self.registration.scope).href; return (await caches.match(shellUrl)) ?? Response.error(); }), ); return; } event.respondWith( caches.match(event.request).then( (cached) => cached ?? fetch(event.request).then((response) => { if (response.ok) { const copy = response.clone(); void caches .open(CACHE_NAME) .then((cache) => cache.put(event.request, copy)); } return response; }), ), ); });