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