Skip to content

Instantly share code, notes, and snippets.

@eusonlito
Last active August 28, 2018 09:28
Show Gist options
  • Save eusonlito/cbfeae6963dcfab62add15ac36417555 to your computer and use it in GitHub Desktop.
Save eusonlito/cbfeae6963dcfab62add15ac36417555 to your computer and use it in GitHub Desktop.
Service Worker loader and installer
if ('serviceWorker' in navigator) {
window.addEventListener('load', function() {
navigator.serviceWorker.register('/service-worker.js').catch(function(e) {
console.error('Error during service worker registration:', e);
});
});
}
const version = 'v1';
self.addEventListener('install', event => {
event.waitUntil(
caches.open(version).then(cache => {
return cache.addAll(['/offline', '/images/network-error.svg']);
})
);
});
self.addEventListener('fetch', event => {
if (!isCacheable(event.request)) {
return;
}
switch (event.request.destination) {
case 'style':
case 'script':
case 'image':
case 'font':
event.respondWith(firstCacheThenNetwork(event.request, 'asset'));
break;
default:
event.respondWith(firstNetworkThenCache(event.request, 'page'));
break;
}
});
function isCacheable(request) {
return (request.method === 'GET')
&& (request.headers.get('X-Requested-With') !== 'XMLHttpRequest')
&& !request.url.match(/images\/large/);
}
function firstCacheThenNetwork(request, type) {
return caches.match(request).then(cached => {
const networked = fetch(request).then(response => {
return store(request, response, type);
}).catch(() => {
return;
});
return cached || networked;
});
}
function firstNetworkThenCache(request, type) {
return fetch(request).then(response => {
return store(request, response, type);
}).catch(e => {
return caches.match(request).then(cached => {
return cached ? cached : error(request, e);
});
});
}
function store(request, response, type) {
if (!response || (response.status !== 200)) {
return response;
}
return caches.open(version + '/' + type).then(cache => {
return cache.put(request, response.clone()).then(() => {
return response;
});
});
}
function error(request, e) {
switch (request.destination) {
case 'style':
return errorStyle();
case 'script':
return errorScript();
case 'image':
return errorImage();
case 'font':
return errorFont();
default:
return errorPage();
}
}
function errorStyle() {
return setResponse('', 'text/css');
}
function errorScript() {
return setResponse('', 'application/javascript');
}
function errorImage() {
return caches.match('/images/network-error.svg').then(cached => {
return cached ? cached : setResponse('', 'image/svg+xml');
});
}
function errorFont() {
return setResponse('', 'application/font-woff2');
}
function errorPage() {
return caches.match('/offline').then(cached => {
return cached ? cached : setResponse('D\'oh!, no connection :(', 'text/html');
});
}
function setResponse(message, contentType) {
return new Response(message, {
status: 503,
statusText: 'Service Unavailable',
headers: { 'Content-Type': contentType }
});
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment