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.
- 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-GYM3LLGS.mjs → chunk-2QNREG6K.mjs} +188 -5
- package/dist/{chunk-4ROBZFL6.cjs → chunk-2SLT3X6G.cjs} +6 -8
- package/dist/{chunk-KZJQ723N.cjs → chunk-3PFZGP23.cjs} +13 -15
- package/dist/{chunk-VWIPB6I5.js → chunk-3PHU7FWS.js} +528 -23
- package/dist/{chunk-BKK77SBA.js → chunk-4YQHPIWJ.js} +32 -11
- package/dist/chunk-5XADBMSU.cjs +33 -0
- package/dist/{chunk-DNFJLJMW.mjs → chunk-6MLAZPBL.mjs} +48 -24
- package/dist/chunk-7TKI527D.cjs +123 -0
- package/dist/{chunk-AGR5B2BC.cjs → chunk-7TXQJFZX.cjs} +564 -12
- package/dist/{chunk-RKGKFN2A.js → chunk-AADFFVYS.js} +1 -1
- package/dist/{chunk-52PPNNI4.cjs → chunk-AJMKZXRB.cjs} +2 -2
- package/dist/{chunk-3AYM6WPJ.js → chunk-BG5RNEA2.js} +20 -299
- package/dist/{chunk-2HQTDLHF.mjs → chunk-ELLF55ER.mjs} +555 -3
- package/dist/{chunk-EOC4UHBS.mjs → chunk-G5JTCFMI.mjs} +2 -2
- package/dist/chunk-H5GYX7RZ.js +6126 -0
- package/dist/{chunk-C3MDXTRZ.js → chunk-HCJ4S3YB.js} +48 -24
- package/dist/{chunk-6IXXWIUM.js → chunk-IBRHSH5H.js} +555 -3
- package/dist/{chunk-Q2I37RP3.cjs → chunk-IFRBVMWJ.cjs} +44 -323
- package/dist/{chunk-52OB2ROS.js → chunk-ITG6I7ZS.js} +2 -4
- package/dist/chunk-ITZQ526U.mjs +33 -0
- package/dist/{chunk-7JIJOVCT.js → chunk-JH4GI3DW.js} +2 -4
- package/dist/{chunk-F6XWZQY4.cjs → chunk-KHACHFBQ.cjs} +583 -78
- package/dist/{chunk-4P2HHGAX.mjs → chunk-KRYP6CAE.mjs} +32 -11
- package/dist/chunk-KTGDLBLD.mjs +123 -0
- package/dist/{chunk-WBGRHGBP.cjs → chunk-LXBU5E77.cjs} +114 -93
- package/dist/{chunk-PD4EJTQC.cjs → chunk-N6QNSTWD.cjs} +5 -5
- package/dist/{chunk-6RY2FFN4.mjs → chunk-OI4ESUMC.mjs} +9 -11
- package/dist/{chunk-EJ6BPYVR.mjs → chunk-OT2TESZU.mjs} +1 -1
- package/dist/{chunk-7X3K5RMS.js → chunk-PSEU65ND.js} +9 -11
- package/dist/{chunk-SK7UZRNI.mjs → chunk-QCOLAHU3.mjs} +528 -23
- package/dist/{chunk-KH4SYAOS.mjs → chunk-QZ6QFJNM.mjs} +20 -299
- package/dist/{chunk-MBEJI5HF.mjs → chunk-R6WDSZA6.mjs} +2 -4
- package/dist/{chunk-FHQGHPMO.mjs → chunk-RREBJX2S.mjs} +2 -4
- package/dist/{chunk-5QC7LRZ3.js → chunk-S4HHFUYP.js} +2 -2
- package/dist/{chunk-GLE2WY7Z.cjs → chunk-SSQJKDN3.cjs} +194 -11
- package/dist/{chunk-CZIVE6NT.cjs → chunk-UUMKZJRJ.cjs} +48 -24
- package/dist/chunk-VIFA4DPN.cjs +6126 -0
- package/dist/chunk-W6WR37HN.js +33 -0
- package/dist/{chunk-FH2X7BVP.js → chunk-XSAHV5HQ.js} +188 -5
- package/dist/chunk-YM3EDNYD.js +123 -0
- package/dist/{chunk-7ZPEZ57L.cjs → chunk-YTX2JYYP.cjs} +18 -20
- package/dist/chunk-Z3PSSXP3.mjs +6126 -0
- package/dist/core/index.cjs +31 -9
- package/dist/core/index.d.ts +19 -152
- package/dist/core/index.js +80 -58
- package/dist/core/index.mjs +80 -58
- package/dist/defaultClient-DhpCQW9m.d.ts +1623 -0
- package/dist/{effect-DIUHZ9IN.d.ts → effect-CtUDl5M5.d.ts} +1 -1
- package/dist/http/index.cjs +202 -59
- package/dist/http/index.d.ts +55 -819
- package/dist/http/index.js +216 -73
- package/dist/http/index.mjs +216 -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 +110 -88
- package/dist/index.d.ts +9 -8
- package/dist/index.js +81 -59
- package/dist/index.mjs +81 -59
- package/dist/{schedule-CK3Ml_7p.d.ts → layer-BalPI6cN.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-C1zVmqE6.d.ts} +5 -5
- package/dist/{stream-B4oK9JFP.d.ts → stream-Bb4FTejt.d.ts} +1 -1
- package/dist/{tracer-Hwt1cl7h.d.ts → tracer-DzfuE6um.d.ts} +2 -2
- package/dist/{tracing-DqbTKGcf.d.ts → tracing-BABA5arE.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 +4 -1
- 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,33 @@
|
|
|
1
|
+
import {
|
|
2
|
+
layerEffect,
|
|
3
|
+
makeServiceTag
|
|
4
|
+
} from "./chunk-IBRHSH5H.js";
|
|
5
|
+
import {
|
|
6
|
+
Runtime
|
|
7
|
+
} from "./chunk-XSAHV5HQ.js";
|
|
8
|
+
import {
|
|
9
|
+
asyncSync
|
|
10
|
+
} from "./chunk-UB4B6OFY.js";
|
|
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,12 +2,15 @@ import {
|
|
|
2
2
|
Async,
|
|
3
3
|
Cause,
|
|
4
4
|
Exit,
|
|
5
|
-
asyncEffect
|
|
5
|
+
asyncEffect,
|
|
6
|
+
asyncFlatMap,
|
|
7
|
+
asyncFold,
|
|
8
|
+
unit
|
|
6
9
|
} from "./chunk-UB4B6OFY.js";
|
|
7
10
|
import {
|
|
8
11
|
Schema,
|
|
9
12
|
parseConfig
|
|
10
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-HCJ4S3YB.js";
|
|
11
14
|
|
|
12
15
|
// src/core/runtime/ringBuffer.ts
|
|
13
16
|
var PushStatus = /* @__PURE__ */ ((PushStatus3) => {
|
|
@@ -2978,7 +2981,7 @@ var Runtime = class _Runtime {
|
|
|
2978
2981
|
if (this.hooks !== NoopHooks) return false;
|
|
2979
2982
|
if (getCurrentFiber() !== null) return false;
|
|
2980
2983
|
if (this.scheduler !== globalScheduler) return false;
|
|
2981
|
-
if (this.
|
|
2984
|
+
if (this.inferLane) return false;
|
|
2982
2985
|
if (this.engineMode !== "ts") return false;
|
|
2983
2986
|
new NativeTopLevelRunner(this, effect, cb).start();
|
|
2984
2987
|
return true;
|
|
@@ -3137,7 +3140,7 @@ var NativeTopLevelRunner = class {
|
|
|
3137
3140
|
syncExit = exit;
|
|
3138
3141
|
return;
|
|
3139
3142
|
}
|
|
3140
|
-
|
|
3143
|
+
this.resumeAsync(exit);
|
|
3141
3144
|
};
|
|
3142
3145
|
try {
|
|
3143
3146
|
current.register(this.runtime.env, resume);
|
|
@@ -4035,6 +4038,183 @@ var JsFiberEngine = class {
|
|
|
4035
4038
|
}
|
|
4036
4039
|
};
|
|
4037
4040
|
|
|
4041
|
+
// src/core/runtime/scope.ts
|
|
4042
|
+
var nextScopeId = 1;
|
|
4043
|
+
function awaitAll(fibers) {
|
|
4044
|
+
return asyncEffect((_env, cb) => {
|
|
4045
|
+
let remaining = fibers.length;
|
|
4046
|
+
if (remaining === 0) {
|
|
4047
|
+
cb({ _tag: "Success", value: void 0 });
|
|
4048
|
+
return;
|
|
4049
|
+
}
|
|
4050
|
+
for (const f of fibers) {
|
|
4051
|
+
f.join(() => {
|
|
4052
|
+
remaining -= 1;
|
|
4053
|
+
if (remaining === 0) cb({ _tag: "Success", value: void 0 });
|
|
4054
|
+
});
|
|
4055
|
+
}
|
|
4056
|
+
});
|
|
4057
|
+
}
|
|
4058
|
+
var Scope = class _Scope {
|
|
4059
|
+
constructor(runtime, parentScopeId) {
|
|
4060
|
+
this.runtime = runtime;
|
|
4061
|
+
this.parentScopeId = parentScopeId;
|
|
4062
|
+
this.id = nextScopeId++;
|
|
4063
|
+
const inferredParent = this.parentScopeId ?? getCurrentFiber()?.scopeId;
|
|
4064
|
+
if (this.runtime.hasActiveHooks()) {
|
|
4065
|
+
this.runtime.emit({
|
|
4066
|
+
type: "scope.open",
|
|
4067
|
+
scopeId: this.id,
|
|
4068
|
+
parentScopeId: inferredParent
|
|
4069
|
+
});
|
|
4070
|
+
}
|
|
4071
|
+
}
|
|
4072
|
+
runtime;
|
|
4073
|
+
parentScopeId;
|
|
4074
|
+
id;
|
|
4075
|
+
closed = false;
|
|
4076
|
+
children = /* @__PURE__ */ new Set();
|
|
4077
|
+
subScopes = /* @__PURE__ */ new Set();
|
|
4078
|
+
finalizers = [];
|
|
4079
|
+
/** registra un finalizer (LIFO) */
|
|
4080
|
+
addFinalizer(f) {
|
|
4081
|
+
if (this.closed) {
|
|
4082
|
+
throw new Error("Trying to add finalizer to closed scope");
|
|
4083
|
+
}
|
|
4084
|
+
this.finalizers.push(f);
|
|
4085
|
+
}
|
|
4086
|
+
/** crea un sub scope (mismo runtime) */
|
|
4087
|
+
subScope() {
|
|
4088
|
+
if (this.closed) throw new Error("Scope closed");
|
|
4089
|
+
const s = new _Scope(this.runtime, this.id);
|
|
4090
|
+
this.subScopes.add(s);
|
|
4091
|
+
return s;
|
|
4092
|
+
}
|
|
4093
|
+
/** ✅ fork en este scope */
|
|
4094
|
+
fork(eff) {
|
|
4095
|
+
if (this.closed) throw new Error("Scope closed");
|
|
4096
|
+
const f = this.runtime.fork(eff, this.id);
|
|
4097
|
+
this.children.add(f);
|
|
4098
|
+
f.join(() => this.children.delete(f));
|
|
4099
|
+
return f;
|
|
4100
|
+
}
|
|
4101
|
+
/** close fire-and-forget (no bloquea) */
|
|
4102
|
+
close(exit = { _tag: "Success", value: void 0 }) {
|
|
4103
|
+
this.runtime.fork(this.closeAsync(exit));
|
|
4104
|
+
}
|
|
4105
|
+
/** Emit the scope.close event if hooks are active. */
|
|
4106
|
+
emitCloseEvent(exit) {
|
|
4107
|
+
if (this.runtime.hasActiveHooks()) {
|
|
4108
|
+
const status = exit._tag === "Success" ? "success" : Cause.isInterruptedOnly(exit.cause) ? "interrupted" : "failure";
|
|
4109
|
+
const failure = exit._tag === "Failure" ? Cause.firstFailure(exit.cause) : void 0;
|
|
4110
|
+
this.runtime.emit({
|
|
4111
|
+
type: "scope.close",
|
|
4112
|
+
scopeId: this.id,
|
|
4113
|
+
status,
|
|
4114
|
+
error: failure?._tag === "Some" ? failure.value : exit._tag === "Failure" ? exit.cause : void 0
|
|
4115
|
+
});
|
|
4116
|
+
}
|
|
4117
|
+
}
|
|
4118
|
+
/**
|
|
4119
|
+
* Build an effect that executes finalizers in LIFO order.
|
|
4120
|
+
*
|
|
4121
|
+
* Optimization over the original: instead of wrapping every finalizer in
|
|
4122
|
+
* `asyncFold(fin(exit), () => unit(), () => unit())` which creates 3 effect
|
|
4123
|
+
* nodes per finalizer (Fold + 2 Succeed), we use a single Sync thunk per
|
|
4124
|
+
* finalizer that catches errors inline. When the finalizer returns a
|
|
4125
|
+
* Succeed effect (like `unit()`), the Sync thunk completes without creating
|
|
4126
|
+
* additional effect nodes.
|
|
4127
|
+
*/
|
|
4128
|
+
buildFinalizerEffect(exit) {
|
|
4129
|
+
const fins = this.finalizers;
|
|
4130
|
+
if (fins.length === 0) return unit();
|
|
4131
|
+
let chain = unit();
|
|
4132
|
+
for (let i = fins.length - 1; i >= 0; i--) {
|
|
4133
|
+
const fin = fins[i];
|
|
4134
|
+
chain = asyncFlatMap(chain, () => {
|
|
4135
|
+
let result;
|
|
4136
|
+
try {
|
|
4137
|
+
result = fin(exit);
|
|
4138
|
+
} catch {
|
|
4139
|
+
return unit();
|
|
4140
|
+
}
|
|
4141
|
+
if (result._tag === "Succeed") {
|
|
4142
|
+
return unit();
|
|
4143
|
+
}
|
|
4144
|
+
return asyncFold(
|
|
4145
|
+
result,
|
|
4146
|
+
() => unit(),
|
|
4147
|
+
() => unit()
|
|
4148
|
+
);
|
|
4149
|
+
});
|
|
4150
|
+
}
|
|
4151
|
+
return chain;
|
|
4152
|
+
}
|
|
4153
|
+
closeAsync(exit = { _tag: "Success", value: void 0 }, opts = { awaitChildren: true }) {
|
|
4154
|
+
return asyncFlatMap(
|
|
4155
|
+
unit(),
|
|
4156
|
+
() => asyncEffect((env, cb) => {
|
|
4157
|
+
if (this.closed) {
|
|
4158
|
+
cb({ _tag: "Success", value: void 0 });
|
|
4159
|
+
return;
|
|
4160
|
+
}
|
|
4161
|
+
this.closed = true;
|
|
4162
|
+
const children = Array.from(this.children);
|
|
4163
|
+
const subScopes = Array.from(this.subScopes);
|
|
4164
|
+
for (const child of children) {
|
|
4165
|
+
child.interrupt();
|
|
4166
|
+
}
|
|
4167
|
+
const closeSubs = subScopes.reduceRight(
|
|
4168
|
+
(acc, s) => asyncFlatMap(acc, () => s.closeAsync(exit, opts)),
|
|
4169
|
+
unit()
|
|
4170
|
+
);
|
|
4171
|
+
const runFinalizers = this.buildFinalizerEffect(exit);
|
|
4172
|
+
const needsAwait = opts.awaitChildren && children.length > 0;
|
|
4173
|
+
const awaitChildrenEff = needsAwait ? awaitAll(children) : unit();
|
|
4174
|
+
const hasSubScopes = subScopes.length > 0;
|
|
4175
|
+
const hasNoFinalizers = this.finalizers.length === 0;
|
|
4176
|
+
if (!hasSubScopes && !needsAwait && hasNoFinalizers) {
|
|
4177
|
+
this.emitCloseEvent(exit);
|
|
4178
|
+
cb({ _tag: "Success", value: void 0 });
|
|
4179
|
+
return;
|
|
4180
|
+
}
|
|
4181
|
+
const all = asyncFlatMap(closeSubs, () => asyncFlatMap(awaitChildrenEff, () => runFinalizers));
|
|
4182
|
+
this.runtime.fork(all).join(() => {
|
|
4183
|
+
this.emitCloseEvent(exit);
|
|
4184
|
+
cb({ _tag: "Success", value: void 0 });
|
|
4185
|
+
});
|
|
4186
|
+
})
|
|
4187
|
+
);
|
|
4188
|
+
}
|
|
4189
|
+
};
|
|
4190
|
+
function withScopeAsync(runtime, f) {
|
|
4191
|
+
return asyncEffect((_env, cb) => {
|
|
4192
|
+
const scope = new Scope(runtime);
|
|
4193
|
+
let done = false;
|
|
4194
|
+
const completeAfterClose = (exit) => {
|
|
4195
|
+
runtime.fork(scope.closeAsync(exit)).join(() => {
|
|
4196
|
+
if (done) return;
|
|
4197
|
+
done = true;
|
|
4198
|
+
cb(exit);
|
|
4199
|
+
});
|
|
4200
|
+
};
|
|
4201
|
+
const fiber = runtime.fork(f(scope));
|
|
4202
|
+
fiber.join(completeAfterClose);
|
|
4203
|
+
return () => {
|
|
4204
|
+
if (done) return;
|
|
4205
|
+
fiber.interrupt();
|
|
4206
|
+
runtime.fork(scope.closeAsync(Exit.failCause(Cause.interrupt())));
|
|
4207
|
+
};
|
|
4208
|
+
});
|
|
4209
|
+
}
|
|
4210
|
+
function withScope(runtime, f) {
|
|
4211
|
+
return withScopeAsync(runtime, (scope) => {
|
|
4212
|
+
const out = f(scope);
|
|
4213
|
+
if (out && typeof out === "object" && "_tag" in out) return out;
|
|
4214
|
+
return unit();
|
|
4215
|
+
});
|
|
4216
|
+
}
|
|
4217
|
+
|
|
4038
4218
|
export {
|
|
4039
4219
|
PushStatus,
|
|
4040
4220
|
RingBuffer,
|
|
@@ -4085,5 +4265,8 @@ export {
|
|
|
4085
4265
|
RuntimeFiber,
|
|
4086
4266
|
getCurrentFiber,
|
|
4087
4267
|
unsafeGetCurrentRuntime,
|
|
4088
|
-
withCurrentFiber
|
|
4268
|
+
withCurrentFiber,
|
|
4269
|
+
Scope,
|
|
4270
|
+
withScopeAsync,
|
|
4271
|
+
withScope
|
|
4089
4272
|
};
|
|
@@ -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
|
+
};
|
|
@@ -1,26 +1,24 @@
|
|
|
1
1
|
"use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } async function _asyncNullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return await 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
3
|
|
|
4
|
-
var
|
|
4
|
+
var _chunkN6QNSTWDcjs = require('./chunk-N6QNSTWD.cjs');
|
|
5
5
|
|
|
6
6
|
|
|
7
|
-
var
|
|
7
|
+
var _chunkKHACHFBQcjs = require('./chunk-KHACHFBQ.cjs');
|
|
8
8
|
|
|
9
9
|
|
|
10
|
-
var
|
|
10
|
+
var _chunkLXBU5E77cjs = require('./chunk-LXBU5E77.cjs');
|
|
11
11
|
|
|
12
12
|
|
|
13
|
-
var
|
|
13
|
+
var _chunkAJMKZXRBcjs = require('./chunk-AJMKZXRB.cjs');
|
|
14
14
|
|
|
15
15
|
|
|
16
|
-
var _chunkWBGRHGBPcjs = require('./chunk-WBGRHGBP.cjs');
|
|
17
16
|
|
|
17
|
+
var _chunkVIFA4DPNcjs = require('./chunk-VIFA4DPN.cjs');
|
|
18
18
|
|
|
19
|
-
var _chunk52PPNNI4cjs = require('./chunk-52PPNNI4.cjs');
|
|
20
19
|
|
|
21
20
|
|
|
22
|
-
|
|
23
|
-
var _chunkGLE2WY7Zcjs = require('./chunk-GLE2WY7Z.cjs');
|
|
21
|
+
var _chunkSSQJKDN3cjs = require('./chunk-SSQJKDN3.cjs');
|
|
24
22
|
|
|
25
23
|
|
|
26
24
|
|
|
@@ -301,10 +299,10 @@ function makeRuntimeCase(variant, chainDepth) {
|
|
|
301
299
|
maxCapacity: 8192,
|
|
302
300
|
flushBudget: 2048
|
|
303
301
|
};
|
|
304
|
-
const scheduler = variant === "wide-scheduler" ? new (0,
|
|
305
|
-
const recorder = variant === "recorder" ?
|
|
306
|
-
const hooks = _nullishCoalesce(_optionalChain([recorder, 'optionalAccess', _8 => _8.hooks]), () => ( (variant === "active-hooks" ? new (0,
|
|
307
|
-
const runtime =
|
|
302
|
+
const scheduler = variant === "wide-scheduler" ? new (0, _chunkSSQJKDN3cjs.Scheduler)(schedulerConfig) : void 0;
|
|
303
|
+
const recorder = variant === "recorder" ? _chunkN6QNSTWDcjs.makeRuntimeRecorder.call(void 0, { maxEvents: 1e4 }) : void 0;
|
|
304
|
+
const hooks = _nullishCoalesce(_optionalChain([recorder, 'optionalAccess', _8 => _8.hooks]), () => ( (variant === "active-hooks" ? new (0, _chunkAJMKZXRBcjs.EventBus)() : void 0)));
|
|
305
|
+
const runtime = _chunkSSQJKDN3cjs.Runtime.makeWithEngine(hooks ? {} : {}, "ts", {
|
|
308
306
|
hooks,
|
|
309
307
|
...scheduler ? { scheduler } : {},
|
|
310
308
|
inferLane: false
|
|
@@ -351,7 +349,7 @@ function makeFlatMapChain(depth) {
|
|
|
351
349
|
return effect;
|
|
352
350
|
}
|
|
353
351
|
function makeFiberRefProgram(depth) {
|
|
354
|
-
const ref =
|
|
352
|
+
const ref = _chunkN6QNSTWDcjs.makeFiberRef.call(void 0, 0);
|
|
355
353
|
let effect = ref.set(0);
|
|
356
354
|
for (let i = 0; i < depth; i++) {
|
|
357
355
|
effect = _chunkMVGUEJ5Zcjs.asyncFlatMap.call(void 0, effect, () => ref.update((n) => n + 1));
|
|
@@ -653,7 +651,7 @@ async function profileHttpLayers(options = {}) {
|
|
|
653
651
|
}
|
|
654
652
|
async function runScenario(scenario) {
|
|
655
653
|
const server = await startDummyServer(scenario.delayMs);
|
|
656
|
-
const observability = scenario.variant === "default-json-observed" ?
|
|
654
|
+
const observability = scenario.variant === "default-json-observed" ? _chunkLXBU5E77cjs.makeObservability.call(void 0, {
|
|
657
655
|
logs: false,
|
|
658
656
|
traces: { maxFinishedSpans: 1e4 },
|
|
659
657
|
autoStart: false
|
|
@@ -840,9 +838,9 @@ function makeDefaultJsonRunner(server, scenario, preset, disableAdaptiveLimiter
|
|
|
840
838
|
}
|
|
841
839
|
function makeProfileRuntime(concurrency, observability) {
|
|
842
840
|
const capacity = Math.max(65536, concurrency * 8);
|
|
843
|
-
return
|
|
841
|
+
return _chunkSSQJKDN3cjs.Runtime.makeWithEngine(_nullishCoalesce(_optionalChain([observability, 'optionalAccess', _30 => _30.env]), () => ( {})), "ts", {
|
|
844
842
|
hooks: _optionalChain([observability, 'optionalAccess', _31 => _31.hooks]),
|
|
845
|
-
scheduler: new (0,
|
|
843
|
+
scheduler: new (0, _chunkSSQJKDN3cjs.Scheduler)({
|
|
846
844
|
laneMode: "single",
|
|
847
845
|
initialCapacity: capacity,
|
|
848
846
|
maxCapacity: capacity,
|
|
@@ -864,24 +862,24 @@ function baseHttpConfig(baseUrl, scenario) {
|
|
|
864
862
|
};
|
|
865
863
|
}
|
|
866
864
|
function makeWireClient(baseUrl, scenario) {
|
|
867
|
-
return
|
|
865
|
+
return _chunkVIFA4DPNcjs.makeHttp.call(void 0, baseHttpConfig(baseUrl, scenario));
|
|
868
866
|
}
|
|
869
867
|
function makeMinimalClient(baseUrl, scenario) {
|
|
870
|
-
return
|
|
868
|
+
return _chunkVIFA4DPNcjs.makeDefaultHttpClient.call(void 0, {
|
|
871
869
|
preset: "minimal",
|
|
872
870
|
compression: false,
|
|
873
871
|
...baseHttpConfig(baseUrl, scenario)
|
|
874
872
|
});
|
|
875
873
|
}
|
|
876
874
|
function makeDefaultClient(baseUrl, scenario, preset, disableAdaptiveLimiter, observability) {
|
|
877
|
-
return
|
|
875
|
+
return _chunkVIFA4DPNcjs.makeDefaultHttpClient.call(void 0, {
|
|
878
876
|
preset,
|
|
879
877
|
compression: false,
|
|
880
878
|
...baseHttpConfig(baseUrl, scenario),
|
|
881
879
|
...disableAdaptiveLimiter ? { adaptiveLimiter: false } : {},
|
|
882
880
|
...observability ? {
|
|
883
881
|
middleware: [
|
|
884
|
-
|
|
882
|
+
_chunkKHACHFBQcjs.withHttpObservability.call(void 0, {
|
|
885
883
|
metrics: observability.metrics,
|
|
886
884
|
logs: false,
|
|
887
885
|
spans: {},
|