26 lines
1.1 KiB
TypeScript
26 lines
1.1 KiB
TypeScript
/** Poll visible page content without overlapping requests. Fleet watches use their own monitor. */
|
|
export function pollVisible(task: () => void | Promise<unknown>, interval: number, immediate = true): () => void {
|
|
let stopped = false;
|
|
let running = false;
|
|
let timer: ReturnType<typeof setTimeout> | undefined;
|
|
const visible = () => document.visibilityState !== 'hidden';
|
|
const run = async () => {
|
|
if (stopped || running || !visible()) return;
|
|
clearTimeout(timer);
|
|
running = true;
|
|
try { await task(); }
|
|
catch (error) { console.error('Page refresh failed', error); }
|
|
finally {
|
|
running = false;
|
|
if (!stopped && visible()) timer = setTimeout(run, interval);
|
|
}
|
|
};
|
|
const visibility = () => {
|
|
clearTimeout(timer);
|
|
if (document.visibilityState !== 'hidden') void run();
|
|
};
|
|
document.addEventListener('visibilitychange', visibility);
|
|
if (immediate) void run(); else timer = setTimeout(run, interval);
|
|
return () => { stopped = true; clearTimeout(timer); document.removeEventListener('visibilitychange', visibility); };
|
|
}
|