const CACHE_VERSION = "cognitive-agent-pad-v163"; const SHELL_CACHE = `${CACHE_VERSION}-shell`; const RUNTIME_CACHE = `${CACHE_VERSION}-runtime`; const APP_SHELL = [ "/", "/index.html", "/styles.css?v=dual-seat-9", "/network.js?v=android-pad-1", "/app.js?v=dual-seat-85", "/gesture-control.js?v=android-pad-8", "/pwa.js?v=android-pad-2", "/console-v2.css?v=sync-layout-11", "/console-v2.js?v=sync-layout-11", "/self-extension.css?v=sync-layout-11", "/self-extension.js?v=sync-layout-11", "/assets/pets/self-extension-cat.png?v=3", "/assets/pets/self-extension-cat-entrance.png?v=3", "/manifest.webmanifest", "/icons/app-icon-192.png", "/icons/app-icon-512.png", "/vendor/lucide/0.468.0/lucide.min.js", "/vendor/three/0.147.0/three.min.js", "/vendor/three/0.147.0/fflate.min.js", "/vendor/three/0.147.0/FBXLoader.js", "/vendor/mediapipe/tasks-vision/0.10.14/vision_bundle.mjs", "/vendor/mediapipe/tasks-vision/0.10.14/wasm/vision_wasm_internal.js", "/vendor/mediapipe/tasks-vision/0.10.14/wasm/vision_wasm_internal.wasm", "/vendor/mediapipe/tasks-vision/0.10.14/wasm/vision_wasm_nosimd_internal.js", "/vendor/mediapipe/tasks-vision/0.10.14/wasm/vision_wasm_nosimd_internal.wasm" ]; self.addEventListener("install", (event) => { event.waitUntil( caches.open(SHELL_CACHE) .then((cache) => cache.addAll(APP_SHELL)) .then(() => self.skipWaiting()) .then(() => self.clients.matchAll({ includeUncontrolled: true })) .then((clients) => clients.forEach((client) => client.postMessage({ type: "OFFLINE_READY" }))) ); }); self.addEventListener("activate", (event) => { event.waitUntil( caches.keys() .then((keys) => Promise.all( keys.filter((key) => key.startsWith("cognitive-agent-pad-") && ![SHELL_CACHE, RUNTIME_CACHE].includes(key)) .map((key) => caches.delete(key)) )) .then(() => self.clients.claim()) ); }); async function cacheFirst(request) { const shellCache = await caches.open(SHELL_CACHE); const runtimeCache = await caches.open(RUNTIME_CACHE); const cached = (await shellCache.match(request)) || (await runtimeCache.match(request)); if (cached) return cached; const response = await fetch(request); if (response.ok) { await runtimeCache.put(request, response.clone()); } return response; } async function navigationResponse(request) { try { const response = await fetch(request); if (response.ok) { const cache = await caches.open(RUNTIME_CACHE); await cache.put("/index.html", response.clone()); } return response; } catch (_error) { const shellCache = await caches.open(SHELL_CACHE); const runtimeCache = await caches.open(RUNTIME_CACHE); return (await runtimeCache.match("/index.html")) || (await shellCache.match("/index.html")) || Response.error(); } } self.addEventListener("fetch", (event) => { const url = new URL(event.request.url); if (url.origin !== self.location.origin || event.request.method !== "GET") return; if (event.request.mode === "navigate") { event.respondWith(navigationResponse(event.request)); return; } if (url.pathname.startsWith("/api/") && url.pathname !== "/api/gesture/model") return; event.respondWith(cacheFirst(event.request)); }); self.addEventListener("message", (event) => { if (event.data?.type === "SKIP_WAITING") self.skipWaiting(); });