// sw.js const CACHE_NAME = 'verbale-v1'; const APP_SHELL = [ './', './ibrida.html', './array.html', './manifest.webmanifest', './assets/logo-icon.svg', './assets/logo-wordmark.svg' // aggiungi qui CSS/JS locali se li separi in file ]; self.addEventListener('install', (e) => { e.waitUntil( caches.open(CACHE_NAME).then((cache) => cache.addAll(APP_SHELL)) ); self.skipWaiting(); }); self.addEventListener('activate', (e) => { e.waitUntil( caches.keys().then(keys => Promise.all(keys.map(k => k !== CACHE_NAME ? caches.delete(k) : null)) ) ); self.clients.claim(); }); // Strategia: network-first per HTML, cache-first per asset self.addEventListener('fetch', (e) => { const req = e.request; // HTML: tenta rete, fallback cache if (req.headers.get('accept')?.includes('text/html')) { e.respondWith( fetch(req).then((res) => { const copy = res.clone(); caches.open(CACHE_NAME).then((c) => c.put(req, copy)); return res; }).catch(() => caches.match(req).then(m => m || caches.match('./ibrida.html'))) ); return; } // Asset: cache-first e.respondWith( caches.match(req).then((cached) => { if (cached) return cached; return fetch(req).then((res) => { const copy = res.clone(); caches.open(CACHE_NAME).then((c) => c.put(req, copy)); return res; }); }) ); });