/// const CACHE_NAME = "capakraken-v2"; const STATIC_EXTENSIONS = /\.(js|css|png|jpg|jpeg|svg|gif|ico|woff2?|ttf|eot)$/; // Offline fallback page (simple inline HTML) const OFFLINE_HTML = ` CapaKraken - Offline

You are offline

CapaKraken requires an internet connection. Please check your network and try again.

`; // Install: pre-cache the offline fallback self.addEventListener("install", (event) => { event.waitUntil( caches.open(CACHE_NAME).then((cache) => { return cache.put( new Request("/_offline"), new Response(OFFLINE_HTML, { headers: { "Content-Type": "text/html; charset=utf-8" }, }) ); }) ); // Activate immediately self.skipWaiting(); }); // Activate: clean up old caches self.addEventListener("activate", (event) => { event.waitUntil( caches.keys().then((keys) => Promise.all( keys .filter((key) => key !== CACHE_NAME) .map((key) => caches.delete(key)) ) ) ); // Take control of all clients immediately self.clients.claim(); }); // Fetch: strategy depends on request type self.addEventListener("fetch", (event) => { const { request } = event; const url = new URL(request.url); // Skip non-GET requests if (request.method !== "GET") return; // Skip chrome-extension, ws, etc. if (!url.protocol.startsWith("http")) return; // API calls and tRPC: network-first if (url.pathname.startsWith("/api/")) { event.respondWith( fetch(request).catch(() => { return new Response( JSON.stringify({ error: "offline" }), { status: 503, headers: { "Content-Type": "application/json" }, } ); }) ); return; } // Static assets: cache-first if (STATIC_EXTENSIONS.test(url.pathname) || url.pathname.startsWith("/_next/static/")) { event.respondWith( caches.match(request).then((cached) => { if (cached) return cached; return fetch(request).then((response) => { // Only cache successful responses if (response.ok) { const clone = response.clone(); caches.open(CACHE_NAME).then((cache) => cache.put(request, clone)); } return response; }); }) ); return; } // Navigation requests: network-first with offline fallback if (request.mode === "navigate") { event.respondWith( fetch(request).catch(() => caches.match("/_offline")) ); return; } // Everything else: network-first, silent fail event.respondWith( fetch(request).catch(() => caches.match(request)) ); });