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.
- package/README.md +36 -3
- package/dist/agent/cli/main.cjs +31 -32
- package/dist/agent/cli/main.js +3 -4
- package/dist/agent/cli/main.mjs +3 -4
- package/dist/agent/index.cjs +4 -5
- package/dist/agent/index.d.ts +1 -1
- package/dist/agent/index.js +3 -4
- package/dist/agent/index.mjs +3 -4
- package/dist/{chunk-7X3K5RMS.js → chunk-22HZQG5F.js} +9 -11
- package/dist/{chunk-GLE2WY7Z.cjs → chunk-2JHJ4YHS.cjs} +417 -124
- package/dist/{chunk-Q2I37RP3.cjs → chunk-2OW6IFY2.cjs} +44 -323
- package/dist/{chunk-7ZPEZ57L.cjs → chunk-5LC7V2OZ.cjs} +18 -20
- package/dist/{chunk-AGR5B2BC.cjs → chunk-5RZ7YITF.cjs} +564 -12
- package/dist/{chunk-DNFJLJMW.mjs → chunk-6MLAZPBL.mjs} +48 -24
- package/dist/{chunk-EJ6BPYVR.mjs → chunk-6V2AWT4R.mjs} +1 -1
- package/dist/{chunk-3AYM6WPJ.js → chunk-7DU7IQHK.js} +20 -299
- package/dist/{chunk-SK7UZRNI.mjs → chunk-7GBJYOX7.mjs} +528 -23
- package/dist/chunk-7TKI527D.cjs +123 -0
- package/dist/{chunk-52OB2ROS.js → chunk-7VQLEN37.js} +2 -4
- package/dist/{chunk-KH4SYAOS.mjs → chunk-B5FKOLTB.mjs} +20 -299
- package/dist/{chunk-FHQGHPMO.mjs → chunk-BC6Q6BCO.mjs} +2 -4
- package/dist/{chunk-4P2HHGAX.mjs → chunk-COOW7BJX.mjs} +32 -11
- package/dist/{chunk-2HQTDLHF.mjs → chunk-EEN5OTCR.mjs} +555 -3
- package/dist/{chunk-KZJQ723N.cjs → chunk-EICAJDNX.cjs} +13 -15
- package/dist/chunk-ELIECDYN.cjs +33 -0
- package/dist/{chunk-GYM3LLGS.mjs → chunk-H626ZTDZ.mjs} +399 -106
- package/dist/{chunk-C3MDXTRZ.js → chunk-HCJ4S3YB.js} +48 -24
- package/dist/{chunk-7JIJOVCT.js → chunk-IPSMXUWA.js} +2 -4
- package/dist/{chunk-4ROBZFL6.cjs → chunk-J6DUHITE.cjs} +6 -8
- package/dist/{chunk-6RY2FFN4.mjs → chunk-JWIEMBE6.mjs} +9 -11
- package/dist/{chunk-PD4EJTQC.cjs → chunk-KNTJ7FQB.cjs} +5 -5
- package/dist/chunk-KTGDLBLD.mjs +123 -0
- package/dist/chunk-LSYQ3C2M.js +33 -0
- package/dist/{chunk-RKGKFN2A.js → chunk-OW5VHAOE.js} +1 -1
- package/dist/{chunk-EOC4UHBS.mjs → chunk-RBHNOKH4.mjs} +2 -2
- package/dist/{chunk-6IXXWIUM.js → chunk-S4HXADU4.js} +555 -3
- package/dist/{chunk-FH2X7BVP.js → chunk-TTSPIU3U.js} +399 -106
- package/dist/{chunk-5QC7LRZ3.js → chunk-UAKAF32U.js} +2 -2
- package/dist/{chunk-CZIVE6NT.cjs → chunk-UUMKZJRJ.cjs} +48 -24
- package/dist/{chunk-MBEJI5HF.mjs → chunk-WCBNXPN6.mjs} +2 -4
- package/dist/{chunk-52PPNNI4.cjs → chunk-WGE2FEZE.cjs} +2 -2
- package/dist/{chunk-WBGRHGBP.cjs → chunk-WI7GZF3B.cjs} +114 -93
- package/dist/chunk-WUDHOZIH.js +6234 -0
- package/dist/{chunk-F6XWZQY4.cjs → chunk-WVSZOPGQ.cjs} +583 -78
- package/dist/chunk-XPIMJQYS.cjs +6234 -0
- package/dist/{chunk-VWIPB6I5.js → chunk-YGR2IN4R.js} +528 -23
- package/dist/chunk-YM3EDNYD.js +123 -0
- package/dist/chunk-YWLLH27R.mjs +33 -0
- package/dist/{chunk-BKK77SBA.js → chunk-YZ5LQ32F.js} +32 -11
- package/dist/chunk-Z3ZZMQUZ.mjs +6234 -0
- package/dist/core/index.cjs +37 -9
- package/dist/core/index.d.ts +19 -152
- package/dist/core/index.js +86 -58
- package/dist/core/index.mjs +86 -58
- package/dist/defaultClient-Cid0JoUR.d.ts +1648 -0
- package/dist/{effect-DIUHZ9IN.d.ts → effect-DnGUuhw6.d.ts} +22 -1
- package/dist/http/index.cjs +206 -59
- package/dist/http/index.d.ts +55 -819
- package/dist/http/index.js +220 -73
- package/dist/http/index.mjs +220 -73
- package/dist/http/testing.cjs +31 -10
- package/dist/http/testing.d.ts +16 -5
- package/dist/http/testing.js +29 -8
- package/dist/http/testing.mjs +29 -8
- package/dist/index.cjs +116 -88
- package/dist/index.d.ts +9 -8
- package/dist/index.js +87 -59
- package/dist/index.mjs +87 -59
- package/dist/{schedule-CK3Ml_7p.d.ts → layer-D2LFcBVx.d.ts} +176 -2
- package/dist/observability/index.cjs +20 -7
- package/dist/observability/index.d.ts +32 -8
- package/dist/observability/index.js +19 -6
- package/dist/observability/index.mjs +19 -6
- package/dist/perf/cli.cjs +26 -28
- package/dist/perf/cli.js +11 -13
- package/dist/perf/cli.mjs +11 -13
- package/dist/perf/index.cjs +13 -15
- package/dist/perf/index.js +11 -13
- package/dist/perf/index.mjs +11 -13
- package/dist/schema/index.cjs +2 -2
- package/dist/schema/index.js +1 -1
- package/dist/schema/index.mjs +1 -1
- package/dist/{server-D6JZ15_e.d.ts → server-Bf1zNYZk.d.ts} +5 -5
- package/dist/{stream-B4oK9JFP.d.ts → stream-I7bkvF7a.d.ts} +1 -1
- package/dist/{tracer-Hwt1cl7h.d.ts → tracer-DF83nLn6.d.ts} +2 -2
- package/dist/{tracing-DqbTKGcf.d.ts → tracing-CWV4gT0u.d.ts} +1 -1
- package/docs/README.md +2 -0
- package/docs/ai/PUBLIC_API.md +28 -7
- package/docs/articles/brass-runtime-http-observability.md +467 -0
- package/docs/frameworks/angular.md +51 -0
- package/docs/frameworks/express.md +58 -0
- package/docs/frameworks/fastify.md +49 -0
- package/docs/frameworks/nestjs.md +53 -0
- package/docs/frameworks/nextjs.md +55 -0
- package/docs/frameworks/react.md +44 -0
- package/docs/frameworks/vanilla.md +56 -0
- package/docs/guides/layers.md +130 -0
- package/docs/http-recipes.md +31 -1
- package/docs/http.md +50 -1
- package/docs/observability.md +132 -0
- package/docs/performance-profiler.md +6 -2
- package/docs/recipes/layers.md +46 -2
- package/docs/recipes/testing.md +25 -0
- package/package.json +6 -2
- package/dist/chunk-3LOYJFRR.cjs +0 -300
- package/dist/chunk-3Y2RIUMM.js +0 -300
- package/dist/chunk-5EC274J5.cjs +0 -2874
- package/dist/chunk-5VRJNBLZ.mjs +0 -2874
- package/dist/chunk-62AZW6UT.cjs +0 -313
- package/dist/chunk-74ZTY6CP.js +0 -2871
- package/dist/chunk-7CMJS3QE.mjs +0 -2871
- package/dist/chunk-A2OM6NEH.mjs +0 -194
- package/dist/chunk-B33ICAKP.js +0 -313
- package/dist/chunk-JF5WGYJJ.cjs +0 -194
- package/dist/chunk-KN32XNTH.mjs +0 -313
- package/dist/chunk-KQLYONSE.cjs +0 -2871
- package/dist/chunk-L2SYFEBS.js +0 -194
- package/dist/chunk-MIIYDLGM.js +0 -2874
- package/dist/chunk-PWC3RBQE.mjs +0 -300
- 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-
|
|
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-
|
|
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-
|
|
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
|
|
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
|
-
|
|
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([
|