const CACHE = "query-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(); const scope = new URL(self.registration.scope); const 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", (e) => e.waitUntil(precacheAppShell().then(() => self.skipWaiting())), ); self.addEventListener("activate", (e) => e.waitUntil( caches .keys() .then((k) => Promise.all(k.filter((x) => x !== CACHE).map((x) => caches.delete(x))), ) .then(() => self.clients.claim()), ), ); self.addEventListener("fetch", (e) => { if ( e.request.method !== "GET" || new URL(e.request.url).origin !== self.location.origin ) return; e.respondWith( (async () => { const cached = await caches.match(e.request); if (cached) return cached; try { const response = await fetch(e.request); if (response.ok) { const cache = await caches.open(CACHE); await cache.put(e.request, response.clone()); } return response; } catch (error) { if (e.request.mode === "navigate") { const fallback = await caches.match("./index.html"); if (fallback) return fallback; } throw error; } })(), ); });