brass-runtime 1.15.0 → 1.16.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 (93) hide show
  1. package/README.md +409 -137
  2. package/dist/agent/cli/main.cjs +40 -35
  3. package/dist/agent/cli/main.js +9 -4
  4. package/dist/agent/cli/main.mjs +9 -4
  5. package/dist/agent/index.cjs +8 -4
  6. package/dist/agent/index.d.ts +1 -1
  7. package/dist/agent/index.js +7 -3
  8. package/dist/agent/index.mjs +7 -3
  9. package/dist/{chunk-PPUXIH5R.js → chunk-2WC63LJK.mjs} +11 -7
  10. package/dist/chunk-3RG5ZIWI.js +10 -0
  11. package/dist/chunk-45F7OKGT.cjs +104 -0
  12. package/dist/chunk-5YOQOXEQ.cjs +2491 -0
  13. package/dist/{chunk-STVLQ3XD.cjs → chunk-7HUOJA4W.cjs} +78 -74
  14. package/dist/{chunk-BMH5AV44.js → chunk-7LVI2GIN.js} +251 -370
  15. package/dist/chunk-7TL2LHQJ.js +2491 -0
  16. package/dist/chunk-7V4KY4RL.mjs +104 -0
  17. package/dist/chunk-7XOPAB5Q.js +2143 -0
  18. package/dist/chunk-CCKHV5BT.mjs +193 -0
  19. package/dist/{chunk-AR22SXML.js → chunk-CY33PGEX.mjs} +488 -421
  20. package/dist/chunk-DJQ7OMMB.cjs +144 -0
  21. package/dist/chunk-F5EUMJL7.mjs +2143 -0
  22. package/dist/chunk-FM4W4QPL.js +193 -0
  23. package/dist/{chunk-TO7IKXYT.js → chunk-G3XGCZDQ.js} +1 -1
  24. package/dist/{chunk-BDF4AMWX.mjs → chunk-G6IQOE4P.mjs} +251 -370
  25. package/dist/chunk-GOV47PPB.mjs +552 -0
  26. package/dist/chunk-H55LI6WY.js +93 -0
  27. package/dist/chunk-IJT6RRQ5.cjs +93 -0
  28. package/dist/{chunk-ELOOF35R.mjs → chunk-J3H54ZRV.mjs} +1 -1
  29. package/dist/chunk-JF4XXPZ5.cjs +552 -0
  30. package/dist/chunk-JNFRRJYH.cjs +2143 -0
  31. package/dist/chunk-JX3LZQJH.cjs +354 -0
  32. package/dist/chunk-K2T3DV26.mjs +93 -0
  33. package/dist/chunk-KCPT2D6G.js +552 -0
  34. package/dist/chunk-MWXMNYJS.cjs +1110 -0
  35. package/dist/{chunk-VEZNF5GZ.cjs → chunk-N6VHMOWB.cjs} +130 -126
  36. package/dist/{chunk-3QMOKAS5.js → chunk-NC5SDRYE.js} +9 -5
  37. package/dist/chunk-NOYZIMUJ.mjs +144 -0
  38. package/dist/{chunk-R3R2FVLG.cjs → chunk-NYL4D7SK.cjs} +5 -5
  39. package/dist/chunk-OBGZSXTJ.cjs +10 -0
  40. package/dist/{chunk-4NHES7VK.mjs → chunk-OOGJ73B6.js} +11 -7
  41. package/dist/chunk-PNVFW245.js +144 -0
  42. package/dist/chunk-PRWCB3QL.mjs +2491 -0
  43. package/dist/{chunk-JFPU5GQI.mjs → chunk-QY5FKYEQ.js} +488 -421
  44. package/dist/chunk-ROJC3NBJ.js +104 -0
  45. package/dist/chunk-SPUEME2B.cjs +343 -0
  46. package/dist/chunk-TDVMADDN.js +343 -0
  47. package/dist/chunk-TVN5I4U6.cjs +193 -0
  48. package/dist/chunk-U5KWK3PX.mjs +343 -0
  49. package/dist/chunk-VFIUZG7J.mjs +354 -0
  50. package/dist/{chunk-TGIFUAK4.cjs → chunk-WQ5QNU5R.cjs} +459 -578
  51. package/dist/chunk-XDZOO4L5.js +354 -0
  52. package/dist/chunk-Y6FXYEAI.mjs +10 -0
  53. package/dist/{chunk-K6M7MDZ4.mjs → chunk-ZGLD4TVZ.mjs} +9 -5
  54. package/dist/client-CtFmoDvM.d.ts +645 -0
  55. package/dist/core/index.cjs +72 -4
  56. package/dist/core/index.d.ts +92 -198
  57. package/dist/core/index.js +106 -38
  58. package/dist/core/index.mjs +106 -38
  59. package/dist/{effect-CMOQKX8y.d.ts → effect-CGNl5Rqp.d.ts} +107 -1
  60. package/dist/effectRunner-3ZHAD3LE.cjs +8 -0
  61. package/dist/effectRunner-A4CHJXJI.js +8 -0
  62. package/dist/effectRunner-OPUF6QRN.mjs +8 -0
  63. package/dist/http/index.cjs +2189 -1271
  64. package/dist/http/index.d.ts +830 -270
  65. package/dist/http/index.js +2008 -1090
  66. package/dist/http/index.mjs +2008 -1090
  67. package/dist/http/testing.cjs +159 -0
  68. package/dist/http/testing.d.ts +42 -0
  69. package/dist/http/testing.js +159 -0
  70. package/dist/http/testing.mjs +159 -0
  71. package/dist/index.cjs +246 -178
  72. package/dist/index.d.ts +9 -35
  73. package/dist/index.js +120 -52
  74. package/dist/index.mjs +120 -52
  75. package/dist/observability/index.cjs +677 -0
  76. package/dist/observability/index.d.ts +79 -0
  77. package/dist/observability/index.js +677 -0
  78. package/dist/observability/index.mjs +677 -0
  79. package/dist/schedule-Fque9Abz.d.ts +70 -0
  80. package/dist/schema/index.cjs +25 -0
  81. package/dist/schema/index.d.ts +177 -0
  82. package/dist/schema/index.js +25 -0
  83. package/dist/schema/index.mjs +25 -0
  84. package/dist/server-C8hDXA74.d.ts +674 -0
  85. package/dist/{stream-FQm9h4Mg.d.ts → stream-dvSs0QS5.d.ts} +1 -1
  86. package/dist/tracer-B5tRH9H7.d.ts +230 -0
  87. package/dist/tracing-Dt9S_6V8.d.ts +148 -0
  88. package/package.json +27 -1
  89. package/dist/chunk-BDYEENHT.js +0 -224
  90. package/dist/chunk-MS34J5LY.cjs +0 -224
  91. package/dist/chunk-UMAZLXAB.mjs +0 -224
  92. package/dist/chunk-XPZNXSVN.cjs +0 -1043
  93. package/dist/tracing-DNT9jEbr.d.ts +0 -106
@@ -1,13 +1,12 @@
1
- "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; } var _class; var _class2; var _class3; var _class4; var _class5;
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { newObj[key] = obj[key]; } } } newObj.default = obj; return newObj; } } function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; } var _class; var _class2; var _class3;
2
2
 
3
- var _chunkSTVLQ3XDcjs = require('../chunk-STVLQ3XD.cjs');
3
+ var _chunkIJT6RRQ5cjs = require('../chunk-IJT6RRQ5.cjs');
4
4
 
5
5
 
6
6
 
7
- var _chunkMS34J5LYcjs = require('../chunk-MS34J5LY.cjs');
8
- require('../chunk-R3R2FVLG.cjs');
9
7
 
10
8
 
9
+ var _chunkJF4XXPZ5cjs = require('../chunk-JF4XXPZ5.cjs');
11
10
 
12
11
 
13
12
 
@@ -19,960 +18,210 @@ require('../chunk-R3R2FVLG.cjs');
19
18
 
20
19
 
21
20
 
22
- var _chunkTGIFUAK4cjs = require('../chunk-TGIFUAK4.cjs');
23
21
 
24
- // src/http/optics/lens.ts
25
- var Lens = {
26
- make(get, set) {
27
- return { get, set };
28
- },
29
- over(ln, f) {
30
- return (s) => ln.set(f(ln.get(s)))(s);
31
- },
32
- compose(ab, sa) {
33
- return Lens.make(
34
- (s) => ab.get(sa.get(s)),
35
- (b) => (s) => sa.set(ab.set(b)(sa.get(s)))(s)
36
- );
37
- }
38
- };
39
22
 
40
- // src/http/optics/request.ts
41
- var Request = {
42
- headers: Lens.make(
43
- (req) => _nullishCoalesce(req.headers, () => ( {})),
44
- (headers) => (req) => ({ ...req, headers })
45
- )
46
- };
47
- var mergeHeaders = (extra) => (req) => Lens.over(Request.headers, (h) => ({ ...h, ...extra }))(req);
48
- var mergeHeadersUnder = (under) => (req) => Lens.over(Request.headers, (h) => ({ ...under, ...h }))(req);
49
- var setHeaderIfMissing = (k, v) => (req) => Lens.over(Request.headers, (h) => h[k] ? h : { ...h, [k]: v })(req);
50
23
 
51
- // src/http/retry/wasmRetryPlanner.ts
52
- var WasmRetryPlannerBridge = class {
53
-
54
- constructor(Ctor) {
55
- this.planner = new Ctor();
56
- }
57
- start(options) {
58
- return this.planner.start(
59
- options.nowMs,
60
- options.maxRetries,
61
- options.baseDelayMs,
62
- options.maxDelayMs,
63
- _nullishCoalesce(options.maxElapsedMs, () => ( -1)),
64
- BigInt(this.seed())
65
- );
66
- }
67
- nextDelayMs(retryId, options) {
68
- const delay = this.planner.next_delay_ms(retryId, options.nowMs, options.retryable, _nullishCoalesce(options.retryAfterMs, () => ( -1)));
69
- return delay < 0 ? void 0 : delay;
70
- }
71
- drop(retryId) {
72
- this.planner.drop_state(retryId);
73
- }
74
- stats() {
75
- return {
76
- live: this.planner.metric_u64(0),
77
- planned: this.planner.metric_u64(1),
78
- exhausted: this.planner.metric_u64(2),
79
- dropped: this.planner.metric_u64(3)
80
- };
81
- }
82
- seed() {
83
- return Math.floor(Math.random() * Number.MAX_SAFE_INTEGER);
84
- }
85
- };
86
- function makeWasmRetryPlanner() {
87
- const mod = _chunkTGIFUAK4cjs.resolveWasmModule.call(void 0, );
88
- const Ctor = _optionalChain([mod, 'optionalAccess', _ => _.BrassWasmRetryPlanner]);
89
- if (!Ctor) throw new Error("brass-runtime wasm retry planner is not available. Run npm run build:wasm first.");
90
- return new WasmRetryPlannerBridge(Ctor);
91
- }
92
-
93
- // src/http/retry/retry.ts
94
- var defaultRetryableMethods = ["GET", "HEAD", "OPTIONS"];
95
- var defaultRetryOnStatus = (s) => s === 408 || s === 429 || s === 500 || s === 502 || s === 503 || s === 504;
96
- var defaultRetryOnError = (e) => e._tag === "FetchError" || e._tag === "Timeout" || e._tag === "PoolTimeout";
97
- var clamp = (n, min, max) => Math.max(min, Math.min(max, n));
98
- var backoffDelayMs = (attempt, base, cap) => {
99
- const b = Math.max(0, base);
100
- const c = Math.max(0, cap);
101
- const exp = b * Math.pow(2, attempt);
102
- const lim = clamp(exp, 0, c);
103
- return Math.floor(Math.random() * lim);
104
- };
105
- var headerCI = (h, name) => {
106
- const k = Object.keys(h).find((x) => x.toLowerCase() === name.toLowerCase());
107
- return k ? h[k] : void 0;
108
- };
109
- var retryAfterMs = (headers) => {
110
- const v = _optionalChain([headerCI, 'call', _2 => _2(headers, "retry-after"), 'optionalAccess', _3 => _3.trim, 'call', _4 => _4()]);
111
- if (!v) return void 0;
112
- const secs = Number(v);
113
- if (Number.isFinite(secs)) return Math.max(0, Math.floor(secs * 1e3));
114
- const t = Date.parse(v);
115
- if (Number.isFinite(t)) return Math.max(0, t - Date.now());
116
- return void 0;
117
- };
118
- var normalizeRetryBudget = (ms) => {
119
- if (ms === void 0 || !Number.isFinite(ms)) return void 0;
120
- return Math.max(0, Math.floor(ms));
121
- };
122
- var resolveEffectivePolicy = (req, basePolicy) => {
123
- const override = req.retry;
124
- if (override === false) return null;
125
- if (override === void 0) return basePolicy;
126
- return {
127
- ...basePolicy,
128
- ...override.maxRetries !== void 0 && { maxRetries: override.maxRetries },
129
- ...override.baseDelayMs !== void 0 && { baseDelayMs: override.baseDelayMs },
130
- ...override.maxDelayMs !== void 0 && { maxDelayMs: override.maxDelayMs },
131
- ...override.retryOnStatus !== void 0 && { retryOnStatus: override.retryOnStatus }
132
- };
133
- };
134
- var resolveRetryEngine = (p) => {
135
- if (p.engine !== void 0) {
136
- if (p.engine === "ts" || p.engine === "wasm") return p.engine;
137
- throw new Error(`brass-runtime retry engine must be 'ts' or 'wasm'; received '${String(p.engine)}'`);
138
- }
139
- if (p.wasm === true) return "wasm";
140
- if (p.wasm === false) return "ts";
141
- return "ts";
142
- };
143
- var withRetry = (p) => (next) => {
144
- const retryOnMethods = _nullishCoalesce(p.retryOnMethods, () => ( defaultRetryableMethods));
145
- const retryEngine = resolveRetryEngine(p);
146
- const wasmPlanner = retryEngine === "wasm" ? makeWasmRetryPlanner() : void 0;
147
- const isMethodRetryable = (req) => retryOnMethods.includes(req.method);
148
- const nextDelay = (ep, epMaxElapsedMs, retryId, attempt, startedAt, retryable, retryAfter) => {
149
- if (!retryable) return void 0;
150
- if (wasmPlanner && retryId !== void 0) {
151
- return wasmPlanner.nextDelayMs(retryId, {
152
- nowMs: performance.now(),
153
- retryable,
154
- retryAfterMs: retryAfter
155
- });
156
- }
157
- const remainingBudget = epMaxElapsedMs === void 0 ? Number.POSITIVE_INFINITY : epMaxElapsedMs - (performance.now() - startedAt);
158
- if (remainingBudget <= 0) return void 0;
159
- const rawDelay = retryAfter === void 0 ? backoffDelayMs(attempt, ep.baseDelayMs, ep.maxDelayMs) : Math.min(retryAfter, ep.maxDelayMs);
160
- return Math.max(0, Math.min(rawDelay, remainingBudget));
161
- };
162
- const sleepWithCleanup = (ms, onCancel) => {
163
- return _chunkTGIFUAK4cjs.asyncEffect.call(void 0, (_env, cb) => {
164
- const delay = Math.max(0, Math.floor(ms));
165
- const id = setTimeout(() => cb({ _tag: "Success", value: void 0 }), delay);
166
- return () => {
167
- clearTimeout(id);
168
- onCancel();
169
- };
170
- });
171
- };
172
- const loop = (req, attempt, startedAt, retryId, ep, epMaxElapsedMs, epRetryOnStatus, epRetryOnError, originalPriority, safeDrop) => {
173
- if (!isMethodRetryable(req)) return next(req);
174
- const effectiveReq = attempt > 0 ? (() => {
175
- const boostedReq = { ...req };
176
- boostedReq.priority = Math.max(0, originalPriority - 1);
177
- return boostedReq;
178
- })() : req;
179
- const remainingBudget = () => epMaxElapsedMs === void 0 ? Number.POSITIVE_INFINITY : epMaxElapsedMs - (performance.now() - startedAt);
180
- return _chunkTGIFUAK4cjs.asyncFold.call(void 0,
181
- next(effectiveReq),
182
- (e) => {
183
- if (e._tag === "Abort" || e._tag === "BadUrl" || e._tag === "PoolRejected" || e._tag === "CircuitBreakerOpen") {
184
- safeDrop(retryId);
185
- return _chunkTGIFUAK4cjs.asyncFail.call(void 0, e);
186
- }
187
- const retryable = attempt < ep.maxRetries && epRetryOnError(e) && remainingBudget() > 0;
188
- const d = nextDelay(ep, epMaxElapsedMs, retryId, attempt, startedAt, retryable);
189
- if (d === void 0 || d <= 0 && epMaxElapsedMs !== void 0) {
190
- safeDrop(retryId);
191
- return _chunkTGIFUAK4cjs.asyncFail.call(void 0, e);
192
- }
193
- if (ep.onRetry) {
194
- ep.onRetry({
195
- attempt,
196
- delayMs: d,
197
- error: e,
198
- status: void 0,
199
- url: req.url,
200
- method: req.method,
201
- timestamp: Date.now()
202
- });
203
- }
204
- return _chunkTGIFUAK4cjs.asyncFlatMap.call(void 0, sleepWithCleanup(d, () => safeDrop(retryId)), () => loop(req, attempt + 1, startedAt, retryId, ep, epMaxElapsedMs, epRetryOnStatus, epRetryOnError, originalPriority, safeDrop));
205
- },
206
- (w) => {
207
- const retryable = attempt < ep.maxRetries && epRetryOnStatus(w.status) && remainingBudget() > 0;
208
- const ra = ep.respectRetryAfter === false ? void 0 : retryAfterMs(w.headers);
209
- const d = nextDelay(ep, epMaxElapsedMs, retryId, attempt, startedAt, retryable, ra);
210
- if (d === void 0 || d <= 0 && epMaxElapsedMs !== void 0) {
211
- safeDrop(retryId);
212
- return _chunkTGIFUAK4cjs.asyncSucceed.call(void 0, w);
213
- }
214
- if (ep.onRetry) {
215
- ep.onRetry({
216
- attempt,
217
- delayMs: d,
218
- error: void 0,
219
- status: w.status,
220
- url: req.url,
221
- method: req.method,
222
- timestamp: Date.now()
223
- });
224
- }
225
- return _chunkTGIFUAK4cjs.asyncFlatMap.call(void 0, sleepWithCleanup(d, () => safeDrop(retryId)), () => loop(req, attempt + 1, startedAt, retryId, ep, epMaxElapsedMs, epRetryOnStatus, epRetryOnError, originalPriority, safeDrop));
226
- }
227
- );
228
- };
229
- return (req) => {
230
- const effectivePolicy = resolveEffectivePolicy(req, p);
231
- if (effectivePolicy === null) return next(req);
232
- if (!isMethodRetryable(req)) return next(req);
233
- const epRetryOnStatus = _nullishCoalesce(effectivePolicy.retryOnStatus, () => ( defaultRetryOnStatus));
234
- const epRetryOnError = _nullishCoalesce(effectivePolicy.retryOnError, () => ( defaultRetryOnError));
235
- const epMaxElapsedMs = normalizeRetryBudget(effectivePolicy.maxElapsedMs);
236
- const originalPriority = _nullishCoalesce(req.priority, () => ( 5));
237
- const startedAt = performance.now();
238
- const retryId = _optionalChain([wasmPlanner, 'optionalAccess', _5 => _5.start, 'call', _6 => _6({
239
- nowMs: startedAt,
240
- maxRetries: effectivePolicy.maxRetries,
241
- baseDelayMs: effectivePolicy.baseDelayMs,
242
- maxDelayMs: effectivePolicy.maxDelayMs,
243
- maxElapsedMs: epMaxElapsedMs
244
- })]);
245
- let plannerDropped = false;
246
- const safeDrop = (id) => {
247
- if (id !== void 0 && !plannerDropped) {
248
- plannerDropped = true;
249
- _optionalChain([wasmPlanner, 'optionalAccess', _7 => _7.drop, 'call', _8 => _8(id)]);
250
- }
251
- };
252
- return loop(req, 0, startedAt, retryId, effectivePolicy, epMaxElapsedMs, epRetryOnStatus, epRetryOnError, originalPriority, safeDrop);
253
- };
254
- };
255
24
 
256
- // src/http/wasmPermitPool.ts
257
- var DECISION_RUN_NOW = 0;
258
- var DECISION_QUEUED = 1;
259
- var WasmHttpPermitPoolBridge = (_class = class {
260
-
261
- __init() {this.keyCache = /* @__PURE__ */ new Map()}
262
- constructor(Ctor, options) {;_class.prototype.__init.call(this);
263
- this.pool = new Ctor(options.concurrency, options.maxQueue, toU64(options.queueTimeoutMs));
264
- }
265
- acquire(key, subjectId, nowMs = Date.now()) {
266
- const keyId = this.internKey(key);
267
- const decision = this.pool.acquire(subjectId, keyId, toU64(nowMs));
268
- const permitId = this.pool.last_permit_id();
269
- if (decision === DECISION_RUN_NOW) return { kind: "run", keyId, permitId };
270
- if (decision === DECISION_QUEUED) return { kind: "queued", keyId, permitId };
271
- return { kind: "rejected", keyId, permitId };
272
- }
273
- release(keyId, nowMs = Date.now()) {
274
- const ptr = this.pool.release(keyId, toU64(nowMs));
275
- return this.readEvents(ptr, this.pool.permit_events_len());
276
- }
277
- cancel(permitId) {
278
- this.pool.cancel(permitId);
279
- }
280
- advanceTime(nowMs = Date.now()) {
281
- const ptr = this.pool.advance_time(toU64(nowMs));
282
- return this.readEvents(ptr, this.pool.permit_events_len());
283
- }
284
- nextDeadlineMs() {
285
- return this.pool.next_deadline_ms();
286
- }
287
- stats() {
25
+
26
+
27
+
28
+
29
+
30
+
31
+
32
+
33
+
34
+
35
+
36
+
37
+
38
+
39
+ var _chunk5YOQOXEQcjs = require('../chunk-5YOQOXEQ.cjs');
40
+ require('../chunk-7HUOJA4W.cjs');
41
+ require('../chunk-45F7OKGT.cjs');
42
+
43
+
44
+
45
+
46
+ var _chunkJNFRRJYHcjs = require('../chunk-JNFRRJYH.cjs');
47
+ require('../chunk-JX3LZQJH.cjs');
48
+ require('../chunk-NYL4D7SK.cjs');
49
+ require('../chunk-TVN5I4U6.cjs');
50
+
51
+
52
+
53
+
54
+ var _chunkWQ5QNU5Rcjs = require('../chunk-WQ5QNU5R.cjs');
55
+
56
+
57
+
58
+
59
+
60
+
61
+
62
+
63
+
64
+ var _chunkDJQ7OMMBcjs = require('../chunk-DJQ7OMMB.cjs');
65
+
66
+
67
+
68
+
69
+
70
+
71
+
72
+
73
+
74
+
75
+
76
+ var _chunkSPUEME2Bcjs = require('../chunk-SPUEME2B.cjs');
77
+
78
+
79
+ var _chunkOBGZSXTJcjs = require('../chunk-OBGZSXTJ.cjs');
80
+
81
+ // src/http/validation.ts
82
+ function decodeJsonBody(bodyText, validator, options = {}) {
83
+ let parsed;
84
+ try {
85
+ parsed = JSON.parse(bodyText);
86
+ } catch (error) {
288
87
  return {
289
- running: this.pool.metric_u64(0),
290
- queued: this.pool.metric_u64(1),
291
- acquired: this.pool.metric_u64(2),
292
- released: this.pool.metric_u64(3),
293
- rejected: this.pool.metric_u64(4),
294
- queueTimeouts: this.pool.metric_u64(5),
295
- keys: this.pool.metric_u64(6)
296
- };
297
- }
298
- internKey(key) {
299
- const normalized = key.trim().slice(0, 160) || "global";
300
- let id = this.keyCache.get(normalized);
301
- if (id === void 0) {
302
- id = this.pool.intern_key(normalized);
303
- this.keyCache.set(normalized, id);
304
- }
305
- return id;
306
- }
307
- readEvents(ptr, len) {
308
- if (ptr === 0 || len <= 1) return [];
309
- const words = new Uint32Array(this.pool.memory().buffer, ptr, len);
310
- const count = words[0] >>> 0;
311
- const out = [];
312
- for (let i = 0; i < count; i++) {
313
- const base = 1 + i * 3;
314
- if (base + 2 >= words.length) break;
315
- out.push({
316
- subjectId: words[base] >>> 0,
317
- permitId: words[base + 1] >>> 0,
318
- keyId: words[base + 2] >>> 0
319
- });
320
- }
321
- return out;
322
- }
323
- }, _class);
324
- function makeWasmHttpPermitPool(options) {
325
- const mod = _chunkTGIFUAK4cjs.resolveWasmModule.call(void 0, );
326
- const Ctor = _optionalChain([mod, 'optionalAccess', _9 => _9.BrassWasmHttpPermitPool]);
327
- if (!Ctor) throw new Error("brass-runtime wasm HTTP permit pool is not available. Run npm run build:wasm first.");
328
- return new WasmHttpPermitPoolBridge(Ctor, options);
329
- }
330
- function toU64(value) {
331
- return BigInt(Math.max(0, Math.floor(value)));
332
- }
333
-
334
- // src/http/pool.ts
335
- var DEFAULT_CONCURRENCY = 64;
336
- var DEFAULT_MAX_QUEUE = 256;
337
- var clampInt = (n, fallback, min) => {
338
- if (n === void 0 || !Number.isFinite(n)) return fallback;
339
- return Math.max(min, Math.floor(n));
340
- };
341
- var queueTimeoutError = (key, timeoutMs) => ({
342
- _tag: "PoolTimeout",
343
- key,
344
- timeoutMs,
345
- message: `HTTP pool '${key}' did not grant a slot within ${timeoutMs}ms`
346
- });
347
- var poolRejectedError = (key, maxQueue) => ({
348
- _tag: "PoolRejected",
349
- key,
350
- limit: maxQueue,
351
- message: `HTTP pool '${key}' queue is full`
352
- });
353
- var abortError = () => ({ _tag: "Abort" });
354
- function resolveHttpPoolEngine(config) {
355
- if (config.engine !== void 0) {
356
- if (config.engine === "ts" || config.engine === "wasm") return config.engine;
357
- throw new Error(`brass-runtime HTTP pool engine must be 'ts' or 'wasm'; received '${String(config.engine)}'`);
358
- }
359
- if (config.wasm === true) return "wasm";
360
- if (config.wasm === false) return "ts";
361
- return "ts";
362
- }
363
- function resolveHttpPoolKey(resolver, req, url) {
364
- const custom = _optionalChain([req, 'access', _10 => _10.poolKey, 'optionalAccess', _11 => _11.trim, 'call', _12 => _12()]);
365
- if (custom) return custom.slice(0, 160);
366
- const r = _nullishCoalesce(resolver, () => ( "origin"));
367
- if (typeof r === "function") return r(req, url).trim().slice(0, 160) || "global";
368
- if (r === "global") return "global";
369
- if (r === "host") return url.host;
370
- return url.origin;
371
- }
372
- var HttpConcurrencyPool = (_class2 = class {
373
- __init2() {this.states = /* @__PURE__ */ new Map()}
374
-
375
-
376
-
377
-
378
-
379
- __init3() {this.wasmWaiters = /* @__PURE__ */ new Map()}
380
-
381
- __init4() {this.nextSubjectId = 1}
382
- constructor(config = {}) {;_class2.prototype.__init2.call(this);_class2.prototype.__init3.call(this);_class2.prototype.__init4.call(this);
383
- this.concurrency = clampInt(config.concurrency, DEFAULT_CONCURRENCY, 1);
384
- this.maxQueue = clampInt(config.maxQueue, DEFAULT_MAX_QUEUE, 0);
385
- this.queueTimeoutMs = config.queueTimeoutMs !== void 0 && Number.isFinite(config.queueTimeoutMs) ? Math.max(0, Math.floor(config.queueTimeoutMs)) : void 0;
386
- this.keyResolver = config.key;
387
- const engine = resolveHttpPoolEngine(config);
388
- this.wasm = engine === "wasm" ? makeWasmHttpPermitPool({
389
- concurrency: this.concurrency,
390
- maxQueue: this.maxQueue,
391
- queueTimeoutMs: _nullishCoalesce(this.queueTimeoutMs, () => ( 0))
392
- }) : void 0;
393
- }
394
- acquire(key, signal) {
395
- return this.wasm ? this.acquireWasm(key, signal) : this.acquireJs(key, signal);
396
- }
397
- stats() {
398
- const keys = Array.from(this.states.values()).map((state) => ({
399
- key: state.key,
400
- running: state.running,
401
- queued: state.queue.length,
402
- concurrency: this.concurrency,
403
- maxQueue: this.maxQueue,
404
- acquired: state.acquired,
405
- released: state.released,
406
- rejected: state.rejected,
407
- queueTimeouts: state.queueTimeouts,
408
- abortedWhileQueued: state.abortedWhileQueued
409
- })).sort((a, b) => b.running + b.queued - (a.running + a.queued) || a.key.localeCompare(b.key));
410
- return keys.reduce((acc, key) => ({
411
- running: acc.running + key.running,
412
- queued: acc.queued + key.queued,
413
- acquired: acc.acquired + key.acquired,
414
- released: acc.released + key.released,
415
- rejected: acc.rejected + key.rejected,
416
- queueTimeouts: acc.queueTimeouts + key.queueTimeouts,
417
- abortedWhileQueued: acc.abortedWhileQueued + key.abortedWhileQueued,
418
- wasm: _optionalChain([this, 'access', _13 => _13.wasm, 'optionalAccess', _14 => _14.stats, 'call', _15 => _15()]),
419
- keys: acc.keys.concat(key)
420
- }), {
421
- running: 0,
422
- queued: 0,
423
- acquired: 0,
424
- released: 0,
425
- rejected: 0,
426
- queueTimeouts: 0,
427
- abortedWhileQueued: 0,
428
- ...this.wasm ? { wasm: this.wasm.stats() } : {},
429
- keys: []
430
- });
431
- }
432
- acquireJs(key, signal) {
433
- const state = this.getState(key);
434
- if (signal.aborted) return Promise.reject(abortError());
435
- if (state.running < this.concurrency) {
436
- state.running++;
437
- state.acquired++;
438
- return Promise.resolve(this.makeLease(state));
439
- }
440
- if (state.queue.length >= this.maxQueue) {
441
- state.rejected++;
442
- return Promise.reject(poolRejectedError(key, this.maxQueue));
443
- }
444
- return new Promise((resolve, reject) => {
445
- const waiter = { signal, resolve, reject };
446
- const removeWaiter = () => this.removeWaiter(state, waiter);
447
- const cleanup = () => this.cleanupWaiter(waiter);
448
- waiter.abort = () => {
449
- cleanup();
450
- removeWaiter();
451
- state.abortedWhileQueued++;
452
- reject(abortError());
453
- };
454
- signal.addEventListener("abort", waiter.abort, { once: true });
455
- if (this.queueTimeoutMs !== void 0 && this.queueTimeoutMs > 0) {
456
- waiter.timer = setTimeout(() => {
457
- cleanup();
458
- removeWaiter();
459
- state.queueTimeouts++;
460
- reject(queueTimeoutError(key, this.queueTimeoutMs));
461
- }, this.queueTimeoutMs);
88
+ success: false,
89
+ error: {
90
+ _tag: "ValidationError",
91
+ message: `JSON parse error: ${error instanceof Error ? error.message : String(error)}`,
92
+ body: bodyText,
93
+ phase: "response",
94
+ schema: options.schemaName,
95
+ issues: [_chunkSPUEME2Bcjs.makeSchemaIssue.call(void 0, [], "valid JSON", bodyText, "Response body is not valid JSON")]
462
96
  }
463
- state.queue.push(waiter);
464
- });
465
- }
466
- acquireWasm(key, signal) {
467
- const wasm = this.wasm;
468
- const state = this.getState(key);
469
- if (signal.aborted) return Promise.reject(abortError());
470
- const subjectId = this.allocateSubjectId();
471
- const decision = wasm.acquire(key, subjectId);
472
- if (decision.kind === "run") {
473
- state.running++;
474
- state.acquired++;
475
- return Promise.resolve(this.makeLease(state, decision.keyId));
476
- }
477
- if (decision.kind === "rejected") {
478
- state.rejected++;
479
- return Promise.reject(poolRejectedError(key, this.maxQueue));
480
- }
481
- return new Promise((resolve, reject) => {
482
- const waiter = { signal, resolve, reject };
483
- const removeWaiter = () => this.removeWaiter(state, waiter);
484
- const cleanup = () => this.cleanupWaiter(waiter);
485
- waiter.abort = () => {
486
- cleanup();
487
- removeWaiter();
488
- wasm.cancel(decision.permitId);
489
- this.wasmWaiters.delete(decision.permitId);
490
- state.abortedWhileQueued++;
491
- reject(abortError());
492
- };
493
- signal.addEventListener("abort", waiter.abort, { once: true });
494
- state.queue.push(waiter);
495
- this.wasmWaiters.set(decision.permitId, { waiter, state, keyId: decision.keyId });
496
- this.scheduleWasmTimeoutPump();
497
- });
498
- }
499
- getState(key) {
500
- const k = key.trim().slice(0, 160) || "global";
501
- const existing = this.states.get(k);
502
- if (existing) return existing;
503
- const created = {
504
- key: k,
505
- running: 0,
506
- queue: [],
507
- acquired: 0,
508
- released: 0,
509
- rejected: 0,
510
- queueTimeouts: 0,
511
- abortedWhileQueued: 0
512
97
  };
513
- this.states.set(k, created);
514
- return created;
515
98
  }
516
- makeLease(state, wasmKeyId) {
517
- let released = false;
99
+ if (!validator) return { success: true, data: parsed };
100
+ let legacyMessage;
101
+ const validation = _chunkSPUEME2Bcjs.isSchema.call(void 0, validator) ? validator.safeParse(parsed) : (() => {
102
+ const result = validator(parsed);
103
+ if (result.success) return { success: true, data: result.data };
104
+ legacyMessage = result.error;
518
105
  return {
519
- key: state.key,
520
- release: () => {
521
- if (released) return;
522
- released = true;
523
- if (state.running > 0) state.running--;
524
- state.released++;
525
- if (this.wasm && wasmKeyId !== void 0) {
526
- this.handleWasmGrants(this.wasm.release(wasmKeyId));
527
- this.scheduleWasmTimeoutPump();
528
- return;
529
- }
530
- this.drain(state);
531
- }
106
+ success: false,
107
+ issues: _nullishCoalesce(result.issues, () => ( [_chunkSPUEME2Bcjs.makeSchemaIssue.call(void 0, [], "valid JSON shape", parsed, result.error)]))
532
108
  };
533
- }
534
- drain(state) {
535
- while (state.running < this.concurrency && state.queue.length > 0) {
536
- const waiter = state.queue.shift();
537
- this.cleanupWaiter(waiter);
538
- if (waiter.signal.aborted) {
539
- state.abortedWhileQueued++;
540
- waiter.reject(abortError());
541
- continue;
542
- }
543
- state.running++;
544
- state.acquired++;
545
- waiter.resolve(this.makeLease(state));
546
- }
547
- }
548
- handleWasmGrants(events) {
549
- for (const event of events) {
550
- const pending = this.wasmWaiters.get(event.permitId);
551
- if (!pending) continue;
552
- this.wasmWaiters.delete(event.permitId);
553
- this.cleanupWaiter(pending.waiter);
554
- this.removeWaiter(pending.state, pending.waiter);
555
- if (pending.waiter.signal.aborted) {
556
- pending.state.abortedWhileQueued++;
557
- pending.waiter.reject(abortError());
558
- continue;
559
- }
560
- pending.state.running++;
561
- pending.state.acquired++;
562
- pending.waiter.resolve(this.makeLease(pending.state, event.keyId));
563
- }
564
- }
565
- handleWasmTimeouts(events) {
566
- for (const event of events) {
567
- const pending = this.wasmWaiters.get(event.permitId);
568
- if (!pending) continue;
569
- this.wasmWaiters.delete(event.permitId);
570
- this.cleanupWaiter(pending.waiter);
571
- this.removeWaiter(pending.state, pending.waiter);
572
- pending.state.queueTimeouts++;
573
- pending.waiter.reject(queueTimeoutError(pending.state.key, _nullishCoalesce(this.queueTimeoutMs, () => ( 0))));
574
- }
575
- }
576
- scheduleWasmTimeoutPump() {
577
- if (!this.wasm) return;
578
- if (this.wasmTimer !== void 0) clearTimeout(this.wasmTimer);
579
- this.wasmTimer = void 0;
580
- const next = this.wasm.nextDeadlineMs();
581
- if (!Number.isFinite(next) || next < 0) return;
582
- const delay = Math.max(0, Math.min(2 ** 31 - 1, Math.floor(next - Date.now())));
583
- this.wasmTimer = setTimeout(() => {
584
- this.wasmTimer = void 0;
585
- if (!this.wasm) return;
586
- this.handleWasmTimeouts(this.wasm.advanceTime());
587
- this.scheduleWasmTimeoutPump();
588
- }, delay);
589
- if (typeof this.wasmTimer.unref === "function") this.wasmTimer.unref();
590
- }
591
- cleanupWaiter(waiter) {
592
- if (waiter.timer !== void 0) {
593
- clearTimeout(waiter.timer);
594
- waiter.timer = void 0;
109
+ })();
110
+ if (validation.success) return { success: true, data: validation.data };
111
+ return {
112
+ success: false,
113
+ error: {
114
+ _tag: "ValidationError",
115
+ message: _nullishCoalesce(legacyMessage, () => ( `JSON response failed validation: ${_chunkSPUEME2Bcjs.formatIssues.call(void 0, validation.issues)}`)),
116
+ body: bodyText,
117
+ phase: "response",
118
+ schema: options.schemaName,
119
+ issues: validation.issues
595
120
  }
596
- if (waiter.abort) {
597
- waiter.signal.removeEventListener("abort", waiter.abort);
598
- waiter.abort = void 0;
121
+ };
122
+ }
123
+ function encodeJsonBodyEffect(bodyObj, validator, options = {}) {
124
+ if (validator) {
125
+ const validation = _chunkSPUEME2Bcjs.validateValue.call(void 0, bodyObj, validator);
126
+ if (!validation.success) {
127
+ return _chunkDJQ7OMMBcjs.asyncFail.call(void 0, {
128
+ _tag: "ValidationError",
129
+ message: `JSON request body failed validation: ${_chunkSPUEME2Bcjs.formatIssues.call(void 0, validation.issues)}`,
130
+ body: previewJson(bodyObj),
131
+ phase: "request",
132
+ schema: options.schemaName,
133
+ issues: validation.issues
134
+ });
599
135
  }
600
136
  }
601
- removeWaiter(state, waiter) {
602
- const idx = state.queue.indexOf(waiter);
603
- if (idx >= 0) state.queue.splice(idx, 1);
604
- }
605
- allocateSubjectId() {
606
- const id = this.nextSubjectId >>> 0;
607
- this.nextSubjectId = this.nextSubjectId + 1 >>> 0;
608
- if (this.nextSubjectId === 0) this.nextSubjectId = 1;
609
- return id === 0 ? this.allocateSubjectId() : id;
610
- }
611
- }, _class2);
612
-
613
- // src/http/client.ts
614
- var emptyStats = () => ({
615
- inFlight: 0,
616
- started: 0,
617
- succeeded: 0,
618
- failed: 0,
619
- aborted: 0,
620
- timedOut: 0,
621
- poolRejected: 0,
622
- poolTimeouts: 0
623
- });
624
- var decorate = (run, stats = emptyStats) => Object.assign(((req) => run(req)), {
625
- with: (mw) => decorate(mw(run), stats),
626
- stats
627
- });
628
- var withMiddleware = (mw) => (c) => decorate(mw(c), c.stats);
629
- var decorateStream = (run, stats = emptyStats) => Object.assign(((req) => run(req)), { stats });
630
- var isTaggedHttpError = (e) => {
631
- if (typeof e !== "object" || e === null || !("_tag" in e)) return false;
632
- const tag = e._tag;
633
- return tag === "Abort" || tag === "BadUrl" || tag === "FetchError" || tag === "Timeout" || tag === "PoolRejected" || tag === "PoolTimeout";
634
- };
635
- var isAbortError = (e) => typeof e === "object" && e !== null && "name" in e && e.name === "AbortError";
636
- var normalizeHttpError = (e) => {
637
- if (isTaggedHttpError(e)) return e;
638
- if (isAbortError(e)) return { _tag: "Abort" };
639
- return { _tag: "FetchError", message: String(e) };
640
- };
641
- var normalizeHeadersInit = (h) => {
642
- if (!h) return void 0;
643
- if (typeof Headers !== "undefined" && h instanceof Headers) {
644
- const out = {};
645
- h.forEach((v, k) => out[k] = v);
646
- return out;
647
- }
648
- if (Array.isArray(h)) return Object.fromEntries(h);
649
- if (typeof h === "object") return { ...h };
650
- return void 0;
651
- };
652
- var normalizeRequest = (defaultHeaders) => (req0) => {
653
- let req = Object.keys(defaultHeaders).length ? mergeHeadersUnder(defaultHeaders)(req0) : req0;
654
- const initHeaders = normalizeHeadersInit(_optionalChain([req0, 'access', _16 => _16.init, 'optionalAccess', _17 => _17.headers]));
655
- if (initHeaders && Object.keys(initHeaders).length) {
656
- req = mergeHeadersUnder(initHeaders)(req);
137
+ try {
138
+ return _chunkDJQ7OMMBcjs.asyncSucceed.call(void 0, JSON.stringify(_nullishCoalesce(bodyObj, () => ( {}))));
139
+ } catch (error) {
140
+ return _chunkDJQ7OMMBcjs.asyncFail.call(void 0, {
141
+ _tag: "ValidationError",
142
+ message: `JSON request body could not be serialized: ${error instanceof Error ? error.message : String(error)}`,
143
+ body: "",
144
+ phase: "request",
145
+ schema: options.schemaName,
146
+ issues: [
147
+ _chunkSPUEME2Bcjs.makeSchemaIssue.call(void 0, [], "JSON-serializable value", bodyObj, "Request body could not be serialized to JSON")
148
+ ]
149
+ });
657
150
  }
658
- return req;
659
- };
660
- var resolvePositiveTimeout = (value) => {
661
- if (value === void 0 || !Number.isFinite(value)) return void 0;
662
- const n = Math.floor(value);
663
- return n > 0 ? n : void 0;
664
- };
665
- var makeHttpStats = (pool) => {
666
- const stats = {
667
- inFlight: 0,
668
- started: 0,
669
- succeeded: 0,
670
- failed: 0,
671
- aborted: 0,
672
- timedOut: 0,
673
- poolRejected: 0,
674
- poolTimeouts: 0
675
- };
676
- const onStart = () => {
677
- stats.inFlight++;
678
- stats.started++;
679
- };
680
- const onFinish = (finish) => {
681
- if (stats.inFlight > 0) stats.inFlight--;
682
- stats.lastDurationMs = finish.durationMs;
683
- if (finish.outcome === "success") {
684
- stats.succeeded++;
685
- return;
686
- }
687
- if (finish.outcome === "interrupt") {
688
- stats.aborted++;
689
- return;
690
- }
691
- if (finish.outcome === "timeout") {
692
- stats.timedOut++;
693
- return;
694
- }
695
- const err = normalizeHttpError(finish.error);
696
- switch (err._tag) {
697
- case "Abort":
698
- stats.aborted++;
699
- return;
700
- case "Timeout":
701
- stats.timedOut++;
702
- return;
703
- case "PoolRejected":
704
- stats.poolRejected++;
705
- stats.failed++;
706
- return;
707
- case "PoolTimeout":
708
- stats.poolTimeouts++;
709
- stats.failed++;
710
- return;
711
- default:
712
- stats.failed++;
713
- return;
714
- }
715
- };
716
- const snapshot = () => ({
717
- ...stats,
718
- ...pool ? { pool: pool.stats() } : {}
719
- });
720
- return { onStart, onFinish, snapshot };
721
- };
722
- var makePool = (cfg) => cfg.pool === void 0 || cfg.pool === false ? void 0 : new HttpConcurrencyPool(cfg.pool);
723
- var resolveRequestUrl = (req, baseUrl) => {
151
+ }
152
+ function decodeJsonBodyEffect(bodyText, validator, options) {
153
+ const result = decodeJsonBody(bodyText, validator, options);
154
+ return result.success ? _chunkDJQ7OMMBcjs.asyncSucceed.call(void 0, result.data) : _chunkDJQ7OMMBcjs.asyncFail.call(void 0, result.error);
155
+ }
156
+ function validatedJson(client, validator) {
157
+ return (req) => _chunkDJQ7OMMBcjs.asyncFold.call(void 0,
158
+ client(req),
159
+ (error) => _chunkDJQ7OMMBcjs.asyncFail.call(void 0, error),
160
+ (response) => decodeJsonBodyEffect(response.bodyText, validator)
161
+ );
162
+ }
163
+ function validatedJsonResponse(client, validator) {
164
+ return (req) => _chunkDJQ7OMMBcjs.asyncFold.call(void 0,
165
+ client(req),
166
+ (error) => _chunkDJQ7OMMBcjs.asyncFail.call(void 0, error),
167
+ (response) => _chunkDJQ7OMMBcjs.asyncFlatMap.call(void 0,
168
+ decodeJsonBodyEffect(response.bodyText, validator),
169
+ (body) => _chunkDJQ7OMMBcjs.asyncSucceed.call(void 0, { ...response, body })
170
+ )
171
+ );
172
+ }
173
+ function previewJson(value) {
724
174
  try {
725
- return new URL(req.url, baseUrl);
175
+ return JSON.stringify(value);
726
176
  } catch (e2) {
727
- return { _tag: "BadUrl", message: `URL inv\xE1lida: ${req.url}` };
177
+ return "[unserializable]";
728
178
  }
729
- };
730
- var headersOf = (res) => {
731
- const headers = {};
732
- res.headers.forEach((v, k) => headers[k] = v);
733
- return headers;
734
- };
735
- var fetchLabel = (req, url) => `http:${req.method}:${url.origin}`;
736
- var timeoutReason = (req, url, timeoutMs) => ({
737
- _tag: "Timeout",
738
- timeoutMs,
739
- phase: "request",
740
- message: `HTTP ${req.method} ${url.origin} timed out after ${timeoutMs}ms`
741
- });
742
- var linkAbortSignals = (runtimeSignal, requestSignal) => {
743
- if (!requestSignal) return { signal: runtimeSignal, cleanup: () => void 0 };
744
- const controller = new AbortController();
745
- const abort = (source) => {
746
- try {
747
- controller.abort(source.reason);
748
- } catch (e3) {
749
- controller.abort();
750
- }
751
- };
752
- const abortFromRuntime = () => abort(runtimeSignal);
753
- const abortFromRequest = () => abort(requestSignal);
754
- if (runtimeSignal.aborted) abortFromRuntime();
755
- else runtimeSignal.addEventListener("abort", abortFromRuntime, { once: true });
756
- if (requestSignal.aborted) abortFromRequest();
757
- else requestSignal.addEventListener("abort", abortFromRequest, { once: true });
758
- return {
759
- signal: controller.signal,
760
- cleanup: () => {
761
- runtimeSignal.removeEventListener("abort", abortFromRuntime);
762
- requestSignal.removeEventListener("abort", abortFromRequest);
763
- }
764
- };
765
- };
766
- function makeHttpStream(cfg = {}) {
767
- const baseUrl = _nullishCoalesce(cfg.baseUrl, () => ( ""));
768
- const defaultHeaders = _nullishCoalesce(cfg.headers, () => ( {}));
769
- const normalize = normalizeRequest(defaultHeaders);
770
- const pool = makePool(cfg);
771
- const metrics = makeHttpStats(pool);
772
- const run = (req0) => {
773
- const req = normalize(req0);
774
- const url = resolveRequestUrl(req, baseUrl);
775
- if (!(url instanceof URL)) return _chunkTGIFUAK4cjs.asyncFail.call(void 0, url);
776
- const timeoutMs = resolvePositiveTimeout(_nullishCoalesce(req.timeoutMs, () => ( cfg.timeoutMs)));
777
- return _chunkTGIFUAK4cjs.fromPromiseAbortable.call(void 0,
778
- async (signal) => {
779
- let lease;
780
- const linkedSignal = linkAbortSignals(signal, _optionalChain([req, 'access', _18 => _18.init, 'optionalAccess', _19 => _19.signal]));
781
- let cleanupTransferredToBody = false;
782
- try {
783
- if (pool) {
784
- const key = resolveHttpPoolKey(pool.keyResolver, req, url);
785
- lease = await pool.acquire(key, linkedSignal.signal);
786
- }
787
- const started = performance.now();
788
- const res = await fetch(url, {
789
- ..._nullishCoalesce(req.init, () => ( {})),
790
- method: req.method,
791
- headers: Request.headers.get(req),
792
- body: req.body,
793
- signal: linkedSignal.signal
794
- });
795
- const headers = headersOf(res);
796
- const body = _chunkSTVLQ3XDcjs.streamFromReadableStream.call(void 0, res.body, normalizeHttpError, {
797
- signal: linkedSignal.signal,
798
- onRelease: linkedSignal.cleanup
799
- });
800
- cleanupTransferredToBody = res.body !== null;
801
- _optionalChain([lease, 'optionalAccess', _20 => _20.release, 'call', _21 => _21()]);
802
- lease = void 0;
803
- return {
804
- status: res.status,
805
- statusText: res.statusText,
806
- headers,
807
- body,
808
- ms: Math.round(performance.now() - started)
809
- };
810
- } finally {
811
- if (!cleanupTransferredToBody) {
812
- linkedSignal.cleanup();
813
- }
814
- _optionalChain([lease, 'optionalAccess', _22 => _22.release, 'call', _23 => _23()]);
815
- }
816
- },
817
- normalizeHttpError,
818
- {
819
- label: fetchLabel(req, url),
820
- timeoutMs,
821
- timeoutReason: timeoutMs ? () => timeoutReason(req, url, timeoutMs) : void 0,
822
- onStart: metrics.onStart,
823
- onFinish: metrics.onFinish
824
- }
825
- );
826
- };
827
- return decorateStream(run, metrics.snapshot);
828
- }
829
- function makeHttp(cfg = {}) {
830
- const baseUrl = _nullishCoalesce(cfg.baseUrl, () => ( ""));
831
- const defaultHeaders = _nullishCoalesce(cfg.headers, () => ( {}));
832
- const normalize = normalizeRequest(defaultHeaders);
833
- const pool = makePool(cfg);
834
- const metrics = makeHttpStats(pool);
835
- const run = (req0) => {
836
- const req = normalize(req0);
837
- const url = resolveRequestUrl(req, baseUrl);
838
- if (!(url instanceof URL)) return _chunkTGIFUAK4cjs.asyncFail.call(void 0, url);
839
- const timeoutMs = resolvePositiveTimeout(_nullishCoalesce(req.timeoutMs, () => ( cfg.timeoutMs)));
840
- return _chunkTGIFUAK4cjs.fromPromiseAbortable.call(void 0,
841
- async (signal) => {
842
- let lease;
843
- const linkedSignal = linkAbortSignals(signal, _optionalChain([req, 'access', _24 => _24.init, 'optionalAccess', _25 => _25.signal]));
844
- try {
845
- if (pool) {
846
- const key = resolveHttpPoolKey(pool.keyResolver, req, url);
847
- lease = await pool.acquire(key, linkedSignal.signal);
848
- }
849
- const started = performance.now();
850
- const res = await fetch(url, {
851
- ..._nullishCoalesce(req.init, () => ( {})),
852
- method: req.method,
853
- headers: Request.headers.get(req),
854
- body: req.body,
855
- signal: linkedSignal.signal
856
- });
857
- const bodyText = await res.text();
858
- const headers = headersOf(res);
859
- return {
860
- status: res.status,
861
- statusText: res.statusText,
862
- headers,
863
- bodyText,
864
- ms: Math.round(performance.now() - started)
865
- };
866
- } finally {
867
- linkedSignal.cleanup();
868
- _optionalChain([lease, 'optionalAccess', _26 => _26.release, 'call', _27 => _27()]);
869
- }
870
- },
871
- normalizeHttpError,
872
- {
873
- label: fetchLabel(req, url),
874
- timeoutMs,
875
- timeoutReason: timeoutMs ? () => timeoutReason(req, url, timeoutMs) : void 0,
876
- onStart: metrics.onStart,
877
- onFinish: metrics.onFinish
878
- }
879
- );
880
- };
881
- return decorate(run, metrics.snapshot);
882
- }
883
- var withRetryStream = (p) => (next) => {
884
- const retryOnStatus = _nullishCoalesce(p.retryOnStatus, () => ( defaultRetryOnStatus));
885
- const retryOnError = _nullishCoalesce(p.retryOnError, () => ( defaultRetryOnError));
886
- const retryOnMethods = _nullishCoalesce(p.retryOnMethods, () => ( defaultRetryableMethods));
887
- const maxElapsedMs = normalizeRetryBudget(p.maxElapsedMs);
888
- const run = (req) => {
889
- if (!retryOnMethods.includes(req.method)) return next(req);
890
- const startedAt = performance.now();
891
- const remainingBudget = () => maxElapsedMs === void 0 ? Number.POSITIVE_INFINITY : maxElapsedMs - (performance.now() - startedAt);
892
- const delayWithinBudget = (delayMs) => Math.max(0, Math.min(delayMs, remainingBudget()));
893
- const loop = (attempt) => _chunkTGIFUAK4cjs.asyncFold.call(void 0,
894
- next(req),
895
- (e) => {
896
- if (e._tag === "Abort" || e._tag === "BadUrl" || e._tag === "PoolRejected") return _chunkTGIFUAK4cjs.asyncFail.call(void 0, e);
897
- const canRetry = attempt < p.maxRetries && retryOnError(e) && remainingBudget() > 0;
898
- if (!canRetry) return _chunkTGIFUAK4cjs.asyncFail.call(void 0, e);
899
- const d = delayWithinBudget(backoffDelayMs(attempt, p.baseDelayMs, p.maxDelayMs));
900
- if (d <= 0 && maxElapsedMs !== void 0) return _chunkTGIFUAK4cjs.asyncFail.call(void 0, e);
901
- _optionalChain([p, 'access', _28 => _28.onRetry, 'optionalCall', _29 => _29({
902
- attempt,
903
- delayMs: d,
904
- error: e,
905
- status: void 0,
906
- url: req.url,
907
- method: req.method,
908
- timestamp: Date.now()
909
- })]);
910
- return _chunkTGIFUAK4cjs.asyncFlatMap.call(void 0, _chunkMS34J5LYcjs.sleep.call(void 0, d), () => loop(attempt + 1));
911
- },
912
- (w) => {
913
- const canRetry = attempt < p.maxRetries && retryOnStatus(w.status) && remainingBudget() > 0;
914
- if (!canRetry) return _chunkTGIFUAK4cjs.asyncSucceed.call(void 0, w);
915
- const ra = p.respectRetryAfter === false ? void 0 : retryAfterMs(w.headers);
916
- const rawDelay = ra === void 0 ? backoffDelayMs(attempt, p.baseDelayMs, p.maxDelayMs) : Math.min(ra, p.maxDelayMs);
917
- const d = delayWithinBudget(rawDelay);
918
- if (d <= 0 && maxElapsedMs !== void 0) return _chunkTGIFUAK4cjs.asyncSucceed.call(void 0, w);
919
- _optionalChain([p, 'access', _30 => _30.onRetry, 'optionalCall', _31 => _31({
920
- attempt,
921
- delayMs: d,
922
- error: void 0,
923
- status: w.status,
924
- url: req.url,
925
- method: req.method,
926
- timestamp: Date.now()
927
- })]);
928
- return _chunkTGIFUAK4cjs.asyncFlatMap.call(void 0, _chunkMS34J5LYcjs.sleep.call(void 0, d), () => loop(attempt + 1));
929
- }
930
- );
931
- return loop(0);
932
- };
933
- return decorateStream(run, next.stats);
934
- };
179
+ }
935
180
 
936
181
  // src/http/httpClient.ts
937
182
  var resolveFinalUrl = (baseUrl, url) => {
938
183
  try {
939
184
  return new URL(url, _nullishCoalesce(baseUrl, () => ( ""))).toString();
940
- } catch (e4) {
185
+ } catch (e3) {
941
186
  return (_nullishCoalesce(baseUrl, () => ( ""))) + url;
942
187
  }
943
188
  };
944
189
  var createHttpCore = (cfg = {}) => {
945
- const wire = makeHttp(cfg);
946
- const withPromise = (eff) => _chunkTGIFUAK4cjs.withAsyncPromise.call(void 0, (e, env) => _chunkTGIFUAK4cjs.toPromise.call(void 0, e, env))(eff);
190
+ const wire = _chunk5YOQOXEQcjs.makeHttp.call(void 0, cfg);
191
+ const withPromise = (eff) => _chunkDJQ7OMMBcjs.withAsyncPromise.call(void 0, (e, env) => _chunkWQ5QNU5Rcjs.toPromise.call(void 0, e, env))(eff);
947
192
  const requestRaw = (req) => wire(req);
948
193
  const splitInit = (init) => {
949
- const { headers, timeoutMs, poolKey, ...rest } = _nullishCoalesce(init, () => ( {}));
194
+ const { headers, timeoutMs, poolKey, schema: schema2, schemaName, bodySchema, bodySchemaName, ...rest } = _nullishCoalesce(init, () => ( {}));
950
195
  return {
951
- headers: normalizeHeadersInit(headers),
196
+ headers: _chunk5YOQOXEQcjs.normalizeHeadersInit.call(void 0, headers),
952
197
  timeoutMs: typeof timeoutMs === "number" ? timeoutMs : void 0,
953
198
  poolKey: typeof poolKey === "string" ? poolKey : void 0,
954
199
  init: rest
955
200
  };
956
201
  };
957
- const applyInitHeaders = (headers) => (req) => headers ? mergeHeaders(headers)(req) : req;
958
- const buildReq = (method, url, init, body) => {
959
- const s = splitInit(init);
202
+ const applyInitHeaders = (headers) => (req) => headers ? _chunk5YOQOXEQcjs.mergeHeaders.call(void 0, headers)(req) : req;
203
+ const buildReq2 = (method, url, init, body) => {
204
+ const s2 = splitInit(init);
960
205
  const req = {
961
206
  method,
962
207
  url,
963
208
  ...body && body.length > 0 ? { body } : {},
964
- ...s.timeoutMs !== void 0 ? { timeoutMs: s.timeoutMs } : {},
965
- ...s.poolKey !== void 0 ? { poolKey: s.poolKey } : {},
966
- init: s.init
209
+ ...s2.timeoutMs !== void 0 ? { timeoutMs: s2.timeoutMs } : {},
210
+ ...s2.poolKey !== void 0 ? { poolKey: s2.poolKey } : {},
211
+ init: s2.init
967
212
  };
968
- return applyInitHeaders(s.headers)(req);
213
+ return applyInitHeaders(s2.headers)(req);
969
214
  };
970
- const toResponse = (w, body) => ({
215
+ const toResponse2 = (w, body) => ({
971
216
  status: w.status,
972
217
  statusText: w.statusText,
973
218
  headers: w.headers,
974
219
  body
975
220
  });
221
+ const decodeResponse2 = (w, validator, schemaName) => _chunkDJQ7OMMBcjs.asyncFlatMap.call(void 0,
222
+ decodeJsonBodyEffect(w.bodyText, validator, { schemaName }),
223
+ (body) => _chunkDJQ7OMMBcjs.asyncSucceed.call(void 0, toResponse2(w, body))
224
+ );
976
225
  return {
977
226
  cfg,
978
227
  wire,
@@ -980,8 +229,9 @@ var createHttpCore = (cfg = {}) => {
980
229
  requestRaw,
981
230
  splitInit,
982
231
  applyInitHeaders,
983
- buildReq,
984
- toResponse
232
+ buildReq: buildReq2,
233
+ toResponse: toResponse2,
234
+ decodeResponse: decodeResponse2
985
235
  };
986
236
  };
987
237
  function httpClient(cfg = {}) {
@@ -993,22 +243,27 @@ function httpClient(cfg = {}) {
993
243
  const post = (url, body, init) => request(core.buildReq("POST", url, init, body));
994
244
  const getText = (url, init) => {
995
245
  const req = core.buildReq("GET", url, init);
996
- return core.withPromise(_chunkTGIFUAK4cjs.mapTryAsync.call(void 0, requestRaw(req), (w) => core.toResponse(w, w.bodyText)));
246
+ return core.withPromise(_chunkDJQ7OMMBcjs.mapTryAsync.call(void 0, requestRaw(req), (w) => core.toResponse(w, w.bodyText)));
997
247
  };
998
- const getJson = (url, init) => {
248
+ const getJson = ((url, init) => {
999
249
  const base = core.buildReq("GET", url, init);
1000
- const req = setHeaderIfMissing("accept", "application/json")(base);
1001
- return core.withPromise(_chunkTGIFUAK4cjs.mapTryAsync.call(void 0, requestRaw(req), (w) => core.toResponse(w, JSON.parse(w.bodyText))));
1002
- };
1003
- const postJson = (url, bodyObj, init) => {
1004
- const base = core.buildReq("POST", url, init, JSON.stringify(_nullishCoalesce(bodyObj, () => ( {}))));
1005
- const req = setHeaderIfMissing("content-type", "application/json")(
1006
- setHeaderIfMissing("accept", "application/json")(base)
1007
- );
250
+ const req = _chunk5YOQOXEQcjs.setHeaderIfMissing.call(void 0, "accept", "application/json")(base);
251
+ return core.withPromise(_chunkDJQ7OMMBcjs.asyncFlatMap.call(void 0, requestRaw(req), (w) => core.decodeResponse(w, _optionalChain([init, 'optionalAccess', _ => _.schema]), _optionalChain([init, 'optionalAccess', _2 => _2.schemaName]))));
252
+ });
253
+ const postJson = ((url, bodyObj, init) => {
1008
254
  return core.withPromise(
1009
- _chunkTGIFUAK4cjs.mapTryAsync.call(void 0, requestRaw(req), (w) => core.toResponse(w, JSON.parse(w.bodyText)))
255
+ _chunkDJQ7OMMBcjs.asyncFlatMap.call(void 0,
256
+ encodeJsonBodyEffect(bodyObj, _optionalChain([init, 'optionalAccess', _3 => _3.bodySchema]), { schemaName: _optionalChain([init, 'optionalAccess', _4 => _4.bodySchemaName]) }),
257
+ (bodyText) => {
258
+ const base = core.buildReq("POST", url, init, bodyText);
259
+ const req = _chunk5YOQOXEQcjs.setHeaderIfMissing.call(void 0, "content-type", "application/json")(
260
+ _chunk5YOQOXEQcjs.setHeaderIfMissing.call(void 0, "accept", "application/json")(base)
261
+ );
262
+ return _chunkDJQ7OMMBcjs.asyncFlatMap.call(void 0, requestRaw(req), (w) => core.decodeResponse(w, _optionalChain([init, 'optionalAccess', _5 => _5.schema]), _optionalChain([init, 'optionalAccess', _6 => _6.schemaName])));
263
+ }
264
+ )
1010
265
  );
1011
- };
266
+ });
1012
267
  return {
1013
268
  request,
1014
269
  get,
@@ -1017,7 +272,7 @@ function httpClient(cfg = {}) {
1017
272
  getJson,
1018
273
  postJson,
1019
274
  with: (mw) => make(wire.with(mw)),
1020
- withRetry: (p) => make(wire.with(withRetry(p))),
275
+ withRetry: (p) => make(wire.with(_chunk5YOQOXEQcjs.withRetry.call(void 0, p))),
1021
276
  wire,
1022
277
  stats: () => wire.stats()
1023
278
  };
@@ -1035,7 +290,7 @@ function httpClientWithMeta(cfg = {}) {
1035
290
  const request = (req) => {
1036
291
  const startedAt = Date.now();
1037
292
  return core.withPromise(
1038
- _chunkTGIFUAK4cjs.mapTryAsync.call(void 0, core.requestRaw(req), (w) => ({
293
+ _chunkDJQ7OMMBcjs.mapTryAsync.call(void 0, core.requestRaw(req), (w) => ({
1039
294
  wire: w,
1040
295
  meta: mkMeta(req, w, startedAt)
1041
296
  }))
@@ -1050,24 +305,35 @@ function httpClientWithMeta(cfg = {}) {
1050
305
  return request(req);
1051
306
  };
1052
307
  const postJson = (url, bodyObj, init) => {
1053
- const base = core.buildReq("POST", url, init, JSON.stringify(_nullishCoalesce(bodyObj, () => ( {}))));
1054
- const req = setHeaderIfMissing("content-type", "application/json")(
1055
- setHeaderIfMissing("accept", "application/json")(base)
1056
- );
1057
308
  const startedAt = Date.now();
1058
309
  return core.withPromise(
1059
- _chunkTGIFUAK4cjs.mapTryAsync.call(void 0, core.requestRaw(req), (w) => ({
1060
- wire: w,
1061
- response: core.toResponse(w, JSON.parse(w.bodyText)),
1062
- meta: mkMeta(req, w, startedAt)
1063
- }))
310
+ _chunkDJQ7OMMBcjs.asyncFlatMap.call(void 0,
311
+ encodeJsonBodyEffect(bodyObj, _optionalChain([init, 'optionalAccess', _7 => _7.bodySchema]), { schemaName: _optionalChain([init, 'optionalAccess', _8 => _8.bodySchemaName]) }),
312
+ (bodyText) => {
313
+ const base = core.buildReq("POST", url, init, bodyText);
314
+ const req = _chunk5YOQOXEQcjs.setHeaderIfMissing.call(void 0, "content-type", "application/json")(
315
+ _chunk5YOQOXEQcjs.setHeaderIfMissing.call(void 0, "accept", "application/json")(base)
316
+ );
317
+ return _chunkDJQ7OMMBcjs.asyncFlatMap.call(void 0,
318
+ core.requestRaw(req),
319
+ (w) => _chunkDJQ7OMMBcjs.asyncFlatMap.call(void 0,
320
+ core.decodeResponse(w, _optionalChain([init, 'optionalAccess', _9 => _9.schema]), _optionalChain([init, 'optionalAccess', _10 => _10.schemaName])),
321
+ (response) => _chunkDJQ7OMMBcjs.asyncSucceed.call(void 0, {
322
+ wire: w,
323
+ response,
324
+ meta: mkMeta(req, w, startedAt)
325
+ })
326
+ )
327
+ );
328
+ }
329
+ )
1064
330
  );
1065
331
  };
1066
332
  const getText = (url, init) => {
1067
333
  const req = core.buildReq("GET", url, init);
1068
334
  const startedAt = Date.now();
1069
335
  return core.withPromise(
1070
- _chunkTGIFUAK4cjs.mapTryAsync.call(void 0, core.requestRaw(req), (w) => ({
336
+ _chunkDJQ7OMMBcjs.mapTryAsync.call(void 0, core.requestRaw(req), (w) => ({
1071
337
  wire: w,
1072
338
  response: core.toResponse(w, w.bodyText),
1073
339
  meta: mkMeta(req, w, startedAt)
@@ -1076,14 +342,20 @@ function httpClientWithMeta(cfg = {}) {
1076
342
  };
1077
343
  const getJson = (url, init) => {
1078
344
  const base = core.buildReq("GET", url, init);
1079
- const req = setHeaderIfMissing("accept", "application/json")(base);
345
+ const req = _chunk5YOQOXEQcjs.setHeaderIfMissing.call(void 0, "accept", "application/json")(base);
1080
346
  const startedAt = Date.now();
1081
347
  return core.withPromise(
1082
- _chunkTGIFUAK4cjs.mapTryAsync.call(void 0, core.requestRaw(req), (w) => ({
1083
- wire: w,
1084
- response: core.toResponse(w, JSON.parse(w.bodyText)),
1085
- meta: mkMeta(req, w, startedAt)
1086
- }))
348
+ _chunkDJQ7OMMBcjs.asyncFlatMap.call(void 0,
349
+ core.requestRaw(req),
350
+ (w) => _chunkDJQ7OMMBcjs.asyncFlatMap.call(void 0,
351
+ core.decodeResponse(w, _optionalChain([init, 'optionalAccess', _11 => _11.schema]), _optionalChain([init, 'optionalAccess', _12 => _12.schemaName])),
352
+ (response) => _chunkDJQ7OMMBcjs.asyncSucceed.call(void 0, {
353
+ wire: w,
354
+ response,
355
+ meta: mkMeta(req, w, startedAt)
356
+ })
357
+ )
358
+ )
1087
359
  );
1088
360
  };
1089
361
  return {
@@ -1102,13 +374,13 @@ function httpClientWithMeta(cfg = {}) {
1102
374
  };
1103
375
  }
1104
376
  function httpClientStream(cfg = {}) {
1105
- const wire = makeHttpStream(cfg);
377
+ const wire = _chunk5YOQOXEQcjs.makeHttpStream.call(void 0, cfg);
1106
378
  const make = (w) => {
1107
- const withPromise = (eff) => _chunkTGIFUAK4cjs.withAsyncPromise.call(void 0, (e, env) => _chunkTGIFUAK4cjs.toPromise.call(void 0, e, env))(eff);
379
+ const withPromise = (eff) => _chunkDJQ7OMMBcjs.withAsyncPromise.call(void 0, (e, env) => _chunkWQ5QNU5Rcjs.toPromise.call(void 0, e, env))(eff);
1108
380
  const request = (req) => withPromise(w(req));
1109
381
  const getStream = (url, init) => {
1110
382
  const base = { method: "GET", url, init };
1111
- const req = setHeaderIfMissing("accept", "*/*")(base);
383
+ const req = _chunk5YOQOXEQcjs.setHeaderIfMissing.call(void 0, "accept", "*/*")(base);
1112
384
  return request(req);
1113
385
  };
1114
386
  return {
@@ -1116,7 +388,7 @@ function httpClientStream(cfg = {}) {
1116
388
  getStream,
1117
389
  get: getStream,
1118
390
  with: (mw) => make(mw(w)),
1119
- withRetry: (p) => make(withRetryStream(p)(w)),
391
+ withRetry: (p) => make(_chunk5YOQOXEQcjs.withRetryStream.call(void 0, p)(w)),
1120
392
  wire: w,
1121
393
  stats: () => w.stats()
1122
394
  };
@@ -1124,137 +396,77 @@ function httpClientStream(cfg = {}) {
1124
396
  return make(wire);
1125
397
  }
1126
398
 
1127
- // src/http/effectRunner.ts
1128
- function registerHttpEffect(effect, env, cb) {
1129
- let done = false;
1130
- let currentCancel;
1131
- const finish = (exit) => {
1132
- if (done) return;
1133
- done = true;
1134
- currentCancel = void 0;
1135
- cb(exit);
1136
- };
1137
- const run = (current, cont) => {
1138
- if (done) return;
1139
- switch (current._tag) {
1140
- case "Succeed":
1141
- cont({ _tag: "Success", value: current.value });
1142
- return;
1143
- case "Fail":
1144
- cont({ _tag: "Failure", cause: _chunkTGIFUAK4cjs.Cause.fail(current.error) });
1145
- return;
1146
- case "Sync":
1147
- try {
1148
- cont({ _tag: "Success", value: current.thunk(env) });
1149
- } catch (e) {
1150
- cont({ _tag: "Failure", cause: _chunkTGIFUAK4cjs.Cause.die(e) });
1151
- }
1152
- return;
1153
- case "Async": {
1154
- const cancel = current.register(env, (exit) => {
1155
- currentCancel = void 0;
1156
- if (done) return;
1157
- cont(exit);
1158
- });
1159
- currentCancel = typeof cancel === "function" ? cancel : void 0;
1160
- return;
1161
- }
1162
- case "FlatMap":
1163
- run(current.first, (exit) => {
1164
- if (done) return;
1165
- if (exit._tag === "Failure") {
1166
- cont(exit);
1167
- return;
1168
- }
1169
- try {
1170
- run(current.andThen(exit.value), cont);
1171
- } catch (e) {
1172
- cont({ _tag: "Failure", cause: _chunkTGIFUAK4cjs.Cause.die(e) });
1173
- }
1174
- });
1175
- return;
1176
- case "Fold":
1177
- run(current.first, (exit) => {
1178
- if (done) return;
1179
- try {
1180
- if (exit._tag === "Success") {
1181
- run(current.onSuccess(exit.value), cont);
1182
- return;
1183
- }
1184
- if (exit.cause._tag === "Fail") {
1185
- run(current.onFailure(exit.cause.error), cont);
1186
- return;
1187
- }
1188
- cont(exit);
1189
- } catch (e) {
1190
- cont({ _tag: "Failure", cause: _chunkTGIFUAK4cjs.Cause.die(e) });
1191
- }
1192
- });
1193
- return;
1194
- case "Fork":
1195
- cont({ _tag: "Success", value: void 0 });
1196
- return;
1197
- }
1198
- };
1199
- run(effect, finish);
1200
- return () => {
1201
- if (done) return;
1202
- const cancel = currentCancel;
1203
- currentCancel = void 0;
1204
- done = true;
1205
- try {
1206
- _optionalChain([cancel, 'optionalCall', _32 => _32()]);
1207
- } finally {
1208
- cb({ _tag: "Failure", cause: _chunkTGIFUAK4cjs.Cause.interrupt() });
1209
- }
1210
- };
1211
- }
1212
-
1213
399
  // src/http/circuitBreaker.ts
1214
400
  function withCircuitBreaker(config = {}) {
1215
401
  if (config.perOrigin) {
1216
402
  const breakers = /* @__PURE__ */ new Map();
1217
- const getBreaker = (url) => {
403
+ const getBreaker = (url, onOpen) => {
1218
404
  try {
1219
405
  const origin = new URL(url).origin;
1220
406
  if (!breakers.has(origin)) {
1221
- breakers.set(origin, _chunkMS34J5LYcjs.makeCircuitBreaker.call(void 0, config));
407
+ breakers.set(origin, _chunkJF4XXPZ5cjs.makeCircuitBreaker.call(void 0, {
408
+ ...config,
409
+ onStateChange: (from, to) => {
410
+ _optionalChain([config, 'access', _13 => _13.onStateChange, 'optionalCall', _14 => _14(from, to)]);
411
+ if (to === "open") onOpen();
412
+ }
413
+ }));
1222
414
  }
1223
415
  return breakers.get(origin);
1224
- } catch (e5) {
416
+ } catch (e4) {
1225
417
  if (!breakers.has("__global__")) {
1226
- breakers.set("__global__", _chunkMS34J5LYcjs.makeCircuitBreaker.call(void 0, config));
418
+ breakers.set("__global__", _chunkJF4XXPZ5cjs.makeCircuitBreaker.call(void 0, {
419
+ ...config,
420
+ onStateChange: (from, to) => {
421
+ _optionalChain([config, 'access', _15 => _15.onStateChange, 'optionalCall', _16 => _16(from, to)]);
422
+ if (to === "open") onOpen();
423
+ }
424
+ }));
1227
425
  }
1228
426
  return breakers.get("__global__");
1229
427
  }
1230
428
  };
1231
429
  return (next) => (req) => {
1232
- const breaker2 = getBreaker(req.url);
1233
- return protectLazy(breaker2, next, req);
430
+ const limiter = resolveAdaptiveLimiter(config, next);
431
+ const limiterKey = resolveAdaptiveLimiterKey(config, limiter, req);
432
+ const onOpen = () => limiterKey !== void 0 && _optionalChain([limiter, 'optionalAccess', _17 => _17.markCircuitOpen, 'call', _18 => _18(limiterKey)]);
433
+ const breaker2 = getBreaker(req.url, onOpen);
434
+ return protectLazy(breaker2, next, req, onOpen);
1234
435
  };
1235
436
  }
1236
- const breaker = _chunkMS34J5LYcjs.makeCircuitBreaker.call(void 0, {
437
+ const breaker = _chunkJF4XXPZ5cjs.makeCircuitBreaker.call(void 0, {
1237
438
  ...config,
439
+ onStateChange: (from, to) => {
440
+ _optionalChain([config, 'access', _19 => _19.onStateChange, 'optionalCall', _20 => _20(from, to)]);
441
+ },
1238
442
  isFailure: _nullishCoalesce(config.isFailure, () => ( ((e) => {
1239
443
  const err = e;
1240
444
  return err._tag !== "BadUrl" && err._tag !== "Abort";
1241
445
  })))
1242
446
  });
1243
447
  return (next) => (req) => {
1244
- return protectLazy(breaker, next, req);
448
+ const limiter = resolveAdaptiveLimiter(config, next);
449
+ const limiterKey = resolveAdaptiveLimiterKey(config, limiter, req);
450
+ const onOpen = () => limiterKey !== void 0 && _optionalChain([limiter, 'optionalAccess', _21 => _21.markCircuitOpen, 'call', _22 => _22(limiterKey)]);
451
+ return protectLazy(breaker, next, req, onOpen);
1245
452
  };
1246
453
  }
1247
- function protectLazy(breaker, next, req) {
454
+ function protectLazy(breaker, next, req, onOpen) {
1248
455
  return {
1249
456
  _tag: "Async",
1250
457
  register: (env, cb) => {
1251
458
  let cancel;
1252
459
  try {
460
+ if (breaker.state() === "open") _optionalChain([onOpen, 'optionalCall', _23 => _23()]);
461
+ const finish = (exit) => {
462
+ if (breaker.state() === "open") _optionalChain([onOpen, 'optionalCall', _24 => _24()]);
463
+ cb(exit);
464
+ };
1253
465
  const deferred = {
1254
466
  _tag: "Async",
1255
- register: (innerEnv, innerCb) => registerHttpEffect(next(req), innerEnv, innerCb)
467
+ register: (innerEnv, innerCb) => _chunkIJT6RRQ5cjs.registerHttpEffect.call(void 0, next(req), innerEnv, innerCb)
1256
468
  };
1257
- cancel = registerHttpEffect(breaker.protect(deferred), env, cb);
469
+ cancel = _chunkIJT6RRQ5cjs.registerHttpEffect.call(void 0, breaker.protect(deferred), env, finish);
1258
470
  } catch (error) {
1259
471
  cb({
1260
472
  _tag: "Failure",
@@ -1264,10 +476,26 @@ function protectLazy(breaker, next, req) {
1264
476
  }
1265
477
  });
1266
478
  }
1267
- return () => _optionalChain([cancel, 'optionalCall', _33 => _33()]);
479
+ return () => _optionalChain([cancel, 'optionalCall', _25 => _25()]);
1268
480
  }
1269
481
  };
1270
482
  }
483
+ function resolveAdaptiveLimiter(config, next) {
484
+ return _nullishCoalesce(config.adaptiveLimiter, () => ( next.adaptiveLimiter));
485
+ }
486
+ function resolveAdaptiveLimiterKey(config, limiter, req) {
487
+ if (!limiter) return void 0;
488
+ if (config.adaptiveLimiterKey) return config.adaptiveLimiterKey(req);
489
+ if (req.poolKey) return req.poolKey;
490
+ if (limiter.keyResolver === "global") return "global";
491
+ try {
492
+ const url = new URL(req.url);
493
+ if (limiter.keyResolver === "host") return url.host;
494
+ return url.origin;
495
+ } catch (e5) {
496
+ return "global";
497
+ }
498
+ }
1271
499
 
1272
500
  // src/http/tracing.ts
1273
501
  function withTracing(tracer) {
@@ -1278,38 +506,69 @@ function withTracing(tracer) {
1278
506
  {
1279
507
  "http.method": req.method,
1280
508
  "http.url": req.url,
1281
- ..._optionalChain([req, 'access', _34 => _34.headers, 'optionalAccess', _35 => _35["content-type"]]) ? { "http.content_type": req.headers["content-type"] } : {}
509
+ ..._optionalChain([req, 'access', _26 => _26.headers, 'optionalAccess', _27 => _27["content-type"]]) ? { "http.content_type": req.headers["content-type"] } : {}
1282
510
  }
1283
511
  );
1284
512
  };
1285
513
  }
1286
514
 
1287
- // src/http/validation.ts
1288
- function validatedJson(client, validator) {
1289
- return (req) => _chunkTGIFUAK4cjs.asyncFold.call(void 0,
1290
- client(req),
1291
- (error) => _chunkTGIFUAK4cjs.asyncFail.call(void 0, error),
1292
- (response) => {
1293
- try {
1294
- const parsed = JSON.parse(response.bodyText);
1295
- const result = validator(parsed);
1296
- if (result.success) {
1297
- return _chunkTGIFUAK4cjs.asyncSucceed.call(void 0, result.data);
1298
- }
1299
- return _chunkTGIFUAK4cjs.asyncFail.call(void 0, {
1300
- _tag: "ValidationError",
1301
- message: result.error,
1302
- body: response.bodyText
1303
- });
1304
- } catch (e) {
1305
- return _chunkTGIFUAK4cjs.asyncFail.call(void 0, {
1306
- _tag: "ValidationError",
1307
- message: `JSON parse error: ${String(e)}`,
1308
- body: response.bodyText
1309
- });
1310
- }
1311
- }
1312
- );
515
+ // src/http/errors.ts
516
+ var HTTP_ERROR_TAGS = /* @__PURE__ */ new Set([
517
+ "Abort",
518
+ "BadUrl",
519
+ "FetchError",
520
+ "Timeout",
521
+ "PoolRejected",
522
+ "PoolTimeout",
523
+ "PoolClosed",
524
+ "BatchSplitError"
525
+ ]);
526
+ function isHttpError(error) {
527
+ return hasTag(error) && HTTP_ERROR_TAGS.has(error._tag);
528
+ }
529
+ function isValidationError(error) {
530
+ return hasTag(error) && error._tag === "ValidationError";
531
+ }
532
+ function isCircuitBreakerOpen(error) {
533
+ return hasTag(error) && error._tag === "CircuitBreakerOpen";
534
+ }
535
+ function isKnownHttpError(error) {
536
+ return isHttpError(error) || isValidationError(error) || isCircuitBreakerOpen(error);
537
+ }
538
+ function matchHttpError(error, handlers) {
539
+ if (isKnownHttpError(error)) {
540
+ const handler = handlers[error._tag];
541
+ if (handler) return handler(error);
542
+ }
543
+ return _optionalChain([handlers, 'access', _28 => _28.default, 'optionalCall', _29 => _29(error)]);
544
+ }
545
+ function formatHttpError(error) {
546
+ if (isValidationError(error)) {
547
+ const phase = error.phase ? `${error.phase} ` : "";
548
+ return `${phase}validation failed: ${error.message}`;
549
+ }
550
+ if (isCircuitBreakerOpen(error)) {
551
+ return `Circuit breaker is open after ${error.failures} failure(s)`;
552
+ }
553
+ if (!isHttpError(error)) {
554
+ return error instanceof Error ? error.message : String(error);
555
+ }
556
+ switch (error._tag) {
557
+ case "Abort":
558
+ return "HTTP request aborted";
559
+ case "BadUrl":
560
+ case "FetchError":
561
+ case "PoolRejected":
562
+ case "PoolTimeout":
563
+ case "PoolClosed":
564
+ case "BatchSplitError":
565
+ return error.message;
566
+ case "Timeout":
567
+ return error.message;
568
+ }
569
+ }
570
+ function hasTag(error) {
571
+ return typeof error === "object" && error !== null && typeof error._tag === "string";
1313
572
  }
1314
573
 
1315
574
  // src/http/body.ts
@@ -1394,8 +653,8 @@ function safeEmit(onEvent, event) {
1394
653
  }
1395
654
  function withDedup(config) {
1396
655
  const inFlight = /* @__PURE__ */ new Map();
1397
- const customKeyFn = _optionalChain([config, 'optionalAccess', _36 => _36.dedupKey]);
1398
- const onEvent = _optionalChain([config, 'optionalAccess', _37 => _37.onEvent]);
656
+ const customKeyFn = _optionalChain([config, 'optionalAccess', _30 => _30.dedupKey]);
657
+ const onEvent = _optionalChain([config, 'optionalAccess', _31 => _31.onEvent]);
1399
658
  return (next) => {
1400
659
  return (req) => {
1401
660
  if (!SAFE_METHODS.has(req.method.toUpperCase())) {
@@ -1432,7 +691,7 @@ function withDedup(config) {
1432
691
  finishCaller({ _tag: "Success", value: res });
1433
692
  },
1434
693
  reject: (err) => {
1435
- finishCaller({ _tag: "Failure", cause: _chunkTGIFUAK4cjs.Cause.fail(err) });
694
+ finishCaller({ _tag: "Failure", cause: _chunkDJQ7OMMBcjs.Cause.fail(err) });
1436
695
  }
1437
696
  };
1438
697
  existing.waiters.push(waiter);
@@ -1448,7 +707,7 @@ function withDedup(config) {
1448
707
  safeEmit(onEvent, { type: "dedup-active", active: inFlight.size });
1449
708
  existing.controller.abort();
1450
709
  }
1451
- finishCaller({ _tag: "Failure", cause: _chunkTGIFUAK4cjs.Cause.interrupt() });
710
+ finishCaller({ _tag: "Failure", cause: _chunkDJQ7OMMBcjs.Cause.interrupt() });
1452
711
  };
1453
712
  }
1454
713
  safeEmit(onEvent, { type: "dedup-miss", cacheKey: key });
@@ -1469,7 +728,7 @@ function withDedup(config) {
1469
728
  }
1470
729
  };
1471
730
  const innerEffect = next(dedupReq);
1472
- const innerCancel = registerHttpEffect(innerEffect, _env, (exit) => {
731
+ const innerCancel = _chunkIJT6RRQ5cjs.registerHttpEffect.call(void 0, innerEffect, _env, (exit) => {
1473
732
  inFlight.delete(key);
1474
733
  safeEmit(onEvent, { type: "dedup-active", active: inFlight.size });
1475
734
  if (exit._tag === "Success") {
@@ -1479,7 +738,7 @@ function withDedup(config) {
1479
738
  }
1480
739
  if (exit.cause._tag === "Interrupt") {
1481
740
  rejectAll(entry, { _tag: "Abort" });
1482
- finishCaller({ _tag: "Failure", cause: _chunkTGIFUAK4cjs.Cause.interrupt() });
741
+ finishCaller({ _tag: "Failure", cause: _chunkDJQ7OMMBcjs.Cause.interrupt() });
1483
742
  return;
1484
743
  }
1485
744
  if (exit.cause._tag === "Fail") {
@@ -1489,7 +748,7 @@ function withDedup(config) {
1489
748
  }
1490
749
  const err = { _tag: "FetchError", message: String(_nullishCoalesce(exit.cause.defect, () => ( "unknown"))) };
1491
750
  rejectAll(entry, err);
1492
- finishCaller({ _tag: "Failure", cause: _chunkTGIFUAK4cjs.Cause.fail(err) });
751
+ finishCaller({ _tag: "Failure", cause: _chunkDJQ7OMMBcjs.Cause.fail(err) });
1493
752
  });
1494
753
  return () => {
1495
754
  if (callerDone) return;
@@ -1502,7 +761,7 @@ function withDedup(config) {
1502
761
  innerCancel();
1503
762
  }
1504
763
  }
1505
- finishCaller({ _tag: "Failure", cause: _chunkTGIFUAK4cjs.Cause.interrupt() });
764
+ finishCaller({ _tag: "Failure", cause: _chunkDJQ7OMMBcjs.Cause.interrupt() });
1506
765
  };
1507
766
  }
1508
767
  };
@@ -1522,6 +781,186 @@ function rejectAll(entry, err) {
1522
781
  }
1523
782
  }
1524
783
 
784
+ // src/http/lifecycle/batch.ts
785
+ function clamp(value, min, max) {
786
+ if (!Number.isFinite(value)) return min;
787
+ return Math.max(min, Math.min(max, Math.floor(value)));
788
+ }
789
+ function safeEmitBatch(onEvent, event) {
790
+ if (!onEvent) return;
791
+ try {
792
+ onEvent(event);
793
+ } catch (e8) {
794
+ }
795
+ }
796
+ function withBatch(config, onEvent) {
797
+ const windowMs = clamp(config.windowMs, 1, 5e3);
798
+ const maxBatchSize = clamp(config.maxBatchSize, 2, 1e4);
799
+ const { batch, batchKey } = config;
800
+ const groups = /* @__PURE__ */ new Map();
801
+ return (next) => {
802
+ function dispatch(group) {
803
+ group.dispatched = true;
804
+ if (group.timer !== null) {
805
+ clearTimeout(group.timer);
806
+ group.timer = null;
807
+ }
808
+ groups.delete(group.key);
809
+ const requests = group.waiters.map((w) => w.request);
810
+ const waiterCount = group.waiters.length;
811
+ let coalescedReq;
812
+ try {
813
+ coalescedReq = batch.coalesce(requests);
814
+ } catch (err) {
815
+ const error = { _tag: "FetchError", message: String(err) };
816
+ rejectAllWaiters(group, error);
817
+ return;
818
+ }
819
+ coalescedReq = {
820
+ ...coalescedReq,
821
+ init: {
822
+ ..._nullishCoalesce(coalescedReq.init, () => ( {})),
823
+ signal: group.controller.signal
824
+ }
825
+ };
826
+ safeEmitBatch(onEvent, { type: "batch-dispatch", batchKey: group.key, batchSize: waiterCount });
827
+ const innerEffect = next(coalescedReq);
828
+ _chunkIJT6RRQ5cjs.registerHttpEffect.call(void 0, innerEffect, void 0, (exit) => {
829
+ if (exit._tag === "Success") {
830
+ let responses;
831
+ try {
832
+ responses = batch.split(exit.value, requests);
833
+ } catch (err2) {
834
+ const error = { _tag: "FetchError", message: String(err2) };
835
+ rejectAllWaiters(group, error);
836
+ return;
837
+ }
838
+ if (responses.length !== waiterCount) {
839
+ const error = {
840
+ _tag: "BatchSplitError",
841
+ expected: waiterCount,
842
+ actual: responses.length,
843
+ message: `split returned ${responses.length} responses but expected ${waiterCount}`
844
+ };
845
+ rejectAllWaiters(group, error);
846
+ return;
847
+ }
848
+ const waiters = group.waiters.slice();
849
+ for (let i = 0; i < waiters.length; i++) {
850
+ waiters[i].resolve(responses[i]);
851
+ }
852
+ return;
853
+ }
854
+ if (exit.cause._tag === "Fail") {
855
+ rejectAllWaiters(group, exit.cause.error);
856
+ return;
857
+ }
858
+ if (exit.cause._tag === "Interrupt") {
859
+ rejectAllWaiters(group, { _tag: "Abort" });
860
+ return;
861
+ }
862
+ const err = { _tag: "FetchError", message: String(_nullishCoalesce(exit.cause.defect, () => ( "unknown"))) };
863
+ rejectAllWaiters(group, err);
864
+ });
865
+ }
866
+ return (req) => {
867
+ let key;
868
+ try {
869
+ key = batchKey(req);
870
+ } catch (e9) {
871
+ return next(req);
872
+ }
873
+ if (!key) {
874
+ return next(req);
875
+ }
876
+ return {
877
+ _tag: "Async",
878
+ register: (_env, cb) => {
879
+ let callerDone = false;
880
+ const finishCaller = (exit) => {
881
+ if (callerDone) return;
882
+ callerDone = true;
883
+ cb(exit);
884
+ };
885
+ const waiter = {
886
+ request: req,
887
+ resolve: (res) => {
888
+ finishCaller({ _tag: "Success", value: res });
889
+ },
890
+ reject: (err) => {
891
+ finishCaller({ _tag: "Failure", cause: _chunkDJQ7OMMBcjs.Cause.fail(err) });
892
+ }
893
+ };
894
+ const existing = groups.get(key);
895
+ if (existing && !existing.dispatched) {
896
+ existing.waiters.push(waiter);
897
+ safeEmitBatch(onEvent, { type: "batch-hit", batchKey: key });
898
+ if (existing.waiters.length >= maxBatchSize) {
899
+ dispatch(existing);
900
+ }
901
+ return () => {
902
+ if (callerDone) return;
903
+ const idx = existing.waiters.indexOf(waiter);
904
+ if (idx >= 0) {
905
+ existing.waiters.splice(idx, 1);
906
+ }
907
+ if (existing.waiters.length === 0 && !existing.dispatched) {
908
+ if (existing.timer !== null) {
909
+ clearTimeout(existing.timer);
910
+ existing.timer = null;
911
+ }
912
+ groups.delete(key);
913
+ }
914
+ if (existing.waiters.length === 0 && existing.dispatched) {
915
+ existing.controller.abort();
916
+ }
917
+ finishCaller({ _tag: "Failure", cause: _chunkDJQ7OMMBcjs.Cause.interrupt() });
918
+ };
919
+ }
920
+ const controller = new AbortController();
921
+ const group = {
922
+ key,
923
+ controller,
924
+ waiters: [waiter],
925
+ timer: null,
926
+ dispatched: false
927
+ };
928
+ group.timer = setTimeout(() => {
929
+ if (!group.dispatched && group.waiters.length > 0) {
930
+ dispatch(group);
931
+ }
932
+ }, windowMs);
933
+ groups.set(key, group);
934
+ return () => {
935
+ if (callerDone) return;
936
+ const idx = group.waiters.indexOf(waiter);
937
+ if (idx >= 0) {
938
+ group.waiters.splice(idx, 1);
939
+ }
940
+ if (group.waiters.length === 0 && !group.dispatched) {
941
+ if (group.timer !== null) {
942
+ clearTimeout(group.timer);
943
+ group.timer = null;
944
+ }
945
+ groups.delete(key);
946
+ }
947
+ if (group.waiters.length === 0 && group.dispatched) {
948
+ group.controller.abort();
949
+ }
950
+ finishCaller({ _tag: "Failure", cause: _chunkDJQ7OMMBcjs.Cause.interrupt() });
951
+ };
952
+ }
953
+ };
954
+ };
955
+ };
956
+ }
957
+ function rejectAllWaiters(group, err) {
958
+ const waiters = group.waiters.slice();
959
+ for (const w of waiters) {
960
+ w.reject(err);
961
+ }
962
+ }
963
+
1525
964
  // src/http/lifecycle/timing.ts
1526
965
  var now = typeof performance !== "undefined" && typeof performance.now === "function" ? () => performance.now() : () => Date.now();
1527
966
 
@@ -1529,10 +968,10 @@ var now = typeof performance !== "undefined" && typeof performance.now === "func
1529
968
  function isExpired(node) {
1530
969
  return now() - node.storedAt >= node.ttlMs;
1531
970
  }
1532
- var LRUCache = (_class3 = class {
1533
- __init5() {this.map = /* @__PURE__ */ new Map()}
1534
- __init6() {this.head = null}
1535
- __init7() {this.tail = null}
971
+ var LRUCache = (_class = class {
972
+ __init() {this.map = /* @__PURE__ */ new Map()}
973
+ __init2() {this.head = null}
974
+ __init3() {this.tail = null}
1536
975
 
1537
976
 
1538
977
  /**
@@ -1549,7 +988,7 @@ var LRUCache = (_class3 = class {
1549
988
  * const cache = new LRUCache<number>({ maxEntries: 50 });
1550
989
  * ```
1551
990
  */
1552
- constructor(config = {}) {;_class3.prototype.__init5.call(this);_class3.prototype.__init6.call(this);_class3.prototype.__init7.call(this);
991
+ constructor(config = {}) {;_class.prototype.__init.call(this);_class.prototype.__init2.call(this);_class.prototype.__init3.call(this);
1553
992
  const max = _nullishCoalesce(config.maxEntries, () => ( 1024));
1554
993
  this.maxEntries = Math.max(1, Math.floor(max));
1555
994
  this.onEvict = config.onEvict;
@@ -1731,7 +1170,7 @@ var LRUCache = (_class3 = class {
1731
1170
  this.onEvict(1);
1732
1171
  }
1733
1172
  }
1734
- }, _class3);
1173
+ }, _class);
1735
1174
 
1736
1175
  // src/http/lifecycle/responseCache.ts
1737
1176
  function clamp2(n, min, max) {
@@ -1741,22 +1180,22 @@ function safeEmit2(onEvent, event) {
1741
1180
  if (!onEvent) return;
1742
1181
  try {
1743
1182
  onEvent(event);
1744
- } catch (e8) {
1183
+ } catch (e10) {
1745
1184
  }
1746
1185
  }
1747
1186
  function withCache(config) {
1748
- const ttlSeconds = clamp2(_nullishCoalesce(_optionalChain([config, 'optionalAccess', _38 => _38.ttlSeconds]), () => ( 60)), 1, 86400);
1187
+ const ttlSeconds = clamp2(_nullishCoalesce(_optionalChain([config, 'optionalAccess', _32 => _32.ttlSeconds]), () => ( 60)), 1, 86400);
1749
1188
  const ttlMs = ttlSeconds * 1e3;
1750
- const maxEntries = Math.max(1, Math.floor(_nullishCoalesce(_optionalChain([config, 'optionalAccess', _39 => _39.maxEntries]), () => ( 1024))));
1751
- const staleWhileRevalidate = _nullishCoalesce(_optionalChain([config, 'optionalAccess', _40 => _40.staleWhileRevalidate]), () => ( false));
1752
- const cachePolicy = _optionalChain([config, 'optionalAccess', _41 => _41.cachePolicy]);
1753
- const cacheRelevantHeaders = _nullishCoalesce(_optionalChain([config, 'optionalAccess', _42 => _42.cacheRelevantHeaders]), () => ( []));
1754
- const baseUrl = _nullishCoalesce(_optionalChain([config, 'optionalAccess', _43 => _43.baseUrl]), () => ( ""));
1755
- const onEvent = _optionalChain([config, 'optionalAccess', _44 => _44.onEvent]);
1756
- const onLifecycleEvent = _optionalChain([config, 'optionalAccess', _45 => _45.onLifecycleEvent]);
1189
+ const maxEntries = Math.max(1, Math.floor(_nullishCoalesce(_optionalChain([config, 'optionalAccess', _33 => _33.maxEntries]), () => ( 1024))));
1190
+ const staleWhileRevalidate = _nullishCoalesce(_optionalChain([config, 'optionalAccess', _34 => _34.staleWhileRevalidate]), () => ( false));
1191
+ const cachePolicy = _optionalChain([config, 'optionalAccess', _35 => _35.cachePolicy]);
1192
+ const cacheRelevantHeaders = _nullishCoalesce(_optionalChain([config, 'optionalAccess', _36 => _36.cacheRelevantHeaders]), () => ( []));
1193
+ const baseUrl = _nullishCoalesce(_optionalChain([config, 'optionalAccess', _37 => _37.baseUrl]), () => ( ""));
1194
+ const onEvent = _optionalChain([config, 'optionalAccess', _38 => _38.onEvent]);
1195
+ const onLifecycleEvent = _optionalChain([config, 'optionalAccess', _39 => _39.onLifecycleEvent]);
1757
1196
  const cache = new LRUCache({
1758
1197
  maxEntries,
1759
- onEvict: (count) => _optionalChain([onLifecycleEvent, 'optionalCall', _46 => _46({ type: "cache-eviction", count })])
1198
+ onEvict: (count) => _optionalChain([onLifecycleEvent, 'optionalCall', _40 => _40({ type: "cache-eviction", count })])
1760
1199
  });
1761
1200
  const revalidating = /* @__PURE__ */ new Set();
1762
1201
  const invalidate = (key) => {
@@ -1777,13 +1216,13 @@ function withCache(config) {
1777
1216
  register: (env, cb) => {
1778
1217
  const cached = cache.get(key);
1779
1218
  if (cached !== void 0) {
1780
- _optionalChain([onLifecycleEvent, 'optionalCall', _47 => _47({ type: "cache-hit", cacheKey: key })]);
1219
+ _optionalChain([onLifecycleEvent, 'optionalCall', _41 => _41({ type: "cache-hit", cacheKey: key })]);
1781
1220
  cb({ _tag: "Success", value: cached });
1782
1221
  return;
1783
1222
  }
1784
- _optionalChain([onLifecycleEvent, 'optionalCall', _48 => _48({ type: "cache-miss", cacheKey: key })]);
1223
+ _optionalChain([onLifecycleEvent, 'optionalCall', _42 => _42({ type: "cache-miss", cacheKey: key })]);
1785
1224
  const innerEffect = next(req);
1786
- return registerHttpEffect(innerEffect, env, (exit) => {
1225
+ return _chunkIJT6RRQ5cjs.registerHttpEffect.call(void 0, innerEffect, env, (exit) => {
1787
1226
  if (exit._tag === "Success") {
1788
1227
  storeIfCacheable(req, exit.value, key);
1789
1228
  }
@@ -1821,7 +1260,7 @@ function withCache(config) {
1821
1260
  });
1822
1261
  }
1823
1262
  };
1824
- registerHttpEffect(innerEffect, void 0, handleExit);
1263
+ _chunkIJT6RRQ5cjs.registerHttpEffect.call(void 0, innerEffect, void 0, handleExit);
1825
1264
  }
1826
1265
  const expirationMap = /* @__PURE__ */ new Map();
1827
1266
  const swrMiddleware = (next) => {
@@ -1838,21 +1277,21 @@ function withCache(config) {
1838
1277
  if (cached !== void 0) {
1839
1278
  const expiresAt = expirationMap.get(key);
1840
1279
  if (expiresAt !== void 0 && now() < expiresAt) {
1841
- _optionalChain([onLifecycleEvent, 'optionalCall', _49 => _49({ type: "cache-hit", cacheKey: key })]);
1280
+ _optionalChain([onLifecycleEvent, 'optionalCall', _43 => _43({ type: "cache-hit", cacheKey: key })]);
1842
1281
  cb({ _tag: "Success", value: cached });
1843
1282
  return;
1844
1283
  }
1845
- _optionalChain([onLifecycleEvent, 'optionalCall', _50 => _50({ type: "cache-hit", cacheKey: key })]);
1284
+ _optionalChain([onLifecycleEvent, 'optionalCall', _44 => _44({ type: "cache-hit", cacheKey: key })]);
1846
1285
  cb({ _tag: "Success", value: cached });
1847
1286
  triggerRevalidation(next, req, key);
1848
1287
  return;
1849
1288
  }
1850
- _optionalChain([onLifecycleEvent, 'optionalCall', _51 => _51({ type: "cache-miss", cacheKey: key })]);
1289
+ _optionalChain([onLifecycleEvent, 'optionalCall', _45 => _45({ type: "cache-miss", cacheKey: key })]);
1851
1290
  const innerEffect = next(req);
1852
1291
  const handleSuccess = (res) => {
1853
1292
  swrStoreIfCacheable(req, res, key);
1854
1293
  };
1855
- return registerHttpEffect(innerEffect, env, (exit) => {
1294
+ return _chunkIJT6RRQ5cjs.registerHttpEffect.call(void 0, innerEffect, env, (exit) => {
1856
1295
  if (exit._tag === "Success") {
1857
1296
  handleSuccess(exit.value);
1858
1297
  }
@@ -1907,9 +1346,9 @@ function comparePriority(a, b) {
1907
1346
  if (a.priority !== b.priority) return a.priority - b.priority;
1908
1347
  return a.arrivalOrder - b.arrivalOrder;
1909
1348
  }
1910
- var PriorityQueue = (_class4 = class {constructor() { _class4.prototype.__init8.call(this);_class4.prototype.__init9.call(this); }
1911
- __init8() {this.heap = []}
1912
- __init9() {this.counter = 0}
1349
+ var PriorityQueue = (_class2 = class {constructor() { _class2.prototype.__init4.call(this);_class2.prototype.__init5.call(this); }
1350
+ __init4() {this.heap = []}
1351
+ __init5() {this.counter = 0}
1913
1352
  /**
1914
1353
  * Returns the number of entries in the queue (including cancelled entries).
1915
1354
  *
@@ -2093,14 +1532,14 @@ var PriorityQueue = (_class4 = class {constructor() { _class4.prototype.__init8.
2093
1532
  index = smallest;
2094
1533
  }
2095
1534
  }
2096
- }, _class4);
1535
+ }, _class2);
2097
1536
 
2098
1537
  // src/http/lifecycle/priorityScheduler.ts
2099
- var DEFAULT_CONCURRENCY2 = 32;
1538
+ var DEFAULT_CONCURRENCY = 32;
2100
1539
  function extractPriority(req) {
2101
1540
  const fromReq = req.priority;
2102
1541
  if (fromReq !== void 0) return clampPriority(fromReq);
2103
- const fromInit = _optionalChain([req, 'access', _52 => _52.init, 'optionalAccess', _53 => _53.priority]);
1542
+ const fromInit = _optionalChain([req, 'access', _46 => _46.init, 'optionalAccess', _47 => _47.priority]);
2104
1543
  if (fromInit !== void 0) return clampPriority(fromInit);
2105
1544
  return 5;
2106
1545
  }
@@ -2108,13 +1547,13 @@ function safeEmit3(onEvent, event) {
2108
1547
  if (!onEvent) return;
2109
1548
  try {
2110
1549
  onEvent(event);
2111
- } catch (e9) {
1550
+ } catch (e11) {
2112
1551
  }
2113
1552
  }
2114
1553
  function withPriority(config) {
2115
- const concurrency = resolveConcurrency(_optionalChain([config, 'optionalAccess', _54 => _54.concurrency]));
2116
- const queueTimeoutMs = resolveQueueTimeout(_optionalChain([config, 'optionalAccess', _55 => _55.queueTimeoutMs]));
2117
- const onEvent = _optionalChain([config, 'optionalAccess', _56 => _56.onEvent]);
1554
+ const concurrency = resolveConcurrency(_optionalChain([config, 'optionalAccess', _48 => _48.concurrency]));
1555
+ const queueTimeoutMs = resolveQueueTimeout(_optionalChain([config, 'optionalAccess', _49 => _49.queueTimeoutMs]));
1556
+ const onEvent = _optionalChain([config, 'optionalAccess', _50 => _50.onEvent]);
2118
1557
  const queue = new PriorityQueue();
2119
1558
  let inFlight = 0;
2120
1559
  const queueDepth = () => {
@@ -2138,7 +1577,7 @@ function withPriority(config) {
2138
1577
  queued.timer = void 0;
2139
1578
  cb({
2140
1579
  _tag: "Failure",
2141
- cause: _chunkTGIFUAK4cjs.Cause.fail({
1580
+ cause: _chunkDJQ7OMMBcjs.Cause.fail({
2142
1581
  _tag: "PoolTimeout",
2143
1582
  key: "priority",
2144
1583
  timeoutMs: queueTimeoutMs,
@@ -2156,12 +1595,12 @@ function withPriority(config) {
2156
1595
  clearTimeout(queued.timer);
2157
1596
  queued.timer = void 0;
2158
1597
  }
2159
- cb({ _tag: "Failure", cause: _chunkTGIFUAK4cjs.Cause.fail({ _tag: "Abort" }) });
1598
+ cb({ _tag: "Failure", cause: _chunkDJQ7OMMBcjs.Cause.fail({ _tag: "Abort" }) });
2160
1599
  };
2161
1600
  signal.addEventListener("abort", abortHandler, { once: true });
2162
- } else if (_optionalChain([signal, 'optionalAccess', _57 => _57.aborted])) {
1601
+ } else if (_optionalChain([signal, 'optionalAccess', _51 => _51.aborted])) {
2163
1602
  entry.cancelled = true;
2164
- cb({ _tag: "Failure", cause: _chunkTGIFUAK4cjs.Cause.fail({ _tag: "Abort" }) });
1603
+ cb({ _tag: "Failure", cause: _chunkDJQ7OMMBcjs.Cause.fail({ _tag: "Abort" }) });
2165
1604
  return;
2166
1605
  }
2167
1606
  return () => {
@@ -2173,7 +1612,7 @@ function withPriority(config) {
2173
1612
  if (abortHandler && signal) {
2174
1613
  signal.removeEventListener("abort", abortHandler);
2175
1614
  }
2176
- cb({ _tag: "Failure", cause: _chunkTGIFUAK4cjs.Cause.interrupt() });
1615
+ cb({ _tag: "Failure", cause: _chunkDJQ7OMMBcjs.Cause.interrupt() });
2177
1616
  };
2178
1617
  }
2179
1618
  };
@@ -2190,7 +1629,7 @@ function withPriority(config) {
2190
1629
  cb(exit);
2191
1630
  drainNext(downstream);
2192
1631
  };
2193
- const innerCancel = registerHttpEffect(innerEffect, env, onComplete);
1632
+ const innerCancel = _chunkIJT6RRQ5cjs.registerHttpEffect.call(void 0, innerEffect, env, onComplete);
2194
1633
  return () => {
2195
1634
  innerCancel();
2196
1635
  };
@@ -2205,8 +1644,8 @@ function withPriority(config) {
2205
1644
  clearTimeout(queued.timer);
2206
1645
  queued.timer = void 0;
2207
1646
  }
2208
- if (_optionalChain([queued, 'access', _58 => _58.signal, 'optionalAccess', _59 => _59.aborted])) {
2209
- queued.cb({ _tag: "Failure", cause: _chunkTGIFUAK4cjs.Cause.fail({ _tag: "Abort" }) });
1647
+ if (_optionalChain([queued, 'access', _52 => _52.signal, 'optionalAccess', _53 => _53.aborted])) {
1648
+ queued.cb({ _tag: "Failure", cause: _chunkDJQ7OMMBcjs.Cause.fail({ _tag: "Abort" }) });
2210
1649
  continue;
2211
1650
  }
2212
1651
  dispatchRequest(downstream, queued.req, queued.env, queued.cb);
@@ -2216,7 +1655,7 @@ function withPriority(config) {
2216
1655
  return Object.assign(middleware, { queueDepth });
2217
1656
  }
2218
1657
  function resolveConcurrency(value) {
2219
- if (value === void 0 || !Number.isFinite(value)) return DEFAULT_CONCURRENCY2;
1658
+ if (value === void 0 || !Number.isFinite(value)) return DEFAULT_CONCURRENCY;
2220
1659
  return Math.max(1, Math.floor(value));
2221
1660
  }
2222
1661
  function resolveQueueTimeout(value) {
@@ -2225,21 +1664,23 @@ function resolveQueueTimeout(value) {
2225
1664
  return n > 0 ? n : void 0;
2226
1665
  }
2227
1666
  function getSignal(req) {
2228
- return _optionalChain([req, 'access', _60 => _60.init, 'optionalAccess', _61 => _61.signal]);
1667
+ return _optionalChain([req, 'access', _54 => _54.init, 'optionalAccess', _55 => _55.signal]);
2229
1668
  }
2230
1669
 
2231
1670
  // src/http/lifecycle/stats.ts
2232
- var LifecycleStatsTracker = (_class5 = class {
2233
- __init10() {this._cacheHits = 0}
2234
- __init11() {this._cacheMisses = 0}
2235
- __init12() {this._cacheEvictions = 0}
2236
- __init13() {this._dedupHits = 0}
2237
- __init14() {this._dedupActive = 0}
2238
- __init15() {this._queueDepth = 0}
2239
- __init16() {this._requestsStarted = 0}
2240
- __init17() {this._requestsCompleted = 0}
2241
- __init18() {this._requestsFailed = 0}
2242
- __init19() {this._retries = 0}
1671
+ var LifecycleStatsTracker = (_class3 = class {
1672
+ __init6() {this._cacheHits = 0}
1673
+ __init7() {this._cacheMisses = 0}
1674
+ __init8() {this._cacheEvictions = 0}
1675
+ __init9() {this._dedupHits = 0}
1676
+ __init10() {this._dedupActive = 0}
1677
+ __init11() {this._queueDepth = 0}
1678
+ __init12() {this._requestsStarted = 0}
1679
+ __init13() {this._requestsCompleted = 0}
1680
+ __init14() {this._requestsFailed = 0}
1681
+ __init15() {this._retries = 0}
1682
+ __init16() {this._batchDispatches = 0}
1683
+ __init17() {this._batchedRequests = 0}
2243
1684
 
2244
1685
 
2245
1686
  /**
@@ -2259,7 +1700,7 @@ var LifecycleStatsTracker = (_class5 = class {
2259
1700
  * });
2260
1701
  * ```
2261
1702
  */
2262
- constructor(opts) {;_class5.prototype.__init10.call(this);_class5.prototype.__init11.call(this);_class5.prototype.__init12.call(this);_class5.prototype.__init13.call(this);_class5.prototype.__init14.call(this);_class5.prototype.__init15.call(this);_class5.prototype.__init16.call(this);_class5.prototype.__init17.call(this);_class5.prototype.__init18.call(this);_class5.prototype.__init19.call(this);
1703
+ constructor(opts) {;_class3.prototype.__init6.call(this);_class3.prototype.__init7.call(this);_class3.prototype.__init8.call(this);_class3.prototype.__init9.call(this);_class3.prototype.__init10.call(this);_class3.prototype.__init11.call(this);_class3.prototype.__init12.call(this);_class3.prototype.__init13.call(this);_class3.prototype.__init14.call(this);_class3.prototype.__init15.call(this);_class3.prototype.__init16.call(this);_class3.prototype.__init17.call(this);
2263
1704
  this._onEvent = opts.onEvent;
2264
1705
  this._wireStats = opts.wireStats;
2265
1706
  }
@@ -2400,6 +1841,19 @@ var LifecycleStatsTracker = (_class5 = class {
2400
1841
  retry() {
2401
1842
  this._retries++;
2402
1843
  }
1844
+ /**
1845
+ * Records a batch dispatch. Increments the batch dispatches counter by 1.
1846
+ */
1847
+ batchDispatch() {
1848
+ this._batchDispatches++;
1849
+ }
1850
+ /**
1851
+ * Records requests that were coalesced into a batch.
1852
+ * @param count - The number of individual requests in the batch.
1853
+ */
1854
+ batchedRequests(count) {
1855
+ this._batchedRequests += count;
1856
+ }
2403
1857
  // --- Event emission ---
2404
1858
  /**
2405
1859
  * Emits a lifecycle event to the registered `onEvent` callback.
@@ -2431,7 +1885,7 @@ var LifecycleStatsTracker = (_class5 = class {
2431
1885
  ...extra
2432
1886
  };
2433
1887
  this._onEvent(event);
2434
- } catch (e10) {
1888
+ } catch (e12) {
2435
1889
  }
2436
1890
  }
2437
1891
  // --- Snapshot ---
@@ -2468,84 +1922,544 @@ var LifecycleStatsTracker = (_class5 = class {
2468
1922
  requestsCompleted: this._requestsCompleted,
2469
1923
  requestsFailed: this._requestsFailed,
2470
1924
  retries: this._retries,
1925
+ batchDispatches: this._batchDispatches,
1926
+ batchedRequests: this._batchedRequests,
2471
1927
  wire: this._wireStats()
2472
1928
  });
2473
1929
  }
2474
- }, _class5);
1930
+ }, _class3);
2475
1931
 
2476
- // src/http/lifecycle/lifecycleClient.ts
2477
- function validateGlobals() {
2478
- if (typeof fetch === "undefined") {
1932
+ // src/http/prewarm/validation.ts
1933
+ function validateOrigin(origin) {
1934
+ if (!origin || typeof origin !== "string") {
1935
+ throw new Error(`validateOrigin: origin must be a non-empty string, got "${origin}"`);
1936
+ }
1937
+ const trimmed = origin.trim();
1938
+ if (!trimmed) {
1939
+ throw new Error(`validateOrigin: origin must be a non-empty string, got "${origin}"`);
1940
+ }
1941
+ const stripped = stripTrailingSlashes(trimmed);
1942
+ const lower = stripped.toLowerCase();
1943
+ if (!lower.startsWith("http://") && !lower.startsWith("https://")) {
2479
1944
  throw new Error(
2480
- "makeLifecycleClient: global `fetch` is not available. Ensure you are running in an environment with fetch support (Node.js 18+ or modern browser)."
1945
+ `validateOrigin: invalid origin "${origin}" \u2014 must start with http:// or https://`
2481
1946
  );
2482
1947
  }
2483
- if (typeof AbortController === "undefined") {
1948
+ let parsed;
1949
+ try {
1950
+ parsed = new URL(stripped);
1951
+ } catch (e13) {
2484
1952
  throw new Error(
2485
- "makeLifecycleClient: global `AbortController` is not available. Ensure you are running in an environment with AbortController support (Node.js 15+ or modern browser)."
1953
+ `validateOrigin: invalid origin "${origin}" \u2014 must be a valid URL origin (scheme + host + optional port)`
1954
+ );
1955
+ }
1956
+ if (parsed.pathname !== "/" && parsed.pathname !== "") {
1957
+ throw new Error(
1958
+ `validateOrigin: invalid origin "${origin}" \u2014 must not contain a path`
2486
1959
  );
2487
1960
  }
1961
+ if (parsed.search) {
1962
+ throw new Error(
1963
+ `validateOrigin: invalid origin "${origin}" \u2014 must not contain query parameters`
1964
+ );
1965
+ }
1966
+ if (parsed.hash) {
1967
+ throw new Error(
1968
+ `validateOrigin: invalid origin "${origin}" \u2014 must not contain a fragment`
1969
+ );
1970
+ }
1971
+ return parsed.origin;
2488
1972
  }
2489
- function extractWireConfig(config) {
2490
- const { dedup, cache, priority, retry, onEvent, ...wireConfig } = config;
2491
- return wireConfig;
1973
+ function stripTrailingSlashes(value) {
1974
+ let end = value.length;
1975
+ while (end > 0 && value.charCodeAt(end - 1) === 47) {
1976
+ end--;
1977
+ }
1978
+ return end === value.length ? value : value.slice(0, end);
2492
1979
  }
2493
- function makeLifecycleClient(config = {}) {
2494
- validateGlobals();
2495
- const wireConfig = extractWireConfig(config);
2496
- const wireClient = makeHttp(wireConfig);
2497
- const activeControllers = /* @__PURE__ */ new Set();
2498
- const tracker = new LifecycleStatsTracker({
2499
- onEvent: config.onEvent,
2500
- wireStats: wireClient.stats
2501
- });
2502
- const hasDedup = config.dedup !== void 0 && config.dedup !== false;
2503
- const hasCache = config.cache !== void 0 && config.cache !== false;
2504
- const hasPriority = config.priority !== void 0 && config.priority !== false;
2505
- const hasRetry = config.retry !== void 0 && config.retry !== false;
2506
- if (!hasDedup && !hasCache && !hasPriority && !hasRetry) {
2507
- return buildLifecycleClient(wireClient, tracker, {
2508
- cacheInvalidate: noopInvalidate,
2509
- cacheClear: noopClear,
2510
- cancelAll: () => cancelControllers(activeControllers),
2511
- activeControllers
2512
- });
1980
+
1981
+ // src/http/prewarm/platform.ts
1982
+ function detectPlatform() {
1983
+ return typeof window !== "undefined" && typeof window.document !== "undefined" ? "browser" : "node";
1984
+ }
1985
+ function validateFetchAvailable() {
1986
+ if (typeof globalThis.fetch !== "function") {
1987
+ throw new Error(
1988
+ "makePrewarmManager: global fetch is not available. Requires Node.js 18+ or modern browser."
1989
+ );
2513
1990
  }
2514
- let priorityMiddleware;
2515
- if (hasPriority) {
2516
- const priorityConfig = config.priority;
2517
- priorityMiddleware = withPriority({
2518
- ...priorityConfig,
2519
- onEvent: (event) => {
2520
- tracker.setQueueDepth(_nullishCoalesce(_optionalChain([priorityMiddleware, 'optionalAccess', _62 => _62.queueDepth, 'call', _63 => _63()]), () => ( 0)));
2521
- tracker.emit(event.type, { priority: event.priority });
1991
+ if (typeof globalThis.AbortController !== "function") {
1992
+ throw new Error(
1993
+ "makePrewarmManager: global AbortController is not available."
1994
+ );
1995
+ }
1996
+ }
1997
+
1998
+ // src/http/prewarm/probe.ts
1999
+ async function executeProbe(origin, options) {
2000
+ const { timeoutMs, signal, platform } = options;
2001
+ const url = `${origin}/`;
2002
+ const start = Date.now();
2003
+ const timeoutController = new AbortController();
2004
+ const timeoutId = setTimeout(() => timeoutController.abort(), timeoutMs);
2005
+ const onExternalAbort = () => timeoutController.abort();
2006
+ signal.addEventListener("abort", onExternalAbort);
2007
+ try {
2008
+ if (options.client) {
2009
+ const result = await executeProbeViaClient(options.client, url, timeoutController.signal);
2010
+ const durationMs2 = Date.now() - start;
2011
+ if (result.ok) {
2012
+ return { ok: true, durationMs: durationMs2 };
2522
2013
  }
2523
- });
2014
+ return { ok: false, durationMs: durationMs2, error: result.error };
2015
+ }
2016
+ const fetchOptions = {
2017
+ method: "HEAD",
2018
+ signal: timeoutController.signal,
2019
+ // Prevent caching of probe requests
2020
+ cache: "no-store"
2021
+ };
2022
+ if (platform === "browser") {
2023
+ fetchOptions.mode = "no-cors";
2024
+ }
2025
+ await globalThis.fetch(url, fetchOptions);
2026
+ const durationMs = Date.now() - start;
2027
+ return { ok: true, durationMs };
2028
+ } catch (err) {
2029
+ const durationMs = Date.now() - start;
2030
+ if (signal.aborted) {
2031
+ return { ok: false, durationMs, error: "cancelled" };
2032
+ }
2033
+ if (timeoutController.signal.aborted && !signal.aborted) {
2034
+ return { ok: false, durationMs, error: `Probe timed out after ${timeoutMs}ms` };
2035
+ }
2036
+ const message = err instanceof Error ? err.message : String(err);
2037
+ return { ok: false, durationMs, error: message };
2038
+ } finally {
2039
+ clearTimeout(timeoutId);
2040
+ signal.removeEventListener("abort", onExternalAbort);
2524
2041
  }
2525
- let cacheLayer;
2526
- if (hasCache) {
2527
- const cacheConfig = config.cache;
2528
- cacheLayer = withCache({
2529
- ...cacheConfig,
2530
- baseUrl: wireConfig.baseUrl,
2531
- onLifecycleEvent: (event) => {
2532
- if (event.type === "cache-hit") tracker.cacheHit();
2533
- if (event.type === "cache-miss") tracker.cacheMiss();
2534
- if (event.type === "cache-eviction") tracker.cacheEviction();
2535
- if (event.type === "cache-hit" || event.type === "cache-miss") {
2536
- tracker.emit(event.type, { cacheKey: event.cacheKey });
2042
+ }
2043
+ async function executeProbeViaClient(client, url, signal) {
2044
+ const { registerHttpEffect: registerHttpEffect2 } = await Promise.resolve().then(() => _interopRequireWildcard(require("../effectRunner-3ZHAD3LE.cjs")));
2045
+ return new Promise((resolve) => {
2046
+ const effect = client({
2047
+ method: "HEAD",
2048
+ url,
2049
+ init: { signal }
2050
+ });
2051
+ const cancel = registerHttpEffect2(effect, {}, (exit) => {
2052
+ if (exit._tag === "Success") {
2053
+ resolve({ ok: true });
2054
+ } else {
2055
+ const cause = exit.cause;
2056
+ if (_optionalChain([cause, 'optionalAccess', _56 => _56._tag]) === "Fail") {
2057
+ const err = cause.error;
2058
+ resolve({ ok: false, error: _nullishCoalesce(_nullishCoalesce(_optionalChain([err, 'optionalAccess', _57 => _57.message]), () => ( _optionalChain([err, 'optionalAccess', _58 => _58._tag]))), () => ( "Unknown error")) });
2059
+ } else {
2060
+ resolve({ ok: false, error: "cancelled" });
2537
2061
  }
2538
2062
  }
2539
2063
  });
2064
+ if (signal.aborted) {
2065
+ cancel();
2066
+ } else {
2067
+ signal.addEventListener("abort", () => {
2068
+ cancel();
2069
+ }, { once: true });
2070
+ }
2071
+ });
2072
+ }
2073
+
2074
+ // src/http/prewarm/connectionState.ts
2075
+ function makeConnectionStateMap(origins, keepAliveDurationMs) {
2076
+ const entries = /* @__PURE__ */ new Map();
2077
+ for (const origin of origins) {
2078
+ entries.set(origin, {
2079
+ origin,
2080
+ status: "idle",
2081
+ lastProbeAt: void 0,
2082
+ warmUntil: void 0
2083
+ });
2540
2084
  }
2541
- let dedupMiddleware;
2542
- if (hasDedup) {
2543
- const dedupConfig = config.dedup;
2544
- const baseUrl = _nullishCoalesce(wireConfig.baseUrl, () => ( ""));
2545
- const effectiveDedupConfig = dedupConfig.dedupKey || !baseUrl ? dedupConfig : { ...dedupConfig, dedupKey: (req) => computeDedupKey(req, baseUrl) };
2546
- dedupMiddleware = withDedup({
2547
- ...effectiveDedupConfig,
2548
- onEvent: (event) => {
2085
+ function markWarm(origin, now2) {
2086
+ const entry = entries.get(origin);
2087
+ if (!entry) return;
2088
+ const timestamp = _nullishCoalesce(now2, () => ( Date.now()));
2089
+ entry.status = "warm";
2090
+ entry.lastProbeAt = timestamp;
2091
+ entry.warmUntil = timestamp + keepAliveDurationMs;
2092
+ }
2093
+ function markExpired(origin) {
2094
+ const entry = entries.get(origin);
2095
+ if (!entry) return;
2096
+ entry.status = "expired";
2097
+ }
2098
+ function markIdle(origin) {
2099
+ const entry = entries.get(origin);
2100
+ if (!entry) return;
2101
+ entry.status = "idle";
2102
+ entry.lastProbeAt = void 0;
2103
+ entry.warmUntil = void 0;
2104
+ }
2105
+ function markProbing(origin) {
2106
+ const entry = entries.get(origin);
2107
+ if (!entry) return;
2108
+ entry.status = "probing";
2109
+ }
2110
+ function isWarm(origin, now2) {
2111
+ const entry = entries.get(origin);
2112
+ if (!entry) return false;
2113
+ if (entry.status !== "warm") return false;
2114
+ if (entry.lastProbeAt === void 0 || entry.warmUntil === void 0) return false;
2115
+ const currentTime = _nullishCoalesce(now2, () => ( Date.now()));
2116
+ if (currentTime >= entry.warmUntil) {
2117
+ entry.status = "expired";
2118
+ return false;
2119
+ }
2120
+ return true;
2121
+ }
2122
+ function getState(origin) {
2123
+ const entry = entries.get(origin);
2124
+ if (!entry) return void 0;
2125
+ return {
2126
+ origin: entry.origin,
2127
+ status: entry.status,
2128
+ lastProbeAt: entry.lastProbeAt,
2129
+ warmUntil: entry.warmUntil
2130
+ };
2131
+ }
2132
+ function snapshot() {
2133
+ const result = [];
2134
+ for (const entry of entries.values()) {
2135
+ result.push({
2136
+ origin: entry.origin,
2137
+ status: entry.status,
2138
+ lastProbeAt: entry.lastProbeAt,
2139
+ warmUntil: entry.warmUntil
2140
+ });
2141
+ }
2142
+ return { origins: result };
2143
+ }
2144
+ return { markWarm, markExpired, markIdle, markProbing, isWarm, getState, snapshot };
2145
+ }
2146
+
2147
+ // src/http/prewarm/budgetSemaphore.ts
2148
+ function makeBudgetSemaphore(capacity) {
2149
+ if (capacity < 1 || !Number.isFinite(capacity)) {
2150
+ throw new Error(`makeBudgetSemaphore: capacity must be >= 1, got ${capacity}`);
2151
+ }
2152
+ capacity = Math.floor(capacity);
2153
+ let active = 0;
2154
+ const waiters = [];
2155
+ function release() {
2156
+ active--;
2157
+ if (waiters.length > 0) {
2158
+ const next = waiters.shift();
2159
+ active++;
2160
+ next({ release });
2161
+ }
2162
+ }
2163
+ function acquire() {
2164
+ if (active < capacity) {
2165
+ active++;
2166
+ return Promise.resolve({ release });
2167
+ }
2168
+ return new Promise((resolve) => {
2169
+ waiters.push(resolve);
2170
+ });
2171
+ }
2172
+ function tryAcquire() {
2173
+ if (active < capacity) {
2174
+ active++;
2175
+ return { release };
2176
+ }
2177
+ return void 0;
2178
+ }
2179
+ function available() {
2180
+ return capacity - active;
2181
+ }
2182
+ function queued() {
2183
+ return waiters.length;
2184
+ }
2185
+ return { acquire, tryAcquire, available, queued };
2186
+ }
2187
+
2188
+ // src/http/prewarm/prewarmManager.ts
2189
+ var DEFAULTS = {
2190
+ keepAliveDurationMs: 55e3,
2191
+ budget: 4,
2192
+ probeTimeoutMs: 5e3,
2193
+ autoRefresh: false,
2194
+ useClientPool: false
2195
+ };
2196
+ function makePrewarmManager(config) {
2197
+ validateFetchAvailable();
2198
+ const keepAliveDurationMs = _nullishCoalesce(config.keepAliveDurationMs, () => ( DEFAULTS.keepAliveDurationMs));
2199
+ const budget = _nullishCoalesce(config.budget, () => ( DEFAULTS.budget));
2200
+ const probeTimeoutMs = _nullishCoalesce(config.probeTimeoutMs, () => ( DEFAULTS.probeTimeoutMs));
2201
+ const autoRefresh = _nullishCoalesce(config.autoRefresh, () => ( DEFAULTS.autoRefresh));
2202
+ const useClientPool = _nullishCoalesce(config.useClientPool, () => ( DEFAULTS.useClientPool));
2203
+ const onEvent = config.onEvent;
2204
+ const client = config.client;
2205
+ const origins = config.origins.map((o) => validateOrigin(o));
2206
+ const platform = detectPlatform();
2207
+ const stateMap = makeConnectionStateMap(origins, keepAliveDurationMs);
2208
+ const semaphore = makeBudgetSemaphore(budget);
2209
+ const abortControllers = /* @__PURE__ */ new Map();
2210
+ const refreshTimers = /* @__PURE__ */ new Map();
2211
+ let disposed = false;
2212
+ function emit3(event) {
2213
+ if (onEvent) {
2214
+ try {
2215
+ onEvent(event);
2216
+ } catch (e14) {
2217
+ }
2218
+ }
2219
+ }
2220
+ function scheduleAutoRefresh(origin) {
2221
+ if (!autoRefresh || disposed) return;
2222
+ clearRefreshTimer(origin);
2223
+ const delay = Math.floor(0.8 * keepAliveDurationMs);
2224
+ const timer = setTimeout(() => {
2225
+ refreshTimers.delete(origin);
2226
+ if (disposed) return;
2227
+ if (stateMap.isWarm(origin)) {
2228
+ stateMap.markExpired(origin);
2229
+ emit3({
2230
+ type: "connection-expired",
2231
+ origin,
2232
+ timestamp: Date.now()
2233
+ });
2234
+ }
2235
+ warm(origin).catch(() => {
2236
+ });
2237
+ }, delay);
2238
+ if (typeof timer === "object" && "unref" in timer) {
2239
+ timer.unref();
2240
+ }
2241
+ refreshTimers.set(origin, timer);
2242
+ }
2243
+ function clearRefreshTimer(origin) {
2244
+ const timer = refreshTimers.get(origin);
2245
+ if (timer !== void 0) {
2246
+ clearTimeout(timer);
2247
+ refreshTimers.delete(origin);
2248
+ }
2249
+ }
2250
+ function clearAllRefreshTimers() {
2251
+ for (const [, timer] of refreshTimers) {
2252
+ clearTimeout(timer);
2253
+ }
2254
+ refreshTimers.clear();
2255
+ }
2256
+ async function warm(origin) {
2257
+ if (disposed) {
2258
+ return { origin, status: "cancelled", durationMs: 0 };
2259
+ }
2260
+ if (stateMap.isWarm(origin)) {
2261
+ return { origin, status: "already-warm", durationMs: 0 };
2262
+ }
2263
+ const { release } = await semaphore.acquire();
2264
+ if (disposed) {
2265
+ release();
2266
+ return { origin, status: "cancelled", durationMs: 0 };
2267
+ }
2268
+ const controller = new AbortController();
2269
+ abortControllers.set(origin, controller);
2270
+ stateMap.markProbing(origin);
2271
+ try {
2272
+ const probeOptions = {
2273
+ timeoutMs: probeTimeoutMs,
2274
+ signal: controller.signal,
2275
+ platform,
2276
+ client: useClientPool ? client : void 0
2277
+ };
2278
+ const outcome = await executeProbe(origin, probeOptions);
2279
+ if (controller.signal.aborted) {
2280
+ stateMap.markIdle(origin);
2281
+ emit3({
2282
+ type: "connection-cancelled",
2283
+ origin,
2284
+ timestamp: Date.now()
2285
+ });
2286
+ return { origin, status: "cancelled", durationMs: outcome.durationMs };
2287
+ }
2288
+ if (outcome.ok) {
2289
+ stateMap.markWarm(origin);
2290
+ emit3({
2291
+ type: "connection-warmed",
2292
+ origin,
2293
+ timestamp: Date.now(),
2294
+ durationMs: outcome.durationMs
2295
+ });
2296
+ scheduleAutoRefresh(origin);
2297
+ return { origin, status: "warmed", durationMs: outcome.durationMs };
2298
+ } else {
2299
+ stateMap.markIdle(origin);
2300
+ emit3({
2301
+ type: "connection-failed",
2302
+ origin,
2303
+ timestamp: Date.now(),
2304
+ error: outcome.error
2305
+ });
2306
+ return { origin, status: "failed", durationMs: outcome.durationMs, error: outcome.error };
2307
+ }
2308
+ } catch (err) {
2309
+ stateMap.markIdle(origin);
2310
+ const error = err instanceof Error ? err.message : String(err);
2311
+ emit3({
2312
+ type: "connection-failed",
2313
+ origin,
2314
+ timestamp: Date.now(),
2315
+ error
2316
+ });
2317
+ return { origin, status: "failed", durationMs: 0, error };
2318
+ } finally {
2319
+ abortControllers.delete(origin);
2320
+ release();
2321
+ }
2322
+ }
2323
+ async function warmAll() {
2324
+ const results = await Promise.all(origins.map((o) => warm(o)));
2325
+ return results;
2326
+ }
2327
+ function cancel(origin) {
2328
+ const controller = abortControllers.get(origin);
2329
+ if (controller) {
2330
+ controller.abort();
2331
+ }
2332
+ clearRefreshTimer(origin);
2333
+ }
2334
+ function cancelAll() {
2335
+ for (const [, controller] of abortControllers) {
2336
+ controller.abort();
2337
+ }
2338
+ clearAllRefreshTimers();
2339
+ }
2340
+ function isWarm(origin) {
2341
+ if (disposed) return false;
2342
+ return stateMap.isWarm(origin);
2343
+ }
2344
+ function status() {
2345
+ return stateMap.snapshot();
2346
+ }
2347
+ function dispose() {
2348
+ if (disposed) return;
2349
+ disposed = true;
2350
+ cancelAll();
2351
+ for (const origin of origins) {
2352
+ stateMap.markIdle(origin);
2353
+ }
2354
+ }
2355
+ return {
2356
+ warm,
2357
+ warmAll,
2358
+ isWarm,
2359
+ cancel,
2360
+ cancelAll,
2361
+ status,
2362
+ dispose
2363
+ };
2364
+ }
2365
+
2366
+ // src/http/lifecycle/lifecycleClient.ts
2367
+ function validateGlobals() {
2368
+ if (typeof fetch === "undefined") {
2369
+ throw new Error(
2370
+ "makeLifecycleClient: global `fetch` is not available. Ensure you are running in an environment with fetch support (Node.js 18+ or modern browser)."
2371
+ );
2372
+ }
2373
+ if (typeof AbortController === "undefined") {
2374
+ throw new Error(
2375
+ "makeLifecycleClient: global `AbortController` is not available. Ensure you are running in an environment with AbortController support (Node.js 15+ or modern browser)."
2376
+ );
2377
+ }
2378
+ }
2379
+ function extractWireConfig(config) {
2380
+ const { dedup, batch, cache, priority, retry, prewarm, onEvent, ...wireConfig } = config;
2381
+ return wireConfig;
2382
+ }
2383
+ function makeLifecycleClient(config = {}) {
2384
+ _chunk5YOQOXEQcjs.validateLifecycleClientConfig.call(void 0, config);
2385
+ validateGlobals();
2386
+ const wireConfig = extractWireConfig(config);
2387
+ const wireClient = _chunk5YOQOXEQcjs.makeHttp.call(void 0, wireConfig);
2388
+ const activeControllers = /* @__PURE__ */ new Set();
2389
+ const tracker = new LifecycleStatsTracker({
2390
+ onEvent: config.onEvent,
2391
+ wireStats: wireClient.stats
2392
+ });
2393
+ const hasDedup = config.dedup !== void 0 && config.dedup !== false;
2394
+ const hasBatch = config.batch !== void 0 && config.batch !== false;
2395
+ const hasCache = config.cache !== void 0 && config.cache !== false;
2396
+ const hasPriority = config.priority !== void 0 && config.priority !== false;
2397
+ const hasRetry = config.retry !== void 0 && config.retry !== false;
2398
+ if (!hasDedup && !hasBatch && !hasCache && !hasPriority && !hasRetry) {
2399
+ let prewarmMgr2;
2400
+ const hasPrewarm2 = config.prewarm !== void 0 && config.prewarm !== false;
2401
+ if (hasPrewarm2) {
2402
+ const prewarmConfig = config.prewarm;
2403
+ const prewarmOrigins = _nullishCoalesce(prewarmConfig.origins, () => ( []));
2404
+ if (prewarmOrigins.length > 0) {
2405
+ prewarmMgr2 = makePrewarmManager({
2406
+ origins: prewarmOrigins,
2407
+ keepAliveDurationMs: prewarmConfig.keepAliveDurationMs,
2408
+ budget: prewarmConfig.budget,
2409
+ probeTimeoutMs: prewarmConfig.probeTimeoutMs,
2410
+ autoRefresh: prewarmConfig.autoRefresh,
2411
+ useClientPool: prewarmConfig.useClientPool,
2412
+ client: prewarmConfig.useClientPool ? wireClient : void 0,
2413
+ onEvent: prewarmConfig.onEvent
2414
+ });
2415
+ }
2416
+ }
2417
+ return buildLifecycleClient(wireClient, tracker, {
2418
+ cacheInvalidate: noopInvalidate,
2419
+ cacheClear: noopClear,
2420
+ cancelAll: () => cancelControllers(activeControllers, prewarmMgr2),
2421
+ shutdown: () => shutdownClient(activeControllers, prewarmMgr2, wireClient.shutdown),
2422
+ activeControllers,
2423
+ adaptiveLimiter: wireClient.adaptiveLimiter,
2424
+ prewarmManager: prewarmMgr2,
2425
+ afterResponse: hasPrewarm2 ? config.prewarm.afterResponse : void 0
2426
+ });
2427
+ }
2428
+ let priorityMiddleware;
2429
+ if (hasPriority) {
2430
+ const priorityConfig = config.priority;
2431
+ priorityMiddleware = withPriority({
2432
+ ...priorityConfig,
2433
+ onEvent: (event) => {
2434
+ tracker.setQueueDepth(_nullishCoalesce(_optionalChain([priorityMiddleware, 'optionalAccess', _59 => _59.queueDepth, 'call', _60 => _60()]), () => ( 0)));
2435
+ tracker.emit(event.type, { priority: event.priority });
2436
+ }
2437
+ });
2438
+ }
2439
+ let cacheLayer;
2440
+ if (hasCache) {
2441
+ const cacheConfig = config.cache;
2442
+ cacheLayer = withCache({
2443
+ ...cacheConfig,
2444
+ baseUrl: wireConfig.baseUrl,
2445
+ onLifecycleEvent: (event) => {
2446
+ if (event.type === "cache-hit") tracker.cacheHit();
2447
+ if (event.type === "cache-miss") tracker.cacheMiss();
2448
+ if (event.type === "cache-eviction") tracker.cacheEviction();
2449
+ if (event.type === "cache-hit" || event.type === "cache-miss") {
2450
+ tracker.emit(event.type, { cacheKey: event.cacheKey });
2451
+ }
2452
+ }
2453
+ });
2454
+ }
2455
+ let dedupMiddleware;
2456
+ if (hasDedup) {
2457
+ const dedupConfig = config.dedup;
2458
+ const baseUrl = _nullishCoalesce(wireConfig.baseUrl, () => ( ""));
2459
+ const effectiveDedupConfig = dedupConfig.dedupKey || !baseUrl ? dedupConfig : { ...dedupConfig, dedupKey: (req) => computeDedupKey(req, baseUrl) };
2460
+ dedupMiddleware = withDedup({
2461
+ ...effectiveDedupConfig,
2462
+ onEvent: (event) => {
2549
2463
  if (event.type === "dedup-hit") tracker.dedupHit();
2550
2464
  if (event.type === "dedup-active") {
2551
2465
  tracker.setDedupActive(_nullishCoalesce(event.active, () => ( 0)));
@@ -2555,13 +2469,24 @@ function makeLifecycleClient(config = {}) {
2555
2469
  }
2556
2470
  });
2557
2471
  }
2472
+ let batchMiddleware;
2473
+ if (hasBatch) {
2474
+ const batchConfig = config.batch;
2475
+ batchMiddleware = withBatch(batchConfig, (event) => {
2476
+ if (event.type === "batch-dispatch") {
2477
+ tracker.batchDispatch();
2478
+ tracker.batchedRequests(_nullishCoalesce(event.batchSize, () => ( 0)));
2479
+ }
2480
+ tracker.emit(event.type, { batchKey: event.batchKey, batchSize: event.batchSize });
2481
+ });
2482
+ }
2558
2483
  let composedFn = wireClient;
2559
2484
  if (priorityMiddleware) {
2560
2485
  composedFn = priorityMiddleware(composedFn);
2561
2486
  }
2562
2487
  if (hasRetry) {
2563
2488
  const retryConfig = config.retry;
2564
- composedFn = withRetry({
2489
+ composedFn = _chunk5YOQOXEQcjs.withRetry.call(void 0, {
2565
2490
  ...retryConfig,
2566
2491
  onRetry: (event) => {
2567
2492
  tracker.retry();
@@ -2569,24 +2494,49 @@ function makeLifecycleClient(config = {}) {
2569
2494
  attempt: event.attempt,
2570
2495
  delayMs: event.delayMs,
2571
2496
  status: event.status,
2572
- errorTag: _optionalChain([event, 'access', _64 => _64.error, 'optionalAccess', _65 => _65._tag])
2497
+ errorTag: _optionalChain([event, 'access', _61 => _61.error, 'optionalAccess', _62 => _62._tag])
2573
2498
  });
2574
- _optionalChain([retryConfig, 'access', _66 => _66.onRetry, 'optionalCall', _67 => _67(event)]);
2499
+ _optionalChain([retryConfig, 'access', _63 => _63.onRetry, 'optionalCall', _64 => _64(event)]);
2575
2500
  }
2576
2501
  })(composedFn);
2577
2502
  }
2578
2503
  if (cacheLayer) {
2579
2504
  composedFn = cacheLayer.middleware(composedFn);
2580
2505
  }
2506
+ if (batchMiddleware) {
2507
+ composedFn = batchMiddleware(composedFn);
2508
+ }
2581
2509
  if (dedupMiddleware) {
2582
2510
  composedFn = dedupMiddleware(composedFn);
2583
2511
  }
2512
+ let prewarmMgr;
2513
+ const hasPrewarm = config.prewarm !== void 0 && config.prewarm !== false;
2514
+ if (hasPrewarm) {
2515
+ const prewarmConfig = config.prewarm;
2516
+ const prewarmOrigins = _nullishCoalesce(prewarmConfig.origins, () => ( []));
2517
+ if (prewarmOrigins.length > 0) {
2518
+ prewarmMgr = makePrewarmManager({
2519
+ origins: prewarmOrigins,
2520
+ keepAliveDurationMs: prewarmConfig.keepAliveDurationMs,
2521
+ budget: prewarmConfig.budget,
2522
+ probeTimeoutMs: prewarmConfig.probeTimeoutMs,
2523
+ autoRefresh: prewarmConfig.autoRefresh,
2524
+ useClientPool: prewarmConfig.useClientPool,
2525
+ client: prewarmConfig.useClientPool ? wireClient : void 0,
2526
+ onEvent: prewarmConfig.onEvent
2527
+ });
2528
+ }
2529
+ }
2584
2530
  return buildLifecycleClient(composedFn, tracker, {
2585
- cacheInvalidate: _nullishCoalesce(_optionalChain([cacheLayer, 'optionalAccess', _68 => _68.invalidate]), () => ( noopInvalidate)),
2586
- cacheClear: _nullishCoalesce(_optionalChain([cacheLayer, 'optionalAccess', _69 => _69.clear]), () => ( noopClear)),
2587
- cancelAll: () => cancelControllers(activeControllers),
2531
+ cacheInvalidate: _nullishCoalesce(_optionalChain([cacheLayer, 'optionalAccess', _65 => _65.invalidate]), () => ( noopInvalidate)),
2532
+ cacheClear: _nullishCoalesce(_optionalChain([cacheLayer, 'optionalAccess', _66 => _66.clear]), () => ( noopClear)),
2533
+ cancelAll: () => cancelControllers(activeControllers, prewarmMgr),
2534
+ shutdown: () => shutdownClient(activeControllers, prewarmMgr, wireClient.shutdown),
2588
2535
  activeControllers,
2589
- queueDepth: _optionalChain([priorityMiddleware, 'optionalAccess', _70 => _70.queueDepth])
2536
+ adaptiveLimiter: wireClient.adaptiveLimiter,
2537
+ queueDepth: _optionalChain([priorityMiddleware, 'optionalAccess', _67 => _67.queueDepth]),
2538
+ prewarmManager: prewarmMgr,
2539
+ afterResponse: hasPrewarm ? config.prewarm.afterResponse : void 0
2590
2540
  });
2591
2541
  }
2592
2542
  function makeHttpClient(config = {}) {
@@ -2599,17 +2549,19 @@ function noopClear() {
2599
2549
  function buildLifecycleClient(fn, tracker, internals) {
2600
2550
  const client = (req) => trackRequest(fn, req, tracker, internals);
2601
2551
  const stats = () => {
2602
- tracker.setQueueDepth(_nullishCoalesce(_optionalChain([internals, 'access', _71 => _71.queueDepth, 'optionalCall', _72 => _72()]), () => ( 0)));
2552
+ tracker.setQueueDepth(_nullishCoalesce(_optionalChain([internals, 'access', _68 => _68.queueDepth, 'optionalCall', _69 => _69()]), () => ( 0)));
2603
2553
  return tracker.snapshot();
2604
2554
  };
2605
2555
  const withMw = (mw) => {
2606
- const wrappedFn = mw(fn);
2556
+ const wrappedFn = mw(withLifecycleMetadata(fn, internals));
2607
2557
  return buildLifecycleClient(wrappedFn, tracker, internals);
2608
2558
  };
2609
2559
  const lifecycleClient = Object.assign(client, {
2610
2560
  with: withMw,
2611
2561
  stats,
2612
2562
  cancelAll: internals.cancelAll,
2563
+ shutdown: internals.shutdown,
2564
+ adaptiveLimiter: internals.adaptiveLimiter,
2613
2565
  cache: {
2614
2566
  invalidate: internals.cacheInvalidate,
2615
2567
  clear: internals.cacheClear
@@ -2617,37 +2569,51 @@ function buildLifecycleClient(fn, tracker, internals) {
2617
2569
  });
2618
2570
  return lifecycleClient;
2619
2571
  }
2620
- function cancelControllers(activeControllers) {
2572
+ function withLifecycleMetadata(fn, internals) {
2573
+ if (!internals.adaptiveLimiter) return fn;
2574
+ return Object.assign(((req) => fn(req)), {
2575
+ adaptiveLimiter: internals.adaptiveLimiter
2576
+ });
2577
+ }
2578
+ function cancelControllers(activeControllers, prewarmMgr) {
2621
2579
  for (const controller of Array.from(activeControllers)) {
2622
2580
  try {
2623
2581
  controller.abort();
2624
- } catch (e11) {
2582
+ } catch (e15) {
2625
2583
  }
2626
2584
  }
2627
- return _chunkTGIFUAK4cjs.asyncSucceed.call(void 0, void 0);
2585
+ if (prewarmMgr) {
2586
+ prewarmMgr.cancelAll();
2587
+ }
2588
+ return _chunkDJQ7OMMBcjs.asyncSucceed.call(void 0, void 0);
2589
+ }
2590
+ function shutdownClient(activeControllers, prewarmMgr, wireShutdown) {
2591
+ cancelControllers(activeControllers, prewarmMgr);
2592
+ _optionalChain([wireShutdown, 'optionalCall', _70 => _70()]);
2593
+ return _chunkDJQ7OMMBcjs.asyncSucceed.call(void 0, void 0);
2628
2594
  }
2629
2595
  function trackRequest(fn, req, tracker, internals) {
2630
2596
  return {
2631
2597
  _tag: "Async",
2632
2598
  register: (env, cb) => {
2633
2599
  const controller = new AbortController();
2634
- const previousSignal = _optionalChain([req, 'access', _73 => _73.init, 'optionalAccess', _74 => _74.signal]);
2600
+ const previousSignal = _optionalChain([req, 'access', _71 => _71.init, 'optionalAccess', _72 => _72.signal]);
2635
2601
  let done = false;
2636
2602
  let abortedByPreviousSignal = false;
2637
2603
  let cancelInner;
2638
2604
  const abortFromPrevious = () => {
2639
2605
  abortedByPreviousSignal = true;
2640
2606
  try {
2641
- controller.abort(_optionalChain([previousSignal, 'optionalAccess', _75 => _75.reason]));
2642
- } catch (e12) {
2607
+ controller.abort(_optionalChain([previousSignal, 'optionalAccess', _73 => _73.reason]));
2608
+ } catch (e16) {
2643
2609
  controller.abort();
2644
2610
  }
2645
- _optionalChain([cancelInner, 'optionalCall', _76 => _76()]);
2611
+ _optionalChain([cancelInner, 'optionalCall', _74 => _74()]);
2646
2612
  };
2647
- if (_optionalChain([previousSignal, 'optionalAccess', _77 => _77.aborted])) {
2613
+ if (_optionalChain([previousSignal, 'optionalAccess', _75 => _75.aborted])) {
2648
2614
  abortFromPrevious();
2649
2615
  } else {
2650
- _optionalChain([previousSignal, 'optionalAccess', _78 => _78.addEventListener, 'call', _79 => _79("abort", abortFromPrevious, { once: true })]);
2616
+ _optionalChain([previousSignal, 'optionalAccess', _76 => _76.addEventListener, 'call', _77 => _77("abort", abortFromPrevious, { once: true })]);
2651
2617
  }
2652
2618
  internals.activeControllers.add(controller);
2653
2619
  tracker.requestStarted();
@@ -2655,11 +2621,23 @@ function trackRequest(fn, req, tracker, internals) {
2655
2621
  const finish = (exit0) => {
2656
2622
  if (done) return;
2657
2623
  done = true;
2658
- const exit = abortedByPreviousSignal && exit0._tag === "Failure" && exit0.cause._tag === "Interrupt" ? { _tag: "Failure", cause: _chunkTGIFUAK4cjs.Cause.fail({ _tag: "Abort" }) } : exit0;
2659
- _optionalChain([previousSignal, 'optionalAccess', _80 => _80.removeEventListener, 'call', _81 => _81("abort", abortFromPrevious)]);
2624
+ const exit = abortedByPreviousSignal && exit0._tag === "Failure" && exit0.cause._tag === "Interrupt" ? { _tag: "Failure", cause: _chunkDJQ7OMMBcjs.Cause.fail({ _tag: "Abort" }) } : exit0;
2625
+ _optionalChain([previousSignal, 'optionalAccess', _78 => _78.removeEventListener, 'call', _79 => _79("abort", abortFromPrevious)]);
2660
2626
  internals.activeControllers.delete(controller);
2661
2627
  if (exit._tag === "Success") {
2662
2628
  tracker.requestCompleted();
2629
+ if (internals.afterResponse && internals.prewarmManager) {
2630
+ try {
2631
+ const originsToWarm = internals.afterResponse(exit.value, req);
2632
+ if (originsToWarm && originsToWarm.length > 0) {
2633
+ for (const origin of originsToWarm) {
2634
+ internals.prewarmManager.warm(origin).catch(() => {
2635
+ });
2636
+ }
2637
+ }
2638
+ } catch (e17) {
2639
+ }
2640
+ }
2663
2641
  } else {
2664
2642
  tracker.requestFailed();
2665
2643
  }
@@ -2674,23 +2652,23 @@ function trackRequest(fn, req, tracker, internals) {
2674
2652
  }
2675
2653
  };
2676
2654
  try {
2677
- cancelInner = registerHttpEffect(fn(trackedReq), env, finish);
2655
+ cancelInner = _chunkIJT6RRQ5cjs.registerHttpEffect.call(void 0, fn(trackedReq), env, finish);
2678
2656
  } catch (error) {
2679
2657
  finish({
2680
2658
  _tag: "Failure",
2681
- cause: _chunkTGIFUAK4cjs.Cause.fail({ _tag: "FetchError", message: String(error) })
2659
+ cause: _chunkDJQ7OMMBcjs.Cause.fail({ _tag: "FetchError", message: String(error) })
2682
2660
  });
2683
2661
  }
2684
2662
  return () => {
2685
2663
  if (done) return;
2686
2664
  try {
2687
2665
  controller.abort();
2688
- } catch (e13) {
2666
+ } catch (e18) {
2689
2667
  }
2690
2668
  if (cancelInner) {
2691
2669
  cancelInner();
2692
2670
  } else {
2693
- finish({ _tag: "Failure", cause: _chunkTGIFUAK4cjs.Cause.interrupt() });
2671
+ finish({ _tag: "Failure", cause: _chunkDJQ7OMMBcjs.Cause.interrupt() });
2694
2672
  }
2695
2673
  };
2696
2674
  }
@@ -2701,7 +2679,7 @@ function trackRequest(fn, req, tracker, internals) {
2701
2679
  function withAuth(tokenProvider) {
2702
2680
  return (next) => {
2703
2681
  return (req) => {
2704
- return _chunkTGIFUAK4cjs.asyncFlatMap.call(void 0, tokenProvider(), (token) => {
2682
+ return _chunkDJQ7OMMBcjs.asyncFlatMap.call(void 0, tokenProvider(), (token) => {
2705
2683
  const modifiedReq = {
2706
2684
  ...req,
2707
2685
  headers: {
@@ -2719,26 +2697,26 @@ function withLogging(logger) {
2719
2697
  return (req) => {
2720
2698
  try {
2721
2699
  logger({ phase: "request", req });
2722
- } catch (e14) {
2700
+ } catch (e19) {
2723
2701
  }
2724
2702
  const startedAt = now();
2725
- return _chunkTGIFUAK4cjs.asyncFold.call(void 0,
2703
+ return _chunkDJQ7OMMBcjs.asyncFold.call(void 0,
2726
2704
  next(req),
2727
2705
  (error) => {
2728
2706
  const durationMs = Math.round(now() - startedAt);
2729
2707
  try {
2730
2708
  logger({ phase: "error", req, error, durationMs });
2731
- } catch (e15) {
2709
+ } catch (e20) {
2732
2710
  }
2733
- return _chunkTGIFUAK4cjs.asyncFail.call(void 0, error);
2711
+ return _chunkDJQ7OMMBcjs.asyncFail.call(void 0, error);
2734
2712
  },
2735
2713
  (res) => {
2736
2714
  const durationMs = Math.round(now() - startedAt);
2737
2715
  try {
2738
2716
  logger({ phase: "response", req, res, durationMs });
2739
- } catch (e16) {
2717
+ } catch (e21) {
2740
2718
  }
2741
- return _chunkTGIFUAK4cjs.asyncSucceed.call(void 0, res);
2719
+ return _chunkDJQ7OMMBcjs.asyncSucceed.call(void 0, res);
2742
2720
  }
2743
2721
  );
2744
2722
  };
@@ -2747,17 +2725,17 @@ function withLogging(logger) {
2747
2725
  function withResponseTransform(fn) {
2748
2726
  return (next) => {
2749
2727
  return (req) => {
2750
- return _chunkTGIFUAK4cjs.asyncFold.call(void 0,
2728
+ return _chunkDJQ7OMMBcjs.asyncFold.call(void 0,
2751
2729
  next(req),
2752
2730
  (error) => {
2753
- return _chunkTGIFUAK4cjs.asyncFail.call(void 0, error);
2731
+ return _chunkDJQ7OMMBcjs.asyncFail.call(void 0, error);
2754
2732
  },
2755
2733
  (res) => {
2756
2734
  try {
2757
2735
  const transformed = fn(res, req);
2758
- return _chunkTGIFUAK4cjs.asyncSucceed.call(void 0, transformed);
2736
+ return _chunkDJQ7OMMBcjs.asyncSucceed.call(void 0, transformed);
2759
2737
  } catch (e) {
2760
- return _chunkTGIFUAK4cjs.asyncFail.call(void 0, { _tag: "FetchError", message: String(e) });
2738
+ return _chunkDJQ7OMMBcjs.asyncFail.call(void 0, { _tag: "FetchError", message: String(e) });
2761
2739
  }
2762
2740
  }
2763
2741
  );
@@ -2773,7 +2751,7 @@ function isNodeEnvironment() {
2773
2751
  return typeof process !== "undefined" && process.versions != null && process.versions.node != null;
2774
2752
  }
2775
2753
 
2776
- // src/http/compression/decompressorNode.ts
2754
+ // src/http/compression/decompressor.node.ts
2777
2755
  function createNodeDecompressor(zlib2) {
2778
2756
  return {
2779
2757
  isPassthrough: false,
@@ -2824,7 +2802,7 @@ function createDecompressor() {
2824
2802
 
2825
2803
  // src/http/compression/types.ts
2826
2804
  var SUPPORTED_ENCODINGS = ["br", "gzip", "deflate"];
2827
- function emptyStats2() {
2805
+ function emptyStats() {
2828
2806
  return {
2829
2807
  decompressed: { gzip: 0, br: 0, deflate: 0 },
2830
2808
  compressedBytes: 0,
@@ -2866,7 +2844,7 @@ function processResponse(res, decompressor, enabledEncodings, stats) {
2866
2844
  const contentEncodingKey = Object.keys(res.headers).find(
2867
2845
  (k) => k.toLowerCase() === "content-encoding"
2868
2846
  );
2869
- const contentEncodingValue = contentEncodingKey ? _optionalChain([res, 'access', _82 => _82.headers, 'access', _83 => _83[contentEncodingKey], 'optionalAccess', _84 => _84.trim, 'call', _85 => _85()]) : void 0;
2847
+ const contentEncodingValue = contentEncodingKey ? _optionalChain([res, 'access', _80 => _80.headers, 'access', _81 => _81[contentEncodingKey], 'optionalAccess', _82 => _82.trim, 'call', _83 => _83()]) : void 0;
2870
2848
  if (!contentEncodingValue || contentEncodingValue.toLowerCase() === "identity") {
2871
2849
  stats.passthroughCount++;
2872
2850
  return res;
@@ -2874,7 +2852,6 @@ function processResponse(res, decompressor, enabledEncodings, stats) {
2874
2852
  const encodings = contentEncodingValue.split(",").map((e) => e.trim().toLowerCase());
2875
2853
  const reversedEncodings = [...encodings].reverse();
2876
2854
  let currentData = Buffer.from(res.bodyText, "latin1");
2877
- const originalData = currentData;
2878
2855
  let decompressedCount = 0;
2879
2856
  for (let i = 0; i < reversedEncodings.length; i++) {
2880
2857
  const enc = reversedEncodings[i];
@@ -2942,21 +2919,21 @@ function processResponse(res, decompressor, enabledEncodings, stats) {
2942
2919
  };
2943
2920
  }
2944
2921
  function makeCompressionMiddleware(config) {
2945
- const enabledEncodings = _nullishCoalesce(_optionalChain([config, 'optionalAccess', _86 => _86.encodings]), () => ( [...SUPPORTED_ENCODINGS]));
2922
+ const enabledEncodings = _nullishCoalesce(_optionalChain([config, 'optionalAccess', _84 => _84.encodings]), () => ( [...SUPPORTED_ENCODINGS]));
2946
2923
  const decompressor = createDecompressor();
2947
- const mutableStats = emptyStats2();
2924
+ const mutableStats = emptyStats();
2948
2925
  const middleware = (next) => {
2949
2926
  return (req) => {
2950
2927
  const modifiedReq = injectAcceptEncoding(req, enabledEncodings);
2951
- return _chunkTGIFUAK4cjs.asyncFold.call(void 0,
2928
+ return _chunkDJQ7OMMBcjs.asyncFold.call(void 0,
2952
2929
  next(modifiedReq),
2953
2930
  // Pass HttpErrors through unchanged
2954
- (error) => _chunkTGIFUAK4cjs.asyncFail.call(void 0, error),
2931
+ (error) => _chunkDJQ7OMMBcjs.asyncFail.call(void 0, error),
2955
2932
  // Process successful responses
2956
2933
  (res) => {
2957
2934
  if (decompressor.isPassthrough) {
2958
2935
  mutableStats.passthroughCount++;
2959
- return _chunkTGIFUAK4cjs.asyncSucceed.call(void 0, res);
2936
+ return _chunkDJQ7OMMBcjs.asyncSucceed.call(void 0, res);
2960
2937
  }
2961
2938
  const processed = processResponse(
2962
2939
  res,
@@ -2964,7 +2941,7 @@ function makeCompressionMiddleware(config) {
2964
2941
  enabledEncodings,
2965
2942
  mutableStats
2966
2943
  );
2967
- return _chunkTGIFUAK4cjs.asyncSucceed.call(void 0, processed);
2944
+ return _chunkDJQ7OMMBcjs.asyncSucceed.call(void 0, processed);
2968
2945
  }
2969
2946
  );
2970
2947
  };
@@ -2982,9 +2959,9 @@ function makeCompressionMiddleware(config) {
2982
2959
  var makeResponseCompressionMiddleware = makeCompressionMiddleware;
2983
2960
  var DEFAULT_REQUEST_COMPRESS_METHODS = ["POST", "PUT", "PATCH"];
2984
2961
  function makeRequestCompressionMiddleware(config) {
2985
- const encoding = _nullishCoalesce(_optionalChain([config, 'optionalAccess', _87 => _87.encoding]), () => ( "gzip"));
2986
- const minBytes = Math.max(0, Math.floor(_nullishCoalesce(_optionalChain([config, 'optionalAccess', _88 => _88.minBytes]), () => ( 1024))));
2987
- const methods = new Set((_nullishCoalesce(_optionalChain([config, 'optionalAccess', _89 => _89.methods]), () => ( DEFAULT_REQUEST_COMPRESS_METHODS))).map((m) => m.toUpperCase()));
2962
+ const encoding = _nullishCoalesce(_optionalChain([config, 'optionalAccess', _85 => _85.encoding]), () => ( "gzip"));
2963
+ const minBytes = Math.max(0, Math.floor(_nullishCoalesce(_optionalChain([config, 'optionalAccess', _86 => _86.minBytes]), () => ( 1024))));
2964
+ const methods = new Set((_nullishCoalesce(_optionalChain([config, 'optionalAccess', _87 => _87.methods]), () => ( DEFAULT_REQUEST_COMPRESS_METHODS))).map((m) => m.toUpperCase()));
2988
2965
  const mutableStats = emptyRequestCompressionStats();
2989
2966
  const middleware = (next) => {
2990
2967
  return (req) => {
@@ -3028,13 +3005,13 @@ function compressRequest(req, encoding, minBytes, methods, stats) {
3028
3005
  "Content-Length": String(compressed.byteLength)
3029
3006
  })
3030
3007
  };
3031
- } catch (e17) {
3008
+ } catch (e22) {
3032
3009
  stats.errorCount++;
3033
3010
  return req;
3034
3011
  }
3035
3012
  }
3036
3013
  function compressBuffer(input, encoding) {
3037
- const zlib2 = _chunkTGIFUAK4cjs.__require.call(void 0, "zlib");
3014
+ const zlib2 = _chunkOBGZSXTJcjs.__require.call(void 0, "zlib");
3038
3015
  switch (encoding) {
3039
3016
  case "gzip":
3040
3017
  return zlib2.gzipSync(input);
@@ -3073,7 +3050,7 @@ function withRequestBatching(config) {
3073
3050
  try {
3074
3051
  if (config.shouldBatch && !config.shouldBatch(req)) return next(req);
3075
3052
  key = _nullishCoalesce(keyOf(req), () => ( void 0));
3076
- } catch (e18) {
3053
+ } catch (e23) {
3077
3054
  return next(req);
3078
3055
  }
3079
3056
  if (!key) return next(req);
@@ -3103,7 +3080,7 @@ function withRequestBatching(config) {
3103
3080
  function cancelEntry(key, entry) {
3104
3081
  if (entry.done || entry.cancelled) return;
3105
3082
  entry.cancelled = true;
3106
- complete(entry, { _tag: "Failure", cause: _chunkTGIFUAK4cjs.Cause.interrupt() });
3083
+ complete(entry, { _tag: "Failure", cause: _chunkDJQ7OMMBcjs.Cause.interrupt() });
3107
3084
  const queued = pending.get(key);
3108
3085
  if (queued) {
3109
3086
  queued.entries = queued.entries.filter((e) => e !== entry);
@@ -3118,7 +3095,7 @@ function withRequestBatching(config) {
3118
3095
  if (!group || group.cancelled) return;
3119
3096
  if (group.entries.every((e) => e.cancelled || e.done)) {
3120
3097
  group.cancelled = true;
3121
- _optionalChain([group, 'access', _90 => _90.cancel, 'optionalCall', _91 => _91()]);
3098
+ _optionalChain([group, 'access', _88 => _88.cancel, 'optionalCall', _89 => _89()]);
3122
3099
  }
3123
3100
  }
3124
3101
  function flush(key, downstream, reason) {
@@ -3170,14 +3147,14 @@ function complete(entry, exit) {
3170
3147
  function failEntries(config, key, entries, error) {
3171
3148
  emit(config, { type: "batch-error", key, size: entries.length, error });
3172
3149
  for (const entry of entries) {
3173
- complete(entry, { _tag: "Failure", cause: _chunkTGIFUAK4cjs.Cause.fail(error) });
3150
+ complete(entry, { _tag: "Failure", cause: _chunkDJQ7OMMBcjs.Cause.fail(error) });
3174
3151
  }
3175
3152
  }
3176
3153
  function toFetchError(error) {
3177
- if (isHttpError(error)) return error;
3154
+ if (isHttpError2(error)) return error;
3178
3155
  return { _tag: "FetchError", message: error instanceof Error ? error.message : String(error) };
3179
3156
  }
3180
- function isHttpError(error) {
3157
+ function isHttpError2(error) {
3181
3158
  if (typeof error !== "object" || error === null || !("_tag" in error)) return false;
3182
3159
  const tag = error._tag;
3183
3160
  return tag === "Abort" || tag === "BadUrl" || tag === "FetchError" || tag === "Timeout" || tag === "PoolRejected" || tag === "PoolTimeout";
@@ -3186,7 +3163,7 @@ function emit(config, event) {
3186
3163
  if (!config.onEvent) return;
3187
3164
  try {
3188
3165
  config.onEvent(event);
3189
- } catch (e19) {
3166
+ } catch (e24) {
3190
3167
  }
3191
3168
  }
3192
3169
  function runEffect(effect, env, cb) {
@@ -3203,13 +3180,13 @@ function runEffect(effect, env, cb) {
3203
3180
  k({ _tag: "Success", value: eff.value });
3204
3181
  return;
3205
3182
  case "Fail":
3206
- k({ _tag: "Failure", cause: _chunkTGIFUAK4cjs.Cause.fail(eff.error) });
3183
+ k({ _tag: "Failure", cause: _chunkDJQ7OMMBcjs.Cause.fail(eff.error) });
3207
3184
  return;
3208
3185
  case "Sync":
3209
3186
  try {
3210
3187
  k({ _tag: "Success", value: eff.thunk(env) });
3211
3188
  } catch (e) {
3212
- k({ _tag: "Failure", cause: _chunkTGIFUAK4cjs.Cause.die(e) });
3189
+ k({ _tag: "Failure", cause: _chunkDJQ7OMMBcjs.Cause.die(e) });
3213
3190
  }
3214
3191
  return;
3215
3192
  case "Async": {
@@ -3229,7 +3206,7 @@ function runEffect(effect, env, cb) {
3229
3206
  try {
3230
3207
  run(eff.andThen(exit.value), k);
3231
3208
  } catch (e) {
3232
- k({ _tag: "Failure", cause: _chunkTGIFUAK4cjs.Cause.die(e) });
3209
+ k({ _tag: "Failure", cause: _chunkDJQ7OMMBcjs.Cause.die(e) });
3233
3210
  }
3234
3211
  });
3235
3212
  return;
@@ -3244,7 +3221,7 @@ function runEffect(effect, env, cb) {
3244
3221
  k(exit);
3245
3222
  }
3246
3223
  } catch (e) {
3247
- k({ _tag: "Failure", cause: _chunkTGIFUAK4cjs.Cause.die(e) });
3224
+ k({ _tag: "Failure", cause: _chunkDJQ7OMMBcjs.Cause.die(e) });
3248
3225
  }
3249
3226
  });
3250
3227
  return;
@@ -3257,16 +3234,16 @@ function runEffect(effect, env, cb) {
3257
3234
  return () => {
3258
3235
  if (cancelled) return;
3259
3236
  cancelled = true;
3260
- _optionalChain([currentCancel, 'optionalCall', _92 => _92()]);
3237
+ _optionalChain([currentCancel, 'optionalCall', _90 => _90()]);
3261
3238
  };
3262
3239
  }
3263
3240
 
3264
- // src/http/prewarm.ts
3241
+ // src/http/prewarm/legacy.ts
3265
3242
  function prewarmConnections(config = {}) {
3266
3243
  const fetchImpl = _nullishCoalesce(config.fetchImpl, () => ( globalThis.fetch));
3267
3244
  const method = _nullishCoalesce(config.method, () => ( "HEAD"));
3268
3245
  const targets = resolveTargets(config);
3269
- return _chunkTGIFUAK4cjs.fromPromiseAbortable.call(void 0,
3246
+ return _chunkWQ5QNU5Rcjs.fromPromiseAbortable.call(void 0,
3270
3247
  async (signal) => {
3271
3248
  if (typeof fetchImpl !== "function" || targets.length === 0) {
3272
3249
  return { attempted: 0, warmed: 0, failed: 0, skipped: targets.length, attempts: [] };
@@ -3322,26 +3299,26 @@ function withConnectionPrewarming(config = {}) {
3322
3299
  const warming = /* @__PURE__ */ new Set();
3323
3300
  return (next) => (req) => {
3324
3301
  if (config.shouldPrewarm && !config.shouldPrewarm(req)) return next(req);
3325
- const target = _nullishCoalesce(_optionalChain([config, 'access', _93 => _93.target, 'optionalCall', _94 => _94(req)]), () => ( req.url));
3302
+ const target = _nullishCoalesce(_optionalChain([config, 'access', _91 => _91.target, 'optionalCall', _92 => _92(req)]), () => ( req.url));
3326
3303
  if (!target) return next(req);
3327
3304
  const resolved = resolveUrl(target, config.baseUrl);
3328
3305
  if (!resolved) return next(req);
3329
3306
  const key = resolved.origin;
3330
3307
  if (once && (warmed.has(key) || warming.has(key))) return next(req);
3331
3308
  warming.add(key);
3332
- return _chunkTGIFUAK4cjs.asyncFold.call(void 0,
3309
+ return _chunkDJQ7OMMBcjs.asyncFold.call(void 0,
3333
3310
  prewarmConnections({
3334
3311
  ...config,
3335
3312
  urls: [resolved.toString()],
3336
3313
  origins: void 0,
3337
3314
  onEvent: (event) => {
3338
3315
  if (event.type === "prewarm-success") warmed.add(key);
3339
- _optionalChain([config, 'access', _95 => _95.onEvent, 'optionalCall', _96 => _96(event)]);
3316
+ _optionalChain([config, 'access', _93 => _93.onEvent, 'optionalCall', _94 => _94(event)]);
3340
3317
  }
3341
3318
  }),
3342
3319
  (error) => {
3343
3320
  warming.delete(key);
3344
- if (config.failFast || error._tag === "Abort") return _chunkTGIFUAK4cjs.asyncFail.call(void 0, error);
3321
+ if (config.failFast || error._tag === "Abort") return _chunkDJQ7OMMBcjs.asyncFail.call(void 0, error);
3345
3322
  return next(req);
3346
3323
  },
3347
3324
  () => {
@@ -3371,18 +3348,18 @@ function resolveTargets(config) {
3371
3348
  function resolveUrl(value, baseUrl) {
3372
3349
  try {
3373
3350
  return new URL(value, baseUrl || void 0);
3374
- } catch (e20) {
3351
+ } catch (e25) {
3375
3352
  return void 0;
3376
3353
  }
3377
3354
  }
3378
3355
  function normalizePrewarmError(error) {
3379
- if (isHttpError2(error)) return error;
3356
+ if (isHttpError3(error)) return error;
3380
3357
  if (typeof error === "object" && error !== null && error.name === "AbortError") {
3381
3358
  return { _tag: "Abort" };
3382
3359
  }
3383
3360
  return { _tag: "FetchError", message: error instanceof Error ? error.message : String(error) };
3384
3361
  }
3385
- function isHttpError2(error) {
3362
+ function isHttpError3(error) {
3386
3363
  if (typeof error !== "object" || error === null || !("_tag" in error)) return false;
3387
3364
  const tag = error._tag;
3388
3365
  return tag === "Abort" || tag === "BadUrl" || tag === "FetchError" || tag === "Timeout" || tag === "PoolRejected" || tag === "PoolTimeout";
@@ -3391,10 +3368,951 @@ function emit2(config, event) {
3391
3368
  if (!config.onEvent) return;
3392
3369
  try {
3393
3370
  config.onEvent(event);
3394
- } catch (e21) {
3371
+ } catch (e26) {
3395
3372
  }
3396
3373
  }
3397
3374
 
3375
+ // src/http/defaultClient.ts
3376
+ var MINIMAL_PRESET_CONFIG = {
3377
+ timeoutMs: 3e4
3378
+ };
3379
+ var BALANCED_PRESET_CONFIG = {
3380
+ ...MINIMAL_PRESET_CONFIG,
3381
+ dedup: {},
3382
+ priority: {
3383
+ concurrency: 32,
3384
+ queueTimeoutMs: 3e4
3385
+ },
3386
+ retry: {
3387
+ maxRetries: 2,
3388
+ baseDelayMs: 100,
3389
+ maxDelayMs: 1e3,
3390
+ maxElapsedMs: 5e3,
3391
+ respectRetryAfter: true
3392
+ },
3393
+ adaptiveLimiter: _chunk5YOQOXEQcjs.makeAdaptiveLimiterConfig.call(void 0, "balanced")
3394
+ };
3395
+ var DEFAULT_CACHEABLE_METHODS = /* @__PURE__ */ new Set(["GET", "HEAD", "OPTIONS"]);
3396
+ var DEFAULT_PRESET_CONFIG = {
3397
+ ...BALANCED_PRESET_CONFIG,
3398
+ cache: {
3399
+ ttlSeconds: 60,
3400
+ maxEntries: 1024,
3401
+ staleWhileRevalidate: true,
3402
+ cachePolicy: (req, res) => ({
3403
+ cacheable: DEFAULT_CACHEABLE_METHODS.has(req.method) && res.status >= 200 && res.status < 400
3404
+ })
3405
+ },
3406
+ priority: {
3407
+ concurrency: 64,
3408
+ queueTimeoutMs: 3e4
3409
+ },
3410
+ retry: {
3411
+ maxRetries: 3,
3412
+ baseDelayMs: 100,
3413
+ maxDelayMs: 2e3,
3414
+ maxElapsedMs: 1e4,
3415
+ respectRetryAfter: true
3416
+ },
3417
+ adaptiveLimiter: _chunk5YOQOXEQcjs.makeAdaptiveLimiterConfig.call(void 0, "aggressive")
3418
+ };
3419
+ var PRESET_CONFIGS = {
3420
+ minimal: MINIMAL_PRESET_CONFIG,
3421
+ balanced: BALANCED_PRESET_CONFIG,
3422
+ default: DEFAULT_PRESET_CONFIG
3423
+ };
3424
+ var defaultHttpClientPreset = "default";
3425
+ function makeDefaultHttpClient(config = {}) {
3426
+ _chunk5YOQOXEQcjs.validateDefaultHttpClientConfig.call(void 0, config);
3427
+ const {
3428
+ preset = defaultHttpClientPreset,
3429
+ compression,
3430
+ middleware = [],
3431
+ ...lifecycleOverrides
3432
+ } = config;
3433
+ const lifecycleConfig = mergeLifecycleConfig(PRESET_CONFIGS[preset], lifecycleOverrides);
3434
+ let wire = makeLifecycleClient(lifecycleConfig);
3435
+ const compressionResult = compression === false || compression === void 0 && preset === "minimal" ? void 0 : makeCompressionMiddleware(compression === void 0 ? void 0 : compression);
3436
+ if (compressionResult) {
3437
+ wire = wire.with(compressionResult.middleware);
3438
+ }
3439
+ for (const mw of middleware) {
3440
+ wire = wire.with(mw);
3441
+ }
3442
+ const features = featureSnapshot(lifecycleConfig, compressionResult !== void 0, middleware.length);
3443
+ return buildDefaultClient(wire, {
3444
+ preset,
3445
+ features,
3446
+ compressionStats: _optionalChain([compressionResult, 'optionalAccess', _95 => _95.stats])
3447
+ });
3448
+ }
3449
+ function buildDefaultClient(wire, meta) {
3450
+ const withPromise = (eff) => _chunkDJQ7OMMBcjs.withAsyncPromise.call(void 0, (e, env) => _chunkWQ5QNU5Rcjs.toPromise.call(void 0, e, env))(eff);
3451
+ const requestRaw = (req) => wire(req);
3452
+ const request = (req) => withPromise(requestRaw(req));
3453
+ const get = (url, init) => request(buildReq("GET", url, init));
3454
+ const post = (url, body, init) => request(buildReq("POST", url, init, body));
3455
+ const getText = (url, init) => {
3456
+ const req = buildReq("GET", url, init);
3457
+ return withPromise(
3458
+ _chunkDJQ7OMMBcjs.mapTryAsync.call(void 0, requestRaw(req), (w) => toResponse(w, w.bodyText))
3459
+ );
3460
+ };
3461
+ const getJson = ((url, init) => {
3462
+ const req = _chunk5YOQOXEQcjs.setHeaderIfMissing.call(void 0, "accept", "application/json")(
3463
+ buildReq("GET", url, init)
3464
+ );
3465
+ return withPromise(
3466
+ _chunkDJQ7OMMBcjs.asyncFlatMap.call(void 0, requestRaw(req), (w) => decodeResponse(w, _optionalChain([init, 'optionalAccess', _96 => _96.schema]), _optionalChain([init, 'optionalAccess', _97 => _97.schemaName])))
3467
+ );
3468
+ });
3469
+ const postJson = ((url, bodyObj, init) => {
3470
+ return withPromise(
3471
+ _chunkDJQ7OMMBcjs.asyncFlatMap.call(void 0,
3472
+ encodeJsonBodyEffect(bodyObj, _optionalChain([init, 'optionalAccess', _98 => _98.bodySchema]), { schemaName: _optionalChain([init, 'optionalAccess', _99 => _99.bodySchemaName]) }),
3473
+ (bodyText) => {
3474
+ const req = _chunk5YOQOXEQcjs.setHeaderIfMissing.call(void 0, "content-type", "application/json")(
3475
+ _chunk5YOQOXEQcjs.setHeaderIfMissing.call(void 0, "accept", "application/json")(
3476
+ buildReq("POST", url, init, bodyText)
3477
+ )
3478
+ );
3479
+ return _chunkDJQ7OMMBcjs.asyncFlatMap.call(void 0, requestRaw(req), (w) => decodeResponse(w, _optionalChain([init, 'optionalAccess', _100 => _100.schema]), _optionalChain([init, 'optionalAccess', _101 => _101.schemaName])));
3480
+ }
3481
+ )
3482
+ );
3483
+ });
3484
+ return {
3485
+ request,
3486
+ get,
3487
+ post,
3488
+ getText,
3489
+ getJson,
3490
+ postJson,
3491
+ with: (mw) => buildDefaultClient(wire.with(mw), {
3492
+ ...meta,
3493
+ features: {
3494
+ ...meta.features,
3495
+ middleware: meta.features.middleware + 1
3496
+ }
3497
+ }),
3498
+ wire,
3499
+ stats: () => wire.stats(),
3500
+ cache: wire.cache,
3501
+ cancelAll: wire.cancelAll,
3502
+ shutdown: wire.shutdown,
3503
+ preset: meta.preset,
3504
+ features: meta.features,
3505
+ ...meta.compressionStats ? {
3506
+ compression: {
3507
+ stats: meta.compressionStats
3508
+ }
3509
+ } : {}
3510
+ };
3511
+ }
3512
+ function buildReq(method, url, init, body) {
3513
+ const { headers, timeoutMs, poolKey, schema: schema2, schemaName, bodySchema, bodySchemaName, ...rest } = _nullishCoalesce(init, () => ( {}));
3514
+ const normalizedHeaders = _chunk5YOQOXEQcjs.normalizeHeadersInit.call(void 0, headers);
3515
+ const req = {
3516
+ method,
3517
+ url,
3518
+ ...body && body.length > 0 ? { body } : {},
3519
+ ...typeof timeoutMs === "number" ? { timeoutMs } : {},
3520
+ ...typeof poolKey === "string" ? { poolKey } : {},
3521
+ init: rest
3522
+ };
3523
+ return normalizedHeaders ? _chunk5YOQOXEQcjs.mergeHeaders.call(void 0, normalizedHeaders)(req) : req;
3524
+ }
3525
+ function toResponse(wire, body) {
3526
+ return {
3527
+ status: wire.status,
3528
+ statusText: wire.statusText,
3529
+ headers: wire.headers,
3530
+ body
3531
+ };
3532
+ }
3533
+ function decodeResponse(wire, schema2, schemaName) {
3534
+ return _chunkDJQ7OMMBcjs.asyncFlatMap.call(void 0,
3535
+ decodeJsonBodyEffect(wire.bodyText, schema2, { schemaName }),
3536
+ (body) => _chunkDJQ7OMMBcjs.asyncSucceed.call(void 0, toResponse(wire, body))
3537
+ );
3538
+ }
3539
+ function mergeLifecycleConfig(defaults, overrides) {
3540
+ return {
3541
+ ...defaults,
3542
+ ...overrides,
3543
+ headers: mergeRecord(defaults.headers, overrides.headers),
3544
+ dedup: mergeLayer(defaults.dedup, overrides.dedup),
3545
+ batch: mergeLayer(defaults.batch, overrides.batch),
3546
+ cache: mergeLayer(defaults.cache, overrides.cache),
3547
+ priority: mergeLayer(defaults.priority, overrides.priority),
3548
+ retry: mergeLayer(defaults.retry, overrides.retry),
3549
+ prewarm: mergeLayer(defaults.prewarm, overrides.prewarm),
3550
+ adaptiveLimiter: mergeAdaptiveLimiterLayer(defaults.adaptiveLimiter, overrides.adaptiveLimiter),
3551
+ pool: mergeLayer(defaults.pool, overrides.pool)
3552
+ };
3553
+ }
3554
+ function mergeRecord(defaults, overrides) {
3555
+ if (!defaults) return overrides;
3556
+ if (!overrides) return defaults;
3557
+ return { ...defaults, ...overrides };
3558
+ }
3559
+ function mergeLayer(defaults, overrides) {
3560
+ if (overrides === void 0) return defaults;
3561
+ if (overrides === false) return false;
3562
+ if (defaults === void 0 || defaults === false) return overrides;
3563
+ return { ...defaults, ...overrides };
3564
+ }
3565
+ function mergeAdaptiveLimiterLayer(defaults, overrides) {
3566
+ if (overrides === void 0) return defaults;
3567
+ if (overrides === false) return false;
3568
+ if (defaults === void 0 || defaults === false) return overrides;
3569
+ if (overrides.preset !== void 0) return overrides;
3570
+ return { ...defaults, ...overrides };
3571
+ }
3572
+ function featureSnapshot(config, compression, middleware) {
3573
+ return Object.freeze({
3574
+ dedup: isEnabled(config.dedup),
3575
+ batch: isEnabled(config.batch),
3576
+ cache: isEnabled(config.cache),
3577
+ priority: isEnabled(config.priority),
3578
+ retry: isEnabled(config.retry),
3579
+ prewarm: isEnabled(config.prewarm),
3580
+ adaptiveLimiter: isEnabled(config.adaptiveLimiter),
3581
+ compression,
3582
+ middleware
3583
+ });
3584
+ }
3585
+ function isEnabled(value) {
3586
+ return value !== void 0 && value !== false;
3587
+ }
3588
+
3589
+ // src/http/builder.ts
3590
+ var DEFAULT_BUILDER_RETRY = {
3591
+ maxRetries: 2,
3592
+ baseDelayMs: 100,
3593
+ maxDelayMs: 1e3
3594
+ };
3595
+ var cloneConfig = (config) => ({
3596
+ ...config,
3597
+ headers: config.headers ? { ...config.headers } : void 0,
3598
+ middleware: config.middleware ? [...config.middleware] : void 0
3599
+ });
3600
+ var freezeConfig = (config) => ({
3601
+ ...config,
3602
+ headers: config.headers ? { ...config.headers } : void 0,
3603
+ middleware: config.middleware ? [...config.middleware] : void 0
3604
+ });
3605
+ var mergeConfig = (current, next) => ({
3606
+ ...current,
3607
+ ...next,
3608
+ headers: {
3609
+ ..._nullishCoalesce(current.headers, () => ( {})),
3610
+ ..._nullishCoalesce(next.headers, () => ( {}))
3611
+ },
3612
+ middleware: [
3613
+ ..._nullishCoalesce(current.middleware, () => ( [])),
3614
+ ..._nullishCoalesce(next.middleware, () => ( []))
3615
+ ]
3616
+ });
3617
+ function makeBuilder(config) {
3618
+ const replace = (patch) => makeBuilder({
3619
+ ...config,
3620
+ ...patch,
3621
+ headers: patch.headers ? { ...patch.headers } : config.headers,
3622
+ middleware: patch.middleware ? [...patch.middleware] : config.middleware
3623
+ });
3624
+ const setLayer = (key, value) => replace({ [key]: value });
3625
+ const middleware = (mw) => makeBuilder({
3626
+ ...config,
3627
+ middleware: [..._nullishCoalesce(config.middleware, () => ( [])), mw]
3628
+ });
3629
+ return Object.freeze({
3630
+ config: () => freezeConfig(config),
3631
+ baseUrl: (baseUrl) => replace({ baseUrl }),
3632
+ header: (name, value) => makeBuilder({
3633
+ ...config,
3634
+ headers: {
3635
+ ..._nullishCoalesce(config.headers, () => ( {})),
3636
+ [name]: value
3637
+ }
3638
+ }),
3639
+ headers: (headers) => makeBuilder({
3640
+ ...config,
3641
+ headers: {
3642
+ ..._nullishCoalesce(config.headers, () => ( {})),
3643
+ ...headers
3644
+ }
3645
+ }),
3646
+ timeoutMs: (timeoutMs) => replace({ timeoutMs }),
3647
+ timeout: (timeoutMs) => replace({ timeoutMs }),
3648
+ preset: (preset) => replace({ preset }),
3649
+ minimal: () => replace({ preset: "minimal" }),
3650
+ balanced: () => replace({ preset: "balanced" }),
3651
+ defaultPreset: () => replace({ preset: "default" }),
3652
+ dedup: (layer = {}) => setLayer("dedup", layer),
3653
+ noDedup: () => setLayer("dedup", false),
3654
+ batch: (layer) => setLayer("batch", layer),
3655
+ noBatch: () => setLayer("batch", false),
3656
+ cache: (layer = {}) => setLayer("cache", layer),
3657
+ noCache: () => setLayer("cache", false),
3658
+ priority: (layer = {}) => setLayer("priority", layer),
3659
+ noPriority: () => setLayer("priority", false),
3660
+ retry: (layer = DEFAULT_BUILDER_RETRY) => setLayer("retry", layer),
3661
+ noRetry: () => setLayer("retry", false),
3662
+ prewarm: (layer = {}) => setLayer("prewarm", layer),
3663
+ noPrewarm: () => setLayer("prewarm", false),
3664
+ adaptiveLimiter: (layer = {}) => setLayer("adaptiveLimiter", layer),
3665
+ adaptiveLimiterPreset: (preset, overrides = {}) => setLayer("adaptiveLimiter", _chunk5YOQOXEQcjs.makeAdaptiveLimiterConfig.call(void 0, preset, overrides)),
3666
+ conservativeLimiter: (overrides = {}) => setLayer("adaptiveLimiter", _chunk5YOQOXEQcjs.makeAdaptiveLimiterConfig.call(void 0, "conservative", overrides)),
3667
+ balancedLimiter: (overrides = {}) => setLayer("adaptiveLimiter", _chunk5YOQOXEQcjs.makeAdaptiveLimiterConfig.call(void 0, "balanced", overrides)),
3668
+ aggressiveLimiter: (overrides = {}) => setLayer("adaptiveLimiter", _chunk5YOQOXEQcjs.makeAdaptiveLimiterConfig.call(void 0, "aggressive", overrides)),
3669
+ noAdaptiveLimiter: () => setLayer("adaptiveLimiter", false),
3670
+ pool: (layer = {}) => setLayer("pool", layer),
3671
+ noPool: () => setLayer("pool", false),
3672
+ compression: (layer = {}) => setLayer("compression", layer),
3673
+ noCompression: () => setLayer("compression", false),
3674
+ middleware,
3675
+ use: middleware,
3676
+ configure: (next) => makeBuilder(mergeConfig(config, next)),
3677
+ build: () => makeDefaultHttpClient(freezeConfig(config)),
3678
+ buildWire: () => makeDefaultHttpClient(freezeConfig(config)).wire
3679
+ });
3680
+ }
3681
+ function httpClientBuilder(config = {}) {
3682
+ return makeBuilder(cloneConfig(config));
3683
+ }
3684
+ var makeHttpClientBuilder = httpClientBuilder;
3685
+ var httpBuilder = httpClientBuilder;
3686
+
3687
+ // src/http/server.ts
3688
+ var _http = require('http');
3689
+ var DEFAULT_MAX_BODY_BYTES = 1024 * 1024;
3690
+ function route(method, path, optionsOrHandler, maybeHandler) {
3691
+ const options = typeof optionsOrHandler === "function" ? {} : optionsOrHandler;
3692
+ const handler = typeof optionsOrHandler === "function" ? optionsOrHandler : maybeHandler;
3693
+ if (!handler) throw new Error(`Missing handler for HTTP route ${method} ${path}`);
3694
+ return {
3695
+ method: normalizeRouteMethod(method),
3696
+ path: normalizeRoutePath(path),
3697
+ options,
3698
+ handler,
3699
+ match: compileRoutePath(path)
3700
+ };
3701
+ }
3702
+ var httpRoute = route;
3703
+ function makeHttpRouter(routes, options = {}) {
3704
+ const normalizedRoutes = routes.map((item) => ({
3705
+ ...item,
3706
+ method: normalizeRouteMethod(item.method),
3707
+ path: normalizeRoutePath(item.path)
3708
+ }));
3709
+ const router = {
3710
+ routes: normalizedRoutes,
3711
+ match: (method, path) => matchRoute(normalizedRoutes, method, path),
3712
+ handle: (request, existingMatch) => {
3713
+ const matched = _nullishCoalesce(existingMatch, () => ( router.match(request.method, request.path)));
3714
+ return handleRouteMatch(request, matched, options);
3715
+ },
3716
+ listen: (serverOptions = {}) => nodeHttpServerResource({
3717
+ ...serverOptions,
3718
+ router
3719
+ })
3720
+ };
3721
+ return router;
3722
+ }
3723
+ function json(body, init = {}) {
3724
+ return {
3725
+ ...init,
3726
+ headers: setHeaderIfMissing2(init.headers, "content-type", "application/json"),
3727
+ body
3728
+ };
3729
+ }
3730
+ function text(body, init = {}) {
3731
+ return {
3732
+ ...init,
3733
+ headers: setHeaderIfMissing2(init.headers, "content-type", "text/plain; charset=utf-8"),
3734
+ body
3735
+ };
3736
+ }
3737
+ function empty(status = 204, headers) {
3738
+ return { status, headers };
3739
+ }
3740
+ function makeRuntimeHealthRoute(options = {}) {
3741
+ const { path = "/health", ...healthOptions } = options;
3742
+ return route(
3743
+ "GET",
3744
+ path,
3745
+ () => _chunkDJQ7OMMBcjs.asyncFlatMap.call(void 0,
3746
+ _chunkJNFRRJYHcjs.makeRuntimeHealth.call(void 0, healthOptions),
3747
+ (report) => _chunkDJQ7OMMBcjs.asyncSucceed.call(void 0, healthReportToServerResponse(report))
3748
+ )
3749
+ );
3750
+ }
3751
+ function makeRuntimeReadinessRoute(options = {}) {
3752
+ return makeRuntimeHealthRoute({
3753
+ ...options,
3754
+ path: _nullishCoalesce(options.path, () => ( "/ready"))
3755
+ });
3756
+ }
3757
+ var runtimeHealthRoute = makeRuntimeHealthRoute;
3758
+ var runtimeReadinessRoute = makeRuntimeReadinessRoute;
3759
+ function withResponseHeader(name, value) {
3760
+ return (next) => (ctx) => _chunkDJQ7OMMBcjs.asyncFlatMap.call(void 0,
3761
+ next(ctx),
3762
+ (response) => _chunkDJQ7OMMBcjs.asyncSucceed.call(void 0, {
3763
+ ...response,
3764
+ headers: setHeaderIfMissing2(response.headers, name, value)
3765
+ })
3766
+ );
3767
+ }
3768
+ function healthReportToServerResponse(report) {
3769
+ return healthHttpResponseToServerResponse(_chunkJNFRRJYHcjs.healthToHttpResponse.call(void 0, report));
3770
+ }
3771
+ function healthHttpResponseToServerResponse(response) {
3772
+ return {
3773
+ status: response.status,
3774
+ headers: response.headers,
3775
+ body: response.body
3776
+ };
3777
+ }
3778
+ function makeNodeHttpServer(options) {
3779
+ return _chunkDJQ7OMMBcjs.asyncEffect.call(void 0, (_env, cb) => {
3780
+ const router = resolveRouter(options.router);
3781
+ const server = _http.createServer.call(void 0, (req, res) => {
3782
+ void handleNodeRequest(req, res, router, options);
3783
+ });
3784
+ let settled = false;
3785
+ let closed = false;
3786
+ const close = () => closeNodeServer(server, options);
3787
+ const fail = (error) => {
3788
+ if (settled) {
3789
+ _optionalChain([options, 'access', _102 => _102.onError, 'optionalCall', _103 => _103(error)]);
3790
+ return;
3791
+ }
3792
+ settled = true;
3793
+ cb({
3794
+ _tag: "Failure",
3795
+ cause: {
3796
+ _tag: "Fail",
3797
+ error: {
3798
+ _tag: "ListenError",
3799
+ error,
3800
+ message: error instanceof Error ? error.message : String(error)
3801
+ }
3802
+ }
3803
+ });
3804
+ };
3805
+ server.once("error", fail);
3806
+ server.once("close", () => {
3807
+ closed = true;
3808
+ });
3809
+ server.listen(_nullishCoalesce(options.port, () => ( 0)), options.host, () => {
3810
+ if (settled) return;
3811
+ settled = true;
3812
+ server.off("error", fail);
3813
+ server.on("error", (error) => _optionalChain([options, 'access', _104 => _104.onError, 'optionalCall', _105 => _105(error)]));
3814
+ cb({
3815
+ _tag: "Success",
3816
+ value: {
3817
+ server,
3818
+ router,
3819
+ address: () => server.address(),
3820
+ url: () => serverUrl(server),
3821
+ close
3822
+ }
3823
+ });
3824
+ });
3825
+ return () => {
3826
+ if (closed) return;
3827
+ void close().catch((error) => _optionalChain([options, 'access', _106 => _106.onError, 'optionalCall', _107 => _107(error)]));
3828
+ };
3829
+ });
3830
+ }
3831
+ function nodeHttpServerResource(options) {
3832
+ return _chunkJF4XXPZ5cjs.resource.call(void 0,
3833
+ makeNodeHttpServer(options),
3834
+ (handle) => _chunkDJQ7OMMBcjs.asyncEffect.call(void 0, (_env, cb) => {
3835
+ handle.close().then(() => cb({ _tag: "Success", value: void 0 })).catch(() => cb({ _tag: "Success", value: void 0 }));
3836
+ })
3837
+ );
3838
+ }
3839
+ var makeNodeHttpServerResource = nodeHttpServerResource;
3840
+ var makeHttpServerResource = nodeHttpServerResource;
3841
+ function handleRouteMatch(request, match, options) {
3842
+ if (match._tag === "NotFound") {
3843
+ return _chunkDJQ7OMMBcjs.asyncSucceed.call(void 0, json({ error: "Not Found" }, { status: 404 }));
3844
+ }
3845
+ if (match._tag === "MethodNotAllowed") {
3846
+ return _chunkDJQ7OMMBcjs.asyncSucceed.call(void 0, json(
3847
+ { error: "Method Not Allowed", allowed: match.allowed.filter((method) => method !== "ALL") },
3848
+ { status: 405, headers: { allow: match.allowed.filter((method) => method !== "ALL").join(", ") } }
3849
+ ));
3850
+ }
3851
+ const routeWithParams = match.route;
3852
+ const prepared = prepareRouteContext(request, match.params, routeWithParams);
3853
+ if (!prepared.success) return _chunkDJQ7OMMBcjs.asyncSucceed.call(void 0, validationErrorResponse(prepared.error));
3854
+ const handler = composeMiddleware(
3855
+ [..._nullishCoalesce(options.middleware, () => ( [])), ..._nullishCoalesce(routeWithParams.options.middleware, () => ( []))],
3856
+ routeWithParams.handler
3857
+ );
3858
+ let handled;
3859
+ try {
3860
+ handled = handler(prepared.ctx);
3861
+ } catch (error) {
3862
+ return _chunkDJQ7OMMBcjs.asyncSucceed.call(void 0, handlerErrorResponse(error, options));
3863
+ }
3864
+ return _chunkDJQ7OMMBcjs.asyncFold.call(void 0,
3865
+ handled,
3866
+ (error) => _chunkDJQ7OMMBcjs.asyncSucceed.call(void 0, handlerErrorResponse(error, options)),
3867
+ (response) => {
3868
+ const normalized = normalizeServerResponse(response);
3869
+ const validation = validateResponseBody(normalized, routeWithParams);
3870
+ return _chunkDJQ7OMMBcjs.asyncSucceed.call(void 0, validation.success ? normalized : validationErrorResponse(validation.error));
3871
+ }
3872
+ );
3873
+ }
3874
+ function prepareRouteContext(request, params, routeWithSchemas) {
3875
+ const paramsResult = validatePart(params, routeWithSchemas.options.params, {
3876
+ phase: "request",
3877
+ schemaName: _nullishCoalesce(routeWithSchemas.options.paramsSchemaName, () => ( "params")),
3878
+ body: JSON.stringify(params)
3879
+ });
3880
+ if (!paramsResult.success) return paramsResult;
3881
+ const queryResult = validatePart(request.query, routeWithSchemas.options.query, {
3882
+ phase: "request",
3883
+ schemaName: _nullishCoalesce(routeWithSchemas.options.querySchemaName, () => ( "query")),
3884
+ body: JSON.stringify(request.query)
3885
+ });
3886
+ if (!queryResult.success) return queryResult;
3887
+ const bodyInput = routeWithSchemas.options.body ? parseJsonRequestBody(request.bodyText) : { success: true, data: request.bodyText.length > 0 ? request.bodyText : void 0 };
3888
+ if (!bodyInput.success) {
3889
+ return {
3890
+ success: false,
3891
+ error: makeValidationError({
3892
+ message: bodyInput.message,
3893
+ body: request.bodyText,
3894
+ phase: "request",
3895
+ schema: _nullishCoalesce(routeWithSchemas.options.bodySchemaName, () => ( "body")),
3896
+ issues: [_chunkSPUEME2Bcjs.makeSchemaIssue.call(void 0, [], "valid JSON", request.bodyText, bodyInput.message)]
3897
+ })
3898
+ };
3899
+ }
3900
+ const bodyResult = validatePart(bodyInput.data, routeWithSchemas.options.body, {
3901
+ phase: "request",
3902
+ schemaName: _nullishCoalesce(routeWithSchemas.options.bodySchemaName, () => ( "body")),
3903
+ body: request.bodyText
3904
+ });
3905
+ if (!bodyResult.success) return bodyResult;
3906
+ return {
3907
+ success: true,
3908
+ ctx: {
3909
+ ...request,
3910
+ route: routeWithSchemas.path,
3911
+ params: paramsResult.data,
3912
+ query: queryResult.data,
3913
+ body: bodyResult.data
3914
+ }
3915
+ };
3916
+ }
3917
+ function validateResponseBody(response, routeWithSchemas) {
3918
+ const schema2 = routeWithSchemas.options.response;
3919
+ if (!schema2) return { success: true };
3920
+ const result = _chunkSPUEME2Bcjs.validateValue.call(void 0, response.body, schema2);
3921
+ if (result.success) return { success: true };
3922
+ return {
3923
+ success: false,
3924
+ error: makeValidationError({
3925
+ message: `HTTP response failed validation: ${_chunkSPUEME2Bcjs.formatIssues.call(void 0, result.issues)}`,
3926
+ body: previewJson2(response.body),
3927
+ phase: "response",
3928
+ schema: _nullishCoalesce(routeWithSchemas.options.responseSchemaName, () => ( "response")),
3929
+ issues: result.issues
3930
+ })
3931
+ };
3932
+ }
3933
+ function validatePart(input, schema2, options) {
3934
+ if (!schema2) return { success: true, data: input };
3935
+ const result = _chunkSPUEME2Bcjs.validateValue.call(void 0, input, schema2);
3936
+ if (result.success) return { success: true, data: result.data };
3937
+ return {
3938
+ success: false,
3939
+ error: makeValidationError({
3940
+ message: `HTTP ${options.schemaName} failed validation: ${_chunkSPUEME2Bcjs.formatIssues.call(void 0, result.issues)}`,
3941
+ body: options.body,
3942
+ phase: options.phase,
3943
+ schema: options.schemaName,
3944
+ issues: result.issues
3945
+ })
3946
+ };
3947
+ }
3948
+ function resolveRouter(input) {
3949
+ return isHttpRouter(input) ? input : makeHttpRouter(input);
3950
+ }
3951
+ function isHttpRouter(value) {
3952
+ return !Array.isArray(value) && typeof value === "object" && value !== null && typeof value.match === "function" && typeof value.handle === "function";
3953
+ }
3954
+ function makeValidationError(input) {
3955
+ return {
3956
+ _tag: "ValidationError",
3957
+ message: input.message,
3958
+ body: input.body,
3959
+ phase: input.phase,
3960
+ schema: input.schema,
3961
+ issues: input.issues
3962
+ };
3963
+ }
3964
+ function validationErrorResponse(error) {
3965
+ return json(
3966
+ {
3967
+ error: error.phase === "response" ? "Response validation failed" : "Request validation failed",
3968
+ message: error.message,
3969
+ phase: error.phase,
3970
+ schema: error.schema,
3971
+ issues: error.issues
3972
+ },
3973
+ { status: error.phase === "response" ? 500 : 400 }
3974
+ );
3975
+ }
3976
+ function handlerErrorResponse(error, options) {
3977
+ return json(
3978
+ {
3979
+ error: "Internal Server Error",
3980
+ ...options.includeErrorDetails ? { message: error instanceof Error ? error.message : String(error) } : {}
3981
+ },
3982
+ { status: 500 }
3983
+ );
3984
+ }
3985
+ async function handleNodeRequest(req, res, router, options) {
3986
+ try {
3987
+ const bodyText = await readNodeRequestBody(req, _nullishCoalesce(options.maxBodyBytes, () => ( DEFAULT_MAX_BODY_BYTES)));
3988
+ const serverRequest = nodeRequestToServerRequest(req, bodyText);
3989
+ const match = router.match(serverRequest.method, serverRequest.path);
3990
+ const effect = router.handle(serverRequest, match);
3991
+ const routeLabel = match._tag === "Match" || match._tag === "MethodNotAllowed" ? match.route.path : void 0;
3992
+ const observedInput = {
3993
+ method: serverRequest.method,
3994
+ route: routeLabel,
3995
+ target: serverRequest.target,
3996
+ headers: serverRequest.headers
3997
+ };
3998
+ const response = options.observability ? (await _chunkJNFRRJYHcjs.runObservedHttpServerEffect.call(void 0,
3999
+ options.observability,
4000
+ observedInput,
4001
+ effect,
4002
+ {
4003
+ statusCode: (value) => _nullishCoalesce(value.status, () => ( 200)),
4004
+ ..._nullishCoalesce(options.observabilityOptions, () => ( {}))
4005
+ },
4006
+ options.env,
4007
+ options.runtimeOptions
4008
+ )).value : await (_nullishCoalesce(options.runtime, () => ( new (0, _chunkWQ5QNU5Rcjs.Runtime)({
4009
+ env: _nullishCoalesce(options.env, () => ( {})),
4010
+ ..._nullishCoalesce(options.runtimeOptions, () => ( {}))
4011
+ })))).toPromise(effect);
4012
+ writeNodeResponse(res, response);
4013
+ } catch (error) {
4014
+ _optionalChain([options, 'access', _108 => _108.onError, 'optionalCall', _109 => _109(error)]);
4015
+ writeNodeResponse(res, json({ error: "Internal Server Error" }, { status: 500 }));
4016
+ }
4017
+ }
4018
+ function nodeRequestToServerRequest(req, bodyText) {
4019
+ const headers = normalizeNodeHeaders(req.headers);
4020
+ const target = _nullishCoalesce(req.url, () => ( "/"));
4021
+ const parsed = parseRequestUrl(target, headers.host);
4022
+ return {
4023
+ method: (_nullishCoalesce(req.method, () => ( "GET"))).toUpperCase(),
4024
+ url: parsed.toString(),
4025
+ path: parsed.pathname,
4026
+ target,
4027
+ headers,
4028
+ query: queryToObject(parsed.searchParams),
4029
+ params: {},
4030
+ bodyText,
4031
+ raw: req
4032
+ };
4033
+ }
4034
+ function writeNodeResponse(res, response) {
4035
+ const normalized = normalizeServerResponse(response);
4036
+ const encoded = encodeResponseBody(normalized);
4037
+ res.statusCode = _nullishCoalesce(normalized.status, () => ( 200));
4038
+ for (const [name, value] of Object.entries(encoded.headers)) {
4039
+ res.setHeader(name, value);
4040
+ }
4041
+ if (encoded.body === void 0) {
4042
+ res.end();
4043
+ return;
4044
+ }
4045
+ res.end(encoded.body);
4046
+ }
4047
+ function normalizeServerResponse(response) {
4048
+ if (isServerResponse(response)) {
4049
+ return { status: 200, ...response };
4050
+ }
4051
+ return { status: 200, body: response };
4052
+ }
4053
+ function isServerResponse(value) {
4054
+ return typeof value === "object" && value !== null && ("status" in value || "headers" in value || "body" in value);
4055
+ }
4056
+ function encodeResponseBody(response) {
4057
+ const headers = { ..._nullishCoalesce(response.headers, () => ( {})) };
4058
+ const body = response.body;
4059
+ if (body === void 0 || response.status === 204 || response.status === 304) return { headers };
4060
+ if (typeof body === "string") {
4061
+ return {
4062
+ headers: setHeaderIfMissing2(headers, "content-type", "text/plain; charset=utf-8"),
4063
+ body
4064
+ };
4065
+ }
4066
+ if (body instanceof Uint8Array) return { headers, body };
4067
+ if (body instanceof ArrayBuffer) return { headers, body: new Uint8Array(body) };
4068
+ return {
4069
+ headers: setHeaderIfMissing2(headers, "content-type", "application/json"),
4070
+ body: JSON.stringify(body)
4071
+ };
4072
+ }
4073
+ function readNodeRequestBody(req, maxBytes) {
4074
+ return new Promise((resolve, reject) => {
4075
+ const chunks = [];
4076
+ let total = 0;
4077
+ req.on("data", (chunk) => {
4078
+ total += chunk.byteLength;
4079
+ if (total > maxBytes) {
4080
+ reject(new Error(`HTTP request body exceeded ${maxBytes} bytes`));
4081
+ req.destroy();
4082
+ return;
4083
+ }
4084
+ chunks.push(chunk);
4085
+ });
4086
+ req.on("error", reject);
4087
+ req.on("end", () => resolve(Buffer.concat(chunks).toString("utf8")));
4088
+ });
4089
+ }
4090
+ function closeNodeServer(server, options) {
4091
+ return new Promise((resolve, reject) => {
4092
+ const startedAt = Date.now();
4093
+ const schedule = _nullishCoalesce(options.shutdownPollSchedule, () => ( defaultShutdownPollSchedule(_nullishCoalesce(options.gracefulShutdownMs, () => ( 5e3)))));
4094
+ let state = schedule.initial();
4095
+ let finished = false;
4096
+ const done = (error) => {
4097
+ if (finished) return;
4098
+ finished = true;
4099
+ if (timer) clearTimeout(timer);
4100
+ if (error && error.message !== "Server is not running.") reject(error);
4101
+ else resolve();
4102
+ };
4103
+ let timer;
4104
+ const poll = () => {
4105
+ if (finished) return;
4106
+ if (!server.listening) {
4107
+ done();
4108
+ return;
4109
+ }
4110
+ const [decision, nextState] = schedule.step(state, {
4111
+ listening: server.listening,
4112
+ elapsedMs: Date.now() - startedAt
4113
+ });
4114
+ state = nextState;
4115
+ if (!decision.continue) {
4116
+ _optionalChain([server, 'access', _110 => _110.closeAllConnections, 'optionalCall', _111 => _111()]);
4117
+ done();
4118
+ return;
4119
+ }
4120
+ timer = setTimeout(poll, decision.delayMs);
4121
+ _optionalChain([timer, 'access', _112 => _112.unref, 'optionalCall', _113 => _113()]);
4122
+ };
4123
+ server.close(done);
4124
+ poll();
4125
+ });
4126
+ }
4127
+ function defaultShutdownPollSchedule(maxMs) {
4128
+ const intervalMs = 25;
4129
+ return _chunkJF4XXPZ5cjs.take.call(void 0, _chunkJF4XXPZ5cjs.fixed.call(void 0, intervalMs), Math.max(1, Math.ceil(Math.max(0, maxMs) / intervalMs)));
4130
+ }
4131
+ function matchRoute(routes, method, path) {
4132
+ const requestedMethod = method.toUpperCase();
4133
+ const allowed = [];
4134
+ let methodMismatch;
4135
+ for (const candidate of routes) {
4136
+ const params = candidate.match(path);
4137
+ if (!params) continue;
4138
+ if (candidate.method === "ALL" || candidate.method === requestedMethod) {
4139
+ return { _tag: "Match", route: candidate, params };
4140
+ }
4141
+ methodMismatch ??= candidate;
4142
+ allowed.push(candidate.method);
4143
+ }
4144
+ if (methodMismatch) {
4145
+ return { _tag: "MethodNotAllowed", route: methodMismatch, allowed };
4146
+ }
4147
+ return { _tag: "NotFound" };
4148
+ }
4149
+ function composeMiddleware(middleware, handler) {
4150
+ return middleware.reduceRight((next, current) => current(next), handler);
4151
+ }
4152
+ function parseJsonRequestBody(bodyText) {
4153
+ if (bodyText.length === 0) return { success: true, data: void 0 };
4154
+ try {
4155
+ return { success: true, data: JSON.parse(bodyText) };
4156
+ } catch (error) {
4157
+ return {
4158
+ success: false,
4159
+ message: `JSON parse error: ${error instanceof Error ? error.message : String(error)}`
4160
+ };
4161
+ }
4162
+ }
4163
+ function compileRoutePath(path) {
4164
+ const keys = [];
4165
+ const normalized = normalizeRoutePath(path);
4166
+ if (normalized === "/") {
4167
+ return (input) => input === "/" ? {} : void 0;
4168
+ }
4169
+ const source = normalized.split("/").filter(Boolean).map((segment) => {
4170
+ if (segment === "*") {
4171
+ keys.push("*");
4172
+ return "(.*)";
4173
+ }
4174
+ if (segment.startsWith(":")) {
4175
+ keys.push(segment.slice(1));
4176
+ return "([^/]+)";
4177
+ }
4178
+ return escapeRegExp(segment);
4179
+ }).join("/");
4180
+ const regex = new RegExp(`^/${source}/?$`);
4181
+ return (input) => {
4182
+ const match = regex.exec(input);
4183
+ if (!match) return void 0;
4184
+ const params = {};
4185
+ keys.forEach((key, index) => {
4186
+ params[key] = decodePathPart(_nullishCoalesce(match[index + 1], () => ( "")));
4187
+ });
4188
+ return params;
4189
+ };
4190
+ }
4191
+ function normalizeRouteMethod(method) {
4192
+ const upper = method.toUpperCase();
4193
+ return upper === "ALL" ? "ALL" : upper;
4194
+ }
4195
+ function normalizeRoutePath(path) {
4196
+ if (!path || path === "*") return "/";
4197
+ const withSlash = path.startsWith("/") ? path : `/${path}`;
4198
+ return withSlash.length > 1 ? withSlash.replace(/\/+$/, "") : withSlash;
4199
+ }
4200
+ function parseRequestUrl(target, host) {
4201
+ try {
4202
+ return new URL(target, `http://${_nullishCoalesce(host, () => ( "localhost"))}`);
4203
+ } catch (e27) {
4204
+ return new URL("/", `http://${_nullishCoalesce(host, () => ( "localhost"))}`);
4205
+ }
4206
+ }
4207
+ function queryToObject(searchParams) {
4208
+ const out = {};
4209
+ for (const [key, value] of searchParams.entries()) {
4210
+ const current = out[key];
4211
+ if (current === void 0) {
4212
+ out[key] = value;
4213
+ } else if (Array.isArray(current)) {
4214
+ current.push(value);
4215
+ } else {
4216
+ out[key] = [current, value];
4217
+ }
4218
+ }
4219
+ return out;
4220
+ }
4221
+ function normalizeNodeHeaders(headers) {
4222
+ const out = {};
4223
+ for (const [key, value] of Object.entries(headers)) {
4224
+ if (value === void 0) continue;
4225
+ out[key.toLowerCase()] = Array.isArray(value) ? value.join(",") : value;
4226
+ }
4227
+ return out;
4228
+ }
4229
+ function setHeaderIfMissing2(headers, name, value) {
4230
+ const out = { ..._nullishCoalesce(headers, () => ( {})) };
4231
+ const existing = Object.keys(out).find((key) => key.toLowerCase() === name.toLowerCase());
4232
+ if (!existing) out[name] = value;
4233
+ return out;
4234
+ }
4235
+ function serverUrl(server) {
4236
+ const address = server.address();
4237
+ if (!address || typeof address === "string") return void 0;
4238
+ const host = address.address === "::" || address.address === "0.0.0.0" ? "127.0.0.1" : address.address;
4239
+ return `http://${host}:${address.port}`;
4240
+ }
4241
+ function previewJson2(value) {
4242
+ try {
4243
+ return JSON.stringify(value);
4244
+ } catch (e28) {
4245
+ return "[unserializable]";
4246
+ }
4247
+ }
4248
+ function decodePathPart(value) {
4249
+ try {
4250
+ return decodeURIComponent(value);
4251
+ } catch (e29) {
4252
+ return value;
4253
+ }
4254
+ }
4255
+ function escapeRegExp(value) {
4256
+ return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
4257
+ }
4258
+
4259
+
4260
+
4261
+
4262
+
4263
+
4264
+
4265
+
4266
+
4267
+
4268
+
4269
+
4270
+
4271
+
4272
+
4273
+
4274
+
4275
+
4276
+
4277
+
4278
+
4279
+
4280
+
4281
+
4282
+
4283
+
4284
+
4285
+
4286
+
4287
+
4288
+
4289
+
4290
+
4291
+
4292
+
4293
+
4294
+
4295
+
4296
+
4297
+
4298
+
4299
+
4300
+
4301
+
4302
+
4303
+
4304
+
4305
+
4306
+
4307
+
4308
+
4309
+
4310
+
4311
+
4312
+
4313
+
4314
+
4315
+
3398
4316
 
3399
4317
 
3400
4318
 
@@ -3440,4 +4358,4 @@ function emit2(config, event) {
3440
4358
 
3441
4359
 
3442
4360
 
3443
- exports.DEFAULT_CACHE_RELEVANT_HEADERS = DEFAULT_CACHE_RELEVANT_HEADERS; exports.HttpConcurrencyPool = HttpConcurrencyPool; exports.LRUCache = LRUCache; exports.LifecycleStatsTracker = LifecycleStatsTracker; exports.PriorityQueue = PriorityQueue; exports.SEPARATOR = SEPARATOR; exports.SUPPORTED_ENCODINGS = SUPPORTED_ENCODINGS; exports.backoffDelayMs = backoffDelayMs; exports.clampPriority = clampPriority; exports.computeCacheKey = computeCacheKey; exports.decorate = decorate; exports.defaultRetryOnError = defaultRetryOnError; exports.defaultRetryOnStatus = defaultRetryOnStatus; exports.defaultRetryableMethods = defaultRetryableMethods; exports.httpClient = httpClient; exports.httpClientStream = httpClientStream; exports.httpClientWithMeta = httpClientWithMeta; exports.makeCompressionMiddleware = makeCompressionMiddleware; exports.makeHttp = makeHttp; exports.makeHttpClient = makeHttpClient; exports.makeHttpStream = makeHttpStream; exports.makeLifecycleClient = makeLifecycleClient; exports.makeRequestCompressionMiddleware = makeRequestCompressionMiddleware; exports.makeResponseCompressionMiddleware = makeResponseCompressionMiddleware; exports.normalizeHeadersInit = normalizeHeadersInit; exports.normalizeRetryBudget = normalizeRetryBudget; exports.parseCacheKey = parseCacheKey; exports.prewarmConnections = prewarmConnections; exports.prewarmHttpConnections = prewarmHttpConnections; exports.resolveHttpPoolKey = resolveHttpPoolKey; exports.retryAfterMs = retryAfterMs; exports.validatedJson = validatedJson; exports.withAuth = withAuth; exports.withCache = withCache; exports.withCircuitBreaker = withCircuitBreaker; exports.withConnectionPrewarming = withConnectionPrewarming; exports.withDedup = withDedup; exports.withLogging = withLogging; exports.withMiddleware = withMiddleware; exports.withPriority = withPriority; exports.withRequestBatching = withRequestBatching; exports.withResponseTransform = withResponseTransform; exports.withRetry = withRetry; exports.withRetryStream = withRetryStream; exports.withTracing = withTracing;
4361
+ exports.AdaptiveLimiter = _chunk5YOQOXEQcjs.AdaptiveLimiter; exports.ConfigValidationError = _chunkSPUEME2Bcjs.ConfigValidationError; exports.DEFAULT_CACHE_RELEVANT_HEADERS = DEFAULT_CACHE_RELEVANT_HEADERS; exports.EmaComputer = _chunk5YOQOXEQcjs.EmaComputer; exports.HttpConcurrencyPool = _chunk5YOQOXEQcjs.HttpConcurrencyPool; exports.LRUCache = LRUCache; exports.LatencyWindow = _chunk5YOQOXEQcjs.LatencyWindow; exports.LifecycleStatsTracker = LifecycleStatsTracker; exports.PriorityQueue = PriorityQueue; exports.SEPARATOR = SEPARATOR; exports.SUPPORTED_ENCODINGS = SUPPORTED_ENCODINGS; exports.Schema = _chunkSPUEME2Bcjs.Schema; exports.SchemaValidationException = _chunkSPUEME2Bcjs.SchemaValidationException; exports.adaptiveLimiterPresets = _chunk5YOQOXEQcjs.adaptiveLimiterPresets; exports.backoffDelayMs = _chunk5YOQOXEQcjs.backoffDelayMs; exports.clampPriority = clampPriority; exports.computeCacheKey = computeCacheKey; exports.computeGradient = _chunk5YOQOXEQcjs.computeGradient; exports.computeNewLimit = _chunk5YOQOXEQcjs.computeNewLimit; exports.decodeJsonBody = decodeJsonBody; exports.decodeJsonBodyEffect = decodeJsonBodyEffect; exports.decorate = _chunk5YOQOXEQcjs.decorate; exports.defaultHttpClientPreset = defaultHttpClientPreset; exports.defaultRetryOnError = _chunk5YOQOXEQcjs.defaultRetryOnError; exports.defaultRetryOnStatus = _chunk5YOQOXEQcjs.defaultRetryOnStatus; exports.defaultRetryableMethods = _chunk5YOQOXEQcjs.defaultRetryableMethods; exports.detectPlatform = detectPlatform; exports.empty = empty; exports.encodeJsonBodyEffect = encodeJsonBodyEffect; exports.executeProbe = executeProbe; exports.formatHttpError = formatHttpError; exports.formatIssues = _chunkSPUEME2Bcjs.formatIssues; exports.httpBuilder = httpBuilder; exports.httpClient = httpClient; exports.httpClientBuilder = httpClientBuilder; exports.httpClientStream = httpClientStream; exports.httpClientWithMeta = httpClientWithMeta; exports.httpRoute = httpRoute; exports.isCircuitBreakerOpen = isCircuitBreakerOpen; exports.isHttpError = isHttpError; exports.isKnownHttpError = isKnownHttpError; exports.isSchema = _chunkSPUEME2Bcjs.isSchema; exports.isValidationError = isValidationError; exports.json = json; exports.makeAdaptiveLimiterConfig = _chunk5YOQOXEQcjs.makeAdaptiveLimiterConfig; exports.makeBudgetSemaphore = makeBudgetSemaphore; exports.makeCompressionMiddleware = makeCompressionMiddleware; exports.makeConnectionStateMap = makeConnectionStateMap; exports.makeDefaultHttpClient = makeDefaultHttpClient; exports.makeHttp = _chunk5YOQOXEQcjs.makeHttp; exports.makeHttpClient = makeHttpClient; exports.makeHttpClientBuilder = makeHttpClientBuilder; exports.makeHttpRouter = makeHttpRouter; exports.makeHttpServerResource = makeHttpServerResource; exports.makeHttpStream = _chunk5YOQOXEQcjs.makeHttpStream; exports.makeLifecycleClient = makeLifecycleClient; exports.makeNodeHttpServer = makeNodeHttpServer; exports.makeNodeHttpServerResource = makeNodeHttpServerResource; exports.makePrewarmManager = makePrewarmManager; exports.makeRequestCompressionMiddleware = makeRequestCompressionMiddleware; exports.makeResponseCompressionMiddleware = makeResponseCompressionMiddleware; exports.makeRuntimeHealthRoute = makeRuntimeHealthRoute; exports.makeRuntimeReadinessRoute = makeRuntimeReadinessRoute; exports.makeSchemaIssue = _chunkSPUEME2Bcjs.makeSchemaIssue; exports.matchHttpError = matchHttpError; exports.nodeHttpServerResource = nodeHttpServerResource; exports.normalizeHeadersInit = _chunk5YOQOXEQcjs.normalizeHeadersInit; exports.normalizeRetryBudget = _chunk5YOQOXEQcjs.normalizeRetryBudget; exports.parseCacheKey = parseCacheKey; exports.parseConfig = _chunkSPUEME2Bcjs.parseConfig; exports.prewarmConnections = prewarmConnections; exports.prewarmHttpConnections = prewarmHttpConnections; exports.resolveConfig = _chunk5YOQOXEQcjs.resolveConfig; exports.resolveHttpPoolKey = _chunk5YOQOXEQcjs.resolveHttpPoolKey; exports.retryAfterMs = _chunk5YOQOXEQcjs.retryAfterMs; exports.route = route; exports.runtimeHealthRoute = runtimeHealthRoute; exports.runtimeReadinessRoute = runtimeReadinessRoute; exports.s = _chunkSPUEME2Bcjs.s; exports.schema = _chunkSPUEME2Bcjs.schema; exports.text = text; exports.validateConfig = _chunk5YOQOXEQcjs.validateConfig; exports.validateFetchAvailable = validateFetchAvailable; exports.validateOrigin = validateOrigin; exports.validateValue = _chunkSPUEME2Bcjs.validateValue; exports.validatedJson = validatedJson; exports.validatedJsonResponse = validatedJsonResponse; exports.withAuth = withAuth; exports.withBatch = withBatch; exports.withCache = withCache; exports.withCircuitBreaker = withCircuitBreaker; exports.withConnectionPrewarming = withConnectionPrewarming; exports.withDedup = withDedup; exports.withLogging = withLogging; exports.withMiddleware = _chunk5YOQOXEQcjs.withMiddleware; exports.withPriority = withPriority; exports.withRequestBatching = withRequestBatching; exports.withResponseHeader = withResponseHeader; exports.withResponseTransform = withResponseTransform; exports.withRetry = _chunk5YOQOXEQcjs.withRetry; exports.withRetryStream = _chunk5YOQOXEQcjs.withRetryStream; exports.withTracing = withTracing;