@fncts/query 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Cache/api.d.ts +28 -0
- package/Cache/definition.d.ts +15 -0
- package/Cache.d.ts +2 -0
- package/CompletedRequestMap.d.ts +17 -0
- package/DataSource/api.d.ts +38 -0
- package/DataSource/definition.d.ts +46 -0
- package/DataSource.d.ts +2 -0
- package/DataSourceAspect.d.ts +7 -0
- package/Described.d.ts +19 -0
- package/Query/api/bimap.d.ts +6 -0
- package/Query/api/catchAllCause.d.ts +12 -0
- package/Query/api/collectAll.d.ts +7 -0
- package/Query/api/collectAllBatched.d.ts +7 -0
- package/Query/api/collectAllConcurrent.d.ts +7 -0
- package/Query/api/defer.d.ts +7 -0
- package/Query/api/ensuring.d.ts +6 -0
- package/Query/api/environment.d.ts +47 -0
- package/Query/api/flatMap.d.ts +11 -0
- package/Query/api/foreach.d.ts +7 -0
- package/Query/api/foreachBatched.d.ts +7 -0
- package/Query/api/foreachConcurrent.d.ts +7 -0
- package/Query/api/fromRequest.d.ts +10 -0
- package/Query/api/map.d.ts +6 -0
- package/Query/api/mapDataSources.d.ts +7 -0
- package/Query/api/mapError.d.ts +6 -0
- package/Query/api/mapErrorCause.d.ts +7 -0
- package/Query/api/mapIO.d.ts +7 -0
- package/Query/api/match.d.ts +6 -0
- package/Query/api/matchCauseQuery.d.ts +7 -0
- package/Query/api/matchQuery.d.ts +6 -0
- package/Query/api/orHalt.d.ts +11 -0
- package/Query/api/race.d.ts +11 -0
- package/Query/api/run.d.ts +18 -0
- package/Query/api/timeout.d.ts +26 -0
- package/Query/api/zipWith.d.ts +7 -0
- package/Query/api/zipWithBatched.d.ts +6 -0
- package/Query/api/zipWithConcurrent.d.ts +6 -0
- package/Query/api.d.ts +66 -0
- package/Query/definition.d.ts +13 -0
- package/Query.d.ts +30 -0
- package/QueryFailure.d.ts +6 -0
- package/Request.d.ts +38 -0
- package/TestSpec.d.ts +6 -0
- package/_cjs/Cache/api.cjs +56 -0
- package/_cjs/Cache/api.cjs.map +1 -0
- package/_cjs/Cache/definition.cjs +13 -0
- package/_cjs/Cache/definition.cjs.map +1 -0
- package/_cjs/Cache.cjs +28 -0
- package/_cjs/Cache.cjs.map +1 -0
- package/_cjs/CompletedRequestMap.cjs +40 -0
- package/_cjs/CompletedRequestMap.cjs.map +1 -0
- package/_cjs/DataSource/api.cjs +111 -0
- package/_cjs/DataSource/api.cjs.map +1 -0
- package/_cjs/DataSource/definition.cjs +76 -0
- package/_cjs/DataSource/definition.cjs.map +1 -0
- package/_cjs/DataSource.cjs +28 -0
- package/_cjs/DataSource.cjs.map +1 -0
- package/_cjs/DataSourceAspect.cjs +17 -0
- package/_cjs/DataSourceAspect.cjs.map +1 -0
- package/_cjs/Described.cjs +32 -0
- package/_cjs/Described.cjs.map +1 -0
- package/_cjs/Query/api/bimap.cjs +19 -0
- package/_cjs/Query/api/bimap.cjs.map +1 -0
- package/_cjs/Query/api/catchAllCause.cjs +29 -0
- package/_cjs/Query/api/catchAllCause.cjs.map +1 -0
- package/_cjs/Query/api/collectAll.cjs +17 -0
- package/_cjs/Query/api/collectAll.cjs.map +1 -0
- package/_cjs/Query/api/collectAllBatched.cjs +17 -0
- package/_cjs/Query/api/collectAllBatched.cjs.map +1 -0
- package/_cjs/Query/api/collectAllConcurrent.cjs +17 -0
- package/_cjs/Query/api/collectAllConcurrent.cjs.map +1 -0
- package/_cjs/Query/api/defer.cjs +18 -0
- package/_cjs/Query/api/defer.cjs.map +1 -0
- package/_cjs/Query/api/ensuring.cjs +20 -0
- package/_cjs/Query/api/ensuring.cjs.map +1 -0
- package/_cjs/Query/api/environment.cjs +94 -0
- package/_cjs/Query/api/environment.cjs.map +1 -0
- package/_cjs/Query/api/flatMap.cjs +35 -0
- package/_cjs/Query/api/flatMap.cjs.map +1 -0
- package/_cjs/Query/api/foreach.cjs +26 -0
- package/_cjs/Query/api/foreach.cjs.map +1 -0
- package/_cjs/Query/api/foreachBatched.cjs +26 -0
- package/_cjs/Query/api/foreachBatched.cjs.map +1 -0
- package/_cjs/Query/api/foreachConcurrent.cjs +19 -0
- package/_cjs/Query/api/foreachConcurrent.cjs.map +1 -0
- package/_cjs/Query/api/fromRequest.cjs +38 -0
- package/_cjs/Query/api/fromRequest.cjs.map +1 -0
- package/_cjs/Query/api/map.cjs +21 -0
- package/_cjs/Query/api/map.cjs.map +1 -0
- package/_cjs/Query/api/mapDataSources.cjs +21 -0
- package/_cjs/Query/api/mapDataSources.cjs.map +1 -0
- package/_cjs/Query/api/mapError.cjs +19 -0
- package/_cjs/Query/api/mapError.cjs.map +1 -0
- package/_cjs/Query/api/mapErrorCause.cjs +19 -0
- package/_cjs/Query/api/mapErrorCause.cjs.map +1 -0
- package/_cjs/Query/api/mapIO.cjs +20 -0
- package/_cjs/Query/api/mapIO.cjs.map +1 -0
- package/_cjs/Query/api/match.cjs +20 -0
- package/_cjs/Query/api/match.cjs.map +1 -0
- package/_cjs/Query/api/matchCauseQuery.cjs +26 -0
- package/_cjs/Query/api/matchCauseQuery.cjs.map +1 -0
- package/_cjs/Query/api/matchQuery.cjs +21 -0
- package/_cjs/Query/api/matchQuery.cjs.map +1 -0
- package/_cjs/Query/api/orHalt.cjs +29 -0
- package/_cjs/Query/api/orHalt.cjs.map +1 -0
- package/_cjs/Query/api/race.cjs +41 -0
- package/_cjs/Query/api/race.cjs.map +1 -0
- package/_cjs/Query/api/run.cjs +49 -0
- package/_cjs/Query/api/run.cjs.map +1 -0
- package/_cjs/Query/api/timeout.cjs +71 -0
- package/_cjs/Query/api/timeout.cjs.map +1 -0
- package/_cjs/Query/api/zipWith.cjs +39 -0
- package/_cjs/Query/api/zipWith.cjs.map +1 -0
- package/_cjs/Query/api/zipWithBatched.cjs +39 -0
- package/_cjs/Query/api/zipWithBatched.cjs.map +1 -0
- package/_cjs/Query/api/zipWithConcurrent.cjs +39 -0
- package/_cjs/Query/api/zipWithConcurrent.cjs.map +1 -0
- package/_cjs/Query/api.cjs +99 -0
- package/_cjs/Query/api.cjs.map +1 -0
- package/_cjs/Query/definition.cjs +22 -0
- package/_cjs/Query/definition.cjs.map +1 -0
- package/_cjs/Query.cjs +336 -0
- package/_cjs/Query.cjs.map +1 -0
- package/_cjs/QueryFailure.cjs +15 -0
- package/_cjs/QueryFailure.cjs.map +1 -0
- package/_cjs/Request.cjs +54 -0
- package/_cjs/Request.cjs.map +1 -0
- package/_cjs/global.cjs +6 -0
- package/_cjs/global.cjs.map +1 -0
- package/_cjs/index.cjs +6 -0
- package/_cjs/index.cjs.map +1 -0
- package/_cjs/internal/BlockedRequest.cjs +30 -0
- package/_cjs/internal/BlockedRequest.cjs.map +1 -0
- package/_cjs/internal/BlockedRequests.cjs +367 -0
- package/_cjs/internal/BlockedRequests.cjs.map +1 -0
- package/_cjs/internal/Continue.cjs +292 -0
- package/_cjs/internal/Continue.cjs.map +1 -0
- package/_cjs/internal/Parallel.cjs +81 -0
- package/_cjs/internal/Parallel.cjs.map +1 -0
- package/_cjs/internal/Result.cjs +234 -0
- package/_cjs/internal/Result.cjs.map +1 -0
- package/_cjs/internal/Sequential.cjs +59 -0
- package/_cjs/internal/Sequential.cjs.map +1 -0
- package/_mjs/Cache/api.mjs +44 -0
- package/_mjs/Cache/api.mjs.map +1 -0
- package/_mjs/Cache/definition.mjs +6 -0
- package/_mjs/Cache/definition.mjs.map +1 -0
- package/_mjs/Cache.mjs +4 -0
- package/_mjs/Cache.mjs.map +1 -0
- package/_mjs/CompletedRequestMap.mjs +31 -0
- package/_mjs/CompletedRequestMap.mjs.map +1 -0
- package/_mjs/DataSource/api.mjs +98 -0
- package/_mjs/DataSource/api.mjs.map +1 -0
- package/_mjs/DataSource/definition.mjs +63 -0
- package/_mjs/DataSource/definition.mjs.map +1 -0
- package/_mjs/DataSource.mjs +4 -0
- package/_mjs/DataSource.mjs.map +1 -0
- package/_mjs/DataSourceAspect.mjs +9 -0
- package/_mjs/DataSourceAspect.mjs.map +1 -0
- package/_mjs/Described.mjs +24 -0
- package/_mjs/Described.mjs.map +1 -0
- package/_mjs/Query/api/bimap.mjs +11 -0
- package/_mjs/Query/api/bimap.mjs.map +1 -0
- package/_mjs/Query/api/catchAllCause.mjs +20 -0
- package/_mjs/Query/api/catchAllCause.mjs.map +1 -0
- package/_mjs/Query/api/collectAll.mjs +9 -0
- package/_mjs/Query/api/collectAll.mjs.map +1 -0
- package/_mjs/Query/api/collectAllBatched.mjs +9 -0
- package/_mjs/Query/api/collectAllBatched.mjs.map +1 -0
- package/_mjs/Query/api/collectAllConcurrent.mjs +9 -0
- package/_mjs/Query/api/collectAllConcurrent.mjs.map +1 -0
- package/_mjs/Query/api/defer.mjs +10 -0
- package/_mjs/Query/api/defer.mjs.map +1 -0
- package/_mjs/Query/api/ensuring.mjs +12 -0
- package/_mjs/Query/api/ensuring.mjs.map +1 -0
- package/_mjs/Query/api/environment.mjs +77 -0
- package/_mjs/Query/api/environment.mjs.map +1 -0
- package/_mjs/Query/api/flatMap.mjs +25 -0
- package/_mjs/Query/api/flatMap.mjs.map +1 -0
- package/_mjs/Query/api/foreach.mjs +18 -0
- package/_mjs/Query/api/foreach.mjs.map +1 -0
- package/_mjs/Query/api/foreachBatched.mjs +18 -0
- package/_mjs/Query/api/foreachBatched.mjs.map +1 -0
- package/_mjs/Query/api/foreachConcurrent.mjs +11 -0
- package/_mjs/Query/api/foreachConcurrent.mjs.map +1 -0
- package/_mjs/Query/api/fromRequest.mjs +30 -0
- package/_mjs/Query/api/fromRequest.mjs.map +1 -0
- package/_mjs/Query/api/map.mjs +13 -0
- package/_mjs/Query/api/map.mjs.map +1 -0
- package/_mjs/Query/api/mapDataSources.mjs +13 -0
- package/_mjs/Query/api/mapDataSources.mjs.map +1 -0
- package/_mjs/Query/api/mapError.mjs +11 -0
- package/_mjs/Query/api/mapError.mjs.map +1 -0
- package/_mjs/Query/api/mapErrorCause.mjs +11 -0
- package/_mjs/Query/api/mapErrorCause.mjs.map +1 -0
- package/_mjs/Query/api/mapIO.mjs +12 -0
- package/_mjs/Query/api/mapIO.mjs.map +1 -0
- package/_mjs/Query/api/match.mjs +12 -0
- package/_mjs/Query/api/match.mjs.map +1 -0
- package/_mjs/Query/api/matchCauseQuery.mjs +18 -0
- package/_mjs/Query/api/matchCauseQuery.mjs.map +1 -0
- package/_mjs/Query/api/matchQuery.mjs +13 -0
- package/_mjs/Query/api/matchQuery.mjs.map +1 -0
- package/_mjs/Query/api/orHalt.mjs +19 -0
- package/_mjs/Query/api/orHalt.mjs.map +1 -0
- package/_mjs/Query/api/race.mjs +33 -0
- package/_mjs/Query/api/race.mjs.map +1 -0
- package/_mjs/Query/api/run.mjs +38 -0
- package/_mjs/Query/api/run.mjs.map +1 -0
- package/_mjs/Query/api/timeout.mjs +59 -0
- package/_mjs/Query/api/timeout.mjs.map +1 -0
- package/_mjs/Query/api/zipWith.mjs +30 -0
- package/_mjs/Query/api/zipWith.mjs.map +1 -0
- package/_mjs/Query/api/zipWithBatched.mjs +31 -0
- package/_mjs/Query/api/zipWithBatched.mjs.map +1 -0
- package/_mjs/Query/api/zipWithConcurrent.mjs +31 -0
- package/_mjs/Query/api/zipWithConcurrent.mjs.map +1 -0
- package/_mjs/Query/api.mjs +77 -0
- package/_mjs/Query/api.mjs.map +1 -0
- package/_mjs/Query/definition.mjs +14 -0
- package/_mjs/Query/definition.mjs.map +1 -0
- package/_mjs/Query.mjs +34 -0
- package/_mjs/Query.mjs.map +1 -0
- package/_mjs/QueryFailure.mjs +8 -0
- package/_mjs/QueryFailure.mjs.map +1 -0
- package/_mjs/Request.mjs +43 -0
- package/_mjs/Request.mjs.map +1 -0
- package/_mjs/global.mjs +2 -0
- package/_mjs/global.mjs.map +1 -0
- package/_mjs/index.mjs +2 -0
- package/_mjs/index.mjs.map +1 -0
- package/_mjs/internal/BlockedRequest.mjs +21 -0
- package/_mjs/internal/BlockedRequest.mjs.map +1 -0
- package/_mjs/internal/BlockedRequests.mjs +341 -0
- package/_mjs/internal/BlockedRequests.mjs.map +1 -0
- package/_mjs/internal/Continue.mjs +262 -0
- package/_mjs/internal/Continue.mjs.map +1 -0
- package/_mjs/internal/Parallel.mjs +62 -0
- package/_mjs/internal/Parallel.mjs.map +1 -0
- package/_mjs/internal/Result.mjs +208 -0
- package/_mjs/internal/Result.mjs.map +1 -0
- package/_mjs/internal/Sequential.mjs +44 -0
- package/_mjs/internal/Sequential.mjs.map +1 -0
- package/_src/Cache/api.ts +49 -0
- package/_src/Cache/definition.ts +13 -0
- package/_src/Cache.ts +4 -0
- package/_src/CompletedRequestMap.ts +38 -0
- package/_src/DataSource/api.ts +97 -0
- package/_src/DataSource/definition.ts +77 -0
- package/_src/DataSource.ts +4 -0
- package/_src/DataSourceAspect.ts +7 -0
- package/_src/Described.ts +21 -0
- package/_src/Query/api/bimap.ts +11 -0
- package/_src/Query/api/catchAllCause.ts +17 -0
- package/_src/Query/api/collectAll.ts +6 -0
- package/_src/Query/api/collectAllBatched.ts +9 -0
- package/_src/Query/api/collectAllConcurrent.ts +6 -0
- package/_src/Query/api/defer.ts +6 -0
- package/_src/Query/api/ensuring.ts +19 -0
- package/_src/Query/api/environment.ts +82 -0
- package/_src/Query/api/flatMap.ts +26 -0
- package/_src/Query/api/foreach.ts +17 -0
- package/_src/Query/api/foreachBatched.ts +17 -0
- package/_src/Query/api/foreachConcurrent.ts +10 -0
- package/_src/Query/api/fromRequest.ts +49 -0
- package/_src/Query/api/map.ts +8 -0
- package/_src/Query/api/mapDataSources.ts +8 -0
- package/_src/Query/api/mapError.ts +8 -0
- package/_src/Query/api/mapErrorCause.ts +8 -0
- package/_src/Query/api/mapIO.ts +8 -0
- package/_src/Query/api/match.ts +11 -0
- package/_src/Query/api/matchCauseQuery.ts +21 -0
- package/_src/Query/api/matchQuery.ts +12 -0
- package/_src/Query/api/orHalt.ts +15 -0
- package/_src/Query/api/race.ts +34 -0
- package/_src/Query/api/run.ts +40 -0
- package/_src/Query/api/timeout.ts +58 -0
- package/_src/Query/api/zipWith.ts +44 -0
- package/_src/Query/api/zipWithBatched.ts +41 -0
- package/_src/Query/api/zipWithConcurrent.ts +45 -0
- package/_src/Query/api.ts +76 -0
- package/_src/Query/definition.ts +13 -0
- package/_src/Query.ts +35 -0
- package/_src/QueryFailure.ts +7 -0
- package/_src/Request.ts +52 -0
- package/_src/global.ts +45 -0
- package/_src/index.ts +3 -0
- package/_src/internal/BlockedRequest.ts +24 -0
- package/_src/internal/BlockedRequests.ts +331 -0
- package/_src/internal/Continue.ts +305 -0
- package/_src/internal/Parallel.ts +82 -0
- package/_src/internal/Result.ts +242 -0
- package/_src/internal/Sequential.ts +63 -0
- package/global.d.ts +45 -0
- package/index.d.ts +1 -0
- package/internal/BlockedRequest.d.ts +21 -0
- package/internal/BlockedRequests.d.ts +123 -0
- package/internal/Continue.d.ts +133 -0
- package/internal/Parallel.d.ts +56 -0
- package/internal/Result.d.ts +115 -0
- package/internal/Sequential.d.ts +40 -0
- package/package.json +22 -0
- package/runTests.d.ts +1 -0
|
@@ -0,0 +1,305 @@
|
|
|
1
|
+
import type { Described } from "@fncts/query/Described";
|
|
2
|
+
|
|
3
|
+
import { QueryFailure } from "../QueryFailure.js";
|
|
4
|
+
|
|
5
|
+
export const ContinueTypeId = Symbol.for("fncts.query.Continue");
|
|
6
|
+
export type ContinueTypeId = typeof ContinueTypeId;
|
|
7
|
+
|
|
8
|
+
export const ContinueVariance = Symbol.for("fncts.query.Continue.Variance");
|
|
9
|
+
export type ContinueVariance = typeof ContinueVariance;
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* @tsplus type fncts.query.Continue
|
|
13
|
+
* @tsplus companion fncts.query.ContinueOps
|
|
14
|
+
*/
|
|
15
|
+
export abstract class Continue<R, E, A> {
|
|
16
|
+
readonly [ContinueTypeId]: ContinueTypeId = ContinueTypeId;
|
|
17
|
+
declare [ContinueVariance]: {
|
|
18
|
+
readonly _R: (_: never) => R;
|
|
19
|
+
readonly _E: (_: never) => E;
|
|
20
|
+
readonly _A: (_: never) => A;
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export const enum ContinueTag {
|
|
25
|
+
Effect,
|
|
26
|
+
Get,
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* @tsplus companion fncts.query.Continue.EffectOps
|
|
31
|
+
*/
|
|
32
|
+
export class Effect<R, E, A> extends Continue<R, E, A> {
|
|
33
|
+
readonly _tag = ContinueTag.Effect;
|
|
34
|
+
constructor(readonly query: Query<R, E, A>) {
|
|
35
|
+
super();
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* @tsplus companion fncts.query.Continue.GetOps
|
|
41
|
+
*/
|
|
42
|
+
export class Get<E, A> extends Continue<never, E, A> {
|
|
43
|
+
readonly _tag = ContinueTag.Get;
|
|
44
|
+
constructor(readonly io: FIO<E, A>) {
|
|
45
|
+
super();
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
type Concrete<R, E, A> = Effect<R, E, A> | Get<E, A>;
|
|
50
|
+
|
|
51
|
+
function concrete<R, E, A>(_: Continue<R, E, A>): asserts _ is Concrete<R, E, A> {
|
|
52
|
+
//
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* @tsplus static fncts.query.Continue.EffectOps __call
|
|
57
|
+
* @tsplus static fncts.query.Continue effect
|
|
58
|
+
*/
|
|
59
|
+
export function effect<R, E, A>(query: Query<R, E, A>): Continue<R, E, A> {
|
|
60
|
+
return new Effect(query);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* @tsplus static fncts.query.Continue.GetOps __call
|
|
65
|
+
* @tsplus static fncts.query.Continue get
|
|
66
|
+
*/
|
|
67
|
+
export function get<E, A>(io: FIO<E, A>): Continue<never, E, A> {
|
|
68
|
+
return new Get(io);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* @tsplus static fncts.query.ContinueOps __call
|
|
73
|
+
*/
|
|
74
|
+
export function makeContinue<R, E, A extends Request<E, B>, B>(
|
|
75
|
+
request: A,
|
|
76
|
+
dataSource: DataSource<R, A>,
|
|
77
|
+
ref: Ref<Maybe<Either<E, B>>>,
|
|
78
|
+
__tsplusTrace?: string,
|
|
79
|
+
): Continue<R, E, B> {
|
|
80
|
+
return Continue.get(
|
|
81
|
+
ref.get.flatMap((m) =>
|
|
82
|
+
m.match(
|
|
83
|
+
() => IO.haltNow(new QueryFailure(dataSource, request)),
|
|
84
|
+
(b) => IO.fromEitherNow(b),
|
|
85
|
+
),
|
|
86
|
+
),
|
|
87
|
+
);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* @tsplus pipeable fncts.query.Continue matchType
|
|
92
|
+
*/
|
|
93
|
+
export function matchType<R, E, A, B, C>(cases: { Effect: (query: Query<R, E, A>) => B; Get: (io: FIO<E, A>) => C }) {
|
|
94
|
+
return (self: Continue<R, E, A>): B | C => {
|
|
95
|
+
concrete(self);
|
|
96
|
+
switch (self._tag) {
|
|
97
|
+
case ContinueTag.Effect:
|
|
98
|
+
return cases.Effect(self.query);
|
|
99
|
+
case ContinueTag.Get:
|
|
100
|
+
return cases.Get(self.io);
|
|
101
|
+
}
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* @tsplus pipeable fncts.query.Continue mapQuery
|
|
107
|
+
*/
|
|
108
|
+
export function mapQuery<A, R1, E1, B>(f: (a: A) => Query<R1, E1, B>, __tsplusTrace?: string) {
|
|
109
|
+
return <R, E>(self: Continue<R, E, A>): Continue<R | R1, E | E1, B> => {
|
|
110
|
+
return self.matchType({
|
|
111
|
+
Effect: (query) => Effect(query.flatMap(f)),
|
|
112
|
+
Get: (io) => Effect(Query.fromIO(io).flatMap(f)),
|
|
113
|
+
});
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* @tsplus pipeable fncts.query.Continue match
|
|
119
|
+
*/
|
|
120
|
+
export function match<E, A, B, C>(failure: (e: E) => B, success: (a: A) => C, __tsplusTrace?: string) {
|
|
121
|
+
return <R>(self: Continue<R, E, A>): Continue<R, never, B | C> => {
|
|
122
|
+
return self.matchType({
|
|
123
|
+
Effect: (query) => Effect(query.match(failure, success)),
|
|
124
|
+
Get: (io) => Get(io.match(failure, success)),
|
|
125
|
+
});
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* @tsplus pipeable fncts.query.Continue matchCauseQuery
|
|
131
|
+
*/
|
|
132
|
+
export function matchCauseQuery<E, A, R1, E1, B, R2, E2, C>(
|
|
133
|
+
failure: (cause: Cause<E>) => Query<R1, E1, B>,
|
|
134
|
+
success: (value: A) => Query<R2, E2, C>,
|
|
135
|
+
__tsplusTrace?: string,
|
|
136
|
+
) {
|
|
137
|
+
return <R>(self: Continue<R, E, A>): Continue<R | R1 | R2, E1 | E2, B | C> => {
|
|
138
|
+
return self.matchType({
|
|
139
|
+
Effect: (query) => Effect(query.matchCauseQuery(failure, success)),
|
|
140
|
+
Get: (io) => Effect(Query.fromIO(io).matchCauseQuery(failure, success)),
|
|
141
|
+
});
|
|
142
|
+
};
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
/**
|
|
146
|
+
* @tsplus pipeable fncts.query.Continue map
|
|
147
|
+
*/
|
|
148
|
+
export function map<A, B>(f: (a: A) => B, __tsplusTrace?: string) {
|
|
149
|
+
return <R, E>(self: Continue<R, E, A>): Continue<R, E, B> => {
|
|
150
|
+
return self.matchType({
|
|
151
|
+
Effect: (query) => Effect(query.map(f)),
|
|
152
|
+
Get: (io) => Get(io.map(f)),
|
|
153
|
+
});
|
|
154
|
+
};
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
/**
|
|
158
|
+
* @tsplus pipeable fncts.query.Continue mapDataSources
|
|
159
|
+
*/
|
|
160
|
+
export function mapDataSources<R1>(f: DataSourceAspect<R1>, __tsplusTrace?: string) {
|
|
161
|
+
return <R, E, A>(self: Continue<R, E, A>): Continue<R | R1, E, A> => {
|
|
162
|
+
return self.matchType({
|
|
163
|
+
Effect: (query) => Effect(query.mapDataSources(f)),
|
|
164
|
+
Get: (io) => Get(io),
|
|
165
|
+
});
|
|
166
|
+
};
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
/**
|
|
170
|
+
* @tsplus pipeable fncts.query.Continue mapError
|
|
171
|
+
*/
|
|
172
|
+
export function mapError<E, E1>(f: (e: E) => E1, __tsplusTrace?: string) {
|
|
173
|
+
return <R, A>(self: Continue<R, E, A>): Continue<R, E1, A> => {
|
|
174
|
+
return self.matchType({
|
|
175
|
+
Effect: (query) => Effect(query.mapError(f)),
|
|
176
|
+
Get: (io) => Get(io.mapError(f)),
|
|
177
|
+
});
|
|
178
|
+
};
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
/**
|
|
182
|
+
* @tsplus pipeable fncts.query.Continue mapErrorCause
|
|
183
|
+
*/
|
|
184
|
+
export function mapErrorCause<E, E1>(f: (cause: Cause<E>) => Cause<E1>, __tsplusTrace?: string) {
|
|
185
|
+
return <R, A>(self: Continue<R, E, A>): Continue<R, E1, A> => {
|
|
186
|
+
return self.matchType({
|
|
187
|
+
Effect: (query) => Effect(query.mapErrorCause(f)),
|
|
188
|
+
Get: (io) => Get(io.mapErrorCause(f)),
|
|
189
|
+
});
|
|
190
|
+
};
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
/**
|
|
194
|
+
* @tsplus pipeable fncts.query.Continue zipWith
|
|
195
|
+
*/
|
|
196
|
+
export function zipWith<A, R1, E1, B, C>(that: Continue<R1, E1, B>, f: (a: A, b: B) => C, __tsplusTrace?: string) {
|
|
197
|
+
return <R, E>(self: Continue<R, E, A>): Continue<R | R1, E | E1, C> => {
|
|
198
|
+
return self.matchType({
|
|
199
|
+
Effect: (l) =>
|
|
200
|
+
that.matchType({
|
|
201
|
+
Effect: (r) => Effect(l.zipWith(r, f)),
|
|
202
|
+
Get: (r) => Effect(l.zipWith(Query.fromIO(r), f)),
|
|
203
|
+
}),
|
|
204
|
+
Get: (l) =>
|
|
205
|
+
that.matchType({
|
|
206
|
+
Effect: (r) => Effect(Query.fromIO(l).zipWith(r, f)),
|
|
207
|
+
Get: (r) => Get(l.zipWith(r, f)),
|
|
208
|
+
}),
|
|
209
|
+
});
|
|
210
|
+
};
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
/**
|
|
214
|
+
* @tsplus pipeable fncts.query.Continue zipWithConcurrent
|
|
215
|
+
*/
|
|
216
|
+
export function zipWithConcurrent<A, R1, E1, B, C>(
|
|
217
|
+
that: Continue<R1, E1, B>,
|
|
218
|
+
f: (a: A, b: B) => C,
|
|
219
|
+
__tsplusTrace?: string,
|
|
220
|
+
) {
|
|
221
|
+
return <R, E>(self: Continue<R, E, A>): Continue<R | R1, E | E1, C> => {
|
|
222
|
+
return self.matchType({
|
|
223
|
+
Effect: (l) =>
|
|
224
|
+
that.matchType({
|
|
225
|
+
Effect: (r) => Effect(l.zipWithConcurrent(r, f)),
|
|
226
|
+
Get: (r) => Effect(l.zipWith(Query.fromIO(r), f)),
|
|
227
|
+
}),
|
|
228
|
+
Get: (l) =>
|
|
229
|
+
that.matchType({
|
|
230
|
+
Effect: (r) => Effect(Query.fromIO(l).zipWith(r, f)),
|
|
231
|
+
Get: (r) => Get(l.zipWith(r, f)),
|
|
232
|
+
}),
|
|
233
|
+
});
|
|
234
|
+
};
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
/**
|
|
238
|
+
* @tsplus pipeable fncts.query.Continue zipWithBatched
|
|
239
|
+
*/
|
|
240
|
+
export function zipWithBatched<A, R1, E1, B, C>(
|
|
241
|
+
that: Continue<R1, E1, B>,
|
|
242
|
+
f: (a: A, b: B) => C,
|
|
243
|
+
__tsplusTrace?: string,
|
|
244
|
+
) {
|
|
245
|
+
return <R, E>(self: Continue<R, E, A>): Continue<R | R1, E | E1, C> => {
|
|
246
|
+
return self.matchType({
|
|
247
|
+
Effect: (l) =>
|
|
248
|
+
that.matchType({
|
|
249
|
+
Effect: (r) => Effect(l.zipWithBatched(r, f)),
|
|
250
|
+
Get: (r) => Effect(l.zipWith(Query.fromIO(r), f)),
|
|
251
|
+
}),
|
|
252
|
+
Get: (l) =>
|
|
253
|
+
that.matchType({
|
|
254
|
+
Effect: (r) => Effect(Query.fromIO(l).zipWith(r, f)),
|
|
255
|
+
Get: (r) => Get(l.zipWith(r, f)),
|
|
256
|
+
}),
|
|
257
|
+
});
|
|
258
|
+
};
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
/**
|
|
262
|
+
* @tsplus static fncts.query.ContinueOps collectAllConcurrent
|
|
263
|
+
*/
|
|
264
|
+
export function collectAllConcurrent<R, E, A>(continues: Iterable<Continue<R, E, A>>): Continue<R, E, Conc<A>> {
|
|
265
|
+
const [queries, ios] = continues.zipWithIndex.foldLeft(
|
|
266
|
+
[Conc.empty<readonly [Query<R, E, A>, number]>(), Conc.empty<readonly [FIO<E, A>, number]>()] as const,
|
|
267
|
+
([queries, ios], [index, cont]) =>
|
|
268
|
+
cont.matchType({
|
|
269
|
+
Effect: (query) => [queries.append([query, index] as const), ios] as const,
|
|
270
|
+
Get: (io) => [queries, ios.append([io, index] as const)] as const,
|
|
271
|
+
}),
|
|
272
|
+
);
|
|
273
|
+
if (queries.length === 0) {
|
|
274
|
+
return Continue.get(IO.sequenceIterable(ios.map(([io]) => io)));
|
|
275
|
+
} else {
|
|
276
|
+
const query = Query.collectAllConcurrent(queries.map(([query]) => query)).flatMap((as) => {
|
|
277
|
+
const array = Array(continues.size);
|
|
278
|
+
as.zip(queries.map(([_, index]) => index)).forEach(([a, i]) => {
|
|
279
|
+
array[i] = a;
|
|
280
|
+
});
|
|
281
|
+
return Query.fromIO(IO.sequenceIterable(ios.map(([io]) => io))).map((as) => {
|
|
282
|
+
as.zip(ios.map(([_, index]) => index)).forEach(([a, i]) => {
|
|
283
|
+
array[i] = a;
|
|
284
|
+
});
|
|
285
|
+
return Conc.from(array);
|
|
286
|
+
});
|
|
287
|
+
});
|
|
288
|
+
return Continue.effect(query);
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
/**
|
|
293
|
+
* @tsplus pipeable fncts.query.Continue contramapEnvironment
|
|
294
|
+
*/
|
|
295
|
+
export function contramapEnvironment<R0, R>(
|
|
296
|
+
f: Described<(_: Environment<R0>) => Environment<R>>,
|
|
297
|
+
__tsplusTrace?: string,
|
|
298
|
+
) {
|
|
299
|
+
return <E, A>(self: Continue<R, E, A>): Continue<R0, E, A> => {
|
|
300
|
+
return self.matchType({
|
|
301
|
+
Effect: (query) => Continue.effect(query.contramapEnvironment(f)),
|
|
302
|
+
Get: (io) => Continue.get(io),
|
|
303
|
+
});
|
|
304
|
+
};
|
|
305
|
+
}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import type { DataSource } from "@fncts/query/DataSource";
|
|
2
|
+
import type { BlockedRequest } from "@fncts/query/internal/BlockedRequest";
|
|
3
|
+
|
|
4
|
+
import { Sequential } from "@fncts/query/internal/Sequential";
|
|
5
|
+
|
|
6
|
+
export const ParallelTypeId = Symbol.for("fncts.query.Parallel");
|
|
7
|
+
export type ParallelTypeId = typeof ParallelTypeId;
|
|
8
|
+
|
|
9
|
+
export const ParallelVariance = Symbol.for("fncts.query.Parallel.Variance");
|
|
10
|
+
export type ParallelVariance = typeof ParallelVariance;
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* @tsplus type fncts.query.Parallel
|
|
14
|
+
* @tsplus companion fncts.query.ParallelOps
|
|
15
|
+
*/
|
|
16
|
+
export class Parallel<R> {
|
|
17
|
+
readonly [ParallelTypeId]: ParallelTypeId = ParallelTypeId;
|
|
18
|
+
declare [ParallelVariance]: {
|
|
19
|
+
readonly _R: (_: never) => R;
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
constructor(readonly map: HashMap<DataSource<any, any>, Conc<BlockedRequest<any>>>) {}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* @tsplus pipeable fncts.query.Parallel concat
|
|
27
|
+
*/
|
|
28
|
+
export function concat<R1>(that: Parallel<R1>) {
|
|
29
|
+
return <R>(self: Parallel<R>): Parallel<R | R1> => {
|
|
30
|
+
return new Parallel(
|
|
31
|
+
that.map.foldLeftWithIndex(self.map, (k, map, v) =>
|
|
32
|
+
map.set(
|
|
33
|
+
k,
|
|
34
|
+
map.get(k).match(
|
|
35
|
+
() => v,
|
|
36
|
+
(requests) => requests.concat(v),
|
|
37
|
+
),
|
|
38
|
+
),
|
|
39
|
+
),
|
|
40
|
+
);
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* @tsplus getter fncts.query.Parallel isEmpty
|
|
46
|
+
*/
|
|
47
|
+
export function isEmpty<R>(self: Parallel<R>): boolean {
|
|
48
|
+
return self.map.isEmpty;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* @tsplus getter fncts.query.Parallel keys
|
|
53
|
+
*/
|
|
54
|
+
export function keys<R>(self: Parallel<R>): Iterable<DataSource<R, any>> {
|
|
55
|
+
return self.map.keys;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* @tsplus getter fncts.query.Parallel toIterable
|
|
60
|
+
*/
|
|
61
|
+
export function toIterable<R>(self: Parallel<R>): Iterable<readonly [DataSource<R, any>, Conc<BlockedRequest<any>>]> {
|
|
62
|
+
return self.map;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* @tsplus getter fncts.query.Parallel sequential
|
|
67
|
+
*/
|
|
68
|
+
export function sequential<R>(self: Parallel<R>): Sequential<R> {
|
|
69
|
+
return new Sequential(self.map.map((v) => Conc(v)));
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* @tsplus static fncts.query.ParallelOps __call
|
|
74
|
+
*/
|
|
75
|
+
export function makeParallel<R, A>(dataSource: DataSource<R, A>, blockedRequest: BlockedRequest<A>): Parallel<R> {
|
|
76
|
+
return new Parallel(HashMap([dataSource, Conc(blockedRequest)]));
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* @tsplus static fncts.query.ParallelOps empty
|
|
81
|
+
*/
|
|
82
|
+
export const empty: Parallel<never> = new Parallel(HashMap.empty());
|
|
@@ -0,0 +1,242 @@
|
|
|
1
|
+
import type { Described } from "@fncts/query/Described";
|
|
2
|
+
|
|
3
|
+
import { BlockedRequests } from "@fncts/query/internal/BlockedRequests";
|
|
4
|
+
|
|
5
|
+
export const ResultTypeId = Symbol.for("fncts.query.Result");
|
|
6
|
+
export type ResultTypeId = typeof ResultTypeId;
|
|
7
|
+
|
|
8
|
+
export const ResultVariance = Symbol.for("fncts.query.Result.Variance");
|
|
9
|
+
export type ResultVariance = typeof ResultVariance;
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* @tsplus type fncts.query.Result
|
|
13
|
+
* @tsplus companion fncts.query.ResultOps
|
|
14
|
+
*/
|
|
15
|
+
export abstract class Result<R, E, A> {
|
|
16
|
+
readonly [ResultTypeId]: ResultTypeId = ResultTypeId;
|
|
17
|
+
declare [ResultVariance]: {
|
|
18
|
+
readonly _R: (_: never) => R;
|
|
19
|
+
readonly _E: (_: never) => E;
|
|
20
|
+
readonly _A: (_: never) => A;
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export const enum ResultTag {
|
|
25
|
+
Blocked,
|
|
26
|
+
Done,
|
|
27
|
+
Fail,
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export class Blocked<R, E, A> extends Result<R, E, A> {
|
|
31
|
+
readonly _tag = ResultTag.Blocked;
|
|
32
|
+
constructor(readonly blockedRequests: BlockedRequests<R>, readonly cont: Continue<R, E, A>) {
|
|
33
|
+
super();
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export class Done<A> extends Result<never, never, A> {
|
|
38
|
+
readonly _tag = ResultTag.Done;
|
|
39
|
+
constructor(readonly value: A) {
|
|
40
|
+
super();
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export class Fail<E> extends Result<never, E, never> {
|
|
45
|
+
readonly _tag = ResultTag.Fail;
|
|
46
|
+
constructor(readonly cause: Cause<E>) {
|
|
47
|
+
super();
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
type Concrete<R, E, A> = Blocked<R, E, A> | Done<A> | Fail<E>;
|
|
52
|
+
|
|
53
|
+
function concrete<R, E, A>(_: Result<R, E, A>): asserts _ is Concrete<R, E, A> {
|
|
54
|
+
//
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* @tsplus static fncts.query.ResultOps blocked
|
|
59
|
+
*/
|
|
60
|
+
export function blocked<R, E, A>(blockedRequests: BlockedRequests<R>, cont: Continue<R, E, A>): Result<R, E, A> {
|
|
61
|
+
return new Blocked(blockedRequests, cont);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* @tsplus static fncts.query.ResultOps done
|
|
66
|
+
*/
|
|
67
|
+
export function done<A>(value: A): Result<never, never, A> {
|
|
68
|
+
return new Done(value);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* @tsplus static fncts.query.ResultOps fail
|
|
73
|
+
*/
|
|
74
|
+
export function fail<E>(cause: Cause<E>): Result<never, E, never> {
|
|
75
|
+
return new Fail(cause);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* @tsplus pipeable fncts.query.Result matchType
|
|
80
|
+
*/
|
|
81
|
+
export function matchType<R, E, A, B, C, D>(cases: {
|
|
82
|
+
Blocked: (blockedRequests: BlockedRequests<R>, cont: Continue<R, E, A>) => B;
|
|
83
|
+
Done: (value: A) => C;
|
|
84
|
+
Fail: (cause: Cause<E>) => D;
|
|
85
|
+
}) {
|
|
86
|
+
return (self: Result<R, E, A>): B | C | D => {
|
|
87
|
+
concrete(self);
|
|
88
|
+
switch (self._tag) {
|
|
89
|
+
case ResultTag.Blocked: {
|
|
90
|
+
return cases.Blocked(self.blockedRequests, self.cont);
|
|
91
|
+
}
|
|
92
|
+
case ResultTag.Done: {
|
|
93
|
+
return cases.Done(self.value);
|
|
94
|
+
}
|
|
95
|
+
case ResultTag.Fail: {
|
|
96
|
+
return cases.Fail(self.cause);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* @tsplus pipeable fncts.query.Result match
|
|
104
|
+
*/
|
|
105
|
+
export function match<E, A, B, C>(failure: (e: E) => B, success: (a: A) => C) {
|
|
106
|
+
return <R>(self: Result<R, E, A>): Result<R, never, B | C> => {
|
|
107
|
+
return self.matchType({
|
|
108
|
+
Blocked: (br, c) => Result.blocked(br, c.match(failure, success)),
|
|
109
|
+
Done: (a) => Result.done(success(a)),
|
|
110
|
+
Fail: (e) => e.failureOrCause.match((e) => Result.done(failure(e)), Result.fail),
|
|
111
|
+
});
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* @tsplus pipeable fncts.query.Result map
|
|
117
|
+
*/
|
|
118
|
+
export function map<A, B>(f: (a: A) => B, __tsplusTrace?: string) {
|
|
119
|
+
return <R, E>(self: Result<R, E, A>): Result<R, E, B> => {
|
|
120
|
+
return self.matchType({
|
|
121
|
+
Blocked: (br, c) => Result.blocked(br, c.map(f)),
|
|
122
|
+
Done: (a) => Result.done(f(a)),
|
|
123
|
+
Fail: (cause) => Result.fail(cause),
|
|
124
|
+
});
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* @tsplus pipeable fncts.query.Result mapDataSources
|
|
130
|
+
*/
|
|
131
|
+
export function mapDataSources<R1>(f: DataSourceAspect<R1>) {
|
|
132
|
+
return <R, E, A>(self: Result<R, E, A>): Result<R | R1, E, A> => {
|
|
133
|
+
return self.matchType({
|
|
134
|
+
Blocked: (br, c) => Result.blocked(br.mapDataSources(f), c.mapDataSources(f)),
|
|
135
|
+
Done: (a) => Result.done(a),
|
|
136
|
+
Fail: (cause) => Result.fail(cause),
|
|
137
|
+
});
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* @tsplus pipeable fncts.query.Result mapError
|
|
143
|
+
*/
|
|
144
|
+
export function mapError<E, E1>(f: (e: E) => E1, __tsplusTrace?: string) {
|
|
145
|
+
return <R, A>(self: Result<R, E, A>): Result<R, E1, A> => {
|
|
146
|
+
return self.matchType({
|
|
147
|
+
Blocked: (br, c) => Result.blocked(br, c.mapError(f)),
|
|
148
|
+
Done: Result.done,
|
|
149
|
+
Fail: (cause) => Result.fail(cause.map(f)),
|
|
150
|
+
});
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* @tsplus pipeable fncts.query.Result mapErrorCause
|
|
156
|
+
*/
|
|
157
|
+
export function mapErrorCause<E, E1>(f: (cause: Cause<E>) => Cause<E1>, __tsplusTrace?: string) {
|
|
158
|
+
return <R, A>(self: Result<R, E, A>): Result<R, E1, A> => {
|
|
159
|
+
return self.matchType({
|
|
160
|
+
Blocked: (br, c) => Result.blocked(br, c.mapErrorCause(f)),
|
|
161
|
+
Done: Result.done,
|
|
162
|
+
Fail: (cause) => Result.fail(f(cause)),
|
|
163
|
+
});
|
|
164
|
+
};
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
/**
|
|
168
|
+
* @tsplus static fncts.query.ResultOps collectAllConcurrent
|
|
169
|
+
*/
|
|
170
|
+
export function collectAllConcurrent<R, E, A>(
|
|
171
|
+
self: Iterable<Result<R, E, A>>,
|
|
172
|
+
__tsplusTrace?: string,
|
|
173
|
+
): Result<R, E, Conc<A>> {
|
|
174
|
+
const [blocked, done, fails] = self.zipWithIndex.foldLeft(
|
|
175
|
+
[
|
|
176
|
+
Conc.empty<readonly [BlockedRequests<R>, Continue<R, E, A>, number]>(),
|
|
177
|
+
Conc.empty<readonly [A, number]>(),
|
|
178
|
+
Conc.empty<readonly [Cause<E>, number]>(),
|
|
179
|
+
] as const,
|
|
180
|
+
([blocked, done, fails], [index, result]) =>
|
|
181
|
+
result.matchType({
|
|
182
|
+
Blocked: (br, c) => [blocked.append([br, c, index] as const), done, fails] as const,
|
|
183
|
+
Done: (a) => [blocked, done.append([a, index] as const), fails] as const,
|
|
184
|
+
Fail: (e) => [blocked, done, fails.append([e, index] as const)] as const,
|
|
185
|
+
}),
|
|
186
|
+
);
|
|
187
|
+
|
|
188
|
+
if (blocked.isEmpty && fails.isEmpty) {
|
|
189
|
+
return Result.done(done.map(([a]) => a));
|
|
190
|
+
} else if (fails.isEmpty) {
|
|
191
|
+
const blockedRequests = blocked
|
|
192
|
+
.map(([br]) => br)
|
|
193
|
+
.foldLeft(BlockedRequests.empty<R>(), (b, a) => BlockedRequests.both(b, a));
|
|
194
|
+
|
|
195
|
+
const cont = Continue.collectAllConcurrent(blocked.map(([_, cont]) => cont)).map((as) => {
|
|
196
|
+
const array = Array(as.length);
|
|
197
|
+
as.zip(blocked.map(([cont]) => cont)).forEachWithIndex((i, a) => {
|
|
198
|
+
array[i] = a;
|
|
199
|
+
});
|
|
200
|
+
done.forEachWithIndex((i, a) => {
|
|
201
|
+
array[i] = a;
|
|
202
|
+
});
|
|
203
|
+
return Conc.from(array);
|
|
204
|
+
});
|
|
205
|
+
return Result.blocked<R, E, Conc<A>>(blockedRequests, cont);
|
|
206
|
+
} else {
|
|
207
|
+
return Result.fail(fails.map(([cause]) => cause).foldLeft(Cause.empty(), (b, a) => Cause.both(b, a)));
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
/**
|
|
212
|
+
* @tsplus pipeable fncts.query.Result contramapEnvironment
|
|
213
|
+
*/
|
|
214
|
+
export function contramapEnvironment<R0, R>(
|
|
215
|
+
f: Described<(_: Environment<R0>) => Environment<R>>,
|
|
216
|
+
__tsplusTrace?: string,
|
|
217
|
+
) {
|
|
218
|
+
return <E, A>(self: Result<R, E, A>): Result<R0, E, A> => {
|
|
219
|
+
return self.matchType({
|
|
220
|
+
Blocked: (br, cont) => Result.blocked(br.contramapEnvironment(f), cont.contramapEnvironment(f)),
|
|
221
|
+
Done: (a) => Result.done(a),
|
|
222
|
+
Fail: (e) => Result.fail(e),
|
|
223
|
+
});
|
|
224
|
+
};
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
/**
|
|
228
|
+
* @tsplus static fncts.query.ResultOps fromEither
|
|
229
|
+
*/
|
|
230
|
+
export function fromEither<E, A>(either: Either<E, A>): Result<never, E, A> {
|
|
231
|
+
return either.match(
|
|
232
|
+
(e) => Result.fail(Cause.fail(e)),
|
|
233
|
+
(a) => Result.done(a),
|
|
234
|
+
);
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
/**
|
|
238
|
+
* @tsplus static fncts.query.ResultOps fromExit
|
|
239
|
+
*/
|
|
240
|
+
export function fromExit<E, A>(exit: Exit<E, A>): Result<never, E, A> {
|
|
241
|
+
return exit.match(Result.fail, Result.done);
|
|
242
|
+
}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import type { DataSource } from "@fncts/query/DataSource";
|
|
2
|
+
import type { BlockedRequest } from "@fncts/query/internal/BlockedRequest";
|
|
3
|
+
|
|
4
|
+
export const SequentialTypeId = Symbol.for("fncts.query.Sequential");
|
|
5
|
+
export type SequentialTypeId = typeof SequentialTypeId;
|
|
6
|
+
|
|
7
|
+
export const SequentialVariance = Symbol.for("fncts.query.Sequential.Variance");
|
|
8
|
+
export type SequentialVariance = typeof SequentialVariance;
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* @tsplus type fncts.query.Sequential
|
|
12
|
+
* @tsplus companion fncts.query.SequentialOps
|
|
13
|
+
*/
|
|
14
|
+
export class Sequential<R> {
|
|
15
|
+
readonly [SequentialTypeId]: SequentialTypeId = SequentialTypeId;
|
|
16
|
+
declare [SequentialVariance]: {
|
|
17
|
+
readonly _R: (_: never) => R;
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
constructor(readonly map: HashMap<DataSource<any, any>, Conc<Conc<BlockedRequest<any>>>>) {}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* @tsplus pipeable fncts.query.Sequential concat
|
|
25
|
+
*/
|
|
26
|
+
export function concat<R1>(that: Sequential<R1>) {
|
|
27
|
+
return <R>(self: Sequential<R>): Sequential<R | R1> => {
|
|
28
|
+
return new Sequential(
|
|
29
|
+
that.map.foldLeftWithIndex(self.map, (k, map, v) =>
|
|
30
|
+
map.set(
|
|
31
|
+
k,
|
|
32
|
+
map.get(k).match(
|
|
33
|
+
() => v,
|
|
34
|
+
(requests) => requests.concat(v),
|
|
35
|
+
),
|
|
36
|
+
),
|
|
37
|
+
),
|
|
38
|
+
);
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* @tsplus getter fncts.query.Sequential isEmpty
|
|
44
|
+
*/
|
|
45
|
+
export function isEmpty<R>(self: Sequential<R>): boolean {
|
|
46
|
+
return self.map.isEmpty;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* @tsplus getter fncts.query.Sequential keys
|
|
51
|
+
*/
|
|
52
|
+
export function keys<R>(self: Sequential<R>): Iterable<DataSource<R, any>> {
|
|
53
|
+
return self.map.keys;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* @tsplus getter fncts.query.Sequential toIterable
|
|
58
|
+
*/
|
|
59
|
+
export function toIterable<R>(
|
|
60
|
+
self: Sequential<R>,
|
|
61
|
+
): Iterable<readonly [DataSource<R, any>, Conc<Conc<BlockedRequest<any>>>]> {
|
|
62
|
+
return self.map;
|
|
63
|
+
}
|