@lostgradient/weft 0.8.0 → 0.10.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 (155) hide show
  1. package/README.md +9 -5
  2. package/dist/alerting/alert-manager.d.ts +3 -1
  3. package/dist/alerting/alert-manager.js +5 -2
  4. package/dist/cli/generated/operation-client.generated.d.ts +1 -0
  5. package/dist/cli-main.js +78 -78
  6. package/dist/core/context/durable-operations.js +1 -1
  7. package/dist/core/context/index.d.ts +3 -1
  8. package/dist/core/context/index.js +10 -0
  9. package/dist/core/context/operation-request.d.ts +4 -0
  10. package/dist/core/context/parallel-cache-entry.d.ts +1 -1
  11. package/dist/core/context/parallel-cache-entry.js +12 -8
  12. package/dist/core/context/parallel-operations.d.ts +1 -1
  13. package/dist/core/context/parallel-operations.js +50 -8
  14. package/dist/core/context/run-operation.js +3 -2
  15. package/dist/core/context/speculative-child.js +1 -0
  16. package/dist/core/context/types.d.ts +1 -0
  17. package/dist/core/engine/activity-heartbeat-tracking.d.ts +1 -1
  18. package/dist/core/engine/activity-heartbeat-tracking.js +5 -1
  19. package/dist/core/engine/anonymous-signal-sequence.js +0 -2
  20. package/dist/core/engine/async-activity-completion.d.ts +24 -54
  21. package/dist/core/engine/async-activity-completion.js +25 -90
  22. package/dist/core/engine/async-activity-records.d.ts +106 -0
  23. package/dist/core/engine/async-activity-records.js +124 -0
  24. package/dist/core/engine/bulk-operations-purge.js +2 -1
  25. package/dist/core/engine/bulk-operations.js +10 -29
  26. package/dist/core/engine/callback-creators-bundles.js +1 -1
  27. package/dist/core/engine/callback-creators-core.js +1 -0
  28. package/dist/core/engine/construction.d.ts +1 -3
  29. package/dist/core/engine/construction.js +2 -5
  30. package/dist/core/engine/deferred-consume-envelope.d.ts +10 -1
  31. package/dist/core/engine/deferred-consume-envelope.js +9 -1
  32. package/dist/core/engine/disposal.js +1 -0
  33. package/dist/core/engine/engine-internal-types.d.ts +2 -0
  34. package/dist/core/engine/engine-runtime-helpers.d.ts +8 -0
  35. package/dist/core/engine/engine-runtime-helpers.js +9 -0
  36. package/dist/core/engine/errors.js +1 -1
  37. package/dist/core/engine/index.d.ts +12 -2
  38. package/dist/core/engine/index.js +35 -16
  39. package/dist/core/engine/inline-launch-queue.js +1 -1
  40. package/dist/core/engine/internals.d.ts +25 -3
  41. package/dist/core/engine/lifecycle/fork-helpers.js +1 -0
  42. package/dist/core/engine/lifecycle/recovered-services.d.ts +4 -2
  43. package/dist/core/engine/lifecycle/recovered-services.js +37 -7
  44. package/dist/core/engine/lifecycle/resume.d.ts +2 -2
  45. package/dist/core/engine/lifecycle/resume.js +45 -7
  46. package/dist/core/engine/lifecycle/shared.d.ts +34 -0
  47. package/dist/core/engine/lifecycle/start-exec.d.ts +2 -2
  48. package/dist/core/engine/lifecycle/start-exec.js +6 -4
  49. package/dist/core/engine/lifecycle/start.js +1 -0
  50. package/dist/core/engine/lifecycle/transition.d.ts +1 -1
  51. package/dist/core/engine/lifecycle/transition.js +9 -3
  52. package/dist/core/engine/lifecycle.d.ts +1 -1
  53. package/dist/core/engine/memo-durable-activity.js +8 -10
  54. package/dist/core/engine/operations-activity.d.ts +1 -1
  55. package/dist/core/engine/operations-activity.js +8 -6
  56. package/dist/core/engine/operations-coordination.d.ts +15 -1
  57. package/dist/core/engine/operations-coordination.js +43 -10
  58. package/dist/core/engine/operations-time.d.ts +2 -2
  59. package/dist/core/engine/operations-time.js +40 -6
  60. package/dist/core/engine/ownership-options.d.ts +1 -0
  61. package/dist/core/engine/ownership-options.js +14 -0
  62. package/dist/core/engine/retention.js +4 -0
  63. package/dist/core/engine/schedule-run-metadata.d.ts +3 -0
  64. package/dist/core/engine/schedule-run-metadata.js +29 -0
  65. package/dist/core/engine/schedule-run.js +19 -4
  66. package/dist/core/engine/schedules.js +7 -3
  67. package/dist/core/engine/sub-operation.js +6 -13
  68. package/dist/core/engine/termination/cleanup.js +18 -14
  69. package/dist/core/engine/termination/finalizer-activity.d.ts +1 -1
  70. package/dist/core/engine/termination/finalizer-activity.js +5 -1
  71. package/dist/core/engine/termination/finalizer.js +1 -1
  72. package/dist/core/engine/validation/schedule-options.d.ts +9 -0
  73. package/dist/core/engine/validation/schedule-options.js +59 -0
  74. package/dist/core/engine/validation/schedule.d.ts +3 -8
  75. package/dist/core/engine/validation/schedule.js +40 -56
  76. package/dist/core/engine/validation.js +1 -0
  77. package/dist/core/execution-strategy.d.ts +1 -0
  78. package/dist/core/inline-execution-strategy.context-options.d.ts +1 -0
  79. package/dist/core/inline-execution-strategy.context-options.js +3 -0
  80. package/dist/core/types/activity.d.ts +11 -0
  81. package/dist/core/types/checkpoint.d.ts +1 -0
  82. package/dist/core/types/options.d.ts +12 -0
  83. package/dist/core/types/schedules.d.ts +10 -0
  84. package/dist/core/types/services-resolution.d.ts +8 -3
  85. package/dist/core/types/state.d.ts +6 -0
  86. package/dist/core/types/workflow-builder.d.ts +2 -2
  87. package/dist/core/types/workflow-context.d.ts +40 -0
  88. package/dist/core/worker-execution-strategy.d.ts +1 -0
  89. package/dist/core/worker-inbound-message.d.ts +1 -0
  90. package/dist/core/worker-inbound-message.js +3 -0
  91. package/dist/index.d.ts +2 -2
  92. package/dist/json-schema.js +2 -2
  93. package/dist/mcp/cli.js +32 -32
  94. package/dist/observability/index.js +2 -2
  95. package/dist/runtime/portable.d.ts +1 -1
  96. package/dist/server/authorization.d.ts +3 -3
  97. package/dist/server/fault-to-json-rpc.d.ts +2 -1
  98. package/dist/server/handler.js +28 -28
  99. package/dist/server/index.d.ts +2 -0
  100. package/dist/server/index.js +30 -30
  101. package/dist/server/json-rpc-dispatch.d.ts +2 -2
  102. package/dist/server/json-rpc-parse.d.ts +1 -1
  103. package/dist/server/json-rpc-protocol.d.ts +2 -2
  104. package/dist/server/json-rpc-websocket.d.ts +1 -1
  105. package/dist/server/operation-fault.d.ts +3 -1
  106. package/dist/server/operations/async-activity.js +2 -2
  107. package/dist/server/operations/create-schedule.d.ts +2 -0
  108. package/dist/server/operations/create-schedule.js +13 -2
  109. package/dist/server/principal.d.ts +2 -2
  110. package/dist/server/rest-binding.d.ts +1 -1
  111. package/dist/server/runtime/task-dispatch.js +6 -0
  112. package/dist/server/runtime/task-polling.js +9 -1
  113. package/dist/server/runtime/task-reconciliation.js +2 -1
  114. package/dist/server/stdio-session.d.ts +4 -4
  115. package/dist/server/task-queue-types.d.ts +2 -0
  116. package/dist/server/task-state.d.ts +4 -0
  117. package/dist/service-worker/index.d.ts +15 -14
  118. package/dist/service-worker/index.js +28 -28
  119. package/dist/service-worker/scheduler.d.ts +41 -1
  120. package/dist/storage/auto.d.ts +36 -18
  121. package/dist/storage/auto.js +1 -1
  122. package/dist/storage/compressed-storage.js +1 -1
  123. package/dist/storage/http.js +2 -2
  124. package/dist/storage/index.d.ts +1 -0
  125. package/dist/storage/indexeddb.d.ts +6 -1
  126. package/dist/storage/indexeddb.js +1 -1
  127. package/dist/storage/interface.d.ts +1 -0
  128. package/dist/storage/interface.js +1 -1
  129. package/dist/storage/lmdb.js +1 -1
  130. package/dist/storage/memory.js +1 -1
  131. package/dist/storage/neon.js +1 -1
  132. package/dist/storage/resolve.js +1 -1
  133. package/dist/storage/scoped-storage.js +1 -1
  134. package/dist/storage/testing.js +1 -1
  135. package/dist/storage/turso.js +1 -1
  136. package/dist/storage/typed-storage.js +1 -1
  137. package/dist/storage/web-extension.d.ts +1 -1
  138. package/dist/storage/web-extension.js +1 -1
  139. package/dist/testing/index.js +33 -33
  140. package/dist/version.d.ts +1 -1
  141. package/dist/version.js +1 -1
  142. package/dist/worker/execute-with-interceptors.d.ts +9 -3
  143. package/dist/worker/execute-with-interceptors.js +14 -2
  144. package/dist/worker/long-poll.d.ts +2 -1
  145. package/dist/worker/long-poll.js +1 -1
  146. package/dist/worker/protocol-messages.d.ts +2 -0
  147. package/dist/worker/protocol-schemas.d.ts +8 -0
  148. package/dist/worker/protocol-schemas.js +1 -0
  149. package/dist/worker/protocol.js +1 -1
  150. package/dist/worker/remote-activity-context.d.ts +2 -0
  151. package/dist/workers/activity-runner.d.ts +2 -0
  152. package/dist/workers/activity-runner.js +9 -1
  153. package/dist/workers/workflow-runner.d.ts +2 -1
  154. package/dist/workers/workflow-runner.js +1 -0
  155. package/package.json +2 -2
@@ -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,
@@ -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;
@@ -218,6 +218,18 @@ export interface ForkOptions {
218
218
  export interface EngineOptions<TServices = unknown> {
219
219
  storage?: WeftStorage;
220
220
  development?: boolean;
221
+ /**
222
+ * Select how engine-owned periodic work is driven. The default `'automatic'`
223
+ * profile starts in-process intervals for update-response cleanup, configured
224
+ * retention sweeps, alert re-evaluation, and the durable-timer scheduler used
225
+ * by {@link Engine.create}. Use `'manual'` in runtimes such as Cloudflare
226
+ * Durable Objects where the host must wake the engine through alarms or Cron
227
+ * triggers, then call {@link Engine.runMaintenance} from each wake-up.
228
+ *
229
+ * Manual mode rejects interval-dependent ownership and second-instance
230
+ * detection options instead of silently starting background work.
231
+ */
232
+ backgroundTasks?: 'automatic' | 'manual';
221
233
  serializer?: Serializer;
222
234
  retention?: RetentionPolicy;
223
235
  retentionSweepInterval?: Duration;
@@ -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. */
@@ -50,7 +50,11 @@ export interface WorkflowServicesResolverLaunchOptions {
50
50
  }
51
51
  /**
52
52
  * Schedule context passed to {@link EngineOptions.resolveWorkflowServices} for
53
- * scheduled occurrences.
53
+ * scheduled occurrences. New scheduled runs persist this context with the
54
+ * workflow record, so a fresh-process recovery receives the same schedule id and
55
+ * known occurrence timestamp as the live launch path. Runs from older stores
56
+ * that predate the metadata may omit it, and queue-drained runs may omit
57
+ * `occurrence` because their original grid timestamp was not retained.
54
58
  *
55
59
  * @example
56
60
  * ```ts
@@ -72,8 +76,9 @@ export interface WorkflowServicesResolverScheduleInfo {
72
76
  * recovered workflow or scheduled occurrence. `input` is the original durable
73
77
  * launch input, available at resume time — typically enough to rebuild the run's
74
78
  * dependencies (tenant, model, tool registry) without a side table. When tags or
75
- * schedule identity are part of the durable launch context, they are exposed so
76
- * resolvers do not need parallel side channels for the same classification.
79
+ * schedule identity are part of the durable launch context, they are exposed on
80
+ * both live scheduled launches and recovery so resolvers do not need parallel
81
+ * side channels for the same classification.
77
82
  *
78
83
  * @example
79
84
  * ```ts
@@ -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
@@ -50,8 +50,8 @@ export type WorkflowGenerator<TInput, TOutput, TActivities extends ActivityMap,
50
50
  * Bare-`WorkflowContext` callers (no declared activity/signal/etc. maps)
51
51
  * typecheck because the interface's generics all default to permissive shapes:
52
52
  * the typed overloads de-prioritise to `never` and the dynamic string-name /
53
- * callable overloads match instead. This permissive path is current API — it is
54
- * how untyped, ad-hoc-name authoring is supported, not a compatibility shim.
53
+ * callable overloads match instead. This permissive path is the current API for
54
+ * untyped, ad-hoc-name authoring.
55
55
  */
56
56
  export type WorkflowContextOf<TActivities extends ActivityMap = ActivityMap, TSignals extends SignalMap = SignalMap, TUpdates extends UpdateMap = UpdateMap, TQueries extends QueryMap = QueryMap, TSearchAttributes extends SearchAttributeSchema = SearchAttributeSchema, TServices = unknown> = WorkflowContext<TActivities, TSignals, TUpdates, TQueries, TSearchAttributes, TServices>;
57
57
  /**
@@ -15,6 +15,32 @@ export type WorkflowOperationResult<TOperation> = TOperation extends Generator<u
15
15
  export type WorkflowOperationTupleResult<TOperations extends readonly WorkflowOperation<unknown>[]> = {
16
16
  -readonly [TIndex in keyof TOperations]: WorkflowOperationResult<TOperations[TIndex]>;
17
17
  };
18
+ /**
19
+ * Discriminated winner returned by {@link WorkflowContext.raceKeyed}. Checking
20
+ * `key` narrows `value` to the result type of that named workflow operation.
21
+ * Numeric object keys are returned as strings, matching JavaScript object
22
+ * enumeration; symbol keys are rejected at runtime.
23
+ *
24
+ * @example
25
+ * ```ts
26
+ * import type { WorkflowKeyedRaceResult, WorkflowOperation } from '@lostgradient/weft';
27
+ *
28
+ * type Winner = WorkflowKeyedRaceResult<{
29
+ * event: WorkflowOperation<string>;
30
+ * idle: WorkflowOperation<void>;
31
+ * }>;
32
+ *
33
+ * function handleWinner(winner: Winner): string {
34
+ * return winner.key === 'event' ? winner.value : 'timed out';
35
+ * }
36
+ * ```
37
+ */
38
+ export type WorkflowKeyedRaceResult<TOperations extends Readonly<Record<string, WorkflowOperation<unknown>>>> = {
39
+ [TKey in keyof TOperations]: {
40
+ key: TKey extends string | number ? `${TKey}` : never;
41
+ value: WorkflowOperationResult<TOperations[TKey]>;
42
+ };
43
+ }[keyof TOperations];
18
44
  type RunAllBranchResult<TBranch> = TBranch extends readonly [
19
45
  execute: infer TExecute,
20
46
  ...rest: unknown[]
@@ -54,6 +80,13 @@ export type RunAllResult<TBranches extends Record<string, WorkflowRunAllBranch>>
54
80
  */
55
81
  export interface WorkflowContext<TActivities extends ActivityMap = {}, TSignals extends SignalMap = {}, TUpdates extends UpdateMap = {}, TQueries extends QueryMap = {}, TSearchAttributes extends SearchAttributeSchema = {}, TServices = unknown> {
56
82
  readonly workflowId: WorkflowId;
83
+ /**
84
+ * Durable token for this concrete run. A stable workflow id reused with
85
+ * `onTerminalConflict: 'start-new'` receives a new token, while recovery of the
86
+ * same run keeps the token. Store this with external side effects so late
87
+ * activity writes or finalizer cleanup can prove they still belong to this run.
88
+ */
89
+ readonly workflowExecutionToken: string | undefined;
57
90
  /**
58
91
  * The registered workflow type name for this run (the `name` field from
59
92
  * `workflow({ name: '...' })`). Useful for logging and self-inspection
@@ -173,6 +206,7 @@ export interface WorkflowContext<TActivities extends ActivityMap = {}, TSignals
173
206
  review(options: HumanReviewOptions): WorkflowOperation<HumanReviewResult>;
174
207
  all<const TOperations extends readonly WorkflowOperation<unknown>[]>(operations: TOperations): WorkflowOperation<WorkflowOperationTupleResult<TOperations>>;
175
208
  race<const TOperations extends readonly WorkflowOperation<unknown>[]>(operations: TOperations): WorkflowOperation<WorkflowOperationTupleResult<TOperations>[number]>;
209
+ raceKeyed<const TOperations extends Readonly<Record<string, WorkflowOperation<unknown>>>>(operations: TOperations): WorkflowOperation<WorkflowKeyedRaceResult<TOperations>>;
176
210
  memo<T>(key: string, fn: () => T | Promise<T>): WorkflowOperation<T>;
177
211
  offload<T>(key: string, fn: () => Promise<T>): WorkflowOperation<OffloadReference>;
178
212
  stream(key: string, fn: (sink: StreamSink) => AsyncGenerator<unknown, void, unknown>): WorkflowOperation<StreamReference>;
@@ -233,6 +267,12 @@ export interface WorkflowContext<TActivities extends ActivityMap = {}, TSignals
233
267
  * Handlers run in registration order; async handlers are awaited; failures
234
268
  * are swallowed — the workflow still finalizes as cancelled.
235
269
  *
270
+ * For inline workflows, `engine.cancel(id)` aborts {@link WorkflowContext.signal}
271
+ * promptly before in-memory execution state is evicted. A handler registered
272
+ * on the live context then runs after the cancelled state commits and before
273
+ * `cancel()` settles. Work that ignores the abort signal is still cooperative
274
+ * JavaScript and cannot be force-interrupted.
275
+ *
236
276
  * **Best-effort only**: handlers run outside the durable effect log and are
237
277
  * not retried. Side effects in handlers are not replay-safe, and registered
238
278
  * handlers are not restored after an engine restart. A hard cancel or an
@@ -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
@@ -22,9 +22,9 @@ export { FAULT_CODE_TO_FAILURE_CATEGORY, failureCategoryForFaultCode, isFaultCod
22
22
  export type { FaultCode } from './core/fault-code.ts';
23
23
  export { DurableActivityScopeError, DurableActivityUnsupportedError, durableActivity, } from './core/context/durable-activity.ts';
24
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';
25
- export type { EngineCreateOptions, EngineStateNamespace, RecoverAllOptions } from './core/engine';
25
+ export type { EngineCreateOptions, EngineStateNamespace, RecoverAllOptions, RecoveredWorkflowInfo, } from './core/engine';
26
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';
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';
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, WorkflowKeyedRaceResult, WorkflowLogLevel, WorkflowLogRecord, WorkflowLogger, WorkflowRegistry, WorkflowReplay, WorkflowServicesResolution, WorkflowServicesResolverInfo, WorkflowServicesResolverLaunchOptions, WorkflowServicesResolverScheduleInfo, WorkflowSessionState, WorkflowSnapshot, WorkflowState, WorkflowStateNamespace, WorkflowStatus, WorkflowSummary, WorkflowTimelineEntry, WorkflowTimelineStatus, WorkflowTypeRetentionPolicy, } from './core/types';
28
28
  export { AlertManager } from './alerting/index';
29
29
  export type { AlertAction, AlertMetric, AlertRule, AlertState, AlertStatus, AlertingOptions, WebhookTarget, } from './alerting/types';
30
30
  export { ActivityAsyncPendingEvent, ActivityCompletedEvent, ActivityFailedEvent, ActivityStartedEvent, AlertFiredEvent, AlertResolvedEvent, AttributesChangedEvent, CheckpointSizeWarningEvent, ConstraintViolatedEvent, DevelopmentWarningEvent, ScheduleFiredEvent, ScheduleMissedFireEvent, SignalDeliveredEvent, SignalReceivedEvent, StorageSizeReportedEvent, TaskResultDeadLetteredEvent, UpdateCompletedEvent, UpdateReceivedEvent, WorkflowCancelledEvent, WorkflowCompletedEvent, WorkflowDefinitionRegisteredEvent, WorkflowFailedEvent, WorkflowRecoverySkippedEvent, WorkflowResumedEvent, WorkflowStartedEvent, WorkflowSuspendedEvent, WorkflowTeardownEvent, WorkflowTimedOutEvent, } from './core/events';
@@ -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,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(`
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};