@temporal-contract/worker 0.0.1
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/.turbo/turbo-build.log +25 -0
- package/LICENSE +21 -0
- package/README.md +128 -0
- package/dist/activity.cjs +8 -0
- package/dist/activity.d.cts +2 -0
- package/dist/activity.d.mts +2 -0
- package/dist/activity.mjs +3 -0
- package/dist/errors-CqX81ysy.d.cts +302 -0
- package/dist/errors-oc-Iiwmu.d.mts +302 -0
- package/dist/handler-B3KY0uDx.cjs +492 -0
- package/dist/handler-aA2RFdV7.mjs +409 -0
- package/dist/workflow.cjs +11 -0
- package/dist/workflow.d.cts +2 -0
- package/dist/workflow.d.mts +2 -0
- package/dist/workflow.mjs +3 -0
- package/package.json +72 -0
- package/src/activity.ts +15 -0
- package/src/errors.ts +164 -0
- package/src/handler.spec.ts +525 -0
- package/src/handler.ts +621 -0
- package/src/workflow.ts +20 -0
- package/tsconfig.json +9 -0
|
@@ -0,0 +1,409 @@
|
|
|
1
|
+
import { defineQuery, defineSignal, defineUpdate, proxyActivities, setHandler, workflowInfo } from "@temporalio/workflow";
|
|
2
|
+
import { ZodError } from "zod";
|
|
3
|
+
|
|
4
|
+
//#region src/errors.ts
|
|
5
|
+
/**
|
|
6
|
+
* Base error class for worker errors
|
|
7
|
+
*/
|
|
8
|
+
var WorkerError = class extends Error {
|
|
9
|
+
constructor(message) {
|
|
10
|
+
super(message);
|
|
11
|
+
this.name = "WorkerError";
|
|
12
|
+
if (Error.captureStackTrace) Error.captureStackTrace(this, this.constructor);
|
|
13
|
+
}
|
|
14
|
+
};
|
|
15
|
+
/**
|
|
16
|
+
* Error thrown when an activity implementation is not found
|
|
17
|
+
*/
|
|
18
|
+
var ActivityImplementationNotFoundError = class extends WorkerError {
|
|
19
|
+
constructor(activityName, availableActivities) {
|
|
20
|
+
super(`Activity implementation not found for: "${activityName}". Available activities: ${availableActivities.length > 0 ? availableActivities.join(", ") : "none"}`);
|
|
21
|
+
this.activityName = activityName;
|
|
22
|
+
this.availableActivities = availableActivities;
|
|
23
|
+
this.name = "ActivityImplementationNotFoundError";
|
|
24
|
+
}
|
|
25
|
+
};
|
|
26
|
+
/**
|
|
27
|
+
* Error thrown when an activity definition is not found in the contract
|
|
28
|
+
*/
|
|
29
|
+
var ActivityDefinitionNotFoundError = class extends WorkerError {
|
|
30
|
+
constructor(activityName, availableDefinitions) {
|
|
31
|
+
super(`Activity definition not found in contract for: "${activityName}". Available definitions: ${availableDefinitions.length > 0 ? availableDefinitions.join(", ") : "none"}`);
|
|
32
|
+
this.activityName = activityName;
|
|
33
|
+
this.availableDefinitions = availableDefinitions;
|
|
34
|
+
this.name = "ActivityDefinitionNotFoundError";
|
|
35
|
+
}
|
|
36
|
+
};
|
|
37
|
+
/**
|
|
38
|
+
* Error thrown when activity input validation fails
|
|
39
|
+
*/
|
|
40
|
+
var ActivityInputValidationError = class extends WorkerError {
|
|
41
|
+
constructor(activityName, zodError) {
|
|
42
|
+
super(`Activity "${activityName}" input validation failed: ${zodError.message}`);
|
|
43
|
+
this.activityName = activityName;
|
|
44
|
+
this.zodError = zodError;
|
|
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, zodError) {
|
|
53
|
+
super(`Activity "${activityName}" output validation failed: ${zodError.message}`);
|
|
54
|
+
this.activityName = activityName;
|
|
55
|
+
this.zodError = zodError;
|
|
56
|
+
this.name = "ActivityOutputValidationError";
|
|
57
|
+
}
|
|
58
|
+
};
|
|
59
|
+
/**
|
|
60
|
+
* Error thrown when workflow input validation fails
|
|
61
|
+
*/
|
|
62
|
+
var WorkflowInputValidationError = class extends WorkerError {
|
|
63
|
+
constructor(workflowName, zodError) {
|
|
64
|
+
super(`Workflow "${workflowName}" input validation failed: ${zodError.message}`);
|
|
65
|
+
this.workflowName = workflowName;
|
|
66
|
+
this.zodError = zodError;
|
|
67
|
+
this.name = "WorkflowInputValidationError";
|
|
68
|
+
}
|
|
69
|
+
};
|
|
70
|
+
/**
|
|
71
|
+
* Error thrown when workflow output validation fails
|
|
72
|
+
*/
|
|
73
|
+
var WorkflowOutputValidationError = class extends WorkerError {
|
|
74
|
+
constructor(workflowName, zodError) {
|
|
75
|
+
super(`Workflow "${workflowName}" output validation failed: ${zodError.message}`);
|
|
76
|
+
this.workflowName = workflowName;
|
|
77
|
+
this.zodError = zodError;
|
|
78
|
+
this.name = "WorkflowOutputValidationError";
|
|
79
|
+
}
|
|
80
|
+
};
|
|
81
|
+
/**
|
|
82
|
+
* Error thrown when signal input validation fails
|
|
83
|
+
*/
|
|
84
|
+
var SignalInputValidationError = class extends WorkerError {
|
|
85
|
+
constructor(signalName, zodError) {
|
|
86
|
+
super(`Signal "${signalName}" input validation failed: ${zodError.message}`);
|
|
87
|
+
this.signalName = signalName;
|
|
88
|
+
this.zodError = zodError;
|
|
89
|
+
this.name = "SignalInputValidationError";
|
|
90
|
+
}
|
|
91
|
+
};
|
|
92
|
+
/**
|
|
93
|
+
* Error thrown when query input validation fails
|
|
94
|
+
*/
|
|
95
|
+
var QueryInputValidationError = class extends WorkerError {
|
|
96
|
+
constructor(queryName, zodError) {
|
|
97
|
+
super(`Query "${queryName}" input validation failed: ${zodError.message}`);
|
|
98
|
+
this.queryName = queryName;
|
|
99
|
+
this.zodError = zodError;
|
|
100
|
+
this.name = "QueryInputValidationError";
|
|
101
|
+
}
|
|
102
|
+
};
|
|
103
|
+
/**
|
|
104
|
+
* Error thrown when query output validation fails
|
|
105
|
+
*/
|
|
106
|
+
var QueryOutputValidationError = class extends WorkerError {
|
|
107
|
+
constructor(queryName, zodError) {
|
|
108
|
+
super(`Query "${queryName}" output validation failed: ${zodError.message}`);
|
|
109
|
+
this.queryName = queryName;
|
|
110
|
+
this.zodError = zodError;
|
|
111
|
+
this.name = "QueryOutputValidationError";
|
|
112
|
+
}
|
|
113
|
+
};
|
|
114
|
+
/**
|
|
115
|
+
* Error thrown when update input validation fails
|
|
116
|
+
*/
|
|
117
|
+
var UpdateInputValidationError = class extends WorkerError {
|
|
118
|
+
constructor(updateName, zodError) {
|
|
119
|
+
super(`Update "${updateName}" input validation failed: ${zodError.message}`);
|
|
120
|
+
this.updateName = updateName;
|
|
121
|
+
this.zodError = zodError;
|
|
122
|
+
this.name = "UpdateInputValidationError";
|
|
123
|
+
}
|
|
124
|
+
};
|
|
125
|
+
/**
|
|
126
|
+
* Error thrown when update output validation fails
|
|
127
|
+
*/
|
|
128
|
+
var UpdateOutputValidationError = class extends WorkerError {
|
|
129
|
+
constructor(updateName, zodError) {
|
|
130
|
+
super(`Update "${updateName}" output validation failed: ${zodError.message}`);
|
|
131
|
+
this.updateName = updateName;
|
|
132
|
+
this.zodError = zodError;
|
|
133
|
+
this.name = "UpdateOutputValidationError";
|
|
134
|
+
}
|
|
135
|
+
};
|
|
136
|
+
|
|
137
|
+
//#endregion
|
|
138
|
+
//#region src/handler.ts
|
|
139
|
+
/**
|
|
140
|
+
* Create a validated activities proxy that parses inputs and outputs
|
|
141
|
+
*
|
|
142
|
+
* This wrapper ensures data integrity across the network boundary between
|
|
143
|
+
* workflow and activity execution.
|
|
144
|
+
*/
|
|
145
|
+
function createValidatedActivities(rawActivities, workflowActivitiesDefinition, contractActivitiesDefinition) {
|
|
146
|
+
const validatedActivities = {};
|
|
147
|
+
const allActivitiesDefinition = {
|
|
148
|
+
...contractActivitiesDefinition,
|
|
149
|
+
...workflowActivitiesDefinition
|
|
150
|
+
};
|
|
151
|
+
for (const [activityName, activityDef] of Object.entries(allActivitiesDefinition)) {
|
|
152
|
+
const rawActivity = rawActivities[activityName];
|
|
153
|
+
if (!rawActivity) throw new ActivityImplementationNotFoundError(activityName, Object.keys(rawActivities));
|
|
154
|
+
validatedActivities[activityName] = async (input) => {
|
|
155
|
+
let validatedInput;
|
|
156
|
+
try {
|
|
157
|
+
validatedInput = activityDef.input.parse(input);
|
|
158
|
+
} catch (error) {
|
|
159
|
+
if (error instanceof ZodError) throw new ActivityInputValidationError(activityName, error);
|
|
160
|
+
throw error;
|
|
161
|
+
}
|
|
162
|
+
const result = await rawActivity(validatedInput);
|
|
163
|
+
try {
|
|
164
|
+
return activityDef.output.parse(result);
|
|
165
|
+
} catch (error) {
|
|
166
|
+
if (error instanceof ZodError) throw new ActivityOutputValidationError(activityName, error);
|
|
167
|
+
throw error;
|
|
168
|
+
}
|
|
169
|
+
};
|
|
170
|
+
}
|
|
171
|
+
return validatedActivities;
|
|
172
|
+
}
|
|
173
|
+
/**
|
|
174
|
+
* Create a typed activities handler with automatic validation
|
|
175
|
+
*
|
|
176
|
+
* This wraps all activity implementations with Zod validation at network boundaries.
|
|
177
|
+
* TypeScript ensures ALL activities (global + workflow-specific) are implemented.
|
|
178
|
+
*
|
|
179
|
+
* Use this to create the activities object for the Temporal Worker.
|
|
180
|
+
*
|
|
181
|
+
* @example
|
|
182
|
+
* ```ts
|
|
183
|
+
* import { declareActivitiesHandler } from '@temporal-contract/worker';
|
|
184
|
+
* import myContract from './contract';
|
|
185
|
+
*
|
|
186
|
+
* export const activitiesHandler = declareActivitiesHandler({
|
|
187
|
+
* contract: myContract,
|
|
188
|
+
* activities: {
|
|
189
|
+
* // Global activities
|
|
190
|
+
* sendEmail: async (to, subject, body) => {
|
|
191
|
+
* await emailService.send({ to, subject, body });
|
|
192
|
+
* return { sent: true };
|
|
193
|
+
* },
|
|
194
|
+
* // Workflow-specific activities
|
|
195
|
+
* validateInventory: async (orderId) => {
|
|
196
|
+
* const available = await inventory.check(orderId);
|
|
197
|
+
* return { available };
|
|
198
|
+
* },
|
|
199
|
+
* },
|
|
200
|
+
* });
|
|
201
|
+
*
|
|
202
|
+
* // Use with Temporal Worker
|
|
203
|
+
* import { Worker } from '@temporalio/worker';
|
|
204
|
+
*
|
|
205
|
+
* const worker = await Worker.create({
|
|
206
|
+
* workflowsPath: require.resolve('./workflows'),
|
|
207
|
+
* activities: activitiesHandler.activities,
|
|
208
|
+
* taskQueue: activitiesHandler.contract.taskQueue,
|
|
209
|
+
* });
|
|
210
|
+
* ```
|
|
211
|
+
*/
|
|
212
|
+
function declareActivitiesHandler(options) {
|
|
213
|
+
const { contract, activities } = options;
|
|
214
|
+
const wrappedActivities = {};
|
|
215
|
+
const allDefinitions = [];
|
|
216
|
+
if (contract.activities) allDefinitions.push(...Object.keys(contract.activities));
|
|
217
|
+
for (const workflow of Object.values(contract.workflows)) if (workflow.activities) allDefinitions.push(...Object.keys(workflow.activities));
|
|
218
|
+
for (const [activityName, activityImpl] of Object.entries(activities)) {
|
|
219
|
+
let activityDef;
|
|
220
|
+
if (contract.activities?.[activityName]) activityDef = contract.activities[activityName];
|
|
221
|
+
else for (const workflow of Object.values(contract.workflows)) if (workflow.activities?.[activityName]) {
|
|
222
|
+
activityDef = workflow.activities[activityName];
|
|
223
|
+
break;
|
|
224
|
+
}
|
|
225
|
+
if (!activityDef) throw new ActivityDefinitionNotFoundError(activityName, allDefinitions);
|
|
226
|
+
wrappedActivities[activityName] = async (input) => {
|
|
227
|
+
let validatedInput;
|
|
228
|
+
try {
|
|
229
|
+
validatedInput = activityDef.input.parse(input);
|
|
230
|
+
} catch (error) {
|
|
231
|
+
if (error instanceof ZodError) throw new ActivityInputValidationError(activityName, error);
|
|
232
|
+
throw error;
|
|
233
|
+
}
|
|
234
|
+
const result = await activityImpl(validatedInput);
|
|
235
|
+
try {
|
|
236
|
+
return activityDef.output.parse(result);
|
|
237
|
+
} catch (error) {
|
|
238
|
+
if (error instanceof ZodError) throw new ActivityOutputValidationError(activityName, error);
|
|
239
|
+
throw error;
|
|
240
|
+
}
|
|
241
|
+
};
|
|
242
|
+
}
|
|
243
|
+
return {
|
|
244
|
+
contract,
|
|
245
|
+
activities: wrappedActivities
|
|
246
|
+
};
|
|
247
|
+
}
|
|
248
|
+
/**
|
|
249
|
+
* Create a typed workflow implementation with automatic validation
|
|
250
|
+
*
|
|
251
|
+
* This wraps a workflow implementation with:
|
|
252
|
+
* - Input/output validation
|
|
253
|
+
* - Typed workflow context with activities
|
|
254
|
+
* - Workflow info access
|
|
255
|
+
*
|
|
256
|
+
* Workflows must be defined in separate files and imported by the Temporal Worker
|
|
257
|
+
* via workflowsPath.
|
|
258
|
+
*
|
|
259
|
+
* @example
|
|
260
|
+
* ```ts
|
|
261
|
+
* // workflows/processOrder.ts
|
|
262
|
+
* import { declareWorkflow } from '@temporal-contract/worker';
|
|
263
|
+
* import myContract from '../contract';
|
|
264
|
+
*
|
|
265
|
+
* export const processOrder = declareWorkflow({
|
|
266
|
+
* workflowName: 'processOrder',
|
|
267
|
+
* contract: myContract,
|
|
268
|
+
* implementation: async (context, orderId, customerId) => {
|
|
269
|
+
* // context.activities: typed activities (workflow + global)
|
|
270
|
+
* // context.info: WorkflowInfo
|
|
271
|
+
*
|
|
272
|
+
* const inventory = await context.activities.validateInventory(orderId);
|
|
273
|
+
*
|
|
274
|
+
* if (!inventory.available) {
|
|
275
|
+
* throw new Error('Out of stock');
|
|
276
|
+
* }
|
|
277
|
+
*
|
|
278
|
+
* const payment = await context.activities.chargePayment(customerId, 100);
|
|
279
|
+
*
|
|
280
|
+
* // Global activity
|
|
281
|
+
* await context.activities.sendEmail(
|
|
282
|
+
* customerId,
|
|
283
|
+
* 'Order processed',
|
|
284
|
+
* 'Your order has been processed'
|
|
285
|
+
* );
|
|
286
|
+
*
|
|
287
|
+
* return {
|
|
288
|
+
* orderId,
|
|
289
|
+
* status: payment.success ? 'success' : 'failed',
|
|
290
|
+
* transactionId: payment.transactionId,
|
|
291
|
+
* };
|
|
292
|
+
* },
|
|
293
|
+
* activityOptions: {
|
|
294
|
+
* startToCloseTimeout: '1 minute',
|
|
295
|
+
* },
|
|
296
|
+
* });
|
|
297
|
+
* ```
|
|
298
|
+
*
|
|
299
|
+
* Then in your worker setup:
|
|
300
|
+
* ```ts
|
|
301
|
+
* // worker.ts
|
|
302
|
+
* import { Worker } from '@temporalio/worker';
|
|
303
|
+
* import { activitiesHandler } from './activities';
|
|
304
|
+
*
|
|
305
|
+
* const worker = await Worker.create({
|
|
306
|
+
* workflowsPath: require.resolve('./workflows'), // Imports processOrder
|
|
307
|
+
* activities: activitiesHandler.activities,
|
|
308
|
+
* taskQueue: activitiesHandler.contract.taskQueue,
|
|
309
|
+
* });
|
|
310
|
+
* ```
|
|
311
|
+
*/
|
|
312
|
+
function declareWorkflow(options) {
|
|
313
|
+
const { workflowName, contract, implementation, activityOptions, signals, queries, updates } = options;
|
|
314
|
+
const definition = contract.workflows[workflowName];
|
|
315
|
+
return async (args) => {
|
|
316
|
+
const singleArg = Array.isArray(args) ? args[0] : args;
|
|
317
|
+
let validatedInput;
|
|
318
|
+
try {
|
|
319
|
+
validatedInput = definition.input.parse(singleArg);
|
|
320
|
+
} catch (error) {
|
|
321
|
+
if (error instanceof ZodError) throw new WorkflowInputValidationError(String(workflowName), error);
|
|
322
|
+
throw error;
|
|
323
|
+
}
|
|
324
|
+
if (definition.signals && signals) {
|
|
325
|
+
const signalDefs = definition.signals;
|
|
326
|
+
const signalHandlers = signals;
|
|
327
|
+
for (const [signalName, signalDef] of Object.entries(signalDefs)) {
|
|
328
|
+
const handler = signalHandlers[signalName];
|
|
329
|
+
if (handler) setHandler(defineSignal(signalName), async (...args$1) => {
|
|
330
|
+
const input = args$1.length === 1 ? args$1[0] : args$1;
|
|
331
|
+
let validatedInput$1;
|
|
332
|
+
try {
|
|
333
|
+
validatedInput$1 = signalDef.input.parse(input);
|
|
334
|
+
} catch (error) {
|
|
335
|
+
if (error instanceof ZodError) throw new SignalInputValidationError(signalName, error);
|
|
336
|
+
throw error;
|
|
337
|
+
}
|
|
338
|
+
await handler(validatedInput$1);
|
|
339
|
+
});
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
if (definition.queries && queries) {
|
|
343
|
+
const queryDefs = definition.queries;
|
|
344
|
+
const queryHandlers = queries;
|
|
345
|
+
for (const [queryName, queryDef] of Object.entries(queryDefs)) {
|
|
346
|
+
const handler = queryHandlers[queryName];
|
|
347
|
+
if (handler) setHandler(defineQuery(queryName), (...args$1) => {
|
|
348
|
+
const input = args$1.length === 1 ? args$1[0] : args$1;
|
|
349
|
+
let validatedInput$1;
|
|
350
|
+
try {
|
|
351
|
+
validatedInput$1 = queryDef.input.parse(input);
|
|
352
|
+
} catch (error) {
|
|
353
|
+
if (error instanceof ZodError) throw new QueryInputValidationError(queryName, error);
|
|
354
|
+
throw error;
|
|
355
|
+
}
|
|
356
|
+
const result$1 = handler(validatedInput$1);
|
|
357
|
+
try {
|
|
358
|
+
return queryDef.output.parse(result$1);
|
|
359
|
+
} catch (error) {
|
|
360
|
+
if (error instanceof ZodError) throw new QueryOutputValidationError(queryName, error);
|
|
361
|
+
throw error;
|
|
362
|
+
}
|
|
363
|
+
});
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
if (definition.updates && updates) {
|
|
367
|
+
const updateDefs = definition.updates;
|
|
368
|
+
const updateHandlers = updates;
|
|
369
|
+
for (const [updateName, updateDef] of Object.entries(updateDefs)) {
|
|
370
|
+
const handler = updateHandlers[updateName];
|
|
371
|
+
if (handler) setHandler(defineUpdate(updateName), async (...args$1) => {
|
|
372
|
+
const input = args$1.length === 1 ? args$1[0] : args$1;
|
|
373
|
+
let validatedInput$1;
|
|
374
|
+
try {
|
|
375
|
+
validatedInput$1 = updateDef.input.parse(input);
|
|
376
|
+
} catch (error) {
|
|
377
|
+
if (error instanceof ZodError) throw new UpdateInputValidationError(updateName, error);
|
|
378
|
+
throw error;
|
|
379
|
+
}
|
|
380
|
+
const result$1 = await handler(validatedInput$1);
|
|
381
|
+
try {
|
|
382
|
+
return updateDef.output.parse(result$1);
|
|
383
|
+
} catch (error) {
|
|
384
|
+
if (error instanceof ZodError) throw new UpdateOutputValidationError(updateName, error);
|
|
385
|
+
throw error;
|
|
386
|
+
}
|
|
387
|
+
});
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
let contextActivities = {};
|
|
391
|
+
if (definition.activities || contract.activities) contextActivities = createValidatedActivities(proxyActivities({
|
|
392
|
+
startToCloseTimeout: activityOptions?.startToCloseTimeout ?? 6e4,
|
|
393
|
+
...activityOptions
|
|
394
|
+
}), definition.activities, contract.activities);
|
|
395
|
+
const result = await implementation({
|
|
396
|
+
activities: contextActivities,
|
|
397
|
+
info: workflowInfo()
|
|
398
|
+
}, validatedInput);
|
|
399
|
+
try {
|
|
400
|
+
return definition.output.parse(result);
|
|
401
|
+
} catch (error) {
|
|
402
|
+
if (error instanceof ZodError) throw new WorkflowOutputValidationError(String(workflowName), error);
|
|
403
|
+
throw error;
|
|
404
|
+
}
|
|
405
|
+
};
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
//#endregion
|
|
409
|
+
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 };
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
const require_handler = require('./handler-B3KY0uDx.cjs');
|
|
2
|
+
|
|
3
|
+
exports.QueryInputValidationError = require_handler.QueryInputValidationError;
|
|
4
|
+
exports.QueryOutputValidationError = require_handler.QueryOutputValidationError;
|
|
5
|
+
exports.SignalInputValidationError = require_handler.SignalInputValidationError;
|
|
6
|
+
exports.UpdateInputValidationError = require_handler.UpdateInputValidationError;
|
|
7
|
+
exports.UpdateOutputValidationError = require_handler.UpdateOutputValidationError;
|
|
8
|
+
exports.WorkerError = require_handler.WorkerError;
|
|
9
|
+
exports.WorkflowInputValidationError = require_handler.WorkflowInputValidationError;
|
|
10
|
+
exports.WorkflowOutputValidationError = require_handler.WorkflowOutputValidationError;
|
|
11
|
+
exports.declareWorkflow = require_handler.declareWorkflow;
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import { S as WorkflowImplementation, _ as QueryHandlerImplementation, a as QueryInputValidationError, b as UpdateHandlerImplementation, c as UpdateInputValidationError, d as WorkflowInputValidationError, f as WorkflowOutputValidationError, g as DeclareWorkflowOptions, l as UpdateOutputValidationError, o as QueryOutputValidationError, s as SignalInputValidationError, u as WorkerError, w as declareWorkflow, x as WorkflowContext, y as SignalHandlerImplementation } from "./errors-CqX81ysy.cjs";
|
|
2
|
+
export { type DeclareWorkflowOptions, type QueryHandlerImplementation, QueryInputValidationError, QueryOutputValidationError, type SignalHandlerImplementation, SignalInputValidationError, type UpdateHandlerImplementation, UpdateInputValidationError, UpdateOutputValidationError, WorkerError, type WorkflowContext, type WorkflowImplementation, WorkflowInputValidationError, WorkflowOutputValidationError, declareWorkflow };
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import { S as WorkflowImplementation, _ as QueryHandlerImplementation, a as QueryInputValidationError, b as UpdateHandlerImplementation, c as UpdateInputValidationError, d as WorkflowInputValidationError, f as WorkflowOutputValidationError, g as DeclareWorkflowOptions, l as UpdateOutputValidationError, o as QueryOutputValidationError, s as SignalInputValidationError, u as WorkerError, w as declareWorkflow, x as WorkflowContext, y as SignalHandlerImplementation } from "./errors-oc-Iiwmu.mjs";
|
|
2
|
+
export { type DeclareWorkflowOptions, type QueryHandlerImplementation, QueryInputValidationError, QueryOutputValidationError, type SignalHandlerImplementation, SignalInputValidationError, type UpdateHandlerImplementation, UpdateInputValidationError, UpdateOutputValidationError, WorkerError, type WorkflowContext, type WorkflowImplementation, WorkflowInputValidationError, WorkflowOutputValidationError, declareWorkflow };
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import { c as QueryOutputValidationError, d as UpdateOutputValidationError, f as WorkerError, l as SignalInputValidationError, m as WorkflowOutputValidationError, n as declareWorkflow, p as WorkflowInputValidationError, s as QueryInputValidationError, u as UpdateInputValidationError } from "./handler-aA2RFdV7.mjs";
|
|
2
|
+
|
|
3
|
+
export { QueryInputValidationError, QueryOutputValidationError, SignalInputValidationError, UpdateInputValidationError, UpdateOutputValidationError, WorkerError, WorkflowInputValidationError, WorkflowOutputValidationError, declareWorkflow };
|
package/package.json
ADDED
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@temporal-contract/worker",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"description": "Worker utilities for implementing temporal-contract workflows and activities",
|
|
6
|
+
"homepage": "https://github.com/btravers/temporal-contract#readme",
|
|
7
|
+
"bugs": {
|
|
8
|
+
"url": "https://github.com/btravers/temporal-contract/issues"
|
|
9
|
+
},
|
|
10
|
+
"repository": {
|
|
11
|
+
"type": "git",
|
|
12
|
+
"url": "https://github.com/btravers/temporal-contract.git",
|
|
13
|
+
"directory": "packages/worker"
|
|
14
|
+
},
|
|
15
|
+
"author": "Benoit TRAVERS <benoit.travers.frgmail.com>",
|
|
16
|
+
"license": "MIT",
|
|
17
|
+
"keywords": [
|
|
18
|
+
"temporal",
|
|
19
|
+
"typescript",
|
|
20
|
+
"contract",
|
|
21
|
+
"worker"
|
|
22
|
+
],
|
|
23
|
+
"main": "./dist/index.cjs",
|
|
24
|
+
"module": "./dist/index.mjs",
|
|
25
|
+
"types": "./dist/index.d.mts",
|
|
26
|
+
"exports": {
|
|
27
|
+
"./activity": {
|
|
28
|
+
"import": {
|
|
29
|
+
"types": "./dist/activity.d.mts",
|
|
30
|
+
"default": "./dist/activity.mjs"
|
|
31
|
+
},
|
|
32
|
+
"require": {
|
|
33
|
+
"types": "./dist/activity.d.cts",
|
|
34
|
+
"default": "./dist/activity.cjs"
|
|
35
|
+
}
|
|
36
|
+
},
|
|
37
|
+
"./workflow": {
|
|
38
|
+
"import": {
|
|
39
|
+
"types": "./dist/workflow.d.mts",
|
|
40
|
+
"default": "./dist/workflow.mjs"
|
|
41
|
+
},
|
|
42
|
+
"require": {
|
|
43
|
+
"types": "./dist/workflow.d.cts",
|
|
44
|
+
"default": "./dist/workflow.cjs"
|
|
45
|
+
}
|
|
46
|
+
},
|
|
47
|
+
"./package.json": "./package.json"
|
|
48
|
+
},
|
|
49
|
+
"dependencies": {
|
|
50
|
+
"@temporal-contract/contract": "0.0.1"
|
|
51
|
+
},
|
|
52
|
+
"devDependencies": {
|
|
53
|
+
"@temporalio/workflow": "1.13.2",
|
|
54
|
+
"@types/node": "24.10.2",
|
|
55
|
+
"tsdown": "0.17.2",
|
|
56
|
+
"typescript": "5.9.3",
|
|
57
|
+
"vitest": "4.0.15",
|
|
58
|
+
"zod": "4.1.13",
|
|
59
|
+
"@temporal-contract/tsconfig": "0.0.1"
|
|
60
|
+
},
|
|
61
|
+
"peerDependencies": {
|
|
62
|
+
"@temporalio/workflow": ">=1.13.0 <2.0.0",
|
|
63
|
+
"zod": "^4.0.0"
|
|
64
|
+
},
|
|
65
|
+
"scripts": {
|
|
66
|
+
"dev": "tsdown src/activity.ts src/workflow.ts --format cjs,esm --dts --watch",
|
|
67
|
+
"build": "tsdown src/activity.ts src/workflow.ts --format cjs,esm --dts --clean",
|
|
68
|
+
"typecheck": "tsc --noEmit",
|
|
69
|
+
"test": "vitest run",
|
|
70
|
+
"test:watch": "vitest"
|
|
71
|
+
}
|
|
72
|
+
}
|
package/src/activity.ts
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
// Entry point for activities
|
|
2
|
+
export { declareActivitiesHandler } from "./handler.js";
|
|
3
|
+
export type {
|
|
4
|
+
RawActivityImplementation,
|
|
5
|
+
ActivityImplementations,
|
|
6
|
+
DeclareActivitiesHandlerOptions,
|
|
7
|
+
ActivitiesHandler,
|
|
8
|
+
} from "./handler.js";
|
|
9
|
+
export {
|
|
10
|
+
WorkerError,
|
|
11
|
+
ActivityImplementationNotFoundError,
|
|
12
|
+
ActivityDefinitionNotFoundError,
|
|
13
|
+
ActivityInputValidationError,
|
|
14
|
+
ActivityOutputValidationError,
|
|
15
|
+
} from "./errors.js";
|
package/src/errors.ts
ADDED
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
import type { z } from "zod";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Base error class for worker errors
|
|
5
|
+
*/
|
|
6
|
+
export class WorkerError extends Error {
|
|
7
|
+
constructor(message: string) {
|
|
8
|
+
super(message);
|
|
9
|
+
this.name = "WorkerError";
|
|
10
|
+
// Maintains proper stack trace for where our error was thrown (only available on V8)
|
|
11
|
+
if (Error.captureStackTrace) {
|
|
12
|
+
Error.captureStackTrace(this, this.constructor);
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Error thrown when an activity implementation is not found
|
|
19
|
+
*/
|
|
20
|
+
export class ActivityImplementationNotFoundError extends WorkerError {
|
|
21
|
+
constructor(
|
|
22
|
+
public readonly activityName: string,
|
|
23
|
+
public readonly availableActivities: readonly string[],
|
|
24
|
+
) {
|
|
25
|
+
super(
|
|
26
|
+
`Activity implementation not found for: "${activityName}". ` +
|
|
27
|
+
`Available activities: ${availableActivities.length > 0 ? availableActivities.join(", ") : "none"}`,
|
|
28
|
+
);
|
|
29
|
+
this.name = "ActivityImplementationNotFoundError";
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Error thrown when an activity definition is not found in the contract
|
|
35
|
+
*/
|
|
36
|
+
export class ActivityDefinitionNotFoundError extends WorkerError {
|
|
37
|
+
constructor(
|
|
38
|
+
public readonly activityName: string,
|
|
39
|
+
public readonly availableDefinitions: readonly string[],
|
|
40
|
+
) {
|
|
41
|
+
super(
|
|
42
|
+
`Activity definition not found in contract for: "${activityName}". ` +
|
|
43
|
+
`Available definitions: ${availableDefinitions.length > 0 ? availableDefinitions.join(", ") : "none"}`,
|
|
44
|
+
);
|
|
45
|
+
this.name = "ActivityDefinitionNotFoundError";
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Error thrown when activity input validation fails
|
|
51
|
+
*/
|
|
52
|
+
export class ActivityInputValidationError extends WorkerError {
|
|
53
|
+
constructor(
|
|
54
|
+
public readonly activityName: string,
|
|
55
|
+
public readonly zodError: z.ZodError,
|
|
56
|
+
) {
|
|
57
|
+
super(`Activity "${activityName}" input validation failed: ${zodError.message}`);
|
|
58
|
+
this.name = "ActivityInputValidationError";
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Error thrown when activity output validation fails
|
|
64
|
+
*/
|
|
65
|
+
export class ActivityOutputValidationError extends WorkerError {
|
|
66
|
+
constructor(
|
|
67
|
+
public readonly activityName: string,
|
|
68
|
+
public readonly zodError: z.ZodError,
|
|
69
|
+
) {
|
|
70
|
+
super(`Activity "${activityName}" output validation failed: ${zodError.message}`);
|
|
71
|
+
this.name = "ActivityOutputValidationError";
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Error thrown when workflow input validation fails
|
|
77
|
+
*/
|
|
78
|
+
export class WorkflowInputValidationError extends WorkerError {
|
|
79
|
+
constructor(
|
|
80
|
+
public readonly workflowName: string,
|
|
81
|
+
public readonly zodError: z.ZodError,
|
|
82
|
+
) {
|
|
83
|
+
super(`Workflow "${workflowName}" input validation failed: ${zodError.message}`);
|
|
84
|
+
this.name = "WorkflowInputValidationError";
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Error thrown when workflow output validation fails
|
|
90
|
+
*/
|
|
91
|
+
export class WorkflowOutputValidationError extends WorkerError {
|
|
92
|
+
constructor(
|
|
93
|
+
public readonly workflowName: string,
|
|
94
|
+
public readonly zodError: z.ZodError,
|
|
95
|
+
) {
|
|
96
|
+
super(`Workflow "${workflowName}" output validation failed: ${zodError.message}`);
|
|
97
|
+
this.name = "WorkflowOutputValidationError";
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* Error thrown when signal input validation fails
|
|
103
|
+
*/
|
|
104
|
+
export class SignalInputValidationError extends WorkerError {
|
|
105
|
+
constructor(
|
|
106
|
+
public readonly signalName: string,
|
|
107
|
+
public readonly zodError: z.ZodError,
|
|
108
|
+
) {
|
|
109
|
+
super(`Signal "${signalName}" input validation failed: ${zodError.message}`);
|
|
110
|
+
this.name = "SignalInputValidationError";
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* Error thrown when query input validation fails
|
|
116
|
+
*/
|
|
117
|
+
export class QueryInputValidationError extends WorkerError {
|
|
118
|
+
constructor(
|
|
119
|
+
public readonly queryName: string,
|
|
120
|
+
public readonly zodError: z.ZodError,
|
|
121
|
+
) {
|
|
122
|
+
super(`Query "${queryName}" input validation failed: ${zodError.message}`);
|
|
123
|
+
this.name = "QueryInputValidationError";
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* Error thrown when query output validation fails
|
|
129
|
+
*/
|
|
130
|
+
export class QueryOutputValidationError extends WorkerError {
|
|
131
|
+
constructor(
|
|
132
|
+
public readonly queryName: string,
|
|
133
|
+
public readonly zodError: z.ZodError,
|
|
134
|
+
) {
|
|
135
|
+
super(`Query "${queryName}" output validation failed: ${zodError.message}`);
|
|
136
|
+
this.name = "QueryOutputValidationError";
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* Error thrown when update input validation fails
|
|
142
|
+
*/
|
|
143
|
+
export class UpdateInputValidationError extends WorkerError {
|
|
144
|
+
constructor(
|
|
145
|
+
public readonly updateName: string,
|
|
146
|
+
public readonly zodError: z.ZodError,
|
|
147
|
+
) {
|
|
148
|
+
super(`Update "${updateName}" input validation failed: ${zodError.message}`);
|
|
149
|
+
this.name = "UpdateInputValidationError";
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
/**
|
|
154
|
+
* Error thrown when update output validation fails
|
|
155
|
+
*/
|
|
156
|
+
export class UpdateOutputValidationError extends WorkerError {
|
|
157
|
+
constructor(
|
|
158
|
+
public readonly updateName: string,
|
|
159
|
+
public readonly zodError: z.ZodError,
|
|
160
|
+
) {
|
|
161
|
+
super(`Update "${updateName}" output validation failed: ${zodError.message}`);
|
|
162
|
+
this.name = "UpdateOutputValidationError";
|
|
163
|
+
}
|
|
164
|
+
}
|