@typed/fx 1.5.1 → 1.5.2
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/package.json +2 -2
- package/project.json +6 -1
- package/src/_internal/Mutable.ts +14 -0
- package/src/_internal/disableCooperativeYielding.ts +7 -0
- package/src/operator/hold.ts +8 -13
- package/src/operator/slice.ts +4 -4
- package/src/operator/switchMap.test.ts +14 -0
- package/src/run/observe.ts +2 -1
- package/src/subject/HoldSubject.ts +9 -4
- package/src/subject/RefSubject.test.ts +68 -0
- package/src/subject/RefSubject.ts +35 -16
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@typed/fx",
|
|
3
|
-
"version": "1.5.
|
|
3
|
+
"version": "1.5.2",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"module": "dist/index.js",
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
"@effect/data": "^0.10.3",
|
|
23
23
|
"@effect/io": "^0.17.0"
|
|
24
24
|
},
|
|
25
|
-
"gitHead": "
|
|
25
|
+
"gitHead": "4ba4f251d38dec8c5bee4d6f81f33b735338a7be",
|
|
26
26
|
"publishConfig": {
|
|
27
27
|
"access": "public"
|
|
28
28
|
},
|
package/project.json
CHANGED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { Effect, withRuntimeFlags } from '@effect/io/Effect'
|
|
2
|
+
import { CooperativeYielding } from '@effect/io/Fiber/Runtime/Flags'
|
|
3
|
+
import { disable } from '@effect/io/Fiber/Runtime/Flags/Patch'
|
|
4
|
+
|
|
5
|
+
export function disableCooperativeYielding<R, E, A>(effect: Effect<R, E, A>): Effect<R, E, A> {
|
|
6
|
+
return withRuntimeFlags(effect, disable(CooperativeYielding))
|
|
7
|
+
}
|
package/src/operator/hold.ts
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { pipe } from '@effect/data/Function'
|
|
2
|
-
import * as MutableRef from '@effect/data/MutableRef'
|
|
3
2
|
import * as Option from '@effect/data/Option'
|
|
4
3
|
import type * as Cause from '@effect/io/Cause'
|
|
5
4
|
import * as Effect from '@effect/io/Effect'
|
|
@@ -7,15 +6,15 @@ import * as Fiber from '@effect/io/Fiber'
|
|
|
7
6
|
import type { Scope } from '@effect/io/Scope'
|
|
8
7
|
|
|
9
8
|
import type { Fx } from '../Fx.js'
|
|
10
|
-
import {
|
|
9
|
+
import { Mutable } from '../_internal/Mutable.js'
|
|
11
10
|
|
|
12
11
|
import { MulticastFx } from './multicast.js'
|
|
13
12
|
|
|
14
13
|
export function hold<R, E, A>(fx: Fx<R, E, A>): Fx<R, E, A> {
|
|
15
|
-
return new HoldFx(fx,
|
|
14
|
+
return new HoldFx(fx, Mutable(Option.none()))
|
|
16
15
|
}
|
|
17
16
|
|
|
18
|
-
export function hold_<R, E, A>(fx: Fx<R, E, A>, value:
|
|
17
|
+
export function hold_<R, E, A>(fx: Fx<R, E, A>, value: Mutable<Option.Option<A>>) {
|
|
19
18
|
return new HoldFx(fx, value)
|
|
20
19
|
}
|
|
21
20
|
|
|
@@ -23,10 +22,7 @@ export class HoldFx<R, E, A> extends MulticastFx<R, E, A> implements Fx<R, E, A>
|
|
|
23
22
|
protected pendingSinks: Array<readonly [Fx.Sink<any, E, A>, A[]]> = []
|
|
24
23
|
protected scheduledFiber: Fiber.RuntimeFiber<any, any> | undefined = undefined
|
|
25
24
|
|
|
26
|
-
constructor(
|
|
27
|
-
readonly fx: Fx<R, E, A>,
|
|
28
|
-
protected current: MutableRef.MutableRef<Option.Option<A>>,
|
|
29
|
-
) {
|
|
25
|
+
constructor(readonly fx: Fx<R, E, A>, readonly current: Mutable<Option.Option<A>>) {
|
|
30
26
|
super(fx)
|
|
31
27
|
|
|
32
28
|
this.event = this.event.bind(this)
|
|
@@ -35,7 +31,7 @@ export class HoldFx<R, E, A> extends MulticastFx<R, E, A> implements Fx<R, E, A>
|
|
|
35
31
|
|
|
36
32
|
run<R2>(sink: Fx.Sink<R2, E, A>): Effect.Effect<Scope | R | R2, never, void> {
|
|
37
33
|
return Effect.suspend(() => {
|
|
38
|
-
if (Option.isSome(
|
|
34
|
+
if (Option.isSome(this.current.get())) {
|
|
39
35
|
return pipe(
|
|
40
36
|
this.scheduleFlush(sink),
|
|
41
37
|
Effect.flatMap(() => super.run(sink)),
|
|
@@ -80,8 +76,7 @@ export class HoldFx<R, E, A> extends MulticastFx<R, E, A> implements Fx<R, E, A>
|
|
|
80
76
|
this.pendingSinks.push([
|
|
81
77
|
sink,
|
|
82
78
|
pipe(
|
|
83
|
-
this.current,
|
|
84
|
-
MutableRef.get,
|
|
79
|
+
this.current.get(),
|
|
85
80
|
Option.match(
|
|
86
81
|
() => [],
|
|
87
82
|
(a) => [a],
|
|
@@ -98,7 +93,7 @@ export class HoldFx<R, E, A> extends MulticastFx<R, E, A> implements Fx<R, E, A>
|
|
|
98
93
|
return pipe(
|
|
99
94
|
interrupt,
|
|
100
95
|
Effect.flatMap(() => this.flushPending()),
|
|
101
|
-
Effect.
|
|
96
|
+
Effect.forkScoped,
|
|
102
97
|
Effect.tap((f) =>
|
|
103
98
|
Effect.sync(() => {
|
|
104
99
|
this.scheduledFiber = f
|
|
@@ -138,7 +133,7 @@ export class HoldFx<R, E, A> extends MulticastFx<R, E, A> implements Fx<R, E, A>
|
|
|
138
133
|
}
|
|
139
134
|
|
|
140
135
|
protected addValue(a: A) {
|
|
141
|
-
|
|
136
|
+
this.current.set(Option.some(a))
|
|
142
137
|
this.pendingSinks.forEach(([, events]) => events.push(a))
|
|
143
138
|
}
|
|
144
139
|
}
|
package/src/operator/slice.ts
CHANGED
|
@@ -32,12 +32,12 @@ class SliceSink<R, E, A> implements Fx.Sink<R, E, A> {
|
|
|
32
32
|
) {}
|
|
33
33
|
|
|
34
34
|
event = (a: A) => {
|
|
35
|
-
if (this.
|
|
36
|
-
this.
|
|
37
|
-
return Effect.unit()
|
|
35
|
+
if (this.take === 0) {
|
|
36
|
+
return this.earlyExit
|
|
38
37
|
}
|
|
39
38
|
|
|
40
|
-
if (this.
|
|
39
|
+
if (this.skip > 0) {
|
|
40
|
+
this.skip--
|
|
41
41
|
return Effect.unit()
|
|
42
42
|
}
|
|
43
43
|
|
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
import { deepStrictEqual } from 'assert'
|
|
2
2
|
|
|
3
3
|
import { millis } from '@effect/data/Duration'
|
|
4
|
+
import * as Either from '@effect/data/Either'
|
|
4
5
|
import { pipe } from '@effect/data/Function'
|
|
5
6
|
import * as Effect from '@effect/io/Effect'
|
|
6
7
|
import { describe, it } from 'vitest'
|
|
7
8
|
|
|
8
9
|
import { at } from '../constructor/at.js'
|
|
10
|
+
import { fail } from '../constructor/fail.js'
|
|
9
11
|
import { collectAll } from '../run/collectAll.js'
|
|
10
12
|
|
|
11
13
|
import { mergeAll } from './merge.js'
|
|
@@ -23,5 +25,17 @@ describe(import.meta.url, () => {
|
|
|
23
25
|
|
|
24
26
|
deepStrictEqual(events, [9])
|
|
25
27
|
})
|
|
28
|
+
|
|
29
|
+
it('collects inner errors', async () => {
|
|
30
|
+
const test = pipe(
|
|
31
|
+
mergeAll(at(millis(0), 1), at(millis(20), 2), at(millis(40), 3)),
|
|
32
|
+
switchMap((n) => fail(n)),
|
|
33
|
+
collectAll,
|
|
34
|
+
)
|
|
35
|
+
|
|
36
|
+
const either = await Effect.runPromiseEither(test)
|
|
37
|
+
|
|
38
|
+
deepStrictEqual(either, Either.left(1))
|
|
39
|
+
})
|
|
26
40
|
})
|
|
27
41
|
})
|
package/src/run/observe.ts
CHANGED
|
@@ -3,13 +3,14 @@ import * as Effect from '@effect/io/Effect'
|
|
|
3
3
|
import type { Scope } from '@effect/io/Scope'
|
|
4
4
|
|
|
5
5
|
import type { Fx } from '../Fx.js'
|
|
6
|
+
import { disableCooperativeYielding } from '../_internal/disableCooperativeYielding.js'
|
|
6
7
|
|
|
7
8
|
import { run_ } from './run.js'
|
|
8
9
|
|
|
9
10
|
export function observe<A, R2, E2, B>(
|
|
10
11
|
f: (a: A) => Effect.Effect<R2, E2, B>,
|
|
11
12
|
): <R, E>(fx: Fx<R, E, A>) => Effect.Effect<R | R2, E2 | E, void> {
|
|
12
|
-
return flow(observe_(f), Effect.scoped)
|
|
13
|
+
return flow(observe_(f), Effect.scoped, disableCooperativeYielding)
|
|
13
14
|
}
|
|
14
15
|
|
|
15
16
|
export function observeSync<A, B>(
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { identity } from '@effect/data/Function'
|
|
2
|
-
import * as MutableRef from '@effect/data/MutableRef'
|
|
3
2
|
import { type Option, none } from '@effect/data/Option'
|
|
4
3
|
import * as Effect from '@effect/io/Effect'
|
|
5
4
|
|
|
5
|
+
import { Mutable } from '../_internal/Mutable.js'
|
|
6
6
|
import { never } from '../constructor/never.js'
|
|
7
7
|
import { HoldFx } from '../operator/hold.js'
|
|
8
8
|
|
|
@@ -10,6 +10,11 @@ import { isSubject, Subject } from './Subject.js'
|
|
|
10
10
|
|
|
11
11
|
export interface HoldSubject<E, A> extends Subject<E, A>, HoldSubject.Variance<E, A> {
|
|
12
12
|
readonly value: Effect.Effect<never, never, Option<A>>
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* @internal
|
|
16
|
+
*/
|
|
17
|
+
readonly current: Mutable<Option<A>>
|
|
13
18
|
}
|
|
14
19
|
|
|
15
20
|
export namespace HoldSubject {
|
|
@@ -32,7 +37,7 @@ export namespace HoldSubject {
|
|
|
32
37
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
33
38
|
export type OutputsOf<T> = [T] extends [Variance<infer _E, infer A>] ? A : never
|
|
34
39
|
|
|
35
|
-
export function unsafeMake<E, A>(value:
|
|
40
|
+
export function unsafeMake<E, A>(value: Mutable<Option<A>> = Mutable(none())): HoldSubject<E, A> {
|
|
36
41
|
return new HoldSubjectImpl(value)
|
|
37
42
|
}
|
|
38
43
|
|
|
@@ -43,11 +48,11 @@ export namespace HoldSubject {
|
|
|
43
48
|
};
|
|
44
49
|
readonly [TypeId]: HoldSubject.Variance<E, A>[TypeId] = this[Subject.TypeId]
|
|
45
50
|
|
|
46
|
-
constructor(value:
|
|
51
|
+
constructor(value: Mutable<Option<A>>) {
|
|
47
52
|
super(never, value)
|
|
48
53
|
}
|
|
49
54
|
|
|
50
|
-
readonly value = Effect.sync(() =>
|
|
55
|
+
readonly value = Effect.sync(() => this.current.get())
|
|
51
56
|
}
|
|
52
57
|
}
|
|
53
58
|
|
|
@@ -1,8 +1,12 @@
|
|
|
1
1
|
import { deepStrictEqual } from 'assert'
|
|
2
2
|
|
|
3
|
+
import { millis } from '@effect/data/Duration'
|
|
3
4
|
import * as Effect from '@effect/io/Effect'
|
|
5
|
+
import * as Fiber from '@effect/io/Fiber'
|
|
4
6
|
import { describe, it } from 'vitest'
|
|
5
7
|
|
|
8
|
+
import { collectAll } from '../run/collectAll.js'
|
|
9
|
+
|
|
6
10
|
import { makeRef, RefSubject } from './RefSubject.js'
|
|
7
11
|
|
|
8
12
|
describe(import.meta.url, () => {
|
|
@@ -77,5 +81,69 @@ describe(import.meta.url, () => {
|
|
|
77
81
|
|
|
78
82
|
await Effect.runPromise(test)
|
|
79
83
|
})
|
|
84
|
+
|
|
85
|
+
it('allows computing values from a Computed', async () => {
|
|
86
|
+
const test = Effect.scoped(
|
|
87
|
+
Effect.gen(function* ($) {
|
|
88
|
+
const refSubject = yield* $(makeRef(() => 1))
|
|
89
|
+
const computed = yield* $(refSubject.computeSync((a) => a + 42))
|
|
90
|
+
const computed2 = yield* $(computed.computeSync((a) => a + 1))
|
|
91
|
+
|
|
92
|
+
deepStrictEqual(yield* $(computed.get), 43, '1a -43')
|
|
93
|
+
deepStrictEqual(yield* $(computed2.get), 44, '1b - 44')
|
|
94
|
+
|
|
95
|
+
yield* $(refSubject.set(2))
|
|
96
|
+
|
|
97
|
+
deepStrictEqual(yield* $(computed.get), 44, '2a - 44')
|
|
98
|
+
deepStrictEqual(yield* $(computed2.get), 45, '2a - 45')
|
|
99
|
+
}),
|
|
100
|
+
)
|
|
101
|
+
|
|
102
|
+
await Effect.runPromise(test)
|
|
103
|
+
})
|
|
104
|
+
})
|
|
105
|
+
|
|
106
|
+
it('allows replaying latest events to late subscribers', async () => {
|
|
107
|
+
const test = Effect.gen(function* ($) {
|
|
108
|
+
const holdSubject = RefSubject.unsafeMake<number>(() => 0)
|
|
109
|
+
|
|
110
|
+
const producer = Effect.gen(function* ($) {
|
|
111
|
+
yield* $(Effect.sleep(millis(0)))
|
|
112
|
+
yield* $(holdSubject.event(1))
|
|
113
|
+
yield* $(Effect.sleep(millis(100)))
|
|
114
|
+
yield* $(holdSubject.event(2))
|
|
115
|
+
yield* $(Effect.sleep(millis(100)))
|
|
116
|
+
yield* $(holdSubject.event(3))
|
|
117
|
+
yield* $(Effect.sleep(millis(100)))
|
|
118
|
+
yield* $(holdSubject.event(4))
|
|
119
|
+
yield* $(Effect.sleep(millis(100)))
|
|
120
|
+
yield* $(holdSubject.event(5))
|
|
121
|
+
yield* $(Effect.sleep(millis(100)))
|
|
122
|
+
yield* $(holdSubject.event(6))
|
|
123
|
+
yield* $(holdSubject.end)
|
|
124
|
+
})
|
|
125
|
+
|
|
126
|
+
yield* $(Effect.fork(producer))
|
|
127
|
+
|
|
128
|
+
const fiber1 = yield* $(Effect.fork(collectAll(holdSubject)))
|
|
129
|
+
|
|
130
|
+
yield* $(Effect.sleep(millis(75)))
|
|
131
|
+
|
|
132
|
+
const fiber2 = yield* $(Effect.fork(collectAll(holdSubject)))
|
|
133
|
+
|
|
134
|
+
yield* $(Effect.sleep(millis(75)))
|
|
135
|
+
|
|
136
|
+
const fiber3 = yield* $(Effect.fork(collectAll(holdSubject)))
|
|
137
|
+
|
|
138
|
+
const events1 = yield* $(Fiber.join(fiber1))
|
|
139
|
+
const events2 = yield* $(Fiber.join(fiber2))
|
|
140
|
+
const events3 = yield* $(Fiber.join(fiber3))
|
|
141
|
+
|
|
142
|
+
deepStrictEqual(events1, [0, 1, 2, 3, 4, 5, 6], '1')
|
|
143
|
+
deepStrictEqual(events2, [1, 2, 3, 4, 5, 6], '2')
|
|
144
|
+
deepStrictEqual(events3, [2, 3, 4, 5, 6], '3')
|
|
145
|
+
})
|
|
146
|
+
|
|
147
|
+
await Effect.runPromise(test)
|
|
80
148
|
})
|
|
81
149
|
})
|
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
import { equals } from '@effect/data/Equal'
|
|
2
2
|
import { identity, pipe, dual, flow } from '@effect/data/Function'
|
|
3
|
-
import * as MutableRef from '@effect/data/MutableRef'
|
|
4
3
|
import * as Option from '@effect/data/Option'
|
|
5
4
|
import * as ReadonlyArray from '@effect/data/ReadonlyArray'
|
|
6
5
|
import * as ReadonlyRecord from '@effect/data/ReadonlyRecord'
|
|
7
6
|
import * as Equivalence from '@effect/data/typeclass/Equivalence'
|
|
7
|
+
import type * as Cause from '@effect/io/Cause'
|
|
8
8
|
import * as Effect from '@effect/io/Effect'
|
|
9
9
|
import type * as Exit from '@effect/io/Exit'
|
|
10
10
|
import * as Ref from '@effect/io/Ref'
|
|
11
11
|
import type * as Scope from '@effect/io/Scope'
|
|
12
12
|
|
|
13
13
|
import { Fx, Sink } from '../Fx.js'
|
|
14
|
+
import { Mutable } from '../_internal/Mutable.js'
|
|
14
15
|
import { flatMapEffect } from '../operator/flatMapEffect.js'
|
|
15
|
-
import { hold } from '../operator/hold.js'
|
|
16
16
|
import { skipWhile } from '../operator/skipWhile.js'
|
|
17
17
|
import { observe } from '../run/observe.js'
|
|
18
18
|
|
|
@@ -24,7 +24,7 @@ export interface RefSubject<A> extends HoldSubject<never, A>, Ref.Ref<A> {
|
|
|
24
24
|
readonly get: Effect.Effect<never, never, A>
|
|
25
25
|
readonly set: (a: A) => Effect.Effect<never, never, A>
|
|
26
26
|
readonly update: (f: (a: A) => A) => Effect.Effect<never, never, A>
|
|
27
|
-
readonly delete: Effect.Effect<never,
|
|
27
|
+
readonly delete: Effect.Effect<never, Cause.NoSuchElementException, A>
|
|
28
28
|
readonly compute: <R, E, B>(
|
|
29
29
|
f: (a: A) => Effect.Effect<R, E, B>,
|
|
30
30
|
) => Effect.Effect<R | Scope.Scope, never, Computed<E, B>>
|
|
@@ -44,18 +44,26 @@ export namespace RefSubject {
|
|
|
44
44
|
export function unsafeMake<A>(
|
|
45
45
|
initial: () => A,
|
|
46
46
|
eq: Equivalence.Equivalence<A> = equals,
|
|
47
|
+
current: Mutable<Option.Option<A>> = Mutable(Option.some(initial())),
|
|
47
48
|
): RefSubject<A> {
|
|
48
|
-
const current = MutableRef.make(Option.some(initial()))
|
|
49
49
|
const subject = HoldSubject.unsafeMake<never, A>(current)
|
|
50
50
|
|
|
51
|
-
const getValue = () =>
|
|
51
|
+
const getValue = () =>
|
|
52
|
+
pipe(
|
|
53
|
+
current.get(),
|
|
54
|
+
Option.getOrElse(() => {
|
|
55
|
+
const a = initial()
|
|
56
|
+
current.set(Option.some(a))
|
|
57
|
+
return a
|
|
58
|
+
}),
|
|
59
|
+
)
|
|
52
60
|
|
|
53
61
|
const modify = <B>(f: (a: A) => readonly [B, A]): Effect.Effect<never, never, B> =>
|
|
54
62
|
Effect.suspend(() => {
|
|
55
63
|
const currentValue = getValue()
|
|
56
64
|
const [b, a] = f(currentValue)
|
|
57
65
|
|
|
58
|
-
|
|
66
|
+
current.set(Option.some(a))
|
|
59
67
|
|
|
60
68
|
if (eq(currentValue, a)) {
|
|
61
69
|
return Effect.succeed(b)
|
|
@@ -76,15 +84,16 @@ export namespace RefSubject {
|
|
|
76
84
|
error: subject.error.bind(subject),
|
|
77
85
|
end: subject.end,
|
|
78
86
|
value: subject.value,
|
|
87
|
+
current: subject.current,
|
|
79
88
|
eq,
|
|
80
89
|
modify,
|
|
81
90
|
...makeDerivations(modify, Effect.sync(getValue)),
|
|
82
|
-
delete: Effect.
|
|
83
|
-
const option =
|
|
84
|
-
|
|
85
|
-
|
|
91
|
+
delete: Effect.suspend(() => {
|
|
92
|
+
const option = current.get()
|
|
93
|
+
|
|
94
|
+
current.set(Option.none())
|
|
86
95
|
|
|
87
|
-
return
|
|
96
|
+
return option
|
|
88
97
|
}),
|
|
89
98
|
compute: (f) => makeComputed(refSubject, f),
|
|
90
99
|
computeSync: (f) => makeComputed(refSubject, (a) => Effect.sync(() => f(a))),
|
|
@@ -258,6 +267,12 @@ export function isRefSubject<A>(u: unknown): u is RefSubject<A> {
|
|
|
258
267
|
|
|
259
268
|
export interface Computed<E, A> extends Fx<never, E, A> {
|
|
260
269
|
readonly get: Effect.Effect<never, E, A>
|
|
270
|
+
|
|
271
|
+
readonly compute: <R2, E2, B>(
|
|
272
|
+
f: (a: A) => Effect.Effect<R2, E2, B>,
|
|
273
|
+
) => Effect.Effect<R2 | Scope.Scope, never, Computed<E | E2, B>>
|
|
274
|
+
|
|
275
|
+
readonly computeSync: <B>(f: (a: A) => B) => Effect.Effect<Scope.Scope, never, Computed<E, B>>
|
|
261
276
|
}
|
|
262
277
|
|
|
263
278
|
export namespace Computed {
|
|
@@ -288,19 +303,23 @@ export namespace Computed {
|
|
|
288
303
|
}
|
|
289
304
|
|
|
290
305
|
class ComputedImpl<E, A> extends Fx.Variance<never, E, A> implements Computed<E, A> {
|
|
291
|
-
readonly fx: Fx<never, E, A>
|
|
292
|
-
|
|
293
306
|
constructor(readonly input: RefSubject<Exit.Exit<E, A>>) {
|
|
294
307
|
super()
|
|
295
|
-
|
|
296
|
-
this.fx = pipe(input, flatMapEffect(Effect.done), hold)
|
|
297
308
|
}
|
|
298
309
|
|
|
299
310
|
run<R3>(sink: Sink<R3, E, A>) {
|
|
300
|
-
return this.
|
|
311
|
+
return pipe(this.input, flatMapEffect(Effect.done)).run(sink)
|
|
301
312
|
}
|
|
302
313
|
|
|
303
314
|
readonly get = Effect.flatMap(this.input.get, Effect.done)
|
|
315
|
+
|
|
316
|
+
readonly compute = <R2, E2, B>(
|
|
317
|
+
f: (a: A) => Effect.Effect<R2, E2, B>,
|
|
318
|
+
): Effect.Effect<R2 | Scope.Scope, never, Computed<E | E2, B>> =>
|
|
319
|
+
Effect.tap(this.input.compute(Effect.flatMap(f)), Effect.yieldNow)
|
|
320
|
+
|
|
321
|
+
readonly computeSync = <B>(f: (a: A) => B): Effect.Effect<Scope.Scope, never, Computed<E, B>> =>
|
|
322
|
+
Effect.tap(this.input.compute(Effect.map(f)), Effect.yieldNow)
|
|
304
323
|
}
|
|
305
324
|
}
|
|
306
325
|
|