@superutils/rx 0.1.17 → 0.1.18
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/browser/index.min.js +2 -2
- package/dist/browser/index.min.js.map +1 -1
- package/dist/index.cjs +20 -13
- package/dist/index.d.cts +62 -26
- package/dist/index.d.ts +62 -26
- package/dist/index.js +21 -14
- package/package.json +4 -4
package/dist/index.cjs
CHANGED
|
@@ -241,7 +241,7 @@ var IntervalRunner = class {
|
|
|
241
241
|
this.sequential = sequential;
|
|
242
242
|
this.preExecute = preExecute;
|
|
243
243
|
this.minIntervalMs = 1e3;
|
|
244
|
-
this.
|
|
244
|
+
this._runCount = 0;
|
|
245
245
|
this.started = false;
|
|
246
246
|
this.clearInterval = () => {
|
|
247
247
|
this.sequential ? clearTimeout(this.idInterval) : clearInterval(this.idInterval);
|
|
@@ -253,16 +253,18 @@ var IntervalRunner = class {
|
|
|
253
253
|
let result;
|
|
254
254
|
if (this.sequential || once) this.clearInterval();
|
|
255
255
|
try {
|
|
256
|
-
++this.
|
|
257
|
-
await ((_a = this.onBeforeExec) == null ? void 0 : _a.call(this, this.
|
|
258
|
-
result = await this.taskFn
|
|
256
|
+
++this._runCount;
|
|
257
|
+
await ((_a = this.onBeforeExec) == null ? void 0 : _a.call(this, this._runCount, once));
|
|
258
|
+
result = await this.taskFn(
|
|
259
|
+
...(0, import_core5.isFn)(this.taskArgs) ? this.taskArgs.call(this, this._runCount) : this.taskArgs
|
|
260
|
+
);
|
|
259
261
|
this.lastResult = result;
|
|
260
262
|
} catch (_err) {
|
|
261
263
|
err = _err;
|
|
262
264
|
}
|
|
263
265
|
(0, import_core5.fallbackIfFails)(
|
|
264
266
|
this.onResult,
|
|
265
|
-
[err != null ? err : null, result, this.
|
|
267
|
+
[err != null ? err : null, result, this._runCount, once],
|
|
266
268
|
void 0
|
|
267
269
|
);
|
|
268
270
|
if (!once && this.sequential && this.intervalMs$.value > this.minIntervalMs) {
|
|
@@ -273,7 +275,7 @@ var IntervalRunner = class {
|
|
|
273
275
|
}
|
|
274
276
|
return this.lastResult;
|
|
275
277
|
};
|
|
276
|
-
/**
|
|
278
|
+
/** Executes the task function once, regardless of the interval runner's current state. */
|
|
277
279
|
this.executeOnce = async () => await this.executeTask(true);
|
|
278
280
|
/** Check if interval is running*/
|
|
279
281
|
this.isStarted = () => this.started;
|
|
@@ -291,18 +293,19 @@ var IntervalRunner = class {
|
|
|
291
293
|
return true;
|
|
292
294
|
};
|
|
293
295
|
/**
|
|
294
|
-
*
|
|
295
|
-
*
|
|
296
|
-
* If it's already running, the callbacks will be used on the next execution.
|
|
296
|
+
* Sets the `onResult` and `onBeforeExec` callbacks and starts the interval execution.
|
|
297
297
|
*
|
|
298
|
+
* If the runner is already started, the new callbacks will be used for subsequent executions.
|
|
299
|
+
* To apply new callbacks immediately, call `stop()` first, then `start()`.
|
|
298
300
|
* In order to start using callbacks immediately, invoke the `intervalRunner.stop()` function first.
|
|
299
301
|
*
|
|
302
|
+
* @param onResult (optional) function to be invoked whenever the task is succefully executed. See {@link OnResultType}
|
|
303
|
+
*
|
|
300
304
|
* @returns {Boolean} indicates whether starting interveral waa successful
|
|
301
305
|
*/
|
|
302
306
|
this.start = (onResult, onBeforeExec) => {
|
|
303
|
-
if (
|
|
304
|
-
this.
|
|
305
|
-
this.onBeforeExec = onBeforeExec;
|
|
307
|
+
if (onResult) this.onResult = onResult;
|
|
308
|
+
if (onBeforeExec) this.onBeforeExec = onBeforeExec;
|
|
306
309
|
if (this.started) return false;
|
|
307
310
|
this.started = true;
|
|
308
311
|
let delayMs;
|
|
@@ -324,7 +327,7 @@ var IntervalRunner = class {
|
|
|
324
327
|
*/
|
|
325
328
|
this.stop = (resetRunCount = false) => {
|
|
326
329
|
var _a, _b;
|
|
327
|
-
if (resetRunCount) this.
|
|
330
|
+
if (resetRunCount) this._runCount = 0;
|
|
328
331
|
this.started = false;
|
|
329
332
|
(_b = (_a = this.subscription) == null ? void 0 : _a.unsubscribe) == null ? void 0 : _b.call(_a);
|
|
330
333
|
this.clearInterval();
|
|
@@ -332,6 +335,10 @@ var IntervalRunner = class {
|
|
|
332
335
|
};
|
|
333
336
|
this.intervalMs$ = intervalMs instanceof import_rxjs5.BehaviorSubject ? intervalMs : new import_rxjs5.BehaviorSubject(intervalMs);
|
|
334
337
|
}
|
|
338
|
+
/** Get number of times task has ran, excluding resets */
|
|
339
|
+
get runCount() {
|
|
340
|
+
return this._runCount;
|
|
341
|
+
}
|
|
335
342
|
};
|
|
336
343
|
// Annotate the CommonJS export names for ESM import in node:
|
|
337
344
|
0 && (module.exports = {
|
package/dist/index.d.cts
CHANGED
|
@@ -178,7 +178,7 @@ output: Observable<TOut>) => ValueOrPromise<TOut> | typeof IGNORE_UPDATE_SYMBOL;
|
|
|
178
178
|
* )
|
|
179
179
|
* ```
|
|
180
180
|
*/
|
|
181
|
-
declare function copyRx<TOut, Source$ extends Observable<any> | unknown[] = Observable<any> | unknown[], TIn = UnwrapSourceValueStrict<Source$>, Copy$ extends BehaviorSubject<TOut> | Subject<TOut> = BehaviorSubject<TOut>, ThisArg = unknown>(source$: Source$, transform?: CopyRx_Transform<TIn, TOut, ThisArg
|
|
181
|
+
declare function copyRx<TOut, Source$ extends Observable<any> | unknown[] = Observable<any> | unknown[], TIn = UnwrapSourceValueStrict<Source$>, Copy$ extends BehaviorSubject<TOut> | Subject<TOut> = BehaviorSubject<TOut>, ThisArg = unknown>(source$: Source$, transform?: null | CopyRx_Transform<TIn, TOut, ThisArg>, options?: CopyRx_Options<TOut, ThisArg>): Copy$;
|
|
182
182
|
declare function copyRx<TOut, Source$ extends Observable<any> | unknown[] = Observable<any> | unknown[], TIn = UnwrapSourceValueStrict<Source$>, Copy$ extends BehaviorSubject<TOut> | Subject<TOut> = BehaviorSubject<TOut>, ThisArg = unknown>(source$: Source$, transform: CopyRx_Transform<TIn, TOut, ThisArg>, options?: CopyRx_Options<TOut, ThisArg>): Copy$;
|
|
183
183
|
declare namespace copyRx {
|
|
184
184
|
var defaults: Required<Omit<DeferredOptions<unknown>, "thisArg"> & {
|
|
@@ -236,23 +236,37 @@ declare class IntervalSubject extends BehaviorSubject<number> {
|
|
|
236
236
|
stop: () => this;
|
|
237
237
|
}
|
|
238
238
|
|
|
239
|
+
/**
|
|
240
|
+
* `onResult` callback signature for {@link IntervalRunner}
|
|
241
|
+
*
|
|
242
|
+
* @param error
|
|
243
|
+
* @param result
|
|
244
|
+
* @param runCount number times the task has been executed
|
|
245
|
+
* @param once: if the task was executed outside of interval setup using `instance.executeOnce()` function.
|
|
246
|
+
*/
|
|
239
247
|
type OnResultType<TResult = unknown> = (error: Error | null, result: TResult | undefined, runCount: number, once: boolean) => void | Promise<void>;
|
|
240
|
-
type onBeforeExecType = (runCount: number, once: boolean) => void | Promise<unknown>;
|
|
241
248
|
/**
|
|
242
|
-
*
|
|
249
|
+
* `onBeforeExecType` callback signature for {@link IntervalRunner}
|
|
250
|
+
*
|
|
251
|
+
* @param runCount number times the task has been executed
|
|
252
|
+
* @param once: if the task was executed outside of interval setup using `instance.executeOnce()` function.
|
|
253
|
+
*/
|
|
254
|
+
type onBeforeExecType = (runCount: number, once: boolean) => void | Promise<void>;
|
|
255
|
+
/**
|
|
256
|
+
* A simple runner to execute a task periodically.
|
|
243
257
|
*
|
|
244
258
|
* When to use `IntervalRunner` instead of `IntervalSubject`?
|
|
245
259
|
*
|
|
246
|
-
* `IntervalRunner` is useful when the execution of the `
|
|
247
|
-
* from the interval delay duration.
|
|
260
|
+
* `IntervalRunner` is useful when the execution of the `taskFn` (and its `onResult` callback)
|
|
261
|
+
* needs to be precisely timed and/or excluded from the interval delay duration.
|
|
248
262
|
*
|
|
249
|
-
*
|
|
263
|
+
* @example
|
|
250
264
|
* When an API call needs to be made periodically and there's a possibility of delayed response (due to network issues
|
|
251
265
|
* or longer backend execution time). In this case, using IntervalRunner with `sequential = true` will ensure the
|
|
252
266
|
* delay is consistent between completion of current and start of the next API call.
|
|
253
267
|
*
|
|
254
268
|
* @param taskFn task function to be executed periodically
|
|
255
|
-
* @param taskArgs arguments to be supplied to the task function.
|
|
269
|
+
* @param taskArgs arguments (or a function that returns arguments) to be supplied to the task function.
|
|
256
270
|
* @param intervalMs timer delay in milliseconds.
|
|
257
271
|
* @param sequential true (default): will use setTimeout and will delay until execution is completed.
|
|
258
272
|
* This will ensure, in case the current execution takes longer, the following execution will not occur until current one is done and the interval delay is passed.
|
|
@@ -267,28 +281,29 @@ type onBeforeExecType = (runCount: number, once: boolean) => void | Promise<unkn
|
|
|
267
281
|
*
|
|
268
282
|
* @example
|
|
269
283
|
* #### Execute a function sequentially
|
|
270
|
-
* Counting time will not start until function execution ends, maintaining the delay
|
|
284
|
+
* Counting time will not start until function execution ends, maintaining the delay between
|
|
271
285
|
* end of execution consistent.
|
|
272
|
-
* ```
|
|
286
|
+
* ```javascript
|
|
273
287
|
* import fetch from '@superutils/fetch'
|
|
274
|
-
* import { IntervalRunner }
|
|
288
|
+
* import { IntervalRunner } from '@superutils/rx'
|
|
275
289
|
*
|
|
276
290
|
* const runner = new IntervalRunner(
|
|
277
|
-
* fetch.get,
|
|
278
|
-
* ['[DUMMYJSON-DOT-COM]/products'],
|
|
291
|
+
* fetch.get, // function to execute
|
|
292
|
+
* ['[DUMMYJSON-DOT-COM]/products'], // arguments to be provided to the function on each execution
|
|
279
293
|
* 2000,
|
|
280
294
|
* )
|
|
281
295
|
* runner.start(result => console.log({ result }))
|
|
282
296
|
* ```
|
|
283
297
|
*
|
|
284
298
|
* @example
|
|
285
|
-
* #### Execute a function
|
|
286
|
-
*
|
|
287
|
-
*
|
|
288
|
-
* ```
|
|
299
|
+
* #### Execute a function without enforcing sequential completion
|
|
300
|
+
* Timing begins at the start of the task, ensuring a consistent interval between the **start**
|
|
301
|
+
* of each execution, regardless of when the task finishes.
|
|
302
|
+
* ```javascript
|
|
289
303
|
* import fetch from '@superutils/fetch'
|
|
290
|
-
* import { IntervalRunner }
|
|
304
|
+
* import { IntervalRunner } from '@superutils/rx'
|
|
291
305
|
*
|
|
306
|
+
* // Create a interval runner that retrieves products every 2 seconds
|
|
292
307
|
* const runner = new IntervalRunner(
|
|
293
308
|
* fetch.get,
|
|
294
309
|
* ['[DUMMYJSON-DOT-COM]/products'],
|
|
@@ -297,10 +312,27 @@ type onBeforeExecType = (runCount: number, once: boolean) => void | Promise<unkn
|
|
|
297
312
|
* )
|
|
298
313
|
* runner.start(result => console.log({ result }))
|
|
299
314
|
* ```
|
|
315
|
+
*
|
|
316
|
+
* @example
|
|
317
|
+
* #### Execute a function and auto-retry on failure
|
|
318
|
+
* ```javascript
|
|
319
|
+
* import fetch from '@superutils/fetch'
|
|
320
|
+
* import { IntervalRunner } from '@superutils/rx'
|
|
321
|
+
*
|
|
322
|
+
* const runner = new IntervalRunner(
|
|
323
|
+
* () => retry(
|
|
324
|
+
* fetch.get, // function to execute
|
|
325
|
+
* { retry: 3 }, // retry maximum 3 times (max 5 attempts )
|
|
326
|
+
* ),
|
|
327
|
+
* ['[DUMMYJSON-DOT-COM]/products'], // arguments to be provided to the function on each execution
|
|
328
|
+
* 2000,
|
|
329
|
+
* )
|
|
330
|
+
* runner.start(result => console.log({ result }))
|
|
331
|
+
* ```
|
|
300
332
|
*/
|
|
301
333
|
declare class IntervalRunner<TResult = unknown, TArgs extends unknown[] = unknown[]> {
|
|
302
334
|
readonly taskFn: (...args: TArgs) => TResult | Promise<TResult>;
|
|
303
|
-
readonly taskArgs: TArgs;
|
|
335
|
+
readonly taskArgs: TArgs | ((this: IntervalRunner<TResult, TArgs>, runCount: number) => TArgs);
|
|
304
336
|
readonly sequential: boolean;
|
|
305
337
|
readonly preExecute: boolean;
|
|
306
338
|
private idInterval;
|
|
@@ -309,17 +341,17 @@ declare class IntervalRunner<TResult = unknown, TArgs extends unknown[] = unknow
|
|
|
309
341
|
private onBeforeExec?;
|
|
310
342
|
private onResult;
|
|
311
343
|
/**
|
|
312
|
-
*
|
|
344
|
+
* RxJS BehaviorSubject to change timer delay (and restart the timer) on the fly
|
|
313
345
|
*/
|
|
314
346
|
readonly intervalMs$: BehaviorSubject<number>;
|
|
315
|
-
private
|
|
347
|
+
private _runCount;
|
|
316
348
|
private started;
|
|
317
349
|
private subscription;
|
|
318
|
-
constructor(taskFn: (...args: TArgs) => TResult | Promise<TResult>, taskArgs: TArgs, intervalMs: BehaviorSubject<number> | number, sequential?: boolean, //
|
|
350
|
+
constructor(taskFn: (...args: TArgs) => TResult | Promise<TResult>, taskArgs: TArgs | ((this: IntervalRunner<TResult, TArgs>, runCount: number) => TArgs), intervalMs: BehaviorSubject<number> | number, sequential?: boolean, // If true, timer will start only after execution is finished.
|
|
319
351
|
preExecute?: boolean);
|
|
320
352
|
private clearInterval;
|
|
321
353
|
private executeTask;
|
|
322
|
-
/**
|
|
354
|
+
/** Executes the task function once, regardless of the interval runner's current state. */
|
|
323
355
|
executeOnce: () => Promise<TResult | undefined>;
|
|
324
356
|
/** Check if interval is running*/
|
|
325
357
|
isStarted: () => boolean;
|
|
@@ -331,16 +363,20 @@ declare class IntervalRunner<TResult = unknown, TArgs extends unknown[] = unknow
|
|
|
331
363
|
* @returns {Boolean} indicates whether restart was successful
|
|
332
364
|
*/
|
|
333
365
|
restart: (resetRunCount?: boolean) => boolean;
|
|
366
|
+
/** Get number of times task has ran, excluding resets */
|
|
367
|
+
get runCount(): number;
|
|
334
368
|
/**
|
|
335
|
-
*
|
|
336
|
-
*
|
|
337
|
-
* If it's already running, the callbacks will be used on the next execution.
|
|
369
|
+
* Sets the `onResult` and `onBeforeExec` callbacks and starts the interval execution.
|
|
338
370
|
*
|
|
371
|
+
* If the runner is already started, the new callbacks will be used for subsequent executions.
|
|
372
|
+
* To apply new callbacks immediately, call `stop()` first, then `start()`.
|
|
339
373
|
* In order to start using callbacks immediately, invoke the `intervalRunner.stop()` function first.
|
|
340
374
|
*
|
|
375
|
+
* @param onResult (optional) function to be invoked whenever the task is succefully executed. See {@link OnResultType}
|
|
376
|
+
*
|
|
341
377
|
* @returns {Boolean} indicates whether starting interveral waa successful
|
|
342
378
|
*/
|
|
343
|
-
start: (onResult
|
|
379
|
+
start: (onResult?: OnResultType<TResult>, onBeforeExec?: onBeforeExecType) => boolean;
|
|
344
380
|
/**
|
|
345
381
|
* Stop interval runner
|
|
346
382
|
*
|
package/dist/index.d.ts
CHANGED
|
@@ -178,7 +178,7 @@ output: Observable<TOut>) => ValueOrPromise<TOut> | typeof IGNORE_UPDATE_SYMBOL;
|
|
|
178
178
|
* )
|
|
179
179
|
* ```
|
|
180
180
|
*/
|
|
181
|
-
declare function copyRx<TOut, Source$ extends Observable<any> | unknown[] = Observable<any> | unknown[], TIn = UnwrapSourceValueStrict<Source$>, Copy$ extends BehaviorSubject<TOut> | Subject<TOut> = BehaviorSubject<TOut>, ThisArg = unknown>(source$: Source$, transform?: CopyRx_Transform<TIn, TOut, ThisArg
|
|
181
|
+
declare function copyRx<TOut, Source$ extends Observable<any> | unknown[] = Observable<any> | unknown[], TIn = UnwrapSourceValueStrict<Source$>, Copy$ extends BehaviorSubject<TOut> | Subject<TOut> = BehaviorSubject<TOut>, ThisArg = unknown>(source$: Source$, transform?: null | CopyRx_Transform<TIn, TOut, ThisArg>, options?: CopyRx_Options<TOut, ThisArg>): Copy$;
|
|
182
182
|
declare function copyRx<TOut, Source$ extends Observable<any> | unknown[] = Observable<any> | unknown[], TIn = UnwrapSourceValueStrict<Source$>, Copy$ extends BehaviorSubject<TOut> | Subject<TOut> = BehaviorSubject<TOut>, ThisArg = unknown>(source$: Source$, transform: CopyRx_Transform<TIn, TOut, ThisArg>, options?: CopyRx_Options<TOut, ThisArg>): Copy$;
|
|
183
183
|
declare namespace copyRx {
|
|
184
184
|
var defaults: Required<Omit<DeferredOptions<unknown>, "thisArg"> & {
|
|
@@ -236,23 +236,37 @@ declare class IntervalSubject extends BehaviorSubject<number> {
|
|
|
236
236
|
stop: () => this;
|
|
237
237
|
}
|
|
238
238
|
|
|
239
|
+
/**
|
|
240
|
+
* `onResult` callback signature for {@link IntervalRunner}
|
|
241
|
+
*
|
|
242
|
+
* @param error
|
|
243
|
+
* @param result
|
|
244
|
+
* @param runCount number times the task has been executed
|
|
245
|
+
* @param once: if the task was executed outside of interval setup using `instance.executeOnce()` function.
|
|
246
|
+
*/
|
|
239
247
|
type OnResultType<TResult = unknown> = (error: Error | null, result: TResult | undefined, runCount: number, once: boolean) => void | Promise<void>;
|
|
240
|
-
type onBeforeExecType = (runCount: number, once: boolean) => void | Promise<unknown>;
|
|
241
248
|
/**
|
|
242
|
-
*
|
|
249
|
+
* `onBeforeExecType` callback signature for {@link IntervalRunner}
|
|
250
|
+
*
|
|
251
|
+
* @param runCount number times the task has been executed
|
|
252
|
+
* @param once: if the task was executed outside of interval setup using `instance.executeOnce()` function.
|
|
253
|
+
*/
|
|
254
|
+
type onBeforeExecType = (runCount: number, once: boolean) => void | Promise<void>;
|
|
255
|
+
/**
|
|
256
|
+
* A simple runner to execute a task periodically.
|
|
243
257
|
*
|
|
244
258
|
* When to use `IntervalRunner` instead of `IntervalSubject`?
|
|
245
259
|
*
|
|
246
|
-
* `IntervalRunner` is useful when the execution of the `
|
|
247
|
-
* from the interval delay duration.
|
|
260
|
+
* `IntervalRunner` is useful when the execution of the `taskFn` (and its `onResult` callback)
|
|
261
|
+
* needs to be precisely timed and/or excluded from the interval delay duration.
|
|
248
262
|
*
|
|
249
|
-
*
|
|
263
|
+
* @example
|
|
250
264
|
* When an API call needs to be made periodically and there's a possibility of delayed response (due to network issues
|
|
251
265
|
* or longer backend execution time). In this case, using IntervalRunner with `sequential = true` will ensure the
|
|
252
266
|
* delay is consistent between completion of current and start of the next API call.
|
|
253
267
|
*
|
|
254
268
|
* @param taskFn task function to be executed periodically
|
|
255
|
-
* @param taskArgs arguments to be supplied to the task function.
|
|
269
|
+
* @param taskArgs arguments (or a function that returns arguments) to be supplied to the task function.
|
|
256
270
|
* @param intervalMs timer delay in milliseconds.
|
|
257
271
|
* @param sequential true (default): will use setTimeout and will delay until execution is completed.
|
|
258
272
|
* This will ensure, in case the current execution takes longer, the following execution will not occur until current one is done and the interval delay is passed.
|
|
@@ -267,28 +281,29 @@ type onBeforeExecType = (runCount: number, once: boolean) => void | Promise<unkn
|
|
|
267
281
|
*
|
|
268
282
|
* @example
|
|
269
283
|
* #### Execute a function sequentially
|
|
270
|
-
* Counting time will not start until function execution ends, maintaining the delay
|
|
284
|
+
* Counting time will not start until function execution ends, maintaining the delay between
|
|
271
285
|
* end of execution consistent.
|
|
272
|
-
* ```
|
|
286
|
+
* ```javascript
|
|
273
287
|
* import fetch from '@superutils/fetch'
|
|
274
|
-
* import { IntervalRunner }
|
|
288
|
+
* import { IntervalRunner } from '@superutils/rx'
|
|
275
289
|
*
|
|
276
290
|
* const runner = new IntervalRunner(
|
|
277
|
-
* fetch.get,
|
|
278
|
-
* ['[DUMMYJSON-DOT-COM]/products'],
|
|
291
|
+
* fetch.get, // function to execute
|
|
292
|
+
* ['[DUMMYJSON-DOT-COM]/products'], // arguments to be provided to the function on each execution
|
|
279
293
|
* 2000,
|
|
280
294
|
* )
|
|
281
295
|
* runner.start(result => console.log({ result }))
|
|
282
296
|
* ```
|
|
283
297
|
*
|
|
284
298
|
* @example
|
|
285
|
-
* #### Execute a function
|
|
286
|
-
*
|
|
287
|
-
*
|
|
288
|
-
* ```
|
|
299
|
+
* #### Execute a function without enforcing sequential completion
|
|
300
|
+
* Timing begins at the start of the task, ensuring a consistent interval between the **start**
|
|
301
|
+
* of each execution, regardless of when the task finishes.
|
|
302
|
+
* ```javascript
|
|
289
303
|
* import fetch from '@superutils/fetch'
|
|
290
|
-
* import { IntervalRunner }
|
|
304
|
+
* import { IntervalRunner } from '@superutils/rx'
|
|
291
305
|
*
|
|
306
|
+
* // Create a interval runner that retrieves products every 2 seconds
|
|
292
307
|
* const runner = new IntervalRunner(
|
|
293
308
|
* fetch.get,
|
|
294
309
|
* ['[DUMMYJSON-DOT-COM]/products'],
|
|
@@ -297,10 +312,27 @@ type onBeforeExecType = (runCount: number, once: boolean) => void | Promise<unkn
|
|
|
297
312
|
* )
|
|
298
313
|
* runner.start(result => console.log({ result }))
|
|
299
314
|
* ```
|
|
315
|
+
*
|
|
316
|
+
* @example
|
|
317
|
+
* #### Execute a function and auto-retry on failure
|
|
318
|
+
* ```javascript
|
|
319
|
+
* import fetch from '@superutils/fetch'
|
|
320
|
+
* import { IntervalRunner } from '@superutils/rx'
|
|
321
|
+
*
|
|
322
|
+
* const runner = new IntervalRunner(
|
|
323
|
+
* () => retry(
|
|
324
|
+
* fetch.get, // function to execute
|
|
325
|
+
* { retry: 3 }, // retry maximum 3 times (max 5 attempts )
|
|
326
|
+
* ),
|
|
327
|
+
* ['[DUMMYJSON-DOT-COM]/products'], // arguments to be provided to the function on each execution
|
|
328
|
+
* 2000,
|
|
329
|
+
* )
|
|
330
|
+
* runner.start(result => console.log({ result }))
|
|
331
|
+
* ```
|
|
300
332
|
*/
|
|
301
333
|
declare class IntervalRunner<TResult = unknown, TArgs extends unknown[] = unknown[]> {
|
|
302
334
|
readonly taskFn: (...args: TArgs) => TResult | Promise<TResult>;
|
|
303
|
-
readonly taskArgs: TArgs;
|
|
335
|
+
readonly taskArgs: TArgs | ((this: IntervalRunner<TResult, TArgs>, runCount: number) => TArgs);
|
|
304
336
|
readonly sequential: boolean;
|
|
305
337
|
readonly preExecute: boolean;
|
|
306
338
|
private idInterval;
|
|
@@ -309,17 +341,17 @@ declare class IntervalRunner<TResult = unknown, TArgs extends unknown[] = unknow
|
|
|
309
341
|
private onBeforeExec?;
|
|
310
342
|
private onResult;
|
|
311
343
|
/**
|
|
312
|
-
*
|
|
344
|
+
* RxJS BehaviorSubject to change timer delay (and restart the timer) on the fly
|
|
313
345
|
*/
|
|
314
346
|
readonly intervalMs$: BehaviorSubject<number>;
|
|
315
|
-
private
|
|
347
|
+
private _runCount;
|
|
316
348
|
private started;
|
|
317
349
|
private subscription;
|
|
318
|
-
constructor(taskFn: (...args: TArgs) => TResult | Promise<TResult>, taskArgs: TArgs, intervalMs: BehaviorSubject<number> | number, sequential?: boolean, //
|
|
350
|
+
constructor(taskFn: (...args: TArgs) => TResult | Promise<TResult>, taskArgs: TArgs | ((this: IntervalRunner<TResult, TArgs>, runCount: number) => TArgs), intervalMs: BehaviorSubject<number> | number, sequential?: boolean, // If true, timer will start only after execution is finished.
|
|
319
351
|
preExecute?: boolean);
|
|
320
352
|
private clearInterval;
|
|
321
353
|
private executeTask;
|
|
322
|
-
/**
|
|
354
|
+
/** Executes the task function once, regardless of the interval runner's current state. */
|
|
323
355
|
executeOnce: () => Promise<TResult | undefined>;
|
|
324
356
|
/** Check if interval is running*/
|
|
325
357
|
isStarted: () => boolean;
|
|
@@ -331,16 +363,20 @@ declare class IntervalRunner<TResult = unknown, TArgs extends unknown[] = unknow
|
|
|
331
363
|
* @returns {Boolean} indicates whether restart was successful
|
|
332
364
|
*/
|
|
333
365
|
restart: (resetRunCount?: boolean) => boolean;
|
|
366
|
+
/** Get number of times task has ran, excluding resets */
|
|
367
|
+
get runCount(): number;
|
|
334
368
|
/**
|
|
335
|
-
*
|
|
336
|
-
*
|
|
337
|
-
* If it's already running, the callbacks will be used on the next execution.
|
|
369
|
+
* Sets the `onResult` and `onBeforeExec` callbacks and starts the interval execution.
|
|
338
370
|
*
|
|
371
|
+
* If the runner is already started, the new callbacks will be used for subsequent executions.
|
|
372
|
+
* To apply new callbacks immediately, call `stop()` first, then `start()`.
|
|
339
373
|
* In order to start using callbacks immediately, invoke the `intervalRunner.stop()` function first.
|
|
340
374
|
*
|
|
375
|
+
* @param onResult (optional) function to be invoked whenever the task is succefully executed. See {@link OnResultType}
|
|
376
|
+
*
|
|
341
377
|
* @returns {Boolean} indicates whether starting interveral waa successful
|
|
342
378
|
*/
|
|
343
|
-
start: (onResult
|
|
379
|
+
start: (onResult?: OnResultType<TResult>, onBeforeExec?: onBeforeExecType) => boolean;
|
|
344
380
|
/**
|
|
345
381
|
* Stop interval runner
|
|
346
382
|
*
|
package/dist/index.js
CHANGED
|
@@ -211,7 +211,7 @@ var IntervalSubject = class extends BehaviorSubject2 {
|
|
|
211
211
|
};
|
|
212
212
|
|
|
213
213
|
// src/IntervalRunner.ts
|
|
214
|
-
import { fallbackIfFails as fallbackIfFails3, noop } from "@superutils/core";
|
|
214
|
+
import { fallbackIfFails as fallbackIfFails3, isFn as isFn5, noop } from "@superutils/core";
|
|
215
215
|
import { BehaviorSubject as BehaviorSubject3 } from "rxjs";
|
|
216
216
|
var IntervalRunner = class {
|
|
217
217
|
constructor(taskFn, taskArgs, intervalMs, sequential = true, preExecute = true) {
|
|
@@ -220,7 +220,7 @@ var IntervalRunner = class {
|
|
|
220
220
|
this.sequential = sequential;
|
|
221
221
|
this.preExecute = preExecute;
|
|
222
222
|
this.minIntervalMs = 1e3;
|
|
223
|
-
this.
|
|
223
|
+
this._runCount = 0;
|
|
224
224
|
this.started = false;
|
|
225
225
|
this.clearInterval = () => {
|
|
226
226
|
this.sequential ? clearTimeout(this.idInterval) : clearInterval(this.idInterval);
|
|
@@ -232,16 +232,18 @@ var IntervalRunner = class {
|
|
|
232
232
|
let result;
|
|
233
233
|
if (this.sequential || once) this.clearInterval();
|
|
234
234
|
try {
|
|
235
|
-
++this.
|
|
236
|
-
await ((_a = this.onBeforeExec) == null ? void 0 : _a.call(this, this.
|
|
237
|
-
result = await this.taskFn
|
|
235
|
+
++this._runCount;
|
|
236
|
+
await ((_a = this.onBeforeExec) == null ? void 0 : _a.call(this, this._runCount, once));
|
|
237
|
+
result = await this.taskFn(
|
|
238
|
+
...isFn5(this.taskArgs) ? this.taskArgs.call(this, this._runCount) : this.taskArgs
|
|
239
|
+
);
|
|
238
240
|
this.lastResult = result;
|
|
239
241
|
} catch (_err) {
|
|
240
242
|
err = _err;
|
|
241
243
|
}
|
|
242
244
|
fallbackIfFails3(
|
|
243
245
|
this.onResult,
|
|
244
|
-
[err != null ? err : null, result, this.
|
|
246
|
+
[err != null ? err : null, result, this._runCount, once],
|
|
245
247
|
void 0
|
|
246
248
|
);
|
|
247
249
|
if (!once && this.sequential && this.intervalMs$.value > this.minIntervalMs) {
|
|
@@ -252,7 +254,7 @@ var IntervalRunner = class {
|
|
|
252
254
|
}
|
|
253
255
|
return this.lastResult;
|
|
254
256
|
};
|
|
255
|
-
/**
|
|
257
|
+
/** Executes the task function once, regardless of the interval runner's current state. */
|
|
256
258
|
this.executeOnce = async () => await this.executeTask(true);
|
|
257
259
|
/** Check if interval is running*/
|
|
258
260
|
this.isStarted = () => this.started;
|
|
@@ -270,18 +272,19 @@ var IntervalRunner = class {
|
|
|
270
272
|
return true;
|
|
271
273
|
};
|
|
272
274
|
/**
|
|
273
|
-
*
|
|
274
|
-
*
|
|
275
|
-
* If it's already running, the callbacks will be used on the next execution.
|
|
275
|
+
* Sets the `onResult` and `onBeforeExec` callbacks and starts the interval execution.
|
|
276
276
|
*
|
|
277
|
+
* If the runner is already started, the new callbacks will be used for subsequent executions.
|
|
278
|
+
* To apply new callbacks immediately, call `stop()` first, then `start()`.
|
|
277
279
|
* In order to start using callbacks immediately, invoke the `intervalRunner.stop()` function first.
|
|
278
280
|
*
|
|
281
|
+
* @param onResult (optional) function to be invoked whenever the task is succefully executed. See {@link OnResultType}
|
|
282
|
+
*
|
|
279
283
|
* @returns {Boolean} indicates whether starting interveral waa successful
|
|
280
284
|
*/
|
|
281
285
|
this.start = (onResult, onBeforeExec) => {
|
|
282
|
-
if (
|
|
283
|
-
this.
|
|
284
|
-
this.onBeforeExec = onBeforeExec;
|
|
286
|
+
if (onResult) this.onResult = onResult;
|
|
287
|
+
if (onBeforeExec) this.onBeforeExec = onBeforeExec;
|
|
285
288
|
if (this.started) return false;
|
|
286
289
|
this.started = true;
|
|
287
290
|
let delayMs;
|
|
@@ -303,7 +306,7 @@ var IntervalRunner = class {
|
|
|
303
306
|
*/
|
|
304
307
|
this.stop = (resetRunCount = false) => {
|
|
305
308
|
var _a, _b;
|
|
306
|
-
if (resetRunCount) this.
|
|
309
|
+
if (resetRunCount) this._runCount = 0;
|
|
307
310
|
this.started = false;
|
|
308
311
|
(_b = (_a = this.subscription) == null ? void 0 : _a.unsubscribe) == null ? void 0 : _b.call(_a);
|
|
309
312
|
this.clearInterval();
|
|
@@ -311,6 +314,10 @@ var IntervalRunner = class {
|
|
|
311
314
|
};
|
|
312
315
|
this.intervalMs$ = intervalMs instanceof BehaviorSubject3 ? intervalMs : new BehaviorSubject3(intervalMs);
|
|
313
316
|
}
|
|
317
|
+
/** Get number of times task has ran, excluding resets */
|
|
318
|
+
get runCount() {
|
|
319
|
+
return this._runCount;
|
|
320
|
+
}
|
|
314
321
|
};
|
|
315
322
|
export {
|
|
316
323
|
IGNORE_UPDATE_SYMBOL,
|
package/package.json
CHANGED
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
"author": "Toufiqur Rahaman Chowdhury",
|
|
3
3
|
"description": "A set of small, focused utilities for working with RxJS observables and subjects.",
|
|
4
4
|
"dependencies": {
|
|
5
|
-
"@superutils/core": "^1.2.
|
|
6
|
-
"@superutils/promise": "^1.3.
|
|
5
|
+
"@superutils/core": "^1.2.22",
|
|
6
|
+
"@superutils/promise": "^1.3.21",
|
|
7
7
|
"@types/react": "^18.0.0",
|
|
8
8
|
"react": ">=16.8.0",
|
|
9
9
|
"rxjs": "^7.8.2"
|
|
@@ -49,6 +49,6 @@
|
|
|
49
49
|
"module": "./dist/index.js",
|
|
50
50
|
"type": "module",
|
|
51
51
|
"types": "./dist/index.d.ts",
|
|
52
|
-
"version": "0.1.
|
|
53
|
-
"gitHead": "
|
|
52
|
+
"version": "0.1.18",
|
|
53
|
+
"gitHead": "35722628393f7eface789fea15e80e521c509831"
|
|
54
54
|
}
|