/* Dashboard Studio service worker: always the network first, so updates show straight away. * When the network fails (or Home Assistant's ingress session has run out), it answers with * the last good copy, so the app can start, show the last known states and reconnect. */ const CACHE = "ds-__VERSION__"; const SKIP = /\/(ws|api\/camera|api\/immich|api\/history)/; self.addEventListener("install", () => self.skipWaiting()); self.addEventListener("activate", (e) => { e.waitUntil(caches.keys().then((keys) => Promise.all(keys.filter((k) => k.startsWith("ds-") && k !== CACHE).map((k) => caches.delete(k)))).then(() => self.clients.claim())); }); self.addEventListener("fetch", (e) => { const req = e.request, url = new URL(req.url); if (req.method !== "GET" || url.origin !== location.origin || SKIP.test(url.pathname)) return; const page = req.mode === "navigate"; e.respondWith((async () => { const cache = await caches.open(CACHE); try { const res = await fetch(req); if (res.ok) { cache.put(page ? new Request(new URL("./", self.registration.scope)) : req, res.clone()); return res; } if (!page) return res; // Signed out of Home Assistant: the last good copy renews the session itself. Without one, pass // the refusal on, so Haven knows to sign in again. return (await cache.match(new URL("./", self.registration.scope).href)) || res; } catch (err) { const hit = page ? await cache.match(new URL("./", self.registration.scope).href) : await cache.match(req); if (hit) return hit; throw err; } })()); });