-
Notifications
You must be signed in to change notification settings - Fork 12
/
sw.js
66 lines (56 loc) · 2.09 KB
/
sw.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
// sw.js
// CACHE_NAMESPACE
// CacheStorage is shared between all sites under same domain.
// A namespace can prevent potential name conflicts and mis-deletion.
const CACHE_NAMESPACE = 'mmpwa-'
const PRECACHE = CACHE_NAMESPACE + 'precache-v3'
const PRECACHE_LIST = [
'./offline.html'
]
const RUNTIME = CACHE_NAMESPACE + 'runtime-v1'
const expectedCaches = [PRECACHE, RUNTIME]
self.oninstall = (event) => {
event.waitUntil(
caches.open(PRECACHE)
.then(cache => cache.addAll(PRECACHE_LIST))
.then(self.skipWaiting())
.catch(err => console.log(err))
)
}
self.onactivate = (event) => {
// delete any cache not match expectedCaches for migration.
// noticed that we delete by cache instead of by request here.
// so we MUST filter out caches opened by this app firstly.
// check out sw-precache or workbox-build for an better way.
event.waitUntil(
caches.keys().then(cacheNames => Promise.all(
cacheNames
.filter(cacheName => cacheName.startsWith(CACHE_NAMESPACE))
.filter(cacheName => !expectedCaches.includes(cacheName))
.map(cacheName => caches.delete(cacheName))
))
)
}
self.onfetch = (event) => {
// Fastest-while-revalidate
const cached = caches.match(event.request);
const fixedUrl = `${event.request.url}?${Date.now()}`;
const fetched = fetch(fixedUrl, {cache: "no-store"});
const fetchedCopy = fetched.then(resp => resp.clone());
console.log(`fetch ${fixedUrl}`)
// Call respondWith() with whatever we get first.
// If the fetch fails (e.g disconnected), wait for the cache.
// If there’s nothing in cache, wait for the fetch.
// If neither yields a response, return offline pages.
event.respondWith(
Promise.race([fetched.catch(_ => cached), cached])
.then(resp => resp || fetched)
.catch(_ => caches.match('offline.html'))
);
// Update the cache with the version we fetched (only for ok status)
event.waitUntil(
Promise.all([fetchedCopy, caches.open(RUNTIME)])
.then(([response, cache]) => response.ok && cache.put(event.request, response))
.catch(_ => {/* eat any errors */})
);
}