Small improvements:
- Switch to CodeMirror - Switch to Parcel Bundler - Fix synchronisation bug - Update dependencies
This commit is contained in:
130
src/serviceworker.js
Normal file
130
src/serviceworker.js
Normal file
@ -0,0 +1,130 @@
|
||||
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);
|
||||
});
|
||||
}
|
Reference in New Issue
Block a user