@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.
@@ -1,481 +0,0 @@
1
- let __temporalio_workflow = require("@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, cause) {
9
- super(message, { cause });
10
- this.name = "WorkerError";
11
- if (Error.captureStackTrace) Error.captureStackTrace(this, this.constructor);
12
- }
13
- };
14
- /**
15
- * Activity error class that should be used to wrap all technical exceptions
16
- * Forces proper error handling and enables retry policies
17
- */
18
- var ActivityError = class ActivityError extends Error {
19
- code;
20
- cause;
21
- constructor(code, message, cause) {
22
- super(message, { cause });
23
- this.code = code;
24
- this.cause = cause;
25
- this.name = "ActivityError";
26
- if (Error.captureStackTrace) Error.captureStackTrace(this, ActivityError);
27
- }
28
- };
29
- /**
30
- * Error thrown when an activity definition is not found in the contract
31
- */
32
- var ActivityDefinitionNotFoundError = class extends WorkerError {
33
- constructor(activityName, availableDefinitions = []) {
34
- const available = availableDefinitions.length > 0 ? availableDefinitions.join(", ") : "none";
35
- super(`Activity definition not found for: "${activityName}". Available activities: ${available}`);
36
- this.activityName = activityName;
37
- this.availableDefinitions = availableDefinitions;
38
- this.name = "ActivityDefinitionNotFoundError";
39
- }
40
- };
41
- /**
42
- * Error thrown when activity input validation fails
43
- */
44
- var ActivityInputValidationError = class extends WorkerError {
45
- constructor(activityName, issues) {
46
- const message = issues.map((issue) => issue.message).join("; ");
47
- super(`Activity "${activityName}" input validation failed: ${message}`);
48
- this.activityName = activityName;
49
- this.issues = issues;
50
- this.name = "ActivityInputValidationError";
51
- }
52
- };
53
- /**
54
- * Error thrown when activity output validation fails
55
- */
56
- var ActivityOutputValidationError = class extends WorkerError {
57
- constructor(activityName, issues) {
58
- const message = issues.map((issue) => issue.message).join("; ");
59
- super(`Activity "${activityName}" output validation failed: ${message}`);
60
- this.activityName = activityName;
61
- this.issues = issues;
62
- this.name = "ActivityOutputValidationError";
63
- }
64
- };
65
- /**
66
- * Error thrown when workflow input validation fails
67
- */
68
- var WorkflowInputValidationError = class extends WorkerError {
69
- constructor(workflowName, issues) {
70
- const message = issues.map((issue) => issue.message).join("; ");
71
- super(`Workflow "${workflowName}" input validation failed: ${message}`);
72
- this.workflowName = workflowName;
73
- this.issues = issues;
74
- this.name = "WorkflowInputValidationError";
75
- }
76
- };
77
- /**
78
- * Error thrown when workflow output validation fails
79
- */
80
- var WorkflowOutputValidationError = class extends WorkerError {
81
- constructor(workflowName, issues) {
82
- const message = issues.map((issue) => issue.message).join("; ");
83
- super(`Workflow "${workflowName}" output validation failed: ${message}`);
84
- this.workflowName = workflowName;
85
- this.issues = issues;
86
- this.name = "WorkflowOutputValidationError";
87
- }
88
- };
89
- /**
90
- * Error thrown when signal input validation fails
91
- */
92
- var SignalInputValidationError = class extends WorkerError {
93
- constructor(signalName, issues) {
94
- const message = issues.map((issue) => issue.message).join("; ");
95
- super(`Signal "${signalName}" input validation failed: ${message}`);
96
- this.signalName = signalName;
97
- this.issues = issues;
98
- this.name = "SignalInputValidationError";
99
- }
100
- };
101
- /**
102
- * Error thrown when query input validation fails
103
- */
104
- var QueryInputValidationError = class extends WorkerError {
105
- constructor(queryName, issues) {
106
- const message = issues.map((issue) => issue.message).join("; ");
107
- super(`Query "${queryName}" input validation failed: ${message}`);
108
- this.queryName = queryName;
109
- this.issues = issues;
110
- this.name = "QueryInputValidationError";
111
- }
112
- };
113
- /**
114
- * Error thrown when query output validation fails
115
- */
116
- var QueryOutputValidationError = class extends WorkerError {
117
- constructor(queryName, issues) {
118
- const message = issues.map((issue) => issue.message).join("; ");
119
- super(`Query "${queryName}" output validation failed: ${message}`);
120
- this.queryName = queryName;
121
- this.issues = issues;
122
- this.name = "QueryOutputValidationError";
123
- }
124
- };
125
- /**
126
- * Error thrown when update input validation fails
127
- */
128
- var UpdateInputValidationError = class extends WorkerError {
129
- constructor(updateName, issues) {
130
- const message = issues.map((issue) => issue.message).join("; ");
131
- super(`Update "${updateName}" input validation failed: ${message}`);
132
- this.updateName = updateName;
133
- this.issues = issues;
134
- this.name = "UpdateInputValidationError";
135
- }
136
- };
137
- /**
138
- * Error thrown when update output validation fails
139
- */
140
- var UpdateOutputValidationError = class extends WorkerError {
141
- constructor(updateName, issues) {
142
- const message = issues.map((issue) => issue.message).join("; ");
143
- super(`Update "${updateName}" output validation failed: ${message}`);
144
- this.updateName = updateName;
145
- this.issues = issues;
146
- this.name = "UpdateOutputValidationError";
147
- }
148
- };
149
-
150
- //#endregion
151
- //#region src/handler.ts
152
- /**
153
- * Create a validated activities proxy that parses inputs and outputs
154
- *
155
- * This wrapper ensures data integrity across the network boundary between
156
- * workflow and activity execution.
157
- */
158
- function createValidatedActivities(rawActivities, workflowActivitiesDefinition, contractActivitiesDefinition) {
159
- const validatedActivities = {};
160
- const allActivitiesDefinition = {
161
- ...contractActivitiesDefinition,
162
- ...workflowActivitiesDefinition
163
- };
164
- for (const [activityName, activityDef] of Object.entries(allActivitiesDefinition)) {
165
- const rawActivity = rawActivities[activityName];
166
- if (!rawActivity) throw new Error(`Activity implementation not found for: "${activityName}". Available activities: ${Object.keys(rawActivities).length > 0 ? Object.keys(rawActivities).join(", ") : "none"}`);
167
- const wrappedActivity = async (input) => {
168
- const inputResult = await activityDef.input["~standard"].validate(input);
169
- if (inputResult.issues) throw new ActivityInputValidationError(activityName, inputResult.issues);
170
- const result = await rawActivity(inputResult.value);
171
- const outputResult = await activityDef.output["~standard"].validate(result);
172
- if (outputResult.issues) throw new ActivityOutputValidationError(activityName, outputResult.issues);
173
- return outputResult.value;
174
- };
175
- validatedActivities[activityName] = wrappedActivity;
176
- }
177
- return validatedActivities;
178
- }
179
- /**
180
- * Create a typed activities handler with automatic validation and Result pattern
181
- *
182
- * This wraps all activity implementations with:
183
- * - Validation at network boundaries
184
- * - Result<T, ActivityError> pattern for explicit error handling
185
- * - Automatic conversion from Result to Promise (throwing on Error)
186
- *
187
- * TypeScript ensures ALL activities (global + workflow-specific) are implemented.
188
- *
189
- * Use this to create the activities object for the Temporal Worker.
190
- *
191
- * @example
192
- * ```ts
193
- * import { declareActivitiesHandler, ActivityError } from '@temporal-contract/worker/activity';
194
- * import { Result, Future } from '@swan-io/boxed';
195
- * import myContract from './contract';
196
- *
197
- * export const activitiesHandler = declareActivitiesHandler({
198
- * contract: myContract,
199
- * activities: {
200
- * // Activity returns Result instead of throwing
201
- * // All technical exceptions must be wrapped in ActivityError for retry policies
202
- * sendEmail: (args) => {
203
- * return Future.make(async resolve => {
204
- * try {
205
- * await emailService.send(args);
206
- * resolve(Result.Ok({ sent: true }));
207
- * } catch (error) {
208
- * // Wrap technical errors in ActivityError to enable retries
209
- * resolve(Result.Error(
210
- * new ActivityError(
211
- * 'EMAIL_SEND_FAILED',
212
- * 'Failed to send email',
213
- * error // Original error as cause for debugging
214
- * )
215
- * ));
216
- * }
217
- * });
218
- * },
219
- * },
220
- * });
221
- *
222
- * // Use with Temporal Worker
223
- * import { Worker } from '@temporalio/worker';
224
- *
225
- * const worker = await Worker.create({
226
- * workflowsPath: require.resolve('./workflows'),
227
- * activities: activitiesHandler.activities,
228
- * taskQueue: activitiesHandler.contract.taskQueue,
229
- * });
230
- * ```
231
- */
232
- function declareActivitiesHandler(options) {
233
- const { contract, activities } = options;
234
- const wrappedActivities = {};
235
- const allDefinitions = [];
236
- if (contract.activities) allDefinitions.push(...Object.keys(contract.activities));
237
- for (const workflow of Object.values(contract.workflows)) if (workflow.activities) allDefinitions.push(...Object.keys(workflow.activities));
238
- for (const [activityName, activityImpl] of Object.entries(activities)) {
239
- let activityDef;
240
- if (contract.activities?.[activityName]) activityDef = contract.activities[activityName];
241
- else for (const workflow of Object.values(contract.workflows)) if (workflow.activities?.[activityName]) {
242
- activityDef = workflow.activities[activityName];
243
- break;
244
- }
245
- if (!activityDef) throw new ActivityDefinitionNotFoundError(activityName, allDefinitions);
246
- wrappedActivities[activityName] = async (...args) => {
247
- const input = args.length === 1 ? args[0] : args;
248
- const inputResult = await activityDef.input["~standard"].validate(input);
249
- if (inputResult.issues) throw new ActivityInputValidationError(activityName, inputResult.issues);
250
- const result = await activityImpl(inputResult.value).toPromise();
251
- if (result.isOk()) {
252
- const outputResult = await activityDef.output["~standard"].validate(result.value);
253
- if (outputResult.issues) throw new ActivityOutputValidationError(activityName, outputResult.issues);
254
- return outputResult.value;
255
- } else throw result.error;
256
- };
257
- }
258
- return {
259
- contract,
260
- activities: wrappedActivities
261
- };
262
- }
263
- /**
264
- * Create a typed workflow implementation with automatic validation
265
- *
266
- * This wraps a workflow implementation with:
267
- * - Input/output validation
268
- * - Typed workflow context with activities
269
- * - Workflow info access
270
- *
271
- * Workflows must be defined in separate files and imported by the Temporal Worker
272
- * via workflowsPath.
273
- *
274
- * @example
275
- * ```ts
276
- * // workflows/processOrder.ts
277
- * import { declareWorkflow } from '@temporal-contract/worker';
278
- * import myContract from '../contract';
279
- *
280
- * export const processOrder = declareWorkflow({
281
- * workflowName: 'processOrder',
282
- * contract: myContract,
283
- * implementation: async (context, orderId, customerId) => {
284
- * // context.activities: typed activities (workflow + global)
285
- * // context.info: WorkflowInfo
286
- *
287
- * const inventory = await context.activities.validateInventory(orderId);
288
- *
289
- * if (!inventory.available) {
290
- * throw new Error('Out of stock');
291
- * }
292
- *
293
- * const payment = await context.activities.chargePayment(customerId, 100);
294
- *
295
- * // Global activity
296
- * await context.activities.sendEmail(
297
- * customerId,
298
- * 'Order processed',
299
- * 'Your order has been processed'
300
- * );
301
- *
302
- * return {
303
- * orderId,
304
- * status: payment.success ? 'success' : 'failed',
305
- * transactionId: payment.transactionId,
306
- * };
307
- * },
308
- * activityOptions: {
309
- * startToCloseTimeout: '1 minute',
310
- * },
311
- * });
312
- * ```
313
- *
314
- * Then in your worker setup:
315
- * ```ts
316
- * // worker.ts
317
- * import { Worker } from '@temporalio/worker';
318
- * import { activitiesHandler } from './activities';
319
- *
320
- * const worker = await Worker.create({
321
- * workflowsPath: require.resolve('./workflows'), // Imports processOrder
322
- * activities: activitiesHandler.activities,
323
- * taskQueue: activitiesHandler.contract.taskQueue,
324
- * });
325
- * ```
326
- */
327
- function declareWorkflow(options) {
328
- const { workflowName, contract, implementation, activityOptions, signals, queries, updates } = options;
329
- const definition = contract.workflows[workflowName];
330
- return async (args) => {
331
- const singleArg = Array.isArray(args) ? args[0] : args;
332
- const inputResult = await definition.input["~standard"].validate(singleArg);
333
- if (inputResult.issues) throw new WorkflowInputValidationError(String(workflowName), inputResult.issues);
334
- const validatedInput = inputResult.value;
335
- if (definition.signals && signals) {
336
- const signalDefs = definition.signals;
337
- const signalHandlers = signals;
338
- for (const [signalName, signalDef] of Object.entries(signalDefs)) {
339
- const handler = signalHandlers[signalName];
340
- if (handler) (0, __temporalio_workflow.setHandler)((0, __temporalio_workflow.defineSignal)(signalName), async (...args$1) => {
341
- const input = args$1.length === 1 ? args$1[0] : args$1;
342
- const inputResult$1 = await signalDef.input["~standard"].validate(input);
343
- if (inputResult$1.issues) throw new SignalInputValidationError(signalName, inputResult$1.issues);
344
- await handler(inputResult$1.value);
345
- });
346
- }
347
- }
348
- if (definition.queries && queries) {
349
- const queryDefs = definition.queries;
350
- const queryHandlers = queries;
351
- for (const [queryName, queryDef] of Object.entries(queryDefs)) {
352
- const handler = queryHandlers[queryName];
353
- if (handler) (0, __temporalio_workflow.setHandler)((0, __temporalio_workflow.defineQuery)(queryName), (...args$1) => {
354
- const input = args$1.length === 1 ? args$1[0] : args$1;
355
- const inputResult$1 = queryDef.input["~standard"].validate(input);
356
- if (inputResult$1 instanceof Promise) throw new Error(`Query "${queryName}" validation must be synchronous. Use a schema library that supports synchronous validation for queries.`);
357
- if (inputResult$1.issues) throw new QueryInputValidationError(queryName, inputResult$1.issues);
358
- const result$1 = handler(inputResult$1.value);
359
- const outputResult$1 = queryDef.output["~standard"].validate(result$1);
360
- 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.`);
361
- if (outputResult$1.issues) throw new QueryOutputValidationError(queryName, outputResult$1.issues);
362
- return outputResult$1.value;
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) (0, __temporalio_workflow.setHandler)((0, __temporalio_workflow.defineUpdate)(updateName), async (...args$1) => {
372
- const input = args$1.length === 1 ? args$1[0] : args$1;
373
- const inputResult$1 = await updateDef.input["~standard"].validate(input);
374
- if (inputResult$1.issues) throw new UpdateInputValidationError(updateName, inputResult$1.issues);
375
- const result$1 = await handler(inputResult$1.value);
376
- const outputResult$1 = await updateDef.output["~standard"].validate(result$1);
377
- if (outputResult$1.issues) throw new UpdateOutputValidationError(updateName, outputResult$1.issues);
378
- return outputResult$1.value;
379
- });
380
- }
381
- }
382
- let contextActivities = {};
383
- if (definition.activities || contract.activities) contextActivities = createValidatedActivities((0, __temporalio_workflow.proxyActivities)({
384
- startToCloseTimeout: activityOptions?.startToCloseTimeout ?? 6e4,
385
- ...activityOptions
386
- }), definition.activities, contract.activities);
387
- const result = await implementation({
388
- activities: contextActivities,
389
- info: (0, __temporalio_workflow.workflowInfo)()
390
- }, validatedInput);
391
- const outputResult = await definition.output["~standard"].validate(result);
392
- if (outputResult.issues) throw new WorkflowOutputValidationError(String(workflowName), outputResult.issues);
393
- return outputResult.value;
394
- };
395
- }
396
-
397
- //#endregion
398
- Object.defineProperty(exports, 'ActivityDefinitionNotFoundError', {
399
- enumerable: true,
400
- get: function () {
401
- return ActivityDefinitionNotFoundError;
402
- }
403
- });
404
- Object.defineProperty(exports, 'ActivityError', {
405
- enumerable: true,
406
- get: function () {
407
- return ActivityError;
408
- }
409
- });
410
- Object.defineProperty(exports, 'ActivityInputValidationError', {
411
- enumerable: true,
412
- get: function () {
413
- return ActivityInputValidationError;
414
- }
415
- });
416
- Object.defineProperty(exports, 'ActivityOutputValidationError', {
417
- enumerable: true,
418
- get: function () {
419
- return ActivityOutputValidationError;
420
- }
421
- });
422
- Object.defineProperty(exports, 'QueryInputValidationError', {
423
- enumerable: true,
424
- get: function () {
425
- return QueryInputValidationError;
426
- }
427
- });
428
- Object.defineProperty(exports, 'QueryOutputValidationError', {
429
- enumerable: true,
430
- get: function () {
431
- return QueryOutputValidationError;
432
- }
433
- });
434
- Object.defineProperty(exports, 'SignalInputValidationError', {
435
- enumerable: true,
436
- get: function () {
437
- return SignalInputValidationError;
438
- }
439
- });
440
- Object.defineProperty(exports, 'UpdateInputValidationError', {
441
- enumerable: true,
442
- get: function () {
443
- return UpdateInputValidationError;
444
- }
445
- });
446
- Object.defineProperty(exports, 'UpdateOutputValidationError', {
447
- enumerable: true,
448
- get: function () {
449
- return UpdateOutputValidationError;
450
- }
451
- });
452
- Object.defineProperty(exports, 'WorkerError', {
453
- enumerable: true,
454
- get: function () {
455
- return WorkerError;
456
- }
457
- });
458
- Object.defineProperty(exports, 'WorkflowInputValidationError', {
459
- enumerable: true,
460
- get: function () {
461
- return WorkflowInputValidationError;
462
- }
463
- });
464
- Object.defineProperty(exports, 'WorkflowOutputValidationError', {
465
- enumerable: true,
466
- get: function () {
467
- return WorkflowOutputValidationError;
468
- }
469
- });
470
- Object.defineProperty(exports, 'declareActivitiesHandler', {
471
- enumerable: true,
472
- get: function () {
473
- return declareActivitiesHandler;
474
- }
475
- });
476
- Object.defineProperty(exports, 'declareWorkflow', {
477
- enumerable: true,
478
- get: function () {
479
- return declareWorkflow;
480
- }
481
- });