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
|
/// <reference lib="webworker" />
import { defaultCache } from "@serwist/next/worker"
import type { PrecacheEntry, SerwistGlobalConfig } from "serwist"
import { Serwist, NetworkFirst, CacheFirst, ExpirationPlugin } from "serwist"
declare global {
interface WorkerGlobalScope extends SerwistGlobalConfig {
__SW_MANIFEST: (PrecacheEntry | string)[] | undefined
}
}
declare const self: ServiceWorkerGlobalScope
let offlineReadingAllowed = false
self.addEventListener("message", (event) => {
if (event.data?.type === "SET_OFFLINE_ACCESS") {
offlineReadingAllowed = event.data.allowed === true
}
})
const offlineGatePlugin = {
cacheWillUpdate: async ({ response }: { response: Response }): Promise<Response | null> => {
if (!offlineReadingAllowed) return null
return response
},
}
const sameOriginCache = defaultCache.map((entry) => ({
...entry,
matcher: (parameters: Parameters<Exclude<(typeof defaultCache)[number]["matcher"], RegExp | string | undefined>>[0]) => {
if (!parameters.sameOrigin) return false
const original = entry.matcher
if (typeof original === "function") return original(parameters)
if (original instanceof RegExp) return original.test(parameters.url.href)
return false
},
}))
const serwist = new Serwist({
precacheEntries: self.__SW_MANIFEST,
skipWaiting: true,
clientsClaim: true,
navigationPreload: true,
runtimeCaching: [
{
matcher: ({ url, request }) =>
url.hostname.endsWith(".supabase.co") &&
url.pathname.startsWith("/rest/v1/") &&
request.method === "GET",
handler: new NetworkFirst({
cacheName: "supabase-rest-get",
networkTimeoutSeconds: 10,
plugins: [
offlineGatePlugin,
new ExpirationPlugin({
maxEntries: 200,
maxAgeSeconds: 60 * 60 * 24,
}),
],
}),
},
{
matcher: ({ request, sameOrigin }) =>
sameOrigin && request.destination === "image",
handler: new CacheFirst({
cacheName: "entry-images",
plugins: [
new ExpirationPlugin({
maxEntries: 500,
maxAgeSeconds: 60 * 60 * 24 * 7,
}),
],
}),
},
...sameOriginCache,
],
})
serwist.addEventListeners()
|