@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.
@@ -0,0 +1 @@
1
+ {"version":3,"file":"internal-BoNcEtYh.mjs","names":[],"sources":["../src/format.ts","../src/errors.ts","../src/internal.ts"],"sourcesContent":["/**\n * Issue / validation-message formatters.\n *\n * Lives in its own module (separate from `errors.ts` and `internal.ts`) so\n * both can import these helpers without forming a circular dependency:\n * `errors.ts` -> `format.ts` and `internal.ts` -> `format.ts` are both safe,\n * even when `internal.ts` later needs to import error classes from\n * `errors.ts` (as `createContinueAsNew` does).\n *\n * Not part of the package's public exports map.\n */\nimport type { StandardSchemaV1 } from \"@standard-schema/spec\";\n\n/**\n * Pattern for string keys safe to render with dot notation. A \"safe\" key is a\n * JavaScript identifier (letters/digits/underscore/$, not starting with a\n * digit). Anything else — keys containing dots, spaces, leading digits, the\n * empty string, the literal string `\"0\"` etc. — gets bracket-quoted so the\n * path is unambiguous. Reserved words are accepted: we are formatting a\n * diagnostic, not generating runnable code.\n */\nconst SAFE_IDENTIFIER = /^[A-Za-z_$][A-Za-z0-9_$]*$/;\n\n/**\n * Render a Standard Schema {@link StandardSchemaV1.Issue} into a human-readable\n * string that includes the failing field's path.\n */\nexport function formatIssue(issue: StandardSchemaV1.Issue): string {\n if (issue.path === undefined || issue.path.length === 0) {\n return issue.message;\n }\n let path = \"\";\n for (let i = 0; i < issue.path.length; i++) {\n const segment = issue.path[i];\n const key =\n segment !== null && typeof segment === \"object\" && \"key\" in segment ? segment.key : segment;\n if (typeof key === \"number\") {\n path += `[${key}]`;\n } else if (typeof key === \"string\" && SAFE_IDENTIFIER.test(key)) {\n path += i === 0 ? key : `.${key}`;\n } else if (typeof key === \"string\") {\n path += `[${JSON.stringify(key)}]`;\n } else {\n path += `[${String(key)}]`;\n }\n }\n return `at ${path}: ${issue.message}`;\n}\n\n/**\n * Join a list of validation issues into a single message, with each issue\n * rendered via {@link formatIssue} so field paths surface in the error text.\n */\nexport function summarizeIssues(issues: ReadonlyArray<StandardSchemaV1.Issue>): string {\n return issues.map(formatIssue).join(\"; \");\n}\n\n/**\n * Build the message attached to a `ChildWorkflowError` for input/output\n * validation failures. Centralized so the worker and any future call sites\n * format identically.\n */\nexport function formatChildWorkflowValidationMessage(\n workflowName: string,\n direction: \"input\" | \"output\",\n issues: ReadonlyArray<StandardSchemaV1.Issue>,\n): string {\n return `Child workflow \"${workflowName}\" ${direction} validation failed: ${summarizeIssues(issues)}`;\n}\n","import type { StandardSchemaV1 } from \"@standard-schema/spec\";\nimport { summarizeIssues } from \"./format.js\";\n\n/**\n * Base error class for worker errors\n */\nabstract class WorkerError extends Error {\n protected constructor(message: string, cause?: unknown) {\n super(message, { cause });\n this.name = \"WorkerError\";\n // Maintains proper stack trace for where our error was thrown (only available on V8)\n if (Error.captureStackTrace) {\n Error.captureStackTrace(this, this.constructor);\n }\n }\n}\n\n/**\n * Error thrown when an activity definition is not found in the contract\n */\nexport class ActivityDefinitionNotFoundError extends WorkerError {\n constructor(\n public readonly activityName: string,\n public readonly availableDefinitions: readonly string[] = [],\n ) {\n const available = availableDefinitions.length > 0 ? availableDefinitions.join(\", \") : \"none\";\n super(\n `Activity definition not found for: \"${activityName}\". Available activities: ${available}`,\n );\n this.name = \"ActivityDefinitionNotFoundError\";\n }\n}\n\n/**\n * Error thrown when activity input validation fails\n */\nexport class ActivityInputValidationError extends WorkerError {\n constructor(\n public readonly activityName: string,\n public readonly issues: ReadonlyArray<StandardSchemaV1.Issue>,\n ) {\n const message = summarizeIssues(issues);\n super(`Activity \"${activityName}\" input validation failed: ${message}`);\n this.name = \"ActivityInputValidationError\";\n }\n}\n\n/**\n * Error thrown when activity output validation fails\n */\nexport class ActivityOutputValidationError extends WorkerError {\n constructor(\n public readonly activityName: string,\n public readonly issues: ReadonlyArray<StandardSchemaV1.Issue>,\n ) {\n const message = summarizeIssues(issues);\n super(`Activity \"${activityName}\" output validation failed: ${message}`);\n this.name = \"ActivityOutputValidationError\";\n }\n}\n\n/**\n * Error thrown when workflow input validation fails\n */\nexport class WorkflowInputValidationError extends WorkerError {\n constructor(\n public readonly workflowName: string,\n public readonly issues: ReadonlyArray<StandardSchemaV1.Issue>,\n ) {\n const message = summarizeIssues(issues);\n super(`Workflow \"${workflowName}\" input validation failed: ${message}`);\n this.name = \"WorkflowInputValidationError\";\n }\n}\n\n/**\n * Error thrown when workflow output validation fails\n */\nexport class WorkflowOutputValidationError extends WorkerError {\n constructor(\n public readonly workflowName: string,\n public readonly issues: ReadonlyArray<StandardSchemaV1.Issue>,\n ) {\n const message = summarizeIssues(issues);\n super(`Workflow \"${workflowName}\" output validation failed: ${message}`);\n this.name = \"WorkflowOutputValidationError\";\n }\n}\n\n/**\n * Error thrown when signal input validation fails\n */\nexport class SignalInputValidationError extends WorkerError {\n constructor(\n public readonly signalName: string,\n public readonly issues: ReadonlyArray<StandardSchemaV1.Issue>,\n ) {\n const message = summarizeIssues(issues);\n super(`Signal \"${signalName}\" input validation failed: ${message}`);\n this.name = \"SignalInputValidationError\";\n }\n}\n\n/**\n * Error thrown when query input validation fails\n */\nexport class QueryInputValidationError extends WorkerError {\n constructor(\n public readonly queryName: string,\n public readonly issues: ReadonlyArray<StandardSchemaV1.Issue>,\n ) {\n const message = summarizeIssues(issues);\n super(`Query \"${queryName}\" input validation failed: ${message}`);\n this.name = \"QueryInputValidationError\";\n }\n}\n\n/**\n * Error thrown when query output validation fails\n */\nexport class QueryOutputValidationError extends WorkerError {\n constructor(\n public readonly queryName: string,\n public readonly issues: ReadonlyArray<StandardSchemaV1.Issue>,\n ) {\n const message = summarizeIssues(issues);\n super(`Query \"${queryName}\" output validation failed: ${message}`);\n this.name = \"QueryOutputValidationError\";\n }\n}\n\n/**\n * Error thrown when update input validation fails\n */\nexport class UpdateInputValidationError extends WorkerError {\n constructor(\n public readonly updateName: string,\n public readonly issues: ReadonlyArray<StandardSchemaV1.Issue>,\n ) {\n const message = summarizeIssues(issues);\n super(`Update \"${updateName}\" input validation failed: ${message}`);\n this.name = \"UpdateInputValidationError\";\n }\n}\n\n/**\n * Error thrown when update output validation fails\n */\nexport class UpdateOutputValidationError extends WorkerError {\n constructor(\n public readonly updateName: string,\n public readonly issues: ReadonlyArray<StandardSchemaV1.Issue>,\n ) {\n const message = summarizeIssues(issues);\n super(`Update \"${updateName}\" output validation failed: ${message}`);\n this.name = \"UpdateOutputValidationError\";\n }\n}\n\n/**\n * Error thrown when a child workflow is not found in the contract\n */\nexport class ChildWorkflowNotFoundError extends WorkerError {\n constructor(\n public readonly workflowName: string,\n public readonly availableWorkflows: readonly string[] = [],\n ) {\n const available = availableWorkflows.length > 0 ? availableWorkflows.join(\", \") : \"none\";\n super(`Child workflow not found: \"${workflowName}\". Available workflows: ${available}`);\n this.name = \"ChildWorkflowNotFoundError\";\n }\n}\n\n/**\n * Generic error for child workflow operations\n */\nexport class ChildWorkflowError extends WorkerError {\n constructor(message: string, cause?: unknown) {\n super(message, cause);\n this.name = \"ChildWorkflowError\";\n }\n}\n\n/**\n * Error returned in the `Result.Error` branch when a typed cancellation\n * scope is cancelled via Temporal's cancellation propagation. Returned by\n * both `context.cancellableScope` (when the workflow or an ancestor scope\n * cancels) and `context.nonCancellableScope` (when cancellation is raised\n * from inside the scope). Distinct from arbitrary thrown errors so call\n * sites can branch on cancellation explicitly while still surfacing\n * non-cancellation errors as Future rejections.\n */\nexport class WorkflowCancelledError extends WorkerError {\n constructor(cause?: unknown) {\n super(\"Workflow cancellation scope was cancelled\", cause);\n this.name = \"WorkflowCancelledError\";\n }\n}\n","/**\n * Internal helpers shared across the worker package's entry points.\n *\n * Not part of the public API — this module is not listed in the package's\n * `exports` map, so consumers can't import from `@temporal-contract/worker/internal`.\n * In-package tests import it directly via relative path.\n */\nimport { makeContinueAsNewFunc, proxyActivities } from \"@temporalio/workflow\";\nimport type { ActivityOptions, ContinueAsNewOptions } from \"@temporalio/workflow\";\nimport type { ActivityDefinition, ContractDefinition } from \"@temporal-contract/contract\";\nimport { WorkflowInputValidationError } from \"./errors.js\";\n\n// Re-export the formatters so workflow.ts and existing tests can keep\n// importing from `./internal.js`. Their canonical home is `./format.js`,\n// which both `errors.ts` and `internal.ts` import from to avoid a\n// circular dependency once `internal.ts` started importing error classes.\nexport { formatIssue, summarizeIssues, formatChildWorkflowValidationMessage } from \"./format.js\";\n\n/**\n * Extract the single payload from a Temporal handler's `...args` array.\n *\n * Temporal invokes handlers with whatever was passed via `args: [...]` at the\n * call site. The typed-contract layer always sends `args: [validatedInput]`,\n * so the common case is a one-element array containing the wrapped input.\n *\n * If a non-typed-contract caller passes multiple positional arguments\n * (`args: [a, b, c]`), we surface the whole array as the input — the schema\n * will then reject it unless the contract specifically modeled a tuple.\n */\nexport function extractHandlerInput(args: unknown[]): unknown {\n return args.length === 1 ? args[0] : args;\n}\n\ntype ActivityFn = (...args: unknown[]) => Promise<unknown>;\n\n/**\n * Build the raw `Record<name, fn>` proxy of activities for a workflow,\n * applying per-activity `ActivityOptions` overrides where requested.\n *\n * **Fast path (no overrides):** a single `proxyActivities(defaultOptions)`\n * call is made and returned directly. The proxy synthesizes a function for\n * any property access by name, so downstream code that looks up\n * `proxy[activityName]` works identically to before.\n *\n * **Override path:** one extra `proxyActivities(merged)` call is made *only*\n * for each activity that has an override. Activities without an entry keep\n * using the single default proxy. The result is a `Proxy` that returns the\n * override-bound function for named keys and falls back to the default proxy\n * for everything else — so the per-execution overhead scales with the number\n * of overrides, not the number of activities.\n *\n * Per-override merge is shallow: the override's properties replace the\n * default's, including the entire nested `retry` block. This matches\n * Temporal's \"one ActivityOptions per `proxyActivities` call\" semantics.\n */\nexport function buildRawActivitiesProxy(\n workflowActivities: Record<string, ActivityDefinition> | undefined,\n contractActivities: Record<string, ActivityDefinition> | undefined,\n defaultOptions: ActivityOptions,\n overrides: Partial<Record<string, ActivityOptions>> | undefined,\n): Record<string, ActivityFn> {\n const defaultProxy = proxyActivities<Record<string, ActivityFn>>(defaultOptions);\n\n // Fast path: no overrides → use the single default proxy directly.\n // (`createValidatedActivities` accesses by name, so the Proxy's get-trap\n // suffices; we don't need an enumerable map.)\n const overrideEntries = overrides\n ? Object.entries(overrides).filter(\n (entry): entry is [string, ActivityOptions] => entry[1] !== undefined,\n )\n : [];\n if (overrideEntries.length === 0) {\n return defaultProxy;\n }\n\n // Validate every override key corresponds to a declared activity.\n // Without this, a typo at runtime (or a stale options bag from a renamed\n // activity) silently builds a proxy for a non-existent activity.\n const declared = new Set<string>([\n ...Object.keys(workflowActivities ?? {}),\n ...Object.keys(contractActivities ?? {}),\n ]);\n for (const [name] of overrideEntries) {\n if (!declared.has(name)) {\n throw new Error(\n `activityOptionsByName entry \"${name}\" does not match any declared activity. Available: ${[...declared].join(\", \") || \"none\"}.`,\n );\n }\n }\n\n // Override path: build one proxy per override; combine with the default\n // proxy via a get-trap so unmatched keys still get the default options.\n const overriddenFns: Record<string, ActivityFn> = {};\n for (const [name, override] of overrideEntries) {\n const mergedOptions: ActivityOptions = { ...defaultOptions, ...override };\n const overrideProxy = proxyActivities<Record<string, ActivityFn>>(mergedOptions);\n const fn = overrideProxy[name];\n if (fn !== undefined) {\n overriddenFns[name] = fn;\n }\n }\n\n return new Proxy(overriddenFns, {\n get(target, prop) {\n if (typeof prop !== \"string\") return undefined;\n return target[prop] ?? defaultProxy[prop];\n },\n });\n}\n\n/**\n * Continue-as-new options the typed wrapper does not own. `workflowType` and\n * `taskQueue` are derived from the contract; everything else is forwarded to\n * Temporal's `makeContinueAsNewFunc`.\n */\nexport type TypedContinueAsNewOptions = Omit<ContinueAsNewOptions, \"workflowType\" | \"taskQueue\">;\n\n/**\n * Build the typed `continueAsNew` function bound to the running workflow's\n * contract. Two overloads — same-workflow and cross-contract — share one\n * implementation; the public type signature lives on `WorkflowContext` so\n * call sites are type-safe.\n *\n * Validation runs *before* Temporal's `makeContinueAsNewFunc(...)` is invoked.\n * On failure, throws a `WorkflowInputValidationError` (matching the behaviour\n * of `declareWorkflow`'s incoming-input validation), which surfaces back to\n * Temporal as a workflow failure rather than silently proceeding with an\n * invalid run.\n *\n * Temporal's `continueAsNew` never returns — it throws a `ContinueAsNew`\n * exception that the runtime intercepts. The returned function preserves\n * `Promise<never>` to encode that.\n *\n * @internal\n */\nexport function createContinueAsNew(\n currentContract: ContractDefinition,\n currentWorkflowName: string | number | symbol,\n) {\n return async function continueAsNew(\n arg1: unknown,\n arg2?: unknown,\n arg3?: unknown,\n arg4?: TypedContinueAsNewOptions,\n ): Promise<never> {\n // Cross-contract dispatch is only triggered when the call signature\n // unambiguously matches `(contract, workflowName, args, options?)`:\n //\n // 1. `arg1` is a non-null object that *looks like* a contract — it has a\n // string `taskQueue` and a non-null `workflows` object.\n // 2. `arg2` is a string — the destination workflow name.\n // 3. `arg2` resolves to a workflow definition on `arg1.workflows` with a\n // Standard Schema `input.~standard.validate` function.\n //\n // Without (2)+(3), a same-workflow input that happens to have `taskQueue`\n // and `workflows` keys (or `workflows = null`, where `typeof === \"object\"`)\n // would be silently misclassified. The full triple of structural checks\n // makes the false-positive surface vanishingly small.\n const isCrossContract = looksLikeCrossContractCall(arg1, arg2);\n\n let targetContract: ContractDefinition;\n let targetName: string;\n let rawArgs: unknown;\n let options: TypedContinueAsNewOptions | undefined;\n\n if (isCrossContract) {\n targetContract = arg1 as ContractDefinition;\n targetName = arg2 as string;\n rawArgs = arg3;\n options = arg4;\n } else {\n targetContract = currentContract;\n targetName = String(currentWorkflowName);\n rawArgs = arg1;\n options = arg2 as TypedContinueAsNewOptions | undefined;\n }\n\n const targetDef = targetContract.workflows[targetName];\n if (!targetDef) {\n throw new WorkflowInputValidationError(targetName, [\n {\n message: `continueAsNew target workflow \"${targetName}\" is not declared on the supplied contract.`,\n },\n ]);\n }\n\n const inputResult = await targetDef.input[\"~standard\"].validate(rawArgs);\n if (inputResult.issues) {\n throw new WorkflowInputValidationError(targetName, inputResult.issues);\n }\n\n // workflowType/taskQueue come from the destination contract; user\n // options are spread last so power users can override (e.g. retry,\n // memo). The public TypedContinueAsNewOptions type Omits workflowType\n // and taskQueue so this isn't a footgun on the typed call path.\n const fn = makeContinueAsNewFunc({\n workflowType: targetName,\n taskQueue: targetContract.taskQueue,\n ...options,\n });\n\n await fn(inputResult.value);\n // Unreachable — Temporal's continueAsNew throws to terminate the run.\n /* c8 ignore next */\n return undefined as never;\n };\n}\n\n/**\n * Structural check: does `(arg1, arg2)` look like the\n * `(contract, workflowName, ...)` cross-contract overload of `continueAsNew`?\n *\n * Returns `true` only when:\n * 1. `arg1` is a non-null object with a string `taskQueue` and a non-null\n * object `workflows` (handles `workflows: null`, where\n * `typeof null === \"object\"`).\n * 2. `arg2` is a string.\n *\n * Both halves matter. A same-workflow input that happens to contain\n * `taskQueue` and `workflows` keys would otherwise be misclassified — but\n * none of the same-workflow signatures (`continueAsNew(args)`,\n * `continueAsNew(args, options)`) accept a string as `arg2`, so the\n * second check makes the false-positive surface vanishingly small.\n *\n * We deliberately do *not* check that `arg1.workflows[arg2]` is a valid\n * workflow definition. If it isn't, the dispatcher falls through to the\n * `targetContract.workflows[targetName]` lookup which throws a clear\n * \"target workflow X is not declared\" error — better than silently\n * misrouting a typo back to the current workflow.\n */\nfunction looksLikeCrossContractCall(arg1: unknown, arg2: unknown): boolean {\n if (typeof arg1 !== \"object\" || arg1 === null) return false;\n if (typeof arg2 !== \"string\") return false;\n const candidate = arg1 as Record<string, unknown>;\n if (typeof candidate[\"taskQueue\"] !== \"string\") return false;\n const workflows = candidate[\"workflows\"];\n return typeof workflows === \"object\" && workflows !== null;\n}\n"],"mappings":"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"}
@@ -0,0 +1,453 @@
1
+ let _temporalio_workflow = require("@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 = (0, _temporalio_workflow.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 = (0, _temporalio_workflow.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 (0, _temporalio_workflow.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
+ Object.defineProperty(exports, "ActivityDefinitionNotFoundError", {
353
+ enumerable: true,
354
+ get: function() {
355
+ return ActivityDefinitionNotFoundError;
356
+ }
357
+ });
358
+ Object.defineProperty(exports, "ActivityInputValidationError", {
359
+ enumerable: true,
360
+ get: function() {
361
+ return ActivityInputValidationError;
362
+ }
363
+ });
364
+ Object.defineProperty(exports, "ActivityOutputValidationError", {
365
+ enumerable: true,
366
+ get: function() {
367
+ return ActivityOutputValidationError;
368
+ }
369
+ });
370
+ Object.defineProperty(exports, "ChildWorkflowError", {
371
+ enumerable: true,
372
+ get: function() {
373
+ return ChildWorkflowError;
374
+ }
375
+ });
376
+ Object.defineProperty(exports, "ChildWorkflowNotFoundError", {
377
+ enumerable: true,
378
+ get: function() {
379
+ return ChildWorkflowNotFoundError;
380
+ }
381
+ });
382
+ Object.defineProperty(exports, "QueryInputValidationError", {
383
+ enumerable: true,
384
+ get: function() {
385
+ return QueryInputValidationError;
386
+ }
387
+ });
388
+ Object.defineProperty(exports, "QueryOutputValidationError", {
389
+ enumerable: true,
390
+ get: function() {
391
+ return QueryOutputValidationError;
392
+ }
393
+ });
394
+ Object.defineProperty(exports, "SignalInputValidationError", {
395
+ enumerable: true,
396
+ get: function() {
397
+ return SignalInputValidationError;
398
+ }
399
+ });
400
+ Object.defineProperty(exports, "UpdateInputValidationError", {
401
+ enumerable: true,
402
+ get: function() {
403
+ return UpdateInputValidationError;
404
+ }
405
+ });
406
+ Object.defineProperty(exports, "UpdateOutputValidationError", {
407
+ enumerable: true,
408
+ get: function() {
409
+ return UpdateOutputValidationError;
410
+ }
411
+ });
412
+ Object.defineProperty(exports, "WorkflowCancelledError", {
413
+ enumerable: true,
414
+ get: function() {
415
+ return WorkflowCancelledError;
416
+ }
417
+ });
418
+ Object.defineProperty(exports, "WorkflowInputValidationError", {
419
+ enumerable: true,
420
+ get: function() {
421
+ return WorkflowInputValidationError;
422
+ }
423
+ });
424
+ Object.defineProperty(exports, "WorkflowOutputValidationError", {
425
+ enumerable: true,
426
+ get: function() {
427
+ return WorkflowOutputValidationError;
428
+ }
429
+ });
430
+ Object.defineProperty(exports, "buildRawActivitiesProxy", {
431
+ enumerable: true,
432
+ get: function() {
433
+ return buildRawActivitiesProxy;
434
+ }
435
+ });
436
+ Object.defineProperty(exports, "createContinueAsNew", {
437
+ enumerable: true,
438
+ get: function() {
439
+ return createContinueAsNew;
440
+ }
441
+ });
442
+ Object.defineProperty(exports, "extractHandlerInput", {
443
+ enumerable: true,
444
+ get: function() {
445
+ return extractHandlerInput;
446
+ }
447
+ });
448
+ Object.defineProperty(exports, "formatChildWorkflowValidationMessage", {
449
+ enumerable: true,
450
+ get: function() {
451
+ return formatChildWorkflowValidationMessage;
452
+ }
453
+ });
package/dist/worker.cjs CHANGED
@@ -1,7 +1,6 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
1
2
  let _temporalio_worker = require("@temporalio/worker");
2
3
  let node_url = require("node:url");
3
- let node_path = require("node:path");
4
-
5
4
  //#region src/worker.ts
6
5
  /**
7
6
  * Create a typed Temporal worker with contract-based configuration
@@ -40,9 +39,14 @@ async function createWorker(options) {
40
39
  });
41
40
  }
42
41
  /**
43
- * Helper to create a workflowsPath from a file URL
42
+ * Helper to resolve a workflow file path relative to the current module's URL.
44
43
  *
45
- * Useful for creating the workflowsPath option when using ES modules
44
+ * Useful when using ES modules (`import.meta.url`) to locate workflow files.
45
+ * The `relativePath` should include the file extension explicitly (e.g. `./workflows.js`)
46
+ * to ensure the resolved path is unambiguous in both source and built contexts.
47
+ *
48
+ * @param baseURL - The base URL to resolve from, typically `import.meta.url`
49
+ * @param relativePath - Relative path to the workflows file, **including extension**
46
50
  *
47
51
  * @example
48
52
  * ```ts
@@ -51,15 +55,15 @@ async function createWorker(options) {
51
55
  * const worker = await createWorker({
52
56
  * contract: myContract,
53
57
  * connection,
54
- * workflowsPath: workflowsPathFromURL(import.meta.url, './workflows'),
58
+ * // Include the extension explicitly to work in both source (.ts) and build (.js) contexts
59
+ * workflowsPath: workflowsPathFromURL(import.meta.url, './workflows.js'),
55
60
  * activities,
56
61
  * });
57
62
  * ```
58
63
  */
59
64
  function workflowsPathFromURL(baseURL, relativePath) {
60
- return (0, node_url.fileURLToPath)(new URL(`${relativePath}${(0, node_path.extname)(baseURL)}`, baseURL));
65
+ return (0, node_url.fileURLToPath)(new URL(relativePath, baseURL));
61
66
  }
62
-
63
67
  //#endregion
64
68
  exports.createWorker = createWorker;
65
- exports.workflowsPathFromURL = workflowsPathFromURL;
69
+ exports.workflowsPathFromURL = workflowsPathFromURL;
package/dist/worker.d.cts CHANGED
@@ -1,4 +1,4 @@
1
- import { t as ActivitiesHandler } from "./activity-5pVNjW7l.cjs";
1
+ import { ActivitiesHandler } from "./activity.cjs";
2
2
  import { ContractDefinition } from "@temporal-contract/contract";
3
3
  import { Worker, WorkerOptions } from "@temporalio/worker";
4
4
 
@@ -6,7 +6,7 @@ import { Worker, WorkerOptions } from "@temporalio/worker";
6
6
  /**
7
7
  * Options for creating a Temporal worker
8
8
  */
9
- interface CreateWorkerOptions<TContract extends ContractDefinition> extends Omit<WorkerOptions, "activities" | "taskQueue"> {
9
+ type CreateWorkerOptions<TContract extends ContractDefinition> = Omit<WorkerOptions, "activities" | "taskQueue"> & {
10
10
  /**
11
11
  * The contract definition for this worker
12
12
  */
@@ -15,7 +15,7 @@ interface CreateWorkerOptions<TContract extends ContractDefinition> extends Omit
15
15
  * Activities handler for this worker
16
16
  */
17
17
  activities: ActivitiesHandler<TContract>;
18
- }
18
+ };
19
19
  /**
20
20
  * Create a typed Temporal worker with contract-based configuration
21
21
  *
@@ -46,9 +46,14 @@ interface CreateWorkerOptions<TContract extends ContractDefinition> extends Omit
46
46
  */
47
47
  declare function createWorker<TContract extends ContractDefinition>(options: CreateWorkerOptions<TContract>): Promise<Worker>;
48
48
  /**
49
- * Helper to create a workflowsPath from a file URL
49
+ * Helper to resolve a workflow file path relative to the current module's URL.
50
50
  *
51
- * Useful for creating the workflowsPath option when using ES modules
51
+ * Useful when using ES modules (`import.meta.url`) to locate workflow files.
52
+ * The `relativePath` should include the file extension explicitly (e.g. `./workflows.js`)
53
+ * to ensure the resolved path is unambiguous in both source and built contexts.
54
+ *
55
+ * @param baseURL - The base URL to resolve from, typically `import.meta.url`
56
+ * @param relativePath - Relative path to the workflows file, **including extension**
52
57
  *
53
58
  * @example
54
59
  * ```ts
@@ -57,11 +62,13 @@ declare function createWorker<TContract extends ContractDefinition>(options: Cre
57
62
  * const worker = await createWorker({
58
63
  * contract: myContract,
59
64
  * connection,
60
- * workflowsPath: workflowsPathFromURL(import.meta.url, './workflows'),
65
+ * // Include the extension explicitly to work in both source (.ts) and build (.js) contexts
66
+ * workflowsPath: workflowsPathFromURL(import.meta.url, './workflows.js'),
61
67
  * activities,
62
68
  * });
63
69
  * ```
64
70
  */
65
71
  declare function workflowsPathFromURL(baseURL: string, relativePath: string): string;
66
72
  //#endregion
67
- export { CreateWorkerOptions, createWorker, workflowsPathFromURL };
73
+ export { CreateWorkerOptions, createWorker, workflowsPathFromURL };
74
+ //# sourceMappingURL=worker.d.cts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"worker.d.cts","names":[],"sources":["../src/worker.ts"],"mappings":";;;;;;;AASA;KAAY,mBAAA,mBAAsC,kBAAA,IAAsB,IAAA,CACtE,aAAA;EAD6B;;;EAO7B,QAAA,EAAU,SAAA;EAAA;;;EAKV,UAAA,EAAY,iBAAA,CAAkB,SAAA;AAAA;;;;;;;;;;;;AA+BhC;;;;;;;;;;;;;;;;;iBAAsB,YAAA,mBAA+B,kBAAA,CAAA,CACnD,OAAA,EAAS,mBAAA,CAAoB,SAAA,IAC5B,OAAA,CAAQ,MAAA;;AAkCX;;;;;;;;;;;;;;;;;;;;;;iBAAgB,oBAAA,CAAqB,OAAA,UAAiB,YAAA"}
package/dist/worker.d.mts CHANGED
@@ -1,4 +1,4 @@
1
- import { t as ActivitiesHandler } from "./activity-BUEBZ7SL.mjs";
1
+ import { ActivitiesHandler } from "./activity.mjs";
2
2
  import { Worker, WorkerOptions } from "@temporalio/worker";
3
3
  import { ContractDefinition } from "@temporal-contract/contract";
4
4
 
@@ -6,7 +6,7 @@ import { ContractDefinition } from "@temporal-contract/contract";
6
6
  /**
7
7
  * Options for creating a Temporal worker
8
8
  */
9
- interface CreateWorkerOptions<TContract extends ContractDefinition> extends Omit<WorkerOptions, "activities" | "taskQueue"> {
9
+ type CreateWorkerOptions<TContract extends ContractDefinition> = Omit<WorkerOptions, "activities" | "taskQueue"> & {
10
10
  /**
11
11
  * The contract definition for this worker
12
12
  */
@@ -15,7 +15,7 @@ interface CreateWorkerOptions<TContract extends ContractDefinition> extends Omit
15
15
  * Activities handler for this worker
16
16
  */
17
17
  activities: ActivitiesHandler<TContract>;
18
- }
18
+ };
19
19
  /**
20
20
  * Create a typed Temporal worker with contract-based configuration
21
21
  *
@@ -46,9 +46,14 @@ interface CreateWorkerOptions<TContract extends ContractDefinition> extends Omit
46
46
  */
47
47
  declare function createWorker<TContract extends ContractDefinition>(options: CreateWorkerOptions<TContract>): Promise<Worker>;
48
48
  /**
49
- * Helper to create a workflowsPath from a file URL
49
+ * Helper to resolve a workflow file path relative to the current module's URL.
50
50
  *
51
- * Useful for creating the workflowsPath option when using ES modules
51
+ * Useful when using ES modules (`import.meta.url`) to locate workflow files.
52
+ * The `relativePath` should include the file extension explicitly (e.g. `./workflows.js`)
53
+ * to ensure the resolved path is unambiguous in both source and built contexts.
54
+ *
55
+ * @param baseURL - The base URL to resolve from, typically `import.meta.url`
56
+ * @param relativePath - Relative path to the workflows file, **including extension**
52
57
  *
53
58
  * @example
54
59
  * ```ts
@@ -57,11 +62,13 @@ declare function createWorker<TContract extends ContractDefinition>(options: Cre
57
62
  * const worker = await createWorker({
58
63
  * contract: myContract,
59
64
  * connection,
60
- * workflowsPath: workflowsPathFromURL(import.meta.url, './workflows'),
65
+ * // Include the extension explicitly to work in both source (.ts) and build (.js) contexts
66
+ * workflowsPath: workflowsPathFromURL(import.meta.url, './workflows.js'),
61
67
  * activities,
62
68
  * });
63
69
  * ```
64
70
  */
65
71
  declare function workflowsPathFromURL(baseURL: string, relativePath: string): string;
66
72
  //#endregion
67
- export { CreateWorkerOptions, createWorker, workflowsPathFromURL };
73
+ export { CreateWorkerOptions, createWorker, workflowsPathFromURL };
74
+ //# sourceMappingURL=worker.d.mts.map