synstate 2.0.2 → 3.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 +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 +181 -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 +156 -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 +50 -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/base/index.mjs.map +1 -0
- package/dist/core/combine/combine.d.mts.map +1 -1
- package/dist/core/combine/combine.mjs +132 -39
- package/dist/core/combine/combine.mjs.map +1 -1
- package/dist/core/combine/index.mjs +4 -4
- package/dist/core/combine/index.mjs.map +1 -1
- package/dist/core/combine/merge.d.mts.map +1 -1
- package/dist/core/combine/merge.mjs +78 -29
- 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 +124 -42
- 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 +82 -57
- 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 +62 -36
- 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 +67 -25
- 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 +72 -28
- package/dist/core/create/from-subscribable.mjs.map +1 -1
- package/dist/core/create/index.mjs +8 -8
- package/dist/core/create/index.mjs.map +1 -1
- package/dist/core/create/just.d.mts.map +1 -1
- package/dist/core/create/just.mjs +36 -12
- package/dist/core/create/just.mjs.map +1 -1
- package/dist/core/create/source.mjs +15 -20
- 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 +67 -44
- 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 +6 -44
- package/dist/core/index.mjs.map +1 -1
- package/dist/core/operators/audit.d.mts.map +1 -1
- package/dist/core/operators/audit.mjs +127 -48
- 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 +115 -45
- 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 +43 -32
- package/dist/core/operators/filter.mjs.map +1 -1
- package/dist/core/operators/index.mjs +18 -18
- package/dist/core/operators/index.mjs.map +1 -1
- package/dist/core/operators/map.d.mts.map +1 -1
- package/dist/core/operators/map.mjs +79 -38
- 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 +131 -47
- 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 +79 -31
- 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 +64 -25
- 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 +93 -39
- 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 +73 -32
- 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 +85 -38
- 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 +121 -40
- 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 +71 -36
- 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 +103 -35
- 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 +109 -47
- 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 +93 -46
- 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 +84 -34
- 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 +68 -21
- package/dist/core/operators/with-initial-value.mjs.map +1 -1
- package/dist/core/predefined/index.mjs +2 -12
- package/dist/core/predefined/index.mjs.map +1 -1
- package/dist/core/predefined/operators/attach-index.mjs +55 -7
- package/dist/core/predefined/operators/attach-index.mjs.map +1 -1
- package/dist/core/predefined/operators/index.mjs +12 -12
- package/dist/core/predefined/operators/index.mjs.map +1 -1
- package/dist/core/predefined/operators/map-optional.mjs +48 -5
- package/dist/core/predefined/operators/map-optional.mjs.map +1 -1
- package/dist/core/predefined/operators/map-result-err.mjs +48 -5
- package/dist/core/predefined/operators/map-result-err.mjs.map +1 -1
- package/dist/core/predefined/operators/map-result-ok.mjs +48 -5
- package/dist/core/predefined/operators/map-result-ok.mjs.map +1 -1
- package/dist/core/predefined/operators/map-to.mjs +41 -6
- package/dist/core/predefined/operators/map-to.mjs.map +1 -1
- package/dist/core/predefined/operators/pluck.mjs +45 -7
- package/dist/core/predefined/operators/pluck.mjs.map +1 -1
- package/dist/core/predefined/operators/skip.mjs +49 -6
- package/dist/core/predefined/operators/skip.mjs.map +1 -1
- package/dist/core/predefined/operators/take.mjs +42 -6
- package/dist/core/predefined/operators/take.mjs.map +1 -1
- package/dist/core/predefined/operators/unwrap-optional.mjs +43 -8
- package/dist/core/predefined/operators/unwrap-optional.mjs.map +1 -1
- package/dist/core/predefined/operators/unwrap-result-err.mjs +41 -5
- package/dist/core/predefined/operators/unwrap-result-err.mjs.map +1 -1
- package/dist/core/predefined/operators/unwrap-result-ok.mjs +43 -8
- package/dist/core/predefined/operators/unwrap-result-ok.mjs.map +1 -1
- package/dist/core/types/id.mjs +2 -2
- package/dist/core/types/id.mjs.map +1 -1
- package/dist/core/types/index.mjs +7 -3
- package/dist/core/types/index.mjs.map +1 -1
- package/dist/core/types/observable-family.mjs +14 -2
- package/dist/core/types/observable-family.mjs.map +1 -1
- package/dist/core/types/observable-kind.mjs +2 -2
- package/dist/core/types/observable-kind.mjs.map +1 -1
- package/dist/core/types/observable.mjs +14 -6
- package/dist/core/types/observable.mjs.map +1 -1
- package/dist/core/types/timer.mjs +2 -2
- package/dist/core/types/timer.mjs.map +1 -1
- package/dist/core/types/types.mjs +9 -2
- package/dist/core/types/types.mjs.map +1 -1
- package/dist/core/utils/id-maker.mjs +10 -11
- package/dist/core/utils/id-maker.mjs.map +1 -1
- package/dist/core/utils/index.mjs +5 -5
- package/dist/core/utils/index.mjs.map +1 -1
- package/dist/core/utils/max-depth.mjs +7 -4
- package/dist/core/utils/max-depth.mjs.map +1 -1
- package/dist/core/utils/observable-utils.mjs +4 -7
- package/dist/core/utils/observable-utils.mjs.map +1 -1
- package/dist/core/utils/utils.mjs +32 -28
- package/dist/core/utils/utils.mjs.map +1 -1
- package/dist/entry-point.mjs +2 -49
- package/dist/entry-point.mjs.map +1 -1
- package/dist/index.mjs +3 -49
- package/dist/index.mjs.map +1 -1
- package/dist/utils/collect-to-array.mjs +8 -13
- package/dist/utils/collect-to-array.mjs.map +1 -1
- package/dist/utils/create-boolean-state.mjs +47 -22
- package/dist/utils/create-boolean-state.mjs.map +1 -1
- package/dist/utils/create-event-emitter.mjs +67 -19
- package/dist/utils/create-event-emitter.mjs.map +1 -1
- package/dist/utils/create-reducer.mjs +54 -16
- package/dist/utils/create-reducer.mjs.map +1 -1
- package/dist/utils/create-state.mjs +54 -27
- package/dist/utils/create-state.mjs.map +1 -1
- package/dist/utils/index.mjs +6 -6
- package/dist/utils/index.mjs.map +1 -1
- package/package.json +17 -19
- 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/index.mjs.map +0 -1
- 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
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Optional, expectType } from 'ts-data-forge';
|
|
2
2
|
import { type ArrayElement, type NonEmptyTuple } from 'ts-type-forge';
|
|
3
|
-
import {
|
|
3
|
+
import { createSyncChildObservable } from '../base/index.mjs';
|
|
4
4
|
import { source } from '../create/index.mjs';
|
|
5
5
|
import {
|
|
6
6
|
type MergeObservable,
|
|
@@ -8,7 +8,6 @@ import {
|
|
|
8
8
|
type NonEmptyUnknownList,
|
|
9
9
|
type Observable,
|
|
10
10
|
type SyncChildObservable,
|
|
11
|
-
type UpdateToken,
|
|
12
11
|
type Wrap,
|
|
13
12
|
} from '../types/index.mjs';
|
|
14
13
|
|
|
@@ -67,33 +66,32 @@ export const merge = <const OS extends NonEmptyTuple<Observable<unknown>>>(
|
|
|
67
66
|
parents: OS,
|
|
68
67
|
): MergeObservableRefined<OS> =>
|
|
69
68
|
// eslint-disable-next-line total-functions/no-unsafe-type-assertion
|
|
70
|
-
|
|
69
|
+
createMergeObservable(parents) as MergeObservableRefined<OS>;
|
|
71
70
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
super({
|
|
71
|
+
const createMergeObservable = <const P extends NonEmptyUnknownList>(
|
|
72
|
+
parents: Wrap<P>,
|
|
73
|
+
): MergeObservable<P> =>
|
|
74
|
+
createSyncChildObservable<ArrayElement<P>, P>(
|
|
75
|
+
{
|
|
78
76
|
parents,
|
|
79
77
|
initialValue: Optional.none,
|
|
80
|
-
}
|
|
81
|
-
|
|
78
|
+
},
|
|
79
|
+
({ setNext }) =>
|
|
80
|
+
(updateToken) => {
|
|
81
|
+
const parentToUse = parents.find(
|
|
82
|
+
(o) =>
|
|
83
|
+
o.updateToken === updateToken && Optional.isSome(o.getSnapshot()),
|
|
84
|
+
);
|
|
82
85
|
|
|
83
|
-
|
|
84
|
-
const parentToUse = this.parents.find(
|
|
85
|
-
(o) => o.updateToken === updateToken && Optional.isSome(o.getSnapshot()),
|
|
86
|
-
);
|
|
86
|
+
if (parentToUse === undefined) return;
|
|
87
87
|
|
|
88
|
-
|
|
88
|
+
const nextValue =
|
|
89
|
+
// eslint-disable-next-line total-functions/no-unsafe-type-assertion
|
|
90
|
+
Optional.unwrap(parentToUse.getSnapshot()) as ArrayElement<P>;
|
|
89
91
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
this.setNext(nextValue, updateToken);
|
|
95
|
-
}
|
|
96
|
-
}
|
|
92
|
+
setNext(nextValue, updateToken);
|
|
93
|
+
},
|
|
94
|
+
);
|
|
97
95
|
|
|
98
96
|
if (import.meta.vitest !== undefined) {
|
|
99
97
|
test('type test', () => {
|
package/src/core/combine/zip.mts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Arr, Optional, createQueue, expectType } from 'ts-data-forge';
|
|
2
2
|
import { type NonEmptyTuple, type Tuple } from 'ts-type-forge';
|
|
3
|
-
import {
|
|
3
|
+
import { createSyncChildObservable } from '../base/index.mjs';
|
|
4
4
|
import { source } from '../create/index.mjs';
|
|
5
5
|
import { withInitialValue } from '../operators/index.mjs';
|
|
6
6
|
import {
|
|
@@ -10,7 +10,6 @@ import {
|
|
|
10
10
|
type Observable,
|
|
11
11
|
type SyncChildObservable,
|
|
12
12
|
type TupleToQueueTuple,
|
|
13
|
-
type UpdateToken,
|
|
14
13
|
type Wrap,
|
|
15
14
|
type ZipObservable,
|
|
16
15
|
type ZipObservableRefined,
|
|
@@ -69,63 +68,60 @@ export const zip = <const OS extends NonEmptyTuple<Observable<unknown>>>(
|
|
|
69
68
|
parents: OS,
|
|
70
69
|
): ZipObservableRefined<OS> =>
|
|
71
70
|
// eslint-disable-next-line total-functions/no-unsafe-type-assertion
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
71
|
+
createZipObservable(parents) as unknown as ZipObservableRefined<OS>;
|
|
72
|
+
|
|
73
|
+
const createZipObservable = <const A extends NonEmptyUnknownList>(
|
|
74
|
+
parents: Wrap<A>,
|
|
75
|
+
): ZipObservable<A> => {
|
|
76
|
+
const parentsValues: Tuple.MapTo<Optional<A[number]>, A> = Arr.map(
|
|
77
|
+
parents,
|
|
78
|
+
(p) => p.getSnapshot(),
|
|
79
|
+
);
|
|
80
|
+
|
|
81
|
+
// The annotation on `initialValue` is what replaces the type assertion.
|
|
82
|
+
// `Arr.map` carries a single result element type, so it reports `A[number]`
|
|
83
|
+
// at every position, and `Tuple.MapTo<A[number], A>` — the uniform mapping
|
|
84
|
+
// — is *not* assignable back to `A`. The positional
|
|
85
|
+
// `Readonly<{ [K in keyof A]: A[K] }>` is, and TypeScript accepts the
|
|
86
|
+
// uniform result into it because the two mapped types share `keyof A`. So
|
|
87
|
+
// it is the annotation, not an assertion, that records the position-wise
|
|
88
|
+
// fact the checker cannot derive on its own.
|
|
89
|
+
const initialValue: Optional<Readonly<{ [K in keyof A]: A[K] }>> = Arr.every(
|
|
90
|
+
parentsValues,
|
|
91
|
+
Optional.isSome,
|
|
92
|
+
)
|
|
93
|
+
? Optional.some(Arr.map(parentsValues, (c) => c.value))
|
|
94
|
+
: Optional.none;
|
|
95
|
+
|
|
96
|
+
const queues: TupleToQueueTuple<A> = Arr.map(parents, () => createQueue());
|
|
97
|
+
|
|
98
|
+
return createSyncChildObservable<A, A>(
|
|
99
|
+
{
|
|
100
100
|
parents,
|
|
101
101
|
initialValue,
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
this.setNext(nextValue, updateToken);
|
|
126
|
-
}
|
|
127
|
-
}
|
|
128
|
-
}
|
|
102
|
+
},
|
|
103
|
+
({ setNext }) =>
|
|
104
|
+
(updateToken) => {
|
|
105
|
+
for (const [index, par] of parents.entries()) {
|
|
106
|
+
const sn = par.getSnapshot();
|
|
107
|
+
|
|
108
|
+
if (par.updateToken === updateToken && Optional.isSome(sn)) {
|
|
109
|
+
queues[index]?.enqueue(sn.value);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
if (queues.every((list) => !list.isEmpty)) {
|
|
114
|
+
const nextValue =
|
|
115
|
+
// `Arr.map` has a single result element type, so it reports
|
|
116
|
+
// `A[number] | undefined` per position rather than `A[P]`.
|
|
117
|
+
// eslint-disable-next-line total-functions/no-unsafe-type-assertion
|
|
118
|
+
Arr.map(queues, (q) => Optional.unwrap(q.dequeue())) as A;
|
|
119
|
+
|
|
120
|
+
setNext(nextValue, updateToken);
|
|
121
|
+
}
|
|
122
|
+
},
|
|
123
|
+
);
|
|
124
|
+
};
|
|
129
125
|
|
|
130
126
|
if (import.meta.vitest !== undefined) {
|
|
131
127
|
test('type test', () => {
|
|
@@ -176,7 +172,7 @@ if (import.meta.vitest !== undefined) {
|
|
|
176
172
|
const _zi = zip([
|
|
177
173
|
r1.pipe(withInitialValue(0)),
|
|
178
174
|
r2.pipe(withInitialValue('0')),
|
|
179
|
-
]
|
|
175
|
+
]);
|
|
180
176
|
|
|
181
177
|
expectType<typeof _z, SyncChildObservable<readonly [number, string]>>('<=');
|
|
182
178
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { asSafeUint, Optional, SafeUint } from 'ts-data-forge';
|
|
2
|
-
import {
|
|
2
|
+
import { createRootObservable } from '../base/index.mjs';
|
|
3
3
|
import { type CounterObservable, type TimerId } from '../types/index.mjs';
|
|
4
4
|
|
|
5
5
|
/**
|
|
@@ -50,79 +50,62 @@ export const counter = (
|
|
|
50
50
|
options?: Readonly<{
|
|
51
51
|
startManually?: boolean;
|
|
52
52
|
}>,
|
|
53
|
-
): CounterObservable =>
|
|
54
|
-
|
|
55
|
-
intervalMilliSeconds,
|
|
56
|
-
options?.startManually ?? false,
|
|
57
|
-
);
|
|
58
|
-
|
|
59
|
-
class CounterObservableClass
|
|
60
|
-
extends RootObservableClass<SafeUint>
|
|
61
|
-
implements CounterObservable
|
|
62
|
-
{
|
|
63
|
-
readonly #intervalMilliSeconds: number;
|
|
64
|
-
#mut_counter: SafeUint;
|
|
65
|
-
#mut_timerId0: TimerId | undefined;
|
|
66
|
-
#mut_timerId: TimerId | undefined;
|
|
67
|
-
#mut_isStarted: boolean;
|
|
68
|
-
|
|
69
|
-
constructor(intervalMilliSeconds: number, startManually: boolean) {
|
|
70
|
-
super({ initialValue: Optional.none });
|
|
71
|
-
|
|
72
|
-
this.#intervalMilliSeconds = intervalMilliSeconds;
|
|
73
|
-
|
|
74
|
-
this.#mut_counter = asSafeUint(0);
|
|
53
|
+
): CounterObservable => {
|
|
54
|
+
let mut_counter: SafeUint = asSafeUint(0);
|
|
75
55
|
|
|
76
|
-
|
|
56
|
+
let mut_timerId0: TimerId | undefined = undefined;
|
|
77
57
|
|
|
78
|
-
|
|
58
|
+
let mut_timerId: TimerId | undefined = undefined;
|
|
79
59
|
|
|
80
|
-
|
|
60
|
+
let mut_isStarted = false;
|
|
81
61
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
#resetTimer(): void {
|
|
88
|
-
if (this.#mut_timerId0 === undefined || this.#mut_timerId === undefined) {
|
|
62
|
+
const resetTimer = (): void => {
|
|
63
|
+
if (mut_timerId0 === undefined || mut_timerId === undefined) {
|
|
89
64
|
return;
|
|
90
65
|
}
|
|
91
66
|
|
|
92
|
-
clearInterval(
|
|
67
|
+
clearInterval(mut_timerId0);
|
|
93
68
|
|
|
94
|
-
clearInterval(
|
|
95
|
-
}
|
|
69
|
+
clearInterval(mut_timerId);
|
|
70
|
+
};
|
|
96
71
|
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
72
|
+
const observable = createRootObservable<
|
|
73
|
+
SafeUint,
|
|
74
|
+
Readonly<{ start: () => void }>
|
|
75
|
+
>(
|
|
76
|
+
{ initialValue: Optional.none, onComplete: resetTimer },
|
|
77
|
+
({ startUpdate, isCompleted }) => ({
|
|
78
|
+
start: () => {
|
|
79
|
+
if (mut_isStarted) {
|
|
80
|
+
console.warn('cannot start twice');
|
|
100
81
|
|
|
101
|
-
|
|
102
|
-
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
103
84
|
|
|
104
|
-
|
|
85
|
+
mut_isStarted = true;
|
|
105
86
|
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
return;
|
|
110
|
-
}
|
|
87
|
+
if (isCompleted()) {
|
|
88
|
+
console.warn('cannot restart stopped CounterObservable');
|
|
111
89
|
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
}, 0);
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
115
92
|
|
|
116
|
-
|
|
117
|
-
|
|
93
|
+
mut_timerId0 = setTimeout(() => {
|
|
94
|
+
startUpdate(mut_counter);
|
|
95
|
+
}, 0);
|
|
118
96
|
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
}
|
|
97
|
+
mut_timerId = setInterval(() => {
|
|
98
|
+
mut_counter = SafeUint.add(1, mut_counter);
|
|
122
99
|
|
|
123
|
-
|
|
124
|
-
|
|
100
|
+
startUpdate(mut_counter);
|
|
101
|
+
}, intervalMilliSeconds);
|
|
102
|
+
},
|
|
103
|
+
}),
|
|
104
|
+
);
|
|
125
105
|
|
|
126
|
-
|
|
106
|
+
if (!(options?.startManually ?? false)) {
|
|
107
|
+
observable.start();
|
|
127
108
|
}
|
|
128
|
-
|
|
109
|
+
|
|
110
|
+
return observable;
|
|
111
|
+
};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Optional, Result } from 'ts-data-forge';
|
|
2
|
-
import {
|
|
2
|
+
import { createRootObservable } from '../base/index.mjs';
|
|
3
3
|
import { type FromPromiseObservable } from '../types/index.mjs';
|
|
4
4
|
|
|
5
5
|
/**
|
|
@@ -31,53 +31,46 @@ import { type FromPromiseObservable } from '../types/index.mjs';
|
|
|
31
31
|
export const fromAbortablePromise = <A, E = unknown>(
|
|
32
32
|
// eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
|
|
33
33
|
factory: (signal: AbortSignal) => Promise<A>,
|
|
34
|
-
): FromPromiseObservable<A, E> =>
|
|
35
|
-
new
|
|
34
|
+
): FromPromiseObservable<A, E> => {
|
|
35
|
+
const abortController = new AbortController();
|
|
36
36
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
{
|
|
41
|
-
|
|
37
|
+
return createRootObservable<Result<A, E>>(
|
|
38
|
+
{
|
|
39
|
+
initialValue: Optional.none,
|
|
40
|
+
onComplete: () => {
|
|
41
|
+
abortController.abort();
|
|
42
|
+
},
|
|
43
|
+
},
|
|
44
|
+
({ startUpdate, isCompleted, complete }) => {
|
|
45
|
+
const promise = factory(abortController.signal);
|
|
42
46
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
this.#abortController = new AbortController();
|
|
48
|
-
|
|
49
|
-
const promise = factory(this.#abortController.signal);
|
|
50
|
-
|
|
51
|
-
promise
|
|
52
|
-
.then((value) => {
|
|
53
|
-
if (this.isCompleted) return;
|
|
54
|
-
|
|
55
|
-
this.startUpdate(Result.ok(value));
|
|
56
|
-
})
|
|
57
|
-
.catch((error: unknown) => {
|
|
58
|
-
if (this.isCompleted) return;
|
|
47
|
+
promise
|
|
48
|
+
.then((value) => {
|
|
49
|
+
if (isCompleted()) return;
|
|
59
50
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
return;
|
|
64
|
-
}
|
|
51
|
+
startUpdate(Result.ok(value));
|
|
52
|
+
})
|
|
53
|
+
.catch((error: unknown) => {
|
|
54
|
+
if (isCompleted()) return;
|
|
65
55
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
);
|
|
72
|
-
})
|
|
73
|
-
.finally(() => {
|
|
74
|
-
this.complete();
|
|
75
|
-
});
|
|
76
|
-
}
|
|
56
|
+
// Silently ignore AbortError — it means the observable was
|
|
57
|
+
// intentionally completed (e.g., by switchMap).
|
|
58
|
+
if (error instanceof DOMException && error.name === 'AbortError') {
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
77
61
|
|
|
78
|
-
|
|
79
|
-
|
|
62
|
+
startUpdate(
|
|
63
|
+
Result.err(
|
|
64
|
+
// eslint-disable-next-line total-functions/no-unsafe-type-assertion
|
|
65
|
+
error as E,
|
|
66
|
+
),
|
|
67
|
+
);
|
|
68
|
+
})
|
|
69
|
+
.finally(() => {
|
|
70
|
+
complete();
|
|
71
|
+
});
|
|
80
72
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
73
|
+
return {};
|
|
74
|
+
},
|
|
75
|
+
);
|
|
76
|
+
};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Optional, Result } from 'ts-data-forge';
|
|
2
|
-
import {
|
|
2
|
+
import { createRootObservable } from '../base/index.mjs';
|
|
3
3
|
import { type FromPromiseObservable } from '../types/index.mjs';
|
|
4
4
|
|
|
5
5
|
/**
|
|
@@ -51,33 +51,30 @@ import { type FromPromiseObservable } from '../types/index.mjs';
|
|
|
51
51
|
*/
|
|
52
52
|
export const fromPromise = <A, E = unknown>(
|
|
53
53
|
promise: Promise<A>,
|
|
54
|
-
): FromPromiseObservable<A, E> =>
|
|
54
|
+
): FromPromiseObservable<A, E> =>
|
|
55
|
+
createRootObservable<Result<A, E>>(
|
|
56
|
+
{ initialValue: Optional.none },
|
|
57
|
+
({ startUpdate, isCompleted, complete }) => {
|
|
58
|
+
promise
|
|
59
|
+
.then((value) => {
|
|
60
|
+
if (isCompleted()) return;
|
|
55
61
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
constructor(promise: Promise<A>) {
|
|
61
|
-
super({ initialValue: Optional.none });
|
|
62
|
+
startUpdate(Result.ok(value));
|
|
63
|
+
})
|
|
64
|
+
.catch((error: unknown) => {
|
|
65
|
+
if (isCompleted()) return;
|
|
62
66
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
67
|
+
startUpdate(
|
|
68
|
+
Result.err(
|
|
69
|
+
// eslint-disable-next-line total-functions/no-unsafe-type-assertion
|
|
70
|
+
error as E,
|
|
71
|
+
),
|
|
72
|
+
);
|
|
73
|
+
})
|
|
74
|
+
.finally(() => {
|
|
75
|
+
complete();
|
|
76
|
+
});
|
|
66
77
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
if (this.isCompleted) return;
|
|
71
|
-
|
|
72
|
-
this.startUpdate(
|
|
73
|
-
Result.err(
|
|
74
|
-
// eslint-disable-next-line total-functions/no-unsafe-type-assertion
|
|
75
|
-
error as E,
|
|
76
|
-
),
|
|
77
|
-
);
|
|
78
|
-
})
|
|
79
|
-
.finally(() => {
|
|
80
|
-
this.complete();
|
|
81
|
-
});
|
|
82
|
-
}
|
|
83
|
-
}
|
|
78
|
+
return {};
|
|
79
|
+
},
|
|
80
|
+
);
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Optional, Result } from 'ts-data-forge';
|
|
2
|
-
import {
|
|
2
|
+
import { createRootObservable } from '../base/index.mjs';
|
|
3
3
|
import {
|
|
4
4
|
type FromSubscribableObservable,
|
|
5
5
|
type Subscribable,
|
|
@@ -66,30 +66,26 @@ import {
|
|
|
66
66
|
export const fromSubscribable = <A, E = unknown>(
|
|
67
67
|
subscribable: Subscribable<A>,
|
|
68
68
|
): FromSubscribableObservable<A, E> =>
|
|
69
|
-
|
|
69
|
+
createRootObservable<Result<A, E>>(
|
|
70
|
+
{ initialValue: Optional.none },
|
|
71
|
+
({ startUpdate, complete }) => {
|
|
72
|
+
subscribable.subscribe(
|
|
73
|
+
(nextValue) => {
|
|
74
|
+
startUpdate(Result.ok(nextValue));
|
|
75
|
+
},
|
|
76
|
+
(error?: unknown) => {
|
|
77
|
+
startUpdate(
|
|
78
|
+
Result.err(
|
|
79
|
+
// eslint-disable-next-line total-functions/no-unsafe-type-assertion
|
|
80
|
+
error as E,
|
|
81
|
+
),
|
|
82
|
+
);
|
|
83
|
+
},
|
|
84
|
+
() => {
|
|
85
|
+
complete();
|
|
86
|
+
},
|
|
87
|
+
);
|
|
70
88
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
{
|
|
75
|
-
constructor(subscribable: Subscribable<A>) {
|
|
76
|
-
super({ initialValue: Optional.none });
|
|
77
|
-
|
|
78
|
-
subscribable.subscribe(
|
|
79
|
-
(nextValue) => {
|
|
80
|
-
this.startUpdate(Result.ok(nextValue));
|
|
81
|
-
},
|
|
82
|
-
(error?: unknown) => {
|
|
83
|
-
this.startUpdate(
|
|
84
|
-
Result.err(
|
|
85
|
-
// eslint-disable-next-line total-functions/no-unsafe-type-assertion
|
|
86
|
-
error as E,
|
|
87
|
-
),
|
|
88
|
-
);
|
|
89
|
-
},
|
|
90
|
-
() => {
|
|
91
|
-
this.complete();
|
|
92
|
-
},
|
|
93
|
-
);
|
|
94
|
-
}
|
|
95
|
-
}
|
|
89
|
+
return {};
|
|
90
|
+
},
|
|
91
|
+
);
|
package/src/core/create/just.mts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Optional } from 'ts-data-forge';
|
|
2
|
-
import {
|
|
2
|
+
import { createRootObservable } from '../base/index.mjs';
|
|
3
3
|
import { type InitializedRootObservable } from '../types/index.mjs';
|
|
4
4
|
|
|
5
5
|
/**
|
|
@@ -32,9 +32,10 @@ import { type InitializedRootObservable } from '../types/index.mjs';
|
|
|
32
32
|
* ```
|
|
33
33
|
*/
|
|
34
34
|
export const just = <const A,>(value: A): InitializedRootObservable<A> => {
|
|
35
|
-
const obs =
|
|
36
|
-
initialValue: Optional.some(value),
|
|
37
|
-
|
|
35
|
+
const obs = createRootObservable<A>(
|
|
36
|
+
{ initialValue: Optional.some(value) },
|
|
37
|
+
() => ({}),
|
|
38
|
+
);
|
|
38
39
|
|
|
39
40
|
obs.complete();
|
|
40
41
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Arr, Optional } from 'ts-data-forge';
|
|
2
|
-
import {
|
|
2
|
+
import { createRootObservable } from '../base/index.mjs';
|
|
3
3
|
import {
|
|
4
4
|
type InitializedSourceObservable,
|
|
5
5
|
type SourceObservable,
|
|
@@ -51,24 +51,18 @@ export function source<const A>(
|
|
|
51
51
|
export function source<const A>(): SourceObservable<A>;
|
|
52
52
|
|
|
53
53
|
export function source<const A>(...args: readonly A[]): SourceObservable<A> {
|
|
54
|
-
return
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
class SourceObservableClass<A>
|
|
58
|
-
extends RootObservableClass<A>
|
|
59
|
-
implements SourceObservable<A>
|
|
60
|
-
{
|
|
61
|
-
constructor(...args: readonly A[]) {
|
|
62
|
-
super({
|
|
54
|
+
return createRootObservable<A, Readonly<{ next: (nextValue: A) => void }>>(
|
|
55
|
+
{
|
|
63
56
|
initialValue: Arr.isNonEmpty(args)
|
|
64
57
|
? Optional.some(args[0])
|
|
65
58
|
: Optional.none,
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
if (this.isCompleted) return;
|
|
59
|
+
},
|
|
60
|
+
({ startUpdate, isCompleted }) => ({
|
|
61
|
+
next: (nextValue: A) => {
|
|
62
|
+
if (isCompleted()) return;
|
|
71
63
|
|
|
72
|
-
|
|
73
|
-
|
|
64
|
+
startUpdate(nextValue);
|
|
65
|
+
},
|
|
66
|
+
}),
|
|
67
|
+
);
|
|
74
68
|
}
|