7cec3030c1
Move frontend sources to frontend/, build content-hashed assets at deploy, network-first SW for shell/JS, immutable cache for /assets/, version.json update banner, and Cache-Control middleware. Docs in docs/PWA-STRATEGY.md. Co-authored-by: Cursor <cursoragent@cursor.com>
63 lines
1.7 KiB
JavaScript
63 lines
1.7 KiB
JavaScript
let bannerVisible = false;
|
|
|
|
function showUpdateBanner() {
|
|
if (bannerVisible) return;
|
|
const banner = document.getElementById("updateBanner");
|
|
if (!banner) return;
|
|
banner.hidden = false;
|
|
bannerVisible = true;
|
|
}
|
|
|
|
async function applyUpdate() {
|
|
const reg = await navigator.serviceWorker?.getRegistration();
|
|
if (reg?.waiting) {
|
|
reg.waiting.postMessage({ type: "SKIP_WAITING" });
|
|
} else {
|
|
await reg?.update();
|
|
location.reload();
|
|
}
|
|
}
|
|
|
|
export function wireAppUpdates() {
|
|
if (!("serviceWorker" in navigator)) return;
|
|
|
|
let refreshing = false;
|
|
navigator.serviceWorker.addEventListener("controllerchange", () => {
|
|
if (refreshing) return;
|
|
refreshing = true;
|
|
location.reload();
|
|
});
|
|
|
|
navigator.serviceWorker.addEventListener("message", (event) => {
|
|
if (event.data?.type === "UPDATE_AVAILABLE") showUpdateBanner();
|
|
});
|
|
|
|
const button = document.getElementById("updateBannerBtn");
|
|
button?.addEventListener("click", () => applyUpdate());
|
|
|
|
const checkVersion = async () => {
|
|
try {
|
|
const reg = await navigator.serviceWorker.getRegistration();
|
|
await reg?.update();
|
|
|
|
const built = document.querySelector('meta[name="app-build"]')?.content;
|
|
if (!built) return;
|
|
|
|
const res = await fetch("/version.json", { cache: "no-store" });
|
|
if (!res.ok) return;
|
|
const data = await res.json();
|
|
if (data.buildHash && data.buildHash !== built) {
|
|
showUpdateBanner();
|
|
}
|
|
} catch {
|
|
/* ignore — offline or transient */
|
|
}
|
|
};
|
|
|
|
window.addEventListener("focus", checkVersion);
|
|
document.addEventListener("visibilitychange", () => {
|
|
if (document.visibilityState === "visible") checkVersion();
|
|
});
|
|
checkVersion();
|
|
}
|