brass-runtime 1.13.7 → 1.14.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 (37) hide show
  1. package/README.md +231 -55
  2. package/dist/agent/cli/main.cjs +43 -43
  3. package/dist/agent/cli/main.js +2 -2
  4. package/dist/agent/cli/main.mjs +2 -2
  5. package/dist/agent/index.cjs +3 -3
  6. package/dist/agent/index.d.ts +1 -1
  7. package/dist/agent/index.js +2 -2
  8. package/dist/agent/index.mjs +2 -2
  9. package/dist/chunk-4N2JEK4H.mjs +3897 -0
  10. package/dist/chunk-BKBFSOGT.cjs +3897 -0
  11. package/dist/{chunk-XNOTJSMZ.mjs → chunk-BMRF4FN6.js} +268 -8
  12. package/dist/chunk-JT7D6M5H.js +3897 -0
  13. package/dist/{chunk-3R7ZYRK2.mjs → chunk-MQF7HZ7Y.mjs} +1 -1
  14. package/dist/chunk-SKVY72E5.cjs +667 -0
  15. package/dist/{chunk-ATHSSDUF.js → chunk-UWMMYKVK.mjs} +268 -8
  16. package/dist/{chunk-INZBKOHY.js → chunk-WJESVBWN.js} +1 -1
  17. package/dist/{chunk-XDINDYNA.cjs → chunk-XTMZTVIT.cjs} +134 -134
  18. package/dist/{effect-ISvXPLgc.d.ts → effect-DM56H743.d.ts} +191 -21
  19. package/dist/http/index.cjs +808 -140
  20. package/dist/http/index.d.ts +181 -8
  21. package/dist/http/index.js +793 -125
  22. package/dist/http/index.mjs +793 -125
  23. package/dist/index.cjs +1785 -137
  24. package/dist/index.d.ts +979 -36
  25. package/dist/index.js +1675 -27
  26. package/dist/index.mjs +1675 -27
  27. package/dist/stream-Oqe6WeLE.d.ts +173 -0
  28. package/package.json +1 -1
  29. package/wasm/pkg/brass_runtime_wasm_engine.d.ts +95 -16
  30. package/wasm/pkg/brass_runtime_wasm_engine.js +715 -15
  31. package/wasm/pkg/brass_runtime_wasm_engine_bg.wasm +0 -0
  32. package/wasm/pkg/brass_runtime_wasm_engine_bg.wasm.d.ts +78 -7
  33. package/dist/chunk-2P4PD6D7.cjs +0 -2557
  34. package/dist/chunk-7F2R7A2V.mjs +0 -2557
  35. package/dist/chunk-L6KKKM66.js +0 -2557
  36. package/dist/chunk-ZTDK2DLG.cjs +0 -407
  37. package/dist/stream-BvukHxCv.d.ts +0 -66
@@ -1,15 +1,96 @@
1
- import { A as Async, a as AsyncWithPromise } from '../effect-ISvXPLgc.js';
2
- import { Z as ZStream } from '../stream-BvukHxCv.js';
1
+ import { A as Async, a as AsyncWithPromise } from '../effect-DM56H743.js';
2
+ import { Z as ZStream, C as CircuitBreakerConfig, T as Tracer } from '../stream-Oqe6WeLE.js';
3
3
 
4
4
  type RetryPolicy = {
5
5
  maxRetries: number;
6
6
  baseDelayMs: number;
7
7
  maxDelayMs: number;
8
+ /** Optional total retry budget, including request attempts and sleeps. */
9
+ maxElapsedMs?: number;
10
+ /** Defaults to true. When true, Retry-After is honored but capped by maxDelayMs/budget. */
11
+ respectRetryAfter?: boolean;
8
12
  retryOnMethods?: HttpMethod[];
9
13
  retryOnStatus?: (status: number) => boolean;
10
14
  retryOnError?: (e: HttpError) => boolean;
15
+ /** Strict engine selector for retry planning. Defaults to ts. */
16
+ engine?: "ts" | "wasm";
17
+ /** Back-compat knob: wasm=true maps to engine="wasm", wasm=false maps to engine="ts". */
18
+ wasm?: boolean;
11
19
  };
12
20
 
21
+ type HttpPoolKeyResolver = "global" | "origin" | "host" | ((req: HttpRequest, url: URL) => string);
22
+ type HttpPoolConfig = {
23
+ /** Max concurrent downstream calls per resolved key. */
24
+ readonly concurrency?: number;
25
+ /** Max queued waiters per key. `0` means fail fast when the pool is full. */
26
+ readonly maxQueue?: number;
27
+ /** Max time a request may wait for a pool slot before failing fast. */
28
+ readonly queueTimeoutMs?: number;
29
+ /** How to isolate pools. Default: `origin`; useful values: `global`, `host`, `origin`. */
30
+ readonly key?: HttpPoolKeyResolver;
31
+ /**
32
+ * Strict engine selector for permit governance. Defaults to ts.
33
+ * - ts: TypeScript permit pool.
34
+ * - wasm: require BrassWasmHttpPermitPool from wasm/pkg; never falls back.
35
+ */
36
+ readonly engine?: "ts" | "wasm";
37
+ /** Back-compat knob: wasm=true maps to engine="wasm", wasm=false maps to engine="ts". */
38
+ readonly wasm?: boolean;
39
+ };
40
+ type HttpPoolKeyStats = {
41
+ readonly key: string;
42
+ readonly running: number;
43
+ readonly queued: number;
44
+ readonly concurrency: number;
45
+ readonly maxQueue: number;
46
+ readonly acquired: number;
47
+ readonly released: number;
48
+ readonly rejected: number;
49
+ readonly queueTimeouts: number;
50
+ readonly abortedWhileQueued: number;
51
+ };
52
+ type HttpPoolStats = {
53
+ readonly running: number;
54
+ readonly queued: number;
55
+ readonly acquired: number;
56
+ readonly released: number;
57
+ readonly rejected: number;
58
+ readonly queueTimeouts: number;
59
+ readonly abortedWhileQueued: number;
60
+ readonly wasm?: unknown;
61
+ readonly keys: HttpPoolKeyStats[];
62
+ };
63
+ type HttpPoolLease = {
64
+ readonly key: string;
65
+ release: () => void;
66
+ };
67
+ declare function resolveHttpPoolKey(resolver: HttpPoolKeyResolver | undefined, req: HttpRequest, url: URL): string;
68
+ declare class HttpConcurrencyPool {
69
+ private readonly states;
70
+ private readonly concurrency;
71
+ private readonly maxQueue;
72
+ private readonly queueTimeoutMs;
73
+ readonly keyResolver: HttpPoolKeyResolver | undefined;
74
+ private readonly wasm;
75
+ private readonly wasmWaiters;
76
+ private wasmTimer;
77
+ private nextSubjectId;
78
+ constructor(config?: HttpPoolConfig);
79
+ acquire(key: string, signal: AbortSignal): Promise<HttpPoolLease>;
80
+ stats(): HttpPoolStats;
81
+ private acquireJs;
82
+ private acquireWasm;
83
+ private getState;
84
+ private makeLease;
85
+ private drain;
86
+ private handleWasmGrants;
87
+ private handleWasmTimeouts;
88
+ private scheduleWasmTimeoutPump;
89
+ private cleanupWaiter;
90
+ private removeWaiter;
91
+ private allocateSubjectId;
92
+ }
93
+
13
94
  type HttpError = {
14
95
  _tag: "Abort";
15
96
  } | {
@@ -18,6 +99,21 @@ type HttpError = {
18
99
  } | {
19
100
  _tag: "FetchError";
20
101
  message: string;
102
+ } | {
103
+ _tag: "Timeout";
104
+ timeoutMs: number;
105
+ message: string;
106
+ phase?: "request" | "queue" | "retry";
107
+ } | {
108
+ _tag: "PoolRejected";
109
+ key: string;
110
+ limit: number;
111
+ message: string;
112
+ } | {
113
+ _tag: "PoolTimeout";
114
+ key: string;
115
+ timeoutMs: number;
116
+ message: string;
21
117
  };
22
118
  type HttpMethod = "GET" | "POST" | "PUT" | "PATCH" | "DELETE" | "HEAD" | "OPTIONS";
23
119
  type HttpInit = Omit<RequestInit, "method" | "body" | "headers">;
@@ -27,6 +123,10 @@ type HttpRequest = {
27
123
  headers?: Record<string, string>;
28
124
  body?: string;
29
125
  init?: HttpInit;
126
+ /** Per-request override for `MakeHttpConfig.timeoutMs`. */
127
+ timeoutMs?: number;
128
+ /** Optional stable key for downstream isolation. When omitted, the pool uses origin/host/global config. */
129
+ poolKey?: string;
30
130
  };
31
131
  type HttpWireResponse = {
32
132
  status: number;
@@ -35,9 +135,25 @@ type HttpWireResponse = {
35
135
  bodyText: string;
36
136
  ms: number;
37
137
  };
138
+ type HttpClientStats = {
139
+ readonly inFlight: number;
140
+ readonly started: number;
141
+ readonly succeeded: number;
142
+ readonly failed: number;
143
+ readonly aborted: number;
144
+ readonly timedOut: number;
145
+ readonly poolRejected: number;
146
+ readonly poolTimeouts: number;
147
+ readonly lastDurationMs?: number;
148
+ readonly pool?: HttpPoolStats;
149
+ };
38
150
  type MakeHttpConfig = {
39
151
  baseUrl?: string;
40
152
  headers?: Record<string, string>;
153
+ /** Request budget covering pool wait + fetch + body read. Disabled when omitted. */
154
+ timeoutMs?: number;
155
+ /** Downstream pool/concurrency limiter. Disabled by default to preserve existing behavior. */
156
+ pool?: false | HttpPoolConfig;
41
157
  };
42
158
  type HttpWireResponseStream = {
43
159
  status: number;
@@ -46,20 +162,28 @@ type HttpWireResponseStream = {
46
162
  body: ZStream<unknown, HttpError, Uint8Array>;
47
163
  ms: number;
48
164
  };
49
- type HttpClientStream = (req: HttpRequest) => Async<unknown, HttpError, HttpWireResponseStream>;
165
+ type HttpClientStreamFn = (req: HttpRequest) => Async<unknown, HttpError, HttpWireResponseStream>;
166
+ type HttpClientStream = HttpClientStreamFn & {
167
+ stats: () => HttpClientStats;
168
+ };
169
+ type HttpClientFn = (req: HttpRequest) => Async<unknown, HttpError, HttpWireResponse>;
170
+ type HttpMiddleware = (next: HttpClientFn) => HttpClientFn;
50
171
  type HttpClient = HttpClientFn & {
51
172
  with: (mw: HttpMiddleware) => HttpClient;
173
+ stats: () => HttpClientStats;
52
174
  };
175
+ declare const decorate: (run: HttpClientFn, stats?: () => HttpClientStats) => HttpClient;
53
176
  declare const withMiddleware: (mw: HttpMiddleware) => (c: HttpClient) => HttpClient;
54
- declare const decorate: (run: HttpClientFn) => HttpClient;
55
- type HttpClientFn = (req: HttpRequest) => Async<unknown, HttpError, HttpWireResponse>;
56
- type HttpMiddleware = (next: HttpClientFn) => HttpClientFn;
57
177
  declare const normalizeHeadersInit: (h: any) => Record<string, string> | undefined;
58
178
  declare function makeHttpStream(cfg?: MakeHttpConfig): HttpClientStream;
59
179
  declare function makeHttp(cfg?: MakeHttpConfig): HttpClient;
60
180
  declare const withRetryStream: (p: RetryPolicy) => (next: HttpClientStream) => HttpClientStream;
61
181
 
62
- type InitNoMethodBody = Omit<RequestInit, "method" | "body">;
182
+ type InitNoMethodBody = Omit<RequestInit, "method" | "body"> & {
183
+ timeoutMs?: number;
184
+ poolKey?: string;
185
+ headers?: any;
186
+ };
63
187
  type HttpMeta = {
64
188
  request: HttpRequest;
65
189
  urlFinal: string;
@@ -83,6 +207,8 @@ type HttpResponseWithMeta<A> = {
83
207
  };
84
208
  type AnyInitWithHeaders = {
85
209
  headers?: any;
210
+ timeoutMs?: number;
211
+ poolKey?: string;
86
212
  } & Record<string, any>;
87
213
  type Dx = {
88
214
  request: (req: HttpRequest) => AsyncWithPromise<unknown, HttpError, HttpWireResponse>;
@@ -94,6 +220,7 @@ type Dx = {
94
220
  with: (mw: HttpMiddleware) => Dx;
95
221
  withRetry: (p: RetryPolicy) => Dx;
96
222
  wire: HttpClient;
223
+ stats: () => ReturnType<HttpClient["stats"]>;
97
224
  };
98
225
  declare function httpClient(cfg?: MakeHttpConfig): Dx;
99
226
  declare function httpClientWithMeta(cfg?: MakeHttpConfig): {
@@ -149,6 +276,52 @@ declare function httpClientStream(cfg?: MakeHttpConfig): {
149
276
  with: (mw: (n: HttpClientStream) => HttpClientStream) => /*elided*/ any;
150
277
  withRetry: (p: RetryPolicy) => /*elided*/ any;
151
278
  wire: HttpClientStream;
279
+ stats: () => HttpClientStats;
280
+ };
281
+
282
+ type HttpCircuitBreakerConfig = CircuitBreakerConfig & {
283
+ /** Key resolver for per-origin circuit breakers. Default: per-origin. */
284
+ perOrigin?: boolean;
285
+ };
286
+ /**
287
+ * HTTP middleware that wraps requests in a circuit breaker.
288
+ * When the circuit opens, requests fail fast with CircuitBreakerOpen error.
289
+ */
290
+ declare function withCircuitBreaker(config?: HttpCircuitBreakerConfig): HttpMiddleware;
291
+
292
+ /**
293
+ * HTTP middleware that creates a span for each request.
294
+ */
295
+ declare function withTracing(tracer: Tracer): HttpMiddleware;
296
+
297
+ type ValidationError = {
298
+ _tag: "ValidationError";
299
+ message: string;
300
+ body: string;
301
+ schema?: string;
302
+ };
303
+ type JsonValidator<A> = (data: unknown) => {
304
+ success: true;
305
+ data: A;
306
+ } | {
307
+ success: false;
308
+ error: string;
152
309
  };
310
+ /**
311
+ * Creates a validated JSON getter that checks the response body against a schema.
312
+ *
313
+ * Usage:
314
+ * ```ts
315
+ * const getUser = validatedJson<User>(client, (data) => {
316
+ * if (typeof data === "object" && data !== null && "id" in data) {
317
+ * return { success: true, data: data as User };
318
+ * }
319
+ * return { success: false, error: "Invalid user shape" };
320
+ * });
321
+ *
322
+ * const user = await run(getUser({ method: "GET", url: "/users/1" }));
323
+ * ```
324
+ */
325
+ declare function validatedJson<A>(client: HttpClientFn, validator: JsonValidator<A>): (req: Parameters<HttpClientFn>[0]) => Async<unknown, HttpError | ValidationError, A>;
153
326
 
154
- export { type Dx, type HttpClient, type HttpClientFn, type HttpClientStream, type HttpError, type HttpInit, type HttpMeta, type HttpMethod, type HttpMiddleware, type HttpRequest, type HttpResponse, type HttpResponseWithMeta, type HttpWireResponse, type HttpWireResponseStream, type HttpWireWithMeta, type MakeHttpConfig, decorate, httpClient, httpClientStream, httpClientWithMeta, makeHttp, makeHttpStream, normalizeHeadersInit, withMiddleware, withRetryStream };
327
+ export { type Dx, type HttpCircuitBreakerConfig, type HttpClient, type HttpClientFn, type HttpClientStats, type HttpClientStream, type HttpClientStreamFn, HttpConcurrencyPool, type HttpError, type HttpInit, type HttpMeta, type HttpMethod, type HttpMiddleware, type HttpPoolConfig, type HttpPoolKeyResolver, type HttpPoolKeyStats, type HttpPoolLease, type HttpPoolStats, type HttpRequest, type HttpResponse, type HttpResponseWithMeta, type HttpWireResponse, type HttpWireResponseStream, type HttpWireWithMeta, type JsonValidator, type MakeHttpConfig, type ValidationError, decorate, httpClient, httpClientStream, httpClientWithMeta, makeHttp, makeHttpStream, normalizeHeadersInit, resolveHttpPoolKey, validatedJson, withCircuitBreaker, withMiddleware, withRetryStream, withTracing };