From 575408748c2dfeca2f5c817d74a1e97543277859 Mon Sep 17 00:00:00 2001 From: Deploy Bot Date: Mon, 2 Nov 2026 22:38:28 -0300 Subject: [PATCH] sw: cache v2 + network-first para shell e /content (evita tela branca com cache antigo apos deploy) --- app/public/sw.js | 46 +++++++++++++++++++++++++++++++++++++--- app/tsconfig.tsbuildinfo | 2 +- 2 files changed, 44 insertions(+), 4 deletions(-) diff --git a/app/public/sw.js b/app/public/sw.js index bd6fb3a..6068e47 100644 --- a/app/public/sw.js +++ b/app/public/sw.js @@ -8,7 +8,7 @@ * Objetivo: modo resgate offline — frases + áudio já baixados funcionam no avião. */ -const CACHE_NAME = "italiano-vivo-v1"; +const CACHE_NAME = "italiano-vivo-v2"; const SHELL_ASSETS = ["/", "/index.html"]; // ─── Install: pré-cache do shell ─── @@ -54,10 +54,28 @@ self.addEventListener("fetch", (event) => { }); /** - * Cache-first: tenta cache, se não achar vai na rede (sem salvar no cache). - * Usado para shell/assets que são pré-cachados no install. + * Network-first para o shell (HTML): sempre busca a versao mais nova e + * atualiza o cache em background. Evita o app ficar preso numa build antiga + * apos deploy. Assets versionados (/assets/*-hash) podem ser cache-first + * porque o nome muda a cada build. */ async function cacheFirst(request) { + const url = new URL(request.url); + const isShellHtml = url.pathname === "/" || url.pathname === "/index.html" || url.pathname === "/sw.js"; + if (isShellHtml) { + try { + const fresh = await fetch(request); + if (fresh.ok) { + const cache = await caches.open(CACHE_NAME); + cache.put(request, fresh.clone()); + } + return fresh; + } catch (_err) { + const cached = await caches.match(request); + if (cached) return cached; + throw _err; + } + } const cached = await caches.match(request); if (cached) return cached; return fetch(request); @@ -69,6 +87,28 @@ async function cacheFirst(request) { * Usado para /content/* e /audio/* que são baixados sob demanda. */ async function cacheFirstWithRuntimeCache(request) { + // Network-first para /content/* (JSON de missoes pode ser corrigido a qualquer + // momento; cache antigo nao deve esconder o novo). Audio e imutavel -> cache-first. + const url = new URL(request.url); + if (url.pathname.startsWith("/content/")) { + try { + const response = await fetch(request); + if (response.ok) { + const cache = await caches.open(CACHE_NAME); + cache.put(request, response.clone()); + } + return response; + } catch (_err) { + const cached = await caches.match(request); + if (cached) return cached; + return new Response("Offline — Italiano Vivo", { + status: 503, + statusText: "Service Unavailable", + headers: { "Content-Type": "text/plain" }, + }); + } + } + const cached = await caches.match(request); if (cached) return cached; diff --git a/app/tsconfig.tsbuildinfo b/app/tsconfig.tsbuildinfo index 30af50b..18eceae 100644 --- a/app/tsconfig.tsbuildinfo +++ b/app/tsconfig.tsbuildinfo @@ -1 +1 @@ -{"root":["./src/db/db.ts","./src/engine/srs.ts","./src/types/content.ts","./src/app.tsx","./src/main.tsx"],"version":"5.9.3"} \ No newline at end of file +{"root":["./src/db/db.ts","./src/engine/srs.ts","./src/types/content.ts","./src/App.tsx","./src/main.tsx"],"version":"5.9.3"} \ No newline at end of file