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
@@ -1,5 +1,5 @@
1
1
  import { Optional } from 'ts-data-forge';
2
- import { RootObservableClass } from '../class/index.mjs';
2
+ import { createRootObservable } from '../base/index.mjs';
3
3
  import { type TimerId, type TimerObservable } from '../types/index.mjs';
4
4
 
5
5
  /**
@@ -43,62 +43,47 @@ export const timer = (
43
43
  options?: Readonly<{
44
44
  startManually?: boolean;
45
45
  }>,
46
- ): TimerObservable =>
47
- new TimerObservableClass(milliSeconds, options?.startManually ?? false);
46
+ ): TimerObservable => {
47
+ let mut_timerId: TimerId | undefined = undefined;
48
48
 
49
- class TimerObservableClass
50
- extends RootObservableClass<0>
51
- implements TimerObservable
52
- {
53
- readonly #milliSeconds: number;
54
- #mut_timerId: TimerId | undefined;
55
- #mut_isStarted: boolean;
49
+ let mut_isStarted = false;
56
50
 
57
- constructor(milliSeconds: number, startManually: boolean) {
58
- super({ initialValue: Optional.none });
59
-
60
- this.#milliSeconds = milliSeconds;
61
-
62
- this.#mut_timerId = undefined;
63
-
64
- this.#mut_isStarted = false;
65
-
66
- if (!startManually) {
67
- this.start();
51
+ const resetTimer = (): void => {
52
+ if (mut_timerId !== undefined) {
53
+ clearTimeout(mut_timerId);
68
54
  }
69
- }
55
+ };
70
56
 
71
- #resetTimer(): void {
72
- if (this.#mut_timerId !== undefined) {
73
- clearTimeout(this.#mut_timerId);
74
- }
75
- }
57
+ const observable = createRootObservable<0, Readonly<{ start: () => void }>>(
58
+ { initialValue: Optional.none, onComplete: resetTimer },
59
+ ({ startUpdate, isCompleted, complete }) => ({
60
+ start: () => {
61
+ if (mut_isStarted) {
62
+ console.warn('cannot start twice');
76
63
 
77
- start(): void {
78
- if (this.#mut_isStarted) {
79
- console.warn('cannot start twice');
64
+ return;
65
+ }
80
66
 
81
- return;
82
- }
67
+ mut_isStarted = true;
83
68
 
84
- this.#mut_isStarted = true;
69
+ if (isCompleted()) {
70
+ console.warn('cannot restart stopped TimerObservable');
85
71
 
86
- if (this.isCompleted) {
87
- console.warn('cannot restart stopped TimerObservable');
72
+ return;
73
+ }
88
74
 
89
- return;
90
- }
75
+ mut_timerId = setTimeout(() => {
76
+ startUpdate(0);
91
77
 
92
- this.#mut_timerId = setTimeout(() => {
93
- this.startUpdate(0);
78
+ complete();
79
+ }, milliSeconds);
80
+ },
81
+ }),
82
+ );
94
83
 
95
- this.complete();
96
- }, this.#milliSeconds);
84
+ if (!(options?.startManually ?? false)) {
85
+ observable.start();
97
86
  }
98
87
 
99
- override complete(): void {
100
- this.#resetTimer();
101
-
102
- super.complete();
103
- }
104
- }
88
+ return observable;
89
+ };
@@ -1,4 +1,3 @@
1
- export * from './class/index.mjs';
2
1
  export * from './combine/index.mjs';
3
2
  export * from './create/index.mjs';
4
3
  export * from './operators/index.mjs';
@@ -1,11 +1,10 @@
1
1
  import { Optional } from 'ts-data-forge';
2
- import { AsyncChildObservableClass } from '../class/index.mjs';
2
+ import { createAsyncChildObservable } from '../base/index.mjs';
3
3
  import {
4
4
  type AuditOperatorObservable,
5
5
  type KeepInitialValueOperator,
6
6
  type Observable,
7
7
  type TimerId,
8
- type UpdateToken,
9
8
  } from '../types/index.mjs';
10
9
 
11
10
  /**
@@ -107,66 +106,53 @@ export const audit = <A,>(
107
106
  ): KeepInitialValueOperator<A, A> =>
108
107
  // eslint-disable-next-line total-functions/no-unsafe-type-assertion
109
108
  ((parentObservable) =>
110
- new AuditObservableClass(
109
+ createAuditObservable(
111
110
  parentObservable,
112
111
  milliSeconds,
113
112
  )) as KeepInitialValueOperator<A, A>;
114
113
 
115
- class AuditObservableClass<A>
116
- extends AsyncChildObservableClass<A, readonly [A]>
117
- implements AuditOperatorObservable<A>
118
- {
119
- readonly #milliSeconds: number;
120
- #mut_timerId: TimerId | undefined;
121
- #mut_isSkipping: boolean;
122
-
123
- constructor(parentObservable: Observable<A>, milliSeconds: number) {
124
- super({
125
- parents: [parentObservable],
126
- initialValue: parentObservable.getSnapshot(),
127
- });
128
-
129
- this.#mut_isSkipping = false;
130
-
131
- this.#mut_timerId = undefined;
132
-
133
- this.#milliSeconds = milliSeconds;
134
- }
135
-
136
- #resetTimer(): void {
137
- if (this.#mut_timerId !== undefined) {
138
- clearTimeout(this.#mut_timerId);
139
- }
140
- }
114
+ const createAuditObservable = <A,>(
115
+ parentObservable: Observable<A>,
116
+ milliSeconds: number,
117
+ ): AuditOperatorObservable<A> => {
118
+ let mut_timerId: TimerId | undefined = undefined;
141
119
 
142
- override tryUpdate(updateToken: UpdateToken): void {
143
- const par = this.parents[0];
120
+ let mut_isSkipping = false;
144
121
 
145
- if (
146
- par.updateToken !== updateToken ||
147
- Optional.isNone(par.getSnapshot()) ||
148
- this.#mut_isSkipping
149
- ) {
150
- return; // skip update
122
+ const resetTimer = (): void => {
123
+ if (mut_timerId !== undefined) {
124
+ clearTimeout(mut_timerId);
151
125
  }
126
+ };
152
127
 
153
- // set timer
154
- this.#mut_isSkipping = true;
155
-
156
- this.#mut_timerId = setTimeout(() => {
157
- const sn = par.getSnapshot();
158
-
159
- if (Optional.isNone(sn)) return;
160
-
161
- this.startUpdate(sn.value);
162
-
163
- this.#mut_isSkipping = false;
164
- }, this.#milliSeconds);
165
- }
166
-
167
- override complete(): void {
168
- this.#resetTimer();
169
-
170
- super.complete();
171
- }
172
- }
128
+ return createAsyncChildObservable(
129
+ {
130
+ parents: [parentObservable],
131
+ initialValue: parentObservable.getSnapshot(),
132
+ onComplete: resetTimer,
133
+ },
134
+ ({ startUpdate }) =>
135
+ (updateToken) => {
136
+ if (
137
+ mut_isSkipping ||
138
+ parentObservable.updateToken !== updateToken ||
139
+ Optional.isNone(parentObservable.getSnapshot())
140
+ ) {
141
+ return; // skip update
142
+ }
143
+
144
+ // set timer
145
+ mut_isSkipping = true;
146
+
147
+ mut_timerId = setTimeout(() => {
148
+ const sn = parentObservable.getSnapshot();
149
+
150
+ if (Optional.isNone(sn)) return;
151
+
152
+ startUpdate(sn.value);
153
+
154
+ mut_isSkipping = false;
155
+ }, milliSeconds);
156
+ },
157
+ );
158
+ };
@@ -1,11 +1,10 @@
1
1
  import { Optional } from 'ts-data-forge';
2
- import { AsyncChildObservableClass } from '../class/index.mjs';
2
+ import { createAsyncChildObservable } from '../base/index.mjs';
3
3
  import {
4
4
  type DebounceOperatorObservable,
5
5
  type KeepInitialValueOperator,
6
6
  type Observable,
7
7
  type TimerId,
8
- type UpdateToken,
9
8
  } from '../types/index.mjs';
10
9
 
11
10
  /**
@@ -98,57 +97,48 @@ export const debounce = <A,>(
98
97
  ): KeepInitialValueOperator<A, A> =>
99
98
  // eslint-disable-next-line total-functions/no-unsafe-type-assertion
100
99
  ((parentObservable) =>
101
- new DebounceObservableClass(
100
+ createDebounceObservable(
102
101
  parentObservable,
103
102
  milliSeconds,
104
103
  )) as KeepInitialValueOperator<A, A>;
105
104
 
106
- class DebounceObservableClass<A>
107
- extends AsyncChildObservableClass<A, readonly [A]>
108
- implements DebounceOperatorObservable<A>
109
- {
110
- readonly #milliSeconds: number;
111
- #mut_timerId: TimerId | undefined;
112
-
113
- constructor(parentObservable: Observable<A>, milliSeconds: number) {
114
- super({
115
- parents: [parentObservable],
116
- initialValue: parentObservable.getSnapshot(),
117
- });
118
-
119
- this.#mut_timerId = undefined;
120
-
121
- this.#milliSeconds = milliSeconds;
122
- }
123
-
124
- #resetTimer(): void {
125
- if (this.#mut_timerId !== undefined) {
126
- clearTimeout(this.#mut_timerId);
127
- }
128
- }
129
-
130
- override tryUpdate(updateToken: UpdateToken): void {
131
- const par = this.parents[0];
132
-
133
- const sn = par.getSnapshot();
105
+ const createDebounceObservable = <A,>(
106
+ parentObservable: Observable<A>,
107
+ milliSeconds: number,
108
+ ): DebounceOperatorObservable<A> => {
109
+ let mut_timerId: TimerId | undefined = undefined;
134
110
 
135
- if (par.updateToken !== updateToken || Optional.isNone(sn)) {
136
- return; // skip update
111
+ const resetTimer = (): void => {
112
+ if (mut_timerId !== undefined) {
113
+ clearTimeout(mut_timerId);
137
114
  }
115
+ };
138
116
 
139
- this.#resetTimer();
117
+ return createAsyncChildObservable(
118
+ {
119
+ parents: [parentObservable],
120
+ initialValue: parentObservable.getSnapshot(),
121
+ onComplete: resetTimer,
122
+ },
123
+ ({ startUpdate }) =>
124
+ (updateToken) => {
125
+ const sn = parentObservable.getSnapshot();
140
126
 
141
- // set timer
142
- this.#mut_timerId = setTimeout(() => {
143
- if (Optional.isNone(sn)) return;
127
+ if (
128
+ parentObservable.updateToken !== updateToken ||
129
+ Optional.isNone(sn)
130
+ ) {
131
+ return; // skip update
132
+ }
144
133
 
145
- this.startUpdate(sn.value);
146
- }, this.#milliSeconds);
147
- }
134
+ resetTimer();
148
135
 
149
- override complete(): void {
150
- this.#resetTimer();
136
+ // set timer
137
+ mut_timerId = setTimeout(() => {
138
+ if (Optional.isNone(sn)) return;
151
139
 
152
- super.complete();
153
- }
154
- }
140
+ startUpdate(sn.value);
141
+ }, milliSeconds);
142
+ },
143
+ );
144
+ };
@@ -5,14 +5,13 @@ import {
5
5
  pipe,
6
6
  SafeUint,
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 FilterOperatorObservable,
13
13
  type InitializedObservable,
14
14
  type Observable,
15
- type UpdateToken,
16
15
  } from '../types/index.mjs';
17
16
  import { withInitialValue } from './with-initial-value.mjs';
18
17
 
@@ -77,21 +76,15 @@ export function filter<A>(
77
76
  predicate: (value: A, index: SafeUint | -1) => boolean,
78
77
  ): DropInitialValueOperator<A, A> {
79
78
  return (parentObservable) =>
80
- new FilterObservableClass(parentObservable, predicate);
79
+ createFilterObservable(parentObservable, predicate);
81
80
  }
82
81
 
83
- class FilterObservableClass<A>
84
- extends SyncChildObservableClass<A, readonly [A]>
85
- implements FilterOperatorObservable<A>
86
- {
87
- readonly #predicate: (x: A, index: SafeUint | -1) => boolean;
88
- #mut_index: SafeUint | -1;
89
-
90
- constructor(
91
- parentObservable: Observable<A>,
92
- predicate: (x: A, index: SafeUint | -1) => boolean,
93
- ) {
94
- super({
82
+ const createFilterObservable = <A,>(
83
+ parentObservable: Observable<A>,
84
+ predicate: (x: A, index: SafeUint | -1) => boolean,
85
+ ): FilterOperatorObservable<A> =>
86
+ createSyncChildObservable(
87
+ {
95
88
  parents: [parentObservable],
96
89
  initialValue: pipe(parentObservable.getSnapshot()).map((sn) =>
97
90
  Optional.isNone(sn)
@@ -100,30 +93,29 @@ class FilterObservableClass<A>
100
93
  ? sn
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
- }
125
- }
126
- }
96
+ },
97
+ ({ setNext }) => {
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
+ }
116
+ };
117
+ },
118
+ );
127
119
 
128
120
  if (import.meta.vitest !== undefined) {
129
121
  test('type test', () => {
@@ -1,12 +1,11 @@
1
1
  import { Optional, SafeUint, asSafeUint, expectType } from 'ts-data-forge';
2
- import { SyncChildObservableClass } from '../class/index.mjs';
2
+ import { createSyncChildObservable } from '../base/index.mjs';
3
3
  import { source } from '../create/index.mjs';
4
4
  import {
5
5
  type InitializedObservable,
6
6
  type KeepInitialValueOperator,
7
7
  type MapOperatorObservable,
8
8
  type Observable,
9
- type UpdateToken,
10
9
  } from '../types/index.mjs';
11
10
  import { withInitialValue } from './with-initial-value.mjs';
12
11
 
@@ -53,51 +52,44 @@ export const map = <A, B>(
53
52
  ): KeepInitialValueOperator<A, B> =>
54
53
  // eslint-disable-next-line total-functions/no-unsafe-type-assertion
55
54
  ((parentObservable) =>
56
- new MapObservableClass(
57
- parentObservable,
58
- mapFn,
59
- )) as KeepInitialValueOperator<A, B>;
55
+ createMapObservable(parentObservable, mapFn)) as KeepInitialValueOperator<
56
+ A,
57
+ B
58
+ >;
60
59
 
61
60
  /* implementation */
62
61
 
63
- class MapObservableClass<A, B>
64
- extends SyncChildObservableClass<B, readonly [A]>
65
- implements MapOperatorObservable<A, B>
66
- {
67
- readonly #mapFn: (x: A, index: SafeUint | -1) => B;
68
- #mut_index: SafeUint | -1;
69
-
70
- constructor(
71
- parentObservable: Observable<A>,
72
- mapFn: (x: A, index: SafeUint | -1) => B,
73
- ) {
74
- super({
62
+ const createMapObservable = <A, B>(
63
+ parentObservable: Observable<A>,
64
+ mapFn: (x: A, index: SafeUint | -1) => B,
65
+ ): MapOperatorObservable<A, B> =>
66
+ createSyncChildObservable(
67
+ {
75
68
  parents: [parentObservable],
76
69
  initialValue: Optional.map(parentObservable.getSnapshot(), (x) =>
77
70
  mapFn(x, -1),
78
71
  ),
79
- });
80
-
81
- this.#mut_index = -1;
82
-
83
- this.#mapFn = mapFn;
84
- }
85
-
86
- override tryUpdate(updateToken: UpdateToken): void {
87
- const par = this.parents[0];
88
-
89
- const sn = par.getSnapshot();
90
-
91
- if (par.updateToken !== updateToken || Optional.isNone(sn)) {
92
- return; // skip update
93
- }
94
-
95
- this.#mut_index =
96
- this.#mut_index === -1 ? asSafeUint(0) : SafeUint.add(1, this.#mut_index);
97
-
98
- this.setNext(this.#mapFn(sn.value, this.#mut_index), updateToken);
99
- }
100
- }
72
+ },
73
+ ({ setNext }) => {
74
+ let mut_index: SafeUint | -1 = -1;
75
+
76
+ return (updateToken) => {
77
+ const sn = parentObservable.getSnapshot();
78
+
79
+ if (
80
+ parentObservable.updateToken !== updateToken ||
81
+ Optional.isNone(sn)
82
+ ) {
83
+ return; // skip update
84
+ }
85
+
86
+ mut_index =
87
+ mut_index === -1 ? asSafeUint(0) : SafeUint.add(1, mut_index);
88
+
89
+ setNext(mapFn(sn.value, mut_index), updateToken);
90
+ };
91
+ },
92
+ );
101
93
 
102
94
  if (import.meta.vitest !== undefined) {
103
95
  test('type test', () => {
@@ -1,11 +1,10 @@
1
1
  import { Arr, Optional } from 'ts-data-forge';
2
- import { AsyncChildObservableClass } from '../class/index.mjs';
2
+ import { createAsyncChildObservable } from '../base/index.mjs';
3
3
  import {
4
4
  type DropInitialValueOperator,
5
5
  type MergeMapOperatorObservable,
6
6
  type Observable,
7
7
  type Subscription,
8
- type UpdateToken,
9
8
  } from '../types/index.mjs';
10
9
 
11
10
  /**
@@ -108,7 +107,7 @@ export const mergeMap =
108
107
  mapToObservable: (curr: A) => Observable<B>,
109
108
  ): DropInitialValueOperator<A, B> =>
110
109
  (parentObservable) =>
111
- new MergeMapObservableClass(parentObservable, mapToObservable);
110
+ createMergeMapObservable(parentObservable, mapToObservable);
112
111
 
113
112
  /**
114
113
  * Alias for `mergeMap`.
@@ -116,62 +115,48 @@ export const mergeMap =
116
115
  */
117
116
  export const flatMap = mergeMap;
118
117
 
119
- class MergeMapObservableClass<A, B>
120
- extends AsyncChildObservableClass<B, readonly [A]>
121
- implements MergeMapOperatorObservable<A, B>
122
- {
123
- readonly #mapToObservable: (curr: A) => Observable<B>;
124
- #mut_observables: readonly Observable<B>[];
125
- #mut_subscriptions: readonly Subscription[];
118
+ const createMergeMapObservable = <A, B>(
119
+ parentObservable: Observable<A>,
120
+ mapToObservable: (curr: A) => Observable<B>,
121
+ ): MergeMapOperatorObservable<A, B> => {
122
+ let mut_observables: readonly Observable<B>[] = [];
126
123
 
127
- constructor(
128
- parentObservable: Observable<A>,
129
- mapToObservable: (curr: A) => Observable<B>,
130
- ) {
131
- super({
124
+ let mut_subscriptions: readonly Subscription[] = [];
125
+
126
+ return createAsyncChildObservable(
127
+ {
132
128
  parents: [parentObservable],
133
129
  initialValue: Optional.none,
134
- });
135
-
136
- this.#mapToObservable = mapToObservable;
137
-
138
- this.#mut_observables = [];
139
-
140
- this.#mut_subscriptions = [];
141
- }
142
-
143
- override tryUpdate(updateToken: UpdateToken): void {
144
- const par = this.parents[0];
145
-
146
- const sn = par.getSnapshot();
147
-
148
- if (par.updateToken !== updateToken || Optional.isNone(sn)) {
149
- return; // skip update
150
- }
151
-
152
- const observable = this.#mapToObservable(sn.value);
153
-
154
- this.#mut_observables = Arr.toPushed(this.#mut_observables, observable);
155
-
156
- const subscription = observable.subscribe((curr) => {
157
- this.startUpdate(curr);
158
- });
159
-
160
- this.#mut_subscriptions = Arr.toPushed(
161
- this.#mut_subscriptions,
162
- subscription,
163
- );
164
- }
165
-
166
- override complete(): void {
167
- for (const s of this.#mut_subscriptions) {
168
- s.unsubscribe();
169
- }
170
-
171
- for (const o of this.#mut_observables) {
172
- o.complete();
173
- }
174
-
175
- super.complete();
176
- }
177
- }
130
+ onComplete: () => {
131
+ for (const s of mut_subscriptions) {
132
+ s.unsubscribe();
133
+ }
134
+
135
+ for (const o of mut_observables) {
136
+ o.complete();
137
+ }
138
+ },
139
+ },
140
+ ({ startUpdate }) =>
141
+ (updateToken) => {
142
+ const sn = parentObservable.getSnapshot();
143
+
144
+ if (
145
+ parentObservable.updateToken !== updateToken ||
146
+ Optional.isNone(sn)
147
+ ) {
148
+ return; // skip update
149
+ }
150
+
151
+ const observable = mapToObservable(sn.value);
152
+
153
+ mut_observables = Arr.toPushed(mut_observables, observable);
154
+
155
+ const subscription = observable.subscribe((curr) => {
156
+ startUpdate(curr);
157
+ });
158
+
159
+ mut_subscriptions = Arr.toPushed(mut_subscriptions, subscription);
160
+ },
161
+ );
162
+ };