@temporal-contract/worker 0.0.7 → 0.2.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/dist/workflow.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import { a as ChildWorkflowNotFoundError, c as SignalInputValidationError, d as WorkflowInputValidationError, f as WorkflowOutputValidationError, i as ChildWorkflowError, l as UpdateInputValidationError, n as ActivityInputValidationError, o as QueryInputValidationError, r as ActivityOutputValidationError, s as QueryOutputValidationError, u as UpdateOutputValidationError } from "./errors-BqVTpfcf.mjs";
1
+ import { a as ChildWorkflowNotFoundError, c as SignalInputValidationError, d as WorkflowInputValidationError, f as WorkflowOutputValidationError, i as ChildWorkflowError, l as UpdateInputValidationError, n as ActivityInputValidationError, o as QueryInputValidationError, r as ActivityOutputValidationError, s as QueryOutputValidationError, u as UpdateOutputValidationError } from "./errors-Di6Ja4Rt.mjs";
2
2
  import { Future, Result } from "@temporal-contract/boxed";
3
3
  import { defineQuery, defineSignal, defineUpdate, executeChild, proxyActivities, setHandler, startChild, workflowInfo } from "@temporalio/workflow";
4
4
 
@@ -17,53 +17,53 @@ import { defineQuery, defineSignal, defineUpdate, executeChild, proxyActivities,
17
17
  * @example
18
18
  * ```ts
19
19
  * // workflows/processOrder.ts
20
- * import { declareWorkflow } from '@temporal-contract/worker';
20
+ * import { declareWorkflow } from '@temporal-contract/worker/workflow';
21
21
  * import myContract from '../contract';
22
22
  *
23
23
  * export const processOrder = declareWorkflow({
24
24
  * workflowName: 'processOrder',
25
25
  * contract: myContract,
26
- * implementation: async (context, orderId, customerId) => {
26
+ * activityOptions: {
27
+ * startToCloseTimeout: '1 minute',
28
+ * },
29
+ * implementation: async (context, args) => {
27
30
  * // context.activities: typed activities (workflow + global)
28
31
  * // context.info: WorkflowInfo
29
32
  *
30
- * const inventory = await context.activities.validateInventory(orderId);
33
+ * const inventory = await context.activities.validateInventory({
34
+ * orderId: args.orderId,
35
+ * });
31
36
  *
32
37
  * if (!inventory.available) {
33
- * throw new Error('Out of stock');
38
+ * return { orderId: args.orderId, status: 'out_of_stock' };
34
39
  * }
35
40
  *
36
- * const payment = await context.activities.chargePayment(customerId, 100);
37
- *
38
- * // Global activity
39
- * await context.activities.sendEmail(
40
- * customerId,
41
- * 'Order processed',
42
- * 'Your order has been processed'
43
- * );
41
+ * const payment = await context.activities.chargePayment({
42
+ * customerId: args.customerId,
43
+ * amount: 100,
44
+ * });
44
45
  *
45
46
  * return {
46
- * orderId,
47
+ * orderId: args.orderId,
47
48
  * status: payment.success ? 'success' : 'failed',
48
49
  * transactionId: payment.transactionId,
49
50
  * };
50
51
  * },
51
- * activityOptions: {
52
- * startToCloseTimeout: '1 minute',
53
- * },
54
52
  * });
55
53
  * ```
56
54
  *
57
55
  * Then in your worker setup:
58
56
  * ```ts
59
57
  * // worker.ts
60
- * import { Worker } from '@temporalio/worker';
61
- * import { activitiesHandler } from './activities';
58
+ * import { createWorker } from '@temporal-contract/worker/worker';
59
+ * import { activities } from './activities';
60
+ * import myContract from './contract';
62
61
  *
63
- * const worker = await Worker.create({
64
- * workflowsPath: require.resolve('./workflows'), // Imports processOrder
65
- * activities: activitiesHandler.activities,
66
- * taskQueue: activitiesHandler.contract.taskQueue,
62
+ * const worker = await createWorker({
63
+ * contract: myContract,
64
+ * connection,
65
+ * workflowsPath: workflowsPathFromURL(import.meta.url, './workflows.js'),
66
+ * activities,
67
67
  * });
68
68
  * ```
69
69
  */
@@ -76,20 +76,20 @@ function declareWorkflow({ workflowName, contract, implementation, activityOptio
76
76
  const validatedInput = inputResult.value;
77
77
  let contextActivities = {};
78
78
  if (definition.activities || contract.activities) contextActivities = createValidatedActivities(proxyActivities(activityOptions), definition.activities, contract.activities);
79
- async function validateChildWorkflowOutput(childDefinition, result$1, childWorkflowName) {
80
- const outputResult$1 = await childDefinition.output["~standard"].validate(result$1);
81
- if (outputResult$1.issues) return Result.Error(new ChildWorkflowError(`Child workflow "${childWorkflowName}" output validation failed: ${outputResult$1.issues.map((i) => i.message).join("; ")}`));
82
- return Result.Ok(outputResult$1.value);
79
+ async function validateChildWorkflowOutput(childDefinition, result, childWorkflowName) {
80
+ const outputResult = await childDefinition.output["~standard"].validate(result);
81
+ if (outputResult.issues) return Result.Error(new ChildWorkflowError(`Child workflow "${childWorkflowName}" output validation failed: ${outputResult.issues.map((i) => i.message).join("; ")}`));
82
+ return Result.Ok(outputResult.value);
83
83
  }
84
- async function getAndValidateChildWorkflow(childContract, childWorkflowName, args$1) {
84
+ async function getAndValidateChildWorkflow(childContract, childWorkflowName, args) {
85
85
  const childDefinition = childContract.workflows[childWorkflowName];
86
86
  if (!childDefinition) return Result.Error(new ChildWorkflowNotFoundError(String(childWorkflowName), Object.keys(childContract.workflows)));
87
- const inputResult$1 = await childDefinition.input["~standard"].validate(args$1);
88
- if (inputResult$1.issues) return Result.Error(new ChildWorkflowError(`Child workflow "${String(childWorkflowName)}" input validation failed: ${inputResult$1.issues.map((i) => i.message).join("; ")}`));
89
- const validatedInput$1 = inputResult$1.value;
87
+ const inputResult = await childDefinition.input["~standard"].validate(args);
88
+ if (inputResult.issues) return Result.Error(new ChildWorkflowError(`Child workflow "${String(childWorkflowName)}" input validation failed: ${inputResult.issues.map((i) => i.message).join("; ")}`));
89
+ const validatedInput = inputResult.value;
90
90
  return Result.Ok({
91
91
  definition: childDefinition,
92
- validatedInput: validatedInput$1,
92
+ validatedInput,
93
93
  taskQueue: childContract.taskQueue
94
94
  });
95
95
  }
@@ -97,107 +97,92 @@ function declareWorkflow({ workflowName, contract, implementation, activityOptio
97
97
  return {
98
98
  workflowId: handle.workflowId,
99
99
  result: () => {
100
- return Future.make((resolve) => {
101
- (async () => {
102
- try {
103
- resolve(await validateChildWorkflowOutput(childDefinition, await handle.result(), childWorkflowName));
104
- } catch (error) {
105
- resolve(Result.Error(new ChildWorkflowError(`Child workflow execution failed: ${error instanceof Error ? error.message : String(error)}`, error)));
106
- }
107
- })();
100
+ return Future.fromAsync(async () => {
101
+ try {
102
+ return validateChildWorkflowOutput(childDefinition, await handle.result(), childWorkflowName);
103
+ } catch (error) {
104
+ return Result.Error(new ChildWorkflowError(`Child workflow execution failed: ${error instanceof Error ? error.message : String(error)}`, error));
105
+ }
108
106
  });
109
107
  }
110
108
  };
111
109
  }
112
110
  function createStartChildWorkflow(childContract, childWorkflowName, options) {
113
- return Future.make((resolve) => {
114
- (async () => {
115
- const validationResult = await getAndValidateChildWorkflow(childContract, childWorkflowName, options.args);
116
- if (validationResult.isError()) {
117
- resolve(Result.Error(validationResult.error));
118
- return;
119
- }
120
- const { definition: childDefinition, validatedInput: validatedInput$1, taskQueue } = validationResult.value;
121
- try {
122
- const { args: _args, ...temporalOptions } = options;
123
- const typedHandle = createTypedChildHandle(await startChild(childWorkflowName, {
124
- ...temporalOptions,
125
- taskQueue,
126
- args: [validatedInput$1]
127
- }), childDefinition, String(childWorkflowName));
128
- resolve(Result.Ok(typedHandle));
129
- } catch (error) {
130
- resolve(Result.Error(new ChildWorkflowError(`Failed to start child workflow: ${error instanceof Error ? error.message : String(error)}`, error)));
131
- }
132
- })();
111
+ return Future.fromAsync(async () => {
112
+ const validationResult = await getAndValidateChildWorkflow(childContract, childWorkflowName, options.args);
113
+ if (validationResult.isError()) return Result.Error(validationResult.error);
114
+ const { definition: childDefinition, validatedInput, taskQueue } = validationResult.value;
115
+ try {
116
+ const { args: _args, ...temporalOptions } = options;
117
+ const typedHandle = createTypedChildHandle(await startChild(childWorkflowName, {
118
+ ...temporalOptions,
119
+ taskQueue,
120
+ args: [validatedInput]
121
+ }), childDefinition, String(childWorkflowName));
122
+ return Result.Ok(typedHandle);
123
+ } catch (error) {
124
+ return Result.Error(new ChildWorkflowError(`Failed to start child workflow: ${error instanceof Error ? error.message : String(error)}`, error));
125
+ }
133
126
  });
134
127
  }
135
128
  function createExecuteChildWorkflow(childContract, childWorkflowName, options) {
136
- return Future.make((resolve) => {
137
- (async () => {
138
- const validationResult = await getAndValidateChildWorkflow(childContract, childWorkflowName, options.args);
139
- if (validationResult.isError()) {
140
- resolve(Result.Error(validationResult.error));
141
- return;
142
- }
143
- const { definition: childDefinition, validatedInput: validatedInput$1, taskQueue } = validationResult.value;
144
- try {
145
- const { args: _args, ...temporalOptions } = options;
146
- const outputValidationResult = await validateChildWorkflowOutput(childDefinition, await executeChild(childWorkflowName, {
147
- ...temporalOptions,
148
- taskQueue,
149
- args: [validatedInput$1]
150
- }), String(childWorkflowName));
151
- if (outputValidationResult.isError()) {
152
- resolve(Result.Error(outputValidationResult.error));
153
- return;
154
- }
155
- resolve(Result.Ok(outputValidationResult.value));
156
- } catch (error) {
157
- resolve(Result.Error(new ChildWorkflowError(`Failed to execute child workflow: ${error instanceof Error ? error.message : String(error)}`, error)));
158
- }
159
- })();
129
+ return Future.fromAsync(async () => {
130
+ const validationResult = await getAndValidateChildWorkflow(childContract, childWorkflowName, options.args);
131
+ if (validationResult.isError()) return Result.Error(validationResult.error);
132
+ const { definition: childDefinition, validatedInput, taskQueue } = validationResult.value;
133
+ try {
134
+ const { args: _args, ...temporalOptions } = options;
135
+ const outputValidationResult = await validateChildWorkflowOutput(childDefinition, await executeChild(childWorkflowName, {
136
+ ...temporalOptions,
137
+ taskQueue,
138
+ args: [validatedInput]
139
+ }), String(childWorkflowName));
140
+ if (outputValidationResult.isError()) return Result.Error(outputValidationResult.error);
141
+ return Result.Ok(outputValidationResult.value);
142
+ } catch (error) {
143
+ return Result.Error(new ChildWorkflowError(`Failed to execute child workflow: ${error instanceof Error ? error.message : String(error)}`, error));
144
+ }
160
145
  });
161
146
  }
162
147
  function createDefineSignal(signalName, handler) {
163
148
  if (!definition.signals) throw new Error(`Signal "${String(signalName)}" cannot be defined: workflow "${String(workflowName)}" has no signals in its contract`);
164
149
  const signalDef = definition.signals[signalName];
165
150
  if (!signalDef) throw new Error(`Signal "${String(signalName)}" not found in workflow "${String(workflowName)}" contract`);
166
- setHandler(defineSignal(signalName), async (...args$1) => {
167
- const input$1 = args$1.length === 1 ? args$1[0] : args$1;
168
- const inputResult$1 = await signalDef.input["~standard"].validate(input$1);
169
- if (inputResult$1.issues) throw new SignalInputValidationError(signalName, inputResult$1.issues);
170
- await handler(inputResult$1.value);
151
+ setHandler(defineSignal(signalName), async (...args) => {
152
+ const input = args.length === 1 ? args[0] : args;
153
+ const inputResult = await signalDef.input["~standard"].validate(input);
154
+ if (inputResult.issues) throw new SignalInputValidationError(signalName, inputResult.issues);
155
+ await handler(inputResult.value);
171
156
  });
172
157
  }
173
158
  function createDefineQuery(queryName, handler) {
174
159
  if (!definition.queries) throw new Error(`Query "${String(queryName)}" cannot be defined: workflow "${String(workflowName)}" has no queries in its contract`);
175
160
  const queryDef = definition.queries[queryName];
176
161
  if (!queryDef) throw new Error(`Query "${String(queryName)}" not found in workflow "${String(workflowName)}" contract`);
177
- setHandler(defineQuery(queryName), (...args$1) => {
178
- const input$1 = args$1.length === 1 ? args$1[0] : args$1;
179
- const inputResult$1 = queryDef.input["~standard"].validate(input$1);
180
- if (inputResult$1 instanceof Promise) throw new Error(`Query "${String(queryName)}" validation must be synchronous. Use a schema library that supports synchronous validation for queries.`);
181
- if (inputResult$1.issues) throw new QueryInputValidationError(queryName, inputResult$1.issues);
182
- const result$1 = handler(inputResult$1.value);
183
- const outputResult$1 = queryDef.output["~standard"].validate(result$1);
184
- if (outputResult$1 instanceof Promise) throw new Error(`Query "${String(queryName)}" output validation must be synchronous. Use a schema library that supports synchronous validation for queries.`);
185
- if (outputResult$1.issues) throw new QueryOutputValidationError(queryName, outputResult$1.issues);
186
- return outputResult$1.value;
162
+ setHandler(defineQuery(queryName), (...args) => {
163
+ const input = args.length === 1 ? args[0] : args;
164
+ const inputResult = queryDef.input["~standard"].validate(input);
165
+ if (inputResult instanceof Promise) throw new Error(`Query "${String(queryName)}" validation must be synchronous. Use a schema library that supports synchronous validation for queries.`);
166
+ if (inputResult.issues) throw new QueryInputValidationError(queryName, inputResult.issues);
167
+ const result = handler(inputResult.value);
168
+ const outputResult = queryDef.output["~standard"].validate(result);
169
+ if (outputResult instanceof Promise) throw new Error(`Query "${String(queryName)}" output validation must be synchronous. Use a schema library that supports synchronous validation for queries.`);
170
+ if (outputResult.issues) throw new QueryOutputValidationError(queryName, outputResult.issues);
171
+ return outputResult.value;
187
172
  });
188
173
  }
189
174
  function createDefineUpdate(updateName, handler) {
190
175
  if (!definition.updates) throw new Error(`Update "${String(updateName)}" cannot be defined: workflow "${String(workflowName)}" has no updates in its contract`);
191
176
  const updateDef = definition.updates[updateName];
192
177
  if (!updateDef) throw new Error(`Update "${String(updateName)}" not found in workflow "${String(workflowName)}" contract`);
193
- setHandler(defineUpdate(updateName), async (...args$1) => {
194
- const input$1 = args$1.length === 1 ? args$1[0] : args$1;
195
- const inputResult$1 = await updateDef.input["~standard"].validate(input$1);
196
- if (inputResult$1.issues) throw new UpdateInputValidationError(updateName, inputResult$1.issues);
197
- const result$1 = await handler(inputResult$1.value);
198
- const outputResult$1 = await updateDef.output["~standard"].validate(result$1);
199
- if (outputResult$1.issues) throw new UpdateOutputValidationError(updateName, outputResult$1.issues);
200
- return outputResult$1.value;
178
+ setHandler(defineUpdate(updateName), async (...args) => {
179
+ const input = args.length === 1 ? args[0] : args;
180
+ const inputResult = await updateDef.input["~standard"].validate(input);
181
+ if (inputResult.issues) throw new UpdateInputValidationError(updateName, inputResult.issues);
182
+ const result = await handler(inputResult.value);
183
+ const outputResult = await updateDef.output["~standard"].validate(result);
184
+ if (outputResult.issues) throw new UpdateOutputValidationError(updateName, outputResult.issues);
185
+ return outputResult.value;
201
186
  });
202
187
  }
203
188
  const result = await implementation({
@@ -242,4 +227,5 @@ function createValidatedActivities(rawActivities, workflowActivitiesDefinition,
242
227
  }
243
228
 
244
229
  //#endregion
245
- export { ActivityInputValidationError, ActivityOutputValidationError, ChildWorkflowError, ChildWorkflowNotFoundError, QueryInputValidationError, QueryOutputValidationError, SignalInputValidationError, UpdateInputValidationError, UpdateOutputValidationError, WorkflowInputValidationError, WorkflowOutputValidationError, declareWorkflow };
230
+ export { ActivityInputValidationError, ActivityOutputValidationError, ChildWorkflowError, ChildWorkflowNotFoundError, QueryInputValidationError, QueryOutputValidationError, SignalInputValidationError, UpdateInputValidationError, UpdateOutputValidationError, WorkflowInputValidationError, WorkflowOutputValidationError, declareWorkflow };
231
+ //# sourceMappingURL=workflow.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"workflow.mjs","names":[],"sources":["../src/workflow.ts"],"sourcesContent":["// Entry point for workflows\nimport {\n ActivityDefinition,\n ContractDefinition,\n QueryDefinition,\n SignalDefinition,\n UpdateDefinition,\n WorkflowDefinition,\n} from \"@temporal-contract/contract\";\nimport {\n ActivityInputValidationError,\n ActivityOutputValidationError,\n ChildWorkflowError,\n ChildWorkflowNotFoundError,\n QueryInputValidationError,\n QueryOutputValidationError,\n SignalInputValidationError,\n UpdateInputValidationError,\n UpdateOutputValidationError,\n WorkflowInputValidationError,\n WorkflowOutputValidationError,\n} from \"./errors.js\";\nimport {\n ClientInferInput,\n ClientInferOutput,\n WorkerInferInput,\n WorkerInferOutput,\n} from \"./types.js\";\nimport { Future, Result } from \"@temporal-contract/boxed\";\nimport {\n ActivityOptions,\n ChildWorkflowHandle,\n ChildWorkflowOptions,\n defineQuery,\n defineSignal,\n defineUpdate,\n executeChild,\n proxyActivities,\n setHandler,\n startChild,\n WorkflowInfo,\n workflowInfo,\n} from \"@temporalio/workflow\";\nimport { StandardSchemaV1 } from \"@standard-schema/spec\";\n\nexport {\n ActivityInputValidationError,\n ActivityOutputValidationError,\n ChildWorkflowError,\n ChildWorkflowNotFoundError,\n QueryInputValidationError,\n QueryOutputValidationError,\n SignalInputValidationError,\n UpdateInputValidationError,\n UpdateOutputValidationError,\n WorkflowInputValidationError,\n WorkflowOutputValidationError,\n} from \"./errors.js\";\n\n/**\n * Create a typed workflow implementation with automatic validation\n *\n * This wraps a workflow implementation with:\n * - Input/output validation\n * - Typed workflow context with activities\n * - Workflow info access\n *\n * Workflows must be defined in separate files and imported by the Temporal Worker\n * via workflowsPath.\n *\n * @example\n * ```ts\n * // workflows/processOrder.ts\n * import { declareWorkflow } from '@temporal-contract/worker/workflow';\n * import myContract from '../contract';\n *\n * export const processOrder = declareWorkflow({\n * workflowName: 'processOrder',\n * contract: myContract,\n * activityOptions: {\n * startToCloseTimeout: '1 minute',\n * },\n * implementation: async (context, args) => {\n * // context.activities: typed activities (workflow + global)\n * // context.info: WorkflowInfo\n *\n * const inventory = await context.activities.validateInventory({\n * orderId: args.orderId,\n * });\n *\n * if (!inventory.available) {\n * return { orderId: args.orderId, status: 'out_of_stock' };\n * }\n *\n * const payment = await context.activities.chargePayment({\n * customerId: args.customerId,\n * amount: 100,\n * });\n *\n * return {\n * orderId: args.orderId,\n * status: payment.success ? 'success' : 'failed',\n * transactionId: payment.transactionId,\n * };\n * },\n * });\n * ```\n *\n * Then in your worker setup:\n * ```ts\n * // worker.ts\n * import { createWorker } from '@temporal-contract/worker/worker';\n * import { activities } from './activities';\n * import myContract from './contract';\n *\n * const worker = await createWorker({\n * contract: myContract,\n * connection,\n * workflowsPath: workflowsPathFromURL(import.meta.url, './workflows.js'),\n * activities,\n * });\n * ```\n */\nexport function declareWorkflow<\n TContract extends ContractDefinition,\n TWorkflowName extends keyof TContract[\"workflows\"],\n>({\n workflowName,\n contract,\n implementation,\n activityOptions,\n}: DeclareWorkflowOptions<TContract, TWorkflowName>): (\n ...args: unknown[]\n) => Promise<WorkerInferOutput<TContract[\"workflows\"][TWorkflowName]>> {\n // Get the workflow definition from the contract\n const definition = contract.workflows[\n workflowName as string\n ] as TContract[\"workflows\"][TWorkflowName];\n\n return async (...args: unknown[]) => {\n // Extract single parameter (Temporal passes arguments as array)\n const input = args.length === 1 ? args[0] : args;\n\n // Validate workflow input\n const inputResult = await definition.input[\"~standard\"].validate(input);\n if (inputResult.issues) {\n throw new WorkflowInputValidationError(String(workflowName), inputResult.issues);\n }\n const validatedInput = inputResult.value as WorkerInferInput<\n TContract[\"workflows\"][TWorkflowName]\n >;\n\n // Create activities proxy with validation if activities are defined.\n //\n // Design note — intentional double-validation:\n // Input and output are validated here (workflow side) AND again inside\n // `declareActivitiesHandler` (activity worker side). This is deliberate:\n //\n // 1. Workflow-side validation catches bad data *before* it crosses the\n // task-queue network boundary, giving an early, descriptive error\n // instead of a confusing deserialization failure inside the activity.\n // 2. Activity-side validation is the authoritative guard, since the\n // activity may be called by other callers that do not use this library.\n //\n // The overhead is minimal relative to the network round-trip.\n let contextActivities: unknown = {};\n\n if (definition.activities || contract.activities) {\n const rawActivities =\n proxyActivities<Record<string, (...args: unknown[]) => Promise<unknown>>>(activityOptions);\n\n contextActivities = createValidatedActivities(\n rawActivities,\n definition.activities,\n contract.activities,\n );\n }\n\n // Helper to validate child workflow output\n async function validateChildWorkflowOutput<TChildWorkflow extends WorkflowDefinition>(\n childDefinition: TChildWorkflow,\n result: unknown,\n childWorkflowName: string,\n ): Promise<Result<ClientInferOutput<TChildWorkflow>, ChildWorkflowError>> {\n const outputResult = await childDefinition.output[\"~standard\"].validate(result);\n if (outputResult.issues) {\n return Result.Error(\n new ChildWorkflowError(\n `Child workflow \"${childWorkflowName}\" output validation failed: ${outputResult.issues.map((i: StandardSchemaV1.Issue) => i.message).join(\"; \")}`,\n ),\n );\n }\n return Result.Ok(outputResult.value as WorkerInferOutput<TChildWorkflow>);\n }\n\n // Helper to get and validate child workflow definition and input\n async function getAndValidateChildWorkflow<\n TChildContract extends ContractDefinition,\n TChildWorkflowName extends keyof TChildContract[\"workflows\"],\n >(\n childContract: TChildContract,\n childWorkflowName: TChildWorkflowName,\n args: unknown,\n ): Promise<\n Result<\n {\n definition: TChildContract[\"workflows\"][TChildWorkflowName];\n validatedInput: WorkerInferInput<TChildContract[\"workflows\"][TChildWorkflowName]>;\n taskQueue: string;\n },\n ChildWorkflowError\n >\n > {\n const childDefinition = childContract.workflows[childWorkflowName as string];\n\n if (!childDefinition) {\n return Result.Error(\n new ChildWorkflowNotFoundError(\n String(childWorkflowName),\n Object.keys(childContract.workflows) as string[],\n ),\n );\n }\n\n const inputResult = await childDefinition.input[\"~standard\"].validate(args);\n if (inputResult.issues) {\n return Result.Error(\n new ChildWorkflowError(\n `Child workflow \"${String(childWorkflowName)}\" input validation failed: ${inputResult.issues.map((i: StandardSchemaV1.Issue) => i.message).join(\"; \")}`,\n ),\n );\n }\n\n const validatedInput = inputResult.value as WorkerInferInput<\n TChildContract[\"workflows\"][TChildWorkflowName]\n >;\n\n return Result.Ok({\n definition: childDefinition as TChildContract[\"workflows\"][TChildWorkflowName],\n validatedInput,\n taskQueue: childContract.taskQueue,\n });\n }\n\n // Helper function to create a typed child workflow handle\n function createTypedChildHandle<TChildWorkflow extends WorkflowDefinition>(\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n handle: ChildWorkflowHandle<any>,\n childDefinition: TChildWorkflow,\n childWorkflowName: string,\n ): TypedChildWorkflowHandle<TChildWorkflow> {\n return {\n workflowId: handle.workflowId,\n result: (): Future<Result<ClientInferOutput<TChildWorkflow>, ChildWorkflowError>> => {\n return Future.fromAsync(async () => {\n try {\n const result = await handle.result();\n return validateChildWorkflowOutput(childDefinition, result, childWorkflowName);\n } catch (error) {\n return Result.Error(\n new ChildWorkflowError(\n `Child workflow execution failed: ${error instanceof Error ? error.message : String(error)}`,\n error,\n ),\n );\n }\n });\n },\n };\n }\n\n // Helper function to start a child workflow\n function createStartChildWorkflow<\n TChildContract extends ContractDefinition,\n TChildWorkflowName extends keyof TChildContract[\"workflows\"],\n >(\n childContract: TChildContract,\n childWorkflowName: TChildWorkflowName,\n options: TypedChildWorkflowOptions<TChildContract, TChildWorkflowName>,\n ): Future<\n Result<\n TypedChildWorkflowHandle<TChildContract[\"workflows\"][TChildWorkflowName]>,\n ChildWorkflowError\n >\n > {\n return Future.fromAsync(async () => {\n // Validate input and get definition\n const validationResult = await getAndValidateChildWorkflow(\n childContract,\n childWorkflowName,\n options.args,\n );\n\n if (validationResult.isError()) {\n return Result.Error(validationResult.error);\n }\n\n const { definition: childDefinition, validatedInput, taskQueue } = validationResult.value;\n\n try {\n // Start child workflow (Temporal expects args as array)\n const { args: _args, ...temporalOptions } = options;\n const handle = await startChild(childWorkflowName as string, {\n ...temporalOptions,\n taskQueue,\n args: [validatedInput],\n });\n\n const typedHandle = createTypedChildHandle(\n handle,\n childDefinition,\n String(childWorkflowName),\n ) as TypedChildWorkflowHandle<TChildContract[\"workflows\"][TChildWorkflowName]>;\n\n return Result.Ok(typedHandle);\n } catch (error) {\n return Result.Error(\n new ChildWorkflowError(\n `Failed to start child workflow: ${error instanceof Error ? error.message : String(error)}`,\n error,\n ),\n );\n }\n });\n }\n\n // Helper function to execute a child workflow\n function createExecuteChildWorkflow<\n TChildContract extends ContractDefinition,\n TChildWorkflowName extends keyof TChildContract[\"workflows\"],\n >(\n childContract: TChildContract,\n childWorkflowName: TChildWorkflowName,\n options: TypedChildWorkflowOptions<TChildContract, TChildWorkflowName>,\n ): Future<\n Result<ClientInferOutput<TChildContract[\"workflows\"][TChildWorkflowName]>, ChildWorkflowError>\n > {\n return Future.fromAsync(async () => {\n // Validate input and get definition\n const validationResult = await getAndValidateChildWorkflow(\n childContract,\n childWorkflowName,\n options.args,\n );\n\n if (validationResult.isError()) {\n return Result.Error(validationResult.error);\n }\n\n const { definition: childDefinition, validatedInput, taskQueue } = validationResult.value;\n\n try {\n // Execute child workflow (Temporal expects args as array)\n const { args: _args, ...temporalOptions } = options;\n const result = await executeChild(childWorkflowName as string, {\n ...temporalOptions,\n taskQueue,\n args: [validatedInput],\n });\n\n // Validate output with Standard Schema\n const outputValidationResult = await validateChildWorkflowOutput(\n childDefinition,\n result,\n String(childWorkflowName),\n );\n\n if (outputValidationResult.isError()) {\n return Result.Error(outputValidationResult.error);\n }\n\n return Result.Ok(\n outputValidationResult.value as ClientInferOutput<\n TChildContract[\"workflows\"][TChildWorkflowName]\n >,\n );\n } catch (error) {\n return Result.Error(\n new ChildWorkflowError(\n `Failed to execute child workflow: ${error instanceof Error ? error.message : String(error)}`,\n error,\n ),\n );\n }\n });\n }\n\n // Context methods for defining signals, queries, and updates\n function createDefineSignal<\n TSignalName extends keyof TContract[\"workflows\"][TWorkflowName][\"signals\"],\n >(\n signalName: TSignalName,\n handler: SignalHandlerImplementation<\n TContract[\"workflows\"][TWorkflowName][\"signals\"][TSignalName] extends SignalDefinition\n ? TContract[\"workflows\"][TWorkflowName][\"signals\"][TSignalName]\n : never\n >,\n ): void {\n if (!definition.signals) {\n throw new Error(\n `Signal \"${String(signalName)}\" cannot be defined: workflow \"${String(workflowName)}\" has no signals in its contract`,\n );\n }\n\n const signalDef = (definition.signals as Record<string, SignalDefinition>)[\n signalName as string\n ];\n if (!signalDef) {\n throw new Error(\n `Signal \"${String(signalName)}\" not found in workflow \"${String(workflowName)}\" contract`,\n );\n }\n\n const signal = defineSignal(signalName as string);\n setHandler(signal, async (...args: unknown[]) => {\n // Extract single parameter (Temporal passes as args array)\n const input = args.length === 1 ? args[0] : args;\n const inputResult = await signalDef.input[\"~standard\"].validate(input);\n if (inputResult.issues) {\n throw new SignalInputValidationError(signalName as string, inputResult.issues);\n }\n await (handler as SignalHandlerImplementation<SignalDefinition>)(inputResult.value);\n });\n }\n\n function createDefineQuery<\n TQueryName extends keyof TContract[\"workflows\"][TWorkflowName][\"queries\"],\n >(\n queryName: TQueryName,\n handler: QueryHandlerImplementation<\n TContract[\"workflows\"][TWorkflowName][\"queries\"][TQueryName] extends QueryDefinition\n ? TContract[\"workflows\"][TWorkflowName][\"queries\"][TQueryName]\n : never\n >,\n ): void {\n if (!definition.queries) {\n throw new Error(\n `Query \"${String(queryName)}\" cannot be defined: workflow \"${String(workflowName)}\" has no queries in its contract`,\n );\n }\n\n const queryDef = (definition.queries as Record<string, QueryDefinition>)[queryName as string];\n if (!queryDef) {\n throw new Error(\n `Query \"${String(queryName)}\" not found in workflow \"${String(workflowName)}\" contract`,\n );\n }\n\n const query = defineQuery(queryName as string);\n setHandler(query, (...args: unknown[]) => {\n // Extract single parameter (Temporal passes as args array)\n const input = args.length === 1 ? args[0] : args;\n // Note: Query handlers must be synchronous, so we need to handle validation synchronously\n const inputResult = queryDef.input[\"~standard\"].validate(input);\n\n // Handle both sync and async validation results\n if (inputResult instanceof Promise) {\n throw new Error(\n `Query \"${String(queryName)}\" validation must be synchronous. Use a schema library that supports synchronous validation for queries.`,\n );\n }\n\n if (inputResult.issues) {\n throw new QueryInputValidationError(queryName as string, inputResult.issues);\n }\n\n const result = handler(inputResult.value);\n\n const outputResult = queryDef.output[\"~standard\"].validate(result);\n if (outputResult instanceof Promise) {\n throw new Error(\n `Query \"${String(queryName)}\" output validation must be synchronous. Use a schema library that supports synchronous validation for queries.`,\n );\n }\n\n if (outputResult.issues) {\n throw new QueryOutputValidationError(queryName as string, outputResult.issues);\n }\n\n return outputResult.value;\n });\n }\n\n function createDefineUpdate<\n TUpdateName extends keyof TContract[\"workflows\"][TWorkflowName][\"updates\"],\n >(\n updateName: TUpdateName,\n handler: UpdateHandlerImplementation<\n TContract[\"workflows\"][TWorkflowName][\"updates\"][TUpdateName] extends UpdateDefinition\n ? TContract[\"workflows\"][TWorkflowName][\"updates\"][TUpdateName]\n : never\n >,\n ): void {\n if (!definition.updates) {\n throw new Error(\n `Update \"${String(updateName)}\" cannot be defined: workflow \"${String(workflowName)}\" has no updates in its contract`,\n );\n }\n\n const updateDef = (definition.updates as Record<string, UpdateDefinition>)[\n updateName as string\n ];\n if (!updateDef) {\n throw new Error(\n `Update \"${String(updateName)}\" not found in workflow \"${String(workflowName)}\" contract`,\n );\n }\n\n const update = defineUpdate(updateName as string);\n setHandler(update, async (...args: unknown[]) => {\n // Extract single parameter (Temporal passes as args array)\n const input = args.length === 1 ? args[0] : args;\n const inputResult = await updateDef.input[\"~standard\"].validate(input);\n if (inputResult.issues) {\n throw new UpdateInputValidationError(updateName as string, inputResult.issues);\n }\n\n const result = await handler(inputResult.value);\n\n const outputResult = await updateDef.output[\"~standard\"].validate(result);\n if (outputResult.issues) {\n throw new UpdateOutputValidationError(updateName as string, outputResult.issues);\n }\n\n return outputResult.value;\n });\n }\n\n // Create workflow context\n const context: WorkflowContext<TContract, TWorkflowName> = {\n activities: contextActivities as WorkflowInferWorkflowContextActivities<\n TContract,\n TWorkflowName\n >,\n info: workflowInfo(),\n startChildWorkflow: createStartChildWorkflow,\n executeChildWorkflow: createExecuteChildWorkflow,\n defineSignal: createDefineSignal as WorkflowContext<TContract, TWorkflowName>[\"defineSignal\"],\n defineQuery: createDefineQuery as WorkflowContext<TContract, TWorkflowName>[\"defineQuery\"],\n defineUpdate: createDefineUpdate as WorkflowContext<TContract, TWorkflowName>[\"defineUpdate\"],\n };\n\n // Execute workflow (pass validated input as tuple)\n const result = await implementation(context, validatedInput);\n\n // Validate workflow output\n const outputResult = await definition.output[\"~standard\"].validate(result);\n if (outputResult.issues) {\n throw new WorkflowOutputValidationError(String(workflowName), outputResult.issues);\n }\n\n return outputResult.value as WorkerInferOutput<TContract[\"workflows\"][TWorkflowName]>;\n };\n}\n\n/**\n * Signal handler implementation\n *\n * Processes signal input and can optionally perform asynchronous operations.\n * Should not return a value (signals are fire-and-forget).\n */\ntype SignalHandlerImplementation<TSignal extends SignalDefinition> = (\n args: WorkerInferInput<TSignal>,\n) => void | Promise<void>;\n\n/**\n * Query handler implementation\n *\n * Processes query input and returns a synchronous response.\n * Must be synchronous to satisfy Temporal's query constraints.\n */\ntype QueryHandlerImplementation<TQuery extends QueryDefinition> = (\n args: WorkerInferInput<TQuery>,\n) => WorkerInferOutput<TQuery>;\n\n/**\n * Update handler implementation\n *\n * Processes update input and returns a validated response after modifying workflow state.\n * Can perform asynchronous operations.\n */\ntype UpdateHandlerImplementation<TUpdate extends UpdateDefinition> = (\n args: WorkerInferInput<TUpdate>,\n) => Promise<WorkerInferOutput<TUpdate>>;\n\n/**\n * Options for declaring a workflow implementation\n */\ntype DeclareWorkflowOptions<\n TContract extends ContractDefinition,\n TWorkflowName extends keyof TContract[\"workflows\"],\n> = {\n workflowName: TWorkflowName;\n contract: TContract;\n implementation: WorkflowImplementation<TContract, TWorkflowName>;\n /**\n * Default activity options applied to all activities in this workflow.\n * For more control, you can override specific Temporal ActivityOptions like:\n * - startToCloseTimeout: Maximum time for activity execution\n * - scheduleToCloseTimeout: End-to-end timeout including queuing\n * - scheduleToStartTimeout: Maximum time activity can wait in queue\n * - heartbeatTimeout: Time between heartbeats before considering activity dead\n * - retry: Retry policy for failed activities\n *\n * @example\n * ```ts\n * activityOptions: {\n * startToCloseTimeout: '5m',\n * retry: { maximumAttempts: 3 }\n * }\n * ```\n */\n activityOptions: ActivityOptions;\n};\n\n/**\n * Workflow implementation function\n *\n * Receives a workflow context (with typed activities and utilities) and validated input arguments.\n * Returns the workflow output which will be validated against the contract schema.\n */\ntype WorkflowImplementation<\n TContract extends ContractDefinition,\n TWorkflowName extends keyof TContract[\"workflows\"],\n> = (\n context: WorkflowContext<TContract, TWorkflowName>,\n args: WorkerInferInput<TContract[\"workflows\"][TWorkflowName]>,\n) => Promise<WorkerInferOutput<TContract[\"workflows\"][TWorkflowName]>>;\n\n/**\n * Workflow execution context providing typed activities, workflow info, and interaction handlers\n *\n * Provides access to:\n * - Typed activities (both workflow-specific and global)\n * - Workflow metadata and execution info\n * - Signal, query, and update handler registration\n * - Child workflow execution capabilities\n */\ntype WorkflowContext<\n TContract extends ContractDefinition,\n TWorkflowName extends keyof TContract[\"workflows\"],\n> = {\n activities: WorkflowInferWorkflowContextActivities<TContract, TWorkflowName>;\n info: WorkflowInfo;\n\n /**\n * Define a signal handler within the workflow implementation\n * Allows the signal handler to access workflow state\n *\n * @example\n * ```ts\n * implementation: async (context, args) => {\n * let currentValue = args.initialValue;\n *\n * context.defineSignal('increment', async (signalArgs) => {\n * currentValue += signalArgs.amount;\n * });\n *\n * // ... rest of workflow\n * }\n * ```\n */\n defineSignal: <K extends keyof TContract[\"workflows\"][TWorkflowName][\"signals\"]>(\n signalName: K,\n handler: SignalHandlerImplementation<\n TContract[\"workflows\"][TWorkflowName][\"signals\"][K] extends SignalDefinition\n ? TContract[\"workflows\"][TWorkflowName][\"signals\"][K]\n : never\n >,\n ) => void;\n\n /**\n * Define a query handler within the workflow implementation\n * Allows the query handler to access workflow state\n *\n * @example\n * ```ts\n * implementation: async (context, args) => {\n * let currentValue = args.initialValue;\n *\n * context.defineQuery('getCurrentValue', () => {\n * return { value: currentValue };\n * });\n *\n * // ... rest of workflow\n * }\n * ```\n */\n defineQuery: <K extends keyof TContract[\"workflows\"][TWorkflowName][\"queries\"]>(\n queryName: K,\n handler: QueryHandlerImplementation<\n TContract[\"workflows\"][TWorkflowName][\"queries\"][K] extends QueryDefinition\n ? TContract[\"workflows\"][TWorkflowName][\"queries\"][K]\n : never\n >,\n ) => void;\n\n /**\n * Define an update handler within the workflow implementation\n * Allows the update handler to access and modify workflow state\n *\n * @example\n * ```ts\n * implementation: async (context, args) => {\n * let currentValue = args.initialValue;\n *\n * context.defineUpdate('multiply', async (updateArgs) => {\n * currentValue *= updateArgs.factor;\n * return { newValue: currentValue };\n * });\n *\n * // ... rest of workflow\n * }\n * ```\n */\n defineUpdate: <K extends keyof TContract[\"workflows\"][TWorkflowName][\"updates\"]>(\n updateName: K,\n handler: UpdateHandlerImplementation<\n TContract[\"workflows\"][TWorkflowName][\"updates\"][K] extends UpdateDefinition\n ? TContract[\"workflows\"][TWorkflowName][\"updates\"][K]\n : never\n >,\n ) => void;\n\n /**\n * Start a child workflow and return a typed handle with Future/Result pattern\n *\n * Supports both same-contract and cross-contract child workflows:\n * - Same contract: Pass workflowName from current contract\n * - Cross-contract: Pass contract and workflowName to invoke workflows from other workers\n *\n * @example\n * ```ts\n * // Same contract child workflow\n * const childResult = await context.startChildWorkflow(myContract, 'processPayment', {\n * workflowId: 'payment-123',\n * args: { amount: 100 }\n * });\n *\n * // Cross-contract child workflow (from another worker)\n * const otherResult = await context.startChildWorkflow(otherContract, 'sendNotification', {\n * workflowId: 'notification-123',\n * args: { message: 'Hello' }\n * });\n *\n * childResult.match({\n * Ok: async (handle) => {\n * const result = await handle.result();\n * // ... handle result\n * },\n * Error: (error) => console.error('Failed to start:', error),\n * });\n * ```\n */\n startChildWorkflow: <\n TChildContract extends ContractDefinition,\n TChildWorkflowName extends keyof TChildContract[\"workflows\"],\n >(\n contract: TChildContract,\n workflowName: TChildWorkflowName,\n options: TypedChildWorkflowOptions<TChildContract, TChildWorkflowName>,\n ) => Future<\n Result<\n TypedChildWorkflowHandle<TChildContract[\"workflows\"][TChildWorkflowName]>,\n ChildWorkflowError\n >\n >;\n\n /**\n * Execute a child workflow (start and wait for result) with Future/Result pattern\n *\n * Supports both same-contract and cross-contract child workflows:\n * - Same contract: Pass workflowName from current contract\n * - Cross-contract: Pass contract and workflowName to invoke workflows from other workers\n *\n * @example\n * ```ts\n * // Same contract child workflow\n * const result = await context.executeChildWorkflow(myContract, 'processPayment', {\n * workflowId: 'payment-123',\n * args: { amount: 100 }\n * });\n *\n * // Cross-contract child workflow (from another worker)\n * const otherResult = await context.executeChildWorkflow(otherContract, 'sendNotification', {\n * workflowId: 'notification-123',\n * args: { message: 'Hello' }\n * });\n *\n * result.match({\n * Ok: (output) => console.log('Payment processed:', output),\n * Error: (error) => console.error('Processing failed:', error),\n * });\n * ```\n */\n executeChildWorkflow: <\n TChildContract extends ContractDefinition,\n TChildWorkflowName extends keyof TChildContract[\"workflows\"],\n >(\n contract: TChildContract,\n workflowName: TChildWorkflowName,\n options: TypedChildWorkflowOptions<TChildContract, TChildWorkflowName>,\n ) => Future<\n Result<ClientInferOutput<TChildContract[\"workflows\"][TChildWorkflowName]>, ChildWorkflowError>\n >;\n};\n\n/**\n * Options for starting a child workflow\n */\ntype TypedChildWorkflowOptions<\n TChildContract extends ContractDefinition,\n TChildWorkflowName extends keyof TChildContract[\"workflows\"],\n> = Omit<ChildWorkflowOptions, \"taskQueue\" | \"args\"> & {\n args: ClientInferInput<TChildContract[\"workflows\"][TChildWorkflowName]>;\n};\n\n/**\n * Typed handle for a child workflow with Future/Result pattern\n */\ntype TypedChildWorkflowHandle<TWorkflow extends WorkflowDefinition> = {\n /**\n * Get child workflow result with Result pattern\n */\n result: () => Future<Result<ClientInferOutput<TWorkflow>, ChildWorkflowError>>;\n\n /**\n * Child workflow ID\n */\n workflowId: string;\n};\n\n/**\n * Activity function signature from workflow execution perspective\n *\n * Workflows call activities with validated input (z.input parsed) and receive validated output (z.output)\n */\ntype WorkflowInferActivity<TActivity extends ActivityDefinition> = (\n args: ClientInferInput<TActivity>,\n) => Promise<ClientInferOutput<TActivity>>;\n\n/**\n * All global activities from a contract (workflow execution perspective)\n */\ntype WorkflowInferActivities<TContract extends ContractDefinition> =\n TContract[\"activities\"] extends Record<string, ActivityDefinition>\n ? {\n [K in keyof TContract[\"activities\"]]: WorkflowInferActivity<TContract[\"activities\"][K]>;\n }\n : {};\n\n/**\n * Workflow-specific activities (workflow execution perspective)\n */\ntype WorkflowInferWorkflowActivities<T extends WorkflowDefinition> =\n T[\"activities\"] extends Record<string, ActivityDefinition>\n ? {\n [K in keyof T[\"activities\"]]: WorkflowInferActivity<T[\"activities\"][K]>;\n }\n : {};\n\n/**\n * All activities available in a workflow context (workflow execution perspective)\n *\n * Combines workflow-specific activities with global contract activities\n */\ntype WorkflowInferWorkflowContextActivities<\n TContract extends ContractDefinition,\n TWorkflowName extends keyof TContract[\"workflows\"],\n> = WorkflowInferWorkflowActivities<TContract[\"workflows\"][TWorkflowName]> &\n WorkflowInferActivities<TContract>;\n\n/**\n * Create a validated activities proxy that parses inputs and outputs\n *\n * This wrapper ensures data integrity across the network boundary between\n * workflow and activity execution.\n */\nfunction createValidatedActivities<\n TContract extends ContractDefinition,\n TWorkflowName extends keyof TContract[\"workflows\"],\n>(\n rawActivities: Record<string, (...args: unknown[]) => Promise<unknown>>,\n workflowActivitiesDefinition: Record<string, ActivityDefinition> | undefined,\n contractActivitiesDefinition: Record<string, ActivityDefinition> | undefined,\n): WorkflowInferWorkflowContextActivities<TContract, TWorkflowName> {\n const validatedActivities = {} as WorkflowInferWorkflowContextActivities<\n TContract,\n TWorkflowName\n >;\n\n // Merge workflow-specific and global contract activities\n // Workflow-specific activities take precedence over global ones\n const allActivitiesDefinition = {\n ...contractActivitiesDefinition,\n ...workflowActivitiesDefinition,\n };\n\n for (const [activityName, activityDef] of Object.entries(allActivitiesDefinition)) {\n const rawActivity = rawActivities[activityName];\n\n if (!rawActivity) {\n throw new Error(\n `Activity implementation not found for: \"${activityName}\". ` +\n `Available activities: ${Object.keys(rawActivities).length > 0 ? Object.keys(rawActivities).join(\", \") : \"none\"}`,\n );\n }\n\n // Wrap activity with input/output validation\n // Register the wrapped activity\n (validatedActivities as Record<string, unknown>)[activityName] = async (input: unknown) => {\n // Validate input before sending over the network\n const inputResult = await activityDef.input[\"~standard\"].validate(input);\n if (inputResult.issues) {\n throw new ActivityInputValidationError(activityName, inputResult.issues);\n }\n\n // Call the actual activity with validated input\n const result = await rawActivity(inputResult.value);\n\n // Validate output after receiving from the network\n const outputResult = await activityDef.output[\"~standard\"].validate(result);\n if (outputResult.issues) {\n throw new ActivityOutputValidationError(activityName, outputResult.issues);\n }\n\n return outputResult.value;\n };\n }\n\n return validatedActivities;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA2HA,SAAgB,gBAGd,EACA,cACA,UACA,gBACA,mBAGqE;CAErE,MAAM,aAAa,SAAS,UAC1B;AAGF,QAAO,OAAO,GAAG,SAAoB;EAEnC,MAAM,QAAQ,KAAK,WAAW,IAAI,KAAK,KAAK;EAG5C,MAAM,cAAc,MAAM,WAAW,MAAM,aAAa,SAAS,MAAM;AACvE,MAAI,YAAY,OACd,OAAM,IAAI,6BAA6B,OAAO,aAAa,EAAE,YAAY,OAAO;EAElF,MAAM,iBAAiB,YAAY;EAiBnC,IAAI,oBAA6B,EAAE;AAEnC,MAAI,WAAW,cAAc,SAAS,WAIpC,qBAAoB,0BAFlB,gBAA0E,gBAAgB,EAI1F,WAAW,YACX,SAAS,WACV;EAIH,eAAe,4BACb,iBACA,QACA,mBACwE;GACxE,MAAM,eAAe,MAAM,gBAAgB,OAAO,aAAa,SAAS,OAAO;AAC/E,OAAI,aAAa,OACf,QAAO,OAAO,MACZ,IAAI,mBACF,mBAAmB,kBAAkB,8BAA8B,aAAa,OAAO,KAAK,MAA8B,EAAE,QAAQ,CAAC,KAAK,KAAK,GAChJ,CACF;AAEH,UAAO,OAAO,GAAG,aAAa,MAA2C;;EAI3E,eAAe,4BAIb,eACA,mBACA,MAUA;GACA,MAAM,kBAAkB,cAAc,UAAU;AAEhD,OAAI,CAAC,gBACH,QAAO,OAAO,MACZ,IAAI,2BACF,OAAO,kBAAkB,EACzB,OAAO,KAAK,cAAc,UAAU,CACrC,CACF;GAGH,MAAM,cAAc,MAAM,gBAAgB,MAAM,aAAa,SAAS,KAAK;AAC3E,OAAI,YAAY,OACd,QAAO,OAAO,MACZ,IAAI,mBACF,mBAAmB,OAAO,kBAAkB,CAAC,6BAA6B,YAAY,OAAO,KAAK,MAA8B,EAAE,QAAQ,CAAC,KAAK,KAAK,GACtJ,CACF;GAGH,MAAM,iBAAiB,YAAY;AAInC,UAAO,OAAO,GAAG;IACf,YAAY;IACZ;IACA,WAAW,cAAc;IAC1B,CAAC;;EAIJ,SAAS,uBAEP,QACA,iBACA,mBAC0C;AAC1C,UAAO;IACL,YAAY,OAAO;IACnB,cAAqF;AACnF,YAAO,OAAO,UAAU,YAAY;AAClC,UAAI;AAEF,cAAO,4BAA4B,iBADpB,MAAM,OAAO,QAAQ,EACwB,kBAAkB;eACvE,OAAO;AACd,cAAO,OAAO,MACZ,IAAI,mBACF,oCAAoC,iBAAiB,QAAQ,MAAM,UAAU,OAAO,MAAM,IAC1F,MACD,CACF;;OAEH;;IAEL;;EAIH,SAAS,yBAIP,eACA,mBACA,SAMA;AACA,UAAO,OAAO,UAAU,YAAY;IAElC,MAAM,mBAAmB,MAAM,4BAC7B,eACA,mBACA,QAAQ,KACT;AAED,QAAI,iBAAiB,SAAS,CAC5B,QAAO,OAAO,MAAM,iBAAiB,MAAM;IAG7C,MAAM,EAAE,YAAY,iBAAiB,gBAAgB,cAAc,iBAAiB;AAEpF,QAAI;KAEF,MAAM,EAAE,MAAM,OAAO,GAAG,oBAAoB;KAO5C,MAAM,cAAc,uBANL,MAAM,WAAW,mBAA6B;MAC3D,GAAG;MACH;MACA,MAAM,CAAC,eAAe;MACvB,CAAC,EAIA,iBACA,OAAO,kBAAkB,CAC1B;AAED,YAAO,OAAO,GAAG,YAAY;aACtB,OAAO;AACd,YAAO,OAAO,MACZ,IAAI,mBACF,mCAAmC,iBAAiB,QAAQ,MAAM,UAAU,OAAO,MAAM,IACzF,MACD,CACF;;KAEH;;EAIJ,SAAS,2BAIP,eACA,mBACA,SAGA;AACA,UAAO,OAAO,UAAU,YAAY;IAElC,MAAM,mBAAmB,MAAM,4BAC7B,eACA,mBACA,QAAQ,KACT;AAED,QAAI,iBAAiB,SAAS,CAC5B,QAAO,OAAO,MAAM,iBAAiB,MAAM;IAG7C,MAAM,EAAE,YAAY,iBAAiB,gBAAgB,cAAc,iBAAiB;AAEpF,QAAI;KAEF,MAAM,EAAE,MAAM,OAAO,GAAG,oBAAoB;KAQ5C,MAAM,yBAAyB,MAAM,4BACnC,iBARa,MAAM,aAAa,mBAA6B;MAC7D,GAAG;MACH;MACA,MAAM,CAAC,eAAe;MACvB,CAAC,EAMA,OAAO,kBAAkB,CAC1B;AAED,SAAI,uBAAuB,SAAS,CAClC,QAAO,OAAO,MAAM,uBAAuB,MAAM;AAGnD,YAAO,OAAO,GACZ,uBAAuB,MAGxB;aACM,OAAO;AACd,YAAO,OAAO,MACZ,IAAI,mBACF,qCAAqC,iBAAiB,QAAQ,MAAM,UAAU,OAAO,MAAM,IAC3F,MACD,CACF;;KAEH;;EAIJ,SAAS,mBAGP,YACA,SAKM;AACN,OAAI,CAAC,WAAW,QACd,OAAM,IAAI,MACR,WAAW,OAAO,WAAW,CAAC,iCAAiC,OAAO,aAAa,CAAC,kCACrF;GAGH,MAAM,YAAa,WAAW,QAC5B;AAEF,OAAI,CAAC,UACH,OAAM,IAAI,MACR,WAAW,OAAO,WAAW,CAAC,2BAA2B,OAAO,aAAa,CAAC,YAC/E;AAIH,cADe,aAAa,WAAqB,EAC9B,OAAO,GAAG,SAAoB;IAE/C,MAAM,QAAQ,KAAK,WAAW,IAAI,KAAK,KAAK;IAC5C,MAAM,cAAc,MAAM,UAAU,MAAM,aAAa,SAAS,MAAM;AACtE,QAAI,YAAY,OACd,OAAM,IAAI,2BAA2B,YAAsB,YAAY,OAAO;AAEhF,UAAO,QAA0D,YAAY,MAAM;KACnF;;EAGJ,SAAS,kBAGP,WACA,SAKM;AACN,OAAI,CAAC,WAAW,QACd,OAAM,IAAI,MACR,UAAU,OAAO,UAAU,CAAC,iCAAiC,OAAO,aAAa,CAAC,kCACnF;GAGH,MAAM,WAAY,WAAW,QAA4C;AACzE,OAAI,CAAC,SACH,OAAM,IAAI,MACR,UAAU,OAAO,UAAU,CAAC,2BAA2B,OAAO,aAAa,CAAC,YAC7E;AAIH,cADc,YAAY,UAAoB,GAC3B,GAAG,SAAoB;IAExC,MAAM,QAAQ,KAAK,WAAW,IAAI,KAAK,KAAK;IAE5C,MAAM,cAAc,SAAS,MAAM,aAAa,SAAS,MAAM;AAG/D,QAAI,uBAAuB,QACzB,OAAM,IAAI,MACR,UAAU,OAAO,UAAU,CAAC,0GAC7B;AAGH,QAAI,YAAY,OACd,OAAM,IAAI,0BAA0B,WAAqB,YAAY,OAAO;IAG9E,MAAM,SAAS,QAAQ,YAAY,MAAM;IAEzC,MAAM,eAAe,SAAS,OAAO,aAAa,SAAS,OAAO;AAClE,QAAI,wBAAwB,QAC1B,OAAM,IAAI,MACR,UAAU,OAAO,UAAU,CAAC,iHAC7B;AAGH,QAAI,aAAa,OACf,OAAM,IAAI,2BAA2B,WAAqB,aAAa,OAAO;AAGhF,WAAO,aAAa;KACpB;;EAGJ,SAAS,mBAGP,YACA,SAKM;AACN,OAAI,CAAC,WAAW,QACd,OAAM,IAAI,MACR,WAAW,OAAO,WAAW,CAAC,iCAAiC,OAAO,aAAa,CAAC,kCACrF;GAGH,MAAM,YAAa,WAAW,QAC5B;AAEF,OAAI,CAAC,UACH,OAAM,IAAI,MACR,WAAW,OAAO,WAAW,CAAC,2BAA2B,OAAO,aAAa,CAAC,YAC/E;AAIH,cADe,aAAa,WAAqB,EAC9B,OAAO,GAAG,SAAoB;IAE/C,MAAM,QAAQ,KAAK,WAAW,IAAI,KAAK,KAAK;IAC5C,MAAM,cAAc,MAAM,UAAU,MAAM,aAAa,SAAS,MAAM;AACtE,QAAI,YAAY,OACd,OAAM,IAAI,2BAA2B,YAAsB,YAAY,OAAO;IAGhF,MAAM,SAAS,MAAM,QAAQ,YAAY,MAAM;IAE/C,MAAM,eAAe,MAAM,UAAU,OAAO,aAAa,SAAS,OAAO;AACzE,QAAI,aAAa,OACf,OAAM,IAAI,4BAA4B,YAAsB,aAAa,OAAO;AAGlF,WAAO,aAAa;KACpB;;EAkBJ,MAAM,SAAS,MAAM,eAdsC;GACzD,YAAY;GAIZ,MAAM,cAAc;GACpB,oBAAoB;GACpB,sBAAsB;GACtB,cAAc;GACd,aAAa;GACb,cAAc;GACf,EAG4C,eAAe;EAG5D,MAAM,eAAe,MAAM,WAAW,OAAO,aAAa,SAAS,OAAO;AAC1E,MAAI,aAAa,OACf,OAAM,IAAI,8BAA8B,OAAO,aAAa,EAAE,aAAa,OAAO;AAGpF,SAAO,aAAa;;;;;;;;;AAuUxB,SAAS,0BAIP,eACA,8BACA,8BACkE;CAClE,MAAM,sBAAsB,EAAE;CAO9B,MAAM,0BAA0B;EAC9B,GAAG;EACH,GAAG;EACJ;AAED,MAAK,MAAM,CAAC,cAAc,gBAAgB,OAAO,QAAQ,wBAAwB,EAAE;EACjF,MAAM,cAAc,cAAc;AAElC,MAAI,CAAC,YACH,OAAM,IAAI,MACR,2CAA2C,aAAa,2BAC7B,OAAO,KAAK,cAAc,CAAC,SAAS,IAAI,OAAO,KAAK,cAAc,CAAC,KAAK,KAAK,GAAG,SAC5G;AAKH,EAAC,oBAAgD,gBAAgB,OAAO,UAAmB;GAEzF,MAAM,cAAc,MAAM,YAAY,MAAM,aAAa,SAAS,MAAM;AACxE,OAAI,YAAY,OACd,OAAM,IAAI,6BAA6B,cAAc,YAAY,OAAO;GAI1E,MAAM,SAAS,MAAM,YAAY,YAAY,MAAM;GAGnD,MAAM,eAAe,MAAM,YAAY,OAAO,aAAa,SAAS,OAAO;AAC3E,OAAI,aAAa,OACf,OAAM,IAAI,8BAA8B,cAAc,aAAa,OAAO;AAG5E,UAAO,aAAa;;;AAIxB,QAAO"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@temporal-contract/worker",
3
- "version": "0.0.7",
3
+ "version": "0.2.0",
4
4
  "description": "Worker utilities with Result/Future pattern for implementing temporal-contract workflows and activities",
5
5
  "keywords": [
6
6
  "contract",
@@ -64,22 +64,25 @@
64
64
  "dependencies": {
65
65
  "@standard-schema/spec": "1.1.0",
66
66
  "@swan-io/boxed": "3.2.1",
67
- "@temporal-contract/boxed": "0.0.7",
68
- "@temporal-contract/contract": "0.0.7"
67
+ "@temporal-contract/boxed": "0.2.0",
68
+ "@temporal-contract/contract": "0.2.0"
69
69
  },
70
70
  "devDependencies": {
71
- "@temporalio/client": "1.14.0",
72
- "@temporalio/worker": "1.14.0",
73
- "@temporalio/workflow": "1.14.0",
74
- "@types/node": "25.0.3",
75
- "@vitest/coverage-v8": "4.0.16",
76
- "tsdown": "0.18.1",
71
+ "@temporalio/client": "1.14.1",
72
+ "@temporalio/worker": "1.14.1",
73
+ "@temporalio/workflow": "1.14.1",
74
+ "@types/node": "25.2.3",
75
+ "@vitest/coverage-v8": "4.0.18",
76
+ "tsdown": "0.20.3",
77
+ "typedoc": "0.28.17",
78
+ "typedoc-plugin-markdown": "4.10.0",
77
79
  "typescript": "5.9.3",
78
- "vitest": "4.0.16",
79
- "zod": "4.2.1",
80
- "@temporal-contract/client": "0.0.7",
81
- "@temporal-contract/testing": "0.0.7",
82
- "@temporal-contract/tsconfig": "0.0.7"
80
+ "vitest": "4.0.18",
81
+ "zod": "4.3.6",
82
+ "@temporal-contract/client": "0.2.0",
83
+ "@temporal-contract/testing": "0.2.0",
84
+ "@temporal-contract/tsconfig": "0.2.0",
85
+ "@temporal-contract/typedoc": "0.1.0"
83
86
  },
84
87
  "peerDependencies": {
85
88
  "@temporalio/worker": "^1",
@@ -87,6 +90,7 @@
87
90
  },
88
91
  "scripts": {
89
92
  "build": "tsdown src/activity.ts src/worker.ts src/workflow.ts --format cjs,esm --dts --clean",
93
+ "build:docs": "typedoc",
90
94
  "dev": "tsdown src/activity.ts src/worker.ts src/workflow.ts --format cjs,esm --dts --watch",
91
95
  "test": "vitest run --project unit",
92
96
  "test:integration": "vitest run --project integration",
@@ -1,162 +0,0 @@
1
- import { g as WorkerInferOutput, h as WorkerInferInput } from "./errors-BqYWpdvd.cjs";
2
- import { ActivityDefinition, ContractDefinition } from "@temporal-contract/contract";
3
- import { Future, Result } from "@swan-io/boxed";
4
-
5
- //#region src/activity-utils.d.ts
6
-
7
- /**
8
- * Extract activity definitions for a specific workflow from a contract
9
- *
10
- * This includes both:
11
- * - Workflow-specific activities defined under workflow.activities
12
- * - Global activities defined under contract.activities
13
- *
14
- * @param contract - The contract definition
15
- * @param workflowName - The name of the workflow
16
- * @returns Activity definitions for the workflow (workflow-specific + global activities merged)
17
- *
18
- * @example
19
- * ```ts
20
- * const orderWorkflowActivities = getWorkflowActivities(myContract, 'processOrder');
21
- * // Returns: { processPayment: ActivityDef, reserveInventory: ActivityDef, sendEmail: ActivityDef }
22
- * // where sendEmail is a global activity
23
- * ```
24
- */
25
- declare function getWorkflowActivities<TContract extends ContractDefinition, TWorkflowName extends keyof TContract["workflows"]>(contract: TContract, workflowName: TWorkflowName): Record<string, ActivityDefinition>;
26
- /**
27
- * Extract all activity names for a specific workflow from a contract
28
- *
29
- * @param contract - The contract definition
30
- * @param workflowName - The name of the workflow
31
- * @returns Array of activity names (strings) available for the workflow
32
- *
33
- * @example
34
- * ```ts
35
- * const activityNames = getWorkflowActivityNames(myContract, 'processOrder');
36
- * // Returns: ['processPayment', 'reserveInventory', 'sendEmail']
37
- * ```
38
- */
39
- declare function getWorkflowActivityNames<TContract extends ContractDefinition, TWorkflowName extends keyof TContract["workflows"]>(contract: TContract, workflowName: TWorkflowName): string[];
40
- /**
41
- * Check if an activity belongs to a specific workflow
42
- *
43
- * @param contract - The contract definition
44
- * @param workflowName - The name of the workflow
45
- * @param activityName - The name of the activity to check
46
- * @returns True if the activity is available for the workflow, false otherwise
47
- *
48
- * @example
49
- * ```ts
50
- * if (isWorkflowActivity(myContract, 'processOrder', 'processPayment')) {
51
- * // Activity is available for this workflow
52
- * }
53
- * ```
54
- */
55
- declare function isWorkflowActivity<TContract extends ContractDefinition, TWorkflowName extends keyof TContract["workflows"]>(contract: TContract, workflowName: TWorkflowName, activityName: string): boolean;
56
- /**
57
- * Get all workflow names from a contract
58
- *
59
- * @param contract - The contract definition
60
- * @returns Array of workflow names defined in the contract
61
- *
62
- * @example
63
- * ```ts
64
- * const workflows = getWorkflowNames(myContract);
65
- * // Returns: ['processOrder', 'processRefund']
66
- * ```
67
- */
68
- declare function getWorkflowNames<TContract extends ContractDefinition>(contract: TContract): Array<keyof TContract["workflows"]>;
69
- //#endregion
70
- //#region src/activity.d.ts
71
- /**
72
- * Activity error class that should be used to wrap all technical exceptions
73
- * Forces proper error handling and enables retry policies
74
- */
75
- declare class ActivityError extends Error {
76
- readonly code: string;
77
- constructor(code: string, message: string, cause?: unknown);
78
- }
79
- /**
80
- * Activity implementation using Future/Result pattern
81
- *
82
- * Returns Future<Result<Output, ActivityError>> for explicit error handling instead of throwing exceptions.
83
- * All errors must be wrapped in ActivityError to enable proper retry policies.
84
- */
85
- type BoxedActivityImplementation<TActivity extends ActivityDefinition> = (args: WorkerInferInput<TActivity>) => Future<Result<WorkerInferOutput<TActivity>, ActivityError>>;
86
- /**
87
- * Map of all activity implementations for a contract (global + all workflow-specific)
88
- */
89
- type ContractBoxedActivitiesImplementations<TContract extends ContractDefinition> = (TContract["activities"] extends Record<string, ActivityDefinition> ? BoxedActivitiesImplementations<TContract["activities"]> : {}) & { [TWorkflow in keyof TContract["workflows"]]: TContract["workflows"][TWorkflow]["activities"] extends Record<string, ActivityDefinition> ? BoxedActivitiesImplementations<TContract["workflows"][TWorkflow]["activities"]> : {} };
90
- type BoxedActivitiesImplementations<TActivities extends Record<string, ActivityDefinition>> = { [K in keyof TActivities]: BoxedActivityImplementation<TActivities[K]> };
91
- /**
92
- * Options for creating activities handler
93
- */
94
- interface DeclareActivitiesHandlerOptions<TContract extends ContractDefinition> {
95
- contract: TContract;
96
- activities: ContractBoxedActivitiesImplementations<TContract>;
97
- }
98
- type ActivityImplementation<TActivity extends ActivityDefinition> = (args: WorkerInferInput<TActivity>) => Promise<WorkerInferOutput<TActivity>>;
99
- type ActivitiesImplementations<TActivities extends Record<string, ActivityDefinition>> = { [K in keyof TActivities]: ActivityImplementation<TActivities[K]> };
100
- type UnionToIntersection<U> = (U extends unknown ? (k: U) => void : never) extends ((k: infer I) => void) ? I : never;
101
- /**
102
- * Activities handler ready for Temporal Worker
103
- *
104
- * Flat structure: all activities (global + all workflow-specific) are at the root level
105
- */
106
- type ActivitiesHandler<TContract extends ContractDefinition> = (TContract["activities"] extends Record<string, ActivityDefinition> ? ActivitiesImplementations<TContract["activities"]> : {}) & UnionToIntersection<{ [TWorkflow in keyof TContract["workflows"]]: TContract["workflows"][TWorkflow]["activities"] extends Record<string, ActivityDefinition> ? ActivitiesImplementations<TContract["workflows"][TWorkflow]["activities"]> : {} }[keyof TContract["workflows"]]>;
107
- /**
108
- * Create a typed activities handler with automatic validation and Result pattern
109
- *
110
- * This wraps all activity implementations with:
111
- * - Validation at network boundaries
112
- * - Result<T, ActivityError> pattern for explicit error handling
113
- * - Automatic conversion from Result to Promise (throwing on Error)
114
- *
115
- * TypeScript ensures ALL activities (global + workflow-specific) are implemented.
116
- *
117
- * Use this to create the activities object for the Temporal Worker.
118
- *
119
- * @example
120
- * ```ts
121
- * import { declareActivitiesHandler, ActivityError } from '@temporal-contract/worker/activity';
122
- * import { Result, Future } from '@swan-io/boxed';
123
- * import myContract from './contract';
124
- *
125
- * export const activities = declareActivitiesHandler({
126
- * contract: myContract,
127
- * activities: {
128
- * // Activity returns Result instead of throwing
129
- * // All technical exceptions must be wrapped in ActivityError for retry policies
130
- * sendEmail: (args) => {
131
- * return Future.make(async resolve => {
132
- * try {
133
- * await emailService.send(args);
134
- * resolve(Result.Ok({ sent: true }));
135
- * } catch (error) {
136
- * // Wrap technical errors in ActivityError to enable retries
137
- * resolve(Result.Error(
138
- * new ActivityError(
139
- * 'EMAIL_SEND_FAILED',
140
- * 'Failed to send email',
141
- * error // Original error as cause for debugging
142
- * )
143
- * ));
144
- * }
145
- * });
146
- * },
147
- * },
148
- * });
149
- *
150
- * // Use with Temporal Worker
151
- * import { Worker } from '@temporalio/worker';
152
- *
153
- * const worker = await Worker.create({
154
- * workflowsPath: require.resolve('./workflows'),
155
- * activities: activities,
156
- * taskQueue: contract.taskQueue,
157
- * });
158
- * ```
159
- */
160
- declare function declareActivitiesHandler<TContract extends ContractDefinition>(options: DeclareActivitiesHandlerOptions<TContract>): ActivitiesHandler<TContract>;
161
- //#endregion
162
- export { getWorkflowActivityNames as a, getWorkflowActivities as i, ActivityError as n, getWorkflowNames as o, declareActivitiesHandler as r, isWorkflowActivity as s, ActivitiesHandler as t };