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,61 @@
|
|
|
1
|
+
import { type InitializedObservable } from '../core/index.mjs';
|
|
2
|
+
/**
|
|
3
|
+
* Creates a reactive state container with getter and setter methods.
|
|
4
|
+
* Provides a simple state management solution with observable state.
|
|
5
|
+
*
|
|
6
|
+
* @template S - The type of the state
|
|
7
|
+
* @param initialState - The initial value of the state
|
|
8
|
+
* @returns An object containing the state observable and methods to manipulate it
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* ```ts
|
|
12
|
+
* const [state, setState, { updateState, resetState }] = createState(0);
|
|
13
|
+
*
|
|
14
|
+
* state.subscribe((value: number) => {
|
|
15
|
+
* console.log(value);
|
|
16
|
+
* }); // logs: 0
|
|
17
|
+
*
|
|
18
|
+
* setState(10); // logs: 10
|
|
19
|
+
*
|
|
20
|
+
* updateState((prev: number) => prev + 1); // logs: 11
|
|
21
|
+
*
|
|
22
|
+
* resetState(); // logs: 0
|
|
23
|
+
* ```
|
|
24
|
+
*/
|
|
25
|
+
export declare const createState: <S>(initialState: S) => readonly [state: InitializedObservable<S>, setState: (v: S) => S, Readonly<{
|
|
26
|
+
updateState: (updateFn: (prev: S) => S) => S;
|
|
27
|
+
resetState: () => S;
|
|
28
|
+
getSnapshot: () => S;
|
|
29
|
+
}>];
|
|
30
|
+
/**
|
|
31
|
+
* Creates a reactive boolean state with convenient methods for boolean operations.
|
|
32
|
+
* Extends `createState` with boolean-specific helpers like `toggle`, `setTrue`, and `setFalse`.
|
|
33
|
+
*
|
|
34
|
+
* @param initialState - The initial boolean value
|
|
35
|
+
* @returns An object with the state observable and boolean-specific methods
|
|
36
|
+
*
|
|
37
|
+
* @example
|
|
38
|
+
* ```ts
|
|
39
|
+
* const [state, { setTrue, toggle }] = createBooleanState(false);
|
|
40
|
+
*
|
|
41
|
+
* state.subscribe((value: boolean) => {
|
|
42
|
+
* console.log(value);
|
|
43
|
+
* }); // logs: false
|
|
44
|
+
*
|
|
45
|
+
* setTrue(); // logs: true
|
|
46
|
+
*
|
|
47
|
+
* toggle(); // logs: false
|
|
48
|
+
*
|
|
49
|
+
* toggle(); // logs: true
|
|
50
|
+
* ```
|
|
51
|
+
*/
|
|
52
|
+
export declare const createBooleanState: (initialState: boolean) => readonly [state: InitializedObservable<boolean>, Readonly<{
|
|
53
|
+
setTrue: () => void;
|
|
54
|
+
setFalse: () => void;
|
|
55
|
+
setState: (next: boolean) => boolean;
|
|
56
|
+
toggle: () => boolean;
|
|
57
|
+
updateState: (updateFn: (prev: boolean) => boolean) => boolean;
|
|
58
|
+
resetState: () => boolean;
|
|
59
|
+
getSnapshot: () => boolean;
|
|
60
|
+
}>];
|
|
61
|
+
//# sourceMappingURL=create-state.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"create-state.d.mts","sourceRoot":"","sources":["../../src/utils/create-state.mts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,qBAAqB,EAAE,MAAM,mBAAmB,CAAC;AAwB/D;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,eAAO,MAAM,WAAW,GAAI,CAAC,EAC3B,cAAc,CAAC,KACd,SAAS,CACV,KAAK,EAAE,qBAAqB,CAAC,CAAC,CAAC,EAC/B,QAAQ,EAAE,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,EACrB,QAAQ,CAAC;IACP,WAAW,EAAE,CAAC,QAAQ,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IAC7C,UAAU,EAAE,MAAM,CAAC,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC,CAAC;CACtB,CAAC,CAwBH,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,eAAO,MAAM,kBAAkB,GAC7B,cAAc,OAAO,KACpB,SAAS,CACV,KAAK,EAAE,qBAAqB,CAAC,OAAO,CAAC,EACrC,QAAQ,CAAC;IACP,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,QAAQ,EAAE,MAAM,IAAI,CAAC;IACrB,QAAQ,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,OAAO,CAAC;IACrC,MAAM,EAAE,MAAM,OAAO,CAAC;IACtB,WAAW,EAAE,CAAC,QAAQ,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,OAAO,KAAK,OAAO,CAAC;IAC/D,UAAU,EAAE,MAAM,OAAO,CAAC;IAC1B,WAAW,EAAE,MAAM,OAAO,CAAC;CAC5B,CAAC,CAqBH,CAAC"}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import { createReducer } from './create-reducer.mjs';
|
|
2
|
+
|
|
3
|
+
const reducer = (state, action) => {
|
|
4
|
+
switch (action.type) {
|
|
5
|
+
case 'set':
|
|
6
|
+
return action.nextState;
|
|
7
|
+
case 'update':
|
|
8
|
+
return action.updateFn(state);
|
|
9
|
+
}
|
|
10
|
+
};
|
|
11
|
+
/**
|
|
12
|
+
* Creates a reactive state container with getter and setter methods.
|
|
13
|
+
* Provides a simple state management solution with observable state.
|
|
14
|
+
*
|
|
15
|
+
* @template S - The type of the state
|
|
16
|
+
* @param initialState - The initial value of the state
|
|
17
|
+
* @returns An object containing the state observable and methods to manipulate it
|
|
18
|
+
*
|
|
19
|
+
* @example
|
|
20
|
+
* ```ts
|
|
21
|
+
* const [state, setState, { updateState, resetState }] = createState(0);
|
|
22
|
+
*
|
|
23
|
+
* state.subscribe((value: number) => {
|
|
24
|
+
* console.log(value);
|
|
25
|
+
* }); // logs: 0
|
|
26
|
+
*
|
|
27
|
+
* setState(10); // logs: 10
|
|
28
|
+
*
|
|
29
|
+
* updateState((prev: number) => prev + 1); // logs: 11
|
|
30
|
+
*
|
|
31
|
+
* resetState(); // logs: 0
|
|
32
|
+
* ```
|
|
33
|
+
*/
|
|
34
|
+
const createState = (initialState) => {
|
|
35
|
+
const [state, dispatch, getSnapshot] = createReducer(reducer, initialState);
|
|
36
|
+
const updateState = (updateFn) => dispatch({ type: 'update', updateFn });
|
|
37
|
+
const setState = (nextState) => dispatch({ type: 'set', nextState });
|
|
38
|
+
const resetState = () => dispatch({ type: 'set', nextState: initialState });
|
|
39
|
+
return [
|
|
40
|
+
state,
|
|
41
|
+
setState,
|
|
42
|
+
{
|
|
43
|
+
updateState,
|
|
44
|
+
resetState,
|
|
45
|
+
getSnapshot,
|
|
46
|
+
},
|
|
47
|
+
];
|
|
48
|
+
};
|
|
49
|
+
/**
|
|
50
|
+
* Creates a reactive boolean state with convenient methods for boolean operations.
|
|
51
|
+
* Extends `createState` with boolean-specific helpers like `toggle`, `setTrue`, and `setFalse`.
|
|
52
|
+
*
|
|
53
|
+
* @param initialState - The initial boolean value
|
|
54
|
+
* @returns An object with the state observable and boolean-specific methods
|
|
55
|
+
*
|
|
56
|
+
* @example
|
|
57
|
+
* ```ts
|
|
58
|
+
* const [state, { setTrue, toggle }] = createBooleanState(false);
|
|
59
|
+
*
|
|
60
|
+
* state.subscribe((value: boolean) => {
|
|
61
|
+
* console.log(value);
|
|
62
|
+
* }); // logs: false
|
|
63
|
+
*
|
|
64
|
+
* setTrue(); // logs: true
|
|
65
|
+
*
|
|
66
|
+
* toggle(); // logs: false
|
|
67
|
+
*
|
|
68
|
+
* toggle(); // logs: true
|
|
69
|
+
* ```
|
|
70
|
+
*/
|
|
71
|
+
const createBooleanState = (initialState) => {
|
|
72
|
+
const [state, setState, { updateState, resetState, getSnapshot }] = createState(initialState);
|
|
73
|
+
return [
|
|
74
|
+
state,
|
|
75
|
+
{
|
|
76
|
+
setTrue: () => {
|
|
77
|
+
setState(true);
|
|
78
|
+
},
|
|
79
|
+
setFalse: () => {
|
|
80
|
+
setState(false);
|
|
81
|
+
},
|
|
82
|
+
toggle: () => updateState((s) => !s),
|
|
83
|
+
setState,
|
|
84
|
+
updateState,
|
|
85
|
+
resetState,
|
|
86
|
+
getSnapshot,
|
|
87
|
+
},
|
|
88
|
+
];
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
export { createBooleanState, createState };
|
|
92
|
+
//# sourceMappingURL=create-state.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"create-state.mjs","sources":["../../src/utils/create-state.mts"],"sourcesContent":[null],"names":[],"mappings":";;AAcA,MAAM,OAAO,GAAG,CAAK,KAAQ,EAAE,MAAiB,KAAO;AACrD,IAAA,QAAQ,MAAM,CAAC,IAAI;AACjB,QAAA,KAAK,KAAK;YACR,OAAO,MAAM,CAAC,SAAS;AAEzB,QAAA,KAAK,QAAQ;AACX,YAAA,OAAO,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC;;AAEnC,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;AAsBG;AACI,MAAM,WAAW,GAAG,CACzB,YAAe,KASb;AACF,IAAA,MAAM,CAAC,KAAK,EAAE,QAAQ,EAAE,WAAW,CAAC,GAAG,aAAa,CAClD,OAAO,EACP,YAAY,CACb;AAED,IAAA,MAAM,WAAW,GAAG,CAAC,QAAwB,KAC3C,QAAQ,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,CAAC;AAExC,IAAA,MAAM,QAAQ,GAAG,CAAC,SAAY,KAAQ,QAAQ,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC;AAE1E,IAAA,MAAM,UAAU,GAAG,MACjB,QAAQ,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,SAAS,EAAE,YAAY,EAAE,CAAC;IAEpD,OAAO;QACL,KAAK;QACL,QAAQ;AACR,QAAA;YACE,WAAW;YACX,UAAU;YACV,WAAW;AACZ,SAAA;KACO;AACZ;AAEA;;;;;;;;;;;;;;;;;;;;;AAqBG;AACI,MAAM,kBAAkB,GAAG,CAChC,YAAqB,KAYnB;AACF,IAAA,MAAM,CAAC,KAAK,EAAE,QAAQ,EAAE,EAAE,WAAW,EAAE,UAAU,EAAE,WAAW,EAAE,CAAC,GAC/D,WAAW,CAAC,YAAY,CAAC;IAE3B,OAAO;QACL,KAAK;AACL,QAAA;YACE,OAAO,EAAE,MAAK;gBACZ,QAAQ,CAAC,IAAI,CAAC;YAChB,CAAC;YACD,QAAQ,EAAE,MAAK;gBACb,QAAQ,CAAC,KAAK,CAAC;YACjB,CAAC;AACD,YAAA,MAAM,EAAE,MAAM,WAAW,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC;YACpC,QAAQ;YACR,WAAW;YACX,UAAU;YACV,WAAW;AACZ,SAAA;KACO;AACZ;;;;"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.mts","sourceRoot":"","sources":["../../src/utils/index.mts"],"names":[],"mappings":"AAAA,cAAc,4BAA4B,CAAC;AAC3C,cAAc,sBAAsB,CAAC;AACrC,cAAc,oBAAoB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.mjs","sources":[],"sourcesContent":[],"names":[],"mappings":";;"}
|
package/package.json
ADDED
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "synstate",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Reactive Programming Library for TypeScript/JavaScript",
|
|
5
|
+
"repository": {
|
|
6
|
+
"type": "git",
|
|
7
|
+
"url": "git+https://github.com/noshiro-pf/synstate.git"
|
|
8
|
+
},
|
|
9
|
+
"license": "Apache-2.0",
|
|
10
|
+
"author": "noshiro-pf <noshiro.pf@gmail.com>",
|
|
11
|
+
"sideEffects": false,
|
|
12
|
+
"type": "module",
|
|
13
|
+
"exports": {
|
|
14
|
+
".": {
|
|
15
|
+
"import": {
|
|
16
|
+
"types": "./dist/index.d.mts",
|
|
17
|
+
"default": "./dist/index.mjs"
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
},
|
|
21
|
+
"module": "./dist/index.js",
|
|
22
|
+
"types": "./dist/index.d.ts",
|
|
23
|
+
"files": [
|
|
24
|
+
"src",
|
|
25
|
+
"dist",
|
|
26
|
+
"README.md",
|
|
27
|
+
"LICENSE"
|
|
28
|
+
],
|
|
29
|
+
"scripts": {
|
|
30
|
+
"build": "tsx ./scripts/cmd/build.mts",
|
|
31
|
+
"build:min": "tsx ./scripts/cmd/build.mts --skip-check",
|
|
32
|
+
"check:ext": "tsx ./scripts/cmd/check-ext.mts",
|
|
33
|
+
"check-all": "tsx ./scripts/cmd/check-all.mts",
|
|
34
|
+
"codemod": "convert-to-readonly '{src,samples,test}/**/*.{mts,tsx}'",
|
|
35
|
+
"doc": "tsx ./scripts/cmd/gen-docs.mts",
|
|
36
|
+
"doc:embed": "tsx ./scripts/cmd/embed-examples.mts",
|
|
37
|
+
"doc:embed:jsdoc": "tsx ./scripts/cmd/embed-examples-in-jsdoc.mts",
|
|
38
|
+
"doc:preview": "vite preview --config ./configs/vite.doc.config.ts",
|
|
39
|
+
"doc:watch": "typedoc --options ./configs/typedoc.config.mjs --watch",
|
|
40
|
+
"fmt": "pnpm run z:prettier .",
|
|
41
|
+
"gi": "run-s gi:src fmt",
|
|
42
|
+
"gi:src": "gen-index-ts ./src --index-ext .mts --export-ext .mjs --target-ext .mts --target-ext .tsx --exclude entry-point.mts",
|
|
43
|
+
"lint": "eslint .",
|
|
44
|
+
"lint:fix": "eslint . --fix",
|
|
45
|
+
"test": "pnpm run z:vitest:node run",
|
|
46
|
+
"test:all": "run-p test test:stream",
|
|
47
|
+
"test:browser": "pnpm run z:vitest --project='Browser' run",
|
|
48
|
+
"test:cov": "pnpm run z:vitest:node run --coverage",
|
|
49
|
+
"test:cov:ui": "vite preview --outDir ./coverage",
|
|
50
|
+
"test:stream": "pnpm run z:vitest:stream run",
|
|
51
|
+
"test:ui": "pnpm run z:vitest:node --ui",
|
|
52
|
+
"testw": "pnpm run z:vitest:node watch",
|
|
53
|
+
"tsc": "tsc --noEmit",
|
|
54
|
+
"tscw": "tsc --noEmit --watch",
|
|
55
|
+
"type-check": "tsc --noEmit",
|
|
56
|
+
"update-packages": "pnpm update --latest",
|
|
57
|
+
"z:prettier": "prettier --config ../../.prettierrc --ignore-path ../../.prettierignore --ignore-path ../../.gitignore --ignore-unknown --no-error-on-unmatched-pattern --write",
|
|
58
|
+
"z:vitest": "vitest --config ./configs/vitest.config.mts",
|
|
59
|
+
"z:vitest:node": "pnpm run z:vitest --project='Node.js'",
|
|
60
|
+
"z:vitest:stream": "vitest --config ./configs/vitest.config.stream.ts"
|
|
61
|
+
},
|
|
62
|
+
"dependencies": {
|
|
63
|
+
"ts-data-forge": "^6.5.0"
|
|
64
|
+
},
|
|
65
|
+
"devDependencies": {
|
|
66
|
+
"@types/argparse": "^2.0.17",
|
|
67
|
+
"@types/react": "^19.2.14",
|
|
68
|
+
"argparse": "^2.0.1",
|
|
69
|
+
"react": "^19.2.4"
|
|
70
|
+
}
|
|
71
|
+
}
|
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
import { Arr } from 'ts-data-forge';
|
|
2
|
+
import {
|
|
3
|
+
isManagerObservable,
|
|
4
|
+
type AsyncChildObservable,
|
|
5
|
+
type ChildObservable,
|
|
6
|
+
type InitializedObservable,
|
|
7
|
+
type InitializedSyncChildObservable,
|
|
8
|
+
type KeepInitialValueOperator,
|
|
9
|
+
type NonEmptyUnknownList,
|
|
10
|
+
type Observable,
|
|
11
|
+
type ObservableId,
|
|
12
|
+
type Operator,
|
|
13
|
+
type SyncChildObservable,
|
|
14
|
+
type WithInitialValueOperator,
|
|
15
|
+
type Wrap,
|
|
16
|
+
} from '../types/index.mjs';
|
|
17
|
+
import { binarySearch, issueUpdaterSymbol, maxDepth } from '../utils/index.mjs';
|
|
18
|
+
import { ObservableBaseClass } from './observable-base-class.mjs';
|
|
19
|
+
|
|
20
|
+
const registerChild = <A,>(
|
|
21
|
+
child: ChildObservable<A>,
|
|
22
|
+
parents: ChildObservable<A>['parents'],
|
|
23
|
+
): void => {
|
|
24
|
+
for (const p of parents) {
|
|
25
|
+
p.addChild(child);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
// register child to all reachable ManagerObservables
|
|
29
|
+
const mut_rest = Array.from(parents);
|
|
30
|
+
|
|
31
|
+
while (Arr.isNonEmpty(mut_rest)) {
|
|
32
|
+
const p = mut_rest.pop();
|
|
33
|
+
|
|
34
|
+
if (p === undefined) break;
|
|
35
|
+
|
|
36
|
+
if (isManagerObservable(p)) {
|
|
37
|
+
p.addDescendant(child);
|
|
38
|
+
} else {
|
|
39
|
+
// trace back dependency graph
|
|
40
|
+
mut_rest.push(...p.parents);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
const tryComplete = <A,>({
|
|
46
|
+
hasSubscriber,
|
|
47
|
+
hasActiveChild,
|
|
48
|
+
parents,
|
|
49
|
+
complete,
|
|
50
|
+
}: Readonly<{
|
|
51
|
+
hasSubscriber: boolean;
|
|
52
|
+
hasActiveChild: boolean;
|
|
53
|
+
parents: ChildObservable<A>['parents'];
|
|
54
|
+
complete: () => void;
|
|
55
|
+
}>): void => {
|
|
56
|
+
// If there is no working parent node
|
|
57
|
+
if (parents.every((r) => r.isCompleted)) {
|
|
58
|
+
complete();
|
|
59
|
+
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// If there are no active child node
|
|
64
|
+
if (!hasSubscriber && !hasActiveChild) {
|
|
65
|
+
complete();
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// propagate to parents
|
|
69
|
+
for (const par of parents) {
|
|
70
|
+
par.tryComplete();
|
|
71
|
+
}
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
export class AsyncChildObservableClass<A, const P extends NonEmptyUnknownList>
|
|
75
|
+
extends ObservableBaseClass<A, 'async child', number>
|
|
76
|
+
implements AsyncChildObservable<A, P>
|
|
77
|
+
{
|
|
78
|
+
readonly parents;
|
|
79
|
+
#mut_procedure: readonly ChildObservable<unknown>[];
|
|
80
|
+
protected readonly descendantsIdSet: MutableSet<ObservableId>;
|
|
81
|
+
|
|
82
|
+
constructor({
|
|
83
|
+
parents,
|
|
84
|
+
depth = 1 + maxDepth(parents),
|
|
85
|
+
initialValue,
|
|
86
|
+
}: Readonly<{
|
|
87
|
+
parents: Wrap<P>;
|
|
88
|
+
depth?: number;
|
|
89
|
+
initialValue: ReturnType<AsyncChildObservable<A>['getSnapshot']>;
|
|
90
|
+
}>) {
|
|
91
|
+
super({
|
|
92
|
+
kind: 'async child',
|
|
93
|
+
depth,
|
|
94
|
+
initialValue,
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
this.parents = parents;
|
|
98
|
+
|
|
99
|
+
this.#mut_procedure = [];
|
|
100
|
+
|
|
101
|
+
this.descendantsIdSet = new Set<ObservableId>();
|
|
102
|
+
|
|
103
|
+
registerChild(this, parents);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
// overload
|
|
107
|
+
addDescendant<B>(child: ChildObservable<B>): void {
|
|
108
|
+
if (this.descendantsIdSet.has(child.id)) return;
|
|
109
|
+
|
|
110
|
+
this.descendantsIdSet.add(child.id);
|
|
111
|
+
|
|
112
|
+
const insertPos = binarySearch(
|
|
113
|
+
this.#mut_procedure.map((a) => a.depth),
|
|
114
|
+
child.depth,
|
|
115
|
+
);
|
|
116
|
+
|
|
117
|
+
this.#mut_procedure = Arr.toInserted(this.#mut_procedure, insertPos, child);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
startUpdate(nextValue: A): void {
|
|
121
|
+
const updaterSymbol = issueUpdaterSymbol();
|
|
122
|
+
|
|
123
|
+
this.setNext(nextValue, updaterSymbol);
|
|
124
|
+
|
|
125
|
+
for (const p of this.#mut_procedure) {
|
|
126
|
+
p.tryUpdate(updaterSymbol);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
override complete(): void {
|
|
131
|
+
super.complete();
|
|
132
|
+
|
|
133
|
+
// propagate to parents
|
|
134
|
+
for (const par of this.parents) {
|
|
135
|
+
par.tryComplete();
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
override tryComplete(): void {
|
|
140
|
+
tryComplete({
|
|
141
|
+
complete: () => {
|
|
142
|
+
this.complete();
|
|
143
|
+
},
|
|
144
|
+
hasActiveChild: this.hasActiveChild(),
|
|
145
|
+
hasSubscriber: this.hasSubscriber,
|
|
146
|
+
parents: this.parents,
|
|
147
|
+
});
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
export class SyncChildObservableClass<A, const P extends NonEmptyUnknownList>
|
|
152
|
+
extends ObservableBaseClass<A, 'sync child', number>
|
|
153
|
+
implements SyncChildObservable<A, P>
|
|
154
|
+
{
|
|
155
|
+
readonly parents;
|
|
156
|
+
|
|
157
|
+
constructor({
|
|
158
|
+
parents,
|
|
159
|
+
depth = 1 + maxDepth(parents),
|
|
160
|
+
initialValue,
|
|
161
|
+
}: Readonly<{
|
|
162
|
+
parents: Wrap<P>;
|
|
163
|
+
depth?: number;
|
|
164
|
+
initialValue: ReturnType<SyncChildObservable<A>['getSnapshot']>;
|
|
165
|
+
}>) {
|
|
166
|
+
super({
|
|
167
|
+
kind: 'sync child',
|
|
168
|
+
depth,
|
|
169
|
+
initialValue,
|
|
170
|
+
});
|
|
171
|
+
|
|
172
|
+
this.parents = parents;
|
|
173
|
+
|
|
174
|
+
registerChild(this, parents);
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
override complete(): void {
|
|
178
|
+
super.complete();
|
|
179
|
+
|
|
180
|
+
for (const par of this.parents) {
|
|
181
|
+
par.tryComplete();
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
override tryComplete(): void {
|
|
186
|
+
tryComplete({
|
|
187
|
+
complete: () => {
|
|
188
|
+
this.complete();
|
|
189
|
+
},
|
|
190
|
+
hasActiveChild: this.hasActiveChild(),
|
|
191
|
+
hasSubscriber: this.hasSubscriber,
|
|
192
|
+
parents: this.parents,
|
|
193
|
+
});
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
export class InitializedSyncChildObservableClass<
|
|
198
|
+
A,
|
|
199
|
+
const P extends NonEmptyUnknownList,
|
|
200
|
+
>
|
|
201
|
+
extends SyncChildObservableClass<A, P>
|
|
202
|
+
implements InitializedSyncChildObservable<A, P>
|
|
203
|
+
{
|
|
204
|
+
constructor({
|
|
205
|
+
parents,
|
|
206
|
+
depth = 1 + maxDepth(parents),
|
|
207
|
+
initialValue,
|
|
208
|
+
}: Readonly<{
|
|
209
|
+
parents: Wrap<P>;
|
|
210
|
+
depth?: number;
|
|
211
|
+
initialValue: ReturnType<InitializedSyncChildObservable<A>['getSnapshot']>;
|
|
212
|
+
}>) {
|
|
213
|
+
super({ parents, depth, initialValue });
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
override getSnapshot(): Some<A> {
|
|
217
|
+
// eslint-disable-next-line total-functions/no-unsafe-type-assertion
|
|
218
|
+
return super.getCurrentValue() as Some<A>;
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
override pipe<B>(
|
|
222
|
+
operator: KeepInitialValueOperator<A, B> | WithInitialValueOperator<A, B>,
|
|
223
|
+
): InitializedObservable<B>;
|
|
224
|
+
|
|
225
|
+
override pipe<B>(operator: Operator<A, B>): Observable<B>;
|
|
226
|
+
override pipe<B>(operator: Operator<A, B>): Observable<B> {
|
|
227
|
+
return operator(
|
|
228
|
+
// eslint-disable-next-line total-functions/no-unsafe-type-assertion
|
|
229
|
+
this as unknown as InitializedObservable<A>,
|
|
230
|
+
);
|
|
231
|
+
}
|
|
232
|
+
}
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
import { Arr, Optional } from 'ts-data-forge';
|
|
2
|
+
import {
|
|
3
|
+
type ChildObservable,
|
|
4
|
+
type InitializedObservable,
|
|
5
|
+
type Observable,
|
|
6
|
+
type ObservableBase,
|
|
7
|
+
type Operator,
|
|
8
|
+
type Subscriber,
|
|
9
|
+
type SubscriberId,
|
|
10
|
+
type Subscription,
|
|
11
|
+
type UpdaterSymbol,
|
|
12
|
+
type WithInitialValueOperator,
|
|
13
|
+
} from '../types/index.mjs';
|
|
14
|
+
import {
|
|
15
|
+
issueObservableId,
|
|
16
|
+
issueSubscriberId,
|
|
17
|
+
issueUpdaterSymbol,
|
|
18
|
+
toSubscriber,
|
|
19
|
+
} from '../utils/index.mjs';
|
|
20
|
+
|
|
21
|
+
export class ObservableBaseClass<
|
|
22
|
+
A,
|
|
23
|
+
Kind extends ObservableBase<A>['kind'],
|
|
24
|
+
Depth extends ObservableBase<A>['depth'],
|
|
25
|
+
> implements ObservableBase<A> {
|
|
26
|
+
readonly id;
|
|
27
|
+
readonly kind: Kind;
|
|
28
|
+
readonly depth: Depth;
|
|
29
|
+
#mut_children: readonly ChildObservable<unknown>[];
|
|
30
|
+
readonly #subscribers: MutableMap<SubscriberId, Subscriber<A>>;
|
|
31
|
+
#mut_currentValue: ReturnType<ObservableBase<A>['getSnapshot']>;
|
|
32
|
+
#mut_isCompleted: ObservableBase<A>['isCompleted'];
|
|
33
|
+
#mut_updaterSymbol: ObservableBase<A>['updaterSymbol'];
|
|
34
|
+
|
|
35
|
+
constructor({
|
|
36
|
+
kind,
|
|
37
|
+
depth,
|
|
38
|
+
initialValue,
|
|
39
|
+
}: Readonly<{
|
|
40
|
+
kind: Kind;
|
|
41
|
+
depth: Depth;
|
|
42
|
+
initialValue: ReturnType<ObservableBase<A>['getSnapshot']>;
|
|
43
|
+
}>) {
|
|
44
|
+
this.kind = kind;
|
|
45
|
+
|
|
46
|
+
this.depth = depth;
|
|
47
|
+
|
|
48
|
+
this.id = issueObservableId();
|
|
49
|
+
|
|
50
|
+
this.#mut_currentValue = initialValue;
|
|
51
|
+
|
|
52
|
+
this.#mut_children = [];
|
|
53
|
+
|
|
54
|
+
this.#subscribers = new Map<SubscriberId, Subscriber<A>>();
|
|
55
|
+
|
|
56
|
+
this.#mut_isCompleted = false;
|
|
57
|
+
|
|
58
|
+
this.#mut_updaterSymbol = issueUpdaterSymbol();
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
addChild<B>(child: ChildObservable<B>): void {
|
|
62
|
+
this.#mut_children = Arr.toPushed(
|
|
63
|
+
this.#mut_children,
|
|
64
|
+
|
|
65
|
+
child as ChildObservable<unknown>,
|
|
66
|
+
);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
getSnapshot(): ReturnType<ObservableBase<A>['getSnapshot']> {
|
|
70
|
+
return this.#mut_currentValue;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
protected getCurrentValue(): ReturnType<ObservableBase<A>['getSnapshot']> {
|
|
74
|
+
return this.#mut_currentValue;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
get isCompleted(): boolean {
|
|
78
|
+
return this.#mut_isCompleted;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
get updaterSymbol(): UpdaterSymbol {
|
|
82
|
+
return this.#mut_updaterSymbol;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
get hasSubscriber(): boolean {
|
|
86
|
+
return this.#subscribers.size > 0;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
get hasChild(): boolean {
|
|
90
|
+
return Arr.isNonEmpty(this.#mut_children);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
hasActiveChild(): boolean {
|
|
94
|
+
return this.#mut_children.some((c) => !c.isCompleted);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
protected setNext(nextValue: A, updaterSymbol: UpdaterSymbol): void {
|
|
98
|
+
this.#mut_updaterSymbol = updaterSymbol;
|
|
99
|
+
|
|
100
|
+
this.#mut_currentValue = Optional.some(nextValue);
|
|
101
|
+
|
|
102
|
+
for (const s of this.#subscribers.values()) {
|
|
103
|
+
s.onNext(nextValue);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
// eslint-disable-next-line @typescript-eslint/class-methods-use-this
|
|
108
|
+
tryUpdate(_updaterSymbol: UpdaterSymbol): void {
|
|
109
|
+
throw new Error('not implemented');
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
tryComplete(): void {
|
|
113
|
+
if (!this.hasSubscriber && !this.hasActiveChild()) {
|
|
114
|
+
this.complete();
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
complete(): void {
|
|
119
|
+
if (this.isCompleted) return; // terminate only once
|
|
120
|
+
|
|
121
|
+
// change state
|
|
122
|
+
this.#mut_isCompleted = true;
|
|
123
|
+
|
|
124
|
+
// run subscribers for the current value
|
|
125
|
+
for (const s of this.#subscribers.values()) {
|
|
126
|
+
s.onComplete();
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
// remove all subscribers
|
|
130
|
+
this.#subscribers.clear();
|
|
131
|
+
|
|
132
|
+
// propagate to children
|
|
133
|
+
for (const o of this.#mut_children) {
|
|
134
|
+
o.tryComplete();
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
pipe<B>(operator: WithInitialValueOperator<A, B>): InitializedObservable<B>;
|
|
139
|
+
pipe<B>(operator: Operator<A, B>): Observable<B>;
|
|
140
|
+
pipe<B>(operator: Operator<A, B>): Observable<B> {
|
|
141
|
+
return operator(
|
|
142
|
+
// eslint-disable-next-line total-functions/no-unsafe-type-assertion
|
|
143
|
+
this as unknown as InitializedObservable<A>,
|
|
144
|
+
);
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
subscribe(onNext: (v: A) => void, onComplete?: () => void): Subscription {
|
|
148
|
+
// first emit
|
|
149
|
+
const curr = this.getSnapshot();
|
|
150
|
+
|
|
151
|
+
if (Optional.isSome(curr)) {
|
|
152
|
+
onNext(curr.value);
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
if (this.isCompleted) {
|
|
156
|
+
if (onComplete !== undefined) {
|
|
157
|
+
onComplete();
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
return { unsubscribe: () => {} };
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
const id: SubscriberId = this.#addSubscriber(
|
|
164
|
+
toSubscriber(onNext, onComplete),
|
|
165
|
+
);
|
|
166
|
+
|
|
167
|
+
return {
|
|
168
|
+
unsubscribe: () => {
|
|
169
|
+
this.#removeSubscriber(id);
|
|
170
|
+
},
|
|
171
|
+
};
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
#addSubscriber(s: Subscriber<A>): SubscriberId {
|
|
175
|
+
// return the id of added subscriber
|
|
176
|
+
const id = issueSubscriberId();
|
|
177
|
+
|
|
178
|
+
this.#subscribers.set(id, s);
|
|
179
|
+
|
|
180
|
+
return id;
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
#removeSubscriber(id: SubscriberId): void {
|
|
184
|
+
this.#subscribers.delete(id);
|
|
185
|
+
}
|
|
186
|
+
}
|