@typed/fx 2.0.0-beta.0 → 2.0.0-beta.10
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/LICENSE +21 -0
- package/README.md +58 -21
- package/dist/Fx/Fx.d.ts +371 -19
- package/dist/Fx/Fx.d.ts.map +1 -1
- package/dist/Fx/Fx.js +37 -6
- package/dist/Fx/TypeId.d.ts +52 -6
- package/dist/Fx/TypeId.d.ts.map +1 -1
- package/dist/Fx/TypeId.js +41 -4
- package/dist/Fx/combinators/additive.d.ts +245 -0
- package/dist/Fx/combinators/additive.d.ts.map +1 -0
- package/dist/Fx/combinators/additive.js +243 -0
- package/dist/Fx/combinators/catch.d.ts +246 -12
- package/dist/Fx/combinators/catch.d.ts.map +1 -1
- package/dist/Fx/combinators/catch.js +236 -12
- package/dist/Fx/combinators/causes.d.ts +25 -2
- package/dist/Fx/combinators/causes.d.ts.map +1 -1
- package/dist/Fx/combinators/causes.js +25 -2
- package/dist/Fx/combinators/changesWithEffect.d.ts +40 -0
- package/dist/Fx/combinators/changesWithEffect.d.ts.map +1 -0
- package/dist/Fx/combinators/changesWithEffect.js +48 -0
- package/dist/Fx/combinators/compact.d.ts +18 -1
- package/dist/Fx/combinators/compact.d.ts.map +1 -1
- package/dist/Fx/combinators/compact.js +18 -1
- package/dist/Fx/combinators/concatMap.d.ts +86 -0
- package/dist/Fx/combinators/concatMap.d.ts.map +1 -0
- package/dist/Fx/combinators/concatMap.js +86 -0
- package/dist/Fx/combinators/continueWith.d.ts +113 -5
- package/dist/Fx/combinators/continueWith.d.ts.map +1 -1
- package/dist/Fx/combinators/continueWith.js +113 -5
- package/dist/Fx/combinators/debounce.d.ts +34 -0
- package/dist/Fx/combinators/debounce.d.ts.map +1 -0
- package/dist/Fx/combinators/debounce.js +35 -0
- package/dist/Fx/combinators/delay.d.ts +36 -0
- package/dist/Fx/combinators/delay.d.ts.map +1 -0
- package/dist/Fx/combinators/delay.js +33 -0
- package/dist/Fx/combinators/dropUntil.d.ts +71 -0
- package/dist/Fx/combinators/dropUntil.d.ts.map +1 -0
- package/dist/Fx/combinators/dropUntil.js +65 -0
- package/dist/Fx/combinators/during.d.ts +38 -0
- package/dist/Fx/combinators/during.d.ts.map +1 -0
- package/dist/Fx/combinators/during.js +85 -0
- package/dist/Fx/combinators/ensuring.d.ts +34 -4
- package/dist/Fx/combinators/ensuring.d.ts.map +1 -1
- package/dist/Fx/combinators/ensuring.js +34 -4
- package/dist/Fx/combinators/exhaustLatestMap.d.ts +41 -5
- package/dist/Fx/combinators/exhaustLatestMap.d.ts.map +1 -1
- package/dist/Fx/combinators/exhaustLatestMap.js +41 -5
- package/dist/Fx/combinators/exhaustLatestMapEffect.d.ts +40 -4
- package/dist/Fx/combinators/exhaustLatestMapEffect.d.ts.map +1 -1
- package/dist/Fx/combinators/exhaustLatestMapEffect.js +40 -4
- package/dist/Fx/combinators/exhaustMap.d.ts +38 -1
- package/dist/Fx/combinators/exhaustMap.d.ts.map +1 -1
- package/dist/Fx/combinators/exhaustMap.js +38 -1
- package/dist/Fx/combinators/exhaustMapEffect.d.ts +33 -1
- package/dist/Fx/combinators/exhaustMapEffect.d.ts.map +1 -1
- package/dist/Fx/combinators/exhaustMapEffect.js +33 -1
- package/dist/Fx/combinators/exit.d.ts +23 -2
- package/dist/Fx/combinators/exit.d.ts.map +1 -1
- package/dist/Fx/combinators/exit.js +23 -2
- package/dist/Fx/combinators/filter.d.ts +17 -1
- package/dist/Fx/combinators/filter.d.ts.map +1 -1
- package/dist/Fx/combinators/filter.js +17 -1
- package/dist/Fx/combinators/filterEffect.d.ts +22 -1
- package/dist/Fx/combinators/filterEffect.d.ts.map +1 -1
- package/dist/Fx/combinators/filterEffect.js +22 -1
- package/dist/Fx/combinators/filterMap.d.ts +20 -1
- package/dist/Fx/combinators/filterMap.d.ts.map +1 -1
- package/dist/Fx/combinators/filterMap.js +20 -1
- package/dist/Fx/combinators/filterMapEffect.d.ts +21 -1
- package/dist/Fx/combinators/filterMapEffect.d.ts.map +1 -1
- package/dist/Fx/combinators/filterMapEffect.js +21 -1
- package/dist/Fx/combinators/filterMapLoop.d.ts +20 -1
- package/dist/Fx/combinators/filterMapLoop.d.ts.map +1 -1
- package/dist/Fx/combinators/filterMapLoop.js +20 -1
- package/dist/Fx/combinators/filterMapLoopCause.d.ts +21 -1
- package/dist/Fx/combinators/filterMapLoopCause.d.ts.map +1 -1
- package/dist/Fx/combinators/filterMapLoopCause.js +21 -1
- package/dist/Fx/combinators/filterMapLoopCauseEffect.d.ts +21 -1
- package/dist/Fx/combinators/filterMapLoopCauseEffect.d.ts.map +1 -1
- package/dist/Fx/combinators/filterMapLoopCauseEffect.js +21 -1
- package/dist/Fx/combinators/filterMapLoopEffect.d.ts +21 -1
- package/dist/Fx/combinators/filterMapLoopEffect.d.ts.map +1 -1
- package/dist/Fx/combinators/filterMapLoopEffect.js +21 -1
- package/dist/Fx/combinators/flatMap.d.ts +50 -5
- package/dist/Fx/combinators/flatMap.d.ts.map +1 -1
- package/dist/Fx/combinators/flatMap.js +36 -3
- package/dist/Fx/combinators/flatMapConcurrently.d.ts +51 -4
- package/dist/Fx/combinators/flatMapConcurrently.d.ts.map +1 -1
- package/dist/Fx/combinators/flatMapConcurrently.js +51 -4
- package/dist/Fx/combinators/flatMapConcurrentlyEffect.d.ts +48 -4
- package/dist/Fx/combinators/flatMapConcurrentlyEffect.d.ts.map +1 -1
- package/dist/Fx/combinators/flatMapConcurrentlyEffect.js +40 -2
- package/dist/Fx/combinators/flatMapEffect.d.ts +46 -4
- package/dist/Fx/combinators/flatMapEffect.d.ts.map +1 -1
- package/dist/Fx/combinators/flatMapEffect.js +32 -2
- package/dist/Fx/combinators/flip.d.ts +34 -2
- package/dist/Fx/combinators/flip.d.ts.map +1 -1
- package/dist/Fx/combinators/flip.js +34 -2
- package/dist/Fx/combinators/gen.d.ts +29 -10
- package/dist/Fx/combinators/gen.d.ts.map +1 -1
- package/dist/Fx/combinators/gen.js +28 -4
- package/dist/Fx/combinators/genScoped.d.ts +33 -10
- package/dist/Fx/combinators/genScoped.d.ts.map +1 -1
- package/dist/Fx/combinators/genScoped.js +31 -3
- package/dist/Fx/combinators/grouped.d.ts +89 -0
- package/dist/Fx/combinators/grouped.d.ts.map +1 -0
- package/dist/Fx/combinators/grouped.js +146 -0
- package/dist/Fx/combinators/index.d.ts +45 -0
- package/dist/Fx/combinators/index.d.ts.map +1 -1
- package/dist/Fx/combinators/index.js +45 -0
- package/dist/Fx/combinators/keyed.d.ts +124 -10
- package/dist/Fx/combinators/keyed.d.ts.map +1 -1
- package/dist/Fx/combinators/keyed.js +69 -11
- package/dist/Fx/combinators/loop.d.ts +17 -1
- package/dist/Fx/combinators/loop.d.ts.map +1 -1
- package/dist/Fx/combinators/loop.js +17 -1
- package/dist/Fx/combinators/loopCause.d.ts +18 -1
- package/dist/Fx/combinators/loopCause.d.ts.map +1 -1
- package/dist/Fx/combinators/loopCause.js +18 -1
- package/dist/Fx/combinators/loopCauseEffect.d.ts +19 -1
- package/dist/Fx/combinators/loopCauseEffect.d.ts.map +1 -1
- package/dist/Fx/combinators/loopCauseEffect.js +19 -1
- package/dist/Fx/combinators/loopEffect.d.ts +24 -1
- package/dist/Fx/combinators/loopEffect.d.ts.map +1 -1
- package/dist/Fx/combinators/loopEffect.js +24 -1
- package/dist/Fx/combinators/map.d.ts +46 -1
- package/dist/Fx/combinators/map.d.ts.map +1 -1
- package/dist/Fx/combinators/map.js +43 -1
- package/dist/Fx/combinators/mapBoth.d.ts +40 -0
- package/dist/Fx/combinators/mapBoth.d.ts.map +1 -0
- package/dist/Fx/combinators/mapBoth.js +33 -0
- package/dist/Fx/combinators/mapEffect.d.ts +25 -1
- package/dist/Fx/combinators/mapEffect.d.ts.map +1 -1
- package/dist/Fx/combinators/mapEffect.js +25 -1
- package/dist/Fx/combinators/mapError.d.ts +33 -0
- package/dist/Fx/combinators/mapError.d.ts.map +1 -0
- package/dist/Fx/combinators/mapError.js +32 -0
- package/dist/Fx/combinators/mergeAll.d.ts +35 -1
- package/dist/Fx/combinators/mergeAll.d.ts.map +1 -1
- package/dist/Fx/combinators/mergeAll.js +35 -1
- package/dist/Fx/combinators/mergeOrdered.d.ts +36 -4
- package/dist/Fx/combinators/mergeOrdered.d.ts.map +1 -1
- package/dist/Fx/combinators/mergeOrdered.js +68 -14
- package/dist/Fx/combinators/onError.d.ts +34 -4
- package/dist/Fx/combinators/onError.d.ts.map +1 -1
- package/dist/Fx/combinators/onError.js +34 -4
- package/dist/Fx/combinators/onExit.d.ts +29 -3
- package/dist/Fx/combinators/onExit.d.ts.map +1 -1
- package/dist/Fx/combinators/onExit.js +29 -3
- package/dist/Fx/combinators/onInterrupt.d.ts +49 -4
- package/dist/Fx/combinators/onInterrupt.d.ts.map +1 -1
- package/dist/Fx/combinators/onInterrupt.js +49 -4
- package/dist/Fx/combinators/pairwise.d.ts +28 -0
- package/dist/Fx/combinators/pairwise.d.ts.map +1 -0
- package/dist/Fx/combinators/pairwise.js +31 -0
- package/dist/Fx/combinators/provide.d.ts +162 -8
- package/dist/Fx/combinators/provide.d.ts.map +1 -1
- package/dist/Fx/combinators/provide.js +154 -6
- package/dist/Fx/combinators/race.d.ts +92 -0
- package/dist/Fx/combinators/race.d.ts.map +1 -0
- package/dist/Fx/combinators/race.js +149 -0
- package/dist/Fx/combinators/repeat.d.ts +41 -0
- package/dist/Fx/combinators/repeat.d.ts.map +1 -0
- package/dist/Fx/combinators/repeat.js +57 -0
- package/dist/Fx/combinators/result.d.ts +45 -0
- package/dist/Fx/combinators/result.d.ts.map +1 -0
- package/dist/Fx/combinators/result.js +46 -0
- package/dist/Fx/combinators/retry.d.ts +53 -0
- package/dist/Fx/combinators/retry.d.ts.map +1 -0
- package/dist/Fx/combinators/retry.js +71 -0
- package/dist/Fx/combinators/sample.d.ts +31 -0
- package/dist/Fx/combinators/sample.d.ts.map +1 -0
- package/dist/Fx/combinators/sample.js +42 -0
- package/dist/Fx/combinators/scan.d.ts +72 -0
- package/dist/Fx/combinators/scan.d.ts.map +1 -0
- package/dist/Fx/combinators/scan.js +77 -0
- package/dist/Fx/combinators/since.d.ts +30 -0
- package/dist/Fx/combinators/since.d.ts.map +1 -0
- package/dist/Fx/combinators/since.js +39 -0
- package/dist/Fx/combinators/skip.d.ts +45 -1
- package/dist/Fx/combinators/skip.d.ts.map +1 -1
- package/dist/Fx/combinators/skip.js +43 -1
- package/dist/Fx/combinators/skipRepeats.d.ts +17 -1
- package/dist/Fx/combinators/skipRepeats.d.ts.map +1 -1
- package/dist/Fx/combinators/skipRepeats.js +17 -1
- package/dist/Fx/combinators/skipRepeatsWith.d.ts +18 -1
- package/dist/Fx/combinators/skipRepeatsWith.d.ts.map +1 -1
- package/dist/Fx/combinators/skipRepeatsWith.js +18 -1
- package/dist/Fx/combinators/skipWhile.d.ts +117 -0
- package/dist/Fx/combinators/skipWhile.d.ts.map +1 -0
- package/dist/Fx/combinators/skipWhile.js +134 -0
- package/dist/Fx/combinators/slice.d.ts +97 -2
- package/dist/Fx/combinators/slice.d.ts.map +1 -1
- package/dist/Fx/combinators/slice.js +45 -1
- package/dist/Fx/combinators/switchMap.d.ts +39 -1
- package/dist/Fx/combinators/switchMap.d.ts.map +1 -1
- package/dist/Fx/combinators/switchMap.js +43 -5
- package/dist/Fx/combinators/switchMapEffect.d.ts +38 -1
- package/dist/Fx/combinators/switchMapEffect.d.ts.map +1 -1
- package/dist/Fx/combinators/switchMapEffect.js +38 -1
- package/dist/Fx/combinators/take.d.ts +46 -1
- package/dist/Fx/combinators/take.d.ts.map +1 -1
- package/dist/Fx/combinators/take.js +44 -1
- package/dist/Fx/combinators/takeUntil.d.ts +62 -2
- package/dist/Fx/combinators/takeUntil.d.ts.map +1 -1
- package/dist/Fx/combinators/takeUntil.js +62 -2
- package/dist/Fx/combinators/takeWhile.d.ts +60 -0
- package/dist/Fx/combinators/takeWhile.d.ts.map +1 -0
- package/dist/Fx/combinators/takeWhile.js +54 -0
- package/dist/Fx/combinators/tapEffect.d.ts +17 -1
- package/dist/Fx/combinators/tapEffect.d.ts.map +1 -1
- package/dist/Fx/combinators/tapEffect.js +17 -1
- package/dist/Fx/combinators/throttle.d.ts +79 -0
- package/dist/Fx/combinators/throttle.d.ts.map +1 -0
- package/dist/Fx/combinators/throttle.js +99 -0
- package/dist/Fx/combinators/timeout.d.ts +76 -0
- package/dist/Fx/combinators/timeout.d.ts.map +1 -0
- package/dist/Fx/combinators/timeout.js +110 -0
- package/dist/Fx/combinators/tuple.d.ts +32 -2
- package/dist/Fx/combinators/tuple.d.ts.map +1 -1
- package/dist/Fx/combinators/tuple.js +36 -5
- package/dist/Fx/combinators/until.d.ts +27 -0
- package/dist/Fx/combinators/until.d.ts.map +1 -0
- package/dist/Fx/combinators/until.js +56 -0
- package/dist/Fx/combinators/unwrap.d.ts +31 -2
- package/dist/Fx/combinators/unwrap.d.ts.map +1 -1
- package/dist/Fx/combinators/unwrap.js +30 -1
- package/dist/Fx/combinators/unwrapScoped.d.ts +34 -1
- package/dist/Fx/combinators/unwrapScoped.d.ts.map +1 -1
- package/dist/Fx/combinators/unwrapScoped.js +34 -1
- package/dist/Fx/combinators/when.d.ts +37 -2
- package/dist/Fx/combinators/when.d.ts.map +1 -1
- package/dist/Fx/combinators/when.js +38 -3
- package/dist/Fx/combinators/withLatestFrom.d.ts +58 -0
- package/dist/Fx/combinators/withLatestFrom.d.ts.map +1 -0
- package/dist/Fx/combinators/withLatestFrom.js +68 -0
- package/dist/Fx/combinators/withSpan.d.ts +35 -1
- package/dist/Fx/combinators/withSpan.d.ts.map +1 -1
- package/dist/Fx/combinators/withSpan.js +34 -3
- package/dist/Fx/combinators/zip.d.ts +135 -0
- package/dist/Fx/combinators/zip.d.ts.map +1 -0
- package/dist/Fx/combinators/zip.js +160 -0
- package/dist/Fx/constructors/at.d.ts +23 -3
- package/dist/Fx/constructors/at.d.ts.map +1 -1
- package/dist/Fx/constructors/at.js +21 -1
- package/dist/Fx/constructors/die.d.ts +22 -1
- package/dist/Fx/constructors/die.d.ts.map +1 -1
- package/dist/Fx/constructors/die.js +22 -1
- package/dist/Fx/constructors/empty.d.ts +19 -1
- package/dist/Fx/constructors/empty.d.ts.map +1 -1
- package/dist/Fx/constructors/empty.js +19 -1
- package/dist/Fx/constructors/fail.d.ts +22 -1
- package/dist/Fx/constructors/fail.d.ts.map +1 -1
- package/dist/Fx/constructors/fail.js +22 -1
- package/dist/Fx/constructors/failCause.d.ts +23 -1
- package/dist/Fx/constructors/failCause.d.ts.map +1 -1
- package/dist/Fx/constructors/failCause.js +23 -1
- package/dist/Fx/constructors/fn.d.ts +116 -16
- package/dist/Fx/constructors/fn.d.ts.map +1 -1
- package/dist/Fx/constructors/fn.js +36 -0
- package/dist/Fx/constructors/fromEffect.d.ts +45 -3
- package/dist/Fx/constructors/fromEffect.d.ts.map +1 -1
- package/dist/Fx/constructors/fromEffect.js +45 -3
- package/dist/Fx/constructors/fromFailures.d.ts +25 -1
- package/dist/Fx/constructors/fromFailures.d.ts.map +1 -1
- package/dist/Fx/constructors/fromFailures.js +25 -1
- package/dist/Fx/constructors/fromIterable.d.ts +23 -1
- package/dist/Fx/constructors/fromIterable.d.ts.map +1 -1
- package/dist/Fx/constructors/fromIterable.js +23 -1
- package/dist/Fx/constructors/fromSchedule.d.ts +26 -1
- package/dist/Fx/constructors/fromSchedule.d.ts.map +1 -1
- package/dist/Fx/constructors/fromSchedule.js +28 -3
- package/dist/Fx/constructors/index.d.ts +2 -1
- package/dist/Fx/constructors/index.d.ts.map +1 -1
- package/dist/Fx/constructors/index.js +2 -1
- package/dist/Fx/constructors/interrupt.d.ts +22 -2
- package/dist/Fx/constructors/interrupt.d.ts.map +1 -1
- package/dist/Fx/constructors/interrupt.js +22 -2
- package/dist/Fx/constructors/make.d.ts +151 -4
- package/dist/Fx/constructors/make.d.ts.map +1 -1
- package/dist/Fx/constructors/make.js +60 -7
- package/dist/Fx/constructors/periodic.d.ts +31 -2
- package/dist/Fx/constructors/periodic.d.ts.map +1 -1
- package/dist/Fx/constructors/periodic.js +30 -1
- package/dist/Fx/constructors/succeed.d.ts +79 -7
- package/dist/Fx/constructors/succeed.d.ts.map +1 -1
- package/dist/Fx/constructors/succeed.js +79 -7
- package/dist/Fx/constructors/suspend.d.ts +28 -0
- package/dist/Fx/constructors/suspend.d.ts.map +1 -1
- package/dist/Fx/constructors/suspend.js +28 -0
- package/dist/Fx/constructors/sync.d.ts +32 -0
- package/dist/Fx/constructors/sync.d.ts.map +1 -0
- package/dist/Fx/constructors/sync.js +32 -0
- package/dist/Fx/internal/DeferredRef.d.ts +259 -7
- package/dist/Fx/internal/DeferredRef.d.ts.map +1 -1
- package/dist/Fx/internal/DeferredRef.js +260 -9
- package/dist/Fx/internal/UnionToTuple.d.ts +22 -0
- package/dist/Fx/internal/UnionToTuple.d.ts.map +1 -1
- package/dist/Fx/internal/diff.d.ts +586 -0
- package/dist/Fx/internal/diff.d.ts.map +1 -1
- package/dist/Fx/internal/diff.js +120 -9
- package/dist/Fx/internal/effectableEvaluateKey.d.ts +30 -0
- package/dist/Fx/internal/effectableEvaluateKey.d.ts.map +1 -0
- package/dist/Fx/internal/effectableEvaluateKey.js +29 -0
- package/dist/Fx/internal/effectableWithOverride.d.ts +55 -0
- package/dist/Fx/internal/effectableWithOverride.d.ts.map +1 -0
- package/dist/Fx/internal/effectableWithOverride.js +46 -0
- package/dist/Fx/internal/equivalence.d.ts +29 -0
- package/dist/Fx/internal/equivalence.d.ts.map +1 -1
- package/dist/Fx/internal/equivalence.js +29 -0
- package/dist/Fx/internal/multicast.d.ts +145 -2
- package/dist/Fx/internal/multicast.d.ts.map +1 -1
- package/dist/Fx/internal/multicast.js +146 -4
- package/dist/Fx/internal/ring-buffer.d.ts +149 -0
- package/dist/Fx/internal/ring-buffer.d.ts.map +1 -1
- package/dist/Fx/internal/ring-buffer.js +155 -0
- package/dist/Fx/internal/scope.d.ts +184 -0
- package/dist/Fx/internal/scope.d.ts.map +1 -1
- package/dist/Fx/internal/scope.js +150 -0
- package/dist/Fx/internal/yieldable.d.ts +117 -2
- package/dist/Fx/internal/yieldable.d.ts.map +1 -1
- package/dist/Fx/internal/yieldable.js +86 -3
- package/dist/Fx/run/collect.d.ts +93 -4
- package/dist/Fx/run/collect.d.ts.map +1 -1
- package/dist/Fx/run/collect.js +94 -5
- package/dist/Fx/run/first.d.ts +23 -1
- package/dist/Fx/run/first.d.ts.map +1 -1
- package/dist/Fx/run/first.js +23 -1
- package/dist/Fx/run/fork.d.ts +52 -2
- package/dist/Fx/run/fork.d.ts.map +1 -1
- package/dist/Fx/run/fork.js +52 -2
- package/dist/Fx/run/observe.d.ts +112 -4
- package/dist/Fx/run/observe.d.ts.map +1 -1
- package/dist/Fx/run/observe.js +137 -16
- package/dist/Fx/run/runPromise.d.ts +45 -2
- package/dist/Fx/run/runPromise.d.ts.map +1 -1
- package/dist/Fx/run/runPromise.js +45 -2
- package/dist/Fx/stream.d.ts +92 -0
- package/dist/Fx/stream.d.ts.map +1 -1
- package/dist/Fx/stream.js +60 -1
- package/dist/Push/Push.d.ts +1286 -98
- package/dist/Push/Push.d.ts.map +1 -1
- package/dist/Push/Push.js +1074 -88
- package/dist/RefArray.d.ts +2 -0
- package/dist/RefArray.d.ts.map +1 -0
- package/dist/RefArray.js +1 -0
- package/dist/RefBigDecimal.d.ts +2 -0
- package/dist/RefBigDecimal.d.ts.map +1 -0
- package/dist/RefBigDecimal.js +1 -0
- package/dist/RefBigInt.d.ts +2 -0
- package/dist/RefBigInt.d.ts.map +1 -0
- package/dist/RefBigInt.js +1 -0
- package/dist/RefBoolean.d.ts +2 -0
- package/dist/RefBoolean.d.ts.map +1 -0
- package/dist/RefBoolean.js +1 -0
- package/dist/RefCause.d.ts +2 -0
- package/dist/RefCause.d.ts.map +1 -0
- package/dist/RefCause.js +1 -0
- package/dist/RefChunk.d.ts +2 -0
- package/dist/RefChunk.d.ts.map +1 -0
- package/dist/RefChunk.js +1 -0
- package/dist/RefDateTime.d.ts +2 -0
- package/dist/RefDateTime.d.ts.map +1 -0
- package/dist/RefDateTime.js +1 -0
- package/dist/RefDuration.d.ts +2 -0
- package/dist/RefDuration.d.ts.map +1 -0
- package/dist/RefDuration.js +1 -0
- package/dist/RefGraph.d.ts +2 -0
- package/dist/RefGraph.d.ts.map +1 -0
- package/dist/RefGraph.js +1 -0
- package/dist/RefHashMap.d.ts +2 -0
- package/dist/RefHashMap.d.ts.map +1 -0
- package/dist/RefHashMap.js +1 -0
- package/dist/RefHashRing.d.ts +2 -0
- package/dist/RefHashRing.d.ts.map +1 -0
- package/dist/RefHashRing.js +1 -0
- package/dist/RefHashSet.d.ts +2 -0
- package/dist/RefHashSet.d.ts.map +1 -0
- package/dist/RefHashSet.js +1 -0
- package/dist/RefIterable.d.ts +2 -0
- package/dist/RefIterable.d.ts.map +1 -0
- package/dist/RefIterable.js +1 -0
- package/dist/RefOption.d.ts +2 -0
- package/dist/RefOption.d.ts.map +1 -0
- package/dist/RefOption.js +1 -0
- package/dist/RefRecord.d.ts +2 -0
- package/dist/RefRecord.d.ts.map +1 -0
- package/dist/RefRecord.js +1 -0
- package/dist/RefResult.d.ts +2 -0
- package/dist/RefResult.d.ts.map +1 -0
- package/dist/RefResult.js +1 -0
- package/dist/RefString.d.ts +2 -0
- package/dist/RefString.d.ts.map +1 -0
- package/dist/RefString.js +1 -0
- package/dist/RefStruct.d.ts +2 -0
- package/dist/RefStruct.d.ts.map +1 -0
- package/dist/RefStruct.js +1 -0
- package/dist/RefSubject/Hydration.d.ts +504 -0
- package/dist/RefSubject/Hydration.d.ts.map +1 -0
- package/dist/RefSubject/Hydration.js +300 -0
- package/dist/RefSubject/RefArray.d.ts +382 -35
- package/dist/RefSubject/RefArray.d.ts.map +1 -1
- package/dist/RefSubject/RefArray.js +374 -40
- package/dist/RefSubject/RefBigDecimal.d.ts +241 -21
- package/dist/RefSubject/RefBigDecimal.d.ts.map +1 -1
- package/dist/RefSubject/RefBigDecimal.js +229 -20
- package/dist/RefSubject/RefBigInt.d.ts +181 -16
- package/dist/RefSubject/RefBigInt.d.ts.map +1 -1
- package/dist/RefSubject/RefBigInt.js +169 -15
- package/dist/RefSubject/RefBoolean.d.ts +181 -16
- package/dist/RefSubject/RefBoolean.d.ts.map +1 -1
- package/dist/RefSubject/RefBoolean.js +169 -15
- package/dist/RefSubject/RefCause.d.ts +133 -12
- package/dist/RefSubject/RefCause.d.ts.map +1 -1
- package/dist/RefSubject/RefCause.js +121 -11
- package/dist/RefSubject/RefChunk.d.ts +481 -76
- package/dist/RefSubject/RefChunk.d.ts.map +1 -1
- package/dist/RefSubject/RefChunk.js +471 -75
- package/dist/RefSubject/RefDateTime.d.ts +137 -16
- package/dist/RefSubject/RefDateTime.d.ts.map +1 -1
- package/dist/RefSubject/RefDateTime.js +122 -12
- package/dist/RefSubject/RefDuration.d.ts +169 -15
- package/dist/RefSubject/RefDuration.d.ts.map +1 -1
- package/dist/RefSubject/RefDuration.js +157 -14
- package/dist/RefSubject/RefGraph.d.ts +349 -35
- package/dist/RefSubject/RefGraph.d.ts.map +1 -1
- package/dist/RefSubject/RefGraph.js +334 -32
- package/dist/RefSubject/RefHashMap.d.ts +323 -28
- package/dist/RefSubject/RefHashMap.d.ts.map +1 -1
- package/dist/RefSubject/RefHashMap.js +317 -29
- package/dist/RefSubject/RefHashRing.d.ts +159 -15
- package/dist/RefSubject/RefHashRing.d.ts.map +1 -1
- package/dist/RefSubject/RefHashRing.js +145 -12
- package/dist/RefSubject/RefHashSet.d.ts +251 -22
- package/dist/RefSubject/RefHashSet.d.ts.map +1 -1
- package/dist/RefSubject/RefHashSet.js +238 -20
- package/dist/RefSubject/RefIterable.d.ts +358 -32
- package/dist/RefSubject/RefIterable.d.ts.map +1 -1
- package/dist/RefSubject/RefIterable.js +350 -30
- package/dist/RefSubject/RefOption.d.ts +157 -14
- package/dist/RefSubject/RefOption.d.ts.map +1 -1
- package/dist/RefSubject/RefOption.js +145 -13
- package/dist/RefSubject/RefRecord.d.ts +402 -64
- package/dist/RefSubject/RefRecord.d.ts.map +1 -1
- package/dist/RefSubject/RefRecord.js +364 -39
- package/dist/RefSubject/RefResult.d.ts +167 -35
- package/dist/RefSubject/RefResult.d.ts.map +1 -1
- package/dist/RefSubject/RefResult.js +133 -12
- package/dist/RefSubject/RefString.d.ts +205 -18
- package/dist/RefSubject/RefString.d.ts.map +1 -1
- package/dist/RefSubject/RefString.js +193 -17
- package/dist/RefSubject/RefStruct.d.ts +169 -14
- package/dist/RefSubject/RefStruct.d.ts.map +1 -1
- package/dist/RefSubject/RefStruct.js +157 -13
- package/dist/RefSubject/RefSubject.d.ts +1242 -43
- package/dist/RefSubject/RefSubject.d.ts.map +1 -1
- package/dist/RefSubject/RefSubject.js +1012 -86
- package/dist/RefSubject/RefTrie.d.ts +323 -37
- package/dist/RefSubject/RefTrie.d.ts.map +1 -1
- package/dist/RefSubject/RefTrie.js +311 -31
- package/dist/RefSubject/RefTuple.d.ts +127 -11
- package/dist/RefSubject/RefTuple.d.ts.map +1 -1
- package/dist/RefSubject/RefTuple.js +114 -9
- package/dist/RefSubject/index.d.ts +1 -0
- package/dist/RefSubject/index.d.ts.map +1 -1
- package/dist/RefSubject/index.js +1 -0
- package/dist/RefSubject.d.ts +2 -1
- package/dist/RefSubject.d.ts.map +1 -1
- package/dist/RefSubject.js +2 -1
- package/dist/RefTrie.d.ts +2 -0
- package/dist/RefTrie.d.ts.map +1 -0
- package/dist/RefTrie.js +1 -0
- package/dist/RefTuple.d.ts +2 -0
- package/dist/RefTuple.d.ts.map +1 -0
- package/dist/RefTuple.js +1 -0
- package/dist/Sink/Sink.d.ts +396 -23
- package/dist/Sink/Sink.d.ts.map +1 -1
- package/dist/Sink/Sink.js +55 -7
- package/dist/Sink/combinators.d.ts +789 -3
- package/dist/Sink/combinators.d.ts.map +1 -1
- package/dist/Sink/combinators.js +812 -7
- package/dist/Subject/Subject.d.ts +1022 -27
- package/dist/Subject/Subject.d.ts.map +1 -1
- package/dist/Subject/Subject.js +909 -43
- package/dist/Versioned/Versioned.d.ts +475 -25
- package/dist/Versioned/Versioned.d.ts.map +1 -1
- package/dist/Versioned/Versioned.js +298 -46
- package/dist/index.d.ts +22 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +22 -3
- package/package.json +125 -11
- package/dist/Fx/constructors/fromYieldable.d.ts +0 -12
- package/dist/Fx/constructors/fromYieldable.d.ts.map +0 -1
- package/dist/Fx/constructors/fromYieldable.js +0 -12
- package/src/Fx/Fx.ts +0 -164
- package/src/Fx/TypeId.ts +0 -25
- package/src/Fx/combinators/catch.ts +0 -165
- package/src/Fx/combinators/causes.ts +0 -23
- package/src/Fx/combinators/compact.ts +0 -15
- package/src/Fx/combinators/continueWith.ts +0 -78
- package/src/Fx/combinators/ensuring.ts +0 -23
- package/src/Fx/combinators/exhaustLatestMap.ts +0 -74
- package/src/Fx/combinators/exhaustLatestMapEffect.ts +0 -25
- package/src/Fx/combinators/exhaustMap.ts +0 -36
- package/src/Fx/combinators/exhaustMapEffect.ts +0 -23
- package/src/Fx/combinators/exit.ts +0 -15
- package/src/Fx/combinators/filter.ts +0 -22
- package/src/Fx/combinators/filterEffect.ts +0 -31
- package/src/Fx/combinators/filterMap.ts +0 -23
- package/src/Fx/combinators/filterMapEffect.ts +0 -32
- package/src/Fx/combinators/filterMapLoop.ts +0 -35
- package/src/Fx/combinators/filterMapLoopCause.ts +0 -36
- package/src/Fx/combinators/filterMapLoopCauseEffect.ts +0 -46
- package/src/Fx/combinators/filterMapLoopEffect.ts +0 -36
- package/src/Fx/combinators/flatMap.ts +0 -51
- package/src/Fx/combinators/flatMapConcurrently.ts +0 -36
- package/src/Fx/combinators/flatMapConcurrentlyEffect.ts +0 -26
- package/src/Fx/combinators/flatMapEffect.ts +0 -42
- package/src/Fx/combinators/flip.ts +0 -14
- package/src/Fx/combinators/gen.ts +0 -24
- package/src/Fx/combinators/genScoped.ts +0 -24
- package/src/Fx/combinators/index.ts +0 -51
- package/src/Fx/combinators/keyed.ts +0 -369
- package/src/Fx/combinators/loop.ts +0 -27
- package/src/Fx/combinators/loopCause.ts +0 -34
- package/src/Fx/combinators/loopCauseEffect.ts +0 -36
- package/src/Fx/combinators/loopEffect.ts +0 -34
- package/src/Fx/combinators/map.ts +0 -22
- package/src/Fx/combinators/mapEffect.ts +0 -32
- package/src/Fx/combinators/mergeAll.ts +0 -22
- package/src/Fx/combinators/mergeOrdered.ts +0 -123
- package/src/Fx/combinators/onError.ts +0 -40
- package/src/Fx/combinators/onExit.ts +0 -82
- package/src/Fx/combinators/onInterrupt.ts +0 -87
- package/src/Fx/combinators/provide.ts +0 -62
- package/src/Fx/combinators/skip.ts +0 -20
- package/src/Fx/combinators/skipRepeats.ts +0 -15
- package/src/Fx/combinators/skipRepeatsWith.ts +0 -40
- package/src/Fx/combinators/slice.ts +0 -32
- package/src/Fx/combinators/switchMap.ts +0 -55
- package/src/Fx/combinators/switchMapEffect.ts +0 -25
- package/src/Fx/combinators/take.ts +0 -17
- package/src/Fx/combinators/takeUntil.ts +0 -50
- package/src/Fx/combinators/tapEffect.ts +0 -39
- package/src/Fx/combinators/tuple.ts +0 -79
- package/src/Fx/combinators/unwrap.ts +0 -21
- package/src/Fx/combinators/unwrapScoped.ts +0 -26
- package/src/Fx/combinators/when.ts +0 -64
- package/src/Fx/combinators/withSpan.ts +0 -24
- package/src/Fx/constructors/at.ts +0 -23
- package/src/Fx/constructors/die.ts +0 -17
- package/src/Fx/constructors/empty.ts +0 -10
- package/src/Fx/constructors/fail.ts +0 -14
- package/src/Fx/constructors/failCause.ts +0 -14
- package/src/Fx/constructors/fn.ts +0 -245
- package/src/Fx/constructors/fromEffect.ts +0 -24
- package/src/Fx/constructors/fromFailures.ts +0 -19
- package/src/Fx/constructors/fromIterable.ts +0 -15
- package/src/Fx/constructors/fromSchedule.ts +0 -18
- package/src/Fx/constructors/fromYieldable.ts +0 -17
- package/src/Fx/constructors/index.ts +0 -15
- package/src/Fx/constructors/interrupt.ts +0 -13
- package/src/Fx/constructors/make.ts +0 -103
- package/src/Fx/constructors/periodic.ts +0 -15
- package/src/Fx/constructors/succeed.ts +0 -37
- package/src/Fx/constructors/suspend.ts +0 -6
- package/src/Fx/index.ts +0 -6
- package/src/Fx/internal/DeferredRef.ts +0 -87
- package/src/Fx/internal/UnionToTuple.ts +0 -12
- package/src/Fx/internal/diff.ts +0 -191
- package/src/Fx/internal/equivalence.ts +0 -12
- package/src/Fx/internal/multicast.ts +0 -51
- package/src/Fx/internal/ring-buffer.ts +0 -60
- package/src/Fx/internal/scope.ts +0 -58
- package/src/Fx/internal/yieldable.ts +0 -31
- package/src/Fx/run/collect.ts +0 -79
- package/src/Fx/run/first.ts +0 -20
- package/src/Fx/run/fork.ts +0 -40
- package/src/Fx/run/index.ts +0 -5
- package/src/Fx/run/observe.ts +0 -114
- package/src/Fx/run/runPromise.ts +0 -32
- package/src/Fx/stream.ts +0 -42
- package/src/Fx.catch.test.ts +0 -61
- package/src/Fx.fn.test.ts +0 -51
- package/src/Fx.lifecycle.test.ts +0 -80
- package/src/Fx.test.ts +0 -71
- package/src/Fx.ts +0 -1
- package/src/Push/Push.ts +0 -903
- package/src/Push/index.ts +0 -1
- package/src/Push.test.ts +0 -26
- package/src/Push.ts +0 -1
- package/src/RefSubject/RefArray.ts +0 -512
- package/src/RefSubject/RefBigDecimal.test.ts +0 -56
- package/src/RefSubject/RefBigDecimal.ts +0 -295
- package/src/RefSubject/RefBigInt.test.ts +0 -56
- package/src/RefSubject/RefBigInt.ts +0 -189
- package/src/RefSubject/RefBoolean.test.ts +0 -57
- package/src/RefSubject/RefBoolean.ts +0 -185
- package/src/RefSubject/RefCause.test.ts +0 -53
- package/src/RefSubject/RefCause.ts +0 -146
- package/src/RefSubject/RefChunk.ts +0 -510
- package/src/RefSubject/RefDateTime.test.ts +0 -43
- package/src/RefSubject/RefDateTime.ts +0 -264
- package/src/RefSubject/RefDuration.test.ts +0 -49
- package/src/RefSubject/RefDuration.ts +0 -188
- package/src/RefSubject/RefGraph.ts +0 -650
- package/src/RefSubject/RefHashMap.ts +0 -465
- package/src/RefSubject/RefHashRing.ts +0 -262
- package/src/RefSubject/RefHashSet.ts +0 -308
- package/src/RefSubject/RefIterable.ts +0 -445
- package/src/RefSubject/RefOption.test.ts +0 -67
- package/src/RefSubject/RefOption.ts +0 -193
- package/src/RefSubject/RefRecord.ts +0 -612
- package/src/RefSubject/RefResult.test.ts +0 -63
- package/src/RefSubject/RefResult.ts +0 -209
- package/src/RefSubject/RefString.test.ts +0 -61
- package/src/RefSubject/RefString.ts +0 -256
- package/src/RefSubject/RefStruct.test.ts +0 -60
- package/src/RefSubject/RefStruct.ts +0 -253
- package/src/RefSubject/RefSubject.ts +0 -2545
- package/src/RefSubject/RefTrie.ts +0 -356
- package/src/RefSubject/RefTuple.test.ts +0 -60
- package/src/RefSubject/RefTuple.ts +0 -231
- package/src/RefSubject/index.ts +0 -21
- package/src/RefSubject.test.ts +0 -65
- package/src/RefSubject.ts +0 -1
- package/src/Sink/Sink.ts +0 -159
- package/src/Sink/combinators.ts +0 -993
- package/src/Sink/index.ts +0 -2
- package/src/Sink.ts +0 -1
- package/src/Subject/Subject.ts +0 -441
- package/src/Subject/index.ts +0 -1
- package/src/Subject.test.ts +0 -47
- package/src/Subject.ts +0 -1
- package/src/Versioned/Versioned.ts +0 -521
- package/src/Versioned/index.ts +0 -1
- package/src/Versioned.test.ts +0 -23
- package/src/Versioned.ts +0 -1
- package/src/index.ts +0 -7
- package/tsconfig.json +0 -6
package/dist/Sink/combinators.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import * as Cause from "effect/Cause";
|
|
2
2
|
import * as Effect from "effect/Effect";
|
|
3
|
+
import * as Semaphore from "effect/Semaphore";
|
|
3
4
|
import * as Exit from "effect/Exit";
|
|
5
|
+
import * as Fiber from "effect/Fiber";
|
|
4
6
|
import { dual, flow, identity } from "effect/Function";
|
|
5
7
|
import * as MutableRef from "effect/MutableRef";
|
|
6
8
|
import * as Option from "effect/Option";
|
|
@@ -33,6 +35,15 @@ class MapSink {
|
|
|
33
35
|
/**
|
|
34
36
|
* Transforms values before they reach the sink using a pure function.
|
|
35
37
|
*
|
|
38
|
+
* @remarks
|
|
39
|
+
* ## Why
|
|
40
|
+
* Contramapping adapts a consumer to a new input without changing the producer or allocating an
|
|
41
|
+
* intermediate Fx.
|
|
42
|
+
*
|
|
43
|
+
* ## Ownership and lifetime
|
|
44
|
+
* Mapping is synchronous, preserves one-for-one input order, and acquires no resources. Thrown
|
|
45
|
+
* exceptions are defects. The wrapped sink still owns its callback effects and service needs.
|
|
46
|
+
*
|
|
36
47
|
* @example
|
|
37
48
|
* ```ts
|
|
38
49
|
* import { Effect } from "effect"
|
|
@@ -55,11 +66,76 @@ class MapSink {
|
|
|
55
66
|
* ```
|
|
56
67
|
*
|
|
57
68
|
* @since 1.0.0
|
|
58
|
-
* @category
|
|
69
|
+
* @category Transforming inputs
|
|
59
70
|
*/
|
|
60
71
|
export function map(sink, f) {
|
|
61
72
|
return MapSink.make(sink, f);
|
|
62
73
|
}
|
|
74
|
+
/**
|
|
75
|
+
* Alias for `map`, named for the input-side direction of the transformation.
|
|
76
|
+
*
|
|
77
|
+
* @remarks
|
|
78
|
+
* ## Why
|
|
79
|
+
* `mapInput` makes contravariant Sink pipelines easier to read beside output-mapping APIs.
|
|
80
|
+
*
|
|
81
|
+
* ## Ownership and lifetime
|
|
82
|
+
* It is exactly `map`: synchronous, one-for-one, ordered, and resource-free.
|
|
83
|
+
*
|
|
84
|
+
* @example
|
|
85
|
+
* ```ts
|
|
86
|
+
* import { Effect } from "effect"
|
|
87
|
+
* import * as Sink from "@typed/fx/Sink"
|
|
88
|
+
* const numbers = Sink.make(Effect.logError, (value: number) => Effect.log(value))
|
|
89
|
+
* const strings = Sink.mapInput(numbers, Number)
|
|
90
|
+
* ```
|
|
91
|
+
*
|
|
92
|
+
* @since 1.0.0
|
|
93
|
+
* @category Transforming inputs
|
|
94
|
+
*/
|
|
95
|
+
export const mapInput = map;
|
|
96
|
+
/**
|
|
97
|
+
* Maps the error channel of a sink using the provided function.
|
|
98
|
+
* Failures are mapped via `Cause.map`; defects and interrupts are preserved.
|
|
99
|
+
*
|
|
100
|
+
* @remarks
|
|
101
|
+
* ## Why
|
|
102
|
+
* A producer's typed error can be translated into the vocabulary expected by an existing consumer
|
|
103
|
+
* without losing Cause structure.
|
|
104
|
+
*
|
|
105
|
+
* ## Ownership and lifetime
|
|
106
|
+
* Mapping is synchronous and resource-free. Success order is unchanged; only `Fail` reasons are
|
|
107
|
+
* mapped, while defects and interruption reasons pass through untouched.
|
|
108
|
+
*
|
|
109
|
+
* @example
|
|
110
|
+
* ```ts
|
|
111
|
+
* import { Effect } from "effect"
|
|
112
|
+
* import * as Sink from "@typed/fx/Sink"
|
|
113
|
+
* const target: Sink.Sink<number, string> = Sink.make(Effect.logError, Effect.log)
|
|
114
|
+
* const acceptsNumbers = Sink.mapError(target, (error: number) => `code:${error}`)
|
|
115
|
+
* ```
|
|
116
|
+
*
|
|
117
|
+
* @since 1.0.0
|
|
118
|
+
* @category Failure handling
|
|
119
|
+
*/
|
|
120
|
+
export function mapError(sink, f) {
|
|
121
|
+
return new MapErrorSink(sink, f);
|
|
122
|
+
}
|
|
123
|
+
class MapErrorSink {
|
|
124
|
+
sink;
|
|
125
|
+
f;
|
|
126
|
+
constructor(sink, f) {
|
|
127
|
+
this.sink = sink;
|
|
128
|
+
this.f = f;
|
|
129
|
+
this.onSuccess = this.onSuccess.bind(this);
|
|
130
|
+
this.onFailure = this.onFailure.bind(this);
|
|
131
|
+
}
|
|
132
|
+
onSuccess(value) {
|
|
133
|
+
return this.sink.onSuccess(value);
|
|
134
|
+
}
|
|
135
|
+
onFailure(cause) {
|
|
136
|
+
return this.sink.onFailure(Cause.map(cause, this.f));
|
|
137
|
+
}
|
|
138
|
+
}
|
|
63
139
|
class FilterMapSink {
|
|
64
140
|
sink;
|
|
65
141
|
f;
|
|
@@ -92,6 +168,14 @@ class FilterMapSink {
|
|
|
92
168
|
/**
|
|
93
169
|
* Filters and transforms values before they reach the sink using a function that returns an `Option`.
|
|
94
170
|
*
|
|
171
|
+
* @remarks
|
|
172
|
+
* ## Why
|
|
173
|
+
* Selection and transformation happen at the consumer boundary without constructing another Fx.
|
|
174
|
+
*
|
|
175
|
+
* ## Ownership and lifetime
|
|
176
|
+
* Inputs are inspected synchronously in arrival order. `Some` invokes the wrapped sink once;
|
|
177
|
+
* `None` invokes it zero times. The adapter acquires no resources and failures pass through.
|
|
178
|
+
*
|
|
95
179
|
* @example
|
|
96
180
|
* ```ts
|
|
97
181
|
* import { Effect, Option } from "effect"
|
|
@@ -115,17 +199,47 @@ class FilterMapSink {
|
|
|
115
199
|
* ```
|
|
116
200
|
*
|
|
117
201
|
* @since 1.0.0
|
|
118
|
-
* @category
|
|
202
|
+
* @category Selecting inputs
|
|
119
203
|
*/
|
|
120
204
|
export function filterMap(sink, f) {
|
|
121
205
|
return FilterMapSink.make(sink, f);
|
|
122
206
|
}
|
|
207
|
+
/**
|
|
208
|
+
* Forwards `Some` values and discards `None` values.
|
|
209
|
+
*
|
|
210
|
+
* @remarks
|
|
211
|
+
* ## Why
|
|
212
|
+
* `compact` consumes optional producer output with the same zero-or-one cardinality as `filterMap`.
|
|
213
|
+
*
|
|
214
|
+
* ## Ownership and lifetime
|
|
215
|
+
* Option inspection is synchronous and resource-free. Present values retain arrival order; failure
|
|
216
|
+
* causes pass through unchanged.
|
|
217
|
+
*
|
|
218
|
+
* @example
|
|
219
|
+
* ```ts
|
|
220
|
+
* import { Effect, Option } from "effect"
|
|
221
|
+
* import * as Sink from "@typed/fx/Sink"
|
|
222
|
+
* const sink = Sink.compact(Sink.make(Effect.logError, (n: number) => Effect.log(n)))
|
|
223
|
+
* sink.onSuccess(Option.some(1))
|
|
224
|
+
* ```
|
|
225
|
+
*
|
|
226
|
+
* @since 1.0.0
|
|
227
|
+
* @category Selecting inputs
|
|
228
|
+
*/
|
|
123
229
|
export function compact(sink) {
|
|
124
230
|
return filterMap(sink, identity);
|
|
125
231
|
}
|
|
126
232
|
/**
|
|
127
233
|
* Filters values before they reach the sink using a predicate function.
|
|
128
234
|
*
|
|
235
|
+
* @remarks
|
|
236
|
+
* ## Why
|
|
237
|
+
* Predicate filtering narrows consumer traffic without changing the producer.
|
|
238
|
+
*
|
|
239
|
+
* ## Ownership and lifetime
|
|
240
|
+
* The predicate runs synchronously in arrival order. Matching values invoke the wrapped sink once;
|
|
241
|
+
* non-matches invoke it zero times. The adapter acquires no resources.
|
|
242
|
+
*
|
|
129
243
|
* @example
|
|
130
244
|
* ```ts
|
|
131
245
|
* import { Effect } from "effect"
|
|
@@ -147,17 +261,53 @@ export function compact(sink) {
|
|
|
147
261
|
* ```
|
|
148
262
|
*
|
|
149
263
|
* @since 1.0.0
|
|
150
|
-
* @category
|
|
264
|
+
* @category Selecting inputs
|
|
151
265
|
*/
|
|
152
266
|
export function filter(sink, f) {
|
|
153
267
|
return filterMap(sink, Option.liftPredicate(f));
|
|
154
268
|
}
|
|
269
|
+
/**
|
|
270
|
+
* Runs a producer-style callback with a sink that can complete the surrounding Effect early.
|
|
271
|
+
*
|
|
272
|
+
* @remarks
|
|
273
|
+
* ## Why
|
|
274
|
+
* Consumer combinators can stop upstream work after a bound or predicate without representing
|
|
275
|
+
* normal completion as failure.
|
|
276
|
+
*
|
|
277
|
+
* ## Ownership and lifetime
|
|
278
|
+
* The returned Effect owns the callback fiber. Completion, `earlyExit`, or interruption aborts that
|
|
279
|
+
* fiber through the supplied signal; deliveries after exit are ignored. The callback's services are
|
|
280
|
+
* combined with the wrapped sink's services.
|
|
281
|
+
*
|
|
282
|
+
* @example
|
|
283
|
+
* ```ts
|
|
284
|
+
* import { Effect } from "effect"
|
|
285
|
+
* import * as Sink from "@typed/fx/Sink"
|
|
286
|
+
* const base = Sink.make(Effect.logError, Effect.log)
|
|
287
|
+
* const program = Sink.withEarlyExit(base, (sink) => sink.onSuccess("done").pipe(Effect.andThen(sink.earlyExit)))
|
|
288
|
+
* ```
|
|
289
|
+
*
|
|
290
|
+
* @since 1.0.0
|
|
291
|
+
* @category Stopping delivery
|
|
292
|
+
*/
|
|
155
293
|
export function withEarlyExit(sink, f) {
|
|
156
|
-
return Effect.
|
|
294
|
+
return Effect.contextWith((services) => Effect.callback(function (resume, signal) {
|
|
157
295
|
let exited = false;
|
|
296
|
+
let exitRequested = false;
|
|
297
|
+
let resumed = false;
|
|
298
|
+
let producerFiber;
|
|
299
|
+
const finish = () => {
|
|
300
|
+
if (resumed || producerFiber === undefined)
|
|
301
|
+
return;
|
|
302
|
+
resumed = true;
|
|
303
|
+
resume(Fiber.interrupt(producerFiber));
|
|
304
|
+
};
|
|
158
305
|
const earlyExit = Effect.sync(() => {
|
|
306
|
+
if (exited)
|
|
307
|
+
return;
|
|
159
308
|
exited = true;
|
|
160
|
-
|
|
309
|
+
exitRequested = true;
|
|
310
|
+
finish();
|
|
161
311
|
});
|
|
162
312
|
const onSuccess = (a) => {
|
|
163
313
|
if (exited)
|
|
@@ -174,16 +324,67 @@ export function withEarlyExit(sink, f) {
|
|
|
174
324
|
onFailure,
|
|
175
325
|
earlyExit,
|
|
176
326
|
};
|
|
177
|
-
f(sinkWithEarlyExit, { signal, scheduler: this }).pipe(Effect.flatMap(() => earlyExit), (_) => Effect.runForkWith(services)(_, { scheduler: this, signal }));
|
|
327
|
+
producerFiber = f(sinkWithEarlyExit, { signal, scheduler: this }).pipe(Effect.flatMap(() => earlyExit), (_) => Effect.runForkWith(services)(_, { scheduler: this, signal }));
|
|
328
|
+
if (exitRequested)
|
|
329
|
+
finish();
|
|
178
330
|
}));
|
|
179
331
|
}
|
|
332
|
+
/**
|
|
333
|
+
* Runs a callback with an early-exit sink and a private Effect `Ref` initialized to `state`.
|
|
334
|
+
*
|
|
335
|
+
* @remarks
|
|
336
|
+
* ## Why
|
|
337
|
+
* It supports stateful consumer protocols while keeping their state local to one run.
|
|
338
|
+
*
|
|
339
|
+
* ## Ownership and lifetime
|
|
340
|
+
* Each execution creates one Ref and owns it until exit or interruption. Ref operations are lazy
|
|
341
|
+
* atomic Effects: serialized callback execution preserves producer order, while concurrent execution
|
|
342
|
+
* is ordered by scheduling. No state is shared across `withState` executions.
|
|
343
|
+
*
|
|
344
|
+
* @example
|
|
345
|
+
* ```ts
|
|
346
|
+
* import { Effect, Ref } from "effect"
|
|
347
|
+
* import * as Sink from "@typed/fx/Sink"
|
|
348
|
+
* const base = Sink.make(Effect.logError, Effect.log)
|
|
349
|
+
* const program = Sink.withState(base, 0, ({ state, earlyExit }) => Ref.set(state, 1).pipe(Effect.andThen(earlyExit)))
|
|
350
|
+
* ```
|
|
351
|
+
*
|
|
352
|
+
* @since 1.0.0
|
|
353
|
+
* @category Stateful delivery
|
|
354
|
+
*/
|
|
180
355
|
export function withState(sink, state, f) {
|
|
181
356
|
return withEarlyExit(sink, (sink, params) => f({ ...sink, state: Ref.makeUnsafe(state) }, params));
|
|
182
357
|
}
|
|
358
|
+
/**
|
|
359
|
+
* Runs a callback with private state whose effectful reads and writes are serialized.
|
|
360
|
+
*
|
|
361
|
+
* @remarks
|
|
362
|
+
* ## Why
|
|
363
|
+
* Overlapping asynchronous callbacks need a lock to prevent multiple updates from reading the same
|
|
364
|
+
* prior state.
|
|
365
|
+
*
|
|
366
|
+
* ## Ownership and lifetime
|
|
367
|
+
* Each execution owns one mutable cell and one single-permit semaphore. Modify Effects serialize in
|
|
368
|
+
* semaphore-acquisition order, release the permit on completion or interruption, and expose their
|
|
369
|
+
* typed errors and services. Constructing an Effect does not acquire the permit; running it does.
|
|
370
|
+
* Exit aborts the surrounding callback fiber.
|
|
371
|
+
*
|
|
372
|
+
* @example
|
|
373
|
+
* ```ts
|
|
374
|
+
* import { Effect } from "effect"
|
|
375
|
+
* import * as Sink from "@typed/fx/Sink"
|
|
376
|
+
* const base = Sink.make(Effect.logError, Effect.log)
|
|
377
|
+
* const program = Sink.withStateSemaphore(base, 0, (state) =>
|
|
378
|
+
* state.updateEffect((n) => Effect.succeed(n + 1)).pipe(Effect.andThen(state.earlyExit)))
|
|
379
|
+
* ```
|
|
380
|
+
*
|
|
381
|
+
* @since 1.0.0
|
|
382
|
+
* @category Stateful delivery
|
|
383
|
+
*/
|
|
183
384
|
export function withStateSemaphore(sink, state, f) {
|
|
184
385
|
return withEarlyExit(sink, (sink, params) => {
|
|
185
386
|
const stateRef = MutableRef.make(state);
|
|
186
|
-
const semaphore =
|
|
387
|
+
const semaphore = Semaphore.makeUnsafe(1);
|
|
187
388
|
const lock = semaphore.withPermits(1);
|
|
188
389
|
const modifyEffect = (f) => Effect.suspend(() => f(MutableRef.get(stateRef))).pipe(Effect.flatMap(([c, b]) => {
|
|
189
390
|
MutableRef.set(stateRef, b);
|
|
@@ -194,6 +395,29 @@ export function withStateSemaphore(sink, state, f) {
|
|
|
194
395
|
return f({ ...sink, modifyEffect, updateEffect, get }, params);
|
|
195
396
|
});
|
|
196
397
|
}
|
|
398
|
+
/**
|
|
399
|
+
* Threads pure state through successful inputs and forwards one derived value per input.
|
|
400
|
+
*
|
|
401
|
+
* @remarks
|
|
402
|
+
* ## Why
|
|
403
|
+
* `loop` implements an ordered consumer-side state machine without exposing mutable state to the
|
|
404
|
+
* producer.
|
|
405
|
+
*
|
|
406
|
+
* ## Ownership and lifetime
|
|
407
|
+
* Each adapted sink owns its seed. Updates are synchronous and follow callback invocation order;
|
|
408
|
+
* every input produces exactly one downstream success. Failures bypass the state machine. Reusing
|
|
409
|
+
* the same sink for another producer run continues from its retained seed; create a new sink to reset.
|
|
410
|
+
*
|
|
411
|
+
* @example
|
|
412
|
+
* ```ts
|
|
413
|
+
* import { Effect } from "effect"
|
|
414
|
+
* import * as Sink from "@typed/fx/Sink"
|
|
415
|
+
* const totals = Sink.loop(Sink.make(Effect.logError, Effect.log), 0, (sum, n: number) => [sum + n, sum + n])
|
|
416
|
+
* ```
|
|
417
|
+
*
|
|
418
|
+
* @since 1.0.0
|
|
419
|
+
* @category Stateful delivery
|
|
420
|
+
*/
|
|
197
421
|
export const loop = dual(3, function loop(sink, seed, f) {
|
|
198
422
|
return new LoopSink(sink, seed, f);
|
|
199
423
|
});
|
|
@@ -217,6 +441,30 @@ class LoopSink {
|
|
|
217
441
|
return this.sink.onSuccess(c);
|
|
218
442
|
}
|
|
219
443
|
}
|
|
444
|
+
/**
|
|
445
|
+
* Threads pure state through failure causes and forwards one transformed cause per failure.
|
|
446
|
+
*
|
|
447
|
+
* @remarks
|
|
448
|
+
* ## Why
|
|
449
|
+
* Stateful error translation can retain retry or protocol context while preserving full Cause
|
|
450
|
+
* information.
|
|
451
|
+
*
|
|
452
|
+
* ## Ownership and lifetime
|
|
453
|
+
* Each adapted sink owns its seed. Failure callbacks update it synchronously in invocation order;
|
|
454
|
+
* successes pass through unchanged. Reusing the sink continues from its retained seed; create a new
|
|
455
|
+
* sink to reset. No resources are acquired.
|
|
456
|
+
*
|
|
457
|
+
* @example
|
|
458
|
+
* ```ts
|
|
459
|
+
* import { Cause, Effect } from "effect"
|
|
460
|
+
* import * as Sink from "@typed/fx/Sink"
|
|
461
|
+
* const target: Sink.Sink<number, string> = Sink.make(Effect.logError, Effect.log)
|
|
462
|
+
* const counted = Sink.loopCause(target, 0, (n, cause: Cause.Cause<string>) => [cause, n + 1])
|
|
463
|
+
* ```
|
|
464
|
+
*
|
|
465
|
+
* @since 1.0.0
|
|
466
|
+
* @category Stateful failure handling
|
|
467
|
+
*/
|
|
220
468
|
export const loopCause = dual(3, function loopCause(sink, seed, f) {
|
|
221
469
|
return new LoopCauseSink(sink, seed, f);
|
|
222
470
|
});
|
|
@@ -240,6 +488,29 @@ class LoopCauseSink {
|
|
|
240
488
|
return this.sink.onSuccess(value);
|
|
241
489
|
}
|
|
242
490
|
}
|
|
491
|
+
/**
|
|
492
|
+
* Threads pure state through successes and optionally forwards a derived value.
|
|
493
|
+
*
|
|
494
|
+
* @remarks
|
|
495
|
+
* ## Why
|
|
496
|
+
* It combines consumer-side state, filtering, and mapping in one ordered transition.
|
|
497
|
+
*
|
|
498
|
+
* ## Ownership and lifetime
|
|
499
|
+
* Each adapted sink owns its seed. Every input updates state synchronously; `Some` emits once and
|
|
500
|
+
* `None` emits nothing. Failures pass through. Reusing the sink continues from its retained seed;
|
|
501
|
+
* create a new sink to reset. The adapter acquires no resources.
|
|
502
|
+
*
|
|
503
|
+
* @example
|
|
504
|
+
* ```ts
|
|
505
|
+
* import { Effect, Option } from "effect"
|
|
506
|
+
* import * as Sink from "@typed/fx/Sink"
|
|
507
|
+
* const target = Sink.make(Effect.logError, Effect.log)
|
|
508
|
+
* const everyOther = Sink.filterMapLoop(target, false, (skip, n: number) => [skip ? Option.none() : Option.some(n), !skip])
|
|
509
|
+
* ```
|
|
510
|
+
*
|
|
511
|
+
* @since 1.0.0
|
|
512
|
+
* @category Stateful delivery
|
|
513
|
+
*/
|
|
243
514
|
export const filterMapLoop = dual(3, function filterMapLoop(sink, seed, f) {
|
|
244
515
|
return new FilterMapLoopSink(sink, seed, f);
|
|
245
516
|
});
|
|
@@ -265,6 +536,29 @@ class FilterMapLoopSink {
|
|
|
265
536
|
return Effect.void;
|
|
266
537
|
}
|
|
267
538
|
}
|
|
539
|
+
/**
|
|
540
|
+
* Threads pure state through failures and optionally forwards a transformed cause.
|
|
541
|
+
*
|
|
542
|
+
* @remarks
|
|
543
|
+
* ## Why
|
|
544
|
+
* Stateful failure suppression and translation can be expressed without discarding Cause structure.
|
|
545
|
+
*
|
|
546
|
+
* ## Ownership and lifetime
|
|
547
|
+
* Each adapted sink owns its seed. Failure callbacks update state synchronously in invocation order;
|
|
548
|
+
* `Some` forwards once and `None` suppresses the failure. Successes pass through unchanged. Reusing
|
|
549
|
+
* the sink continues from its retained seed; create a new sink to reset.
|
|
550
|
+
*
|
|
551
|
+
* @example
|
|
552
|
+
* ```ts
|
|
553
|
+
* import { Cause, Effect, Option } from "effect"
|
|
554
|
+
* import * as Sink from "@typed/fx/Sink"
|
|
555
|
+
* const target: Sink.Sink<number, string> = Sink.make(Effect.logError, Effect.log)
|
|
556
|
+
* const first = Sink.filterMapLoopCause(target, true, (keep, cause: Cause.Cause<string>) => [keep ? Option.some(cause) : Option.none(), false])
|
|
557
|
+
* ```
|
|
558
|
+
*
|
|
559
|
+
* @since 1.0.0
|
|
560
|
+
* @category Stateful failure handling
|
|
561
|
+
*/
|
|
268
562
|
export const filterMapLoopCause = dual(3, function filterMapLoopCause(sink, seed, f) {
|
|
269
563
|
return new FilterMapLoopCauseSink(sink, seed, f);
|
|
270
564
|
});
|
|
@@ -290,6 +584,32 @@ class FilterMapLoopCauseSink {
|
|
|
290
584
|
return this.sink.onSuccess(value);
|
|
291
585
|
}
|
|
292
586
|
}
|
|
587
|
+
/**
|
|
588
|
+
* Threads state through an effectful success transformation and forwards one value on success.
|
|
589
|
+
*
|
|
590
|
+
* @remarks
|
|
591
|
+
* ## Why
|
|
592
|
+
* Stateful consumer transitions can consult Effect services or fail without moving the state
|
|
593
|
+
* machine into the producer.
|
|
594
|
+
*
|
|
595
|
+
* ## Ownership and lifetime
|
|
596
|
+
* Callback invocation constructs a transition Effect from the seed visible at that moment. The
|
|
597
|
+
* adapter does not serialize those Effects: overlapping callbacks can read the same seed, and
|
|
598
|
+
* successful transitions commit in completion order. A failure is sent to the wrapped sink and does
|
|
599
|
+
* not commit. The sink instance retains its last committed seed when reused by another producer run;
|
|
600
|
+
* construct a new adapted sink to reset it. Transition services and interruption remain typed.
|
|
601
|
+
*
|
|
602
|
+
* @example
|
|
603
|
+
* ```ts
|
|
604
|
+
* import { Effect } from "effect"
|
|
605
|
+
* import * as Sink from "@typed/fx/Sink"
|
|
606
|
+
* const target = Sink.make(Effect.logError, Effect.log)
|
|
607
|
+
* const totals = Sink.loopEffect(target, 0, (sum, n: number) => Effect.succeed([sum + n, sum + n] as const))
|
|
608
|
+
* ```
|
|
609
|
+
*
|
|
610
|
+
* @since 1.0.0
|
|
611
|
+
* @category Stateful delivery
|
|
612
|
+
*/
|
|
293
613
|
export const loopEffect = dual(3, function loopEffect(sink, seed, f) {
|
|
294
614
|
return new LoopEffectSink(sink, seed, f);
|
|
295
615
|
});
|
|
@@ -317,6 +637,32 @@ class LoopEffectSink {
|
|
|
317
637
|
});
|
|
318
638
|
}
|
|
319
639
|
}
|
|
640
|
+
/**
|
|
641
|
+
* Threads state through an effectful success transition and optionally forwards its value.
|
|
642
|
+
*
|
|
643
|
+
* @remarks
|
|
644
|
+
* ## Why
|
|
645
|
+
* One transition can perform service-backed work, update state, and decide whether the consumer
|
|
646
|
+
* should observe a value.
|
|
647
|
+
*
|
|
648
|
+
* ## Ownership and lifetime
|
|
649
|
+
* Callback invocation constructs a transition Effect from the seed visible at that moment. The
|
|
650
|
+
* adapter does not serialize those Effects: overlapping callbacks can read the same seed, and
|
|
651
|
+
* successful transitions commit in completion order. `Some` then invokes the wrapped sink once,
|
|
652
|
+
* `None` not at all, and failure invokes its failure callback without committing. The sink instance
|
|
653
|
+
* retains its seed across producer runs; construct a new one to reset it.
|
|
654
|
+
*
|
|
655
|
+
* @example
|
|
656
|
+
* ```ts
|
|
657
|
+
* import { Effect, Option } from "effect"
|
|
658
|
+
* import * as Sink from "@typed/fx/Sink"
|
|
659
|
+
* const target = Sink.make(Effect.logError, Effect.log)
|
|
660
|
+
* const sink = Sink.filterMapLoopEffect(target, 0, (count, n: number) => Effect.succeed([Option.some(n), count + 1] as const))
|
|
661
|
+
* ```
|
|
662
|
+
*
|
|
663
|
+
* @since 1.0.0
|
|
664
|
+
* @category Stateful delivery
|
|
665
|
+
*/
|
|
320
666
|
export const filterMapLoopEffect = dual(3, function filterMapLoopEffect(sink, seed, f) {
|
|
321
667
|
return new FilterMapLoopEffectSink(sink, seed, f);
|
|
322
668
|
});
|
|
@@ -346,6 +692,32 @@ class FilterMapLoopEffectSink {
|
|
|
346
692
|
});
|
|
347
693
|
}
|
|
348
694
|
}
|
|
695
|
+
/**
|
|
696
|
+
* Threads state through an effectful failure transformation.
|
|
697
|
+
*
|
|
698
|
+
* @remarks
|
|
699
|
+
* ## Why
|
|
700
|
+
* Failure handling can consult services and retain state while preserving the original Cause when
|
|
701
|
+
* the handler itself fails.
|
|
702
|
+
*
|
|
703
|
+
* ## Ownership and lifetime
|
|
704
|
+
* Callback invocation constructs a transition Effect from the seed visible at that moment. The
|
|
705
|
+
* adapter does not serialize those Effects: overlapping failures can read the same seed, and
|
|
706
|
+
* successful transitions commit in completion order. A transition failure is combined with the
|
|
707
|
+
* original cause and does not commit. Success values bypass the state machine. The sink instance
|
|
708
|
+
* retains its seed across producer runs; construct a new one to reset it.
|
|
709
|
+
*
|
|
710
|
+
* @example
|
|
711
|
+
* ```ts
|
|
712
|
+
* import { Effect } from "effect"
|
|
713
|
+
* import * as Sink from "@typed/fx/Sink"
|
|
714
|
+
* const target = Sink.make(Effect.logError, Effect.log)
|
|
715
|
+
* const sink = Sink.loopCauseEffect(target, 0, (count, cause) => Effect.succeed([cause, count + 1] as const))
|
|
716
|
+
* ```
|
|
717
|
+
*
|
|
718
|
+
* @since 1.0.0
|
|
719
|
+
* @category Stateful failure handling
|
|
720
|
+
*/
|
|
349
721
|
export const loopCauseEffect = dual(3, function loopCauseEffect(sink, seed, f) {
|
|
350
722
|
return new LoopCauseEffectSink(sink, seed, f);
|
|
351
723
|
});
|
|
@@ -373,6 +745,32 @@ class LoopCauseEffectSink {
|
|
|
373
745
|
return this.sink.onSuccess(value);
|
|
374
746
|
}
|
|
375
747
|
}
|
|
748
|
+
/**
|
|
749
|
+
* Threads state through an effectful failure transition and optionally forwards a cause.
|
|
750
|
+
*
|
|
751
|
+
* @remarks
|
|
752
|
+
* ## Why
|
|
753
|
+
* It supports service-backed, stateful failure suppression or translation at the consumer boundary.
|
|
754
|
+
*
|
|
755
|
+
* ## Ownership and lifetime
|
|
756
|
+
* Callback invocation constructs a transition Effect from the seed visible at that moment. The
|
|
757
|
+
* adapter does not serialize those Effects: overlapping failures can read the same seed, and
|
|
758
|
+
* successful transitions commit in completion order. `Some` forwards one cause, `None` suppresses
|
|
759
|
+
* it, and transition failure is forwarded without committing. Successes pass through. The sink
|
|
760
|
+
* instance retains its seed across producer runs; construct a new one to reset it.
|
|
761
|
+
*
|
|
762
|
+
* @example
|
|
763
|
+
* ```ts
|
|
764
|
+
* import { Cause, Effect, Option } from "effect"
|
|
765
|
+
* import * as Sink from "@typed/fx/Sink"
|
|
766
|
+
* const target: Sink.Sink<number, string> = Sink.make(Effect.logError, Effect.log)
|
|
767
|
+
* const sink = Sink.filterMapLoopCauseEffect(target, false, (seen, cause: Cause.Cause<string>) =>
|
|
768
|
+
* Effect.succeed([seen ? Option.none() : Option.some(cause), true] as const))
|
|
769
|
+
* ```
|
|
770
|
+
*
|
|
771
|
+
* @since 1.0.0
|
|
772
|
+
* @category Stateful failure handling
|
|
773
|
+
*/
|
|
376
774
|
export function filterMapLoopCauseEffect(sink, seed, f) {
|
|
377
775
|
return new FilterMapLoopCauseEffectSink(sink, seed, f);
|
|
378
776
|
}
|
|
@@ -402,6 +800,30 @@ class FilterMapLoopCauseEffectSink {
|
|
|
402
800
|
return this.sink.onSuccess(value);
|
|
403
801
|
}
|
|
404
802
|
}
|
|
803
|
+
/**
|
|
804
|
+
* Runs a producer callback through a bounded view of a sink.
|
|
805
|
+
*
|
|
806
|
+
* @remarks
|
|
807
|
+
* ## Why
|
|
808
|
+
* Consumers can skip an initial prefix and stop after a fixed number of values, allowing the
|
|
809
|
+
* surrounding producer work to finish early.
|
|
810
|
+
*
|
|
811
|
+
* ## Ownership and lifetime
|
|
812
|
+
* Each execution owns fresh counters and an early-exit callback. Successes remain ordered; at most
|
|
813
|
+
* `take` values are delivered after `skip` values. Failures always pass through. Reaching the bound
|
|
814
|
+
* completes and aborts the callback fiber; negative bounds are not normalized.
|
|
815
|
+
*
|
|
816
|
+
* @example
|
|
817
|
+
* ```ts
|
|
818
|
+
* import { Effect } from "effect"
|
|
819
|
+
* import * as Sink from "@typed/fx/Sink"
|
|
820
|
+
* const target = Sink.make(Effect.logError, Effect.log)
|
|
821
|
+
* const program = Sink.slice(target, { skip: 1, take: 2 }, (bounded) => bounded.onSuccess("kept"))
|
|
822
|
+
* ```
|
|
823
|
+
*
|
|
824
|
+
* @since 1.0.0
|
|
825
|
+
* @category Stopping delivery
|
|
826
|
+
*/
|
|
405
827
|
export const slice = dual(3, function slice(sink, bounds, f) {
|
|
406
828
|
return withEarlyExit(sink, (s) => f(new SliceSink(s, bounds)));
|
|
407
829
|
});
|
|
@@ -432,6 +854,30 @@ class SliceSink {
|
|
|
432
854
|
return this.sink.earlyExit;
|
|
433
855
|
}
|
|
434
856
|
}
|
|
857
|
+
/**
|
|
858
|
+
* Runs an Effect for each input and forwards its successful value to the sink.
|
|
859
|
+
*
|
|
860
|
+
* @remarks
|
|
861
|
+
* ## Why
|
|
862
|
+
* Consumer-side adaptation can use services and typed failure without creating an intermediate Fx.
|
|
863
|
+
*
|
|
864
|
+
* ## Ownership and lifetime
|
|
865
|
+
* One transition Effect runs per callback invocation. Its success is forwarded once; its complete
|
|
866
|
+
* failure Cause is sent to `onFailure`. Calls themselves are not serialized by this adapter, so
|
|
867
|
+
* ordering follows the invoking producer. Services join the sink requirements; interruption is local
|
|
868
|
+
* to each callback Effect.
|
|
869
|
+
*
|
|
870
|
+
* @example
|
|
871
|
+
* ```ts
|
|
872
|
+
* import { Effect } from "effect"
|
|
873
|
+
* import * as Sink from "@typed/fx/Sink"
|
|
874
|
+
* const numbers = Sink.mapEffect(Sink.make(Effect.logError, Effect.log), (text: string) =>
|
|
875
|
+
* Effect.succeed(Number(text)))
|
|
876
|
+
* ```
|
|
877
|
+
*
|
|
878
|
+
* @since 1.0.0
|
|
879
|
+
* @category Transforming inputs
|
|
880
|
+
*/
|
|
435
881
|
export const mapEffect = dual(2, function mapEffect(sink, f) {
|
|
436
882
|
return new MapEffectSink(sink, f);
|
|
437
883
|
});
|
|
@@ -451,6 +897,51 @@ class MapEffectSink {
|
|
|
451
897
|
return Effect.matchCauseEffect(this.f(value), this.sink);
|
|
452
898
|
}
|
|
453
899
|
}
|
|
900
|
+
/**
|
|
901
|
+
* Alias for `mapEffect`, named for the input-side direction of the effectful transformation.
|
|
902
|
+
*
|
|
903
|
+
* @remarks
|
|
904
|
+
* ## Why
|
|
905
|
+
* The name highlights that Sink composition is contravariant in successful input.
|
|
906
|
+
*
|
|
907
|
+
* ## Ownership and lifetime
|
|
908
|
+
* It is exactly `mapEffect`: one Effect per input, with the same failures, services, ordering, and
|
|
909
|
+
* interruption behavior.
|
|
910
|
+
*
|
|
911
|
+
* @example
|
|
912
|
+
* ```ts
|
|
913
|
+
* import { Effect } from "effect"
|
|
914
|
+
* import * as Sink from "@typed/fx/Sink"
|
|
915
|
+
* const sink = Sink.mapInputEffect(Sink.make(Effect.logError, Effect.log), (n: number) => Effect.succeed(String(n)))
|
|
916
|
+
* ```
|
|
917
|
+
*
|
|
918
|
+
* @since 1.0.0
|
|
919
|
+
* @category Transforming inputs
|
|
920
|
+
*/
|
|
921
|
+
export const mapInputEffect = mapEffect;
|
|
922
|
+
/**
|
|
923
|
+
* Runs an Effect for each input and forwards its optional successful value.
|
|
924
|
+
*
|
|
925
|
+
* @remarks
|
|
926
|
+
* ## Why
|
|
927
|
+
* Service-backed validation, selection, and transformation can happen in one consumer adapter.
|
|
928
|
+
*
|
|
929
|
+
* ## Ownership and lifetime
|
|
930
|
+
* Each input runs one Effect. `Some` invokes the sink once, `None` zero times, and failure is routed
|
|
931
|
+
* as a Cause. Invocation order and concurrency are controlled by the producer; services and
|
|
932
|
+
* interruption remain explicit in the returned sink.
|
|
933
|
+
*
|
|
934
|
+
* @example
|
|
935
|
+
* ```ts
|
|
936
|
+
* import { Effect, Option } from "effect"
|
|
937
|
+
* import * as Sink from "@typed/fx/Sink"
|
|
938
|
+
* const sink = Sink.filterMapEffect(Sink.make(Effect.logError, Effect.log), (n: number) =>
|
|
939
|
+
* Effect.succeed(n > 0 ? Option.some(n) : Option.none()))
|
|
940
|
+
* ```
|
|
941
|
+
*
|
|
942
|
+
* @since 1.0.0
|
|
943
|
+
* @category Selecting inputs
|
|
944
|
+
*/
|
|
454
945
|
export const filterMapEffect = dual(2, function filterMapEffect(sink, f) {
|
|
455
946
|
return new FilterMapEffectSink(sink, f);
|
|
456
947
|
});
|
|
@@ -478,6 +969,28 @@ class FilterMapEffectSink {
|
|
|
478
969
|
});
|
|
479
970
|
}
|
|
480
971
|
}
|
|
972
|
+
/**
|
|
973
|
+
* Runs an effectful predicate and forwards inputs for which it succeeds with `true`.
|
|
974
|
+
*
|
|
975
|
+
* @remarks
|
|
976
|
+
* ## Why
|
|
977
|
+
* A consumer can filter using service-backed or asynchronous policy without changing the producer.
|
|
978
|
+
*
|
|
979
|
+
* ## Ownership and lifetime
|
|
980
|
+
* Each input runs one predicate Effect. `true` forwards once, `false` not at all, and predicate
|
|
981
|
+
* failure reaches the sink's failure callback. The producer controls callback ordering and
|
|
982
|
+
* concurrency; predicate services and interruption remain typed.
|
|
983
|
+
*
|
|
984
|
+
* @example
|
|
985
|
+
* ```ts
|
|
986
|
+
* import { Effect } from "effect"
|
|
987
|
+
* import * as Sink from "@typed/fx/Sink"
|
|
988
|
+
* const positive = Sink.filterEffect(Sink.make(Effect.logError, Effect.log), (n: number) => Effect.succeed(n > 0))
|
|
989
|
+
* ```
|
|
990
|
+
*
|
|
991
|
+
* @since 1.0.0
|
|
992
|
+
* @category Selecting inputs
|
|
993
|
+
*/
|
|
481
994
|
export const filterEffect = dual(2, function filterEffect(sink, f) {
|
|
482
995
|
return new FilterEffectSink(sink, f);
|
|
483
996
|
});
|
|
@@ -505,6 +1018,29 @@ class FilterEffectSink {
|
|
|
505
1018
|
});
|
|
506
1019
|
}
|
|
507
1020
|
}
|
|
1021
|
+
/**
|
|
1022
|
+
* Runs an effectful observation before forwarding each successful input unchanged.
|
|
1023
|
+
*
|
|
1024
|
+
* @remarks
|
|
1025
|
+
* ## Why
|
|
1026
|
+
* Logging, metrics, and other observations can be attached at the consumer boundary without
|
|
1027
|
+
* changing the value type.
|
|
1028
|
+
*
|
|
1029
|
+
* ## Ownership and lifetime
|
|
1030
|
+
* The tap Effect completes before the value is forwarded. If it fails, its Cause is delivered and
|
|
1031
|
+
* the value is not forwarded. The producer controls call order and concurrency; tap services and
|
|
1032
|
+
* interruption are reflected by the returned sink.
|
|
1033
|
+
*
|
|
1034
|
+
* @example
|
|
1035
|
+
* ```ts
|
|
1036
|
+
* import { Effect } from "effect"
|
|
1037
|
+
* import * as Sink from "@typed/fx/Sink"
|
|
1038
|
+
* const observed = Sink.tapEffect(Sink.make(Effect.logError, Effect.log), (n: number) => Effect.log(`saw ${n}`))
|
|
1039
|
+
* ```
|
|
1040
|
+
*
|
|
1041
|
+
* @since 1.0.0
|
|
1042
|
+
* @category Transforming inputs
|
|
1043
|
+
*/
|
|
508
1044
|
export const tapEffect = dual(2, function tapEffect(sink, f) {
|
|
509
1045
|
return new TapEffectSink(sink, f);
|
|
510
1046
|
});
|
|
@@ -527,11 +1063,37 @@ class TapEffectSink {
|
|
|
527
1063
|
});
|
|
528
1064
|
}
|
|
529
1065
|
}
|
|
1066
|
+
/**
|
|
1067
|
+
* Exchanges a sink's typed success and failure channels.
|
|
1068
|
+
*
|
|
1069
|
+
* @remarks
|
|
1070
|
+
* ## Why
|
|
1071
|
+
* Error-oriented consumers can be reused as value consumers, and vice versa, without changing the
|
|
1072
|
+
* producer-side protocol.
|
|
1073
|
+
*
|
|
1074
|
+
* ## Ownership and lifetime
|
|
1075
|
+
* A successful input becomes `Cause.fail` downstream. For an incoming Cause, the first typed `Fail`
|
|
1076
|
+
* reason becomes a success and every remaining reason is discarded, including later failures,
|
|
1077
|
+
* defects, or interruption reasons. A Cause with no typed failure passes through intact. The adapter
|
|
1078
|
+
* is synchronous, ordered, and resource-free; use `exit` when the whole Cause must remain observable.
|
|
1079
|
+
*
|
|
1080
|
+
* @example
|
|
1081
|
+
* ```ts
|
|
1082
|
+
* import { Effect } from "effect"
|
|
1083
|
+
* import * as Sink from "@typed/fx/Sink"
|
|
1084
|
+
* const errorsAsValues = Sink.flip(Sink.make(Effect.logError, (value: number) => Effect.log(value)))
|
|
1085
|
+
* ```
|
|
1086
|
+
*
|
|
1087
|
+
* @since 1.0.0
|
|
1088
|
+
* @category Failure handling
|
|
1089
|
+
*/
|
|
530
1090
|
export const flip = (sink) => new FlipSink(sink);
|
|
531
1091
|
class FlipSink {
|
|
532
1092
|
sink;
|
|
533
1093
|
constructor(sink) {
|
|
534
1094
|
this.sink = sink;
|
|
1095
|
+
this.onSuccess = this.onSuccess.bind(this);
|
|
1096
|
+
this.onFailure = this.onFailure.bind(this);
|
|
535
1097
|
}
|
|
536
1098
|
onSuccess(value) {
|
|
537
1099
|
return this.sink.onFailure(Cause.fail(value));
|
|
@@ -543,11 +1105,34 @@ class FlipSink {
|
|
|
543
1105
|
return this.sink.onSuccess(fail.error);
|
|
544
1106
|
}
|
|
545
1107
|
}
|
|
1108
|
+
/**
|
|
1109
|
+
* Materializes both sink channels as successful Effect `Exit` values.
|
|
1110
|
+
*
|
|
1111
|
+
* @remarks
|
|
1112
|
+
* ## Why
|
|
1113
|
+
* A single infallible consumer can record or inspect success and the complete failure Cause as data.
|
|
1114
|
+
*
|
|
1115
|
+
* ## Ownership and lifetime
|
|
1116
|
+
* Every input produces exactly one downstream success: `Exit.succeed` for values or
|
|
1117
|
+
* `Exit.failCause` for failures. Order is preserved and the adapter acquires no resources.
|
|
1118
|
+
*
|
|
1119
|
+
* @example
|
|
1120
|
+
* ```ts
|
|
1121
|
+
* import { Effect } from "effect"
|
|
1122
|
+
* import * as Sink from "@typed/fx/Sink"
|
|
1123
|
+
* const exits = Sink.exit(Sink.make(Effect.logError, Effect.log))
|
|
1124
|
+
* ```
|
|
1125
|
+
*
|
|
1126
|
+
* @since 1.0.0
|
|
1127
|
+
* @category Failure handling
|
|
1128
|
+
*/
|
|
546
1129
|
export const exit = (sink) => new ExitSink(sink);
|
|
547
1130
|
class ExitSink {
|
|
548
1131
|
sink;
|
|
549
1132
|
constructor(sink) {
|
|
550
1133
|
this.sink = sink;
|
|
1134
|
+
this.onSuccess = this.onSuccess.bind(this);
|
|
1135
|
+
this.onFailure = this.onFailure.bind(this);
|
|
551
1136
|
}
|
|
552
1137
|
onSuccess(value) {
|
|
553
1138
|
return this.sink.onSuccess(Exit.succeed(value));
|
|
@@ -556,6 +1141,30 @@ class ExitSink {
|
|
|
556
1141
|
return this.sink.onSuccess(Exit.failCause(cause));
|
|
557
1142
|
}
|
|
558
1143
|
}
|
|
1144
|
+
/**
|
|
1145
|
+
* Runs a producer callback until the first matching value has been forwarded.
|
|
1146
|
+
*
|
|
1147
|
+
* @remarks
|
|
1148
|
+
* ## Why
|
|
1149
|
+
* Unlike a filtering operation, `dropAfter` includes the boundary value and then terminates
|
|
1150
|
+
* producer work normally.
|
|
1151
|
+
*
|
|
1152
|
+
* ## Ownership and lifetime
|
|
1153
|
+
* Values are forwarded in order through the first predicate match, then early exit completes and
|
|
1154
|
+
* aborts the callback fiber. Callback failure is caught and sent to the original sink. The predicate
|
|
1155
|
+
* is synchronous; thrown exceptions are defects.
|
|
1156
|
+
*
|
|
1157
|
+
* @example
|
|
1158
|
+
* ```ts
|
|
1159
|
+
* import { Effect } from "effect"
|
|
1160
|
+
* import * as Sink from "@typed/fx/Sink"
|
|
1161
|
+
* const target = Sink.make(Effect.logError, Effect.log)
|
|
1162
|
+
* const program = Sink.dropAfter(target, (n: number) => n >= 10, (limited) => limited.onSuccess(10))
|
|
1163
|
+
* ```
|
|
1164
|
+
*
|
|
1165
|
+
* @since 1.0.0
|
|
1166
|
+
* @category Stopping delivery
|
|
1167
|
+
*/
|
|
559
1168
|
export const dropAfter = dual(3, function dropAfter(sink, predicate, f) {
|
|
560
1169
|
return withEarlyExit(sink, (s) => f(new DropAfterSink(s, predicate)).pipe(Effect.catchCause(sink.onFailure)));
|
|
561
1170
|
});
|
|
@@ -578,9 +1187,205 @@ class DropAfterSink {
|
|
|
578
1187
|
return this.sink.onSuccess(value);
|
|
579
1188
|
}
|
|
580
1189
|
}
|
|
1190
|
+
/**
|
|
1191
|
+
* Suppresses failure causes made entirely of interruption reasons.
|
|
1192
|
+
*
|
|
1193
|
+
* @remarks
|
|
1194
|
+
* ## Why
|
|
1195
|
+
* Some terminal consumers treat expected cancellation as silent completion while still needing
|
|
1196
|
+
* typed failures and defects.
|
|
1197
|
+
*
|
|
1198
|
+
* ## Ownership and lifetime
|
|
1199
|
+
* Successes pass through unchanged. A pure interruption Cause invokes no downstream callback;
|
|
1200
|
+
* mixed or non-interruption causes are preserved. The adapter does not change fiber ownership or
|
|
1201
|
+
* cleanup and acquires no resources.
|
|
1202
|
+
*
|
|
1203
|
+
* @example
|
|
1204
|
+
* ```ts
|
|
1205
|
+
* import { Effect } from "effect"
|
|
1206
|
+
* import * as Sink from "@typed/fx/Sink"
|
|
1207
|
+
* const quietCancellation = Sink.skipInterrupt(Sink.make(Effect.logError, Effect.log))
|
|
1208
|
+
* ```
|
|
1209
|
+
*
|
|
1210
|
+
* @since 1.0.0
|
|
1211
|
+
* @category Failure handling
|
|
1212
|
+
*/
|
|
581
1213
|
export const skipInterrupt = (sink) => {
|
|
582
1214
|
return {
|
|
583
1215
|
onSuccess: (value) => sink.onSuccess(value),
|
|
584
1216
|
onFailure: (cause) => cause.reasons.every(Cause.isInterruptReason) ? Effect.void : sink.onFailure(cause),
|
|
585
1217
|
};
|
|
586
1218
|
};
|
|
1219
|
+
// -----------------------------------------------------------------------------
|
|
1220
|
+
// Reducing / collecting combinators (additive)
|
|
1221
|
+
// -----------------------------------------------------------------------------
|
|
1222
|
+
/**
|
|
1223
|
+
* Reduces values into a single result using a pure function. Pass a `Ref<B>`
|
|
1224
|
+
* (e.g. from `Ref.make(initial)`); after running, read the result with `Ref.get(ref)`.
|
|
1225
|
+
*
|
|
1226
|
+
* @remarks
|
|
1227
|
+
* ## Why
|
|
1228
|
+
* An existing Ref provides an explicit, independently readable result location for consumer-side
|
|
1229
|
+
* aggregation.
|
|
1230
|
+
*
|
|
1231
|
+
* ## Ownership and lifetime
|
|
1232
|
+
* The caller owns the Ref. Each success returns a lazy atomic `Ref.update`; invoking `onSuccess`
|
|
1233
|
+
* does not update immediately. If the producer executes callback Effects serially, values reduce in
|
|
1234
|
+
* that execution order. Concurrent execution is still atomic but may be scheduled in a different
|
|
1235
|
+
* order than callback invocation. Failures are ignored and a thrown reducer exception is a defect.
|
|
1236
|
+
*
|
|
1237
|
+
* @example
|
|
1238
|
+
* ```ts
|
|
1239
|
+
* import { Effect, Ref } from "effect"
|
|
1240
|
+
* import * as Sink from "@typed/fx/Sink"
|
|
1241
|
+
* const program = Effect.gen(function* () {
|
|
1242
|
+
* const total = yield* Ref.make(0)
|
|
1243
|
+
* return Sink.reduce(total, (sum, n: number) => sum + n)
|
|
1244
|
+
* })
|
|
1245
|
+
* ```
|
|
1246
|
+
*
|
|
1247
|
+
* @since 1.0.0
|
|
1248
|
+
* @category Collecting values
|
|
1249
|
+
*/
|
|
1250
|
+
export function reduce(ref, f) {
|
|
1251
|
+
return {
|
|
1252
|
+
onSuccess: (value) => Ref.update(ref, (b) => f(b, value)),
|
|
1253
|
+
onFailure: () => Effect.void,
|
|
1254
|
+
};
|
|
1255
|
+
}
|
|
1256
|
+
/**
|
|
1257
|
+
* Reduces values into a single result using an effectful function. Pass a `Ref<B>`;
|
|
1258
|
+
* after running, read the result with `Ref.get(ref)`. If the reducer effect fails,
|
|
1259
|
+
* the ref is left unchanged (Sink onSuccess is typed as never failing).
|
|
1260
|
+
*
|
|
1261
|
+
* @remarks
|
|
1262
|
+
* ## Why
|
|
1263
|
+
* Aggregation may require Effect services or asynchronous work while the result remains explicitly
|
|
1264
|
+
* available through a caller-owned Ref.
|
|
1265
|
+
*
|
|
1266
|
+
* ## Ownership and lifetime
|
|
1267
|
+
* The caller owns the Ref. Each success returns a lazy read/reduce/write Effect; invocation alone does
|
|
1268
|
+
* no work. The three steps are not one atomic operation. Serialized producers preserve execution
|
|
1269
|
+
* order, while overlapping executions can read the same value and commit in completion order.
|
|
1270
|
+
* Reducer failures, producer failures, and interrupted writes are ignored. Use
|
|
1271
|
+
* `withStateSemaphore` when the whole effectful transition must be serialized.
|
|
1272
|
+
*
|
|
1273
|
+
* @example
|
|
1274
|
+
* ```ts
|
|
1275
|
+
* import { Effect, Ref } from "effect"
|
|
1276
|
+
* import * as Sink from "@typed/fx/Sink"
|
|
1277
|
+
* const program = Effect.gen(function* () {
|
|
1278
|
+
* const total = yield* Ref.make(0)
|
|
1279
|
+
* return Sink.reduceEffect(total, (sum, n: number) => Effect.succeed(sum + n))
|
|
1280
|
+
* })
|
|
1281
|
+
* ```
|
|
1282
|
+
*
|
|
1283
|
+
* @since 1.0.0
|
|
1284
|
+
* @category Collecting values
|
|
1285
|
+
*/
|
|
1286
|
+
export function reduceEffect(ref, f) {
|
|
1287
|
+
return {
|
|
1288
|
+
onSuccess: (value) => Effect.flatMap(Ref.get(ref), (b) => Effect.matchCauseEffect(f(b, value), {
|
|
1289
|
+
onFailure: () => Effect.void,
|
|
1290
|
+
onSuccess: (next) => Ref.set(ref, next),
|
|
1291
|
+
})),
|
|
1292
|
+
onFailure: () => Effect.void,
|
|
1293
|
+
};
|
|
1294
|
+
}
|
|
1295
|
+
/**
|
|
1296
|
+
* Collects all values into an array. Pass a `Ref<ReadonlyArray<A>>` (e.g. `Ref.make([])`);
|
|
1297
|
+
* after running, read the result with `Ref.get(ref)`.
|
|
1298
|
+
*
|
|
1299
|
+
* @remarks
|
|
1300
|
+
* ## Why
|
|
1301
|
+
* Collection remains an explicit consumer concern and the accumulated result can be read without
|
|
1302
|
+
* changing the producer.
|
|
1303
|
+
*
|
|
1304
|
+
* ## Ownership and lifetime
|
|
1305
|
+
* The caller owns the Ref. Each success returns a lazy atomic `Ref.update` that allocates a new array.
|
|
1306
|
+
* Serialized producers collect in callback-Effect execution order. Concurrent updates remain atomic,
|
|
1307
|
+
* but execution scheduling—not invocation order—determines array order. Failures are ignored.
|
|
1308
|
+
*
|
|
1309
|
+
* @example
|
|
1310
|
+
* ```ts
|
|
1311
|
+
* import { Effect, Ref } from "effect"
|
|
1312
|
+
* import * as Sink from "@typed/fx/Sink"
|
|
1313
|
+
* const program = Effect.gen(function* () {
|
|
1314
|
+
* const values = yield* Ref.make<ReadonlyArray<number>>([])
|
|
1315
|
+
* return Sink.collect(values)
|
|
1316
|
+
* })
|
|
1317
|
+
* ```
|
|
1318
|
+
*
|
|
1319
|
+
* @since 1.0.0
|
|
1320
|
+
* @category Collecting values
|
|
1321
|
+
*/
|
|
1322
|
+
export function collect(ref) {
|
|
1323
|
+
return {
|
|
1324
|
+
onSuccess: (value) => Ref.update(ref, (arr) => [...arr, value]),
|
|
1325
|
+
onFailure: () => Effect.void,
|
|
1326
|
+
};
|
|
1327
|
+
}
|
|
1328
|
+
/**
|
|
1329
|
+
* Keeps only the first value. Pass a `Ref<Option.Option<A>>` (e.g. `Ref.make(Option.none())`);
|
|
1330
|
+
* after running, read the result with `Ref.get(ref)`.
|
|
1331
|
+
*
|
|
1332
|
+
* @remarks
|
|
1333
|
+
* ## Why
|
|
1334
|
+
* The first observed value can be retained in a caller-owned location without stopping the producer.
|
|
1335
|
+
*
|
|
1336
|
+
* ## Ownership and lifetime
|
|
1337
|
+
* The caller owns the Ref. Each success returns a lazy atomic update. The first update Effect to
|
|
1338
|
+
* execute while the Ref is `None` stores its value; that is the first callback only when the producer
|
|
1339
|
+
* executes callback Effects serially. Later updates leave `Some` unchanged. Failures are ignored.
|
|
1340
|
+
*
|
|
1341
|
+
* @example
|
|
1342
|
+
* ```ts
|
|
1343
|
+
* import { Effect, Option, Ref } from "effect"
|
|
1344
|
+
* import * as Sink from "@typed/fx/Sink"
|
|
1345
|
+
* const program = Effect.gen(function* () {
|
|
1346
|
+
* const first = yield* Ref.make<Option.Option<number>>(Option.none())
|
|
1347
|
+
* return Sink.head(first)
|
|
1348
|
+
* })
|
|
1349
|
+
* ```
|
|
1350
|
+
*
|
|
1351
|
+
* @since 1.0.0
|
|
1352
|
+
* @category Collecting values
|
|
1353
|
+
*/
|
|
1354
|
+
export function head(ref) {
|
|
1355
|
+
return {
|
|
1356
|
+
onSuccess: (value) => Ref.update(ref, (opt) => (Option.isNone(opt) ? Option.some(value) : opt)),
|
|
1357
|
+
onFailure: () => Effect.void,
|
|
1358
|
+
};
|
|
1359
|
+
}
|
|
1360
|
+
/**
|
|
1361
|
+
* Keeps only the last value. Pass a `Ref<Option.Option<A>>` (e.g. `Ref.make(Option.none())`);
|
|
1362
|
+
* after running, read the result with `Ref.get(ref)`.
|
|
1363
|
+
*
|
|
1364
|
+
* @remarks
|
|
1365
|
+
* ## Why
|
|
1366
|
+
* The latest observed value can be retained independently of producer completion.
|
|
1367
|
+
*
|
|
1368
|
+
* ## Ownership and lifetime
|
|
1369
|
+
* The caller owns the Ref. Each success returns a lazy atomic `Ref.set`. With serialized callback
|
|
1370
|
+
* Effects the last callback wins; with concurrent execution the last set to execute wins, which may
|
|
1371
|
+
* differ from invocation order. Failures are ignored and the sink acquires no resources.
|
|
1372
|
+
*
|
|
1373
|
+
* @example
|
|
1374
|
+
* ```ts
|
|
1375
|
+
* import { Effect, Option, Ref } from "effect"
|
|
1376
|
+
* import * as Sink from "@typed/fx/Sink"
|
|
1377
|
+
* const program = Effect.gen(function* () {
|
|
1378
|
+
* const latest = yield* Ref.make<Option.Option<number>>(Option.none())
|
|
1379
|
+
* return Sink.last(latest)
|
|
1380
|
+
* })
|
|
1381
|
+
* ```
|
|
1382
|
+
*
|
|
1383
|
+
* @since 1.0.0
|
|
1384
|
+
* @category Collecting values
|
|
1385
|
+
*/
|
|
1386
|
+
export function last(ref) {
|
|
1387
|
+
return {
|
|
1388
|
+
onSuccess: (value) => Ref.set(ref, Option.some(value)),
|
|
1389
|
+
onFailure: () => Effect.void,
|
|
1390
|
+
};
|
|
1391
|
+
}
|