const CACHE = "font-tools-v0.1.0", APP = [ "./", "./index.html", "./manifest.webmanifest", "./favicon.svg", "./toolbox-app.json", ]; async function precacheAppShell() { const cache = await caches.open(CACHE); await cache.addAll(APP); const index = await cache.match("./index.html"); if (index) { const markup = await index.text(), scope = new URL(self.registration.scope), assets = [...markup.matchAll(/\b(?:src|href)=["']([^"'#]+)["']/g)] .map((match) => new URL(match[1], self.location.href)) .filter( (url) => url.origin === scope.origin && url.pathname.startsWith(scope.pathname), ); await cache.addAll(assets); } } self.addEventListener("install", (event) => event.waitUntil(precacheAppShell().then(() => self.skipWaiting())), ); self.addEventListener("activate", (event) => event.waitUntil( caches .keys() .then((keys) => Promise.all( keys.filter((key) => key !== CACHE).map((key) => caches.delete(key)), ), ) .then(() => self.clients.claim()), ), ); self.addEventListener("fetch", (event) => { if ( event.request.method !== "GET" || new URL(event.request.url).origin !== self.location.origin ) return; event.respondWith( (async () => { const cached = await caches.match(event.request); if (cached) return cached; try { const response = await fetch(event.request); if (response.ok) { const cache = await caches.open(CACHE); await cache.put(event.request, response.clone()); } return response; } catch (error) { if (event.request.mode === "navigate") { const fallback = await caches.match("./index.html"); if (fallback) return fallback; } throw error; } })(), ); });