/** * public/sw.js — minimal service worker (M4: PWA installability + offline shell). * * Network-first so we never serve a stale build while online; falls back to the * cache when offline. Never intercepts the WebSocket (/term) or hook endpoints. */ const CACHE = 'webterm-v1' self.addEventListener('install', () => self.skipWaiting()) self.addEventListener('activate', (e) => e.waitUntil(self.clients.claim())) self.addEventListener('fetch', (e) => { const req = e.request if (req.method !== 'GET') return const url = new URL(req.url) if (url.pathname === '/term' || url.pathname.startsWith('/hook')) return // WS / hooks e.respondWith( fetch(req) .then((res) => { const copy = res.clone() caches.open(CACHE).then((c) => c.put(req, copy)) return res }) .catch(() => caches.match(req)), ) })