const STATIC = "static";
const RESOURCES = "resources";
self.addEventListener("install", event => event.waitUntil(
Promise.all([
self.skipWaiting(),
caches.delete(STATIC),
caches.delete(RESOURCES),
]).then(() => Promise.all([
caches.open(STATIC).then(cache => cache.addAll([
"/main.js",
"/index.html",
])),
]))));
self.addEventListener("activate", event => event.waitUntil(clients.claim()));
self.addEventListener("sync", event =>
event.waitUntil(
Promise.all([
clients.claim(),
caches.delete(RESOURCES),
])
)
)
const base64Fixer = c => c.charCodeAt(0);
const utf8base64ToUint8Array = payload => {
const brokenPayload = atob(payload);
return Uint8Array.from(brokenPayload, base64Fixer);
};
const responseFromBuffer = (
buffer,
contentType,
etag
) => {
const headers = new Headers({
"Content-Length": buffer.length.toString(),
"Content-Type": contentType,
});
if (etag) {
headers.append("ETag", etag);
}
return new Response(buffer, { status: 200, headers });
};
const createResponseFromAttachment = (
{
data,
contentType = "application/javascript",
},
etag
) => responseFromBuffer(utf8base64ToUint8Array(data), contentType, etag);
const handleEntryRequest = async event => {
try {
const base = event.request.url.substring(event.request.url.indexOf("/entries/"));
const nextSeparator = base.indexOf("/", 9);
const nextDot = base.indexOf(".", 9);
let endIndex;
if (nextSeparator !== -1 && nextDot !== -1) {
endIndex = Math.min(nextSeparator, nextDot);
} else if (nextSeparator !== -1) {
endIndex = nextSeparator
} else if (nextDot !== -1) {
endIndex = nextDot;
}
const response = await fetch(`${base.substring(0, endIndex).replace("/entries/", "/resources/")}.json`);
const data = await response.json();
const cache = await caches.open(RESOURCES);
/*for (const requestUrl in data) {
console.log(requestUrl)
const contentType = requestUrl.endsWith(".css") ? "text/css" : "application/javascript";
await cache.put(requestUrl, createResponseFromAttachment({
data: data[requestUrl],
contentType,
}, response.headers.get("ETag")));
}*/
console.log('matching', base);
return cache.match(base).then(async resp => {
console.log('opening', base);
if (!resp && data[base]) {
let requestUrl = base;
const contentType = requestUrl.endsWith(".css") ? "text/css" : "application/javascript";
resp = createResponseFromAttachment({
data: data[requestUrl],
contentType,
}, response.headers.get("ETag"));
cache.put(requestUrl, resp.clone())
//await cache.put(requestUrl, resp);
// resp = await cache.match(base);
}
console.log('opened', base);
return resp || new Response(undefined, { status: 404 })
});
// return cache.then(cache => cache.match(base)).then(resp => resp || new Response(undefined, { status: 404 }));
} catch (e) {
console.log(e)
}
};
self.addEventListener("fetch", event => {
if (event.request.url.includes("/entries/")) {
event.respondWith(handleEntryRequest(event));
} else if (event.request.url.endsWith("/main.js") || event.request.url.endsWith("/index.html")) {
return event.respondWith(
caches.open(STATIC)
.then(cache => cache.match(event.request))
.then(match => match || fetch(event.request))
);
} else {
console.log('error', event.request.url)
}
});