121 lines
3.2 KiB
JavaScript
121 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",
|
|
"/main.js",
|
|
"/main.css",
|
|
"/serviceworker.js"
|
|
]
|
|
|
|
//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);
|
|
});
|
|
} |