@temporal-contract/worker 0.1.0 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1 @@
1
+ {"version":3,"file":"worker.d.mts","names":[],"sources":["../src/worker.ts"],"mappings":";;;;;;;AASA;KAAY,mBAAA,mBAAsC,kBAAA,IAAsB,IAAA,CACtE,aAAA;EAD6B;;;EAO7B,QAAA,EAAU,SAAA;EAAA;;;EAKV,UAAA,EAAY,iBAAA,CAAkB,SAAA;AAAA;;;;;;;;;;;;AA+BhC;;;;;;;;;;;;;;;;;iBAAsB,YAAA,mBAA+B,kBAAA,CAAA,CACnD,OAAA,EAAS,mBAAA,CAAoB,SAAA,IAC5B,OAAA,CAAQ,MAAA;;AAkCX;;;;;;;;;;;;;;;;;;;;;;iBAAgB,oBAAA,CAAqB,OAAA,UAAiB,YAAA"}
package/dist/worker.mjs CHANGED
@@ -1,7 +1,5 @@
1
1
  import { Worker } from "@temporalio/worker";
2
2
  import { fileURLToPath } from "node:url";
3
- import { extname } from "node:path";
4
-
5
3
  //#region src/worker.ts
6
4
  /**
7
5
  * Create a typed Temporal worker with contract-based configuration
@@ -40,9 +38,14 @@ async function createWorker(options) {
40
38
  });
41
39
  }
42
40
  /**
43
- * Helper to create a workflowsPath from a file URL
41
+ * Helper to resolve a workflow file path relative to the current module's URL.
42
+ *
43
+ * Useful when using ES modules (`import.meta.url`) to locate workflow files.
44
+ * The `relativePath` should include the file extension explicitly (e.g. `./workflows.js`)
45
+ * to ensure the resolved path is unambiguous in both source and built contexts.
44
46
  *
45
- * Useful for creating the workflowsPath option when using ES modules
47
+ * @param baseURL - The base URL to resolve from, typically `import.meta.url`
48
+ * @param relativePath - Relative path to the workflows file, **including extension**
46
49
  *
47
50
  * @example
48
51
  * ```ts
@@ -51,14 +54,16 @@ async function createWorker(options) {
51
54
  * const worker = await createWorker({
52
55
  * contract: myContract,
53
56
  * connection,
54
- * workflowsPath: workflowsPathFromURL(import.meta.url, './workflows'),
57
+ * // Include the extension explicitly to work in both source (.ts) and build (.js) contexts
58
+ * workflowsPath: workflowsPathFromURL(import.meta.url, './workflows.js'),
55
59
  * activities,
56
60
  * });
57
61
  * ```
58
62
  */
59
63
  function workflowsPathFromURL(baseURL, relativePath) {
60
- return fileURLToPath(new URL(`${relativePath}${extname(baseURL)}`, baseURL));
64
+ return fileURLToPath(new URL(relativePath, baseURL));
61
65
  }
62
-
63
66
  //#endregion
64
- export { createWorker, workflowsPathFromURL };
67
+ export { createWorker, workflowsPathFromURL };
68
+
69
+ //# sourceMappingURL=worker.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"worker.mjs","names":[],"sources":["../src/worker.ts"],"sourcesContent":["// Entry point for worker creation utilities\nimport { ContractDefinition } from \"@temporal-contract/contract\";\nimport { Worker, WorkerOptions } from \"@temporalio/worker\";\nimport { fileURLToPath } from \"node:url\";\nimport type { ActivitiesHandler } from \"./activity.js\";\n\n/**\n * Options for creating a Temporal worker\n */\nexport type CreateWorkerOptions<TContract extends ContractDefinition> = Omit<\n WorkerOptions,\n \"activities\" | \"taskQueue\"\n> & {\n /**\n * The contract definition for this worker\n */\n contract: TContract;\n\n /**\n * Activities handler for this worker\n */\n activities: ActivitiesHandler<TContract>;\n};\n\n/**\n * Create a typed Temporal worker with contract-based configuration\n *\n * This helper simplifies worker creation by:\n * - Using the contract's task queue automatically\n * - Providing type-safe configuration\n *\n * @example\n * ```ts\n * import { NativeConnection } from '@temporalio/worker';\n * import { createWorker } from '@temporal-contract/worker/worker';\n * import { activities } from './activities';\n * import myContract from './contract';\n *\n * const connection = await NativeConnection.connect({\n * address: 'localhost:7233',\n * });\n *\n * const worker = await createWorker({\n * contract: myContract,\n * connection,\n * workflowsPath: require.resolve('./workflows'),\n * activities,\n * });\n *\n * await worker.run();\n * ```\n */\nexport async function createWorker<TContract extends ContractDefinition>(\n options: CreateWorkerOptions<TContract>,\n): Promise<Worker> {\n const { contract, activities, ...workerOptions } = options;\n\n // Create the worker with contract's task queue\n return await Worker.create({\n ...workerOptions,\n activities,\n taskQueue: contract.taskQueue,\n });\n}\n\n/**\n * Helper to resolve a workflow file path relative to the current module's URL.\n *\n * Useful when using ES modules (`import.meta.url`) to locate workflow files.\n * The `relativePath` should include the file extension explicitly (e.g. `./workflows.js`)\n * to ensure the resolved path is unambiguous in both source and built contexts.\n *\n * @param baseURL - The base URL to resolve from, typically `import.meta.url`\n * @param relativePath - Relative path to the workflows file, **including extension**\n *\n * @example\n * ```ts\n * import { workflowsPathFromURL } from '@temporal-contract/worker/worker';\n *\n * const worker = await createWorker({\n * contract: myContract,\n * connection,\n * // Include the extension explicitly to work in both source (.ts) and build (.js) contexts\n * workflowsPath: workflowsPathFromURL(import.meta.url, './workflows.js'),\n * activities,\n * });\n * ```\n */\nexport function workflowsPathFromURL(baseURL: string, relativePath: string): string {\n return fileURLToPath(new URL(relativePath, baseURL));\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAoDA,eAAsB,aACpB,SACiB;CACjB,MAAM,EAAE,UAAU,YAAY,GAAG,kBAAkB;AAGnD,QAAO,MAAM,OAAO,OAAO;EACzB,GAAG;EACH;EACA,WAAW,SAAS;EACrB,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;AA0BJ,SAAgB,qBAAqB,SAAiB,cAA8B;AAClF,QAAO,cAAc,IAAI,IAAI,cAAc,QAAQ,CAAC"}
package/dist/workflow.cjs CHANGED
@@ -1,7 +1,148 @@
1
- const require_errors = require('./errors-DjSZg-93.cjs');
2
- let _temporal_contract_boxed = require("@temporal-contract/boxed");
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ const require_internal = require("./internal-Tj4m4f_K.cjs");
3
3
  let _temporalio_workflow = require("@temporalio/workflow");
4
-
4
+ let _temporal_contract_boxed = require("@temporal-contract/boxed");
5
+ //#region src/cancellation.ts
6
+ /**
7
+ * Typed wrappers around Temporal's `CancellationScope` so workflows can
8
+ * opt into cancellation control without reaching for
9
+ * `@temporalio/workflow` directly. The wrappers fold cancellation into
10
+ * the same `Future<Result<...>>` shape used elsewhere in the worker
11
+ * context — callers branch on `Result.Error(WorkflowCancelledError)`
12
+ * instead of catching `CancelledFailure`.
13
+ *
14
+ * Non-cancellation errors thrown inside the scope are *not* swallowed:
15
+ * the Future rejects with the original error so user-domain failures
16
+ * keep their identity.
17
+ */
18
+ /**
19
+ * Run `fn` inside a cancellable Temporal scope. If the workflow (or an
20
+ * ancestor scope) is cancelled while the function is in flight, the
21
+ * resulting Future resolves to `Result.Error(WorkflowCancelledError)`,
22
+ * letting callers handle cancellation explicitly — typically to perform
23
+ * a graceful exit from the current step.
24
+ *
25
+ * @example
26
+ * ```ts
27
+ * const result = await context.cancellableScope(async () => {
28
+ * return await context.activities.processStep(...);
29
+ * });
30
+ *
31
+ * result.match({
32
+ * Ok: (output) => { ... },
33
+ * Error: (err) => {
34
+ * // err instanceof WorkflowCancelledError — graceful exit
35
+ * },
36
+ * });
37
+ * ```
38
+ */
39
+ function cancellableScope(fn) {
40
+ return _temporal_contract_boxed.Future.fromAsync(async () => {
41
+ try {
42
+ const value = await _temporalio_workflow.CancellationScope.cancellable(async () => fn());
43
+ return _temporal_contract_boxed.Result.Ok(value);
44
+ } catch (error) {
45
+ if ((0, _temporalio_workflow.isCancellation)(error)) return _temporal_contract_boxed.Result.Error(new require_internal.WorkflowCancelledError(error));
46
+ throw error;
47
+ }
48
+ });
49
+ }
50
+ /**
51
+ * Run `fn` inside a non-cancellable Temporal scope. Cancellation requests
52
+ * from outside the scope are ignored for its duration — the idiomatic way
53
+ * to perform cleanup that must not be interrupted (e.g. releasing a
54
+ * resource after a graceful shutdown).
55
+ *
56
+ * Mirrors `cancellableScope`'s `Future<Result<...>>` shape for symmetry;
57
+ * the `Result.Error` branch only triggers when cancellation is raised
58
+ * from inside the scope (rare).
59
+ *
60
+ * @example
61
+ * ```ts
62
+ * await context.nonCancellableScope(async () => {
63
+ * await context.activities.releaseResources(...);
64
+ * });
65
+ * ```
66
+ */
67
+ function nonCancellableScope(fn) {
68
+ return _temporal_contract_boxed.Future.fromAsync(async () => {
69
+ try {
70
+ const value = await _temporalio_workflow.CancellationScope.nonCancellable(async () => fn());
71
+ return _temporal_contract_boxed.Result.Ok(value);
72
+ } catch (error) {
73
+ if ((0, _temporalio_workflow.isCancellation)(error)) return _temporal_contract_boxed.Result.Error(new require_internal.WorkflowCancelledError(error));
74
+ throw error;
75
+ }
76
+ });
77
+ }
78
+ //#endregion
79
+ //#region src/handlers.ts
80
+ /**
81
+ * Bind a typed signal handler to the running workflow. Validates the
82
+ * signal payload against the contract's input schema before invoking the
83
+ * user-supplied handler.
84
+ *
85
+ * The runtime guard against a missing `signals` block — and an unknown
86
+ * signal name within it — covers the union-typed-`workflowName` case
87
+ * where the type system's keyset constraint collapses; without the
88
+ * check, a caller would see `Cannot read properties of undefined`
89
+ * instead of a controlled error.
90
+ */
91
+ function bindSignalHandler(workflowDefinition, workflowName, signalName, handler) {
92
+ if (!workflowDefinition.signals) throw new Error(`Signal "${signalName}" cannot be defined: workflow "${workflowName}" has no signals in its contract`);
93
+ const signalDef = workflowDefinition.signals[signalName];
94
+ if (!signalDef) throw new Error(`Signal "${signalName}" not found in workflow "${workflowName}" contract`);
95
+ (0, _temporalio_workflow.setHandler)((0, _temporalio_workflow.defineSignal)(signalName), async (...args) => {
96
+ const input = require_internal.extractHandlerInput(args);
97
+ const inputResult = await signalDef.input["~standard"].validate(input);
98
+ if (inputResult.issues) throw new require_internal.SignalInputValidationError(signalName, inputResult.issues);
99
+ await handler(inputResult.value);
100
+ });
101
+ }
102
+ /**
103
+ * Bind a typed query handler to the running workflow. Validates input
104
+ * and output against the contract synchronously.
105
+ *
106
+ * Temporal's query API requires a synchronous handler — async
107
+ * validation breaks replay determinism. The handler trips a clear error
108
+ * if the schema library returns a Promise from `validate(...)`, instead
109
+ * of letting the async path silently corrupt query semantics.
110
+ */
111
+ function bindQueryHandler(workflowDefinition, workflowName, queryName, handler) {
112
+ if (!workflowDefinition.queries) throw new Error(`Query "${queryName}" cannot be defined: workflow "${workflowName}" has no queries in its contract`);
113
+ const queryDef = workflowDefinition.queries[queryName];
114
+ if (!queryDef) throw new Error(`Query "${queryName}" not found in workflow "${workflowName}" contract`);
115
+ (0, _temporalio_workflow.setHandler)((0, _temporalio_workflow.defineQuery)(queryName), (...args) => {
116
+ const input = require_internal.extractHandlerInput(args);
117
+ const inputResult = queryDef.input["~standard"].validate(input);
118
+ if (inputResult instanceof Promise) throw new Error(`Query "${queryName}" validation must be synchronous. Use a schema library that supports synchronous validation for queries.`);
119
+ if (inputResult.issues) throw new require_internal.QueryInputValidationError(queryName, inputResult.issues);
120
+ const result = handler(inputResult.value);
121
+ const outputResult = queryDef.output["~standard"].validate(result);
122
+ if (outputResult instanceof Promise) throw new Error(`Query "${queryName}" output validation must be synchronous. Use a schema library that supports synchronous validation for queries.`);
123
+ if (outputResult.issues) throw new require_internal.QueryOutputValidationError(queryName, outputResult.issues);
124
+ return outputResult.value;
125
+ });
126
+ }
127
+ /**
128
+ * Bind a typed update handler to the running workflow. Validates both
129
+ * input and output (asynchronously, like signals).
130
+ */
131
+ function bindUpdateHandler(workflowDefinition, workflowName, updateName, handler) {
132
+ if (!workflowDefinition.updates) throw new Error(`Update "${updateName}" cannot be defined: workflow "${workflowName}" has no updates in its contract`);
133
+ const updateDef = workflowDefinition.updates[updateName];
134
+ if (!updateDef) throw new Error(`Update "${updateName}" not found in workflow "${workflowName}" contract`);
135
+ (0, _temporalio_workflow.setHandler)((0, _temporalio_workflow.defineUpdate)(updateName), async (...args) => {
136
+ const input = require_internal.extractHandlerInput(args);
137
+ const inputResult = await updateDef.input["~standard"].validate(input);
138
+ if (inputResult.issues) throw new require_internal.UpdateInputValidationError(updateName, inputResult.issues);
139
+ const result = await handler(inputResult.value);
140
+ const outputResult = await updateDef.output["~standard"].validate(result);
141
+ if (outputResult.issues) throw new require_internal.UpdateOutputValidationError(updateName, outputResult.issues);
142
+ return outputResult.value;
143
+ });
144
+ }
145
+ //#endregion
5
146
  //#region src/workflow.ts
6
147
  /**
7
148
  * Create a typed workflow implementation with automatic validation
@@ -17,200 +158,88 @@ let _temporalio_workflow = require("@temporalio/workflow");
17
158
  * @example
18
159
  * ```ts
19
160
  * // workflows/processOrder.ts
20
- * import { declareWorkflow } from '@temporal-contract/worker';
161
+ * import { declareWorkflow } from '@temporal-contract/worker/workflow';
21
162
  * import myContract from '../contract';
22
163
  *
23
164
  * export const processOrder = declareWorkflow({
24
165
  * workflowName: 'processOrder',
25
166
  * contract: myContract,
26
- * implementation: async (context, orderId, customerId) => {
167
+ * activityOptions: {
168
+ * startToCloseTimeout: '1 minute',
169
+ * },
170
+ * // Optional: override `activityOptions` for specific activities. Each
171
+ * // entry shallow-merges over the workflow default — the override wins on
172
+ * // every property it specifies, including the whole `retry` block.
173
+ * activityOptionsByName: {
174
+ * chargePayment: {
175
+ * startToCloseTimeout: '5 minutes',
176
+ * retry: { maximumAttempts: 5 },
177
+ * },
178
+ * },
179
+ * implementation: async (context, args) => {
27
180
  * // context.activities: typed activities (workflow + global)
28
181
  * // context.info: WorkflowInfo
29
182
  *
30
- * const inventory = await context.activities.validateInventory(orderId);
183
+ * const inventory = await context.activities.validateInventory({
184
+ * orderId: args.orderId,
185
+ * });
31
186
  *
32
187
  * if (!inventory.available) {
33
- * throw new Error('Out of stock');
188
+ * return { orderId: args.orderId, status: 'out_of_stock' };
34
189
  * }
35
190
  *
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
- * );
191
+ * const payment = await context.activities.chargePayment({
192
+ * customerId: args.customerId,
193
+ * amount: 100,
194
+ * });
44
195
  *
45
196
  * return {
46
- * orderId,
197
+ * orderId: args.orderId,
47
198
  * status: payment.success ? 'success' : 'failed',
48
199
  * transactionId: payment.transactionId,
49
200
  * };
50
201
  * },
51
- * activityOptions: {
52
- * startToCloseTimeout: '1 minute',
53
- * },
54
202
  * });
55
203
  * ```
56
204
  *
57
205
  * Then in your worker setup:
58
206
  * ```ts
59
207
  * // worker.ts
60
- * import { Worker } from '@temporalio/worker';
61
- * import { activitiesHandler } from './activities';
208
+ * import { createWorker } from '@temporal-contract/worker/worker';
209
+ * import { activities } from './activities';
210
+ * import myContract from './contract';
62
211
  *
63
- * const worker = await Worker.create({
64
- * workflowsPath: require.resolve('./workflows'), // Imports processOrder
65
- * activities: activitiesHandler.activities,
66
- * taskQueue: activitiesHandler.contract.taskQueue,
212
+ * const worker = await createWorker({
213
+ * contract: myContract,
214
+ * connection,
215
+ * workflowsPath: workflowsPathFromURL(import.meta.url, './workflows.js'),
216
+ * activities,
67
217
  * });
68
218
  * ```
69
219
  */
70
- function declareWorkflow({ workflowName, contract, implementation, activityOptions }) {
220
+ function declareWorkflow({ workflowName, contract, implementation, activityOptions, activityOptionsByName }) {
71
221
  const definition = contract.workflows[workflowName];
72
222
  return async (...args) => {
73
- const input = args.length === 1 ? args[0] : args;
223
+ const input = require_internal.extractHandlerInput(args);
74
224
  const inputResult = await definition.input["~standard"].validate(input);
75
- if (inputResult.issues) throw new require_errors.WorkflowInputValidationError(String(workflowName), inputResult.issues);
225
+ if (inputResult.issues) throw new require_internal.WorkflowInputValidationError(String(workflowName), inputResult.issues);
76
226
  const validatedInput = inputResult.value;
77
227
  let contextActivities = {};
78
- if (definition.activities || contract.activities) contextActivities = createValidatedActivities((0, _temporalio_workflow.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 _temporal_contract_boxed.Result.Error(new require_errors.ChildWorkflowError(`Child workflow "${childWorkflowName}" output validation failed: ${outputResult$1.issues.map((i) => i.message).join("; ")}`));
82
- return _temporal_contract_boxed.Result.Ok(outputResult$1.value);
83
- }
84
- async function getAndValidateChildWorkflow(childContract, childWorkflowName, args$1) {
85
- const childDefinition = childContract.workflows[childWorkflowName];
86
- if (!childDefinition) return _temporal_contract_boxed.Result.Error(new require_errors.ChildWorkflowNotFoundError(String(childWorkflowName), Object.keys(childContract.workflows)));
87
- const inputResult$1 = await childDefinition.input["~standard"].validate(args$1);
88
- if (inputResult$1.issues) return _temporal_contract_boxed.Result.Error(new require_errors.ChildWorkflowError(`Child workflow "${String(childWorkflowName)}" input validation failed: ${inputResult$1.issues.map((i) => i.message).join("; ")}`));
89
- const validatedInput$1 = inputResult$1.value;
90
- return _temporal_contract_boxed.Result.Ok({
91
- definition: childDefinition,
92
- validatedInput: validatedInput$1,
93
- taskQueue: childContract.taskQueue
94
- });
95
- }
96
- function createTypedChildHandle(handle, childDefinition, childWorkflowName) {
97
- return {
98
- workflowId: handle.workflowId,
99
- result: () => {
100
- return _temporal_contract_boxed.Future.make((resolve) => {
101
- (async () => {
102
- try {
103
- resolve(await validateChildWorkflowOutput(childDefinition, await handle.result(), childWorkflowName));
104
- } catch (error) {
105
- resolve(_temporal_contract_boxed.Result.Error(new require_errors.ChildWorkflowError(`Child workflow execution failed: ${error instanceof Error ? error.message : String(error)}`, error)));
106
- }
107
- })();
108
- });
109
- }
110
- };
111
- }
112
- function createStartChildWorkflow(childContract, childWorkflowName, options) {
113
- return _temporal_contract_boxed.Future.make((resolve) => {
114
- (async () => {
115
- const validationResult = await getAndValidateChildWorkflow(childContract, childWorkflowName, options.args);
116
- if (validationResult.isError()) {
117
- resolve(_temporal_contract_boxed.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 (0, _temporalio_workflow.startChild)(childWorkflowName, {
124
- ...temporalOptions,
125
- taskQueue,
126
- args: [validatedInput$1]
127
- }), childDefinition, String(childWorkflowName));
128
- resolve(_temporal_contract_boxed.Result.Ok(typedHandle));
129
- } catch (error) {
130
- resolve(_temporal_contract_boxed.Result.Error(new require_errors.ChildWorkflowError(`Failed to start child workflow: ${error instanceof Error ? error.message : String(error)}`, error)));
131
- }
132
- })();
133
- });
134
- }
135
- function createExecuteChildWorkflow(childContract, childWorkflowName, options) {
136
- return _temporal_contract_boxed.Future.make((resolve) => {
137
- (async () => {
138
- const validationResult = await getAndValidateChildWorkflow(childContract, childWorkflowName, options.args);
139
- if (validationResult.isError()) {
140
- resolve(_temporal_contract_boxed.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 (0, _temporalio_workflow.executeChild)(childWorkflowName, {
147
- ...temporalOptions,
148
- taskQueue,
149
- args: [validatedInput$1]
150
- }), String(childWorkflowName));
151
- if (outputValidationResult.isError()) {
152
- resolve(_temporal_contract_boxed.Result.Error(outputValidationResult.error));
153
- return;
154
- }
155
- resolve(_temporal_contract_boxed.Result.Ok(outputValidationResult.value));
156
- } catch (error) {
157
- resolve(_temporal_contract_boxed.Result.Error(new require_errors.ChildWorkflowError(`Failed to execute child workflow: ${error instanceof Error ? error.message : String(error)}`, error)));
158
- }
159
- })();
160
- });
161
- }
162
- function createDefineSignal(signalName, handler) {
163
- if (!definition.signals) throw new Error(`Signal "${String(signalName)}" cannot be defined: workflow "${String(workflowName)}" has no signals in its contract`);
164
- const signalDef = definition.signals[signalName];
165
- if (!signalDef) throw new Error(`Signal "${String(signalName)}" not found in workflow "${String(workflowName)}" contract`);
166
- (0, _temporalio_workflow.setHandler)((0, _temporalio_workflow.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 require_errors.SignalInputValidationError(signalName, inputResult$1.issues);
170
- await handler(inputResult$1.value);
171
- });
172
- }
173
- function createDefineQuery(queryName, handler) {
174
- if (!definition.queries) throw new Error(`Query "${String(queryName)}" cannot be defined: workflow "${String(workflowName)}" has no queries in its contract`);
175
- const queryDef = definition.queries[queryName];
176
- if (!queryDef) throw new Error(`Query "${String(queryName)}" not found in workflow "${String(workflowName)}" contract`);
177
- (0, _temporalio_workflow.setHandler)((0, _temporalio_workflow.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 require_errors.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 require_errors.QueryOutputValidationError(queryName, outputResult$1.issues);
186
- return outputResult$1.value;
187
- });
188
- }
189
- function createDefineUpdate(updateName, handler) {
190
- if (!definition.updates) throw new Error(`Update "${String(updateName)}" cannot be defined: workflow "${String(workflowName)}" has no updates in its contract`);
191
- const updateDef = definition.updates[updateName];
192
- if (!updateDef) throw new Error(`Update "${String(updateName)}" not found in workflow "${String(workflowName)}" contract`);
193
- (0, _temporalio_workflow.setHandler)((0, _temporalio_workflow.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 require_errors.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 require_errors.UpdateOutputValidationError(updateName, outputResult$1.issues);
200
- return outputResult$1.value;
201
- });
202
- }
228
+ if (definition.activities || contract.activities) contextActivities = createValidatedActivities(require_internal.buildRawActivitiesProxy(definition.activities, contract.activities, activityOptions, activityOptionsByName), definition.activities, contract.activities);
203
229
  const result = await implementation({
204
230
  activities: contextActivities,
205
231
  info: (0, _temporalio_workflow.workflowInfo)(),
206
232
  startChildWorkflow: createStartChildWorkflow,
207
233
  executeChildWorkflow: createExecuteChildWorkflow,
208
- defineSignal: createDefineSignal,
209
- defineQuery: createDefineQuery,
210
- defineUpdate: createDefineUpdate
234
+ cancellableScope,
235
+ nonCancellableScope,
236
+ defineSignal: ((signalName, handler) => bindSignalHandler(definition, String(workflowName), signalName, handler)),
237
+ defineQuery: ((queryName, handler) => bindQueryHandler(definition, String(workflowName), queryName, handler)),
238
+ defineUpdate: ((updateName, handler) => bindUpdateHandler(definition, String(workflowName), updateName, handler)),
239
+ continueAsNew: require_internal.createContinueAsNew(contract, workflowName)
211
240
  }, validatedInput);
212
241
  const outputResult = await definition.output["~standard"].validate(result);
213
- if (outputResult.issues) throw new require_errors.WorkflowOutputValidationError(String(workflowName), outputResult.issues);
242
+ if (outputResult.issues) throw new require_internal.WorkflowOutputValidationError(String(workflowName), outputResult.issues);
214
243
  return outputResult.value;
215
244
  };
216
245
  }
@@ -231,26 +260,94 @@ function createValidatedActivities(rawActivities, workflowActivitiesDefinition,
231
260
  if (!rawActivity) throw new Error(`Activity implementation not found for: "${activityName}". Available activities: ${Object.keys(rawActivities).length > 0 ? Object.keys(rawActivities).join(", ") : "none"}`);
232
261
  validatedActivities[activityName] = async (input) => {
233
262
  const inputResult = await activityDef.input["~standard"].validate(input);
234
- if (inputResult.issues) throw new require_errors.ActivityInputValidationError(activityName, inputResult.issues);
263
+ if (inputResult.issues) throw new require_internal.ActivityInputValidationError(activityName, inputResult.issues);
235
264
  const result = await rawActivity(inputResult.value);
236
265
  const outputResult = await activityDef.output["~standard"].validate(result);
237
- if (outputResult.issues) throw new require_errors.ActivityOutputValidationError(activityName, outputResult.issues);
266
+ if (outputResult.issues) throw new require_internal.ActivityOutputValidationError(activityName, outputResult.issues);
238
267
  return outputResult.value;
239
268
  };
240
269
  }
241
270
  return validatedActivities;
242
271
  }
243
-
272
+ async function validateChildWorkflowOutput(childDefinition, result, childWorkflowName) {
273
+ const outputResult = await childDefinition.output["~standard"].validate(result);
274
+ if (outputResult.issues) return _temporal_contract_boxed.Result.Error(new require_internal.ChildWorkflowError(require_internal.formatChildWorkflowValidationMessage(childWorkflowName, "output", outputResult.issues)));
275
+ return _temporal_contract_boxed.Result.Ok(outputResult.value);
276
+ }
277
+ async function getAndValidateChildWorkflow(childContract, childWorkflowName, args) {
278
+ const childDefinition = childContract.workflows[childWorkflowName];
279
+ if (!childDefinition) return _temporal_contract_boxed.Result.Error(new require_internal.ChildWorkflowNotFoundError(String(childWorkflowName), Object.keys(childContract.workflows)));
280
+ const inputResult = await childDefinition.input["~standard"].validate(args);
281
+ if (inputResult.issues) return _temporal_contract_boxed.Result.Error(new require_internal.ChildWorkflowError(require_internal.formatChildWorkflowValidationMessage(String(childWorkflowName), "input", inputResult.issues)));
282
+ const validatedInput = inputResult.value;
283
+ return _temporal_contract_boxed.Result.Ok({
284
+ definition: childDefinition,
285
+ validatedInput,
286
+ taskQueue: childContract.taskQueue
287
+ });
288
+ }
289
+ function createTypedChildHandle(handle, childDefinition, childWorkflowName) {
290
+ return {
291
+ workflowId: handle.workflowId,
292
+ result: () => {
293
+ return _temporal_contract_boxed.Future.fromAsync(async () => {
294
+ try {
295
+ return validateChildWorkflowOutput(childDefinition, await handle.result(), childWorkflowName);
296
+ } catch (error) {
297
+ return _temporal_contract_boxed.Result.Error(new require_internal.ChildWorkflowError(`Child workflow execution failed: ${error instanceof Error ? error.message : String(error)}`, error));
298
+ }
299
+ });
300
+ }
301
+ };
302
+ }
303
+ function createStartChildWorkflow(childContract, childWorkflowName, options) {
304
+ return _temporal_contract_boxed.Future.fromAsync(async () => {
305
+ const validationResult = await getAndValidateChildWorkflow(childContract, childWorkflowName, options.args);
306
+ if (validationResult.isError()) return _temporal_contract_boxed.Result.Error(validationResult.error);
307
+ const { definition: childDefinition, validatedInput, taskQueue } = validationResult.value;
308
+ try {
309
+ const { args: _args, ...temporalOptions } = options;
310
+ const typedHandle = createTypedChildHandle(await (0, _temporalio_workflow.startChild)(childWorkflowName, {
311
+ ...temporalOptions,
312
+ taskQueue,
313
+ args: [validatedInput]
314
+ }), childDefinition, String(childWorkflowName));
315
+ return _temporal_contract_boxed.Result.Ok(typedHandle);
316
+ } catch (error) {
317
+ return _temporal_contract_boxed.Result.Error(new require_internal.ChildWorkflowError(`Failed to start child workflow: ${error instanceof Error ? error.message : String(error)}`, error));
318
+ }
319
+ });
320
+ }
321
+ function createExecuteChildWorkflow(childContract, childWorkflowName, options) {
322
+ return _temporal_contract_boxed.Future.fromAsync(async () => {
323
+ const validationResult = await getAndValidateChildWorkflow(childContract, childWorkflowName, options.args);
324
+ if (validationResult.isError()) return _temporal_contract_boxed.Result.Error(validationResult.error);
325
+ const { definition: childDefinition, validatedInput, taskQueue } = validationResult.value;
326
+ try {
327
+ const { args: _args, ...temporalOptions } = options;
328
+ const outputValidationResult = await validateChildWorkflowOutput(childDefinition, await (0, _temporalio_workflow.executeChild)(childWorkflowName, {
329
+ ...temporalOptions,
330
+ taskQueue,
331
+ args: [validatedInput]
332
+ }), String(childWorkflowName));
333
+ if (outputValidationResult.isError()) return _temporal_contract_boxed.Result.Error(outputValidationResult.error);
334
+ return _temporal_contract_boxed.Result.Ok(outputValidationResult.value);
335
+ } catch (error) {
336
+ return _temporal_contract_boxed.Result.Error(new require_internal.ChildWorkflowError(`Failed to execute child workflow: ${error instanceof Error ? error.message : String(error)}`, error));
337
+ }
338
+ });
339
+ }
244
340
  //#endregion
245
- exports.ActivityInputValidationError = require_errors.ActivityInputValidationError;
246
- exports.ActivityOutputValidationError = require_errors.ActivityOutputValidationError;
247
- exports.ChildWorkflowError = require_errors.ChildWorkflowError;
248
- exports.ChildWorkflowNotFoundError = require_errors.ChildWorkflowNotFoundError;
249
- exports.QueryInputValidationError = require_errors.QueryInputValidationError;
250
- exports.QueryOutputValidationError = require_errors.QueryOutputValidationError;
251
- exports.SignalInputValidationError = require_errors.SignalInputValidationError;
252
- exports.UpdateInputValidationError = require_errors.UpdateInputValidationError;
253
- exports.UpdateOutputValidationError = require_errors.UpdateOutputValidationError;
254
- exports.WorkflowInputValidationError = require_errors.WorkflowInputValidationError;
255
- exports.WorkflowOutputValidationError = require_errors.WorkflowOutputValidationError;
256
- exports.declareWorkflow = declareWorkflow;
341
+ exports.ActivityInputValidationError = require_internal.ActivityInputValidationError;
342
+ exports.ActivityOutputValidationError = require_internal.ActivityOutputValidationError;
343
+ exports.ChildWorkflowError = require_internal.ChildWorkflowError;
344
+ exports.ChildWorkflowNotFoundError = require_internal.ChildWorkflowNotFoundError;
345
+ exports.QueryInputValidationError = require_internal.QueryInputValidationError;
346
+ exports.QueryOutputValidationError = require_internal.QueryOutputValidationError;
347
+ exports.SignalInputValidationError = require_internal.SignalInputValidationError;
348
+ exports.UpdateInputValidationError = require_internal.UpdateInputValidationError;
349
+ exports.UpdateOutputValidationError = require_internal.UpdateOutputValidationError;
350
+ exports.WorkflowCancelledError = require_internal.WorkflowCancelledError;
351
+ exports.WorkflowInputValidationError = require_internal.WorkflowInputValidationError;
352
+ exports.WorkflowOutputValidationError = require_internal.WorkflowOutputValidationError;
353
+ exports.declareWorkflow = declareWorkflow;