@workglow/task-graph 0.0.87 → 0.0.89

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/bun.js.map CHANGED
@@ -1,13 +1,12 @@
1
1
  {
2
2
  "version": 3,
3
- "sources": ["../src/task/TaskTypes.ts", "../src/task-graph/Dataflow.ts", "../src/common.ts", "../src/task-graph/TaskGraph.ts", "../src/task/GraphAsTask.ts", "../src/task-graph/TaskGraphRunner.ts", "../src/storage/TaskOutputRepository.ts", "../src/task/Task.ts", "../src/task/TaskError.ts", "../src/task/TaskRunner.ts", "../src/task/InputResolver.ts", "../src/task/ConditionalTask.ts", "../src/task-graph/TaskGraphScheduler.ts", "../src/task/GraphAsTaskRunner.ts", "../src/task-graph/Conversions.ts", "../src/task-graph/Workflow.ts", "../src/task-graph/TaskGraphEvents.ts", "../src/task/IteratorTaskRunner.ts", "../src/task/TaskQueueRegistry.ts", "../src/task/IteratorTask.ts", "../src/task/BatchTask.ts", "../src/task/ForEachTask.ts", "../src/task/JobQueueFactory.ts", "../src/task/JobQueueTask.ts", "../src/task/MapTask.ts", "../src/task/ReduceTask.ts", "../src/task/TaskJSON.ts", "../src/task/TaskRegistry.ts", "../src/task/index.ts", "../src/task/WhileTask.ts", "../src/storage/TaskGraphRepository.ts", "../src/storage/TaskGraphTabularRepository.ts", "../src/storage/TaskOutputTabularRepository.ts"],
3
+ "sources": ["../src/task-graph/Dataflow.ts", "../src/task/TaskTypes.ts", "../src/task-graph/TaskGraph.ts", "../src/task/GraphAsTask.ts", "../src/task-graph/TaskGraphRunner.ts", "../src/storage/TaskOutputRepository.ts", "../src/task/Task.ts", "../src/task/TaskError.ts", "../src/task/TaskRunner.ts", "../src/task/InputResolver.ts", "../src/task/ConditionalTask.ts", "../src/task-graph/TaskGraphScheduler.ts", "../src/task/GraphAsTaskRunner.ts", "../src/task-graph/Workflow.ts", "../src/task-graph/Conversions.ts", "../src/task-graph/TaskGraphEvents.ts", "../src/task/JobQueueFactory.ts", "../src/task/JobQueueTask.ts", "../src/task/TaskQueueRegistry.ts", "../src/task/TaskRegistry.ts", "../src/task/TaskJSON.ts", "../src/task/index.ts", "../src/storage/TaskGraphRepository.ts", "../src/storage/TaskGraphTabularRepository.ts", "../src/storage/TaskOutputTabularRepository.ts"],
4
4
  "sourcesContent": [
5
- "/**\n * @license\n * Copyright 2025 Steven Roussey <sroussey@gmail.com>\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport { StripJSONSchema } from \"@workglow/util\";\nimport { TaskOutputRepository } from \"../storage/TaskOutputRepository\";\nimport type { Task } from \"./Task\";\n\n/**\n * Enum representing the possible states of a task\n *\n * PENDING -> PROCESSING -> COMPLETED\n * PENDING -> PROCESSING -> ABORTING -> FAILED\n * PENDING -> PROCESSING -> FAILED\n * PENDING -> DISABLED\n */\nexport type TaskStatus =\n | \"PENDING\"\n | \"DISABLED\"\n | \"PROCESSING\"\n | \"COMPLETED\"\n | \"ABORTING\"\n | \"FAILED\";\n\nexport const TaskStatus = {\n /** Task is created but not yet started */\n PENDING: \"PENDING\",\n /** Task is disabled due to conditional logic */\n DISABLED: \"DISABLED\",\n /** Task is currently running */\n PROCESSING: \"PROCESSING\",\n /** Task has completed successfully */\n COMPLETED: \"COMPLETED\",\n /** Task is in the process of being aborted */\n ABORTING: \"ABORTING\",\n /** Task has failed */\n FAILED: \"FAILED\",\n} as const satisfies Record<TaskStatus, TaskStatus>;\n\n// ========================================================================\n// Core Task Data Types\n// ========================================================================\n\nexport interface DataPorts extends StripJSONSchema<Record<string, any>> {\n [key: string]: unknown;\n}\n\n/** Type for task input data */\nexport type TaskInput = DataPorts;\n\n/** Type for task output data */\nexport type TaskOutput = DataPorts;\n\nexport type CompoundTaskOutput =\n | {\n outputs: TaskOutput[];\n }\n | {\n [key: string]: unknown | unknown[] | undefined;\n };\n\n\n/** Type for task type names */\nexport type TaskTypeName = string;\n\n/** Type for task configuration */\nexport type TaskConfig = Partial<IConfig>;\n\n// ========================================================================\n// Task Configuration Types\n// ========================================================================\n\nexport interface IConfig {\n /** Unique identifier for the task */\n id: unknown;\n\n /** Optional display name for the task */\n name?: string;\n\n\n /** Optional ID of the runner to use for this task */\n runnerId?: string;\n\n /** Optional output cache to use for this task */\n outputCache?: TaskOutputRepository | boolean;\n\n /** Optional cacheable flag to use for this task, overriding the default static property */\n cacheable?: boolean;\n\n /** Optional user data to use for this task, not used by the task framework except it will be exported as part of the task JSON*/\n extras?: DataPorts;\n}\n\n/** Type for task ID */\nexport type TaskIdType = Task<TaskInput, TaskOutput, TaskConfig>[\"config\"][\"id\"];\n",
6
5
  "/**\n * @license\n * Copyright 2025 Steven Roussey <sroussey@gmail.com>\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport { areSemanticallyCompatible, EventEmitter } from \"@workglow/util\";\nimport { TaskError } from \"../task/TaskError\";\nimport { DataflowJson } from \"../task/TaskJSON\";\nimport { TaskIdType, TaskOutput, TaskStatus } from \"../task/TaskTypes\";\nimport {\n DataflowEventListener,\n DataflowEventListeners,\n DataflowEventParameters,\n DataflowEvents,\n} from \"./DataflowEvents\";\nimport { TaskGraph } from \"./TaskGraph\";\n\nexport type DataflowIdType = `${string}[${string}] ==> ${string}[${string}]`;\n\nexport const DATAFLOW_ALL_PORTS = \"*\";\nexport const DATAFLOW_ERROR_PORT = \"[error]\";\n\n/**\n * Represents a data flow between two tasks, indicating how one task's output is used as input for another task\n */\nexport class Dataflow {\n constructor(\n public sourceTaskId: TaskIdType,\n public sourceTaskPortId: string,\n public targetTaskId: TaskIdType,\n public targetTaskPortId: string\n ) {}\n public static createId(\n sourceTaskId: TaskIdType,\n sourceTaskPortId: string,\n targetTaskId: TaskIdType,\n targetTaskPortId: string\n ): DataflowIdType {\n return `${sourceTaskId}[${sourceTaskPortId}] ==> ${targetTaskId}[${targetTaskPortId}]`;\n }\n get id(): DataflowIdType {\n return Dataflow.createId(\n this.sourceTaskId,\n this.sourceTaskPortId,\n this.targetTaskId,\n this.targetTaskPortId\n );\n }\n public value: any = undefined;\n public status: TaskStatus = TaskStatus.PENDING;\n public error: TaskError | undefined;\n\n public reset() {\n this.status = TaskStatus.PENDING;\n this.error = undefined;\n this.value = undefined;\n this.emit(\"reset\");\n this.emit(\"status\", this.status);\n }\n\n public setStatus(status: TaskStatus) {\n if (status === this.status) return;\n this.status = status;\n switch (status) {\n case TaskStatus.PROCESSING:\n this.emit(\"start\");\n break;\n case TaskStatus.COMPLETED:\n this.emit(\"complete\");\n break;\n case TaskStatus.ABORTING:\n this.emit(\"abort\");\n break;\n case TaskStatus.PENDING:\n this.emit(\"reset\");\n break;\n case TaskStatus.FAILED:\n this.emit(\"error\", this.error!);\n break;\n case TaskStatus.DISABLED:\n this.emit(\"disabled\");\n break;\n }\n this.emit(\"status\", this.status);\n }\n\n setPortData(entireDataBlock: any) {\n if (this.sourceTaskPortId === DATAFLOW_ALL_PORTS) {\n this.value = entireDataBlock;\n } else if (this.sourceTaskPortId === DATAFLOW_ERROR_PORT) {\n this.error = entireDataBlock;\n } else {\n this.value = entireDataBlock[this.sourceTaskPortId];\n }\n }\n\n getPortData(): TaskOutput {\n let result: TaskOutput;\n if (this.targetTaskPortId === DATAFLOW_ALL_PORTS) {\n result = this.value;\n } else if (this.targetTaskPortId === DATAFLOW_ERROR_PORT) {\n result = { [DATAFLOW_ERROR_PORT]: this.error };\n } else {\n result = { [this.targetTaskPortId]: this.value };\n }\n return result;\n }\n\n toJSON(): DataflowJson {\n return {\n sourceTaskId: this.sourceTaskId,\n sourceTaskPortId: this.sourceTaskPortId,\n targetTaskId: this.targetTaskId,\n targetTaskPortId: this.targetTaskPortId,\n };\n }\n\n semanticallyCompatible(\n graph: TaskGraph,\n dataflow: Dataflow\n ): \"static\" | \"runtime\" | \"incompatible\" {\n // TODO(str): this is inefficient\n const targetSchema = graph.getTask(dataflow.targetTaskId)!.inputSchema();\n const sourceSchema = graph.getTask(dataflow.sourceTaskId)!.outputSchema();\n\n if (typeof targetSchema === \"boolean\") {\n if (targetSchema === false) {\n return \"incompatible\";\n }\n return \"static\";\n }\n if (typeof sourceSchema === \"boolean\") {\n if (sourceSchema === false) {\n return \"incompatible\";\n }\n return \"runtime\";\n }\n\n let targetSchemaProperty =\n DATAFLOW_ALL_PORTS === dataflow.targetTaskPortId\n ? true // Accepts any schema (equivalent to Type.Any())\n : (targetSchema.properties as any)?.[dataflow.targetTaskPortId];\n // If the specific property doesn't exist but additionalProperties is true,\n // treat it as accepting any schema\n if (targetSchemaProperty === undefined && targetSchema.additionalProperties === true) {\n targetSchemaProperty = true;\n }\n let sourceSchemaProperty =\n DATAFLOW_ALL_PORTS === dataflow.sourceTaskPortId\n ? true // Accepts any schema (equivalent to Type.Any())\n : (sourceSchema.properties as any)?.[dataflow.sourceTaskPortId];\n // If the specific property doesn't exist but additionalProperties is true,\n // treat it as outputting any schema\n if (sourceSchemaProperty === undefined && sourceSchema.additionalProperties === true) {\n sourceSchemaProperty = true;\n }\n\n const semanticallyCompatible = areSemanticallyCompatible(\n sourceSchemaProperty,\n targetSchemaProperty\n );\n\n return semanticallyCompatible;\n }\n\n // ========================================================================\n // Event handling methods\n // ========================================================================\n\n /**\n * Event emitter for dataflow events\n */\n public get events(): EventEmitter<DataflowEventListeners> {\n if (!this._events) {\n this._events = new EventEmitter<DataflowEventListeners>();\n }\n return this._events;\n }\n protected _events: EventEmitter<DataflowEventListeners> | undefined;\n\n public subscribe<Event extends DataflowEvents>(\n name: Event,\n fn: DataflowEventListener<Event>\n ): () => void {\n return this.events.subscribe(name, fn);\n }\n\n /**\n * Registers an event listener\n */\n public on<Event extends DataflowEvents>(name: Event, fn: DataflowEventListener<Event>): void {\n this.events.on(name, fn);\n }\n\n /**\n * Removes an event listener\n */\n public off<Event extends DataflowEvents>(name: Event, fn: DataflowEventListener<Event>): void {\n this.events.off(name, fn);\n }\n\n /**\n * Registers a one-time event listener\n */\n public once<Event extends DataflowEvents>(name: Event, fn: DataflowEventListener<Event>): void {\n this.events.once(name, fn);\n }\n\n /**\n * Returns a promise that resolves when the specified event is emitted\n */\n public waitOn<Event extends DataflowEvents>(\n name: Event\n ): Promise<DataflowEventParameters<Event>> {\n return this.events.waitOn(name) as Promise<DataflowEventParameters<Event>>;\n }\n\n /**\n * Emits an event\n */\n public emit<Event extends DataflowEvents>(\n name: Event,\n ...args: DataflowEventParameters<Event>\n ): void {\n this._events?.emit(name, ...args);\n }\n}\n\n/**\n * Represents a data flow between two tasks, indicating how one task's output is used as input for another task\n *\n * This is a helper class that parses a data flow id string into a Dataflow object\n *\n * @param dataflow - The data flow string, e.g. \"sourceTaskId[sourceTaskPortId] ==> targetTaskId[targetTaskPortId]\"\n */\nexport class DataflowArrow extends Dataflow {\n constructor(dataflow: DataflowIdType) {\n // Parse the dataflow string using regex\n const pattern =\n /^([a-zA-Z0-9-]+?)\\[([a-zA-Z0-9-]+?)\\] ==> ([a-zA-Z0-9-]+?)\\[([a-zA-Z0-9-]+?)\\]$/;\n const match = dataflow.match(pattern);\n\n if (!match) {\n throw new Error(`Invalid dataflow format: ${dataflow}`);\n }\n\n const [, sourceTaskId, sourceTaskPortId, targetTaskId, targetTaskPortId] = match;\n super(sourceTaskId, sourceTaskPortId, targetTaskId, targetTaskPortId);\n }\n}\n",
7
- "/**\n * @license\n * Copyright 2025 Steven Roussey <sroussey@gmail.com>\n * SPDX-License-Identifier: Apache-2.0\n */\n\nexport * from \"./task-graph/Dataflow\";\nexport * from \"./task-graph/DataflowEvents\";\n\nexport * from \"./task-graph/ITaskGraph\";\nexport * from \"./task-graph/TaskGraph\";\nexport * from \"./task-graph/TaskGraphEvents\";\nexport * from \"./task-graph/TaskGraphRunner\";\n\nexport * from \"./task-graph/Conversions\";\nexport * from \"./task-graph/IWorkflow\";\nexport * from \"./task-graph/Workflow\";\n\nexport * from \"./task\";\n\nexport * from \"./storage/TaskGraphRepository\";\nexport * from \"./storage/TaskGraphTabularRepository\";\nexport * from \"./storage/TaskOutputRepository\";\nexport * from \"./storage/TaskOutputTabularRepository\";\n",
8
- "/**\n * @license\n * Copyright 2025 Steven Roussey <sroussey@gmail.com>\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport { DirectedAcyclicGraph, EventEmitter, ServiceRegistry, uuid4 } from \"@workglow/util\";\nimport { TaskOutputRepository } from \"../storage/TaskOutputRepository\";\nimport type { ITask } from \"../task/ITask\";\nimport { JsonTaskItem, TaskGraphJson } from \"../task/TaskJSON\";\nimport type { TaskIdType, TaskInput, TaskOutput, TaskStatus } from \"../task/TaskTypes\";\nimport { ensureTask, type PipeFunction } from \"./Conversions\";\nimport { Dataflow, type DataflowIdType } from \"./Dataflow\";\nimport type { ITaskGraph } from \"./ITaskGraph\";\nimport {\n EventTaskGraphToDagMapping,\n GraphEventDagEvents,\n GraphEventDagParameters,\n TaskGraphEventListener,\n TaskGraphEvents,\n TaskGraphEventStatusParameters,\n TaskGraphStatusEvents,\n TaskGraphStatusListeners,\n} from \"./TaskGraphEvents\";\nimport {\n CompoundMergeStrategy,\n GraphResult,\n type GraphResultArray,\n TaskGraphRunner,\n} from \"./TaskGraphRunner\";\n\n/**\n * Configuration for running a task graph\n */\nexport interface TaskGraphRunConfig {\n /** Optional output cache to use for this task graph */\n outputCache?: TaskOutputRepository | boolean;\n /** Optional signal to abort the task graph */\n parentSignal?: AbortSignal;\n /** Optional service registry to use for this task graph (creates child from global if not provided) */\n registry?: ServiceRegistry;\n}\n\nclass TaskGraphDAG extends DirectedAcyclicGraph<\n ITask<any, any, any>,\n Dataflow,\n TaskIdType,\n DataflowIdType\n> {\n constructor() {\n super(\n (task: ITask<any, any, any>) => task.config.id,\n (dataflow: Dataflow) => dataflow.id\n );\n }\n}\n\ninterface TaskGraphConstructorConfig {\n outputCache?: TaskOutputRepository;\n dag?: TaskGraphDAG;\n}\n\n/**\n * Represents a task graph, a directed acyclic graph of tasks and data flows\n */\nexport class TaskGraph implements ITaskGraph {\n /** Optional output cache to use for this task graph */\n public outputCache?: TaskOutputRepository;\n\n /**\n * Constructor for TaskGraph\n * @param config Configuration for the task graph\n */\n constructor({ outputCache, dag }: TaskGraphConstructorConfig = {}) {\n this.outputCache = outputCache;\n this._dag = dag || new TaskGraphDAG();\n }\n\n private _dag: TaskGraphDAG;\n\n private _runner: TaskGraphRunner | undefined;\n public get runner(): TaskGraphRunner {\n if (!this._runner) {\n this._runner = new TaskGraphRunner(this, this.outputCache);\n }\n return this._runner;\n }\n\n // ========================================================================\n // Public methods\n // ========================================================================\n\n /**\n * Runs the task graph\n * @param config Configuration for the graph run\n * @returns A promise that resolves when all tasks are complete\n * @throws TaskError if any tasks have failed\n */\n public run<ExecuteOutput extends TaskOutput>(\n input: TaskInput = {} as TaskInput,\n config: TaskGraphRunConfig = {}\n ): Promise<GraphResultArray<ExecuteOutput>> {\n return this.runner.runGraph<ExecuteOutput>(input, {\n outputCache: config?.outputCache || this.outputCache,\n parentSignal: config?.parentSignal || undefined,\n });\n }\n\n /**\n * Runs the task graph reactively\n * @returns A promise that resolves when all tasks are complete\n * @throws TaskError if any tasks have failed\n */\n public runReactive<Output extends TaskOutput>(): Promise<GraphResultArray<Output>> {\n return this.runner.runGraphReactive<Output>();\n }\n\n /**\n * Merges the execute output to the run output\n * @param results The execute output\n * @param compoundMerge The compound merge strategy to use\n * @returns The run output\n */\n\n public mergeExecuteOutputsToRunOutput<\n ExecuteOutput extends TaskOutput,\n Merge extends CompoundMergeStrategy = CompoundMergeStrategy,\n >(\n results: GraphResultArray<ExecuteOutput>,\n compoundMerge: Merge\n ): GraphResult<ExecuteOutput, Merge> {\n return this.runner.mergeExecuteOutputsToRunOutput(results, compoundMerge);\n }\n\n /**\n * Aborts the task graph\n */\n public abort() {\n this.runner.abort();\n }\n\n /**\n * Disables the task graph\n */\n public async disable() {\n await this.runner.disable();\n }\n\n /**\n * Retrieves a task from the task graph by its id\n * @param id The id of the task to retrieve\n * @returns The task with the given id, or undefined if not found\n */\n public getTask(id: TaskIdType): ITask<any, any, any> | undefined {\n return this._dag.getNode(id);\n }\n\n /**\n * Retrieves all tasks in the task graph\n * @returns An array of tasks in the task graph\n */\n public getTasks(): ITask<any, any, any>[] {\n return this._dag.getNodes();\n }\n\n /**\n * Retrieves all tasks in the task graph topologically sorted\n * @returns An array of tasks in the task graph topologically sorted\n */\n public topologicallySortedNodes(): ITask<any, any, any>[] {\n return this._dag.topologicallySortedNodes();\n }\n\n /**\n * Adds a task to the task graph\n * @param task The task to add\n * @returns The current task graph\n */\n public addTask(fn: PipeFunction<any, any>, config?: any): unknown;\n public addTask(task: ITask<any, any, any>): unknown;\n public addTask(task: ITask<any, any, any> | PipeFunction<any, any>, config?: any): unknown {\n return this._dag.addNode(ensureTask(task, config));\n }\n\n /**\n * Adds multiple tasks to the task graph\n * @param tasks The tasks to add\n * @returns The current task graph\n */\n public addTasks(tasks: PipeFunction<any, any>[]): unknown[];\n public addTasks(tasks: ITask<any, any, any>[]): unknown[];\n public addTasks(tasks: ITask<any, any, any>[] | PipeFunction<any, any>[]): unknown[] {\n return this._dag.addNodes(tasks.map(ensureTask));\n }\n\n /**\n * Adds a data flow to the task graph\n * @param dataflow The data flow to add\n * @returns The current task graph\n */\n public addDataflow(dataflow: Dataflow) {\n return this._dag.addEdge(dataflow.sourceTaskId, dataflow.targetTaskId, dataflow);\n }\n\n /**\n * Adds multiple data flows to the task graph\n * @param dataflows The data flows to add\n * @returns The current task graph\n */\n public addDataflows(dataflows: Dataflow[]) {\n const addedEdges = dataflows.map<[s: unknown, t: unknown, e: Dataflow]>((edge) => {\n return [edge.sourceTaskId, edge.targetTaskId, edge];\n });\n return this._dag.addEdges(addedEdges);\n }\n\n /**\n * Retrieves a data flow from the task graph by its id\n * @param id The id of the data flow to retrieve\n * @returns The data flow with the given id, or undefined if not found\n */\n public getDataflow(id: DataflowIdType): Dataflow | undefined {\n // @ts-ignore\n for (const i in this._dag.adjacency) {\n // @ts-ignore\n for (const j in this._dag.adjacency[i]) {\n // @ts-ignore\n const maybeEdges = this._dag.adjacency[i][j];\n if (maybeEdges !== null) {\n for (const edge of maybeEdges) {\n // @ts-ignore\n if (this._dag.edgeIdentity(edge, \"\", \"\") == id) {\n return edge;\n }\n }\n }\n }\n }\n }\n\n /**\n * Retrieves all data flows in the task graph\n * @returns An array of data flows in the task graph\n */\n public getDataflows(): Dataflow[] {\n return this._dag.getEdges().map((edge) => edge[2]);\n }\n\n /**\n * Removes a data flow from the task graph\n * @param dataflow The data flow to remove\n * @returns The current task graph\n */\n public removeDataflow(dataflow: Dataflow) {\n return this._dag.removeEdge(dataflow.sourceTaskId, dataflow.targetTaskId, dataflow.id);\n }\n\n /**\n * Retrieves the data flows that are sources of a given task\n * @param taskId The id of the task to retrieve sources for\n * @returns An array of data flows that are sources of the given task\n */\n public getSourceDataflows(taskId: unknown): Dataflow[] {\n return this._dag.inEdges(taskId).map(([, , dataflow]) => dataflow);\n }\n\n /**\n * Retrieves the data flows that are targets of a given task\n * @param taskId The id of the task to retrieve targets for\n * @returns An array of data flows that are targets of the given task\n */\n public getTargetDataflows(taskId: unknown): Dataflow[] {\n return this._dag.outEdges(taskId).map(([, , dataflow]) => dataflow);\n }\n\n /**\n * Retrieves the tasks that are sources of a given task\n * @param taskId The id of the task to retrieve sources for\n * @returns An array of tasks that are sources of the given task\n */\n public getSourceTasks(taskId: unknown): ITask<any, any, any>[] {\n return this.getSourceDataflows(taskId).map((dataflow) => this.getTask(dataflow.sourceTaskId)!);\n }\n\n /**\n * Retrieves the tasks that are targets of a given task\n * @param taskId The id of the task to retrieve targets for\n * @returns An array of tasks that are targets of the given task\n */\n public getTargetTasks(taskId: unknown): ITask<any, any, any>[] {\n return this.getTargetDataflows(taskId).map((dataflow) => this.getTask(dataflow.targetTaskId)!);\n }\n\n /**\n * Removes a task from the task graph\n * @param taskId The id of the task to remove\n * @returns The current task graph\n */\n public removeTask(taskId: unknown) {\n return this._dag.removeNode(taskId);\n }\n\n public resetGraph() {\n this.runner.resetGraph(this, uuid4());\n }\n\n /**\n * Converts the task graph to a JSON format suitable for dependency tracking\n * @returns An array of JsonTaskItem objects, each representing a task and its dependencies\n */\n public toJSON(): TaskGraphJson {\n const tasks = this.getTasks().map((node) => node.toJSON());\n const dataflows = this.getDataflows().map((df) => df.toJSON());\n return {\n tasks,\n dataflows,\n };\n }\n\n /**\n * Converts the task graph to a JSON format suitable for dependency tracking\n * @returns An array of JsonTaskItem objects, each representing a task and its dependencies\n */\n public toDependencyJSON(): JsonTaskItem[] {\n const tasks = this.getTasks().flatMap((node) => node.toDependencyJSON());\n this.getDataflows().forEach((df) => {\n const target = tasks.find((node) => node.id === df.targetTaskId)!;\n if (!target.dependencies) {\n target.dependencies = {};\n }\n const targetDeps = target.dependencies[df.targetTaskPortId];\n if (!targetDeps) {\n target.dependencies[df.targetTaskPortId] = {\n id: df.sourceTaskId,\n output: df.sourceTaskPortId,\n };\n } else {\n if (Array.isArray(targetDeps)) {\n targetDeps.push({\n id: df.sourceTaskId,\n output: df.sourceTaskPortId,\n });\n } else {\n target.dependencies[df.targetTaskPortId] = [\n targetDeps,\n { id: df.sourceTaskId, output: df.sourceTaskPortId },\n ];\n }\n }\n });\n return tasks;\n }\n\n // ========================================================================\n // Event handling\n // ========================================================================\n\n /**\n * Event emitter for task lifecycle events\n */\n public get events(): EventEmitter<TaskGraphStatusListeners> {\n if (!this._events) {\n this._events = new EventEmitter<TaskGraphStatusListeners>();\n }\n return this._events;\n }\n protected _events: EventEmitter<TaskGraphStatusListeners> | undefined;\n\n /**\n * Subscribes to an event\n * @param name - The event name to listen for\n * @param fn - The callback function to execute when the event occurs\n * @returns a function to unsubscribe from the event\n */\n public subscribe<Event extends TaskGraphEvents>(\n name: Event,\n fn: TaskGraphEventListener<Event>\n ): () => void {\n this.on(name, fn);\n return () => this.off(name, fn);\n }\n\n /**\n * Subscribes to status changes on all tasks (existing and future)\n * @param callback - Function called when any task's status changes\n * @param callback.taskId - The ID of the task whose status changed\n * @param callback.status - The new status of the task\n * @returns a function to unsubscribe from all task status events\n */\n public subscribeToTaskStatus(\n callback: (taskId: TaskIdType, status: TaskStatus) => void\n ): () => void {\n const unsubscribes: (() => void)[] = [];\n\n // Subscribe to status events on all existing tasks\n const tasks = this.getTasks();\n tasks.forEach((task) => {\n const unsub = task.subscribe(\"status\", (status) => {\n callback(task.config.id, status);\n });\n unsubscribes.push(unsub);\n });\n\n const handleTaskAdded = (taskId: TaskIdType) => {\n const task = this.getTask(taskId);\n if (!task || typeof task.subscribe !== \"function\") return;\n\n const unsub = task.subscribe(\"status\", (status) => {\n callback(task.config.id, status);\n });\n unsubscribes.push(unsub);\n };\n\n const graphUnsub = this.subscribe(\"task_added\", handleTaskAdded);\n unsubscribes.push(graphUnsub);\n\n // Return unsubscribe function\n return () => {\n unsubscribes.forEach((unsub) => unsub());\n };\n }\n\n /**\n * Subscribes to progress updates on all tasks (existing and future)\n * @param callback - Function called when any task reports progress\n * @param callback.taskId - The ID of the task reporting progress\n * @param callback.progress - The progress value (0-100)\n * @param callback.message - Optional progress message\n * @param callback.args - Additional arguments passed with the progress update\n * @returns a function to unsubscribe from all task progress events\n */\n public subscribeToTaskProgress(\n callback: (taskId: TaskIdType, progress: number, message?: string, ...args: any[]) => void\n ): () => void {\n const unsubscribes: (() => void)[] = [];\n\n // Subscribe to progress events on all existing tasks\n const tasks = this.getTasks();\n tasks.forEach((task) => {\n const unsub = task.subscribe(\"progress\", (progress, message, ...args) => {\n callback(task.config.id, progress, message, ...args);\n });\n unsubscribes.push(unsub);\n });\n\n const handleTaskAdded = (taskId: TaskIdType) => {\n const task = this.getTask(taskId);\n if (!task || typeof task.subscribe !== \"function\") return;\n\n const unsub = task.subscribe(\"progress\", (progress, message, ...args) => {\n callback(task.config.id, progress, message, ...args);\n });\n unsubscribes.push(unsub);\n };\n\n const graphUnsub = this.subscribe(\"task_added\", handleTaskAdded);\n unsubscribes.push(graphUnsub);\n\n // Return unsubscribe function\n return () => {\n unsubscribes.forEach((unsub) => unsub());\n };\n }\n\n /**\n * Subscribes to status changes on all dataflows (existing and future)\n * @param callback - Function called when any dataflow's status changes\n * @param callback.dataflowId - The ID of the dataflow whose status changed\n * @param callback.status - The new status of the dataflow\n * @returns a function to unsubscribe from all dataflow status events\n */\n public subscribeToDataflowStatus(\n callback: (dataflowId: DataflowIdType, status: TaskStatus) => void\n ): () => void {\n const unsubscribes: (() => void)[] = [];\n\n // Subscribe to status events on all existing dataflows\n const dataflows = this.getDataflows();\n dataflows.forEach((dataflow) => {\n const unsub = dataflow.subscribe(\"status\", (status) => {\n callback(dataflow.id, status);\n });\n unsubscribes.push(unsub);\n });\n\n const handleDataflowAdded = (dataflowId: DataflowIdType) => {\n const dataflow = this.getDataflow(dataflowId);\n if (!dataflow || typeof dataflow.subscribe !== \"function\") return;\n\n const unsub = dataflow.subscribe(\"status\", (status) => {\n callback(dataflow.id, status);\n });\n unsubscribes.push(unsub);\n };\n\n const graphUnsub = this.subscribe(\"dataflow_added\", handleDataflowAdded);\n unsubscribes.push(graphUnsub);\n\n // Return unsubscribe function\n return () => {\n unsubscribes.forEach((unsub) => unsub());\n };\n }\n\n /**\n * Registers an event listener for the specified event\n * @param name - The event name to listen for\n * @param fn - The callback function to execute when the event occurs\n */\n on<Event extends TaskGraphEvents>(name: Event, fn: TaskGraphEventListener<Event>) {\n const dagEvent = EventTaskGraphToDagMapping[name as keyof typeof EventTaskGraphToDagMapping];\n if (dagEvent) {\n // Safe cast: TaskGraph dag events (task_added, etc.) have the same signature as\n // the underlying DAG events (node-added, etc.) - both pass IDs, not full objects\n return this._dag.on(dagEvent, fn as Parameters<typeof this._dag.on>[1]);\n }\n return this.events.on(\n name as TaskGraphStatusEvents,\n fn as TaskGraphEventListener<TaskGraphStatusEvents>\n );\n }\n\n /**\n * Removes an event listener for the specified event\n * @param name - The event name to listen for\n * @param fn - The callback function to execute when the event occurs\n */\n off<Event extends TaskGraphEvents>(name: Event, fn: TaskGraphEventListener<Event>) {\n const dagEvent = EventTaskGraphToDagMapping[name as keyof typeof EventTaskGraphToDagMapping];\n if (dagEvent) {\n // Safe cast: TaskGraph dag events (task_added, etc.) have the same signature as\n // the underlying DAG events (node-added, etc.) - both pass IDs, not full objects\n return this._dag.off(dagEvent, fn as Parameters<typeof this._dag.off>[1]);\n }\n return this.events.off(\n name as TaskGraphStatusEvents,\n fn as TaskGraphEventListener<TaskGraphStatusEvents>\n );\n }\n\n /**\n * Emits an event for the specified event\n * @param name - The event name to emit\n * @param args - The arguments to pass to the event listener\n */\n emit<E extends GraphEventDagEvents>(name: E, ...args: GraphEventDagParameters<E>): void;\n emit<E extends TaskGraphStatusEvents>(name: E, ...args: TaskGraphEventStatusParameters<E>): void;\n emit(name: string, ...args: any[]): void {\n const dagEvent = EventTaskGraphToDagMapping[name as keyof typeof EventTaskGraphToDagMapping];\n if (dagEvent) {\n // @ts-ignore\n return this.emit_dag(name, ...args);\n } else {\n // @ts-ignore\n return this.emit_local(name, ...args);\n }\n }\n\n /**\n * Emits an event for the specified event\n * @param name - The event name to emit\n * @param args - The arguments to pass to the event listener\n */\n protected emit_local<Event extends TaskGraphStatusEvents>(\n name: Event,\n ...args: TaskGraphEventStatusParameters<Event>\n ) {\n return this.events?.emit(name, ...args);\n }\n\n /**\n * Emits an event for the specified event\n * @param name - The event name to emit\n * @param args - The arguments to pass to the event listener\n */\n protected emit_dag<Event extends GraphEventDagEvents>(\n name: Event,\n ...args: GraphEventDagParameters<Event>\n ) {\n const dagEvent = EventTaskGraphToDagMapping[name as keyof typeof EventTaskGraphToDagMapping];\n // Safe cast: GraphEventDagParameters matches the DAG's emit parameters (both are ID-based)\n return this._dag.emit(dagEvent, ...(args as unknown as [unknown]));\n }\n}\n\n/**\n * Super simple helper if you know the input and output handles, and there is only one each\n *\n * @param tasks\n * @param inputHandle\n * @param outputHandle\n * @returns\n */\nfunction serialGraphEdges(\n tasks: ITask<any, any, any>[],\n inputHandle: string,\n outputHandle: string\n): Dataflow[] {\n const edges: Dataflow[] = [];\n for (let i = 0; i < tasks.length - 1; i++) {\n edges.push(new Dataflow(tasks[i].config.id, inputHandle, tasks[i + 1].config.id, outputHandle));\n }\n return edges;\n}\n\n/**\n * Super simple helper if you know the input and output handles, and there is only one each\n *\n * @param tasks\n * @param inputHandle\n * @param outputHandle\n * @returns\n */\nexport function serialGraph(\n tasks: ITask<any, any, any>[],\n inputHandle: string,\n outputHandle: string\n): TaskGraph {\n const graph = new TaskGraph();\n graph.addTasks(tasks);\n graph.addDataflows(serialGraphEdges(tasks, inputHandle, outputHandle));\n return graph;\n}\n",
6
+ "/**\n * @license\n * Copyright 2025 Steven Roussey <sroussey@gmail.com>\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport { StripJSONSchema } from \"@workglow/util\";\nimport { TaskOutputRepository } from \"../storage/TaskOutputRepository\";\nimport type { Task } from \"./Task\";\n\n/**\n * Enum representing the possible states of a task\n *\n * PENDING -> PROCESSING -> COMPLETED\n * PENDING -> PROCESSING -> ABORTING -> FAILED\n * PENDING -> PROCESSING -> FAILED\n * PENDING -> DISABLED\n */\nexport type TaskStatus =\n | \"PENDING\"\n | \"DISABLED\"\n | \"PROCESSING\"\n | \"COMPLETED\"\n | \"ABORTING\"\n | \"FAILED\";\n\nexport const TaskStatus = {\n /** Task is created but not yet started */\n PENDING: \"PENDING\",\n /** Task is disabled due to conditional logic */\n DISABLED: \"DISABLED\",\n /** Task is currently running */\n PROCESSING: \"PROCESSING\",\n /** Task has completed successfully */\n COMPLETED: \"COMPLETED\",\n /** Task is in the process of being aborted */\n ABORTING: \"ABORTING\",\n /** Task has failed */\n FAILED: \"FAILED\",\n} as const satisfies Record<TaskStatus, TaskStatus>;\n\n// ========================================================================\n// Core Task Data Types\n// ========================================================================\n\nexport interface DataPorts extends StripJSONSchema<Record<string, any>> {\n [key: string]: unknown;\n}\n\n/** Type for task input data */\nexport type TaskInput = DataPorts;\n\n/** Type for task output data */\nexport type TaskOutput = DataPorts;\n\nexport type CompoundTaskOutput =\n | {\n outputs: TaskOutput[];\n }\n | {\n [key: string]: unknown | unknown[] | undefined;\n };\n\n\n/** Type for task type names */\nexport type TaskTypeName = string;\n\n/** Type for task configuration */\nexport type TaskConfig = Partial<IConfig>;\n\n// ========================================================================\n// Task Configuration Types\n// ========================================================================\n\nexport interface IConfig {\n /** Unique identifier for the task */\n id: unknown;\n\n /** Optional display name for the task */\n name?: string;\n\n\n /** Optional ID of the runner to use for this task */\n runnerId?: string;\n\n /** Optional output cache to use for this task */\n outputCache?: TaskOutputRepository | boolean;\n\n /** Optional cacheable flag to use for this task, overriding the default static property */\n cacheable?: boolean;\n\n /** Optional user data to use for this task, not used by the task framework except it will be exported as part of the task JSON*/\n extras?: DataPorts;\n}\n\n/** Type for task ID */\nexport type TaskIdType = Task<TaskInput, TaskOutput, TaskConfig>[\"config\"][\"id\"];\n",
7
+ "/**\n * @license\n * Copyright 2025 Steven Roussey <sroussey@gmail.com>\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport { DirectedAcyclicGraph, EventEmitter, ServiceRegistry, uuid4 } from \"@workglow/util\";\nimport { TaskOutputRepository } from \"../storage/TaskOutputRepository\";\nimport type { ITask } from \"../task/ITask\";\nimport { JsonTaskItem, TaskGraphJson } from \"../task/TaskJSON\";\nimport type { TaskIdType, TaskInput, TaskOutput, TaskStatus } from \"../task/TaskTypes\";\nimport { ensureTask, type PipeFunction } from \"./Conversions\";\nimport { Dataflow, type DataflowIdType } from \"./Dataflow\";\nimport type { ITaskGraph } from \"./ITaskGraph\";\nimport {\n EventTaskGraphToDagMapping,\n GraphEventDagEvents,\n GraphEventDagParameters,\n TaskGraphEventListener,\n TaskGraphEvents,\n TaskGraphEventStatusParameters,\n TaskGraphStatusEvents,\n TaskGraphStatusListeners,\n} from \"./TaskGraphEvents\";\nimport {\n CompoundMergeStrategy,\n GraphResult,\n type GraphResultArray,\n TaskGraphRunner,\n} from \"./TaskGraphRunner\";\n\n/**\n * Configuration for running a task graph\n */\nexport interface TaskGraphRunConfig {\n /** Optional output cache to use for this task graph */\n outputCache?: TaskOutputRepository | boolean;\n /** Optional signal to abort the task graph */\n parentSignal?: AbortSignal;\n /** Optional service registry to use for this task graph (creates child from global if not provided) */\n registry?: ServiceRegistry;\n}\n\nclass TaskGraphDAG extends DirectedAcyclicGraph<\n ITask<any, any, any>,\n Dataflow,\n TaskIdType,\n DataflowIdType\n> {\n constructor() {\n super(\n (task: ITask<any, any, any>) => task.config.id,\n (dataflow: Dataflow) => dataflow.id\n );\n }\n}\n\ninterface TaskGraphConstructorConfig {\n outputCache?: TaskOutputRepository;\n dag?: TaskGraphDAG;\n}\n\n/**\n * Represents a task graph, a directed acyclic graph of tasks and data flows\n */\nexport class TaskGraph implements ITaskGraph {\n /** Optional output cache to use for this task graph */\n public outputCache?: TaskOutputRepository;\n\n /**\n * Constructor for TaskGraph\n * @param config Configuration for the task graph\n */\n constructor({ outputCache, dag }: TaskGraphConstructorConfig = {}) {\n this.outputCache = outputCache;\n this._dag = dag || new TaskGraphDAG();\n }\n\n private _dag: TaskGraphDAG;\n\n private _runner: TaskGraphRunner | undefined;\n public get runner(): TaskGraphRunner {\n if (!this._runner) {\n this._runner = new TaskGraphRunner(this, this.outputCache);\n }\n return this._runner;\n }\n\n // ========================================================================\n // Public methods\n // ========================================================================\n\n /**\n * Runs the task graph\n * @param config Configuration for the graph run\n * @returns A promise that resolves when all tasks are complete\n * @throws TaskError if any tasks have failed\n */\n public run<ExecuteOutput extends TaskOutput>(\n input: TaskInput = {} as TaskInput,\n config: TaskGraphRunConfig = {}\n ): Promise<GraphResultArray<ExecuteOutput>> {\n return this.runner.runGraph<ExecuteOutput>(input, {\n outputCache: config?.outputCache || this.outputCache,\n parentSignal: config?.parentSignal || undefined,\n });\n }\n\n /**\n * Runs the task graph reactively\n * @returns A promise that resolves when all tasks are complete\n * @throws TaskError if any tasks have failed\n */\n public runReactive<Output extends TaskOutput>(\n input: TaskInput = {} as TaskInput\n ): Promise<GraphResultArray<Output>> {\n return this.runner.runGraphReactive<Output>(input);\n }\n\n /**\n * Merges the execute output to the run output\n * @param results The execute output\n * @param compoundMerge The compound merge strategy to use\n * @returns The run output\n */\n\n public mergeExecuteOutputsToRunOutput<\n ExecuteOutput extends TaskOutput,\n Merge extends CompoundMergeStrategy = CompoundMergeStrategy,\n >(\n results: GraphResultArray<ExecuteOutput>,\n compoundMerge: Merge\n ): GraphResult<ExecuteOutput, Merge> {\n return this.runner.mergeExecuteOutputsToRunOutput(results, compoundMerge);\n }\n\n /**\n * Aborts the task graph\n */\n public abort() {\n this.runner.abort();\n }\n\n /**\n * Disables the task graph\n */\n public async disable() {\n await this.runner.disable();\n }\n\n /**\n * Retrieves a task from the task graph by its id\n * @param id The id of the task to retrieve\n * @returns The task with the given id, or undefined if not found\n */\n public getTask(id: TaskIdType): ITask<any, any, any> | undefined {\n return this._dag.getNode(id);\n }\n\n /**\n * Retrieves all tasks in the task graph\n * @returns An array of tasks in the task graph\n */\n public getTasks(): ITask<any, any, any>[] {\n return this._dag.getNodes();\n }\n\n /**\n * Retrieves all tasks in the task graph topologically sorted\n * @returns An array of tasks in the task graph topologically sorted\n */\n public topologicallySortedNodes(): ITask<any, any, any>[] {\n return this._dag.topologicallySortedNodes();\n }\n\n /**\n * Adds a task to the task graph\n * @param task The task to add\n * @returns The current task graph\n */\n public addTask(fn: PipeFunction<any, any>, config?: any): unknown;\n public addTask(task: ITask<any, any, any>): unknown;\n public addTask(task: ITask<any, any, any> | PipeFunction<any, any>, config?: any): unknown {\n return this._dag.addNode(ensureTask(task, config));\n }\n\n /**\n * Adds multiple tasks to the task graph\n * @param tasks The tasks to add\n * @returns The current task graph\n */\n public addTasks(tasks: PipeFunction<any, any>[]): unknown[];\n public addTasks(tasks: ITask<any, any, any>[]): unknown[];\n public addTasks(tasks: ITask<any, any, any>[] | PipeFunction<any, any>[]): unknown[] {\n return this._dag.addNodes(tasks.map(ensureTask));\n }\n\n /**\n * Adds a data flow to the task graph\n * @param dataflow The data flow to add\n * @returns The current task graph\n */\n public addDataflow(dataflow: Dataflow) {\n return this._dag.addEdge(dataflow.sourceTaskId, dataflow.targetTaskId, dataflow);\n }\n\n /**\n * Adds multiple data flows to the task graph\n * @param dataflows The data flows to add\n * @returns The current task graph\n */\n public addDataflows(dataflows: Dataflow[]) {\n const addedEdges = dataflows.map<[s: unknown, t: unknown, e: Dataflow]>((edge) => {\n return [edge.sourceTaskId, edge.targetTaskId, edge];\n });\n return this._dag.addEdges(addedEdges);\n }\n\n /**\n * Retrieves a data flow from the task graph by its id\n * @param id The id of the data flow to retrieve\n * @returns The data flow with the given id, or undefined if not found\n */\n public getDataflow(id: DataflowIdType): Dataflow | undefined {\n // @ts-ignore\n for (const i in this._dag.adjacency) {\n // @ts-ignore\n for (const j in this._dag.adjacency[i]) {\n // @ts-ignore\n const maybeEdges = this._dag.adjacency[i][j];\n if (maybeEdges !== null) {\n for (const edge of maybeEdges) {\n // @ts-ignore\n if (this._dag.edgeIdentity(edge, \"\", \"\") == id) {\n return edge;\n }\n }\n }\n }\n }\n }\n\n /**\n * Retrieves all data flows in the task graph\n * @returns An array of data flows in the task graph\n */\n public getDataflows(): Dataflow[] {\n return this._dag.getEdges().map((edge) => edge[2]);\n }\n\n /**\n * Removes a data flow from the task graph\n * @param dataflow The data flow to remove\n * @returns The current task graph\n */\n public removeDataflow(dataflow: Dataflow) {\n return this._dag.removeEdge(dataflow.sourceTaskId, dataflow.targetTaskId, dataflow.id);\n }\n\n /**\n * Retrieves the data flows that are sources of a given task\n * @param taskId The id of the task to retrieve sources for\n * @returns An array of data flows that are sources of the given task\n */\n public getSourceDataflows(taskId: unknown): Dataflow[] {\n return this._dag.inEdges(taskId).map(([, , dataflow]) => dataflow);\n }\n\n /**\n * Retrieves the data flows that are targets of a given task\n * @param taskId The id of the task to retrieve targets for\n * @returns An array of data flows that are targets of the given task\n */\n public getTargetDataflows(taskId: unknown): Dataflow[] {\n return this._dag.outEdges(taskId).map(([, , dataflow]) => dataflow);\n }\n\n /**\n * Retrieves the tasks that are sources of a given task\n * @param taskId The id of the task to retrieve sources for\n * @returns An array of tasks that are sources of the given task\n */\n public getSourceTasks(taskId: unknown): ITask<any, any, any>[] {\n return this.getSourceDataflows(taskId).map((dataflow) => this.getTask(dataflow.sourceTaskId)!);\n }\n\n /**\n * Retrieves the tasks that are targets of a given task\n * @param taskId The id of the task to retrieve targets for\n * @returns An array of tasks that are targets of the given task\n */\n public getTargetTasks(taskId: unknown): ITask<any, any, any>[] {\n return this.getTargetDataflows(taskId).map((dataflow) => this.getTask(dataflow.targetTaskId)!);\n }\n\n /**\n * Removes a task from the task graph\n * @param taskId The id of the task to remove\n * @returns The current task graph\n */\n public removeTask(taskId: unknown) {\n return this._dag.removeNode(taskId);\n }\n\n public resetGraph() {\n this.runner.resetGraph(this, uuid4());\n }\n\n /**\n * Converts the task graph to a JSON format suitable for dependency tracking\n * @returns An array of JsonTaskItem objects, each representing a task and its dependencies\n */\n public toJSON(): TaskGraphJson {\n const tasks = this.getTasks().map((node) => node.toJSON());\n const dataflows = this.getDataflows().map((df) => df.toJSON());\n return {\n tasks,\n dataflows,\n };\n }\n\n /**\n * Converts the task graph to a JSON format suitable for dependency tracking\n * @returns An array of JsonTaskItem objects, each representing a task and its dependencies\n */\n public toDependencyJSON(): JsonTaskItem[] {\n const tasks = this.getTasks().flatMap((node) => node.toDependencyJSON());\n this.getDataflows().forEach((df) => {\n const target = tasks.find((node) => node.id === df.targetTaskId)!;\n if (!target.dependencies) {\n target.dependencies = {};\n }\n const targetDeps = target.dependencies[df.targetTaskPortId];\n if (!targetDeps) {\n target.dependencies[df.targetTaskPortId] = {\n id: df.sourceTaskId,\n output: df.sourceTaskPortId,\n };\n } else {\n if (Array.isArray(targetDeps)) {\n targetDeps.push({\n id: df.sourceTaskId,\n output: df.sourceTaskPortId,\n });\n } else {\n target.dependencies[df.targetTaskPortId] = [\n targetDeps,\n { id: df.sourceTaskId, output: df.sourceTaskPortId },\n ];\n }\n }\n });\n return tasks;\n }\n\n // ========================================================================\n // Event handling\n // ========================================================================\n\n /**\n * Event emitter for task lifecycle events\n */\n public get events(): EventEmitter<TaskGraphStatusListeners> {\n if (!this._events) {\n this._events = new EventEmitter<TaskGraphStatusListeners>();\n }\n return this._events;\n }\n protected _events: EventEmitter<TaskGraphStatusListeners> | undefined;\n\n /**\n * Subscribes to an event\n * @param name - The event name to listen for\n * @param fn - The callback function to execute when the event occurs\n * @returns a function to unsubscribe from the event\n */\n public subscribe<Event extends TaskGraphEvents>(\n name: Event,\n fn: TaskGraphEventListener<Event>\n ): () => void {\n this.on(name, fn);\n return () => this.off(name, fn);\n }\n\n /**\n * Subscribes to status changes on all tasks (existing and future)\n * @param callback - Function called when any task's status changes\n * @param callback.taskId - The ID of the task whose status changed\n * @param callback.status - The new status of the task\n * @returns a function to unsubscribe from all task status events\n */\n public subscribeToTaskStatus(\n callback: (taskId: TaskIdType, status: TaskStatus) => void\n ): () => void {\n const unsubscribes: (() => void)[] = [];\n\n // Subscribe to status events on all existing tasks\n const tasks = this.getTasks();\n tasks.forEach((task) => {\n const unsub = task.subscribe(\"status\", (status) => {\n callback(task.config.id, status);\n });\n unsubscribes.push(unsub);\n });\n\n const handleTaskAdded = (taskId: TaskIdType) => {\n const task = this.getTask(taskId);\n if (!task || typeof task.subscribe !== \"function\") return;\n\n const unsub = task.subscribe(\"status\", (status) => {\n callback(task.config.id, status);\n });\n unsubscribes.push(unsub);\n };\n\n const graphUnsub = this.subscribe(\"task_added\", handleTaskAdded);\n unsubscribes.push(graphUnsub);\n\n // Return unsubscribe function\n return () => {\n unsubscribes.forEach((unsub) => unsub());\n };\n }\n\n /**\n * Subscribes to progress updates on all tasks (existing and future)\n * @param callback - Function called when any task reports progress\n * @param callback.taskId - The ID of the task reporting progress\n * @param callback.progress - The progress value (0-100)\n * @param callback.message - Optional progress message\n * @param callback.args - Additional arguments passed with the progress update\n * @returns a function to unsubscribe from all task progress events\n */\n public subscribeToTaskProgress(\n callback: (taskId: TaskIdType, progress: number, message?: string, ...args: any[]) => void\n ): () => void {\n const unsubscribes: (() => void)[] = [];\n\n // Subscribe to progress events on all existing tasks\n const tasks = this.getTasks();\n tasks.forEach((task) => {\n const unsub = task.subscribe(\"progress\", (progress, message, ...args) => {\n callback(task.config.id, progress, message, ...args);\n });\n unsubscribes.push(unsub);\n });\n\n const handleTaskAdded = (taskId: TaskIdType) => {\n const task = this.getTask(taskId);\n if (!task || typeof task.subscribe !== \"function\") return;\n\n const unsub = task.subscribe(\"progress\", (progress, message, ...args) => {\n callback(task.config.id, progress, message, ...args);\n });\n unsubscribes.push(unsub);\n };\n\n const graphUnsub = this.subscribe(\"task_added\", handleTaskAdded);\n unsubscribes.push(graphUnsub);\n\n // Return unsubscribe function\n return () => {\n unsubscribes.forEach((unsub) => unsub());\n };\n }\n\n /**\n * Subscribes to status changes on all dataflows (existing and future)\n * @param callback - Function called when any dataflow's status changes\n * @param callback.dataflowId - The ID of the dataflow whose status changed\n * @param callback.status - The new status of the dataflow\n * @returns a function to unsubscribe from all dataflow status events\n */\n public subscribeToDataflowStatus(\n callback: (dataflowId: DataflowIdType, status: TaskStatus) => void\n ): () => void {\n const unsubscribes: (() => void)[] = [];\n\n // Subscribe to status events on all existing dataflows\n const dataflows = this.getDataflows();\n dataflows.forEach((dataflow) => {\n const unsub = dataflow.subscribe(\"status\", (status) => {\n callback(dataflow.id, status);\n });\n unsubscribes.push(unsub);\n });\n\n const handleDataflowAdded = (dataflowId: DataflowIdType) => {\n const dataflow = this.getDataflow(dataflowId);\n if (!dataflow || typeof dataflow.subscribe !== \"function\") return;\n\n const unsub = dataflow.subscribe(\"status\", (status) => {\n callback(dataflow.id, status);\n });\n unsubscribes.push(unsub);\n };\n\n const graphUnsub = this.subscribe(\"dataflow_added\", handleDataflowAdded);\n unsubscribes.push(graphUnsub);\n\n // Return unsubscribe function\n return () => {\n unsubscribes.forEach((unsub) => unsub());\n };\n }\n\n /**\n * Registers an event listener for the specified event\n * @param name - The event name to listen for\n * @param fn - The callback function to execute when the event occurs\n */\n on<Event extends TaskGraphEvents>(name: Event, fn: TaskGraphEventListener<Event>) {\n const dagEvent = EventTaskGraphToDagMapping[name as keyof typeof EventTaskGraphToDagMapping];\n if (dagEvent) {\n // Safe cast: TaskGraph dag events (task_added, etc.) have the same signature as\n // the underlying DAG events (node-added, etc.) - both pass IDs, not full objects\n return this._dag.on(dagEvent, fn as Parameters<typeof this._dag.on>[1]);\n }\n return this.events.on(\n name as TaskGraphStatusEvents,\n fn as TaskGraphEventListener<TaskGraphStatusEvents>\n );\n }\n\n /**\n * Removes an event listener for the specified event\n * @param name - The event name to listen for\n * @param fn - The callback function to execute when the event occurs\n */\n off<Event extends TaskGraphEvents>(name: Event, fn: TaskGraphEventListener<Event>) {\n const dagEvent = EventTaskGraphToDagMapping[name as keyof typeof EventTaskGraphToDagMapping];\n if (dagEvent) {\n // Safe cast: TaskGraph dag events (task_added, etc.) have the same signature as\n // the underlying DAG events (node-added, etc.) - both pass IDs, not full objects\n return this._dag.off(dagEvent, fn as Parameters<typeof this._dag.off>[1]);\n }\n return this.events.off(\n name as TaskGraphStatusEvents,\n fn as TaskGraphEventListener<TaskGraphStatusEvents>\n );\n }\n\n /**\n * Emits an event for the specified event\n * @param name - The event name to emit\n * @param args - The arguments to pass to the event listener\n */\n emit<E extends GraphEventDagEvents>(name: E, ...args: GraphEventDagParameters<E>): void;\n emit<E extends TaskGraphStatusEvents>(name: E, ...args: TaskGraphEventStatusParameters<E>): void;\n emit(name: string, ...args: any[]): void {\n const dagEvent = EventTaskGraphToDagMapping[name as keyof typeof EventTaskGraphToDagMapping];\n if (dagEvent) {\n // @ts-ignore\n return this.emit_dag(name, ...args);\n } else {\n // @ts-ignore\n return this.emit_local(name, ...args);\n }\n }\n\n /**\n * Emits an event for the specified event\n * @param name - The event name to emit\n * @param args - The arguments to pass to the event listener\n */\n protected emit_local<Event extends TaskGraphStatusEvents>(\n name: Event,\n ...args: TaskGraphEventStatusParameters<Event>\n ) {\n return this.events?.emit(name, ...args);\n }\n\n /**\n * Emits an event for the specified event\n * @param name - The event name to emit\n * @param args - The arguments to pass to the event listener\n */\n protected emit_dag<Event extends GraphEventDagEvents>(\n name: Event,\n ...args: GraphEventDagParameters<Event>\n ) {\n const dagEvent = EventTaskGraphToDagMapping[name as keyof typeof EventTaskGraphToDagMapping];\n // Safe cast: GraphEventDagParameters matches the DAG's emit parameters (both are ID-based)\n return this._dag.emit(dagEvent, ...(args as unknown as [unknown]));\n }\n}\n\n/**\n * Super simple helper if you know the input and output handles, and there is only one each\n *\n * @param tasks\n * @param inputHandle\n * @param outputHandle\n * @returns\n */\nfunction serialGraphEdges(\n tasks: ITask<any, any, any>[],\n inputHandle: string,\n outputHandle: string\n): Dataflow[] {\n const edges: Dataflow[] = [];\n for (let i = 0; i < tasks.length - 1; i++) {\n edges.push(new Dataflow(tasks[i].config.id, inputHandle, tasks[i + 1].config.id, outputHandle));\n }\n return edges;\n}\n\n/**\n * Super simple helper if you know the input and output handles, and there is only one each\n *\n * @param tasks\n * @param inputHandle\n * @param outputHandle\n * @returns\n */\nexport function serialGraph(\n tasks: ITask<any, any, any>[],\n inputHandle: string,\n outputHandle: string\n): TaskGraph {\n const graph = new TaskGraph();\n graph.addTasks(tasks);\n graph.addDataflows(serialGraphEdges(tasks, inputHandle, outputHandle));\n return graph;\n}\n",
9
8
  "/**\n * @license\n * Copyright 2025 Steven Roussey <sroussey@gmail.com>\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport type { DataPortSchema } from \"@workglow/util\";\nimport { compileSchema, SchemaNode } from \"@workglow/util\";\nimport { DATAFLOW_ALL_PORTS } from \"../task-graph/Dataflow\";\nimport { TaskGraph } from \"../task-graph/TaskGraph\";\nimport { CompoundMergeStrategy, PROPERTY_ARRAY } from \"../task-graph/TaskGraphRunner\";\nimport { GraphAsTaskRunner } from \"./GraphAsTaskRunner\";\nimport { Task } from \"./Task\";\nimport type { JsonTaskItem, TaskGraphItemJson } from \"./TaskJSON\";\nimport {\n type TaskConfig,\n type TaskIdType,\n type TaskInput,\n type TaskOutput,\n type TaskTypeName,\n} from \"./TaskTypes\";\n\nexport interface GraphAsTaskConfig extends TaskConfig {\n subGraph?: TaskGraph;\n compoundMerge?: CompoundMergeStrategy;\n}\n\n/**\n * A task that contains a subgraph of tasks\n */\nexport class GraphAsTask<\n Input extends TaskInput = TaskInput,\n Output extends TaskOutput = TaskOutput,\n Config extends GraphAsTaskConfig = GraphAsTaskConfig,\n> extends Task<Input, Output, Config> {\n // ========================================================================\n // Static properties - should be overridden by subclasses\n // ========================================================================\n\n public static type: TaskTypeName = \"GraphAsTask\";\n public static title: string = \"Graph as Task\";\n public static description: string = \"A task that contains a subgraph of tasks\";\n public static category: string = \"Hidden\";\n public static compoundMerge: CompoundMergeStrategy = PROPERTY_ARRAY;\n\n /** This task has dynamic schemas that change based on the subgraph structure */\n public static hasDynamicSchemas: boolean = true;\n\n // ========================================================================\n // Constructor\n // ========================================================================\n\n constructor(input: Partial<Input> = {}, config: Partial<Config> = {}) {\n const { subGraph, ...rest } = config;\n super(input, rest as Config);\n if (subGraph) {\n this.subGraph = subGraph;\n }\n this.regenerateGraph();\n }\n\n // ========================================================================\n // TaskRunner delegation - Executes and manages the task\n // ========================================================================\n\n declare _runner: GraphAsTaskRunner<Input, Output, Config>;\n\n /**\n * Task runner for handling the task execution\n */\n override get runner(): GraphAsTaskRunner<Input, Output, Config> {\n if (!this._runner) {\n this._runner = new GraphAsTaskRunner<Input, Output, Config>(this);\n }\n return this._runner;\n }\n\n // ========================================================================\n // Static to Instance conversion methods\n // ========================================================================\n\n public get compoundMerge(): CompoundMergeStrategy {\n return this.config?.compoundMerge || (this.constructor as typeof GraphAsTask).compoundMerge;\n }\n\n public get cacheable(): boolean {\n return (\n // if cacheable is set in config, always use that\n this.config?.cacheable ??\n ((this.constructor as typeof GraphAsTask).cacheable && !this.hasChildren())\n );\n }\n\n // ========================================================================\n // Input/Output handling\n // ========================================================================\n\n /**\n * Override inputSchema to compute it dynamically from the subgraph at runtime\n * The input schema is the union of all unconnected inputs from starting nodes\n * (nodes with zero incoming connections)\n */\n public inputSchema(): DataPortSchema {\n // If there's no subgraph or it has no children, fall back to the static schema\n if (!this.hasChildren()) {\n return (this.constructor as typeof Task).inputSchema();\n }\n\n const properties: Record<string, any> = {};\n const required: string[] = [];\n\n // Get all tasks in the graph\n const tasks = this.subGraph.getTasks();\n\n // Identify starting nodes: tasks with no incoming dataflows\n const startingNodes = tasks.filter(\n (task) => this.subGraph.getSourceDataflows(task.config.id).length === 0\n );\n\n // For starting nodes only, collect their unconnected inputs\n for (const task of startingNodes) {\n const taskInputSchema = task.inputSchema();\n if (typeof taskInputSchema === \"boolean\") {\n if (taskInputSchema === false) {\n continue;\n }\n if (taskInputSchema === true) {\n properties[DATAFLOW_ALL_PORTS] = {};\n continue;\n }\n }\n const taskProperties = taskInputSchema.properties || {};\n\n // Add all inputs from starting nodes to the graph's input schema\n for (const [inputName, inputProp] of Object.entries(taskProperties)) {\n // If the same input name exists in multiple nodes, we use the first one\n // In a more sophisticated implementation, we might want to merge or validate compatibility\n if (!properties[inputName]) {\n properties[inputName] = inputProp;\n\n // Check if this input is required\n if (taskInputSchema.required && taskInputSchema.required.includes(inputName)) {\n required.push(inputName);\n }\n }\n }\n }\n\n return {\n type: \"object\",\n properties,\n ...(required.length > 0 ? { required } : {}),\n additionalProperties: false,\n } as const satisfies DataPortSchema;\n }\n\n protected _inputSchemaNode: SchemaNode | undefined;\n /**\n * Gets the compiled input schema\n */\n protected override getInputSchemaNode(type: TaskTypeName): SchemaNode {\n // every graph as task is different, so we need to compile the schema for each one\n if (!this._inputSchemaNode) {\n const dataPortSchema = this.inputSchema();\n const schemaNode = Task.generateInputSchemaNode(dataPortSchema);\n try {\n this._inputSchemaNode = schemaNode;\n } catch (error) {\n // If compilation fails, fall back to accepting any object structure\n // This is a safety net for schemas that json-schema-library can't compile\n console.warn(\n `Failed to compile input schema for ${type}, falling back to permissive validation:`,\n error\n );\n this._inputSchemaNode = compileSchema({});\n }\n }\n return this._inputSchemaNode!;\n }\n\n /**\n * Calculates the depth (longest path from any starting node) for each task in the graph\n * @returns A map of task IDs to their depths\n */\n private calculateNodeDepths(): Map<TaskIdType, number> {\n const depths = new Map<TaskIdType, number>();\n const tasks = this.subGraph.getTasks();\n\n // Initialize all depths to 0\n for (const task of tasks) {\n depths.set(task.config.id, 0);\n }\n\n // Use topological sort to calculate depths in order\n const sortedTasks = this.subGraph.topologicallySortedNodes();\n\n for (const task of sortedTasks) {\n const currentDepth = depths.get(task.config.id) || 0;\n const targetTasks = this.subGraph.getTargetTasks(task.config.id);\n\n // Update depths of all target tasks\n for (const targetTask of targetTasks) {\n const targetDepth = depths.get(targetTask.config.id) || 0;\n depths.set(targetTask.config.id, Math.max(targetDepth, currentDepth + 1));\n }\n }\n\n return depths;\n }\n\n /**\n * Override outputSchema to compute it dynamically from the subgraph at runtime\n * The output schema depends on the compoundMerge strategy and the nodes at the last level\n */\n public override outputSchema(): DataPortSchema {\n // If there's no subgraph or it has no children, fall back to the static schema\n if (!this.hasChildren()) {\n return (this.constructor as typeof Task).outputSchema();\n }\n\n const properties: Record<string, any> = {};\n const required: string[] = [];\n\n // Find all ending nodes (nodes with no outgoing dataflows)\n const tasks = this.subGraph.getTasks();\n const endingNodes = tasks.filter(\n (task) => this.subGraph.getTargetDataflows(task.config.id).length === 0\n );\n\n // Calculate depths for all nodes\n const depths = this.calculateNodeDepths();\n\n // Find the maximum depth among ending nodes\n const maxDepth = Math.max(...endingNodes.map((task) => depths.get(task.config.id) || 0));\n\n // Filter ending nodes to only those at the maximum depth (last level)\n const lastLevelNodes = endingNodes.filter((task) => depths.get(task.config.id) === maxDepth);\n\n // ONLY handle PROPERTY_ARRAY strategy\n // Count how many ending nodes produce each property\n const propertyCount: Record<string, number> = {};\n const propertySchema: Record<string, any> = {};\n\n for (const task of lastLevelNodes) {\n const taskOutputSchema = task.outputSchema();\n if (typeof taskOutputSchema === \"boolean\") {\n if (taskOutputSchema === false) {\n continue;\n }\n if (taskOutputSchema === true) {\n properties[DATAFLOW_ALL_PORTS] = {};\n continue;\n }\n }\n const taskProperties = taskOutputSchema.properties || {};\n\n for (const [outputName, outputProp] of Object.entries(taskProperties)) {\n propertyCount[outputName] = (propertyCount[outputName] || 0) + 1;\n // Store the first schema we encounter for each property\n if (!propertySchema[outputName]) {\n propertySchema[outputName] = outputProp;\n }\n }\n }\n\n // Build the final schema: properties produced by multiple nodes become arrays\n for (const [outputName, count] of Object.entries(propertyCount)) {\n const outputProp = propertySchema[outputName];\n\n if (lastLevelNodes.length === 1) {\n // Single ending node: use property as-is\n properties[outputName] = outputProp;\n } else {\n // Multiple ending nodes: all properties become arrays due to collectPropertyValues\n properties[outputName] = {\n type: \"array\",\n items: outputProp as any,\n };\n }\n }\n\n return {\n type: \"object\",\n properties,\n ...(required.length > 0 ? { required } : {}),\n additionalProperties: false,\n } as DataPortSchema;\n }\n\n /**\n * Resets input data to defaults\n */\n public resetInputData(): void {\n super.resetInputData();\n if (this.hasChildren()) {\n this.subGraph!.getTasks().forEach((node) => {\n node.resetInputData();\n });\n this.subGraph!.getDataflows().forEach((dataflow) => {\n dataflow.reset();\n });\n }\n }\n\n // ========================================================================\n // Compound task methods\n // ========================================================================\n\n /**\n * Regenerates the subtask graph and emits a \"regenerate\" event\n *\n * Subclasses should override this method to implement the actual graph\n * regeneration logic, but all they need to do is call this method to\n * emit the \"regenerate\" event.\n */\n public regenerateGraph(): void {\n this._inputSchemaNode = undefined;\n this.events.emit(\"regenerate\");\n }\n\n // ========================================================================\n // Serialization methods\n // ========================================================================\n\n /**\n * Serializes the task and its subtasks into a format that can be stored\n * @returns The serialized task and subtasks\n */\n public toJSON(): TaskGraphItemJson {\n let json = super.toJSON();\n const hasChildren = this.hasChildren();\n if (hasChildren) {\n json = {\n ...json,\n merge: this.compoundMerge,\n subgraph: this.subGraph!.toJSON(),\n };\n }\n return json;\n }\n\n /**\n * Converts the task to a JSON format suitable for dependency tracking\n * @returns The task and subtasks in JSON thats easier for humans to read\n */\n public toDependencyJSON(): JsonTaskItem {\n const json = this.toJSON();\n if (this.hasChildren()) {\n if (\"subgraph\" in json) {\n delete json.subgraph;\n }\n return { ...json, subtasks: this.subGraph!.toDependencyJSON() };\n }\n return json;\n }\n}\n",
10
- "/**\n * @license\n * Copyright 2025 Steven Roussey <sroussey@gmail.com>\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {\n collectPropertyValues,\n ConvertAllToOptionalArray,\n globalServiceRegistry,\n ServiceRegistry,\n uuid4,\n} from \"@workglow/util\";\nimport { TASK_OUTPUT_REPOSITORY, TaskOutputRepository } from \"../storage/TaskOutputRepository\";\nimport { ConditionalTask } from \"../task/ConditionalTask\";\nimport { ITask } from \"../task/ITask\";\nimport { TaskAbortedError, TaskConfigurationError, TaskError } from \"../task/TaskError\";\nimport { TaskInput, TaskOutput, TaskStatus } from \"../task/TaskTypes\";\nimport { DATAFLOW_ALL_PORTS } from \"./Dataflow\";\nimport { TaskGraph, TaskGraphRunConfig } from \"./TaskGraph\";\nimport { DependencyBasedScheduler, TopologicalScheduler } from \"./TaskGraphScheduler\";\n\nexport type GraphSingleTaskResult<T> = {\n id: unknown;\n type: String;\n data: T;\n};\nexport type GraphResultArray<T> = Array<GraphSingleTaskResult<T>>;\nexport type PropertyArrayGraphResult<T> = ConvertAllToOptionalArray<T>;\nexport type AnyGraphResult<T> = PropertyArrayGraphResult<T> | GraphResultArray<T>;\n\nexport const PROPERTY_ARRAY = \"PROPERTY_ARRAY\" as const;\nexport const GRAPH_RESULT_ARRAY = \"GRAPH_RESULT_ARRAY\" as const;\n\nexport type GraphResultMap<T> = {\n // array of results with id for tasks that created them -- output is an array of {id, type, data}[]\n [GRAPH_RESULT_ARRAY]: GraphResultArray<T>;\n // property-array -- output is consolidation of each output property, with duplicate properties turned into an array\n [PROPERTY_ARRAY]: PropertyArrayGraphResult<T>;\n};\n\n/**\n * Enum representing the possible compound merge strategies\n */\nexport type CompoundMergeStrategy = typeof PROPERTY_ARRAY | typeof GRAPH_RESULT_ARRAY;\n\nexport type GraphResult<\n Output,\n Merge extends CompoundMergeStrategy,\n> = GraphResultMap<Output>[Merge];\n\n/**\n * Class for running a task graph\n * Manages the execution of tasks in a task graph, including caching\n */\nexport class TaskGraphRunner {\n /**\n * Whether the task graph is currently running\n */\n protected running = false;\n protected reactiveRunning = false;\n\n /**\n * The task graph to run\n */\n public readonly graph: TaskGraph;\n\n /**\n * Output cache repository\n */\n protected outputCache?: TaskOutputRepository;\n /**\n * Service registry for this graph run\n */\n protected registry: ServiceRegistry = globalServiceRegistry;\n /**\n * AbortController for cancelling graph execution\n */\n protected abortController: AbortController | undefined;\n\n /**\n * Maps to track task execution state\n */\n protected inProgressTasks: Map<unknown, Promise<TaskOutput>> = new Map();\n protected inProgressFunctions: Map<unknown, Promise<any>> = new Map();\n protected failedTaskErrors: Map<unknown, TaskError> = new Map();\n\n /**\n * Constructor for TaskGraphRunner\n * @param graph The task graph to run\n * @param outputCache The task output repository to use for caching task outputs\n * @param processScheduler The scheduler to use for task execution\n * @param reactiveScheduler The scheduler to use for reactive task execution\n */\n constructor(\n graph: TaskGraph,\n outputCache?: TaskOutputRepository,\n protected processScheduler = new DependencyBasedScheduler(graph),\n protected reactiveScheduler = new TopologicalScheduler(graph)\n ) {\n this.graph = graph;\n graph.outputCache = outputCache;\n this.handleProgress = this.handleProgress.bind(this);\n }\n\n // ========================================================================\n // Public methods\n // ========================================================================\n\n public async runGraph<ExecuteOutput extends TaskOutput>(\n input: TaskInput = {} as TaskInput,\n config?: TaskGraphRunConfig\n ): Promise<GraphResultArray<ExecuteOutput>> {\n await this.handleStart(config);\n\n const results: GraphResultArray<ExecuteOutput> = [];\n let error: TaskError | undefined;\n\n try {\n // TODO: A different graph runner may chunk tasks that are in parallel\n // rather them all currently available\n for await (const task of this.processScheduler.tasks()) {\n if (this.abortController?.signal.aborted) {\n break;\n }\n\n if (this.failedTaskErrors.size > 0) {\n break;\n }\n\n const isRootTask = this.graph.getSourceDataflows(task.config.id).length === 0;\n\n const runAsync = async () => {\n try {\n // Only filter input for non-root tasks; root tasks get the full input\n const taskInput = isRootTask ? input : this.filterInputForTask(task, input);\n\n const taskPromise = this.runTask(task, taskInput);\n this.inProgressTasks!.set(task.config.id, taskPromise);\n const taskResult = await taskPromise;\n\n if (this.graph.getTargetDataflows(task.config.id).length === 0) {\n // we save the results of all the leaves\n results.push(taskResult as GraphSingleTaskResult<ExecuteOutput>);\n }\n } catch (error) {\n this.failedTaskErrors.set(task.config.id, error as TaskError);\n } finally {\n // IMPORTANT: Push status to edges BEFORE notifying scheduler\n // This ensures dataflow statuses (including DISABLED) are set\n // before the scheduler checks which tasks are ready\n this.pushStatusFromNodeToEdges(this.graph, task);\n this.pushErrorFromNodeToEdges(this.graph, task);\n this.processScheduler.onTaskCompleted(task.config.id);\n }\n };\n\n // Start task execution without awaiting\n // so we can have many tasks running in parallel\n // but keep track of them to make sure they get awaited\n // otherwise, things will finish after this promise is resolved\n this.inProgressFunctions.set(Symbol(task.config.id as string), runAsync());\n }\n } catch (err) {\n error = err as Error;\n }\n // Wait for all tasks to complete since we did not await runAsync()/this.runTaskWithProvenance()\n await Promise.allSettled(Array.from(this.inProgressTasks.values()));\n // Clean up stragglers to avoid unhandled promise rejections\n await Promise.allSettled(Array.from(this.inProgressFunctions.values()));\n\n if (this.failedTaskErrors.size > 0) {\n const latestError = this.failedTaskErrors.values().next().value!;\n this.handleError(latestError);\n throw latestError;\n }\n if (this.abortController?.signal.aborted) {\n await this.handleAbort();\n throw new TaskAbortedError();\n }\n\n await this.handleComplete();\n\n return results;\n }\n\n /**\n * Runs the task graph in a reactive manner\n * @returns A promise that resolves when all tasks are complete\n * @throws TaskConfigurationError if the graph is already running reactively\n */\n public async runGraphReactive<Output extends TaskOutput>(): Promise<GraphResultArray<Output>> {\n await this.handleStartReactive();\n\n const results: GraphResultArray<Output> = [];\n try {\n for await (const task of this.reactiveScheduler.tasks()) {\n if (task.status === TaskStatus.PENDING) {\n task.resetInputData();\n this.copyInputFromEdgesToNode(task);\n // TODO: cacheable here??\n // if (task.cacheable) {\n // const results = await this.outputCache?.getOutput(\n // (task.constructor as any).type,\n // task.runInputData\n // );\n // if (results) {\n // task.runOutputData = results;\n // }\n // }\n }\n const taskResult = await task.runReactive();\n\n await this.pushOutputFromNodeToEdges(task, taskResult);\n if (this.graph.getTargetDataflows(task.config.id).length === 0) {\n results.push({\n id: task.config.id,\n type: (task.constructor as any).runtype || (task.constructor as any).type,\n data: taskResult as Output,\n });\n }\n }\n await this.handleCompleteReactive();\n return results;\n } catch (error) {\n await this.handleErrorReactive();\n throw error;\n }\n }\n\n /**\n * Aborts the task graph execution\n */\n public abort(): void {\n this.abortController?.abort();\n }\n\n /**\n * Disables the task graph execution\n */\n public async disable(): Promise<void> {\n await this.handleDisable();\n }\n\n /**\n * Filters graph-level input to only include properties that are not connected via dataflows for a given task\n * @param task The task to filter input for\n * @param input The graph-level input\n * @returns Filtered input containing only unconnected properties\n */\n protected filterInputForTask(task: ITask, input: TaskInput): TaskInput {\n // Get all inputs that are connected to this task via dataflows\n const sourceDataflows = this.graph.getSourceDataflows(task.config.id);\n const connectedInputs = new Set(sourceDataflows.map((df) => df.targetTaskPortId));\n\n // If DATAFLOW_ALL_PORTS (\"*\") is in the set, all inputs are connected\n const allPortsConnected = connectedInputs.has(DATAFLOW_ALL_PORTS);\n\n // Filter out connected inputs from the graph input\n const filteredInput: TaskInput = {};\n for (const [key, value] of Object.entries(input)) {\n // Skip this input if it's explicitly connected OR if all ports are connected\n if (!connectedInputs.has(key) && !allPortsConnected) {\n filteredInput[key] = value;\n }\n }\n\n return filteredInput;\n }\n\n /**\n * Adds input data to a task.\n * Delegates to {@link Task.addInput} for the actual merging logic.\n *\n * @param task The task to add input data to\n * @param overrides The input data to override (or add to if an array)\n */\n public addInputData(task: ITask, overrides: Partial<TaskInput> | undefined): void {\n if (!overrides) return;\n\n const changed = task.addInput(overrides);\n\n // TODO(str): This is a hack.\n if (changed && \"regenerateGraph\" in task && typeof task.regenerateGraph === \"function\") {\n task.regenerateGraph();\n }\n }\n\n // ========================================================================\n // Protected Handlers\n // ========================================================================\n public mergeExecuteOutputsToRunOutput<\n ExecuteOutput extends TaskOutput,\n Merge extends CompoundMergeStrategy = CompoundMergeStrategy,\n >(\n results: GraphResultArray<ExecuteOutput>,\n compoundMerge: Merge\n ): GraphResult<ExecuteOutput, Merge> {\n if (compoundMerge === GRAPH_RESULT_ARRAY) {\n return results as GraphResult<ExecuteOutput, Merge>;\n }\n\n if (compoundMerge === PROPERTY_ARRAY) {\n let fixedOutput = {} as PropertyArrayGraphResult<ExecuteOutput>;\n const outputs = results.map((result: any) => result.data);\n if (outputs.length === 1) {\n fixedOutput = outputs[0];\n } else if (outputs.length > 1) {\n const collected = collectPropertyValues<ExecuteOutput>(outputs as ExecuteOutput[]);\n if (Object.keys(collected).length > 0) {\n fixedOutput = collected;\n }\n }\n return fixedOutput as GraphResult<ExecuteOutput, Merge>;\n }\n throw new TaskConfigurationError(`Unknown compound merge strategy: ${compoundMerge}`);\n }\n\n /**\n * Copies input data from edges to a task\n * @param task The task to copy input data to\n */\n protected copyInputFromEdgesToNode(task: ITask) {\n const dataflows = this.graph.getSourceDataflows(task.config.id);\n for (const dataflow of dataflows) {\n this.addInputData(task, dataflow.getPortData());\n }\n }\n\n /**\n * Pushes the output of a task to its target tasks\n * @param node The task that produced the output\n * @param results The output of the task\n */\n protected async pushOutputFromNodeToEdges(node: ITask, results: TaskOutput) {\n const dataflows = this.graph.getTargetDataflows(node.config.id);\n for (const dataflow of dataflows) {\n const compatibility = dataflow.semanticallyCompatible(this.graph, dataflow);\n // console.log(\"pushOutputFromNodeToEdges\", dataflow.id, compatibility, Object.keys(results));\n if (compatibility === \"static\") {\n dataflow.setPortData(results);\n } else if (compatibility === \"runtime\") {\n const task = this.graph.getTask(dataflow.targetTaskId)!;\n const narrowed = await task.narrowInput({ ...results }, this.registry);\n dataflow.setPortData(narrowed);\n } else {\n // don't push incompatible data\n }\n }\n }\n\n /**\n * Pushes the status of a task to its target edges\n * @param node The task that produced the status\n *\n * For ConditionalTask, this method handles selective dataflow status:\n * - Active branch dataflows get COMPLETED status\n * - Inactive branch dataflows get DISABLED status\n */\n protected pushStatusFromNodeToEdges(graph: TaskGraph, node: ITask, status?: TaskStatus): void {\n if (!node?.config?.id) return;\n\n const dataflows = graph.getTargetDataflows(node.config.id);\n const effectiveStatus = status ?? node.status;\n\n // Check if this is a ConditionalTask with selective branching\n if (node instanceof ConditionalTask && effectiveStatus === TaskStatus.COMPLETED) {\n // Build a map of output port -> branch ID for lookup\n const branches = node.config.branches ?? [];\n const portToBranch = new Map<string, string>();\n for (const branch of branches) {\n portToBranch.set(branch.outputPort, branch.id);\n }\n\n const activeBranches = node.getActiveBranches();\n\n for (const dataflow of dataflows) {\n const branchId = portToBranch.get(dataflow.sourceTaskPortId);\n if (branchId !== undefined) {\n // This dataflow is from a branch port\n if (activeBranches.has(branchId)) {\n // Branch is active - dataflow gets completed status\n dataflow.setStatus(TaskStatus.COMPLETED);\n } else {\n // Branch is inactive - dataflow gets disabled status\n dataflow.setStatus(TaskStatus.DISABLED);\n }\n } else {\n // Not a branch port (e.g., _activeBranches metadata) - use normal status\n dataflow.setStatus(effectiveStatus);\n }\n }\n\n // Cascade disabled status to downstream tasks\n this.propagateDisabledStatus(graph);\n return;\n }\n\n // Default behavior for non-conditional tasks\n dataflows.forEach((dataflow) => {\n dataflow.setStatus(effectiveStatus);\n });\n }\n\n /**\n * Pushes the error of a task to its target edges\n * @param node The task that produced the error\n */\n protected pushErrorFromNodeToEdges(graph: TaskGraph, node: ITask): void {\n if (!node?.config?.id) return;\n graph.getTargetDataflows(node.config.id).forEach((dataflow) => {\n dataflow.error = node.error;\n });\n }\n\n /**\n * Propagates DISABLED status through the graph.\n *\n * When a task's ALL incoming dataflows are DISABLED, that task becomes unreachable\n * and should also be disabled. This cascades through the graph until no more\n * tasks can be disabled.\n *\n * This is used by ConditionalTask to disable downstream tasks on inactive branches.\n *\n * @param graph The task graph to propagate disabled status through\n */\n protected propagateDisabledStatus(graph: TaskGraph): void {\n let changed = true;\n\n // Keep iterating until no more changes (fixed-point iteration)\n while (changed) {\n changed = false;\n\n for (const task of graph.getTasks()) {\n // Only consider tasks that are still pending\n if (task.status !== TaskStatus.PENDING) {\n continue;\n }\n\n const incomingDataflows = graph.getSourceDataflows(task.config.id);\n\n // Skip tasks with no incoming dataflows (root tasks)\n if (incomingDataflows.length === 0) {\n continue;\n }\n\n // Check if ALL incoming dataflows are DISABLED\n const allDisabled = incomingDataflows.every((df) => df.status === TaskStatus.DISABLED);\n\n if (allDisabled) {\n // This task is unreachable - disable it synchronously\n // Set status directly to avoid async issues\n task.status = TaskStatus.DISABLED;\n task.progress = 100;\n task.completedAt = new Date();\n task.emit(\"disabled\");\n task.emit(\"status\", task.status);\n\n // Propagate disabled status to its outgoing dataflows\n graph.getTargetDataflows(task.config.id).forEach((dataflow) => {\n dataflow.setStatus(TaskStatus.DISABLED);\n });\n\n // Mark as completed in scheduler so it doesn't wait for this task\n this.processScheduler.onTaskCompleted(task.config.id);\n\n changed = true;\n }\n }\n }\n }\n\n /**\n * Runs a task\n * @param task The task to run\n * @param input The input for the task\n * @returns The output of the task\n */\n protected async runTask<T>(task: ITask, input: TaskInput): Promise<GraphSingleTaskResult<T>> {\n this.copyInputFromEdgesToNode(task);\n\n const results = await task.runner.run(input, {\n outputCache: this.outputCache,\n updateProgress: async (task: ITask, progress: number, message?: string, ...args: any[]) =>\n await this.handleProgress(task, progress, message, ...args),\n registry: this.registry,\n });\n\n await this.pushOutputFromNodeToEdges(task, results);\n\n return {\n id: task.config.id,\n type: (task.constructor as any).runtype || (task.constructor as any).type,\n data: results as T,\n };\n }\n\n /**\n * Resets a task\n * @param graph The task graph to reset\n * @param task The task to reset\n * @param runId The run ID\n */\n protected resetTask(graph: TaskGraph, task: ITask, runId: string) {\n task.status = TaskStatus.PENDING;\n task.resetInputData();\n task.runOutputData = {};\n task.error = undefined;\n task.progress = 0;\n if (task.config) {\n task.config.runnerId = runId;\n }\n this.pushStatusFromNodeToEdges(graph, task);\n this.pushErrorFromNodeToEdges(graph, task);\n task.emit(\"reset\");\n task.emit(\"status\", task.status);\n }\n\n /**\n * Resets the task graph, recursively\n * @param graph The task graph to reset\n */\n public resetGraph(graph: TaskGraph, runnerId: string) {\n graph.getTasks().forEach((node) => {\n this.resetTask(graph, node, runnerId);\n node.regenerateGraph();\n if (node.hasChildren()) {\n this.resetGraph(node.subGraph, runnerId);\n }\n });\n graph.getDataflows().forEach((dataflow) => {\n dataflow.reset();\n });\n }\n\n /**\n * Handles the start of task graph execution\n * @param parentSignal Optional abort signal from parent\n */\n protected async handleStart(config?: TaskGraphRunConfig): Promise<void> {\n // Setup registry - create child from global if not provided\n if (config?.registry !== undefined) {\n this.registry = config.registry;\n } else {\n // Create a child container that inherits from global but allows overrides\n this.registry = new ServiceRegistry(globalServiceRegistry.container.createChildContainer());\n }\n\n if (config?.outputCache !== undefined) {\n if (typeof config.outputCache === \"boolean\") {\n if (config.outputCache === true) {\n this.outputCache = this.registry.get(TASK_OUTPUT_REPOSITORY);\n } else {\n this.outputCache = undefined;\n }\n } else {\n this.outputCache = config.outputCache;\n }\n this.graph.outputCache = this.outputCache;\n }\n // Prevent reentrancy\n if (this.running || this.reactiveRunning) {\n throw new TaskConfigurationError(\"Graph is already running\");\n }\n\n this.running = true;\n this.abortController = new AbortController();\n this.abortController.signal.addEventListener(\"abort\", () => {\n this.handleAbort();\n });\n\n if (config?.parentSignal?.aborted) {\n this.abortController.abort(); // Immediately abort if the parent is already aborted\n return;\n } else {\n config?.parentSignal?.addEventListener(\n \"abort\",\n () => {\n this.abortController?.abort();\n },\n { once: true }\n );\n }\n\n this.resetGraph(this.graph, uuid4());\n this.processScheduler.reset();\n this.inProgressTasks.clear();\n this.inProgressFunctions.clear();\n this.failedTaskErrors.clear();\n this.graph.emit(\"start\");\n }\n\n protected async handleStartReactive(): Promise<void> {\n if (this.reactiveRunning) {\n throw new TaskConfigurationError(\"Graph is already running reactively\");\n }\n this.reactiveScheduler.reset();\n this.reactiveRunning = true;\n }\n\n /**\n * Handles the completion of task graph execution\n */\n protected async handleComplete(): Promise<void> {\n this.running = false;\n this.graph.emit(\"complete\");\n }\n\n protected async handleCompleteReactive(): Promise<void> {\n this.reactiveRunning = false;\n }\n\n /**\n * Handles errors during task graph execution\n */\n protected async handleError(error: TaskError): Promise<void> {\n await Promise.allSettled(\n this.graph.getTasks().map(async (task: ITask) => {\n if (task.status === TaskStatus.PROCESSING) {\n task.abort();\n }\n })\n );\n this.running = false;\n this.graph.emit(\"error\", error);\n }\n\n protected async handleErrorReactive(): Promise<void> {\n this.reactiveRunning = false;\n }\n\n /**\n * Handles task graph abortion\n */\n protected async handleAbort(): Promise<void> {\n this.graph.getTasks().map(async (task: ITask) => {\n if (task.status === TaskStatus.PROCESSING) {\n task.abort();\n }\n });\n this.running = false;\n this.graph.emit(\"abort\");\n }\n\n protected async handleAbortReactive(): Promise<void> {\n this.reactiveRunning = false;\n }\n\n /**\n * Handles task graph disabling\n */\n protected async handleDisable(): Promise<void> {\n await Promise.allSettled(\n this.graph.getTasks().map(async (task: ITask) => {\n if (task.status === TaskStatus.PENDING) {\n return task.disable();\n }\n })\n );\n this.running = false;\n this.graph.emit(\"disabled\");\n }\n\n /**\n * Handles progress updates for the task graph\n * Currently not implemented at the graph level\n * @param progress Progress value (0-100)\n * @param message Optional message\n * @param args Additional arguments\n */\n protected async handleProgress(\n task: ITask,\n progress: number,\n message?: string,\n ...args: any[]\n ): Promise<void> {\n const total = this.graph.getTasks().length;\n if (total > 1) {\n const completed = this.graph.getTasks().reduce((acc, t) => acc + t.progress, 0);\n progress = Math.round(completed / total);\n }\n this.pushStatusFromNodeToEdges(this.graph, task);\n await this.pushOutputFromNodeToEdges(task, task.runOutputData);\n this.graph.emit(\"graph_progress\", progress, message, args);\n }\n}\n",
9
+ "/**\n * @license\n * Copyright 2025 Steven Roussey <sroussey@gmail.com>\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {\n collectPropertyValues,\n ConvertAllToOptionalArray,\n globalServiceRegistry,\n ServiceRegistry,\n uuid4,\n} from \"@workglow/util\";\nimport { TASK_OUTPUT_REPOSITORY, TaskOutputRepository } from \"../storage/TaskOutputRepository\";\nimport { ConditionalTask } from \"../task/ConditionalTask\";\nimport { ITask } from \"../task/ITask\";\nimport { TaskAbortedError, TaskConfigurationError, TaskError } from \"../task/TaskError\";\nimport { TaskInput, TaskOutput, TaskStatus } from \"../task/TaskTypes\";\nimport { DATAFLOW_ALL_PORTS } from \"./Dataflow\";\nimport { TaskGraph, TaskGraphRunConfig } from \"./TaskGraph\";\nimport { DependencyBasedScheduler, TopologicalScheduler } from \"./TaskGraphScheduler\";\n\nexport type GraphSingleTaskResult<T> = {\n id: unknown;\n type: String;\n data: T;\n};\nexport type GraphResultArray<T> = Array<GraphSingleTaskResult<T>>;\nexport type PropertyArrayGraphResult<T> = ConvertAllToOptionalArray<T>;\nexport type AnyGraphResult<T> = PropertyArrayGraphResult<T> | GraphResultArray<T>;\n\nexport const PROPERTY_ARRAY = \"PROPERTY_ARRAY\" as const;\nexport const GRAPH_RESULT_ARRAY = \"GRAPH_RESULT_ARRAY\" as const;\n\nexport type GraphResultMap<T> = {\n // array of results with id for tasks that created them -- output is an array of {id, type, data}[]\n [GRAPH_RESULT_ARRAY]: GraphResultArray<T>;\n // property-array -- output is consolidation of each output property, with duplicate properties turned into an array\n [PROPERTY_ARRAY]: PropertyArrayGraphResult<T>;\n};\n\n/**\n * Enum representing the possible compound merge strategies\n */\nexport type CompoundMergeStrategy = typeof PROPERTY_ARRAY | typeof GRAPH_RESULT_ARRAY;\n\nexport type GraphResult<\n Output,\n Merge extends CompoundMergeStrategy,\n> = GraphResultMap<Output>[Merge];\n\n/**\n * Class for running a task graph\n * Manages the execution of tasks in a task graph, including caching\n */\nexport class TaskGraphRunner {\n /**\n * Whether the task graph is currently running\n */\n protected running = false;\n protected reactiveRunning = false;\n\n /**\n * The task graph to run\n */\n public readonly graph: TaskGraph;\n\n /**\n * Output cache repository\n */\n protected outputCache?: TaskOutputRepository;\n /**\n * Service registry for this graph run\n */\n protected registry: ServiceRegistry = globalServiceRegistry;\n /**\n * AbortController for cancelling graph execution\n */\n protected abortController: AbortController | undefined;\n\n /**\n * Maps to track task execution state\n */\n protected inProgressTasks: Map<unknown, Promise<TaskOutput>> = new Map();\n protected inProgressFunctions: Map<unknown, Promise<any>> = new Map();\n protected failedTaskErrors: Map<unknown, TaskError> = new Map();\n\n /**\n * Constructor for TaskGraphRunner\n * @param graph The task graph to run\n * @param outputCache The task output repository to use for caching task outputs\n * @param processScheduler The scheduler to use for task execution\n * @param reactiveScheduler The scheduler to use for reactive task execution\n */\n constructor(\n graph: TaskGraph,\n outputCache?: TaskOutputRepository,\n protected processScheduler = new DependencyBasedScheduler(graph),\n protected reactiveScheduler = new TopologicalScheduler(graph)\n ) {\n this.graph = graph;\n graph.outputCache = outputCache;\n this.handleProgress = this.handleProgress.bind(this);\n }\n\n // ========================================================================\n // Public methods\n // ========================================================================\n\n public async runGraph<ExecuteOutput extends TaskOutput>(\n input: TaskInput = {} as TaskInput,\n config?: TaskGraphRunConfig\n ): Promise<GraphResultArray<ExecuteOutput>> {\n await this.handleStart(config);\n\n const results: GraphResultArray<ExecuteOutput> = [];\n let error: TaskError | undefined;\n\n try {\n // TODO: A different graph runner may chunk tasks that are in parallel\n // rather them all currently available\n for await (const task of this.processScheduler.tasks()) {\n if (this.abortController?.signal.aborted) {\n break;\n }\n\n if (this.failedTaskErrors.size > 0) {\n break;\n }\n\n const isRootTask = this.graph.getSourceDataflows(task.config.id).length === 0;\n\n const runAsync = async () => {\n try {\n // Only filter input for non-root tasks; root tasks get the full input\n const taskInput = isRootTask ? input : this.filterInputForTask(task, input);\n\n const taskPromise = this.runTask(task, taskInput);\n this.inProgressTasks!.set(task.config.id, taskPromise);\n const taskResult = await taskPromise;\n\n if (this.graph.getTargetDataflows(task.config.id).length === 0) {\n // we save the results of all the leaves\n results.push(taskResult as GraphSingleTaskResult<ExecuteOutput>);\n }\n } catch (error) {\n this.failedTaskErrors.set(task.config.id, error as TaskError);\n } finally {\n // IMPORTANT: Push status to edges BEFORE notifying scheduler\n // This ensures dataflow statuses (including DISABLED) are set\n // before the scheduler checks which tasks are ready\n this.pushStatusFromNodeToEdges(this.graph, task);\n this.pushErrorFromNodeToEdges(this.graph, task);\n this.processScheduler.onTaskCompleted(task.config.id);\n }\n };\n\n // Start task execution without awaiting\n // so we can have many tasks running in parallel\n // but keep track of them to make sure they get awaited\n // otherwise, things will finish after this promise is resolved\n this.inProgressFunctions.set(Symbol(task.config.id as string), runAsync());\n }\n } catch (err) {\n error = err as Error;\n }\n // Wait for all tasks to complete since we did not await runAsync()/this.runTaskWithProvenance()\n await Promise.allSettled(Array.from(this.inProgressTasks.values()));\n // Clean up stragglers to avoid unhandled promise rejections\n await Promise.allSettled(Array.from(this.inProgressFunctions.values()));\n\n if (this.failedTaskErrors.size > 0) {\n const latestError = this.failedTaskErrors.values().next().value!;\n this.handleError(latestError);\n throw latestError;\n }\n if (this.abortController?.signal.aborted) {\n await this.handleAbort();\n throw new TaskAbortedError();\n }\n\n await this.handleComplete();\n\n return results;\n }\n\n /**\n * Runs the task graph in a reactive manner\n * @param input Optional input to pass to root tasks (tasks with no incoming dataflows)\n * @returns A promise that resolves when all tasks are complete\n * @throws TaskConfigurationError if the graph is already running reactively\n */\n public async runGraphReactive<Output extends TaskOutput>(\n input: TaskInput = {} as TaskInput\n ): Promise<GraphResultArray<Output>> {\n await this.handleStartReactive();\n\n const results: GraphResultArray<Output> = [];\n try {\n for await (const task of this.reactiveScheduler.tasks()) {\n const isRootTask = this.graph.getSourceDataflows(task.config.id).length === 0;\n\n if (task.status === TaskStatus.PENDING) {\n task.resetInputData();\n this.copyInputFromEdgesToNode(task);\n // TODO: cacheable here??\n // if (task.cacheable) {\n // const results = await this.outputCache?.getOutput(\n // (task.constructor as any).type,\n // task.runInputData\n // );\n // if (results) {\n // task.runOutputData = results;\n // }\n // }\n }\n\n // For root tasks (no incoming dataflows), apply the input parameter\n // This is important for GraphAsTask subgraphs where the InputTask needs\n // to receive the parent's input values\n const taskInput = isRootTask ? input : {};\n\n const taskResult = await task.runReactive(taskInput);\n\n await this.pushOutputFromNodeToEdges(task, taskResult);\n if (this.graph.getTargetDataflows(task.config.id).length === 0) {\n results.push({\n id: task.config.id,\n type: (task.constructor as any).runtype || (task.constructor as any).type,\n data: taskResult as Output,\n });\n }\n }\n await this.handleCompleteReactive();\n return results;\n } catch (error) {\n await this.handleErrorReactive();\n throw error;\n }\n }\n\n /**\n * Aborts the task graph execution\n */\n public abort(): void {\n this.abortController?.abort();\n }\n\n /**\n * Disables the task graph execution\n */\n public async disable(): Promise<void> {\n await this.handleDisable();\n }\n\n /**\n * Filters graph-level input to only include properties that are not connected via dataflows for a given task\n * @param task The task to filter input for\n * @param input The graph-level input\n * @returns Filtered input containing only unconnected properties\n */\n protected filterInputForTask(task: ITask, input: TaskInput): TaskInput {\n // Get all inputs that are connected to this task via dataflows\n const sourceDataflows = this.graph.getSourceDataflows(task.config.id);\n const connectedInputs = new Set(sourceDataflows.map((df) => df.targetTaskPortId));\n\n // If DATAFLOW_ALL_PORTS (\"*\") is in the set, all inputs are connected\n const allPortsConnected = connectedInputs.has(DATAFLOW_ALL_PORTS);\n\n // Filter out connected inputs from the graph input\n const filteredInput: TaskInput = {};\n for (const [key, value] of Object.entries(input)) {\n // Skip this input if it's explicitly connected OR if all ports are connected\n if (!connectedInputs.has(key) && !allPortsConnected) {\n filteredInput[key] = value;\n }\n }\n\n return filteredInput;\n }\n\n /**\n * Adds input data to a task.\n * Delegates to {@link Task.addInput} for the actual merging logic.\n *\n * @param task The task to add input data to\n * @param overrides The input data to override (or add to if an array)\n */\n public addInputData(task: ITask, overrides: Partial<TaskInput> | undefined): void {\n if (!overrides) return;\n\n const changed = task.addInput(overrides);\n\n // TODO(str): This is a hack.\n if (changed && \"regenerateGraph\" in task && typeof task.regenerateGraph === \"function\") {\n task.regenerateGraph();\n }\n }\n\n // ========================================================================\n // Protected Handlers\n // ========================================================================\n public mergeExecuteOutputsToRunOutput<\n ExecuteOutput extends TaskOutput,\n Merge extends CompoundMergeStrategy = CompoundMergeStrategy,\n >(\n results: GraphResultArray<ExecuteOutput>,\n compoundMerge: Merge\n ): GraphResult<ExecuteOutput, Merge> {\n if (compoundMerge === GRAPH_RESULT_ARRAY) {\n return results as GraphResult<ExecuteOutput, Merge>;\n }\n\n if (compoundMerge === PROPERTY_ARRAY) {\n let fixedOutput = {} as PropertyArrayGraphResult<ExecuteOutput>;\n const outputs = results.map((result: any) => result.data);\n if (outputs.length === 1) {\n fixedOutput = outputs[0];\n } else if (outputs.length > 1) {\n const collected = collectPropertyValues<ExecuteOutput>(outputs as ExecuteOutput[]);\n if (Object.keys(collected).length > 0) {\n fixedOutput = collected;\n }\n }\n return fixedOutput as GraphResult<ExecuteOutput, Merge>;\n }\n throw new TaskConfigurationError(`Unknown compound merge strategy: ${compoundMerge}`);\n }\n\n /**\n * Copies input data from edges to a task\n * @param task The task to copy input data to\n */\n protected copyInputFromEdgesToNode(task: ITask) {\n const dataflows = this.graph.getSourceDataflows(task.config.id);\n for (const dataflow of dataflows) {\n this.addInputData(task, dataflow.getPortData());\n }\n }\n\n /**\n * Pushes the output of a task to its target tasks\n * @param node The task that produced the output\n * @param results The output of the task\n */\n protected async pushOutputFromNodeToEdges(node: ITask, results: TaskOutput) {\n const dataflows = this.graph.getTargetDataflows(node.config.id);\n for (const dataflow of dataflows) {\n const compatibility = dataflow.semanticallyCompatible(this.graph, dataflow);\n // console.log(\"pushOutputFromNodeToEdges\", dataflow.id, compatibility, Object.keys(results));\n if (compatibility === \"static\") {\n dataflow.setPortData(results);\n } else if (compatibility === \"runtime\") {\n const task = this.graph.getTask(dataflow.targetTaskId)!;\n const narrowed = await task.narrowInput({ ...results }, this.registry);\n dataflow.setPortData(narrowed);\n } else {\n // don't push incompatible data\n }\n }\n }\n\n /**\n * Pushes the status of a task to its target edges\n * @param node The task that produced the status\n *\n * For ConditionalTask, this method handles selective dataflow status:\n * - Active branch dataflows get COMPLETED status\n * - Inactive branch dataflows get DISABLED status\n */\n protected pushStatusFromNodeToEdges(graph: TaskGraph, node: ITask, status?: TaskStatus): void {\n if (!node?.config?.id) return;\n\n const dataflows = graph.getTargetDataflows(node.config.id);\n const effectiveStatus = status ?? node.status;\n\n // Check if this is a ConditionalTask with selective branching\n if (node instanceof ConditionalTask && effectiveStatus === TaskStatus.COMPLETED) {\n // Build a map of output port -> branch ID for lookup\n const branches = node.config.branches ?? [];\n const portToBranch = new Map<string, string>();\n for (const branch of branches) {\n portToBranch.set(branch.outputPort, branch.id);\n }\n\n const activeBranches = node.getActiveBranches();\n\n for (const dataflow of dataflows) {\n const branchId = portToBranch.get(dataflow.sourceTaskPortId);\n if (branchId !== undefined) {\n // This dataflow is from a branch port\n if (activeBranches.has(branchId)) {\n // Branch is active - dataflow gets completed status\n dataflow.setStatus(TaskStatus.COMPLETED);\n } else {\n // Branch is inactive - dataflow gets disabled status\n dataflow.setStatus(TaskStatus.DISABLED);\n }\n } else {\n // Not a branch port (e.g., _activeBranches metadata) - use normal status\n dataflow.setStatus(effectiveStatus);\n }\n }\n\n // Cascade disabled status to downstream tasks\n this.propagateDisabledStatus(graph);\n return;\n }\n\n // Default behavior for non-conditional tasks\n dataflows.forEach((dataflow) => {\n dataflow.setStatus(effectiveStatus);\n });\n }\n\n /**\n * Pushes the error of a task to its target edges\n * @param node The task that produced the error\n */\n protected pushErrorFromNodeToEdges(graph: TaskGraph, node: ITask): void {\n if (!node?.config?.id) return;\n graph.getTargetDataflows(node.config.id).forEach((dataflow) => {\n dataflow.error = node.error;\n });\n }\n\n /**\n * Propagates DISABLED status through the graph.\n *\n * When a task's ALL incoming dataflows are DISABLED, that task becomes unreachable\n * and should also be disabled. This cascades through the graph until no more\n * tasks can be disabled.\n *\n * This is used by ConditionalTask to disable downstream tasks on inactive branches.\n *\n * @param graph The task graph to propagate disabled status through\n */\n protected propagateDisabledStatus(graph: TaskGraph): void {\n let changed = true;\n\n // Keep iterating until no more changes (fixed-point iteration)\n while (changed) {\n changed = false;\n\n for (const task of graph.getTasks()) {\n // Only consider tasks that are still pending\n if (task.status !== TaskStatus.PENDING) {\n continue;\n }\n\n const incomingDataflows = graph.getSourceDataflows(task.config.id);\n\n // Skip tasks with no incoming dataflows (root tasks)\n if (incomingDataflows.length === 0) {\n continue;\n }\n\n // Check if ALL incoming dataflows are DISABLED\n const allDisabled = incomingDataflows.every((df) => df.status === TaskStatus.DISABLED);\n\n if (allDisabled) {\n // This task is unreachable - disable it synchronously\n // Set status directly to avoid async issues\n task.status = TaskStatus.DISABLED;\n task.progress = 100;\n task.completedAt = new Date();\n task.emit(\"disabled\");\n task.emit(\"status\", task.status);\n\n // Propagate disabled status to its outgoing dataflows\n graph.getTargetDataflows(task.config.id).forEach((dataflow) => {\n dataflow.setStatus(TaskStatus.DISABLED);\n });\n\n // Mark as completed in scheduler so it doesn't wait for this task\n this.processScheduler.onTaskCompleted(task.config.id);\n\n changed = true;\n }\n }\n }\n }\n\n /**\n * Runs a task\n * @param task The task to run\n * @param input The input for the task\n * @returns The output of the task\n */\n protected async runTask<T>(task: ITask, input: TaskInput): Promise<GraphSingleTaskResult<T>> {\n this.copyInputFromEdgesToNode(task);\n\n const results = await task.runner.run(input, {\n outputCache: this.outputCache,\n updateProgress: async (task: ITask, progress: number, message?: string, ...args: any[]) =>\n await this.handleProgress(task, progress, message, ...args),\n registry: this.registry,\n });\n\n await this.pushOutputFromNodeToEdges(task, results);\n\n return {\n id: task.config.id,\n type: (task.constructor as any).runtype || (task.constructor as any).type,\n data: results as T,\n };\n }\n\n /**\n * Resets a task\n * @param graph The task graph to reset\n * @param task The task to reset\n * @param runId The run ID\n */\n protected resetTask(graph: TaskGraph, task: ITask, runId: string) {\n task.status = TaskStatus.PENDING;\n task.resetInputData();\n task.runOutputData = {};\n task.error = undefined;\n task.progress = 0;\n if (task.config) {\n task.config.runnerId = runId;\n }\n this.pushStatusFromNodeToEdges(graph, task);\n this.pushErrorFromNodeToEdges(graph, task);\n task.emit(\"reset\");\n task.emit(\"status\", task.status);\n }\n\n /**\n * Resets the task graph, recursively\n * @param graph The task graph to reset\n */\n public resetGraph(graph: TaskGraph, runnerId: string) {\n graph.getTasks().forEach((node) => {\n this.resetTask(graph, node, runnerId);\n node.regenerateGraph();\n if (node.hasChildren()) {\n this.resetGraph(node.subGraph, runnerId);\n }\n });\n graph.getDataflows().forEach((dataflow) => {\n dataflow.reset();\n });\n }\n\n /**\n * Handles the start of task graph execution\n * @param parentSignal Optional abort signal from parent\n */\n protected async handleStart(config?: TaskGraphRunConfig): Promise<void> {\n // Setup registry - create child from global if not provided\n if (config?.registry !== undefined) {\n this.registry = config.registry;\n } else {\n // Create a child container that inherits from global but allows overrides\n this.registry = new ServiceRegistry(globalServiceRegistry.container.createChildContainer());\n }\n\n if (config?.outputCache !== undefined) {\n if (typeof config.outputCache === \"boolean\") {\n if (config.outputCache === true) {\n this.outputCache = this.registry.get(TASK_OUTPUT_REPOSITORY);\n } else {\n this.outputCache = undefined;\n }\n } else {\n this.outputCache = config.outputCache;\n }\n this.graph.outputCache = this.outputCache;\n }\n // Prevent reentrancy\n if (this.running || this.reactiveRunning) {\n throw new TaskConfigurationError(\"Graph is already running\");\n }\n\n this.running = true;\n this.abortController = new AbortController();\n this.abortController.signal.addEventListener(\"abort\", () => {\n this.handleAbort();\n });\n\n if (config?.parentSignal?.aborted) {\n this.abortController.abort(); // Immediately abort if the parent is already aborted\n return;\n } else {\n config?.parentSignal?.addEventListener(\n \"abort\",\n () => {\n this.abortController?.abort();\n },\n { once: true }\n );\n }\n\n this.resetGraph(this.graph, uuid4());\n this.processScheduler.reset();\n this.inProgressTasks.clear();\n this.inProgressFunctions.clear();\n this.failedTaskErrors.clear();\n this.graph.emit(\"start\");\n }\n\n protected async handleStartReactive(): Promise<void> {\n if (this.reactiveRunning) {\n throw new TaskConfigurationError(\"Graph is already running reactively\");\n }\n this.reactiveScheduler.reset();\n this.reactiveRunning = true;\n }\n\n /**\n * Handles the completion of task graph execution\n */\n protected async handleComplete(): Promise<void> {\n this.running = false;\n this.graph.emit(\"complete\");\n }\n\n protected async handleCompleteReactive(): Promise<void> {\n this.reactiveRunning = false;\n }\n\n /**\n * Handles errors during task graph execution\n */\n protected async handleError(error: TaskError): Promise<void> {\n await Promise.allSettled(\n this.graph.getTasks().map(async (task: ITask) => {\n if (task.status === TaskStatus.PROCESSING) {\n task.abort();\n }\n })\n );\n this.running = false;\n this.graph.emit(\"error\", error);\n }\n\n protected async handleErrorReactive(): Promise<void> {\n this.reactiveRunning = false;\n }\n\n /**\n * Handles task graph abortion\n */\n protected async handleAbort(): Promise<void> {\n this.graph.getTasks().map(async (task: ITask) => {\n if (task.status === TaskStatus.PROCESSING) {\n task.abort();\n }\n });\n this.running = false;\n this.graph.emit(\"abort\");\n }\n\n protected async handleAbortReactive(): Promise<void> {\n this.reactiveRunning = false;\n }\n\n /**\n * Handles task graph disabling\n */\n protected async handleDisable(): Promise<void> {\n await Promise.allSettled(\n this.graph.getTasks().map(async (task: ITask) => {\n if (task.status === TaskStatus.PENDING) {\n return task.disable();\n }\n })\n );\n this.running = false;\n this.graph.emit(\"disabled\");\n }\n\n /**\n * Handles progress updates for the task graph\n * Currently not implemented at the graph level\n * @param progress Progress value (0-100)\n * @param message Optional message\n * @param args Additional arguments\n */\n protected async handleProgress(\n task: ITask,\n progress: number,\n message?: string,\n ...args: any[]\n ): Promise<void> {\n const total = this.graph.getTasks().length;\n if (total > 1) {\n const completed = this.graph.getTasks().reduce((acc, t) => acc + t.progress, 0);\n progress = Math.round(completed / total);\n }\n this.pushStatusFromNodeToEdges(this.graph, task);\n await this.pushOutputFromNodeToEdges(task, task.runOutputData);\n this.graph.emit(\"graph_progress\", progress, message, args);\n }\n}\n",
11
10
  "/**\n * @license\n * Copyright 2025 Steven Roussey <sroussey@gmail.com>\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport { createServiceToken, EventEmitter, EventParameters } from \"@workglow/util\";\nimport { TaskInput, TaskOutput } from \"../task/TaskTypes\";\n\n/**\n * Service token for TaskOutputRepository\n */\nexport const TASK_OUTPUT_REPOSITORY = createServiceToken<TaskOutputRepository>(\n \"taskgraph.taskOutputRepository\"\n);\n\nexport type TaskOutputEventListeners = {\n output_saved: (taskType: string) => void;\n output_retrieved: (taskType: string) => void;\n output_cleared: () => void;\n output_pruned: () => void;\n};\n\nexport type TaskOutputEvents = keyof TaskOutputEventListeners;\n\nexport type TaskOutputEventListener<Event extends TaskOutputEvents> =\n TaskOutputEventListeners[Event];\n\nexport type TaskOutputEventParameters<Event extends TaskOutputEvents> = EventParameters<\n TaskOutputEventListeners,\n Event\n>;\n\n/**\n * Abstract class for managing task outputs in a repository\n * Provides methods for saving, retrieving, and clearing task outputs\n */\nexport abstract class TaskOutputRepository {\n /**\n * Whether to compress the output\n */\n outputCompression: boolean;\n\n /**\n * Constructor for the TaskOutputRepository\n * @param options The options for the repository\n */\n constructor({ outputCompression = true }) {\n this.outputCompression = outputCompression;\n }\n\n private get events() {\n if (!this._events) {\n this._events = new EventEmitter<TaskOutputEventListeners>();\n }\n return this._events;\n }\n private _events: EventEmitter<TaskOutputEventListeners> | undefined;\n\n /**\n * Registers an event listener for a specific event\n * @param name The event name to listen for\n * @param fn The callback function to execute when the event occurs\n */\n on<Event extends TaskOutputEvents>(name: Event, fn: TaskOutputEventListener<Event>) {\n this.events.on(name, fn);\n }\n\n /**\n * Removes an event listener for a specific event\n * @param name The event name to stop listening for\n * @param fn The callback function to remove\n */\n off<Event extends TaskOutputEvents>(name: Event, fn: TaskOutputEventListener<Event>) {\n this.events.off(name, fn);\n }\n\n /**\n * Returns a promise that resolves when the event is emitted\n * @param name The event name to listen for\n * @returns a promise that resolves to the event parameters\n */\n waitOn<Event extends TaskOutputEvents>(name: Event) {\n return this.events.waitOn(name) as Promise<TaskOutputEventParameters<Event>>;\n }\n\n /**\n * Emits an event (if there are listeners)\n * @param name The event name to emit\n * @param args The event parameters\n */\n emit<Event extends TaskOutputEvents>(name: Event, ...args: TaskOutputEventParameters<Event>) {\n this._events?.emit(name, ...args);\n }\n\n /**\n * Saves a task output to the repository\n * @param taskType The type of task to save the output for\n * @param inputs The input parameters for the task\n * @param output The task output to save\n */\n abstract saveOutput(\n taskType: string,\n inputs: TaskInput,\n output: TaskOutput,\n createdAt?: Date // for testing purposes\n ): Promise<void>;\n\n /**\n * Retrieves a task output from the repository\n * @param taskType The type of task to retrieve the output for\n * @param inputs The input parameters for the task\n * @returns The retrieved task output, or undefined if not found\n */\n abstract getOutput(taskType: string, inputs: TaskInput): Promise<TaskOutput | undefined>;\n\n /**\n * Clears all task outputs from the repository\n * @emits output_cleared when the operation completes\n */\n abstract clear(): Promise<void>;\n\n /**\n * Returns the number of task outputs stored in the repository\n * @returns The count of stored task outputs\n */\n abstract size(): Promise<number>;\n\n /**\n * Clear all task outputs from the repository that are older than the given date\n * @param olderThanInMs The time in milliseconds to clear task outputs older than\n */\n abstract clearOlderThan(olderThanInMs: number): Promise<void>;\n}\n",
12
11
  "/**\n * @license\n * Copyright 2025 Steven Roussey <sroussey@gmail.com>\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {\n compileSchema,\n deepEqual,\n EventEmitter,\n SchemaNode,\n uuid4,\n type DataPortSchema,\n type ServiceRegistry,\n} from \"@workglow/util\";\nimport { DATAFLOW_ALL_PORTS } from \"../task-graph/Dataflow\";\nimport { TaskGraph } from \"../task-graph/TaskGraph\";\nimport type { IExecuteContext, IExecuteReactiveContext, ITask } from \"./ITask\";\nimport { TaskAbortedError, TaskError, TaskInvalidInputError } from \"./TaskError\";\nimport {\n type TaskEventListener,\n type TaskEventListeners,\n type TaskEventParameters,\n type TaskEvents,\n} from \"./TaskEvents\";\nimport type { JsonTaskItem, TaskGraphItemJson } from \"./TaskJSON\";\nimport { TaskRunner } from \"./TaskRunner\";\nimport {\n TaskStatus,\n type TaskConfig,\n type TaskIdType,\n type TaskInput,\n type TaskOutput,\n type TaskTypeName,\n} from \"./TaskTypes\";\n\n/**\n * Base class for all tasks that implements the ITask interface.\n * This abstract class provides common functionality for both simple and compound tasks.\n *\n * The Task class is responsible for:\n * 1. Defining what a task is (inputs, outputs, configuration)\n * 2. Providing the execution logic (via execute and executeReactive)\n * 3. Delegating the running logic to a TaskRunner\n */\nexport class Task<\n Input extends TaskInput = TaskInput,\n Output extends TaskOutput = TaskOutput,\n Config extends TaskConfig = TaskConfig,\n> implements ITask<Input, Output, Config> {\n // ========================================================================\n // Static properties - should be overridden by subclasses\n // ========================================================================\n\n /**\n * The type identifier for this task class\n */\n public static type: TaskTypeName = \"Task\";\n\n /**\n * The category this task belongs to\n */\n public static category: string = \"Hidden\";\n\n /**\n * The title of this task\n */\n public static title: string = \"\";\n\n /**\n * Whether this task has side effects\n */\n public static cacheable: boolean = true;\n\n /**\n * Whether this task has dynamic input/output schemas that can change at runtime.\n * Tasks with dynamic schemas should override instance methods for inputSchema() and/or outputSchema()\n * and emit 'schemaChange' events when their schemas change.\n */\n public static hasDynamicSchemas: boolean = false;\n\n /**\n * Input schema for this task\n */\n public static inputSchema(): DataPortSchema {\n return {\n type: \"object\",\n properties: {},\n additionalProperties: false,\n } as const satisfies DataPortSchema;\n }\n\n /**\n * Output schema for this task\n */\n public static outputSchema(): DataPortSchema {\n return {\n type: \"object\",\n properties: {},\n additionalProperties: false,\n } as const satisfies DataPortSchema;\n }\n\n // ========================================================================\n // Task Execution Methods - Core logic provided by subclasses\n // ========================================================================\n\n /**\n * The actual task execution logic for subclasses to override\n *\n * @param input The input to the task\n * @param config The configuration for the task\n * @throws TaskError if the task fails\n * @returns The output of the task or undefined if no changes\n */\n public async execute(input: Input, context: IExecuteContext): Promise<Output | undefined> {\n if (context.signal?.aborted) {\n throw new TaskAbortedError(\"Task aborted\");\n }\n return undefined;\n }\n\n /**\n * Default implementation of executeReactive that does nothing.\n * Subclasses should override this to provide actual reactive functionality.\n *\n * This is generally for UI updating, and should be lightweight.\n * @param input The input to the task\n * @param output The current output of the task\n * @returns The updated output of the task or undefined if no changes\n */\n public async executeReactive(\n input: Input,\n output: Output,\n context: IExecuteReactiveContext\n ): Promise<Output | undefined> {\n return output;\n }\n\n // ========================================================================\n // TaskRunner delegation - Executes and manages the task\n // ========================================================================\n\n /**\n * Task runner for handling the task execution\n */\n protected _runner: TaskRunner<Input, Output, Config> | undefined;\n\n /**\n * Gets the task runner instance\n * Creates a new one if it doesn't exist\n */\n public get runner(): TaskRunner<Input, Output, Config> {\n if (!this._runner) {\n this._runner = new TaskRunner<Input, Output, Config>(this);\n }\n return this._runner;\n }\n\n /**\n * Runs the task and returns the output\n * Delegates to the task runner\n *\n * @param overrides Optional input overrides\n * @throws TaskError if the task fails\n * @returns The task output\n */\n async run(overrides: Partial<Input> = {}): Promise<Output> {\n return this.runner.run(overrides);\n }\n\n /**\n * Runs the task in reactive mode\n * Delegates to the task runner\n *\n * @param overrides Optional input overrides\n * @returns The task output\n */\n public async runReactive(overrides: Partial<Input> = {}): Promise<Output> {\n return this.runner.runReactive(overrides);\n }\n\n /**\n * Aborts task execution\n * Delegates to the task runner\n */\n public abort(): void {\n this.runner.abort();\n }\n\n /**\n * Disables task execution\n * Delegates to the task runner\n */\n public async disable(): Promise<void> {\n await this.runner.disable();\n }\n\n // ========================================================================\n // Static to Instance conversion methods\n // ========================================================================\n\n /**\n * Gets input schema for this task\n */\n public inputSchema(): DataPortSchema {\n return (this.constructor as typeof Task).inputSchema();\n }\n\n /**\n * Gets output schema for this task\n */\n public outputSchema(): DataPortSchema {\n return (this.constructor as typeof Task).outputSchema();\n }\n\n public get type(): TaskTypeName {\n return (this.constructor as typeof Task).type;\n }\n\n public get category(): string {\n return (this.constructor as typeof Task).category;\n }\n\n public get title(): string {\n return (this.constructor as typeof Task).title;\n }\n\n public get cacheable(): boolean {\n return (\n // if cacheable is set in config, always use that\n this.config?.cacheable ?? (this.constructor as typeof Task).cacheable\n );\n }\n\n // ========================================================================\n // Instance properties using @template types\n // ========================================================================\n\n /**\n * Default input values for this task.\n * If no overrides at run time, then this would be equal to the input.\n * resetInputData() will reset inputs to these defaults.\n */\n defaults: Record<string, any>;\n\n /**\n * The input to the task at the time of the task run.\n * This takes defaults from construction time and overrides from run time.\n * It is the input that created the output.\n */\n runInputData: Record<string, any> = {};\n\n /**\n * The output of the task at the time of the task run.\n * This is the result of the task execution.\n */\n runOutputData: Record<string, any> = {};\n\n // ========================================================================\n // Task state properties\n // ========================================================================\n\n /**\n * The configuration of the task\n */\n config: Config;\n\n /**\n * Current status of the task\n */\n status: TaskStatus = TaskStatus.PENDING;\n\n /**\n * Progress of the task (0-100)\n */\n progress: number = 0;\n\n /**\n * When the task was created\n */\n createdAt: Date = new Date();\n\n /**\n * When the task started execution\n */\n startedAt?: Date;\n\n /**\n * When the task completed execution\n */\n completedAt?: Date;\n\n /**\n * Error that occurred during task execution, if any\n */\n error?: TaskError;\n\n /**\n * Event emitter for task lifecycle events\n */\n public get events(): EventEmitter<TaskEventListeners> {\n if (!this._events) {\n this._events = new EventEmitter<TaskEventListeners>();\n }\n return this._events;\n }\n protected _events: EventEmitter<TaskEventListeners> | undefined;\n\n /**\n * Creates a new task instance\n *\n * @param callerDefaultInputs Default input values provided by the caller\n * @param config Configuration for the task\n */\n constructor(callerDefaultInputs: Partial<Input> = {}, config: Partial<Config> = {}) {\n // Initialize input defaults\n const inputDefaults = this.getDefaultInputsFromStaticInputDefinitions();\n const mergedDefaults = Object.assign(inputDefaults, callerDefaultInputs);\n // Strip symbol properties (like [$JSONSchema]) before storing defaults\n this.defaults = this.stripSymbols(mergedDefaults) as Record<string, any>;\n this.resetInputData();\n\n // Setup configuration defaults\n const name = this.title || new.target.title || new.target.name;\n this.config = Object.assign(\n {\n id: uuid4(),\n name: name,\n },\n config\n ) as Config;\n }\n\n // ========================================================================\n // Input/Output handling\n // ========================================================================\n\n /**\n * Gets default input values from input schema\n */\n getDefaultInputsFromStaticInputDefinitions(): Partial<Input> {\n const schema = this.inputSchema();\n if (typeof schema === \"boolean\") {\n return {};\n }\n try {\n const compiledSchema = this.getInputSchemaNode(this.type);\n const defaultData = compiledSchema.getData(undefined, {\n addOptionalProps: true,\n removeInvalidData: false,\n useTypeDefaults: false,\n });\n return (defaultData || {}) as Partial<Input>;\n } catch (error) {\n console.warn(\n `Failed to compile input schema for ${this.type}, falling back to manual extraction:`,\n error\n );\n // Fallback to manual extraction if compilation fails\n return Object.entries(schema.properties || {}).reduce<Record<string, any>>(\n (acc, [id, prop]) => {\n const defaultValue = (prop as any).default;\n if (defaultValue !== undefined) {\n acc[id] = defaultValue;\n }\n return acc;\n },\n {}\n ) as Partial<Input>;\n }\n }\n\n /**\n * Resets input data to defaults\n */\n public resetInputData(): void {\n this.runInputData = this.smartClone(this.defaults) as Record<string, any>;\n }\n\n /**\n * Smart clone that deep-clones plain objects and arrays while preserving\n * class instances (objects with non-Object prototype) by reference.\n * Detects and throws an error on circular references.\n *\n * This is necessary because:\n * - structuredClone cannot clone class instances (methods are lost)\n * - JSON.parse/stringify loses methods and fails on circular references\n * - Class instances like repositories should be passed by reference\n *\n * This breaks the idea of everything being json serializable, but it allows\n * more efficient use cases. Do be careful with this though! Use sparingly.\n *\n * @param obj The object to clone\n * @param visited Set of objects in the current cloning path (for circular reference detection)\n * @returns A cloned object with class instances preserved by reference\n */\n private smartClone(obj: any, visited: WeakSet<object> = new WeakSet()): any {\n if (obj === null || obj === undefined) {\n return obj;\n }\n\n // Primitives (string, number, boolean, symbol, bigint) are returned as-is\n if (typeof obj !== \"object\") {\n return obj;\n }\n\n // Check for circular references\n if (visited.has(obj)) {\n throw new Error(\n \"Circular reference detected in input data. \" +\n \"Cannot clone objects with circular references.\"\n );\n }\n\n // Clone TypedArrays (Float32Array, Int8Array, etc.) to avoid shared-mutation\n // between defaults and runInputData, while preserving DataView by reference.\n if (ArrayBuffer.isView(obj)) {\n // Preserve DataView instances by reference (constructor signature differs)\n if (typeof DataView !== \"undefined\" && obj instanceof DataView) {\n return obj;\n }\n // For TypedArrays, create a new instance with the same data\n const typedArray = obj as any;\n return new (typedArray.constructor as any)(typedArray);\n }\n\n // Preserve class instances (objects with non-Object/non-Array prototype)\n // This includes repository instances, custom classes, etc.\n if (!Array.isArray(obj)) {\n const proto = Object.getPrototypeOf(obj);\n if (proto !== Object.prototype && proto !== null) {\n return obj; // Pass by reference\n }\n }\n\n // Add object to visited set before recursing\n visited.add(obj);\n\n try {\n // Deep clone arrays, preserving class instances within\n if (Array.isArray(obj)) {\n return obj.map((item) => this.smartClone(item, visited));\n }\n\n // Deep clone plain objects\n const result: Record<string, any> = {};\n for (const key in obj) {\n if (Object.prototype.hasOwnProperty.call(obj, key)) {\n result[key] = this.smartClone(obj[key], visited);\n }\n }\n return result;\n } finally {\n // Remove from visited set after processing to allow the same object\n // in different branches (non-circular references)\n visited.delete(obj);\n }\n }\n\n /**\n * Sets the default input values for the task\n *\n * @param defaults The default input values to set\n */\n public setDefaults(defaults: Record<string, any>): void {\n // Strip symbol properties (like [$JSONSchema]) before storing defaults\n this.defaults = this.stripSymbols(defaults) as Record<string, any>;\n }\n\n /**\n * Sets input values for the task\n *\n * @param input Input values to set\n */\n public setInput(input: Record<string, any>): void {\n const schema = this.inputSchema();\n if (typeof schema === \"boolean\") {\n if (schema === true) {\n for (const [inputId, value] of Object.entries(input)) {\n if (value !== undefined) {\n this.runInputData[inputId] = value;\n }\n }\n }\n return;\n }\n const properties = schema.properties || {};\n\n // Copy explicitly defined properties\n for (const [inputId, prop] of Object.entries(properties)) {\n if (input[inputId] !== undefined) {\n this.runInputData[inputId] = input[inputId];\n } else if (this.runInputData[inputId] === undefined && (prop as any).default !== undefined) {\n this.runInputData[inputId] = (prop as any).default;\n }\n }\n\n // If additionalProperties is true, also copy any additional input properties\n if (schema.additionalProperties === true) {\n for (const [inputId, value] of Object.entries(input)) {\n if (!(inputId in properties)) {\n this.runInputData[inputId] = value;\n }\n }\n }\n }\n\n /**\n * Adds/merges input data during graph execution.\n * Unlike {@link setInput}, this method:\n * - Detects changes using deep equality\n * - Accumulates array values (appends rather than replaces)\n * - Handles DATAFLOW_ALL_PORTS for pass-through\n * - Handles additionalProperties for dynamic schemas\n *\n * @param overrides The input data to merge\n * @returns true if any input data was changed, false otherwise\n */\n public addInput(overrides: Partial<Input> | undefined): boolean {\n if (!overrides) return false;\n\n let changed = false;\n const inputSchema = this.inputSchema();\n\n if (typeof inputSchema === \"boolean\") {\n if (inputSchema === false) {\n return false;\n }\n // Schema is `true` - accept any input\n for (const [key, value] of Object.entries(overrides)) {\n if (!deepEqual(this.runInputData[key], value)) {\n this.runInputData[key] = value;\n changed = true;\n }\n }\n return changed;\n }\n\n const properties = inputSchema.properties || {};\n\n for (const [inputId, prop] of Object.entries(properties)) {\n if (inputId === DATAFLOW_ALL_PORTS) {\n this.runInputData = { ...this.runInputData, ...overrides };\n changed = true;\n } else {\n if (overrides[inputId] === undefined) continue;\n const isArray =\n (prop as any)?.type === \"array\" ||\n ((prop as any)?.type === \"any\" &&\n (Array.isArray(overrides[inputId]) || Array.isArray(this.runInputData[inputId])));\n\n if (isArray) {\n const existingItems = Array.isArray(this.runInputData[inputId])\n ? this.runInputData[inputId]\n : [this.runInputData[inputId]];\n const newitems = [...existingItems];\n\n const overrideItem = overrides[inputId];\n if (Array.isArray(overrideItem)) {\n newitems.push(...overrideItem);\n } else {\n newitems.push(overrideItem);\n }\n this.runInputData[inputId] = newitems;\n changed = true;\n } else {\n if (!deepEqual(this.runInputData[inputId], overrides[inputId])) {\n this.runInputData[inputId] = overrides[inputId];\n changed = true;\n }\n }\n }\n }\n\n // If additionalProperties is true, also accept any additional input properties\n if (inputSchema.additionalProperties === true) {\n for (const [inputId, value] of Object.entries(overrides)) {\n if (!(inputId in properties)) {\n if (!deepEqual(this.runInputData[inputId], value)) {\n this.runInputData[inputId] = value;\n changed = true;\n }\n }\n }\n }\n\n return changed;\n }\n\n /**\n * Stub for narrowing input. Override in subclasses for custom logic.\n * @param input The input to narrow\n * @param _registry Optional service registry for lookups\n * @returns The (possibly narrowed) input\n */\n public async narrowInput(\n input: Record<string, any>,\n _registry: ServiceRegistry\n ): Promise<Record<string, any>> {\n return input;\n }\n\n // ========================================================================\n // Event handling methods\n // ========================================================================\n\n /**\n * Subscribes to an event\n */\n public subscribe<Event extends TaskEvents>(\n name: Event,\n fn: TaskEventListener<Event>\n ): () => void {\n return this.events.subscribe(name, fn);\n }\n\n /**\n * Registers an event listener\n */\n public on<Event extends TaskEvents>(name: Event, fn: TaskEventListener<Event>): void {\n this.events.on(name, fn);\n }\n\n /**\n * Removes an event listener\n */\n public off<Event extends TaskEvents>(name: Event, fn: TaskEventListener<Event>): void {\n this.events.off(name, fn);\n }\n\n /**\n * Registers a one-time event listener\n */\n public once<Event extends TaskEvents>(name: Event, fn: TaskEventListener<Event>): void {\n this.events.once(name, fn);\n }\n\n /**\n * Returns a promise that resolves when the specified event is emitted\n */\n public waitOn<Event extends TaskEvents>(name: Event): Promise<TaskEventParameters<Event>> {\n return this.events.waitOn(name) as Promise<TaskEventParameters<Event>>;\n }\n\n /**\n * Emits an event\n */\n public emit<Event extends TaskEvents>(name: Event, ...args: TaskEventParameters<Event>): void {\n // this one is not like the others. Listeners will cause a lazy load of the event emitter.\n // but no need to emit if no one is listening, so we don't want to create the event emitter if not needed\n this._events?.emit(name, ...args);\n }\n\n /**\n * Emits a schemaChange event when the task's input or output schema changes.\n * This should be called by tasks with dynamic schemas when their configuration\n * changes in a way that affects their schemas.\n *\n * @param inputSchema - The new input schema (optional, will use current schema if not provided)\n * @param outputSchema - The new output schema (optional, will use current schema if not provided)\n */\n protected emitSchemaChange(inputSchema?: DataPortSchema, outputSchema?: DataPortSchema): void {\n const finalInputSchema = inputSchema ?? this.inputSchema();\n const finalOutputSchema = outputSchema ?? this.outputSchema();\n this.emit(\"schemaChange\", finalInputSchema, finalOutputSchema);\n }\n\n // ========================================================================\n // Input validation methods\n // ========================================================================\n\n /**\n * The compiled input schema\n */\n private static _inputSchemaNode: Map<string, SchemaNode> = new Map();\n\n protected static generateInputSchemaNode(schema: DataPortSchema) {\n if (typeof schema === \"boolean\") {\n if (schema === false) {\n return compileSchema({ not: {} });\n }\n return compileSchema({});\n }\n return compileSchema(schema);\n }\n\n /**\n * Gets the compiled input schema\n */\n protected static getInputSchemaNode(type: TaskTypeName): SchemaNode {\n if (!this._inputSchemaNode.has(type)) {\n const dataPortSchema = this.inputSchema();\n const schemaNode = this.generateInputSchemaNode(dataPortSchema);\n try {\n this._inputSchemaNode.set(type, schemaNode);\n } catch (error) {\n // If compilation fails, fall back to accepting any object structure\n // This is a safety net for schemas that json-schema-library can't compile\n console.warn(\n `Failed to compile input schema for ${this.type}, falling back to permissive validation:`,\n error\n );\n this._inputSchemaNode.set(type, compileSchema({}));\n }\n }\n return this._inputSchemaNode.get(type)!;\n }\n\n protected getInputSchemaNode(type: TaskTypeName): SchemaNode {\n return (this.constructor as typeof Task).getInputSchemaNode(type);\n }\n\n /**\n * Validates an input data object against the task's input schema\n */\n public async validateInput(input: Partial<Input>): Promise<boolean> {\n const schemaNode = this.getInputSchemaNode(this.type);\n const result = schemaNode.validate(input);\n\n if (!result.valid) {\n const errorMessages = result.errors.map((e) => {\n const path = e.data.pointer || \"\";\n return `${e.message}${path ? ` (${path})` : \"\"}`;\n });\n throw new TaskInvalidInputError(\n `Input ${JSON.stringify(Object.keys(input))} does not match schema: ${errorMessages.join(\", \")}`\n );\n }\n\n return true;\n }\n\n /**\n * Gets the task ID from the config\n */\n public id(): unknown {\n return this.config.id;\n }\n\n // ========================================================================\n // Serialization methods\n // ========================================================================\n\n /**\n * Strips symbol properties from an object to make it serializable\n * @param obj The object to strip symbols from\n * @returns A new object without symbol properties\n */\n private stripSymbols(obj: any): any {\n if (obj === null || obj === undefined) {\n return obj;\n }\n // Preserve TypedArrays (Float32Array, Int8Array, etc.)\n if (ArrayBuffer.isView(obj)) {\n return obj;\n }\n if (Array.isArray(obj)) {\n return obj.map((item) => this.stripSymbols(item));\n }\n if (typeof obj === \"object\") {\n const result: Record<string, any> = {};\n for (const key in obj) {\n if (Object.prototype.hasOwnProperty.call(obj, key)) {\n result[key] = this.stripSymbols(obj[key]);\n }\n }\n return result;\n }\n return obj;\n }\n\n /**\n * Serializes the task and its subtasks into a format that can be stored\n * @returns The serialized task and subtasks\n */\n public toJSON(): TaskGraphItemJson {\n const extras = this.config.extras;\n let json: TaskGraphItemJson = this.stripSymbols({\n id: this.config.id,\n type: this.type,\n ...(this.config.name ? { name: this.config.name } : {}),\n defaults: this.defaults,\n ...(extras && Object.keys(extras).length ? { extras } : {}),\n });\n return json as TaskGraphItemJson;\n }\n\n /**\n * Converts the task to a JSON format suitable for dependency tracking\n * @returns The task and subtasks in JSON thats easier for humans to read\n */\n public toDependencyJSON(): JsonTaskItem {\n const json = this.toJSON();\n return json;\n }\n\n // ========================================================================\n // Internal graph methods\n // ========================================================================\n\n /**\n * Checks if the task has children. Useful to gate to use of the internal subGraph\n * as this will return without creating a new graph if graph is non-existent .\n *\n * @returns True if the task has children, otherwise false\n */\n public hasChildren(): boolean {\n return (\n this._subGraph !== undefined &&\n this._subGraph !== null &&\n this._subGraph.getTasks().length > 0\n );\n }\n\n private _taskAddedListener: (taskId: TaskIdType) => void = () => {\n this.emit(\"regenerate\");\n };\n\n /**\n * The internal task graph containing subtasks\n *\n * In the base case, these may just be incidental tasks that are not part of the task graph\n * but are used to manage the task's state as part of task execution. Therefore, the graph\n * is not used by the default runner.\n */\n protected _subGraph: TaskGraph | undefined = undefined;\n\n /**\n * Sets the subtask graph for the compound task\n * @param subGraph The subtask graph to set\n */\n set subGraph(subGraph: TaskGraph) {\n if (this._subGraph) {\n this._subGraph.off(\"task_added\", this._taskAddedListener);\n }\n this._subGraph = subGraph;\n this._subGraph.on(\"task_added\", this._taskAddedListener);\n }\n\n /**\n * The internal task graph containing subtasks\n *\n * In the base case, these may just be incidental tasks that are not part of the task graph\n * but are used to manage the task's state as part of task execution. Therefore, the graph\n * is not used by the default runner.\n *\n * Creates a new graph if one doesn't exist.\n *\n * @returns The task graph\n */\n get subGraph(): TaskGraph {\n if (!this._subGraph) {\n this._subGraph = new TaskGraph();\n this._subGraph.on(\"task_added\", this._taskAddedListener);\n }\n return this._subGraph;\n }\n\n /**\n * Regenerates the task graph, which is internal state to execute() with config.own()\n *\n * This is a destructive operation that removes all dataflows and tasks from the graph.\n * It is used to reset the graph to a clean state.\n *\n * GraphAsTask and others override this and do not call super\n */\n public regenerateGraph(): void {\n if (this.hasChildren()) {\n for (const dataflow of this.subGraph.getDataflows()) {\n this.subGraph.removeDataflow(dataflow);\n }\n for (const child of this.subGraph.getTasks()) {\n this.subGraph.removeTask(child.config.id);\n }\n }\n this.events.emit(\"regenerate\");\n }\n}\n",
13
12
  "/**\n * @license\n * Copyright 2025 Steven Roussey <sroussey@gmail.com>\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport { JobError } from \"@workglow/job-queue\";\nimport { BaseError } from \"@workglow/util\";\n\nexport class TaskError extends BaseError {\n static readonly type: string = \"TaskError\";\n constructor(message: string) {\n super(message);\n }\n}\n\n/**\n * A task configuration error\n *\n */\nexport class TaskConfigurationError extends TaskError {\n static readonly type: string = \"TaskConfigurationError\";\n constructor(message: string) {\n super(message);\n }\n}\n\n/**\n * A task workflow error\n */\nexport class WorkflowError extends TaskError {\n static readonly type: string = \"WorkflowError\";\n constructor(message: string) {\n super(message);\n }\n}\n\n/**\n * A task error that is caused by a task being aborted\n *\n * Examples: task.abort() was called, or some other reason an abort signal was received\n */\nexport class TaskAbortedError extends TaskError {\n static readonly type: string = \"TaskAbortedError\";\n constructor(message: string = \"Task aborted\") {\n super(message);\n }\n}\n\n/**\n * A task error that is caused by a task failing\n *\n * Examples: task.run() threw an error\n */\nexport class TaskFailedError extends TaskError {\n static readonly type: string = \"TaskFailedError\";\n constructor(message: string = \"Task failed\") {\n super(message);\n }\n}\n\nexport class JobTaskFailedError extends TaskFailedError {\n static readonly type: string = \"JobTaskFailedError\";\n public jobError: JobError;\n constructor(err: JobError) {\n super(String(err));\n this.jobError = err;\n }\n}\n\n/**\n * A task error that is caused by an error converting JSON to a Task\n */\nexport class TaskJSONError extends TaskError {\n static readonly type: string = \"TaskJSONError\";\n constructor(message: string = \"Error converting JSON to a Task\") {\n super(message);\n }\n}\n\n/**\n * A task error that is caused by invalid input data\n *\n * Examples: task.run() received invalid input data\n */\nexport class TaskInvalidInputError extends TaskError {\n static readonly type: string = \"TaskInvalidInputError\";\n constructor(message: string = \"Invalid input data\") {\n super(message);\n }\n}\n",
@@ -15,28 +14,21 @@
15
14
  "/**\n * @license\n * Copyright 2025 Steven Roussey <sroussey@gmail.com>\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport type { DataPortSchema, ServiceRegistry } from \"@workglow/util\";\nimport { getInputResolvers } from \"@workglow/util\";\n\n/**\n * Configuration for the input resolver\n */\nexport interface InputResolverConfig {\n readonly registry: ServiceRegistry;\n}\n\n/**\n * Extracts the format string from a schema, handling oneOf/anyOf wrappers.\n */\nfunction getSchemaFormat(schema: unknown): string | undefined {\n if (typeof schema !== \"object\" || schema === null) return undefined;\n\n const s = schema as Record<string, unknown>;\n\n // Direct format\n if (typeof s.format === \"string\") return s.format;\n\n // Check oneOf/anyOf for format\n const variants = (s.oneOf ?? s.anyOf) as unknown[] | undefined;\n if (Array.isArray(variants)) {\n for (const variant of variants) {\n if (typeof variant === \"object\" && variant !== null) {\n const v = variant as Record<string, unknown>;\n if (typeof v.format === \"string\") return v.format;\n }\n }\n }\n\n return undefined;\n}\n\n/**\n * Gets the format prefix from a format string.\n * For \"model:TextEmbedding\" returns \"model\"\n * For \"storage:tabular\" returns \"storage\"\n */\nfunction getFormatPrefix(format: string): string {\n const colonIndex = format.indexOf(\":\");\n return colonIndex >= 0 ? format.substring(0, colonIndex) : format;\n}\n\n/**\n * Resolves schema-annotated inputs by looking up string IDs from registries.\n * String values with matching format annotations are resolved to their instances.\n * Non-string values (objects/instances) are passed through unchanged.\n *\n * @param input The task input object\n * @param schema The task's input schema\n * @param config Configuration including the service registry\n * @returns The input with resolved values\n *\n * @example\n * ```typescript\n * // In TaskRunner.run()\n * const resolvedInput = await resolveSchemaInputs(\n * this.task.runInputData,\n * (this.task.constructor as typeof Task).inputSchema(),\n * { registry: this.registry }\n * );\n * ```\n */\nexport async function resolveSchemaInputs<T extends Record<string, unknown>>(\n input: T,\n schema: DataPortSchema,\n config: InputResolverConfig\n): Promise<T> {\n if (typeof schema === \"boolean\") return input;\n\n const properties = schema.properties;\n if (!properties || typeof properties !== \"object\") return input;\n\n const resolvers = getInputResolvers();\n const resolved: Record<string, unknown> = { ...input };\n\n for (const [key, propSchema] of Object.entries(properties)) {\n const value = resolved[key];\n\n const format = getSchemaFormat(propSchema);\n if (!format) continue;\n\n // Try full format first (e.g., \"dataset:document-chunk\"), then fall back to prefix (e.g., \"dataset\")\n let resolver = resolvers.get(format);\n if (!resolver) {\n const prefix = getFormatPrefix(format);\n resolver = resolvers.get(prefix);\n }\n\n if (!resolver) continue;\n\n // Handle string values\n if (typeof value === \"string\") {\n resolved[key] = await resolver(value, format, config.registry);\n }\n // Handle arrays of strings - iterate and resolve each element\n else if (Array.isArray(value) && value.every((item) => typeof item === \"string\")) {\n const results = await Promise.all(\n (value as string[]).map((item) => resolver(item, format, config.registry))\n );\n resolved[key] = results.filter((result) => result !== undefined);\n }\n // Skip if not a string or array of strings (already resolved or direct instance)\n }\n\n return resolved as T;\n}\n",
16
15
  "/**\n * @license\n * Copyright 2025 Steven Roussey <sroussey@gmail.com>\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport type { DataPortSchema } from \"@workglow/util\";\nimport type { IExecuteContext } from \"./ITask\";\nimport { Task } from \"./Task\";\nimport type { TaskConfig, TaskInput, TaskOutput, TaskTypeName } from \"./TaskTypes\";\n\n// ============================================================================\n// Types and Interfaces\n// ============================================================================\n\n/**\n * A predicate function that evaluates whether a branch condition is met.\n * Receives the task's input data and returns true if the branch should be active.\n *\n * @template Input - The input type for the conditional task\n * @param input - The input data to evaluate\n * @returns true if the branch condition is met, false otherwise\n *\n * @example\n * ```typescript\n * // Simple numeric comparison\n * const isHighValue: ConditionFn<{ value: number }> = (input) => input.value > 100;\n *\n * // String equality check\n * const isAdmin: ConditionFn<{ role: string }> = (input) => input.role === \"admin\";\n *\n * // Complex boolean logic\n * const isEligible: ConditionFn<{ age: number; verified: boolean }> = (input) =>\n * input.age >= 18 && input.verified;\n * ```\n */\nexport type ConditionFn<Input> = (input: Input) => boolean;\n\n/**\n * Configuration for a single branch in a ConditionalTask.\n *\n * Each branch represents a possible path through the conditional logic.\n * When the condition evaluates to true, the branch becomes active and\n * its output port will receive the task's input data.\n *\n * @template Input - The input type for the conditional task\n *\n * @example\n * ```typescript\n * const highValueBranch: BranchConfig<{ amount: number }> = {\n * id: \"high\",\n * condition: (input) => input.amount > 1000,\n * outputPort: \"highValue\"\n * };\n * ```\n */\nexport interface BranchConfig<Input> {\n /** Unique identifier for this branch within the task */\n readonly id: string;\n\n /** Predicate function that determines if this branch is active */\n readonly condition: ConditionFn<Input>;\n\n /** Name of the output port that will receive data when this branch is active */\n readonly outputPort: string;\n}\n\n/**\n * Configuration interface for ConditionalTask.\n *\n * Extends the base TaskConfig with conditional-specific options including\n * branch definitions, default branch handling, and execution mode.\n *\n * @example\n * ```typescript\n * const config: ConditionalTaskConfig = {\n * id: \"router\",\n * branches: [\n * { id: \"premium\", condition: (i) => i.tier === \"premium\", outputPort: \"premium\" },\n * { id: \"standard\", condition: (i) => i.tier === \"standard\", outputPort: \"standard\" },\n * ],\n * defaultBranch: \"standard\",\n * exclusive: true, // Only first matching branch activates\n * };\n * ```\n */\nexport interface ConditionalTaskConfig extends TaskConfig {\n /**\n * Array of branch configurations defining the conditional logic.\n * Branches are evaluated in order. In exclusive mode, only the first\n * matching branch activates. In non-exclusive mode, all matching\n * branches activate.\n */\n readonly branches: BranchConfig<any>[];\n\n /**\n * ID of the branch to activate if no conditions match.\n * Must correspond to an existing branch ID. If not specified\n * and no conditions match, no branches will be active.\n */\n readonly defaultBranch?: string;\n\n /**\n * When true (default), only the first matching branch activates (switch/case behavior).\n * When false, all matching branches activate (multi-path routing).\n *\n * @default true\n */\n readonly exclusive?: boolean;\n}\n\n// ============================================================================\n// ConditionalTask Class\n// ============================================================================\n\n/**\n * A task that evaluates conditions to determine which downstream paths are active.\n *\n * ConditionalTask implements conditional branching within a task graph, similar to\n * if/then/else or switch/case statements. It evaluates configured conditions against\n * its input and selectively enables output ports for active branches while disabling\n * dataflows to inactive branches.\n *\n * ## Key Features\n *\n * - **Condition-based routing**: Route data to different downstream tasks based on input values\n * - **Exclusive mode**: Act as a switch/case where only the first matching branch activates\n * - **Multi-path mode**: Enable multiple branches simultaneously when conditions match\n * - **Default branch**: Specify a fallback branch when no conditions match\n * - **Disabled propagation**: Inactive branches result in DISABLED status for downstream tasks\n *\n * ## Execution Modes\n *\n * ### Exclusive Mode (default)\n * In exclusive mode (`exclusive: true`), the task behaves like a switch statement.\n * Branches are evaluated in order, and only the first matching branch becomes active.\n * This is useful for mutually exclusive paths.\n *\n * ### Multi-Path Mode\n * In multi-path mode (`exclusive: false`), all branches whose conditions evaluate\n * to true become active simultaneously. This enables fan-out patterns where the\n * same input triggers multiple downstream processing paths.\n *\n * ## Output Behavior\n *\n * For each active branch, the task passes through its entire input to that branch's\n * output port. Inactive branches receive no data, and their outgoing dataflows are\n * set to DISABLED status, which cascades to downstream tasks that have no other\n * active inputs.\n *\n * @template Input - The input type for the task\n * @template Output - The output type for the task\n * @template Config - The configuration type (must extend ConditionalTaskConfig)\n *\n * @example\n * ```typescript\n * // Simple if/else routing based on a numeric threshold\n * const thresholdRouter = new ConditionalTask(\n * {},\n * {\n * branches: [\n * { id: \"high\", condition: (i) => i.value > 100, outputPort: \"highPath\" },\n * { id: \"low\", condition: (i) => i.value <= 100, outputPort: \"lowPath\" },\n * ],\n * }\n * );\n *\n * // Switch/case style routing based on string enum\n * const statusRouter = new ConditionalTask(\n * {},\n * {\n * branches: [\n * { id: \"active\", condition: (i) => i.status === \"active\", outputPort: \"active\" },\n * { id: \"pending\", condition: (i) => i.status === \"pending\", outputPort: \"pending\" },\n * { id: \"inactive\", condition: (i) => i.status === \"inactive\", outputPort: \"inactive\" },\n * ],\n * defaultBranch: \"inactive\",\n * exclusive: true,\n * }\n * );\n *\n * // Multi-path fan-out for parallel processing\n * const fanOut = new ConditionalTask(\n * {},\n * {\n * branches: [\n * { id: \"log\", condition: () => true, outputPort: \"logger\" },\n * { id: \"process\", condition: () => true, outputPort: \"processor\" },\n * { id: \"archive\", condition: (i) => i.shouldArchive, outputPort: \"archiver\" },\n * ],\n * exclusive: false, // All matching branches activate\n * }\n * );\n * ```\n */\nexport class ConditionalTask<\n Input extends TaskInput = TaskInput,\n Output extends TaskOutput = TaskOutput,\n Config extends ConditionalTaskConfig = ConditionalTaskConfig,\n> extends Task<Input, Output, Config> {\n /** Task type identifier for serialization and registry lookup */\n static type: TaskTypeName = \"ConditionalTask\";\n\n /** Category for UI organization and filtering */\n static category = \"Hidden\";\n\n /** Human-readable title for display in UIs */\n static title = \"Conditional Task\";\n static description = \"Evaluates conditions to determine which dataflows are active\";\n\n /** This task has dynamic schemas that change based on branch configuration */\n static hasDynamicSchemas: boolean = true;\n\n /**\n * Set of branch IDs that are currently active after execution.\n * Populated during execute() and used by the graph runner to\n * determine which dataflows should be enabled vs disabled.\n */\n public activeBranches: Set<string> = new Set();\n\n // ========================================================================\n // Execution methods\n // ========================================================================\n\n /**\n * Evaluates branch conditions and determines which branches are active.\n * Only active branches will have their output ports populated.\n *\n * @param input - The input data to evaluate conditions against\n * @param context - Execution context with signal and progress callback\n * @returns Output with active branch data and metadata\n */\n public async execute(input: Input, context: IExecuteContext): Promise<Output | undefined> {\n if (context.signal?.aborted) {\n return undefined;\n }\n\n // Clear previous branch activation state\n this.activeBranches.clear();\n\n const branches = this.config.branches ?? [];\n const isExclusive = this.config.exclusive ?? true;\n\n // Evaluate each branch condition\n for (const branch of branches) {\n try {\n const isActive = branch.condition(input);\n if (isActive) {\n this.activeBranches.add(branch.id);\n if (isExclusive) {\n // In exclusive mode, stop at first match\n break;\n }\n }\n } catch (error) {\n // If condition throws, treat it as false (branch not taken)\n console.warn(`Condition evaluation failed for branch \"${branch.id}\":`, error);\n }\n }\n\n // If no branch matched and there's a default, use it\n if (this.activeBranches.size === 0 && this.config.defaultBranch) {\n const defaultBranchExists = branches.some((b) => b.id === this.config.defaultBranch);\n if (defaultBranchExists) {\n this.activeBranches.add(this.config.defaultBranch);\n }\n }\n\n // Build output: pass through input to active branch ports\n return this.buildOutput(input);\n }\n\n /**\n * Builds the output object with data routed to active branch ports.\n * Each active branch's output port receives the full input data.\n *\n * @param input - The input data to pass through to active branches\n * @returns Output object with active branch ports populated\n */\n protected buildOutput(input: Input): Output {\n const output: Record<string, unknown> = {\n _activeBranches: Array.from(this.activeBranches),\n };\n\n const branches = this.config.branches ?? [];\n\n // For each active branch, populate its output port with the input data\n for (const branch of branches) {\n if (this.activeBranches.has(branch.id)) {\n // Pass through all input properties to the active branch's output port\n output[branch.outputPort] = { ...input };\n }\n }\n\n return output as Output;\n }\n\n // ========================================================================\n // Branch information methods\n // ========================================================================\n\n /**\n * Checks if a specific branch is currently active.\n *\n * @param branchId - The ID of the branch to check\n * @returns true if the branch is active, false otherwise\n *\n * @example\n * ```typescript\n * await conditionalTask.run({ value: 150 });\n * if (conditionalTask.isBranchActive(\"high\")) {\n * console.log(\"High value path was taken\");\n * }\n * ```\n */\n public isBranchActive(branchId: string): boolean {\n return this.activeBranches.has(branchId);\n }\n\n /**\n * Gets the set of currently active branch IDs.\n * Returns a new Set to prevent external modification.\n *\n * @returns Set of active branch IDs\n */\n public getActiveBranches(): Set<string> {\n return new Set(this.activeBranches);\n }\n\n /**\n * Gets a map of output port names to their active status.\n * Useful for inspecting which output ports will have data.\n *\n * @returns Map of output port name to boolean active status\n *\n * @example\n * ```typescript\n * const portStatus = conditionalTask.getPortActiveStatus();\n * for (const [port, isActive] of portStatus) {\n * console.log(`Port ${port}: ${isActive ? \"active\" : \"inactive\"}`);\n * }\n * ```\n */\n public getPortActiveStatus(): Map<string, boolean> {\n const status = new Map<string, boolean>();\n const branches = this.config.branches ?? [];\n\n for (const branch of branches) {\n status.set(branch.outputPort, this.activeBranches.has(branch.id));\n }\n\n return status;\n }\n\n // ========================================================================\n // Schema methods\n // ========================================================================\n\n /**\n * Generates the output schema dynamically based on configured branches.\n * Each branch's output port is defined as an object type that will\n * receive the pass-through input data when active.\n *\n * @returns JSON Schema for the task's output\n */\n static outputSchema(): DataPortSchema {\n // Base schema - actual properties are determined by branch configuration\n return {\n type: \"object\",\n properties: {\n _activeBranches: {\n type: \"array\",\n items: { type: \"string\" },\n description: \"List of active branch IDs after condition evaluation\",\n },\n },\n additionalProperties: true,\n } as const satisfies DataPortSchema;\n }\n\n /**\n * Instance method to get output schema with branch-specific ports.\n * Dynamically generates properties based on the configured branches.\n *\n * @returns JSON Schema for the task's output including branch ports\n */\n outputSchema(): DataPortSchema {\n const branches = this.config?.branches ?? [];\n const properties: Record<string, any> = {\n _activeBranches: {\n type: \"array\",\n items: { type: \"string\" },\n description: \"List of active branch IDs after condition evaluation\",\n },\n };\n\n // Add each branch's output port to the schema\n for (const branch of branches) {\n properties[branch.outputPort] = {\n type: \"object\",\n description: `Output for branch \"${branch.id}\" when active`,\n additionalProperties: true,\n };\n }\n\n return {\n type: \"object\",\n properties,\n additionalProperties: false,\n } as DataPortSchema;\n }\n\n /**\n * Returns schema indicating the task accepts any input.\n * ConditionalTask passes through its input to active branches,\n * so it doesn't constrain the input type.\n *\n * @returns Schema that accepts any input\n */\n static inputSchema(): DataPortSchema {\n return {\n type: \"object\",\n properties: {},\n additionalProperties: true,\n } as const satisfies DataPortSchema;\n }\n\n /**\n * Instance method returning schema that accepts any input.\n *\n * @returns Schema that accepts any input\n */\n inputSchema(): DataPortSchema {\n return {\n type: \"object\",\n properties: {},\n additionalProperties: true,\n } as const satisfies DataPortSchema;\n }\n}\n",
17
16
  "/**\n * @license\n * Copyright 2025 Steven Roussey <sroussey@gmail.com>\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport { ITask } from \"../task/ITask\";\nimport { TaskStatus } from \"../task/TaskTypes\";\nimport { TaskGraph } from \"./TaskGraph\";\n\n/**\n * Interface for task graph schedulers\n */\nexport interface ITaskGraphScheduler {\n /**\n * Gets an async iterator of tasks that can be executed\n * @returns AsyncIterator of tasks that resolves to each task when it's ready\n */\n tasks(): AsyncIterableIterator<ITask>;\n\n /**\n * Notifies the scheduler that a task has completed\n * @param taskId The ID of the completed task\n */\n onTaskCompleted(taskId: unknown): void;\n\n /**\n * Resets the scheduler state\n */\n reset(): void;\n}\n\n/**\n * Sequential scheduler that executes one task at a time in topological order\n * Useful for debugging and understanding task execution flow\n */\nexport class TopologicalScheduler implements ITaskGraphScheduler {\n private sortedNodes: ITask[];\n private currentIndex: number;\n\n constructor(private dag: TaskGraph) {\n this.sortedNodes = [];\n this.currentIndex = 0;\n this.reset();\n }\n\n async *tasks(): AsyncIterableIterator<ITask> {\n while (this.currentIndex < this.sortedNodes.length) {\n yield this.sortedNodes[this.currentIndex++];\n }\n }\n\n onTaskCompleted(taskId: unknown): void {\n // Topological scheduler doesn't need to track individual task completion\n }\n\n reset(): void {\n this.sortedNodes = this.dag.topologicallySortedNodes();\n this.currentIndex = 0;\n }\n}\n\n/**\n * Event-driven scheduler that executes tasks as soon as their dependencies are satisfied\n * Most efficient for parallel execution but requires completion notifications\n */\nexport class DependencyBasedScheduler implements ITaskGraphScheduler {\n private completedTasks: Set<unknown>;\n private pendingTasks: Set<ITask>;\n private nextResolver: ((task: ITask | null) => void) | null = null;\n\n constructor(private dag: TaskGraph) {\n this.completedTasks = new Set();\n this.pendingTasks = new Set();\n this.reset();\n }\n\n private isTaskReady(task: ITask): boolean {\n // DISABLED tasks are never ready - they should be skipped\n if (task.status === TaskStatus.DISABLED) {\n return false;\n }\n\n const sourceDataflows = this.dag.getSourceDataflows(task.config.id);\n\n // If task has incoming dataflows, check if all are DISABLED\n // (In that case, task will be disabled by propagateDisabledStatus, not ready to run)\n if (sourceDataflows.length > 0) {\n const allIncomingDisabled = sourceDataflows.every(\n (df) => df.status === TaskStatus.DISABLED\n );\n if (allIncomingDisabled) {\n return false;\n }\n }\n\n // A task is ready if all its non-disabled dependencies are completed\n // DISABLED dataflows are considered \"satisfied\" (their branch was not taken)\n const dependencies = sourceDataflows\n .filter((df) => df.status !== TaskStatus.DISABLED)\n .map((dataflow) => dataflow.sourceTaskId);\n\n return dependencies.every((dep) => this.completedTasks.has(dep));\n }\n\n private async waitForNextTask(): Promise<ITask | null> {\n if (this.pendingTasks.size === 0) return null;\n\n // Remove any disabled tasks from pending (they were disabled by propagateDisabledStatus)\n for (const task of Array.from(this.pendingTasks)) {\n if (task.status === TaskStatus.DISABLED) {\n this.pendingTasks.delete(task);\n }\n }\n\n if (this.pendingTasks.size === 0) return null;\n\n const readyTask = Array.from(this.pendingTasks).find((task) => this.isTaskReady(task));\n if (readyTask) {\n this.pendingTasks.delete(readyTask);\n return readyTask;\n }\n\n // If there are pending tasks but none are ready, wait for task completion\n if (this.pendingTasks.size > 0) {\n return new Promise((resolve) => {\n this.nextResolver = resolve;\n });\n }\n\n return null;\n }\n\n async *tasks(): AsyncIterableIterator<ITask> {\n while (this.pendingTasks.size > 0) {\n const task = await this.waitForNextTask();\n if (task) {\n yield task;\n } else {\n break;\n }\n }\n }\n\n onTaskCompleted(taskId: unknown): void {\n this.completedTasks.add(taskId);\n\n // Remove any disabled tasks from pending\n for (const task of Array.from(this.pendingTasks)) {\n if (task.status === TaskStatus.DISABLED) {\n this.pendingTasks.delete(task);\n }\n }\n\n // Check if any pending tasks are now ready\n if (this.nextResolver) {\n const readyTask = Array.from(this.pendingTasks).find((task) => this.isTaskReady(task));\n if (readyTask) {\n this.pendingTasks.delete(readyTask);\n const resolver = this.nextResolver;\n this.nextResolver = null;\n resolver(readyTask);\n } else if (this.pendingTasks.size === 0) {\n // No more pending tasks - resolve with null to signal completion\n const resolver = this.nextResolver;\n this.nextResolver = null;\n resolver(null);\n }\n }\n }\n\n reset(): void {\n this.completedTasks.clear();\n this.pendingTasks = new Set(this.dag.topologicallySortedNodes());\n this.nextResolver = null;\n }\n}\n",
18
- "/**\n * @license\n * Copyright 2025 Steven Roussey <sroussey@gmail.com>\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport { GraphResultArray } from \"../task-graph/TaskGraphRunner\";\nimport { GraphAsTask } from \"./GraphAsTask\";\nimport { TaskRunner } from \"./TaskRunner\";\nimport { TaskConfig, TaskInput, TaskOutput } from \"./TaskTypes\";\n\nexport class GraphAsTaskRunner<\n Input extends TaskInput = TaskInput,\n Output extends TaskOutput = TaskOutput,\n Config extends TaskConfig = TaskConfig,\n> extends TaskRunner<Input, Output, Config> {\n declare task: GraphAsTask<Input, Output, Config>;\n\n /**\n * Protected method to execute a task subgraph by delegating back to the task itself.\n */\n protected async executeTaskChildren(input: Input): Promise<GraphResultArray<Output>> {\n const unsubscribe = this.task.subGraph!.subscribe(\n \"graph_progress\",\n (progress: number, message?: string, ...args: any[]) => {\n this.task.emit(\"progress\", progress, message, ...args);\n }\n );\n const results = await this.task.subGraph!.run<Output>(input, {\n parentSignal: this.abortController?.signal,\n outputCache: this.outputCache,\n });\n unsubscribe();\n return results;\n }\n /**\n * Protected method for reactive execution delegation\n *\n * Note: Reactive execution doesn't accept input parameters by design.\n * It works with the graph's internal state and dataflow connections.\n * Tasks in the subgraph will use their existing runInputData (from defaults\n * or previous execution) combined with dataflow connections.\n */\n protected async executeTaskChildrenReactive(): Promise<GraphResultArray<Output>> {\n return this.task.subGraph!.runReactive<Output>();\n }\n\n protected async handleDisable(): Promise<void> {\n if (this.task.hasChildren()) {\n await this.task.subGraph!.disable();\n }\n super.handleDisable();\n }\n\n // ========================================================================\n // TaskRunner method overrides and helpers\n // ========================================================================\n\n /**\n * Execute the task\n */\n protected async executeTask(input: Input): Promise<Output | undefined> {\n if (this.task.hasChildren()) {\n const runExecuteOutputData = await this.executeTaskChildren(input);\n this.task.runOutputData = this.task.subGraph.mergeExecuteOutputsToRunOutput(\n runExecuteOutputData,\n this.task.compoundMerge\n );\n } else {\n const result = await super.executeTask(input);\n this.task.runOutputData = result ?? ({} as Output);\n }\n return this.task.runOutputData as Output;\n }\n\n /**\n * Execute the task reactively\n */\n public async executeTaskReactive(input: Input, output: Output): Promise<Output> {\n if (this.task.hasChildren()) {\n const reactiveResults = await this.executeTaskChildrenReactive();\n this.task.runOutputData = this.task.subGraph.mergeExecuteOutputsToRunOutput(\n reactiveResults,\n this.task.compoundMerge\n );\n } else {\n const reactiveResults = await super.executeTaskReactive(input, output);\n this.task.runOutputData = Object.assign({}, output, reactiveResults ?? {}) as Output;\n }\n return this.task.runOutputData as Output;\n }\n}\n",
17
+ "/**\n * @license\n * Copyright 2025 Steven Roussey <sroussey@gmail.com>\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport { GraphResultArray } from \"../task-graph/TaskGraphRunner\";\nimport { GraphAsTask } from \"./GraphAsTask\";\nimport { TaskRunner } from \"./TaskRunner\";\nimport { TaskConfig, TaskInput, TaskOutput } from \"./TaskTypes\";\n\nexport class GraphAsTaskRunner<\n Input extends TaskInput = TaskInput,\n Output extends TaskOutput = TaskOutput,\n Config extends TaskConfig = TaskConfig,\n> extends TaskRunner<Input, Output, Config> {\n declare task: GraphAsTask<Input, Output, Config>;\n\n /**\n * Protected method to execute a task subgraph by delegating back to the task itself.\n */\n protected async executeTaskChildren(input: Input): Promise<GraphResultArray<Output>> {\n const unsubscribe = this.task.subGraph!.subscribe(\n \"graph_progress\",\n (progress: number, message?: string, ...args: any[]) => {\n this.task.emit(\"progress\", progress, message, ...args);\n }\n );\n const results = await this.task.subGraph!.run<Output>(input, {\n parentSignal: this.abortController?.signal,\n outputCache: this.outputCache,\n });\n unsubscribe();\n return results;\n }\n /**\n * Protected method for reactive execution delegation\n *\n * For GraphAsTask, we pass the parent's runInputData to the subgraph's runReactive.\n * This ensures that root tasks in the subgraph (like InputTask) receive the\n * parent's input values after resetInputData() is called.\n */\n protected async executeTaskChildrenReactive(): Promise<GraphResultArray<Output>> {\n return this.task.subGraph!.runReactive<Output>(this.task.runInputData);\n }\n\n protected async handleDisable(): Promise<void> {\n if (this.task.hasChildren()) {\n await this.task.subGraph!.disable();\n }\n super.handleDisable();\n }\n\n // ========================================================================\n // TaskRunner method overrides and helpers\n // ========================================================================\n\n /**\n * Execute the task\n */\n protected async executeTask(input: Input): Promise<Output | undefined> {\n if (this.task.hasChildren()) {\n const runExecuteOutputData = await this.executeTaskChildren(input);\n this.task.runOutputData = this.task.subGraph.mergeExecuteOutputsToRunOutput(\n runExecuteOutputData,\n this.task.compoundMerge\n );\n } else {\n const result = await super.executeTask(input);\n this.task.runOutputData = result ?? ({} as Output);\n }\n return this.task.runOutputData as Output;\n }\n\n /**\n * Execute the task reactively\n */\n public async executeTaskReactive(input: Input, output: Output): Promise<Output> {\n if (this.task.hasChildren()) {\n const reactiveResults = await this.executeTaskChildrenReactive();\n this.task.runOutputData = this.task.subGraph.mergeExecuteOutputsToRunOutput(\n reactiveResults,\n this.task.compoundMerge\n );\n } else {\n const reactiveResults = await super.executeTaskReactive(input, output);\n this.task.runOutputData = Object.assign({}, output, reactiveResults ?? {}) as Output;\n }\n return this.task.runOutputData as Output;\n }\n}\n",
18
+ "/**\n * @license\n * Copyright 2025 Steven Roussey <sroussey@gmail.com>\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport { EventEmitter, JsonSchema, type EventParameters } from \"@workglow/util\";\nimport { TaskOutputRepository } from \"../storage/TaskOutputRepository\";\nimport { GraphAsTask } from \"../task/GraphAsTask\";\nimport type { ITask, ITaskConstructor } from \"../task/ITask\";\nimport { Task } from \"../task/Task\";\nimport { WorkflowError } from \"../task/TaskError\";\nimport type { JsonTaskItem, TaskGraphJson } from \"../task/TaskJSON\";\nimport { DataPorts, TaskConfig } from \"../task/TaskTypes\";\nimport { getLastTask, parallel, pipe, PipeFunction, Taskish } from \"./Conversions\";\nimport { Dataflow, DATAFLOW_ALL_PORTS } from \"./Dataflow\";\nimport { IWorkflow } from \"./IWorkflow\";\nimport { TaskGraph } from \"./TaskGraph\";\nimport {\n CompoundMergeStrategy,\n PROPERTY_ARRAY,\n type PropertyArrayGraphResult,\n} from \"./TaskGraphRunner\";\n\n// Type definitions for the workflow\nexport type CreateWorkflow<I extends DataPorts, O extends DataPorts, C extends TaskConfig> = (\n input?: Partial<I>,\n config?: Partial<C>\n) => Workflow<I, O>;\n\n// Event types\nexport type WorkflowEventListeners = {\n changed: (id: unknown) => void;\n reset: () => void;\n error: (error: string) => void;\n start: () => void;\n complete: () => void;\n abort: (error: string) => void;\n};\n\nexport type WorkflowEvents = keyof WorkflowEventListeners;\nexport type WorkflowEventListener<Event extends WorkflowEvents> = WorkflowEventListeners[Event];\nexport type WorkflowEventParameters<Event extends WorkflowEvents> = EventParameters<\n WorkflowEventListeners,\n Event\n>;\n\nclass WorkflowTask<I extends DataPorts, O extends DataPorts> extends GraphAsTask<I, O> {\n public static readonly type = \"Workflow\";\n public static readonly compoundMerge = PROPERTY_ARRAY as CompoundMergeStrategy;\n}\n\n// Task ID counter\nlet taskIdCounter = 0;\n\n/**\n * Class for building and managing a task graph\n * Provides methods for adding tasks, connecting outputs to inputs, and running the task graph\n */\nexport class Workflow<\n Input extends DataPorts = DataPorts,\n Output extends DataPorts = DataPorts,\n> implements IWorkflow<Input, Output> {\n /**\n * Creates a new Workflow\n *\n * @param repository - Optional repository for task outputs\n */\n constructor(repository?: TaskOutputRepository) {\n this._repository = repository;\n this._graph = new TaskGraph({\n outputCache: this._repository,\n });\n this._onChanged = this._onChanged.bind(this);\n this.setupEvents();\n }\n // Private properties\n private _graph: TaskGraph;\n private _dataFlows: Dataflow[] = [];\n private _error: string = \"\";\n private _repository?: TaskOutputRepository;\n\n // Abort controller for cancelling task execution\n private _abortController?: AbortController;\n\n /**\n * Event emitter for task graph events\n */\n public readonly events = new EventEmitter<WorkflowEventListeners>();\n\n /**\n * Creates a helper function for adding specific task types to a Workflow\n *\n * @param taskClass - The task class to create a helper for\n * @returns A function that adds the specified task type to a Workflow\n */\n public static createWorkflow<\n I extends DataPorts,\n O extends DataPorts,\n C extends TaskConfig = TaskConfig,\n >(taskClass: ITaskConstructor<I, O, C>): CreateWorkflow<I, O, C> {\n const helper = function (\n this: Workflow<any, any>,\n input: Partial<I> = {},\n config: Partial<C> = {}\n ) {\n this._error = \"\";\n\n const parent = getLastTask(this);\n\n // Create and add the new task\n taskIdCounter++;\n\n const task = this.addTask<I, O, C>(\n taskClass,\n input as I,\n { id: String(taskIdCounter), ...config } as C\n );\n\n // Process any pending data flows\n if (this._dataFlows.length > 0) {\n this._dataFlows.forEach((dataflow) => {\n const taskSchema = task.inputSchema();\n if (\n (typeof taskSchema !== \"boolean\" &&\n taskSchema.properties?.[dataflow.targetTaskPortId] === undefined) ||\n (taskSchema === true && dataflow.targetTaskPortId !== DATAFLOW_ALL_PORTS)\n ) {\n this._error = `Input ${dataflow.targetTaskPortId} not found on task ${task.config.id}`;\n console.error(this._error);\n return;\n }\n\n dataflow.targetTaskId = task.config.id;\n this.graph.addDataflow(dataflow);\n });\n\n this._dataFlows = [];\n }\n\n // Auto-connect to parent if needed\n if (parent && this.graph.getTargetDataflows(parent.config.id).length === 0) {\n // Find matches between parent outputs and task inputs based on valueType\n const matches = new Map<string, string>();\n const sourceSchema = parent.outputSchema();\n const targetSchema = task.inputSchema();\n\n const makeMatch = (\n comparator: (\n [fromOutputPortId, fromPortOutputSchema]: [string, JsonSchema],\n [toInputPortId, toPortInputSchema]: [string, JsonSchema]\n ) => boolean\n ): Map<string, string> => {\n if (typeof sourceSchema === \"object\") {\n if (\n targetSchema === true ||\n (typeof targetSchema === \"object\" && targetSchema.additionalProperties === true)\n ) {\n for (const fromOutputPortId of Object.keys(sourceSchema.properties || {})) {\n matches.set(fromOutputPortId, fromOutputPortId);\n this.connect(parent.config.id, fromOutputPortId, task.config.id, fromOutputPortId);\n }\n return matches;\n }\n }\n // If either schema is true or false, skip auto-matching\n // as we cannot determine the appropriate connections\n if (typeof sourceSchema === \"boolean\" || typeof targetSchema === \"boolean\") {\n return matches;\n }\n\n for (const [fromOutputPortId, fromPortOutputSchema] of Object.entries(\n sourceSchema.properties || {}\n )) {\n for (const [toInputPortId, toPortInputSchema] of Object.entries(\n targetSchema.properties || {}\n )) {\n if (\n !matches.has(toInputPortId) &&\n comparator(\n [fromOutputPortId, fromPortOutputSchema],\n [toInputPortId, toPortInputSchema]\n )\n ) {\n matches.set(toInputPortId, fromOutputPortId);\n this.connect(parent.config.id, fromOutputPortId, task.config.id, toInputPortId);\n }\n }\n }\n return matches;\n };\n\n /**\n * Extracts specific type identifiers (format, $id) from a schema,\n * looking inside oneOf/anyOf wrappers if needed.\n */\n const getSpecificTypeIdentifiers = (\n schema: JsonSchema\n ): { formats: Set<string>; ids: Set<string> } => {\n const formats = new Set<string>();\n const ids = new Set<string>();\n\n if (typeof schema === \"boolean\") {\n return { formats, ids };\n }\n\n // Helper to extract from a single schema object\n const extractFromSchema = (s: any): void => {\n if (!s || typeof s !== \"object\" || Array.isArray(s)) return;\n if (s.format) formats.add(s.format);\n if (s.$id) ids.add(s.$id);\n };\n\n // Check top-level format/$id\n extractFromSchema(schema);\n\n // Check inside oneOf/anyOf\n const checkUnion = (schemas: JsonSchema[] | undefined): void => {\n if (!schemas) return;\n for (const s of schemas) {\n if (typeof s === \"boolean\") continue;\n extractFromSchema(s);\n // Also check nested items for array types\n if (s.items && typeof s.items === \"object\" && !Array.isArray(s.items)) {\n extractFromSchema(s.items);\n }\n }\n };\n\n checkUnion(schema.oneOf as JsonSchema[] | undefined);\n checkUnion(schema.anyOf as JsonSchema[] | undefined);\n\n // Check items for array types (single schema, not tuple)\n if (schema.items && typeof schema.items === \"object\" && !Array.isArray(schema.items)) {\n extractFromSchema(schema.items);\n }\n\n return { formats, ids };\n };\n\n /**\n * Checks if output schema type is compatible with input schema type.\n * Handles $id matching, format matching, and oneOf/anyOf unions.\n */\n const isTypeCompatible = (\n fromPortOutputSchema: JsonSchema,\n toPortInputSchema: JsonSchema,\n requireSpecificType: boolean = false\n ): boolean => {\n if (typeof fromPortOutputSchema === \"boolean\" || typeof toPortInputSchema === \"boolean\") {\n return fromPortOutputSchema === true && toPortInputSchema === true;\n }\n\n // Extract specific type identifiers from both schemas\n const outputIds = getSpecificTypeIdentifiers(fromPortOutputSchema);\n const inputIds = getSpecificTypeIdentifiers(toPortInputSchema);\n\n // Check if any format matches\n for (const format of outputIds.formats) {\n if (inputIds.formats.has(format)) {\n return true;\n }\n }\n\n // Check if any $id matches\n for (const id of outputIds.ids) {\n if (inputIds.ids.has(id)) {\n return true;\n }\n }\n\n // For type-only fallback, we require specific types (not primitives)\n // to avoid over-matching strings, numbers, etc.\n if (requireSpecificType) {\n return false;\n }\n\n // $id both blank at top level - check type directly (only for name-matched ports)\n const idTypeBlank =\n fromPortOutputSchema.$id === undefined && toPortInputSchema.$id === undefined;\n if (!idTypeBlank) return false;\n\n // Direct type match (for primitives, only when names also match)\n if (fromPortOutputSchema.type === toPortInputSchema.type) return true;\n\n // Check if output type matches any option in oneOf/anyOf\n const matchesOneOf =\n toPortInputSchema.oneOf?.some((schema: any) => {\n if (typeof schema === \"boolean\") return schema;\n return schema.type === fromPortOutputSchema.type;\n }) ?? false;\n\n const matchesAnyOf =\n toPortInputSchema.anyOf?.some((schema: any) => {\n if (typeof schema === \"boolean\") return schema;\n return schema.type === fromPortOutputSchema.type;\n }) ?? false;\n\n return matchesOneOf || matchesAnyOf;\n };\n\n // Strategy 1: Match by type AND port name (highest priority)\n makeMatch(\n ([fromOutputPortId, fromPortOutputSchema], [toInputPortId, toPortInputSchema]) => {\n const outputPortIdMatch = fromOutputPortId === toInputPortId;\n const outputPortIdOutputInput =\n fromOutputPortId === \"output\" && toInputPortId === \"input\";\n const portIdsCompatible = outputPortIdMatch || outputPortIdOutputInput;\n\n return (\n portIdsCompatible && isTypeCompatible(fromPortOutputSchema, toPortInputSchema, false)\n );\n }\n );\n\n // Strategy 2: Match by specific type only (fallback for unmatched ports)\n // Only matches specific types like TypedArray (with format), not primitives\n // This allows connecting ports with different names but compatible specific types\n makeMatch(\n ([_fromOutputPortId, fromPortOutputSchema], [_toInputPortId, toPortInputSchema]) => {\n return isTypeCompatible(fromPortOutputSchema, toPortInputSchema, true);\n }\n );\n\n // Strategy 3: Look back through earlier tasks for unmatched required inputs\n // Extract required inputs from target schema\n const requiredInputs = new Set<string>(\n typeof targetSchema === \"object\" ? (targetSchema.required as string[]) || [] : []\n );\n\n // Filter out required inputs that are already provided in the input parameter\n // These don't need to be connected from previous tasks\n const providedInputKeys = new Set(Object.keys(input || {}));\n const requiredInputsNeedingConnection = [...requiredInputs].filter(\n (r) => !providedInputKeys.has(r)\n );\n\n // Compute unmatched required inputs (that aren't already provided)\n let unmatchedRequired = requiredInputsNeedingConnection.filter((r) => !matches.has(r));\n\n // If there are unmatched required inputs, iterate backwards through earlier tasks\n if (unmatchedRequired.length > 0) {\n const nodes = this._graph.getTasks();\n const parentIndex = nodes.findIndex((n) => n.config.id === parent.config.id);\n\n // Iterate backwards from task before parent\n for (let i = parentIndex - 1; i >= 0 && unmatchedRequired.length > 0; i--) {\n const earlierTask = nodes[i];\n const earlierOutputSchema = earlierTask.outputSchema();\n\n // Helper function to match from an earlier task (only for unmatched required inputs)\n const makeMatchFromEarlier = (\n comparator: (\n [fromOutputPortId, fromPortOutputSchema]: [string, JsonSchema],\n [toInputPortId, toPortInputSchema]: [string, JsonSchema]\n ) => boolean\n ): void => {\n if (typeof earlierOutputSchema === \"boolean\" || typeof targetSchema === \"boolean\") {\n return;\n }\n\n for (const [fromOutputPortId, fromPortOutputSchema] of Object.entries(\n earlierOutputSchema.properties || {}\n )) {\n for (const requiredInputId of unmatchedRequired) {\n const toPortInputSchema = (targetSchema.properties as any)?.[requiredInputId];\n if (\n !matches.has(requiredInputId) &&\n toPortInputSchema &&\n comparator(\n [fromOutputPortId, fromPortOutputSchema],\n [requiredInputId, toPortInputSchema]\n )\n ) {\n matches.set(requiredInputId, fromOutputPortId);\n this.connect(\n earlierTask.config.id,\n fromOutputPortId,\n task.config.id,\n requiredInputId\n );\n }\n }\n }\n };\n\n // Try both matching strategies for earlier tasks\n // Strategy 1: Match by type AND port name\n makeMatchFromEarlier(\n ([fromOutputPortId, fromPortOutputSchema], [toInputPortId, toPortInputSchema]) => {\n const outputPortIdMatch = fromOutputPortId === toInputPortId;\n const outputPortIdOutputInput =\n fromOutputPortId === \"output\" && toInputPortId === \"input\";\n const portIdsCompatible = outputPortIdMatch || outputPortIdOutputInput;\n\n return (\n portIdsCompatible &&\n isTypeCompatible(fromPortOutputSchema, toPortInputSchema, false)\n );\n }\n );\n\n // Strategy 2: Match by specific type only\n makeMatchFromEarlier(\n ([_fromOutputPortId, fromPortOutputSchema], [_toInputPortId, toPortInputSchema]) => {\n return isTypeCompatible(fromPortOutputSchema, toPortInputSchema, true);\n }\n );\n\n // Update unmatched required inputs\n unmatchedRequired = unmatchedRequired.filter((r) => !matches.has(r));\n }\n }\n\n // Updated failure condition: only fail when required inputs (that need connection) remain unmatched\n const stillUnmatchedRequired = requiredInputsNeedingConnection.filter(\n (r) => !matches.has(r)\n );\n if (stillUnmatchedRequired.length > 0) {\n this._error =\n `Could not find matches for required inputs [${stillUnmatchedRequired.join(\", \")}] of ${task.type}. ` +\n `Attempted to match from ${parent.type} and earlier tasks. Task not added.`;\n\n console.error(this._error);\n this.graph.removeTask(task.config.id);\n } else if (matches.size === 0 && requiredInputsNeedingConnection.length === 0) {\n // No matches were made AND no required inputs need connection\n // This happens in two cases:\n // 1. Task has required inputs, but they were all provided as parameters\n // 2. Task has no required inputs (all optional)\n\n // If task has required inputs that were all provided as parameters, allow the task\n const hasRequiredInputs = requiredInputs.size > 0;\n const allRequiredInputsProvided =\n hasRequiredInputs && [...requiredInputs].every((r) => providedInputKeys.has(r));\n\n // If no required inputs (all optional), check if there are defaults\n const hasInputsWithDefaults =\n typeof targetSchema === \"object\" &&\n targetSchema.properties &&\n Object.values(targetSchema.properties).some(\n (prop: any) => prop && typeof prop === \"object\" && \"default\" in prop\n );\n\n // Allow if:\n // - All required inputs were provided as parameters, OR\n // - No required inputs and task has defaults\n // Otherwise fail (no required inputs, no defaults, no matches)\n if (!allRequiredInputsProvided && !hasInputsWithDefaults) {\n this._error =\n `Could not find a match between the outputs of ${parent.type} and the inputs of ${task.type}. ` +\n `You now need to connect the outputs to the inputs via connect() manually before adding this task. Task not added.`;\n\n console.error(this._error);\n this.graph.removeTask(task.config.id);\n }\n }\n }\n\n // Preserve input type from the start of the chain\n // If this is the first task, set both input and output types\n // Otherwise, only update the output type (input type is preserved from 'this')\n return this as any;\n };\n\n // Copy metadata from the task class\n // @ts-expect-error - using internals\n helper.type = taskClass.runtype ?? taskClass.type;\n helper.category = taskClass.category;\n helper.inputSchema = taskClass.inputSchema;\n helper.outputSchema = taskClass.outputSchema;\n helper.cacheable = taskClass.cacheable;\n helper.workflowCreate = true;\n\n return helper as CreateWorkflow<I, O, C>;\n }\n\n /**\n * Gets the current task graph\n */\n public get graph(): TaskGraph {\n return this._graph;\n }\n\n /**\n * Sets a new task graph\n */\n public set graph(value: TaskGraph) {\n this._dataFlows = [];\n this._error = \"\";\n this.clearEvents();\n this._graph = value;\n this.setupEvents();\n this.events.emit(\"reset\");\n }\n\n /**\n * Gets the current error message\n */\n public get error(): string {\n return this._error;\n }\n\n /**\n * Event subscription methods\n */\n public on<Event extends WorkflowEvents>(name: Event, fn: WorkflowEventListener<Event>): void {\n this.events.on(name, fn);\n }\n\n public off<Event extends WorkflowEvents>(name: Event, fn: WorkflowEventListener<Event>): void {\n this.events.off(name, fn);\n }\n\n public once<Event extends WorkflowEvents>(name: Event, fn: WorkflowEventListener<Event>): void {\n this.events.once(name, fn);\n }\n\n public waitOn<Event extends WorkflowEvents>(\n name: Event\n ): Promise<WorkflowEventParameters<Event>> {\n return this.events.waitOn(name) as Promise<WorkflowEventParameters<Event>>;\n }\n\n /**\n * Runs the task graph\n *\n * @param input - The input to the task graph\n * @returns The output of the task graph\n */\n public async run(input: Input = {} as Input): Promise<PropertyArrayGraphResult<Output>> {\n this.events.emit(\"start\");\n this._abortController = new AbortController();\n\n try {\n const output = await this.graph.run<Output>(input, {\n parentSignal: this._abortController.signal,\n outputCache: this._repository,\n });\n const results = this.graph.mergeExecuteOutputsToRunOutput<Output, typeof PROPERTY_ARRAY>(\n output,\n PROPERTY_ARRAY\n );\n this.events.emit(\"complete\");\n return results;\n } catch (error) {\n this.events.emit(\"error\", String(error));\n throw error;\n } finally {\n this._abortController = undefined;\n }\n }\n\n /**\n * Aborts the running task graph\n */\n public async abort(): Promise<void> {\n this._abortController?.abort();\n }\n\n /**\n * Removes the last task from the task graph\n *\n * @returns The current task graph workflow\n */\n public pop(): Workflow {\n this._error = \"\";\n const nodes = this._graph.getTasks();\n\n if (nodes.length === 0) {\n this._error = \"No tasks to remove\";\n console.error(this._error);\n return this;\n }\n\n const lastNode = nodes[nodes.length - 1];\n this._graph.removeTask(lastNode.config.id);\n return this;\n }\n\n /**\n * Converts the task graph to JSON\n *\n * @returns The task graph as JSON\n */\n public toJSON(): TaskGraphJson {\n return this._graph.toJSON();\n }\n\n /**\n * Converts the task graph to dependency JSON\n *\n * @returns The task graph as dependency JSON\n */\n public toDependencyJSON(): JsonTaskItem[] {\n return this._graph.toDependencyJSON();\n }\n\n // Replace both the instance and static pipe methods with properly typed versions\n // Pipe method overloads\n public pipe<A extends DataPorts, B extends DataPorts>(fn1: Taskish<A, B>): IWorkflow<A, B>;\n public pipe<A extends DataPorts, B extends DataPorts, C extends DataPorts>(\n fn1: Taskish<A, B>,\n fn2: Taskish<B, C>\n ): IWorkflow<A, C>;\n public pipe<A extends DataPorts, B extends DataPorts, C extends DataPorts, D extends DataPorts>(\n fn1: Taskish<A, B>,\n fn2: Taskish<B, C>,\n fn3: Taskish<C, D>\n ): IWorkflow<A, D>;\n public pipe<\n A extends DataPorts,\n B extends DataPorts,\n C extends DataPorts,\n D extends DataPorts,\n E extends DataPorts,\n >(\n fn1: Taskish<A, B>,\n fn2: Taskish<B, C>,\n fn3: Taskish<C, D>,\n fn4: Taskish<D, E>\n ): IWorkflow<A, E>;\n public pipe<\n A extends DataPorts,\n B extends DataPorts,\n C extends DataPorts,\n D extends DataPorts,\n E extends DataPorts,\n F extends DataPorts,\n >(\n fn1: Taskish<A, B>,\n fn2: Taskish<B, C>,\n fn3: Taskish<C, D>,\n fn4: Taskish<D, E>,\n fn5: Taskish<E, F>\n ): IWorkflow<A, F>;\n public pipe(...args: Taskish<DataPorts, DataPorts>[]): IWorkflow {\n return pipe(args as any, this);\n }\n\n // Static pipe method overloads\n public static pipe<A extends DataPorts, B extends DataPorts>(\n fn1: PipeFunction<A, B> | ITask<A, B>\n ): IWorkflow;\n public static pipe<A extends DataPorts, B extends DataPorts, C extends DataPorts>(\n fn1: PipeFunction<A, B> | ITask<A, B>,\n fn2: PipeFunction<B, C> | ITask<B, C>\n ): IWorkflow;\n public static pipe<\n A extends DataPorts,\n B extends DataPorts,\n C extends DataPorts,\n D extends DataPorts,\n >(\n fn1: PipeFunction<A, B> | ITask<A, B>,\n fn2: PipeFunction<B, C> | ITask<B, C>,\n fn3: PipeFunction<C, D> | ITask<C, D>\n ): IWorkflow;\n public static pipe<\n A extends DataPorts,\n B extends DataPorts,\n C extends DataPorts,\n D extends DataPorts,\n E extends DataPorts,\n >(\n fn1: PipeFunction<A, B> | ITask<A, B>,\n fn2: PipeFunction<B, C> | ITask<B, C>,\n fn3: PipeFunction<C, D> | ITask<C, D>,\n fn4: PipeFunction<D, E> | ITask<D, E>\n ): IWorkflow;\n public static pipe<\n A extends DataPorts,\n B extends DataPorts,\n C extends DataPorts,\n D extends DataPorts,\n E extends DataPorts,\n F extends DataPorts,\n >(\n fn1: PipeFunction<A, B> | ITask<A, B>,\n fn2: PipeFunction<B, C> | ITask<B, C>,\n fn3: PipeFunction<C, D> | ITask<C, D>,\n fn4: PipeFunction<D, E> | ITask<D, E>,\n fn5: PipeFunction<E, F> | ITask<E, F>\n ): IWorkflow;\n public static pipe(...args: (PipeFunction | ITask)[]): IWorkflow {\n return pipe(args as any, new Workflow());\n }\n\n public parallel(\n args: (PipeFunction<any, any> | Task)[],\n mergeFn?: CompoundMergeStrategy\n ): IWorkflow {\n return parallel(args, mergeFn ?? PROPERTY_ARRAY, this);\n }\n\n public static parallel(\n args: (PipeFunction<any, any> | ITask)[],\n mergeFn?: CompoundMergeStrategy\n ): IWorkflow {\n return parallel(args, mergeFn ?? PROPERTY_ARRAY, new Workflow());\n }\n\n /**\n * Renames an output of a task to a new target input\n *\n * @param source - The id of the output to rename\n * @param target - The id of the input to rename to\n * @param index - The index of the task to rename the output of, defaults to the last task\n * @returns The current task graph workflow\n */\n public rename(source: string, target: string, index: number = -1): Workflow {\n this._error = \"\";\n\n const nodes = this._graph.getTasks();\n if (-index > nodes.length) {\n const errorMsg = `Back index greater than number of tasks`;\n this._error = errorMsg;\n console.error(this._error);\n throw new WorkflowError(errorMsg);\n }\n\n const lastNode = nodes[nodes.length + index];\n const outputSchema = lastNode.outputSchema();\n\n // Handle boolean schemas\n if (typeof outputSchema === \"boolean\") {\n if (outputSchema === false && source !== DATAFLOW_ALL_PORTS) {\n const errorMsg = `Task ${lastNode.config.id} has schema 'false' and outputs nothing`;\n this._error = errorMsg;\n console.error(this._error);\n throw new WorkflowError(errorMsg);\n }\n // If outputSchema is true, we skip validation as it outputs everything\n } else if (!(outputSchema.properties as any)?.[source] && source !== DATAFLOW_ALL_PORTS) {\n const errorMsg = `Output ${source} not found on task ${lastNode.config.id}`;\n this._error = errorMsg;\n console.error(this._error);\n throw new WorkflowError(errorMsg);\n }\n\n this._dataFlows.push(new Dataflow(lastNode.config.id, source, undefined, target));\n return this;\n }\n\n toTaskGraph(): TaskGraph {\n return this._graph;\n }\n\n toTask(): GraphAsTask {\n const task = new WorkflowTask();\n task.subGraph = this.toTaskGraph();\n return task;\n }\n\n /**\n * Resets the task graph workflow to its initial state\n *\n * @returns The current task graph workflow\n */\n public reset(): Workflow {\n taskIdCounter = 0;\n this.clearEvents();\n this._graph = new TaskGraph({\n outputCache: this._repository,\n });\n this._dataFlows = [];\n this._error = \"\";\n this.setupEvents();\n this.events.emit(\"changed\", undefined);\n this.events.emit(\"reset\");\n return this;\n }\n\n /**\n * Sets up event listeners for the task graph\n */\n private setupEvents(): void {\n this._graph.on(\"task_added\", this._onChanged);\n this._graph.on(\"task_replaced\", this._onChanged);\n this._graph.on(\"task_removed\", this._onChanged);\n this._graph.on(\"dataflow_added\", this._onChanged);\n this._graph.on(\"dataflow_replaced\", this._onChanged);\n this._graph.on(\"dataflow_removed\", this._onChanged);\n }\n\n /**\n * Clears event listeners for the task graph\n */\n private clearEvents(): void {\n this._graph.off(\"task_added\", this._onChanged);\n this._graph.off(\"task_replaced\", this._onChanged);\n this._graph.off(\"task_removed\", this._onChanged);\n this._graph.off(\"dataflow_added\", this._onChanged);\n this._graph.off(\"dataflow_replaced\", this._onChanged);\n this._graph.off(\"dataflow_removed\", this._onChanged);\n }\n\n /**\n * Handles changes to the task graph\n */\n private _onChanged(id: unknown): void {\n this.events.emit(\"changed\", id);\n }\n\n /**\n * Connects outputs to inputs between tasks\n */\n public connect(\n sourceTaskId: unknown,\n sourceTaskPortId: string,\n targetTaskId: unknown,\n targetTaskPortId: string\n ): Workflow {\n const sourceTask = this.graph.getTask(sourceTaskId);\n const targetTask = this.graph.getTask(targetTaskId);\n\n if (!sourceTask || !targetTask) {\n throw new WorkflowError(\"Source or target task not found\");\n }\n\n const sourceSchema = sourceTask.outputSchema();\n const targetSchema = targetTask.inputSchema();\n\n // Handle boolean schemas\n if (typeof sourceSchema === \"boolean\") {\n if (sourceSchema === false) {\n throw new WorkflowError(`Source task has schema 'false' and outputs nothing`);\n }\n // If sourceSchema is true, we skip validation as it accepts everything\n } else if (!sourceSchema.properties?.[sourceTaskPortId]) {\n throw new WorkflowError(`Output ${sourceTaskPortId} not found on source task`);\n }\n\n if (typeof targetSchema === \"boolean\") {\n if (targetSchema === false) {\n throw new WorkflowError(`Target task has schema 'false' and accepts no inputs`);\n }\n if (targetSchema === true) {\n // do nothing, we allow additional properties\n }\n } else if (targetSchema.additionalProperties === true) {\n // do nothing, we allow additional properties\n } else if (!targetSchema.properties?.[targetTaskPortId]) {\n throw new WorkflowError(`Input ${targetTaskPortId} not found on target task`);\n }\n\n const dataflow = new Dataflow(sourceTaskId, sourceTaskPortId, targetTaskId, targetTaskPortId);\n this.graph.addDataflow(dataflow);\n return this;\n }\n\n public addTask<I extends DataPorts, O extends DataPorts, C extends TaskConfig = TaskConfig>(\n taskClass: ITaskConstructor<I, O, C>,\n input: I,\n config: C\n ): ITask<I, O, C> {\n const task = new taskClass(input, config);\n const id = this.graph.addTask(task);\n this.events.emit(\"changed\", id);\n return task;\n }\n}\n\n/**\n * Helper function for backward compatibility\n */\nexport function CreateWorkflow<\n I extends DataPorts,\n O extends DataPorts,\n C extends TaskConfig = TaskConfig,\n>(taskClass: any): CreateWorkflow<I, O, C> {\n return Workflow.createWorkflow<I, O, C>(taskClass);\n}\n",
19
19
  "/**\n * @license\n * Copyright 2025 Steven Roussey <sroussey@gmail.com>\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport type { DataPortSchema } from \"@workglow/util\";\nimport { GraphAsTask } from \"../task/GraphAsTask\";\nimport type { IExecuteContext, ITask } from \"../task/ITask\";\nimport { Task } from \"../task/Task\";\nimport type { DataPorts } from \"../task/TaskTypes\";\nimport { Dataflow, DATAFLOW_ALL_PORTS } from \"./Dataflow\";\nimport type { ITaskGraph } from \"./ITaskGraph\";\nimport type { IWorkflow } from \"./IWorkflow\";\nimport { TaskGraph } from \"./TaskGraph\";\nimport { PROPERTY_ARRAY, type CompoundMergeStrategy } from \"./TaskGraphRunner\";\nimport { Workflow } from \"./Workflow\";\n\nclass ListeningGraphAsTask extends GraphAsTask<any, any> {\n constructor(input: any, config: any) {\n super(input, config);\n this.subGraph.on(\"start\", () => {\n this.emit(\"start\");\n });\n this.subGraph.on(\"complete\", () => {\n this.emit(\"complete\");\n });\n this.subGraph.on(\"error\", (e) => {\n this.emit(\"error\", e);\n });\n }\n}\n\nclass OwnGraphTask extends ListeningGraphAsTask {\n public static readonly type = \"Own[Graph]\";\n}\n\nclass OwnWorkflowTask extends ListeningGraphAsTask {\n public static readonly type = \"Own[Workflow]\";\n}\nclass GraphTask extends GraphAsTask {\n public static readonly type = \"Graph\";\n}\n\nclass WorkflowTask extends GraphAsTask {\n public static readonly type = \"Workflow\";\n}\n\n// Update PipeFunction type to be more specific about input/output types\nexport type PipeFunction<I extends DataPorts = any, O extends DataPorts = any> = (\n input: I,\n context: IExecuteContext\n) => O | Promise<O>;\n\nexport type Taskish<A extends DataPorts = DataPorts, B extends DataPorts = DataPorts> =\n | PipeFunction<A, B>\n | ITask<A, B>\n | ITaskGraph\n | IWorkflow<A, B>;\n\nfunction convertPipeFunctionToTask<I extends DataPorts, O extends DataPorts>(\n fn: PipeFunction<I, O>,\n config?: any\n): ITask<I, O> {\n class QuickTask extends Task<I, O> {\n public static type = fn.name ? `𝑓 ${fn.name}` : \"𝑓\";\n public static inputSchema = () => {\n return {\n type: \"object\",\n properties: {\n [DATAFLOW_ALL_PORTS]: {},\n },\n additionalProperties: false,\n } as const satisfies DataPortSchema;\n };\n public static outputSchema = () => {\n return {\n type: \"object\",\n properties: {\n [DATAFLOW_ALL_PORTS]: {},\n },\n additionalProperties: false,\n } as const satisfies DataPortSchema;\n };\n public static cacheable = false;\n public async execute(input: I, context: IExecuteContext) {\n return fn(input, context);\n }\n }\n return new QuickTask({}, config);\n}\n\nexport function ensureTask<I extends DataPorts, O extends DataPorts>(\n arg: Taskish<I, O>,\n config: any = {}\n): ITask<any, any, any> {\n if (arg instanceof Task) {\n return arg;\n }\n if (arg instanceof TaskGraph) {\n if (config.isOwned) {\n return new OwnGraphTask({}, { ...config, subGraph: arg });\n } else {\n return new GraphTask({}, { ...config, subGraph: arg });\n }\n }\n if (arg instanceof Workflow) {\n if (config.isOwned) {\n return new OwnWorkflowTask({}, { ...config, subGraph: arg.graph });\n } else {\n return new WorkflowTask({}, { ...config, subGraph: arg.graph });\n }\n }\n return convertPipeFunctionToTask(arg as PipeFunction<I, O>, config);\n}\n\nexport function getLastTask(workflow: IWorkflow): ITask<any, any, any> | undefined {\n const tasks = workflow.graph.getTasks();\n return tasks.length > 0 ? tasks[tasks.length - 1] : undefined;\n}\n\nexport function connect(\n source: ITask<any, any, any>,\n target: ITask<any, any, any>,\n workflow: IWorkflow<any, any>\n): void {\n workflow.graph.addDataflow(new Dataflow(source.config.id, \"*\", target.config.id, \"*\"));\n}\n\nexport function pipe<A extends DataPorts, B extends DataPorts>(\n [fn1]: [Taskish<A, B>],\n workflow?: IWorkflow<A, B>\n): IWorkflow<A, B>;\n\nexport function pipe<A extends DataPorts, B extends DataPorts, C extends DataPorts>(\n [fn1, fn2]: [Taskish<A, B>, Taskish<B, C>],\n workflow?: IWorkflow<A, C>\n): IWorkflow<A, C>;\n\nexport function pipe<\n A extends DataPorts,\n B extends DataPorts,\n C extends DataPorts,\n D extends DataPorts,\n>(\n [fn1, fn2, fn3]: [Taskish<A, B>, Taskish<B, C>, Taskish<C, D>],\n workflow?: IWorkflow<A, D>\n): IWorkflow<A, D>;\n\nexport function pipe<\n A extends DataPorts,\n B extends DataPorts,\n C extends DataPorts,\n D extends DataPorts,\n E extends DataPorts,\n>(\n [fn1, fn2, fn3, fn4]: [Taskish<A, B>, Taskish<B, C>, Taskish<C, D>, Taskish<D, E>],\n workflow?: IWorkflow<A, E>\n): IWorkflow<A, E>;\n\nexport function pipe<\n A extends DataPorts,\n B extends DataPorts,\n C extends DataPorts,\n D extends DataPorts,\n E extends DataPorts,\n F extends DataPorts,\n>(\n [fn1, fn2, fn3, fn4, fn5]: [\n Taskish<A, B>,\n Taskish<B, C>,\n Taskish<C, D>,\n Taskish<D, E>,\n Taskish<E, F>,\n ],\n workflow?: IWorkflow<A, F>\n): IWorkflow<A, F>;\n\nexport function pipe<I extends DataPorts, O extends DataPorts>(\n args: Taskish<I, O>[],\n workflow: IWorkflow<I, O> = new Workflow<I, O>()\n): IWorkflow<I, O> {\n let previousTask = getLastTask(workflow);\n const tasks = args.map((arg) => ensureTask(arg));\n tasks.forEach((task) => {\n workflow.graph.addTask(task);\n if (previousTask) {\n connect(previousTask, task, workflow);\n }\n previousTask = task;\n });\n return workflow;\n}\n\nexport function parallel<I extends DataPorts = DataPorts, O extends DataPorts = DataPorts>(\n args: (PipeFunction<I, O> | ITask<I, O> | IWorkflow<I, O> | ITaskGraph)[],\n mergeFn: CompoundMergeStrategy = PROPERTY_ARRAY,\n workflow: IWorkflow<I, O> = new Workflow<I, O>()\n): IWorkflow<I, O> {\n let previousTask = getLastTask(workflow);\n const tasks = args.map((arg) => ensureTask(arg));\n const input = {};\n const config = {\n compoundMerge: mergeFn,\n };\n const name = `‖${args.map((arg) => \"𝑓\").join(\"‖\")}‖`;\n class ParallelTask extends GraphAsTask<I, O> {\n public static type = name;\n }\n const mergeTask = new ParallelTask(input, config);\n mergeTask.subGraph!.addTasks(tasks);\n workflow.graph.addTask(mergeTask);\n if (previousTask) {\n connect(previousTask, mergeTask, workflow);\n }\n return workflow;\n}\n",
20
- "/**\n * @license\n * Copyright 2025 Steven Roussey <sroussey@gmail.com>\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport { EventEmitter, JsonSchema, uuid4, type EventParameters } from \"@workglow/util\";\nimport { IteratorTask } from \"../common\";\nimport { TaskOutputRepository } from \"../storage/TaskOutputRepository\";\nimport { GraphAsTask } from \"../task/GraphAsTask\";\nimport type { ITask, ITaskConstructor } from \"../task/ITask\";\nimport { Task } from \"../task/Task\";\nimport { WorkflowError } from \"../task/TaskError\";\nimport type { JsonTaskItem, TaskGraphJson } from \"../task/TaskJSON\";\nimport { DataPorts, TaskConfig } from \"../task/TaskTypes\";\nimport { getLastTask, parallel, pipe, PipeFunction, Taskish } from \"./Conversions\";\nimport { Dataflow, DATAFLOW_ALL_PORTS } from \"./Dataflow\";\nimport { IWorkflow } from \"./IWorkflow\";\nimport { TaskGraph } from \"./TaskGraph\";\nimport {\n CompoundMergeStrategy,\n PROPERTY_ARRAY,\n type PropertyArrayGraphResult,\n} from \"./TaskGraphRunner\";\n\n// Type definitions for the workflow\nexport type CreateWorkflow<I extends DataPorts, O extends DataPorts, C extends TaskConfig> = (\n input?: Partial<I>,\n config?: Partial<C>\n) => Workflow<I, O>;\n\nexport function CreateWorkflow<\n I extends DataPorts,\n O extends DataPorts,\n C extends TaskConfig = TaskConfig,\n>(taskClass: ITaskConstructor<I, O, C>): CreateWorkflow<I, O, C> {\n return Workflow.createWorkflow<I, O, C>(taskClass);\n}\n\n/**\n * Type for loop workflow methods (forEach, map, batch, while, reduce).\n * Represents the method signature with proper `this` context.\n * Loop methods take only a config parameter - input is not used for loop tasks.\n */\nexport type CreateLoopWorkflow<\n I extends DataPorts,\n O extends DataPorts,\n C extends TaskConfig = TaskConfig,\n> = (this: Workflow<I, O>, config?: Partial<C>) => Workflow<I, O>;\n\n/**\n * Factory function that creates a loop workflow method for a given task class.\n * Returns a method that can be assigned to Workflow.prototype.\n *\n * @param taskClass - The iterator task class (ForEachTask, MapTask, etc.)\n * @returns A method that creates the task and returns a loop builder workflow\n */\nexport function CreateLoopWorkflow<\n I extends DataPorts,\n O extends DataPorts,\n C extends TaskConfig = TaskConfig,\n>(taskClass: ITaskConstructor<I, O, C>): CreateLoopWorkflow<I, O, C> {\n return function (this: Workflow<I, O>, config: Partial<C> = {}): Workflow<I, O> {\n const task = new taskClass({} as I, config as C);\n this.graph.addTask(task);\n\n // Connect to previous task if exists\n const previousTask = getLastTask(this);\n if (previousTask && previousTask !== task) {\n this.graph.addDataflow(new Dataflow(previousTask.config.id, \"*\", task.config.id, \"*\"));\n }\n\n return new Workflow(this.outputCache(), this, task as unknown as IteratorTask);\n };\n}\n\n/**\n * Type for end loop workflow methods (endForEach, endMap, etc.).\n */\nexport type EndLoopWorkflow = (this: Workflow) => Workflow;\n\n/**\n * Factory function that creates an end loop workflow method.\n *\n * @param methodName - The name of the method (for error messages)\n * @returns A method that finalizes the loop and returns to the parent workflow\n */\nexport function CreateEndLoopWorkflow(methodName: string): EndLoopWorkflow {\n return function (this: Workflow): Workflow {\n if (!this.isLoopBuilder) {\n throw new Error(`${methodName}() can only be called on loop workflows`);\n }\n return this.finalizeAndReturn();\n };\n}\n\n// Event types\nexport type WorkflowEventListeners = {\n changed: (id: unknown) => void;\n reset: () => void;\n error: (error: string) => void;\n start: () => void;\n complete: () => void;\n abort: (error: string) => void;\n};\n\nexport type WorkflowEvents = keyof WorkflowEventListeners;\nexport type WorkflowEventListener<Event extends WorkflowEvents> = WorkflowEventListeners[Event];\nexport type WorkflowEventParameters<Event extends WorkflowEvents> = EventParameters<\n WorkflowEventListeners,\n Event\n>;\n\nclass WorkflowTask<I extends DataPorts, O extends DataPorts> extends GraphAsTask<I, O> {\n public static readonly type = \"Workflow\";\n public static readonly compoundMerge = PROPERTY_ARRAY as CompoundMergeStrategy;\n}\n\n/**\n * Class for building and managing a task graph\n * Provides methods for adding tasks, connecting outputs to inputs, and running the task graph\n *\n * When used with a parent workflow (loop builder mode), this class redirects task additions\n * to the iterator task's template graph until an end method (endMap, endForEach, etc.) is called.\n */\nexport class Workflow<\n Input extends DataPorts = DataPorts,\n Output extends DataPorts = DataPorts,\n> implements IWorkflow<Input, Output> {\n /**\n * Creates a new Workflow\n *\n * @param cache - Optional repository for task outputs\n * @param parent - Optional parent workflow (for loop builder mode)\n * @param iteratorTask - Optional iterator task being configured (for loop builder mode)\n */\n constructor(cache?: TaskOutputRepository, parent?: Workflow, iteratorTask?: IteratorTask) {\n this._outputCache = cache;\n this._parentWorkflow = parent;\n this._iteratorTask = iteratorTask;\n this._graph = new TaskGraph({ outputCache: this._outputCache });\n\n if (!parent) {\n this._onChanged = this._onChanged.bind(this);\n this.setupEvents();\n }\n }\n\n // Private properties\n private _graph: TaskGraph;\n private _dataFlows: Dataflow[] = [];\n private _error: string = \"\";\n private _outputCache?: TaskOutputRepository;\n\n // Abort controller for cancelling task execution\n private _abortController?: AbortController;\n\n // Loop builder properties\n private readonly _parentWorkflow?: Workflow;\n private readonly _iteratorTask?: IteratorTask;\n\n public outputCache(): TaskOutputRepository | undefined {\n return this._outputCache;\n }\n\n /**\n * Whether this workflow is in loop builder mode.\n * When true, tasks are added to the template graph for an iterator task.\n */\n public get isLoopBuilder(): boolean {\n return this._parentWorkflow !== undefined;\n }\n\n /**\n * Event emitter for task graph events\n */\n public readonly events = new EventEmitter<WorkflowEventListeners>();\n\n /**\n * Creates a helper function for adding specific task types to a Workflow\n *\n * @param taskClass - The task class to create a helper for\n * @returns A function that adds the specified task type to a Workflow\n */\n public static createWorkflow<\n I extends DataPorts,\n O extends DataPorts,\n C extends TaskConfig = TaskConfig,\n >(taskClass: ITaskConstructor<I, O, C>): CreateWorkflow<I, O, C> {\n const helper = function (\n this: Workflow<any, any>,\n input: Partial<I> = {},\n config: Partial<C> = {}\n ) {\n this._error = \"\";\n\n const parent = getLastTask(this);\n\n const task = this.addTaskToGraph<I, O, C>(\n taskClass,\n input as I,\n { id: uuid4(), ...config } as C\n );\n\n // Process any pending data flows\n if (this._dataFlows.length > 0) {\n this._dataFlows.forEach((dataflow) => {\n const taskSchema = task.inputSchema();\n if (\n (typeof taskSchema !== \"boolean\" &&\n taskSchema.properties?.[dataflow.targetTaskPortId] === undefined) ||\n (taskSchema === true && dataflow.targetTaskPortId !== DATAFLOW_ALL_PORTS)\n ) {\n this._error = `Input ${dataflow.targetTaskPortId} not found on task ${task.config.id}`;\n console.error(this._error);\n return;\n }\n\n dataflow.targetTaskId = task.config.id;\n this.graph.addDataflow(dataflow);\n });\n\n this._dataFlows = [];\n }\n\n // Auto-connect to parent if needed\n if (parent && this.graph.getTargetDataflows(parent.config.id).length === 0) {\n // Build the list of earlier tasks (in reverse chronological order)\n const nodes = this._graph.getTasks();\n const parentIndex = nodes.findIndex((n) => n.config.id === parent.config.id);\n const earlierTasks: ITask[] = [];\n for (let i = parentIndex - 1; i >= 0; i--) {\n earlierTasks.push(nodes[i]);\n }\n\n const providedInputKeys = new Set(Object.keys(input || {}));\n\n const result = Workflow.autoConnect(this.graph, parent, task, {\n providedInputKeys,\n earlierTasks,\n });\n\n if (result.error) {\n // In loop builder mode, don't remove the task - allow manual connection\n // In normal mode, remove the task since auto-connect is required\n if (this.isLoopBuilder) {\n this._error = result.error;\n console.warn(this._error);\n } else {\n this._error = result.error + \" Task not added.\";\n console.error(this._error);\n this.graph.removeTask(task.config.id);\n }\n }\n }\n\n // Preserve input type from the start of the chain\n // If this is the first task, set both input and output types\n // Otherwise, only update the output type (input type is preserved from 'this')\n return this as any;\n };\n\n // Copy metadata from the task class\n // @ts-expect-error - using internals\n helper.type = taskClass.runtype ?? taskClass.type;\n helper.category = taskClass.category;\n helper.inputSchema = taskClass.inputSchema;\n helper.outputSchema = taskClass.outputSchema;\n helper.cacheable = taskClass.cacheable;\n helper.workflowCreate = true;\n\n return helper as CreateWorkflow<I, O, C>;\n }\n\n /**\n * Gets the current task graph\n */\n public get graph(): TaskGraph {\n return this._graph;\n }\n\n /**\n * Sets a new task graph\n */\n public set graph(value: TaskGraph) {\n this._dataFlows = [];\n this._error = \"\";\n this.clearEvents();\n this._graph = value;\n this.setupEvents();\n this.events.emit(\"reset\");\n }\n\n /**\n * Gets the current error message\n */\n public get error(): string {\n return this._error;\n }\n\n /**\n * Event subscription methods\n */\n public on<Event extends WorkflowEvents>(name: Event, fn: WorkflowEventListener<Event>): void {\n this.events.on(name, fn);\n }\n\n public off<Event extends WorkflowEvents>(name: Event, fn: WorkflowEventListener<Event>): void {\n this.events.off(name, fn);\n }\n\n public once<Event extends WorkflowEvents>(name: Event, fn: WorkflowEventListener<Event>): void {\n this.events.once(name, fn);\n }\n\n public waitOn<Event extends WorkflowEvents>(\n name: Event\n ): Promise<WorkflowEventParameters<Event>> {\n return this.events.waitOn(name) as Promise<WorkflowEventParameters<Event>>;\n }\n\n /**\n * Runs the task graph\n *\n * @param input - The input to the task graph\n * @returns The output of the task graph\n */\n public async run(input: Input = {} as Input): Promise<PropertyArrayGraphResult<Output>> {\n // In loop builder mode, finalize template and delegate to parent\n if (this.isLoopBuilder) {\n this.finalizeTemplate();\n return this._parentWorkflow!.run(input as any) as Promise<PropertyArrayGraphResult<Output>>;\n }\n\n this.events.emit(\"start\");\n this._abortController = new AbortController();\n\n try {\n const output = await this.graph.run<Output>(input, {\n parentSignal: this._abortController.signal,\n outputCache: this._outputCache,\n });\n const results = this.graph.mergeExecuteOutputsToRunOutput<Output, typeof PROPERTY_ARRAY>(\n output,\n PROPERTY_ARRAY\n );\n this.events.emit(\"complete\");\n return results;\n } catch (error) {\n this.events.emit(\"error\", String(error));\n throw error;\n } finally {\n this._abortController = undefined;\n }\n }\n\n /**\n * Aborts the running task graph\n */\n public async abort(): Promise<void> {\n // In loop builder mode, delegate to parent\n if (this._parentWorkflow) {\n return this._parentWorkflow.abort();\n }\n this._abortController?.abort();\n }\n\n /**\n * Removes the last task from the task graph\n *\n * @returns The current task graph workflow\n */\n public pop(): Workflow {\n this._error = \"\";\n const nodes = this._graph.getTasks();\n\n if (nodes.length === 0) {\n this._error = \"No tasks to remove\";\n console.error(this._error);\n return this;\n }\n\n const lastNode = nodes[nodes.length - 1];\n this._graph.removeTask(lastNode.config.id);\n return this;\n }\n\n /**\n * Converts the task graph to JSON\n *\n * @returns The task graph as JSON\n */\n public toJSON(): TaskGraphJson {\n return this._graph.toJSON();\n }\n\n /**\n * Converts the task graph to dependency JSON\n *\n * @returns The task graph as dependency JSON\n */\n public toDependencyJSON(): JsonTaskItem[] {\n return this._graph.toDependencyJSON();\n }\n\n // Replace both the instance and static pipe methods with properly typed versions\n // Pipe method overloads\n public pipe<A extends DataPorts, B extends DataPorts>(fn1: Taskish<A, B>): IWorkflow<A, B>;\n public pipe<A extends DataPorts, B extends DataPorts, C extends DataPorts>(\n fn1: Taskish<A, B>,\n fn2: Taskish<B, C>\n ): IWorkflow<A, C>;\n public pipe<A extends DataPorts, B extends DataPorts, C extends DataPorts, D extends DataPorts>(\n fn1: Taskish<A, B>,\n fn2: Taskish<B, C>,\n fn3: Taskish<C, D>\n ): IWorkflow<A, D>;\n public pipe<\n A extends DataPorts,\n B extends DataPorts,\n C extends DataPorts,\n D extends DataPorts,\n E extends DataPorts,\n >(\n fn1: Taskish<A, B>,\n fn2: Taskish<B, C>,\n fn3: Taskish<C, D>,\n fn4: Taskish<D, E>\n ): IWorkflow<A, E>;\n public pipe<\n A extends DataPorts,\n B extends DataPorts,\n C extends DataPorts,\n D extends DataPorts,\n E extends DataPorts,\n F extends DataPorts,\n >(\n fn1: Taskish<A, B>,\n fn2: Taskish<B, C>,\n fn3: Taskish<C, D>,\n fn4: Taskish<D, E>,\n fn5: Taskish<E, F>\n ): IWorkflow<A, F>;\n public pipe(...args: Taskish<DataPorts, DataPorts>[]): IWorkflow {\n return pipe(args as any, this);\n }\n\n // Static pipe method overloads\n public static pipe<A extends DataPorts, B extends DataPorts>(\n fn1: PipeFunction<A, B> | ITask<A, B>\n ): IWorkflow;\n public static pipe<A extends DataPorts, B extends DataPorts, C extends DataPorts>(\n fn1: PipeFunction<A, B> | ITask<A, B>,\n fn2: PipeFunction<B, C> | ITask<B, C>\n ): IWorkflow;\n public static pipe<\n A extends DataPorts,\n B extends DataPorts,\n C extends DataPorts,\n D extends DataPorts,\n >(\n fn1: PipeFunction<A, B> | ITask<A, B>,\n fn2: PipeFunction<B, C> | ITask<B, C>,\n fn3: PipeFunction<C, D> | ITask<C, D>\n ): IWorkflow;\n public static pipe<\n A extends DataPorts,\n B extends DataPorts,\n C extends DataPorts,\n D extends DataPorts,\n E extends DataPorts,\n >(\n fn1: PipeFunction<A, B> | ITask<A, B>,\n fn2: PipeFunction<B, C> | ITask<B, C>,\n fn3: PipeFunction<C, D> | ITask<C, D>,\n fn4: PipeFunction<D, E> | ITask<D, E>\n ): IWorkflow;\n public static pipe<\n A extends DataPorts,\n B extends DataPorts,\n C extends DataPorts,\n D extends DataPorts,\n E extends DataPorts,\n F extends DataPorts,\n >(\n fn1: PipeFunction<A, B> | ITask<A, B>,\n fn2: PipeFunction<B, C> | ITask<B, C>,\n fn3: PipeFunction<C, D> | ITask<C, D>,\n fn4: PipeFunction<D, E> | ITask<D, E>,\n fn5: PipeFunction<E, F> | ITask<E, F>\n ): IWorkflow;\n public static pipe(...args: (PipeFunction | ITask)[]): IWorkflow {\n return pipe(args as any, new Workflow());\n }\n\n public parallel(\n args: (PipeFunction<any, any> | Task)[],\n mergeFn?: CompoundMergeStrategy\n ): IWorkflow {\n return parallel(args, mergeFn ?? PROPERTY_ARRAY, this);\n }\n\n public static parallel(\n args: (PipeFunction<any, any> | ITask)[],\n mergeFn?: CompoundMergeStrategy\n ): IWorkflow {\n return parallel(args, mergeFn ?? PROPERTY_ARRAY, new Workflow());\n }\n\n /**\n * Renames an output of a task to a new target input\n *\n * @param source - The id of the output to rename\n * @param target - The id of the input to rename to\n * @param index - The index of the task to rename the output of, defaults to the last task\n * @returns The current task graph workflow\n */\n public rename(source: string, target: string, index: number = -1): Workflow {\n this._error = \"\";\n\n const nodes = this._graph.getTasks();\n if (-index > nodes.length) {\n const errorMsg = `Back index greater than number of tasks`;\n this._error = errorMsg;\n console.error(this._error);\n throw new WorkflowError(errorMsg);\n }\n\n const lastNode = nodes[nodes.length + index];\n const outputSchema = lastNode.outputSchema();\n\n // Handle boolean schemas\n if (typeof outputSchema === \"boolean\") {\n if (outputSchema === false && source !== DATAFLOW_ALL_PORTS) {\n const errorMsg = `Task ${lastNode.config.id} has schema 'false' and outputs nothing`;\n this._error = errorMsg;\n console.error(this._error);\n throw new WorkflowError(errorMsg);\n }\n // If outputSchema is true, we skip validation as it outputs everything\n } else if (!(outputSchema.properties as any)?.[source] && source !== DATAFLOW_ALL_PORTS) {\n const errorMsg = `Output ${source} not found on task ${lastNode.config.id}`;\n this._error = errorMsg;\n console.error(this._error);\n throw new WorkflowError(errorMsg);\n }\n\n this._dataFlows.push(new Dataflow(lastNode.config.id, source, undefined, target));\n return this;\n }\n\n toTaskGraph(): TaskGraph {\n return this._graph;\n }\n\n toTask(): GraphAsTask {\n const task = new WorkflowTask();\n task.subGraph = this.toTaskGraph();\n return task;\n }\n\n /**\n * Resets the task graph workflow to its initial state\n *\n * @returns The current task graph workflow\n */\n public reset(): Workflow {\n // In loop builder mode, reset is not supported\n if (this._parentWorkflow) {\n throw new WorkflowError(\"Cannot reset a loop workflow. Call reset() on the parent workflow.\");\n }\n\n this.clearEvents();\n this._graph = new TaskGraph({\n outputCache: this._outputCache,\n });\n this._dataFlows = [];\n this._error = \"\";\n this.setupEvents();\n this.events.emit(\"changed\", undefined);\n this.events.emit(\"reset\");\n return this;\n }\n\n /**\n * Sets up event listeners for the task graph\n */\n private setupEvents(): void {\n this._graph.on(\"task_added\", this._onChanged);\n this._graph.on(\"task_replaced\", this._onChanged);\n this._graph.on(\"task_removed\", this._onChanged);\n this._graph.on(\"dataflow_added\", this._onChanged);\n this._graph.on(\"dataflow_replaced\", this._onChanged);\n this._graph.on(\"dataflow_removed\", this._onChanged);\n }\n\n /**\n * Clears event listeners for the task graph\n */\n private clearEvents(): void {\n this._graph.off(\"task_added\", this._onChanged);\n this._graph.off(\"task_replaced\", this._onChanged);\n this._graph.off(\"task_removed\", this._onChanged);\n this._graph.off(\"dataflow_added\", this._onChanged);\n this._graph.off(\"dataflow_replaced\", this._onChanged);\n this._graph.off(\"dataflow_removed\", this._onChanged);\n }\n\n /**\n * Handles changes to the task graph\n */\n private _onChanged(id: unknown): void {\n this.events.emit(\"changed\", id);\n }\n\n /**\n * Connects outputs to inputs between tasks\n */\n public connect(\n sourceTaskId: unknown,\n sourceTaskPortId: string,\n targetTaskId: unknown,\n targetTaskPortId: string\n ): Workflow {\n const sourceTask = this.graph.getTask(sourceTaskId);\n const targetTask = this.graph.getTask(targetTaskId);\n\n if (!sourceTask || !targetTask) {\n throw new WorkflowError(\"Source or target task not found\");\n }\n\n const sourceSchema = sourceTask.outputSchema();\n const targetSchema = targetTask.inputSchema();\n\n // Handle boolean schemas\n if (typeof sourceSchema === \"boolean\") {\n if (sourceSchema === false) {\n throw new WorkflowError(`Source task has schema 'false' and outputs nothing`);\n }\n // If sourceSchema is true, we skip validation as it accepts everything\n } else if (!sourceSchema.properties?.[sourceTaskPortId]) {\n throw new WorkflowError(`Output ${sourceTaskPortId} not found on source task`);\n }\n\n if (typeof targetSchema === \"boolean\") {\n if (targetSchema === false) {\n throw new WorkflowError(`Target task has schema 'false' and accepts no inputs`);\n }\n if (targetSchema === true) {\n // do nothing, we allow additional properties\n }\n } else if (targetSchema.additionalProperties === true) {\n // do nothing, we allow additional properties\n } else if (!targetSchema.properties?.[targetTaskPortId]) {\n throw new WorkflowError(`Input ${targetTaskPortId} not found on target task`);\n }\n\n const dataflow = new Dataflow(sourceTaskId, sourceTaskPortId, targetTaskId, targetTaskPortId);\n this.graph.addDataflow(dataflow);\n return this;\n }\n\n public addTaskToGraph<\n I extends DataPorts,\n O extends DataPorts,\n C extends TaskConfig = TaskConfig,\n >(taskClass: ITaskConstructor<I, O, C>, input: I, config: C): ITask<I, O, C> {\n const task = new taskClass(input, config);\n const id = this.graph.addTask(task);\n this.events.emit(\"changed\", id);\n return task;\n }\n\n /**\n * Adds a task to the workflow using the same logic as createWorkflow() helpers.\n * Auto-generates an ID, processes pending dataflows, and auto-connects to previous tasks.\n *\n * @param taskClass - The task class to instantiate and add\n * @param input - Optional input values for the task\n * @param config - Optional configuration (id will be auto-generated if not provided)\n * @returns The workflow for chaining\n */\n public addTask<I extends DataPorts, O extends DataPorts, C extends TaskConfig = TaskConfig>(\n taskClass: ITaskConstructor<I, O, C>,\n input?: Partial<I>,\n config?: Partial<C>\n ): Workflow<Input, Output> {\n const helper = Workflow.createWorkflow<I, O, C>(taskClass);\n return helper.call(this, input, config) as Workflow<Input, Output>;\n }\n\n // ========================================================================\n // Loop Builder Methods\n // ========================================================================\n\n /**\n * Options for auto-connect operation.\n */\n public static readonly AutoConnectOptions: unique symbol = Symbol(\"AutoConnectOptions\");\n\n /**\n * Auto-connects two tasks based on their schemas.\n * Uses multiple matching strategies:\n * 1. Match by type AND port name (highest priority)\n * 2. Match by specific type only (format, $id) for unmatched ports\n * 3. Look back through earlier tasks for unmatched required inputs\n *\n * @param graph - The task graph to add dataflows to\n * @param sourceTask - The source task to connect from\n * @param targetTask - The target task to connect to\n * @param options - Optional configuration for the auto-connect operation\n * @returns Result containing matches made, any errors, and unmatched required inputs\n */\n public static autoConnect(\n graph: TaskGraph,\n sourceTask: ITask,\n targetTask: ITask,\n options?: {\n /** Keys of inputs that are already provided and don't need connection */\n readonly providedInputKeys?: Set<string>;\n /** Earlier tasks to search for unmatched required inputs (in reverse chronological order) */\n readonly earlierTasks?: readonly ITask[];\n }\n ): {\n readonly matches: Map<string, string>;\n readonly error?: string;\n readonly unmatchedRequired: readonly string[];\n } {\n const matches = new Map<string, string>();\n const sourceSchema = sourceTask.outputSchema();\n const targetSchema = targetTask.inputSchema();\n const providedInputKeys = options?.providedInputKeys ?? new Set<string>();\n const earlierTasks = options?.earlierTasks ?? [];\n\n /**\n * Extracts specific type identifiers (format, $id) from a schema,\n * looking inside oneOf/anyOf wrappers if needed.\n */\n const getSpecificTypeIdentifiers = (\n schema: JsonSchema\n ): { formats: Set<string>; ids: Set<string> } => {\n const formats = new Set<string>();\n const ids = new Set<string>();\n\n if (typeof schema === \"boolean\") {\n return { formats, ids };\n }\n\n // Helper to extract from a single schema object\n const extractFromSchema = (s: any): void => {\n if (!s || typeof s !== \"object\" || Array.isArray(s)) return;\n if (s.format) formats.add(s.format);\n if (s.$id) ids.add(s.$id);\n };\n\n // Check top-level format/$id\n extractFromSchema(schema);\n\n // Check inside oneOf/anyOf\n const checkUnion = (schemas: JsonSchema[] | undefined): void => {\n if (!schemas) return;\n for (const s of schemas) {\n if (typeof s === \"boolean\") continue;\n extractFromSchema(s);\n // Also check nested items for array types\n if (s.items && typeof s.items === \"object\" && !Array.isArray(s.items)) {\n extractFromSchema(s.items);\n }\n }\n };\n\n checkUnion(schema.oneOf as JsonSchema[] | undefined);\n checkUnion(schema.anyOf as JsonSchema[] | undefined);\n\n // Check items for array types (single schema, not tuple)\n if (schema.items && typeof schema.items === \"object\" && !Array.isArray(schema.items)) {\n extractFromSchema(schema.items);\n }\n\n return { formats, ids };\n };\n\n /**\n * Checks if output schema type is compatible with input schema type.\n * Handles $id matching, format matching, and oneOf/anyOf unions.\n */\n const isTypeCompatible = (\n fromPortOutputSchema: JsonSchema,\n toPortInputSchema: JsonSchema,\n requireSpecificType: boolean = false\n ): boolean => {\n if (typeof fromPortOutputSchema === \"boolean\" || typeof toPortInputSchema === \"boolean\") {\n return fromPortOutputSchema === true && toPortInputSchema === true;\n }\n\n // Extract specific type identifiers from both schemas\n const outputIds = getSpecificTypeIdentifiers(fromPortOutputSchema);\n const inputIds = getSpecificTypeIdentifiers(toPortInputSchema);\n\n // Check if any format matches\n for (const format of outputIds.formats) {\n if (inputIds.formats.has(format)) {\n return true;\n }\n }\n\n // Check if any $id matches\n for (const id of outputIds.ids) {\n if (inputIds.ids.has(id)) {\n return true;\n }\n }\n\n // For type-only fallback, we require specific types (not primitives)\n // to avoid over-matching strings, numbers, etc.\n if (requireSpecificType) {\n return false;\n }\n\n // $id both blank at top level - check type directly (only for name-matched ports)\n const idTypeBlank =\n fromPortOutputSchema.$id === undefined && toPortInputSchema.$id === undefined;\n if (!idTypeBlank) return false;\n\n // Direct type match (for primitives, only when names also match)\n if (fromPortOutputSchema.type === toPortInputSchema.type) return true;\n\n // Check if output type matches any option in oneOf/anyOf\n const matchesOneOf =\n toPortInputSchema.oneOf?.some((schema: any) => {\n if (typeof schema === \"boolean\") return schema;\n return schema.type === fromPortOutputSchema.type;\n }) ?? false;\n\n const matchesAnyOf =\n toPortInputSchema.anyOf?.some((schema: any) => {\n if (typeof schema === \"boolean\") return schema;\n return schema.type === fromPortOutputSchema.type;\n }) ?? false;\n\n return matchesOneOf || matchesAnyOf;\n };\n\n const makeMatch = (\n fromSchema: JsonSchema,\n toSchema: JsonSchema,\n fromTaskId: unknown,\n toTaskId: unknown,\n comparator: (\n [fromOutputPortId, fromPortOutputSchema]: [string, JsonSchema],\n [toInputPortId, toPortInputSchema]: [string, JsonSchema]\n ) => boolean\n ): void => {\n if (typeof fromSchema === \"object\") {\n if (\n toSchema === true ||\n (typeof toSchema === \"object\" && toSchema.additionalProperties === true)\n ) {\n for (const fromOutputPortId of Object.keys(fromSchema.properties || {})) {\n matches.set(fromOutputPortId, fromOutputPortId);\n graph.addDataflow(\n new Dataflow(fromTaskId, fromOutputPortId, toTaskId, fromOutputPortId)\n );\n }\n return;\n }\n }\n // If either schema is true or false, skip auto-matching\n // as we cannot determine the appropriate connections\n if (typeof fromSchema === \"boolean\" || typeof toSchema === \"boolean\") {\n return;\n }\n\n for (const [fromOutputPortId, fromPortOutputSchema] of Object.entries(\n fromSchema.properties || {}\n )) {\n for (const [toInputPortId, toPortInputSchema] of Object.entries(\n toSchema.properties || {}\n )) {\n if (\n !matches.has(toInputPortId) &&\n comparator([fromOutputPortId, fromPortOutputSchema], [toInputPortId, toPortInputSchema])\n ) {\n matches.set(toInputPortId, fromOutputPortId);\n graph.addDataflow(new Dataflow(fromTaskId, fromOutputPortId, toTaskId, toInputPortId));\n }\n }\n }\n };\n\n // Strategy 1: Match by type AND port name (highest priority)\n makeMatch(\n sourceSchema,\n targetSchema,\n sourceTask.config.id,\n targetTask.config.id,\n ([fromOutputPortId, fromPortOutputSchema], [toInputPortId, toPortInputSchema]) => {\n const outputPortIdMatch = fromOutputPortId === toInputPortId;\n const outputPortIdOutputInput = fromOutputPortId === \"output\" && toInputPortId === \"input\";\n const portIdsCompatible = outputPortIdMatch || outputPortIdOutputInput;\n\n return (\n portIdsCompatible && isTypeCompatible(fromPortOutputSchema, toPortInputSchema, false)\n );\n }\n );\n\n // Strategy 2: Match by specific type only (fallback for unmatched ports)\n // Only matches specific types like TypedArray (with format), not primitives\n // This allows connecting ports with different names but compatible specific types\n makeMatch(\n sourceSchema,\n targetSchema,\n sourceTask.config.id,\n targetTask.config.id,\n ([_fromOutputPortId, fromPortOutputSchema], [_toInputPortId, toPortInputSchema]) => {\n return isTypeCompatible(fromPortOutputSchema, toPortInputSchema, true);\n }\n );\n\n // Strategy 3: Look back through earlier tasks for unmatched required inputs\n // Extract required inputs from target schema\n const requiredInputs = new Set<string>(\n typeof targetSchema === \"object\" ? (targetSchema.required as string[]) || [] : []\n );\n\n // Filter out required inputs that are already provided in the input parameter\n // These don't need to be connected from previous tasks\n const requiredInputsNeedingConnection = [...requiredInputs].filter(\n (r) => !providedInputKeys.has(r)\n );\n\n // Compute unmatched required inputs (that aren't already provided)\n let unmatchedRequired = requiredInputsNeedingConnection.filter((r) => !matches.has(r));\n\n // If there are unmatched required inputs, iterate through earlier tasks\n if (unmatchedRequired.length > 0 && earlierTasks.length > 0) {\n for (let i = 0; i < earlierTasks.length && unmatchedRequired.length > 0; i++) {\n const earlierTask = earlierTasks[i];\n const earlierOutputSchema = earlierTask.outputSchema();\n\n // Helper function to match from an earlier task (only for unmatched required inputs)\n const makeMatchFromEarlier = (\n comparator: (\n [fromOutputPortId, fromPortOutputSchema]: [string, JsonSchema],\n [toInputPortId, toPortInputSchema]: [string, JsonSchema]\n ) => boolean\n ): void => {\n if (typeof earlierOutputSchema === \"boolean\" || typeof targetSchema === \"boolean\") {\n return;\n }\n\n for (const [fromOutputPortId, fromPortOutputSchema] of Object.entries(\n earlierOutputSchema.properties || {}\n )) {\n for (const requiredInputId of unmatchedRequired) {\n const toPortInputSchema = (targetSchema.properties as any)?.[requiredInputId];\n if (\n !matches.has(requiredInputId) &&\n toPortInputSchema &&\n comparator(\n [fromOutputPortId, fromPortOutputSchema],\n [requiredInputId, toPortInputSchema]\n )\n ) {\n matches.set(requiredInputId, fromOutputPortId);\n graph.addDataflow(\n new Dataflow(\n earlierTask.config.id,\n fromOutputPortId,\n targetTask.config.id,\n requiredInputId\n )\n );\n }\n }\n }\n };\n\n // Try both matching strategies for earlier tasks\n // Strategy 1: Match by type AND port name\n makeMatchFromEarlier(\n ([fromOutputPortId, fromPortOutputSchema], [toInputPortId, toPortInputSchema]) => {\n const outputPortIdMatch = fromOutputPortId === toInputPortId;\n const outputPortIdOutputInput =\n fromOutputPortId === \"output\" && toInputPortId === \"input\";\n const portIdsCompatible = outputPortIdMatch || outputPortIdOutputInput;\n\n return (\n portIdsCompatible && isTypeCompatible(fromPortOutputSchema, toPortInputSchema, false)\n );\n }\n );\n\n // Strategy 2: Match by specific type only\n makeMatchFromEarlier(\n ([_fromOutputPortId, fromPortOutputSchema], [_toInputPortId, toPortInputSchema]) => {\n return isTypeCompatible(fromPortOutputSchema, toPortInputSchema, true);\n }\n );\n\n // Update unmatched required inputs\n unmatchedRequired = unmatchedRequired.filter((r) => !matches.has(r));\n }\n }\n\n // Determine if there's an error\n const stillUnmatchedRequired = requiredInputsNeedingConnection.filter((r) => !matches.has(r));\n\n if (stillUnmatchedRequired.length > 0) {\n return {\n matches,\n error:\n `Could not find matches for required inputs [${stillUnmatchedRequired.join(\", \")}] of ${targetTask.type}. ` +\n `Attempted to match from ${sourceTask.type} and earlier tasks.`,\n unmatchedRequired: stillUnmatchedRequired,\n };\n }\n\n if (matches.size === 0 && requiredInputsNeedingConnection.length === 0) {\n // No matches were made AND no required inputs need connection\n // This happens in two cases:\n // 1. Task has required inputs, but they were all provided as parameters\n // 2. Task has no required inputs (all optional)\n\n // If task has required inputs that were all provided as parameters, allow the task\n const hasRequiredInputs = requiredInputs.size > 0;\n const allRequiredInputsProvided =\n hasRequiredInputs && [...requiredInputs].every((r) => providedInputKeys.has(r));\n\n // If no required inputs (all optional), check if there are defaults\n const hasInputsWithDefaults =\n typeof targetSchema === \"object\" &&\n targetSchema.properties &&\n Object.values(targetSchema.properties).some(\n (prop: any) => prop && typeof prop === \"object\" && \"default\" in prop\n );\n\n // Allow if:\n // - All required inputs were provided as parameters, OR\n // - No required inputs and task has defaults\n // Otherwise fail (no required inputs, no defaults, no matches)\n if (!allRequiredInputsProvided && !hasInputsWithDefaults) {\n return {\n matches,\n error:\n `Could not find a match between the outputs of ${sourceTask.type} and the inputs of ${targetTask.type}. ` +\n `You may need to connect the outputs to the inputs via connect() manually.`,\n unmatchedRequired: [],\n };\n }\n }\n\n return {\n matches,\n unmatchedRequired: [],\n };\n }\n\n /**\n * Finalizes the template graph and sets it on the iterator task.\n * Only applicable in loop builder mode.\n */\n public finalizeTemplate(): void {\n if (this._iteratorTask && this.graph.getTasks().length > 0) {\n this._iteratorTask.setTemplateGraph(this.graph);\n }\n }\n\n /**\n * Finalizes the template graph and returns the parent workflow.\n * Only applicable in loop builder mode.\n *\n * @returns The parent workflow\n * @throws WorkflowError if not in loop builder mode\n */\n public finalizeAndReturn(): Workflow {\n if (!this._parentWorkflow) {\n throw new WorkflowError(\"finalizeAndReturn() can only be called on loop workflows\");\n }\n this.finalizeTemplate();\n return this._parentWorkflow;\n }\n}\n",
21
20
  "/**\n * @license\n * Copyright 2025 Steven Roussey <sroussey@gmail.com>\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport { EventParameters } from \"@workglow/util\";\nimport { TaskIdType } from \"../task/TaskTypes\";\nimport { DataflowIdType } from \"./Dataflow\";\n\n/**\n * Events that can be emitted by the TaskGraph\n */\n\nexport type TaskGraphStatusListeners = {\n graph_progress: (progress: number, message?: string, ...args: any[]) => void;\n start: () => void;\n complete: () => void;\n error: (error: Error) => void;\n abort: () => void;\n disabled: () => void;\n};\nexport type TaskGraphStatusEvents = keyof TaskGraphStatusListeners;\nexport type TaskGraphStatusListener<Event extends TaskGraphStatusEvents> =\n TaskGraphStatusListeners[Event];\nexport type TaskGraphEventStatusParameters<Event extends TaskGraphStatusEvents> = EventParameters<\n TaskGraphStatusListeners,\n Event\n>;\n\nexport type GraphEventDagListeners = {\n task_added: (taskId: TaskIdType) => void;\n task_removed: (taskId: TaskIdType) => void;\n task_replaced: (taskId: TaskIdType) => void;\n dataflow_added: (dataflowId: DataflowIdType) => void;\n dataflow_removed: (dataflowId: DataflowIdType) => void;\n dataflow_replaced: (dataflowId: DataflowIdType) => void;\n};\nexport type GraphEventDagEvents = keyof GraphEventDagListeners;\nexport type GraphEventDagListener<Event extends GraphEventDagEvents> =\n GraphEventDagListeners[Event];\nexport type GraphEventDagParameters<Event extends GraphEventDagEvents> = EventParameters<\n GraphEventDagListeners,\n Event\n>;\n\nexport type TaskGraphListeners = TaskGraphStatusListeners & GraphEventDagListeners;\nexport type TaskGraphEvents = keyof TaskGraphListeners;\nexport type TaskGraphEventListener<Event extends TaskGraphEvents> = TaskGraphListeners[Event];\nexport type TaskGraphEventParameters<Event extends TaskGraphEvents> = EventParameters<\n TaskGraphListeners,\n Event\n>;\n\nexport const EventDagToTaskGraphMapping = {\n \"node-added\": \"task_added\",\n \"node-removed\": \"task_removed\",\n \"node-replaced\": \"task_replaced\",\n \"edge-added\": \"dataflow_added\",\n \"edge-removed\": \"dataflow_removed\",\n \"edge-replaced\": \"dataflow_replaced\",\n} as const;\n\nexport const EventTaskGraphToDagMapping = {\n task_added: \"node-added\",\n task_removed: \"node-removed\",\n task_replaced: \"node-replaced\",\n dataflow_added: \"edge-added\",\n dataflow_removed: \"edge-removed\",\n dataflow_replaced: \"edge-replaced\",\n} as const;\n",
22
- "/**\n * @license\n * Copyright 2025 Steven Roussey <sroussey@gmail.com>\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport { Job, JobConstructorParam, JobQueueClient, JobQueueServer } from \"@workglow/job-queue\";\nimport { InMemoryQueueStorage, IQueueStorage } from \"@workglow/storage\";\nimport { uuid4 } from \"@workglow/util\";\nimport { GraphResultArray } from \"../task-graph/TaskGraphRunner\";\nimport { GraphAsTaskRunner } from \"./GraphAsTaskRunner\";\nimport type { ExecutionMode, IteratorTask, IteratorTaskConfig } from \"./IteratorTask\";\nimport { getTaskQueueRegistry, RegisteredQueue } from \"./TaskQueueRegistry\";\nimport type { TaskConfig, TaskInput, TaskOutput } from \"./TaskTypes\";\n\n/**\n * Job class for iterator task items.\n * Wraps individual iteration execution.\n */\nclass IteratorItemJob<Input extends TaskInput, Output extends TaskOutput> extends Job<\n Input,\n Output\n> {\n /**\n * The task to execute for this iteration.\n */\n private iteratorTask: IteratorTask<Input, Output>;\n\n /**\n * The index of this iteration.\n */\n private iterationIndex: number;\n\n constructor(\n params: JobConstructorParam<Input, Output> & {\n iteratorTask: IteratorTask<Input, Output>;\n iterationIndex: number;\n }\n ) {\n super(params);\n this.iteratorTask = params.iteratorTask;\n this.iterationIndex = params.iterationIndex;\n }\n\n async execute(\n input: Input,\n context: { signal: AbortSignal; updateProgress: (progress: number) => void }\n ): Promise<Output> {\n // This would execute the subgraph for a single item\n // For now, return the input as output (placeholder)\n return input as unknown as Output;\n }\n}\n\n/**\n * Custom runner for IteratorTask that handles execution mode and queue integration.\n *\n * This runner manages:\n * - Dynamic queue creation based on execution mode\n * - Concurrency limiting for parallel-limited mode\n * - Sequential execution for sequential mode\n * - Batch grouping for batched mode\n */\nexport class IteratorTaskRunner<\n Input extends TaskInput = TaskInput,\n Output extends TaskOutput = TaskOutput,\n Config extends IteratorTaskConfig = IteratorTaskConfig,\n> extends GraphAsTaskRunner<Input, Output, Config> {\n declare task: IteratorTask<Input, Output, Config>;\n\n /**\n * The queue used for this iterator's executions.\n */\n protected iteratorQueue?: RegisteredQueue<Input, Output>;\n\n /**\n * Generated queue name for this iterator instance.\n */\n protected iteratorQueueName?: string;\n\n // ========================================================================\n // Queue Management\n // ========================================================================\n\n /**\n * Gets or creates the queue for this iterator based on execution mode.\n */\n protected async getOrCreateIteratorQueue(): Promise<RegisteredQueue<Input, Output> | undefined> {\n const executionMode = this.task.executionMode;\n\n // Parallel mode doesn't need a queue - just run everything\n if (executionMode === \"parallel\") {\n return undefined;\n }\n\n // Check if we already have a queue\n if (this.iteratorQueue) {\n return this.iteratorQueue;\n }\n\n // Generate queue name\n const queueName =\n this.task.config.queueName ?? `iterator-${this.task.config.id}-${uuid4().slice(0, 8)}`;\n this.iteratorQueueName = queueName;\n\n // Check registry first\n const existingQueue = getTaskQueueRegistry().getQueue<Input, Output>(queueName);\n if (existingQueue) {\n this.iteratorQueue = existingQueue;\n return existingQueue;\n }\n\n // Create new queue with appropriate concurrency\n const concurrency = this.getConcurrencyForMode(executionMode);\n this.iteratorQueue = await this.createIteratorQueue(queueName, concurrency);\n\n return this.iteratorQueue;\n }\n\n /**\n * Gets the concurrency level for the given execution mode.\n */\n protected getConcurrencyForMode(mode: ExecutionMode): number {\n switch (mode) {\n case \"sequential\":\n return 1;\n case \"parallel-limited\":\n return this.task.concurrencyLimit;\n case \"batched\":\n // For batched mode, we process one batch at a time\n // but items within a batch can be parallel\n return this.task.batchSize;\n case \"parallel\":\n default:\n return Infinity;\n }\n }\n\n /**\n * Creates a new queue for iterator execution.\n */\n protected async createIteratorQueue(\n queueName: string,\n concurrency: number\n ): Promise<RegisteredQueue<Input, Output>> {\n const storage = new InMemoryQueueStorage<Input, Output>(queueName);\n await storage.setupDatabase();\n\n // Create a simple job class for iteration items\n const JobClass = class extends Job<Input, Output> {\n async execute(input: Input): Promise<Output> {\n return input as unknown as Output;\n }\n };\n\n const server = new JobQueueServer<Input, Output>(JobClass, {\n storage: storage as IQueueStorage<Input, Output>,\n queueName,\n workerCount: Math.min(concurrency, 10), // Cap worker count\n });\n\n const client = new JobQueueClient<Input, Output>({\n storage: storage as IQueueStorage<Input, Output>,\n queueName,\n });\n\n client.attach(server);\n\n const queue: RegisteredQueue<Input, Output> = {\n server,\n client,\n storage: storage as IQueueStorage<Input, Output>,\n };\n\n // Register the queue\n try {\n getTaskQueueRegistry().registerQueue(queue);\n } catch (err) {\n // Queue might already exist from concurrent creation\n const existing = getTaskQueueRegistry().getQueue<Input, Output>(queueName);\n if (existing) {\n return existing;\n }\n throw err;\n }\n\n // Start the server\n await server.start();\n\n return queue;\n }\n\n // ========================================================================\n // Execution Overrides\n // ========================================================================\n\n /**\n * Execute the iterator's children based on execution mode.\n */\n protected async executeTaskChildren(input: Input): Promise<GraphResultArray<Output>> {\n const executionMode = this.task.executionMode;\n\n switch (executionMode) {\n case \"sequential\":\n return this.executeSequential(input);\n case \"parallel-limited\":\n return this.executeParallelLimited(input);\n case \"batched\":\n return this.executeBatched(input);\n case \"parallel\":\n default:\n // Use default parallel execution from parent\n return super.executeTaskChildren(input);\n }\n }\n\n /**\n * Execute iterations sequentially (one at a time).\n */\n protected async executeSequential(input: Input): Promise<GraphResultArray<Output>> {\n const tasks = this.task.subGraph.getTasks();\n const results: GraphResultArray<Output> = [];\n\n for (const task of tasks) {\n if (this.abortController?.signal.aborted) {\n break;\n }\n\n const taskResult = await task.run(input);\n results.push({\n id: task.config.id,\n type: task.type,\n data: taskResult as Output,\n });\n }\n\n return results;\n }\n\n /**\n * Execute iterations with a concurrency limit.\n */\n protected async executeParallelLimited(input: Input): Promise<GraphResultArray<Output>> {\n const tasks = this.task.subGraph.getTasks();\n const results: GraphResultArray<Output> = [];\n const limit = this.task.concurrencyLimit;\n\n // Process in chunks of 'limit' size\n for (let i = 0; i < tasks.length; i += limit) {\n if (this.abortController?.signal.aborted) {\n break;\n }\n\n const chunk = tasks.slice(i, i + limit);\n const chunkPromises = chunk.map(async (task) => {\n const taskResult = await task.run(input);\n return {\n id: task.config.id,\n type: task.type,\n data: taskResult as Output,\n };\n });\n\n const chunkResults = await Promise.all(chunkPromises);\n results.push(...chunkResults);\n }\n\n return results;\n }\n\n /**\n * Execute iterations in batches.\n */\n protected async executeBatched(input: Input): Promise<GraphResultArray<Output>> {\n const tasks = this.task.subGraph.getTasks();\n const results: GraphResultArray<Output> = [];\n const batchSize = this.task.batchSize;\n\n // Process in batches\n for (let i = 0; i < tasks.length; i += batchSize) {\n if (this.abortController?.signal.aborted) {\n break;\n }\n\n const batch = tasks.slice(i, i + batchSize);\n\n // Execute batch items in parallel\n const batchPromises = batch.map(async (task) => {\n const taskResult = await task.run(input);\n return {\n id: task.config.id,\n type: task.type,\n data: taskResult as Output,\n };\n });\n\n const batchResults = await Promise.all(batchPromises);\n results.push(...batchResults);\n\n // Emit progress for batch completion\n const progress = Math.round(((i + batch.length) / tasks.length) * 100);\n this.task.emit(\"progress\", progress, `Completed batch ${Math.ceil((i + 1) / batchSize)}`);\n }\n\n return results;\n }\n\n // ========================================================================\n // Cleanup\n // ========================================================================\n\n /**\n * Clean up the iterator queue when done.\n */\n protected async cleanup(): Promise<void> {\n if (this.iteratorQueue && this.iteratorQueueName) {\n try {\n this.iteratorQueue.server.stop();\n } catch (err) {\n // Ignore cleanup errors\n }\n }\n }\n}\n",
23
- "/**\n * @license\n * Copyright 2025 Steven Roussey <sroussey@gmail.com>\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport { JobQueueClient, JobQueueServer } from \"@workglow/job-queue\";\nimport { IQueueStorage } from \"@workglow/storage\";\n\n/**\n * Combined structure for a registered job queue containing server, client, and storage\n */\nexport interface RegisteredQueue<Input = unknown, Output = unknown> {\n readonly server: JobQueueServer<Input, Output>;\n readonly client: JobQueueClient<Input, Output>;\n readonly storage: IQueueStorage<Input, Output>;\n}\n\n/**\n * Global singleton instance of the TaskQueueRegistry.\n * This is used to manage all job queues across the application.\n */\nlet taskQueueRegistry: TaskQueueRegistry | null = null;\n\n/**\n * Registry for managing task queues in the application.\n * Provides functionality to register, manage, and control job queues.\n *\n * @template Input - The type of input data for tasks in the queues\n * @template Output - The type of output data for tasks in the queues\n */\nexport class TaskQueueRegistry {\n /**\n * Map of queue names to their corresponding registered queue instances\n */\n public readonly queues: Map<string, RegisteredQueue<unknown, unknown>> = new Map();\n\n /**\n * Registers a new job queue with the registry\n *\n * @param queue - The registered queue containing server, client, and storage\n * @throws Error if a queue with the same name already exists\n */\n registerQueue<Input, Output>(queue: RegisteredQueue<Input, Output>): void {\n const queueName = queue.server.queueName;\n if (this.queues.has(queueName)) {\n throw new Error(`Queue with name ${queueName} already exists`);\n }\n this.queues.set(queueName, queue as RegisteredQueue<unknown, unknown>);\n }\n\n /**\n * Retrieves a registered queue by its name\n *\n * @param queueName - The name of the queue to retrieve\n * @returns The registered queue or undefined if not found\n */\n getQueue<Input, Output>(queueName: string): RegisteredQueue<Input, Output> | undefined {\n return this.queues.get(queueName) as RegisteredQueue<Input, Output> | undefined;\n }\n\n /**\n * Starts all registered job queue servers\n * This allows queues to begin processing their jobs\n *\n * @returns The registry instance for chaining\n */\n startQueues(): this {\n for (const queue of this.queues.values()) {\n queue.server.start();\n }\n return this;\n }\n\n /**\n * Stops all registered job queue servers\n * This pauses job processing but maintains the queued jobs\n *\n * @returns The registry instance for chaining\n */\n stopQueues(): this {\n for (const queue of this.queues.values()) {\n queue.server.stop();\n }\n return this;\n }\n\n /**\n * Clears all registered job queues\n * This removes all queued jobs from the storage\n *\n * @returns The registry instance for chaining\n */\n clearQueues(): this {\n for (const queue of this.queues.values()) {\n queue.storage.deleteAll();\n }\n return this;\n }\n}\n\n/**\n * Gets the global TaskQueueRegistry instance\n * Creates a new instance if one doesn't exist\n *\n * @returns The global TaskQueueRegistry instance\n */\nexport function getTaskQueueRegistry(): TaskQueueRegistry {\n if (!taskQueueRegistry) {\n taskQueueRegistry = new TaskQueueRegistry();\n }\n return taskQueueRegistry;\n}\n\n/**\n * Sets the global TaskQueueRegistry instance\n * Stops and clears any existing registry before replacing it\n *\n * @param registry - The new registry instance to use, or null to clear\n */\nexport function setTaskQueueRegistry(registry: TaskQueueRegistry | null): void {\n if (taskQueueRegistry) {\n taskQueueRegistry.stopQueues();\n taskQueueRegistry.clearQueues();\n }\n taskQueueRegistry = registry;\n}\n",
24
- "/**\n * @license\n * Copyright 2025 Steven Roussey <sroussey@gmail.com>\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport type { DataPortSchema } from \"@workglow/util\";\nimport { TaskGraph } from \"../task-graph/TaskGraph\";\nimport { GraphAsTask, GraphAsTaskConfig } from \"./GraphAsTask\";\nimport type { IExecuteContext } from \"./ITask\";\nimport { IteratorTaskRunner } from \"./IteratorTaskRunner\";\nimport { TaskConfigurationError } from \"./TaskError\";\nimport type { TaskInput, TaskOutput, TaskTypeName } from \"./TaskTypes\";\n\n/**\n * Execution mode for iterator tasks.\n * - `parallel`: Execute all iterations concurrently (unlimited)\n * - `parallel-limited`: Execute with a concurrency limit\n * - `sequential`: Execute one at a time\n * - `batched`: Execute in batches of batchSize\n */\nexport type ExecutionMode = \"parallel\" | \"parallel-limited\" | \"sequential\" | \"batched\";\n\n/**\n * Configuration interface for IteratorTask.\n * Extends GraphAsTaskConfig with iterator-specific options.\n */\nexport interface IteratorTaskConfig extends GraphAsTaskConfig {\n /**\n * The execution mode for iterations.\n * @default \"parallel\"\n */\n readonly executionMode?: ExecutionMode;\n\n /**\n * Maximum number of concurrent iterations when executionMode is \"parallel-limited\".\n * @default 5\n */\n readonly concurrencyLimit?: number;\n\n /**\n * Number of items per batch when executionMode is \"batched\".\n * @default 10\n */\n readonly batchSize?: number;\n\n /**\n * Optional custom queue name for job queue integration.\n * If not provided, a unique queue name will be generated.\n */\n readonly queueName?: string;\n\n /**\n * The name of the input port containing the array to iterate.\n * If not provided, auto-detection will find the first array-typed port.\n */\n readonly iteratorPort?: string;\n}\n\n/**\n * Result of detecting the iterator port from the input schema.\n */\ninterface IteratorPortInfo {\n readonly portName: string;\n readonly itemSchema: DataPortSchema;\n}\n\n/**\n * Base class for iterator tasks that process collections of items.\n *\n * IteratorTask provides the foundation for loop-type tasks in the task graph.\n * It manages a subgraph of tasks that are executed for each item in a collection,\n * with configurable execution modes (parallel, sequential, batched, etc.).\n *\n * Subclasses should implement:\n * - `getIterableItems(input)`: Extract the items to iterate over from input\n * - Optionally override `collectResults()`: Define how to collect/merge results\n *\n * @template Input - The input type for the iterator task\n * @template Output - The output type for the iterator task\n * @template Config - The configuration type (must extend IteratorTaskConfig)\n */\nexport abstract class IteratorTask<\n Input extends TaskInput = TaskInput,\n Output extends TaskOutput = TaskOutput,\n Config extends IteratorTaskConfig = IteratorTaskConfig,\n> extends GraphAsTask<Input, Output, Config> {\n public static type: TaskTypeName = \"IteratorTask\";\n public static category: string = \"Flow Control\";\n public static title: string = \"Iterator\";\n public static description: string = \"Base class for loop-type tasks\";\n\n /** This task has dynamic schemas based on the inner workflow */\n public static hasDynamicSchemas: boolean = true;\n\n /**\n * The template subgraph that will be cloned for each iteration.\n * This is the workflow defined between forEach() and endForEach().\n */\n protected _templateGraph: TaskGraph | undefined;\n\n /**\n * Cached iterator port info from schema analysis.\n */\n protected _iteratorPortInfo: IteratorPortInfo | undefined;\n\n constructor(input: Partial<Input> = {}, config: Partial<Config> = {}) {\n super(input, config as Config);\n }\n\n // ========================================================================\n // TaskRunner Override\n // ========================================================================\n\n declare _runner: IteratorTaskRunner<Input, Output, Config>;\n\n /**\n * Gets the custom iterator task runner.\n */\n override get runner(): IteratorTaskRunner<Input, Output, Config> {\n if (!this._runner) {\n this._runner = new IteratorTaskRunner<Input, Output, Config>(this);\n }\n return this._runner;\n }\n\n // ========================================================================\n // Execution Mode Configuration\n // ========================================================================\n\n /**\n * Gets the execution mode for this iterator.\n */\n public get executionMode(): ExecutionMode {\n return this.config.executionMode ?? \"parallel\";\n }\n\n /**\n * Gets the concurrency limit for parallel-limited mode.\n */\n public get concurrencyLimit(): number {\n return this.config.concurrencyLimit ?? 5;\n }\n\n /**\n * Gets the batch size for batched mode.\n */\n public get batchSize(): number {\n return this.config.batchSize ?? 10;\n }\n\n // ========================================================================\n // Iterator Port Detection\n // ========================================================================\n\n /**\n * Auto-detects the iterator port from the input schema.\n * Finds the first property with type \"array\" or that has an \"items\" property.\n *\n * @returns The port info or undefined if no array port found\n */\n protected detectIteratorPort(): IteratorPortInfo | undefined {\n if (this._iteratorPortInfo) {\n return this._iteratorPortInfo;\n }\n\n // If explicitly configured, use that\n if (this.config.iteratorPort) {\n const schema = this.inputSchema();\n if (typeof schema === \"boolean\") return undefined;\n\n const portSchema = schema.properties?.[this.config.iteratorPort];\n if (portSchema && typeof portSchema === \"object\") {\n const itemSchema = (portSchema as any).items ?? { type: \"object\" };\n this._iteratorPortInfo = {\n portName: this.config.iteratorPort,\n itemSchema,\n };\n return this._iteratorPortInfo;\n }\n }\n\n // Auto-detect: find first array-typed port\n const schema = this.inputSchema();\n if (typeof schema === \"boolean\") return undefined;\n\n const properties = schema.properties || {};\n for (const [portName, portSchema] of Object.entries(properties)) {\n if (typeof portSchema !== \"object\" || portSchema === null) continue;\n\n const ps = portSchema as Record<string, unknown>;\n\n // Check if it's an array type\n if (ps.type === \"array\" || ps.items !== undefined) {\n const itemSchema = (ps.items as DataPortSchema) ?? {\n type: \"object\",\n properties: {},\n additionalProperties: true,\n };\n this._iteratorPortInfo = { portName, itemSchema };\n return this._iteratorPortInfo;\n }\n\n // Check oneOf/anyOf for array types\n const variants = (ps.oneOf ?? ps.anyOf) as unknown[] | undefined;\n if (Array.isArray(variants)) {\n for (const variant of variants) {\n if (typeof variant === \"object\" && variant !== null) {\n const v = variant as Record<string, unknown>;\n if (v.type === \"array\" || v.items !== undefined) {\n const itemSchema = (v.items as DataPortSchema) ?? {\n type: \"object\",\n properties: {},\n additionalProperties: true,\n };\n this._iteratorPortInfo = { portName, itemSchema };\n return this._iteratorPortInfo;\n }\n }\n }\n }\n }\n\n return undefined;\n }\n\n /**\n * Gets the name of the port containing the iterable collection.\n */\n public getIteratorPortName(): string | undefined {\n return this.detectIteratorPort()?.portName;\n }\n\n /**\n * Gets the schema for individual items in the collection.\n */\n public getItemSchema(): DataPortSchema {\n return (\n this.detectIteratorPort()?.itemSchema ?? {\n type: \"object\",\n properties: {},\n additionalProperties: true,\n }\n );\n }\n\n // ========================================================================\n // Iterable Items Extraction\n // ========================================================================\n\n /**\n * Extracts the items to iterate over from the input.\n * Subclasses can override this to provide custom extraction logic.\n *\n * @param input - The task input\n * @returns Array of items to iterate over\n */\n protected getIterableItems(input: Input): unknown[] {\n const portName = this.getIteratorPortName();\n if (!portName) {\n throw new TaskConfigurationError(\n `${this.type}: No array port found in input schema. ` +\n `Specify 'iteratorPort' in config or ensure input has an array-typed property.`\n );\n }\n\n const items = input[portName];\n if (items === undefined || items === null) {\n return [];\n }\n\n if (Array.isArray(items)) {\n return items;\n }\n\n // Single item - wrap in array\n return [items];\n }\n\n // ========================================================================\n // Template Graph Management\n // ========================================================================\n\n /**\n * Sets the template graph that defines the workflow to run for each iteration.\n * This is called by the Workflow builder when setting up the loop.\n *\n * Note: This does NOT call regenerateGraph() automatically because during\n * workflow construction, input data may not be available. The graph is\n * regenerated at execution time when actual input data is provided.\n */\n public setTemplateGraph(graph: TaskGraph): void {\n this._templateGraph = graph;\n // Don't regenerate here - wait for execution when input data is available\n this.events.emit(\"regenerate\");\n }\n\n /**\n * Gets the template graph.\n */\n public getTemplateGraph(): TaskGraph | undefined {\n return this._templateGraph;\n }\n\n // ========================================================================\n // Graph Regeneration\n // ========================================================================\n\n /**\n * Regenerates the subgraph based on the template and current input.\n * This creates cloned task instances for each item in the iteration.\n */\n public regenerateGraph(): void {\n // Clear the existing subgraph\n this.subGraph = new TaskGraph();\n\n // If no template or no items, emit and return\n if (!this._templateGraph || !this._templateGraph.getTasks().length) {\n super.regenerateGraph();\n return;\n }\n\n const items = this.getIterableItems(this.runInputData as Input);\n if (items.length === 0) {\n super.regenerateGraph();\n return;\n }\n\n // For each item, clone the template graph tasks\n this.createIterationTasks(items);\n\n super.regenerateGraph();\n }\n\n /**\n * Creates task instances for each iteration item.\n * Subclasses can override this for custom iteration behavior.\n *\n * @param items - The items to iterate over\n */\n protected createIterationTasks(items: unknown[]): void {\n const portName = this.getIteratorPortName();\n if (!portName) return;\n\n // Get all non-iterator input values to pass to each iteration\n const baseInput: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(this.runInputData)) {\n if (key !== portName) {\n baseInput[key] = value;\n }\n }\n\n // Create tasks for each item\n for (let i = 0; i < items.length; i++) {\n const item = items[i];\n const iterationInput = {\n ...baseInput,\n [portName]: item,\n _iterationIndex: i,\n _iterationItem: item,\n };\n\n // Clone template tasks for this iteration\n this.cloneTemplateForIteration(iterationInput, i);\n }\n }\n\n /**\n * Clones the template graph tasks for a single iteration.\n *\n * @param iterationInput - The input for this iteration\n * @param index - The iteration index\n */\n protected cloneTemplateForIteration(\n iterationInput: Record<string, unknown>,\n index: number\n ): void {\n if (!this._templateGraph) return;\n\n const templateTasks = this._templateGraph.getTasks();\n const templateDataflows = this._templateGraph.getDataflows();\n\n // Map from template task ID to cloned task ID\n const idMap = new Map<unknown, unknown>();\n\n // Clone each task\n for (const templateTask of templateTasks) {\n const TaskClass = templateTask.constructor as any;\n const clonedTask = new TaskClass(\n { ...templateTask.defaults, ...iterationInput },\n {\n ...templateTask.config,\n id: `${templateTask.config.id}_iter${index}`,\n name: `${templateTask.config.name || templateTask.type} [${index}]`,\n }\n );\n\n this.subGraph.addTask(clonedTask);\n idMap.set(templateTask.config.id, clonedTask.config.id);\n }\n\n // Clone dataflows with updated IDs\n for (const templateDataflow of templateDataflows) {\n const sourceId = idMap.get(templateDataflow.sourceTaskId);\n const targetId = idMap.get(templateDataflow.targetTaskId);\n\n if (sourceId !== undefined && targetId !== undefined) {\n const { Dataflow } = require(\"../task-graph/Dataflow\");\n const clonedDataflow = new Dataflow(\n sourceId,\n templateDataflow.sourceTaskPortId,\n targetId,\n templateDataflow.targetTaskPortId\n );\n this.subGraph.addDataflow(clonedDataflow);\n }\n }\n }\n\n // ========================================================================\n // Execution\n // ========================================================================\n\n /**\n * Execute the iterator task.\n * Sets up the iteration and delegates to the parent GraphAsTask execution.\n */\n public async execute(input: Input, context: IExecuteContext): Promise<Output | undefined> {\n // Ensure we have items to iterate\n const items = this.getIterableItems(input);\n if (items.length === 0) {\n return this.getEmptyResult();\n }\n\n // Regenerate graph with current input\n this.runInputData = { ...this.defaults, ...input };\n this.regenerateGraph();\n\n // Let the parent handle subgraph execution\n return super.execute(input, context);\n }\n\n /**\n * Returns the result when there are no items to iterate.\n * Subclasses should override this to return appropriate empty results.\n */\n protected getEmptyResult(): Output {\n return {} as Output;\n }\n\n // ========================================================================\n // Result Collection\n // ========================================================================\n\n /**\n * Collects and merges results from all iterations.\n * Subclasses can override this for custom result handling.\n *\n * @param results - Array of results from each iteration\n * @returns Merged output\n */\n protected collectResults(results: TaskOutput[]): Output {\n // Default: use the GraphAsTask's PROPERTY_ARRAY merge strategy\n // which collects values into arrays per property\n return results as unknown as Output;\n }\n\n // ========================================================================\n // Schema Methods\n // ========================================================================\n\n /**\n * Input schema for the iterator.\n * Returns the static schema since the iterator accepts the full array.\n */\n public inputSchema(): DataPortSchema {\n // If we have a template graph, derive from its starting nodes\n if (this.hasChildren() || this._templateGraph) {\n return super.inputSchema();\n }\n return (this.constructor as typeof IteratorTask).inputSchema();\n }\n\n /**\n * Output schema for the iterator.\n * Subclasses should override to define their specific output structure.\n */\n public outputSchema(): DataPortSchema {\n // Default: wrap inner output properties in arrays\n if (!this.hasChildren() && !this._templateGraph) {\n return (this.constructor as typeof IteratorTask).outputSchema();\n }\n\n return this.getWrappedOutputSchema();\n }\n\n /**\n * Gets the output schema with properties wrapped in arrays.\n * Used by MapTask and similar tasks that collect results.\n */\n protected getWrappedOutputSchema(): DataPortSchema {\n const templateGraph = this._templateGraph ?? this.subGraph;\n if (!templateGraph) {\n return { type: \"object\", properties: {}, additionalProperties: false };\n }\n\n // Get ending nodes in the template\n const tasks = templateGraph.getTasks();\n const endingNodes = tasks.filter(\n (task) => templateGraph.getTargetDataflows(task.config.id).length === 0\n );\n\n if (endingNodes.length === 0) {\n return { type: \"object\", properties: {}, additionalProperties: false };\n }\n\n const properties: Record<string, unknown> = {};\n\n for (const task of endingNodes) {\n const taskOutputSchema = task.outputSchema();\n if (typeof taskOutputSchema === \"boolean\") continue;\n\n const taskProperties = taskOutputSchema.properties || {};\n for (const [key, schema] of Object.entries(taskProperties)) {\n // Wrap in array\n properties[key] = {\n type: \"array\",\n items: schema,\n };\n }\n }\n\n return {\n type: \"object\",\n properties,\n additionalProperties: false,\n } as DataPortSchema;\n }\n}\n",
25
- "/**\n * @license\n * Copyright 2025 Steven Roussey <sroussey@gmail.com>\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport { type DataPortSchema } from \"@workglow/util\";\nimport { TaskGraph } from \"../task-graph/TaskGraph\";\nimport { PROPERTY_ARRAY } from \"../task-graph/TaskGraphRunner\";\nimport {\n CreateEndLoopWorkflow,\n CreateLoopWorkflow,\n Workflow,\n} from \"../task-graph/Workflow\";\nimport { IteratorTask, IteratorTaskConfig } from \"./IteratorTask\";\nimport type { TaskInput, TaskOutput, TaskTypeName } from \"./TaskTypes\";\n\n/**\n * Configuration for BatchTask.\n */\nexport interface BatchTaskConfig extends IteratorTaskConfig {\n /**\n * Number of items per batch.\n * @default 10\n */\n readonly batchSize?: number;\n\n /**\n * Whether to flatten results from all batches into a single array.\n * When false, results are grouped by batch.\n * @default true\n */\n readonly flattenResults?: boolean;\n\n /**\n * Whether to execute batches in parallel or sequentially.\n * @default \"sequential\"\n */\n readonly batchExecutionMode?: \"parallel\" | \"sequential\";\n}\n\n/**\n * BatchTask processes an array in configurable chunks/batches.\n *\n * This task is useful for:\n * - Rate-limited API calls that accept multiple items\n * - Memory-constrained processing\n * - Progress tracking at batch granularity\n *\n * ## Features\n *\n * - Groups array into chunks of batchSize\n * - Runs inner workflow per batch (receives array of items)\n * - Configurable batch and within-batch execution\n * - Optional result flattening\n *\n * ## Usage\n *\n * ```typescript\n * // Process in batches of 10\n * workflow\n * .input({ documents: [...100 docs...] })\n * .batch({ batchSize: 10 })\n * .bulkEmbed()\n * .bulkStore()\n * .endBatch()\n *\n * // Sequential batches for rate limiting\n * workflow\n * .batch({ batchSize: 5, batchExecutionMode: \"sequential\" })\n * .apiCall()\n * .endBatch()\n * ```\n *\n * @template Input - The input type containing the array to batch\n * @template Output - The output type (collected batch results)\n * @template Config - The configuration type\n */\nexport class BatchTask<\n Input extends TaskInput = TaskInput,\n Output extends TaskOutput = TaskOutput,\n Config extends BatchTaskConfig = BatchTaskConfig,\n> extends IteratorTask<Input, Output, Config> {\n public static type: TaskTypeName = \"BatchTask\";\n public static category: string = \"Flow Control\";\n public static title: string = \"Batch\";\n public static description: string = \"Processes an array in configurable batches\";\n\n /**\n * BatchTask always uses PROPERTY_ARRAY merge strategy.\n */\n public static readonly compoundMerge = PROPERTY_ARRAY;\n\n /**\n * Static input schema for BatchTask.\n */\n public static inputSchema(): DataPortSchema {\n return {\n type: \"object\",\n properties: {},\n additionalProperties: true,\n } as const satisfies DataPortSchema;\n }\n\n /**\n * Static output schema for BatchTask.\n */\n public static outputSchema(): DataPortSchema {\n return {\n type: \"object\",\n properties: {},\n additionalProperties: true,\n } as const satisfies DataPortSchema;\n }\n\n /**\n * Gets the batch size.\n */\n public override get batchSize(): number {\n return this.config.batchSize ?? 10;\n }\n\n /**\n * Whether to flatten results from all batches.\n */\n public get flattenResults(): boolean {\n return this.config.flattenResults ?? true;\n }\n\n /**\n * Batch execution mode.\n */\n public get batchExecutionMode(): \"parallel\" | \"sequential\" {\n return this.config.batchExecutionMode ?? \"sequential\";\n }\n\n /**\n * Override to group items into batches instead of individual items.\n */\n protected override getIterableItems(input: Input): unknown[] {\n const items = super.getIterableItems(input);\n return this.groupIntoBatches(items);\n }\n\n /**\n * Groups items into batches of batchSize.\n */\n protected groupIntoBatches(items: unknown[]): unknown[][] {\n const batches: unknown[][] = [];\n const size = this.batchSize;\n\n for (let i = 0; i < items.length; i += size) {\n batches.push(items.slice(i, i + size));\n }\n\n return batches;\n }\n\n /**\n * Creates iteration tasks for batches.\n * Each batch receives the array of items for that batch.\n */\n protected override createIterationTasks(batches: unknown[]): void {\n const portName = this.getIteratorPortName();\n if (!portName) return;\n\n // Get all non-iterator input values\n const baseInput: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(this.runInputData)) {\n if (key !== portName) {\n baseInput[key] = value;\n }\n }\n\n // Create tasks for each batch\n for (let i = 0; i < batches.length; i++) {\n const batch = batches[i];\n const batchInput = {\n ...baseInput,\n [portName]: batch, // Batch is an array of items\n _batchIndex: i,\n _batchItems: batch,\n };\n\n this.cloneTemplateForIteration(batchInput, i);\n }\n }\n\n /**\n * Returns the empty result for BatchTask.\n */\n protected override getEmptyResult(): Output {\n const schema = this.outputSchema();\n if (typeof schema === \"boolean\") {\n return {} as Output;\n }\n\n const result: Record<string, unknown[]> = {};\n for (const key of Object.keys(schema.properties || {})) {\n result[key] = [];\n }\n\n return result as Output;\n }\n\n /**\n * Output schema for BatchTask.\n * Similar to MapTask - wraps inner outputs in arrays.\n */\n public override outputSchema(): DataPortSchema {\n if (!this.hasChildren() && !this._templateGraph) {\n return (this.constructor as typeof BatchTask).outputSchema();\n }\n\n return this.getWrappedOutputSchema();\n }\n\n /**\n * Collects and optionally flattens results from all batches.\n */\n protected override collectResults(results: TaskOutput[]): Output {\n const collected = super.collectResults(results);\n\n if (!this.flattenResults || typeof collected !== \"object\" || collected === null) {\n return collected;\n }\n\n // Flatten nested arrays (from batch results)\n const flattened: Record<string, unknown[]> = {};\n for (const [key, value] of Object.entries(collected)) {\n if (Array.isArray(value)) {\n // Deep flatten for batch results\n flattened[key] = value.flat(2);\n } else {\n flattened[key] = value as unknown[];\n }\n }\n\n return flattened as Output;\n }\n\n /**\n * Regenerates the graph for batch execution.\n */\n public override regenerateGraph(): void {\n // Clear the existing subgraph\n this.subGraph = new TaskGraph();\n\n if (!this._templateGraph || !this._templateGraph.getTasks().length) {\n super.regenerateGraph();\n return;\n }\n\n const batches = this.getIterableItems(this.runInputData as Input);\n if (batches.length === 0) {\n super.regenerateGraph();\n return;\n }\n\n // Create tasks for each batch\n this.createIterationTasks(batches);\n\n // Emit regenerate event\n this.events.emit(\"regenerate\");\n }\n}\n\n// ============================================================================\n// Workflow Prototype Extensions\n// ============================================================================\n\ndeclare module \"../task-graph/Workflow\" {\n interface Workflow {\n /**\n * Starts a batch loop that processes arrays in chunks.\n * Use .endBatch() to close the loop and return to the parent workflow.\n *\n * @param config - Configuration for the batch loop\n * @returns A Workflow in loop builder mode for defining the batch processing\n *\n * @example\n * ```typescript\n * workflow\n * .batch({ batchSize: 10 })\n * .bulkProcess()\n * .endBatch()\n * ```\n */\n // batch(config?: Partial<BatchTaskConfig>): Workflow;\n batch: CreateLoopWorkflow<TaskInput, TaskOutput, BatchTaskConfig>;\n\n /**\n * Ends the batch loop and returns to the parent workflow.\n * Only callable on workflows in loop builder mode.\n *\n * @returns The parent workflow\n */\n endBatch(): Workflow;\n }\n}\n\nWorkflow.prototype.batch = CreateLoopWorkflow(BatchTask);\n\nWorkflow.prototype.endBatch = CreateEndLoopWorkflow(\"endBatch\");\n",
26
- "/**\n * @license\n * Copyright 2025 Steven Roussey <sroussey@gmail.com>\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport type { DataPortSchema } from \"@workglow/util\";\nimport {\n CreateEndLoopWorkflow,\n CreateLoopWorkflow,\n Workflow,\n} from \"../task-graph/Workflow\";\nimport { IteratorTask, IteratorTaskConfig } from \"./IteratorTask\";\nimport type { TaskInput, TaskOutput, TaskTypeName } from \"./TaskTypes\";\n\n/**\n * Configuration for ForEachTask.\n */\nexport interface ForEachTaskConfig extends IteratorTaskConfig {\n /**\n * Whether to collect and return results from each iteration.\n * When false (default), ForEachTask is optimized for side effects.\n * When true, results are collected but not transformed.\n * @default false\n */\n readonly shouldCollectResults?: boolean;\n}\n\n/**\n * ForEachTask iterates over an array and runs a workflow for each element.\n *\n * This task is optimized for side-effect operations where the primary goal\n * is to process each item rather than collect transformed results.\n * For transformations that collect results, use MapTask instead.\n *\n * ## Features\n *\n * - Iterates over array input\n * - Runs inner workflow for each element\n * - Configurable execution modes (parallel, sequential, etc.)\n * - Optimized for side effects (default: doesn't collect results)\n *\n * ## Usage\n *\n * ```typescript\n * // Using Workflow API\n * workflow\n * .input({ items: [\"a\", \"b\", \"c\"] })\n * .forEach()\n * .processItem()\n * .saveToDatabase()\n * .endForEach()\n *\n * // With sequential execution\n * workflow\n * .forEach({ executionMode: \"sequential\" })\n * .processItem()\n * .endForEach()\n * ```\n *\n * @template Input - The input type containing the array to iterate\n * @template Output - The output type (typically empty for side-effect operations)\n * @template Config - The configuration type\n */\nexport class ForEachTask<\n Input extends TaskInput = TaskInput,\n Output extends TaskOutput = TaskOutput,\n Config extends ForEachTaskConfig = ForEachTaskConfig,\n> extends IteratorTask<Input, Output, Config> {\n public static type: TaskTypeName = \"ForEachTask\";\n public static category: string = \"Flow Control\";\n public static title: string = \"For Each\";\n public static description: string = \"Iterates over an array and runs a workflow for each element\";\n\n /**\n * Static input schema for ForEachTask.\n * Accepts any object with at least one array property.\n */\n public static inputSchema(): DataPortSchema {\n return {\n type: \"object\",\n properties: {},\n additionalProperties: true,\n } as const satisfies DataPortSchema;\n }\n\n /**\n * Static output schema for ForEachTask.\n * By default, returns an empty object (side-effect focused).\n */\n public static outputSchema(): DataPortSchema {\n return {\n type: \"object\",\n properties: {\n completed: {\n type: \"boolean\",\n title: \"Completed\",\n description: \"Whether all iterations completed successfully\",\n },\n count: {\n type: \"number\",\n title: \"Count\",\n description: \"Number of items processed\",\n },\n },\n additionalProperties: false,\n } as const satisfies DataPortSchema;\n }\n\n /**\n * Whether to collect results from iterations.\n */\n public get shouldCollectResults(): boolean {\n return this.config.shouldCollectResults ?? false;\n }\n\n /**\n * Returns the empty result for ForEachTask.\n * Indicates completion with zero items processed.\n */\n protected override getEmptyResult(): Output {\n return {\n completed: true,\n count: 0,\n } as unknown as Output;\n }\n\n /**\n * Output schema for ForEachTask instance.\n * If shouldCollectResults is enabled, wraps inner output in arrays.\n * Otherwise, returns the simple completion status schema.\n */\n public override outputSchema(): DataPortSchema {\n if (this.shouldCollectResults && (this.hasChildren() || this._templateGraph)) {\n // When collecting results, wrap inner outputs in arrays\n return this.getWrappedOutputSchema();\n }\n\n // Default: simple completion status\n return (this.constructor as typeof ForEachTask).outputSchema();\n }\n\n /**\n * Collects results from all iterations.\n * For ForEachTask, this primarily returns completion status.\n */\n protected override collectResults(results: TaskOutput[]): Output {\n if (this.config.shouldCollectResults) {\n // When collecting, return the wrapped results\n return super.collectResults(results);\n }\n\n // Default: return completion status\n return {\n completed: true,\n count: results.length,\n } as unknown as Output;\n }\n}\n\n// ============================================================================\n// Workflow Prototype Extensions\n// ============================================================================\n\ndeclare module \"../task-graph/Workflow\" {\n interface Workflow {\n /**\n * Starts a forEach loop that iterates over an array.\n * Use .endForEach() to close the loop and return to the parent workflow.\n *\n * @param config - Configuration for the forEach loop\n * @returns A Workflow in loop builder mode for defining the loop body\n *\n * @example\n * ```typescript\n * workflow\n * .forEach({ executionMode: \"sequential\" })\n * .processItem()\n * .endForEach()\n * ```\n */\n forEach: CreateLoopWorkflow<TaskInput, TaskOutput, ForEachTaskConfig>;\n\n /**\n * Ends the forEach loop and returns to the parent workflow.\n * Only callable on workflows in loop builder mode.\n *\n * @returns The parent workflow\n */\n endForEach(): Workflow;\n }\n}\n\nWorkflow.prototype.forEach = CreateLoopWorkflow(ForEachTask);\n\nWorkflow.prototype.endForEach = CreateEndLoopWorkflow(\"endForEach\");\n",
27
21
  "/**\n * @license\n * Copyright 2025 Steven Roussey <sroussey@gmail.com>\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {\n Job,\n JobConstructorParam,\n JobQueueClient,\n JobQueueServer,\n JobQueueServerOptions,\n} from \"@workglow/job-queue\";\nimport { InMemoryQueueStorage, IQueueStorage } from \"@workglow/storage\";\nimport { createServiceToken, globalServiceRegistry } from \"@workglow/util\";\nimport type { JobQueueTask, JobQueueTaskConfig } from \"./JobQueueTask\";\nimport type { RegisteredQueue } from \"./TaskQueueRegistry\";\nimport type { TaskInput, TaskOutput } from \"./TaskTypes\";\n\nexport type JobClassConstructor<Input extends TaskInput, Output extends TaskOutput> = new (\n params: JobConstructorParam<Input, Output>\n) => Job<Input, Output>;\n\n/**\n * Options for creating a job queue via the factory\n */\nexport interface JobQueueFactoryOptions<Input, Output> {\n readonly storage?: IQueueStorage<Input, Output>;\n readonly limiter?: JobQueueServerOptions<Input, Output>[\"limiter\"];\n readonly workerCount?: number;\n readonly pollIntervalMs?: number;\n readonly deleteAfterCompletionMs?: number;\n readonly deleteAfterFailureMs?: number;\n readonly deleteAfterDisabledMs?: number;\n readonly cleanupIntervalMs?: number;\n}\n\nexport interface JobQueueFactoryParams<Input extends TaskInput, Output extends TaskOutput> {\n readonly queueName: string;\n readonly jobClass: JobClassConstructor<Input, Output>;\n readonly input?: Input;\n readonly config?: JobQueueTaskConfig;\n readonly task?: JobQueueTask<Input, Output>;\n readonly options?: JobQueueFactoryOptions<Input, Output>;\n}\n\nexport type JobQueueFactory = <Input extends TaskInput, Output extends TaskOutput>(\n params: JobQueueFactoryParams<Input, Output>\n) => Promise<RegisteredQueue<Input, Output>> | RegisteredQueue<Input, Output>;\n\nexport const JOB_QUEUE_FACTORY = createServiceToken<JobQueueFactory>(\"taskgraph.jobQueueFactory\");\n\nconst defaultJobQueueFactory: JobQueueFactory = async <\n Input extends TaskInput,\n Output extends TaskOutput,\n>({\n queueName,\n jobClass,\n options,\n}: JobQueueFactoryParams<Input, Output>): Promise<RegisteredQueue<Input, Output>> => {\n const storage =\n (options?.storage as IQueueStorage<Input, Output>) ??\n new InMemoryQueueStorage<Input, Output>(queueName);\n await storage.setupDatabase();\n\n const server = new JobQueueServer<Input, Output>(jobClass as JobClassConstructor<any, any>, {\n storage,\n queueName,\n limiter: options?.limiter,\n workerCount: options?.workerCount,\n pollIntervalMs: options?.pollIntervalMs,\n deleteAfterCompletionMs: options?.deleteAfterCompletionMs,\n deleteAfterFailureMs: options?.deleteAfterFailureMs,\n deleteAfterDisabledMs: options?.deleteAfterDisabledMs,\n cleanupIntervalMs: options?.cleanupIntervalMs,\n });\n\n const client = new JobQueueClient<Input, Output>({\n storage,\n queueName,\n });\n\n // Attach client to server for same-process optimization\n client.attach(server);\n\n return { server, client, storage };\n};\n\nexport function registerJobQueueFactory(factory: JobQueueFactory): void {\n globalServiceRegistry.registerInstance(JOB_QUEUE_FACTORY, factory);\n}\n\n/**\n * Creates a job queue factory from server options\n */\nexport function createJobQueueFactoryWithOptions(\n defaultOptions: Partial<JobQueueFactoryOptions<unknown, unknown>> = {}\n): JobQueueFactory {\n return async <Input extends TaskInput, Output extends TaskOutput>({\n queueName,\n jobClass,\n options,\n }: JobQueueFactoryParams<Input, Output>): Promise<RegisteredQueue<Input, Output>> => {\n const mergedOptions = {\n ...defaultOptions,\n ...(options ?? {}),\n } as JobQueueFactoryOptions<Input, Output>;\n\n const storage =\n (mergedOptions.storage as IQueueStorage<Input, Output>) ??\n new InMemoryQueueStorage<Input, Output>(queueName);\n await storage.setupDatabase();\n\n const server = new JobQueueServer<Input, Output>(jobClass as JobClassConstructor<any, any>, {\n storage,\n queueName,\n limiter: mergedOptions.limiter,\n workerCount: mergedOptions.workerCount,\n pollIntervalMs: mergedOptions.pollIntervalMs,\n deleteAfterCompletionMs: mergedOptions.deleteAfterCompletionMs,\n deleteAfterFailureMs: mergedOptions.deleteAfterFailureMs,\n deleteAfterDisabledMs: mergedOptions.deleteAfterDisabledMs,\n cleanupIntervalMs: mergedOptions.cleanupIntervalMs,\n });\n\n const client = new JobQueueClient<Input, Output>({\n storage,\n queueName,\n });\n\n // Attach client to server for same-process optimization\n client.attach(server);\n\n return { server, client, storage };\n };\n}\n\nexport function getJobQueueFactory(): JobQueueFactory {\n if (!globalServiceRegistry.has(JOB_QUEUE_FACTORY)) {\n registerJobQueueFactory(defaultJobQueueFactory);\n }\n return globalServiceRegistry.get(JOB_QUEUE_FACTORY);\n}\n\nif (!globalServiceRegistry.has(JOB_QUEUE_FACTORY)) {\n registerJobQueueFactory(defaultJobQueueFactory);\n}\n",
28
22
  "/**\n * @license\n * Copyright 2025 Steven Roussey <sroussey@gmail.com>\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport { Job, JobConstructorParam } from \"@workglow/job-queue\";\nimport { GraphAsTask } from \"./GraphAsTask\";\nimport { IExecuteContext } from \"./ITask\";\nimport { getJobQueueFactory } from \"./JobQueueFactory\";\nimport { JobTaskFailedError, TaskConfigurationError } from \"./TaskError\";\nimport { TaskEventListeners } from \"./TaskEvents\";\nimport { getTaskQueueRegistry, RegisteredQueue } from \"./TaskQueueRegistry\";\nimport { TaskConfig, TaskInput, TaskOutput } from \"./TaskTypes\";\n\n/**\n * Configuration interface for JobQueueTask.\n * Extends the base TaskConfig with job queue specific properties.\n */\nexport interface JobQueueTaskConfig extends TaskConfig {\n /**\n * Queue selection for the task\n * - `true` (default): create/use the task's default queue\n * - `false`: run directly without queueing (requires `canRunDirectly`)\n * - `string`: use an explicitly registered queue name\n */\n queue?: boolean | string;\n}\n\n/**\n * Extended event listeners for JobQueueTask.\n * Adds progress event handling to base task event listeners.\n */\nexport type JobQueueTaskEventListeners = Omit<TaskEventListeners, \"progress\"> & {\n progress: (progress: number, message?: string, details?: Record<string, any> | null) => void;\n};\n\n/**\n * Abstract base class for tasks that operate within a job queue.\n * Provides functionality for managing job execution, progress tracking, and queue integration.\n *\n * @template Input - Type of input data for the task\n * @template Output - Type of output data produced by the task\n * @template Config - Type of configuration object for the task\n */\nexport abstract class JobQueueTask<\n Input extends TaskInput = TaskInput,\n Output extends TaskOutput = TaskOutput,\n Config extends JobQueueTaskConfig = JobQueueTaskConfig,\n> extends GraphAsTask<Input, Output, Config> {\n static readonly type: string = \"JobQueueTask\";\n static canRunDirectly = true;\n\n /** Name of the queue currently processing the task */\n currentQueueName?: string;\n /** ID of the current job being processed */\n currentJobId?: string | unknown;\n /** ID of the current runner being used */\n currentRunnerId?: string;\n\n public jobClass: new (config: JobConstructorParam<Input, Output>) => Job<Input, Output>;\n\n constructor(input: Partial<Input> = {} as Input, config: Config = {} as Config) {\n config.queue ??= true;\n super(input, config);\n this.jobClass = Job as unknown as new (\n config: JobConstructorParam<Input, Output>\n ) => Job<Input, Output>;\n }\n\n async execute(input: Input, executeContext: IExecuteContext): Promise<Output | undefined> {\n let cleanup: () => void = () => {};\n\n try {\n if (\n this.config.queue === false &&\n !(this.constructor as typeof JobQueueTask).canRunDirectly\n ) {\n throw new TaskConfigurationError(`${this.type} cannot run directly without a queue`);\n }\n\n const registeredQueue = await this.resolveQueue(input);\n\n if (!registeredQueue) {\n // Direct execution without a queue\n if (!(this.constructor as typeof JobQueueTask).canRunDirectly) {\n const queueLabel =\n typeof this.config.queue === \"string\"\n ? this.config.queue\n : (this.currentQueueName ?? this.type);\n throw new TaskConfigurationError(\n `Queue ${queueLabel} not found, and ${this.type} cannot run directly`\n );\n }\n this.currentJobId = undefined;\n\n // Create job for direct execution\n const job = await this.createJob(input, this.currentQueueName);\n cleanup = job.onJobProgress(\n (progress: number, message: string, details: Record<string, any> | null) => {\n executeContext.updateProgress(progress, message, details);\n }\n );\n const output = await job.execute(job.input, {\n signal: executeContext.signal,\n updateProgress: executeContext.updateProgress.bind(this),\n });\n return output;\n }\n\n // Execute via queue\n const { client } = registeredQueue;\n const jobInput = await this.getJobInput(input);\n const handle = await client.submit(jobInput as Input, {\n jobRunId: this.currentRunnerId,\n maxRetries: 10,\n });\n\n this.currentJobId = handle.id;\n this.currentQueueName = client.queueName;\n\n cleanup = handle.onProgress((progress, message, details) => {\n executeContext.updateProgress(progress, message, details);\n });\n\n const output = await handle.waitFor();\n if (output === undefined) {\n throw new TaskConfigurationError(\"Job disabled, should not happen\");\n }\n\n return output as Output;\n } catch (err: any) {\n throw new JobTaskFailedError(err);\n } finally {\n cleanup();\n }\n }\n\n /**\n * Get the input to submit to the job queue.\n * Override this method to transform task input to job input.\n * @param input - The task input\n * @returns The input to submit to the job queue\n */\n protected async getJobInput(input: Input): Promise<unknown> {\n return input;\n }\n\n /**\n * Override this method to create the right job class for direct execution (without a queue).\n * This is used when running the task directly without queueing.\n * @param input - The task input\n * @param queueName - The queue name (if any)\n * @returns Promise<Job> - The created job\n */\n async createJob(input: Input, queueName?: string): Promise<Job<any, Output>> {\n return new this.jobClass({\n queueName: queueName ?? this.currentQueueName,\n jobRunId: this.currentRunnerId, // could be undefined\n input: input,\n });\n }\n\n protected async resolveQueue(input: Input): Promise<RegisteredQueue<Input, Output> | undefined> {\n const preference = this.config.queue ?? true;\n\n if (preference === false) {\n this.currentQueueName = undefined;\n return undefined;\n }\n\n if (typeof preference === \"string\") {\n const registeredQueue = getTaskQueueRegistry().getQueue<Input, Output>(preference);\n if (registeredQueue) {\n this.currentQueueName = registeredQueue.server.queueName;\n return registeredQueue;\n }\n this.currentQueueName = preference;\n return undefined;\n }\n\n const queueName = await this.getDefaultQueueName(input);\n if (!queueName) {\n this.currentQueueName = undefined;\n return undefined;\n }\n\n this.currentQueueName = queueName;\n\n let registeredQueue = getTaskQueueRegistry().getQueue<Input, Output>(queueName);\n if (!registeredQueue) {\n registeredQueue = await this.createAndRegisterQueue(queueName, input);\n await registeredQueue.server.start();\n }\n\n return registeredQueue;\n }\n\n protected async getDefaultQueueName(_input: Input): Promise<string | undefined> {\n return this.type;\n }\n\n protected async createAndRegisterQueue(\n queueName: string,\n input: Input\n ): Promise<RegisteredQueue<Input, Output>> {\n const factory = getJobQueueFactory();\n let registeredQueue = await factory({\n queueName,\n jobClass: this.jobClass,\n input,\n config: this.config,\n task: this,\n });\n\n const registry = getTaskQueueRegistry();\n\n try {\n registry.registerQueue(registeredQueue);\n } catch (err) {\n if (err instanceof Error && err.message.includes(\"already exists\")) {\n const existing = registry.getQueue<Input, Output>(queueName);\n if (existing) {\n registeredQueue = existing;\n }\n } else {\n throw err;\n }\n }\n\n return registeredQueue;\n }\n\n /**\n * Aborts the task\n * @returns A promise that resolves when the task is aborted\n */\n async abort(): Promise<void> {\n if (this.currentQueueName && this.currentJobId) {\n const registeredQueue = getTaskQueueRegistry().getQueue(this.currentQueueName);\n if (registeredQueue) {\n await registeredQueue.client.abort(this.currentJobId);\n }\n }\n // Always call the parent abort to ensure the task is properly marked as aborted\n super.abort();\n }\n}\n",
29
- "/**\n * @license\n * Copyright 2025 Steven Roussey <sroussey@gmail.com>\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport type { DataPortSchema } from \"@workglow/util\";\nimport { PROPERTY_ARRAY } from \"../task-graph/TaskGraphRunner\";\nimport {\n CreateEndLoopWorkflow,\n CreateLoopWorkflow,\n Workflow,\n} from \"../task-graph/Workflow\";\nimport { IteratorTask, IteratorTaskConfig } from \"./IteratorTask\";\nimport type { TaskInput, TaskOutput, TaskTypeName } from \"./TaskTypes\";\n\n/**\n * Configuration for MapTask.\n */\nexport interface MapTaskConfig extends IteratorTaskConfig {\n /**\n * Whether to preserve the order of results matching the input order.\n * When false, results may be in completion order (faster for parallel).\n * @default true\n */\n readonly preserveOrder?: boolean;\n\n /**\n * Whether to flatten array results from each iteration.\n * When true, if each iteration returns an array, they are concatenated.\n * @default false\n */\n readonly flatten?: boolean;\n}\n\n/**\n * MapTask transforms an array by running a workflow for each element and collecting results.\n *\n * This task is the functional-style map operation: it takes an array input,\n * applies a transformation workflow to each element, and returns an array\n * of transformed results.\n *\n * ## Features\n *\n * - Transforms each array element through inner workflow\n * - Collects and returns array of results\n * - Maintains result order by default\n * - Configurable execution modes (parallel, sequential, etc.)\n * - Optional flattening of nested arrays\n *\n * ## Usage\n *\n * ```typescript\n * // Transform texts to embeddings\n * workflow\n * .input({ texts: [\"hello\", \"world\"] })\n * .map()\n * .textEmbedding()\n * .endMap()\n * // Result: { vectors: [Float32Array, Float32Array] }\n *\n * // With explicit port\n * workflow\n * .map({ iteratorPort: \"documents\" })\n * .enrich()\n * .chunk()\n * .endMap()\n * ```\n *\n * @template Input - The input type containing the array to transform\n * @template Output - The output type (array of transformed results)\n * @template Config - The configuration type\n */\nexport class MapTask<\n Input extends TaskInput = TaskInput,\n Output extends TaskOutput = TaskOutput,\n Config extends MapTaskConfig = MapTaskConfig,\n> extends IteratorTask<Input, Output, Config> {\n public static type: TaskTypeName = \"MapTask\";\n public static category: string = \"Flow Control\";\n public static title: string = \"Map\";\n public static description: string =\n \"Transforms an array by running a workflow for each element\";\n\n /**\n * MapTask always uses PROPERTY_ARRAY merge strategy to collect results.\n */\n public static readonly compoundMerge = PROPERTY_ARRAY;\n\n /**\n * Static input schema for MapTask.\n * Accepts any object with at least one array property.\n */\n public static inputSchema(): DataPortSchema {\n return {\n type: \"object\",\n properties: {},\n additionalProperties: true,\n } as const satisfies DataPortSchema;\n }\n\n /**\n * Static output schema for MapTask.\n * Dynamic based on inner workflow outputs.\n */\n public static outputSchema(): DataPortSchema {\n return {\n type: \"object\",\n properties: {},\n additionalProperties: true,\n } as const satisfies DataPortSchema;\n }\n\n /**\n * Whether to preserve order of results.\n */\n public get preserveOrder(): boolean {\n return this.config.preserveOrder ?? true;\n }\n\n /**\n * Whether to flatten nested array results.\n */\n public get flatten(): boolean {\n return this.config.flatten ?? false;\n }\n\n /**\n * Returns the empty result for MapTask.\n * Returns empty arrays for each output property.\n */\n protected override getEmptyResult(): Output {\n const schema = this.outputSchema();\n if (typeof schema === \"boolean\") {\n return {} as Output;\n }\n\n const result: Record<string, unknown[]> = {};\n for (const key of Object.keys(schema.properties || {})) {\n result[key] = [];\n }\n\n return result as Output;\n }\n\n /**\n * Output schema for MapTask.\n * Wraps inner workflow output properties in arrays.\n */\n public override outputSchema(): DataPortSchema {\n if (!this.hasChildren() && !this._templateGraph) {\n return (this.constructor as typeof MapTask).outputSchema();\n }\n\n return this.getWrappedOutputSchema();\n }\n\n /**\n * Collects and optionally flattens results from all iterations.\n */\n protected override collectResults(results: TaskOutput[]): Output {\n const collected = super.collectResults(results);\n\n if (!this.flatten || typeof collected !== \"object\" || collected === null) {\n return collected;\n }\n\n // Flatten array properties\n const flattened: Record<string, unknown[]> = {};\n for (const [key, value] of Object.entries(collected)) {\n if (Array.isArray(value)) {\n // Flatten nested arrays\n flattened[key] = value.flat();\n } else {\n flattened[key] = value as unknown[];\n }\n }\n\n return flattened as Output;\n }\n}\n\n// ============================================================================\n// Workflow Prototype Extensions\n// ============================================================================\n\ndeclare module \"../task-graph/Workflow\" {\n interface Workflow {\n /**\n * Starts a map loop that transforms each element in an array.\n * Use .endMap() to close the loop and return to the parent workflow.\n *\n * @param config - Configuration for the map loop\n * @returns A Workflow in loop builder mode for defining the transformation\n *\n * @example\n * ```typescript\n * workflow\n * .map()\n * .textEmbedding()\n * .endMap()\n * // Result: { vectors: [...] }\n * ```\n */\n map: CreateLoopWorkflow<TaskInput, TaskOutput, MapTaskConfig>;\n\n /**\n * Ends the map loop and returns to the parent workflow.\n * Only callable on workflows in loop builder mode.\n *\n * @returns The parent workflow\n */\n endMap(): Workflow;\n }\n}\n\nWorkflow.prototype.map = CreateLoopWorkflow(MapTask);\n\nWorkflow.prototype.endMap = CreateEndLoopWorkflow(\"endMap\");\n",
30
- "/**\n * @license\n * Copyright 2025 Steven Roussey <sroussey@gmail.com>\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport type { DataPortSchema } from \"@workglow/util\";\nimport { TaskGraph } from \"../task-graph/TaskGraph\";\nimport {\n CreateEndLoopWorkflow,\n CreateLoopWorkflow,\n Workflow,\n} from \"../task-graph/Workflow\";\nimport { IteratorTask, IteratorTaskConfig } from \"./IteratorTask\";\nimport type { IExecuteContext } from \"./ITask\";\nimport type { TaskInput, TaskOutput, TaskTypeName } from \"./TaskTypes\";\n\n/**\n * Configuration for ReduceTask.\n */\nexport interface ReduceTaskConfig<Accumulator = unknown> extends IteratorTaskConfig {\n /**\n * The initial value for the accumulator.\n * This is the starting value before processing any items.\n */\n readonly initialValue?: Accumulator;\n\n /**\n * Name of the accumulator port in the inner workflow input.\n * @default \"accumulator\"\n */\n readonly accumulatorPort?: string;\n\n /**\n * Name of the current item port in the inner workflow input.\n * @default \"currentItem\"\n */\n readonly currentItemPort?: string;\n\n /**\n * Name of the index port in the inner workflow input.\n * @default \"index\"\n */\n readonly indexPort?: string;\n}\n\n/**\n * ReduceTask processes array elements sequentially with an accumulator.\n *\n * This task implements the functional reduce/fold pattern:\n * - Starts with an initial accumulator value\n * - Processes items one at a time (always sequential)\n * - Passes accumulator, current item, and index to each iteration\n * - Uses the output as the new accumulator for the next iteration\n *\n * ## Features\n *\n * - Sequential-only execution (accumulator pattern requires it)\n * - Configurable initial value\n * - Access to accumulator, current item, and index\n * - Final output is the last accumulator value\n *\n * ## Usage\n *\n * ```typescript\n * // Sum all numbers\n * workflow\n * .input({ numbers: [1, 2, 3, 4, 5] })\n * .reduce({ initialValue: { sum: 0 } })\n * .addToSum() // receives { accumulator, currentItem, index }\n * .endReduce()\n * // Result: { sum: 15 }\n *\n * // Build a string from parts\n * workflow\n * .reduce({ initialValue: { text: \"\" } })\n * .appendText()\n * .endReduce()\n * ```\n *\n * @template Input - The input type containing the array to reduce\n * @template Output - The output/accumulator type\n * @template Config - The configuration type\n */\nexport class ReduceTask<\n Input extends TaskInput = TaskInput,\n Output extends TaskOutput = TaskOutput,\n Config extends ReduceTaskConfig<Output> = ReduceTaskConfig<Output>,\n> extends IteratorTask<Input, Output, Config> {\n public static type: TaskTypeName = \"ReduceTask\";\n public static category: string = \"Flow Control\";\n public static title: string = \"Reduce\";\n public static description: string =\n \"Processes array elements sequentially with an accumulator (fold)\";\n\n\n constructor(input: Partial<Input> = {}, config: Partial<Config> = {}) {\n // Force sequential execution for reduce\n const reduceConfig = {\n ...config,\n executionMode: \"sequential\" as const,\n };\n super(input, reduceConfig as Config);\n }\n\n // ========================================================================\n // Configuration Accessors\n // ========================================================================\n\n /**\n * Gets the initial accumulator value.\n */\n public get initialValue(): Output {\n return (this.config.initialValue ?? {}) as Output;\n }\n\n /**\n * Gets the accumulator port name.\n */\n public get accumulatorPort(): string {\n return this.config.accumulatorPort ?? \"accumulator\";\n }\n\n /**\n * Gets the current item port name.\n */\n public get currentItemPort(): string {\n return this.config.currentItemPort ?? \"currentItem\";\n }\n\n /**\n * Gets the index port name.\n */\n public get indexPort(): string {\n return this.config.indexPort ?? \"index\";\n }\n\n // ========================================================================\n // Execution\n // ========================================================================\n\n /**\n * Execute the reduce operation.\n * Processes items sequentially, passing accumulator through each iteration.\n */\n public override async execute(\n input: Input,\n context: IExecuteContext\n ): Promise<Output | undefined> {\n if (!this._templateGraph || this._templateGraph.getTasks().length === 0) {\n // No template - just return initial value\n return this.initialValue;\n }\n\n const items = this.getIterableItems(input);\n if (items.length === 0) {\n return this.initialValue;\n }\n\n let accumulator: Output = { ...this.initialValue };\n\n // Process each item sequentially\n for (let index = 0; index < items.length; index++) {\n if (context.signal?.aborted) {\n break;\n }\n\n const currentItem = items[index];\n\n // Build input for this reduction step\n const stepInput = {\n ...input,\n [this.accumulatorPort]: accumulator,\n [this.currentItemPort]: currentItem,\n [this.indexPort]: index,\n };\n\n // Clone template for this step\n this.subGraph = this.cloneTemplateForStep(index);\n\n // Run the subgraph\n const results = await this.subGraph.run<Output>(stepInput as Input, {\n parentSignal: context.signal,\n });\n\n // Merge results to get new accumulator\n accumulator = this.subGraph.mergeExecuteOutputsToRunOutput(\n results,\n this.compoundMerge\n ) as Output;\n\n // Update progress\n const progress = Math.round(((index + 1) / items.length) * 100);\n await context.updateProgress(progress, `Processing item ${index + 1}/${items.length}`);\n }\n\n return accumulator;\n }\n\n /**\n * Returns the initial value as empty result.\n */\n protected override getEmptyResult(): Output {\n return this.initialValue;\n }\n\n /**\n * Clones the template graph for a specific reduction step.\n */\n protected cloneTemplateForStep(stepIndex: number): TaskGraph {\n const clonedGraph = new TaskGraph();\n\n if (!this._templateGraph) {\n return clonedGraph;\n }\n\n const templateTasks = this._templateGraph.getTasks();\n const templateDataflows = this._templateGraph.getDataflows();\n\n // Map from template task ID to cloned task ID\n const idMap = new Map<unknown, unknown>();\n\n // Clone each task\n for (const templateTask of templateTasks) {\n const TaskClass = templateTask.constructor as any;\n const clonedTask = new TaskClass(\n { ...templateTask.defaults },\n {\n ...templateTask.config,\n id: `${templateTask.config.id}_step${stepIndex}`,\n name: `${templateTask.config.name || templateTask.type} [${stepIndex}]`,\n }\n );\n\n clonedGraph.addTask(clonedTask);\n idMap.set(templateTask.config.id, clonedTask.config.id);\n }\n\n // Clone dataflows\n for (const templateDataflow of templateDataflows) {\n const sourceId = idMap.get(templateDataflow.sourceTaskId);\n const targetId = idMap.get(templateDataflow.targetTaskId);\n\n if (sourceId !== undefined && targetId !== undefined) {\n const { Dataflow } = require(\"../task-graph/Dataflow\");\n const clonedDataflow = new Dataflow(\n sourceId,\n templateDataflow.sourceTaskPortId,\n targetId,\n templateDataflow.targetTaskPortId\n );\n clonedGraph.addDataflow(clonedDataflow);\n }\n }\n\n return clonedGraph;\n }\n\n // ========================================================================\n // Schema Methods\n // ========================================================================\n\n /**\n * Static input schema for ReduceTask.\n * Includes standard accumulator/item/index ports.\n */\n public static inputSchema(): DataPortSchema {\n return {\n type: \"object\",\n properties: {\n accumulator: {\n title: \"Accumulator\",\n description: \"The current accumulator value\",\n },\n currentItem: {\n title: \"Current Item\",\n description: \"The current item being processed\",\n },\n index: {\n type: \"number\",\n title: \"Index\",\n description: \"The current item index\",\n },\n },\n additionalProperties: true,\n } as const satisfies DataPortSchema;\n }\n\n /**\n * Static output schema for ReduceTask.\n */\n public static outputSchema(): DataPortSchema {\n return {\n type: \"object\",\n properties: {},\n additionalProperties: true,\n } as const satisfies DataPortSchema;\n }\n\n /**\n * Instance output schema - returns the accumulator schema from template.\n */\n public override outputSchema(): DataPortSchema {\n if (!this._templateGraph) {\n return (this.constructor as typeof ReduceTask).outputSchema();\n }\n\n // Get ending nodes from template\n const tasks = this._templateGraph.getTasks();\n const endingNodes = tasks.filter(\n (task) => this._templateGraph!.getTargetDataflows(task.config.id).length === 0\n );\n\n if (endingNodes.length === 0) {\n return (this.constructor as typeof ReduceTask).outputSchema();\n }\n\n const properties: Record<string, unknown> = {};\n\n // Merge output schemas from ending nodes (not wrapped in arrays for reduce)\n for (const task of endingNodes) {\n const taskOutputSchema = task.outputSchema();\n if (typeof taskOutputSchema === \"boolean\") continue;\n\n const taskProperties = taskOutputSchema.properties || {};\n for (const [key, schema] of Object.entries(taskProperties)) {\n if (!properties[key]) {\n properties[key] = schema;\n }\n }\n }\n\n return {\n type: \"object\",\n properties,\n additionalProperties: false,\n } as DataPortSchema;\n }\n\n /**\n * Override regenerateGraph to do nothing for ReduceTask.\n * We create subgraphs on-the-fly during execution.\n */\n public override regenerateGraph(): void {\n // Don't regenerate - we create graphs dynamically during execution\n this.events.emit(\"regenerate\");\n }\n}\n\n// ============================================================================\n// Workflow Prototype Extensions\n// ============================================================================\n\ndeclare module \"../task-graph/Workflow\" {\n interface Workflow {\n /**\n * Starts a reduce loop that processes items with an accumulator.\n * Use .endReduce() to close the loop and return to the parent workflow.\n *\n * @param config - Configuration for the reduce loop\n * @returns A Workflow in loop builder mode for defining the reduction\n *\n * @example\n * ```typescript\n * workflow\n * .reduce({ initialValue: { sum: 0 } })\n * .addToAccumulator()\n * .endReduce()\n * ```\n */\n reduce: CreateLoopWorkflow<TaskInput, TaskOutput, ReduceTaskConfig<any>>;\n\n /**\n * Ends the reduce loop and returns to the parent workflow.\n * Only callable on workflows in loop builder mode.\n *\n * @returns The parent workflow\n */\n endReduce(): Workflow;\n }\n}\n\nWorkflow.prototype.reduce = CreateLoopWorkflow(ReduceTask);\n\nWorkflow.prototype.endReduce = CreateEndLoopWorkflow(\"endReduce\");\n",
31
- "/**\n * @license\n * Copyright 2025 Steven Roussey <sroussey@gmail.com>\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport { Dataflow } from \"../task-graph/Dataflow\";\nimport { TaskGraph } from \"../task-graph/TaskGraph\";\nimport { CompoundMergeStrategy } from \"../task-graph/TaskGraphRunner\";\nimport { TaskConfigurationError, TaskJSONError } from \"../task/TaskError\";\nimport { TaskRegistry } from \"../task/TaskRegistry\";\nimport { GraphAsTask } from \"./GraphAsTask\";\nimport { DataPorts, TaskConfig, TaskInput } from \"./TaskTypes\";\n\n// ========================================================================\n// JSON Serialization Types\n// ========================================================================\n/**\n * Represents a single task item in the JSON configuration.\n * This structure defines how tasks should be configured in JSON format.\n */\n\nexport type JsonTaskItem = {\n /** Unique identifier for the task */\n id: unknown;\n\n /** Type of task to create */\n type: string;\n\n /** Optional display name for the task */\n name?: string;\n\n /** Default input values for the task */\n defaults?: TaskInput;\n\n /** Defines data flow between tasks */\n dependencies?: {\n /** Input parameter name mapped to source task output */\n [x: string]:\n | {\n /** ID of the source task */\n id: unknown;\n\n /** Output parameter name from source task */\n output: string;\n }\n | Array<{\n id: unknown;\n output: string;\n }>;\n };\n\n /** Optional user data to use for this task, not used by the task framework except it will be exported as part of the task JSON*/\n extras?: DataPorts;\n\n /** Nested tasks for compound operations */\n subtasks?: JsonTaskItem[];\n}; /**\n * Represents a task graph item, which can be a task or a subgraph\n */\n\nexport type TaskGraphItemJson = {\n id: unknown;\n type: string;\n name?: string;\n defaults?: TaskInput;\n extras?: DataPorts;\n subgraph?: TaskGraphJson;\n merge?: CompoundMergeStrategy;\n};\n\nexport type TaskGraphJson = {\n tasks: TaskGraphItemJson[];\n dataflows: DataflowJson[];\n};\n\nexport type DataflowJson = {\n sourceTaskId: unknown;\n sourceTaskPortId: string;\n targetTaskId: unknown;\n targetTaskPortId: string;\n};\n\nconst createSingleTaskFromJSON = (item: JsonTaskItem | TaskGraphItemJson) => {\n if (!item.id) throw new TaskJSONError(\"Task id required\");\n if (!item.type) throw new TaskJSONError(\"Task type required\");\n if (item.defaults && Array.isArray(item.defaults))\n throw new TaskJSONError(\"Task defaults must be an object\");\n\n const taskClass = TaskRegistry.all.get(item.type);\n if (!taskClass)\n throw new TaskJSONError(`Task type ${item.type} not found, perhaps not registered?`);\n\n const taskConfig: TaskConfig = {\n id: item.id,\n name: item.name,\n extras: item.extras,\n };\n const task = new taskClass(item.defaults ?? {}, taskConfig);\n return task;\n};\n\n/**\n * Creates a task instance from a JSON task item configuration\n * Validates required fields and resolves task type from registry\n */\nexport const createTaskFromDependencyJSON = (item: JsonTaskItem) => {\n const task = createSingleTaskFromJSON(item);\n if (item.subtasks && item.subtasks.length > 0) {\n if (!(task instanceof GraphAsTask)) {\n throw new TaskConfigurationError(\"Subgraph is only supported for CompoundTasks\");\n }\n task.subGraph = createGraphFromDependencyJSON(item.subtasks);\n }\n return task;\n};\n\n/**\n * Creates a task graph from an array of JSON task items\n * Recursively processes subtasks for compound tasks\n */\nexport const createGraphFromDependencyJSON = (jsonItems: JsonTaskItem[]) => {\n const subGraph = new TaskGraph();\n for (const subitem of jsonItems) {\n subGraph.addTask(createTaskFromDependencyJSON(subitem));\n }\n return subGraph;\n};\n\n/**\n * Creates a task instance from a task graph item JSON representation\n * @param item The JSON representation of the task\n * @returns A new task instance\n * @throws Error if required fields are missing or invalid\n */\nexport const createTaskFromGraphJSON = (item: TaskGraphItemJson) => {\n const task = createSingleTaskFromJSON(item);\n if (item.subgraph) {\n if (!(task instanceof GraphAsTask)) {\n throw new TaskConfigurationError(\"Subgraph is only supported for GraphAsTask\");\n }\n task.subGraph = createGraphFromGraphJSON(item.subgraph);\n }\n return task;\n};\n\n/**\n * Creates a TaskGraph instance from its JSON representation\n * @param graphJsonObj The JSON representation of the task graph\n * @returns A new TaskGraph instance with all tasks and data flows\n */\nexport const createGraphFromGraphJSON = (graphJsonObj: TaskGraphJson) => {\n const subGraph = new TaskGraph();\n for (const subitem of graphJsonObj.tasks) {\n subGraph.addTask(createTaskFromGraphJSON(subitem));\n }\n for (const subitem of graphJsonObj.dataflows) {\n subGraph.addDataflow(\n new Dataflow(\n subitem.sourceTaskId,\n subitem.sourceTaskPortId,\n subitem.targetTaskId,\n subitem.targetTaskPortId\n )\n );\n }\n return subGraph;\n};\n",
23
+ "/**\n * @license\n * Copyright 2025 Steven Roussey <sroussey@gmail.com>\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport { JobQueueClient, JobQueueServer } from \"@workglow/job-queue\";\nimport { IQueueStorage } from \"@workglow/storage\";\n\n/**\n * Combined structure for a registered job queue containing server, client, and storage\n */\nexport interface RegisteredQueue<Input = unknown, Output = unknown> {\n readonly server: JobQueueServer<Input, Output>;\n readonly client: JobQueueClient<Input, Output>;\n readonly storage: IQueueStorage<Input, Output>;\n}\n\n/**\n * Global singleton instance of the TaskQueueRegistry.\n * This is used to manage all job queues across the application.\n */\nlet taskQueueRegistry: TaskQueueRegistry | null = null;\n\n/**\n * Registry for managing task queues in the application.\n * Provides functionality to register, manage, and control job queues.\n *\n * @template Input - The type of input data for tasks in the queues\n * @template Output - The type of output data for tasks in the queues\n */\nexport class TaskQueueRegistry {\n /**\n * Map of queue names to their corresponding registered queue instances\n */\n public readonly queues: Map<string, RegisteredQueue<unknown, unknown>> = new Map();\n\n /**\n * Registers a new job queue with the registry\n *\n * @param queue - The registered queue containing server, client, and storage\n * @throws Error if a queue with the same name already exists\n */\n registerQueue<Input, Output>(queue: RegisteredQueue<Input, Output>): void {\n const queueName = queue.server.queueName;\n if (this.queues.has(queueName)) {\n throw new Error(`Queue with name ${queueName} already exists`);\n }\n this.queues.set(queueName, queue as RegisteredQueue<unknown, unknown>);\n }\n\n /**\n * Retrieves a registered queue by its name\n *\n * @param queueName - The name of the queue to retrieve\n * @returns The registered queue or undefined if not found\n */\n getQueue<Input, Output>(queueName: string): RegisteredQueue<Input, Output> | undefined {\n return this.queues.get(queueName) as RegisteredQueue<Input, Output> | undefined;\n }\n\n /**\n * Starts all registered job queue servers\n * This allows queues to begin processing their jobs\n *\n * @returns The registry instance for chaining\n */\n startQueues(): this {\n for (const queue of this.queues.values()) {\n queue.server.start();\n }\n return this;\n }\n\n /**\n * Stops all registered job queue servers\n * This pauses job processing but maintains the queued jobs\n *\n * @returns The registry instance for chaining\n */\n stopQueues(): this {\n for (const queue of this.queues.values()) {\n queue.server.stop();\n }\n return this;\n }\n\n /**\n * Clears all registered job queues\n * This removes all queued jobs from the storage\n *\n * @returns The registry instance for chaining\n */\n clearQueues(): this {\n for (const queue of this.queues.values()) {\n queue.storage.deleteAll();\n }\n return this;\n }\n}\n\n/**\n * Gets the global TaskQueueRegistry instance\n * Creates a new instance if one doesn't exist\n *\n * @returns The global TaskQueueRegistry instance\n */\nexport function getTaskQueueRegistry(): TaskQueueRegistry {\n if (!taskQueueRegistry) {\n taskQueueRegistry = new TaskQueueRegistry();\n }\n return taskQueueRegistry;\n}\n\n/**\n * Sets the global TaskQueueRegistry instance\n * Stops and clears any existing registry before replacing it\n *\n * @param registry - The new registry instance to use, or null to clear\n */\nexport function setTaskQueueRegistry(registry: TaskQueueRegistry | null): void {\n if (taskQueueRegistry) {\n taskQueueRegistry.stopQueues();\n taskQueueRegistry.clearQueues();\n }\n taskQueueRegistry = registry;\n}\n",
32
24
  "/**\n * @license\n * Copyright 2025 Steven Roussey <sroussey@gmail.com>\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport type { ITaskConstructor } from \"./ITask\";\n\n/**\n * Map storing all registered task constructors.\n * Keys are task type identifiers and values are their corresponding constructor functions.\n */\nconst taskConstructors = new Map<string, ITaskConstructor<any, any, any>>();\n\n/**\n * Registers a task constructor with the registry.\n * This allows the task type to be instantiated dynamically based on its type identifier.\n *\n * @param type - The unique identifier for the task type\n * @param constructor - The constructor function for the task\n * @throws Error if a task with the same type is already registered\n */\nfunction registerTask(baseClass: ITaskConstructor<any, any, any>): void {\n if (taskConstructors.has(baseClass.type)) {\n // TODO: fix this\n // throw new Error(`Task type ${baseClass.type} is already registered`);\n }\n taskConstructors.set(baseClass.type, baseClass);\n}\n\n/**\n * TaskRegistry provides a centralized registry for task types.\n * It enables dynamic task instantiation and management across the application.\n */\nexport const TaskRegistry = {\n /**\n * Map containing all registered task constructors\n */\n all: taskConstructors,\n\n /**\n * Function to register new task types\n */\n registerTask,\n};\n",
33
- "/**\n * @license\n * Copyright 2025 Steven Roussey <sroussey@gmail.com>\n * SPDX-License-Identifier: Apache-2.0\n */\n\nexport * from \"./BatchTask\";\nexport * from \"./ConditionalTask\";\nexport * from \"./ForEachTask\";\nexport * from \"./GraphAsTask\";\nexport * from \"./GraphAsTaskRunner\";\nexport * from \"./InputResolver\";\nexport * from \"./ITask\";\nexport * from \"./IteratorTask\";\nexport * from \"./IteratorTaskRunner\";\nexport * from \"./JobQueueFactory\";\nexport * from \"./JobQueueTask\";\nexport * from \"./MapTask\";\nexport * from \"./ReduceTask\";\nexport * from \"./Task\";\nexport * from \"./TaskError\";\nexport * from \"./TaskEvents\";\nexport * from \"./TaskJSON\";\nexport * from \"./TaskQueueRegistry\";\nexport * from \"./TaskRegistry\";\nexport * from \"./TaskTypes\";\nexport * from \"./WhileTask\";\n\nimport { BatchTask } from \"./BatchTask\";\nimport { ConditionalTask } from \"./ConditionalTask\";\nimport { ForEachTask } from \"./ForEachTask\";\nimport { GraphAsTask } from \"./GraphAsTask\";\nimport { MapTask } from \"./MapTask\";\nimport { ReduceTask } from \"./ReduceTask\";\nimport { TaskRegistry } from \"./TaskRegistry\";\nimport { WhileTask } from \"./WhileTask\";\n\nexport const registerBaseTasks = () => {\n const tasks = [\n ConditionalTask,\n GraphAsTask,\n ForEachTask,\n MapTask,\n BatchTask,\n WhileTask,\n ReduceTask,\n ];\n tasks.map(TaskRegistry.registerTask);\n return tasks;\n};\n",
34
- "/**\n * @license\n * Copyright 2025 Steven Roussey <sroussey@gmail.com>\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport type { DataPortSchema } from \"@workglow/util\";\nimport { TaskGraph } from \"../task-graph/TaskGraph\";\nimport {\n CreateEndLoopWorkflow,\n CreateLoopWorkflow,\n Workflow,\n} from \"../task-graph/Workflow\";\nimport { GraphAsTask, GraphAsTaskConfig } from \"./GraphAsTask\";\nimport type { IExecuteContext } from \"./ITask\";\nimport { TaskConfigurationError } from \"./TaskError\";\nimport type { TaskInput, TaskOutput, TaskTypeName } from \"./TaskTypes\";\n\n/**\n * Condition function type for WhileTask.\n * Receives the current output and iteration count, returns whether to continue looping.\n *\n * @param output - The output from the last iteration\n * @param iteration - The current iteration number (0-based)\n * @returns true to continue looping, false to stop\n */\nexport type WhileConditionFn<Output> = (output: Output, iteration: number) => boolean;\n\n/**\n * Configuration for WhileTask.\n */\nexport interface WhileTaskConfig<Output extends TaskOutput = TaskOutput>\n extends GraphAsTaskConfig {\n /**\n * Condition function that determines whether to continue looping.\n * Called after each iteration with the current output and iteration count.\n * Returns true to continue, false to stop.\n */\n readonly condition?: WhileConditionFn<Output>;\n\n /**\n * Maximum number of iterations to prevent infinite loops.\n * @default 100\n */\n readonly maxIterations?: number;\n\n /**\n * Whether to pass the output of each iteration as input to the next.\n * When true, output from iteration N becomes input to iteration N+1.\n * @default true\n */\n readonly chainIterations?: boolean;\n}\n\n/**\n * WhileTask loops until a condition function returns false.\n *\n * This task is useful for:\n * - Iterative refinement processes\n * - Polling until a condition is met\n * - Convergence algorithms\n * - Retry logic with conditions\n *\n * ## Features\n *\n * - Loops until condition returns false\n * - Configurable maximum iterations (safety limit)\n * - Passes output from each iteration to the next\n * - Access to iteration count in condition function\n *\n * ## Usage\n *\n * ```typescript\n * // Refine until quality threshold\n * workflow\n * .while({\n * condition: (output, iteration) => output.quality < 0.9 && iteration < 10,\n * maxIterations: 20\n * })\n * .refineResult()\n * .evaluateQuality()\n * .endWhile()\n *\n * // Retry until success\n * workflow\n * .while({\n * condition: (output) => !output.success,\n * maxIterations: 5\n * })\n * .attemptOperation()\n * .endWhile()\n * ```\n *\n * @template Input - The input type for the while task\n * @template Output - The output type for the while task\n * @template Config - The configuration type\n */\nexport class WhileTask<\n Input extends TaskInput = TaskInput,\n Output extends TaskOutput = TaskOutput,\n Config extends WhileTaskConfig<Output> = WhileTaskConfig<Output>,\n> extends GraphAsTask<Input, Output, Config> {\n public static type: TaskTypeName = \"WhileTask\";\n public static category: string = \"Flow Control\";\n public static title: string = \"While Loop\";\n public static description: string = \"Loops until a condition function returns false\";\n\n /** This task has dynamic schemas based on the inner workflow */\n public static hasDynamicSchemas: boolean = true;\n\n /**\n * The template subgraph that will be executed each iteration.\n */\n protected _templateGraph: TaskGraph | undefined;\n\n /**\n * Current iteration count during execution.\n */\n protected _currentIteration: number = 0;\n\n constructor(input: Partial<Input> = {}, config: Partial<Config> = {}) {\n super(input, config as Config);\n }\n\n // ========================================================================\n // Configuration Accessors\n // ========================================================================\n\n /**\n * Gets the condition function.\n */\n public get condition(): WhileConditionFn<Output> | undefined {\n return this.config.condition;\n }\n\n /**\n * Gets the maximum iterations limit.\n */\n public get maxIterations(): number {\n return this.config.maxIterations ?? 100;\n }\n\n /**\n * Whether to chain iteration outputs to inputs.\n */\n public get chainIterations(): boolean {\n return this.config.chainIterations ?? true;\n }\n\n /**\n * Gets the current iteration count.\n */\n public get currentIteration(): number {\n return this._currentIteration;\n }\n\n // ========================================================================\n // Template Graph Management\n // ========================================================================\n\n /**\n * Sets the template graph that defines the workflow to run each iteration.\n */\n public setTemplateGraph(graph: TaskGraph): void {\n this._templateGraph = graph;\n }\n\n /**\n * Gets the template graph.\n */\n public getTemplateGraph(): TaskGraph | undefined {\n return this._templateGraph;\n }\n\n // ========================================================================\n // Execution\n // ========================================================================\n\n /**\n * Execute the while loop.\n */\n public async execute(input: Input, context: IExecuteContext): Promise<Output | undefined> {\n if (!this._templateGraph || this._templateGraph.getTasks().length === 0) {\n throw new TaskConfigurationError(`${this.type}: No template graph set for while loop`);\n }\n\n if (!this.condition) {\n throw new TaskConfigurationError(`${this.type}: No condition function provided`);\n }\n\n this._currentIteration = 0;\n let currentInput: Input = { ...input };\n let currentOutput: Output = {} as Output;\n\n // Execute iterations until condition returns false or max iterations reached\n while (this._currentIteration < this.maxIterations) {\n if (context.signal?.aborted) {\n break;\n }\n\n // Clone template for this iteration\n this.subGraph = this.cloneTemplateGraph(this._currentIteration);\n\n // Run the subgraph\n const results = await this.subGraph.run<Output>(currentInput, {\n parentSignal: context.signal,\n });\n\n // Merge results\n currentOutput = this.subGraph.mergeExecuteOutputsToRunOutput(\n results,\n this.compoundMerge\n ) as Output;\n\n // Check condition\n if (!this.condition(currentOutput, this._currentIteration)) {\n break;\n }\n\n // Chain output to input for next iteration if enabled\n if (this.chainIterations) {\n currentInput = { ...currentInput, ...currentOutput } as Input;\n }\n\n this._currentIteration++;\n\n // Update progress\n const progress = Math.min(\n (this._currentIteration / this.maxIterations) * 100,\n 99\n );\n await context.updateProgress(progress, `Iteration ${this._currentIteration}`);\n }\n\n return currentOutput;\n }\n\n /**\n * Clones the template graph for a specific iteration.\n */\n protected cloneTemplateGraph(iteration: number): TaskGraph {\n const clonedGraph = new TaskGraph();\n\n if (!this._templateGraph) {\n return clonedGraph;\n }\n\n const templateTasks = this._templateGraph.getTasks();\n const templateDataflows = this._templateGraph.getDataflows();\n\n // Map from template task ID to cloned task ID\n const idMap = new Map<unknown, unknown>();\n\n // Clone each task\n for (const templateTask of templateTasks) {\n const TaskClass = templateTask.constructor as any;\n const clonedTask = new TaskClass(\n { ...templateTask.defaults },\n {\n ...templateTask.config,\n id: `${templateTask.config.id}_iter${iteration}`,\n name: `${templateTask.config.name || templateTask.type} [${iteration}]`,\n }\n );\n\n clonedGraph.addTask(clonedTask);\n idMap.set(templateTask.config.id, clonedTask.config.id);\n }\n\n // Clone dataflows\n for (const templateDataflow of templateDataflows) {\n const sourceId = idMap.get(templateDataflow.sourceTaskId);\n const targetId = idMap.get(templateDataflow.targetTaskId);\n\n if (sourceId !== undefined && targetId !== undefined) {\n const { Dataflow } = require(\"../task-graph/Dataflow\");\n const clonedDataflow = new Dataflow(\n sourceId,\n templateDataflow.sourceTaskPortId,\n targetId,\n templateDataflow.targetTaskPortId\n );\n clonedGraph.addDataflow(clonedDataflow);\n }\n }\n\n return clonedGraph;\n }\n\n // ========================================================================\n // Schema Methods\n // ========================================================================\n\n /**\n * Static input schema for WhileTask.\n */\n public static inputSchema(): DataPortSchema {\n return {\n type: \"object\",\n properties: {},\n additionalProperties: true,\n } as const satisfies DataPortSchema;\n }\n\n /**\n * Static output schema for WhileTask.\n */\n public static outputSchema(): DataPortSchema {\n return {\n type: \"object\",\n properties: {\n _iterations: {\n type: \"number\",\n title: \"Iterations\",\n description: \"Number of iterations executed\",\n },\n },\n additionalProperties: true,\n } as const satisfies DataPortSchema;\n }\n\n /**\n * Instance output schema - returns final iteration output schema.\n */\n public override outputSchema(): DataPortSchema {\n if (!this._templateGraph) {\n return (this.constructor as typeof WhileTask).outputSchema();\n }\n\n // Get ending nodes from template\n const tasks = this._templateGraph.getTasks();\n const endingNodes = tasks.filter(\n (task) => this._templateGraph!.getTargetDataflows(task.config.id).length === 0\n );\n\n if (endingNodes.length === 0) {\n return (this.constructor as typeof WhileTask).outputSchema();\n }\n\n const properties: Record<string, unknown> = {\n _iterations: {\n type: \"number\",\n title: \"Iterations\",\n description: \"Number of iterations executed\",\n },\n };\n\n // Merge output schemas from ending nodes\n for (const task of endingNodes) {\n const taskOutputSchema = task.outputSchema();\n if (typeof taskOutputSchema === \"boolean\") continue;\n\n const taskProperties = taskOutputSchema.properties || {};\n for (const [key, schema] of Object.entries(taskProperties)) {\n if (!properties[key]) {\n properties[key] = schema;\n }\n }\n }\n\n return {\n type: \"object\",\n properties,\n additionalProperties: false,\n } as DataPortSchema;\n }\n}\n\n// ============================================================================\n// Workflow Prototype Extensions\n// ============================================================================\n\ndeclare module \"../task-graph/Workflow\" {\n interface Workflow {\n /**\n * Starts a while loop that continues until a condition is false.\n * Use .endWhile() to close the loop and return to the parent workflow.\n *\n * @param config - Configuration for the while loop (must include condition)\n * @returns A Workflow in loop builder mode for defining the loop body\n *\n * @example\n * ```typescript\n * workflow\n * .while({\n * condition: (output, iteration) => output.quality < 0.9,\n * maxIterations: 10\n * })\n * .refineResult()\n * .endWhile()\n * ```\n */\n while: CreateLoopWorkflow<TaskInput, TaskOutput, WhileTaskConfig<any>>;\n\n /**\n * Ends the while loop and returns to the parent workflow.\n * Only callable on workflows in loop builder mode.\n *\n * @returns The parent workflow\n */\n endWhile(): Workflow;\n }\n}\n\nWorkflow.prototype.while = CreateLoopWorkflow(WhileTask);\n\nWorkflow.prototype.endWhile = CreateEndLoopWorkflow(\"endWhile\");\n",
25
+ "/**\n * @license\n * Copyright 2025 Steven Roussey <sroussey@gmail.com>\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport { Dataflow } from \"../task-graph/Dataflow\";\nimport { TaskGraph } from \"../task-graph/TaskGraph\";\nimport { CompoundMergeStrategy } from \"../task-graph/TaskGraphRunner\";\nimport { TaskConfigurationError, TaskJSONError } from \"../task/TaskError\";\nimport { TaskRegistry } from \"../task/TaskRegistry\";\nimport { GraphAsTask } from \"./GraphAsTask\";\nimport { DataPorts, TaskConfig, TaskInput } from \"./TaskTypes\";\n\n// ========================================================================\n// JSON Serialization Types\n// ========================================================================\n/**\n * Represents a single task item in the JSON configuration.\n * This structure defines how tasks should be configured in JSON format.\n */\n\nexport type JsonTaskItem = {\n /** Unique identifier for the task */\n id: unknown;\n\n /** Type of task to create */\n type: string;\n\n /** Optional display name for the task */\n name?: string;\n\n /** Default input values for the task */\n defaults?: TaskInput;\n\n /** Defines data flow between tasks */\n dependencies?: {\n /** Input parameter name mapped to source task output */\n [x: string]:\n | {\n /** ID of the source task */\n id: unknown;\n\n /** Output parameter name from source task */\n output: string;\n }\n | Array<{\n id: unknown;\n output: string;\n }>;\n };\n\n /** Optional user data to use for this task, not used by the task framework except it will be exported as part of the task JSON*/\n extras?: DataPorts;\n\n /** Nested tasks for compound operations */\n subtasks?: JsonTaskItem[];\n}; /**\n * Represents a task graph item, which can be a task or a subgraph\n */\n\nexport type TaskGraphItemJson = {\n id: unknown;\n type: string;\n name?: string;\n defaults?: TaskInput;\n extras?: DataPorts;\n subgraph?: TaskGraphJson;\n merge?: CompoundMergeStrategy;\n};\n\nexport type TaskGraphJson = {\n tasks: TaskGraphItemJson[];\n dataflows: DataflowJson[];\n};\n\nexport type DataflowJson = {\n sourceTaskId: unknown;\n sourceTaskPortId: string;\n targetTaskId: unknown;\n targetTaskPortId: string;\n};\n\nconst createSingleTaskFromJSON = (item: JsonTaskItem | TaskGraphItemJson) => {\n if (!item.id) throw new TaskJSONError(\"Task id required\");\n if (!item.type) throw new TaskJSONError(\"Task type required\");\n if (item.defaults && Array.isArray(item.defaults))\n throw new TaskJSONError(\"Task defaults must be an object\");\n\n const taskClass = TaskRegistry.all.get(item.type);\n if (!taskClass)\n throw new TaskJSONError(`Task type ${item.type} not found, perhaps not registered?`);\n\n const taskConfig: TaskConfig = {\n id: item.id,\n name: item.name,\n extras: item.extras,\n };\n const task = new taskClass(item.defaults ?? {}, taskConfig);\n return task;\n};\n\n/**\n * Creates a task instance from a JSON task item configuration\n * Validates required fields and resolves task type from registry\n */\nexport const createTaskFromDependencyJSON = (item: JsonTaskItem) => {\n const task = createSingleTaskFromJSON(item);\n if (item.subtasks && item.subtasks.length > 0) {\n if (!(task instanceof GraphAsTask)) {\n throw new TaskConfigurationError(\"Subgraph is only supported for CompoundTasks\");\n }\n task.subGraph = createGraphFromDependencyJSON(item.subtasks);\n }\n return task;\n};\n\n/**\n * Creates a task graph from an array of JSON task items\n * Recursively processes subtasks for compound tasks\n */\nexport const createGraphFromDependencyJSON = (jsonItems: JsonTaskItem[]) => {\n const subGraph = new TaskGraph();\n for (const subitem of jsonItems) {\n subGraph.addTask(createTaskFromDependencyJSON(subitem));\n }\n return subGraph;\n};\n\n/**\n * Creates a task instance from a task graph item JSON representation\n * @param item The JSON representation of the task\n * @returns A new task instance\n * @throws Error if required fields are missing or invalid\n */\nexport const createTaskFromGraphJSON = (item: TaskGraphItemJson) => {\n const task = createSingleTaskFromJSON(item);\n if (item.subgraph) {\n if (!(task instanceof GraphAsTask)) {\n throw new TaskConfigurationError(\"Subgraph is only supported for GraphAsTask\");\n }\n task.subGraph = createGraphFromGraphJSON(item.subgraph);\n }\n return task;\n};\n\n/**\n * Creates a TaskGraph instance from its JSON representation\n * @param graphJsonObj The JSON representation of the task graph\n * @returns A new TaskGraph instance with all tasks and data flows\n */\nexport const createGraphFromGraphJSON = (graphJsonObj: TaskGraphJson) => {\n const subGraph = new TaskGraph();\n for (const subitem of graphJsonObj.tasks) {\n subGraph.addTask(createTaskFromGraphJSON(subitem));\n }\n for (const subitem of graphJsonObj.dataflows) {\n subGraph.addDataflow(\n new Dataflow(\n subitem.sourceTaskId,\n subitem.sourceTaskPortId,\n subitem.targetTaskId,\n subitem.targetTaskPortId\n )\n );\n }\n return subGraph;\n};\n",
26
+ "/**\n * @license\n * Copyright 2025 Steven Roussey <sroussey@gmail.com>\n * SPDX-License-Identifier: Apache-2.0\n */\n\nexport * from \"./ConditionalTask\";\nexport * from \"./GraphAsTask\";\nexport * from \"./GraphAsTaskRunner\";\nexport * from \"./InputResolver\";\nexport * from \"./ITask\";\nexport * from \"./JobQueueFactory\";\nexport * from \"./JobQueueTask\";\nexport * from \"./Task\";\nexport * from \"./TaskError\";\nexport * from \"./TaskEvents\";\nexport * from \"./TaskJSON\";\nexport * from \"./TaskQueueRegistry\";\nexport * from \"./TaskRegistry\";\nexport * from \"./TaskTypes\";\n\nimport { ConditionalTask } from \"./ConditionalTask\";\nimport { GraphAsTask } from \"./GraphAsTask\";\nimport { TaskRegistry } from \"./TaskRegistry\";\n\nexport const registerBaseTasks = () => {\n const tasks = [ConditionalTask, GraphAsTask];\n tasks.map(TaskRegistry.registerTask);\n return tasks;\n};\n",
35
27
  "/**\n * @license\n * Copyright 2025 Steven Roussey <sroussey@gmail.com>\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport { createServiceToken, EventEmitter, EventParameters } from \"@workglow/util\";\nimport { TaskGraph } from \"../task-graph/TaskGraph\";\n\n/**\n * Service token for TaskGraphRepository\n */\nexport const TASK_GRAPH_REPOSITORY = createServiceToken<TaskGraphRepository>(\n \"taskgraph.taskGraphRepository\"\n);\n\n/**\n * Events that can be emitted by the TaskGraphRepository\n */\nexport type TaskGraphRepositoryEvents = keyof TaskGraphRepositoryEventListeners;\n\nexport type TaskGraphRepositoryEventListeners = {\n graph_saved: (key: string) => void;\n graph_retrieved: (key: string) => void;\n graph_cleared: () => void;\n};\n\nexport type TaskGraphRepositoryEventListener<Event extends TaskGraphRepositoryEvents> =\n TaskGraphRepositoryEventListeners[Event];\n\nexport type TaskGraphRepositoryEventParameters<Event extends TaskGraphRepositoryEvents> =\n EventParameters<TaskGraphRepositoryEventListeners, Event>;\n\n/**\n * Repository class for managing task graphs persistence and retrieval.\n * Provides functionality to save, load, and manipulate task graphs with their associated tasks and data flows.\n */\nexport abstract class TaskGraphRepository {\n /**\n * The type of the repository\n */\n public type = \"TaskGraphRepository\";\n\n /**\n * The event emitter for the task graphs\n */\n private get events() {\n if (!this._events) {\n this._events = new EventEmitter<TaskGraphRepositoryEventListeners>();\n }\n return this._events;\n }\n private _events: EventEmitter<TaskGraphRepositoryEventListeners> | undefined;\n\n /**\n * Registers an event listener for the specified event\n * @param name The event name to listen for\n * @param fn The callback function to execute when the event occurs\n */\n on<Event extends TaskGraphRepositoryEvents>(\n name: Event,\n fn: TaskGraphRepositoryEventListener<Event>\n ) {\n this.events.on(name, fn);\n }\n\n /**\n * Removes an event listener for the specified event\n * @param name The event name to stop listening for\n * @param fn The callback function to remove\n */\n off<Event extends TaskGraphRepositoryEvents>(\n name: Event,\n fn: TaskGraphRepositoryEventListener<Event>\n ) {\n this.events.off(name, fn);\n }\n\n /**\n * Adds an event listener that will only be called once\n * @param name The event name to listen for\n * @param fn The callback function to execute when the event occurs\n */\n once<Event extends TaskGraphRepositoryEvents>(\n name: Event,\n fn: TaskGraphRepositoryEventListener<Event>\n ) {\n this.events.once(name, fn);\n }\n\n /**\n * Returns when the event was emitted (promise form of once)\n * @param name The event name to check\n * @returns true if the event has listeners, false otherwise\n */\n waitOn<Event extends TaskGraphRepositoryEvents>(name: Event) {\n return this.events.waitOn(name) as Promise<TaskGraphRepositoryEventParameters<Event>>;\n }\n\n /**\n * Emits an event (if there are listeners)\n * @param name The event name to emit\n * @param args The event parameters\n */\n emit<Event extends TaskGraphRepositoryEvents>(\n name: Event,\n ...args: TaskGraphRepositoryEventParameters<Event>\n ) {\n this._events?.emit(name, ...args);\n }\n\n /**\n * Saves a task graph to persistent storage\n * @param key The unique identifier for the task graph\n * @param output The task graph to save\n * @emits graph_saved when the operation completes\n */\n abstract saveTaskGraph(key: string, output: TaskGraph): Promise<void>;\n\n /**\n * Retrieves a task graph from persistent storage\n * @param key The unique identifier of the task graph to retrieve\n * @returns The retrieved task graph, or undefined if not found\n * @emits graph_retrieved when the operation completes successfully\n */\n abstract getTaskGraph(key: string): Promise<TaskGraph | undefined>;\n\n /**\n * Clears all task graphs from the repository\n * @emits graph_cleared when the operation completes\n */\n abstract clear(): Promise<void>;\n\n /**\n * Returns the number of task graphs stored in the repository\n * @returns The count of stored task graphs\n */\n abstract size(): Promise<number>;\n}\n",
36
28
  "/**\n * @license\n * Copyright 2025 Steven Roussey <sroussey@gmail.com>\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport type { BaseTabularStorage } from \"@workglow/storage\";\nimport { DataPortSchemaObject } from \"@workglow/util\";\nimport { TaskGraph } from \"../task-graph/TaskGraph\";\nimport { createGraphFromGraphJSON } from \"../task/TaskJSON\";\nimport { TaskGraphRepository } from \"./TaskGraphRepository\";\n\nexport const TaskGraphSchema = {\n type: \"object\",\n properties: {\n key: { type: \"string\" },\n value: { type: \"string\" },\n },\n additionalProperties: false,\n} satisfies DataPortSchemaObject;\n\nexport const TaskGraphPrimaryKeyNames = [\"key\"] as const;\n\n/**\n * Options for the TaskGraphRepository\n */\nexport type TaskGraphRepositoryStorage = BaseTabularStorage<\n typeof TaskGraphSchema,\n typeof TaskGraphPrimaryKeyNames\n>;\ntype TaskGraphRepositoryOptions = {\n tabularRepository: TaskGraphRepositoryStorage;\n};\n\n/**\n * Repository class for managing task graphs persistence and retrieval.\n * Provides functionality to save, load, and manipulate task graphs with their associated tasks and data flows.\n */\nexport class TaskGraphTabularRepository extends TaskGraphRepository {\n /**\n * The type of the repository\n */\n public type = \"TaskGraphTabularRepository\";\n\n /**\n * The tabular repository for the task graphs\n */\n tabularRepository: TaskGraphRepositoryStorage;\n\n /**\n * Constructor for the TaskGraphRepository\n * @param options The options for the repository\n */\n constructor({ tabularRepository }: TaskGraphRepositoryOptions) {\n super();\n this.tabularRepository = tabularRepository;\n }\n\n /**\n * Sets up the database for the repository.\n * Must be called before using any other methods.\n */\n async setupDatabase(): Promise<void> {\n await this.tabularRepository.setupDatabase?.();\n }\n\n /**\n * Saves a task graph to persistent storage\n * @param key The unique identifier for the task graph\n * @param output The task graph to save\n * @emits graph_saved when the operation completes\n */\n async saveTaskGraph(key: string, output: TaskGraph): Promise<void> {\n const value = JSON.stringify(output.toJSON());\n await this.tabularRepository.put({ key, value });\n this.emit(\"graph_saved\", key);\n }\n\n /**\n * Retrieves a task graph from persistent storage\n * @param key The unique identifier of the task graph to retrieve\n * @returns The retrieved task graph, or undefined if not found\n * @emits graph_retrieved when the operation completes successfully\n */\n async getTaskGraph(key: string): Promise<TaskGraph | undefined> {\n const result = await this.tabularRepository.get({ key });\n const value = result?.value;\n if (!value) {\n return undefined;\n }\n const jsonObj = JSON.parse(value);\n const graph = createGraphFromGraphJSON(jsonObj);\n\n this.emit(\"graph_retrieved\", key);\n return graph;\n }\n\n /**\n * Clears all task graphs from the repository\n * @emits graph_cleared when the operation completes\n */\n async clear(): Promise<void> {\n await this.tabularRepository.deleteAll();\n this.emit(\"graph_cleared\");\n }\n\n /**\n * Returns the number of task graphs stored in the repository\n * @returns The count of stored task graphs\n */\n async size(): Promise<number> {\n return await this.tabularRepository.size();\n }\n}\n",
37
29
  "/**\n * @license\n * Copyright 2025 Steven Roussey <sroussey@gmail.com>\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport { type BaseTabularStorage } from \"@workglow/storage\";\nimport { compress, DataPortSchemaObject, decompress, makeFingerprint } from \"@workglow/util\";\nimport { TaskInput, TaskOutput } from \"../task/TaskTypes\";\nimport { TaskOutputRepository } from \"./TaskOutputRepository\";\n\nexport type TaskOutputPrimaryKey = {\n key: string;\n taskType: string;\n};\n\nexport const TaskOutputSchema = {\n type: \"object\",\n properties: {\n key: { type: \"string\" },\n taskType: { type: \"string\" },\n value: { type: \"string\", contentEncoding: \"blob\" },\n createdAt: { type: \"string\", format: \"date-time\" },\n },\n additionalProperties: false,\n} satisfies DataPortSchemaObject;\n\nexport const TaskOutputPrimaryKeyNames = [\"key\", \"taskType\"] as const;\n\nexport type TaskOutputRepositoryStorage = BaseTabularStorage<\n typeof TaskOutputSchema,\n typeof TaskOutputPrimaryKeyNames\n>;\n\nexport type TaskOutputRepositoryOptions = {\n tabularRepository: TaskOutputRepositoryStorage;\n outputCompression?: boolean;\n};\n\n/**\n * Abstract class for managing task outputs in a repository\n * Provides methods for saving, retrieving, and clearing task outputs\n */\nexport class TaskOutputTabularRepository extends TaskOutputRepository {\n /**\n * The tabular repository for the task outputs\n */\n tabularRepository: TaskOutputRepositoryStorage;\n\n /**\n * Constructor for the TaskOutputTabularRepository\n * @param options The options for the repository\n */\n constructor({ tabularRepository, outputCompression = true }: TaskOutputRepositoryOptions) {\n super({ outputCompression });\n this.tabularRepository = tabularRepository;\n this.outputCompression = outputCompression;\n }\n\n /**\n * Sets up the database for the repository.\n * Must be called before using any other methods.\n */\n async setupDatabase(): Promise<void> {\n await this.tabularRepository.setupDatabase?.();\n }\n\n public async keyFromInputs(inputs: TaskInput): Promise<string> {\n return await makeFingerprint(inputs);\n }\n\n /**\n * Saves a task output to the repository\n * @param taskType The type of task to save the output for\n * @param inputs The input parameters for the task\n * @param output The task output to save\n */\n async saveOutput(\n taskType: string,\n inputs: TaskInput,\n output: TaskOutput,\n createdAt = new Date() // for testing purposes\n ): Promise<void> {\n const key = await this.keyFromInputs(inputs);\n const value = JSON.stringify(output);\n if (this.outputCompression) {\n const compressedValue = await compress(value);\n await this.tabularRepository.put({\n taskType,\n key,\n // contentEncoding: \"blob\" allows Uint8Array despite schema type being \"string\"\n value: compressedValue as unknown as string,\n createdAt: createdAt.toISOString(),\n });\n } else {\n const valueBuffer = Buffer.from(value);\n await this.tabularRepository.put({\n taskType,\n key,\n // contentEncoding: \"blob\" allows Buffer/Uint8Array despite schema type being \"string\"\n value: valueBuffer as unknown as string,\n createdAt: createdAt.toISOString(),\n });\n }\n this.emit(\"output_saved\", taskType);\n }\n\n /**\n * Retrieves a task output from the repository\n * @param taskType The type of task to retrieve the output for\n * @param inputs The input parameters for the task\n * @returns The retrieved task output, or undefined if not found\n */\n async getOutput(taskType: string, inputs: TaskInput): Promise<TaskOutput | undefined> {\n const key = await this.keyFromInputs(inputs);\n const output = await this.tabularRepository.get({ key, taskType });\n this.emit(\"output_retrieved\", taskType);\n if (output?.value) {\n if (this.outputCompression) {\n // Coerce JSON-serialized binary (from filesystem JSON store) back to Uint8Array\n const raw: unknown = output.value as unknown;\n const bytes: Uint8Array =\n raw instanceof Uint8Array\n ? raw\n : Array.isArray(raw)\n ? new Uint8Array(raw as number[])\n : raw && typeof raw === \"object\"\n ? new Uint8Array(\n Object.keys(raw as Record<string, number>)\n .filter((k) => /^\\d+$/.test(k))\n .sort((a, b) => Number(a) - Number(b))\n .map((k) => (raw as Record<string, number>)[k])\n )\n : new Uint8Array();\n const decompressedValue = await decompress(bytes);\n const value = JSON.parse(decompressedValue) as TaskOutput;\n return value as TaskOutput;\n } else {\n const stringValue = output.value.toString();\n const value = JSON.parse(stringValue) as TaskOutput;\n return value as TaskOutput;\n }\n } else {\n return undefined;\n }\n }\n\n /**\n * Clears all task outputs from the repository\n * @emits output_cleared when the operation completes\n */\n async clear(): Promise<void> {\n await this.tabularRepository.deleteAll();\n this.emit(\"output_cleared\");\n }\n\n /**\n * Returns the number of task outputs stored in the repository\n * @returns The count of stored task outputs\n */\n async size(): Promise<number> {\n return await this.tabularRepository.size();\n }\n\n /**\n * Clear all task outputs from the repository that are older than the given date\n * @param olderThanInMs The time in milliseconds to clear task outputs older than\n */\n async clearOlderThan(olderThanInMs: number): Promise<void> {\n const date = new Date(Date.now() - olderThanInMs).toISOString();\n await this.tabularRepository.deleteSearch({ createdAt: { value: date, operator: \"<\" } });\n this.emit(\"output_pruned\");\n }\n}\n"
38
30
  ],
39
- "mappings": "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",
40
- "debugId": "F4A17E03C9237E9864756E2164756E21",
31
+ "mappings": "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",
32
+ "debugId": "B92DF56229C4FC4064756E2164756E21",
41
33
  "names": []
42
34
  }