131 lines
3.2 KiB
JavaScript
131 lines
3.2 KiB
JavaScript
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);
|
|
});
|
|
}
|