/// 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 => { if (!offlineReadingAllowed) return null return response }, } const sameOriginCache = defaultCache.map((entry) => ({ ...entry, matcher: (parameters: Parameters>[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()