@fncts/io 0.0.34 → 0.0.36
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/Fiber/FiberRuntime.d.ts +7 -7
- package/Fiber/constructors.d.ts +5 -0
- package/IO/api/all.d.ts +41 -0
- package/IO/api/concurrency.d.ts +11 -0
- package/IO/api/interrupt.d.ts +1 -1
- package/IO/api/raceWith.d.ts +2 -1
- package/IO/api.d.ts +7 -2
- package/IO/definition.d.ts +103 -127
- package/IO.d.ts +1 -0
- package/Push/api.d.ts +86 -36
- package/Push/definition.d.ts +28 -13
- package/Push/internal.d.ts +7 -11
- package/RefSubject/Atomic.d.ts +8 -11
- package/RefSubject/Synchronized/definition.d.ts +4 -6
- package/RefSubject/api.d.ts +0 -1
- package/RefSubject/definition.d.ts +6 -8
- package/STM/definition.d.ts +19 -2
- package/Sink/api.d.ts +24 -24
- package/Subject/Atomic.d.ts +4 -6
- package/Subject/definition.d.ts +2 -2
- package/_cjs/Channel/api/runScoped.cjs +1 -1
- package/_cjs/Channel/api/runScoped.cjs.map +1 -1
- package/_cjs/Channel/api.cjs +2 -2
- package/_cjs/Channel/api.cjs.map +1 -1
- package/_cjs/Fiber/FiberRuntime.cjs +110 -98
- package/_cjs/Fiber/FiberRuntime.cjs.map +1 -1
- package/_cjs/Fiber/constructors.cjs +10 -2
- package/_cjs/Fiber/constructors.cjs.map +1 -1
- package/_cjs/Future/api.cjs +1 -1
- package/_cjs/Future/api.cjs.map +1 -1
- package/_cjs/IO/api/all.cjs +33 -0
- package/_cjs/IO/api/all.cjs.map +1 -0
- package/_cjs/IO/api/asyncIO.cjs +1 -1
- package/_cjs/IO/api/asyncIO.cjs.map +1 -1
- package/_cjs/IO/api/bracketExit.cjs +1 -1
- package/_cjs/IO/api/bracketExit.cjs.map +1 -1
- package/_cjs/IO/api/concurrency.cjs +25 -4
- package/_cjs/IO/api/concurrency.cjs.map +1 -1
- package/_cjs/IO/api/disconnect.cjs +1 -1
- package/_cjs/IO/api/disconnect.cjs.map +1 -1
- package/_cjs/IO/api/foreachConcurrent.cjs +1 -1
- package/_cjs/IO/api/foreachConcurrent.cjs.map +1 -1
- package/_cjs/IO/api/foreachExec.cjs +1 -1
- package/_cjs/IO/api/foreachExec.cjs.map +1 -1
- package/_cjs/IO/api/forkIn.cjs +1 -1
- package/_cjs/IO/api/forkIn.cjs.map +1 -1
- package/_cjs/IO/api/forkScoped.cjs +1 -1
- package/_cjs/IO/api/forkScoped.cjs.map +1 -1
- package/_cjs/IO/api/fulfill.cjs +1 -1
- package/_cjs/IO/api/fulfill.cjs.map +1 -1
- package/_cjs/IO/api/interrupt.cjs +18 -6
- package/_cjs/IO/api/interrupt.cjs.map +1 -1
- package/_cjs/IO/api/raceWith.cjs +4 -4
- package/_cjs/IO/api/raceWith.cjs.map +1 -1
- package/_cjs/IO/api/timeout.cjs +8 -5
- package/_cjs/IO/api/timeout.cjs.map +1 -1
- package/_cjs/IO/api/zipConcurrent.cjs +1 -1
- package/_cjs/IO/api/zipConcurrent.cjs.map +1 -1
- package/_cjs/IO/api.cjs +78 -20
- package/_cjs/IO/api.cjs.map +1 -1
- package/_cjs/IO/definition.cjs +14 -191
- package/_cjs/IO/definition.cjs.map +1 -1
- package/_cjs/IO.cjs +11 -0
- package/_cjs/IO.cjs.map +1 -1
- package/_cjs/Layer/MemoMap.cjs +1 -1
- package/_cjs/Layer/MemoMap.cjs.map +1 -1
- package/_cjs/Layer/api.cjs.map +1 -1
- package/_cjs/Push/api.cjs +238 -168
- package/_cjs/Push/api.cjs.map +1 -1
- package/_cjs/Push/definition.cjs +12 -13
- package/_cjs/Push/definition.cjs.map +1 -1
- package/_cjs/Push/internal.cjs +37 -29
- package/_cjs/Push/internal.cjs.map +1 -1
- package/_cjs/RefSubject/Atomic.cjs +15 -19
- package/_cjs/RefSubject/Atomic.cjs.map +1 -1
- package/_cjs/RefSubject/Synchronized/definition.cjs +9 -10
- package/_cjs/RefSubject/Synchronized/definition.cjs.map +1 -1
- package/_cjs/RefSubject/api.cjs +5 -6
- package/_cjs/RefSubject/api.cjs.map +1 -1
- package/_cjs/RefSubject/definition.cjs.map +1 -1
- package/_cjs/STM/api/atomically.cjs +1 -1
- package/_cjs/STM/api/atomically.cjs.map +1 -1
- package/_cjs/STM/api.cjs +2 -2
- package/_cjs/STM/api.cjs.map +1 -1
- package/_cjs/STM/definition.cjs +1 -1
- package/_cjs/STM/definition.cjs.map +1 -1
- package/_cjs/ScopedRef/api.cjs +2 -2
- package/_cjs/ScopedRef/api.cjs.map +1 -1
- package/_cjs/Semaphore.cjs +1 -1
- package/_cjs/Semaphore.cjs.map +1 -1
- package/_cjs/Sink/api.cjs +13 -13
- package/_cjs/Sink/api.cjs.map +1 -1
- package/_cjs/Subject/Atomic.cjs +4 -5
- package/_cjs/Subject/Atomic.cjs.map +1 -1
- package/_cjs/TReentrantLock/api.cjs +2 -2
- package/_cjs/TReentrantLock/api.cjs.map +1 -1
- package/_cjs/TSemaphore/api.cjs +1 -1
- package/_cjs/TSemaphore/api.cjs.map +1 -1
- package/_cjs/collection/immutable/Conc/dropUntilIO.cjs +12 -17
- package/_cjs/collection/immutable/Conc/dropUntilIO.cjs.map +1 -1
- package/_cjs/collection/immutable/Conc/dropWhileIO.cjs +12 -17
- package/_cjs/collection/immutable/Conc/dropWhileIO.cjs.map +1 -1
- package/_cjs/collection/immutable/Conc/filterIO.cjs +2 -12
- package/_cjs/collection/immutable/Conc/filterIO.cjs.map +1 -1
- package/_cjs/collection/immutable/Conc/mapIO.cjs +3 -9
- package/_cjs/collection/immutable/Conc/mapIO.cjs.map +1 -1
- package/_cjs/collection/immutable/Conc/takeWhileIO.cjs +11 -27
- package/_cjs/collection/immutable/Conc/takeWhileIO.cjs.map +1 -1
- package/_mjs/Channel/api/runScoped.mjs +1 -1
- package/_mjs/Channel/api/runScoped.mjs.map +1 -1
- package/_mjs/Channel/api.mjs +2 -2
- package/_mjs/Channel/api.mjs.map +1 -1
- package/_mjs/Fiber/FiberRuntime.mjs +111 -100
- package/_mjs/Fiber/FiberRuntime.mjs.map +1 -1
- package/_mjs/Fiber/constructors.mjs +7 -1
- package/_mjs/Fiber/constructors.mjs.map +1 -1
- package/_mjs/Future/api.mjs +1 -1
- package/_mjs/Future/api.mjs.map +1 -1
- package/_mjs/IO/api/all.mjs +24 -0
- package/_mjs/IO/api/all.mjs.map +1 -0
- package/_mjs/IO/api/asyncIO.mjs +1 -1
- package/_mjs/IO/api/asyncIO.mjs.map +1 -1
- package/_mjs/IO/api/bracketExit.mjs +1 -1
- package/_mjs/IO/api/bracketExit.mjs.map +1 -1
- package/_mjs/IO/api/concurrency.mjs +19 -2
- package/_mjs/IO/api/concurrency.mjs.map +1 -1
- package/_mjs/IO/api/disconnect.mjs +1 -1
- package/_mjs/IO/api/disconnect.mjs.map +1 -1
- package/_mjs/IO/api/foreachConcurrent.mjs +1 -1
- package/_mjs/IO/api/foreachConcurrent.mjs.map +1 -1
- package/_mjs/IO/api/foreachExec.mjs +1 -1
- package/_mjs/IO/api/foreachExec.mjs.map +1 -1
- package/_mjs/IO/api/forkIn.mjs +1 -1
- package/_mjs/IO/api/forkIn.mjs.map +1 -1
- package/_mjs/IO/api/forkScoped.mjs +1 -1
- package/_mjs/IO/api/forkScoped.mjs.map +1 -1
- package/_mjs/IO/api/fulfill.mjs +1 -1
- package/_mjs/IO/api/fulfill.mjs.map +1 -1
- package/_mjs/IO/api/interrupt.mjs +19 -7
- package/_mjs/IO/api/interrupt.mjs.map +1 -1
- package/_mjs/IO/api/raceWith.mjs +4 -4
- package/_mjs/IO/api/raceWith.mjs.map +1 -1
- package/_mjs/IO/api/timeout.mjs +8 -5
- package/_mjs/IO/api/timeout.mjs.map +1 -1
- package/_mjs/IO/api/zipConcurrent.mjs +1 -1
- package/_mjs/IO/api/zipConcurrent.mjs.map +1 -1
- package/_mjs/IO/api.mjs +78 -23
- package/_mjs/IO/api.mjs.map +1 -1
- package/_mjs/IO/definition.mjs +12 -181
- package/_mjs/IO/definition.mjs.map +1 -1
- package/_mjs/IO.mjs +1 -0
- package/_mjs/IO.mjs.map +1 -1
- package/_mjs/Layer/MemoMap.mjs +1 -1
- package/_mjs/Layer/MemoMap.mjs.map +1 -1
- package/_mjs/Layer/api.mjs.map +1 -1
- package/_mjs/Push/api.mjs +223 -166
- package/_mjs/Push/api.mjs.map +1 -1
- package/_mjs/Push/definition.mjs +9 -10
- package/_mjs/Push/definition.mjs.map +1 -1
- package/_mjs/Push/internal.mjs +33 -22
- package/_mjs/Push/internal.mjs.map +1 -1
- package/_mjs/RefSubject/Atomic.mjs +15 -19
- package/_mjs/RefSubject/Atomic.mjs.map +1 -1
- package/_mjs/RefSubject/Synchronized/definition.mjs +9 -10
- package/_mjs/RefSubject/Synchronized/definition.mjs.map +1 -1
- package/_mjs/RefSubject/api.mjs +6 -7
- package/_mjs/RefSubject/api.mjs.map +1 -1
- package/_mjs/RefSubject/definition.mjs.map +1 -1
- package/_mjs/STM/api/atomically.mjs +1 -1
- package/_mjs/STM/api/atomically.mjs.map +1 -1
- package/_mjs/STM/api.mjs +2 -2
- package/_mjs/STM/api.mjs.map +1 -1
- package/_mjs/STM/definition.mjs +1 -1
- package/_mjs/STM/definition.mjs.map +1 -1
- package/_mjs/ScopedRef/api.mjs +2 -2
- package/_mjs/ScopedRef/api.mjs.map +1 -1
- package/_mjs/Semaphore.mjs +1 -1
- package/_mjs/Semaphore.mjs.map +1 -1
- package/_mjs/Sink/api.mjs +10 -10
- package/_mjs/Sink/api.mjs.map +1 -1
- package/_mjs/Subject/Atomic.mjs +4 -5
- package/_mjs/Subject/Atomic.mjs.map +1 -1
- package/_mjs/TReentrantLock/api.mjs +2 -2
- package/_mjs/TReentrantLock/api.mjs.map +1 -1
- package/_mjs/TSemaphore/api.mjs +1 -1
- package/_mjs/TSemaphore/api.mjs.map +1 -1
- package/_mjs/collection/immutable/Conc/dropUntilIO.mjs +12 -17
- package/_mjs/collection/immutable/Conc/dropUntilIO.mjs.map +1 -1
- package/_mjs/collection/immutable/Conc/dropWhileIO.mjs +12 -17
- package/_mjs/collection/immutable/Conc/dropWhileIO.mjs.map +1 -1
- package/_mjs/collection/immutable/Conc/filterIO.mjs +2 -12
- package/_mjs/collection/immutable/Conc/filterIO.mjs.map +1 -1
- package/_mjs/collection/immutable/Conc/mapIO.mjs +3 -9
- package/_mjs/collection/immutable/Conc/mapIO.mjs.map +1 -1
- package/_mjs/collection/immutable/Conc/takeWhileIO.mjs +11 -27
- package/_mjs/collection/immutable/Conc/takeWhileIO.mjs.map +1 -1
- package/_src/Channel/api.ts +3 -3
- package/_src/Fiber/FiberRuntime.ts +76 -75
- package/_src/Fiber/constructors.ts +5 -0
- package/_src/IO/api/all.ts +64 -0
- package/_src/IO/api/concurrency.ts +33 -0
- package/_src/IO/api/foreachExec.ts +2 -2
- package/_src/IO/api/interrupt.ts +20 -7
- package/_src/IO/api/raceWith.ts +4 -2
- package/_src/IO/api/timeout.ts +21 -1
- package/_src/IO/api.ts +79 -27
- package/_src/IO/definition.ts +155 -200
- package/_src/IO.ts +1 -0
- package/_src/Layer/api.ts +0 -1
- package/_src/Push/api.ts +305 -304
- package/_src/Push/definition.ts +19 -17
- package/_src/Push/internal.ts +63 -31
- package/_src/RefSubject/Atomic.ts +16 -22
- package/_src/RefSubject/Synchronized/definition.ts +6 -9
- package/_src/RefSubject/api.ts +9 -12
- package/_src/RefSubject/definition.ts +6 -8
- package/_src/STM/api.ts +0 -5
- package/_src/STM/definition.ts +8 -2
- package/_src/Sink/api.ts +9 -9
- package/_src/Subject/Atomic.ts +6 -8
- package/_src/Subject/definition.ts +2 -2
- package/_src/collection/immutable/Conc/dropUntilIO.ts +18 -15
- package/_src/collection/immutable/Conc/dropWhileIO.ts +18 -17
- package/_src/collection/immutable/Conc/filterIO.ts +1 -11
- package/_src/collection/immutable/Conc/mapIO.ts +2 -9
- package/_src/collection/immutable/Conc/takeWhileIO.ts +19 -28
- package/collection/immutable/Conc/filterIO.d.ts +1 -1
- package/collection/immutable/Conc/mapIO.d.ts +1 -1
- package/collection/immutable/Conc/takeWhileIO.d.ts +1 -1
- package/package.json +2 -2
package/_src/Push/api.ts
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
1
|
-
import type { _A, _E, _R } from "@fncts/base/types";
|
|
2
|
-
|
|
3
1
|
import { AtomicReference } from "@fncts/base/internal/AtomicReference";
|
|
2
|
+
import { IO } from "@fncts/io/IO";
|
|
3
|
+
import { withExhaust, withSwitch, withUnboundedConcurrency } from "@fncts/io/Push/internal";
|
|
4
4
|
|
|
5
|
-
import {
|
|
6
|
-
import { earlyExit, onEarlyExit } from "./internal.js";
|
|
5
|
+
import { Push, PushTypeId, PushVariance, Sink } from "./definition.js";
|
|
7
6
|
|
|
8
7
|
/**
|
|
9
8
|
* @tsplus pipeable fncts.io.Push as
|
|
@@ -14,36 +13,73 @@ export function as<B>(b: Lazy<B>) {
|
|
|
14
13
|
};
|
|
15
14
|
}
|
|
16
15
|
|
|
16
|
+
interface UnsafeSink<E, A> {
|
|
17
|
+
event: (value: A) => void;
|
|
18
|
+
error: (cause: Cause<E>) => void;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* @tsplus static fncts.io.PushOps asyncInterrupt
|
|
23
|
+
*/
|
|
24
|
+
export function asyncInterrupt<R, E, A>(
|
|
25
|
+
make: (emitter: UnsafeSink<E, A>) => Either<IO<R, never, void>, Push<R, E, A>>,
|
|
26
|
+
): Push<R, E, A> {
|
|
27
|
+
return Push<R, E, A>(
|
|
28
|
+
<R1>(sink: Sink<R | R1, E, A>) =>
|
|
29
|
+
Do((Δ) => {
|
|
30
|
+
const future = Δ(Future.make<never, void>());
|
|
31
|
+
const scope = Δ(IO.scope);
|
|
32
|
+
const runtime = Δ(IO.runtime<R | R1>());
|
|
33
|
+
const unsafeSink: UnsafeSink<E, A> = {
|
|
34
|
+
event: (value) => runtime.unsafeRunOrFork(sink.event(value).forkIn(scope)),
|
|
35
|
+
error: (cause) => runtime.unsafeRunOrFork(sink.error(cause).fulfill(future).forkIn(scope)),
|
|
36
|
+
};
|
|
37
|
+
const eitherPush = Δ(IO(make(unsafeSink)));
|
|
38
|
+
Δ(
|
|
39
|
+
eitherPush.match(
|
|
40
|
+
(canceller) => future.await.onInterrupt(canceller),
|
|
41
|
+
(push) => push.run(sink),
|
|
42
|
+
),
|
|
43
|
+
);
|
|
44
|
+
}).scoped,
|
|
45
|
+
);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* @tsplus static fncts.io.PushOps async
|
|
50
|
+
*/
|
|
51
|
+
export function async<E, A>(make: (sink: UnsafeSink<E, A>) => void): Push<never, E, A> {
|
|
52
|
+
return Push.asyncInterrupt((sink) => {
|
|
53
|
+
make(sink);
|
|
54
|
+
return Either.left(IO.unit);
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
|
|
17
58
|
/**
|
|
18
59
|
* @tsplus static fncts.io.PushOps combineLatest
|
|
19
60
|
*/
|
|
20
61
|
export function combineLatest<A extends ReadonlyArray<Push<any, any, any>>>(
|
|
21
62
|
streams: [...A],
|
|
22
|
-
): Push<
|
|
63
|
+
): Push<Push.EnvironmentOf<A[number]>, Push.ErrorOf<A[number]>, { [K in keyof A]: Push.ValueOf<A[K]> }>;
|
|
23
64
|
export function combineLatest<R, E, A>(streams: Iterable<Push<R, E, A>>): Push<R, E, ReadonlyArray<A>>;
|
|
24
65
|
export function combineLatest<R, E, A>(streams: Iterable<Push<R, E, A>>): Push<R, E, ReadonlyArray<A>> {
|
|
25
66
|
return Push((emitter) =>
|
|
26
67
|
Do((Δ) => {
|
|
27
68
|
const size = streams.size;
|
|
28
69
|
const ref: Array<A> = Δ(IO(Array(size)));
|
|
29
|
-
const latch = Δ(CountdownLatch(size));
|
|
30
70
|
const emitIfReady = IO(ref.filter((a) => a != null)).flatMap((as) =>
|
|
31
|
-
as.length === size ? emitter.
|
|
71
|
+
as.length === size ? emitter.event(as) : IO.unit,
|
|
32
72
|
);
|
|
33
73
|
Δ(
|
|
34
|
-
IO.
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
latch.countDown,
|
|
42
|
-
),
|
|
43
|
-
).forkScoped,
|
|
74
|
+
IO.foreachConcurrent(streams.zipWithIndex, ([i, stream]) =>
|
|
75
|
+
stream.run(
|
|
76
|
+
Sink(
|
|
77
|
+
(value) => IO((ref[i] = value)) > emitIfReady,
|
|
78
|
+
(cause) => emitter.error(cause),
|
|
79
|
+
),
|
|
80
|
+
),
|
|
44
81
|
),
|
|
45
82
|
);
|
|
46
|
-
Δ(latch.await > emitter.end);
|
|
47
83
|
}),
|
|
48
84
|
);
|
|
49
85
|
}
|
|
@@ -62,28 +98,7 @@ export function combineLatestWith<A, R1, E1, B, C>(that: Push<R1, E1, B>, f: (a:
|
|
|
62
98
|
*/
|
|
63
99
|
export function debounce(duration: Lazy<Duration>) {
|
|
64
100
|
return <R, E, A>(self: Push<R, E, A>): Push<R, E, A> => {
|
|
65
|
-
return
|
|
66
|
-
Do((Δ) => {
|
|
67
|
-
const ref = Δ(Ref.Synchronized.make<Fiber<never, unknown> | null>(null));
|
|
68
|
-
const latch = Δ(CountdownLatch(1));
|
|
69
|
-
Δ(
|
|
70
|
-
self.run(
|
|
71
|
-
Emitter(
|
|
72
|
-
(value) =>
|
|
73
|
-
ref.updateIO((previous) =>
|
|
74
|
-
Do((Δ) => {
|
|
75
|
-
Δ(IO.defer(previous ? previous.interrupt : latch.increment));
|
|
76
|
-
return Δ(IO.acquireRelease(emitter.emit(value).delay(duration), () => latch.countDown).forkScoped);
|
|
77
|
-
}),
|
|
78
|
-
),
|
|
79
|
-
(cause) => emitter.failCause(cause),
|
|
80
|
-
latch.countDown,
|
|
81
|
-
),
|
|
82
|
-
),
|
|
83
|
-
);
|
|
84
|
-
Δ(latch.await > emitter.end);
|
|
85
|
-
}),
|
|
86
|
-
);
|
|
101
|
+
return self.switchMapIO((a) => IO.succeedNow(a).delay(duration));
|
|
87
102
|
};
|
|
88
103
|
}
|
|
89
104
|
|
|
@@ -94,14 +109,90 @@ export function defer<R, E, A>(self: Lazy<Push<R, E, A>>): Push<R, E, A> {
|
|
|
94
109
|
return Push((emitter) => IO(self).flatMap((push) => push.run(emitter)));
|
|
95
110
|
}
|
|
96
111
|
|
|
112
|
+
/**
|
|
113
|
+
* @tsplus pipeable fncts.io.Push exhaustMap
|
|
114
|
+
*/
|
|
115
|
+
export function exhaustMap<A, R1, E1, B>(f: (a: A) => Push<R1, E1, B>) {
|
|
116
|
+
return <R, E>(self: Push<R, E, A>): Push<R | R1, E | E1, B> => {
|
|
117
|
+
return Push((sink) => withExhaust((fork) => self.run(Sink((a) => fork(f(a).run(sink)), sink.error))));
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* @tsplus pipeable fncts.io.Push exhaustMapIO
|
|
123
|
+
*/
|
|
124
|
+
export function exhaustMapIO<A, R1, E1, B>(f: (a: A) => IO<R1, E1, B>) {
|
|
125
|
+
return <R, E>(self: Push<R, E, A>): Push<R | R1, E | E1, B> => {
|
|
126
|
+
return self.exhaustMap((a) => Push.fromIO(f(a)));
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
/**
|
|
131
|
+
* @tsplus pipeable fncts.io.Push filterIO
|
|
132
|
+
*/
|
|
133
|
+
export function filterIO<A, R1, E1>(predicate: (a: A) => IO<R1, E1, boolean>) {
|
|
134
|
+
return <R, E>(self: Push<R, E, A>): Push<R | R1, E | E1, A> => {
|
|
135
|
+
return Push((sink) =>
|
|
136
|
+
self.run(
|
|
137
|
+
Sink(
|
|
138
|
+
(a) =>
|
|
139
|
+
predicate(a)
|
|
140
|
+
.flatMap((b) => (b ? sink.event(a) : IO.unit))
|
|
141
|
+
.catchAllCause(sink.error),
|
|
142
|
+
sink.error,
|
|
143
|
+
),
|
|
144
|
+
),
|
|
145
|
+
);
|
|
146
|
+
};
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
/**
|
|
150
|
+
* @tsplus pipeable fncts.io.Push filterMapIO
|
|
151
|
+
*/
|
|
152
|
+
export function filterMapIO<A, R1, E1, B>(f: (a: A) => IO<R1, E1, Maybe<B>>) {
|
|
153
|
+
return <R, E>(self: Push<R, E, A>): Push<R | R1, E | E1, B> => {
|
|
154
|
+
return Push((sink) =>
|
|
155
|
+
self.run(
|
|
156
|
+
Sink(
|
|
157
|
+
(a) =>
|
|
158
|
+
f(a)
|
|
159
|
+
.flatMap((mb) => mb.match(() => IO.unit, sink.event))
|
|
160
|
+
.catchAllCause(sink.error),
|
|
161
|
+
sink.error,
|
|
162
|
+
),
|
|
163
|
+
),
|
|
164
|
+
);
|
|
165
|
+
};
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
/**
|
|
169
|
+
* @tsplus pipeable fncts.io.Push filter
|
|
170
|
+
*/
|
|
171
|
+
export function filter<A, B extends A>(refinement: Refinement<A, B>): <R, E>(self: Push<R, E, A>) => Push<R, E, B>;
|
|
172
|
+
export function filter<A>(predicate: Predicate<A>): <R, E>(self: Push<R, E, A>) => Push<R, E, A>;
|
|
173
|
+
export function filter<A>(predicate: Predicate<A>) {
|
|
174
|
+
return <R, E>(self: Push<R, E, A>): Push<R, E, A> => {
|
|
175
|
+
return Push((sink) => self.run(Sink((a) => (predicate(a) ? sink.event(a) : IO.unit), sink.error)));
|
|
176
|
+
};
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
/**
|
|
180
|
+
* @tsplus pipeable fncts.io.Push filterMap
|
|
181
|
+
*/
|
|
182
|
+
export function filterMap<A, B>(f: (a: A) => Maybe<B>) {
|
|
183
|
+
return <R, E>(self: Push<R, E, A>): Push<R, E, B> => {
|
|
184
|
+
return Push((sink) => self.run(Sink((a) => f(a).match(() => IO.unit, sink.event), sink.error)));
|
|
185
|
+
};
|
|
186
|
+
}
|
|
187
|
+
|
|
97
188
|
/**
|
|
98
189
|
* @tsplus pipeable fncts.io.Push flatMapConcurrentBounded
|
|
99
190
|
*/
|
|
100
191
|
export function flatMapConcurrentBounded<A, R1, E1, B>(f: (a: A) => Push<R1, E1, B>, concurrency: number) {
|
|
101
192
|
return <R, E>(self: Push<R, E, A>): Push<R | R1, E | E1, B> => {
|
|
102
|
-
return Push(<R2>(emitter:
|
|
193
|
+
return Push(<R2>(emitter: Sink<R | R1 | R2, E | E1, B>) =>
|
|
103
194
|
Do((Δ) => {
|
|
104
|
-
const semaphore = Δ(
|
|
195
|
+
const semaphore = Δ(Semaphore(concurrency));
|
|
105
196
|
Δ(self.flatMapConcurrentUnbounded((a) => f(a).transform((io) => semaphore.withPermit(io))).run(emitter));
|
|
106
197
|
}),
|
|
107
198
|
);
|
|
@@ -113,22 +204,7 @@ export function flatMapConcurrentBounded<A, R1, E1, B>(f: (a: A) => Push<R1, E1,
|
|
|
113
204
|
*/
|
|
114
205
|
export function flatMapConcurrentUnbounded<A, R1, E1, B>(f: (a: A) => Push<R1, E1, B>) {
|
|
115
206
|
return <R, E>(self: Push<R, E, A>): Push<R | R1, E | E1, B> => {
|
|
116
|
-
return Push((
|
|
117
|
-
Do((Δ) => {
|
|
118
|
-
const latch = Δ(CountdownLatch(1));
|
|
119
|
-
Δ(
|
|
120
|
-
self.run(
|
|
121
|
-
Emitter(
|
|
122
|
-
(value) =>
|
|
123
|
-
latch.increment > f(value).run(Emitter(emitter.emit, emitter.failCause, latch.countDown)).forkScoped,
|
|
124
|
-
emitter.failCause,
|
|
125
|
-
latch.countDown,
|
|
126
|
-
),
|
|
127
|
-
),
|
|
128
|
-
);
|
|
129
|
-
Δ(latch.await > emitter.end);
|
|
130
|
-
}),
|
|
131
|
-
);
|
|
207
|
+
return Push((sink) => withUnboundedConcurrency((fork) => self.run(Sink((a) => fork(f(a).run(sink)), sink.error))));
|
|
132
208
|
};
|
|
133
209
|
}
|
|
134
210
|
|
|
@@ -168,12 +244,11 @@ export function flatten<R, E, R1, E1, A>(self: Push<R, E, Push<R1, E1, A>>): Pus
|
|
|
168
244
|
* @tsplus static fncts.io.PushOps fromIO
|
|
169
245
|
*/
|
|
170
246
|
export function fromIO<R, E, A>(io: Lazy<IO<R, E, A>>): Push<R, E, A> {
|
|
171
|
-
return Push(
|
|
172
|
-
(
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
) > emitter.end,
|
|
247
|
+
return Push((emitter) =>
|
|
248
|
+
IO.defer(io).matchCauseIO(
|
|
249
|
+
(cause) => emitter.error(cause),
|
|
250
|
+
(value) => emitter.event(value),
|
|
251
|
+
),
|
|
177
252
|
);
|
|
178
253
|
}
|
|
179
254
|
|
|
@@ -181,17 +256,20 @@ export function fromIO<R, E, A>(io: Lazy<IO<R, E, A>>): Push<R, E, A> {
|
|
|
181
256
|
* @tsplus static fncts.io.PushOps fromAsyncIterable
|
|
182
257
|
*/
|
|
183
258
|
export function fromAsyncIterable<A>(iterable: AsyncIterable<A>): Push<never, never, A> {
|
|
184
|
-
return Push((
|
|
259
|
+
return Push(<R>(sink: Sink<R, never, A>) =>
|
|
260
|
+
IO.asyncIO<R, never, void>((cb) => IO.defer(fromAsyncIterableLoop(iterable[Symbol.asyncIterator](), sink, cb))),
|
|
261
|
+
);
|
|
185
262
|
}
|
|
186
263
|
|
|
187
264
|
function fromAsyncIterableLoop<A, R>(
|
|
188
265
|
iterator: AsyncIterator<A>,
|
|
189
|
-
|
|
266
|
+
sink: Sink<R, never, A>,
|
|
267
|
+
cb: (io: UIO<void>) => void,
|
|
190
268
|
__tsplusTrace?: string,
|
|
191
269
|
): IO<R, never, void> {
|
|
192
270
|
return IO.fromPromiseHalt(iterator.next).matchCauseIO(
|
|
193
|
-
(cause) =>
|
|
194
|
-
(result) => (result.done ?
|
|
271
|
+
(cause) => sink.error(cause),
|
|
272
|
+
(result) => (result.done ? IO(cb(IO.unit)) : sink.event(result.value) > fromAsyncIterableLoop(iterator, sink, cb)),
|
|
195
273
|
);
|
|
196
274
|
}
|
|
197
275
|
|
|
@@ -199,13 +277,19 @@ function fromAsyncIterableLoop<A, R>(
|
|
|
199
277
|
* @tsplus static fncts.io.PushOps fromIterable
|
|
200
278
|
*/
|
|
201
279
|
export function fromIterable<A>(iterable: Iterable<A>): Push<never, never, A> {
|
|
202
|
-
return Push((
|
|
280
|
+
return Push(<R>(sink: Sink<R, never, A>) =>
|
|
281
|
+
IO.asyncIO<R, never, void>((cb) => IO.defer(fromIterableLoop(iterable[Symbol.iterator](), sink, cb))),
|
|
282
|
+
);
|
|
203
283
|
}
|
|
204
284
|
|
|
205
|
-
function fromIterableLoop<A, R>(
|
|
285
|
+
function fromIterableLoop<A, R>(
|
|
286
|
+
iterator: Iterator<A>,
|
|
287
|
+
sink: Sink<R, never, A>,
|
|
288
|
+
cb: (io: UIO<void>) => void,
|
|
289
|
+
): IO<R, never, void> {
|
|
206
290
|
return IO.defer(() => {
|
|
207
291
|
const value = iterator.next();
|
|
208
|
-
return value.done ?
|
|
292
|
+
return value.done ? IO(cb(IO.unit)) : sink.event(value.value) > fromIterableLoop(iterator, sink, cb);
|
|
209
293
|
});
|
|
210
294
|
}
|
|
211
295
|
|
|
@@ -217,12 +301,11 @@ export function multicast<R, E, A>(self: Push<R, E, A>): Push<R, E, A> {
|
|
|
217
301
|
}
|
|
218
302
|
|
|
219
303
|
interface MulticastObserver<E, A> {
|
|
220
|
-
readonly
|
|
304
|
+
readonly sink: Sink<any, E, A>;
|
|
221
305
|
readonly environment: Environment<any>;
|
|
222
|
-
readonly future: Future<never, void>;
|
|
223
306
|
}
|
|
224
307
|
|
|
225
|
-
export class Multicast<R, E, A> implements Push<R, E, A>,
|
|
308
|
+
export class Multicast<R, E, A> implements Push<R, E, A>, Sink<never, E, A> {
|
|
226
309
|
readonly [PushTypeId]: PushTypeId = PushTypeId;
|
|
227
310
|
declare [PushVariance]: {
|
|
228
311
|
readonly _R: (_: never) => R;
|
|
@@ -233,67 +316,59 @@ export class Multicast<R, E, A> implements Push<R, E, A>, Emitter<never, E, A> {
|
|
|
233
316
|
protected fiber: Fiber<never, unknown> | undefined;
|
|
234
317
|
constructor(readonly push: Push<R, E, A>) {}
|
|
235
318
|
|
|
236
|
-
run<R1>(
|
|
319
|
+
run<R1>(sink: Sink<R1, E, A>): IO<R | R1, never, void> {
|
|
237
320
|
return Do((Δ) => {
|
|
238
321
|
const environment = Δ(IO.environment<R1>());
|
|
239
|
-
const future = Δ(Future.make<never, void>());
|
|
240
322
|
Δ(
|
|
241
323
|
IO.defer(() => {
|
|
242
|
-
|
|
243
|
-
if (this.
|
|
244
|
-
|
|
245
|
-
} else {
|
|
246
|
-
return this.push
|
|
247
|
-
.run(this)
|
|
248
|
-
.schedule(Schedule.asap)
|
|
249
|
-
.forkScoped.tap((fiber) => IO((this.fiber = fiber)));
|
|
324
|
+
let io: URIO<R, void> = IO.unit;
|
|
325
|
+
if (this.observers.push({ sink: sink, environment }) === 1) {
|
|
326
|
+
io = this.push.run(this).forkDaemon.flatMap((fiber) => IO((this.fiber = fiber)));
|
|
250
327
|
}
|
|
328
|
+
return io > this.fiber!.await.ensuring(this.removeSink(sink));
|
|
251
329
|
}),
|
|
252
330
|
);
|
|
253
|
-
return Δ(future.await);
|
|
254
331
|
});
|
|
255
332
|
}
|
|
256
333
|
|
|
257
|
-
|
|
258
|
-
return IO.defer(IO.foreachDiscard(this.observers.slice(), (observer) => this.
|
|
334
|
+
event(value: A) {
|
|
335
|
+
return IO.defer(IO.foreachDiscard(this.observers.slice(), (observer) => this.runValue(value, observer)));
|
|
259
336
|
}
|
|
260
337
|
|
|
261
|
-
|
|
262
|
-
return (
|
|
263
|
-
IO.defer(IO.foreachDiscard(this.observers.slice(), (observer) => this.runFailCause(cause, observer))) >
|
|
264
|
-
IO.defer(this.cleanup())
|
|
265
|
-
);
|
|
338
|
+
error(cause: Cause<E>) {
|
|
339
|
+
return IO.defer(IO.foreachDiscard(this.observers.slice(), (observer) => this.runError(cause, observer)));
|
|
266
340
|
}
|
|
267
341
|
|
|
268
|
-
|
|
269
|
-
return
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
342
|
+
protected runValue(value: A, observer: MulticastObserver<E, A>) {
|
|
343
|
+
return observer.sink
|
|
344
|
+
.event(value)
|
|
345
|
+
.provideEnvironment(observer.environment)
|
|
346
|
+
.catchAllCause(() => this.removeSink(observer.sink));
|
|
273
347
|
}
|
|
274
348
|
|
|
275
|
-
protected
|
|
276
|
-
return observer.
|
|
277
|
-
.
|
|
278
|
-
.
|
|
279
|
-
.
|
|
349
|
+
protected runError(cause: Cause<E>, observer: MulticastObserver<E, A>) {
|
|
350
|
+
return observer.sink
|
|
351
|
+
.error(cause)
|
|
352
|
+
.provideEnvironment(observer.environment)
|
|
353
|
+
.catchAllCause(() => this.removeSink(observer.sink));
|
|
280
354
|
}
|
|
281
355
|
|
|
282
|
-
protected
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
356
|
+
protected removeSink(sink: Sink<any, E, A>) {
|
|
357
|
+
return IO.defer(() => {
|
|
358
|
+
if (this.observers.length === 0) {
|
|
359
|
+
return IO.unit;
|
|
360
|
+
}
|
|
361
|
+
const index = this.observers.findIndex((observer) => observer.sink === sink);
|
|
362
|
+
if (index > -1) {
|
|
363
|
+
this.observers.splice(index, 1);
|
|
364
|
+
if (this.observers.length === 0) {
|
|
365
|
+
const interrupt = this.fiber!.interrupt;
|
|
366
|
+
this.fiber = undefined;
|
|
367
|
+
return interrupt;
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
return IO.unit;
|
|
371
|
+
});
|
|
297
372
|
}
|
|
298
373
|
}
|
|
299
374
|
|
|
@@ -305,87 +380,26 @@ export function hold<R, E, A>(self: Push<R, E, A>): Push<R, E, A> {
|
|
|
305
380
|
}
|
|
306
381
|
|
|
307
382
|
export class Hold<R, E, A> extends Multicast<R, E, A> {
|
|
308
|
-
readonly
|
|
309
|
-
protected pendingEmitters: Array<readonly [Emitter<unknown, E, A>, Array<A>]> = [];
|
|
310
|
-
protected scheduledFiber: Fiber<any, any> | null = null;
|
|
383
|
+
readonly current = new AtomicReference(Nothing<A>());
|
|
311
384
|
|
|
312
|
-
constructor(
|
|
385
|
+
constructor(public push: Push<R, E, A>) {
|
|
313
386
|
super(push);
|
|
314
387
|
}
|
|
315
388
|
|
|
316
|
-
run<R1>(
|
|
317
|
-
|
|
318
|
-
return this.scheduleFlush(emitter).flatMap(() => super.run(emitter));
|
|
319
|
-
}
|
|
389
|
+
run<R1>(sink: Sink<R1, E, A>): IO<R | R1, never, void> {
|
|
390
|
+
const current = this.current.get;
|
|
320
391
|
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
return emitter.emit(value.value).flatMap(() => super.run(emitter));
|
|
392
|
+
if (current.isJust()) {
|
|
393
|
+
return sink.event(current.value) > super.run(sink);
|
|
324
394
|
}
|
|
325
395
|
|
|
326
|
-
return super.run(
|
|
396
|
+
return super.run(sink);
|
|
327
397
|
}
|
|
328
398
|
|
|
329
|
-
|
|
399
|
+
event(value: A): IO<never, never, void> {
|
|
330
400
|
return IO.defer(() => {
|
|
331
|
-
this.
|
|
332
|
-
return
|
|
333
|
-
});
|
|
334
|
-
}
|
|
335
|
-
|
|
336
|
-
failCause(cause: Cause<E>) {
|
|
337
|
-
return IO.defer(this.flushPending().flatMap(() => super.failCause(cause)));
|
|
338
|
-
}
|
|
339
|
-
|
|
340
|
-
get end() {
|
|
341
|
-
return IO.defer(this.flushPending().flatMap(() => super.end));
|
|
342
|
-
}
|
|
343
|
-
|
|
344
|
-
protected shouldScheduleFlush() {
|
|
345
|
-
return this.value.get.isJust() && this.observers.length > 0;
|
|
346
|
-
}
|
|
347
|
-
|
|
348
|
-
protected scheduleFlush<R>(observer: Emitter<R, E, A>) {
|
|
349
|
-
this.pendingEmitters.push([
|
|
350
|
-
observer,
|
|
351
|
-
this.value.get.match(
|
|
352
|
-
() => [],
|
|
353
|
-
(a) => [a],
|
|
354
|
-
),
|
|
355
|
-
]);
|
|
356
|
-
|
|
357
|
-
const interrupt = this.scheduledFiber ? this.scheduledFiber.interruptAsFork(FiberId.none) : IO.unit;
|
|
358
|
-
this.scheduledFiber = null;
|
|
359
|
-
|
|
360
|
-
return (IO.yieldNow > interrupt.flatMap(() => this.flushPending())).forkScoped.tap((fiber) =>
|
|
361
|
-
IO((this.scheduledFiber = fiber)),
|
|
362
|
-
);
|
|
363
|
-
}
|
|
364
|
-
|
|
365
|
-
protected flushPending() {
|
|
366
|
-
if (this.pendingEmitters.length === 0) {
|
|
367
|
-
return IO.unit;
|
|
368
|
-
}
|
|
369
|
-
|
|
370
|
-
const emitters = this.pendingEmitters;
|
|
371
|
-
this.pendingEmitters = [];
|
|
372
|
-
|
|
373
|
-
return IO.foreachDiscard(emitters, (pendingEmitter) => {
|
|
374
|
-
return IO.defer(() => {
|
|
375
|
-
const [emitter, values] = pendingEmitter;
|
|
376
|
-
const observer = this.observers.find((observer) => observer.emitter === emitter);
|
|
377
|
-
if (!observer) {
|
|
378
|
-
return IO.unit;
|
|
379
|
-
}
|
|
380
|
-
return IO.foreachDiscard(values, (value) => this.runEvent(value, observer));
|
|
381
|
-
});
|
|
382
|
-
});
|
|
383
|
-
}
|
|
384
|
-
|
|
385
|
-
protected addValue(value: A) {
|
|
386
|
-
this.value.set(Just(value));
|
|
387
|
-
this.pendingEmitters.forEach(([, values]) => {
|
|
388
|
-
values.push(value);
|
|
401
|
+
this.current.set(Just(value));
|
|
402
|
+
return super.event(value);
|
|
389
403
|
});
|
|
390
404
|
}
|
|
391
405
|
}
|
|
@@ -406,10 +420,9 @@ export function mapError<E, E1>(f: (e: E) => E1) {
|
|
|
406
420
|
return <R, A>(self: Push<R, E, A>): Push<R, E1, A> => {
|
|
407
421
|
return Push((emitter) =>
|
|
408
422
|
self.run(
|
|
409
|
-
|
|
410
|
-
(value) => emitter.
|
|
411
|
-
(cause) => emitter.
|
|
412
|
-
emitter.end,
|
|
423
|
+
Sink(
|
|
424
|
+
(value) => emitter.event(value),
|
|
425
|
+
(cause) => emitter.error(cause.map(f)),
|
|
413
426
|
),
|
|
414
427
|
),
|
|
415
428
|
);
|
|
@@ -423,10 +436,9 @@ export function mapErrorCause<E, E1>(f: (cause: Cause<E>) => Cause<E1>) {
|
|
|
423
436
|
return <R, A>(self: Push<R, E, A>): Push<R, E1, A> => {
|
|
424
437
|
return Push((emitter) =>
|
|
425
438
|
self.run(
|
|
426
|
-
|
|
427
|
-
(value) => emitter.
|
|
428
|
-
(cause) => emitter.
|
|
429
|
-
emitter.end,
|
|
439
|
+
Sink(
|
|
440
|
+
(value) => emitter.event(value),
|
|
441
|
+
(cause) => emitter.error(f(cause)),
|
|
430
442
|
),
|
|
431
443
|
),
|
|
432
444
|
);
|
|
@@ -440,14 +452,13 @@ export function mapIO<A, R1, E1, B>(f: (a: A) => IO<R1, E1, B>) {
|
|
|
440
452
|
return <R, E>(self: Push<R, E, A>): Push<R | R1, E | E1, B> =>
|
|
441
453
|
Push((emitter) =>
|
|
442
454
|
self.run(
|
|
443
|
-
|
|
455
|
+
Sink(
|
|
444
456
|
(value) =>
|
|
445
457
|
f(value).matchCauseIO(
|
|
446
|
-
(cause) => emitter.
|
|
447
|
-
(b) => emitter.
|
|
458
|
+
(cause) => emitter.error(cause),
|
|
459
|
+
(b) => emitter.event(b),
|
|
448
460
|
),
|
|
449
|
-
(cause) => emitter.
|
|
450
|
-
emitter.end,
|
|
461
|
+
(cause) => emitter.error(cause),
|
|
451
462
|
),
|
|
452
463
|
),
|
|
453
464
|
);
|
|
@@ -467,29 +478,40 @@ export function merge<R1, E1, B>(that: Push<R1, E1, B>) {
|
|
|
467
478
|
*/
|
|
468
479
|
export function mergeAll<A extends ReadonlyArray<Push<any, any, any>>>(
|
|
469
480
|
streams: [...A],
|
|
470
|
-
): Push<
|
|
481
|
+
): Push<Push.EnvironmentOf<A[number]>, Push.ErrorOf<A[number]>, Push.ValueOf<A[number]>>;
|
|
471
482
|
export function mergeAll<R, E, A>(streams: Iterable<Push<R, E, A>>): Push<R, E, A>;
|
|
472
483
|
export function mergeAll<R, E, A>(streams: Iterable<Push<R, E, A>>): Push<R, E, A> {
|
|
473
|
-
return Push((
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
streams.traverseIOConcurrent(
|
|
478
|
-
(stream) =>
|
|
479
|
-
stream.run(
|
|
480
|
-
Emitter(
|
|
481
|
-
(value) => emitter.emit(value),
|
|
482
|
-
(cause) => emitter.failCause(cause),
|
|
483
|
-
latch.countDown,
|
|
484
|
-
),
|
|
485
|
-
).forkScoped,
|
|
486
|
-
),
|
|
487
|
-
);
|
|
488
|
-
Δ(latch.await > emitter.end);
|
|
489
|
-
}),
|
|
484
|
+
return Push((sink) =>
|
|
485
|
+
IO.foreachConcurrentDiscard(streams, (stream) =>
|
|
486
|
+
stream.run(Sink(sink.event, (cause) => (cause.isInterruptedOnly ? IO.unit : sink.error(cause)))),
|
|
487
|
+
),
|
|
490
488
|
);
|
|
491
489
|
}
|
|
492
490
|
|
|
491
|
+
/**
|
|
492
|
+
* @tsplus pipeable fncts.io.Push observe
|
|
493
|
+
*/
|
|
494
|
+
export function observe<A, R1, E1>(f: (a: A) => IO<R1, E1, void>, __tsplusTrace?: string) {
|
|
495
|
+
return <R, E>(self: Push<R, E, A>): IO<R | R1 | Scope, E | E1, void> => {
|
|
496
|
+
return Do((Δ) => {
|
|
497
|
+
const future = Δ(Future.make<E | E1, void>());
|
|
498
|
+
const fiber = Δ(
|
|
499
|
+
self
|
|
500
|
+
.run(
|
|
501
|
+
Sink(
|
|
502
|
+
(a) => f(a).catchAllCause((cause) => future.failCause(cause)),
|
|
503
|
+
(cause) => future.failCause(cause),
|
|
504
|
+
),
|
|
505
|
+
)
|
|
506
|
+
.flatMap(() => future.succeed(undefined)).forkScoped,
|
|
507
|
+
);
|
|
508
|
+
|
|
509
|
+
Δ(future.await);
|
|
510
|
+
Δ(fiber.interruptFork);
|
|
511
|
+
});
|
|
512
|
+
};
|
|
513
|
+
}
|
|
514
|
+
|
|
493
515
|
/**
|
|
494
516
|
* @tsplus static fncts.io.PushOps repeatIOMaybe
|
|
495
517
|
*/
|
|
@@ -507,18 +529,7 @@ export function repeatIOMaybe<R, E, A>(io: IO<R, Maybe<E>, A>, __tsplusTrace?: s
|
|
|
507
529
|
export function runCollect<R, E, A>(self: Push<R, E, A>): IO<R | Scope, E, Conc<A>> {
|
|
508
530
|
return IO.defer(() => {
|
|
509
531
|
const out: Array<A> = [];
|
|
510
|
-
return
|
|
511
|
-
(future) =>
|
|
512
|
-
self.run(
|
|
513
|
-
Emitter(
|
|
514
|
-
(value) => IO(out.push(value)),
|
|
515
|
-
(cause) => future.failCause(cause),
|
|
516
|
-
future.succeed(undefined),
|
|
517
|
-
),
|
|
518
|
-
) >
|
|
519
|
-
future.await >
|
|
520
|
-
IO(Conc.fromArray(out)),
|
|
521
|
-
);
|
|
532
|
+
return self.observe((a) => IO(out.push(a))).as(Conc.fromArray(out));
|
|
522
533
|
});
|
|
523
534
|
}
|
|
524
535
|
|
|
@@ -526,28 +537,18 @@ export function runCollect<R, E, A>(self: Push<R, E, A>): IO<R | Scope, E, Conc<
|
|
|
526
537
|
* @tsplus getter fncts.io.Push runDrain
|
|
527
538
|
*/
|
|
528
539
|
export function runDrain<R, E, A>(self: Push<R, E, A>): IO<R | Scope, E, void> {
|
|
529
|
-
return
|
|
530
|
-
(future) =>
|
|
531
|
-
self.run(
|
|
532
|
-
Emitter(
|
|
533
|
-
() => IO.unit,
|
|
534
|
-
(cause) => future.failCause(cause),
|
|
535
|
-
future.succeed(undefined),
|
|
536
|
-
),
|
|
537
|
-
) > future.await,
|
|
538
|
-
);
|
|
540
|
+
return self.observe(() => IO.unit);
|
|
539
541
|
}
|
|
540
542
|
|
|
541
543
|
/**
|
|
542
544
|
* @tsplus static fncts.io.PushOps scoped
|
|
543
545
|
*/
|
|
544
546
|
export function scoped<R, E, A>(io: Lazy<IO<R, E, A>>, __tsplusTrace?: string): Push<Exclude<R, Scope>, E, A> {
|
|
545
|
-
return Push(
|
|
546
|
-
(
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
) > emitter.end,
|
|
547
|
+
return Push((emitter) =>
|
|
548
|
+
IO.defer(io).scoped.matchCauseIO(
|
|
549
|
+
(cause) => emitter.error(cause),
|
|
550
|
+
(value) => emitter.event(value),
|
|
551
|
+
),
|
|
551
552
|
);
|
|
552
553
|
}
|
|
553
554
|
|
|
@@ -559,34 +560,29 @@ export function succeed<A>(value: Lazy<A>): Push<never, never, A> {
|
|
|
559
560
|
}
|
|
560
561
|
|
|
561
562
|
/**
|
|
562
|
-
* @tsplus pipeable fncts.io.
|
|
563
|
+
* @tsplus pipeable fncts.io.Push switchMap
|
|
563
564
|
*/
|
|
564
565
|
export function switchMap<A, R1, E1, B>(f: (a: A) => Push<R1, E1, B>) {
|
|
565
566
|
return <R, E>(self: Push<R, E, A>): Push<R | R1, E | E1, B> => {
|
|
566
|
-
return Push(
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
),
|
|
586
|
-
);
|
|
587
|
-
Δ(latch.await > emitter.end);
|
|
588
|
-
}),
|
|
589
|
-
);
|
|
567
|
+
return Push((sink) => withSwitch((fork) => self.run(Sink((a) => fork(f(a).run(sink)), sink.error))));
|
|
568
|
+
};
|
|
569
|
+
}
|
|
570
|
+
|
|
571
|
+
/**
|
|
572
|
+
* @tsplus pipeable fncts.io.Push switchMapIO
|
|
573
|
+
*/
|
|
574
|
+
export function switchMapIO<A, R1, E1, B>(f: (a: A) => IO<R1, E1, B>) {
|
|
575
|
+
return <R, E>(self: Push<R, E, A>): Push<R | R1, E | E1, B> => {
|
|
576
|
+
return self.switchMap((a) => Push.fromIO(f(a)));
|
|
577
|
+
};
|
|
578
|
+
}
|
|
579
|
+
|
|
580
|
+
/**
|
|
581
|
+
* @tsplus pipeable fncts.io.Push tap
|
|
582
|
+
*/
|
|
583
|
+
export function tap<A, R1, E1, B>(f: (a: A) => IO<R1, E1, B>) {
|
|
584
|
+
return <R, E>(self: Push<R, E, A>): Push<R | R1, E | E1, A> => {
|
|
585
|
+
return Push((sink) => self.run(Sink((a) => f(a).matchCauseIO(sink.error, () => sink.event(a)), sink.error)));
|
|
590
586
|
};
|
|
591
587
|
}
|
|
592
588
|
|
|
@@ -600,11 +596,11 @@ export function transform<R1 = never>(f: <R, E, A>(io: IO<R, E, A>) => IO<R | R1
|
|
|
600
596
|
function unfoldLoop<S, A, R1>(
|
|
601
597
|
s: S,
|
|
602
598
|
f: (s: S) => Maybe<readonly [A, S]>,
|
|
603
|
-
emitter:
|
|
599
|
+
emitter: Sink<R1, never, A>,
|
|
604
600
|
): IO<R1, never, void> {
|
|
605
601
|
return f(s).match(
|
|
606
|
-
() =>
|
|
607
|
-
([a, s]) => emitter.
|
|
602
|
+
() => IO.unit,
|
|
603
|
+
([a, s]) => emitter.event(a) > unfoldLoop(s, f, emitter),
|
|
608
604
|
);
|
|
609
605
|
}
|
|
610
606
|
|
|
@@ -618,16 +614,16 @@ export function unfold<S, A>(s: S, f: (s: S) => Maybe<readonly [A, S]>): Push<ne
|
|
|
618
614
|
function unfoldIOLoop<S, R, E, A, R1>(
|
|
619
615
|
s: S,
|
|
620
616
|
f: (s: S) => IO<R, E, Maybe<readonly [A, S]>>,
|
|
621
|
-
emitter:
|
|
617
|
+
emitter: Sink<R1, E, A>,
|
|
622
618
|
): IO<R | R1, never, void> {
|
|
623
619
|
return f(s)
|
|
624
620
|
.flatMap((result) =>
|
|
625
621
|
result.match(
|
|
626
|
-
() =>
|
|
627
|
-
([a, s]) => emitter.
|
|
622
|
+
() => IO.unit,
|
|
623
|
+
([a, s]) => emitter.event(a) > unfoldIOLoop(s, f, emitter),
|
|
628
624
|
),
|
|
629
625
|
)
|
|
630
|
-
.catchAllCause((cause) => emitter.
|
|
626
|
+
.catchAllCause((cause) => emitter.error(cause));
|
|
631
627
|
}
|
|
632
628
|
|
|
633
629
|
/**
|
|
@@ -642,18 +638,21 @@ export function unfoldIO<S, R, E, A>(s: S, f: (s: S) => IO<R, E, Maybe<readonly
|
|
|
642
638
|
*/
|
|
643
639
|
export function untilFuture<E1, B>(future: Future<E1, B>) {
|
|
644
640
|
return <R, E, A>(self: Push<R, E, A>): Push<R, E | E1, A> => {
|
|
645
|
-
return Push((
|
|
646
|
-
|
|
647
|
-
const
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
641
|
+
return Push(<R1>(sink: Sink<R1, E | E1, A>) =>
|
|
642
|
+
IO.asyncIO<R | R1, never, void>((cb) => {
|
|
643
|
+
const exit = IO(cb(IO.unit));
|
|
644
|
+
return Do((Δ) => {
|
|
645
|
+
const streamFiber = Δ(self.run(sink).fork);
|
|
646
|
+
const futureFiber = Δ(
|
|
647
|
+
future.await
|
|
648
|
+
.matchCauseIO(
|
|
649
|
+
(cause) => sink.error(cause),
|
|
650
|
+
() => IO.unit,
|
|
651
|
+
)
|
|
652
|
+
.zipRight(exit).fork,
|
|
653
|
+
);
|
|
654
|
+
Δ(Fiber.joinAll([streamFiber, futureFiber]));
|
|
655
|
+
});
|
|
657
656
|
}),
|
|
658
657
|
);
|
|
659
658
|
};
|
|
@@ -664,19 +663,21 @@ export function untilFuture<E1, B>(future: Future<E1, B>) {
|
|
|
664
663
|
*/
|
|
665
664
|
export function untilPush<R1, E1, B>(signal: Push<R1, E1, B>) {
|
|
666
665
|
return <R, E, A>(self: Push<R, E, A>): Push<R | R1, E | E1, A> => {
|
|
667
|
-
return Push((
|
|
668
|
-
|
|
669
|
-
const
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
(
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
666
|
+
return Push(<R2>(sink: Sink<R2, E | E1, A>) =>
|
|
667
|
+
IO.asyncIO<R | R1 | R2, never, void>((cb) => {
|
|
668
|
+
const exit = IO(cb(IO.unit));
|
|
669
|
+
return Do((Δ) => {
|
|
670
|
+
const signalFiber = Δ(
|
|
671
|
+
signal.run(
|
|
672
|
+
Sink(
|
|
673
|
+
() => exit,
|
|
674
|
+
(cause) => sink.error(cause),
|
|
675
|
+
),
|
|
676
|
+
).fork,
|
|
677
|
+
);
|
|
678
|
+
const streamFiber = Δ(self.run(sink).fork);
|
|
679
|
+
Δ(Fiber.joinAll([signalFiber, streamFiber]));
|
|
680
|
+
});
|
|
680
681
|
}),
|
|
681
682
|
);
|
|
682
683
|
};
|