brass-runtime 1.17.0 → 1.18.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 (120) hide show
  1. package/README.md +36 -3
  2. package/dist/agent/cli/main.cjs +31 -32
  3. package/dist/agent/cli/main.js +3 -4
  4. package/dist/agent/cli/main.mjs +3 -4
  5. package/dist/agent/index.cjs +4 -5
  6. package/dist/agent/index.d.ts +1 -1
  7. package/dist/agent/index.js +3 -4
  8. package/dist/agent/index.mjs +3 -4
  9. package/dist/{chunk-GYM3LLGS.mjs → chunk-2QNREG6K.mjs} +188 -5
  10. package/dist/{chunk-4ROBZFL6.cjs → chunk-2SLT3X6G.cjs} +6 -8
  11. package/dist/{chunk-KZJQ723N.cjs → chunk-3PFZGP23.cjs} +13 -15
  12. package/dist/{chunk-VWIPB6I5.js → chunk-3PHU7FWS.js} +528 -23
  13. package/dist/{chunk-BKK77SBA.js → chunk-4YQHPIWJ.js} +32 -11
  14. package/dist/chunk-5XADBMSU.cjs +33 -0
  15. package/dist/{chunk-DNFJLJMW.mjs → chunk-6MLAZPBL.mjs} +48 -24
  16. package/dist/chunk-7TKI527D.cjs +123 -0
  17. package/dist/{chunk-AGR5B2BC.cjs → chunk-7TXQJFZX.cjs} +564 -12
  18. package/dist/{chunk-RKGKFN2A.js → chunk-AADFFVYS.js} +1 -1
  19. package/dist/{chunk-52PPNNI4.cjs → chunk-AJMKZXRB.cjs} +2 -2
  20. package/dist/{chunk-3AYM6WPJ.js → chunk-BG5RNEA2.js} +20 -299
  21. package/dist/{chunk-2HQTDLHF.mjs → chunk-ELLF55ER.mjs} +555 -3
  22. package/dist/{chunk-EOC4UHBS.mjs → chunk-G5JTCFMI.mjs} +2 -2
  23. package/dist/chunk-H5GYX7RZ.js +6126 -0
  24. package/dist/{chunk-C3MDXTRZ.js → chunk-HCJ4S3YB.js} +48 -24
  25. package/dist/{chunk-6IXXWIUM.js → chunk-IBRHSH5H.js} +555 -3
  26. package/dist/{chunk-Q2I37RP3.cjs → chunk-IFRBVMWJ.cjs} +44 -323
  27. package/dist/{chunk-52OB2ROS.js → chunk-ITG6I7ZS.js} +2 -4
  28. package/dist/chunk-ITZQ526U.mjs +33 -0
  29. package/dist/{chunk-7JIJOVCT.js → chunk-JH4GI3DW.js} +2 -4
  30. package/dist/{chunk-F6XWZQY4.cjs → chunk-KHACHFBQ.cjs} +583 -78
  31. package/dist/{chunk-4P2HHGAX.mjs → chunk-KRYP6CAE.mjs} +32 -11
  32. package/dist/chunk-KTGDLBLD.mjs +123 -0
  33. package/dist/{chunk-WBGRHGBP.cjs → chunk-LXBU5E77.cjs} +114 -93
  34. package/dist/{chunk-PD4EJTQC.cjs → chunk-N6QNSTWD.cjs} +5 -5
  35. package/dist/{chunk-6RY2FFN4.mjs → chunk-OI4ESUMC.mjs} +9 -11
  36. package/dist/{chunk-EJ6BPYVR.mjs → chunk-OT2TESZU.mjs} +1 -1
  37. package/dist/{chunk-7X3K5RMS.js → chunk-PSEU65ND.js} +9 -11
  38. package/dist/{chunk-SK7UZRNI.mjs → chunk-QCOLAHU3.mjs} +528 -23
  39. package/dist/{chunk-KH4SYAOS.mjs → chunk-QZ6QFJNM.mjs} +20 -299
  40. package/dist/{chunk-MBEJI5HF.mjs → chunk-R6WDSZA6.mjs} +2 -4
  41. package/dist/{chunk-FHQGHPMO.mjs → chunk-RREBJX2S.mjs} +2 -4
  42. package/dist/{chunk-5QC7LRZ3.js → chunk-S4HHFUYP.js} +2 -2
  43. package/dist/{chunk-GLE2WY7Z.cjs → chunk-SSQJKDN3.cjs} +194 -11
  44. package/dist/{chunk-CZIVE6NT.cjs → chunk-UUMKZJRJ.cjs} +48 -24
  45. package/dist/chunk-VIFA4DPN.cjs +6126 -0
  46. package/dist/chunk-W6WR37HN.js +33 -0
  47. package/dist/{chunk-FH2X7BVP.js → chunk-XSAHV5HQ.js} +188 -5
  48. package/dist/chunk-YM3EDNYD.js +123 -0
  49. package/dist/{chunk-7ZPEZ57L.cjs → chunk-YTX2JYYP.cjs} +18 -20
  50. package/dist/chunk-Z3PSSXP3.mjs +6126 -0
  51. package/dist/core/index.cjs +31 -9
  52. package/dist/core/index.d.ts +19 -152
  53. package/dist/core/index.js +80 -58
  54. package/dist/core/index.mjs +80 -58
  55. package/dist/defaultClient-DhpCQW9m.d.ts +1623 -0
  56. package/dist/{effect-DIUHZ9IN.d.ts → effect-CtUDl5M5.d.ts} +1 -1
  57. package/dist/http/index.cjs +202 -59
  58. package/dist/http/index.d.ts +55 -819
  59. package/dist/http/index.js +216 -73
  60. package/dist/http/index.mjs +216 -73
  61. package/dist/http/testing.cjs +31 -10
  62. package/dist/http/testing.d.ts +16 -5
  63. package/dist/http/testing.js +29 -8
  64. package/dist/http/testing.mjs +29 -8
  65. package/dist/index.cjs +110 -88
  66. package/dist/index.d.ts +9 -8
  67. package/dist/index.js +81 -59
  68. package/dist/index.mjs +81 -59
  69. package/dist/{schedule-CK3Ml_7p.d.ts → layer-BalPI6cN.d.ts} +176 -2
  70. package/dist/observability/index.cjs +20 -7
  71. package/dist/observability/index.d.ts +32 -8
  72. package/dist/observability/index.js +19 -6
  73. package/dist/observability/index.mjs +19 -6
  74. package/dist/perf/cli.cjs +26 -28
  75. package/dist/perf/cli.js +11 -13
  76. package/dist/perf/cli.mjs +11 -13
  77. package/dist/perf/index.cjs +13 -15
  78. package/dist/perf/index.js +11 -13
  79. package/dist/perf/index.mjs +11 -13
  80. package/dist/schema/index.cjs +2 -2
  81. package/dist/schema/index.js +1 -1
  82. package/dist/schema/index.mjs +1 -1
  83. package/dist/{server-D6JZ15_e.d.ts → server-C1zVmqE6.d.ts} +5 -5
  84. package/dist/{stream-B4oK9JFP.d.ts → stream-Bb4FTejt.d.ts} +1 -1
  85. package/dist/{tracer-Hwt1cl7h.d.ts → tracer-DzfuE6um.d.ts} +2 -2
  86. package/dist/{tracing-DqbTKGcf.d.ts → tracing-BABA5arE.d.ts} +1 -1
  87. package/docs/README.md +2 -0
  88. package/docs/ai/PUBLIC_API.md +28 -7
  89. package/docs/articles/brass-runtime-http-observability.md +467 -0
  90. package/docs/frameworks/angular.md +51 -0
  91. package/docs/frameworks/express.md +58 -0
  92. package/docs/frameworks/fastify.md +49 -0
  93. package/docs/frameworks/nestjs.md +53 -0
  94. package/docs/frameworks/nextjs.md +55 -0
  95. package/docs/frameworks/react.md +44 -0
  96. package/docs/frameworks/vanilla.md +56 -0
  97. package/docs/guides/layers.md +130 -0
  98. package/docs/http-recipes.md +31 -1
  99. package/docs/http.md +50 -1
  100. package/docs/observability.md +132 -0
  101. package/docs/performance-profiler.md +6 -2
  102. package/docs/recipes/layers.md +46 -2
  103. package/docs/recipes/testing.md +25 -0
  104. package/package.json +4 -1
  105. package/dist/chunk-3LOYJFRR.cjs +0 -300
  106. package/dist/chunk-3Y2RIUMM.js +0 -300
  107. package/dist/chunk-5EC274J5.cjs +0 -2874
  108. package/dist/chunk-5VRJNBLZ.mjs +0 -2874
  109. package/dist/chunk-62AZW6UT.cjs +0 -313
  110. package/dist/chunk-74ZTY6CP.js +0 -2871
  111. package/dist/chunk-7CMJS3QE.mjs +0 -2871
  112. package/dist/chunk-A2OM6NEH.mjs +0 -194
  113. package/dist/chunk-B33ICAKP.js +0 -313
  114. package/dist/chunk-JF5WGYJJ.cjs +0 -194
  115. package/dist/chunk-KN32XNTH.mjs +0 -313
  116. package/dist/chunk-KQLYONSE.cjs +0 -2871
  117. package/dist/chunk-L2SYFEBS.js +0 -194
  118. package/dist/chunk-MIIYDLGM.js +0 -2874
  119. package/dist/chunk-PWC3RBQE.mjs +0 -300
  120. package/dist/client-CZHU674n.d.ts +0 -820
@@ -1,5 +1,6 @@
1
1
  "use strict";Object.defineProperty(exports, "__esModule", {value: true}); 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; }
2
2
 
3
+ var _chunk5XADBMSUcjs = require('./chunk-5XADBMSU.cjs');
3
4
 
4
5
 
5
6
 
@@ -9,15 +10,31 @@
9
10
 
10
11
 
11
12
 
12
- var _chunkWBGRHGBPcjs = require('./chunk-WBGRHGBP.cjs');
13
13
 
14
14
 
15
15
 
16
+ var _chunkLXBU5E77cjs = require('./chunk-LXBU5E77.cjs');
16
17
 
17
- var _chunk3LOYJFRRcjs = require('./chunk-3LOYJFRR.cjs');
18
18
 
19
19
 
20
- var _chunkGLE2WY7Zcjs = require('./chunk-GLE2WY7Z.cjs');
20
+
21
+
22
+
23
+ var _chunkVIFA4DPNcjs = require('./chunk-VIFA4DPN.cjs');
24
+
25
+
26
+ var _chunkL6VB5N7Qcjs = require('./chunk-L6VB5N7Q.cjs');
27
+
28
+
29
+
30
+ var _chunk7TXQJFZXcjs = require('./chunk-7TXQJFZX.cjs');
31
+
32
+
33
+
34
+
35
+ var _chunkSSQJKDN3cjs = require('./chunk-SSQJKDN3.cjs');
36
+
37
+
21
38
 
22
39
 
23
40
 
@@ -28,6 +45,9 @@ var _chunkMVGUEJ5Zcjs = require('./chunk-MVGUEJ5Z.cjs');
28
45
 
29
46
  // src/observability/http.ts
30
47
  var DEFAULT_DURATION_BUCKETS = [1, 5, 10, 25, 50, 100, 250, 500, 1e3, 2500, 5e3, 1e4];
48
+ var MAX_HTTP_METRIC_CACHE_ENTRIES = 4096;
49
+ var EMPTY_SPAN_ATTRIBUTES = Object.freeze({});
50
+ var TRACE_SAMPLER_RATIO = /* @__PURE__ */ Symbol.for("brass-runtime.traceSampler.ratio");
31
51
  var POLICY_LABEL_NAMES = {
32
52
  preset: "policy",
33
53
  lane: "lane",
@@ -100,13 +120,22 @@ var HTTP_OBSERVABILITY_CONTRACT = Object.freeze({
100
120
  });
101
121
  function withHttpObservability(options) {
102
122
  if (!isObservabilityInstance(options)) {
103
- _chunkWBGRHGBPcjs.validateHttpObservabilityOptions.call(void 0, _nullishCoalesce(options, () => ( {})));
123
+ _chunkLXBU5E77cjs.validateHttpObservabilityOptions.call(void 0, _nullishCoalesce(options, () => ( {})));
104
124
  }
105
125
  const resolved = resolveHttpObservabilityOptions(options);
126
+ const metricCache = makeHttpMetricCache();
127
+ attachMetricCache(resolved.metrics, metricCache);
106
128
  return (next) => {
129
+ const adaptiveLimiter = adaptiveLimiterOf(next);
130
+ if (canUseLeanHttpMetricsPath(resolved, adaptiveLimiter)) {
131
+ return withLeanHttpMetricsObservability(next, resolved, metricCache);
132
+ }
133
+ if (canUseLeanHttpSampledSpanPath(resolved, adaptiveLimiter)) {
134
+ return withLeanHttpSampledSpanObservability(next, resolved, metricCache);
135
+ }
107
136
  return (req) => {
108
137
  const run = _chunkMVGUEJ5Zcjs.asyncFlatMap.call(void 0,
109
- beginHttpObservation(req, resolved),
138
+ beginHttpObservation(req, resolved, metricCache),
110
139
  (state) => _chunkMVGUEJ5Zcjs.asyncFlatMap.call(void 0,
111
140
  logHttpRequest(req, resolved),
112
141
  () => _chunkMVGUEJ5Zcjs.asyncFlatMap.call(void 0,
@@ -116,23 +145,25 @@ function withHttpObservability(options) {
116
145
  (error) => {
117
146
  const finish = state.finishWithError(error);
118
147
  const adaptiveLimiterAttrs = observeAdaptiveLimiter(wireReq, next, resolved);
148
+ const traceEvent = !shouldEmitHttpSpanEvents(resolved) ? _chunkMVGUEJ5Zcjs.asyncSucceed.call(void 0, void 0) : _chunkLXBU5E77cjs.spanEvent.call(void 0, "http.client.error", {
149
+ ...finish.spanAttributes,
150
+ ...adaptiveLimiterAttrs,
151
+ "error.type": error._tag
152
+ });
119
153
  return _chunkMVGUEJ5Zcjs.asyncFlatMap.call(void 0,
120
- _chunkWBGRHGBPcjs.spanEvent.call(void 0, "http.client.error", {
121
- ...finish.spanAttributes,
122
- ...adaptiveLimiterAttrs,
123
- "error.type": error._tag
124
- }),
154
+ traceEvent,
125
155
  () => _chunkMVGUEJ5Zcjs.asyncFlatMap.call(void 0, logHttpError(req, error, finish, resolved), () => _chunkMVGUEJ5Zcjs.asyncFail.call(void 0, error))
126
156
  );
127
157
  },
128
158
  (res) => {
129
159
  const finish = state.finishWithResponse(res);
130
160
  const adaptiveLimiterAttrs = observeAdaptiveLimiter(wireReq, next, resolved);
161
+ const traceEvent = !shouldEmitHttpSpanEvents(resolved) ? _chunkMVGUEJ5Zcjs.asyncSucceed.call(void 0, void 0) : _chunkLXBU5E77cjs.spanEvent.call(void 0, "http.client.response", {
162
+ ...finish.spanAttributes,
163
+ ...adaptiveLimiterAttrs
164
+ });
131
165
  return _chunkMVGUEJ5Zcjs.asyncFlatMap.call(void 0,
132
- _chunkWBGRHGBPcjs.spanEvent.call(void 0, "http.client.response", {
133
- ...finish.spanAttributes,
134
- ...adaptiveLimiterAttrs
135
- }),
166
+ traceEvent,
136
167
  () => _chunkMVGUEJ5Zcjs.asyncFlatMap.call(void 0, logHttpResponse(req, res, finish, resolved), () => _chunkMVGUEJ5Zcjs.asyncSucceed.call(void 0, res))
137
168
  );
138
169
  }
@@ -141,31 +172,415 @@ function withHttpObservability(options) {
141
172
  )
142
173
  );
143
174
  if (resolved.spans === false) return run;
144
- return _chunkWBGRHGBPcjs.withSpan.call(void 0, spanName(req, resolved.spans), run, spanStartAttributes(req, resolved));
175
+ return _chunkLXBU5E77cjs.withSpan.call(void 0, spanName(req, resolved.spans), run, spanStartAttributes(req, resolved));
145
176
  };
146
177
  };
147
178
  }
148
179
  var makeHttpObservabilityMiddleware = withHttpObservability;
149
- function beginHttpObservation(req, options) {
180
+ var metricResetRegistry = /* @__PURE__ */ new WeakMap();
181
+ function canUseLeanHttpMetricsPath(options, adaptiveLimiter) {
182
+ return Boolean(
183
+ options.metrics && options.logs === false && options.spans === false && !options.injectTraceHeaders && (!options.adaptiveLimiter.enabled || !adaptiveLimiter)
184
+ );
185
+ }
186
+ function canUseLeanHttpSampledSpanPath(options, adaptiveLimiter) {
187
+ return Boolean(
188
+ options.spans !== false && options.spans.events === false && options.logs === false && !options.injectTraceHeaders && (!options.adaptiveLimiter.enabled || !adaptiveLimiter)
189
+ );
190
+ }
191
+ function withLeanHttpSampledSpanObservability(next, options, metricCache) {
192
+ return (req) => _chunkMVGUEJ5Zcjs.asyncEffect.call(void 0, (env, cb) => {
193
+ const startedAt = options.clock();
194
+ const baseLabels = requestBaseLabels(req, options);
195
+ const handles = beginLeanHttpMetricsObservation(baseLabels, options, metricCache);
196
+ const span = startLeanHttpSpan(req, options);
197
+ let finished = false;
198
+ let cancelInner;
199
+ const finish = (exit) => {
200
+ if (finished) return;
201
+ finished = true;
202
+ cancelInner = void 0;
203
+ if (exit._tag === "Success") {
204
+ recordHttpMetricsFinish(
205
+ handles,
206
+ httpStatusOutcome(exit.value.status),
207
+ String(exit.value.status),
208
+ startedAt,
209
+ options,
210
+ metricCache
211
+ );
212
+ finishLeanHttpSpan(span, "success");
213
+ } else {
214
+ const error = httpErrorFromCause(exit.cause);
215
+ const status = _chunkVIFA4DPNcjs.httpErrorStatus.call(void 0, error);
216
+ recordHttpMetricsFinish(
217
+ handles,
218
+ httpErrorOutcome(error),
219
+ status !== void 0 ? String(status) : void 0,
220
+ startedAt,
221
+ options,
222
+ metricCache
223
+ );
224
+ finishLeanHttpSpan(span, _chunkMVGUEJ5Zcjs.Cause.containsInterrupt(exit.cause) ? "interrupted" : "failure", error);
225
+ }
226
+ cb(exit);
227
+ };
228
+ try {
229
+ cancelInner = _chunkL6VB5N7Qcjs.registerHttpEffect.call(void 0, next(req), env, finish);
230
+ } catch (error) {
231
+ const defectExit = {
232
+ _tag: "Failure",
233
+ cause: _chunkMVGUEJ5Zcjs.Cause.die(error)
234
+ };
235
+ finish(defectExit);
236
+ }
237
+ return () => {
238
+ if (!finished) {
239
+ finished = true;
240
+ recordHttpMetricsFinish(
241
+ handles,
242
+ "abort",
243
+ void 0,
244
+ startedAt,
245
+ options,
246
+ metricCache
247
+ );
248
+ finishLeanHttpSpan(span, "interrupted");
249
+ }
250
+ const cancel = cancelInner;
251
+ cancelInner = void 0;
252
+ _optionalChain([cancel, 'optionalCall', _ => _()]);
253
+ };
254
+ });
255
+ }
256
+ function withLeanHttpMetricsObservability(next, options, metricCache) {
257
+ return (req) => _chunkMVGUEJ5Zcjs.asyncEffect.call(void 0, (env, cb) => {
258
+ const startedAt = options.clock();
259
+ const baseLabels = requestBaseLabels(req, options);
260
+ const handles = beginLeanHttpMetricsObservation(baseLabels, options, metricCache);
261
+ let finished = false;
262
+ let cancelInner;
263
+ const finish = (exit) => {
264
+ if (finished) return;
265
+ finished = true;
266
+ cancelInner = void 0;
267
+ if (exit._tag === "Success") {
268
+ recordHttpMetricsFinish(
269
+ handles,
270
+ httpStatusOutcome(exit.value.status),
271
+ String(exit.value.status),
272
+ startedAt,
273
+ options,
274
+ metricCache
275
+ );
276
+ } else {
277
+ const error = httpErrorFromCause(exit.cause);
278
+ const status = _chunkVIFA4DPNcjs.httpErrorStatus.call(void 0, error);
279
+ recordHttpMetricsFinish(
280
+ handles,
281
+ httpErrorOutcome(error),
282
+ status !== void 0 ? String(status) : void 0,
283
+ startedAt,
284
+ options,
285
+ metricCache
286
+ );
287
+ }
288
+ cb(exit);
289
+ };
290
+ try {
291
+ cancelInner = _chunkL6VB5N7Qcjs.registerHttpEffect.call(void 0, next(req), env, finish);
292
+ } catch (error) {
293
+ const defectExit = {
294
+ _tag: "Failure",
295
+ cause: _chunkMVGUEJ5Zcjs.Cause.die(error)
296
+ };
297
+ finish(defectExit);
298
+ }
299
+ return () => {
300
+ if (!finished) {
301
+ finished = true;
302
+ recordHttpMetricsFinish(
303
+ handles,
304
+ "abort",
305
+ void 0,
306
+ startedAt,
307
+ options,
308
+ metricCache
309
+ );
310
+ }
311
+ const cancel = cancelInner;
312
+ cancelInner = void 0;
313
+ _optionalChain([cancel, 'optionalCall', _2 => _2()]);
314
+ };
315
+ });
316
+ }
317
+ function beginLeanHttpMetricsObservation(baseLabels, options, metricCache) {
318
+ const cacheKey = metricCacheKey("brass_http_client", baseLabels);
319
+ const existing = metricCache.disabled ? void 0 : metricCache.leanEntries.get(cacheKey);
320
+ if (existing) {
321
+ _optionalChain([existing, 'access', _3 => _3.inFlight, 'optionalAccess', _4 => _4.increment, 'call', _5 => _5()]);
322
+ return existing;
323
+ }
324
+ const inFlight = options.metrics ? getCachedMetric(
325
+ metricCache,
326
+ metricCache.inFlightGauges,
327
+ metricCacheKey("brass_http_client_in_flight", baseLabels),
328
+ () => options.metrics.gauge("brass_http_client_in_flight", baseLabels)
329
+ ) : void 0;
330
+ _optionalChain([inFlight, 'optionalAccess', _6 => _6.increment, 'call', _7 => _7()]);
331
+ const created = {
332
+ baseLabels,
333
+ inFlight,
334
+ finishMetrics: /* @__PURE__ */ new Map()
335
+ };
336
+ if (!metricCache.disabled && metricCache.leanEntries.size < MAX_HTTP_METRIC_CACHE_ENTRIES) {
337
+ metricCache.leanEntries.set(cacheKey, created);
338
+ }
339
+ return created;
340
+ }
341
+ function recordHttpMetricsFinish(handles, outcome, status, startedAt, options, metricCache) {
342
+ const durationMs = Math.max(0, options.clock() - startedAt);
343
+ _optionalChain([handles, 'access', _8 => _8.inFlight, 'optionalAccess', _9 => _9.decrement, 'call', _10 => _10()]);
344
+ if (!options.metrics) return;
345
+ const finishKey = `${outcome}|${_nullishCoalesce(status, () => ( "none"))}`;
346
+ let finishMetrics = metricCache.disabled ? void 0 : handles.finishMetrics.get(finishKey);
347
+ if (!finishMetrics) {
348
+ const labels = requestFinishLabelsFromBase(handles.baseLabels, outcome, status);
349
+ finishMetrics = {
350
+ counter: options.metrics.counter("brass_http_client_requests_total", labels),
351
+ histogram: options.metrics.histogram(
352
+ "brass_http_client_duration_ms",
353
+ [..._nullishCoalesce(options.durationBuckets, () => ( DEFAULT_DURATION_BUCKETS))],
354
+ labels
355
+ )
356
+ };
357
+ if (!metricCache.disabled) handles.finishMetrics.set(finishKey, finishMetrics);
358
+ }
359
+ finishMetrics.counter.increment();
360
+ finishMetrics.histogram.observe(durationMs);
361
+ }
362
+ function startLeanHttpSpan(req, options) {
363
+ const configuredSampleRate = options.spans === false ? void 0 : options.spans.sampleRate;
364
+ if (configuredSampleRate !== void 0) {
365
+ if (configuredSampleRate <= 0) return void 0;
366
+ if (configuredSampleRate < 1 && Math.random() >= configuredSampleRate) return void 0;
367
+ }
368
+ const fiber = _chunkSSQJKDN3cjs.getCurrentFiber.call(void 0, );
369
+ const runtime = _optionalChain([fiber, 'optionalAccess', _11 => _11.runtime]);
370
+ const sink = _nullishCoalesce(options.spanSink, () => ( _optionalChain([runtime, 'optionalAccess', _12 => _12.hooks])));
371
+ if (!_optionalChain([fiber, 'optionalAccess', _13 => _13.fiberContext]) || !runtime || !sink) return void 0;
372
+ const previousTrace = _nullishCoalesce(fiber.fiberContext.trace, () => ( null));
373
+ const brass = _optionalChain([runtime, 'access', _14 => _14.env, 'optionalAccess', _15 => _15.brass]);
374
+ if (_optionalChain([previousTrace, 'optionalAccess', _16 => _16.sampled]) === false && _optionalChain([brass, 'optionalAccess', _17 => _17.respectRemoteSampled]) !== false) return void 0;
375
+ const name = spanName(req, options.spans);
376
+ const tracer = resolveRuntimeTracer(runtime);
377
+ let traceId = _optionalChain([previousTrace, 'optionalAccess', _18 => _18.traceId]);
378
+ let sampled = _optionalChain([previousTrace, 'optionalAccess', _19 => _19.sampled]);
379
+ let attributes;
380
+ if (!previousTrace && configuredSampleRate === void 0) {
381
+ const ratio = traceSamplerRatio(_optionalChain([brass, 'optionalAccess', _20 => _20.sampler]));
382
+ if (ratio !== void 0) {
383
+ if (ratio <= 0) return void 0;
384
+ if (ratio < 1 && Math.random() >= ratio) return void 0;
385
+ sampled = true;
386
+ }
387
+ traceId = tracer.newTraceId();
388
+ } else if (!previousTrace) {
389
+ sampled = true;
390
+ traceId = tracer.newTraceId();
391
+ }
392
+ attributes = spanStartAttributes(req, options);
393
+ if (sampled === void 0) {
394
+ traceId = _nullishCoalesce(traceId, () => ( tracer.newTraceId()));
395
+ sampled = _chunkLXBU5E77cjs.shouldSampleWith.call(void 0, _optionalChain([brass, 'optionalAccess', _21 => _21.sampler]), {
396
+ traceId,
397
+ spanName: name,
398
+ parentSampled: _optionalChain([previousTrace, 'optionalAccess', _22 => _22.sampled]),
399
+ attributes
400
+ });
401
+ }
402
+ if (sampled === false) return void 0;
403
+ const trace = {
404
+ traceId: _nullishCoalesce(traceId, () => ( tracer.newTraceId())),
405
+ spanId: tracer.newSpanId(),
406
+ parentSpanId: _optionalChain([previousTrace, 'optionalAccess', _23 => _23.spanId]),
407
+ sampled: true,
408
+ traceState: _optionalChain([previousTrace, 'optionalAccess', _24 => _24.traceState]),
409
+ ..._optionalChain([previousTrace, 'optionalAccess', _25 => _25.baggage]) ? { baggage: previousTrace.baggage } : {}
410
+ };
411
+ const state = {
412
+ fiber,
413
+ sink,
414
+ previousTrace,
415
+ trace,
416
+ name,
417
+ ended: false
418
+ };
419
+ fiber.fiberContext = { ...fiber.fiberContext, trace };
420
+ _optionalChain([fiber, 'access', _26 => _26.addFinalizer, 'optionalCall', _27 => _27((exit) => {
421
+ const status = _optionalChain([exit, 'optionalAccess', _28 => _28._tag]) === "Success" ? "success" : _optionalChain([exit, 'optionalAccess', _29 => _29.cause]) && _chunkMVGUEJ5Zcjs.Cause.containsInterrupt(exit.cause) ? "interrupted" : "failure";
422
+ finishLeanHttpSpan(state, status, _optionalChain([exit, 'optionalAccess', _30 => _30._tag]) === "Failure" ? exit.cause : void 0);
423
+ })]);
424
+ sink.emit(
425
+ { type: "span.start", name, attributes, links: [] },
426
+ leanSpanContext(fiber, trace)
427
+ );
428
+ return state;
429
+ }
430
+ function finishLeanHttpSpan(state, status, error) {
431
+ if (!state || state.ended) return;
432
+ state.ended = true;
433
+ state.sink.emit(
434
+ { type: "span.end", name: state.name, status, error },
435
+ leanSpanContext(state.fiber, state.trace)
436
+ );
437
+ if (_optionalChain([state, 'access', _31 => _31.fiber, 'optionalAccess', _32 => _32.fiberContext])) {
438
+ state.fiber.fiberContext = { ...state.fiber.fiberContext, trace: state.previousTrace };
439
+ }
440
+ }
441
+ function leanSpanContext(fiber, trace) {
442
+ return {
443
+ fiberId: _optionalChain([fiber, 'optionalAccess', _33 => _33.id]),
444
+ scopeId: _optionalChain([fiber, 'optionalAccess', _34 => _34.scopeId]),
445
+ traceId: trace.traceId,
446
+ spanId: trace.spanId,
447
+ parentSpanId: trace.parentSpanId,
448
+ traceState: trace.traceState,
449
+ baggage: trace.baggage,
450
+ sampled: trace.sampled
451
+ };
452
+ }
453
+ function resolveRuntimeTracer(runtime) {
454
+ const tracer = _optionalChain([runtime, 'optionalAccess', _35 => _35.env, 'optionalAccess', _36 => _36.brass, 'optionalAccess', _37 => _37.tracer]);
455
+ if (_optionalChain([tracer, 'optionalAccess', _38 => _38.newTraceId]) && _optionalChain([tracer, 'optionalAccess', _39 => _39.newSpanId])) return tracer;
456
+ return {
457
+ newTraceId: () => randomRuntimeId("trace"),
458
+ newSpanId: () => randomRuntimeId("span")
459
+ };
460
+ }
461
+ function traceSamplerRatio(sampler) {
462
+ if (!sampler || typeof sampler === "function") return void 0;
463
+ const ratio = sampler[TRACE_SAMPLER_RATIO];
464
+ return typeof ratio === "number" && Number.isFinite(ratio) ? ratio : void 0;
465
+ }
466
+ function randomRuntimeId(prefix) {
467
+ const cryptoLike = globalThis.crypto;
468
+ if (typeof _optionalChain([cryptoLike, 'optionalAccess', _40 => _40.randomUUID]) === "function") return cryptoLike.randomUUID();
469
+ return `${prefix}-${Date.now().toString(36)}-${Math.random().toString(36).slice(2)}`;
470
+ }
471
+ function httpErrorFromCause(cause) {
472
+ const failure = _chunkMVGUEJ5Zcjs.Cause.firstFailure(cause);
473
+ if (failure._tag === "Some") return failure.value;
474
+ if (_chunkMVGUEJ5Zcjs.Cause.containsInterrupt(cause)) return { _tag: "Abort" };
475
+ const defect = _chunkMVGUEJ5Zcjs.Cause.firstDefect(cause);
476
+ const value = defect._tag === "Some" ? defect.value : _chunkMVGUEJ5Zcjs.Cause.toError(cause);
477
+ return {
478
+ _tag: "FetchError",
479
+ message: value instanceof Error ? value.message : String(value),
480
+ cause: value
481
+ };
482
+ }
483
+ function makeHttpMetricCache() {
484
+ return {
485
+ disabled: false,
486
+ leanEntries: /* @__PURE__ */ new Map(),
487
+ inFlightGauges: /* @__PURE__ */ new Map(),
488
+ requestCounters: /* @__PURE__ */ new Map(),
489
+ durationHistograms: /* @__PURE__ */ new Map()
490
+ };
491
+ }
492
+ function attachMetricCache(metrics, cache) {
493
+ if (!metrics) return;
494
+ const existing = metricResetRegistry.get(metrics);
495
+ if (existing) {
496
+ existing.caches.add(cache);
497
+ return;
498
+ }
499
+ const entry = {
500
+ caches: /* @__PURE__ */ new Set([cache]),
501
+ reset: metrics.reset.bind(metrics)
502
+ };
503
+ try {
504
+ Object.defineProperty(metrics, "reset", {
505
+ configurable: true,
506
+ value: () => {
507
+ for (const cached of entry.caches) clearHttpMetricCache(cached);
508
+ entry.reset();
509
+ }
510
+ });
511
+ metricResetRegistry.set(metrics, entry);
512
+ } catch (e) {
513
+ cache.disabled = true;
514
+ }
515
+ }
516
+ function clearHttpMetricCache(cache) {
517
+ cache.leanEntries.clear();
518
+ cache.inFlightGauges.clear();
519
+ cache.requestCounters.clear();
520
+ cache.durationHistograms.clear();
521
+ }
522
+ function getCachedMetric(owner, cache, key, create) {
523
+ if (owner.disabled) return create();
524
+ const existing = cache.get(key);
525
+ if (existing) return existing;
526
+ const created = create();
527
+ if (cache.size < MAX_HTTP_METRIC_CACHE_ENTRIES) {
528
+ cache.set(key, created);
529
+ }
530
+ return created;
531
+ }
532
+ function metricCacheKey(name, labels) {
533
+ let key = name;
534
+ for (const [label, value] of Object.entries(labels)) {
535
+ key += `|${label.length}:${label}=${value.length}:${value}`;
536
+ }
537
+ return key;
538
+ }
539
+ function beginHttpObservation(req, options, metricCache) {
150
540
  return _chunkMVGUEJ5Zcjs.asyncSync.call(void 0, () => {
151
541
  const startedAt = options.clock();
152
542
  let finished = false;
153
- const inFlight = _optionalChain([options, 'access', _ => _.metrics, 'optionalAccess', _2 => _2.gauge, 'call', _3 => _3("brass_http_client_in_flight", requestBaseLabels(req, options))]);
154
- _optionalChain([inFlight, 'optionalAccess', _4 => _4.increment, 'call', _5 => _5()]);
543
+ const baseLabels = requestBaseLabels(req, options);
544
+ const inFlight = options.metrics ? getCachedMetric(
545
+ metricCache,
546
+ metricCache.inFlightGauges,
547
+ metricCacheKey("brass_http_client_in_flight", baseLabels),
548
+ () => options.metrics.gauge("brass_http_client_in_flight", baseLabels)
549
+ ) : void 0;
550
+ _optionalChain([inFlight, 'optionalAccess', _41 => _41.increment, 'call', _42 => _42()]);
155
551
  const finish = (outcome, status, extra = {}) => {
156
552
  const durationMs = Math.max(0, options.clock() - startedAt);
157
- const labels = requestFinishLabels(req, outcome, status, options);
553
+ const labels = requestFinishLabelsFromBase(baseLabels, outcome, status);
158
554
  if (!finished) {
159
555
  finished = true;
160
556
  if (inFlight && inFlight.value() > 0) inFlight.decrement();
161
- _optionalChain([options, 'access', _6 => _6.metrics, 'optionalAccess', _7 => _7.counter, 'call', _8 => _8("brass_http_client_requests_total", labels), 'access', _9 => _9.increment, 'call', _10 => _10()]);
162
- _optionalChain([options, 'access', _11 => _11.metrics, 'optionalAccess', _12 => _12.histogram, 'call', _13 => _13("brass_http_client_duration_ms", [..._nullishCoalesce(options.durationBuckets, () => ( DEFAULT_DURATION_BUCKETS))], labels), 'access', _14 => _14.observe, 'call', _15 => _15(durationMs, currentTraceExemplar(durationMs, startedAt + durationMs))]);
557
+ if (options.metrics) {
558
+ getCachedMetric(
559
+ metricCache,
560
+ metricCache.requestCounters,
561
+ metricCacheKey("brass_http_client_requests_total", labels),
562
+ () => options.metrics.counter("brass_http_client_requests_total", labels)
563
+ ).increment();
564
+ getCachedMetric(
565
+ metricCache,
566
+ metricCache.durationHistograms,
567
+ metricCacheKey("brass_http_client_duration_ms", labels),
568
+ () => options.metrics.histogram(
569
+ "brass_http_client_duration_ms",
570
+ [..._nullishCoalesce(options.durationBuckets, () => ( DEFAULT_DURATION_BUCKETS))],
571
+ labels
572
+ )
573
+ ).observe(
574
+ durationMs,
575
+ options.spans === false ? void 0 : currentTraceExemplar(durationMs, startedAt + durationMs)
576
+ );
577
+ }
163
578
  }
164
579
  return {
165
580
  durationMs,
166
581
  outcome,
167
582
  labels,
168
- spanAttributes: {
583
+ spanAttributes: options.spans === false ? EMPTY_SPAN_ATTRIBUTES : {
169
584
  "http.duration_ms": durationMs,
170
585
  "http.outcome": outcome,
171
586
  ...status ? { "http.status_code": Number(status) } : {},
@@ -174,17 +589,17 @@ function beginHttpObservation(req, options) {
174
589
  }
175
590
  };
176
591
  };
177
- const fiber = _chunkGLE2WY7Zcjs.getCurrentFiber.call(void 0, );
178
- _optionalChain([fiber, 'optionalAccess', _16 => _16.addFinalizer, 'optionalCall', _17 => _17(() => {
592
+ const fiber = _chunkSSQJKDN3cjs.getCurrentFiber.call(void 0, );
593
+ _optionalChain([fiber, 'optionalAccess', _43 => _43.addFinalizer, 'optionalCall', _44 => _44(() => {
179
594
  finish("abort", void 0, { "http.cancelled": true });
180
595
  })]);
181
596
  return {
182
597
  finishWithResponse: (res) => finish(httpStatusOutcome(res.status), String(res.status)),
183
598
  finishWithError: (error) => {
184
- const status = _chunk3LOYJFRRcjs.httpErrorStatus.call(void 0, error);
599
+ const status = _chunkVIFA4DPNcjs.httpErrorStatus.call(void 0, error);
185
600
  return finish(httpErrorOutcome(error), status !== void 0 ? String(status) : void 0, {
186
601
  "error.type": error._tag,
187
- "http.retryable": _chunk3LOYJFRRcjs.isRetryableHttpError.call(void 0, error)
602
+ "http.retryable": _chunkVIFA4DPNcjs.isRetryableHttpError.call(void 0, error)
188
603
  });
189
604
  }
190
605
  };
@@ -197,13 +612,13 @@ function prepareHttpRequest(req, options) {
197
612
  function logHttpRequest(req, options) {
198
613
  const level = options.logs === false ? false : _nullishCoalesce(options.logs.requestLevel, () => ( false));
199
614
  if (!level) return _chunkMVGUEJ5Zcjs.asyncSucceed.call(void 0, void 0);
200
- return _chunkWBGRHGBPcjs.logEffect.call(void 0, level, "http.client.request", requestLogFields(req, options));
615
+ return _chunkLXBU5E77cjs.logEffect.call(void 0, level, "http.client.request", requestLogFields(req, options));
201
616
  }
202
617
  function logHttpResponse(req, res, finish, options) {
203
618
  const configured = options.logs === false ? false : _nullishCoalesce(options.logs.responseLevel, () => ( false));
204
619
  const level = configured || (finish.outcome === "error" ? options.logs !== false ? _nullishCoalesce(options.logs.errorLevel, () => ( "warn")) : false : false);
205
620
  if (!level) return _chunkMVGUEJ5Zcjs.asyncSucceed.call(void 0, void 0);
206
- return _chunkWBGRHGBPcjs.logEffect.call(void 0, level, "http.client.response", {
621
+ return _chunkLXBU5E77cjs.logEffect.call(void 0, level, "http.client.response", {
207
622
  ...requestLogFields(req, options),
208
623
  status: res.status,
209
624
  statusText: res.statusText,
@@ -214,15 +629,15 @@ function logHttpResponse(req, res, finish, options) {
214
629
  function logHttpError(req, error, finish, options) {
215
630
  const level = options.logs === false ? false : _nullishCoalesce(options.logs.errorLevel, () => ( "error"));
216
631
  if (!level) return _chunkMVGUEJ5Zcjs.asyncSucceed.call(void 0, void 0);
217
- const status = _chunk3LOYJFRRcjs.httpErrorStatus.call(void 0, error);
632
+ const status = _chunkVIFA4DPNcjs.httpErrorStatus.call(void 0, error);
218
633
  const statusText = httpErrorStatusText(error);
219
- return _chunkWBGRHGBPcjs.logEffect.call(void 0, level, "http.client.error", {
634
+ return _chunkLXBU5E77cjs.logEffect.call(void 0, level, "http.client.error", {
220
635
  ...requestLogFields(req, options),
221
636
  outcome: finish.outcome,
222
637
  durationMs: finish.durationMs,
223
638
  ...status !== void 0 ? { status } : {},
224
639
  ...statusText ? { statusText } : {},
225
- retryable: _chunk3LOYJFRRcjs.isRetryableHttpError.call(void 0, error),
640
+ retryable: _chunkVIFA4DPNcjs.isRetryableHttpError.call(void 0, error),
226
641
  errorTag: error._tag,
227
642
  message: httpErrorMessage(error)
228
643
  });
@@ -231,16 +646,17 @@ function resolveHttpObservabilityOptions(options) {
231
646
  const maybeObservability = isObservabilityInstance(options) ? options : void 0;
232
647
  const raw = maybeObservability ? { metrics: maybeObservability.metrics } : options;
233
648
  return {
234
- metrics: _optionalChain([raw, 'optionalAccess', _18 => _18.metrics]) === false ? void 0 : _optionalChain([raw, 'optionalAccess', _19 => _19.metrics]),
235
- logs: _nullishCoalesce(_optionalChain([raw, 'optionalAccess', _20 => _20.logs]), () => ( {})),
236
- spans: _nullishCoalesce(_optionalChain([raw, 'optionalAccess', _21 => _21.spans]), () => ( {})),
237
- adaptiveLimiter: resolveAdaptiveLimiterObservabilityOptions(_optionalChain([raw, 'optionalAccess', _22 => _22.adaptiveLimiter])),
238
- policy: resolveHttpPolicyObservabilityOptions(_optionalChain([raw, 'optionalAccess', _23 => _23.policy])),
239
- injectTraceHeaders: _nullishCoalesce(_optionalChain([raw, 'optionalAccess', _24 => _24.injectTraceHeaders]), () => ( true)),
240
- includeHostLabel: _nullishCoalesce(_optionalChain([raw, 'optionalAccess', _25 => _25.includeHostLabel]), () => ( true)),
241
- route: _optionalChain([raw, 'optionalAccess', _26 => _26.route]),
242
- clock: _nullishCoalesce(_optionalChain([raw, 'optionalAccess', _27 => _27.clock]), () => ( Date.now)),
243
- durationBuckets: _optionalChain([raw, 'optionalAccess', _28 => _28.durationBuckets])
649
+ metrics: _optionalChain([raw, 'optionalAccess', _45 => _45.metrics]) === false ? void 0 : _optionalChain([raw, 'optionalAccess', _46 => _46.metrics]),
650
+ logs: _nullishCoalesce(_optionalChain([raw, 'optionalAccess', _47 => _47.logs]), () => ( {})),
651
+ spans: _nullishCoalesce(_optionalChain([raw, 'optionalAccess', _48 => _48.spans]), () => ( {})),
652
+ spanSink: _optionalChain([raw, 'optionalAccess', _49 => _49.spanSink]) === false ? void 0 : _optionalChain([raw, 'optionalAccess', _50 => _50.spanSink]),
653
+ adaptiveLimiter: resolveAdaptiveLimiterObservabilityOptions(_optionalChain([raw, 'optionalAccess', _51 => _51.adaptiveLimiter])),
654
+ policy: resolveHttpPolicyObservabilityOptions(_optionalChain([raw, 'optionalAccess', _52 => _52.policy])),
655
+ injectTraceHeaders: _nullishCoalesce(_optionalChain([raw, 'optionalAccess', _53 => _53.injectTraceHeaders]), () => ( true)),
656
+ includeHostLabel: _nullishCoalesce(_optionalChain([raw, 'optionalAccess', _54 => _54.includeHostLabel]), () => ( true)),
657
+ route: _optionalChain([raw, 'optionalAccess', _55 => _55.route]),
658
+ clock: _nullishCoalesce(_optionalChain([raw, 'optionalAccess', _56 => _56.clock]), () => ( Date.now)),
659
+ durationBuckets: _optionalChain([raw, 'optionalAccess', _57 => _57.durationBuckets])
244
660
  };
245
661
  }
246
662
  function isObservabilityInstance(options) {
@@ -303,11 +719,11 @@ function adaptiveLimiterLabels(req, stats, options) {
303
719
  });
304
720
  }
305
721
  function inferAdaptiveLimiterKey(req, stats) {
306
- const policy = _chunk3LOYJFRRcjs.getHttpRequestPolicy.call(void 0, req);
722
+ const policy = _chunkVIFA4DPNcjs.getHttpRequestPolicy.call(void 0, req);
307
723
  if (policy.poolKey) return policy.poolKey;
308
724
  const host = requestHost(req);
309
725
  if (host) return host;
310
- return _optionalChain([stats, 'access', _29 => _29.keys, 'optionalAccess', _30 => _30.length]) === 1 ? stats.keys[0] : void 0;
726
+ return _optionalChain([stats, 'access', _58 => _58.keys, 'optionalAccess', _59 => _59.length]) === 1 ? stats.keys[0] : void 0;
311
727
  }
312
728
  function setGauge(metrics, name, value, labels) {
313
729
  if (!metrics || value === void 0 || !Number.isFinite(value)) return;
@@ -330,6 +746,9 @@ function spanName(req, options) {
330
746
  }
331
747
  return `HTTP ${req.method}`;
332
748
  }
749
+ function shouldEmitHttpSpanEvents(options) {
750
+ return options.spans !== false && options.spans.events !== false;
751
+ }
333
752
  function spanStartAttributes(req, options) {
334
753
  const spanOptions = options.spans === false ? {} : options.spans.attributes;
335
754
  const custom = typeof spanOptions === "function" ? spanOptions(req) : _nullishCoalesce(spanOptions, () => ( {}));
@@ -361,9 +780,9 @@ function requestBaseLabels(req, options) {
361
780
  ...requestPolicyMetricLabels(req, options)
362
781
  });
363
782
  }
364
- function requestFinishLabels(req, outcome, status, options) {
783
+ function requestFinishLabelsFromBase(baseLabels, outcome, status) {
365
784
  return {
366
- ...requestBaseLabels(req, options),
785
+ ...baseLabels,
367
786
  outcome,
368
787
  status: _nullishCoalesce(status, () => ( "none"))
369
788
  };
@@ -382,7 +801,7 @@ function requestLogFields(req, options) {
382
801
  }
383
802
  function requestPolicyLogFields(req, options) {
384
803
  if (!options.policy.enabled) return void 0;
385
- const policy = _chunk3LOYJFRRcjs.getHttpRequestPolicy.call(void 0, req);
804
+ const policy = _chunkVIFA4DPNcjs.getHttpRequestPolicy.call(void 0, req);
386
805
  const fields = {
387
806
  ...policy.preset ? { preset: policy.preset } : {},
388
807
  ...policy.lane ? { lane: policy.lane } : {},
@@ -395,7 +814,7 @@ function requestPolicyLogFields(req, options) {
395
814
  }
396
815
  function requestPolicySpanAttributes(req, options) {
397
816
  if (!options.policy.enabled) return {};
398
- const policy = _chunk3LOYJFRRcjs.getHttpRequestPolicy.call(void 0, req);
817
+ const policy = _chunkVIFA4DPNcjs.getHttpRequestPolicy.call(void 0, req);
399
818
  return {
400
819
  ...compactSpanAttributes({
401
820
  "http.request.policy.lane": policy.lane,
@@ -409,7 +828,7 @@ function requestPolicySpanAttributes(req, options) {
409
828
  }
410
829
  function requestPolicyMetricLabels(req, options) {
411
830
  if (!options.policy.enabled || options.policy.labelKeys.length === 0) return {};
412
- const policy = _chunk3LOYJFRRcjs.getHttpRequestPolicy.call(void 0, req);
831
+ const policy = _chunkVIFA4DPNcjs.getHttpRequestPolicy.call(void 0, req);
413
832
  const values = {
414
833
  preset: policy.preset,
415
834
  lane: policy.lane,
@@ -485,23 +904,23 @@ function httpErrorStatusText(error) {
485
904
  return error._tag === "FetchError" ? error.statusText : void 0;
486
905
  }
487
906
  function injectCurrentTraceContext(req) {
488
- const fiber = _chunkGLE2WY7Zcjs.getCurrentFiber.call(void 0, );
489
- const trace = _optionalChain([fiber, 'optionalAccess', _31 => _31.fiberContext, 'optionalAccess', _32 => _32.trace]);
490
- if (!_optionalChain([trace, 'optionalAccess', _33 => _33.traceId]) || !_optionalChain([trace, 'optionalAccess', _34 => _34.spanId])) return req;
907
+ const fiber = _chunkSSQJKDN3cjs.getCurrentFiber.call(void 0, );
908
+ const trace = _optionalChain([fiber, 'optionalAccess', _60 => _60.fiberContext, 'optionalAccess', _61 => _61.trace]);
909
+ if (!_optionalChain([trace, 'optionalAccess', _62 => _62.traceId]) || !_optionalChain([trace, 'optionalAccess', _63 => _63.spanId])) return req;
491
910
  return {
492
911
  ...req,
493
- headers: _chunkWBGRHGBPcjs.injectTraceContext.call(void 0, req.headers, trace)
912
+ headers: _chunkLXBU5E77cjs.injectTraceContext.call(void 0, req.headers, trace)
494
913
  };
495
914
  }
496
915
  function currentTraceExemplar(value, timestamp) {
497
- const fiber = _chunkGLE2WY7Zcjs.getCurrentFiber.call(void 0, );
498
- return _chunkWBGRHGBPcjs.exemplarFromTraceContext.call(void 0, _optionalChain([fiber, 'optionalAccess', _35 => _35.fiberContext, 'optionalAccess', _36 => _36.trace]), value, timestamp);
916
+ const fiber = _chunkSSQJKDN3cjs.getCurrentFiber.call(void 0, );
917
+ return _chunkLXBU5E77cjs.exemplarFromTraceContext.call(void 0, _optionalChain([fiber, 'optionalAccess', _64 => _64.fiberContext, 'optionalAccess', _65 => _65.trace]), value, timestamp);
499
918
  }
500
919
  function requestHost(req) {
501
920
  if (!isAbsoluteUrl(req.url)) return void 0;
502
921
  try {
503
922
  return new URL(req.url).host;
504
- } catch (e) {
923
+ } catch (e2) {
505
924
  return void 0;
506
925
  }
507
926
  }
@@ -511,7 +930,7 @@ function urlScheme(url) {
511
930
  if (!isAbsoluteUrl(url)) return void 0;
512
931
  try {
513
932
  return new URL(url).protocol.replace(/:$/, "");
514
- } catch (e2) {
933
+ } catch (e3) {
515
934
  return void 0;
516
935
  }
517
936
  }
@@ -522,7 +941,7 @@ function urlPath(url) {
522
941
  }
523
942
  try {
524
943
  return new URL(url).pathname;
525
- } catch (e3) {
944
+ } catch (e4) {
526
945
  return void 0;
527
946
  }
528
947
  }
@@ -533,7 +952,7 @@ function sanitizeUrl(url) {
533
952
  parsed.search = "";
534
953
  parsed.hash = "";
535
954
  return parsed.toString();
536
- } catch (e4) {
955
+ } catch (e5) {
537
956
  const [withoutHash] = url.split("#", 1);
538
957
  const [withoutQuery] = withoutHash.split("?", 1);
539
958
  return withoutQuery;
@@ -563,38 +982,38 @@ function compactLabels(labels) {
563
982
 
564
983
  // src/observability/adapters.ts
565
984
  function makeFetchRequestObservabilityContext(observability, request, input = {}) {
566
- return _chunkWBGRHGBPcjs.makeRequestObservabilityContext.call(void 0, observability, {
985
+ return _chunkLXBU5E77cjs.makeRequestObservabilityContext.call(void 0, observability, {
567
986
  headers: request.headers,
568
987
  method: request.method,
569
- target: _chunkWBGRHGBPcjs.sanitizeHttpTarget.call(void 0, request.url),
570
- route: _nullishCoalesce(input.route, () => ( _chunkWBGRHGBPcjs.normalizeHttpRoute.call(void 0, urlPathname(request.url)))),
988
+ target: _chunkLXBU5E77cjs.sanitizeHttpTarget.call(void 0, request.url),
989
+ route: _nullishCoalesce(input.route, () => ( _chunkLXBU5E77cjs.normalizeHttpRoute.call(void 0, urlPathname(request.url)))),
571
990
  ...input
572
991
  });
573
992
  }
574
993
  function makeNodeRequestObservabilityContext(observability, request, input = {}) {
575
- return _chunkWBGRHGBPcjs.makeRequestObservabilityContext.call(void 0, observability, {
994
+ return _chunkLXBU5E77cjs.makeRequestObservabilityContext.call(void 0, observability, {
576
995
  headers: request.headers,
577
996
  method: request.method,
578
- target: _chunkWBGRHGBPcjs.sanitizeHttpTarget.call(void 0, request.url),
579
- route: _nullishCoalesce(input.route, () => ( _chunkWBGRHGBPcjs.normalizeHttpRoute.call(void 0, request.url))),
997
+ target: _chunkLXBU5E77cjs.sanitizeHttpTarget.call(void 0, request.url),
998
+ route: _nullishCoalesce(input.route, () => ( _chunkLXBU5E77cjs.normalizeHttpRoute.call(void 0, request.url))),
580
999
  ...input
581
1000
  });
582
1001
  }
583
1002
  function makeExpressRequestObservabilityContext(observability, request, input = {}) {
584
- return _chunkWBGRHGBPcjs.makeRequestObservabilityContext.call(void 0, observability, {
1003
+ return _chunkLXBU5E77cjs.makeRequestObservabilityContext.call(void 0, observability, {
585
1004
  headers: request.headers,
586
1005
  method: request.method,
587
- target: _chunkWBGRHGBPcjs.sanitizeHttpTarget.call(void 0, _nullishCoalesce(request.originalUrl, () => ( request.url))),
588
- route: _nullishCoalesce(_nullishCoalesce(input.route, () => ( _optionalChain([request, 'access', _37 => _37.route, 'optionalAccess', _38 => _38.path]))), () => ( _chunkWBGRHGBPcjs.normalizeHttpRoute.call(void 0, _nullishCoalesce(request.path, () => ( request.url))))),
1006
+ target: _chunkLXBU5E77cjs.sanitizeHttpTarget.call(void 0, _nullishCoalesce(request.originalUrl, () => ( request.url))),
1007
+ route: _nullishCoalesce(_nullishCoalesce(input.route, () => ( _optionalChain([request, 'access', _66 => _66.route, 'optionalAccess', _67 => _67.path]))), () => ( _chunkLXBU5E77cjs.normalizeHttpRoute.call(void 0, _nullishCoalesce(request.path, () => ( request.url))))),
589
1008
  ...input
590
1009
  });
591
1010
  }
592
1011
  function makeFastifyRequestObservabilityContext(observability, request, input = {}) {
593
- return _chunkWBGRHGBPcjs.makeRequestObservabilityContext.call(void 0, observability, {
1012
+ return _chunkLXBU5E77cjs.makeRequestObservabilityContext.call(void 0, observability, {
594
1013
  headers: request.headers,
595
1014
  method: request.method,
596
- target: _chunkWBGRHGBPcjs.sanitizeHttpTarget.call(void 0, request.url),
597
- route: _nullishCoalesce(_nullishCoalesce(_nullishCoalesce(input.route, () => ( _optionalChain([request, 'access', _39 => _39.routeOptions, 'optionalAccess', _40 => _40.url]))), () => ( request.routerPath)), () => ( _chunkWBGRHGBPcjs.normalizeHttpRoute.call(void 0, request.url))),
1015
+ target: _chunkLXBU5E77cjs.sanitizeHttpTarget.call(void 0, request.url),
1016
+ route: _nullishCoalesce(_nullishCoalesce(_nullishCoalesce(input.route, () => ( _optionalChain([request, 'access', _68 => _68.routeOptions, 'optionalAccess', _69 => _69.url]))), () => ( request.routerPath)), () => ( _chunkLXBU5E77cjs.normalizeHttpRoute.call(void 0, request.url))),
598
1017
  ...input
599
1018
  });
600
1019
  }
@@ -608,14 +1027,14 @@ function urlPathname(url) {
608
1027
  if (!url) return void 0;
609
1028
  try {
610
1029
  return new URL(url, "http://local").pathname;
611
- } catch (e5) {
1030
+ } catch (e6) {
612
1031
  return url;
613
1032
  }
614
1033
  }
615
1034
 
616
1035
  // src/observability/config.ts
617
1036
  function makeNoopObservability() {
618
- return _chunkWBGRHGBPcjs.makeObservability.call(void 0, {
1037
+ return _chunkLXBU5E77cjs.makeObservability.call(void 0, {
619
1038
  metrics: false,
620
1039
  logs: false,
621
1040
  traces: false,
@@ -624,12 +1043,12 @@ function makeNoopObservability() {
624
1043
  }
625
1044
  function makeObservabilityPreset(preset, overrides = {}) {
626
1045
  if (preset === "disabled") return makeNoopObservability();
627
- return _chunkWBGRHGBPcjs.makeObservability.call(void 0, mergeObservabilityOptions(observabilityOptionsForPreset(preset), overrides));
1046
+ return _chunkLXBU5E77cjs.makeObservability.call(void 0, mergeObservabilityOptions(observabilityOptionsForPreset(preset), overrides));
628
1047
  }
629
1048
  function makeObservabilityFromEnv(env = readProcessEnv(), overrides = {}) {
630
1049
  const preset = env.BRASS_OBSERVABILITY === "disabled" ? "disabled" : parsePreset(_nullishCoalesce(env.BRASS_OBSERVABILITY_PRESET, () => ( env.NODE_ENV)));
631
1050
  if (preset === "disabled") return makeNoopObservability();
632
- return _chunkWBGRHGBPcjs.makeObservability.call(void 0, mergeObservabilityOptions(observabilityOptionsFromEnv(env, preset), overrides));
1051
+ return _chunkLXBU5E77cjs.makeObservability.call(void 0, mergeObservabilityOptions(observabilityOptionsFromEnv(env, preset), overrides));
633
1052
  }
634
1053
  function observabilityOptionsForPreset(preset) {
635
1054
  switch (preset) {
@@ -713,10 +1132,10 @@ function mergeObservabilityOptions(base, overrides) {
713
1132
  otlp: {
714
1133
  ..._nullishCoalesce(base.otlp, () => ( {})),
715
1134
  ..._nullishCoalesce(overrides.otlp, () => ( {})),
716
- retry: _nullishCoalesce(_optionalChain([overrides, 'access', _41 => _41.otlp, 'optionalAccess', _42 => _42.retry]), () => ( _optionalChain([base, 'access', _43 => _43.otlp, 'optionalAccess', _44 => _44.retry]))),
1135
+ retry: _nullishCoalesce(_optionalChain([overrides, 'access', _70 => _70.otlp, 'optionalAccess', _71 => _71.retry]), () => ( _optionalChain([base, 'access', _72 => _72.otlp, 'optionalAccess', _73 => _73.retry]))),
717
1136
  pipeline: {
718
- ..._nullishCoalesce(_optionalChain([base, 'access', _45 => _45.otlp, 'optionalAccess', _46 => _46.pipeline]), () => ( {})),
719
- ..._nullishCoalesce(_optionalChain([overrides, 'access', _47 => _47.otlp, 'optionalAccess', _48 => _48.pipeline]), () => ( {}))
1137
+ ..._nullishCoalesce(_optionalChain([base, 'access', _74 => _74.otlp, 'optionalAccess', _75 => _75.pipeline]), () => ( {})),
1138
+ ..._nullishCoalesce(_optionalChain([overrides, 'access', _76 => _76.otlp, 'optionalAccess', _77 => _77.pipeline]), () => ( {}))
720
1139
  }
721
1140
  }
722
1141
  };
@@ -759,6 +1178,92 @@ function readProcessEnv() {
759
1178
  return typeof process !== "undefined" ? process.env : {};
760
1179
  }
761
1180
 
1181
+ // src/observability/layer.ts
1182
+ var ObservabilityService = _chunk7TXQJFZXcjs.makeServiceTag.call(void 0, "Observability");
1183
+ function makeObservabilityLayer(config = {}, options = {}) {
1184
+ const tag = _nullishCoalesce(options.tag, () => ( ObservabilityService));
1185
+ return _chunk7TXQJFZXcjs.layerEffect.call(void 0,
1186
+ tag,
1187
+ (context) => _chunkMVGUEJ5Zcjs.asyncSync.call(void 0, () => _chunkLXBU5E77cjs.makeObservability.call(void 0, resolveObservabilityLayerConfig(config, context))),
1188
+ shutdownObservability
1189
+ );
1190
+ }
1191
+ function makeObservedRuntimeLayer(options = {}) {
1192
+ const {
1193
+ observabilityTag = ObservabilityService,
1194
+ runtimeTag = _chunk5XADBMSUcjs.RuntimeService,
1195
+ env = {},
1196
+ ...runtimeOptions
1197
+ } = options;
1198
+ return _chunk7TXQJFZXcjs.layerEffect.call(void 0,
1199
+ runtimeTag,
1200
+ (context) => _chunkMVGUEJ5Zcjs.asyncSync.call(void 0, () => {
1201
+ const observability = context.unsafeGet(observabilityTag);
1202
+ return new (0, _chunkSSQJKDN3cjs.Runtime)({
1203
+ ...runtimeOptions,
1204
+ env: mergeRuntimeEnv(resolveObservedRuntimeLayerEnv(env, context, observability), observability.env),
1205
+ hooks: observability.hooks
1206
+ });
1207
+ })
1208
+ );
1209
+ }
1210
+ function makeObservedHttpClientLayer(config = {}, options = {}) {
1211
+ const observabilityTag = _nullishCoalesce(options.observabilityTag, () => ( ObservabilityService));
1212
+ const httpTag = _nullishCoalesce(options.httpTag, () => ( _chunkVIFA4DPNcjs.HttpClientService));
1213
+ return _chunk7TXQJFZXcjs.layerEffect.call(void 0,
1214
+ httpTag,
1215
+ (context) => _chunkMVGUEJ5Zcjs.asyncSync.call(void 0, () => {
1216
+ const observability = context.unsafeGet(observabilityTag);
1217
+ const httpConfig = resolveObservedHttpClientLayerConfig(config, context, observability);
1218
+ const httpObservability = resolveObservedHttpObservabilityOptions(
1219
+ options.httpObservability,
1220
+ context,
1221
+ observability
1222
+ );
1223
+ return _chunkVIFA4DPNcjs.makeDefaultHttpClient.call(void 0, {
1224
+ ...httpConfig,
1225
+ middleware: [
1226
+ ..._nullishCoalesce(httpConfig.middleware, () => ( [])),
1227
+ withHttpObservability({
1228
+ metrics: observability.metrics,
1229
+ ...httpObservability
1230
+ })
1231
+ ]
1232
+ });
1233
+ }),
1234
+ shutdownDefaultHttpClient
1235
+ );
1236
+ }
1237
+ function resolveObservabilityLayerConfig(config, context) {
1238
+ return typeof config === "function" ? config(context) : config;
1239
+ }
1240
+ function resolveObservedHttpClientLayerConfig(config, context, observability) {
1241
+ return typeof config === "function" ? config(context, observability) : config;
1242
+ }
1243
+ function resolveObservedHttpObservabilityOptions(options, context, observability) {
1244
+ return typeof options === "function" ? options(context, observability) : _nullishCoalesce(options, () => ( {}));
1245
+ }
1246
+ function resolveObservedRuntimeLayerEnv(env, context, observability) {
1247
+ return typeof env === "function" ? env(context, observability) : env;
1248
+ }
1249
+ function mergeRuntimeEnv(env, observabilityEnv) {
1250
+ return Object.assign({}, env, observabilityEnv);
1251
+ }
1252
+ function shutdownObservability(observability) {
1253
+ return _chunkSSQJKDN3cjs.fromPromiseAbortable.call(void 0,
1254
+ () => observability.shutdown().then(() => void 0),
1255
+ () => void 0,
1256
+ { label: "observability.shutdown" }
1257
+ );
1258
+ }
1259
+ function shutdownDefaultHttpClient(client) {
1260
+ return client.shutdown();
1261
+ }
1262
+
1263
+
1264
+
1265
+
1266
+
762
1267
 
763
1268
 
764
1269
 
@@ -774,4 +1279,4 @@ function readProcessEnv() {
774
1279
 
775
1280
 
776
1281
 
777
- exports.HTTP_OBSERVABILITY_CONTRACT = HTTP_OBSERVABILITY_CONTRACT; exports.withHttpObservability = withHttpObservability; exports.makeHttpObservabilityMiddleware = makeHttpObservabilityMiddleware; exports.makeFetchRequestObservabilityContext = makeFetchRequestObservabilityContext; exports.makeNodeRequestObservabilityContext = makeNodeRequestObservabilityContext; exports.makeExpressRequestObservabilityContext = makeExpressRequestObservabilityContext; exports.makeFastifyRequestObservabilityContext = makeFastifyRequestObservabilityContext; exports.withFetchRequestObservability = withFetchRequestObservability; exports.withNodeRequestObservability = withNodeRequestObservability; exports.makeNoopObservability = makeNoopObservability; exports.makeObservabilityPreset = makeObservabilityPreset; exports.makeObservabilityFromEnv = makeObservabilityFromEnv; exports.observabilityOptionsForPreset = observabilityOptionsForPreset; exports.observabilityOptionsFromEnv = observabilityOptionsFromEnv;
1282
+ exports.HTTP_OBSERVABILITY_CONTRACT = HTTP_OBSERVABILITY_CONTRACT; exports.withHttpObservability = withHttpObservability; exports.makeHttpObservabilityMiddleware = makeHttpObservabilityMiddleware; exports.makeFetchRequestObservabilityContext = makeFetchRequestObservabilityContext; exports.makeNodeRequestObservabilityContext = makeNodeRequestObservabilityContext; exports.makeExpressRequestObservabilityContext = makeExpressRequestObservabilityContext; exports.makeFastifyRequestObservabilityContext = makeFastifyRequestObservabilityContext; exports.withFetchRequestObservability = withFetchRequestObservability; exports.withNodeRequestObservability = withNodeRequestObservability; exports.makeNoopObservability = makeNoopObservability; exports.makeObservabilityPreset = makeObservabilityPreset; exports.makeObservabilityFromEnv = makeObservabilityFromEnv; exports.observabilityOptionsForPreset = observabilityOptionsForPreset; exports.observabilityOptionsFromEnv = observabilityOptionsFromEnv; exports.ObservabilityService = ObservabilityService; exports.makeObservabilityLayer = makeObservabilityLayer; exports.makeObservedRuntimeLayer = makeObservedRuntimeLayer; exports.makeObservedHttpClientLayer = makeObservedHttpClientLayer;