@fluixi/reactive 1.0.0-alpha.53

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 (176) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +343 -0
  3. package/dist/cdn/reactive.cjs +1 -0
  4. package/dist/cdn/reactive.d.ts +11 -0
  5. package/dist/cdn/reactive.d.ts.map +1 -0
  6. package/dist/cdn/reactive.global.js +1 -0
  7. package/dist/cdn/reactive.js +10 -0
  8. package/dist/cdn/reactive.mjs +1 -0
  9. package/dist/cdn/signal.cjs +1 -0
  10. package/dist/cdn/signal.d.ts +19 -0
  11. package/dist/cdn/signal.d.ts.map +1 -0
  12. package/dist/cdn/signal.global.js +1 -0
  13. package/dist/cdn/signal.js +18 -0
  14. package/dist/cdn/signal.mjs +1 -0
  15. package/dist/index.cjs +1 -0
  16. package/dist/index.d.ts +2 -0
  17. package/dist/index.d.ts.map +1 -0
  18. package/dist/index.js +1 -0
  19. package/dist/index.mjs +1 -0
  20. package/dist/lib/index.cjs +1 -0
  21. package/dist/lib/index.d.ts +5 -0
  22. package/dist/lib/index.d.ts.map +1 -0
  23. package/dist/lib/index.js +4 -0
  24. package/dist/lib/index.mjs +1 -0
  25. package/dist/lib/observable/index.cjs +1 -0
  26. package/dist/lib/observable/index.d.ts +4 -0
  27. package/dist/lib/observable/index.d.ts.map +1 -0
  28. package/dist/lib/observable/index.js +3 -0
  29. package/dist/lib/observable/index.mjs +1 -0
  30. package/dist/lib/observable/observable.cjs +1 -0
  31. package/dist/lib/observable/observable.d.ts +383 -0
  32. package/dist/lib/observable/observable.d.ts.map +1 -0
  33. package/dist/lib/observable/observable.js +339 -0
  34. package/dist/lib/observable/observable.mjs +1 -0
  35. package/dist/lib/observable/subscription.cjs +1 -0
  36. package/dist/lib/observable/subscription.d.ts +70 -0
  37. package/dist/lib/observable/subscription.d.ts.map +1 -0
  38. package/dist/lib/observable/subscription.js +190 -0
  39. package/dist/lib/observable/subscription.mjs +1 -0
  40. package/dist/lib/observable/types.cjs +1 -0
  41. package/dist/lib/observable/types.d.ts +44 -0
  42. package/dist/lib/observable/types.d.ts.map +1 -0
  43. package/dist/lib/observable/types.js +1 -0
  44. package/dist/lib/observable/types.mjs +0 -0
  45. package/dist/lib/signal/cached-resource.cjs +1 -0
  46. package/dist/lib/signal/cached-resource.d.ts +94 -0
  47. package/dist/lib/signal/cached-resource.d.ts.map +1 -0
  48. package/dist/lib/signal/cached-resource.js +257 -0
  49. package/dist/lib/signal/cached-resource.mjs +1 -0
  50. package/dist/lib/signal/graph/children.cjs +1 -0
  51. package/dist/lib/signal/graph/children.d.ts +2 -0
  52. package/dist/lib/signal/graph/children.d.ts.map +1 -0
  53. package/dist/lib/signal/graph/children.js +30 -0
  54. package/dist/lib/signal/graph/children.mjs +1 -0
  55. package/dist/lib/signal/graph/compat.cjs +1 -0
  56. package/dist/lib/signal/graph/compat.d.ts +64 -0
  57. package/dist/lib/signal/graph/compat.d.ts.map +1 -0
  58. package/dist/lib/signal/graph/compat.js +178 -0
  59. package/dist/lib/signal/graph/compat.mjs +1 -0
  60. package/dist/lib/signal/graph/core.cjs +1 -0
  61. package/dist/lib/signal/graph/core.d.ts +95 -0
  62. package/dist/lib/signal/graph/core.d.ts.map +1 -0
  63. package/dist/lib/signal/graph/core.js +254 -0
  64. package/dist/lib/signal/graph/core.mjs +1 -0
  65. package/dist/lib/signal/graph/derived.cjs +1 -0
  66. package/dist/lib/signal/graph/derived.d.ts +14 -0
  67. package/dist/lib/signal/graph/derived.d.ts.map +1 -0
  68. package/dist/lib/signal/graph/derived.js +81 -0
  69. package/dist/lib/signal/graph/derived.mjs +1 -0
  70. package/dist/lib/signal/graph/detect.cjs +1 -0
  71. package/dist/lib/signal/graph/detect.d.ts +16 -0
  72. package/dist/lib/signal/graph/detect.d.ts.map +1 -0
  73. package/dist/lib/signal/graph/detect.js +36 -0
  74. package/dist/lib/signal/graph/detect.mjs +1 -0
  75. package/dist/lib/signal/graph/error-boundary.cjs +1 -0
  76. package/dist/lib/signal/graph/error-boundary.d.ts +16 -0
  77. package/dist/lib/signal/graph/error-boundary.d.ts.map +1 -0
  78. package/dist/lib/signal/graph/error-boundary.js +34 -0
  79. package/dist/lib/signal/graph/error-boundary.mjs +1 -0
  80. package/dist/lib/signal/graph/index.cjs +1 -0
  81. package/dist/lib/signal/graph/index.d.ts +21 -0
  82. package/dist/lib/signal/graph/index.d.ts.map +1 -0
  83. package/dist/lib/signal/graph/index.js +20 -0
  84. package/dist/lib/signal/graph/index.mjs +1 -0
  85. package/dist/lib/signal/graph/resource.cjs +1 -0
  86. package/dist/lib/signal/graph/resource.d.ts +36 -0
  87. package/dist/lib/signal/graph/resource.d.ts.map +1 -0
  88. package/dist/lib/signal/graph/resource.js +156 -0
  89. package/dist/lib/signal/graph/resource.mjs +1 -0
  90. package/dist/lib/signal/graph/runtime.cjs +1 -0
  91. package/dist/lib/signal/graph/runtime.d.ts +56 -0
  92. package/dist/lib/signal/graph/runtime.d.ts.map +1 -0
  93. package/dist/lib/signal/graph/runtime.js +277 -0
  94. package/dist/lib/signal/graph/runtime.mjs +1 -0
  95. package/dist/lib/signal/graph/signal-next.cjs +1 -0
  96. package/dist/lib/signal/graph/signal-next.d.ts +37 -0
  97. package/dist/lib/signal/graph/signal-next.d.ts.map +1 -0
  98. package/dist/lib/signal/graph/signal-next.js +41 -0
  99. package/dist/lib/signal/graph/signal-next.mjs +1 -0
  100. package/dist/lib/signal/graph/ssr-hooks.cjs +1 -0
  101. package/dist/lib/signal/graph/ssr-hooks.d.ts +28 -0
  102. package/dist/lib/signal/graph/ssr-hooks.d.ts.map +1 -0
  103. package/dist/lib/signal/graph/ssr-hooks.js +45 -0
  104. package/dist/lib/signal/graph/ssr-hooks.mjs +1 -0
  105. package/dist/lib/signal/graph/state.cjs +1 -0
  106. package/dist/lib/signal/graph/state.d.ts +43 -0
  107. package/dist/lib/signal/graph/state.d.ts.map +1 -0
  108. package/dist/lib/signal/graph/state.js +37 -0
  109. package/dist/lib/signal/graph/state.mjs +1 -0
  110. package/dist/lib/signal/graph/suspense.cjs +1 -0
  111. package/dist/lib/signal/graph/suspense.d.ts +13 -0
  112. package/dist/lib/signal/graph/suspense.d.ts.map +1 -0
  113. package/dist/lib/signal/graph/suspense.js +36 -0
  114. package/dist/lib/signal/graph/suspense.mjs +1 -0
  115. package/dist/lib/signal/index-legacy.cjs +1 -0
  116. package/dist/lib/signal/index-legacy.d.ts +12 -0
  117. package/dist/lib/signal/index-legacy.d.ts.map +1 -0
  118. package/dist/lib/signal/index-legacy.js +11 -0
  119. package/dist/lib/signal/index-legacy.mjs +1 -0
  120. package/dist/lib/signal/index.cjs +1 -0
  121. package/dist/lib/signal/index.d.ts +12 -0
  122. package/dist/lib/signal/index.d.ts.map +1 -0
  123. package/dist/lib/signal/index.js +11 -0
  124. package/dist/lib/signal/index.mjs +1 -0
  125. package/dist/lib/signal/list.cjs +1 -0
  126. package/dist/lib/signal/list.d.ts +39 -0
  127. package/dist/lib/signal/list.d.ts.map +1 -0
  128. package/dist/lib/signal/list.js +172 -0
  129. package/dist/lib/signal/list.mjs +1 -0
  130. package/dist/lib/signal/signal.cjs +1 -0
  131. package/dist/lib/signal/signal.d.ts +295 -0
  132. package/dist/lib/signal/signal.d.ts.map +1 -0
  133. package/dist/lib/signal/signal.js +1219 -0
  134. package/dist/lib/signal/signal.mjs +1 -0
  135. package/dist/lib/signal/types.cjs +1 -0
  136. package/dist/lib/signal/types.d.ts +133 -0
  137. package/dist/lib/signal/types.d.ts.map +1 -0
  138. package/dist/lib/signal/types.js +38 -0
  139. package/dist/lib/signal/types.mjs +1 -0
  140. package/dist/lib/signal/utilities.cjs +1 -0
  141. package/dist/lib/signal/utilities.d.ts +355 -0
  142. package/dist/lib/signal/utilities.d.ts.map +1 -0
  143. package/dist/lib/signal/utilities.js +504 -0
  144. package/dist/lib/signal/utilities.mjs +1 -0
  145. package/dist/lib/store/index.cjs +1 -0
  146. package/dist/lib/store/index.d.ts +14 -0
  147. package/dist/lib/store/index.d.ts.map +1 -0
  148. package/dist/lib/store/index.js +11 -0
  149. package/dist/lib/store/index.mjs +1 -0
  150. package/dist/lib/store/setter.types.cjs +1 -0
  151. package/dist/lib/store/setter.types.d.ts +79 -0
  152. package/dist/lib/store/setter.types.d.ts.map +1 -0
  153. package/dist/lib/store/setter.types.js +65 -0
  154. package/dist/lib/store/setter.types.mjs +0 -0
  155. package/dist/lib/store/store.cjs +1 -0
  156. package/dist/lib/store/store.d.ts +86 -0
  157. package/dist/lib/store/store.d.ts.map +1 -0
  158. package/dist/lib/store/store.js +442 -0
  159. package/dist/lib/store/store.mjs +1 -0
  160. package/dist/lib/store/types.cjs +1 -0
  161. package/dist/lib/store/types.d.ts +57 -0
  162. package/dist/lib/store/types.d.ts.map +1 -0
  163. package/dist/lib/store/types.js +1 -0
  164. package/dist/lib/store/types.mjs +0 -0
  165. package/dist/lib/store/utils.cjs +1 -0
  166. package/dist/lib/store/utils.d.ts +13 -0
  167. package/dist/lib/store/utils.d.ts.map +1 -0
  168. package/dist/lib/store/utils.js +29 -0
  169. package/dist/lib/store/utils.mjs +1 -0
  170. package/dist/lib/subject.cjs +1 -0
  171. package/dist/lib/subject.d.ts +14 -0
  172. package/dist/lib/subject.d.ts.map +1 -0
  173. package/dist/lib/subject.js +169 -0
  174. package/dist/lib/subject.mjs +1 -0
  175. package/dist/tsconfig.lib.tsbuildinfo +1 -0
  176. package/package.json +114 -0
@@ -0,0 +1,339 @@
1
+ // import { Subscription, toPromise } from "@fluixi/reactive";
2
+ // import { toPromise } from "./operators/index.js";
3
+ import { Subscription } from "./subscription.js";
4
+ /**
5
+ * A subscriber is both an Observer and a Subscription.
6
+ * This is the object that gets passed to the Observable's subscribe function.
7
+ *
8
+ * @template T - The type of values being observed
9
+ * @class Subscriber
10
+ * @extends {Subscription}
11
+ * @implements {Observer<T>}
12
+ */
13
+ export class Subscriber extends Subscription {
14
+ /** @private */ isStopped = false;
15
+ /** @private */ destination;
16
+ /**
17
+ * Creates a new Subscriber.
18
+ *
19
+ * @param {Partial<Observer<T>>|((value: T) => void)} [destinationOrNext] -
20
+ * Either an observer object or a next handler function
21
+ * @param {(error: any) => void} [error] - Error handler (if first param is next function)
22
+ * @param {() => void} [complete] - Complete handler (if first param is next function)
23
+ */
24
+ constructor(destinationOrNext, error, complete) {
25
+ super();
26
+ // Normalize arguments to observer object
27
+ let observer;
28
+ if (!destinationOrNext) {
29
+ observer = {};
30
+ }
31
+ else if (typeof destinationOrNext === 'object') {
32
+ observer = destinationOrNext;
33
+ }
34
+ else {
35
+ observer = {
36
+ next: destinationOrNext,
37
+ error: error,
38
+ complete: complete
39
+ };
40
+ }
41
+ this.destination = observer;
42
+ }
43
+ /**
44
+ * Sends the next value to the observer.
45
+ *
46
+ * @param {T} value - The value to send
47
+ * @returns {void}
48
+ */
49
+ next(value) {
50
+ if (!this.isStopped && this.destination.next) {
51
+ try {
52
+ this.destination.next(value);
53
+ }
54
+ catch (error) {
55
+ this.error(error);
56
+ }
57
+ }
58
+ }
59
+ /**
60
+ * Sends an error notification to the observer.
61
+ *
62
+ * @param {any} err - The error to send
63
+ * @returns {void}
64
+ */
65
+ error(err) {
66
+ if (!this.isStopped) {
67
+ this.isStopped = true;
68
+ if (this.destination.error) {
69
+ try {
70
+ this.destination.error(err);
71
+ }
72
+ catch (error) {
73
+ // Rethrow if error handler throws
74
+ throw error;
75
+ }
76
+ }
77
+ else {
78
+ throw err;
79
+ }
80
+ this.unsubscribe();
81
+ }
82
+ }
83
+ /**
84
+ * Sends a complete notification to the observer.
85
+ *
86
+ * @returns {void}
87
+ */
88
+ complete() {
89
+ if (!this.isStopped) {
90
+ this.isStopped = true;
91
+ if (this.destination.complete) {
92
+ try {
93
+ this.destination.complete();
94
+ }
95
+ catch (error) {
96
+ this.error(error);
97
+ return;
98
+ }
99
+ }
100
+ this.unsubscribe();
101
+ }
102
+ }
103
+ /**
104
+ * Unsubscribes the subscriber.
105
+ *
106
+ * @returns {void}
107
+ */
108
+ unsubscribe() {
109
+ if (this.closed) {
110
+ return;
111
+ }
112
+ this.isStopped = true;
113
+ super.unsubscribe();
114
+ }
115
+ }
116
+ /**
117
+ * SafeSubscriber adds extra safety checks to prevent reentrant calls.
118
+ *
119
+ * @template T - The type of values being observed
120
+ * @class SafeSubscriber
121
+ * @extends {Subscriber<T>}
122
+ */
123
+ export class SafeSubscriber extends Subscriber {
124
+ /** @private */ _isUnsubscribing = false;
125
+ /** @private */ _parentSubscriber = null;
126
+ constructor(observerOrNext, error, complete, parentSubscriber) {
127
+ super(observerOrNext, error, complete);
128
+ this._parentSubscriber = parentSubscriber || null;
129
+ }
130
+ next(value) {
131
+ if (!this.isStopped && !this._isUnsubscribing) {
132
+ // Use try-catch to ensure errors don't break the subscriber
133
+ try {
134
+ super.next(value);
135
+ }
136
+ catch (error) {
137
+ this.error(error);
138
+ }
139
+ }
140
+ }
141
+ error(err) {
142
+ if (!this.isStopped && !this._isUnsubscribing) {
143
+ this._isUnsubscribing = true;
144
+ try {
145
+ super.error(err);
146
+ }
147
+ finally {
148
+ this._isUnsubscribing = false;
149
+ }
150
+ }
151
+ }
152
+ complete() {
153
+ if (!this.isStopped && !this._isUnsubscribing) {
154
+ this._isUnsubscribing = true;
155
+ try {
156
+ super.complete();
157
+ }
158
+ finally {
159
+ this._isUnsubscribing = false;
160
+ }
161
+ }
162
+ }
163
+ unsubscribe() {
164
+ if (this.closed) {
165
+ return;
166
+ }
167
+ this._isUnsubscribing = true;
168
+ super.unsubscribe();
169
+ this._isUnsubscribing = false;
170
+ }
171
+ }
172
+ export function operate(destination) {
173
+ return new Subscriber(destination.next, destination.error, destination.complete);
174
+ }
175
+ /**
176
+ * A representation of any set of values over any amount of time.
177
+ * This is the most basic building block of RxJS.
178
+ *
179
+ * @template T - The type of values emitted by the Observable
180
+ * @class Observable
181
+ *
182
+ * @example
183
+ * // Create an Observable from scratch
184
+ * const observable = new Observable<string>(subscriber => {
185
+ * subscriber.next('Hello');
186
+ * subscriber.next('World');
187
+ * subscriber.complete();
188
+ *
189
+ * return () => console.log('Cleanup');
190
+ * });
191
+ *
192
+ * @example
193
+ * // Subscribe to an Observable
194
+ * const subscription = observable.subscribe({
195
+ * next: value => console.log(value),
196
+ * error: err => console.error(err),
197
+ * complete: () => console.log('Done')
198
+ * });
199
+ *
200
+ * // Later, unsubscribe
201
+ * subscription.unsubscribe();
202
+ */
203
+ // export class Observable<T> extends Subscription {
204
+ // constructor(
205
+ // private _subscribeFn: (observer: Observer<T>) => void | (() => void) | Subscription
206
+ // ) {
207
+ // super()
208
+ // }
209
+ // subscribe(observer: Partial<Observer<T>> | ((v: T) => void)): Subscription {
210
+ // const finalObserver: Observer<T> =
211
+ // typeof observer === "function"
212
+ // ? { next: observer, error: () => {}, complete: () => {} }
213
+ // : {
214
+ // next: observer.next!,
215
+ // error: observer.error,
216
+ // complete: observer.complete
217
+ // } as Observer<T>;
218
+ // const subscription = new Subscription();
219
+ // const teardown = this._subscribeFn(finalObserver);
220
+ // if (typeof teardown === "function") {
221
+ // subscription.add(teardown);
222
+ // }
223
+ // return subscription;
224
+ // }
225
+ // /** Fully dynamic variadic pipe */
226
+ // pipe(): Observable<T>;
227
+ // pipe<A>(op1: OperatorFunction<T, A>): Observable<A>;
228
+ // pipe<A, B>(op1: OperatorFunction<T, A>, op2: OperatorFunction<A, B>): Observable<B>;
229
+ // pipe<A, B, C>(op1: OperatorFunction<T, A>, op2: OperatorFunction<A, B>, op3: OperatorFunction<B, C>): Observable<C>;
230
+ // pipe<A, B, C, D>(
231
+ // op1: OperatorFunction<T, A>,
232
+ // op2: OperatorFunction<A, B>,
233
+ // op3: OperatorFunction<B, C>,
234
+ // op4: OperatorFunction<C, D>
235
+ // ): Observable<D>;
236
+ // pipe<A, B, C, D, E>(
237
+ // op1: OperatorFunction<T, A>,
238
+ // op2: OperatorFunction<A, B>,
239
+ // op3: OperatorFunction<B, C>,
240
+ // op4: OperatorFunction<C, D>,
241
+ // op5: OperatorFunction<D, E>
242
+ // ): Observable<E>;
243
+ // // generic fallback for >5 operators (loses some inference but keeps runtime behavior)
244
+ // pipe(...ops: OperatorFunction<any, any>[]): Observable<any> {
245
+ // if (ops.length === 0) return this;
246
+ // return ops.reduce((prev, fn) => fn(prev), this as any);
247
+ // }
248
+ // }
249
+ export class Observable extends Subscription {
250
+ /**
251
+ * The function that is called when the Observable is subscribed to.
252
+ * This function is given a Subscriber to which new values can be `next`ed,
253
+ * or an `error` or `complete` notification can be sent.
254
+ *
255
+ * @private
256
+ * @type {function(Subscriber<T>): (void | (() => void) | Subscription)}
257
+ */
258
+ _subscribe;
259
+ /**
260
+ * Creates a new Observable.
261
+ *
262
+ * @param {function(Subscriber<T>): (void | (() => void) | Subscription)} subscribe -
263
+ * The function that is called when the Observable is subscribed to
264
+ */
265
+ constructor(subscribe) {
266
+ super();
267
+ if (subscribe) {
268
+ this._subscribe = subscribe;
269
+ }
270
+ else {
271
+ throw new TypeError('Observable constructor requires a subscribe function');
272
+ }
273
+ }
274
+ subscribe(observerOrNext, error, complete) {
275
+ // Create subscriber
276
+ let subscriber;
277
+ if (observerOrNext instanceof Subscriber) {
278
+ subscriber = observerOrNext;
279
+ }
280
+ else {
281
+ subscriber = new SafeSubscriber(observerOrNext, error, complete);
282
+ }
283
+ // Add finalization logic
284
+ const { _subscribe } = this;
285
+ // Call the subscribe function
286
+ try {
287
+ const result = _subscribe.call(this, subscriber);
288
+ // Handle return value (could be a cleanup function or subscription)
289
+ if (result) {
290
+ if (typeof result === 'function') {
291
+ subscriber.add(result);
292
+ }
293
+ else if (typeof result.unsubscribe === 'function') {
294
+ subscriber.add(result);
295
+ }
296
+ }
297
+ }
298
+ catch (err) {
299
+ // If subscribe function throws, error the subscriber
300
+ subscriber.error(err);
301
+ }
302
+ return subscriber;
303
+ }
304
+ pipe(...operations) {
305
+ if (operations.length === 0) {
306
+ return this;
307
+ }
308
+ // Apply operators in sequence
309
+ return operations.reduce((prev, fn) => fn(prev), this);
310
+ }
311
+ /**
312
+ * Converts the Observable to a Promise.
313
+ * The Promise resolves with the last emitted value when the Observable completes,
314
+ * or rejects if the Observable errors.
315
+ *
316
+ * @returns {Promise<T | undefined>} A Promise that resolves with the last value
317
+ *
318
+ * @example
319
+ * // Convert Observable to Promise
320
+ * const value = await of(1, 2, 3).toPromise();
321
+ * console.log(value); // 3
322
+ *
323
+ * @example
324
+ * // Handle empty Observable
325
+ * const value = await EMPTY.toPromise();
326
+ * console.log(value); // undefined
327
+ */
328
+ toPromise() {
329
+ return new Promise((resolve, reject) => {
330
+ let lastValue;
331
+ this.subscribe({
332
+ next: value => lastValue = value,
333
+ error: reject,
334
+ complete: () => resolve(lastValue)
335
+ });
336
+ });
337
+ }
338
+ }
339
+ // Observable.prototype.toPromise = toPromise;
@@ -0,0 +1 @@
1
+ import{isObject as l}from"@fluixi/utils/object";import{isFunction as a}from"@fluixi/utils/functions";var p=class o{constructor(e){this._closed=!1;this._parentOrParents=null;this._subscriptions=null;e&&(this._subscriptions=[e])}get closed(){return this._closed}unsubscribe(){if(this._closed)return;this._closed=!0;let{_parentOrParents:e,_subscriptions:r}=this;if(e instanceof o)e.remove(this);else if(e!==null)for(let t of e)t.remove(this);if(r){for(let t of r)if(a(t)&&!(t instanceof o))try{t()}catch(i){console.error("Error in unsubscribe function:",i)}else if(l(t)&&typeof t.unsubscribe=="function")try{t.unsubscribe()}catch(i){console.error("Error unsubscribing child:",i)}this._subscriptions=null}}add(e){if(!e||e===this)return this;if(e.closed)return this;let{_closed:r,_subscriptions:t}=this;if(r){if(a(e))try{e()}catch(i){console.error("Error in unsubscribe function:",i)}else if(e.unsubscribe)try{e.unsubscribe()}catch(i){console.error("Error unsubscribing:",i)}return this}return t||(this._subscriptions=[]),this._subscriptions.push(e),e instanceof o&&e._addParent(this),this}remove(e){let{_subscriptions:r}=this;if(!r)return;let t=r.indexOf(e);t!==-1&&(r.splice(t,1),e._removeParent(this))}_addParent(e){let{_parentOrParents:r}=this;r?Array.isArray(r)?r.push(e):this._parentOrParents=[r,e]:this._parentOrParents=e}_removeParent(e){let{_parentOrParents:r}=this;if(r===e)this._parentOrParents=null;else if(Array.isArray(r)){let t=r.indexOf(e);t!==-1&&(r.splice(t,1),r.length===1&&(this._parentOrParents=r[0]))}}};var u=class extends p{constructor(r,t,i){super();this.isStopped=!1;let n;r?typeof r=="object"?n=r:n={next:r,error:t,complete:i}:n={},this.destination=n}next(r){if(!this.isStopped&&this.destination.next)try{this.destination.next(r)}catch(t){this.error(t)}}error(r){if(!this.isStopped){if(this.isStopped=!0,this.destination.error)try{this.destination.error(r)}catch(t){throw t}else throw r;this.unsubscribe()}}complete(){if(!this.isStopped){if(this.isStopped=!0,this.destination.complete)try{this.destination.complete()}catch(r){this.error(r);return}this.unsubscribe()}}unsubscribe(){this.closed||(this.isStopped=!0,super.unsubscribe())}},c=class extends u{constructor(r,t,i,n){super(r,t,i);this._isUnsubscribing=!1;this._parentSubscriber=null;this._parentSubscriber=n||null}next(r){if(!this.isStopped&&!this._isUnsubscribing)try{super.next(r)}catch(t){this.error(t)}}error(r){if(!this.isStopped&&!this._isUnsubscribing){this._isUnsubscribing=!0;try{super.error(r)}finally{this._isUnsubscribing=!1}}}complete(){if(!this.isStopped&&!this._isUnsubscribing){this._isUnsubscribing=!0;try{super.complete()}finally{this._isUnsubscribing=!1}}}unsubscribe(){this.closed||(this._isUnsubscribing=!0,super.unsubscribe(),this._isUnsubscribing=!1)}};function f(o){return new u(o.next,o.error,o.complete)}var b=class extends p{constructor(e){if(super(),e)this._subscribe=e;else throw new TypeError("Observable constructor requires a subscribe function")}subscribe(e,r,t){let i;e instanceof u?i=e:i=new c(e,r,t);let{_subscribe:n}=this;try{let s=n.call(this,i);s&&(typeof s=="function"||typeof s.unsubscribe=="function")&&i.add(s)}catch(s){i.error(s)}return i}pipe(...e){return e.length===0?this:e.reduce((r,t)=>t(r),this)}toPromise(){return new Promise((e,r)=>{let t;this.subscribe({next:i=>t=i,error:r,complete:()=>e(t)})})}};export{b as Observable,c as SafeSubscriber,u as Subscriber,f as operate};
@@ -0,0 +1 @@
1
+ "use strict";var n=Object.defineProperty;var a=Object.getOwnPropertyDescriptor;var l=Object.getOwnPropertyNames;var b=Object.prototype.hasOwnProperty;var f=(t,r)=>{for(var s in r)n(t,s,{get:r[s],enumerable:!0})},h=(t,r,s,i)=>{if(r&&typeof r=="object"||typeof r=="function")for(let e of l(r))!b.call(t,e)&&e!==s&&n(t,e,{get:()=>r[e],enumerable:!(i=a(r,e))||i.enumerable});return t};var p=t=>h(n({},"__esModule",{value:!0}),t);var d={};f(d,{Subscription:()=>c});module.exports=p(d);var u=require("@fluixi/utils/object"),o=require("@fluixi/utils/functions"),c=class t{constructor(r){this._closed=!1;this._parentOrParents=null;this._subscriptions=null;r&&(this._subscriptions=[r])}get closed(){return this._closed}unsubscribe(){if(this._closed)return;this._closed=!0;let{_parentOrParents:r,_subscriptions:s}=this;if(r instanceof t)r.remove(this);else if(r!==null)for(let i of r)i.remove(this);if(s){for(let i of s)if((0,o.isFunction)(i)&&!(i instanceof t))try{i()}catch(e){console.error("Error in unsubscribe function:",e)}else if((0,u.isObject)(i)&&typeof i.unsubscribe=="function")try{i.unsubscribe()}catch(e){console.error("Error unsubscribing child:",e)}this._subscriptions=null}}add(r){if(!r||r===this)return this;if(r.closed)return this;let{_closed:s,_subscriptions:i}=this;if(s){if((0,o.isFunction)(r))try{r()}catch(e){console.error("Error in unsubscribe function:",e)}else if(r.unsubscribe)try{r.unsubscribe()}catch(e){console.error("Error unsubscribing:",e)}return this}return i||(this._subscriptions=[]),this._subscriptions.push(r),r instanceof t&&r._addParent(this),this}remove(r){let{_subscriptions:s}=this;if(!s)return;let i=s.indexOf(r);i!==-1&&(s.splice(i,1),r._removeParent(this))}_addParent(r){let{_parentOrParents:s}=this;s?Array.isArray(s)?s.push(r):this._parentOrParents=[s,r]:this._parentOrParents=r}_removeParent(r){let{_parentOrParents:s}=this;if(s===r)this._parentOrParents=null;else if(Array.isArray(s)){let i=s.indexOf(r);i!==-1&&(s.splice(i,1),s.length===1&&(this._parentOrParents=s[0]))}}};
@@ -0,0 +1,70 @@
1
+ import { SubscriptionLike, Unsubscribable } from './types.js';
2
+ /**
3
+ * Represents a disposable resource, such as the execution of an Observable.
4
+ * This is the primary mechanism for cleaning up Observable executions.
5
+ *
6
+ * @class Subscription
7
+ * @implements {SubscriptionLike}
8
+ *
9
+ * @example
10
+ * // Basic usage
11
+ * const subscription = new Subscription();
12
+ * subscription.add(() => console.log('Cleanup'));
13
+ * subscription.unsubscribe(); // Logs: Cleanup
14
+ *
15
+ * @example
16
+ * // Adding child subscriptions
17
+ * const parent = new Subscription();
18
+ * const child = new Subscription();
19
+ * parent.add(child);
20
+ *
21
+ * // Unsubscribing parent also unsubscribes child
22
+ * parent.unsubscribe();
23
+ * console.log(child.closed); // true
24
+ */
25
+ export declare class Subscription implements SubscriptionLike {
26
+ /** @private */ private _closed;
27
+ /** @private */ private _parentOrParents;
28
+ /** @private */ private _subscriptions;
29
+ /**
30
+ * Creates a new Subscription.
31
+ *
32
+ * @param {Unsubscribable} [unsubscribe] - Optional cleanup function to call on unsubscribe
33
+ */
34
+ constructor(unsubscribe?: Unsubscribable);
35
+ /**
36
+ * Whether the subscription is closed.
37
+ *
38
+ * @returns {boolean} True if the subscription is closed
39
+ */
40
+ get closed(): boolean;
41
+ /**
42
+ * Disposes the resources held by the subscription.
43
+ * May be called multiple times (idempotent).
44
+ *
45
+ * @returns {void}
46
+ */
47
+ unsubscribe(): void;
48
+ /**
49
+ * Adds a child subscription or cleanup function to this subscription.
50
+ * When this subscription is unsubscribed, all added subscriptions/functions will be unsubscribed/called.
51
+ *
52
+ * @param {SubscriptionLike|Unsubscribable} subscription - Subscription or cleanup function to add
53
+ * @returns {Subscription} This subscription for chaining
54
+ *
55
+ * @throws {TypeError} If the argument is not a subscription-like object or function
56
+ */
57
+ add(subscription: SubscriptionLike | Unsubscribable): this;
58
+ /**
59
+ * Removes a child subscription from this subscription.
60
+ *
61
+ * @param {Subscription} subscription - Subscription to remove
62
+ * @returns {void}
63
+ */
64
+ remove(subscription: Subscription): void;
65
+ /** @private */
66
+ private _addParent;
67
+ /** @private */
68
+ private _removeParent;
69
+ }
70
+ //# sourceMappingURL=subscription.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"subscription.d.ts","sourceRoot":"","sources":["../../../src/lib/observable/subscription.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,gBAAgB,EAAiB,cAAc,EAAE,MAAM,YAAY,CAAC;AAE7E;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,qBAAa,YAAa,YAAW,gBAAgB;IACnD,eAAe,CAAC,OAAO,CAAC,OAAO,CAAS;IACxC,eAAe,CAAC,OAAO,CAAC,gBAAgB,CAGxB;IAChB,eAAe,CAAC,OAAO,CAAC,cAAc,CAEtB;IAEhB;;;;OAIG;gBACS,WAAW,CAAC,EAAE,cAAc;IAMxC;;;;OAIG;IACH,IAAI,MAAM,IAAI,OAAO,CAEpB;IAED;;;;;OAKG;IACH,WAAW,IAAI,IAAI;IAuCnB;;;;;;;;OAQG;IACH,GAAG,CAAC,YAAY,EAAE,gBAAgB,GAAG,cAAc,GAAG,IAAI;IA8C1D;;;;;OAKG;IACH,MAAM,CAAC,YAAY,EAAE,YAAY,GAAG,IAAI;IAexC,eAAe;IACf,OAAO,CAAC,UAAU;IAWlB,eAAe;IACf,OAAO,CAAC,aAAa;CActB"}
@@ -0,0 +1,190 @@
1
+ import { isObject } from '@fluixi/utils/object';
2
+ import { isFunction } from '@fluixi/utils/functions';
3
+ /**
4
+ * Represents a disposable resource, such as the execution of an Observable.
5
+ * This is the primary mechanism for cleaning up Observable executions.
6
+ *
7
+ * @class Subscription
8
+ * @implements {SubscriptionLike}
9
+ *
10
+ * @example
11
+ * // Basic usage
12
+ * const subscription = new Subscription();
13
+ * subscription.add(() => console.log('Cleanup'));
14
+ * subscription.unsubscribe(); // Logs: Cleanup
15
+ *
16
+ * @example
17
+ * // Adding child subscriptions
18
+ * const parent = new Subscription();
19
+ * const child = new Subscription();
20
+ * parent.add(child);
21
+ *
22
+ * // Unsubscribing parent also unsubscribes child
23
+ * parent.unsubscribe();
24
+ * console.log(child.closed); // true
25
+ */
26
+ export class Subscription {
27
+ /** @private */ _closed = false;
28
+ /** @private */ _parentOrParents = null;
29
+ /** @private */ _subscriptions = null;
30
+ /**
31
+ * Creates a new Subscription.
32
+ *
33
+ * @param {Unsubscribable} [unsubscribe] - Optional cleanup function to call on unsubscribe
34
+ */
35
+ constructor(unsubscribe) {
36
+ if (unsubscribe) {
37
+ this._subscriptions = [unsubscribe];
38
+ }
39
+ }
40
+ /**
41
+ * Whether the subscription is closed.
42
+ *
43
+ * @returns {boolean} True if the subscription is closed
44
+ */
45
+ get closed() {
46
+ return this._closed;
47
+ }
48
+ /**
49
+ * Disposes the resources held by the subscription.
50
+ * May be called multiple times (idempotent).
51
+ *
52
+ * @returns {void}
53
+ */
54
+ unsubscribe() {
55
+ if (this._closed) {
56
+ return;
57
+ }
58
+ this._closed = true;
59
+ const { _parentOrParents, _subscriptions } = this;
60
+ // Remove from parent
61
+ if (_parentOrParents instanceof Subscription) {
62
+ _parentOrParents.remove(this);
63
+ }
64
+ else if (_parentOrParents !== null) {
65
+ for (const parent of _parentOrParents) {
66
+ parent.remove(this);
67
+ }
68
+ }
69
+ // Unsubscribe all child subscriptions
70
+ if (_subscriptions) {
71
+ for (const sub of _subscriptions) {
72
+ if (isFunction(sub) && !(sub instanceof Subscription)) {
73
+ try {
74
+ sub();
75
+ }
76
+ catch (error) {
77
+ // Don't let errors in cleanup functions break unsubscribe chain
78
+ console.error('Error in unsubscribe function:', error);
79
+ }
80
+ }
81
+ else if (isObject(sub) && typeof sub.unsubscribe === 'function') {
82
+ try {
83
+ sub.unsubscribe();
84
+ }
85
+ catch (error) {
86
+ console.error('Error unsubscribing child:', error);
87
+ }
88
+ }
89
+ }
90
+ this._subscriptions = null;
91
+ }
92
+ }
93
+ /**
94
+ * Adds a child subscription or cleanup function to this subscription.
95
+ * When this subscription is unsubscribed, all added subscriptions/functions will be unsubscribed/called.
96
+ *
97
+ * @param {SubscriptionLike|Unsubscribable} subscription - Subscription or cleanup function to add
98
+ * @returns {Subscription} This subscription for chaining
99
+ *
100
+ * @throws {TypeError} If the argument is not a subscription-like object or function
101
+ */
102
+ add(subscription) {
103
+ if (!subscription || subscription === this) {
104
+ return this;
105
+ }
106
+ // If subscription is already closed, do nothing
107
+ if (subscription.closed) {
108
+ return this;
109
+ }
110
+ let { _closed, _subscriptions } = this;
111
+ // If this subscription is already closed, unsubscribe the added subscription immediately
112
+ if (_closed) {
113
+ if (isFunction(subscription)) {
114
+ try {
115
+ subscription();
116
+ }
117
+ catch (error) {
118
+ console.error('Error in unsubscribe function:', error);
119
+ }
120
+ }
121
+ else if (subscription.unsubscribe) {
122
+ try {
123
+ subscription.unsubscribe();
124
+ }
125
+ catch (error) {
126
+ console.error('Error unsubscribing:', error);
127
+ }
128
+ }
129
+ return this;
130
+ }
131
+ // Initialize subscriptions array if needed
132
+ if (!_subscriptions) {
133
+ this._subscriptions = [];
134
+ }
135
+ // Add to subscriptions array
136
+ this._subscriptions.push(subscription);
137
+ // Set parent reference
138
+ if (subscription instanceof Subscription) {
139
+ subscription._addParent(this);
140
+ }
141
+ return this;
142
+ }
143
+ /**
144
+ * Removes a child subscription from this subscription.
145
+ *
146
+ * @param {Subscription} subscription - Subscription to remove
147
+ * @returns {void}
148
+ */
149
+ remove(subscription) {
150
+ const { _subscriptions } = this;
151
+ if (!_subscriptions) {
152
+ return;
153
+ }
154
+ const index = _subscriptions.indexOf(subscription);
155
+ if (index !== -1) {
156
+ _subscriptions.splice(index, 1);
157
+ // Remove parent reference
158
+ subscription._removeParent(this);
159
+ }
160
+ }
161
+ /** @private */
162
+ _addParent(parent) {
163
+ const { _parentOrParents } = this;
164
+ if (!_parentOrParents) {
165
+ this._parentOrParents = parent;
166
+ }
167
+ else if (Array.isArray(_parentOrParents)) {
168
+ _parentOrParents.push(parent);
169
+ }
170
+ else {
171
+ this._parentOrParents = [_parentOrParents, parent];
172
+ }
173
+ }
174
+ /** @private */
175
+ _removeParent(parent) {
176
+ const { _parentOrParents } = this;
177
+ if (_parentOrParents === parent) {
178
+ this._parentOrParents = null;
179
+ }
180
+ else if (Array.isArray(_parentOrParents)) {
181
+ const index = _parentOrParents.indexOf(parent);
182
+ if (index !== -1) {
183
+ _parentOrParents.splice(index, 1);
184
+ if (_parentOrParents.length === 1) {
185
+ this._parentOrParents = _parentOrParents[0];
186
+ }
187
+ }
188
+ }
189
+ }
190
+ }
@@ -0,0 +1 @@
1
+ import{isObject as c}from"@fluixi/utils/object";import{isFunction as n}from"@fluixi/utils/functions";var o=class t{constructor(r){this._closed=!1;this._parentOrParents=null;this._subscriptions=null;r&&(this._subscriptions=[r])}get closed(){return this._closed}unsubscribe(){if(this._closed)return;this._closed=!0;let{_parentOrParents:r,_subscriptions:s}=this;if(r instanceof t)r.remove(this);else if(r!==null)for(let i of r)i.remove(this);if(s){for(let i of s)if(n(i)&&!(i instanceof t))try{i()}catch(e){console.error("Error in unsubscribe function:",e)}else if(c(i)&&typeof i.unsubscribe=="function")try{i.unsubscribe()}catch(e){console.error("Error unsubscribing child:",e)}this._subscriptions=null}}add(r){if(!r||r===this)return this;if(r.closed)return this;let{_closed:s,_subscriptions:i}=this;if(s){if(n(r))try{r()}catch(e){console.error("Error in unsubscribe function:",e)}else if(r.unsubscribe)try{r.unsubscribe()}catch(e){console.error("Error unsubscribing:",e)}return this}return i||(this._subscriptions=[]),this._subscriptions.push(r),r instanceof t&&r._addParent(this),this}remove(r){let{_subscriptions:s}=this;if(!s)return;let i=s.indexOf(r);i!==-1&&(s.splice(i,1),r._removeParent(this))}_addParent(r){let{_parentOrParents:s}=this;s?Array.isArray(s)?s.push(r):this._parentOrParents=[s,r]:this._parentOrParents=r}_removeParent(r){let{_parentOrParents:s}=this;if(s===r)this._parentOrParents=null;else if(Array.isArray(s)){let i=s.indexOf(r);i!==-1&&(s.splice(i,1),s.length===1&&(this._parentOrParents=s[0]))}}};export{o as Subscription};
@@ -0,0 +1 @@
1
+ "use strict";var t=Object.defineProperty;var v=Object.getOwnPropertyDescriptor;var p=Object.getOwnPropertyNames;var b=Object.prototype.hasOwnProperty;var c=(r,e,n,i)=>{if(e&&typeof e=="object"||typeof e=="function")for(let o of p(e))!b.call(r,o)&&o!==n&&t(r,o,{get:()=>e[o],enumerable:!(i=v(e,o))||i.enumerable});return r};var d=r=>c(t({},"__esModule",{value:!0}),r);var a={};module.exports=d(a);
@@ -0,0 +1,44 @@
1
+ import { Subscription } from "./subscription.js";
2
+ /**
3
+ * Type representing a function that can be called to unsubscribe from an Observable.
4
+ *
5
+ * @typedef {function(): void} Unsubscribable
6
+ */
7
+ export type Unsubscribable = () => void;
8
+ /**
9
+ * Type representing any object that can be unsubscribed.
10
+ *
11
+ * @interface SubscriptionLike
12
+ * @property {boolean} closed - Whether the subscription is closed
13
+ * @property {function(): void} unsubscribe - Function to unsubscribe
14
+ */
15
+ export interface SubscriptionLike {
16
+ closed: boolean;
17
+ unsubscribe(): void;
18
+ }
19
+ export type TeardownLogic = Subscription | Unsubscribable | (() => void) | void;
20
+ /**
21
+ * Next observer in a chain
22
+ */
23
+ export interface NextObserver<T> {
24
+ next: (value: T) => void;
25
+ error?: (error: any) => void;
26
+ complete?: () => void;
27
+ }
28
+ /**
29
+ * Error observer in a chain
30
+ */
31
+ export interface ErrorObserver<T> {
32
+ next?: (value: T) => void;
33
+ error: (error: any) => void;
34
+ complete?: () => void;
35
+ }
36
+ /**
37
+ * Completion observer in a chain
38
+ */
39
+ export interface CompletionObserver<T> {
40
+ next?: (value: T) => void;
41
+ error?: (error: any) => void;
42
+ complete: () => void;
43
+ }
44
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/lib/observable/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAEjD;;;;GAIG;AACH,MAAM,MAAM,cAAc,GAAG,MAAM,IAAI,CAAC;AAExC;;;;;;GAMG;AACH,MAAM,WAAW,gBAAgB;IAC7B,MAAM,EAAE,OAAO,CAAC;IAChB,WAAW,IAAI,IAAI,CAAC;CACvB;AAGD,MAAM,MAAM,aAAa,GAAG,YAAY,GAAG,cAAc,GAAG,CAAC,MAAM,IAAI,CAAC,GAAG,IAAI,CAAC;AAG9E;;GAEG;AACH,MAAM,WAAW,YAAY,CAAC,CAAC;IAC7B,IAAI,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,IAAI,CAAC;IACzB,KAAK,CAAC,EAAE,CAAC,KAAK,EAAE,GAAG,KAAK,IAAI,CAAC;IAC7B,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAC;CACvB;AAED;;GAEG;AACH,MAAM,WAAW,aAAa,CAAC,CAAC;IAC9B,IAAI,CAAC,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,IAAI,CAAC;IAC1B,KAAK,EAAE,CAAC,KAAK,EAAE,GAAG,KAAK,IAAI,CAAC;IAC5B,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAC;CACvB;AAED;;GAEG;AACH,MAAM,WAAW,kBAAkB,CAAC,CAAC;IACnC,IAAI,CAAC,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,IAAI,CAAC;IAC1B,KAAK,CAAC,EAAE,CAAC,KAAK,EAAE,GAAG,KAAK,IAAI,CAAC;IAC7B,QAAQ,EAAE,MAAM,IAAI,CAAC;CACtB"}
@@ -0,0 +1 @@
1
+ export {};
File without changes