@temporal-contract/worker 2.3.1 → 2.4.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 CHANGED
@@ -117,6 +117,45 @@ export const parentWorkflow = declareWorkflow({
117
117
  });
118
118
  ```
119
119
 
120
+ ### Per-activity options
121
+
122
+ `activityOptions` sets defaults for every activity reachable from the workflow.
123
+ To override options for individual activities, add `activityOptionsByName`. Each
124
+ entry shallow-merges over the defaults — the override wins on every property it
125
+ sets, including the whole nested `retry` block.
126
+
127
+ The override value is Temporal's full `ActivityOptions`, so `taskQueue` is
128
+ available too. That lets you route specific activities to dedicated worker pools
129
+ (e.g. a concurrency-capped queue for LLM calls) while the rest of the workflow
130
+ stays on the default queue — without dropping to a raw `proxyActivities` call,
131
+ which would bypass the Zod input/output validation:
132
+
133
+ ```typescript
134
+ export const extractLayout = declareWorkflow({
135
+ workflowName: "extractLayout",
136
+ contract: myContract,
137
+ activityOptions: { startToCloseTimeout: "10 minutes" }, // default for all
138
+ activityOptionsByName: {
139
+ // LLM activity → dedicated, concurrency-capped queue.
140
+ extractLayoutChunk: { taskQueue: "gemini-pro" },
141
+ // Slow payment gateway → longer timeout + aggressive retry.
142
+ chargePayment: {
143
+ startToCloseTimeout: "5 minutes",
144
+ retry: { maximumAttempts: 5 },
145
+ },
146
+ // Activities not listed here fall through to the default queue/options.
147
+ },
148
+ implementation: async ({ activities }, input) => {
149
+ // Each call still validates input/output against the contract.
150
+ const layout = await activities.extractLayoutChunk({ docId: input.docId });
151
+ return { layout };
152
+ },
153
+ });
154
+ ```
155
+
156
+ Activity names are typed against the contract (workflow-local + global), so
157
+ typos surface as TypeScript errors rather than silently running with defaults.
158
+
120
159
  ## Documentation
121
160
 
122
161
  📖 **[Read the full documentation →](https://btravers.github.io/temporal-contract)**
package/dist/activity.cjs CHANGED
@@ -1,5 +1,5 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
- const require_internal = require("./internal-DcM-YWYX.cjs");
2
+ const require_internal = require("./internal-o5vk6e1H.cjs");
3
3
  let _temporalio_common = require("@temporalio/common");
4
4
  //#region src/activity.ts
5
5
  /**
@@ -108,4 +108,5 @@ Object.defineProperty(exports, "ApplicationFailure", {
108
108
  return _temporalio_common.ApplicationFailure;
109
109
  }
110
110
  });
111
+ exports.ValidationError = require_internal.ValidationError;
111
112
  exports.declareActivitiesHandler = declareActivitiesHandler;
@@ -1,4 +1,4 @@
1
- import { n as ActivityInputValidationError, r as ActivityOutputValidationError, t as ActivityDefinitionNotFoundError, v as WorkerInferInput, y as WorkerInferOutput } from "./errors-BP48RaOI.cjs";
1
+ import { b as WorkerInferOutput, f as ValidationError, n as ActivityInputValidationError, r as ActivityOutputValidationError, t as ActivityDefinitionNotFoundError, y as WorkerInferInput } from "./errors-CE56feY1.cjs";
2
2
  import { ActivityDefinition, ContractDefinition } from "@temporal-contract/contract";
3
3
  import { ResultAsync } from "neverthrow";
4
4
  import { ApplicationFailure, ApplicationFailure as ApplicationFailure$1 } from "@temporalio/common";
@@ -122,5 +122,5 @@ type ActivitiesHandler<TContract extends ContractDefinition> = (TContract["activ
122
122
  */
123
123
  declare function declareActivitiesHandler<TContract extends ContractDefinition>(options: DeclareActivitiesHandlerOptions<TContract>): ActivitiesHandler<TContract>;
124
124
  //#endregion
125
- export { ActivitiesHandler, ActivityDefinitionNotFoundError, ActivityInputValidationError, ActivityOutputValidationError, ApplicationFailure, declareActivitiesHandler };
125
+ export { ActivitiesHandler, ActivityDefinitionNotFoundError, ActivityInputValidationError, ActivityOutputValidationError, ApplicationFailure, ValidationError, declareActivitiesHandler };
126
126
  //# sourceMappingURL=activity.d.cts.map
@@ -1 +1 @@
1
- {"version":3,"file":"activity.d.cts","names":[],"sources":["../src/activity.ts"],"mappings":";;;;;;AA+BwD;;;;;;;;;AAAA,KAWnD,4BAAA,mBAA+C,kBAAA,KAClD,IAAA,EAAM,gBAAA,CAAiB,SAAA,MACpB,WAAA,CAAY,iBAAA,CAAkB,SAAA,GAAY,oBAAA;;;;;;;;;;;;;AAAkB;AAAA;;;;;;;;;;KAyB5D,uCAAA,mBAA0D,kBAAA,KAE5D,SAAA,uBAAgC,MAAA,SAAe,kBAAA,IAC5C,+BAAA,CAAgC,SAAA,8CAIZ,SAAA,gBAAyB,SAAA,cAAuB,SAAA,wBAAiC,MAAA,SAEnG,kBAAA,IAEE,+BAAA,CAAgC,SAAA,cAAuB,SAAA;AAAA,KAI5D,+BAAA,qBAAoD,MAAA,SAAe,kBAAA,mBAC1D,WAAA,GAAc,4BAAA,CAA6B,WAAA,CAAY,CAAA;;;;KAMhE,+BAAA,mBAAkD,kBAAA;EACrD,QAAA,EAAU,SAAA;EACV,UAAA,EAAY,uCAAA,CAAwC,SAAA;AAAA;AAAA,KAGjD,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,CAAC,6BACtD,CAAA,sBAEE,CAAA;;;;;;;;;KAWQ,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;;;;;;;;;;;;;;;;;;;AA/CwD;AAAA;;;;;;;;;;;;;;;;;AAQP;AAAA;;;;;;;;;;;;;;;;;;;;AAKvB;AAAA;;;;iBAmGxB,wBAAA,mBAA2C,kBAAA,EACzD,OAAA,EAAS,+BAAA,CAAgC,SAAA,IACxC,iBAAA,CAAkB,SAAA"}
1
+ {"version":3,"file":"activity.d.cts","names":[],"sources":["../src/activity.ts"],"mappings":";;;;;;AAgCwD;;;;;;;;;AAAA,KAWnD,4BAAA,mBAA+C,kBAAA,KAClD,IAAA,EAAM,gBAAA,CAAiB,SAAA,MACpB,WAAA,CAAY,iBAAA,CAAkB,SAAA,GAAY,oBAAA;;;;;;;;;;;;;AAAkB;AAAA;;;;;;;;;;KAyB5D,uCAAA,mBAA0D,kBAAA,KAE5D,SAAA,uBAAgC,MAAA,SAAe,kBAAA,IAC5C,+BAAA,CAAgC,SAAA,8CAIZ,SAAA,gBAAyB,SAAA,cAAuB,SAAA,wBAAiC,MAAA,SAEnG,kBAAA,IAEE,+BAAA,CAAgC,SAAA,cAAuB,SAAA;AAAA,KAI5D,+BAAA,qBAAoD,MAAA,SAAe,kBAAA,mBAC1D,WAAA,GAAc,4BAAA,CAA6B,WAAA,CAAY,CAAA;;;;KAMhE,+BAAA,mBAAkD,kBAAA;EACrD,QAAA,EAAU,SAAA;EACV,UAAA,EAAY,uCAAA,CAAwC,SAAA;AAAA;AAAA,KAGjD,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,CAAC,6BACtD,CAAA,sBAEE,CAAA;;;;;;;;;KAWQ,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;;;;;;;;;;;;;;;;;;;AA/CwD;AAAA;;;;;;;;;;;;;;;;;AAQP;AAAA;;;;;;;;;;;;;;;;;;;;AAKvB;AAAA;;;;iBAmGxB,wBAAA,mBAA2C,kBAAA,EACzD,OAAA,EAAS,+BAAA,CAAgC,SAAA,IACxC,iBAAA,CAAkB,SAAA"}
@@ -1,4 +1,4 @@
1
- import { n as ActivityInputValidationError, r as ActivityOutputValidationError, t as ActivityDefinitionNotFoundError, v as WorkerInferInput, y as WorkerInferOutput } from "./errors-BP48RaOI.mjs";
1
+ import { b as WorkerInferOutput, f as ValidationError, n as ActivityInputValidationError, r as ActivityOutputValidationError, t as ActivityDefinitionNotFoundError, y as WorkerInferInput } from "./errors-CE56feY1.mjs";
2
2
  import { ActivityDefinition, ContractDefinition } from "@temporal-contract/contract";
3
3
  import { ApplicationFailure, ApplicationFailure as ApplicationFailure$1 } from "@temporalio/common";
4
4
  import { ResultAsync } from "neverthrow";
@@ -122,5 +122,5 @@ type ActivitiesHandler<TContract extends ContractDefinition> = (TContract["activ
122
122
  */
123
123
  declare function declareActivitiesHandler<TContract extends ContractDefinition>(options: DeclareActivitiesHandlerOptions<TContract>): ActivitiesHandler<TContract>;
124
124
  //#endregion
125
- export { ActivitiesHandler, ActivityDefinitionNotFoundError, ActivityInputValidationError, ActivityOutputValidationError, ApplicationFailure, declareActivitiesHandler };
125
+ export { ActivitiesHandler, ActivityDefinitionNotFoundError, ActivityInputValidationError, ActivityOutputValidationError, ApplicationFailure, ValidationError, declareActivitiesHandler };
126
126
  //# sourceMappingURL=activity.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"activity.d.mts","names":[],"sources":["../src/activity.ts"],"mappings":";;;;;;AA+BwD;;;;;;;;;AAAA,KAWnD,4BAAA,mBAA+C,kBAAA,KAClD,IAAA,EAAM,gBAAA,CAAiB,SAAA,MACpB,WAAA,CAAY,iBAAA,CAAkB,SAAA,GAAY,oBAAA;;;;;;;;;;;;;AAAkB;AAAA;;;;;;;;;;KAyB5D,uCAAA,mBAA0D,kBAAA,KAE5D,SAAA,uBAAgC,MAAA,SAAe,kBAAA,IAC5C,+BAAA,CAAgC,SAAA,8CAIZ,SAAA,gBAAyB,SAAA,cAAuB,SAAA,wBAAiC,MAAA,SAEnG,kBAAA,IAEE,+BAAA,CAAgC,SAAA,cAAuB,SAAA;AAAA,KAI5D,+BAAA,qBAAoD,MAAA,SAAe,kBAAA,mBAC1D,WAAA,GAAc,4BAAA,CAA6B,WAAA,CAAY,CAAA;;;;KAMhE,+BAAA,mBAAkD,kBAAA;EACrD,QAAA,EAAU,SAAA;EACV,UAAA,EAAY,uCAAA,CAAwC,SAAA;AAAA;AAAA,KAGjD,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,CAAC,6BACtD,CAAA,sBAEE,CAAA;;;;;;;;;KAWQ,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;;;;;;;;;;;;;;;;;;;AA/CwD;AAAA;;;;;;;;;;;;;;;;;AAQP;AAAA;;;;;;;;;;;;;;;;;;;;AAKvB;AAAA;;;;iBAmGxB,wBAAA,mBAA2C,kBAAA,EACzD,OAAA,EAAS,+BAAA,CAAgC,SAAA,IACxC,iBAAA,CAAkB,SAAA"}
1
+ {"version":3,"file":"activity.d.mts","names":[],"sources":["../src/activity.ts"],"mappings":";;;;;;AAgCwD;;;;;;;;;AAAA,KAWnD,4BAAA,mBAA+C,kBAAA,KAClD,IAAA,EAAM,gBAAA,CAAiB,SAAA,MACpB,WAAA,CAAY,iBAAA,CAAkB,SAAA,GAAY,oBAAA;;;;;;;;;;;;;AAAkB;AAAA;;;;;;;;;;KAyB5D,uCAAA,mBAA0D,kBAAA,KAE5D,SAAA,uBAAgC,MAAA,SAAe,kBAAA,IAC5C,+BAAA,CAAgC,SAAA,8CAIZ,SAAA,gBAAyB,SAAA,cAAuB,SAAA,wBAAiC,MAAA,SAEnG,kBAAA,IAEE,+BAAA,CAAgC,SAAA,cAAuB,SAAA;AAAA,KAI5D,+BAAA,qBAAoD,MAAA,SAAe,kBAAA,mBAC1D,WAAA,GAAc,4BAAA,CAA6B,WAAA,CAAY,CAAA;;;;KAMhE,+BAAA,mBAAkD,kBAAA;EACrD,QAAA,EAAU,SAAA;EACV,UAAA,EAAY,uCAAA,CAAwC,SAAA;AAAA;AAAA,KAGjD,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,CAAC,6BACtD,CAAA,sBAEE,CAAA;;;;;;;;;KAWQ,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;;;;;;;;;;;;;;;;;;;AA/CwD;AAAA;;;;;;;;;;;;;;;;;AAQP;AAAA;;;;;;;;;;;;;;;;;;;;AAKvB;AAAA;;;;iBAmGxB,wBAAA,mBAA2C,kBAAA,EACzD,OAAA,EAAS,+BAAA,CAAgC,SAAA,IACxC,iBAAA,CAAkB,SAAA"}
package/dist/activity.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import { c as ActivityInputValidationError, i as extractHandlerInput, l as ActivityOutputValidationError, s as ActivityDefinitionNotFoundError } from "./internal-D8Dl9D43.mjs";
1
+ import { c as ActivityInputValidationError, i as extractHandlerInput, l as ActivityOutputValidationError, s as ActivityDefinitionNotFoundError, v as ValidationError } from "./internal-D0wfFl0y.mjs";
2
2
  import { ApplicationFailure } from "@temporalio/common";
3
3
  //#region src/activity.ts
4
4
  /**
@@ -98,6 +98,6 @@ function declareActivitiesHandler(options) {
98
98
  return wrappedActivities;
99
99
  }
100
100
  //#endregion
101
- export { ActivityDefinitionNotFoundError, ActivityInputValidationError, ActivityOutputValidationError, ApplicationFailure, declareActivitiesHandler };
101
+ export { ActivityDefinitionNotFoundError, ActivityInputValidationError, ActivityOutputValidationError, ApplicationFailure, ValidationError, declareActivitiesHandler };
102
102
 
103
103
  //# sourceMappingURL=activity.mjs.map
@@ -1 +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 use neverthrow's\n// `ResultAsync` directly. Workflow code (see workflow.ts) uses the same\n// neverthrow API — neverthrow's evaluation is compatible with Temporal's\n// 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 type { ResultAsync } from \"neverthrow\";\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 neverthrow's `ResultAsync`.\n *\n * Returns `ResultAsync<Output, ApplicationFailure>` for explicit error\n * handling instead of throwing. The wrapper rethrows `err()` payloads at\n * the activity boundary; Temporal recognizes `ApplicationFailure` natively\n * and applies the configured retry policy (with `nonRetryable: true`\n * opting an instance out per-call).\n */\ntype ResultActivityImplementation<TActivity extends ActivityDefinition> = (\n args: WorkerInferInput<TActivity>,\n) => ResultAsync<WorkerInferOutput<TActivity>, ApplicationFailure>;\n\n/**\n * Map of all activity implementations for a contract (global + all workflow-specific).\n *\n * **Shape note — input is nested by workflow, output is flat.** This\n * asymmetry is deliberate:\n *\n * - The implementation map you write **mirrors the contract's structure**:\n * global activities sit at the root, workflow-local activities nest\n * under their owning workflow's name. Mirroring the contract gives\n * IDE autocomplete that matches `defineContract`, prevents typos that\n * put a workflow-local activity at the global level, and makes\n * ownership visible at definition time.\n * - The handler returned by {@link declareActivitiesHandler} (see\n * {@link ActivitiesHandler}) is **flat** because Temporal's worker\n * sees a single activity namespace at runtime —\n * `proxyActivities<...>()` resolves names from one map regardless of\n * which workflow consumes them. `defineContract` enforces no name\n * collisions across global + workflow-local scopes, so the flat\n * output has no ambiguity to resolve.\n *\n * In short: write nested (mirror the contract); the wrapper flattens\n * for Temporal.\n */\ntype ContractResultActivitiesImplementations<TContract extends ContractDefinition> =\n // Global activities\n (TContract[\"activities\"] extends Record<string, ActivityDefinition>\n ? ResultActivitiesImplementations<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 ? ResultActivitiesImplementations<TContract[\"workflows\"][TWorkflow][\"activities\"]>\n : {};\n };\n\ntype ResultActivitiesImplementations<TActivities extends Record<string, ActivityDefinition>> = {\n [K in keyof TActivities]: ResultActivityImplementation<TActivities[K]>;\n};\n\n/**\n * Options for creating activities handler\n */\ntype DeclareActivitiesHandlerOptions<TContract extends ContractDefinition> = {\n contract: TContract;\n activities: ContractResultActivitiesImplementations<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's `Worker.create({ activities })`.\n *\n * Flat shape: every activity (global + all workflow-local) lives at the\n * root of the returned map. See the doc comment on\n * {@link ContractResultActivitiesImplementations} for why the input you\n * write is nested by workflow while this output is flat.\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 * - `ResultAsync<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 { ResultAsync, errAsync, okAsync } from 'neverthrow';\n * import myContract from './contract';\n *\n * export const activities = declareActivitiesHandler({\n * contract: myContract,\n * activities: {\n * // Activity returns ResultAsync instead of throwing.\n * sendEmail: (args) =>\n * ResultAsync.fromPromise(\n * emailService.send(args),\n * (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 * 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 * ).map(() => ({ sent: true })),\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 * `ResultAsync<T, ApplicationFailure>` shape and produces ordinary\n * Promise-returning Temporal handlers (`err(...)` → thrown\n * `ApplicationFailure`; `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) => ResultAsync<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 neverthrow activity (returns ResultAsync<T, ApplicationFailure>);\n // awaiting yields a Result<T, ApplicationFailure>.\n const result = await activityImpl(inputResult.value);\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 err(...) payload 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) => ResultAsync<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) => ResultAsync<unknown, ApplicationFailure>,\n );\n }\n }\n }\n\n return wrappedActivities;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAqMA,SAAgB,yBACd,SAC8B;CAC9B,MAAM,EAAE,UAAU,eAAe;CAGjC,MAAM,oBAAoB,CAAC;CAG3B,SAAS,YACP,cACA,aACA,cACA;EACA,OAAO,OAAO,GAAG,SAAoB;GACnC,MAAM,QAAQ,oBAAoB,IAAI;GAGtC,MAAM,cAAc,MAAM,YAAY,MAAM,YAAY,CAAC,SAAS,KAAK;GACvE,IAAI,YAAY,QACd,MAAM,IAAI,6BAA6B,cAAc,YAAY,MAAM;GAKzE,MAAM,SAAS,MAAM,aAAa,YAAY,KAAK;GAGnD,IAAI,OAAO,KAAK,GAAG;IAEjB,MAAM,eAAe,MAAM,YAAY,OAAO,YAAY,CAAC,SAAS,OAAO,KAAK;IAChF,IAAI,aAAa,QACf,MAAM,IAAI,8BAA8B,cAAc,aAAa,MAAM;IAE3E,OAAO,aAAa;GACtB,OAIE,MAAM,OAAO;EAEjB;CACF;CAGA,IAAI,SAAS,YACX,KAAK,MAAM,CAAC,cAAc,SAAS,OAAO,QAAQ,UAAU,GAAG;EAE7D,IAAI,SAAS,aAAa,gBAAgB,SAAS,WACjD;EAGF,MAAM,cAAc,SAAS,WAAW;EACxC,IAAI,CAAC,aACH,MAAM,IAAI,gCAAgC,cAAc,OAAO,KAAK,SAAS,UAAU,CAAC;EAI1F,kBAA+C,gBAAgB,YAC7D,cACA,aACA,IACF;CACF;CAIF,IAAI,SAAS,WACX,KAAK,MAAM,CAAC,cAAc,gBAAgB,OAAO,QAAQ,SAAS,SAAS,GAAG;EAC5E,MAAM,mBAAoB,WAAuC;EAGjE,IAAI,CAAC,kBAEH;EAGF,MAAM,SAAS,YAAY,cAAc,CAAC;EAE1C,KAAK,MAAM,CAAC,cAAc,SAAS,OAAO,QAAQ,gBAAgB,GAAG;GACnE,MAAM,cAAc,OAAO;GAC3B,IAAI,CAAC,aACH,MAAM,IAAI,gCACR,GAAG,aAAa,GAAG,gBACnB,OAAO,KAAK,MAAM,CACpB;GAIF,kBAA+C,gBAAgB,YAC7D,GAAG,aAAa,GAAG,gBACnB,aACA,IACF;EACF;CACF;CAGF,OAAO;AACT"}
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 use neverthrow's\n// `ResultAsync` directly. Workflow code (see workflow.ts) uses the same\n// neverthrow API — neverthrow's evaluation is compatible with Temporal's\n// 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 type { ResultAsync } from \"neverthrow\";\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 ValidationError,\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 neverthrow's `ResultAsync`.\n *\n * Returns `ResultAsync<Output, ApplicationFailure>` for explicit error\n * handling instead of throwing. The wrapper rethrows `err()` payloads at\n * the activity boundary; Temporal recognizes `ApplicationFailure` natively\n * and applies the configured retry policy (with `nonRetryable: true`\n * opting an instance out per-call).\n */\ntype ResultActivityImplementation<TActivity extends ActivityDefinition> = (\n args: WorkerInferInput<TActivity>,\n) => ResultAsync<WorkerInferOutput<TActivity>, ApplicationFailure>;\n\n/**\n * Map of all activity implementations for a contract (global + all workflow-specific).\n *\n * **Shape note — input is nested by workflow, output is flat.** This\n * asymmetry is deliberate:\n *\n * - The implementation map you write **mirrors the contract's structure**:\n * global activities sit at the root, workflow-local activities nest\n * under their owning workflow's name. Mirroring the contract gives\n * IDE autocomplete that matches `defineContract`, prevents typos that\n * put a workflow-local activity at the global level, and makes\n * ownership visible at definition time.\n * - The handler returned by {@link declareActivitiesHandler} (see\n * {@link ActivitiesHandler}) is **flat** because Temporal's worker\n * sees a single activity namespace at runtime —\n * `proxyActivities<...>()` resolves names from one map regardless of\n * which workflow consumes them. `defineContract` enforces no name\n * collisions across global + workflow-local scopes, so the flat\n * output has no ambiguity to resolve.\n *\n * In short: write nested (mirror the contract); the wrapper flattens\n * for Temporal.\n */\ntype ContractResultActivitiesImplementations<TContract extends ContractDefinition> =\n // Global activities\n (TContract[\"activities\"] extends Record<string, ActivityDefinition>\n ? ResultActivitiesImplementations<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 ? ResultActivitiesImplementations<TContract[\"workflows\"][TWorkflow][\"activities\"]>\n : {};\n };\n\ntype ResultActivitiesImplementations<TActivities extends Record<string, ActivityDefinition>> = {\n [K in keyof TActivities]: ResultActivityImplementation<TActivities[K]>;\n};\n\n/**\n * Options for creating activities handler\n */\ntype DeclareActivitiesHandlerOptions<TContract extends ContractDefinition> = {\n contract: TContract;\n activities: ContractResultActivitiesImplementations<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's `Worker.create({ activities })`.\n *\n * Flat shape: every activity (global + all workflow-local) lives at the\n * root of the returned map. See the doc comment on\n * {@link ContractResultActivitiesImplementations} for why the input you\n * write is nested by workflow while this output is flat.\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 * - `ResultAsync<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 { ResultAsync, errAsync, okAsync } from 'neverthrow';\n * import myContract from './contract';\n *\n * export const activities = declareActivitiesHandler({\n * contract: myContract,\n * activities: {\n * // Activity returns ResultAsync instead of throwing.\n * sendEmail: (args) =>\n * ResultAsync.fromPromise(\n * emailService.send(args),\n * (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 * 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 * ).map(() => ({ sent: true })),\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 * `ResultAsync<T, ApplicationFailure>` shape and produces ordinary\n * Promise-returning Temporal handlers (`err(...)` → thrown\n * `ApplicationFailure`; `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) => ResultAsync<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 neverthrow activity (returns ResultAsync<T, ApplicationFailure>);\n // awaiting yields a Result<T, ApplicationFailure>.\n const result = await activityImpl(inputResult.value);\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 err(...) payload 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) => ResultAsync<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) => ResultAsync<unknown, ApplicationFailure>,\n );\n }\n }\n }\n\n return wrappedActivities;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAsMA,SAAgB,yBACd,SAC8B;CAC9B,MAAM,EAAE,UAAU,eAAe;CAGjC,MAAM,oBAAoB,CAAC;CAG3B,SAAS,YACP,cACA,aACA,cACA;EACA,OAAO,OAAO,GAAG,SAAoB;GACnC,MAAM,QAAQ,oBAAoB,IAAI;GAGtC,MAAM,cAAc,MAAM,YAAY,MAAM,YAAY,CAAC,SAAS,KAAK;GACvE,IAAI,YAAY,QACd,MAAM,IAAI,6BAA6B,cAAc,YAAY,MAAM;GAKzE,MAAM,SAAS,MAAM,aAAa,YAAY,KAAK;GAGnD,IAAI,OAAO,KAAK,GAAG;IAEjB,MAAM,eAAe,MAAM,YAAY,OAAO,YAAY,CAAC,SAAS,OAAO,KAAK;IAChF,IAAI,aAAa,QACf,MAAM,IAAI,8BAA8B,cAAc,aAAa,MAAM;IAE3E,OAAO,aAAa;GACtB,OAIE,MAAM,OAAO;EAEjB;CACF;CAGA,IAAI,SAAS,YACX,KAAK,MAAM,CAAC,cAAc,SAAS,OAAO,QAAQ,UAAU,GAAG;EAE7D,IAAI,SAAS,aAAa,gBAAgB,SAAS,WACjD;EAGF,MAAM,cAAc,SAAS,WAAW;EACxC,IAAI,CAAC,aACH,MAAM,IAAI,gCAAgC,cAAc,OAAO,KAAK,SAAS,UAAU,CAAC;EAI1F,kBAA+C,gBAAgB,YAC7D,cACA,aACA,IACF;CACF;CAIF,IAAI,SAAS,WACX,KAAK,MAAM,CAAC,cAAc,gBAAgB,OAAO,QAAQ,SAAS,SAAS,GAAG;EAC5E,MAAM,mBAAoB,WAAuC;EAGjE,IAAI,CAAC,kBAEH;EAGF,MAAM,SAAS,YAAY,cAAc,CAAC;EAE1C,KAAK,MAAM,CAAC,cAAc,SAAS,OAAO,QAAQ,gBAAgB,GAAG;GACnE,MAAM,cAAc,OAAO;GAC3B,IAAI,CAAC,aACH,MAAM,IAAI,gCACR,GAAG,aAAa,GAAG,gBACnB,OAAO,KAAK,MAAM,CACpB;GAIF,kBAA+C,gBAAgB,YAC7D,GAAG,aAAa,GAAG,gBACnB,aACA,IACF;EACF;CACF;CAGF,OAAO;AACT"}
@@ -1,4 +1,5 @@
1
1
  import { AnySchema } from "@temporal-contract/contract";
2
+ import { ApplicationFailure } from "@temporalio/common";
2
3
  import { StandardSchemaV1 } from "@standard-schema/spec";
3
4
 
4
5
  //#region src/types.d.ts
@@ -38,6 +39,38 @@ type ClientInferOutput<T extends {
38
39
  declare abstract class WorkerError extends Error {
39
40
  protected constructor(message: string, cause?: unknown);
40
41
  }
42
+ /**
43
+ * Base class for the contract's runtime validation failures — workflow and
44
+ * activity input/output, plus signal/query/update payloads.
45
+ *
46
+ * These extend Temporal's {@link ApplicationFailure} with `nonRetryable: true`
47
+ * rather than a plain `Error`, and that distinction is load-bearing. The
48
+ * TypeScript SDK classifies a non-`TemporalFailure` thrown from *workflow* code
49
+ * as a Workflow Task failure — presumed to be a transient code bug or
50
+ * non-determinism — and retries the task indefinitely, leaving the execution
51
+ * silently `Running` forever (it looks like the worker "hung"). Only a
52
+ * `TemporalFailure` such as `ApplicationFailure` fails the Workflow Execution
53
+ * terminally. The same logic applies at the activity boundary, where Temporal's
54
+ * default retry policy has unlimited attempts: a plain `Error` would retry
55
+ * forever too.
56
+ *
57
+ * Contract validation failures are deterministic — the schema is static, so bad
58
+ * input/output never becomes valid on replay or retry — so they are surfaced as
59
+ * non-retryable, failing fast with a clear error instead of an infinite retry
60
+ * loop.
61
+ *
62
+ * The concrete subclass name is passed through as the failure `type`, so it
63
+ * stays discriminable after crossing Temporal's serialization boundary (where
64
+ * the JS class identity is lost) via `failure.type`. The failing field path is
65
+ * carried in the human-readable `message` (see {@link summarizeIssues}). The
66
+ * raw `issues` remain available as a property for in-process inspection.
67
+ *
68
+ * See issue #251.
69
+ */
70
+ declare abstract class ValidationError extends ApplicationFailure {
71
+ readonly issues: ReadonlyArray<StandardSchemaV1.Issue>;
72
+ protected constructor(message: string, type: string, issues: ReadonlyArray<StandardSchemaV1.Issue>);
73
+ }
41
74
  /**
42
75
  * Error thrown when an activity definition is not found in the contract
43
76
  */
@@ -49,73 +82,64 @@ declare class ActivityDefinitionNotFoundError extends WorkerError {
49
82
  /**
50
83
  * Error thrown when activity input validation fails
51
84
  */
52
- declare class ActivityInputValidationError extends WorkerError {
85
+ declare class ActivityInputValidationError extends ValidationError {
53
86
  readonly activityName: string;
54
- readonly issues: ReadonlyArray<StandardSchemaV1.Issue>;
55
87
  constructor(activityName: string, issues: ReadonlyArray<StandardSchemaV1.Issue>);
56
88
  }
57
89
  /**
58
90
  * Error thrown when activity output validation fails
59
91
  */
60
- declare class ActivityOutputValidationError extends WorkerError {
92
+ declare class ActivityOutputValidationError extends ValidationError {
61
93
  readonly activityName: string;
62
- readonly issues: ReadonlyArray<StandardSchemaV1.Issue>;
63
94
  constructor(activityName: string, issues: ReadonlyArray<StandardSchemaV1.Issue>);
64
95
  }
65
96
  /**
66
97
  * Error thrown when workflow input validation fails
67
98
  */
68
- declare class WorkflowInputValidationError extends WorkerError {
99
+ declare class WorkflowInputValidationError extends ValidationError {
69
100
  readonly workflowName: string;
70
- readonly issues: ReadonlyArray<StandardSchemaV1.Issue>;
71
101
  constructor(workflowName: string, issues: ReadonlyArray<StandardSchemaV1.Issue>);
72
102
  }
73
103
  /**
74
104
  * Error thrown when workflow output validation fails
75
105
  */
76
- declare class WorkflowOutputValidationError extends WorkerError {
106
+ declare class WorkflowOutputValidationError extends ValidationError {
77
107
  readonly workflowName: string;
78
- readonly issues: ReadonlyArray<StandardSchemaV1.Issue>;
79
108
  constructor(workflowName: string, issues: ReadonlyArray<StandardSchemaV1.Issue>);
80
109
  }
81
110
  /**
82
111
  * Error thrown when signal input validation fails
83
112
  */
84
- declare class SignalInputValidationError extends WorkerError {
113
+ declare class SignalInputValidationError extends ValidationError {
85
114
  readonly signalName: string;
86
- readonly issues: ReadonlyArray<StandardSchemaV1.Issue>;
87
115
  constructor(signalName: string, issues: ReadonlyArray<StandardSchemaV1.Issue>);
88
116
  }
89
117
  /**
90
118
  * Error thrown when query input validation fails
91
119
  */
92
- declare class QueryInputValidationError extends WorkerError {
120
+ declare class QueryInputValidationError extends ValidationError {
93
121
  readonly queryName: string;
94
- readonly issues: ReadonlyArray<StandardSchemaV1.Issue>;
95
122
  constructor(queryName: string, issues: ReadonlyArray<StandardSchemaV1.Issue>);
96
123
  }
97
124
  /**
98
125
  * Error thrown when query output validation fails
99
126
  */
100
- declare class QueryOutputValidationError extends WorkerError {
127
+ declare class QueryOutputValidationError extends ValidationError {
101
128
  readonly queryName: string;
102
- readonly issues: ReadonlyArray<StandardSchemaV1.Issue>;
103
129
  constructor(queryName: string, issues: ReadonlyArray<StandardSchemaV1.Issue>);
104
130
  }
105
131
  /**
106
132
  * Error thrown when update input validation fails
107
133
  */
108
- declare class UpdateInputValidationError extends WorkerError {
134
+ declare class UpdateInputValidationError extends ValidationError {
109
135
  readonly updateName: string;
110
- readonly issues: ReadonlyArray<StandardSchemaV1.Issue>;
111
136
  constructor(updateName: string, issues: ReadonlyArray<StandardSchemaV1.Issue>);
112
137
  }
113
138
  /**
114
139
  * Error thrown when update output validation fails
115
140
  */
116
- declare class UpdateOutputValidationError extends WorkerError {
141
+ declare class UpdateOutputValidationError extends ValidationError {
117
142
  readonly updateName: string;
118
- readonly issues: ReadonlyArray<StandardSchemaV1.Issue>;
119
143
  constructor(updateName: string, issues: ReadonlyArray<StandardSchemaV1.Issue>);
120
144
  }
121
145
  /**
@@ -204,5 +228,5 @@ declare class WorkflowScopeError extends WorkerError {
204
228
  constructor(cause: unknown);
205
229
  }
206
230
  //#endregion
207
- export { ClientInferOutput as _, ChildWorkflowError as a, QueryOutputValidationError as c, UpdateOutputValidationError as d, WorkflowCancelledError as f, ClientInferInput as g, WorkflowScopeError as h, ChildWorkflowCancelledError as i, SignalInputValidationError as l, WorkflowOutputValidationError as m, ActivityInputValidationError as n, ChildWorkflowNotFoundError as o, WorkflowInputValidationError as p, ActivityOutputValidationError as r, QueryInputValidationError as s, ActivityDefinitionNotFoundError as t, UpdateInputValidationError as u, WorkerInferInput as v, WorkerInferOutput as y };
208
- //# sourceMappingURL=errors-BP48RaOI.d.cts.map
231
+ export { ClientInferInput as _, ChildWorkflowError as a, WorkerInferOutput as b, QueryOutputValidationError as c, UpdateOutputValidationError as d, ValidationError as f, WorkflowScopeError as g, WorkflowOutputValidationError as h, ChildWorkflowCancelledError as i, SignalInputValidationError as l, WorkflowInputValidationError as m, ActivityInputValidationError as n, ChildWorkflowNotFoundError as o, WorkflowCancelledError as p, ActivityOutputValidationError as r, QueryInputValidationError as s, ActivityDefinitionNotFoundError as t, UpdateInputValidationError as u, ClientInferOutput as v, WorkerInferInput as y };
232
+ //# sourceMappingURL=errors-CE56feY1.d.cts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors-CE56feY1.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;;;;;;uBCzBa,WAAA,SAAoB,KAAK;EAAA,UAC7B,WAAA,CAAa,OAAA,UAAiB,KAAA;AAAA;;;;;;;;;;;;;ADAtC;AAOH;;;;;;;;;;;;;;;uBC+BsB,eAAA,SAAwB,kBAAA;EAAA,SAI1B,MAAA,EAAQ,aAAA,CAAc,gBAAA,CAAiB,KAAA;EAAA,UAHhD,WAAA,CACP,OAAA,UACA,IAAA,UACgB,MAAA,EAAQ,aAAA,CAAc,gBAAA,CAAiB,KAAA;AAAA;;;;cA0B9C,+BAAA,SAAwC,WAAW;EAAA,SAE5C,YAAA;EAAA,SACA,oBAAA;cADA,YAAA,UACA,oBAAA;AAAA;;;;cAaP,4BAAA,SAAqC,eAAA;EAAA,SAE9B,YAAA;cAAA,YAAA,UAChB,MAAA,EAAQ,aAAA,CAAc,gBAAA,CAAiB,KAAA;AAAA;;;;cAc9B,6BAAA,SAAsC,eAAA;EAAA,SAE/B,YAAA;cAAA,YAAA,UAChB,MAAA,EAAQ,aAAA,CAAc,gBAAA,CAAiB,KAAA;AAAA;;;;cAc9B,4BAAA,SAAqC,eAAA;EAAA,SAE9B,YAAA;cAAA,YAAA,UAChB,MAAA,EAAQ,aAAA,CAAc,gBAAA,CAAiB,KAAA;AAAA;;;;cAc9B,6BAAA,SAAsC,eAAA;EAAA,SAE/B,YAAA;cAAA,YAAA,UAChB,MAAA,EAAQ,aAAA,CAAc,gBAAA,CAAiB,KAAA;AAAA;;;;cAc9B,0BAAA,SAAmC,eAAA;EAAA,SAE5B,UAAA;cAAA,UAAA,UAChB,MAAA,EAAQ,aAAA,CAAc,gBAAA,CAAiB,KAAA;AAAA;;;;cAc9B,yBAAA,SAAkC,eAAA;EAAA,SAE3B,SAAA;cAAA,SAAA,UAChB,MAAA,EAAQ,aAAA,CAAc,gBAAA,CAAiB,KAAA;AAAA;;;;cAc9B,0BAAA,SAAmC,eAAA;EAAA,SAE5B,SAAA;cAAA,SAAA,UAChB,MAAA,EAAQ,aAAA,CAAc,gBAAA,CAAiB,KAAA;AAAA;;;;cAc9B,0BAAA,SAAmC,eAAA;EAAA,SAE5B,UAAA;cAAA,UAAA,UAChB,MAAA,EAAQ,aAAA,CAAc,gBAAA,CAAiB,KAAA;AAAA;;AApKsB;AA0BjE;cAwJa,2BAAA,SAAoC,eAAA;EAAA,SAE7B,UAAA;cAAA,UAAA,UAChB,MAAA,EAAQ,aAAA,CAAc,gBAAA,CAAiB,KAAA;AAAA;;;;cAc9B,0BAAA,SAAmC,WAAW;EAAA,SAEvC,YAAA;EAAA,SACA,kBAAA;cADA,YAAA,UACA,kBAAA;AAAA;;;;;;;;;;cAiBP,kBAAA,SAA2B,WAAW;cACrC,OAAA,UAAiB,KAAA;AAAA;;;;;AA3KkB;AAcjD;;;;;;;;;cAiLa,2BAAA,SAAoC,kBAAkB;EAAA,SAE/C,YAAA;cAAA,YAAA,UAChB,KAAA;AAAA;;;;;AAjL6C;AAcjD;;;;;;;cAsLa,sBAAA,SAA+B,WAAW;cACzC,KAAA;AAAA;;;;;;;;AApLmC;AAcjD;;;;;;;;;;;;;;;;;AAGiD;AAcjD;;;cAwLa,kBAAA,SAA2B,WAAW;cACrC,KAAA;AAAA"}
@@ -1,4 +1,5 @@
1
1
  import { AnySchema } from "@temporal-contract/contract";
2
+ import { ApplicationFailure } from "@temporalio/common";
2
3
  import { StandardSchemaV1 } from "@standard-schema/spec";
3
4
 
4
5
  //#region src/types.d.ts
@@ -38,6 +39,38 @@ type ClientInferOutput<T extends {
38
39
  declare abstract class WorkerError extends Error {
39
40
  protected constructor(message: string, cause?: unknown);
40
41
  }
42
+ /**
43
+ * Base class for the contract's runtime validation failures — workflow and
44
+ * activity input/output, plus signal/query/update payloads.
45
+ *
46
+ * These extend Temporal's {@link ApplicationFailure} with `nonRetryable: true`
47
+ * rather than a plain `Error`, and that distinction is load-bearing. The
48
+ * TypeScript SDK classifies a non-`TemporalFailure` thrown from *workflow* code
49
+ * as a Workflow Task failure — presumed to be a transient code bug or
50
+ * non-determinism — and retries the task indefinitely, leaving the execution
51
+ * silently `Running` forever (it looks like the worker "hung"). Only a
52
+ * `TemporalFailure` such as `ApplicationFailure` fails the Workflow Execution
53
+ * terminally. The same logic applies at the activity boundary, where Temporal's
54
+ * default retry policy has unlimited attempts: a plain `Error` would retry
55
+ * forever too.
56
+ *
57
+ * Contract validation failures are deterministic — the schema is static, so bad
58
+ * input/output never becomes valid on replay or retry — so they are surfaced as
59
+ * non-retryable, failing fast with a clear error instead of an infinite retry
60
+ * loop.
61
+ *
62
+ * The concrete subclass name is passed through as the failure `type`, so it
63
+ * stays discriminable after crossing Temporal's serialization boundary (where
64
+ * the JS class identity is lost) via `failure.type`. The failing field path is
65
+ * carried in the human-readable `message` (see {@link summarizeIssues}). The
66
+ * raw `issues` remain available as a property for in-process inspection.
67
+ *
68
+ * See issue #251.
69
+ */
70
+ declare abstract class ValidationError extends ApplicationFailure {
71
+ readonly issues: ReadonlyArray<StandardSchemaV1.Issue>;
72
+ protected constructor(message: string, type: string, issues: ReadonlyArray<StandardSchemaV1.Issue>);
73
+ }
41
74
  /**
42
75
  * Error thrown when an activity definition is not found in the contract
43
76
  */
@@ -49,73 +82,64 @@ declare class ActivityDefinitionNotFoundError extends WorkerError {
49
82
  /**
50
83
  * Error thrown when activity input validation fails
51
84
  */
52
- declare class ActivityInputValidationError extends WorkerError {
85
+ declare class ActivityInputValidationError extends ValidationError {
53
86
  readonly activityName: string;
54
- readonly issues: ReadonlyArray<StandardSchemaV1.Issue>;
55
87
  constructor(activityName: string, issues: ReadonlyArray<StandardSchemaV1.Issue>);
56
88
  }
57
89
  /**
58
90
  * Error thrown when activity output validation fails
59
91
  */
60
- declare class ActivityOutputValidationError extends WorkerError {
92
+ declare class ActivityOutputValidationError extends ValidationError {
61
93
  readonly activityName: string;
62
- readonly issues: ReadonlyArray<StandardSchemaV1.Issue>;
63
94
  constructor(activityName: string, issues: ReadonlyArray<StandardSchemaV1.Issue>);
64
95
  }
65
96
  /**
66
97
  * Error thrown when workflow input validation fails
67
98
  */
68
- declare class WorkflowInputValidationError extends WorkerError {
99
+ declare class WorkflowInputValidationError extends ValidationError {
69
100
  readonly workflowName: string;
70
- readonly issues: ReadonlyArray<StandardSchemaV1.Issue>;
71
101
  constructor(workflowName: string, issues: ReadonlyArray<StandardSchemaV1.Issue>);
72
102
  }
73
103
  /**
74
104
  * Error thrown when workflow output validation fails
75
105
  */
76
- declare class WorkflowOutputValidationError extends WorkerError {
106
+ declare class WorkflowOutputValidationError extends ValidationError {
77
107
  readonly workflowName: string;
78
- readonly issues: ReadonlyArray<StandardSchemaV1.Issue>;
79
108
  constructor(workflowName: string, issues: ReadonlyArray<StandardSchemaV1.Issue>);
80
109
  }
81
110
  /**
82
111
  * Error thrown when signal input validation fails
83
112
  */
84
- declare class SignalInputValidationError extends WorkerError {
113
+ declare class SignalInputValidationError extends ValidationError {
85
114
  readonly signalName: string;
86
- readonly issues: ReadonlyArray<StandardSchemaV1.Issue>;
87
115
  constructor(signalName: string, issues: ReadonlyArray<StandardSchemaV1.Issue>);
88
116
  }
89
117
  /**
90
118
  * Error thrown when query input validation fails
91
119
  */
92
- declare class QueryInputValidationError extends WorkerError {
120
+ declare class QueryInputValidationError extends ValidationError {
93
121
  readonly queryName: string;
94
- readonly issues: ReadonlyArray<StandardSchemaV1.Issue>;
95
122
  constructor(queryName: string, issues: ReadonlyArray<StandardSchemaV1.Issue>);
96
123
  }
97
124
  /**
98
125
  * Error thrown when query output validation fails
99
126
  */
100
- declare class QueryOutputValidationError extends WorkerError {
127
+ declare class QueryOutputValidationError extends ValidationError {
101
128
  readonly queryName: string;
102
- readonly issues: ReadonlyArray<StandardSchemaV1.Issue>;
103
129
  constructor(queryName: string, issues: ReadonlyArray<StandardSchemaV1.Issue>);
104
130
  }
105
131
  /**
106
132
  * Error thrown when update input validation fails
107
133
  */
108
- declare class UpdateInputValidationError extends WorkerError {
134
+ declare class UpdateInputValidationError extends ValidationError {
109
135
  readonly updateName: string;
110
- readonly issues: ReadonlyArray<StandardSchemaV1.Issue>;
111
136
  constructor(updateName: string, issues: ReadonlyArray<StandardSchemaV1.Issue>);
112
137
  }
113
138
  /**
114
139
  * Error thrown when update output validation fails
115
140
  */
116
- declare class UpdateOutputValidationError extends WorkerError {
141
+ declare class UpdateOutputValidationError extends ValidationError {
117
142
  readonly updateName: string;
118
- readonly issues: ReadonlyArray<StandardSchemaV1.Issue>;
119
143
  constructor(updateName: string, issues: ReadonlyArray<StandardSchemaV1.Issue>);
120
144
  }
121
145
  /**
@@ -204,5 +228,5 @@ declare class WorkflowScopeError extends WorkerError {
204
228
  constructor(cause: unknown);
205
229
  }
206
230
  //#endregion
207
- export { ClientInferOutput as _, ChildWorkflowError as a, QueryOutputValidationError as c, UpdateOutputValidationError as d, WorkflowCancelledError as f, ClientInferInput as g, WorkflowScopeError as h, ChildWorkflowCancelledError as i, SignalInputValidationError as l, WorkflowOutputValidationError as m, ActivityInputValidationError as n, ChildWorkflowNotFoundError as o, WorkflowInputValidationError as p, ActivityOutputValidationError as r, QueryInputValidationError as s, ActivityDefinitionNotFoundError as t, UpdateInputValidationError as u, WorkerInferInput as v, WorkerInferOutput as y };
208
- //# sourceMappingURL=errors-BP48RaOI.d.mts.map
231
+ export { ClientInferInput as _, ChildWorkflowError as a, WorkerInferOutput as b, QueryOutputValidationError as c, UpdateOutputValidationError as d, ValidationError as f, WorkflowScopeError as g, WorkflowOutputValidationError as h, ChildWorkflowCancelledError as i, SignalInputValidationError as l, WorkflowInputValidationError as m, ActivityInputValidationError as n, ChildWorkflowNotFoundError as o, WorkflowCancelledError as p, ActivityOutputValidationError as r, QueryInputValidationError as s, ActivityDefinitionNotFoundError as t, UpdateInputValidationError as u, ClientInferOutput as v, WorkerInferInput as y };
232
+ //# sourceMappingURL=errors-CE56feY1.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors-CE56feY1.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;;;;;;uBCzBa,WAAA,SAAoB,KAAK;EAAA,UAC7B,WAAA,CAAa,OAAA,UAAiB,KAAA;AAAA;;;;;;;;;;;;;ADAtC;AAOH;;;;;;;;;;;;;;;uBC+BsB,eAAA,SAAwB,kBAAA;EAAA,SAI1B,MAAA,EAAQ,aAAA,CAAc,gBAAA,CAAiB,KAAA;EAAA,UAHhD,WAAA,CACP,OAAA,UACA,IAAA,UACgB,MAAA,EAAQ,aAAA,CAAc,gBAAA,CAAiB,KAAA;AAAA;;;;cA0B9C,+BAAA,SAAwC,WAAW;EAAA,SAE5C,YAAA;EAAA,SACA,oBAAA;cADA,YAAA,UACA,oBAAA;AAAA;;;;cAaP,4BAAA,SAAqC,eAAA;EAAA,SAE9B,YAAA;cAAA,YAAA,UAChB,MAAA,EAAQ,aAAA,CAAc,gBAAA,CAAiB,KAAA;AAAA;;;;cAc9B,6BAAA,SAAsC,eAAA;EAAA,SAE/B,YAAA;cAAA,YAAA,UAChB,MAAA,EAAQ,aAAA,CAAc,gBAAA,CAAiB,KAAA;AAAA;;;;cAc9B,4BAAA,SAAqC,eAAA;EAAA,SAE9B,YAAA;cAAA,YAAA,UAChB,MAAA,EAAQ,aAAA,CAAc,gBAAA,CAAiB,KAAA;AAAA;;;;cAc9B,6BAAA,SAAsC,eAAA;EAAA,SAE/B,YAAA;cAAA,YAAA,UAChB,MAAA,EAAQ,aAAA,CAAc,gBAAA,CAAiB,KAAA;AAAA;;;;cAc9B,0BAAA,SAAmC,eAAA;EAAA,SAE5B,UAAA;cAAA,UAAA,UAChB,MAAA,EAAQ,aAAA,CAAc,gBAAA,CAAiB,KAAA;AAAA;;;;cAc9B,yBAAA,SAAkC,eAAA;EAAA,SAE3B,SAAA;cAAA,SAAA,UAChB,MAAA,EAAQ,aAAA,CAAc,gBAAA,CAAiB,KAAA;AAAA;;;;cAc9B,0BAAA,SAAmC,eAAA;EAAA,SAE5B,SAAA;cAAA,SAAA,UAChB,MAAA,EAAQ,aAAA,CAAc,gBAAA,CAAiB,KAAA;AAAA;;;;cAc9B,0BAAA,SAAmC,eAAA;EAAA,SAE5B,UAAA;cAAA,UAAA,UAChB,MAAA,EAAQ,aAAA,CAAc,gBAAA,CAAiB,KAAA;AAAA;;AApKsB;AA0BjE;cAwJa,2BAAA,SAAoC,eAAA;EAAA,SAE7B,UAAA;cAAA,UAAA,UAChB,MAAA,EAAQ,aAAA,CAAc,gBAAA,CAAiB,KAAA;AAAA;;;;cAc9B,0BAAA,SAAmC,WAAW;EAAA,SAEvC,YAAA;EAAA,SACA,kBAAA;cADA,YAAA,UACA,kBAAA;AAAA;;;;;;;;;;cAiBP,kBAAA,SAA2B,WAAW;cACrC,OAAA,UAAiB,KAAA;AAAA;;;;;AA3KkB;AAcjD;;;;;;;;;cAiLa,2BAAA,SAAoC,kBAAkB;EAAA,SAE/C,YAAA;cAAA,YAAA,UAChB,KAAA;AAAA;;;;;AAjL6C;AAcjD;;;;;;;cAsLa,sBAAA,SAA+B,WAAW;cACzC,KAAA;AAAA;;;;;;;;AApLmC;AAcjD;;;;;;;;;;;;;;;;;AAGiD;AAcjD;;;cAwLa,kBAAA,SAA2B,WAAW;cACrC,KAAA;AAAA"}