aboutsummaryrefslogtreecommitdiff
path: root/src/frontend/app/utils/serviceWorkerManager.ts
blob: cbff748441771070fbb50339c9a5e3cfc9662ddf (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
export class ServiceWorkerManager {
  private registration: ServiceWorkerRegistration | null = null;
  private updateAvailable = false;
  private onUpdateCallback?: () => void;

  async initialize() {
    if (!("serviceWorker" in navigator)) {
      console.log("Service Workers not supported");
      return;
    }

    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?.();
            }
          });
        }
      });

      // Listen for messages from the service worker
      navigator.serviceWorker.addEventListener("message", (event) => {
        if (event.data.type === "SW_UPDATED") {
          this.updateAvailable = true;
          this.onUpdateCallback?.();
        }
      });

      // Check for updates periodically
      setInterval(() => {
        this.checkForUpdates();
      }, 60 * 1000); // Check every minute

    } catch (error) {
      console.error("Service Worker registration failed:", error);
    }
  }

  async checkForUpdates() {
    if (this.registration) {
      try {
        await this.registration.update();
      } catch (error) {
        console.error("Failed to check for updates:", error);
      }
    }
  }

  activateUpdate() {
    if (this.registration && this.registration.waiting) {
      this.registration.waiting.postMessage({ type: "SKIP_WAITING" });
      this.updateAvailable = false;
    }
  }

  onUpdate(callback: () => void) {
    this.onUpdateCallback = callback;
  }

  isUpdateAvailable() {
    return this.updateAvailable;
  }

  async clearCache() {
    if (this.registration && this.registration.active) {
      this.registration.active.postMessage({ type: "CLEAR_CACHE" });
    }
  }
}

export const swManager = new ServiceWorkerManager();