// --- Time Pulse Service Worker --- const CACHE_NAME = 'timepulse-v1'; // Files to cache (App Shell) const filesToCache = [ '/', '/index.html', '/style/style.css', '/js/main.js', '/js/ui.js', '/js/api.js', '/js/utils.js', '/manifest.json', '/icons/icon-192x192.webp', '/icons/icon-512x512.webp' ]; // --- Install Event --- self.addEventListener('install', event => { console.log('[SW] Install event'); event.waitUntil( caches.open(CACHE_NAME) .then(cache => { console.log('[SW] Caching app shell'); return cache.addAll(filesToCache); }) ); self.skipWaiting(); // Activate worker immediately }); // --- Activate Event --- self.addEventListener('activate', event => { console.log('[SW] Activate event'); event.waitUntil( caches.keys().then(keys => Promise.all( keys.map(key => { if (key !== CACHE_NAME) { console.log('[SW] Removing old cache:', key); return caches.delete(key); } }) ) ) ); self.clients.claim(); // Become available to all pages }); // --- Fetch Event --- self.addEventListener('fetch', event => { // Ignore non-GET requests and API calls if (event.request.method !== 'GET' || event.request.url.includes('/api/')) { return; } event.respondWith( caches.match(event.request) .then(response => { // Return cached file OR fetch from network return response || fetch(event.request).then(fetchResponse => { // Optionally cache new files on the fly return caches.open(CACHE_NAME).then(cache => { cache.put(event.request, fetchResponse.clone()); return fetchResponse; }); }); }) .catch(() => { // Optional: return a fallback page or image here }) ); });