export const createHeartbeatController = (args: { intervalMs: number; heartbeat: (jobId: string) => Promise<{ cancelRequested: boolean }>; onCancel: (jobId: string) => Promise; onError: (error: unknown) => void; }) => { const timers = new Map>(); const inFlight = new Set(); const stop = (jobId: string) => { const timer = timers.get(jobId); if (timer) clearInterval(timer); timers.delete(jobId); }; const tick = async (jobId: string) => { if (inFlight.has(jobId) || !timers.has(jobId)) return; inFlight.add(jobId); try { const result = await args.heartbeat(jobId); if (result.cancelRequested) { stop(jobId); await args.onCancel(jobId); } } catch (error) { args.onError(error); } finally { inFlight.delete(jobId); } }; return { start: (jobId: string) => { stop(jobId); const timer = setInterval(() => void tick(jobId), args.intervalMs); timer.unref(); timers.set(jobId, timer); }, stop, has: (jobId: string) => timers.has(jobId), }; };