import { registerSW } from "virtual:pwa-register"; import { ref } from "vue"; interface UsePWAUpdateOptions { /** * Whether to automatically reload the app when a new version is detected. * @default false */ autoUpdate?: boolean; /** * Interval in seconds to check for updates. * Set to 0 to disable periodic checks. * @default 86400 (24 hours) */ updateInterval?: number; } const needRefresh = ref(false); const offlineReady = ref(false); let updateSW: ((reloadPage?: boolean) => Promise) | undefined; let registered = false; let intervalId: ReturnType | undefined; /** * Registers the service worker on the first call. State is shared across all * callers. * * @example * // Automatic updates * const { needRefresh } = usePWAUpdate({ autoUpdate: true }); * * @example * // Manual updates with UI notification * const { needRefresh, updateApp } = usePWAUpdate(); * watch(needRefresh, (value) => { * if (value) { * updateApp(); // once the user confirms the prompt * } * }); */ export function usePWAUpdate(options: UsePWAUpdateOptions = {}) { const { autoUpdate = false, updateInterval = 60 * 60 * 24 } = options; const updateApp = async () => { if (updateSW) { try { await updateSW(true); needRefresh.value = false; } catch (error) { console.error("PWA: Failed to update app:", error); } } }; if (!registered) { registered = true; updateSW = registerSW({ immediate: true, onNeedRefresh() { console.log("PWA: Update available - need refresh"); needRefresh.value = true; if (autoUpdate) { console.log("PWA: Auto-update enabled, updating app..."); updateApp(); } }, onOfflineReady() { console.log("PWA: App is ready to work offline"); offlineReady.value = true; }, onRegistered(registration: ServiceWorkerRegistration | undefined) { console.log("PWA: Service worker registered successfully"); if (registration && updateInterval > 0 && !intervalId) { intervalId = setInterval(() => { console.log("PWA: Checking for updates..."); registration.update(); }, updateInterval * 1000); } }, onRegisterError(error: Error) { console.error("PWA: Service worker registration error:", error); }, }); } return { needRefresh, offlineReady, updateApp, }; }