@lostgradient/weft 0.11.0 → 0.13.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 (242) hide show
  1. package/README.md +1 -1
  2. package/dist/cli/api.d.ts +2 -0
  3. package/dist/cli/api.js +3 -4
  4. package/dist/cli/generated/operation-catalog.snapshot.json +5167 -0
  5. package/dist/cli/generated/operation-client.generated.d.ts +119 -10
  6. package/dist/cli/generated/operation-client.generated.js +74 -1
  7. package/dist/cli/index.js +1 -0
  8. package/dist/cli/operation-catalog-snapshot.d.ts +11 -2
  9. package/dist/cli/operation-catalog-snapshot.js +14 -5
  10. package/dist/cli/operation-client-runtime.d.ts +29 -0
  11. package/dist/cli-main.js +227 -401
  12. package/dist/client/client-storage.d.ts +24 -0
  13. package/dist/client/client-storage.js +14 -0
  14. package/dist/client/handle-delegation.d.ts +3 -3
  15. package/dist/client/handle-delegation.js +2 -2
  16. package/dist/client/http-client-requests.d.ts +5 -3
  17. package/dist/client/http-client-requests.js +20 -2
  18. package/dist/client/http-client-storage.d.ts +3 -0
  19. package/dist/client/http-client-storage.js +110 -0
  20. package/dist/client/http-client.d.ts +9 -6
  21. package/dist/client/http-client.js +13 -18
  22. package/dist/client/http-operations.d.ts +3 -1
  23. package/dist/client/http-operations.js +84 -2
  24. package/dist/client/http-request.d.ts +35 -6
  25. package/dist/client/http-request.js +31 -10
  26. package/dist/client/in-process-operations.d.ts +2 -2
  27. package/dist/client/in-process-operations.js +2 -2
  28. package/dist/client/index.d.ts +6 -0
  29. package/dist/client/index.js +18 -0
  30. package/dist/client/interface.d.ts +26 -26
  31. package/dist/client/local.d.ts +9 -6
  32. package/dist/client/local.js +9 -4
  33. package/dist/client/search-params.js +10 -6
  34. package/dist/client/start-body.d.ts +3 -1
  35. package/dist/client/start-body.js +9 -0
  36. package/dist/connection.d.ts +8 -0
  37. package/dist/connection.js +41 -17
  38. package/dist/core/bulk-workflow-filter.d.ts +2 -1
  39. package/dist/core/bulk-workflow-filter.js +5 -1
  40. package/dist/core/engine/async-activity-records.d.ts +12 -1
  41. package/dist/core/engine/async-activity-records.js +81 -2
  42. package/dist/core/engine/bulk-operations-purge.js +16 -1
  43. package/dist/core/engine/bulk-operations-shared.js +2 -0
  44. package/dist/core/engine/callback-creators-core.js +2 -1
  45. package/dist/core/engine/callback-creators-schedule.d.ts +2 -1
  46. package/dist/core/engine/callback-creators-schedule.js +3 -3
  47. package/dist/core/engine/checkpoint-reads.js +11 -1
  48. package/dist/core/engine/child-workflow.js +15 -6
  49. package/dist/core/engine/construction.js +3 -0
  50. package/dist/core/engine/disposal.js +2 -0
  51. package/dist/core/engine/engine-internal-types.d.ts +4 -1
  52. package/dist/core/engine/fenced-write.d.ts +5 -3
  53. package/dist/core/engine/finalizer-status.d.ts +10 -0
  54. package/dist/core/engine/finalizer-status.js +82 -0
  55. package/dist/core/engine/index.d.ts +69 -2
  56. package/dist/core/engine/index.js +71 -8
  57. package/dist/core/engine/internals.d.ts +3 -0
  58. package/dist/core/engine/lease-health.d.ts +64 -0
  59. package/dist/core/engine/lease-health.js +0 -0
  60. package/dist/core/engine/lease-manager.d.ts +4 -2
  61. package/dist/core/engine/lease-manager.js +32 -4
  62. package/dist/core/engine/lifecycle/recovered-services.js +0 -2
  63. package/dist/core/engine/lifecycle/shared.d.ts +28 -0
  64. package/dist/core/engine/lifecycle/start-batch.js +12 -0
  65. package/dist/core/engine/lifecycle/start.d.ts +1 -1
  66. package/dist/core/engine/lifecycle/start.js +34 -5
  67. package/dist/core/engine/lifecycle/transition.js +19 -9
  68. package/dist/core/engine/operations-coordination.d.ts +1 -12
  69. package/dist/core/engine/operations-coordination.js +57 -10
  70. package/dist/core/engine/operations-speculate.d.ts +1 -1
  71. package/dist/core/engine/operations-speculate.js +19 -5
  72. package/dist/core/engine/registration.js +14 -0
  73. package/dist/core/engine/schedule-handle.d.ts +4 -4
  74. package/dist/core/engine/schedule-handle.js +2 -2
  75. package/dist/core/engine/schedule-overlap.d.ts +11 -0
  76. package/dist/core/engine/schedule-overlap.js +50 -0
  77. package/dist/core/engine/schedule-run.d.ts +11 -3
  78. package/dist/core/engine/schedule-run.js +27 -4
  79. package/dist/core/engine/schedule-timer.js +10 -1
  80. package/dist/core/engine/schedules.d.ts +5 -4
  81. package/dist/core/engine/schedules.js +62 -56
  82. package/dist/core/engine/state-utilities.js +1 -1
  83. package/dist/core/engine/storage-io.d.ts +12 -0
  84. package/dist/core/engine/storage-io.js +49 -10
  85. package/dist/core/engine/termination/finalizer-claim.d.ts +8 -6
  86. package/dist/core/engine/termination/finalizer-claim.js +2 -1
  87. package/dist/core/engine/termination/finalizer.js +10 -14
  88. package/dist/core/engine/timeline-coordinator-constants.d.ts +3 -0
  89. package/dist/core/engine/timeline-coordinator-constants.js +1 -0
  90. package/dist/core/engine/timeline-coordinator-detail.d.ts +13 -0
  91. package/dist/core/engine/timeline-coordinator-detail.js +76 -0
  92. package/dist/core/engine/validation/schedule-options.d.ts +8 -1
  93. package/dist/core/engine/validation/schedule-options.js +18 -0
  94. package/dist/core/engine/validation/schedule.d.ts +1 -1
  95. package/dist/core/engine/validation/schedule.js +27 -3
  96. package/dist/core/engine/validation.js +66 -2
  97. package/dist/core/engine/workflow-state-stream.d.ts +5 -1
  98. package/dist/core/engine/workflow-state-stream.js +37 -14
  99. package/dist/core/events/schedule-events.d.ts +3 -4
  100. package/dist/core/events/workflow-events.d.ts +2 -1
  101. package/dist/core/list-filter-validation.d.ts +3 -0
  102. package/dist/core/list-filter-validation.js +11 -0
  103. package/dist/core/registry-snapshot.d.ts +32 -0
  104. package/dist/core/registry-snapshot.js +28 -0
  105. package/dist/core/review/index.d.ts +4 -4
  106. package/dist/core/types/activity.d.ts +52 -5
  107. package/dist/core/types/bulk.d.ts +1 -0
  108. package/dist/core/types/definition-schema-to-json.d.ts +11 -0
  109. package/dist/core/types/definition-schema-to-json.js +11 -2
  110. package/dist/core/types/list-options.d.ts +6 -0
  111. package/dist/core/types/options.d.ts +6 -5
  112. package/dist/core/types/reviews.d.ts +2 -2
  113. package/dist/core/types/schedules.d.ts +45 -2
  114. package/dist/core/types/services-resolution.d.ts +5 -5
  115. package/dist/core/types/state.d.ts +64 -0
  116. package/dist/core/types/workflow-log.d.ts +3 -2
  117. package/dist/core/types/workflow-observability.d.ts +50 -0
  118. package/dist/core/types/workflow-observability.js +0 -0
  119. package/dist/core/types/workflow-registry.d.ts +7 -0
  120. package/dist/core/types.d.ts +1 -0
  121. package/dist/core/types.js +1 -0
  122. package/dist/http.js +2 -0
  123. package/dist/index.d.ts +4 -3
  124. package/dist/indexeddb.js +1 -0
  125. package/dist/json-schema.js +3 -3
  126. package/dist/mcp/cli.js +63 -61
  127. package/dist/mcp/http.d.ts +7 -2
  128. package/dist/mcp/session.d.ts +3 -3
  129. package/dist/mcp/session.js +3 -2
  130. package/dist/mcp/stdio.d.ts +7 -2
  131. package/dist/observability/index.js +2 -2
  132. package/dist/runtime/portable.d.ts +33 -0
  133. package/dist/runtime/portable.js +17 -6
  134. package/dist/server/access-policy-metadata.d.ts +92 -0
  135. package/dist/server/access-policy-metadata.js +78 -0
  136. package/dist/server/engine-event-feed-backend.d.ts +22 -3
  137. package/dist/server/fault-to-http.d.ts +3 -7
  138. package/dist/server/fault-to-http.js +2 -34
  139. package/dist/server/fleet-event-feed.d.ts +65 -0
  140. package/dist/server/handler/index.d.ts +11 -2
  141. package/dist/server/handler/index.js +8 -1
  142. package/dist/server/handler/route-dispatch.d.ts +10 -3
  143. package/dist/server/handler/route-dispatch.js +19 -4
  144. package/dist/server/handler.js +1 -56
  145. package/dist/server/index.d.ts +13 -2
  146. package/dist/server/index.js +88 -64
  147. package/dist/server/interactive-operations.js +2 -0
  148. package/dist/server/openapi-error-responses.js +55 -4
  149. package/dist/server/openapi.d.ts +3 -1
  150. package/dist/server/openapi.js +4 -0
  151. package/dist/server/openrpc-document-schema.d.ts +64 -0
  152. package/dist/server/openrpc-document-schema.js +6 -26
  153. package/dist/server/openrpc.d.ts +4 -0
  154. package/dist/server/openrpc.js +9 -33
  155. package/dist/server/operation-fault.d.ts +24 -7
  156. package/dist/server/operation-fault.js +65 -13
  157. package/dist/server/operations/aggregate-workflows.d.ts +6 -0
  158. package/dist/server/operations/aggregate-workflows.js +3 -2
  159. package/dist/server/operations/async-activity.d.ts +14 -0
  160. package/dist/server/operations/async-activity.js +88 -4
  161. package/dist/server/operations/bulk-filter-helpers.d.ts +3 -0
  162. package/dist/server/operations/bulk-filter-helpers.js +27 -3
  163. package/dist/server/operations/bulk-mutate-workflow-tags.d.ts +6 -0
  164. package/dist/server/operations/bulk-signal-workflows.d.ts +6 -0
  165. package/dist/server/operations/get-stream-chunks.js +2 -7
  166. package/dist/server/operations/get-system-lease.d.ts +19 -0
  167. package/dist/server/operations/get-system-lease.js +48 -0
  168. package/dist/server/operations/get-workflow-observability.d.ts +24 -0
  169. package/dist/server/operations/get-workflow-observability.js +80 -0
  170. package/dist/server/operations/get-workflow-result.js +2 -2
  171. package/dist/server/operations/get-workflow.d.ts +2 -2
  172. package/dist/server/operations/list-filter-query-extractor.js +15 -0
  173. package/dist/server/operations/list-workflows.d.ts +6 -0
  174. package/dist/server/operations/list-workflows.js +12 -3
  175. package/dist/server/operations/operation-helpers.d.ts +9 -18
  176. package/dist/server/operations/operation-helpers.js +5 -23
  177. package/dist/server/operations/purge-workflows.d.ts +3 -0
  178. package/dist/server/operations/recover-all.js +2 -1
  179. package/dist/server/operations/single-workflow-tag-mutation.js +2 -2
  180. package/dist/server/operations/sse-stream.js +2 -7
  181. package/dist/server/operations/storage-capabilities.d.ts +34 -0
  182. package/dist/server/operations/storage-capabilities.js +38 -0
  183. package/dist/server/operations/storage.js +8 -17
  184. package/dist/server/operations/stream-workflow-sse.js +3 -9
  185. package/dist/server/operations/submit-review-decision.d.ts +2 -0
  186. package/dist/server/operations/submit-review-decision.js +19 -2
  187. package/dist/server/operations/update-schedule.d.ts +8 -0
  188. package/dist/server/operations/update-schedule.js +70 -7
  189. package/dist/server/operations/workflow-events-sse.js +2 -2
  190. package/dist/server/replay-live-feed-internals.d.ts +19 -0
  191. package/dist/server/replay-live-feed-internals.js +76 -0
  192. package/dist/server/rest-binding.d.ts +7 -6
  193. package/dist/server/rest-bindings.d.ts +2 -13
  194. package/dist/server/rest-bindings.js +19 -10
  195. package/dist/server/runtime/authentication-bridge.d.ts +2 -2
  196. package/dist/server/serve-internals.js +3 -3
  197. package/dist/server/task-queue.d.ts +7 -5
  198. package/dist/server/workflow-event-feed.d.ts +100 -11
  199. package/dist/server/workflow-event-feed.js +1 -140
  200. package/dist/service-worker/index.d.ts +8 -2
  201. package/dist/service-worker/index.js +37 -56
  202. package/dist/service-worker/setup.d.ts +6 -2
  203. package/dist/storage/auto.js +1 -1
  204. package/dist/storage/bun-sql.js +3 -3
  205. package/dist/storage/capabilities.d.ts +1 -1
  206. package/dist/storage/cloudflare-durable-object-sql.d.ts +75 -0
  207. package/dist/storage/cloudflare-durable-object-sql.js +0 -0
  208. package/dist/storage/cloudflare-value-codec.d.ts +67 -0
  209. package/dist/storage/cloudflare-value-codec.js +46 -0
  210. package/dist/storage/cloudflare.d.ts +140 -0
  211. package/dist/storage/cloudflare.js +127 -0
  212. package/dist/storage/compressed-storage.js +1 -1
  213. package/dist/storage/http.js +200 -2
  214. package/dist/storage/index.d.ts +8 -1
  215. package/dist/storage/indexeddb.js +311 -1
  216. package/dist/storage/interface.d.ts +16 -4
  217. package/dist/storage/interface.js +1 -1
  218. package/dist/storage/key-prefixes.d.ts +1 -1
  219. package/dist/storage/key-prefixes.js +4 -0
  220. package/dist/storage/lmdb.js +1 -1
  221. package/dist/storage/memory.js +1 -1
  222. package/dist/storage/neon.js +4 -4
  223. package/dist/storage/node-sqlite.js +3 -3
  224. package/dist/storage/postgres-key-value-queries.d.ts +6 -0
  225. package/dist/storage/postgres-key-value-queries.js +2 -3
  226. package/dist/storage/postgres.js +4 -4
  227. package/dist/storage/resolve.js +1 -1
  228. package/dist/storage/scoped-storage.js +1 -1
  229. package/dist/storage/sql-identifier.d.ts +35 -0
  230. package/dist/storage/sql-identifier.js +5 -0
  231. package/dist/storage/sqlite-key-value-queries.d.ts +11 -6
  232. package/dist/storage/sqlite-key-value-queries.js +3 -3
  233. package/dist/storage/testing.js +1 -1
  234. package/dist/storage/turso.js +2 -2
  235. package/dist/storage/typed-storage.js +138 -2
  236. package/dist/storage/web-extension.js +298 -1
  237. package/dist/testing/index.js +21 -60
  238. package/dist/version.d.ts +1 -1
  239. package/dist/version.js +1 -1
  240. package/dist/web-extension.js +1 -0
  241. package/dist/worker/protocol.js +1 -1
  242. package/package.json +8 -3
@@ -1,4 +1,4 @@
1
- import type { Engine } from '../core/engine.ts';
1
+ import type { RegistryAgnosticEngine } from '../core/engine.ts';
2
2
  import { type Principal } from '../server/principal.ts';
3
3
  import { McpSessionManager } from './session.ts';
4
4
  /**
@@ -25,7 +25,12 @@ import { McpSessionManager } from './session.ts';
25
25
  */
26
26
  export type McpHttpRequestOptions = {
27
27
  readonly request: Request;
28
- readonly engine: Engine;
28
+ /**
29
+ * Typed as {@link RegistryAgnosticEngine} (see its JSDoc) rather than the
30
+ * plain default `Engine`, so both `new Engine({ storage })` and
31
+ * `Engine.create({ workflows })` type-check here directly.
32
+ */
33
+ readonly engine: RegistryAgnosticEngine;
29
34
  readonly sessionManager: McpSessionManager;
30
35
  readonly principal?: Principal;
31
36
  readonly authRequired: boolean;
@@ -1,4 +1,4 @@
1
- import type { Engine } from '../core/engine.ts';
1
+ import type { RegistryAgnosticEngine } from '../core/engine.ts';
2
2
  import { WeftError } from '../core/weft-error.ts';
3
3
  import type { Principal } from '../server/principal.ts';
4
4
  import { type McpResponse } from './protocol.ts';
@@ -123,7 +123,7 @@ export declare class McpSession {
123
123
  */
124
124
  export declare class McpSessionManager implements AsyncDisposable {
125
125
  #private;
126
- constructor(engine: Engine, options?: McpSessionManagerOptions);
126
+ constructor(engine: RegistryAgnosticEngine, options?: McpSessionManagerOptions);
127
127
  /** Create and store a new session for a principal. */
128
128
  create(principal: Principal): McpSession;
129
129
  /** Store an externally-created session. Used by stdio. */
@@ -150,5 +150,5 @@ export declare class McpSessionManager implements AsyncDisposable {
150
150
  * void manager;
151
151
  * ```
152
152
  */
153
- export declare function createMcpSessionManager(engine: Engine, options?: McpSessionManagerOptions): McpSessionManager;
153
+ export declare function createMcpSessionManager(engine: RegistryAgnosticEngine, options?: McpSessionManagerOptions): McpSessionManager;
154
154
  export {};
@@ -127,11 +127,12 @@ export class McpSessionManager {
127
127
  #currentTimeMilliseconds;
128
128
  #toolListSignature;
129
129
  constructor(engine, options = {}) {
130
- this.#engine = engine;
130
+ const erasedEngine = engine;
131
+ this.#engine = erasedEngine;
131
132
  this.#maximumSessions = options.maximumSessions ?? 1024;
132
133
  this.#sessionIdleTimeoutMilliseconds = options.sessionIdleTimeoutMilliseconds ?? 1800000;
133
134
  this.#currentTimeMilliseconds = options.currentTimeMilliseconds ?? Date.now;
134
- this.#toolListSignature = toolListSignature(engine);
135
+ this.#toolListSignature = toolListSignature(erasedEngine);
135
136
  this.#resourceListener = (event) => {
136
137
  const workflowId = event.workflowId;
137
138
  if (typeof workflowId !== "string")
@@ -1,4 +1,4 @@
1
- import type { Engine } from '../core/engine.ts';
1
+ import type { RegistryAgnosticEngine } from '../core/engine.ts';
2
2
  import { type McpSessionManagerOptions } from './session.ts';
3
3
  /**
4
4
  * Admission modes for local MCP stdio sessions.
@@ -46,7 +46,12 @@ export type McpStdioAdmission = {
46
46
  export type McpStdioSessionOptions = {
47
47
  readonly input: ReadableStream<Uint8Array>;
48
48
  readonly output: WritableStream<Uint8Array>;
49
- readonly engine: Engine;
49
+ /**
50
+ * Typed as {@link RegistryAgnosticEngine} (see its JSDoc) rather than the
51
+ * plain default `Engine`, so both `new Engine({ storage })` and
52
+ * `Engine.create({ workflows })` type-check here directly.
53
+ */
54
+ readonly engine: RegistryAgnosticEngine;
50
55
  readonly admission: McpStdioAdmission;
51
56
  readonly maxFrameBytes?: number;
52
57
  readonly sessionManagerOptions?: McpSessionManagerOptions;
@@ -1,4 +1,4 @@
1
1
  // @bun
2
- var kS=Object.defineProperty;var zS=(S)=>S;function CS(S,W){this[S]=zS.bind(null,W)}var L0=(S,W)=>{for(var $ in W)kS(S,$,{get:W[$],enumerable:!0,configurable:!0,set:CS.bind(W,$)})};var L=(S,W)=>()=>(S&&(W=S(S=0)),W);var Q0=import.meta.require,j0=(S,W,$)=>{if(W!=null){if(typeof W!=="object"&&typeof W!=="function")throw TypeError('Object expected to be assigned to "using" declaration');let x;if($)x=W[Symbol.asyncDispose];if(x===void 0)x=W[Symbol.dispose];if(typeof x!=="function")throw TypeError("Object not disposable");S.push([$,x,W])}else if($)S.push([$]);return W},H0=(S,W,$)=>{let x=(K)=>W=$?new SuppressedError(K,W,"An error was suppressed during disposal"):($=!0,K),G=(K)=>{while(K=S.pop())try{var J=K[1]&&K[1].call(K[2]);if(K[0])return Promise.resolve(J).then(G,(H)=>(x(H),G()))}catch(H){x(H)}if($)throw W};return G()};var c,i,d,n,l;var o=L(()=>{c=class c extends Event{static type="activity:started";operationId;workflowId;activityName;attempt;constructor(S,W,$,x){super(c.type);this.operationId=S,this.workflowId=W,this.activityName=$,this.attempt=x}};i=class i extends Event{static type="activity:completed";operationId;workflowId;activityName;duration;constructor(S,W,$,x){super(i.type);this.operationId=S,this.workflowId=W,this.activityName=$,this.duration=x}};d=class d extends Event{static type="activity:async-pending";token;operationId;workflowId;activityName;attempt;constructor(S,W,$,x,G){super(d.type);this.token=S,this.operationId=W,this.workflowId=$,this.activityName=x,this.attempt=G}};n=class n extends Event{static type="activity:failed";operationId;workflowId;activityName;error;attempt;constructor(S,W,$,x,G){super(n.type);this.operationId=S,this.workflowId=W,this.activityName=$,this.error=x,this.attempt=G}};l=class l extends Event{static type="task:dead-lettered";operationId;workflowId;activityName;queue;workerId;reason;errorMessage;constructor({operationId:S,workflowId:W,activityName:$,queue:x,workerId:G,errorMessage:K}){super(l.type);this.operationId=S,this.workflowId=W,this.activityName=$,this.queue=x,this.workerId=G,this.reason="result-resolution-storage-exhausted",this.errorMessage=K}}});var r;var s=L(()=>{r=class r extends Event{static type="attributes:changed";workflowId;changes;constructor(S,W){super(r.type);this.workflowId=S,this.changes=W}}});var a,t;var e=L(()=>{a=class a extends Event{static type="schedule:fired";scheduleId;workflowId;firedAt;occurrence;constructor(S,W,$,x){super(a.type);this.scheduleId=S,this.workflowId=W,this.firedAt=$,this.occurrence=x}};t=class t extends Event{static type="schedule:missed-fire";scheduleId;missedCount;windowStart;windowEnd;constructor(S,W,$,x){super(t.type);this.scheduleId=S,this.missedCount=W,this.windowStart=$,this.windowEnd=x}}});var SS,WS;var $S=L(()=>{SS=class SS extends Event{static type="signal:received";workflowId;signalName;payload;constructor(S,W,$){super(SS.type);this.workflowId=S,this.signalName=W,this.payload=$}};WS=class WS extends Event{static type="signal:delivered";workflowId;signalName;constructor(S,W){super(WS.type);this.workflowId=S,this.signalName=W}}});var xS,GS,KS,XS,JS,LS,QS,jS,HS;var YS=L(()=>{xS=class xS extends Event{static type="checkpoint:size-warning";workflowId;sizeBytes;step;constructor(S,W,$){super(xS.type);this.workflowId=S,this.sizeBytes=W,this.step=$}};GS=class GS extends Event{static type="development:warning";workflowId;message;fieldPaths;constructor(S,W,$){super(GS.type);this.workflowId=S,this.message=W,this.fieldPaths=$}};KS=class KS extends Event{static type="cleanup:warning";source;error;workflowId;constructor(S,W,$){super(KS.type);this.source=S,this.error=W,this.workflowId=$}};XS=class XS extends Event{static type="storage:size-reported";sizeBytes;constructor(S){super(XS.type);this.sizeBytes=S}};JS=class JS extends Event{static type="worker:connected";workerId;queue;activities;concurrency;constructor(S,W,$,x){super(JS.type);this.workerId=S,this.queue=W,this.activities=$,this.concurrency=x}};LS=class LS extends Event{static type="worker:disconnected";workerId;inFlightTaskCount;constructor(S,W){super(LS.type);this.workerId=S,this.inFlightTaskCount=W}};QS=class QS extends Event{static type="alert:fired";metric;threshold;currentValue;window;constructor(S,W,$,x){super(QS.type);this.metric=S,this.threshold=W,this.currentValue=$,this.window=x}};jS=class jS extends Event{static type="alert:resolved";metric;threshold;currentValue;window;constructor(S,W,$,x){super(jS.type);this.metric=S,this.threshold=W,this.currentValue=$,this.window=x}};HS=class HS extends Event{static type="constraint:violated";workflowId;constraintName;scope;onViolation;constructor(S,W,$,x){super(HS.type);this.workflowId=S,this.constraintName=W,this.scope=$,this.onViolation=x}}});var ZS,OS;var BS=L(()=>{ZS=class ZS extends Event{static type="update:received";updateId;workflowId;name;payload;constructor(S,W,$,x){super(ZS.type);this.updateId=S,this.workflowId=W,this.name=$,this.payload=x}};OS=class OS extends Event{static type="update:completed";updateId;workflowId;name;result;error;constructor(S,W,$,x,G){super(OS.type);this.updateId=S,this.workflowId=W,this.name=$,this.result=x,this.error=G}}});var PS,qS,Y,Z,O,B,C0,TS,yS,US,_S;var bS=L(()=>{PS=class PS extends Event{static type="workflow:definition-registered";workflowType;constructor(S){super(PS.type);this.workflowType=S}};qS=class qS extends Event{static type="workflow:started";workflowId;workflowType;input;constructor(S,W,$){super(qS.type);this.workflowId=S,this.workflowType=W,this.input=$}};Y=class Y extends Event{static type="workflow:completed";workflowId;result;duration;constructor(S,W,$){super(Y.type);this.workflowId=S,this.result=W,this.duration=$}};Z=class Z extends Event{static type="workflow:failed";workflowId;error;constructor(S,W){super(Z.type);this.workflowId=S,this.error=W}};O=class O extends Event{static type="workflow:cancelled";workflowId;constructor(S){super(O.type);this.workflowId=S}};B=class B extends Event{static type="workflow:timed-out";workflowId;timeoutType;elapsed;reason;constructor(S,W,$,x){super(B.type);if(this.workflowId=S,this.timeoutType=W,this.elapsed=$,x!==void 0)this.reason=x}};C0=new Set([Y.type,Z.type,O.type,B.type]);TS=class TS extends Event{static type="workflow:resumed";workflowId;fromStep;constructor(S,W){super(TS.type);this.workflowId=S,this.fromStep=W}};yS=class yS extends Event{static type="workflow:suspended";workflowId;constructor(S){super(yS.type);this.workflowId=S}};US=class US extends Event{static type="workflow:recovery-skipped";workflowId;workflowType;reason;constructor(S,W,$){super(US.type);this.workflowId=S,this.workflowType=W,this.reason=$}};_S=class _S extends Event{static type="workflow:teardown";workflowId;workflowType;status;attempts;error;constructor(S,W,$,x,G){super(_S.type);this.workflowId=S,this.workflowType=W,this.status=$,this.attempts=x,this.error=G}}});var FS=L(()=>{o();s();e();$S();YS();BS();bS()});var MS=L(()=>{FS()});var wS={traceId:"0".repeat(32),spanId:"0".repeat(16),traceFlags:0},F={setAttribute(){},setStatus(){},recordException(){},end(){},spanContext(){return wS}},w={setAttribute:(...S)=>F.setAttribute(...S),setStatus:(...S)=>F.setStatus(...S),recordException:(...S)=>F.recordException(...S),end:(...S)=>F.end(...S)},pS={startSpan(){return F}},k={record(){},add(){}},IS={createHistogram(){return k},createCounter(){return k},createUpDownCounter(){return k}},NS=Symbol("ROOT_CONTEXT"),gS={trace:{getTracer(){return pS},setSpan(S){return S}},metrics:{getMeter(){return IS}},context:{ROOT_CONTEXT:NS,with(S,W){return W()}},SpanStatusCode:{OK:1,ERROR:2,UNSET:0}},q;function vS(){let S=globalThis.require;if(typeof S==="function")return(W)=>S(W);return()=>{return}}function ES(S){return S?.trace?.getTracer!=null&&S.SpanStatusCode!=null}function hS(S=vS()){try{let W=S("@opentelemetry/api");if(ES(W))return W}catch{}return}function T(S){if(q)return q;let W=hS(S);if(W)return q=W,q;return q=gS,q}function p(S){let W=new Uint8Array(S);return crypto.getRandomValues(W),Array.from(W,($)=>$.toString(16).padStart(2,"0")).join("")}var I="traceparent",uS=/^([0-9a-f]{2})-([0-9a-f]{32})-([0-9a-f]{16})-([0-9a-f]{2})$/,mS="00000000000000000000000000000000",cS="0000000000000000";function N(S){let W=uS.exec(S);if(!W)return null;let[,$,x,G,K]=W;if(x===mS)return null;if(G===cS)return null;return{version:$,traceId:x,spanId:G,traceFlags:parseInt(K,16)}}function g(S){let W=S.traceFlags.toString(16).padStart(2,"0");return`${S.version}-${S.traceId}-${S.spanId}-${W}`}function M(S){let W=S.get(I);if(!W)return null;return N(W)}function z(S,W){S.set(I,g(W))}function iS(){return p(16)}function dS(){return p(8)}var v=1024;function y(S,W){let $;try{$=JSON.stringify(S)}catch{$=String(S)}if($.length>W)return $.slice(0,W)+"...";return $}function nS(S){return S instanceof Error?S.message:String(S)}function lS(S){return S instanceof Error?S:Error(String(S))}function R(S,W){let $=S.spanContext();z(W,{version:"00",traceId:$.traceId,spanId:$.spanId,traceFlags:$.traceFlags})}function U(S,W,$){let x=S.attributeExtractor;if(!x)return;let G=x($);for(let[K,J]of Object.entries(G))W.setAttribute(K,J)}function A(S,W){let $=S.workflowSpans.get(W);return $?S.trace.setSpan(S.api.context.ROOT_CONTEXT,$.span):S.api.context.ROOT_CONTEXT}function C(S,W,$){W.setStatus({code:S.SpanStatusCode.ERROR,message:nS($)}),W.recordException(lS($))}function E(S,W,$,x){try{let G=$();return W.setStatus({code:S.SpanStatusCode.OK}),x?.(G),G}catch(G){throw C(S,W,G),G}finally{W.end()}}async function f(S,W,$,x){try{let G=await $();return W.setStatus({code:S.SpanStatusCode.OK}),x?.(G),G}catch(G){throw C(S,W,G),G}finally{W.end()}}function*D(S,W,$,x){try{let G=yield*$();return W.setStatus({code:S.SpanStatusCode.OK}),x?.(G),G}catch(G){throw C(S,W,G),G}finally{W.end()}}function h(S){return{async execute(W,$){let x=M(W.headers),G=S.api.context.ROOT_CONTEXT;if(x){let J={...w,spanContext(){return{traceId:x.traceId,spanId:x.spanId,traceFlags:x.traceFlags}}};G=S.trace.setSpan(S.api.context.ROOT_CONTEXT,J)}let K=S.tracer.startSpan(`activity:execute:${W.activityName}`,{attributes:{"weft.activity.name":W.activityName,"weft.activity.attempt":W.attempt,...x?{"weft.parent.trace_id":x.traceId}:{}}},G);if(S.recordPayloads&&W.input!==void 0)K.setAttribute("weft.payload.input",y(W.input,S.maxPayloadSize));return f(S,K,()=>$(W))}}}var _={workflowDuration:{name:"weft.workflow.duration",description:"Duration of workflow execution in milliseconds",unit:"ms",type:"histogram"},activityDuration:{name:"weft.activity.duration",description:"Duration of activity execution in milliseconds",unit:"ms",type:"histogram"},activityAttempts:{name:"weft.activity.attempts",description:"Total activity execution attempts",unit:"attempts",type:"counter"},workflowActive:{name:"weft.workflow.active",description:"Number of currently active workflows",unit:"workflows",type:"gauge"},workflowStarted:{name:"weft.workflow.started",description:"Total workflows started",unit:"workflows",type:"counter"},workflowCompleted:{name:"weft.workflow.completed",description:"Total workflows completed",unit:"workflows",type:"counter"},workflowFailed:{name:"weft.workflow.failed",description:"Total workflows failed",unit:"workflows",type:"counter"},promptCacheHits:{name:"weft.prompt_cache.hits",description:"Total prompt prefix cache hits",unit:"hits",type:"counter"},promptCacheMisses:{name:"weft.prompt_cache.misses",description:"Total prompt prefix cache misses",unit:"misses",type:"counter"},dpmoDefects:{name:"weft.dpmo.defects",description:"Total failed workflows (DPMO numerator)",unit:"workflows",type:"counter"},dpmoOperations:{name:"weft.dpmo.operations",description:"Total started workflows (DPMO denominator)",unit:"workflows",type:"counter"},taskBacklog:{name:"weft.task.backlog",description:"Number of queued tasks waiting for workers",unit:"tasks",type:"gauge"},taskQueueLatency:{name:"weft.task.queue_latency",description:"Time tasks spend queued before dispatch in milliseconds",unit:"ms",type:"histogram"},taskExecutionLatency:{name:"weft.task.execution_latency",description:"Time tasks spend executing after worker start in milliseconds",unit:"ms",type:"histogram"},taskRetries:{name:"weft.task.retries",description:"Total task retry attempts after the first dispatch attempt",unit:"retries",type:"counter"},taskRequeues:{name:"weft.task.requeues",description:"Total visibility-timeout or disconnect task requeues",unit:"requeues",type:"counter"},taskStaleHeartbeats:{name:"weft.task.stale_heartbeats",description:"Number of in-flight tasks whose heartbeat age exceeds the diagnostic threshold",unit:"tasks",type:"gauge"},workerCapacitySaturation:{name:"weft.worker.capacity_saturation",description:"Ratio of in-flight worker slots to total worker concurrency",unit:"ratio",type:"gauge"}};var oS=1e4;class u{#S;#$=0;#W=0;constructor(S){this.#S=new Float64Array(S)}push(S){if(this.#S[this.#$]=S,this.#$=(this.#$+1)%this.#S.length,this.#W<this.#S.length)this.#W++}toArray(){if(this.#W<this.#S.length)return Array.from(this.#S.subarray(0,this.#W));let S=Array.from({length:this.#W});for(let W=0;W<this.#W;W++)S[W]=this.#S[(this.#$+W)%this.#S.length];return S}}class V{#S;#$;#W;constructor(){this.#S=new Map,this.#$=new Map,this.#W=new Map}increment(S,W=1){this.#S.set(S,(this.#S.get(S)??0)+W)}record(S,W){let $=this.#$.get(S);if(!$)$=new u(oS),this.#$.set(S,$);$.push(W)}gauge(S,W){this.#W.set(S,W)}snapshot(){let S={};for(let[W,$]of this.#S)S[W]={type:"counter",value:$};for(let[W,$]of this.#$){let x=$.toArray(),G=sS(x);S[W]={type:"histogram",count:x.length,sum:aS(x),p50:G[Math.floor(G.length*0.5)]??0,p99:G[Math.floor(G.length*0.99)]??0,min:G[0]??0,max:G[G.length-1]??0}}for(let[W,$]of this.#W)S[W]={type:"gauge",value:$};return S}reset(){this.#S.clear(),this.#$.clear(),this.#W.clear()}}function rS(S){let W;if(typeof S==="string")W=T().metrics.getMeter(S);else if(S)W=S;else W=T().metrics.getMeter("weft");return{workflowDuration:W.createHistogram("weft.workflow.duration",{unit:"ms"}),activityDuration:W.createHistogram("weft.activity.duration",{unit:"ms"}),activityAttempts:W.createCounter("weft.activity.attempts"),activeWorkflows:W.createUpDownCounter("weft.workflow.active")}}function sS(S){let W=[...S];return W.sort(($,x)=>$-x),W}function aS(S){let W=0;for(let $ of S)W+=$;return W}function tS(S,W){let $=W?.type==="histogram"?W.count:0,x=W?.type==="histogram"?W.sum:0;return[`# TYPE ${S} histogram`,`${S}_count ${$}`,`${S}_sum ${x}`]}function eS(S,W){let $=W?.type==="counter"?W.value:0;return[`# TYPE ${S} counter`,`${S}_total ${$}`]}function S0(S,W){let $=W?.type==="gauge"?W.value:0;return[`# TYPE ${S} gauge`,`${S} ${$}`]}var W0={histogram:tS,counter:eS,gauge:S0};function $0(S,W){let $=S.name.replace(/\./g,"_"),x=W[S.name];return[`# HELP ${$} ${S.description}`,...W0[S.type]($,x)]}function x0(S){let W=S[_.dpmoDefects.name],$=S[_.dpmoOperations.name],x=W?.type==="counter"?W.value:0,G=$?.type==="counter"?$.value:0,K=G===0?0:x*1e6/G,J="weft_dpmo";return["# HELP weft_dpmo Defects per million operations (failed workflows / started workflows * 1e6)","# TYPE weft_dpmo gauge",`weft_dpmo ${K}`]}function m(S){let W=[];for(let $ of Object.values(_))W.push(...$0($,S));return W.push(...x0(S)),W.join(`
2
+ var Jn=import.meta.require,Qn=(n,w,i)=>{if(w!=null){if(typeof w!=="object"&&typeof w!=="function")throw TypeError('Object expected to be assigned to "using" declaration');let S;if(i)S=w[Symbol.asyncDispose];if(S===void 0)S=w[Symbol.dispose];if(typeof S!=="function")throw TypeError("Object not disposable");n.push([i,S,w])}else if(i)n.push([i]);return w},jn=(n,w,i)=>{let S=(f)=>w=i?new SuppressedError(f,w,"An error was suppressed during disposal"):(i=!0,f),k=(f)=>{while(f=n.pop())try{var y=f[1]&&f[1].call(f[2]);if(f[0])return Promise.resolve(y).then(k,(p)=>(S(p),k()))}catch(p){S(p)}if(i)throw w};return k()};var h={traceId:"0".repeat(32),spanId:"0".repeat(16),traceFlags:0},T={setAttribute(){},setStatus(){},recordException(){},end(){},spanContext(){return h}},q={setAttribute:(...n)=>T.setAttribute(...n),setStatus:(...n)=>T.setStatus(...n),recordException:(...n)=>T.recordException(...n),end:(...n)=>T.end(...n)},l={startSpan(){return T}},P={record(){},add(){}},t={createHistogram(){return P},createCounter(){return P},createUpDownCounter(){return P}},r=Symbol("ROOT_CONTEXT"),a={trace:{getTracer(){return l},setSpan(n){return n}},metrics:{getMeter(){return t}},context:{ROOT_CONTEXT:r,with(n,w){return w()}},SpanStatusCode:{OK:1,ERROR:2,UNSET:0}},o;function s(){let n=globalThis.require;if(typeof n==="function")return(w)=>n(w);return()=>{return}}function e(n){return n?.trace?.getTracer!=null&&n.SpanStatusCode!=null}function nn(n=s()){try{let w=n("@opentelemetry/api");if(e(w))return w}catch{}return}function K(n){if(o)return o;let w=nn(n);if(w)return o=w,o;return o=a,o}function H(n){let w=new Uint8Array(n);return crypto.getRandomValues(w),Array.from(w,(i)=>i.toString(16).padStart(2,"0")).join("")}var Y="traceparent",wn=/^([0-9a-f]{2})-([0-9a-f]{32})-([0-9a-f]{16})-([0-9a-f]{2})$/,Sn="00000000000000000000000000000000",kn="0000000000000000";function Z(n){let w=wn.exec(n);if(!w)return null;let[,i,S,k,f]=w;if(S===Sn)return null;if(k===kn)return null;return{version:i,traceId:S,spanId:k,traceFlags:parseInt(f,16)}}function M(n){let w=n.traceFlags.toString(16).padStart(2,"0");return`${n.version}-${n.traceId}-${n.spanId}-${w}`}function J(n){let w=n.get(Y);if(!w)return null;return Z(w)}function U(n,w){n.set(Y,M(w))}function fn(){return H(16)}function vn(){return H(8)}var O=1024;function C(n,w){let i;try{i=JSON.stringify(n)}catch{i=String(n)}if(i.length>w)return i.slice(0,w)+"...";return i}function yn(n){return n instanceof Error?n.message:String(n)}function Wn(n){return n instanceof Error?n:Error(String(n))}function Q(n,w){let i=n.spanContext();U(w,{version:"00",traceId:i.traceId,spanId:i.spanId,traceFlags:i.traceFlags})}function A(n,w,i){let S=n.attributeExtractor;if(!S)return;let k=S(i);for(let[f,y]of Object.entries(k))w.setAttribute(f,y)}function j(n,w){let i=n.workflowSpans.get(w);return i?n.trace.setSpan(n.api.context.ROOT_CONTEXT,i.span):n.api.context.ROOT_CONTEXT}function V(n,w,i){w.setStatus({code:n.SpanStatusCode.ERROR,message:yn(i)}),w.recordException(Wn(i))}function _(n,w,i,S){try{let k=i();return w.setStatus({code:n.SpanStatusCode.OK}),S?.(k),k}catch(k){throw V(n,w,k),k}finally{w.end()}}async function x(n,w,i,S){try{let k=await i();return w.setStatus({code:n.SpanStatusCode.OK}),S?.(k),k}catch(k){throw V(n,w,k),k}finally{w.end()}}function*B(n,w,i,S){try{let k=yield*i();return w.setStatus({code:n.SpanStatusCode.OK}),S?.(k),k}catch(k){throw V(n,w,k),k}finally{w.end()}}function g(n){return{async execute(w,i){let S=J(w.headers),k=n.api.context.ROOT_CONTEXT;if(S){let y={...q,spanContext(){return{traceId:S.traceId,spanId:S.spanId,traceFlags:S.traceFlags}}};k=n.trace.setSpan(n.api.context.ROOT_CONTEXT,y)}let f=n.tracer.startSpan(`activity:execute:${w.activityName}`,{attributes:{"weft.activity.name":w.activityName,"weft.activity.attempt":w.attempt,...S?{"weft.parent.trace_id":S.traceId}:{}}},k);if(n.recordPayloads&&w.input!==void 0)f.setAttribute("weft.payload.input",C(w.input,n.maxPayloadSize));return x(n,f,()=>i(w))}}}var X={workflowDuration:{name:"weft.workflow.duration",description:"Duration of workflow execution in milliseconds",unit:"ms",type:"histogram"},activityDuration:{name:"weft.activity.duration",description:"Duration of activity execution in milliseconds",unit:"ms",type:"histogram"},activityAttempts:{name:"weft.activity.attempts",description:"Total activity execution attempts",unit:"attempts",type:"counter"},workflowActive:{name:"weft.workflow.active",description:"Number of currently active workflows",unit:"workflows",type:"gauge"},workflowStarted:{name:"weft.workflow.started",description:"Total workflows started",unit:"workflows",type:"counter"},workflowCompleted:{name:"weft.workflow.completed",description:"Total workflows completed",unit:"workflows",type:"counter"},workflowFailed:{name:"weft.workflow.failed",description:"Total workflows failed",unit:"workflows",type:"counter"},promptCacheHits:{name:"weft.prompt_cache.hits",description:"Total prompt prefix cache hits",unit:"hits",type:"counter"},promptCacheMisses:{name:"weft.prompt_cache.misses",description:"Total prompt prefix cache misses",unit:"misses",type:"counter"},dpmoDefects:{name:"weft.dpmo.defects",description:"Total failed workflows (DPMO numerator)",unit:"workflows",type:"counter"},dpmoOperations:{name:"weft.dpmo.operations",description:"Total started workflows (DPMO denominator)",unit:"workflows",type:"counter"},taskBacklog:{name:"weft.task.backlog",description:"Number of queued tasks waiting for workers",unit:"tasks",type:"gauge"},taskQueueLatency:{name:"weft.task.queue_latency",description:"Time tasks spend queued before dispatch in milliseconds",unit:"ms",type:"histogram"},taskExecutionLatency:{name:"weft.task.execution_latency",description:"Time tasks spend executing after worker start in milliseconds",unit:"ms",type:"histogram"},taskRetries:{name:"weft.task.retries",description:"Total task retry attempts after the first dispatch attempt",unit:"retries",type:"counter"},taskRequeues:{name:"weft.task.requeues",description:"Total visibility-timeout or disconnect task requeues",unit:"requeues",type:"counter"},taskStaleHeartbeats:{name:"weft.task.stale_heartbeats",description:"Number of in-flight tasks whose heartbeat age exceeds the diagnostic threshold",unit:"tasks",type:"gauge"},workerCapacitySaturation:{name:"weft.worker.capacity_saturation",description:"Ratio of in-flight worker slots to total worker concurrency",unit:"ratio",type:"gauge"}};var dn=1e4;class z{#n;#i=0;#w=0;constructor(n){this.#n=new Float64Array(n)}push(n){if(this.#n[this.#i]=n,this.#i=(this.#i+1)%this.#n.length,this.#w<this.#n.length)this.#w++}toArray(){if(this.#w<this.#n.length)return Array.from(this.#n.subarray(0,this.#w));let n=Array.from({length:this.#w});for(let w=0;w<this.#w;w++)n[w]=this.#n[(this.#i+w)%this.#n.length];return n}}class D{#n;#i;#w;constructor(){this.#n=new Map,this.#i=new Map,this.#w=new Map}increment(n,w=1){this.#n.set(n,(this.#n.get(n)??0)+w)}record(n,w){let i=this.#i.get(n);if(!i)i=new z(dn),this.#i.set(n,i);i.push(w)}gauge(n,w){this.#w.set(n,w)}snapshot(){let n={};for(let[w,i]of this.#n)n[w]={type:"counter",value:i};for(let[w,i]of this.#i){let S=i.toArray(),k=In(S);n[w]={type:"histogram",count:S.length,sum:Fn(S),p50:k[Math.floor(k.length*0.5)]??0,p99:k[Math.floor(k.length*0.99)]??0,min:k[0]??0,max:k[k.length-1]??0}}for(let[w,i]of this.#w)n[w]={type:"gauge",value:i};return n}reset(){this.#n.clear(),this.#i.clear(),this.#w.clear()}}function pn(n){let w;if(typeof n==="string")w=K().metrics.getMeter(n);else if(n)w=n;else w=K().metrics.getMeter("weft");return{workflowDuration:w.createHistogram("weft.workflow.duration",{unit:"ms"}),activityDuration:w.createHistogram("weft.activity.duration",{unit:"ms"}),activityAttempts:w.createCounter("weft.activity.attempts"),activeWorkflows:w.createUpDownCounter("weft.workflow.active")}}function In(n){let w=[...n];return w.sort((i,S)=>i-S),w}function Fn(n){let w=0;for(let i of n)w+=i;return w}function Ln(n,w){let i=w?.type==="histogram"?w.count:0,S=w?.type==="histogram"?w.sum:0;return[`# TYPE ${n} histogram`,`${n}_count ${i}`,`${n}_sum ${S}`]}function $n(n,w){let i=w?.type==="counter"?w.value:0;return[`# TYPE ${n} counter`,`${n}_total ${i}`]}function Gn(n,w){let i=w?.type==="gauge"?w.value:0;return[`# TYPE ${n} gauge`,`${n} ${i}`]}var on={histogram:Ln,counter:$n,gauge:Gn};function Kn(n,w){let i=n.name.replace(/\./g,"_"),S=w[n.name];return[`# HELP ${i} ${n.description}`,...on[n.type](i,S)]}function Cn(n){let w=n[X.dpmoDefects.name],i=n[X.dpmoOperations.name],S=w?.type==="counter"?w.value:0,k=i?.type==="counter"?i.value:0,f=k===0?0:S*1e6/k,y="weft_dpmo";return["# HELP weft_dpmo Defects per million operations (failed workflows / started workflows * 1e6)","# TYPE weft_dpmo gauge",`weft_dpmo ${f}`]}function b(n){let w=[];for(let i of Object.values(X))w.push(...Kn(i,n));return w.push(...Cn(n)),w.join(`
3
3
  `)+`
4
- `}function G0(S){return{serialize(){let W=S?.snapshot()??{};return m(W)}}}MS();var K0=3600000,RS=1e4,X0=3600000;function AS(S){let W=Date.now();for(let[$,x]of S.workflowSpans)if(W-x.createdAt>K0)x.span.end(),S.workflowSpans.delete($);if(S.workflowSpans.size>RS){let $=S.workflowSpans.size-RS,x=0;for(let[G,K]of S.workflowSpans){if(x>=$)break;K.span.end(),S.workflowSpans.delete(G),x++}}}function fS(S,W){let $=S.workflowSpans.get(W);if($)$.span.end(),S.workflowSpans.delete(W)}function DS(S){function W(X,P,Q){let j=S.workflowSpans.get(X);if(!j)return;if(P==="error")j.span.setStatus({code:S.SpanStatusCode.ERROR,...Q?{message:Q}:{}});else j.span.setStatus({code:S.SpanStatusCode.OK});j.span.end(),S.workflowSpans.delete(X)}let $=(X)=>{if(!(X instanceof Y))return;W(X.workflowId,"ok")},x=(X)=>{if(!(X instanceof Z))return;W(X.workflowId,"error",X.error.message),S.metrics.increment("weft.dpmo.defects")},G=(X)=>{if(!(X instanceof O))return;W(X.workflowId,"error","Workflow cancelled")},K=(X)=>{if(!(X instanceof B))return;W(X.workflowId,"error",`Workflow timed out (${X.timeoutType}) after ${X.elapsed}ms`),S.metrics.increment("weft.dpmo.defects")};if(S.eventTarget)S.eventTarget.addEventListener(Y.type,$),S.eventTarget.addEventListener(Z.type,x),S.eventTarget.addEventListener(O.type,G),S.eventTarget.addEventListener(B.type,K);function J(X=X0){let P=Date.now()-X,Q=0;for(let[j,b]of S.workflowSpans)if(b.createdAt<=P)b.span.setStatus({code:S.SpanStatusCode.ERROR,message:"span evicted (stale)"}),b.span.end(),S.workflowSpans.delete(j),Q++;return Q}function H(){if(S.eventTarget)S.eventTarget.removeEventListener(Y.type,$),S.eventTarget.removeEventListener(Z.type,x),S.eventTarget.removeEventListener(O.type,G),S.eventTarget.removeEventListener(B.type,K);for(let X of S.workflowSpans.values())X.span.setStatus({code:S.SpanStatusCode.ERROR,message:"Observability disposed"}),X.span.end();S.workflowSpans.clear()}return{endWorkflowSpan:W,evictStaleSpans:J,dispose:H}}function VS(S){return{workflowStart(W,$){AS(S);let x=S.workflowSpans.get(W.workflowId);if(x)x.span.setStatus({code:S.SpanStatusCode.OK}),fS(S,W.workflowId);let G=S.tracer.startSpan(`workflow:${W.workflowType}`,{attributes:{"weft.workflow.id":W.workflowId,"weft.workflow.type":W.workflowType}});if(S.workflowSpans.set(W.workflowId,{span:G,createdAt:Date.now()}),R(G,W.headers),S.recordPayloads&&W.input!==void 0)G.setAttribute("weft.payload.input",y(W.input,S.maxPayloadSize));U(S,G,W),S.metrics.increment("weft.workflow.started"),S.metrics.increment("weft.dpmo.operations"),$(W)},*activity(W,$){let x=S.tracer.startSpan(`activity:${W.activityName}`,{attributes:{"weft.activity.name":W.activityName,"weft.activity.attempt":W.attempt}},A(S,W.workflowId));if(R(x,W.headers),S.recordPayloads&&W.input!==void 0)x.setAttribute("weft.payload.input",y(W.input,S.maxPayloadSize));U(S,x,W);let G=Date.now();return yield*D(S,x,()=>$(W),()=>{S.metrics.record("weft.activity.duration",Date.now()-G),S.metrics.increment("weft.activity.attempts")})},*sleep(W,$){let x=S.tracer.startSpan("sleep",{attributes:{"weft.sleep.duration":W.duration}},A(S,W.workflowId));U(S,x,W),yield*D(S,x,()=>$(W))},*waitForSignal(W,$){let x=S.tracer.startSpan("waitForSignal",{attributes:{"weft.signal.name":W.signalName}},A(S,W.workflowId));return U(S,x,W),yield*D(S,x,()=>$(W))},async childWorkflow(W,$){let x=[],G=M(W.parentHeaders);if(G)x.push({context:{traceId:G.traceId,spanId:G.spanId,traceFlags:G.traceFlags}});let K=S.tracer.startSpan(`childWorkflow:${W.workflowType}`,{attributes:{"weft.child_workflow.type":W.workflowType,"weft.child_workflow.id":W.childWorkflowId,"weft.child_workflow.parent_id":W.workflowId},links:x},S.api.context.ROOT_CONTEXT);if(R(K,W.headers),S.recordPayloads&&W.input!==void 0)K.setAttribute("weft.payload.input",y(W.input,S.maxPayloadSize));return S.metrics.increment("weft.child_workflow.started"),f(S,K,()=>$(W))},signalReceived(W,$){let x=S.tracer.startSpan(`signal:received:${W.signalName}`,{attributes:{"weft.signal.name":W.signalName,"weft.signal.workflow_id":W.workflowId}});U(S,x,W),E(S,x,()=>$(W))}}}function J0(S){let{attributeExtractor:W,eventTarget:$,maxPayloadSize:x=v,metrics:G=new V,openTelemetryApi:K=T(),recordPayloads:J=!1,tracerName:H="weft",tracerVersion:X}=S??{},P=K,{trace:Q,SpanStatusCode:j}=P,b=Q.getTracer(H,X);return{api:P,trace:Q,SpanStatusCode:j,tracer:b,recordPayloads:J,maxPayloadSize:x,attributeExtractor:W,eventTarget:$,metrics:G,workflowSpans:new Map}}function xW(S){let W=J0(S),$=VS(W),x=h(W),G={...$,...x},K=DS(W);return{interceptor:G,metrics:W.metrics,...K}}export{m as serializeMetricsSnapshotForPrometheus,N as parseTraceParent,z as injectTraceParent,T as getOpenTelemetryApi,iS as generateTraceId,dS as generateSpanId,g as formatTraceParent,M as extractTraceParent,rS as createOpenTelemetryMetrics,xW as createObservabilityInterceptors,G0 as createMetricsCollectorExporter,V as MetricsCollector,_ as METRICS};
4
+ `}function An(n){return{serialize(){let w=n?.snapshot()??{};return b(w)}}}class I extends Event{static type="workflow:completed";workflowId;result;duration;constructor(n,w,i){super(I.type);this.workflowId=n,this.result=w,this.duration=i}}class F extends Event{static type="workflow:failed";workflowId;error;constructor(n,w){super(F.type);this.workflowId=n,this.error=w}}class L extends Event{static type="workflow:cancelled";workflowId;constructor(n){super(L.type);this.workflowId=n}}class $ extends Event{static type="workflow:timed-out";workflowId;timeoutType;elapsed;reason;constructor(n,w,i,S){super($.type);if(this.workflowId=n,this.timeoutType=w,this.elapsed=i,S!==void 0)this.reason=S}}var zn=new Set([I.type,F.type,L.type,$.type]);var Xn=3600000,E=1e4,Rn=3600000;function c(n){let w=Date.now();for(let[i,S]of n.workflowSpans)if(w-S.createdAt>Xn)S.span.end(),n.workflowSpans.delete(i);if(n.workflowSpans.size>E){let i=n.workflowSpans.size-E,S=0;for(let[k,f]of n.workflowSpans){if(S>=i)break;f.span.end(),n.workflowSpans.delete(k),S++}}}function N(n,w){let i=n.workflowSpans.get(w);if(i)i.span.end(),n.workflowSpans.delete(w)}function u(n){function w(v,G,W){let d=n.workflowSpans.get(v);if(!d)return;if(G==="error")d.span.setStatus({code:n.SpanStatusCode.ERROR,...W?{message:W}:{}});else d.span.setStatus({code:n.SpanStatusCode.OK});d.span.end(),n.workflowSpans.delete(v)}let i=(v)=>{if(!(v instanceof I))return;w(v.workflowId,"ok")},S=(v)=>{if(!(v instanceof F))return;w(v.workflowId,"error",v.error.message),n.metrics.increment("weft.dpmo.defects")},k=(v)=>{if(!(v instanceof L))return;w(v.workflowId,"error","Workflow cancelled")},f=(v)=>{if(!(v instanceof $))return;w(v.workflowId,"error",`Workflow timed out (${v.timeoutType}) after ${v.elapsed}ms`),n.metrics.increment("weft.dpmo.defects")};if(n.eventTarget)n.eventTarget.addEventListener(I.type,i),n.eventTarget.addEventListener(F.type,S),n.eventTarget.addEventListener(L.type,k),n.eventTarget.addEventListener($.type,f);function y(v=Rn){let G=Date.now()-v,W=0;for(let[d,R]of n.workflowSpans)if(R.createdAt<=G)R.span.setStatus({code:n.SpanStatusCode.ERROR,message:"span evicted (stale)"}),R.span.end(),n.workflowSpans.delete(d),W++;return W}function p(){if(n.eventTarget)n.eventTarget.removeEventListener(I.type,i),n.eventTarget.removeEventListener(F.type,S),n.eventTarget.removeEventListener(L.type,k),n.eventTarget.removeEventListener($.type,f);for(let v of n.workflowSpans.values())v.span.setStatus({code:n.SpanStatusCode.ERROR,message:"Observability disposed"}),v.span.end();n.workflowSpans.clear()}return{endWorkflowSpan:w,evictStaleSpans:y,dispose:p}}function m(n){return{workflowStart(w,i){c(n);let S=n.workflowSpans.get(w.workflowId);if(S)S.span.setStatus({code:n.SpanStatusCode.OK}),N(n,w.workflowId);let k=n.tracer.startSpan(`workflow:${w.workflowType}`,{attributes:{"weft.workflow.id":w.workflowId,"weft.workflow.type":w.workflowType}});if(n.workflowSpans.set(w.workflowId,{span:k,createdAt:Date.now()}),Q(k,w.headers),n.recordPayloads&&w.input!==void 0)k.setAttribute("weft.payload.input",C(w.input,n.maxPayloadSize));A(n,k,w),n.metrics.increment("weft.workflow.started"),n.metrics.increment("weft.dpmo.operations"),i(w)},*activity(w,i){let S=n.tracer.startSpan(`activity:${w.activityName}`,{attributes:{"weft.activity.name":w.activityName,"weft.activity.attempt":w.attempt}},j(n,w.workflowId));if(Q(S,w.headers),n.recordPayloads&&w.input!==void 0)S.setAttribute("weft.payload.input",C(w.input,n.maxPayloadSize));A(n,S,w);let k=Date.now();return yield*B(n,S,()=>i(w),()=>{n.metrics.record("weft.activity.duration",Date.now()-k),n.metrics.increment("weft.activity.attempts")})},*sleep(w,i){let S=n.tracer.startSpan("sleep",{attributes:{"weft.sleep.duration":w.duration}},j(n,w.workflowId));A(n,S,w),yield*B(n,S,()=>i(w))},*waitForSignal(w,i){let S=n.tracer.startSpan("waitForSignal",{attributes:{"weft.signal.name":w.signalName}},j(n,w.workflowId));return A(n,S,w),yield*B(n,S,()=>i(w))},async childWorkflow(w,i){let S=[],k=J(w.parentHeaders);if(k)S.push({context:{traceId:k.traceId,spanId:k.spanId,traceFlags:k.traceFlags}});let f=n.tracer.startSpan(`childWorkflow:${w.workflowType}`,{attributes:{"weft.child_workflow.type":w.workflowType,"weft.child_workflow.id":w.childWorkflowId,"weft.child_workflow.parent_id":w.workflowId},links:S},n.api.context.ROOT_CONTEXT);if(Q(f,w.headers),n.recordPayloads&&w.input!==void 0)f.setAttribute("weft.payload.input",C(w.input,n.maxPayloadSize));return n.metrics.increment("weft.child_workflow.started"),x(n,f,()=>i(w))},signalReceived(w,i){let S=n.tracer.startSpan(`signal:received:${w.signalName}`,{attributes:{"weft.signal.name":w.signalName,"weft.signal.workflow_id":w.workflowId}});A(n,S,w),_(n,S,()=>i(w))}}}function Tn(n){let{attributeExtractor:w,eventTarget:i,maxPayloadSize:S=O,metrics:k=new D,openTelemetryApi:f=K(),recordPayloads:y=!1,tracerName:p="weft",tracerVersion:v}=n??{},G=f,{trace:W,SpanStatusCode:d}=G,R=W.getTracer(p,v);return{api:G,trace:W,SpanStatusCode:d,tracer:R,recordPayloads:y,maxPayloadSize:S,attributeExtractor:w,eventTarget:i,metrics:k,workflowSpans:new Map}}function nw(n){let w=Tn(n),i=m(w),S=g(w),k={...i,...S},f=u(w);return{interceptor:k,metrics:w.metrics,...f}}export{b as serializeMetricsSnapshotForPrometheus,Z as parseTraceParent,U as injectTraceParent,K as getOpenTelemetryApi,fn as generateTraceId,vn as generateSpanId,M as formatTraceParent,J as extractTraceParent,pn as createOpenTelemetryMetrics,nw as createObservabilityInterceptors,An as createMetricsCollectorExporter,D as MetricsCollector,X as METRICS};
@@ -15,6 +15,15 @@ type PortableRuntimeTestOverrides = {
15
15
  document?: typeof globalThis.document | undefined;
16
16
  };
17
17
  export declare function setPortableRuntimeTestOverridesForTesting(overrides?: PortableRuntimeTestOverrides): void;
18
+ /**
19
+ * Whether the current runtime is Bun. Honors
20
+ * {@link setPortableRuntimeTestOverridesForTesting}, unlike a bare
21
+ * `typeof Bun !== 'undefined'` check, so callers that need to simulate a
22
+ * non-Bun runtime in tests (e.g. to exercise a Node or browser fallback
23
+ * branch) can do so without a real environment change.
24
+ * @internal
25
+ */
26
+ export declare function isBunRuntime(): boolean;
18
27
  /**
19
28
  * Detect the current JavaScript runtime.
20
29
  * Detection precedence is bun → node → browser → edge: a Bun process running
@@ -31,6 +40,16 @@ export declare function setPortableRuntimeTestOverridesForTesting(overrides?: Po
31
40
  * ```
32
41
  */
33
42
  export declare function detectRuntime(): RuntimeKind;
43
+ /**
44
+ * Read an environment variable without assuming a runtime.
45
+ *
46
+ * Prefers `Bun.env` under Bun, falls back to `process.env` under Node, and
47
+ * returns `undefined` anywhere else (browsers, edge runtimes) — where
48
+ * neither global exists and a bare `Bun.env[...]` or `process.env[...]`
49
+ * reference would throw a `ReferenceError`.
50
+ * @internal
51
+ */
52
+ export declare function readEnvironmentVariable(name: string): string | undefined;
34
53
  /**
35
54
  * Pause execution for the given number of milliseconds.
36
55
  *
@@ -85,6 +104,20 @@ export declare function hashBytes(data: Uint8Array): string;
85
104
  * ```
86
105
  */
87
106
  export declare function hashString(data: string): string;
107
+ /**
108
+ * Load a Node.js built-in module without a static `node:*` import.
109
+ *
110
+ * This package is ESM (`"type": "module"` in package.json), so `require`
111
+ * is not defined in Node runtime. `process.getBuiltinModule` (Node 22.5+,
112
+ * also implemented by Bun) is the correct way to load Node built-ins from
113
+ * ESM code without needing `createRequire` — and, crucially, without a
114
+ * static `import ... from 'node:*'` specifier that a browser bundler would
115
+ * try to resolve or stub. Returns `undefined` in the browser or any runtime
116
+ * lacking `process.getBuiltinModule`, so callers on a browser-reachable path
117
+ * must treat the result as optional rather than throwing at import time.
118
+ * @internal
119
+ */
120
+ export declare function tryLoadNodeBuiltin<T>(id: string): T | undefined;
88
121
  /**
89
122
  * Return the byte size of a file at the given path.
90
123
  *
@@ -2,8 +2,13 @@ let portableRuntimeTestOverrides;
2
2
  export function setPortableRuntimeTestOverridesForTesting(overrides) {
3
3
  portableRuntimeTestOverrides = overrides;
4
4
  }
5
- function isBunRuntime() {
6
- return typeof (portableRuntimeTestOverrides && "bun" in portableRuntimeTestOverrides ? portableRuntimeTestOverrides.bun : globalThis.Bun) < "u";
5
+ function getBunGlobal() {
6
+ if (portableRuntimeTestOverrides && "bun" in portableRuntimeTestOverrides)
7
+ return portableRuntimeTestOverrides.bun;
8
+ return globalThis.Bun;
9
+ }
10
+ export function isBunRuntime() {
11
+ return typeof getBunGlobal() < "u";
7
12
  }
8
13
  function getProcess() {
9
14
  if (portableRuntimeTestOverrides && "process" in portableRuntimeTestOverrides)
@@ -28,6 +33,12 @@ export function detectRuntime() {
28
33
  return detector.kind;
29
34
  return "edge";
30
35
  }
36
+ export function readEnvironmentVariable(name) {
37
+ const bun = getBunGlobal();
38
+ if (bun !== void 0)
39
+ return bun.env[name];
40
+ return getProcess()?.env?.[name];
41
+ }
31
42
  export function sleep(ms) {
32
43
  if (isBunRuntime())
33
44
  return Bun.sleep(ms);
@@ -49,7 +60,7 @@ export function hashBytes(data) {
49
60
  export function hashString(data) {
50
61
  return fnv1a64(textEncoder.encode(data));
51
62
  }
52
- function loadNodeBuiltin(id) {
63
+ export function tryLoadNodeBuiltin(id) {
53
64
  const getBuiltinModule = getProcess()?.getBuiltinModule;
54
65
  if (typeof getBuiltinModule !== "function")
55
66
  return;
@@ -58,7 +69,7 @@ function loadNodeBuiltin(id) {
58
69
  export function fileSize(path) {
59
70
  if (isBunRuntime())
60
71
  return Bun.file(path).size;
61
- const fs = loadNodeBuiltin("node:fs");
72
+ const fs = tryLoadNodeBuiltin("node:fs");
62
73
  if (!fs)
63
74
  throw Error("fileSize() requires Bun or Node 22.5+ (process.getBuiltinModule). Not available in browser or edge runtimes.");
64
75
  try {
@@ -70,7 +81,7 @@ export function fileSize(path) {
70
81
  }
71
82
  }
72
83
  function loadNodeZlib() {
73
- const zlib = loadNodeBuiltin("node:zlib");
84
+ const zlib = tryLoadNodeBuiltin("node:zlib");
74
85
  if (!zlib)
75
86
  throw Error("gzip/gunzip require Bun or Node 22.5+ (process.getBuiltinModule). " + "Not available in browser or edge runtimes \u2014 use CompressionStream directly.");
76
87
  return zlib;
@@ -86,5 +97,5 @@ export function gunzipSync(data) {
86
97
  return new Uint8Array(loadNodeZlib().gunzipSync(data));
87
98
  }
88
99
  export function tryLoadNodeZlib() {
89
- return loadNodeBuiltin("node:zlib");
100
+ return tryLoadNodeBuiltin("node:zlib");
90
101
  }
@@ -0,0 +1,92 @@
1
+ /**
2
+ * Canonical discovery-document metadata for operation access policies.
3
+ *
4
+ * @module server/access-policy-metadata
5
+ */
6
+ import { z } from 'zod';
7
+ import type { AccessPolicy } from './authorization.ts';
8
+ import type { ParameterizedAccessHint } from './operation-catalog/types.ts';
9
+ export declare const ScopeRequirementMetadataSchema: z.ZodObject<{
10
+ kind: z.ZodEnum<{
11
+ anyOf: "anyOf";
12
+ allOf: "allOf";
13
+ }>;
14
+ scopes: z.ZodArray<z.ZodString>;
15
+ }, z.core.$strict>;
16
+ export declare const AccessPolicyMetadataSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
17
+ kind: z.ZodLiteral<"public">;
18
+ }, z.core.$strict>, z.ZodObject<{
19
+ kind: z.ZodLiteral<"authenticated">;
20
+ }, z.core.$strict>, z.ZodObject<{
21
+ kind: z.ZodLiteral<"scoped">;
22
+ scopes: z.ZodObject<{
23
+ kind: z.ZodEnum<{
24
+ anyOf: "anyOf";
25
+ allOf: "allOf";
26
+ }>;
27
+ scopes: z.ZodArray<z.ZodString>;
28
+ }, z.core.$strict>;
29
+ }, z.core.$strict>, z.ZodObject<{
30
+ kind: z.ZodLiteral<"optionalAuth">;
31
+ authenticatedScopes: z.ZodObject<{
32
+ kind: z.ZodEnum<{
33
+ anyOf: "anyOf";
34
+ allOf: "allOf";
35
+ }>;
36
+ scopes: z.ZodArray<z.ZodString>;
37
+ }, z.core.$strict>;
38
+ }, z.core.$strict>, z.ZodObject<{
39
+ kind: z.ZodLiteral<"scopedAlternatives">;
40
+ alternatives: z.ZodArray<z.ZodObject<{
41
+ kind: z.ZodEnum<{
42
+ anyOf: "anyOf";
43
+ allOf: "allOf";
44
+ }>;
45
+ scopes: z.ZodArray<z.ZodString>;
46
+ }, z.core.$strict>>;
47
+ }, z.core.$strict>], "kind">;
48
+ export declare const ParameterizedAccessMetadataSchema: z.ZodObject<{
49
+ discriminator: z.ZodString;
50
+ defaultValue: z.ZodOptional<z.ZodString>;
51
+ variants: z.ZodArray<z.ZodObject<{
52
+ value: z.ZodString;
53
+ access: z.ZodDiscriminatedUnion<[z.ZodObject<{
54
+ kind: z.ZodLiteral<"public">;
55
+ }, z.core.$strict>, z.ZodObject<{
56
+ kind: z.ZodLiteral<"authenticated">;
57
+ }, z.core.$strict>, z.ZodObject<{
58
+ kind: z.ZodLiteral<"scoped">;
59
+ scopes: z.ZodObject<{
60
+ kind: z.ZodEnum<{
61
+ anyOf: "anyOf";
62
+ allOf: "allOf";
63
+ }>;
64
+ scopes: z.ZodArray<z.ZodString>;
65
+ }, z.core.$strict>;
66
+ }, z.core.$strict>, z.ZodObject<{
67
+ kind: z.ZodLiteral<"optionalAuth">;
68
+ authenticatedScopes: z.ZodObject<{
69
+ kind: z.ZodEnum<{
70
+ anyOf: "anyOf";
71
+ allOf: "allOf";
72
+ }>;
73
+ scopes: z.ZodArray<z.ZodString>;
74
+ }, z.core.$strict>;
75
+ }, z.core.$strict>, z.ZodObject<{
76
+ kind: z.ZodLiteral<"scopedAlternatives">;
77
+ alternatives: z.ZodArray<z.ZodObject<{
78
+ kind: z.ZodEnum<{
79
+ anyOf: "anyOf";
80
+ allOf: "allOf";
81
+ }>;
82
+ scopes: z.ZodArray<z.ZodString>;
83
+ }, z.core.$strict>>;
84
+ }, z.core.$strict>], "kind">;
85
+ }, z.core.$strict>>;
86
+ }, z.core.$strict>;
87
+ export type AccessPolicyMetadata = z.infer<typeof AccessPolicyMetadataSchema>;
88
+ export type ParameterizedAccessMetadata = z.infer<typeof ParameterizedAccessMetadataSchema>;
89
+ /** Serialize an operation's static access policy for discovery documents. */
90
+ export declare function serializeAccessPolicy(policy: AccessPolicy): AccessPolicyMetadata;
91
+ /** Serialize discriminator-specific access overrides for discovery documents. */
92
+ export declare function serializeParameterizedAccess(hint: ParameterizedAccessHint): ParameterizedAccessMetadata;
@@ -0,0 +1,78 @@
1
+ import { z } from "zod";
2
+ import { compareStrings } from "./json-schema-utilities.js";
3
+ export const ScopeRequirementMetadataSchema = z.strictObject({
4
+ kind: z.enum(["anyOf", "allOf"]),
5
+ scopes: z.array(z.string()).min(1)
6
+ }), AccessPolicyMetadataSchema = z.discriminatedUnion("kind", [
7
+ z.strictObject({ kind: z.literal("public") }),
8
+ z.strictObject({ kind: z.literal("authenticated") }),
9
+ z.strictObject({
10
+ kind: z.literal("scoped"),
11
+ scopes: ScopeRequirementMetadataSchema
12
+ }),
13
+ z.strictObject({
14
+ kind: z.literal("optionalAuth"),
15
+ authenticatedScopes: ScopeRequirementMetadataSchema
16
+ }),
17
+ z.strictObject({
18
+ kind: z.literal("scopedAlternatives"),
19
+ alternatives: z.array(ScopeRequirementMetadataSchema).min(1)
20
+ })
21
+ ]), ParameterizedAccessMetadataSchema = z.strictObject({
22
+ discriminator: z.string(),
23
+ defaultValue: z.string().optional(),
24
+ variants: z.array(z.strictObject({
25
+ value: z.string(),
26
+ access: AccessPolicyMetadataSchema
27
+ }))
28
+ });
29
+ export function serializeAccessPolicy(policy) {
30
+ switch (policy.kind) {
31
+ case "public":
32
+ return { kind: "public" };
33
+ case "authenticated":
34
+ return { kind: "authenticated" };
35
+ case "scoped":
36
+ return { kind: "scoped", scopes: serializeScopeRequirement(policy.scopes) };
37
+ case "optionalAuth":
38
+ return {
39
+ kind: "optionalAuth",
40
+ authenticatedScopes: serializeScopeRequirement(policy.authenticatedScopes)
41
+ };
42
+ case "scopedAlternatives":
43
+ return {
44
+ kind: "scopedAlternatives",
45
+ alternatives: policy.alternatives.map(serializeScopeRequirement)
46
+ };
47
+ default:
48
+ return unsupportedAccessPolicy(policy);
49
+ }
50
+ }
51
+ export function serializeParameterizedAccess(hint) {
52
+ return {
53
+ discriminator: hint.discriminator,
54
+ ...hint.defaultValue === void 0 ? {} : { defaultValue: hint.defaultValue },
55
+ variants: hint.variants.map((variant) => ({
56
+ value: variant.value,
57
+ access: serializeAccessPolicy(variant.access)
58
+ }))
59
+ };
60
+ }
61
+ function serializeScopeRequirement(requirement) {
62
+ switch (requirement.kind) {
63
+ case "anyOf":
64
+ case "allOf":
65
+ return {
66
+ kind: requirement.kind,
67
+ scopes: [...requirement.scopes].toSorted(compareStrings)
68
+ };
69
+ default:
70
+ return unsupportedScopeRequirement(requirement);
71
+ }
72
+ }
73
+ function unsupportedAccessPolicy(policy) {
74
+ throw Error(`cannot serialize unsupported access policy: ${String(policy)}`);
75
+ }
76
+ function unsupportedScopeRequirement(requirement) {
77
+ throw Error(`cannot serialize unsupported scope requirement: ${String(requirement)}`);
78
+ }
@@ -20,11 +20,30 @@
20
20
  *
21
21
  * @module server/engine-event-feed-backend
22
22
  */
23
- import type { Engine } from '../core/engine.ts';
23
+ import type { RegistryAgnosticEngine } from '../core/engine.ts';
24
24
  import { type WorkflowEventFeedBackend } from './workflow-event-feed.ts';
25
25
  /**
26
26
  * Build the production `WorkflowEventFeedBackend`. Call once per
27
27
  * engine instance and share the returned backend across every
28
- * transport that needs a feed.
28
+ * transport that needs a feed. Pass the result to `createWorkflowEventFeed()`
29
+ * to build a `WorkflowEventFeed` for `HandlerOptions.workflowEventFeed`.
30
+ *
31
+ * Accepts `RegistryAgnosticEngine` — the same registry-erased engine type
32
+ * `handleRequest()` and `ServeOptions.engine` accept — so a concretely
33
+ * narrowed engine from `Engine.create({ workflows })` works here without a
34
+ * call-site cast.
35
+ *
36
+ * @example
37
+ * ```ts
38
+ * import { Engine, MemoryStorage } from '@lostgradient/weft';
39
+ * import {
40
+ * createEngineEventFeedBackend,
41
+ * createWorkflowEventFeed,
42
+ * } from '@lostgradient/weft/server/handler';
43
+ *
44
+ * const engine = new Engine({ storage: new MemoryStorage() });
45
+ * const workflowEventFeed = createWorkflowEventFeed(createEngineEventFeedBackend(engine));
46
+ * void workflowEventFeed;
47
+ * ```
29
48
  */
30
- export declare function createEngineEventFeedBackend(engine: Engine): WorkflowEventFeedBackend;
49
+ export declare function createEngineEventFeedBackend(engine: RegistryAgnosticEngine): WorkflowEventFeedBackend;
@@ -2,13 +2,9 @@
2
2
  * `faultToHttpResponse` — pure mapper from a transport-neutral
3
3
  * `OperationFault` into a `Response` shaped for the REST surface.
4
4
  *
5
- * Body shape: `{ error: { code, message, data? } }`. The `code` matches the
6
- * fault discriminant verbatim so REST clients can switch on the same names
7
- * that JSON-RPC clients see in their `data.weftCode`.
8
- *
9
- * Pure: no engine, no I/O, no logging. Errors visible to clients are
10
- * exactly what the fault carries; internal `EngineFailure` detail belongs
11
- * in server logs, not the response body.
5
+ * This fallback uses the same flat, audited projection as every explicit REST
6
+ * binding. Keeping one mapper prevents a binding that omits `shapeFault` from
7
+ * accidentally exposing a broader nested payload or raw EngineFailure detail.
12
8
  */
13
9
  import { type OperationFault } from './operation-fault.ts';
14
10
  export declare function faultToHttpResponse(fault: OperationFault): Response;
@@ -1,36 +1,4 @@
1
- import { FAULT_CODE_TO_HTTP_STATUS } from "./operation-fault.js";
1
+ import { shapeRestFaultAsJson } from "./operation-fault.js";
2
2
  export function faultToHttpResponse(fault) {
3
- const status = FAULT_CODE_TO_HTTP_STATUS[fault.code], body = JSON.stringify({ error: shapeErrorBody(fault) }), headers = new Headers({ "content-type": "application/json; charset=utf-8" });
4
- return new Response(body, { status, headers });
5
- }
6
- function shapeErrorBody(fault) {
7
- const base = { code: fault.code, message: fault.message };
8
- if (fault.code === "EngineFailure" || fault.code === "NotImplemented")
9
- return base;
10
- if (fault.code === "Timeout")
11
- return shapeTimeoutBody(base, fault.data);
12
- if (fault.code === "NotFound")
13
- return shapeNotFoundBody(base, fault.data);
14
- return { ...base, data: fault.data };
15
- }
16
- function shapeTimeoutBody(base, data) {
17
- const defined = filterDefined(data);
18
- return Object.keys(defined).length === 0 ? base : { ...base, data: defined };
19
- }
20
- function shapeNotFoundBody(base, data) {
21
- const shaped = {
22
- resource: data.resource
23
- };
24
- if (data.identifier !== void 0)
25
- shaped.identifier = data.identifier;
26
- if (data.weftCode !== void 0)
27
- shaped.weftCode = data.weftCode;
28
- return { ...base, data: shaped };
29
- }
30
- function filterDefined(input) {
31
- const output = {};
32
- for (const [key, value] of Object.entries(input))
33
- if (value !== void 0)
34
- output[key] = value;
35
- return output;
3
+ return shapeRestFaultAsJson(fault);
36
4
  }
@@ -1,5 +1,20 @@
1
1
  import { type Storage } from '../storage/interface.ts';
2
2
  import { type Cursor, type FeedEventKind, type ReplayLiveSubscribeOptions, type WorkflowEventFeedOptions } from './workflow-event-feed.ts';
3
+ /**
4
+ * A single committed record from the fleet-wide event feed — cross-workflow
5
+ * lifecycle and system events, optionally scoped to one `workflowId`.
6
+ * Returned by `FleetEventFeed.replay()` / `FleetEventFeed.subscribe()`, and
7
+ * consumed directly by the `/v1/events/sse` REST route.
8
+ *
9
+ * @example
10
+ * ```ts
11
+ * import type { FleetEventEnvelope } from '@lostgradient/weft/server/handler';
12
+ *
13
+ * declare const envelope: FleetEventEnvelope;
14
+ * console.log(envelope.kind); // e.g. 'workflow:completed'
15
+ * console.log(envelope.workflowId); // string | undefined
16
+ * ```
17
+ */
3
18
  export type FleetEventEnvelope = {
4
19
  readonly kind: FeedEventKind;
5
20
  readonly workflowId?: string | undefined;
@@ -17,6 +32,23 @@ export type FleetEventInput = {
17
32
  export type FleetWorkflowEventInput = FleetEventInput & {
18
33
  readonly workflowId: string;
19
34
  };
35
+ /**
36
+ * The fleet-wide event feed: append cross-workflow events, replay committed
37
+ * history from a cursor, then subscribe for live delivery. This is the shape
38
+ * of `HandlerOptions.fleetEventFeed` — build a real one with
39
+ * `createFleetEventFeed()` to drive `/v1/events/sse` through `handleRequest()`
40
+ * without `serve()`.
41
+ *
42
+ * @example
43
+ * ```ts
44
+ * import { Engine, MemoryStorage } from '@lostgradient/weft';
45
+ * import { createFleetEventFeed, type FleetEventFeed } from '@lostgradient/weft/server/handler';
46
+ *
47
+ * const engine = new Engine({ storage: new MemoryStorage() });
48
+ * const fleetEventFeed: FleetEventFeed = createFleetEventFeed(engine.storage);
49
+ * void fleetEventFeed;
50
+ * ```
51
+ */
20
52
  export type FleetEventFeed = {
21
53
  append(event: FleetEventInput): Promise<FleetEventEnvelope>;
22
54
  appendWorkflowEventIfPresent(event: FleetWorkflowEventInput): Promise<FleetEventEnvelope | null>;
@@ -28,4 +60,37 @@ export type FleetEventFeed = {
28
60
  snapshotTailSequence(): Promise<number>;
29
61
  dispose(): void;
30
62
  };
63
+ /**
64
+ * Build a `FleetEventFeed` backed by the given `Storage` — typically
65
+ * `engine.storage`. Pass the result as `HandlerOptions.fleetEventFeed` to
66
+ * drive `/v1/events/sse` through `handleRequest()` directly, without
67
+ * `serve()`. Call once per storage instance and share the returned feed
68
+ * across every transport that needs it.
69
+ *
70
+ * **This feed does not subscribe to `Engine` events on its own.** `serve()`
71
+ * bridges engine lifecycle events into it via `wireEventBroadcasting()`; a
72
+ * direct `handleRequest()` host that skips `serve()` is responsible for
73
+ * calling `fleetEventFeed.append()` (or `appendWorkflowEventIfPresent()`)
74
+ * itself for whatever events it wants `/v1/events/sse` to carry — e.g. from
75
+ * `engine.addEventListener(...)` handlers wired up separately.
76
+ *
77
+ * @example
78
+ * ```ts
79
+ * import { Engine, MemoryStorage } from '@lostgradient/weft';
80
+ * import {
81
+ * createFleetEventFeed,
82
+ * handleRequest,
83
+ * type HandlerOptions,
84
+ * } from '@lostgradient/weft/server/handler';
85
+ *
86
+ * const engine = new Engine({ storage: new MemoryStorage() });
87
+ * const fleetEventFeed = createFleetEventFeed(engine.storage);
88
+ * const options: HandlerOptions = { fleetEventFeed };
89
+ *
90
+ * async function handleFleetEventsSse(request: Request): Promise<Response> {
91
+ * return handleRequest(request, engine, options);
92
+ * }
93
+ * void handleFleetEventsSse;
94
+ * ```
95
+ */
31
96
  export declare function createFleetEventFeed(storage: Storage, feedOptions?: WorkflowEventFeedOptions): FleetEventFeed;