@lotiai/composer 0.2.0 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/build-config/index.d.ts +52 -0
- package/dist/build-config/index.d.ts.map +1 -0
- package/dist/build-config/index.js +66 -0
- package/dist/build-config/index.js.map +1 -0
- package/dist/build-config/loader.d.ts +80 -0
- package/dist/build-config/loader.d.ts.map +1 -0
- package/dist/build-config/loader.js +238 -0
- package/dist/build-config/loader.js.map +1 -0
- package/dist/build-config/schema.d.ts +101 -0
- package/dist/build-config/schema.d.ts.map +1 -0
- package/dist/build-config/schema.js +94 -0
- package/dist/build-config/schema.js.map +1 -0
- package/dist/cli/commands/dev-temporal.d.ts +15 -0
- package/dist/cli/commands/dev-temporal.d.ts.map +1 -0
- package/dist/cli/commands/dev-temporal.js +68 -0
- package/dist/cli/commands/dev-temporal.js.map +1 -0
- package/dist/cli/commands/dev.d.ts +21 -0
- package/dist/cli/commands/dev.d.ts.map +1 -0
- package/dist/cli/commands/dev.js +421 -0
- package/dist/cli/commands/dev.js.map +1 -0
- package/dist/cli/commands/profiles.d.ts +15 -0
- package/dist/cli/commands/profiles.d.ts.map +1 -0
- package/dist/cli/commands/profiles.js +69 -0
- package/dist/cli/commands/profiles.js.map +1 -0
- package/dist/cli/index.d.ts +21 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +44 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/index.d.ts +15 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +57 -0
- package/dist/index.js.map +1 -0
- package/dist/internal/async/build/workflow-factory.d.ts +212 -0
- package/dist/internal/async/build/workflow-factory.d.ts.map +1 -0
- package/dist/internal/async/build/workflow-factory.js +533 -0
- package/dist/internal/async/build/workflow-factory.js.map +1 -0
- package/dist/internal/async/build-scripts/utils/common.d.ts +28 -0
- package/dist/internal/async/build-scripts/utils/common.d.ts.map +1 -0
- package/dist/internal/async/build-scripts/utils/common.js +50 -0
- package/dist/internal/async/build-scripts/utils/common.js.map +1 -0
- package/dist/internal/async/build-scripts/utils/import-module.d.ts +19 -0
- package/dist/internal/async/build-scripts/utils/import-module.d.ts.map +1 -0
- package/dist/internal/async/build-scripts/utils/import-module.js +80 -0
- package/dist/internal/async/build-scripts/utils/import-module.js.map +1 -0
- package/dist/internal/async/build-scripts/utils/type-guards.d.ts +123 -0
- package/dist/internal/async/build-scripts/utils/type-guards.d.ts.map +1 -0
- package/dist/internal/async/build-scripts/utils/type-guards.js +145 -0
- package/dist/internal/async/build-scripts/utils/type-guards.js.map +1 -0
- package/dist/internal/async/config/cleanup-policy.d.ts +50 -0
- package/dist/internal/async/config/cleanup-policy.d.ts.map +1 -0
- package/dist/internal/async/config/cleanup-policy.js +20 -0
- package/dist/internal/async/config/cleanup-policy.js.map +1 -0
- package/dist/internal/async/config/worker-profiles.d.ts +172 -0
- package/dist/internal/async/config/worker-profiles.d.ts.map +1 -0
- package/dist/internal/async/config/worker-profiles.js +275 -0
- package/dist/internal/async/config/worker-profiles.js.map +1 -0
- package/dist/internal/async/execute/temporal-client.d.ts +182 -0
- package/dist/internal/async/execute/temporal-client.d.ts.map +1 -0
- package/dist/internal/async/execute/temporal-client.js +190 -0
- package/dist/internal/async/execute/temporal-client.js.map +1 -0
- package/dist/internal/async/execute/workflow-execution.d.ts +98 -0
- package/dist/internal/async/execute/workflow-execution.d.ts.map +1 -0
- package/dist/internal/async/execute/workflow-execution.js +191 -0
- package/dist/internal/async/execute/workflow-execution.js.map +1 -0
- package/dist/internal/async/metrics/task-queue-metrics.d.ts +74 -0
- package/dist/internal/async/metrics/task-queue-metrics.d.ts.map +1 -0
- package/dist/internal/async/metrics/task-queue-metrics.js +155 -0
- package/dist/internal/async/metrics/task-queue-metrics.js.map +1 -0
- package/dist/internal/async/register/activity-worker.d.ts +123 -0
- package/dist/internal/async/register/activity-worker.d.ts.map +1 -0
- package/dist/internal/async/register/activity-worker.js +355 -0
- package/dist/internal/async/register/activity-worker.js.map +1 -0
- package/dist/internal/async/register/generate-workflow-source.d.ts +43 -0
- package/dist/internal/async/register/generate-workflow-source.d.ts.map +1 -0
- package/dist/internal/async/register/generate-workflow-source.js +193 -0
- package/dist/internal/async/register/generate-workflow-source.js.map +1 -0
- package/dist/internal/async/register/workflow-worker.d.ts +125 -0
- package/dist/internal/async/register/workflow-worker.d.ts.map +1 -0
- package/dist/internal/async/register/workflow-worker.js +215 -0
- package/dist/internal/async/register/workflow-worker.js.map +1 -0
- package/dist/internal/async/register-scripts/start-activity-worker.d.ts +70 -0
- package/dist/internal/async/register-scripts/start-activity-worker.d.ts.map +1 -0
- package/dist/internal/async/register-scripts/start-activity-worker.js +75 -0
- package/dist/internal/async/register-scripts/start-activity-worker.js.map +1 -0
- package/dist/internal/async/register-scripts/start-all-workers.d.ts +81 -0
- package/dist/internal/async/register-scripts/start-all-workers.d.ts.map +1 -0
- package/dist/internal/async/register-scripts/start-all-workers.js +84 -0
- package/dist/internal/async/register-scripts/start-all-workers.js.map +1 -0
- package/dist/internal/async/register-scripts/start-workflow-worker.d.ts +69 -0
- package/dist/internal/async/register-scripts/start-workflow-worker.d.ts.map +1 -0
- package/dist/internal/async/register-scripts/start-workflow-worker.js +74 -0
- package/dist/internal/async/register-scripts/start-workflow-worker.js.map +1 -0
- package/dist/internal/async/register-scripts/sync-schedules-cli.d.ts +28 -0
- package/dist/internal/async/register-scripts/sync-schedules-cli.d.ts.map +1 -0
- package/dist/internal/async/register-scripts/sync-schedules-cli.js +124 -0
- package/dist/internal/async/register-scripts/sync-schedules-cli.js.map +1 -0
- package/dist/internal/async/register-scripts/sync-schedules-via-lambda.d.ts +55 -0
- package/dist/internal/async/register-scripts/sync-schedules-via-lambda.d.ts.map +1 -0
- package/dist/internal/async/register-scripts/sync-schedules-via-lambda.js +146 -0
- package/dist/internal/async/register-scripts/sync-schedules-via-lambda.js.map +1 -0
- package/dist/internal/async/register-scripts/sync-schedules.d.ts +68 -0
- package/dist/internal/async/register-scripts/sync-schedules.d.ts.map +1 -0
- package/dist/internal/async/register-scripts/sync-schedules.js +83 -0
- package/dist/internal/async/register-scripts/sync-schedules.js.map +1 -0
- package/dist/internal/async/schedule/constants.d.ts +10 -0
- package/dist/internal/async/schedule/constants.d.ts.map +1 -0
- package/dist/internal/async/schedule/constants.js +13 -0
- package/dist/internal/async/schedule/constants.js.map +1 -0
- package/dist/internal/async/schedule/define-schedule.d.ts +192 -0
- package/dist/internal/async/schedule/define-schedule.d.ts.map +1 -0
- package/dist/internal/async/schedule/define-schedule.js +79 -0
- package/dist/internal/async/schedule/define-schedule.js.map +1 -0
- package/dist/internal/async/schedule/index.d.ts +3 -0
- package/dist/internal/async/schedule/index.d.ts.map +1 -0
- package/dist/internal/async/schedule/index.js +9 -0
- package/dist/internal/async/schedule/index.js.map +1 -0
- package/dist/internal/async/schedule/schedule-definition-schema.d.ts +64 -0
- package/dist/internal/async/schedule/schedule-definition-schema.d.ts.map +1 -0
- package/dist/internal/async/schedule/schedule-definition-schema.js +77 -0
- package/dist/internal/async/schedule/schedule-definition-schema.js.map +1 -0
- package/dist/internal/async/schedule/sync-schedules.d.ts +71 -0
- package/dist/internal/async/schedule/sync-schedules.d.ts.map +1 -0
- package/dist/internal/async/schedule/sync-schedules.js +231 -0
- package/dist/internal/async/schedule/sync-schedules.js.map +1 -0
- package/dist/internal/async/utils/ensure-namespace.d.ts +16 -0
- package/dist/internal/async/utils/ensure-namespace.d.ts.map +1 -0
- package/dist/internal/async/utils/ensure-namespace.js +64 -0
- package/dist/internal/async/utils/ensure-namespace.js.map +1 -0
- package/dist/internal/async/utils/find-package-root.d.ts +9 -0
- package/dist/internal/async/utils/find-package-root.d.ts.map +1 -0
- package/dist/internal/async/utils/find-package-root.js +28 -0
- package/dist/internal/async/utils/find-package-root.js.map +1 -0
- package/dist/internal/async/utils/is-composer-error.d.ts +14 -0
- package/dist/internal/async/utils/is-composer-error.d.ts.map +1 -0
- package/dist/internal/async/utils/is-composer-error.js +17 -0
- package/dist/internal/async/utils/is-composer-error.js.map +1 -0
- package/dist/internal/context-provider.d.ts +316 -0
- package/dist/internal/context-provider.d.ts.map +1 -0
- package/dist/internal/context-provider.js +12 -0
- package/dist/internal/context-provider.js.map +1 -0
- package/dist/internal/create-composer.d.ts +57 -0
- package/dist/internal/create-composer.d.ts.map +1 -0
- package/dist/internal/create-composer.js +125 -0
- package/dist/internal/create-composer.js.map +1 -0
- package/dist/internal/dag-sync-fanout.d.ts +79 -0
- package/dist/internal/dag-sync-fanout.d.ts.map +1 -0
- package/dist/internal/dag-sync-fanout.js +59 -0
- package/dist/internal/dag-sync-fanout.js.map +1 -0
- package/dist/internal/dag-sync-step.d.ts +230 -0
- package/dist/internal/dag-sync-step.d.ts.map +1 -0
- package/dist/internal/dag-sync-step.js +159 -0
- package/dist/internal/dag-sync-step.js.map +1 -0
- package/dist/internal/dag-sync-workflow.d.ts +535 -0
- package/dist/internal/dag-sync-workflow.d.ts.map +1 -0
- package/dist/internal/dag-sync-workflow.js +843 -0
- package/dist/internal/dag-sync-workflow.js.map +1 -0
- package/dist/internal/defaults.d.ts +24 -0
- package/dist/internal/defaults.d.ts.map +1 -0
- package/dist/internal/defaults.js +102 -0
- package/dist/internal/defaults.js.map +1 -0
- package/dist/internal/errors.d.ts +109 -0
- package/dist/internal/errors.d.ts.map +1 -0
- package/dist/internal/errors.js +212 -0
- package/dist/internal/errors.js.map +1 -0
- package/dist/internal/index.d.ts +9 -0
- package/dist/internal/index.d.ts.map +1 -0
- package/dist/internal/index.js +22 -0
- package/dist/internal/index.js.map +1 -0
- package/dist/internal/observability.d.ts +63 -0
- package/dist/internal/observability.d.ts.map +1 -0
- package/dist/internal/observability.js +323 -0
- package/dist/internal/observability.js.map +1 -0
- package/dist/internal/types.d.ts +80 -0
- package/dist/internal/types.d.ts.map +1 -0
- package/dist/internal/types.js +9 -0
- package/dist/internal/types.js.map +1 -0
- package/dist/internal/workflow-planning.d.ts +107 -0
- package/dist/internal/workflow-planning.d.ts.map +1 -0
- package/dist/internal/workflow-planning.js +216 -0
- package/dist/internal/workflow-planning.js.map +1 -0
- package/dist/schedule-sync.d.ts +17 -0
- package/dist/schedule-sync.d.ts.map +1 -0
- package/dist/schedule-sync.js +22 -0
- package/dist/schedule-sync.js.map +1 -0
- package/dist/temporal-naming.d.ts +27 -0
- package/dist/temporal-naming.d.ts.map +1 -0
- package/dist/temporal-naming.js +33 -0
- package/dist/temporal-naming.js.map +1 -0
- package/package.json +16 -17
|
@@ -0,0 +1,316 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Context Provider Types for Composer
|
|
3
|
+
*
|
|
4
|
+
* This module defines the generic context provider pattern that allows
|
|
5
|
+
* steps to receive context (e.g., database connections) via lifecycle hooks.
|
|
6
|
+
*
|
|
7
|
+
* The context provider is configured once via createComposer() and used
|
|
8
|
+
* for both sync and async workflow execution.
|
|
9
|
+
*/
|
|
10
|
+
import type { ScheduleDefinition } from "./async/schedule/define-schedule";
|
|
11
|
+
import type { SyncSchedulesResult } from "./async/schedule/sync-schedules";
|
|
12
|
+
import type { ExtractWorkflowBag, ExtractWorkflowCheckpointNames, ExtractWorkflowConfig, ExtractWorkflowRequiredInitial, ExtractWorkflowSteps, InferWorkflowResult, SafeConfiguredKeys, Workflow, WorkflowResult } from "./dag-sync-workflow";
|
|
13
|
+
import type { ComposerLogger } from "./types";
|
|
14
|
+
/**
|
|
15
|
+
* Step Context Provider - manages context lifecycle for steps.
|
|
16
|
+
*
|
|
17
|
+
* Implement this interface to provide context (e.g., database connections,
|
|
18
|
+
* loggers) to steps. The beforeStep/afterStep hooks ensure proper lifecycle
|
|
19
|
+
* management (creation and cleanup).
|
|
20
|
+
*
|
|
21
|
+
* @typeParam TContext - The context type that steps will receive
|
|
22
|
+
*
|
|
23
|
+
* @example
|
|
24
|
+
* ```typescript
|
|
25
|
+
* const contextProvider: StepContextProvider<{ em: SqlEntityManager }> = {
|
|
26
|
+
* beforeStep: async (stepName) => ({
|
|
27
|
+
* em: await IxDbConnection.getInstance().getForkedEntityManager(),
|
|
28
|
+
* }),
|
|
29
|
+
* afterStep: async (ctx, error) => {
|
|
30
|
+
* if (!error) await ctx.em.flush();
|
|
31
|
+
* ctx.em.clear();
|
|
32
|
+
* },
|
|
33
|
+
* };
|
|
34
|
+
* ```
|
|
35
|
+
*/
|
|
36
|
+
export interface StepContextProvider<TContext> {
|
|
37
|
+
/**
|
|
38
|
+
* Called before each step executes.
|
|
39
|
+
* Returns the context that will be passed to the step's run function.
|
|
40
|
+
*
|
|
41
|
+
* @param stepName - The name of the step about to execute
|
|
42
|
+
* @returns The context for this step execution
|
|
43
|
+
*/
|
|
44
|
+
beforeStep: (stepName: string) => Promise<TContext>;
|
|
45
|
+
/**
|
|
46
|
+
* Called after each step completes (success or failure).
|
|
47
|
+
* Use this to clean up resources (e.g., clear entity manager).
|
|
48
|
+
*
|
|
49
|
+
* @param ctx - The context that was passed to the step
|
|
50
|
+
* @param error - The error if the step failed, undefined if successful
|
|
51
|
+
*/
|
|
52
|
+
afterStep: (ctx: TContext, error?: Error) => Promise<void>;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Configuration for creating a Composer instance.
|
|
56
|
+
*
|
|
57
|
+
* @typeParam TContext - The context type that steps will receive
|
|
58
|
+
*
|
|
59
|
+
* @example
|
|
60
|
+
* ```typescript
|
|
61
|
+
* const composer = createComposer({
|
|
62
|
+
* contextProvider: myContextProvider,
|
|
63
|
+
* logger: myPinoLogger, // optional, defaults to console
|
|
64
|
+
* deepFreeze: true, // optional, defaults to false
|
|
65
|
+
* });
|
|
66
|
+
* ```
|
|
67
|
+
*/
|
|
68
|
+
export interface ComposerConfig<TContext> {
|
|
69
|
+
/**
|
|
70
|
+
* The context provider that manages step context lifecycle.
|
|
71
|
+
*/
|
|
72
|
+
contextProvider: StepContextProvider<TContext>;
|
|
73
|
+
/**
|
|
74
|
+
* Custom logger for framework diagnostics.
|
|
75
|
+
*
|
|
76
|
+
* If not provided, defaults to a console-based logger.
|
|
77
|
+
* The logger is used for internal framework messages (step cleanup failures,
|
|
78
|
+
* error handler issues, workflow success/failure summaries).
|
|
79
|
+
*
|
|
80
|
+
* Any object with `info`, `warn`, `error`, and `debug` methods works.
|
|
81
|
+
* Compatible with console, pino, winston, and most logging libraries.
|
|
82
|
+
*/
|
|
83
|
+
logger?: ComposerLogger;
|
|
84
|
+
/**
|
|
85
|
+
* Enable deep-freezing of step outputs for immutability protection.
|
|
86
|
+
*
|
|
87
|
+
* When enabled, all step outputs are deeply frozen before being merged into
|
|
88
|
+
* the shared bag. This prevents mutation bugs (parallel batch mutations,
|
|
89
|
+
* downstream mutations, post-return mutations) at the cost of a small
|
|
90
|
+
* performance overhead (~0.5-10ms per output depending on object size).
|
|
91
|
+
*
|
|
92
|
+
* Recommended for development and testing. In production, enable unless
|
|
93
|
+
* profiling shows it's a bottleneck.
|
|
94
|
+
*
|
|
95
|
+
* @default false
|
|
96
|
+
*/
|
|
97
|
+
deepFreeze?: boolean;
|
|
98
|
+
/**
|
|
99
|
+
* Temporal server configuration for async workflow execution.
|
|
100
|
+
*
|
|
101
|
+
* When provided, `createComposer` returns a full `Composer` with async methods.
|
|
102
|
+
* When omitted, it returns a `SyncComposer` with only `runSyncWorkflow`.
|
|
103
|
+
*/
|
|
104
|
+
temporal?: TemporalConfig;
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Temporal server connection configuration.
|
|
108
|
+
*/
|
|
109
|
+
export interface TemporalConfig {
|
|
110
|
+
/** Temporal server address (e.g. "localhost:7233") */
|
|
111
|
+
serverAddress: string;
|
|
112
|
+
/** Temporal namespace (e.g. "default") */
|
|
113
|
+
namespace: string;
|
|
114
|
+
/**
|
|
115
|
+
* Service name used as the base for Worker Versioning deployment series
|
|
116
|
+
* (e.g., "orders-service"). Activity and workflow workers derive their
|
|
117
|
+
* series names as "{serviceName}-activities" and "{serviceName}-workflows".
|
|
118
|
+
*/
|
|
119
|
+
serviceName: string;
|
|
120
|
+
/**
|
|
121
|
+
* Build identifier for Worker Versioning (typically git commit SHA).
|
|
122
|
+
* When set, enables versioning for both worker registration and workflow starts.
|
|
123
|
+
* When unset (e.g., local dev), Worker Versioning is disabled.
|
|
124
|
+
*/
|
|
125
|
+
buildId?: string;
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Options for async workflow execution.
|
|
129
|
+
*
|
|
130
|
+
* @typeParam CheckpointNames - Union of valid checkpoint names for the workflow (defaults to `never`)
|
|
131
|
+
*/
|
|
132
|
+
export interface AsyncWorkflowOptions<CheckpointNames extends string = never> {
|
|
133
|
+
/**
|
|
134
|
+
* Optional caller-supplied workflow ID.
|
|
135
|
+
*
|
|
136
|
+
* If omitted, Composer generates a UUIDv7 automatically.
|
|
137
|
+
*/
|
|
138
|
+
workflowId?: string;
|
|
139
|
+
/**
|
|
140
|
+
* Checkpoint name to await for early return.
|
|
141
|
+
*
|
|
142
|
+
* If specified, returns partial bag state when the checkpoint is reached
|
|
143
|
+
* instead of waiting for full workflow completion. The workflow continues
|
|
144
|
+
* executing in the background after the checkpoint.
|
|
145
|
+
*
|
|
146
|
+
* Useful for fast HTTP responses while long-running work continues.
|
|
147
|
+
*
|
|
148
|
+
* @example
|
|
149
|
+
* ```typescript
|
|
150
|
+
* // Workflow with checkpoints
|
|
151
|
+
* const wf = createWorkflow<Bag>("my-workflow")
|
|
152
|
+
* .build([step1, step2, step3])
|
|
153
|
+
* .checkpoint("earlyReturn", { afterStep: step1 });
|
|
154
|
+
*
|
|
155
|
+
* // Get partial result after step1 completes
|
|
156
|
+
* const result = await composer.runAsyncWorkflow(wf, data, {
|
|
157
|
+
* awaitCheckpoint: "earlyReturn",
|
|
158
|
+
* });
|
|
159
|
+
* ```
|
|
160
|
+
*/
|
|
161
|
+
awaitCheckpoint?: [CheckpointNames] extends [never] ? "ERROR: Cannot use awaitCheckpoint - this workflow has no checkpoints defined" : NoInfer<CheckpointNames>;
|
|
162
|
+
/**
|
|
163
|
+
* Start the Temporal workflow and return immediately after Temporal accepts it.
|
|
164
|
+
*
|
|
165
|
+
* This is intended for long-running fire-and-forget workflows where the caller
|
|
166
|
+
* only needs to confirm handoff to Temporal, not wait for business completion.
|
|
167
|
+
*/
|
|
168
|
+
startOnly?: boolean;
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* Sync-only Composer instance.
|
|
172
|
+
*
|
|
173
|
+
* Returned by `createComposer()` when no `temporal` config is provided.
|
|
174
|
+
* Supports only synchronous (in-process) workflow execution.
|
|
175
|
+
*
|
|
176
|
+
* Workflows never throw - errors are returned in `result.error`.
|
|
177
|
+
* Check `result.error` to handle failures, use `result.bag` for success data.
|
|
178
|
+
*
|
|
179
|
+
* @typeParam TContext - The context type that steps will receive
|
|
180
|
+
*/
|
|
181
|
+
export interface SyncComposer<TContext> {
|
|
182
|
+
/**
|
|
183
|
+
* Run a workflow synchronously (in-process).
|
|
184
|
+
*
|
|
185
|
+
* Best for: tests, local development, simple use cases.
|
|
186
|
+
*
|
|
187
|
+
* @param workflow - The workflow to execute
|
|
188
|
+
* @param initialData - Initial data for the workflow bag
|
|
189
|
+
* @returns WorkflowResult with bag and optional error
|
|
190
|
+
*
|
|
191
|
+
* @example
|
|
192
|
+
* ```typescript
|
|
193
|
+
* const result = await composer.runSyncWorkflow(myWorkflow, data);
|
|
194
|
+
* if (result.error) {
|
|
195
|
+
* // Handle error
|
|
196
|
+
* }
|
|
197
|
+
* // Use result.bag
|
|
198
|
+
* ```
|
|
199
|
+
*/
|
|
200
|
+
runSyncWorkflow<W extends Workflow<any, never, any, any, any>>(workflow: W, initialData?: Partial<ExtractWorkflowBag<W>>): Promise<WorkflowResult<InferWorkflowResult<ExtractWorkflowBag<W>, ExtractWorkflowSteps<W>, never, SafeConfiguredKeys<ExtractWorkflowConfig<W>, ExtractWorkflowBag<W>>> & Partial<ExtractWorkflowBag<W>>>>;
|
|
201
|
+
runSyncWorkflow<W extends Workflow<any, any, any, any, any>>(workflow: W, initialData: Partial<ExtractWorkflowBag<W>> & Pick<ExtractWorkflowBag<W>, ExtractWorkflowRequiredInitial<W>>): Promise<WorkflowResult<InferWorkflowResult<ExtractWorkflowBag<W>, ExtractWorkflowSteps<W>, ExtractWorkflowRequiredInitial<W>, SafeConfiguredKeys<ExtractWorkflowConfig<W>, ExtractWorkflowBag<W>>>>>;
|
|
202
|
+
/**
|
|
203
|
+
* Access the underlying context provider.
|
|
204
|
+
* Useful for advanced use cases or when you need to share the provider.
|
|
205
|
+
*/
|
|
206
|
+
contextProvider: StepContextProvider<TContext>;
|
|
207
|
+
/**
|
|
208
|
+
* The logger used for framework diagnostics.
|
|
209
|
+
* This is the resolved logger (either the one passed to createComposer or the default).
|
|
210
|
+
*/
|
|
211
|
+
readonly logger: ComposerLogger;
|
|
212
|
+
}
|
|
213
|
+
/**
|
|
214
|
+
* Full Composer instance with sync and async workflow support.
|
|
215
|
+
*
|
|
216
|
+
* Returned by `createComposer()` when `temporal` config is provided.
|
|
217
|
+
* Supports both synchronous and Temporal-based async workflow execution.
|
|
218
|
+
*
|
|
219
|
+
* @typeParam TContext - The context type that steps will receive
|
|
220
|
+
*/
|
|
221
|
+
export interface Composer<TContext> extends SyncComposer<TContext> {
|
|
222
|
+
/**
|
|
223
|
+
* Run a workflow asynchronously via Temporal.
|
|
224
|
+
*
|
|
225
|
+
* Best for: production, long-running workflows, reliability.
|
|
226
|
+
*
|
|
227
|
+
* @param workflow - The workflow to execute
|
|
228
|
+
* @param initialData - Initial data for the workflow bag
|
|
229
|
+
* @param options - Optional execution options (e.g., awaitCheckpoint for early return)
|
|
230
|
+
* @returns WorkflowResult with bag and optional error
|
|
231
|
+
*
|
|
232
|
+
* @example
|
|
233
|
+
* ```typescript
|
|
234
|
+
* // Full workflow completion
|
|
235
|
+
* const result = await composer.runAsyncWorkflow(myWorkflow, data);
|
|
236
|
+
*
|
|
237
|
+
* // Early return at checkpoint (workflow continues in background)
|
|
238
|
+
* const partialResult = await composer.runAsyncWorkflow(myWorkflow, data, {
|
|
239
|
+
* awaitCheckpoint: "created",
|
|
240
|
+
* });
|
|
241
|
+
* ```
|
|
242
|
+
*/
|
|
243
|
+
runAsyncWorkflow<W extends Workflow<any, never, any, any, any>>(workflow: W, initialData?: Partial<ExtractWorkflowBag<W>>, options?: AsyncWorkflowOptions<ExtractWorkflowCheckpointNames<W>>): Promise<WorkflowResult<InferWorkflowResult<ExtractWorkflowBag<W>, ExtractWorkflowSteps<W>, never, SafeConfiguredKeys<ExtractWorkflowConfig<W>, ExtractWorkflowBag<W>>> & Partial<ExtractWorkflowBag<W>>>>;
|
|
244
|
+
runAsyncWorkflow<W extends Workflow<any, any, any, any, any>>(workflow: W, initialData: Partial<ExtractWorkflowBag<W>> & Pick<ExtractWorkflowBag<W>, ExtractWorkflowRequiredInitial<W>>, options?: AsyncWorkflowOptions<ExtractWorkflowCheckpointNames<W>>): Promise<WorkflowResult<InferWorkflowResult<ExtractWorkflowBag<W>, ExtractWorkflowSteps<W>, ExtractWorkflowRequiredInitial<W>, SafeConfiguredKeys<ExtractWorkflowConfig<W>, ExtractWorkflowBag<W>>>>>;
|
|
245
|
+
/**
|
|
246
|
+
* Start an async workflow without waiting for completion (fire-and-forget).
|
|
247
|
+
*
|
|
248
|
+
* Returns only the workflowId. The workflow executes in the background
|
|
249
|
+
* on Temporal workers. Use this for 202 Accepted HTTP responses.
|
|
250
|
+
*
|
|
251
|
+
* @example
|
|
252
|
+
* ```typescript
|
|
253
|
+
* const { workflowId } = await composer.startAsyncWorkflow(myWorkflow, data);
|
|
254
|
+
* reply.code(202).send({ workflowId });
|
|
255
|
+
* ```
|
|
256
|
+
*/
|
|
257
|
+
startAsyncWorkflow<W extends Workflow<any, never, any, any, any>>(workflow: W, initialData?: Partial<ExtractWorkflowBag<W>>): Promise<{
|
|
258
|
+
workflowId: string;
|
|
259
|
+
}>;
|
|
260
|
+
startAsyncWorkflow<W extends Workflow<any, any, any, any, any>>(workflow: W, initialData: Partial<ExtractWorkflowBag<W>> & Pick<ExtractWorkflowBag<W>, ExtractWorkflowRequiredInitial<W>>): Promise<{
|
|
261
|
+
workflowId: string;
|
|
262
|
+
}>;
|
|
263
|
+
/**
|
|
264
|
+
* The Temporal connection configuration.
|
|
265
|
+
* Available on full Composer instances (created with temporal config).
|
|
266
|
+
*/
|
|
267
|
+
readonly temporal: TemporalConfig;
|
|
268
|
+
/**
|
|
269
|
+
* Start activity workers for Temporal execution.
|
|
270
|
+
*
|
|
271
|
+
* This starts long-running worker processes that execute step business logic.
|
|
272
|
+
* The Temporal server address, namespace, context provider, and logger are
|
|
273
|
+
* automatically injected from the Composer's configuration.
|
|
274
|
+
*
|
|
275
|
+
* Call this in your worker startup scripts.
|
|
276
|
+
*
|
|
277
|
+
* @param config - Activity worker configuration (queues, concurrency)
|
|
278
|
+
*/
|
|
279
|
+
runActivityWorkers: (config: {
|
|
280
|
+
taskQueues: string[];
|
|
281
|
+
maxConcurrentActivityTaskExecutions: number;
|
|
282
|
+
workflows: Workflow<any, any, any>[];
|
|
283
|
+
}) => Promise<void>;
|
|
284
|
+
/**
|
|
285
|
+
* Start workflow workers for Temporal execution.
|
|
286
|
+
*
|
|
287
|
+
* This starts long-running worker processes that generate workflow plans and
|
|
288
|
+
* execute workflow orchestration logic (batch sequencing, parallel execution).
|
|
289
|
+
* The Temporal server address, namespace, and logger are automatically injected
|
|
290
|
+
* from the Composer's configuration.
|
|
291
|
+
*
|
|
292
|
+
* Call this in your worker startup scripts.
|
|
293
|
+
*
|
|
294
|
+
* @param config - Workflow worker configuration (queues, concurrency, workflows)
|
|
295
|
+
*/
|
|
296
|
+
runWorkflowWorkers: (config: {
|
|
297
|
+
taskQueues: string[];
|
|
298
|
+
maxConcurrentWorkflowTaskExecutions: number;
|
|
299
|
+
workflows: Workflow<any, any, any>[];
|
|
300
|
+
}) => Promise<void>;
|
|
301
|
+
/**
|
|
302
|
+
* Declaratively sync schedule definitions to the Temporal server.
|
|
303
|
+
*
|
|
304
|
+
* Creates new schedules, updates existing ones, and deletes composer-managed
|
|
305
|
+
* schedules that are no longer in the definitions. Non-composer schedules
|
|
306
|
+
* (without the `managedBy: "composer"` memo) are never touched.
|
|
307
|
+
*
|
|
308
|
+
* @param schedules - Schedule definitions (source of truth)
|
|
309
|
+
* @param options - Optional sync options
|
|
310
|
+
* @returns Summary of what was created, updated, and deleted
|
|
311
|
+
*/
|
|
312
|
+
syncSchedules: (schedules: ScheduleDefinition[], options?: {
|
|
313
|
+
dryRun?: boolean;
|
|
314
|
+
}) => Promise<SyncSchedulesResult>;
|
|
315
|
+
}
|
|
316
|
+
//# sourceMappingURL=context-provider.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context-provider.d.ts","sourceRoot":"","sources":["../../src/internal/context-provider.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Context Provider Types for Composer
|
|
4
|
+
*
|
|
5
|
+
* This module defines the generic context provider pattern that allows
|
|
6
|
+
* steps to receive context (e.g., database connections) via lifecycle hooks.
|
|
7
|
+
*
|
|
8
|
+
* The context provider is configured once via createComposer() and used
|
|
9
|
+
* for both sync and async workflow execution.
|
|
10
|
+
*/
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
//# sourceMappingURL=context-provider.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context-provider.js","sourceRoot":"","sources":["../../src/internal/context-provider.ts"],"names":[],"mappings":";AAAA;;;;;;;;GAQG"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Composer Factory
|
|
3
|
+
*
|
|
4
|
+
* Creates a configured Composer instance with methods for running workflows
|
|
5
|
+
* synchronously or asynchronously, and for starting activity workers.
|
|
6
|
+
*
|
|
7
|
+
* The composer provides a unified interface that uses the same context provider
|
|
8
|
+
* for all execution modes, ensuring consistent context management.
|
|
9
|
+
*/
|
|
10
|
+
import type { Composer, ComposerConfig, SyncComposer, TemporalConfig } from "./context-provider";
|
|
11
|
+
/**
|
|
12
|
+
* Creates a Composer instance with the given configuration.
|
|
13
|
+
*
|
|
14
|
+
* The composer provides methods for:
|
|
15
|
+
* - `runSyncWorkflow`: Execute workflows synchronously (in-process)
|
|
16
|
+
* - `runAsyncWorkflow`: Execute workflows via Temporal
|
|
17
|
+
* - `runActivityWorkers`: Start Temporal activity workers
|
|
18
|
+
*
|
|
19
|
+
* All methods use the same context provider, ensuring consistent context management.
|
|
20
|
+
*
|
|
21
|
+
* @param config - Configuration including the context provider
|
|
22
|
+
* @returns A configured Composer instance
|
|
23
|
+
*
|
|
24
|
+
* @example
|
|
25
|
+
* ```typescript
|
|
26
|
+
* const composer = createComposer({
|
|
27
|
+
* contextProvider: {
|
|
28
|
+
* beforeStep: async () => ({
|
|
29
|
+
* em: await IxDbConnection.getInstance().getForkedEntityManager(),
|
|
30
|
+
* }),
|
|
31
|
+
* afterStep: async (ctx, error) => {
|
|
32
|
+
* if (!error) await ctx.em.flush();
|
|
33
|
+
* ctx.em.clear();
|
|
34
|
+
* },
|
|
35
|
+
* },
|
|
36
|
+
* });
|
|
37
|
+
*
|
|
38
|
+
* // Run sync workflow
|
|
39
|
+
* const result = await composer.runSyncWorkflow(myWorkflow, initialData);
|
|
40
|
+
*
|
|
41
|
+
* // Run async workflow
|
|
42
|
+
* const result = await composer.runAsyncWorkflow(myWorkflow, initialData);
|
|
43
|
+
*
|
|
44
|
+
* // Start activity workers (in worker script)
|
|
45
|
+
* await composer.runActivityWorkers({
|
|
46
|
+
* serverAddress: "localhost:7233",
|
|
47
|
+
* namespace: "default",
|
|
48
|
+
* taskQueues: ["standard-tasks"],
|
|
49
|
+
* maxConcurrentActivityTaskExecutions: 10,
|
|
50
|
+
* });
|
|
51
|
+
* ```
|
|
52
|
+
*/
|
|
53
|
+
export declare function createComposer<TContext>(config: ComposerConfig<TContext> & {
|
|
54
|
+
temporal: TemporalConfig;
|
|
55
|
+
}): Composer<TContext>;
|
|
56
|
+
export declare function createComposer<TContext>(config: ComposerConfig<TContext>): SyncComposer<TContext>;
|
|
57
|
+
//# sourceMappingURL=create-composer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"create-composer.d.ts","sourceRoot":"","sources":["../../src/internal/create-composer.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AASH,OAAO,KAAK,EAEV,QAAQ,EACR,cAAc,EAEd,YAAY,EACZ,cAAc,EACf,MAAM,oBAAoB,CAAC;AAM5B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyCG;AAEH,wBAAgB,cAAc,CAAC,QAAQ,EACrC,MAAM,EAAE,cAAc,CAAC,QAAQ,CAAC,GAAG;IAAE,QAAQ,EAAE,cAAc,CAAA;CAAE,GAC9D,QAAQ,CAAC,QAAQ,CAAC,CAAC;AAGtB,wBAAgB,cAAc,CAAC,QAAQ,EAAE,MAAM,EAAE,cAAc,CAAC,QAAQ,CAAC,GAAG,YAAY,CAAC,QAAQ,CAAC,CAAC"}
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Composer Factory
|
|
4
|
+
*
|
|
5
|
+
* Creates a configured Composer instance with methods for running workflows
|
|
6
|
+
* synchronously or asynchronously, and for starting activity workers.
|
|
7
|
+
*
|
|
8
|
+
* The composer provides a unified interface that uses the same context provider
|
|
9
|
+
* for all execution modes, ensuring consistent context management.
|
|
10
|
+
*/
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.createComposer = createComposer;
|
|
13
|
+
const uuid_1 = require("uuid");
|
|
14
|
+
const temporal_naming_1 = require("../temporal-naming");
|
|
15
|
+
const workflow_execution_1 = require("./async/execute/workflow-execution");
|
|
16
|
+
const activity_worker_1 = require("./async/register/activity-worker");
|
|
17
|
+
const workflow_worker_1 = require("./async/register/workflow-worker");
|
|
18
|
+
const sync_schedules_1 = require("./async/schedule/sync-schedules");
|
|
19
|
+
const dag_sync_workflow_1 = require("./dag-sync-workflow");
|
|
20
|
+
const defaults_1 = require("./defaults");
|
|
21
|
+
// Implementation
|
|
22
|
+
function createComposer(config) {
|
|
23
|
+
const { contextProvider, deepFreeze, temporal } = config;
|
|
24
|
+
// Resolve effective logger (use provided or default) before defining closures
|
|
25
|
+
// so all closures capture the resolved logger consistently.
|
|
26
|
+
const resolvedLogger = config.logger ?? defaults_1.defaultLogger;
|
|
27
|
+
// Create a type-erased version for internal use
|
|
28
|
+
const internalContextProvider = {
|
|
29
|
+
beforeStep: contextProvider.beforeStep,
|
|
30
|
+
afterStep: contextProvider.afterStep,
|
|
31
|
+
};
|
|
32
|
+
// Implementation
|
|
33
|
+
function runSyncWorkflowImpl(workflow, initialData) {
|
|
34
|
+
return (0, dag_sync_workflow_1.runSyncWorkflow)(workflow, initialData, internalContextProvider, resolvedLogger, deepFreeze);
|
|
35
|
+
}
|
|
36
|
+
// Base result (sync-only)
|
|
37
|
+
const syncComposer = {
|
|
38
|
+
contextProvider,
|
|
39
|
+
logger: resolvedLogger,
|
|
40
|
+
runSyncWorkflow: runSyncWorkflowImpl,
|
|
41
|
+
};
|
|
42
|
+
// If no temporal config, return sync-only composer
|
|
43
|
+
if (!temporal) {
|
|
44
|
+
return syncComposer;
|
|
45
|
+
}
|
|
46
|
+
// Capture after guard so TypeScript narrows the type for closures
|
|
47
|
+
const temporalConfig = temporal;
|
|
48
|
+
// Construct versioningOverride for workflow starts when buildId is set.
|
|
49
|
+
// This pins new workflows to the same deployment version as the workers,
|
|
50
|
+
// eliminating the TOCTOU gap that would require a separate setCurrentDeployment call.
|
|
51
|
+
const seriesNames = (0, temporal_naming_1.getDeploymentSeriesNames)(temporalConfig.serviceName);
|
|
52
|
+
const workflowVersioningOverride = temporalConfig.buildId
|
|
53
|
+
? {
|
|
54
|
+
pinnedTo: {
|
|
55
|
+
buildId: temporalConfig.buildId,
|
|
56
|
+
deploymentName: seriesNames.workflows,
|
|
57
|
+
},
|
|
58
|
+
}
|
|
59
|
+
: undefined;
|
|
60
|
+
// Implementation
|
|
61
|
+
function runAsyncWorkflowImpl(workflow, initialData, options) {
|
|
62
|
+
const workflowId = options?.workflowId ? options.workflowId : (0, uuid_1.v7)();
|
|
63
|
+
return (0, workflow_execution_1.executeWorkflowTemporal)(workflow, initialData, {
|
|
64
|
+
workflowId,
|
|
65
|
+
clientConfig: {
|
|
66
|
+
address: temporalConfig.serverAddress,
|
|
67
|
+
namespace: temporalConfig.namespace,
|
|
68
|
+
},
|
|
69
|
+
versioningOverride: workflowVersioningOverride,
|
|
70
|
+
awaitCheckpoint: options?.awaitCheckpoint,
|
|
71
|
+
startOnly: options?.startOnly,
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
// Implementation
|
|
75
|
+
function startAsyncWorkflowImpl(workflow, initialData) {
|
|
76
|
+
const workflowId = (0, uuid_1.v7)();
|
|
77
|
+
return (0, workflow_execution_1.startWorkflowTemporal)(workflow, initialData, {
|
|
78
|
+
workflowId,
|
|
79
|
+
clientConfig: {
|
|
80
|
+
address: temporalConfig.serverAddress,
|
|
81
|
+
namespace: temporalConfig.namespace,
|
|
82
|
+
},
|
|
83
|
+
versioningOverride: workflowVersioningOverride,
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
return {
|
|
87
|
+
...syncComposer,
|
|
88
|
+
temporal: temporalConfig,
|
|
89
|
+
runAsyncWorkflow: runAsyncWorkflowImpl,
|
|
90
|
+
startAsyncWorkflow: startAsyncWorkflowImpl,
|
|
91
|
+
async runActivityWorkers(config) {
|
|
92
|
+
return (0, activity_worker_1.runActivityWorkers)({
|
|
93
|
+
serverAddress: temporalConfig.serverAddress,
|
|
94
|
+
namespace: temporalConfig.namespace,
|
|
95
|
+
deploymentSeriesName: seriesNames.activities,
|
|
96
|
+
buildId: temporalConfig.buildId,
|
|
97
|
+
...config,
|
|
98
|
+
contextProvider: internalContextProvider,
|
|
99
|
+
logger: resolvedLogger,
|
|
100
|
+
});
|
|
101
|
+
},
|
|
102
|
+
async runWorkflowWorkers(config) {
|
|
103
|
+
return (0, workflow_worker_1.runWorkflowWorkers)({
|
|
104
|
+
serverAddress: temporalConfig.serverAddress,
|
|
105
|
+
namespace: temporalConfig.namespace,
|
|
106
|
+
deploymentSeriesName: seriesNames.workflows,
|
|
107
|
+
buildId: temporalConfig.buildId,
|
|
108
|
+
...config,
|
|
109
|
+
logger: resolvedLogger,
|
|
110
|
+
});
|
|
111
|
+
},
|
|
112
|
+
async syncSchedules(schedules, options) {
|
|
113
|
+
return (0, sync_schedules_1.syncSchedules)({
|
|
114
|
+
temporalConfig: {
|
|
115
|
+
address: temporalConfig.serverAddress,
|
|
116
|
+
namespace: temporalConfig.namespace,
|
|
117
|
+
},
|
|
118
|
+
schedules,
|
|
119
|
+
dryRun: options?.dryRun,
|
|
120
|
+
logger: resolvedLogger,
|
|
121
|
+
});
|
|
122
|
+
},
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
//# sourceMappingURL=create-composer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"create-composer.js","sourceRoot":"","sources":["../../src/internal/create-composer.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import type { AssertSerializable, Step, StrictStepReturn } from "./dag-sync-step";
|
|
2
|
+
import type { ExtractWorkflowBag, ExtractWorkflowRequiredInitial, InferWorkflowResult, SafeConfiguredKeys, Workflow } from "./dag-sync-workflow";
|
|
3
|
+
/**
|
|
4
|
+
* Computes the precise result type of a workflow from its type parameter.
|
|
5
|
+
*
|
|
6
|
+
* Given a Workflow<Bag, RequiredInitial, Config, Steps, CheckpointNames>, produces
|
|
7
|
+
* Pick<Bag, (all step provides) | RequiredInitial | ConfiguredKeys> -- the exact
|
|
8
|
+
* set of fields available after the workflow completes.
|
|
9
|
+
*/
|
|
10
|
+
export type InferWorkflowResultFromWorkflow<W> = W extends Workflow<infer B, infer R, infer C, infer S, infer _CN> ? InferWorkflowResult<B, S, R, SafeConfiguredKeys<C, B>> : never;
|
|
11
|
+
/**
|
|
12
|
+
* Runtime metadata for a FanOut node. Carries the child workflow reference,
|
|
13
|
+
* data transformation functions, and concurrency configuration.
|
|
14
|
+
*
|
|
15
|
+
* Types are erased at the metadata level (Record<string, unknown>) because
|
|
16
|
+
* the runtimes call these functions with dynamically-typed data. Full type
|
|
17
|
+
* safety is enforced at the factory level during construction.
|
|
18
|
+
*/
|
|
19
|
+
export interface FanOutMetadata {
|
|
20
|
+
childWorkflow: Workflow<any, any, any, any, any>;
|
|
21
|
+
mapInput: (bag: Record<string, unknown>) => Record<string, unknown>[];
|
|
22
|
+
aggregateResults: (results: Record<string, unknown>[]) => Record<string, unknown>;
|
|
23
|
+
concurrency: number;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* A FanOut is a Step with additional __fanOut metadata.
|
|
27
|
+
*
|
|
28
|
+
* It participates in the DAG like a regular step (has name, needs, provides)
|
|
29
|
+
* but the runtimes detect __fanOut and execute it specially: calling mapInput
|
|
30
|
+
* to produce child workflow inputs, running child workflows with concurrency
|
|
31
|
+
* control (lane-based), then calling aggregateResults to merge the child
|
|
32
|
+
* results back into the parent bag.
|
|
33
|
+
*
|
|
34
|
+
* The `run` function on a FanOut always throws -- it exists only to satisfy
|
|
35
|
+
* the Step interface for the DAG planner. Actual execution is handled by the
|
|
36
|
+
* sync and async runtimes.
|
|
37
|
+
*/
|
|
38
|
+
export type FanOut<Bag extends Record<string, any>, Needs extends readonly (keyof Bag)[], Provides extends readonly (keyof Bag)[], Name extends string = string> = Step<Bag, Needs, Provides, unknown, Name> & {
|
|
39
|
+
__fanOut: FanOutMetadata;
|
|
40
|
+
};
|
|
41
|
+
/**
|
|
42
|
+
* Runtime type guard for detecting FanOut nodes within a step array.
|
|
43
|
+
*/
|
|
44
|
+
export declare function isFanOutStep(value: Step<any, any, any, any, any>): value is FanOut<any, any, any, any>;
|
|
45
|
+
/**
|
|
46
|
+
* Factory function for creating type-safe FanOut nodes.
|
|
47
|
+
*
|
|
48
|
+
* Usage:
|
|
49
|
+
* const fo = fanOut<ParentBag>()({
|
|
50
|
+
* name: "startTldIngestions",
|
|
51
|
+
* needs: ["tlds"] as const,
|
|
52
|
+
* childWorkflow: ingestCzdsTld,
|
|
53
|
+
* mapInput: (bag) => bag.tlds.map(tld => ({ tld })),
|
|
54
|
+
* provides: ["tldResults"] as const,
|
|
55
|
+
* aggregateResults: (results) => ({ tldResults: results }),
|
|
56
|
+
* concurrency: 5,
|
|
57
|
+
* });
|
|
58
|
+
*
|
|
59
|
+
* The double-call pattern (fanOut<ParentBag>()({...})) matches the step()
|
|
60
|
+
* factory -- ParentBag is explicit, all other generics are inferred from
|
|
61
|
+
* the definition object.
|
|
62
|
+
*
|
|
63
|
+
* Generic parameters:
|
|
64
|
+
* - ParentBag (explicit): The parent workflow's bag type
|
|
65
|
+
* - Name (inferred): Literal string name of this fanOut node
|
|
66
|
+
* - Needs (inferred): Bag keys this fanOut requires as input
|
|
67
|
+
* - Provides (inferred): Bag keys this fanOut produces as output
|
|
68
|
+
* - W (inferred): The child workflow type (carries Bag, RequiredInitial, etc.)
|
|
69
|
+
*/
|
|
70
|
+
export declare function fanOut<ParentBag extends Record<string, any>>(): <const Name extends string, const Needs extends readonly (keyof ParentBag)[], const Provides extends readonly (keyof ParentBag)[], W extends Workflow<any, any, any, any, any>>(definition: {
|
|
71
|
+
name: Name;
|
|
72
|
+
needs: Needs;
|
|
73
|
+
childWorkflow: W;
|
|
74
|
+
mapInput: (bag: Pick<ParentBag, Needs[number]>) => Pick<ExtractWorkflowBag<W>, ExtractWorkflowRequiredInitial<W>>[];
|
|
75
|
+
provides: Provides;
|
|
76
|
+
aggregateResults: (results: InferWorkflowResultFromWorkflow<W>[]) => AssertSerializable<StrictStepReturn<ParentBag, Provides[number]>>;
|
|
77
|
+
concurrency?: number;
|
|
78
|
+
}) => FanOut<ParentBag, Needs, Provides, Name>;
|
|
79
|
+
//# sourceMappingURL=dag-sync-fanout.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dag-sync-fanout.d.ts","sourceRoot":"","sources":["../../src/internal/dag-sync-fanout.ts"],"names":[],"mappings":"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"}
|