//#region src/core/tasks/task.d.ts /** Recursively marks all properties as readonly. */ type DeepReadonly = T extends (infer U)[] ? ReadonlyArray> : T extends object ? { readonly [K in keyof T]: DeepReadonly; } : T; type TaskStatus = 'pending' | 'running' | 'done' | 'error'; /** * Configuration for a Task. */ interface TaskConfig { /** * Identifier for this task. * - string: used as-is * - () => string: called once at construction time * - undefined: a unique ID is generated via generateId() */ id?: string | (() => string); /** * Optional external AbortSignal to compose with the task's internal one. * The task's work is aborted when either the internal controller (via abort()) * or this external signal fires — whichever comes first. */ signal?: AbortSignal; } /** * Minimal contract for a schedulable unit of async work. */ interface TaskLike { readonly id: string; readonly status: TaskStatus; readonly value: DeepReadonly | undefined; readonly error: DeepReadonly | undefined; run(): Promise; abort(): void; } /** * Generic reusable task that wraps an async run function. * * Owns its own AbortController so it can always be aborted independently. * Optionally composes an external AbortSignal so that a parent's cancellation * propagates into the task's work without requiring the caller to track the * task separately. * * Ordering guarantee: `value` is written before `status` transitions to `'done'`; * `error` is written before `status` transitions to `'error'`. Any reader * observing `status === 'done'` is guaranteed `value` is already present. */ declare class Task implements TaskLike { #private; readonly id: string; constructor(runFn: (signal: AbortSignal) => Promise, config?: TaskConfig); get status(): TaskStatus; get value(): DeepReadonly | undefined; get error(): DeepReadonly | undefined; run(): Promise; abort(): void; } /** * Runs tasks concurrently, deduplicated by task id. * * If a task with a given id is already in flight, subsequent schedule() calls * for that id are silently ignored until the first completes. Tasks are stored * so abortAll() can cancel any in-flight work (e.g. on engine cleanup). */ declare class ConcurrentRunner { #private; schedule(task: TaskLike): Promise; /** * Registers a callback to fire when all currently in-flight tasks settle. * If the runner is already idle, the callback is never called. If abortAll() * is called before the batch settles, the callback is superseded and silently * dropped — no stale callbacks, no generation token required by the caller. */ whenSettled(callback: () => void): void; abortAll(): void; destroy(): void; } /** * Runs tasks one at a time in submission order. * * Each schedule() call returns a Promise that resolves or rejects with the * task's result when it is eventually executed. Tasks wait in queue until the * prior task completes. * * Serialization is achieved by chaining each task's run() onto the tail of a * shared promise chain — no explicit queue or drain loop needed. * * abortAll() aborts all pending (not yet started) tasks and the currently * in-flight task. Pending tasks still run briefly but receive an aborted * signal and are expected to exit early. */ declare class SerialRunner { #private; schedule(task: TaskLike): Promise; /** * A promise that resolves when all currently-scheduled tasks have settled. * Use the reference as a generation token: capture it after scheduling a * batch, then check identity in the resolution callback to detect whether * a subsequent abortAll() + new batch has superseded this one. */ get settled(): Promise; /** * Registers a callback to fire when all currently-pending tasks settle. * If the runner is already idle (no pending or running tasks), the callback * is never called. If new tasks are scheduled before the current batch * settles, the callback is superseded and silently dropped — no stale * callbacks, no generation token required by the caller. */ whenSettled(callback: () => void): void; /** Aborts and clears queued tasks without touching the in-flight task. */ abortPending(): void; abortAll(): void; destroy(): void; } //#endregion export { ConcurrentRunner, DeepReadonly, SerialRunner, Task, TaskConfig, TaskLike, TaskStatus }; //# sourceMappingURL=task.d.ts.map