synstate 1.0.2 → 2.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +16 -17
- package/dist/core/class/child-observable-class.d.mts.map +1 -1
- package/dist/core/class/child-observable-class.mjs +148 -140
- package/dist/core/class/child-observable-class.mjs.map +1 -1
- package/dist/core/class/observable-base-class.d.mts.map +1 -1
- package/dist/core/class/observable-base-class.mjs +111 -107
- package/dist/core/class/observable-base-class.mjs.map +1 -1
- package/dist/core/class/root-observable-class.d.mts.map +1 -1
- package/dist/core/class/root-observable-class.mjs +32 -24
- package/dist/core/class/root-observable-class.mjs.map +1 -1
- package/dist/core/combine/combine.d.mts +3 -3
- package/dist/core/combine/combine.d.mts.map +1 -1
- package/dist/core/combine/combine.mjs +31 -113
- package/dist/core/combine/combine.mjs.map +1 -1
- package/dist/core/combine/merge.d.mts +2 -2
- package/dist/core/combine/merge.d.mts.map +1 -1
- package/dist/core/combine/merge.mjs +21 -69
- package/dist/core/combine/merge.mjs.map +1 -1
- package/dist/core/combine/zip.d.mts +2 -2
- package/dist/core/combine/zip.d.mts.map +1 -1
- package/dist/core/combine/zip.mjs +34 -79
- package/dist/core/combine/zip.mjs.map +1 -1
- package/dist/core/create/counter.d.mts +1 -1
- package/dist/core/create/counter.d.mts.map +1 -1
- package/dist/core/create/counter.mjs +45 -84
- package/dist/core/create/counter.mjs.map +1 -1
- package/dist/core/create/from-abortable-promise.d.mts.map +1 -1
- package/dist/core/create/from-abortable-promise.mjs +29 -61
- package/dist/core/create/from-abortable-promise.mjs.map +1 -1
- package/dist/core/create/from-promise.d.mts.map +1 -1
- package/dist/core/create/from-promise.mjs +17 -66
- package/dist/core/create/from-promise.mjs.map +1 -1
- package/dist/core/create/from-subscribable.d.mts.map +1 -1
- package/dist/core/create/from-subscribable.mjs +18 -69
- package/dist/core/create/from-subscribable.mjs.map +1 -1
- package/dist/core/create/just.d.mts.map +1 -1
- package/dist/core/create/just.mjs +5 -35
- package/dist/core/create/just.mjs.map +1 -1
- package/dist/core/create/source.mjs +10 -13
- package/dist/core/create/source.mjs.map +1 -1
- package/dist/core/create/timer.d.mts.map +1 -1
- package/dist/core/create/timer.mjs +32 -68
- package/dist/core/create/timer.mjs.map +1 -1
- package/dist/core/operators/audit.d.mts.map +1 -1
- package/dist/core/operators/audit.mjs +39 -133
- package/dist/core/operators/audit.mjs.map +1 -1
- package/dist/core/operators/debounce.d.mts.map +1 -1
- package/dist/core/operators/debounce.mjs +36 -119
- package/dist/core/operators/debounce.mjs.map +1 -1
- package/dist/core/operators/filter.mjs +22 -25
- package/dist/core/operators/filter.mjs.map +1 -1
- package/dist/core/operators/map.d.mts.map +1 -1
- package/dist/core/operators/map.mjs +28 -61
- package/dist/core/operators/map.mjs.map +1 -1
- package/dist/core/operators/merge-map.d.mts +1 -1
- package/dist/core/operators/merge-map.d.mts.map +1 -1
- package/dist/core/operators/merge-map.mjs +34 -130
- package/dist/core/operators/merge-map.mjs.map +1 -1
- package/dist/core/operators/pairwise.d.mts +3 -2
- package/dist/core/operators/pairwise.d.mts.map +1 -1
- package/dist/core/operators/pairwise.mjs +19 -75
- package/dist/core/operators/pairwise.mjs.map +1 -1
- package/dist/core/operators/scan.d.mts.map +1 -1
- package/dist/core/operators/scan.mjs +16 -67
- package/dist/core/operators/scan.mjs.map +1 -1
- package/dist/core/operators/skip-if-no-change.d.mts +1 -1
- package/dist/core/operators/skip-if-no-change.d.mts.map +1 -1
- package/dist/core/operators/skip-if-no-change.mjs +28 -92
- package/dist/core/operators/skip-if-no-change.mjs.map +1 -1
- package/dist/core/operators/skip-until.d.mts.map +1 -1
- package/dist/core/operators/skip-until.mjs +23 -72
- package/dist/core/operators/skip-until.mjs.map +1 -1
- package/dist/core/operators/skip-while.d.mts.map +1 -1
- package/dist/core/operators/skip-while.mjs +26 -88
- package/dist/core/operators/skip-while.mjs.map +1 -1
- package/dist/core/operators/switch-map.d.mts.map +1 -1
- package/dist/core/operators/switch-map.mjs +31 -124
- package/dist/core/operators/switch-map.mjs.map +1 -1
- package/dist/core/operators/take-until.d.mts.map +1 -1
- package/dist/core/operators/take-until.mjs +28 -69
- package/dist/core/operators/take-until.mjs.map +1 -1
- package/dist/core/operators/take-while.d.mts.map +1 -1
- package/dist/core/operators/take-while.mjs +23 -83
- package/dist/core/operators/take-while.mjs.map +1 -1
- package/dist/core/operators/throttle.d.mts.map +1 -1
- package/dist/core/operators/throttle.mjs +38 -115
- package/dist/core/operators/throttle.mjs.map +1 -1
- package/dist/core/operators/with-buffered-from.d.mts +1 -1
- package/dist/core/operators/with-buffered-from.d.mts.map +1 -1
- package/dist/core/operators/with-buffered-from.mjs +37 -90
- package/dist/core/operators/with-buffered-from.mjs.map +1 -1
- package/dist/core/operators/with-current-value-from.d.mts +1 -1
- package/dist/core/operators/with-current-value-from.d.mts.map +1 -1
- package/dist/core/operators/with-current-value-from.mjs +23 -84
- package/dist/core/operators/with-current-value-from.mjs.map +1 -1
- package/dist/core/operators/with-initial-value.d.mts.map +1 -1
- package/dist/core/operators/with-initial-value.mjs +13 -58
- package/dist/core/operators/with-initial-value.mjs.map +1 -1
- package/dist/core/predefined/operators/attach-index.d.mts +1 -1
- package/dist/core/predefined/operators/attach-index.d.mts.map +1 -1
- package/dist/core/predefined/operators/attach-index.mjs +0 -53
- package/dist/core/predefined/operators/attach-index.mjs.map +1 -1
- package/dist/core/predefined/operators/map-optional.d.mts.map +1 -1
- package/dist/core/predefined/operators/map-optional.mjs +1 -48
- package/dist/core/predefined/operators/map-optional.mjs.map +1 -1
- package/dist/core/predefined/operators/map-result-err.d.mts.map +1 -1
- package/dist/core/predefined/operators/map-result-err.mjs +1 -48
- package/dist/core/predefined/operators/map-result-err.mjs.map +1 -1
- package/dist/core/predefined/operators/map-result-ok.d.mts.map +1 -1
- package/dist/core/predefined/operators/map-result-ok.mjs +1 -48
- package/dist/core/predefined/operators/map-result-ok.mjs.map +1 -1
- package/dist/core/predefined/operators/map-to.d.mts.map +1 -1
- package/dist/core/predefined/operators/map-to.mjs +0 -40
- package/dist/core/predefined/operators/map-to.mjs.map +1 -1
- package/dist/core/predefined/operators/pluck.d.mts +1 -1
- package/dist/core/predefined/operators/pluck.d.mts.map +1 -1
- package/dist/core/predefined/operators/pluck.mjs +0 -43
- package/dist/core/predefined/operators/pluck.mjs.map +1 -1
- package/dist/core/predefined/operators/skip.d.mts.map +1 -1
- package/dist/core/predefined/operators/skip.mjs +0 -47
- package/dist/core/predefined/operators/skip.mjs.map +1 -1
- package/dist/core/predefined/operators/take.d.mts.map +1 -1
- package/dist/core/predefined/operators/take.mjs +0 -41
- package/dist/core/predefined/operators/take.mjs.map +1 -1
- package/dist/core/predefined/operators/unwrap-optional.mjs +4 -43
- package/dist/core/predefined/operators/unwrap-optional.mjs.map +1 -1
- package/dist/core/predefined/operators/unwrap-result-err.mjs +0 -40
- package/dist/core/predefined/operators/unwrap-result-err.mjs.map +1 -1
- package/dist/core/predefined/operators/unwrap-result-ok.mjs +4 -43
- package/dist/core/predefined/operators/unwrap-result-ok.mjs.map +1 -1
- package/dist/core/types/observable-family.d.mts +10 -10
- package/dist/core/types/observable-family.d.mts.map +1 -1
- package/dist/core/types/observable.d.mts.map +1 -1
- package/dist/core/types/observable.mjs +3 -5
- package/dist/core/types/observable.mjs.map +1 -1
- package/dist/core/types/types.d.mts +2 -1
- package/dist/core/types/types.d.mts.map +1 -1
- package/dist/core/utils/id-maker.mjs +5 -6
- package/dist/core/utils/id-maker.mjs.map +1 -1
- package/dist/core/utils/max-depth.d.mts.map +1 -1
- package/dist/core/utils/max-depth.mjs +1 -3
- package/dist/core/utils/max-depth.mjs.map +1 -1
- package/dist/core/utils/observable-utils.d.mts.map +1 -1
- package/dist/core/utils/observable-utils.mjs +3 -2
- package/dist/core/utils/observable-utils.mjs.map +1 -1
- package/dist/core/utils/utils.d.mts.map +1 -1
- package/dist/core/utils/utils.mjs +23 -30
- package/dist/core/utils/utils.mjs.map +1 -1
- package/dist/utils/collect-to-array.d.mts.map +1 -1
- package/dist/utils/collect-to-array.mjs +9 -6
- package/dist/utils/collect-to-array.mjs.map +1 -1
- package/dist/utils/create-boolean-state.d.mts +1 -1
- package/dist/utils/create-boolean-state.d.mts.map +1 -1
- package/dist/utils/create-boolean-state.mjs +18 -46
- package/dist/utils/create-boolean-state.mjs.map +1 -1
- package/dist/utils/create-event-emitter.mjs +10 -64
- package/dist/utils/create-event-emitter.mjs.map +1 -1
- package/dist/utils/create-reducer.d.mts +1 -1
- package/dist/utils/create-reducer.d.mts.map +1 -1
- package/dist/utils/create-reducer.mjs +8 -52
- package/dist/utils/create-reducer.mjs.map +1 -1
- package/dist/utils/create-state.d.mts +1 -1
- package/dist/utils/create-state.d.mts.map +1 -1
- package/dist/utils/create-state.mjs +23 -53
- package/dist/utils/create-state.mjs.map +1 -1
- package/package.json +42 -29
- package/src/core/class/child-observable-class.mts +1 -1
- package/src/core/class/observable-base-class.mts +16 -16
- package/src/core/combine/combine.mts +38 -16
- package/src/core/combine/merge.mts +3 -3
- package/src/core/combine/zip.mts +24 -13
- package/src/core/create/counter.mts +11 -9
- package/src/core/create/counter.test.mts +11 -0
- package/src/core/create/timer.mts +6 -6
- package/src/core/create/timer.test.mts +11 -0
- package/src/core/operators/audit-throttle-teardown.test.mts +21 -0
- package/src/core/operators/audit.mts +6 -6
- package/src/core/operators/debounce.mts +6 -6
- package/src/core/operators/pairwise.mts +10 -5
- package/src/core/operators/skip-while.mts +1 -5
- package/src/core/operators/skip-while.test.mts +20 -0
- package/src/core/operators/throttle.mts +6 -6
- package/src/core/operators/with-buffered-from.mts +4 -4
- package/src/core/predefined/operators/map-optional.mts +1 -2
- package/src/core/predefined/operators/map-result-err.mts +1 -1
- package/src/core/predefined/operators/map-result-ok.mts +1 -1
- package/src/core/types/observable-family.mts +12 -11
- package/src/core/types/observable.mts +5 -7
- package/src/core/types/types.mts +2 -1
- package/src/core/utils/max-depth.mts +5 -1
- package/src/core/utils/utils.mts +1 -1
- package/src/utils/create-boolean-state.mts +1 -1
- package/src/utils/create-reducer.mts +1 -1
- package/src/utils/create-state.mts +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"skip-until.d.mts","sourceRoot":"","sources":["../../../src/core/operators/skip-until.mts"],"names":[],"mappings":"AAEA,OAAO,EACL,KAAK,wBAAwB,EAC7B,KAAK,UAAU,EAGhB,MAAM,oBAAoB,CAAC;AAE5B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiDG;AACH,eAAO,MAAM,SAAS,GACnB,CAAC,
|
|
1
|
+
{"version":3,"file":"skip-until.d.mts","sourceRoot":"","sources":["../../../src/core/operators/skip-until.mts"],"names":[],"mappings":"AAEA,OAAO,EACL,KAAK,wBAAwB,EAC7B,KAAK,UAAU,EAGhB,MAAM,oBAAoB,CAAC;AAE5B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiDG;AACH,eAAO,MAAM,SAAS,GACnB,CAAC,YAAa,UAAU,CAAC,OAAO,CAAC,KAAG,wBAAwB,CAAC,CAAC,EAAE,CAAC,CAER,CAAC"}
|
|
@@ -2,81 +2,32 @@ import { Optional } from 'ts-data-forge';
|
|
|
2
2
|
import { SyncChildObservableClass } from '../class/child-observable-class.mjs';
|
|
3
3
|
import '../utils/id-maker.mjs';
|
|
4
4
|
|
|
5
|
-
/**
|
|
6
|
-
* Skips all values from the source observable until the notifier observable emits.
|
|
7
|
-
*
|
|
8
|
-
* @template A - The type of values from the source
|
|
9
|
-
* @param notifier - An observable that signals when to start emitting
|
|
10
|
-
* @returns An operator that skips values until the notifier emits
|
|
11
|
-
*
|
|
12
|
-
* @example
|
|
13
|
-
* ```ts
|
|
14
|
-
* // Timeline:
|
|
15
|
-
* //
|
|
16
|
-
* // num$ 1 2 3 start 4 5 6
|
|
17
|
-
* // startNotifier X
|
|
18
|
-
* // skipped$ 4 5 6
|
|
19
|
-
* // |------ skipped -------|
|
|
20
|
-
* //
|
|
21
|
-
* // Explanation:
|
|
22
|
-
* // - skipUntil ignores all values until the notifier emits
|
|
23
|
-
* // - After the notifier emits, all subsequent values are passed through
|
|
24
|
-
* // - Opposite of takeUntil (which completes when notifier emits)
|
|
25
|
-
*
|
|
26
|
-
* const num$ = source<number>();
|
|
27
|
-
*
|
|
28
|
-
* const [startNotifier, start_] = createEventEmitter();
|
|
29
|
-
*
|
|
30
|
-
* const skipped$ = num$.pipe(skipUntil(startNotifier));
|
|
31
|
-
*
|
|
32
|
-
* const valueHistory: number[] = [];
|
|
33
|
-
*
|
|
34
|
-
* skipped$.subscribe((x) => {
|
|
35
|
-
* valueHistory.push(x);
|
|
36
|
-
* });
|
|
37
|
-
*
|
|
38
|
-
* num$.next(1); // nothing logged
|
|
39
|
-
*
|
|
40
|
-
* num$.next(2); // nothing logged
|
|
41
|
-
*
|
|
42
|
-
* assert.deepStrictEqual(valueHistory, []);
|
|
43
|
-
*
|
|
44
|
-
* start_();
|
|
45
|
-
*
|
|
46
|
-
* num$.next(4); // logs: 4
|
|
47
|
-
*
|
|
48
|
-
* assert.deepStrictEqual(valueHistory, [4]);
|
|
49
|
-
*
|
|
50
|
-
* num$.next(5); // logs: 5
|
|
51
|
-
*
|
|
52
|
-
* assert.deepStrictEqual(valueHistory, [4, 5]);
|
|
53
|
-
* ```
|
|
54
|
-
*/
|
|
55
5
|
const skipUntil = (notifier) => (parentObservable) => new SkipUntilObservableClass(parentObservable, notifier);
|
|
56
6
|
class SkipUntilObservableClass extends SyncChildObservableClass {
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
this.setNext(sn.value, updateToken);
|
|
7
|
+
#mut_isSkipping;
|
|
8
|
+
constructor(parentObservable, notifier) {
|
|
9
|
+
super({
|
|
10
|
+
parents: [parentObservable],
|
|
11
|
+
initialValue: Optional.none
|
|
12
|
+
});
|
|
13
|
+
this.#mut_isSkipping = true;
|
|
14
|
+
notifier.subscribe(
|
|
15
|
+
() => {
|
|
16
|
+
this.#mut_isSkipping = false;
|
|
17
|
+
},
|
|
18
|
+
() => {
|
|
19
|
+
this.#mut_isSkipping = false;
|
|
20
|
+
}
|
|
21
|
+
);
|
|
22
|
+
}
|
|
23
|
+
tryUpdate(updateToken) {
|
|
24
|
+
const par = this.parents[0];
|
|
25
|
+
const sn = par.getSnapshot();
|
|
26
|
+
if (par.updateToken !== updateToken || Optional.isNone(sn) || this.#mut_isSkipping) {
|
|
27
|
+
return;
|
|
79
28
|
}
|
|
29
|
+
this.setNext(sn.value, updateToken);
|
|
30
|
+
}
|
|
80
31
|
}
|
|
81
32
|
|
|
82
33
|
export { skipUntil };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"skip-until.mjs","sources":["../../../src/core/operators/skip-until.mts"],"sourcesContent":[
|
|
1
|
+
{"version":3,"file":"skip-until.mjs","sources":["../../../src/core/operators/skip-until.mts"],"sourcesContent":["import { Optional } from 'ts-data-forge';\nimport { SyncChildObservableClass } from '../class/index.mjs';\nimport {\n type DropInitialValueOperator,\n type Observable,\n type SkipUntilOperatorObservable,\n type UpdateToken,\n} from '../types/index.mjs';\n\n/**\n * Skips all values from the source observable until the notifier observable emits.\n *\n * @template A - The type of values from the source\n * @param notifier - An observable that signals when to start emitting\n * @returns An operator that skips values until the notifier emits\n *\n * @example\n * ```ts\n * // Timeline:\n * //\n * // num$ 1 2 3 start 4 5 6\n * // startNotifier X\n * // skipped$ 4 5 6\n * // |------ skipped -------|\n * //\n * // Explanation:\n * // - skipUntil ignores all values until the notifier emits\n * // - After the notifier emits, all subsequent values are passed through\n * // - Opposite of takeUntil (which completes when notifier emits)\n *\n * const num$ = source<number>();\n *\n * const [startNotifier, start_] = createEventEmitter();\n *\n * const skipped$ = num$.pipe(skipUntil(startNotifier));\n *\n * const valueHistory: number[] = [];\n *\n * skipped$.subscribe((x) => {\n * valueHistory.push(x);\n * });\n *\n * num$.next(1); // nothing logged\n *\n * num$.next(2); // nothing logged\n *\n * assert.deepStrictEqual(valueHistory, []);\n *\n * start_();\n *\n * num$.next(4); // logs: 4\n *\n * assert.deepStrictEqual(valueHistory, [4]);\n *\n * num$.next(5); // logs: 5\n *\n * assert.deepStrictEqual(valueHistory, [4, 5]);\n * ```\n */\nexport const skipUntil =\n <A,>(notifier: Observable<unknown>): DropInitialValueOperator<A, A> =>\n (parentObservable) =>\n new SkipUntilObservableClass(parentObservable, notifier);\n\nclass SkipUntilObservableClass<A>\n extends SyncChildObservableClass<A, readonly [A]>\n implements SkipUntilOperatorObservable<A>\n{\n #mut_isSkipping: boolean;\n\n constructor(parentObservable: Observable<A>, notifier: Observable<unknown>) {\n super({\n parents: [parentObservable],\n initialValue: Optional.none,\n });\n\n this.#mut_isSkipping = true;\n\n notifier.subscribe(\n () => {\n this.#mut_isSkipping = false;\n },\n () => {\n this.#mut_isSkipping = false;\n },\n );\n }\n\n override tryUpdate(updateToken: UpdateToken): void {\n const par = this.parents[0];\n\n const sn = par.getSnapshot();\n\n if (\n par.updateToken !== updateToken ||\n Optional.isNone(sn) ||\n this.#mut_isSkipping\n ) {\n return; // skip update\n }\n\n this.setNext(sn.value, updateToken);\n }\n}\n"],"names":[],"mappings":";;;;AA2DO,MAAM,SAAA,GACX,CAAK,QAAA,KACL,CAAC,qBACC,IAAI,wBAAA,CAAyB,kBAAkB,QAAQ;AAE3D,MAAM,iCACI,wBAAA,CAEV;AAAA,EACE,eAAA;AAAA,EAEA,WAAA,CAAY,kBAAiC,QAAA,EAA+B;AAC1E,IAAA,KAAA,CAAM;AAAA,MACJ,OAAA,EAAS,CAAC,gBAAgB,CAAA;AAAA,MAC1B,cAAc,QAAA,CAAS;AAAA,KACxB,CAAA;AAED,IAAA,IAAA,CAAK,eAAA,GAAkB,IAAA;AAEvB,IAAA,QAAA,CAAS,SAAA;AAAA,MACP,MAAM;AACJ,QAAA,IAAA,CAAK,eAAA,GAAkB,KAAA;AAAA,MACzB,CAAA;AAAA,MACA,MAAM;AACJ,QAAA,IAAA,CAAK,eAAA,GAAkB,KAAA;AAAA,MACzB;AAAA,KACF;AAAA,EACF;AAAA,EAES,UAAU,WAAA,EAAgC;AACjD,IAAA,MAAM,GAAA,GAAM,IAAA,CAAK,OAAA,CAAQ,CAAC,CAAA;AAE1B,IAAA,MAAM,EAAA,GAAK,IAAI,WAAA,EAAY;AAE3B,IAAA,IACE,GAAA,CAAI,gBAAgB,WAAA,IACpB,QAAA,CAAS,OAAO,EAAE,CAAA,IAClB,KAAK,eAAA,EACL;AACA,MAAA;AAAA,IACF;AAEA,IAAA,IAAA,CAAK,OAAA,CAAQ,EAAA,CAAG,KAAA,EAAO,WAAW,CAAA;AAAA,EACpC;AACF;;;;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"skip-while.d.mts","sourceRoot":"","sources":["../../../src/core/operators/skip-while.mts"],"names":[],"mappings":"AAAA,OAAO,EAAY,QAAQ,EAAoB,MAAM,eAAe,CAAC;AAErE,OAAO,EACL,KAAK,wBAAwB,EAI9B,MAAM,oBAAoB,CAAC;AAE5B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyDG;AACH,eAAO,MAAM,SAAS,GACnB,CAAC,
|
|
1
|
+
{"version":3,"file":"skip-while.d.mts","sourceRoot":"","sources":["../../../src/core/operators/skip-while.mts"],"names":[],"mappings":"AAAA,OAAO,EAAY,QAAQ,EAAoB,MAAM,eAAe,CAAC;AAErE,OAAO,EACL,KAAK,wBAAwB,EAI9B,MAAM,oBAAoB,CAAC;AAE5B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyDG;AACH,eAAO,MAAM,SAAS,GACnB,CAAC,aACW,CAAC,KAAK,EAAE,CAAC,EAAE,KAAK,EAAE,QAAQ,GAAG,CAAC,CAAC,KAAK,OAAO,KACrD,wBAAwB,CAAC,CAAC,EAAE,CAAC,CAE2B,CAAC"}
|
|
@@ -2,98 +2,36 @@ import { pipe, Optional, asSafeUint, SafeUint } from 'ts-data-forge';
|
|
|
2
2
|
import { SyncChildObservableClass } from '../class/child-observable-class.mjs';
|
|
3
3
|
import '../utils/id-maker.mjs';
|
|
4
4
|
|
|
5
|
-
/**
|
|
6
|
-
* Skips values from the source observable while the predicate returns true.
|
|
7
|
-
* Once the predicate returns false, all subsequent values pass through.
|
|
8
|
-
*
|
|
9
|
-
* @template A - The type of values from the source
|
|
10
|
-
* @param predicate - Function to test each value
|
|
11
|
-
* @returns An operator that skips values while the predicate is true
|
|
12
|
-
*
|
|
13
|
-
* @example
|
|
14
|
-
* ```ts
|
|
15
|
-
* // Timeline:
|
|
16
|
-
* //
|
|
17
|
-
* // num$ 1 2 3 4 5 6 7 1 2
|
|
18
|
-
* // skipped$ 5 6 7 1 2
|
|
19
|
-
* // |-------- skip --------|
|
|
20
|
-
* //
|
|
21
|
-
* // Explanation:
|
|
22
|
-
* // - skipWhile skips values while the predicate returns true
|
|
23
|
-
* // - Once the predicate returns false, all subsequent values pass through
|
|
24
|
-
* // - Unlike filter, the predicate is never checked again after the first false
|
|
25
|
-
*
|
|
26
|
-
* const num$ = source<number>();
|
|
27
|
-
*
|
|
28
|
-
* const skipped$ = num$.pipe(skipWhile((x) => x < 5));
|
|
29
|
-
*
|
|
30
|
-
* const valueHistory: number[] = [];
|
|
31
|
-
*
|
|
32
|
-
* skipped$.subscribe((x) => {
|
|
33
|
-
* valueHistory.push(x);
|
|
34
|
-
* });
|
|
35
|
-
*
|
|
36
|
-
* num$.next(1); // nothing logged
|
|
37
|
-
*
|
|
38
|
-
* num$.next(2); // nothing logged
|
|
39
|
-
*
|
|
40
|
-
* num$.next(3); // nothing logged
|
|
41
|
-
*
|
|
42
|
-
* num$.next(4); // nothing logged
|
|
43
|
-
*
|
|
44
|
-
* num$.next(5); // logs: 5
|
|
45
|
-
*
|
|
46
|
-
* assert.deepStrictEqual(valueHistory, [5]);
|
|
47
|
-
*
|
|
48
|
-
* num$.next(6); // logs: 6
|
|
49
|
-
*
|
|
50
|
-
* assert.deepStrictEqual(valueHistory, [5, 6]);
|
|
51
|
-
*
|
|
52
|
-
* num$.next(7); // logs: 7
|
|
53
|
-
*
|
|
54
|
-
* assert.deepStrictEqual(valueHistory, [5, 6, 7]);
|
|
55
|
-
*
|
|
56
|
-
* num$.next(1); // logs: 1
|
|
57
|
-
*
|
|
58
|
-
* num$.next(2); // logs: 2
|
|
59
|
-
*
|
|
60
|
-
* assert.deepStrictEqual(valueHistory, [5, 6, 7, 1, 2]);
|
|
61
|
-
* ```
|
|
62
|
-
*/
|
|
63
5
|
const skipWhile = (predicate) => (parentObservable) => new SkipWhileObservableClass(parentObservable, predicate);
|
|
64
|
-
/* implementation */
|
|
65
6
|
class SkipWhileObservableClass extends SyncChildObservableClass {
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
7
|
+
#predicate;
|
|
8
|
+
#mut_index;
|
|
9
|
+
#mut_skipping;
|
|
10
|
+
constructor(parentObservable, predicate) {
|
|
11
|
+
super({
|
|
12
|
+
parents: [parentObservable],
|
|
13
|
+
initialValue: pipe(parentObservable.getSnapshot()).map(
|
|
14
|
+
(sn) => Optional.isNone(sn) || predicate(sn.value, -1) ? Optional.none : sn
|
|
15
|
+
).value
|
|
16
|
+
});
|
|
17
|
+
this.#mut_index = -1;
|
|
18
|
+
this.#predicate = predicate;
|
|
19
|
+
this.#mut_skipping = true;
|
|
20
|
+
}
|
|
21
|
+
tryUpdate(updateToken) {
|
|
22
|
+
const par = this.parents[0];
|
|
23
|
+
const sn = par.getSnapshot();
|
|
24
|
+
if (par.updateToken !== updateToken || Optional.isNone(sn)) {
|
|
25
|
+
return;
|
|
81
26
|
}
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
if (par.updateToken !== updateToken || Optional.isNone(sn)) {
|
|
86
|
-
return; // skip update
|
|
87
|
-
}
|
|
88
|
-
this.#mut_index =
|
|
89
|
-
this.#mut_index === -1 ? asSafeUint(0) : SafeUint.add(1, this.#mut_index);
|
|
90
|
-
if (!this.#predicate(sn.value, this.#mut_index)) {
|
|
91
|
-
this.#mut_skipping = false;
|
|
92
|
-
}
|
|
93
|
-
if (!this.#mut_skipping) {
|
|
94
|
-
this.setNext(sn.value, updateToken);
|
|
95
|
-
}
|
|
27
|
+
this.#mut_index = this.#mut_index === -1 ? asSafeUint(0) : SafeUint.add(1, this.#mut_index);
|
|
28
|
+
if (!this.#predicate(sn.value, this.#mut_index)) {
|
|
29
|
+
this.#mut_skipping = false;
|
|
96
30
|
}
|
|
31
|
+
if (!this.#mut_skipping) {
|
|
32
|
+
this.setNext(sn.value, updateToken);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
97
35
|
}
|
|
98
36
|
|
|
99
37
|
export { skipWhile };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"skip-while.mjs","sources":["../../../src/core/operators/skip-while.mts"],"sourcesContent":[
|
|
1
|
+
{"version":3,"file":"skip-while.mjs","sources":["../../../src/core/operators/skip-while.mts"],"sourcesContent":["import { Optional, SafeUint, asSafeUint, pipe } from 'ts-data-forge';\nimport { SyncChildObservableClass } from '../class/index.mjs';\nimport {\n type DropInitialValueOperator,\n type Observable,\n type SkipWhileOperatorObservable,\n type UpdateToken,\n} from '../types/index.mjs';\n\n/**\n * Skips values from the source observable while the predicate returns true.\n * Once the predicate returns false, all subsequent values pass through.\n *\n * @template A - The type of values from the source\n * @param predicate - Function to test each value\n * @returns An operator that skips values while the predicate is true\n *\n * @example\n * ```ts\n * // Timeline:\n * //\n * // num$ 1 2 3 4 5 6 7 1 2\n * // skipped$ 5 6 7 1 2\n * // |-------- skip --------|\n * //\n * // Explanation:\n * // - skipWhile skips values while the predicate returns true\n * // - Once the predicate returns false, all subsequent values pass through\n * // - Unlike filter, the predicate is never checked again after the first false\n *\n * const num$ = source<number>();\n *\n * const skipped$ = num$.pipe(skipWhile((x) => x < 5));\n *\n * const valueHistory: number[] = [];\n *\n * skipped$.subscribe((x) => {\n * valueHistory.push(x);\n * });\n *\n * num$.next(1); // nothing logged\n *\n * num$.next(2); // nothing logged\n *\n * num$.next(3); // nothing logged\n *\n * num$.next(4); // nothing logged\n *\n * num$.next(5); // logs: 5\n *\n * assert.deepStrictEqual(valueHistory, [5]);\n *\n * num$.next(6); // logs: 6\n *\n * assert.deepStrictEqual(valueHistory, [5, 6]);\n *\n * num$.next(7); // logs: 7\n *\n * assert.deepStrictEqual(valueHistory, [5, 6, 7]);\n *\n * num$.next(1); // logs: 1\n *\n * num$.next(2); // logs: 2\n *\n * assert.deepStrictEqual(valueHistory, [5, 6, 7, 1, 2]);\n * ```\n */\nexport const skipWhile =\n <A,>(\n predicate: (value: A, index: SafeUint | -1) => boolean,\n ): DropInitialValueOperator<A, A> =>\n (parentObservable) =>\n new SkipWhileObservableClass(parentObservable, predicate);\n\n/* implementation */\n\nclass SkipWhileObservableClass<A>\n extends SyncChildObservableClass<A, readonly [A]>\n implements SkipWhileOperatorObservable<A>\n{\n readonly #predicate: (value: A, index: SafeUint | -1) => boolean;\n #mut_index: SafeUint | -1;\n #mut_skipping: boolean;\n\n constructor(\n parentObservable: Observable<A>,\n predicate: (value: A, index: SafeUint | -1) => boolean,\n ) {\n super({\n parents: [parentObservable],\n initialValue: pipe(parentObservable.getSnapshot()).map((sn) =>\n Optional.isNone(sn) || predicate(sn.value, -1) ? Optional.none : sn,\n ).value,\n });\n\n this.#mut_index = -1;\n\n this.#predicate = predicate;\n\n this.#mut_skipping = true;\n }\n\n override tryUpdate(updateToken: UpdateToken): void {\n const par = this.parents[0];\n\n const sn = par.getSnapshot();\n\n if (par.updateToken !== updateToken || Optional.isNone(sn)) {\n return; // skip update\n }\n\n this.#mut_index =\n this.#mut_index === -1 ? asSafeUint(0) : SafeUint.add(1, this.#mut_index);\n\n if (!this.#predicate(sn.value, this.#mut_index)) {\n this.#mut_skipping = false;\n }\n\n if (!this.#mut_skipping) {\n this.setNext(sn.value, updateToken);\n }\n }\n}\n"],"names":[],"mappings":";;;;AAmEO,MAAM,SAAA,GACX,CACE,SAAA,KAEF,CAAC,qBACC,IAAI,wBAAA,CAAyB,kBAAkB,SAAS;AAI5D,MAAM,iCACI,wBAAA,CAEV;AAAA,EACW,UAAA;AAAA,EACT,UAAA;AAAA,EACA,aAAA;AAAA,EAEA,WAAA,CACE,kBACA,SAAA,EACA;AACA,IAAA,KAAA,CAAM;AAAA,MACJ,OAAA,EAAS,CAAC,gBAAgB,CAAA;AAAA,MAC1B,YAAA,EAAc,IAAA,CAAK,gBAAA,CAAiB,WAAA,EAAa,CAAA,CAAE,GAAA;AAAA,QAAI,CAAC,EAAA,KACtD,QAAA,CAAS,MAAA,CAAO,EAAE,CAAA,IAAK,SAAA,CAAU,EAAA,CAAG,KAAA,EAAO,EAAE,CAAA,GAAI,QAAA,CAAS,IAAA,GAAO;AAAA,OACnE,CAAE;AAAA,KACH,CAAA;AAED,IAAA,IAAA,CAAK,UAAA,GAAa,EAAA;AAElB,IAAA,IAAA,CAAK,UAAA,GAAa,SAAA;AAElB,IAAA,IAAA,CAAK,aAAA,GAAgB,IAAA;AAAA,EACvB;AAAA,EAES,UAAU,WAAA,EAAgC;AACjD,IAAA,MAAM,GAAA,GAAM,IAAA,CAAK,OAAA,CAAQ,CAAC,CAAA;AAE1B,IAAA,MAAM,EAAA,GAAK,IAAI,WAAA,EAAY;AAE3B,IAAA,IAAI,IAAI,WAAA,KAAgB,WAAA,IAAe,QAAA,CAAS,MAAA,CAAO,EAAE,CAAA,EAAG;AAC1D,MAAA;AAAA,IACF;AAEA,IAAA,IAAA,CAAK,UAAA,GACH,IAAA,CAAK,UAAA,KAAe,EAAA,GAAK,UAAA,CAAW,CAAC,CAAA,GAAI,QAAA,CAAS,GAAA,CAAI,CAAA,EAAG,IAAA,CAAK,UAAU,CAAA;AAE1E,IAAA,IAAI,CAAC,IAAA,CAAK,UAAA,CAAW,GAAG,KAAA,EAAO,IAAA,CAAK,UAAU,CAAA,EAAG;AAC/C,MAAA,IAAA,CAAK,aAAA,GAAgB,KAAA;AAAA,IACvB;AAEA,IAAA,IAAI,CAAC,KAAK,aAAA,EAAe;AACvB,MAAA,IAAA,CAAK,OAAA,CAAQ,EAAA,CAAG,KAAA,EAAO,WAAW,CAAA;AAAA,IACpC;AAAA,EACF;AACF;;;;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"switch-map.d.mts","sourceRoot":"","sources":["../../../src/core/operators/switch-map.mts"],"names":[],"mappings":"AAEA,OAAO,EACL,KAAK,wBAAwB,EAC7B,KAAK,UAAU,EAIhB,MAAM,oBAAoB,CAAC;AAE5B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4FG;AACH,eAAO,MAAM,SAAS,GACnB,CAAC,EAAE,CAAC,
|
|
1
|
+
{"version":3,"file":"switch-map.d.mts","sourceRoot":"","sources":["../../../src/core/operators/switch-map.mts"],"names":[],"mappings":"AAEA,OAAO,EACL,KAAK,wBAAwB,EAC7B,KAAK,UAAU,EAIhB,MAAM,oBAAoB,CAAC;AAE5B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4FG;AACH,eAAO,MAAM,SAAS,GACnB,CAAC,EAAE,CAAC,mBACc,CAAC,IAAI,EAAE,CAAC,KAAK,UAAU,CAAC,CAAC,CAAC,KAC1C,wBAAwB,CAAC,CAAC,EAAE,CAAC,CAEiC,CAAC"}
|
|
@@ -2,133 +2,40 @@ import { Optional } from 'ts-data-forge';
|
|
|
2
2
|
import { AsyncChildObservableClass } from '../class/child-observable-class.mjs';
|
|
3
3
|
import '../utils/id-maker.mjs';
|
|
4
4
|
|
|
5
|
-
/**
|
|
6
|
-
* Projects each source value to an observable, subscribes to it, and emits its values.
|
|
7
|
-
* When a new value arrives from the source, the previous inner observable is unsubscribed.
|
|
8
|
-
*
|
|
9
|
-
* @template A - The type of values from the source
|
|
10
|
-
* @template B - The type of values from the projected observable
|
|
11
|
-
* @param mapToObservable - A function that maps each source value to an observable
|
|
12
|
-
* @returns An operator that switches to new observables
|
|
13
|
-
*
|
|
14
|
-
* @example
|
|
15
|
-
* ```ts
|
|
16
|
-
* // Timeline:
|
|
17
|
-
* //
|
|
18
|
-
* // input$ A B C
|
|
19
|
-
* // inner A A1 A2 A3
|
|
20
|
-
* // inner B B1 B2 (switched!)
|
|
21
|
-
* // inner C C1 C2 C3
|
|
22
|
-
* // result$ A1 A2 A3 B1 B2 C1 C2 C3
|
|
23
|
-
* //
|
|
24
|
-
* // Explanation:
|
|
25
|
-
* // - switchMap creates an inner observable for each source value
|
|
26
|
-
* // - When a new source value arrives, the previous inner is unsubscribed
|
|
27
|
-
* // - A's inner completes normally (all 3 values emitted)
|
|
28
|
-
* // - B's inner is interrupted by C (only 2 values emitted)
|
|
29
|
-
* // - C's inner completes normally (all 3 values emitted)
|
|
30
|
-
*
|
|
31
|
-
* const input$ = source<string>();
|
|
32
|
-
*
|
|
33
|
-
* const result$ = input$.pipe(
|
|
34
|
-
* switchMap((letter) => {
|
|
35
|
-
* const inner$ = source<string>();
|
|
36
|
-
*
|
|
37
|
-
* setTimeout(() => {
|
|
38
|
-
* inner$.next(`${letter}1`);
|
|
39
|
-
* }, 10);
|
|
40
|
-
*
|
|
41
|
-
* setTimeout(() => {
|
|
42
|
-
* inner$.next(`${letter}2`);
|
|
43
|
-
* }, 110);
|
|
44
|
-
*
|
|
45
|
-
* setTimeout(() => {
|
|
46
|
-
* inner$.next(`${letter}3`);
|
|
47
|
-
* }, 210);
|
|
48
|
-
*
|
|
49
|
-
* return inner$;
|
|
50
|
-
* }),
|
|
51
|
-
* );
|
|
52
|
-
*
|
|
53
|
-
* const valueHistory: string[] = [];
|
|
54
|
-
*
|
|
55
|
-
* result$.subscribe((value) => {
|
|
56
|
-
* valueHistory.push(value);
|
|
57
|
-
* });
|
|
58
|
-
*
|
|
59
|
-
* const sleep = (ms: number): Promise<void> =>
|
|
60
|
-
* new Promise((resolve) => {
|
|
61
|
-
* setTimeout(resolve, ms);
|
|
62
|
-
* });
|
|
63
|
-
*
|
|
64
|
-
* // Emit A - inner emits A1, A2, A3 at 10ms, 110ms, 210ms
|
|
65
|
-
* input$.next('A');
|
|
66
|
-
*
|
|
67
|
-
* await sleep(250);
|
|
68
|
-
*
|
|
69
|
-
* assert.deepStrictEqual(valueHistory, ['A1', 'A2', 'A3']);
|
|
70
|
-
*
|
|
71
|
-
* // Emit B - inner starts emitting B1, B2 at 10ms, 110ms
|
|
72
|
-
* input$.next('B');
|
|
73
|
-
*
|
|
74
|
-
* await sleep(150);
|
|
75
|
-
*
|
|
76
|
-
* assert.deepStrictEqual(valueHistory, ['A1', 'A2', 'A3', 'B1', 'B2']);
|
|
77
|
-
*
|
|
78
|
-
* // Emit C - switches away from B (B3 cancelled), C's inner starts
|
|
79
|
-
* input$.next('C');
|
|
80
|
-
*
|
|
81
|
-
* await sleep(250);
|
|
82
|
-
*
|
|
83
|
-
* assert.deepStrictEqual(valueHistory, [
|
|
84
|
-
* 'A1',
|
|
85
|
-
* 'A2',
|
|
86
|
-
* 'A3',
|
|
87
|
-
* 'B1',
|
|
88
|
-
* 'B2',
|
|
89
|
-
* 'C1',
|
|
90
|
-
* 'C2',
|
|
91
|
-
* 'C3',
|
|
92
|
-
* ]);
|
|
93
|
-
* ```
|
|
94
|
-
*
|
|
95
|
-
* @note To improve code readability, consider using `createState` instead of `switchMap`,
|
|
96
|
-
* subscribe to `parentObservable` and call `setState` within it.
|
|
97
|
-
*/
|
|
98
5
|
const switchMap = (mapToObservable) => (parentObservable) => new SwitchMapObservableClass(parentObservable, mapToObservable);
|
|
99
6
|
class SwitchMapObservableClass extends AsyncChildObservableClass {
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
}
|
|
118
|
-
this.#mut_observable?.complete();
|
|
119
|
-
this.#mut_subscription?.unsubscribe();
|
|
120
|
-
const observable = this.#mapToObservable(sn.value);
|
|
121
|
-
this.#mut_observable = observable;
|
|
122
|
-
const subscription = observable.subscribe((curr) => {
|
|
123
|
-
this.startUpdate(curr);
|
|
124
|
-
});
|
|
125
|
-
this.#mut_subscription = subscription;
|
|
126
|
-
}
|
|
127
|
-
complete() {
|
|
128
|
-
this.#mut_subscription?.unsubscribe();
|
|
129
|
-
this.#mut_observable?.complete();
|
|
130
|
-
super.complete();
|
|
7
|
+
#mapToObservable;
|
|
8
|
+
#mut_observable;
|
|
9
|
+
#mut_subscription;
|
|
10
|
+
constructor(parentObservable, mapToObservable) {
|
|
11
|
+
super({
|
|
12
|
+
parents: [parentObservable],
|
|
13
|
+
initialValue: Optional.none
|
|
14
|
+
});
|
|
15
|
+
this.#mapToObservable = mapToObservable;
|
|
16
|
+
this.#mut_observable = void 0;
|
|
17
|
+
this.#mut_subscription = void 0;
|
|
18
|
+
}
|
|
19
|
+
tryUpdate(updateToken) {
|
|
20
|
+
const par = this.parents[0];
|
|
21
|
+
const sn = par.getSnapshot();
|
|
22
|
+
if (par.updateToken !== updateToken || Optional.isNone(sn)) {
|
|
23
|
+
return;
|
|
131
24
|
}
|
|
25
|
+
this.#mut_observable?.complete();
|
|
26
|
+
this.#mut_subscription?.unsubscribe();
|
|
27
|
+
const observable = this.#mapToObservable(sn.value);
|
|
28
|
+
this.#mut_observable = observable;
|
|
29
|
+
const subscription = observable.subscribe((curr) => {
|
|
30
|
+
this.startUpdate(curr);
|
|
31
|
+
});
|
|
32
|
+
this.#mut_subscription = subscription;
|
|
33
|
+
}
|
|
34
|
+
complete() {
|
|
35
|
+
this.#mut_subscription?.unsubscribe();
|
|
36
|
+
this.#mut_observable?.complete();
|
|
37
|
+
super.complete();
|
|
38
|
+
}
|
|
132
39
|
}
|
|
133
40
|
|
|
134
41
|
export { switchMap };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"switch-map.mjs","sources":["../../../src/core/operators/switch-map.mts"],"sourcesContent":[
|
|
1
|
+
{"version":3,"file":"switch-map.mjs","sources":["../../../src/core/operators/switch-map.mts"],"sourcesContent":["import { Optional } from 'ts-data-forge';\nimport { AsyncChildObservableClass } from '../class/index.mjs';\nimport {\n type DropInitialValueOperator,\n type Observable,\n type Subscription,\n type SwitchMapOperatorObservable,\n type UpdateToken,\n} from '../types/index.mjs';\n\n/**\n * Projects each source value to an observable, subscribes to it, and emits its values.\n * When a new value arrives from the source, the previous inner observable is unsubscribed.\n *\n * @template A - The type of values from the source\n * @template B - The type of values from the projected observable\n * @param mapToObservable - A function that maps each source value to an observable\n * @returns An operator that switches to new observables\n *\n * @example\n * ```ts\n * // Timeline:\n * //\n * // input$ A B C\n * // inner A A1 A2 A3\n * // inner B B1 B2 (switched!)\n * // inner C C1 C2 C3\n * // result$ A1 A2 A3 B1 B2 C1 C2 C3\n * //\n * // Explanation:\n * // - switchMap creates an inner observable for each source value\n * // - When a new source value arrives, the previous inner is unsubscribed\n * // - A's inner completes normally (all 3 values emitted)\n * // - B's inner is interrupted by C (only 2 values emitted)\n * // - C's inner completes normally (all 3 values emitted)\n *\n * const input$ = source<string>();\n *\n * const result$ = input$.pipe(\n * switchMap((letter) => {\n * const inner$ = source<string>();\n *\n * setTimeout(() => {\n * inner$.next(`${letter}1`);\n * }, 10);\n *\n * setTimeout(() => {\n * inner$.next(`${letter}2`);\n * }, 110);\n *\n * setTimeout(() => {\n * inner$.next(`${letter}3`);\n * }, 210);\n *\n * return inner$;\n * }),\n * );\n *\n * const valueHistory: string[] = [];\n *\n * result$.subscribe((value) => {\n * valueHistory.push(value);\n * });\n *\n * const sleep = (ms: number): Promise<void> =>\n * new Promise((resolve) => {\n * setTimeout(resolve, ms);\n * });\n *\n * // Emit A - inner emits A1, A2, A3 at 10ms, 110ms, 210ms\n * input$.next('A');\n *\n * await sleep(250);\n *\n * assert.deepStrictEqual(valueHistory, ['A1', 'A2', 'A3']);\n *\n * // Emit B - inner starts emitting B1, B2 at 10ms, 110ms\n * input$.next('B');\n *\n * await sleep(150);\n *\n * assert.deepStrictEqual(valueHistory, ['A1', 'A2', 'A3', 'B1', 'B2']);\n *\n * // Emit C - switches away from B (B3 cancelled), C's inner starts\n * input$.next('C');\n *\n * await sleep(250);\n *\n * assert.deepStrictEqual(valueHistory, [\n * 'A1',\n * 'A2',\n * 'A3',\n * 'B1',\n * 'B2',\n * 'C1',\n * 'C2',\n * 'C3',\n * ]);\n * ```\n *\n * @note To improve code readability, consider using `createState` instead of `switchMap`,\n * subscribe to `parentObservable` and call `setState` within it.\n */\nexport const switchMap =\n <A, B>(\n mapToObservable: (curr: A) => Observable<B>,\n ): DropInitialValueOperator<A, B> =>\n (parentObservable) =>\n new SwitchMapObservableClass(parentObservable, mapToObservable);\n\nclass SwitchMapObservableClass<A, B>\n extends AsyncChildObservableClass<B, readonly [A]>\n implements SwitchMapOperatorObservable<A, B>\n{\n readonly #mapToObservable: (curr: A) => Observable<B>;\n #mut_observable: Observable<B> | undefined;\n #mut_subscription: Subscription | undefined;\n\n constructor(\n parentObservable: Observable<A>,\n mapToObservable: (curr: A) => Observable<B>,\n ) {\n super({\n parents: [parentObservable],\n initialValue: Optional.none,\n });\n\n this.#mapToObservable = mapToObservable;\n\n this.#mut_observable = undefined;\n\n this.#mut_subscription = undefined;\n }\n\n override tryUpdate(updateToken: UpdateToken): void {\n const par = this.parents[0];\n\n const sn = par.getSnapshot();\n\n if (par.updateToken !== updateToken || Optional.isNone(sn)) {\n return; // skip update\n }\n\n this.#mut_observable?.complete();\n\n this.#mut_subscription?.unsubscribe();\n\n const observable = this.#mapToObservable(sn.value);\n\n this.#mut_observable = observable;\n\n const subscription = observable.subscribe((curr) => {\n this.startUpdate(curr);\n });\n\n this.#mut_subscription = subscription;\n }\n\n override complete(): void {\n this.#mut_subscription?.unsubscribe();\n\n this.#mut_observable?.complete();\n\n super.complete();\n }\n}\n"],"names":[],"mappings":";;;;AAuGO,MAAM,SAAA,GACX,CACE,eAAA,KAEF,CAAC,qBACC,IAAI,wBAAA,CAAyB,kBAAkB,eAAe;AAElE,MAAM,iCACI,yBAAA,CAEV;AAAA,EACW,gBAAA;AAAA,EACT,eAAA;AAAA,EACA,iBAAA;AAAA,EAEA,WAAA,CACE,kBACA,eAAA,EACA;AACA,IAAA,KAAA,CAAM;AAAA,MACJ,OAAA,EAAS,CAAC,gBAAgB,CAAA;AAAA,MAC1B,cAAc,QAAA,CAAS;AAAA,KACxB,CAAA;AAED,IAAA,IAAA,CAAK,gBAAA,GAAmB,eAAA;AAExB,IAAA,IAAA,CAAK,eAAA,GAAkB,MAAA;AAEvB,IAAA,IAAA,CAAK,iBAAA,GAAoB,MAAA;AAAA,EAC3B;AAAA,EAES,UAAU,WAAA,EAAgC;AACjD,IAAA,MAAM,GAAA,GAAM,IAAA,CAAK,OAAA,CAAQ,CAAC,CAAA;AAE1B,IAAA,MAAM,EAAA,GAAK,IAAI,WAAA,EAAY;AAE3B,IAAA,IAAI,IAAI,WAAA,KAAgB,WAAA,IAAe,QAAA,CAAS,MAAA,CAAO,EAAE,CAAA,EAAG;AAC1D,MAAA;AAAA,IACF;AAEA,IAAA,IAAA,CAAK,iBAAiB,QAAA,EAAS;AAE/B,IAAA,IAAA,CAAK,mBAAmB,WAAA,EAAY;AAEpC,IAAA,MAAM,UAAA,GAAa,IAAA,CAAK,gBAAA,CAAiB,EAAA,CAAG,KAAK,CAAA;AAEjD,IAAA,IAAA,CAAK,eAAA,GAAkB,UAAA;AAEvB,IAAA,MAAM,YAAA,GAAe,UAAA,CAAW,SAAA,CAAU,CAAC,IAAA,KAAS;AAClD,MAAA,IAAA,CAAK,YAAY,IAAI,CAAA;AAAA,IACvB,CAAC,CAAA;AAED,IAAA,IAAA,CAAK,iBAAA,GAAoB,YAAA;AAAA,EAC3B;AAAA,EAES,QAAA,GAAiB;AACxB,IAAA,IAAA,CAAK,mBAAmB,WAAA,EAAY;AAEpC,IAAA,IAAA,CAAK,iBAAiB,QAAA,EAAS;AAE/B,IAAA,KAAA,CAAM,QAAA,EAAS;AAAA,EACjB;AACF;;;;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"take-until.d.mts","sourceRoot":"","sources":["../../../src/core/operators/take-until.mts"],"names":[],"mappings":"AAEA,OAAO,EACL,KAAK,wBAAwB,EAC7B,KAAK,UAAU,EAGhB,MAAM,oBAAoB,CAAC;AAE5B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+CG;AACH,eAAO,MAAM,SAAS,GAAI,CAAC,
|
|
1
|
+
{"version":3,"file":"take-until.d.mts","sourceRoot":"","sources":["../../../src/core/operators/take-until.mts"],"names":[],"mappings":"AAEA,OAAO,EACL,KAAK,wBAAwB,EAC7B,KAAK,UAAU,EAGhB,MAAM,oBAAoB,CAAC;AAE5B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+CG;AACH,eAAO,MAAM,SAAS,GAAI,CAAC,YACf,UAAU,CAAC,OAAO,CAAC,KAC5B,wBAAwB,CAAC,CAAC,EAAE,CAAC,CAMQ,CAAC"}
|
|
@@ -2,77 +2,36 @@ import { Optional } from 'ts-data-forge';
|
|
|
2
2
|
import { SyncChildObservableClass } from '../class/child-observable-class.mjs';
|
|
3
3
|
import '../utils/id-maker.mjs';
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
*
|
|
13
|
-
* @example
|
|
14
|
-
* ```ts
|
|
15
|
-
* // Timeline:
|
|
16
|
-
* //
|
|
17
|
-
* // num$ 1 2 stop 3 (ignored)
|
|
18
|
-
* // stopNotifier X
|
|
19
|
-
* // limited$ 1 2 |------- (completed)
|
|
20
|
-
* //
|
|
21
|
-
* // Explanation:
|
|
22
|
-
* // - takeUntil completes the observable when the notifier emits
|
|
23
|
-
* // - After stop() is called, no further values are emitted
|
|
24
|
-
* // - Useful for cleanup and cancellation patterns
|
|
25
|
-
*
|
|
26
|
-
* const num$ = source<number>();
|
|
27
|
-
*
|
|
28
|
-
* const [stopNotifier, stop_] = createEventEmitter();
|
|
29
|
-
*
|
|
30
|
-
* const limited$ = num$.pipe(takeUntil(stopNotifier));
|
|
31
|
-
*
|
|
32
|
-
* const valueHistory: number[] = [];
|
|
33
|
-
*
|
|
34
|
-
* limited$.subscribe((x) => {
|
|
35
|
-
* valueHistory.push(x);
|
|
36
|
-
* });
|
|
37
|
-
*
|
|
38
|
-
* num$.next(1); // logs: 1
|
|
39
|
-
*
|
|
40
|
-
* assert.deepStrictEqual(valueHistory, [1]);
|
|
41
|
-
*
|
|
42
|
-
* num$.next(2); // logs: 2
|
|
43
|
-
*
|
|
44
|
-
* assert.deepStrictEqual(valueHistory, [1, 2]);
|
|
45
|
-
*
|
|
46
|
-
* stop_();
|
|
47
|
-
*
|
|
48
|
-
* num$.next(3); // nothing logged (completed)
|
|
49
|
-
*
|
|
50
|
-
* assert.deepStrictEqual(valueHistory, [1, 2]);
|
|
51
|
-
* ```
|
|
52
|
-
*/
|
|
53
|
-
const takeUntil = (notifier) =>
|
|
54
|
-
// eslint-disable-next-line total-functions/no-unsafe-type-assertion
|
|
55
|
-
((parentObservable) => new TakeUntilObservableClass(parentObservable, notifier));
|
|
5
|
+
const takeUntil = (notifier) => (
|
|
6
|
+
// eslint-disable-next-line total-functions/no-unsafe-type-assertion
|
|
7
|
+
((parentObservable) => new TakeUntilObservableClass(
|
|
8
|
+
parentObservable,
|
|
9
|
+
notifier
|
|
10
|
+
))
|
|
11
|
+
);
|
|
56
12
|
class TakeUntilObservableClass extends SyncChildObservableClass {
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
13
|
+
constructor(parentObservable, notifier) {
|
|
14
|
+
super({
|
|
15
|
+
parents: [parentObservable],
|
|
16
|
+
initialValue: parentObservable.getSnapshot()
|
|
17
|
+
});
|
|
18
|
+
notifier.subscribe(
|
|
19
|
+
() => {
|
|
20
|
+
this.complete();
|
|
21
|
+
},
|
|
22
|
+
() => {
|
|
23
|
+
this.complete();
|
|
24
|
+
}
|
|
25
|
+
);
|
|
26
|
+
}
|
|
27
|
+
tryUpdate(updateToken) {
|
|
28
|
+
const par = this.parents[0];
|
|
29
|
+
const sn = par.getSnapshot();
|
|
30
|
+
if (par.updateToken !== updateToken || Optional.isNone(sn)) {
|
|
31
|
+
return;
|
|
75
32
|
}
|
|
33
|
+
this.setNext(sn.value, updateToken);
|
|
34
|
+
}
|
|
76
35
|
}
|
|
77
36
|
|
|
78
37
|
export { takeUntil };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"take-until.mjs","sources":["../../../src/core/operators/take-until.mts"],"sourcesContent":[
|
|
1
|
+
{"version":3,"file":"take-until.mjs","sources":["../../../src/core/operators/take-until.mts"],"sourcesContent":["import { Optional } from 'ts-data-forge';\nimport { SyncChildObservableClass } from '../class/index.mjs';\nimport {\n type KeepInitialValueOperator,\n type Observable,\n type TakeUntilOperatorObservable,\n type UpdateToken,\n} from '../types/index.mjs';\n\n/**\n * Emits values from the source until the notifier observable emits.\n * When the notifier emits, this observable completes.\n *\n * @template A - The type of values from the source\n * @param notifier - An observable that signals when to complete\n * @returns An operator that takes values until notifier emits\n *\n * @example\n * ```ts\n * // Timeline:\n * //\n * // num$ 1 2 stop 3 (ignored)\n * // stopNotifier X\n * // limited$ 1 2 |------- (completed)\n * //\n * // Explanation:\n * // - takeUntil completes the observable when the notifier emits\n * // - After stop() is called, no further values are emitted\n * // - Useful for cleanup and cancellation patterns\n *\n * const num$ = source<number>();\n *\n * const [stopNotifier, stop_] = createEventEmitter();\n *\n * const limited$ = num$.pipe(takeUntil(stopNotifier));\n *\n * const valueHistory: number[] = [];\n *\n * limited$.subscribe((x) => {\n * valueHistory.push(x);\n * });\n *\n * num$.next(1); // logs: 1\n *\n * assert.deepStrictEqual(valueHistory, [1]);\n *\n * num$.next(2); // logs: 2\n *\n * assert.deepStrictEqual(valueHistory, [1, 2]);\n *\n * stop_();\n *\n * num$.next(3); // nothing logged (completed)\n *\n * assert.deepStrictEqual(valueHistory, [1, 2]);\n * ```\n */\nexport const takeUntil = <A,>(\n notifier: Observable<unknown>,\n): KeepInitialValueOperator<A, A> =>\n // eslint-disable-next-line total-functions/no-unsafe-type-assertion\n ((parentObservable) =>\n new TakeUntilObservableClass(\n parentObservable,\n notifier,\n )) as KeepInitialValueOperator<A, A>;\n\nclass TakeUntilObservableClass<A>\n extends SyncChildObservableClass<A, readonly [A]>\n implements TakeUntilOperatorObservable<A>\n{\n constructor(parentObservable: Observable<A>, notifier: Observable<unknown>) {\n super({\n parents: [parentObservable],\n initialValue: parentObservable.getSnapshot(),\n });\n\n notifier.subscribe(\n () => {\n this.complete();\n },\n () => {\n this.complete();\n },\n );\n }\n\n override tryUpdate(updateToken: UpdateToken): void {\n const par = this.parents[0];\n\n const sn = par.getSnapshot();\n\n if (par.updateToken !== updateToken || Optional.isNone(sn)) {\n return; // skip update\n }\n\n this.setNext(sn.value, updateToken);\n }\n}\n"],"names":[],"mappings":";;;;AAyDO,MAAM,YAAY,CACvB,QAAA;AAAA;AAAA,GAGC,CAAC,qBACA,IAAI,wBAAA;AAAA,IACF,gBAAA;AAAA,IACA;AAAA,GACF;AAAA;AAEJ,MAAM,iCACI,wBAAA,CAEV;AAAA,EACE,WAAA,CAAY,kBAAiC,QAAA,EAA+B;AAC1E,IAAA,KAAA,CAAM;AAAA,MACJ,OAAA,EAAS,CAAC,gBAAgB,CAAA;AAAA,MAC1B,YAAA,EAAc,iBAAiB,WAAA;AAAY,KAC5C,CAAA;AAED,IAAA,QAAA,CAAS,SAAA;AAAA,MACP,MAAM;AACJ,QAAA,IAAA,CAAK,QAAA,EAAS;AAAA,MAChB,CAAA;AAAA,MACA,MAAM;AACJ,QAAA,IAAA,CAAK,QAAA,EAAS;AAAA,MAChB;AAAA,KACF;AAAA,EACF;AAAA,EAES,UAAU,WAAA,EAAgC;AACjD,IAAA,MAAM,GAAA,GAAM,IAAA,CAAK,OAAA,CAAQ,CAAC,CAAA;AAE1B,IAAA,MAAM,EAAA,GAAK,IAAI,WAAA,EAAY;AAE3B,IAAA,IAAI,IAAI,WAAA,KAAgB,WAAA,IAAe,QAAA,CAAS,MAAA,CAAO,EAAE,CAAA,EAAG;AAC1D,MAAA;AAAA,IACF;AAEA,IAAA,IAAA,CAAK,OAAA,CAAQ,EAAA,CAAG,KAAA,EAAO,WAAW,CAAA;AAAA,EACpC;AACF;;;;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"take-while.d.mts","sourceRoot":"","sources":["../../../src/core/operators/take-while.mts"],"names":[],"mappings":"AAAA,OAAO,EAEL,QAAQ,EAIT,MAAM,eAAe,CAAC;AAGvB,OAAO,EACL,KAAK,wBAAwB,EAK9B,MAAM,oBAAoB,CAAC;AAG5B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsDG;AACH,eAAO,MAAM,SAAS,GACnB,CAAC,
|
|
1
|
+
{"version":3,"file":"take-while.d.mts","sourceRoot":"","sources":["../../../src/core/operators/take-while.mts"],"names":[],"mappings":"AAAA,OAAO,EAEL,QAAQ,EAIT,MAAM,eAAe,CAAC;AAGvB,OAAO,EACL,KAAK,wBAAwB,EAK9B,MAAM,oBAAoB,CAAC;AAG5B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsDG;AACH,eAAO,MAAM,SAAS,GACnB,CAAC,aACW,CAAC,KAAK,EAAE,CAAC,EAAE,KAAK,EAAE,QAAQ,GAAG,CAAC,CAAC,KAAK,OAAO,KACrD,wBAAwB,CAAC,CAAC,EAAE,CAAC,CAE2B,CAAC"}
|