-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathOneSignalSDKWorker.js
75 lines (74 loc) · 3.13 KB
/
OneSignalSDKWorker.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
importScripts('https://cdn.onesignal.com/sdks/OneSignalSDKWorker.js')
class MasterServiceWorker {
constructor() {
this.name = 'ServiceWorker'
this.version = 'v26'
this.precache = [
'./',
'./index.html',
'./manifest.json',
'./favicon.gif'
]
this.doNotIntercept = []
this.doIntercept = [location.origin]
}
run() {
this.addInstallEventListener()
this.addActivateEventListener()
this.addFetchEventListener()
}
// onInstall init cache
addInstallEventListener() {
self.addEventListener('install', event => event.waitUntil(caches.open(this.version).then(cache => cache.addAll(this.precache))))
}
// onActivate clear old caches to avoid conflict
addActivateEventListener(){
self.addEventListener('activate', event => event.waitUntil(caches.keys().then(keyList => Promise.all(keyList.map(key => key !== this.version ? caches.delete(key) : undefined)))))
}
// 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.some(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()