@nicolastoulemont/std 0.8.1 → 0.9.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 +63 -11
- package/dist/adt/index.d.mts +1 -1
- package/dist/adt/index.mjs +1 -1
- package/dist/adt-CY8wLJJI.mjs +2 -0
- package/dist/adt-CY8wLJJI.mjs.map +1 -0
- package/dist/data/index.d.mts +1 -1
- package/dist/data/index.mjs +1 -1
- package/dist/data-DqACNS_g.mjs +2 -0
- package/dist/data-DqACNS_g.mjs.map +1 -0
- package/dist/duration/index.d.mts +1 -1
- package/dist/duration/index.mjs +1 -1
- package/dist/{duration-CYoDHcOR.mjs → duration-Bas3mi1N.mjs} +2 -2
- package/dist/{duration-CYoDHcOR.mjs.map → duration-Bas3mi1N.mjs.map} +1 -1
- package/dist/fx/index.d.mts +1 -1
- package/dist/fx/index.mjs +1 -1
- package/dist/{fx-DUXDxwsU.mjs → fx-C_RTDEpv.mjs} +2 -2
- package/dist/{fx-DUXDxwsU.mjs.map → fx-C_RTDEpv.mjs.map} +1 -1
- package/dist/{index-MsJqfQu0.d.mts → index-BD-els5J.d.mts} +2 -2
- package/dist/{index-MsJqfQu0.d.mts.map → index-BD-els5J.d.mts.map} +1 -1
- package/dist/{index-DUki2Bcp.d.mts → index-BaRJVkLo.d.mts} +2 -2
- package/dist/{index-DUki2Bcp.d.mts.map → index-BaRJVkLo.d.mts.map} +1 -1
- package/dist/{index-B4WfexUL.d.mts → index-BipW0MC3.d.mts} +32 -25
- package/dist/index-BipW0MC3.d.mts.map +1 -0
- package/dist/index-BqJ1GWAF.d.mts.map +1 -1
- package/dist/{index-Ctqe1fD1.d.mts → index-CVmgBpDt.d.mts} +2 -2
- package/dist/{index-Ctqe1fD1.d.mts.map → index-CVmgBpDt.d.mts.map} +1 -1
- package/dist/{index-UINIHFuh.d.mts → index-D6pjHqlK.d.mts} +48 -2
- package/dist/index-D6pjHqlK.d.mts.map +1 -0
- package/dist/{index-crtzMG48.d.mts → index-D8gcYvR9.d.mts} +38 -3
- package/dist/index-D8gcYvR9.d.mts.map +1 -0
- package/dist/index-D8rDE60Y.d.mts.map +1 -1
- package/dist/{index-BsPOcZk9.d.mts → index-DfAqfnY0.d.mts} +2 -2
- package/dist/{index-BsPOcZk9.d.mts.map → index-DfAqfnY0.d.mts.map} +1 -1
- package/dist/index.d.mts +8 -8
- package/dist/index.mjs +1 -1
- package/dist/{equality-BX6BUidG.mjs → is-plain-object-BoFjRafL.mjs} +2 -2
- package/dist/is-plain-object-BoFjRafL.mjs.map +1 -0
- package/dist/layer/index.mjs +1 -1
- package/dist/{layer-CKtH7TRL.mjs → layer-C5A-EM0h.mjs} +2 -2
- package/dist/{layer-CKtH7TRL.mjs.map → layer-C5A-EM0h.mjs.map} +1 -1
- package/dist/provide/index.d.mts +1 -1
- package/dist/provide/index.mjs +1 -1
- package/dist/provide-CuccogWx.mjs +2 -0
- package/dist/provide-CuccogWx.mjs.map +1 -0
- package/dist/queue/index.d.mts +1 -1
- package/dist/queue/index.mjs +1 -1
- package/dist/{queue-apiEOlRD.mjs → queue-GYVrD39q.mjs} +2 -2
- package/dist/{queue-apiEOlRD.mjs.map → queue-GYVrD39q.mjs.map} +1 -1
- package/dist/schedule/index.d.mts +1 -1
- package/dist/schedule/index.mjs +1 -1
- package/dist/{schedule-C6iN3oMt.mjs → schedule-B7qV60tO.mjs} +2 -2
- package/dist/{schedule-C6iN3oMt.mjs.map → schedule-B7qV60tO.mjs.map} +1 -1
- package/dist/{schedule-B9K_2Z21.d.mts → schedule-BzPjvMXc.d.mts} +3 -3
- package/dist/{schedule-B9K_2Z21.d.mts.map → schedule-BzPjvMXc.d.mts.map} +1 -1
- package/dist/schema/index.d.mts +1 -1
- package/dist/schema/index.mjs +1 -1
- package/dist/schema-DstB1_VK.mjs +2 -0
- package/dist/schema-DstB1_VK.mjs.map +1 -0
- package/dist/{schema.types-CBEXCwfs.d.mts → schema.types-w1WK4kGS.d.mts} +7 -5
- package/dist/schema.types-w1WK4kGS.d.mts.map +1 -0
- package/package.json +1 -1
- package/dist/adt-CPG_sa8q.mjs +0 -2
- package/dist/adt-CPG_sa8q.mjs.map +0 -1
- package/dist/data-BHYPdqWZ.mjs +0 -2
- package/dist/data-BHYPdqWZ.mjs.map +0 -1
- package/dist/equality-BX6BUidG.mjs.map +0 -1
- package/dist/index-B4WfexUL.d.mts.map +0 -1
- package/dist/index-UINIHFuh.d.mts.map +0 -1
- package/dist/index-crtzMG48.d.mts.map +0 -1
- package/dist/provide--yZE8x-n.mjs +0 -2
- package/dist/provide--yZE8x-n.mjs.map +0 -1
- package/dist/schema-CJ-aaQe8.mjs +0 -2
- package/dist/schema-CJ-aaQe8.mjs.map +0 -1
- package/dist/schema.types-CBEXCwfs.d.mts.map +0 -1
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { f as RunnableFx, m as SyncFx, t as AsyncFx } from "./fx.types-BdN1EWxr.mjs";
|
|
2
2
|
import { t as ServiceClass } from "./service-D8mr0wwg.mjs";
|
|
3
3
|
import { t as Context } from "./context-B2dWloPl.mjs";
|
|
4
|
-
import { n as Layer } from "./layer.types-BB0MrvLg.mjs";
|
|
4
|
+
import { a as UnprovidedDeps, i as MergeROut, n as Layer, r as MergeError, t as AllSync } from "./layer.types-BB0MrvLg.mjs";
|
|
5
5
|
|
|
6
6
|
//#region src/provide/provide.d.ts
|
|
7
7
|
declare namespace provide_d_exports {
|
|
8
|
-
export { context, layer, service };
|
|
8
|
+
export { context, layer, layers, service };
|
|
9
9
|
}
|
|
10
10
|
/**
|
|
11
11
|
* Extract the value type from an Fx.
|
|
@@ -24,6 +24,8 @@ type FxErrorType<F> = F extends RunnableFx<unknown, infer E, unknown> ? E : neve
|
|
|
24
24
|
* - Unknown sync layer + any fx → RunnableFx (fallback)
|
|
25
25
|
*/
|
|
26
26
|
type ProvideResult<E2, LayerSync extends boolean, Fx extends RunnableFx<unknown, unknown, unknown>> = LayerSync extends true ? Fx["_tag"] extends "SyncFx" ? SyncFx<FxValueType<Fx>, FxErrorType<Fx> | E2> : AsyncFx<FxValueType<Fx>, FxErrorType<Fx> | E2> : LayerSync extends false ? AsyncFx<FxValueType<Fx>, FxErrorType<Fx> | E2> : RunnableFx<FxValueType<Fx>, FxErrorType<Fx> | E2>;
|
|
27
|
+
type LayerList = [Layer<unknown, unknown, unknown>, ...Layer<unknown, unknown, unknown>[]];
|
|
28
|
+
type CompleteLayers<L extends LayerList> = UnprovidedDeps<L> extends never ? L : never;
|
|
27
29
|
/**
|
|
28
30
|
* Provide a layer to an Fx computation, resolving all service requirements.
|
|
29
31
|
* Creates a new scope for resource management.
|
|
@@ -52,6 +54,39 @@ type ProvideResult<E2, LayerSync extends boolean, Fx extends RunnableFx<unknown,
|
|
|
52
54
|
* ```
|
|
53
55
|
*/
|
|
54
56
|
declare function layer<ROut, E2, LayerSync extends boolean>(layer: Layer<ROut, E2, never, LayerSync>): <Fx extends RunnableFx<unknown, unknown, ROut>>(fx: Fx) => ProvideResult<E2, LayerSync, Fx>;
|
|
57
|
+
/**
|
|
58
|
+
* Provide multiple layers to an Fx computation.
|
|
59
|
+
* Equivalent to `Provide.layer(Layer.merge(...layers))`, but keeps the call site flatter.
|
|
60
|
+
*
|
|
61
|
+
* @param layers - Layers whose combined external requirements are fully satisfied
|
|
62
|
+
* @returns A function that takes an Fx and returns an Fx with dependencies resolved
|
|
63
|
+
*
|
|
64
|
+
* @example
|
|
65
|
+
* ```ts
|
|
66
|
+
* import { Fx, Layer, Provide, Service, pipe } from "@nicolastoulemont/std"
|
|
67
|
+
*
|
|
68
|
+
* const Document = Service.tag<{ readonly getById: (id: string) => string }>("Document")
|
|
69
|
+
* const Team = Service.tag<{ readonly canRead: (id: string) => boolean }>("Team")
|
|
70
|
+
*
|
|
71
|
+
* const program = Fx.gen(function* () {
|
|
72
|
+
* const document = yield* Document
|
|
73
|
+
* const team = yield* Team
|
|
74
|
+
* return team.canRead("doc-1") ? document.getById("doc-1") : "forbidden"
|
|
75
|
+
* })
|
|
76
|
+
*
|
|
77
|
+
* const exit = Fx.run(
|
|
78
|
+
* pipe(
|
|
79
|
+
* program,
|
|
80
|
+
* Provide.layers(
|
|
81
|
+
* Layer.ok(Document, { getById: (id) => id }),
|
|
82
|
+
* Layer.ok(Team, { canRead: () => true }),
|
|
83
|
+
* ),
|
|
84
|
+
* ),
|
|
85
|
+
* )
|
|
86
|
+
* // => { _tag: "Ok", value: "doc-1" }
|
|
87
|
+
* ```
|
|
88
|
+
*/
|
|
89
|
+
declare function layers<L extends LayerList>(...layers: CompleteLayers<L>): <Fx extends RunnableFx<unknown, unknown, MergeROut<L>>>(fx: Fx) => ProvideResult<MergeError<L>, AllSync<L>, Fx>;
|
|
55
90
|
/**
|
|
56
91
|
* Provide a context directly to an Fx computation.
|
|
57
92
|
*
|
|
@@ -96,4 +131,4 @@ declare const context: <R>(ctx: Context<R>) => <A, E>(fx: RunnableFx<A, E, R>) =
|
|
|
96
131
|
declare const service: <S>(service: ServiceClass<S>, impl: S) => <A, E, R>(fx: RunnableFx<A, E, R | S>) => RunnableFx<A, E, Exclude<R, S>>;
|
|
97
132
|
//#endregion
|
|
98
133
|
export { provide_d_exports as t };
|
|
99
|
-
//# sourceMappingURL=index-
|
|
134
|
+
//# sourceMappingURL=index-D8gcYvR9.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index-D8gcYvR9.d.mts","names":[],"sources":["../src/provide/provide.ts"],"sourcesContent":[],"mappings":";;;;;;;;;;;;KAqBK,iBAAiB,UAAU;;;;KAK3B,iBAAiB,UAAU;;AAlBsB;AAaZ;AAKA;;;;;KAUrC,aAMQ,CAAA,EAAA,EAAA,kBAAA,OAAA,EAAA,WAHA,UAGA,CAAA,OAAA,EAAA,OAAA,EAAA,OAAA,CAAA,CAAA,GAFT,SAES,SAAA,IAAA,GADT,EACS,CAAA,MAAA,CAAA,SAAA,QAAA,GAAP,MAAO,CAAA,WAAA,CAAY,EAAZ,CAAA,EAAiB,WAAjB,CAA6B,EAA7B,CAAA,GAAmC,EAAnC,CAAA,GACP,OADO,CACC,WADD,CACa,EADb,CAAA,EACkB,WADlB,CAC8B,EAD9B,CAAA,GACoC,EADpC,CAAA,GAET,SAFS,SAAA,KAAA,GAGP,OAHO,CAGC,WAHD,CAGa,EAHb,CAAA,EAGkB,WAHlB,CAG8B,EAH9B,CAAA,GAGoC,EAHpC,CAAA,GAIP,UAJO,CAII,WAJJ,CAIgB,EAJhB,CAAA,EAIqB,WAJrB,CAIiC,EAJjC,CAAA,GAIuC,EAJvC,CAAA;KAMR,SAAA,GANqC,CAMxB,KANwB,CAAA,OAAA,EAAA,OAAA,EAAA,OAAA,CAAA,EAAA,GAMiB,KANjB,CAAA,OAAA,EAAA,OAAA,EAAA,OAAA,CAAA,EAAA,CAAA;KAOrC,cAPyB,CAAA,UAOA,SAPA,CAAA,GAOa,cAPb,CAO4B,CAP5B,CAAA,SAAA,KAAA,GAO+C,CAP/C,GAAA,KAAA;;;;;;;;;;;;;;;;;;;;;;;AAId;AAEoD;;;;AACS,iBA6B7D,KA7B6D,CAAA,IAAA,EAAA,EAAA,EAAA,kBAAA,OAAA,CAAA,CAAA,KAAA,EA8BpE,KA9BoE,CA8B1D,IA9B0D,EA8BpD,EA9BoD,EAAA,KAAA,EA8BzC,SA9ByC,CAAA,CAAA,EAAA,CAAA,WA+B9D,UA/B8D,CAAA,OAAA,EAAA,OAAA,EA+BjC,IA/BiC,CAAA,CAAA,CAAA,EAAA,EA+BtB,EA/BsB,EAAA,GA+Bf,aA/Be,CA+BD,EA/BC,EA+BG,SA/BH,EA+Bc,EA/Bd,CAAA;;AA6B7E;;;;;;;;;;;;;AAwMA;;;;;;;;;;;;;;;AA+BA;;;AAEwB,iBAjCR,MAiCQ,CAAA,UAjCS,SAiCT,CAAA,CAAA,GAAA,MAAA,EAhCX,cAgCW,CAhCI,CAgCJ,CAAA,CAAA,EAAA,CAAA,WA/BT,UA+BS,CAAA,OAAA,EAAA,OAAA,EA/BoB,SA+BpB,CA/B8B,CA+B9B,CAAA,CAAA,CAAA,CAAA,EAAA,EA/BuC,EA+BvC,EAAA,GA/B8C,aA+B9C,CA/B4D,UA+B5D,CA/BuE,CA+BvE,CAAA,EA/B2E,OA+B3E,CA/BmF,CA+BnF,CAAA,EA/BuF,EA+BvF,CAAA;;;;;;;;AA4FxB;;;;;;;;;;;;;AAE2D,cAhG9C,OAgG8C,EAAA,CAAA,CAAA,CAAA,CAAA,GAAA,EA/FhD,OA+FgD,CA/FxC,CA+FwC,CAAA,EAAA,GAAA,CAAA,CAAA,EAAA,CAAA,CAAA,CAAA,EAAA,EA9F9C,UA8F8C,CA9FnC,CA8FmC,EA9FhC,CA8FgC,EA9F7B,CA8F6B,CAAA,EAAA,GA9FxB,UA8FwB,CA9Fb,CA8Fa,EA9FV,CA8FU,CAAA;;;;;;;;;;;;;;;;;;;;;cAF9C,sBACE,aAAa,UAAU,oBACtB,WAAW,GAAG,GAAG,IAAI,OAAK,WAAW,GAAG,GAAG,QAAQ,GAAG"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index-D8rDE60Y.d.mts","names":[],"sources":["../src/order/order.types.ts","../src/order/order.ts"],"sourcesContent":[],"mappings":";;;;AAOA;AAOA;;;AAAgD,KAPpC,UAAA,GAOoC,CAAA,CAAA,GAAA,CAAA,GAAA,CAAA;;AAKhD;;;;KALY,uBAAqB,SAAS,MAAM;;;;KAKpC;oBACQ;oBACA;;;;;;;AAdpB;AAOA;;;;;AAKA;;KCsBY,WAAW,QAAU;;;;;;;;;;;KAYrB,QAAA,GAAW;;;;;;;;;;;;;;;;;;;;AAZX,iBAiCI,
|
|
1
|
+
{"version":3,"file":"index-D8rDE60Y.d.mts","names":[],"sources":["../src/order/order.types.ts","../src/order/order.ts"],"sourcesContent":[],"mappings":"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"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { n as Branded } from "./brand.types-B3NDX1vo.mjs";
|
|
2
|
-
import { n as TaggedErrorFactory } from "./index-
|
|
2
|
+
import { n as TaggedErrorFactory } from "./index-D6pjHqlK.mjs";
|
|
3
3
|
import { t as Result } from "./index-CIvNgjsx.mjs";
|
|
4
4
|
|
|
5
5
|
//#region src/duration/duration.d.ts
|
|
@@ -93,4 +93,4 @@ declare const parse: (input: string) => Result<Duration, DurationParseError>;
|
|
|
93
93
|
declare const from: (input: Input) => Result<Duration, InputError>;
|
|
94
94
|
//#endregion
|
|
95
95
|
export { InputError as n, duration_d_exports as r, Input as t };
|
|
96
|
-
//# sourceMappingURL=index-
|
|
96
|
+
//# sourceMappingURL=index-DfAqfnY0.d.mts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index-
|
|
1
|
+
{"version":3,"file":"index-DfAqfnY0.d.mts","names":[],"sources":["../src/duration/duration.ts"],"sourcesContent":[],"mappings":";;;;;;;;;;;KA4BY,QAAA,GAAW;;;;KAKX,IAAA;;;;KAiBA,WAAA,gBAA2B;;;;KAK3B,KAAA,GAAQ,oBAAoB;cAAW,yBAAA;;;;cAKtC,kBAAA,SAA2B;;;AAhCxC,CAAA,CAAA,CAAA;AAsBA,cAaK,8BAbsC,EAatC,kBAbsC,CAAA,2BAAA,CAAA;AAK3C;AAAmD;AAKnD;AAGK,cAKQ,yBAAA,SAAkC,8BAL1C,CAAA;EAKQ,KAAA,EAAA,MAAA;EAGR,OAAA,EAAA,MAAA;AAKL,CAAA,CAAA,CAAA;cALK,8BAQK,EARL,kBAQK,CAAA,2BAAA,CAAA;;;;AAME,cATC,yBAAA,SAAkC,8BASJ,CAAA;EAK/B,KAAA,EAbH,KAaG;EAAa,OAAA,EAAA,MAAA;EAA4B,KAAA,CAAA,EAX3C,kBAW2C,GAXtB,yBAWsB;CAAqB,CAAA,CAAA;AAwB1E;AAKA;AAKA;AAKa,KA5CD,UAAA,GAAa,kBA4CkD;AAK3E;AAKA;AAKA;AAiCa,KAvFD,UAAA,GAAa,yBAkHxB,GAlHoD,kBAkHpD,GAlHyE,yBAkHzE;;;;AA3BkD,cA/DtC,MA+DsC,EAAA,CAAA,KAAA,EAAA,MAAA,EAAA,GA/DZ,QA+DY;AAgCnD;;;AAA4D,cA1F/C,OA0F+C,EAAA,CAAA,KAAA,EAAA,MAAA,EAAA,GA1FpB,QA0FoB;;;;cArF/C,4BAA2B;;;;cAK3B,0BAAyB;;;;cAKzB,yBAAwB;;;;cAKxB,0BAAyB;;;;cAKzB,qBAAsB;;;;cAiCtB,0BAAyB,OAAc,UAAU;;;;cAgCjD,cAAe,UAAQ,OAAc,UAAU"}
|
package/dist/index.d.mts
CHANGED
|
@@ -1,25 +1,25 @@
|
|
|
1
|
-
import { t as adt_d_exports } from "./index-
|
|
1
|
+
import { t as adt_d_exports } from "./index-BaRJVkLo.mjs";
|
|
2
2
|
import { t as brand_d_exports } from "./index-BA0EsFxS.mjs";
|
|
3
3
|
import { n as service_d_exports } from "./service-D8mr0wwg.mjs";
|
|
4
4
|
import { n as context_d_exports } from "./context-B2dWloPl.mjs";
|
|
5
5
|
import "./context/index.mjs";
|
|
6
|
-
import { t as data_d_exports } from "./index-
|
|
6
|
+
import { t as data_d_exports } from "./index-D6pjHqlK.mjs";
|
|
7
7
|
import { n as result_d_exports } from "./index-CIvNgjsx.mjs";
|
|
8
|
-
import { r as duration_d_exports } from "./index-
|
|
8
|
+
import { r as duration_d_exports } from "./index-DfAqfnY0.mjs";
|
|
9
9
|
import { t as either_d_exports } from "./index-dCRymj_g.mjs";
|
|
10
10
|
import { n as flow, t as pipe } from "./index-D7mFNjot.mjs";
|
|
11
|
-
import { r as schedule_d_exports } from "./schedule-
|
|
12
|
-
import { t as fx_d_exports } from "./index-
|
|
11
|
+
import { r as schedule_d_exports } from "./schedule-BzPjvMXc.mjs";
|
|
12
|
+
import { t as fx_d_exports } from "./index-BD-els5J.mjs";
|
|
13
13
|
import { r as scope_d_exports } from "./scope-CuM3CzwG.mjs";
|
|
14
14
|
import { t as layer_d_exports } from "./index-uE3S3Krx.mjs";
|
|
15
15
|
import { t as multithread_d_exports } from "./index-DR7hzXU4.mjs";
|
|
16
16
|
import { t as option_d_exports } from "./index-BqJ1GWAF.mjs";
|
|
17
17
|
import { t as order_d_exports } from "./index-D8rDE60Y.mjs";
|
|
18
18
|
import { t as predicate_d_exports } from "./index-CNTYbcY9.mjs";
|
|
19
|
-
import { t as provide_d_exports } from "./index-
|
|
20
|
-
import { t as queue_d_exports } from "./index-
|
|
19
|
+
import { t as provide_d_exports } from "./index-D8gcYvR9.mjs";
|
|
20
|
+
import { t as queue_d_exports } from "./index-CVmgBpDt.mjs";
|
|
21
21
|
import "./schedule/index.mjs";
|
|
22
|
-
import { t as schema_d_exports } from "./index-
|
|
22
|
+
import { t as schema_d_exports } from "./index-BipW0MC3.mjs";
|
|
23
23
|
import "./scope/index.mjs";
|
|
24
24
|
import "./service/index.mjs";
|
|
25
25
|
export { adt_d_exports as Adt, brand_d_exports as Brand, context_d_exports as Context, data_d_exports as Data, duration_d_exports as Duration, either_d_exports as Either, fx_d_exports as Fx, layer_d_exports as Layer, multithread_d_exports as Multithread, option_d_exports as Option, order_d_exports as Order, predicate_d_exports as Predicate, provide_d_exports as Provide, queue_d_exports as Queue, result_d_exports as Result, schedule_d_exports as Schedule, schema_d_exports as Schema, scope_d_exports as Scope, service_d_exports as Service, flow, pipe };
|
package/dist/index.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{t as e}from"./adt-
|
|
1
|
+
import{t as e}from"./adt-CY8wLJJI.mjs";import{t}from"./flow-CNyLsPGb.mjs";import{a as n}from"./result-D3VY0qBG.mjs";import{t as r}from"./brand-DZgGDrAe.mjs";import{t as i}from"./context-0xDbwtpx.mjs";import"./context/index.mjs";import{n as a}from"./data-DqACNS_g.mjs";import{t as o}from"./duration-Bas3mi1N.mjs";import{r as s}from"./option-C2iCxAuJ.mjs";import{t as c}from"./either-G7uOu4Ar.mjs";import{t as l}from"./functions-ByAk682_.mjs";import{a as u}from"./queue-GYVrD39q.mjs";import{t as d}from"./fx-C_RTDEpv.mjs";import{t as f}from"./layer-C5A-EM0h.mjs";import"./layer/index.mjs";import{t as p}from"./multithread-Cyc8Bz45.mjs";import{t as m}from"./order-BXOBEKvB.mjs";import{t as h}from"./predicate-D_1SsIi4.mjs";import{n as g}from"./scope-gVt4PESc.mjs";import{t as _}from"./provide-CuccogWx.mjs";import"./queue/index.mjs";import{t as v}from"./schedule-B7qV60tO.mjs";import{t as y}from"./schema-DstB1_VK.mjs";import"./scope/index.mjs";import{t as b}from"./service-CWAIEH46.mjs";export{e as Adt,r as Brand,i as Context,a as Data,o as Duration,c as Either,d as Fx,f as Layer,p as Multithread,s as Option,m as Order,h as Predicate,_ as Provide,u as Queue,n as Result,v as Schedule,y as Schema,g as Scope,b as Service,t as flow,l as pipe};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
const e=16777619,t=()=>({hashes:new WeakMap,inProgress:new WeakSet,objectIds:new WeakMap,nextObjectId:1}),n=(e,t)=>{let n=e.objectIds.get(t);if(n!==void 0)return n;let r=e.nextObjectId;return e.objectIds.set(t,r),e.nextObjectId++,r},r=(t,i)=>{let a=2166136261;if(t===null)return a^1853189228;if(t===void 0)return a^1970168933;switch(typeof t){case`boolean`:return a^(t?1:0);case`number`:return Number.isNaN(t)?a^5136718:Number.isFinite(t)?a^(t|0)^(t*1e6|0):a^(t>0?4812390:759787110);case`string`:for(let n=0;n<t.length;n++)a^=t.codePointAt(n),a=Math.imul(a,e);return a>>>0;case`object`:{let o=t,s=i.hashes.get(o);if(s!==void 0)return s;if(i.inProgress.has(o))return(a^1668899692^n(i,o))>>>0;if(t instanceof Date)return a^r(t.getTime(),i);if(i.inProgress.add(o),n(i,o),Array.isArray(t)){a^=23389;for(let n=0;n<t.length;n++)a^=r(t[n],i),a=Math.imul(a,e);let n=a>>>0;return i.inProgress.delete(o),i.hashes.set(o,n),n}a^=31613;let c=t,l=Object.keys(c).toSorted();for(let t of l)a^=r(t,i),a=Math.imul(a,e),a^=r(c[t],i),a=Math.imul(a,e);let u=a>>>0;return i.inProgress.delete(o),i.hashes.set(o,u),u}default:return a}};function i(e){return r(e,t())}const a=(e,t,n)=>{let r=e.get(t);return r?.has(n)===!0?!0:r===void 0?(e.set(t,new WeakSet([n])),!1):(r.add(n),!1)},o=(e,t,n)=>{if(e===t)return!0;if(typeof e!=typeof t||e===null||t===null||typeof e!=`object`||typeof t!=`object`)return!1;if(a(n,e,t))return!0;if(e instanceof Date&&t instanceof Date)return e.getTime()===t.getTime();if(Array.isArray(e)&&Array.isArray(t))return e.length===t.length?e.every((e,r)=>o(e,t[r],n)):!1;if(Array.isArray(e)!==Array.isArray(t))return!1;let r=e,i=t,s=Object.keys(r),c=Object.keys(i);return s.length===c.length?s.every(e=>o(r[e],i[e],n)):!1};function s(e,t){return o(e,t,new WeakMap)}function c(e){return(t,n)=>t===n?!0:t._tag!==e||n._tag!==e?!1:s(t,n)}function l(e){return t=>t._tag===e?i(t):0}function u(e){return(t,n)=>t===n?!0:t._tag!==n._tag||!e.includes(t._tag)?!1:s(t,n)}function d(e){return t=>e.includes(t._tag)?i(t):0}export{
|
|
2
|
-
//# sourceMappingURL=
|
|
1
|
+
const e=16777619,t=()=>({hashes:new WeakMap,inProgress:new WeakSet,objectIds:new WeakMap,nextObjectId:1}),n=(e,t)=>{let n=e.objectIds.get(t);if(n!==void 0)return n;let r=e.nextObjectId;return e.objectIds.set(t,r),e.nextObjectId++,r},r=(t,i)=>{let a=2166136261;if(t===null)return a^1853189228;if(t===void 0)return a^1970168933;switch(typeof t){case`boolean`:return a^(t?1:0);case`number`:return Number.isNaN(t)?a^5136718:Number.isFinite(t)?a^(t|0)^(t*1e6|0):a^(t>0?4812390:759787110);case`string`:for(let n=0;n<t.length;n++)a^=t.codePointAt(n),a=Math.imul(a,e);return a>>>0;case`object`:{let o=t,s=i.hashes.get(o);if(s!==void 0)return s;if(i.inProgress.has(o))return(a^1668899692^n(i,o))>>>0;if(t instanceof Date)return a^r(t.getTime(),i);if(i.inProgress.add(o),n(i,o),Array.isArray(t)){a^=23389;for(let n=0;n<t.length;n++)a^=r(t[n],i),a=Math.imul(a,e);let n=a>>>0;return i.inProgress.delete(o),i.hashes.set(o,n),n}a^=31613;let c=t,l=Object.keys(c).toSorted();for(let t of l)a^=r(t,i),a=Math.imul(a,e),a^=r(c[t],i),a=Math.imul(a,e);let u=a>>>0;return i.inProgress.delete(o),i.hashes.set(o,u),u}default:return a}};function i(e){return r(e,t())}const a=(e,t,n)=>{let r=e.get(t);return r?.has(n)===!0?!0:r===void 0?(e.set(t,new WeakSet([n])),!1):(r.add(n),!1)},o=(e,t,n)=>{if(e===t)return!0;if(typeof e!=typeof t||e===null||t===null||typeof e!=`object`||typeof t!=`object`)return!1;if(a(n,e,t))return!0;if(e instanceof Date&&t instanceof Date)return e.getTime()===t.getTime();if(Array.isArray(e)&&Array.isArray(t))return e.length===t.length?e.every((e,r)=>o(e,t[r],n)):!1;if(Array.isArray(e)!==Array.isArray(t))return!1;let r=e,i=t,s=Object.keys(r),c=Object.keys(i);return s.length===c.length?s.every(e=>o(r[e],i[e],n)):!1};function s(e,t){return o(e,t,new WeakMap)}function c(e){return(t,n)=>t===n?!0:t._tag!==e||n._tag!==e?!1:s(t,n)}function l(e){return t=>t._tag===e?i(t):0}function u(e){return(t,n)=>t===n?!0:t._tag!==n._tag||!e.includes(t._tag)?!1:s(t,n)}function d(e){return t=>e.includes(t._tag)?i(t):0}function f(e){return typeof e!=`object`||!e?!1:Object.getPrototypeOf(e)===null||Object.getPrototypeOf(e)===Object.prototype}export{l as a,c as i,u as n,s as o,d as r,i as s,f as t};
|
|
2
|
+
//# sourceMappingURL=is-plain-object-BoFjRafL.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"is-plain-object-BoFjRafL.mjs","names":["result"],"sources":["../src/equality/equality.ts","../src/shared/is-plain-object.ts"],"sourcesContent":["import type { Discriminator } from \"../shared/discriminator.types\"\n\n// ============================================================================\n// Hashing (FNV-1a inspired algorithm)\n// ============================================================================\n\nconst FNV_OFFSET = 2166136261\nconst FNV_PRIME = 16777619\n// \"cycl\"\nconst CYCLE_MARKER = 0x6379636c\n\ntype HashState = {\n readonly hashes: WeakMap<object, number>\n readonly inProgress: WeakSet<object>\n readonly objectIds: WeakMap<object, number>\n nextObjectId: number\n}\n\nconst createHashState = (): HashState => ({\n hashes: new WeakMap<object, number>(),\n inProgress: new WeakSet<object>(),\n objectIds: new WeakMap<object, number>(),\n nextObjectId: 1,\n})\n\nconst getObjectId = (state: HashState, value: object): number => {\n const existing = state.objectIds.get(value)\n if (existing !== undefined) return existing\n const id = state.nextObjectId\n state.objectIds.set(value, id)\n state.nextObjectId++\n return id\n}\n\nconst deepHashInternal = (value: unknown, state: HashState): number => {\n let hash = FNV_OFFSET\n\n // \"null\" as hex\n if (value === null) return hash ^ 0x6e756c6c\n // \"unde\" as hex\n if (value === undefined) return hash ^ 0x756e6465\n\n /* oxlint-disable unicorn/prefer-math-trunc, no-case-declarations, switch-exhaustiveness-check -- Bitwise ops are intentional for FNV-1a hash: | 0 truncates to signed 32-bit, >>> 0 converts to unsigned 32-bit (Math.trunc cannot do this). Default case handles function, symbol, bigint. */\n switch (typeof value) {\n case \"boolean\":\n return hash ^ (value ? 1 : 0)\n\n case \"number\": {\n // Handle special cases: \"NaN\" as hex\n if (Number.isNaN(value)) return hash ^ 0x4e614e\n if (!Number.isFinite(value)) return hash ^ (value > 0 ? 0x496e66 : 0x2d496e66)\n // Mix the number bits into hash\n return hash ^ (value | 0) ^ ((value * 1000000) | 0)\n }\n\n case \"string\":\n for (let i = 0; i < value.length; i++) {\n hash ^= value.codePointAt(i)!\n hash = Math.imul(hash, FNV_PRIME)\n }\n // Convert to unsigned 32-bit\n return hash >>> 0\n\n case \"object\": {\n const objectValue = value\n\n const existingHash = state.hashes.get(objectValue)\n if (existingHash !== undefined) return existingHash\n\n if (state.inProgress.has(objectValue)) {\n return (hash ^ CYCLE_MARKER ^ getObjectId(state, objectValue)) >>> 0\n }\n\n if (value instanceof Date) {\n return hash ^ deepHashInternal(value.getTime(), state)\n }\n\n state.inProgress.add(objectValue)\n getObjectId(state, objectValue)\n\n if (Array.isArray(value)) {\n // \"[]\" as hex\n hash ^= 0x5b5d\n for (let i = 0; i < value.length; i++) {\n hash ^= deepHashInternal(value[i], state)\n hash = Math.imul(hash, FNV_PRIME)\n }\n const result = hash >>> 0\n state.inProgress.delete(objectValue)\n state.hashes.set(objectValue, result)\n return result\n }\n\n // Plain object: \"{}\" as hex\n hash ^= 0x7b7d\n // oxlint-disable-next-line no-unsafe-type-assertion -- Required for object iteration\n const obj = value as Record<string, unknown>\n // Sort keys for consistency\n const keys = Object.keys(obj).toSorted()\n for (const key of keys) {\n hash ^= deepHashInternal(key, state)\n hash = Math.imul(hash, FNV_PRIME)\n hash ^= deepHashInternal(obj[key], state)\n hash = Math.imul(hash, FNV_PRIME)\n }\n const result = hash >>> 0\n state.inProgress.delete(objectValue)\n state.hashes.set(objectValue, result)\n return result\n }\n\n default:\n // Handles: function, symbol, bigint\n return hash\n }\n /* oxlint-enable unicorn/prefer-math-trunc, no-case-declarations */\n}\n\n/**\n * Compute a 32-bit hash code for any value using an FNV-1a inspired algorithm.\n *\n * Handles: primitives, null, undefined, Date, arrays, plain objects, and cyclic structures.\n * Object keys are sorted for deterministic hashing regardless of insertion order.\n *\n * @param value - The value to hash (any type)\n * @returns A 32-bit unsigned integer hash code\n *\n * @example\n * ```ts\n * deepHash({ a: 1, b: 2 }) // deterministic number\n * deepHash({ b: 2, a: 1 }) // same number (keys sorted)\n * deepHash([1, 2, 3]) === deepHash([1, 2, 3]) // true\n * ```\n */\nexport function deepHash(value: unknown): number {\n return deepHashInternal(value, createHashState())\n}\n\ntype EqualsState = WeakMap<object, WeakSet<object>>\n\nconst markComparedPair = (state: EqualsState, a: object, b: object): boolean => {\n const compared = state.get(a)\n if (compared?.has(b) === true) return true\n if (compared === undefined) {\n state.set(a, new WeakSet<object>([b]))\n return false\n }\n compared.add(b)\n return false\n}\n\nconst deepEqualsInternal = (a: unknown, b: unknown, state: EqualsState): boolean => {\n // Same reference or both null/undefined\n if (a === b) return true\n\n // Different types\n if (typeof a !== typeof b) return false\n\n // Handle null\n if (a === null || b === null) return false\n\n // Primitives (already checked === above)\n if (typeof a !== \"object\") return false\n if (typeof b !== \"object\") return false\n\n const aObjRef = a\n const bObjRef = b\n\n if (markComparedPair(state, aObjRef, bObjRef)) return true\n\n // Date comparison\n if (a instanceof Date && b instanceof Date) {\n return a.getTime() === b.getTime()\n }\n\n // Array comparison\n if (Array.isArray(a) && Array.isArray(b)) {\n if (a.length !== b.length) return false\n return a.every((item, index) => deepEqualsInternal(item, b[index], state))\n }\n\n // Plain object comparison\n if (Array.isArray(a) !== Array.isArray(b)) return false\n\n // oxlint-disable-next-line no-unsafe-type-assertion -- Required for object comparison\n const aObj = a as Record<string, unknown>\n // oxlint-disable-next-line no-unsafe-type-assertion -- Required for object comparison\n const bObj = b as Record<string, unknown>\n\n const aKeys = Object.keys(aObj)\n const bKeys = Object.keys(bObj)\n\n if (aKeys.length !== bKeys.length) return false\n\n return aKeys.every((key) => deepEqualsInternal(aObj[key], bObj[key], state))\n}\n\n// ============================================================================\n// Equality\n// ============================================================================\n\n/**\n * Deep structural equality comparison for two values.\n *\n * Compares by value rather than reference. Handles:\n * - Primitives (===)\n * - null and undefined\n * - Date objects (by timestamp)\n * - Arrays (element-wise, same length required)\n * - Plain objects (key-value pairs, same keys required)\n * - Cyclic/self-referential object graphs\n *\n * @param a - First value to compare\n * @param b - Second value to compare\n * @returns true if values are structurally equal\n *\n * @example\n * ```ts\n * deepEquals({ x: 1 }, { x: 1 }) // true\n * deepEquals([1, 2], [1, 2]) // true\n * deepEquals(new Date(0), new Date(0)) // true\n * deepEquals({ a: 1 }, { a: 1, b: 2 }) // false (different keys)\n * ```\n */\nexport function deepEquals(a: unknown, b: unknown): boolean {\n return deepEqualsInternal(a, b, new WeakMap<object, WeakSet<object>>())\n}\n\n// ============================================================================\n// Factory Functions\n// ============================================================================\n\n/**\n * Create an equals method for a specific record type.\n *\n * Returns a function that compares two values of the same record type.\n * Returns false if either value doesn't have the expected _tag.\n *\n * @template Tag - The discriminator string literal type\n * @template T - The record's data type (excluding _tag)\n * @param _tag - The expected _tag discriminator value\n * @returns A binary equality function for the record type\n *\n * @example\n * ```ts\n * const equalsPoint = createEqualsMethod<'Point', { x: number; y: number }>('Point')\n * equalsPoint(\n * { _tag: 'Point', x: 1, y: 2 },\n * { _tag: 'Point', x: 1, y: 2 }\n * ) // true\n * ```\n */\nexport function createEqualsMethod<Tag extends string, T>(\n _tag: Tag,\n): (a: T & Discriminator<Tag>, b: T & Discriminator<Tag>) => boolean {\n return (a, b) => {\n if (a === b) return true\n if (a._tag !== _tag || b._tag !== _tag) return false\n return deepEquals(a, b)\n }\n}\n\n/**\n * Create a hash method for a specific record type.\n *\n * Returns a function that computes a hash code for values of the record type.\n * Returns 0 if the value doesn't have the expected _tag.\n *\n * @template Tag - The discriminator string literal type\n * @template T - The record's data type (excluding _tag)\n * @param _tag - The expected _tag discriminator value\n * @returns A unary hash function for the record type\n *\n * @example\n * ```ts\n * const hashPoint = createHashMethod<'Point', { x: number; y: number }>('Point')\n * hashPoint({ _tag: 'Point', x: 1, y: 2 }) // number\n * ```\n */\nexport function createHashMethod<Tag extends string, T>(_tag: Tag): (value: T & Discriminator<Tag>) => number {\n return (value) => {\n if (value._tag !== _tag) return 0\n return deepHash(value)\n }\n}\n\n/**\n * Create an equals method for an ADT (any variant).\n *\n * Returns a function that compares two ADT values for structural equality.\n * Values must have the same _tag and be a known variant.\n *\n * @template T - The ADT type (union of all variants with _tag)\n * @param tags - Array of valid _tag values for this ADT\n * @returns A binary equality function for any variant of the ADT\n *\n * @example\n * ```ts\n * const equalsShape = createADTEqualsMethod<Circle | Square>(['Circle', 'Square'])\n * equalsShape(circle1, circle2) // true if structurally equal\n * equalsShape(circle, square) // false (different _tag)\n * ```\n */\nexport function createADTEqualsMethod<T extends { readonly _tag: string }>(tags: string[]): (a: T, b: T) => boolean {\n return (a, b) => {\n if (a === b) return true\n if (a._tag !== b._tag) return false\n if (!tags.includes(a._tag)) return false\n return deepEquals(a, b)\n }\n}\n\n/**\n * Create a hash method for an ADT (any variant).\n *\n * Returns a function that computes a hash code for any variant of the ADT.\n * Returns 0 if the value's _tag is not a known variant.\n *\n * @template T - The ADT type (union of all variants with _tag)\n * @param tags - Array of valid _tag values for this ADT\n * @returns A unary hash function for any variant of the ADT\n *\n * @example\n * ```ts\n * const hashShape = createADTHashMethod<Circle | Square>(['Circle', 'Square'])\n * hashShape(circle) // number\n * hashShape(square) // number\n * ```\n */\nexport function createADTHashMethod<T extends { readonly _tag: string }>(tags: string[]): (value: T) => number {\n return (value) => {\n if (!tags.includes(value._tag)) return 0\n return deepHash(value)\n }\n}\n","/**\n * Check if a value is a plain object.\n * A plain object is an object created with `{}`, `Object.create(null)`, or `new Object()`.\n * Arrays, functions, dates, maps, etc. are not considered plain objects.\n */\nexport function isPlainObject(value: unknown): value is Record<PropertyKey, unknown> {\n if (value === null || typeof value !== \"object\") {\n return false\n }\n\n return Object.getPrototypeOf(value) === null || Object.getPrototypeOf(value) === Object.prototype\n}\n"],"mappings":"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"}
|
package/dist/layer/index.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{t as e}from"../layer-
|
|
1
|
+
import{t as e}from"../layer-C5A-EM0h.mjs";export{e as Layer};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{t as e}from"./chunk-oQKkju2G.mjs";import{t}from"./fx.types-DyQVgTS8.mjs";import{i as n,n as r,r as i}from"./context-0xDbwtpx.mjs";import{n as a,t as o}from"./service-resolution-BefYr4nR.mjs";var s=e({err:()=>h,fx:()=>g,merge:()=>y,ok:()=>m,provide:()=>v,scoped:()=>_});const c=(e,n)=>({_tag:`Layer`,_ROut:void 0,_E:void 0,_RIn:void 0,_Sync:void 0,build:()=>({_tag:`SyncFx`,[t]:{_A:()=>void 0,_E:()=>void 0,_R:()=>void 0},*[Symbol.iterator](){return i(e,n)}})}),l=e=>({_tag:`Layer`,_ROut:void 0,_E:void 0,_RIn:void 0,_Sync:void 0,build:()=>({_tag:`SyncFx`,[t]:{_A:()=>void 0,_E:()=>e,_R:()=>void 0},*[Symbol.iterator](){throw yield e,Error(`Unreachable`)}})});function u(e){return n=>({_tag:`Layer`,_ROut:void 0,_E:void 0,_RIn:void 0,_Sync:void 0,build:()=>n._tag===`AsyncFx`?{_tag:`AsyncFx`,[t]:{_A:()=>void 0,_E:()=>void 0,_R:()=>void 0},async*[Symbol.asyncIterator](){let t=n[Symbol.asyncIterator](),r=await t.next();for(;r.done!==!0;){let e=yield r.value;r=await t.next(e)}return i(e,r.value)}}:{_tag:`SyncFx`,[t]:{_A:()=>void 0,_E:()=>void 0,_R:()=>void 0},*[Symbol.iterator](){let t=n[Symbol.iterator](),r=t.next();for(;r.done!==!0;){let e=yield r.value;r=t.next(e)}return i(e,r.value)}}})}function d(e){return n=>({_tag:`Layer`,_ROut:void 0,_E:void 0,_RIn:void 0,_Sync:void 0,build:(r,a)=>n._tag===`AsyncFx`?{_tag:`AsyncFx`,[t]:{_A:()=>void 0,_E:()=>void 0,_R:()=>void 0},async*[Symbol.asyncIterator](){let t=n[Symbol.asyncIterator](),r=await t.next();for(;r.done!==!0;){let e=r.value;if(o(e)?.key===`@std/Scope`)r=await t.next(a);else{let n=yield e;r=await t.next(n)}}return i(e,r.value)}}:{_tag:`SyncFx`,[t]:{_A:()=>void 0,_E:()=>void 0,_R:()=>void 0},*[Symbol.iterator](){let t=n[Symbol.iterator](),r=t.next();for(;r.done!==!0;){let e=r.value;if(o(e)?.key===`@std/Scope`)r=t.next(a);else{let n=yield e;r=t.next(n)}}return i(e,r.value)}}})}function f(e){return r=>({_tag:`Layer`,_ROut:void 0,_E:void 0,_RIn:void 0,_Sync:void 0,build:(i,o)=>{let s=e.build(i,o);return s._tag===`AsyncFx`?{_tag:`AsyncFx`,[t]:{_A:()=>void 0,_E:()=>void 0,_R:()=>void 0},async*[Symbol.asyncIterator](){let e=s[Symbol.asyncIterator](),t=await e.next();for(;t.done!==!0;){let n=yield t.value;t=await e.next(n)}let c=t.value,l=r.build(i,o);if(l._tag===`AsyncFx`){let e=l[Symbol.asyncIterator](),t=await e.next();for(;t.done!==!0;){let n=t.value,r=a(c,n);if(r!==void 0){t=await e.next(r);continue}let i=yield n;t=await e.next(i)}return n(c,t.value)}let u=l[Symbol.iterator](),d=u.next();for(;d.done!==!0;){let e=d.value,t=a(c,e);if(t!==void 0){d=u.next(t);continue}let n=yield e;d=u.next(n)}return n(c,d.value)}}:{_tag:`SyncFx`,[t]:{_A:()=>void 0,_E:()=>void 0,_R:()=>void 0},*[Symbol.iterator](){let e=s[Symbol.iterator](),t=e.next();for(;t.done!==!0;){let n=yield t.value;t=e.next(n)}let c=t.value,l=r.build(i,o);if(l._tag===`SyncFx`){let e=l[Symbol.iterator](),t=e.next();for(;t.done!==!0;){let n=t.value,r=a(c,n);if(r!==void 0){t=e.next(r);continue}let i=yield n;t=e.next(i)}return n(c,t.value)}throw Error(`Cannot use async layer in sync context`)}}}})}function p(...e){return{_tag:`Layer`,_ROut:void 0,_E:void 0,_RIn:void 0,_Sync:void 0,build:(i,o)=>e.some(e=>e.build(i,o)._tag===`AsyncFx`)?{_tag:`AsyncFx`,[t]:{_A:()=>void 0,_E:()=>void 0,_R:()=>void 0},async*[Symbol.asyncIterator](){let t=r();for(let r of e){let e=r.build(i,o);if(e._tag===`AsyncFx`){let r=e[Symbol.asyncIterator](),i=await r.next();for(;i.done!==!0;){let e=i.value,n=a(t,e);if(n!==void 0){i=await r.next(n);continue}let o=yield e;i=await r.next(o)}t=n(t,i.value)}else{let r=e[Symbol.iterator](),i=r.next();for(;i.done!==!0;){let e=i.value,n=a(t,e);if(n!==void 0){i=r.next(n);continue}let o=yield e;i=r.next(o)}t=n(t,i.value)}}return t}}:{_tag:`SyncFx`,[t]:{_A:()=>void 0,_E:()=>void 0,_R:()=>void 0},*[Symbol.iterator](){let t=r();for(let r of e){let e=r.build(i,o);if(e._tag!==`SyncFx`)throw Error(`Expected sync layer in sync context`);let s=e[Symbol.iterator](),c=s.next();for(;c.done!==!0;){let e=c.value,n=a(t,e);if(n!==void 0){c=s.next(n);continue}let r=yield e;c=s.next(r)}t=n(t,c.value)}return t}}}}const m=c,h=l,g=u,_=d,v=f,y=p;export{s as t};
|
|
2
|
-
//# sourceMappingURL=layer-
|
|
1
|
+
import{t as e}from"./chunk-oQKkju2G.mjs";import{t}from"./fx.types-DyQVgTS8.mjs";import{i as n,n as r,r as i}from"./context-0xDbwtpx.mjs";import{n as a,t as o}from"./service-resolution-BefYr4nR.mjs";var s=e({err:()=>h,fx:()=>g,merge:()=>y,ok:()=>m,provide:()=>v,scoped:()=>_});const c=(e,n)=>({_tag:`Layer`,_ROut:void 0,_E:void 0,_RIn:void 0,_Sync:void 0,build:()=>({_tag:`SyncFx`,[t]:{_A:()=>void 0,_E:()=>void 0,_R:()=>void 0},*[Symbol.iterator](){return i(e,n)}})}),l=e=>({_tag:`Layer`,_ROut:void 0,_E:void 0,_RIn:void 0,_Sync:void 0,build:()=>({_tag:`SyncFx`,[t]:{_A:()=>void 0,_E:()=>e,_R:()=>void 0},*[Symbol.iterator](){throw yield e,Error(`Unreachable`)}})});function u(e){return n=>({_tag:`Layer`,_ROut:void 0,_E:void 0,_RIn:void 0,_Sync:void 0,build:()=>n._tag===`AsyncFx`?{_tag:`AsyncFx`,[t]:{_A:()=>void 0,_E:()=>void 0,_R:()=>void 0},async*[Symbol.asyncIterator](){let t=n[Symbol.asyncIterator](),r=await t.next();for(;r.done!==!0;){let e=yield r.value;r=await t.next(e)}return i(e,r.value)}}:{_tag:`SyncFx`,[t]:{_A:()=>void 0,_E:()=>void 0,_R:()=>void 0},*[Symbol.iterator](){let t=n[Symbol.iterator](),r=t.next();for(;r.done!==!0;){let e=yield r.value;r=t.next(e)}return i(e,r.value)}}})}function d(e){return n=>({_tag:`Layer`,_ROut:void 0,_E:void 0,_RIn:void 0,_Sync:void 0,build:(r,a)=>n._tag===`AsyncFx`?{_tag:`AsyncFx`,[t]:{_A:()=>void 0,_E:()=>void 0,_R:()=>void 0},async*[Symbol.asyncIterator](){let t=n[Symbol.asyncIterator](),r=await t.next();for(;r.done!==!0;){let e=r.value;if(o(e)?.key===`@std/Scope`)r=await t.next(a);else{let n=yield e;r=await t.next(n)}}return i(e,r.value)}}:{_tag:`SyncFx`,[t]:{_A:()=>void 0,_E:()=>void 0,_R:()=>void 0},*[Symbol.iterator](){let t=n[Symbol.iterator](),r=t.next();for(;r.done!==!0;){let e=r.value;if(o(e)?.key===`@std/Scope`)r=t.next(a);else{let n=yield e;r=t.next(n)}}return i(e,r.value)}}})}function f(e){return r=>({_tag:`Layer`,_ROut:void 0,_E:void 0,_RIn:void 0,_Sync:void 0,build:(i,o)=>{let s=e.build(i,o);return s._tag===`AsyncFx`?{_tag:`AsyncFx`,[t]:{_A:()=>void 0,_E:()=>void 0,_R:()=>void 0},async*[Symbol.asyncIterator](){let e=s[Symbol.asyncIterator](),t=await e.next();for(;t.done!==!0;){let n=yield t.value;t=await e.next(n)}let c=t.value,l=r.build(i,o);if(l._tag===`AsyncFx`){let e=l[Symbol.asyncIterator](),t=await e.next();for(;t.done!==!0;){let n=t.value,r=a(c,n);if(r!==void 0){t=await e.next(r);continue}let i=yield n;t=await e.next(i)}return n(c,t.value)}let u=l[Symbol.iterator](),d=u.next();for(;d.done!==!0;){let e=d.value,t=a(c,e);if(t!==void 0){d=u.next(t);continue}let n=yield e;d=u.next(n)}return n(c,d.value)}}:{_tag:`SyncFx`,[t]:{_A:()=>void 0,_E:()=>void 0,_R:()=>void 0},*[Symbol.iterator](){let e=s[Symbol.iterator](),t=e.next();for(;t.done!==!0;){let n=yield t.value;t=e.next(n)}let c=t.value,l=r.build(i,o);if(l._tag===`SyncFx`){let e=l[Symbol.iterator](),t=e.next();for(;t.done!==!0;){let n=t.value,r=a(c,n);if(r!==void 0){t=e.next(r);continue}let i=yield n;t=e.next(i)}return n(c,t.value)}throw Error(`Cannot use async layer in sync context`)}}}})}function p(...e){return{_tag:`Layer`,_ROut:void 0,_E:void 0,_RIn:void 0,_Sync:void 0,build:(i,o)=>e.some(e=>e.build(i,o)._tag===`AsyncFx`)?{_tag:`AsyncFx`,[t]:{_A:()=>void 0,_E:()=>void 0,_R:()=>void 0},async*[Symbol.asyncIterator](){let t=r();for(let r of e){let e=r.build(i,o);if(e._tag===`AsyncFx`){let r=e[Symbol.asyncIterator](),i=await r.next();for(;i.done!==!0;){let e=i.value,n=a(t,e);if(n!==void 0){i=await r.next(n);continue}let o=yield e;i=await r.next(o)}t=n(t,i.value)}else{let r=e[Symbol.iterator](),i=r.next();for(;i.done!==!0;){let e=i.value,n=a(t,e);if(n!==void 0){i=r.next(n);continue}let o=yield e;i=r.next(o)}t=n(t,i.value)}}return t}}:{_tag:`SyncFx`,[t]:{_A:()=>void 0,_E:()=>void 0,_R:()=>void 0},*[Symbol.iterator](){let t=r();for(let r of e){let e=r.build(i,o);if(e._tag!==`SyncFx`)throw Error(`Expected sync layer in sync context`);let s=e[Symbol.iterator](),c=s.next();for(;c.done!==!0;){let e=c.value,n=a(t,e);if(n!==void 0){c=s.next(n);continue}let r=yield e;c=s.next(r)}t=n(t,c.value)}return t}}}}const m=c,h=l,g=u,_=d,v=f,y=p;export{y as n,s as t};
|
|
2
|
+
//# sourceMappingURL=layer-C5A-EM0h.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"layer-CKtH7TRL.mjs","names":["Context.make","fx","layerGen","layerResult","Context.merge","Context.empty"],"sources":["../src/layer/layer.ts"],"sourcesContent":["/**\n * Layer construction and composition for service dependency graphs.\n *\n * **Mental model**\n * - A `Layer` builds one or more services, potentially requiring other services.\n * - Compose layers and provide dependencies before running `Fx`.\n *\n * **Common tasks**\n * - Build from values with `Layer.ok`.\n * - Build from effects with `Layer.fx` or `Layer.scoped`.\n * - Compose with `Layer.provide` and `Layer.merge`.\n *\n * **Gotchas**\n * - Async layers force async execution paths.\n * - Scoped layers require scope finalization.\n *\n * **Quickstart**\n *\n * @example\n * ```ts\n * import { Fx, Layer, Provide, Service } from \"@nicolastoulemont/std\"\n *\n * const Port = Service.tag<number>(\"Port\")\n * const program = Fx.gen(function* () {\n * return yield* Port\n * })\n * const exit = Fx.run(Provide.layer(Layer.ok(Port, 3000))(program))\n * // => { _tag: \"Ok\", value: 3000 }\n * ```\n *\n * @module\n */\nimport * as Context from \"../context/context\"\nimport type { Context as ContextType } from \"../context/context\"\nimport { FxTypeId } from \"../fx/fx.types\"\nimport type { RunnableFx, SyncFx, AsyncFx, FxYield } from \"../fx/fx.types\"\nimport type { ScopeService, ExcludeScope } from \"../scope/scope\"\nimport type { ServiceClass } from \"../service/service\"\nimport { asServiceRequest, resolveService } from \"../service/service-resolution\"\nimport type { Layer as LayerType, MergeROut, MergeError, UnprovidedDeps, AllSync } from \"./layer.types\"\n\n/* oxlint-disable no-unsafe-type-assertion -- Layer composition carries erased generic channels and phantom type slots that require assertion-based reconstruction. */\n\n/**\n * Create a layer from a synchronous value (no dependencies).\n */\nconst layerOk = <S>(service: ServiceClass<S>, impl: S): LayerType<S, never, never, true> => ({\n _tag: \"Layer\",\n _ROut: undefined as unknown as S,\n _E: undefined as never,\n _RIn: undefined as never,\n _Sync: undefined as unknown as true,\n build: (): SyncFx<ContextType<S>> => ({\n _tag: \"SyncFx\",\n [FxTypeId]: {\n _A: () => undefined as unknown as ContextType<S>,\n _E: () => undefined as never,\n _R: () => undefined as never,\n },\n // oxlint-disable-next-line require-yield\n *[Symbol.iterator](): Generator<never, ContextType<S>, unknown> {\n return Context.make(service, impl)\n },\n }),\n})\n\n/**\n * Create a layer that always fails with an error.\n */\nconst layerErr = <E>(error: E): LayerType<never, E, never, true> => ({\n _tag: \"Layer\",\n _ROut: undefined as never,\n _E: undefined as unknown as E,\n _RIn: undefined as never,\n _Sync: undefined as unknown as true,\n build: (): SyncFx<ContextType, E> => ({\n _tag: \"SyncFx\",\n [FxTypeId]: {\n _A: () => undefined as never,\n _E: () => error,\n _R: () => undefined as never,\n },\n *[Symbol.iterator](): Generator<E, never, unknown> {\n yield error\n throw new Error(\"Unreachable\")\n },\n }),\n})\n\n/**\n * Create a layer from an Fx computation (can have dependencies).\n * The Sync type parameter is inferred from the input fx:\n * - SyncFx input → Layer with Sync=true\n * - AsyncFx input → Layer with Sync=false\n *\n * @example\n * ```ts\n * import { Fx, Layer, Provide, Service } from \"@nicolastoulemont/std\"\n *\n * const Port = Service.tag<number>(\"Port\")\n * const portLayer = Layer.fx(Port)(Fx.gen(function* () {\n * return 3000\n * }))\n * const program = Fx.gen(function* () {\n * return yield* Port\n * })\n * const exit = Fx.run(Provide.layer(portLayer)(program))\n * // => { _tag: \"Ok\", value: 3000 }\n * ```\n */\nfunction layerFx<S>(service: ServiceClass<S>): {\n <E, R>(fx: SyncFx<S, E, R>): LayerType<S, E, R, true>\n <E, R>(fx: AsyncFx<S, E, R>): LayerType<S, E, R, false>\n <E, R>(fx: RunnableFx<S, E, R>): LayerType<S, E, R>\n}\nfunction layerFx<S>(service: ServiceClass<S>) {\n return <E, R>(fx: RunnableFx<S, E, R>): LayerType<S, E, R> => ({\n _tag: \"Layer\",\n _ROut: undefined as unknown as S,\n _E: undefined as unknown as E,\n _RIn: undefined as unknown as R,\n _Sync: undefined as unknown as boolean,\n build: (): RunnableFx<ContextType<S>, E, R> => {\n if (fx._tag === \"AsyncFx\") {\n return {\n _tag: \"AsyncFx\",\n [FxTypeId]: {\n _A: () => undefined as unknown as ContextType<S>,\n _E: () => undefined as unknown as E,\n _R: () => undefined as unknown as R,\n },\n async *[Symbol.asyncIterator](): AsyncGenerator<FxYield<E, R>, ContextType<S>, unknown> {\n const gen = fx[Symbol.asyncIterator]()\n let result = await gen.next()\n while (result.done !== true) {\n const value = yield result.value\n // oxlint-disable-next-line no-await-in-loop\n result = await gen.next(value)\n }\n return Context.make(service, result.value)\n },\n } as AsyncFx<ContextType<S>, E, R>\n }\n\n return {\n _tag: \"SyncFx\",\n [FxTypeId]: {\n _A: () => undefined as unknown as ContextType<S>,\n _E: () => undefined as unknown as E,\n _R: () => undefined as unknown as R,\n },\n *[Symbol.iterator](): Generator<FxYield<E, R>, ContextType<S>, unknown> {\n const gen = fx[Symbol.iterator]()\n let result = gen.next()\n while (result.done !== true) {\n const value = yield result.value\n result = gen.next(value)\n }\n return Context.make(service, result.value)\n },\n } as SyncFx<ContextType<S>, E, R>\n },\n })\n}\n\n/**\n * Create a scoped layer (with resource cleanup).\n * The Sync type parameter is inferred from the input fx.\n *\n * @example\n * ```ts\n * import { Fx, Layer, Provide, Scope, Service } from \"@nicolastoulemont/std\"\n *\n * const Resource = Service.tag<{ readonly id: number }>(\"Resource\")\n * const ScopeTag = Service.tag<Scope.ScopeService>(\"@std/Scope\")\n * let finalized = 0\n *\n * const resourceLayer = Layer.scoped(Resource)(Fx.gen(function* () {\n * const scope = yield* ScopeTag\n * yield* scope.addFinalizer(() =>\n * Fx.gen(function* () {\n * finalized += 1\n * }),\n * )\n * return { id: 1 }\n * }))\n * const program = Fx.gen(function* () {\n * return (yield* Resource).id\n * })\n * const exit = Fx.run(Provide.layer(resourceLayer)(program))\n * // => { _tag: \"Ok\", value: 1 }\n * ```\n */\nfunction layerScoped<S>(service: ServiceClass<S>): {\n <E, R>(fx: SyncFx<S, E, R | ScopeService>): LayerType<S, E, ExcludeScope<R>, true>\n <E, R>(fx: AsyncFx<S, E, R | ScopeService>): LayerType<S, E, ExcludeScope<R>, false>\n <E, R>(fx: RunnableFx<S, E, R | ScopeService>): LayerType<S, E, ExcludeScope<R>>\n}\nfunction layerScoped<S>(service: ServiceClass<S>) {\n return <E, R>(fx: RunnableFx<S, E, R | ScopeService>): LayerType<S, E, ExcludeScope<R>> => ({\n _tag: \"Layer\",\n _ROut: undefined as unknown as S,\n _E: undefined as unknown as E,\n _RIn: undefined as unknown as ExcludeScope<R>,\n _Sync: undefined as unknown as boolean,\n build: (_memoMap, scope): RunnableFx<ContextType<S>, E, ExcludeScope<R>> => {\n if (fx._tag === \"AsyncFx\") {\n return {\n _tag: \"AsyncFx\",\n [FxTypeId]: {\n _A: () => undefined as unknown as ContextType<S>,\n _E: () => undefined as unknown as E,\n _R: () => undefined as unknown as ExcludeScope<R>,\n },\n async *[Symbol.asyncIterator](): AsyncGenerator<FxYield<E, ExcludeScope<R>>, ContextType<S>, unknown> {\n const gen = fx[Symbol.asyncIterator]()\n let result = await gen.next()\n while (result.done !== true) {\n const yielded = result.value\n const serviceRequest = asServiceRequest(yielded)\n if (serviceRequest?.key === \"@std/Scope\") {\n // oxlint-disable-next-line no-await-in-loop\n result = await gen.next(scope)\n } else {\n const value = yield yielded as FxYield<E, ExcludeScope<R>>\n // oxlint-disable-next-line no-await-in-loop\n result = await gen.next(value)\n }\n }\n return Context.make(service, result.value)\n },\n } as AsyncFx<ContextType<S>, E, ExcludeScope<R>>\n }\n\n return {\n _tag: \"SyncFx\",\n [FxTypeId]: {\n _A: () => undefined as unknown as ContextType<S>,\n _E: () => undefined as unknown as E,\n _R: () => undefined as unknown as ExcludeScope<R>,\n },\n *[Symbol.iterator](): Generator<FxYield<E, ExcludeScope<R>>, ContextType<S>, unknown> {\n const gen = fx[Symbol.iterator]()\n let result = gen.next()\n while (result.done !== true) {\n const yielded = result.value\n const serviceRequest = asServiceRequest(yielded)\n if (serviceRequest?.key === \"@std/Scope\") {\n result = gen.next(scope)\n } else {\n const value = yield yielded as FxYield<E, ExcludeScope<R>>\n result = gen.next(value)\n }\n }\n return Context.make(service, result.value)\n },\n } as SyncFx<ContextType<S>, E, ExcludeScope<R>>\n },\n })\n}\n\n// ============================================================================\n// Layer Composition\n// ============================================================================\n\n/**\n * Provide dependencies to a layer and merge outputs.\n * Sync is preserved only if both the deps layer and the consuming layer are sync.\n *\n * @example\n * ```ts\n * import { Fx, Layer, Provide, Service } from \"@nicolastoulemont/std\"\n *\n * const Port = Service.tag<number>(\"Port\")\n * const Server = Service.tag<{ readonly port: number }>(\"Server\")\n * const portLayer = Layer.ok(Port, 3000)\n * const serverLayer = Layer.fx(Server)(Fx.gen(function* () {\n * const port = yield* Port\n * return { port }\n * }))\n * const provided = Layer.provide(portLayer)(serverLayer)\n * const program = Fx.gen(function* () {\n * return (yield* Server).port\n * })\n * const exit = Fx.run(Provide.layer(provided)(program))\n * // => { _tag: \"Ok\", value: 3000 }\n * ```\n */\nfunction layerProvide<DepsROut, DepsE, DepsRIn, DepsSync extends boolean>(\n deps: LayerType<DepsROut, DepsE, DepsRIn, DepsSync>,\n): {\n <ROut, E, RIn extends DepsROut, LayerSync extends boolean>(\n layer: LayerType<ROut, E, RIn, LayerSync>,\n ): LayerType<ROut | DepsROut, E | DepsE, DepsRIn, LayerSync extends true ? DepsSync : false>\n}\nfunction layerProvide<DepsROut, DepsE, DepsRIn>(deps: LayerType<DepsROut, DepsE, DepsRIn>) {\n return <ROut, E, RIn extends DepsROut>(\n layer: LayerType<ROut, E, RIn>,\n ): LayerType<ROut | DepsROut, E | DepsE, DepsRIn> => ({\n _tag: \"Layer\",\n _ROut: undefined as unknown as ROut | DepsROut,\n _E: undefined as unknown as E | DepsE,\n _RIn: undefined as unknown as DepsRIn,\n _Sync: undefined as unknown as boolean,\n build: (memoMap, scope): RunnableFx<ContextType<ROut | DepsROut>, E | DepsE, DepsRIn> => {\n const depsBuildFx = deps.build(memoMap, scope)\n\n if (depsBuildFx._tag === \"AsyncFx\") {\n return {\n _tag: \"AsyncFx\",\n [FxTypeId]: {\n _A: () => undefined as unknown as ContextType<ROut | DepsROut>,\n _E: () => undefined as unknown as E | DepsE,\n _R: () => undefined as unknown as DepsRIn,\n },\n async *[Symbol.asyncIterator](): AsyncGenerator<\n FxYield<E | DepsE, DepsRIn>,\n ContextType<ROut | DepsROut>,\n unknown\n > {\n const depsGen = depsBuildFx[Symbol.asyncIterator]()\n let depsResult = await depsGen.next()\n while (depsResult.done !== true) {\n const value = yield depsResult.value\n // oxlint-disable-next-line no-await-in-loop\n depsResult = await depsGen.next(value)\n }\n const depsCtx = depsResult.value\n\n const layerBuildFx = layer.build(memoMap, scope)\n if (layerBuildFx._tag === \"AsyncFx\") {\n const layerGen = layerBuildFx[Symbol.asyncIterator]()\n let layerResult = await layerGen.next()\n while (layerResult.done !== true) {\n const yielded = layerResult.value\n const service = resolveService(depsCtx, yielded)\n if (service !== undefined) {\n // oxlint-disable-next-line no-await-in-loop\n layerResult = await layerGen.next(service)\n continue\n }\n const value = yield yielded as FxYield<E, DepsRIn>\n // oxlint-disable-next-line no-await-in-loop\n layerResult = await layerGen.next(value)\n }\n return Context.merge(depsCtx, layerResult.value)\n }\n\n const layerGen = layerBuildFx[Symbol.iterator]()\n let layerResult = layerGen.next()\n while (layerResult.done !== true) {\n const yielded = layerResult.value\n const service = resolveService(depsCtx, yielded)\n if (service !== undefined) {\n layerResult = layerGen.next(service)\n continue\n }\n const value = yield yielded as FxYield<E, DepsRIn>\n layerResult = layerGen.next(value)\n }\n return Context.merge(depsCtx, layerResult.value)\n },\n } as AsyncFx<ContextType<ROut | DepsROut>, E | DepsE, DepsRIn>\n }\n\n return {\n _tag: \"SyncFx\",\n [FxTypeId]: {\n _A: () => undefined as unknown as ContextType<ROut | DepsROut>,\n _E: () => undefined as unknown as E | DepsE,\n _R: () => undefined as unknown as DepsRIn,\n },\n *[Symbol.iterator](): Generator<FxYield<E | DepsE, DepsRIn>, ContextType<ROut | DepsROut>, unknown> {\n const depsGen = depsBuildFx[Symbol.iterator]()\n let depsResult = depsGen.next()\n while (depsResult.done !== true) {\n const value = yield depsResult.value\n depsResult = depsGen.next(value)\n }\n const depsCtx = depsResult.value\n\n const layerBuildFx = layer.build(memoMap, scope)\n if (layerBuildFx._tag === \"SyncFx\") {\n const syncGen = layerBuildFx[Symbol.iterator]()\n let layerResult = syncGen.next()\n while (layerResult.done !== true) {\n const yielded = layerResult.value\n const service = resolveService(depsCtx, yielded)\n if (service !== undefined) {\n layerResult = syncGen.next(service)\n continue\n }\n const value = yield yielded as FxYield<E, DepsRIn>\n layerResult = syncGen.next(value)\n }\n return Context.merge(depsCtx, layerResult.value)\n }\n throw new Error(\"Cannot use async layer in sync context\")\n },\n } as SyncFx<ContextType<ROut | DepsROut>, E | DepsE, DepsRIn>\n },\n })\n}\n\n/**\n * Merge multiple layers with automatic dependency resolution.\n * The merged layer is sync only if ALL input layers are sync.\n *\n * @example\n * ```ts\n * import { Fx, Layer, Provide, Service } from \"@nicolastoulemont/std\"\n *\n * const Logger = Service.tag<{ readonly prefix: string }>(\"Logger\")\n * const Clock = Service.tag<{ readonly now: () => number }>(\"Clock\")\n * const merged = Layer.merge(\n * Layer.ok(Logger, { prefix: \"dev\" }),\n * Layer.ok(Clock, { now: () => 123 }),\n * )\n * const program = Fx.gen(function* () {\n * const logger = yield* Logger\n * const clock = yield* Clock\n * return `${logger.prefix}:${clock.now()}`\n * })\n * const exit = Fx.run(Provide.layer(merged)(program))\n * // => { _tag: \"Ok\", value: \"dev:123\" }\n * ```\n */\nfunction layerMerge<L extends LayerType<unknown, unknown, unknown>[]>(\n ...layers: L\n): LayerType<MergeROut<L>, MergeError<L>, UnprovidedDeps<L>, AllSync<L>>\nfunction layerMerge<L extends LayerType<unknown, unknown, unknown>[]>(\n ...layers: L\n): LayerType<MergeROut<L>, MergeError<L>, UnprovidedDeps<L>> {\n return {\n _tag: \"Layer\",\n _ROut: undefined as unknown as MergeROut<L>,\n _E: undefined as unknown as MergeError<L>,\n _RIn: undefined as unknown as UnprovidedDeps<L>,\n _Sync: undefined as unknown as boolean,\n build: (memoMap, scope): RunnableFx<ContextType<MergeROut<L>>, MergeError<L>, UnprovidedDeps<L>> => {\n const hasAsync = layers.some((l) => l.build(memoMap, scope)._tag === \"AsyncFx\")\n\n if (hasAsync) {\n return {\n _tag: \"AsyncFx\",\n [FxTypeId]: {\n _A: () => undefined as unknown as ContextType<MergeROut<L>>,\n _E: () => undefined as unknown as MergeError<L>,\n _R: () => undefined as unknown as UnprovidedDeps<L>,\n },\n async *[Symbol.asyncIterator](): AsyncGenerator<\n FxYield<MergeError<L>, UnprovidedDeps<L>>,\n ContextType<MergeROut<L>>,\n unknown\n > {\n let ctx = Context.empty() as ContextType<unknown>\n for (const layer of layers) {\n const buildFx = layer.build(memoMap, scope)\n if (buildFx._tag === \"AsyncFx\") {\n const gen = buildFx[Symbol.asyncIterator]()\n // oxlint-disable-next-line no-await-in-loop\n let result = await gen.next()\n while (result.done !== true) {\n const yielded = result.value\n const service = resolveService(ctx, yielded)\n if (service !== undefined) {\n // oxlint-disable-next-line no-await-in-loop\n result = await gen.next(service)\n continue\n }\n const value = yield yielded as FxYield<MergeError<L>, UnprovidedDeps<L>>\n // oxlint-disable-next-line no-await-in-loop\n result = await gen.next(value)\n }\n ctx = Context.merge(ctx, result.value)\n } else {\n const gen = buildFx[Symbol.iterator]()\n let result = gen.next()\n while (result.done !== true) {\n const yielded = result.value\n const service = resolveService(ctx, yielded)\n if (service !== undefined) {\n result = gen.next(service)\n continue\n }\n const value = yield yielded as FxYield<MergeError<L>, UnprovidedDeps<L>>\n result = gen.next(value)\n }\n ctx = Context.merge(ctx, result.value)\n }\n }\n return ctx as ContextType<MergeROut<L>>\n },\n } as AsyncFx<ContextType<MergeROut<L>>, MergeError<L>, UnprovidedDeps<L>>\n }\n\n return {\n _tag: \"SyncFx\",\n [FxTypeId]: {\n _A: () => undefined as unknown as ContextType<MergeROut<L>>,\n _E: () => undefined as unknown as MergeError<L>,\n _R: () => undefined as unknown as UnprovidedDeps<L>,\n },\n *[Symbol.iterator](): Generator<FxYield<MergeError<L>, UnprovidedDeps<L>>, ContextType<MergeROut<L>>, unknown> {\n let ctx = Context.empty() as ContextType<unknown>\n for (const layer of layers) {\n const buildFx = layer.build(memoMap, scope)\n if (buildFx._tag !== \"SyncFx\") {\n throw new Error(\"Expected sync layer in sync context\")\n }\n const gen = buildFx[Symbol.iterator]()\n let result = gen.next()\n while (result.done !== true) {\n const yielded = result.value\n const service = resolveService(ctx, yielded)\n if (service !== undefined) {\n result = gen.next(service)\n continue\n }\n const value = yield yielded as FxYield<MergeError<L>, UnprovidedDeps<L>>\n result = gen.next(value)\n }\n ctx = Context.merge(ctx, result.value)\n }\n return ctx as ContextType<MergeROut<L>>\n },\n } as SyncFx<ContextType<MergeROut<L>>, MergeError<L>, UnprovidedDeps<L>>\n },\n }\n}\n\n/**\n * Create a successful no-dependency layer from a plain service value.\n *\n * @example\n * ```ts\n * import { Fx, Layer, Provide, Service } from \"@nicolastoulemont/std\"\n *\n * const Port = Service.tag<number>(\"Port\")\n * const program = Fx.gen(function* () {\n * return yield* Port\n * })\n * const exit = Fx.run(Provide.layer(Layer.ok(Port, 3000))(program))\n * // => { _tag: \"Ok\", value: 3000 }\n * ```\n */\nexport const ok = layerOk\n\n/**\n * Create a layer that always fails with an error.\n *\n * @example\n * ```ts\n * import { Fx, Layer, Provide } from \"@nicolastoulemont/std\"\n *\n * const program = Fx.gen(function* () {\n * return 1\n * })\n * const exit = Fx.run(Provide.layer(Layer.err(\"missing-config\"))(program))\n * // => { _tag: \"Err\", error: \"missing-config\" }\n * ```\n */\nexport const err = layerErr\n\n/**\n * Create a layer from an effectful service builder.\n *\n * @example\n * ```ts\n * import { Fx, Layer, Provide, Service } from \"@nicolastoulemont/std\"\n *\n * const Port = Service.tag<number>(\"Port\")\n * const portLayer = Layer.fx(Port)(Fx.gen(function* () {\n * return 3000\n * }))\n * const program = Fx.gen(function* () {\n * return yield* Port\n * })\n * const exit = Fx.run(Provide.layer(portLayer)(program))\n * // => { _tag: \"Ok\", value: 3000 }\n * ```\n */\nexport const fx = layerFx\n\n/**\n * Create a scoped layer that registers resource finalizers.\n *\n * @example\n * ```ts\n * import { Fx, Layer, Provide, Scope, Service } from \"@nicolastoulemont/std\"\n *\n * const Resource = Service.tag<{ readonly id: number }>(\"Resource\")\n * const ScopeTag = Service.tag<Scope.ScopeService>(\"@std/Scope\")\n * let finalized = 0\n *\n * const resourceLayer = Layer.scoped(Resource)(Fx.gen(function* () {\n * const scope = yield* ScopeTag\n * yield* scope.addFinalizer(() =>\n * Fx.gen(function* () {\n * finalized += 1\n * }),\n * )\n * return { id: 1 }\n * }))\n * const program = Fx.gen(function* () {\n * return (yield* Resource).id\n * })\n * const exit = Fx.run(Provide.layer(resourceLayer)(program))\n * // => { _tag: \"Ok\", value: 1 }\n * ```\n */\nexport const scoped = layerScoped\n\n/**\n * Provide one layer to another, satisfying dependencies.\n *\n * @example\n * ```ts\n * import { Fx, Layer, Provide, Service } from \"@nicolastoulemont/std\"\n *\n * const Port = Service.tag<number>(\"Port\")\n * const Server = Service.tag<{ readonly port: number }>(\"Server\")\n * const portLayer = Layer.ok(Port, 3000)\n * const serverLayer = Layer.fx(Server)(Fx.gen(function* () {\n * const port = yield* Port\n * return { port }\n * }))\n * const provided = Layer.provide(portLayer)(serverLayer)\n * const program = Fx.gen(function* () {\n * return (yield* Server).port\n * })\n * const exit = Fx.run(Provide.layer(provided)(program))\n * // => { _tag: \"Ok\", value: 3000 }\n * ```\n */\nexport const provide = layerProvide\n\n/**\n * Merge multiple layers into a single composite layer.\n *\n * @example\n * ```ts\n * import { Fx, Layer, Provide, Service } from \"@nicolastoulemont/std\"\n *\n * const Logger = Service.tag<{ readonly prefix: string }>(\"Logger\")\n * const Clock = Service.tag<{ readonly now: () => number }>(\"Clock\")\n * const merged = Layer.merge(\n * Layer.ok(Logger, { prefix: \"dev\" }),\n * Layer.ok(Clock, { now: () => 123 }),\n * )\n * const program = Fx.gen(function* () {\n * const logger = yield* Logger\n * const clock = yield* Clock\n * return `${logger.prefix}:${clock.now()}`\n * })\n * const exit = Fx.run(Provide.layer(merged)(program))\n * // => { _tag: \"Ok\", value: \"dev:123\" }\n * ```\n */\nexport const merge = layerMerge\n\n/* oxlint-enable no-unsafe-type-assertion */\n"],"mappings":"oRA8CA,MAAM,GAAc,EAA0B,KAA+C,CAC3F,KAAM,QACN,MAAO,IAAA,GACP,GAAI,IAAA,GACJ,KAAM,IAAA,GACN,MAAO,IAAA,GACP,WAAsC,CACpC,KAAM,UACL,GAAW,CACV,OAAU,IAAA,GACV,OAAU,IAAA,GACV,OAAU,IAAA,GACX,CAED,EAAE,OAAO,WAAuD,CAC9D,OAAOA,EAAa,EAAS,EAAK,EAErC,EACF,EAKK,EAAe,IAAgD,CACnE,KAAM,QACN,MAAO,IAAA,GACP,GAAI,IAAA,GACJ,KAAM,IAAA,GACN,MAAO,IAAA,GACP,WAAsC,CACpC,KAAM,UACL,GAAW,CACV,OAAU,IAAA,GACV,OAAU,EACV,OAAU,IAAA,GACX,CACD,EAAE,OAAO,WAA0C,CAEjD,MADA,MAAM,EACI,MAAM,cAAc,EAEjC,EACF,EA4BD,SAAS,EAAW,EAA0B,CAC5C,MAAc,KAAiD,CAC7D,KAAM,QACN,MAAO,IAAA,GACP,GAAI,IAAA,GACJ,KAAM,IAAA,GACN,MAAO,IAAA,GACP,UACMC,EAAG,OAAS,UACP,CACL,KAAM,WACL,GAAW,CACV,OAAU,IAAA,GACV,OAAU,IAAA,GACV,OAAU,IAAA,GACX,CACD,OAAQ,OAAO,gBAAyE,CACtF,IAAM,EAAMA,EAAG,OAAO,gBAAgB,CAClC,EAAS,MAAM,EAAI,MAAM,CAC7B,KAAO,EAAO,OAAS,IAAM,CAC3B,IAAM,EAAQ,MAAM,EAAO,MAE3B,EAAS,MAAM,EAAI,KAAK,EAAM,CAEhC,OAAOD,EAAa,EAAS,EAAO,MAAM,EAE7C,CAGI,CACL,KAAM,UACL,GAAW,CACV,OAAU,IAAA,GACV,OAAU,IAAA,GACV,OAAU,IAAA,GACX,CACD,EAAE,OAAO,WAA+D,CACtE,IAAM,EAAMC,EAAG,OAAO,WAAW,CAC7B,EAAS,EAAI,MAAM,CACvB,KAAO,EAAO,OAAS,IAAM,CAC3B,IAAM,EAAQ,MAAM,EAAO,MAC3B,EAAS,EAAI,KAAK,EAAM,CAE1B,OAAOD,EAAa,EAAS,EAAO,MAAM,EAE7C,CAEJ,EAoCH,SAAS,EAAe,EAA0B,CAChD,MAAc,KAA8E,CAC1F,KAAM,QACN,MAAO,IAAA,GACP,GAAI,IAAA,GACJ,KAAM,IAAA,GACN,MAAO,IAAA,GACP,OAAQ,EAAU,IACZC,EAAG,OAAS,UACP,CACL,KAAM,WACL,GAAW,CACV,OAAU,IAAA,GACV,OAAU,IAAA,GACV,OAAU,IAAA,GACX,CACD,OAAQ,OAAO,gBAAuF,CACpG,IAAM,EAAMA,EAAG,OAAO,gBAAgB,CAClC,EAAS,MAAM,EAAI,MAAM,CAC7B,KAAO,EAAO,OAAS,IAAM,CAC3B,IAAM,EAAU,EAAO,MAEvB,GADuB,EAAiB,EAAQ,EAC5B,MAAQ,aAE1B,EAAS,MAAM,EAAI,KAAK,EAAM,KACzB,CACL,IAAM,EAAQ,MAAM,EAEpB,EAAS,MAAM,EAAI,KAAK,EAAM,EAGlC,OAAOD,EAAa,EAAS,EAAO,MAAM,EAE7C,CAGI,CACL,KAAM,UACL,GAAW,CACV,OAAU,IAAA,GACV,OAAU,IAAA,GACV,OAAU,IAAA,GACX,CACD,EAAE,OAAO,WAA6E,CACpF,IAAM,EAAMC,EAAG,OAAO,WAAW,CAC7B,EAAS,EAAI,MAAM,CACvB,KAAO,EAAO,OAAS,IAAM,CAC3B,IAAM,EAAU,EAAO,MAEvB,GADuB,EAAiB,EAAQ,EAC5B,MAAQ,aAC1B,EAAS,EAAI,KAAK,EAAM,KACnB,CACL,IAAM,EAAQ,MAAM,EACpB,EAAS,EAAI,KAAK,EAAM,EAG5B,OAAOD,EAAa,EAAS,EAAO,MAAM,EAE7C,CAEJ,EAqCH,SAAS,EAAuC,EAA2C,CACzF,MACE,KACoD,CACpD,KAAM,QACN,MAAO,IAAA,GACP,GAAI,IAAA,GACJ,KAAM,IAAA,GACN,MAAO,IAAA,GACP,OAAQ,EAAS,IAAwE,CACvF,IAAM,EAAc,EAAK,MAAM,EAAS,EAAM,CA4D9C,OA1DI,EAAY,OAAS,UAChB,CACL,KAAM,WACL,GAAW,CACV,OAAU,IAAA,GACV,OAAU,IAAA,GACV,OAAU,IAAA,GACX,CACD,OAAQ,OAAO,gBAIb,CACA,IAAM,EAAU,EAAY,OAAO,gBAAgB,CAC/C,EAAa,MAAM,EAAQ,MAAM,CACrC,KAAO,EAAW,OAAS,IAAM,CAC/B,IAAM,EAAQ,MAAM,EAAW,MAE/B,EAAa,MAAM,EAAQ,KAAK,EAAM,CAExC,IAAM,EAAU,EAAW,MAErB,EAAe,EAAM,MAAM,EAAS,EAAM,CAChD,GAAI,EAAa,OAAS,UAAW,CACnC,IAAME,EAAW,EAAa,OAAO,gBAAgB,CACjDC,EAAc,MAAMD,EAAS,MAAM,CACvC,KAAOC,EAAY,OAAS,IAAM,CAChC,IAAM,EAAUA,EAAY,MACtB,EAAU,EAAe,EAAS,EAAQ,CAChD,GAAI,IAAY,IAAA,GAAW,CAEzB,EAAc,MAAMD,EAAS,KAAK,EAAQ,CAC1C,SAEF,IAAM,EAAQ,MAAM,EAEpB,EAAc,MAAMA,EAAS,KAAK,EAAM,CAE1C,OAAOE,EAAc,EAASD,EAAY,MAAM,CAGlD,IAAM,EAAW,EAAa,OAAO,WAAW,CAC5C,EAAc,EAAS,MAAM,CACjC,KAAO,EAAY,OAAS,IAAM,CAChC,IAAM,EAAU,EAAY,MACtB,EAAU,EAAe,EAAS,EAAQ,CAChD,GAAI,IAAY,IAAA,GAAW,CACzB,EAAc,EAAS,KAAK,EAAQ,CACpC,SAEF,IAAM,EAAQ,MAAM,EACpB,EAAc,EAAS,KAAK,EAAM,CAEpC,OAAOC,EAAc,EAAS,EAAY,MAAM,EAEnD,CAGI,CACL,KAAM,UACL,GAAW,CACV,OAAU,IAAA,GACV,OAAU,IAAA,GACV,OAAU,IAAA,GACX,CACD,EAAE,OAAO,WAA2F,CAClG,IAAM,EAAU,EAAY,OAAO,WAAW,CAC1C,EAAa,EAAQ,MAAM,CAC/B,KAAO,EAAW,OAAS,IAAM,CAC/B,IAAM,EAAQ,MAAM,EAAW,MAC/B,EAAa,EAAQ,KAAK,EAAM,CAElC,IAAM,EAAU,EAAW,MAErB,EAAe,EAAM,MAAM,EAAS,EAAM,CAChD,GAAI,EAAa,OAAS,SAAU,CAClC,IAAM,EAAU,EAAa,OAAO,WAAW,CAC3C,EAAc,EAAQ,MAAM,CAChC,KAAO,EAAY,OAAS,IAAM,CAChC,IAAM,EAAU,EAAY,MACtB,EAAU,EAAe,EAAS,EAAQ,CAChD,GAAI,IAAY,IAAA,GAAW,CACzB,EAAc,EAAQ,KAAK,EAAQ,CACnC,SAEF,IAAM,EAAQ,MAAM,EACpB,EAAc,EAAQ,KAAK,EAAM,CAEnC,OAAOA,EAAc,EAAS,EAAY,MAAM,CAElD,MAAU,MAAM,yCAAyC,EAE5D,EAEJ,EA6BH,SAAS,EACP,GAAG,EACwD,CAC3D,MAAO,CACL,KAAM,QACN,MAAO,IAAA,GACP,GAAI,IAAA,GACJ,KAAM,IAAA,GACN,MAAO,IAAA,GACP,OAAQ,EAAS,IACE,EAAO,KAAM,GAAM,EAAE,MAAM,EAAS,EAAM,CAAC,OAAS,UAAU,CAGtE,CACL,KAAM,WACL,GAAW,CACV,OAAU,IAAA,GACV,OAAU,IAAA,GACV,OAAU,IAAA,GACX,CACD,OAAQ,OAAO,gBAIb,CACA,IAAI,EAAMC,GAAe,CACzB,IAAK,IAAM,KAAS,EAAQ,CAC1B,IAAM,EAAU,EAAM,MAAM,EAAS,EAAM,CAC3C,GAAI,EAAQ,OAAS,UAAW,CAC9B,IAAM,EAAM,EAAQ,OAAO,gBAAgB,CAEvC,EAAS,MAAM,EAAI,MAAM,CAC7B,KAAO,EAAO,OAAS,IAAM,CAC3B,IAAM,EAAU,EAAO,MACjB,EAAU,EAAe,EAAK,EAAQ,CAC5C,GAAI,IAAY,IAAA,GAAW,CAEzB,EAAS,MAAM,EAAI,KAAK,EAAQ,CAChC,SAEF,IAAM,EAAQ,MAAM,EAEpB,EAAS,MAAM,EAAI,KAAK,EAAM,CAEhC,EAAMD,EAAc,EAAK,EAAO,MAAM,KACjC,CACL,IAAM,EAAM,EAAQ,OAAO,WAAW,CAClC,EAAS,EAAI,MAAM,CACvB,KAAO,EAAO,OAAS,IAAM,CAC3B,IAAM,EAAU,EAAO,MACjB,EAAU,EAAe,EAAK,EAAQ,CAC5C,GAAI,IAAY,IAAA,GAAW,CACzB,EAAS,EAAI,KAAK,EAAQ,CAC1B,SAEF,IAAM,EAAQ,MAAM,EACpB,EAAS,EAAI,KAAK,EAAM,CAE1B,EAAMA,EAAc,EAAK,EAAO,MAAM,EAG1C,OAAO,GAEV,CAGI,CACL,KAAM,UACL,GAAW,CACV,OAAU,IAAA,GACV,OAAU,IAAA,GACV,OAAU,IAAA,GACX,CACD,EAAE,OAAO,WAAsG,CAC7G,IAAI,EAAMC,GAAe,CACzB,IAAK,IAAM,KAAS,EAAQ,CAC1B,IAAM,EAAU,EAAM,MAAM,EAAS,EAAM,CAC3C,GAAI,EAAQ,OAAS,SACnB,MAAU,MAAM,sCAAsC,CAExD,IAAM,EAAM,EAAQ,OAAO,WAAW,CAClC,EAAS,EAAI,MAAM,CACvB,KAAO,EAAO,OAAS,IAAM,CAC3B,IAAM,EAAU,EAAO,MACjB,EAAU,EAAe,EAAK,EAAQ,CAC5C,GAAI,IAAY,IAAA,GAAW,CACzB,EAAS,EAAI,KAAK,EAAQ,CAC1B,SAEF,IAAM,EAAQ,MAAM,EACpB,EAAS,EAAI,KAAK,EAAM,CAE1B,EAAMD,EAAc,EAAK,EAAO,MAAM,CAExC,OAAO,GAEV,CAEJ,CAkBH,MAAa,EAAK,EAgBL,EAAM,EAoBN,EAAK,EA6BL,EAAS,EAwBT,EAAU,EAwBV,EAAQ"}
|
|
1
|
+
{"version":3,"file":"layer-C5A-EM0h.mjs","names":["Context.make","fx","layerGen","layerResult","Context.merge","Context.empty"],"sources":["../src/layer/layer.ts"],"sourcesContent":["/**\n * Layer construction and composition for service dependency graphs.\n *\n * **Mental model**\n * - A `Layer` builds one or more services, potentially requiring other services.\n * - Compose layers and provide dependencies before running `Fx`.\n *\n * **Common tasks**\n * - Build from values with `Layer.ok`.\n * - Build from effects with `Layer.fx` or `Layer.scoped`.\n * - Compose with `Layer.provide` and `Layer.merge`.\n *\n * **Gotchas**\n * - Async layers force async execution paths.\n * - Scoped layers require scope finalization.\n *\n * **Quickstart**\n *\n * @example\n * ```ts\n * import { Fx, Layer, Provide, Service } from \"@nicolastoulemont/std\"\n *\n * const Port = Service.tag<number>(\"Port\")\n * const program = Fx.gen(function* () {\n * return yield* Port\n * })\n * const exit = Fx.run(Provide.layer(Layer.ok(Port, 3000))(program))\n * // => { _tag: \"Ok\", value: 3000 }\n * ```\n *\n * @module\n */\nimport * as Context from \"../context/context\"\nimport type { Context as ContextType } from \"../context/context\"\nimport { FxTypeId } from \"../fx/fx.types\"\nimport type { RunnableFx, SyncFx, AsyncFx, FxYield } from \"../fx/fx.types\"\nimport type { ScopeService, ExcludeScope } from \"../scope/scope\"\nimport type { ServiceClass } from \"../service/service\"\nimport { asServiceRequest, resolveService } from \"../service/service-resolution\"\nimport type { Layer as LayerType, MergeROut, MergeError, UnprovidedDeps, AllSync } from \"./layer.types\"\n\n/* oxlint-disable no-unsafe-type-assertion -- Layer composition carries erased generic channels and phantom type slots that require assertion-based reconstruction. */\n\n/**\n * Create a layer from a synchronous value (no dependencies).\n */\nconst layerOk = <S>(service: ServiceClass<S>, impl: S): LayerType<S, never, never, true> => ({\n _tag: \"Layer\",\n _ROut: undefined as unknown as S,\n _E: undefined as never,\n _RIn: undefined as never,\n _Sync: undefined as unknown as true,\n build: (): SyncFx<ContextType<S>> => ({\n _tag: \"SyncFx\",\n [FxTypeId]: {\n _A: () => undefined as unknown as ContextType<S>,\n _E: () => undefined as never,\n _R: () => undefined as never,\n },\n // oxlint-disable-next-line require-yield\n *[Symbol.iterator](): Generator<never, ContextType<S>, unknown> {\n return Context.make(service, impl)\n },\n }),\n})\n\n/**\n * Create a layer that always fails with an error.\n */\nconst layerErr = <E>(error: E): LayerType<never, E, never, true> => ({\n _tag: \"Layer\",\n _ROut: undefined as never,\n _E: undefined as unknown as E,\n _RIn: undefined as never,\n _Sync: undefined as unknown as true,\n build: (): SyncFx<ContextType, E> => ({\n _tag: \"SyncFx\",\n [FxTypeId]: {\n _A: () => undefined as never,\n _E: () => error,\n _R: () => undefined as never,\n },\n *[Symbol.iterator](): Generator<E, never, unknown> {\n yield error\n throw new Error(\"Unreachable\")\n },\n }),\n})\n\n/**\n * Create a layer from an Fx computation (can have dependencies).\n * The Sync type parameter is inferred from the input fx:\n * - SyncFx input → Layer with Sync=true\n * - AsyncFx input → Layer with Sync=false\n *\n * @example\n * ```ts\n * import { Fx, Layer, Provide, Service } from \"@nicolastoulemont/std\"\n *\n * const Port = Service.tag<number>(\"Port\")\n * const portLayer = Layer.fx(Port)(Fx.gen(function* () {\n * return 3000\n * }))\n * const program = Fx.gen(function* () {\n * return yield* Port\n * })\n * const exit = Fx.run(Provide.layer(portLayer)(program))\n * // => { _tag: \"Ok\", value: 3000 }\n * ```\n */\nfunction layerFx<S>(service: ServiceClass<S>): {\n <E, R>(fx: SyncFx<S, E, R>): LayerType<S, E, R, true>\n <E, R>(fx: AsyncFx<S, E, R>): LayerType<S, E, R, false>\n <E, R>(fx: RunnableFx<S, E, R>): LayerType<S, E, R>\n}\nfunction layerFx<S>(service: ServiceClass<S>) {\n return <E, R>(fx: RunnableFx<S, E, R>): LayerType<S, E, R> => ({\n _tag: \"Layer\",\n _ROut: undefined as unknown as S,\n _E: undefined as unknown as E,\n _RIn: undefined as unknown as R,\n _Sync: undefined as unknown as boolean,\n build: (): RunnableFx<ContextType<S>, E, R> => {\n if (fx._tag === \"AsyncFx\") {\n return {\n _tag: \"AsyncFx\",\n [FxTypeId]: {\n _A: () => undefined as unknown as ContextType<S>,\n _E: () => undefined as unknown as E,\n _R: () => undefined as unknown as R,\n },\n async *[Symbol.asyncIterator](): AsyncGenerator<FxYield<E, R>, ContextType<S>, unknown> {\n const gen = fx[Symbol.asyncIterator]()\n let result = await gen.next()\n while (result.done !== true) {\n const value = yield result.value\n // oxlint-disable-next-line no-await-in-loop\n result = await gen.next(value)\n }\n return Context.make(service, result.value)\n },\n } as AsyncFx<ContextType<S>, E, R>\n }\n\n return {\n _tag: \"SyncFx\",\n [FxTypeId]: {\n _A: () => undefined as unknown as ContextType<S>,\n _E: () => undefined as unknown as E,\n _R: () => undefined as unknown as R,\n },\n *[Symbol.iterator](): Generator<FxYield<E, R>, ContextType<S>, unknown> {\n const gen = fx[Symbol.iterator]()\n let result = gen.next()\n while (result.done !== true) {\n const value = yield result.value\n result = gen.next(value)\n }\n return Context.make(service, result.value)\n },\n } as SyncFx<ContextType<S>, E, R>\n },\n })\n}\n\n/**\n * Create a scoped layer (with resource cleanup).\n * The Sync type parameter is inferred from the input fx.\n *\n * @example\n * ```ts\n * import { Fx, Layer, Provide, Scope, Service } from \"@nicolastoulemont/std\"\n *\n * const Resource = Service.tag<{ readonly id: number }>(\"Resource\")\n * const ScopeTag = Service.tag<Scope.ScopeService>(\"@std/Scope\")\n * let finalized = 0\n *\n * const resourceLayer = Layer.scoped(Resource)(Fx.gen(function* () {\n * const scope = yield* ScopeTag\n * yield* scope.addFinalizer(() =>\n * Fx.gen(function* () {\n * finalized += 1\n * }),\n * )\n * return { id: 1 }\n * }))\n * const program = Fx.gen(function* () {\n * return (yield* Resource).id\n * })\n * const exit = Fx.run(Provide.layer(resourceLayer)(program))\n * // => { _tag: \"Ok\", value: 1 }\n * ```\n */\nfunction layerScoped<S>(service: ServiceClass<S>): {\n <E, R>(fx: SyncFx<S, E, R | ScopeService>): LayerType<S, E, ExcludeScope<R>, true>\n <E, R>(fx: AsyncFx<S, E, R | ScopeService>): LayerType<S, E, ExcludeScope<R>, false>\n <E, R>(fx: RunnableFx<S, E, R | ScopeService>): LayerType<S, E, ExcludeScope<R>>\n}\nfunction layerScoped<S>(service: ServiceClass<S>) {\n return <E, R>(fx: RunnableFx<S, E, R | ScopeService>): LayerType<S, E, ExcludeScope<R>> => ({\n _tag: \"Layer\",\n _ROut: undefined as unknown as S,\n _E: undefined as unknown as E,\n _RIn: undefined as unknown as ExcludeScope<R>,\n _Sync: undefined as unknown as boolean,\n build: (_memoMap, scope): RunnableFx<ContextType<S>, E, ExcludeScope<R>> => {\n if (fx._tag === \"AsyncFx\") {\n return {\n _tag: \"AsyncFx\",\n [FxTypeId]: {\n _A: () => undefined as unknown as ContextType<S>,\n _E: () => undefined as unknown as E,\n _R: () => undefined as unknown as ExcludeScope<R>,\n },\n async *[Symbol.asyncIterator](): AsyncGenerator<FxYield<E, ExcludeScope<R>>, ContextType<S>, unknown> {\n const gen = fx[Symbol.asyncIterator]()\n let result = await gen.next()\n while (result.done !== true) {\n const yielded = result.value\n const serviceRequest = asServiceRequest(yielded)\n if (serviceRequest?.key === \"@std/Scope\") {\n // oxlint-disable-next-line no-await-in-loop\n result = await gen.next(scope)\n } else {\n const value = yield yielded as FxYield<E, ExcludeScope<R>>\n // oxlint-disable-next-line no-await-in-loop\n result = await gen.next(value)\n }\n }\n return Context.make(service, result.value)\n },\n } as AsyncFx<ContextType<S>, E, ExcludeScope<R>>\n }\n\n return {\n _tag: \"SyncFx\",\n [FxTypeId]: {\n _A: () => undefined as unknown as ContextType<S>,\n _E: () => undefined as unknown as E,\n _R: () => undefined as unknown as ExcludeScope<R>,\n },\n *[Symbol.iterator](): Generator<FxYield<E, ExcludeScope<R>>, ContextType<S>, unknown> {\n const gen = fx[Symbol.iterator]()\n let result = gen.next()\n while (result.done !== true) {\n const yielded = result.value\n const serviceRequest = asServiceRequest(yielded)\n if (serviceRequest?.key === \"@std/Scope\") {\n result = gen.next(scope)\n } else {\n const value = yield yielded as FxYield<E, ExcludeScope<R>>\n result = gen.next(value)\n }\n }\n return Context.make(service, result.value)\n },\n } as SyncFx<ContextType<S>, E, ExcludeScope<R>>\n },\n })\n}\n\n// ============================================================================\n// Layer Composition\n// ============================================================================\n\n/**\n * Provide dependencies to a layer and merge outputs.\n * Sync is preserved only if both the deps layer and the consuming layer are sync.\n *\n * @example\n * ```ts\n * import { Fx, Layer, Provide, Service } from \"@nicolastoulemont/std\"\n *\n * const Port = Service.tag<number>(\"Port\")\n * const Server = Service.tag<{ readonly port: number }>(\"Server\")\n * const portLayer = Layer.ok(Port, 3000)\n * const serverLayer = Layer.fx(Server)(Fx.gen(function* () {\n * const port = yield* Port\n * return { port }\n * }))\n * const provided = Layer.provide(portLayer)(serverLayer)\n * const program = Fx.gen(function* () {\n * return (yield* Server).port\n * })\n * const exit = Fx.run(Provide.layer(provided)(program))\n * // => { _tag: \"Ok\", value: 3000 }\n * ```\n */\nfunction layerProvide<DepsROut, DepsE, DepsRIn, DepsSync extends boolean>(\n deps: LayerType<DepsROut, DepsE, DepsRIn, DepsSync>,\n): {\n <ROut, E, RIn extends DepsROut, LayerSync extends boolean>(\n layer: LayerType<ROut, E, RIn, LayerSync>,\n ): LayerType<ROut | DepsROut, E | DepsE, DepsRIn, LayerSync extends true ? DepsSync : false>\n}\nfunction layerProvide<DepsROut, DepsE, DepsRIn>(deps: LayerType<DepsROut, DepsE, DepsRIn>) {\n return <ROut, E, RIn extends DepsROut>(\n layer: LayerType<ROut, E, RIn>,\n ): LayerType<ROut | DepsROut, E | DepsE, DepsRIn> => ({\n _tag: \"Layer\",\n _ROut: undefined as unknown as ROut | DepsROut,\n _E: undefined as unknown as E | DepsE,\n _RIn: undefined as unknown as DepsRIn,\n _Sync: undefined as unknown as boolean,\n build: (memoMap, scope): RunnableFx<ContextType<ROut | DepsROut>, E | DepsE, DepsRIn> => {\n const depsBuildFx = deps.build(memoMap, scope)\n\n if (depsBuildFx._tag === \"AsyncFx\") {\n return {\n _tag: \"AsyncFx\",\n [FxTypeId]: {\n _A: () => undefined as unknown as ContextType<ROut | DepsROut>,\n _E: () => undefined as unknown as E | DepsE,\n _R: () => undefined as unknown as DepsRIn,\n },\n async *[Symbol.asyncIterator](): AsyncGenerator<\n FxYield<E | DepsE, DepsRIn>,\n ContextType<ROut | DepsROut>,\n unknown\n > {\n const depsGen = depsBuildFx[Symbol.asyncIterator]()\n let depsResult = await depsGen.next()\n while (depsResult.done !== true) {\n const value = yield depsResult.value\n // oxlint-disable-next-line no-await-in-loop\n depsResult = await depsGen.next(value)\n }\n const depsCtx = depsResult.value\n\n const layerBuildFx = layer.build(memoMap, scope)\n if (layerBuildFx._tag === \"AsyncFx\") {\n const layerGen = layerBuildFx[Symbol.asyncIterator]()\n let layerResult = await layerGen.next()\n while (layerResult.done !== true) {\n const yielded = layerResult.value\n const service = resolveService(depsCtx, yielded)\n if (service !== undefined) {\n // oxlint-disable-next-line no-await-in-loop\n layerResult = await layerGen.next(service)\n continue\n }\n const value = yield yielded as FxYield<E, DepsRIn>\n // oxlint-disable-next-line no-await-in-loop\n layerResult = await layerGen.next(value)\n }\n return Context.merge(depsCtx, layerResult.value)\n }\n\n const layerGen = layerBuildFx[Symbol.iterator]()\n let layerResult = layerGen.next()\n while (layerResult.done !== true) {\n const yielded = layerResult.value\n const service = resolveService(depsCtx, yielded)\n if (service !== undefined) {\n layerResult = layerGen.next(service)\n continue\n }\n const value = yield yielded as FxYield<E, DepsRIn>\n layerResult = layerGen.next(value)\n }\n return Context.merge(depsCtx, layerResult.value)\n },\n } as AsyncFx<ContextType<ROut | DepsROut>, E | DepsE, DepsRIn>\n }\n\n return {\n _tag: \"SyncFx\",\n [FxTypeId]: {\n _A: () => undefined as unknown as ContextType<ROut | DepsROut>,\n _E: () => undefined as unknown as E | DepsE,\n _R: () => undefined as unknown as DepsRIn,\n },\n *[Symbol.iterator](): Generator<FxYield<E | DepsE, DepsRIn>, ContextType<ROut | DepsROut>, unknown> {\n const depsGen = depsBuildFx[Symbol.iterator]()\n let depsResult = depsGen.next()\n while (depsResult.done !== true) {\n const value = yield depsResult.value\n depsResult = depsGen.next(value)\n }\n const depsCtx = depsResult.value\n\n const layerBuildFx = layer.build(memoMap, scope)\n if (layerBuildFx._tag === \"SyncFx\") {\n const syncGen = layerBuildFx[Symbol.iterator]()\n let layerResult = syncGen.next()\n while (layerResult.done !== true) {\n const yielded = layerResult.value\n const service = resolveService(depsCtx, yielded)\n if (service !== undefined) {\n layerResult = syncGen.next(service)\n continue\n }\n const value = yield yielded as FxYield<E, DepsRIn>\n layerResult = syncGen.next(value)\n }\n return Context.merge(depsCtx, layerResult.value)\n }\n throw new Error(\"Cannot use async layer in sync context\")\n },\n } as SyncFx<ContextType<ROut | DepsROut>, E | DepsE, DepsRIn>\n },\n })\n}\n\n/**\n * Merge multiple layers with automatic dependency resolution.\n * The merged layer is sync only if ALL input layers are sync.\n *\n * @example\n * ```ts\n * import { Fx, Layer, Provide, Service } from \"@nicolastoulemont/std\"\n *\n * const Logger = Service.tag<{ readonly prefix: string }>(\"Logger\")\n * const Clock = Service.tag<{ readonly now: () => number }>(\"Clock\")\n * const merged = Layer.merge(\n * Layer.ok(Logger, { prefix: \"dev\" }),\n * Layer.ok(Clock, { now: () => 123 }),\n * )\n * const program = Fx.gen(function* () {\n * const logger = yield* Logger\n * const clock = yield* Clock\n * return `${logger.prefix}:${clock.now()}`\n * })\n * const exit = Fx.run(Provide.layer(merged)(program))\n * // => { _tag: \"Ok\", value: \"dev:123\" }\n * ```\n */\nfunction layerMerge<L extends LayerType<unknown, unknown, unknown>[]>(\n ...layers: L\n): LayerType<MergeROut<L>, MergeError<L>, UnprovidedDeps<L>, AllSync<L>>\nfunction layerMerge<L extends LayerType<unknown, unknown, unknown>[]>(\n ...layers: L\n): LayerType<MergeROut<L>, MergeError<L>, UnprovidedDeps<L>> {\n return {\n _tag: \"Layer\",\n _ROut: undefined as unknown as MergeROut<L>,\n _E: undefined as unknown as MergeError<L>,\n _RIn: undefined as unknown as UnprovidedDeps<L>,\n _Sync: undefined as unknown as boolean,\n build: (memoMap, scope): RunnableFx<ContextType<MergeROut<L>>, MergeError<L>, UnprovidedDeps<L>> => {\n const hasAsync = layers.some((l) => l.build(memoMap, scope)._tag === \"AsyncFx\")\n\n if (hasAsync) {\n return {\n _tag: \"AsyncFx\",\n [FxTypeId]: {\n _A: () => undefined as unknown as ContextType<MergeROut<L>>,\n _E: () => undefined as unknown as MergeError<L>,\n _R: () => undefined as unknown as UnprovidedDeps<L>,\n },\n async *[Symbol.asyncIterator](): AsyncGenerator<\n FxYield<MergeError<L>, UnprovidedDeps<L>>,\n ContextType<MergeROut<L>>,\n unknown\n > {\n let ctx = Context.empty() as ContextType<unknown>\n for (const layer of layers) {\n const buildFx = layer.build(memoMap, scope)\n if (buildFx._tag === \"AsyncFx\") {\n const gen = buildFx[Symbol.asyncIterator]()\n // oxlint-disable-next-line no-await-in-loop\n let result = await gen.next()\n while (result.done !== true) {\n const yielded = result.value\n const service = resolveService(ctx, yielded)\n if (service !== undefined) {\n // oxlint-disable-next-line no-await-in-loop\n result = await gen.next(service)\n continue\n }\n const value = yield yielded as FxYield<MergeError<L>, UnprovidedDeps<L>>\n // oxlint-disable-next-line no-await-in-loop\n result = await gen.next(value)\n }\n ctx = Context.merge(ctx, result.value)\n } else {\n const gen = buildFx[Symbol.iterator]()\n let result = gen.next()\n while (result.done !== true) {\n const yielded = result.value\n const service = resolveService(ctx, yielded)\n if (service !== undefined) {\n result = gen.next(service)\n continue\n }\n const value = yield yielded as FxYield<MergeError<L>, UnprovidedDeps<L>>\n result = gen.next(value)\n }\n ctx = Context.merge(ctx, result.value)\n }\n }\n return ctx as ContextType<MergeROut<L>>\n },\n } as AsyncFx<ContextType<MergeROut<L>>, MergeError<L>, UnprovidedDeps<L>>\n }\n\n return {\n _tag: \"SyncFx\",\n [FxTypeId]: {\n _A: () => undefined as unknown as ContextType<MergeROut<L>>,\n _E: () => undefined as unknown as MergeError<L>,\n _R: () => undefined as unknown as UnprovidedDeps<L>,\n },\n *[Symbol.iterator](): Generator<FxYield<MergeError<L>, UnprovidedDeps<L>>, ContextType<MergeROut<L>>, unknown> {\n let ctx = Context.empty() as ContextType<unknown>\n for (const layer of layers) {\n const buildFx = layer.build(memoMap, scope)\n if (buildFx._tag !== \"SyncFx\") {\n throw new Error(\"Expected sync layer in sync context\")\n }\n const gen = buildFx[Symbol.iterator]()\n let result = gen.next()\n while (result.done !== true) {\n const yielded = result.value\n const service = resolveService(ctx, yielded)\n if (service !== undefined) {\n result = gen.next(service)\n continue\n }\n const value = yield yielded as FxYield<MergeError<L>, UnprovidedDeps<L>>\n result = gen.next(value)\n }\n ctx = Context.merge(ctx, result.value)\n }\n return ctx as ContextType<MergeROut<L>>\n },\n } as SyncFx<ContextType<MergeROut<L>>, MergeError<L>, UnprovidedDeps<L>>\n },\n }\n}\n\n/**\n * Create a successful no-dependency layer from a plain service value.\n *\n * @example\n * ```ts\n * import { Fx, Layer, Provide, Service } from \"@nicolastoulemont/std\"\n *\n * const Port = Service.tag<number>(\"Port\")\n * const program = Fx.gen(function* () {\n * return yield* Port\n * })\n * const exit = Fx.run(Provide.layer(Layer.ok(Port, 3000))(program))\n * // => { _tag: \"Ok\", value: 3000 }\n * ```\n */\nexport const ok = layerOk\n\n/**\n * Create a layer that always fails with an error.\n *\n * @example\n * ```ts\n * import { Fx, Layer, Provide } from \"@nicolastoulemont/std\"\n *\n * const program = Fx.gen(function* () {\n * return 1\n * })\n * const exit = Fx.run(Provide.layer(Layer.err(\"missing-config\"))(program))\n * // => { _tag: \"Err\", error: \"missing-config\" }\n * ```\n */\nexport const err = layerErr\n\n/**\n * Create a layer from an effectful service builder.\n *\n * @example\n * ```ts\n * import { Fx, Layer, Provide, Service } from \"@nicolastoulemont/std\"\n *\n * const Port = Service.tag<number>(\"Port\")\n * const portLayer = Layer.fx(Port)(Fx.gen(function* () {\n * return 3000\n * }))\n * const program = Fx.gen(function* () {\n * return yield* Port\n * })\n * const exit = Fx.run(Provide.layer(portLayer)(program))\n * // => { _tag: \"Ok\", value: 3000 }\n * ```\n */\nexport const fx = layerFx\n\n/**\n * Create a scoped layer that registers resource finalizers.\n *\n * @example\n * ```ts\n * import { Fx, Layer, Provide, Scope, Service } from \"@nicolastoulemont/std\"\n *\n * const Resource = Service.tag<{ readonly id: number }>(\"Resource\")\n * const ScopeTag = Service.tag<Scope.ScopeService>(\"@std/Scope\")\n * let finalized = 0\n *\n * const resourceLayer = Layer.scoped(Resource)(Fx.gen(function* () {\n * const scope = yield* ScopeTag\n * yield* scope.addFinalizer(() =>\n * Fx.gen(function* () {\n * finalized += 1\n * }),\n * )\n * return { id: 1 }\n * }))\n * const program = Fx.gen(function* () {\n * return (yield* Resource).id\n * })\n * const exit = Fx.run(Provide.layer(resourceLayer)(program))\n * // => { _tag: \"Ok\", value: 1 }\n * ```\n */\nexport const scoped = layerScoped\n\n/**\n * Provide one layer to another, satisfying dependencies.\n *\n * @example\n * ```ts\n * import { Fx, Layer, Provide, Service } from \"@nicolastoulemont/std\"\n *\n * const Port = Service.tag<number>(\"Port\")\n * const Server = Service.tag<{ readonly port: number }>(\"Server\")\n * const portLayer = Layer.ok(Port, 3000)\n * const serverLayer = Layer.fx(Server)(Fx.gen(function* () {\n * const port = yield* Port\n * return { port }\n * }))\n * const provided = Layer.provide(portLayer)(serverLayer)\n * const program = Fx.gen(function* () {\n * return (yield* Server).port\n * })\n * const exit = Fx.run(Provide.layer(provided)(program))\n * // => { _tag: \"Ok\", value: 3000 }\n * ```\n */\nexport const provide = layerProvide\n\n/**\n * Merge multiple layers into a single composite layer.\n *\n * @example\n * ```ts\n * import { Fx, Layer, Provide, Service } from \"@nicolastoulemont/std\"\n *\n * const Logger = Service.tag<{ readonly prefix: string }>(\"Logger\")\n * const Clock = Service.tag<{ readonly now: () => number }>(\"Clock\")\n * const merged = Layer.merge(\n * Layer.ok(Logger, { prefix: \"dev\" }),\n * Layer.ok(Clock, { now: () => 123 }),\n * )\n * const program = Fx.gen(function* () {\n * const logger = yield* Logger\n * const clock = yield* Clock\n * return `${logger.prefix}:${clock.now()}`\n * })\n * const exit = Fx.run(Provide.layer(merged)(program))\n * // => { _tag: \"Ok\", value: \"dev:123\" }\n * ```\n */\nexport const merge = layerMerge\n\n/* oxlint-enable no-unsafe-type-assertion */\n"],"mappings":"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"}
|
package/dist/provide/index.d.mts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { t as provide_d_exports } from "../index-
|
|
1
|
+
import { t as provide_d_exports } from "../index-D8gcYvR9.mjs";
|
|
2
2
|
export { provide_d_exports as Provide };
|
package/dist/provide/index.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{t as e}from"../provide
|
|
1
|
+
import{t as e}from"../provide-CuccogWx.mjs";export{e as Provide};
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{t as e}from"./chunk-oQKkju2G.mjs";import{t}from"./fx.types-DyQVgTS8.mjs";import{i as n}from"./result-D3VY0qBG.mjs";import{n as r,t as i}from"./service-resolution-BefYr4nR.mjs";import{n as a,t as o}from"./fx.runtime-jQxh77s3.mjs";import{n as s}from"./layer-C5A-EM0h.mjs";import{t as c}from"./scope-gVt4PESc.mjs";var l=class{cache=new Map;getOrBuild(e,r,a){let o=this.cache.get(e);if(o?.context)return{_tag:`SyncFx`,[t]:{_A:()=>o.context,_E:()=>void 0,_R:()=>void 0},run:()=>n(o.context),*[Symbol.iterator](){return o.context}};if(o?.promise)return{_tag:`AsyncFx`,[t]:{_A:()=>void 0,_E:()=>void 0,_R:()=>void 0},run:async()=>n(await o.promise),async*[Symbol.asyncIterator](){return await o.promise}};this.cache.set(e,{building:!0});let s=e.build(this,r),c=this.cache;if(s._tag===`AsyncFx`){let r=(async()=>{let t=s[Symbol.asyncIterator](),n=await t.next();for(;n.done!==!0;){let e=n.value,r=i(e);if(r===void 0)throw e;let o=a._services.get(r.key);if(o===void 0)throw Error(`Service "${r.key}" not found during layer build`);n=await t.next(o)}let r=n.value;return c.set(e,{context:r}),r})();return this.cache.set(e,{promise:r}),{_tag:`AsyncFx`,[t]:{_A:()=>void 0,_E:()=>void 0,_R:()=>void 0},run:async()=>{try{return n(await r)}catch(e){return{ok:!1,error:e,*[Symbol.iterator](){throw yield e,Error(`Unreachable`)}}}},async*[Symbol.asyncIterator](){try{return await r}catch(e){throw yield e,Error(`Unreachable`,{cause:e})}}}}return{_tag:`SyncFx`,[t]:{_A:()=>void 0,_E:()=>void 0,_R:()=>void 0},run:()=>{let t=s[Symbol.iterator](),r=t.next();for(;r.done!==!0;){let e=r.value,n=i(e);if(n===void 0)return{ok:!1,error:e,*[Symbol.iterator](){throw yield e,Error(`Unreachable`)}};let o=a._services.get(n.key);if(o===void 0)throw Error(`Service "${n.key}" not found during layer build`);r=t.next(o)}let o=r.value;return c.set(e,{context:o}),n(o)},*[Symbol.iterator](){let t=s[Symbol.iterator](),n=t.next();for(;n.done!==!0;){let e=n.value,r=i(e);if(r===void 0)throw yield e,Error(`Unreachable`);let o=a._services.get(r.key);if(o===void 0)throw Error(`Service "${r.key}" not found during layer build`);n=t.next(o)}return c.set(e,{context:n.value}),n.value}}}clear(){this.cache.clear()}get size(){return this.cache.size}},u=e({context:()=>p,layer:()=>d,layers:()=>f,service:()=>m});function d(e){return i=>{let s=e.build(new l,c())._tag,u=()=>{let t=new l,n=c();return{scope:n,layerBuildFx:e.build(t,n)}};return s===`AsyncFx`||i._tag===`AsyncFx`?{_tag:`AsyncFx`,[t]:{_A:()=>void 0,_E:()=>void 0,_R:()=>void 0},async*[Symbol.asyncIterator](){let{scope:e,layerBuildFx:t}=u();try{let e;if(t._tag===`AsyncFx`){let n=t[Symbol.asyncIterator](),r=await n.next();for(;r.done!==!0;)yield r.value,r=await n.next(void 0);e=r.value}else{let n=t[Symbol.iterator](),r=n.next();for(;r.done!==!0;)yield r.value,r=n.next(void 0);e=r.value}if(i._tag===`AsyncFx`){let t=i[Symbol.asyncIterator](),n=await t.next();for(;n.done!==!0;){let i=n.value,a=r(e,i);if(a!==void 0){n=await t.next(a);continue}let o=yield i;n=await t.next(o)}return n.value}let n=i[Symbol.iterator](),a=n.next();for(;a.done!==!0;){let t=a.value,i=r(e,t);if(i!==void 0){a=n.next(i);continue}let o=yield t;a=n.next(o)}return a.value}finally{let t=e.close(n(void 0));t._tag===`AsyncFx`?await o(t):a(t)}}}:{_tag:`SyncFx`,[t]:{_A:()=>void 0,_E:()=>void 0,_R:()=>void 0},*[Symbol.iterator](){let{scope:e,layerBuildFx:t}=u();if(t._tag===`AsyncFx`)throw Error(`Provide.layer sync execution encountered an async layer build. Ensure async layers are treated as async at composition time.`);try{let e=t[Symbol.iterator](),n=e.next();for(;n.done!==!0;)yield n.value,n=e.next(void 0);let a=n.value,o=i[Symbol.iterator](),s=o.next();for(;s.done!==!0;){let e=s.value,t=r(a,e);if(t!==void 0){s=o.next(t);continue}let n=yield e;s=o.next(n)}return s.value}finally{a(e.close(n(void 0)))}}}}}function f(...e){return d(s(...e))}const p=e=>n=>n._tag===`AsyncFx`?{_tag:`AsyncFx`,[t]:{_A:()=>void 0,_E:()=>void 0,_R:()=>void 0},async*[Symbol.asyncIterator](){let t=n[Symbol.asyncIterator](),r=await t.next();for(;r.done!==!0;){let n=r.value,a=i(n);if(a===void 0){yield n,r=await t.next(void 0);continue}let o=e._services.get(a.key);if(o===void 0)throw Error(`Service "${a.key}" not found`);r=await t.next(o)}return r.value}}:{_tag:`SyncFx`,[t]:{_A:()=>void 0,_E:()=>void 0,_R:()=>void 0},*[Symbol.iterator](){let t=n[Symbol.iterator](),r=t.next();for(;r.done!==!0;){let n=r.value,a=i(n);if(a===void 0){yield n,r=t.next(void 0);continue}let o=e._services.get(a.key);if(o===void 0)throw Error(`Service "${a.key}" not found`);r=t.next(o)}return r.value}},m=(e,n)=>r=>r._tag===`AsyncFx`?{_tag:`AsyncFx`,[t]:{_A:()=>void 0,_E:()=>void 0,_R:()=>void 0},async*[Symbol.asyncIterator](){let t=r[Symbol.asyncIterator](),a=await t.next();for(;a.done!==!0;){let r=a.value;if(i(r)?.key===e.key)a=await t.next(n);else{let e=yield r;a=await t.next(e)}}return a.value}}:{_tag:`SyncFx`,[t]:{_A:()=>void 0,_E:()=>void 0,_R:()=>void 0},*[Symbol.iterator](){let t=r[Symbol.iterator](),a=t.next();for(;a.done!==!0;){let r=a.value;if(i(r)?.key===e.key)a=t.next(n);else{let e=yield r;a=t.next(e)}}return a.value}};export{u as t};
|
|
2
|
+
//# sourceMappingURL=provide-CuccogWx.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"provide-CuccogWx.mjs","names":["layer","service","layer","makeScope","fxGen","fxResult","service","layers","mergeLayers"],"sources":["../src/provide/memo-map.ts","../src/provide/provide.ts"],"sourcesContent":["import type { Context } from \"../context/context\"\nimport { FxTypeId } from \"../fx/fx.types\"\nimport type { RunnableFx, SyncFx, AsyncFx, FxYield } from \"../fx/fx.types\"\nimport type { Layer } from \"../layer/layer.types\"\nimport { ok } from \"../result/result\"\nimport type { ScopeService } from \"../scope/scope\"\nimport { asServiceRequest } from \"../service/service-resolution\"\n\n/* oxlint-disable no-unsafe-type-assertion, only-throw-error -- MemoMap bridges erased generic Fx channels and re-emits typed domain errors from generator boundaries. */\n\n// ============================================================================\n// MemoMap\n// ============================================================================\n\ntype AnyLayer = Layer<unknown, unknown, unknown>\n\n/**\n * MemoMap caches built layers so each layer is only built once.\n * Multiple dependents share the same service instance.\n *\n * This implements the \"service singleton\" pattern where a service\n * is instantiated once and shared across all consumers.\n *\n * @example\n * ```ts\n * // Database is built once, shared by DocumentService and TeamService\n * const AppLayer = Layer.merge(\n * ConfigLive,\n * LoggerLive,\n * DatabaseLive, // Built once\n * DocumentServiceLive, // Uses shared Database\n * TeamServiceLive, // Uses same Database instance\n * )\n * ```\n */\nexport class MemoMap {\n private cache = new Map<\n AnyLayer,\n {\n promise?: Promise<Context<unknown>>\n context?: Context<unknown>\n building?: boolean\n }\n >()\n\n /**\n * Get a cached context or build the layer if not cached.\n *\n * @param layer - The layer to get or build\n * @param scope - The scope for resource management\n * @param deps - Context containing the layer's dependencies\n * @returns A RunnableFx producing the layer's context\n */\n getOrBuild<ROut, E, RIn>(\n layer: Layer<ROut, E, RIn>,\n scope: ScopeService,\n deps: Context<RIn>,\n ): RunnableFx<Context<ROut>, E> {\n const cached = this.cache.get(layer as AnyLayer)\n\n // Already built - return cached context\n if (cached?.context) {\n return {\n _tag: \"SyncFx\",\n [FxTypeId]: {\n _A: () => cached.context as Context<ROut>,\n _E: () => undefined as unknown as E,\n _R: () => undefined as never,\n },\n run: () => ok(cached.context as Context<ROut>),\n // oxlint-disable-next-line require-yield\n *[Symbol.iterator](): Generator<FxYield<E, never>, Context<ROut>, unknown> {\n return cached.context as Context<ROut>\n },\n } as SyncFx<Context<ROut>, E>\n }\n\n // Building in progress (async) - wait for it\n if (cached?.promise) {\n return {\n _tag: \"AsyncFx\",\n [FxTypeId]: {\n _A: () => undefined as unknown as Context<ROut>,\n _E: () => undefined as unknown as E,\n _R: () => undefined as never,\n },\n run: async () => {\n const ctx = await cached.promise!\n return ok(ctx as Context<ROut>)\n },\n // oxlint-disable-next-line require-yield\n async *[Symbol.asyncIterator](): AsyncGenerator<FxYield<E, never>, Context<ROut>, unknown> {\n const ctx = await cached.promise!\n return ctx as Context<ROut>\n },\n } as AsyncFx<Context<ROut>, E>\n }\n\n // Need to build - mark as building\n this.cache.set(layer as AnyLayer, { building: true })\n\n // Build the layer with provided dependencies\n const buildFx = layer.build(this, scope)\n const cacheRef = this.cache\n\n // Determine if async\n if (buildFx._tag === \"AsyncFx\") {\n // Create a promise for the build\n const buildPromise = (async () => {\n const gen = buildFx[Symbol.asyncIterator]()\n let result = await gen.next()\n\n // Resolve service requests from deps\n while (result.done !== true) {\n const yielded = result.value\n const serviceRequest = asServiceRequest(yielded)\n if (serviceRequest === undefined) {\n // It's an error - rethrow\n throw yielded\n }\n const service = deps._services.get(serviceRequest.key)\n if (service === undefined) {\n throw new Error(`Service \"${serviceRequest.key}\" not found during layer build`)\n }\n // oxlint-disable-next-line no-await-in-loop\n result = await gen.next(service)\n }\n\n const ctx = result.value\n cacheRef.set(layer as AnyLayer, { context: ctx })\n return ctx\n })()\n\n this.cache.set(layer as AnyLayer, { promise: buildPromise })\n\n return {\n _tag: \"AsyncFx\",\n [FxTypeId]: {\n _A: () => undefined as unknown as Context<ROut>,\n _E: () => undefined as unknown as E,\n _R: () => undefined as never,\n },\n run: async () => {\n try {\n const ctx = await buildPromise\n return ok(ctx)\n } catch (e) {\n return {\n ok: false,\n error: e as E,\n *[Symbol.iterator]() {\n yield e as E\n throw new Error(\"Unreachable\")\n },\n }\n }\n },\n async *[Symbol.asyncIterator](): AsyncGenerator<FxYield<E, never>, Context<ROut>, unknown> {\n try {\n const ctx = await buildPromise\n return ctx\n } catch (e) {\n yield e as E\n throw new Error(\"Unreachable\", { cause: e })\n }\n },\n } as AsyncFx<Context<ROut>, E>\n }\n\n // Sync build\n return {\n _tag: \"SyncFx\",\n [FxTypeId]: {\n _A: () => undefined as unknown as Context<ROut>,\n _E: () => undefined as unknown as E,\n _R: () => undefined as never,\n },\n run: () => {\n const gen = buildFx[Symbol.iterator]()\n let result = gen.next()\n\n // Resolve service requests from deps\n while (result.done !== true) {\n const yielded = result.value\n const serviceRequest = asServiceRequest(yielded)\n if (serviceRequest === undefined) {\n // It's an error\n return {\n ok: false,\n error: yielded as E,\n *[Symbol.iterator]() {\n yield yielded as E\n throw new Error(\"Unreachable\")\n },\n }\n }\n const service = deps._services.get(serviceRequest.key)\n if (service === undefined) {\n throw new Error(`Service \"${serviceRequest.key}\" not found during layer build`)\n }\n result = gen.next(service)\n }\n\n const ctx = result.value\n cacheRef.set(layer as AnyLayer, { context: ctx })\n return ok(ctx)\n },\n *[Symbol.iterator](): Generator<FxYield<E, never>, Context<ROut>, unknown> {\n const gen = buildFx[Symbol.iterator]()\n let result = gen.next()\n\n // Resolve service requests from deps\n while (result.done !== true) {\n const yielded = result.value\n const serviceRequest = asServiceRequest(yielded)\n if (serviceRequest === undefined) {\n // It's an error - yield it\n yield yielded as E\n throw new Error(\"Unreachable\")\n }\n const service = deps._services.get(serviceRequest.key)\n if (service === undefined) {\n throw new Error(`Service \"${serviceRequest.key}\" not found during layer build`)\n }\n result = gen.next(service)\n }\n\n cacheRef.set(layer as AnyLayer, { context: result.value })\n return result.value\n },\n } as SyncFx<Context<ROut>, E>\n }\n\n /**\n * Clear the cache.\n * Useful for testing.\n */\n clear(): void {\n this.cache.clear()\n }\n\n /**\n * Get the number of cached layers.\n */\n get size(): number {\n return this.cache.size\n }\n}\n\n/* oxlint-enable no-unsafe-type-assertion, only-throw-error */\n","import type { Context } from \"../context/context\"\nimport { runSync, runAsync } from \"../fx/fx.runtime\"\nimport { FxTypeId } from \"../fx/fx.types\"\nimport type { RunnableFx, SyncFx, AsyncFx, FxYield } from \"../fx/fx.types\"\nimport { merge as mergeLayers } from \"../layer/layer\"\nimport type { AllSync, Layer as LayerType, MergeError, MergeROut, UnprovidedDeps } from \"../layer/layer.types\"\nimport { ok } from \"../result/result\"\nimport { make as makeScope } from \"../scope/scope\"\nimport type { ServiceClass } from \"../service/service\"\nimport { asServiceRequest, resolveService } from \"../service/service-resolution\"\nimport { MemoMap } from \"./memo-map\"\n\n/* oxlint-disable no-unsafe-type-assertion -- layer/service re-thread generic Fx channels through runtime service injection points. */\n\n// ============================================================================\n// Provide Layer\n// ============================================================================\n\n/**\n * Extract the value type from an Fx.\n */\ntype FxValueType<F> = F extends RunnableFx<infer A, unknown, unknown> ? A : never\n\n/**\n * Extract the error type from an Fx.\n */\ntype FxErrorType<F> = F extends RunnableFx<unknown, infer E, unknown> ? E : never\n\n/**\n * Type for the result of provide based on layer sync and fx type.\n * Uses infer to extract A and E from the actual Fx type.\n * - Sync layer + SyncFx → SyncFx\n * - Sync layer + AsyncFx → AsyncFx\n * - Async layer + any fx → AsyncFx\n * - Unknown sync layer + any fx → RunnableFx (fallback)\n */\ntype ProvideResult<\n E2,\n LayerSync extends boolean,\n Fx extends RunnableFx<unknown, unknown, unknown>,\n> = LayerSync extends true\n ? Fx[\"_tag\"] extends \"SyncFx\"\n ? SyncFx<FxValueType<Fx>, FxErrorType<Fx> | E2>\n : AsyncFx<FxValueType<Fx>, FxErrorType<Fx> | E2>\n : LayerSync extends false\n ? AsyncFx<FxValueType<Fx>, FxErrorType<Fx> | E2>\n : RunnableFx<FxValueType<Fx>, FxErrorType<Fx> | E2>\n\ntype LayerList = [LayerType<unknown, unknown, unknown>, ...LayerType<unknown, unknown, unknown>[]]\ntype CompleteLayers<L extends LayerList> = UnprovidedDeps<L> extends never ? L : never\n\n/**\n * Provide a layer to an Fx computation, resolving all service requirements.\n * Creates a new scope for resource management.\n *\n * Type preservation:\n * - Sync layer + SyncFx → SyncFx\n * - Sync layer + AsyncFx → AsyncFx\n * - Async layer + any fx → AsyncFx\n * - Unknown sync layer + any fx → RunnableFx (fallback)\n *\n * @param layer - The layer providing services (must have no external requirements)\n * @returns A function that takes an Fx and returns an Fx with dependencies resolved\n *\n * @example\n * ```ts\n * import { Fx, Layer, Provide, Service } from \"@nicolastoulemont/std\"\n *\n * const Port = Service.tag<number>(\"Port\")\n * const portLayer = Layer.ok(Port, 3000)\n * const readPort = Fx.gen(function* () {\n * return yield* Port\n * })\n * const provided = Provide.layer(portLayer)(readPort)\n * const exit = Fx.run(provided)\n * // => { _tag: \"Ok\", value: 3000 }\n * ```\n */\nexport function layer<ROut, E2, LayerSync extends boolean>(\n layer: LayerType<ROut, E2, never, LayerSync>,\n): <Fx extends RunnableFx<unknown, unknown, ROut>>(fx: Fx) => ProvideResult<E2, LayerSync, Fx>\nexport function layer<ROut, E2>(layer: LayerType<ROut, E2>) {\n return <A, E, R extends ROut>(fx: RunnableFx<A, E, R>): RunnableFx<A, E | E2> => {\n // Build mode selection should remain stable for this wrapper,\n // while actual layer state (scope + memoization) must be per-execution.\n const layerBuildTag = layer.build(new MemoMap(), makeScope())._tag\n\n const createRunLayerState = (): {\n readonly scope: ReturnType<typeof makeScope>\n readonly layerBuildFx: ReturnType<typeof layer.build>\n } => {\n const memoMap = new MemoMap()\n const scope = makeScope()\n return {\n scope,\n layerBuildFx: layer.build(memoMap, scope),\n }\n }\n\n if (layerBuildTag === \"AsyncFx\" || fx._tag === \"AsyncFx\") {\n return {\n _tag: \"AsyncFx\",\n [FxTypeId]: {\n _A: () => undefined as unknown as A,\n _E: () => undefined as unknown as E | E2,\n _R: () => undefined as never,\n },\n async *[Symbol.asyncIterator](): AsyncGenerator<FxYield<E | E2, Exclude<R, ROut>>, A, unknown> {\n const { scope, layerBuildFx } = createRunLayerState()\n\n try {\n // Build the layer\n let ctx: Context<ROut>\n\n if (layerBuildFx._tag === \"AsyncFx\") {\n const gen = layerBuildFx[Symbol.asyncIterator]()\n let result = await gen.next()\n\n while (result.done !== true) {\n yield result.value as E2\n // oxlint-disable-next-line no-await-in-loop\n result = await gen.next(undefined)\n }\n ctx = result.value\n } else {\n const gen = layerBuildFx[Symbol.iterator]()\n let result = gen.next()\n\n while (result.done !== true) {\n yield result.value as E2\n result = gen.next(undefined)\n }\n ctx = result.value\n }\n\n // Run the fx with the context\n if (fx._tag === \"AsyncFx\") {\n const fxGen = fx[Symbol.asyncIterator]()\n let fxResult = await fxGen.next()\n\n while (fxResult.done !== true) {\n const yielded = fxResult.value\n\n const service = resolveService(ctx, yielded)\n if (service !== undefined) {\n // oxlint-disable-next-line no-await-in-loop\n fxResult = await fxGen.next(service)\n continue\n }\n\n // Pass through (error or unsatisfied service)\n const value = yield yielded as FxYield<E, Exclude<R, ROut>>\n // oxlint-disable-next-line no-await-in-loop\n fxResult = await fxGen.next(value)\n }\n\n return fxResult.value\n }\n\n // Sync fx\n const fxGen = fx[Symbol.iterator]()\n let fxResult = fxGen.next()\n\n while (fxResult.done !== true) {\n const yielded = fxResult.value\n\n const service = resolveService(ctx, yielded)\n if (service !== undefined) {\n fxResult = fxGen.next(service)\n continue\n }\n\n const value = yield yielded as FxYield<E, Exclude<R, ROut>>\n fxResult = fxGen.next(value)\n }\n\n return fxResult.value\n } finally {\n const closeResult = scope.close(ok(undefined))\n if (closeResult._tag === \"AsyncFx\") {\n await runAsync(closeResult)\n } else {\n runSync(closeResult)\n }\n }\n },\n } as AsyncFx<A, E | E2>\n }\n\n // Both sync\n return {\n _tag: \"SyncFx\",\n [FxTypeId]: {\n _A: () => undefined as unknown as A,\n _E: () => undefined as unknown as E | E2,\n _R: () => undefined as never,\n },\n *[Symbol.iterator](): Generator<FxYield<E | E2, Exclude<R, ROut>>, A, unknown> {\n const { scope, layerBuildFx } = createRunLayerState()\n\n if (layerBuildFx._tag === \"AsyncFx\") {\n throw new Error(\n \"Provide.layer sync execution encountered an async layer build. Ensure async layers are treated as async at composition time.\",\n )\n }\n\n try {\n // Build the layer\n const layerGen = layerBuildFx[Symbol.iterator]()\n let layerResult = layerGen.next()\n\n while (layerResult.done !== true) {\n yield layerResult.value as E2\n layerResult = layerGen.next(undefined)\n }\n\n const ctx = layerResult.value\n\n // Run the fx with the context\n const fxGen = fx[Symbol.iterator]()\n let fxResult = fxGen.next()\n\n while (fxResult.done !== true) {\n const yielded = fxResult.value\n\n const service = resolveService(ctx, yielded)\n if (service !== undefined) {\n fxResult = fxGen.next(service)\n continue\n }\n\n const value = yield yielded as FxYield<E, Exclude<R, ROut>>\n fxResult = fxGen.next(value)\n }\n\n return fxResult.value\n } finally {\n const closeResult = scope.close(ok(undefined))\n // In sync-only branch, closeResult is always SyncFx\n runSync(closeResult as SyncFx<void>)\n }\n },\n } as SyncFx<A, E | E2>\n }\n}\n\n/**\n * Provide multiple layers to an Fx computation.\n * Equivalent to `Provide.layer(Layer.merge(...layers))`, but keeps the call site flatter.\n *\n * @param layers - Layers whose combined external requirements are fully satisfied\n * @returns A function that takes an Fx and returns an Fx with dependencies resolved\n *\n * @example\n * ```ts\n * import { Fx, Layer, Provide, Service, pipe } from \"@nicolastoulemont/std\"\n *\n * const Document = Service.tag<{ readonly getById: (id: string) => string }>(\"Document\")\n * const Team = Service.tag<{ readonly canRead: (id: string) => boolean }>(\"Team\")\n *\n * const program = Fx.gen(function* () {\n * const document = yield* Document\n * const team = yield* Team\n * return team.canRead(\"doc-1\") ? document.getById(\"doc-1\") : \"forbidden\"\n * })\n *\n * const exit = Fx.run(\n * pipe(\n * program,\n * Provide.layers(\n * Layer.ok(Document, { getById: (id) => id }),\n * Layer.ok(Team, { canRead: () => true }),\n * ),\n * ),\n * )\n * // => { _tag: \"Ok\", value: \"doc-1\" }\n * ```\n */\nexport function layers<L extends LayerList>(\n ...layers: CompleteLayers<L>\n): <Fx extends RunnableFx<unknown, unknown, MergeROut<L>>>(fx: Fx) => ProvideResult<MergeError<L>, AllSync<L>, Fx>\nexport function layers(...layers: LayerList) {\n return layer(mergeLayers(...layers))\n}\n\n// ============================================================================\n// Provide Context\n// ============================================================================\n\n/**\n * Provide a context directly to an Fx computation.\n *\n * @param ctx - The context containing services\n * @returns A function that takes an Fx and returns an Fx with dependencies resolved\n *\n * @example\n * ```ts\n * import { Context, Fx, Provide, Service } from \"@nicolastoulemont/std\"\n *\n * const Port = Service.tag<number>(\"Port\")\n * const ctx = Context.make(Port, 3000)\n * const readPort = Fx.gen(function* () {\n * return yield* Port\n * })\n * const provided = Provide.context(ctx)(readPort)\n * const exit = Fx.run(provided)\n * // => { _tag: \"Ok\", value: 3000 }\n * ```\n */\nexport const context =\n <R>(ctx: Context<R>) =>\n <A, E>(fx: RunnableFx<A, E, R>): RunnableFx<A, E> => {\n if (fx._tag === \"AsyncFx\") {\n return {\n _tag: \"AsyncFx\",\n [FxTypeId]: {\n _A: () => undefined as unknown as A,\n _E: () => undefined as unknown as E,\n _R: () => undefined as never,\n },\n async *[Symbol.asyncIterator](): AsyncGenerator<FxYield<E, never>, A, unknown> {\n const gen = fx[Symbol.asyncIterator]()\n let result = await gen.next()\n\n while (result.done !== true) {\n const yielded = result.value\n\n const serviceRequest = asServiceRequest(yielded)\n if (serviceRequest === undefined) {\n yield yielded as E\n // oxlint-disable-next-line no-await-in-loop\n result = await gen.next(undefined)\n continue\n }\n const service = ctx._services.get(serviceRequest.key)\n if (service === undefined) {\n throw new Error(`Service \"${serviceRequest.key}\" not found`)\n }\n // oxlint-disable-next-line no-await-in-loop\n result = await gen.next(service)\n }\n\n return result.value\n },\n } as AsyncFx<A, E>\n }\n\n return {\n _tag: \"SyncFx\",\n [FxTypeId]: {\n _A: () => undefined as unknown as A,\n _E: () => undefined as unknown as E,\n _R: () => undefined as never,\n },\n *[Symbol.iterator](): Generator<FxYield<E, never>, A, unknown> {\n const gen = fx[Symbol.iterator]()\n let result = gen.next()\n\n while (result.done !== true) {\n const yielded = result.value\n\n const serviceRequest = asServiceRequest(yielded)\n if (serviceRequest === undefined) {\n yield yielded as E\n result = gen.next(undefined)\n continue\n }\n const service = ctx._services.get(serviceRequest.key)\n if (service === undefined) {\n throw new Error(`Service \"${serviceRequest.key}\" not found`)\n }\n result = gen.next(service)\n }\n\n return result.value\n },\n } as SyncFx<A, E>\n }\n\n// ============================================================================\n// Provide Service\n// ============================================================================\n\n/**\n * Provide a single service to an Fx computation.\n *\n * @param service - The service class (tag)\n * @param impl - The service implementation\n * @returns A function that takes an Fx and returns an Fx with the service provided\n *\n * @example\n * ```ts\n * import { Fx, Provide, Service } from \"@nicolastoulemont/std\"\n *\n * const Port = Service.tag<number>(\"Port\")\n * const readPort = Fx.gen(function* () {\n * return yield* Port\n * })\n * const provided = Provide.service(Port, 3000)(readPort)\n * const exit = Fx.run(provided)\n * // => { _tag: \"Ok\", value: 3000 }\n * ```\n */\nexport const service =\n <S>(service: ServiceClass<S>, impl: S) =>\n <A, E, R>(fx: RunnableFx<A, E, R | S>): RunnableFx<A, E, Exclude<R, S>> => {\n if (fx._tag === \"AsyncFx\") {\n return {\n _tag: \"AsyncFx\",\n [FxTypeId]: {\n _A: () => undefined as unknown as A,\n _E: () => undefined as unknown as E,\n _R: () => undefined as unknown as Exclude<R, S>,\n },\n async *[Symbol.asyncIterator](): AsyncGenerator<FxYield<E, Exclude<R, S>>, A, unknown> {\n const gen = fx[Symbol.asyncIterator]()\n let result = await gen.next()\n\n while (result.done !== true) {\n const yielded = result.value\n\n const serviceRequest = asServiceRequest(yielded)\n if (serviceRequest?.key === service.key) {\n // oxlint-disable-next-line no-await-in-loop\n result = await gen.next(impl)\n } else {\n const value = yield yielded as FxYield<E, Exclude<R, S>>\n // oxlint-disable-next-line no-await-in-loop\n result = await gen.next(value)\n }\n }\n\n return result.value\n },\n } as AsyncFx<A, E, Exclude<R, S>>\n }\n\n return {\n _tag: \"SyncFx\",\n [FxTypeId]: {\n _A: () => undefined as unknown as A,\n _E: () => undefined as unknown as E,\n _R: () => undefined as unknown as Exclude<R, S>,\n },\n *[Symbol.iterator](): Generator<FxYield<E, Exclude<R, S>>, A, unknown> {\n const gen = fx[Symbol.iterator]()\n let result = gen.next()\n\n while (result.done !== true) {\n const yielded = result.value\n\n const serviceRequest = asServiceRequest(yielded)\n if (serviceRequest?.key === service.key) {\n result = gen.next(impl)\n } else {\n const value = yield yielded as FxYield<E, Exclude<R, S>>\n result = gen.next(value)\n }\n }\n\n return result.value\n },\n } as SyncFx<A, E, Exclude<R, S>>\n }\n\n/* oxlint-enable no-unsafe-type-assertion */\n"],"mappings":"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"}
|
package/dist/queue/index.d.mts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { t as queue_d_exports } from "../index-
|
|
1
|
+
import { t as queue_d_exports } from "../index-CVmgBpDt.mjs";
|
|
2
2
|
export { queue_d_exports as Queue };
|
package/dist/queue/index.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{a as e}from"../queue-
|
|
1
|
+
import{a as e}from"../queue-GYVrD39q.mjs";export{e as Queue};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{t as e}from"./chunk-oQKkju2G.mjs";import{t}from"./data-
|
|
2
|
-
//# sourceMappingURL=queue-
|
|
1
|
+
import{t as e}from"./chunk-oQKkju2G.mjs";import{t}from"./data-DqACNS_g.mjs";var n=e({QueueAbortedError:()=>i,QueueClosedError:()=>r,QueueTaskAbortedError:()=>a,bounded:()=>h,is:()=>f,make:()=>m,unbounded:()=>g}),r=class extends t(`QueueClosedError`){},i=class extends t(`QueueAbortedError`){},a=class extends t(`QueueTaskAbortedError`){};const o=e=>{let t=e??`unbounded`;if(t===`unbounded`)return 1/0;if(!Number.isInteger(t)||t<=0)throw RangeError(`Queue concurrency must be a positive integer or "unbounded", received: ${String(t)}`);return t},s=e=>{if(e!==1/0&&(!Number.isInteger(e)||e<0))throw RangeError(`Queue maxSize must be an integer >= 0, received: ${String(e)}`)},c=e=>new a({reason:e.reason}),l=e=>new r({state:e}),u=e=>e instanceof Error?e:Error(`Queue rejection reason was not an Error`,{cause:e}),d=(e,t)=>{if(t===void 0)return e;if(t.aborted)return t;if(e.aborted)return e;let n=new AbortController,r=()=>{n.abort(e.reason),t.removeEventListener(`abort`,i)},i=()=>{n.abort(t.reason),e.removeEventListener(`abort`,r)};return e.addEventListener(`abort`,r,{once:!0}),t.addEventListener(`abort`,i,{once:!0}),n.signal.addEventListener(`abort`,()=>{e.removeEventListener(`abort`,r),t.removeEventListener(`abort`,i)},{once:!0}),n.signal},f=e=>typeof e==`object`&&!!e&&`_tag`in e&&e._tag===`Queue`,p=(e,t)=>{s(e);let n=o(t?.concurrency),r=`open`,a,f=t?.autoStart===!1,p=0,m=!1,h=[],g=[],_=new Set,v=new AbortController,y,b,x=()=>{if(!(p!==0||h.length>0)){for(let e of _)e();_.clear(),(r===`draining`||r===`aborted`)&&(r=`closed`,y?.(),y=void 0)}},S=e=>{if(g.length===0)return;let t=g.splice(0);for(let n of t)n.reject(e)},C=()=>{if(!(!Number.isFinite(e)||g.length===0))for(;g.length>0&&h.length<e&&r===`open`;){let e=g.shift();e!==void 0&&e.resolve()}},w=e=>{if(h.length===0)return;let t=new i({reason:e}),n=h.splice(0);for(let e of n)e.reject(t)},T=t=>!Number.isFinite(e)||h.length<e?Promise.resolve():new Promise((e,n)=>{let r={resolve:()=>{t!==void 0&&i!==void 0&&t.removeEventListener(`abort`,i),e()},reject:e=>{t!==void 0&&i!==void 0&&t.removeEventListener(`abort`,i),n(e)},signal:t},i=t===void 0?void 0:()=>{let e=g.indexOf(r);e!==-1&&g.splice(e,1),n(c(t))};if(t!==void 0&&t.aborted){n(c(t));return}t!==void 0&&i!==void 0&&t.addEventListener(`abort`,i,{once:!0}),g.push(r)}),E=()=>{(r===`draining`||r===`aborted`)&&p===0&&h.length===0&&x()},D=e=>{p+=1;let t=d(v.signal,e.signal),n;if(t.aborted)n=Promise.reject(c(t));else try{n=Promise.resolve(e.task({signal:t}))}catch(e){n=Promise.reject(u(e))}n.then(t=>{e.resolve(t)},t=>{e.reject(u(t))}).finally(()=>{--p,C(),O(),x()})},O=()=>{if(!m){m=!0;try{if(r===`aborted`){E();return}for(;!f&&p<n&&h.length>0;){let e=h.shift();if(e===void 0)break;C(),D(e)}E()}finally{m=!1}}},k=()=>l(a===void 0?r===`aborted`?`aborted`:r===`draining`?`draining`:r===`closed`?a??`draining`:`draining`:a);return{_tag:`Queue`,get pending(){return p},get size(){return h.length},get isPaused(){return f},get isShutdown(){return r!==`open`},enqueue(t,n){let i=n?.signal;if(i!==void 0&&i.aborted)return Promise.reject(c(i));if(r!==`open`)return Promise.reject(k());let a=()=>new Promise((e,n)=>{let r={task:t,resolve:e,reject:n,signal:i};h.push(r),O()});return!Number.isFinite(e)||h.length<e?a():T(i).then(()=>{if(i!==void 0&&i.aborted)throw c(i);if(r!==`open`)throw k();return a()})},pause(){f=!0},resume(){f&&(f=!1,O())},awaitIdle(){return p===0&&h.length===0?Promise.resolve():new Promise(e=>{_.add(e)})},shutdown(e){let t=e?.mode??`drain`;return b!==void 0&&(r===`draining`||r===`aborted`||r===`closed`)?(t===`abort`&&a!==`aborted`&&(a=`aborted`,r=`aborted`,v.abort(e?.reason),w(e?.reason),S(l(`aborted`)),E()),b):(b??=new Promise(e=>{y=e}),t===`abort`?(a=`aborted`,r=`aborted`,f=!1,v.abort(e?.reason),w(e?.reason),S(l(`aborted`))):(a=`draining`,r===`open`&&(r=`draining`),f=!1,S(l(`draining`))),O(),x(),b)}}},m=e=>p(1/0,e),h=(e,t)=>p(e,t),g=e=>p(1/0,e);export{n as a,m as i,r as n,a as r,i as t};
|
|
2
|
+
//# sourceMappingURL=queue-GYVrD39q.mjs.map
|