@typed/fx 1.32.0 → 2.0.0-beta.1
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/README.md +367 -2
- package/dist/Fx/Fx.d.ts +96 -0
- package/dist/Fx/Fx.d.ts.map +1 -0
- package/dist/Fx/Fx.js +35 -0
- package/dist/Fx/TypeId.d.ts +20 -0
- package/dist/Fx/TypeId.d.ts.map +1 -0
- package/dist/Fx/TypeId.js +15 -0
- package/dist/Fx/combinators/additive.d.ts +94 -0
- package/dist/Fx/combinators/additive.d.ts.map +1 -0
- package/dist/Fx/combinators/additive.js +92 -0
- package/dist/Fx/combinators/catch.d.ts +114 -0
- package/dist/Fx/combinators/catch.d.ts.map +1 -0
- package/dist/Fx/combinators/catch.js +123 -0
- package/dist/Fx/combinators/causes.d.ts +12 -0
- package/dist/Fx/combinators/causes.d.ts.map +1 -0
- package/dist/Fx/combinators/causes.js +16 -0
- package/dist/Fx/combinators/changesWithEffect.d.ts +20 -0
- package/dist/Fx/combinators/changesWithEffect.d.ts.map +1 -0
- package/dist/Fx/combinators/changesWithEffect.js +28 -0
- package/dist/Fx/combinators/compact.d.ts +12 -0
- package/dist/Fx/combinators/compact.d.ts.map +1 -0
- package/dist/Fx/combinators/compact.js +11 -0
- package/dist/Fx/combinators/continueWith.d.ts +51 -0
- package/dist/Fx/combinators/continueWith.d.ts.map +1 -0
- package/dist/Fx/combinators/continueWith.js +41 -0
- package/dist/Fx/combinators/dropUntil.d.ts +29 -0
- package/dist/Fx/combinators/dropUntil.d.ts.map +1 -0
- package/dist/Fx/combinators/dropUntil.js +23 -0
- package/dist/Fx/combinators/ensuring.d.ts +16 -0
- package/dist/Fx/combinators/ensuring.d.ts.map +1 -0
- package/dist/Fx/combinators/ensuring.js +13 -0
- package/dist/Fx/combinators/exhaustLatestMap.d.ts +15 -0
- package/dist/Fx/combinators/exhaustLatestMap.d.ts.map +1 -0
- package/dist/Fx/combinators/exhaustLatestMap.js +48 -0
- package/dist/Fx/combinators/exhaustLatestMapEffect.d.ts +13 -0
- package/dist/Fx/combinators/exhaustLatestMapEffect.d.ts.map +1 -0
- package/dist/Fx/combinators/exhaustLatestMapEffect.js +14 -0
- package/dist/Fx/combinators/exhaustMap.d.ts +11 -0
- package/dist/Fx/combinators/exhaustMap.d.ts.map +1 -0
- package/dist/Fx/combinators/exhaustMap.js +19 -0
- package/dist/Fx/combinators/exhaustMapEffect.d.ts +11 -0
- package/dist/Fx/combinators/exhaustMapEffect.d.ts.map +1 -0
- package/dist/Fx/combinators/exhaustMapEffect.js +12 -0
- package/dist/Fx/combinators/exit.d.ts +12 -0
- package/dist/Fx/combinators/exit.d.ts.map +1 -0
- package/dist/Fx/combinators/exit.js +11 -0
- package/dist/Fx/combinators/filter.d.ts +14 -0
- package/dist/Fx/combinators/filter.d.ts.map +1 -0
- package/dist/Fx/combinators/filter.js +12 -0
- package/dist/Fx/combinators/filterEffect.d.ts +15 -0
- package/dist/Fx/combinators/filterEffect.d.ts.map +1 -0
- package/dist/Fx/combinators/filterEffect.js +12 -0
- package/dist/Fx/combinators/filterMap.d.ts +15 -0
- package/dist/Fx/combinators/filterMap.d.ts.map +1 -0
- package/dist/Fx/combinators/filterMap.js +12 -0
- package/dist/Fx/combinators/filterMapEffect.d.ts +16 -0
- package/dist/Fx/combinators/filterMapEffect.d.ts.map +1 -0
- package/dist/Fx/combinators/filterMapEffect.js +12 -0
- package/dist/Fx/combinators/filterMapLoop.d.ts +17 -0
- package/dist/Fx/combinators/filterMapLoop.d.ts.map +1 -0
- package/dist/Fx/combinators/filterMapLoop.js +14 -0
- package/dist/Fx/combinators/filterMapLoopCause.d.ts +18 -0
- package/dist/Fx/combinators/filterMapLoopCause.d.ts.map +1 -0
- package/dist/Fx/combinators/filterMapLoopCause.js +14 -0
- package/dist/Fx/combinators/filterMapLoopCauseEffect.d.ts +18 -0
- package/dist/Fx/combinators/filterMapLoopCauseEffect.d.ts.map +1 -0
- package/dist/Fx/combinators/filterMapLoopCauseEffect.js +13 -0
- package/dist/Fx/combinators/filterMapLoopEffect.d.ts +17 -0
- package/dist/Fx/combinators/filterMapLoopEffect.d.ts.map +1 -0
- package/dist/Fx/combinators/filterMapLoopEffect.js +13 -0
- package/dist/Fx/combinators/flatMap.d.ts +23 -0
- package/dist/Fx/combinators/flatMap.d.ts.map +1 -0
- package/dist/Fx/combinators/flatMap.js +21 -0
- package/dist/Fx/combinators/flatMapConcurrently.d.ts +12 -0
- package/dist/Fx/combinators/flatMapConcurrently.d.ts.map +1 -0
- package/dist/Fx/combinators/flatMapConcurrently.js +23 -0
- package/dist/Fx/combinators/flatMapConcurrentlyEffect.d.ts +12 -0
- package/dist/Fx/combinators/flatMapConcurrentlyEffect.d.ts.map +1 -0
- package/dist/Fx/combinators/flatMapConcurrentlyEffect.js +13 -0
- package/dist/Fx/combinators/flatMapEffect.d.ts +24 -0
- package/dist/Fx/combinators/flatMapEffect.d.ts.map +1 -0
- package/dist/Fx/combinators/flatMapEffect.js +14 -0
- package/dist/Fx/combinators/flip.d.ts +11 -0
- package/dist/Fx/combinators/flip.d.ts.map +1 -0
- package/dist/Fx/combinators/flip.js +11 -0
- package/dist/Fx/combinators/gen.d.ts +20 -0
- package/dist/Fx/combinators/gen.d.ts.map +1 -0
- package/dist/Fx/combinators/gen.js +14 -0
- package/dist/Fx/combinators/genScoped.d.ts +20 -0
- package/dist/Fx/combinators/genScoped.d.ts.map +1 -0
- package/dist/Fx/combinators/genScoped.js +13 -0
- package/dist/Fx/combinators/index.d.ts +62 -0
- package/dist/Fx/combinators/index.d.ts.map +1 -0
- package/dist/Fx/combinators/index.js +61 -0
- package/dist/Fx/combinators/keyed.d.ts +44 -0
- package/dist/Fx/combinators/keyed.d.ts.map +1 -0
- package/dist/Fx/combinators/keyed.js +199 -0
- package/dist/Fx/combinators/loop.d.ts +16 -0
- package/dist/Fx/combinators/loop.d.ts.map +1 -0
- package/dist/Fx/combinators/loop.js +14 -0
- package/dist/Fx/combinators/loopCause.d.ts +16 -0
- package/dist/Fx/combinators/loopCause.d.ts.map +1 -0
- package/dist/Fx/combinators/loopCause.js +13 -0
- package/dist/Fx/combinators/loopCauseEffect.d.ts +17 -0
- package/dist/Fx/combinators/loopCauseEffect.d.ts.map +1 -0
- package/dist/Fx/combinators/loopCauseEffect.js +13 -0
- package/dist/Fx/combinators/loopEffect.d.ts +16 -0
- package/dist/Fx/combinators/loopEffect.d.ts.map +1 -0
- package/dist/Fx/combinators/loopEffect.js +13 -0
- package/dist/Fx/combinators/map.d.ts +14 -0
- package/dist/Fx/combinators/map.d.ts.map +1 -0
- package/dist/Fx/combinators/map.js +12 -0
- package/dist/Fx/combinators/mapBoth.d.ts +21 -0
- package/dist/Fx/combinators/mapBoth.d.ts.map +1 -0
- package/dist/Fx/combinators/mapBoth.js +14 -0
- package/dist/Fx/combinators/mapEffect.d.ts +15 -0
- package/dist/Fx/combinators/mapEffect.d.ts.map +1 -0
- package/dist/Fx/combinators/mapEffect.js +12 -0
- package/dist/Fx/combinators/mapError.d.ts +17 -0
- package/dist/Fx/combinators/mapError.d.ts.map +1 -0
- package/dist/Fx/combinators/mapError.js +16 -0
- package/dist/Fx/combinators/mergeAll.d.ts +11 -0
- package/dist/Fx/combinators/mergeAll.d.ts.map +1 -0
- package/dist/Fx/combinators/mergeAll.js +15 -0
- package/dist/Fx/combinators/mergeOrdered.d.ts +14 -0
- package/dist/Fx/combinators/mergeOrdered.d.ts.map +1 -0
- package/dist/Fx/combinators/mergeOrdered.js +89 -0
- package/dist/Fx/combinators/onError.d.ts +17 -0
- package/dist/Fx/combinators/onError.d.ts.map +1 -0
- package/dist/Fx/combinators/onError.js +14 -0
- package/dist/Fx/combinators/onExit.d.ts +16 -0
- package/dist/Fx/combinators/onExit.d.ts.map +1 -0
- package/dist/Fx/combinators/onExit.js +39 -0
- package/dist/Fx/combinators/onInterrupt.d.ts +16 -0
- package/dist/Fx/combinators/onInterrupt.d.ts.map +1 -0
- package/dist/Fx/combinators/onInterrupt.js +38 -0
- package/dist/Fx/combinators/provide.d.ts +56 -0
- package/dist/Fx/combinators/provide.d.ts.map +1 -0
- package/dist/Fx/combinators/provide.js +54 -0
- package/dist/Fx/combinators/result.d.ts +23 -0
- package/dist/Fx/combinators/result.d.ts.map +1 -0
- package/dist/Fx/combinators/result.js +32 -0
- package/dist/Fx/combinators/scan.d.ts +33 -0
- package/dist/Fx/combinators/scan.d.ts.map +1 -0
- package/dist/Fx/combinators/scan.js +38 -0
- package/dist/Fx/combinators/skip.d.ts +27 -0
- package/dist/Fx/combinators/skip.d.ts.map +1 -0
- package/dist/Fx/combinators/skip.js +22 -0
- package/dist/Fx/combinators/skipRepeats.d.ts +11 -0
- package/dist/Fx/combinators/skipRepeats.d.ts.map +1 -0
- package/dist/Fx/combinators/skipRepeats.js +12 -0
- package/dist/Fx/combinators/skipRepeatsWith.d.ts +12 -0
- package/dist/Fx/combinators/skipRepeatsWith.d.ts.map +1 -0
- package/dist/Fx/combinators/skipRepeatsWith.js +20 -0
- package/dist/Fx/combinators/skipWhile.d.ts +49 -0
- package/dist/Fx/combinators/skipWhile.d.ts.map +1 -0
- package/dist/Fx/combinators/skipWhile.js +66 -0
- package/dist/Fx/combinators/slice.d.ts +36 -0
- package/dist/Fx/combinators/slice.d.ts.map +1 -0
- package/dist/Fx/combinators/slice.js +23 -0
- package/dist/Fx/combinators/switchMap.d.ts +13 -0
- package/dist/Fx/combinators/switchMap.d.ts.map +1 -0
- package/dist/Fx/combinators/switchMap.js +33 -0
- package/dist/Fx/combinators/switchMapEffect.d.ts +13 -0
- package/dist/Fx/combinators/switchMapEffect.d.ts.map +1 -0
- package/dist/Fx/combinators/switchMapEffect.js +14 -0
- package/dist/Fx/combinators/take.d.ts +27 -0
- package/dist/Fx/combinators/take.d.ts.map +1 -0
- package/dist/Fx/combinators/take.js +22 -0
- package/dist/Fx/combinators/takeUntil.d.ts +42 -0
- package/dist/Fx/combinators/takeUntil.d.ts.map +1 -0
- package/dist/Fx/combinators/takeUntil.js +45 -0
- package/dist/Fx/combinators/takeWhile.d.ts +29 -0
- package/dist/Fx/combinators/takeWhile.d.ts.map +1 -0
- package/dist/Fx/combinators/takeWhile.js +23 -0
- package/dist/Fx/combinators/tapEffect.d.ts +15 -0
- package/dist/Fx/combinators/tapEffect.d.ts.map +1 -0
- package/dist/Fx/combinators/tapEffect.js +18 -0
- package/dist/Fx/combinators/tuple.d.ts +27 -0
- package/dist/Fx/combinators/tuple.d.ts.map +1 -0
- package/dist/Fx/combinators/tuple.js +46 -0
- package/dist/Fx/combinators/unwrap.d.ts +12 -0
- package/dist/Fx/combinators/unwrap.d.ts.map +1 -0
- package/dist/Fx/combinators/unwrap.js +14 -0
- package/dist/Fx/combinators/unwrapScoped.d.ts +15 -0
- package/dist/Fx/combinators/unwrapScoped.d.ts.map +1 -0
- package/dist/Fx/combinators/unwrapScoped.js +16 -0
- package/dist/Fx/combinators/when.d.ts +36 -0
- package/dist/Fx/combinators/when.d.ts.map +1 -0
- package/dist/Fx/combinators/when.js +28 -0
- package/dist/Fx/combinators/withSpan.d.ts +4 -0
- package/dist/Fx/combinators/withSpan.d.ts.map +1 -0
- package/dist/Fx/combinators/withSpan.js +6 -0
- package/dist/Fx/combinators/zip.d.ts +75 -0
- package/dist/Fx/combinators/zip.d.ts.map +1 -0
- package/dist/Fx/combinators/zip.js +100 -0
- package/dist/Fx/constructors/at.d.ts +16 -0
- package/dist/Fx/constructors/at.d.ts.map +1 -0
- package/dist/Fx/constructors/at.js +13 -0
- package/dist/Fx/constructors/die.d.ts +11 -0
- package/dist/Fx/constructors/die.d.ts.map +1 -0
- package/dist/Fx/constructors/die.js +12 -0
- package/dist/Fx/constructors/empty.d.ts +8 -0
- package/dist/Fx/constructors/empty.d.ts.map +1 -0
- package/dist/Fx/constructors/empty.js +8 -0
- package/dist/Fx/constructors/fail.d.ts +11 -0
- package/dist/Fx/constructors/fail.d.ts.map +1 -0
- package/dist/Fx/constructors/fail.js +12 -0
- package/dist/Fx/constructors/failCause.d.ts +12 -0
- package/dist/Fx/constructors/failCause.d.ts.map +1 -0
- package/dist/Fx/constructors/failCause.js +11 -0
- package/dist/Fx/constructors/fn.d.ts +47 -0
- package/dist/Fx/constructors/fn.d.ts.map +1 -0
- package/dist/Fx/constructors/fn.js +23 -0
- package/dist/Fx/constructors/fromEffect.d.ts +21 -0
- package/dist/Fx/constructors/fromEffect.d.ts.map +1 -0
- package/dist/Fx/constructors/fromEffect.js +21 -0
- package/dist/Fx/constructors/fromFailures.d.ts +10 -0
- package/dist/Fx/constructors/fromFailures.d.ts.map +1 -0
- package/dist/Fx/constructors/fromFailures.js +13 -0
- package/dist/Fx/constructors/fromIterable.d.ts +12 -0
- package/dist/Fx/constructors/fromIterable.d.ts.map +1 -0
- package/dist/Fx/constructors/fromIterable.js +12 -0
- package/dist/Fx/constructors/fromSchedule.d.ts +13 -0
- package/dist/Fx/constructors/fromSchedule.d.ts.map +1 -0
- package/dist/Fx/constructors/fromSchedule.js +13 -0
- package/dist/Fx/constructors/fromYieldable.d.ts +12 -0
- package/dist/Fx/constructors/fromYieldable.d.ts.map +1 -0
- package/dist/Fx/constructors/fromYieldable.js +12 -0
- package/dist/Fx/constructors/index.d.ts +16 -0
- package/dist/Fx/constructors/index.d.ts.map +1 -0
- package/dist/Fx/constructors/index.js +15 -0
- package/dist/Fx/constructors/interrupt.d.ts +10 -0
- package/dist/Fx/constructors/interrupt.d.ts.map +1 -0
- package/dist/Fx/constructors/interrupt.js +12 -0
- package/dist/Fx/constructors/make.d.ts +40 -0
- package/dist/Fx/constructors/make.d.ts.map +1 -0
- package/dist/Fx/constructors/make.js +61 -0
- package/dist/Fx/constructors/periodic.d.ts +12 -0
- package/dist/Fx/constructors/periodic.d.ts.map +1 -0
- package/dist/Fx/constructors/periodic.js +12 -0
- package/dist/Fx/constructors/succeed.d.ts +32 -0
- package/dist/Fx/constructors/succeed.d.ts.map +1 -0
- package/dist/Fx/constructors/succeed.js +32 -0
- package/dist/Fx/constructors/suspend.d.ts +3 -0
- package/dist/Fx/constructors/suspend.d.ts.map +1 -0
- package/dist/Fx/constructors/suspend.js +3 -0
- package/dist/Fx/index.d.ts +7 -0
- package/dist/Fx/index.d.ts.map +1 -0
- package/dist/Fx/index.js +6 -0
- package/dist/Fx/internal/DeferredRef.d.ts +29 -0
- package/dist/Fx/internal/DeferredRef.d.ts.map +1 -0
- package/dist/Fx/internal/DeferredRef.js +63 -0
- package/dist/Fx/internal/UnionToTuple.d.ts.map +1 -0
- package/dist/Fx/internal/UnionToTuple.js +1 -0
- package/dist/Fx/internal/diff.d.ts +44 -0
- package/dist/Fx/internal/diff.d.ts.map +1 -0
- package/dist/Fx/internal/diff.js +106 -0
- package/dist/Fx/internal/equivalence.d.ts +4 -0
- package/dist/Fx/internal/equivalence.d.ts.map +1 -0
- package/dist/Fx/internal/equivalence.js +10 -0
- package/dist/Fx/internal/multicast.d.ts +10 -0
- package/dist/Fx/internal/multicast.d.ts.map +1 -0
- package/dist/Fx/internal/multicast.js +32 -0
- package/dist/Fx/internal/ring-buffer.d.ts +14 -0
- package/dist/Fx/internal/ring-buffer.d.ts.map +1 -0
- package/dist/Fx/internal/ring-buffer.js +52 -0
- package/dist/Fx/internal/scope.d.ts +11 -0
- package/dist/Fx/internal/scope.d.ts.map +1 -0
- package/dist/Fx/internal/scope.js +12 -0
- package/dist/Fx/internal/yieldable.d.ts +17 -0
- package/dist/Fx/internal/yieldable.d.ts.map +1 -0
- package/dist/Fx/internal/yieldable.js +20 -0
- package/dist/Fx/run/collect.d.ts +45 -0
- package/dist/Fx/run/collect.d.ts.map +1 -0
- package/dist/Fx/run/collect.js +51 -0
- package/dist/Fx/run/first.d.ts +14 -0
- package/dist/Fx/run/first.d.ts.map +1 -0
- package/dist/Fx/run/first.js +16 -0
- package/dist/Fx/run/fork.d.ts +29 -0
- package/dist/Fx/run/fork.d.ts.map +1 -0
- package/dist/Fx/run/fork.js +27 -0
- package/dist/Fx/run/index.d.ts +6 -0
- package/dist/Fx/run/index.d.ts.map +1 -0
- package/dist/Fx/run/index.js +5 -0
- package/dist/Fx/run/observe.d.ts +53 -0
- package/dist/Fx/run/observe.d.ts.map +1 -0
- package/dist/Fx/run/observe.js +55 -0
- package/dist/Fx/run/runPromise.d.ts +25 -0
- package/dist/Fx/run/runPromise.d.ts.map +1 -0
- package/dist/Fx/run/runPromise.js +23 -0
- package/dist/Fx/stream.d.ts +7 -0
- package/dist/Fx/stream.d.ts.map +1 -0
- package/dist/Fx/stream.js +7 -0
- package/dist/Fx.d.ts +2 -0
- package/dist/Fx.d.ts.map +1 -0
- package/dist/Fx.js +1 -0
- package/dist/Push/Push.d.ts +375 -0
- package/dist/Push/Push.d.ts.map +1 -0
- package/dist/Push/Push.js +346 -0
- package/dist/Push/index.d.ts +2 -0
- package/dist/Push/index.d.ts.map +1 -0
- package/dist/Push/index.js +1 -0
- package/dist/Push.d.ts +2 -0
- package/dist/Push.d.ts.map +1 -0
- package/dist/Push.js +1 -0
- package/dist/RefSubject/RefArray.d.ts +328 -0
- package/dist/RefSubject/RefArray.d.ts.map +1 -0
- package/dist/RefSubject/RefArray.js +302 -0
- package/dist/RefSubject/RefBigDecimal.d.ts +183 -0
- package/dist/RefSubject/RefBigDecimal.d.ts.map +1 -0
- package/dist/RefSubject/RefBigDecimal.js +161 -0
- package/dist/RefSubject/RefBigInt.d.ts +138 -0
- package/dist/RefSubject/RefBigInt.d.ts.map +1 -0
- package/dist/RefSubject/RefBigInt.js +126 -0
- package/dist/RefSubject/RefBoolean.d.ts +135 -0
- package/dist/RefSubject/RefBoolean.d.ts.map +1 -0
- package/dist/RefSubject/RefBoolean.js +124 -0
- package/dist/RefSubject/RefCause.d.ts +100 -0
- package/dist/RefSubject/RefCause.d.ts.map +1 -0
- package/dist/RefSubject/RefCause.js +93 -0
- package/dist/RefSubject/RefChunk.d.ts +316 -0
- package/dist/RefSubject/RefChunk.d.ts.map +1 -0
- package/dist/RefSubject/RefChunk.js +286 -0
- package/dist/RefSubject/RefDateTime.d.ts +155 -0
- package/dist/RefSubject/RefDateTime.d.ts.map +1 -0
- package/dist/RefSubject/RefDateTime.js +101 -0
- package/dist/RefSubject/RefDuration.d.ts +126 -0
- package/dist/RefSubject/RefDuration.d.ts.map +1 -0
- package/dist/RefSubject/RefDuration.js +115 -0
- package/dist/RefSubject/RefGraph.d.ts +239 -0
- package/dist/RefSubject/RefGraph.d.ts.map +1 -0
- package/dist/RefSubject/RefGraph.js +272 -0
- package/dist/RefSubject/RefHashMap.d.ts +228 -0
- package/dist/RefSubject/RefHashMap.d.ts.map +1 -0
- package/dist/RefSubject/RefHashMap.js +212 -0
- package/dist/RefSubject/RefHashRing.d.ts +123 -0
- package/dist/RefSubject/RefHashRing.d.ts.map +1 -0
- package/dist/RefSubject/RefHashRing.js +115 -0
- package/dist/RefSubject/RefHashSet.d.ts +179 -0
- package/dist/RefSubject/RefHashSet.d.ts.map +1 -0
- package/dist/RefSubject/RefHashSet.js +164 -0
- package/dist/RefSubject/RefIterable.d.ts +257 -0
- package/dist/RefSubject/RefIterable.d.ts.map +1 -0
- package/dist/RefSubject/RefIterable.js +237 -0
- package/dist/RefSubject/RefOption.d.ts +124 -0
- package/dist/RefSubject/RefOption.d.ts.map +1 -0
- package/dist/RefSubject/RefOption.js +115 -0
- package/dist/RefSubject/RefRecord.d.ts +264 -0
- package/dist/RefSubject/RefRecord.d.ts.map +1 -0
- package/dist/RefSubject/RefRecord.js +249 -0
- package/dist/RefSubject/RefResult.d.ts +121 -0
- package/dist/RefSubject/RefResult.d.ts.map +1 -0
- package/dist/RefSubject/RefResult.js +107 -0
- package/dist/RefSubject/RefString.d.ts +147 -0
- package/dist/RefSubject/RefString.d.ts.map +1 -0
- package/dist/RefSubject/RefString.js +137 -0
- package/dist/RefSubject/RefStruct.d.ts +123 -0
- package/dist/RefSubject/RefStruct.d.ts.map +1 -0
- package/dist/RefSubject/RefStruct.js +113 -0
- package/dist/RefSubject/RefSubject.d.ts +1057 -0
- package/dist/RefSubject/RefSubject.d.ts.map +1 -0
- package/dist/RefSubject/RefSubject.js +1389 -0
- package/dist/RefSubject/RefTrie.d.ts +216 -0
- package/dist/RefSubject/RefTrie.d.ts.map +1 -0
- package/dist/RefSubject/RefTrie.js +201 -0
- package/dist/RefSubject/RefTuple.d.ts +107 -0
- package/dist/RefSubject/RefTuple.d.ts.map +1 -0
- package/dist/RefSubject/RefTuple.js +94 -0
- package/dist/RefSubject/index.d.ts +22 -0
- package/dist/RefSubject/index.d.ts.map +1 -0
- package/dist/RefSubject/index.js +21 -0
- package/dist/RefSubject.d.ts +2 -0
- package/dist/RefSubject.d.ts.map +1 -0
- package/dist/RefSubject.js +1 -0
- package/dist/Sink/Sink.d.ts +94 -0
- package/dist/Sink/Sink.d.ts.map +1 -0
- package/dist/Sink/Sink.js +34 -0
- package/dist/Sink/combinators.d.ts +228 -0
- package/dist/Sink/combinators.d.ts.map +1 -0
- package/dist/Sink/combinators.js +689 -0
- package/dist/Sink/index.d.ts +3 -0
- package/dist/Sink/index.d.ts.map +1 -0
- package/dist/Sink/index.js +2 -0
- package/dist/Sink.d.ts +2 -0
- package/dist/Sink.d.ts.map +1 -0
- package/dist/Sink.js +1 -0
- package/dist/Subject/Subject.d.ts +152 -0
- package/dist/Subject/Subject.d.ts.map +1 -0
- package/dist/Subject/Subject.js +272 -0
- package/dist/Subject/index.d.ts +2 -0
- package/dist/Subject/index.d.ts.map +1 -0
- package/dist/Subject/index.js +1 -0
- package/dist/Subject.d.ts +2 -0
- package/dist/Subject.d.ts.map +1 -0
- package/dist/Subject.js +1 -0
- package/dist/Versioned/Versioned.d.ts +206 -0
- package/dist/Versioned/Versioned.d.ts.map +1 -0
- package/dist/Versioned/Versioned.js +246 -0
- package/dist/Versioned/index.d.ts +2 -0
- package/dist/Versioned/index.d.ts.map +1 -0
- package/dist/Versioned/index.js +1 -0
- package/dist/Versioned.d.ts +2 -0
- package/dist/Versioned.d.ts.map +1 -0
- package/dist/Versioned.js +1 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +7 -0
- package/package.json +26 -195
- package/src/Fx/Fx.ts +164 -0
- package/src/Fx/TypeId.ts +25 -0
- package/src/Fx/combinators/additive.ts +142 -0
- package/src/Fx/combinators/catch.ts +421 -0
- package/src/Fx/combinators/causes.ts +23 -0
- package/src/Fx/combinators/changesWithEffect.ts +66 -0
- package/src/Fx/combinators/compact.ts +15 -0
- package/src/Fx/combinators/continueWith.ts +78 -0
- package/src/Fx/combinators/dropUntil.ts +47 -0
- package/src/Fx/combinators/ensuring.ts +23 -0
- package/src/Fx/combinators/exhaustLatestMap.ts +74 -0
- package/src/Fx/combinators/exhaustLatestMapEffect.ts +25 -0
- package/src/Fx/combinators/exhaustMap.ts +36 -0
- package/src/Fx/combinators/exhaustMapEffect.ts +23 -0
- package/src/Fx/combinators/exit.ts +15 -0
- package/src/Fx/combinators/filter.ts +22 -0
- package/src/Fx/combinators/filterEffect.ts +31 -0
- package/src/Fx/combinators/filterMap.ts +23 -0
- package/src/Fx/combinators/filterMapEffect.ts +32 -0
- package/src/Fx/combinators/filterMapLoop.ts +35 -0
- package/src/Fx/combinators/filterMapLoopCause.ts +36 -0
- package/src/Fx/combinators/filterMapLoopCauseEffect.ts +46 -0
- package/src/Fx/combinators/filterMapLoopEffect.ts +36 -0
- package/src/Fx/combinators/flatMap.ts +51 -0
- package/src/Fx/combinators/flatMapConcurrently.ts +39 -0
- package/src/Fx/combinators/flatMapConcurrentlyEffect.ts +26 -0
- package/src/Fx/combinators/flatMapEffect.ts +42 -0
- package/src/Fx/combinators/flip.ts +14 -0
- package/src/Fx/combinators/gen.ts +24 -0
- package/src/Fx/combinators/genScoped.ts +24 -0
- package/src/Fx/combinators/index.ts +61 -0
- package/src/Fx/combinators/keyed.ts +369 -0
- package/src/Fx/combinators/loop.ts +27 -0
- package/src/Fx/combinators/loopCause.ts +34 -0
- package/src/Fx/combinators/loopCauseEffect.ts +36 -0
- package/src/Fx/combinators/loopEffect.ts +34 -0
- package/src/Fx/combinators/map.ts +22 -0
- package/src/Fx/combinators/mapBoth.ts +40 -0
- package/src/Fx/combinators/mapEffect.ts +32 -0
- package/src/Fx/combinators/mapError.ts +28 -0
- package/src/Fx/combinators/mergeAll.ts +22 -0
- package/src/Fx/combinators/mergeOrdered.ts +123 -0
- package/src/Fx/combinators/onError.ts +40 -0
- package/src/Fx/combinators/onExit.ts +82 -0
- package/src/Fx/combinators/onInterrupt.ts +87 -0
- package/src/Fx/combinators/provide.ts +124 -0
- package/src/Fx/combinators/result.ts +39 -0
- package/src/Fx/combinators/scan.ts +82 -0
- package/src/Fx/combinators/skip.ts +41 -0
- package/src/Fx/combinators/skipRepeats.ts +15 -0
- package/src/Fx/combinators/skipRepeatsWith.ts +40 -0
- package/src/Fx/combinators/skipWhile.ts +100 -0
- package/src/Fx/combinators/slice.ts +55 -0
- package/src/Fx/combinators/switchMap.ts +55 -0
- package/src/Fx/combinators/switchMapEffect.ts +25 -0
- package/src/Fx/combinators/take.ts +38 -0
- package/src/Fx/combinators/takeUntil.ts +88 -0
- package/src/Fx/combinators/takeWhile.ts +47 -0
- package/src/Fx/combinators/tapEffect.ts +39 -0
- package/src/Fx/combinators/tuple.ts +79 -0
- package/src/Fx/combinators/unwrap.ts +21 -0
- package/src/Fx/combinators/unwrapScoped.ts +26 -0
- package/src/Fx/combinators/when.ts +64 -0
- package/src/Fx/combinators/withSpan.ts +24 -0
- package/src/Fx/combinators/zip.ts +175 -0
- package/src/Fx/constructors/at.ts +23 -0
- package/src/Fx/constructors/die.ts +17 -0
- package/src/Fx/constructors/empty.ts +10 -0
- package/src/Fx/constructors/fail.ts +14 -0
- package/src/Fx/constructors/failCause.ts +14 -0
- package/src/Fx/constructors/fn.ts +245 -0
- package/src/Fx/constructors/fromEffect.ts +24 -0
- package/src/Fx/constructors/fromFailures.ts +19 -0
- package/src/Fx/constructors/fromIterable.ts +15 -0
- package/src/Fx/constructors/fromSchedule.ts +18 -0
- package/src/Fx/constructors/fromYieldable.ts +17 -0
- package/src/Fx/constructors/index.ts +15 -0
- package/src/Fx/constructors/interrupt.ts +13 -0
- package/src/Fx/constructors/make.ts +103 -0
- package/src/Fx/constructors/periodic.ts +15 -0
- package/src/Fx/constructors/succeed.ts +37 -0
- package/src/Fx/constructors/suspend.ts +6 -0
- package/src/Fx/index.ts +6 -0
- package/src/Fx/internal/DeferredRef.ts +87 -0
- package/src/Fx/internal/UnionToTuple.ts +12 -0
- package/src/Fx/internal/diff.ts +191 -0
- package/src/Fx/internal/equivalence.ts +12 -0
- package/src/Fx/internal/multicast.ts +51 -0
- package/src/Fx/internal/ring-buffer.ts +60 -0
- package/src/Fx/internal/scope.ts +58 -0
- package/src/Fx/internal/yieldable.ts +31 -0
- package/src/Fx/run/collect.ts +79 -0
- package/src/Fx/run/first.ts +20 -0
- package/src/Fx/run/fork.ts +40 -0
- package/src/Fx/run/index.ts +5 -0
- package/src/Fx/run/observe.ts +114 -0
- package/src/Fx/run/runPromise.ts +32 -0
- package/src/Fx/stream.ts +42 -0
- package/src/Fx.additive-combinators.test.ts +126 -0
- package/src/Fx.catch-additive.test.ts +206 -0
- package/src/Fx.catch.test.ts +60 -0
- package/src/Fx.dropUntil.test.ts +61 -0
- package/src/Fx.fn.test.ts +51 -0
- package/src/Fx.lifecycle.test.ts +79 -0
- package/src/Fx.mapError-mapBoth.test.ts +101 -0
- package/src/Fx.provide-combinators.test.ts +94 -0
- package/src/Fx.result-changesWithEffect.test.ts +112 -0
- package/src/Fx.scan.test.ts +73 -0
- package/src/Fx.takeWhile-skipWhile.test.ts +84 -0
- package/src/Fx.test.ts +71 -0
- package/src/Fx.ts +1 -2591
- package/src/Fx.zip-merge-additive.test.ts +171 -0
- package/src/Fx.zip.test.ts +133 -0
- package/src/Push/Push.ts +1072 -0
- package/src/Push/index.ts +1 -0
- package/src/Push.additive.test.ts +256 -0
- package/src/Push.test.ts +26 -0
- package/src/Push.ts +1 -480
- package/src/RefSubject/RefArray.ts +512 -0
- package/src/RefSubject/RefBigDecimal.test.ts +56 -0
- package/src/RefSubject/RefBigDecimal.ts +295 -0
- package/src/RefSubject/RefBigInt.test.ts +56 -0
- package/src/RefSubject/RefBigInt.ts +189 -0
- package/src/RefSubject/RefBoolean.test.ts +57 -0
- package/src/RefSubject/RefBoolean.ts +185 -0
- package/src/RefSubject/RefCause.test.ts +53 -0
- package/src/RefSubject/RefCause.ts +146 -0
- package/src/RefSubject/RefChunk.ts +510 -0
- package/src/RefSubject/RefDateTime.test.ts +43 -0
- package/src/RefSubject/RefDateTime.ts +264 -0
- package/src/RefSubject/RefDuration.test.ts +49 -0
- package/src/RefSubject/RefDuration.ts +188 -0
- package/src/RefSubject/RefGraph.ts +650 -0
- package/src/RefSubject/RefHashMap.ts +465 -0
- package/src/RefSubject/RefHashRing.ts +262 -0
- package/src/RefSubject/RefHashSet.ts +308 -0
- package/src/RefSubject/RefIterable.ts +445 -0
- package/src/RefSubject/RefOption.test.ts +67 -0
- package/src/RefSubject/RefOption.ts +193 -0
- package/src/RefSubject/RefRecord.ts +612 -0
- package/src/RefSubject/RefResult.test.ts +63 -0
- package/src/RefSubject/RefResult.ts +209 -0
- package/src/RefSubject/RefString.test.ts +61 -0
- package/src/RefSubject/RefString.ts +256 -0
- package/src/RefSubject/RefStruct.test.ts +60 -0
- package/src/RefSubject/RefStruct.ts +253 -0
- package/src/RefSubject/RefSubject.ts +2646 -0
- package/src/RefSubject/RefTrie.ts +356 -0
- package/src/RefSubject/RefTuple.test.ts +60 -0
- package/src/RefSubject/RefTuple.ts +231 -0
- package/src/RefSubject/index.ts +21 -0
- package/src/RefSubject.additive-parity.test.ts +101 -0
- package/src/RefSubject.test.ts +65 -0
- package/src/RefSubject.ts +1 -2488
- package/src/Sink/Sink.ts +159 -0
- package/src/Sink/combinators.ts +1115 -0
- package/src/Sink/index.ts +2 -0
- package/src/Sink.combinators.test.ts +88 -0
- package/src/Sink.reduce-collect-head-last.test.ts +107 -0
- package/src/Sink.ts +1 -1044
- package/src/Subject/Subject.ts +441 -0
- package/src/Subject/index.ts +1 -0
- package/src/Subject.test.ts +47 -0
- package/src/Subject.ts +1 -330
- package/src/Versioned/Versioned.ts +597 -0
- package/src/Versioned/index.ts +1 -0
- package/src/Versioned.filterMap.test.ts +91 -0
- package/src/Versioned.test.ts +23 -0
- package/src/Versioned.ts +1 -357
- package/src/index.ts +7 -130
- package/AsyncData/package.json +0 -6
- package/Emitter/package.json +0 -6
- package/Form/package.json +0 -6
- package/FormEntry/package.json +0 -6
- package/Fx/package.json +0 -6
- package/Idle/package.json +0 -6
- package/LICENSE +0 -21
- package/Match/package.json +0 -6
- package/Pull/package.json +0 -6
- package/Push/package.json +0 -6
- package/RefArray/package.json +0 -6
- package/RefChunk/package.json +0 -6
- package/RefHashMap/package.json +0 -6
- package/RefHashSet/package.json +0 -6
- package/RefSubject/package.json +0 -6
- package/Sink/package.json +0 -6
- package/Stream/package.json +0 -6
- package/Subject/package.json +0 -6
- package/TypeId/package.json +0 -6
- package/Typeclass/package.json +0 -6
- package/Versioned/package.json +0 -6
- package/dist/cjs/AsyncData.js +0 -188
- package/dist/cjs/AsyncData.js.map +0 -1
- package/dist/cjs/Emitter.js +0 -44
- package/dist/cjs/Emitter.js.map +0 -1
- package/dist/cjs/Form.js +0 -178
- package/dist/cjs/Form.js.map +0 -1
- package/dist/cjs/FormEntry.js +0 -110
- package/dist/cjs/FormEntry.js.map +0 -1
- package/dist/cjs/Fx.js +0 -998
- package/dist/cjs/Fx.js.map +0 -1
- package/dist/cjs/Idle.js +0 -190
- package/dist/cjs/Idle.js.map +0 -1
- package/dist/cjs/Match.js +0 -191
- package/dist/cjs/Match.js.map +0 -1
- package/dist/cjs/Pull.js +0 -52
- package/dist/cjs/Pull.js.map +0 -1
- package/dist/cjs/Push.js +0 -168
- package/dist/cjs/Push.js.map +0 -1
- package/dist/cjs/RefArray.js +0 -253
- package/dist/cjs/RefArray.js.map +0 -1
- package/dist/cjs/RefChunk.js +0 -212
- package/dist/cjs/RefChunk.js.map +0 -1
- package/dist/cjs/RefHashMap.js +0 -198
- package/dist/cjs/RefHashMap.js.map +0 -1
- package/dist/cjs/RefHashSet.js +0 -99
- package/dist/cjs/RefHashSet.js.map +0 -1
- package/dist/cjs/RefSubject.js +0 -1115
- package/dist/cjs/RefSubject.js.map +0 -1
- package/dist/cjs/Sink.js +0 -662
- package/dist/cjs/Sink.js.map +0 -1
- package/dist/cjs/Stream.js +0 -87
- package/dist/cjs/Stream.js.map +0 -1
- package/dist/cjs/Subject.js +0 -205
- package/dist/cjs/Subject.js.map +0 -1
- package/dist/cjs/TypeId.js +0 -32
- package/dist/cjs/TypeId.js.map +0 -1
- package/dist/cjs/Typeclass.js +0 -380
- package/dist/cjs/Typeclass.js.map +0 -1
- package/dist/cjs/Versioned.js +0 -172
- package/dist/cjs/Versioned.js.map +0 -1
- package/dist/cjs/index.js +0 -89
- package/dist/cjs/index.js.map +0 -1
- package/dist/cjs/internal/DeferredRef.js +0 -67
- package/dist/cjs/internal/DeferredRef.js.map +0 -1
- package/dist/cjs/internal/UnionToTuple.js +0 -6
- package/dist/cjs/internal/UnionToTuple.js.map +0 -1
- package/dist/cjs/internal/bounds.js +0 -26
- package/dist/cjs/internal/bounds.js.map +0 -1
- package/dist/cjs/internal/core.js +0 -1783
- package/dist/cjs/internal/core.js.map +0 -1
- package/dist/cjs/internal/diff.js +0 -122
- package/dist/cjs/internal/diff.js.map +0 -1
- package/dist/cjs/internal/effect-loop-operator.js +0 -288
- package/dist/cjs/internal/effect-loop-operator.js.map +0 -1
- package/dist/cjs/internal/effect-operator.js +0 -156
- package/dist/cjs/internal/effect-operator.js.map +0 -1
- package/dist/cjs/internal/effect-producer.js +0 -74
- package/dist/cjs/internal/effect-producer.js.map +0 -1
- package/dist/cjs/internal/helpers.js +0 -317
- package/dist/cjs/internal/helpers.js.map +0 -1
- package/dist/cjs/internal/keyed.js +0 -168
- package/dist/cjs/internal/keyed.js.map +0 -1
- package/dist/cjs/internal/loop-operator.js +0 -213
- package/dist/cjs/internal/loop-operator.js.map +0 -1
- package/dist/cjs/internal/operator.js +0 -79
- package/dist/cjs/internal/operator.js.map +0 -1
- package/dist/cjs/internal/protos.js +0 -48
- package/dist/cjs/internal/protos.js.map +0 -1
- package/dist/cjs/internal/provide.js +0 -100
- package/dist/cjs/internal/provide.js.map +0 -1
- package/dist/cjs/internal/requestIdleCallback.js +0 -22
- package/dist/cjs/internal/requestIdleCallback.js.map +0 -1
- package/dist/cjs/internal/share.js +0 -74
- package/dist/cjs/internal/share.js.map +0 -1
- package/dist/cjs/internal/strategies.js +0 -34
- package/dist/cjs/internal/strategies.js.map +0 -1
- package/dist/cjs/internal/sync-operator.js +0 -120
- package/dist/cjs/internal/sync-operator.js.map +0 -1
- package/dist/cjs/internal/sync-producer.js +0 -118
- package/dist/cjs/internal/sync-producer.js.map +0 -1
- package/dist/cjs/internal/withKey.js +0 -63
- package/dist/cjs/internal/withKey.js.map +0 -1
- package/dist/dts/AsyncData.d.ts +0 -179
- package/dist/dts/AsyncData.d.ts.map +0 -1
- package/dist/dts/Emitter.d.ts +0 -24
- package/dist/dts/Emitter.d.ts.map +0 -1
- package/dist/dts/Form.d.ts +0 -145
- package/dist/dts/Form.d.ts.map +0 -1
- package/dist/dts/FormEntry.d.ts +0 -65
- package/dist/dts/FormEntry.d.ts.map +0 -1
- package/dist/dts/Fx.d.ts +0 -1678
- package/dist/dts/Fx.d.ts.map +0 -1
- package/dist/dts/Idle.d.ts +0 -84
- package/dist/dts/Idle.d.ts.map +0 -1
- package/dist/dts/Match.d.ts +0 -60
- package/dist/dts/Match.d.ts.map +0 -1
- package/dist/dts/Pull.d.ts +0 -37
- package/dist/dts/Pull.d.ts.map +0 -1
- package/dist/dts/Push.d.ts +0 -176
- package/dist/dts/Push.d.ts.map +0 -1
- package/dist/dts/RefArray.d.ts +0 -278
- package/dist/dts/RefArray.d.ts.map +0 -1
- package/dist/dts/RefChunk.d.ts +0 -230
- package/dist/dts/RefChunk.d.ts.map +0 -1
- package/dist/dts/RefHashMap.d.ts +0 -189
- package/dist/dts/RefHashMap.d.ts.map +0 -1
- package/dist/dts/RefHashSet.d.ts +0 -100
- package/dist/dts/RefHashSet.d.ts.map +0 -1
- package/dist/dts/RefSubject.d.ts +0 -601
- package/dist/dts/RefSubject.d.ts.map +0 -1
- package/dist/dts/Sink.d.ts +0 -252
- package/dist/dts/Sink.d.ts.map +0 -1
- package/dist/dts/Stream.d.ts +0 -66
- package/dist/dts/Stream.d.ts.map +0 -1
- package/dist/dts/Subject.d.ts +0 -61
- package/dist/dts/Subject.d.ts.map +0 -1
- package/dist/dts/TypeId.d.ts +0 -51
- package/dist/dts/TypeId.d.ts.map +0 -1
- package/dist/dts/Typeclass.d.ts +0 -284
- package/dist/dts/Typeclass.d.ts.map +0 -1
- package/dist/dts/Versioned.d.ts +0 -117
- package/dist/dts/Versioned.d.ts.map +0 -1
- package/dist/dts/index.d.ts +0 -111
- package/dist/dts/index.d.ts.map +0 -1
- package/dist/dts/internal/DeferredRef.d.ts +0 -22
- package/dist/dts/internal/DeferredRef.d.ts.map +0 -1
- package/dist/dts/internal/UnionToTuple.d.ts.map +0 -1
- package/dist/dts/internal/bounds.d.ts +0 -9
- package/dist/dts/internal/bounds.d.ts.map +0 -1
- package/dist/dts/internal/core.d.ts +0 -237
- package/dist/dts/internal/core.d.ts.map +0 -1
- package/dist/dts/internal/diff.d.ts +0 -42
- package/dist/dts/internal/diff.d.ts.map +0 -1
- package/dist/dts/internal/effect-loop-operator.d.ts +0 -34
- package/dist/dts/internal/effect-loop-operator.d.ts.map +0 -1
- package/dist/dts/internal/effect-operator.d.ts +0 -40
- package/dist/dts/internal/effect-operator.d.ts.map +0 -1
- package/dist/dts/internal/effect-producer.d.ts +0 -25
- package/dist/dts/internal/effect-producer.d.ts.map +0 -1
- package/dist/dts/internal/helpers.d.ts +0 -60
- package/dist/dts/internal/helpers.d.ts.map +0 -1
- package/dist/dts/internal/keyed.d.ts +0 -4
- package/dist/dts/internal/keyed.d.ts.map +0 -1
- package/dist/dts/internal/loop-operator.d.ts +0 -40
- package/dist/dts/internal/loop-operator.d.ts.map +0 -1
- package/dist/dts/internal/operator.d.ts +0 -16
- package/dist/dts/internal/operator.d.ts.map +0 -1
- package/dist/dts/internal/protos.d.ts +0 -23
- package/dist/dts/internal/protos.d.ts.map +0 -1
- package/dist/dts/internal/provide.d.ts +0 -46
- package/dist/dts/internal/provide.d.ts.map +0 -1
- package/dist/dts/internal/requestIdleCallback.d.ts +0 -3
- package/dist/dts/internal/requestIdleCallback.d.ts.map +0 -1
- package/dist/dts/internal/share.d.ts +0 -33
- package/dist/dts/internal/share.d.ts.map +0 -1
- package/dist/dts/internal/strategies.d.ts +0 -9
- package/dist/dts/internal/strategies.d.ts.map +0 -1
- package/dist/dts/internal/sync-operator.d.ts +0 -32
- package/dist/dts/internal/sync-operator.d.ts.map +0 -1
- package/dist/dts/internal/sync-producer.d.ts +0 -36
- package/dist/dts/internal/sync-producer.d.ts.map +0 -1
- package/dist/dts/internal/withKey.d.ts +0 -4
- package/dist/dts/internal/withKey.d.ts.map +0 -1
- package/dist/esm/AsyncData.js +0 -156
- package/dist/esm/AsyncData.js.map +0 -1
- package/dist/esm/Emitter.js +0 -33
- package/dist/esm/Emitter.js.map +0 -1
- package/dist/esm/Form.js +0 -163
- package/dist/esm/Form.js.map +0 -1
- package/dist/esm/FormEntry.js +0 -100
- package/dist/esm/FormEntry.js.map +0 -1
- package/dist/esm/Fx.js +0 -984
- package/dist/esm/Fx.js.map +0 -1
- package/dist/esm/Idle.js +0 -178
- package/dist/esm/Idle.js.map +0 -1
- package/dist/esm/Match.js +0 -185
- package/dist/esm/Match.js.map +0 -1
- package/dist/esm/Pull.js +0 -41
- package/dist/esm/Pull.js.map +0 -1
- package/dist/esm/Push.js +0 -159
- package/dist/esm/Push.js.map +0 -1
- package/dist/esm/RefArray.js +0 -234
- package/dist/esm/RefArray.js.map +0 -1
- package/dist/esm/RefChunk.js +0 -196
- package/dist/esm/RefChunk.js.map +0 -1
- package/dist/esm/RefHashMap.js +0 -176
- package/dist/esm/RefHashMap.js.map +0 -1
- package/dist/esm/RefHashSet.js +0 -86
- package/dist/esm/RefHashSet.js.map +0 -1
- package/dist/esm/RefSubject.js +0 -1076
- package/dist/esm/RefSubject.js.map +0 -1
- package/dist/esm/Sink.js +0 -673
- package/dist/esm/Sink.js.map +0 -1
- package/dist/esm/Stream.js +0 -76
- package/dist/esm/Stream.js.map +0 -1
- package/dist/esm/Subject.js +0 -198
- package/dist/esm/Subject.js.map +0 -1
- package/dist/esm/TypeId.js +0 -26
- package/dist/esm/TypeId.js.map +0 -1
- package/dist/esm/Typeclass.js +0 -375
- package/dist/esm/Typeclass.js.map +0 -1
- package/dist/esm/Versioned.js +0 -149
- package/dist/esm/Versioned.js.map +0 -1
- package/dist/esm/index.js +0 -111
- package/dist/esm/index.js.map +0 -1
- package/dist/esm/internal/DeferredRef.js +0 -57
- package/dist/esm/internal/DeferredRef.js.map +0 -1
- package/dist/esm/internal/UnionToTuple.js +0 -2
- package/dist/esm/internal/UnionToTuple.js.map +0 -1
- package/dist/esm/internal/bounds.js +0 -13
- package/dist/esm/internal/bounds.js.map +0 -1
- package/dist/esm/internal/core.js +0 -1647
- package/dist/esm/internal/core.js.map +0 -1
- package/dist/esm/internal/diff.js +0 -92
- package/dist/esm/internal/diff.js.map +0 -1
- package/dist/esm/internal/effect-loop-operator.js +0 -269
- package/dist/esm/internal/effect-loop-operator.js.map +0 -1
- package/dist/esm/internal/effect-operator.js +0 -134
- package/dist/esm/internal/effect-operator.js.map +0 -1
- package/dist/esm/internal/effect-producer.js +0 -47
- package/dist/esm/internal/effect-producer.js.map +0 -1
- package/dist/esm/internal/helpers.js +0 -299
- package/dist/esm/internal/helpers.js.map +0 -1
- package/dist/esm/internal/keyed.js +0 -153
- package/dist/esm/internal/keyed.js.map +0 -1
- package/dist/esm/internal/loop-operator.js +0 -186
- package/dist/esm/internal/loop-operator.js.map +0 -1
- package/dist/esm/internal/operator.js +0 -68
- package/dist/esm/internal/operator.js.map +0 -1
- package/dist/esm/internal/protos.js +0 -39
- package/dist/esm/internal/protos.js.map +0 -1
- package/dist/esm/internal/provide.js +0 -72
- package/dist/esm/internal/provide.js.map +0 -1
- package/dist/esm/internal/requestIdleCallback.js +0 -16
- package/dist/esm/internal/requestIdleCallback.js.map +0 -1
- package/dist/esm/internal/share.js +0 -62
- package/dist/esm/internal/share.js.map +0 -1
- package/dist/esm/internal/strategies.js +0 -8
- package/dist/esm/internal/strategies.js.map +0 -1
- package/dist/esm/internal/sync-operator.js +0 -95
- package/dist/esm/internal/sync-operator.js.map +0 -1
- package/dist/esm/internal/sync-producer.js +0 -90
- package/dist/esm/internal/sync-producer.js.map +0 -1
- package/dist/esm/internal/withKey.js +0 -56
- package/dist/esm/internal/withKey.js.map +0 -1
- package/dist/esm/package.json +0 -4
- package/src/AsyncData.ts +0 -453
- package/src/Emitter.ts +0 -59
- package/src/Form.ts +0 -489
- package/src/FormEntry.ts +0 -214
- package/src/Idle.ts +0 -294
- package/src/Match.ts +0 -314
- package/src/Pull.ts +0 -95
- package/src/RefArray.ts +0 -514
- package/src/RefChunk.ts +0 -407
- package/src/RefHashMap.ts +0 -335
- package/src/RefHashSet.ts +0 -179
- package/src/Stream.ts +0 -140
- package/src/TypeId.ts +0 -59
- package/src/Typeclass.ts +0 -459
- package/src/internal/DeferredRef.ts +0 -72
- package/src/internal/UnionToTuple.ts +0 -11
- package/src/internal/bounds.ts +0 -21
- package/src/internal/core.ts +0 -3091
- package/src/internal/diff.ts +0 -171
- package/src/internal/effect-loop-operator.ts +0 -466
- package/src/internal/effect-operator.ts +0 -317
- package/src/internal/effect-producer.ts +0 -125
- package/src/internal/helpers.ts +0 -538
- package/src/internal/keyed.ts +0 -235
- package/src/internal/loop-operator.ts +0 -266
- package/src/internal/operator.ts +0 -87
- package/src/internal/protos.ts +0 -57
- package/src/internal/provide.ts +0 -151
- package/src/internal/requestIdleCallback.ts +0 -19
- package/src/internal/share.ts +0 -97
- package/src/internal/strategies.ts +0 -15
- package/src/internal/sync-operator.ts +0 -166
- package/src/internal/sync-producer.ts +0 -148
- package/src/internal/withKey.ts +0 -82
- /package/dist/{dts → Fx}/internal/UnionToTuple.d.ts +0 -0
|
@@ -0,0 +1,2646 @@
|
|
|
1
|
+
/** @effect-diagnostics missingEffectError:skip-file */
|
|
2
|
+
/** @effect-diagnostics missingEffectContext:skip-file */
|
|
3
|
+
|
|
4
|
+
import * as Array from "effect/Array";
|
|
5
|
+
import type * as Cause from "effect/Cause";
|
|
6
|
+
import * as Effect from "effect/Effect";
|
|
7
|
+
import * as Semaphore from "effect/Semaphore";
|
|
8
|
+
import { equals } from "effect/Equal";
|
|
9
|
+
import type { Equivalence } from "effect/Equivalence";
|
|
10
|
+
import * as Exit from "effect/Exit";
|
|
11
|
+
import * as Fiber from "effect/Fiber";
|
|
12
|
+
import { dual, identity } from "effect/Function";
|
|
13
|
+
import * as Layer from "effect/Layer";
|
|
14
|
+
import * as MutableRef from "effect/MutableRef";
|
|
15
|
+
import { sum } from "effect/Number";
|
|
16
|
+
import * as Option from "effect/Option";
|
|
17
|
+
import { pipeArguments } from "effect/Pipeable";
|
|
18
|
+
import * as Scope from "effect/Scope";
|
|
19
|
+
import * as ServiceMap from "effect/ServiceMap";
|
|
20
|
+
import * as Stream from "effect/Stream";
|
|
21
|
+
import { compact as fxCompact } from "../Fx/combinators/compact.js";
|
|
22
|
+
import { continueWith } from "../Fx/combinators/continueWith.js";
|
|
23
|
+
import { filterMapEffect as fxFilterMapEffect } from "../Fx/combinators/filterMapEffect.js";
|
|
24
|
+
import { mapEffect as fxMapEffect } from "../Fx/combinators/mapEffect.js";
|
|
25
|
+
import { skipRepeats } from "../Fx/combinators/skipRepeats.js";
|
|
26
|
+
import type { Bounds } from "../Fx/combinators/slice.js";
|
|
27
|
+
import { slice as fxSlice } from "../Fx/combinators/slice.js";
|
|
28
|
+
import { unwrap } from "../Fx/combinators/unwrap.js";
|
|
29
|
+
import { fromEffect as fxFromEffect } from "../Fx/constructors/fromEffect.js";
|
|
30
|
+
import { fromYieldable } from "../Fx/constructors/fromYieldable.js";
|
|
31
|
+
import type { Error as FxError, Fx } from "../Fx/index.js";
|
|
32
|
+
import * as DeferredRef from "../Fx/internal/DeferredRef.js";
|
|
33
|
+
import { getExitEquivalence } from "../Fx/internal/equivalence.js";
|
|
34
|
+
import type { UnionToTuple } from "../Fx/internal/UnionToTuple.js";
|
|
35
|
+
import { YieldableFx } from "../Fx/internal/yieldable.js";
|
|
36
|
+
import { FxTypeId, isFx } from "../Fx/TypeId.js";
|
|
37
|
+
import * as Sink from "../Sink/Sink.js";
|
|
38
|
+
import * as Subject from "../Subject/Subject.js";
|
|
39
|
+
import * as Versioned from "../Versioned/Versioned.js";
|
|
40
|
+
|
|
41
|
+
export const RefSubjectTypeId = Symbol.for("@typed/fx/RefSubject");
|
|
42
|
+
export type RefSubjectTypeId = typeof RefSubjectTypeId;
|
|
43
|
+
|
|
44
|
+
export const ComputedTypeId = Symbol.for("@typed/fx/Computed");
|
|
45
|
+
export type ComputedTypeId = typeof ComputedTypeId;
|
|
46
|
+
|
|
47
|
+
export const FilteredTypeId = Symbol.for("@typed/fx/Filtered");
|
|
48
|
+
export type FilteredTypeId = typeof FilteredTypeId;
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* A `Computed` is a read-only view of a value that can change over time.
|
|
52
|
+
* It is an `Fx` that emits the current value and subsequent updates.
|
|
53
|
+
* It is also an `Effect` that samples the current value.
|
|
54
|
+
*
|
|
55
|
+
* @example
|
|
56
|
+
* ```ts
|
|
57
|
+
* import { Effect } from "effect"
|
|
58
|
+
* import * as RefSubject from "@typed/fx/RefSubject"
|
|
59
|
+
* import { Fx } from "@typed/fx"
|
|
60
|
+
*
|
|
61
|
+
* // Create a RefSubject and derive a Computed from it
|
|
62
|
+
* const program = Effect.gen(function* () {
|
|
63
|
+
* const count = yield* RefSubject.make(0)
|
|
64
|
+
*
|
|
65
|
+
* // Create a computed that doubles the count
|
|
66
|
+
* const doubled = RefSubject.map(count, (n) => n * 2)
|
|
67
|
+
*
|
|
68
|
+
* // Sample the computed value
|
|
69
|
+
* const value = yield* doubled
|
|
70
|
+
* console.log(value) // 0
|
|
71
|
+
*
|
|
72
|
+
* // Update the source
|
|
73
|
+
* yield* RefSubject.set(count, 5)
|
|
74
|
+
*
|
|
75
|
+
* // The computed automatically reflects the change
|
|
76
|
+
* const newValue = yield* doubled
|
|
77
|
+
* console.log(newValue) // 10
|
|
78
|
+
* })
|
|
79
|
+
* ```
|
|
80
|
+
*
|
|
81
|
+
* @since 1.0.0
|
|
82
|
+
* @category models
|
|
83
|
+
*/
|
|
84
|
+
export interface Computed<out A, out E = never, out R = never> extends Versioned.Versioned<
|
|
85
|
+
R,
|
|
86
|
+
E,
|
|
87
|
+
A,
|
|
88
|
+
E,
|
|
89
|
+
R | Scope.Scope,
|
|
90
|
+
A,
|
|
91
|
+
E,
|
|
92
|
+
R
|
|
93
|
+
> {
|
|
94
|
+
readonly [ComputedTypeId]: ComputedTypeId;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
export declare namespace Computed {
|
|
98
|
+
export type Any =
|
|
99
|
+
| Computed<any, any, any>
|
|
100
|
+
| Computed<never, any, any>
|
|
101
|
+
| Computed<any, never, any>
|
|
102
|
+
| Computed<never, never, any>;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* A `Filtered` is a `Computed` that may not always have a value.
|
|
107
|
+
* It is essentially a `Computed<Option<A>>` with helper methods.
|
|
108
|
+
*
|
|
109
|
+
* @example
|
|
110
|
+
* ```ts
|
|
111
|
+
* import { Effect, Option } from "effect"
|
|
112
|
+
* import * as RefSubject from "@typed/fx/RefSubject"
|
|
113
|
+
*
|
|
114
|
+
* // Create a RefSubject and filter it
|
|
115
|
+
* const program = Effect.gen(function* () {
|
|
116
|
+
* const numbers = yield* RefSubject.make([1, 2, 3, 4, 5])
|
|
117
|
+
*
|
|
118
|
+
* // Get the first even number (filtered)
|
|
119
|
+
* const firstEven = RefSubject.filterMap(
|
|
120
|
+
* numbers,
|
|
121
|
+
* (arr) => Option.fromNullable(arr.find((n) => n % 2 === 0))
|
|
122
|
+
* )
|
|
123
|
+
*
|
|
124
|
+
* // Try to get the value (may fail with NoSuchElementError)
|
|
125
|
+
* const value = yield* firstEven
|
|
126
|
+
* console.log(value) // 2
|
|
127
|
+
*
|
|
128
|
+
* // Or convert back to Option
|
|
129
|
+
* const option = firstEven.asComputed()
|
|
130
|
+
* const maybeValue = yield* option
|
|
131
|
+
* console.log(Option.isSome(maybeValue)) // true
|
|
132
|
+
* })
|
|
133
|
+
* ```
|
|
134
|
+
*
|
|
135
|
+
* @since 1.0.0
|
|
136
|
+
* @category models
|
|
137
|
+
*/
|
|
138
|
+
export interface Filtered<out A, out E = never, out R = never> extends Versioned.Versioned<
|
|
139
|
+
R,
|
|
140
|
+
E,
|
|
141
|
+
A,
|
|
142
|
+
E,
|
|
143
|
+
R | Scope.Scope,
|
|
144
|
+
A,
|
|
145
|
+
E | Cause.NoSuchElementError,
|
|
146
|
+
R
|
|
147
|
+
> {
|
|
148
|
+
readonly [FilteredTypeId]: FilteredTypeId;
|
|
149
|
+
|
|
150
|
+
/**
|
|
151
|
+
* Converts the Filtered back to a Computed of Option.
|
|
152
|
+
*
|
|
153
|
+
* @example
|
|
154
|
+
* ```ts
|
|
155
|
+
* import { Effect, Option } from "effect"
|
|
156
|
+
* import * as RefSubject from "@typed/fx/RefSubject"
|
|
157
|
+
*
|
|
158
|
+
* const program = Effect.gen(function* () {
|
|
159
|
+
* const filtered = RefSubject.filterMap(
|
|
160
|
+
* yield* RefSubject.make([1, 2, 3]),
|
|
161
|
+
* (arr) => Option.fromNullable(arr.find((n) => n > 5))
|
|
162
|
+
* )
|
|
163
|
+
*
|
|
164
|
+
* // Convert to Computed<Option<number>>
|
|
165
|
+
* const computed = filtered.asComputed()
|
|
166
|
+
* const option = yield* computed
|
|
167
|
+
* console.log(Option.isNone(option)) // true (no number > 5)
|
|
168
|
+
* })
|
|
169
|
+
* ```
|
|
170
|
+
*/
|
|
171
|
+
asComputed(): Computed<Option.Option<A>, E, R>;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
export declare namespace Filtered {
|
|
175
|
+
export type Any =
|
|
176
|
+
| Filtered<any, any, any>
|
|
177
|
+
| Filtered<never, any, any>
|
|
178
|
+
| Filtered<any, never, any>
|
|
179
|
+
| Filtered<never, never, any>;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
/**
|
|
183
|
+
* Interface for basic RefSubject operations: get, set, delete.
|
|
184
|
+
* @since 1.0.0
|
|
185
|
+
* @category models
|
|
186
|
+
*/
|
|
187
|
+
export interface GetSetDelete<A, E = never, R = never> {
|
|
188
|
+
readonly get: Effect.Effect<A, E, R>;
|
|
189
|
+
readonly set: (a: A) => Effect.Effect<A, E, R>;
|
|
190
|
+
readonly delete: Effect.Effect<Option.Option<A>, E, R>;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
/**
|
|
194
|
+
* A `RefSubject` is a mutable reference that can be observed as an Fx.
|
|
195
|
+
* It combines the capabilities of a `Ref` (get/set/update) with a `Subject` (subscribe).
|
|
196
|
+
*
|
|
197
|
+
* @example
|
|
198
|
+
* ```ts
|
|
199
|
+
* import { Effect } from "effect"
|
|
200
|
+
* import * as RefSubject from "@typed/fx/RefSubject"
|
|
201
|
+
* import { Fx } from "@typed/fx"
|
|
202
|
+
*
|
|
203
|
+
* // Create a RefSubject with an initial value
|
|
204
|
+
* const program = Effect.gen(function* () {
|
|
205
|
+
* const count = yield* RefSubject.make(0)
|
|
206
|
+
*
|
|
207
|
+
* // Get the current value
|
|
208
|
+
* const current = yield* count
|
|
209
|
+
* console.log(current) // 0
|
|
210
|
+
*
|
|
211
|
+
* // Update the value
|
|
212
|
+
* yield* RefSubject.set(count, 5)
|
|
213
|
+
* const updated = yield* count
|
|
214
|
+
* console.log(updated) // 5
|
|
215
|
+
*
|
|
216
|
+
* // Use as an Fx to observe changes
|
|
217
|
+
* yield* Fx.observe(
|
|
218
|
+
* count,
|
|
219
|
+
* (value) => Effect.sync(() => console.log("Count changed:", value))
|
|
220
|
+
* )
|
|
221
|
+
*
|
|
222
|
+
* // Increment
|
|
223
|
+
* yield* RefSubject.increment(count)
|
|
224
|
+
* // Output: "Count changed: 6"
|
|
225
|
+
* })
|
|
226
|
+
* ```
|
|
227
|
+
*
|
|
228
|
+
* @since 1.0.0
|
|
229
|
+
* @category models
|
|
230
|
+
*/
|
|
231
|
+
export interface RefSubject<A, E = never, R = never>
|
|
232
|
+
extends Computed<A, E, R>, Subject.Subject<A, E, R> {
|
|
233
|
+
readonly [RefSubjectTypeId]: RefSubjectTypeId;
|
|
234
|
+
|
|
235
|
+
/**
|
|
236
|
+
* Runs an effect that can modify the RefSubject transactionally.
|
|
237
|
+
* All operations within the transaction are atomic and serialized.
|
|
238
|
+
*
|
|
239
|
+
* @example
|
|
240
|
+
* ```ts
|
|
241
|
+
* import { Effect } from "effect"
|
|
242
|
+
* import * as RefSubject from "@typed/fx/RefSubject"
|
|
243
|
+
*
|
|
244
|
+
* const program = Effect.gen(function* () {
|
|
245
|
+
* const balance = yield* RefSubject.make(100)
|
|
246
|
+
*
|
|
247
|
+
* // Transfer money atomically
|
|
248
|
+
* yield* balance.updates((ref) =>
|
|
249
|
+
* Effect.gen(function* () {
|
|
250
|
+
* const current = yield* ref.get
|
|
251
|
+
* if (current >= 50) {
|
|
252
|
+
* yield* ref.set(current - 50)
|
|
253
|
+
* return "Transfer successful"
|
|
254
|
+
* }
|
|
255
|
+
* return "Insufficient funds"
|
|
256
|
+
* })
|
|
257
|
+
* )
|
|
258
|
+
* })
|
|
259
|
+
* ```
|
|
260
|
+
*/
|
|
261
|
+
readonly updates: <B, E2, R2>(
|
|
262
|
+
f: (ref: GetSetDelete<A, E, R>) => Effect.Effect<B, E2, R2>,
|
|
263
|
+
) => Effect.Effect<B, E | E2, R | R2>;
|
|
264
|
+
|
|
265
|
+
/**
|
|
266
|
+
* Interrupts the RefSubject, stopping all subscriptions and cleaning up resources.
|
|
267
|
+
*
|
|
268
|
+
* @example
|
|
269
|
+
* ```ts
|
|
270
|
+
* import { Effect } from "effect"
|
|
271
|
+
* import * as RefSubject from "@typed/fx/RefSubject"
|
|
272
|
+
*
|
|
273
|
+
* const program = Effect.gen(function* () {
|
|
274
|
+
* const ref = yield* RefSubject.make(0)
|
|
275
|
+
*
|
|
276
|
+
* // Later, clean up
|
|
277
|
+
* yield* ref.interrupt
|
|
278
|
+
* })
|
|
279
|
+
* ```
|
|
280
|
+
*/
|
|
281
|
+
readonly interrupt: Effect.Effect<void, never, R>;
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
export declare namespace RefSubject {
|
|
285
|
+
export type Any =
|
|
286
|
+
| RefSubject<any, any, any>
|
|
287
|
+
| RefSubject<any, any>
|
|
288
|
+
| RefSubject<any, never, any>
|
|
289
|
+
| RefSubject<any>;
|
|
290
|
+
|
|
291
|
+
export interface Service<Self, Id extends string, A, E> extends RefSubject<A, E, Self> {
|
|
292
|
+
readonly id: Id;
|
|
293
|
+
|
|
294
|
+
readonly service: ServiceMap.Service<Self, RefSubject<A, E>>;
|
|
295
|
+
|
|
296
|
+
readonly make: <R = never>(
|
|
297
|
+
value: A | Effect.Effect<A, E, R> | Fx<A, E, R>,
|
|
298
|
+
options?: RefSubjectOptions<A> & { readonly skip?: number; readonly take?: number },
|
|
299
|
+
) => Layer.Layer<Self, never, Exclude<R, Scope.Scope>>;
|
|
300
|
+
|
|
301
|
+
readonly layer: <E2, R2>(
|
|
302
|
+
make: Effect.Effect<RefSubject<A, E>, E2, R2 | Scope.Scope>,
|
|
303
|
+
) => Layer.Layer<Self, E2, Exclude<R2, Scope.Scope>>;
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
export interface Class<Self, Id extends string, A, E> extends RefSubject.Service<Self, Id, A, E> {
|
|
307
|
+
new (): RefSubject.Service<Self, Id, A, E>;
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
export const CurrentComputedBehavior = ServiceMap.Reference("@typed/fx/CurrentComputedBehavior", {
|
|
311
|
+
defaultValue: (): "one" | "multiple" => "multiple",
|
|
312
|
+
});
|
|
313
|
+
|
|
314
|
+
const checkIsMultiple = (
|
|
315
|
+
ctx: ServiceMap.ServiceMap<any>,
|
|
316
|
+
): ctx is ServiceMap.ServiceMap<"multiple"> =>
|
|
317
|
+
ServiceMap.getReferenceUnsafe(ctx, CurrentComputedBehavior) === "multiple";
|
|
318
|
+
|
|
319
|
+
class ComputedImpl<R0, E0, A, E, R, E2, R2, C, E3, R3>
|
|
320
|
+
extends Versioned.VersionedTransform<
|
|
321
|
+
R0,
|
|
322
|
+
E0,
|
|
323
|
+
A,
|
|
324
|
+
E,
|
|
325
|
+
R,
|
|
326
|
+
A,
|
|
327
|
+
E2,
|
|
328
|
+
R2,
|
|
329
|
+
C,
|
|
330
|
+
E0 | E | E2 | E3,
|
|
331
|
+
R0 | Exclude<R, Scope.Scope> | R2 | R3 | Scope.Scope,
|
|
332
|
+
C,
|
|
333
|
+
E0 | E | E2 | E3,
|
|
334
|
+
R0 | Exclude<R, Scope.Scope> | R2 | R3
|
|
335
|
+
>
|
|
336
|
+
implements Computed<C, E0 | E | E2 | E3, R0 | Exclude<R, Scope.Scope> | R2 | R3>
|
|
337
|
+
{
|
|
338
|
+
readonly [ComputedTypeId]: ComputedTypeId = ComputedTypeId;
|
|
339
|
+
private _computed: Fx<C, E0 | E | E2 | E3, R0 | R | Scope.Scope | R2 | R3>;
|
|
340
|
+
|
|
341
|
+
override input: Versioned.Versioned<R0, E0, A, E, R, A, E2, R2>;
|
|
342
|
+
readonly f: (a: A) => Effect.Effect<C, E3, R3>;
|
|
343
|
+
|
|
344
|
+
constructor(
|
|
345
|
+
input: Versioned.Versioned<R0, E0, A, E, R, A, E2, R2>,
|
|
346
|
+
f: (a: A) => Effect.Effect<C, E3, R3>,
|
|
347
|
+
) {
|
|
348
|
+
super(input, (fx) => fxMapEffect(fx, f) as any, Effect.flatMap(f));
|
|
349
|
+
|
|
350
|
+
this.input = input;
|
|
351
|
+
this.f = f;
|
|
352
|
+
|
|
353
|
+
this._computed = Subject.hold(
|
|
354
|
+
unwrap(
|
|
355
|
+
Effect.map(Effect.services(), (ctx) => {
|
|
356
|
+
if (checkIsMultiple(ctx)) {
|
|
357
|
+
return fromYieldable(input).pipe(
|
|
358
|
+
continueWith(() => input),
|
|
359
|
+
skipRepeats,
|
|
360
|
+
fxMapEffect(f),
|
|
361
|
+
);
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
return fxFromEffect(Effect.flatMap(input.asEffect(), f));
|
|
365
|
+
}),
|
|
366
|
+
),
|
|
367
|
+
);
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
override run<RSink>(sink: Sink.Sink<C, E0 | E | E2 | E3, RSink>) {
|
|
371
|
+
return this._computed.run(sink) as any;
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
export function makeComputed<R0, E0, A, E, R, E2, R2, C, E3, R3>(
|
|
376
|
+
input: Versioned.Versioned<R0, E0, A, E, R, A, E2, R2>,
|
|
377
|
+
f: (a: A) => Effect.Effect<C, E3, R3>,
|
|
378
|
+
): Computed<C, E0 | E | E2 | E3, R0 | R2 | R3 | Exclude<R, Scope.Scope>> {
|
|
379
|
+
return new ComputedImpl(input, f);
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
export function makeFiltered<R0, E0, A, E, R, E2, R2, C, E3, R3>(
|
|
383
|
+
input: Versioned.Versioned<R0, E0, A, E, R, A, E2, R2>,
|
|
384
|
+
f: (a: A) => Effect.Effect<Option.Option<C>, E3, R3>,
|
|
385
|
+
): Filtered<C, E0 | E | E2 | E3, R0 | Exclude<R, Scope.Scope> | R2 | R3> {
|
|
386
|
+
return new FilteredImpl(input, f);
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
class FilteredImpl<R0, E0, A, E, R, E2, R2, C, E3, R3>
|
|
390
|
+
extends Versioned.VersionedTransform<
|
|
391
|
+
R0,
|
|
392
|
+
E0,
|
|
393
|
+
A,
|
|
394
|
+
E,
|
|
395
|
+
R,
|
|
396
|
+
A,
|
|
397
|
+
E2,
|
|
398
|
+
R2,
|
|
399
|
+
C,
|
|
400
|
+
E0 | E | E2 | E3,
|
|
401
|
+
R0 | Exclude<R, Scope.Scope> | R2 | R3 | Scope.Scope,
|
|
402
|
+
C,
|
|
403
|
+
E0 | E | E2 | E3 | Cause.NoSuchElementError,
|
|
404
|
+
R0 | Exclude<R, Scope.Scope> | R2 | R3
|
|
405
|
+
>
|
|
406
|
+
implements Filtered<C, E0 | E | E2 | E3, R0 | Exclude<R, Scope.Scope> | R2 | R3>
|
|
407
|
+
{
|
|
408
|
+
readonly [FilteredTypeId]: FilteredTypeId = FilteredTypeId;
|
|
409
|
+
private _computed: Fx<C, E0 | E | E2 | E3, R0 | R | Scope.Scope | R2 | R3>;
|
|
410
|
+
|
|
411
|
+
override input: Versioned.Versioned<R0, E0, A, E, R, A, E2, R2>;
|
|
412
|
+
readonly f: (a: A) => Effect.Effect<Option.Option<C>, E3, R3>;
|
|
413
|
+
|
|
414
|
+
constructor(
|
|
415
|
+
input: Versioned.Versioned<R0, E0, A, E, R, A, E2, R2>,
|
|
416
|
+
f: (a: A) => Effect.Effect<Option.Option<C>, E3, R3>,
|
|
417
|
+
) {
|
|
418
|
+
super(
|
|
419
|
+
input,
|
|
420
|
+
(fx) => fxFilterMapEffect(fx, f) as any,
|
|
421
|
+
(effect) => Effect.flatMap(Effect.flatMap(effect, f), (option) => option.asEffect()),
|
|
422
|
+
);
|
|
423
|
+
|
|
424
|
+
this.input = input;
|
|
425
|
+
this.f = f;
|
|
426
|
+
|
|
427
|
+
this._computed = Subject.hold(
|
|
428
|
+
unwrap(
|
|
429
|
+
Effect.map(Effect.services(), (ctx) => {
|
|
430
|
+
if (checkIsMultiple(ctx)) {
|
|
431
|
+
return fromYieldable(input).pipe(
|
|
432
|
+
continueWith(() => input),
|
|
433
|
+
skipRepeats,
|
|
434
|
+
fxFilterMapEffect(f),
|
|
435
|
+
);
|
|
436
|
+
}
|
|
437
|
+
|
|
438
|
+
return fxCompact(fxFromEffect(Effect.flatMap(input.asEffect(), f)));
|
|
439
|
+
}),
|
|
440
|
+
),
|
|
441
|
+
);
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
override run<RSink>(sink: Sink.Sink<C, E0 | E | E2 | E3, RSink>) {
|
|
445
|
+
return this._computed.run(sink) as any;
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
asComputed(): Computed<
|
|
449
|
+
Option.Option<C>,
|
|
450
|
+
E0 | E | E2 | E3,
|
|
451
|
+
R0 | R2 | R3 | Exclude<R, Scope.Scope>
|
|
452
|
+
> {
|
|
453
|
+
return new ComputedImpl(this.input, this.f);
|
|
454
|
+
}
|
|
455
|
+
}
|
|
456
|
+
|
|
457
|
+
class RefSubjectCore<A, E, R, R2> {
|
|
458
|
+
readonly initial: Effect.Effect<A, E, R>;
|
|
459
|
+
readonly subject: Subject.HoldSubjectImpl<A, E>;
|
|
460
|
+
readonly services: ServiceMap.ServiceMap<R2>;
|
|
461
|
+
readonly scope: Scope.Closeable;
|
|
462
|
+
readonly deferredRef: DeferredRef.DeferredRef<E, A>;
|
|
463
|
+
readonly semaphore: Semaphore.Semaphore;
|
|
464
|
+
constructor(
|
|
465
|
+
initial: Effect.Effect<A, E, R>,
|
|
466
|
+
subject: Subject.HoldSubjectImpl<A, E>,
|
|
467
|
+
services: ServiceMap.ServiceMap<R2>,
|
|
468
|
+
scope: Scope.Closeable,
|
|
469
|
+
deferredRef: DeferredRef.DeferredRef<E, A>,
|
|
470
|
+
semaphore: Semaphore.Semaphore,
|
|
471
|
+
) {
|
|
472
|
+
this.initial = initial;
|
|
473
|
+
this.subject = subject;
|
|
474
|
+
this.services = services;
|
|
475
|
+
this.scope = scope;
|
|
476
|
+
this.deferredRef = deferredRef;
|
|
477
|
+
this.semaphore = semaphore;
|
|
478
|
+
}
|
|
479
|
+
|
|
480
|
+
public _fiber: Fiber.Fiber<A, E> | undefined = undefined;
|
|
481
|
+
}
|
|
482
|
+
|
|
483
|
+
export interface RefSubjectOptions<A> {
|
|
484
|
+
readonly eq?: Equivalence<A>;
|
|
485
|
+
}
|
|
486
|
+
|
|
487
|
+
function getSetDelete<A, E, R, R2>(
|
|
488
|
+
ref: RefSubjectCore<A, E, R, R2>,
|
|
489
|
+
): GetSetDelete<A, E, Exclude<R, R2>> {
|
|
490
|
+
return {
|
|
491
|
+
get: getOrInitializeCore(ref, false),
|
|
492
|
+
set: (a) => setCore(ref, a),
|
|
493
|
+
delete: deleteCore(ref),
|
|
494
|
+
};
|
|
495
|
+
}
|
|
496
|
+
class RefSubjectImpl<A, E, R, R2>
|
|
497
|
+
extends YieldableFx<A, E, Exclude<R, R2> | Scope.Scope, A, E, Exclude<R, R2>>
|
|
498
|
+
implements RefSubject<A, E, Exclude<R, R2>>
|
|
499
|
+
{
|
|
500
|
+
readonly [ComputedTypeId]: ComputedTypeId = ComputedTypeId;
|
|
501
|
+
readonly [RefSubjectTypeId]: RefSubjectTypeId = RefSubjectTypeId;
|
|
502
|
+
|
|
503
|
+
readonly version: Effect.Effect<number>;
|
|
504
|
+
readonly interrupt: Effect.Effect<void, never, Exclude<R, R2>>;
|
|
505
|
+
readonly subscriberCount: Effect.Effect<number, never, Exclude<R, R2>>;
|
|
506
|
+
|
|
507
|
+
readonly getSetDelete: GetSetDelete<A, E, Exclude<R, R2>>;
|
|
508
|
+
|
|
509
|
+
readonly core: RefSubjectCore<A, E, R, R2>;
|
|
510
|
+
|
|
511
|
+
constructor(core: RefSubjectCore<A, E, R, R2>) {
|
|
512
|
+
super();
|
|
513
|
+
|
|
514
|
+
this.core = core;
|
|
515
|
+
this.version = Effect.sync(() => core.deferredRef.version);
|
|
516
|
+
this.interrupt = Effect.provide(interruptCore(core), core.services);
|
|
517
|
+
this.subscriberCount = Effect.provide(core.subject.subscriberCount, core.services);
|
|
518
|
+
this.getSetDelete = getSetDelete(core);
|
|
519
|
+
|
|
520
|
+
this.updates = this.updates.bind(this);
|
|
521
|
+
this.onSuccess = this.onSuccess.bind(this);
|
|
522
|
+
this.onFailure = this.onFailure.bind(this);
|
|
523
|
+
}
|
|
524
|
+
|
|
525
|
+
run<R3>(
|
|
526
|
+
sink: Sink.Sink<A, E, R3>,
|
|
527
|
+
): Effect.Effect<unknown, never, Exclude<R, R2> | R3 | Scope.Scope> {
|
|
528
|
+
return Effect.matchCauseEffect(getOrInitializeCore(this.core, true), {
|
|
529
|
+
onFailure: (cause) => sink.onFailure(cause),
|
|
530
|
+
onSuccess: () => Effect.provide(this.core.subject.run(sink), this.core.services),
|
|
531
|
+
});
|
|
532
|
+
}
|
|
533
|
+
|
|
534
|
+
updates<R3, E3, B>(run: (ref: GetSetDelete<A, E, Exclude<R, R2>>) => Effect.Effect<B, E3, R3>) {
|
|
535
|
+
return this.core.semaphore.withPermits(1)(run(this.getSetDelete));
|
|
536
|
+
}
|
|
537
|
+
|
|
538
|
+
onSuccess(value: A): Effect.Effect<unknown, never, Exclude<R, R2>> {
|
|
539
|
+
return setCore(this.core, value);
|
|
540
|
+
}
|
|
541
|
+
|
|
542
|
+
onFailure(cause: Cause.Cause<E>): Effect.Effect<unknown, never, Exclude<R, R2>> {
|
|
543
|
+
return onFailureCore(this.core, cause);
|
|
544
|
+
}
|
|
545
|
+
|
|
546
|
+
toEffect(): Effect.Effect<A, E, Exclude<R, R2>> {
|
|
547
|
+
return getOrInitializeCore(this.core, true);
|
|
548
|
+
}
|
|
549
|
+
}
|
|
550
|
+
|
|
551
|
+
/**
|
|
552
|
+
* Creates a new `RefSubject` from a value, `Effect`, or `Fx`.
|
|
553
|
+
*
|
|
554
|
+
* @example
|
|
555
|
+
* ```ts
|
|
556
|
+
* import { Effect } from "effect"
|
|
557
|
+
* import * as RefSubject from "@typed/fx/RefSubject"
|
|
558
|
+
* import { Fx } from "@typed/fx"
|
|
559
|
+
*
|
|
560
|
+
* // From a plain value
|
|
561
|
+
* const program1 = Effect.gen(function* () {
|
|
562
|
+
* const ref = yield* RefSubject.make(42)
|
|
563
|
+
* const value = yield* ref
|
|
564
|
+
* console.log(value) // 42
|
|
565
|
+
* })
|
|
566
|
+
*
|
|
567
|
+
* // From an Effect
|
|
568
|
+
* const program2 = Effect.gen(function* () {
|
|
569
|
+
* const ref = yield* RefSubject.make(
|
|
570
|
+
* Effect.succeed("Hello")
|
|
571
|
+
* )
|
|
572
|
+
* const value = yield* ref
|
|
573
|
+
* console.log(value) // "Hello"
|
|
574
|
+
* })
|
|
575
|
+
*
|
|
576
|
+
* // From an Fx (tracks the latest value)
|
|
577
|
+
* const program3 = Effect.gen(function* () {
|
|
578
|
+
* const ref = yield* RefSubject.make(
|
|
579
|
+
* Fx.fromIterable([1, 2, 3])
|
|
580
|
+
* )
|
|
581
|
+
* const value = yield* ref
|
|
582
|
+
* console.log(value) // 3 (latest value)
|
|
583
|
+
* })
|
|
584
|
+
* ```
|
|
585
|
+
*
|
|
586
|
+
* @since 1.0.0
|
|
587
|
+
* @category constructors
|
|
588
|
+
*/
|
|
589
|
+
export function make<A, E = never, R = never>(
|
|
590
|
+
effect: A | Effect.Effect<A, E, R> | Stream.Stream<A, E, R> | Fx<A, E, R>,
|
|
591
|
+
options?: RefSubjectOptions<A>,
|
|
592
|
+
): Effect.Effect<RefSubject<A, E>, never, R | Scope.Scope> {
|
|
593
|
+
if (isFx(effect)) {
|
|
594
|
+
return fromFx(effect, options);
|
|
595
|
+
} else if (Effect.isEffect(effect)) {
|
|
596
|
+
return fromEffect(effect, options);
|
|
597
|
+
} else if (Stream.isStream(effect)) {
|
|
598
|
+
return fromStream(effect, options);
|
|
599
|
+
} else {
|
|
600
|
+
return fromEffect<A, E, R>(Effect.succeed(effect), options);
|
|
601
|
+
}
|
|
602
|
+
}
|
|
603
|
+
|
|
604
|
+
/**
|
|
605
|
+
* Creates a `RefSubject` from an `Effect`.
|
|
606
|
+
*
|
|
607
|
+
* @example
|
|
608
|
+
* ```ts
|
|
609
|
+
* import { Effect } from "effect"
|
|
610
|
+
* import * as RefSubject from "@typed/fx/RefSubject"
|
|
611
|
+
*
|
|
612
|
+
* const program = Effect.gen(function* () {
|
|
613
|
+
* const ref = yield* RefSubject.fromEffect(
|
|
614
|
+
* Effect.succeed("Initial value")
|
|
615
|
+
* )
|
|
616
|
+
*
|
|
617
|
+
* const value = yield* ref
|
|
618
|
+
* console.log(value) // "Initial value"
|
|
619
|
+
* })
|
|
620
|
+
* ```
|
|
621
|
+
*
|
|
622
|
+
* @since 1.0.0
|
|
623
|
+
* @category constructors
|
|
624
|
+
*/
|
|
625
|
+
export function fromEffect<A, E, R>(
|
|
626
|
+
effect: Effect.Effect<A, E, R>,
|
|
627
|
+
options?: RefSubjectOptions<A>,
|
|
628
|
+
): Effect.Effect<RefSubject<A, E>, never, R | Scope.Scope> {
|
|
629
|
+
return Effect.map(makeCore(effect, options), (core) => new RefSubjectImpl(core));
|
|
630
|
+
}
|
|
631
|
+
|
|
632
|
+
/**
|
|
633
|
+
* Creates a `RefSubject` from an `Fx`, tracking the latest emitted value.
|
|
634
|
+
*
|
|
635
|
+
* @example
|
|
636
|
+
* ```ts
|
|
637
|
+
* import { Effect } from "effect"
|
|
638
|
+
* import * as RefSubject from "@typed/fx/RefSubject"
|
|
639
|
+
* import { Fx } from "@typed/fx"
|
|
640
|
+
*
|
|
641
|
+
* const program = Effect.gen(function* () {
|
|
642
|
+
* // Create an Fx that emits multiple values
|
|
643
|
+
* const numbers = Fx.fromIterable([1, 2, 3, 4, 5])
|
|
644
|
+
*
|
|
645
|
+
* // Create a RefSubject that tracks the latest value
|
|
646
|
+
* const ref = yield* RefSubject.fromFx(numbers)
|
|
647
|
+
*
|
|
648
|
+
* // Get the latest value
|
|
649
|
+
* const latest = yield* ref
|
|
650
|
+
* console.log(latest) // 5
|
|
651
|
+
* })
|
|
652
|
+
* ```
|
|
653
|
+
*
|
|
654
|
+
* @since 1.0.0
|
|
655
|
+
* @category constructors
|
|
656
|
+
*/
|
|
657
|
+
export function fromFx<A, E, R>(
|
|
658
|
+
fx: Fx<A, E, R>,
|
|
659
|
+
options?: RefSubjectOptions<A>,
|
|
660
|
+
): Effect.Effect<RefSubject<A, E>, never, R | Scope.Scope> {
|
|
661
|
+
return Effect.gen(function* () {
|
|
662
|
+
const core = yield* makeDeferredCore<A, E, R>(options);
|
|
663
|
+
const ref = new RefSubjectImpl(core);
|
|
664
|
+
yield* Effect.forkIn(
|
|
665
|
+
fx.run(
|
|
666
|
+
Sink.make(
|
|
667
|
+
(cause) => onFailureCore(core, cause),
|
|
668
|
+
(value) => setCore(core, value),
|
|
669
|
+
),
|
|
670
|
+
),
|
|
671
|
+
core.scope,
|
|
672
|
+
{ startImmediately: true },
|
|
673
|
+
);
|
|
674
|
+
return ref;
|
|
675
|
+
});
|
|
676
|
+
}
|
|
677
|
+
|
|
678
|
+
export function fromStream<A, E, R>(
|
|
679
|
+
stream: Stream.Stream<A, E, R>,
|
|
680
|
+
options?: RefSubjectOptions<A>,
|
|
681
|
+
): Effect.Effect<RefSubject<A, E>, never, R | Scope.Scope> {
|
|
682
|
+
return Effect.gen(function* () {
|
|
683
|
+
const core = yield* makeDeferredCore<A, E, R>(options);
|
|
684
|
+
const ref = new RefSubjectImpl(core);
|
|
685
|
+
yield* Effect.forkIn(
|
|
686
|
+
stream.pipe(
|
|
687
|
+
redirectCause(core),
|
|
688
|
+
Stream.runForEach((value) => setCore(core, value)),
|
|
689
|
+
),
|
|
690
|
+
core.scope,
|
|
691
|
+
{ startImmediately: true },
|
|
692
|
+
);
|
|
693
|
+
return ref;
|
|
694
|
+
});
|
|
695
|
+
}
|
|
696
|
+
|
|
697
|
+
/**
|
|
698
|
+
* Creates a `RefSubject` from an `Option` value.
|
|
699
|
+
*
|
|
700
|
+
* @example
|
|
701
|
+
* ```ts
|
|
702
|
+
* import { Effect, Option } from "effect"
|
|
703
|
+
* import * as RefSubject from "@typed/fx/RefSubject"
|
|
704
|
+
*
|
|
705
|
+
* const program = Effect.gen(function* () {
|
|
706
|
+
* const ref = yield* RefSubject.fromOption(Option.some(42))
|
|
707
|
+
* const value = yield* ref
|
|
708
|
+
* console.log(Option.isSome(value)) // true
|
|
709
|
+
* })
|
|
710
|
+
* ```
|
|
711
|
+
*
|
|
712
|
+
* @since 1.0.0
|
|
713
|
+
* @category constructors
|
|
714
|
+
*/
|
|
715
|
+
export function fromOption<A>(
|
|
716
|
+
option: Option.Option<A>,
|
|
717
|
+
options?: RefSubjectOptions<Option.Option<A>>,
|
|
718
|
+
): Effect.Effect<RefSubject<Option.Option<A>>, never, Scope.Scope> {
|
|
719
|
+
return make(option, options);
|
|
720
|
+
}
|
|
721
|
+
|
|
722
|
+
/**
|
|
723
|
+
* Creates a `RefSubject` from a nullable value (null/undefined become `Option.none()`).
|
|
724
|
+
*
|
|
725
|
+
* @example
|
|
726
|
+
* ```ts
|
|
727
|
+
* import { Effect, Option } from "effect"
|
|
728
|
+
* import * as RefSubject from "@typed/fx/RefSubject"
|
|
729
|
+
*
|
|
730
|
+
* const program = Effect.gen(function* () {
|
|
731
|
+
* const ref = yield* RefSubject.fromNullable("hello")
|
|
732
|
+
* const value = yield* ref
|
|
733
|
+
* console.log(Option.isSome(value)) // true
|
|
734
|
+
*
|
|
735
|
+
* const empty = yield* RefSubject.fromNullable(null)
|
|
736
|
+
* const none = yield* empty
|
|
737
|
+
* console.log(Option.isNone(none)) // true
|
|
738
|
+
* })
|
|
739
|
+
* ```
|
|
740
|
+
*
|
|
741
|
+
* @since 1.0.0
|
|
742
|
+
* @category constructors
|
|
743
|
+
*/
|
|
744
|
+
function optionFromNullable<A>(value: A | null | undefined): Option.Option<NonNullable<A>> {
|
|
745
|
+
return value === null || value === undefined
|
|
746
|
+
? Option.none()
|
|
747
|
+
: Option.some(value as NonNullable<A>);
|
|
748
|
+
}
|
|
749
|
+
|
|
750
|
+
export function fromNullable<A>(
|
|
751
|
+
value: A | null | undefined,
|
|
752
|
+
options?: RefSubjectOptions<Option.Option<NonNullable<A>>>,
|
|
753
|
+
): Effect.Effect<RefSubject<Option.Option<NonNullable<A>>>, never, Scope.Scope> {
|
|
754
|
+
return make(optionFromNullable(value), options);
|
|
755
|
+
}
|
|
756
|
+
|
|
757
|
+
function redirectCause<A, E, R>(core: RefSubjectCore<A, E, R, R | Scope.Scope>) {
|
|
758
|
+
return Stream.catchCause((cause: Cause.Cause<E>) =>
|
|
759
|
+
Stream.unwrap(Effect.as(onFailureCore(core, cause), Stream.empty)),
|
|
760
|
+
);
|
|
761
|
+
}
|
|
762
|
+
|
|
763
|
+
function makeCore<A, E, R>(
|
|
764
|
+
initial: Effect.Effect<A, E, R>,
|
|
765
|
+
options?: RefSubjectOptions<A>,
|
|
766
|
+
deferredRef?: DeferredRef.DeferredRef<E, A>,
|
|
767
|
+
) {
|
|
768
|
+
return Effect.gen(function* () {
|
|
769
|
+
const services = yield* Effect.services<R | Scope.Scope>();
|
|
770
|
+
const scope = yield* Scope.fork(ServiceMap.get(services, Scope.Scope));
|
|
771
|
+
const id = yield* Effect.withFiber((fiber) => Effect.succeed(fiber.id));
|
|
772
|
+
const subject = new Subject.HoldSubjectImpl<A, E>();
|
|
773
|
+
const core = new RefSubjectCore(
|
|
774
|
+
initial,
|
|
775
|
+
subject,
|
|
776
|
+
services,
|
|
777
|
+
scope,
|
|
778
|
+
deferredRef ??
|
|
779
|
+
DeferredRef.unsafeMake(id, getExitEquivalence(options?.eq ?? equals), subject.lastValue),
|
|
780
|
+
Semaphore.makeUnsafe(1),
|
|
781
|
+
);
|
|
782
|
+
yield* Scope.addFinalizer(scope, core.subject.interrupt);
|
|
783
|
+
return core;
|
|
784
|
+
});
|
|
785
|
+
}
|
|
786
|
+
|
|
787
|
+
function makeDeferredCore<A, E = never, R = never>(options?: RefSubjectOptions<A>) {
|
|
788
|
+
return Effect.gen(function* () {
|
|
789
|
+
const deferredRef = yield* DeferredRef.make<E, A>(getExitEquivalence(options?.eq ?? equals));
|
|
790
|
+
return yield* makeCore<A, E, R>(deferredRef.asEffect(), options, deferredRef);
|
|
791
|
+
});
|
|
792
|
+
}
|
|
793
|
+
|
|
794
|
+
function getOrInitializeCore<A, E, R, R2>(
|
|
795
|
+
core: RefSubjectCore<A, E, R, R2>,
|
|
796
|
+
lockInitialize: boolean,
|
|
797
|
+
): Effect.Effect<A, E, Exclude<R, R2>> {
|
|
798
|
+
return Effect.suspend(() => {
|
|
799
|
+
if (core._fiber === undefined && Option.isNone(MutableRef.get(core.deferredRef.current))) {
|
|
800
|
+
return initializeCoreAndTap(core, lockInitialize);
|
|
801
|
+
} else {
|
|
802
|
+
return core.deferredRef.asEffect();
|
|
803
|
+
}
|
|
804
|
+
});
|
|
805
|
+
}
|
|
806
|
+
|
|
807
|
+
function initializeCoreEffect<A, E, R, R2>(
|
|
808
|
+
core: RefSubjectCore<A, E, R, R2>,
|
|
809
|
+
lock: boolean,
|
|
810
|
+
): Effect.Effect<Fiber.Fiber<A, E>, never, Exclude<R, R2>> {
|
|
811
|
+
const initialize = Effect.onExit(Effect.provide(core.initial, core.services), (exit) =>
|
|
812
|
+
Effect.sync(() => {
|
|
813
|
+
core._fiber = undefined;
|
|
814
|
+
core.deferredRef.done(exit);
|
|
815
|
+
}),
|
|
816
|
+
);
|
|
817
|
+
|
|
818
|
+
return Effect.flatMap(
|
|
819
|
+
Effect.forkIn(lock ? core.semaphore.withPermits(1)(initialize) : initialize, core.scope),
|
|
820
|
+
(fiber) => Effect.sync(() => (core._fiber = fiber)),
|
|
821
|
+
);
|
|
822
|
+
}
|
|
823
|
+
|
|
824
|
+
function initializeCoreAndTap<A, E, R, R2>(
|
|
825
|
+
core: RefSubjectCore<A, E, R, R2>,
|
|
826
|
+
lock: boolean,
|
|
827
|
+
): Effect.Effect<A, E, Exclude<R, R2>> {
|
|
828
|
+
return Effect.flatMapEager(initializeCoreEffect(core, lock), () =>
|
|
829
|
+
tapEventCore(core, core.deferredRef.asEffect()),
|
|
830
|
+
);
|
|
831
|
+
}
|
|
832
|
+
|
|
833
|
+
function setCore<A, E, R, R2>(
|
|
834
|
+
core: RefSubjectCore<A, E, R, R2>,
|
|
835
|
+
a: A,
|
|
836
|
+
): Effect.Effect<A, never, Exclude<R, R2>> {
|
|
837
|
+
return Effect.suspend(() => {
|
|
838
|
+
const exit = Exit.succeed(a);
|
|
839
|
+
|
|
840
|
+
if (core.deferredRef.done(exit)) {
|
|
841
|
+
// If the value changed, send an event
|
|
842
|
+
return Effect.as(sendEvent(core, exit), a);
|
|
843
|
+
} else {
|
|
844
|
+
// Otherwise, just return the current value
|
|
845
|
+
return Effect.succeed(a);
|
|
846
|
+
}
|
|
847
|
+
});
|
|
848
|
+
}
|
|
849
|
+
|
|
850
|
+
function onFailureCore<A, E, R, R2>(core: RefSubjectCore<A, E, R, R2>, cause: Cause.Cause<E>) {
|
|
851
|
+
const exit = Exit.failCause(cause);
|
|
852
|
+
|
|
853
|
+
return Effect.suspend(() => {
|
|
854
|
+
if (core.deferredRef.done(exit)) {
|
|
855
|
+
return sendEvent(core, exit);
|
|
856
|
+
} else {
|
|
857
|
+
return Effect.void;
|
|
858
|
+
}
|
|
859
|
+
});
|
|
860
|
+
}
|
|
861
|
+
|
|
862
|
+
function interruptCore<A, E, R, R2>(
|
|
863
|
+
core: RefSubjectCore<A, E, R, R2>,
|
|
864
|
+
): Effect.Effect<void, never, R> {
|
|
865
|
+
return Effect.withFiber((fiber) => {
|
|
866
|
+
core.deferredRef.reset();
|
|
867
|
+
|
|
868
|
+
const closeScope = Scope.close(core.scope, Exit.interrupt(fiber.id));
|
|
869
|
+
const interruptFiber = core._fiber ? Fiber.interrupt(core._fiber) : Effect.void;
|
|
870
|
+
const interruptSubject = core.subject.interrupt;
|
|
871
|
+
|
|
872
|
+
return Effect.all([closeScope, interruptFiber, interruptSubject], { discard: true });
|
|
873
|
+
});
|
|
874
|
+
}
|
|
875
|
+
|
|
876
|
+
function deleteCore<A, E, R, R2>(
|
|
877
|
+
core: RefSubjectCore<A, E, R, R2>,
|
|
878
|
+
): Effect.Effect<Option.Option<A>, E, Exclude<R, R2>> {
|
|
879
|
+
return Effect.suspend(() => {
|
|
880
|
+
const current = MutableRef.get(core.deferredRef.current);
|
|
881
|
+
core.deferredRef.reset();
|
|
882
|
+
|
|
883
|
+
if (Option.isNone(current)) {
|
|
884
|
+
return Effect.succeed(Option.none());
|
|
885
|
+
}
|
|
886
|
+
|
|
887
|
+
return core.subject.subscriberCount.pipe(
|
|
888
|
+
Effect.flatMap((count: number) =>
|
|
889
|
+
count > 0 && !core._fiber ? initializeCoreEffect(core, false) : Effect.void,
|
|
890
|
+
),
|
|
891
|
+
Effect.flatMap(() => Effect.asSome(current.value)),
|
|
892
|
+
);
|
|
893
|
+
});
|
|
894
|
+
}
|
|
895
|
+
|
|
896
|
+
function tapEventCore<A, E, R, R2, R3>(
|
|
897
|
+
core: RefSubjectCore<A, E, R, R2>,
|
|
898
|
+
effect: Effect.Effect<A, E, R3>,
|
|
899
|
+
) {
|
|
900
|
+
return effect.pipe(Effect.onExit((exit) => sendEvent(core, exit)));
|
|
901
|
+
}
|
|
902
|
+
|
|
903
|
+
function sendEvent<A, E, R, R2>(
|
|
904
|
+
core: RefSubjectCore<A, E, R, R2>,
|
|
905
|
+
exit: Exit.Exit<A, E>,
|
|
906
|
+
): Effect.Effect<unknown, never, Exclude<R, R2>> {
|
|
907
|
+
if (Exit.isSuccess(exit)) {
|
|
908
|
+
return core.subject.onSuccess(exit.value);
|
|
909
|
+
} else {
|
|
910
|
+
return core.subject.onFailure(exit.cause);
|
|
911
|
+
}
|
|
912
|
+
}
|
|
913
|
+
|
|
914
|
+
/**
|
|
915
|
+
* Sets the value of a `RefSubject`.
|
|
916
|
+
*
|
|
917
|
+
* @example
|
|
918
|
+
* ```ts
|
|
919
|
+
* import { Effect } from "effect"
|
|
920
|
+
* import * as RefSubject from "@typed/fx/RefSubject"
|
|
921
|
+
*
|
|
922
|
+
* const program = Effect.gen(function* () {
|
|
923
|
+
* const count = yield* RefSubject.make(0)
|
|
924
|
+
*
|
|
925
|
+
* // Set the value
|
|
926
|
+
* yield* RefSubject.set(count, 10)
|
|
927
|
+
* const value = yield* count
|
|
928
|
+
* console.log(value) // 10
|
|
929
|
+
*
|
|
930
|
+
* // Can also use pipe syntax
|
|
931
|
+
* yield* count.pipe(RefSubject.set(20))
|
|
932
|
+
* const newValue = yield* count
|
|
933
|
+
* console.log(newValue) // 20
|
|
934
|
+
* })
|
|
935
|
+
* ```
|
|
936
|
+
*
|
|
937
|
+
* @since 1.0.0
|
|
938
|
+
* @category combinators
|
|
939
|
+
*/
|
|
940
|
+
export const set: {
|
|
941
|
+
<A>(value: A): <E, R>(ref: RefSubject<A, E, R>) => Effect.Effect<A, E, R>;
|
|
942
|
+
<A, E, R>(ref: RefSubject<A, E, R>, a: A): Effect.Effect<A, E, R>;
|
|
943
|
+
} = dual(2, function set<A, E, R>(ref: RefSubject<A, E, R>, a: A): Effect.Effect<A, E, R> {
|
|
944
|
+
return ref.updates((ref) => ref.set(a));
|
|
945
|
+
});
|
|
946
|
+
|
|
947
|
+
/**
|
|
948
|
+
* Resets a `RefSubject` to its initial value, returning the previous value if it existed.
|
|
949
|
+
*
|
|
950
|
+
* @example
|
|
951
|
+
* ```ts
|
|
952
|
+
* import { Effect, Option } from "effect"
|
|
953
|
+
* import * as RefSubject from "@typed/fx/RefSubject"
|
|
954
|
+
*
|
|
955
|
+
* const program = Effect.gen(function* () {
|
|
956
|
+
* const count = yield* RefSubject.make(0)
|
|
957
|
+
*
|
|
958
|
+
* yield* RefSubject.set(count, 5)
|
|
959
|
+
* const before = yield* count
|
|
960
|
+
* console.log(before) // 5
|
|
961
|
+
*
|
|
962
|
+
* // Reset to initial value
|
|
963
|
+
* const previous = yield* RefSubject.reset(count)
|
|
964
|
+
* console.log(Option.isSome(previous)) // true
|
|
965
|
+
* console.log(previous.value) // 5
|
|
966
|
+
*
|
|
967
|
+
* const after = yield* count
|
|
968
|
+
* console.log(after) // 0
|
|
969
|
+
* })
|
|
970
|
+
* ```
|
|
971
|
+
*
|
|
972
|
+
* @since 1.0.0
|
|
973
|
+
* @category combinators
|
|
974
|
+
*/
|
|
975
|
+
export function reset<A, E, R>(ref: RefSubject<A, E, R>): Effect.Effect<Option.Option<A>, E, R> {
|
|
976
|
+
return ref.updates((ref) => ref.delete);
|
|
977
|
+
}
|
|
978
|
+
|
|
979
|
+
export {
|
|
980
|
+
/**
|
|
981
|
+
* Deletes the current value of a `RefSubject`, resetting it to its initial state.
|
|
982
|
+
*
|
|
983
|
+
* @example
|
|
984
|
+
* ```ts
|
|
985
|
+
* import { Effect, Option } from "effect"
|
|
986
|
+
* import * as RefSubject from "@typed/fx/RefSubject"
|
|
987
|
+
*
|
|
988
|
+
* const program = Effect.gen(function* () {
|
|
989
|
+
* const ref = yield* RefSubject.make(10)
|
|
990
|
+
* yield* RefSubject.set(ref, 20)
|
|
991
|
+
*
|
|
992
|
+
* // Delete the current value
|
|
993
|
+
* const deleted = yield* RefSubject.delete(ref)
|
|
994
|
+
* console.log(Option.isSome(deleted)) // true
|
|
995
|
+
* console.log(deleted.value) // 20
|
|
996
|
+
*
|
|
997
|
+
* // Value is reset to initial
|
|
998
|
+
* const current = yield* ref
|
|
999
|
+
* console.log(current) // 10
|
|
1000
|
+
* })
|
|
1001
|
+
* ```
|
|
1002
|
+
*
|
|
1003
|
+
* @since 1.20.0
|
|
1004
|
+
* @category combinators
|
|
1005
|
+
*/
|
|
1006
|
+
reset as delete,
|
|
1007
|
+
};
|
|
1008
|
+
|
|
1009
|
+
/**
|
|
1010
|
+
* Updates a `RefSubject` using an `Effect`ful function.
|
|
1011
|
+
*
|
|
1012
|
+
* @example
|
|
1013
|
+
* ```ts
|
|
1014
|
+
* import { Effect } from "effect"
|
|
1015
|
+
* import * as RefSubject from "@typed/fx/RefSubject"
|
|
1016
|
+
*
|
|
1017
|
+
* const program = Effect.gen(function* () {
|
|
1018
|
+
* const count = yield* RefSubject.make(5)
|
|
1019
|
+
*
|
|
1020
|
+
* // Update with an async operation
|
|
1021
|
+
* yield* RefSubject.updateEffect(count, (value) =>
|
|
1022
|
+
* Effect.succeed(value * 2)
|
|
1023
|
+
* )
|
|
1024
|
+
*
|
|
1025
|
+
* const result = yield* count
|
|
1026
|
+
* console.log(result) // 10
|
|
1027
|
+
* })
|
|
1028
|
+
* ```
|
|
1029
|
+
*
|
|
1030
|
+
* @since 1.0.0
|
|
1031
|
+
* @category combinators
|
|
1032
|
+
*/
|
|
1033
|
+
export const updateEffect: {
|
|
1034
|
+
<A, E2, R2>(
|
|
1035
|
+
f: (value: A) => Effect.Effect<A, E2, R2>,
|
|
1036
|
+
): <E, R>(ref: RefSubject<A, E, R>) => Effect.Effect<A, E | E2, R | R2>;
|
|
1037
|
+
<A, E, R, E2, R2>(
|
|
1038
|
+
ref: RefSubject<A, E, R>,
|
|
1039
|
+
f: (value: A) => Effect.Effect<A, E2, R2>,
|
|
1040
|
+
): Effect.Effect<A, E | E2, R | R2>;
|
|
1041
|
+
} = dual(2, function updateEffect<
|
|
1042
|
+
A,
|
|
1043
|
+
E,
|
|
1044
|
+
R,
|
|
1045
|
+
E2,
|
|
1046
|
+
R2,
|
|
1047
|
+
>(ref: RefSubject<A, E, R>, f: (value: A) => Effect.Effect<A, E2, R2>) {
|
|
1048
|
+
return ref.updates((ref) => Effect.flatMap(Effect.flatMap(ref.get, f), ref.set));
|
|
1049
|
+
});
|
|
1050
|
+
|
|
1051
|
+
/**
|
|
1052
|
+
* Updates a `RefSubject` using a pure function.
|
|
1053
|
+
*
|
|
1054
|
+
* @example
|
|
1055
|
+
* ```ts
|
|
1056
|
+
* import { Effect } from "effect"
|
|
1057
|
+
* import * as RefSubject from "@typed/fx/RefSubject"
|
|
1058
|
+
*
|
|
1059
|
+
* const program = Effect.gen(function* () {
|
|
1060
|
+
* const count = yield* RefSubject.make(5)
|
|
1061
|
+
*
|
|
1062
|
+
* // Increment by 1
|
|
1063
|
+
* yield* RefSubject.update(count, (n) => n + 1)
|
|
1064
|
+
* const value = yield* count
|
|
1065
|
+
* console.log(value) // 6
|
|
1066
|
+
*
|
|
1067
|
+
* // Can also use pipe syntax
|
|
1068
|
+
* yield* count.pipe(RefSubject.update((n) => n * 2))
|
|
1069
|
+
* const doubled = yield* count
|
|
1070
|
+
* console.log(doubled) // 12
|
|
1071
|
+
* })
|
|
1072
|
+
* ```
|
|
1073
|
+
*
|
|
1074
|
+
* @since 1.0.0
|
|
1075
|
+
* @category combinators
|
|
1076
|
+
*/
|
|
1077
|
+
export const update: {
|
|
1078
|
+
<A>(f: (value: A) => A): <E, R>(ref: RefSubject<A, E, R>) => Effect.Effect<A, E, R>;
|
|
1079
|
+
<A, E, R>(ref: RefSubject<A, E, R>, f: (value: A) => A): Effect.Effect<A, E, R>;
|
|
1080
|
+
} = dual(2, function update<A, E, R>(ref: RefSubject<A, E, R>, f: (value: A) => A) {
|
|
1081
|
+
return updateEffect(ref, (value) => Effect.succeed(f(value)));
|
|
1082
|
+
});
|
|
1083
|
+
|
|
1084
|
+
/**
|
|
1085
|
+
* Modifies a `RefSubject` using an `Effect`ful function that returns both a result and a new value.
|
|
1086
|
+
*
|
|
1087
|
+
* @example
|
|
1088
|
+
* ```ts
|
|
1089
|
+
* import { Effect } from "effect"
|
|
1090
|
+
* import * as RefSubject from "@typed/fx/RefSubject"
|
|
1091
|
+
*
|
|
1092
|
+
* const program = Effect.gen(function* () {
|
|
1093
|
+
* const count = yield* RefSubject.make(5)
|
|
1094
|
+
*
|
|
1095
|
+
* // Get the old value and set a new one, returning the old value
|
|
1096
|
+
* const oldValue = yield* RefSubject.modifyEffect(count, (value) =>
|
|
1097
|
+
* Effect.succeed([value, value + 10] as const)
|
|
1098
|
+
* )
|
|
1099
|
+
*
|
|
1100
|
+
* console.log(oldValue) // 5
|
|
1101
|
+
* const newValue = yield* count
|
|
1102
|
+
* console.log(newValue) // 15
|
|
1103
|
+
* })
|
|
1104
|
+
* ```
|
|
1105
|
+
*
|
|
1106
|
+
* @since 1.0.0
|
|
1107
|
+
* @category combinators
|
|
1108
|
+
*/
|
|
1109
|
+
export const modifyEffect: {
|
|
1110
|
+
<A, B, E2, R2>(
|
|
1111
|
+
f: (value: A) => Effect.Effect<readonly [B, A], E2, R2>,
|
|
1112
|
+
): <E, R>(ref: RefSubject<A, E, R>) => Effect.Effect<B, E | E2, R | R2>;
|
|
1113
|
+
<A, E, R, B, E2, R2>(
|
|
1114
|
+
ref: RefSubject<A, E, R>,
|
|
1115
|
+
f: (value: A) => Effect.Effect<readonly [B, A], E2, R2>,
|
|
1116
|
+
): Effect.Effect<B, E | E2, R | R2>;
|
|
1117
|
+
} = dual(2, function modifyEffect<
|
|
1118
|
+
A,
|
|
1119
|
+
E,
|
|
1120
|
+
R,
|
|
1121
|
+
B,
|
|
1122
|
+
E2,
|
|
1123
|
+
R2,
|
|
1124
|
+
>(ref: RefSubject<A, E, R>, f: (value: A) => Effect.Effect<readonly [B, A], E2, R2>) {
|
|
1125
|
+
return ref.updates((ref) =>
|
|
1126
|
+
Effect.flatMap(ref.get, (value) =>
|
|
1127
|
+
Effect.flatMap(f(value), ([b, a]) => Effect.flatMap(ref.set(a), () => Effect.succeed(b))),
|
|
1128
|
+
),
|
|
1129
|
+
);
|
|
1130
|
+
});
|
|
1131
|
+
|
|
1132
|
+
/**
|
|
1133
|
+
* Modifies a `RefSubject` using a pure function that returns both a result and a new value.
|
|
1134
|
+
*
|
|
1135
|
+
* @example
|
|
1136
|
+
* ```ts
|
|
1137
|
+
* import { Effect } from "effect"
|
|
1138
|
+
* import * as RefSubject from "@typed/fx/RefSubject"
|
|
1139
|
+
*
|
|
1140
|
+
* const program = Effect.gen(function* () {
|
|
1141
|
+
* const count = yield* RefSubject.make(5)
|
|
1142
|
+
*
|
|
1143
|
+
* // Get the old value and increment, returning the old value
|
|
1144
|
+
* const oldValue = yield* RefSubject.modify(count, (value) => [value, value + 1] as const)
|
|
1145
|
+
*
|
|
1146
|
+
* console.log(oldValue) // 5
|
|
1147
|
+
* const newValue = yield* count
|
|
1148
|
+
* console.log(newValue) // 6
|
|
1149
|
+
* })
|
|
1150
|
+
* ```
|
|
1151
|
+
*
|
|
1152
|
+
* @since 1.0.0
|
|
1153
|
+
* @category combinators
|
|
1154
|
+
*/
|
|
1155
|
+
export const modify: {
|
|
1156
|
+
<A, B>(
|
|
1157
|
+
f: (value: A) => readonly [B, A],
|
|
1158
|
+
): <E, R>(ref: RefSubject<A, E, R>) => Effect.Effect<B, E, R>;
|
|
1159
|
+
<A, E, R, B>(ref: RefSubject<A, E, R>, f: (value: A) => readonly [B, A]): Effect.Effect<B, E, R>;
|
|
1160
|
+
} = dual(2, function modify<
|
|
1161
|
+
A,
|
|
1162
|
+
E,
|
|
1163
|
+
R,
|
|
1164
|
+
B,
|
|
1165
|
+
>(ref: RefSubject<A, E, R>, f: (value: A) => readonly [B, A]) {
|
|
1166
|
+
return modifyEffect(ref, (value) => Effect.succeed(f(value)));
|
|
1167
|
+
});
|
|
1168
|
+
|
|
1169
|
+
/**
|
|
1170
|
+
* Checks if a value is a `RefSubject`.
|
|
1171
|
+
*
|
|
1172
|
+
* @example
|
|
1173
|
+
* ```ts
|
|
1174
|
+
* import { Effect } from "effect"
|
|
1175
|
+
* import * as RefSubject from "@typed/fx/RefSubject"
|
|
1176
|
+
*
|
|
1177
|
+
* const program = Effect.gen(function* () {
|
|
1178
|
+
* const ref = yield* RefSubject.make(42)
|
|
1179
|
+
* const isRef = RefSubject.isRefSubject(ref)
|
|
1180
|
+
* console.log(isRef) // true
|
|
1181
|
+
*
|
|
1182
|
+
* const notRef = { value: 42 }
|
|
1183
|
+
* const isNotRef = RefSubject.isRefSubject(notRef)
|
|
1184
|
+
* console.log(isNotRef) // false
|
|
1185
|
+
* })
|
|
1186
|
+
* ```
|
|
1187
|
+
*
|
|
1188
|
+
* @since 1.0.0
|
|
1189
|
+
* @category guards
|
|
1190
|
+
*/
|
|
1191
|
+
export function isRefSubject(value: any): value is RefSubject<any, any, any> {
|
|
1192
|
+
return value && typeof value === "object" && value[RefSubjectTypeId] === RefSubjectTypeId;
|
|
1193
|
+
}
|
|
1194
|
+
|
|
1195
|
+
const isRefSubjectDataFirst = (args: IArguments) => isRefSubject(args[0]);
|
|
1196
|
+
|
|
1197
|
+
/**
|
|
1198
|
+
* Runs an effect that can modify a `RefSubject` transactionally, with optional interrupt handling.
|
|
1199
|
+
*
|
|
1200
|
+
* @example
|
|
1201
|
+
* ```ts
|
|
1202
|
+
* import { Effect } from "effect"
|
|
1203
|
+
* import * as RefSubject from "@typed/fx/RefSubject"
|
|
1204
|
+
*
|
|
1205
|
+
* const program = Effect.gen(function* () {
|
|
1206
|
+
* const balance = yield* RefSubject.make(100)
|
|
1207
|
+
*
|
|
1208
|
+
* // Transfer money atomically with interrupt handling
|
|
1209
|
+
* yield* RefSubject.runUpdates(
|
|
1210
|
+
* balance,
|
|
1211
|
+
* (ref) =>
|
|
1212
|
+
* Effect.gen(function* () {
|
|
1213
|
+
* const current = yield* ref.get
|
|
1214
|
+
* if (current >= 50) {
|
|
1215
|
+
* yield* ref.set(current - 50)
|
|
1216
|
+
* return "Transfer successful"
|
|
1217
|
+
* }
|
|
1218
|
+
* return "Insufficient funds"
|
|
1219
|
+
* }),
|
|
1220
|
+
* {
|
|
1221
|
+
* onInterrupt: (value) => Effect.sync(() => console.log(`Interrupted at balance: ${value}`)),
|
|
1222
|
+
* value: "initial"
|
|
1223
|
+
* }
|
|
1224
|
+
* )
|
|
1225
|
+
* })
|
|
1226
|
+
* ```
|
|
1227
|
+
*
|
|
1228
|
+
* @since 1.0.0
|
|
1229
|
+
* @category combinators
|
|
1230
|
+
*/
|
|
1231
|
+
export const runUpdates: {
|
|
1232
|
+
<A, E, R, B, E2, R2, R3 = never, E3 = never, C = never>(
|
|
1233
|
+
f: (ref: GetSetDelete<A, E, R>) => Effect.Effect<B, E2, R2>,
|
|
1234
|
+
options?: {
|
|
1235
|
+
readonly onInterrupt: (value: A) => Effect.Effect<C, E3, R3>;
|
|
1236
|
+
readonly value?: "initial" | "current";
|
|
1237
|
+
},
|
|
1238
|
+
): (ref: RefSubject<A, E, R>) => Effect.Effect<B, E | E2 | E3, R | R2 | R3>;
|
|
1239
|
+
|
|
1240
|
+
<A, E, R, B, E2, R2, R3 = never, E3 = never, C = never>(
|
|
1241
|
+
ref: RefSubject<A, E, R>,
|
|
1242
|
+
f: (ref: GetSetDelete<A, E, R>) => Effect.Effect<B, E2, R2>,
|
|
1243
|
+
options?:
|
|
1244
|
+
| {
|
|
1245
|
+
readonly onInterrupt: (value: A) => Effect.Effect<C, E3, R3>;
|
|
1246
|
+
readonly value?: "initial" | "current";
|
|
1247
|
+
}
|
|
1248
|
+
| undefined,
|
|
1249
|
+
): Effect.Effect<B, E | E2 | E3, R | R2 | R3>;
|
|
1250
|
+
} = dual(
|
|
1251
|
+
isRefSubjectDataFirst,
|
|
1252
|
+
function runUpdates<A, E, R, B, E2, R2, R3 = never, E3 = never, C = never>(
|
|
1253
|
+
ref: RefSubject<A, E, R>,
|
|
1254
|
+
f: (ref: GetSetDelete<A, E, R>) => Effect.Effect<B, E2, R2>,
|
|
1255
|
+
options?: {
|
|
1256
|
+
readonly onInterrupt: (value: A) => Effect.Effect<C, E3, R3>;
|
|
1257
|
+
readonly value?: "initial" | "current";
|
|
1258
|
+
},
|
|
1259
|
+
) {
|
|
1260
|
+
if (options === undefined) {
|
|
1261
|
+
return ref.updates(f);
|
|
1262
|
+
} else if (options.value === "initial") {
|
|
1263
|
+
return ref.updates((ref) =>
|
|
1264
|
+
Effect.flatMap(ref.get, (initial) =>
|
|
1265
|
+
f(ref).pipe(Effect.onInterrupt(() => options.onInterrupt(initial))),
|
|
1266
|
+
),
|
|
1267
|
+
);
|
|
1268
|
+
} else {
|
|
1269
|
+
return ref.updates((ref) =>
|
|
1270
|
+
f(ref).pipe(Effect.onInterrupt(() => Effect.flatMap(ref.get, options.onInterrupt))),
|
|
1271
|
+
);
|
|
1272
|
+
}
|
|
1273
|
+
},
|
|
1274
|
+
);
|
|
1275
|
+
|
|
1276
|
+
/**
|
|
1277
|
+
* Increments a numeric `RefSubject` by 1.
|
|
1278
|
+
*
|
|
1279
|
+
* @example
|
|
1280
|
+
* ```ts
|
|
1281
|
+
* import { Effect } from "effect"
|
|
1282
|
+
* import * as RefSubject from "@typed/fx/RefSubject"
|
|
1283
|
+
*
|
|
1284
|
+
* const program = Effect.gen(function* () {
|
|
1285
|
+
* const count = yield* RefSubject.make(0)
|
|
1286
|
+
*
|
|
1287
|
+
* yield* RefSubject.increment(count)
|
|
1288
|
+
* const value = yield* count
|
|
1289
|
+
* console.log(value) // 1
|
|
1290
|
+
*
|
|
1291
|
+
* yield* RefSubject.increment(count)
|
|
1292
|
+
* const newValue = yield* count
|
|
1293
|
+
* console.log(newValue) // 2
|
|
1294
|
+
* })
|
|
1295
|
+
* ```
|
|
1296
|
+
*
|
|
1297
|
+
* @since 1.0.0
|
|
1298
|
+
* @category combinators
|
|
1299
|
+
*/
|
|
1300
|
+
export function increment<E, R>(ref: RefSubject<number, E, R>): Effect.Effect<number, E, R> {
|
|
1301
|
+
return update(ref, (value) => value + 1);
|
|
1302
|
+
}
|
|
1303
|
+
|
|
1304
|
+
/**
|
|
1305
|
+
* Decrements a numeric `RefSubject` by 1.
|
|
1306
|
+
*
|
|
1307
|
+
* @example
|
|
1308
|
+
* ```ts
|
|
1309
|
+
* import { Effect } from "effect"
|
|
1310
|
+
* import * as RefSubject from "@typed/fx/RefSubject"
|
|
1311
|
+
*
|
|
1312
|
+
* const program = Effect.gen(function* () {
|
|
1313
|
+
* const count = yield* RefSubject.make(10)
|
|
1314
|
+
*
|
|
1315
|
+
* yield* RefSubject.decrement(count)
|
|
1316
|
+
* const value = yield* count
|
|
1317
|
+
* console.log(value) // 9
|
|
1318
|
+
*
|
|
1319
|
+
* yield* RefSubject.decrement(count)
|
|
1320
|
+
* const newValue = yield* count
|
|
1321
|
+
* console.log(newValue) // 8
|
|
1322
|
+
* })
|
|
1323
|
+
* ```
|
|
1324
|
+
*
|
|
1325
|
+
* @since 1.0.0
|
|
1326
|
+
* @category combinators
|
|
1327
|
+
*/
|
|
1328
|
+
export function decrement<E, R>(ref: RefSubject<number, E, R>): Effect.Effect<number, E, R> {
|
|
1329
|
+
return update(ref, (value) => value - 1);
|
|
1330
|
+
}
|
|
1331
|
+
|
|
1332
|
+
const Variance: Fx.Variance<any, any, any> = {
|
|
1333
|
+
_A: identity,
|
|
1334
|
+
_E: identity,
|
|
1335
|
+
_R: identity,
|
|
1336
|
+
};
|
|
1337
|
+
|
|
1338
|
+
export function Service<Self, A, E = never>() {
|
|
1339
|
+
return <const Id extends string>(id: Id): RefSubject.Class<Self, Id, A, E> => {
|
|
1340
|
+
const service = ServiceMap.Service<Self, RefSubject<A, E>>(id);
|
|
1341
|
+
|
|
1342
|
+
// eslint-disable-next-line @typescript-eslint/no-extraneous-class
|
|
1343
|
+
return class RefSubjectService {
|
|
1344
|
+
/// Service
|
|
1345
|
+
|
|
1346
|
+
static readonly id = id;
|
|
1347
|
+
static readonly service = service;
|
|
1348
|
+
|
|
1349
|
+
static readonly layer = <E2, R2>(
|
|
1350
|
+
make: Effect.Effect<RefSubject<A, E>, E2, R2 | Scope.Scope>,
|
|
1351
|
+
) => Layer.effect(service, make);
|
|
1352
|
+
|
|
1353
|
+
static readonly make = <R = never>(
|
|
1354
|
+
value: A | Effect.Effect<A, E, R> | Fx<A, E, R>,
|
|
1355
|
+
options?: RefSubjectOptions<A> & Partial<Bounds>,
|
|
1356
|
+
): Layer.Layer<Self, never, R> => {
|
|
1357
|
+
const bounds = getDefaultBounds(options);
|
|
1358
|
+
return make(value, options).pipe(
|
|
1359
|
+
Effect.map((ref) => (bounds ? slice(ref, bounds.skip, bounds.take) : ref)),
|
|
1360
|
+
this.layer,
|
|
1361
|
+
);
|
|
1362
|
+
};
|
|
1363
|
+
|
|
1364
|
+
// Fx
|
|
1365
|
+
static readonly [FxTypeId]: Fx.Variance<A, E, Self> = Variance;
|
|
1366
|
+
static readonly run = <RSink>(sink: Sink.Sink<A, E, RSink>) =>
|
|
1367
|
+
Effect.flatMap(service.asEffect(), (ref) => ref.run(sink));
|
|
1368
|
+
|
|
1369
|
+
// Sink
|
|
1370
|
+
static readonly onSuccess = (value: A) =>
|
|
1371
|
+
Effect.flatMap(service.asEffect(), (ref) => ref.onSuccess(value));
|
|
1372
|
+
static readonly onFailure = (cause: Cause.Cause<E>) =>
|
|
1373
|
+
Effect.flatMap(service.asEffect(), (ref) => ref.onFailure(cause));
|
|
1374
|
+
|
|
1375
|
+
/// Computed
|
|
1376
|
+
static readonly [ComputedTypeId]: ComputedTypeId = ComputedTypeId;
|
|
1377
|
+
static readonly version = Effect.flatMap(service.asEffect(), (ref) => ref.version);
|
|
1378
|
+
|
|
1379
|
+
// Subject
|
|
1380
|
+
static readonly subscriberCount = Effect.flatMap(
|
|
1381
|
+
service.asEffect(),
|
|
1382
|
+
(ref) => ref.subscriberCount,
|
|
1383
|
+
);
|
|
1384
|
+
static readonly interrupt = Effect.flatMap(service.asEffect(), (ref) => ref.interrupt);
|
|
1385
|
+
|
|
1386
|
+
// RefSubject
|
|
1387
|
+
static readonly [RefSubjectTypeId]: RefSubjectTypeId = RefSubjectTypeId;
|
|
1388
|
+
static readonly updates = <B, E2, R2>(
|
|
1389
|
+
f: (ref: GetSetDelete<A, E, never>) => Effect.Effect<B, E2, R2>,
|
|
1390
|
+
) => Effect.flatMap(service.asEffect(), (ref) => ref.updates(f));
|
|
1391
|
+
|
|
1392
|
+
// Yieldable
|
|
1393
|
+
static readonly asEffect = () => Effect.flatMap(service.asEffect(), Effect.fromYieldable);
|
|
1394
|
+
static readonly [Symbol.iterator] = function* () {
|
|
1395
|
+
const ref = yield* service;
|
|
1396
|
+
return yield* ref;
|
|
1397
|
+
};
|
|
1398
|
+
static readonly pipe: RefSubject.Service<Self, Id, A, E>["pipe"] = function pipe(
|
|
1399
|
+
this: RefSubject.Service<Self, Id, A, E>,
|
|
1400
|
+
) {
|
|
1401
|
+
return pipeArguments(this, arguments);
|
|
1402
|
+
};
|
|
1403
|
+
|
|
1404
|
+
constructor() {
|
|
1405
|
+
return RefSubjectService;
|
|
1406
|
+
}
|
|
1407
|
+
} as unknown as RefSubject.Class<Self, Id, A, E>;
|
|
1408
|
+
};
|
|
1409
|
+
}
|
|
1410
|
+
|
|
1411
|
+
function getDefaultBounds(options?: Partial<Bounds>): Bounds | undefined {
|
|
1412
|
+
if (options === undefined || (options.skip === undefined && options.take === undefined)) {
|
|
1413
|
+
return { skip: 0, take: Infinity };
|
|
1414
|
+
}
|
|
1415
|
+
|
|
1416
|
+
return { skip: options.skip ?? 0, take: options.take ?? Infinity };
|
|
1417
|
+
}
|
|
1418
|
+
|
|
1419
|
+
/**
|
|
1420
|
+
* Extract all values from an object using a Proxy.
|
|
1421
|
+
* Allows accessing nested properties of a `Computed` or `Filtered` object/array as individual computed values.
|
|
1422
|
+
*
|
|
1423
|
+
* @example
|
|
1424
|
+
* ```ts
|
|
1425
|
+
* import { Effect } from "effect"
|
|
1426
|
+
* import * as RefSubject from "@typed/fx/RefSubject"
|
|
1427
|
+
*
|
|
1428
|
+
* const program = Effect.gen(function* () {
|
|
1429
|
+
* const user = yield* RefSubject.make({ name: "Alice", age: 30 })
|
|
1430
|
+
*
|
|
1431
|
+
* // Create a proxy to access nested properties
|
|
1432
|
+
* const proxied = RefSubject.proxy(user)
|
|
1433
|
+
*
|
|
1434
|
+
* // Access individual properties as Computed values
|
|
1435
|
+
* const name = yield* proxied.name
|
|
1436
|
+
* console.log(name) // "Alice"
|
|
1437
|
+
*
|
|
1438
|
+
* const age = yield* proxied.age
|
|
1439
|
+
* console.log(age) // 30
|
|
1440
|
+
*
|
|
1441
|
+
* // Update the source
|
|
1442
|
+
* yield* RefSubject.set(user, { name: "Bob", age: 25 })
|
|
1443
|
+
*
|
|
1444
|
+
* // Proxied values automatically update
|
|
1445
|
+
* const newName = yield* proxied.name
|
|
1446
|
+
* console.log(newName) // "Bob"
|
|
1447
|
+
* })
|
|
1448
|
+
* ```
|
|
1449
|
+
*
|
|
1450
|
+
* @since 2.0.0
|
|
1451
|
+
* @category combinators
|
|
1452
|
+
*/
|
|
1453
|
+
export const proxy: {
|
|
1454
|
+
<A extends ReadonlyArray<any> | Readonly<Record<PropertyKey, any>>, E, R>(
|
|
1455
|
+
source: Computed<A, E, R>,
|
|
1456
|
+
): { readonly [K in keyof A]: Computed<A[K], E, R> };
|
|
1457
|
+
|
|
1458
|
+
<A extends ReadonlyArray<any> | Readonly<Record<PropertyKey, any>>, E, R>(
|
|
1459
|
+
source: Filtered<A, E, R>,
|
|
1460
|
+
): { readonly [K in keyof A]: Filtered<A[K], E, R> };
|
|
1461
|
+
} = <A extends Readonly<Record<PropertyKey, any>> | ReadonlyArray<any>, E, R>(
|
|
1462
|
+
source: Computed<A, E, R> | Filtered<A, E, R>,
|
|
1463
|
+
): any => {
|
|
1464
|
+
const target: any = {};
|
|
1465
|
+
return new Proxy(target, {
|
|
1466
|
+
get(self, prop) {
|
|
1467
|
+
if (prop in self) return self[prop];
|
|
1468
|
+
return (self[prop] = map(source, (a) => a[prop as keyof A]));
|
|
1469
|
+
},
|
|
1470
|
+
});
|
|
1471
|
+
};
|
|
1472
|
+
|
|
1473
|
+
export type Services<T> =
|
|
1474
|
+
T extends RefSubject<infer _A, infer _E, infer R>
|
|
1475
|
+
? R
|
|
1476
|
+
: T extends Computed<infer _A, infer _E, infer R>
|
|
1477
|
+
? R
|
|
1478
|
+
: T extends Filtered<infer _A, infer _E, infer R>
|
|
1479
|
+
? R
|
|
1480
|
+
: never;
|
|
1481
|
+
|
|
1482
|
+
export type Error<T> =
|
|
1483
|
+
T extends RefSubject<infer _A, infer E, infer _R>
|
|
1484
|
+
? E
|
|
1485
|
+
: T extends Computed<infer _A, infer E, infer _R>
|
|
1486
|
+
? E
|
|
1487
|
+
: T extends Filtered<infer _A, infer E, infer _R>
|
|
1488
|
+
? E
|
|
1489
|
+
: never;
|
|
1490
|
+
|
|
1491
|
+
export type Success<T> =
|
|
1492
|
+
T extends RefSubject<infer A, infer _E, infer _R>
|
|
1493
|
+
? A
|
|
1494
|
+
: T extends Computed<infer A, infer _E, infer _R>
|
|
1495
|
+
? A
|
|
1496
|
+
: T extends Filtered<infer A, infer _E, infer _R>
|
|
1497
|
+
? A
|
|
1498
|
+
: never;
|
|
1499
|
+
|
|
1500
|
+
export type Identifier<T> =
|
|
1501
|
+
T extends RefSubject.Service<infer R, infer _Id, infer _A, infer _E> ? R : never;
|
|
1502
|
+
|
|
1503
|
+
/**
|
|
1504
|
+
* Transforms a `RefSubject`, `Computed`, or `Filtered` using an `Effect`ful function.
|
|
1505
|
+
*
|
|
1506
|
+
* @example
|
|
1507
|
+
* ```ts
|
|
1508
|
+
* import { Effect } from "effect"
|
|
1509
|
+
* import * as RefSubject from "@typed/fx/RefSubject"
|
|
1510
|
+
*
|
|
1511
|
+
* const program = Effect.gen(function* () {
|
|
1512
|
+
* const count = yield* RefSubject.make(5)
|
|
1513
|
+
*
|
|
1514
|
+
* // Transform with an async operation
|
|
1515
|
+
* const doubled = RefSubject.mapEffect(count, (n) =>
|
|
1516
|
+
* Effect.succeed(n * 2)
|
|
1517
|
+
* )
|
|
1518
|
+
*
|
|
1519
|
+
* const value = yield* doubled
|
|
1520
|
+
* console.log(value) // 10
|
|
1521
|
+
*
|
|
1522
|
+
* // Update source
|
|
1523
|
+
* yield* RefSubject.set(count, 7)
|
|
1524
|
+
*
|
|
1525
|
+
* // Computed automatically updates
|
|
1526
|
+
* const newValue = yield* doubled
|
|
1527
|
+
* console.log(newValue) // 14
|
|
1528
|
+
* })
|
|
1529
|
+
* ```
|
|
1530
|
+
*
|
|
1531
|
+
* @since 1.0.0
|
|
1532
|
+
* @category combinators
|
|
1533
|
+
*/
|
|
1534
|
+
export const mapEffect: {
|
|
1535
|
+
<T extends RefSubject.Any | Computed.Any | Filtered.Any, B, E2, R2>(
|
|
1536
|
+
f: (a: Success<T>) => Effect.Effect<B, E2, R2>,
|
|
1537
|
+
): (
|
|
1538
|
+
ref: T,
|
|
1539
|
+
) => T extends Filtered.Any
|
|
1540
|
+
? Filtered<B, Error<T> | E2, Services<T> | R2>
|
|
1541
|
+
: Computed<B, Error<T> | E2, Services<T> | R2>;
|
|
1542
|
+
|
|
1543
|
+
<A, E, R, B, E2, R2>(
|
|
1544
|
+
ref: RefSubject<A, E, R> | Computed<A, E, R>,
|
|
1545
|
+
f: (a: A) => Effect.Effect<B, E2, R2>,
|
|
1546
|
+
): Computed<B, E | E2, R | R2>;
|
|
1547
|
+
|
|
1548
|
+
<A, E, R, B, E2, R2>(
|
|
1549
|
+
ref: Filtered<A, E, R>,
|
|
1550
|
+
f: (a: A) => Effect.Effect<B, E2, R2>,
|
|
1551
|
+
): Filtered<B, E | E2, R | R2>;
|
|
1552
|
+
|
|
1553
|
+
<R0, E0, A, E, R, E2, R2, C, E3, R3>(
|
|
1554
|
+
versioned: Versioned.Versioned<R0, E0, A, E, R, A, E2, R2>,
|
|
1555
|
+
f: (a: A) => Effect.Effect<C, E3, R3>,
|
|
1556
|
+
): Computed<C, E0 | E | E2 | E3, R0 | R2 | R3 | Exclude<R, Scope.Scope>>;
|
|
1557
|
+
} = dual(2, function mapEffect<
|
|
1558
|
+
R0,
|
|
1559
|
+
E0,
|
|
1560
|
+
A,
|
|
1561
|
+
E,
|
|
1562
|
+
R,
|
|
1563
|
+
E2,
|
|
1564
|
+
R2,
|
|
1565
|
+
C,
|
|
1566
|
+
E3,
|
|
1567
|
+
R3,
|
|
1568
|
+
>(versioned: Versioned.Versioned<R0, E0, A, E, R, A, E2, R2>, f: (a: A) => Effect.Effect<C, E3, R3>):
|
|
1569
|
+
| Computed<C, E0 | E | E2 | E3, R0 | Exclude<R, Scope.Scope> | R2 | R3>
|
|
1570
|
+
| Filtered<C, E0 | E | E2 | E3, R0 | Exclude<R, Scope.Scope> | R2 | R3> {
|
|
1571
|
+
return FilteredTypeId in versioned
|
|
1572
|
+
? new FilteredImpl(versioned, (a) => Effect.asSome(f(a)))
|
|
1573
|
+
: new ComputedImpl(versioned, f);
|
|
1574
|
+
});
|
|
1575
|
+
|
|
1576
|
+
/**
|
|
1577
|
+
* Transforms a `RefSubject`, `Computed`, or `Filtered` using a pure function.
|
|
1578
|
+
*
|
|
1579
|
+
* @example
|
|
1580
|
+
* ```ts
|
|
1581
|
+
* import { Effect } from "effect"
|
|
1582
|
+
* import * as RefSubject from "@typed/fx/RefSubject"
|
|
1583
|
+
*
|
|
1584
|
+
* const program = Effect.gen(function* () {
|
|
1585
|
+
* const count = yield* RefSubject.make(5)
|
|
1586
|
+
*
|
|
1587
|
+
* // Create a computed that doubles the count
|
|
1588
|
+
* const doubled = RefSubject.map(count, (n) => n * 2)
|
|
1589
|
+
*
|
|
1590
|
+
* const value = yield* doubled
|
|
1591
|
+
* console.log(value) // 10
|
|
1592
|
+
*
|
|
1593
|
+
* // Update source
|
|
1594
|
+
* yield* RefSubject.set(count, 7)
|
|
1595
|
+
*
|
|
1596
|
+
* // Computed automatically updates
|
|
1597
|
+
* const newValue = yield* doubled
|
|
1598
|
+
* console.log(newValue) // 14
|
|
1599
|
+
* })
|
|
1600
|
+
* ```
|
|
1601
|
+
*
|
|
1602
|
+
* @since 1.0.0
|
|
1603
|
+
* @category combinators
|
|
1604
|
+
*/
|
|
1605
|
+
export const map: {
|
|
1606
|
+
<T extends RefSubject.Any | Computed.Any | Filtered.Any, B>(
|
|
1607
|
+
f: (a: Success<T>) => B,
|
|
1608
|
+
): (
|
|
1609
|
+
ref: T,
|
|
1610
|
+
) => T extends Filtered.Any
|
|
1611
|
+
? Filtered<B, Error<T>, Services<T>>
|
|
1612
|
+
: Computed<B, Error<T>, Services<T>>;
|
|
1613
|
+
|
|
1614
|
+
<A, E, R, B>(ref: RefSubject<A, E, R> | Computed<A, E, R>, f: (a: A) => B): Computed<B, E, R>;
|
|
1615
|
+
<A, E, R, B>(filtered: Filtered<A, E, R>, f: (a: A) => B): Filtered<B, E, R>;
|
|
1616
|
+
|
|
1617
|
+
<R0, E0, A, E, R, B, E2, R2>(
|
|
1618
|
+
versioned: Versioned.Versioned<R0, E0, A, E, R, A, E2, R2>,
|
|
1619
|
+
f: (a: A) => B,
|
|
1620
|
+
):
|
|
1621
|
+
| Computed<B, E0 | E | E2, R0 | R2 | Exclude<R, Scope.Scope>>
|
|
1622
|
+
| Filtered<B, E0 | E | E2, R0 | R2 | Exclude<R, Scope.Scope>>;
|
|
1623
|
+
} = dual(2, function map<
|
|
1624
|
+
R0,
|
|
1625
|
+
E0,
|
|
1626
|
+
A,
|
|
1627
|
+
E,
|
|
1628
|
+
R,
|
|
1629
|
+
B,
|
|
1630
|
+
E2,
|
|
1631
|
+
R2,
|
|
1632
|
+
>(versioned: Versioned.Versioned<R0, E0, A, E, R, A, E2, R2>, f: (a: A) => B):
|
|
1633
|
+
| Computed<B, E0 | E | E2, R0 | Exclude<R, Scope.Scope> | R2>
|
|
1634
|
+
| Filtered<B, E0 | E | E2, R0 | Exclude<R, Scope.Scope> | R2> {
|
|
1635
|
+
return mapEffect(versioned, (a) => Effect.succeed(f(a)));
|
|
1636
|
+
});
|
|
1637
|
+
|
|
1638
|
+
/**
|
|
1639
|
+
* Filters and transforms a `RefSubject`, `Computed`, or `Filtered` using an `Effect`ful function that returns an `Option`.
|
|
1640
|
+
*
|
|
1641
|
+
* @example
|
|
1642
|
+
* ```ts
|
|
1643
|
+
* import { Effect, Option } from "effect"
|
|
1644
|
+
* import * as RefSubject from "@typed/fx/RefSubject"
|
|
1645
|
+
*
|
|
1646
|
+
* const program = Effect.gen(function* () {
|
|
1647
|
+
* const numbers = yield* RefSubject.make([1, 2, 3, 4, 5])
|
|
1648
|
+
*
|
|
1649
|
+
* // Find the first even number
|
|
1650
|
+
* const firstEven = RefSubject.filterMapEffect(numbers, (arr) =>
|
|
1651
|
+
* Effect.succeed(Option.fromNullable(arr.find((n) => n % 2 === 0)))
|
|
1652
|
+
* )
|
|
1653
|
+
*
|
|
1654
|
+
* const value = yield* firstEven
|
|
1655
|
+
* console.log(value) // 2
|
|
1656
|
+
* })
|
|
1657
|
+
* ```
|
|
1658
|
+
*
|
|
1659
|
+
* @since 1.0.0
|
|
1660
|
+
* @category combinators
|
|
1661
|
+
*/
|
|
1662
|
+
export const filterMapEffect: {
|
|
1663
|
+
<A, B, E2, R2>(
|
|
1664
|
+
f: (a: A) => Effect.Effect<Option.Option<B>, E2, R2>,
|
|
1665
|
+
): {
|
|
1666
|
+
<E, R>(ref: RefSubject<A, E, R> | Computed<A, E, R>): Filtered<B, E | E2, R | R2>;
|
|
1667
|
+
<E, R>(ref: Filtered<A, E, R>): Filtered<B, E | E2, R | R2>;
|
|
1668
|
+
<R0, E0, B, E, R, E2, R2>(
|
|
1669
|
+
versioned: Versioned.Versioned<R0, E0, A, E, R, A, E2, R2>,
|
|
1670
|
+
f: (a: A) => Effect.Effect<Option.Option<B>, E2, R2>,
|
|
1671
|
+
): Filtered<B, E0 | E | E2, R0 | R2>;
|
|
1672
|
+
};
|
|
1673
|
+
|
|
1674
|
+
<A, E, R, B, E2, R2>(
|
|
1675
|
+
ref: RefSubject<A, E, R> | Computed<A, E, R> | Filtered<A, E, R>,
|
|
1676
|
+
f: (a: A) => Effect.Effect<Option.Option<B>, E2, R2>,
|
|
1677
|
+
): Filtered<B, E | E2, R | R2>;
|
|
1678
|
+
<R0, E0, A, E, R, B, E2, R2, R3, E3>(
|
|
1679
|
+
versioned: Versioned.Versioned<R0, E0, A, E, R, A, E2, R2>,
|
|
1680
|
+
f: (a: A) => Effect.Effect<Option.Option<B>, E3, R3>,
|
|
1681
|
+
): Filtered<B, E0 | E | E2 | E3, R0 | R2 | R3 | Exclude<R, Scope.Scope>>;
|
|
1682
|
+
} = dual(2, function filterMapEffect<
|
|
1683
|
+
R0,
|
|
1684
|
+
E0,
|
|
1685
|
+
A,
|
|
1686
|
+
E,
|
|
1687
|
+
R,
|
|
1688
|
+
B,
|
|
1689
|
+
E2,
|
|
1690
|
+
R2,
|
|
1691
|
+
R3,
|
|
1692
|
+
E3,
|
|
1693
|
+
>(versioned: Versioned.Versioned<R0, E0, A, E, R, A, E2, R2>, f: (a: A) => Effect.Effect<Option.Option<B>, E3, R3>): Filtered<
|
|
1694
|
+
B,
|
|
1695
|
+
E0 | E | E2 | E3,
|
|
1696
|
+
R0 | Exclude<R, Scope.Scope> | R2 | R3
|
|
1697
|
+
> {
|
|
1698
|
+
return new FilteredImpl(versioned, f);
|
|
1699
|
+
});
|
|
1700
|
+
|
|
1701
|
+
/**
|
|
1702
|
+
* Filters and transforms a `RefSubject`, `Computed`, or `Filtered` using a pure function that returns an `Option`.
|
|
1703
|
+
*
|
|
1704
|
+
* @example
|
|
1705
|
+
* ```ts
|
|
1706
|
+
* import { Effect, Option } from "effect"
|
|
1707
|
+
* import * as RefSubject from "@typed/fx/RefSubject"
|
|
1708
|
+
*
|
|
1709
|
+
* const program = Effect.gen(function* () {
|
|
1710
|
+
* const numbers = yield* RefSubject.make([1, 2, 3, 4, 5])
|
|
1711
|
+
*
|
|
1712
|
+
* // Get the first even number
|
|
1713
|
+
* const firstEven = RefSubject.filterMap(numbers, (arr) =>
|
|
1714
|
+
* Option.fromNullable(arr.find((n) => n % 2 === 0))
|
|
1715
|
+
* )
|
|
1716
|
+
*
|
|
1717
|
+
* const value = yield* firstEven
|
|
1718
|
+
* console.log(value) // 2
|
|
1719
|
+
* })
|
|
1720
|
+
* ```
|
|
1721
|
+
*
|
|
1722
|
+
* @since 1.0.0
|
|
1723
|
+
* @category combinators
|
|
1724
|
+
*/
|
|
1725
|
+
export const filterMap: {
|
|
1726
|
+
<A, B>(
|
|
1727
|
+
f: (a: A) => Option.Option<B>,
|
|
1728
|
+
): {
|
|
1729
|
+
<E, R>(ref: RefSubject<A, E, R> | Computed<A, E, R> | Filtered<A, E, R>): Filtered<B, E, R>;
|
|
1730
|
+
<R0, E0, B, E, R, E2, R2>(
|
|
1731
|
+
versioned: Versioned.Versioned<R0, E0, A, E, R, A, E2, R2>,
|
|
1732
|
+
f: (a: A) => Option.Option<B>,
|
|
1733
|
+
): Filtered<B, E0 | E | E2, R0 | R2>;
|
|
1734
|
+
};
|
|
1735
|
+
|
|
1736
|
+
<R0, E0, A, E, R, B, E2, R2>(
|
|
1737
|
+
versioned: Versioned.Versioned<R0, E0, A, E, R, A, E2, R2>,
|
|
1738
|
+
f: (a: A) => Option.Option<B>,
|
|
1739
|
+
): Filtered<B, E0 | E | E2, R0 | R2 | Exclude<R, Scope.Scope>>;
|
|
1740
|
+
|
|
1741
|
+
<A, E, R, B>(
|
|
1742
|
+
ref: RefSubject<A, E, R> | Computed<A, E, R> | Filtered<A, E, R>,
|
|
1743
|
+
f: (a: A) => Option.Option<B>,
|
|
1744
|
+
): Filtered<B, E, R>;
|
|
1745
|
+
} = dual(2, function filterMap<
|
|
1746
|
+
R0,
|
|
1747
|
+
E0,
|
|
1748
|
+
A,
|
|
1749
|
+
E,
|
|
1750
|
+
R,
|
|
1751
|
+
B,
|
|
1752
|
+
E2,
|
|
1753
|
+
R2,
|
|
1754
|
+
>(versioned: Versioned.Versioned<R0, E0, A, E, R, A, E2, R2>, f: (a: A) => Option.Option<B>): Filtered<
|
|
1755
|
+
B,
|
|
1756
|
+
E0 | E | E2,
|
|
1757
|
+
R0 | Exclude<R, Scope.Scope> | R2
|
|
1758
|
+
> {
|
|
1759
|
+
return new FilteredImpl(versioned, (a) => Effect.succeed(f(a)));
|
|
1760
|
+
});
|
|
1761
|
+
|
|
1762
|
+
/**
|
|
1763
|
+
* Converts a `Computed` or `Filtered` of `Option<A>` into a `Filtered<A>`, filtering out `None` values.
|
|
1764
|
+
*
|
|
1765
|
+
* @example
|
|
1766
|
+
* ```ts
|
|
1767
|
+
* import { Effect, Option } from "effect"
|
|
1768
|
+
* import * as RefSubject from "@typed/fx/RefSubject"
|
|
1769
|
+
*
|
|
1770
|
+
* const program = Effect.gen(function* () {
|
|
1771
|
+
* const maybeValue = yield* RefSubject.make(Option.some(42))
|
|
1772
|
+
*
|
|
1773
|
+
* // Compact the Option
|
|
1774
|
+
* const filtered = RefSubject.compact(maybeValue)
|
|
1775
|
+
*
|
|
1776
|
+
* const value = yield* filtered
|
|
1777
|
+
* console.log(value) // 42
|
|
1778
|
+
*
|
|
1779
|
+
* // If the Option becomes None, the Filtered will fail
|
|
1780
|
+
* yield* RefSubject.set(maybeValue, Option.none())
|
|
1781
|
+
* // yield* filtered would fail with NoSuchElementError
|
|
1782
|
+
* })
|
|
1783
|
+
* ```
|
|
1784
|
+
*
|
|
1785
|
+
* @since 1.0.0
|
|
1786
|
+
* @category combinators
|
|
1787
|
+
*/
|
|
1788
|
+
export const compact: {
|
|
1789
|
+
<A, E, R>(ref: Computed<Option.Option<A>, E, R>): Filtered<A>;
|
|
1790
|
+
<A, E, R>(ref: Filtered<Option.Option<A>, E, R>): Filtered<A>;
|
|
1791
|
+
|
|
1792
|
+
<R0, E0, A, E, R, E2, R2>(
|
|
1793
|
+
versioned: Versioned.Versioned<R0, E0, Option.Option<A>, E, R, Option.Option<A>, E2, R2>,
|
|
1794
|
+
): Filtered<
|
|
1795
|
+
A,
|
|
1796
|
+
E0 | E | Exclude<E, Cause.NoSuchElementError> | Exclude<E2, Cause.NoSuchElementError>,
|
|
1797
|
+
R0 | R2 | Exclude<R, Scope.Scope>
|
|
1798
|
+
>;
|
|
1799
|
+
} = function compact<R0, E0, A, E, R, E2, R2>(
|
|
1800
|
+
versioned: Versioned.Versioned<R0, E0, Option.Option<A>, E, R, Option.Option<A>, E2, R2>,
|
|
1801
|
+
): any {
|
|
1802
|
+
return new FilteredImpl(versioned, Effect.succeed);
|
|
1803
|
+
};
|
|
1804
|
+
|
|
1805
|
+
/**
|
|
1806
|
+
* Returns a `Computed` that yields the value inside the `Option`, or the fallback when `None`.
|
|
1807
|
+
* Works with `Computed<Option<A>>` (e.g. from `fromOption` / `fromNullable`) and with `Filtered<A>`.
|
|
1808
|
+
*
|
|
1809
|
+
* @example
|
|
1810
|
+
* ```ts
|
|
1811
|
+
* import { Effect, Option } from "effect"
|
|
1812
|
+
* import * as RefSubject from "@typed/fx/RefSubject"
|
|
1813
|
+
*
|
|
1814
|
+
* const program = Effect.gen(function* () {
|
|
1815
|
+
* const ref = yield* RefSubject.fromOption(Option.some(42))
|
|
1816
|
+
* const withDefault = RefSubject.getOrElse(ref, () => 0)
|
|
1817
|
+
* expect(yield* withDefault).toBe(42)
|
|
1818
|
+
*
|
|
1819
|
+
* const empty = yield* RefSubject.fromNullable(null)
|
|
1820
|
+
* const fallback = RefSubject.getOrElse(empty, () => 99)
|
|
1821
|
+
* expect(yield* fallback).toBe(99)
|
|
1822
|
+
* })
|
|
1823
|
+
* ```
|
|
1824
|
+
*
|
|
1825
|
+
* @since 1.0.0
|
|
1826
|
+
* @category combinators
|
|
1827
|
+
*/
|
|
1828
|
+
export const getOrElse: {
|
|
1829
|
+
<A>(
|
|
1830
|
+
fallback: () => A,
|
|
1831
|
+
): <E, R>(ref: Computed<Option.Option<A>, E, R> | Filtered<A, E, R>) => Computed<A, E, R>;
|
|
1832
|
+
<A, E, R>(
|
|
1833
|
+
ref: Computed<Option.Option<A>, E, R> | Filtered<A, E, R>,
|
|
1834
|
+
fallback: () => A,
|
|
1835
|
+
): Computed<A, E, R>;
|
|
1836
|
+
} = dual(2, function getOrElse<
|
|
1837
|
+
A,
|
|
1838
|
+
E,
|
|
1839
|
+
R,
|
|
1840
|
+
>(ref: Computed<Option.Option<A>, E, R> | Filtered<A, E, R>, fallback: () => A): Computed<A, E, R> {
|
|
1841
|
+
const computed = FilteredTypeId in ref ? (ref as Filtered<A, E, R>).asComputed() : ref;
|
|
1842
|
+
return map(computed, (opt) => Option.getOrElse(opt, fallback));
|
|
1843
|
+
});
|
|
1844
|
+
|
|
1845
|
+
class RefSubjectSimpleTransform<A, E, R, R2, R3>
|
|
1846
|
+
extends YieldableFx<A, E, R | R2 | Scope.Scope, A, E, R | R3>
|
|
1847
|
+
implements RefSubject<A, E, R | R2 | R3>
|
|
1848
|
+
{
|
|
1849
|
+
readonly [ComputedTypeId]: ComputedTypeId = ComputedTypeId;
|
|
1850
|
+
readonly [RefSubjectTypeId]: RefSubjectTypeId = RefSubjectTypeId;
|
|
1851
|
+
|
|
1852
|
+
readonly version: Effect.Effect<number, E, R>;
|
|
1853
|
+
readonly interrupt: Effect.Effect<void, never, R>;
|
|
1854
|
+
readonly subscriberCount: Effect.Effect<number, never, R>;
|
|
1855
|
+
private _fx: Fx<A, E, Scope.Scope | R | R2>;
|
|
1856
|
+
|
|
1857
|
+
readonly ref: RefSubject<A, E, R>;
|
|
1858
|
+
readonly transformFx: (fx: Fx<A, E, Scope.Scope | R>) => Fx<A, E, Scope.Scope | R | R2>;
|
|
1859
|
+
readonly transformEffect: (effect: Effect.Effect<A, E, R>) => Effect.Effect<A, E, R | R3>;
|
|
1860
|
+
|
|
1861
|
+
constructor(
|
|
1862
|
+
ref: RefSubject<A, E, R>,
|
|
1863
|
+
transformFx: (fx: Fx<A, E, Scope.Scope | R>) => Fx<A, E, Scope.Scope | R | R2>,
|
|
1864
|
+
transformEffect: (effect: Effect.Effect<A, E, R>) => Effect.Effect<A, E, R | R3>,
|
|
1865
|
+
) {
|
|
1866
|
+
super();
|
|
1867
|
+
|
|
1868
|
+
this.ref = ref;
|
|
1869
|
+
this.transformFx = transformFx;
|
|
1870
|
+
this.transformEffect = transformEffect;
|
|
1871
|
+
this.version = ref.version;
|
|
1872
|
+
this.interrupt = ref.interrupt;
|
|
1873
|
+
this.subscriberCount = ref.subscriberCount;
|
|
1874
|
+
|
|
1875
|
+
this._fx = transformFx(ref);
|
|
1876
|
+
}
|
|
1877
|
+
|
|
1878
|
+
run<R4>(sink: Sink.Sink<A, E, R4>) {
|
|
1879
|
+
return this._fx.run(sink);
|
|
1880
|
+
}
|
|
1881
|
+
|
|
1882
|
+
toEffect(): Effect.Effect<A, E, R | R3> {
|
|
1883
|
+
return this.transformEffect(this.ref.asEffect());
|
|
1884
|
+
}
|
|
1885
|
+
|
|
1886
|
+
updates<E2, R2, C>(
|
|
1887
|
+
run: (ref: GetSetDelete<A, E, R>) => Effect.Effect<C, E2, R2>,
|
|
1888
|
+
): Effect.Effect<C, E | E2, R | R2> {
|
|
1889
|
+
return this.ref.updates(run);
|
|
1890
|
+
}
|
|
1891
|
+
|
|
1892
|
+
onFailure(cause: Cause.Cause<E>): Effect.Effect<unknown, never, R> {
|
|
1893
|
+
return this.ref.onFailure(cause);
|
|
1894
|
+
}
|
|
1895
|
+
|
|
1896
|
+
onSuccess(value: A): Effect.Effect<unknown, never, R> {
|
|
1897
|
+
return this.ref.onSuccess(value);
|
|
1898
|
+
}
|
|
1899
|
+
}
|
|
1900
|
+
|
|
1901
|
+
export const slice: {
|
|
1902
|
+
(skip: number, take: number): <A, E, R>(ref: RefSubject<A, E, R>) => RefSubject<A, E, R>;
|
|
1903
|
+
<A, E, R>(ref: RefSubject<A, E, R>, skip: number, take: number): RefSubject<A, E, R>;
|
|
1904
|
+
} = dual(3, function slice<
|
|
1905
|
+
A,
|
|
1906
|
+
E,
|
|
1907
|
+
R,
|
|
1908
|
+
>(ref: RefSubject<A, E, R>, skip: number, take: number): RefSubject<A, E, R> {
|
|
1909
|
+
return new RefSubjectSimpleTransform(ref, (_) => fxSlice(_, { skip, take }), identity);
|
|
1910
|
+
});
|
|
1911
|
+
|
|
1912
|
+
class RefSubjectTransform<A, B, E, R>
|
|
1913
|
+
extends YieldableFx<B, E, R | Scope.Scope, B, E, R>
|
|
1914
|
+
implements RefSubject<B, E, R>
|
|
1915
|
+
{
|
|
1916
|
+
readonly [ComputedTypeId]: ComputedTypeId = ComputedTypeId;
|
|
1917
|
+
readonly [RefSubjectTypeId]: RefSubjectTypeId = RefSubjectTypeId;
|
|
1918
|
+
|
|
1919
|
+
readonly version: Effect.Effect<number, E, R>;
|
|
1920
|
+
readonly interrupt: Effect.Effect<void, never, R>;
|
|
1921
|
+
readonly subscriberCount: Effect.Effect<number, never, R>;
|
|
1922
|
+
private _fx: Fx<B, E, Scope.Scope | R>;
|
|
1923
|
+
|
|
1924
|
+
readonly ref: RefSubject<A, E, R>;
|
|
1925
|
+
readonly toB: (a: A) => B;
|
|
1926
|
+
readonly toA: (b: B) => A;
|
|
1927
|
+
|
|
1928
|
+
constructor(ref: RefSubject<A, E, R>, toB: (a: A) => B, toA: (b: B) => A) {
|
|
1929
|
+
super();
|
|
1930
|
+
|
|
1931
|
+
this.ref = ref;
|
|
1932
|
+
this.toB = toB;
|
|
1933
|
+
this.toA = toA;
|
|
1934
|
+
this.version = ref.version;
|
|
1935
|
+
this.interrupt = ref.interrupt;
|
|
1936
|
+
this.subscriberCount = ref.subscriberCount;
|
|
1937
|
+
|
|
1938
|
+
this._fx = fxMapEffect(ref, (a) => Effect.succeed(toB(a)));
|
|
1939
|
+
}
|
|
1940
|
+
|
|
1941
|
+
run<R2>(sink: Sink.Sink<B, E, R2>) {
|
|
1942
|
+
return this._fx.run(sink);
|
|
1943
|
+
}
|
|
1944
|
+
|
|
1945
|
+
toEffect(): Effect.Effect<B, E, R> {
|
|
1946
|
+
return Effect.map(this.ref.asEffect(), this.toB);
|
|
1947
|
+
}
|
|
1948
|
+
|
|
1949
|
+
updates<E2, R2, C>(
|
|
1950
|
+
run: (ref: GetSetDelete<B, E, R>) => Effect.Effect<C, E2, R2>,
|
|
1951
|
+
): Effect.Effect<C, E | E2, R | R2> {
|
|
1952
|
+
return this.ref.updates((innerRef) => {
|
|
1953
|
+
const getSetDelete: GetSetDelete<B, E, R> = {
|
|
1954
|
+
get: Effect.map(innerRef.get, this.toB),
|
|
1955
|
+
set: (b: B) => Effect.map(innerRef.set(this.toA(b)), this.toB),
|
|
1956
|
+
delete: Effect.map(innerRef.delete, Option.map(this.toB)),
|
|
1957
|
+
};
|
|
1958
|
+
return run(getSetDelete);
|
|
1959
|
+
});
|
|
1960
|
+
}
|
|
1961
|
+
|
|
1962
|
+
onFailure(cause: Cause.Cause<E>): Effect.Effect<unknown, never, R> {
|
|
1963
|
+
return this.ref.onFailure(cause);
|
|
1964
|
+
}
|
|
1965
|
+
|
|
1966
|
+
onSuccess(value: B): Effect.Effect<unknown, never, R> {
|
|
1967
|
+
return this.ref.onSuccess(this.toA(value));
|
|
1968
|
+
}
|
|
1969
|
+
}
|
|
1970
|
+
|
|
1971
|
+
/**
|
|
1972
|
+
* Transforms a `RefSubject` invariantly using bidirectional mapping functions.
|
|
1973
|
+
*
|
|
1974
|
+
* @example
|
|
1975
|
+
* ```ts
|
|
1976
|
+
* import { Effect } from "effect"
|
|
1977
|
+
* import * as RefSubject from "@typed/fx/RefSubject"
|
|
1978
|
+
*
|
|
1979
|
+
* const program = Effect.gen(function* () {
|
|
1980
|
+
* const count = yield* RefSubject.make(5)
|
|
1981
|
+
*
|
|
1982
|
+
* // Transform to string and back
|
|
1983
|
+
* const countStr = RefSubject.transform(
|
|
1984
|
+
* count,
|
|
1985
|
+
* (n) => n.toString(),
|
|
1986
|
+
* (s) => parseInt(s, 10)
|
|
1987
|
+
* )
|
|
1988
|
+
*
|
|
1989
|
+
* const value = yield* countStr
|
|
1990
|
+
* console.log(value) // "5"
|
|
1991
|
+
*
|
|
1992
|
+
* // Set using the transformed type
|
|
1993
|
+
* yield* RefSubject.set(countStr, "10")
|
|
1994
|
+
*
|
|
1995
|
+
* // Original reflects the change
|
|
1996
|
+
* const original = yield* count
|
|
1997
|
+
* console.log(original) // 10
|
|
1998
|
+
* })
|
|
1999
|
+
* ```
|
|
2000
|
+
*
|
|
2001
|
+
* @since 1.0.0
|
|
2002
|
+
* @category combinators
|
|
2003
|
+
*/
|
|
2004
|
+
export const transform: {
|
|
2005
|
+
<A, B>(
|
|
2006
|
+
toB: (a: A) => B,
|
|
2007
|
+
toA: (b: B) => A,
|
|
2008
|
+
): <E, R>(ref: RefSubject<A, E, R>) => RefSubject<B, E, R>;
|
|
2009
|
+
<A, E, R, B>(ref: RefSubject<A, E, R>, toB: (a: A) => B, toA: (b: B) => A): RefSubject<B, E, R>;
|
|
2010
|
+
} = dual(3, function transform<
|
|
2011
|
+
A,
|
|
2012
|
+
E,
|
|
2013
|
+
R,
|
|
2014
|
+
B,
|
|
2015
|
+
>(ref: RefSubject<A, E, R>, toB: (a: A) => B, toA: (b: B) => A): RefSubject<B, E, R> {
|
|
2016
|
+
return new RefSubjectTransform(ref, toB, toA);
|
|
2017
|
+
});
|
|
2018
|
+
|
|
2019
|
+
type RefKind = "r" | "c" | "f";
|
|
2020
|
+
|
|
2021
|
+
const join = (a: RefKind, b: RefKind) => {
|
|
2022
|
+
if (a === "r") return b;
|
|
2023
|
+
if (b === "r") return a;
|
|
2024
|
+
if (a === "f") return a;
|
|
2025
|
+
if (b === "f") return b;
|
|
2026
|
+
return "c";
|
|
2027
|
+
};
|
|
2028
|
+
|
|
2029
|
+
function getRefKind<
|
|
2030
|
+
const Refs extends ReadonlyArray<
|
|
2031
|
+
RefSubject<any, any, any> | Computed<any, any, any> | Filtered<any, any, any>
|
|
2032
|
+
>,
|
|
2033
|
+
>(refs: Refs): RefKind {
|
|
2034
|
+
let kind: RefKind = "r";
|
|
2035
|
+
|
|
2036
|
+
for (const ref of refs) {
|
|
2037
|
+
if (FilteredTypeId in ref) {
|
|
2038
|
+
kind = "f";
|
|
2039
|
+
break;
|
|
2040
|
+
} else if (!(RefSubjectTypeId in ref)) {
|
|
2041
|
+
kind = join(kind, "c");
|
|
2042
|
+
}
|
|
2043
|
+
}
|
|
2044
|
+
|
|
2045
|
+
return kind;
|
|
2046
|
+
}
|
|
2047
|
+
|
|
2048
|
+
type StructFrom<
|
|
2049
|
+
Refs extends Readonly<Record<string, RefSubject.Any | Computed.Any | Filtered.Any>>,
|
|
2050
|
+
> = {
|
|
2051
|
+
c: [ComputedStructFrom<Refs>] extends [Computed<infer A, infer E, infer R>]
|
|
2052
|
+
? Computed<A, E, R>
|
|
2053
|
+
: never;
|
|
2054
|
+
f: [FilteredStructFrom<Refs>] extends [Filtered<infer A, infer E, infer R>]
|
|
2055
|
+
? Filtered<A, E, R>
|
|
2056
|
+
: never;
|
|
2057
|
+
r: [RefSubjectStructFrom<Refs>] extends [RefSubject<infer A, infer E, infer R>]
|
|
2058
|
+
? RefSubject<A, E, R>
|
|
2059
|
+
: never;
|
|
2060
|
+
}[GetStructKind<Refs>];
|
|
2061
|
+
|
|
2062
|
+
type GetStructKind<
|
|
2063
|
+
Refs extends Readonly<Record<string, RefSubject.Any | Computed.Any | Filtered.Any>>,
|
|
2064
|
+
> = MergeKinds<
|
|
2065
|
+
UnionToTuple<
|
|
2066
|
+
{
|
|
2067
|
+
[K in keyof Refs]: MatchKind<Refs[K]>;
|
|
2068
|
+
}[keyof Refs]
|
|
2069
|
+
>
|
|
2070
|
+
>;
|
|
2071
|
+
|
|
2072
|
+
type Ref = RefSubject.Any | Computed.Any | Filtered.Any;
|
|
2073
|
+
|
|
2074
|
+
type MatchKind<T extends Ref> = [T] extends [Filtered.Any]
|
|
2075
|
+
? "f"
|
|
2076
|
+
: [T] extends [RefSubject.Any]
|
|
2077
|
+
? "r"
|
|
2078
|
+
: "c";
|
|
2079
|
+
|
|
2080
|
+
type MergeKind<A extends RefKind, B extends RefKind> = A extends "f"
|
|
2081
|
+
? A
|
|
2082
|
+
: B extends "f"
|
|
2083
|
+
? B
|
|
2084
|
+
: A extends "r"
|
|
2085
|
+
? B
|
|
2086
|
+
: B extends "r"
|
|
2087
|
+
? A
|
|
2088
|
+
: "c";
|
|
2089
|
+
|
|
2090
|
+
type MergeKinds<Kinds extends ReadonlyArray<any>> = Kinds extends readonly [
|
|
2091
|
+
infer Head extends RefKind,
|
|
2092
|
+
...infer Tail extends ReadonlyArray<RefKind>,
|
|
2093
|
+
]
|
|
2094
|
+
? MergeKind<Head, MergeKinds<Tail>>
|
|
2095
|
+
: "r";
|
|
2096
|
+
|
|
2097
|
+
type FilteredStructFrom<
|
|
2098
|
+
Refs extends Readonly<Record<string, RefSubject.Any | Computed.Any | Filtered.Any>>,
|
|
2099
|
+
> = Filtered<
|
|
2100
|
+
{
|
|
2101
|
+
readonly [K in keyof Refs]: Effect.Success<Refs[K]>;
|
|
2102
|
+
},
|
|
2103
|
+
FxError<Refs[keyof Refs]>,
|
|
2104
|
+
Effect.Services<Refs[keyof Refs]>
|
|
2105
|
+
>;
|
|
2106
|
+
|
|
2107
|
+
type ComputedStructFrom<
|
|
2108
|
+
Refs extends Readonly<Record<string, RefSubject.Any | Computed.Any | Filtered.Any>>,
|
|
2109
|
+
> = Computed<
|
|
2110
|
+
{
|
|
2111
|
+
readonly [K in keyof Refs]: Effect.Success<Refs[K]>;
|
|
2112
|
+
},
|
|
2113
|
+
Effect.Error<Refs[keyof Refs]>,
|
|
2114
|
+
Effect.Services<Refs[keyof Refs]>
|
|
2115
|
+
>;
|
|
2116
|
+
|
|
2117
|
+
type RefSubjectStructFrom<
|
|
2118
|
+
Refs extends Readonly<Record<string, RefSubject.Any | Computed.Any | Filtered.Any>>,
|
|
2119
|
+
> = RefSubject<
|
|
2120
|
+
{
|
|
2121
|
+
readonly [K in keyof Refs]: Effect.Success<Refs[K]>;
|
|
2122
|
+
},
|
|
2123
|
+
Effect.Error<Refs[keyof Refs]>,
|
|
2124
|
+
Effect.Services<Refs[keyof Refs]>
|
|
2125
|
+
>;
|
|
2126
|
+
|
|
2127
|
+
type TupleFrom<
|
|
2128
|
+
Refs extends ReadonlyArray<
|
|
2129
|
+
RefSubject<any, any, any> | Computed<any, any, any> | Filtered<any, any, any>
|
|
2130
|
+
>,
|
|
2131
|
+
> = {
|
|
2132
|
+
c: [ComputedTupleFrom<Refs>] extends [Computed<infer A, infer E, infer R>]
|
|
2133
|
+
? Computed<A, E, R>
|
|
2134
|
+
: never;
|
|
2135
|
+
f: [FilteredTupleFrom<Refs>] extends [Filtered<infer A, infer E, infer R>]
|
|
2136
|
+
? Filtered<A, E, R>
|
|
2137
|
+
: never;
|
|
2138
|
+
r: [RefSubjectTupleFrom<Refs>] extends [RefSubject<infer A, infer E, infer R>]
|
|
2139
|
+
? RefSubject<A, E, R>
|
|
2140
|
+
: never;
|
|
2141
|
+
}[GetTupleKind<Refs>];
|
|
2142
|
+
|
|
2143
|
+
type GetTupleKind<
|
|
2144
|
+
Refs extends ReadonlyArray<Ref>,
|
|
2145
|
+
Kind extends RefKind = "r",
|
|
2146
|
+
> = Refs extends readonly [infer Head extends Ref, ...infer Tail extends ReadonlyArray<Ref>]
|
|
2147
|
+
? GetTupleKind<Tail, MergeKind<Kind, MatchKind<Head>>>
|
|
2148
|
+
: Kind;
|
|
2149
|
+
|
|
2150
|
+
type FilteredTupleFrom<
|
|
2151
|
+
Refs extends ReadonlyArray<
|
|
2152
|
+
RefSubject<any, any, any> | Computed<any, any, any> | Filtered<any, any, any>
|
|
2153
|
+
>,
|
|
2154
|
+
> = Filtered<
|
|
2155
|
+
{
|
|
2156
|
+
readonly [K in keyof Refs]: Effect.Success<Refs[K]>;
|
|
2157
|
+
},
|
|
2158
|
+
FxError<Refs[number]>,
|
|
2159
|
+
Effect.Services<Refs[number]>
|
|
2160
|
+
>;
|
|
2161
|
+
|
|
2162
|
+
type ComputedTupleFrom<
|
|
2163
|
+
Refs extends ReadonlyArray<
|
|
2164
|
+
RefSubject<any, any, any> | Computed<any, any, any> | Filtered<any, any, any>
|
|
2165
|
+
>,
|
|
2166
|
+
> = Computed<
|
|
2167
|
+
{
|
|
2168
|
+
readonly [K in keyof Refs]: Effect.Success<Refs[K]>;
|
|
2169
|
+
},
|
|
2170
|
+
Effect.Error<Refs[number]>,
|
|
2171
|
+
Effect.Services<Refs[number]>
|
|
2172
|
+
>;
|
|
2173
|
+
|
|
2174
|
+
type RefSubjectTupleFrom<
|
|
2175
|
+
Refs extends ReadonlyArray<
|
|
2176
|
+
RefSubject<any, any, any> | Computed<any, any, any> | Filtered<any, any, any>
|
|
2177
|
+
>,
|
|
2178
|
+
> = RefSubject<
|
|
2179
|
+
{
|
|
2180
|
+
readonly [K in keyof Refs]: Effect.Success<Refs[K]>;
|
|
2181
|
+
},
|
|
2182
|
+
Effect.Error<Refs[number]>,
|
|
2183
|
+
Effect.Services<Refs[number]>
|
|
2184
|
+
>;
|
|
2185
|
+
|
|
2186
|
+
/**
|
|
2187
|
+
* Combines multiple `RefSubject`, `Computed`, or `Filtered` instances into a single struct.
|
|
2188
|
+
*
|
|
2189
|
+
* @example
|
|
2190
|
+
* ```ts
|
|
2191
|
+
* import { Effect } from "effect"
|
|
2192
|
+
* import * as RefSubject from "@typed/fx/RefSubject"
|
|
2193
|
+
*
|
|
2194
|
+
* const program = Effect.gen(function* () {
|
|
2195
|
+
* const firstName = yield* RefSubject.make("Alice")
|
|
2196
|
+
* const lastName = yield* RefSubject.make("Smith")
|
|
2197
|
+
* const age = yield* RefSubject.make(30)
|
|
2198
|
+
*
|
|
2199
|
+
* // Combine into a struct
|
|
2200
|
+
* const person = RefSubject.struct({
|
|
2201
|
+
* firstName,
|
|
2202
|
+
* lastName,
|
|
2203
|
+
* age
|
|
2204
|
+
* })
|
|
2205
|
+
*
|
|
2206
|
+
* const fullPerson = yield* person
|
|
2207
|
+
* console.log(fullPerson) // { firstName: "Alice", lastName: "Smith", age: 30 }
|
|
2208
|
+
*
|
|
2209
|
+
* // Update one field
|
|
2210
|
+
* yield* RefSubject.set(firstName, "Bob")
|
|
2211
|
+
*
|
|
2212
|
+
* // Struct automatically updates
|
|
2213
|
+
* const updated = yield* person
|
|
2214
|
+
* console.log(updated.firstName) // "Bob"
|
|
2215
|
+
* })
|
|
2216
|
+
* ```
|
|
2217
|
+
*
|
|
2218
|
+
* @since 1.0.0
|
|
2219
|
+
* @category combinators
|
|
2220
|
+
*/
|
|
2221
|
+
export function struct<
|
|
2222
|
+
const Refs extends Readonly<Record<string, RefSubject.Any | Computed.Any | Filtered.Any>>,
|
|
2223
|
+
>(refs: Refs): StructFrom<Refs> {
|
|
2224
|
+
const kind = getRefKind(Object.values(refs));
|
|
2225
|
+
switch (kind) {
|
|
2226
|
+
case "r":
|
|
2227
|
+
return makeStructRef(refs as any) as StructFrom<Refs>;
|
|
2228
|
+
case "c":
|
|
2229
|
+
return makeStructComputed(refs as any) as StructFrom<Refs>;
|
|
2230
|
+
case "f":
|
|
2231
|
+
return makeStructFiltered(refs as any) as any as StructFrom<Refs>;
|
|
2232
|
+
}
|
|
2233
|
+
}
|
|
2234
|
+
/**
|
|
2235
|
+
* Combines multiple `RefSubject`, `Computed`, or `Filtered` instances into a single tuple.
|
|
2236
|
+
*
|
|
2237
|
+
* @example
|
|
2238
|
+
* ```ts
|
|
2239
|
+
* import { Effect } from "effect"
|
|
2240
|
+
* import * as RefSubject from "@typed/fx/RefSubject"
|
|
2241
|
+
*
|
|
2242
|
+
* const program = Effect.gen(function* () {
|
|
2243
|
+
* const x = yield* RefSubject.make(10)
|
|
2244
|
+
* const y = yield* RefSubject.make(20)
|
|
2245
|
+
* const z = yield* RefSubject.make(30)
|
|
2246
|
+
*
|
|
2247
|
+
* // Combine into a tuple
|
|
2248
|
+
* const point = RefSubject.tuple([x, y, z])
|
|
2249
|
+
*
|
|
2250
|
+
* const coords = yield* point
|
|
2251
|
+
* console.log(coords) // [10, 20, 30]
|
|
2252
|
+
*
|
|
2253
|
+
* // Update one value
|
|
2254
|
+
* yield* RefSubject.set(x, 15)
|
|
2255
|
+
*
|
|
2256
|
+
* // Tuple automatically updates
|
|
2257
|
+
* const updated = yield* point
|
|
2258
|
+
* console.log(updated) // [15, 20, 30]
|
|
2259
|
+
* })
|
|
2260
|
+
* ```
|
|
2261
|
+
*
|
|
2262
|
+
* @since 1.0.0
|
|
2263
|
+
* @category combinators
|
|
2264
|
+
*/
|
|
2265
|
+
export function tuple<const Refs extends ReadonlyArray<Ref>>(refs: Refs): TupleFrom<Refs> {
|
|
2266
|
+
const kind = getRefKind(refs);
|
|
2267
|
+
switch (kind) {
|
|
2268
|
+
case "r":
|
|
2269
|
+
return makeTupleRef(refs as any) as TupleFrom<Refs>;
|
|
2270
|
+
case "c":
|
|
2271
|
+
return makeTupleComputed(refs as any) as TupleFrom<Refs>;
|
|
2272
|
+
case "f":
|
|
2273
|
+
return makeTupleFiltered(refs as any) as any as TupleFrom<Refs>;
|
|
2274
|
+
}
|
|
2275
|
+
}
|
|
2276
|
+
|
|
2277
|
+
function makeTupleRef<const Refs extends ReadonlyArray<RefSubject<any, any, any>>>(
|
|
2278
|
+
refs: Refs,
|
|
2279
|
+
): RefSubjectTupleFrom<Refs> {
|
|
2280
|
+
return new RefSubjectTuple(refs);
|
|
2281
|
+
}
|
|
2282
|
+
|
|
2283
|
+
const UNBOUNDED = { concurrency: "unbounded" } as const;
|
|
2284
|
+
|
|
2285
|
+
class RefSubjectTuple<const Refs extends ReadonlyArray<RefSubject<any, any, any>>>
|
|
2286
|
+
extends YieldableFx<
|
|
2287
|
+
{
|
|
2288
|
+
readonly [K in keyof Refs]: Effect.Success<Refs[K]>;
|
|
2289
|
+
},
|
|
2290
|
+
Effect.Error<Refs[number]>,
|
|
2291
|
+
Effect.Services<Refs[number]>,
|
|
2292
|
+
{
|
|
2293
|
+
readonly [K in keyof Refs]: Effect.Success<Refs[K]>;
|
|
2294
|
+
},
|
|
2295
|
+
Effect.Error<Refs[number]>,
|
|
2296
|
+
Effect.Services<Refs[number]>
|
|
2297
|
+
>
|
|
2298
|
+
implements RefSubjectTupleFrom<Refs>
|
|
2299
|
+
{
|
|
2300
|
+
readonly [ComputedTypeId]: ComputedTypeId = ComputedTypeId;
|
|
2301
|
+
readonly [RefSubjectTypeId]: RefSubjectTypeId = RefSubjectTypeId;
|
|
2302
|
+
|
|
2303
|
+
readonly version: Effect.Effect<
|
|
2304
|
+
number,
|
|
2305
|
+
Effect.Error<Refs[number]>,
|
|
2306
|
+
Effect.Services<Refs[number]>
|
|
2307
|
+
>;
|
|
2308
|
+
readonly interrupt: Effect.Effect<void, never, Effect.Services<Refs[number]>>;
|
|
2309
|
+
readonly subscriberCount: Effect.Effect<number, never, Effect.Services<Refs[number]>>;
|
|
2310
|
+
|
|
2311
|
+
private versioned: Versioned.Versioned<
|
|
2312
|
+
Effect.Services<Refs[number]>,
|
|
2313
|
+
Effect.Error<Refs[number]>,
|
|
2314
|
+
{ readonly [K in keyof Refs]: Effect.Success<Refs[K]> },
|
|
2315
|
+
Effect.Error<Refs[number]>,
|
|
2316
|
+
Effect.Services<Refs[number]>,
|
|
2317
|
+
{ readonly [K in keyof Refs]: Effect.Success<Refs[K]> },
|
|
2318
|
+
Effect.Error<Refs[number]>,
|
|
2319
|
+
Effect.Services<Refs[number]>
|
|
2320
|
+
>;
|
|
2321
|
+
|
|
2322
|
+
private getSetDelete: GetSetDelete<
|
|
2323
|
+
{ readonly [K in keyof Refs]: Effect.Success<Refs[K]> },
|
|
2324
|
+
Effect.Error<Refs[number]>,
|
|
2325
|
+
Effect.Services<Refs[number]>
|
|
2326
|
+
>;
|
|
2327
|
+
|
|
2328
|
+
readonly refs: Refs;
|
|
2329
|
+
|
|
2330
|
+
constructor(refs: Refs) {
|
|
2331
|
+
super();
|
|
2332
|
+
|
|
2333
|
+
this.refs = refs;
|
|
2334
|
+
this.versioned = Versioned.hold(Versioned.tuple(refs)) as any;
|
|
2335
|
+
this.version = this.versioned.version;
|
|
2336
|
+
this.interrupt = Effect.all(
|
|
2337
|
+
refs.map((r) => r.interrupt),
|
|
2338
|
+
UNBOUNDED,
|
|
2339
|
+
);
|
|
2340
|
+
this.subscriberCount = Effect.map(
|
|
2341
|
+
Effect.all(
|
|
2342
|
+
refs.map((r) => r.subscriberCount),
|
|
2343
|
+
UNBOUNDED,
|
|
2344
|
+
),
|
|
2345
|
+
Array.reduce(0, sum),
|
|
2346
|
+
);
|
|
2347
|
+
|
|
2348
|
+
this.getSetDelete = {
|
|
2349
|
+
get: this.versioned.asEffect(),
|
|
2350
|
+
set: (a) =>
|
|
2351
|
+
Effect.all(
|
|
2352
|
+
refs.map((r, i) => set(r, a[i])),
|
|
2353
|
+
UNBOUNDED,
|
|
2354
|
+
) as any,
|
|
2355
|
+
delete: Effect.map(
|
|
2356
|
+
Effect.all(
|
|
2357
|
+
refs.map((r) => reset(r)),
|
|
2358
|
+
UNBOUNDED,
|
|
2359
|
+
),
|
|
2360
|
+
Option.all,
|
|
2361
|
+
) as any,
|
|
2362
|
+
};
|
|
2363
|
+
|
|
2364
|
+
this.updates = this.updates.bind(this);
|
|
2365
|
+
this.onFailure = this.onFailure.bind(this);
|
|
2366
|
+
this.onSuccess = this.onSuccess.bind(this);
|
|
2367
|
+
}
|
|
2368
|
+
|
|
2369
|
+
run<R2 = never>(
|
|
2370
|
+
sink: Sink.Sink<
|
|
2371
|
+
{
|
|
2372
|
+
readonly [K in keyof Refs]: Effect.Success<Refs[K]>;
|
|
2373
|
+
},
|
|
2374
|
+
Effect.Error<Refs[number]>,
|
|
2375
|
+
R2
|
|
2376
|
+
>,
|
|
2377
|
+
): Effect.Effect<unknown, never, Effect.Services<Refs[number]> | R2> {
|
|
2378
|
+
return this.versioned.run(sink);
|
|
2379
|
+
}
|
|
2380
|
+
|
|
2381
|
+
override toEffect(): Effect.Effect<
|
|
2382
|
+
{ readonly [K in keyof Refs]: Effect.Success<Refs[K]> },
|
|
2383
|
+
Effect.Error<Refs[number]>,
|
|
2384
|
+
Effect.Services<Refs[number]>
|
|
2385
|
+
> {
|
|
2386
|
+
return this.versioned.asEffect();
|
|
2387
|
+
}
|
|
2388
|
+
|
|
2389
|
+
updates<E2, R2, C>(
|
|
2390
|
+
run: (
|
|
2391
|
+
ref: GetSetDelete<
|
|
2392
|
+
{
|
|
2393
|
+
readonly [K in keyof Refs]: Effect.Success<Refs[K]>;
|
|
2394
|
+
},
|
|
2395
|
+
Effect.Error<Refs[number]>,
|
|
2396
|
+
Effect.Services<Refs[number]>
|
|
2397
|
+
>,
|
|
2398
|
+
) => Effect.Effect<C, E2, R2>,
|
|
2399
|
+
) {
|
|
2400
|
+
return run(this.getSetDelete);
|
|
2401
|
+
}
|
|
2402
|
+
|
|
2403
|
+
onFailure(
|
|
2404
|
+
cause: Cause.Cause<Effect.Error<Refs[number]>>,
|
|
2405
|
+
): Effect.Effect<unknown, never, Effect.Services<Refs[number]>> {
|
|
2406
|
+
return Effect.all(this.refs.map((ref) => ref.onFailure(cause)));
|
|
2407
|
+
}
|
|
2408
|
+
|
|
2409
|
+
onSuccess(value: { readonly [K in keyof Refs]: Effect.Success<Refs[K]> }): Effect.Effect<
|
|
2410
|
+
unknown,
|
|
2411
|
+
never,
|
|
2412
|
+
Effect.Services<Refs[number]>
|
|
2413
|
+
> {
|
|
2414
|
+
return Effect.catchCause(this.getSetDelete.set(value), (c) => this.onFailure(c));
|
|
2415
|
+
}
|
|
2416
|
+
}
|
|
2417
|
+
|
|
2418
|
+
function makeTupleComputed<const Refs extends ReadonlyArray<Computed<any, any, any>>>(
|
|
2419
|
+
refs: Refs,
|
|
2420
|
+
): ComputedTupleFrom<Refs> {
|
|
2421
|
+
return new ComputedImpl(Versioned.tuple(refs) as any, Effect.succeed) as any;
|
|
2422
|
+
}
|
|
2423
|
+
|
|
2424
|
+
function makeTupleFiltered<
|
|
2425
|
+
const Refs extends ReadonlyArray<Computed<any, any, any> | Filtered<any, any, any>>,
|
|
2426
|
+
>(refs: Refs): FilteredTupleFrom<Refs> {
|
|
2427
|
+
return new FilteredImpl(Versioned.tuple(refs) as any, Effect.succeedSome) as any;
|
|
2428
|
+
}
|
|
2429
|
+
|
|
2430
|
+
function makeStructRef<const Refs extends Readonly<Record<string, RefSubject.Any>>>(
|
|
2431
|
+
refs: Refs,
|
|
2432
|
+
): RefSubjectStructFrom<Refs> {
|
|
2433
|
+
return new RefSubjectStruct(refs) as any;
|
|
2434
|
+
}
|
|
2435
|
+
|
|
2436
|
+
class RefSubjectStruct<const Refs extends Readonly<Record<string, RefSubject.Any>>>
|
|
2437
|
+
extends YieldableFx<
|
|
2438
|
+
{
|
|
2439
|
+
readonly [K in keyof Refs]: Success<Refs[K]>;
|
|
2440
|
+
},
|
|
2441
|
+
Error<Refs[keyof Refs]>,
|
|
2442
|
+
Services<Refs[keyof Refs]> | Scope.Scope,
|
|
2443
|
+
{
|
|
2444
|
+
readonly [K in keyof Refs]: Success<Refs[K]>;
|
|
2445
|
+
},
|
|
2446
|
+
Error<Refs[keyof Refs]>,
|
|
2447
|
+
Services<Refs[keyof Refs]>
|
|
2448
|
+
>
|
|
2449
|
+
implements
|
|
2450
|
+
RefSubject<
|
|
2451
|
+
{
|
|
2452
|
+
readonly [K in keyof Refs]: Success<Refs[K]>;
|
|
2453
|
+
},
|
|
2454
|
+
Error<Refs[keyof Refs]>,
|
|
2455
|
+
Services<Refs[keyof Refs]>
|
|
2456
|
+
>
|
|
2457
|
+
{
|
|
2458
|
+
readonly [ComputedTypeId]: ComputedTypeId = ComputedTypeId;
|
|
2459
|
+
readonly [RefSubjectTypeId]: RefSubjectTypeId = RefSubjectTypeId;
|
|
2460
|
+
|
|
2461
|
+
readonly version: Effect.Effect<number, Error<Refs[keyof Refs]>, Services<Refs[keyof Refs]>>;
|
|
2462
|
+
readonly interrupt: Effect.Effect<void, never, Services<Refs[keyof Refs]>>;
|
|
2463
|
+
readonly subscriberCount: Effect.Effect<number, never, Services<Refs[keyof Refs]>>;
|
|
2464
|
+
|
|
2465
|
+
private versioned: Versioned.Versioned<
|
|
2466
|
+
Services<Refs[keyof Refs]>,
|
|
2467
|
+
Error<Refs[keyof Refs]>,
|
|
2468
|
+
{ readonly [K in keyof Refs]: Success<Refs[K]> },
|
|
2469
|
+
Error<Refs[keyof Refs]>,
|
|
2470
|
+
Services<Refs[keyof Refs]>,
|
|
2471
|
+
{ readonly [K in keyof Refs]: Success<Refs[K]> },
|
|
2472
|
+
Error<Refs[keyof Refs]>,
|
|
2473
|
+
Services<Refs[keyof Refs]>
|
|
2474
|
+
>;
|
|
2475
|
+
|
|
2476
|
+
private getSetDelete: GetSetDelete<
|
|
2477
|
+
{ readonly [K in keyof Refs]: Success<Refs[K]> },
|
|
2478
|
+
Error<Refs[keyof Refs]>,
|
|
2479
|
+
Services<Refs[keyof Refs]>
|
|
2480
|
+
>;
|
|
2481
|
+
|
|
2482
|
+
readonly refs: Refs;
|
|
2483
|
+
|
|
2484
|
+
constructor(refs: Refs) {
|
|
2485
|
+
super();
|
|
2486
|
+
|
|
2487
|
+
this.refs = refs;
|
|
2488
|
+
this.versioned = Versioned.hold(Versioned.struct(refs)) as any;
|
|
2489
|
+
this.version = this.versioned.version;
|
|
2490
|
+
this.interrupt = Effect.all(
|
|
2491
|
+
Object.values(refs).map((r) => r.interrupt),
|
|
2492
|
+
UNBOUNDED,
|
|
2493
|
+
);
|
|
2494
|
+
this.subscriberCount = Effect.map(
|
|
2495
|
+
Effect.all(
|
|
2496
|
+
Object.values(refs).map((r) => r.subscriberCount),
|
|
2497
|
+
UNBOUNDED,
|
|
2498
|
+
),
|
|
2499
|
+
Array.reduce(0, sum),
|
|
2500
|
+
);
|
|
2501
|
+
|
|
2502
|
+
this.getSetDelete = {
|
|
2503
|
+
get: this.versioned.asEffect(),
|
|
2504
|
+
set: (a) =>
|
|
2505
|
+
Effect.all(
|
|
2506
|
+
Object.keys(refs).map((k) => set(refs[k] as any, a[k])),
|
|
2507
|
+
UNBOUNDED,
|
|
2508
|
+
) as any,
|
|
2509
|
+
delete: Effect.map(
|
|
2510
|
+
Effect.all(
|
|
2511
|
+
Object.values(refs).map((r) => reset(r as any)),
|
|
2512
|
+
UNBOUNDED,
|
|
2513
|
+
),
|
|
2514
|
+
Option.all,
|
|
2515
|
+
) as any,
|
|
2516
|
+
};
|
|
2517
|
+
|
|
2518
|
+
this.updates = this.updates.bind(this);
|
|
2519
|
+
this.onFailure = this.onFailure.bind(this);
|
|
2520
|
+
this.onSuccess = this.onSuccess.bind(this);
|
|
2521
|
+
}
|
|
2522
|
+
|
|
2523
|
+
run<R3 = never>(
|
|
2524
|
+
sink: Sink.Sink<{ readonly [K in keyof Refs]: Success<Refs[K]> }, Error<Refs[keyof Refs]>, R3>,
|
|
2525
|
+
): Effect.Effect<unknown, never, Services<Refs[keyof Refs]> | Scope.Scope | R3> {
|
|
2526
|
+
return this.versioned.run(sink as any) as any;
|
|
2527
|
+
}
|
|
2528
|
+
|
|
2529
|
+
toEffect() {
|
|
2530
|
+
return this.versioned.asEffect();
|
|
2531
|
+
}
|
|
2532
|
+
|
|
2533
|
+
updates<E2, R2, C>(
|
|
2534
|
+
run: (
|
|
2535
|
+
ref: GetSetDelete<
|
|
2536
|
+
{
|
|
2537
|
+
readonly [K in keyof Refs]: Success<Refs[K]>;
|
|
2538
|
+
},
|
|
2539
|
+
Error<Refs[keyof Refs]>,
|
|
2540
|
+
Services<Refs[keyof Refs]>
|
|
2541
|
+
>,
|
|
2542
|
+
) => Effect.Effect<C, E2, R2>,
|
|
2543
|
+
) {
|
|
2544
|
+
return run(this.getSetDelete);
|
|
2545
|
+
}
|
|
2546
|
+
|
|
2547
|
+
onFailure(
|
|
2548
|
+
cause: Cause.Cause<Error<Refs[keyof Refs]>>,
|
|
2549
|
+
): Effect.Effect<unknown, never, Services<Refs[keyof Refs]>> {
|
|
2550
|
+
return Effect.all(Object.values(this.refs).map((ref) => ref.onFailure(cause as any)));
|
|
2551
|
+
}
|
|
2552
|
+
|
|
2553
|
+
onSuccess(value: { readonly [K in keyof Refs]: Success<Refs[K]> }): Effect.Effect<
|
|
2554
|
+
unknown,
|
|
2555
|
+
never,
|
|
2556
|
+
Services<Refs[keyof Refs]>
|
|
2557
|
+
> {
|
|
2558
|
+
return Effect.catchCause(this.getSetDelete.set(value), (c) => this.onFailure(c));
|
|
2559
|
+
}
|
|
2560
|
+
}
|
|
2561
|
+
|
|
2562
|
+
function makeStructComputed<const Refs extends Readonly<Record<string, Computed<any, any, any>>>>(
|
|
2563
|
+
refs: Refs,
|
|
2564
|
+
): ComputedStructFrom<Refs> {
|
|
2565
|
+
return new ComputedImpl(Versioned.struct(refs) as any, Effect.succeed) as any;
|
|
2566
|
+
}
|
|
2567
|
+
|
|
2568
|
+
function makeStructFiltered<
|
|
2569
|
+
const Refs extends Readonly<Record<string, Computed<any, any, any> | Filtered<any, any, any>>>,
|
|
2570
|
+
>(refs: Refs): FilteredStructFrom<Refs> {
|
|
2571
|
+
return new FilteredImpl(Versioned.struct(refs) as any, Effect.succeedSome) as any;
|
|
2572
|
+
}
|
|
2573
|
+
|
|
2574
|
+
export function computedFromService<R, A, E, R2>(
|
|
2575
|
+
effect: Effect.Effect<Computed<A, E, R2>, never, R>,
|
|
2576
|
+
): Computed<A, E, R | R2> {
|
|
2577
|
+
return new ComputedFromService(effect);
|
|
2578
|
+
}
|
|
2579
|
+
|
|
2580
|
+
class ComputedFromService<R, A, E, R2>
|
|
2581
|
+
extends YieldableFx<A, E, R | R2 | Scope.Scope, A, E, R | R2>
|
|
2582
|
+
implements Computed<A, E, R | R2>
|
|
2583
|
+
{
|
|
2584
|
+
readonly [ComputedTypeId]: ComputedTypeId = ComputedTypeId;
|
|
2585
|
+
|
|
2586
|
+
private readonly effect: Effect.Effect<Computed<A, E, R2>, never, R>;
|
|
2587
|
+
readonly version: Effect.Effect<number, E, R | R2>;
|
|
2588
|
+
readonly interrupt: Effect.Effect<void, never, R | R2>;
|
|
2589
|
+
|
|
2590
|
+
constructor(effect: Effect.Effect<Computed<A, E, R2>, never, R>) {
|
|
2591
|
+
super();
|
|
2592
|
+
this.effect = effect;
|
|
2593
|
+
this.version = Effect.flatMap(this.effect, (c) => c.version);
|
|
2594
|
+
this.interrupt = Effect.flatMap(this.effect, (c) => c.interrupt);
|
|
2595
|
+
}
|
|
2596
|
+
|
|
2597
|
+
run<RSink>(
|
|
2598
|
+
sink: Sink.Sink<A, E, RSink>,
|
|
2599
|
+
): Effect.Effect<unknown, never, R | R2 | RSink | Scope.Scope> {
|
|
2600
|
+
return Effect.flatMap(this.effect, (c) => c.run(sink));
|
|
2601
|
+
}
|
|
2602
|
+
|
|
2603
|
+
toEffect(): Effect.Effect<A, E, R | R2> {
|
|
2604
|
+
return Effect.flatMap(this.effect, (c) => c.asEffect());
|
|
2605
|
+
}
|
|
2606
|
+
}
|
|
2607
|
+
|
|
2608
|
+
export function filteredFromService<R, A, E, R2>(
|
|
2609
|
+
effect: Effect.Effect<Filtered<A, E, R2>, never, R>,
|
|
2610
|
+
): Filtered<A, E, R | R2> {
|
|
2611
|
+
return new FilteredFromService(effect);
|
|
2612
|
+
}
|
|
2613
|
+
|
|
2614
|
+
class FilteredFromService<R, A, E, R2>
|
|
2615
|
+
extends YieldableFx<A, E, R | R2 | Scope.Scope, A, E | Cause.NoSuchElementError, R | R2>
|
|
2616
|
+
implements Filtered<A, E, R | R2>
|
|
2617
|
+
{
|
|
2618
|
+
readonly [FilteredTypeId]: FilteredTypeId = FilteredTypeId;
|
|
2619
|
+
|
|
2620
|
+
private readonly effect: Effect.Effect<Filtered<A, E, R2>, never, R>;
|
|
2621
|
+
readonly version: Effect.Effect<number, E, R | R2>;
|
|
2622
|
+
readonly interrupt: Effect.Effect<void, never, R | R2>;
|
|
2623
|
+
|
|
2624
|
+
constructor(effect: Effect.Effect<Filtered<A, E, R2>, never, R>) {
|
|
2625
|
+
super();
|
|
2626
|
+
this.effect = effect;
|
|
2627
|
+
this.version = Effect.flatMap(this.effect, (c) => c.version);
|
|
2628
|
+
this.interrupt = Effect.flatMap(this.effect, (c) => c.interrupt);
|
|
2629
|
+
}
|
|
2630
|
+
|
|
2631
|
+
run<RSink>(
|
|
2632
|
+
sink: Sink.Sink<A, E, RSink>,
|
|
2633
|
+
): Effect.Effect<unknown, never, R | R2 | RSink | Scope.Scope> {
|
|
2634
|
+
return Effect.flatMap(this.effect, (c) => c.run(sink));
|
|
2635
|
+
}
|
|
2636
|
+
|
|
2637
|
+
toEffect(): Effect.Effect<A, E | Cause.NoSuchElementError, R | R2> {
|
|
2638
|
+
return Effect.flatMap(this.effect, (c) => c.asEffect());
|
|
2639
|
+
}
|
|
2640
|
+
|
|
2641
|
+
asComputed(): Computed<Option.Option<A>, E, R | R2> {
|
|
2642
|
+
return computedFromService<R, Option.Option<A>, E, R2>(
|
|
2643
|
+
Effect.map(this.effect, (c) => c.asComputed()),
|
|
2644
|
+
);
|
|
2645
|
+
}
|
|
2646
|
+
}
|