brass-runtime 1.17.0 → 1.18.1

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-7X3K5RMS.js → chunk-22HZQG5F.js} +9 -11
  10. package/dist/{chunk-GLE2WY7Z.cjs → chunk-2JHJ4YHS.cjs} +417 -124
  11. package/dist/{chunk-Q2I37RP3.cjs → chunk-2OW6IFY2.cjs} +44 -323
  12. package/dist/{chunk-7ZPEZ57L.cjs → chunk-5LC7V2OZ.cjs} +18 -20
  13. package/dist/{chunk-AGR5B2BC.cjs → chunk-5RZ7YITF.cjs} +564 -12
  14. package/dist/{chunk-DNFJLJMW.mjs → chunk-6MLAZPBL.mjs} +48 -24
  15. package/dist/{chunk-EJ6BPYVR.mjs → chunk-6V2AWT4R.mjs} +1 -1
  16. package/dist/{chunk-3AYM6WPJ.js → chunk-7DU7IQHK.js} +20 -299
  17. package/dist/{chunk-SK7UZRNI.mjs → chunk-7GBJYOX7.mjs} +528 -23
  18. package/dist/chunk-7TKI527D.cjs +123 -0
  19. package/dist/{chunk-52OB2ROS.js → chunk-7VQLEN37.js} +2 -4
  20. package/dist/{chunk-KH4SYAOS.mjs → chunk-B5FKOLTB.mjs} +20 -299
  21. package/dist/{chunk-FHQGHPMO.mjs → chunk-BC6Q6BCO.mjs} +2 -4
  22. package/dist/{chunk-4P2HHGAX.mjs → chunk-COOW7BJX.mjs} +32 -11
  23. package/dist/{chunk-2HQTDLHF.mjs → chunk-EEN5OTCR.mjs} +555 -3
  24. package/dist/{chunk-KZJQ723N.cjs → chunk-EICAJDNX.cjs} +13 -15
  25. package/dist/chunk-ELIECDYN.cjs +33 -0
  26. package/dist/{chunk-GYM3LLGS.mjs → chunk-H626ZTDZ.mjs} +399 -106
  27. package/dist/{chunk-C3MDXTRZ.js → chunk-HCJ4S3YB.js} +48 -24
  28. package/dist/{chunk-7JIJOVCT.js → chunk-IPSMXUWA.js} +2 -4
  29. package/dist/{chunk-4ROBZFL6.cjs → chunk-J6DUHITE.cjs} +6 -8
  30. package/dist/{chunk-6RY2FFN4.mjs → chunk-JWIEMBE6.mjs} +9 -11
  31. package/dist/{chunk-PD4EJTQC.cjs → chunk-KNTJ7FQB.cjs} +5 -5
  32. package/dist/chunk-KTGDLBLD.mjs +123 -0
  33. package/dist/chunk-LSYQ3C2M.js +33 -0
  34. package/dist/{chunk-RKGKFN2A.js → chunk-OW5VHAOE.js} +1 -1
  35. package/dist/{chunk-EOC4UHBS.mjs → chunk-RBHNOKH4.mjs} +2 -2
  36. package/dist/{chunk-6IXXWIUM.js → chunk-S4HXADU4.js} +555 -3
  37. package/dist/{chunk-FH2X7BVP.js → chunk-TTSPIU3U.js} +399 -106
  38. package/dist/{chunk-5QC7LRZ3.js → chunk-UAKAF32U.js} +2 -2
  39. package/dist/{chunk-CZIVE6NT.cjs → chunk-UUMKZJRJ.cjs} +48 -24
  40. package/dist/{chunk-MBEJI5HF.mjs → chunk-WCBNXPN6.mjs} +2 -4
  41. package/dist/{chunk-52PPNNI4.cjs → chunk-WGE2FEZE.cjs} +2 -2
  42. package/dist/{chunk-WBGRHGBP.cjs → chunk-WI7GZF3B.cjs} +114 -93
  43. package/dist/chunk-WUDHOZIH.js +6234 -0
  44. package/dist/{chunk-F6XWZQY4.cjs → chunk-WVSZOPGQ.cjs} +583 -78
  45. package/dist/chunk-XPIMJQYS.cjs +6234 -0
  46. package/dist/{chunk-VWIPB6I5.js → chunk-YGR2IN4R.js} +528 -23
  47. package/dist/chunk-YM3EDNYD.js +123 -0
  48. package/dist/chunk-YWLLH27R.mjs +33 -0
  49. package/dist/{chunk-BKK77SBA.js → chunk-YZ5LQ32F.js} +32 -11
  50. package/dist/chunk-Z3ZZMQUZ.mjs +6234 -0
  51. package/dist/core/index.cjs +37 -9
  52. package/dist/core/index.d.ts +19 -152
  53. package/dist/core/index.js +86 -58
  54. package/dist/core/index.mjs +86 -58
  55. package/dist/defaultClient-Cid0JoUR.d.ts +1648 -0
  56. package/dist/{effect-DIUHZ9IN.d.ts → effect-DnGUuhw6.d.ts} +22 -1
  57. package/dist/http/index.cjs +206 -59
  58. package/dist/http/index.d.ts +55 -819
  59. package/dist/http/index.js +220 -73
  60. package/dist/http/index.mjs +220 -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 +116 -88
  66. package/dist/index.d.ts +9 -8
  67. package/dist/index.js +87 -59
  68. package/dist/index.mjs +87 -59
  69. package/dist/{schedule-CK3Ml_7p.d.ts → layer-D2LFcBVx.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-Bf1zNYZk.d.ts} +5 -5
  84. package/dist/{stream-B4oK9JFP.d.ts → stream-I7bkvF7a.d.ts} +1 -1
  85. package/dist/{tracer-Hwt1cl7h.d.ts → tracer-DF83nLn6.d.ts} +2 -2
  86. package/dist/{tracing-DqbTKGcf.d.ts → tracing-CWV4gT0u.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 +6 -2
  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
@@ -0,0 +1,123 @@
1
+ import {
2
+ asyncFail,
3
+ asyncFold,
4
+ asyncSucceed
5
+ } from "./chunk-UB4B6OFY.js";
6
+
7
+ // src/core/runtime/circuitBreaker.ts
8
+ function makeCircuitBreaker(config = {}) {
9
+ const failureThreshold = config.failureThreshold ?? 5;
10
+ const resetTimeoutMs = config.resetTimeoutMs ?? 3e4;
11
+ const successThreshold = config.successThreshold ?? 1;
12
+ const isFailure = config.isFailure ?? (() => true);
13
+ const onStateChange = config.onStateChange;
14
+ let currentState = "closed";
15
+ let consecutiveFailures = 0;
16
+ let consecutiveSuccesses = 0;
17
+ let openedAt = 0;
18
+ let totalRequests = 0;
19
+ let totalFailures = 0;
20
+ let totalSuccesses = 0;
21
+ let totalRejected = 0;
22
+ let lastFailureTime = null;
23
+ let lastSuccessTime = null;
24
+ const transition = (to) => {
25
+ if (currentState === to) return;
26
+ const from = currentState;
27
+ currentState = to;
28
+ onStateChange?.(from, to);
29
+ };
30
+ const onSuccess = () => {
31
+ totalSuccesses++;
32
+ lastSuccessTime = Date.now();
33
+ consecutiveFailures = 0;
34
+ if (currentState === "half-open") {
35
+ consecutiveSuccesses++;
36
+ if (consecutiveSuccesses >= successThreshold) {
37
+ consecutiveSuccesses = 0;
38
+ transition("closed");
39
+ }
40
+ }
41
+ };
42
+ const onFailure = (error) => {
43
+ if (!isFailure(error)) {
44
+ onSuccess();
45
+ return;
46
+ }
47
+ totalFailures++;
48
+ lastFailureTime = Date.now();
49
+ consecutiveSuccesses = 0;
50
+ consecutiveFailures++;
51
+ if (currentState === "half-open") {
52
+ openedAt = Date.now();
53
+ transition("open");
54
+ } else if (currentState === "closed" && consecutiveFailures >= failureThreshold) {
55
+ openedAt = Date.now();
56
+ transition("open");
57
+ }
58
+ };
59
+ const shouldAllow = () => {
60
+ switch (currentState) {
61
+ case "closed":
62
+ return true;
63
+ case "open": {
64
+ const elapsed = Date.now() - openedAt;
65
+ if (elapsed >= resetTimeoutMs) {
66
+ transition("half-open");
67
+ return true;
68
+ }
69
+ return false;
70
+ }
71
+ case "half-open":
72
+ return true;
73
+ }
74
+ };
75
+ const protect = (effect) => {
76
+ totalRequests++;
77
+ if (!shouldAllow()) {
78
+ totalRejected++;
79
+ return asyncFail({
80
+ _tag: "CircuitBreakerOpen",
81
+ openSince: openedAt,
82
+ failures: consecutiveFailures
83
+ });
84
+ }
85
+ return asyncFold(
86
+ effect,
87
+ (error) => {
88
+ onFailure(error);
89
+ return asyncFail(error);
90
+ },
91
+ (value) => {
92
+ onSuccess();
93
+ return asyncSucceed(value);
94
+ }
95
+ );
96
+ };
97
+ const stats = () => ({
98
+ state: currentState,
99
+ failures: consecutiveFailures,
100
+ successes: consecutiveSuccesses,
101
+ totalRequests,
102
+ totalFailures,
103
+ totalSuccesses,
104
+ totalRejected,
105
+ lastFailureTime,
106
+ lastSuccessTime
107
+ });
108
+ const reset = () => {
109
+ consecutiveFailures = 0;
110
+ consecutiveSuccesses = 0;
111
+ transition("closed");
112
+ };
113
+ return {
114
+ state: () => currentState,
115
+ protect,
116
+ stats,
117
+ reset
118
+ };
119
+ }
120
+
121
+ export {
122
+ makeCircuitBreaker
123
+ };
@@ -0,0 +1,33 @@
1
+ import {
2
+ layerEffect,
3
+ makeServiceTag
4
+ } from "./chunk-EEN5OTCR.mjs";
5
+ import {
6
+ Runtime
7
+ } from "./chunk-H626ZTDZ.mjs";
8
+ import {
9
+ asyncSync
10
+ } from "./chunk-36I3M4UC.mjs";
11
+
12
+ // src/core/runtime/runtimeLayer.ts
13
+ var RuntimeService = makeServiceTag("Runtime");
14
+ function makeRuntimeLayer(env = {}, options = {}) {
15
+ const { tag = RuntimeService, ...runtimeOptions } = options;
16
+ return layerEffect(
17
+ tag,
18
+ (context) => asyncSync(
19
+ () => new Runtime({
20
+ ...runtimeOptions,
21
+ env: resolveRuntimeLayerEnv(env, context)
22
+ })
23
+ )
24
+ );
25
+ }
26
+ function resolveRuntimeLayerEnv(env, context) {
27
+ return typeof env === "function" ? env(context) : env;
28
+ }
29
+
30
+ export {
31
+ RuntimeService,
32
+ makeRuntimeLayer
33
+ };
@@ -2,14 +2,14 @@ import {
2
2
  EventBus,
3
3
  InMemoryTracer,
4
4
  makeMetrics
5
- } from "./chunk-RKGKFN2A.js";
5
+ } from "./chunk-OW5VHAOE.js";
6
6
  import {
7
7
  Runtime,
8
8
  ctxExtend,
9
9
  ctxToObject,
10
10
  emptyContext,
11
11
  getCurrentFiber
12
- } from "./chunk-FH2X7BVP.js";
12
+ } from "./chunk-TTSPIU3U.js";
13
13
  import {
14
14
  asyncFail,
15
15
  asyncFlatMap,
@@ -20,7 +20,7 @@ import {
20
20
  import {
21
21
  Schema,
22
22
  parseConfig
23
- } from "./chunk-C3MDXTRZ.js";
23
+ } from "./chunk-HCJ4S3YB.js";
24
24
 
25
25
  // src/observability/health.ts
26
26
  function snapshotRuntimeHealth(options = {}) {
@@ -881,24 +881,25 @@ function normalizeLogAttributes(fields) {
881
881
  }
882
882
 
883
883
  // src/observability/sampling.ts
884
- var alwaysOnSampler = {
884
+ var TRACE_SAMPLER_RATIO = /* @__PURE__ */ Symbol.for("brass-runtime.traceSampler.ratio");
885
+ var alwaysOnSampler = withRatio({
885
886
  shouldSample: () => true
886
- };
887
- var alwaysOffSampler = {
887
+ }, 1);
888
+ var alwaysOffSampler = withRatio({
888
889
  shouldSample: () => false
889
- };
890
+ }, 0);
890
891
  function ratioSampler(ratio2) {
891
892
  const bounded = clampRatio(ratio2);
892
893
  if (bounded >= 1) return alwaysOnSampler;
893
894
  if (bounded <= 0) return alwaysOffSampler;
894
- return {
895
+ return withRatio({
895
896
  shouldSample: (input) => traceRatio(input.traceId) < bounded
896
- };
897
+ }, bounded);
897
898
  }
898
899
  function makeTraceSampler(options = {}) {
899
900
  const fallback = options.sampler ?? ratioSampler(options.ratio ?? 1);
900
901
  const rules = options.rules ?? [];
901
- return {
902
+ const sampler = {
902
903
  shouldSample(input) {
903
904
  for (const rule of rules) {
904
905
  if (!samplingRuleMatches(rule, input)) continue;
@@ -908,6 +909,8 @@ function makeTraceSampler(options = {}) {
908
909
  return shouldSampleWith(fallback, input);
909
910
  }
910
911
  };
912
+ const fallbackRatio = samplerRatio(fallback);
913
+ return rules.length === 0 && fallbackRatio !== void 0 ? withRatio(sampler, fallbackRatio) : sampler;
911
914
  }
912
915
  function resolveTraceSampling(config) {
913
916
  if (config === false) {
@@ -942,6 +945,22 @@ function matchText(pattern, value) {
942
945
  function isTraceSampler(value) {
943
946
  return typeof value === "function" || typeof value === "object" && value !== null && typeof value.shouldSample === "function";
944
947
  }
948
+ function samplerRatio(sampler) {
949
+ if (!sampler || typeof sampler === "function") return void 0;
950
+ const ratio2 = sampler[TRACE_SAMPLER_RATIO];
951
+ return typeof ratio2 === "number" && Number.isFinite(ratio2) ? ratio2 : void 0;
952
+ }
953
+ function withRatio(sampler, ratio2) {
954
+ try {
955
+ Object.defineProperty(sampler, TRACE_SAMPLER_RATIO, {
956
+ configurable: false,
957
+ enumerable: false,
958
+ value: ratio2
959
+ });
960
+ } catch {
961
+ }
962
+ return sampler;
963
+ }
945
964
  function traceRatio(traceId) {
946
965
  const normalized = normalizeTraceId(traceId);
947
966
  const head = normalized.slice(0, 8);
@@ -1538,7 +1557,9 @@ var httpObservabilityOptions = Schema.object({
1538
1557
  Schema.literal(false),
1539
1558
  Schema.object({
1540
1559
  name: Schema.union([Schema.string({ minLength: 1 }), fn]).optional(),
1541
- attributes: Schema.union([object, fn]).optional()
1560
+ attributes: Schema.union([object, fn]).optional(),
1561
+ events: Schema.boolean().optional(),
1562
+ sampleRate: ratio.optional()
1542
1563
  }, { unknownKeys: "passthrough" })
1543
1564
  ]).optional(),
1544
1565
  adaptiveLimiter: Schema.union([