/** * @file A background poll that slows down while it finds nothing to do: the * next pass runs `baseMs` after a pass that did work (or failed), `idleMs` * after one whose `tick` resolved `false` (nothing changed, nothing pending). * One pass at a time — the next is scheduled only once the last settled — and * every timer is `unref`'d. Used by the Cursor and Antigravity usage polls. * @author Nguyễn Ngọc Trí Vĩ */ /** Default slow interval: 60 s, never faster than the base one. */ const idleDefault = (baseMs) => Math.max(baseMs, 60_000); /** * Run `tick` now, then again and again. `tick` resolves `false` for an idle * pass; anything else (or a throw) keeps the base pace. * @returns {{stop: () => void}} */ function startBackoffPoll(tick, { baseMs, idleMs = idleDefault(baseMs) }) { let timer = null; let stopped = false; const schedule = (ms) => { if (stopped) return; timer = setTimeout(run, ms); if (timer.unref) timer.unref(); }; function run() { Promise.resolve() .then(tick) .then( (busy) => schedule(busy === false ? idleMs : baseMs), () => schedule(baseMs) ); } run(); return { stop() { stopped = true; clearTimeout(timer); }, }; } module.exports = { startBackoffPoll, idleDefault };