@superutils/rx 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js ADDED
@@ -0,0 +1,636 @@
1
+ // src/asPromise.ts
2
+ import {
3
+ fallbackIfFails,
4
+ isError,
5
+ isFn,
6
+ isObj,
7
+ isPositiveNumber,
8
+ isSubjectLike
9
+ } from "@superutils/core";
10
+ import PromisE, {
11
+ TIMEOUT_MAX
12
+ } from "@superutils/promise";
13
+
14
+ // src/rxjs.ts
15
+ import {
16
+ BehaviorSubject,
17
+ isObservable,
18
+ skip,
19
+ Subject,
20
+ Subscription
21
+ } from "rxjs";
22
+
23
+ // src/asPromise.ts
24
+ var asPromise = (subject, expectedValue, timeoutOrOptions) => {
25
+ if (!isSubjectLike(subject) && !isObservable(subject))
26
+ return PromisE.reject(
27
+ new Error("subject must be an instance of BehaviorSubject")
28
+ );
29
+ let subscription;
30
+ const options = isObj(timeoutOrOptions) ? timeoutOrOptions : { timeout: timeoutOrOptions };
31
+ options.timeout = isPositiveNumber(options.timeout) ? options.timeout : TIMEOUT_MAX;
32
+ const promise = PromisE.timeout(
33
+ {
34
+ ...options,
35
+ onTimeout: async () => {
36
+ const { onTimeout, timeoutMsg } = options;
37
+ const msg = await fallbackIfFails(onTimeout, [], void 0);
38
+ return msg != null ? msg : isError(timeoutMsg) ? timeoutMsg : new Error(
39
+ timeoutMsg != null ? timeoutMsg : "request timed out before an expected value is received"
40
+ );
41
+ }
42
+ },
43
+ new PromisE((resolve) => {
44
+ subscription = subject.subscribe((value) => {
45
+ const shouldResolve = value === expectedValue || expectedValue === void 0 || isFn(expectedValue) && fallbackIfFails(expectedValue, [value], false);
46
+ shouldResolve && resolve(value);
47
+ });
48
+ })
49
+ );
50
+ promise.onFinalize.push(() => {
51
+ var _a;
52
+ (_a = subscription == null ? void 0 : subscription.unsubscribe) == null ? void 0 : _a.call(subscription);
53
+ });
54
+ return promise;
55
+ };
56
+
57
+ // src/copyRxSubject.ts
58
+ import {
59
+ deferred,
60
+ fallbackIfFails as fallbackIfFails2,
61
+ isArr,
62
+ isFn as isFn4,
63
+ isPositiveNumber as isPositiveNumber2
64
+ } from "@superutils/core";
65
+
66
+ // src/isSubjectLike.ts
67
+ import { isSubjectLike as _isSubjectLike } from "@superutils/core";
68
+ var isSubjectLike2 = (x, withValue = false) => _isSubjectLike(x, withValue);
69
+ var isSubjectLike_default = isSubjectLike2;
70
+
71
+ // src/unsubscribeAll.ts
72
+ import { isFn as isFn3 } from "@superutils/core";
73
+
74
+ // src/isSubscriptionLike.ts
75
+ import { isBool, isFn as isFn2 } from "@superutils/core";
76
+ var isSubscriptionLike = (value, strict = false) => {
77
+ if (value instanceof Subscription) return true;
78
+ const sub = value;
79
+ return !strict && !!sub && isBool(sub.closed) && isFn2(sub.unsubscribe);
80
+ };
81
+ var isSubscriptionLike_default = isSubscriptionLike;
82
+
83
+ // src/unsubscribeAll.ts
84
+ var unsubscribeAll = (unsub = {}, onError) => {
85
+ if (!unsub) return;
86
+ try {
87
+ if (isFn3(unsub)) return unsub();
88
+ if (isSubscriptionLike_default(unsub)) return unsub.unsubscribe();
89
+ Object.values(unsub).forEach(
90
+ (value) => unsubscribeAll(value, onError)
91
+ );
92
+ } catch (err) {
93
+ onError == null ? void 0 : onError(err);
94
+ }
95
+ };
96
+ var unsubscribeAll_default = unsubscribeAll;
97
+
98
+ // src/copyRxSubject.ts
99
+ var IGNORE_UPDATE_SYMBOL = /* @__PURE__ */ Symbol("ignore-rx-update");
100
+ function copyRxSubject(source$, copy$, valueModifier, options) {
101
+ var _a;
102
+ copy$ = isSubjectLike_default(copy$) ? copy$ : new BehaviorSubject(void 0);
103
+ options = {
104
+ ...copyRxSubject.defaults,
105
+ ...options != null ? options : {}
106
+ };
107
+ const sourceArr = isSubjectLike_default(source$) ? [source$] : isArr(source$) ? source$ : [source$];
108
+ const cache = new Map(
109
+ sourceArr.map((subject, i) => [
110
+ i,
111
+ isSubjectLike_default(subject) ? subject.value : subject
112
+ // fixed value provided
113
+ ])
114
+ );
115
+ const triggerChange = () => {
116
+ const currentValue = isArr(source$) ? [...cache.values()] : cache.get(0);
117
+ if (!isFn4(valueModifier)) return copy$.next(currentValue);
118
+ const modifiedValue = fallbackIfFails2(
119
+ valueModifier,
120
+ [currentValue, void 0, copy$],
121
+ (err) => {
122
+ var _a2;
123
+ fallbackIfFails2(
124
+ (_a2 = options.onError) == null ? void 0 : _a2.bind(options.thisArg),
125
+ [err],
126
+ void 0
127
+ );
128
+ return IGNORE_UPDATE_SYMBOL;
129
+ }
130
+ );
131
+ modifiedValue !== IGNORE_UPDATE_SYMBOL && copy$.next(modifiedValue);
132
+ };
133
+ const triggerChangeDeferred = isPositiveNumber2(options.delay) ? deferred(triggerChange, options.delay, options) : triggerChange;
134
+ const subscriptions = sourceArr.map((subject, i) => {
135
+ if (!isSubjectLike_default(subject) || subject.closed) return;
136
+ return (subject instanceof BehaviorSubject ? subject.pipe(
137
+ skip(1)
138
+ // skip initial value
139
+ ) : subject).subscribe((newValue) => {
140
+ cache.set(i, newValue);
141
+ triggerChangeDeferred();
142
+ });
143
+ }).filter(Boolean);
144
+ const unsubscribeOrg = (_a = copy$ == null ? void 0 : copy$.unsubscribe) == null ? void 0 : _a.bind(copy$);
145
+ copy$.unsubscribe = (...args) => {
146
+ unsubscribeOrg == null ? void 0 : unsubscribeOrg(...args);
147
+ unsubscribeAll(subscriptions);
148
+ cache.clear();
149
+ };
150
+ triggerChange();
151
+ return copy$;
152
+ }
153
+ copyRxSubject.defaults = {
154
+ delay: 0,
155
+ throttle: false
156
+ };
157
+ copyRxSubject.IGNORE_UPDATE_SYMBOL = IGNORE_UPDATE_SYMBOL;
158
+
159
+ // src/data-storage/DataStorage.ts
160
+ import {
161
+ deferred as deferred2,
162
+ fallbackIfFails as fallbackIfFails3,
163
+ filter,
164
+ find,
165
+ getEntries,
166
+ getKeys,
167
+ isArr as isArr2,
168
+ isFn as isFn5,
169
+ isMap,
170
+ isPositiveNumber as isPositiveNumber3,
171
+ isStr,
172
+ mapJoin,
173
+ search,
174
+ sort
175
+ } from "@superutils/core";
176
+ var forceUpdateCache$ = new Subject();
177
+ var DataStorage = class {
178
+ /**
179
+ * A wrapper for reading and writing to LocalStorage (browser) or JSON files (NodeJS),
180
+ * providing a Map-like interface with advanced features like search, filtering, and sorting.
181
+ *
182
+ * #### Notes:
183
+ * - **Performance**: `DataStorage` is optimized for small to medium datasets.
184
+ * - For datasets > 1MB, consider increasing the `delay` option to reduce write frequency.
185
+ * - It is **NOT** recommended for datasets larger than 3MB due to synchronous serialization costs.
186
+ * - **RxJS Integration**: Built on RxJS for reactive data handling, though no prior RxJS knowledge is required.
187
+ * - **Storage Behavior**:
188
+ * - If `name` is omitted, the instance operates in-memory only and data is not persisted to storage.
189
+ * - If `cacheDisabled` is `true`, data is not kept in memory; every read/write operation accesses the underlying
190
+ * storage directly.
191
+ *
192
+ * @example
193
+ * #### Browser Usage
194
+ * ```javascript
195
+ * import { DataStorage } from '@superutils/rx'
196
+ * import fetch from '@superutils/fetch'
197
+ *
198
+ * const storage = new DataStorage('products')
199
+ * const { products } = await fetch('[DUMMYJSON-DOT-COM]/products')
200
+ * // save all items to storage
201
+ * storage.setAll(
202
+ * new Map(products.map(p => [p.id, p])), // convert to Map
203
+ * )
204
+ *
205
+ * // print product with id `1`
206
+ * console.log(storage.get(1))
207
+ *
208
+ * // search for items
209
+ * const searchResult = storage.search({
210
+ * query: { availabilityStatus: 'low' }
211
+ * })
212
+ * console.log(searchResult)
213
+ * ```
214
+ * @example
215
+ * #### NodeJS Usage
216
+ * ```javascript
217
+ * import { DataStorage } from '@superutils/rx'
218
+ * import fetch from '@superutils/fetch'
219
+ * import { LocalStorage } from 'node-localstorage'
220
+ *
221
+ * // Add localStorage alternative for NodeJS that reads and writes to JSON files.
222
+ * // This is not necessary for browsers.
223
+ * globalThis.localStorage = new LocalStorage('./data', 1e7)
224
+ *
225
+ * const storage = new DataStorage('products')
226
+ * const { products } = await fetch('[DUMMYJSON-DOT-COM]/products')
227
+ * // save all items to storage
228
+ * storage.setAll(
229
+ * new Map(products.map(p => [p.id, p])), // convert to Map
230
+ * )
231
+ *
232
+ * // print product with id `1`
233
+ * console.log(storage.get(1))
234
+ *
235
+ * // search for items
236
+ * const searchResult = storage.search({
237
+ * query: { availabilityStatus: 'low' }
238
+ * })
239
+ * console.log(searchResult)
240
+ * ```
241
+ *
242
+ * @example
243
+ * #### Advanced: `onChange` and RxJS subject
244
+ *
245
+ * Internally, `DataStorage` uses RxJS subject which is exposed as `subject` property.
246
+ * You can use this to subscribe to changes and do additional operations such as logging or sanitization etc.
247
+ *
248
+ * Alternatively, you can also set the `onChange` callback which is triggered whenever the subject changes and
249
+ * does not require maintaining a subscription or knowledge of RxJS subject.
250
+ *
251
+ * ```javascript
252
+ * import { DataStorage } from '@superutils/rx'
253
+ *
254
+ * const storage = new DataStorage('my-data')
255
+ * const sub = storage.subject.subscribe(data => {
256
+ * // Write to the database whenever data changes
257
+ * console.log('Saving to database...', data)
258
+ * })
259
+ * // unsubscribe from subject
260
+ * setTimeout(()=> sub.unsbuscribe(), 1000)
261
+ *
262
+ * // add an entry to storage
263
+ * storage.set('bob', { age: 99, id: 'bob', name: 'Bob' })
264
+ * ```
265
+ */
266
+ constructor(name, options) {
267
+ /** Debounce and throttle related options */
268
+ // readonly deferOptions
269
+ this.initialized = false;
270
+ this.subscriptions = {
271
+ subject: void 0,
272
+ forceUpdateCache: void 0
273
+ };
274
+ this.clear = () => {
275
+ this.setAll(/* @__PURE__ */ new Map(), true);
276
+ return this;
277
+ };
278
+ this.delete = (keys) => {
279
+ if (!isArr2(keys)) keys = [keys];
280
+ const data = this.getAll();
281
+ for (const k of keys) data.delete(k);
282
+ this.setAll(data, true);
283
+ return this;
284
+ };
285
+ this.find = (predicateOrOptions) => find(this.getAll(), predicateOrOptions);
286
+ this.filter = (predicate, limit, asArray, result) => filter(this.getAll(), predicate, limit, asArray, result);
287
+ this.get = (key) => this.getAll().get(key);
288
+ this.getAll = (forceRead = false) => {
289
+ var _a;
290
+ const wasInitialized = this.initialized;
291
+ if (!wasInitialized) this.init();
292
+ const readFromStorage = this.cacheDisabled || this.name && forceRead;
293
+ if (readFromStorage) {
294
+ const data = this.read();
295
+ const shouldTrigger = forceRead || !wasInitialized && !!data.size;
296
+ shouldTrigger && this.subject.next(data);
297
+ return data;
298
+ }
299
+ return (_a = this.subject) == null ? void 0 : _a.value;
300
+ };
301
+ this.has = (key) => this.getAll().has(key);
302
+ this.init = (initialValue) => {
303
+ var _a, _b;
304
+ if (this.initialized) return false;
305
+ this.initialized = true;
306
+ this.subject instanceof BehaviorSubject && this.subject.next(this.read());
307
+ unsubscribeAll_default(this.subscriptions);
308
+ if (!this.cacheDisabled) {
309
+ this.subscriptions.forceUpdateCache = forceUpdateCache$.subscribe(
310
+ (refresh) => {
311
+ const doRefresh = !this.name ? false : isArr2(refresh) ? refresh.includes(this.name) : isStr(refresh) ? refresh === this.name : refresh === true;
312
+ if (!doRefresh) return;
313
+ const newData = this.read();
314
+ this.subject.next(newData);
315
+ }
316
+ );
317
+ }
318
+ !((_b = (_a = this.subject) == null ? void 0 : _a.value) == null ? void 0 : _b.size) && isMap(initialValue) && !!(initialValue == null ? void 0 : initialValue.size) && this.setAll(initialValue);
319
+ const piped = this.subject.pipe(
320
+ skip(this.cacheDisabled || !!(initialValue == null ? void 0 : initialValue.size) ? 0 : 1)
321
+ );
322
+ let handleChange = (data) => {
323
+ if (!isMap(data)) return this.subject.next(/* @__PURE__ */ new Map());
324
+ this.write(data);
325
+ fallbackIfFails3(
326
+ async () => {
327
+ var _a2;
328
+ return await ((_a2 = this.onChange) == null ? void 0 : _a2.call(this, data));
329
+ },
330
+ [],
331
+ this.triggerOnError("onChange")
332
+ );
333
+ };
334
+ if (this.delay > 0)
335
+ handleChange = deferred2(handleChange, this.delay, this.delayOptions);
336
+ this.subscriptions.subject = piped.subscribe(handleChange);
337
+ return true;
338
+ };
339
+ this.keys = () => getKeys(this.getAll());
340
+ this.map = (callback) => this.toArray().map(
341
+ ([key, value], index, data) => callback(value, key, data, index)
342
+ );
343
+ this.read = () => {
344
+ var _a, _b;
345
+ const dataStr = (_b = (_a = this.storage) == null ? void 0 : _a.getItem(this.name)) != null ? _b : "[]";
346
+ const data = isFn5(this.parse) && fallbackIfFails3(
347
+ this.parse,
348
+ [dataStr],
349
+ this.triggerOnError("parse")
350
+ );
351
+ if (isMap(data)) return data;
352
+ return new Map(
353
+ fallbackIfFails3(
354
+ () => JSON.parse(dataStr),
355
+ [],
356
+ this.triggerOnError("parse-json")
357
+ )
358
+ );
359
+ };
360
+ this.search = (options) => search(this.getAll(), options);
361
+ this.set = (key, value) => {
362
+ this.setAll(/* @__PURE__ */ new Map([[key, value]]), false);
363
+ return this;
364
+ };
365
+ this.setAll = (data = /* @__PURE__ */ new Map(), replace = false) => {
366
+ if (!isMap(data)) return this;
367
+ data = replace ? data : mapJoin(this.getAll(), data);
368
+ this.subject.next(new Map(data));
369
+ return this;
370
+ };
371
+ this.sort = ((nameOrComparator, options) => {
372
+ const result = sort(
373
+ this.getAll(),
374
+ nameOrComparator,
375
+ options
376
+ );
377
+ (options == null ? void 0 : options.save) && this.setAll(result, true);
378
+ return result;
379
+ });
380
+ this.toArray = () => getEntries(this.getAll());
381
+ this.toJSON = (replacer, spacing = this.spaces, data = this.getAll()) => {
382
+ const arr = Array.from(data);
383
+ const str = fallbackIfFails3(
384
+ () => {
385
+ var _a;
386
+ return (_a = this.stringify) == null ? void 0 : _a.call(this, data);
387
+ },
388
+ [],
389
+ this.triggerOnError("stringify")
390
+ );
391
+ if (isStr(str)) return str;
392
+ return fallbackIfFails3(
393
+ () => JSON.stringify(arr, replacer, spacing),
394
+ [],
395
+ this.triggerOnError("stringify-json")
396
+ );
397
+ };
398
+ this.toString = (data) => this.toJSON(void 0, void 0, data);
399
+ this.triggerOnError = (type) => (err) => {
400
+ this.onError && fallbackIfFails3(this.onError, [err, type], "");
401
+ };
402
+ this.unsubscribe = () => unsubscribeAll_default(this.subscriptions);
403
+ this.values = () => [...this.getAll().values()];
404
+ this.write = (data) => {
405
+ try {
406
+ !this.initialized && this.init();
407
+ data != null ? data : data = this.subject.value;
408
+ if (!this.name || !this.storage || !isMap(data)) return false;
409
+ this.storage.setItem(this.name, this.toString(data));
410
+ return true;
411
+ } catch (err) {
412
+ this.triggerOnError("write")(err);
413
+ return false;
414
+ }
415
+ };
416
+ const {
417
+ cacheDisabled = false,
418
+ delay,
419
+ delayOptions,
420
+ initialValue,
421
+ onError,
422
+ onChange,
423
+ parse,
424
+ spaces,
425
+ storage,
426
+ stringify
427
+ } = options != null ? options : {};
428
+ this.delay = cacheDisabled ? 0 : delay === 0 || isPositiveNumber3(delay) ? delay : 300;
429
+ this.name = `${name != null ? name : ""}`.trim();
430
+ this.onError = onError;
431
+ this.onChange = onChange;
432
+ this.parse = parse;
433
+ this.storage = storage === null ? null : storage != null ? storage : fallbackIfFails3(
434
+ () => globalThis.localStorage,
435
+ [],
436
+ void 0
437
+ );
438
+ if (this.name && !this.storage)
439
+ throw new Error(
440
+ "options.storage: LocalStorage instance or equivalent required"
441
+ );
442
+ this.cacheDisabled = !!this.storage && cacheDisabled;
443
+ this.stringify = stringify;
444
+ this.spaces = spaces;
445
+ this.subject = this.cacheDisabled ? new Subject() : new BehaviorSubject(void 0);
446
+ this.delayOptions = delayOptions;
447
+ isMap(initialValue) && initialValue.size && this.init(initialValue);
448
+ }
449
+ get size() {
450
+ return this.getAll().size;
451
+ }
452
+ };
453
+ /**
454
+ * Trigger forced update of cached data from storage.
455
+ *
456
+ * @param name determines which storage instances to be updated.
457
+ * - name (`string` | `string[]`): update all instances with a specific name(s)
458
+ * - global (`true`): update all instances globally
459
+ *
460
+ * @example
461
+ * ```javascript
462
+ * import { DataStorage } from '@superutils/rx'
463
+ *
464
+ * // Update all DataStorage instances with specific name(s)
465
+ * const name = 'products'
466
+ * DataStorage.forceUpdateCache([name])
467
+ *
468
+ * // Update every single instance of DataStorage that uses storage (has a "name")
469
+ * DataStorage.forceUpdateCache(true)
470
+ * ```
471
+ */
472
+ DataStorage.forceUpdateCache = (name) => {
473
+ forceUpdateCache$.next(name);
474
+ };
475
+
476
+ // src/IntervalSubject.ts
477
+ var IntervalSubject = class extends BehaviorSubject {
478
+ constructor(autoStart, _delay = 1e3, initialValue = 0, incrementBy = 1) {
479
+ super(initialValue);
480
+ this.autoStart = autoStart;
481
+ this._delay = _delay;
482
+ this.initialValue = initialValue;
483
+ this.incrementBy = incrementBy;
484
+ this._running = false;
485
+ this.pause = () => {
486
+ clearInterval(this._intervalId);
487
+ this._running = false;
488
+ return this;
489
+ };
490
+ this.resume = () => this.start();
491
+ this.start = () => {
492
+ if (!this._running) {
493
+ this._running = true;
494
+ this._intervalId = setInterval(
495
+ () => this.next(this.value + this.incrementBy),
496
+ this._delay
497
+ );
498
+ }
499
+ return this;
500
+ };
501
+ this.stop = () => {
502
+ this.pause();
503
+ this.next(0);
504
+ return this;
505
+ };
506
+ this.autoStart && this.start();
507
+ }
508
+ get delay() {
509
+ return this._delay;
510
+ }
511
+ set delay(newDelay) {
512
+ if (!this._running) this._delay = newDelay;
513
+ }
514
+ get running() {
515
+ return this._running;
516
+ }
517
+ };
518
+
519
+ // src/IntervalRunner.ts
520
+ import { fallbackIfFails as fallbackIfFails4, noop } from "@superutils/core";
521
+ var IntervalRunner = class {
522
+ constructor(taskFn, taskArgs, intervalMs, sequential = true, preExecute = true) {
523
+ this.taskFn = taskFn;
524
+ this.taskArgs = taskArgs;
525
+ this.sequential = sequential;
526
+ this.preExecute = preExecute;
527
+ this.minIntervalMs = 1e3;
528
+ this.runCount = 0;
529
+ this.started = false;
530
+ this.clearInterval = () => {
531
+ this.sequential ? clearTimeout(this.idInterval) : clearInterval(this.idInterval);
532
+ this.idInterval = void 0;
533
+ };
534
+ this.executeTask = async (once = false) => {
535
+ var _a;
536
+ let err;
537
+ let result;
538
+ if (this.sequential || once) this.clearInterval();
539
+ try {
540
+ ++this.runCount;
541
+ await ((_a = this.onBeforeExec) == null ? void 0 : _a.call(this, this.runCount, once));
542
+ result = await this.taskFn.apply(void 0, this.taskArgs);
543
+ this.lastResult = result;
544
+ } catch (_err) {
545
+ err = _err;
546
+ }
547
+ fallbackIfFails4(
548
+ this.onResult,
549
+ [err != null ? err : null, result, this.runCount, once],
550
+ void 0
551
+ );
552
+ if (!once && this.sequential && this.intervalMs$.value > this.minIntervalMs) {
553
+ this.idInterval = setTimeout(
554
+ this.executeTask,
555
+ this.intervalMs$.value
556
+ );
557
+ }
558
+ return this.lastResult;
559
+ };
560
+ /** Execute the task function regardless of the interval runner state */
561
+ this.executeOnce = async () => await this.executeTask(true);
562
+ /** Check if interval is running*/
563
+ this.isStarted = () => this.started;
564
+ /**
565
+ * Restart interval
566
+ *
567
+ * @param resetRunCount (optional) whether to reset run count
568
+ *
569
+ * @returns {Boolean} indicates whether restart was successful
570
+ */
571
+ this.restart = (resetRunCount = false) => {
572
+ if (!this.onResult) return false;
573
+ this.stop(resetRunCount);
574
+ this.start(this.onResult, this.onBeforeExec);
575
+ return true;
576
+ };
577
+ /**
578
+ * @summary set `onResult` & `onBeforeExec` callbacks and start execution.
579
+ *
580
+ * If it's already running, the callbacks will be used on the next execution.
581
+ *
582
+ * In order to start using callbacks immediately, invoke the `intervalRunner.stop()` function first.
583
+ *
584
+ * @returns {Boolean} indicates whether starting interveral waa successful
585
+ */
586
+ this.start = (onResult, onBeforeExec) => {
587
+ if (!onResult) return false;
588
+ this.onResult = onResult;
589
+ this.onBeforeExec = onBeforeExec;
590
+ if (this.started) return false;
591
+ this.started = true;
592
+ let delayMs;
593
+ this.subscription = this.intervalMs$.subscribe((newDelayMs) => {
594
+ var _a;
595
+ if (delayMs === newDelayMs && newDelayMs !== void 0) return;
596
+ delayMs = Math.max((_a = newDelayMs != null ? newDelayMs : delayMs) != null ? _a : 0, this.minIntervalMs);
597
+ this.clearInterval();
598
+ const preExec = this.lastResult === void 0 && this.preExecute;
599
+ preExec && this.executeTask().catch(noop);
600
+ this.idInterval = !this.sequential ? setInterval(this.executeTask, delayMs) : !preExec ? setTimeout(this.executeTask, delayMs) : void 0;
601
+ });
602
+ return true;
603
+ };
604
+ /**
605
+ * Stop interval runner
606
+ *
607
+ * @param resetRunCount (optional) whether to reset the run counter
608
+ */
609
+ this.stop = (resetRunCount = false) => {
610
+ var _a, _b;
611
+ if (resetRunCount) this.runCount = 0;
612
+ this.started = false;
613
+ (_b = (_a = this.subscription) == null ? void 0 : _a.unsubscribe) == null ? void 0 : _b.call(_a);
614
+ this.clearInterval();
615
+ return this;
616
+ };
617
+ this.intervalMs$ = intervalMs instanceof BehaviorSubject ? intervalMs : new BehaviorSubject(intervalMs);
618
+ }
619
+ };
620
+ export {
621
+ BehaviorSubject,
622
+ DataStorage,
623
+ IGNORE_UPDATE_SYMBOL,
624
+ IntervalRunner,
625
+ IntervalSubject,
626
+ Subject,
627
+ Subscription,
628
+ asPromise,
629
+ copyRxSubject,
630
+ forceUpdateCache$,
631
+ isObservable,
632
+ isSubjectLike2 as isSubjectLike,
633
+ isSubscriptionLike,
634
+ skip,
635
+ unsubscribeAll
636
+ };
package/package.json ADDED
@@ -0,0 +1,53 @@
1
+ {
2
+ "author": "Toufiqur Rahaman Chowdhury",
3
+ "description": "RxJS utilities and hooks for React applications.",
4
+ "dependencies": {
5
+ "@superutils/core": "^1.2.8",
6
+ "@superutils/promise": "^1.3.6",
7
+ "@types/react": "^18.0.0",
8
+ "react": ">=16.8.0",
9
+ "rxjs": "^7.8.2"
10
+ },
11
+ "files": [
12
+ "dist",
13
+ "README.md",
14
+ "LICENSE"
15
+ ],
16
+ "keywords": [
17
+ "rxjs",
18
+ "utils",
19
+ "typescript",
20
+ "react",
21
+ "hooks"
22
+ ],
23
+ "license": "MIT",
24
+ "name": "@superutils/rx",
25
+ "peerDependencies": {
26
+ "@superutils/core": "latest",
27
+ "@superutils/promise": "latest"
28
+ },
29
+ "publishConfig": {
30
+ "access": "public"
31
+ },
32
+ "scripts": {
33
+ "_build": "tsc -p tsconfig.json",
34
+ "_watch": "tsc -p tsconfig.json --watch",
35
+ "build": "tsup --config ../../tsup.config.js",
36
+ "dev": "npm run build -- --watch",
37
+ "start": "npm run dev",
38
+ "test": "cd ../../ && npm run test rx"
39
+ },
40
+ "sideEffects": false,
41
+ "exports": {
42
+ ".": {
43
+ "types": "./dist/index.d.ts",
44
+ "import": "./dist/index.js",
45
+ "require": "./dist/index.cjs"
46
+ }
47
+ },
48
+ "main": "./dist/index.cjs",
49
+ "module": "./dist/index.js",
50
+ "type": "module",
51
+ "types": "./dist/index.d.ts",
52
+ "version": "0.1.1"
53
+ }