@anishhs/retryq 1.0.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 ADDED
@@ -0,0 +1,254 @@
1
+ ## @anishhs/retryq
2
+
3
+ A tiny, dependency-free retry queue manager for handling multiple concurrent async jobs with priorities, exponential backoff, jitter, cancellation, and simple introspection.
4
+
5
+ - **Concurrency control**: limit how many jobs run at once
6
+ - **Exponential backoff** with configurable base delay, multiplier, jitter
7
+ - **Global time cap** per job via `maxTime`
8
+ - **Priority queueing**: higher priority jobs run first
9
+ - **Cancellation**: cancel pending retries and sleep waits
10
+ - **Introspection**: list jobs, find by id/label
11
+ - **TypeScript** ready with bundled types
12
+
13
+
14
+ ### Installation
15
+
16
+ ```bash
17
+ npm install @anishhs/retryq
18
+ ```
19
+
20
+ Node.js 16+ recommended.
21
+
22
+
23
+ ### Quick start
24
+
25
+ ```ts
26
+ import { RetryQManager } from "@anishhs/retryq";
27
+
28
+ // Allow up to 3 jobs to run concurrently
29
+ const retryQ = new RetryQManager(3);
30
+
31
+ // Any function returning a Promise can be a job
32
+ async function flakyTask() {
33
+ // ... do something that may fail
34
+ }
35
+
36
+ const job = retryQ.createJob(flakyTask, {
37
+ label: "sync-user",
38
+ priority: 10,
39
+ retries: 5,
40
+ delay: 500, // ms
41
+ backoff: 2, // exponential factor
42
+ jitter: 0.1, // ±10%
43
+ maxTime: 5000, // total time window per job (ms)
44
+ });
45
+
46
+ // Get the actual result or throw last error
47
+ job.promise
48
+ .then((value) => console.log("completed", value))
49
+ .catch((err) => console.error("failed", err));
50
+ ```
51
+
52
+
53
+ ### How it works (in short)
54
+ - Jobs are queued and sorted by `priority` (higher first).
55
+ - Up to `maxConcurrent` jobs can run simultaneously.
56
+ - Each job retries up to `retries` times with exponential backoff starting from `delay` and multiplying by `backoff`.
57
+ - A random jitter (±`jitter` fraction) is applied to each wait to avoid thundering-herd patterns.
58
+ - The total elapsed time per job is capped by `maxTime`.
59
+ - `job.promise` resolves with the function’s resolved value, or rejects with the last error.
60
+
61
+
62
+ ## API
63
+
64
+ ### `class RetryQManager`
65
+
66
+ #### `constructor(maxConcurrent?: number)`
67
+ - **maxConcurrent**: maximum number of jobs allowed to run at once. Default: `Infinity`.
68
+
69
+ #### `createJob(fn: () => Promise<any>, options?: RetryQJobOptions): RetryQJob`
70
+ Queues and starts a job. Returns a `RetryQJob` with a `promise` that resolves with the function’s return value or rejects after exhausting retries.
71
+
72
+ - `fn`: async function to execute (must return a Promise)
73
+ - `options`: optional behavior overrides (see below)
74
+
75
+ #### `cancelJob(id: string): void`
76
+ Cancels a job by id. If the job is sleeping between retries, the sleep is interrupted. If the job’s function is currently executing, it will not be forcibly aborted (user code should be cooperative if needed), but further retries are stopped and the job is marked `cancelled`.
77
+
78
+ #### `listJobs()`
79
+ Returns a snapshot of jobs grouped by state:
80
+ ```ts
81
+ {
82
+ pending: Array<{ id, label, state, retriesLeft, priority }>,
83
+ running: Array<{ id, label, state, retriesLeft, priority }>,
84
+ failed: Array<{ id, label, state, retriesLeft, priority }>,
85
+ completed: Array<{ id, label, state, retriesLeft, priority }>,
86
+ }
87
+ ```
88
+
89
+ #### `findJobById(id: string)`
90
+ Returns the `RetryQJob` if found in any state, otherwise `null`.
91
+
92
+ #### `findJobsByLabel(label: string)`
93
+ Returns an array of `RetryQJob` with the given label across any state.
94
+
95
+
96
+ ### Types
97
+
98
+ ```ts
99
+ export type RetryQJobOptions = {
100
+ retries?: number; // default 3
101
+ delay?: number; // initial delay in ms, default 1000
102
+ backoff?: number; // multiplier, default 2
103
+ maxTime?: number; // total allowed time in ms, default 5000
104
+ jitter?: number; // fraction, e.g., 0.1 = ±10%, default 0.1
105
+ label?: string; // human-readable tag
106
+ priority?: number; // higher runs sooner, default 1
107
+ };
108
+
109
+ export type JobState =
110
+ | "pending"
111
+ | "running"
112
+ | "completed"
113
+ | "failed"
114
+ | "cancelled";
115
+
116
+ export interface RetryQJob {
117
+ id: string;
118
+ label: string;
119
+ state: JobState;
120
+ priority: number;
121
+ retriesLeft: number;
122
+ promise: Promise<any>; // resolves to your function’s actual value
123
+ cancel: () => void; // convenience wrapper for cancelJob
124
+ fn: () => Promise<any>;
125
+ options: RetryQJobOptions;
126
+ createdAt: number;
127
+ startedAt?: number;
128
+ finishedAt?: number;
129
+ error?: any;
130
+ }
131
+ ```
132
+
133
+
134
+ ## Usage patterns
135
+
136
+ ### Priorities and concurrency
137
+ ```ts
138
+ const q = new RetryQManager(2); // two at a time
139
+
140
+ q.createJob(taskA, { label: "A", priority: 5 });
141
+ q.createJob(taskB, { label: "B", priority: 1 });
142
+ q.createJob(taskC, { label: "C", priority: 10 });
143
+
144
+ // C and A start first (highest priorities), then B.
145
+ ```
146
+
147
+ ### Custom backoff and jitter
148
+ ```ts
149
+ q.createJob(fetchWithRetry, {
150
+ retries: 4,
151
+ delay: 250,
152
+ backoff: 1.5,
153
+ jitter: 0.2, // ±20%
154
+ maxTime: 8000,
155
+ });
156
+ ```
157
+
158
+ ### Cancellation
159
+ ```ts
160
+ const job = q.createJob(sendEmail, { label: "email#42" });
161
+
162
+ // later
163
+ q.cancelJob(job.id);
164
+ // or
165
+ job.cancel();
166
+ ```
167
+
168
+ If the job is sleeping between retries, the sleep is aborted immediately. If it’s executing your function, it will not be forcibly interrupted—cooperative cancellation is advised for long-running tasks.
169
+
170
+ ### Introspection
171
+ ```ts
172
+ const { pending, running, failed, completed } = q.listJobs();
173
+
174
+ const maybe = q.findJobById("job-123");
175
+ const allEmailJobs = q.findJobsByLabel("email#42");
176
+ ```
177
+
178
+
179
+ ## Error handling
180
+ - When a job ultimately fails (retries exhausted or `maxTime` exceeded), its `promise` rejects with the last captured error.
181
+ - Failed and cancelled jobs are tracked in `listJobs()` for post-mortem or metrics.
182
+
183
+
184
+ ## Defaults
185
+ - `retries`: 3
186
+ - `delay`: 1000 ms
187
+ - `backoff`: 2
188
+ - `maxTime`: 5000 ms
189
+ - `jitter`: 0.1 (±10%)
190
+ - `priority`: 1
191
+ - `maxConcurrent`: `Infinity` (constructor)
192
+
193
+
194
+ ## Common recipes
195
+
196
+ ### Retrying HTTP with fetch/axios
197
+ ```ts
198
+ async function getJson(url: string) {
199
+ const res = await fetch(url);
200
+ if (!res.ok) throw new Error("Network error " + res.status);
201
+ return res.json();
202
+ }
203
+
204
+ const q = new RetryQManager(4);
205
+ const job = q.createJob(() => getJson("https://api.example.com/data"), {
206
+ retries: 6,
207
+ delay: 300,
208
+ backoff: 2,
209
+ jitter: 0.15,
210
+ maxTime: 5000,
211
+ });
212
+
213
+ const data = await job.promise;
214
+ ```
215
+
216
+ ### Queueing many tasks with labels
217
+ ```ts
218
+ const q = new RetryQManager(5);
219
+
220
+ for (const userId of users) {
221
+ q.createJob(() => syncUser(userId), {
222
+ label: `sync-user:${userId}`,
223
+ priority: 5,
224
+ });
225
+ }
226
+ ```
227
+
228
+
229
+ ## Notes and caveats
230
+ - Cancellation does not forcibly abort your `fn` while it’s running; design long-running tasks to be cancellable if required.
231
+ - `maxTime` is a soft cap applied across the job’s lifetime. If elapsed time exceeds `maxTime`, the manager stops retrying and marks the job failed.
232
+ - The manager generates ids like `job-<timestamp>-<random>`; you can set a human-readable `label` for easier lookups.
233
+
234
+
235
+ ## Development
236
+
237
+ Scripts:
238
+ ```bash
239
+ # build TypeScript to dist/
240
+ npm run build
241
+
242
+ # run compiled output
243
+ npm start
244
+
245
+ # dev-run directly from src/
246
+ npm run dev
247
+ ```
248
+
249
+ `tsconfig.json` emits `dist/index.js` and type declarations in `dist/index.d.ts`.
250
+
251
+
252
+ ## License
253
+
254
+ ISC © Anish Shekh
@@ -0,0 +1,76 @@
1
+ export type RetryQJobOptions = {
2
+ retries?: number;
3
+ delay?: number;
4
+ backoff?: number;
5
+ maxTime?: number;
6
+ jitter?: number;
7
+ label?: string;
8
+ priority?: number;
9
+ };
10
+ export type JobState = "pending" | "running" | "completed" | "failed" | "cancelled";
11
+ export interface RetryQJob {
12
+ id: string;
13
+ label: string;
14
+ state: JobState;
15
+ priority: number;
16
+ retriesLeft: number;
17
+ promise: Promise<any>;
18
+ cancel: () => void;
19
+ fn: () => Promise<any>;
20
+ options: RetryQJobOptions;
21
+ createdAt: number;
22
+ startedAt?: number;
23
+ finishedAt?: number;
24
+ error?: any;
25
+ }
26
+ export interface CancelableFunction {
27
+ (): void;
28
+ cancelSleep?: () => void;
29
+ }
30
+ export declare class RetryQManager {
31
+ private pendingQueue;
32
+ private runningJobs;
33
+ private failedJobs;
34
+ private completedJobs;
35
+ private maxConcurrent;
36
+ private registry;
37
+ constructor(maxConcurrent?: number);
38
+ createJob(fn: () => Promise<any>, options?: RetryQJobOptions): RetryQJob;
39
+ private _sortQueue;
40
+ private _processQueue;
41
+ private _runJob;
42
+ cancelJob(id: string): void;
43
+ listJobs(): {
44
+ pending: {
45
+ id: string;
46
+ label: string;
47
+ state: JobState;
48
+ retriesLeft: number;
49
+ priority: number;
50
+ }[];
51
+ running: {
52
+ id: string;
53
+ label: string;
54
+ state: JobState;
55
+ retriesLeft: number;
56
+ priority: number;
57
+ }[];
58
+ failed: {
59
+ id: string;
60
+ label: string;
61
+ state: JobState;
62
+ retriesLeft: number;
63
+ priority: number;
64
+ }[];
65
+ completed: {
66
+ id: string;
67
+ label: string;
68
+ state: JobState;
69
+ retriesLeft: number;
70
+ priority: number;
71
+ }[];
72
+ };
73
+ findJobById(id: string): RetryQJob | null;
74
+ findJobsByLabel(label: string): RetryQJob[];
75
+ private _jobSummary;
76
+ }
package/dist/index.js ADDED
@@ -0,0 +1,165 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.RetryQManager = void 0;
13
+ // Custom ID generator using timestamp + larger random suffix
14
+ function randomId() {
15
+ return `job-${Date.now()}-${Math.random().toString(36).slice(2, 12)}`;
16
+ }
17
+ function sleep(ms, cancelFn) {
18
+ return new Promise((resolve, reject) => {
19
+ const timer = setTimeout(() => resolve(), ms);
20
+ if (cancelFn) {
21
+ cancelFn.cancelSleep = () => {
22
+ clearTimeout(timer);
23
+ reject(new Error("RetryQ job cancelled"));
24
+ };
25
+ }
26
+ });
27
+ }
28
+ class RetryQManager {
29
+ constructor(maxConcurrent = Infinity) {
30
+ this.pendingQueue = [];
31
+ this.runningJobs = new Map();
32
+ this.failedJobs = new Map();
33
+ this.completedJobs = new Map();
34
+ this.registry = new Map();
35
+ this.maxConcurrent = maxConcurrent;
36
+ }
37
+ createJob(fn, options = {}) {
38
+ var _a, _b;
39
+ const id = randomId();
40
+ const job = {
41
+ id,
42
+ label: options.label || id,
43
+ state: "pending",
44
+ priority: (_a = options.priority) !== null && _a !== void 0 ? _a : 1,
45
+ retriesLeft: (_b = options.retries) !== null && _b !== void 0 ? _b : 3,
46
+ promise: Promise.resolve(), // placeholder
47
+ cancel: () => this.cancelJob(id),
48
+ fn,
49
+ options,
50
+ createdAt: Date.now(),
51
+ };
52
+ job.promise = this._runJob(job);
53
+ this.pendingQueue.push(job);
54
+ this._sortQueue();
55
+ this._processQueue();
56
+ return job;
57
+ }
58
+ _sortQueue() {
59
+ this.pendingQueue.sort((a, b) => b.priority - a.priority);
60
+ }
61
+ _processQueue() {
62
+ return __awaiter(this, void 0, void 0, function* () {
63
+ while (this.runningJobs.size < this.maxConcurrent &&
64
+ this.pendingQueue.length > 0) {
65
+ const job = this.pendingQueue.shift();
66
+ // job.promise already set in createJob
67
+ this.runningJobs.set(job.id, job);
68
+ }
69
+ });
70
+ }
71
+ _runJob(job) {
72
+ return __awaiter(this, void 0, void 0, function* () {
73
+ var _a;
74
+ job.state = "running";
75
+ job.startedAt = Date.now();
76
+ const cancelFn = () => { };
77
+ this.registry.set(job.id, cancelFn);
78
+ const { delay = 1000, backoff = 2, maxTime = 5000, jitter = 0.1, } = job.options;
79
+ let currentDelay = delay;
80
+ while (job.retriesLeft > 0) {
81
+ const elapsed = Date.now() - ((_a = job.startedAt) !== null && _a !== void 0 ? _a : Date.now());
82
+ if (elapsed >= maxTime)
83
+ break;
84
+ try {
85
+ const result = yield job.fn();
86
+ job.state = "completed";
87
+ job.finishedAt = Date.now();
88
+ this.completedJobs.set(job.id, job);
89
+ this.runningJobs.delete(job.id);
90
+ this._processQueue();
91
+ return result; // returns actual value
92
+ }
93
+ catch (err) {
94
+ job.retriesLeft--;
95
+ job.error = err;
96
+ if (job.retriesLeft <= 0)
97
+ break;
98
+ // jitter
99
+ const jitterAmount = currentDelay * jitter;
100
+ let adjustedDelay = currentDelay + (Math.random() * 2 - 1) * jitterAmount;
101
+ adjustedDelay = Math.min(adjustedDelay, maxTime - elapsed);
102
+ if (adjustedDelay > 0)
103
+ yield sleep(adjustedDelay, cancelFn);
104
+ currentDelay *= backoff;
105
+ }
106
+ }
107
+ if (!["cancelled", "failed"].includes(job.state))
108
+ job.state = "failed";
109
+ job.finishedAt = Date.now();
110
+ this.runningJobs.delete(job.id);
111
+ this.failedJobs.set(job.id, job);
112
+ this._processQueue();
113
+ throw job.error || new Error("Job failed");
114
+ });
115
+ }
116
+ cancelJob(id) {
117
+ const job = this.runningJobs.get(id) || this.pendingQueue.find((j) => j.id === id);
118
+ if (!job)
119
+ return;
120
+ job.state = "cancelled";
121
+ job.error = new Error("Job cancelled");
122
+ job.finishedAt = Date.now();
123
+ this.runningJobs.delete(id);
124
+ this.pendingQueue = this.pendingQueue.filter((j) => j.id !== id);
125
+ this.failedJobs.set(id, job);
126
+ const cancelFn = this.registry.get(id);
127
+ if (cancelFn === null || cancelFn === void 0 ? void 0 : cancelFn.cancelSleep)
128
+ cancelFn.cancelSleep();
129
+ }
130
+ listJobs() {
131
+ return {
132
+ pending: this.pendingQueue.map((j) => this._jobSummary(j)),
133
+ running: Array.from(this.runningJobs.values()).map((j) => this._jobSummary(j)),
134
+ failed: Array.from(this.failedJobs.values()).map((j) => this._jobSummary(j)),
135
+ completed: Array.from(this.completedJobs.values()).map((j) => this._jobSummary(j)),
136
+ };
137
+ }
138
+ findJobById(id) {
139
+ return (this.runningJobs.get(id) ||
140
+ this.pendingQueue.find((j) => j.id === id) ||
141
+ this.failedJobs.get(id) ||
142
+ this.completedJobs.get(id) ||
143
+ null);
144
+ }
145
+ findJobsByLabel(label) {
146
+ const all = [
147
+ ...Array.from(this.runningJobs.values()),
148
+ ...this.pendingQueue,
149
+ ...Array.from(this.failedJobs.values()),
150
+ ...Array.from(this.completedJobs.values()),
151
+ ];
152
+ return all.filter((j) => j.label === label);
153
+ }
154
+ _jobSummary(job) {
155
+ return {
156
+ id: job.id,
157
+ label: job.label,
158
+ state: job.state,
159
+ retriesLeft: job.retriesLeft,
160
+ priority: job.priority,
161
+ };
162
+ }
163
+ }
164
+ exports.RetryQManager = RetryQManager;
165
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,35 @@
1
+ {
2
+ "name": "@anishhs/retryq",
3
+ "version": "1.0.0",
4
+ "description": "Retry manager for handling multiple concurrent jobs",
5
+ "main": "dist/index.js",
6
+ "types": "dist/index.d.ts",
7
+ "files": [
8
+ "dist"
9
+ ],
10
+ "scripts": {
11
+ "prepare": "npm run build",
12
+ "build": "tsc",
13
+ "start": "node dist/index.js",
14
+ "dev": "ts-node src/index.ts"
15
+ },
16
+ "keywords": [
17
+ "retryq",
18
+ "retry",
19
+ "queue",
20
+ "manager",
21
+ "priority",
22
+ "jobs",
23
+ "asynchronous",
24
+ "concurrent",
25
+ "typescript",
26
+ "anishhs"
27
+ ],
28
+ "author": "Anish Shekh",
29
+ "license": "ISC",
30
+ "devDependencies": {
31
+ "@types/node": "^24.6.1",
32
+ "ts-node": "^10.9.2",
33
+ "typescript": "^5.9.3"
34
+ }
35
+ }