// src/utils/versionGuard.js const VERSION_URL = '/version.json'; const LS_KEY = '__app_version__'; const SESSION_REFRESH_FLAG = '__just_refreshed__'; async function fetchRemoteVersion() { const res = await fetch(VERSION_URL, { cache: 'no-store' }); // ★ 關鍵:不快取 if (!res.ok) throw new Error('version.json fetch failed'); return res.json(); } async function unregisterAllSW() { if (!('serviceWorker' in navigator)) return; const regs = await navigator.serviceWorker.getRegistrations(); await Promise.all(regs.map(r => r.unregister())); } async function clearCacheStorage() { if (!('caches' in window)) return; const keys = await caches.keys(); await Promise.all(keys.map(k => caches.delete(k))); } export async function ensureFreshAssets() { try { const prev = localStorage.getItem(LS_KEY); const remote = await fetchRemoteVersion(); const ver = remote.version || remote.buildId || remote.commit; if (!ver) return; if (prev && prev !== ver) { await unregisterAllSW(); await clearCacheStorage(); sessionStorage.setItem(SESSION_REFRESH_FLAG, '1'); // 用 replace 避免回上一頁又載到舊 index.html location.replace(location.href.split('#')[0]); return; } if (!prev) localStorage.setItem(LS_KEY, ver); } catch (e) { console.warn('[versionGuard] check failed:', e); } } export async function syncLocalVersion() { try { const remote = await fetchRemoteVersion(); const ver = remote.version || remote.buildId || remote.commit; if (ver) localStorage.setItem(LS_KEY, ver); } catch {} }