+'use strict';
+
+const internals = {
+ version: '1',
+ offlineEssentials: [
+ '/',
+ '/css/application.css'
+ ],
+
+ // Response for when network is not available
+
+ errorResponse: '<h1>Service Unavailable</h1>',
+
+ // Main entry point, adds event listeners for service worker
+
+ main() {
+
+ self.addEventListener('install', internals.onInstall);
+ self.addEventListener('fetch', internals.onFetch);
+ self.addEventListener('activate', internals.onActivate);
+ },
+
+ // Runs on installation of the service worker
+
+ onInstall(event) {
+
+ event.waitUntil(
+ caches.open(`${internals.version}/essentials`)
+ .then((cache) => {
+
+ return cache.addAll(internals.offlineEssentials)
+ })
+ );
+ },
+
+ // Runs when a path is fetched, returns files from cache
+
+ onFetch(event) {
+
+ if (event.request.method !== 'GET') {
+ return;
+ }
+
+ event.respondWith(
+ caches.match(event.request)
+ .then((cached) => {
+
+ const freshContent = fetch(event.request)
+ .then((response) => {
+
+ caches.open(`${internals.version}/paths`)
+ .then((cache) => cache.put(event.request, response.clone()));
+ }, internals.onFetchFail)
+ .catch(internals.onFetchFail);
+
+ return cached || freshContent;
+ })
+ );
+ },
+
+ onActivate(event) {
+
+ event.waitUntil(
+ caches.keys()
+ .then((keys) => {
+
+ return Promise.all(keys
+ .filter((key) => !key.startsWith(internals.version))
+ .map((key) => caches.delete(key))
+ );
+ })
+ );
+ },
+
+ // Responds with Servie Unavailable if we can't fetch a
+ // file from network
+
+ onFetchFail() {
+
+ return new Response(internals.errorResponse, {
+ status: 503,
+ statusText: 'Service Unavailable',
+ headers: new Headers({
+ 'Content-Type': 'text/html'
+ })
+ });
+ }
+};
+
+internals.main();