function log(...params) { console.log.apply(this, [ ...["%c[SW]: %c", "color: #f4b942;", "color:unset;"], ...params, ]); } const CACHE = "offline"; let precacheFiles = ["/", "/index.html"]; //Install stage sets up the cache-array to configure pre-cache content self.addEventListener("install", (evt) => { log("The service worker is being installed."); evt.waitUntil( precache() .then(() => { log("Skip waiting on install"); }) .catch(log) .then(() => self.skipWaiting()) ); }); //allow sw to control of current page self.addEventListener("activate", (event) => { log("Claiming clients for current page"); return self.clients.claim(); }); self.addEventListener("message", (event) => { log("Clearing cache"); caches.delete(CACHE); event.waitUntil(precache()); }); var Types; (function (Types) { Types[(Types["CACHE"] = 0)] = "CACHE"; Types[(Types["NOCACHE"] = 1)] = "NOCACHE"; Types[(Types["REFRESH"] = 2)] = "REFRESH"; Types[(Types["INDEX"] = 3)] = "INDEX"; })(Types || (Types = {})); let rules = [ { match: (url) => { return url.indexOf("/api/") >= 0; }, type: Types.NOCACHE, }, { match: (url) => { return url.indexOf("/share") >= 0; }, type: Types.INDEX, }, { match: () => { return true; }, type: Types.REFRESH, }, ]; self.addEventListener("fetch", (evt) => { if (evt.request.method != "GET") return; // Dont care about POST requests let rule = rules.find((rule) => rule.match(evt.request.url)); evt.respondWith( (async () => { log("Cache:", Types[rule.type]); switch (rule.type) { case Types.CACHE: return fromCache(evt.request); case Types.REFRESH: return refresh(evt.request).then((r) => { evt.waitUntil(r.refresh.catch((_) => {})); return r.result; }); case Types.NOCACHE: return fetch(evt.request); case Types.INDEX: return refresh(new Request("/")).then((r) => { evt.waitUntil(r.refresh.catch((_) => {})); return r.result; }); } })() ); }); async function fromCache(request) { let cache = await caches.open(CACHE); let matching = await cache.match(request); if (matching) return matching; let res = await fetch(request.clone()); await cache.put( request, { match: (url) => { return url.indexOf("/version_hash") >= 0; }, type: Types.NOCACHE, }, res ); return await cache.match(request); } async function refresh(request) { let cache = await caches.open(CACHE); let web = fetch(request.clone()).then((res) => { return cache.put(request, res).then(() => { return cache.match(request); }); }); let matching = await cache.match(request); return { result: matching ? matching : web, refresh: web, }; } function precache() { return caches.open(CACHE).then(function (cache) { return cache.addAll(precacheFiles); }); }