@temporal-contract/worker 0.0.3 → 0.0.4
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/dist/activity.cjs +27 -2
- package/dist/activity.d.cts +3 -2
- package/dist/activity.d.mts +3 -2
- package/dist/activity.mjs +3 -2
- package/dist/{handler-BP9xAycT.mjs → handler-B7B5QHez.mjs} +52 -30
- package/dist/{errors-B50uht6a.d.cts → handler-Czi-kgwZ.d.cts} +129 -115
- package/dist/{handler-Cc951VQp.cjs → handler-D9BllGor.cjs} +53 -31
- package/dist/{errors-DgUMRes-.d.mts → handler-DThqdaaS.d.mts} +129 -115
- package/dist/workflow.cjs +1 -1
- package/dist/workflow.d.cts +1 -1
- package/dist/workflow.d.mts +1 -1
- package/dist/workflow.mjs +1 -1
- package/package.json +23 -20
package/dist/activity.cjs
CHANGED
|
@@ -1,8 +1,33 @@
|
|
|
1
|
-
const require_handler = require('./handler-
|
|
1
|
+
const require_handler = require('./handler-D9BllGor.cjs');
|
|
2
|
+
let __swan_io_boxed = require("@swan-io/boxed");
|
|
2
3
|
|
|
3
4
|
exports.ActivityDefinitionNotFoundError = require_handler.ActivityDefinitionNotFoundError;
|
|
4
|
-
exports.
|
|
5
|
+
exports.ActivityError = require_handler.ActivityError;
|
|
5
6
|
exports.ActivityInputValidationError = require_handler.ActivityInputValidationError;
|
|
6
7
|
exports.ActivityOutputValidationError = require_handler.ActivityOutputValidationError;
|
|
8
|
+
Object.defineProperty(exports, 'AsyncData', {
|
|
9
|
+
enumerable: true,
|
|
10
|
+
get: function () {
|
|
11
|
+
return __swan_io_boxed.AsyncData;
|
|
12
|
+
}
|
|
13
|
+
});
|
|
14
|
+
Object.defineProperty(exports, 'Future', {
|
|
15
|
+
enumerable: true,
|
|
16
|
+
get: function () {
|
|
17
|
+
return __swan_io_boxed.Future;
|
|
18
|
+
}
|
|
19
|
+
});
|
|
20
|
+
Object.defineProperty(exports, 'Option', {
|
|
21
|
+
enumerable: true,
|
|
22
|
+
get: function () {
|
|
23
|
+
return __swan_io_boxed.Option;
|
|
24
|
+
}
|
|
25
|
+
});
|
|
26
|
+
Object.defineProperty(exports, 'Result', {
|
|
27
|
+
enumerable: true,
|
|
28
|
+
get: function () {
|
|
29
|
+
return __swan_io_boxed.Result;
|
|
30
|
+
}
|
|
31
|
+
});
|
|
7
32
|
exports.WorkerError = require_handler.WorkerError;
|
|
8
33
|
exports.declareActivitiesHandler = require_handler.declareActivitiesHandler;
|
package/dist/activity.d.cts
CHANGED
|
@@ -1,2 +1,3 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
1
|
+
import { S as WorkerError, d as declareActivitiesHandler, g as ActivityOutputValidationError, h as ActivityInputValidationError, i as DeclareActivitiesHandlerOptions, m as ActivityError, n as ActivityImplementations, p as ActivityDefinitionNotFoundError, r as BoxedActivityImplementation, t as ActivitiesHandler } from "./handler-Czi-kgwZ.cjs";
|
|
2
|
+
import { AsyncData, Future, Option, Result } from "@swan-io/boxed";
|
|
3
|
+
export { type ActivitiesHandler, ActivityDefinitionNotFoundError, ActivityError, type ActivityImplementations, ActivityInputValidationError, ActivityOutputValidationError, AsyncData, type BoxedActivityImplementation, type DeclareActivitiesHandlerOptions, Future, Option, Result, WorkerError, declareActivitiesHandler };
|
package/dist/activity.d.mts
CHANGED
|
@@ -1,2 +1,3 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
1
|
+
import { S as WorkerError, d as declareActivitiesHandler, g as ActivityOutputValidationError, h as ActivityInputValidationError, i as DeclareActivitiesHandlerOptions, m as ActivityError, n as ActivityImplementations, p as ActivityDefinitionNotFoundError, r as BoxedActivityImplementation, t as ActivitiesHandler } from "./handler-DThqdaaS.mjs";
|
|
2
|
+
import { AsyncData, Future, Option, Result } from "@swan-io/boxed";
|
|
3
|
+
export { type ActivitiesHandler, ActivityDefinitionNotFoundError, ActivityError, type ActivityImplementations, ActivityInputValidationError, ActivityOutputValidationError, AsyncData, type BoxedActivityImplementation, type DeclareActivitiesHandlerOptions, Future, Option, Result, WorkerError, declareActivitiesHandler };
|
package/dist/activity.mjs
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
-
import { a as ActivityInputValidationError, f as WorkerError, i as
|
|
1
|
+
import { a as ActivityInputValidationError, f as WorkerError, i as ActivityError, o as ActivityOutputValidationError, r as ActivityDefinitionNotFoundError, t as declareActivitiesHandler } from "./handler-B7B5QHez.mjs";
|
|
2
|
+
import { AsyncData, Future, Option, Result } from "@swan-io/boxed";
|
|
2
3
|
|
|
3
|
-
export { ActivityDefinitionNotFoundError,
|
|
4
|
+
export { ActivityDefinitionNotFoundError, ActivityError, ActivityInputValidationError, ActivityOutputValidationError, AsyncData, Future, Option, Result, WorkerError, declareActivitiesHandler };
|
|
@@ -5,29 +5,34 @@ import { defineQuery, defineSignal, defineUpdate, proxyActivities, setHandler, w
|
|
|
5
5
|
* Base error class for worker errors
|
|
6
6
|
*/
|
|
7
7
|
var WorkerError = class extends Error {
|
|
8
|
-
constructor(message) {
|
|
9
|
-
super(message);
|
|
8
|
+
constructor(message, cause) {
|
|
9
|
+
super(message, { cause });
|
|
10
10
|
this.name = "WorkerError";
|
|
11
11
|
if (Error.captureStackTrace) Error.captureStackTrace(this, this.constructor);
|
|
12
12
|
}
|
|
13
13
|
};
|
|
14
14
|
/**
|
|
15
|
-
*
|
|
15
|
+
* Activity error class that should be used to wrap all technical exceptions
|
|
16
|
+
* Forces proper error handling and enables retry policies
|
|
16
17
|
*/
|
|
17
|
-
var
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
this.
|
|
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);
|
|
23
27
|
}
|
|
24
28
|
};
|
|
25
29
|
/**
|
|
26
30
|
* Error thrown when an activity definition is not found in the contract
|
|
27
31
|
*/
|
|
28
32
|
var ActivityDefinitionNotFoundError = class extends WorkerError {
|
|
29
|
-
constructor(activityName, availableDefinitions) {
|
|
30
|
-
|
|
33
|
+
constructor(activityName, availableDefinitions = []) {
|
|
34
|
+
const available = availableDefinitions.length > 0 ? availableDefinitions.join(", ") : "none";
|
|
35
|
+
super(`Activity definition not found for: "${activityName}". Available activities: ${available}`);
|
|
31
36
|
this.activityName = activityName;
|
|
32
37
|
this.availableDefinitions = availableDefinitions;
|
|
33
38
|
this.name = "ActivityDefinitionNotFoundError";
|
|
@@ -158,7 +163,7 @@ function createValidatedActivities(rawActivities, workflowActivitiesDefinition,
|
|
|
158
163
|
};
|
|
159
164
|
for (const [activityName, activityDef] of Object.entries(allActivitiesDefinition)) {
|
|
160
165
|
const rawActivity = rawActivities[activityName];
|
|
161
|
-
if (!rawActivity) throw new
|
|
166
|
+
if (!rawActivity) throw new Error(`Activity implementation not found for: "${activityName}". Available activities: ${Object.keys(rawActivities).length > 0 ? Object.keys(rawActivities).join(", ") : "none"}`);
|
|
162
167
|
const wrappedActivity = async (input) => {
|
|
163
168
|
const inputResult = await activityDef.input["~standard"].validate(input);
|
|
164
169
|
if (inputResult.issues) throw new ActivityInputValidationError(activityName, inputResult.issues);
|
|
@@ -172,30 +177,44 @@ function createValidatedActivities(rawActivities, workflowActivitiesDefinition,
|
|
|
172
177
|
return validatedActivities;
|
|
173
178
|
}
|
|
174
179
|
/**
|
|
175
|
-
* Create a typed activities handler with automatic validation
|
|
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)
|
|
176
186
|
*
|
|
177
|
-
* This wraps all activity implementations with Zod validation at network boundaries.
|
|
178
187
|
* TypeScript ensures ALL activities (global + workflow-specific) are implemented.
|
|
179
188
|
*
|
|
180
189
|
* Use this to create the activities object for the Temporal Worker.
|
|
181
190
|
*
|
|
182
191
|
* @example
|
|
183
192
|
* ```ts
|
|
184
|
-
* import { declareActivitiesHandler } from '@temporal-contract/worker';
|
|
193
|
+
* import { declareActivitiesHandler, ActivityError } from '@temporal-contract/worker/activity';
|
|
194
|
+
* import { Result, Future } from '@swan-io/boxed';
|
|
185
195
|
* import myContract from './contract';
|
|
186
196
|
*
|
|
187
197
|
* export const activitiesHandler = declareActivitiesHandler({
|
|
188
198
|
* contract: myContract,
|
|
189
199
|
* activities: {
|
|
190
|
-
* //
|
|
191
|
-
*
|
|
192
|
-
*
|
|
193
|
-
* return
|
|
194
|
-
*
|
|
195
|
-
*
|
|
196
|
-
*
|
|
197
|
-
*
|
|
198
|
-
*
|
|
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
|
+
* });
|
|
199
218
|
* },
|
|
200
219
|
* },
|
|
201
220
|
* });
|
|
@@ -224,13 +243,16 @@ function declareActivitiesHandler(options) {
|
|
|
224
243
|
break;
|
|
225
244
|
}
|
|
226
245
|
if (!activityDef) throw new ActivityDefinitionNotFoundError(activityName, allDefinitions);
|
|
227
|
-
wrappedActivities[activityName] = async (
|
|
246
|
+
wrappedActivities[activityName] = async (...args) => {
|
|
247
|
+
const input = args.length === 1 ? args[0] : args;
|
|
228
248
|
const inputResult = await activityDef.input["~standard"].validate(input);
|
|
229
249
|
if (inputResult.issues) throw new ActivityInputValidationError(activityName, inputResult.issues);
|
|
230
|
-
const result = await activityImpl(inputResult.value);
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
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;
|
|
234
256
|
};
|
|
235
257
|
}
|
|
236
258
|
return {
|
|
@@ -373,4 +395,4 @@ function declareWorkflow(options) {
|
|
|
373
395
|
}
|
|
374
396
|
|
|
375
397
|
//#endregion
|
|
376
|
-
export { ActivityInputValidationError as a, QueryOutputValidationError as c, UpdateOutputValidationError as d, WorkerError as f,
|
|
398
|
+
export { ActivityInputValidationError as a, QueryOutputValidationError as c, UpdateOutputValidationError as d, WorkerError as f, ActivityError 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 };
|
|
@@ -1,9 +1,106 @@
|
|
|
1
|
+
import { Future, Result } from "@swan-io/boxed";
|
|
1
2
|
import { ActivityOptions, WorkflowInfo } from "@temporalio/workflow";
|
|
2
3
|
import { ActivityDefinition, ContractDefinition, QueryDefinition, SignalDefinition, UpdateDefinition, WorkerInferInput, WorkerInferOutput, WorkerInferWorkflowContextActivities } from "@temporal-contract/contract";
|
|
3
4
|
import { StandardSchemaV1 } from "@standard-schema/spec";
|
|
4
5
|
|
|
6
|
+
//#region src/errors.d.ts
|
|
7
|
+
/**
|
|
8
|
+
* Base error class for worker errors
|
|
9
|
+
*/
|
|
10
|
+
declare class WorkerError extends Error {
|
|
11
|
+
constructor(message: string, cause?: unknown);
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Activity error class that should be used to wrap all technical exceptions
|
|
15
|
+
* Forces proper error handling and enables retry policies
|
|
16
|
+
*/
|
|
17
|
+
declare class ActivityError extends Error {
|
|
18
|
+
readonly code: string;
|
|
19
|
+
readonly cause?: unknown;
|
|
20
|
+
constructor(code: string, message: string, cause?: unknown);
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Error thrown when an activity definition is not found in the contract
|
|
24
|
+
*/
|
|
25
|
+
declare class ActivityDefinitionNotFoundError extends WorkerError {
|
|
26
|
+
readonly activityName: string;
|
|
27
|
+
readonly availableDefinitions: readonly string[];
|
|
28
|
+
constructor(activityName: string, availableDefinitions?: readonly string[]);
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Error thrown when activity input validation fails
|
|
32
|
+
*/
|
|
33
|
+
declare class ActivityInputValidationError extends WorkerError {
|
|
34
|
+
readonly activityName: string;
|
|
35
|
+
readonly issues: ReadonlyArray<StandardSchemaV1.Issue>;
|
|
36
|
+
constructor(activityName: string, issues: ReadonlyArray<StandardSchemaV1.Issue>);
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Error thrown when activity output validation fails
|
|
40
|
+
*/
|
|
41
|
+
declare class ActivityOutputValidationError extends WorkerError {
|
|
42
|
+
readonly activityName: string;
|
|
43
|
+
readonly issues: ReadonlyArray<StandardSchemaV1.Issue>;
|
|
44
|
+
constructor(activityName: string, issues: ReadonlyArray<StandardSchemaV1.Issue>);
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Error thrown when workflow input validation fails
|
|
48
|
+
*/
|
|
49
|
+
declare class WorkflowInputValidationError extends WorkerError {
|
|
50
|
+
readonly workflowName: string;
|
|
51
|
+
readonly issues: ReadonlyArray<StandardSchemaV1.Issue>;
|
|
52
|
+
constructor(workflowName: string, issues: ReadonlyArray<StandardSchemaV1.Issue>);
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Error thrown when workflow output validation fails
|
|
56
|
+
*/
|
|
57
|
+
declare class WorkflowOutputValidationError extends WorkerError {
|
|
58
|
+
readonly workflowName: string;
|
|
59
|
+
readonly issues: ReadonlyArray<StandardSchemaV1.Issue>;
|
|
60
|
+
constructor(workflowName: string, issues: ReadonlyArray<StandardSchemaV1.Issue>);
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Error thrown when signal input validation fails
|
|
64
|
+
*/
|
|
65
|
+
declare class SignalInputValidationError extends WorkerError {
|
|
66
|
+
readonly signalName: string;
|
|
67
|
+
readonly issues: ReadonlyArray<StandardSchemaV1.Issue>;
|
|
68
|
+
constructor(signalName: string, issues: ReadonlyArray<StandardSchemaV1.Issue>);
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Error thrown when query input validation fails
|
|
72
|
+
*/
|
|
73
|
+
declare class QueryInputValidationError extends WorkerError {
|
|
74
|
+
readonly queryName: string;
|
|
75
|
+
readonly issues: ReadonlyArray<StandardSchemaV1.Issue>;
|
|
76
|
+
constructor(queryName: string, issues: ReadonlyArray<StandardSchemaV1.Issue>);
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Error thrown when query output validation fails
|
|
80
|
+
*/
|
|
81
|
+
declare class QueryOutputValidationError extends WorkerError {
|
|
82
|
+
readonly queryName: string;
|
|
83
|
+
readonly issues: ReadonlyArray<StandardSchemaV1.Issue>;
|
|
84
|
+
constructor(queryName: string, issues: ReadonlyArray<StandardSchemaV1.Issue>);
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Error thrown when update input validation fails
|
|
88
|
+
*/
|
|
89
|
+
declare class UpdateInputValidationError extends WorkerError {
|
|
90
|
+
readonly updateName: string;
|
|
91
|
+
readonly issues: ReadonlyArray<StandardSchemaV1.Issue>;
|
|
92
|
+
constructor(updateName: string, issues: ReadonlyArray<StandardSchemaV1.Issue>);
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Error thrown when update output validation fails
|
|
96
|
+
*/
|
|
97
|
+
declare class UpdateOutputValidationError extends WorkerError {
|
|
98
|
+
readonly updateName: string;
|
|
99
|
+
readonly issues: ReadonlyArray<StandardSchemaV1.Issue>;
|
|
100
|
+
constructor(updateName: string, issues: ReadonlyArray<StandardSchemaV1.Issue>);
|
|
101
|
+
}
|
|
102
|
+
//#endregion
|
|
5
103
|
//#region src/handler.d.ts
|
|
6
|
-
|
|
7
104
|
/**
|
|
8
105
|
* Workflow context with typed activities (workflow + global) and workflow info
|
|
9
106
|
* Note: activities is typed as 'any' to work around TypeScript generic type inference limitations with Zod tuples
|
|
@@ -19,11 +116,10 @@ interface WorkflowContext<TContract extends ContractDefinition, TWorkflowName ex
|
|
|
19
116
|
*/
|
|
20
117
|
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
118
|
/**
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
* The actual types will be enforced at runtime by Zod validation
|
|
119
|
+
* Activity implementation using Result pattern
|
|
120
|
+
* Returns Future<Result<Output, ActivityError>> instead of throwing exceptions
|
|
25
121
|
*/
|
|
26
|
-
type
|
|
122
|
+
type BoxedActivityImplementation<TActivity extends ActivityDefinition> = (args: WorkerInferInput<TActivity>) => Future<Result<WorkerInferOutput<TActivity>, ActivityError>>;
|
|
27
123
|
/**
|
|
28
124
|
* Signal handler implementation
|
|
29
125
|
*/
|
|
@@ -39,7 +135,7 @@ type UpdateHandlerImplementation<TUpdate extends UpdateDefinition> = (args: Work
|
|
|
39
135
|
/**
|
|
40
136
|
* Map of all activity implementations for a contract (global + all workflow-specific)
|
|
41
137
|
*/
|
|
42
|
-
type ActivityImplementations<T extends ContractDefinition> = (T["activities"] extends Record<string, ActivityDefinition> ? { [K in keyof T["activities"]]:
|
|
138
|
+
type ActivityImplementations<T extends ContractDefinition> = (T["activities"] extends Record<string, ActivityDefinition> ? { [K in keyof T["activities"]]: BoxedActivityImplementation<T["activities"][K]> } : {}) & UnionToIntersection<{ [K in keyof T["workflows"]]: T["workflows"][K]["activities"] extends Record<string, ActivityDefinition> ? { [A in keyof T["workflows"][K]["activities"]]: BoxedActivityImplementation<T["workflows"][K]["activities"][A]> } : {} }[keyof T["workflows"]]>;
|
|
43
139
|
/**
|
|
44
140
|
* Utility type to convert union to intersection
|
|
45
141
|
*/
|
|
@@ -98,30 +194,44 @@ interface DeclareWorkflowOptions<TContract extends ContractDefinition, TWorkflow
|
|
|
98
194
|
updates?: TContract["workflows"][TWorkflowName]["updates"] extends Record<string, UpdateDefinition> ? { [K in keyof TContract["workflows"][TWorkflowName]["updates"]]: UpdateHandlerImplementation<TContract["workflows"][TWorkflowName]["updates"][K]> } : never;
|
|
99
195
|
}
|
|
100
196
|
/**
|
|
101
|
-
* Create a typed activities handler with automatic validation
|
|
197
|
+
* Create a typed activities handler with automatic validation and Result pattern
|
|
198
|
+
*
|
|
199
|
+
* This wraps all activity implementations with:
|
|
200
|
+
* - Validation at network boundaries
|
|
201
|
+
* - Result<T, ActivityError> pattern for explicit error handling
|
|
202
|
+
* - Automatic conversion from Result to Promise (throwing on Error)
|
|
102
203
|
*
|
|
103
|
-
* This wraps all activity implementations with Zod validation at network boundaries.
|
|
104
204
|
* TypeScript ensures ALL activities (global + workflow-specific) are implemented.
|
|
105
205
|
*
|
|
106
206
|
* Use this to create the activities object for the Temporal Worker.
|
|
107
207
|
*
|
|
108
208
|
* @example
|
|
109
209
|
* ```ts
|
|
110
|
-
* import { declareActivitiesHandler } from '@temporal-contract/worker';
|
|
210
|
+
* import { declareActivitiesHandler, ActivityError } from '@temporal-contract/worker/activity';
|
|
211
|
+
* import { Result, Future } from '@swan-io/boxed';
|
|
111
212
|
* import myContract from './contract';
|
|
112
213
|
*
|
|
113
214
|
* export const activitiesHandler = declareActivitiesHandler({
|
|
114
215
|
* contract: myContract,
|
|
115
216
|
* activities: {
|
|
116
|
-
* //
|
|
117
|
-
*
|
|
118
|
-
*
|
|
119
|
-
* return
|
|
120
|
-
*
|
|
121
|
-
*
|
|
122
|
-
*
|
|
123
|
-
*
|
|
124
|
-
*
|
|
217
|
+
* // Activity returns Result instead of throwing
|
|
218
|
+
* // All technical exceptions must be wrapped in ActivityError for retry policies
|
|
219
|
+
* sendEmail: (args) => {
|
|
220
|
+
* return Future.make(async resolve => {
|
|
221
|
+
* try {
|
|
222
|
+
* await emailService.send(args);
|
|
223
|
+
* resolve(Result.Ok({ sent: true }));
|
|
224
|
+
* } catch (error) {
|
|
225
|
+
* // Wrap technical errors in ActivityError to enable retries
|
|
226
|
+
* resolve(Result.Error(
|
|
227
|
+
* new ActivityError(
|
|
228
|
+
* 'EMAIL_SEND_FAILED',
|
|
229
|
+
* 'Failed to send email',
|
|
230
|
+
* error // Original error as cause for debugging
|
|
231
|
+
* )
|
|
232
|
+
* ));
|
|
233
|
+
* }
|
|
234
|
+
* });
|
|
125
235
|
* },
|
|
126
236
|
* },
|
|
127
237
|
* });
|
|
@@ -203,100 +313,4 @@ declare function declareActivitiesHandler<T extends ContractDefinition>(options:
|
|
|
203
313
|
*/
|
|
204
314
|
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
315
|
//#endregion
|
|
206
|
-
|
|
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 };
|
|
316
|
+
export { WorkflowInputValidationError as C, WorkerError as S, QueryInputValidationError as _, DeclareWorkflowOptions as a, UpdateInputValidationError as b, UpdateHandlerImplementation as c, declareActivitiesHandler as d, declareWorkflow as f, ActivityOutputValidationError as g, ActivityInputValidationError as h, DeclareActivitiesHandlerOptions as i, WorkflowContext as l, ActivityError as m, ActivityImplementations as n, QueryHandlerImplementation as o, ActivityDefinitionNotFoundError as p, BoxedActivityImplementation as r, SignalHandlerImplementation as s, ActivitiesHandler as t, WorkflowImplementation as u, QueryOutputValidationError as v, WorkflowOutputValidationError as w, UpdateOutputValidationError as x, SignalInputValidationError as y };
|
|
@@ -5,29 +5,34 @@ let __temporalio_workflow = require("@temporalio/workflow");
|
|
|
5
5
|
* Base error class for worker errors
|
|
6
6
|
*/
|
|
7
7
|
var WorkerError = class extends Error {
|
|
8
|
-
constructor(message) {
|
|
9
|
-
super(message);
|
|
8
|
+
constructor(message, cause) {
|
|
9
|
+
super(message, { cause });
|
|
10
10
|
this.name = "WorkerError";
|
|
11
11
|
if (Error.captureStackTrace) Error.captureStackTrace(this, this.constructor);
|
|
12
12
|
}
|
|
13
13
|
};
|
|
14
14
|
/**
|
|
15
|
-
*
|
|
15
|
+
* Activity error class that should be used to wrap all technical exceptions
|
|
16
|
+
* Forces proper error handling and enables retry policies
|
|
16
17
|
*/
|
|
17
|
-
var
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
this.
|
|
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);
|
|
23
27
|
}
|
|
24
28
|
};
|
|
25
29
|
/**
|
|
26
30
|
* Error thrown when an activity definition is not found in the contract
|
|
27
31
|
*/
|
|
28
32
|
var ActivityDefinitionNotFoundError = class extends WorkerError {
|
|
29
|
-
constructor(activityName, availableDefinitions) {
|
|
30
|
-
|
|
33
|
+
constructor(activityName, availableDefinitions = []) {
|
|
34
|
+
const available = availableDefinitions.length > 0 ? availableDefinitions.join(", ") : "none";
|
|
35
|
+
super(`Activity definition not found for: "${activityName}". Available activities: ${available}`);
|
|
31
36
|
this.activityName = activityName;
|
|
32
37
|
this.availableDefinitions = availableDefinitions;
|
|
33
38
|
this.name = "ActivityDefinitionNotFoundError";
|
|
@@ -158,7 +163,7 @@ function createValidatedActivities(rawActivities, workflowActivitiesDefinition,
|
|
|
158
163
|
};
|
|
159
164
|
for (const [activityName, activityDef] of Object.entries(allActivitiesDefinition)) {
|
|
160
165
|
const rawActivity = rawActivities[activityName];
|
|
161
|
-
if (!rawActivity) throw new
|
|
166
|
+
if (!rawActivity) throw new Error(`Activity implementation not found for: "${activityName}". Available activities: ${Object.keys(rawActivities).length > 0 ? Object.keys(rawActivities).join(", ") : "none"}`);
|
|
162
167
|
const wrappedActivity = async (input) => {
|
|
163
168
|
const inputResult = await activityDef.input["~standard"].validate(input);
|
|
164
169
|
if (inputResult.issues) throw new ActivityInputValidationError(activityName, inputResult.issues);
|
|
@@ -172,30 +177,44 @@ function createValidatedActivities(rawActivities, workflowActivitiesDefinition,
|
|
|
172
177
|
return validatedActivities;
|
|
173
178
|
}
|
|
174
179
|
/**
|
|
175
|
-
* Create a typed activities handler with automatic validation
|
|
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)
|
|
176
186
|
*
|
|
177
|
-
* This wraps all activity implementations with Zod validation at network boundaries.
|
|
178
187
|
* TypeScript ensures ALL activities (global + workflow-specific) are implemented.
|
|
179
188
|
*
|
|
180
189
|
* Use this to create the activities object for the Temporal Worker.
|
|
181
190
|
*
|
|
182
191
|
* @example
|
|
183
192
|
* ```ts
|
|
184
|
-
* import { declareActivitiesHandler } from '@temporal-contract/worker';
|
|
193
|
+
* import { declareActivitiesHandler, ActivityError } from '@temporal-contract/worker/activity';
|
|
194
|
+
* import { Result, Future } from '@swan-io/boxed';
|
|
185
195
|
* import myContract from './contract';
|
|
186
196
|
*
|
|
187
197
|
* export const activitiesHandler = declareActivitiesHandler({
|
|
188
198
|
* contract: myContract,
|
|
189
199
|
* activities: {
|
|
190
|
-
* //
|
|
191
|
-
*
|
|
192
|
-
*
|
|
193
|
-
* return
|
|
194
|
-
*
|
|
195
|
-
*
|
|
196
|
-
*
|
|
197
|
-
*
|
|
198
|
-
*
|
|
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
|
+
* });
|
|
199
218
|
* },
|
|
200
219
|
* },
|
|
201
220
|
* });
|
|
@@ -224,13 +243,16 @@ function declareActivitiesHandler(options) {
|
|
|
224
243
|
break;
|
|
225
244
|
}
|
|
226
245
|
if (!activityDef) throw new ActivityDefinitionNotFoundError(activityName, allDefinitions);
|
|
227
|
-
wrappedActivities[activityName] = async (
|
|
246
|
+
wrappedActivities[activityName] = async (...args) => {
|
|
247
|
+
const input = args.length === 1 ? args[0] : args;
|
|
228
248
|
const inputResult = await activityDef.input["~standard"].validate(input);
|
|
229
249
|
if (inputResult.issues) throw new ActivityInputValidationError(activityName, inputResult.issues);
|
|
230
|
-
const result = await activityImpl(inputResult.value);
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
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;
|
|
234
256
|
};
|
|
235
257
|
}
|
|
236
258
|
return {
|
|
@@ -379,10 +401,10 @@ Object.defineProperty(exports, 'ActivityDefinitionNotFoundError', {
|
|
|
379
401
|
return ActivityDefinitionNotFoundError;
|
|
380
402
|
}
|
|
381
403
|
});
|
|
382
|
-
Object.defineProperty(exports, '
|
|
404
|
+
Object.defineProperty(exports, 'ActivityError', {
|
|
383
405
|
enumerable: true,
|
|
384
406
|
get: function () {
|
|
385
|
-
return
|
|
407
|
+
return ActivityError;
|
|
386
408
|
}
|
|
387
409
|
});
|
|
388
410
|
Object.defineProperty(exports, 'ActivityInputValidationError', {
|
|
@@ -1,9 +1,106 @@
|
|
|
1
1
|
import { ActivityOptions, WorkflowInfo } from "@temporalio/workflow";
|
|
2
|
+
import { Future, Result } from "@swan-io/boxed";
|
|
2
3
|
import { ActivityDefinition, ContractDefinition, QueryDefinition, SignalDefinition, UpdateDefinition, WorkerInferInput, WorkerInferOutput, WorkerInferWorkflowContextActivities } from "@temporal-contract/contract";
|
|
3
4
|
import { StandardSchemaV1 } from "@standard-schema/spec";
|
|
4
5
|
|
|
6
|
+
//#region src/errors.d.ts
|
|
7
|
+
/**
|
|
8
|
+
* Base error class for worker errors
|
|
9
|
+
*/
|
|
10
|
+
declare class WorkerError extends Error {
|
|
11
|
+
constructor(message: string, cause?: unknown);
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Activity error class that should be used to wrap all technical exceptions
|
|
15
|
+
* Forces proper error handling and enables retry policies
|
|
16
|
+
*/
|
|
17
|
+
declare class ActivityError extends Error {
|
|
18
|
+
readonly code: string;
|
|
19
|
+
readonly cause?: unknown;
|
|
20
|
+
constructor(code: string, message: string, cause?: unknown);
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Error thrown when an activity definition is not found in the contract
|
|
24
|
+
*/
|
|
25
|
+
declare class ActivityDefinitionNotFoundError extends WorkerError {
|
|
26
|
+
readonly activityName: string;
|
|
27
|
+
readonly availableDefinitions: readonly string[];
|
|
28
|
+
constructor(activityName: string, availableDefinitions?: readonly string[]);
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Error thrown when activity input validation fails
|
|
32
|
+
*/
|
|
33
|
+
declare class ActivityInputValidationError extends WorkerError {
|
|
34
|
+
readonly activityName: string;
|
|
35
|
+
readonly issues: ReadonlyArray<StandardSchemaV1.Issue>;
|
|
36
|
+
constructor(activityName: string, issues: ReadonlyArray<StandardSchemaV1.Issue>);
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Error thrown when activity output validation fails
|
|
40
|
+
*/
|
|
41
|
+
declare class ActivityOutputValidationError extends WorkerError {
|
|
42
|
+
readonly activityName: string;
|
|
43
|
+
readonly issues: ReadonlyArray<StandardSchemaV1.Issue>;
|
|
44
|
+
constructor(activityName: string, issues: ReadonlyArray<StandardSchemaV1.Issue>);
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Error thrown when workflow input validation fails
|
|
48
|
+
*/
|
|
49
|
+
declare class WorkflowInputValidationError extends WorkerError {
|
|
50
|
+
readonly workflowName: string;
|
|
51
|
+
readonly issues: ReadonlyArray<StandardSchemaV1.Issue>;
|
|
52
|
+
constructor(workflowName: string, issues: ReadonlyArray<StandardSchemaV1.Issue>);
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Error thrown when workflow output validation fails
|
|
56
|
+
*/
|
|
57
|
+
declare class WorkflowOutputValidationError extends WorkerError {
|
|
58
|
+
readonly workflowName: string;
|
|
59
|
+
readonly issues: ReadonlyArray<StandardSchemaV1.Issue>;
|
|
60
|
+
constructor(workflowName: string, issues: ReadonlyArray<StandardSchemaV1.Issue>);
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Error thrown when signal input validation fails
|
|
64
|
+
*/
|
|
65
|
+
declare class SignalInputValidationError extends WorkerError {
|
|
66
|
+
readonly signalName: string;
|
|
67
|
+
readonly issues: ReadonlyArray<StandardSchemaV1.Issue>;
|
|
68
|
+
constructor(signalName: string, issues: ReadonlyArray<StandardSchemaV1.Issue>);
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Error thrown when query input validation fails
|
|
72
|
+
*/
|
|
73
|
+
declare class QueryInputValidationError extends WorkerError {
|
|
74
|
+
readonly queryName: string;
|
|
75
|
+
readonly issues: ReadonlyArray<StandardSchemaV1.Issue>;
|
|
76
|
+
constructor(queryName: string, issues: ReadonlyArray<StandardSchemaV1.Issue>);
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Error thrown when query output validation fails
|
|
80
|
+
*/
|
|
81
|
+
declare class QueryOutputValidationError extends WorkerError {
|
|
82
|
+
readonly queryName: string;
|
|
83
|
+
readonly issues: ReadonlyArray<StandardSchemaV1.Issue>;
|
|
84
|
+
constructor(queryName: string, issues: ReadonlyArray<StandardSchemaV1.Issue>);
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Error thrown when update input validation fails
|
|
88
|
+
*/
|
|
89
|
+
declare class UpdateInputValidationError extends WorkerError {
|
|
90
|
+
readonly updateName: string;
|
|
91
|
+
readonly issues: ReadonlyArray<StandardSchemaV1.Issue>;
|
|
92
|
+
constructor(updateName: string, issues: ReadonlyArray<StandardSchemaV1.Issue>);
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Error thrown when update output validation fails
|
|
96
|
+
*/
|
|
97
|
+
declare class UpdateOutputValidationError extends WorkerError {
|
|
98
|
+
readonly updateName: string;
|
|
99
|
+
readonly issues: ReadonlyArray<StandardSchemaV1.Issue>;
|
|
100
|
+
constructor(updateName: string, issues: ReadonlyArray<StandardSchemaV1.Issue>);
|
|
101
|
+
}
|
|
102
|
+
//#endregion
|
|
5
103
|
//#region src/handler.d.ts
|
|
6
|
-
|
|
7
104
|
/**
|
|
8
105
|
* Workflow context with typed activities (workflow + global) and workflow info
|
|
9
106
|
* Note: activities is typed as 'any' to work around TypeScript generic type inference limitations with Zod tuples
|
|
@@ -19,11 +116,10 @@ interface WorkflowContext<TContract extends ContractDefinition, TWorkflowName ex
|
|
|
19
116
|
*/
|
|
20
117
|
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
118
|
/**
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
* The actual types will be enforced at runtime by Zod validation
|
|
119
|
+
* Activity implementation using Result pattern
|
|
120
|
+
* Returns Future<Result<Output, ActivityError>> instead of throwing exceptions
|
|
25
121
|
*/
|
|
26
|
-
type
|
|
122
|
+
type BoxedActivityImplementation<TActivity extends ActivityDefinition> = (args: WorkerInferInput<TActivity>) => Future<Result<WorkerInferOutput<TActivity>, ActivityError>>;
|
|
27
123
|
/**
|
|
28
124
|
* Signal handler implementation
|
|
29
125
|
*/
|
|
@@ -39,7 +135,7 @@ type UpdateHandlerImplementation<TUpdate extends UpdateDefinition> = (args: Work
|
|
|
39
135
|
/**
|
|
40
136
|
* Map of all activity implementations for a contract (global + all workflow-specific)
|
|
41
137
|
*/
|
|
42
|
-
type ActivityImplementations<T extends ContractDefinition> = (T["activities"] extends Record<string, ActivityDefinition> ? { [K in keyof T["activities"]]:
|
|
138
|
+
type ActivityImplementations<T extends ContractDefinition> = (T["activities"] extends Record<string, ActivityDefinition> ? { [K in keyof T["activities"]]: BoxedActivityImplementation<T["activities"][K]> } : {}) & UnionToIntersection<{ [K in keyof T["workflows"]]: T["workflows"][K]["activities"] extends Record<string, ActivityDefinition> ? { [A in keyof T["workflows"][K]["activities"]]: BoxedActivityImplementation<T["workflows"][K]["activities"][A]> } : {} }[keyof T["workflows"]]>;
|
|
43
139
|
/**
|
|
44
140
|
* Utility type to convert union to intersection
|
|
45
141
|
*/
|
|
@@ -98,30 +194,44 @@ interface DeclareWorkflowOptions<TContract extends ContractDefinition, TWorkflow
|
|
|
98
194
|
updates?: TContract["workflows"][TWorkflowName]["updates"] extends Record<string, UpdateDefinition> ? { [K in keyof TContract["workflows"][TWorkflowName]["updates"]]: UpdateHandlerImplementation<TContract["workflows"][TWorkflowName]["updates"][K]> } : never;
|
|
99
195
|
}
|
|
100
196
|
/**
|
|
101
|
-
* Create a typed activities handler with automatic validation
|
|
197
|
+
* Create a typed activities handler with automatic validation and Result pattern
|
|
198
|
+
*
|
|
199
|
+
* This wraps all activity implementations with:
|
|
200
|
+
* - Validation at network boundaries
|
|
201
|
+
* - Result<T, ActivityError> pattern for explicit error handling
|
|
202
|
+
* - Automatic conversion from Result to Promise (throwing on Error)
|
|
102
203
|
*
|
|
103
|
-
* This wraps all activity implementations with Zod validation at network boundaries.
|
|
104
204
|
* TypeScript ensures ALL activities (global + workflow-specific) are implemented.
|
|
105
205
|
*
|
|
106
206
|
* Use this to create the activities object for the Temporal Worker.
|
|
107
207
|
*
|
|
108
208
|
* @example
|
|
109
209
|
* ```ts
|
|
110
|
-
* import { declareActivitiesHandler } from '@temporal-contract/worker';
|
|
210
|
+
* import { declareActivitiesHandler, ActivityError } from '@temporal-contract/worker/activity';
|
|
211
|
+
* import { Result, Future } from '@swan-io/boxed';
|
|
111
212
|
* import myContract from './contract';
|
|
112
213
|
*
|
|
113
214
|
* export const activitiesHandler = declareActivitiesHandler({
|
|
114
215
|
* contract: myContract,
|
|
115
216
|
* activities: {
|
|
116
|
-
* //
|
|
117
|
-
*
|
|
118
|
-
*
|
|
119
|
-
* return
|
|
120
|
-
*
|
|
121
|
-
*
|
|
122
|
-
*
|
|
123
|
-
*
|
|
124
|
-
*
|
|
217
|
+
* // Activity returns Result instead of throwing
|
|
218
|
+
* // All technical exceptions must be wrapped in ActivityError for retry policies
|
|
219
|
+
* sendEmail: (args) => {
|
|
220
|
+
* return Future.make(async resolve => {
|
|
221
|
+
* try {
|
|
222
|
+
* await emailService.send(args);
|
|
223
|
+
* resolve(Result.Ok({ sent: true }));
|
|
224
|
+
* } catch (error) {
|
|
225
|
+
* // Wrap technical errors in ActivityError to enable retries
|
|
226
|
+
* resolve(Result.Error(
|
|
227
|
+
* new ActivityError(
|
|
228
|
+
* 'EMAIL_SEND_FAILED',
|
|
229
|
+
* 'Failed to send email',
|
|
230
|
+
* error // Original error as cause for debugging
|
|
231
|
+
* )
|
|
232
|
+
* ));
|
|
233
|
+
* }
|
|
234
|
+
* });
|
|
125
235
|
* },
|
|
126
236
|
* },
|
|
127
237
|
* });
|
|
@@ -203,100 +313,4 @@ declare function declareActivitiesHandler<T extends ContractDefinition>(options:
|
|
|
203
313
|
*/
|
|
204
314
|
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
315
|
//#endregion
|
|
206
|
-
|
|
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 };
|
|
316
|
+
export { WorkflowInputValidationError as C, WorkerError as S, QueryInputValidationError as _, DeclareWorkflowOptions as a, UpdateInputValidationError as b, UpdateHandlerImplementation as c, declareActivitiesHandler as d, declareWorkflow as f, ActivityOutputValidationError as g, ActivityInputValidationError as h, DeclareActivitiesHandlerOptions as i, WorkflowContext as l, ActivityError as m, ActivityImplementations as n, QueryHandlerImplementation as o, ActivityDefinitionNotFoundError as p, BoxedActivityImplementation as r, SignalHandlerImplementation as s, ActivitiesHandler as t, WorkflowImplementation as u, QueryOutputValidationError as v, WorkflowOutputValidationError as w, UpdateOutputValidationError as x, SignalInputValidationError as y };
|
package/dist/workflow.cjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const require_handler = require('./handler-
|
|
1
|
+
const require_handler = require('./handler-D9BllGor.cjs');
|
|
2
2
|
|
|
3
3
|
exports.QueryInputValidationError = require_handler.QueryInputValidationError;
|
|
4
4
|
exports.QueryOutputValidationError = require_handler.QueryOutputValidationError;
|
package/dist/workflow.d.cts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { C as WorkflowInputValidationError, S as WorkerError, _ as QueryInputValidationError, a as DeclareWorkflowOptions, b as UpdateInputValidationError, c as UpdateHandlerImplementation, f as declareWorkflow, l as WorkflowContext, o as QueryHandlerImplementation, s as SignalHandlerImplementation, u as WorkflowImplementation, v as QueryOutputValidationError, w as WorkflowOutputValidationError, x as UpdateOutputValidationError, y as SignalInputValidationError } from "./handler-Czi-kgwZ.cjs";
|
|
2
2
|
export { type DeclareWorkflowOptions, type QueryHandlerImplementation, QueryInputValidationError, QueryOutputValidationError, type SignalHandlerImplementation, SignalInputValidationError, type UpdateHandlerImplementation, UpdateInputValidationError, UpdateOutputValidationError, WorkerError, type WorkflowContext, type WorkflowImplementation, WorkflowInputValidationError, WorkflowOutputValidationError, declareWorkflow };
|
package/dist/workflow.d.mts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { C as WorkflowInputValidationError, S as WorkerError, _ as QueryInputValidationError, a as DeclareWorkflowOptions, b as UpdateInputValidationError, c as UpdateHandlerImplementation, f as declareWorkflow, l as WorkflowContext, o as QueryHandlerImplementation, s as SignalHandlerImplementation, u as WorkflowImplementation, v as QueryOutputValidationError, w as WorkflowOutputValidationError, x as UpdateOutputValidationError, y as SignalInputValidationError } from "./handler-DThqdaaS.mjs";
|
|
2
2
|
export { type DeclareWorkflowOptions, type QueryHandlerImplementation, QueryInputValidationError, QueryOutputValidationError, type SignalHandlerImplementation, SignalInputValidationError, type UpdateHandlerImplementation, UpdateInputValidationError, UpdateOutputValidationError, WorkerError, type WorkflowContext, type WorkflowImplementation, WorkflowInputValidationError, WorkflowOutputValidationError, declareWorkflow };
|
package/dist/workflow.mjs
CHANGED
|
@@ -1,3 +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-
|
|
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-B7B5QHez.mjs";
|
|
2
2
|
|
|
3
3
|
export { QueryInputValidationError, QueryOutputValidationError, SignalInputValidationError, UpdateInputValidationError, UpdateOutputValidationError, WorkerError, WorkflowInputValidationError, WorkflowOutputValidationError, declareWorkflow };
|
package/package.json
CHANGED
|
@@ -1,8 +1,15 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@temporal-contract/worker",
|
|
3
|
-
"version": "0.0.
|
|
4
|
-
"
|
|
5
|
-
"
|
|
3
|
+
"version": "0.0.4",
|
|
4
|
+
"description": "Worker utilities with Result/Future pattern for implementing temporal-contract workflows and activities",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"temporal",
|
|
7
|
+
"typescript",
|
|
8
|
+
"contract",
|
|
9
|
+
"worker",
|
|
10
|
+
"result",
|
|
11
|
+
"future"
|
|
12
|
+
],
|
|
6
13
|
"homepage": "https://github.com/btravers/temporal-contract#readme",
|
|
7
14
|
"bugs": {
|
|
8
15
|
"url": "https://github.com/btravers/temporal-contract/issues"
|
|
@@ -12,17 +19,9 @@
|
|
|
12
19
|
"url": "https://github.com/btravers/temporal-contract.git",
|
|
13
20
|
"directory": "packages/worker"
|
|
14
21
|
},
|
|
15
|
-
"author": "Benoit TRAVERS <benoit.travers.frgmail.com>",
|
|
16
22
|
"license": "MIT",
|
|
17
|
-
"
|
|
18
|
-
|
|
19
|
-
"typescript",
|
|
20
|
-
"contract",
|
|
21
|
-
"worker"
|
|
22
|
-
],
|
|
23
|
-
"main": "./dist/index.cjs",
|
|
24
|
-
"module": "./dist/index.mjs",
|
|
25
|
-
"types": "./dist/index.d.mts",
|
|
23
|
+
"author": "Benoit TRAVERS <benoit.travers.frgmail.com>",
|
|
24
|
+
"type": "module",
|
|
26
25
|
"exports": {
|
|
27
26
|
"./activity": {
|
|
28
27
|
"import": {
|
|
@@ -46,31 +45,35 @@
|
|
|
46
45
|
},
|
|
47
46
|
"./package.json": "./package.json"
|
|
48
47
|
},
|
|
48
|
+
"main": "./dist/index.cjs",
|
|
49
|
+
"module": "./dist/index.mjs",
|
|
50
|
+
"types": "./dist/index.d.mts",
|
|
49
51
|
"files": [
|
|
50
52
|
"dist"
|
|
51
53
|
],
|
|
52
54
|
"dependencies": {
|
|
53
55
|
"@standard-schema/spec": "1.0.0",
|
|
54
|
-
"@
|
|
56
|
+
"@swan-io/boxed": "3.2.1",
|
|
57
|
+
"@temporal-contract/contract": "0.0.4"
|
|
55
58
|
},
|
|
56
59
|
"devDependencies": {
|
|
57
60
|
"@temporalio/workflow": "1.13.2",
|
|
58
|
-
"@types/node": "
|
|
61
|
+
"@types/node": "25.0.1",
|
|
59
62
|
"@vitest/coverage-v8": "4.0.15",
|
|
60
|
-
"tsdown": "0.17.
|
|
63
|
+
"tsdown": "0.17.3",
|
|
61
64
|
"typescript": "5.9.3",
|
|
62
65
|
"vitest": "4.0.15",
|
|
63
66
|
"zod": "4.1.13",
|
|
64
|
-
"@temporal-contract/tsconfig": "0.0.
|
|
67
|
+
"@temporal-contract/tsconfig": "0.0.4"
|
|
65
68
|
},
|
|
66
69
|
"peerDependencies": {
|
|
67
70
|
"@temporalio/workflow": ">=1.13.0 <2.0.0"
|
|
68
71
|
},
|
|
69
72
|
"scripts": {
|
|
70
|
-
"dev": "tsdown src/activity.ts src/workflow.ts --format cjs,esm --dts --watch",
|
|
71
73
|
"build": "tsdown src/activity.ts src/workflow.ts --format cjs,esm --dts --clean",
|
|
72
|
-
"
|
|
74
|
+
"dev": "tsdown src/activity.ts src/workflow.ts --format cjs,esm --dts --watch",
|
|
73
75
|
"test": "vitest run",
|
|
74
|
-
"test:watch": "vitest"
|
|
76
|
+
"test:watch": "vitest",
|
|
77
|
+
"typecheck": "tsc --noEmit"
|
|
75
78
|
}
|
|
76
79
|
}
|