synstate 2.0.1 → 3.0.0

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