@anishhs/retryq 1.1.0 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +142 -19
- package/dist/cjs/index.d.ts +9 -0
- package/dist/cjs/index.d.ts.map +1 -0
- package/dist/cjs/index.js +13 -0
- package/dist/cjs/index.js.map +1 -0
- package/dist/cjs/manager.d.ts +139 -0
- package/dist/cjs/manager.d.ts.map +1 -0
- package/dist/cjs/manager.js +431 -0
- package/dist/cjs/manager.js.map +1 -0
- package/dist/cjs/package.json +3 -0
- package/dist/cjs/types.d.ts +237 -0
- package/dist/cjs/types.d.ts.map +1 -0
- package/dist/cjs/types.js +3 -0
- package/dist/cjs/types.js.map +1 -0
- package/dist/cjs/utils.d.ts +43 -0
- package/dist/cjs/utils.d.ts.map +1 -0
- package/dist/cjs/utils.js +71 -0
- package/dist/cjs/utils.js.map +1 -0
- package/dist/cjs/validation.d.ts +37 -0
- package/dist/cjs/validation.d.ts.map +1 -0
- package/dist/cjs/validation.js +69 -0
- package/dist/cjs/validation.js.map +1 -0
- package/dist/esm/index.d.ts +9 -0
- package/dist/esm/index.d.ts.map +1 -0
- package/dist/esm/index.js +8 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/manager.d.ts +139 -0
- package/dist/esm/manager.d.ts.map +1 -0
- package/dist/esm/manager.js +427 -0
- package/dist/esm/manager.js.map +1 -0
- package/dist/esm/package.json +3 -0
- package/dist/esm/types.d.ts +237 -0
- package/dist/esm/types.d.ts.map +1 -0
- package/dist/esm/types.js +2 -0
- package/dist/esm/types.js.map +1 -0
- package/dist/esm/utils.d.ts +43 -0
- package/dist/esm/utils.d.ts.map +1 -0
- package/dist/esm/utils.js +64 -0
- package/dist/esm/utils.js.map +1 -0
- package/dist/esm/validation.d.ts +37 -0
- package/dist/esm/validation.d.ts.map +1 -0
- package/dist/esm/validation.js +65 -0
- package/dist/esm/validation.js.map +1 -0
- package/package.json +29 -12
- package/dist/index.d.ts +0 -85
- package/dist/index.js +0 -293
- package/dist/index.js.map +0 -1
package/README.md
CHANGED
|
@@ -10,15 +10,18 @@ A production-ready, zero-dependency retry queue manager for Node.js with support
|
|
|
10
10
|
|
|
11
11
|
- ✅ **Concurrency control** - Limit concurrent job execution
|
|
12
12
|
- ✅ **Priority queue** - Higher priority jobs execute first
|
|
13
|
-
- ✅ **Exponential backoff** with configurable delay, multiplier, and jitter
|
|
13
|
+
- ✅ **Exponential backoff** with configurable delay, multiplier, `maxDelay`, and jitter
|
|
14
|
+
- ✅ **Lifecycle events & hooks** - `retry`/`success`/`failure`/`cancel`/`idle` events + per-job callbacks
|
|
15
|
+
- ✅ **Conditional retries** - `shouldRetry(error, attempt)` predicate to skip non-retryable errors
|
|
14
16
|
- ✅ **Force cancellation** - Abort in-progress jobs with AbortController
|
|
15
17
|
- ✅ **Cooperative cancellation** - Graceful job termination
|
|
18
|
+
- ✅ **Real time limits** - `maxTime` (and `attemptTimeout`) actively abort in-flight attempts
|
|
19
|
+
- ✅ **Queue draining** - `onIdle()` / `drain()` to await all work
|
|
16
20
|
- ✅ **Memory safe** - Bounded job history with LRU eviction
|
|
17
|
-
- ✅ **Time limits** - Global timeout per job with `maxTime`
|
|
18
21
|
- ✅ **Job introspection** - List, find, and track jobs by ID or label
|
|
19
|
-
- ✅ **TypeScript** -
|
|
22
|
+
- ✅ **TypeScript** - Generic, fully-typed API with bundled declarations
|
|
23
|
+
- ✅ **Dual ESM + CJS** - Ships both module formats with an `exports` map
|
|
20
24
|
- ✅ **Zero dependencies** - Minimal footprint, no external packages
|
|
21
|
-
- ✅ **Production tested** - 50+ tests covering all features
|
|
22
25
|
|
|
23
26
|
## Installation
|
|
24
27
|
|
|
@@ -268,6 +271,68 @@ retryQ.clearHistory();
|
|
|
268
271
|
|
|
269
272
|
---
|
|
270
273
|
|
|
274
|
+
#### onIdle() / drain()
|
|
275
|
+
|
|
276
|
+
```typescript
|
|
277
|
+
onIdle(): Promise<void>
|
|
278
|
+
drain(): Promise<void> // alias
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
Resolves when the queue is fully idle (no pending **and** no running jobs).
|
|
282
|
+
Resolves immediately if already idle.
|
|
283
|
+
|
|
284
|
+
```typescript
|
|
285
|
+
for (const item of items) {
|
|
286
|
+
retryQ.createJob(() => process(item), { retries: 3 });
|
|
287
|
+
}
|
|
288
|
+
await retryQ.onIdle(); // wait for the whole batch to settle
|
|
289
|
+
```
|
|
290
|
+
|
|
291
|
+
---
|
|
292
|
+
|
|
293
|
+
### Events
|
|
294
|
+
|
|
295
|
+
`RetryQManager` extends Node's `EventEmitter` and emits typed events:
|
|
296
|
+
|
|
297
|
+
```typescript
|
|
298
|
+
retryQ.on('retry', ({ job, info }) => console.log(`retry #${info.attempt} in ${info.nextDelay}ms`));
|
|
299
|
+
retryQ.on('success', ({ job, result }) => console.log('done', job.label));
|
|
300
|
+
retryQ.on('failure', ({ job, error }) => console.error('failed', job.label, error));
|
|
301
|
+
retryQ.on('cancel', ({ job }) => console.log('cancelled', job.label));
|
|
302
|
+
retryQ.on('idle', () => console.log('queue drained'));
|
|
303
|
+
```
|
|
304
|
+
|
|
305
|
+
| Event | Payload | Fired when |
|
|
306
|
+
|-------|---------|-----------|
|
|
307
|
+
| `retry` | `{ job, info: RetryInfo }` | A failed attempt schedules another try |
|
|
308
|
+
| `success` | `{ job, result }` | A job completes successfully |
|
|
309
|
+
| `failure` | `{ job, error }` | A job fails terminally |
|
|
310
|
+
| `cancel` | `{ job }` | A job is cancelled |
|
|
311
|
+
| `idle` | _(none)_ | The queue transitions to fully idle |
|
|
312
|
+
|
|
313
|
+
Prefer per-job feedback? Use the `onRetry` / `onSuccess` / `onFailure` /
|
|
314
|
+
`onCancel` callbacks in `RetryQJobOptions`.
|
|
315
|
+
|
|
316
|
+
---
|
|
317
|
+
|
|
318
|
+
### Conditional Retries
|
|
319
|
+
|
|
320
|
+
Skip retries for errors that will never succeed:
|
|
321
|
+
|
|
322
|
+
```typescript
|
|
323
|
+
retryQ.createJob(async (signal) => {
|
|
324
|
+
const res = await fetch(url, { signal });
|
|
325
|
+
if (!res.ok) throw Object.assign(new Error('HTTP'), { status: res.status });
|
|
326
|
+
return res.json();
|
|
327
|
+
}, {
|
|
328
|
+
retries: 5,
|
|
329
|
+
// Retry 5xx and network errors; give up on 4xx immediately.
|
|
330
|
+
shouldRetry: (err) => !(err?.status >= 400 && err?.status < 500),
|
|
331
|
+
});
|
|
332
|
+
```
|
|
333
|
+
|
|
334
|
+
---
|
|
335
|
+
|
|
271
336
|
### RetryQJob Interface
|
|
272
337
|
|
|
273
338
|
```typescript
|
|
@@ -525,15 +590,26 @@ process.on('SIGTERM', async () => {
|
|
|
525
590
|
### RetryQJobOptions
|
|
526
591
|
|
|
527
592
|
```typescript
|
|
528
|
-
type RetryQJobOptions = {
|
|
529
|
-
retries?: number;
|
|
530
|
-
delay?: number;
|
|
531
|
-
backoff?: number;
|
|
532
|
-
maxTime?: number;
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
593
|
+
type RetryQJobOptions<T = unknown> = {
|
|
594
|
+
retries?: number; // Number of retry attempts (default: 3)
|
|
595
|
+
delay?: number; // Initial delay in ms (default: 1000)
|
|
596
|
+
backoff?: number; // Delay multiplier (default: 2)
|
|
597
|
+
maxTime?: number; // Total time limit in ms (default: 30000)
|
|
598
|
+
maxDelay?: number; // Cap for a single backoff delay (default: Infinity)
|
|
599
|
+
attemptTimeout?: number; // Per-attempt timeout in ms (default: Infinity)
|
|
600
|
+
jitter?: number; // Jitter fraction 0-1 (default: 0.1)
|
|
601
|
+
label?: string; // Human-readable identifier (default: job ID)
|
|
602
|
+
priority?: number; // Execution priority (default: 1)
|
|
603
|
+
signal?: AbortSignal; // External abort signal (optional)
|
|
604
|
+
|
|
605
|
+
// Conditional retry: return false to stop retrying immediately
|
|
606
|
+
shouldRetry?: (error: unknown, attempt: number) => boolean;
|
|
607
|
+
|
|
608
|
+
// Per-job lifecycle callbacks
|
|
609
|
+
onRetry?: (info: RetryInfo) => void;
|
|
610
|
+
onSuccess?: (result: T) => void;
|
|
611
|
+
onFailure?: (error: unknown) => void;
|
|
612
|
+
onCancel?: () => void;
|
|
537
613
|
};
|
|
538
614
|
```
|
|
539
615
|
|
|
@@ -544,7 +620,9 @@ type RetryQJobOptions = {
|
|
|
544
620
|
| `retries` | `3` | Number of retry attempts after initial try |
|
|
545
621
|
| `delay` | `1000` | Initial delay between retries (ms) |
|
|
546
622
|
| `backoff` | `2` | Multiplier for exponential backoff |
|
|
547
|
-
| `maxTime` | `30000` | Total execution time limit (30s) |
|
|
623
|
+
| `maxTime` | `30000` | Total execution time limit (30s), enforced during attempts |
|
|
624
|
+
| `maxDelay` | `Infinity` | Cap for a single backoff delay (ms) |
|
|
625
|
+
| `attemptTimeout` | `Infinity` | Per-attempt timeout (ms) |
|
|
548
626
|
| `jitter` | `0.1` | Random delay variation (±10%) |
|
|
549
627
|
| `priority` | `1` | Queue priority (higher = sooner) |
|
|
550
628
|
| `maxConcurrent` | `Infinity` | Concurrent job limit |
|
|
@@ -644,6 +722,19 @@ throw new Error('API request failed');
|
|
|
644
722
|
|
|
645
723
|
## Migration Guide
|
|
646
724
|
|
|
725
|
+
### From v1.1.x to v1.2.x
|
|
726
|
+
|
|
727
|
+
**No breaking API changes.** All existing code keeps working; new options,
|
|
728
|
+
callbacks, events, and methods are additive. Two behavior fixes to be aware of:
|
|
729
|
+
|
|
730
|
+
- `listJobs().cancelled` now holds cancelled jobs — they no longer appear under
|
|
731
|
+
`failed`.
|
|
732
|
+
- `maxTime` now actively aborts an in-flight attempt once the budget is
|
|
733
|
+
exhausted (previously it only blocked starting a new attempt).
|
|
734
|
+
|
|
735
|
+
The package now ships **both ESM and CJS** with an `exports` map; `import` and
|
|
736
|
+
`require` both resolve automatically.
|
|
737
|
+
|
|
647
738
|
### From v1.0.x to v1.1.x
|
|
648
739
|
|
|
649
740
|
**No breaking changes!** All existing code works.
|
|
@@ -763,7 +854,7 @@ async (signal) => {
|
|
|
763
854
|
## FAQ
|
|
764
855
|
|
|
765
856
|
**Q: Is this production-ready?**
|
|
766
|
-
A: Yes
|
|
857
|
+
A: Yes — covered by a `node:test` suite spanning concurrency, cancellation, events, timeouts, and retry semantics.
|
|
767
858
|
|
|
768
859
|
**Q: Does it work with TypeScript?**
|
|
769
860
|
A: Yes, full TypeScript support with bundled type definitions.
|
|
@@ -788,13 +879,43 @@ More examples available at: [github.com/anishhs-gh/retryq-examples](https://gith
|
|
|
788
879
|
|
|
789
880
|
---
|
|
790
881
|
|
|
882
|
+
## Development
|
|
883
|
+
|
|
884
|
+
```bash
|
|
885
|
+
npm install # install dev dependencies
|
|
886
|
+
npm run typecheck # tsc --noEmit
|
|
887
|
+
npm run build # emit dual ESM + CJS into dist/ (with .d.ts)
|
|
888
|
+
npm test # build (pretest) then run node:test suite
|
|
889
|
+
```
|
|
890
|
+
|
|
891
|
+
The package builds to both module formats:
|
|
892
|
+
|
|
893
|
+
- CommonJS → `dist/cjs` (`require`)
|
|
894
|
+
- ES modules → `dist/esm` (`import`)
|
|
895
|
+
|
|
896
|
+
resolved automatically via the `exports` map in `package.json`.
|
|
897
|
+
|
|
898
|
+
## CI / Release
|
|
899
|
+
|
|
900
|
+
| Workflow | Trigger | Purpose |
|
|
901
|
+
|----------|---------|---------|
|
|
902
|
+
| **Test** | push/PR to `develop`/`master` | Typecheck, build, and test on Node 16/18/20 |
|
|
903
|
+
| **Audit** | push/PR + weekly | `npm audit` of production dependencies |
|
|
904
|
+
| **Dry-run publish** | push to `develop`, PRs | Gated on Test + Audit; verifies the npm token authenticates and has publish permission, and that `npm publish` would succeed — without publishing |
|
|
905
|
+
| **Publish (manual)** | `workflow_dispatch` | Gated on Test + Audit; publishes to npm and creates a GitHub Release + version tag |
|
|
906
|
+
|
|
907
|
+
Releases are **manual**: bump the version in `package.json`, merge to `master`,
|
|
908
|
+
then run the **Publish** workflow from the Actions tab. Requires an `NPM_TOKEN`
|
|
909
|
+
repository secret with publish access to the `@anishhs` scope.
|
|
910
|
+
|
|
791
911
|
## Contributing
|
|
792
912
|
|
|
793
913
|
Contributions welcome! Please:
|
|
794
914
|
1. Fork the repository
|
|
795
|
-
2. Create a feature branch
|
|
796
|
-
3. Add tests for new features
|
|
797
|
-
4.
|
|
915
|
+
2. Create a feature branch (off `develop`)
|
|
916
|
+
3. Add tests for new features (`tests/*.test.js`, `node:test`)
|
|
917
|
+
4. Ensure `npm test` passes
|
|
918
|
+
5. Submit a pull request into `develop`
|
|
798
919
|
|
|
799
920
|
---
|
|
800
921
|
|
|
@@ -813,7 +934,9 @@ See [CHANGELOG.md](./CHANGELOG.md) for version history.
|
|
|
813
934
|
## Support
|
|
814
935
|
|
|
815
936
|
- **Issues**: [GitHub Issues](https://github.com/anishhs-gh/retryq/issues)
|
|
816
|
-
- **
|
|
937
|
+
- **GitHub**: [anishhs-gh](https://github.com/anishhs-gh)
|
|
938
|
+
- **Website**: [anishhs.com](https://anishhs.com)
|
|
939
|
+
- **LinkedIn**: [linkedin.com/in/anishsh](https://linkedin.com/in/anishsh)
|
|
817
940
|
|
|
818
941
|
---
|
|
819
942
|
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `@anishhs/retryq` — a production-ready, zero-dependency retry queue manager.
|
|
3
|
+
*
|
|
4
|
+
* @packageDocumentation
|
|
5
|
+
*/
|
|
6
|
+
export { RetryQManager } from "./manager.js";
|
|
7
|
+
export { RetryQTimeoutError } from "./utils.js";
|
|
8
|
+
export type { CancelableFunction, CancelEvent, FailureEvent, JobListSnapshot, JobState, JobSummary, RetryEvent, RetryInfo, RetryQEvents, RetryQJob, RetryQJobOptions, RetryQManagerConfig, SuccessEvent, } from "./types.js";
|
|
9
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAC7C,OAAO,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAChD,YAAY,EACV,kBAAkB,EAClB,WAAW,EACX,YAAY,EACZ,eAAe,EACf,QAAQ,EACR,UAAU,EACV,UAAU,EACV,SAAS,EACT,YAAY,EACZ,SAAS,EACT,gBAAgB,EAChB,mBAAmB,EACnB,YAAY,GACb,MAAM,YAAY,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.RetryQTimeoutError = exports.RetryQManager = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* `@anishhs/retryq` — a production-ready, zero-dependency retry queue manager.
|
|
6
|
+
*
|
|
7
|
+
* @packageDocumentation
|
|
8
|
+
*/
|
|
9
|
+
var manager_js_1 = require("./manager.js");
|
|
10
|
+
Object.defineProperty(exports, "RetryQManager", { enumerable: true, get: function () { return manager_js_1.RetryQManager; } });
|
|
11
|
+
var utils_js_1 = require("./utils.js");
|
|
12
|
+
Object.defineProperty(exports, "RetryQTimeoutError", { enumerable: true, get: function () { return utils_js_1.RetryQTimeoutError; } });
|
|
13
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":";;;AAAA;;;;GAIG;AACH,2CAA6C;AAApC,2GAAA,aAAa,OAAA;AACtB,uCAAgD;AAAvC,8GAAA,kBAAkB,OAAA"}
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
import { EventEmitter } from "node:events";
|
|
2
|
+
import type { JobListSnapshot, JobState, RetryQEvents, RetryQJob, RetryQJobOptions, RetryQManagerConfig } from "./types.js";
|
|
3
|
+
/**
|
|
4
|
+
* In-memory retry queue manager with concurrency control, priority scheduling,
|
|
5
|
+
* exponential backoff with jitter, lifecycle events, cooperative/force
|
|
6
|
+
* cancellation, and bounded job history.
|
|
7
|
+
*
|
|
8
|
+
* The manager extends {@link EventEmitter}; subscribe to `retry`, `success`,
|
|
9
|
+
* `failure`, `cancel`, and `idle` events (see {@link RetryQEvents}).
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* ```ts
|
|
13
|
+
* const q = new RetryQManager({ maxConcurrent: 3 });
|
|
14
|
+
* q.on("failure", ({ job, error }) => console.error(job.label, error));
|
|
15
|
+
*
|
|
16
|
+
* const job = q.createJob(async (signal) => {
|
|
17
|
+
* const res = await fetch("https://api.example.com", { signal });
|
|
18
|
+
* if (!res.ok) throw new Error(`HTTP ${res.status}`);
|
|
19
|
+
* return res.json();
|
|
20
|
+
* }, { retries: 5, shouldRetry: (e) => !`${e}`.includes("404") });
|
|
21
|
+
*
|
|
22
|
+
* await job.promise;
|
|
23
|
+
* await q.onIdle();
|
|
24
|
+
* ```
|
|
25
|
+
*/
|
|
26
|
+
export declare class RetryQManager extends EventEmitter {
|
|
27
|
+
private pendingQueue;
|
|
28
|
+
private runningJobs;
|
|
29
|
+
private failedJobs;
|
|
30
|
+
private completedJobs;
|
|
31
|
+
private cancelledJobs;
|
|
32
|
+
private maxConcurrent;
|
|
33
|
+
private maxHistorySize;
|
|
34
|
+
private registry;
|
|
35
|
+
/** Cleanup callbacks (e.g. external-signal listener removal) keyed by job id. */
|
|
36
|
+
private cleanups;
|
|
37
|
+
/** Resolvers waiting for the queue to become idle. */
|
|
38
|
+
private idleWaiters;
|
|
39
|
+
/** Tracks idle state so the `idle` event only fires on transition. */
|
|
40
|
+
private wasIdle;
|
|
41
|
+
/**
|
|
42
|
+
* @param config - Manager configuration, or a number for `maxConcurrent`
|
|
43
|
+
* (legacy form, kept for backwards compatibility).
|
|
44
|
+
*/
|
|
45
|
+
constructor(config?: RetryQManagerConfig | number);
|
|
46
|
+
/** Subscribe to a manager event. See {@link RetryQEvents}. */
|
|
47
|
+
on<E extends keyof RetryQEvents>(event: E, listener: RetryQEvents[E]): this;
|
|
48
|
+
on(event: string | symbol, listener: (...args: any[]) => void): this;
|
|
49
|
+
/** Subscribe to a manager event once. See {@link RetryQEvents}. */
|
|
50
|
+
once<E extends keyof RetryQEvents>(event: E, listener: RetryQEvents[E]): this;
|
|
51
|
+
once(event: string | symbol, listener: (...args: any[]) => void): this;
|
|
52
|
+
/** Remove a previously registered listener. See {@link RetryQEvents}. */
|
|
53
|
+
off<E extends keyof RetryQEvents>(event: E, listener: RetryQEvents[E]): this;
|
|
54
|
+
off(event: string | symbol, listener: (...args: any[]) => void): this;
|
|
55
|
+
/** Emit a manager event. See {@link RetryQEvents}. */
|
|
56
|
+
emit<E extends keyof RetryQEvents>(event: E, ...args: Parameters<RetryQEvents[E]>): boolean;
|
|
57
|
+
emit(event: string | symbol, ...args: any[]): boolean;
|
|
58
|
+
/**
|
|
59
|
+
* Create and immediately enqueue a job.
|
|
60
|
+
*
|
|
61
|
+
* @typeParam T - Resolved value produced by `fn`.
|
|
62
|
+
* @param fn - Async function to run. Receives an {@link AbortSignal} that
|
|
63
|
+
* aborts on force-cancellation or attempt/`maxTime` timeout.
|
|
64
|
+
* @param options - Per-job configuration (see {@link RetryQJobOptions}).
|
|
65
|
+
* @returns The created {@link RetryQJob}. Await `job.promise` for the result.
|
|
66
|
+
* @throws {Error} If any option fails validation.
|
|
67
|
+
*/
|
|
68
|
+
createJob<T>(fn: (signal?: AbortSignal) => Promise<T>, options?: RetryQJobOptions<T>): RetryQJob<T>;
|
|
69
|
+
/**
|
|
70
|
+
* Cancel a pending or running job.
|
|
71
|
+
*
|
|
72
|
+
* Cooperative (default) cancellation stops future retries and interrupts the
|
|
73
|
+
* delay between them. Force cancellation additionally aborts the in-flight
|
|
74
|
+
* attempt via its {@link AbortSignal}.
|
|
75
|
+
*
|
|
76
|
+
* @param id - Id of the job to cancel.
|
|
77
|
+
* @param force - When `true`, abort in-progress execution. Defaults to `false`.
|
|
78
|
+
*/
|
|
79
|
+
cancelJob(id: string, force?: boolean): void;
|
|
80
|
+
/**
|
|
81
|
+
* Returns a promise that resolves when the queue is fully idle — no pending
|
|
82
|
+
* and no running jobs. Resolves immediately if already idle.
|
|
83
|
+
*
|
|
84
|
+
* @returns A promise that resolves on idle.
|
|
85
|
+
*/
|
|
86
|
+
onIdle(): Promise<void>;
|
|
87
|
+
/**
|
|
88
|
+
* Alias for {@link RetryQManager.onIdle}.
|
|
89
|
+
* @returns A promise that resolves when the queue is idle.
|
|
90
|
+
*/
|
|
91
|
+
drain(): Promise<void>;
|
|
92
|
+
/**
|
|
93
|
+
* Clear retained job history.
|
|
94
|
+
*
|
|
95
|
+
* @param state - Optional terminal state to clear (`completed`, `failed`, or
|
|
96
|
+
* `cancelled`). When omitted, all history is cleared.
|
|
97
|
+
*/
|
|
98
|
+
clearHistory(state?: JobState): void;
|
|
99
|
+
/**
|
|
100
|
+
* Snapshot of all jobs grouped by state.
|
|
101
|
+
* @returns A {@link JobListSnapshot}.
|
|
102
|
+
*/
|
|
103
|
+
listJobs(): JobListSnapshot;
|
|
104
|
+
/**
|
|
105
|
+
* Find a job by id across every state.
|
|
106
|
+
* @param id - Job id.
|
|
107
|
+
* @returns The job, or `null` if not found.
|
|
108
|
+
*/
|
|
109
|
+
findJobById(id: string): RetryQJob | null;
|
|
110
|
+
/**
|
|
111
|
+
* Find all jobs (across every state) with a matching label.
|
|
112
|
+
* @param label - Label to match.
|
|
113
|
+
* @returns Matching jobs.
|
|
114
|
+
*/
|
|
115
|
+
findJobsByLabel(label: string): RetryQJob[];
|
|
116
|
+
/** Evict the oldest entry from a history map when it reaches the size cap. */
|
|
117
|
+
private _evictOldest;
|
|
118
|
+
/** Sort the pending queue by descending priority (stable: FIFO within a tier). */
|
|
119
|
+
private _sortQueue;
|
|
120
|
+
/** Promote pending jobs into running while capacity allows (synchronous). */
|
|
121
|
+
private _processQueue;
|
|
122
|
+
private _isIdle;
|
|
123
|
+
/** Resolve idle waiters and emit `idle` once when the queue drains. */
|
|
124
|
+
private _checkIdle;
|
|
125
|
+
/** Run and remove a job's cleanup callback, if any. */
|
|
126
|
+
private _runCleanup;
|
|
127
|
+
/**
|
|
128
|
+
* Execute a single attempt, bounded by `timeoutMs`. A per-attempt
|
|
129
|
+
* AbortController is linked to the job's controller so force-cancellation
|
|
130
|
+
* still propagates, while a timeout aborts only this attempt (leaving the job
|
|
131
|
+
* free to retry). Uses `Promise.race` so the loop advances even if `fn`
|
|
132
|
+
* ignores the signal.
|
|
133
|
+
*/
|
|
134
|
+
private _runAttempt;
|
|
135
|
+
/** Core retry loop for a single job. */
|
|
136
|
+
private _runJob;
|
|
137
|
+
private _jobSummary;
|
|
138
|
+
}
|
|
139
|
+
//# sourceMappingURL=manager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"manager.d.ts","sourceRoot":"","sources":["../../src/manager.ts"],"names":[],"mappings":"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"}
|