Skip to content

Instantly share code, notes, and snippets.

@jakearchibald

jakearchibald/sw.js Secret

Created Jun 2, 2016
Embed
What would you like to do?
const staticCacheName = 'static-e6350322ee01';
const expectedCaches = [
staticCacheName
];
self.addEventListener('install', event => {
self.skipWaiting();
event.waitUntil(
caches.open(staticCacheName)
.then(cache => cache.addAll([
"/shell-start.cbd594dfa81d.inc",
"/shell-end.cbd594dfa81d.inc",
"/offline.d989ddb2d13b.inc",
"/error.ba6821d4f751.inc",
"https://themes.googleusercontent.com/static/fonts/inconsolata/v6/BjAYBlHtW3CJxDcjzrnZCCwlidHJgAgmTjOEEzwu1L8.ttf",
"https://themes.googleusercontent.com/static/fonts/ptserif/v5/EgBlzoNBIHxNPCMwXaAhYHYhjbSpvc47ee6xR_80Hnw.ttf",
"/static/js/main.6e994df71e3d.js",
"/static/css/all.9281a377cb2c.css"
]))
);
});
// remove caches that aren't in expectedCaches
self.addEventListener('activate', event => {
event.waitUntil(
caches.keys().then(keys => Promise.all(
keys.map(key => {
if (!expectedCaches.includes(key)) return caches.delete(key);
})
))
);
});
function createPageStream(request) {
const stream = new ReadableStream({
start(controller) {
// the body url is the request url plus 'include'
const url = new URL(request.url);
url.pathname += 'include';
const startFetch = caches.match('/shell-start.cbd594dfa81d.inc');
const endFetch = caches.match('/shell-end.cbd594dfa81d.inc');
const middleFetch = fetch(url).then(response => {
if (!response.ok && response.status != 404) {
return caches.match('/error.ba6821d4f751.inc');
}
return response;
}).catch(err => caches.match('/offline.d989ddb2d13b.inc'));
function pushStream(stream) {
const reader = stream.getReader();
return reader.read().then(function process(result) {
if (result.done) return;
controller.enqueue(result.value);
return reader.read().then(process);
});
}
startFetch
.then(response => pushStream(response.body))
.then(() => middleFetch)
.then(response => pushStream(response.body))
.then(() => endFetch)
.then(response => pushStream(response.body))
.then(() => controller.close());
}
});
return new Response(stream, {
headers: {'Content-Type': 'text/html; charset=utf-8'}
});
}
self.addEventListener('fetch', event => {
const url = new URL(event.request.url);
if (url.origin === location.origin) {
// home or article pages
if (url.pathname === '/' || /^\/20\d\d\/[a-z0-9-]+\/$/.test(url.pathname)) {
event.respondWith(createPageStream(event.request));
return;
}
}
// cache-first for the rest
event.respondWith(
caches.match(event.request).then(r => r || fetch(event.request))
);
});
@Satys

This comment has been minimized.

Copy link

@Satys Satys commented Oct 19, 2017

This looks something great, I am going to try it out!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment