import { Workbox } from "workbox-window"; import { usePWA } from "~/composables/global/usePwa"; export default defineNuxtPlugin(() => { const updateAvailable = ref(false); let wb: Workbox | null = null; const { isInstalledAsPWA } = usePWA(); if ("serviceWorker" in navigator && isInstalledAsPWA.value) { // Initialize Workbox wb = new Workbox("/sw.js"); navigator.serviceWorker .register("/sw.js") .then((registration) => { // Native Service Worker API for update detection registration.addEventListener("updatefound", () => { const newWorker = registration.installing; if (newWorker) { newWorker.addEventListener("statechange", () => { if (newWorker.state === "installed") { // Only show prompt if there's a controller (not first install) if (navigator.serviceWorker.controller) { checkForUpdate(); } } }); } }); // Workbox events for consistency wb?.addEventListener("waiting", () => { checkForUpdate(); }); // Check if there's already a waiting worker if (registration.waiting) { checkForUpdate(); } // Periodic update checks (optional) setInterval(() => { registration.update().catch((err) => { console.debug( "Service worker update check failed:", err ); }); }, 60 * 60 * 1000); // Check every hour }) .catch((err) => { console.error("Service worker registration failed:", err); }); // Register Workbox wb.register().catch((error) => { console.error("Workbox registration failed:", error); }); } const checkForUpdate = () => { if (!updateAvailable.value) { updateAvailable.value = true; } }; const handleUpdate = () => { if (wb) { // Send skip waiting message wb.messageSW({ type: "SKIP_WAITING" }).then(() => { // Notify all tabs to reload if (navigator.serviceWorker.controller) { navigator.serviceWorker.controller.postMessage({ type: "CLIENT_RELOAD", }); } window.location.reload(); }); } }; return { provide: { updateAvailable, handleUpdate, }, }; });