@lostgradient/weft 0.7.0 → 0.9.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.
Files changed (141) hide show
  1. package/README.md +9 -3
  2. package/dist/cli/generated/operation-client.generated.d.ts +1 -0
  3. package/dist/cli-main.js +78 -78
  4. package/dist/core/context/activity-retry-state.d.ts +6 -5
  5. package/dist/core/context/activity-retry-state.js +31 -21
  6. package/dist/core/context/durable-activity.d.ts +117 -0
  7. package/dist/core/context/durable-activity.js +79 -0
  8. package/dist/core/context/durable-operations.js +1 -1
  9. package/dist/core/context/index.d.ts +1 -0
  10. package/dist/core/context/index.js +2 -0
  11. package/dist/core/context/operation-request.d.ts +17 -0
  12. package/dist/core/context/parallel-operations.js +1 -0
  13. package/dist/core/context/run-operation-cached-request.d.ts +8 -0
  14. package/dist/core/context/run-operation-cached-request.js +59 -0
  15. package/dist/core/context/run-operation.d.ts +23 -5
  16. package/dist/core/context/run-operation.js +63 -47
  17. package/dist/core/context/speculative-child.js +1 -0
  18. package/dist/core/context/types.d.ts +1 -0
  19. package/dist/core/engine/activity-heartbeat-tracking.d.ts +8 -17
  20. package/dist/core/engine/activity-heartbeat-tracking.js +12 -2
  21. package/dist/core/engine/activity-reconciliation.d.ts +1 -0
  22. package/dist/core/engine/activity-reconciliation.js +7 -2
  23. package/dist/core/engine/anonymous-signal-sequence.js +6 -6
  24. package/dist/core/engine/async-activity-completion.d.ts +5 -7
  25. package/dist/core/engine/async-activity-completion.js +13 -9
  26. package/dist/core/engine/bulk-operations-purge.js +2 -1
  27. package/dist/core/engine/bulk-operations.js +18 -36
  28. package/dist/core/engine/callback-checkpoint-persistence.d.ts +3 -0
  29. package/dist/core/engine/callback-checkpoint-persistence.js +25 -0
  30. package/dist/core/engine/callback-creators-bundles.js +5 -2
  31. package/dist/core/engine/checkpoint-io.d.ts +4 -1
  32. package/dist/core/engine/checkpoint-io.js +19 -10
  33. package/dist/core/engine/completed-review-storage.d.ts +2 -1
  34. package/dist/core/engine/completed-review-storage.js +4 -3
  35. package/dist/core/engine/disposal.js +1 -0
  36. package/dist/core/engine/engine-internal-types.d.ts +1 -0
  37. package/dist/core/engine/index.d.ts +31 -0
  38. package/dist/core/engine/index.js +19 -10
  39. package/dist/core/engine/inline-launch-queue.js +1 -1
  40. package/dist/core/engine/internals.d.ts +25 -2
  41. package/dist/core/engine/lease-manager.js +2 -2
  42. package/dist/core/engine/lifecycle/fork-helpers.js +1 -0
  43. package/dist/core/engine/lifecycle/resume.js +6 -0
  44. package/dist/core/engine/lifecycle/start-exec.d.ts +2 -2
  45. package/dist/core/engine/lifecycle/start-exec.js +6 -4
  46. package/dist/core/engine/lifecycle/start.js +1 -0
  47. package/dist/core/engine/lifecycle/transition.js +6 -0
  48. package/dist/core/engine/memo-durable-activity.d.ts +11 -0
  49. package/dist/core/engine/memo-durable-activity.js +282 -0
  50. package/dist/core/engine/operations-activity.d.ts +6 -2
  51. package/dist/core/engine/operations-activity.js +24 -10
  52. package/dist/core/engine/operations-data.d.ts +4 -1
  53. package/dist/core/engine/operations-data.js +3 -3
  54. package/dist/core/engine/operations-time.d.ts +2 -2
  55. package/dist/core/engine/operations-time.js +40 -6
  56. package/dist/core/engine/reviews.js +7 -4
  57. package/dist/core/engine/schedule-timer.js +2 -0
  58. package/dist/core/engine/schedules.js +3 -0
  59. package/dist/core/engine/storage-io.js +1 -1
  60. package/dist/core/engine/termination/cleanup.js +15 -13
  61. package/dist/core/engine/termination/finalizer-activity.d.ts +1 -1
  62. package/dist/core/engine/termination/finalizer-activity.js +5 -1
  63. package/dist/core/engine/termination/finalizer.js +1 -1
  64. package/dist/core/engine/validation/schedule-options.d.ts +9 -0
  65. package/dist/core/engine/validation/schedule-options.js +59 -0
  66. package/dist/core/engine/validation/schedule.d.ts +3 -8
  67. package/dist/core/engine/validation/schedule.js +40 -56
  68. package/dist/core/engine/validation.js +1 -0
  69. package/dist/core/execution-strategy.d.ts +1 -0
  70. package/dist/core/inline-execution-strategy.context-options.d.ts +1 -0
  71. package/dist/core/inline-execution-strategy.context-options.js +3 -0
  72. package/dist/core/json.js +1 -1
  73. package/dist/core/types/activity.d.ts +11 -0
  74. package/dist/core/types/checkpoint.d.ts +1 -0
  75. package/dist/core/types/schedules.d.ts +10 -0
  76. package/dist/core/types/state.d.ts +6 -0
  77. package/dist/core/types/workflow-context.d.ts +13 -0
  78. package/dist/core/weft-error.d.ts +1 -1
  79. package/dist/core/weft-error.js +2 -0
  80. package/dist/core/worker-execution-strategy.d.ts +1 -0
  81. package/dist/core/worker-inbound-message.d.ts +1 -0
  82. package/dist/core/worker-inbound-message.js +3 -0
  83. package/dist/index.d.ts +2 -1
  84. package/dist/index.js +6 -0
  85. package/dist/json-schema.js +2 -2
  86. package/dist/mcp/cli.js +32 -32
  87. package/dist/observability/index.js +2 -2
  88. package/dist/runtime/portable.d.ts +1 -1
  89. package/dist/server/handler.js +27 -27
  90. package/dist/server/index.d.ts +2 -0
  91. package/dist/server/index.js +32 -32
  92. package/dist/server/operations/create-schedule.d.ts +2 -0
  93. package/dist/server/operations/create-schedule.js +13 -2
  94. package/dist/server/rest-binding.d.ts +1 -1
  95. package/dist/server/runtime/task-dispatch.js +6 -0
  96. package/dist/server/runtime/task-polling.js +9 -1
  97. package/dist/server/runtime/task-reconciliation.js +2 -1
  98. package/dist/server/runtime/websocket-worker.js +7 -2
  99. package/dist/server/serve-internals.d.ts +28 -0
  100. package/dist/server/serve-internals.js +4 -2
  101. package/dist/server/task-queue-types.d.ts +2 -0
  102. package/dist/server/task-state.d.ts +4 -0
  103. package/dist/service-worker/index.d.ts +15 -14
  104. package/dist/service-worker/index.js +28 -28
  105. package/dist/service-worker/scheduler.d.ts +41 -1
  106. package/dist/service-worker/setup.d.ts +18 -1
  107. package/dist/service-worker/setup.js +7 -4
  108. package/dist/storage/auto.d.ts +36 -18
  109. package/dist/storage/auto.js +1 -1
  110. package/dist/storage/compressed-storage.js +1 -1
  111. package/dist/storage/indexeddb.d.ts +6 -1
  112. package/dist/storage/indexeddb.js +1 -1
  113. package/dist/storage/interface.js +1 -1
  114. package/dist/storage/lmdb.js +1 -1
  115. package/dist/storage/memory.js +1 -1
  116. package/dist/storage/neon.js +1 -1
  117. package/dist/storage/resolve.js +1 -1
  118. package/dist/storage/scoped-storage.js +1 -1
  119. package/dist/storage/testing.js +1 -1
  120. package/dist/storage/turso.js +1 -1
  121. package/dist/storage/typed-storage.d.ts +1 -1
  122. package/dist/storage/typed-storage.js +1 -1
  123. package/dist/storage/web-extension.d.ts +1 -1
  124. package/dist/storage/web-extension.js +1 -1
  125. package/dist/testing/index.js +32 -32
  126. package/dist/version.d.ts +1 -1
  127. package/dist/version.js +1 -1
  128. package/dist/worker/execute-with-interceptors.d.ts +9 -3
  129. package/dist/worker/execute-with-interceptors.js +14 -2
  130. package/dist/worker/long-poll.d.ts +2 -1
  131. package/dist/worker/long-poll.js +1 -1
  132. package/dist/worker/protocol-messages.d.ts +2 -0
  133. package/dist/worker/protocol-schemas.d.ts +8 -0
  134. package/dist/worker/protocol-schemas.js +1 -0
  135. package/dist/worker/protocol.js +1 -1
  136. package/dist/worker/remote-activity-context.d.ts +2 -0
  137. package/dist/workers/activity-runner.d.ts +2 -0
  138. package/dist/workers/activity-runner.js +9 -1
  139. package/dist/workers/workflow-runner.d.ts +2 -1
  140. package/dist/workers/workflow-runner.js +1 -0
  141. package/package.json +1 -1
@@ -1,6 +1,6 @@
1
1
  import { parseDuration } from "../../scheduler.js";
2
2
  import { withPerAttemptTimeout } from "../activity-per-attempt-timeout.js";
3
- export async function runFinalizerActivity(finalizer, input, attempt, shutdownSignal) {
3
+ export async function runFinalizerActivity(finalizer, input, attempt, shutdownSignal, workflowExecutionToken) {
4
4
  const perAttemptTimeoutMs = finalizer.timeout === void 0 ? void 0 : parseDuration(finalizer.timeout), attemptController = new AbortController, relayShutdownAbort = () => attemptController.abort(shutdownSignal.reason);
5
5
  if (shutdownSignal.aborted)
6
6
  attemptController.abort(shutdownSignal.reason);
@@ -8,6 +8,10 @@ export async function runFinalizerActivity(finalizer, input, attempt, shutdownSi
8
8
  shutdownSignal.addEventListener("abort", relayShutdownAbort, { once: !0 });
9
9
  const activityContext = {
10
10
  signal: attemptController.signal,
11
+ ...workflowExecutionToken !== void 0 && {
12
+ workflowExecutionToken,
13
+ activityAttemptToken: `${workflowExecutionToken}:finalizer:${String(attempt)}`
14
+ },
11
15
  heartbeat: () => {},
12
16
  completeAsync: () => {
13
17
  throw Error(`Finalizer "${finalizer.name}" called ctx.completeAsync(), which is not supported in a workflow finalizer: the finalizer runs after the workflow is already terminal, so there is no durable step to complete out of band. Run the teardown synchronously instead.`);
@@ -103,7 +103,7 @@ async function driveResolvedTeardown(internals, workflowId, token, drive, callba
103
103
  await rearmTeardownTimer(internals, workflowId, token, TEARDOWN_SELF_HEAL_DELAY_MS);
104
104
  return;
105
105
  }
106
- const result = await runFinalizerActivity(finalizer, finalizerInput, attempt, internals.abortController.signal);
106
+ const result = await runFinalizerActivity(finalizer, finalizerInput, attempt, internals.abortController.signal, state.workflowExecutionToken);
107
107
  if (result.ok) {
108
108
  await settleTeardownSuccess(internals, workflowId, state.type, token, attempt, runningBytes, callbacks);
109
109
  return;
@@ -0,0 +1,9 @@
1
+ import type { ScheduleOptions, ScheduleOverlapPolicy } from '../../types.ts';
2
+ export declare const SCHEDULE_OVERLAP_POLICIES: Set<ScheduleOverlapPolicy>;
3
+ type NormalizedScheduleOptions = Required<Pick<ScheduleOptions, 'overlap' | 'backfill'>> & {
4
+ id?: string;
5
+ description?: string;
6
+ jitterMs?: number;
7
+ };
8
+ export declare function normalizeScheduleOptions(options: ScheduleOptions | undefined): NormalizedScheduleOptions;
9
+ export {};
@@ -0,0 +1,59 @@
1
+ import { parseDuration } from "../../scheduler.js";
2
+ import { coerceStartWorkflowId } from "../../start-workflow-validation.js";
3
+ export const SCHEDULE_OVERLAP_POLICIES = new Set([
4
+ "skip",
5
+ "queue",
6
+ "cancel-running",
7
+ "allow"
8
+ ]);
9
+ export function normalizeScheduleOptions(options) {
10
+ if (options === void 0)
11
+ return { overlap: "skip", backfill: !1 };
12
+ if (typeof options !== "object" || options === null)
13
+ throw Error("options must be an object when provided");
14
+ return {
15
+ overlap: normalizeScheduleOverlap(options.overlap),
16
+ backfill: normalizeScheduleBackfill(options.backfill),
17
+ ...options.id !== void 0 && { id: coerceStartWorkflowId(options.id, "options.id") },
18
+ ...options.description !== void 0 && {
19
+ description: normalizeScheduleDescription(options.description)
20
+ },
21
+ ...options.jitter !== void 0 && {
22
+ jitterMs: normalizeScheduleJitter(options.jitter, "options.jitter")
23
+ }
24
+ };
25
+ }
26
+ function normalizeScheduleDescription(description) {
27
+ if (typeof description !== "string")
28
+ throw Error("options.description must be a string when provided");
29
+ return description;
30
+ }
31
+ function normalizeScheduleOverlap(overlap) {
32
+ if (overlap === void 0)
33
+ return "skip";
34
+ if (!SCHEDULE_OVERLAP_POLICIES.has(overlap))
35
+ throw Error(`options.overlap must be one of ${[...SCHEDULE_OVERLAP_POLICIES].join(", ")}`);
36
+ return overlap;
37
+ }
38
+ function normalizeScheduleBackfill(backfill) {
39
+ if (backfill === void 0)
40
+ return !1;
41
+ if (typeof backfill !== "boolean")
42
+ throw Error("options.backfill must be a boolean when provided");
43
+ return backfill;
44
+ }
45
+ function normalizeScheduleJitter(value, fieldName) {
46
+ if (typeof value !== "string" && typeof value !== "number")
47
+ throw Error(`${fieldName} must be a duration string or a number of milliseconds`);
48
+ let milliseconds;
49
+ try {
50
+ milliseconds = parseDuration(value);
51
+ } catch (error) {
52
+ const message = error instanceof Error ? error.message : String(error);
53
+ throw Error(`Invalid ${fieldName}: ${message}`, { cause: error });
54
+ }
55
+ const jitterMs = Math.ceil(milliseconds);
56
+ if (!Number.isSafeInteger(jitterMs) || jitterMs <= 0)
57
+ throw Error(`${fieldName} must resolve to a positive number of milliseconds`);
58
+ return jitterMs;
59
+ }
@@ -1,15 +1,11 @@
1
- import type { ScheduleFilter, ScheduleOptions, ScheduleOverlapPolicy, ScheduleSpec, ScheduleState, ScheduleStatus } from '../../types.ts';
1
+ import type { ScheduleFilter, ScheduleOverlapPolicy, ScheduleSpec, ScheduleState, ScheduleStatus } from '../../types.ts';
2
+ export { normalizeScheduleOptions, SCHEDULE_OVERLAP_POLICIES } from './schedule-options.ts';
2
3
  export declare const SCHEDULE_STATUSES: Set<ScheduleStatus>;
3
- export declare const SCHEDULE_OVERLAP_POLICIES: Set<ScheduleOverlapPolicy>;
4
4
  export declare function isValidScheduleTimestamp(value: unknown): value is number;
5
5
  export declare function isValidScheduleStatus(value: unknown): value is ScheduleStatus;
6
6
  export declare function isValidScheduleOverlapPolicy(value: unknown): value is ScheduleOverlapPolicy;
7
7
  export declare function isValidScheduleIdentifier(value: unknown): value is string;
8
8
  export declare function coerceScheduleId(scheduleId: string, fieldName: string): string;
9
- export declare function normalizeScheduleOptions(options: ScheduleOptions | undefined): Required<Pick<ScheduleOptions, 'overlap' | 'backfill'>> & {
10
- id?: string;
11
- jitterMs?: number;
12
- };
13
9
  /**
14
10
  * A recurrence specification normalized into the discriminated cadence the
15
11
  * engine persists. Interval periods are resolved to whole milliseconds.
@@ -33,7 +29,6 @@ export declare function decodeScheduleIdentityFields(decoded: Record<string, unk
33
29
  cronExpression?: string;
34
30
  intervalMs?: number;
35
31
  }) | null;
36
- type ScheduleRuntimeFields = Pick<ScheduleState, 'backfill' | 'jitterMs' | 'createdAt' | 'updatedAt' | 'lastFireAt' | 'lastMissedFireAt' | 'nextFireAt' | 'currentWorkflowId' | 'missedFireCount' | 'queuedRuns'>;
32
+ type ScheduleRuntimeFields = Pick<ScheduleState, 'description' | 'backfill' | 'jitterMs' | 'createdAt' | 'updatedAt' | 'lastFireAt' | 'lastMissedFireAt' | 'nextFireAt' | 'currentWorkflowId' | 'missedFireCount' | 'queuedRuns'>;
37
33
  export declare function decodeScheduleRuntimeFields(decoded: Record<string, unknown>, scheduleId: string): ScheduleRuntimeFields | null;
38
34
  export declare function decodeScheduleState(bytes: Uint8Array): ScheduleState | null;
39
- export {};
@@ -3,12 +3,9 @@ import { isRecord } from "../../debug-output.js";
3
3
  import { parseCronExpression } from "../../schedule.js";
4
4
  import { parseDuration } from "../../scheduler.js";
5
5
  import { coerceStartWorkflowId } from "../../start-workflow-validation.js";
6
- export const SCHEDULE_STATUSES = new Set(["active", "paused", "cancelled"]), SCHEDULE_OVERLAP_POLICIES = new Set([
7
- "skip",
8
- "queue",
9
- "cancel-running",
10
- "allow"
11
- ]);
6
+ import { SCHEDULE_OVERLAP_POLICIES } from "./schedule-options.js";
7
+ export { normalizeScheduleOptions, SCHEDULE_OVERLAP_POLICIES } from "./schedule-options.js";
8
+ export const SCHEDULE_STATUSES = new Set(["active", "paused", "cancelled"]);
12
9
  export function isValidScheduleTimestamp(value) {
13
10
  return typeof value === "number" && Number.isSafeInteger(value) && value >= 0;
14
11
  }
@@ -31,46 +28,6 @@ export function isValidScheduleIdentifier(value) {
31
28
  export function coerceScheduleId(scheduleId, fieldName) {
32
29
  return coerceStartWorkflowId(scheduleId, fieldName);
33
30
  }
34
- export function normalizeScheduleOptions(options) {
35
- if (options === void 0)
36
- return { overlap: "skip", backfill: !1 };
37
- if (typeof options !== "object" || options === null)
38
- throw Error("options must be an object when provided");
39
- const { id, overlap, backfill, jitter } = options, normalizedOptions = {
40
- overlap: "skip",
41
- backfill: !1
42
- };
43
- if (id !== void 0)
44
- normalizedOptions.id = coerceScheduleId(id, "options.id");
45
- if (overlap !== void 0) {
46
- if (!SCHEDULE_OVERLAP_POLICIES.has(overlap))
47
- throw Error(`options.overlap must be one of ${[...SCHEDULE_OVERLAP_POLICIES].join(", ")}`);
48
- normalizedOptions.overlap = overlap;
49
- }
50
- if (backfill !== void 0) {
51
- if (typeof backfill !== "boolean")
52
- throw Error("options.backfill must be a boolean when provided");
53
- normalizedOptions.backfill = backfill;
54
- }
55
- if (jitter !== void 0)
56
- normalizedOptions.jitterMs = normalizeScheduleJitter(jitter, "options.jitter");
57
- return normalizedOptions;
58
- }
59
- function normalizeScheduleJitter(value, fieldName) {
60
- if (typeof value !== "string" && typeof value !== "number")
61
- throw Error(`${fieldName} must be a duration string or a number of milliseconds`);
62
- let milliseconds;
63
- try {
64
- milliseconds = parseDuration(value);
65
- } catch (error) {
66
- const message = error instanceof Error ? error.message : String(error);
67
- throw Error(`Invalid ${fieldName}: ${message}`, { cause: error });
68
- }
69
- const jitterMs = Math.ceil(milliseconds);
70
- if (!Number.isSafeInteger(jitterMs) || jitterMs <= 0)
71
- throw Error(`${fieldName} must resolve to a positive number of milliseconds`);
72
- return jitterMs;
73
- }
74
31
  function normalizeIntervalEvery(every) {
75
32
  if (typeof every !== "string" && typeof every !== "number")
76
33
  throw Error('Schedule interval "every" must be a duration string or a number of milliseconds');
@@ -188,6 +145,16 @@ function decodeScheduleBackfill(decoded, scheduleId) {
188
145
  }
189
146
  return backfill;
190
147
  }
148
+ function decodeScheduleDescription(decoded, scheduleId) {
149
+ const description = decoded.description;
150
+ if (description === void 0)
151
+ return;
152
+ if (typeof description !== "string") {
153
+ rejectInvalidScheduleRecord(scheduleId, "with invalid description");
154
+ return null;
155
+ }
156
+ return description;
157
+ }
191
158
  function decodeScheduleJitterMs(decoded, scheduleId) {
192
159
  const jitterMs = decoded.jitterMs;
193
160
  if (jitterMs === void 0)
@@ -255,13 +222,35 @@ function decodeScheduleMissedFireCount(decoded, scheduleId) {
255
222
  }
256
223
  return missedFireCount;
257
224
  }
258
- export function decodeScheduleRuntimeFields(decoded, scheduleId) {
225
+ function decodeScheduleQueueFields(decoded, scheduleId) {
226
+ const queuedRuns = decodeScheduleQueuedRuns(decoded, scheduleId);
227
+ if (queuedRuns === null)
228
+ return null;
229
+ const missedFireCount = decodeScheduleMissedFireCount(decoded, scheduleId);
230
+ if (missedFireCount === null)
231
+ return null;
232
+ return { missedFireCount, queuedRuns };
233
+ }
234
+ function decodeScheduleOptionFields(decoded, scheduleId) {
235
+ const description = decodeScheduleDescription(decoded, scheduleId);
236
+ if (description === null)
237
+ return null;
259
238
  const backfill = decodeScheduleBackfill(decoded, scheduleId);
260
239
  if (backfill === null)
261
240
  return null;
262
241
  const jitterMs = decodeScheduleJitterMs(decoded, scheduleId);
263
242
  if (jitterMs === null)
264
243
  return null;
244
+ return {
245
+ ...description !== void 0 && { description },
246
+ backfill,
247
+ ...jitterMs !== void 0 && { jitterMs }
248
+ };
249
+ }
250
+ export function decodeScheduleRuntimeFields(decoded, scheduleId) {
251
+ const optionFields = decodeScheduleOptionFields(decoded, scheduleId);
252
+ if (optionFields === null)
253
+ return null;
265
254
  const timestamps = decodeScheduleTimestamps(decoded, scheduleId);
266
255
  if (timestamps === null)
267
256
  return null;
@@ -271,20 +260,15 @@ export function decodeScheduleRuntimeFields(decoded, scheduleId) {
271
260
  const currentWorkflow = decodeScheduleCurrentWorkflowId(decoded, scheduleId);
272
261
  if (!currentWorkflow.ok)
273
262
  return null;
274
- const queuedRuns = decodeScheduleQueuedRuns(decoded, scheduleId);
275
- if (queuedRuns === null)
276
- return null;
277
- const missedFireCount = decodeScheduleMissedFireCount(decoded, scheduleId);
278
- if (missedFireCount === null)
263
+ const queueFields = decodeScheduleQueueFields(decoded, scheduleId);
264
+ if (queueFields === null)
279
265
  return null;
280
266
  return {
281
- backfill,
282
- ...jitterMs !== void 0 && { jitterMs },
267
+ ...optionFields,
283
268
  ...timestamps,
284
269
  nextFireAt: nextFireAt.value,
285
270
  ...currentWorkflow.value !== void 0 && { currentWorkflowId: currentWorkflow.value },
286
- missedFireCount,
287
- queuedRuns
271
+ ...queueFields
288
272
  };
289
273
  }
290
274
  export function decodeScheduleState(bytes) {
@@ -26,6 +26,7 @@ const WORKFLOW_STATE_FIELD_NAMES = new Set(defineCompleteWorkflowStateFieldNames
26
26
  "failureCategory",
27
27
  "terminationReason",
28
28
  "versionTuple",
29
+ "workflowExecutionToken",
29
30
  "executionStateOwnerId",
30
31
  "createdAt",
31
32
  "startedAt",
@@ -76,6 +76,7 @@ export interface ExecutionStrategy extends Disposable, AsyncDisposable {
76
76
  */
77
77
  startWorkflow(parameters: {
78
78
  workflowId: string;
79
+ workflowExecutionToken?: string;
79
80
  workflowType: string;
80
81
  input: unknown;
81
82
  checkpoint: ArrayBuffer | Uint8Array;
@@ -45,6 +45,7 @@ export type InlineWorkflowRegistration = NonNullable<ReturnType<InlineExecutionD
45
45
  /** Parameters for starting a workflow run on the inline strategy. */
46
46
  export type InlineStartWorkflowParameters = {
47
47
  workflowId: string;
48
+ workflowExecutionToken?: string;
48
49
  workflowType: string;
49
50
  input: unknown;
50
51
  checkpoint: ArrayBuffer | Uint8Array;
@@ -1,6 +1,9 @@
1
1
  export function createInlineContextOptions(dependencies, registration, parameters, workflowAbort) {
2
2
  return {
3
3
  workflowId: parameters.workflowId,
4
+ ...parameters.workflowExecutionToken !== void 0 && {
5
+ workflowExecutionToken: parameters.workflowExecutionToken
6
+ },
4
7
  workflowType: parameters.workflowType,
5
8
  startedAt: parameters.startedAt ?? dependencies.getNow(),
6
9
  abortController: workflowAbort,
package/dist/core/json.js CHANGED
@@ -33,7 +33,7 @@ function isJSONPrimitive(value) {
33
33
  if (value === null)
34
34
  return !0;
35
35
  if (typeof value === "number")
36
- return Number.isFinite(value);
36
+ return Number.isFinite(value) && !Object.is(value, -0);
37
37
  return typeof value === "string" || typeof value === "boolean";
38
38
  }
39
39
  function isUnsupportedJSONType(value) {
@@ -47,6 +47,17 @@ export type ActivityFunction<TInput = unknown, TOutput = unknown> = (input: TInp
47
47
  */
48
48
  export interface ActivityContext {
49
49
  signal: AbortSignal;
50
+ /**
51
+ * Durable token for the workflow run that launched this activity. It changes
52
+ * when a stable workflow id is replaced with `onTerminalConflict: 'start-new'`
53
+ * and stays stable for recovery of the same run.
54
+ */
55
+ workflowExecutionToken?: string;
56
+ /**
57
+ * Token for this specific activity dispatch attempt. It changes on retry and
58
+ * can be copied into external writes to reject stale late completions.
59
+ */
60
+ activityAttemptToken?: string;
50
61
  heartbeat(details?: unknown): void;
51
62
  /**
52
63
  * The heartbeat payload recorded by the PREVIOUS attempt of this activity, or
@@ -198,6 +198,7 @@ export type WorkerInboundMessage = {
198
198
  turnId?: number;
199
199
  maxProtocolMessageBytes?: number;
200
200
  workflowId: WorkflowId;
201
+ workflowExecutionToken?: string;
201
202
  workflowType: string;
202
203
  checkpoint: ArrayBuffer;
203
204
  input: unknown;
@@ -53,6 +53,7 @@ export type ScheduleSpec = {
53
53
  * schedule identifier; `overlap` controls what happens when a tick fires while a
54
54
  * previous run is still active; `backfill` controls missed ticks after downtime;
55
55
  * `jitter` deterministically spreads each occurrence's effective dispatch time.
56
+ * `description` stores a human-readable operator label with the schedule.
56
57
  *
57
58
  * @example
58
59
  * ```ts
@@ -65,6 +66,7 @@ export type ScheduleSpec = {
65
66
  * overlap: 'skip',
66
67
  * backfill: false,
67
68
  * jitter: '30s',
69
+ * description: 'Generate the daily report',
68
70
  * };
69
71
  * const handle = await engine.schedule('report', null, '0 9 * * *', options);
70
72
  * void handle;
@@ -72,6 +74,8 @@ export type ScheduleSpec = {
72
74
  */
73
75
  export interface ScheduleOptions {
74
76
  id?: string;
77
+ /** Human-readable operator description stored with this schedule. */
78
+ description?: string;
75
79
  overlap?: ScheduleOverlapPolicy;
76
80
  /**
77
81
  * When `false` (the default), a tick that is more than one second late is
@@ -118,6 +122,8 @@ export type ScheduleDefinition<TInput = unknown> = ScheduleSpec & {
118
122
  workflow: string | WorkflowDefinition<TInput>;
119
123
  input: TInput;
120
124
  id?: string;
125
+ /** Human-readable operator description stored with this schedule. */
126
+ description?: string;
121
127
  overlapPolicy?: ScheduleOverlapPolicy;
122
128
  backfill?: boolean;
123
129
  jitter?: Duration;
@@ -142,6 +148,8 @@ export interface ScheduleState {
142
148
  id: string;
143
149
  workflowType: string;
144
150
  input: unknown;
151
+ /** Human-readable operator description stored with this schedule. */
152
+ description?: string;
145
153
  /**
146
154
  * Cron expression driving the cadence for cron-based schedules. Present when
147
155
  * `intervalMs` is absent; the two are mutually exclusive.
@@ -179,6 +187,8 @@ export interface ScheduleState {
179
187
  export interface ScheduleSummary {
180
188
  id: string;
181
189
  workflowType: string;
190
+ /** Human-readable operator description stored with this schedule. */
191
+ description?: string;
182
192
  /** Cron expression for cron-based schedules; absent for interval schedules. */
183
193
  cronExpression?: string;
184
194
  /** Interval period in milliseconds for interval-based schedules; absent for cron schedules. */
@@ -53,6 +53,12 @@ export interface WorkflowState {
53
53
  * detect version drift.
54
54
  */
55
55
  versionTuple: WorkflowVersionTuple;
56
+ /**
57
+ * Durable token identifying this concrete workflow run. It changes when a
58
+ * stable workflow id is reused with `onTerminalConflict: 'start-new'`, and
59
+ * stays stable for the same run across recovery.
60
+ */
61
+ workflowExecutionToken?: string;
56
62
  /**
57
63
  * Owner identifier for execution-scoped durable state. Top-level workflows
58
64
  * own their own execution state; durable child workflows inherit the
@@ -54,6 +54,13 @@ export type RunAllResult<TBranches extends Record<string, WorkflowRunAllBranch>>
54
54
  */
55
55
  export interface WorkflowContext<TActivities extends ActivityMap = {}, TSignals extends SignalMap = {}, TUpdates extends UpdateMap = {}, TQueries extends QueryMap = {}, TSearchAttributes extends SearchAttributeSchema = {}, TServices = unknown> {
56
56
  readonly workflowId: WorkflowId;
57
+ /**
58
+ * Durable token for this concrete run. A stable workflow id reused with
59
+ * `onTerminalConflict: 'start-new'` receives a new token, while recovery of the
60
+ * same run keeps the token. Store this with external side effects so late
61
+ * activity writes or finalizer cleanup can prove they still belong to this run.
62
+ */
63
+ readonly workflowExecutionToken: string | undefined;
57
64
  /**
58
65
  * The registered workflow type name for this run (the `name` field from
59
66
  * `workflow({ name: '...' })`). Useful for logging and self-inspection
@@ -233,6 +240,12 @@ export interface WorkflowContext<TActivities extends ActivityMap = {}, TSignals
233
240
  * Handlers run in registration order; async handlers are awaited; failures
234
241
  * are swallowed — the workflow still finalizes as cancelled.
235
242
  *
243
+ * For inline workflows, `engine.cancel(id)` aborts {@link WorkflowContext.signal}
244
+ * promptly before in-memory execution state is evicted. A handler registered
245
+ * on the live context then runs after the cancelled state commits and before
246
+ * `cancel()` settles. Work that ignores the abort signal is still cooperative
247
+ * JavaScript and cannot be force-interrupted.
248
+ *
236
249
  * **Best-effort only**: handlers run outside the durable effect log and are
237
250
  * not retried. Side effects in handlers are not replay-safe, and registered
238
251
  * handlers are not restored after an engine restart. A hard cancel or an
@@ -25,7 +25,7 @@
25
25
  * }
26
26
  * ```
27
27
  */
28
- export type WeftErrorCode = 'WorkflowAlreadyExistsError' | 'BulkDeleteRequiresTerminalWorkflowsError' | 'BulkOperationConfirmationError' | 'WorkflowTypeNotRegisteredForRecoveryError' | 'EngineCreateNameMismatchError' | 'EngineDisposedError' | 'WorkflowNotFoundError' | 'WorkflowNotRegisteredError' | 'WorkflowConcurrencyLimitExceededError' | 'WorkflowSuspendNotSupportedError' | 'ActivityResolutionError' | 'BranchTopologyChangedError' | 'PersistedDataIncompatibleError' | 'WorkflowTimeoutError' | 'HttpClientError' | 'WorkerProtocolIncompatibleError' | 'UpdateTimeoutError' | 'UpdateValidationError' | 'WorkflowTerminalError' | 'WorkflowBuilderError' | 'VersionMismatchError' | 'EffectReplayConflictError' | 'ReviewTimeoutError' | 'AtomicStateConflictError' | 'StandardSchemaValidationError' | 'ActivityReconciliationCapabilityError' | 'ActivityReconciliationConflictError' | 'ActivityReconciliationIndeterminateError' | 'AsyncActivityTokenNotFoundError' | 'ActivityScheduleToCloseTimeoutError' | 'ActivityPerAttemptTimeoutError' | 'PayloadSizeExceededError' | 'StartOrSignalConflictError' | 'WorkflowTeardownPendingError' | 'IdempotencyKeyPurgedError';
28
+ export type WeftErrorCode = 'WorkflowAlreadyExistsError' | 'BulkDeleteRequiresTerminalWorkflowsError' | 'BulkOperationConfirmationError' | 'WorkflowTypeNotRegisteredForRecoveryError' | 'EngineCreateNameMismatchError' | 'EngineDisposedError' | 'WorkflowNotFoundError' | 'WorkflowNotRegisteredError' | 'WorkflowConcurrencyLimitExceededError' | 'WorkflowSuspendNotSupportedError' | 'ActivityResolutionError' | 'BranchTopologyChangedError' | 'PersistedDataIncompatibleError' | 'WorkflowTimeoutError' | 'HttpClientError' | 'WorkerProtocolIncompatibleError' | 'UpdateTimeoutError' | 'UpdateValidationError' | 'WorkflowTerminalError' | 'WorkflowBuilderError' | 'VersionMismatchError' | 'EffectReplayConflictError' | 'ReviewTimeoutError' | 'AtomicStateConflictError' | 'StandardSchemaValidationError' | 'ActivityReconciliationCapabilityError' | 'ActivityReconciliationConflictError' | 'ActivityReconciliationIndeterminateError' | 'DurableActivityScopeError' | 'DurableActivityUnsupportedError' | 'AsyncActivityTokenNotFoundError' | 'ActivityScheduleToCloseTimeoutError' | 'ActivityPerAttemptTimeoutError' | 'PayloadSizeExceededError' | 'StartOrSignalConflictError' | 'WorkflowTeardownPendingError' | 'IdempotencyKeyPurgedError';
29
29
  /**
30
30
  * Generic abstract base for all Weft library errors. The `TCode` parameter
31
31
  * makes each subclass's `code` its own literal type; the exported base surface
@@ -35,6 +35,8 @@ const publicWeftErrorCodeMap = {
35
35
  ActivityReconciliationCapabilityError: !0,
36
36
  ActivityReconciliationConflictError: !0,
37
37
  ActivityReconciliationIndeterminateError: !0,
38
+ DurableActivityScopeError: !0,
39
+ DurableActivityUnsupportedError: !0,
38
40
  AsyncActivityTokenNotFoundError: !0,
39
41
  ActivityScheduleToCloseTimeoutError: !0,
40
42
  ActivityPerAttemptTimeoutError: !0,
@@ -8,6 +8,7 @@ export declare class WorkerExecutionStrategy implements ExecutionStrategy {
8
8
  onMessage(handler: (message: WorkerOutboundMessage) => void | Promise<void>): void;
9
9
  startWorkflow(parameters: {
10
10
  workflowId: string;
11
+ workflowExecutionToken?: string;
11
12
  workflowType: string;
12
13
  input: unknown;
13
14
  checkpoint: ArrayBuffer;
@@ -19,6 +19,7 @@ export interface WorkerInboundMessageContext {
19
19
  /** Build a `run` inbound message from start parameters and the turn context. */
20
20
  export declare function buildRunMessage(parameters: {
21
21
  workflowId: string;
22
+ workflowExecutionToken?: string;
22
23
  workflowType: string;
23
24
  input: unknown;
24
25
  checkpoint: ArrayBuffer;
@@ -5,6 +5,9 @@ export function buildRunMessage(parameters, context) {
5
5
  protocolVersion: WORKER_PROTOCOL_VERSION,
6
6
  turnId: context.turnId,
7
7
  workflowId: parameters.workflowId,
8
+ ...parameters.workflowExecutionToken !== void 0 && {
9
+ workflowExecutionToken: parameters.workflowExecutionToken
10
+ },
8
11
  workflowType: parameters.workflowType,
9
12
  checkpoint: parameters.checkpoint,
10
13
  input: parameters.input,
package/dist/index.d.ts CHANGED
@@ -20,7 +20,8 @@ export { WeftError, isWeftError, isWeftErrorCode, isWeftErrorLike, isWeftFault,
20
20
  export type { WeftErrorCode } from './core/weft-error.ts';
21
21
  export { FAULT_CODE_TO_FAILURE_CATEGORY, failureCategoryForFaultCode, isFaultCode, } from './core/fault-code.ts';
22
22
  export type { FaultCode } from './core/fault-code.ts';
23
- export { ActivityReconciliationCapabilityError, ActivityReconciliationConflictError, ActivityReconciliationIndeterminateError, ActivityResolutionError, AsyncActivityTokenNotFoundError, BulkDeleteRequiresTerminalWorkflowsError, BulkOperationConfirmationError, ENGINE_LEASE_LOST_WARNING_NAME, Engine, EngineCreateNameMismatchError, EngineDisposedError, EngineLeaseAcquisitionTimeoutError, EngineLeaseCorruptedError, EngineLeaseNotHeldError, IdempotencyKeyPurgedError, PersistedDataIncompatibleError, ScheduleHandle, StartOrSignalConflictError, WorkflowAlreadyExistsError, WorkflowConcurrencyLimitExceededError, WorkflowHandle, WorkflowNotFoundError, WorkflowNotRegisteredError, WorkflowSuspendNotSupportedError, WorkflowTeardownPendingError, WorkflowTypeNotRegisteredForRecoveryError, } from './core/engine';
23
+ export { DurableActivityScopeError, DurableActivityUnsupportedError, durableActivity, } from './core/context/durable-activity.ts';
24
+ export { ActivityReconciliationCapabilityError, ActivityReconciliationConflictError, ActivityReconciliationIndeterminateError, ActivityResolutionError, AsyncActivityTokenNotFoundError, BulkDeleteRequiresTerminalWorkflowsError, BulkOperationConfirmationError, ENGINE_LEASE_LOST_WARNING_NAME, ENGINE_LEASE_SYNCHRONOUS_DISPOSE_WARNING_NAME, Engine, EngineCreateNameMismatchError, EngineDisposedError, EngineLeaseAcquisitionTimeoutError, EngineLeaseCorruptedError, EngineLeaseNotHeldError, IdempotencyKeyPurgedError, PersistedDataIncompatibleError, ScheduleHandle, StartOrSignalConflictError, WorkflowAlreadyExistsError, WorkflowConcurrencyLimitExceededError, WorkflowHandle, WorkflowNotFoundError, WorkflowNotRegisteredError, WorkflowSuspendNotSupportedError, WorkflowTeardownPendingError, WorkflowTypeNotRegisteredForRecoveryError, } from './core/engine';
24
25
  export type { EngineCreateOptions, EngineStateNamespace, RecoverAllOptions } from './core/engine';
25
26
  export { DEFAULT_CHECKPOINT_SIZE_WARNING_THRESHOLD, DEFAULT_MAX_NESTING_DEPTH, DEFAULT_POLL_INTERVAL_MS, DEFAULT_RETRY_POLICY, DEFAULT_VISIBILITY_TIMEOUT_MS, HISTORY_CIRCUIT_BREAKER_REASON, WorkflowBuilderError, query, schedule, signal, update, workflow, } from './core/types';
26
27
  export type { ActivityArgsFor, ActivityCallOptions, ActivityCallable, ActivityContext, ActivityDefinition, ActivityEntryInput, ActivityFunction, ActivityMap, ActivityMapInput, ActivityObjectInput, ActivityResultFor, ActivityVerificationContext, ActivityVerificationPhase, ActivityVerificationResult, AnyActivityDefinition, AnyWorkflowDefinition, ArchiveAdapter, BuilderState, BuiltWorkflowDefinition, BulkCancelResult, BulkDeleteResult, BulkOperationAction, BulkOperationAuditEvent, BulkOperationCommitOptions, BulkOperationDryRunOptions, BulkOperationDryRunResult, BulkOperationError, BulkOperationFilterSummary, BulkOperationOptions, BulkOperationPrincipal, BulkOperationScopeSummary, BulkRetryFailedResult, BulkSignalAllCommitOptions, BulkSignalAllDryRunOptions, BulkSignalAllOptions, BulkSignalResult, BulkTagResult, Checkpoint, CheckpointState, CheckpointSummary, CompletedReviewEntry, CoordinatedUpdateResult, DefinitionSchema, Duration, EngineOptions, FailureCategory, ForkLineage, ForkOptions, HistoryPolicy, InferActivityEntries, InferActivityEntry, InferWorkflowEntries, InferWorkflowEntry, InitialBuilderState, LaunchMetadata, ListFilter, ListOptions, MarkBuilderState, NormalizeActivities, NormalizedActivityEntry, NormalizedRetentionPolicy, PaginatedResult, PayloadSizePolicy, PendingReviewEntry, PurgeResult, QueryDefinition, QueryMap, QueryShape, RegisteredWorkflowDefinition, RetentionOverview, RetentionPolicy, RetryPolicy, ReviewListEntry, ReviewListFilter, ReviewStatus, ScheduleDefinition, ScheduleFilter, ScheduleOptions, ScheduleOverlapPolicy, ScheduleSpec, ScheduleState, ScheduleStatus, ScheduleSummary, SearchAttributeDefinition, SearchAttributeHandle, SearchAttributeSchema, SearchAttributeValue, Serializer, SignalDefinition, SignalDeliveryOptions, SignalMap, SignalPayload, StartOptions, StartOrSignalOptions, StartOrSignalSignal, SubmitReviewOptions, TerminationReason, UpdateDefinition, UpdateMap, UpdatePayload, WorkerReplayOperationFailure, WorkerReplayOperationSignature, WorkflowAlreadyRegistered, WorkflowAtomicState, WorkflowAtomicStateOptions, WorkflowBuilder, WorkflowBuilderOptions, WorkflowConcurrencyOptions, WorkflowContext, WorkflowDefinition, WorkflowEvent, WorkflowFunction, WorkflowGenerator, WorkflowId, WorkflowLogLevel, WorkflowLogRecord, WorkflowLogger, WorkflowRegistry, WorkflowReplay, WorkflowServicesResolution, WorkflowServicesResolverInfo, WorkflowServicesResolverLaunchOptions, WorkflowServicesResolverScheduleInfo, WorkflowSessionState, WorkflowSnapshot, WorkflowState, WorkflowStateNamespace, WorkflowStatus, WorkflowSummary, WorkflowTimelineEntry, WorkflowTimelineStatus, WorkflowTypeRetentionPolicy, } from './core/types';
package/dist/index.js CHANGED
@@ -11,6 +11,11 @@ export {
11
11
  failureCategoryForFaultCode,
12
12
  isFaultCode
13
13
  } from "./core/fault-code.js";
14
+ export {
15
+ DurableActivityScopeError,
16
+ DurableActivityUnsupportedError,
17
+ durableActivity
18
+ } from "./core/context/durable-activity.js";
14
19
  export {
15
20
  ActivityReconciliationCapabilityError,
16
21
  ActivityReconciliationConflictError,
@@ -20,6 +25,7 @@ export {
20
25
  BulkDeleteRequiresTerminalWorkflowsError,
21
26
  BulkOperationConfirmationError,
22
27
  ENGINE_LEASE_LOST_WARNING_NAME,
28
+ ENGINE_LEASE_SYNCHRONOUS_DISPOSE_WARNING_NAME,
23
29
  Engine,
24
30
  EngineCreateNameMismatchError,
25
31
  EngineDisposedError,
@@ -1,4 +1,4 @@
1
1
  // @bun
2
- var b=Object.defineProperty;var w=(j)=>j;function F(j,q){this[j]=w.bind(null,q)}var I=(j,q)=>{for(var z in q)b(j,z,{get:q[z],enumerable:!0,configurable:!0,set:F.bind(q,z)})};var Z=(j,q)=>()=>(j&&(q=j(j=0)),q);var N=(j,q,z)=>{if(q!=null){if(typeof q!=="object"&&typeof q!=="function")throw TypeError('Object expected to be assigned to "using" declaration');let A;if(z)A=q[Symbol.asyncDispose];if(A===void 0)A=q[Symbol.dispose];if(typeof A!=="function")throw TypeError("Object not disposable");j.push([z,A,q])}else if(z)j.push([z]);return q},V=(j,q,z)=>{let A=(G)=>q=z?new SuppressedError(G,q,"An error was suppressed during disposal"):(z=!0,G),H=(G)=>{while(G=j.pop())try{var U=G[1]&&G[1].call(G[2]);if(G[0])return Promise.resolve(U).then(H,(Q)=>(A(Q),H()))}catch(Q){A(Q)}if(z)throw q};return H()};function P(j){return typeof j==="string"&&M.has(j)}var X,J,M;var $=Z(()=>{X=class X extends Error{code;constructor(j,q,z){super(q,z);this.code=j,this.name=j}};J={WorkflowAlreadyExistsError:!0,BulkDeleteRequiresTerminalWorkflowsError:!0,BulkOperationConfirmationError:!0,WorkflowTypeNotRegisteredForRecoveryError:!0,EngineCreateNameMismatchError:!0,EngineDisposedError:!0,WorkflowNotFoundError:!0,WorkflowNotRegisteredError:!0,WorkflowConcurrencyLimitExceededError:!0,WorkflowSuspendNotSupportedError:!0,ActivityResolutionError:!0,BranchTopologyChangedError:!0,PersistedDataIncompatibleError:!0,WorkflowTimeoutError:!0,HttpClientError:!0,WorkerProtocolIncompatibleError:!0,UpdateTimeoutError:!0,UpdateValidationError:!0,WorkflowTerminalError:!0,WorkflowBuilderError:!0,VersionMismatchError:!0,EffectReplayConflictError:!0,ReviewTimeoutError:!0,AtomicStateConflictError:!0,StandardSchemaValidationError:!0,ActivityReconciliationCapabilityError:!0,ActivityReconciliationConflictError:!0,ActivityReconciliationIndeterminateError:!0,AsyncActivityTokenNotFoundError:!0,ActivityScheduleToCloseTimeoutError:!0,ActivityPerAttemptTimeoutError:!0,PayloadSizeExceededError:!0,StartOrSignalConflictError:!0,WorkflowTeardownPendingError:!0,IdempotencyKeyPurgedError:!0},M=new Set(Object.keys(J))});async function B(j,q,z){let A=j["~standard"];if(!O(A))throw TypeError(`Schema for ${z.fieldName} does not provide runtime validation. Attach a Standard Schema validator (Zod, Valibot, or another vendor) or supply a runtime-validating schema at this boundary.`);let H=await A.validate(q);if(H.issues===void 0)return H.value;throw new K({fieldName:z.fieldName,operation:z.operation,issues:H.issues.map(T)})}function Y(j){return j.map((q)=>q.path===""?q.message:`${q.path}: ${q.message}`).join(`
2
+ var b=Object.defineProperty;var w=(j)=>j;function F(j,q){this[j]=w.bind(null,q)}var I=(j,q)=>{for(var z in q)b(j,z,{get:q[z],enumerable:!0,configurable:!0,set:F.bind(q,z)})};var Z=(j,q)=>()=>(j&&(q=j(j=0)),q);var N=import.meta.require,V=(j,q,z)=>{if(q!=null){if(typeof q!=="object"&&typeof q!=="function")throw TypeError('Object expected to be assigned to "using" declaration');let A;if(z)A=q[Symbol.asyncDispose];if(A===void 0)A=q[Symbol.dispose];if(typeof A!=="function")throw TypeError("Object not disposable");j.push([z,A,q])}else if(z)j.push([z]);return q},k=(j,q,z)=>{let A=(G)=>q=z?new SuppressedError(G,q,"An error was suppressed during disposal"):(z=!0,G),H=(G)=>{while(G=j.pop())try{var U=G[1]&&G[1].call(G[2]);if(G[0])return Promise.resolve(U).then(H,(Q)=>(A(Q),H()))}catch(Q){A(Q)}if(z)throw q};return H()};function x(j){return typeof j==="string"&&M.has(j)}var X,J,M;var $=Z(()=>{X=class X extends Error{code;constructor(j,q,z){super(q,z);this.code=j,this.name=j}};J={WorkflowAlreadyExistsError:!0,BulkDeleteRequiresTerminalWorkflowsError:!0,BulkOperationConfirmationError:!0,WorkflowTypeNotRegisteredForRecoveryError:!0,EngineCreateNameMismatchError:!0,EngineDisposedError:!0,WorkflowNotFoundError:!0,WorkflowNotRegisteredError:!0,WorkflowConcurrencyLimitExceededError:!0,WorkflowSuspendNotSupportedError:!0,ActivityResolutionError:!0,BranchTopologyChangedError:!0,PersistedDataIncompatibleError:!0,WorkflowTimeoutError:!0,HttpClientError:!0,WorkerProtocolIncompatibleError:!0,UpdateTimeoutError:!0,UpdateValidationError:!0,WorkflowTerminalError:!0,WorkflowBuilderError:!0,VersionMismatchError:!0,EffectReplayConflictError:!0,ReviewTimeoutError:!0,AtomicStateConflictError:!0,StandardSchemaValidationError:!0,ActivityReconciliationCapabilityError:!0,ActivityReconciliationConflictError:!0,ActivityReconciliationIndeterminateError:!0,DurableActivityScopeError:!0,DurableActivityUnsupportedError:!0,AsyncActivityTokenNotFoundError:!0,ActivityScheduleToCloseTimeoutError:!0,ActivityPerAttemptTimeoutError:!0,PayloadSizeExceededError:!0,StartOrSignalConflictError:!0,WorkflowTeardownPendingError:!0,IdempotencyKeyPurgedError:!0},M=new Set(Object.keys(J))});async function B(j,q,z){let A=j["~standard"];if(!O(A))throw TypeError(`Schema for ${z.fieldName} does not provide runtime validation. Attach a Standard Schema validator (Zod, Valibot, or another vendor) or supply a runtime-validating schema at this boundary.`);let H=await A.validate(q);if(H.issues===void 0)return H.value;throw new K({fieldName:z.fieldName,operation:z.operation,issues:H.issues.map(T)})}function Y(j){return j.map((q)=>q.path===""?q.message:`${q.path}: ${q.message}`).join(`
3
3
  `)}function O(j){return typeof j.validate==="function"}function T(j){return{message:j.message,path:y(j.path)}}function y(j){if(j===void 0||j.length===0)return"";let q="";for(let z of j)q+="/",q+=L(z);return q}function L(j){let q=R(j)?j.key:j;return _(String(q))}function R(j){return j!==null&&typeof j==="object"&&"key"in j}function _(j){return j.replace(/~/g,"~0").replace(/\//g,"~1")}function C(j,q,z){return`Validation failed for ${q===void 0?j:`${q} ${j}`}:
4
- ${Y(z)}`}var K;var D=Z(()=>{$();K=class K extends X{fieldName;operation;issues;constructor(j){super("StandardSchemaValidationError",C(j.fieldName,j.operation,j.issues));this.fieldName=j.fieldName,this.operation=j.operation,this.issues=j.issues}}});D();var g=Y,S=K,h=B;export{h as validateStandardSchema,g as formatStandardSchemaIssues,S as StandardSchemaValidationError};
4
+ ${Y(z)}`}var K;var D=Z(()=>{$();K=class K extends X{fieldName;operation;issues;constructor(j){super("StandardSchemaValidationError",C(j.fieldName,j.operation,j.issues));this.fieldName=j.fieldName,this.operation=j.operation,this.issues=j.issues}}});D();var S=Y,h=K,v=B;export{v as validateStandardSchema,S as formatStandardSchemaIssues,h as StandardSchemaValidationError};