import { browser } from '$app/environment'; import { stops } from './stops'; export type PrecacheState = 'idle' | 'running' | 'complete' | 'unsupported'; let state: PrecacheState = $state('idle'); let done = $state(0); let total = $state(0); export function precacheState() { return { state, done, total }; } export async function precacheAll(): Promise { if (!browser) return; if (!('serviceWorker' in navigator)) { state = 'unsupported'; return; } if (state === 'running' || state === 'complete') return; const reg = await navigator.serviceWorker.ready.catch(() => null); const target = reg?.active ?? navigator.serviceWorker.controller; if (!target) { state = 'unsupported'; return; } const urls = stops.flatMap((s) => [s.audio, s.image]); state = 'running'; done = 0; total = urls.length; const onMessage = (event: MessageEvent) => { const data = event.data; if (!data || typeof data !== 'object') return; if (data.type === 'precache-progress') { done = data.done; total = data.total; } else if (data.type === 'precache-done') { done = data.done; total = data.total; state = 'complete'; navigator.serviceWorker.removeEventListener('message', onMessage); } }; navigator.serviceWorker.addEventListener('message', onMessage); target.postMessage({ type: 'precache-stops', urls }); }