forked from elk-zone/elk
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsw.ts
107 lines (96 loc) · 3.21 KB
/
sw.ts
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
104
105
106
107
/// <reference lib="WebWorker" />
/// <reference types="vite/client" />
import { cleanupOutdatedCaches, createHandlerBoundToURL, precacheAndRoute } from 'workbox-precaching'
import { NavigationRoute, registerRoute } from 'workbox-routing'
import { CacheableResponsePlugin } from 'workbox-cacheable-response'
import { NetworkFirst, StaleWhileRevalidate } from 'workbox-strategies'
import { ExpirationPlugin } from 'workbox-expiration'
import { onNotificationClick, onPush } from './web-push-notifications'
import { onShareTarget } from './share-target'
declare const self: ServiceWorkerGlobalScope
self.addEventListener('message', (event) => {
if (event.data && event.data.type === 'SKIP_WAITING')
self.skipWaiting()
})
const entries = self.__WB_MANIFEST
if (import.meta.env.DEV)
entries.push({ url: '/', revision: Math.random().toString() })
precacheAndRoute(entries)
// clean old assets
cleanupOutdatedCaches()
// allow only fallback in dev: we don't want to cache anything
let allowlist: undefined | RegExp[]
if (import.meta.env.DEV)
allowlist = [/^\/$/]
// deny api and server page calls
let denylist: undefined | RegExp[]
if (import.meta.env.PROD) {
denylist = [
/^\/api\//,
/^\/login\//,
/^\/oauth\//,
/^\/signin\//,
/^\/web-share-target\//,
// exclude emoji: has its own cache
/^\/emojis\//,
// exclude sw: if the user navigates to it, fallback to index.html
/^\/sw.js$/,
// exclude webmanifest: has its own cache
/^\/manifest-(.*).webmanifest$/,
]
}
// only cache pages and external assets on local build + start or in production
if (import.meta.env.PROD) {
// include webmanifest cache
registerRoute(
({ request, sameOrigin }) =>
sameOrigin && request.destination === 'manifest',
new NetworkFirst({
cacheName: 'elk-webmanifest',
plugins: [
new CacheableResponsePlugin({ statuses: [200] }),
// we only need a few entries
new ExpirationPlugin({ maxEntries: 100 }),
],
}),
)
// include emoji icons
registerRoute(
({ sameOrigin, request, url }) =>
sameOrigin
&& request.destination === 'image'
&& url.pathname.startsWith('/emojis/'),
new StaleWhileRevalidate({
cacheName: 'elk-emojis',
plugins: [
new CacheableResponsePlugin({ statuses: [200] }),
// 15 days max
new ExpirationPlugin({ purgeOnQuotaError: true, maxAgeSeconds: 60 * 60 * 24 * 15 }),
],
}),
)
// external assets: rn avatars from mas.to
// requires <img crossorigin="anonymous".../> and http header: Allow-Control-Allow-Origin: *
/*
registerRoute(
({ sameOrigin, request }) => !sameOrigin && request.destination === 'image',
new NetworkFirst({
cacheName: 'elk-external-media',
plugins: [
// add opaque responses?
new CacheableResponsePlugin({ statuses: [/!* 0, *!/200] }),
// 15 days max
new ExpirationPlugin({ maxAgeSeconds: 60 * 60 * 24 * 15 }),
],
}),
)
*/
}
// to allow work offline
registerRoute(new NavigationRoute(
createHandlerBoundToURL('/'),
{ allowlist, denylist },
))
self.addEventListener('push', onPush)
self.addEventListener('notificationclick', onNotificationClick)
self.addEventListener('fetch', onShareTarget)