/** * @file newBuildReload.ts * @description Reloads the tab onto the new UI build after the server was * updated. Every update — the dashboard's own Update button in any tab, * `/agenthub-update`, a restart onto a newer plugin — drops the WebSocket; when * it comes back, `GET /api/health` names the server's version, and a version * other than this bundle's `__APP_VERSION__` means the page is stale. At most * one reload per version (sessionStorage), so a server whose UI build failed * cannot make the tab reload on every reconnect. * @author Nguyễn Ngọc Trí Vĩ */ import { eventBus } from "./eventBus"; const KEY = "agenthub.reloadedFor"; export function reloadOnNewBuild({ bundle = __APP_VERSION__, health = () => fetch("/api/health").then((r) => r.json() as Promise<{ version?: string }>), reload = () => window.location.reload(), storage = window.sessionStorage, }: { bundle?: string; health?: () => Promise<{ version?: string }>; reload?: () => void; storage?: Pick; } = {}): () => void { let wasDown = false; return eventBus.onConnection((up) => { if (!up) { wasDown = true; return; } if (!wasDown) return; wasDown = false; health() .then(({ version }) => { if (!version || version === bundle || storage.getItem(KEY) === version) return; storage.setItem(KEY, version); reload(); }) .catch(() => { /* the next reconnect asks again */ }); }); }