synstate 0.1.1 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +317 -298
- package/dist/core/class/child-observable-class.d.mts.map +1 -1
- package/dist/core/class/child-observable-class.mjs +43 -10
- package/dist/core/class/child-observable-class.mjs.map +1 -1
- package/dist/core/class/observable-base-class.d.mts +4 -4
- package/dist/core/class/observable-base-class.d.mts.map +1 -1
- package/dist/core/class/observable-base-class.mjs +8 -8
- package/dist/core/class/observable-base-class.mjs.map +1 -1
- package/dist/core/class/root-observable-class.d.mts +1 -1
- package/dist/core/class/root-observable-class.d.mts.map +1 -1
- package/dist/core/class/root-observable-class.mjs +9 -9
- package/dist/core/class/root-observable-class.mjs.map +1 -1
- package/dist/core/combine/combine.d.mts +7 -7
- package/dist/core/combine/combine.mjs +13 -14
- package/dist/core/combine/combine.mjs.map +1 -1
- package/dist/core/combine/merge.d.mts +6 -6
- package/dist/core/combine/merge.mjs +9 -9
- package/dist/core/combine/merge.mjs.map +1 -1
- package/dist/core/combine/zip.d.mts +20 -19
- package/dist/core/combine/zip.d.mts.map +1 -1
- package/dist/core/combine/zip.mjs +22 -21
- package/dist/core/combine/zip.mjs.map +1 -1
- package/dist/core/create/{interval.d.mts → counter.d.mts} +14 -12
- package/dist/core/create/counter.d.mts.map +1 -0
- package/dist/core/create/{interval.mjs → counter.mjs} +21 -23
- package/dist/core/create/counter.mjs.map +1 -0
- package/dist/core/create/from-abortable-promise.d.mts +29 -0
- package/dist/core/create/from-abortable-promise.d.mts.map +1 -0
- package/dist/core/create/from-abortable-promise.mjs +70 -0
- package/dist/core/create/from-abortable-promise.mjs.map +1 -0
- package/dist/core/create/from-promise.d.mts +9 -6
- package/dist/core/create/from-promise.d.mts.map +1 -1
- package/dist/core/create/from-promise.mjs +8 -5
- package/dist/core/create/from-promise.mjs.map +1 -1
- package/dist/core/create/from-subscribable.d.mts +4 -4
- package/dist/core/create/from-subscribable.mjs +4 -4
- package/dist/core/create/index.d.mts +3 -3
- package/dist/core/create/index.d.mts.map +1 -1
- package/dist/core/create/index.mjs +4 -4
- package/dist/core/create/just.d.mts +32 -0
- package/dist/core/create/just.d.mts.map +1 -0
- package/dist/core/create/just.mjs +44 -0
- package/dist/core/create/just.mjs.map +1 -0
- package/dist/core/create/source.d.mts +7 -12
- package/dist/core/create/source.d.mts.map +1 -1
- package/dist/core/create/source.mjs +1 -6
- package/dist/core/create/source.mjs.map +1 -1
- package/dist/core/create/timer.d.mts +6 -4
- package/dist/core/create/timer.d.mts.map +1 -1
- package/dist/core/create/timer.mjs +6 -7
- package/dist/core/create/timer.mjs.map +1 -1
- package/dist/core/index.d.mts +1 -1
- package/dist/core/index.d.mts.map +1 -1
- package/dist/core/index.mjs +21 -14
- package/dist/core/index.mjs.map +1 -1
- package/dist/core/operators/audit.d.mts +97 -0
- package/dist/core/operators/audit.d.mts.map +1 -0
- package/dist/core/operators/audit.mjs +144 -0
- package/dist/core/operators/audit.mjs.map +1 -0
- package/dist/core/operators/debounce.d.mts +88 -0
- package/dist/core/operators/debounce.d.mts.map +1 -0
- package/dist/core/operators/debounce.mjs +130 -0
- package/dist/core/operators/debounce.mjs.map +1 -0
- package/dist/core/operators/filter.d.mts +5 -5
- package/dist/core/operators/filter.mjs +3 -3
- package/dist/core/operators/filter.mjs.map +1 -1
- package/dist/core/operators/index.d.mts +4 -4
- package/dist/core/operators/index.d.mts.map +1 -1
- package/dist/core/operators/index.mjs +6 -6
- package/dist/core/operators/map.d.mts +41 -0
- package/dist/core/operators/map.d.mts.map +1 -0
- package/dist/core/operators/map.mjs +71 -0
- package/dist/core/operators/map.mjs.map +1 -0
- package/dist/core/operators/merge-map.d.mts +57 -30
- package/dist/core/operators/merge-map.d.mts.map +1 -1
- package/dist/core/operators/merge-map.mjs +59 -32
- package/dist/core/operators/merge-map.mjs.map +1 -1
- package/dist/core/operators/pairwise.d.mts +6 -6
- package/dist/core/operators/pairwise.mjs +9 -9
- package/dist/core/operators/pairwise.mjs.map +1 -1
- package/dist/core/operators/scan.d.mts +6 -6
- package/dist/core/operators/scan.mjs +9 -9
- package/dist/core/operators/scan.mjs.map +1 -1
- package/dist/core/operators/skip-if-no-change.d.mts +21 -9
- package/dist/core/operators/skip-if-no-change.d.mts.map +1 -1
- package/dist/core/operators/skip-if-no-change.mjs +25 -13
- package/dist/core/operators/skip-if-no-change.mjs.map +1 -1
- package/dist/core/operators/skip-until.d.mts +5 -5
- package/dist/core/operators/skip-until.mjs +8 -8
- package/dist/core/operators/skip-until.mjs.map +1 -1
- package/dist/core/operators/skip-while.d.mts +18 -9
- package/dist/core/operators/skip-while.d.mts.map +1 -1
- package/dist/core/operators/skip-while.mjs +28 -16
- package/dist/core/operators/skip-while.mjs.map +1 -1
- package/dist/core/operators/switch-map.d.mts +57 -26
- package/dist/core/operators/switch-map.d.mts.map +1 -1
- package/dist/core/operators/switch-map.mjs +59 -28
- package/dist/core/operators/switch-map.mjs.map +1 -1
- package/dist/core/operators/take-until.d.mts +5 -5
- package/dist/core/operators/take-until.mjs +8 -8
- package/dist/core/operators/take-until.mjs.map +1 -1
- package/dist/core/operators/take-while.d.mts +15 -8
- package/dist/core/operators/take-while.d.mts.map +1 -1
- package/dist/core/operators/take-while.mjs +19 -13
- package/dist/core/operators/take-while.mjs.map +1 -1
- package/dist/core/operators/throttle.d.mts +81 -0
- package/dist/core/operators/throttle.d.mts.map +1 -0
- package/dist/core/operators/throttle.mjs +126 -0
- package/dist/core/operators/throttle.mjs.map +1 -0
- package/dist/core/operators/with-buffered-from.d.mts +13 -9
- package/dist/core/operators/with-buffered-from.d.mts.map +1 -1
- package/dist/core/operators/with-buffered-from.mjs +17 -13
- package/dist/core/operators/with-buffered-from.mjs.map +1 -1
- package/dist/core/operators/with-current-value-from.d.mts +14 -9
- package/dist/core/operators/with-current-value-from.d.mts.map +1 -1
- package/dist/core/operators/with-current-value-from.mjs +18 -13
- package/dist/core/operators/with-current-value-from.mjs.map +1 -1
- package/dist/core/operators/with-initial-value.d.mts +5 -5
- package/dist/core/operators/with-initial-value.mjs +8 -8
- package/dist/core/operators/with-initial-value.mjs.map +1 -1
- package/dist/core/predefined/index.d.mts +2 -0
- package/dist/core/predefined/index.d.mts.map +1 -0
- package/dist/core/predefined/index.mjs +12 -0
- package/dist/core/predefined/index.mjs.map +1 -0
- package/dist/core/predefined/operators/attach-index.d.mts +57 -0
- package/dist/core/predefined/operators/attach-index.d.mts.map +1 -0
- package/dist/core/predefined/operators/attach-index.mjs +62 -0
- package/dist/core/predefined/operators/attach-index.mjs.map +1 -0
- package/dist/core/predefined/operators/index.d.mts +12 -0
- package/dist/core/predefined/operators/index.d.mts.map +1 -0
- package/dist/core/predefined/operators/index.mjs +12 -0
- package/dist/core/predefined/operators/index.mjs.map +1 -0
- package/dist/core/predefined/operators/map-optional.d.mts +51 -0
- package/dist/core/predefined/operators/map-optional.d.mts.map +1 -0
- package/dist/core/predefined/operators/map-optional.mjs +55 -0
- package/dist/core/predefined/operators/map-optional.mjs.map +1 -0
- package/dist/core/predefined/operators/map-result-err.d.mts +51 -0
- package/dist/core/predefined/operators/map-result-err.d.mts.map +1 -0
- package/dist/core/predefined/operators/map-result-err.mjs +55 -0
- package/dist/core/predefined/operators/map-result-err.mjs.map +1 -0
- package/dist/core/predefined/operators/map-result-ok.d.mts +51 -0
- package/dist/core/predefined/operators/map-result-ok.d.mts.map +1 -0
- package/dist/core/predefined/operators/map-result-ok.mjs +55 -0
- package/dist/core/predefined/operators/map-result-ok.mjs.map +1 -0
- package/dist/core/predefined/operators/map-to.d.mts +43 -0
- package/dist/core/predefined/operators/map-to.d.mts.map +1 -0
- package/dist/core/predefined/operators/map-to.mjs +48 -0
- package/dist/core/predefined/operators/map-to.mjs.map +1 -0
- package/dist/core/predefined/operators/pluck.d.mts +47 -0
- package/dist/core/predefined/operators/pluck.d.mts.map +1 -0
- package/dist/core/predefined/operators/pluck.mjs +52 -0
- package/dist/core/predefined/operators/pluck.mjs.map +1 -0
- package/dist/core/predefined/operators/skip.d.mts +50 -0
- package/dist/core/predefined/operators/skip.d.mts.map +1 -0
- package/dist/core/predefined/operators/skip.mjs +56 -0
- package/dist/core/predefined/operators/skip.mjs.map +1 -0
- package/dist/core/predefined/operators/take.d.mts +44 -0
- package/dist/core/predefined/operators/take.d.mts.map +1 -0
- package/dist/core/predefined/operators/take.mjs +49 -0
- package/dist/core/predefined/operators/take.mjs.map +1 -0
- package/dist/core/predefined/operators/unwrap-optional.d.mts +44 -0
- package/dist/core/predefined/operators/unwrap-optional.d.mts.map +1 -0
- package/dist/core/predefined/operators/unwrap-optional.mjs +50 -0
- package/dist/core/predefined/operators/unwrap-optional.mjs.map +1 -0
- package/dist/core/predefined/operators/unwrap-result-err.d.mts +44 -0
- package/dist/core/predefined/operators/unwrap-result-err.d.mts.map +1 -0
- package/dist/core/predefined/operators/unwrap-result-err.mjs +48 -0
- package/dist/core/predefined/operators/unwrap-result-err.mjs.map +1 -0
- package/dist/core/predefined/operators/unwrap-result-ok.d.mts +44 -0
- package/dist/core/predefined/operators/unwrap-result-ok.d.mts.map +1 -0
- package/dist/core/predefined/operators/unwrap-result-ok.mjs +50 -0
- package/dist/core/predefined/operators/unwrap-result-ok.mjs.map +1 -0
- package/dist/core/types/id.d.mts +1 -1
- package/dist/core/types/id.d.mts.map +1 -1
- package/dist/core/types/index.d.mts +1 -0
- package/dist/core/types/index.d.mts.map +1 -1
- package/dist/core/types/observable-family.d.mts +8 -14
- package/dist/core/types/observable-family.d.mts.map +1 -1
- package/dist/core/types/observable.d.mts +3 -3
- package/dist/core/types/observable.d.mts.map +1 -1
- package/dist/core/types/timer.d.mts +2 -0
- package/dist/core/types/timer.d.mts.map +1 -0
- package/dist/core/types/timer.mjs +2 -0
- package/dist/core/types/timer.mjs.map +1 -0
- package/dist/core/utils/id-maker.d.mts +2 -2
- package/dist/core/utils/id-maker.d.mts.map +1 -1
- package/dist/core/utils/id-maker.mjs +3 -3
- package/dist/core/utils/id-maker.mjs.map +1 -1
- package/dist/core/utils/index.mjs +1 -1
- package/dist/entry-point.mjs +24 -15
- package/dist/entry-point.mjs.map +1 -1
- package/dist/globals.d.mts +0 -3
- package/dist/index.mjs +24 -15
- package/dist/index.mjs.map +1 -1
- package/dist/utils/collect-to-array.d.mts +3 -0
- package/dist/utils/collect-to-array.d.mts.map +1 -0
- package/dist/utils/collect-to-array.mjs +11 -0
- package/dist/utils/collect-to-array.mjs.map +1 -0
- package/dist/utils/create-boolean-state.d.mts +40 -0
- package/dist/utils/create-boolean-state.d.mts.map +1 -0
- package/dist/utils/create-boolean-state.mjs +53 -0
- package/dist/utils/create-boolean-state.mjs.map +1 -0
- package/dist/utils/create-event-emitter.d.mts +4 -4
- package/dist/utils/create-event-emitter.mjs +4 -4
- package/dist/utils/create-reducer.d.mts +10 -7
- package/dist/utils/create-reducer.d.mts.map +1 -1
- package/dist/utils/create-reducer.mjs +7 -7
- package/dist/utils/create-reducer.mjs.map +1 -1
- package/dist/utils/create-state.d.mts +8 -48
- package/dist/utils/create-state.d.mts.map +1 -1
- package/dist/utils/create-state.mjs +10 -60
- package/dist/utils/create-state.mjs.map +1 -1
- package/dist/utils/index.d.mts +2 -0
- package/dist/utils/index.d.mts.map +1 -1
- package/dist/utils/index.mjs +3 -1
- package/dist/utils/index.mjs.map +1 -1
- package/package.json +17 -11
- package/src/core/class/child-observable-class.mts +65 -9
- package/src/core/class/circular-dependency-comparison.test.mts +142 -0
- package/src/core/class/circular-dependency.test.mts +251 -0
- package/src/core/class/observable-base-class.mts +9 -9
- package/src/core/class/root-observable-class.mts +14 -10
- package/src/core/combine/combine.mts +15 -15
- package/src/core/combine/merge.mts +13 -14
- package/src/core/combine/zip.mts +26 -25
- package/src/core/create/{interval.mts → counter.mts} +32 -30
- package/src/core/create/from-abortable-promise.mts +83 -0
- package/src/core/create/from-promise.mts +10 -7
- package/src/core/create/from-subscribable.mts +4 -4
- package/src/core/create/index.mts +3 -3
- package/src/core/create/just.mts +43 -0
- package/src/core/create/source.mts +10 -14
- package/src/core/create/timer.mts +12 -11
- package/src/core/index.mts +1 -1
- package/src/core/operators/audit.mts +172 -0
- package/src/core/operators/debounce.mts +154 -0
- package/src/core/operators/filter.mts +9 -9
- package/src/core/operators/index.mts +4 -4
- package/src/core/operators/map.mts +124 -0
- package/src/core/operators/merge-map.mts +60 -33
- package/src/core/operators/pairwise.mts +10 -10
- package/src/core/operators/scan.mts +10 -10
- package/src/core/operators/skip-if-no-change.mts +26 -14
- package/src/core/operators/skip-until.mts +9 -9
- package/src/core/operators/skip-while.mts +30 -28
- package/src/core/operators/switch-map.mts +60 -29
- package/src/core/operators/take-until.mts +9 -9
- package/src/core/operators/take-while.mts +21 -19
- package/src/core/operators/{throttle-time.mts → throttle.mts} +58 -38
- package/src/core/operators/with-buffered-from.mts +18 -14
- package/src/core/operators/with-current-value-from.mts +19 -14
- package/src/core/operators/with-initial-value.mts +9 -9
- package/src/core/predefined/index.mts +1 -0
- package/src/core/predefined/operators/attach-index.mts +62 -0
- package/src/core/predefined/operators/index.mts +11 -0
- package/src/core/predefined/operators/map-optional.mts +55 -0
- package/src/core/predefined/operators/map-result-err.mts +55 -0
- package/src/core/predefined/operators/map-result-ok.mts +55 -0
- package/src/core/predefined/operators/map-to.mts +45 -0
- package/src/core/predefined/operators/pluck.mts +51 -0
- package/src/core/predefined/operators/skip.mts +57 -0
- package/src/core/predefined/operators/take.mts +47 -0
- package/src/core/predefined/operators/unwrap-optional.mts +49 -0
- package/src/core/predefined/operators/unwrap-result-err.mts +48 -0
- package/src/core/predefined/operators/unwrap-result-ok.mts +49 -0
- package/src/core/types/id.mts +1 -1
- package/src/core/types/index.mts +1 -0
- package/src/core/types/observable-family.mts +8 -24
- package/src/core/types/observable.mts +3 -3
- package/src/core/types/timer.mts +2 -0
- package/src/core/utils/id-maker.mts +4 -4
- package/src/globals.d.mts +0 -3
- package/src/utils/collect-to-array.mts +17 -0
- package/src/utils/create-boolean-state.mts +68 -0
- package/src/utils/create-event-emitter.mts +4 -4
- package/src/utils/create-reducer.mts +11 -8
- package/src/utils/create-state.mts +10 -75
- package/src/utils/index.mts +2 -0
- package/dist/core/create/from-array.d.mts +0 -39
- package/dist/core/create/from-array.d.mts.map +0 -1
- package/dist/core/create/from-array.mjs +0 -65
- package/dist/core/create/from-array.mjs.map +0 -1
- package/dist/core/create/interval.d.mts.map +0 -1
- package/dist/core/create/interval.mjs.map +0 -1
- package/dist/core/create/of.d.mts +0 -39
- package/dist/core/create/of.d.mts.map +0 -1
- package/dist/core/create/of.mjs +0 -63
- package/dist/core/create/of.mjs.map +0 -1
- package/dist/core/operators/audit-time.d.mts +0 -62
- package/dist/core/operators/audit-time.d.mts.map +0 -1
- package/dist/core/operators/audit-time.mjs +0 -109
- package/dist/core/operators/audit-time.mjs.map +0 -1
- package/dist/core/operators/debounce-time.d.mts +0 -51
- package/dist/core/operators/debounce-time.d.mts.map +0 -1
- package/dist/core/operators/debounce-time.mjs +0 -93
- package/dist/core/operators/debounce-time.mjs.map +0 -1
- package/dist/core/operators/map-with-index.d.mts +0 -54
- package/dist/core/operators/map-with-index.d.mts.map +0 -1
- package/dist/core/operators/map-with-index.mjs +0 -88
- package/dist/core/operators/map-with-index.mjs.map +0 -1
- package/dist/core/operators/throttle-time.d.mts +0 -62
- package/dist/core/operators/throttle-time.d.mts.map +0 -1
- package/dist/core/operators/throttle-time.mjs +0 -107
- package/dist/core/operators/throttle-time.mjs.map +0 -1
- package/src/core/create/from-array.mts +0 -76
- package/src/core/create/of.mts +0 -73
- package/src/core/operators/audit-time.mts +0 -136
- package/src/core/operators/debounce-time.mts +0 -116
- package/src/core/operators/map-with-index.mts +0 -183
|
@@ -3,8 +3,9 @@ import { SyncChildObservableClass } from '../class/index.mjs';
|
|
|
3
3
|
import {
|
|
4
4
|
type KeepInitialValueOperator,
|
|
5
5
|
type Observable,
|
|
6
|
-
type
|
|
7
|
-
type
|
|
6
|
+
type ThrottleOperatorObservable,
|
|
7
|
+
type TimerId,
|
|
8
|
+
type UpdateToken,
|
|
8
9
|
} from '../types/index.mjs';
|
|
9
10
|
|
|
10
11
|
/**
|
|
@@ -17,68 +18,87 @@ import {
|
|
|
17
18
|
*
|
|
18
19
|
* @example
|
|
19
20
|
* ```ts
|
|
20
|
-
* // Timeline (
|
|
21
|
+
* // Timeline (250ms throttle):
|
|
21
22
|
* //
|
|
22
|
-
* // Time(
|
|
23
|
-
* //
|
|
24
|
-
* //
|
|
25
|
-
* //
|
|
23
|
+
* // Time(x50ms) 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0
|
|
24
|
+
* //
|
|
25
|
+
* // input$ 0 2 3 9 10 11 12 13 14
|
|
26
|
+
* // |- 250ms -> |- 250ms -> |- 250ms -> |- 250ms ->
|
|
27
|
+
* // throttled$ 0 3 9 12 (emitted at start of window)
|
|
26
28
|
* //
|
|
27
29
|
* // Explanation:
|
|
28
|
-
* // -
|
|
29
|
-
* // for the specified duration (
|
|
30
|
-
* // -
|
|
31
|
-
* // -
|
|
32
|
-
* // - At 1000ms: e5 is emitted (1000ms has passed since e1)
|
|
33
|
-
* // - At 1100-1200ms: e6, e7 are ignored
|
|
34
|
-
* // - At 2000ms: e8 is emitted (1000ms has passed since e5)
|
|
30
|
+
* // - throttle emits the FIRST value received, then ignores subsequent values
|
|
31
|
+
* // for the specified duration (250ms)
|
|
32
|
+
* // - Unlike audit (which emits the LAST value), throttle emits the FIRST
|
|
33
|
+
* // - Useful for rate-limiting scroll/resize events
|
|
35
34
|
*
|
|
36
|
-
* const
|
|
35
|
+
* const input$ = source<number>();
|
|
37
36
|
*
|
|
38
|
-
* const throttled$ =
|
|
37
|
+
* const throttled$ = input$.pipe(throttle(250));
|
|
39
38
|
*
|
|
40
|
-
* const
|
|
39
|
+
* const valueHistory: number[] = [];
|
|
41
40
|
*
|
|
42
41
|
* throttled$.subscribe((value) => {
|
|
43
|
-
*
|
|
42
|
+
* valueHistory.push(value);
|
|
44
43
|
* });
|
|
45
44
|
*
|
|
46
|
-
*
|
|
45
|
+
* const sleep = (ms: number): Promise<void> =>
|
|
46
|
+
* new Promise((resolve) => {
|
|
47
|
+
* setTimeout(resolve, ms);
|
|
48
|
+
* });
|
|
47
49
|
*
|
|
48
|
-
*
|
|
50
|
+
* input$.next(0);
|
|
49
51
|
*
|
|
50
|
-
*
|
|
51
|
-
* setTimeout(resolve, 50);
|
|
52
|
-
* });
|
|
52
|
+
* assert.deepStrictEqual(valueHistory, [0]);
|
|
53
53
|
*
|
|
54
|
-
*
|
|
54
|
+
* await sleep(200);
|
|
55
55
|
*
|
|
56
|
-
*
|
|
56
|
+
* input$.next(2);
|
|
57
57
|
*
|
|
58
|
-
* assert.deepStrictEqual(
|
|
58
|
+
* assert.deepStrictEqual(valueHistory, [0]);
|
|
59
59
|
*
|
|
60
|
-
* await
|
|
61
|
-
*
|
|
62
|
-
*
|
|
60
|
+
* await sleep(100);
|
|
61
|
+
*
|
|
62
|
+
* input$.next(3);
|
|
63
|
+
*
|
|
64
|
+
* assert.deepStrictEqual(valueHistory, [0, 3]);
|
|
65
|
+
*
|
|
66
|
+
* await sleep(300);
|
|
67
|
+
*
|
|
68
|
+
* input$.next(9);
|
|
69
|
+
*
|
|
70
|
+
* assert.deepStrictEqual(valueHistory, [0, 3, 9]);
|
|
71
|
+
*
|
|
72
|
+
* await sleep(100);
|
|
73
|
+
*
|
|
74
|
+
* input$.next(10);
|
|
75
|
+
*
|
|
76
|
+
* await sleep(100);
|
|
77
|
+
*
|
|
78
|
+
* input$.next(11);
|
|
79
|
+
*
|
|
80
|
+
* assert.deepStrictEqual(valueHistory, [0, 3, 9]);
|
|
81
|
+
*
|
|
82
|
+
* await sleep(100);
|
|
63
83
|
*
|
|
64
|
-
*
|
|
84
|
+
* input$.next(12);
|
|
65
85
|
*
|
|
66
|
-
* assert.deepStrictEqual(
|
|
86
|
+
* assert.deepStrictEqual(valueHistory, [0, 3, 9, 12]);
|
|
67
87
|
* ```
|
|
68
88
|
*/
|
|
69
|
-
export const
|
|
89
|
+
export const throttle = <A,>(
|
|
70
90
|
milliSeconds: number,
|
|
71
91
|
): KeepInitialValueOperator<A, A> =>
|
|
72
92
|
// eslint-disable-next-line total-functions/no-unsafe-type-assertion
|
|
73
93
|
((parentObservable) =>
|
|
74
|
-
new
|
|
94
|
+
new ThrottleObservableClass(
|
|
75
95
|
parentObservable,
|
|
76
96
|
milliSeconds,
|
|
77
97
|
)) as KeepInitialValueOperator<A, A>;
|
|
78
98
|
|
|
79
|
-
class
|
|
99
|
+
class ThrottleObservableClass<A>
|
|
80
100
|
extends SyncChildObservableClass<A, readonly [A]>
|
|
81
|
-
implements
|
|
101
|
+
implements ThrottleOperatorObservable<A>
|
|
82
102
|
{
|
|
83
103
|
readonly #milliSeconds: number;
|
|
84
104
|
#mut_timerId: TimerId | undefined;
|
|
@@ -97,20 +117,20 @@ class ThrottleTimeObservableClass<A>
|
|
|
97
117
|
this.#milliSeconds = milliSeconds;
|
|
98
118
|
}
|
|
99
119
|
|
|
100
|
-
override tryUpdate(
|
|
120
|
+
override tryUpdate(updateToken: UpdateToken): void {
|
|
101
121
|
const par = this.parents[0];
|
|
102
122
|
|
|
103
123
|
const sn = par.getSnapshot();
|
|
104
124
|
|
|
105
125
|
if (
|
|
106
|
-
par.
|
|
126
|
+
par.updateToken !== updateToken ||
|
|
107
127
|
Optional.isNone(sn) ||
|
|
108
128
|
this.#mut_isSkipping
|
|
109
129
|
) {
|
|
110
130
|
return; // skip update
|
|
111
131
|
}
|
|
112
132
|
|
|
113
|
-
this.setNext(sn.value,
|
|
133
|
+
this.setNext(sn.value, updateToken);
|
|
114
134
|
|
|
115
135
|
this.#mut_isSkipping = true;
|
|
116
136
|
|
|
@@ -3,7 +3,7 @@ import { SyncChildObservableClass } from '../class/index.mjs';
|
|
|
3
3
|
import {
|
|
4
4
|
type KeepInitialValueOperator,
|
|
5
5
|
type Observable,
|
|
6
|
-
type
|
|
6
|
+
type UpdateToken,
|
|
7
7
|
type WithBufferedFromOperatorObservable,
|
|
8
8
|
} from '../types/index.mjs';
|
|
9
9
|
import { maxDepth } from '../utils/index.mjs';
|
|
@@ -37,27 +37,27 @@ import { maxDepth } from '../utils/index.mjs';
|
|
|
37
37
|
*
|
|
38
38
|
* const result$ = trigger$.pipe(withBufferedFrom(data$));
|
|
39
39
|
*
|
|
40
|
-
* const
|
|
40
|
+
* const valueHistory: (readonly [number, readonly string[]])[] = [];
|
|
41
41
|
*
|
|
42
42
|
* result$.subscribe(([triggerValue, bufferedData]) => {
|
|
43
|
-
*
|
|
43
|
+
* valueHistory.push([triggerValue, bufferedData]);
|
|
44
44
|
* });
|
|
45
45
|
*
|
|
46
|
-
* data$.next('
|
|
46
|
+
* data$.next('A');
|
|
47
47
|
*
|
|
48
|
-
* data$.next('
|
|
48
|
+
* data$.next('B');
|
|
49
49
|
*
|
|
50
50
|
* trigger$.next(1);
|
|
51
51
|
*
|
|
52
|
-
* assert.deepStrictEqual(
|
|
52
|
+
* assert.deepStrictEqual(valueHistory, [[1, ['A', 'B']]]);
|
|
53
53
|
*
|
|
54
|
-
* data$.next('
|
|
54
|
+
* data$.next('C');
|
|
55
55
|
*
|
|
56
56
|
* trigger$.next(2);
|
|
57
57
|
*
|
|
58
|
-
* assert.deepStrictEqual(
|
|
59
|
-
* [1, ['
|
|
60
|
-
* [2, ['
|
|
58
|
+
* assert.deepStrictEqual(valueHistory, [
|
|
59
|
+
* [1, ['A', 'B']],
|
|
60
|
+
* [2, ['C']],
|
|
61
61
|
* ]);
|
|
62
62
|
* ```
|
|
63
63
|
*/
|
|
@@ -71,7 +71,11 @@ export const withBufferedFrom = <A, B>(
|
|
|
71
71
|
observable,
|
|
72
72
|
)) as KeepInitialValueOperator<A, readonly [A, readonly B[]]>;
|
|
73
73
|
|
|
74
|
-
|
|
74
|
+
/**
|
|
75
|
+
* Alias for `withBufferedFrom`.
|
|
76
|
+
* @see withBufferedFrom
|
|
77
|
+
*/
|
|
78
|
+
export const withBuffered = withBufferedFrom;
|
|
75
79
|
|
|
76
80
|
class WithBufferedFromObservableClass<A, B>
|
|
77
81
|
extends SyncChildObservableClass<readonly [A, readonly B[]], readonly [A]>
|
|
@@ -101,16 +105,16 @@ class WithBufferedFromObservableClass<A, B>
|
|
|
101
105
|
});
|
|
102
106
|
}
|
|
103
107
|
|
|
104
|
-
override tryUpdate(
|
|
108
|
+
override tryUpdate(updateToken: UpdateToken): void {
|
|
105
109
|
const par = this.parents[0];
|
|
106
110
|
|
|
107
111
|
const sn = par.getSnapshot();
|
|
108
112
|
|
|
109
|
-
if (par.
|
|
113
|
+
if (par.updateToken !== updateToken || Optional.isNone(sn)) {
|
|
110
114
|
return; // skip update
|
|
111
115
|
}
|
|
112
116
|
|
|
113
|
-
this.setNext([sn.value, this.#mut_bufferedValues],
|
|
117
|
+
this.setNext([sn.value, this.#mut_bufferedValues], updateToken);
|
|
114
118
|
|
|
115
119
|
this.#clearBuffer();
|
|
116
120
|
}
|
|
@@ -3,7 +3,7 @@ import { SyncChildObservableClass } from '../class/index.mjs';
|
|
|
3
3
|
import {
|
|
4
4
|
type DropInitialValueOperator,
|
|
5
5
|
type Observable,
|
|
6
|
-
type
|
|
6
|
+
type UpdateToken,
|
|
7
7
|
type WithCurrentValueFromOperatorObservable,
|
|
8
8
|
} from '../types/index.mjs';
|
|
9
9
|
import { maxDepth } from '../utils/index.mjs';
|
|
@@ -22,14 +22,15 @@ import { maxDepth } from '../utils/index.mjs';
|
|
|
22
22
|
* // Timeline:
|
|
23
23
|
* //
|
|
24
24
|
* // name$ "Alice" "Bob" "Charlie"
|
|
25
|
-
* // age$ 25 30
|
|
26
|
-
* // result$
|
|
25
|
+
* // age$ 25 30
|
|
26
|
+
* // result$ (skip) ["Bob",25] ["Charlie",30]
|
|
27
27
|
* //
|
|
28
28
|
* // Explanation:
|
|
29
29
|
* // - withCurrentValueFrom samples the current value from another observable
|
|
30
|
-
* // - Emits a tuple [sourceValue, sampledValue] each time the
|
|
30
|
+
* // - Emits a tuple [sourceValue, sampledValue] each time the SOURCE emits
|
|
31
|
+
* // - Does NOT emit when the sampled observable (age$) emits
|
|
31
32
|
* // - Does not emit until both observables have emitted at least once
|
|
32
|
-
* // -
|
|
33
|
+
* // - "Alice" is skipped because age$ hasn't emitted yet
|
|
33
34
|
*
|
|
34
35
|
* const name$ = source<string>();
|
|
35
36
|
*
|
|
@@ -37,27 +38,27 @@ import { maxDepth } from '../utils/index.mjs';
|
|
|
37
38
|
*
|
|
38
39
|
* const result$ = name$.pipe(withCurrentValueFrom(age$));
|
|
39
40
|
*
|
|
40
|
-
* const
|
|
41
|
+
* const valueHistory: (readonly [string, number])[] = [];
|
|
41
42
|
*
|
|
42
43
|
* result$.subscribe(([name_, currentAge]) => {
|
|
43
|
-
*
|
|
44
|
+
* valueHistory.push([name_, currentAge]);
|
|
44
45
|
* });
|
|
45
46
|
*
|
|
46
47
|
* name$.next('Alice'); // nothing logged (age$ hasn't emitted)
|
|
47
48
|
*
|
|
48
|
-
* assert.deepStrictEqual(
|
|
49
|
+
* assert.deepStrictEqual(valueHistory, []);
|
|
49
50
|
*
|
|
50
51
|
* age$.next(25);
|
|
51
52
|
*
|
|
52
53
|
* name$.next('Bob'); // logs: Bob is 25 years old
|
|
53
54
|
*
|
|
54
|
-
* assert.deepStrictEqual(
|
|
55
|
+
* assert.deepStrictEqual(valueHistory, [['Bob', 25]]);
|
|
55
56
|
*
|
|
56
57
|
* age$.next(30);
|
|
57
58
|
*
|
|
58
59
|
* name$.next('Charlie'); // logs: Charlie is 30 years old
|
|
59
60
|
*
|
|
60
|
-
* assert.deepStrictEqual(
|
|
61
|
+
* assert.deepStrictEqual(valueHistory, [
|
|
61
62
|
* ['Bob', 25],
|
|
62
63
|
* ['Charlie', 30],
|
|
63
64
|
* ]);
|
|
@@ -70,7 +71,11 @@ export const withCurrentValueFrom =
|
|
|
70
71
|
(parentObservable) =>
|
|
71
72
|
new WithCurrentValueFromObservableClass(parentObservable, observable);
|
|
72
73
|
|
|
73
|
-
|
|
74
|
+
/**
|
|
75
|
+
* Alias for `withCurrentValueFrom`.
|
|
76
|
+
* @see withCurrentValueFrom
|
|
77
|
+
*/
|
|
78
|
+
export const withLatestFrom = withCurrentValueFrom;
|
|
74
79
|
|
|
75
80
|
class WithCurrentValueFromObservableClass<A, B>
|
|
76
81
|
extends SyncChildObservableClass<readonly [A, B], readonly [A]>
|
|
@@ -95,12 +100,12 @@ class WithCurrentValueFromObservableClass<A, B>
|
|
|
95
100
|
this.#observable = observable;
|
|
96
101
|
}
|
|
97
102
|
|
|
98
|
-
override tryUpdate(
|
|
103
|
+
override tryUpdate(updateToken: UpdateToken): void {
|
|
99
104
|
const par = this.parents[0];
|
|
100
105
|
|
|
101
106
|
const ps = par.getSnapshot();
|
|
102
107
|
|
|
103
|
-
if (par.
|
|
108
|
+
if (par.updateToken !== updateToken || Optional.isNone(ps)) {
|
|
104
109
|
return; // skip update
|
|
105
110
|
}
|
|
106
111
|
|
|
@@ -108,6 +113,6 @@ class WithCurrentValueFromObservableClass<A, B>
|
|
|
108
113
|
|
|
109
114
|
if (Optional.isNone(curr)) return; // skip update
|
|
110
115
|
|
|
111
|
-
this.setNext([ps.value, curr.value],
|
|
116
|
+
this.setNext([ps.value, curr.value], updateToken);
|
|
112
117
|
}
|
|
113
118
|
}
|
|
@@ -4,7 +4,7 @@ import { source } from '../create/index.mjs';
|
|
|
4
4
|
import {
|
|
5
5
|
type InitializedObservable,
|
|
6
6
|
type Observable,
|
|
7
|
-
type
|
|
7
|
+
type UpdateToken,
|
|
8
8
|
type WithInitialValueOperator,
|
|
9
9
|
type WithInitialValueOperatorObservable,
|
|
10
10
|
} from '../types/index.mjs';
|
|
@@ -37,21 +37,21 @@ import {
|
|
|
37
37
|
*
|
|
38
38
|
* const initialized$ = num$.pipe(withInitialValue(0));
|
|
39
39
|
*
|
|
40
|
-
* const
|
|
40
|
+
* const valueHistory: number[] = [];
|
|
41
41
|
*
|
|
42
42
|
* initialized$.subscribe((x) => {
|
|
43
|
-
*
|
|
43
|
+
* valueHistory.push(x);
|
|
44
44
|
* });
|
|
45
45
|
*
|
|
46
|
-
* assert.deepStrictEqual(
|
|
46
|
+
* assert.deepStrictEqual(valueHistory, [0]);
|
|
47
47
|
*
|
|
48
48
|
* num$.next(1); // logs: 1
|
|
49
49
|
*
|
|
50
|
-
* assert.deepStrictEqual(
|
|
50
|
+
* assert.deepStrictEqual(valueHistory, [0, 1]);
|
|
51
51
|
*
|
|
52
52
|
* num$.next(2); // logs: 2
|
|
53
53
|
*
|
|
54
|
-
* assert.deepStrictEqual(
|
|
54
|
+
* assert.deepStrictEqual(valueHistory, [0, 1, 2]);
|
|
55
55
|
* ```
|
|
56
56
|
*/
|
|
57
57
|
export const withInitialValue =
|
|
@@ -70,16 +70,16 @@ class WithInitialValueObservableClass<A, I>
|
|
|
70
70
|
});
|
|
71
71
|
}
|
|
72
72
|
|
|
73
|
-
override tryUpdate(
|
|
73
|
+
override tryUpdate(updateToken: UpdateToken): void {
|
|
74
74
|
const par = this.parents[0];
|
|
75
75
|
|
|
76
76
|
const sn = par.getSnapshot();
|
|
77
77
|
|
|
78
|
-
if (par.
|
|
78
|
+
if (par.updateToken !== updateToken || Optional.isNone(sn)) {
|
|
79
79
|
return; // skip update
|
|
80
80
|
}
|
|
81
81
|
|
|
82
|
-
this.setNext(sn.value,
|
|
82
|
+
this.setNext(sn.value, updateToken);
|
|
83
83
|
}
|
|
84
84
|
}
|
|
85
85
|
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './operators/index.mjs';
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { map } from '../../operators/index.mjs';
|
|
2
|
+
import { type KeepInitialValueOperator } from '../../types/index.mjs';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Attaches a sequential index to each emitted value, producing `[index, value]` tuples.
|
|
6
|
+
* Index starts at 0 and increments with each emission.
|
|
7
|
+
*
|
|
8
|
+
* @template A - The type of values from the source
|
|
9
|
+
* @returns An operator that emits `[index, value]` tuples
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* ```ts
|
|
13
|
+
* // Timeline:
|
|
14
|
+
* //
|
|
15
|
+
* // letter$ "A" "B" "C"
|
|
16
|
+
* // indexed$ [0,"A"] [1,"B"] [2,"C"]
|
|
17
|
+
* //
|
|
18
|
+
* // Explanation:
|
|
19
|
+
* // - attachIndex attaches a sequential index to each emitted value
|
|
20
|
+
* // - Produces [index, value] tuples
|
|
21
|
+
* // - Index starts at 0 and increments with each emission
|
|
22
|
+
*
|
|
23
|
+
* const letter$ = source<string>();
|
|
24
|
+
*
|
|
25
|
+
* const indexed$ = letter$.pipe(attachIndex());
|
|
26
|
+
*
|
|
27
|
+
* const valueHistory: (readonly [number, string])[] = [];
|
|
28
|
+
*
|
|
29
|
+
* indexed$.subscribe(([i, letter]) => {
|
|
30
|
+
* valueHistory.push([i, letter]);
|
|
31
|
+
* });
|
|
32
|
+
*
|
|
33
|
+
* letter$.next('A');
|
|
34
|
+
*
|
|
35
|
+
* assert.deepStrictEqual(valueHistory, [[0, 'A']]);
|
|
36
|
+
*
|
|
37
|
+
* letter$.next('B');
|
|
38
|
+
*
|
|
39
|
+
* assert.deepStrictEqual(valueHistory, [
|
|
40
|
+
* [0, 'A'],
|
|
41
|
+
* [1, 'B'],
|
|
42
|
+
* ]);
|
|
43
|
+
*
|
|
44
|
+
* letter$.next('C');
|
|
45
|
+
*
|
|
46
|
+
* assert.deepStrictEqual(valueHistory, [
|
|
47
|
+
* [0, 'A'],
|
|
48
|
+
* [1, 'B'],
|
|
49
|
+
* [2, 'C'],
|
|
50
|
+
* ]);
|
|
51
|
+
* ```
|
|
52
|
+
*/
|
|
53
|
+
export const withIndex = <A,>(): KeepInitialValueOperator<
|
|
54
|
+
A,
|
|
55
|
+
readonly [SafeUint | -1, A]
|
|
56
|
+
> => map((a, i) => [i, a] as const);
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Alias for `withIndex`.
|
|
60
|
+
* @see withIndex
|
|
61
|
+
*/
|
|
62
|
+
export const attachIndex = withIndex;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export * from './attach-index.mjs';
|
|
2
|
+
export * from './map-optional.mjs';
|
|
3
|
+
export * from './map-result-err.mjs';
|
|
4
|
+
export * from './map-result-ok.mjs';
|
|
5
|
+
export * from './map-to.mjs';
|
|
6
|
+
export * from './pluck.mjs';
|
|
7
|
+
export * from './skip.mjs';
|
|
8
|
+
export * from './take.mjs';
|
|
9
|
+
export * from './unwrap-optional.mjs';
|
|
10
|
+
export * from './unwrap-result-err.mjs';
|
|
11
|
+
export * from './unwrap-result-ok.mjs';
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { Optional } from 'ts-data-forge';
|
|
2
|
+
import { map } from '../../operators/index.mjs';
|
|
3
|
+
import { type KeepInitialValueOperator } from '../../types/index.mjs';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Transforms the inner value of an `Optional` type emitted by the source.
|
|
7
|
+
* If the value is `Some`, the mapping function is applied; if `None`, it remains `None`.
|
|
8
|
+
*
|
|
9
|
+
* @template O - The Optional type from the source
|
|
10
|
+
* @template B - The type of the mapped inner value
|
|
11
|
+
* @param mapFn - A function to transform the unwrapped value
|
|
12
|
+
* @returns An operator that maps the inner value of Optional emissions
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* ```ts
|
|
16
|
+
* // Timeline:
|
|
17
|
+
* //
|
|
18
|
+
* // value$ Some(2) None Some(5)
|
|
19
|
+
* // doubled$ Some(4) None Some(10)
|
|
20
|
+
* //
|
|
21
|
+
* // Explanation:
|
|
22
|
+
* // - mapOptional transforms the inner value of Optional emissions
|
|
23
|
+
* // - Some values are mapped; None values pass through unchanged
|
|
24
|
+
*
|
|
25
|
+
* const value$ = source<Optional<number>>();
|
|
26
|
+
*
|
|
27
|
+
* const doubled$ = value$.pipe(mapOptional((x) => x * 2));
|
|
28
|
+
*
|
|
29
|
+
* const valueHistory: Optional<number>[] = [];
|
|
30
|
+
*
|
|
31
|
+
* doubled$.subscribe((v) => {
|
|
32
|
+
* valueHistory.push(v);
|
|
33
|
+
* });
|
|
34
|
+
*
|
|
35
|
+
* value$.next(Optional.some(2));
|
|
36
|
+
*
|
|
37
|
+
* assert.deepStrictEqual(valueHistory, [Optional.some(4)]);
|
|
38
|
+
*
|
|
39
|
+
* value$.next(Optional.none);
|
|
40
|
+
*
|
|
41
|
+
* assert.deepStrictEqual(valueHistory, [Optional.some(4), Optional.none]);
|
|
42
|
+
*
|
|
43
|
+
* value$.next(Optional.some(5));
|
|
44
|
+
*
|
|
45
|
+
* assert.deepStrictEqual(valueHistory, [
|
|
46
|
+
* Optional.some(4),
|
|
47
|
+
* Optional.none,
|
|
48
|
+
* Optional.some(10),
|
|
49
|
+
* ]);
|
|
50
|
+
* ```
|
|
51
|
+
*/
|
|
52
|
+
export const mapOptional = <O extends UnknownOptional, B>(
|
|
53
|
+
mapFn: (x: Optional.Unwrap<O>) => B,
|
|
54
|
+
): KeepInitialValueOperator<O, Optional<B>> =>
|
|
55
|
+
map((a) => Optional.map(a, mapFn));
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { Result } from 'ts-data-forge';
|
|
2
|
+
import { map } from '../../operators/index.mjs';
|
|
3
|
+
import { type KeepInitialValueOperator } from '../../types/index.mjs';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Transforms the error value (`Err`) of a `Result` type emitted by the source.
|
|
7
|
+
* If the value is `Err`, the mapping function is applied; if `Ok`, it remains unchanged.
|
|
8
|
+
*
|
|
9
|
+
* @template R - The Result type from the source
|
|
10
|
+
* @template E2 - The type of the mapped error value
|
|
11
|
+
* @param mapFn - A function to transform the Err value
|
|
12
|
+
* @returns An operator that maps the Err side of Result emissions
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* ```ts
|
|
16
|
+
* // Timeline:
|
|
17
|
+
* //
|
|
18
|
+
* // result$ Ok(1) Err("bad") Err("fail")
|
|
19
|
+
* // mapped$ Ok(1) Err("BAD") Err("FAIL")
|
|
20
|
+
* //
|
|
21
|
+
* // Explanation:
|
|
22
|
+
* // - mapResultErr transforms the Err value of Result emissions
|
|
23
|
+
* // - Ok values pass through unchanged
|
|
24
|
+
*
|
|
25
|
+
* const result$ = source<Result<number, string>>();
|
|
26
|
+
*
|
|
27
|
+
* const mapped$ = result$.pipe(mapResultErr((e) => e.toUpperCase()));
|
|
28
|
+
*
|
|
29
|
+
* const valueHistory: Result<number, string>[] = [];
|
|
30
|
+
*
|
|
31
|
+
* mapped$.subscribe((v) => {
|
|
32
|
+
* valueHistory.push(v);
|
|
33
|
+
* });
|
|
34
|
+
*
|
|
35
|
+
* result$.next(Result.ok(1));
|
|
36
|
+
*
|
|
37
|
+
* assert.deepStrictEqual(valueHistory, [Result.ok(1)]);
|
|
38
|
+
*
|
|
39
|
+
* result$.next(Result.err('bad'));
|
|
40
|
+
*
|
|
41
|
+
* assert.deepStrictEqual(valueHistory, [Result.ok(1), Result.err('BAD')]);
|
|
42
|
+
*
|
|
43
|
+
* result$.next(Result.err('fail'));
|
|
44
|
+
*
|
|
45
|
+
* assert.deepStrictEqual(valueHistory, [
|
|
46
|
+
* Result.ok(1),
|
|
47
|
+
* Result.err('BAD'),
|
|
48
|
+
* Result.err('FAIL'),
|
|
49
|
+
* ]);
|
|
50
|
+
* ```
|
|
51
|
+
*/
|
|
52
|
+
export const mapResultErr = <R extends UnknownResult, E2>(
|
|
53
|
+
mapFn: (x: Result.UnwrapErr<R>) => E2,
|
|
54
|
+
): KeepInitialValueOperator<R, Result<Result.UnwrapOk<R>, E2>> =>
|
|
55
|
+
map((a) => Result.mapErr(a, mapFn));
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { Result } from 'ts-data-forge';
|
|
2
|
+
import { map } from '../../operators/index.mjs';
|
|
3
|
+
import { type KeepInitialValueOperator } from '../../types/index.mjs';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Transforms the success value (`Ok`) of a `Result` type emitted by the source.
|
|
7
|
+
* If the value is `Ok`, the mapping function is applied; if `Err`, it remains unchanged.
|
|
8
|
+
*
|
|
9
|
+
* @template R - The Result type from the source
|
|
10
|
+
* @template S2 - The type of the mapped success value
|
|
11
|
+
* @param mapFn - A function to transform the Ok value
|
|
12
|
+
* @returns An operator that maps the Ok side of Result emissions
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* ```ts
|
|
16
|
+
* // Timeline:
|
|
17
|
+
* //
|
|
18
|
+
* // result$ Ok(2) Err("e") Ok(5)
|
|
19
|
+
* // doubled$ Ok(4) Err("e") Ok(10)
|
|
20
|
+
* //
|
|
21
|
+
* // Explanation:
|
|
22
|
+
* // - mapResultOk transforms the Ok value of Result emissions
|
|
23
|
+
* // - Err values pass through unchanged
|
|
24
|
+
*
|
|
25
|
+
* const result$ = source<Result<number, string>>();
|
|
26
|
+
*
|
|
27
|
+
* const doubled$ = result$.pipe(mapResultOk((x) => x * 2));
|
|
28
|
+
*
|
|
29
|
+
* const valueHistory: Result<number, string>[] = [];
|
|
30
|
+
*
|
|
31
|
+
* doubled$.subscribe((v) => {
|
|
32
|
+
* valueHistory.push(v);
|
|
33
|
+
* });
|
|
34
|
+
*
|
|
35
|
+
* result$.next(Result.ok(2));
|
|
36
|
+
*
|
|
37
|
+
* assert.deepStrictEqual(valueHistory, [Result.ok(4)]);
|
|
38
|
+
*
|
|
39
|
+
* result$.next(Result.err('e'));
|
|
40
|
+
*
|
|
41
|
+
* assert.deepStrictEqual(valueHistory, [Result.ok(4), Result.err('e')]);
|
|
42
|
+
*
|
|
43
|
+
* result$.next(Result.ok(5));
|
|
44
|
+
*
|
|
45
|
+
* assert.deepStrictEqual(valueHistory, [
|
|
46
|
+
* Result.ok(4),
|
|
47
|
+
* Result.err('e'),
|
|
48
|
+
* Result.ok(10),
|
|
49
|
+
* ]);
|
|
50
|
+
* ```
|
|
51
|
+
*/
|
|
52
|
+
export const mapResultOk = <R extends UnknownResult, S2>(
|
|
53
|
+
mapFn: (x: Result.UnwrapOk<R>) => S2,
|
|
54
|
+
): KeepInitialValueOperator<R, Result<S2, Result.UnwrapErr<R>>> =>
|
|
55
|
+
map((a) => Result.map(a, mapFn));
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { map } from '../../operators/index.mjs';
|
|
2
|
+
import { type KeepInitialValueOperator } from '../../types/index.mjs';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Maps all emitted values to a constant value, ignoring the source values.
|
|
6
|
+
* Equivalent to `map(() => value)`.
|
|
7
|
+
*
|
|
8
|
+
* @template A - The type of values from the source
|
|
9
|
+
* @template B - The type of the constant value
|
|
10
|
+
* @param value - The constant value to emit
|
|
11
|
+
* @returns An operator that always emits the given constant
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* ```ts
|
|
15
|
+
* // Timeline:
|
|
16
|
+
* //
|
|
17
|
+
* // click$ MouseEvent MouseEvent MouseEvent
|
|
18
|
+
* // count$ 1 1 1
|
|
19
|
+
* //
|
|
20
|
+
* // Explanation:
|
|
21
|
+
* // - mapTo maps all emitted values to a constant value
|
|
22
|
+
* // - Ignores the source values entirely
|
|
23
|
+
* // - Useful for converting events to signals
|
|
24
|
+
*
|
|
25
|
+
* const click$ = source<string>();
|
|
26
|
+
*
|
|
27
|
+
* const one$ = click$.pipe(mapTo(1));
|
|
28
|
+
*
|
|
29
|
+
* const valueHistory: number[] = [];
|
|
30
|
+
*
|
|
31
|
+
* one$.subscribe((value) => {
|
|
32
|
+
* valueHistory.push(value);
|
|
33
|
+
* });
|
|
34
|
+
*
|
|
35
|
+
* click$.next('click1');
|
|
36
|
+
*
|
|
37
|
+
* click$.next('click2');
|
|
38
|
+
*
|
|
39
|
+
* click$.next('click3');
|
|
40
|
+
*
|
|
41
|
+
* assert.deepStrictEqual(valueHistory, [1, 1, 1]);
|
|
42
|
+
* ```
|
|
43
|
+
*/
|
|
44
|
+
export const mapTo = <A, B>(value: B): KeepInitialValueOperator<A, B> =>
|
|
45
|
+
map(() => value);
|