@ts-ignore
2import { registerSW } from 'virtual:pwa-register';
jevstrudel: the service worker is in prompt mode (astro.config.mjs). When a new deploy has installed and is waiting, the REPL's update modal (src/jev/UpdateModal.jsx) hears 'jev:update-ready' and calls window.jevUpdate() to switch to it and reload. Checks for a new deploy run on load, every ten minutes, and when the tab comes back into view.
9const CHECK_MS = 10 * 60 * 1000;
Switch to the waiting deploy and reload into it. This messages the waiting worker itself rather than calling registerSW's updateSW: that reloads only on a Workbox 'controlling' event marked as an update, and Workbox marks a deploy found by the periodic check below as external, so the worker activated and the page never reloaded (measured 2026-09-24).
16async function switchToWaiting() { 17 const registration = await navigator.serviceWorker.getRegistration(); 18 const waiting = registration?.waiting; 19 if (!waiting) return location.reload(); 20 navigator.serviceWorker.addEventListener('controllerchange', () => location.reload(), { once: true }); 21 waiting.postMessage({ type: 'SKIP_WAITING' }); 22 setTimeout(() => location.reload(), 5000); // in case controllerchange never comes 23}
25registerSW({ 26 immediate: true, 27 onNeedRefresh() { 28 (window as any).jevUpdate = switchToWaiting; 29 (window as any).jevUpdateReady = true; 30 window.dispatchEvent(new Event('jev:update-ready')); 31 }, 32 onRegisteredSW(_url: string, registration?: ServiceWorkerRegistration) { 33 if (!registration) return; 34 const check = () => registration.update().catch(() => {}); 35 setInterval(check, CHECK_MS); 36 document.addEventListener('visibilitychange', () => { 37 if (document.visibilityState === 'visible') check(); 38 }); 39 }, 40});