/// /// import { clientsClaim } from 'workbox-core' import { registerRoute } from 'workbox-routing' import { CacheFirst, NetworkFirst, StaleWhileRevalidate } from 'workbox-strategies' import { CacheableResponsePlugin } from 'workbox-cacheable-response' import { ExpirationPlugin } from 'workbox-expiration' import { onNotificationClick, onPush } from './web-push-notifications' declare let self: ServiceWorkerGlobalScope self.skipWaiting() clientsClaim() if (import.meta.env.DEV) { // Avoid caching on dev: force always go to the server registerRoute( () => true, new NetworkFirst({ cacheName: 'elk-dev', plugins: [ new CacheableResponsePlugin({ statuses: [-1] }), ], }), ) } if (import.meta.env.PROD) { const denyList: RegExp[] = [/^\/api\//, /^\/login\//, /^\/oauth\//, /^\/signin\//, /^\/web-share-target\//] const matchDenyList = (url: URL) => { const pathnameAndSearch = url.pathname + url.search for (const regExp of denyList) { if (regExp.test(pathnameAndSearch)) return false } return true } // Cache page navigations (html) with a Network First strategy registerRoute( ({ sameOrigin, request, url }) => { return sameOrigin && request.mode === 'navigate' && matchDenyList(url) }, new NetworkFirst({ cacheName: 'elk-pages', plugins: [ new CacheableResponsePlugin({ statuses: [200] }), ], }), ) // Cache CSS, JS, and Web Worker requests with a Stale While Revalidate strategy registerRoute( ({ sameOrigin, request }) => sameOrigin && (request.destination === 'style' || request.destination === 'manifest' || request.destination === 'script' || request.destination === 'worker'), new StaleWhileRevalidate({ cacheName: 'elk-assets', plugins: [ new CacheableResponsePlugin({ statuses: [200] }), ], }), ) // include shiki cache registerRoute( ({ sameOrigin, url }) => sameOrigin && url.pathname.startsWith('/shiki/'), new StaleWhileRevalidate({ cacheName: 'elk-shiki', plugins: [ new CacheableResponsePlugin({ statuses: [200] }), // 365 days max new ExpirationPlugin({ maxAgeSeconds: 60 * 60 * 24 * 365 }), ], }), ) // Cache images with a Cache First strategy registerRoute( ({ sameOrigin, request }) => sameOrigin && request.destination === 'image', new CacheFirst({ cacheName: 'elk-images', plugins: [ new CacheableResponsePlugin({ statuses: [200] }), // 150 max, 30 days max: purge on quota error new ExpirationPlugin({ purgeOnQuotaError: true, maxEntries: 150, maxAgeSeconds: 60 * 60 * 24 * 30 }), ], }), ) } self.addEventListener('push', onPush) self.addEventListener('notificationclick', onNotificationClick)