summaryrefslogtreecommitdiff
path: root/static/sw.js
diff options
context:
space:
mode:
Diffstat (limited to 'static/sw.js')
-rw-r--r--static/sw.js68
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;
+ });
+ })
+ );
+ }
+});