@typed/fx 1.13.0 → 1.15.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/Computed.d.ts +42 -0
- package/dist/Computed.d.ts.map +1 -0
- package/dist/Computed.js +39 -0
- package/dist/Computed.js.map +1 -0
- package/dist/Filtered.d.ts +34 -0
- package/dist/Filtered.d.ts.map +1 -0
- package/dist/Filtered.js +40 -0
- package/dist/Filtered.js.map +1 -0
- package/dist/Fx.d.ts +2 -3
- package/dist/Fx.d.ts.map +1 -1
- package/dist/Fx.js +11 -26
- package/dist/Fx.js.map +1 -1
- package/dist/RefArray.d.ts +116 -0
- package/dist/RefArray.d.ts.map +1 -0
- package/dist/RefArray.js +67 -0
- package/dist/RefArray.js.map +1 -0
- package/dist/RefSubject.d.ts +23 -20
- package/dist/RefSubject.d.ts.map +1 -1
- package/dist/RefSubject.js +352 -247
- package/dist/RefSubject.js.map +1 -1
- package/dist/RefTransform.d.ts +51 -0
- package/dist/RefTransform.d.ts.map +1 -0
- package/dist/RefTransform.js +69 -0
- package/dist/RefTransform.js.map +1 -0
- package/dist/Subject.d.ts.map +1 -1
- package/dist/Subject.js +2 -3
- package/dist/Subject.js.map +1 -1
- package/dist/catchAllCause.d.ts +6 -0
- package/dist/catchAllCause.d.ts.map +1 -1
- package/dist/catchAllCause.js +21 -2
- package/dist/catchAllCause.js.map +1 -1
- package/dist/cjs/Computed.d.ts +42 -0
- package/dist/cjs/Computed.d.ts.map +1 -0
- package/dist/cjs/Computed.js +66 -0
- package/dist/cjs/Computed.js.map +1 -0
- package/dist/cjs/Filtered.d.ts +34 -0
- package/dist/cjs/Filtered.d.ts.map +1 -0
- package/dist/cjs/Filtered.js +67 -0
- package/dist/cjs/Filtered.js.map +1 -0
- package/dist/cjs/Fx.d.ts +2 -3
- package/dist/cjs/Fx.d.ts.map +1 -1
- package/dist/cjs/Fx.js +13 -28
- package/dist/cjs/Fx.js.map +1 -1
- package/dist/cjs/RefArray.d.ts +116 -0
- package/dist/cjs/RefArray.d.ts.map +1 -0
- package/dist/cjs/RefArray.js +97 -0
- package/dist/cjs/RefArray.js.map +1 -0
- package/dist/cjs/RefSubject.d.ts +23 -20
- package/dist/cjs/RefSubject.d.ts.map +1 -1
- package/dist/cjs/RefSubject.js +358 -249
- package/dist/cjs/RefSubject.js.map +1 -1
- package/dist/cjs/RefTransform.d.ts +51 -0
- package/dist/cjs/RefTransform.d.ts.map +1 -0
- package/dist/cjs/RefTransform.js +96 -0
- package/dist/cjs/RefTransform.js.map +1 -0
- package/dist/cjs/Subject.d.ts.map +1 -1
- package/dist/cjs/Subject.js +2 -3
- package/dist/cjs/Subject.js.map +1 -1
- package/dist/cjs/catchAllCause.d.ts +6 -0
- package/dist/cjs/catchAllCause.d.ts.map +1 -1
- package/dist/cjs/catchAllCause.js +23 -2
- package/dist/cjs/catchAllCause.js.map +1 -1
- package/dist/cjs/combineAll.d.ts.map +1 -1
- package/dist/cjs/combineAll.js +4 -4
- package/dist/cjs/combineAll.js.map +1 -1
- package/dist/cjs/combineAllDiscard.d.ts.map +1 -1
- package/dist/cjs/combineAllDiscard.js +4 -4
- package/dist/cjs/combineAllDiscard.js.map +1 -1
- package/dist/cjs/data-first.d.ts +10 -0
- package/dist/cjs/data-first.d.ts.map +1 -1
- package/dist/cjs/data-first.js +10 -0
- package/dist/cjs/data-first.js.map +1 -1
- package/dist/cjs/empty.js +1 -1
- package/dist/cjs/empty.js.map +1 -1
- package/dist/cjs/exhaustMapCause.js +1 -1
- package/dist/cjs/exhaustMapCause.js.map +1 -1
- package/dist/cjs/exhaustMapLatestCause.js +1 -1
- package/dist/cjs/exhaustMapLatestCause.js.map +1 -1
- package/dist/cjs/failCause.d.ts +1 -0
- package/dist/cjs/failCause.d.ts.map +1 -1
- package/dist/cjs/failCause.js +5 -1
- package/dist/cjs/failCause.js.map +1 -1
- package/dist/cjs/filter.d.ts.map +1 -1
- package/dist/cjs/filter.js +1 -1
- package/dist/cjs/filter.js.map +1 -1
- package/dist/cjs/filterMap.d.ts.map +1 -1
- package/dist/cjs/filterMap.js +1 -1
- package/dist/cjs/filterMap.js.map +1 -1
- package/dist/cjs/fromArray.js +1 -1
- package/dist/cjs/fromArray.js.map +1 -1
- package/dist/cjs/fromDequeue.d.ts +5 -0
- package/dist/cjs/fromDequeue.d.ts.map +1 -0
- package/dist/cjs/fromDequeue.js +49 -0
- package/dist/cjs/fromDequeue.js.map +1 -0
- package/dist/cjs/fromEffect.d.ts.map +1 -1
- package/dist/cjs/fromEffect.js +9 -1
- package/dist/cjs/fromEffect.js.map +1 -1
- package/dist/cjs/fromEmitter.d.ts.map +1 -1
- package/dist/cjs/fromEmitter.js +4 -5
- package/dist/cjs/fromEmitter.js.map +1 -1
- package/dist/cjs/fromFxEffect.d.ts.map +1 -1
- package/dist/cjs/fromFxEffect.js +1 -1
- package/dist/cjs/fromFxEffect.js.map +1 -1
- package/dist/cjs/fromHub.d.ts +5 -0
- package/dist/cjs/fromHub.d.ts.map +1 -0
- package/dist/cjs/fromHub.js +34 -0
- package/dist/cjs/fromHub.js.map +1 -0
- package/dist/cjs/fromIterable.js +1 -1
- package/dist/cjs/fromIterable.js.map +1 -1
- package/dist/cjs/fromStream.d.ts +4 -0
- package/dist/cjs/fromStream.d.ts.map +1 -0
- package/dist/cjs/fromStream.js +34 -0
- package/dist/cjs/fromStream.js.map +1 -0
- package/dist/cjs/helpers.d.ts +3 -2
- package/dist/cjs/helpers.d.ts.map +1 -1
- package/dist/cjs/helpers.js +28 -69
- package/dist/cjs/helpers.js.map +1 -1
- package/dist/cjs/hold.d.ts +2 -4
- package/dist/cjs/hold.d.ts.map +1 -1
- package/dist/cjs/hold.js +0 -4
- package/dist/cjs/hold.js.map +1 -1
- package/dist/cjs/index.d.ts +36 -1
- package/dist/cjs/index.d.ts.map +1 -1
- package/dist/cjs/index.js +185 -119
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/keyed.d.ts.map +1 -1
- package/dist/cjs/keyed.js +23 -12
- package/dist/cjs/keyed.js.map +1 -1
- package/dist/cjs/mergeAll.d.ts.map +1 -1
- package/dist/cjs/mergeAll.js +1 -1
- package/dist/cjs/mergeAll.js.map +1 -1
- package/dist/cjs/mergeBufferConcurrently.d.ts +8 -0
- package/dist/cjs/mergeBufferConcurrently.d.ts.map +1 -0
- package/dist/cjs/mergeBufferConcurrently.js +95 -0
- package/dist/cjs/mergeBufferConcurrently.js.map +1 -0
- package/dist/cjs/mergeConcurrently.d.ts +3 -0
- package/dist/cjs/mergeConcurrently.d.ts.map +1 -0
- package/dist/cjs/mergeConcurrently.js +69 -0
- package/dist/cjs/mergeConcurrently.js.map +1 -0
- package/dist/cjs/multicast.d.ts +5 -5
- package/dist/cjs/multicast.d.ts.map +1 -1
- package/dist/cjs/multicast.js +14 -14
- package/dist/cjs/multicast.js.map +1 -1
- package/dist/cjs/never.js +1 -1
- package/dist/cjs/never.js.map +1 -1
- package/dist/cjs/observe.d.ts +3 -0
- package/dist/cjs/observe.d.ts.map +1 -1
- package/dist/cjs/observe.js +12 -7
- package/dist/cjs/observe.js.map +1 -1
- package/dist/cjs/onExit.d.ts +5 -0
- package/dist/cjs/onExit.d.ts.map +1 -0
- package/dist/cjs/onExit.js +33 -0
- package/dist/cjs/onExit.js.map +1 -0
- package/dist/cjs/orElse.d.ts +4 -0
- package/dist/cjs/orElse.d.ts.map +1 -0
- package/dist/cjs/orElse.js +34 -0
- package/dist/cjs/orElse.js.map +1 -0
- package/dist/cjs/promise.js +4 -4
- package/dist/cjs/promise.js.map +1 -1
- package/dist/cjs/provide.d.ts.map +1 -1
- package/dist/cjs/provide.js +6 -3
- package/dist/cjs/provide.js.map +1 -1
- package/dist/cjs/skipRepeats.d.ts +1 -1
- package/dist/cjs/skipRepeats.d.ts.map +1 -1
- package/dist/cjs/skipRepeats.js +7 -6
- package/dist/cjs/skipRepeats.js.map +1 -1
- package/dist/cjs/skipWhile.js +1 -1
- package/dist/cjs/skipWhile.js.map +1 -1
- package/dist/cjs/slice.js +3 -3
- package/dist/cjs/slice.js.map +1 -1
- package/dist/cjs/struct.d.ts +5 -0
- package/dist/cjs/struct.d.ts.map +1 -0
- package/dist/cjs/struct.js +10 -0
- package/dist/cjs/struct.js.map +1 -0
- package/dist/cjs/switchMapCause.d.ts +1 -0
- package/dist/cjs/switchMapCause.d.ts.map +1 -1
- package/dist/cjs/switchMapCause.js +13 -2
- package/dist/cjs/switchMapCause.js.map +1 -1
- package/dist/cjs/switchMatch.js +1 -1
- package/dist/cjs/switchMatch.js.map +1 -1
- package/dist/cjs/takeWhile.js +1 -1
- package/dist/cjs/takeWhile.js.map +1 -1
- package/dist/cjs/tap.d.ts.map +1 -1
- package/dist/cjs/tap.js +1 -1
- package/dist/cjs/tap.js.map +1 -1
- package/dist/cjs/tapCause.d.ts.map +1 -1
- package/dist/cjs/tapCause.js +5 -2
- package/dist/cjs/tapCause.js.map +1 -1
- package/dist/cjs/test-utils.js +2 -2
- package/dist/cjs/test-utils.js.map +1 -1
- package/dist/cjs/toArray.d.ts.map +1 -1
- package/dist/cjs/toArray.js +2 -3
- package/dist/cjs/toArray.js.map +1 -1
- package/dist/cjs/toEnqueue.d.ts +6 -0
- package/dist/cjs/toEnqueue.d.ts.map +1 -0
- package/dist/cjs/toEnqueue.js +9 -0
- package/dist/cjs/toEnqueue.js.map +1 -0
- package/dist/cjs/toStream.d.ts +4 -0
- package/dist/cjs/toStream.d.ts.map +1 -0
- package/dist/cjs/toStream.js +35 -0
- package/dist/cjs/toStream.js.map +1 -0
- package/dist/combineAll.d.ts.map +1 -1
- package/dist/combineAll.js +4 -4
- package/dist/combineAll.js.map +1 -1
- package/dist/combineAllDiscard.d.ts.map +1 -1
- package/dist/combineAllDiscard.js +4 -4
- package/dist/combineAllDiscard.js.map +1 -1
- package/dist/data-first.d.ts +10 -0
- package/dist/data-first.d.ts.map +1 -1
- package/dist/data-first.js +10 -0
- package/dist/data-first.js.map +1 -1
- package/dist/empty.js +1 -1
- package/dist/empty.js.map +1 -1
- package/dist/exhaustMapCause.js +1 -1
- package/dist/exhaustMapCause.js.map +1 -1
- package/dist/exhaustMapLatestCause.js +1 -1
- package/dist/exhaustMapLatestCause.js.map +1 -1
- package/dist/failCause.d.ts +1 -0
- package/dist/failCause.d.ts.map +1 -1
- package/dist/failCause.js +3 -0
- package/dist/failCause.js.map +1 -1
- package/dist/filter.d.ts.map +1 -1
- package/dist/filter.js +1 -1
- package/dist/filter.js.map +1 -1
- package/dist/filterMap.d.ts.map +1 -1
- package/dist/filterMap.js +1 -1
- package/dist/filterMap.js.map +1 -1
- package/dist/fromArray.js +1 -1
- package/dist/fromArray.js.map +1 -1
- package/dist/fromDequeue.d.ts +5 -0
- package/dist/fromDequeue.d.ts.map +1 -0
- package/dist/fromDequeue.js +21 -0
- package/dist/fromDequeue.js.map +1 -0
- package/dist/fromEffect.d.ts.map +1 -1
- package/dist/fromEffect.js +10 -2
- package/dist/fromEffect.js.map +1 -1
- package/dist/fromEmitter.d.ts.map +1 -1
- package/dist/fromEmitter.js +4 -5
- package/dist/fromEmitter.js.map +1 -1
- package/dist/fromFxEffect.d.ts.map +1 -1
- package/dist/fromFxEffect.js +1 -1
- package/dist/fromFxEffect.js.map +1 -1
- package/dist/fromHub.d.ts +5 -0
- package/dist/fromHub.d.ts.map +1 -0
- package/dist/fromHub.js +7 -0
- package/dist/fromHub.js.map +1 -0
- package/dist/fromIterable.js +1 -1
- package/dist/fromIterable.js.map +1 -1
- package/dist/fromStream.d.ts +4 -0
- package/dist/fromStream.d.ts.map +1 -0
- package/dist/fromStream.js +7 -0
- package/dist/fromStream.js.map +1 -0
- package/dist/helpers.d.ts +3 -2
- package/dist/helpers.d.ts.map +1 -1
- package/dist/helpers.js +28 -69
- package/dist/helpers.js.map +1 -1
- package/dist/hold.d.ts +2 -4
- package/dist/hold.d.ts.map +1 -1
- package/dist/hold.js +0 -4
- package/dist/hold.js.map +1 -1
- package/dist/index.d.ts +36 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +132 -116
- package/dist/index.js.map +1 -1
- package/dist/keyed.d.ts.map +1 -1
- package/dist/keyed.js +24 -13
- package/dist/keyed.js.map +1 -1
- package/dist/mergeAll.d.ts.map +1 -1
- package/dist/mergeAll.js +1 -1
- package/dist/mergeAll.js.map +1 -1
- package/dist/mergeBufferConcurrently.d.ts +8 -0
- package/dist/mergeBufferConcurrently.d.ts.map +1 -0
- package/dist/mergeBufferConcurrently.js +68 -0
- package/dist/mergeBufferConcurrently.js.map +1 -0
- package/dist/mergeConcurrently.d.ts +3 -0
- package/dist/mergeConcurrently.d.ts.map +1 -0
- package/dist/mergeConcurrently.js +42 -0
- package/dist/mergeConcurrently.js.map +1 -0
- package/dist/multicast.d.ts +5 -5
- package/dist/multicast.d.ts.map +1 -1
- package/dist/multicast.js +15 -15
- package/dist/multicast.js.map +1 -1
- package/dist/never.js +1 -1
- package/dist/never.js.map +1 -1
- package/dist/observe.d.ts +3 -0
- package/dist/observe.d.ts.map +1 -1
- package/dist/observe.js +9 -6
- package/dist/observe.js.map +1 -1
- package/dist/onExit.d.ts +5 -0
- package/dist/onExit.d.ts.map +1 -0
- package/dist/onExit.js +6 -0
- package/dist/onExit.js.map +1 -0
- package/dist/orElse.d.ts +4 -0
- package/dist/orElse.d.ts.map +1 -0
- package/dist/orElse.js +7 -0
- package/dist/orElse.js.map +1 -0
- package/dist/promise.js +4 -4
- package/dist/promise.js.map +1 -1
- package/dist/provide.d.ts.map +1 -1
- package/dist/provide.js +6 -3
- package/dist/provide.js.map +1 -1
- package/dist/skipRepeats.d.ts +1 -1
- package/dist/skipRepeats.d.ts.map +1 -1
- package/dist/skipRepeats.js +4 -6
- package/dist/skipRepeats.js.map +1 -1
- package/dist/skipWhile.js +1 -1
- package/dist/skipWhile.js.map +1 -1
- package/dist/slice.js +3 -3
- package/dist/slice.js.map +1 -1
- package/dist/struct.d.ts +5 -0
- package/dist/struct.d.ts.map +1 -0
- package/dist/struct.js +6 -0
- package/dist/struct.js.map +1 -0
- package/dist/switchMapCause.d.ts +1 -0
- package/dist/switchMapCause.d.ts.map +1 -1
- package/dist/switchMapCause.js +11 -1
- package/dist/switchMapCause.js.map +1 -1
- package/dist/switchMatch.js +1 -1
- package/dist/switchMatch.js.map +1 -1
- package/dist/takeWhile.js +1 -1
- package/dist/takeWhile.js.map +1 -1
- package/dist/tap.d.ts.map +1 -1
- package/dist/tap.js +1 -1
- package/dist/tap.js.map +1 -1
- package/dist/tapCause.d.ts.map +1 -1
- package/dist/tapCause.js +5 -2
- package/dist/tapCause.js.map +1 -1
- package/dist/test-utils.js +2 -2
- package/dist/test-utils.js.map +1 -1
- package/dist/toArray.d.ts.map +1 -1
- package/dist/toArray.js +2 -3
- package/dist/toArray.js.map +1 -1
- package/dist/toEnqueue.d.ts +6 -0
- package/dist/toEnqueue.d.ts.map +1 -0
- package/dist/toEnqueue.js +5 -0
- package/dist/toEnqueue.js.map +1 -0
- package/dist/toStream.d.ts +4 -0
- package/dist/toStream.d.ts.map +1 -0
- package/dist/toStream.js +8 -0
- package/dist/toStream.js.map +1 -0
- package/dist/tsconfig.cjs.build.tsbuildinfo +1 -1
- package/package.json +5 -5
- package/src/Computed.ts +114 -0
- package/src/Filtered.ts +112 -0
- package/src/Fx.ts +17 -42
- package/src/RefArray.ts +226 -0
- package/src/RefSubject.test.ts +67 -6
- package/src/RefSubject.ts +601 -581
- package/src/RefTransform.ts +134 -0
- package/src/Subject.ts +4 -13
- package/src/catchAllCause.ts +43 -2
- package/src/combineAll.ts +16 -13
- package/src/combineAllDiscard.ts +16 -13
- package/src/data-first.ts +10 -0
- package/src/empty.ts +1 -1
- package/src/exhaustMapCause.ts +1 -1
- package/src/exhaustMapLatestCause.ts +1 -1
- package/src/failCause.ts +4 -0
- package/src/filter.ts +1 -3
- package/src/filterMap.ts +8 -1
- package/src/fromArray.ts +1 -1
- package/src/fromDequeue.ts +39 -0
- package/src/fromEffect.ts +12 -2
- package/src/fromEmitter.ts +4 -10
- package/src/fromFxEffect.ts +3 -1
- package/src/fromHub.ts +10 -0
- package/src/fromIterable.ts +1 -1
- package/src/helpers.ts +73 -106
- package/src/hold.ts +1 -7
- package/src/index.ts +573 -607
- package/src/keyed.ts +45 -28
- package/src/mergeAll.ts +8 -5
- package/src/mergeBufferConcurrently.test.ts +37 -0
- package/src/mergeBufferConcurrently.ts +105 -0
- package/src/mergeConcurrently.test.ts +20 -0
- package/src/mergeConcurrently.ts +57 -0
- package/src/multicast.ts +30 -22
- package/src/never.ts +1 -1
- package/src/observe.ts +16 -7
- package/src/onExit.ts +13 -0
- package/src/orElse.ts +16 -0
- package/src/promise.ts +4 -4
- package/src/provide.ts +9 -7
- package/src/skipRepeats.ts +5 -7
- package/src/skipWhile.ts +1 -1
- package/src/slice.ts +3 -3
- package/src/struct.ts +18 -0
- package/src/switchMapCause.ts +17 -1
- package/src/switchMatch.ts +1 -1
- package/src/takeWhile.ts +1 -1
- package/src/tap.ts +5 -1
- package/src/tapCause.ts +8 -6
- package/src/test-utils.ts +2 -2
- package/src/toArray.ts +5 -4
- package/src/toEnqueue.ts +13 -0
- package/tsconfig.build.json +2 -1
- package/tsconfig.build.tsbuildinfo +1 -1
- package/vite.config.js +3 -0
package/src/keyed.ts
CHANGED
|
@@ -4,11 +4,13 @@ import * as ReadonlyArray from '@effect/data/ReadonlyArray'
|
|
|
4
4
|
import * as Cause from '@effect/io/Cause'
|
|
5
5
|
import * as Effect from '@effect/io/Effect'
|
|
6
6
|
import * as Fiber from '@effect/io/Fiber'
|
|
7
|
+
import * as Scope from '@effect/io/Scope'
|
|
7
8
|
|
|
8
9
|
import { Fx, Sink } from './Fx.js'
|
|
9
|
-
import { RefSubject } from './RefSubject.js'
|
|
10
|
+
import { RefSubject, makeRef } from './RefSubject.js'
|
|
10
11
|
import { Subject, makeHoldSubject } from './Subject.js'
|
|
11
12
|
import { ScopedFork, withScopedFork } from './helpers.js'
|
|
13
|
+
import { skipRepeats } from './skipRepeats.js'
|
|
12
14
|
|
|
13
15
|
export function keyed<R, E, A, R2, E2, B, C>(
|
|
14
16
|
fx: Fx<R, E, readonly A[]>,
|
|
@@ -16,13 +18,13 @@ export function keyed<R, E, A, R2, E2, B, C>(
|
|
|
16
18
|
getKey: (a: A) => C,
|
|
17
19
|
): Fx<R | R2, E | E2, readonly B[]> {
|
|
18
20
|
return Fx(<R3>(sink: Sink<R3, E | E2, readonly B[]>) =>
|
|
19
|
-
withScopedFork((fork) =>
|
|
21
|
+
withScopedFork((fork, scope) =>
|
|
20
22
|
Effect.gen(function* ($) {
|
|
21
23
|
const state = createKeyedState<A, B, C>()
|
|
22
24
|
const emit = emitWhenReady(state, getKey)
|
|
23
25
|
|
|
24
26
|
// Let output emit to the sink, it is closes by the surrounding scope
|
|
25
|
-
yield* $(fork(state.output.run(sink)))
|
|
27
|
+
yield* $(fork(skipRepeats(state.output).run(sink)))
|
|
26
28
|
|
|
27
29
|
// Listen to the input and update the state
|
|
28
30
|
yield* $(
|
|
@@ -35,6 +37,7 @@ export function keyed<R, E, A, R2, E2, B, C>(
|
|
|
35
37
|
getKey,
|
|
36
38
|
f,
|
|
37
39
|
fork,
|
|
40
|
+
scope,
|
|
38
41
|
emit,
|
|
39
42
|
error: sink.error,
|
|
40
43
|
}),
|
|
@@ -78,6 +81,7 @@ function updateState<A, B, C, R2, E2, R3>({
|
|
|
78
81
|
updated,
|
|
79
82
|
f,
|
|
80
83
|
fork,
|
|
84
|
+
scope,
|
|
81
85
|
emit,
|
|
82
86
|
error,
|
|
83
87
|
getKey,
|
|
@@ -86,31 +90,42 @@ function updateState<A, B, C, R2, E2, R3>({
|
|
|
86
90
|
updated: readonly A[]
|
|
87
91
|
f: (fx: RefSubject<never, A>) => Fx<R2, E2, B>
|
|
88
92
|
fork: ScopedFork
|
|
93
|
+
scope: Scope.Scope
|
|
89
94
|
emit: Effect.Effect<never, never, void>
|
|
90
95
|
error: (e: Cause.Cause<E2>) => Effect.Effect<R3, never, void>
|
|
91
96
|
getKey: (a: A) => C
|
|
92
97
|
}) {
|
|
93
|
-
return Effect.
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
)
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
98
|
+
return Effect.provideService(
|
|
99
|
+
Effect.gen(function* ($) {
|
|
100
|
+
const { added, removed, unchanged } = diffValues(state, updated, getKey)
|
|
101
|
+
|
|
102
|
+
// Remove values that are no longer in the stream
|
|
103
|
+
yield* $(Effect.forEach(removed, (key) => removeValue(state, key), { discard: true }))
|
|
104
|
+
|
|
105
|
+
// Update values that are still in the stream
|
|
106
|
+
yield* $(
|
|
107
|
+
Effect.forEach(unchanged, (value) => updateValue(state, value, getKey), {
|
|
108
|
+
concurrency: 'unbounded',
|
|
109
|
+
discard: true,
|
|
110
|
+
}),
|
|
111
|
+
)
|
|
112
|
+
|
|
113
|
+
// Add values that are new to the stream
|
|
114
|
+
yield* $(
|
|
115
|
+
Effect.forEach(added, (value) => addValue({ state, value, f, fork, emit, error, getKey }), {
|
|
116
|
+
concurrency: 'unbounded',
|
|
117
|
+
discard: true,
|
|
118
|
+
}),
|
|
119
|
+
)
|
|
120
|
+
|
|
121
|
+
// If nothing was added, emit the current values
|
|
122
|
+
if (added.length === 0) {
|
|
123
|
+
yield* $(emit)
|
|
124
|
+
}
|
|
125
|
+
}),
|
|
126
|
+
Scope.Scope,
|
|
127
|
+
scope,
|
|
128
|
+
)
|
|
114
129
|
}
|
|
115
130
|
|
|
116
131
|
function diffValues<A, B, C>(
|
|
@@ -186,7 +201,7 @@ function addValue<A, B, C, R2, E2, R3>({
|
|
|
186
201
|
}) {
|
|
187
202
|
return Effect.gen(function* ($) {
|
|
188
203
|
const key = getKey(value)
|
|
189
|
-
const subject =
|
|
204
|
+
const subject = yield* $(makeRef<never, never, A>(Effect.succeed(value)))
|
|
190
205
|
const fx = f(subject)
|
|
191
206
|
const fiber = yield* $(
|
|
192
207
|
fork(
|
|
@@ -223,7 +238,7 @@ function emitWhenReady<A, B, C>(state: KeyedState<A, B, C>, getKey: (a: A) => C)
|
|
|
223
238
|
return Effect.suspend(() => {
|
|
224
239
|
// Fast path: if we don't have enough values, don't emit
|
|
225
240
|
if (MutableHashMap.size(state.values) !== state.previous.length) {
|
|
226
|
-
return Effect.unit
|
|
241
|
+
return Effect.unit
|
|
227
242
|
}
|
|
228
243
|
|
|
229
244
|
const values = ReadonlyArray.filterMap(state.previous, (value) =>
|
|
@@ -235,10 +250,12 @@ function emitWhenReady<A, B, C>(state: KeyedState<A, B, C>, getKey: (a: A) => C)
|
|
|
235
250
|
return state.output.event(values)
|
|
236
251
|
}
|
|
237
252
|
|
|
238
|
-
return Effect.unit
|
|
253
|
+
return Effect.unit
|
|
239
254
|
})
|
|
240
255
|
}
|
|
241
256
|
|
|
242
257
|
function endAll<A, B, C>(state: KeyedState<A, B, C>) {
|
|
243
|
-
return Effect.
|
|
258
|
+
return Effect.forEach(state.subjects, ([, subject]) => subject.end(), {
|
|
259
|
+
concurrency: 'unbounded',
|
|
260
|
+
})
|
|
244
261
|
}
|
package/src/mergeAll.ts
CHANGED
|
@@ -10,12 +10,15 @@ export function mergeAll<FXS extends ReadonlyArray<Fx<any, any, any>>>(
|
|
|
10
10
|
...fxs: FXS
|
|
11
11
|
): Fx<Fx.ResourcesOf<FXS[number]>, Fx.ErrorsOf<FXS[number]>, Fx.OutputOf<FXS[number]>> {
|
|
12
12
|
return Fx((sink) =>
|
|
13
|
-
Effect.
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
13
|
+
Effect.forEach(
|
|
14
|
+
fxs,
|
|
15
|
+
(fx) =>
|
|
16
|
+
fx.run(
|
|
17
|
+
Sink(sink.event, (cause) =>
|
|
18
|
+
Cause.isInterruptedOnly(cause) ? Effect.unit : sink.error(cause),
|
|
19
|
+
),
|
|
17
20
|
),
|
|
18
|
-
|
|
21
|
+
{ concurrency: 'unbounded', discard: true },
|
|
19
22
|
),
|
|
20
23
|
)
|
|
21
24
|
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { millis } from '@effect/data/Duration'
|
|
2
|
+
import { describe } from 'vitest'
|
|
3
|
+
|
|
4
|
+
import { at } from './at.js'
|
|
5
|
+
import { fromArray } from './fromArray.js'
|
|
6
|
+
import { mergeAll } from './mergeAll.js'
|
|
7
|
+
import { mergeBufferConcurrently } from './mergeBufferConcurrently.js'
|
|
8
|
+
import { testCollectAll } from './test-utils.js'
|
|
9
|
+
|
|
10
|
+
describe(__filename, () => {
|
|
11
|
+
describe(mergeBufferConcurrently.name, () => {
|
|
12
|
+
testCollectAll(
|
|
13
|
+
'buffers values until the previous stream completes',
|
|
14
|
+
mergeBufferConcurrently(
|
|
15
|
+
at(1, millis(50)),
|
|
16
|
+
mergeAll(at(2, millis(0)), at(3, millis(20)), at(4, millis(40))),
|
|
17
|
+
),
|
|
18
|
+
[1, 2, 3, 4],
|
|
19
|
+
)
|
|
20
|
+
|
|
21
|
+
testCollectAll(
|
|
22
|
+
'emits immediately if previous stream has ended',
|
|
23
|
+
mergeBufferConcurrently(
|
|
24
|
+
at(1, millis(0)),
|
|
25
|
+
mergeAll(at(2, millis(5)), at(3, millis(10)), at(4, millis(20))),
|
|
26
|
+
mergeAll(at(5, millis(0)), at(6, millis(5)), at(7, millis(10))),
|
|
27
|
+
),
|
|
28
|
+
[1, 2, 3, 4, 5, 6, 7],
|
|
29
|
+
)
|
|
30
|
+
|
|
31
|
+
testCollectAll(
|
|
32
|
+
'merges multiple synchronous streams',
|
|
33
|
+
mergeBufferConcurrently(fromArray([1, 2, 3]), fromArray([4, 5, 6])),
|
|
34
|
+
[1, 2, 3, 4, 5, 6],
|
|
35
|
+
)
|
|
36
|
+
})
|
|
37
|
+
})
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import * as Chunk from '@effect/data/Chunk'
|
|
2
|
+
import * as Effect from '@effect/io/Effect'
|
|
3
|
+
|
|
4
|
+
import { Fx, Sink } from './Fx.js'
|
|
5
|
+
import { empty } from './empty.js'
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Merges n Fx concurrently, emitting the values in order of the streams are provided.
|
|
9
|
+
* For example, Fx at index 0 will emit all of its values first, when it completes, Fx at index 1 will emit all of its values, and so on.
|
|
10
|
+
* When there is asynchrony, the indexes which are not yet ready are buffered.
|
|
11
|
+
*/
|
|
12
|
+
export function mergeBufferConcurrently<FXS extends Fx.TupleAny>(
|
|
13
|
+
...fxs: FXS
|
|
14
|
+
): Fx<Fx.ResourcesOf<FXS[number]>, Fx.ErrorsOf<FXS[number]>, Fx.OutputOf<FXS[number]>> {
|
|
15
|
+
if (fxs.length === 0) return empty()
|
|
16
|
+
if (fxs.length === 1) return fxs[0]
|
|
17
|
+
|
|
18
|
+
return Fx(<R2>(sink: Sink<R2, Fx.ErrorsOf<FXS[number]>, Fx.OutputOf<FXS[number]>>) =>
|
|
19
|
+
Effect.suspend(() => {
|
|
20
|
+
type O = Fx.OutputOf<FXS[number]>
|
|
21
|
+
|
|
22
|
+
const finished = new Map<number, Chunk.Chunk<O>>()
|
|
23
|
+
let currentIndex = 0
|
|
24
|
+
|
|
25
|
+
function onFinished(index: number, buffer: Chunk.Chunk<O>): Effect.Effect<R2, never, void> {
|
|
26
|
+
if (currentIndex < index) {
|
|
27
|
+
// If the current index is behind, buffer the value
|
|
28
|
+
return Effect.sync(() => {
|
|
29
|
+
finished.set(index, buffer)
|
|
30
|
+
})
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
if (Chunk.size(buffer) === 0) {
|
|
34
|
+
return next(index)
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
return Effect.flatMap(Effect.all(Chunk.map(buffer, sink.event)), () => next(index))
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
function next(index: number): Effect.Effect<R2, never, void> {
|
|
41
|
+
finished.delete(index)
|
|
42
|
+
|
|
43
|
+
const nextIndex = ++currentIndex
|
|
44
|
+
|
|
45
|
+
if (finished.has(nextIndex)) {
|
|
46
|
+
return onFinished(nextIndex, finished.get(nextIndex) as Chunk.Chunk<O>)
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
return Effect.unit
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
return Effect.asUnit(
|
|
53
|
+
Effect.all(
|
|
54
|
+
fxs.map((fx, index) =>
|
|
55
|
+
Effect.suspend(() => {
|
|
56
|
+
if (index === currentIndex) return Effect.flatMap(fx.run(sink), () => next(index))
|
|
57
|
+
|
|
58
|
+
let buffer: Chunk.Chunk<O> = Chunk.empty()
|
|
59
|
+
let isEmitting = false
|
|
60
|
+
|
|
61
|
+
return Effect.flatMap(
|
|
62
|
+
fx.run(
|
|
63
|
+
Sink(
|
|
64
|
+
(o) =>
|
|
65
|
+
Effect.suspend(
|
|
66
|
+
Effect.unifiedFn(() => {
|
|
67
|
+
// The current index is emitting now
|
|
68
|
+
if (isEmitting) {
|
|
69
|
+
return sink.event(o)
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// This index is ready to emit values
|
|
73
|
+
if (index === currentIndex) {
|
|
74
|
+
if (Chunk.size(buffer) === 0) return sink.event(o)
|
|
75
|
+
|
|
76
|
+
// Drain the current buffer first
|
|
77
|
+
const toEmit = Chunk.append(buffer, o)
|
|
78
|
+
// Clear the buffer
|
|
79
|
+
buffer = Chunk.empty()
|
|
80
|
+
// Fast-path for remaining values
|
|
81
|
+
isEmitting = true
|
|
82
|
+
|
|
83
|
+
// Emit the values
|
|
84
|
+
return Effect.all(Chunk.map(toEmit, sink.event))
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// Otherwise, buffer the value
|
|
88
|
+
buffer = Chunk.append(buffer, o)
|
|
89
|
+
|
|
90
|
+
return Effect.unit
|
|
91
|
+
}),
|
|
92
|
+
),
|
|
93
|
+
sink.error,
|
|
94
|
+
),
|
|
95
|
+
),
|
|
96
|
+
() => (isEmitting ? next(index) : onFinished(index, buffer)),
|
|
97
|
+
)
|
|
98
|
+
}),
|
|
99
|
+
),
|
|
100
|
+
{ concurrency: 'unbounded' },
|
|
101
|
+
),
|
|
102
|
+
)
|
|
103
|
+
}),
|
|
104
|
+
)
|
|
105
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { millis } from '@effect/data/Duration'
|
|
2
|
+
import { describe } from 'vitest'
|
|
3
|
+
|
|
4
|
+
import { at } from './at.js'
|
|
5
|
+
import { mergeAll } from './mergeAll.js'
|
|
6
|
+
import { mergeConcurrently } from './mergeConcurrently.js'
|
|
7
|
+
import { testCollectAll } from './test-utils.js'
|
|
8
|
+
|
|
9
|
+
describe(__filename, () => {
|
|
10
|
+
describe(mergeConcurrently.name, () => {
|
|
11
|
+
testCollectAll(
|
|
12
|
+
'merges multiple streams together taking 1 value from each in order, but always the latest value from each stream',
|
|
13
|
+
mergeConcurrently(
|
|
14
|
+
at(1, millis(100)),
|
|
15
|
+
mergeAll(at(2, millis(0)), at(3, millis(30)), at(4, millis(60))),
|
|
16
|
+
),
|
|
17
|
+
[1, 4],
|
|
18
|
+
)
|
|
19
|
+
})
|
|
20
|
+
})
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import * as Effect from '@effect/io/Effect'
|
|
2
|
+
import * as Fiber from '@effect/io/Fiber'
|
|
3
|
+
|
|
4
|
+
import { Fx, Sink } from './Fx.js'
|
|
5
|
+
import { empty } from './empty.js'
|
|
6
|
+
|
|
7
|
+
export function mergeConcurrently<FXS extends ReadonlyArray<Fx<any, any, any>>>(
|
|
8
|
+
...fxs: FXS
|
|
9
|
+
): Fx<Fx.ResourcesOf<FXS[number]>, Fx.ErrorsOf<FXS[number]>, Fx.OutputOf<FXS[number]>> {
|
|
10
|
+
if (fxs.length === 0) return empty()
|
|
11
|
+
if (fxs.length === 1) return fxs[0]
|
|
12
|
+
|
|
13
|
+
return Fx(<R2>(sink: Sink<R2, Fx.ErrorsOf<FXS[number]>, Fx.OutputOf<FXS[number]>>) =>
|
|
14
|
+
Effect.gen(function* ($) {
|
|
15
|
+
let currentIndex = 0
|
|
16
|
+
const values = new Map<number, Fx.OutputOf<FXS[number]>>()
|
|
17
|
+
const fibers: Fiber.Fiber<never, void>[] = []
|
|
18
|
+
|
|
19
|
+
for (let i = 0; i < fxs.length; ++i) {
|
|
20
|
+
fibers[i] = yield* $(
|
|
21
|
+
Effect.fork(fxs[i].run(Sink((value) => onValue(i, value), sink.error))),
|
|
22
|
+
)
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
function emit(index: number): Effect.Effect<R2, never, void> {
|
|
26
|
+
if (index === currentIndex && values.has(index)) {
|
|
27
|
+
return Effect.gen(function* ($) {
|
|
28
|
+
// Send this value to the sink
|
|
29
|
+
yield* $(sink.event(values.get(index) as Fx.OutputOf<FXS[number]>))
|
|
30
|
+
|
|
31
|
+
// Interrupt the underlying Fiber
|
|
32
|
+
yield* $(Fiber.interruptFork(fibers[index]))
|
|
33
|
+
|
|
34
|
+
const next = ++currentIndex
|
|
35
|
+
|
|
36
|
+
// If there's a value for the next index, emit it
|
|
37
|
+
if (values.has(next)) {
|
|
38
|
+
yield* $(emit(next))
|
|
39
|
+
}
|
|
40
|
+
})
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
return Effect.unit
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
function onValue(index: number, value: Fx.OutputOf<FXS[number]>) {
|
|
47
|
+
return Effect.suspend(() => {
|
|
48
|
+
values.set(index, value)
|
|
49
|
+
|
|
50
|
+
return emit(index)
|
|
51
|
+
})
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
yield* $(Fiber.joinAll(fibers))
|
|
55
|
+
}),
|
|
56
|
+
)
|
|
57
|
+
}
|
package/src/multicast.ts
CHANGED
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
import type * as Context from '@effect/data/Context'
|
|
2
|
-
import type { Trace } from '@effect/data/Debug'
|
|
3
2
|
import { identity } from '@effect/data/Function'
|
|
4
3
|
import type * as Cause from '@effect/io/Cause'
|
|
5
4
|
import * as Effect from '@effect/io/Effect'
|
|
6
5
|
import * as Fiber from '@effect/io/Fiber'
|
|
7
6
|
|
|
8
|
-
import { FxTypeId
|
|
7
|
+
import { FxTypeId } from './Fx.js'
|
|
9
8
|
import type { Fx, Sink } from './Fx.js'
|
|
10
9
|
|
|
11
10
|
export function multicast<R, E, A>(fx: Fx<R, E, A>): Fx<R, E, A> {
|
|
@@ -24,8 +23,10 @@ export class MulticastFx<R, E, A> implements Fx<R, E, A>, Sink<never, E, A> {
|
|
|
24
23
|
_A: identity,
|
|
25
24
|
}
|
|
26
25
|
|
|
27
|
-
|
|
28
|
-
|
|
26
|
+
/**@internal */
|
|
27
|
+
public observers: Array<MulticastObserver<any, E, A>> = []
|
|
28
|
+
/**@internal */
|
|
29
|
+
public fiber: Fiber.RuntimeFiber<never, void> | undefined
|
|
29
30
|
|
|
30
31
|
constructor(readonly fx: Fx<R, E, A>) {
|
|
31
32
|
this.run = this.run.bind(this)
|
|
@@ -39,40 +40,47 @@ export class MulticastFx<R, E, A> implements Fx<R, E, A>, Sink<never, E, A> {
|
|
|
39
40
|
// eslint-disable-next-line @typescript-eslint/no-this-alias
|
|
40
41
|
const that = this
|
|
41
42
|
|
|
42
|
-
return Effect.
|
|
43
|
-
|
|
44
|
-
|
|
43
|
+
return Effect.flatMap(Effect.context<R2>(), (context) =>
|
|
44
|
+
Effect.suspend(() => {
|
|
45
|
+
const observer: MulticastObserver<R2, E, A> = { sink, context }
|
|
45
46
|
|
|
46
|
-
|
|
47
|
-
that.fiber = yield* $(Effect.forkDaemon(that.fx.run(that)))
|
|
48
|
-
}
|
|
47
|
+
const effects: Array<Effect.Effect<R, never, void>> = []
|
|
49
48
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
49
|
+
if (observers.push(observer) === 1) {
|
|
50
|
+
effects.push(
|
|
51
|
+
Effect.tap(Effect.forkDaemon(that.fx.run(that)), (fiber) =>
|
|
52
|
+
Effect.sync(() => (that.fiber = fiber)),
|
|
53
|
+
),
|
|
54
|
+
)
|
|
55
|
+
}
|
|
54
56
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
+
effects.push(
|
|
58
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
59
|
+
Effect.suspend(() => Effect.ensuring(Fiber.await(that.fiber!), that.removeSink(sink))),
|
|
60
|
+
)
|
|
61
|
+
|
|
62
|
+
return Effect.all(effects)
|
|
63
|
+
}),
|
|
64
|
+
)
|
|
57
65
|
}
|
|
58
66
|
|
|
59
67
|
event(a: A) {
|
|
60
68
|
if (this.observers.length === 0) {
|
|
61
|
-
return Effect.unit
|
|
69
|
+
return Effect.unit
|
|
62
70
|
}
|
|
63
71
|
|
|
64
72
|
return Effect.suspend(() =>
|
|
65
|
-
Effect.
|
|
73
|
+
Effect.forEach(this.observers.slice(0), (observer) => this.runEvent(observer, a)),
|
|
66
74
|
)
|
|
67
75
|
}
|
|
68
76
|
|
|
69
77
|
error(cause: Cause.Cause<E>) {
|
|
70
78
|
if (this.observers.length === 0) {
|
|
71
|
-
return Effect.unit
|
|
79
|
+
return Effect.unit
|
|
72
80
|
}
|
|
73
81
|
|
|
74
82
|
return Effect.suspend(() =>
|
|
75
|
-
Effect.
|
|
83
|
+
Effect.forEach(this.observers.slice(0), (observer) => this.runError(observer, cause)),
|
|
76
84
|
)
|
|
77
85
|
}
|
|
78
86
|
|
|
@@ -94,7 +102,7 @@ export class MulticastFx<R, E, A> implements Fx<R, E, A>, Sink<never, E, A> {
|
|
|
94
102
|
return Effect.suspend(() => {
|
|
95
103
|
const { observers } = this
|
|
96
104
|
|
|
97
|
-
if (observers.length === 0) return Effect.unit
|
|
105
|
+
if (observers.length === 0) return Effect.unit
|
|
98
106
|
|
|
99
107
|
const index = observers.findIndex((o) => o.sink === sink)
|
|
100
108
|
|
|
@@ -111,7 +119,7 @@ export class MulticastFx<R, E, A> implements Fx<R, E, A>, Sink<never, E, A> {
|
|
|
111
119
|
}
|
|
112
120
|
}
|
|
113
121
|
|
|
114
|
-
return Effect.unit
|
|
122
|
+
return Effect.unit
|
|
115
123
|
})
|
|
116
124
|
}
|
|
117
125
|
}
|
package/src/never.ts
CHANGED
package/src/observe.ts
CHANGED
|
@@ -11,22 +11,31 @@ export function observe<R, E, A, R2, E2>(
|
|
|
11
11
|
fx: Fx<R, E, A>,
|
|
12
12
|
f: (a: A) => Effect.Effect<R2, E2, void>,
|
|
13
13
|
): Effect.Effect<R | R2 | Scope, E | E2, void> {
|
|
14
|
-
return Effect.
|
|
15
|
-
const deferred = yield* $(Deferred.make<E | E2, void>())
|
|
14
|
+
return Effect.flatMap(Deferred.make<E | E2, void>(), (deferred) => {
|
|
16
15
|
const error = (cause: Cause.Cause<E | E2>) => Deferred.failCause(deferred, cause)
|
|
17
16
|
const end = () => Deferred.succeed(deferred, undefined)
|
|
18
17
|
|
|
19
|
-
|
|
18
|
+
return Effect.flatMap(
|
|
20
19
|
Effect.forkScoped(
|
|
21
20
|
Effect.flatMap(fx.run(Sink((a: A) => Effect.catchAllCause(f(a), error), error)), end),
|
|
22
21
|
),
|
|
22
|
+
(fiber) => Effect.flatMap(Deferred.await(deferred), () => Fiber.interruptFork(fiber)),
|
|
23
23
|
)
|
|
24
|
-
|
|
25
|
-
yield* $(Deferred.await(deferred))
|
|
26
|
-
yield* $(Fiber.interruptFork(fiber))
|
|
27
24
|
})
|
|
28
25
|
}
|
|
29
26
|
|
|
30
27
|
export function drain<R, E, A>(fx: Fx<R, E, A>): Effect.Effect<R | Scope, E, void> {
|
|
31
|
-
return observe(fx,
|
|
28
|
+
return observe(fx, Effect.unit as any)
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export function forkScoped<R, E, A>(
|
|
32
|
+
fx: Fx<R, E, A>,
|
|
33
|
+
): Effect.Effect<R | Scope, never, Fiber.RuntimeFiber<E, void>> {
|
|
34
|
+
return Effect.forkScoped(drain(fx))
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export function fork<R, E, A>(
|
|
38
|
+
fx: Fx<R, E, A>,
|
|
39
|
+
): Effect.Effect<R | Scope, never, Fiber.RuntimeFiber<E, void>> {
|
|
40
|
+
return Effect.fork(drain(fx))
|
|
32
41
|
}
|
package/src/onExit.ts
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import * as Effect from '@effect/io/Effect'
|
|
2
|
+
import * as Exit from '@effect/io/Exit'
|
|
3
|
+
|
|
4
|
+
import { Fx } from './Fx.js'
|
|
5
|
+
|
|
6
|
+
export function onExit<R, E, A, R2, E2, B>(
|
|
7
|
+
fx: Fx<R, E, A>,
|
|
8
|
+
f: (exit: Exit.Exit<E, void>) => Effect.Effect<R2, E2, B>,
|
|
9
|
+
): Fx<R | R2, E | E2, A> {
|
|
10
|
+
return Fx((sink) =>
|
|
11
|
+
Effect.onExit(fx.run(sink), (exit) => Effect.catchAllCause(f(exit), sink.error)),
|
|
12
|
+
)
|
|
13
|
+
}
|
package/src/orElse.ts
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import * as Cause from '@effect/io/Cause'
|
|
2
|
+
import * as Effect from '@effect/io/Effect'
|
|
3
|
+
|
|
4
|
+
import { Fx } from './Fx.js'
|
|
5
|
+
import { observe } from './observe.js'
|
|
6
|
+
|
|
7
|
+
export function orElse<R, E, A, R2, E2, B>(
|
|
8
|
+
self: Fx<R, E, A>,
|
|
9
|
+
that: (cause: Cause.Cause<E>) => Fx<R2, E2, B>,
|
|
10
|
+
): Fx<R | R2, E2, A | B> {
|
|
11
|
+
return Fx((sink) =>
|
|
12
|
+
Effect.catchAllCause(Effect.scoped(observe(self, sink.event)), (cause) =>
|
|
13
|
+
that(cause).run(sink),
|
|
14
|
+
),
|
|
15
|
+
)
|
|
16
|
+
}
|
package/src/promise.ts
CHANGED
|
@@ -26,14 +26,14 @@ export function tryCatchPromise<A, E>(
|
|
|
26
26
|
f: () => Promise<A>,
|
|
27
27
|
g: (error: unknown) => E,
|
|
28
28
|
): Fx<never, E, A> {
|
|
29
|
-
return fromEffect(Effect.
|
|
29
|
+
return fromEffect(Effect.tryPromise({ try: f, catch: g }))
|
|
30
30
|
}
|
|
31
31
|
|
|
32
32
|
export function tryCatchPromiseInterrupt<A, E>(
|
|
33
33
|
f: (signal: AbortSignal) => Promise<A>,
|
|
34
34
|
g: (error: unknown) => E,
|
|
35
35
|
): Fx<never, E, A> {
|
|
36
|
-
return fromEffect(Effect.
|
|
36
|
+
return fromEffect(Effect.tryPromiseInterrupt({ try: f, catch: g }))
|
|
37
37
|
}
|
|
38
38
|
|
|
39
39
|
export function promiseFx<R, E, A>(f: () => Promise<Fx<R, E, A>>): Fx<R, E, A> {
|
|
@@ -60,12 +60,12 @@ export function tryCatchPromiseFx<R, E, A, E2>(
|
|
|
60
60
|
f: () => Promise<Fx<R, E, A>>,
|
|
61
61
|
g: (error: unknown) => E2,
|
|
62
62
|
): Fx<R, E | E2, A> {
|
|
63
|
-
return fromFxEffect(Effect.
|
|
63
|
+
return fromFxEffect(Effect.tryPromise({ try: f, catch: g }))
|
|
64
64
|
}
|
|
65
65
|
|
|
66
66
|
export function tryCatchPromiseInterruptFx<R, E, A, E2>(
|
|
67
67
|
f: (signal: AbortSignal) => Promise<Fx<R, E, A>>,
|
|
68
68
|
g: (error: unknown) => E2,
|
|
69
69
|
): Fx<R, E | E2, A> {
|
|
70
|
-
return fromFxEffect(Effect.
|
|
70
|
+
return fromFxEffect(Effect.tryPromiseInterrupt({ try: f, catch: g }))
|
|
71
71
|
}
|
package/src/provide.ts
CHANGED
|
@@ -12,7 +12,7 @@ export function provideContext<R, E, A>(
|
|
|
12
12
|
): Fx<never, E, A> {
|
|
13
13
|
return Fx(
|
|
14
14
|
<R2>(sink: Sink<R2, E, A>): Effect.Effect<R2, never, void> =>
|
|
15
|
-
Effect.
|
|
15
|
+
Effect.mapInputContext(fx.run(sink), (ctx) => Context.merge(ctx, context)),
|
|
16
16
|
)
|
|
17
17
|
}
|
|
18
18
|
|
|
@@ -22,7 +22,7 @@ export function provideSomeContext<R, E, A, R2>(
|
|
|
22
22
|
): Fx<Exclude<R, R2>, E, A> {
|
|
23
23
|
return Fx(
|
|
24
24
|
<R3>(sink: Sink<R3, E, A>): Effect.Effect<Exclude<R, R2> | R3, never, void> =>
|
|
25
|
-
Effect.
|
|
25
|
+
Effect.mapInputContext(fx.run(sink), (ctx) =>
|
|
26
26
|
Context.merge(ctx as Context.Context<R | R3>, context),
|
|
27
27
|
),
|
|
28
28
|
)
|
|
@@ -57,11 +57,13 @@ export function provideServiceEffect<R, E, A, I, S, R2, E2>(
|
|
|
57
57
|
): Fx<Exclude<R, I> | R2, E | E2, A> {
|
|
58
58
|
return Fx(
|
|
59
59
|
<R3>(sink: Sink<R3, E | E2, A>): Effect.Effect<Exclude<R, I> | R2 | R3, never, void> =>
|
|
60
|
-
Effect.matchCauseEffect(service,
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
60
|
+
Effect.matchCauseEffect(service, {
|
|
61
|
+
onFailure: sink.error,
|
|
62
|
+
onSuccess: (s) =>
|
|
63
|
+
Effect.mapInputContext(fx.run(sink), (ctx) =>
|
|
64
|
+
Context.merge(ctx as Context.Context<R | R2 | R3>, Context.make(tag, s)),
|
|
65
|
+
),
|
|
66
|
+
}),
|
|
65
67
|
)
|
|
66
68
|
}
|
|
67
69
|
|