summaryrefslogtreecommitdiff
path: root/static/sw.js
blob: 71f0e5f8278882ba9b2b86924eced0ea0231c8fe (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
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;
        });
      })
    );
  }
});