|
| 1 | +'use strict'; |
| 2 | + |
| 3 | +// Serve the static files of the compiled Adminer from the Cache Storage. |
| 4 | +// The HTTP cache is enough almost everywhere but some hosts forbid caching anything their |
| 5 | +// interface generates, and Adminer generates its own files. Cache Storage is filled by |
| 6 | +// explicit put() calls so those headers don't apply to it. |
| 7 | + |
| 8 | +// this script is served from <Adminer URL>?file=worker.js&version=<version>, the rest follows from that |
| 9 | +const prefix = self.location.href.replace(/worker\.js&version=.*/, ''); |
| 10 | +const version = self.location.href.replace(/.*&version=/, ''); |
| 11 | +const cacheName = 'adminer-' + version; |
| 12 | + |
| 13 | +// don't wait for the tabs of the previous version to close |
| 14 | +self.addEventListener('install', () => self.skipWaiting()); |
| 15 | + |
| 16 | +self.addEventListener('activate', event => { |
| 17 | + event.waitUntil(self.clients.claim().then(() => caches.keys()).then(keys => Promise.all( |
| 18 | + keys.filter(key => key != cacheName && key.startsWith('adminer-')).map(key => caches.delete(key)) |
| 19 | + ))); |
| 20 | +}); |
| 21 | + |
| 22 | +self.addEventListener('fetch', event => { |
| 23 | + const url = event.request.url; |
| 24 | + if ( |
| 25 | + event.request.method != 'GET' |
| 26 | + || !url.startsWith(prefix) |
| 27 | + || !url.endsWith('&version=' + version) // a file of another version, its cache is deleted on activate |
| 28 | + || url == self.location.href // the browser fetches this script bypassing this handler but a cached service worker could never be replaced |
| 29 | + ) { |
| 30 | + return; // not ours - do nothing, which lets the browser handle it as if there was no service worker |
| 31 | + } |
| 32 | + event.respondWith(caches.open(cacheName) |
| 33 | + .then(cache => cache.match(event.request).then(cached => cached || fetch(event.request).then(response => { |
| 34 | + if (response.ok) { |
| 35 | + // the version in the URL makes the file immutable so it is never revalidated; waitUntil keeps the worker alive until it is stored |
| 36 | + event.waitUntil(cache.put(event.request, response.clone())); |
| 37 | + } |
| 38 | + return response; |
| 39 | + }))) |
| 40 | + .catch(() => fetch(event.request)) // a broken cache must not make Adminer unreachable |
| 41 | + ); |
| 42 | +}); |
0 commit comments