@temporal-contract/worker 0.1.0 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +13 -12
- package/dist/activity.cjs +44 -118
- package/dist/activity.d.cts +109 -3
- package/dist/activity.d.cts.map +1 -0
- package/dist/activity.d.mts +109 -3
- package/dist/activity.d.mts.map +1 -0
- package/dist/activity.mjs +33 -107
- package/dist/activity.mjs.map +1 -0
- package/dist/{errors-Vr-sKdW7.d.mts → errors-CG1y7SHO.d.cts} +14 -1
- package/dist/errors-CG1y7SHO.d.cts.map +1 -0
- package/dist/{errors-CXpHOFmk.d.cts → errors-DZhaNhwr.d.mts} +14 -1
- package/dist/errors-DZhaNhwr.d.mts.map +1 -0
- package/dist/internal-BoNcEtYh.mjs +354 -0
- package/dist/internal-BoNcEtYh.mjs.map +1 -0
- package/dist/internal-Tj4m4f_K.cjs +453 -0
- package/dist/worker.cjs +12 -8
- package/dist/worker.d.cts +14 -7
- package/dist/worker.d.cts.map +1 -0
- package/dist/worker.d.mts +14 -7
- package/dist/worker.d.mts.map +1 -0
- package/dist/worker.mjs +13 -8
- package/dist/worker.mjs.map +1 -0
- package/dist/workflow.cjs +269 -172
- package/dist/workflow.d.cts +184 -60
- package/dist/workflow.d.cts.map +1 -0
- package/dist/workflow.d.mts +184 -60
- package/dist/workflow.d.mts.map +1 -0
- package/dist/workflow.mjs +254 -157
- package/dist/workflow.mjs.map +1 -0
- package/package.json +24 -23
- package/dist/activity-5pVNjW7l.d.cts +0 -161
- package/dist/activity-BUEBZ7SL.d.mts +0 -161
- package/dist/errors-BqVTpfcf.mjs +0 -155
- package/dist/errors-DjSZg-93.cjs +0 -227
package/README.md
CHANGED
|
@@ -14,7 +14,7 @@ pnpm add @temporal-contract/worker @temporal-contract/contract @temporalio/workf
|
|
|
14
14
|
|
|
15
15
|
```typescript
|
|
16
16
|
// activities.ts
|
|
17
|
-
import { declareActivitiesHandler,
|
|
17
|
+
import { declareActivitiesHandler, ApplicationFailure } from "@temporal-contract/worker/activity";
|
|
18
18
|
import { Future, Result } from "@swan-io/boxed";
|
|
19
19
|
|
|
20
20
|
export const activities = declareActivitiesHandler({
|
|
@@ -22,13 +22,12 @@ export const activities = declareActivitiesHandler({
|
|
|
22
22
|
activities: {
|
|
23
23
|
sendEmail: ({ to, body }) => {
|
|
24
24
|
return Future.fromPromise(emailService.send({ to, body }))
|
|
25
|
-
.mapError(
|
|
26
|
-
(
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
),
|
|
25
|
+
.mapError((error) =>
|
|
26
|
+
ApplicationFailure.create({
|
|
27
|
+
type: "EMAIL_FAILED",
|
|
28
|
+
message: error instanceof Error ? error.message : "Failed to send email",
|
|
29
|
+
cause: error,
|
|
30
|
+
}),
|
|
32
31
|
)
|
|
33
32
|
.mapOk(() => ({ sent: true }));
|
|
34
33
|
},
|
|
@@ -41,6 +40,7 @@ import { declareWorkflow } from "@temporal-contract/worker/workflow";
|
|
|
41
40
|
export const processOrder = declareWorkflow({
|
|
42
41
|
workflowName: "processOrder",
|
|
43
42
|
contract: myContract,
|
|
43
|
+
activityOptions: { startToCloseTimeout: "1 minute" },
|
|
44
44
|
implementation: async ({ activities }, input) => {
|
|
45
45
|
// Activities return plain values (Result is unwrapped internally)
|
|
46
46
|
await activities.sendEmail({ to: "user@example.com", body: "Done!" });
|
|
@@ -77,9 +77,10 @@ import { declareWorkflow } from "@temporal-contract/worker/workflow";
|
|
|
77
77
|
export const parentWorkflow = declareWorkflow({
|
|
78
78
|
workflowName: "parentWorkflow",
|
|
79
79
|
contract: myContract,
|
|
80
|
-
|
|
80
|
+
activityOptions: { startToCloseTimeout: "1 minute" },
|
|
81
|
+
implementation: async (context, input) => {
|
|
81
82
|
// Execute child workflow from same contract and wait for result
|
|
82
|
-
const childResult = await executeChildWorkflow(myContract, "processPayment", {
|
|
83
|
+
const childResult = await context.executeChildWorkflow(myContract, "processPayment", {
|
|
83
84
|
workflowId: `payment-${input.orderId}`,
|
|
84
85
|
args: { amount: input.totalAmount },
|
|
85
86
|
});
|
|
@@ -90,7 +91,7 @@ export const parentWorkflow = declareWorkflow({
|
|
|
90
91
|
});
|
|
91
92
|
|
|
92
93
|
// Execute child workflow from another contract (another worker)
|
|
93
|
-
const notificationResult = await executeChildWorkflow(
|
|
94
|
+
const notificationResult = await context.executeChildWorkflow(
|
|
94
95
|
notificationContract,
|
|
95
96
|
"sendNotification",
|
|
96
97
|
{
|
|
@@ -100,7 +101,7 @@ export const parentWorkflow = declareWorkflow({
|
|
|
100
101
|
);
|
|
101
102
|
|
|
102
103
|
// Or start child workflow without waiting
|
|
103
|
-
const handleResult = await startChildWorkflow(myContract, "sendEmail", {
|
|
104
|
+
const handleResult = await context.startChildWorkflow(myContract, "sendEmail", {
|
|
104
105
|
workflowId: `email-${input.orderId}`,
|
|
105
106
|
args: { to: "user@example.com", body: "Order received" },
|
|
106
107
|
});
|
package/dist/activity.cjs
CHANGED
|
@@ -1,102 +1,13 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* Extract activity definitions for a specific workflow from a contract
|
|
6
|
-
*
|
|
7
|
-
* This includes both:
|
|
8
|
-
* - Workflow-specific activities defined under workflow.activities
|
|
9
|
-
* - Global activities defined under contract.activities
|
|
10
|
-
*
|
|
11
|
-
* @param contract - The contract definition
|
|
12
|
-
* @param workflowName - The name of the workflow
|
|
13
|
-
* @returns Activity definitions for the workflow (workflow-specific + global activities merged)
|
|
14
|
-
*
|
|
15
|
-
* @example
|
|
16
|
-
* ```ts
|
|
17
|
-
* const orderWorkflowActivities = getWorkflowActivities(myContract, 'processOrder');
|
|
18
|
-
* // Returns: { processPayment: ActivityDef, reserveInventory: ActivityDef, sendEmail: ActivityDef }
|
|
19
|
-
* // where sendEmail is a global activity
|
|
20
|
-
* ```
|
|
21
|
-
*/
|
|
22
|
-
function getWorkflowActivities(contract, workflowName) {
|
|
23
|
-
const workflowActivities = contract.workflows[workflowName]?.activities || {};
|
|
24
|
-
return {
|
|
25
|
-
...contract.activities || {},
|
|
26
|
-
...workflowActivities
|
|
27
|
-
};
|
|
28
|
-
}
|
|
29
|
-
/**
|
|
30
|
-
* Extract all activity names for a specific workflow from a contract
|
|
31
|
-
*
|
|
32
|
-
* @param contract - The contract definition
|
|
33
|
-
* @param workflowName - The name of the workflow
|
|
34
|
-
* @returns Array of activity names (strings) available for the workflow
|
|
35
|
-
*
|
|
36
|
-
* @example
|
|
37
|
-
* ```ts
|
|
38
|
-
* const activityNames = getWorkflowActivityNames(myContract, 'processOrder');
|
|
39
|
-
* // Returns: ['processPayment', 'reserveInventory', 'sendEmail']
|
|
40
|
-
* ```
|
|
41
|
-
*/
|
|
42
|
-
function getWorkflowActivityNames(contract, workflowName) {
|
|
43
|
-
const activities = getWorkflowActivities(contract, workflowName);
|
|
44
|
-
return Object.keys(activities);
|
|
45
|
-
}
|
|
46
|
-
/**
|
|
47
|
-
* Check if an activity belongs to a specific workflow
|
|
48
|
-
*
|
|
49
|
-
* @param contract - The contract definition
|
|
50
|
-
* @param workflowName - The name of the workflow
|
|
51
|
-
* @param activityName - The name of the activity to check
|
|
52
|
-
* @returns True if the activity is available for the workflow, false otherwise
|
|
53
|
-
*
|
|
54
|
-
* @example
|
|
55
|
-
* ```ts
|
|
56
|
-
* if (isWorkflowActivity(myContract, 'processOrder', 'processPayment')) {
|
|
57
|
-
* // Activity is available for this workflow
|
|
58
|
-
* }
|
|
59
|
-
* ```
|
|
60
|
-
*/
|
|
61
|
-
function isWorkflowActivity(contract, workflowName, activityName) {
|
|
62
|
-
return activityName in getWorkflowActivities(contract, workflowName);
|
|
63
|
-
}
|
|
64
|
-
/**
|
|
65
|
-
* Get all workflow names from a contract
|
|
66
|
-
*
|
|
67
|
-
* @param contract - The contract definition
|
|
68
|
-
* @returns Array of workflow names defined in the contract
|
|
69
|
-
*
|
|
70
|
-
* @example
|
|
71
|
-
* ```ts
|
|
72
|
-
* const workflows = getWorkflowNames(myContract);
|
|
73
|
-
* // Returns: ['processOrder', 'processRefund']
|
|
74
|
-
* ```
|
|
75
|
-
*/
|
|
76
|
-
function getWorkflowNames(contract) {
|
|
77
|
-
return Object.keys(contract.workflows);
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
//#endregion
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
+
const require_internal = require("./internal-Tj4m4f_K.cjs");
|
|
3
|
+
let _temporalio_common = require("@temporalio/common");
|
|
81
4
|
//#region src/activity.ts
|
|
82
5
|
/**
|
|
83
|
-
*
|
|
84
|
-
* Forces proper error handling and enables retry policies
|
|
85
|
-
*/
|
|
86
|
-
var ActivityError = class ActivityError extends Error {
|
|
87
|
-
constructor(code, message, cause) {
|
|
88
|
-
super(message, { cause });
|
|
89
|
-
this.code = code;
|
|
90
|
-
this.name = "ActivityError";
|
|
91
|
-
if (Error.captureStackTrace) Error.captureStackTrace(this, ActivityError);
|
|
92
|
-
}
|
|
93
|
-
};
|
|
94
|
-
/**
|
|
95
|
-
* Create a typed activities handler with automatic validation and Result pattern
|
|
6
|
+
* Create a typed activities handler with automatic validation and Result pattern.
|
|
96
7
|
*
|
|
97
8
|
* This wraps all activity implementations with:
|
|
98
9
|
* - Validation at network boundaries
|
|
99
|
-
* - Result<T,
|
|
10
|
+
* - `Result<T, ApplicationFailure>` pattern for explicit error handling
|
|
100
11
|
* - Automatic conversion from Result to Promise (throwing on Error)
|
|
101
12
|
*
|
|
102
13
|
* TypeScript ensures ALL activities (global + workflow-specific) are implemented.
|
|
@@ -105,28 +16,30 @@ var ActivityError = class ActivityError extends Error {
|
|
|
105
16
|
*
|
|
106
17
|
* @example
|
|
107
18
|
* ```ts
|
|
108
|
-
* import { declareActivitiesHandler,
|
|
19
|
+
* import { declareActivitiesHandler, ApplicationFailure } from '@temporal-contract/worker/activity';
|
|
109
20
|
* import { Result, Future } from '@swan-io/boxed';
|
|
110
21
|
* import myContract from './contract';
|
|
111
22
|
*
|
|
112
23
|
* export const activities = declareActivitiesHandler({
|
|
113
24
|
* contract: myContract,
|
|
114
25
|
* activities: {
|
|
115
|
-
* // Activity returns Result instead of throwing
|
|
116
|
-
* // All technical exceptions must be wrapped in ActivityError for retry policies
|
|
26
|
+
* // Activity returns Result instead of throwing.
|
|
117
27
|
* sendEmail: (args) => {
|
|
118
|
-
* return Future.make(async resolve => {
|
|
28
|
+
* return Future.make(async (resolve) => {
|
|
119
29
|
* try {
|
|
120
30
|
* await emailService.send(args);
|
|
121
31
|
* resolve(Result.Ok({ sent: true }));
|
|
122
32
|
* } catch (error) {
|
|
123
|
-
* // Wrap technical errors in
|
|
33
|
+
* // Wrap technical errors in ApplicationFailure. `nonRetryable`
|
|
34
|
+
* // is per-instance: set it to true on permanent failures so
|
|
35
|
+
* // Temporal stops retrying immediately.
|
|
124
36
|
* resolve(Result.Error(
|
|
125
|
-
*
|
|
126
|
-
* 'EMAIL_SEND_FAILED',
|
|
127
|
-
* 'Failed to send email',
|
|
128
|
-
*
|
|
129
|
-
*
|
|
37
|
+
* ApplicationFailure.create({
|
|
38
|
+
* type: 'EMAIL_SEND_FAILED',
|
|
39
|
+
* message: 'Failed to send email',
|
|
40
|
+
* nonRetryable: false,
|
|
41
|
+
* cause: error instanceof Error ? error : undefined,
|
|
42
|
+
* }),
|
|
130
43
|
* ));
|
|
131
44
|
* }
|
|
132
45
|
* });
|
|
@@ -143,19 +56,32 @@ var ActivityError = class ActivityError extends Error {
|
|
|
143
56
|
* taskQueue: contract.taskQueue,
|
|
144
57
|
* });
|
|
145
58
|
* ```
|
|
59
|
+
*
|
|
60
|
+
* @remarks
|
|
61
|
+
* The wrapper accepts implementations in the
|
|
62
|
+
* `Future<Result<T, ApplicationFailure>>` shape and produces ordinary
|
|
63
|
+
* Promise-returning Temporal handlers (Result.Error → thrown
|
|
64
|
+
* `ApplicationFailure`; Result.Ok → output validated against the
|
|
65
|
+
* contract and resolved). It does **not** hide Temporal's
|
|
66
|
+
* `@temporalio/activity` runtime: inside the body you can still call
|
|
67
|
+
* `Context.current()` from `@temporalio/activity` to access heartbeats
|
|
68
|
+
* (`heartbeat(details)`, `heartbeatDetails`), activity info (attempt
|
|
69
|
+
* number, workflow IDs), and the async-completion task token. See the
|
|
70
|
+
* "Working with the Activity Context" section of the worker
|
|
71
|
+
* implementation guide for end-to-end examples.
|
|
146
72
|
*/
|
|
147
73
|
function declareActivitiesHandler(options) {
|
|
148
74
|
const { contract, activities } = options;
|
|
149
75
|
const wrappedActivities = {};
|
|
150
76
|
function makeWrapped(activityName, activityDef, activityImpl) {
|
|
151
77
|
return async (...args) => {
|
|
152
|
-
const input =
|
|
78
|
+
const input = require_internal.extractHandlerInput(args);
|
|
153
79
|
const inputResult = await activityDef.input["~standard"].validate(input);
|
|
154
|
-
if (inputResult.issues) throw new
|
|
80
|
+
if (inputResult.issues) throw new require_internal.ActivityInputValidationError(activityName, inputResult.issues);
|
|
155
81
|
const result = await activityImpl(inputResult.value);
|
|
156
82
|
if (result.isOk()) {
|
|
157
83
|
const outputResult = await activityDef.output["~standard"].validate(result.value);
|
|
158
|
-
if (outputResult.issues) throw new
|
|
84
|
+
if (outputResult.issues) throw new require_internal.ActivityOutputValidationError(activityName, outputResult.issues);
|
|
159
85
|
return outputResult.value;
|
|
160
86
|
} else throw result.error;
|
|
161
87
|
};
|
|
@@ -163,7 +89,7 @@ function declareActivitiesHandler(options) {
|
|
|
163
89
|
if (contract.activities) for (const [activityName, impl] of Object.entries(activities)) {
|
|
164
90
|
if (contract.workflows && activityName in contract.workflows) continue;
|
|
165
91
|
const activityDef = contract.activities[activityName];
|
|
166
|
-
if (!activityDef) throw new
|
|
92
|
+
if (!activityDef) throw new require_internal.ActivityDefinitionNotFoundError(activityName, Object.keys(contract.activities));
|
|
167
93
|
wrappedActivities[activityName] = makeWrapped(activityName, activityDef, impl);
|
|
168
94
|
}
|
|
169
95
|
if (contract.workflows) for (const [workflowName, workflowDef] of Object.entries(contract.workflows)) {
|
|
@@ -172,20 +98,20 @@ function declareActivitiesHandler(options) {
|
|
|
172
98
|
const wfDefs = workflowDef.activities ?? {};
|
|
173
99
|
for (const [activityName, impl] of Object.entries(wfActivitiesImpl)) {
|
|
174
100
|
const activityDef = wfDefs[activityName];
|
|
175
|
-
if (!activityDef) throw new
|
|
101
|
+
if (!activityDef) throw new require_internal.ActivityDefinitionNotFoundError(`${workflowName}.${activityName}`, Object.keys(wfDefs));
|
|
176
102
|
wrappedActivities[activityName] = makeWrapped(`${workflowName}.${activityName}`, activityDef, impl);
|
|
177
103
|
}
|
|
178
104
|
}
|
|
179
105
|
return wrappedActivities;
|
|
180
106
|
}
|
|
181
|
-
|
|
182
107
|
//#endregion
|
|
183
|
-
exports.ActivityDefinitionNotFoundError =
|
|
184
|
-
exports.
|
|
185
|
-
exports.
|
|
186
|
-
exports
|
|
108
|
+
exports.ActivityDefinitionNotFoundError = require_internal.ActivityDefinitionNotFoundError;
|
|
109
|
+
exports.ActivityInputValidationError = require_internal.ActivityInputValidationError;
|
|
110
|
+
exports.ActivityOutputValidationError = require_internal.ActivityOutputValidationError;
|
|
111
|
+
Object.defineProperty(exports, "ApplicationFailure", {
|
|
112
|
+
enumerable: true,
|
|
113
|
+
get: function() {
|
|
114
|
+
return _temporalio_common.ApplicationFailure;
|
|
115
|
+
}
|
|
116
|
+
});
|
|
187
117
|
exports.declareActivitiesHandler = declareActivitiesHandler;
|
|
188
|
-
exports.getWorkflowActivities = getWorkflowActivities;
|
|
189
|
-
exports.getWorkflowActivityNames = getWorkflowActivityNames;
|
|
190
|
-
exports.getWorkflowNames = getWorkflowNames;
|
|
191
|
-
exports.isWorkflowActivity = isWorkflowActivity;
|
package/dist/activity.d.cts
CHANGED
|
@@ -1,3 +1,109 @@
|
|
|
1
|
-
import { n as ActivityInputValidationError, r as ActivityOutputValidationError, t as ActivityDefinitionNotFoundError } from "./errors-
|
|
2
|
-
import {
|
|
3
|
-
|
|
1
|
+
import { _ as WorkerInferOutput, g as WorkerInferInput, n as ActivityInputValidationError, r as ActivityOutputValidationError, t as ActivityDefinitionNotFoundError } from "./errors-CG1y7SHO.cjs";
|
|
2
|
+
import { ActivityDefinition, ContractDefinition } from "@temporal-contract/contract";
|
|
3
|
+
import { Future, Result } from "@swan-io/boxed";
|
|
4
|
+
import { ApplicationFailure, ApplicationFailure as ApplicationFailure$1 } from "@temporalio/common";
|
|
5
|
+
|
|
6
|
+
//#region src/activity.d.ts
|
|
7
|
+
/**
|
|
8
|
+
* Activity implementation using Future/Result pattern.
|
|
9
|
+
*
|
|
10
|
+
* Returns `Future<Result<Output, ApplicationFailure>>` for explicit error
|
|
11
|
+
* handling instead of throwing. The wrapper rethrows `Result.Error`
|
|
12
|
+
* payloads at the activity boundary; Temporal recognizes
|
|
13
|
+
* `ApplicationFailure` natively and applies the configured retry policy
|
|
14
|
+
* (with `nonRetryable: true` opting an instance out per-call).
|
|
15
|
+
*/
|
|
16
|
+
type BoxedActivityImplementation<TActivity extends ActivityDefinition> = (args: WorkerInferInput<TActivity>) => Future<Result<WorkerInferOutput<TActivity>, ApplicationFailure$1>>;
|
|
17
|
+
/**
|
|
18
|
+
* Map of all activity implementations for a contract (global + all workflow-specific)
|
|
19
|
+
*/
|
|
20
|
+
type ContractBoxedActivitiesImplementations<TContract extends ContractDefinition> = (TContract["activities"] extends Record<string, ActivityDefinition> ? BoxedActivitiesImplementations<TContract["activities"]> : {}) & { [TWorkflow in keyof TContract["workflows"]]: TContract["workflows"][TWorkflow]["activities"] extends Record<string, ActivityDefinition> ? BoxedActivitiesImplementations<TContract["workflows"][TWorkflow]["activities"]> : {} };
|
|
21
|
+
type BoxedActivitiesImplementations<TActivities extends Record<string, ActivityDefinition>> = { [K in keyof TActivities]: BoxedActivityImplementation<TActivities[K]> };
|
|
22
|
+
/**
|
|
23
|
+
* Options for creating activities handler
|
|
24
|
+
*/
|
|
25
|
+
type DeclareActivitiesHandlerOptions<TContract extends ContractDefinition> = {
|
|
26
|
+
contract: TContract;
|
|
27
|
+
activities: ContractBoxedActivitiesImplementations<TContract>;
|
|
28
|
+
};
|
|
29
|
+
type ActivityImplementation<TActivity extends ActivityDefinition> = (args: WorkerInferInput<TActivity>) => Promise<WorkerInferOutput<TActivity>>;
|
|
30
|
+
type ActivitiesImplementations<TActivities extends Record<string, ActivityDefinition>> = { [K in keyof TActivities]: ActivityImplementation<TActivities[K]> };
|
|
31
|
+
type UnionToIntersection<U> = (U extends unknown ? (k: U) => void : never) extends ((k: infer I) => void) ? I : never;
|
|
32
|
+
/**
|
|
33
|
+
* Activities handler ready for Temporal Worker
|
|
34
|
+
*
|
|
35
|
+
* Flat structure: all activities (global + all workflow-specific) are at the root level
|
|
36
|
+
*/
|
|
37
|
+
type ActivitiesHandler<TContract extends ContractDefinition> = (TContract["activities"] extends Record<string, ActivityDefinition> ? ActivitiesImplementations<TContract["activities"]> : {}) & UnionToIntersection<{ [TWorkflow in keyof TContract["workflows"]]: TContract["workflows"][TWorkflow]["activities"] extends Record<string, ActivityDefinition> ? ActivitiesImplementations<TContract["workflows"][TWorkflow]["activities"]> : {} }[keyof TContract["workflows"]]>;
|
|
38
|
+
/**
|
|
39
|
+
* Create a typed activities handler with automatic validation and Result pattern.
|
|
40
|
+
*
|
|
41
|
+
* This wraps all activity implementations with:
|
|
42
|
+
* - Validation at network boundaries
|
|
43
|
+
* - `Result<T, ApplicationFailure>` pattern for explicit error handling
|
|
44
|
+
* - Automatic conversion from Result to Promise (throwing on Error)
|
|
45
|
+
*
|
|
46
|
+
* TypeScript ensures ALL activities (global + workflow-specific) are implemented.
|
|
47
|
+
*
|
|
48
|
+
* Use this to create the activities object for the Temporal Worker.
|
|
49
|
+
*
|
|
50
|
+
* @example
|
|
51
|
+
* ```ts
|
|
52
|
+
* import { declareActivitiesHandler, ApplicationFailure } from '@temporal-contract/worker/activity';
|
|
53
|
+
* import { Result, Future } from '@swan-io/boxed';
|
|
54
|
+
* import myContract from './contract';
|
|
55
|
+
*
|
|
56
|
+
* export const activities = declareActivitiesHandler({
|
|
57
|
+
* contract: myContract,
|
|
58
|
+
* activities: {
|
|
59
|
+
* // Activity returns Result instead of throwing.
|
|
60
|
+
* sendEmail: (args) => {
|
|
61
|
+
* return Future.make(async (resolve) => {
|
|
62
|
+
* try {
|
|
63
|
+
* await emailService.send(args);
|
|
64
|
+
* resolve(Result.Ok({ sent: true }));
|
|
65
|
+
* } catch (error) {
|
|
66
|
+
* // Wrap technical errors in ApplicationFailure. `nonRetryable`
|
|
67
|
+
* // is per-instance: set it to true on permanent failures so
|
|
68
|
+
* // Temporal stops retrying immediately.
|
|
69
|
+
* resolve(Result.Error(
|
|
70
|
+
* ApplicationFailure.create({
|
|
71
|
+
* type: 'EMAIL_SEND_FAILED',
|
|
72
|
+
* message: 'Failed to send email',
|
|
73
|
+
* nonRetryable: false,
|
|
74
|
+
* cause: error instanceof Error ? error : undefined,
|
|
75
|
+
* }),
|
|
76
|
+
* ));
|
|
77
|
+
* }
|
|
78
|
+
* });
|
|
79
|
+
* },
|
|
80
|
+
* },
|
|
81
|
+
* });
|
|
82
|
+
*
|
|
83
|
+
* // Use with Temporal Worker
|
|
84
|
+
* import { Worker } from '@temporalio/worker';
|
|
85
|
+
*
|
|
86
|
+
* const worker = await Worker.create({
|
|
87
|
+
* workflowsPath: require.resolve('./workflows'),
|
|
88
|
+
* activities: activities,
|
|
89
|
+
* taskQueue: contract.taskQueue,
|
|
90
|
+
* });
|
|
91
|
+
* ```
|
|
92
|
+
*
|
|
93
|
+
* @remarks
|
|
94
|
+
* The wrapper accepts implementations in the
|
|
95
|
+
* `Future<Result<T, ApplicationFailure>>` shape and produces ordinary
|
|
96
|
+
* Promise-returning Temporal handlers (Result.Error → thrown
|
|
97
|
+
* `ApplicationFailure`; Result.Ok → output validated against the
|
|
98
|
+
* contract and resolved). It does **not** hide Temporal's
|
|
99
|
+
* `@temporalio/activity` runtime: inside the body you can still call
|
|
100
|
+
* `Context.current()` from `@temporalio/activity` to access heartbeats
|
|
101
|
+
* (`heartbeat(details)`, `heartbeatDetails`), activity info (attempt
|
|
102
|
+
* number, workflow IDs), and the async-completion task token. See the
|
|
103
|
+
* "Working with the Activity Context" section of the worker
|
|
104
|
+
* implementation guide for end-to-end examples.
|
|
105
|
+
*/
|
|
106
|
+
declare function declareActivitiesHandler<TContract extends ContractDefinition>(options: DeclareActivitiesHandlerOptions<TContract>): ActivitiesHandler<TContract>;
|
|
107
|
+
//#endregion
|
|
108
|
+
export { ActivitiesHandler, ActivityDefinitionNotFoundError, ActivityInputValidationError, ActivityOutputValidationError, ApplicationFailure, declareActivitiesHandler };
|
|
109
|
+
//# sourceMappingURL=activity.d.cts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"activity.d.cts","names":[],"sources":["../src/activity.ts"],"mappings":";;;;;;AAgCwD;;;;;;;;;AAAA,KAWnD,2BAAA,mBAA8C,kBAAA,KACjD,IAAA,EAAM,gBAAA,CAAiB,SAAA,MACpB,MAAA,CAAO,MAAA,CAAO,iBAAA,CAAkB,SAAA,GAAY,oBAAA;;;;KAK5C,sCAAA,mBAAyD,kBAAA,KAE3D,SAAA,uBAAgC,MAAA,SAAe,kBAAA,IAC5C,8BAAA,CAA+B,SAAA,8CAIX,SAAA,gBAAyB,SAAA,cAAuB,SAAA,wBAAiC,MAAA,SAEnG,kBAAA,IAEE,8BAAA,CAA+B,SAAA,cAAuB,SAAA;AAAA,KAI3D,8BAAA,qBAAmD,MAAA,SAAe,kBAAA,mBACzD,WAAA,GAAc,2BAAA,CAA4B,WAAA,CAAY,CAAA;;;;KAM/D,+BAAA,mBAAkD,kBAAA;EACrD,QAAA,EAAU,SAAA;EACV,UAAA,EAAY,sCAAA,CAAuC,SAAA;AAAA;AAAA,KAGhD,sBAAA,mBAAyC,kBAAA,KAC5C,IAAA,EAAM,gBAAA,CAAiB,SAAA,MACpB,OAAA,CAAQ,iBAAA,CAAkB,SAAA;AAAA,KAE1B,yBAAA,qBAA8C,MAAA,SAAe,kBAAA,mBACpD,WAAA,GAAc,sBAAA,CAAuB,WAAA,CAAY,CAAA;AAAA,KAG1D,mBAAA,OAA0B,CAAA,oBAAqB,CAAA,EAAG,CAAA,6BACrD,CAAA,sBAEE,CAAA;;;;;;KAQQ,iBAAA,mBAAoC,kBAAA,KAE7C,SAAA,uBAAgC,MAAA,SAAe,kBAAA,IAC5C,yBAAA,CAA0B,SAAA,wBAG5B,mBAAA,uBAEwB,SAAA,gBAAyB,SAAA,cAAuB,SAAA,wBAAiC,MAAA,SAEnG,kBAAA,IAEE,yBAAA,CAA0B,SAAA,cAAuB,SAAA,8BAE/C,SAAA;;;;;;;;;;;;;;;;;;;;;;;;AAjD2D;;;;;;;;;;;;;;;;;;;;;AAKJ;;;;;;;;;;;;;;;;;;AAQP;;;;;;iBA2G9C,wBAAA,mBAA2C,kBAAA,CAAA,CACzD,OAAA,EAAS,+BAAA,CAAgC,SAAA,IACxC,iBAAA,CAAkB,SAAA"}
|
package/dist/activity.d.mts
CHANGED
|
@@ -1,3 +1,109 @@
|
|
|
1
|
-
import { n as ActivityInputValidationError, r as ActivityOutputValidationError, t as ActivityDefinitionNotFoundError } from "./errors-
|
|
2
|
-
import {
|
|
3
|
-
|
|
1
|
+
import { _ as WorkerInferOutput, g as WorkerInferInput, n as ActivityInputValidationError, r as ActivityOutputValidationError, t as ActivityDefinitionNotFoundError } from "./errors-DZhaNhwr.mjs";
|
|
2
|
+
import { ApplicationFailure, ApplicationFailure as ApplicationFailure$1 } from "@temporalio/common";
|
|
3
|
+
import { ActivityDefinition, ContractDefinition } from "@temporal-contract/contract";
|
|
4
|
+
import { Future, Result } from "@swan-io/boxed";
|
|
5
|
+
|
|
6
|
+
//#region src/activity.d.ts
|
|
7
|
+
/**
|
|
8
|
+
* Activity implementation using Future/Result pattern.
|
|
9
|
+
*
|
|
10
|
+
* Returns `Future<Result<Output, ApplicationFailure>>` for explicit error
|
|
11
|
+
* handling instead of throwing. The wrapper rethrows `Result.Error`
|
|
12
|
+
* payloads at the activity boundary; Temporal recognizes
|
|
13
|
+
* `ApplicationFailure` natively and applies the configured retry policy
|
|
14
|
+
* (with `nonRetryable: true` opting an instance out per-call).
|
|
15
|
+
*/
|
|
16
|
+
type BoxedActivityImplementation<TActivity extends ActivityDefinition> = (args: WorkerInferInput<TActivity>) => Future<Result<WorkerInferOutput<TActivity>, ApplicationFailure$1>>;
|
|
17
|
+
/**
|
|
18
|
+
* Map of all activity implementations for a contract (global + all workflow-specific)
|
|
19
|
+
*/
|
|
20
|
+
type ContractBoxedActivitiesImplementations<TContract extends ContractDefinition> = (TContract["activities"] extends Record<string, ActivityDefinition> ? BoxedActivitiesImplementations<TContract["activities"]> : {}) & { [TWorkflow in keyof TContract["workflows"]]: TContract["workflows"][TWorkflow]["activities"] extends Record<string, ActivityDefinition> ? BoxedActivitiesImplementations<TContract["workflows"][TWorkflow]["activities"]> : {} };
|
|
21
|
+
type BoxedActivitiesImplementations<TActivities extends Record<string, ActivityDefinition>> = { [K in keyof TActivities]: BoxedActivityImplementation<TActivities[K]> };
|
|
22
|
+
/**
|
|
23
|
+
* Options for creating activities handler
|
|
24
|
+
*/
|
|
25
|
+
type DeclareActivitiesHandlerOptions<TContract extends ContractDefinition> = {
|
|
26
|
+
contract: TContract;
|
|
27
|
+
activities: ContractBoxedActivitiesImplementations<TContract>;
|
|
28
|
+
};
|
|
29
|
+
type ActivityImplementation<TActivity extends ActivityDefinition> = (args: WorkerInferInput<TActivity>) => Promise<WorkerInferOutput<TActivity>>;
|
|
30
|
+
type ActivitiesImplementations<TActivities extends Record<string, ActivityDefinition>> = { [K in keyof TActivities]: ActivityImplementation<TActivities[K]> };
|
|
31
|
+
type UnionToIntersection<U> = (U extends unknown ? (k: U) => void : never) extends ((k: infer I) => void) ? I : never;
|
|
32
|
+
/**
|
|
33
|
+
* Activities handler ready for Temporal Worker
|
|
34
|
+
*
|
|
35
|
+
* Flat structure: all activities (global + all workflow-specific) are at the root level
|
|
36
|
+
*/
|
|
37
|
+
type ActivitiesHandler<TContract extends ContractDefinition> = (TContract["activities"] extends Record<string, ActivityDefinition> ? ActivitiesImplementations<TContract["activities"]> : {}) & UnionToIntersection<{ [TWorkflow in keyof TContract["workflows"]]: TContract["workflows"][TWorkflow]["activities"] extends Record<string, ActivityDefinition> ? ActivitiesImplementations<TContract["workflows"][TWorkflow]["activities"]> : {} }[keyof TContract["workflows"]]>;
|
|
38
|
+
/**
|
|
39
|
+
* Create a typed activities handler with automatic validation and Result pattern.
|
|
40
|
+
*
|
|
41
|
+
* This wraps all activity implementations with:
|
|
42
|
+
* - Validation at network boundaries
|
|
43
|
+
* - `Result<T, ApplicationFailure>` pattern for explicit error handling
|
|
44
|
+
* - Automatic conversion from Result to Promise (throwing on Error)
|
|
45
|
+
*
|
|
46
|
+
* TypeScript ensures ALL activities (global + workflow-specific) are implemented.
|
|
47
|
+
*
|
|
48
|
+
* Use this to create the activities object for the Temporal Worker.
|
|
49
|
+
*
|
|
50
|
+
* @example
|
|
51
|
+
* ```ts
|
|
52
|
+
* import { declareActivitiesHandler, ApplicationFailure } from '@temporal-contract/worker/activity';
|
|
53
|
+
* import { Result, Future } from '@swan-io/boxed';
|
|
54
|
+
* import myContract from './contract';
|
|
55
|
+
*
|
|
56
|
+
* export const activities = declareActivitiesHandler({
|
|
57
|
+
* contract: myContract,
|
|
58
|
+
* activities: {
|
|
59
|
+
* // Activity returns Result instead of throwing.
|
|
60
|
+
* sendEmail: (args) => {
|
|
61
|
+
* return Future.make(async (resolve) => {
|
|
62
|
+
* try {
|
|
63
|
+
* await emailService.send(args);
|
|
64
|
+
* resolve(Result.Ok({ sent: true }));
|
|
65
|
+
* } catch (error) {
|
|
66
|
+
* // Wrap technical errors in ApplicationFailure. `nonRetryable`
|
|
67
|
+
* // is per-instance: set it to true on permanent failures so
|
|
68
|
+
* // Temporal stops retrying immediately.
|
|
69
|
+
* resolve(Result.Error(
|
|
70
|
+
* ApplicationFailure.create({
|
|
71
|
+
* type: 'EMAIL_SEND_FAILED',
|
|
72
|
+
* message: 'Failed to send email',
|
|
73
|
+
* nonRetryable: false,
|
|
74
|
+
* cause: error instanceof Error ? error : undefined,
|
|
75
|
+
* }),
|
|
76
|
+
* ));
|
|
77
|
+
* }
|
|
78
|
+
* });
|
|
79
|
+
* },
|
|
80
|
+
* },
|
|
81
|
+
* });
|
|
82
|
+
*
|
|
83
|
+
* // Use with Temporal Worker
|
|
84
|
+
* import { Worker } from '@temporalio/worker';
|
|
85
|
+
*
|
|
86
|
+
* const worker = await Worker.create({
|
|
87
|
+
* workflowsPath: require.resolve('./workflows'),
|
|
88
|
+
* activities: activities,
|
|
89
|
+
* taskQueue: contract.taskQueue,
|
|
90
|
+
* });
|
|
91
|
+
* ```
|
|
92
|
+
*
|
|
93
|
+
* @remarks
|
|
94
|
+
* The wrapper accepts implementations in the
|
|
95
|
+
* `Future<Result<T, ApplicationFailure>>` shape and produces ordinary
|
|
96
|
+
* Promise-returning Temporal handlers (Result.Error → thrown
|
|
97
|
+
* `ApplicationFailure`; Result.Ok → output validated against the
|
|
98
|
+
* contract and resolved). It does **not** hide Temporal's
|
|
99
|
+
* `@temporalio/activity` runtime: inside the body you can still call
|
|
100
|
+
* `Context.current()` from `@temporalio/activity` to access heartbeats
|
|
101
|
+
* (`heartbeat(details)`, `heartbeatDetails`), activity info (attempt
|
|
102
|
+
* number, workflow IDs), and the async-completion task token. See the
|
|
103
|
+
* "Working with the Activity Context" section of the worker
|
|
104
|
+
* implementation guide for end-to-end examples.
|
|
105
|
+
*/
|
|
106
|
+
declare function declareActivitiesHandler<TContract extends ContractDefinition>(options: DeclareActivitiesHandlerOptions<TContract>): ActivitiesHandler<TContract>;
|
|
107
|
+
//#endregion
|
|
108
|
+
export { ActivitiesHandler, ActivityDefinitionNotFoundError, ActivityInputValidationError, ActivityOutputValidationError, ApplicationFailure, declareActivitiesHandler };
|
|
109
|
+
//# sourceMappingURL=activity.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"activity.d.mts","names":[],"sources":["../src/activity.ts"],"mappings":";;;;;;AAgCwD;;;;;;;;;AAAA,KAWnD,2BAAA,mBAA8C,kBAAA,KACjD,IAAA,EAAM,gBAAA,CAAiB,SAAA,MACpB,MAAA,CAAO,MAAA,CAAO,iBAAA,CAAkB,SAAA,GAAY,oBAAA;;;;KAK5C,sCAAA,mBAAyD,kBAAA,KAE3D,SAAA,uBAAgC,MAAA,SAAe,kBAAA,IAC5C,8BAAA,CAA+B,SAAA,8CAIX,SAAA,gBAAyB,SAAA,cAAuB,SAAA,wBAAiC,MAAA,SAEnG,kBAAA,IAEE,8BAAA,CAA+B,SAAA,cAAuB,SAAA;AAAA,KAI3D,8BAAA,qBAAmD,MAAA,SAAe,kBAAA,mBACzD,WAAA,GAAc,2BAAA,CAA4B,WAAA,CAAY,CAAA;;;;KAM/D,+BAAA,mBAAkD,kBAAA;EACrD,QAAA,EAAU,SAAA;EACV,UAAA,EAAY,sCAAA,CAAuC,SAAA;AAAA;AAAA,KAGhD,sBAAA,mBAAyC,kBAAA,KAC5C,IAAA,EAAM,gBAAA,CAAiB,SAAA,MACpB,OAAA,CAAQ,iBAAA,CAAkB,SAAA;AAAA,KAE1B,yBAAA,qBAA8C,MAAA,SAAe,kBAAA,mBACpD,WAAA,GAAc,sBAAA,CAAuB,WAAA,CAAY,CAAA;AAAA,KAG1D,mBAAA,OAA0B,CAAA,oBAAqB,CAAA,EAAG,CAAA,6BACrD,CAAA,sBAEE,CAAA;;;;;;KAQQ,iBAAA,mBAAoC,kBAAA,KAE7C,SAAA,uBAAgC,MAAA,SAAe,kBAAA,IAC5C,yBAAA,CAA0B,SAAA,wBAG5B,mBAAA,uBAEwB,SAAA,gBAAyB,SAAA,cAAuB,SAAA,wBAAiC,MAAA,SAEnG,kBAAA,IAEE,yBAAA,CAA0B,SAAA,cAAuB,SAAA,8BAE/C,SAAA;;;;;;;;;;;;;;;;;;;;;;;;AAjD2D;;;;;;;;;;;;;;;;;;;;;AAKJ;;;;;;;;;;;;;;;;;;AAQP;;;;;;iBA2G9C,wBAAA,mBAA2C,kBAAA,CAAA,CACzD,OAAA,EAAS,+BAAA,CAAgC,SAAA,IACxC,iBAAA,CAAkB,SAAA"}
|