@temporal-contract/worker 0.0.3 → 0.0.5

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.
@@ -1,302 +0,0 @@
1
- import { ActivityOptions, WorkflowInfo } from "@temporalio/workflow";
2
- import { ActivityDefinition, ContractDefinition, QueryDefinition, SignalDefinition, UpdateDefinition, WorkerInferInput, WorkerInferOutput, WorkerInferWorkflowContextActivities } from "@temporal-contract/contract";
3
- import { StandardSchemaV1 } from "@standard-schema/spec";
4
-
5
- //#region src/handler.d.ts
6
-
7
- /**
8
- * Workflow context with typed activities (workflow + global) and workflow info
9
- * Note: activities is typed as 'any' to work around TypeScript generic type inference limitations with Zod tuples
10
- */
11
- interface WorkflowContext<TContract extends ContractDefinition, TWorkflowName extends keyof TContract["workflows"]> {
12
- activities: WorkerInferWorkflowContextActivities<TContract, TWorkflowName>;
13
- info: WorkflowInfo;
14
- }
15
- /**
16
- * Workflow implementation function (receives context + typed args as tuple)
17
- * Note: We use 'any' for args to work around TypeScript limitations with generic Zod tuple inference
18
- * The actual type will be enforced at runtime by Zod validation
19
- */
20
- type WorkflowImplementation<TContract extends ContractDefinition, TWorkflowName extends keyof TContract["workflows"]> = (context: WorkflowContext<TContract, TWorkflowName>, args: WorkerInferInput<TContract["workflows"][TWorkflowName]>) => Promise<WorkerInferOutput<TContract["workflows"][TWorkflowName]>>;
21
- /**
22
- * Raw activity implementation function (receives typed args as tuple)
23
- * Note: We use 'any' for args/return to work around TypeScript limitations with generic Zod tuple inference
24
- * The actual types will be enforced at runtime by Zod validation
25
- */
26
- type RawActivityImplementation<TActivity extends ActivityDefinition> = (args: WorkerInferInput<TActivity>) => Promise<WorkerInferOutput<TActivity>>;
27
- /**
28
- * Signal handler implementation
29
- */
30
- type SignalHandlerImplementation<TSignal extends SignalDefinition> = (args: WorkerInferInput<TSignal>) => void | Promise<void>;
31
- /**
32
- * Query handler implementation
33
- */
34
- type QueryHandlerImplementation<TQuery extends QueryDefinition> = (args: WorkerInferInput<TQuery>) => WorkerInferOutput<TQuery>;
35
- /**
36
- * Update handler implementation
37
- */
38
- type UpdateHandlerImplementation<TUpdate extends UpdateDefinition> = (args: WorkerInferInput<TUpdate>) => Promise<WorkerInferOutput<TUpdate>>;
39
- /**
40
- * Map of all activity implementations for a contract (global + all workflow-specific)
41
- */
42
- type ActivityImplementations<T extends ContractDefinition> = (T["activities"] extends Record<string, ActivityDefinition> ? { [K in keyof T["activities"]]: RawActivityImplementation<T["activities"][K]> } : {}) & UnionToIntersection<{ [K in keyof T["workflows"]]: T["workflows"][K]["activities"] extends Record<string, ActivityDefinition> ? { [A in keyof T["workflows"][K]["activities"]]: RawActivityImplementation<T["workflows"][K]["activities"][A]> } : {} }[keyof T["workflows"]]>;
43
- /**
44
- * Utility type to convert union to intersection
45
- */
46
- type UnionToIntersection<U> = (U extends unknown ? (k: U) => void : never) extends ((k: infer I) => void) ? I : never;
47
- /**
48
- * Options for creating activities handler
49
- */
50
- interface DeclareActivitiesHandlerOptions<T extends ContractDefinition> {
51
- contract: T;
52
- activities: ActivityImplementations<T>;
53
- }
54
- /**
55
- * Activities handler ready for Temporal Worker
56
- */
57
- interface ActivitiesHandler<T extends ContractDefinition> {
58
- contract: T;
59
- activities: Record<string, (...args: unknown[]) => Promise<unknown>>;
60
- }
61
- /**
62
- * Options for declaring a workflow implementation
63
- */
64
- interface DeclareWorkflowOptions<TContract extends ContractDefinition, TWorkflowName extends keyof TContract["workflows"]> {
65
- workflowName: TWorkflowName;
66
- contract: TContract;
67
- implementation: WorkflowImplementation<TContract, TWorkflowName>;
68
- /**
69
- * Default activity options applied to all activities in this workflow.
70
- * These will be merged with the default startToCloseTimeout of 60 seconds.
71
- * For more control, you can override specific Temporal ActivityOptions like:
72
- * - startToCloseTimeout: Maximum time for activity execution
73
- * - scheduleToCloseTimeout: End-to-end timeout including queuing
74
- * - scheduleToStartTimeout: Maximum time activity can wait in queue
75
- * - heartbeatTimeout: Time between heartbeats before considering activity dead
76
- * - retry: Retry policy for failed activities
77
- *
78
- * @example
79
- * ```ts
80
- * activityOptions: {
81
- * startToCloseTimeout: '5m',
82
- * retry: { maximumAttempts: 3 }
83
- * }
84
- * ```
85
- */
86
- activityOptions?: ActivityOptions;
87
- /**
88
- * Signal handlers (if defined in workflow)
89
- */
90
- signals?: TContract["workflows"][TWorkflowName]["signals"] extends Record<string, SignalDefinition> ? { [K in keyof TContract["workflows"][TWorkflowName]["signals"]]: SignalHandlerImplementation<TContract["workflows"][TWorkflowName]["signals"][K]> } : never;
91
- /**
92
- * Query handlers (if defined in workflow)
93
- */
94
- queries?: TContract["workflows"][TWorkflowName]["queries"] extends Record<string, QueryDefinition> ? { [K in keyof TContract["workflows"][TWorkflowName]["queries"]]: QueryHandlerImplementation<TContract["workflows"][TWorkflowName]["queries"][K]> } : never;
95
- /**
96
- * Update handlers (if defined in workflow)
97
- */
98
- updates?: TContract["workflows"][TWorkflowName]["updates"] extends Record<string, UpdateDefinition> ? { [K in keyof TContract["workflows"][TWorkflowName]["updates"]]: UpdateHandlerImplementation<TContract["workflows"][TWorkflowName]["updates"][K]> } : never;
99
- }
100
- /**
101
- * Create a typed activities handler with automatic validation
102
- *
103
- * This wraps all activity implementations with Zod validation at network boundaries.
104
- * TypeScript ensures ALL activities (global + workflow-specific) are implemented.
105
- *
106
- * Use this to create the activities object for the Temporal Worker.
107
- *
108
- * @example
109
- * ```ts
110
- * import { declareActivitiesHandler } from '@temporal-contract/worker';
111
- * import myContract from './contract';
112
- *
113
- * export const activitiesHandler = declareActivitiesHandler({
114
- * contract: myContract,
115
- * activities: {
116
- * // Global activities
117
- * sendEmail: async (to, subject, body) => {
118
- * await emailService.send({ to, subject, body });
119
- * return { sent: true };
120
- * },
121
- * // Workflow-specific activities
122
- * validateInventory: async (orderId) => {
123
- * const available = await inventory.check(orderId);
124
- * return { available };
125
- * },
126
- * },
127
- * });
128
- *
129
- * // Use with Temporal Worker
130
- * import { Worker } from '@temporalio/worker';
131
- *
132
- * const worker = await Worker.create({
133
- * workflowsPath: require.resolve('./workflows'),
134
- * activities: activitiesHandler.activities,
135
- * taskQueue: activitiesHandler.contract.taskQueue,
136
- * });
137
- * ```
138
- */
139
- declare function declareActivitiesHandler<T extends ContractDefinition>(options: DeclareActivitiesHandlerOptions<T>): ActivitiesHandler<T>;
140
- /**
141
- * Create a typed workflow implementation with automatic validation
142
- *
143
- * This wraps a workflow implementation with:
144
- * - Input/output validation
145
- * - Typed workflow context with activities
146
- * - Workflow info access
147
- *
148
- * Workflows must be defined in separate files and imported by the Temporal Worker
149
- * via workflowsPath.
150
- *
151
- * @example
152
- * ```ts
153
- * // workflows/processOrder.ts
154
- * import { declareWorkflow } from '@temporal-contract/worker';
155
- * import myContract from '../contract';
156
- *
157
- * export const processOrder = declareWorkflow({
158
- * workflowName: 'processOrder',
159
- * contract: myContract,
160
- * implementation: async (context, orderId, customerId) => {
161
- * // context.activities: typed activities (workflow + global)
162
- * // context.info: WorkflowInfo
163
- *
164
- * const inventory = await context.activities.validateInventory(orderId);
165
- *
166
- * if (!inventory.available) {
167
- * throw new Error('Out of stock');
168
- * }
169
- *
170
- * const payment = await context.activities.chargePayment(customerId, 100);
171
- *
172
- * // Global activity
173
- * await context.activities.sendEmail(
174
- * customerId,
175
- * 'Order processed',
176
- * 'Your order has been processed'
177
- * );
178
- *
179
- * return {
180
- * orderId,
181
- * status: payment.success ? 'success' : 'failed',
182
- * transactionId: payment.transactionId,
183
- * };
184
- * },
185
- * activityOptions: {
186
- * startToCloseTimeout: '1 minute',
187
- * },
188
- * });
189
- * ```
190
- *
191
- * Then in your worker setup:
192
- * ```ts
193
- * // worker.ts
194
- * import { Worker } from '@temporalio/worker';
195
- * import { activitiesHandler } from './activities';
196
- *
197
- * const worker = await Worker.create({
198
- * workflowsPath: require.resolve('./workflows'), // Imports processOrder
199
- * activities: activitiesHandler.activities,
200
- * taskQueue: activitiesHandler.contract.taskQueue,
201
- * });
202
- * ```
203
- */
204
- declare function declareWorkflow<TContract extends ContractDefinition, TWorkflowName extends keyof TContract["workflows"]>(options: DeclareWorkflowOptions<TContract, TWorkflowName>): (args: WorkerInferInput<TContract["workflows"][TWorkflowName]>) => Promise<WorkerInferOutput<TContract["workflows"][TWorkflowName]>>;
205
- //#endregion
206
- //#region src/errors.d.ts
207
- /**
208
- * Base error class for worker errors
209
- */
210
- declare class WorkerError extends Error {
211
- constructor(message: string);
212
- }
213
- /**
214
- * Error thrown when an activity implementation is not found
215
- */
216
- declare class ActivityImplementationNotFoundError extends WorkerError {
217
- readonly activityName: string;
218
- readonly availableActivities: readonly string[];
219
- constructor(activityName: string, availableActivities: readonly string[]);
220
- }
221
- /**
222
- * Error thrown when an activity definition is not found in the contract
223
- */
224
- declare class ActivityDefinitionNotFoundError extends WorkerError {
225
- readonly activityName: string;
226
- readonly availableDefinitions: readonly string[];
227
- constructor(activityName: string, availableDefinitions: readonly string[]);
228
- }
229
- /**
230
- * Error thrown when activity input validation fails
231
- */
232
- declare class ActivityInputValidationError extends WorkerError {
233
- readonly activityName: string;
234
- readonly issues: ReadonlyArray<StandardSchemaV1.Issue>;
235
- constructor(activityName: string, issues: ReadonlyArray<StandardSchemaV1.Issue>);
236
- }
237
- /**
238
- * Error thrown when activity output validation fails
239
- */
240
- declare class ActivityOutputValidationError extends WorkerError {
241
- readonly activityName: string;
242
- readonly issues: ReadonlyArray<StandardSchemaV1.Issue>;
243
- constructor(activityName: string, issues: ReadonlyArray<StandardSchemaV1.Issue>);
244
- }
245
- /**
246
- * Error thrown when workflow input validation fails
247
- */
248
- declare class WorkflowInputValidationError extends WorkerError {
249
- readonly workflowName: string;
250
- readonly issues: ReadonlyArray<StandardSchemaV1.Issue>;
251
- constructor(workflowName: string, issues: ReadonlyArray<StandardSchemaV1.Issue>);
252
- }
253
- /**
254
- * Error thrown when workflow output validation fails
255
- */
256
- declare class WorkflowOutputValidationError extends WorkerError {
257
- readonly workflowName: string;
258
- readonly issues: ReadonlyArray<StandardSchemaV1.Issue>;
259
- constructor(workflowName: string, issues: ReadonlyArray<StandardSchemaV1.Issue>);
260
- }
261
- /**
262
- * Error thrown when signal input validation fails
263
- */
264
- declare class SignalInputValidationError extends WorkerError {
265
- readonly signalName: string;
266
- readonly issues: ReadonlyArray<StandardSchemaV1.Issue>;
267
- constructor(signalName: string, issues: ReadonlyArray<StandardSchemaV1.Issue>);
268
- }
269
- /**
270
- * Error thrown when query input validation fails
271
- */
272
- declare class QueryInputValidationError extends WorkerError {
273
- readonly queryName: string;
274
- readonly issues: ReadonlyArray<StandardSchemaV1.Issue>;
275
- constructor(queryName: string, issues: ReadonlyArray<StandardSchemaV1.Issue>);
276
- }
277
- /**
278
- * Error thrown when query output validation fails
279
- */
280
- declare class QueryOutputValidationError extends WorkerError {
281
- readonly queryName: string;
282
- readonly issues: ReadonlyArray<StandardSchemaV1.Issue>;
283
- constructor(queryName: string, issues: ReadonlyArray<StandardSchemaV1.Issue>);
284
- }
285
- /**
286
- * Error thrown when update input validation fails
287
- */
288
- declare class UpdateInputValidationError extends WorkerError {
289
- readonly updateName: string;
290
- readonly issues: ReadonlyArray<StandardSchemaV1.Issue>;
291
- constructor(updateName: string, issues: ReadonlyArray<StandardSchemaV1.Issue>);
292
- }
293
- /**
294
- * Error thrown when update output validation fails
295
- */
296
- declare class UpdateOutputValidationError extends WorkerError {
297
- readonly updateName: string;
298
- readonly issues: ReadonlyArray<StandardSchemaV1.Issue>;
299
- constructor(updateName: string, issues: ReadonlyArray<StandardSchemaV1.Issue>);
300
- }
301
- //#endregion
302
- export { declareActivitiesHandler as C, WorkflowImplementation as S, QueryHandlerImplementation as _, QueryInputValidationError as a, UpdateHandlerImplementation as b, UpdateInputValidationError as c, WorkflowInputValidationError as d, WorkflowOutputValidationError as f, DeclareWorkflowOptions as g, DeclareActivitiesHandlerOptions as h, ActivityOutputValidationError as i, UpdateOutputValidationError as l, ActivityImplementations as m, ActivityImplementationNotFoundError as n, QueryOutputValidationError as o, ActivitiesHandler as p, ActivityInputValidationError as r, SignalInputValidationError as s, ActivityDefinitionNotFoundError as t, WorkerError as u, RawActivityImplementation as v, declareWorkflow as w, WorkflowContext as x, SignalHandlerImplementation as y };
@@ -1,376 +0,0 @@
1
- import { defineQuery, defineSignal, defineUpdate, proxyActivities, setHandler, workflowInfo } from "@temporalio/workflow";
2
-
3
- //#region src/errors.ts
4
- /**
5
- * Base error class for worker errors
6
- */
7
- var WorkerError = class extends Error {
8
- constructor(message) {
9
- super(message);
10
- this.name = "WorkerError";
11
- if (Error.captureStackTrace) Error.captureStackTrace(this, this.constructor);
12
- }
13
- };
14
- /**
15
- * Error thrown when an activity implementation is not found
16
- */
17
- var ActivityImplementationNotFoundError = class extends WorkerError {
18
- constructor(activityName, availableActivities) {
19
- super(`Activity implementation not found for: "${activityName}". Available activities: ${availableActivities.length > 0 ? availableActivities.join(", ") : "none"}`);
20
- this.activityName = activityName;
21
- this.availableActivities = availableActivities;
22
- this.name = "ActivityImplementationNotFoundError";
23
- }
24
- };
25
- /**
26
- * Error thrown when an activity definition is not found in the contract
27
- */
28
- var ActivityDefinitionNotFoundError = class extends WorkerError {
29
- constructor(activityName, availableDefinitions) {
30
- super(`Activity definition not found in contract for: "${activityName}". Available definitions: ${availableDefinitions.length > 0 ? availableDefinitions.join(", ") : "none"}`);
31
- this.activityName = activityName;
32
- this.availableDefinitions = availableDefinitions;
33
- this.name = "ActivityDefinitionNotFoundError";
34
- }
35
- };
36
- /**
37
- * Error thrown when activity input validation fails
38
- */
39
- var ActivityInputValidationError = class extends WorkerError {
40
- constructor(activityName, issues) {
41
- const message = issues.map((issue) => issue.message).join("; ");
42
- super(`Activity "${activityName}" input validation failed: ${message}`);
43
- this.activityName = activityName;
44
- this.issues = issues;
45
- this.name = "ActivityInputValidationError";
46
- }
47
- };
48
- /**
49
- * Error thrown when activity output validation fails
50
- */
51
- var ActivityOutputValidationError = class extends WorkerError {
52
- constructor(activityName, issues) {
53
- const message = issues.map((issue) => issue.message).join("; ");
54
- super(`Activity "${activityName}" output validation failed: ${message}`);
55
- this.activityName = activityName;
56
- this.issues = issues;
57
- this.name = "ActivityOutputValidationError";
58
- }
59
- };
60
- /**
61
- * Error thrown when workflow input validation fails
62
- */
63
- var WorkflowInputValidationError = class extends WorkerError {
64
- constructor(workflowName, issues) {
65
- const message = issues.map((issue) => issue.message).join("; ");
66
- super(`Workflow "${workflowName}" input validation failed: ${message}`);
67
- this.workflowName = workflowName;
68
- this.issues = issues;
69
- this.name = "WorkflowInputValidationError";
70
- }
71
- };
72
- /**
73
- * Error thrown when workflow output validation fails
74
- */
75
- var WorkflowOutputValidationError = class extends WorkerError {
76
- constructor(workflowName, issues) {
77
- const message = issues.map((issue) => issue.message).join("; ");
78
- super(`Workflow "${workflowName}" output validation failed: ${message}`);
79
- this.workflowName = workflowName;
80
- this.issues = issues;
81
- this.name = "WorkflowOutputValidationError";
82
- }
83
- };
84
- /**
85
- * Error thrown when signal input validation fails
86
- */
87
- var SignalInputValidationError = class extends WorkerError {
88
- constructor(signalName, issues) {
89
- const message = issues.map((issue) => issue.message).join("; ");
90
- super(`Signal "${signalName}" input validation failed: ${message}`);
91
- this.signalName = signalName;
92
- this.issues = issues;
93
- this.name = "SignalInputValidationError";
94
- }
95
- };
96
- /**
97
- * Error thrown when query input validation fails
98
- */
99
- var QueryInputValidationError = class extends WorkerError {
100
- constructor(queryName, issues) {
101
- const message = issues.map((issue) => issue.message).join("; ");
102
- super(`Query "${queryName}" input validation failed: ${message}`);
103
- this.queryName = queryName;
104
- this.issues = issues;
105
- this.name = "QueryInputValidationError";
106
- }
107
- };
108
- /**
109
- * Error thrown when query output validation fails
110
- */
111
- var QueryOutputValidationError = class extends WorkerError {
112
- constructor(queryName, issues) {
113
- const message = issues.map((issue) => issue.message).join("; ");
114
- super(`Query "${queryName}" output validation failed: ${message}`);
115
- this.queryName = queryName;
116
- this.issues = issues;
117
- this.name = "QueryOutputValidationError";
118
- }
119
- };
120
- /**
121
- * Error thrown when update input validation fails
122
- */
123
- var UpdateInputValidationError = class extends WorkerError {
124
- constructor(updateName, issues) {
125
- const message = issues.map((issue) => issue.message).join("; ");
126
- super(`Update "${updateName}" input validation failed: ${message}`);
127
- this.updateName = updateName;
128
- this.issues = issues;
129
- this.name = "UpdateInputValidationError";
130
- }
131
- };
132
- /**
133
- * Error thrown when update output validation fails
134
- */
135
- var UpdateOutputValidationError = class extends WorkerError {
136
- constructor(updateName, issues) {
137
- const message = issues.map((issue) => issue.message).join("; ");
138
- super(`Update "${updateName}" output validation failed: ${message}`);
139
- this.updateName = updateName;
140
- this.issues = issues;
141
- this.name = "UpdateOutputValidationError";
142
- }
143
- };
144
-
145
- //#endregion
146
- //#region src/handler.ts
147
- /**
148
- * Create a validated activities proxy that parses inputs and outputs
149
- *
150
- * This wrapper ensures data integrity across the network boundary between
151
- * workflow and activity execution.
152
- */
153
- function createValidatedActivities(rawActivities, workflowActivitiesDefinition, contractActivitiesDefinition) {
154
- const validatedActivities = {};
155
- const allActivitiesDefinition = {
156
- ...contractActivitiesDefinition,
157
- ...workflowActivitiesDefinition
158
- };
159
- for (const [activityName, activityDef] of Object.entries(allActivitiesDefinition)) {
160
- const rawActivity = rawActivities[activityName];
161
- if (!rawActivity) throw new ActivityImplementationNotFoundError(activityName, Object.keys(rawActivities));
162
- const wrappedActivity = async (input) => {
163
- const inputResult = await activityDef.input["~standard"].validate(input);
164
- if (inputResult.issues) throw new ActivityInputValidationError(activityName, inputResult.issues);
165
- const result = await rawActivity(inputResult.value);
166
- const outputResult = await activityDef.output["~standard"].validate(result);
167
- if (outputResult.issues) throw new ActivityOutputValidationError(activityName, outputResult.issues);
168
- return outputResult.value;
169
- };
170
- validatedActivities[activityName] = wrappedActivity;
171
- }
172
- return validatedActivities;
173
- }
174
- /**
175
- * Create a typed activities handler with automatic validation
176
- *
177
- * This wraps all activity implementations with Zod validation at network boundaries.
178
- * TypeScript ensures ALL activities (global + workflow-specific) are implemented.
179
- *
180
- * Use this to create the activities object for the Temporal Worker.
181
- *
182
- * @example
183
- * ```ts
184
- * import { declareActivitiesHandler } from '@temporal-contract/worker';
185
- * import myContract from './contract';
186
- *
187
- * export const activitiesHandler = declareActivitiesHandler({
188
- * contract: myContract,
189
- * activities: {
190
- * // Global activities
191
- * sendEmail: async (to, subject, body) => {
192
- * await emailService.send({ to, subject, body });
193
- * return { sent: true };
194
- * },
195
- * // Workflow-specific activities
196
- * validateInventory: async (orderId) => {
197
- * const available = await inventory.check(orderId);
198
- * return { available };
199
- * },
200
- * },
201
- * });
202
- *
203
- * // Use with Temporal Worker
204
- * import { Worker } from '@temporalio/worker';
205
- *
206
- * const worker = await Worker.create({
207
- * workflowsPath: require.resolve('./workflows'),
208
- * activities: activitiesHandler.activities,
209
- * taskQueue: activitiesHandler.contract.taskQueue,
210
- * });
211
- * ```
212
- */
213
- function declareActivitiesHandler(options) {
214
- const { contract, activities } = options;
215
- const wrappedActivities = {};
216
- const allDefinitions = [];
217
- if (contract.activities) allDefinitions.push(...Object.keys(contract.activities));
218
- for (const workflow of Object.values(contract.workflows)) if (workflow.activities) allDefinitions.push(...Object.keys(workflow.activities));
219
- for (const [activityName, activityImpl] of Object.entries(activities)) {
220
- let activityDef;
221
- if (contract.activities?.[activityName]) activityDef = contract.activities[activityName];
222
- else for (const workflow of Object.values(contract.workflows)) if (workflow.activities?.[activityName]) {
223
- activityDef = workflow.activities[activityName];
224
- break;
225
- }
226
- if (!activityDef) throw new ActivityDefinitionNotFoundError(activityName, allDefinitions);
227
- wrappedActivities[activityName] = async (input) => {
228
- const inputResult = await activityDef.input["~standard"].validate(input);
229
- if (inputResult.issues) throw new ActivityInputValidationError(activityName, inputResult.issues);
230
- const result = await activityImpl(inputResult.value);
231
- const outputResult = await activityDef.output["~standard"].validate(result);
232
- if (outputResult.issues) throw new ActivityOutputValidationError(activityName, outputResult.issues);
233
- return outputResult.value;
234
- };
235
- }
236
- return {
237
- contract,
238
- activities: wrappedActivities
239
- };
240
- }
241
- /**
242
- * Create a typed workflow implementation with automatic validation
243
- *
244
- * This wraps a workflow implementation with:
245
- * - Input/output validation
246
- * - Typed workflow context with activities
247
- * - Workflow info access
248
- *
249
- * Workflows must be defined in separate files and imported by the Temporal Worker
250
- * via workflowsPath.
251
- *
252
- * @example
253
- * ```ts
254
- * // workflows/processOrder.ts
255
- * import { declareWorkflow } from '@temporal-contract/worker';
256
- * import myContract from '../contract';
257
- *
258
- * export const processOrder = declareWorkflow({
259
- * workflowName: 'processOrder',
260
- * contract: myContract,
261
- * implementation: async (context, orderId, customerId) => {
262
- * // context.activities: typed activities (workflow + global)
263
- * // context.info: WorkflowInfo
264
- *
265
- * const inventory = await context.activities.validateInventory(orderId);
266
- *
267
- * if (!inventory.available) {
268
- * throw new Error('Out of stock');
269
- * }
270
- *
271
- * const payment = await context.activities.chargePayment(customerId, 100);
272
- *
273
- * // Global activity
274
- * await context.activities.sendEmail(
275
- * customerId,
276
- * 'Order processed',
277
- * 'Your order has been processed'
278
- * );
279
- *
280
- * return {
281
- * orderId,
282
- * status: payment.success ? 'success' : 'failed',
283
- * transactionId: payment.transactionId,
284
- * };
285
- * },
286
- * activityOptions: {
287
- * startToCloseTimeout: '1 minute',
288
- * },
289
- * });
290
- * ```
291
- *
292
- * Then in your worker setup:
293
- * ```ts
294
- * // worker.ts
295
- * import { Worker } from '@temporalio/worker';
296
- * import { activitiesHandler } from './activities';
297
- *
298
- * const worker = await Worker.create({
299
- * workflowsPath: require.resolve('./workflows'), // Imports processOrder
300
- * activities: activitiesHandler.activities,
301
- * taskQueue: activitiesHandler.contract.taskQueue,
302
- * });
303
- * ```
304
- */
305
- function declareWorkflow(options) {
306
- const { workflowName, contract, implementation, activityOptions, signals, queries, updates } = options;
307
- const definition = contract.workflows[workflowName];
308
- return async (args) => {
309
- const singleArg = Array.isArray(args) ? args[0] : args;
310
- const inputResult = await definition.input["~standard"].validate(singleArg);
311
- if (inputResult.issues) throw new WorkflowInputValidationError(String(workflowName), inputResult.issues);
312
- const validatedInput = inputResult.value;
313
- if (definition.signals && signals) {
314
- const signalDefs = definition.signals;
315
- const signalHandlers = signals;
316
- for (const [signalName, signalDef] of Object.entries(signalDefs)) {
317
- const handler = signalHandlers[signalName];
318
- if (handler) setHandler(defineSignal(signalName), async (...args$1) => {
319
- const input = args$1.length === 1 ? args$1[0] : args$1;
320
- const inputResult$1 = await signalDef.input["~standard"].validate(input);
321
- if (inputResult$1.issues) throw new SignalInputValidationError(signalName, inputResult$1.issues);
322
- await handler(inputResult$1.value);
323
- });
324
- }
325
- }
326
- if (definition.queries && queries) {
327
- const queryDefs = definition.queries;
328
- const queryHandlers = queries;
329
- for (const [queryName, queryDef] of Object.entries(queryDefs)) {
330
- const handler = queryHandlers[queryName];
331
- if (handler) setHandler(defineQuery(queryName), (...args$1) => {
332
- const input = args$1.length === 1 ? args$1[0] : args$1;
333
- const inputResult$1 = queryDef.input["~standard"].validate(input);
334
- if (inputResult$1 instanceof Promise) throw new Error(`Query "${queryName}" validation must be synchronous. Use a schema library that supports synchronous validation for queries.`);
335
- if (inputResult$1.issues) throw new QueryInputValidationError(queryName, inputResult$1.issues);
336
- const result$1 = handler(inputResult$1.value);
337
- const outputResult$1 = queryDef.output["~standard"].validate(result$1);
338
- if (outputResult$1 instanceof Promise) throw new Error(`Query "${queryName}" output validation must be synchronous. Use a schema library that supports synchronous validation for queries.`);
339
- if (outputResult$1.issues) throw new QueryOutputValidationError(queryName, outputResult$1.issues);
340
- return outputResult$1.value;
341
- });
342
- }
343
- }
344
- if (definition.updates && updates) {
345
- const updateDefs = definition.updates;
346
- const updateHandlers = updates;
347
- for (const [updateName, updateDef] of Object.entries(updateDefs)) {
348
- const handler = updateHandlers[updateName];
349
- if (handler) setHandler(defineUpdate(updateName), async (...args$1) => {
350
- const input = args$1.length === 1 ? args$1[0] : args$1;
351
- const inputResult$1 = await updateDef.input["~standard"].validate(input);
352
- if (inputResult$1.issues) throw new UpdateInputValidationError(updateName, inputResult$1.issues);
353
- const result$1 = await handler(inputResult$1.value);
354
- const outputResult$1 = await updateDef.output["~standard"].validate(result$1);
355
- if (outputResult$1.issues) throw new UpdateOutputValidationError(updateName, outputResult$1.issues);
356
- return outputResult$1.value;
357
- });
358
- }
359
- }
360
- let contextActivities = {};
361
- if (definition.activities || contract.activities) contextActivities = createValidatedActivities(proxyActivities({
362
- startToCloseTimeout: activityOptions?.startToCloseTimeout ?? 6e4,
363
- ...activityOptions
364
- }), definition.activities, contract.activities);
365
- const result = await implementation({
366
- activities: contextActivities,
367
- info: workflowInfo()
368
- }, validatedInput);
369
- const outputResult = await definition.output["~standard"].validate(result);
370
- if (outputResult.issues) throw new WorkflowOutputValidationError(String(workflowName), outputResult.issues);
371
- return outputResult.value;
372
- };
373
- }
374
-
375
- //#endregion
376
- export { ActivityInputValidationError as a, QueryOutputValidationError as c, UpdateOutputValidationError as d, WorkerError as f, ActivityImplementationNotFoundError as i, SignalInputValidationError as l, WorkflowOutputValidationError as m, declareWorkflow as n, ActivityOutputValidationError as o, WorkflowInputValidationError as p, ActivityDefinitionNotFoundError as r, QueryInputValidationError as s, declareActivitiesHandler as t, UpdateInputValidationError as u };