// Service Worker for ECHO TUTOR PRO const CACHE_NAME = 'echo-tutor-cache-v4'; const STATIC_CACHE_PREFIX = 'echo-tutor-cache-'; const STATIC_ASSETS = [ '/', '/app', '/static/css/style.css', '/static/js/script.js', '/static/js/features.js', '/static/manifest.json', '/static/icons/icon-192.png', '/static/icons/icon-512.png', '/static/icons/Echo.png', ]; function isApiRequest(url) { return ( url.pathname.startsWith('/chat') || url.pathname.startsWith('/topics') || url.pathname.startsWith('/health') || url.pathname.startsWith('/transcribe') || url.pathname.startsWith('/auth') ); } self.addEventListener('install', (event) => { self.skipWaiting(); event.waitUntil( caches .open(CACHE_NAME) .then((cache) => cache.addAll(STATIC_ASSETS)) .catch(() => {}), ); }); self.addEventListener('activate', (event) => { event.waitUntil( caches .keys() .then((keys) => Promise.all( keys .filter( (key) => key.startsWith(STATIC_CACHE_PREFIX) && key !== CACHE_NAME, ) .map((key) => caches.delete(key)), ), ) .then(() => self.clients.claim()), ); }); self.addEventListener('fetch', (event) => { if (event.request.method !== 'GET') { return; } const requestUrl = new URL(event.request.url); if (requestUrl.origin !== self.location.origin || isApiRequest(requestUrl)) { return; } const isNavigation = event.request.mode === 'navigate'; if (isNavigation) { event.respondWith( fetch(event.request) .then((networkResponse) => { const cloned = networkResponse.clone(); caches .open(CACHE_NAME) .then((cache) => cache.put(event.request, cloned)); return networkResponse; }) .catch(() => caches .match(event.request) .then((cached) => cached || caches.match('/')), ), ); return; } event.respondWith( caches.match(event.request).then((cached) => { const fetchPromise = fetch(event.request) .then((networkResponse) => { if (networkResponse && networkResponse.status === 200) { const cloned = networkResponse.clone(); caches .open(CACHE_NAME) .then((cache) => cache.put(event.request, cloned)); } return networkResponse; }) .catch(() => cached); return cached || fetchPromise; }), ); });