@typed/fx 2.0.0-beta.2 → 2.0.0-beta.4
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/dist/Fx/Fx.d.ts +2 -2
- package/dist/Fx/Fx.d.ts.map +1 -1
- package/dist/Fx/Fx.js +5 -5
- package/dist/Fx/combinators/catch.d.ts.map +1 -1
- package/dist/Fx/combinators/keyed.js +4 -4
- package/dist/Fx/combinators/provide.d.ts +9 -9
- package/dist/Fx/combinators/provide.d.ts.map +1 -1
- package/dist/Fx/combinators/provide.js +5 -5
- package/dist/Fx/combinators/scan.js +2 -2
- package/dist/Fx/combinators/switchMap.js +4 -4
- package/dist/Fx/combinators/unwrap.d.ts +1 -1
- package/dist/Fx/combinators/unwrap.d.ts.map +1 -1
- package/dist/Fx/constructors/make.js +2 -2
- package/dist/Fx/run/observe.d.ts.map +1 -1
- package/dist/Fx/run/observe.js +4 -4
- package/dist/Push/Push.d.ts +6 -6
- package/dist/Push/Push.d.ts.map +1 -1
- package/dist/Push/Push.js +3 -3
- package/dist/RefSubject/RefArray.d.ts.map +1 -1
- package/dist/RefSubject/RefArray.js +3 -6
- package/dist/RefSubject/RefChunk.d.ts.map +1 -1
- package/dist/RefSubject/RefChunk.js +3 -2
- package/dist/RefSubject/RefDateTime.d.ts.map +1 -1
- package/dist/RefSubject/RefDateTime.js +1 -1
- package/dist/RefSubject/RefGraph.d.ts.map +1 -1
- package/dist/RefSubject/RefGraph.js +3 -4
- package/dist/RefSubject/RefHashMap.js +2 -2
- package/dist/RefSubject/RefRecord.d.ts.map +1 -1
- package/dist/RefSubject/RefRecord.js +4 -7
- package/dist/RefSubject/RefSubject.d.ts +3 -3
- package/dist/RefSubject/RefSubject.d.ts.map +1 -1
- package/dist/RefSubject/RefSubject.js +8 -8
- package/dist/Sink/Sink.d.ts +4 -4
- package/dist/Sink/Sink.d.ts.map +1 -1
- package/dist/Sink/Sink.js +4 -4
- package/dist/Sink/combinators.js +1 -1
- package/dist/Subject/Subject.d.ts +3 -3
- package/dist/Subject/Subject.d.ts.map +1 -1
- package/dist/Subject/Subject.js +3 -3
- package/dist/Versioned/Versioned.d.ts +2 -2
- package/dist/Versioned/Versioned.d.ts.map +1 -1
- package/dist/Versioned/Versioned.js +4 -4
- package/package.json +13 -13
- package/src/Fx/Fx.ts +6 -6
- package/src/Fx/combinators/catch.ts +20 -25
- package/src/Fx/combinators/keyed.ts +4 -4
- package/src/Fx/combinators/provide.ts +15 -15
- package/src/Fx/combinators/scan.ts +2 -2
- package/src/Fx/combinators/switchMap.ts +4 -4
- package/src/Fx/combinators/unwrap.ts +1 -1
- package/src/Fx/constructors/make.ts +2 -2
- package/src/Fx/run/observe.ts +5 -5
- package/src/Fx.provide-combinators.test.ts +2 -2
- package/src/Push/Push.ts +34 -13
- package/src/RefSubject/RefArray.ts +8 -7
- package/src/RefSubject/RefChunk.ts +7 -2
- package/src/RefSubject/RefDateTime.test.ts +3 -3
- package/src/RefSubject/RefDateTime.ts +2 -5
- package/src/RefSubject/RefGraph.ts +3 -4
- package/src/RefSubject/RefHashMap.ts +2 -2
- package/src/RefSubject/RefRecord.ts +8 -6
- package/src/RefSubject/RefSubject.ts +12 -14
- package/src/Sink/Sink.ts +7 -7
- package/src/Sink/combinators.ts +1 -1
- package/src/Subject/Subject.ts +8 -9
- package/src/Versioned/Versioned.ts +6 -8
|
@@ -65,7 +65,7 @@ export const scanEffect: {
|
|
|
65
65
|
): Fx<S, E | E2, R | R2> =>
|
|
66
66
|
make<S, E | E2, R | R2>(<RSink>(sink: Sink<S, E | E2, RSink>) =>
|
|
67
67
|
Effect.gen(function* () {
|
|
68
|
-
const services = yield* Effect.
|
|
68
|
+
const services = yield* Effect.context<R | R2 | RSink>();
|
|
69
69
|
yield* sink.onSuccess(initial);
|
|
70
70
|
yield* fx.run(
|
|
71
71
|
sinkLoopEffect(sink, initial, (s, a) =>
|
|
@@ -73,7 +73,7 @@ export const scanEffect: {
|
|
|
73
73
|
f(s, a),
|
|
74
74
|
Effect.catchCause((cause) => sink.onFailure(cause).pipe(Effect.as(s))),
|
|
75
75
|
Effect.map((next) => [next, next] as const),
|
|
76
|
-
Effect.
|
|
76
|
+
Effect.provideContext(services),
|
|
77
77
|
),
|
|
78
78
|
),
|
|
79
79
|
);
|
|
@@ -2,7 +2,7 @@ import * as Effect from "effect/Effect";
|
|
|
2
2
|
import * as Fiber from "effect/Fiber";
|
|
3
3
|
import { dual } from "effect/Function";
|
|
4
4
|
import * as Scope from "effect/Scope";
|
|
5
|
-
import * as
|
|
5
|
+
import * as Context from "effect/Context";
|
|
6
6
|
import * as SyncronizedRef from "effect/SynchronizedRef";
|
|
7
7
|
import { make as makeSink } from "../../Sink/Sink.js";
|
|
8
8
|
import { make } from "../constructors/make.js";
|
|
@@ -28,12 +28,12 @@ export const switchMap: FlatMapLike = dual(
|
|
|
28
28
|
): Fx<B, E | E2, R | R2 | Scope.Scope> =>
|
|
29
29
|
make<B, E | E2, R | R2 | Scope.Scope>(
|
|
30
30
|
Effect.fn(function* (sink) {
|
|
31
|
-
const ctx = yield* Effect.
|
|
32
|
-
const scope =
|
|
31
|
+
const ctx = yield* Effect.context<R2 | Scope.Scope>();
|
|
32
|
+
const scope = Context.get(ctx, Scope.Scope);
|
|
33
33
|
const fiberRef = yield* SyncronizedRef.make<Fiber.Fiber<unknown, never> | null>(null);
|
|
34
34
|
|
|
35
35
|
const next = (value: A) =>
|
|
36
|
-
Effect.forkIn(Effect.
|
|
36
|
+
Effect.forkIn(Effect.provideContext(f(value).run(sink), ctx), scope, {
|
|
37
37
|
startImmediately: false,
|
|
38
38
|
uninterruptible: false,
|
|
39
39
|
});
|
|
@@ -10,7 +10,7 @@ import type { Fx } from "../Fx.js";
|
|
|
10
10
|
* @since 1.0.0
|
|
11
11
|
* @category combinators
|
|
12
12
|
*/
|
|
13
|
-
export const unwrap = <A, E, R, E2, R2>(
|
|
13
|
+
export const unwrap = <A = never, E = never, R = never, E2 = never, R2 = never>(
|
|
14
14
|
effect: Effect.Effect<Fx<A, E, R>, E2, R2>,
|
|
15
15
|
): Fx<A, E | E2, R | R2> =>
|
|
16
16
|
make<A, E | E2, R | R2>((sink) =>
|
|
@@ -75,7 +75,7 @@ export const callback = <A, E = never, R = never>(
|
|
|
75
75
|
withEarlyExit(
|
|
76
76
|
sink,
|
|
77
77
|
Effect.fn(function* <RSink = never>(sink: Sink.WithEarlyExit<A, E, RSink>) {
|
|
78
|
-
const services = yield* Effect.
|
|
78
|
+
const services = yield* Effect.context<R | RSink>();
|
|
79
79
|
const runFork = Effect.runForkWith(services);
|
|
80
80
|
const controller = new AbortController();
|
|
81
81
|
yield* Scope.addFinalizer(
|
|
@@ -94,7 +94,7 @@ export const callback = <A, E = never, R = never>(
|
|
|
94
94
|
};
|
|
95
95
|
|
|
96
96
|
const effect = run(emit);
|
|
97
|
-
if (effect) yield* Scope.addFinalizer(scope, Effect.
|
|
97
|
+
if (effect) yield* Scope.addFinalizer(scope, Effect.provideContext(effect, services));
|
|
98
98
|
return yield* Effect.never;
|
|
99
99
|
}),
|
|
100
100
|
),
|
package/src/Fx/run/observe.ts
CHANGED
|
@@ -4,11 +4,11 @@ import {
|
|
|
4
4
|
callback,
|
|
5
5
|
catchCause,
|
|
6
6
|
failCause,
|
|
7
|
-
|
|
7
|
+
forkScoped,
|
|
8
8
|
isEffect,
|
|
9
9
|
matchCauseEffect,
|
|
10
10
|
runForkWith,
|
|
11
|
-
|
|
11
|
+
contextWith,
|
|
12
12
|
sync,
|
|
13
13
|
void as void_,
|
|
14
14
|
} from "effect/Effect";
|
|
@@ -45,7 +45,7 @@ export const observe: {
|
|
|
45
45
|
fx: Fx<A, E, R>,
|
|
46
46
|
f: (value: A) => void | Effect<unknown, E2, R2>,
|
|
47
47
|
): Effect<unknown, E | E2, R | R2> =>
|
|
48
|
-
|
|
48
|
+
contextWith((services) =>
|
|
49
49
|
callback<void, E | E2, R | R2>((resume) => {
|
|
50
50
|
const onFailure = (cause: Cause<E | E2>) => sync(() => resume(failCause(cause)));
|
|
51
51
|
const onSuccess = (value: A) => {
|
|
@@ -84,7 +84,7 @@ export const drain = <A, E, R>(fx: Fx<A, E, R>): Effect<void, E, R> => observe(f
|
|
|
84
84
|
* @category runners
|
|
85
85
|
*/
|
|
86
86
|
export const drainLayer = <A, E, R>(fx: Fx<A, E, R>): Layer<never, E, Exclude<R, Scope>> =>
|
|
87
|
-
effectDiscard(
|
|
87
|
+
effectDiscard(forkScoped(drain(fx)));
|
|
88
88
|
|
|
89
89
|
/**
|
|
90
90
|
* Observes the values of an `Fx` stream using a callback function and returns a `Layer`.
|
|
@@ -110,5 +110,5 @@ export const observeLayer: {
|
|
|
110
110
|
<A, E, R, E2 = never, R2 = never>(
|
|
111
111
|
fx: Fx<A, E, R>,
|
|
112
112
|
f: (value: A) => void | Effect<unknown, E2, R2>,
|
|
113
|
-
): Layer<never, E | E2, Exclude<R | R2, Scope>> => effectDiscard(observe(fx, f)),
|
|
113
|
+
): Layer<never, E | E2, Exclude<R | R2, Scope>> => effectDiscard(forkScoped(observe(fx, f))),
|
|
114
114
|
);
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { assert, describe, it } from "vitest";
|
|
2
2
|
import * as Effect from "effect/Effect";
|
|
3
3
|
import { Fx } from "./index.js";
|
|
4
|
-
import * as
|
|
4
|
+
import * as Context from "effect/Context";
|
|
5
5
|
|
|
6
|
-
const Foo =
|
|
6
|
+
const Foo = Context.Service<{ readonly n: number }>("Test/Foo");
|
|
7
7
|
|
|
8
8
|
describe("Fx provideService", () => {
|
|
9
9
|
it("provides a single service and Fx can use it", () =>
|
package/src/Push/Push.ts
CHANGED
|
@@ -11,7 +11,7 @@ import * as Layer from "effect/Layer";
|
|
|
11
11
|
import * as Option from "effect/Option";
|
|
12
12
|
import { pipeArguments } from "effect/Pipeable";
|
|
13
13
|
import type * as Scope from "effect/Scope";
|
|
14
|
-
import * as
|
|
14
|
+
import * as Context from "effect/Context";
|
|
15
15
|
import * as Fx from "../Fx/index.js";
|
|
16
16
|
import { FxTypeId } from "../Fx/TypeId.js";
|
|
17
17
|
import * as Sink from "../Sink.js";
|
|
@@ -68,7 +68,7 @@ export namespace Push {
|
|
|
68
68
|
Self
|
|
69
69
|
> {
|
|
70
70
|
readonly id: Id;
|
|
71
|
-
readonly service:
|
|
71
|
+
readonly service: Context.Service<Self, Push<A, E, never, B, E2, never>>;
|
|
72
72
|
readonly make: <R = never, R2 = never>(
|
|
73
73
|
sink: Sink.Sink<A, E, R>,
|
|
74
74
|
fx: Fx.Fx<B, E2, R2>,
|
|
@@ -201,13 +201,20 @@ export const mapInput: {
|
|
|
201
201
|
f: (c: C) => Sink.Success<P>,
|
|
202
202
|
): (
|
|
203
203
|
push: P,
|
|
204
|
-
) => Push<
|
|
204
|
+
) => Push<
|
|
205
|
+
Sink.Services<P>,
|
|
206
|
+
Sink.Error<P>,
|
|
207
|
+
C,
|
|
208
|
+
Fx.Fx.Services<P>,
|
|
209
|
+
Fx.Fx.Error<P>,
|
|
210
|
+
Fx.Fx.Success<P>
|
|
211
|
+
>;
|
|
205
212
|
|
|
206
213
|
<P extends Push.Any, C>(
|
|
207
214
|
push: P,
|
|
208
215
|
f: (c: C) => Sink.Sink.Success<P>,
|
|
209
216
|
): Push<
|
|
210
|
-
Sink.Sink.
|
|
217
|
+
Sink.Sink.Services<P>,
|
|
211
218
|
Sink.Sink.Error<P>,
|
|
212
219
|
C,
|
|
213
220
|
Fx.Fx.Services<P>,
|
|
@@ -215,7 +222,7 @@ export const mapInput: {
|
|
|
215
222
|
Fx.Fx.Success<P>
|
|
216
223
|
>;
|
|
217
224
|
} = dual(2, function mapInput<P extends Push.Any, C>(push: P, f: (c: C) => Sink.Success<P>): Push<
|
|
218
|
-
Sink.
|
|
225
|
+
Sink.Services<P>,
|
|
219
226
|
Sink.Error<P>,
|
|
220
227
|
C,
|
|
221
228
|
Fx.Fx.Services<P>,
|
|
@@ -259,7 +266,14 @@ export const filterInput: {
|
|
|
259
266
|
f: (a: A) => boolean,
|
|
260
267
|
): <P extends Push.Any>(
|
|
261
268
|
push: P,
|
|
262
|
-
) => Push<
|
|
269
|
+
) => Push<
|
|
270
|
+
Sink.Services<P>,
|
|
271
|
+
Sink.Error<P>,
|
|
272
|
+
A,
|
|
273
|
+
Fx.Fx.Services<P>,
|
|
274
|
+
Fx.Fx.Error<P>,
|
|
275
|
+
Fx.Fx.Success<P>
|
|
276
|
+
>;
|
|
263
277
|
<A, E, R, B, E2, R2>(
|
|
264
278
|
push: Push<A, E, R, B, E2, R2>,
|
|
265
279
|
f: (a: A) => boolean,
|
|
@@ -308,7 +322,14 @@ export const filterMapInput: {
|
|
|
308
322
|
f: (c: C) => Option.Option<A>,
|
|
309
323
|
): <P extends Push.Any>(
|
|
310
324
|
push: P,
|
|
311
|
-
) => Push<
|
|
325
|
+
) => Push<
|
|
326
|
+
C,
|
|
327
|
+
Sink.Error<P>,
|
|
328
|
+
Sink.Services<P>,
|
|
329
|
+
Fx.Fx.Success<P>,
|
|
330
|
+
Fx.Fx.Error<P>,
|
|
331
|
+
Fx.Fx.Services<P>
|
|
332
|
+
>;
|
|
312
333
|
<A, E, R, B, E2, R2, C>(
|
|
313
334
|
push: Push<A, E, R, B, E2, R2>,
|
|
314
335
|
f: (c: C) => Option.Option<A>,
|
|
@@ -1015,7 +1036,7 @@ export const mapAccumEffect: {
|
|
|
1015
1036
|
|
|
1016
1037
|
export function Service<Self, A, E = never, B = never, E2 = never>() {
|
|
1017
1038
|
return <const Id extends string>(id: Id): Push.Class<Self, Id, A, E, B, E2> => {
|
|
1018
|
-
const service =
|
|
1039
|
+
const service = Context.Service<Self, Push<A, E, never, B, E2, never>>(id);
|
|
1019
1040
|
|
|
1020
1041
|
// eslint-disable-next-line @typescript-eslint/no-extraneous-class
|
|
1021
1042
|
return class PushService {
|
|
@@ -1028,17 +1049,17 @@ export function Service<Self, A, E = never, B = never, E2 = never>() {
|
|
|
1028
1049
|
): Layer.Layer<Self, never, Exclude<R | R2, Scope.Scope>> =>
|
|
1029
1050
|
Layer.effect(
|
|
1030
1051
|
service,
|
|
1031
|
-
Effect.
|
|
1052
|
+
Effect.context<R | R2>().pipe(
|
|
1032
1053
|
Effect.map((services) =>
|
|
1033
1054
|
make(
|
|
1034
1055
|
Sink.make(
|
|
1035
|
-
(cause) => Effect.
|
|
1036
|
-
(value) => Effect.
|
|
1056
|
+
(cause) => Effect.provideContext(sink.onFailure(cause), services),
|
|
1057
|
+
(value) => Effect.provideContext(sink.onSuccess(value), services),
|
|
1037
1058
|
),
|
|
1038
1059
|
Fx.make(<RSink>(sink: Sink.Sink<B, E2, RSink>) =>
|
|
1039
|
-
Effect.
|
|
1060
|
+
Effect.context<RSink>().pipe(
|
|
1040
1061
|
Effect.flatMap((services2) =>
|
|
1041
|
-
Effect.
|
|
1062
|
+
Effect.provideContext(fx.run(sink), Context.merge(services, services2)),
|
|
1042
1063
|
),
|
|
1043
1064
|
),
|
|
1044
1065
|
),
|
|
@@ -14,7 +14,7 @@ import type * as Order from "effect/Order";
|
|
|
14
14
|
import type * as Scope from "effect/Scope";
|
|
15
15
|
import type * as Fx from "../Fx/index.js";
|
|
16
16
|
import * as RefSubject from "./RefSubject.js";
|
|
17
|
-
import {
|
|
17
|
+
import { Result } from "effect";
|
|
18
18
|
|
|
19
19
|
/**
|
|
20
20
|
* A RefArray is a RefSubject that is specialized over an array of values.
|
|
@@ -211,10 +211,7 @@ export const insertAt: {
|
|
|
211
211
|
<A, E, R>(ref: RefArray<A, E, R>, index: number, a: A): Effect.Effect<ReadonlyArray<A>, E, R>;
|
|
212
212
|
} = dual(3, function insertAt<A, E, R>(ref: RefArray<A, E, R>, index: number, a: A) {
|
|
213
213
|
return RefSubject.update(ref, (as) =>
|
|
214
|
-
Option.getOrElse(
|
|
215
|
-
...as,
|
|
216
|
-
a,
|
|
217
|
-
]),
|
|
214
|
+
Option.getOrElse(ReadonlyArray.insertAt(as, index, a), () => [...as, a]),
|
|
218
215
|
);
|
|
219
216
|
});
|
|
220
217
|
|
|
@@ -292,7 +289,9 @@ export const modifyAt: {
|
|
|
292
289
|
f: (a: A) => A,
|
|
293
290
|
): Effect.Effect<ReadonlyArray<A>, E, R>;
|
|
294
291
|
} = dual(3, function modifyAt<A, E, R>(ref: RefArray<A, E, R>, index: number, f: (a: A) => A) {
|
|
295
|
-
return RefSubject.update(ref, (values) =>
|
|
292
|
+
return RefSubject.update(ref, (values) =>
|
|
293
|
+
Option.getOrElse(ReadonlyArray.modify(values, index, f), () => values),
|
|
294
|
+
);
|
|
296
295
|
});
|
|
297
296
|
|
|
298
297
|
/**
|
|
@@ -373,7 +372,9 @@ export const replaceAt: {
|
|
|
373
372
|
<A>(index: number, a: A): <E, R>(ref: RefArray<A, E, R>) => Effect.Effect<ReadonlyArray<A>, E, R>;
|
|
374
373
|
<A, E, R>(ref: RefArray<A, E, R>, index: number, a: A): Effect.Effect<ReadonlyArray<A>, E, R>;
|
|
375
374
|
} = dual(3, function replaceAt<A, E, R>(ref: RefArray<A, E, R>, index: number, a: A) {
|
|
376
|
-
return RefSubject.update(ref, (values) =>
|
|
375
|
+
return RefSubject.update(ref, (values) =>
|
|
376
|
+
Option.getOrElse(ReadonlyArray.replace(values, index, a), () => values),
|
|
377
|
+
);
|
|
377
378
|
});
|
|
378
379
|
|
|
379
380
|
/**
|
|
@@ -8,6 +8,7 @@ import type * as Effect from "effect/Effect";
|
|
|
8
8
|
import { equals } from "effect/Equal";
|
|
9
9
|
import type { Equivalence } from "effect/Equivalence";
|
|
10
10
|
import { dual } from "effect/Function";
|
|
11
|
+
import * as Option from "effect/Option";
|
|
11
12
|
import type * as Order from "effect/Order";
|
|
12
13
|
import type * as Scope from "effect/Scope";
|
|
13
14
|
import type * as Fx from "../Fx/index.js";
|
|
@@ -183,7 +184,9 @@ export const modifyAt: {
|
|
|
183
184
|
f: (a: A) => A,
|
|
184
185
|
): Effect.Effect<Chunk.Chunk<A>, E, R>;
|
|
185
186
|
} = dual(3, function modifyAt<A, E, R>(ref: RefChunk<A, E, R>, index: number, f: (a: A) => A) {
|
|
186
|
-
return RefSubject.update(ref, (chunk) =>
|
|
187
|
+
return RefSubject.update(ref, (chunk) =>
|
|
188
|
+
Option.getOrElse(Chunk.modify(chunk, index, f), () => chunk),
|
|
189
|
+
);
|
|
187
190
|
});
|
|
188
191
|
|
|
189
192
|
/**
|
|
@@ -195,7 +198,9 @@ export const replaceAt: {
|
|
|
195
198
|
<A>(index: number, a: A): <E, R>(ref: RefChunk<A, E, R>) => Effect.Effect<Chunk.Chunk<A>, E, R>;
|
|
196
199
|
<A, E, R>(ref: RefChunk<A, E, R>, index: number, a: A): Effect.Effect<Chunk.Chunk<A>, E, R>;
|
|
197
200
|
} = dual(3, function replaceAt<A, E, R>(ref: RefChunk<A, E, R>, index: number, a: A) {
|
|
198
|
-
return RefSubject.update(ref, (chunk) =>
|
|
201
|
+
return RefSubject.update(ref, (chunk) =>
|
|
202
|
+
Option.getOrElse(Chunk.replace(chunk, index, a), () => chunk),
|
|
203
|
+
);
|
|
199
204
|
});
|
|
200
205
|
|
|
201
206
|
/**
|
|
@@ -10,21 +10,21 @@ describe("RefDateTime", () => {
|
|
|
10
10
|
const value = DateTime.nowUnsafe();
|
|
11
11
|
const ref = yield* RefDateTime.make(value);
|
|
12
12
|
const current = yield* ref;
|
|
13
|
-
expect(current
|
|
13
|
+
expect(DateTime.toEpochMillis(current)).toBe(DateTime.toEpochMillis(value));
|
|
14
14
|
}).pipe(Effect.scoped, Effect.runPromise));
|
|
15
15
|
|
|
16
16
|
it("adds duration", () =>
|
|
17
17
|
Effect.gen(function* () {
|
|
18
18
|
const ref = yield* RefDateTime.make(DateTime.makeUnsafe(0));
|
|
19
19
|
const result = yield* RefDateTime.addDuration(ref, Duration.seconds(5));
|
|
20
|
-
expect(result
|
|
20
|
+
expect(DateTime.toEpochMillis(result)).toBe(5000);
|
|
21
21
|
}).pipe(Effect.scoped, Effect.runPromise));
|
|
22
22
|
|
|
23
23
|
it("subtracts duration", () =>
|
|
24
24
|
Effect.gen(function* () {
|
|
25
25
|
const ref = yield* RefDateTime.make(DateTime.makeUnsafe(10000));
|
|
26
26
|
const result = yield* RefDateTime.subtractDuration(ref, Duration.seconds(3));
|
|
27
|
-
expect(result
|
|
27
|
+
expect(DateTime.toEpochMillis(result)).toBe(7000);
|
|
28
28
|
}).pipe(Effect.scoped, Effect.runPromise));
|
|
29
29
|
|
|
30
30
|
it("gets epoch milliseconds", () =>
|
|
@@ -183,10 +183,7 @@ export const subtractDuration: {
|
|
|
183
183
|
ref: RefDateTime<E, R>,
|
|
184
184
|
duration: Duration.Input,
|
|
185
185
|
): RefSubject.Computed<DateTime.DateTime, E, R>;
|
|
186
|
-
} = dual(2, function subtractDuration<
|
|
187
|
-
E,
|
|
188
|
-
R,
|
|
189
|
-
>(ref: RefDateTime<E, R>, duration: Duration.Input) {
|
|
186
|
+
} = dual(2, function subtractDuration<E, R>(ref: RefDateTime<E, R>, duration: Duration.Input) {
|
|
190
187
|
return RefSubject.map(ref, (self) => DateTime.subtractDuration(self, duration));
|
|
191
188
|
});
|
|
192
189
|
|
|
@@ -196,7 +193,7 @@ export const subtractDuration: {
|
|
|
196
193
|
* @category computed
|
|
197
194
|
*/
|
|
198
195
|
export const epochMillis = <E, R>(ref: RefDateTime<E, R>): RefSubject.Computed<number, E, R> =>
|
|
199
|
-
RefSubject.map(ref, (self) => self
|
|
196
|
+
RefSubject.map(ref, (self) => DateTime.toEpochMillis(self));
|
|
200
197
|
|
|
201
198
|
/**
|
|
202
199
|
* Format the current state of a RefDateTime.
|
|
@@ -7,7 +7,6 @@ import type * as Effect from "effect/Effect";
|
|
|
7
7
|
import { equals } from "effect/Equal";
|
|
8
8
|
import { dual } from "effect/Function";
|
|
9
9
|
import * as Graph from "effect/Graph";
|
|
10
|
-
import * as Option from "effect/Option";
|
|
11
10
|
import type * as Scope from "effect/Scope";
|
|
12
11
|
import type * as Fx from "../Fx/index.js";
|
|
13
12
|
import * as RefSubject from "./RefSubject.js";
|
|
@@ -596,7 +595,7 @@ export const getEdge: {
|
|
|
596
595
|
Err,
|
|
597
596
|
R,
|
|
598
597
|
>(ref: RefGraph<N, E, T, Err, R>, edgeIndex: Graph.EdgeIndex) {
|
|
599
|
-
return RefSubject.filterMap(ref, (g) =>
|
|
598
|
+
return RefSubject.filterMap(ref, (g) => Graph.getEdge(g, edgeIndex));
|
|
600
599
|
});
|
|
601
600
|
|
|
602
601
|
/**
|
|
@@ -621,7 +620,7 @@ export const findNode: {
|
|
|
621
620
|
Err,
|
|
622
621
|
R,
|
|
623
622
|
>(ref: RefGraph<N, E, T, Err, R>, predicate: (data: N) => boolean) {
|
|
624
|
-
return RefSubject.filterMap(ref, (g) =>
|
|
623
|
+
return RefSubject.filterMap(ref, (g) => Graph.findNode(g, predicate));
|
|
625
624
|
});
|
|
626
625
|
|
|
627
626
|
/**
|
|
@@ -646,5 +645,5 @@ export const findEdge: {
|
|
|
646
645
|
Err,
|
|
647
646
|
R,
|
|
648
647
|
>(ref: RefGraph<N, E, T, Err, R>, predicate: (edge: E) => boolean) {
|
|
649
|
-
return RefSubject.filterMap(ref, (g) =>
|
|
648
|
+
return RefSubject.filterMap(ref, (g) => Graph.findEdge(g, predicate));
|
|
650
649
|
});
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
|
|
6
6
|
import type * as Effect from "effect/Effect";
|
|
7
7
|
import { equals } from "effect/Equal";
|
|
8
|
-
import { dual
|
|
8
|
+
import { dual } from "effect/Function";
|
|
9
9
|
import * as HashMap from "effect/HashMap";
|
|
10
10
|
import * as Option from "effect/Option";
|
|
11
11
|
import type * as Scope from "effect/Scope";
|
|
@@ -470,5 +470,5 @@ export const findFirst: {
|
|
|
470
470
|
E,
|
|
471
471
|
R,
|
|
472
472
|
>(ref: RefHashMap<K, V, E, R>, predicate: (value: V, key: K) => boolean) {
|
|
473
|
-
return RefSubject.filterMap(ref,
|
|
473
|
+
return RefSubject.filterMap(ref, (g) => HashMap.findFirst(g, predicate));
|
|
474
474
|
});
|
|
@@ -100,7 +100,7 @@ export const modify: {
|
|
|
100
100
|
E,
|
|
101
101
|
R,
|
|
102
102
|
>(ref: RefRecord<K, V, E, R>, key: K, f: (v: V) => V) {
|
|
103
|
-
return RefSubject.update(ref, (r) => Record.modify(r, key, f)
|
|
103
|
+
return RefSubject.update(ref, (r) => Option.getOrElse(Record.modify(r, key, f), () => r));
|
|
104
104
|
});
|
|
105
105
|
|
|
106
106
|
/**
|
|
@@ -124,7 +124,7 @@ export const replace: {
|
|
|
124
124
|
E,
|
|
125
125
|
R,
|
|
126
126
|
>(ref: RefRecord<K, V, E, R>, key: K, value: V) {
|
|
127
|
-
return RefSubject.update(ref, (r) => Record.replace(r, key, value)
|
|
127
|
+
return RefSubject.update(ref, (r) => Option.getOrElse(Record.replace(r, key, value), () => r));
|
|
128
128
|
});
|
|
129
129
|
|
|
130
130
|
/**
|
|
@@ -592,7 +592,7 @@ export const findFirst: {
|
|
|
592
592
|
E,
|
|
593
593
|
R,
|
|
594
594
|
>(ref: RefRecord<K, V, E, R>, predicate: (value: V, key: K) => boolean) {
|
|
595
|
-
return RefSubject.filterMap(ref, (r) =>
|
|
595
|
+
return RefSubject.filterMap(ref, (r) => Record.findFirst(r, predicate));
|
|
596
596
|
});
|
|
597
597
|
|
|
598
598
|
/**
|
|
@@ -612,8 +612,10 @@ export const pop: {
|
|
|
612
612
|
): RefSubject.Filtered<[V, Record.ReadonlyRecord<K, V>], E, R>;
|
|
613
613
|
} = dual(2, function pop<K extends string, V, E, R>(ref: RefRecord<K, V, E, R>, key: K) {
|
|
614
614
|
return RefSubject.filterMap(ref, (r) => {
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
615
|
+
return Option.map(
|
|
616
|
+
Record.pop(r, key),
|
|
617
|
+
([value, next]) =>
|
|
618
|
+
[value, next as Record.ReadonlyRecord<K, V>] as [V, Record.ReadonlyRecord<K, V>],
|
|
619
|
+
);
|
|
618
620
|
});
|
|
619
621
|
});
|
|
@@ -16,7 +16,7 @@ import { sum } from "effect/Number";
|
|
|
16
16
|
import * as Option from "effect/Option";
|
|
17
17
|
import { pipeArguments } from "effect/Pipeable";
|
|
18
18
|
import * as Scope from "effect/Scope";
|
|
19
|
-
import * as
|
|
19
|
+
import * as Context from "effect/Context";
|
|
20
20
|
import * as Stream from "effect/Stream";
|
|
21
21
|
import { compact as fxCompact } from "../Fx/combinators/compact.js";
|
|
22
22
|
import { continueWith } from "../Fx/combinators/continueWith.js";
|
|
@@ -291,7 +291,7 @@ export declare namespace RefSubject {
|
|
|
291
291
|
export interface Service<Self, Id extends string, A, E> extends RefSubject<A, E, Self> {
|
|
292
292
|
readonly id: Id;
|
|
293
293
|
|
|
294
|
-
readonly service:
|
|
294
|
+
readonly service: Context.Service<Self, RefSubject<A, E>>;
|
|
295
295
|
|
|
296
296
|
readonly make: <R = never>(
|
|
297
297
|
value: A | Effect.Effect<A, E, R> | Fx<A, E, R>,
|
|
@@ -307,14 +307,12 @@ export declare namespace RefSubject {
|
|
|
307
307
|
new (): RefSubject.Service<Self, Id, A, E>;
|
|
308
308
|
}
|
|
309
309
|
}
|
|
310
|
-
export const CurrentComputedBehavior =
|
|
310
|
+
export const CurrentComputedBehavior = Context.Reference("@typed/fx/CurrentComputedBehavior", {
|
|
311
311
|
defaultValue: (): "one" | "multiple" => "multiple",
|
|
312
312
|
});
|
|
313
313
|
|
|
314
|
-
const checkIsMultiple = (
|
|
315
|
-
ctx
|
|
316
|
-
): ctx is ServiceMap.ServiceMap<"multiple"> =>
|
|
317
|
-
ServiceMap.getReferenceUnsafe(ctx, CurrentComputedBehavior) === "multiple";
|
|
314
|
+
const checkIsMultiple = (ctx: Context.Context<any>): ctx is Context.Context<"multiple"> =>
|
|
315
|
+
Context.getReferenceUnsafe(ctx, CurrentComputedBehavior) === "multiple";
|
|
318
316
|
|
|
319
317
|
class ComputedImpl<R0, E0, A, E, R, E2, R2, C, E3, R3>
|
|
320
318
|
extends Versioned.VersionedTransform<
|
|
@@ -352,7 +350,7 @@ class ComputedImpl<R0, E0, A, E, R, E2, R2, C, E3, R3>
|
|
|
352
350
|
|
|
353
351
|
this._computed = Subject.hold(
|
|
354
352
|
unwrap(
|
|
355
|
-
Effect.map(Effect.
|
|
353
|
+
Effect.map(Effect.context(), (ctx) => {
|
|
356
354
|
if (checkIsMultiple(ctx)) {
|
|
357
355
|
return fromYieldable(input).pipe(
|
|
358
356
|
continueWith(() => input),
|
|
@@ -426,7 +424,7 @@ class FilteredImpl<R0, E0, A, E, R, E2, R2, C, E3, R3>
|
|
|
426
424
|
|
|
427
425
|
this._computed = Subject.hold(
|
|
428
426
|
unwrap(
|
|
429
|
-
Effect.map(Effect.
|
|
427
|
+
Effect.map(Effect.context(), (ctx) => {
|
|
430
428
|
if (checkIsMultiple(ctx)) {
|
|
431
429
|
return fromYieldable(input).pipe(
|
|
432
430
|
continueWith(() => input),
|
|
@@ -457,14 +455,14 @@ class FilteredImpl<R0, E0, A, E, R, E2, R2, C, E3, R3>
|
|
|
457
455
|
class RefSubjectCore<A, E, R, R2> {
|
|
458
456
|
readonly initial: Effect.Effect<A, E, R>;
|
|
459
457
|
readonly subject: Subject.HoldSubjectImpl<A, E>;
|
|
460
|
-
readonly services:
|
|
458
|
+
readonly services: Context.Context<R2>;
|
|
461
459
|
readonly scope: Scope.Closeable;
|
|
462
460
|
readonly deferredRef: DeferredRef.DeferredRef<E, A>;
|
|
463
461
|
readonly semaphore: Semaphore.Semaphore;
|
|
464
462
|
constructor(
|
|
465
463
|
initial: Effect.Effect<A, E, R>,
|
|
466
464
|
subject: Subject.HoldSubjectImpl<A, E>,
|
|
467
|
-
services:
|
|
465
|
+
services: Context.Context<R2>,
|
|
468
466
|
scope: Scope.Closeable,
|
|
469
467
|
deferredRef: DeferredRef.DeferredRef<E, A>,
|
|
470
468
|
semaphore: Semaphore.Semaphore,
|
|
@@ -766,8 +764,8 @@ function makeCore<A, E, R>(
|
|
|
766
764
|
deferredRef?: DeferredRef.DeferredRef<E, A>,
|
|
767
765
|
) {
|
|
768
766
|
return Effect.gen(function* () {
|
|
769
|
-
const services = yield* Effect.
|
|
770
|
-
const scope = yield* Scope.fork(
|
|
767
|
+
const services = yield* Effect.context<R | Scope.Scope>();
|
|
768
|
+
const scope = yield* Scope.fork(Context.get(services, Scope.Scope));
|
|
771
769
|
const id = yield* Effect.withFiber((fiber) => Effect.succeed(fiber.id));
|
|
772
770
|
const subject = new Subject.HoldSubjectImpl<A, E>();
|
|
773
771
|
const core = new RefSubjectCore(
|
|
@@ -1335,7 +1333,7 @@ const Variance: Fx.Variance<any, any, any> = {
|
|
|
1335
1333
|
|
|
1336
1334
|
export function Service<Self, A, E = never>() {
|
|
1337
1335
|
return <const Id extends string>(id: Id): RefSubject.Class<Self, Id, A, E> => {
|
|
1338
|
-
const service =
|
|
1336
|
+
const service = Context.Service<Self, RefSubject<A, E>>(id);
|
|
1339
1337
|
|
|
1340
1338
|
// eslint-disable-next-line @typescript-eslint/no-extraneous-class
|
|
1341
1339
|
return class RefSubjectService {
|
package/src/Sink/Sink.ts
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import type * as Cause from "effect/Cause";
|
|
2
2
|
import type { Effect } from "effect/Effect";
|
|
3
|
-
import { flatMap, map, provide,
|
|
3
|
+
import { flatMap, map, provide, context } from "effect/Effect";
|
|
4
4
|
import type { Layer } from "effect/Layer";
|
|
5
5
|
import { effect } from "effect/Layer";
|
|
6
6
|
import type { Ref } from "effect/Ref";
|
|
7
7
|
import type { Scope } from "effect/Scope";
|
|
8
|
-
import * as
|
|
8
|
+
import * as Context from "effect/Context";
|
|
9
9
|
|
|
10
10
|
/**
|
|
11
11
|
* A Sink is a consumer of values. It consists of two effectful callbacks:
|
|
@@ -46,11 +46,11 @@ export declare namespace Sink {
|
|
|
46
46
|
* @since 1.0.0
|
|
47
47
|
* @category type-level
|
|
48
48
|
*/
|
|
49
|
-
export type
|
|
49
|
+
export type Services<T> = T extends Sink<infer _A, infer _E, infer _R> ? _R : never;
|
|
50
50
|
|
|
51
51
|
export interface Service<Self, Id extends string, A, E> extends Sink<A, E, Self> {
|
|
52
52
|
readonly id: Id;
|
|
53
|
-
readonly service:
|
|
53
|
+
readonly service: Context.Service<Self, Sink<A, E>>;
|
|
54
54
|
readonly make: <R = never>(
|
|
55
55
|
onFailure: (cause: Cause.Cause<E>) => Effect<unknown, never, R>,
|
|
56
56
|
onSuccess: (value: A) => Effect<unknown, never, R>,
|
|
@@ -64,7 +64,7 @@ export declare namespace Sink {
|
|
|
64
64
|
|
|
65
65
|
export type Success<T> = Sink.Success<T>;
|
|
66
66
|
export type Error<T> = Sink.Error<T>;
|
|
67
|
-
export type
|
|
67
|
+
export type Services<T> = Sink.Services<T>;
|
|
68
68
|
|
|
69
69
|
/**
|
|
70
70
|
* Creates a Sink from success and failure callbacks.
|
|
@@ -124,7 +124,7 @@ export declare namespace Sink {
|
|
|
124
124
|
|
|
125
125
|
export function Service<Self, A, E = never>() {
|
|
126
126
|
return <const Id extends string>(id: Id): Sink.Class<Self, Id, A, E> => {
|
|
127
|
-
const service =
|
|
127
|
+
const service = Context.Service<Self, Sink<A, E>>(id);
|
|
128
128
|
|
|
129
129
|
// eslint-disable-next-line @typescript-eslint/no-extraneous-class
|
|
130
130
|
return class SinkService {
|
|
@@ -137,7 +137,7 @@ export function Service<Self, A, E = never>() {
|
|
|
137
137
|
): Layer<Self, never, Exclude<R | R2, Scope>> =>
|
|
138
138
|
effect(
|
|
139
139
|
service,
|
|
140
|
-
map(
|
|
140
|
+
map(context<R | R2>(), (context) =>
|
|
141
141
|
make(
|
|
142
142
|
(cause) => provide(onFailure(cause), context),
|
|
143
143
|
(value) => provide(onSuccess(value), context),
|
package/src/Sink/combinators.ts
CHANGED
|
@@ -219,7 +219,7 @@ export function withEarlyExit<A, E, R, R2>(
|
|
|
219
219
|
params: { signal: AbortSignal; scheduler: Scheduler },
|
|
220
220
|
) => Effect.Effect<unknown, never, R2>,
|
|
221
221
|
): Effect.Effect<void, never, R | R2> {
|
|
222
|
-
return Effect.
|
|
222
|
+
return Effect.contextWith((services) =>
|
|
223
223
|
Effect.callback<unknown, never, R2>(function (this: Scheduler, resume, signal) {
|
|
224
224
|
let exited = false;
|
|
225
225
|
const earlyExit = Effect.sync<void>(() => {
|