Something went wrong. Try again.
a tool for shared writing and social publishing
Something went wrong. Try again.
1234567891011121314151617181920212223242526272829303132333435363738394041424344import { useEffect, useState } from "react";
const REFRESH_MS = 3_000;const REFRESH_WINDOW_MS = 10 * 60_000;// setTimeout fires immediately for a delay past 2^31 - 1 ms.const MAX_TIMEOUT_MS = 2 ** 31 - 1;
// The current time for a list of jobs that run at a set time, fresh enough to// tell which of them are due. While one is running (its status says so, or// it's "scheduled" and its time has come) this ticks every few seconds and// calls `refresh`, so the job settles on screen without a reload; otherwise// it wakes when the next one comes due. A job that hasn't settled within the// window is stuck, not slow.export function useDueRefresh( jobs: { status: string; dueAt: string | null }[], runningStatus: string, refresh: () => void,) { let [now, setNow] = useState(() => Date.now()); let running = false; let next = Infinity; for (let job of jobs) { let at = new Date(job.dueAt ?? 0).getTime(); if (job.status === "scheduled" && at > now) next = Math.min(next, at); else if ( (job.status === "scheduled" || job.status === runningStatus) && now - at < REFRESH_WINDOW_MS ) running = true; } useEffect(() => { if (!running && next === Infinity) return; let timeout = setTimeout( () => { setNow(Date.now()); if (running) refresh(); }, running ? REFRESH_MS : Math.min(next - now, MAX_TIMEOUT_MS), ); return () => clearTimeout(timeout); }, [running, next, now, refresh]); return now;}