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
package/dist/chunk-A2OM6NEH.mjs
DELETED
|
@@ -1,194 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
getCurrentFiber
|
|
3
|
-
} from "./chunk-GYM3LLGS.mjs";
|
|
4
|
-
import {
|
|
5
|
-
Cause,
|
|
6
|
-
Exit,
|
|
7
|
-
asyncEffect,
|
|
8
|
-
asyncFlatMap,
|
|
9
|
-
asyncFold,
|
|
10
|
-
unit
|
|
11
|
-
} from "./chunk-36I3M4UC.mjs";
|
|
12
|
-
|
|
13
|
-
// src/core/runtime/scope.ts
|
|
14
|
-
var nextScopeId = 1;
|
|
15
|
-
function awaitAll(fibers) {
|
|
16
|
-
return asyncEffect((_env, cb) => {
|
|
17
|
-
let remaining = fibers.length;
|
|
18
|
-
if (remaining === 0) {
|
|
19
|
-
cb({ _tag: "Success", value: void 0 });
|
|
20
|
-
return;
|
|
21
|
-
}
|
|
22
|
-
for (const f of fibers) {
|
|
23
|
-
f.join(() => {
|
|
24
|
-
remaining -= 1;
|
|
25
|
-
if (remaining === 0) cb({ _tag: "Success", value: void 0 });
|
|
26
|
-
});
|
|
27
|
-
}
|
|
28
|
-
});
|
|
29
|
-
}
|
|
30
|
-
var Scope = class _Scope {
|
|
31
|
-
constructor(runtime, parentScopeId) {
|
|
32
|
-
this.runtime = runtime;
|
|
33
|
-
this.parentScopeId = parentScopeId;
|
|
34
|
-
this.id = nextScopeId++;
|
|
35
|
-
const inferredParent = this.parentScopeId ?? getCurrentFiber()?.scopeId;
|
|
36
|
-
if (this.runtime.hasActiveHooks()) {
|
|
37
|
-
this.runtime.emit({
|
|
38
|
-
type: "scope.open",
|
|
39
|
-
scopeId: this.id,
|
|
40
|
-
parentScopeId: inferredParent
|
|
41
|
-
});
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
runtime;
|
|
45
|
-
parentScopeId;
|
|
46
|
-
id;
|
|
47
|
-
closed = false;
|
|
48
|
-
children = /* @__PURE__ */ new Set();
|
|
49
|
-
subScopes = /* @__PURE__ */ new Set();
|
|
50
|
-
finalizers = [];
|
|
51
|
-
/** registra un finalizer (LIFO) */
|
|
52
|
-
addFinalizer(f) {
|
|
53
|
-
if (this.closed) {
|
|
54
|
-
throw new Error("Trying to add finalizer to closed scope");
|
|
55
|
-
}
|
|
56
|
-
this.finalizers.push(f);
|
|
57
|
-
}
|
|
58
|
-
/** crea un sub scope (mismo runtime) */
|
|
59
|
-
subScope() {
|
|
60
|
-
if (this.closed) throw new Error("Scope closed");
|
|
61
|
-
const s = new _Scope(this.runtime, this.id);
|
|
62
|
-
this.subScopes.add(s);
|
|
63
|
-
return s;
|
|
64
|
-
}
|
|
65
|
-
/** ✅ fork en este scope */
|
|
66
|
-
fork(eff) {
|
|
67
|
-
if (this.closed) throw new Error("Scope closed");
|
|
68
|
-
const f = this.runtime.fork(eff, this.id);
|
|
69
|
-
this.children.add(f);
|
|
70
|
-
f.join(() => this.children.delete(f));
|
|
71
|
-
return f;
|
|
72
|
-
}
|
|
73
|
-
/** close fire-and-forget (no bloquea) */
|
|
74
|
-
close(exit = { _tag: "Success", value: void 0 }) {
|
|
75
|
-
this.runtime.fork(this.closeAsync(exit));
|
|
76
|
-
}
|
|
77
|
-
/** Emit the scope.close event if hooks are active. */
|
|
78
|
-
emitCloseEvent(exit) {
|
|
79
|
-
if (this.runtime.hasActiveHooks()) {
|
|
80
|
-
const status = exit._tag === "Success" ? "success" : Cause.isInterruptedOnly(exit.cause) ? "interrupted" : "failure";
|
|
81
|
-
const failure = exit._tag === "Failure" ? Cause.firstFailure(exit.cause) : void 0;
|
|
82
|
-
this.runtime.emit({
|
|
83
|
-
type: "scope.close",
|
|
84
|
-
scopeId: this.id,
|
|
85
|
-
status,
|
|
86
|
-
error: failure?._tag === "Some" ? failure.value : exit._tag === "Failure" ? exit.cause : void 0
|
|
87
|
-
});
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
/**
|
|
91
|
-
* Build an effect that executes finalizers in LIFO order.
|
|
92
|
-
*
|
|
93
|
-
* Optimization over the original: instead of wrapping every finalizer in
|
|
94
|
-
* `asyncFold(fin(exit), () => unit(), () => unit())` which creates 3 effect
|
|
95
|
-
* nodes per finalizer (Fold + 2 Succeed), we use a single Sync thunk per
|
|
96
|
-
* finalizer that catches errors inline. When the finalizer returns a
|
|
97
|
-
* Succeed effect (like `unit()`), the Sync thunk completes without creating
|
|
98
|
-
* additional effect nodes.
|
|
99
|
-
*/
|
|
100
|
-
buildFinalizerEffect(exit) {
|
|
101
|
-
const fins = this.finalizers;
|
|
102
|
-
if (fins.length === 0) return unit();
|
|
103
|
-
let chain = unit();
|
|
104
|
-
for (let i = fins.length - 1; i >= 0; i--) {
|
|
105
|
-
const fin = fins[i];
|
|
106
|
-
chain = asyncFlatMap(chain, () => {
|
|
107
|
-
let result;
|
|
108
|
-
try {
|
|
109
|
-
result = fin(exit);
|
|
110
|
-
} catch {
|
|
111
|
-
return unit();
|
|
112
|
-
}
|
|
113
|
-
if (result._tag === "Succeed") {
|
|
114
|
-
return unit();
|
|
115
|
-
}
|
|
116
|
-
return asyncFold(
|
|
117
|
-
result,
|
|
118
|
-
() => unit(),
|
|
119
|
-
() => unit()
|
|
120
|
-
);
|
|
121
|
-
});
|
|
122
|
-
}
|
|
123
|
-
return chain;
|
|
124
|
-
}
|
|
125
|
-
closeAsync(exit = { _tag: "Success", value: void 0 }, opts = { awaitChildren: true }) {
|
|
126
|
-
return asyncFlatMap(
|
|
127
|
-
unit(),
|
|
128
|
-
() => asyncEffect((env, cb) => {
|
|
129
|
-
if (this.closed) {
|
|
130
|
-
cb({ _tag: "Success", value: void 0 });
|
|
131
|
-
return;
|
|
132
|
-
}
|
|
133
|
-
this.closed = true;
|
|
134
|
-
const children = Array.from(this.children);
|
|
135
|
-
const subScopes = Array.from(this.subScopes);
|
|
136
|
-
for (const child of children) {
|
|
137
|
-
child.interrupt();
|
|
138
|
-
}
|
|
139
|
-
const closeSubs = subScopes.reduceRight(
|
|
140
|
-
(acc, s) => asyncFlatMap(acc, () => s.closeAsync(exit, opts)),
|
|
141
|
-
unit()
|
|
142
|
-
);
|
|
143
|
-
const runFinalizers = this.buildFinalizerEffect(exit);
|
|
144
|
-
const needsAwait = opts.awaitChildren && children.length > 0;
|
|
145
|
-
const awaitChildrenEff = needsAwait ? awaitAll(children) : unit();
|
|
146
|
-
const hasSubScopes = subScopes.length > 0;
|
|
147
|
-
const hasNoFinalizers = this.finalizers.length === 0;
|
|
148
|
-
if (!hasSubScopes && !needsAwait && hasNoFinalizers) {
|
|
149
|
-
this.emitCloseEvent(exit);
|
|
150
|
-
cb({ _tag: "Success", value: void 0 });
|
|
151
|
-
return;
|
|
152
|
-
}
|
|
153
|
-
const all = asyncFlatMap(closeSubs, () => asyncFlatMap(awaitChildrenEff, () => runFinalizers));
|
|
154
|
-
this.runtime.fork(all).join(() => {
|
|
155
|
-
this.emitCloseEvent(exit);
|
|
156
|
-
cb({ _tag: "Success", value: void 0 });
|
|
157
|
-
});
|
|
158
|
-
})
|
|
159
|
-
);
|
|
160
|
-
}
|
|
161
|
-
};
|
|
162
|
-
function withScopeAsync(runtime, f) {
|
|
163
|
-
return asyncEffect((_env, cb) => {
|
|
164
|
-
const scope = new Scope(runtime);
|
|
165
|
-
let done = false;
|
|
166
|
-
const completeAfterClose = (exit) => {
|
|
167
|
-
runtime.fork(scope.closeAsync(exit)).join(() => {
|
|
168
|
-
if (done) return;
|
|
169
|
-
done = true;
|
|
170
|
-
cb(exit);
|
|
171
|
-
});
|
|
172
|
-
};
|
|
173
|
-
const fiber = runtime.fork(f(scope));
|
|
174
|
-
fiber.join(completeAfterClose);
|
|
175
|
-
return () => {
|
|
176
|
-
if (done) return;
|
|
177
|
-
fiber.interrupt();
|
|
178
|
-
runtime.fork(scope.closeAsync(Exit.failCause(Cause.interrupt())));
|
|
179
|
-
};
|
|
180
|
-
});
|
|
181
|
-
}
|
|
182
|
-
function withScope(runtime, f) {
|
|
183
|
-
return withScopeAsync(runtime, (scope) => {
|
|
184
|
-
const out = f(scope);
|
|
185
|
-
if (out && typeof out === "object" && "_tag" in out) return out;
|
|
186
|
-
return unit();
|
|
187
|
-
});
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
export {
|
|
191
|
-
Scope,
|
|
192
|
-
withScopeAsync,
|
|
193
|
-
withScope
|
|
194
|
-
};
|
package/dist/chunk-B33ICAKP.js
DELETED
|
@@ -1,313 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
Scope
|
|
3
|
-
} from "./chunk-L2SYFEBS.js";
|
|
4
|
-
import {
|
|
5
|
-
unsafeGetCurrentRuntime
|
|
6
|
-
} from "./chunk-FH2X7BVP.js";
|
|
7
|
-
import {
|
|
8
|
-
Cause,
|
|
9
|
-
Exit,
|
|
10
|
-
asyncEffect,
|
|
11
|
-
asyncFail,
|
|
12
|
-
asyncFold,
|
|
13
|
-
asyncSucceed,
|
|
14
|
-
unit
|
|
15
|
-
} from "./chunk-UB4B6OFY.js";
|
|
16
|
-
|
|
17
|
-
// src/core/runtime/resource.ts
|
|
18
|
-
function bracket(acquire, use, release) {
|
|
19
|
-
return asyncEffect((env, cb) => {
|
|
20
|
-
const runtime = unsafeGetCurrentRuntime();
|
|
21
|
-
const scope = new Scope(runtime);
|
|
22
|
-
const acquireFiber = scope.fork(acquire);
|
|
23
|
-
acquireFiber.join((acquireExit) => {
|
|
24
|
-
if (acquireExit._tag === "Failure") {
|
|
25
|
-
scope.close(acquireExit);
|
|
26
|
-
cb(acquireExit);
|
|
27
|
-
return;
|
|
28
|
-
}
|
|
29
|
-
const resource2 = acquireExit.value;
|
|
30
|
-
const useFiber = scope.fork(use(resource2));
|
|
31
|
-
useFiber.join((useExit) => {
|
|
32
|
-
const releaseEffect = safeRelease(release, resource2, useExit);
|
|
33
|
-
const releaseFiber = runtime.fork(releaseEffect);
|
|
34
|
-
releaseFiber.join(() => {
|
|
35
|
-
scope.close(useExit);
|
|
36
|
-
cb(useExit);
|
|
37
|
-
});
|
|
38
|
-
});
|
|
39
|
-
});
|
|
40
|
-
return () => {
|
|
41
|
-
scope.close(Exit.failCause(Cause.interrupt()));
|
|
42
|
-
};
|
|
43
|
-
});
|
|
44
|
-
}
|
|
45
|
-
function safeRelease(release, resource2, exit) {
|
|
46
|
-
return asyncFold(
|
|
47
|
-
(() => {
|
|
48
|
-
try {
|
|
49
|
-
return release(resource2, exit);
|
|
50
|
-
} catch {
|
|
51
|
-
return unit();
|
|
52
|
-
}
|
|
53
|
-
})(),
|
|
54
|
-
() => unit(),
|
|
55
|
-
() => unit()
|
|
56
|
-
);
|
|
57
|
-
}
|
|
58
|
-
function ensuring(effect, finalizer) {
|
|
59
|
-
return asyncEffect((env, cb) => {
|
|
60
|
-
const runtime = unsafeGetCurrentRuntime();
|
|
61
|
-
const fiber = runtime.fork(effect);
|
|
62
|
-
fiber.join((exit) => {
|
|
63
|
-
const fin = asyncFold(
|
|
64
|
-
(() => {
|
|
65
|
-
try {
|
|
66
|
-
return finalizer(exit);
|
|
67
|
-
} catch {
|
|
68
|
-
return unit();
|
|
69
|
-
}
|
|
70
|
-
})(),
|
|
71
|
-
() => unit(),
|
|
72
|
-
() => unit()
|
|
73
|
-
);
|
|
74
|
-
runtime.fork(fin).join(() => {
|
|
75
|
-
cb(exit);
|
|
76
|
-
});
|
|
77
|
-
});
|
|
78
|
-
return () => {
|
|
79
|
-
fiber.interrupt();
|
|
80
|
-
};
|
|
81
|
-
});
|
|
82
|
-
}
|
|
83
|
-
function resource(acquire, release) {
|
|
84
|
-
return makeResourceFromUse((body) => bracket(acquire, body, release));
|
|
85
|
-
}
|
|
86
|
-
var makeResource = resource;
|
|
87
|
-
function resourceSucceed(value) {
|
|
88
|
-
return makeResourceFromUse((body) => body(value));
|
|
89
|
-
}
|
|
90
|
-
function resourceFromManaged(m) {
|
|
91
|
-
return makeResourceFromUse((body) => useManaged(m, body));
|
|
92
|
-
}
|
|
93
|
-
function useResource(res, body) {
|
|
94
|
-
return res.use(body);
|
|
95
|
-
}
|
|
96
|
-
function resourceAll(resources) {
|
|
97
|
-
const build = (index) => {
|
|
98
|
-
if (index >= resources.length) return resourceSucceed([]);
|
|
99
|
-
return resources[index].flatMap(
|
|
100
|
-
(head) => build(index + 1).map((tail) => [head, ...tail])
|
|
101
|
-
);
|
|
102
|
-
};
|
|
103
|
-
return build(0).map((values) => values);
|
|
104
|
-
}
|
|
105
|
-
var Resource = Object.freeze({
|
|
106
|
-
make: resource,
|
|
107
|
-
succeed: resourceSucceed,
|
|
108
|
-
fromManaged: resourceFromManaged,
|
|
109
|
-
all: resourceAll,
|
|
110
|
-
use: useResource
|
|
111
|
-
});
|
|
112
|
-
function makeResourceFromUse(use) {
|
|
113
|
-
const self = {
|
|
114
|
-
_tag: "Resource",
|
|
115
|
-
use,
|
|
116
|
-
map: (f) => makeResourceFromUse((body) => self.use((a) => body(f(a)))),
|
|
117
|
-
flatMap: (f) => makeResourceFromUse((body) => self.use((a) => f(a).use(body))),
|
|
118
|
-
zip: (that) => self.flatMap((a) => that.map((b) => [a, b]))
|
|
119
|
-
};
|
|
120
|
-
return self;
|
|
121
|
-
}
|
|
122
|
-
function managed(acquire, release) {
|
|
123
|
-
return {
|
|
124
|
-
_tag: "Managed",
|
|
125
|
-
acquire,
|
|
126
|
-
release: (resource2, exit) => release(resource2, exit)
|
|
127
|
-
};
|
|
128
|
-
}
|
|
129
|
-
function useManaged(m, body) {
|
|
130
|
-
return bracket(m.acquire, body, m.release);
|
|
131
|
-
}
|
|
132
|
-
function managedAll(manageds) {
|
|
133
|
-
const acquire = asyncEffect((env, cb) => {
|
|
134
|
-
const runtime = unsafeGetCurrentRuntime();
|
|
135
|
-
const resources = [];
|
|
136
|
-
let i = 0;
|
|
137
|
-
const acquireNext = () => {
|
|
138
|
-
if (i >= manageds.length) {
|
|
139
|
-
cb({ _tag: "Success", value: resources });
|
|
140
|
-
return;
|
|
141
|
-
}
|
|
142
|
-
const m = manageds[i];
|
|
143
|
-
const fiber = runtime.fork(m.acquire);
|
|
144
|
-
fiber.join((exit) => {
|
|
145
|
-
if (exit._tag === "Failure") {
|
|
146
|
-
releaseAcquired(runtime, manageds, resources, exit).then(() => {
|
|
147
|
-
cb(exit);
|
|
148
|
-
});
|
|
149
|
-
return;
|
|
150
|
-
}
|
|
151
|
-
resources.push(exit.value);
|
|
152
|
-
i++;
|
|
153
|
-
acquireNext();
|
|
154
|
-
});
|
|
155
|
-
};
|
|
156
|
-
acquireNext();
|
|
157
|
-
});
|
|
158
|
-
const release = (resources, exit) => {
|
|
159
|
-
return asyncEffect((_env, cb) => {
|
|
160
|
-
const runtime = unsafeGetCurrentRuntime();
|
|
161
|
-
releaseAcquired(runtime, manageds, resources, exit).then(() => {
|
|
162
|
-
cb({ _tag: "Success", value: void 0 });
|
|
163
|
-
});
|
|
164
|
-
});
|
|
165
|
-
};
|
|
166
|
-
return { _tag: "Managed", acquire, release };
|
|
167
|
-
}
|
|
168
|
-
async function releaseAcquired(runtime, manageds, resources, exit) {
|
|
169
|
-
for (let i = resources.length - 1; i >= 0; i--) {
|
|
170
|
-
try {
|
|
171
|
-
const m = manageds[i];
|
|
172
|
-
await new Promise((resolve) => {
|
|
173
|
-
const releaseEff = asyncFold(
|
|
174
|
-
m.release(resources[i], exit),
|
|
175
|
-
() => unit(),
|
|
176
|
-
() => unit()
|
|
177
|
-
);
|
|
178
|
-
runtime.fork(releaseEff).join(() => resolve());
|
|
179
|
-
});
|
|
180
|
-
} catch {
|
|
181
|
-
}
|
|
182
|
-
}
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
// src/core/runtime/circuitBreaker.ts
|
|
186
|
-
function makeCircuitBreaker(config = {}) {
|
|
187
|
-
const failureThreshold = config.failureThreshold ?? 5;
|
|
188
|
-
const resetTimeoutMs = config.resetTimeoutMs ?? 3e4;
|
|
189
|
-
const successThreshold = config.successThreshold ?? 1;
|
|
190
|
-
const isFailure = config.isFailure ?? (() => true);
|
|
191
|
-
const onStateChange = config.onStateChange;
|
|
192
|
-
let currentState = "closed";
|
|
193
|
-
let consecutiveFailures = 0;
|
|
194
|
-
let consecutiveSuccesses = 0;
|
|
195
|
-
let openedAt = 0;
|
|
196
|
-
let totalRequests = 0;
|
|
197
|
-
let totalFailures = 0;
|
|
198
|
-
let totalSuccesses = 0;
|
|
199
|
-
let totalRejected = 0;
|
|
200
|
-
let lastFailureTime = null;
|
|
201
|
-
let lastSuccessTime = null;
|
|
202
|
-
const transition = (to) => {
|
|
203
|
-
if (currentState === to) return;
|
|
204
|
-
const from = currentState;
|
|
205
|
-
currentState = to;
|
|
206
|
-
onStateChange?.(from, to);
|
|
207
|
-
};
|
|
208
|
-
const onSuccess = () => {
|
|
209
|
-
totalSuccesses++;
|
|
210
|
-
lastSuccessTime = Date.now();
|
|
211
|
-
consecutiveFailures = 0;
|
|
212
|
-
if (currentState === "half-open") {
|
|
213
|
-
consecutiveSuccesses++;
|
|
214
|
-
if (consecutiveSuccesses >= successThreshold) {
|
|
215
|
-
consecutiveSuccesses = 0;
|
|
216
|
-
transition("closed");
|
|
217
|
-
}
|
|
218
|
-
}
|
|
219
|
-
};
|
|
220
|
-
const onFailure = (error) => {
|
|
221
|
-
if (!isFailure(error)) {
|
|
222
|
-
onSuccess();
|
|
223
|
-
return;
|
|
224
|
-
}
|
|
225
|
-
totalFailures++;
|
|
226
|
-
lastFailureTime = Date.now();
|
|
227
|
-
consecutiveSuccesses = 0;
|
|
228
|
-
consecutiveFailures++;
|
|
229
|
-
if (currentState === "half-open") {
|
|
230
|
-
openedAt = Date.now();
|
|
231
|
-
transition("open");
|
|
232
|
-
} else if (currentState === "closed" && consecutiveFailures >= failureThreshold) {
|
|
233
|
-
openedAt = Date.now();
|
|
234
|
-
transition("open");
|
|
235
|
-
}
|
|
236
|
-
};
|
|
237
|
-
const shouldAllow = () => {
|
|
238
|
-
switch (currentState) {
|
|
239
|
-
case "closed":
|
|
240
|
-
return true;
|
|
241
|
-
case "open": {
|
|
242
|
-
const elapsed = Date.now() - openedAt;
|
|
243
|
-
if (elapsed >= resetTimeoutMs) {
|
|
244
|
-
transition("half-open");
|
|
245
|
-
return true;
|
|
246
|
-
}
|
|
247
|
-
return false;
|
|
248
|
-
}
|
|
249
|
-
case "half-open":
|
|
250
|
-
return true;
|
|
251
|
-
}
|
|
252
|
-
};
|
|
253
|
-
const protect = (effect) => {
|
|
254
|
-
totalRequests++;
|
|
255
|
-
if (!shouldAllow()) {
|
|
256
|
-
totalRejected++;
|
|
257
|
-
return asyncFail({
|
|
258
|
-
_tag: "CircuitBreakerOpen",
|
|
259
|
-
openSince: openedAt,
|
|
260
|
-
failures: consecutiveFailures
|
|
261
|
-
});
|
|
262
|
-
}
|
|
263
|
-
return asyncFold(
|
|
264
|
-
effect,
|
|
265
|
-
(error) => {
|
|
266
|
-
onFailure(error);
|
|
267
|
-
return asyncFail(error);
|
|
268
|
-
},
|
|
269
|
-
(value) => {
|
|
270
|
-
onSuccess();
|
|
271
|
-
return asyncSucceed(value);
|
|
272
|
-
}
|
|
273
|
-
);
|
|
274
|
-
};
|
|
275
|
-
const stats = () => ({
|
|
276
|
-
state: currentState,
|
|
277
|
-
failures: consecutiveFailures,
|
|
278
|
-
successes: consecutiveSuccesses,
|
|
279
|
-
totalRequests,
|
|
280
|
-
totalFailures,
|
|
281
|
-
totalSuccesses,
|
|
282
|
-
totalRejected,
|
|
283
|
-
lastFailureTime,
|
|
284
|
-
lastSuccessTime
|
|
285
|
-
});
|
|
286
|
-
const reset = () => {
|
|
287
|
-
consecutiveFailures = 0;
|
|
288
|
-
consecutiveSuccesses = 0;
|
|
289
|
-
transition("closed");
|
|
290
|
-
};
|
|
291
|
-
return {
|
|
292
|
-
state: () => currentState,
|
|
293
|
-
protect,
|
|
294
|
-
stats,
|
|
295
|
-
reset
|
|
296
|
-
};
|
|
297
|
-
}
|
|
298
|
-
|
|
299
|
-
export {
|
|
300
|
-
bracket,
|
|
301
|
-
ensuring,
|
|
302
|
-
resource,
|
|
303
|
-
makeResource,
|
|
304
|
-
resourceSucceed,
|
|
305
|
-
resourceFromManaged,
|
|
306
|
-
useResource,
|
|
307
|
-
resourceAll,
|
|
308
|
-
Resource,
|
|
309
|
-
managed,
|
|
310
|
-
useManaged,
|
|
311
|
-
managedAll,
|
|
312
|
-
makeCircuitBreaker
|
|
313
|
-
};
|
package/dist/chunk-JF5WGYJJ.cjs
DELETED
|
@@ -1,194 +0,0 @@
|
|
|
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; } var _class;
|
|
2
|
-
|
|
3
|
-
var _chunkGLE2WY7Zcjs = require('./chunk-GLE2WY7Z.cjs');
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
var _chunkMVGUEJ5Zcjs = require('./chunk-MVGUEJ5Z.cjs');
|
|
12
|
-
|
|
13
|
-
// src/core/runtime/scope.ts
|
|
14
|
-
var nextScopeId = 1;
|
|
15
|
-
function awaitAll(fibers) {
|
|
16
|
-
return _chunkMVGUEJ5Zcjs.asyncEffect.call(void 0, (_env, cb) => {
|
|
17
|
-
let remaining = fibers.length;
|
|
18
|
-
if (remaining === 0) {
|
|
19
|
-
cb({ _tag: "Success", value: void 0 });
|
|
20
|
-
return;
|
|
21
|
-
}
|
|
22
|
-
for (const f of fibers) {
|
|
23
|
-
f.join(() => {
|
|
24
|
-
remaining -= 1;
|
|
25
|
-
if (remaining === 0) cb({ _tag: "Success", value: void 0 });
|
|
26
|
-
});
|
|
27
|
-
}
|
|
28
|
-
});
|
|
29
|
-
}
|
|
30
|
-
var Scope = (_class = class _Scope {
|
|
31
|
-
constructor(runtime, parentScopeId) {;_class.prototype.__init.call(this);_class.prototype.__init2.call(this);_class.prototype.__init3.call(this);_class.prototype.__init4.call(this);
|
|
32
|
-
this.runtime = runtime;
|
|
33
|
-
this.parentScopeId = parentScopeId;
|
|
34
|
-
this.id = nextScopeId++;
|
|
35
|
-
const inferredParent = _nullishCoalesce(this.parentScopeId, () => ( _optionalChain([_chunkGLE2WY7Zcjs.getCurrentFiber.call(void 0, ), 'optionalAccess', _ => _.scopeId])));
|
|
36
|
-
if (this.runtime.hasActiveHooks()) {
|
|
37
|
-
this.runtime.emit({
|
|
38
|
-
type: "scope.open",
|
|
39
|
-
scopeId: this.id,
|
|
40
|
-
parentScopeId: inferredParent
|
|
41
|
-
});
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
__init() {this.closed = false}
|
|
48
|
-
__init2() {this.children = /* @__PURE__ */ new Set()}
|
|
49
|
-
__init3() {this.subScopes = /* @__PURE__ */ new Set()}
|
|
50
|
-
__init4() {this.finalizers = []}
|
|
51
|
-
/** registra un finalizer (LIFO) */
|
|
52
|
-
addFinalizer(f) {
|
|
53
|
-
if (this.closed) {
|
|
54
|
-
throw new Error("Trying to add finalizer to closed scope");
|
|
55
|
-
}
|
|
56
|
-
this.finalizers.push(f);
|
|
57
|
-
}
|
|
58
|
-
/** crea un sub scope (mismo runtime) */
|
|
59
|
-
subScope() {
|
|
60
|
-
if (this.closed) throw new Error("Scope closed");
|
|
61
|
-
const s = new _Scope(this.runtime, this.id);
|
|
62
|
-
this.subScopes.add(s);
|
|
63
|
-
return s;
|
|
64
|
-
}
|
|
65
|
-
/** ✅ fork en este scope */
|
|
66
|
-
fork(eff) {
|
|
67
|
-
if (this.closed) throw new Error("Scope closed");
|
|
68
|
-
const f = this.runtime.fork(eff, this.id);
|
|
69
|
-
this.children.add(f);
|
|
70
|
-
f.join(() => this.children.delete(f));
|
|
71
|
-
return f;
|
|
72
|
-
}
|
|
73
|
-
/** close fire-and-forget (no bloquea) */
|
|
74
|
-
close(exit = { _tag: "Success", value: void 0 }) {
|
|
75
|
-
this.runtime.fork(this.closeAsync(exit));
|
|
76
|
-
}
|
|
77
|
-
/** Emit the scope.close event if hooks are active. */
|
|
78
|
-
emitCloseEvent(exit) {
|
|
79
|
-
if (this.runtime.hasActiveHooks()) {
|
|
80
|
-
const status = exit._tag === "Success" ? "success" : _chunkMVGUEJ5Zcjs.Cause.isInterruptedOnly(exit.cause) ? "interrupted" : "failure";
|
|
81
|
-
const failure = exit._tag === "Failure" ? _chunkMVGUEJ5Zcjs.Cause.firstFailure(exit.cause) : void 0;
|
|
82
|
-
this.runtime.emit({
|
|
83
|
-
type: "scope.close",
|
|
84
|
-
scopeId: this.id,
|
|
85
|
-
status,
|
|
86
|
-
error: _optionalChain([failure, 'optionalAccess', _2 => _2._tag]) === "Some" ? failure.value : exit._tag === "Failure" ? exit.cause : void 0
|
|
87
|
-
});
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
/**
|
|
91
|
-
* Build an effect that executes finalizers in LIFO order.
|
|
92
|
-
*
|
|
93
|
-
* Optimization over the original: instead of wrapping every finalizer in
|
|
94
|
-
* `asyncFold(fin(exit), () => unit(), () => unit())` which creates 3 effect
|
|
95
|
-
* nodes per finalizer (Fold + 2 Succeed), we use a single Sync thunk per
|
|
96
|
-
* finalizer that catches errors inline. When the finalizer returns a
|
|
97
|
-
* Succeed effect (like `unit()`), the Sync thunk completes without creating
|
|
98
|
-
* additional effect nodes.
|
|
99
|
-
*/
|
|
100
|
-
buildFinalizerEffect(exit) {
|
|
101
|
-
const fins = this.finalizers;
|
|
102
|
-
if (fins.length === 0) return _chunkMVGUEJ5Zcjs.unit.call(void 0, );
|
|
103
|
-
let chain = _chunkMVGUEJ5Zcjs.unit.call(void 0, );
|
|
104
|
-
for (let i = fins.length - 1; i >= 0; i--) {
|
|
105
|
-
const fin = fins[i];
|
|
106
|
-
chain = _chunkMVGUEJ5Zcjs.asyncFlatMap.call(void 0, chain, () => {
|
|
107
|
-
let result;
|
|
108
|
-
try {
|
|
109
|
-
result = fin(exit);
|
|
110
|
-
} catch (e) {
|
|
111
|
-
return _chunkMVGUEJ5Zcjs.unit.call(void 0, );
|
|
112
|
-
}
|
|
113
|
-
if (result._tag === "Succeed") {
|
|
114
|
-
return _chunkMVGUEJ5Zcjs.unit.call(void 0, );
|
|
115
|
-
}
|
|
116
|
-
return _chunkMVGUEJ5Zcjs.asyncFold.call(void 0,
|
|
117
|
-
result,
|
|
118
|
-
() => _chunkMVGUEJ5Zcjs.unit.call(void 0, ),
|
|
119
|
-
() => _chunkMVGUEJ5Zcjs.unit.call(void 0, )
|
|
120
|
-
);
|
|
121
|
-
});
|
|
122
|
-
}
|
|
123
|
-
return chain;
|
|
124
|
-
}
|
|
125
|
-
closeAsync(exit = { _tag: "Success", value: void 0 }, opts = { awaitChildren: true }) {
|
|
126
|
-
return _chunkMVGUEJ5Zcjs.asyncFlatMap.call(void 0,
|
|
127
|
-
_chunkMVGUEJ5Zcjs.unit.call(void 0, ),
|
|
128
|
-
() => _chunkMVGUEJ5Zcjs.asyncEffect.call(void 0, (env, cb) => {
|
|
129
|
-
if (this.closed) {
|
|
130
|
-
cb({ _tag: "Success", value: void 0 });
|
|
131
|
-
return;
|
|
132
|
-
}
|
|
133
|
-
this.closed = true;
|
|
134
|
-
const children = Array.from(this.children);
|
|
135
|
-
const subScopes = Array.from(this.subScopes);
|
|
136
|
-
for (const child of children) {
|
|
137
|
-
child.interrupt();
|
|
138
|
-
}
|
|
139
|
-
const closeSubs = subScopes.reduceRight(
|
|
140
|
-
(acc, s) => _chunkMVGUEJ5Zcjs.asyncFlatMap.call(void 0, acc, () => s.closeAsync(exit, opts)),
|
|
141
|
-
_chunkMVGUEJ5Zcjs.unit.call(void 0, )
|
|
142
|
-
);
|
|
143
|
-
const runFinalizers = this.buildFinalizerEffect(exit);
|
|
144
|
-
const needsAwait = opts.awaitChildren && children.length > 0;
|
|
145
|
-
const awaitChildrenEff = needsAwait ? awaitAll(children) : _chunkMVGUEJ5Zcjs.unit.call(void 0, );
|
|
146
|
-
const hasSubScopes = subScopes.length > 0;
|
|
147
|
-
const hasNoFinalizers = this.finalizers.length === 0;
|
|
148
|
-
if (!hasSubScopes && !needsAwait && hasNoFinalizers) {
|
|
149
|
-
this.emitCloseEvent(exit);
|
|
150
|
-
cb({ _tag: "Success", value: void 0 });
|
|
151
|
-
return;
|
|
152
|
-
}
|
|
153
|
-
const all = _chunkMVGUEJ5Zcjs.asyncFlatMap.call(void 0, closeSubs, () => _chunkMVGUEJ5Zcjs.asyncFlatMap.call(void 0, awaitChildrenEff, () => runFinalizers));
|
|
154
|
-
this.runtime.fork(all).join(() => {
|
|
155
|
-
this.emitCloseEvent(exit);
|
|
156
|
-
cb({ _tag: "Success", value: void 0 });
|
|
157
|
-
});
|
|
158
|
-
})
|
|
159
|
-
);
|
|
160
|
-
}
|
|
161
|
-
}, _class);
|
|
162
|
-
function withScopeAsync(runtime, f) {
|
|
163
|
-
return _chunkMVGUEJ5Zcjs.asyncEffect.call(void 0, (_env, cb) => {
|
|
164
|
-
const scope = new Scope(runtime);
|
|
165
|
-
let done = false;
|
|
166
|
-
const completeAfterClose = (exit) => {
|
|
167
|
-
runtime.fork(scope.closeAsync(exit)).join(() => {
|
|
168
|
-
if (done) return;
|
|
169
|
-
done = true;
|
|
170
|
-
cb(exit);
|
|
171
|
-
});
|
|
172
|
-
};
|
|
173
|
-
const fiber = runtime.fork(f(scope));
|
|
174
|
-
fiber.join(completeAfterClose);
|
|
175
|
-
return () => {
|
|
176
|
-
if (done) return;
|
|
177
|
-
fiber.interrupt();
|
|
178
|
-
runtime.fork(scope.closeAsync(_chunkMVGUEJ5Zcjs.Exit.failCause(_chunkMVGUEJ5Zcjs.Cause.interrupt())));
|
|
179
|
-
};
|
|
180
|
-
});
|
|
181
|
-
}
|
|
182
|
-
function withScope(runtime, f) {
|
|
183
|
-
return withScopeAsync(runtime, (scope) => {
|
|
184
|
-
const out = f(scope);
|
|
185
|
-
if (out && typeof out === "object" && "_tag" in out) return out;
|
|
186
|
-
return _chunkMVGUEJ5Zcjs.unit.call(void 0, );
|
|
187
|
-
});
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
exports.Scope = Scope; exports.withScopeAsync = withScopeAsync; exports.withScope = withScope;
|