self.addEventListener("install", (event) => { console.info("Service worker installed.", event) }) self.addEventListener("activate", (event) => { console.info("Service worker activated.", event) }) const CACHE_NAME = "APP-V0" const FILES_TO_CACHE = [ "/index.html", "/js/app.js", "/manifest.json", ] const FILE_ALIASES = new Map([ ["/", "/index.html"] ]) const normalizeUrl = (url) => { const url_ = new URL(url) url_.pathname = url_.pathname.replace(/\/+/g, "/").replace(/\/$/, "") if (FILE_ALIASES.has(url_.pathname)) { url_.pathname = FILE_ALIASES.get(url_.pathname) } return url_.href } self.addEventListener("install", async (event) => { const cache = await caches.open(CACHE_NAME) const additions = cache.addAll(FILES_TO_CACHE) await additions console.info(`Files cached: [\n ${FILES_TO_CACHE.join(`,\n `)}\n]`) }) self.addEventListener("activate", async (event) => { const oldCacheKeys = (await caches.keys()).filter((key) => key != CACHE_NAME) oldCacheKeys.forEach((key) => caches.delete(key)) }) self.addEventListener("fetch", (event) => { const normalizedUrl = normalizeUrl(event.request.url) let response = fetch(event.request) if (FILES_TO_CACHE.includes(normalizedUrl)) { response = response .then(async (response) => { const cache = await caches.open(CACHE_NAME) await cache.put(normalizedUrl, response.clone()) return response }) .catch(() => caches.match(normalizedUrl)) .catch(e => null) } event.respondWith( fetch(event.request) .then(async (response) => { if (FILES_TO_CACHE.includes(new URL(normalizedUrl).pathname)) { const cache = await caches.open(CACHE_NAME) await cache.put(normalizedUrl, response.clone()) } return response }) .catch(() => caches.match(normalizedUrl)) .catch(e => null) ) })