import EventEmitter from "events"; import { Multimap } from "./multimap.js"; export type TaskOptions = { taskId: TASK_ID; signal: AbortSignal; onComplete: (success: boolean) => void; }; export type TaskTreeOptions = { jobs: number; }; export declare class CycleError extends Error { cycle: TASK_ID[]; constructor(cycle: TASK_ID[]); } export type TaskStatus = 'n/a' | 'pending' | 'running' | 'ok' | 'fail'; export type TaskTreeStatus = 'ok' | 'fail' | 'pending' | 'running'; type TaskTreeEvents = { 'tree_status_changed': [TaskTreeStatus]; 'task_started': [TASK_ID]; 'task_finished': [TASK_ID]; 'task_reset': [TASK_ID]; }; /** * Task tree is an orchestration engine. It is given a set of tasks with their IDs and their * inter-dependencies, and its goal to run these tasks to a completion. * * TaskTree doesn't know how to run tasks and it doesn't know about task inputs. Instead, its clients * are requested to run tasks (via provided callback) and they should notify TaskTree about task input * changes via the `taskTree.markChanged(taskId)` method. * * Tasks are organized as a directed acyclic graph; TaskTree makes sure to never accept tasks with cycles * and will throw in this case. * * Once initialized, TaskTree requires client to call `run()` to start running tasks. TaskTree will * advance tasks execution until there will be no more runnable tasks. In this case, it will fire the "completed" * event. * * TaskTree will also run the following events, signaling about Task lifecycle: * - "task_started" - when the execution of a task started * - "task_finished" - when the execution completed * - "task_reset" - when the execution was started, but it is no longer relevant since task version has changed due to * either `taskTree.setTasks()` or `taskTree.markChanged()` methods. */ export declare class TaskTree extends EventEmitter> { private _runCallback; private _options; static findDependencyCycle(tasks: Multimap): TASK_ID[] | undefined; private _tasks; private _roots; private _status; constructor(_runCallback: (options: TaskOptions) => void, _options: TaskTreeOptions); private _computeTreeStatus; private _setTreeStatus; status(): TaskTreeStatus; taskStatus(taskId: TASK_ID): TaskStatus; resetAllTasks(): void; clear(): void; /** * Set build tree. This will synchronously abort builds for those nodes * that were either removed or changed their dependencies. * NOTE: to actually kick off build, call `taskTree.run()` after setting the tree. * @param tasks */ setTasks(tasks: Multimap): void; topsort(): TASK_ID[]; bfs(): TASK_ID[]; children(taskId: TASK_ID): TASK_ID[]; parents(taskId: TASK_ID): TASK_ID[]; taskVersion(taskId: TASK_ID): string; /** * This will synchronously abort builds for the `nodeId` and all its parents. * @param taskId */ markChanged(taskId: TASK_ID): void; private _resetTask; private _runnableTasks; private _tasksBeingRun; /** * This method will traverse the tree and start building nodes that are buildable. * Note that once these nodes complete to build, other node will be started. * To stop the process, run the `resetAllBuilds()` method. * @returns */ run(): void; private _onTaskComplete; } export {};