@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/dist/activity.mjs
CHANGED
|
@@ -1,102 +1,12 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
//#region src/activity-utils.ts
|
|
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
|
+
import { a as ActivityInputValidationError, i as ActivityDefinitionNotFoundError, o as ActivityOutputValidationError, r as extractHandlerInput } from "./internal-BoNcEtYh.mjs";
|
|
2
|
+
import { ApplicationFailure } from "@temporalio/common";
|
|
81
3
|
//#region src/activity.ts
|
|
82
4
|
/**
|
|
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
|
|
5
|
+
* Create a typed activities handler with automatic validation and Result pattern.
|
|
96
6
|
*
|
|
97
7
|
* This wraps all activity implementations with:
|
|
98
8
|
* - Validation at network boundaries
|
|
99
|
-
* - Result<T,
|
|
9
|
+
* - `Result<T, ApplicationFailure>` pattern for explicit error handling
|
|
100
10
|
* - Automatic conversion from Result to Promise (throwing on Error)
|
|
101
11
|
*
|
|
102
12
|
* TypeScript ensures ALL activities (global + workflow-specific) are implemented.
|
|
@@ -105,28 +15,30 @@ var ActivityError = class ActivityError extends Error {
|
|
|
105
15
|
*
|
|
106
16
|
* @example
|
|
107
17
|
* ```ts
|
|
108
|
-
* import { declareActivitiesHandler,
|
|
18
|
+
* import { declareActivitiesHandler, ApplicationFailure } from '@temporal-contract/worker/activity';
|
|
109
19
|
* import { Result, Future } from '@swan-io/boxed';
|
|
110
20
|
* import myContract from './contract';
|
|
111
21
|
*
|
|
112
22
|
* export const activities = declareActivitiesHandler({
|
|
113
23
|
* contract: myContract,
|
|
114
24
|
* activities: {
|
|
115
|
-
* // Activity returns Result instead of throwing
|
|
116
|
-
* // All technical exceptions must be wrapped in ActivityError for retry policies
|
|
25
|
+
* // Activity returns Result instead of throwing.
|
|
117
26
|
* sendEmail: (args) => {
|
|
118
|
-
* return Future.make(async resolve => {
|
|
27
|
+
* return Future.make(async (resolve) => {
|
|
119
28
|
* try {
|
|
120
29
|
* await emailService.send(args);
|
|
121
30
|
* resolve(Result.Ok({ sent: true }));
|
|
122
31
|
* } catch (error) {
|
|
123
|
-
* // Wrap technical errors in
|
|
32
|
+
* // Wrap technical errors in ApplicationFailure. `nonRetryable`
|
|
33
|
+
* // is per-instance: set it to true on permanent failures so
|
|
34
|
+
* // Temporal stops retrying immediately.
|
|
124
35
|
* resolve(Result.Error(
|
|
125
|
-
*
|
|
126
|
-
* 'EMAIL_SEND_FAILED',
|
|
127
|
-
* 'Failed to send email',
|
|
128
|
-
*
|
|
129
|
-
*
|
|
36
|
+
* ApplicationFailure.create({
|
|
37
|
+
* type: 'EMAIL_SEND_FAILED',
|
|
38
|
+
* message: 'Failed to send email',
|
|
39
|
+
* nonRetryable: false,
|
|
40
|
+
* cause: error instanceof Error ? error : undefined,
|
|
41
|
+
* }),
|
|
130
42
|
* ));
|
|
131
43
|
* }
|
|
132
44
|
* });
|
|
@@ -143,13 +55,26 @@ var ActivityError = class ActivityError extends Error {
|
|
|
143
55
|
* taskQueue: contract.taskQueue,
|
|
144
56
|
* });
|
|
145
57
|
* ```
|
|
58
|
+
*
|
|
59
|
+
* @remarks
|
|
60
|
+
* The wrapper accepts implementations in the
|
|
61
|
+
* `Future<Result<T, ApplicationFailure>>` shape and produces ordinary
|
|
62
|
+
* Promise-returning Temporal handlers (Result.Error → thrown
|
|
63
|
+
* `ApplicationFailure`; Result.Ok → output validated against the
|
|
64
|
+
* contract and resolved). It does **not** hide Temporal's
|
|
65
|
+
* `@temporalio/activity` runtime: inside the body you can still call
|
|
66
|
+
* `Context.current()` from `@temporalio/activity` to access heartbeats
|
|
67
|
+
* (`heartbeat(details)`, `heartbeatDetails`), activity info (attempt
|
|
68
|
+
* number, workflow IDs), and the async-completion task token. See the
|
|
69
|
+
* "Working with the Activity Context" section of the worker
|
|
70
|
+
* implementation guide for end-to-end examples.
|
|
146
71
|
*/
|
|
147
72
|
function declareActivitiesHandler(options) {
|
|
148
73
|
const { contract, activities } = options;
|
|
149
74
|
const wrappedActivities = {};
|
|
150
75
|
function makeWrapped(activityName, activityDef, activityImpl) {
|
|
151
76
|
return async (...args) => {
|
|
152
|
-
const input = args
|
|
77
|
+
const input = extractHandlerInput(args);
|
|
153
78
|
const inputResult = await activityDef.input["~standard"].validate(input);
|
|
154
79
|
if (inputResult.issues) throw new ActivityInputValidationError(activityName, inputResult.issues);
|
|
155
80
|
const result = await activityImpl(inputResult.value);
|
|
@@ -178,6 +103,7 @@ function declareActivitiesHandler(options) {
|
|
|
178
103
|
}
|
|
179
104
|
return wrappedActivities;
|
|
180
105
|
}
|
|
181
|
-
|
|
182
106
|
//#endregion
|
|
183
|
-
export { ActivityDefinitionNotFoundError,
|
|
107
|
+
export { ActivityDefinitionNotFoundError, ActivityInputValidationError, ActivityOutputValidationError, ApplicationFailure, declareActivitiesHandler };
|
|
108
|
+
|
|
109
|
+
//# sourceMappingURL=activity.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"activity.mjs","names":[],"sources":["../src/activity.ts"],"sourcesContent":["// Entry point for activity implementations.\n//\n// Activities run *outside* the workflow sandbox, so they can use any\n// implementation of the Result/Future pattern — we standardize on\n// `@swan-io/boxed` here for its richer API. Workflow code (see workflow.ts)\n// must use `@temporal-contract/boxed` instead, since it's compatible with\n// Temporal's deterministic replay machinery.\n//\n// Errors flow through Temporal's `ApplicationFailure` (re-exported from\n// `@temporalio/common`) — it's the SDK's first-class failure shape, so we\n// don't wrap it in a custom class. `ApplicationFailure` exposes\n// `nonRetryable`, `type`, `details`, and `category` natively, and survives\n// the activity → workflow serialization boundary unchanged.\nimport { ActivityDefinition, ContractDefinition } from \"@temporal-contract/contract\";\nimport { Future, Result } from \"@swan-io/boxed\";\nimport { ApplicationFailure } from \"@temporalio/common\";\nimport { WorkerInferInput, WorkerInferOutput } from \"./types.js\";\nimport {\n ActivityDefinitionNotFoundError,\n ActivityInputValidationError,\n ActivityOutputValidationError,\n} from \"./errors.js\";\nimport { extractHandlerInput } from \"./internal.js\";\n\nexport {\n ActivityDefinitionNotFoundError,\n ActivityInputValidationError,\n ActivityOutputValidationError,\n} from \"./errors.js\";\n\n// Re-export the canonical activity-failure class so consumers don't need\n// a separate `@temporalio/common` import to construct one.\nexport { ApplicationFailure } from \"@temporalio/common\";\n\n/**\n * Activity implementation using Future/Result pattern.\n *\n * Returns `Future<Result<Output, ApplicationFailure>>` for explicit error\n * handling instead of throwing. The wrapper rethrows `Result.Error`\n * payloads at the activity boundary; Temporal recognizes\n * `ApplicationFailure` natively and applies the configured retry policy\n * (with `nonRetryable: true` opting an instance out per-call).\n */\ntype BoxedActivityImplementation<TActivity extends ActivityDefinition> = (\n args: WorkerInferInput<TActivity>,\n) => Future<Result<WorkerInferOutput<TActivity>, ApplicationFailure>>;\n\n/**\n * Map of all activity implementations for a contract (global + all workflow-specific)\n */\ntype ContractBoxedActivitiesImplementations<TContract extends ContractDefinition> =\n // Global activities\n (TContract[\"activities\"] extends Record<string, ActivityDefinition>\n ? BoxedActivitiesImplementations<TContract[\"activities\"]>\n : {}) &\n // All workflow-specific activities merged\n {\n [TWorkflow in keyof TContract[\"workflows\"]]: TContract[\"workflows\"][TWorkflow][\"activities\"] extends Record<\n string,\n ActivityDefinition\n >\n ? BoxedActivitiesImplementations<TContract[\"workflows\"][TWorkflow][\"activities\"]>\n : {};\n };\n\ntype BoxedActivitiesImplementations<TActivities extends Record<string, ActivityDefinition>> = {\n [K in keyof TActivities]: BoxedActivityImplementation<TActivities[K]>;\n};\n\n/**\n * Options for creating activities handler\n */\ntype DeclareActivitiesHandlerOptions<TContract extends ContractDefinition> = {\n contract: TContract;\n activities: ContractBoxedActivitiesImplementations<TContract>;\n};\n\ntype ActivityImplementation<TActivity extends ActivityDefinition> = (\n args: WorkerInferInput<TActivity>,\n) => Promise<WorkerInferOutput<TActivity>>;\n\ntype ActivitiesImplementations<TActivities extends Record<string, ActivityDefinition>> = {\n [K in keyof TActivities]: ActivityImplementation<TActivities[K]>;\n};\n\ntype UnionToIntersection<U> = (U extends unknown ? (k: U) => void : never) extends (\n k: infer I,\n) => void\n ? I\n : never;\n\n/**\n * Activities handler ready for Temporal Worker\n *\n * Flat structure: all activities (global + all workflow-specific) are at the root level\n */\nexport type ActivitiesHandler<TContract extends ContractDefinition> =\n // Global activities\n (TContract[\"activities\"] extends Record<string, ActivityDefinition>\n ? ActivitiesImplementations<TContract[\"activities\"]>\n : {}) &\n // All workflow-specific activities merged at root level (flat)\n UnionToIntersection<\n {\n [TWorkflow in keyof TContract[\"workflows\"]]: TContract[\"workflows\"][TWorkflow][\"activities\"] extends Record<\n string,\n ActivityDefinition\n >\n ? ActivitiesImplementations<TContract[\"workflows\"][TWorkflow][\"activities\"]>\n : {};\n }[keyof TContract[\"workflows\"]]\n >;\n\n/**\n * Create a typed activities handler with automatic validation and Result pattern.\n *\n * This wraps all activity implementations with:\n * - Validation at network boundaries\n * - `Result<T, ApplicationFailure>` pattern for explicit error handling\n * - Automatic conversion from Result to Promise (throwing on Error)\n *\n * TypeScript ensures ALL activities (global + workflow-specific) are implemented.\n *\n * Use this to create the activities object for the Temporal Worker.\n *\n * @example\n * ```ts\n * import { declareActivitiesHandler, ApplicationFailure } from '@temporal-contract/worker/activity';\n * import { Result, Future } from '@swan-io/boxed';\n * import myContract from './contract';\n *\n * export const activities = declareActivitiesHandler({\n * contract: myContract,\n * activities: {\n * // Activity returns Result instead of throwing.\n * sendEmail: (args) => {\n * return Future.make(async (resolve) => {\n * try {\n * await emailService.send(args);\n * resolve(Result.Ok({ sent: true }));\n * } catch (error) {\n * // Wrap technical errors in ApplicationFailure. `nonRetryable`\n * // is per-instance: set it to true on permanent failures so\n * // Temporal stops retrying immediately.\n * resolve(Result.Error(\n * ApplicationFailure.create({\n * type: 'EMAIL_SEND_FAILED',\n * message: 'Failed to send email',\n * nonRetryable: false,\n * cause: error instanceof Error ? error : undefined,\n * }),\n * ));\n * }\n * });\n * },\n * },\n * });\n *\n * // Use with Temporal Worker\n * import { Worker } from '@temporalio/worker';\n *\n * const worker = await Worker.create({\n * workflowsPath: require.resolve('./workflows'),\n * activities: activities,\n * taskQueue: contract.taskQueue,\n * });\n * ```\n *\n * @remarks\n * The wrapper accepts implementations in the\n * `Future<Result<T, ApplicationFailure>>` shape and produces ordinary\n * Promise-returning Temporal handlers (Result.Error → thrown\n * `ApplicationFailure`; Result.Ok → output validated against the\n * contract and resolved). It does **not** hide Temporal's\n * `@temporalio/activity` runtime: inside the body you can still call\n * `Context.current()` from `@temporalio/activity` to access heartbeats\n * (`heartbeat(details)`, `heartbeatDetails`), activity info (attempt\n * number, workflow IDs), and the async-completion task token. See the\n * \"Working with the Activity Context\" section of the worker\n * implementation guide for end-to-end examples.\n */\nexport function declareActivitiesHandler<TContract extends ContractDefinition>(\n options: DeclareActivitiesHandlerOptions<TContract>,\n): ActivitiesHandler<TContract> {\n const { contract, activities } = options;\n\n // Prepare Temporal-compatible activities with validation and Result unwrapping\n const wrappedActivities = {} as ActivitiesHandler<TContract>;\n\n // Helper to create a wrapped implementation from a definition and impl\n function makeWrapped(\n activityName: string,\n activityDef: ActivityDefinition,\n activityImpl: (args: unknown) => Future<Result<unknown, ApplicationFailure>>,\n ) {\n return async (...args: unknown[]) => {\n const input = extractHandlerInput(args);\n\n // Validate input\n const inputResult = await activityDef.input[\"~standard\"].validate(input);\n if (inputResult.issues) {\n throw new ActivityInputValidationError(activityName, inputResult.issues);\n }\n\n // Execute boxed activity (returns Future<Result<T, ApplicationFailure>>)\n const futureResult = activityImpl(inputResult.value);\n\n // Await Future and unwrap Result\n const result = await futureResult;\n\n // Process result: validate output or throw error\n if (result.isOk()) {\n // Validate output on success\n const outputResult = await activityDef.output[\"~standard\"].validate(result.value);\n if (outputResult.issues) {\n throw new ActivityOutputValidationError(activityName, outputResult.issues);\n }\n return outputResult.value;\n } else {\n // Convert Result.Error to thrown ApplicationFailure for Temporal.\n // Temporal recognizes this class natively and applies the\n // configured retry policy (honoring `nonRetryable: true`).\n throw result.error;\n }\n };\n }\n\n // 1) Wrap global activities defined directly under contract.activities\n if (contract.activities) {\n for (const [activityName, impl] of Object.entries(activities)) {\n // Skip workflow namespaces if present at root\n if (contract.workflows && activityName in contract.workflows) {\n continue;\n }\n\n const activityDef = contract.activities[activityName];\n if (!activityDef) {\n throw new ActivityDefinitionNotFoundError(activityName, Object.keys(contract.activities));\n }\n\n // Assign wrapped global activity\n (wrappedActivities as Record<string, unknown>)[activityName] = makeWrapped(\n activityName,\n activityDef,\n impl as (args: unknown) => Future<Result<unknown, ApplicationFailure>>,\n );\n }\n }\n\n // 2) Wrap workflow-scoped activities at root level (flat)\n if (contract.workflows) {\n for (const [workflowName, workflowDef] of Object.entries(contract.workflows)) {\n const wfActivitiesImpl = (activities as Record<string, unknown>)[workflowName] as\n | Record<string, unknown>\n | undefined;\n if (!wfActivitiesImpl) {\n // If no implementations provided for this workflow, skip (TypeScript typing should enforce completeness for declared ones)\n continue;\n }\n\n const wfDefs = workflowDef.activities ?? {};\n\n for (const [activityName, impl] of Object.entries(wfActivitiesImpl)) {\n const activityDef = wfDefs[activityName];\n if (!activityDef) {\n throw new ActivityDefinitionNotFoundError(\n `${workflowName}.${activityName}`,\n Object.keys(wfDefs),\n );\n }\n\n // Assign workflow activity directly at root level (flat structure)\n (wrappedActivities as Record<string, unknown>)[activityName] = makeWrapped(\n `${workflowName}.${activityName}`,\n activityDef,\n impl as (args: unknown) => Future<Result<unknown, ApplicationFailure>>,\n );\n }\n }\n }\n\n return wrappedActivities;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAqLA,SAAgB,yBACd,SAC8B;CAC9B,MAAM,EAAE,UAAU,eAAe;CAGjC,MAAM,oBAAoB,EAAE;CAG5B,SAAS,YACP,cACA,aACA,cACA;AACA,SAAO,OAAO,GAAG,SAAoB;GACnC,MAAM,QAAQ,oBAAoB,KAAK;GAGvC,MAAM,cAAc,MAAM,YAAY,MAAM,aAAa,SAAS,MAAM;AACxE,OAAI,YAAY,OACd,OAAM,IAAI,6BAA6B,cAAc,YAAY,OAAO;GAO1E,MAAM,SAAS,MAHM,aAAa,YAAY,MAGb;AAGjC,OAAI,OAAO,MAAM,EAAE;IAEjB,MAAM,eAAe,MAAM,YAAY,OAAO,aAAa,SAAS,OAAO,MAAM;AACjF,QAAI,aAAa,OACf,OAAM,IAAI,8BAA8B,cAAc,aAAa,OAAO;AAE5E,WAAO,aAAa;SAKpB,OAAM,OAAO;;;AAMnB,KAAI,SAAS,WACX,MAAK,MAAM,CAAC,cAAc,SAAS,OAAO,QAAQ,WAAW,EAAE;AAE7D,MAAI,SAAS,aAAa,gBAAgB,SAAS,UACjD;EAGF,MAAM,cAAc,SAAS,WAAW;AACxC,MAAI,CAAC,YACH,OAAM,IAAI,gCAAgC,cAAc,OAAO,KAAK,SAAS,WAAW,CAAC;AAI1F,oBAA8C,gBAAgB,YAC7D,cACA,aACA,KACD;;AAKL,KAAI,SAAS,UACX,MAAK,MAAM,CAAC,cAAc,gBAAgB,OAAO,QAAQ,SAAS,UAAU,EAAE;EAC5E,MAAM,mBAAoB,WAAuC;AAGjE,MAAI,CAAC,iBAEH;EAGF,MAAM,SAAS,YAAY,cAAc,EAAE;AAE3C,OAAK,MAAM,CAAC,cAAc,SAAS,OAAO,QAAQ,iBAAiB,EAAE;GACnE,MAAM,cAAc,OAAO;AAC3B,OAAI,CAAC,YACH,OAAM,IAAI,gCACR,GAAG,aAAa,GAAG,gBACnB,OAAO,KAAK,OAAO,CACpB;AAIF,qBAA8C,gBAAgB,YAC7D,GAAG,aAAa,GAAG,gBACnB,aACA,KACD;;;AAKP,QAAO"}
|
|
@@ -132,5 +132,18 @@ declare class ChildWorkflowNotFoundError extends WorkerError {
|
|
|
132
132
|
declare class ChildWorkflowError extends WorkerError {
|
|
133
133
|
constructor(message: string, cause?: unknown);
|
|
134
134
|
}
|
|
135
|
+
/**
|
|
136
|
+
* Error returned in the `Result.Error` branch when a typed cancellation
|
|
137
|
+
* scope is cancelled via Temporal's cancellation propagation. Returned by
|
|
138
|
+
* both `context.cancellableScope` (when the workflow or an ancestor scope
|
|
139
|
+
* cancels) and `context.nonCancellableScope` (when cancellation is raised
|
|
140
|
+
* from inside the scope). Distinct from arbitrary thrown errors so call
|
|
141
|
+
* sites can branch on cancellation explicitly while still surfacing
|
|
142
|
+
* non-cancellation errors as Future rejections.
|
|
143
|
+
*/
|
|
144
|
+
declare class WorkflowCancelledError extends WorkerError {
|
|
145
|
+
constructor(cause?: unknown);
|
|
146
|
+
}
|
|
135
147
|
//#endregion
|
|
136
|
-
export { ChildWorkflowNotFoundError as a, SignalInputValidationError as c,
|
|
148
|
+
export { WorkerInferOutput as _, ChildWorkflowNotFoundError as a, SignalInputValidationError as c, WorkflowCancelledError as d, WorkflowInputValidationError as f, WorkerInferInput as g, ClientInferOutput as h, ChildWorkflowError as i, UpdateInputValidationError as l, ClientInferInput as m, ActivityInputValidationError as n, QueryInputValidationError as o, WorkflowOutputValidationError as p, ActivityOutputValidationError as r, QueryOutputValidationError as s, ActivityDefinitionNotFoundError as t, UpdateOutputValidationError as u };
|
|
149
|
+
//# sourceMappingURL=errors-CG1y7SHO.d.cts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors-CG1y7SHO.d.cts","names":[],"sources":["../src/types.ts","../src/errors.ts"],"mappings":";;;;;;AAOA;;KAAY,gBAAA;EAA6B,KAAA,EAAO,SAAA;AAAA,KAAe,gBAAA,CAAiB,WAAA,CAC9E,CAAA;;;;;KAOU,iBAAA;EAA8B,MAAA,EAAQ,SAAA;AAAA,KAAe,gBAAA,CAAiB,UAAA,CAChF,CAAA;;;;;KAOU,gBAAA;EAA6B,KAAA,EAAO,SAAA;AAAA,KAAe,gBAAA,CAAiB,UAAA,CAC9E,CAAA;;;;;KAOU,iBAAA;EAA8B,MAAA,EAAQ,SAAA;AAAA,KAAe,gBAAA,CAAiB,WAAA,CAChF,CAAA;;;;;;uBC1Ba,WAAA,SAAoB,KAAA;EAAA,UACxB,WAAA,CAAa,OAAA,UAAiB,KAAA;AAAA;;;;cAa5B,+BAAA,SAAwC,WAAA;EAAA,SAEjC,YAAA;EAAA,SACA,oBAAA;cADA,YAAA,UACA,oBAAA;AAAA;;;;cAaP,4BAAA,SAAqC,WAAA;EAAA,SAE9B,YAAA;EAAA,SACA,MAAA,EAAQ,aAAA,CAAc,gBAAA,CAAiB,KAAA;cADvC,YAAA,UACA,MAAA,EAAQ,aAAA,CAAc,gBAAA,CAAiB,KAAA;AAAA;;;;cAW9C,6BAAA,SAAsC,WAAA;EAAA,SAE/B,YAAA;EAAA,SACA,MAAA,EAAQ,aAAA,CAAc,gBAAA,CAAiB,KAAA;cADvC,YAAA,UACA,MAAA,EAAQ,aAAA,CAAc,gBAAA,CAAiB,KAAA;AAAA;;;;cAW9C,4BAAA,SAAqC,WAAA;EAAA,SAE9B,YAAA;EAAA,SACA,MAAA,EAAQ,aAAA,CAAc,gBAAA,CAAiB,KAAA;cADvC,YAAA,UACA,MAAA,EAAQ,aAAA,CAAc,gBAAA,CAAiB,KAAA;AAAA;;;;cAW9C,6BAAA,SAAsC,WAAA;EAAA,SAE/B,YAAA;EAAA,SACA,MAAA,EAAQ,aAAA,CAAc,gBAAA,CAAiB,KAAA;cADvC,YAAA,UACA,MAAA,EAAQ,aAAA,CAAc,gBAAA,CAAiB,KAAA;AAAA;;;;cAW9C,0BAAA,SAAmC,WAAA;EAAA,SAE5B,UAAA;EAAA,SACA,MAAA,EAAQ,aAAA,CAAc,gBAAA,CAAiB,KAAA;cADvC,UAAA,UACA,MAAA,EAAQ,aAAA,CAAc,gBAAA,CAAiB,KAAA;AAAA;;;;cAW9C,yBAAA,SAAkC,WAAA;EAAA,SAE3B,SAAA;EAAA,SACA,MAAA,EAAQ,aAAA,CAAc,gBAAA,CAAiB,KAAA;cADvC,SAAA,UACA,MAAA,EAAQ,aAAA,CAAc,gBAAA,CAAiB,KAAA;AAAA;;;;cAW9C,0BAAA,SAAmC,WAAA;EAAA,SAE5B,SAAA;EAAA,SACA,MAAA,EAAQ,aAAA,CAAc,gBAAA,CAAiB,KAAA;cADvC,SAAA,UACA,MAAA,EAAQ,aAAA,CAAc,gBAAA,CAAiB,KAAA;AAAA;AA3HG;;;AAAA,cAsIjD,0BAAA,SAAmC,WAAA;EAAA,SAE5B,UAAA;EAAA,SACA,MAAA,EAAQ,aAAA,CAAc,gBAAA,CAAiB,KAAA;cADvC,UAAA,UACA,MAAA,EAAQ,aAAA,CAAc,gBAAA,CAAiB,KAAA;AAAA;;;AArH3D;cAgIa,2BAAA,SAAoC,WAAA;EAAA,SAE7B,UAAA;EAAA,SACA,MAAA,EAAQ,aAAA,CAAc,gBAAA,CAAiB,KAAA;cADvC,UAAA,UACA,MAAA,EAAQ,aAAA,CAAc,gBAAA,CAAiB,KAAA;AAAA;;;;cAW9C,0BAAA,SAAmC,WAAA;EAAA,SAE5B,YAAA;EAAA,SACA,kBAAA;cADA,YAAA,UACA,kBAAA;AAAA;;;;cAWP,kBAAA,SAA2B,WAAA;cAC1B,OAAA,UAAiB,KAAA;AAAA;;;;;;;;;;cAelB,sBAAA,SAA+B,WAAA;cAC9B,KAAA;AAAA"}
|
|
@@ -132,5 +132,18 @@ declare class ChildWorkflowNotFoundError extends WorkerError {
|
|
|
132
132
|
declare class ChildWorkflowError extends WorkerError {
|
|
133
133
|
constructor(message: string, cause?: unknown);
|
|
134
134
|
}
|
|
135
|
+
/**
|
|
136
|
+
* Error returned in the `Result.Error` branch when a typed cancellation
|
|
137
|
+
* scope is cancelled via Temporal's cancellation propagation. Returned by
|
|
138
|
+
* both `context.cancellableScope` (when the workflow or an ancestor scope
|
|
139
|
+
* cancels) and `context.nonCancellableScope` (when cancellation is raised
|
|
140
|
+
* from inside the scope). Distinct from arbitrary thrown errors so call
|
|
141
|
+
* sites can branch on cancellation explicitly while still surfacing
|
|
142
|
+
* non-cancellation errors as Future rejections.
|
|
143
|
+
*/
|
|
144
|
+
declare class WorkflowCancelledError extends WorkerError {
|
|
145
|
+
constructor(cause?: unknown);
|
|
146
|
+
}
|
|
135
147
|
//#endregion
|
|
136
|
-
export { ChildWorkflowNotFoundError as a, SignalInputValidationError as c,
|
|
148
|
+
export { WorkerInferOutput as _, ChildWorkflowNotFoundError as a, SignalInputValidationError as c, WorkflowCancelledError as d, WorkflowInputValidationError as f, WorkerInferInput as g, ClientInferOutput as h, ChildWorkflowError as i, UpdateInputValidationError as l, ClientInferInput as m, ActivityInputValidationError as n, QueryInputValidationError as o, WorkflowOutputValidationError as p, ActivityOutputValidationError as r, QueryOutputValidationError as s, ActivityDefinitionNotFoundError as t, UpdateOutputValidationError as u };
|
|
149
|
+
//# sourceMappingURL=errors-DZhaNhwr.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors-DZhaNhwr.d.mts","names":[],"sources":["../src/types.ts","../src/errors.ts"],"mappings":";;;;;;AAOA;;KAAY,gBAAA;EAA6B,KAAA,EAAO,SAAA;AAAA,KAAe,gBAAA,CAAiB,WAAA,CAC9E,CAAA;;;;;KAOU,iBAAA;EAA8B,MAAA,EAAQ,SAAA;AAAA,KAAe,gBAAA,CAAiB,UAAA,CAChF,CAAA;;;;;KAOU,gBAAA;EAA6B,KAAA,EAAO,SAAA;AAAA,KAAe,gBAAA,CAAiB,UAAA,CAC9E,CAAA;;;;;KAOU,iBAAA;EAA8B,MAAA,EAAQ,SAAA;AAAA,KAAe,gBAAA,CAAiB,WAAA,CAChF,CAAA;;;;;;uBC1Ba,WAAA,SAAoB,KAAA;EAAA,UACxB,WAAA,CAAa,OAAA,UAAiB,KAAA;AAAA;;;;cAa5B,+BAAA,SAAwC,WAAA;EAAA,SAEjC,YAAA;EAAA,SACA,oBAAA;cADA,YAAA,UACA,oBAAA;AAAA;;;;cAaP,4BAAA,SAAqC,WAAA;EAAA,SAE9B,YAAA;EAAA,SACA,MAAA,EAAQ,aAAA,CAAc,gBAAA,CAAiB,KAAA;cADvC,YAAA,UACA,MAAA,EAAQ,aAAA,CAAc,gBAAA,CAAiB,KAAA;AAAA;;;;cAW9C,6BAAA,SAAsC,WAAA;EAAA,SAE/B,YAAA;EAAA,SACA,MAAA,EAAQ,aAAA,CAAc,gBAAA,CAAiB,KAAA;cADvC,YAAA,UACA,MAAA,EAAQ,aAAA,CAAc,gBAAA,CAAiB,KAAA;AAAA;;;;cAW9C,4BAAA,SAAqC,WAAA;EAAA,SAE9B,YAAA;EAAA,SACA,MAAA,EAAQ,aAAA,CAAc,gBAAA,CAAiB,KAAA;cADvC,YAAA,UACA,MAAA,EAAQ,aAAA,CAAc,gBAAA,CAAiB,KAAA;AAAA;;;;cAW9C,6BAAA,SAAsC,WAAA;EAAA,SAE/B,YAAA;EAAA,SACA,MAAA,EAAQ,aAAA,CAAc,gBAAA,CAAiB,KAAA;cADvC,YAAA,UACA,MAAA,EAAQ,aAAA,CAAc,gBAAA,CAAiB,KAAA;AAAA;;;;cAW9C,0BAAA,SAAmC,WAAA;EAAA,SAE5B,UAAA;EAAA,SACA,MAAA,EAAQ,aAAA,CAAc,gBAAA,CAAiB,KAAA;cADvC,UAAA,UACA,MAAA,EAAQ,aAAA,CAAc,gBAAA,CAAiB,KAAA;AAAA;;;;cAW9C,yBAAA,SAAkC,WAAA;EAAA,SAE3B,SAAA;EAAA,SACA,MAAA,EAAQ,aAAA,CAAc,gBAAA,CAAiB,KAAA;cADvC,SAAA,UACA,MAAA,EAAQ,aAAA,CAAc,gBAAA,CAAiB,KAAA;AAAA;;;;cAW9C,0BAAA,SAAmC,WAAA;EAAA,SAE5B,SAAA;EAAA,SACA,MAAA,EAAQ,aAAA,CAAc,gBAAA,CAAiB,KAAA;cADvC,SAAA,UACA,MAAA,EAAQ,aAAA,CAAc,gBAAA,CAAiB,KAAA;AAAA;AA3HG;;;AAAA,cAsIjD,0BAAA,SAAmC,WAAA;EAAA,SAE5B,UAAA;EAAA,SACA,MAAA,EAAQ,aAAA,CAAc,gBAAA,CAAiB,KAAA;cADvC,UAAA,UACA,MAAA,EAAQ,aAAA,CAAc,gBAAA,CAAiB,KAAA;AAAA;;;AArH3D;cAgIa,2BAAA,SAAoC,WAAA;EAAA,SAE7B,UAAA;EAAA,SACA,MAAA,EAAQ,aAAA,CAAc,gBAAA,CAAiB,KAAA;cADvC,UAAA,UACA,MAAA,EAAQ,aAAA,CAAc,gBAAA,CAAiB,KAAA;AAAA;;;;cAW9C,0BAAA,SAAmC,WAAA;EAAA,SAE5B,YAAA;EAAA,SACA,kBAAA;cADA,YAAA,UACA,kBAAA;AAAA;;;;cAWP,kBAAA,SAA2B,WAAA;cAC1B,OAAA,UAAiB,KAAA;AAAA;;;;;;;;;;cAelB,sBAAA,SAA+B,WAAA;cAC9B,KAAA;AAAA"}
|
|
@@ -0,0 +1,354 @@
|
|
|
1
|
+
import { makeContinueAsNewFunc, proxyActivities } from "@temporalio/workflow";
|
|
2
|
+
//#region src/format.ts
|
|
3
|
+
/**
|
|
4
|
+
* Pattern for string keys safe to render with dot notation. A "safe" key is a
|
|
5
|
+
* JavaScript identifier (letters/digits/underscore/$, not starting with a
|
|
6
|
+
* digit). Anything else — keys containing dots, spaces, leading digits, the
|
|
7
|
+
* empty string, the literal string `"0"` etc. — gets bracket-quoted so the
|
|
8
|
+
* path is unambiguous. Reserved words are accepted: we are formatting a
|
|
9
|
+
* diagnostic, not generating runnable code.
|
|
10
|
+
*/
|
|
11
|
+
const SAFE_IDENTIFIER = /^[A-Za-z_$][A-Za-z0-9_$]*$/;
|
|
12
|
+
/**
|
|
13
|
+
* Render a Standard Schema {@link StandardSchemaV1.Issue} into a human-readable
|
|
14
|
+
* string that includes the failing field's path.
|
|
15
|
+
*/
|
|
16
|
+
function formatIssue(issue) {
|
|
17
|
+
if (issue.path === void 0 || issue.path.length === 0) return issue.message;
|
|
18
|
+
let path = "";
|
|
19
|
+
for (let i = 0; i < issue.path.length; i++) {
|
|
20
|
+
const segment = issue.path[i];
|
|
21
|
+
const key = segment !== null && typeof segment === "object" && "key" in segment ? segment.key : segment;
|
|
22
|
+
if (typeof key === "number") path += `[${key}]`;
|
|
23
|
+
else if (typeof key === "string" && SAFE_IDENTIFIER.test(key)) path += i === 0 ? key : `.${key}`;
|
|
24
|
+
else if (typeof key === "string") path += `[${JSON.stringify(key)}]`;
|
|
25
|
+
else path += `[${String(key)}]`;
|
|
26
|
+
}
|
|
27
|
+
return `at ${path}: ${issue.message}`;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Join a list of validation issues into a single message, with each issue
|
|
31
|
+
* rendered via {@link formatIssue} so field paths surface in the error text.
|
|
32
|
+
*/
|
|
33
|
+
function summarizeIssues(issues) {
|
|
34
|
+
return issues.map(formatIssue).join("; ");
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Build the message attached to a `ChildWorkflowError` for input/output
|
|
38
|
+
* validation failures. Centralized so the worker and any future call sites
|
|
39
|
+
* format identically.
|
|
40
|
+
*/
|
|
41
|
+
function formatChildWorkflowValidationMessage(workflowName, direction, issues) {
|
|
42
|
+
return `Child workflow "${workflowName}" ${direction} validation failed: ${summarizeIssues(issues)}`;
|
|
43
|
+
}
|
|
44
|
+
//#endregion
|
|
45
|
+
//#region src/errors.ts
|
|
46
|
+
/**
|
|
47
|
+
* Base error class for worker errors
|
|
48
|
+
*/
|
|
49
|
+
var WorkerError = class extends Error {
|
|
50
|
+
constructor(message, cause) {
|
|
51
|
+
super(message, { cause });
|
|
52
|
+
this.name = "WorkerError";
|
|
53
|
+
if (Error.captureStackTrace) Error.captureStackTrace(this, this.constructor);
|
|
54
|
+
}
|
|
55
|
+
};
|
|
56
|
+
/**
|
|
57
|
+
* Error thrown when an activity definition is not found in the contract
|
|
58
|
+
*/
|
|
59
|
+
var ActivityDefinitionNotFoundError = class extends WorkerError {
|
|
60
|
+
constructor(activityName, availableDefinitions = []) {
|
|
61
|
+
const available = availableDefinitions.length > 0 ? availableDefinitions.join(", ") : "none";
|
|
62
|
+
super(`Activity definition not found for: "${activityName}". Available activities: ${available}`);
|
|
63
|
+
this.activityName = activityName;
|
|
64
|
+
this.availableDefinitions = availableDefinitions;
|
|
65
|
+
this.name = "ActivityDefinitionNotFoundError";
|
|
66
|
+
}
|
|
67
|
+
};
|
|
68
|
+
/**
|
|
69
|
+
* Error thrown when activity input validation fails
|
|
70
|
+
*/
|
|
71
|
+
var ActivityInputValidationError = class extends WorkerError {
|
|
72
|
+
constructor(activityName, issues) {
|
|
73
|
+
const message = summarizeIssues(issues);
|
|
74
|
+
super(`Activity "${activityName}" input validation failed: ${message}`);
|
|
75
|
+
this.activityName = activityName;
|
|
76
|
+
this.issues = issues;
|
|
77
|
+
this.name = "ActivityInputValidationError";
|
|
78
|
+
}
|
|
79
|
+
};
|
|
80
|
+
/**
|
|
81
|
+
* Error thrown when activity output validation fails
|
|
82
|
+
*/
|
|
83
|
+
var ActivityOutputValidationError = class extends WorkerError {
|
|
84
|
+
constructor(activityName, issues) {
|
|
85
|
+
const message = summarizeIssues(issues);
|
|
86
|
+
super(`Activity "${activityName}" output validation failed: ${message}`);
|
|
87
|
+
this.activityName = activityName;
|
|
88
|
+
this.issues = issues;
|
|
89
|
+
this.name = "ActivityOutputValidationError";
|
|
90
|
+
}
|
|
91
|
+
};
|
|
92
|
+
/**
|
|
93
|
+
* Error thrown when workflow input validation fails
|
|
94
|
+
*/
|
|
95
|
+
var WorkflowInputValidationError = class extends WorkerError {
|
|
96
|
+
constructor(workflowName, issues) {
|
|
97
|
+
const message = summarizeIssues(issues);
|
|
98
|
+
super(`Workflow "${workflowName}" input validation failed: ${message}`);
|
|
99
|
+
this.workflowName = workflowName;
|
|
100
|
+
this.issues = issues;
|
|
101
|
+
this.name = "WorkflowInputValidationError";
|
|
102
|
+
}
|
|
103
|
+
};
|
|
104
|
+
/**
|
|
105
|
+
* Error thrown when workflow output validation fails
|
|
106
|
+
*/
|
|
107
|
+
var WorkflowOutputValidationError = class extends WorkerError {
|
|
108
|
+
constructor(workflowName, issues) {
|
|
109
|
+
const message = summarizeIssues(issues);
|
|
110
|
+
super(`Workflow "${workflowName}" output validation failed: ${message}`);
|
|
111
|
+
this.workflowName = workflowName;
|
|
112
|
+
this.issues = issues;
|
|
113
|
+
this.name = "WorkflowOutputValidationError";
|
|
114
|
+
}
|
|
115
|
+
};
|
|
116
|
+
/**
|
|
117
|
+
* Error thrown when signal input validation fails
|
|
118
|
+
*/
|
|
119
|
+
var SignalInputValidationError = class extends WorkerError {
|
|
120
|
+
constructor(signalName, issues) {
|
|
121
|
+
const message = summarizeIssues(issues);
|
|
122
|
+
super(`Signal "${signalName}" input validation failed: ${message}`);
|
|
123
|
+
this.signalName = signalName;
|
|
124
|
+
this.issues = issues;
|
|
125
|
+
this.name = "SignalInputValidationError";
|
|
126
|
+
}
|
|
127
|
+
};
|
|
128
|
+
/**
|
|
129
|
+
* Error thrown when query input validation fails
|
|
130
|
+
*/
|
|
131
|
+
var QueryInputValidationError = class extends WorkerError {
|
|
132
|
+
constructor(queryName, issues) {
|
|
133
|
+
const message = summarizeIssues(issues);
|
|
134
|
+
super(`Query "${queryName}" input validation failed: ${message}`);
|
|
135
|
+
this.queryName = queryName;
|
|
136
|
+
this.issues = issues;
|
|
137
|
+
this.name = "QueryInputValidationError";
|
|
138
|
+
}
|
|
139
|
+
};
|
|
140
|
+
/**
|
|
141
|
+
* Error thrown when query output validation fails
|
|
142
|
+
*/
|
|
143
|
+
var QueryOutputValidationError = class extends WorkerError {
|
|
144
|
+
constructor(queryName, issues) {
|
|
145
|
+
const message = summarizeIssues(issues);
|
|
146
|
+
super(`Query "${queryName}" output validation failed: ${message}`);
|
|
147
|
+
this.queryName = queryName;
|
|
148
|
+
this.issues = issues;
|
|
149
|
+
this.name = "QueryOutputValidationError";
|
|
150
|
+
}
|
|
151
|
+
};
|
|
152
|
+
/**
|
|
153
|
+
* Error thrown when update input validation fails
|
|
154
|
+
*/
|
|
155
|
+
var UpdateInputValidationError = class extends WorkerError {
|
|
156
|
+
constructor(updateName, issues) {
|
|
157
|
+
const message = summarizeIssues(issues);
|
|
158
|
+
super(`Update "${updateName}" input validation failed: ${message}`);
|
|
159
|
+
this.updateName = updateName;
|
|
160
|
+
this.issues = issues;
|
|
161
|
+
this.name = "UpdateInputValidationError";
|
|
162
|
+
}
|
|
163
|
+
};
|
|
164
|
+
/**
|
|
165
|
+
* Error thrown when update output validation fails
|
|
166
|
+
*/
|
|
167
|
+
var UpdateOutputValidationError = class extends WorkerError {
|
|
168
|
+
constructor(updateName, issues) {
|
|
169
|
+
const message = summarizeIssues(issues);
|
|
170
|
+
super(`Update "${updateName}" output validation failed: ${message}`);
|
|
171
|
+
this.updateName = updateName;
|
|
172
|
+
this.issues = issues;
|
|
173
|
+
this.name = "UpdateOutputValidationError";
|
|
174
|
+
}
|
|
175
|
+
};
|
|
176
|
+
/**
|
|
177
|
+
* Error thrown when a child workflow is not found in the contract
|
|
178
|
+
*/
|
|
179
|
+
var ChildWorkflowNotFoundError = class extends WorkerError {
|
|
180
|
+
constructor(workflowName, availableWorkflows = []) {
|
|
181
|
+
const available = availableWorkflows.length > 0 ? availableWorkflows.join(", ") : "none";
|
|
182
|
+
super(`Child workflow not found: "${workflowName}". Available workflows: ${available}`);
|
|
183
|
+
this.workflowName = workflowName;
|
|
184
|
+
this.availableWorkflows = availableWorkflows;
|
|
185
|
+
this.name = "ChildWorkflowNotFoundError";
|
|
186
|
+
}
|
|
187
|
+
};
|
|
188
|
+
/**
|
|
189
|
+
* Generic error for child workflow operations
|
|
190
|
+
*/
|
|
191
|
+
var ChildWorkflowError = class extends WorkerError {
|
|
192
|
+
constructor(message, cause) {
|
|
193
|
+
super(message, cause);
|
|
194
|
+
this.name = "ChildWorkflowError";
|
|
195
|
+
}
|
|
196
|
+
};
|
|
197
|
+
/**
|
|
198
|
+
* Error returned in the `Result.Error` branch when a typed cancellation
|
|
199
|
+
* scope is cancelled via Temporal's cancellation propagation. Returned by
|
|
200
|
+
* both `context.cancellableScope` (when the workflow or an ancestor scope
|
|
201
|
+
* cancels) and `context.nonCancellableScope` (when cancellation is raised
|
|
202
|
+
* from inside the scope). Distinct from arbitrary thrown errors so call
|
|
203
|
+
* sites can branch on cancellation explicitly while still surfacing
|
|
204
|
+
* non-cancellation errors as Future rejections.
|
|
205
|
+
*/
|
|
206
|
+
var WorkflowCancelledError = class extends WorkerError {
|
|
207
|
+
constructor(cause) {
|
|
208
|
+
super("Workflow cancellation scope was cancelled", cause);
|
|
209
|
+
this.name = "WorkflowCancelledError";
|
|
210
|
+
}
|
|
211
|
+
};
|
|
212
|
+
//#endregion
|
|
213
|
+
//#region src/internal.ts
|
|
214
|
+
/**
|
|
215
|
+
* Internal helpers shared across the worker package's entry points.
|
|
216
|
+
*
|
|
217
|
+
* Not part of the public API — this module is not listed in the package's
|
|
218
|
+
* `exports` map, so consumers can't import from `@temporal-contract/worker/internal`.
|
|
219
|
+
* In-package tests import it directly via relative path.
|
|
220
|
+
*/
|
|
221
|
+
/**
|
|
222
|
+
* Extract the single payload from a Temporal handler's `...args` array.
|
|
223
|
+
*
|
|
224
|
+
* Temporal invokes handlers with whatever was passed via `args: [...]` at the
|
|
225
|
+
* call site. The typed-contract layer always sends `args: [validatedInput]`,
|
|
226
|
+
* so the common case is a one-element array containing the wrapped input.
|
|
227
|
+
*
|
|
228
|
+
* If a non-typed-contract caller passes multiple positional arguments
|
|
229
|
+
* (`args: [a, b, c]`), we surface the whole array as the input — the schema
|
|
230
|
+
* will then reject it unless the contract specifically modeled a tuple.
|
|
231
|
+
*/
|
|
232
|
+
function extractHandlerInput(args) {
|
|
233
|
+
return args.length === 1 ? args[0] : args;
|
|
234
|
+
}
|
|
235
|
+
/**
|
|
236
|
+
* Build the raw `Record<name, fn>` proxy of activities for a workflow,
|
|
237
|
+
* applying per-activity `ActivityOptions` overrides where requested.
|
|
238
|
+
*
|
|
239
|
+
* **Fast path (no overrides):** a single `proxyActivities(defaultOptions)`
|
|
240
|
+
* call is made and returned directly. The proxy synthesizes a function for
|
|
241
|
+
* any property access by name, so downstream code that looks up
|
|
242
|
+
* `proxy[activityName]` works identically to before.
|
|
243
|
+
*
|
|
244
|
+
* **Override path:** one extra `proxyActivities(merged)` call is made *only*
|
|
245
|
+
* for each activity that has an override. Activities without an entry keep
|
|
246
|
+
* using the single default proxy. The result is a `Proxy` that returns the
|
|
247
|
+
* override-bound function for named keys and falls back to the default proxy
|
|
248
|
+
* for everything else — so the per-execution overhead scales with the number
|
|
249
|
+
* of overrides, not the number of activities.
|
|
250
|
+
*
|
|
251
|
+
* Per-override merge is shallow: the override's properties replace the
|
|
252
|
+
* default's, including the entire nested `retry` block. This matches
|
|
253
|
+
* Temporal's "one ActivityOptions per `proxyActivities` call" semantics.
|
|
254
|
+
*/
|
|
255
|
+
function buildRawActivitiesProxy(workflowActivities, contractActivities, defaultOptions, overrides) {
|
|
256
|
+
const defaultProxy = proxyActivities(defaultOptions);
|
|
257
|
+
const overrideEntries = overrides ? Object.entries(overrides).filter((entry) => entry[1] !== void 0) : [];
|
|
258
|
+
if (overrideEntries.length === 0) return defaultProxy;
|
|
259
|
+
const declared = new Set([...Object.keys(workflowActivities ?? {}), ...Object.keys(contractActivities ?? {})]);
|
|
260
|
+
for (const [name] of overrideEntries) if (!declared.has(name)) throw new Error(`activityOptionsByName entry "${name}" does not match any declared activity. Available: ${[...declared].join(", ") || "none"}.`);
|
|
261
|
+
const overriddenFns = {};
|
|
262
|
+
for (const [name, override] of overrideEntries) {
|
|
263
|
+
const fn = proxyActivities({
|
|
264
|
+
...defaultOptions,
|
|
265
|
+
...override
|
|
266
|
+
})[name];
|
|
267
|
+
if (fn !== void 0) overriddenFns[name] = fn;
|
|
268
|
+
}
|
|
269
|
+
return new Proxy(overriddenFns, { get(target, prop) {
|
|
270
|
+
if (typeof prop !== "string") return void 0;
|
|
271
|
+
return target[prop] ?? defaultProxy[prop];
|
|
272
|
+
} });
|
|
273
|
+
}
|
|
274
|
+
/**
|
|
275
|
+
* Build the typed `continueAsNew` function bound to the running workflow's
|
|
276
|
+
* contract. Two overloads — same-workflow and cross-contract — share one
|
|
277
|
+
* implementation; the public type signature lives on `WorkflowContext` so
|
|
278
|
+
* call sites are type-safe.
|
|
279
|
+
*
|
|
280
|
+
* Validation runs *before* Temporal's `makeContinueAsNewFunc(...)` is invoked.
|
|
281
|
+
* On failure, throws a `WorkflowInputValidationError` (matching the behaviour
|
|
282
|
+
* of `declareWorkflow`'s incoming-input validation), which surfaces back to
|
|
283
|
+
* Temporal as a workflow failure rather than silently proceeding with an
|
|
284
|
+
* invalid run.
|
|
285
|
+
*
|
|
286
|
+
* Temporal's `continueAsNew` never returns — it throws a `ContinueAsNew`
|
|
287
|
+
* exception that the runtime intercepts. The returned function preserves
|
|
288
|
+
* `Promise<never>` to encode that.
|
|
289
|
+
*
|
|
290
|
+
* @internal
|
|
291
|
+
*/
|
|
292
|
+
function createContinueAsNew(currentContract, currentWorkflowName) {
|
|
293
|
+
return async function continueAsNew(arg1, arg2, arg3, arg4) {
|
|
294
|
+
const isCrossContract = looksLikeCrossContractCall(arg1, arg2);
|
|
295
|
+
let targetContract;
|
|
296
|
+
let targetName;
|
|
297
|
+
let rawArgs;
|
|
298
|
+
let options;
|
|
299
|
+
if (isCrossContract) {
|
|
300
|
+
targetContract = arg1;
|
|
301
|
+
targetName = arg2;
|
|
302
|
+
rawArgs = arg3;
|
|
303
|
+
options = arg4;
|
|
304
|
+
} else {
|
|
305
|
+
targetContract = currentContract;
|
|
306
|
+
targetName = String(currentWorkflowName);
|
|
307
|
+
rawArgs = arg1;
|
|
308
|
+
options = arg2;
|
|
309
|
+
}
|
|
310
|
+
const targetDef = targetContract.workflows[targetName];
|
|
311
|
+
if (!targetDef) throw new WorkflowInputValidationError(targetName, [{ message: `continueAsNew target workflow "${targetName}" is not declared on the supplied contract.` }]);
|
|
312
|
+
const inputResult = await targetDef.input["~standard"].validate(rawArgs);
|
|
313
|
+
if (inputResult.issues) throw new WorkflowInputValidationError(targetName, inputResult.issues);
|
|
314
|
+
await makeContinueAsNewFunc({
|
|
315
|
+
workflowType: targetName,
|
|
316
|
+
taskQueue: targetContract.taskQueue,
|
|
317
|
+
...options
|
|
318
|
+
})(inputResult.value);
|
|
319
|
+
};
|
|
320
|
+
}
|
|
321
|
+
/**
|
|
322
|
+
* Structural check: does `(arg1, arg2)` look like the
|
|
323
|
+
* `(contract, workflowName, ...)` cross-contract overload of `continueAsNew`?
|
|
324
|
+
*
|
|
325
|
+
* Returns `true` only when:
|
|
326
|
+
* 1. `arg1` is a non-null object with a string `taskQueue` and a non-null
|
|
327
|
+
* object `workflows` (handles `workflows: null`, where
|
|
328
|
+
* `typeof null === "object"`).
|
|
329
|
+
* 2. `arg2` is a string.
|
|
330
|
+
*
|
|
331
|
+
* Both halves matter. A same-workflow input that happens to contain
|
|
332
|
+
* `taskQueue` and `workflows` keys would otherwise be misclassified — but
|
|
333
|
+
* none of the same-workflow signatures (`continueAsNew(args)`,
|
|
334
|
+
* `continueAsNew(args, options)`) accept a string as `arg2`, so the
|
|
335
|
+
* second check makes the false-positive surface vanishingly small.
|
|
336
|
+
*
|
|
337
|
+
* We deliberately do *not* check that `arg1.workflows[arg2]` is a valid
|
|
338
|
+
* workflow definition. If it isn't, the dispatcher falls through to the
|
|
339
|
+
* `targetContract.workflows[targetName]` lookup which throws a clear
|
|
340
|
+
* "target workflow X is not declared" error — better than silently
|
|
341
|
+
* misrouting a typo back to the current workflow.
|
|
342
|
+
*/
|
|
343
|
+
function looksLikeCrossContractCall(arg1, arg2) {
|
|
344
|
+
if (typeof arg1 !== "object" || arg1 === null) return false;
|
|
345
|
+
if (typeof arg2 !== "string") return false;
|
|
346
|
+
const candidate = arg1;
|
|
347
|
+
if (typeof candidate["taskQueue"] !== "string") return false;
|
|
348
|
+
const workflows = candidate["workflows"];
|
|
349
|
+
return typeof workflows === "object" && workflows !== null;
|
|
350
|
+
}
|
|
351
|
+
//#endregion
|
|
352
|
+
export { formatChildWorkflowValidationMessage as _, ActivityInputValidationError as a, ChildWorkflowNotFoundError as c, SignalInputValidationError as d, UpdateInputValidationError as f, WorkflowOutputValidationError as g, WorkflowInputValidationError as h, ActivityDefinitionNotFoundError as i, QueryInputValidationError as l, WorkflowCancelledError as m, createContinueAsNew as n, ActivityOutputValidationError as o, UpdateOutputValidationError as p, extractHandlerInput as r, ChildWorkflowError as s, buildRawActivitiesProxy as t, QueryOutputValidationError as u };
|
|
353
|
+
|
|
354
|
+
//# sourceMappingURL=internal-BoNcEtYh.mjs.map
|