synstate 0.1.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 +878 -0
- package/dist/core/class/child-observable-class.d.mts +37 -0
- package/dist/core/class/child-observable-class.d.mts.map +1 -0
- package/dist/core/class/child-observable-class.mjs +134 -0
- package/dist/core/class/child-observable-class.mjs.map +1 -0
- package/dist/core/class/index.d.mts +4 -0
- package/dist/core/class/index.d.mts.map +1 -0
- package/dist/core/class/index.mjs +4 -0
- package/dist/core/class/index.mjs.map +1 -0
- package/dist/core/class/observable-base-class.d.mts +28 -0
- package/dist/core/class/observable-base-class.d.mts.map +1 -0
- package/dist/core/class/observable-base-class.mjs +116 -0
- package/dist/core/class/observable-base-class.mjs.map +1 -0
- package/dist/core/class/root-observable-class.d.mts +12 -0
- package/dist/core/class/root-observable-class.d.mts.map +1 -0
- package/dist/core/class/root-observable-class.mjs +35 -0
- package/dist/core/class/root-observable-class.mjs.map +1 -0
- package/dist/core/combine/combine.d.mts +35 -0
- package/dist/core/combine/combine.d.mts.map +1 -0
- package/dist/core/combine/combine.mjs +94 -0
- package/dist/core/combine/combine.mjs.map +1 -0
- package/dist/core/combine/index.d.mts +4 -0
- package/dist/core/combine/index.d.mts.map +1 -0
- package/dist/core/combine/index.mjs +4 -0
- package/dist/core/combine/index.mjs.map +1 -0
- package/dist/core/combine/merge.d.mts +28 -0
- package/dist/core/combine/merge.d.mts.map +1 -0
- package/dist/core/combine/merge.mjs +52 -0
- package/dist/core/combine/merge.mjs.map +1 -0
- package/dist/core/combine/zip.d.mts +26 -0
- package/dist/core/combine/zip.d.mts.map +1 -0
- package/dist/core/combine/zip.mjs +63 -0
- package/dist/core/combine/zip.mjs.map +1 -0
- package/dist/core/create/from-array.d.mts +21 -0
- package/dist/core/create/from-array.d.mts.map +1 -0
- package/dist/core/create/from-array.mjs +47 -0
- package/dist/core/create/from-array.mjs.map +1 -0
- package/dist/core/create/from-promise.d.mts +25 -0
- package/dist/core/create/from-promise.d.mts.map +1 -0
- package/dist/core/create/from-promise.mjs +51 -0
- package/dist/core/create/from-promise.mjs.map +1 -0
- package/dist/core/create/from-subscribable.d.mts +3 -0
- package/dist/core/create/from-subscribable.d.mts.map +1 -0
- package/dist/core/create/from-subscribable.mjs +22 -0
- package/dist/core/create/from-subscribable.mjs.map +1 -0
- package/dist/core/create/index.d.mts +8 -0
- package/dist/core/create/index.d.mts.map +1 -0
- package/dist/core/create/index.mjs +8 -0
- package/dist/core/create/index.mjs.map +1 -0
- package/dist/core/create/interval.d.mts +21 -0
- package/dist/core/create/interval.d.mts.map +1 -0
- package/dist/core/create/interval.mjs +74 -0
- package/dist/core/create/interval.mjs.map +1 -0
- package/dist/core/create/of.d.mts +20 -0
- package/dist/core/create/of.d.mts.map +1 -0
- package/dist/core/create/of.mjs +44 -0
- package/dist/core/create/of.mjs.map +1 -0
- package/dist/core/create/source.d.mts +29 -0
- package/dist/core/create/source.d.mts.map +1 -0
- package/dist/core/create/source.mjs +29 -0
- package/dist/core/create/source.mjs.map +1 -0
- package/dist/core/create/timer.d.mts +20 -0
- package/dist/core/create/timer.d.mts.map +1 -0
- package/dist/core/create/timer.mjs +64 -0
- package/dist/core/create/timer.mjs.map +1 -0
- package/dist/core/index.d.mts +7 -0
- package/dist/core/index.d.mts.map +1 -0
- package/dist/core/index.mjs +37 -0
- package/dist/core/index.mjs.map +1 -0
- package/dist/core/operators/audit-time.d.mts +3 -0
- package/dist/core/operators/audit-time.d.mts.map +1 -0
- package/dist/core/operators/audit-time.mjs +50 -0
- package/dist/core/operators/audit-time.mjs.map +1 -0
- package/dist/core/operators/debounce-time.d.mts +31 -0
- package/dist/core/operators/debounce-time.d.mts.map +1 -0
- package/dist/core/operators/debounce-time.mjs +73 -0
- package/dist/core/operators/debounce-time.mjs.map +1 -0
- package/dist/core/operators/filter.d.mts +28 -0
- package/dist/core/operators/filter.d.mts.map +1 -0
- package/dist/core/operators/filter.mjs +38 -0
- package/dist/core/operators/filter.mjs.map +1 -0
- package/dist/core/operators/index.d.mts +18 -0
- package/dist/core/operators/index.d.mts.map +1 -0
- package/dist/core/operators/index.mjs +18 -0
- package/dist/core/operators/index.mjs.map +1 -0
- package/dist/core/operators/map-with-index.d.mts +39 -0
- package/dist/core/operators/map-with-index.d.mts.map +1 -0
- package/dist/core/operators/map-with-index.mjs +73 -0
- package/dist/core/operators/map-with-index.mjs.map +1 -0
- package/dist/core/operators/merge-map.d.mts +34 -0
- package/dist/core/operators/merge-map.d.mts.map +1 -0
- package/dist/core/operators/merge-map.mjs +75 -0
- package/dist/core/operators/merge-map.mjs.map +1 -0
- package/dist/core/operators/pairwise.d.mts +27 -0
- package/dist/core/operators/pairwise.d.mts.map +1 -0
- package/dist/core/operators/pairwise.mjs +59 -0
- package/dist/core/operators/pairwise.mjs.map +1 -0
- package/dist/core/operators/scan.d.mts +30 -0
- package/dist/core/operators/scan.d.mts.map +1 -0
- package/dist/core/operators/scan.mjs +56 -0
- package/dist/core/operators/scan.mjs.map +1 -0
- package/dist/core/operators/skip-if-no-change.d.mts +33 -0
- package/dist/core/operators/skip-if-no-change.d.mts.map +1 -0
- package/dist/core/operators/skip-if-no-change.mjs +68 -0
- package/dist/core/operators/skip-if-no-change.mjs.map +1 -0
- package/dist/core/operators/skip-until.d.mts +3 -0
- package/dist/core/operators/skip-until.d.mts.map +1 -0
- package/dist/core/operators/skip-until.mjs +33 -0
- package/dist/core/operators/skip-until.mjs.map +1 -0
- package/dist/core/operators/skip-while.d.mts +4 -0
- package/dist/core/operators/skip-while.d.mts.map +1 -0
- package/dist/core/operators/skip-while.mjs +40 -0
- package/dist/core/operators/skip-while.mjs.map +1 -0
- package/dist/core/operators/switch-map.d.mts +31 -0
- package/dist/core/operators/switch-map.d.mts.map +1 -0
- package/dist/core/operators/switch-map.mjs +70 -0
- package/dist/core/operators/switch-map.mjs.map +1 -0
- package/dist/core/operators/take-until.d.mts +32 -0
- package/dist/core/operators/take-until.d.mts.map +1 -0
- package/dist/core/operators/take-until.mjs +60 -0
- package/dist/core/operators/take-until.mjs.map +1 -0
- package/dist/core/operators/take-while.d.mts +4 -0
- package/dist/core/operators/take-while.d.mts.map +1 -0
- package/dist/core/operators/take-while.mjs +42 -0
- package/dist/core/operators/take-while.mjs.map +1 -0
- package/dist/core/operators/throttle-time.d.mts +23 -0
- package/dist/core/operators/throttle-time.d.mts.map +1 -0
- package/dist/core/operators/throttle-time.mjs +68 -0
- package/dist/core/operators/throttle-time.mjs.map +1 -0
- package/dist/core/operators/with-buffered-from.d.mts +4 -0
- package/dist/core/operators/with-buffered-from.d.mts.map +1 -0
- package/dist/core/operators/with-buffered-from.mjs +45 -0
- package/dist/core/operators/with-buffered-from.mjs.map +1 -0
- package/dist/core/operators/with-current-value-from.d.mts +4 -0
- package/dist/core/operators/with-current-value-from.d.mts.map +1 -0
- package/dist/core/operators/with-current-value-from.mjs +37 -0
- package/dist/core/operators/with-current-value-from.mjs.map +1 -0
- package/dist/core/operators/with-initial-value.d.mts +26 -0
- package/dist/core/operators/with-initial-value.d.mts.map +1 -0
- package/dist/core/operators/with-initial-value.mjs +47 -0
- package/dist/core/operators/with-initial-value.mjs.map +1 -0
- package/dist/core/types/id.d.mts +4 -0
- package/dist/core/types/id.d.mts.map +1 -0
- package/dist/core/types/id.mjs +2 -0
- package/dist/core/types/id.mjs.map +1 -0
- package/dist/core/types/index.d.mts +6 -0
- package/dist/core/types/index.d.mts.map +1 -0
- package/dist/core/types/index.mjs +3 -0
- package/dist/core/types/index.mjs.map +1 -0
- package/dist/core/types/observable-family.d.mts +68 -0
- package/dist/core/types/observable-family.d.mts.map +1 -0
- package/dist/core/types/observable-family.mjs +2 -0
- package/dist/core/types/observable-family.mjs.map +1 -0
- package/dist/core/types/observable-kind.d.mts +4 -0
- package/dist/core/types/observable-kind.d.mts.map +1 -0
- package/dist/core/types/observable-kind.mjs +2 -0
- package/dist/core/types/observable-kind.mjs.map +1 -0
- package/dist/core/types/observable.d.mts +83 -0
- package/dist/core/types/observable.d.mts.map +1 -0
- package/dist/core/types/observable.mjs +10 -0
- package/dist/core/types/observable.mjs.map +1 -0
- package/dist/core/types/types.d.mts +16 -0
- package/dist/core/types/types.d.mts.map +1 -0
- package/dist/core/types/types.mjs +2 -0
- package/dist/core/types/types.mjs.map +1 -0
- package/dist/core/utils/id-maker.d.mts +5 -0
- package/dist/core/utils/id-maker.d.mts.map +1 -0
- package/dist/core/utils/id-maker.mjs +17 -0
- package/dist/core/utils/id-maker.mjs.map +1 -0
- package/dist/core/utils/index.d.mts +5 -0
- package/dist/core/utils/index.d.mts.map +1 -0
- package/dist/core/utils/index.mjs +5 -0
- package/dist/core/utils/index.mjs.map +1 -0
- package/dist/core/utils/max-depth.d.mts +3 -0
- package/dist/core/utils/max-depth.d.mts.map +1 -0
- package/dist/core/utils/max-depth.mjs +8 -0
- package/dist/core/utils/max-depth.mjs.map +1 -0
- package/dist/core/utils/observable-utils.d.mts +3 -0
- package/dist/core/utils/observable-utils.d.mts.map +1 -0
- package/dist/core/utils/observable-utils.mjs +7 -0
- package/dist/core/utils/observable-utils.mjs.map +1 -0
- package/dist/core/utils/utils.d.mts +4 -0
- package/dist/core/utils/utils.d.mts.map +1 -0
- package/dist/core/utils/utils.mjs +38 -0
- package/dist/core/utils/utils.mjs.map +1 -0
- package/dist/entry-point.d.mts +2 -0
- package/dist/entry-point.d.mts.map +1 -0
- package/dist/entry-point.mjs +40 -0
- package/dist/entry-point.mjs.map +1 -0
- package/dist/globals.d.mts +4 -0
- package/dist/index.d.mts +3 -0
- package/dist/index.d.mts.map +1 -0
- package/dist/index.mjs +40 -0
- package/dist/index.mjs.map +1 -0
- package/dist/tsconfig.json +1 -0
- package/dist/types.d.mts +2 -0
- package/dist/utils/create-event-emitter.d.mts +39 -0
- package/dist/utils/create-event-emitter.d.mts.map +1 -0
- package/dist/utils/create-event-emitter.mjs +57 -0
- package/dist/utils/create-event-emitter.mjs.map +1 -0
- package/dist/utils/create-reducer.d.mts +34 -0
- package/dist/utils/create-reducer.d.mts.map +1 -0
- package/dist/utils/create-reducer.mjs +49 -0
- package/dist/utils/create-reducer.mjs.map +1 -0
- package/dist/utils/create-state.d.mts +61 -0
- package/dist/utils/create-state.d.mts.map +1 -0
- package/dist/utils/create-state.mjs +92 -0
- package/dist/utils/create-state.mjs.map +1 -0
- package/dist/utils/index.d.mts +4 -0
- package/dist/utils/index.d.mts.map +1 -0
- package/dist/utils/index.mjs +4 -0
- package/dist/utils/index.mjs.map +1 -0
- package/package.json +71 -0
- package/src/core/class/child-observable-class.mts +232 -0
- package/src/core/class/index.mts +3 -0
- package/src/core/class/observable-base-class.mts +186 -0
- package/src/core/class/observable.class.test.mts +89 -0
- package/src/core/class/root-observable-class.mts +68 -0
- package/src/core/combine/combine.mts +144 -0
- package/src/core/combine/index.mts +3 -0
- package/src/core/combine/merge.mts +84 -0
- package/src/core/combine/zip.mts +149 -0
- package/src/core/create/from-array.mts +58 -0
- package/src/core/create/from-promise.mts +58 -0
- package/src/core/create/from-subscribable.mts +37 -0
- package/src/core/create/index.mts +7 -0
- package/src/core/create/interval.mts +99 -0
- package/src/core/create/of.mts +54 -0
- package/src/core/create/source.mts +59 -0
- package/src/core/create/timer.mts +84 -0
- package/src/core/index.mts +6 -0
- package/src/core/operators/audit-time.mts +77 -0
- package/src/core/operators/debounce-time.mts +96 -0
- package/src/core/operators/filter.mts +125 -0
- package/src/core/operators/index.mts +17 -0
- package/src/core/operators/map-with-index.mts +168 -0
- package/src/core/operators/merge-map.mts +108 -0
- package/src/core/operators/pairwise.mts +77 -0
- package/src/core/operators/scan.mts +81 -0
- package/src/core/operators/skip-if-no-change.mts +91 -0
- package/src/core/operators/skip-until.mts +54 -0
- package/src/core/operators/skip-while.mts +77 -0
- package/src/core/operators/switch-map.mts +101 -0
- package/src/core/operators/take-until.mts +80 -0
- package/src/core/operators/take-while.mts +103 -0
- package/src/core/operators/throttle-time.mts +95 -0
- package/src/core/operators/with-buffered-from.mts +68 -0
- package/src/core/operators/with-current-value-from.mts +58 -0
- package/src/core/operators/with-initial-value.mts +76 -0
- package/src/core/types/id.mts +5 -0
- package/src/core/types/index.mts +5 -0
- package/src/core/types/observable-family.mts +259 -0
- package/src/core/types/observable-kind.mts +5 -0
- package/src/core/types/observable.mts +218 -0
- package/src/core/types/types.mts +40 -0
- package/src/core/utils/id-maker.mts +31 -0
- package/src/core/utils/index.mts +4 -0
- package/src/core/utils/max-depth.mts +7 -0
- package/src/core/utils/observable-utils.mts +10 -0
- package/src/core/utils/utils.mts +51 -0
- package/src/core/utils/utils.test.mts +88 -0
- package/src/entry-point.mts +1 -0
- package/src/globals.d.mts +4 -0
- package/src/index.mts +2 -0
- package/src/utils/create-event-emitter.mts +62 -0
- package/src/utils/create-reducer.mts +55 -0
- package/src/utils/create-state.mts +138 -0
- package/src/utils/index.mts +3 -0
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
import {
|
|
2
|
+
Optional,
|
|
3
|
+
Result,
|
|
4
|
+
SafeUint,
|
|
5
|
+
asSafeUint,
|
|
6
|
+
expectType,
|
|
7
|
+
} from 'ts-data-forge';
|
|
8
|
+
import { SyncChildObservableClass } from '../class/index.mjs';
|
|
9
|
+
import { source } from '../create/index.mjs';
|
|
10
|
+
import {
|
|
11
|
+
type InitializedObservable,
|
|
12
|
+
type KeepInitialValueOperator,
|
|
13
|
+
type MapWithIndexOperatorObservable,
|
|
14
|
+
type Observable,
|
|
15
|
+
type UpdaterSymbol,
|
|
16
|
+
} from '../types/index.mjs';
|
|
17
|
+
import { withInitialValue } from './with-initial-value.mjs';
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Transforms each value emitted by the source using a mapping function that also receives the emission index.
|
|
21
|
+
*
|
|
22
|
+
* @template A - The type of values from the source
|
|
23
|
+
* @template B - The type of mapped values
|
|
24
|
+
* @param mapFn - A function that maps each value (receives value and index)
|
|
25
|
+
* @returns An operator that maps values with index
|
|
26
|
+
*
|
|
27
|
+
* @example
|
|
28
|
+
* ```ts
|
|
29
|
+
* const num$ = source<number>();
|
|
30
|
+
*
|
|
31
|
+
* const indexed$ = num$.pipe(mapWithIndex((x, i) => `${i}: ${x}`));
|
|
32
|
+
*
|
|
33
|
+
* indexed$.subscribe((s) => {
|
|
34
|
+
* console.log(s);
|
|
35
|
+
* });
|
|
36
|
+
*
|
|
37
|
+
* num$.next(10); // logs: 0: 10
|
|
38
|
+
*
|
|
39
|
+
* num$.next(20); // logs: 1: 20
|
|
40
|
+
* ```
|
|
41
|
+
*/
|
|
42
|
+
export const mapWithIndex = <A, B>(
|
|
43
|
+
mapFn: (x: A, index: SafeUint | -1) => B,
|
|
44
|
+
): KeepInitialValueOperator<A, B> =>
|
|
45
|
+
// eslint-disable-next-line total-functions/no-unsafe-type-assertion
|
|
46
|
+
((parentObservable) =>
|
|
47
|
+
new MapWithIndexObservableClass(
|
|
48
|
+
parentObservable,
|
|
49
|
+
mapFn,
|
|
50
|
+
)) as KeepInitialValueOperator<A, B>;
|
|
51
|
+
|
|
52
|
+
/* Specialized operators */
|
|
53
|
+
|
|
54
|
+
export const map = <A, B>(mapFn: (x: A) => B): KeepInitialValueOperator<A, B> =>
|
|
55
|
+
mapWithIndex(mapFn);
|
|
56
|
+
|
|
57
|
+
export const mapTo = <A, B>(value: B): KeepInitialValueOperator<A, B> =>
|
|
58
|
+
map(() => value);
|
|
59
|
+
|
|
60
|
+
export const pluck = <A, K extends keyof A>(
|
|
61
|
+
key: K,
|
|
62
|
+
): KeepInitialValueOperator<A, A[K]> => map((a) => a[key]);
|
|
63
|
+
|
|
64
|
+
export const getKey = pluck; // alias
|
|
65
|
+
|
|
66
|
+
export const attachIndex = <A,>(): KeepInitialValueOperator<
|
|
67
|
+
A,
|
|
68
|
+
readonly [SafeUint | -1, A]
|
|
69
|
+
> => mapWithIndex((a, i) => [i, a] as const);
|
|
70
|
+
|
|
71
|
+
export const withIndex = attachIndex; // alias
|
|
72
|
+
|
|
73
|
+
export const unwrapOptional = <
|
|
74
|
+
O extends UnknownOptional,
|
|
75
|
+
>(): KeepInitialValueOperator<O, Optional.Unwrap<O> | undefined> =>
|
|
76
|
+
// eslint-disable-next-line total-functions/no-unsafe-type-assertion
|
|
77
|
+
map(Optional.unwrap as Fn<O, Optional.Unwrap<O> | undefined>);
|
|
78
|
+
|
|
79
|
+
export const unwrapResultOk = <
|
|
80
|
+
R extends UnknownResult,
|
|
81
|
+
>(): KeepInitialValueOperator<R, Result.UnwrapOk<R> | undefined> =>
|
|
82
|
+
// eslint-disable-next-line total-functions/no-unsafe-type-assertion
|
|
83
|
+
map(Result.unwrapOk as Fn<R, Result.UnwrapOk<R> | undefined>);
|
|
84
|
+
|
|
85
|
+
export const unwrapResultErr = <
|
|
86
|
+
R extends UnknownResult,
|
|
87
|
+
>(): KeepInitialValueOperator<R, Result.UnwrapErr<R> | undefined> =>
|
|
88
|
+
map(Result.unwrapErr as Fn<R, Result.UnwrapErr<R> | undefined>);
|
|
89
|
+
|
|
90
|
+
export const mapOptional = <O extends UnknownOptional, B>(
|
|
91
|
+
mapFn: (x: Optional.Unwrap<O>) => B,
|
|
92
|
+
): KeepInitialValueOperator<O, Optional<B>> =>
|
|
93
|
+
map((a) => Optional.map(a, mapFn));
|
|
94
|
+
|
|
95
|
+
export const mapResultOk = <R extends UnknownResult, S2>(
|
|
96
|
+
mapFn: (x: Result.UnwrapOk<R>) => S2,
|
|
97
|
+
): KeepInitialValueOperator<R, Result<S2, Result.UnwrapErr<R>>> =>
|
|
98
|
+
map((a) => Result.map(a, mapFn));
|
|
99
|
+
|
|
100
|
+
export const mapResultErr = <R extends UnknownResult, E2>(
|
|
101
|
+
mapFn: (x: Result.UnwrapErr<R>) => E2,
|
|
102
|
+
): KeepInitialValueOperator<R, Result<Result.UnwrapOk<R>, E2>> =>
|
|
103
|
+
map((a) => Result.mapErr(a, mapFn));
|
|
104
|
+
|
|
105
|
+
/* implementation */
|
|
106
|
+
|
|
107
|
+
class MapWithIndexObservableClass<A, B>
|
|
108
|
+
extends SyncChildObservableClass<B, readonly [A]>
|
|
109
|
+
implements MapWithIndexOperatorObservable<A, B>
|
|
110
|
+
{
|
|
111
|
+
readonly #mapFn: (x: A, index: SafeUint | -1) => B;
|
|
112
|
+
#mut_index: SafeUint | -1;
|
|
113
|
+
|
|
114
|
+
constructor(
|
|
115
|
+
parentObservable: Observable<A>,
|
|
116
|
+
mapFn: (x: A, index: SafeUint | -1) => B,
|
|
117
|
+
) {
|
|
118
|
+
super({
|
|
119
|
+
parents: [parentObservable],
|
|
120
|
+
initialValue: Optional.map(parentObservable.getSnapshot(), (x) =>
|
|
121
|
+
mapFn(x, -1),
|
|
122
|
+
),
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
this.#mut_index = -1;
|
|
126
|
+
|
|
127
|
+
this.#mapFn = mapFn;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
override tryUpdate(updaterSymbol: UpdaterSymbol): void {
|
|
131
|
+
const par = this.parents[0];
|
|
132
|
+
|
|
133
|
+
const sn = par.getSnapshot();
|
|
134
|
+
|
|
135
|
+
if (par.updaterSymbol !== updaterSymbol || Optional.isNone(sn)) {
|
|
136
|
+
return; // skip update
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
this.#mut_index =
|
|
140
|
+
this.#mut_index === -1 ? asSafeUint(0) : SafeUint.add(1, this.#mut_index);
|
|
141
|
+
|
|
142
|
+
this.setNext(this.#mapFn(sn.value, this.#mut_index), updaterSymbol);
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
if (import.meta.vitest !== undefined) {
|
|
147
|
+
test('type test', () => {
|
|
148
|
+
expect(1).toBe(1); // dummy
|
|
149
|
+
});
|
|
150
|
+
|
|
151
|
+
{
|
|
152
|
+
const s: Observable<number> = source<number>();
|
|
153
|
+
|
|
154
|
+
const _d1 = s.pipe(map((x) => x + 1));
|
|
155
|
+
|
|
156
|
+
expectType<typeof _d1, Observable<number>>('=');
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
{
|
|
160
|
+
const s = source<number>();
|
|
161
|
+
|
|
162
|
+
const m: InitializedObservable<number> = s.pipe(withInitialValue(0));
|
|
163
|
+
|
|
164
|
+
const _d = m.pipe(map((x) => x + 1));
|
|
165
|
+
|
|
166
|
+
expectType<typeof _d, InitializedObservable<number>>('=');
|
|
167
|
+
}
|
|
168
|
+
}
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import { Arr, Optional } from 'ts-data-forge';
|
|
2
|
+
import { AsyncChildObservableClass } from '../class/index.mjs';
|
|
3
|
+
import {
|
|
4
|
+
type DropInitialValueOperator,
|
|
5
|
+
type MergeMapOperatorObservable,
|
|
6
|
+
type Observable,
|
|
7
|
+
type Subscription,
|
|
8
|
+
type UpdaterSymbol,
|
|
9
|
+
} from '../types/index.mjs';
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Projects each source value to an observable and merges all inner observables.
|
|
13
|
+
* Unlike `switchMap`, does not cancel previous inner observables.
|
|
14
|
+
*
|
|
15
|
+
* @template A - The type of values from the source
|
|
16
|
+
* @template B - The type of values from the projected observable
|
|
17
|
+
* @param mapToObservable - A function that maps each source value to an observable
|
|
18
|
+
* @returns An operator that merges mapped observables
|
|
19
|
+
*
|
|
20
|
+
* @example
|
|
21
|
+
* ```ts
|
|
22
|
+
* const ids$ = source<number>();
|
|
23
|
+
*
|
|
24
|
+
* const users$ = ids$.pipe(mergeMap((id) => fromPromise(fetchUser(id))));
|
|
25
|
+
*
|
|
26
|
+
* users$.subscribe((user) => {
|
|
27
|
+
* console.log(user);
|
|
28
|
+
* });
|
|
29
|
+
* // All requests run in parallel, results merged as they arrive
|
|
30
|
+
*
|
|
31
|
+
* const fetchUser = async (id: number): Promise<unknown> => ({ id });
|
|
32
|
+
* ```
|
|
33
|
+
*
|
|
34
|
+
* @note To improve code readability, consider using `createState` instead of `mergeMap`,
|
|
35
|
+
* subscribing to `parentObservable` and calling `setState` within it.
|
|
36
|
+
*/
|
|
37
|
+
export const mergeMap =
|
|
38
|
+
<A, B>(
|
|
39
|
+
mapToObservable: (curr: A) => Observable<B>,
|
|
40
|
+
): DropInitialValueOperator<A, B> =>
|
|
41
|
+
(parentObservable) =>
|
|
42
|
+
new MergeMapObservableClass(parentObservable, mapToObservable);
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Alias for `mergeMap()`.
|
|
46
|
+
* @see mergeMap
|
|
47
|
+
*/
|
|
48
|
+
export const flatMap = mergeMap;
|
|
49
|
+
|
|
50
|
+
class MergeMapObservableClass<A, B>
|
|
51
|
+
extends AsyncChildObservableClass<B, readonly [A]>
|
|
52
|
+
implements MergeMapOperatorObservable<A, B>
|
|
53
|
+
{
|
|
54
|
+
readonly #mapToObservable: (curr: A) => Observable<B>;
|
|
55
|
+
#mut_observables: readonly Observable<B>[];
|
|
56
|
+
#mut_subscriptions: readonly Subscription[];
|
|
57
|
+
|
|
58
|
+
constructor(
|
|
59
|
+
parentObservable: Observable<A>,
|
|
60
|
+
mapToObservable: (curr: A) => Observable<B>,
|
|
61
|
+
) {
|
|
62
|
+
super({
|
|
63
|
+
parents: [parentObservable],
|
|
64
|
+
initialValue: Optional.none,
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
this.#mapToObservable = mapToObservable;
|
|
68
|
+
|
|
69
|
+
this.#mut_observables = [];
|
|
70
|
+
|
|
71
|
+
this.#mut_subscriptions = [];
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
override tryUpdate(updaterSymbol: UpdaterSymbol): void {
|
|
75
|
+
const par = this.parents[0];
|
|
76
|
+
|
|
77
|
+
const sn = par.getSnapshot();
|
|
78
|
+
|
|
79
|
+
if (par.updaterSymbol !== updaterSymbol || Optional.isNone(sn)) {
|
|
80
|
+
return; // skip update
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
const observable = this.#mapToObservable(sn.value);
|
|
84
|
+
|
|
85
|
+
this.#mut_observables = Arr.toPushed(this.#mut_observables, observable);
|
|
86
|
+
|
|
87
|
+
const subscription = observable.subscribe((curr) => {
|
|
88
|
+
this.startUpdate(curr);
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
this.#mut_subscriptions = Arr.toPushed(
|
|
92
|
+
this.#mut_subscriptions,
|
|
93
|
+
subscription,
|
|
94
|
+
);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
override complete(): void {
|
|
98
|
+
for (const s of this.#mut_subscriptions) {
|
|
99
|
+
s.unsubscribe();
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
for (const o of this.#mut_observables) {
|
|
103
|
+
o.complete();
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
super.complete();
|
|
107
|
+
}
|
|
108
|
+
}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { Optional } from 'ts-data-forge';
|
|
2
|
+
import { SyncChildObservableClass } from '../class/index.mjs';
|
|
3
|
+
import {
|
|
4
|
+
type DropInitialValueOperator,
|
|
5
|
+
type Observable,
|
|
6
|
+
type PairwiseOperatorObservable,
|
|
7
|
+
type UpdaterSymbol,
|
|
8
|
+
} from '../types/index.mjs';
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Emits the previous and current values as a pair.
|
|
12
|
+
* Does not emit until the source has emitted at least twice.
|
|
13
|
+
*
|
|
14
|
+
* @template A - The type of values from the source
|
|
15
|
+
* @returns An operator that pairs consecutive values
|
|
16
|
+
*
|
|
17
|
+
* @example
|
|
18
|
+
* ```ts
|
|
19
|
+
* const num$ = source<number>();
|
|
20
|
+
*
|
|
21
|
+
* const pairs$ = num$.pipe(pairwise());
|
|
22
|
+
*
|
|
23
|
+
* pairs$.subscribe(([prev, curr]) => {
|
|
24
|
+
* console.log(prev, curr);
|
|
25
|
+
* });
|
|
26
|
+
*
|
|
27
|
+
* num$.next(1); // nothing logged
|
|
28
|
+
*
|
|
29
|
+
* num$.next(2); // logs: 1, 2
|
|
30
|
+
*
|
|
31
|
+
* num$.next(3); // logs: 2, 3
|
|
32
|
+
* ```
|
|
33
|
+
*/
|
|
34
|
+
export const pairwise = <A,>(): DropInitialValueOperator<A, readonly [A, A]> =>
|
|
35
|
+
f;
|
|
36
|
+
|
|
37
|
+
const f = <A,>(parentObservable: Observable<A>): Observable<readonly [A, A]> =>
|
|
38
|
+
new PairwiseObservableClass(parentObservable);
|
|
39
|
+
|
|
40
|
+
class PairwiseObservableClass<A>
|
|
41
|
+
extends SyncChildObservableClass<readonly [A, A], readonly [A]>
|
|
42
|
+
implements PairwiseOperatorObservable<A>
|
|
43
|
+
{
|
|
44
|
+
#mut_previousValue: Optional<A>;
|
|
45
|
+
|
|
46
|
+
constructor(parentObservable: Observable<A>) {
|
|
47
|
+
super({
|
|
48
|
+
parents: [parentObservable],
|
|
49
|
+
initialValue: Optional.none,
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
// parentObservable.snapshot has value
|
|
53
|
+
// if parentObservable is InitializedObservable
|
|
54
|
+
this.#mut_previousValue = parentObservable.getSnapshot();
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
override tryUpdate(updaterSymbol: UpdaterSymbol): void {
|
|
58
|
+
const par = this.parents[0];
|
|
59
|
+
|
|
60
|
+
const sn = par.getSnapshot();
|
|
61
|
+
|
|
62
|
+
if (par.updaterSymbol !== updaterSymbol || Optional.isNone(sn)) {
|
|
63
|
+
return; // skip update
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
const prev = this.#mut_previousValue;
|
|
67
|
+
|
|
68
|
+
const cond = !Optional.isNone(prev);
|
|
69
|
+
|
|
70
|
+
// NOTE: Must update before setNext, otherwise Optional.isNone(prev) remains true when tryUpdate is called consecutively
|
|
71
|
+
this.#mut_previousValue = par.getSnapshot();
|
|
72
|
+
|
|
73
|
+
if (cond) {
|
|
74
|
+
this.setNext([prev.value, sn.value], updaterSymbol);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { Optional } from 'ts-data-forge';
|
|
2
|
+
import { InitializedSyncChildObservableClass } from '../class/index.mjs';
|
|
3
|
+
import {
|
|
4
|
+
type Observable,
|
|
5
|
+
type ScanOperatorObservable,
|
|
6
|
+
type UpdaterSymbol,
|
|
7
|
+
type WithInitialValueOperator,
|
|
8
|
+
} from '../types/index.mjs';
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Applies an accumulator function over the source observable and emits each intermediate result.
|
|
12
|
+
* Similar to Array.reduce but emits accumulated value after each source emission.
|
|
13
|
+
*
|
|
14
|
+
* @template A - The type of values from the source
|
|
15
|
+
* @template B - The type of the accumulated value
|
|
16
|
+
* @param reducer - The accumulator function
|
|
17
|
+
* @param initialValue - The initial accumulated value (seed)
|
|
18
|
+
* @returns An operator that accumulates values
|
|
19
|
+
*
|
|
20
|
+
* @example
|
|
21
|
+
* ```ts
|
|
22
|
+
* const num$ = source<number>();
|
|
23
|
+
*
|
|
24
|
+
* const sum$ = num$.pipe(scan((acc, curr) => acc + curr, 0));
|
|
25
|
+
*
|
|
26
|
+
* sum$.subscribe((x) => {
|
|
27
|
+
* console.log(x);
|
|
28
|
+
* });
|
|
29
|
+
*
|
|
30
|
+
* num$.next(1); // logs: 1
|
|
31
|
+
*
|
|
32
|
+
* num$.next(2); // logs: 3
|
|
33
|
+
*
|
|
34
|
+
* num$.next(3); // logs: 6
|
|
35
|
+
* ```
|
|
36
|
+
*/
|
|
37
|
+
export const scan =
|
|
38
|
+
<A, B>(
|
|
39
|
+
reducer: (acc: B, curr: A) => B,
|
|
40
|
+
initialValue: B,
|
|
41
|
+
): WithInitialValueOperator<A, B> =>
|
|
42
|
+
(parentObservable) =>
|
|
43
|
+
new ScanObservableClass(parentObservable, reducer, initialValue);
|
|
44
|
+
|
|
45
|
+
class ScanObservableClass<A, B>
|
|
46
|
+
extends InitializedSyncChildObservableClass<B, readonly [A]>
|
|
47
|
+
implements ScanOperatorObservable<A, B>
|
|
48
|
+
{
|
|
49
|
+
readonly #reducer: (acc: B, curr: A) => B;
|
|
50
|
+
|
|
51
|
+
constructor(
|
|
52
|
+
parentObservable: Observable<A>,
|
|
53
|
+
reducer: (acc: B, curr: A) => B,
|
|
54
|
+
initialValue: B,
|
|
55
|
+
) {
|
|
56
|
+
super({
|
|
57
|
+
parents: [parentObservable],
|
|
58
|
+
initialValue: Optional.some(initialValue),
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
this.#reducer = reducer;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
override tryUpdate(updaterSymbol: UpdaterSymbol): void {
|
|
65
|
+
const par = this.parents[0];
|
|
66
|
+
|
|
67
|
+
const psn = par.getSnapshot();
|
|
68
|
+
|
|
69
|
+
const sn = this.getSnapshot();
|
|
70
|
+
|
|
71
|
+
if (
|
|
72
|
+
par.updaterSymbol !== updaterSymbol ||
|
|
73
|
+
Optional.isNone(psn) ||
|
|
74
|
+
Optional.isNone(sn)
|
|
75
|
+
) {
|
|
76
|
+
return; // skip update
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
this.setNext(this.#reducer(sn.value, psn.value), updaterSymbol);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import { Optional } from 'ts-data-forge';
|
|
2
|
+
import { SyncChildObservableClass } from '../class/index.mjs';
|
|
3
|
+
import {
|
|
4
|
+
type KeepInitialValueOperator,
|
|
5
|
+
type Observable,
|
|
6
|
+
type SkipIfNoChangeOperatorObservable,
|
|
7
|
+
type UpdaterSymbol,
|
|
8
|
+
} from '../types/index.mjs';
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Skips emissions if the value hasn't changed from the previous emission.
|
|
12
|
+
* Uses a custom equality function or Object.is by default.
|
|
13
|
+
*
|
|
14
|
+
* @template A - The type of values from the source
|
|
15
|
+
* @param eq - Equality comparison function (default: Object.is)
|
|
16
|
+
* @returns An operator that skips duplicate consecutive values
|
|
17
|
+
*
|
|
18
|
+
* @example
|
|
19
|
+
* ```ts
|
|
20
|
+
* const num$ = source<number>();
|
|
21
|
+
*
|
|
22
|
+
* const distinct$ = num$.pipe(skipIfNoChange());
|
|
23
|
+
*
|
|
24
|
+
* distinct$.subscribe((x) => {
|
|
25
|
+
* console.log(x);
|
|
26
|
+
* });
|
|
27
|
+
*
|
|
28
|
+
* num$.next(1); // logs: 1
|
|
29
|
+
*
|
|
30
|
+
* num$.next(1); // nothing logged
|
|
31
|
+
*
|
|
32
|
+
* num$.next(2); // logs: 2
|
|
33
|
+
* ```
|
|
34
|
+
*/
|
|
35
|
+
export const skipIfNoChange = <A,>(
|
|
36
|
+
eq: (x: A, y: A) => boolean = (x, y) => Object.is(x, y),
|
|
37
|
+
): KeepInitialValueOperator<A, A> =>
|
|
38
|
+
// eslint-disable-next-line total-functions/no-unsafe-type-assertion
|
|
39
|
+
((parentObservable) =>
|
|
40
|
+
new SkipIfNoChangeObservableClass(
|
|
41
|
+
parentObservable,
|
|
42
|
+
eq,
|
|
43
|
+
)) as KeepInitialValueOperator<A, A>;
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Alias for `skipIfNoChange()`.
|
|
47
|
+
* @see skipIfNoChange
|
|
48
|
+
*/
|
|
49
|
+
export const distinctUntilChanged = skipIfNoChange; // alias
|
|
50
|
+
|
|
51
|
+
class SkipIfNoChangeObservableClass<A>
|
|
52
|
+
extends SyncChildObservableClass<A, readonly [A]>
|
|
53
|
+
implements SkipIfNoChangeOperatorObservable<A>
|
|
54
|
+
{
|
|
55
|
+
readonly #eq: (x: A, y: A) => boolean;
|
|
56
|
+
#mut_previousValue: Optional<A>;
|
|
57
|
+
|
|
58
|
+
constructor(parentObservable: Observable<A>, eq: (x: A, y: A) => boolean) {
|
|
59
|
+
super({
|
|
60
|
+
parents: [parentObservable],
|
|
61
|
+
initialValue: parentObservable.getSnapshot(),
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
// parentObservable.snapshot has value
|
|
65
|
+
// if parentObservable is InitializedObservable
|
|
66
|
+
this.#mut_previousValue = parentObservable.getSnapshot();
|
|
67
|
+
|
|
68
|
+
this.#eq = eq;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
override tryUpdate(updaterSymbol: UpdaterSymbol): void {
|
|
72
|
+
const par = this.parents[0];
|
|
73
|
+
|
|
74
|
+
const sn = par.getSnapshot();
|
|
75
|
+
|
|
76
|
+
if (par.updaterSymbol !== updaterSymbol || Optional.isNone(sn)) {
|
|
77
|
+
return; // skip update
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
const prev = this.#mut_previousValue;
|
|
81
|
+
|
|
82
|
+
const cond = Optional.isNone(prev) || !this.#eq(prev.value, sn.value);
|
|
83
|
+
|
|
84
|
+
// NOTE: Must update before setNext, otherwise Optional.isNone(prev) remains true when tryUpdate is called consecutively
|
|
85
|
+
this.#mut_previousValue = sn;
|
|
86
|
+
|
|
87
|
+
if (cond) {
|
|
88
|
+
this.setNext(sn.value, updaterSymbol);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { Optional } from 'ts-data-forge';
|
|
2
|
+
import { SyncChildObservableClass } from '../class/index.mjs';
|
|
3
|
+
import {
|
|
4
|
+
type DropInitialValueOperator,
|
|
5
|
+
type Observable,
|
|
6
|
+
type SkipUntilOperatorObservable,
|
|
7
|
+
type UpdaterSymbol,
|
|
8
|
+
} from '../types/index.mjs';
|
|
9
|
+
|
|
10
|
+
export const skipUntil =
|
|
11
|
+
<A,>(notifier: Observable<unknown>): DropInitialValueOperator<A, A> =>
|
|
12
|
+
(parentObservable) =>
|
|
13
|
+
new SkipUntilObservableClass(parentObservable, notifier);
|
|
14
|
+
|
|
15
|
+
class SkipUntilObservableClass<A>
|
|
16
|
+
extends SyncChildObservableClass<A, readonly [A]>
|
|
17
|
+
implements SkipUntilOperatorObservable<A>
|
|
18
|
+
{
|
|
19
|
+
#mut_isSkipping: boolean;
|
|
20
|
+
|
|
21
|
+
constructor(parentObservable: Observable<A>, notifier: Observable<unknown>) {
|
|
22
|
+
super({
|
|
23
|
+
parents: [parentObservable],
|
|
24
|
+
initialValue: Optional.none,
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
this.#mut_isSkipping = true;
|
|
28
|
+
|
|
29
|
+
notifier.subscribe(
|
|
30
|
+
() => {
|
|
31
|
+
this.#mut_isSkipping = false;
|
|
32
|
+
},
|
|
33
|
+
() => {
|
|
34
|
+
this.#mut_isSkipping = false;
|
|
35
|
+
},
|
|
36
|
+
);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
override tryUpdate(updaterSymbol: UpdaterSymbol): void {
|
|
40
|
+
const par = this.parents[0];
|
|
41
|
+
|
|
42
|
+
const sn = par.getSnapshot();
|
|
43
|
+
|
|
44
|
+
if (
|
|
45
|
+
par.updaterSymbol !== updaterSymbol ||
|
|
46
|
+
Optional.isNone(sn) ||
|
|
47
|
+
this.#mut_isSkipping
|
|
48
|
+
) {
|
|
49
|
+
return; // skip update
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
this.setNext(sn.value, updaterSymbol);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import {
|
|
2
|
+
Optional,
|
|
3
|
+
PositiveSafeInt,
|
|
4
|
+
SafeUint,
|
|
5
|
+
asSafeUint,
|
|
6
|
+
pipe,
|
|
7
|
+
} from 'ts-data-forge';
|
|
8
|
+
import { SyncChildObservableClass } from '../class/index.mjs';
|
|
9
|
+
import {
|
|
10
|
+
type DropInitialValueOperator,
|
|
11
|
+
type Observable,
|
|
12
|
+
type SkipWhileOperatorObservable,
|
|
13
|
+
type UpdaterSymbol,
|
|
14
|
+
} from '../types/index.mjs';
|
|
15
|
+
|
|
16
|
+
export const skipWhile =
|
|
17
|
+
<A,>(
|
|
18
|
+
predicate: (value: A, index: SafeUint | -1) => boolean,
|
|
19
|
+
): DropInitialValueOperator<A, A> =>
|
|
20
|
+
(parentObservable) =>
|
|
21
|
+
new SkipWhileObservableClass(parentObservable, predicate);
|
|
22
|
+
|
|
23
|
+
/* Specialized operators */
|
|
24
|
+
|
|
25
|
+
export const skip = <A,>(
|
|
26
|
+
n: PositiveSafeIntWithSmallInt,
|
|
27
|
+
): DropInitialValueOperator<A, A> =>
|
|
28
|
+
!PositiveSafeInt.is(n) ? idFn : skipWhile((_, index) => index + 1 <= n);
|
|
29
|
+
|
|
30
|
+
const idFn = <T,>(value: T): T => value;
|
|
31
|
+
|
|
32
|
+
/* implementation */
|
|
33
|
+
|
|
34
|
+
class SkipWhileObservableClass<A>
|
|
35
|
+
extends SyncChildObservableClass<A, readonly [A]>
|
|
36
|
+
implements SkipWhileOperatorObservable<A>
|
|
37
|
+
{
|
|
38
|
+
readonly #predicate: (value: A, index: SafeUint | -1) => boolean;
|
|
39
|
+
#mut_index: SafeUint | -1;
|
|
40
|
+
|
|
41
|
+
constructor(
|
|
42
|
+
parentObservable: Observable<A>,
|
|
43
|
+
predicate: (value: A, index: SafeUint | -1) => boolean,
|
|
44
|
+
) {
|
|
45
|
+
super({
|
|
46
|
+
parents: [parentObservable],
|
|
47
|
+
initialValue: pipe(parentObservable.getSnapshot()).map((sn) =>
|
|
48
|
+
Optional.isNone(sn)
|
|
49
|
+
? Optional.none
|
|
50
|
+
: predicate(sn.value, -1)
|
|
51
|
+
? Optional.none
|
|
52
|
+
: sn,
|
|
53
|
+
).value,
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
this.#mut_index = -1;
|
|
57
|
+
|
|
58
|
+
this.#predicate = predicate;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
override tryUpdate(updaterSymbol: UpdaterSymbol): void {
|
|
62
|
+
const par = this.parents[0];
|
|
63
|
+
|
|
64
|
+
const sn = par.getSnapshot();
|
|
65
|
+
|
|
66
|
+
if (par.updaterSymbol !== updaterSymbol || Optional.isNone(sn)) {
|
|
67
|
+
return; // skip update
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
this.#mut_index =
|
|
71
|
+
this.#mut_index === -1 ? asSafeUint(0) : SafeUint.add(1, this.#mut_index);
|
|
72
|
+
|
|
73
|
+
if (!this.#predicate(sn.value, this.#mut_index)) {
|
|
74
|
+
this.setNext(sn.value, updaterSymbol);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
}
|