forked from theninthsky/client-side-rendering
-
-
Notifications
You must be signed in to change notification settings - Fork 0
/
service-worker.js
56 lines (41 loc) · 1.76 KB
/
service-worker.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
const CACHE_NAME = 'client-side-rendering'
const CACHED_URLS = ['/', ...self.__WB_MANIFEST.map(({ url }) => url)]
const MAX_STALE_DURATION = 7 * 24 * 60 * 60
const preCache = async () => {
await caches.delete(CACHE_NAME)
const cache = await caches.open(CACHE_NAME)
const [windowClient] = await clients.matchAll({ includeUncontrolled: true, type: 'window' })
await cache.addAll(CACHED_URLS)
windowClient.postMessage({ type: 'update-available' })
}
const staleWhileRevalidate = async request => {
const documentRequest = request.destination === 'document'
if (documentRequest) request = new Request(self.registration.scope)
const cache = await caches.open(CACHE_NAME)
const cachedResponsePromise = await cache.match(request)
const networkResponsePromise = fetch(request)
if (documentRequest) {
networkResponsePromise.then(response => cache.put(request, response.clone()))
if ((new Date() - new Date(cachedResponsePromise?.headers.get('date'))) / 1000 > MAX_STALE_DURATION) {
return networkResponsePromise
}
return cachedResponsePromise
}
return cachedResponsePromise || networkResponsePromise
}
self.addEventListener('install', async event => {
event.waitUntil(preCache())
self.skipWaiting()
})
self.addEventListener('fetch', event => {
if (['document', 'font', 'script'].includes(event.request.destination)) {
event.respondWith(staleWhileRevalidate(event.request))
}
})
self.addEventListener('periodicsync', async event => {
if (event.tag === 'revalidate-assets') {
await event.target.registration.update()
const [windowClient] = await clients.matchAll({ includeUncontrolled: true, type: 'window' })
windowClient.postMessage({ type: 'periodic-sync-update-occured', syncTime: new Date().toISOString() })
}
})