@lostgradient/weft 0.2.1 → 0.3.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 (188) hide show
  1. package/README.md +47 -22
  2. package/dist/cli/generated/operation-client.generated.d.ts +28 -1
  3. package/dist/cli/generated/operation-client.generated.js +2 -0
  4. package/dist/cli-main.js +79 -79
  5. package/dist/client/handle-delegation.d.ts +4 -0
  6. package/dist/client/handle-delegation.js +6 -0
  7. package/dist/client/http-client-requests.d.ts +2 -0
  8. package/dist/client/http-client-requests.js +3 -0
  9. package/dist/client/http-client.d.ts +4 -1
  10. package/dist/client/http-client.js +9 -1
  11. package/dist/client/interface.d.ts +57 -2
  12. package/dist/client/local.d.ts +4 -1
  13. package/dist/client/local.js +7 -0
  14. package/dist/client/start-body.d.ts +7 -1
  15. package/dist/client/start-body.js +13 -4
  16. package/dist/core/codec/extension-codec.js +4 -2
  17. package/dist/core/codec/index.d.ts +1 -0
  18. package/dist/core/codec/index.js +1 -0
  19. package/dist/core/codec/serializer-registry.d.ts +122 -0
  20. package/dist/core/codec/serializer-registry.js +51 -0
  21. package/dist/core/context/index.d.ts +9 -0
  22. package/dist/core/context/internals.d.ts +9 -0
  23. package/dist/core/context/internals.js +3 -0
  24. package/dist/core/context/run-operation.d.ts +16 -3
  25. package/dist/core/context/run-operation.js +16 -7
  26. package/dist/core/engine/bulk-operations.js +1 -1
  27. package/dist/core/engine/construction.d.ts +0 -1
  28. package/dist/core/engine/construction.js +10 -1
  29. package/dist/core/engine/disposal.js +12 -0
  30. package/dist/core/engine/engine-create-types.d.ts +0 -14
  31. package/dist/core/engine/engine-internal-types.d.ts +12 -0
  32. package/dist/core/engine/engine-leak-warnings.d.ts +6 -0
  33. package/dist/core/engine/engine-leak-warnings.js +4 -0
  34. package/dist/core/engine/engine-runtime-helpers.d.ts +17 -0
  35. package/dist/core/engine/engine-runtime-helpers.js +26 -5
  36. package/dist/core/engine/errors.d.ts +74 -0
  37. package/dist/core/engine/errors.js +25 -1
  38. package/dist/core/engine/handle-result.js +1 -1
  39. package/dist/core/engine/handles.d.ts +89 -40
  40. package/dist/core/engine/handles.js +25 -27
  41. package/dist/core/engine/index.d.ts +96 -4
  42. package/dist/core/engine/index.js +75 -4
  43. package/dist/core/engine/inline-launch-queue.d.ts +14 -0
  44. package/dist/core/engine/inline-launch-queue.js +32 -7
  45. package/dist/core/engine/internals.d.ts +18 -10
  46. package/dist/core/engine/lifecycle/fork-helpers.js +1 -7
  47. package/dist/core/engine/lifecycle/persist.js +5 -20
  48. package/dist/core/engine/lifecycle/resume.js +25 -4
  49. package/dist/core/engine/lifecycle/start-commit.d.ts +47 -0
  50. package/dist/core/engine/lifecycle/start-commit.js +27 -0
  51. package/dist/core/engine/lifecycle/start-exec.d.ts +30 -2
  52. package/dist/core/engine/lifecycle/start-exec.js +38 -0
  53. package/dist/core/engine/lifecycle/start-or-signal-resolution.d.ts +79 -0
  54. package/dist/core/engine/lifecycle/start-or-signal-resolution.js +60 -0
  55. package/dist/core/engine/lifecycle/start-or-signal.d.ts +45 -0
  56. package/dist/core/engine/lifecycle/start-or-signal.js +141 -0
  57. package/dist/core/engine/lifecycle/start.d.ts +3 -3
  58. package/dist/core/engine/lifecycle/start.js +31 -37
  59. package/dist/core/engine/lifecycle.d.ts +3 -2
  60. package/dist/core/engine/lifecycle.js +9 -2
  61. package/dist/core/engine/listing.js +1 -1
  62. package/dist/core/engine/persisted-data-version.d.ts +5 -9
  63. package/dist/core/engine/persisted-data-version.js +4 -5
  64. package/dist/core/engine/schedule-handle.d.ts +45 -0
  65. package/dist/core/engine/schedule-handle.js +26 -0
  66. package/dist/core/engine/schedules.d.ts +1 -1
  67. package/dist/core/engine/schedules.js +7 -3
  68. package/dist/core/engine/second-instance-detector.d.ts +96 -0
  69. package/dist/core/engine/second-instance-detector.js +108 -0
  70. package/dist/core/engine/signals.d.ts +22 -0
  71. package/dist/core/engine/signals.js +15 -0
  72. package/dist/core/engine/termination/cleanup.d.ts +25 -0
  73. package/dist/core/engine/termination/cleanup.js +19 -1
  74. package/dist/core/engine/termination/complete.js +4 -3
  75. package/dist/core/engine/termination/suspend.d.ts +68 -0
  76. package/dist/core/engine/termination/suspend.js +41 -0
  77. package/dist/core/engine/termination.d.ts +4 -2
  78. package/dist/core/engine/termination.js +2 -0
  79. package/dist/core/engine/validation.js +25 -1
  80. package/dist/core/engine/workflow-feed.d.ts +5 -3
  81. package/dist/core/events/event-map.d.ts +2 -1
  82. package/dist/core/events/workflow-events.d.ts +23 -0
  83. package/dist/core/events/workflow-events.js +9 -0
  84. package/dist/core/list-filter-validation.js +2 -1
  85. package/dist/core/start-workflow-validation.d.ts +22 -0
  86. package/dist/core/start-workflow-validation.js +11 -1
  87. package/dist/core/step-context.d.ts +10 -6
  88. package/dist/core/step-context.js +7 -15
  89. package/dist/core/types/activity.d.ts +6 -3
  90. package/dist/core/types/identity.d.ts +8 -1
  91. package/dist/core/types/launch-metadata.d.ts +33 -0
  92. package/dist/core/types/launch-metadata.js +0 -0
  93. package/dist/core/types/message-handles.d.ts +25 -0
  94. package/dist/core/types/options.d.ts +48 -54
  95. package/dist/core/types/reviews.d.ts +2 -1
  96. package/dist/core/types/services-resolution.d.ts +47 -0
  97. package/dist/core/types/services-resolution.js +0 -0
  98. package/dist/core/types/state.d.ts +11 -11
  99. package/dist/core/types/workflow-builder.d.ts +5 -4
  100. package/dist/core/types/workflow-function.d.ts +17 -0
  101. package/dist/core/types/workflow-snapshot.d.ts +29 -0
  102. package/dist/core/types/workflow-snapshot.js +0 -0
  103. package/dist/core/types.d.ts +3 -0
  104. package/dist/core/types.js +3 -0
  105. package/dist/core/weft-error.d.ts +1 -1
  106. package/dist/core/weft-error.js +3 -1
  107. package/dist/diagnostics/doctor.js +6 -3
  108. package/dist/diagnostics/format.js +2 -2
  109. package/dist/diagnostics/types.d.ts +1 -0
  110. package/dist/diagnostics/version-check.js +6 -4
  111. package/dist/index.d.ts +4 -4
  112. package/dist/index.js +10 -1
  113. package/dist/json-schema.js +1 -1
  114. package/dist/mcp/cli.js +35 -35
  115. package/dist/mcp/list-filter.js +2 -1
  116. package/dist/mcp/session.js +1 -0
  117. package/dist/observability/index.js +2 -2
  118. package/dist/server/handler.js +30 -30
  119. package/dist/server/index.js +33 -33
  120. package/dist/server/interactive-operations.js +1 -0
  121. package/dist/server/operations/resume-workflow.js +2 -2
  122. package/dist/server/operations/start-or-signal-workflow.d.ts +39 -0
  123. package/dist/server/operations/start-or-signal-workflow.js +140 -0
  124. package/dist/server/operations/start-workflow-options.d.ts +32 -0
  125. package/dist/server/operations/start-workflow-options.js +63 -0
  126. package/dist/server/operations/start-workflow.js +7 -69
  127. package/dist/server/operations/suspend-workflow.d.ts +13 -0
  128. package/dist/server/operations/suspend-workflow.js +36 -0
  129. package/dist/server/rest-binding.d.ts +18 -7
  130. package/dist/server/rest-bindings.js +12 -0
  131. package/dist/server/runtime/task-dispatch.js +5 -3
  132. package/dist/server/runtime/task-polling.d.ts +16 -2
  133. package/dist/server/runtime/task-polling.js +20 -5
  134. package/dist/server/runtime/websocket-worker.js +8 -0
  135. package/dist/server/serve-internals.d.ts +8 -0
  136. package/dist/server/serve-internals.js +4 -2
  137. package/dist/server/task-state.d.ts +8 -0
  138. package/dist/service-worker/index.js +28 -28
  139. package/dist/storage/capabilities.d.ts +10 -2
  140. package/dist/storage/capabilities.js +2 -2
  141. package/dist/storage/http.js +2 -2
  142. package/dist/storage/index.d.ts +6 -1
  143. package/dist/storage/indexeddb.js +1 -1
  144. package/dist/storage/interface.d.ts +26 -0
  145. package/dist/storage/interface.js +1 -1
  146. package/dist/storage/key-prefixes.d.ts +1 -1
  147. package/dist/storage/key-prefixes.js +2 -0
  148. package/dist/storage/lmdb.js +1 -1
  149. package/dist/storage/memory.js +1 -1
  150. package/dist/storage/neon-value-mapping.d.ts +47 -0
  151. package/dist/storage/neon-value-mapping.js +11 -0
  152. package/dist/storage/neon.d.ts +108 -0
  153. package/dist/storage/neon.js +10 -0
  154. package/dist/storage/node-sqlite-loader.d.ts +71 -0
  155. package/dist/storage/node-sqlite-loader.js +41 -0
  156. package/dist/storage/node-sqlite.d.ts +1 -19
  157. package/dist/storage/node-sqlite.js +38 -32
  158. package/dist/storage/postgres-key-value-queries.d.ts +79 -0
  159. package/dist/storage/postgres-key-value-queries.js +63 -0
  160. package/dist/storage/resolve.d.ts +2 -165
  161. package/dist/storage/resolve.js +1 -1
  162. package/dist/storage/scoped-storage.js +1 -1
  163. package/dist/storage/storage-configuration.d.ts +209 -0
  164. package/dist/storage/storage-configuration.js +0 -0
  165. package/dist/storage/text-value-store.d.ts +9 -9
  166. package/dist/storage/turso.js +2 -2
  167. package/dist/storage/typed-storage.js +1 -1
  168. package/dist/storage/web-extension.js +1 -1
  169. package/dist/testing/index.js +33 -33
  170. package/dist/version.d.ts +1 -1
  171. package/dist/version.js +1 -1
  172. package/dist/worker/index.js +9 -5
  173. package/dist/worker/long-poll.js +4 -0
  174. package/dist/worker/protocol-messages.d.ts +20 -0
  175. package/dist/worker/protocol-schemas.d.ts +32 -0
  176. package/dist/worker/protocol-schemas.js +8 -4
  177. package/dist/worker/protocol-task-result.d.ts +28 -0
  178. package/dist/worker/protocol-task-result.js +76 -0
  179. package/dist/worker/protocol.d.ts +4 -15
  180. package/dist/worker/protocol.js +1 -1
  181. package/dist/worker/registry/fair-share.d.ts +29 -0
  182. package/dist/worker/registry/fair-share.js +30 -0
  183. package/dist/worker/registry/routing.d.ts +18 -0
  184. package/dist/worker/registry/routing.js +14 -0
  185. package/dist/worker/registry/types.d.ts +7 -0
  186. package/dist/worker/registry.d.ts +16 -1
  187. package/dist/worker/registry.js +24 -36
  188. package/package.json +17 -4
@@ -9,19 +9,28 @@ import type { PayloadSizePolicy } from './payload-size-policy.ts';
9
9
  import type { Duration, RetentionPolicy } from './retry-retention.ts';
10
10
  import type { SearchAttributeHandle, SearchAttributeValue } from './search-attributes.ts';
11
11
  import type { Serializer } from './serializer.ts';
12
+ import type { WorkflowServicesResolution, WorkflowServicesResolverInfo } from './services-resolution.ts';
12
13
  /**
13
14
  * Options accepted by `engine.start(type, input, options?)`.
14
15
  *
15
16
  * Every field is optional. `id` lets you specify your own workflow ID;
16
- * `idempotencyKey` enforces single-execution semantics within a window;
17
- * `executionTimeout` caps wall-clock time; `startAt`/`startAfter` defer
17
+ * `idempotencyKey` enforces at-most-once starts (a repeated key returns the
18
+ * existing run instead of starting a second, even after it reaches a terminal
19
+ * state); `executionTimeout` caps wall-clock time; `startAt`/`startAfter` defer
18
20
  * execution; `tags` and `searchAttributes` make the workflow discoverable
19
- * via filters.
21
+ * via filters. `id` and `idempotencyKey` are mutually exclusive — idempotency
22
+ * assigns its own generated id and dedups through the key.
20
23
  *
21
- * `HttpClient.start` forwards `searchAttributes` to the server. It rejects
22
- * `idempotencyKey` until the HTTP start protocol exposes matching
23
- * single-execution semantics, so callers do not accidentally rely on a
24
- * silently dropped option.
24
+ * The `idempotencyKey` mapping is durable and permanent: it survives the run
25
+ * reaching a terminal state, so repeat calls keep returning the same handle. When
26
+ * the workflow record is purged or swept by retention the mapping itself survives
27
+ * (purge does not touch the `start-idem:` keyspace) but now points at a gone run;
28
+ * a call with that spent key throws {@link IdempotencyKeyPurgedError} (mapped to
29
+ * HTTP 409 over REST/JSON-RPC) rather than silently starting a new run.
30
+ *
31
+ * Both `LocalClient.start` and `HttpClient.start` forward `idempotencyKey` and
32
+ * `searchAttributes` to the server, so single-execution semantics hold across
33
+ * transports. Idempotent start requires a storage backend with `conditionalBatch`.
25
34
  *
26
35
  * @example Start a delayed workflow with tags and search attributes
27
36
  * ```ts
@@ -64,53 +73,19 @@ export interface StartOptions {
64
73
  * non-serializable value cannot cross to a Worker.
65
74
  */
66
75
  services?: unknown;
67
- }
68
- /**
69
- * Result of {@link EngineOptions.resolveWorkflowServices}. An explicit union
70
- * rather than a nullable return: `'unavailable'` is a deliberate, named outcome
71
- * (the run's dependencies cannot be rebuilt in this process) that fails just
72
- * that recovered run it does not overload the resolved value with a lifecycle
73
- * signal.
74
- *
75
- * @example
76
- * ```ts
77
- * import { type WorkflowServicesResolution } from '@lostgradient/weft';
78
- *
79
- * const ok: WorkflowServicesResolution = {
80
- * status: 'available',
81
- * services: { db: { query: () => [] } },
82
- * };
83
- * const no: WorkflowServicesResolution = { status: 'unavailable', reason: 'no config' };
84
- * void ok;
85
- * void no;
86
- * ```
87
- */
88
- export type WorkflowServicesResolution = {
89
- status: 'available';
90
- services: unknown;
91
- } | {
92
- status: 'unavailable';
93
- reason: string;
94
- };
95
- /**
96
- * Information passed to {@link EngineOptions.resolveWorkflowServices} for each
97
- * recovered workflow. `input` is the original durable launch input, available
98
- * at resume time — typically enough to rebuild the run's dependencies (tenant,
99
- * model, tool registry) without a side table.
100
- *
101
- * @example
102
- * ```ts
103
- * import { type WorkflowServicesResolverInfo } from '@lostgradient/weft';
104
- *
105
- * function describe(info: WorkflowServicesResolverInfo): string {
106
- * return `${info.workflowType}/${info.workflowId}`;
107
- * }
108
- * ```
109
- */
110
- export interface WorkflowServicesResolverInfo {
111
- workflowId: string;
112
- workflowType: string;
113
- input: unknown;
76
+ /**
77
+ * When `false`, `engine.start()` resolves only after the workflow has begun
78
+ * executing (its generator has been driven its first turn), not merely after
79
+ * the initial state is persisted. The default (`true`) returns a handle as
80
+ * soon as state is written and queues execution onto a macrotask, so a caller
81
+ * cannot assume the run is live without a round-trip. Use `defer: false` when a
82
+ * caller — or a test — must rely on the run being live immediately after
83
+ * `await engine.start(...)`. If the body throws on its first turn, `start()`
84
+ * still resolves; observe the failure via `handle.result()`. Inline mode only;
85
+ * throws at `engine.start()` under `workflowExecutionMode: 'worker'` or with a
86
+ * delayed start (`startAt`/`startAfter`), neither of which has liveness to await.
87
+ */
88
+ defer?: boolean;
114
89
  }
115
90
  /**
116
91
  * Options for {@link Engine.fork}. Controls which checkpoint step to fork
@@ -162,6 +137,25 @@ export interface EngineOptions {
162
137
  retention?: RetentionPolicy;
163
138
  retentionSweepInterval?: Duration;
164
139
  retentionSweepBatchSize?: number;
140
+ /**
141
+ * Enable a best-effort, warn-only detector for a SECOND engine instance writing
142
+ * to the same durable store — a smoke alarm for singleton misconfiguration (an
143
+ * autoscaler above one replica, or overlapping rolling deploys). Default `false`.
144
+ * This is **liveness, not fencing**: it never blocks boot, gates recovery, or
145
+ * prevents duplicate execution — enforce one instance at the infrastructure layer
146
+ * (one replica + a `Recreate` deploy, or a single systemd unit). When enabled,
147
+ * each engine writes a periodic heartbeat and warns (`process.emitWarning`) when
148
+ * it sees another instance's heartbeat advancing while it runs. The periodic
149
+ * writes are an ongoing cost, so leave it off unless you want the backstop.
150
+ */
151
+ detectSecondInstance?: boolean;
152
+ /**
153
+ * Heartbeat interval for {@link EngineOptions.detectSecondInstance} (default
154
+ * `15s`). A foreign heartbeat must advance across two intervals before warning,
155
+ * so this also sets how long a deploy overlap must last before it warns — keep it
156
+ * well above your deploy drain window. Ignored when detection is disabled.
157
+ */
158
+ secondInstanceHeartbeatInterval?: Duration;
165
159
  /**
166
160
  * History circuit-breaker thresholds. When `history.maxEvents` is set, a
167
161
  * workflow whose event-log record count would exceed it is forced to a
@@ -54,7 +54,8 @@ export type ReviewStatus = 'pending' | 'completed';
54
54
  * Filter accepted by `engine.listReviews(filter?)` and the `/v1/reviews`
55
55
  * transport surfaces.
56
56
  *
57
- * Omitting `status` preserves the legacy pending-only behavior.
57
+ * Omitting `status` lists pending reviews; pass `status: 'completed'` to list
58
+ * completed reviews instead.
58
59
  *
59
60
  * @example
60
61
  * ```ts
@@ -0,0 +1,47 @@
1
+ /**
2
+ * Result of {@link EngineOptions.resolveWorkflowServices}. An explicit union
3
+ * rather than a nullable return: `'unavailable'` is a deliberate, named outcome
4
+ * (the run's dependencies cannot be rebuilt in this process) that fails just
5
+ * that recovered run — it does not overload the resolved value with a lifecycle
6
+ * signal.
7
+ *
8
+ * @example
9
+ * ```ts
10
+ * import { type WorkflowServicesResolution } from '@lostgradient/weft';
11
+ *
12
+ * const ok: WorkflowServicesResolution = {
13
+ * status: 'available',
14
+ * services: { db: { query: () => [] } },
15
+ * };
16
+ * const no: WorkflowServicesResolution = { status: 'unavailable', reason: 'no config' };
17
+ * void ok;
18
+ * void no;
19
+ * ```
20
+ */
21
+ export type WorkflowServicesResolution = {
22
+ status: 'available';
23
+ services: unknown;
24
+ } | {
25
+ status: 'unavailable';
26
+ reason: string;
27
+ };
28
+ /**
29
+ * Information passed to {@link EngineOptions.resolveWorkflowServices} for each
30
+ * recovered workflow. `input` is the original durable launch input, available
31
+ * at resume time — typically enough to rebuild the run's dependencies (tenant,
32
+ * model, tool registry) without a side table.
33
+ *
34
+ * @example
35
+ * ```ts
36
+ * import { type WorkflowServicesResolverInfo } from '@lostgradient/weft';
37
+ *
38
+ * function describe(info: WorkflowServicesResolverInfo): string {
39
+ * return `${info.workflowType}/${info.workflowId}`;
40
+ * }
41
+ * ```
42
+ */
43
+ export interface WorkflowServicesResolverInfo {
44
+ workflowId: string;
45
+ workflowType: string;
46
+ input: unknown;
47
+ }
File without changes
@@ -42,7 +42,17 @@ export interface WorkflowState {
42
42
  * leaves this `undefined`).
43
43
  */
44
44
  terminationReason?: TerminationReason;
45
- version: string;
45
+ /**
46
+ * The `(workflowVersion, agentVersion?, toolVersions?)` tuple captured for
47
+ * this workflow. This is the single canonical representation of version
48
+ * metadata on the state: it shares the {@link WorkflowVersionTuple} shape the
49
+ * event log records, so the two cannot drift, and it is rewritten on every
50
+ * versioned persist. `workflowVersion` is always present;
51
+ * `agentVersion`/`toolVersions` are present only when the workflow declares
52
+ * them. Resuming compares this against the currently registered definition to
53
+ * detect version drift.
54
+ */
55
+ versionTuple: WorkflowVersionTuple;
46
56
  /**
47
57
  * Owner identifier for execution-scoped durable state. Top-level workflows
48
58
  * own their own execution state; durable child workflows inherit the
@@ -50,16 +60,6 @@ export interface WorkflowState {
50
60
  * tree.
51
61
  */
52
62
  executionStateOwnerId?: string;
53
- /**
54
- * Legacy version tuple metadata retained so existing persisted workflow
55
- * states can still be decoded and compared during recovery.
56
- */
57
- agentVersion?: string;
58
- /**
59
- * Legacy version tuple metadata retained so existing persisted workflow
60
- * states can still be decoded and compared during recovery.
61
- */
62
- toolVersions?: string[];
63
63
  createdAt: number;
64
64
  startedAt?: number;
65
65
  updatedAt: number;
@@ -47,10 +47,11 @@ export type WorkflowGenerator<TInput, TOutput, TActivities extends ActivityMap,
47
47
  * `TSearchAttributes`), and the builder threads its normalised maps through
48
48
  * this alias so `.execute(fn)` sees the right `ctx` shape inside `fn`.
49
49
  *
50
- * Legacy bare-`WorkflowContext` callers continue to typecheck because the
51
- * interface's generics all default to empty/permissive shapes, so the typed
52
- * overloads de-prioritise to `never` and existing string-name/callable
53
- * overloads still match.
50
+ * Bare-`WorkflowContext` callers (no declared activity/signal/etc. maps)
51
+ * typecheck because the interface's generics all default to permissive shapes:
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.
54
55
  */
55
56
  export type WorkflowContextOf<TActivities extends ActivityMap = ActivityMap, TSignals extends SignalMap = SignalMap, TUpdates extends UpdateMap = UpdateMap, TQueries extends QueryMap = QueryMap, TSearchAttributes extends SearchAttributeSchema = SearchAttributeSchema> = WorkflowContext<TActivities, TSignals, TUpdates, TQueries, TSearchAttributes>;
56
57
  /**
@@ -54,6 +54,23 @@ export type WorkflowFunction<TInput = unknown, TOutput = unknown> = (context: Wo
54
54
  export interface StepWorkflowContext {
55
55
  readonly workflowId: string;
56
56
  readonly signal: AbortSignal;
57
+ /**
58
+ * Run `fn` as a durable step. Each call routes through the same machinery as
59
+ * `ctx.run(...)`: the engine assigns a positional replay slot, persists the
60
+ * result to the checkpoint, and on crash recovery returns the stored result
61
+ * without re-running `fn`. `name` is the durable activity label (timeline and
62
+ * diagnostics only) — replay is keyed by position, not by name.
63
+ *
64
+ * Because durability is positional, you must `await` each step before
65
+ * starting the next: steps must be queued in a deterministic order so the
66
+ * original run and a recovered run agree on which slot is which. Firing steps
67
+ * concurrently (so a continuation enqueues further steps in completion order)
68
+ * can return a wrong cached value after a crash. For parallelism, durable
69
+ * timers, or signals, use the generator API instead.
70
+ *
71
+ * Requires `workflowExecutionMode: 'inline'` (the default); the worker
72
+ * execution strategy has no step machinery and throws an actionable error.
73
+ */
57
74
  step<T>(name: string, fn: () => Promise<T> | T): Promise<T>;
58
75
  }
59
76
  /**
@@ -0,0 +1,29 @@
1
+ import type { WorkflowStatus } from './identity.ts';
2
+ /**
3
+ * A point-in-time view of a workflow's progress, returned by
4
+ * {@link WorkflowHandle.snapshot}. Combines the persisted status with the
5
+ * current checkpoint step (the run's cursor), so a caller — typically after
6
+ * `engine.recoverAll()` — can rebuild its own progress adapter for a recovered
7
+ * run and re-register it on a live surface, without awaiting the run's final
8
+ * result.
9
+ *
10
+ * `step` is the run's current checkpoint step: the number of generator turns it
11
+ * has advanced. For a run live in this engine it reflects the latest in-memory
12
+ * checkpoint (which may be one step ahead of the last durable commit); for a
13
+ * run inspected or recovered in a fresh process it reflects the durably
14
+ * persisted checkpoint. It is `0` for a run that has its initial checkpoint but
15
+ * has not yet advanced, and increases as the run makes progress.
16
+ *
17
+ * @example
18
+ * ```ts
19
+ * import { type WorkflowSnapshot } from '@lostgradient/weft';
20
+ *
21
+ * function describe(snapshot: WorkflowSnapshot): string {
22
+ * return `${snapshot.status} @ step ${snapshot.step}`;
23
+ * }
24
+ * ```
25
+ */
26
+ export interface WorkflowSnapshot {
27
+ status: WorkflowStatus;
28
+ step: number;
29
+ }
File without changes
@@ -7,6 +7,7 @@ export * from './types/definition-schema-to-json.ts';
7
7
  export * from './types/definition-schema.ts';
8
8
  export * from './types/history-policy.ts';
9
9
  export * from './types/identity.ts';
10
+ export * from './types/launch-metadata.ts';
10
11
  export * from './types/message-handles.ts';
11
12
  export * from './types/options.ts';
12
13
  export * from './types/payload-size-policy.ts';
@@ -15,6 +16,7 @@ export * from './types/reviews.ts';
15
16
  export * from './types/schedules.ts';
16
17
  export * from './types/search-attributes.ts';
17
18
  export * from './types/serializer.ts';
19
+ export * from './types/services-resolution.ts';
18
20
  export * from './types/standard-schema-validate.ts';
19
21
  export * from './types/state.ts';
20
22
  export * from './types/workflow-builder-helpers.ts';
@@ -24,3 +26,4 @@ export * from './types/workflow-context.ts';
24
26
  export * from './types/workflow-function.ts';
25
27
  export * from './types/workflow-registries.ts';
26
28
  export * from './types/workflow-registry.ts';
29
+ export * from './types/workflow-snapshot.ts';
@@ -7,6 +7,7 @@ export * from "./types/definition-schema-to-json.js";
7
7
  export * from "./types/definition-schema.js";
8
8
  export * from "./types/history-policy.js";
9
9
  export * from "./types/identity.js";
10
+ export * from "./types/launch-metadata.js";
10
11
  export * from "./types/message-handles.js";
11
12
  export * from "./types/options.js";
12
13
  export * from "./types/payload-size-policy.js";
@@ -15,6 +16,7 @@ export * from "./types/reviews.js";
15
16
  export * from "./types/schedules.js";
16
17
  export * from "./types/search-attributes.js";
17
18
  export * from "./types/serializer.js";
19
+ export * from "./types/services-resolution.js";
18
20
  export * from "./types/standard-schema-validate.js";
19
21
  export * from "./types/state.js";
20
22
  export * from "./types/workflow-builder-helpers.js";
@@ -24,3 +26,4 @@ export * from "./types/workflow-context.js";
24
26
  export * from "./types/workflow-function.js";
25
27
  export * from "./types/workflow-registries.js";
26
28
  export * from "./types/workflow-registry.js";
29
+ export * from "./types/workflow-snapshot.js";
@@ -22,7 +22,7 @@
22
22
  * }
23
23
  * ```
24
24
  */
25
- export type WeftErrorCode = 'WorkflowAlreadyExistsError' | 'BulkDeleteRequiresTerminalWorkflowsError' | 'BulkOperationConfirmationError' | 'WorkflowTypeNotRegisteredForRecoveryError' | 'EngineCreateNameMismatchError' | 'EngineDisposedError' | 'WorkflowNotFoundError' | 'WorkflowNotRegisteredError' | 'ActivityResolutionError' | 'PersistedDataIncompatibleError' | 'WorkflowTimeoutError' | 'HttpClientError' | 'WorkerProtocolIncompatibleError' | 'UpdateTimeoutError' | 'UpdateValidationError' | 'WorkflowTerminalError' | 'WorkflowBuilderError' | 'VersionMismatchError' | 'EffectReplayConflictError' | 'ReviewTimeoutError' | 'AtomicStateConflictError' | 'StandardSchemaValidationError' | 'ActivityReconciliationCapabilityError' | 'ActivityReconciliationConflictError' | 'ActivityReconciliationIndeterminateError' | 'AsyncActivityTokenNotFoundError' | 'PayloadSizeExceededError';
25
+ export type WeftErrorCode = 'WorkflowAlreadyExistsError' | 'BulkDeleteRequiresTerminalWorkflowsError' | 'BulkOperationConfirmationError' | 'WorkflowTypeNotRegisteredForRecoveryError' | 'EngineCreateNameMismatchError' | 'EngineDisposedError' | 'WorkflowNotFoundError' | 'WorkflowNotRegisteredError' | 'ActivityResolutionError' | 'PersistedDataIncompatibleError' | 'WorkflowTimeoutError' | 'HttpClientError' | 'WorkerProtocolIncompatibleError' | 'UpdateTimeoutError' | 'UpdateValidationError' | 'WorkflowTerminalError' | 'WorkflowBuilderError' | 'VersionMismatchError' | 'EffectReplayConflictError' | 'ReviewTimeoutError' | 'AtomicStateConflictError' | 'StandardSchemaValidationError' | 'ActivityReconciliationCapabilityError' | 'ActivityReconciliationConflictError' | 'ActivityReconciliationIndeterminateError' | 'AsyncActivityTokenNotFoundError' | 'PayloadSizeExceededError' | 'StartOrSignalConflictError' | 'IdempotencyKeyPurgedError';
26
26
  /**
27
27
  * Generic abstract base for all Weft library errors. The `TCode` parameter
28
28
  * makes each subclass's `code` its own literal type; the exported base surface
@@ -33,7 +33,9 @@ const publicWeftErrorCodeMap = {
33
33
  ActivityReconciliationConflictError: !0,
34
34
  ActivityReconciliationIndeterminateError: !0,
35
35
  AsyncActivityTokenNotFoundError: !0,
36
- PayloadSizeExceededError: !0
36
+ PayloadSizeExceededError: !0,
37
+ StartOrSignalConflictError: !0,
38
+ IdempotencyKeyPurgedError: !0
37
39
  }, PUBLIC_WEFT_ERROR_CODES = new Set(Object.keys(publicWeftErrorCodeMap));
38
40
  export function isWeftError(value) {
39
41
  return value instanceof WeftError;
@@ -1,4 +1,6 @@
1
1
  import { decode } from "../core/codec.js";
2
+ import { decodeWorkflowState } from "../core/engine/validation.js";
3
+ import { isTopLevelWorkflowStateKey } from "../core/engine/workflow-state-stream.js";
2
4
  import { fileSize } from "../runtime/portable.js";
3
5
  import { KEYS } from "../storage/interface.js";
4
6
  import { generateRecommendations } from "./recommendations.js";
@@ -89,13 +91,14 @@ async function aggregateWorkflowScan(storage, now) {
89
91
  completed: 0,
90
92
  failed: 0,
91
93
  cancelled: 0,
92
- timedOut: 0
94
+ timedOut: 0,
95
+ suspended: 0
93
96
  };
94
97
  let total = 0, longestRunning = null, earliestCreatedAt = 1 / 0;
95
98
  for await (const [key, value] of storage.scan("wf:")) {
96
- if (key.includes(":ckpt"))
99
+ if (!isTopLevelWorkflowStateKey(key))
97
100
  continue;
98
- const state = decode(value);
101
+ const state = decodeWorkflowState(value);
99
102
  total++;
100
103
  statusCounts[mapStatusKey(state.status)]++;
101
104
  if (state.status === "running" && state.createdAt < earliestCreatedAt) {
@@ -47,8 +47,8 @@ function appendWorkflowsSection(lines, workflows) {
47
47
  lines.push(" Total: 0 (no workflows)");
48
48
  return;
49
49
  }
50
- const counts = workflows.statusCounts;
51
- lines.push(` Total: ${workflows.total} (${counts.running} running, ${counts.completed} completed, ${counts.failed} failed)`);
50
+ const counts = workflows.statusCounts, suspendedSummary = counts.suspended > 0 ? `, ${counts.suspended} suspended` : "";
51
+ lines.push(` Total: ${workflows.total} (${counts.running} running, ${counts.completed} completed, ${counts.failed} failed${suspendedSummary})`);
52
52
  if (workflows.longestRunning) {
53
53
  const longest = workflows.longestRunning;
54
54
  lines.push(` Longest running: ${longest.id} (started ${formatDuration(longest.elapsedMilliseconds)} ago, step ${longest.currentStep})`);
@@ -48,6 +48,7 @@ export interface WorkflowStatusCounts {
48
48
  failed: number;
49
49
  cancelled: number;
50
50
  timedOut: number;
51
+ suspended: number;
51
52
  }
52
53
  /**
53
54
  * Identity and elapsed wall-clock time of the longest-running workflow in
@@ -1,20 +1,22 @@
1
- import { decode } from "../core/codec.js";
1
+ import { decodeWorkflowState } from "../core/engine/validation.js";
2
+ import { isTopLevelWorkflowStateKey } from "../core/engine/workflow-state-stream.js";
2
3
  import { DEFAULT_WORKFLOW_VERSION, checkVersionCompatibility } from "../core/versioning.js";
3
4
  async function groupActiveWorkflowsByType(storage) {
4
5
  const groups = new Map;
5
6
  for await (const [key, bytes] of storage.scan("wf:")) {
6
- if (key.includes(":ckpt"))
7
+ if (!isTopLevelWorkflowStateKey(key))
7
8
  continue;
8
- const state = decode(bytes);
9
+ const state = decodeWorkflowState(bytes);
9
10
  if (state.status !== "running" && state.status !== "pending")
10
11
  continue;
12
+ const storedVersion = state.versionTuple.workflowVersion;
11
13
  let group = groups.get(state.type);
12
14
  if (!group) {
13
15
  group = { count: 0, versionCounts: new Map };
14
16
  groups.set(state.type, group);
15
17
  }
16
18
  group.count++;
17
- group.versionCounts.set(state.version, (group.versionCounts.get(state.version) ?? 0) + 1);
19
+ group.versionCounts.set(storedVersion, (group.versionCounts.get(storedVersion) ?? 0) + 1);
18
20
  }
19
21
  return groups;
20
22
  }
package/dist/index.d.ts CHANGED
@@ -20,13 +20,13 @@ export { WeftError, isWeftError, isWeftErrorCode, isWeftErrorLike } from './core
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, EngineCreateNameMismatchError, EngineDisposedError, PersistedDataIncompatibleError, ScheduleHandle, WorkflowAlreadyExistsError, WorkflowHandle, WorkflowNotFoundError, WorkflowNotRegisteredError, WorkflowTypeNotRegisteredForRecoveryError, } from './core/engine';
23
+ export { ActivityReconciliationCapabilityError, ActivityReconciliationConflictError, ActivityReconciliationIndeterminateError, ActivityResolutionError, AsyncActivityTokenNotFoundError, BulkDeleteRequiresTerminalWorkflowsError, BulkOperationConfirmationError, Engine, EngineCreateNameMismatchError, EngineDisposedError, IdempotencyKeyPurgedError, PersistedDataIncompatibleError, ScheduleHandle, StartOrSignalConflictError, WorkflowAlreadyExistsError, WorkflowHandle, WorkflowNotFoundError, WorkflowNotRegisteredError, WorkflowSuspendNotSupportedError, WorkflowTypeNotRegisteredForRecoveryError, } from './core/engine';
24
24
  export type { EngineCreateOptions, EngineStateNamespace, RecoverAllOptions } from './core/engine';
25
25
  export { DEFAULT_CHECKPOINT_SIZE_WARNING_THRESHOLD, DEFAULT_MAX_NESTING_DEPTH, DEFAULT_RETRY_POLICY, DEFAULT_VISIBILITY_TIMEOUT_MS, HISTORY_CIRCUIT_BREAKER_REASON, WorkflowBuilderError, query, schedule, signal, update, workflow, } from './core/types';
26
- 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, BulkSignalAllCommitOptions, BulkSignalAllDryRunOptions, BulkSignalAllOptions, BulkSignalResult, BulkTagResult, Checkpoint, CheckpointState, CheckpointSummary, CompletedReviewEntry, CoordinatedUpdateResult, DefinitionSchema, Duration, EngineOptions, FailureCategory, ForkLineage, ForkOptions, HistoryPolicy, InferActivityEntries, InferActivityEntry, InferWorkflowEntries, InferWorkflowEntry, InitialBuilderState, 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, SubmitReviewOptions, TerminationReason, UpdateDefinition, UpdateMap, UpdatePayload, WorkerReplayOperationFailure, WorkerReplayOperationSignature, WorkflowAlreadyRegistered, WorkflowAtomicState, WorkflowAtomicStateOptions, WorkflowBuilder, WorkflowBuilderOptions, WorkflowContext, WorkflowDefinition, WorkflowEvent, WorkflowFunction, WorkflowGenerator, WorkflowId, WorkflowRegistry, WorkflowReplay, WorkflowServicesResolution, WorkflowServicesResolverInfo, WorkflowSessionState, WorkflowState, WorkflowStateNamespace, WorkflowStatus, WorkflowSummary, WorkflowTimelineEntry, WorkflowTimelineStatus, WorkflowTypeRetentionPolicy, } from './core/types';
26
+ 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, 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, StartOrSignalSignal, SubmitReviewOptions, TerminationReason, UpdateDefinition, UpdateMap, UpdatePayload, WorkerReplayOperationFailure, WorkerReplayOperationSignature, WorkflowAlreadyRegistered, WorkflowAtomicState, WorkflowAtomicStateOptions, WorkflowBuilder, WorkflowBuilderOptions, WorkflowContext, WorkflowDefinition, WorkflowEvent, WorkflowFunction, WorkflowGenerator, WorkflowId, WorkflowRegistry, WorkflowReplay, WorkflowServicesResolution, WorkflowServicesResolverInfo, WorkflowSessionState, WorkflowSnapshot, WorkflowState, WorkflowStateNamespace, WorkflowStatus, WorkflowSummary, WorkflowTimelineEntry, WorkflowTimelineStatus, WorkflowTypeRetentionPolicy, } from './core/types';
27
27
  export { AlertManager } from './alerting/index';
28
28
  export type { AlertAction, AlertMetric, AlertRule, AlertState, AlertStatus, AlertingOptions, WebhookTarget, } from './alerting/types';
29
- export { ActivityAsyncPendingEvent, ActivityCompletedEvent, ActivityFailedEvent, ActivityStartedEvent, AlertFiredEvent, AlertResolvedEvent, AttributesChangedEvent, CheckpointSizeWarningEvent, ConstraintViolatedEvent, DevelopmentWarningEvent, SignalDeliveredEvent, SignalReceivedEvent, StorageSizeReportedEvent, UpdateCompletedEvent, UpdateReceivedEvent, WorkflowCancelledEvent, WorkflowCompletedEvent, WorkflowFailedEvent, WorkflowRecoverySkippedEvent, WorkflowResumedEvent, WorkflowStartedEvent, WorkflowTimedOutEvent, } from './core/events';
29
+ export { ActivityAsyncPendingEvent, ActivityCompletedEvent, ActivityFailedEvent, ActivityStartedEvent, AlertFiredEvent, AlertResolvedEvent, AttributesChangedEvent, CheckpointSizeWarningEvent, ConstraintViolatedEvent, DevelopmentWarningEvent, SignalDeliveredEvent, SignalReceivedEvent, StorageSizeReportedEvent, UpdateCompletedEvent, UpdateReceivedEvent, WorkflowCancelledEvent, WorkflowCompletedEvent, WorkflowFailedEvent, WorkflowRecoverySkippedEvent, WorkflowResumedEvent, WorkflowStartedEvent, WorkflowSuspendedEvent, WorkflowTimedOutEvent, } from './core/events';
30
30
  export type { TypedEventTarget, WeftEventMap, WorkflowRecoverySkippedReason } from './core/events';
31
31
  export { detectRuntime, hashBytes, hashString, sleep } from './runtime/portable';
32
32
  export type { RuntimeKind } from './runtime/portable';
@@ -43,7 +43,7 @@ export { copyTextKeyValueRowsToStorage } from './storage/text-value-import';
43
43
  export type { CopyTextKeyValueRowsToStorageOptions, CopyTextKeyValueRowsToStorageResult, TextKeyValueRow, } from './storage/text-value-import';
44
44
  export { jsonCodec, msgpackCodec, withCodec } from './storage/typed-storage';
45
45
  export type { CodecStorageOptions, MessagePackValue, StorageCodec, StorageValueParser, TypedBatchOperation, TypedConditionalBatchCondition, TypedStorage, } from './storage/typed-storage';
46
- export { decode, encode, validateCloneable } from './core/codec';
46
+ export { decode, encode, registerSerializer, validateCloneable, type SerializerHandlers, } from './core/codec';
47
47
  export { PayloadSizeExceededError } from './core/payload-size';
48
48
  export { advanceCheckpoint, checkpointSizeBytes, createCheckpoint, deserializeCheckpoint, serializeCheckpoint, } from './core/checkpoint';
49
49
  export { Scheduler, calculateBackoff, parseDuration } from './core/scheduler';
package/dist/index.js CHANGED
@@ -16,12 +16,15 @@ export {
16
16
  Engine,
17
17
  EngineCreateNameMismatchError,
18
18
  EngineDisposedError,
19
+ IdempotencyKeyPurgedError,
19
20
  PersistedDataIncompatibleError,
20
21
  ScheduleHandle,
22
+ StartOrSignalConflictError,
21
23
  WorkflowAlreadyExistsError,
22
24
  WorkflowHandle,
23
25
  WorkflowNotFoundError,
24
26
  WorkflowNotRegisteredError,
27
+ WorkflowSuspendNotSupportedError,
25
28
  WorkflowTypeNotRegisteredForRecoveryError
26
29
  } from "./core/engine.js";
27
30
  export {
@@ -60,6 +63,7 @@ export {
60
63
  WorkflowRecoverySkippedEvent,
61
64
  WorkflowResumedEvent,
62
65
  WorkflowStartedEvent,
66
+ WorkflowSuspendedEvent,
63
67
  WorkflowTimedOutEvent
64
68
  } from "./core/events.js";
65
69
  export { detectRuntime, hashBytes, hashString, sleep } from "./runtime/portable.js";
@@ -78,7 +82,12 @@ export { MemoryStorage } from "./storage/memory.js";
78
82
  export { ScopedStorage, scopedStorage } from "./storage/scoped-storage.js";
79
83
  export { copyTextKeyValueRowsToStorage } from "./storage/text-value-import.js";
80
84
  export { jsonCodec, msgpackCodec, withCodec } from "./storage/typed-storage.js";
81
- export { decode, encode, validateCloneable } from "./core/codec.js";
85
+ export {
86
+ decode,
87
+ encode,
88
+ registerSerializer,
89
+ validateCloneable
90
+ } from "./core/codec.js";
82
91
  export { PayloadSizeExceededError } from "./core/payload-size.js";
83
92
  export {
84
93
  advanceCheckpoint,
@@ -1,4 +1,4 @@
1
1
  // @bun
2
- var w=Object.defineProperty;var y=(j)=>j;function B(j,q){this[j]=y.bind(null,q)}var T=(j,q)=>{for(var z in q)w(j,z,{get:q[z],enumerable:!0,configurable:!0,set:B.bind(q,z)})};var X=(j,q)=>()=>(j&&(q=j(j=0)),q);var K,D,_;var Y=X(()=>{K=class K extends Error{code;constructor(j,q,z){super(q,z);this.code=j,this.name=j}};D={WorkflowAlreadyExistsError:!0,BulkDeleteRequiresTerminalWorkflowsError:!0,BulkOperationConfirmationError:!0,WorkflowTypeNotRegisteredForRecoveryError:!0,EngineCreateNameMismatchError:!0,EngineDisposedError:!0,WorkflowNotFoundError:!0,WorkflowNotRegisteredError:!0,ActivityResolutionError:!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,PayloadSizeExceededError:!0},_=new Set(Object.keys(D))});async function Z(j,q,z){let G=j["~standard"];if(!L(G))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 G.validate(q);if(H.issues===void 0)return H.value;throw new A({fieldName:z.fieldName,operation:z.operation,issues:H.issues.map(U)})}function Q(j){return j.map((q)=>q.path===""?q.message:`${q.path}: ${q.message}`).join(`
2
+ var w=Object.defineProperty;var y=(j)=>j;function B(j,q){this[j]=y.bind(null,q)}var T=(j,q)=>{for(var z in q)w(j,z,{get:q[z],enumerable:!0,configurable:!0,set:B.bind(q,z)})};var X=(j,q)=>()=>(j&&(q=j(j=0)),q);var K,D,_;var Y=X(()=>{K=class K extends Error{code;constructor(j,q,z){super(q,z);this.code=j,this.name=j}};D={WorkflowAlreadyExistsError:!0,BulkDeleteRequiresTerminalWorkflowsError:!0,BulkOperationConfirmationError:!0,WorkflowTypeNotRegisteredForRecoveryError:!0,EngineCreateNameMismatchError:!0,EngineDisposedError:!0,WorkflowNotFoundError:!0,WorkflowNotRegisteredError:!0,ActivityResolutionError:!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,PayloadSizeExceededError:!0,StartOrSignalConflictError:!0,IdempotencyKeyPurgedError:!0},_=new Set(Object.keys(D))});async function Z(j,q,z){let G=j["~standard"];if(!L(G))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 G.validate(q);if(H.issues===void 0)return H.value;throw new A({fieldName:z.fieldName,operation:z.operation,issues:H.issues.map(U)})}function Q(j){return j.map((q)=>q.path===""?q.message:`${q.path}: ${q.message}`).join(`
3
3
  `)}function L(j){return typeof j.validate==="function"}function U(j){return{message:j.message,path:b(j.path)}}function b(j){if(j===void 0||j.length===0)return"";let q="";for(let z of j)q+="/",q+=F(z);return q}function F(j){let q=J(j)?j.key:j;return M(String(q))}function J(j){return j!==null&&typeof j==="object"&&"key"in j}function M(j){return j.replace(/~/g,"~0").replace(/\//g,"~1")}function O(j,q,z){return`Validation failed for ${q===void 0?j:`${q} ${j}`}:
4
4
  ${Q(z)}`}var A;var $=X(()=>{Y();A=class A extends K{fieldName;operation;issues;constructor(j){super("StandardSchemaValidationError",O(j.fieldName,j.operation,j.issues));this.fieldName=j.fieldName,this.operation=j.operation,this.issues=j.issues}}});$();var V=Q,P=A,W=Z;export{W as validateStandardSchema,V as formatStandardSchemaIssues,P as StandardSchemaValidationError};