diff options
Diffstat (limited to 'static/sw.js')
| -rw-r--r-- | static/sw.js | 68 |
1 files changed, 68 insertions, 0 deletions
diff --git a/static/sw.js b/static/sw.js new file mode 100644 index 0000000..71f0e5f --- /dev/null +++ b/static/sw.js @@ -0,0 +1,68 @@ +/* Service Worker — caderno de estudos + Estratégia: cache-first para assets estáticos, network-first para HTML + Versão: 3 (com suporte a stale-while-revalidate) */ +const CACHE = 'caderno-v3'; +const STATIC = [ + '/', + '/offline.html' +]; + +self.addEventListener('install', e => { + e.waitUntil( + caches.open(CACHE).then(c => c.addAll(STATIC)).then(() => self.skipWaiting()) + ); +}); + +self.addEventListener('activate', e => { + e.waitUntil( + caches.keys().then(keys => + Promise.all(keys.filter(k => k !== CACHE).map(k => caches.delete(k))) + ).then(() => self.clients.claim()) + ); +}); + +self.addEventListener('fetch', e => { + const url = new URL(e.request.url); + + // Ignora requisições externas (fontes Google, etc.) + if (url.origin !== location.origin) return; + + if (e.request.mode === 'navigate') { + // HTML: network-first, fallback para offline.html + e.respondWith( + fetch(e.request) + .then(res => { + const clone = res.clone(); + caches.open(CACHE).then(c => c.put(e.request, clone)); + return res; + }) + .catch(() => caches.match(e.request).then(r => r || caches.match('/offline.html'))) + ); + } else { + // Assets (CSS, JS, imagens): stale-while-revalidate + e.respondWith( + caches.match(e.request).then(cached => { + // Se estiver em cache, retorna imediatamente e atualiza em background + if (cached) { + // Atualizar em background + fetch(e.request).then(res => { + if (res && res.status === 200) { + const clone = res.clone(); + caches.open(CACHE).then(c => c.put(e.request, clone)); + } + }); + return cached; + } + + // Se não estiver em cache, busca da rede + return fetch(e.request).then(res => { + if (res && res.status === 200) { + const clone = res.clone(); + caches.open(CACHE).then(c => c.put(e.request, clone)); + } + return res; + }); + }) + ); + } +}); |
