flowcraft 1.0.0 → 2.1.0

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 (201) hide show
  1. package/README.md +37 -134
  2. package/dist/analysis.d.ts +43 -0
  3. package/dist/analysis.js +3 -0
  4. package/dist/chunk-4PELJWF7.js +29 -0
  5. package/dist/chunk-4PELJWF7.js.map +1 -0
  6. package/dist/chunk-55J6XMHW.js +3 -0
  7. package/dist/{chunk-7XUN3OQT.js.map → chunk-55J6XMHW.js.map} +1 -1
  8. package/dist/chunk-5EHIPX23.js +202 -0
  9. package/dist/chunk-5EHIPX23.js.map +1 -0
  10. package/dist/chunk-5QMPFUKA.js +40 -0
  11. package/dist/chunk-5QMPFUKA.js.map +1 -0
  12. package/dist/chunk-5ZWYSKMH.js +147 -0
  13. package/dist/chunk-5ZWYSKMH.js.map +1 -0
  14. package/dist/chunk-5ZXV3R5D.js +28 -0
  15. package/dist/chunk-5ZXV3R5D.js.map +1 -0
  16. package/dist/chunk-CO5BTPKI.js +410 -0
  17. package/dist/chunk-CO5BTPKI.js.map +1 -0
  18. package/dist/chunk-CSZ6EOWG.js +61 -0
  19. package/dist/chunk-CSZ6EOWG.js.map +1 -0
  20. package/dist/chunk-CYHZ2YVH.js +24 -0
  21. package/dist/chunk-CYHZ2YVH.js.map +1 -0
  22. package/dist/chunk-DSYAC4WB.js +27 -0
  23. package/dist/chunk-DSYAC4WB.js.map +1 -0
  24. package/dist/chunk-HMR2GEGE.js +3 -0
  25. package/dist/{chunk-F2RSES6P.js.map → chunk-HMR2GEGE.js.map} +1 -1
  26. package/dist/chunk-HN72TZY5.js +110 -0
  27. package/dist/chunk-HN72TZY5.js.map +1 -0
  28. package/dist/chunk-KWQHFT7E.js +49 -0
  29. package/dist/chunk-KWQHFT7E.js.map +1 -0
  30. package/dist/chunk-PH2IYZHV.js +48 -0
  31. package/dist/chunk-PH2IYZHV.js.map +1 -0
  32. package/dist/chunk-QRMUKDSP.js +141 -0
  33. package/dist/chunk-QRMUKDSP.js.map +1 -0
  34. package/dist/chunk-UETC63DP.js +65 -0
  35. package/dist/chunk-UETC63DP.js.map +1 -0
  36. package/dist/chunk-UMXW3TCY.js +165 -0
  37. package/dist/chunk-UMXW3TCY.js.map +1 -0
  38. package/dist/context.d.ts +23 -105
  39. package/dist/context.js +1 -1
  40. package/dist/errors.d.ts +15 -31
  41. package/dist/errors.js +1 -1
  42. package/dist/evaluator.d.ts +30 -0
  43. package/dist/evaluator.js +3 -0
  44. package/dist/evaluator.js.map +1 -0
  45. package/dist/flow.d.ts +55 -0
  46. package/dist/flow.js +4 -0
  47. package/dist/flow.js.map +1 -0
  48. package/dist/index.d.ts +15 -16
  49. package/dist/index.js +17 -25
  50. package/dist/linter.d.ts +24 -0
  51. package/dist/linter.js +4 -0
  52. package/dist/linter.js.map +1 -0
  53. package/dist/logger.d.ts +15 -40
  54. package/dist/logger.js +1 -1
  55. package/dist/node.d.ts +1 -0
  56. package/dist/node.js +3 -0
  57. package/dist/node.js.map +1 -0
  58. package/dist/runtime/adapter.d.ts +94 -0
  59. package/dist/runtime/adapter.js +15 -0
  60. package/dist/runtime/adapter.js.map +1 -0
  61. package/dist/runtime/executors.d.ts +26 -0
  62. package/dist/runtime/executors.js +4 -0
  63. package/dist/runtime/executors.js.map +1 -0
  64. package/dist/runtime/index.d.ts +7 -0
  65. package/dist/runtime/index.js +16 -0
  66. package/dist/runtime/runtime.d.ts +34 -0
  67. package/dist/runtime/runtime.js +14 -0
  68. package/dist/runtime/runtime.js.map +1 -0
  69. package/dist/runtime/state.d.ts +21 -0
  70. package/dist/runtime/state.js +4 -0
  71. package/dist/runtime/state.js.map +1 -0
  72. package/dist/runtime/traverser.d.ts +25 -0
  73. package/dist/runtime/traverser.js +5 -0
  74. package/dist/runtime/traverser.js.map +1 -0
  75. package/dist/runtime/types.d.ts +15 -0
  76. package/dist/runtime/types.js +3 -0
  77. package/dist/sanitizer.d.ts +10 -0
  78. package/dist/sanitizer.js +3 -0
  79. package/dist/{utils/sanitize.js.map → sanitizer.js.map} +1 -1
  80. package/dist/serializer.d.ts +16 -0
  81. package/dist/serializer.js +3 -0
  82. package/dist/serializer.js.map +1 -0
  83. package/dist/types-lG3xCzp_.d.ts +206 -0
  84. package/dist/types.d.ts +1 -3
  85. package/dist/types.js +1 -1
  86. package/package.json +10 -21
  87. package/LICENSE +0 -21
  88. package/dist/builder/graph/graph.d.ts +0 -57
  89. package/dist/builder/graph/graph.js +0 -21
  90. package/dist/builder/graph/graph.js.map +0 -1
  91. package/dist/builder/graph/index.d.ts +0 -8
  92. package/dist/builder/graph/index.js +0 -23
  93. package/dist/builder/graph/internal-nodes.d.ts +0 -59
  94. package/dist/builder/graph/internal-nodes.js +0 -20
  95. package/dist/builder/graph/internal-nodes.js.map +0 -1
  96. package/dist/builder/graph/runner.d.ts +0 -51
  97. package/dist/builder/graph/runner.js +0 -21
  98. package/dist/builder/graph/runner.js.map +0 -1
  99. package/dist/builder/graph/types.d.ts +0 -3
  100. package/dist/builder/graph/types.js +0 -3
  101. package/dist/builder/index.d.ts +0 -8
  102. package/dist/builder/index.js +0 -24
  103. package/dist/builder/index.js.map +0 -1
  104. package/dist/builder/patterns.d.ts +0 -136
  105. package/dist/builder/patterns.js +0 -19
  106. package/dist/builder/patterns.js.map +0 -1
  107. package/dist/chunk-3YMBNZ77.js +0 -441
  108. package/dist/chunk-3YMBNZ77.js.map +0 -1
  109. package/dist/chunk-64DNBF5W.js +0 -36
  110. package/dist/chunk-64DNBF5W.js.map +0 -1
  111. package/dist/chunk-6QCXIRLA.js +0 -18
  112. package/dist/chunk-6QCXIRLA.js.map +0 -1
  113. package/dist/chunk-7XUN3OQT.js +0 -3
  114. package/dist/chunk-AOHBHYF6.js +0 -7
  115. package/dist/chunk-AOHBHYF6.js.map +0 -1
  116. package/dist/chunk-BRFMFLR6.js +0 -85
  117. package/dist/chunk-BRFMFLR6.js.map +0 -1
  118. package/dist/chunk-ELEHMJPM.js +0 -13
  119. package/dist/chunk-ELEHMJPM.js.map +0 -1
  120. package/dist/chunk-F2RSES6P.js +0 -3
  121. package/dist/chunk-F6C6J7HK.js +0 -3
  122. package/dist/chunk-F6C6J7HK.js.map +0 -1
  123. package/dist/chunk-GMKJ34T2.js +0 -3
  124. package/dist/chunk-GMKJ34T2.js.map +0 -1
  125. package/dist/chunk-HEO3XL4Z.js +0 -328
  126. package/dist/chunk-HEO3XL4Z.js.map +0 -1
  127. package/dist/chunk-IIKTTIW5.js +0 -56
  128. package/dist/chunk-IIKTTIW5.js.map +0 -1
  129. package/dist/chunk-KOBEU2EM.js +0 -3
  130. package/dist/chunk-KOBEU2EM.js.map +0 -1
  131. package/dist/chunk-L5PK5VL2.js +0 -178
  132. package/dist/chunk-L5PK5VL2.js.map +0 -1
  133. package/dist/chunk-P3RPDZHO.js +0 -36
  134. package/dist/chunk-P3RPDZHO.js.map +0 -1
  135. package/dist/chunk-PNWOW52F.js +0 -19
  136. package/dist/chunk-PNWOW52F.js.map +0 -1
  137. package/dist/chunk-R27FIYR5.js +0 -62
  138. package/dist/chunk-R27FIYR5.js.map +0 -1
  139. package/dist/chunk-S4WFNGQG.js +0 -17
  140. package/dist/chunk-S4WFNGQG.js.map +0 -1
  141. package/dist/chunk-TS3M7MWA.js +0 -3
  142. package/dist/chunk-TS3M7MWA.js.map +0 -1
  143. package/dist/chunk-UY4PNPBX.js +0 -156
  144. package/dist/chunk-UY4PNPBX.js.map +0 -1
  145. package/dist/chunk-VMH2LRM6.js +0 -114
  146. package/dist/chunk-VMH2LRM6.js.map +0 -1
  147. package/dist/chunk-VZDHIOCH.js +0 -76
  148. package/dist/chunk-VZDHIOCH.js.map +0 -1
  149. package/dist/chunk-WGVHM7DU.js +0 -66
  150. package/dist/chunk-WGVHM7DU.js.map +0 -1
  151. package/dist/chunk-WR5PDOPP.js +0 -91
  152. package/dist/chunk-WR5PDOPP.js.map +0 -1
  153. package/dist/chunk-YR433ZDA.js +0 -20
  154. package/dist/chunk-YR433ZDA.js.map +0 -1
  155. package/dist/executors/in-memory.d.ts +0 -39
  156. package/dist/executors/in-memory.js +0 -6
  157. package/dist/executors/in-memory.js.map +0 -1
  158. package/dist/executors/types.d.ts +0 -3
  159. package/dist/executors/types.js +0 -3
  160. package/dist/executors/types.js.map +0 -1
  161. package/dist/functions.d.ts +0 -88
  162. package/dist/functions.js +0 -21
  163. package/dist/functions.js.map +0 -1
  164. package/dist/types-U76Ukj96.d.ts +0 -609
  165. package/dist/utils/analysis.d.ts +0 -75
  166. package/dist/utils/analysis.js +0 -3
  167. package/dist/utils/index.d.ts +0 -8
  168. package/dist/utils/index.js +0 -10
  169. package/dist/utils/index.js.map +0 -1
  170. package/dist/utils/mermaid.d.ts +0 -46
  171. package/dist/utils/mermaid.js +0 -4
  172. package/dist/utils/mermaid.js.map +0 -1
  173. package/dist/utils/middleware.d.ts +0 -11
  174. package/dist/utils/middleware.js +0 -3
  175. package/dist/utils/middleware.js.map +0 -1
  176. package/dist/utils/sanitize.d.ts +0 -19
  177. package/dist/utils/sanitize.js +0 -3
  178. package/dist/utils/sleep.d.ts +0 -9
  179. package/dist/utils/sleep.js +0 -4
  180. package/dist/utils/sleep.js.map +0 -1
  181. package/dist/workflow/AbstractNode.d.ts +0 -3
  182. package/dist/workflow/AbstractNode.js +0 -4
  183. package/dist/workflow/AbstractNode.js.map +0 -1
  184. package/dist/workflow/Flow.d.ts +0 -3
  185. package/dist/workflow/Flow.js +0 -16
  186. package/dist/workflow/Flow.js.map +0 -1
  187. package/dist/workflow/Node.d.ts +0 -3
  188. package/dist/workflow/Node.js +0 -15
  189. package/dist/workflow/Node.js.map +0 -1
  190. package/dist/workflow/index.d.ts +0 -4
  191. package/dist/workflow/index.js +0 -18
  192. package/dist/workflow/index.js.map +0 -1
  193. package/dist/workflow/node-patterns.d.ts +0 -55
  194. package/dist/workflow/node-patterns.js +0 -16
  195. package/dist/workflow/node-patterns.js.map +0 -1
  196. package/dist/workflow/registry.d.ts +0 -17
  197. package/dist/workflow/registry.js +0 -3
  198. package/dist/workflow/registry.js.map +0 -1
  199. /package/dist/{utils/analysis.js.map → analysis.js.map} +0 -0
  200. /package/dist/{builder/graph → runtime}/index.js.map +0 -0
  201. /package/dist/{builder/graph → runtime}/types.js.map +0 -0
@@ -1,328 +0,0 @@
1
- import { sleep } from './chunk-6QCXIRLA.js';
2
- import { InMemoryExecutor } from './chunk-BRFMFLR6.js';
3
- import { AbstractNode } from './chunk-VZDHIOCH.js';
4
- import { getFlowConstructor } from './chunk-S4WFNGQG.js';
5
- import { AbortError, WorkflowError, FatalWorkflowError } from './chunk-64DNBF5W.js';
6
- import { NullLogger } from './chunk-IIKTTIW5.js';
7
- import { DEFAULT_ACTION, FILTER_FAILED } from './chunk-AOHBHYF6.js';
8
-
9
- // src/workflow/Node.ts
10
- var Node = class _Node extends AbstractNode {
11
- /** The total number of times the `exec` phase will be attempted. */
12
- maxRetries;
13
- /** The time in milliseconds to wait between failed `exec` attempts. */
14
- wait;
15
- /**
16
- * @param options Configuration options for the node's behavior.
17
- * @param options.maxRetries Total number of `exec` attempts. Defaults to `1`.
18
- * @param options.wait Milliseconds to wait between failed `exec` attempts. Defaults to `0`.
19
- */
20
- constructor(options = {}) {
21
- super();
22
- this.maxRetries = options.maxRetries ?? 1;
23
- this.wait = options.wait ?? 0;
24
- }
25
- _wrapError(e, phase) {
26
- if (e instanceof AbortError || e instanceof WorkflowError)
27
- return e;
28
- return new WorkflowError(`Failed in ${phase} phase for node ${this.constructor.name}`, this.constructor.name, phase, e);
29
- }
30
- /**
31
- * (Lifecycle) Prepares data for execution. Runs once before `exec`.
32
- * This is the ideal place to read data from the `Context`.
33
- * @param args The arguments for the node, including `ctx` and `params`.
34
- * @returns The data required by the `exec` phase.
35
- */
36
- async prep(args) {
37
- return void 0;
38
- }
39
- /**
40
- * (Lifecycle) Performs the core, isolated logic of the node.
41
- * This is the only phase that is retried on failure. It should not access the `Context` directly.
42
- * @param args The arguments for the node, including `prepRes`.
43
- * @returns The result of the execution.
44
- */
45
- async exec(args) {
46
- return void 0;
47
- }
48
- /**
49
- * (Lifecycle) Processes results and determines the next step. Runs once after `exec` succeeds.
50
- * This is the ideal place to write data to the `Context`.
51
- * @param args The arguments for the node, including `execRes`.
52
- * @returns An "action" string to determine which successor to execute next. Defaults to `DEFAULT_ACTION`.
53
- */
54
- async post(args) {
55
- return DEFAULT_ACTION;
56
- }
57
- /**
58
- * (Lifecycle) A fallback that runs if all `exec` retries fail.
59
- * If not implemented, the final error will be re-thrown, halting the workflow.
60
- * @param args The arguments for the node, including the final `error` that caused the failure.
61
- * @returns A fallback result of type `ExecRes`, allowing the workflow to recover and continue.
62
- */
63
- async execFallback(args) {
64
- if (args.error)
65
- throw args.error;
66
- throw new Error(`Node ${this.constructor.name} failed and has no fallback implementation.`);
67
- }
68
- /**
69
- * The internal retry-aware execution logic for the `exec` phase.
70
- * @internal
71
- */
72
- async _exec(args) {
73
- let lastError;
74
- for (let curRetry = 0; curRetry < this.maxRetries; curRetry++) {
75
- if (args.signal?.aborted)
76
- throw new AbortError();
77
- try {
78
- return await this.exec(args);
79
- } catch (e) {
80
- const error = e;
81
- lastError = error;
82
- if (error instanceof FatalWorkflowError)
83
- throw error;
84
- if (error instanceof AbortError || error.name === "AbortError")
85
- throw error;
86
- if (curRetry < this.maxRetries - 1) {
87
- args.logger.warn(`Attempt ${curRetry + 1}/${this.maxRetries} failed for ${this.constructor.name}. Retrying...`, { error });
88
- if (this.wait > 0)
89
- await sleep(this.wait, args.signal);
90
- }
91
- }
92
- }
93
- args.logger.error(`All retries failed for ${this.constructor.name}. Executing fallback.`, { error: lastError });
94
- if (args.signal?.aborted)
95
- throw new AbortError();
96
- return await this.execFallback({ ...args, error: lastError });
97
- }
98
- /**
99
- * The internal method that executes the node's full lifecycle.
100
- * @internal
101
- */
102
- async _run({ ctx, params, signal, logger, executor, visitedInParallel }) {
103
- if (signal?.aborted)
104
- throw new AbortError();
105
- let prepRes;
106
- try {
107
- prepRes = await this.prep({ ctx, params, signal, logger, prepRes: void 0, execRes: void 0, executor, visitedInParallel });
108
- } catch (e) {
109
- throw this._wrapError(e, "prep");
110
- }
111
- if (signal?.aborted)
112
- throw new AbortError();
113
- let execRes;
114
- try {
115
- execRes = await this._exec({ ctx, params, signal, logger, prepRes, execRes: void 0, executor, visitedInParallel });
116
- } catch (e) {
117
- throw this._wrapError(e, "exec");
118
- }
119
- if (signal?.aborted)
120
- throw new AbortError();
121
- try {
122
- const action = await this.post({ ctx, params, signal, logger, prepRes, execRes, executor, visitedInParallel });
123
- return action === void 0 ? DEFAULT_ACTION : action;
124
- } catch (e) {
125
- throw this._wrapError(e, "post");
126
- }
127
- }
128
- /**
129
- * Runs the node as a standalone unit, independent of a larger flow.
130
- * This is useful for testing individual nodes in isolation.
131
- *
132
- * @param ctx The shared workflow context.
133
- * @param options Runtime options like a logger or abort controller.
134
- * @returns The result of the node's `post` method (its action).
135
- */
136
- async run(ctx, options) {
137
- const Flow = getFlowConstructor();
138
- const logger = options?.logger ?? new NullLogger();
139
- if (this.successors.size > 0 && !(this instanceof Flow))
140
- logger.warn("Node.run() called directly on a node with successors. The flow will not continue. Use a Flow to execute a sequence.");
141
- const executor = options?.executor ?? new InMemoryExecutor();
142
- return executor.run(new Flow(this), ctx, { ...options, params: this.params });
143
- }
144
- /**
145
- * Creates a new node that transforms the result of this node's `exec` phase.
146
- *
147
- * @remarks
148
- * This method returns a **new** `Node` instance and does not modify the original.
149
- * The new node inherits the original's `prep` method. The original `post` method
150
- * is discarded as it is incompatible with the new result type.
151
- *
152
- * @example
153
- * const fetchUserNode = new FetchUserNode() // returns { id: 1, name: 'Alice' }
154
- * const getUserNameNode = fetchUserNode.map(user => user.name) // returns 'Alice'
155
- *
156
- * @param fn A sync or async function to transform the execution result from `ExecRes` to `NewRes`.
157
- * @returns A new `Node` instance with the transformed output type.
158
- */
159
- map(fn) {
160
- const originalNode = this;
161
- const maxRetries = this.maxRetries;
162
- const wait = this.wait;
163
- return new class extends _Node {
164
- constructor() {
165
- super({ maxRetries, wait });
166
- }
167
- async prep(args) {
168
- return originalNode.prep(args);
169
- }
170
- async exec(args) {
171
- const originalResult = await originalNode.exec(args);
172
- return fn(originalResult);
173
- }
174
- async post(_args) {
175
- return DEFAULT_ACTION;
176
- }
177
- }();
178
- }
179
- /**
180
- * Creates a new node that stores the result of this node's `exec` phase in the `Context`.
181
- * This is a common terminal operation for a data processing chain.
182
- *
183
- * @remarks
184
- * This method returns a **new** `Node` instance and does not modify the original.
185
- *
186
- * @example
187
- * const USER_NAME = contextKey<string>('user_name')
188
- * const workflow = new FetchUserNode()
189
- * .map(user => user.name)
190
- * .toContext(USER_NAME)
191
- *
192
- * @param key The type-safe `ContextKey` to use for storing the result.
193
- * @returns A new `Node` instance that performs the context update in its `post` phase.
194
- */
195
- toContext(key) {
196
- const originalNode = this;
197
- const maxRetries = this.maxRetries;
198
- const wait = this.wait;
199
- return new class extends _Node {
200
- constructor() {
201
- super({ maxRetries, wait });
202
- }
203
- async prep(args) {
204
- return originalNode.prep(args);
205
- }
206
- async exec(args) {
207
- return originalNode.exec(args);
208
- }
209
- async post(args) {
210
- args.ctx.set(key, args.execRes);
211
- return DEFAULT_ACTION;
212
- }
213
- }();
214
- }
215
- /**
216
- * Creates a new node that acts as a conditional gate based on the `exec` result.
217
- * If the predicate returns `true`, the node returns `DEFAULT_ACTION`.
218
- * If it returns `false`, the node returns `FILTER_FAILED`, enabling branching.
219
- *
220
- * @remarks
221
- * This method returns a **new** `Node` instance and does not modify the original.
222
- *
223
- * @example
224
- * const checkAdminNode = new FetchUserNode().filter(user => user.isAdmin)
225
- *
226
- * checkAdminNode.next(adminOnlyNode, DEFAULT_ACTION)
227
- * checkAdminNode.next(accessDeniedNode, FILTER_FAILED)
228
- *
229
- * @param predicate A sync or async function that returns `true` or `false`.
230
- * @returns A new `Node` instance that implements the filter logic.
231
- */
232
- filter(predicate) {
233
- const originalNode = this;
234
- return new class extends _Node {
235
- didPass = false;
236
- async prep(args) {
237
- return originalNode.prep(args);
238
- }
239
- async exec(args) {
240
- const result = await originalNode.exec(args);
241
- this.didPass = await predicate(result);
242
- if (!this.didPass)
243
- args.logger.debug(`[Filter] Predicate failed for node ${this.constructor.name}.`);
244
- return result;
245
- }
246
- async post(_args) {
247
- return this.didPass ? DEFAULT_ACTION : FILTER_FAILED;
248
- }
249
- }();
250
- }
251
- /**
252
- * Creates a new node that performs a side effect with the `exec` result,
253
- * but passes the original result through unmodified. Ideal for logging or debugging.
254
- *
255
- * @remarks
256
- * This method returns a **new** `Node` instance and does not modify the original.
257
- *
258
- * @example
259
- * const workflow = new FetchUserNode()
260
- * .tap(user => console.log('Fetched User:', user))
261
- * .map(user => user.id)
262
- *
263
- * @param fn A function to call with the execution result for its side effect.
264
- * @returns A new `Node` instance that wraps the original.
265
- */
266
- tap(fn) {
267
- const originalNode = this;
268
- const maxRetries = this.maxRetries;
269
- const wait = this.wait;
270
- return new class extends _Node {
271
- constructor() {
272
- super({ maxRetries, wait });
273
- }
274
- async prep(args) {
275
- return originalNode.prep(args);
276
- }
277
- async exec(args) {
278
- const originalResult = await originalNode.exec(args);
279
- await fn(originalResult);
280
- return originalResult;
281
- }
282
- async post(args) {
283
- return originalNode.post(args);
284
- }
285
- }();
286
- }
287
- /**
288
- * Creates a new node that applies a context mutation using a lens before executing.
289
- * This allows for declaratively setting or updating context as part of a fluent chain.
290
- *
291
- * @remarks
292
- * This method returns a **new** `Node` instance and does not modify the original.
293
- *
294
- * @example
295
- * const VALUE = contextKey<number>('value')
296
- * const valueLens = lens(VALUE)
297
- *
298
- * const nodeWithLens = new SomeNode().withLens(valueLens, 42) // Sets VALUE to 42 before SomeNode runs
299
- *
300
- * @param lens The `ContextLens` to use for the operation.
301
- * @param value The value to set in the context via the lens.
302
- * @returns A new `Node` instance that applies the context change.
303
- */
304
- withLens(lens, value) {
305
- const originalNode = this;
306
- const maxRetries = this.maxRetries;
307
- const wait = this.wait;
308
- return new class extends _Node {
309
- constructor() {
310
- super({ maxRetries, wait });
311
- }
312
- async prep(args) {
313
- await lens.set(value)(args.ctx);
314
- return originalNode.prep(args);
315
- }
316
- async exec(args) {
317
- return originalNode.exec(args);
318
- }
319
- async post(args) {
320
- return originalNode.post(args);
321
- }
322
- }();
323
- }
324
- };
325
-
326
- export { Node };
327
- //# sourceMappingURL=chunk-HEO3XL4Z.js.map
328
- //# sourceMappingURL=chunk-HEO3XL4Z.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/workflow/Node.ts"],"names":[],"mappings":"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","file":"chunk-HEO3XL4Z.js","sourcesContent":["/* eslint-disable unused-imports/no-unused-vars, ts/no-this-alias */\n\nimport type { Context, ContextKey, ContextLens } from '../context'\nimport type { NodeArgs, NodeOptions, NodeRunContext, Params, RunOptions } from '../types'\nimport { AbortError, FatalWorkflowError, WorkflowError } from '../errors'\nimport { InMemoryExecutor } from '../executors/in-memory'\nimport { NullLogger } from '../logger'\nimport { DEFAULT_ACTION, FILTER_FAILED } from '../types'\nimport { sleep } from '../utils/index'\nimport { AbstractNode } from './AbstractNode'\nimport { getFlowConstructor } from './registry'\n\n/**\n * The fundamental building block of a workflow, representing a single unit of work.\n * It features a three-phase lifecycle, retry logic, and a fluent API for creating\n * data processing pipelines.\n *\n * @template PrepRes The type of data returned by the `prep` phase.\n * @template ExecRes The type of data returned by the `exec` phase.\n * @template PostRes The type of the action returned by the `post` phase.\n * @template TParams The type for the node's static parameters.\n */\nexport class Node<\n\tPrepRes = any,\n\tExecRes = any,\n\tPostRes = any,\n\tTParams extends Params = Params,\n\tTContext extends Context = Context,\n> extends AbstractNode<PostRes, TParams, TContext> {\n\t/** The total number of times the `exec` phase will be attempted. */\n\tpublic maxRetries: number\n\t/** The time in milliseconds to wait between failed `exec` attempts. */\n\tpublic wait: number\n\n\t/**\n\t * @param options Configuration options for the node's behavior.\n\t * @param options.maxRetries Total number of `exec` attempts. Defaults to `1`.\n\t * @param options.wait Milliseconds to wait between failed `exec` attempts. Defaults to `0`.\n\t */\n\tconstructor(options: NodeOptions = {}) {\n\t\tsuper()\n\t\tthis.maxRetries = options.maxRetries ?? 1\n\t\tthis.wait = options.wait ?? 0\n\t}\n\n\tprotected _wrapError(e: any, phase: 'prep' | 'exec' | 'post'): Error {\n\t\tif (e instanceof AbortError || e instanceof WorkflowError)\n\t\t\treturn e\n\n\t\treturn new WorkflowError(`Failed in ${phase} phase for node ${this.constructor.name}`, this.constructor.name, phase, e as Error)\n\t}\n\n\t/**\n\t * (Lifecycle) Prepares data for execution. Runs once before `exec`.\n\t * This is the ideal place to read data from the `Context`.\n\t * @param args The arguments for the node, including `ctx` and `params`.\n\t * @returns The data required by the `exec` phase.\n\t */\n\tasync prep(args: NodeArgs<void, void, TParams, TContext>): Promise<PrepRes> { return undefined as unknown as PrepRes }\n\n\t/**\n\t * (Lifecycle) Performs the core, isolated logic of the node.\n\t * This is the only phase that is retried on failure. It should not access the `Context` directly.\n\t * @param args The arguments for the node, including `prepRes`.\n\t * @returns The result of the execution.\n\t */\n\tasync exec(args: NodeArgs<PrepRes, void, TParams, TContext>): Promise<ExecRes> { return undefined as unknown as ExecRes }\n\n\t/**\n\t * (Lifecycle) Processes results and determines the next step. Runs once after `exec` succeeds.\n\t * This is the ideal place to write data to the `Context`.\n\t * @param args The arguments for the node, including `execRes`.\n\t * @returns An \"action\" string to determine which successor to execute next. Defaults to `DEFAULT_ACTION`.\n\t */\n\tasync post(args: NodeArgs<PrepRes, ExecRes, TParams, TContext>): Promise<PostRes> { return DEFAULT_ACTION as any }\n\n\t/**\n\t * (Lifecycle) A fallback that runs if all `exec` retries fail.\n\t * If not implemented, the final error will be re-thrown, halting the workflow.\n\t * @param args The arguments for the node, including the final `error` that caused the failure.\n\t * @returns A fallback result of type `ExecRes`, allowing the workflow to recover and continue.\n\t */\n\tasync execFallback(args: NodeArgs<PrepRes, void, TParams, TContext>): Promise<ExecRes> {\n\t\tif (args.error)\n\t\t\tthrow args.error\n\n\t\tthrow new Error(`Node ${this.constructor.name} failed and has no fallback implementation.`)\n\t}\n\n\t/**\n\t * The internal retry-aware execution logic for the `exec` phase.\n\t * @internal\n\t */\n\tasync _exec(args: NodeArgs<PrepRes, void, TParams, TContext>): Promise<ExecRes> {\n\t\tlet lastError: Error | undefined\n\t\tfor (let curRetry = 0; curRetry < this.maxRetries; curRetry++) {\n\t\t\tif (args.signal?.aborted)\n\t\t\t\tthrow new AbortError()\n\t\t\ttry {\n\t\t\t\treturn await this.exec(args)\n\t\t\t}\n\t\t\tcatch (e) {\n\t\t\t\tconst error = e as Error\n\t\t\t\tlastError = error\n\n\t\t\t\tif (error instanceof FatalWorkflowError)\n\t\t\t\t\tthrow error\n\n\t\t\t\tif (error instanceof AbortError || error.name === 'AbortError')\n\t\t\t\t\tthrow error\n\n\t\t\t\tif (curRetry < this.maxRetries - 1) {\n\t\t\t\t\targs.logger.warn(`Attempt ${curRetry + 1}/${this.maxRetries} failed for ${this.constructor.name}. Retrying...`, { error })\n\t\t\t\t\tif (this.wait > 0)\n\t\t\t\t\t\tawait sleep(this.wait, args.signal)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\targs.logger.error(`All retries failed for ${this.constructor.name}. Executing fallback.`, { error: lastError })\n\t\tif (args.signal?.aborted)\n\t\t\tthrow new AbortError()\n\t\treturn await this.execFallback({ ...args, error: lastError })\n\t}\n\n\t/**\n\t * The internal method that executes the node's full lifecycle.\n\t * @internal\n\t */\n\tasync _run({ ctx, params, signal, logger, executor, visitedInParallel }: NodeRunContext<TContext>): Promise<PostRes> {\n\t\tif (signal?.aborted)\n\t\t\tthrow new AbortError()\n\t\tlet prepRes: PrepRes\n\t\ttry {\n\t\t\tprepRes = await this.prep({ ctx: ctx as TContext, params: params as TParams, signal, logger, prepRes: undefined, execRes: undefined, executor, visitedInParallel })\n\t\t}\n\t\tcatch (e) {\n\t\t\tthrow this._wrapError(e, 'prep')\n\t\t}\n\n\t\tif (signal?.aborted)\n\t\t\tthrow new AbortError()\n\t\tlet execRes: ExecRes\n\t\ttry {\n\t\t\texecRes = await this._exec({ ctx: ctx as TContext, params: params as TParams, signal, logger, prepRes, execRes: undefined, executor, visitedInParallel })\n\t\t}\n\t\tcatch (e) {\n\t\t\tthrow this._wrapError(e, 'exec')\n\t\t}\n\n\t\tif (signal?.aborted)\n\t\t\tthrow new AbortError()\n\t\ttry {\n\t\t\tconst action = await this.post({ ctx: ctx as TContext, params: params as TParams, signal, logger, prepRes, execRes, executor, visitedInParallel })\n\t\t\treturn action === undefined ? DEFAULT_ACTION as any : action\n\t\t}\n\t\tcatch (e) {\n\t\t\tthrow this._wrapError(e, 'post')\n\t\t}\n\t}\n\n\t/**\n\t * Runs the node as a standalone unit, independent of a larger flow.\n\t * This is useful for testing individual nodes in isolation.\n\t *\n\t * @param ctx The shared workflow context.\n\t * @param options Runtime options like a logger or abort controller.\n\t * @returns The result of the node's `post` method (its action).\n\t */\n\tasync run(ctx: TContext, options?: RunOptions): Promise<PostRes> {\n\t\tconst Flow = getFlowConstructor()\n\t\tconst logger = options?.logger ?? new NullLogger()\n\t\tif (this.successors.size > 0 && !(this instanceof Flow))\n\t\t\tlogger.warn('Node.run() called directly on a node with successors. The flow will not continue. Use a Flow to execute a sequence.')\n\t\tconst executor = options?.executor ?? new InMemoryExecutor()\n\t\t// Wrap the node in a Flow and pass its params via the options.\n\t\treturn executor.run(new Flow(this), ctx, { ...options, params: this.params })\n\t}\n\n\t/**\n\t * Creates a new node that transforms the result of this node's `exec` phase.\n\t *\n\t * @remarks\n\t * This method returns a **new** `Node` instance and does not modify the original.\n\t * The new node inherits the original's `prep` method. The original `post` method\n\t * is discarded as it is incompatible with the new result type.\n\t *\n\t * @example\n\t * const fetchUserNode = new FetchUserNode() // returns { id: 1, name: 'Alice' }\n\t * const getUserNameNode = fetchUserNode.map(user => user.name) // returns 'Alice'\n\t *\n\t * @param fn A sync or async function to transform the execution result from `ExecRes` to `NewRes`.\n\t * @returns A new `Node` instance with the transformed output type.\n\t */\n\tmap<NewRes>(fn: (result: ExecRes) => NewRes | Promise<NewRes>): Node<PrepRes, NewRes, any, TParams, TContext> {\n\t\tconst originalNode = this\n\t\tconst maxRetries = this.maxRetries\n\t\tconst wait = this.wait\n\n\t\treturn new class extends Node<PrepRes, NewRes, any, TParams, TContext> {\n\t\t\tconstructor() { super({ maxRetries, wait }) }\n\t\t\tasync prep(args: NodeArgs<void, void, TParams, TContext>): Promise<PrepRes> { return originalNode.prep(args) }\n\t\t\tasync exec(args: NodeArgs<PrepRes, void, TParams, TContext>): Promise<NewRes> {\n\t\t\t\tconst originalResult = await originalNode.exec(args)\n\t\t\t\treturn fn(originalResult)\n\t\t\t}\n\n\t\t\tasync post(_args: NodeArgs<PrepRes, NewRes, TParams, TContext>): Promise<any> {\n\t\t\t\treturn DEFAULT_ACTION\n\t\t\t}\n\t\t}()\n\t}\n\n\t/**\n\t * Creates a new node that stores the result of this node's `exec` phase in the `Context`.\n\t * This is a common terminal operation for a data processing chain.\n\t *\n\t * @remarks\n\t * This method returns a **new** `Node` instance and does not modify the original.\n\t *\n\t * @example\n\t * const USER_NAME = contextKey<string>('user_name')\n\t * const workflow = new FetchUserNode()\n\t * .map(user => user.name)\n\t * .toContext(USER_NAME)\n\t *\n\t * @param key The type-safe `ContextKey` to use for storing the result.\n\t * @returns A new `Node` instance that performs the context update in its `post` phase.\n\t */\n\ttoContext(key: ContextKey<ExecRes>): Node<PrepRes, ExecRes, any, TParams, TContext> {\n\t\tconst originalNode = this\n\t\tconst maxRetries = this.maxRetries\n\t\tconst wait = this.wait\n\n\t\treturn new class extends Node<PrepRes, ExecRes, any, TParams, TContext> {\n\t\t\tconstructor() { super({ maxRetries, wait }) }\n\t\t\tasync prep(args: NodeArgs<void, void, TParams, TContext>): Promise<PrepRes> { return originalNode.prep(args) }\n\t\t\tasync exec(args: NodeArgs<PrepRes, void, TParams, TContext>): Promise<ExecRes> { return originalNode.exec(args) }\n\t\t\tasync post(args: NodeArgs<PrepRes, ExecRes, TParams, TContext>): Promise<any> {\n\t\t\t\targs.ctx.set(key, args.execRes)\n\t\t\t\treturn DEFAULT_ACTION\n\t\t\t}\n\t\t}()\n\t}\n\n\t/**\n\t * Creates a new node that acts as a conditional gate based on the `exec` result.\n\t * If the predicate returns `true`, the node returns `DEFAULT_ACTION`.\n\t * If it returns `false`, the node returns `FILTER_FAILED`, enabling branching.\n\t *\n\t * @remarks\n\t * This method returns a **new** `Node` instance and does not modify the original.\n\t *\n\t * @example\n\t * const checkAdminNode = new FetchUserNode().filter(user => user.isAdmin)\n\t *\n\t * checkAdminNode.next(adminOnlyNode, DEFAULT_ACTION)\n\t * checkAdminNode.next(accessDeniedNode, FILTER_FAILED)\n\t *\n\t * @param predicate A sync or async function that returns `true` or `false`.\n\t * @returns A new `Node` instance that implements the filter logic.\n\t */\n\tfilter(predicate: (result: ExecRes) => boolean | Promise<boolean>): Node<PrepRes, ExecRes, any, TParams, TContext> {\n\t\tconst originalNode = this\n\n\t\treturn new class extends Node<PrepRes, ExecRes, any, TParams, TContext> {\n\t\t\tprivate didPass = false\n\n\t\t\tasync prep(args: NodeArgs<void, void, TParams, TContext>) { return originalNode.prep(args) }\n\t\t\tasync exec(args: NodeArgs<PrepRes, void, TParams, TContext>): Promise<ExecRes> {\n\t\t\t\tconst result = await originalNode.exec(args)\n\t\t\t\tthis.didPass = await predicate(result)\n\t\t\t\tif (!this.didPass)\n\t\t\t\t\targs.logger.debug(`[Filter] Predicate failed for node ${this.constructor.name}.`)\n\n\t\t\t\treturn result\n\t\t\t}\n\n\t\t\tasync post(_args: NodeArgs<PrepRes, ExecRes, TParams, TContext>): Promise<any> {\n\t\t\t\treturn this.didPass ? DEFAULT_ACTION : FILTER_FAILED\n\t\t\t}\n\t\t}()\n\t}\n\n\t/**\n\t * Creates a new node that performs a side effect with the `exec` result,\n\t * but passes the original result through unmodified. Ideal for logging or debugging.\n\t *\n\t * @remarks\n\t * This method returns a **new** `Node` instance and does not modify the original.\n\t *\n\t * @example\n\t * const workflow = new FetchUserNode()\n\t * .tap(user => console.log('Fetched User:', user))\n\t * .map(user => user.id)\n\t *\n\t * @param fn A function to call with the execution result for its side effect.\n\t * @returns A new `Node` instance that wraps the original.\n\t */\n\ttap(fn: (result: ExecRes) => void | Promise<void>): Node<PrepRes, ExecRes, PostRes, TParams, TContext> {\n\t\tconst originalNode = this\n\t\tconst maxRetries = this.maxRetries\n\t\tconst wait = this.wait\n\n\t\treturn new class extends Node<PrepRes, ExecRes, PostRes, TParams, TContext> {\n\t\t\tconstructor() { super({ maxRetries, wait }) }\n\t\t\tasync prep(args: NodeArgs<void, void, TParams, TContext>): Promise<PrepRes> {\n\t\t\t\treturn originalNode.prep(args)\n\t\t\t}\n\n\t\t\tasync exec(args: NodeArgs<PrepRes, void, TParams, TContext>): Promise<ExecRes> {\n\t\t\t\tconst originalResult = await originalNode.exec(args)\n\t\t\t\tawait fn(originalResult)\n\t\t\t\treturn originalResult\n\t\t\t}\n\n\t\t\tasync post(args: NodeArgs<PrepRes, ExecRes, TParams, TContext>): Promise<PostRes> {\n\t\t\t\treturn originalNode.post(args)\n\t\t\t}\n\t\t}()\n\t}\n\n\t/**\n\t * Creates a new node that applies a context mutation using a lens before executing.\n\t * This allows for declaratively setting or updating context as part of a fluent chain.\n\t *\n\t * @remarks\n\t * This method returns a **new** `Node` instance and does not modify the original.\n\t *\n\t * @example\n\t * const VALUE = contextKey<number>('value')\n\t * const valueLens = lens(VALUE)\n\t *\n\t * const nodeWithLens = new SomeNode().withLens(valueLens, 42) // Sets VALUE to 42 before SomeNode runs\n\t *\n\t * @param lens The `ContextLens` to use for the operation.\n\t * @param value The value to set in the context via the lens.\n\t * @returns A new `Node` instance that applies the context change.\n\t */\n\twithLens<T>(lens: ContextLens<T>, value: T): Node<PrepRes, ExecRes, PostRes, TParams, TContext> {\n\t\tconst originalNode = this\n\t\tconst maxRetries = this.maxRetries\n\t\tconst wait = this.wait\n\n\t\treturn new class extends Node<PrepRes, ExecRes, PostRes, TParams, TContext> {\n\t\t\tconstructor() { super({ maxRetries, wait }) }\n\t\t\tasync prep(args: NodeArgs<void, void, TParams, TContext>): Promise<PrepRes> {\n\t\t\t\t// Apply the lens transformation before executing the original node's logic.\n\t\t\t\tawait lens.set(value)(args.ctx)\n\t\t\t\treturn originalNode.prep(args)\n\t\t\t}\n\n\t\t\tasync exec(args: NodeArgs<PrepRes, void, TParams, TContext>): Promise<ExecRes> {\n\t\t\t\treturn originalNode.exec(args)\n\t\t\t}\n\n\t\t\tasync post(args: NodeArgs<PrepRes, ExecRes, TParams, TContext>): Promise<PostRes> {\n\t\t\t\treturn originalNode.post(args)\n\t\t\t}\n\t\t}()\n\t}\n}\n"]}
@@ -1,56 +0,0 @@
1
- // src/logger.ts
2
- var NullLogger = class {
3
- debug() {
4
- }
5
- info() {
6
- }
7
- warn() {
8
- }
9
- error() {
10
- }
11
- };
12
- var levelPriorities = {
13
- debug: 1,
14
- info: 2,
15
- warn: 3,
16
- error: 4
17
- };
18
- var ConsoleLogger = class {
19
- minLevel;
20
- /**
21
- * @param options Configuration for the logger.
22
- * @param options.level The minimum level of messages to log. Defaults to 'info'.
23
- */
24
- constructor(options = {}) {
25
- this.minLevel = options.level ?? "info";
26
- }
27
- log(level, message, context) {
28
- if (levelPriorities[level] < levelPriorities[this.minLevel]) {
29
- return;
30
- }
31
- const fullMessage = `[${level.toUpperCase()}] ${message}`;
32
- if (context && Object.keys(context).length > 0) {
33
- const logMethod = console[level] || console.log;
34
- logMethod(fullMessage, context);
35
- } else {
36
- const logMethod = console[level] || console.log;
37
- logMethod(fullMessage);
38
- }
39
- }
40
- debug(message, context) {
41
- this.log("debug", message, context);
42
- }
43
- info(message, context) {
44
- this.log("info", message, context);
45
- }
46
- warn(message, context) {
47
- this.log("warn", message, context);
48
- }
49
- error(message, context) {
50
- this.log("error", message, context);
51
- }
52
- };
53
-
54
- export { ConsoleLogger, NullLogger };
55
- //# sourceMappingURL=chunk-IIKTTIW5.js.map
56
- //# sourceMappingURL=chunk-IIKTTIW5.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/logger.ts"],"names":[],"mappings":";AAgBO,IAAM,aAAN,MAAmC;AAAA,EACzC,KAAA,GAAQ;AAAA,EAAc;AAAA,EACtB,IAAA,GAAO;AAAA,EAAc;AAAA,EACrB,IAAA,GAAO;AAAA,EAAc;AAAA,EACrB,KAAA,GAAQ;AAAA,EAAc;AACvB;AAIA,IAAM,eAAA,GAA4C;AAAA,EACjD,KAAA,EAAO,CAAA;AAAA,EACP,IAAA,EAAM,CAAA;AAAA,EACN,IAAA,EAAM,CAAA;AAAA,EACN,KAAA,EAAO;AACR,CAAA;AAMO,IAAM,gBAAN,MAAsC;AAAA,EACpC,QAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAMR,WAAA,CAAY,OAAA,GAAgC,EAAC,EAAG;AAC/C,IAAA,IAAA,CAAK,QAAA,GAAW,QAAQ,KAAA,IAAS,MAAA;AAAA,EAClC;AAAA,EAEQ,GAAA,CAAI,KAAA,EAAiB,OAAA,EAAiB,OAAA,EAAkB;AAC/D,IAAA,IAAI,gBAAgB,KAAK,CAAA,GAAI,eAAA,CAAgB,IAAA,CAAK,QAAQ,CAAA,EAAG;AAC5D,MAAA;AAAA,IACD;AAEA,IAAA,MAAM,cAAc,CAAA,CAAA,EAAI,KAAA,CAAM,WAAA,EAAa,KAAK,OAAO,CAAA,CAAA;AACvD,IAAA,IAAI,WAAW,MAAA,CAAO,IAAA,CAAK,OAAO,CAAA,CAAE,SAAS,CAAA,EAAG;AAC/C,MAAA,MAAM,SAAA,GAAY,OAAA,CAAQ,KAAK,CAAA,IAAK,OAAA,CAAQ,GAAA;AAC5C,MAAA,SAAA,CAAU,aAAa,OAAO,CAAA;AAAA,IAC/B,CAAA,MACK;AACJ,MAAA,MAAM,SAAA,GAAY,OAAA,CAAQ,KAAK,CAAA,IAAK,OAAA,CAAQ,GAAA;AAC5C,MAAA,SAAA,CAAU,WAAW,CAAA;AAAA,IACtB;AAAA,EACD;AAAA,EAEA,KAAA,CAAM,SAAiB,OAAA,EAAkB;AAAE,IAAA,IAAA,CAAK,GAAA,CAAI,OAAA,EAAS,OAAA,EAAS,OAAO,CAAA;AAAA,EAAE;AAAA,EAC/E,IAAA,CAAK,SAAiB,OAAA,EAAkB;AAAE,IAAA,IAAA,CAAK,GAAA,CAAI,MAAA,EAAQ,OAAA,EAAS,OAAO,CAAA;AAAA,EAAE;AAAA,EAC7E,IAAA,CAAK,SAAiB,OAAA,EAAkB;AAAE,IAAA,IAAA,CAAK,GAAA,CAAI,MAAA,EAAQ,OAAA,EAAS,OAAO,CAAA;AAAA,EAAE;AAAA,EAC7E,KAAA,CAAM,SAAiB,OAAA,EAAkB;AAAE,IAAA,IAAA,CAAK,GAAA,CAAI,OAAA,EAAS,OAAA,EAAS,OAAO,CAAA;AAAA,EAAE;AAChF","file":"chunk-IIKTTIW5.js","sourcesContent":["/**\n * Defines the interface for a logger that can be used by the workflow engine.\n * This allows for plugging in any logging library (e.g., Pino, Winston).\n */\nexport interface Logger {\n\tdebug: (message: string, context?: object) => void\n\tinfo: (message: string, context?: object) => void\n\twarn: (message: string, context?: object) => void\n\terror: (message: string, context?: object) => void\n}\n\n/**\n * A logger implementation that performs no action (a \"no-op\" logger).\n * This is the default logger used by the framework if none is provided,\n * making Flowcraft silent out-of-the-box.\n */\nexport class NullLogger implements Logger {\n\tdebug() { /* no-op */ }\n\tinfo() { /* no-op */ }\n\twarn() { /* no-op */ }\n\terror() { /* no-op */ }\n}\n\ntype LogLevel = 'debug' | 'info' | 'warn' | 'error'\n\nconst levelPriorities: Record<LogLevel, number> = {\n\tdebug: 1,\n\tinfo: 2,\n\twarn: 3,\n\terror: 4,\n}\n\n/**\n * A default logger implementation that writes messages to the `console`.\n * It supports a minimum log level to control verbosity.\n */\nexport class ConsoleLogger implements Logger {\n\tprivate minLevel: LogLevel\n\n\t/**\n\t * @param options Configuration for the logger.\n\t * @param options.level The minimum level of messages to log. Defaults to 'info'.\n\t */\n\tconstructor(options: { level?: LogLevel } = {}) {\n\t\tthis.minLevel = options.level ?? 'info'\n\t}\n\n\tprivate log(level: LogLevel, message: string, context?: object) {\n\t\tif (levelPriorities[level] < levelPriorities[this.minLevel]) {\n\t\t\treturn\n\t\t}\n\n\t\tconst fullMessage = `[${level.toUpperCase()}] ${message}`\n\t\tif (context && Object.keys(context).length > 0) {\n\t\t\tconst logMethod = console[level] || console.log\n\t\t\tlogMethod(fullMessage, context)\n\t\t}\n\t\telse {\n\t\t\tconst logMethod = console[level] || console.log\n\t\t\tlogMethod(fullMessage)\n\t\t}\n\t}\n\n\tdebug(message: string, context?: object) { this.log('debug', message, context) }\n\tinfo(message: string, context?: object) { this.log('info', message, context) }\n\twarn(message: string, context?: object) { this.log('warn', message, context) }\n\terror(message: string, context?: object) { this.log('error', message, context) }\n}\n"]}
@@ -1,3 +0,0 @@
1
-
2
- //# sourceMappingURL=chunk-KOBEU2EM.js.map
3
- //# sourceMappingURL=chunk-KOBEU2EM.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":[],"names":[],"mappings":"","file":"chunk-KOBEU2EM.js"}
@@ -1,178 +0,0 @@
1
- import { Flow } from './chunk-UY4PNPBX.js';
2
- import { AbortError } from './chunk-64DNBF5W.js';
3
-
4
- // src/builder/patterns.ts
5
- var SequenceFlow = class extends Flow {
6
- /**
7
- * @param nodes A sequence of `Node` or `Flow` instances to be executed in order.
8
- */
9
- constructor(...nodes) {
10
- if (nodes.length === 0) {
11
- super();
12
- return;
13
- }
14
- super(nodes[0]);
15
- let current = nodes[0];
16
- for (let i = 1; i < nodes.length; i++)
17
- current = current.next(nodes[i]);
18
- }
19
- };
20
- var ParallelFlow = class extends Flow {
21
- /**
22
- * @param nodesToRun The array of nodes to execute concurrently.
23
- */
24
- constructor(nodesToRun = []) {
25
- super();
26
- this.nodesToRun = nodesToRun;
27
- }
28
- /** A tag to reliably identify this node type in the visualizer. */
29
- isParallelContainer = true;
30
- /**
31
- * Orchestrates the parallel execution of all nodes.
32
- * @internal
33
- */
34
- async exec({ ctx, params, signal, logger, executor, visitedInParallel }) {
35
- if (!visitedInParallel)
36
- throw new Error("ParallelFlow requires a visitedInParallel set from its executor.");
37
- const branches = this.nodesToRun.length > 0 ? this.nodesToRun : Array.from(this.successors.values()).flat();
38
- if (branches.length === 0) {
39
- logger.debug("[ParallelFlow] No branches to execute.");
40
- return;
41
- }
42
- const runBranch = async (startNode) => {
43
- let currentNode = startNode;
44
- while (currentNode) {
45
- if (signal?.aborted)
46
- throw new AbortError();
47
- if (visitedInParallel.has(currentNode))
48
- break;
49
- visitedInParallel.add(currentNode);
50
- const action = await currentNode._run({
51
- ctx,
52
- params: { ...params, ...currentNode.params },
53
- signal,
54
- logger,
55
- executor,
56
- visitedInParallel
57
- });
58
- currentNode = executor?.getNextNode(currentNode, action);
59
- }
60
- };
61
- const promises = branches.map(runBranch);
62
- await Promise.allSettled(promises);
63
- }
64
- };
65
- var BatchFlow = class extends Flow {
66
- constructor() {
67
- super();
68
- }
69
- /**
70
- * (Abstract) Prepares the list of items to be processed.
71
- * This method is called once before the batch processing begins.
72
- * @param _args The arguments for the node, including `ctx` and `params`.
73
- * @returns An array or iterable of parameter objects, one for each item.
74
- * The `nodeToRun` will be executed once for each of these objects.
75
- */
76
- async prep(_args) {
77
- return [];
78
- }
79
- /**
80
- * Orchestrates the sequential execution of `nodeToRun` for each item.
81
- * @internal
82
- */
83
- async exec(args) {
84
- if (!this.nodeToRun)
85
- return null;
86
- const combinedParams = { ...this.params, ...args.params };
87
- const batchParamsIterable = await this.prep(args) || [];
88
- const batchParamsList = Array.from(batchParamsIterable);
89
- for (const batchParams of batchParamsList) {
90
- if (args.signal?.aborted)
91
- throw new AbortError();
92
- await this.nodeToRun._run({
93
- ctx: args.ctx,
94
- params: { ...combinedParams, ...batchParams },
95
- signal: args.signal,
96
- logger: args.logger,
97
- executor: args.executor
98
- });
99
- }
100
- return null;
101
- }
102
- };
103
- var ParallelBatchFlow = class extends Flow {
104
- constructor() {
105
- super();
106
- }
107
- /**
108
- * (Abstract) Prepares the list of items to be processed.
109
- * This method is called once before the batch processing begins.
110
- * @param _args The arguments for the node, including `ctx` and `params`.
111
- * @returns An array or iterable of parameter objects, one for each item.
112
- * The `nodeToRun` will be executed concurrently for each of these objects.
113
- */
114
- async prep(_args) {
115
- return [];
116
- }
117
- /**
118
- * Orchestrates the parallel execution of `nodeToRun` for each item.
119
- * @internal
120
- */
121
- async exec(args) {
122
- if (!this.nodeToRun)
123
- return [];
124
- const combinedParams = { ...this.params, ...args.params };
125
- const batchParamsIterable = await this.prep(args) || [];
126
- const batchParamsList = Array.from(batchParamsIterable);
127
- const promises = batchParamsList.map((batchParams) => {
128
- return this.nodeToRun._run({
129
- ctx: args.ctx,
130
- params: { ...combinedParams, ...batchParams },
131
- signal: args.signal,
132
- logger: args.logger,
133
- executor: args.executor
134
- });
135
- });
136
- const results = await Promise.allSettled(promises);
137
- for (const result of results) {
138
- if (result.status === "rejected") {
139
- args.logger.error("A parallel batch item failed.", { error: result.reason });
140
- }
141
- }
142
- return results;
143
- }
144
- };
145
- function mapCollection(items, fn) {
146
- return new class extends Flow {
147
- async exec() {
148
- const promises = items.map((item) => fn(item));
149
- return Promise.all(promises);
150
- }
151
- }();
152
- }
153
- function filterCollection(items, predicate) {
154
- return new class extends Flow {
155
- async exec() {
156
- const results = await Promise.all(items.map((item) => predicate(item)));
157
- return items.filter((_, index) => results[index]);
158
- }
159
- }();
160
- }
161
- function reduceCollection(items, reducer, initialValue) {
162
- return new class extends Flow {
163
- async exec(_args) {
164
- let accumulator = initialValue;
165
- for (const item of items) {
166
- if (_args.signal?.aborted) {
167
- throw new AbortError();
168
- }
169
- accumulator = await reducer(accumulator, item);
170
- }
171
- return accumulator;
172
- }
173
- }();
174
- }
175
-
176
- export { BatchFlow, ParallelBatchFlow, ParallelFlow, SequenceFlow, filterCollection, mapCollection, reduceCollection };
177
- //# sourceMappingURL=chunk-L5PK5VL2.js.map
178
- //# sourceMappingURL=chunk-L5PK5VL2.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/builder/patterns.ts"],"names":[],"mappings":"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","file":"chunk-L5PK5VL2.js","sourcesContent":["import type { Context } from '../context'\nimport type { NodeFunction } from '../functions'\nimport type { NodeArgs, Params } from '../types'\nimport type { AbstractNode } from '../workflow/index'\nimport { AbortError } from '../errors'\nimport { Flow } from '../workflow/index'\n\n/**\n * A `Flow` that creates a linear workflow from a sequence of nodes,\n * automatically chaining them in order.\n */\nexport class SequenceFlow<\n\tPrepRes = any,\n\tExecRes = any,\n\tTParams extends Params = Params,\n\tTContext extends Context = Context,\n> extends Flow<PrepRes, ExecRes, TParams, TContext> {\n\t/**\n\t * @param nodes A sequence of `Node` or `Flow` instances to be executed in order.\n\t */\n\tconstructor(...nodes: AbstractNode<any, any, TContext>[]) {\n\t\tif (nodes.length === 0) {\n\t\t\tsuper()\n\t\t\treturn\n\t\t}\n\t\tsuper(nodes[0])\n\t\tlet current = nodes[0]\n\t\tfor (let i = 1; i < nodes.length; i++)\n\t\t\tcurrent = current.next(nodes[i])\n\t}\n}\n\n/**\n * A `Flow` that executes a collection of different nodes concurrently.\n * This is the core of the \"fan-out, fan-in\" pattern for structural parallelism.\n * After all parallel branches complete, the flow can proceed to a single successor.\n */\nexport class ParallelFlow<\n\tTContext extends Context = Context,\n> extends Flow<void, void, Params, TContext> {\n\t/** A tag to reliably identify this node type in the visualizer. */\n\tpublic readonly isParallelContainer = true\n\n\t/**\n\t * @param nodesToRun The array of nodes to execute concurrently.\n\t */\n\tconstructor(protected nodesToRun: AbstractNode<any, any, TContext>[] = []) {\n\t\tsuper()\n\t}\n\n\t/**\n\t * Orchestrates the parallel execution of all nodes.\n\t * @internal\n\t */\n\tasync exec({ ctx, params, signal, logger, executor, visitedInParallel }: NodeArgs<void, void, Params, TContext>): Promise<void> {\n\t\tif (!visitedInParallel)\n\t\t\tthrow new Error('ParallelFlow requires a visitedInParallel set from its executor.')\n\n\t\tconst branches = this.nodesToRun.length > 0\n\t\t\t? this.nodesToRun\n\t\t\t: Array.from(this.successors.values()).flat()\n\n\t\tif (branches.length === 0) {\n\t\t\tlogger.debug('[ParallelFlow] No branches to execute.')\n\t\t\treturn\n\t\t}\n\n\t\tconst runBranch = async (startNode: AbstractNode<any, any, TContext>) => {\n\t\t\tlet currentNode: AbstractNode<any, any, TContext> | undefined = startNode\n\t\t\twhile (currentNode) {\n\t\t\t\tif (signal?.aborted)\n\t\t\t\t\tthrow new AbortError()\n\n\t\t\t\tif (visitedInParallel.has(currentNode))\n\t\t\t\t\tbreak\n\t\t\t\tvisitedInParallel.add(currentNode)\n\n\t\t\t\tconst action = await currentNode._run({\n\t\t\t\t\tctx,\n\t\t\t\t\tparams: { ...params, ...currentNode.params },\n\t\t\t\t\tsignal,\n\t\t\t\t\tlogger,\n\t\t\t\t\texecutor,\n\t\t\t\t\tvisitedInParallel,\n\t\t\t\t})\n\n\t\t\t\tcurrentNode = executor?.getNextNode(currentNode, action)\n\t\t\t}\n\t\t}\n\n\t\tconst promises = branches.map(runBranch)\n\t\tawait Promise.allSettled(promises)\n\t}\n}\n\n/**\n * An abstract `Flow` that processes a collection of items sequentially, one by one.\n * Subclasses must implement the `prep` method to provide the items and the\n * `nodeToRun` property to define the processing logic for each item.\n */\nexport abstract class BatchFlow<\n\tT = any,\n\tTContext extends Context = Context,\n> extends Flow<Iterable<T>, null, Params, TContext> {\n\t/**\n\t * The `Node` instance that will be executed for each item in the batch.\n\t * This must be implemented by any subclass.\n\t */\n\tprotected abstract nodeToRun: AbstractNode<any, any, TContext>\n\n\tconstructor() {\n\t\tsuper()\n\t}\n\n\t/**\n\t * (Abstract) Prepares the list of items to be processed.\n\t * This method is called once before the batch processing begins.\n\t * @param _args The arguments for the node, including `ctx` and `params`.\n\t * @returns An array or iterable of parameter objects, one for each item.\n\t * The `nodeToRun` will be executed once for each of these objects.\n\t */\n\tasync prep(_args: NodeArgs<void, void, Params, TContext>): Promise<Iterable<any>> {\n\t\treturn []\n\t}\n\n\t/**\n\t * Orchestrates the sequential execution of `nodeToRun` for each item.\n\t * @internal\n\t */\n\tasync exec(args: NodeArgs<void, void, Params, TContext>): Promise<null> {\n\t\tif (!this.nodeToRun)\n\t\t\treturn null\n\n\t\tconst combinedParams = { ...this.params, ...args.params }\n\t\tconst batchParamsIterable = (await this.prep(args)) || []\n\t\tconst batchParamsList = Array.from(batchParamsIterable)\n\n\t\tfor (const batchParams of batchParamsList) {\n\t\t\tif (args.signal?.aborted)\n\t\t\t\tthrow new AbortError()\n\n\t\t\tawait this.nodeToRun._run({\n\t\t\t\tctx: args.ctx,\n\t\t\t\tparams: { ...combinedParams, ...batchParams },\n\t\t\t\tsignal: args.signal,\n\t\t\t\tlogger: args.logger,\n\t\t\t\texecutor: args.executor,\n\t\t\t})\n\t\t}\n\t\treturn null\n\t}\n}\n\n/**\n * An abstract `Flow` that processes a collection of items concurrently.\n * Subclasses must implement the `prep` method to provide the items and the\n * `nodeToRun` property to define the processing logic for each item.\n * This provides a significant performance boost for I/O-bound tasks.\n */\nexport abstract class ParallelBatchFlow<\n\tT = any,\n\tTContext extends Context = Context,\n> extends Flow<Iterable<T>, PromiseSettledResult<any>[], Params, TContext> {\n\t/**\n\t * The `Node` instance that will be executed concurrently for each item in the batch.\n\t * This must be implemented by any subclass.\n\t */\n\tprotected abstract nodeToRun: AbstractNode<any, any, TContext>\n\n\tconstructor() {\n\t\tsuper()\n\t}\n\n\t/**\n\t * (Abstract) Prepares the list of items to be processed.\n\t * This method is called once before the batch processing begins.\n\t * @param _args The arguments for the node, including `ctx` and `params`.\n\t * @returns An array or iterable of parameter objects, one for each item.\n\t * The `nodeToRun` will be executed concurrently for each of these objects.\n\t */\n\tasync prep(_args: NodeArgs<void, void, Params, TContext>): Promise<Iterable<any>> {\n\t\treturn []\n\t}\n\n\t/**\n\t * Orchestrates the parallel execution of `nodeToRun` for each item.\n\t * @internal\n\t */\n\tasync exec(args: NodeArgs<any, void, Params, TContext>): Promise<PromiseSettledResult<any>[]> {\n\t\tif (!this.nodeToRun)\n\t\t\treturn []\n\n\t\tconst combinedParams = { ...this.params, ...args.params }\n\t\tconst batchParamsIterable = (await this.prep(args)) || []\n\t\tconst batchParamsList = Array.from(batchParamsIterable)\n\n\t\tconst promises = batchParamsList.map((batchParams) => {\n\t\t\treturn this.nodeToRun._run({\n\t\t\t\tctx: args.ctx,\n\t\t\t\tparams: { ...combinedParams, ...batchParams },\n\t\t\t\tsignal: args.signal,\n\t\t\t\tlogger: args.logger,\n\t\t\t\texecutor: args.executor,\n\t\t\t})\n\t\t})\n\n\t\tconst results = await Promise.allSettled(promises)\n\n\t\tfor (const result of results) {\n\t\t\tif (result.status === 'rejected') {\n\t\t\t\targs.logger.error('A parallel batch item failed.', { error: result.reason })\n\t\t\t}\n\t\t}\n\n\t\treturn results\n\t}\n}\n\n/**\n * Creates a flow that applies a mapping function to each item in a collection in parallel\n * and returns a new array containing the results.\n *\n * @example\n * const numbers = [1, 2, 3];\n * const double = (n: number) => n * 2;\n * const processingFlow = mapCollection(numbers, double);\n * // When run, processingFlow's result will be [2, 4, 6]\n *\n * @param items The initial array of items of type `T`.\n * @param fn An async or sync function that transforms an item from type `T` to type `U`.\n * @returns A `Flow` instance that, when run, will output an array of type `U[]`.\n */\nexport function mapCollection<T, U, TContext extends Context = Context>(items: T[], fn: NodeFunction<T, U>): Flow<void, U[], Params, TContext> {\n\treturn new class extends Flow<void, U[], Params, TContext> {\n\t\tasync exec(): Promise<U[]> {\n\t\t\tconst promises = items.map(item => fn(item))\n\t\t\treturn Promise.all(promises)\n\t\t}\n\t}()\n}\n\n/**\n * Creates a flow that filters a collection based on a predicate function,\n * returning a new array containing only the items that pass the predicate.\n * The predicate is applied to all items concurrently.\n *\n * @example\n * const users = [{ id: 1, admin: true }, { id: 2, admin: false }];\n * const isAdmin = async (user: { admin: boolean }) => user.admin;\n * const adminFilterFlow = filterCollection(users, isAdmin);\n * // When run, the result will be [{ id: 1, admin: true }]\n *\n * @param items The initial array of items of type `T`.\n * @param predicate An async or sync function that returns `true` or `false` for an item.\n * @returns A `Flow` instance that, when run, will output a filtered array of type `T[]`.\n */\nexport function filterCollection<T, TContext extends Context = Context>(items: T[], predicate: (item: T) => boolean | Promise<boolean>): Flow<void, T[], Params, TContext> {\n\treturn new class extends Flow<void, T[], Params, TContext> {\n\t\tasync exec(): Promise<T[]> {\n\t\t\tconst results = await Promise.all(items.map(item => predicate(item)))\n\t\t\treturn items.filter((_, index) => results[index])\n\t\t}\n\t}()\n}\n\n/**\n * Creates a flow that reduces a collection to a single value by executing a\n * reducer function sequentially for each item, similar to `Array.prototype.reduce()`.\n *\n * @example\n * const numbers = [1, 2, 3, 4];\n * const sumReducer = (acc: number, val: number) => acc + val;\n * const sumFlow = reduceCollection(numbers, sumReducer, 0);\n * // When run, the result will be 10.\n *\n * @param items The array of items to be reduced.\n * @param reducer An async or sync function that processes the accumulator and the current item.\n * @param initialValue The initial value for the accumulator.\n * @returns A `Flow` instance that, when run, will output the final accumulated value of type `U`.\n */\nexport function reduceCollection<T, U, TContext extends Context = Context>(\n\titems: T[],\n\treducer: (accumulator: U, item: T) => U | Promise<U>,\n\tinitialValue: U,\n): Flow<void, U, Params, TContext> {\n\treturn new class extends Flow<void, U, Params, TContext> {\n\t\tasync exec(_args: NodeArgs<void, void, Params, TContext>): Promise<U> {\n\t\t\tlet accumulator = initialValue\n\t\t\tfor (const item of items) {\n\t\t\t\tif (_args.signal?.aborted) {\n\t\t\t\t\tthrow new AbortError()\n\t\t\t\t}\n\t\t\t\taccumulator = await reducer(accumulator, item)\n\t\t\t}\n\t\t\treturn accumulator\n\t\t}\n\t}()\n}\n"]}