const CACHE_NAME = 'yuki-bonsai-cache-v1'; const APP_SHELL_URLS = [ '/', '/index.html' ]; self.addEventListener('install', event => { event.waitUntil( caches.open(CACHE_NAME) .then(cache => cache.addAll(APP_SHELL_URLS)) .then(() => self.skipWaiting()) ); }); self.addEventListener('activate', event => { event.waitUntil( caches.keys().then(cacheNames => { return Promise.all( cacheNames.map(cacheName => { if (cacheName !== CACHE_NAME) { return caches.delete(cacheName); } }) ); }).then(() => self.clients.claim()) ); }); self.addEventListener('fetch', event => { if (event.request.method !== 'GET') { return; } // For navigation requests, use a network-first strategy to get latest HTML. if (event.request.mode === 'navigate') { event.respondWith( fetch(event.request) .catch(() => caches.match('/index.html')) ); return; } // For all other requests (JS, CSS, images from esm.sh), use a cache-first strategy. event.respondWith( caches.match(event.request).then(cachedResponse => { if (cachedResponse) { return cachedResponse; } return fetch(event.request).then(response => { // Don't cache opaque responses (from CDNs without CORS) or non-200 responses. if (!response || response.status !== 200 || response.type === 'opaque') { return response; } const responseToCache = response.clone(); caches.open(CACHE_NAME) .then(cache => { cache.put(event.request, responseToCache); }); return response; }); }) ); });