@outputai/core 0.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.
- package/LICENSE +201 -0
- package/README.md +11 -0
- package/bin/healthcheck.mjs +36 -0
- package/bin/healthcheck.spec.js +90 -0
- package/bin/worker.sh +26 -0
- package/package.json +67 -0
- package/src/activity_integration/context.d.ts +27 -0
- package/src/activity_integration/context.js +17 -0
- package/src/activity_integration/context.spec.js +42 -0
- package/src/activity_integration/events.d.ts +7 -0
- package/src/activity_integration/events.js +10 -0
- package/src/activity_integration/index.d.ts +9 -0
- package/src/activity_integration/index.js +3 -0
- package/src/activity_integration/tracing.d.ts +32 -0
- package/src/activity_integration/tracing.js +37 -0
- package/src/async_storage.js +19 -0
- package/src/bus.js +3 -0
- package/src/consts.js +32 -0
- package/src/errors.d.ts +15 -0
- package/src/errors.js +14 -0
- package/src/hooks/index.d.ts +28 -0
- package/src/hooks/index.js +32 -0
- package/src/index.d.ts +49 -0
- package/src/index.js +4 -0
- package/src/interface/evaluation_result.d.ts +173 -0
- package/src/interface/evaluation_result.js +215 -0
- package/src/interface/evaluator.d.ts +70 -0
- package/src/interface/evaluator.js +34 -0
- package/src/interface/evaluator.spec.js +565 -0
- package/src/interface/index.d.ts +9 -0
- package/src/interface/index.js +26 -0
- package/src/interface/step.d.ts +138 -0
- package/src/interface/step.js +22 -0
- package/src/interface/types.d.ts +27 -0
- package/src/interface/validations/runtime.js +20 -0
- package/src/interface/validations/runtime.spec.js +29 -0
- package/src/interface/validations/schema_utils.js +8 -0
- package/src/interface/validations/schema_utils.spec.js +67 -0
- package/src/interface/validations/static.js +136 -0
- package/src/interface/validations/static.spec.js +366 -0
- package/src/interface/webhook.d.ts +84 -0
- package/src/interface/webhook.js +64 -0
- package/src/interface/webhook.spec.js +122 -0
- package/src/interface/workflow.d.ts +273 -0
- package/src/interface/workflow.js +128 -0
- package/src/interface/workflow.spec.js +467 -0
- package/src/interface/workflow_context.js +31 -0
- package/src/interface/workflow_utils.d.ts +76 -0
- package/src/interface/workflow_utils.js +50 -0
- package/src/interface/workflow_utils.spec.js +190 -0
- package/src/interface/zod_integration.spec.js +646 -0
- package/src/internal_activities/index.js +66 -0
- package/src/internal_activities/index.spec.js +102 -0
- package/src/logger.js +73 -0
- package/src/tracing/internal_interface.js +71 -0
- package/src/tracing/processors/local/index.js +111 -0
- package/src/tracing/processors/local/index.spec.js +149 -0
- package/src/tracing/processors/s3/configs.js +31 -0
- package/src/tracing/processors/s3/configs.spec.js +64 -0
- package/src/tracing/processors/s3/index.js +114 -0
- package/src/tracing/processors/s3/index.spec.js +153 -0
- package/src/tracing/processors/s3/redis_client.js +62 -0
- package/src/tracing/processors/s3/redis_client.spec.js +185 -0
- package/src/tracing/processors/s3/s3_client.js +27 -0
- package/src/tracing/processors/s3/s3_client.spec.js +62 -0
- package/src/tracing/tools/build_trace_tree.js +83 -0
- package/src/tracing/tools/build_trace_tree.spec.js +135 -0
- package/src/tracing/tools/utils.js +21 -0
- package/src/tracing/tools/utils.spec.js +14 -0
- package/src/tracing/trace_engine.js +97 -0
- package/src/tracing/trace_engine.spec.js +199 -0
- package/src/utils/index.d.ts +134 -0
- package/src/utils/index.js +2 -0
- package/src/utils/resolve_invocation_dir.js +34 -0
- package/src/utils/resolve_invocation_dir.spec.js +102 -0
- package/src/utils/utils.js +211 -0
- package/src/utils/utils.spec.js +448 -0
- package/src/worker/bundler_options.js +43 -0
- package/src/worker/catalog_workflow/catalog.js +114 -0
- package/src/worker/catalog_workflow/index.js +54 -0
- package/src/worker/catalog_workflow/index.spec.js +196 -0
- package/src/worker/catalog_workflow/workflow.js +24 -0
- package/src/worker/configs.js +49 -0
- package/src/worker/configs.spec.js +130 -0
- package/src/worker/index.js +89 -0
- package/src/worker/index.spec.js +177 -0
- package/src/worker/interceptors/activity.js +62 -0
- package/src/worker/interceptors/activity.spec.js +212 -0
- package/src/worker/interceptors/workflow.js +70 -0
- package/src/worker/interceptors/workflow.spec.js +167 -0
- package/src/worker/interceptors.js +10 -0
- package/src/worker/loader.js +151 -0
- package/src/worker/loader.spec.js +236 -0
- package/src/worker/loader_tools.js +132 -0
- package/src/worker/loader_tools.spec.js +156 -0
- package/src/worker/log_hooks.js +95 -0
- package/src/worker/log_hooks.spec.js +217 -0
- package/src/worker/sandboxed_utils.js +18 -0
- package/src/worker/shutdown.js +26 -0
- package/src/worker/shutdown.spec.js +82 -0
- package/src/worker/sinks.js +74 -0
- package/src/worker/start_catalog.js +36 -0
- package/src/worker/start_catalog.spec.js +118 -0
- package/src/worker/webpack_loaders/consts.js +9 -0
- package/src/worker/webpack_loaders/tools.js +548 -0
- package/src/worker/webpack_loaders/tools.spec.js +330 -0
- package/src/worker/webpack_loaders/workflow_rewriter/collect_target_imports.js +221 -0
- package/src/worker/webpack_loaders/workflow_rewriter/collect_target_imports.spec.js +336 -0
- package/src/worker/webpack_loaders/workflow_rewriter/index.mjs +61 -0
- package/src/worker/webpack_loaders/workflow_rewriter/index.spec.js +216 -0
- package/src/worker/webpack_loaders/workflow_rewriter/rewrite_fn_bodies.js +196 -0
- package/src/worker/webpack_loaders/workflow_rewriter/rewrite_fn_bodies.spec.js +123 -0
- package/src/worker/webpack_loaders/workflow_validator/index.mjs +205 -0
- package/src/worker/webpack_loaders/workflow_validator/index.spec.js +613 -0
|
@@ -0,0 +1,273 @@
|
|
|
1
|
+
import type { z } from 'zod';
|
|
2
|
+
import type { DeepPartial, AnyZodSchema, TemporalActivityOptions } from './types.d.ts';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* The second argument passed to the workflow's `fn` function.
|
|
6
|
+
*/
|
|
7
|
+
export type WorkflowContext<
|
|
8
|
+
InputSchema extends AnyZodSchema | undefined = undefined,
|
|
9
|
+
OutputSchema extends AnyZodSchema | undefined = undefined
|
|
10
|
+
> = {
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Functions that allow fine control over the underlying Temporal workflows
|
|
14
|
+
*/
|
|
15
|
+
control: {
|
|
16
|
+
/**
|
|
17
|
+
* Closes the current workflow execution successfully and creates a new workflow execution.
|
|
18
|
+
*
|
|
19
|
+
* The new workflow execution is in the same chain as the previous workflow, but it generates another trace file.
|
|
20
|
+
*
|
|
21
|
+
* It acts as a checkpoint when the workflow gets too long or approaches certain scaling limits.
|
|
22
|
+
*
|
|
23
|
+
* It accepts input with the same schema as the parent workflow function (`inputSchema`).
|
|
24
|
+
*
|
|
25
|
+
* Calling this function must be the last statement in the workflow, accompanied by a `return`:
|
|
26
|
+
*
|
|
27
|
+
* @example
|
|
28
|
+
* ```js
|
|
29
|
+
* return control.continueAsNew();
|
|
30
|
+
* ```
|
|
31
|
+
* Upon returning, the parent workflow execution closes without any output, and the new execution takes its place.
|
|
32
|
+
*
|
|
33
|
+
* The function's return type matches `outputSchema`; although no value is returned, the execution is replaced.
|
|
34
|
+
*
|
|
35
|
+
* @see {@link https://docs.temporal.io/develop/typescript/continue-as-new}
|
|
36
|
+
*
|
|
37
|
+
* @param input - The input for the new run. Omit when the workflow has no input schema.
|
|
38
|
+
* @returns The workflow output type for type-checking; never returns at runtime.
|
|
39
|
+
*/
|
|
40
|
+
continueAsNew: InputSchema extends AnyZodSchema ?
|
|
41
|
+
( input: z.infer<InputSchema> ) => ( OutputSchema extends AnyZodSchema ? z.infer<OutputSchema> : void ) :
|
|
42
|
+
() => ( OutputSchema extends AnyZodSchema ? z.infer<OutputSchema> : void ),
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Indicates whether the Temporal runtime suggests continuing this workflow as new.
|
|
46
|
+
*
|
|
47
|
+
* Use this to decide whether to `continueAsNew` before long waits or at loop boundaries.
|
|
48
|
+
* Prefer returning the `continueAsNew(...)` call immediately when this becomes `true`.
|
|
49
|
+
*
|
|
50
|
+
* @see {@link https://docs.temporal.io/develop/typescript/continue-as-new#how-to-test}
|
|
51
|
+
*
|
|
52
|
+
* @returns True if a continue-as-new is suggested for the current run; otherwise false.
|
|
53
|
+
*/
|
|
54
|
+
isContinueAsNewSuggested: () => boolean,
|
|
55
|
+
},
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Information about the workflow execution
|
|
59
|
+
*/
|
|
60
|
+
info: {
|
|
61
|
+
/**
|
|
62
|
+
* Internal Temporal workflow id.
|
|
63
|
+
*
|
|
64
|
+
* @see {@link https://docs.temporal.io/workflow-execution/workflowid-runid#workflow-id}
|
|
65
|
+
*/
|
|
66
|
+
workflowId: string
|
|
67
|
+
}
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Configuration for workflow invocations.
|
|
72
|
+
*
|
|
73
|
+
* Allows overriding Temporal Activity options for this workflow.
|
|
74
|
+
*/
|
|
75
|
+
export type WorkflowInvocationConfiguration<Context extends WorkflowContext = WorkflowContext> = {
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Temporal activity options for this invocation (overrides the workflow's default activity options).
|
|
79
|
+
*/
|
|
80
|
+
options?: TemporalActivityOptions,
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Configures whether this workflow runs detached.
|
|
84
|
+
* Detached workflows called without explicitly awaiting the result are "fire-and-forget" and may outlive the parent.
|
|
85
|
+
*/
|
|
86
|
+
detached?: boolean,
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Allow to overwrite properties of the "context" of workflows when called in tests environments.
|
|
90
|
+
*/
|
|
91
|
+
context?: DeepPartial<Context>
|
|
92
|
+
};
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Options for a workflow.
|
|
96
|
+
*/
|
|
97
|
+
export type WorkflowOptions = {
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* Temporal activity options for activities invoked by this workflow.
|
|
101
|
+
*/
|
|
102
|
+
activityOptions?: TemporalActivityOptions,
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* When `true`, disables trace file generation for this workflow. Only has effect when tracing is enabled.
|
|
106
|
+
*/
|
|
107
|
+
disableTrace?: boolean
|
|
108
|
+
};
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* The handler function of a workflow.
|
|
112
|
+
*
|
|
113
|
+
* @param input - The workflow input; it matches the schema defined by `inputSchema`.
|
|
114
|
+
* @param context - A context object with tools and information.
|
|
115
|
+
*
|
|
116
|
+
* @returns A value matching the schema defined by `outputSchema`.
|
|
117
|
+
*/
|
|
118
|
+
export type WorkflowFunction<
|
|
119
|
+
InputSchema extends AnyZodSchema | undefined = undefined,
|
|
120
|
+
OutputSchema extends AnyZodSchema | undefined = undefined
|
|
121
|
+
> = InputSchema extends AnyZodSchema ?
|
|
122
|
+
( input: z.infer<InputSchema>, context: WorkflowContext<InputSchema, OutputSchema> ) =>
|
|
123
|
+
Promise<OutputSchema extends AnyZodSchema ? z.infer<OutputSchema> : void> :
|
|
124
|
+
( input?: undefined | null, context: WorkflowContext<InputSchema, OutputSchema> ) =>
|
|
125
|
+
Promise<OutputSchema extends AnyZodSchema ? z.infer<OutputSchema> : void>;
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* A wrapper around the user defined `fn` handler function.
|
|
129
|
+
*
|
|
130
|
+
* It accepts the same input and returns the same value, calling the user function inside.
|
|
131
|
+
*
|
|
132
|
+
* The second argument is a WorkflowInvocationConfiguration object, allowing workflows configuration overwrite.
|
|
133
|
+
*
|
|
134
|
+
* It adds input and output validation based on the `inputSchema`, `outputSchema`.
|
|
135
|
+
*
|
|
136
|
+
* @param input - The workflow input; it matches the schema defined by `inputSchema`.
|
|
137
|
+
* @param config - Additional configuration for the invocation.
|
|
138
|
+
* @returns A value matching the schema defined by `outputSchema`.
|
|
139
|
+
*/
|
|
140
|
+
export type WorkflowFunctionWrapper<WorkflowFunction> =
|
|
141
|
+
[Parameters<WorkflowFunction>[0]] extends [undefined | null] ?
|
|
142
|
+
( input?: undefined | null, config?: WorkflowInvocationConfiguration<Parameters<WorkflowFunction>[1]> ) =>
|
|
143
|
+
ReturnType<WorkflowFunction> :
|
|
144
|
+
( input: Parameters<WorkflowFunction>[0], config?: WorkflowInvocationConfiguration<Parameters<WorkflowFunction>[1]> ) =>
|
|
145
|
+
ReturnType<WorkflowFunction>;
|
|
146
|
+
|
|
147
|
+
/**
|
|
148
|
+
* Creates a workflow.
|
|
149
|
+
*
|
|
150
|
+
* A workflow is an orchestration of one or more steps. It is translated to a Temporal Workflow.
|
|
151
|
+
*
|
|
152
|
+
* The workflow logic is defined in the `fn` handler function.
|
|
153
|
+
*
|
|
154
|
+
* The schema of the input that the function receives as the first argument is defined by `inputSchema`.
|
|
155
|
+
*
|
|
156
|
+
* The output of the `fn` handler must match `outputSchema`; otherwise, a validation error is raised.
|
|
157
|
+
*
|
|
158
|
+
* @remarks
|
|
159
|
+
* - Workflows should respect the same limitations as Temporal workflows.
|
|
160
|
+
* - Workflows can invoke steps or evaluators and cannot perform I/O directly.
|
|
161
|
+
* - The workflow `name` needs to be unique across all workflows in the project.
|
|
162
|
+
*
|
|
163
|
+
* @example
|
|
164
|
+
* ```
|
|
165
|
+
* import { step } from './my_steps.ts';
|
|
166
|
+
*
|
|
167
|
+
* workflow( {
|
|
168
|
+
* name: 'main',
|
|
169
|
+
* description: 'A generic workflow',
|
|
170
|
+
* inputSchema: z.object( {
|
|
171
|
+
* value: z.number()
|
|
172
|
+
* } ),
|
|
173
|
+
* outputSchema: z.string(),
|
|
174
|
+
* fn: async input => {
|
|
175
|
+
* const result = await step( input.value );
|
|
176
|
+
* return result as string;
|
|
177
|
+
* }
|
|
178
|
+
* } )
|
|
179
|
+
* ```
|
|
180
|
+
*
|
|
181
|
+
* @example Workflow without outputSchema
|
|
182
|
+
* ```
|
|
183
|
+
* import { step } from './my_steps.ts';
|
|
184
|
+
*
|
|
185
|
+
* workflow( {
|
|
186
|
+
* name: 'main',
|
|
187
|
+
* description: 'A generic workflow',
|
|
188
|
+
* inputSchema: z.object( {
|
|
189
|
+
* value: z.number()
|
|
190
|
+
* } ),
|
|
191
|
+
* fn: async input => {
|
|
192
|
+
* await step( input.value );
|
|
193
|
+
* }
|
|
194
|
+
* } )
|
|
195
|
+
* ```
|
|
196
|
+
*
|
|
197
|
+
* @example Workflow without inputSchema
|
|
198
|
+
* ```
|
|
199
|
+
* import { step } from './my_steps.ts';
|
|
200
|
+
*
|
|
201
|
+
* workflow( {
|
|
202
|
+
* name: 'main',
|
|
203
|
+
* description: 'A generic workflow',
|
|
204
|
+
* outputSchema: z.string(),
|
|
205
|
+
* fn: async () => {
|
|
206
|
+
* const result = await step();
|
|
207
|
+
* return result as string;
|
|
208
|
+
* }
|
|
209
|
+
* } )
|
|
210
|
+
* ```
|
|
211
|
+
*
|
|
212
|
+
* @example Workflow without inputSchema and outputSchema
|
|
213
|
+
* ```
|
|
214
|
+
* import { step } from './my_steps.ts';
|
|
215
|
+
*
|
|
216
|
+
* workflow( {
|
|
217
|
+
* name: 'main',
|
|
218
|
+
* description: 'A generic workflow',
|
|
219
|
+
* fn: async () => {
|
|
220
|
+
* await step();
|
|
221
|
+
* }
|
|
222
|
+
* } )
|
|
223
|
+
* ```
|
|
224
|
+
*
|
|
225
|
+
* @example Using continueAsNew
|
|
226
|
+
* The function `continueAsNew` (same as Temporal) can be used to create a new workflow with the same ID and pass different input.
|
|
227
|
+
*
|
|
228
|
+
* ```
|
|
229
|
+
* import { step } from './my_steps.ts';
|
|
230
|
+
*
|
|
231
|
+
* workflow( {
|
|
232
|
+
* name: 'main',
|
|
233
|
+
* description: 'A generic workflow',
|
|
234
|
+
* inputSchema: z.object( {
|
|
235
|
+
* value: z.number()
|
|
236
|
+
* } ),
|
|
237
|
+
* outputSchema: z.string(),
|
|
238
|
+
* fn: async ( input, context ) => {
|
|
239
|
+
* const result = await step( input.value );
|
|
240
|
+
* if ( context.control.isContinueAsNewSuggested() ) {
|
|
241
|
+
* return context.control.continueAsNew( input );
|
|
242
|
+
* }
|
|
243
|
+
*
|
|
244
|
+
* return result as string;
|
|
245
|
+
* }
|
|
246
|
+
* } )
|
|
247
|
+
* ```
|
|
248
|
+
* @typeParam InputSchema - Zod schema of the fn's input.
|
|
249
|
+
* @typeParam OutputSchema - Zod schema of the fn's return.
|
|
250
|
+
*
|
|
251
|
+
* @throws {@link ValidationError}
|
|
252
|
+
* @throws {@link FatalError}
|
|
253
|
+
*
|
|
254
|
+
* @param params - Workflow parameters
|
|
255
|
+
* @param params.name - Human-readable workflow name (must start with a letter or underscore, followed by letters, numbers, or underscores).
|
|
256
|
+
* @param params.description - Description of the workflow
|
|
257
|
+
* @param params.inputSchema - Zod schema for workflow input
|
|
258
|
+
* @param params.outputSchema - Zod schema for workflow output
|
|
259
|
+
* @param params.fn - A function containing the workflow code
|
|
260
|
+
* @param params.options - Optional workflow options.
|
|
261
|
+
* @returns The same handler function set at `fn` with a different signature
|
|
262
|
+
*/
|
|
263
|
+
export declare function workflow<
|
|
264
|
+
InputSchema extends AnyZodSchema | undefined = undefined,
|
|
265
|
+
OutputSchema extends AnyZodSchema | undefined = undefined
|
|
266
|
+
>( params: {
|
|
267
|
+
name: string;
|
|
268
|
+
description?: string;
|
|
269
|
+
inputSchema?: InputSchema;
|
|
270
|
+
outputSchema?: OutputSchema;
|
|
271
|
+
fn: WorkflowFunction<InputSchema, OutputSchema>;
|
|
272
|
+
options?: WorkflowOptions;
|
|
273
|
+
} ): WorkflowFunctionWrapper<WorkflowFunction<InputSchema, OutputSchema>>;
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
// THIS RUNS IN THE TEMPORAL'S SANDBOX ENVIRONMENT
|
|
2
|
+
import { proxyActivities, inWorkflowContext, executeChild, workflowInfo, uuid4, ParentClosePolicy, continueAsNew } from '@temporalio/workflow';
|
|
3
|
+
import { validateWorkflow } from './validations/static.js';
|
|
4
|
+
import { validateWithSchema } from './validations/runtime.js';
|
|
5
|
+
import { SHARED_STEP_PREFIX, ACTIVITY_GET_TRACE_DESTINATIONS, METADATA_ACCESS_SYMBOL } from '#consts';
|
|
6
|
+
import { deepMerge, setMetadata, toUrlSafeBase64 } from '#utils';
|
|
7
|
+
import { FatalError, ValidationError } from '#errors';
|
|
8
|
+
import { Context } from './workflow_context.js';
|
|
9
|
+
|
|
10
|
+
const defaultOptions = {
|
|
11
|
+
activityOptions: {
|
|
12
|
+
startToCloseTimeout: '20m',
|
|
13
|
+
heartbeatTimeout: '5m',
|
|
14
|
+
retry: {
|
|
15
|
+
initialInterval: '10s',
|
|
16
|
+
backoffCoefficient: 2.0,
|
|
17
|
+
maximumInterval: '2m',
|
|
18
|
+
maximumAttempts: 3,
|
|
19
|
+
nonRetryableErrorTypes: [ ValidationError.name, FatalError.name ]
|
|
20
|
+
}
|
|
21
|
+
},
|
|
22
|
+
disableTrace: false
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
export function workflow( { name, description, inputSchema, outputSchema, fn, options = {} } ) {
|
|
26
|
+
validateWorkflow( { name, description, inputSchema, outputSchema, fn, options } );
|
|
27
|
+
|
|
28
|
+
const { disableTrace, activityOptions } = deepMerge( defaultOptions, options );
|
|
29
|
+
const steps = proxyActivities( activityOptions );
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Wraps the `fn` function of the workflow
|
|
33
|
+
*
|
|
34
|
+
* @param {unknown} input - The input, must match the inputSchema
|
|
35
|
+
* @param {object} extra - Workflow configurations (received directly only in unit tests)
|
|
36
|
+
* @returns {unknown} The result, will match the outputSchema
|
|
37
|
+
*/
|
|
38
|
+
const wrapper = async ( input, extra = {} ) => {
|
|
39
|
+
// this returns a plain function, for example, in unit tests
|
|
40
|
+
if ( !inWorkflowContext() ) {
|
|
41
|
+
validateWithSchema( inputSchema, input, `Workflow ${name} input` );
|
|
42
|
+
const context = Context.build( { workflowId: 'test-workflow', continueAsNew: async () => {}, isContinueAsNewSuggested: () => false } );
|
|
43
|
+
const output = await fn( input, deepMerge( context, extra.context ) );
|
|
44
|
+
validateWithSchema( outputSchema, output, `Workflow ${name} output` );
|
|
45
|
+
return output;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
const { workflowId, memo, startTime } = workflowInfo();
|
|
49
|
+
|
|
50
|
+
const context = Context.build( { workflowId, continueAsNew, isContinueAsNewSuggested: () => workflowInfo().continueAsNewSuggested } );
|
|
51
|
+
|
|
52
|
+
// Root workflows will not have the execution context yet, since it is set here.
|
|
53
|
+
const isRoot = !memo.executionContext;
|
|
54
|
+
|
|
55
|
+
/* Creates the execution context object or preserve if it already exists:
|
|
56
|
+
It will always contain the information about the root workflow
|
|
57
|
+
It will be used to as context for tracing (connecting events) */
|
|
58
|
+
const executionContext = memo.executionContext ?? {
|
|
59
|
+
workflowId,
|
|
60
|
+
workflowName: name,
|
|
61
|
+
disableTrace,
|
|
62
|
+
startTime: startTime.getTime()
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
Object.assign( memo, {
|
|
66
|
+
executionContext,
|
|
67
|
+
activityOptions: memo.activityOptions ?? activityOptions // Also preserve the original activity options
|
|
68
|
+
} );
|
|
69
|
+
|
|
70
|
+
// Run the internal activity to retrieve the workflow trace destinations (only for root workflows, not nested)
|
|
71
|
+
const traceDestinations = isRoot ? ( await steps[ACTIVITY_GET_TRACE_DESTINATIONS]( executionContext ) ) : null;
|
|
72
|
+
const traceObject = { trace: { destinations: traceDestinations } };
|
|
73
|
+
|
|
74
|
+
try {
|
|
75
|
+
// validation comes after setting memo to have that info already set for interceptor even if validations fail
|
|
76
|
+
validateWithSchema( inputSchema, input, `Workflow ${name} input` );
|
|
77
|
+
|
|
78
|
+
const dispatchers = {
|
|
79
|
+
invokeStep: async ( stepName, input, options ) => steps[`${name}#${stepName}`]( input, options ),
|
|
80
|
+
invokeSharedStep: async ( stepName, input, options ) => steps[`${SHARED_STEP_PREFIX}#${stepName}`]( input, options ),
|
|
81
|
+
invokeEvaluator: async ( evaluatorName, input, options ) => steps[`${name}#${evaluatorName}`]( input, options ),
|
|
82
|
+
invokeSharedEvaluator: async ( evaluatorName, input, options ) => steps[`${SHARED_STEP_PREFIX}#${evaluatorName}`]( input, options ),
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Start a child workflow
|
|
86
|
+
*
|
|
87
|
+
* @param {string} childName
|
|
88
|
+
* @param {unknown} input
|
|
89
|
+
* @param {object} extra
|
|
90
|
+
* @param {boolean} extra.detached
|
|
91
|
+
* @param {import('@temporalio/workflow').ActivityOptions} extra.options
|
|
92
|
+
* @returns {Promise<unknown>}
|
|
93
|
+
*/
|
|
94
|
+
startWorkflow: async ( childName, input, extra = {} ) =>
|
|
95
|
+
executeChild( childName, {
|
|
96
|
+
args: input ? [ input ] : [],
|
|
97
|
+
workflowId: `${workflowId}-${toUrlSafeBase64( uuid4() )}`,
|
|
98
|
+
parentClosePolicy: ParentClosePolicy[extra?.detached ? 'ABANDON' : 'TERMINATE'],
|
|
99
|
+
memo: {
|
|
100
|
+
executionContext,
|
|
101
|
+
parentId: workflowId,
|
|
102
|
+
...( extra?.options?.activityOptions && { activityOptions: deepMerge( activityOptions, extra.options.activityOptions ) } )
|
|
103
|
+
}
|
|
104
|
+
} )
|
|
105
|
+
};
|
|
106
|
+
|
|
107
|
+
const output = await fn.call( dispatchers, input, context );
|
|
108
|
+
|
|
109
|
+
validateWithSchema( outputSchema, output, `Workflow ${name} output` );
|
|
110
|
+
|
|
111
|
+
if ( isRoot ) {
|
|
112
|
+
// Append the trace info to the result of the workflow
|
|
113
|
+
return { output, ...traceObject };
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
return output;
|
|
117
|
+
} catch ( e ) {
|
|
118
|
+
// Append the trace info as metadata of the error, so it can be read by the interceptor.
|
|
119
|
+
if ( isRoot ) {
|
|
120
|
+
e[METADATA_ACCESS_SYMBOL] = { ...( e[METADATA_ACCESS_SYMBOL] ?? {} ), ...traceObject };
|
|
121
|
+
}
|
|
122
|
+
throw e;
|
|
123
|
+
}
|
|
124
|
+
};
|
|
125
|
+
|
|
126
|
+
setMetadata( wrapper, { name, description, inputSchema, outputSchema } );
|
|
127
|
+
return wrapper;
|
|
128
|
+
};
|