@workglow/task-graph 0.0.52

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.
Files changed (83) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +1280 -0
  3. package/dist/browser.d.ts +7 -0
  4. package/dist/browser.d.ts.map +1 -0
  5. package/dist/browser.js +2842 -0
  6. package/dist/browser.js.map +33 -0
  7. package/dist/bun.d.ts +7 -0
  8. package/dist/bun.d.ts.map +1 -0
  9. package/dist/bun.js +2843 -0
  10. package/dist/bun.js.map +33 -0
  11. package/dist/common.d.ts +33 -0
  12. package/dist/common.d.ts.map +1 -0
  13. package/dist/node.d.ts +7 -0
  14. package/dist/node.d.ts.map +1 -0
  15. package/dist/node.js +2842 -0
  16. package/dist/node.js.map +33 -0
  17. package/dist/storage/TaskGraphRepository.d.ts +92 -0
  18. package/dist/storage/TaskGraphRepository.d.ts.map +1 -0
  19. package/dist/storage/TaskGraphTabularRepository.d.ts +73 -0
  20. package/dist/storage/TaskGraphTabularRepository.d.ts.map +1 -0
  21. package/dist/storage/TaskOutputRepository.d.ts +93 -0
  22. package/dist/storage/TaskOutputRepository.d.ts.map +1 -0
  23. package/dist/storage/TaskOutputTabularRepository.d.ts +84 -0
  24. package/dist/storage/TaskOutputTabularRepository.d.ts.map +1 -0
  25. package/dist/task/ArrayTask.d.ts +72 -0
  26. package/dist/task/ArrayTask.d.ts.map +1 -0
  27. package/dist/task/ConditionalTask.d.ts +278 -0
  28. package/dist/task/ConditionalTask.d.ts.map +1 -0
  29. package/dist/task/GraphAsTask.d.ts +79 -0
  30. package/dist/task/GraphAsTask.d.ts.map +1 -0
  31. package/dist/task/GraphAsTaskRunner.d.ts +36 -0
  32. package/dist/task/GraphAsTaskRunner.d.ts.map +1 -0
  33. package/dist/task/ITask.d.ts +144 -0
  34. package/dist/task/ITask.d.ts.map +1 -0
  35. package/dist/task/ITaskRunner.d.ts +36 -0
  36. package/dist/task/ITaskRunner.d.ts.map +1 -0
  37. package/dist/task/JobQueueFactory.d.ts +23 -0
  38. package/dist/task/JobQueueFactory.d.ts.map +1 -0
  39. package/dist/task/JobQueueTask.d.ts +65 -0
  40. package/dist/task/JobQueueTask.d.ts.map +1 -0
  41. package/dist/task/Task.d.ts +334 -0
  42. package/dist/task/Task.d.ts.map +1 -0
  43. package/dist/task/TaskError.d.ts +66 -0
  44. package/dist/task/TaskError.d.ts.map +1 -0
  45. package/dist/task/TaskEvents.d.ts +40 -0
  46. package/dist/task/TaskEvents.d.ts.map +1 -0
  47. package/dist/task/TaskJSON.d.ts +82 -0
  48. package/dist/task/TaskJSON.d.ts.map +1 -0
  49. package/dist/task/TaskQueueRegistry.d.ts +69 -0
  50. package/dist/task/TaskQueueRegistry.d.ts.map +1 -0
  51. package/dist/task/TaskRegistry.d.ts +31 -0
  52. package/dist/task/TaskRegistry.d.ts.map +1 -0
  53. package/dist/task/TaskRunner.d.ts +99 -0
  54. package/dist/task/TaskRunner.d.ts.map +1 -0
  55. package/dist/task/TaskTypes.d.ts +68 -0
  56. package/dist/task/TaskTypes.d.ts.map +1 -0
  57. package/dist/task-graph/Conversions.d.ts +28 -0
  58. package/dist/task-graph/Conversions.d.ts.map +1 -0
  59. package/dist/task-graph/Dataflow.d.ts +73 -0
  60. package/dist/task-graph/Dataflow.d.ts.map +1 -0
  61. package/dist/task-graph/DataflowEvents.d.ts +34 -0
  62. package/dist/task-graph/DataflowEvents.d.ts.map +1 -0
  63. package/dist/task-graph/ITaskGraph.d.ts +38 -0
  64. package/dist/task-graph/ITaskGraph.d.ts.map +1 -0
  65. package/dist/task-graph/IWorkflow.d.ts +13 -0
  66. package/dist/task-graph/IWorkflow.d.ts.map +1 -0
  67. package/dist/task-graph/TaskGraph.d.ts +230 -0
  68. package/dist/task-graph/TaskGraph.d.ts.map +1 -0
  69. package/dist/task-graph/TaskGraphEvents.d.ts +54 -0
  70. package/dist/task-graph/TaskGraphEvents.d.ts.map +1 -0
  71. package/dist/task-graph/TaskGraphRunner.d.ts +202 -0
  72. package/dist/task-graph/TaskGraphRunner.d.ts.map +1 -0
  73. package/dist/task-graph/TaskGraphScheduler.d.ts +56 -0
  74. package/dist/task-graph/TaskGraphScheduler.d.ts.map +1 -0
  75. package/dist/task-graph/Workflow.d.ts +155 -0
  76. package/dist/task-graph/Workflow.d.ts.map +1 -0
  77. package/dist/types.d.ts +7 -0
  78. package/dist/types.d.ts.map +1 -0
  79. package/package.json +59 -0
  80. package/src/storage/README.md +61 -0
  81. package/src/task/ConditionalTask.README.md +268 -0
  82. package/src/task/README.md +251 -0
  83. package/src/task-graph/README.md +142 -0
@@ -0,0 +1,155 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2025 Steven Roussey <sroussey@gmail.com>
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+ import { EventEmitter, type EventParameters } from "@workglow/util";
7
+ import { TaskOutputRepository } from "../storage/TaskOutputRepository";
8
+ import { GraphAsTask } from "../task/GraphAsTask";
9
+ import type { ITask, ITaskConstructor } from "../task/ITask";
10
+ import { Task } from "../task/Task";
11
+ import type { JsonTaskItem, TaskGraphJson } from "../task/TaskJSON";
12
+ import { DataPorts, TaskConfig } from "../task/TaskTypes";
13
+ import { PipeFunction, Taskish } from "./Conversions";
14
+ import { IWorkflow } from "./IWorkflow";
15
+ import { TaskGraph } from "./TaskGraph";
16
+ import { CompoundMergeStrategy, type PropertyArrayGraphResult } from "./TaskGraphRunner";
17
+ export type CreateWorkflow<I extends DataPorts, _O extends DataPorts, C extends TaskConfig> = (input?: Partial<I>, config?: Partial<C>) => Workflow;
18
+ export type WorkflowEventListeners = {
19
+ changed: (id: unknown) => void;
20
+ reset: () => void;
21
+ error: (error: string) => void;
22
+ start: () => void;
23
+ complete: () => void;
24
+ abort: (error: string) => void;
25
+ };
26
+ export type WorkflowEvents = keyof WorkflowEventListeners;
27
+ export type WorkflowEventListener<Event extends WorkflowEvents> = WorkflowEventListeners[Event];
28
+ export type WorkflowEventParameters<Event extends WorkflowEvents> = EventParameters<WorkflowEventListeners, Event>;
29
+ /**
30
+ * Class for building and managing a task graph
31
+ * Provides methods for adding tasks, connecting outputs to inputs, and running the task graph
32
+ */
33
+ export declare class Workflow<Input extends DataPorts = DataPorts, Output extends DataPorts = DataPorts> implements IWorkflow<Input, Output> {
34
+ /**
35
+ * Creates a new Workflow
36
+ *
37
+ * @param repository - Optional repository for task outputs
38
+ */
39
+ constructor(repository?: TaskOutputRepository);
40
+ private _graph;
41
+ private _dataFlows;
42
+ private _error;
43
+ private _repository?;
44
+ private _abortController?;
45
+ /**
46
+ * Event emitter for task graph events
47
+ */
48
+ readonly events: EventEmitter<WorkflowEventListeners>;
49
+ /**
50
+ * Creates a helper function for adding specific task types to a Workflow
51
+ *
52
+ * @param taskClass - The task class to create a helper for
53
+ * @returns A function that adds the specified task type to a Workflow
54
+ */
55
+ static createWorkflow<I extends DataPorts, O extends DataPorts, C extends TaskConfig = TaskConfig>(taskClass: ITaskConstructor<I, O, C>): CreateWorkflow<I, O, C>;
56
+ /**
57
+ * Gets the current task graph
58
+ */
59
+ get graph(): TaskGraph;
60
+ /**
61
+ * Sets a new task graph
62
+ */
63
+ set graph(value: TaskGraph);
64
+ /**
65
+ * Gets the current error message
66
+ */
67
+ get error(): string;
68
+ /**
69
+ * Event subscription methods
70
+ */
71
+ on<Event extends WorkflowEvents>(name: Event, fn: WorkflowEventListener<Event>): void;
72
+ off<Event extends WorkflowEvents>(name: Event, fn: WorkflowEventListener<Event>): void;
73
+ once<Event extends WorkflowEvents>(name: Event, fn: WorkflowEventListener<Event>): void;
74
+ waitOn<Event extends WorkflowEvents>(name: Event): Promise<WorkflowEventParameters<Event>>;
75
+ /**
76
+ * Runs the task graph
77
+ *
78
+ * @param input - The input to the task graph
79
+ * @returns The output of the task graph
80
+ */
81
+ run(input?: Input): Promise<PropertyArrayGraphResult<Output>>;
82
+ /**
83
+ * Aborts the running task graph
84
+ */
85
+ abort(): Promise<void>;
86
+ /**
87
+ * Removes the last task from the task graph
88
+ *
89
+ * @returns The current task graph workflow
90
+ */
91
+ pop(): Workflow;
92
+ /**
93
+ * Converts the task graph to JSON
94
+ *
95
+ * @returns The task graph as JSON
96
+ */
97
+ toJSON(): TaskGraphJson;
98
+ /**
99
+ * Converts the task graph to dependency JSON
100
+ *
101
+ * @returns The task graph as dependency JSON
102
+ */
103
+ toDependencyJSON(): JsonTaskItem[];
104
+ pipe<A extends DataPorts, B extends DataPorts>(fn1: Taskish<A, B>): IWorkflow<A, B>;
105
+ pipe<A extends DataPorts, B extends DataPorts, C extends DataPorts>(fn1: Taskish<A, B>, fn2: Taskish<B, C>): IWorkflow<A, C>;
106
+ pipe<A extends DataPorts, B extends DataPorts, C extends DataPorts, D extends DataPorts>(fn1: Taskish<A, B>, fn2: Taskish<B, C>, fn3: Taskish<C, D>): IWorkflow<A, D>;
107
+ pipe<A extends DataPorts, B extends DataPorts, C extends DataPorts, D extends DataPorts, E extends DataPorts>(fn1: Taskish<A, B>, fn2: Taskish<B, C>, fn3: Taskish<C, D>, fn4: Taskish<D, E>): IWorkflow<A, E>;
108
+ pipe<A extends DataPorts, B extends DataPorts, C extends DataPorts, D extends DataPorts, E extends DataPorts, F extends DataPorts>(fn1: Taskish<A, B>, fn2: Taskish<B, C>, fn3: Taskish<C, D>, fn4: Taskish<D, E>, fn5: Taskish<E, F>): IWorkflow<A, F>;
109
+ static pipe<A extends DataPorts, B extends DataPorts>(fn1: PipeFunction<A, B> | ITask<A, B>): IWorkflow;
110
+ static pipe<A extends DataPorts, B extends DataPorts, C extends DataPorts>(fn1: PipeFunction<A, B> | ITask<A, B>, fn2: PipeFunction<B, C> | ITask<B, C>): IWorkflow;
111
+ static pipe<A extends DataPorts, B extends DataPorts, C extends DataPorts, D extends DataPorts>(fn1: PipeFunction<A, B> | ITask<A, B>, fn2: PipeFunction<B, C> | ITask<B, C>, fn3: PipeFunction<C, D> | ITask<C, D>): IWorkflow;
112
+ static pipe<A extends DataPorts, B extends DataPorts, C extends DataPorts, D extends DataPorts, E extends DataPorts>(fn1: PipeFunction<A, B> | ITask<A, B>, fn2: PipeFunction<B, C> | ITask<B, C>, fn3: PipeFunction<C, D> | ITask<C, D>, fn4: PipeFunction<D, E> | ITask<D, E>): IWorkflow;
113
+ static pipe<A extends DataPorts, B extends DataPorts, C extends DataPorts, D extends DataPorts, E extends DataPorts, F extends DataPorts>(fn1: PipeFunction<A, B> | ITask<A, B>, fn2: PipeFunction<B, C> | ITask<B, C>, fn3: PipeFunction<C, D> | ITask<C, D>, fn4: PipeFunction<D, E> | ITask<D, E>, fn5: PipeFunction<E, F> | ITask<E, F>): IWorkflow;
114
+ parallel(args: (PipeFunction<any, any> | Task)[], mergeFn?: CompoundMergeStrategy): IWorkflow;
115
+ static parallel(args: (PipeFunction<any, any> | ITask)[], mergeFn?: CompoundMergeStrategy): IWorkflow;
116
+ /**
117
+ * Renames an output of a task to a new target input
118
+ *
119
+ * @param source - The id of the output to rename
120
+ * @param target - The id of the input to rename to
121
+ * @param index - The index of the task to rename the output of, defaults to the last task
122
+ * @returns The current task graph workflow
123
+ */
124
+ rename(source: string, target: string, index?: number): Workflow;
125
+ toTaskGraph(): TaskGraph;
126
+ toTask(): GraphAsTask;
127
+ /**
128
+ * Resets the task graph workflow to its initial state
129
+ *
130
+ * @returns The current task graph workflow
131
+ */
132
+ reset(): Workflow;
133
+ /**
134
+ * Sets up event listeners for the task graph
135
+ */
136
+ private setupEvents;
137
+ /**
138
+ * Clears event listeners for the task graph
139
+ */
140
+ private clearEvents;
141
+ /**
142
+ * Handles changes to the task graph
143
+ */
144
+ private _onChanged;
145
+ /**
146
+ * Connects outputs to inputs between tasks
147
+ */
148
+ connect(sourceTaskId: unknown, sourceTaskPortId: string, targetTaskId: unknown, targetTaskPortId: string): Workflow;
149
+ addTask<I extends DataPorts, O extends DataPorts, C extends TaskConfig = TaskConfig>(taskClass: ITaskConstructor<I, O, C>, input: I, config: C): ITask<I, O, C>;
150
+ }
151
+ /**
152
+ * Helper function for backward compatibility
153
+ */
154
+ export declare function CreateWorkflow<I extends DataPorts, O extends DataPorts, C extends TaskConfig = TaskConfig>(taskClass: any): CreateWorkflow<I, O, C>;
155
+ //# sourceMappingURL=Workflow.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Workflow.d.ts","sourceRoot":"","sources":["../../src/task-graph/Workflow.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2025 Steven Roussey <sroussey@gmail.com>
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+ export * from "./common";
7
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,cAAc,UAAU,CAAC"}
package/package.json ADDED
@@ -0,0 +1,59 @@
1
+ {
2
+ "name": "@workglow/task-graph",
3
+ "type": "module",
4
+ "version": "0.0.52",
5
+ "description": "Task graph management for Workglow, providing DAG construction, execution planning, and workflow orchestration.",
6
+ "scripts": {
7
+ "watch": "concurrently -c 'auto' 'bun:watch-*'",
8
+ "watch-browser": "bun build --watch --no-clear-screen --target=browser --sourcemap=external --packages=external --outdir ./dist ./src/browser.ts",
9
+ "watch-node": "bun build --watch --no-clear-screen --target=node --sourcemap=external --packages=external --outdir ./dist ./src/node.ts",
10
+ "watch-bun": "bun build --watch --no-clear-screen --target=bun --sourcemap=external --packages=external --outdir ./dist ./src/bun.ts",
11
+ "watch-types": "tsc --watch --preserveWatchOutput",
12
+ "build-package": "bun run build-clean && concurrently -c 'auto' -n 'browser,node,bun,types' 'bun run build-browser' 'bun run build-node' 'bun run build-bun' 'bun run build-types'",
13
+ "build-clean": "rm -fr dist/* tsconfig.tsbuildinfo",
14
+ "build-browser": "bun build --target=browser --sourcemap=external --packages=external --outdir ./dist ./src/browser.ts",
15
+ "build-node": "bun build --target=node --sourcemap=external --packages=external --outdir ./dist ./src/node.ts",
16
+ "build-bun": "bun build --target=bun --sourcemap=external --packages=external --outdir ./dist ./src/bun.ts",
17
+ "build-types": "rm -f tsconfig.tsbuildinfo && tsc",
18
+ "lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0",
19
+ "test": "bun test",
20
+ "prepare": "node -e \"const pkg=require('./package.json');pkg.exports['.'].bun='./dist/bun.js';pkg.exports['.'].types='./dist/types.d.ts';require('fs').writeFileSync('package.json',JSON.stringify(pkg,null,2))\""
21
+ },
22
+ "exports": {
23
+ ".": {
24
+ "react-native": "./dist/browser.js",
25
+ "browser": "./dist/browser.js",
26
+ "bun": "./dist/bun.js",
27
+ "types": "./dist/types.d.ts",
28
+ "node": "./dist/node.js"
29
+ }
30
+ },
31
+ "files": [
32
+ "dist",
33
+ "src/**/*.md"
34
+ ],
35
+ "publishConfig": {
36
+ "access": "public"
37
+ },
38
+ "peerDependencies": {
39
+ "@workglow/job-queue": "0.0.52",
40
+ "@workglow/storage": "0.0.52",
41
+ "@workglow/util": "0.0.52"
42
+ },
43
+ "peerDependenciesMeta": {
44
+ "@workglow/job-queue": {
45
+ "optional": false
46
+ },
47
+ "@workglow/storage": {
48
+ "optional": false
49
+ },
50
+ "@workglow/util": {
51
+ "optional": false
52
+ }
53
+ },
54
+ "devDependencies": {
55
+ "@workglow/job-queue": "0.0.52",
56
+ "@workglow/storage": "0.0.52",
57
+ "@workglow/util": "0.0.52"
58
+ }
59
+ }
@@ -0,0 +1,61 @@
1
+ # Task Graph Storage Module
2
+
3
+ This module provides persistent storage solutions for task graphs and task outputs using various storage backends. The implementation follows a repository pattern with multiple concrete implementations for different storage technologies.
4
+
5
+ - [Task Output Repositories](#task-output-repositories)
6
+ - [Task Graph Repositories](#task-graph-repositories)
7
+ - [Testing](#testing)
8
+ - [Architecture Notes](#architecture-notes)
9
+ - [License](#license)
10
+
11
+ ## Task Output Repositories
12
+
13
+ TaskOutputRepository is a repository for task caching. If a task has the same input it is assumed to return the same output. The task graph runner does not resume, but you can quickly get to the aborted state by using the output repository and re-running the task graph.
14
+
15
+ ```typescript
16
+ // Example usage
17
+ import { SqliteTaskOutputRepository } from "@workglow/test"; // pre-bound implementation for sqlite
18
+ const outputRepo = new SqliteTaskOutputRepository(":memory:");
19
+ await outputRepo.saveOutput("MyTaskType", { param: "value" }, { result: "data" });
20
+ ```
21
+
22
+ ## Task Graph Repositories
23
+
24
+ TaskGraphRepository is a repository for task graphs themselves. It is used to save and load task graphs.
25
+
26
+ The `TaskGraphRepository` class provides:
27
+
28
+ - CRUD operations for task graphs
29
+ - Event emitters for storage operations
30
+ - Serialization/deserialization of task graphs with data flows
31
+
32
+ ```typescript
33
+ // Example usage
34
+ import { SqliteTaskGraphRepository } from "@workglow/test"; // pre-bound implementation for sqlite
35
+ const fsRepo = new FsFolderTaskGraphRepository("./storage");
36
+ const memoryRepo = new InMemoryTaskGraphRepository();
37
+ ```
38
+
39
+ ## Testing
40
+
41
+ Tests are written using Bun test runner. To run tests:
42
+
43
+ ```bash
44
+ bun test
45
+ ```
46
+
47
+ Tests include:
48
+
49
+ - Generic repository tests that run against all implementations
50
+ - Storage-specific test suites
51
+
52
+ ## Architecture Notes
53
+
54
+ - All repositories use a TabularRepository pattern internally
55
+ - Schema definitions are centralized in `TaskGraphSchema`/`TaskOutputSchema`
56
+ - Primary key configurations are managed through `PrimaryKeyNames` constants
57
+ - Event emitters provide hooks for monitoring repository operations
58
+
59
+ ## License
60
+
61
+ Apache 2.0 - See LICENSE file for details
@@ -0,0 +1,268 @@
1
+ # ConditionalTask
2
+
3
+ A task that implements conditional branching within a task graph, similar to if/then/else or switch/case statements.
4
+
5
+ ## Overview
6
+
7
+ `ConditionalTask` evaluates configured conditions against its input and selectively enables output ports for active branches. Inactive branches result in `DISABLED` status for their downstream dataflows, which cascades to disable unreachable downstream tasks.
8
+
9
+ ## Key Features
10
+
11
+ - **Condition-based routing**: Route data to different downstream tasks based on input values
12
+ - **Exclusive mode (default)**: Act as a switch/case where only the first matching branch activates
13
+ - **Multi-path mode**: Enable multiple branches simultaneously when conditions match
14
+ - **Default branch**: Specify a fallback branch when no conditions match
15
+ - **Disabled propagation**: Inactive branches result in DISABLED status for downstream tasks
16
+
17
+ ## Basic Usage
18
+
19
+ ### Simple If/Else
20
+
21
+ ```typescript
22
+ import { ConditionalTask, TaskGraph, Dataflow } from "@workglow/task-graph";
23
+
24
+ const conditional = new ConditionalTask(
25
+ {},
26
+ {
27
+ branches: [
28
+ { id: "high", condition: (i) => i.value > 100, outputPort: "highPath" },
29
+ { id: "low", condition: (i) => i.value <= 100, outputPort: "lowPath" },
30
+ ],
31
+ }
32
+ );
33
+
34
+ const highHandler = new SomeTask({}, { id: "highHandler" });
35
+ const lowHandler = new SomeTask({}, { id: "lowHandler" });
36
+
37
+ const graph = new TaskGraph();
38
+ graph.addTasks([conditional, highHandler, lowHandler]);
39
+ graph.addDataflow(new Dataflow(conditional.config.id, "highPath", highHandler.config.id, "*"));
40
+ graph.addDataflow(new Dataflow(conditional.config.id, "lowPath", lowHandler.config.id, "*"));
41
+
42
+ // When value > 100, highHandler runs and lowHandler is DISABLED
43
+ // When value <= 100, lowHandler runs and highHandler is DISABLED
44
+ await graph.run({ value: 150 });
45
+ ```
46
+
47
+ ### Switch/Case Pattern
48
+
49
+ ```typescript
50
+ const statusRouter = new ConditionalTask(
51
+ {},
52
+ {
53
+ branches: [
54
+ { id: "active", condition: (i) => i.status === "active", outputPort: "active" },
55
+ { id: "pending", condition: (i) => i.status === "pending", outputPort: "pending" },
56
+ { id: "inactive", condition: (i) => i.status === "inactive", outputPort: "inactive" },
57
+ ],
58
+ defaultBranch: "inactive", // Fallback if no match
59
+ exclusive: true, // Only first match activates (default)
60
+ }
61
+ );
62
+ ```
63
+
64
+ ### Multi-Path Fan-Out
65
+
66
+ ```typescript
67
+ const fanOut = new ConditionalTask(
68
+ {},
69
+ {
70
+ branches: [
71
+ { id: "log", condition: () => true, outputPort: "logger" },
72
+ { id: "process", condition: () => true, outputPort: "processor" },
73
+ { id: "archive", condition: (i) => i.shouldArchive, outputPort: "archiver" },
74
+ ],
75
+ exclusive: false, // All matching branches activate
76
+ }
77
+ );
78
+ ```
79
+
80
+ ## Configuration
81
+
82
+ ### BranchConfig
83
+
84
+ Each branch in the `branches` array has the following properties:
85
+
86
+ | Property | Type | Description |
87
+ | ------------ | -------------------- | -------------------------------- |
88
+ | `id` | `string` | Unique identifier for the branch |
89
+ | `condition` | `(input) => boolean` | Predicate function to evaluate |
90
+ | `outputPort` | `string` | Output port name for this branch |
91
+
92
+ ### ConditionalTaskConfig
93
+
94
+ | Property | Type | Default | Description |
95
+ | --------------- | ---------------- | ----------- | --------------------------------------------- |
96
+ | `branches` | `BranchConfig[]` | Required | Array of branch configurations |
97
+ | `defaultBranch` | `string` | `undefined` | Branch ID to use if no conditions match |
98
+ | `exclusive` | `boolean` | `true` | If true, only first matching branch activates |
99
+
100
+ ## Execution Modes
101
+
102
+ ### Exclusive Mode (Default)
103
+
104
+ In exclusive mode (`exclusive: true`), branches are evaluated in order and only the first matching branch becomes active. This is similar to a switch/case statement or if/else-if chain.
105
+
106
+ ```typescript
107
+ const router = new ConditionalTask(
108
+ {},
109
+ {
110
+ branches: [
111
+ { id: "tier1", condition: (i) => i.value > 1000, outputPort: "tier1" },
112
+ { id: "tier2", condition: (i) => i.value > 100, outputPort: "tier2" },
113
+ { id: "tier3", condition: (i) => i.value > 0, outputPort: "tier3" },
114
+ ],
115
+ exclusive: true,
116
+ }
117
+ );
118
+
119
+ // With value = 500:
120
+ // - tier1 condition: 500 > 1000 = false
121
+ // - tier2 condition: 500 > 100 = true ← ACTIVATES, stops here
122
+ // - tier3 is NOT evaluated (exclusive mode)
123
+ ```
124
+
125
+ ### Multi-Path Mode
126
+
127
+ In multi-path mode (`exclusive: false`), all branches whose conditions evaluate to true become active simultaneously. This enables fan-out patterns.
128
+
129
+ ```typescript
130
+ const multiRouter = new ConditionalTask(
131
+ {},
132
+ {
133
+ branches: [
134
+ { id: "even", condition: (i) => i.value % 2 === 0, outputPort: "evenPath" },
135
+ { id: "div3", condition: (i) => i.value % 3 === 0, outputPort: "div3Path" },
136
+ { id: "div5", condition: (i) => i.value % 5 === 0, outputPort: "div5Path" },
137
+ ],
138
+ exclusive: false,
139
+ }
140
+ );
141
+
142
+ // With value = 30:
143
+ // - even: 30 % 2 === 0 = true ← ACTIVATES
144
+ // - div3: 30 % 3 === 0 = true ← ACTIVATES
145
+ // - div5: 30 % 5 === 0 = true ← ACTIVATES
146
+ // All three downstream tasks will run!
147
+ ```
148
+
149
+ ## Output Behavior
150
+
151
+ For each active branch, the task passes through its entire input to that branch's output port:
152
+
153
+ ```typescript
154
+ // Input: { value: 150, metadata: { source: "api" } }
155
+
156
+ // Output when "high" branch is active:
157
+ {
158
+ _activeBranches: ["high"],
159
+ highPath: { value: 150, metadata: { source: "api" } }
160
+ }
161
+ ```
162
+
163
+ The `_activeBranches` property is always present and contains the IDs of all active branches.
164
+
165
+ ## Dataflow Wiring
166
+
167
+ When wiring ConditionalTask outputs to downstream tasks, use `"*"` (DATAFLOW_ALL_PORTS) as the target port to pass all properties from the branch output:
168
+
169
+ ```typescript
170
+ // Pass all properties from the branch output to the downstream task
171
+ graph.addDataflow(
172
+ new Dataflow(
173
+ conditional.config.id,
174
+ "highPath", // Source port (branch output)
175
+ handler.config.id,
176
+ "*" // Target: all ports (passes { value, metadata, ... })
177
+ )
178
+ );
179
+ ```
180
+
181
+ ## Disabled Status Propagation
182
+
183
+ When a branch is inactive, its outgoing dataflow is set to `DISABLED` status. The graph runner then propagates this status:
184
+
185
+ 1. If ALL incoming dataflows to a task are `DISABLED`, that task becomes `DISABLED`
186
+ 2. The disabled task's outgoing dataflows are also set to `DISABLED`
187
+ 3. This cascades through the graph until no more tasks can be disabled
188
+
189
+ This ensures that tasks which cannot receive data (because all paths to them are disabled) don't run unnecessarily.
190
+
191
+ ## Inspecting Branch Status
192
+
193
+ After execution, you can inspect which branches were activated:
194
+
195
+ ```typescript
196
+ await conditionalTask.run({ value: 150 });
197
+
198
+ // Check individual branch
199
+ if (conditionalTask.isBranchActive("high")) {
200
+ console.log("High value path was taken");
201
+ }
202
+
203
+ // Get all active branches
204
+ const active = conditionalTask.getActiveBranches();
205
+ console.log("Active branches:", Array.from(active));
206
+
207
+ // Get port status map
208
+ const portStatus = conditionalTask.getPortActiveStatus();
209
+ for (const [port, isActive] of portStatus) {
210
+ console.log(`Port ${port}: ${isActive ? "active" : "inactive"}`);
211
+ }
212
+ ```
213
+
214
+ ## Events
215
+
216
+ ConditionalTask emits a custom event after branch evaluation:
217
+
218
+ ```typescript
219
+ conditionalTask.on("branches_evaluated", (activeBranches: Set<string>) => {
220
+ console.log("Active branches:", Array.from(activeBranches));
221
+ });
222
+ ```
223
+
224
+ ## Error Handling
225
+
226
+ If a condition function throws an error, the branch is treated as if the condition returned `false`:
227
+
228
+ ```typescript
229
+ const router = new ConditionalTask(
230
+ {},
231
+ {
232
+ branches: [
233
+ {
234
+ id: "risky",
235
+ condition: (i) => {
236
+ if (!i.data) throw new Error("No data!");
237
+ return i.data.value > 100;
238
+ },
239
+ outputPort: "risky",
240
+ },
241
+ { id: "safe", condition: () => true, outputPort: "safe" },
242
+ ],
243
+ }
244
+ );
245
+
246
+ // If input.data is undefined:
247
+ // - "risky" condition throws, treated as false
248
+ // - "safe" condition returns true, becomes active
249
+ // Console warning: Condition evaluation failed for branch "risky": Error: No data!
250
+ ```
251
+
252
+ ## Integration with Task Graph
253
+
254
+ ConditionalTask integrates seamlessly with TaskGraph and its scheduler:
255
+
256
+ 1. ConditionalTask executes and determines active branches
257
+ 2. Graph runner sets dataflow status based on branch activation
258
+ 3. Scheduler respects DISABLED status when determining ready tasks
259
+ 4. Downstream tasks on disabled branches never execute
260
+
261
+ This makes ConditionalTask ideal for implementing:
262
+
263
+ - Feature flags
264
+ - A/B testing
265
+ - Error handling and retry logic
266
+ - Priority-based routing
267
+ - Validation pipelines
268
+ - Any workflow that requires conditional execution paths