History

Service worker refactoring

Jasper van Merle committed 7 years ago

Commit ec8616e1 parent 8ed1f4a2 files · +29 −41Browse files

Unified · Split

2 files
  1. assets/javascripts/app/serviceworker.coffee +5 −13
  2. views/service-worker.js.erb +24 −28
assets/javascripts/app/serviceworker.coffee+5−13
@@ -6,7 +6,6 @@ class app.ServiceWorker · 5 unmodified lines
6 6
7 constructor: ->7 constructor: ->
8 @registration = null8 @registration = null
9 @installingRegistration = null
10 @notifyUpdate = true9 @notifyUpdate = true
11 10
12 navigator.serviceWorker.register(app.config.service_worker_path, {scope: '/'})11 navigator.serviceWorker.register(app.config.service_worker_path, {scope: '/'})
@@ -16,37 +15,30 @@ class app.ServiceWorker · 3 unmodified lines
16 update: ->15 update: ->
17 return unless @registration16 return unless @registration
18 @notifyUpdate = true17 @notifyUpdate = true
19 return @doUpdate()18 return @registration.update().catch(->)
20 19
21 updateInBackground: ->20 updateInBackground: ->
22 return unless @registration21 return unless @registration
23 @notifyUpdate = false22 @notifyUpdate = false
24 return @doUpdate()23 return @registration.update().catch(->)
25 24
26 reload: ->25 reload: ->
27 return @updateInBackground().then(() -> app.reboot())26 return @updateInBackground().then(() -> app.reboot())
28 27
29 doUpdate: ->
30 return @registration.update().catch(->)
31
32 updateRegistration: (registration) ->28 updateRegistration: (registration) ->
33 $.off @registration, 'updatefound', @onUpdateFound if @registration
34 $.off @installingRegistration, 'statechange', @onStateChange if @installingRegistration
35
36 @registration = registration29 @registration = registration
37 @installingRegistration = null
38
39 $.on @registration, 'updatefound', @onUpdateFound30 $.on @registration, 'updatefound', @onUpdateFound
40 return31 return
41 32
42 onUpdateFound: () =>33 onUpdateFound: () =>
34 $.off @installingRegistration, 'statechange', @onStateChange() if @installingRegistration
43 @installingRegistration = @registration.installing35 @installingRegistration = @registration.installing
44 $.on @installingRegistration, 'statechange', @onStateChange36 $.on @installingRegistration, 'statechange', @onStateChange
45 return37 return
46 38
47 onStateChange: () =>39 onStateChange: () =>
48 if @installingRegistration.state == 'installed' and navigator.serviceWorker.controller40 if @installingRegistration and @installingRegistration.state == 'installed' and navigator.serviceWorker.controller
49 @updateRegistration(@installingRegistration)41 @installingRegistration = null
50 @onUpdateReady()42 @onUpdateReady()
51 return43 return
52 44
views/service-worker.js.erb+24−28
@@ -1,4 +1,4 @@
1<%# Use the hash of the application.js file as cache name, or 'app' if not running in production %>1<%# Use the hash of the application.js file as cache name or 'app' if not running in production %>
2<%# This ensures that the cache is always updated if the hash of the application.js file changes %>2<%# This ensures that the cache is always updated if the hash of the application.js file changes %>
3const cacheName = '<%= javascript_path('application', asset_host: false).scan(/application-([^\.]+)\.js/).last&.first || 'app' %>';3const cacheName = '<%= javascript_path('application', asset_host: false).scan(/application-([^\.]+)\.js/).last&.first || 'app' %>';
4 4
@@ -28,37 +28,33 @@ self.addEventListener('install', event => { · 23 unmodified lines
28 28
29<%# Remove old caches %>29<%# Remove old caches %>
30self.addEventListener('activate', event => {30self.addEventListener('activate', event => {
31 event.waitUntil(31 event.waitUntil((async () => {
32 caches.keys().then(keys => Promise.all(32 const keys = await caches.keys();
33 keys.map(key => {33 const jobs = keys.map(key => key !== cacheName ? caches.delete(key) : Promise.resolve());
34 if (key !== cacheName) {34 return await Promise.all(jobs);
35 return caches.delete(key);35 })());
36 }
37 })
38 ))
39 );
40});36});
41 37
42<%# Handle HTTP requests %>38<%# Handle HTTP requests %>
43self.addEventListener('fetch', event => {39self.addEventListener('fetch', event => {
44 event.respondWith(40 event.respondWith((async () => {
45 caches.match(event.request).then(response => {41 const cachedResponse = await caches.match(event.request);
46 if (response) {42 if (cachedResponse) return cachedResponse;
47 return response;43
44 try {
45 const response = await fetch(event.request);
46 return response;
47 } catch (err) {
48 const url = new URL(event.request.url);
49
50 <%# Attempt to return the index page from the cache if the user is visiting a url like devdocs.io/javascript/global_objects/array/find %>
51 <%# The index page will make sure the correct documentation or a proper offline page is shown %>
52 if (url.origin === location.origin && !url.pathname.includes('.')) {
53 const cachedIndex = await caches.match('/');
54 if (cachedIndex) return cachedIndex;
48 }55 }
49 56
50 return fetch(event.request)57 throw err;
51 .catch(err => {58 }
52 const url = new URL(event.request.url);59 })());
53
54 <%# Return the index page from the cache if the user is visiting a url like devdocs.io/javascript/global_objects/array/find %>
55 <%# The index page will make sure the correct documentation or a proper offline page is shown %>
56 if (url.origin === location.origin && !url.pathname.includes('.')) {
57 return caches.match('/').then(response => response || err);
58 }
59
60 return err;
61 });
62 })
63 );
64});60});