@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
@@ -0,0 +1,234 @@
1
+ import {
2
+ attemptControllerRegistry,
3
+ releaseAttemptControllerRegistry
4
+ } from "./application-primitive-attempt-registry.js";
5
+ import { claimNextDelivery } from "./outbox-delivery.js";
6
+ import { drainOutbox } from "./outbox-drain.js";
7
+ import { capacityOf, enqueueDelivery } from "./outbox-enqueue.js";
8
+ import {
9
+ ApplicationDeliveryValidationError,
10
+ requireClockInstant,
11
+ requireMaintenanceInstant,
12
+ validateCancellationReason,
13
+ validateDeliveryIdentifier,
14
+ validateDurableJSONValue
15
+ } from "./outbox-guards.js";
16
+ import {
17
+ OUTBOX_PRIMITIVE,
18
+ toApplicationDeliveryReceipt
19
+ } from "./outbox-internals.js";
20
+ import { listDeliveries } from "./outbox-listing.js";
21
+ import { runOutboxMaintenance } from "./outbox-maintenance.js";
22
+ import { deadLetterDelivery, retryDelivery } from "./outbox-operations.js";
23
+ import { deliverNext } from "./outbox-runner.js";
24
+ import {
25
+ beginAttempt,
26
+ heartbeatAttempt,
27
+ readCleanupState,
28
+ requestCancellation,
29
+ settleAttempt
30
+ } from "./outbox-settlement.js";
31
+ import { createOutboxKeys, loadDelivery, loadOutboxHeader } from "./outbox-storage.js";
32
+ import { resolveOutboxPolicy, validateOutcome } from "./outbox-validation.js";
33
+ import { waitForCleanup, waitForDueWork } from "./outbox-waits.js";
34
+ function requireOutboxStorage(storage) {
35
+ const capabilities = storage.capabilities();
36
+ if (!capabilities.conditionalBatch)
37
+ throw new ApplicationDeliveryValidationError("Application outboxes require storage with conditional batch support: every transition is a compare-and-swap.");
38
+ if (capabilities.scanConsistency !== "snapshot")
39
+ throw new ApplicationDeliveryValidationError("Application outboxes require storage with snapshot scan consistency: claims read the earliest due entry, and a best-effort scan can miss one.");
40
+ if (capabilities.readAfterWrite !== "linearizable")
41
+ throw new ApplicationDeliveryValidationError("Application outboxes require storage with linearizable read-after-write: maintenance reconciles live attempts against what it reads, and a stale read could abort a current one.");
42
+ }
43
+
44
+ export class Outbox {
45
+ #runtime;
46
+ #disposal = new AbortController;
47
+ #ownAttempts = new Set;
48
+ #maintenanceCursor;
49
+ #maintenanceTimer = null;
50
+ #disposed = !1;
51
+ constructor(options) {
52
+ const policy = resolveOutboxPolicy(options);
53
+ requireOutboxStorage(options.storage);
54
+ if (options.adapter !== void 0 && typeof options.adapter.send !== "function")
55
+ throw new ApplicationDeliveryValidationError("adapter must expose a send() function.");
56
+ if (options.onMaintenanceError !== void 0 && typeof options.onMaintenanceError !== "function")
57
+ throw new ApplicationDeliveryValidationError("onMaintenanceError must be a function.");
58
+ this.#runtime = {
59
+ storage: options.storage,
60
+ events: options.events,
61
+ adapter: options.adapter,
62
+ policy,
63
+ keys: createOutboxKeys(policy.namespace, policy.ownerId),
64
+ now: () => requireClockInstant((options.now ?? Date.now)()),
65
+ generateId: options.generateId ?? (() => crypto.randomUUID()),
66
+ disposal: this.#disposal.signal,
67
+ attemptControllers: attemptControllerRegistry(options.storage, OUTBOX_PRIMITIVE, policy.namespace, policy.ownerId),
68
+ adoptAttempt: (attemptToken) => {
69
+ if (this.#disposed)
70
+ return null;
71
+ this.#ownAttempts.add(attemptToken);
72
+ return () => {
73
+ this.#ownAttempts.delete(attemptToken);
74
+ };
75
+ },
76
+ readMaintenanceCursor: () => this.#maintenanceCursor,
77
+ writeMaintenanceCursor: (cursor) => {
78
+ this.#maintenanceCursor = cursor;
79
+ }
80
+ };
81
+ if (policy.backgroundTasks === "automatic")
82
+ this.#scheduleMaintenance(options.onMaintenanceError ?? defaultMaintenanceErrorSink);
83
+ }
84
+ #scheduleMaintenance(onError) {
85
+ const tick = async () => {
86
+ this.#maintenanceTimer = null;
87
+ if (this.#disposed)
88
+ return;
89
+ try {
90
+ await runOutboxMaintenance(this.#runtime, this.#runtime.now());
91
+ } catch (error) {
92
+ if (this.#disposed)
93
+ return;
94
+ try {
95
+ onError(error);
96
+ } catch {}
97
+ }
98
+ if (!this.#disposed)
99
+ arm();
100
+ }, arm = () => {
101
+ this.#maintenanceTimer = setTimeout(() => {
102
+ tick();
103
+ }, this.#runtime.policy.maintenanceIntervalMs);
104
+ this.#maintenanceTimer.unref?.();
105
+ };
106
+ arm();
107
+ }
108
+ get namespace() {
109
+ return this.#runtime.policy.namespace;
110
+ }
111
+ get ownerId() {
112
+ return this.#runtime.policy.ownerId;
113
+ }
114
+ get storage() {
115
+ return this.#runtime.storage;
116
+ }
117
+ #assertLive() {
118
+ if (this.#disposed)
119
+ throw new ApplicationDeliveryValidationError("This application outbox has been disposed.");
120
+ }
121
+ async enqueue(delivery) {
122
+ this.#assertLive();
123
+ return enqueueDelivery(this.#runtime, delivery);
124
+ }
125
+ async receipt(deliveryId) {
126
+ this.#assertLive();
127
+ const loaded = await loadDelivery(this.#runtime.storage, this.#runtime.keys, validateDeliveryIdentifier(deliveryId));
128
+ return loaded === null ? null : toApplicationDeliveryReceipt(loaded.record);
129
+ }
130
+ async list(options) {
131
+ this.#assertLive();
132
+ return listDeliveries(this.#runtime, options);
133
+ }
134
+ async capacity() {
135
+ this.#assertLive();
136
+ const header = await loadOutboxHeader(this.#runtime.storage, this.#runtime.keys, this.#runtime.policy.namespace, this.#runtime.policy.ownerId);
137
+ return capacityOf(this.#runtime, header.record.openCount, header.record.enqueuedCount);
138
+ }
139
+ async claim(options) {
140
+ this.#assertLive();
141
+ return claimNextDelivery(this.#runtime, options);
142
+ }
143
+ async beginAttempt(options) {
144
+ this.#assertLive();
145
+ return beginAttempt(this.#runtime, {
146
+ deliveryId: validateDeliveryIdentifier(options.deliveryId),
147
+ attemptToken: options.attemptToken
148
+ });
149
+ }
150
+ async heartbeat(options) {
151
+ this.#assertLive();
152
+ return heartbeatAttempt(this.#runtime, {
153
+ deliveryId: validateDeliveryIdentifier(options.deliveryId),
154
+ attemptToken: options.attemptToken,
155
+ transportActivity: validateDurableJSONValue(options.transportActivity, "transportActivity")
156
+ });
157
+ }
158
+ async settle(options) {
159
+ this.#assertLive();
160
+ return settleAttempt(this.#runtime, {
161
+ deliveryId: validateDeliveryIdentifier(options.deliveryId),
162
+ attemptToken: options.attemptToken,
163
+ outcome: validateOutcome(options.outcome)
164
+ });
165
+ }
166
+ async deliverNext(options) {
167
+ this.#assertLive();
168
+ return deliverNext(this.#runtime, options);
169
+ }
170
+ async drain(options) {
171
+ this.#assertLive();
172
+ return drainOutbox(this.#runtime, options);
173
+ }
174
+ async requestCancellation(options) {
175
+ this.#assertLive();
176
+ return requestCancellation(this.#runtime, {
177
+ deliveryId: validateDeliveryIdentifier(options.deliveryId),
178
+ reason: validateCancellationReason(options.reason)
179
+ });
180
+ }
181
+ async cleanupState(deliveryId) {
182
+ this.#assertLive();
183
+ return readCleanupState(this.#runtime, validateDeliveryIdentifier(deliveryId));
184
+ }
185
+ async awaitCleanup(options) {
186
+ this.#assertLive();
187
+ return waitForCleanup(this.#runtime, {
188
+ ...options,
189
+ deliveryId: validateDeliveryIdentifier(options.deliveryId)
190
+ });
191
+ }
192
+ async retry(options) {
193
+ this.#assertLive();
194
+ return retryDelivery(this.#runtime, validateDeliveryIdentifier(options.deliveryId));
195
+ }
196
+ async deadLetter(options) {
197
+ this.#assertLive();
198
+ return deadLetterDelivery(this.#runtime, validateDeliveryIdentifier(options.deliveryId), validateCancellationReason(options.reason));
199
+ }
200
+ async waitForDue(options) {
201
+ this.#assertLive();
202
+ return waitForDueWork(this.#runtime, options);
203
+ }
204
+ async runMaintenance(now = this.#runtime.now()) {
205
+ this.#assertLive();
206
+ return runOutboxMaintenance(this.#runtime, requireMaintenanceInstant(now));
207
+ }
208
+ dispose() {
209
+ if (this.#disposed)
210
+ return;
211
+ this.#disposed = !0;
212
+ if (this.#maintenanceTimer !== null) {
213
+ clearTimeout(this.#maintenanceTimer);
214
+ this.#maintenanceTimer = null;
215
+ }
216
+ for (const attemptToken of this.#ownAttempts) {
217
+ const registration = this.#runtime.attemptControllers.get(attemptToken);
218
+ if (registration === void 0)
219
+ continue;
220
+ this.#runtime.attemptControllers.delete(attemptToken);
221
+ if (!registration.controller.signal.aborted)
222
+ registration.controller.abort(Error("The application outbox was disposed while this attempt was open."));
223
+ }
224
+ this.#ownAttempts.clear();
225
+ this.#disposal.abort(Error("The application outbox was disposed."));
226
+ releaseAttemptControllerRegistry(this.#runtime.storage, OUTBOX_PRIMITIVE, this.#runtime.policy.namespace, this.#runtime.policy.ownerId);
227
+ }
228
+ [Symbol.dispose]() {
229
+ this.dispose();
230
+ }
231
+ }
232
+ function defaultMaintenanceErrorSink(error) {
233
+ console.error("Application outbox maintenance failed:", error);
234
+ }
@@ -0,0 +1,49 @@
1
+ /**
2
+ * Aggregate registry-snapshot limits shared between the producer
3
+ * (`buildRegistrySnapshot`) and the codegen consumer
4
+ * (`cli/codegen-validate.ts`). Split into its own leaf module — rather than
5
+ * living in `registry-snapshot.ts` — so `codegen-validate.ts` can import the
6
+ * constant and error type without pulling in the rest of the (non-public)
7
+ * snapshot-building surface, and so `registry-snapshot.ts` stays under the
8
+ * repository's implementation-file-size ceiling.
9
+ *
10
+ * Deliberately not re-exported from `core/contract/limits.ts` or any other
11
+ * public-surface module: `registry-snapshot.ts` and this module are internal
12
+ * to the package (never re-exported from the package root), so this constant
13
+ * and error class are not part of the public API and carry no `@example`/
14
+ * jsdoc-audit obligations.
15
+ *
16
+ * @module core/registry-limits
17
+ */
18
+ import { WeftError } from './weft-error.ts';
19
+ /**
20
+ * Ceiling on the number of workflows one registry snapshot may report,
21
+ * enforced at snapshot-build time in `buildRegistrySnapshot` (the producer)
22
+ * and, independently, on the raw wire payload in `codegen-validate.ts` (the
23
+ * consumer) before that payload is parsed. The two call sites deliberately
24
+ * share this one constant rather than each defining its own: a consumer
25
+ * ceiling looser than the producer's would be dead code, and a consumer
26
+ * ceiling tighter than the producer's would make `weft codegen --server`
27
+ * reject a legitimately-generated snapshot from a same-release server.
28
+ *
29
+ * 512 matches `worker/manifest/limits.ts`'s `MAX_MANIFEST_WORKFLOW_COUNT` —
30
+ * the analogous ceiling an advertised worker manifest's `workflows` array is
31
+ * held to — without importing across the `core`/`worker` boundary; the two
32
+ * numbers are intentionally kept in sync by convention, not by a shared
33
+ * import, since `core/` does not depend on `worker/`.
34
+ */
35
+ export declare const MAX_REGISTRY_WORKFLOW_COUNT = 512;
36
+ /**
37
+ * Thrown when `buildRegistrySnapshot` would otherwise publish more than
38
+ * {@link MAX_REGISTRY_WORKFLOW_COUNT} workflows in one snapshot. Unlike
39
+ * {@link RegistryManifestLimitError}, this is an aggregate violation with no
40
+ * single offending workflow to name. Mirrors
41
+ * `RegistrySchemaConversionError`/`RegistryManifestLimitError`'s masked-500
42
+ * handling in `server/operations/get-registry.ts`: the wire response stays a
43
+ * generic `500 / Internal server error`, and the actual count reaches
44
+ * server-side logs only.
45
+ */
46
+ export declare class RegistryWorkflowCountLimitError extends WeftError<'RegistryWorkflowCountLimitError'> {
47
+ readonly count: number;
48
+ constructor(count: number);
49
+ }
@@ -0,0 +1,10 @@
1
+ import { WeftError } from "./weft-error.js";
2
+ export const MAX_REGISTRY_WORKFLOW_COUNT = 512;
3
+
4
+ export class RegistryWorkflowCountLimitError extends WeftError {
5
+ count;
6
+ constructor(count) {
7
+ super("RegistryWorkflowCountLimitError", `Registry snapshot would report ${count} workflows, exceeding the maximum of ${MAX_REGISTRY_WORKFLOW_COUNT}`);
8
+ this.count = count;
9
+ }
10
+ }
@@ -0,0 +1,20 @@
1
+ import type { DefinitionSchema } from './types/definition-schema.ts';
2
+ import { WeftError } from './weft-error.ts';
3
+ /**
4
+ * Thrown when a registered workflow or activity schema cannot be converted
5
+ * to JSON Schema. Carries the offending entity name and direction so
6
+ * server-side observability (logs and telemetry) and non-HTTP callers
7
+ * (the in-process MCP builder, programmatic users of `buildRegistrySnapshot`)
8
+ * can identify which registration is broken. The HTTP REST binding
9
+ * deliberately masks this on the wire as a generic `500 / Internal server
10
+ * error` so a misbehaving registration cannot leak schema layout to clients
11
+ * that only have `system:read`.
12
+ */
13
+ export declare class RegistrySchemaConversionError extends WeftError<'RegistrySchemaConversionError'> {
14
+ readonly entityKind: 'workflow' | 'activity';
15
+ readonly entityName: string;
16
+ readonly direction: 'inputSchema' | 'outputSchema';
17
+ constructor(entityKind: 'workflow' | 'activity', entityName: string, direction: 'inputSchema' | 'outputSchema', cause: unknown);
18
+ }
19
+ /** Convert one `DefinitionSchema` fragment to JSON Schema, wrapping a conversion failure as {@link RegistrySchemaConversionError}. */
20
+ export declare function convertSchema(entityKind: 'workflow' | 'activity', entityName: string, field: 'inputSchema' | 'outputSchema', schema: DefinitionSchema): Record<string, unknown>;
@@ -0,0 +1,22 @@
1
+ import { definitionSchemaToJsonSchema } from "./types/definition-schema-to-json.js";
2
+ import { WeftError } from "./weft-error.js";
3
+
4
+ export class RegistrySchemaConversionError extends WeftError {
5
+ entityKind;
6
+ entityName;
7
+ direction;
8
+ constructor(entityKind, entityName, direction, cause) {
9
+ const causeMessage = cause instanceof Error ? cause.message : String(cause);
10
+ super("RegistrySchemaConversionError", `Failed to convert ${direction} for ${entityKind} "${entityName}": ${causeMessage}`, { cause });
11
+ this.entityKind = entityKind;
12
+ this.entityName = entityName;
13
+ this.direction = direction;
14
+ }
15
+ }
16
+ export function convertSchema(entityKind, entityName, field, schema) {
17
+ try {
18
+ return definitionSchemaToJsonSchema(schema, field === "inputSchema" ? "input" : "output");
19
+ } catch (cause) {
20
+ throw new RegistrySchemaConversionError(entityKind, entityName, field, cause);
21
+ }
22
+ }
@@ -8,41 +8,45 @@
8
8
  * exceptions surface as a typed {@link RegistrySchemaConversionError} (see
9
9
  * its JSDoc for what reaches the wire vs server logs).
10
10
  *
11
- * **Ordering guarantee.** Builder code inserts workflow, activity, signal,
12
- * update, and query keys in alphabetical (codepoint) order. Workflow and
13
- * activity names cannot be integer-like (the name grammar requires a leading
14
- * letter or underscore), but signal/update/query names accept any string, so
15
- * integer-like message names could theoretically be reordered by JS engines
16
- * despite the explicit sort. Clients that want to protect themselves from
17
- * future registry sources should still sort `Object.keys(...)` before
18
- * presenting or diffing snapshot entries.
11
+ * **v2.** Each registered workflow's schema/description/tags/message
12
+ * metadata is packaged as a {@link WorkflowRevisionManifest} (`core/contract`,
13
+ * WFT-5) rather than a flat `Record<name, entry>` `workflows` is a sorted
14
+ * array and `activeRevisions` is the `name -> revision` pointer map a
15
+ * consumer resolves the "currently active" manifest through. Building a
16
+ * manifest hashes the normalized contract (`crypto.subtle`), so this module
17
+ * is async where v1 was not.
18
+ *
19
+ * **Ordering guarantee.** `workflows` is sorted by `(name, revision)` via
20
+ * {@link compareWorkflowManifests} — see that export's JSDoc for why the
21
+ * revision tiebreak can never actually fire through this builder.
22
+ * `activities` keys are inserted in alphabetical (codepoint) order, and
23
+ * signal/update/query keys inside each manifest's `contract` the same way.
24
+ * Workflow and activity names cannot be integer-like (the name grammar
25
+ * requires a leading letter or underscore), but signal/update/query names
26
+ * accept any string, so integer-like message names could theoretically be
27
+ * reordered by JS engines despite the explicit sort. Clients that want to
28
+ * protect themselves from future registry sources should still sort
29
+ * `Object.keys(...)` before presenting or diffing snapshot entries.
30
+ *
31
+ * The per-workflow entry/message/scoped-activity conversion this module
32
+ * folds into each manifest lives in `registry-workflow-manifest.ts` — see
33
+ * that module's doc for why it is a separate file.
19
34
  *
20
35
  * @module core/registry-snapshot
21
36
  */
22
37
  import type { ActivityMetadata } from './activity-registry.ts';
38
+ import type { WorkflowRevisionManifest } from './contract/index.ts';
23
39
  import type { Engine } from './engine.ts';
24
- import { WeftError } from './weft-error.ts';
40
+ import { RegistryWorkflowCountLimitError } from './registry-limits.ts';
41
+ import { RegistrySchemaConversionError } from './registry-schema-conversion.ts';
42
+ export { buildWorkflowManifestForType, RegistryManifestLimitError, type RegistryMessageEntry, type RegistryWorkflowEntry, } from './registry-workflow-manifest.ts';
43
+ export { RegistrySchemaConversionError, RegistryWorkflowCountLimitError };
25
44
  /**
26
45
  * Current registry contract version. Future incompatible changes to the
27
46
  * snapshot shape must bump this number; the codegen CLI rejects unknown
28
47
  * versions with a clear upgrade message.
29
48
  */
30
- export declare const REGISTRY_VERSION = 1;
31
- /** Schema metadata reported for a statically registered workflow message. */
32
- export type RegistryMessageEntry = {
33
- inputSchema?: Record<string, unknown>;
34
- outputSchema?: Record<string, unknown>;
35
- };
36
- /** Metadata reported per workflow in a registry snapshot. */
37
- export type RegistryWorkflowEntry = {
38
- inputSchema?: Record<string, unknown>;
39
- outputSchema?: Record<string, unknown>;
40
- description?: string;
41
- tags?: ReadonlyArray<string>;
42
- signals?: Record<string, RegistryMessageEntry>;
43
- updates?: Record<string, RegistryMessageEntry>;
44
- queries?: Record<string, RegistryMessageEntry>;
45
- };
49
+ export declare const REGISTRY_VERSION = 2;
46
50
  /**
47
51
  * Metadata reported per activity in a registry snapshot.
48
52
  *
@@ -67,27 +71,46 @@ export type RegistryActivityEntry = {
67
71
  /**
68
72
  * Snapshot of every locally-registered workflow and activity, suitable for
69
73
  * serialization as the `GET /v1/registry` response body.
74
+ *
75
+ * `workflows` carries one {@link WorkflowRevisionManifest} per registered
76
+ * workflow, sorted by {@link compareWorkflowManifests}. `activeRevisions`
77
+ * points each workflow name at the `revision` of its currently active
78
+ * manifest in `workflows` — today that is always the manifest a consumer
79
+ * resolves, since the engine registers exactly one implementation per name;
80
+ * the pointer exists so a future multi-revision registry source does not
81
+ * require another wire-shape bump. `activities` is unchanged from v1: a
82
+ * flat `Record<name, entry>`, since activities are not versioned contracts.
70
83
  */
71
84
  export type RegistrySnapshot = {
72
- registryVersion: 1;
73
- workflows: Record<string, RegistryWorkflowEntry>;
85
+ registryVersion: typeof REGISTRY_VERSION;
86
+ /** ISO-8601 generation timestamp. Informational only — excluded from codegen input validation and any determinism/drift comparison. */
87
+ generatedAt: string;
88
+ workflows: readonly WorkflowRevisionManifest[];
89
+ activeRevisions: Readonly<Record<string, string>>;
74
90
  activities: Record<string, RegistryActivityEntry>;
75
91
  };
76
92
  /**
77
- * Thrown when a registered workflow or activity schema cannot be converted
78
- * to JSON Schema. Carries the offending entity name and direction so
79
- * server-side observability (logs and telemetry) and non-HTTP callers
80
- * (the in-process MCP builder, programmatic users of `buildRegistrySnapshot`)
81
- * can identify which registration is broken. The HTTP REST binding
82
- * deliberately masks this on the wire as a generic `500 / Internal server
83
- * error` so a misbehaving registration cannot leak schema layout to clients
84
- * that only have `system:read`.
93
+ * Order two workflow revision manifests by `(name, revision)`. `workflows`
94
+ * is sorted with this comparator so registry output is deterministic
95
+ * regardless of registration order.
96
+ *
97
+ * The `revision` tiebreak can never actually fire through
98
+ * {@link buildRegistrySnapshot}: the engine registers at most one
99
+ * implementation per workflow name, so `name` alone is already unique
100
+ * within one snapshot. It exists, and is exported, so a future
101
+ * multi-revision registry source (or this function in isolation) has a
102
+ * total order to rely on, and so the tiebreak itself has direct unit-test
103
+ * coverage independent of engine registration uniqueness.
85
104
  */
86
- export declare class RegistrySchemaConversionError extends WeftError<'RegistrySchemaConversionError'> {
87
- readonly entityKind: 'workflow' | 'activity';
88
- readonly entityName: string;
89
- readonly direction: 'inputSchema' | 'outputSchema';
90
- constructor(entityKind: 'workflow' | 'activity', entityName: string, direction: 'inputSchema' | 'outputSchema', cause: unknown);
105
+ export declare function compareWorkflowManifests(a: Pick<WorkflowRevisionManifest, 'name' | 'revision'>, b: Pick<WorkflowRevisionManifest, 'name' | 'revision'>): number;
106
+ /** Options accepted by {@link buildRegistrySnapshot}. */
107
+ export interface BuildRegistrySnapshotOptions {
108
+ /**
109
+ * Clock used for `generatedAt`. Defaults to `Date.now`; exists solely so
110
+ * tests can pin `generatedAt` for exact-equality assertions. Production
111
+ * call sites never pass this.
112
+ */
113
+ now?: () => number;
91
114
  }
92
115
  /**
93
116
  * Build a registry snapshot from an engine's locally-registered workflows
@@ -95,7 +118,33 @@ export declare class RegistrySchemaConversionError extends WeftError<'RegistrySc
95
118
  * worker but never registered with the local engine) are excluded by
96
119
  * construction — `engine.listActivityDefinitions()` is the only source.
97
120
  *
121
+ * `engine.listWorkflowDefinitions()`/`listActivityDefinitions()` are read
122
+ * synchronously in one eager pass before any `await`, so a workflow
123
+ * registered concurrently mid-build simply does not appear in that call's
124
+ * snapshot — the same eventual-consistency behavior v1's fully-synchronous
125
+ * builder had. No torn or partial manifest is possible.
126
+ *
98
127
  * Throws {@link RegistrySchemaConversionError} if any registered schema
99
- * fails JSON Schema conversion.
128
+ * fails JSON Schema conversion, {@link RegistryManifestLimitError} if a
129
+ * registered workflow's contract exceeds a WFT-5 hostile-input limit, or
130
+ * {@link RegistryWorkflowCountLimitError} if the engine has more than
131
+ * {@link MAX_REGISTRY_WORKFLOW_COUNT} workflows registered in total —
132
+ * checked here, at the producer, so `weft codegen --server`'s matching
133
+ * consumer-side ceiling in `cli/codegen-validate.ts` can never reject a
134
+ * `GET /v1/registry` response this function actually emits. A caller that
135
+ * wants only one or a few workflows' manifests — never the full snapshot,
136
+ * so neither limit above is the right contract — should use
137
+ * `buildWorkflowManifestForType` (`registry-workflow-manifest.ts`) instead;
138
+ * it is what this function itself calls per workflow.
139
+ */
140
+ export declare function buildRegistrySnapshot(engine: Engine, options?: BuildRegistrySnapshotOptions): Promise<RegistrySnapshot>;
141
+ /**
142
+ * Convert one activity's catalog metadata to its `RegistryActivityEntry`
143
+ * projection (schema pair plus queue/description/retry/timeout). Exported
144
+ * so build tooling that resolves a single activity outside a full
145
+ * {@link buildRegistrySnapshot} pass — see
146
+ * `worker/manifest/registry-contract-builder.ts`'s workflow-scoped-first
147
+ * activity resolution — can reuse the same conversion rather than
148
+ * reimplementing it.
100
149
  */
101
- export declare function buildRegistrySnapshot(engine: Engine): RegistrySnapshot;
150
+ export declare function buildActivityEntry(metadata: ActivityMetadata): RegistryActivityEntry;
@@ -1,81 +1,50 @@
1
- import { definitionSchemaToJsonSchema } from "./types/definition-schema-to-json.js";
2
- import { WeftError } from "./weft-error.js";
3
- export const REGISTRY_VERSION = 1;
4
-
5
- export class RegistrySchemaConversionError extends WeftError {
6
- entityKind;
7
- entityName;
8
- direction;
9
- constructor(entityKind, entityName, direction, cause) {
10
- const causeMessage = cause instanceof Error ? cause.message : String(cause);
11
- super("RegistrySchemaConversionError", `Failed to convert ${direction} for ${entityKind} "${entityName}": ${causeMessage}`, { cause });
12
- this.entityKind = entityKind;
13
- this.entityName = entityName;
14
- this.direction = direction;
15
- }
1
+ import { compareCodepoint } from "./compare-codepoint.js";
2
+ import { ensureWorkflowCatalogReady, getWorkflowCatalog } from "./engine/catalog-readiness.js";
3
+ import { MAX_REGISTRY_WORKFLOW_COUNT, RegistryWorkflowCountLimitError } from "./registry-limits.js";
4
+ import { convertSchema, RegistrySchemaConversionError } from "./registry-schema-conversion.js";
5
+ import { buildOneWorkflowManifest } from "./registry-workflow-manifest.js";
6
+ export {
7
+ buildWorkflowManifestForType,
8
+ RegistryManifestLimitError
9
+ } from "./registry-workflow-manifest.js";
10
+ export { RegistrySchemaConversionError, RegistryWorkflowCountLimitError };
11
+ export const REGISTRY_VERSION = 2;
12
+ export function compareWorkflowManifests(a, b) {
13
+ if (a.name < b.name)
14
+ return -1;
15
+ if (a.name > b.name)
16
+ return 1;
17
+ if (a.revision < b.revision)
18
+ return -1;
19
+ if (a.revision > b.revision)
20
+ return 1;
21
+ return 0;
16
22
  }
17
- export function buildRegistrySnapshot(engine) {
18
- const workflowDefinitions = engine.listWorkflowDefinitions(), activityDefinitions = engine.listActivityDefinitions(), sortedWorkflows = workflowDefinitions.toSorted((a, b) => {
19
- if (a.type < b.type)
20
- return -1;
21
- if (a.type > b.type)
22
- return 1;
23
- return 0;
24
- }), sortedActivities = activityDefinitions.toSorted((a, b) => {
25
- if (a.name < b.name)
26
- return -1;
27
- if (a.name > b.name)
28
- return 1;
29
- return 0;
30
- }), workflows = Object.create(null);
31
- for (const definition of sortedWorkflows)
32
- workflows[definition.type] = buildWorkflowEntry(definition);
33
- const activities = Object.create(null);
23
+ export async function buildRegistrySnapshot(engine, options) {
24
+ await ensureWorkflowCatalogReady(engine);
25
+ const workflowDefinitions = engine.listWorkflowDefinitions();
26
+ if (workflowDefinitions.length > MAX_REGISTRY_WORKFLOW_COUNT)
27
+ throw new RegistryWorkflowCountLimitError(workflowDefinitions.length);
28
+ const activityDefinitions = engine.listActivityDefinitions(), sortedWorkflows = workflowDefinitions.toSorted((a, b) => compareCodepoint(a.type, b.type)), sortedActivities = activityDefinitions.toSorted((a, b) => compareCodepoint(a.name, b.name)), manifests = await Promise.all(sortedWorkflows.map((definition) => buildOneWorkflowManifest(engine, definition))), catalog = getWorkflowCatalog(engine), activeRevisions = Object.create(null);
29
+ for (const manifest of manifests) {
30
+ const activePointer = catalog.resolveActive(manifest.name);
31
+ if (activePointer === void 0)
32
+ throw Error(`Registry snapshot invariant violated: workflow "${manifest.name}" has no active workflow ` + "catalog pointer. This is a Weft bug \u2014 engine.register() always installs and activates on " + "registration, and ensureWorkflowCatalogReady() is awaited before this point.");
33
+ activeRevisions[manifest.name] = activePointer.revision;
34
+ }
35
+ const sortedManifests = manifests.toSorted(compareWorkflowManifests), activities = Object.create(null);
34
36
  for (const metadata of sortedActivities)
35
37
  activities[metadata.name] = buildActivityEntry(metadata);
38
+ const now = options?.now ?? Date.now;
36
39
  return {
37
40
  registryVersion: REGISTRY_VERSION,
38
- workflows,
41
+ generatedAt: new Date(now()).toISOString(),
42
+ workflows: sortedManifests,
43
+ activeRevisions,
39
44
  activities
40
45
  };
41
46
  }
42
- function buildWorkflowEntry(definition) {
43
- const entry = {};
44
- if (definition.inputSchema !== void 0)
45
- entry.inputSchema = convertSchema("workflow", definition.type, "inputSchema", definition.inputSchema);
46
- if (definition.outputSchema !== void 0)
47
- entry.outputSchema = convertSchema("workflow", definition.type, "outputSchema", definition.outputSchema);
48
- if (definition.description !== void 0)
49
- entry.description = definition.description;
50
- if (definition.tags.length > 0)
51
- entry.tags = [...definition.tags];
52
- addWorkflowMessageEntries(entry, definition);
53
- return entry;
54
- }
55
- function addWorkflowMessageEntries(entry, definition) {
56
- if (definition.signals !== void 0 && Object.keys(definition.signals).length > 0)
57
- entry.signals = buildMessageEntries(definition.type, "signal", definition.signals);
58
- if (definition.updates !== void 0 && Object.keys(definition.updates).length > 0)
59
- entry.updates = buildMessageEntries(definition.type, "update", definition.updates);
60
- if (definition.queries !== void 0 && Object.keys(definition.queries).length > 0)
61
- entry.queries = buildMessageEntries(definition.type, "query", definition.queries);
62
- }
63
- function buildMessageEntries(workflowType, messageKind, definitions) {
64
- const entries = Object.create(null);
65
- for (const name of Object.keys(definitions).toSorted()) {
66
- const definition = definitions[name];
67
- if (definition === void 0)
68
- continue;
69
- const entry = {}, entityName = `${workflowType}.${messageKind}.${name}`;
70
- if (definition.inputSchema !== void 0)
71
- entry.inputSchema = convertSchema("workflow", entityName, "inputSchema", definition.inputSchema);
72
- if (definition.outputSchema !== void 0)
73
- entry.outputSchema = convertSchema("workflow", entityName, "outputSchema", definition.outputSchema);
74
- entries[name] = entry;
75
- }
76
- return entries;
77
- }
78
- function buildActivityEntry(metadata) {
47
+ export function buildActivityEntry(metadata) {
79
48
  const entry = { queue: metadata.queue };
80
49
  if (metadata.inputSchema !== void 0)
81
50
  entry.inputSchema = convertSchema("activity", metadata.name, "inputSchema", metadata.inputSchema);
@@ -89,10 +58,3 @@ function buildActivityEntry(metadata) {
89
58
  entry.timeout = metadata.timeout;
90
59
  return entry;
91
60
  }
92
- function convertSchema(entityKind, entityName, field, schema) {
93
- try {
94
- return definitionSchemaToJsonSchema(schema, field === "inputSchema" ? "input" : "output");
95
- } catch (cause) {
96
- throw new RegistrySchemaConversionError(entityKind, entityName, field, cause);
97
- }
98
- }