@asaidimu/utils-pipeline 1.0.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.
- package/LICENSE.md +21 -0
- package/README.md +328 -0
- package/index.d.mts +502 -0
- package/index.d.ts +502 -0
- package/index.js +1 -0
- package/index.mjs +1 -0
- package/package.json +63 -0
package/index.d.mts
ADDED
|
@@ -0,0 +1,502 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Severity levels for structured issues and errors.
|
|
3
|
+
*/
|
|
4
|
+
type Severity = "error" | "warning" | "info";
|
|
5
|
+
/**
|
|
6
|
+
* Represents a detailed validation or operational problem.
|
|
7
|
+
* Designed to be machine-readable while remaining human-friendly.
|
|
8
|
+
*/
|
|
9
|
+
interface Issue {
|
|
10
|
+
/** Machine-readable identifier (e.g., "REQUIRED_FIELD_MISSING"). */
|
|
11
|
+
readonly code: string;
|
|
12
|
+
/** Human-readable description of the problem. */
|
|
13
|
+
readonly message: string;
|
|
14
|
+
/** Field path in a document or state (e.g., "users.0.email"). */
|
|
15
|
+
readonly path?: string;
|
|
16
|
+
/** Optional array index when the issue relates to a specific element. */
|
|
17
|
+
readonly index?: number;
|
|
18
|
+
/** Seriousness of the issue. Defaults to "error". */
|
|
19
|
+
readonly severity?: Severity;
|
|
20
|
+
/** Optional detailed explanation, can be multi-line. */
|
|
21
|
+
readonly description?: string;
|
|
22
|
+
/** Nested issues that caused this one. */
|
|
23
|
+
readonly cause?: readonly Issue[];
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Standardized error code format: CATEGORY-XXX[-SUFFIX]
|
|
27
|
+
* Examples:
|
|
28
|
+
* - VAL-001 (Validation: required field missing)
|
|
29
|
+
* - DB-002-NF (Database: not found)
|
|
30
|
+
* - AUTH-003-DENIED (Auth: permission denied)
|
|
31
|
+
*/
|
|
32
|
+
interface ErrorCodeMetadata {
|
|
33
|
+
/** The formal error code (e.g., "VAL-001") */
|
|
34
|
+
readonly code: string;
|
|
35
|
+
/** Human-readable name for the error type */
|
|
36
|
+
readonly name: string;
|
|
37
|
+
/** Detailed description of when this error occurs */
|
|
38
|
+
readonly description: string;
|
|
39
|
+
/** Suggested action for handling or resolving the error */
|
|
40
|
+
readonly action?: string;
|
|
41
|
+
/** HTTP status code mapping (if applicable) */
|
|
42
|
+
readonly httpStatus?: number;
|
|
43
|
+
/** Category of the error */
|
|
44
|
+
readonly category: ErrorCategory;
|
|
45
|
+
/** Whether this error should be logged as warning vs error */
|
|
46
|
+
readonly logLevel?: "debug" | "info" | "warn" | "error";
|
|
47
|
+
}
|
|
48
|
+
type ErrorCategory = "validation" | "database" | "auth" | "business" | "system" | "network" | "concurrency" | "custom";
|
|
49
|
+
/**
|
|
50
|
+
* SystemError is the primary error type for all operational and validation errors.
|
|
51
|
+
* Supports both predefined and custom error codes with full metadata.
|
|
52
|
+
*/
|
|
53
|
+
declare class SystemError extends Error {
|
|
54
|
+
readonly code: string;
|
|
55
|
+
readonly codeMetadata: ErrorCodeMetadata;
|
|
56
|
+
readonly severity: Severity;
|
|
57
|
+
readonly path?: string;
|
|
58
|
+
readonly operation?: string;
|
|
59
|
+
readonly issues: readonly Issue[];
|
|
60
|
+
readonly cause?: unknown;
|
|
61
|
+
constructor(params: {
|
|
62
|
+
code: string;
|
|
63
|
+
message?: string;
|
|
64
|
+
severity?: Severity;
|
|
65
|
+
path?: string;
|
|
66
|
+
operation?: string;
|
|
67
|
+
issues?: readonly Issue[];
|
|
68
|
+
cause?: unknown;
|
|
69
|
+
metadata?: Partial<Omit<ErrorCodeMetadata, "code">>;
|
|
70
|
+
});
|
|
71
|
+
/**
|
|
72
|
+
* Returns a new SystemError with the specified path.
|
|
73
|
+
*/
|
|
74
|
+
withPath(path: string): SystemError;
|
|
75
|
+
/**
|
|
76
|
+
* Returns a new SystemError with the specified operation name.
|
|
77
|
+
*/
|
|
78
|
+
withOperation(operation: string): SystemError;
|
|
79
|
+
/**
|
|
80
|
+
* Returns a new SystemError with the specified issue appended.
|
|
81
|
+
*/
|
|
82
|
+
withIssue(issue: Issue): SystemError;
|
|
83
|
+
/**
|
|
84
|
+
* Returns a new SystemError with multiple issues appended.
|
|
85
|
+
*/
|
|
86
|
+
withIssues(issues: readonly Issue[]): SystemError;
|
|
87
|
+
/**
|
|
88
|
+
* Returns a new SystemError wrapping the specified cause.
|
|
89
|
+
*/
|
|
90
|
+
withCause(cause: unknown): SystemError;
|
|
91
|
+
/**
|
|
92
|
+
* Returns the HTTP status code for this error (if applicable).
|
|
93
|
+
*/
|
|
94
|
+
getHttpStatus(): number | undefined;
|
|
95
|
+
/**
|
|
96
|
+
* Formats the error for logging with structured metadata.
|
|
97
|
+
*/
|
|
98
|
+
toLogEntry(): Record<string, unknown>;
|
|
99
|
+
/**
|
|
100
|
+
* Produces a human-readable representation suitable for logging.
|
|
101
|
+
*/
|
|
102
|
+
toString(): string;
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* A functional wrapper for operations that can fail.
|
|
106
|
+
* Encourages explicit error handling over try/catch blocks.
|
|
107
|
+
*/
|
|
108
|
+
type Result<T, E = SystemError> = {
|
|
109
|
+
readonly ok: true;
|
|
110
|
+
readonly value: T;
|
|
111
|
+
} | {
|
|
112
|
+
readonly ok: false;
|
|
113
|
+
readonly error: E;
|
|
114
|
+
};
|
|
115
|
+
/**
|
|
116
|
+
* Type-safe helpers for creating Results.
|
|
117
|
+
*/
|
|
118
|
+
declare const Result: {
|
|
119
|
+
ok: <T>(value: T) => Result<T, never>;
|
|
120
|
+
fail: <E>(error: E) => Result<never, E>;
|
|
121
|
+
};
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* Interface defining the shape of the EventBus.
|
|
125
|
+
* @template TEventMap - A record mapping event names to their respective payload types.
|
|
126
|
+
*/
|
|
127
|
+
interface EventBus<TEventMap extends Record<string, any>> {
|
|
128
|
+
/**
|
|
129
|
+
* Subscribes to a specific event by name.
|
|
130
|
+
* @param eventName - The name of the event to subscribe to.
|
|
131
|
+
* @param callback - The function to call when the event is emitted.
|
|
132
|
+
* @param options - Extra options to determine the behaviour of the
|
|
133
|
+
* subscription
|
|
134
|
+
* @returns A function to unsubscribe from the event.
|
|
135
|
+
*/
|
|
136
|
+
subscribe: <TEventName extends keyof TEventMap>(eventName: TEventName, callback: (payload: TEventMap[TEventName]) => void, options?: SubscribeOptions) => () => void;
|
|
137
|
+
/**
|
|
138
|
+
* Subscribes to an event and automatically unsubscribes after it fires once.
|
|
139
|
+
* @param eventName - The name of the event to subscribe to.
|
|
140
|
+
* @param callback - The function to call when the event is emitted.
|
|
141
|
+
* @returns A function to cancel the one-shot subscription before it fires.
|
|
142
|
+
*/
|
|
143
|
+
once: <TEventName extends keyof TEventMap>(eventName: TEventName, callback: (payload: TEventMap[TEventName]) => void, options?: SubscribeOptions) => () => void;
|
|
144
|
+
/**
|
|
145
|
+
* Emits an event with a payload to all subscribed listeners.
|
|
146
|
+
* @param event - An object containing the event name and payload.
|
|
147
|
+
*/
|
|
148
|
+
emit: <TEventName extends keyof TEventMap>(event: {
|
|
149
|
+
name: TEventName;
|
|
150
|
+
payload: TEventMap[TEventName];
|
|
151
|
+
}) => void;
|
|
152
|
+
/**
|
|
153
|
+
* Retrieves metrics about event bus usage.
|
|
154
|
+
* @returns An object containing various metrics.
|
|
155
|
+
*/
|
|
156
|
+
metrics: () => EventMetrics;
|
|
157
|
+
/**
|
|
158
|
+
* Clears all subscriptions and resets metrics.
|
|
159
|
+
* After calling clear(), the bus is fully reset and can be reused —
|
|
160
|
+
* cross-tab communication is re-established if it was previously enabled.
|
|
161
|
+
*/
|
|
162
|
+
clear: () => void;
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* Interface defining the metrics tracked by the EventBus.
|
|
166
|
+
*/
|
|
167
|
+
interface EventMetrics {
|
|
168
|
+
/** Total number of events emitted (both sync and deferred paths). */
|
|
169
|
+
totalEvents: number;
|
|
170
|
+
/** Number of active subscriptions across all event names. */
|
|
171
|
+
activeSubscriptions: number;
|
|
172
|
+
/** Map of event names to their emission counts. */
|
|
173
|
+
eventCounts: Map<string, number>;
|
|
174
|
+
/** Average duration of event dispatch in milliseconds. */
|
|
175
|
+
averageEmitDuration: number;
|
|
176
|
+
}
|
|
177
|
+
interface SubscribeOptions {
|
|
178
|
+
/**
|
|
179
|
+
* Debounce delay in milliseconds. When multiple events arrive in quick
|
|
180
|
+
* succession, the callback runs only after the quiet period ends, using the
|
|
181
|
+
* latest payload. Default = no debouncing.
|
|
182
|
+
*/
|
|
183
|
+
debounce?: number;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
/**
|
|
187
|
+
* The uniform data payload passed between pipeline stages.
|
|
188
|
+
* Always a flat record of `{ [stepKey]: value }` accumulated across stages.
|
|
189
|
+
*/
|
|
190
|
+
type StageCarry = Record<string, any>;
|
|
191
|
+
/**
|
|
192
|
+
* Lifecycle events emitted during any pipeline execution.
|
|
193
|
+
* `executionId` allows listeners to filter events when multiple runs are
|
|
194
|
+
* in-flight on the same pipeline instance simultaneously.
|
|
195
|
+
*/
|
|
196
|
+
interface PipelineEventMap {
|
|
197
|
+
/** Fired once when the execution loop begins. */
|
|
198
|
+
start: {
|
|
199
|
+
stepKey: string;
|
|
200
|
+
executionId: string;
|
|
201
|
+
};
|
|
202
|
+
/** Fired after each step completes successfully. */
|
|
203
|
+
"step:success": {
|
|
204
|
+
stepKey: string;
|
|
205
|
+
executionId: string;
|
|
206
|
+
result: any;
|
|
207
|
+
};
|
|
208
|
+
/** Fired after each step that returns or throws a failure. */
|
|
209
|
+
"step:failure": {
|
|
210
|
+
stepKey: string;
|
|
211
|
+
executionId: string;
|
|
212
|
+
error: SystemError;
|
|
213
|
+
};
|
|
214
|
+
/** Fired after all steps in a stage have settled. `carry` is that stage's output only. */
|
|
215
|
+
"stage:success": {
|
|
216
|
+
order: number;
|
|
217
|
+
executionId: string;
|
|
218
|
+
carry: StageCarry;
|
|
219
|
+
};
|
|
220
|
+
/** Fired when the execution loop completes normally. `carry` is the final stage output. */
|
|
221
|
+
terminate: {
|
|
222
|
+
carry: StageCarry;
|
|
223
|
+
executionId: string;
|
|
224
|
+
};
|
|
225
|
+
/** Fired on the first step failure in a stage. */
|
|
226
|
+
failure: {
|
|
227
|
+
stepKey: string;
|
|
228
|
+
executionId: string;
|
|
229
|
+
error: SystemError;
|
|
230
|
+
};
|
|
231
|
+
/** Fired when a step emits a routing instruction. */
|
|
232
|
+
"step:routing": {
|
|
233
|
+
stepKey: string;
|
|
234
|
+
executionId: string;
|
|
235
|
+
fromStep: string;
|
|
236
|
+
toStep: string;
|
|
237
|
+
value: any;
|
|
238
|
+
iteration?: number;
|
|
239
|
+
};
|
|
240
|
+
/** Fired on each loop iteration. */
|
|
241
|
+
"loop:iteration"?: {
|
|
242
|
+
executionId: string;
|
|
243
|
+
stepKey: string;
|
|
244
|
+
iteration: number;
|
|
245
|
+
maxIterations?: number;
|
|
246
|
+
};
|
|
247
|
+
/** Fired when a loop is terminated by limit or condition. */
|
|
248
|
+
"loop:terminated"?: {
|
|
249
|
+
executionId: string;
|
|
250
|
+
stepKey: string;
|
|
251
|
+
reason: "max_iterations" | "condition_failed" | "manual_break";
|
|
252
|
+
iteration: number;
|
|
253
|
+
};
|
|
254
|
+
/** Fired when a step is skipped during selective re-execution (routing mode). */
|
|
255
|
+
"step:skipped": {
|
|
256
|
+
stepKey: string;
|
|
257
|
+
executionId: string;
|
|
258
|
+
};
|
|
259
|
+
}
|
|
260
|
+
/**
|
|
261
|
+
* A single executable step in a sequential pipeline.
|
|
262
|
+
*
|
|
263
|
+
* @template TIn Shape of the incoming StageCarry this step expects to read.
|
|
264
|
+
* @template TOut Value type this step produces on success.
|
|
265
|
+
*/
|
|
266
|
+
interface PipelineStep<TIn extends StageCarry = StageCarry, TOut = any> {
|
|
267
|
+
/** Unique identifier. Used as the carry key for this step's output. */
|
|
268
|
+
key: string;
|
|
269
|
+
/** Execution order. Steps sharing the same order run concurrently. */
|
|
270
|
+
order: number;
|
|
271
|
+
/**
|
|
272
|
+
* Business logic for this step.
|
|
273
|
+
* @param input Accumulated carry from all previous stages.
|
|
274
|
+
* @param signal Abort signal scoped to this execution run.
|
|
275
|
+
*/
|
|
276
|
+
action: (input: TIn, signal?: AbortSignal) => Promise<Result<TOut>>;
|
|
277
|
+
}
|
|
278
|
+
/** Step definition without an explicit `order` — derived from array position in a definition. */
|
|
279
|
+
type PipelineStepDefinition = Omit<PipelineStep, "order">;
|
|
280
|
+
/**
|
|
281
|
+
* Declarative sequential pipeline shape passed to the constructor.
|
|
282
|
+
* Outer array index → stage `order`. Inner arrays → parallel slots within a stage.
|
|
283
|
+
*/
|
|
284
|
+
type PipelineDefinition = Array<PipelineStepDefinition | PipelineStepDefinition[]>;
|
|
285
|
+
/**
|
|
286
|
+
* Returned by a routing step action to redirect execution to another step.
|
|
287
|
+
* Use the `routeTo()` helper to construct this.
|
|
288
|
+
*/
|
|
289
|
+
interface RoutingInstruction {
|
|
290
|
+
/** Key of the step to jump to. May refer to any registered step, including earlier ones. */
|
|
291
|
+
next: string;
|
|
292
|
+
/** Value to place in the carry under the target step's key before jumping. */
|
|
293
|
+
value: any;
|
|
294
|
+
/** Maximum number of times this loop point may be visited before the engine hard-fails. */
|
|
295
|
+
maxIterations?: number;
|
|
296
|
+
/**
|
|
297
|
+
* Optional guard evaluated after each iteration increment.
|
|
298
|
+
* Return false to terminate the loop cleanly (emits `loop:terminated` with reason
|
|
299
|
+
* `"condition_failed"` and exits with the last successful carry).
|
|
300
|
+
*/
|
|
301
|
+
condition?: (carry: StageCarry, iteration: number) => boolean | Promise<boolean>;
|
|
302
|
+
}
|
|
303
|
+
/**
|
|
304
|
+
* Context injected into every routing step action.
|
|
305
|
+
* Analogous to `ArtifactFactoryContext` — the step interacts with the engine through this.
|
|
306
|
+
*/
|
|
307
|
+
interface PipelineStepContext {
|
|
308
|
+
/**
|
|
309
|
+
* Abort signal scoped to this execution run.
|
|
310
|
+
* Check this inside long-running actions to respect cancellation.
|
|
311
|
+
*/
|
|
312
|
+
signal: AbortSignal;
|
|
313
|
+
/**
|
|
314
|
+
* Reads a value from the current carry AND registers a dependency edge in the
|
|
315
|
+
* execution graph so the engine knows which carry keys this step depends on.
|
|
316
|
+
*
|
|
317
|
+
* Steps with no `use()` calls have no declared dependencies and will always
|
|
318
|
+
* re-execute when their stage is revisited — the safe conservative fallback.
|
|
319
|
+
*
|
|
320
|
+
* @param key The carry key to read (always the key of a previous step).
|
|
321
|
+
* @returns The value stored under that key in the current carry.
|
|
322
|
+
*/
|
|
323
|
+
use<K extends string>(key: K): StageCarry[K];
|
|
324
|
+
/**
|
|
325
|
+
* The number of times this specific step has been executed in the current
|
|
326
|
+
* routing chain. Zero on first execution, increments on each re-visit.
|
|
327
|
+
* Useful for backoff logic or conditional behaviour without external state.
|
|
328
|
+
*/
|
|
329
|
+
iteration: number;
|
|
330
|
+
}
|
|
331
|
+
/**
|
|
332
|
+
* A single executable step in a routing pipeline.
|
|
333
|
+
* May return a plain result OR a `RoutingInstruction` to redirect execution.
|
|
334
|
+
*
|
|
335
|
+
* @template TIn Shape of the incoming StageCarry this step expects to read.
|
|
336
|
+
* @template TOut Value type this step produces on a non-routing success.
|
|
337
|
+
*/
|
|
338
|
+
interface RoutingPipelineStep<TIn extends StageCarry = StageCarry, TOut = any> {
|
|
339
|
+
/** Unique identifier. Used as the carry key for this step's output. */
|
|
340
|
+
key: string;
|
|
341
|
+
/** Execution order. Steps sharing the same order run concurrently. */
|
|
342
|
+
order: number;
|
|
343
|
+
/**
|
|
344
|
+
* Business logic for this step.
|
|
345
|
+
* @param input Accumulated carry from all previous stages.
|
|
346
|
+
* @param ctx Engine-provided context: signal, use(), iteration.
|
|
347
|
+
* @returns A Result wrapping either a plain output value or a RoutingInstruction.
|
|
348
|
+
*/
|
|
349
|
+
action: (input: TIn, ctx: PipelineStepContext) => Promise<Result<TOut | RoutingInstruction>>;
|
|
350
|
+
}
|
|
351
|
+
/** Step definition without an explicit `order` — derived from array position. */
|
|
352
|
+
type RoutingPipelineStepDefinition = Omit<RoutingPipelineStep, "order">;
|
|
353
|
+
/**
|
|
354
|
+
* Declarative routing pipeline shape passed to the constructor.
|
|
355
|
+
* Outer array index → stage `order`. Inner arrays → parallel slots within a stage.
|
|
356
|
+
*/
|
|
357
|
+
type RoutingPipelineDefinition = Array<RoutingPipelineStepDefinition | RoutingPipelineStepDefinition[]>;
|
|
358
|
+
/** Per-step loop tracking state, maintained inside a RoutingExecutionContext. */
|
|
359
|
+
interface LoopContext {
|
|
360
|
+
/** Number of times this step has been visited in the current routing chain. */
|
|
361
|
+
iteration: number;
|
|
362
|
+
/** Hard ceiling on iterations for this step (if specified via routeTo options). */
|
|
363
|
+
maxIterations?: number;
|
|
364
|
+
/** Timestamp of the first visit — useful for timeout / telemetry. */
|
|
365
|
+
startTime: number;
|
|
366
|
+
/** History of values and source steps passed through this loop point. */
|
|
367
|
+
history: Array<{
|
|
368
|
+
value: any;
|
|
369
|
+
fromStep: string | undefined;
|
|
370
|
+
timestamp: number;
|
|
371
|
+
}>;
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
/**
|
|
375
|
+
* Isolated runtime for one sequential pipeline run.
|
|
376
|
+
*
|
|
377
|
+
* Each context owns its own AbortController and EventBus so concurrent
|
|
378
|
+
* executions on the same Pipeline instance cannot interleave their
|
|
379
|
+
* cancellation state or misfire each other's lifecycle events.
|
|
380
|
+
*
|
|
381
|
+
* `run()` is Once-gated: the first call executes; subsequent calls on the
|
|
382
|
+
* same context instance return the cached result immediately.
|
|
383
|
+
*/
|
|
384
|
+
declare class SequentialExecutionContext {
|
|
385
|
+
private readonly pipeline;
|
|
386
|
+
readonly stepKey: string;
|
|
387
|
+
readonly params: any;
|
|
388
|
+
/** Unique identifier for this execution run. */
|
|
389
|
+
readonly id: string;
|
|
390
|
+
private readonly localBus;
|
|
391
|
+
private readonly controller;
|
|
392
|
+
private readonly once;
|
|
393
|
+
constructor(pipeline: Pipeline, stepKey: string, params: any, externalSignal?: AbortSignal, bus?: EventBus<PipelineEventMap>);
|
|
394
|
+
/** Abort signal scoped to this execution run. */
|
|
395
|
+
get signal(): AbortSignal;
|
|
396
|
+
/**
|
|
397
|
+
* Subscribe to lifecycle events scoped strictly to this execution run.
|
|
398
|
+
* @returns Unsubscribe function.
|
|
399
|
+
*/
|
|
400
|
+
on<K extends keyof PipelineEventMap>(event: K, handler: (payload: PipelineEventMap[K]) => void): () => void;
|
|
401
|
+
/** Immediately cancels this execution. */
|
|
402
|
+
abort(): void;
|
|
403
|
+
/**
|
|
404
|
+
* Runs the sequential execution loop from `stepKey`.
|
|
405
|
+
* Guaranteed to execute at most once — subsequent calls return the cached result.
|
|
406
|
+
*/
|
|
407
|
+
run(): Promise<Result<StageCarry>>;
|
|
408
|
+
private _run;
|
|
409
|
+
/** Runs all steps in a stage concurrently and collects their outputs. */
|
|
410
|
+
private runStage;
|
|
411
|
+
private emit;
|
|
412
|
+
private failCancelled;
|
|
413
|
+
}
|
|
414
|
+
/**
|
|
415
|
+
* A staged sequential async pipeline.
|
|
416
|
+
*
|
|
417
|
+
* Steps are grouped by `order`. All steps sharing the same order execute
|
|
418
|
+
* concurrently; stages execute one after another. Data flows forward via
|
|
419
|
+
* the `StageCarry` — each stage receives the accumulated outputs of all
|
|
420
|
+
* prior stages and contributes its own output under its step key.
|
|
421
|
+
*
|
|
422
|
+
* Callers receive only the final stage's output, keeping the result clean
|
|
423
|
+
* regardless of how many intermediate stages ran.
|
|
424
|
+
*
|
|
425
|
+
* `execute()` serialises invocations on the same instance and deduplicates
|
|
426
|
+
* concurrent calls with identical parameters. For true concurrent execution,
|
|
427
|
+
* use `prepare()` to obtain isolated `SequentialExecutionContext` instances
|
|
428
|
+
* and call `.run()` on each independently.
|
|
429
|
+
*
|
|
430
|
+
* @example
|
|
431
|
+
* const pipeline = new Pipeline([
|
|
432
|
+
* { key: "fetch", action: async ({ fetch }) => Result.ok(await fetchData(fetch.url)) },
|
|
433
|
+
* { key: "process", action: async ({ fetch }) => Result.ok(transform(fetch)) },
|
|
434
|
+
* { key: "save", action: async ({ process }) => Result.ok(await saveData(process)) },
|
|
435
|
+
* ]);
|
|
436
|
+
*
|
|
437
|
+
* const result = await pipeline.execute("fetch", { url: "https://..." });
|
|
438
|
+
*/
|
|
439
|
+
declare class Pipeline {
|
|
440
|
+
private readonly steps;
|
|
441
|
+
private readonly globalBus;
|
|
442
|
+
private readonly serializer;
|
|
443
|
+
private readonly executions;
|
|
444
|
+
/** @param definition Optional declarative stage/step structure. */
|
|
445
|
+
constructor(definition?: PipelineDefinition);
|
|
446
|
+
/** @internal Exposes registered steps to SequentialExecutionContext. */
|
|
447
|
+
getSteps(): Map<string, PipelineStep>;
|
|
448
|
+
/**
|
|
449
|
+
* Registers or overwrites a step after construction.
|
|
450
|
+
* @returns The Pipeline instance for fluent chaining.
|
|
451
|
+
*/
|
|
452
|
+
step<TIn extends StageCarry, TOut>(definition: PipelineStep<TIn, TOut>): this;
|
|
453
|
+
/**
|
|
454
|
+
* Subscribes to lifecycle events on the default execution bus.
|
|
455
|
+
* Only receives events from calls to `execute()` — not from `prepare()` contexts.
|
|
456
|
+
* @returns Unsubscribe function.
|
|
457
|
+
*/
|
|
458
|
+
on<K extends keyof PipelineEventMap>(event: K, handler: (payload: PipelineEventMap[K]) => void): () => void;
|
|
459
|
+
/**
|
|
460
|
+
* Spawns an isolated execution context without running it.
|
|
461
|
+
* Use this when you need to run multiple executions concurrently, each with
|
|
462
|
+
* its own abort control and scoped event listeners.
|
|
463
|
+
*/
|
|
464
|
+
prepare<TIn = any>(stepKey: string, params: TIn, options?: {
|
|
465
|
+
signal?: AbortSignal;
|
|
466
|
+
}, bus?: EventBus<PipelineEventMap>): SequentialExecutionContext;
|
|
467
|
+
/**
|
|
468
|
+
* Executes the pipeline from `stepKey` with `params`.
|
|
469
|
+
*
|
|
470
|
+
* Concurrent calls with identical `stepKey` + `params` join the in-flight
|
|
471
|
+
* execution rather than spawning a duplicate. Calls with different params
|
|
472
|
+
* are serialised to preserve the single-thread model on this instance.
|
|
473
|
+
*
|
|
474
|
+
* @param options.signal External AbortSignal to cancel execution.
|
|
475
|
+
* @param options.disableDeduplication Force a fresh execution even if one is in-flight.
|
|
476
|
+
*/
|
|
477
|
+
execute<TIn = any>(stepKey: string, params: TIn, options?: {
|
|
478
|
+
signal?: AbortSignal;
|
|
479
|
+
disableDeduplication?: boolean;
|
|
480
|
+
}): Promise<Result<StageCarry>>;
|
|
481
|
+
/**
|
|
482
|
+
* Returns all registered step keys.
|
|
483
|
+
* Useful for debugging and validation.
|
|
484
|
+
*/
|
|
485
|
+
getRegisteredSteps(): string[];
|
|
486
|
+
/**
|
|
487
|
+
* Validates the pipeline for obvious structural issues.
|
|
488
|
+
* @returns Array of error strings — empty if valid.
|
|
489
|
+
*/
|
|
490
|
+
validate(): string[];
|
|
491
|
+
/**
|
|
492
|
+
* Disposes of the pipeline, clearing all steps, event listeners, and
|
|
493
|
+
* the deduplication cache.
|
|
494
|
+
*/
|
|
495
|
+
destroy(): void;
|
|
496
|
+
/** @internal Groups steps by order for stage-based execution. */
|
|
497
|
+
groupByOrder(): Map<number, PipelineStep[]>;
|
|
498
|
+
private getDedupeKey;
|
|
499
|
+
private sortObjectKeys;
|
|
500
|
+
}
|
|
501
|
+
|
|
502
|
+
export { type LoopContext, Pipeline, type PipelineDefinition, type PipelineEventMap, type PipelineStep, type PipelineStepContext, type PipelineStepDefinition, Result, type RoutingInstruction, type RoutingPipelineDefinition, type RoutingPipelineStep, type RoutingPipelineStepDefinition, SequentialExecutionContext, type StageCarry, SystemError };
|