From ec8616e289fc1b2eff7cdd623d1713f00fee1f68 Mon Sep 17 00:00:00 2001 From: Jasper van Merle Date: Sun, 7 Jul 2019 03:25:42 +0200 Subject: [PATCH] Service worker refactoring --- assets/javascripts/app/serviceworker.coffee | 18 ++----- views/service-worker.js.erb | 52 ++++++++++----------- 2 files changed, 29 insertions(+), 41 deletions(-) diff --git a/assets/javascripts/app/serviceworker.coffee b/assets/javascripts/app/serviceworker.coffee index 2faab8f2..8bdd5064 100644 --- a/assets/javascripts/app/serviceworker.coffee +++ b/assets/javascripts/app/serviceworker.coffee @@ -6,7 +6,6 @@ class app.ServiceWorker constructor: -> @registration = null - @installingRegistration = null @notifyUpdate = true navigator.serviceWorker.register(app.config.service_worker_path, {scope: '/'}) @@ -16,37 +15,30 @@ class app.ServiceWorker update: -> return unless @registration @notifyUpdate = true - return @doUpdate() + return @registration.update().catch(->) updateInBackground: -> return unless @registration @notifyUpdate = false - return @doUpdate() + return @registration.update().catch(->) reload: -> return @updateInBackground().then(() -> app.reboot()) - doUpdate: -> - return @registration.update().catch(->) - updateRegistration: (registration) -> - $.off @registration, 'updatefound', @onUpdateFound if @registration - $.off @installingRegistration, 'statechange', @onStateChange if @installingRegistration - @registration = registration - @installingRegistration = null - $.on @registration, 'updatefound', @onUpdateFound return onUpdateFound: () => + $.off @installingRegistration, 'statechange', @onStateChange() if @installingRegistration @installingRegistration = @registration.installing $.on @installingRegistration, 'statechange', @onStateChange return onStateChange: () => - if @installingRegistration.state == 'installed' and navigator.serviceWorker.controller - @updateRegistration(@installingRegistration) + if @installingRegistration and @installingRegistration.state == 'installed' and navigator.serviceWorker.controller + @installingRegistration = null @onUpdateReady() return diff --git a/views/service-worker.js.erb b/views/service-worker.js.erb index 74ce45b2..498ef716 100644 --- a/views/service-worker.js.erb +++ b/views/service-worker.js.erb @@ -1,4 +1,4 @@ -<%# Use the hash of the application.js file as cache name, or 'app' if not running in production %> +<%# Use the hash of the application.js file as cache name or 'app' if not running in production %> <%# This ensures that the cache is always updated if the hash of the application.js file changes %> const cacheName = '<%= javascript_path('application', asset_host: false).scan(/application-([^\.]+)\.js/).last&.first || 'app' %>'; @@ -28,37 +28,33 @@ self.addEventListener('install', event => { <%# Remove old caches %> self.addEventListener('activate', event => { - event.waitUntil( - caches.keys().then(keys => Promise.all( - keys.map(key => { - if (key !== cacheName) { - return caches.delete(key); - } - }) - )) - ); + event.waitUntil((async () => { + const keys = await caches.keys(); + const jobs = keys.map(key => key !== cacheName ? caches.delete(key) : Promise.resolve()); + return await Promise.all(jobs); + })()); }); <%# Handle HTTP requests %> self.addEventListener('fetch', event => { - event.respondWith( - caches.match(event.request).then(response => { - if (response) { - return response; + event.respondWith((async () => { + const cachedResponse = await caches.match(event.request); + if (cachedResponse) return cachedResponse; + + try { + const response = await fetch(event.request); + return response; + } catch (err) { + const url = new URL(event.request.url); + + <%# Attempt to return the index page from the cache if the user is visiting a url like devdocs.io/javascript/global_objects/array/find %> + <%# The index page will make sure the correct documentation or a proper offline page is shown %> + if (url.origin === location.origin && !url.pathname.includes('.')) { + const cachedIndex = await caches.match('/'); + if (cachedIndex) return cachedIndex; } - return fetch(event.request) - .catch(err => { - const url = new URL(event.request.url); - - <%# Return the index page from the cache if the user is visiting a url like devdocs.io/javascript/global_objects/array/find %> - <%# The index page will make sure the correct documentation or a proper offline page is shown %> - if (url.origin === location.origin && !url.pathname.includes('.')) { - return caches.match('/').then(response => response || err); - } - - return err; - }); - }) - ); + throw err; + } + })()); });