/* eslint-disable no-var */ import { build, files, version } from '$service-worker'; const worker = (self as unknown) as ServiceWorkerGlobalScope; const FILES = `cache${version}`; // build is an array of all files generated by the bundler // files is an array of all files in the static dir const to_cache = build.concat(files); const staticAssets = new Set(to_cache); worker.addEventListener("install", (event) => { event.waitUntil( caches .open(FILES) .then((cache) => cache.addAll(to_cache)) .then(() => { worker.skipWaiting(); }) ); }); worker.addEventListener("activate", (event) => { event.waitUntil( caches.keys() .then(async (keys) => { // Delete old caches for (const key of keys) { if (key !== FILES) await caches.delete(key); } console.log("old caches deleted") worker.clients.claim(); }) .then(() => console.log("Activated")) ) }) // Fetch the asset from the network and store it in the cache // Falls back to the cache if the user is offline async function fetchAndCache(request: Request) { const cache = await caches.open(`offline${version}`); try { const response = await fetch(request); cache.put(request, response.clone()); return response; } catch (err) { // if the user is offline, the request will fail const response = await cache.match(request); if (response) return response; // if not in cache, throw error anyway throw err; } } worker.addEventListener("fetch", (event) => { if (event.request.method !== "GET") return; console.log("fetch event intercepted") // Firefox has not yet fixed this, so it needs to be excluded from this caching behavior // https://web.dev/sw-range-requests/ // https://wpt.fyi/results/fetch/range/sw.https.window.html?label=master&label=experimental&aligned if (navigator.userAgent.includes("Firefox/") && event.request.headers.has("range")) return; const url = new URL(event.request.url); // Don't try to cache protocols other than http/https const isHttp = url.protocol.startsWith("http"); const isStaticAsset = url.host === self.location.host && staticAssets.has(url.pathname); const skipBecauseUncached = event.request.cache === 'only-if-cached' && !isStaticAsset; if (isHttp && !skipBecauseUncached) { event.respondWith( (async () => { const cachedAsset = isStaticAsset && (await caches.match(event.request)); return cachedAsset || fetchAndCache(event.request); })() ) } })