@temporal-contract/worker 0.0.4 → 0.0.6
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/README.md +72 -0
- package/dist/activity.cjs +108 -32
- package/dist/activity.d.cts +98 -3
- package/dist/activity.d.mts +98 -3
- package/dist/activity.mjs +104 -3
- package/dist/errors-BqVTpfcf.mjs +155 -0
- package/dist/errors-BqYWpdvd.d.cts +137 -0
- package/dist/errors-C1RFkCuD.d.mts +137 -0
- package/dist/errors-DjSZg-93.cjs +227 -0
- package/dist/worker.cjs +65 -0
- package/dist/worker.d.cts +68 -0
- package/dist/worker.d.mts +68 -0
- package/dist/worker.mjs +64 -0
- package/dist/workflow.cjs +255 -10
- package/dist/workflow.d.cts +299 -2
- package/dist/workflow.d.mts +299 -2
- package/dist/workflow.mjs +244 -2
- package/package.json +39 -23
- package/dist/handler-B7B5QHez.mjs +0 -398
- package/dist/handler-Czi-kgwZ.d.cts +0 -316
- package/dist/handler-D9BllGor.cjs +0 -481
- package/dist/handler-DThqdaaS.d.mts +0 -316
package/dist/workflow.d.cts
CHANGED
|
@@ -1,2 +1,299 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
1
|
+
import { a as ChildWorkflowNotFoundError, c as SignalInputValidationError, d as WorkflowInputValidationError, f as WorkflowOutputValidationError, g as WorkerInferOutput, h as WorkerInferInput, i as ChildWorkflowError, l as UpdateInputValidationError, m as ClientInferOutput, n as ActivityInputValidationError, o as QueryInputValidationError, p as ClientInferInput, r as ActivityOutputValidationError, s as QueryOutputValidationError, u as UpdateOutputValidationError } from "./errors-BqYWpdvd.cjs";
|
|
2
|
+
import { ActivityDefinition, ContractDefinition, QueryDefinition, SignalDefinition, UpdateDefinition, WorkflowDefinition } from "@temporal-contract/contract";
|
|
3
|
+
import { Future, Result } from "@temporal-contract/boxed";
|
|
4
|
+
import { ActivityOptions, ChildWorkflowOptions, WorkflowInfo } from "@temporalio/workflow";
|
|
5
|
+
|
|
6
|
+
//#region src/workflow.d.ts
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Create a typed workflow implementation with automatic validation
|
|
10
|
+
*
|
|
11
|
+
* This wraps a workflow implementation with:
|
|
12
|
+
* - Input/output validation
|
|
13
|
+
* - Typed workflow context with activities
|
|
14
|
+
* - Workflow info access
|
|
15
|
+
*
|
|
16
|
+
* Workflows must be defined in separate files and imported by the Temporal Worker
|
|
17
|
+
* via workflowsPath.
|
|
18
|
+
*
|
|
19
|
+
* @example
|
|
20
|
+
* ```ts
|
|
21
|
+
* // workflows/processOrder.ts
|
|
22
|
+
* import { declareWorkflow } from '@temporal-contract/worker';
|
|
23
|
+
* import myContract from '../contract';
|
|
24
|
+
*
|
|
25
|
+
* export const processOrder = declareWorkflow({
|
|
26
|
+
* workflowName: 'processOrder',
|
|
27
|
+
* contract: myContract,
|
|
28
|
+
* implementation: async (context, orderId, customerId) => {
|
|
29
|
+
* // context.activities: typed activities (workflow + global)
|
|
30
|
+
* // context.info: WorkflowInfo
|
|
31
|
+
*
|
|
32
|
+
* const inventory = await context.activities.validateInventory(orderId);
|
|
33
|
+
*
|
|
34
|
+
* if (!inventory.available) {
|
|
35
|
+
* throw new Error('Out of stock');
|
|
36
|
+
* }
|
|
37
|
+
*
|
|
38
|
+
* const payment = await context.activities.chargePayment(customerId, 100);
|
|
39
|
+
*
|
|
40
|
+
* // Global activity
|
|
41
|
+
* await context.activities.sendEmail(
|
|
42
|
+
* customerId,
|
|
43
|
+
* 'Order processed',
|
|
44
|
+
* 'Your order has been processed'
|
|
45
|
+
* );
|
|
46
|
+
*
|
|
47
|
+
* return {
|
|
48
|
+
* orderId,
|
|
49
|
+
* status: payment.success ? 'success' : 'failed',
|
|
50
|
+
* transactionId: payment.transactionId,
|
|
51
|
+
* };
|
|
52
|
+
* },
|
|
53
|
+
* activityOptions: {
|
|
54
|
+
* startToCloseTimeout: '1 minute',
|
|
55
|
+
* },
|
|
56
|
+
* });
|
|
57
|
+
* ```
|
|
58
|
+
*
|
|
59
|
+
* Then in your worker setup:
|
|
60
|
+
* ```ts
|
|
61
|
+
* // worker.ts
|
|
62
|
+
* import { Worker } from '@temporalio/worker';
|
|
63
|
+
* import { activitiesHandler } from './activities';
|
|
64
|
+
*
|
|
65
|
+
* const worker = await Worker.create({
|
|
66
|
+
* workflowsPath: require.resolve('./workflows'), // Imports processOrder
|
|
67
|
+
* activities: activitiesHandler.activities,
|
|
68
|
+
* taskQueue: activitiesHandler.contract.taskQueue,
|
|
69
|
+
* });
|
|
70
|
+
* ```
|
|
71
|
+
*/
|
|
72
|
+
declare function declareWorkflow<TContract extends ContractDefinition, TWorkflowName extends keyof TContract["workflows"]>({
|
|
73
|
+
workflowName,
|
|
74
|
+
contract,
|
|
75
|
+
implementation,
|
|
76
|
+
activityOptions
|
|
77
|
+
}: DeclareWorkflowOptions<TContract, TWorkflowName>): (...args: unknown[]) => Promise<WorkerInferOutput<TContract["workflows"][TWorkflowName]>>;
|
|
78
|
+
/**
|
|
79
|
+
* Signal handler implementation
|
|
80
|
+
*
|
|
81
|
+
* Processes signal input and can optionally perform asynchronous operations.
|
|
82
|
+
* Should not return a value (signals are fire-and-forget).
|
|
83
|
+
*/
|
|
84
|
+
type SignalHandlerImplementation<TSignal extends SignalDefinition> = (args: WorkerInferInput<TSignal>) => void | Promise<void>;
|
|
85
|
+
/**
|
|
86
|
+
* Query handler implementation
|
|
87
|
+
*
|
|
88
|
+
* Processes query input and returns a synchronous response.
|
|
89
|
+
* Must be synchronous to satisfy Temporal's query constraints.
|
|
90
|
+
*/
|
|
91
|
+
type QueryHandlerImplementation<TQuery extends QueryDefinition> = (args: WorkerInferInput<TQuery>) => WorkerInferOutput<TQuery>;
|
|
92
|
+
/**
|
|
93
|
+
* Update handler implementation
|
|
94
|
+
*
|
|
95
|
+
* Processes update input and returns a validated response after modifying workflow state.
|
|
96
|
+
* Can perform asynchronous operations.
|
|
97
|
+
*/
|
|
98
|
+
type UpdateHandlerImplementation<TUpdate extends UpdateDefinition> = (args: WorkerInferInput<TUpdate>) => Promise<WorkerInferOutput<TUpdate>>;
|
|
99
|
+
/**
|
|
100
|
+
* Options for declaring a workflow implementation
|
|
101
|
+
*/
|
|
102
|
+
interface DeclareWorkflowOptions<TContract extends ContractDefinition, TWorkflowName extends keyof TContract["workflows"]> {
|
|
103
|
+
workflowName: TWorkflowName;
|
|
104
|
+
contract: TContract;
|
|
105
|
+
implementation: WorkflowImplementation<TContract, TWorkflowName>;
|
|
106
|
+
/**
|
|
107
|
+
* Default activity options applied to all activities in this workflow.
|
|
108
|
+
* For more control, you can override specific Temporal ActivityOptions like:
|
|
109
|
+
* - startToCloseTimeout: Maximum time for activity execution
|
|
110
|
+
* - scheduleToCloseTimeout: End-to-end timeout including queuing
|
|
111
|
+
* - scheduleToStartTimeout: Maximum time activity can wait in queue
|
|
112
|
+
* - heartbeatTimeout: Time between heartbeats before considering activity dead
|
|
113
|
+
* - retry: Retry policy for failed activities
|
|
114
|
+
*
|
|
115
|
+
* @example
|
|
116
|
+
* ```ts
|
|
117
|
+
* activityOptions: {
|
|
118
|
+
* startToCloseTimeout: '5m',
|
|
119
|
+
* retry: { maximumAttempts: 3 }
|
|
120
|
+
* }
|
|
121
|
+
* ```
|
|
122
|
+
*/
|
|
123
|
+
activityOptions: ActivityOptions;
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Workflow implementation function
|
|
127
|
+
*
|
|
128
|
+
* Receives a workflow context (with typed activities and utilities) and validated input arguments.
|
|
129
|
+
* Returns the workflow output which will be validated against the contract schema.
|
|
130
|
+
*/
|
|
131
|
+
type WorkflowImplementation<TContract extends ContractDefinition, TWorkflowName extends keyof TContract["workflows"]> = (context: WorkflowContext<TContract, TWorkflowName>, args: WorkerInferInput<TContract["workflows"][TWorkflowName]>) => Promise<WorkerInferOutput<TContract["workflows"][TWorkflowName]>>;
|
|
132
|
+
/**
|
|
133
|
+
* Workflow execution context providing typed activities, workflow info, and interaction handlers
|
|
134
|
+
*
|
|
135
|
+
* Provides access to:
|
|
136
|
+
* - Typed activities (both workflow-specific and global)
|
|
137
|
+
* - Workflow metadata and execution info
|
|
138
|
+
* - Signal, query, and update handler registration
|
|
139
|
+
* - Child workflow execution capabilities
|
|
140
|
+
*/
|
|
141
|
+
interface WorkflowContext<TContract extends ContractDefinition, TWorkflowName extends keyof TContract["workflows"]> {
|
|
142
|
+
activities: WorkflowInferWorkflowContextActivities<TContract, TWorkflowName>;
|
|
143
|
+
info: WorkflowInfo;
|
|
144
|
+
/**
|
|
145
|
+
* Define a signal handler within the workflow implementation
|
|
146
|
+
* Allows the signal handler to access workflow state
|
|
147
|
+
*
|
|
148
|
+
* @example
|
|
149
|
+
* ```ts
|
|
150
|
+
* implementation: async (context, args) => {
|
|
151
|
+
* let currentValue = args.initialValue;
|
|
152
|
+
*
|
|
153
|
+
* context.defineSignal('increment', async (signalArgs) => {
|
|
154
|
+
* currentValue += signalArgs.amount;
|
|
155
|
+
* });
|
|
156
|
+
*
|
|
157
|
+
* // ... rest of workflow
|
|
158
|
+
* }
|
|
159
|
+
* ```
|
|
160
|
+
*/
|
|
161
|
+
defineSignal: <K$1 extends keyof TContract["workflows"][TWorkflowName]["signals"]>(signalName: K$1, handler: SignalHandlerImplementation<TContract["workflows"][TWorkflowName]["signals"][K$1] extends SignalDefinition ? TContract["workflows"][TWorkflowName]["signals"][K$1] : never>) => void;
|
|
162
|
+
/**
|
|
163
|
+
* Define a query handler within the workflow implementation
|
|
164
|
+
* Allows the query handler to access workflow state
|
|
165
|
+
*
|
|
166
|
+
* @example
|
|
167
|
+
* ```ts
|
|
168
|
+
* implementation: async (context, args) => {
|
|
169
|
+
* let currentValue = args.initialValue;
|
|
170
|
+
*
|
|
171
|
+
* context.defineQuery('getCurrentValue', () => {
|
|
172
|
+
* return { value: currentValue };
|
|
173
|
+
* });
|
|
174
|
+
*
|
|
175
|
+
* // ... rest of workflow
|
|
176
|
+
* }
|
|
177
|
+
* ```
|
|
178
|
+
*/
|
|
179
|
+
defineQuery: <K$1 extends keyof TContract["workflows"][TWorkflowName]["queries"]>(queryName: K$1, handler: QueryHandlerImplementation<TContract["workflows"][TWorkflowName]["queries"][K$1] extends QueryDefinition ? TContract["workflows"][TWorkflowName]["queries"][K$1] : never>) => void;
|
|
180
|
+
/**
|
|
181
|
+
* Define an update handler within the workflow implementation
|
|
182
|
+
* Allows the update handler to access and modify workflow state
|
|
183
|
+
*
|
|
184
|
+
* @example
|
|
185
|
+
* ```ts
|
|
186
|
+
* implementation: async (context, args) => {
|
|
187
|
+
* let currentValue = args.initialValue;
|
|
188
|
+
*
|
|
189
|
+
* context.defineUpdate('multiply', async (updateArgs) => {
|
|
190
|
+
* currentValue *= updateArgs.factor;
|
|
191
|
+
* return { newValue: currentValue };
|
|
192
|
+
* });
|
|
193
|
+
*
|
|
194
|
+
* // ... rest of workflow
|
|
195
|
+
* }
|
|
196
|
+
* ```
|
|
197
|
+
*/
|
|
198
|
+
defineUpdate: <K$1 extends keyof TContract["workflows"][TWorkflowName]["updates"]>(updateName: K$1, handler: UpdateHandlerImplementation<TContract["workflows"][TWorkflowName]["updates"][K$1] extends UpdateDefinition ? TContract["workflows"][TWorkflowName]["updates"][K$1] : never>) => void;
|
|
199
|
+
/**
|
|
200
|
+
* Start a child workflow and return a typed handle with Future/Result pattern
|
|
201
|
+
*
|
|
202
|
+
* Supports both same-contract and cross-contract child workflows:
|
|
203
|
+
* - Same contract: Pass workflowName from current contract
|
|
204
|
+
* - Cross-contract: Pass contract and workflowName to invoke workflows from other workers
|
|
205
|
+
*
|
|
206
|
+
* @example
|
|
207
|
+
* ```ts
|
|
208
|
+
* // Same contract child workflow
|
|
209
|
+
* const childResult = await context.startChildWorkflow(myContract, 'processPayment', {
|
|
210
|
+
* workflowId: 'payment-123',
|
|
211
|
+
* args: { amount: 100 }
|
|
212
|
+
* });
|
|
213
|
+
*
|
|
214
|
+
* // Cross-contract child workflow (from another worker)
|
|
215
|
+
* const otherResult = await context.startChildWorkflow(otherContract, 'sendNotification', {
|
|
216
|
+
* workflowId: 'notification-123',
|
|
217
|
+
* args: { message: 'Hello' }
|
|
218
|
+
* });
|
|
219
|
+
*
|
|
220
|
+
* childResult.match({
|
|
221
|
+
* Ok: async (handle) => {
|
|
222
|
+
* const result = await handle.result();
|
|
223
|
+
* // ... handle result
|
|
224
|
+
* },
|
|
225
|
+
* Error: (error) => console.error('Failed to start:', error),
|
|
226
|
+
* });
|
|
227
|
+
* ```
|
|
228
|
+
*/
|
|
229
|
+
startChildWorkflow: <TChildContract extends ContractDefinition, TChildWorkflowName extends keyof TChildContract["workflows"]>(contract: TChildContract, workflowName: TChildWorkflowName, options: TypedChildWorkflowOptions<TChildContract, TChildWorkflowName>) => Future<Result<TypedChildWorkflowHandle<TChildContract["workflows"][TChildWorkflowName]>, ChildWorkflowError>>;
|
|
230
|
+
/**
|
|
231
|
+
* Execute a child workflow (start and wait for result) with Future/Result pattern
|
|
232
|
+
*
|
|
233
|
+
* Supports both same-contract and cross-contract child workflows:
|
|
234
|
+
* - Same contract: Pass workflowName from current contract
|
|
235
|
+
* - Cross-contract: Pass contract and workflowName to invoke workflows from other workers
|
|
236
|
+
*
|
|
237
|
+
* @example
|
|
238
|
+
* ```ts
|
|
239
|
+
* // Same contract child workflow
|
|
240
|
+
* const result = await context.executeChildWorkflow(myContract, 'processPayment', {
|
|
241
|
+
* workflowId: 'payment-123',
|
|
242
|
+
* args: { amount: 100 }
|
|
243
|
+
* });
|
|
244
|
+
*
|
|
245
|
+
* // Cross-contract child workflow (from another worker)
|
|
246
|
+
* const otherResult = await context.executeChildWorkflow(otherContract, 'sendNotification', {
|
|
247
|
+
* workflowId: 'notification-123',
|
|
248
|
+
* args: { message: 'Hello' }
|
|
249
|
+
* });
|
|
250
|
+
*
|
|
251
|
+
* result.match({
|
|
252
|
+
* Ok: (output) => console.log('Payment processed:', output),
|
|
253
|
+
* Error: (error) => console.error('Processing failed:', error),
|
|
254
|
+
* });
|
|
255
|
+
* ```
|
|
256
|
+
*/
|
|
257
|
+
executeChildWorkflow: <TChildContract extends ContractDefinition, TChildWorkflowName extends keyof TChildContract["workflows"]>(contract: TChildContract, workflowName: TChildWorkflowName, options: TypedChildWorkflowOptions<TChildContract, TChildWorkflowName>) => Future<Result<ClientInferOutput<TChildContract["workflows"][TChildWorkflowName]>, ChildWorkflowError>>;
|
|
258
|
+
}
|
|
259
|
+
/**
|
|
260
|
+
* Options for starting a child workflow
|
|
261
|
+
*/
|
|
262
|
+
type TypedChildWorkflowOptions<TChildContract extends ContractDefinition, TChildWorkflowName extends keyof TChildContract["workflows"]> = Omit<ChildWorkflowOptions, "taskQueue" | "args"> & {
|
|
263
|
+
args: ClientInferInput<TChildContract["workflows"][TChildWorkflowName]>;
|
|
264
|
+
};
|
|
265
|
+
/**
|
|
266
|
+
* Typed handle for a child workflow with Future/Result pattern
|
|
267
|
+
*/
|
|
268
|
+
interface TypedChildWorkflowHandle<TWorkflow extends WorkflowDefinition> {
|
|
269
|
+
/**
|
|
270
|
+
* Get child workflow result with Result pattern
|
|
271
|
+
*/
|
|
272
|
+
result: () => Future<Result<ClientInferOutput<TWorkflow>, ChildWorkflowError>>;
|
|
273
|
+
/**
|
|
274
|
+
* Child workflow ID
|
|
275
|
+
*/
|
|
276
|
+
workflowId: string;
|
|
277
|
+
}
|
|
278
|
+
/**
|
|
279
|
+
* Activity function signature from workflow execution perspective
|
|
280
|
+
*
|
|
281
|
+
* Workflows call activities with validated input (z.input parsed) and receive validated output (z.output)
|
|
282
|
+
*/
|
|
283
|
+
type WorkflowInferActivity<TActivity extends ActivityDefinition> = (args: ClientInferInput<TActivity>) => Promise<ClientInferOutput<TActivity>>;
|
|
284
|
+
/**
|
|
285
|
+
* All global activities from a contract (workflow execution perspective)
|
|
286
|
+
*/
|
|
287
|
+
type WorkflowInferActivities<TContract extends ContractDefinition> = TContract["activities"] extends Record<string, ActivityDefinition> ? { [K in keyof TContract["activities"]]: WorkflowInferActivity<TContract["activities"][K]> } : {};
|
|
288
|
+
/**
|
|
289
|
+
* Workflow-specific activities (workflow execution perspective)
|
|
290
|
+
*/
|
|
291
|
+
type WorkflowInferWorkflowActivities<T extends WorkflowDefinition> = T["activities"] extends Record<string, ActivityDefinition> ? { [K in keyof T["activities"]]: WorkflowInferActivity<T["activities"][K]> } : {};
|
|
292
|
+
/**
|
|
293
|
+
* All activities available in a workflow context (workflow execution perspective)
|
|
294
|
+
*
|
|
295
|
+
* Combines workflow-specific activities with global contract activities
|
|
296
|
+
*/
|
|
297
|
+
type WorkflowInferWorkflowContextActivities<TContract extends ContractDefinition, TWorkflowName extends keyof TContract["workflows"]> = WorkflowInferWorkflowActivities<TContract["workflows"][TWorkflowName]> & WorkflowInferActivities<TContract>;
|
|
298
|
+
//#endregion
|
|
299
|
+
export { ActivityInputValidationError, ActivityOutputValidationError, ChildWorkflowError, ChildWorkflowNotFoundError, QueryInputValidationError, QueryOutputValidationError, SignalInputValidationError, UpdateInputValidationError, UpdateOutputValidationError, WorkflowInputValidationError, WorkflowOutputValidationError, declareWorkflow };
|
package/dist/workflow.d.mts
CHANGED
|
@@ -1,2 +1,299 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
1
|
+
import { a as ChildWorkflowNotFoundError, c as SignalInputValidationError, d as WorkflowInputValidationError, f as WorkflowOutputValidationError, g as WorkerInferOutput, h as WorkerInferInput, i as ChildWorkflowError, l as UpdateInputValidationError, m as ClientInferOutput, n as ActivityInputValidationError, o as QueryInputValidationError, p as ClientInferInput, r as ActivityOutputValidationError, s as QueryOutputValidationError, u as UpdateOutputValidationError } from "./errors-C1RFkCuD.mjs";
|
|
2
|
+
import { Future, Result } from "@temporal-contract/boxed";
|
|
3
|
+
import { ActivityOptions, ChildWorkflowOptions, WorkflowInfo } from "@temporalio/workflow";
|
|
4
|
+
import { ActivityDefinition, ContractDefinition, QueryDefinition, SignalDefinition, UpdateDefinition, WorkflowDefinition } from "@temporal-contract/contract";
|
|
5
|
+
|
|
6
|
+
//#region src/workflow.d.ts
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Create a typed workflow implementation with automatic validation
|
|
10
|
+
*
|
|
11
|
+
* This wraps a workflow implementation with:
|
|
12
|
+
* - Input/output validation
|
|
13
|
+
* - Typed workflow context with activities
|
|
14
|
+
* - Workflow info access
|
|
15
|
+
*
|
|
16
|
+
* Workflows must be defined in separate files and imported by the Temporal Worker
|
|
17
|
+
* via workflowsPath.
|
|
18
|
+
*
|
|
19
|
+
* @example
|
|
20
|
+
* ```ts
|
|
21
|
+
* // workflows/processOrder.ts
|
|
22
|
+
* import { declareWorkflow } from '@temporal-contract/worker';
|
|
23
|
+
* import myContract from '../contract';
|
|
24
|
+
*
|
|
25
|
+
* export const processOrder = declareWorkflow({
|
|
26
|
+
* workflowName: 'processOrder',
|
|
27
|
+
* contract: myContract,
|
|
28
|
+
* implementation: async (context, orderId, customerId) => {
|
|
29
|
+
* // context.activities: typed activities (workflow + global)
|
|
30
|
+
* // context.info: WorkflowInfo
|
|
31
|
+
*
|
|
32
|
+
* const inventory = await context.activities.validateInventory(orderId);
|
|
33
|
+
*
|
|
34
|
+
* if (!inventory.available) {
|
|
35
|
+
* throw new Error('Out of stock');
|
|
36
|
+
* }
|
|
37
|
+
*
|
|
38
|
+
* const payment = await context.activities.chargePayment(customerId, 100);
|
|
39
|
+
*
|
|
40
|
+
* // Global activity
|
|
41
|
+
* await context.activities.sendEmail(
|
|
42
|
+
* customerId,
|
|
43
|
+
* 'Order processed',
|
|
44
|
+
* 'Your order has been processed'
|
|
45
|
+
* );
|
|
46
|
+
*
|
|
47
|
+
* return {
|
|
48
|
+
* orderId,
|
|
49
|
+
* status: payment.success ? 'success' : 'failed',
|
|
50
|
+
* transactionId: payment.transactionId,
|
|
51
|
+
* };
|
|
52
|
+
* },
|
|
53
|
+
* activityOptions: {
|
|
54
|
+
* startToCloseTimeout: '1 minute',
|
|
55
|
+
* },
|
|
56
|
+
* });
|
|
57
|
+
* ```
|
|
58
|
+
*
|
|
59
|
+
* Then in your worker setup:
|
|
60
|
+
* ```ts
|
|
61
|
+
* // worker.ts
|
|
62
|
+
* import { Worker } from '@temporalio/worker';
|
|
63
|
+
* import { activitiesHandler } from './activities';
|
|
64
|
+
*
|
|
65
|
+
* const worker = await Worker.create({
|
|
66
|
+
* workflowsPath: require.resolve('./workflows'), // Imports processOrder
|
|
67
|
+
* activities: activitiesHandler.activities,
|
|
68
|
+
* taskQueue: activitiesHandler.contract.taskQueue,
|
|
69
|
+
* });
|
|
70
|
+
* ```
|
|
71
|
+
*/
|
|
72
|
+
declare function declareWorkflow<TContract extends ContractDefinition, TWorkflowName extends keyof TContract["workflows"]>({
|
|
73
|
+
workflowName,
|
|
74
|
+
contract,
|
|
75
|
+
implementation,
|
|
76
|
+
activityOptions
|
|
77
|
+
}: DeclareWorkflowOptions<TContract, TWorkflowName>): (...args: unknown[]) => Promise<WorkerInferOutput<TContract["workflows"][TWorkflowName]>>;
|
|
78
|
+
/**
|
|
79
|
+
* Signal handler implementation
|
|
80
|
+
*
|
|
81
|
+
* Processes signal input and can optionally perform asynchronous operations.
|
|
82
|
+
* Should not return a value (signals are fire-and-forget).
|
|
83
|
+
*/
|
|
84
|
+
type SignalHandlerImplementation<TSignal extends SignalDefinition> = (args: WorkerInferInput<TSignal>) => void | Promise<void>;
|
|
85
|
+
/**
|
|
86
|
+
* Query handler implementation
|
|
87
|
+
*
|
|
88
|
+
* Processes query input and returns a synchronous response.
|
|
89
|
+
* Must be synchronous to satisfy Temporal's query constraints.
|
|
90
|
+
*/
|
|
91
|
+
type QueryHandlerImplementation<TQuery extends QueryDefinition> = (args: WorkerInferInput<TQuery>) => WorkerInferOutput<TQuery>;
|
|
92
|
+
/**
|
|
93
|
+
* Update handler implementation
|
|
94
|
+
*
|
|
95
|
+
* Processes update input and returns a validated response after modifying workflow state.
|
|
96
|
+
* Can perform asynchronous operations.
|
|
97
|
+
*/
|
|
98
|
+
type UpdateHandlerImplementation<TUpdate extends UpdateDefinition> = (args: WorkerInferInput<TUpdate>) => Promise<WorkerInferOutput<TUpdate>>;
|
|
99
|
+
/**
|
|
100
|
+
* Options for declaring a workflow implementation
|
|
101
|
+
*/
|
|
102
|
+
interface DeclareWorkflowOptions<TContract extends ContractDefinition, TWorkflowName extends keyof TContract["workflows"]> {
|
|
103
|
+
workflowName: TWorkflowName;
|
|
104
|
+
contract: TContract;
|
|
105
|
+
implementation: WorkflowImplementation<TContract, TWorkflowName>;
|
|
106
|
+
/**
|
|
107
|
+
* Default activity options applied to all activities in this workflow.
|
|
108
|
+
* For more control, you can override specific Temporal ActivityOptions like:
|
|
109
|
+
* - startToCloseTimeout: Maximum time for activity execution
|
|
110
|
+
* - scheduleToCloseTimeout: End-to-end timeout including queuing
|
|
111
|
+
* - scheduleToStartTimeout: Maximum time activity can wait in queue
|
|
112
|
+
* - heartbeatTimeout: Time between heartbeats before considering activity dead
|
|
113
|
+
* - retry: Retry policy for failed activities
|
|
114
|
+
*
|
|
115
|
+
* @example
|
|
116
|
+
* ```ts
|
|
117
|
+
* activityOptions: {
|
|
118
|
+
* startToCloseTimeout: '5m',
|
|
119
|
+
* retry: { maximumAttempts: 3 }
|
|
120
|
+
* }
|
|
121
|
+
* ```
|
|
122
|
+
*/
|
|
123
|
+
activityOptions: ActivityOptions;
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Workflow implementation function
|
|
127
|
+
*
|
|
128
|
+
* Receives a workflow context (with typed activities and utilities) and validated input arguments.
|
|
129
|
+
* Returns the workflow output which will be validated against the contract schema.
|
|
130
|
+
*/
|
|
131
|
+
type WorkflowImplementation<TContract extends ContractDefinition, TWorkflowName extends keyof TContract["workflows"]> = (context: WorkflowContext<TContract, TWorkflowName>, args: WorkerInferInput<TContract["workflows"][TWorkflowName]>) => Promise<WorkerInferOutput<TContract["workflows"][TWorkflowName]>>;
|
|
132
|
+
/**
|
|
133
|
+
* Workflow execution context providing typed activities, workflow info, and interaction handlers
|
|
134
|
+
*
|
|
135
|
+
* Provides access to:
|
|
136
|
+
* - Typed activities (both workflow-specific and global)
|
|
137
|
+
* - Workflow metadata and execution info
|
|
138
|
+
* - Signal, query, and update handler registration
|
|
139
|
+
* - Child workflow execution capabilities
|
|
140
|
+
*/
|
|
141
|
+
interface WorkflowContext<TContract extends ContractDefinition, TWorkflowName extends keyof TContract["workflows"]> {
|
|
142
|
+
activities: WorkflowInferWorkflowContextActivities<TContract, TWorkflowName>;
|
|
143
|
+
info: WorkflowInfo;
|
|
144
|
+
/**
|
|
145
|
+
* Define a signal handler within the workflow implementation
|
|
146
|
+
* Allows the signal handler to access workflow state
|
|
147
|
+
*
|
|
148
|
+
* @example
|
|
149
|
+
* ```ts
|
|
150
|
+
* implementation: async (context, args) => {
|
|
151
|
+
* let currentValue = args.initialValue;
|
|
152
|
+
*
|
|
153
|
+
* context.defineSignal('increment', async (signalArgs) => {
|
|
154
|
+
* currentValue += signalArgs.amount;
|
|
155
|
+
* });
|
|
156
|
+
*
|
|
157
|
+
* // ... rest of workflow
|
|
158
|
+
* }
|
|
159
|
+
* ```
|
|
160
|
+
*/
|
|
161
|
+
defineSignal: <K$1 extends keyof TContract["workflows"][TWorkflowName]["signals"]>(signalName: K$1, handler: SignalHandlerImplementation<TContract["workflows"][TWorkflowName]["signals"][K$1] extends SignalDefinition ? TContract["workflows"][TWorkflowName]["signals"][K$1] : never>) => void;
|
|
162
|
+
/**
|
|
163
|
+
* Define a query handler within the workflow implementation
|
|
164
|
+
* Allows the query handler to access workflow state
|
|
165
|
+
*
|
|
166
|
+
* @example
|
|
167
|
+
* ```ts
|
|
168
|
+
* implementation: async (context, args) => {
|
|
169
|
+
* let currentValue = args.initialValue;
|
|
170
|
+
*
|
|
171
|
+
* context.defineQuery('getCurrentValue', () => {
|
|
172
|
+
* return { value: currentValue };
|
|
173
|
+
* });
|
|
174
|
+
*
|
|
175
|
+
* // ... rest of workflow
|
|
176
|
+
* }
|
|
177
|
+
* ```
|
|
178
|
+
*/
|
|
179
|
+
defineQuery: <K$1 extends keyof TContract["workflows"][TWorkflowName]["queries"]>(queryName: K$1, handler: QueryHandlerImplementation<TContract["workflows"][TWorkflowName]["queries"][K$1] extends QueryDefinition ? TContract["workflows"][TWorkflowName]["queries"][K$1] : never>) => void;
|
|
180
|
+
/**
|
|
181
|
+
* Define an update handler within the workflow implementation
|
|
182
|
+
* Allows the update handler to access and modify workflow state
|
|
183
|
+
*
|
|
184
|
+
* @example
|
|
185
|
+
* ```ts
|
|
186
|
+
* implementation: async (context, args) => {
|
|
187
|
+
* let currentValue = args.initialValue;
|
|
188
|
+
*
|
|
189
|
+
* context.defineUpdate('multiply', async (updateArgs) => {
|
|
190
|
+
* currentValue *= updateArgs.factor;
|
|
191
|
+
* return { newValue: currentValue };
|
|
192
|
+
* });
|
|
193
|
+
*
|
|
194
|
+
* // ... rest of workflow
|
|
195
|
+
* }
|
|
196
|
+
* ```
|
|
197
|
+
*/
|
|
198
|
+
defineUpdate: <K$1 extends keyof TContract["workflows"][TWorkflowName]["updates"]>(updateName: K$1, handler: UpdateHandlerImplementation<TContract["workflows"][TWorkflowName]["updates"][K$1] extends UpdateDefinition ? TContract["workflows"][TWorkflowName]["updates"][K$1] : never>) => void;
|
|
199
|
+
/**
|
|
200
|
+
* Start a child workflow and return a typed handle with Future/Result pattern
|
|
201
|
+
*
|
|
202
|
+
* Supports both same-contract and cross-contract child workflows:
|
|
203
|
+
* - Same contract: Pass workflowName from current contract
|
|
204
|
+
* - Cross-contract: Pass contract and workflowName to invoke workflows from other workers
|
|
205
|
+
*
|
|
206
|
+
* @example
|
|
207
|
+
* ```ts
|
|
208
|
+
* // Same contract child workflow
|
|
209
|
+
* const childResult = await context.startChildWorkflow(myContract, 'processPayment', {
|
|
210
|
+
* workflowId: 'payment-123',
|
|
211
|
+
* args: { amount: 100 }
|
|
212
|
+
* });
|
|
213
|
+
*
|
|
214
|
+
* // Cross-contract child workflow (from another worker)
|
|
215
|
+
* const otherResult = await context.startChildWorkflow(otherContract, 'sendNotification', {
|
|
216
|
+
* workflowId: 'notification-123',
|
|
217
|
+
* args: { message: 'Hello' }
|
|
218
|
+
* });
|
|
219
|
+
*
|
|
220
|
+
* childResult.match({
|
|
221
|
+
* Ok: async (handle) => {
|
|
222
|
+
* const result = await handle.result();
|
|
223
|
+
* // ... handle result
|
|
224
|
+
* },
|
|
225
|
+
* Error: (error) => console.error('Failed to start:', error),
|
|
226
|
+
* });
|
|
227
|
+
* ```
|
|
228
|
+
*/
|
|
229
|
+
startChildWorkflow: <TChildContract extends ContractDefinition, TChildWorkflowName extends keyof TChildContract["workflows"]>(contract: TChildContract, workflowName: TChildWorkflowName, options: TypedChildWorkflowOptions<TChildContract, TChildWorkflowName>) => Future<Result<TypedChildWorkflowHandle<TChildContract["workflows"][TChildWorkflowName]>, ChildWorkflowError>>;
|
|
230
|
+
/**
|
|
231
|
+
* Execute a child workflow (start and wait for result) with Future/Result pattern
|
|
232
|
+
*
|
|
233
|
+
* Supports both same-contract and cross-contract child workflows:
|
|
234
|
+
* - Same contract: Pass workflowName from current contract
|
|
235
|
+
* - Cross-contract: Pass contract and workflowName to invoke workflows from other workers
|
|
236
|
+
*
|
|
237
|
+
* @example
|
|
238
|
+
* ```ts
|
|
239
|
+
* // Same contract child workflow
|
|
240
|
+
* const result = await context.executeChildWorkflow(myContract, 'processPayment', {
|
|
241
|
+
* workflowId: 'payment-123',
|
|
242
|
+
* args: { amount: 100 }
|
|
243
|
+
* });
|
|
244
|
+
*
|
|
245
|
+
* // Cross-contract child workflow (from another worker)
|
|
246
|
+
* const otherResult = await context.executeChildWorkflow(otherContract, 'sendNotification', {
|
|
247
|
+
* workflowId: 'notification-123',
|
|
248
|
+
* args: { message: 'Hello' }
|
|
249
|
+
* });
|
|
250
|
+
*
|
|
251
|
+
* result.match({
|
|
252
|
+
* Ok: (output) => console.log('Payment processed:', output),
|
|
253
|
+
* Error: (error) => console.error('Processing failed:', error),
|
|
254
|
+
* });
|
|
255
|
+
* ```
|
|
256
|
+
*/
|
|
257
|
+
executeChildWorkflow: <TChildContract extends ContractDefinition, TChildWorkflowName extends keyof TChildContract["workflows"]>(contract: TChildContract, workflowName: TChildWorkflowName, options: TypedChildWorkflowOptions<TChildContract, TChildWorkflowName>) => Future<Result<ClientInferOutput<TChildContract["workflows"][TChildWorkflowName]>, ChildWorkflowError>>;
|
|
258
|
+
}
|
|
259
|
+
/**
|
|
260
|
+
* Options for starting a child workflow
|
|
261
|
+
*/
|
|
262
|
+
type TypedChildWorkflowOptions<TChildContract extends ContractDefinition, TChildWorkflowName extends keyof TChildContract["workflows"]> = Omit<ChildWorkflowOptions, "taskQueue" | "args"> & {
|
|
263
|
+
args: ClientInferInput<TChildContract["workflows"][TChildWorkflowName]>;
|
|
264
|
+
};
|
|
265
|
+
/**
|
|
266
|
+
* Typed handle for a child workflow with Future/Result pattern
|
|
267
|
+
*/
|
|
268
|
+
interface TypedChildWorkflowHandle<TWorkflow extends WorkflowDefinition> {
|
|
269
|
+
/**
|
|
270
|
+
* Get child workflow result with Result pattern
|
|
271
|
+
*/
|
|
272
|
+
result: () => Future<Result<ClientInferOutput<TWorkflow>, ChildWorkflowError>>;
|
|
273
|
+
/**
|
|
274
|
+
* Child workflow ID
|
|
275
|
+
*/
|
|
276
|
+
workflowId: string;
|
|
277
|
+
}
|
|
278
|
+
/**
|
|
279
|
+
* Activity function signature from workflow execution perspective
|
|
280
|
+
*
|
|
281
|
+
* Workflows call activities with validated input (z.input parsed) and receive validated output (z.output)
|
|
282
|
+
*/
|
|
283
|
+
type WorkflowInferActivity<TActivity extends ActivityDefinition> = (args: ClientInferInput<TActivity>) => Promise<ClientInferOutput<TActivity>>;
|
|
284
|
+
/**
|
|
285
|
+
* All global activities from a contract (workflow execution perspective)
|
|
286
|
+
*/
|
|
287
|
+
type WorkflowInferActivities<TContract extends ContractDefinition> = TContract["activities"] extends Record<string, ActivityDefinition> ? { [K in keyof TContract["activities"]]: WorkflowInferActivity<TContract["activities"][K]> } : {};
|
|
288
|
+
/**
|
|
289
|
+
* Workflow-specific activities (workflow execution perspective)
|
|
290
|
+
*/
|
|
291
|
+
type WorkflowInferWorkflowActivities<T extends WorkflowDefinition> = T["activities"] extends Record<string, ActivityDefinition> ? { [K in keyof T["activities"]]: WorkflowInferActivity<T["activities"][K]> } : {};
|
|
292
|
+
/**
|
|
293
|
+
* All activities available in a workflow context (workflow execution perspective)
|
|
294
|
+
*
|
|
295
|
+
* Combines workflow-specific activities with global contract activities
|
|
296
|
+
*/
|
|
297
|
+
type WorkflowInferWorkflowContextActivities<TContract extends ContractDefinition, TWorkflowName extends keyof TContract["workflows"]> = WorkflowInferWorkflowActivities<TContract["workflows"][TWorkflowName]> & WorkflowInferActivities<TContract>;
|
|
298
|
+
//#endregion
|
|
299
|
+
export { ActivityInputValidationError, ActivityOutputValidationError, ChildWorkflowError, ChildWorkflowNotFoundError, QueryInputValidationError, QueryOutputValidationError, SignalInputValidationError, UpdateInputValidationError, UpdateOutputValidationError, WorkflowInputValidationError, WorkflowOutputValidationError, declareWorkflow };
|