import { registerSW } from "virtual:pwa-register"; import { canUseWindow, isEnterpriseMessengerContainer, matchesMedia } from "./lib/runtimeContext"; const MOBILE_APPROVAL_TASK_PATH = /^\/workflow\/tasks\/([^/]+)$/i; const OFFLINE_ALLOWED_PATHS = ["/mobile/approvals"]; const CLEARABLE_CACHE_PREFIXES = ["app-api-runtime", "app-static-runtime", "workbox-precache"]; export function registerPwaIfEnabled() { if (import.meta.env.DEV) { return; } if (import.meta.env.VITE_PWA_ENABLED === "false") { return; } registerSW({ immediate: true, onOfflineReady() { if (canUseWindow()) { window.dispatchEvent(new CustomEvent("hyb-oa:pwa-offline-ready")); } }, }); } export function buildMobileApprovalsPath(taskId?: string | null) { const normalizedTaskId = String(taskId ?? "").trim(); if (!normalizedTaskId) { return "/mobile/approvals"; } const params = new URLSearchParams({ taskId: normalizedTaskId }); return `/mobile/approvals?${params.toString()}`; } export function extractWorkflowTaskId(pathname: string) { const match = pathname.match(MOBILE_APPROVAL_TASK_PATH); return match?.[1] ?? null; } export function isOfflineSnapshotAllowedPath(pathname: string) { if (OFFLINE_ALLOWED_PATHS.includes(pathname)) { return true; } return Boolean(extractWorkflowTaskId(pathname)); } export function shouldPreferMobileApprovalExperience() { if (!canUseWindow()) { return false; } const isStandalone = matchesMedia("(display-mode: standalone)") || (window.navigator as Navigator & { standalone?: boolean }).standalone === true; const isTouchSmallScreen = window.navigator.maxTouchPoints > 0 && matchesMedia("(max-width: 1024px)"); return isStandalone || isEnterpriseMessengerContainer() || isTouchSmallScreen; } export async function clearPwaRuntimeCaches() { if (!canUseWindow() || !("caches" in window)) { return; } const cacheNames = await window.caches.keys(); const cachesToDelete = cacheNames.filter((cacheName) => CLEARABLE_CACHE_PREFIXES.some((prefix) => cacheName.startsWith(prefix)), ); await Promise.all(cachesToDelete.map(async (cacheName) => { try { await window.caches.delete(cacheName); } catch { } })); }