diff --git a/src/service-worker.ts b/src/service-worker.ts index 7d09cc8..2e12c9a 100644 --- a/src/service-worker.ts +++ b/src/service-worker.ts @@ -1,20 +1,43 @@ /* eslint-disable no-var */ import { build, files, version } from '$service-worker'; -const worker = (self as unknown) as ServiceWorkerGlobalScope; +// Code mostly comes from: https://dev.to/100lvlmaster/create-a-pwa-with-sveltekit-svelte-a36 +// With some modifications done by someone in the comments -const FILES = `cache${version}`; +const worker = (self as unknown) as ServiceWorkerGlobalScope; +const STATIC_CACHE_NAME = `cache${version}` +const APP_CACHE_NAME = `cache${version}`; + +// Hardcoded bunch of routes to always preemptively cache +const routes = ["/", "/about"]; + +// Hardcoded list of other assets to always preemptively cache +const custom_assets = [ + "https://fonts.googleapis.com/css2?family=Montserrat:wght@200&family=Roboto+Flex:opsz,wght@8..144,300;8..144,400;8..144,500&family=Roboto+Slab&display=swap" +]; + +// Adds the domain to the file path, making it a full name +const addDomain = (assets: string[]) => + assets.map((f) => self.location.origin + f); // 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 ourAssets = addDomain([ + ...files, + ...build, + ...routes +]); + +const to_cache = [...ourAssets, ...custom_assets] const staticAssets = new Set(to_cache); worker.addEventListener("install", (event) => { event.waitUntil( caches - .open(FILES) - .then((cache) => cache.addAll(to_cache)) + .open(STATIC_CACHE_NAME) + .then((cache) => { + return cache.addAll(to_cache) + }) .then(() => { worker.skipWaiting(); }) @@ -27,7 +50,7 @@ worker.addEventListener("activate", (event) => { .then(async (keys) => { // Delete old caches for (const key of keys) { - if (key !== FILES) await caches.delete(key); + if (key !== STATIC_CACHE_NAME && key !== APP_CACHE_NAME) await caches.delete(key); } console.log("old caches deleted") worker.clients.claim(); @@ -39,7 +62,7 @@ worker.addEventListener("activate", (event) => { // 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}`); + const cache = await caches.open(APP_CACHE_NAME); try { const response = await fetch(request); @@ -56,8 +79,8 @@ async function fetchAndCache(request: Request) { worker.addEventListener("fetch", (event) => { if (event.request.method !== "GET") return; - - console.log("fetch event intercepted") + + //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/ @@ -68,12 +91,15 @@ worker.addEventListener("fetch", (event) => { // 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 isStaticAsset = staticAssets.has(url.href); const skipBecauseUncached = event.request.cache === 'only-if-cached' && !isStaticAsset; if (isHttp && !skipBecauseUncached) { event.respondWith( (async () => { + // always serve static files and bundler-generated assets from cache. + // if your application has other URLs with data that will never change, + // set this variable to true for them, and they will only be fetched once. const cachedAsset = isStaticAsset && (await caches.match(event.request)); return cachedAsset || fetchAndCache(event.request);