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
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
import { Optional } from 'ts-data-forge';
|
|
2
|
+
import { AsyncChildObservableClass } from '../class/index.mjs';
|
|
3
|
+
import {
|
|
4
|
+
type DebounceOperatorObservable,
|
|
5
|
+
type KeepInitialValueOperator,
|
|
6
|
+
type Observable,
|
|
7
|
+
type TimerId,
|
|
8
|
+
type UpdateToken,
|
|
9
|
+
} from '../types/index.mjs';
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Delays emissions from the source observable until a specified time has passed without another emission.
|
|
13
|
+
* Useful for handling user input events like typing or scrolling.
|
|
14
|
+
*
|
|
15
|
+
* @template A - The type of values from the source
|
|
16
|
+
* @param milliSeconds - The debounce duration in milliseconds
|
|
17
|
+
* @returns An operator that debounces the observable
|
|
18
|
+
*
|
|
19
|
+
* @example
|
|
20
|
+
* ```ts
|
|
21
|
+
* // Timeline (250ms debounce):
|
|
22
|
+
* //
|
|
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 ->
|
|
27
|
+
* // debounced$ 3 14 (emitted after 250ms silence)
|
|
28
|
+
* //
|
|
29
|
+
* // Explanation:
|
|
30
|
+
* // - debounce emits the latest value AFTER a quiet period with no new emissions
|
|
31
|
+
* // - Unlike audit (which uses a fixed window), debounce resets the timer on every emission
|
|
32
|
+
* // - Useful for search-as-you-type and form validation
|
|
33
|
+
*
|
|
34
|
+
* const input$ = source<number>();
|
|
35
|
+
*
|
|
36
|
+
* const debounced$ = input$.pipe(debounce(250));
|
|
37
|
+
*
|
|
38
|
+
* const valueHistory: number[] = [];
|
|
39
|
+
*
|
|
40
|
+
* debounced$.subscribe((value) => {
|
|
41
|
+
* valueHistory.push(value);
|
|
42
|
+
* });
|
|
43
|
+
*
|
|
44
|
+
* const sleep = (ms: number): Promise<void> =>
|
|
45
|
+
* new Promise((resolve) => {
|
|
46
|
+
* setTimeout(resolve, ms);
|
|
47
|
+
* });
|
|
48
|
+
*
|
|
49
|
+
* input$.next(0);
|
|
50
|
+
*
|
|
51
|
+
* await sleep(200);
|
|
52
|
+
*
|
|
53
|
+
* input$.next(2);
|
|
54
|
+
*
|
|
55
|
+
* await sleep(100);
|
|
56
|
+
*
|
|
57
|
+
* input$.next(3);
|
|
58
|
+
*
|
|
59
|
+
* assert.deepStrictEqual(valueHistory, []);
|
|
60
|
+
*
|
|
61
|
+
* await sleep(300);
|
|
62
|
+
*
|
|
63
|
+
* assert.deepStrictEqual(valueHistory, [3]);
|
|
64
|
+
*
|
|
65
|
+
* await sleep(300);
|
|
66
|
+
*
|
|
67
|
+
* input$.next(9);
|
|
68
|
+
*
|
|
69
|
+
* await sleep(100);
|
|
70
|
+
*
|
|
71
|
+
* input$.next(10);
|
|
72
|
+
*
|
|
73
|
+
* await sleep(100);
|
|
74
|
+
*
|
|
75
|
+
* input$.next(11);
|
|
76
|
+
*
|
|
77
|
+
* await sleep(100);
|
|
78
|
+
*
|
|
79
|
+
* input$.next(12);
|
|
80
|
+
*
|
|
81
|
+
* await sleep(100);
|
|
82
|
+
*
|
|
83
|
+
* input$.next(13);
|
|
84
|
+
*
|
|
85
|
+
* await sleep(100);
|
|
86
|
+
*
|
|
87
|
+
* input$.next(14);
|
|
88
|
+
*
|
|
89
|
+
* assert.deepStrictEqual(valueHistory, [3]);
|
|
90
|
+
*
|
|
91
|
+
* await sleep(300);
|
|
92
|
+
*
|
|
93
|
+
* assert.deepStrictEqual(valueHistory, [3, 14]);
|
|
94
|
+
* ```
|
|
95
|
+
*/
|
|
96
|
+
export const debounce = <A,>(
|
|
97
|
+
milliSeconds: number,
|
|
98
|
+
): KeepInitialValueOperator<A, A> =>
|
|
99
|
+
// eslint-disable-next-line total-functions/no-unsafe-type-assertion
|
|
100
|
+
((parentObservable) =>
|
|
101
|
+
new DebounceObservableClass(
|
|
102
|
+
parentObservable,
|
|
103
|
+
milliSeconds,
|
|
104
|
+
)) as KeepInitialValueOperator<A, A>;
|
|
105
|
+
|
|
106
|
+
class DebounceObservableClass<A>
|
|
107
|
+
extends AsyncChildObservableClass<A, readonly [A]>
|
|
108
|
+
implements DebounceOperatorObservable<A>
|
|
109
|
+
{
|
|
110
|
+
readonly #milliSeconds: number;
|
|
111
|
+
#mut_timerId: TimerId | undefined;
|
|
112
|
+
|
|
113
|
+
constructor(parentObservable: Observable<A>, milliSeconds: number) {
|
|
114
|
+
super({
|
|
115
|
+
parents: [parentObservable],
|
|
116
|
+
initialValue: parentObservable.getSnapshot(),
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
this.#mut_timerId = undefined;
|
|
120
|
+
|
|
121
|
+
this.#milliSeconds = milliSeconds;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
override tryUpdate(updateToken: UpdateToken): void {
|
|
125
|
+
const par = this.parents[0];
|
|
126
|
+
|
|
127
|
+
const sn = par.getSnapshot();
|
|
128
|
+
|
|
129
|
+
if (par.updateToken !== updateToken || Optional.isNone(sn)) {
|
|
130
|
+
return; // skip update
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
this.#resetTimer();
|
|
134
|
+
|
|
135
|
+
// set timer
|
|
136
|
+
this.#mut_timerId = setTimeout(() => {
|
|
137
|
+
if (Optional.isNone(sn)) return;
|
|
138
|
+
|
|
139
|
+
this.startUpdate(sn.value);
|
|
140
|
+
}, this.#milliSeconds);
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
#resetTimer(): void {
|
|
144
|
+
if (this.#mut_timerId !== undefined) {
|
|
145
|
+
clearTimeout(this.#mut_timerId);
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
override complete(): void {
|
|
150
|
+
this.#resetTimer();
|
|
151
|
+
|
|
152
|
+
super.complete();
|
|
153
|
+
}
|
|
154
|
+
}
|
|
@@ -12,7 +12,7 @@ import {
|
|
|
12
12
|
type FilterOperatorObservable,
|
|
13
13
|
type InitializedObservable,
|
|
14
14
|
type Observable,
|
|
15
|
-
type
|
|
15
|
+
type UpdateToken,
|
|
16
16
|
} from '../types/index.mjs';
|
|
17
17
|
import { withInitialValue } from './with-initial-value.mjs';
|
|
18
18
|
|
|
@@ -40,29 +40,29 @@ import { withInitialValue } from './with-initial-value.mjs';
|
|
|
40
40
|
*
|
|
41
41
|
* const even$ = num$.pipe(filter((x) => x % 2 === 0));
|
|
42
42
|
*
|
|
43
|
-
* const
|
|
43
|
+
* const valueHistory: number[] = [];
|
|
44
44
|
*
|
|
45
45
|
* even$.subscribe((x) => {
|
|
46
|
-
*
|
|
46
|
+
* valueHistory.push(x);
|
|
47
47
|
* });
|
|
48
48
|
*
|
|
49
49
|
* num$.next(1); // nothing logged
|
|
50
50
|
*
|
|
51
51
|
* num$.next(2); // logs: 2
|
|
52
52
|
*
|
|
53
|
-
* assert.deepStrictEqual(
|
|
53
|
+
* assert.deepStrictEqual(valueHistory, [2]);
|
|
54
54
|
*
|
|
55
55
|
* num$.next(3); // nothing logged
|
|
56
56
|
*
|
|
57
57
|
* num$.next(4); // logs: 4
|
|
58
58
|
*
|
|
59
|
-
* assert.deepStrictEqual(
|
|
59
|
+
* assert.deepStrictEqual(valueHistory, [2, 4]);
|
|
60
60
|
*
|
|
61
61
|
* num$.next(5);
|
|
62
62
|
*
|
|
63
63
|
* num$.next(6);
|
|
64
64
|
*
|
|
65
|
-
* assert.deepStrictEqual(
|
|
65
|
+
* assert.deepStrictEqual(valueHistory, [2, 4, 6]);
|
|
66
66
|
* ```
|
|
67
67
|
*/
|
|
68
68
|
export function filter<A, B extends A>(
|
|
@@ -107,12 +107,12 @@ class FilterObservableClass<A>
|
|
|
107
107
|
this.#predicate = predicate;
|
|
108
108
|
}
|
|
109
109
|
|
|
110
|
-
override tryUpdate(
|
|
110
|
+
override tryUpdate(updateToken: UpdateToken): void {
|
|
111
111
|
const par = this.parents[0];
|
|
112
112
|
|
|
113
113
|
const sn = par.getSnapshot();
|
|
114
114
|
|
|
115
|
-
if (par.
|
|
115
|
+
if (par.updateToken !== updateToken || Optional.isNone(sn)) {
|
|
116
116
|
return; // skip update
|
|
117
117
|
}
|
|
118
118
|
|
|
@@ -120,7 +120,7 @@ class FilterObservableClass<A>
|
|
|
120
120
|
this.#mut_index === -1 ? asSafeUint(0) : SafeUint.add(1, this.#mut_index);
|
|
121
121
|
|
|
122
122
|
if (this.#predicate(sn.value, this.#mut_index)) {
|
|
123
|
-
this.setNext(sn.value,
|
|
123
|
+
this.setNext(sn.value, updateToken);
|
|
124
124
|
}
|
|
125
125
|
}
|
|
126
126
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
export * from './audit
|
|
2
|
-
export * from './debounce
|
|
1
|
+
export * from './audit.mjs';
|
|
2
|
+
export * from './debounce.mjs';
|
|
3
3
|
export * from './filter.mjs';
|
|
4
|
-
export * from './map
|
|
4
|
+
export * from './map.mjs';
|
|
5
5
|
export * from './merge-map.mjs';
|
|
6
6
|
export * from './pairwise.mjs';
|
|
7
7
|
export * from './scan.mjs';
|
|
@@ -11,7 +11,7 @@ export * from './skip-while.mjs';
|
|
|
11
11
|
export * from './switch-map.mjs';
|
|
12
12
|
export * from './take-until.mjs';
|
|
13
13
|
export * from './take-while.mjs';
|
|
14
|
-
export * from './throttle
|
|
14
|
+
export * from './throttle.mjs';
|
|
15
15
|
export * from './with-buffered-from.mjs';
|
|
16
16
|
export * from './with-current-value-from.mjs';
|
|
17
17
|
export * from './with-initial-value.mjs';
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
import { Optional, SafeUint, asSafeUint, expectType } from 'ts-data-forge';
|
|
2
|
+
import { SyncChildObservableClass } from '../class/index.mjs';
|
|
3
|
+
import { source } from '../create/index.mjs';
|
|
4
|
+
import {
|
|
5
|
+
type InitializedObservable,
|
|
6
|
+
type KeepInitialValueOperator,
|
|
7
|
+
type MapOperatorObservable,
|
|
8
|
+
type Observable,
|
|
9
|
+
type UpdateToken,
|
|
10
|
+
} from '../types/index.mjs';
|
|
11
|
+
import { withInitialValue } from './with-initial-value.mjs';
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Transforms each value emitted by the source using a mapping function that also receives the emission index.
|
|
15
|
+
*
|
|
16
|
+
* @template A - The type of values from the source
|
|
17
|
+
* @template B - The type of mapped values
|
|
18
|
+
* @param mapFn - A function that maps each value (receives value and index)
|
|
19
|
+
* @returns An operator that maps values with index
|
|
20
|
+
*
|
|
21
|
+
* @example
|
|
22
|
+
* ```ts
|
|
23
|
+
* // Timeline:
|
|
24
|
+
* //
|
|
25
|
+
* // num$ "A" "B" "C"
|
|
26
|
+
* // indexed$ "0: A" "1: B" "2: C"
|
|
27
|
+
* //
|
|
28
|
+
* // Explanation:
|
|
29
|
+
* // - mapWithIndex transforms each value along with its index
|
|
30
|
+
* // - Index starts at 0 and increments with each emission
|
|
31
|
+
*
|
|
32
|
+
* const num$ = source<string>();
|
|
33
|
+
*
|
|
34
|
+
* const indexed$ = num$.pipe(map((x, i) => `${i}: ${x}`));
|
|
35
|
+
*
|
|
36
|
+
* const valueHistory: string[] = [];
|
|
37
|
+
*
|
|
38
|
+
* indexed$.subscribe((s) => {
|
|
39
|
+
* valueHistory.push(s);
|
|
40
|
+
* });
|
|
41
|
+
*
|
|
42
|
+
* num$.next('A'); // 0: A
|
|
43
|
+
*
|
|
44
|
+
* num$.next('B'); // 1: B
|
|
45
|
+
*
|
|
46
|
+
* num$.next('C'); // 2: C
|
|
47
|
+
*
|
|
48
|
+
* assert.deepStrictEqual(valueHistory, ['0: A', '1: B', '2: C']);
|
|
49
|
+
* ```
|
|
50
|
+
*/
|
|
51
|
+
export const map = <A, B>(
|
|
52
|
+
mapFn: (x: A, index: SafeUint | -1) => B,
|
|
53
|
+
): KeepInitialValueOperator<A, B> =>
|
|
54
|
+
// eslint-disable-next-line total-functions/no-unsafe-type-assertion
|
|
55
|
+
((parentObservable) =>
|
|
56
|
+
new MapObservableClass(
|
|
57
|
+
parentObservable,
|
|
58
|
+
mapFn,
|
|
59
|
+
)) as KeepInitialValueOperator<A, B>;
|
|
60
|
+
|
|
61
|
+
/* implementation */
|
|
62
|
+
|
|
63
|
+
class MapObservableClass<A, B>
|
|
64
|
+
extends SyncChildObservableClass<B, readonly [A]>
|
|
65
|
+
implements MapOperatorObservable<A, B>
|
|
66
|
+
{
|
|
67
|
+
readonly #mapFn: (x: A, index: SafeUint | -1) => B;
|
|
68
|
+
#mut_index: SafeUint | -1;
|
|
69
|
+
|
|
70
|
+
constructor(
|
|
71
|
+
parentObservable: Observable<A>,
|
|
72
|
+
mapFn: (x: A, index: SafeUint | -1) => B,
|
|
73
|
+
) {
|
|
74
|
+
super({
|
|
75
|
+
parents: [parentObservable],
|
|
76
|
+
initialValue: Optional.map(parentObservable.getSnapshot(), (x) =>
|
|
77
|
+
mapFn(x, -1),
|
|
78
|
+
),
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
this.#mut_index = -1;
|
|
82
|
+
|
|
83
|
+
this.#mapFn = mapFn;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
override tryUpdate(updateToken: UpdateToken): void {
|
|
87
|
+
const par = this.parents[0];
|
|
88
|
+
|
|
89
|
+
const sn = par.getSnapshot();
|
|
90
|
+
|
|
91
|
+
if (par.updateToken !== updateToken || Optional.isNone(sn)) {
|
|
92
|
+
return; // skip update
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
this.#mut_index =
|
|
96
|
+
this.#mut_index === -1 ? asSafeUint(0) : SafeUint.add(1, this.#mut_index);
|
|
97
|
+
|
|
98
|
+
this.setNext(this.#mapFn(sn.value, this.#mut_index), updateToken);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
if (import.meta.vitest !== undefined) {
|
|
103
|
+
test('type test', () => {
|
|
104
|
+
expect(1).toBe(1); // dummy
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
{
|
|
108
|
+
const s: Observable<number> = source<number>();
|
|
109
|
+
|
|
110
|
+
const _d1 = s.pipe(map((x, i) => x + i));
|
|
111
|
+
|
|
112
|
+
expectType<typeof _d1, Observable<number>>('=');
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
{
|
|
116
|
+
const s = source<number>();
|
|
117
|
+
|
|
118
|
+
const m: InitializedObservable<number> = s.pipe(withInitialValue(0));
|
|
119
|
+
|
|
120
|
+
const _d = m.pipe(map((x, i) => x + i));
|
|
121
|
+
|
|
122
|
+
expectType<typeof _d, InitializedObservable<number>>('=');
|
|
123
|
+
}
|
|
124
|
+
}
|
|
@@ -5,7 +5,7 @@ import {
|
|
|
5
5
|
type MergeMapOperatorObservable,
|
|
6
6
|
type Observable,
|
|
7
7
|
type Subscription,
|
|
8
|
-
type
|
|
8
|
+
type UpdateToken,
|
|
9
9
|
} from '../types/index.mjs';
|
|
10
10
|
|
|
11
11
|
/**
|
|
@@ -21,56 +21,83 @@ import {
|
|
|
21
21
|
* ```ts
|
|
22
22
|
* // Timeline:
|
|
23
23
|
* //
|
|
24
|
-
* //
|
|
25
|
-
* //
|
|
26
|
-
* //
|
|
27
|
-
* //
|
|
24
|
+
* // input$ A B C
|
|
25
|
+
* // inner A A1 A2 A3
|
|
26
|
+
* // inner B B1 B2 B3
|
|
27
|
+
* // inner C C1 C2 C3
|
|
28
|
+
* // result$ A1 A2 A3 B1 B2 C1 B3 C2 C3
|
|
28
29
|
* //
|
|
29
30
|
* // Explanation:
|
|
30
|
-
* // - mergeMap
|
|
31
|
-
* // -
|
|
32
|
-
* // -
|
|
33
|
-
* // - All
|
|
31
|
+
* // - mergeMap creates an inner observable for each source value
|
|
32
|
+
* // - Unlike switchMap, previous inner observables are NOT cancelled
|
|
33
|
+
* // - B's inner continues even after C arrives (B3 is still emitted)
|
|
34
|
+
* // - All inner observables run concurrently and their results are merged
|
|
34
35
|
*
|
|
35
|
-
* const
|
|
36
|
+
* const input$ = source<string>();
|
|
36
37
|
*
|
|
37
|
-
* const
|
|
38
|
-
* mergeMap((
|
|
39
|
-
* const
|
|
38
|
+
* const result$ = input$.pipe(
|
|
39
|
+
* mergeMap((letter) => {
|
|
40
|
+
* const inner$ = source<string>();
|
|
40
41
|
*
|
|
41
42
|
* setTimeout(() => {
|
|
42
|
-
*
|
|
43
|
-
*
|
|
44
|
-
* result$.complete();
|
|
43
|
+
* inner$.next(`${letter}1`);
|
|
45
44
|
* }, 10);
|
|
46
45
|
*
|
|
47
|
-
*
|
|
46
|
+
* setTimeout(() => {
|
|
47
|
+
* inner$.next(`${letter}2`);
|
|
48
|
+
* }, 110);
|
|
49
|
+
*
|
|
50
|
+
* setTimeout(() => {
|
|
51
|
+
* inner$.next(`${letter}3`);
|
|
52
|
+
* }, 210);
|
|
53
|
+
*
|
|
54
|
+
* return inner$;
|
|
48
55
|
* }),
|
|
49
56
|
* );
|
|
50
57
|
*
|
|
51
|
-
* const
|
|
58
|
+
* const valueHistory: string[] = [];
|
|
52
59
|
*
|
|
53
|
-
*
|
|
54
|
-
*
|
|
60
|
+
* result$.subscribe((value) => {
|
|
61
|
+
* valueHistory.push(value);
|
|
55
62
|
* });
|
|
56
63
|
*
|
|
57
|
-
*
|
|
64
|
+
* const sleep = (ms: number): Promise<void> =>
|
|
65
|
+
* new Promise((resolve) => {
|
|
66
|
+
* setTimeout(resolve, ms);
|
|
67
|
+
* });
|
|
58
68
|
*
|
|
59
|
-
*
|
|
69
|
+
* // Emit A - inner emits A1, A2, A3 at 10ms, 110ms, 210ms
|
|
70
|
+
* input$.next('A');
|
|
60
71
|
*
|
|
61
|
-
*
|
|
72
|
+
* await sleep(250);
|
|
62
73
|
*
|
|
63
|
-
*
|
|
64
|
-
*
|
|
65
|
-
*
|
|
74
|
+
* assert.deepStrictEqual(valueHistory, ['A1', 'A2', 'A3']);
|
|
75
|
+
*
|
|
76
|
+
* // Emit B - inner starts emitting B1, B2 at 10ms, 110ms
|
|
77
|
+
* input$.next('B');
|
|
78
|
+
*
|
|
79
|
+
* await sleep(150);
|
|
66
80
|
*
|
|
67
|
-
* assert.deepStrictEqual(
|
|
81
|
+
* assert.deepStrictEqual(valueHistory, ['A1', 'A2', 'A3', 'B1', 'B2']);
|
|
68
82
|
*
|
|
69
|
-
*
|
|
83
|
+
* // Emit C while B's inner is still running (B3 at 210ms not yet fired)
|
|
84
|
+
* // Unlike switchMap, B's inner is NOT cancelled
|
|
85
|
+
* input$.next('C');
|
|
70
86
|
*
|
|
71
|
-
*
|
|
87
|
+
* await sleep(250);
|
|
72
88
|
*
|
|
73
|
-
*
|
|
89
|
+
* // B3 appears between C1 and C2, showing the merge behavior
|
|
90
|
+
* assert.deepStrictEqual(valueHistory, [
|
|
91
|
+
* 'A1',
|
|
92
|
+
* 'A2',
|
|
93
|
+
* 'A3',
|
|
94
|
+
* 'B1',
|
|
95
|
+
* 'B2',
|
|
96
|
+
* 'C1',
|
|
97
|
+
* 'B3',
|
|
98
|
+
* 'C2',
|
|
99
|
+
* 'C3',
|
|
100
|
+
* ]);
|
|
74
101
|
* ```
|
|
75
102
|
*
|
|
76
103
|
* @note To improve code readability, consider using `createState` instead of `mergeMap`,
|
|
@@ -84,7 +111,7 @@ export const mergeMap =
|
|
|
84
111
|
new MergeMapObservableClass(parentObservable, mapToObservable);
|
|
85
112
|
|
|
86
113
|
/**
|
|
87
|
-
* Alias for `mergeMap
|
|
114
|
+
* Alias for `mergeMap`.
|
|
88
115
|
* @see mergeMap
|
|
89
116
|
*/
|
|
90
117
|
export const flatMap = mergeMap;
|
|
@@ -113,12 +140,12 @@ class MergeMapObservableClass<A, B>
|
|
|
113
140
|
this.#mut_subscriptions = [];
|
|
114
141
|
}
|
|
115
142
|
|
|
116
|
-
override tryUpdate(
|
|
143
|
+
override tryUpdate(updateToken: UpdateToken): void {
|
|
117
144
|
const par = this.parents[0];
|
|
118
145
|
|
|
119
146
|
const sn = par.getSnapshot();
|
|
120
147
|
|
|
121
|
-
if (par.
|
|
148
|
+
if (par.updateToken !== updateToken || Optional.isNone(sn)) {
|
|
122
149
|
return; // skip update
|
|
123
150
|
}
|
|
124
151
|
|
|
@@ -4,7 +4,7 @@ import {
|
|
|
4
4
|
type DropInitialValueOperator,
|
|
5
5
|
type Observable,
|
|
6
6
|
type PairwiseOperatorObservable,
|
|
7
|
-
type
|
|
7
|
+
type UpdateToken,
|
|
8
8
|
} from '../types/index.mjs';
|
|
9
9
|
|
|
10
10
|
/**
|
|
@@ -30,30 +30,30 @@ import {
|
|
|
30
30
|
*
|
|
31
31
|
* const pairs$ = num$.pipe(pairwise());
|
|
32
32
|
*
|
|
33
|
-
* const
|
|
33
|
+
* const valueHistory: (readonly [number, number])[] = [];
|
|
34
34
|
*
|
|
35
35
|
* pairs$.subscribe(([prev, curr]) => {
|
|
36
|
-
*
|
|
36
|
+
* valueHistory.push([prev, curr]);
|
|
37
37
|
* });
|
|
38
38
|
*
|
|
39
39
|
* num$.next(1); // nothing logged
|
|
40
40
|
*
|
|
41
|
-
* assert.deepStrictEqual(
|
|
41
|
+
* assert.deepStrictEqual(valueHistory, []);
|
|
42
42
|
*
|
|
43
43
|
* num$.next(2); // logs: 1, 2
|
|
44
44
|
*
|
|
45
|
-
* assert.deepStrictEqual(
|
|
45
|
+
* assert.deepStrictEqual(valueHistory, [[1, 2]]);
|
|
46
46
|
*
|
|
47
47
|
* num$.next(3); // logs: 2, 3
|
|
48
48
|
*
|
|
49
|
-
* assert.deepStrictEqual(
|
|
49
|
+
* assert.deepStrictEqual(valueHistory, [
|
|
50
50
|
* [1, 2],
|
|
51
51
|
* [2, 3],
|
|
52
52
|
* ]);
|
|
53
53
|
*
|
|
54
54
|
* num$.next(4); // logs: 3, 4
|
|
55
55
|
*
|
|
56
|
-
* assert.deepStrictEqual(
|
|
56
|
+
* assert.deepStrictEqual(valueHistory, [
|
|
57
57
|
* [1, 2],
|
|
58
58
|
* [2, 3],
|
|
59
59
|
* [3, 4],
|
|
@@ -83,12 +83,12 @@ class PairwiseObservableClass<A>
|
|
|
83
83
|
this.#mut_previousValue = parentObservable.getSnapshot();
|
|
84
84
|
}
|
|
85
85
|
|
|
86
|
-
override tryUpdate(
|
|
86
|
+
override tryUpdate(updateToken: UpdateToken): void {
|
|
87
87
|
const par = this.parents[0];
|
|
88
88
|
|
|
89
89
|
const sn = par.getSnapshot();
|
|
90
90
|
|
|
91
|
-
if (par.
|
|
91
|
+
if (par.updateToken !== updateToken || Optional.isNone(sn)) {
|
|
92
92
|
return; // skip update
|
|
93
93
|
}
|
|
94
94
|
|
|
@@ -100,7 +100,7 @@ class PairwiseObservableClass<A>
|
|
|
100
100
|
this.#mut_previousValue = par.getSnapshot();
|
|
101
101
|
|
|
102
102
|
if (cond) {
|
|
103
|
-
this.setNext([prev.value, sn.value],
|
|
103
|
+
this.setNext([prev.value, sn.value], updateToken);
|
|
104
104
|
}
|
|
105
105
|
}
|
|
106
106
|
}
|
|
@@ -3,7 +3,7 @@ import { InitializedSyncChildObservableClass } from '../class/index.mjs';
|
|
|
3
3
|
import {
|
|
4
4
|
type Observable,
|
|
5
5
|
type ScanOperatorObservable,
|
|
6
|
-
type
|
|
6
|
+
type UpdateToken,
|
|
7
7
|
type WithInitialValueOperator,
|
|
8
8
|
} from '../types/index.mjs';
|
|
9
9
|
|
|
@@ -35,25 +35,25 @@ import {
|
|
|
35
35
|
*
|
|
36
36
|
* const sum$ = num$.pipe(scan((acc, curr) => acc + curr, 0));
|
|
37
37
|
*
|
|
38
|
-
* const
|
|
38
|
+
* const valueHistory: number[] = [];
|
|
39
39
|
*
|
|
40
40
|
* sum$.subscribe((x) => {
|
|
41
|
-
*
|
|
41
|
+
* valueHistory.push(x);
|
|
42
42
|
* });
|
|
43
43
|
*
|
|
44
|
-
* assert.deepStrictEqual(
|
|
44
|
+
* assert.deepStrictEqual(valueHistory, [0]);
|
|
45
45
|
*
|
|
46
46
|
* num$.next(1); // logs: 1
|
|
47
47
|
*
|
|
48
|
-
* assert.deepStrictEqual(
|
|
48
|
+
* assert.deepStrictEqual(valueHistory, [0, 1]);
|
|
49
49
|
*
|
|
50
50
|
* num$.next(2); // logs: 3
|
|
51
51
|
*
|
|
52
|
-
* assert.deepStrictEqual(
|
|
52
|
+
* assert.deepStrictEqual(valueHistory, [0, 1, 3]);
|
|
53
53
|
*
|
|
54
54
|
* num$.next(3); // logs: 6
|
|
55
55
|
*
|
|
56
|
-
* assert.deepStrictEqual(
|
|
56
|
+
* assert.deepStrictEqual(valueHistory, [0, 1, 3, 6]);
|
|
57
57
|
* ```
|
|
58
58
|
*/
|
|
59
59
|
export const scan =
|
|
@@ -83,7 +83,7 @@ class ScanObservableClass<A, B>
|
|
|
83
83
|
this.#reducer = reducer;
|
|
84
84
|
}
|
|
85
85
|
|
|
86
|
-
override tryUpdate(
|
|
86
|
+
override tryUpdate(updateToken: UpdateToken): void {
|
|
87
87
|
const par = this.parents[0];
|
|
88
88
|
|
|
89
89
|
const psn = par.getSnapshot();
|
|
@@ -91,13 +91,13 @@ class ScanObservableClass<A, B>
|
|
|
91
91
|
const sn = this.getSnapshot();
|
|
92
92
|
|
|
93
93
|
if (
|
|
94
|
-
par.
|
|
94
|
+
par.updateToken !== updateToken ||
|
|
95
95
|
Optional.isNone(psn) ||
|
|
96
96
|
Optional.isNone(sn)
|
|
97
97
|
) {
|
|
98
98
|
return; // skip update
|
|
99
99
|
}
|
|
100
100
|
|
|
101
|
-
this.setNext(this.#reducer(sn.value, psn.value),
|
|
101
|
+
this.setNext(this.#reducer(sn.value, psn.value), updateToken);
|
|
102
102
|
}
|
|
103
103
|
}
|