This repository has been archived by the owner on Feb 21, 2018. It is now read-only.
/
sw.js
103 lines (92 loc) · 2.66 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
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
// vecka.14islands.com/service-worker.js
// https://github.com/14islands/vecka.14islands.com/blob/master/server/service-worker.js
const ASSETS_CACHE = 'assets-v1.2'
const PAGES_CACHE = 'pages-v1.2'
const expectedCaches = [ASSETS_CACHE, PAGES_CACHE]
const urlsToCache = [
'/assets/css/main.css',
'/assets/js/main.js',
'/manifest.json',
'/offline.html',
]
self.addEventListener('install', (event) => {
event.waitUntil(
caches.open(ASSETS_CACHE)
.then((cache) => {
console.log('Opened cache')
return cache.addAll(urlsToCache)
})
)
})
function matchPath(path) {
return regExp => regExp.test(path)
}
self.addEventListener('fetch', (event) => {
if (!shouldHandleFetch(event.request)) return
const request = event.request
const url = new URL(request.url)
const match = matchPath(url.pathname)
if (request.headers.get('accept').includes('text/html')) {
respondFromNetworkThenCache(event, PAGES_CACHE)
} else if (match(/^\/(css|fonts|js|assets)\/.*$/)) {
respondFromCacheThenNetwork(event, ASSETS_CACHE)
}
})
self.addEventListener('activate', (event) => {
event.waitUntil(
caches.keys().then(keys =>
Promise.all(
keys.map((key) => {
if (expectedCaches.includes(key)) return undefined
return caches.delete(key)
})
)
).then(() => {
console.log('now ready to handle fetches.')
})
)
})
function fetchFromCache(request) {
return caches.match(request).then((response) => {
if (response) {
return response
}
throw Error(`${request.url} not found in cache`)
})
}
function putCache(request, response, key) {
if (response.ok) {
const copy = response.clone()
caches.open(key).then((cache) => {
cache.put(request, copy)
})
}
return response
}
function offlineResponse(request) {
if (!request.headers.get('accept').includes('text/html')) return undefined
return caches.match('offline.html')
}
function respondFromCacheThenNetwork(event, key) {
const request = event.request
event.respondWith(
fetchFromCache(request)
.catch(() => fetch(request.clone()))
.then(response => putCache(request, response, key))
.catch(() => offlineResponse(request))
)
}
function respondFromNetworkThenCache(event, key) {
const request = event.request
event.respondWith(
fetch(request.clone())
.then(response => putCache(request, response, key))
.catch(() => fetchFromCache(request))
.catch(() => offlineResponse(request))
)
}
function shouldHandleFetch(request) {
const url = new URL(request.url)
const should = request.method.toLowerCase() === 'get' && url.origin === location.origin
return should
}