synstate 0.1.2 → 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 +199 -146
- 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 +6 -6
- package/dist/core/combine/combine.mjs +11 -12
- 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 +0 -1
- package/dist/core/index.d.mts.map +1 -1
- package/dist/core/index.mjs +8 -13
- 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 +4 -4
- package/dist/core/operators/{map-with-index.d.mts → map.d.mts} +11 -11
- package/dist/core/operators/map.d.mts.map +1 -0
- package/dist/core/operators/{map-with-index.mjs → map.mjs} +17 -17
- package/dist/core/operators/map.mjs.map +1 -0
- package/dist/core/operators/merge-map.d.mts +56 -29
- package/dist/core/operators/merge-map.d.mts.map +1 -1
- package/dist/core/operators/merge-map.mjs +58 -31
- 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 +20 -8
- package/dist/core/operators/skip-if-no-change.d.mts.map +1 -1
- package/dist/core/operators/skip-if-no-change.mjs +23 -11
- 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 -8
- package/dist/core/operators/skip-while.d.mts.map +1 -1
- package/dist/core/operators/skip-while.mjs +26 -11
- 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 -7
- package/dist/core/operators/take-while.d.mts.map +1 -1
- package/dist/core/operators/take-while.mjs +18 -10
- 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 +9 -9
- package/dist/core/operators/with-buffered-from.mjs +12 -12
- package/dist/core/operators/with-buffered-from.mjs.map +1 -1
- package/dist/core/operators/with-current-value-from.d.mts +10 -9
- package/dist/core/operators/with-current-value-from.d.mts.map +1 -1
- package/dist/core/operators/with-current-value-from.mjs +13 -12
- 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.mjs +0 -1
- package/dist/core/predefined/index.mjs.map +1 -1
- package/dist/core/predefined/operators/attach-index.d.mts +49 -0
- package/dist/core/predefined/operators/attach-index.d.mts.map +1 -1
- package/dist/core/predefined/operators/attach-index.mjs +51 -2
- package/dist/core/predefined/operators/attach-index.mjs.map +1 -1
- package/dist/core/predefined/operators/index.d.mts +0 -1
- package/dist/core/predefined/operators/index.d.mts.map +1 -1
- package/dist/core/predefined/operators/index.mjs +0 -1
- package/dist/core/predefined/operators/index.mjs.map +1 -1
- package/dist/core/predefined/operators/map-optional.d.mts +47 -0
- package/dist/core/predefined/operators/map-optional.d.mts.map +1 -1
- package/dist/core/predefined/operators/map-optional.mjs +49 -1
- package/dist/core/predefined/operators/map-optional.mjs.map +1 -1
- package/dist/core/predefined/operators/map-result-err.d.mts +47 -0
- package/dist/core/predefined/operators/map-result-err.d.mts.map +1 -1
- package/dist/core/predefined/operators/map-result-err.mjs +49 -1
- package/dist/core/predefined/operators/map-result-err.mjs.map +1 -1
- package/dist/core/predefined/operators/map-result-ok.d.mts +47 -0
- package/dist/core/predefined/operators/map-result-ok.d.mts.map +1 -1
- package/dist/core/predefined/operators/map-result-ok.mjs +49 -1
- package/dist/core/predefined/operators/map-result-ok.mjs.map +1 -1
- package/dist/core/predefined/operators/map-to.d.mts +40 -0
- package/dist/core/predefined/operators/map-to.d.mts.map +1 -1
- package/dist/core/predefined/operators/map-to.mjs +43 -1
- package/dist/core/predefined/operators/map-to.mjs.map +1 -1
- package/dist/core/predefined/operators/pluck.d.mts +39 -0
- package/dist/core/predefined/operators/pluck.d.mts.map +1 -1
- package/dist/core/predefined/operators/pluck.mjs +42 -1
- package/dist/core/predefined/operators/pluck.mjs.map +1 -1
- package/dist/core/predefined/operators/skip.d.mts +47 -0
- package/dist/core/predefined/operators/skip.d.mts.map +1 -1
- package/dist/core/predefined/operators/skip.mjs +47 -0
- package/dist/core/predefined/operators/skip.mjs.map +1 -1
- package/dist/core/predefined/operators/take.d.mts +41 -0
- package/dist/core/predefined/operators/take.d.mts.map +1 -1
- package/dist/core/predefined/operators/take.mjs +41 -0
- package/dist/core/predefined/operators/take.mjs.map +1 -1
- package/dist/core/predefined/operators/unwrap-optional.d.mts +40 -0
- package/dist/core/predefined/operators/unwrap-optional.d.mts.map +1 -1
- package/dist/core/predefined/operators/unwrap-optional.mjs +42 -1
- package/dist/core/predefined/operators/unwrap-optional.mjs.map +1 -1
- package/dist/core/predefined/operators/unwrap-result-err.d.mts +40 -0
- package/dist/core/predefined/operators/unwrap-result-err.d.mts.map +1 -1
- package/dist/core/predefined/operators/unwrap-result-err.mjs +42 -1
- package/dist/core/predefined/operators/unwrap-result-err.mjs.map +1 -1
- package/dist/core/predefined/operators/unwrap-result-ok.d.mts +40 -0
- package/dist/core/predefined/operators/unwrap-result-ok.d.mts.map +1 -1
- package/dist/core/predefined/operators/unwrap-result-ok.mjs +42 -1
- package/dist/core/predefined/operators/unwrap-result-ok.mjs.map +1 -1
- 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 +11 -14
- package/dist/entry-point.mjs.map +1 -1
- package/dist/globals.d.mts +0 -3
- package/dist/index.mjs +11 -14
- 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 +13 -13
- 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 +0 -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-with-index.mts → map.mts} +20 -20
- package/src/core/operators/merge-map.mts +59 -32
- 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 +24 -12
- package/src/core/operators/skip-until.mts +9 -9
- package/src/core/operators/skip-while.mts +29 -12
- 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 +19 -11
- package/src/core/operators/{throttle-time.mts → throttle.mts} +58 -38
- package/src/core/operators/with-buffered-from.mts +13 -13
- package/src/core/operators/with-current-value-from.mts +14 -13
- package/src/core/operators/with-initial-value.mts +9 -9
- package/src/core/predefined/operators/attach-index.mts +51 -2
- package/src/core/predefined/operators/index.mts +0 -1
- package/src/core/predefined/operators/map-optional.mts +48 -1
- package/src/core/predefined/operators/map-result-err.mts +48 -1
- package/src/core/predefined/operators/map-result-ok.mts +48 -1
- package/src/core/predefined/operators/map-to.mts +41 -1
- package/src/core/predefined/operators/pluck.mts +40 -1
- package/src/core/predefined/operators/skip.mts +47 -0
- package/src/core/predefined/operators/take.mts +41 -0
- package/src/core/predefined/operators/unwrap-optional.mts +41 -1
- package/src/core/predefined/operators/unwrap-result-err.mts +41 -1
- package/src/core/predefined/operators/unwrap-result-ok.mts +41 -1
- 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.map +0 -1
- 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/dist/core/predefined/operators/map.d.mts +0 -3
- package/dist/core/predefined/operators/map.d.mts.map +0 -1
- package/dist/core/predefined/operators/map.mjs +0 -8
- package/dist/core/predefined/operators/map.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/predefined/operators/map.mts +0 -5
|
@@ -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
|
*/
|
|
@@ -105,16 +105,16 @@ class WithBufferedFromObservableClass<A, B>
|
|
|
105
105
|
});
|
|
106
106
|
}
|
|
107
107
|
|
|
108
|
-
override tryUpdate(
|
|
108
|
+
override tryUpdate(updateToken: UpdateToken): void {
|
|
109
109
|
const par = this.parents[0];
|
|
110
110
|
|
|
111
111
|
const sn = par.getSnapshot();
|
|
112
112
|
|
|
113
|
-
if (par.
|
|
113
|
+
if (par.updateToken !== updateToken || Optional.isNone(sn)) {
|
|
114
114
|
return; // skip update
|
|
115
115
|
}
|
|
116
116
|
|
|
117
|
-
this.setNext([sn.value, this.#mut_bufferedValues],
|
|
117
|
+
this.setNext([sn.value, this.#mut_bufferedValues], updateToken);
|
|
118
118
|
|
|
119
119
|
this.#clearBuffer();
|
|
120
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
|
* ]);
|
|
@@ -99,12 +100,12 @@ class WithCurrentValueFromObservableClass<A, B>
|
|
|
99
100
|
this.#observable = observable;
|
|
100
101
|
}
|
|
101
102
|
|
|
102
|
-
override tryUpdate(
|
|
103
|
+
override tryUpdate(updateToken: UpdateToken): void {
|
|
103
104
|
const par = this.parents[0];
|
|
104
105
|
|
|
105
106
|
const ps = par.getSnapshot();
|
|
106
107
|
|
|
107
|
-
if (par.
|
|
108
|
+
if (par.updateToken !== updateToken || Optional.isNone(ps)) {
|
|
108
109
|
return; // skip update
|
|
109
110
|
}
|
|
110
111
|
|
|
@@ -112,6 +113,6 @@ class WithCurrentValueFromObservableClass<A, B>
|
|
|
112
113
|
|
|
113
114
|
if (Optional.isNone(curr)) return; // skip update
|
|
114
115
|
|
|
115
|
-
this.setNext([ps.value, curr.value],
|
|
116
|
+
this.setNext([ps.value, curr.value], updateToken);
|
|
116
117
|
}
|
|
117
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
|
|
|
@@ -1,10 +1,59 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { map } from '../../operators/index.mjs';
|
|
2
2
|
import { type KeepInitialValueOperator } from '../../types/index.mjs';
|
|
3
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
|
+
*/
|
|
4
53
|
export const withIndex = <A,>(): KeepInitialValueOperator<
|
|
5
54
|
A,
|
|
6
55
|
readonly [SafeUint | -1, A]
|
|
7
|
-
> =>
|
|
56
|
+
> => map((a, i) => [i, a] as const);
|
|
8
57
|
|
|
9
58
|
/**
|
|
10
59
|
* Alias for `withIndex`.
|
|
@@ -1,7 +1,54 @@
|
|
|
1
1
|
import { Optional } from 'ts-data-forge';
|
|
2
|
+
import { map } from '../../operators/index.mjs';
|
|
2
3
|
import { type KeepInitialValueOperator } from '../../types/index.mjs';
|
|
3
|
-
import { map } from './map.mjs';
|
|
4
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
|
+
*/
|
|
5
52
|
export const mapOptional = <O extends UnknownOptional, B>(
|
|
6
53
|
mapFn: (x: Optional.Unwrap<O>) => B,
|
|
7
54
|
): KeepInitialValueOperator<O, Optional<B>> =>
|
|
@@ -1,7 +1,54 @@
|
|
|
1
1
|
import { Result } from 'ts-data-forge';
|
|
2
|
+
import { map } from '../../operators/index.mjs';
|
|
2
3
|
import { type KeepInitialValueOperator } from '../../types/index.mjs';
|
|
3
|
-
import { map } from './map.mjs';
|
|
4
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
|
+
*/
|
|
5
52
|
export const mapResultErr = <R extends UnknownResult, E2>(
|
|
6
53
|
mapFn: (x: Result.UnwrapErr<R>) => E2,
|
|
7
54
|
): KeepInitialValueOperator<R, Result<Result.UnwrapOk<R>, E2>> =>
|
|
@@ -1,7 +1,54 @@
|
|
|
1
1
|
import { Result } from 'ts-data-forge';
|
|
2
|
+
import { map } from '../../operators/index.mjs';
|
|
2
3
|
import { type KeepInitialValueOperator } from '../../types/index.mjs';
|
|
3
|
-
import { map } from './map.mjs';
|
|
4
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
|
+
*/
|
|
5
52
|
export const mapResultOk = <R extends UnknownResult, S2>(
|
|
6
53
|
mapFn: (x: Result.UnwrapOk<R>) => S2,
|
|
7
54
|
): KeepInitialValueOperator<R, Result<S2, Result.UnwrapErr<R>>> =>
|
|
@@ -1,5 +1,45 @@
|
|
|
1
|
+
import { map } from '../../operators/index.mjs';
|
|
1
2
|
import { type KeepInitialValueOperator } from '../../types/index.mjs';
|
|
2
|
-
import { map } from './map.mjs';
|
|
3
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
|
+
*/
|
|
4
44
|
export const mapTo = <A, B>(value: B): KeepInitialValueOperator<A, B> =>
|
|
5
45
|
map(() => value);
|
|
@@ -1,6 +1,45 @@
|
|
|
1
|
+
import { map } from '../../operators/index.mjs';
|
|
1
2
|
import { type KeepInitialValueOperator } from '../../types/index.mjs';
|
|
2
|
-
import { map } from './map.mjs';
|
|
3
3
|
|
|
4
|
+
/**
|
|
5
|
+
* Extracts a property value from each emitted object by key.
|
|
6
|
+
* Equivalent to `map(value => value[key])`.
|
|
7
|
+
*
|
|
8
|
+
* @template A - The type of the emitted object
|
|
9
|
+
* @template K - The key to extract
|
|
10
|
+
* @param key - The property key to pluck
|
|
11
|
+
* @returns An operator that emits the property value
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* ```ts
|
|
15
|
+
* // Timeline:
|
|
16
|
+
* //
|
|
17
|
+
* // user$ { name: "Alice", age: 25 } { name: "Bob", age: 30 }
|
|
18
|
+
* // name$ "Alice" "Bob"
|
|
19
|
+
* //
|
|
20
|
+
* // Explanation:
|
|
21
|
+
* // - getKey extracts a property value from each emitted object
|
|
22
|
+
* // - Equivalent to map(value => value[key])
|
|
23
|
+
*
|
|
24
|
+
* const user$ = source<Readonly<{ name: string; age: number }>>();
|
|
25
|
+
*
|
|
26
|
+
* const name$ = user$.pipe(getKey('name'));
|
|
27
|
+
*
|
|
28
|
+
* const valueHistory: string[] = [];
|
|
29
|
+
*
|
|
30
|
+
* name$.subscribe((n) => {
|
|
31
|
+
* valueHistory.push(n);
|
|
32
|
+
* });
|
|
33
|
+
*
|
|
34
|
+
* user$.next({ name: 'Alice', age: 25 });
|
|
35
|
+
*
|
|
36
|
+
* assert.deepStrictEqual(valueHistory, ['Alice']);
|
|
37
|
+
*
|
|
38
|
+
* user$.next({ name: 'Bob', age: 30 });
|
|
39
|
+
*
|
|
40
|
+
* assert.deepStrictEqual(valueHistory, ['Alice', 'Bob']);
|
|
41
|
+
* ```
|
|
42
|
+
*/
|
|
4
43
|
export const pluck = <A, K extends keyof A>(
|
|
5
44
|
key: K,
|
|
6
45
|
): KeepInitialValueOperator<A, A[K]> => map((a) => a[key]);
|
|
@@ -2,6 +2,53 @@ import { PositiveSafeInt } from 'ts-data-forge';
|
|
|
2
2
|
import { skipWhile } from '../../operators/index.mjs';
|
|
3
3
|
import { type DropInitialValueOperator } from '../../types/index.mjs';
|
|
4
4
|
|
|
5
|
+
/**
|
|
6
|
+
* Skips the first `n` emissions from the source observable.
|
|
7
|
+
* After `n` values are skipped, all subsequent values pass through.
|
|
8
|
+
*
|
|
9
|
+
* @template A - The type of values from the source
|
|
10
|
+
* @param n - The number of values to skip
|
|
11
|
+
* @returns An operator that skips the first n emissions
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* ```ts
|
|
15
|
+
* // Timeline:
|
|
16
|
+
* //
|
|
17
|
+
* // num$ 1 2 3 4 5
|
|
18
|
+
* // skipped$ 3 4 5
|
|
19
|
+
* // |skip 2|
|
|
20
|
+
* //
|
|
21
|
+
* // Explanation:
|
|
22
|
+
* // - skip ignores the first n emissions from the source
|
|
23
|
+
* // - After n values are skipped, all subsequent values pass through
|
|
24
|
+
*
|
|
25
|
+
* const num$ = source<number>();
|
|
26
|
+
*
|
|
27
|
+
* const skipped$ = num$.pipe(skip(2));
|
|
28
|
+
*
|
|
29
|
+
* const valueHistory: number[] = [];
|
|
30
|
+
*
|
|
31
|
+
* skipped$.subscribe((x) => {
|
|
32
|
+
* valueHistory.push(x);
|
|
33
|
+
* });
|
|
34
|
+
*
|
|
35
|
+
* num$.next(1); // skipped
|
|
36
|
+
*
|
|
37
|
+
* num$.next(2); // skipped
|
|
38
|
+
*
|
|
39
|
+
* assert.deepStrictEqual(valueHistory, []);
|
|
40
|
+
*
|
|
41
|
+
* num$.next(3); // logs: 3
|
|
42
|
+
*
|
|
43
|
+
* assert.deepStrictEqual(valueHistory, [3]);
|
|
44
|
+
*
|
|
45
|
+
* num$.next(4); // logs: 4
|
|
46
|
+
*
|
|
47
|
+
* num$.next(5); // logs: 5
|
|
48
|
+
*
|
|
49
|
+
* assert.deepStrictEqual(valueHistory, [3, 4, 5]);
|
|
50
|
+
* ```
|
|
51
|
+
*/
|
|
5
52
|
export const skip = <A,>(
|
|
6
53
|
n: PositiveSafeIntWithSmallInt,
|
|
7
54
|
): DropInitialValueOperator<A, A> =>
|
|
@@ -1,6 +1,47 @@
|
|
|
1
1
|
import { takeWhile } from '../../operators/index.mjs';
|
|
2
2
|
import { type DropInitialValueOperator } from '../../types/index.mjs';
|
|
3
3
|
|
|
4
|
+
/**
|
|
5
|
+
* Takes only the first `n` emissions from the source observable, then completes.
|
|
6
|
+
*
|
|
7
|
+
* @template A - The type of values from the source
|
|
8
|
+
* @param n - The number of values to take
|
|
9
|
+
* @returns An operator that takes the first n emissions
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* ```ts
|
|
13
|
+
* // Timeline:
|
|
14
|
+
* //
|
|
15
|
+
* // num$ 1 2 3 4 (ignored)
|
|
16
|
+
* // taken$ 1 2 3 | (completes)
|
|
17
|
+
* //
|
|
18
|
+
* // Explanation:
|
|
19
|
+
* // - take emits only the first n values, then completes
|
|
20
|
+
* // - Subsequent emissions from the source are ignored
|
|
21
|
+
*
|
|
22
|
+
* const num$ = source<number>();
|
|
23
|
+
*
|
|
24
|
+
* const taken$ = num$.pipe(take(3));
|
|
25
|
+
*
|
|
26
|
+
* const valueHistory: number[] = [];
|
|
27
|
+
*
|
|
28
|
+
* taken$.subscribe((x) => {
|
|
29
|
+
* valueHistory.push(x);
|
|
30
|
+
* });
|
|
31
|
+
*
|
|
32
|
+
* num$.next(1);
|
|
33
|
+
*
|
|
34
|
+
* num$.next(2);
|
|
35
|
+
*
|
|
36
|
+
* num$.next(3);
|
|
37
|
+
*
|
|
38
|
+
* assert.deepStrictEqual(valueHistory, [1, 2, 3]);
|
|
39
|
+
*
|
|
40
|
+
* num$.next(4); // ignored (already completed)
|
|
41
|
+
*
|
|
42
|
+
* assert.deepStrictEqual(valueHistory, [1, 2, 3]);
|
|
43
|
+
* ```
|
|
44
|
+
*/
|
|
4
45
|
export const take = <A,>(
|
|
5
46
|
n: PositiveSafeIntWithSmallInt,
|
|
6
47
|
): DropInitialValueOperator<A, A> => takeWhile((_, index) => index + 1 <= n);
|
|
@@ -1,7 +1,47 @@
|
|
|
1
1
|
import { Optional } from 'ts-data-forge';
|
|
2
|
+
import { map } from '../../operators/index.mjs';
|
|
2
3
|
import { type KeepInitialValueOperator } from '../../types/index.mjs';
|
|
3
|
-
import { map } from './map.mjs';
|
|
4
4
|
|
|
5
|
+
/**
|
|
6
|
+
* Unwraps `Optional` values, converting `Some(value)` to `value` and `None` to `undefined`.
|
|
7
|
+
*
|
|
8
|
+
* @template O - The Optional type from the source
|
|
9
|
+
* @returns An operator that unwraps Optional emissions
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* ```ts
|
|
13
|
+
* // Timeline:
|
|
14
|
+
* //
|
|
15
|
+
* // opt$ Some(42) None Some(7)
|
|
16
|
+
* // unwrapped$ 42 undefined 7
|
|
17
|
+
* //
|
|
18
|
+
* // Explanation:
|
|
19
|
+
* // - unwrapOptional converts Some(value) to value, and None to undefined
|
|
20
|
+
* // - Useful for extracting raw values from Optional streams
|
|
21
|
+
*
|
|
22
|
+
* const opt$ = source<Optional<number>>();
|
|
23
|
+
*
|
|
24
|
+
* const unwrapped$ = opt$.pipe(unwrapOptional());
|
|
25
|
+
*
|
|
26
|
+
* const valueHistory: (number | undefined)[] = [];
|
|
27
|
+
*
|
|
28
|
+
* unwrapped$.subscribe((v) => {
|
|
29
|
+
* valueHistory.push(v);
|
|
30
|
+
* });
|
|
31
|
+
*
|
|
32
|
+
* opt$.next(Optional.some(42));
|
|
33
|
+
*
|
|
34
|
+
* assert.deepStrictEqual(valueHistory, [42]);
|
|
35
|
+
*
|
|
36
|
+
* opt$.next(Optional.none);
|
|
37
|
+
*
|
|
38
|
+
* assert.deepStrictEqual(valueHistory, [42, undefined]);
|
|
39
|
+
*
|
|
40
|
+
* opt$.next(Optional.some(7));
|
|
41
|
+
*
|
|
42
|
+
* assert.deepStrictEqual(valueHistory, [42, undefined, 7]);
|
|
43
|
+
* ```
|
|
44
|
+
*/
|
|
5
45
|
export const unwrapOptional = <
|
|
6
46
|
O extends UnknownOptional,
|
|
7
47
|
>(): KeepInitialValueOperator<O, Optional.Unwrap<O> | undefined> =>
|