/** * One background task at a time, in priority order, with same-kind coalescing. * * ── What it replaces ───────────────────────────────────────────────────── * Three independent in-flight booleans — `syncInFlight`, `intentDrainInFlight`, * `codeIndexInFlight`. Each correctly stopped its OWN tick from overlapping * itself, and none of them knew about the others, so a code-intelligence sweep * could run at the same time as a full sync walk and an intent drain. All three * are heavy: the sweep spawns codeindex and holds its output, the walk holds a * session container, the drain copies files. Measured with a sweep and a walk * overlapping, the main thread sat at 80–95% and RSS more than doubled. * * They also could not express what the daemon actually wants: shipping to the * server matters more than refreshing code intelligence, so if both are due, the * sweep should wait. * * ── Semantics ──────────────────────────────────────────────────────────── * SERIAL — exactly one task runs at a time. * * COALESCED PER KIND — if a kind is already waiting, a new request for that kind * is dropped rather than queued twice. Both would do the same work against the * same state, and the second would find nothing to do. This preserves what the * booleans got right (no self-overlap) without the "silently skipped" behaviour: * a request that arrives while its kind is RUNNING sets a re-run flag, so a file * change during a walk still gets a walk afterwards instead of being lost. * * PRIORITISED — lower number first, and only among tasks already waiting. A * running task is never preempted; a long sweep still finishes. */ export type TickKind = string; export interface TickQueueOpts { /** Reports every state change; the daemon logs through it. */ onError?: (kind: TickKind, err: unknown) => void; } export declare class TickQueue { private readonly opts; private waiting; private running; /** Kinds that asked to run while they were already running. */ private rerun; constructor(opts?: TickQueueOpts); /** The kind currently executing, or null when idle. Diagnostics only. */ get active(): TickKind | null; get depth(): number; /** * Ask for `kind` to run. Returns immediately — this is a scheduler, not a * `await`-able task. */ request(kind: TickKind, priority: number, run: () => Promise): void; private pump; /** Tests: settle the queue. */ drain(): Promise; } /** * Priorities for the daemon's ticks. Lower runs first. * * Shipping to the server is the product; everything else is enrichment. Code * intelligence is last because it is the heaviest and the least urgent — it * refreshes on a 180-minute cadence, so waiting out a walk costs nothing. */ export declare const TICK_PRIORITY: { readonly sync: 10; readonly intents: 20; readonly codeIndex: 30; readonly housekeeping: 40; }; //# sourceMappingURL=tick-queue.d.ts.map