@lostgradient/weft 0.23.1 → 0.24.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 (294) hide show
  1. package/README.md +72 -4
  2. package/dist/cli/codegen-emit-dedup.d.ts +81 -0
  3. package/dist/cli/codegen-emit-dedup.js +45 -0
  4. package/dist/cli/codegen-emit-registry.d.ts +90 -0
  5. package/dist/cli/codegen-emit-registry.js +50 -0
  6. package/dist/cli/codegen-emit.d.ts +26 -39
  7. package/dist/cli/codegen-emit.js +4 -27
  8. package/dist/cli/codegen-validate.d.ts +49 -0
  9. package/dist/cli/codegen-validate.js +186 -0
  10. package/dist/cli/codegen.js +6 -87
  11. package/dist/cli/generated/operation-catalog.snapshot.json +287 -3
  12. package/dist/cli/generated/operation-client.generated.d.ts +324 -10
  13. package/dist/cli/generated/operation-client.generated.js +12 -0
  14. package/dist/cli/output.js +1 -1
  15. package/dist/cli/storage-factory.js +2 -0
  16. package/dist/cli/workflow-commands.js +2 -0
  17. package/dist/cli-main.js +1 -1
  18. package/dist/core/application-payload-digest.d.ts +42 -0
  19. package/dist/core/application-payload-digest.js +76 -0
  20. package/dist/core/application-primitive-abort.d.ts +50 -0
  21. package/dist/core/application-primitive-abort.js +40 -0
  22. package/dist/core/application-primitive-attempt-registry.d.ts +74 -0
  23. package/dist/core/application-primitive-attempt-registry.js +73 -0
  24. package/dist/core/application-primitive-codec.d.ts +36 -0
  25. package/dist/core/application-primitive-codec.js +56 -0
  26. package/dist/core/application-primitive-commit.d.ts +67 -0
  27. package/dist/core/application-primitive-commit.js +66 -0
  28. package/dist/core/application-primitive-guards.d.ts +62 -0
  29. package/dist/core/application-primitive-guards.js +89 -0
  30. package/dist/core/application-primitive-payload.d.ts +29 -0
  31. package/dist/core/application-primitive-payload.js +65 -0
  32. package/dist/core/application-primitive-timing.d.ts +18 -0
  33. package/dist/core/application-primitive-timing.js +22 -0
  34. package/dist/core/atomic-state.js +2 -0
  35. package/dist/core/catalog/codec.d.ts +40 -0
  36. package/dist/core/catalog/codec.js +45 -0
  37. package/dist/core/catalog/errors.d.ts +104 -0
  38. package/dist/core/catalog/errors.js +41 -0
  39. package/dist/core/catalog/index.d.ts +25 -0
  40. package/dist/core/catalog/index.js +15 -0
  41. package/dist/core/catalog/reference-counts.d.ts +105 -0
  42. package/dist/core/catalog/reference-counts.js +28 -0
  43. package/dist/core/catalog/removal.d.ts +52 -0
  44. package/dist/core/catalog/removal.js +14 -0
  45. package/dist/core/catalog/storage-io.d.ts +78 -0
  46. package/dist/core/catalog/storage-io.js +106 -0
  47. package/dist/core/catalog/types.d.ts +108 -0
  48. package/dist/core/catalog/types.js +0 -0
  49. package/dist/core/catalog/workflow-catalog.d.ts +165 -0
  50. package/dist/core/catalog/workflow-catalog.js +198 -0
  51. package/dist/core/compare-codepoint.d.ts +13 -0
  52. package/dist/core/compare-codepoint.js +7 -0
  53. package/dist/core/compression.js +2 -0
  54. package/dist/core/context/attributes.d.ts +1 -1
  55. package/dist/core/context/durable-operations.d.ts +2 -2
  56. package/dist/core/context/index.js +5 -3
  57. package/dist/core/context/state-namespace.d.ts +1 -1
  58. package/dist/core/contract/build.d.ts +64 -0
  59. package/dist/core/contract/build.js +99 -0
  60. package/dist/core/contract/compatibility.d.ts +187 -0
  61. package/dist/core/contract/compatibility.js +37 -0
  62. package/dist/core/contract/failure.d.ts +64 -0
  63. package/dist/core/contract/failure.js +4 -0
  64. package/dist/core/contract/hash.d.ts +92 -0
  65. package/dist/core/contract/hash.js +34 -0
  66. package/dist/core/contract/index.d.ts +21 -0
  67. package/dist/core/contract/index.js +22 -0
  68. package/dist/core/contract/limits.d.ts +74 -0
  69. package/dist/core/contract/limits.js +1 -0
  70. package/dist/core/contract/manifest-parse-schema.d.ts +37 -0
  71. package/dist/core/contract/manifest-parse-schema.js +106 -0
  72. package/dist/core/contract/manifest-parse.d.ts +76 -0
  73. package/dist/core/contract/manifest-parse.js +189 -0
  74. package/dist/core/contract/manifest.d.ts +56 -0
  75. package/dist/core/contract/manifest.js +31 -0
  76. package/dist/core/contract/normalize.d.ts +97 -0
  77. package/dist/core/contract/normalize.js +127 -0
  78. package/dist/core/contract/revision.d.ts +29 -0
  79. package/dist/core/contract/revision.js +5 -0
  80. package/dist/core/contract/types.d.ts +274 -0
  81. package/dist/core/contract/types.js +1 -0
  82. package/dist/core/engine/catalog-activation.d.ts +40 -0
  83. package/dist/core/engine/catalog-activation.js +17 -0
  84. package/dist/core/engine/catalog-events.d.ts +36 -0
  85. package/dist/core/engine/catalog-events.js +15 -0
  86. package/dist/core/engine/catalog-readiness.d.ts +49 -0
  87. package/dist/core/engine/catalog-readiness.js +59 -0
  88. package/dist/core/engine/catalog-removal.d.ts +132 -0
  89. package/dist/core/engine/catalog-removal.js +70 -0
  90. package/dist/core/engine/construction.d.ts +1 -1
  91. package/dist/core/engine/construction.js +4 -2
  92. package/dist/core/engine/disposal.js +9 -0
  93. package/dist/core/engine/engine-workflows-namespace.d.ts +130 -0
  94. package/dist/core/engine/engine-workflows-namespace.js +49 -0
  95. package/dist/core/engine/finalizer-metadata.d.ts +22 -0
  96. package/dist/core/engine/finalizer-metadata.js +12 -0
  97. package/dist/core/engine/handle-result.js +2 -0
  98. package/dist/core/engine/index.d.ts +83 -0
  99. package/dist/core/engine/index.js +61 -0
  100. package/dist/core/engine/internals.d.ts +44 -1
  101. package/dist/core/engine/internals.js +6 -0
  102. package/dist/core/engine/lifecycle/start.js +3 -0
  103. package/dist/core/engine/registration.d.ts +76 -0
  104. package/dist/core/engine/registration.js +12 -6
  105. package/dist/core/engine/source-registration.d.ts +42 -0
  106. package/dist/core/engine/source-registration.js +36 -0
  107. package/dist/core/engine/source-resolution.d.ts +85 -0
  108. package/dist/core/engine/source-resolution.js +119 -0
  109. package/dist/core/engine/validation.js +2 -2
  110. package/dist/core/events/catalog-events.d.ts +117 -0
  111. package/dist/core/events/catalog-events.js +62 -0
  112. package/dist/core/events/event-map.d.ts +6 -0
  113. package/dist/core/events/index.d.ts +1 -0
  114. package/dist/core/events/index.js +1 -0
  115. package/dist/core/mailbox-admission.d.ts +26 -0
  116. package/dist/core/mailbox-admission.js +130 -0
  117. package/dist/core/mailbox-claims.d.ts +251 -0
  118. package/dist/core/mailbox-claims.js +0 -0
  119. package/dist/core/mailbox-codec.d.ts +32 -0
  120. package/dist/core/mailbox-codec.js +221 -0
  121. package/dist/core/mailbox-contract.d.ts +290 -0
  122. package/dist/core/mailbox-contract.js +0 -0
  123. package/dist/core/mailbox-delivery.d.ts +37 -0
  124. package/dist/core/mailbox-delivery.js +193 -0
  125. package/dist/core/mailbox-guards.d.ts +78 -0
  126. package/dist/core/mailbox-guards.js +58 -0
  127. package/dist/core/mailbox-index-codec.d.ts +41 -0
  128. package/dist/core/mailbox-index-codec.js +71 -0
  129. package/dist/core/mailbox-internals.d.ts +156 -0
  130. package/dist/core/mailbox-internals.js +154 -0
  131. package/dist/core/mailbox-maintenance.d.ts +29 -0
  132. package/dist/core/mailbox-maintenance.js +196 -0
  133. package/dist/core/mailbox-settlement.d.ts +69 -0
  134. package/dist/core/mailbox-settlement.js +206 -0
  135. package/dist/core/mailbox-storage.d.ts +117 -0
  136. package/dist/core/mailbox-storage.js +115 -0
  137. package/dist/core/mailbox-transition-helpers.d.ts +70 -0
  138. package/dist/core/mailbox-transition-helpers.js +43 -0
  139. package/dist/core/mailbox-transitions-recovery.d.ts +28 -0
  140. package/dist/core/mailbox-transitions-recovery.js +64 -0
  141. package/dist/core/mailbox-transitions.d.ts +138 -0
  142. package/dist/core/mailbox-transitions.js +180 -0
  143. package/dist/core/mailbox-types.d.ts +406 -0
  144. package/dist/core/mailbox-types.js +16 -0
  145. package/dist/core/mailbox-validation.d.ts +65 -0
  146. package/dist/core/mailbox-validation.js +73 -0
  147. package/dist/core/mailbox-waits.d.ts +50 -0
  148. package/dist/core/mailbox-waits.js +97 -0
  149. package/dist/core/mailbox.d.ts +163 -0
  150. package/dist/core/mailbox.js +211 -0
  151. package/dist/core/outbox-claims.d.ts +307 -0
  152. package/dist/core/outbox-claims.js +0 -0
  153. package/dist/core/outbox-codec.d.ts +24 -0
  154. package/dist/core/outbox-codec.js +257 -0
  155. package/dist/core/outbox-contract.d.ts +346 -0
  156. package/dist/core/outbox-contract.js +0 -0
  157. package/dist/core/outbox-delivery.d.ts +34 -0
  158. package/dist/core/outbox-delivery.js +149 -0
  159. package/dist/core/outbox-drain.d.ts +29 -0
  160. package/dist/core/outbox-drain.js +158 -0
  161. package/dist/core/outbox-enqueue.d.ts +24 -0
  162. package/dist/core/outbox-enqueue.js +115 -0
  163. package/dist/core/outbox-guards.d.ts +76 -0
  164. package/dist/core/outbox-guards.js +60 -0
  165. package/dist/core/outbox-index-codec.d.ts +33 -0
  166. package/dist/core/outbox-index-codec.js +71 -0
  167. package/dist/core/outbox-internals.d.ts +99 -0
  168. package/dist/core/outbox-internals.js +159 -0
  169. package/dist/core/outbox-listing.d.ts +12 -0
  170. package/dist/core/outbox-listing.js +38 -0
  171. package/dist/core/outbox-maintenance.d.ts +28 -0
  172. package/dist/core/outbox-maintenance.js +191 -0
  173. package/dist/core/outbox-operations.d.ts +18 -0
  174. package/dist/core/outbox-operations.js +46 -0
  175. package/dist/core/outbox-runner.d.ts +30 -0
  176. package/dist/core/outbox-runner.js +217 -0
  177. package/dist/core/outbox-settlement.d.ts +57 -0
  178. package/dist/core/outbox-settlement.js +183 -0
  179. package/dist/core/outbox-storage.d.ts +107 -0
  180. package/dist/core/outbox-storage.js +127 -0
  181. package/dist/core/outbox-transition-helpers.d.ts +83 -0
  182. package/dist/core/outbox-transition-helpers.js +63 -0
  183. package/dist/core/outbox-transitions-recovery.d.ts +30 -0
  184. package/dist/core/outbox-transitions-recovery.js +42 -0
  185. package/dist/core/outbox-transitions.d.ts +145 -0
  186. package/dist/core/outbox-transitions.js +236 -0
  187. package/dist/core/outbox-types.d.ts +400 -0
  188. package/dist/core/outbox-types.js +20 -0
  189. package/dist/core/outbox-validation.d.ts +101 -0
  190. package/dist/core/outbox-validation.js +127 -0
  191. package/dist/core/outbox-waits.d.ts +39 -0
  192. package/dist/core/outbox-waits.js +88 -0
  193. package/dist/core/outbox.d.ts +156 -0
  194. package/dist/core/outbox.js +234 -0
  195. package/dist/core/registry-limits.d.ts +49 -0
  196. package/dist/core/registry-limits.js +10 -0
  197. package/dist/core/registry-schema-conversion.d.ts +20 -0
  198. package/dist/core/registry-schema-conversion.js +22 -0
  199. package/dist/core/registry-snapshot.d.ts +91 -42
  200. package/dist/core/registry-snapshot.js +39 -77
  201. package/dist/core/registry-workflow-contract-draft.d.ts +32 -0
  202. package/dist/core/registry-workflow-contract-draft.js +28 -0
  203. package/dist/core/registry-workflow-manifest.d.ts +122 -0
  204. package/dist/core/registry-workflow-manifest.js +92 -0
  205. package/dist/core/source/errors.d.ts +55 -0
  206. package/dist/core/source/errors.js +13 -0
  207. package/dist/core/source/index.d.ts +19 -0
  208. package/dist/core/source/index.js +4 -0
  209. package/dist/core/source/resolvers.d.ts +45 -0
  210. package/dist/core/source/resolvers.js +9 -0
  211. package/dist/core/source/types.d.ts +211 -0
  212. package/dist/core/source/types.js +0 -0
  213. package/dist/core/source/validate.d.ts +91 -0
  214. package/dist/core/source/validate.js +62 -0
  215. package/dist/core/source/workflow-source.d.ts +43 -0
  216. package/dist/core/source/workflow-source.js +16 -0
  217. package/dist/core/types/workflow-registries.d.ts +7 -0
  218. package/dist/core/types/workflow-registry.d.ts +12 -0
  219. package/dist/core/versioning.js +2 -0
  220. package/dist/core/weft-error.d.ts +1 -1
  221. package/dist/core/weft-error.js +9 -1
  222. package/dist/http.js +2 -2
  223. package/dist/index.d.ts +23 -2
  224. package/dist/index.js +50 -0
  225. package/dist/indexeddb.js +1 -1
  226. package/dist/json-schema.js +3 -3
  227. package/dist/mcp/resources.js +2 -0
  228. package/dist/runtime/portable.d.ts +9 -1
  229. package/dist/server/fault-to-json-rpc.js +3 -1
  230. package/dist/server/handler/auth-context-principal.js +4 -0
  231. package/dist/server/json-rpc-http.js +2 -0
  232. package/dist/server/json-rpc-websocket.js +6 -4
  233. package/dist/server/operation-catalog/index.d.ts +1 -1
  234. package/dist/server/operation-catalog/pipeline-helpers.js +2 -0
  235. package/dist/server/operation-catalog/types.d.ts +17 -0
  236. package/dist/server/operation-fault.d.ts +3 -0
  237. package/dist/server/operation-fault.js +3 -1
  238. package/dist/server/operations/activate-workflow-revision.d.ts +30 -0
  239. package/dist/server/operations/activate-workflow-revision.js +69 -0
  240. package/dist/server/operations/fleet-events-subscription.js +1 -1
  241. package/dist/server/operations/fork-workflow.js +1 -1
  242. package/dist/server/operations/get-active-workflow-revision.d.ts +32 -0
  243. package/dist/server/operations/get-active-workflow-revision.js +46 -0
  244. package/dist/server/operations/get-catalog-diagnostics.d.ts +85 -0
  245. package/dist/server/operations/get-catalog-diagnostics.js +57 -0
  246. package/dist/server/operations/get-registry.js +17 -4
  247. package/dist/server/operations/get-workflow-revision.d.ts +25 -0
  248. package/dist/server/operations/get-workflow-revision.js +50 -0
  249. package/dist/server/operations/install-workflow-revision.d.ts +27 -0
  250. package/dist/server/operations/install-workflow-revision.js +46 -0
  251. package/dist/server/operations/list-workflow-revisions.d.ts +20 -0
  252. package/dist/server/operations/list-workflow-revisions.js +40 -0
  253. package/dist/server/operations/start-or-signal-workflow.js +1 -1
  254. package/dist/server/operations/start-workflow.js +1 -1
  255. package/dist/server/operations/static-registrations.js +36 -0
  256. package/dist/server/operations/storage.js +2 -2
  257. package/dist/server/operations/submit-review-decision.js +1 -1
  258. package/dist/server/operations/workflow-catalog-operation-helpers.d.ts +59 -0
  259. package/dist/server/operations/workflow-catalog-operation-helpers.js +135 -0
  260. package/dist/server/runtime/websocket-upgrade.js +2 -0
  261. package/dist/storage/bun-sql.js +49 -6
  262. package/dist/storage/catalog-keys.d.ts +45 -0
  263. package/dist/storage/catalog-keys.js +6 -0
  264. package/dist/storage/compressed-storage.js +1 -1
  265. package/dist/storage/derived-operations.js +1 -1
  266. package/dist/storage/index.d.ts +26 -1
  267. package/dist/storage/interface.d.ts +26 -1
  268. package/dist/storage/interface.js +1 -1
  269. package/dist/storage/key-encoding.d.ts +15 -0
  270. package/dist/storage/key-encoding.js +3 -0
  271. package/dist/storage/key-prefixes.d.ts +1 -1
  272. package/dist/storage/key-prefixes.js +15 -0
  273. package/dist/storage/lmdb.d.ts +26 -1
  274. package/dist/storage/lmdb.js +1 -1
  275. package/dist/storage/mailbox-keys.d.ts +80 -0
  276. package/dist/storage/mailbox-keys.js +14 -0
  277. package/dist/storage/memory.js +1 -1
  278. package/dist/storage/neon.js +2 -2
  279. package/dist/storage/node-sqlite-loader.d.ts +1 -1
  280. package/dist/storage/node-sqlite.js +49 -6
  281. package/dist/storage/outbox-keys.d.ts +77 -0
  282. package/dist/storage/outbox-keys.js +14 -0
  283. package/dist/storage/postgres.js +2 -2
  284. package/dist/storage/resolve.js +1 -1
  285. package/dist/storage/scoped-storage.js +1 -1
  286. package/dist/storage/storage-configuration.d.ts +6 -0
  287. package/dist/storage/testing.js +1 -1
  288. package/dist/storage/turso.js +2 -2
  289. package/dist/version.d.ts +1 -1
  290. package/dist/version.js +1 -1
  291. package/dist/web-extension.js +1 -1
  292. package/dist/worker/manifest/registry-contract-builder.d.ts +21 -3
  293. package/dist/worker/manifest/registry-contract-builder.js +40 -31
  294. package/package.json +1 -1
@@ -1,11 +1,13 @@
1
1
  import type { AlertStateSnapshot } from '../../alerting/types.ts';
2
2
  import { type Storage as WeftStorage } from '../../storage/interface.ts';
3
3
  import { type ActivityMetadata, type ActivityRegistrationOptions, type RegisteredActivityFunction } from '../activity-registry.ts';
4
+ import type { WorkflowRevisionRecord } from '../catalog/index.ts';
4
5
  import type { StoredStreamChunk } from '../context.ts';
5
6
  import type { TypedEventTarget, WeftEventMap } from '../events.ts';
6
7
  import type { Interceptor } from '../interceptor.ts';
7
8
  import { type ReviewRequest } from '../review/index.ts';
8
9
  import { Scheduler } from '../scheduler.ts';
10
+ import type { WorkflowSourceHandle } from '../source/index.ts';
9
11
  import { type AnyActivityDefinition, type AnyWorkflowDefinition, type AttributeFilterKey, type BulkCancelResult, type BulkDeleteResult, type BulkOperationCommitOptions, type BulkOperationDryRunOptions, type BulkOperationDryRunResult, type BulkRetryFailedResult, type BulkSignalAllCommitOptions, type BulkSignalAllDryRunOptions, type BulkSignalResult, type BulkTagResult, type CheckpointState, type CheckpointSummary, type CoordinatedUpdateResult, type DefaultActivityTypes, type DefaultWorkflowRegistry, type ForkOptions, type InferActivityEntries, type InferActivityEntry, type InferWorkflowEntries, type InferWorkflowEntry, type ListFilter, type ListOptions, type PaginatedResult, type PendingAsyncActivityListOptions, type PendingAsyncActivityPage, type PurgeResult, type QueryDefinition, type RegisteredWorkflowDefinition, type RetentionOverview, type ReviewListEntry, type ReviewListFilter, type ScheduleDefinition, type ScheduleFilter, type ScheduleOptions, type ScheduleSpec, type ScheduleSummary, type ScheduleUpdateOptions, type SearchAttributeValue, type SignalDefinition, type SignalDeliveryOptions, type StartOrSignalOptions, type StartOrSignalSignal, type StartWorkflowOptions, type SubmitReviewOptions, type TypedListFilter, type UpdateDefinition, type WorkflowEvent, type WorkflowFinalizerStatus, type WorkflowInput, type WorkflowOutput, type WorkflowReplay, type WorkflowScheduleProvenance, type WorkflowServices, type WorkflowServicesUnion, type WorkflowState, type WorkflowSummary, type WorkflowTimelineEntry } from '../types.ts';
10
12
  import type { TimerEntry } from '../types/checkpoint.ts';
11
13
  import type { WorkflowAlreadyRegistered } from '../types/workflow-builder.ts';
@@ -14,29 +16,36 @@ import { type EmptyActivityDefinitions, type EmptyWorkflowDefinitions, type Know
14
16
  import { type ActivityDefinitionName, type EngineCreateOptions, type EngineCreateWorkflowRegistry, type RegisteredActivityDefinitionExecute, type UnknownWorkflowNameWhenDefaultRegistryIsEmpty } from './engine-create-types.ts';
15
17
  import type { EngineConstructorOptions } from './engine-internal-types.ts';
16
18
  import type { EngineStateNamespace } from './engine-state-namespace.ts';
19
+ import { type EngineWorkflowsNamespace } from './engine-workflows-namespace.ts';
17
20
  import { HANDLE_RESULT_PROMISE, WorkflowHandle } from './handles.ts';
18
21
  import { ENGINE_LEASE_LOST_WARNING_NAME } from './lease-deposition.ts';
19
22
  import type { EngineLeaseHealth } from './lease-health.ts';
20
23
  import { type RecoverAllOptions, type StartOrSignalResult } from './lifecycle.ts';
21
24
  import { assertCompatiblePersistedDataVersion } from './persisted-data-version.ts';
22
25
  import { ScheduleHandle } from './schedule-handle.ts';
26
+ import { type ResolveWorkflowSourceOptions } from './source-resolution.ts';
23
27
  import { type WorkflowFeedListener, type WorkflowFeedRecord, type WorkflowFeedSelector } from './workflow-feed.ts';
28
+ export type { WorkflowRevisionReferenceCounts } from '../catalog/index.ts';
24
29
  export { ActivityReconciliationCapabilityError, ActivityReconciliationConflictError, ActivityReconciliationIndeterminateError, } from './activity-reconciliation.ts';
25
30
  export { AsyncActivityTokenNotFoundError } from './async-activity-completion.ts';
26
31
  export type { PendingAsyncActivity } from './async-activity-records.ts';
32
+ export { getWorkflowRevisionDiagnostics, removeWorkflowRevision, type WorkflowCatalogRemovalResult, type WorkflowRevisionDiagnostics, } from './catalog-removal.ts';
27
33
  export type { PendingTimelineEntry, RegistrationEntry, ResolvedOptions, TrackedWaiterKeys, WorkflowResultWaiter, } from './engine-internal-types.ts';
28
34
  export { ActivityResolutionError, BulkDeleteRequiresTerminalWorkflowsError, BulkOperationConfirmationError, EngineCreateNameMismatchError, EngineDisposalError, EngineDisposedError, IdempotencyKeyPurgedError, PersistedDataCorruptError, PersistedDataIncompatibleError, StartOrSignalConflictError, WorkflowAlreadyExistsError, WorkflowConcurrencyLimitExceededError, WorkflowNotFoundError, WorkflowNotRegisteredError, WorkflowSuspendNotSupportedError, WorkflowTeardownPendingError, WorkflowTypeNotRegisteredForRecoveryError, } from './errors.ts';
29
35
  export { HANDLE_RESULT_PROMISE, WorkflowHandle } from './handles.ts';
36
+ export { getWorkflowCatalog } from './internals.ts';
30
37
  export { WeftWorkflowClaimLostWarning, WeftWorkflowWakeDiscardedWarning, WORKFLOW_CLAIM_LOST_WARNING_NAME, WORKFLOW_WAKE_DISCARDED_WARNING_NAME, } from './lease-deposition.ts';
31
38
  export type { WorkflowWakeKind } from './lease-deposition.ts';
32
39
  export { EngineLeaseAcquisitionTimeoutError, EngineLeaseCorruptedError, EngineLeaseNotHeldError, OwnershipModeMismatchError, WorkflowClaimUnavailableError, } from './lease-errors.ts';
33
40
  export type { EngineLeaseHealth, LeaseLostReason } from './lease-health.ts';
34
41
  export type { RecoverAllOptions, RecoveredWorkflowInfo } from './lifecycle.ts';
35
42
  export { ScheduleHandle } from './schedule-handle.ts';
43
+ export type { ResolveWorkflowSourceOptions } from './source-resolution.ts';
36
44
  export type { WorkflowFeedListener, WorkflowFeedRecord, WorkflowFeedSelector, } from './workflow-feed.ts';
37
45
  export type { EngineCreateOptions } from './engine-create-types.ts';
38
46
  export { clearEngineLeakWarningTokenForTesting, getEngineLeakCollectionCountForTesting, hasEngineLeakWarningTokenForTesting, setEngineLeakWarningOverrideForTesting, setNextEngineLeakWarningTokenForTesting, shouldEmitEngineLeakWarningForTesting, } from './engine-leak-warnings.ts';
39
47
  export type { EngineStateNamespace } from './engine-state-namespace.ts';
48
+ export type { ActivateWorkflowRevisionOptions, EngineWorkflowsNamespace, } from './engine-workflows-namespace.ts';
40
49
  export { assertCompatiblePersistedDataVersion };
41
50
  export declare const ENGINE_PARKED_WORKFLOW_COUNT_FOR_TESTING: unique symbol;
42
51
  export declare const ENGINE_SIGNAL_WAITER_COUNT_FOR_TESTING: unique symbol;
@@ -172,6 +181,7 @@ export declare class Engine<TWorkflows extends object = DefaultWorkflowRegistry,
172
181
  removeEventListener<K extends Extract<keyof WeftEventMap, string>>(type: K, listener: (event: WeftEventMap[K]) => void, options?: boolean | EventListenerOptions): void;
173
182
  removeEventListener(type: string, listener: EventListenerOrEventListenerObject | null, options?: boolean | EventListenerOptions): void;
174
183
  get state(): EngineStateNamespace;
184
+ get workflows(): EngineWorkflowsNamespace;
175
185
  /** Return detached snapshots of the alert rules that are currently firing. */
176
186
  getActiveAlerts(): readonly AlertStateSnapshot[];
177
187
  /**
@@ -212,6 +222,50 @@ export declare class Engine<TWorkflows extends object = DefaultWorkflowRegistry,
212
222
  readonly execute: RegisteredActivityDefinitionExecute<TActivities, TName>;
213
223
  }): Engine<TWorkflows, TActivities & InferActivityEntry<TDefinition>>;
214
224
  register<TDefinition extends AnyActivityDefinition>(definition: ActivityDefinitionName<TDefinition> extends Extract<keyof TActivities, string> ? never : TDefinition): Engine<TWorkflows, TActivities & InferActivityEntry<TDefinition>>;
225
+ /**
226
+ * Record `source` as a lazily-resolvable dynamic workflow source
227
+ * (WFT-13/14): synchronous, and it never invokes `source.load` — it only
228
+ * records a catalog candidate keyed `(source.descriptor.name,
229
+ * source.descriptor.revision)`. Call `resolveWorkflowSource()` to
230
+ * actually load, validate, and install it. A workflow name may not be
231
+ * both eagerly registered (`engine.register()`) and a dynamic source;
232
+ * registering the identical `source` reference twice for the same
233
+ * `(name, revision)` is idempotent.
234
+ *
235
+ * @example
236
+ * ```ts
237
+ * import { Engine, workflowSource } from '@lostgradient/weft';
238
+ *
239
+ * declare const loadCheckout: () => Promise<{
240
+ * checkout: import('@lostgradient/weft').WorkflowDefinition<unknown, unknown, 'checkout'>;
241
+ * }>;
242
+ * const engine = new Engine();
243
+ * engine.registerSource(
244
+ * workflowSource(
245
+ * { name: 'checkout', location: './checkout.ts', exportName: 'checkout', revision: 'r1' },
246
+ * loadCheckout,
247
+ * ),
248
+ * );
249
+ * ```
250
+ */
251
+ registerSource(source: WorkflowSourceHandle): void;
252
+ /**
253
+ * Load, validate, and install one dynamic workflow source revision
254
+ * previously recorded via {@link Engine.registerSource}. Single-flight
255
+ * per `(name, revision)`: concurrent callers for the same key share one
256
+ * loader invocation. Does not wire `engine.start()` or recovery to await
257
+ * resolution — that is a later batch's job (WFT-15).
258
+ *
259
+ * @example
260
+ * ```ts
261
+ * import { Engine } from '@lostgradient/weft';
262
+ *
263
+ * declare const engine: Engine;
264
+ * const record = await engine.resolveWorkflowSource('checkout', 'r1');
265
+ * console.log(record.manifest.revision);
266
+ * ```
267
+ */
268
+ resolveWorkflowSource(name: string, revision: string, options?: ResolveWorkflowSourceOptions): Promise<WorkflowRevisionRecord>;
215
269
  /**
216
270
  * Register every workflow from an object map at once and return a typed
217
271
  * engine view that exposes the newly added workflow names.
@@ -244,6 +298,35 @@ export declare class Engine<TWorkflows extends object = DefaultWorkflowRegistry,
244
298
  listWorkflowDefinitions(): RegisteredWorkflowDefinition[];
245
299
  getActivityDefinition(name: string): ActivityMetadata | undefined;
246
300
  listActivityDefinitions(): ActivityMetadata[];
301
+ /**
302
+ * Resolve one activity's catalog metadata the same way dispatch resolves
303
+ * it for a running workflow of this type: the workflow's per-workflow
304
+ * `.activities({...})` registry first, falling back to the global registry
305
+ * — see `activity-resolution.ts`'s `resolveActivityViaRegistries`. Build
306
+ * tooling (`buildWorkerManifestFromRegistry`) uses this so a workflow-scoped
307
+ * activity's schema, not a same-named global activity's, feeds its
308
+ * `contractHash` when both are registered.
309
+ */
310
+ getWorkflowActivityDefinition(workflowType: string, activityName: string): ActivityMetadata | undefined;
311
+ /**
312
+ * List every activity definition registered on this workflow's own
313
+ * per-workflow `.activities({...})` registry — name, schema, description,
314
+ * tags, retry/timeout metadata, never a handler function. Returns an
315
+ * empty array for a workflow with no `.activities({...})` step (including
316
+ * an unknown `workflowType`), never `undefined`, so a caller can fold the
317
+ * result straight into a contract without an existence check first.
318
+ *
319
+ * Companion to {@link getWorkflowActivityDefinition}: that resolves one
320
+ * activity by name with the per-workflow-first, global-fallback dispatch
321
+ * order; this enumerates only the names the per-workflow registry itself
322
+ * declares — activities a workflow reaches solely through the global
323
+ * registry are deliberately excluded, since those are not part of what
324
+ * `.activities({...})` scoped to this workflow. Build tooling that needs a
325
+ * workflow's full scoped-activity contract set (`buildRegistrySnapshot`,
326
+ * `worker/manifest/registry-contract-builder.ts`) uses this instead of
327
+ * reaching into engine internals directly.
328
+ */
329
+ listWorkflowActivityDefinitions(workflowType: string): ActivityMetadata[];
247
330
  start<TName extends KnownWorkflowNames<TWorkflows>>(type: TName, input: WorkflowInput<TWorkflows, TName>, options?: StartWorkflowOptions<WorkflowServices<TWorkflows, TName>>): Promise<WorkflowHandle<WorkflowOutput<TWorkflows, TName>>>;
248
331
  start<TName extends string>(type: UnknownWorkflowNameWhenDefaultRegistryIsEmpty<TWorkflows, TName>, input: unknown, options?: StartWorkflowOptions): Promise<WorkflowHandle>;
249
332
  /**
@@ -47,6 +47,7 @@ import {
47
47
  createUpdateCallbacks as createUpdateCallbacksForEngine
48
48
  } from "./callback-creators.js";
49
49
  import { registerCancelHandler } from "./cancel-handlers.js";
50
+ import { ensureWorkflowCatalogReady, isWorkflowCatalogReady } from "./catalog-readiness.js";
50
51
  import {
51
52
  getCheckpointAt as getCheckpointStateAt,
52
53
  getEvents as getWorkflowEvents,
@@ -78,6 +79,9 @@ import {
78
79
  shouldStartEngineScheduler,
79
80
  validateEngineCreateBackgroundTaskOptions
80
81
  } from "./engine-runtime-helpers.js";
82
+ import {
83
+ createEngineWorkflowsNamespace
84
+ } from "./engine-workflows-namespace.js";
81
85
  import {
82
86
  EngineCreateNameMismatchError,
83
87
  EngineDisposalError,
@@ -167,6 +171,10 @@ import {
167
171
  releaseSignalWaiter,
168
172
  signal as signalWorkflow
169
173
  } from "./signals.js";
174
+ import { registerSource as registerWorkflowSource } from "./source-registration.js";
175
+ import {
176
+ resolveWorkflowSource as resolveWorkflowSourceImpl
177
+ } from "./source-resolution.js";
170
178
  import {
171
179
  loadScheduleState,
172
180
  loadWorkflowState,
@@ -204,6 +212,10 @@ export {
204
212
  ActivityReconciliationIndeterminateError
205
213
  } from "./activity-reconciliation.js";
206
214
  export { AsyncActivityTokenNotFoundError } from "./async-activity-completion.js";
215
+ export {
216
+ getWorkflowRevisionDiagnostics,
217
+ removeWorkflowRevision
218
+ } from "./catalog-removal.js";
207
219
  export {
208
220
  ActivityResolutionError,
209
221
  BulkDeleteRequiresTerminalWorkflowsError,
@@ -224,6 +236,7 @@ export {
224
236
  WorkflowTypeNotRegisteredForRecoveryError
225
237
  } from "./errors.js";
226
238
  export { HANDLE_RESULT_PROMISE, WorkflowHandle } from "./handles.js";
239
+ export { getWorkflowCatalog } from "./internals.js";
227
240
  export {
228
241
  WeftWorkflowClaimLostWarning,
229
242
  WeftWorkflowWakeDiscardedWarning,
@@ -282,6 +295,8 @@ export class Engine extends EventTarget {
282
295
  }
283
296
  await engine.#bootstrapOwnershipIfConfigured();
284
297
  await engine.#acquireLeaseIfConfigured();
298
+ if (!isWorkflowCatalogReady(engine))
299
+ await ensureWorkflowCatalogReady(engine);
285
300
  if (options.recover !== !1)
286
301
  await engine.recoverAll(options.acknowledgeUnknownWorkflowTypes !== void 0 ? { acknowledgeUnknownWorkflowTypes: options.acknowledgeUnknownWorkflowTypes } : {});
287
302
  if (shouldStartEngineScheduler(options, getInternals(engine).options.backgroundTaskMode))
@@ -424,6 +439,16 @@ export class Engine extends EventTarget {
424
439
  getInternals(this).activityWorkerDispatcher = createActivityWorkerDispatcher(options?.activityExecution);
425
440
  getInternals(this).strategy.onMessage(this.#handleStrategyMessage.bind(this));
426
441
  getInternals(this).alertManager = options?.alerts ? new AlertManager(this, options.alerts, getNow, resolvedOptions.backgroundTaskMode === "automatic") : null;
442
+ getInternals(this).workflowCatalog = null;
443
+ getInternals(this).pendingCatalogInstalls = [];
444
+ getInternals(this).catalogRestored = !1;
445
+ getInternals(this).catalogDrainPromise = null;
446
+ getInternals(this).registeredCatalogRevisions = new Map;
447
+ getInternals(this).inFlightStartsByRevision = new Map;
448
+ getInternals(this).workflowSourcesByName = new Map;
449
+ getInternals(this).sourceResolutionsInFlight = new Map;
450
+ getInternals(this).sourceResolutionWaiterControllers = new Set;
451
+ getInternals(this).resolvedWorkflowSources = new Map;
427
452
  this.#ensureRetentionSweepInterval();
428
453
  this.#startSecondInstanceDetection();
429
454
  }
@@ -675,6 +700,9 @@ export class Engine extends EventTarget {
675
700
  workflow: (workflowType, key, options) => new AtomicState(storage, KEYS.stateWorkflow(workflowType, key), options)
676
701
  };
677
702
  }
703
+ get workflows() {
704
+ return createEngineWorkflowsNamespace(this);
705
+ }
678
706
  getActiveAlerts() {
679
707
  return getInternals(this).alertManager?.activeStates ?? [];
680
708
  }
@@ -692,6 +720,12 @@ export class Engine extends EventTarget {
692
720
  registerWorkflow(getInternals(this), definition, this.#createRegistrationCallbacks());
693
721
  return typedEngineView(this);
694
722
  }
723
+ registerSource(source) {
724
+ registerWorkflowSource(getInternals(this), source);
725
+ }
726
+ async resolveWorkflowSource(name, revision, options) {
727
+ return resolveWorkflowSourceImpl(this, name, revision, options);
728
+ }
695
729
  registerWorkflows(workflows) {
696
730
  for (const [name, definition] of Object.entries(workflows)) {
697
731
  if (name !== definition.name)
@@ -730,14 +764,25 @@ export class Engine extends EventTarget {
730
764
  listActivityDefinitions() {
731
765
  return getInternals(this).activityRegistry.listDefinitions();
732
766
  }
767
+ getWorkflowActivityDefinition(workflowType, activityName) {
768
+ const internals = getInternals(this);
769
+ return internals.activityRegistriesByWorkflow.get(workflowType)?.getDefinition(activityName) ?? internals.activityRegistry.getDefinition(activityName);
770
+ }
771
+ listWorkflowActivityDefinitions(workflowType) {
772
+ return getInternals(this).activityRegistriesByWorkflow.get(workflowType)?.listDefinitions() ?? [];
773
+ }
733
774
  async start(type, input, options) {
734
775
  assertLeaseHeldForEngineWork(getInternals(this));
776
+ if (!isWorkflowCatalogReady(this))
777
+ await ensureWorkflowCatalogReady(this);
735
778
  if (options?.idempotencyKey !== void 0)
736
779
  return startWithIdempotencyFromLifecycle(getInternals(this), type, input, options, this.#createLifecycleCallbacks());
737
780
  return startWorkflowFromLifecycle(getInternals(this), type, input, options, void 0, this.#createLifecycleCallbacks());
738
781
  }
739
782
  async startOrSignal(type, input, signal, options) {
740
783
  assertLeaseHeldForEngineWork(getInternals(this));
784
+ if (!isWorkflowCatalogReady(this))
785
+ await ensureWorkflowCatalogReady(this);
741
786
  return startOrSignalFromLifecycle(getInternals(this), type, input, signal, options, this.#createStartOrSignalCallbacks());
742
787
  }
743
788
  #createStartOrSignalCallbacks() {
@@ -810,6 +855,8 @@ export class Engine extends EventTarget {
810
855
  async schedule(typeOrDefinition, input, spec, options) {
811
856
  const internals = getInternals(this);
812
857
  assertLeaseHeldForEngineWork(internals);
858
+ if (!isWorkflowCatalogReady(this))
859
+ await ensureWorkflowCatalogReady(this);
813
860
  if (typeof typeOrDefinition === "object")
814
861
  return scheduleDefinitionFromInternals(internals, typeOrDefinition);
815
862
  if (spec === void 0)
@@ -826,21 +873,29 @@ export class Engine extends EventTarget {
826
873
  async pauseSchedule(scheduleId) {
827
874
  const internals = getInternals(this);
828
875
  assertLeaseHeldForEngineWork(internals);
876
+ if (!isWorkflowCatalogReady(this))
877
+ await ensureWorkflowCatalogReady(this);
829
878
  return pauseScheduleFromInternals(internals, scheduleId);
830
879
  }
831
880
  async resumeSchedule(scheduleId) {
832
881
  const internals = getInternals(this);
833
882
  assertLeaseHeldForEngineWork(internals);
883
+ if (!isWorkflowCatalogReady(this))
884
+ await ensureWorkflowCatalogReady(this);
834
885
  return resumeScheduleFromInternals(internals, scheduleId);
835
886
  }
836
887
  async cancelSchedule(scheduleId) {
837
888
  const internals = getInternals(this);
838
889
  assertLeaseHeldForEngineWork(internals);
890
+ if (!isWorkflowCatalogReady(this))
891
+ await ensureWorkflowCatalogReady(this);
839
892
  return cancelScheduleFromInternals(internals, scheduleId);
840
893
  }
841
894
  async updateSchedule(scheduleId, newSpec, options) {
842
895
  const internals = getInternals(this);
843
896
  assertLeaseHeldForEngineWork(internals);
897
+ if (!isWorkflowCatalogReady(this))
898
+ await ensureWorkflowCatalogReady(this);
844
899
  return updateScheduleFromInternals(internals, scheduleId, newSpec, options);
845
900
  }
846
901
  [HANDLE_RESULT_PROMISE](workflowId) {
@@ -906,10 +961,14 @@ export class Engine extends EventTarget {
906
961
  }
907
962
  async fork(sourceWorkflowId, options) {
908
963
  assertLeaseHeldForEngineWork(getInternals(this));
964
+ if (!isWorkflowCatalogReady(this))
965
+ await ensureWorkflowCatalogReady(this);
909
966
  return forkFromLifecycle(getInternals(this), sourceWorkflowId, options, this.#createLifecycleCallbacks());
910
967
  }
911
968
  async resume(workflowId) {
912
969
  assertLeaseHeldForEngineWork(getInternals(this));
970
+ if (!isWorkflowCatalogReady(this))
971
+ await ensureWorkflowCatalogReady(this);
913
972
  return resumeFromLifecycle(getInternals(this), workflowId, this.#createLifecycleCallbacks());
914
973
  }
915
974
  async recoverAll(options) {
@@ -917,6 +976,8 @@ export class Engine extends EventTarget {
917
976
  await this.#acquireLeaseIfConfigured();
918
977
  if (getInternals(this).disposed)
919
978
  throw new EngineDisposedError;
979
+ if (!isWorkflowCatalogReady(this))
980
+ await ensureWorkflowCatalogReady(this);
920
981
  await recoverPendingAsyncActivities(getInternals(this));
921
982
  await recoverOrphanedScheduleTimers(getInternals(this));
922
983
  getInternals(this).onRecoveredWorkflowHook = options?.onRecoveredWorkflow;
@@ -29,7 +29,7 @@ import type { InlineExecutionStrategy } from '../inline-execution-strategy.ts';
29
29
  import type { ComposedActivityInterceptor, ComposedWorkflowInterceptor, Interceptor } from '../interceptor.ts';
30
30
  import type { HumanReviewResult, ReviewCoordinator } from '../review/index.ts';
31
31
  import type { Scheduler } from '../scheduler.ts';
32
- import type { Checkpoint, StartWorkflowOptions } from '../types.ts';
32
+ import type { Checkpoint, StartWorkflowOptions, WorkflowDefinition } from '../types.ts';
33
33
  import type { UpdateCoordinator } from '../updates.ts';
34
34
  import type { WorkflowVersionTuple } from '../workflow-version-tuple.ts';
35
35
  import type { RecoveredWorkflowInfo } from './lifecycle/shared.ts';
@@ -58,6 +58,12 @@ export type DurableInlineOperation = {
58
58
  type EngineRuntime = WorkflowHandleEngine & ScheduleHandleEngine & {
59
59
  start(type: string, input: unknown, options?: StartWorkflowOptions): Promise<WorkflowHandle>;
60
60
  };
61
+ type SourceHandle = import('../source/index.ts').WorkflowSourceHandle;
62
+ type CatalogRevisionRecord = import('../catalog/index.ts').WorkflowRevisionRecord;
63
+ type ResolvedSource = {
64
+ definition: WorkflowDefinition;
65
+ activityRegistry: ActivityRegistry;
66
+ };
61
67
  export interface EngineInternals {
62
68
  engine: EngineRuntime;
63
69
  storage: WeftStorage;
@@ -386,6 +392,31 @@ export interface EngineInternals {
386
392
  workflowVisibilityWatermarkExpiresAt: number | undefined;
387
393
  pendingTimelineEntries: Map<string, PendingTimelineEntry>;
388
394
  pendingAtomicWorkflowCommitSideEffects: Map<string, import('./checkpoint-side-effects.ts').AtomicWorkflowCommitSideEffects>;
395
+ /**
396
+ * The durable workflow catalog (WFT-9/WFT-10), `null` until
397
+ * {@link import('./catalog-readiness.ts').ensureWorkflowCatalogReady} first
398
+ * restores it from storage. Read via {@link getWorkflowCatalog}, never
399
+ * directly.
400
+ */
401
+ workflowCatalog: import('../catalog/index.ts').WorkflowCatalog | null;
402
+ /** Workflow names `commitWorkflowDefinition` (`registration.ts`) has queued for catalog install+activate since the last drain — `engine.register()` stays synchronous (it cannot itself build a manifest) and defers to the next `ensureWorkflowCatalogReady` call. */
403
+ pendingCatalogInstalls: string[];
404
+ /** Whether {@link workflowCatalog} has been restored from storage at least once. */
405
+ catalogRestored: boolean;
406
+ /** The in-flight catalog restore-and-drain, or `null` when none is running; concurrent `ensureWorkflowCatalogReady` callers await this same promise rather than racing a second restore/drain. */
407
+ catalogDrainPromise: Promise<void> | null;
408
+ /** Name -> revision this process's own register()-drain most recently activated (WFT-12, `catalog-readiness.ts`). Process-local, never persisted. */
409
+ registeredCatalogRevisions: Map<string, string>;
410
+ /** Name -> revision -> in-flight `startWorkflow` count (WFT-12, `lifecycle/start.ts`). Process-local, never persisted. */
411
+ inFlightStartsByRevision: Map<string, Map<string, number>>;
412
+ /** Dynamic workflow sources (WFT-13/14): `registerSource()` candidates, keyed name then revision. Registering never invokes the loader. Process-local, never persisted. */
413
+ workflowSourcesByName: Map<string, Map<string, SourceHandle>>;
414
+ /** In-flight `resolveWorkflowSource` single-flight load per `(name, revision)`. Self-removes on settle via a `catalogDrainPromise`-style identity guard. */
415
+ sourceResolutionsInFlight: Map<string, Map<string, Promise<CatalogRevisionRecord>>>;
416
+ /** Per-caller `AbortController`s from in-flight `resolveWorkflowSource()` calls; disposal aborts every waiter without touching the shared load (mirrors `pendingWebhooks`). */
417
+ sourceResolutionWaiterControllers: Set<AbortController>;
418
+ /** A successful `resolveWorkflowSource()`'s live definition, keyed name then revision. Unread this batch — WFT-15's job. */
419
+ resolvedWorkflowSources: Map<string, Map<string, ResolvedSource>>;
389
420
  }
390
421
  /**
391
422
  * Set up an empty `EngineInternals` skeleton in the WeakMap. The Engine
@@ -406,4 +437,16 @@ export declare function initializeInternals(engine: EngineRuntime): void;
406
437
  * internals existing.
407
438
  */
408
439
  export declare function getInternals(engine: object): EngineInternals;
440
+ /**
441
+ * Read an engine's durable workflow catalog. Throws when it has not been
442
+ * restored yet — every public entry point that can observe catalog state
443
+ * (`start`, `startOrSignal`, `schedule`/`pauseSchedule`/`resumeSchedule`/
444
+ * `cancelSchedule`/`updateSchedule`, `fork`, `resume`, `recoverAll`,
445
+ * `Engine.create`, and `buildRegistrySnapshot`) awaits
446
+ * `ensureWorkflowCatalogReady(engine)` first, which restores it. Calling
447
+ * this before that await boundary — for example from a pathological
448
+ * direct-internals test — is a programming error, not a recoverable runtime
449
+ * condition, so it fails loud rather than returning a placeholder catalog.
450
+ */
451
+ export declare function getWorkflowCatalog(engine: object): import('../catalog/index.ts').WorkflowCatalog;
409
452
  export {};
@@ -9,3 +9,9 @@ export function getInternals(engine) {
9
9
  throw Error("Engine internals not initialized \u2014 initializeInternals(this) was not called in the Engine constructor");
10
10
  return internals;
11
11
  }
12
+ export function getWorkflowCatalog(engine) {
13
+ const internals = getInternals(engine);
14
+ if (internals.workflowCatalog === null)
15
+ throw Error("Workflow catalog not restored \u2014 ensureWorkflowCatalogReady(engine) was not awaited before " + "getWorkflowCatalog(engine) was called.");
16
+ return internals.workflowCatalog;
17
+ }
@@ -9,6 +9,7 @@ import {
9
9
  coerceStartWorkflowTimestamp,
10
10
  parseStartWorkflowDuration
11
11
  } from "../../start-workflow-validation.js";
12
+ import { releaseInFlightStart, reserveInFlightStart } from "../catalog-removal.js";
12
13
  import { forgetCommittedCheckpointBytes } from "../checkpoint-commit-snapshots.js";
13
14
  import { WorkflowAlreadyExistsError, WorkflowNotRegisteredError } from "../errors.js";
14
15
  import { createDelayedStartTimerEntry } from "../operations-time.js";
@@ -90,6 +91,7 @@ export async function startWorkflow(internals, type, input, options, additionalS
90
91
  throw new WorkflowAlreadyExistsError(workflowId);
91
92
  internals.pendingStarts.add(workflowId);
92
93
  let startSucceeded = !1;
94
+ const inFlightRevision = reserveInFlightStart(internals, type);
93
95
  try {
94
96
  const terminalRunToPurge = callerProvidedId ? await resolveTerminalConflictForRestart(internals, workflowId, options) : null;
95
97
  assertPayloadWithinLimit(input, internals.options.payloadSizePolicy.maxBytes, "workflow input");
@@ -133,6 +135,7 @@ export async function startWorkflow(internals, type, input, options, additionalS
133
135
  return handle;
134
136
  } finally {
135
137
  internals.pendingStarts.delete(workflowId);
138
+ releaseInFlightStart(internals, type, inFlightRevision);
136
139
  if (!startSucceeded)
137
140
  rollbackTransientStartState(internals, workflowId);
138
141
  }
@@ -1,7 +1,83 @@
1
+ import { ActivityRegistry } from '../activity-registry.ts';
2
+ import { type ActivityDefinition, type QueryDefinition, type SignalDefinition, type UpdateDefinition, type WorkflowDefinition } from '../types.ts';
3
+ import type { RegistrationEntry } from './engine-internal-types.ts';
1
4
  import type { EngineInternals } from './internals.ts';
2
5
  export type RegistrationCallbacks = {
3
6
  ensureRetentionSweepInterval: () => void;
4
7
  dispatchEvent: (event: Event) => void;
5
8
  };
9
+ /**
10
+ * Build the `RegistrationEntry` `engine.register()` would store for
11
+ * `registration`, without committing anything — pure normalization
12
+ * (base fields, optional fields, and, for a builder-produced definition,
13
+ * signal/update/query name-collision checks). Exported so the dynamic
14
+ * workflow-source validation pipeline (`core/source/validate.ts`, WFT-13/14)
15
+ * can normalize a loaded module's exported definition through the identical
16
+ * path `engine.register()` uses, rather than re-deriving a
17
+ * `RegistrationEntry` independently and risking the two producers drifting
18
+ * apart.
19
+ *
20
+ * @example
21
+ * ```ts
22
+ * import { workflow } from '@lostgradient/weft';
23
+ *
24
+ * const greet = workflow({ name: 'greet' }).execute(async function* (_ctx, input: string) {
25
+ * return `hello ${input}`;
26
+ * });
27
+ * console.log(greet.name);
28
+ * ```
29
+ */
30
+ export declare function buildRegistrationEntry(name: string, registration: WorkflowDefinition): RegistrationEntry;
31
+ /**
32
+ * Structural predicate for `BuiltWorkflowDefinition` — the runtime shape
33
+ * `workflow({ name }).execute(...)` returns. Exported so the dynamic
34
+ * workflow-source validation pipeline (`core/source/validate.ts`, WFT-13/14)
35
+ * can reject a loaded export that is a hand-rolled `{ name, handler }`
36
+ * literal rather than a builder-produced definition — the same "removed
37
+ * bare-handler shape" rejection `engine.register()` itself applies via
38
+ * {@link buildRegistrationEntry}.
39
+ *
40
+ * @example
41
+ * ```ts
42
+ * import { workflow } from '@lostgradient/weft';
43
+ *
44
+ * const greet = workflow({ name: 'greet' }).execute(async function* (_ctx, input: string) {
45
+ * return `hello ${input}`;
46
+ * });
47
+ * console.log(typeof greet.activities === 'object');
48
+ * ```
49
+ */
50
+ export declare function isBuilderWorkflowDefinition(value: unknown): value is WorkflowDefinition & {
51
+ readonly activities: Readonly<Record<string, Readonly<ActivityDefinition>>>;
52
+ readonly signals: Readonly<Record<string, Readonly<SignalDefinition<unknown>>>>;
53
+ readonly updates: Readonly<Record<string, Readonly<UpdateDefinition<unknown>>>>;
54
+ readonly queries: Readonly<Record<string, Readonly<QueryDefinition<unknown>>>>;
55
+ readonly searchAttributes: Readonly<Record<string, unknown>>;
56
+ };
57
+ /**
58
+ * Build a fresh per-workflow {@link ActivityRegistry} from a builder workflow's
59
+ * activities map. Each entry is defensively deep-cloned and then turned into a
60
+ * fresh `ActivityCallable` via {@link activity}, so the engine's registry holds
61
+ * its own callable references and the user's `BuiltWorkflowDefinition` cannot
62
+ * influence dispatch by post-registration mutation.
63
+ *
64
+ * Exported so the dynamic workflow-source validation pipeline
65
+ * (`core/source/validate.ts`, WFT-13/14) can build the same
66
+ * uncommitted-but-canonical per-workflow registry for a loaded module's
67
+ * export that `engine.register()` builds for an eagerly registered one —
68
+ * required so {@link import('../registry-workflow-manifest.ts').buildWorkflowManifestFromDefinition}
69
+ * produces byte-identical manifests for the two paths.
70
+ *
71
+ * @example
72
+ * ```ts
73
+ * import { workflow } from '@lostgradient/weft';
74
+ *
75
+ * const greet = workflow({ name: 'greet' }).execute(async function* (_ctx, input: string) {
76
+ * return `hello ${input}`;
77
+ * });
78
+ * console.log(Object.keys(greet.activities).length);
79
+ * ```
80
+ */
81
+ export declare function buildPerWorkflowActivityRegistry(activities: Readonly<Record<string, Readonly<ActivityDefinition>>>): ActivityRegistry;
6
82
  export declare function register(internals: EngineInternals, definition: unknown, callbacks: RegistrationCallbacks): void;
7
83
  export declare function resolveWorkflowTypeTarget(internals: EngineInternals, target: string | Function, _callbacks: RegistrationCallbacks): string;
@@ -1,3 +1,4 @@
1
+ import { isRecord } from "../../worker/manifest/is-record.js";
1
2
  import { ActivityRegistry } from "../activity-registry.js";
2
3
  import { WorkflowDefinitionRegisteredEvent } from "../events.js";
3
4
  import {
@@ -6,12 +7,13 @@ import {
6
7
  } from "../types.js";
7
8
  import { clonePlain } from "../types/clone-plain.js";
8
9
  import { validateWorkflowOrActivityName } from "../types/name-grammar.js";
10
+ import { DEFAULT_WORKFLOW_VERSION } from "../versioning.js";
9
11
  import { normalizeRetentionPolicy } from "./validation.js";
10
12
  function copiedTags(tags) {
11
13
  return tags === void 0 ? void 0 : [...tags];
12
14
  }
13
15
  function isWorkflowDefinition(value) {
14
- return typeof value === "object" && value !== null && "name" in value && "handler" in value;
16
+ return typeof value === "object" && value !== null && "name" in value && "handler" in value && typeof value.handler === "function";
15
17
  }
16
18
  function assertConstraintsSupported(internals, name, registration) {
17
19
  if (!registration.constraints || registration.constraints.length === 0)
@@ -23,7 +25,7 @@ function buildBaseRegistrationEntry(name, registration) {
23
25
  const tags = copiedTags(registration.tags), normalizedRetention = normalizeRetentionPolicy(registration.retention, `registration("${name}").retention`);
24
26
  return {
25
27
  handler: registration.handler,
26
- version: registration.version ?? "1",
28
+ version: registration.version ?? DEFAULT_WORKFLOW_VERSION,
27
29
  ...registration.description === void 0 ? {} : { description: registration.description },
28
30
  ...tags === void 0 ? {} : { tags },
29
31
  ...registration.inputSchema === void 0 ? {} : {
@@ -56,7 +58,7 @@ function applyOptionalRegistrationFields(entry, registration) {
56
58
  if (registration.finalizer !== void 0)
57
59
  entry.finalizer = registration.finalizer;
58
60
  }
59
- function buildRegistrationEntry(name, registration) {
61
+ export function buildRegistrationEntry(name, registration) {
60
62
  const entry = buildBaseRegistrationEntry(name, registration);
61
63
  applyOptionalRegistrationFields(entry, registration);
62
64
  if (isBuilderWorkflowDefinition(registration)) {
@@ -78,25 +80,29 @@ function normalizeMessageDefinitions(workflowType, messageKind, definitions) {
78
80
  function commitWorkflowDefinition(internals, definition, callbacks) {
79
81
  const name = definition.name;
80
82
  validateWorkflowOrActivityName(name, "workflow");
83
+ if (internals.workflowSourcesByName.has(name))
84
+ throw Error(`Cannot register("${name}"): "${name}" is already registered as a dynamic workflow source via engine.registerSource(). A workflow name may not be both eagerly registered and a dynamic source.`);
81
85
  assertConstraintsSupported(internals, name, definition);
82
86
  const entry = buildRegistrationEntry(name, definition);
83
87
  internals.registrations.set(name, entry);
84
88
  callbacks.ensureRetentionSweepInterval();
85
89
  internals.workflowTypesByHandler.set(definition.handler, name);
90
+ if (!internals.pendingCatalogInstalls.includes(name))
91
+ internals.pendingCatalogInstalls.push(name);
86
92
  callbacks.dispatchEvent(new WorkflowDefinitionRegisteredEvent(name));
87
93
  }
88
94
  function hasNonNullObjectField(value, key) {
89
95
  if (!(key in value))
90
96
  return !1;
91
97
  const fieldValue = value[key];
92
- return typeof fieldValue === "object" && fieldValue !== null;
98
+ return isRecord(fieldValue);
93
99
  }
94
- function isBuilderWorkflowDefinition(value) {
100
+ export function isBuilderWorkflowDefinition(value) {
95
101
  if (!isWorkflowDefinition(value))
96
102
  return !1;
97
103
  return hasNonNullObjectField(value, "activities") && hasNonNullObjectField(value, "signals") && hasNonNullObjectField(value, "updates") && hasNonNullObjectField(value, "queries") && hasNonNullObjectField(value, "searchAttributes");
98
104
  }
99
- function buildPerWorkflowActivityRegistry(activities) {
105
+ export function buildPerWorkflowActivityRegistry(activities) {
100
106
  const registry = new ActivityRegistry;
101
107
  for (const definition of Object.values(activities)) {
102
108
  const clonedDefinition = clonePlain(definition), callable = activity(clonedDefinition);
@@ -0,0 +1,42 @@
1
+ /**
2
+ * `registerSource()` — the synchronous entry point for a dynamic workflow
3
+ * source (WFT-13/14). Mirrors `engine.register()`'s own "stays synchronous,
4
+ * defers the real work" contract: this records a catalog candidate keyed
5
+ * `(name, revision)` and returns — it never invokes the source's loader and
6
+ * never touches storage. The loader runs only inside a later, explicit
7
+ * `resolveWorkflowSource()` call (`source-resolution.ts`).
8
+ *
9
+ * @module core/engine/source-registration
10
+ */
11
+ import type { WorkflowSourceHandle } from '../source/index.ts';
12
+ import type { EngineInternals } from './internals.ts';
13
+ /**
14
+ * Record `source` as a lazily-resolvable candidate for
15
+ * `(source.descriptor.name, source.descriptor.revision)`. Synchronous and
16
+ * side-effect-free beyond the in-memory record: never invokes
17
+ * `source.load`, never reads or writes storage.
18
+ *
19
+ * Collision rules, checked in both directions against `engine.register()`'s
20
+ * own state so a workflow name can never be simultaneously eager and lazy:
21
+ *
22
+ * - A name already eagerly registered (`internals.registrations` — set by
23
+ * BOTH branches of `engine.register()`, unlike `workflowDefinitionsByName`,
24
+ * which only the builder-produced branch populates; checking that narrower
25
+ * map here would let a plain `{ name, handler }` `WorkflowDefinition`
26
+ * registered via `engine.register()` collide silently with a same-named
27
+ * `registerSource()` call) cannot also be registered as a source — throws.
28
+ * - Re-registering the identical `source` object reference for the same
29
+ * `(name, revision)` is idempotent (a no-op), mirroring `engine.register()`'s
30
+ * own same-reference-is-idempotent rule for eager definitions.
31
+ * - Registering a *different* handle under the same `(name, revision)` key
32
+ * throws — a revision identity, once claimed, names exactly one source.
33
+ * - Multiple *different* revisions of the same lazy name may coexist
34
+ * unregistered — this is the direct lazy analog of the catalog already
35
+ * supporting multiple installed revisions per name (WFT-9/10); nothing in
36
+ * this batch's acceptance criteria forbids it.
37
+ *
38
+ * The symmetric check — an eager `engine.register()` call for a name
39
+ * already claimed by a source — lives in `registration.ts`'s
40
+ * `commitWorkflowDefinition`.
41
+ */
42
+ export declare function registerSource(internals: EngineInternals, source: WorkflowSourceHandle): void;