aboutsummaryrefslogtreecommitdiff
path: root/src/frontend/app/utils
diff options
context:
space:
mode:
authorAriel Costas Guerrero <ariel@costas.dev>2025-08-06 21:52:21 +0200
committerAriel Costas Guerrero <ariel@costas.dev>2025-08-06 21:52:21 +0200
commitebfb7c1c8bc0a9ec50bde72eb9a0859c6e5dcee5 (patch)
tree35353c15726d7d036907df731b00d390c1d1f538 /src/frontend/app/utils
parent5cc27f852b02446659e0ab85305916c9f5e5a5f0 (diff)
Fix this fucking pile of steaming garbage
Diffstat (limited to 'src/frontend/app/utils')
-rw-r--r--src/frontend/app/utils/serviceWorkerManager.ts125
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;
}
}
}