synstate 2.0.1 → 3.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 +2 -2
- package/dist/core/base/create-child-observable.d.mts +65 -0
- package/dist/core/base/create-child-observable.d.mts.map +1 -0
- package/dist/core/base/create-child-observable.mjs +157 -0
- package/dist/core/base/create-child-observable.mjs.map +1 -0
- package/dist/core/base/create-observable-base.d.mts +82 -0
- package/dist/core/base/create-observable-base.d.mts.map +1 -0
- package/dist/core/base/create-observable-base.mjs +160 -0
- package/dist/core/base/create-observable-base.mjs.map +1 -0
- package/dist/core/base/create-root-observable.d.mts +37 -0
- package/dist/core/base/create-root-observable.d.mts.map +1 -0
- package/dist/core/base/create-root-observable.mjs +36 -0
- package/dist/core/base/create-root-observable.mjs.map +1 -0
- package/dist/core/base/index.d.mts +3 -0
- package/dist/core/base/index.d.mts.map +1 -0
- package/dist/core/base/index.mjs +3 -0
- package/dist/core/{class → base}/index.mjs.map +1 -1
- package/dist/core/combine/combine.d.mts.map +1 -1
- package/dist/core/combine/combine.mjs +28 -27
- package/dist/core/combine/combine.mjs.map +1 -1
- package/dist/core/combine/merge.d.mts.map +1 -1
- package/dist/core/combine/merge.mjs +11 -13
- package/dist/core/combine/merge.mjs.map +1 -1
- package/dist/core/combine/zip.d.mts.map +1 -1
- package/dist/core/combine/zip.mjs +32 -31
- package/dist/core/combine/zip.mjs.map +1 -1
- package/dist/core/create/counter.d.mts.map +1 -1
- package/dist/core/create/counter.mjs +39 -50
- 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 +33 -32
- 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 +12 -12
- 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 +10 -10
- 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 -4
- package/dist/core/create/just.mjs.map +1 -1
- package/dist/core/create/source.mjs +11 -12
- 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 -38
- 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 +0 -3
- package/dist/core/index.mjs.map +1 -1
- package/dist/core/operators/audit.d.mts.map +1 -1
- package/dist/core/operators/audit.mjs +28 -36
- 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 +26 -33
- package/dist/core/operators/debounce.mjs.map +1 -1
- package/dist/core/operators/filter.d.mts.map +1 -1
- package/dist/core/operators/filter.mjs +23 -27
- 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 +21 -28
- package/dist/core/operators/map.mjs.map +1 -1
- package/dist/core/operators/merge-map.d.mts.map +1 -1
- package/dist/core/operators/merge-map.mjs +30 -39
- package/dist/core/operators/merge-map.mjs.map +1 -1
- package/dist/core/operators/pairwise.d.mts.map +1 -1
- package/dist/core/operators/pairwise.mjs +22 -24
- 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 +13 -18
- package/dist/core/operators/scan.mjs.map +1 -1
- package/dist/core/operators/skip-if-no-change.d.mts.map +1 -1
- package/dist/core/operators/skip-if-no-change.mjs +22 -26
- 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 -24
- 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 +27 -32
- 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 +28 -34
- 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 +22 -22
- 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 +25 -29
- 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 +27 -35
- package/dist/core/operators/throttle.mjs.map +1 -1
- package/dist/core/operators/with-buffered-from.d.mts.map +1 -1
- package/dist/core/operators/with-buffered-from.mjs +24 -24
- package/dist/core/operators/with-buffered-from.mjs.map +1 -1
- package/dist/core/operators/with-current-value-from.d.mts.map +1 -1
- package/dist/core/operators/with-current-value-from.mjs +20 -25
- 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 +12 -15
- package/dist/core/operators/with-initial-value.mjs.map +1 -1
- package/dist/entry-point.mjs +0 -3
- package/dist/entry-point.mjs.map +1 -1
- package/dist/index.mjs +0 -3
- package/dist/index.mjs.map +1 -1
- package/package.json +25 -18
- package/src/core/{class → base}/circular-dependency-comparison.test.mts +28 -18
- package/src/core/base/circular-dependency.test.mts +322 -0
- package/src/core/base/create-child-observable.mts +340 -0
- package/src/core/base/create-observable-base.mts +358 -0
- package/src/core/base/create-root-observable.mts +102 -0
- package/src/core/base/index.mts +2 -0
- package/src/core/{class/observable.class.test.mts → base/observable-base.test.mts} +25 -17
- package/src/core/combine/combine.mts +51 -53
- package/src/core/combine/merge.mts +21 -23
- package/src/core/combine/zip.mts +54 -58
- package/src/core/create/counter.mts +42 -59
- package/src/core/create/from-abortable-promise.mts +38 -45
- package/src/core/create/from-promise.mts +25 -28
- package/src/core/create/from-subscribable.mts +23 -27
- package/src/core/create/just.mts +5 -4
- package/src/core/create/source.mts +11 -17
- package/src/core/create/timer.mts +32 -47
- package/src/core/index.mts +0 -1
- package/src/core/operators/audit.mts +43 -57
- package/src/core/operators/debounce.mts +35 -45
- package/src/core/operators/filter.mts +31 -39
- package/src/core/operators/map.mts +32 -40
- package/src/core/operators/merge-map.mts +44 -59
- package/src/core/operators/pairwise.mts +30 -33
- package/src/core/operators/scan.mts +24 -35
- package/src/core/operators/skip-if-no-change.mts +31 -36
- package/src/core/operators/skip-until.mts +32 -35
- package/src/core/operators/skip-while.mts +31 -40
- package/src/core/operators/switch-map.mts +36 -48
- package/src/core/operators/take-until.mts +31 -29
- package/src/core/operators/take-while.mts +33 -41
- package/src/core/operators/throttle.mts +37 -51
- package/src/core/operators/with-buffered-from.mts +35 -30
- package/src/core/operators/with-current-value-from.mts +23 -28
- package/src/core/operators/with-initial-value.mts +21 -22
- package/dist/core/class/child-observable-class.d.mts +0 -39
- package/dist/core/class/child-observable-class.d.mts.map +0 -1
- package/dist/core/class/child-observable-class.mjs +0 -173
- package/dist/core/class/child-observable-class.mjs.map +0 -1
- package/dist/core/class/index.d.mts +0 -4
- package/dist/core/class/index.d.mts.map +0 -1
- package/dist/core/class/index.mjs +0 -4
- package/dist/core/class/observable-base-class.d.mts +0 -28
- package/dist/core/class/observable-base-class.d.mts.map +0 -1
- package/dist/core/class/observable-base-class.mjs +0 -120
- package/dist/core/class/observable-base-class.mjs.map +0 -1
- package/dist/core/class/root-observable-class.d.mts +0 -14
- package/dist/core/class/root-observable-class.d.mts.map +0 -1
- package/dist/core/class/root-observable-class.mjs +0 -43
- package/dist/core/class/root-observable-class.mjs.map +0 -1
- package/src/core/class/child-observable-class.mts +0 -286
- package/src/core/class/circular-dependency.test.mts +0 -251
- package/src/core/class/index.mts +0 -3
- package/src/core/class/observable-base-class.mts +0 -187
- package/src/core/class/root-observable-class.mts +0 -73
|
@@ -5,14 +5,13 @@ import {
|
|
|
5
5
|
expectType,
|
|
6
6
|
pipe,
|
|
7
7
|
} from 'ts-data-forge';
|
|
8
|
-
import {
|
|
8
|
+
import { createSyncChildObservable } from '../base/index.mjs';
|
|
9
9
|
import { source } from '../create/index.mjs';
|
|
10
10
|
import {
|
|
11
11
|
type DropInitialValueOperator,
|
|
12
12
|
type InitializedObservable,
|
|
13
13
|
type Observable,
|
|
14
14
|
type TakeWhileOperatorObservable,
|
|
15
|
-
type UpdateToken,
|
|
16
15
|
} from '../types/index.mjs';
|
|
17
16
|
import { withInitialValue } from './with-initial-value.mjs';
|
|
18
17
|
|
|
@@ -76,22 +75,16 @@ export const takeWhile =
|
|
|
76
75
|
predicate: (value: A, index: SafeUint | -1) => boolean,
|
|
77
76
|
): DropInitialValueOperator<A, A> =>
|
|
78
77
|
(parentObservable) =>
|
|
79
|
-
|
|
78
|
+
createTakeWhileObservable(parentObservable, predicate);
|
|
80
79
|
|
|
81
80
|
/* implementation */
|
|
82
81
|
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
constructor(
|
|
91
|
-
parentObservable: Observable<A>,
|
|
92
|
-
predicate: (value: A, index: SafeUint | -1) => boolean,
|
|
93
|
-
) {
|
|
94
|
-
super({
|
|
82
|
+
const createTakeWhileObservable = <A,>(
|
|
83
|
+
parentObservable: Observable<A>,
|
|
84
|
+
predicate: (value: A, index: SafeUint | -1) => boolean,
|
|
85
|
+
): TakeWhileOperatorObservable<A> =>
|
|
86
|
+
createSyncChildObservable(
|
|
87
|
+
{
|
|
95
88
|
parents: [parentObservable],
|
|
96
89
|
initialValue: pipe(parentObservable.getSnapshot()).map((par) =>
|
|
97
90
|
Optional.isNone(par)
|
|
@@ -100,32 +93,31 @@ class TakeWhileObservableClass<A>
|
|
|
100
93
|
? par
|
|
101
94
|
: Optional.none,
|
|
102
95
|
).value,
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
}
|
|
96
|
+
},
|
|
97
|
+
({ setNext, complete }) => {
|
|
98
|
+
let mut_index: SafeUint | -1 = -1;
|
|
99
|
+
|
|
100
|
+
return (updateToken) => {
|
|
101
|
+
const sn = parentObservable.getSnapshot();
|
|
102
|
+
|
|
103
|
+
if (
|
|
104
|
+
parentObservable.updateToken !== updateToken ||
|
|
105
|
+
Optional.isNone(sn)
|
|
106
|
+
) {
|
|
107
|
+
return; // skip update
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
mut_index =
|
|
111
|
+
mut_index === -1 ? asSafeUint(0) : SafeUint.add(1, mut_index);
|
|
112
|
+
|
|
113
|
+
if (predicate(sn.value, mut_index)) {
|
|
114
|
+
setNext(sn.value, updateToken);
|
|
115
|
+
} else {
|
|
116
|
+
complete();
|
|
117
|
+
}
|
|
118
|
+
};
|
|
119
|
+
},
|
|
120
|
+
);
|
|
129
121
|
|
|
130
122
|
if (import.meta.vitest !== undefined) {
|
|
131
123
|
test('type test', () => {
|
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
import { Optional } from 'ts-data-forge';
|
|
2
|
-
import {
|
|
2
|
+
import { createSyncChildObservable } from '../base/index.mjs';
|
|
3
3
|
import {
|
|
4
4
|
type KeepInitialValueOperator,
|
|
5
5
|
type Observable,
|
|
6
6
|
type ThrottleOperatorObservable,
|
|
7
7
|
type TimerId,
|
|
8
|
-
type UpdateToken,
|
|
9
8
|
} from '../types/index.mjs';
|
|
10
9
|
|
|
11
10
|
/**
|
|
@@ -91,64 +90,51 @@ export const throttle = <A,>(
|
|
|
91
90
|
): KeepInitialValueOperator<A, A> =>
|
|
92
91
|
// eslint-disable-next-line total-functions/no-unsafe-type-assertion
|
|
93
92
|
((parentObservable) =>
|
|
94
|
-
|
|
93
|
+
createThrottleObservable(
|
|
95
94
|
parentObservable,
|
|
96
95
|
milliSeconds,
|
|
97
96
|
)) as KeepInitialValueOperator<A, A>;
|
|
98
97
|
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
{
|
|
103
|
-
|
|
104
|
-
#mut_timerId: TimerId | undefined;
|
|
105
|
-
#mut_isSkipping: boolean;
|
|
106
|
-
|
|
107
|
-
constructor(parentObservable: Observable<A>, milliSeconds: number) {
|
|
108
|
-
super({
|
|
109
|
-
parents: [parentObservable],
|
|
110
|
-
initialValue: parentObservable.getSnapshot(),
|
|
111
|
-
});
|
|
112
|
-
|
|
113
|
-
this.#mut_timerId = undefined;
|
|
114
|
-
|
|
115
|
-
this.#mut_isSkipping = false;
|
|
116
|
-
|
|
117
|
-
this.#milliSeconds = milliSeconds;
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
#resetTimer(): void {
|
|
121
|
-
if (this.#mut_timerId !== undefined) {
|
|
122
|
-
clearTimeout(this.#mut_timerId);
|
|
123
|
-
}
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
override tryUpdate(updateToken: UpdateToken): void {
|
|
127
|
-
const par = this.parents[0];
|
|
98
|
+
const createThrottleObservable = <A,>(
|
|
99
|
+
parentObservable: Observable<A>,
|
|
100
|
+
milliSeconds: number,
|
|
101
|
+
): ThrottleOperatorObservable<A> => {
|
|
102
|
+
let mut_timerId: TimerId | undefined = undefined;
|
|
128
103
|
|
|
129
|
-
|
|
104
|
+
let mut_isSkipping = false;
|
|
130
105
|
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
this.#mut_isSkipping
|
|
135
|
-
) {
|
|
136
|
-
return; // skip update
|
|
106
|
+
const resetTimer = (): void => {
|
|
107
|
+
if (mut_timerId !== undefined) {
|
|
108
|
+
clearTimeout(mut_timerId);
|
|
137
109
|
}
|
|
110
|
+
};
|
|
138
111
|
|
|
139
|
-
|
|
112
|
+
return createSyncChildObservable(
|
|
113
|
+
{
|
|
114
|
+
parents: [parentObservable],
|
|
115
|
+
initialValue: parentObservable.getSnapshot(),
|
|
116
|
+
onComplete: resetTimer,
|
|
117
|
+
},
|
|
118
|
+
({ setNext }) =>
|
|
119
|
+
(updateToken) => {
|
|
120
|
+
const sn = parentObservable.getSnapshot();
|
|
140
121
|
|
|
141
|
-
|
|
122
|
+
if (
|
|
123
|
+
mut_isSkipping ||
|
|
124
|
+
parentObservable.updateToken !== updateToken ||
|
|
125
|
+
Optional.isNone(sn)
|
|
126
|
+
) {
|
|
127
|
+
return; // skip update
|
|
128
|
+
}
|
|
142
129
|
|
|
143
|
-
|
|
144
|
-
this.#mut_timerId = setTimeout(() => {
|
|
145
|
-
this.#mut_isSkipping = false;
|
|
146
|
-
}, this.#milliSeconds);
|
|
147
|
-
}
|
|
130
|
+
setNext(sn.value, updateToken);
|
|
148
131
|
|
|
149
|
-
|
|
150
|
-
this.#resetTimer();
|
|
132
|
+
mut_isSkipping = true;
|
|
151
133
|
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
134
|
+
// set timer
|
|
135
|
+
mut_timerId = setTimeout(() => {
|
|
136
|
+
mut_isSkipping = false;
|
|
137
|
+
}, milliSeconds);
|
|
138
|
+
},
|
|
139
|
+
);
|
|
140
|
+
};
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
import { Arr, Optional, pipe } from 'ts-data-forge';
|
|
2
|
-
import {
|
|
2
|
+
import { createSyncChildObservable } from '../base/index.mjs';
|
|
3
3
|
import {
|
|
4
4
|
type KeepInitialValueOperator,
|
|
5
5
|
type Observable,
|
|
6
|
-
type UpdateToken,
|
|
7
6
|
type WithBufferedFromOperatorObservable,
|
|
8
7
|
} from '../types/index.mjs';
|
|
9
8
|
import { maxDepth } from '../utils/index.mjs';
|
|
@@ -66,7 +65,7 @@ export const withBufferedFrom = <A, B>(
|
|
|
66
65
|
): KeepInitialValueOperator<A, readonly [A, readonly B[]]> =>
|
|
67
66
|
// eslint-disable-next-line total-functions/no-unsafe-type-assertion
|
|
68
67
|
((parentObservable) =>
|
|
69
|
-
|
|
68
|
+
createWithBufferedFromObservable(
|
|
70
69
|
parentObservable,
|
|
71
70
|
observable,
|
|
72
71
|
)) as KeepInitialValueOperator<A, readonly [A, readonly B[]]>;
|
|
@@ -77,14 +76,21 @@ export const withBufferedFrom = <A, B>(
|
|
|
77
76
|
*/
|
|
78
77
|
export const withBuffered = withBufferedFrom;
|
|
79
78
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
{
|
|
84
|
-
|
|
79
|
+
const createWithBufferedFromObservable = <A, B>(
|
|
80
|
+
parentObservable: Observable<A>,
|
|
81
|
+
observable: Observable<B>,
|
|
82
|
+
): WithBufferedFromOperatorObservable<A, B> => {
|
|
83
|
+
let mut_bufferedValues: readonly B[] = [];
|
|
84
|
+
|
|
85
|
+
const clearBuffer = (): void => {
|
|
86
|
+
mut_bufferedValues = [];
|
|
87
|
+
};
|
|
85
88
|
|
|
86
|
-
|
|
87
|
-
|
|
89
|
+
const result = createSyncChildObservable<
|
|
90
|
+
readonly [A, readonly B[]],
|
|
91
|
+
readonly [A]
|
|
92
|
+
>(
|
|
93
|
+
{
|
|
88
94
|
parents: [parentObservable],
|
|
89
95
|
depth: 1 + maxDepth([parentObservable, observable]),
|
|
90
96
|
initialValue: pipe({
|
|
@@ -98,28 +104,27 @@ class WithBufferedFromObservableClass<A, B>
|
|
|
98
104
|
Optional.isNone(me) ? [] : [me.value],
|
|
99
105
|
] as const),
|
|
100
106
|
).value,
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
});
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
#clearBuffer(): void {
|
|
109
|
-
this.#mut_bufferedValues = [];
|
|
110
|
-
}
|
|
107
|
+
},
|
|
108
|
+
({ setNext }) =>
|
|
109
|
+
(updateToken) => {
|
|
110
|
+
const sn = parentObservable.getSnapshot();
|
|
111
111
|
|
|
112
|
-
|
|
113
|
-
|
|
112
|
+
if (
|
|
113
|
+
parentObservable.updateToken !== updateToken ||
|
|
114
|
+
Optional.isNone(sn)
|
|
115
|
+
) {
|
|
116
|
+
return; // skip update
|
|
117
|
+
}
|
|
114
118
|
|
|
115
|
-
|
|
119
|
+
setNext([sn.value, mut_bufferedValues], updateToken);
|
|
116
120
|
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
121
|
+
clearBuffer();
|
|
122
|
+
},
|
|
123
|
+
);
|
|
120
124
|
|
|
121
|
-
|
|
125
|
+
observable.subscribe((value) => {
|
|
126
|
+
mut_bufferedValues = Arr.toPushed(mut_bufferedValues, value);
|
|
127
|
+
});
|
|
122
128
|
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
}
|
|
129
|
+
return result;
|
|
130
|
+
};
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
import { Optional, pipe } from 'ts-data-forge';
|
|
2
|
-
import {
|
|
2
|
+
import { createSyncChildObservable } from '../base/index.mjs';
|
|
3
3
|
import {
|
|
4
4
|
type DropInitialValueOperator,
|
|
5
5
|
type Observable,
|
|
6
|
-
type UpdateToken,
|
|
7
6
|
type WithCurrentValueFromOperatorObservable,
|
|
8
7
|
} from '../types/index.mjs';
|
|
9
8
|
import { maxDepth } from '../utils/index.mjs';
|
|
@@ -69,7 +68,7 @@ export const withCurrentValueFrom =
|
|
|
69
68
|
observable: Observable<B>,
|
|
70
69
|
): DropInitialValueOperator<A, readonly [A, B]> =>
|
|
71
70
|
(parentObservable) =>
|
|
72
|
-
|
|
71
|
+
createWithCurrentValueFromObservable(parentObservable, observable);
|
|
73
72
|
|
|
74
73
|
/**
|
|
75
74
|
* Alias for `withCurrentValueFrom`.
|
|
@@ -77,14 +76,12 @@ export const withCurrentValueFrom =
|
|
|
77
76
|
*/
|
|
78
77
|
export const withLatestFrom = withCurrentValueFrom;
|
|
79
78
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
readonly
|
|
85
|
-
|
|
86
|
-
constructor(parentObservable: Observable<A>, observable: Observable<B>) {
|
|
87
|
-
super({
|
|
79
|
+
const createWithCurrentValueFromObservable = <A, B>(
|
|
80
|
+
parentObservable: Observable<A>,
|
|
81
|
+
observable: Observable<B>,
|
|
82
|
+
): WithCurrentValueFromOperatorObservable<A, B> =>
|
|
83
|
+
createSyncChildObservable<readonly [A, B], readonly [A]>(
|
|
84
|
+
{
|
|
88
85
|
parents: [parentObservable],
|
|
89
86
|
depth: 1 + maxDepth([parentObservable, observable]),
|
|
90
87
|
initialValue: pipe({
|
|
@@ -95,24 +92,22 @@ class WithCurrentValueFromObservableClass<A, B>
|
|
|
95
92
|
? Optional.none
|
|
96
93
|
: Optional.some([par.value, me.value] as const),
|
|
97
94
|
).value,
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
override tryUpdate(updateToken: UpdateToken): void {
|
|
104
|
-
const par = this.parents[0];
|
|
105
|
-
|
|
106
|
-
const ps = par.getSnapshot();
|
|
95
|
+
},
|
|
96
|
+
({ setNext }) =>
|
|
97
|
+
(updateToken) => {
|
|
98
|
+
const ps = parentObservable.getSnapshot();
|
|
107
99
|
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
100
|
+
if (
|
|
101
|
+
parentObservable.updateToken !== updateToken ||
|
|
102
|
+
Optional.isNone(ps)
|
|
103
|
+
) {
|
|
104
|
+
return; // skip update
|
|
105
|
+
}
|
|
111
106
|
|
|
112
|
-
|
|
107
|
+
const curr = observable.getSnapshot();
|
|
113
108
|
|
|
114
|
-
|
|
109
|
+
if (Optional.isNone(curr)) return; // skip update
|
|
115
110
|
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
111
|
+
setNext([ps.value, curr.value], updateToken);
|
|
112
|
+
},
|
|
113
|
+
);
|
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
import { expectType, Optional } from 'ts-data-forge';
|
|
2
|
-
import {
|
|
2
|
+
import { createInitializedSyncChildObservable } from '../base/index.mjs';
|
|
3
3
|
import { source } from '../create/index.mjs';
|
|
4
4
|
import {
|
|
5
5
|
type InitializedObservable,
|
|
6
6
|
type Observable,
|
|
7
|
-
type UpdateToken,
|
|
8
7
|
type WithInitialValueOperator,
|
|
9
8
|
type WithInitialValueOperatorObservable,
|
|
10
9
|
} from '../types/index.mjs';
|
|
@@ -57,31 +56,31 @@ import {
|
|
|
57
56
|
export const withInitialValue =
|
|
58
57
|
<A, I = A>(initialValue: I): WithInitialValueOperator<A, A | I> =>
|
|
59
58
|
(parentObservable) =>
|
|
60
|
-
|
|
59
|
+
createWithInitialValueObservable(parentObservable, initialValue);
|
|
61
60
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
61
|
+
const createWithInitialValueObservable = <A, I>(
|
|
62
|
+
parentObservable: Observable<A>,
|
|
63
|
+
initialValue: I,
|
|
64
|
+
): WithInitialValueOperatorObservable<A, I> =>
|
|
65
|
+
createInitializedSyncChildObservable<A | I, readonly [A]>(
|
|
66
|
+
{
|
|
68
67
|
parents: [parentObservable],
|
|
69
68
|
initialValue: Optional.some(initialValue),
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
const par = this.parents[0];
|
|
75
|
-
|
|
76
|
-
const sn = par.getSnapshot();
|
|
69
|
+
},
|
|
70
|
+
({ setNext }) =>
|
|
71
|
+
(updateToken) => {
|
|
72
|
+
const sn = parentObservable.getSnapshot();
|
|
77
73
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
74
|
+
if (
|
|
75
|
+
parentObservable.updateToken !== updateToken ||
|
|
76
|
+
Optional.isNone(sn)
|
|
77
|
+
) {
|
|
78
|
+
return; // skip update
|
|
79
|
+
}
|
|
81
80
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
81
|
+
setNext(sn.value, updateToken);
|
|
82
|
+
},
|
|
83
|
+
);
|
|
85
84
|
|
|
86
85
|
if (import.meta.vitest !== undefined) {
|
|
87
86
|
test('type test', () => {
|
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
import { type Some } from 'ts-data-forge';
|
|
2
|
-
import { type MutableSet } from 'ts-type-forge';
|
|
3
|
-
import { type AsyncChildObservable, type ChildObservable, type InitializedObservable, type InitializedSyncChildObservable, type KeepInitialValueOperator, type NonEmptyUnknownList, type Observable, type ObservableId, type Operator, type SyncChildObservable, type WithInitialValueOperator, type Wrap } from '../types/index.mjs';
|
|
4
|
-
import { ObservableBaseClass } from './observable-base-class.mjs';
|
|
5
|
-
export declare class AsyncChildObservableClass<A, const P extends NonEmptyUnknownList> extends ObservableBaseClass<A, 'async child', number> implements AsyncChildObservable<A, P> {
|
|
6
|
-
#private;
|
|
7
|
-
readonly parents: Readonly<{ [P_1 in keyof P]: Observable<P[P_1]>; }>;
|
|
8
|
-
protected readonly descendantsIdSet: MutableSet<ObservableId>;
|
|
9
|
-
constructor({ parents, depth, initialValue, }: Readonly<{
|
|
10
|
-
parents: Wrap<P>;
|
|
11
|
-
depth?: number;
|
|
12
|
-
initialValue: ReturnType<AsyncChildObservable<A>['getSnapshot']>;
|
|
13
|
-
}>);
|
|
14
|
-
addDescendant<B>(child: ChildObservable<B>): void;
|
|
15
|
-
startUpdate(nextValue: A): void;
|
|
16
|
-
complete(): void;
|
|
17
|
-
tryComplete(): void;
|
|
18
|
-
}
|
|
19
|
-
export declare class SyncChildObservableClass<A, const P extends NonEmptyUnknownList> extends ObservableBaseClass<A, 'sync child', number> implements SyncChildObservable<A, P> {
|
|
20
|
-
readonly parents: Readonly<{ [P_1 in keyof P]: Observable<P[P_1]>; }>;
|
|
21
|
-
constructor({ parents, depth, initialValue, }: Readonly<{
|
|
22
|
-
parents: Wrap<P>;
|
|
23
|
-
depth?: number;
|
|
24
|
-
initialValue: ReturnType<SyncChildObservable<A>['getSnapshot']>;
|
|
25
|
-
}>);
|
|
26
|
-
complete(): void;
|
|
27
|
-
tryComplete(): void;
|
|
28
|
-
}
|
|
29
|
-
export declare class InitializedSyncChildObservableClass<A, const P extends NonEmptyUnknownList> extends SyncChildObservableClass<A, P> implements InitializedSyncChildObservable<A, P> {
|
|
30
|
-
constructor({ parents, depth, initialValue, }: Readonly<{
|
|
31
|
-
parents: Wrap<P>;
|
|
32
|
-
depth?: number;
|
|
33
|
-
initialValue: ReturnType<InitializedSyncChildObservable<A>['getSnapshot']>;
|
|
34
|
-
}>);
|
|
35
|
-
getSnapshot(): Some<A>;
|
|
36
|
-
pipe<B>(operator: KeepInitialValueOperator<A, B> | WithInitialValueOperator<A, B>): InitializedObservable<B>;
|
|
37
|
-
pipe<B>(operator: Operator<A, B>): Observable<B>;
|
|
38
|
-
}
|
|
39
|
-
//# sourceMappingURL=child-observable-class.d.mts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"child-observable-class.d.mts","sourceRoot":"","sources":["../../../src/core/class/child-observable-class.mts"],"names":[],"mappings":"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"}
|
|
@@ -1,173 +0,0 @@
|
|
|
1
|
-
import { Arr } from 'ts-data-forge';
|
|
2
|
-
import { isManagerObservable, isChildObservable } from '../types/observable.mjs';
|
|
3
|
-
import { issueUpdateToken } from '../utils/id-maker.mjs';
|
|
4
|
-
import { maxDepth } from '../utils/max-depth.mjs';
|
|
5
|
-
import { binarySearch } from '../utils/utils.mjs';
|
|
6
|
-
import { ObservableBaseClass } from './observable-base-class.mjs';
|
|
7
|
-
|
|
8
|
-
const hasCircularDependencyFrom = (node, mut_visited, mut_inPath) => {
|
|
9
|
-
if (mut_inPath.has(node.id)) return true;
|
|
10
|
-
if (mut_visited.has(node.id)) return false;
|
|
11
|
-
mut_visited.add(node.id);
|
|
12
|
-
mut_inPath.add(node.id);
|
|
13
|
-
if (isChildObservable(node)) {
|
|
14
|
-
for (const parent of node.parents) {
|
|
15
|
-
if (hasCircularDependencyFrom(parent, mut_visited, mut_inPath)) {
|
|
16
|
-
return true;
|
|
17
|
-
}
|
|
18
|
-
}
|
|
19
|
-
}
|
|
20
|
-
mut_inPath.delete(node.id);
|
|
21
|
-
return false;
|
|
22
|
-
};
|
|
23
|
-
const detectCircularDependency = (child, parents) => {
|
|
24
|
-
const mut_visited = /* @__PURE__ */ new Set();
|
|
25
|
-
const mut_inPath = /* @__PURE__ */ new Set([child.id]);
|
|
26
|
-
for (const parent of parents) {
|
|
27
|
-
if (hasCircularDependencyFrom(parent, mut_visited, mut_inPath)) {
|
|
28
|
-
throw new Error(
|
|
29
|
-
"Circular dependency detected in observable graph: a child observable cannot be its own ancestor."
|
|
30
|
-
);
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
};
|
|
34
|
-
const registerChild = (child, parents) => {
|
|
35
|
-
detectCircularDependency(child, parents);
|
|
36
|
-
for (const p of parents) {
|
|
37
|
-
p.addChild(child);
|
|
38
|
-
}
|
|
39
|
-
const mut_rest = Array.from(parents);
|
|
40
|
-
while (Arr.isNonEmpty(mut_rest)) {
|
|
41
|
-
const p = mut_rest.pop();
|
|
42
|
-
if (p === void 0) break;
|
|
43
|
-
if (isManagerObservable(p)) {
|
|
44
|
-
p.addDescendant(child);
|
|
45
|
-
} else {
|
|
46
|
-
mut_rest.push(...p.parents);
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
};
|
|
50
|
-
const tryComplete = ({
|
|
51
|
-
hasSubscriber,
|
|
52
|
-
hasActiveChild,
|
|
53
|
-
parents,
|
|
54
|
-
complete
|
|
55
|
-
}) => {
|
|
56
|
-
if (parents.every((r) => r.isCompleted)) {
|
|
57
|
-
complete();
|
|
58
|
-
return;
|
|
59
|
-
}
|
|
60
|
-
if (!hasSubscriber && !hasActiveChild) {
|
|
61
|
-
complete();
|
|
62
|
-
}
|
|
63
|
-
for (const par of parents) {
|
|
64
|
-
par.tryComplete();
|
|
65
|
-
}
|
|
66
|
-
};
|
|
67
|
-
class AsyncChildObservableClass extends ObservableBaseClass {
|
|
68
|
-
#mut_propagationOrder;
|
|
69
|
-
parents;
|
|
70
|
-
descendantsIdSet;
|
|
71
|
-
constructor({
|
|
72
|
-
parents,
|
|
73
|
-
depth = 1 + maxDepth(parents),
|
|
74
|
-
initialValue
|
|
75
|
-
}) {
|
|
76
|
-
super({
|
|
77
|
-
kind: "async child",
|
|
78
|
-
depth,
|
|
79
|
-
initialValue
|
|
80
|
-
});
|
|
81
|
-
this.parents = parents;
|
|
82
|
-
this.#mut_propagationOrder = [];
|
|
83
|
-
this.descendantsIdSet = /* @__PURE__ */ new Set();
|
|
84
|
-
registerChild(this, parents);
|
|
85
|
-
}
|
|
86
|
-
// overload
|
|
87
|
-
addDescendant(child) {
|
|
88
|
-
if (this.descendantsIdSet.has(child.id)) return;
|
|
89
|
-
this.descendantsIdSet.add(child.id);
|
|
90
|
-
const insertPos = binarySearch(
|
|
91
|
-
this.#mut_propagationOrder.map((a) => a.depth),
|
|
92
|
-
child.depth
|
|
93
|
-
);
|
|
94
|
-
this.#mut_propagationOrder = Arr.toInserted(
|
|
95
|
-
this.#mut_propagationOrder,
|
|
96
|
-
insertPos,
|
|
97
|
-
child
|
|
98
|
-
);
|
|
99
|
-
}
|
|
100
|
-
startUpdate(nextValue) {
|
|
101
|
-
const updateToken = issueUpdateToken();
|
|
102
|
-
this.setNext(nextValue, updateToken);
|
|
103
|
-
for (const p of this.#mut_propagationOrder) {
|
|
104
|
-
p.tryUpdate(updateToken);
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
complete() {
|
|
108
|
-
super.complete();
|
|
109
|
-
for (const par of this.parents) {
|
|
110
|
-
par.tryComplete();
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
tryComplete() {
|
|
114
|
-
tryComplete({
|
|
115
|
-
complete: () => {
|
|
116
|
-
this.complete();
|
|
117
|
-
},
|
|
118
|
-
hasActiveChild: this.hasActiveChild(),
|
|
119
|
-
hasSubscriber: this.hasSubscriber,
|
|
120
|
-
parents: this.parents
|
|
121
|
-
});
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
class SyncChildObservableClass extends ObservableBaseClass {
|
|
125
|
-
parents;
|
|
126
|
-
constructor({
|
|
127
|
-
parents,
|
|
128
|
-
depth = 1 + maxDepth(parents),
|
|
129
|
-
initialValue
|
|
130
|
-
}) {
|
|
131
|
-
super({
|
|
132
|
-
kind: "sync child",
|
|
133
|
-
depth,
|
|
134
|
-
initialValue
|
|
135
|
-
});
|
|
136
|
-
this.parents = parents;
|
|
137
|
-
registerChild(this, parents);
|
|
138
|
-
}
|
|
139
|
-
complete() {
|
|
140
|
-
super.complete();
|
|
141
|
-
for (const par of this.parents) {
|
|
142
|
-
par.tryComplete();
|
|
143
|
-
}
|
|
144
|
-
}
|
|
145
|
-
tryComplete() {
|
|
146
|
-
tryComplete({
|
|
147
|
-
complete: () => {
|
|
148
|
-
this.complete();
|
|
149
|
-
},
|
|
150
|
-
hasActiveChild: this.hasActiveChild(),
|
|
151
|
-
hasSubscriber: this.hasSubscriber,
|
|
152
|
-
parents: this.parents
|
|
153
|
-
});
|
|
154
|
-
}
|
|
155
|
-
}
|
|
156
|
-
class InitializedSyncChildObservableClass extends SyncChildObservableClass {
|
|
157
|
-
constructor({
|
|
158
|
-
parents,
|
|
159
|
-
depth = 1 + maxDepth(parents),
|
|
160
|
-
initialValue
|
|
161
|
-
}) {
|
|
162
|
-
super({ parents, depth, initialValue });
|
|
163
|
-
}
|
|
164
|
-
getSnapshot() {
|
|
165
|
-
return super.getCurrentValue();
|
|
166
|
-
}
|
|
167
|
-
pipe(operator) {
|
|
168
|
-
return operator(this);
|
|
169
|
-
}
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
export { AsyncChildObservableClass, InitializedSyncChildObservableClass, SyncChildObservableClass };
|
|
173
|
-
//# sourceMappingURL=child-observable-class.mjs.map
|