90 lines
2.9 KiB
TypeScript
90 lines
2.9 KiB
TypeScript
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,
|
|
},
|
|
};
|
|
});
|