diff options
| author | Ariel Costas Guerrero <ariel@costas.dev> | 2025-08-06 21:52:21 +0200 |
|---|---|---|
| committer | Ariel Costas Guerrero <ariel@costas.dev> | 2025-08-06 21:52:21 +0200 |
| commit | ebfb7c1c8bc0a9ec50bde72eb9a0859c6e5dcee5 (patch) | |
| tree | 35353c15726d7d036907df731b00d390c1d1f538 /src/frontend/app/utils/serviceWorkerManager.ts | |
| parent | 5cc27f852b02446659e0ab85305916c9f5e5a5f0 (diff) | |
Fix this fucking pile of steaming garbage
Diffstat (limited to 'src/frontend/app/utils/serviceWorkerManager.ts')
| -rw-r--r-- | src/frontend/app/utils/serviceWorkerManager.ts | 125 |
1 files changed, 100 insertions, 25 deletions
diff --git a/src/frontend/app/utils/serviceWorkerManager.ts b/src/frontend/app/utils/serviceWorkerManager.ts index cbff748..a1ddbab 100644 --- a/src/frontend/app/utils/serviceWorkerManager.ts +++ b/src/frontend/app/utils/serviceWorkerManager.ts @@ -10,41 +10,81 @@ export class ServiceWorkerManager { } try { - this.registration = await navigator.serviceWorker.register("/sw.js"); - console.log("Service Worker registered with scope:", this.registration.scope); - - // Listen for updates - this.registration.addEventListener("updatefound", () => { - const newWorker = this.registration!.installing; - if (newWorker) { - newWorker.addEventListener("statechange", () => { - if (newWorker.state === "installed" && navigator.serviceWorker.controller) { - // New service worker is installed and ready - this.updateAvailable = true; - this.onUpdateCallback?.(); - } - }); + // First, unregister any old service workers to start fresh + const registrations = await navigator.serviceWorker.getRegistrations(); + for (const registration of registrations) { + if (registration.scope.includes(window.location.origin)) { + console.log("Unregistering old service worker:", registration.scope); + await registration.unregister(); } - }); + } - // Listen for messages from the service worker - navigator.serviceWorker.addEventListener("message", (event) => { - if (event.data.type === "SW_UPDATED") { - this.updateAvailable = true; - this.onUpdateCallback?.(); - } + // Register the new worker with a fresh name + this.registration = await navigator.serviceWorker.register("/pwa-worker.js", { + updateViaCache: 'none' // Disable caching for the SW file itself }); + console.log("PWA Worker registered with scope:", this.registration.scope); + + // Implement proper updatefound detection (web.dev pattern) + await this.detectSWUpdate(); // Check for updates periodically setInterval(() => { this.checkForUpdates(); - }, 60 * 1000); // Check every minute + }, 30 * 1000); + + // Check when page becomes visible + document.addEventListener("visibilitychange", () => { + if (!document.hidden) { + this.checkForUpdates(); + } + }); } catch (error) { console.error("Service Worker registration failed:", error); } } + private async detectSWUpdate() { + if (!this.registration) return; + + // Listen for new service worker discovery + this.registration.addEventListener("updatefound", () => { + const newSW = this.registration!.installing; + if (!newSW) return; + + console.log("New service worker found, monitoring installation..."); + + newSW.addEventListener("statechange", () => { + console.log("New SW state:", newSW.state); + + if (newSW.state === "installed") { + if (navigator.serviceWorker.controller) { + // New service worker is installed, but old one is still controlling + // This means an update is available + console.log("New service worker installed - update available!"); + this.updateAvailable = true; + this.onUpdateCallback?.(); + } else { + // First install, no controller yet + console.log("Service worker installed for the first time"); + } + } + + if (newSW.state === "activated") { + console.log("New service worker activated"); + // Optionally notify about successful update + } + }); + }); + + // Also listen for controller changes + navigator.serviceWorker.addEventListener("controllerchange", () => { + console.log("Service worker controller changed - reloading page"); + window.location.reload(); + }); + } + async checkForUpdates() { if (this.registration) { try { @@ -70,9 +110,44 @@ export class ServiceWorkerManager { return this.updateAvailable; } - async clearCache() { - if (this.registration && this.registration.active) { - this.registration.active.postMessage({ type: "CLEAR_CACHE" }); + async clearCache(): Promise<void> { + try { + // Delete all caches + const cacheNames = await caches.keys(); + await Promise.all(cacheNames.map(name => caches.delete(name))); + console.log("All caches cleared"); + } catch (error) { + console.error("Failed to clear cache:", error); + throw error; + } + } + + // Nuclear option: completely reset the PWA + async resetPWA(): Promise<void> { + try { + console.log("Resetting PWA completely..."); + + // 1. Unregister ALL service workers + const registrations = await navigator.serviceWorker.getRegistrations(); + await Promise.all(registrations.map(reg => reg.unregister())); + + // 2. Clear all caches + await this.clearCache(); + + // 3. Clear local storage (optional) + localStorage.clear(); + sessionStorage.clear(); + + console.log("PWA reset complete - reloading..."); + + // 4. Force reload after a short delay + setTimeout(() => { + window.location.reload(); + }, 500); + + } catch (error) { + console.error("Failed to reset PWA:", error); + throw error; } } } |
