Files
kochwas/src/lib/client/pwa.svelte.ts

53 lines
1.6 KiB
TypeScript
Raw Normal View History

class PwaStore {
updateAvailable = $state(false);
private registration: ServiceWorkerRegistration | null = null;
private pollTimer: ReturnType<typeof setInterval> | null = null;
async init(): Promise<void> {
if (typeof navigator === 'undefined' || !('serviceWorker' in navigator)) return;
try {
this.registration = await navigator.serviceWorker.ready;
} catch {
return;
}
if (!this.registration) return;
// Wenn beim Mount schon ein neuer SW installiert und aktiv wartet,
// zeigen wir den Toast direkt an.
if (this.registration.waiting) {
this.updateAvailable = true;
}
this.registration.addEventListener('updatefound', () => this.onUpdateFound());
// Alle 30 Minuten aktiv nach Updates fragen, damit der User sie auch
// mitbekommt, wenn er die Seite lange offen lässt ohne zu navigieren.
this.pollTimer = setInterval(() => {
void this.registration?.update().catch(() => {});
}, 30 * 60_000);
}
private onUpdateFound(): void {
const installing = this.registration?.installing;
if (!installing) return;
installing.addEventListener('statechange', () => {
// 'installed' UND ein laufender controller = Update für bestehenden Tab.
// (Ohne controller wäre das die erste Installation, kein Update.)
if (installing.state === 'installed' && navigator.serviceWorker.controller) {
this.updateAvailable = true;
}
});
}
reload(): void {
this.updateAvailable = false;
location.reload();
}
dismiss(): void {
this.updateAvailable = false;
}
}
export const pwaStore = new PwaStore();