-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathMasterServiceWorker.js
executable file
·66 lines (66 loc) · 2.05 KB
/
MasterServiceWorker.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
class MasterServiceWorker {
constructor(){
this.name = 'ServiceWorker'
this.version = 'v1'
this.precache = [
'./',
'./favicon.gif'
]
this.doNotIntercept = []
this.doIntercept = [location.origin]
}
run(){
this.addInstallEventListener()
this.addFetchEventListener()
}
// onInstall init cache
addInstallEventListener() {
self.addEventListener('install', event => event.waitUntil(caches.open(this.version).then(cache => cache.addAll(this.precache))))
}
// intercepts fetches, asks cache for fast response and still fetches and caches afterwards
addFetchEventListener() {
self.addEventListener('fetch', event => event.respondWith(
this.doNotIntercept.every(url => !event.request.url.includes(url)) && this.doIntercept.every(url => event.request.url.includes(url))
? new Promise((resolve, reject) => {
let counter = 0
let didResolve = false
const doResolve = response => {
counter++
if(!didResolve){
if(response){
didResolve = true
resolve(response)
}else if (counter >= 2){ // two which race, when none resulted in any useful response, reject
reject(response)
}
}
return response || new Error(`No response for ${event.request.url}`)
}
// race fetch vs. cache to resolve
this.getFetch(event).then(response => doResolve(response)).catch(error => { // start fetching and caching
console.info(`Can't fetch ${event.request.url}`, error)
})
this.getCache(event).then(response => doResolve(response)).catch(error => { // grab cache
console.info(`Can't get cache ${event.request.url}`, error)
})
})
: fetch(event.request)
))
}
async getCache(event){
return await caches.match(event.request)
}
async getFetch(event){
return await fetch(event.request).then(
response => caches.open(this.version).then(
cache => {
//console.log('cached', event.request.url)
cache.put(event.request, response.clone())
return response
}
)
)
}
}
const ServiceWorker = new MasterServiceWorker()
ServiceWorker.run()