quantam-async 0.1.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/LICENSE +22 -0
- package/README.md +198 -0
- package/dist/bench.d.ts +2 -0
- package/dist/bench.d.ts.map +1 -0
- package/dist/bench.js +25 -0
- package/dist/bench.js.map +1 -0
- package/dist/core.d.ts +27 -0
- package/dist/core.d.ts.map +1 -0
- package/dist/core.js +175 -0
- package/dist/core.js.map +1 -0
- package/dist/examples/basic.d.ts +2 -0
- package/dist/examples/basic.d.ts.map +1 -0
- package/dist/examples/basic.js +25 -0
- package/dist/examples/basic.js.map +1 -0
- package/dist/examples/batch.d.ts +2 -0
- package/dist/examples/batch.d.ts.map +1 -0
- package/dist/examples/batch.js +18 -0
- package/dist/examples/batch.js.map +1 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +11 -0
- package/dist/index.js.map +1 -0
- package/dist/tests/quantam.test.d.ts +2 -0
- package/dist/tests/quantam.test.d.ts.map +1 -0
- package/dist/tests/quantam.test.js +66 -0
- package/dist/tests/quantam.test.js.map +1 -0
- package/dist/types.d.ts +31 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +6 -0
- package/dist/types.js.map +1 -0
- package/examples/basic.d.ts +2 -0
- package/examples/basic.d.ts.map +1 -0
- package/examples/basic.js +25 -0
- package/examples/basic.js.map +1 -0
- package/examples/basic.ts +0 -0
- package/examples/batch.d.ts +2 -0
- package/examples/batch.d.ts.map +1 -0
- package/examples/batch.js +18 -0
- package/examples/batch.js.map +1 -0
- package/examples/batch.ts +0 -0
- package/package.json +29 -0
- package/src/bench.ts +28 -0
- package/src/core.ts +244 -0
- package/src/examples/basic.ts +42 -0
- package/src/examples/batch.ts +20 -0
- package/src/index.ts +7 -0
- package/src/tests/quantam.test.ts +74 -0
- package/src/types.ts +36 -0
- package/tsconfig.json +20 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Quantam contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
22
|
+
|
package/README.md
ADDED
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
# Quantam
|
|
2
|
+
|
|
3
|
+
A lightweight async workflow engine that lets developers compose, run, and control complex task pipelines with retries, parallel execution, timeouts, and cancellation using a simple fluent API.
|
|
4
|
+
|
|
5
|
+
## The Problem
|
|
6
|
+
|
|
7
|
+
Writing reliable async code is hard. Without a framework, you end up with:
|
|
8
|
+
|
|
9
|
+
- **Messy Promise chains** — impossible to read after 3 levels
|
|
10
|
+
- **Nested try/catch** — error handling scattered everywhere
|
|
11
|
+
- **Broken retries** — manual retry logic that fails silently
|
|
12
|
+
- **Race conditions** — concurrent tasks stepping on each other
|
|
13
|
+
- **No cancellation** — long-running jobs can't be stopped
|
|
14
|
+
- **Lost context** — data and state disappear between steps
|
|
15
|
+
- **Non-deterministic behavior** — same input, different output
|
|
16
|
+
|
|
17
|
+
## The Solution
|
|
18
|
+
|
|
19
|
+
Quantam gives you one clean, powerful API:
|
|
20
|
+
|
|
21
|
+
```typescript
|
|
22
|
+
const result = await quantam()
|
|
23
|
+
.step(fetchUser)
|
|
24
|
+
.step(enrichUserData)
|
|
25
|
+
.parallel([saveToCache, logAnalytics])
|
|
26
|
+
.retry(3)
|
|
27
|
+
.timeout(5000)
|
|
28
|
+
.run(userId);
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## Features
|
|
32
|
+
|
|
33
|
+
- ✅ **Fluent API** — read like prose, write like a plan
|
|
34
|
+
- ✅ **Step-by-step execution** — functions run in order with data flowing between them
|
|
35
|
+
- ✅ **Parallel execution** — run multiple steps concurrently with `parallel()`
|
|
36
|
+
- ✅ **Automatic retries** — built-in exponential backoff with `retryCount` in context
|
|
37
|
+
- ✅ **Timeouts** — enforce SLA with global or per-step limits
|
|
38
|
+
- ✅ **Cancellation** — AbortController integration for clean shutdown or `withSignal()`
|
|
39
|
+
- ✅ **Batch processing** — run many inputs efficiently with `runMany()`
|
|
40
|
+
- ✅ **Error propagation** — catch errors once at the end
|
|
41
|
+
- ✅ **Deterministic** — same input always produces same behavior
|
|
42
|
+
- ✅ **Testable** — mock steps, assert flows
|
|
43
|
+
|
|
44
|
+
## Install
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
npm install quantam-async
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
## Quick Start
|
|
51
|
+
|
|
52
|
+
```typescript
|
|
53
|
+
import { quantam } from 'quantam-async';
|
|
54
|
+
|
|
55
|
+
// Define your async functions
|
|
56
|
+
async function fetchUser(id: string) {
|
|
57
|
+
return { id, name: 'Alice' };
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
async function fetchOrders(user: any) {
|
|
61
|
+
return { user, orders: [1, 2, 3] };
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
async function enrichData(data: any) {
|
|
65
|
+
return { ...data, enriched: true };
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// Compose and run
|
|
69
|
+
const result = await quantam()
|
|
70
|
+
.step(fetchUser)
|
|
71
|
+
.step(fetchOrders)
|
|
72
|
+
.step(enrichData)
|
|
73
|
+
.run('user-123');
|
|
74
|
+
|
|
75
|
+
console.log(result);
|
|
76
|
+
// { user: { id: 'user-123', name: 'Alice' }, orders: [...], enriched: true }
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
## Core API
|
|
80
|
+
|
|
81
|
+
### `quantam()`
|
|
82
|
+
|
|
83
|
+
Creates a new flow.
|
|
84
|
+
|
|
85
|
+
```typescript
|
|
86
|
+
const flow = quantam();
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
### `.step(fn)`
|
|
90
|
+
|
|
91
|
+
Add a single async step. Each step receives the output of the previous step.
|
|
92
|
+
|
|
93
|
+
```typescript
|
|
94
|
+
flow.step(async (input) => { /* process */ return output; })
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
### `.parallel(fns)`
|
|
98
|
+
|
|
99
|
+
Run multiple steps concurrently. All functions receive the same input. Results are collected in an array.
|
|
100
|
+
|
|
101
|
+
```typescript
|
|
102
|
+
flow.parallel([
|
|
103
|
+
async (input) => { /* task A */ },
|
|
104
|
+
async (input) => { /* task B */ },
|
|
105
|
+
])
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
### `.retry(count, delayMs?)`
|
|
109
|
+
|
|
110
|
+
Retry the last step on failure with exponential backoff.
|
|
111
|
+
|
|
112
|
+
```typescript
|
|
113
|
+
flow.retry(3, 100); // Retry 3 times, start with 100ms delay
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
### `.timeout(ms)`
|
|
117
|
+
|
|
118
|
+
Enforce a timeout on the entire pipeline.
|
|
119
|
+
|
|
120
|
+
```typescript
|
|
121
|
+
flow.timeout(5000); // 5 second limit
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
### `.stepTimeout(ms)`
|
|
125
|
+
|
|
126
|
+
Apply a timeout only to the most recent step.
|
|
127
|
+
|
|
128
|
+
```typescript
|
|
129
|
+
flow
|
|
130
|
+
.step(fetchUser)
|
|
131
|
+
.stepTimeout(200); // only this step is limited to 200ms
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
### `.withSignal(signal)`
|
|
135
|
+
|
|
136
|
+
Bind an AbortSignal to the flow for reuse.
|
|
137
|
+
|
|
138
|
+
```typescript
|
|
139
|
+
const controller = new AbortController();
|
|
140
|
+
|
|
141
|
+
const flow = quantam()
|
|
142
|
+
.withSignal(controller.signal)
|
|
143
|
+
.step(longTask);
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
### `.run(input)`
|
|
147
|
+
|
|
148
|
+
Execute the pipeline with the given input. Returns a Promise.
|
|
149
|
+
|
|
150
|
+
```typescript
|
|
151
|
+
const result = await flow.run(data);
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
### `.runMany(inputs, options?)`
|
|
155
|
+
|
|
156
|
+
Run the same flow for many inputs with optional concurrency control.
|
|
157
|
+
|
|
158
|
+
```typescript
|
|
159
|
+
const inputs = Array.from({ length: 100000 }, (_, i) => i);
|
|
160
|
+
const results = await flow.runMany(inputs, { concurrency: 512 });
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
## Error Handling
|
|
164
|
+
|
|
165
|
+
Errors bubble up to a single promise rejection:
|
|
166
|
+
|
|
167
|
+
```typescript
|
|
168
|
+
try {
|
|
169
|
+
const result = await quantam()
|
|
170
|
+
.step(riskyOperation)
|
|
171
|
+
.run(input);
|
|
172
|
+
} catch (error) {
|
|
173
|
+
console.error('Pipeline failed:', error.message);
|
|
174
|
+
}
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
## Cancellation
|
|
178
|
+
|
|
179
|
+
Abort a running pipeline:
|
|
180
|
+
|
|
181
|
+
```typescript
|
|
182
|
+
const controller = new AbortController();
|
|
183
|
+
|
|
184
|
+
const promise = quantam()
|
|
185
|
+
.step(longTask)
|
|
186
|
+
.run(input, { signal: controller.signal });
|
|
187
|
+
|
|
188
|
+
// Later...
|
|
189
|
+
controller.abort();
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
## Version
|
|
193
|
+
|
|
194
|
+
**v0.1.0** — Core features only. API subject to change.
|
|
195
|
+
|
|
196
|
+
## License
|
|
197
|
+
|
|
198
|
+
MIT
|
package/dist/bench.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bench.d.ts","sourceRoot":"","sources":["../src/bench.ts"],"names":[],"mappings":""}
|
package/dist/bench.js
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const index_1 = require("./index");
|
|
4
|
+
async function main() {
|
|
5
|
+
const size = 100000;
|
|
6
|
+
const inputs = Array.from({ length: size }, (_, i) => i);
|
|
7
|
+
const flow = (0, index_1.quantam)().step(async (n) => n + 1);
|
|
8
|
+
const start = Date.now();
|
|
9
|
+
const results = await flow.runMany(inputs, { concurrency: 512 });
|
|
10
|
+
const durationMs = Date.now() - start;
|
|
11
|
+
const opsPerSec = durationMs > 0 ? size / (durationMs / 1000) : 0;
|
|
12
|
+
console.log(JSON.stringify({
|
|
13
|
+
size,
|
|
14
|
+
concurrency: 512,
|
|
15
|
+
durationMs,
|
|
16
|
+
opsPerSec,
|
|
17
|
+
first: results[0],
|
|
18
|
+
last: results[results.length - 1],
|
|
19
|
+
}));
|
|
20
|
+
}
|
|
21
|
+
main().catch((err) => {
|
|
22
|
+
console.error(err);
|
|
23
|
+
process.exitCode = 1;
|
|
24
|
+
});
|
|
25
|
+
//# sourceMappingURL=bench.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bench.js","sourceRoot":"","sources":["../src/bench.ts"],"names":[],"mappings":";;AAAA,mCAAkC;AAElC,KAAK,UAAU,IAAI;IACjB,MAAM,IAAI,GAAG,MAAM,CAAC;IACpB,MAAM,MAAM,GAAG,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC;IACzD,MAAM,IAAI,GAAG,IAAA,eAAO,GAAU,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IACxD,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IACzB,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,WAAW,EAAE,GAAG,EAAE,CAAC,CAAC;IACjE,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK,CAAC;IACtC,MAAM,SAAS,GAAG,UAAU,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,UAAU,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAElE,OAAO,CAAC,GAAG,CACT,IAAI,CAAC,SAAS,CAAC;QACb,IAAI;QACJ,WAAW,EAAE,GAAG;QAChB,UAAU;QACV,SAAS;QACT,KAAK,EAAE,OAAO,CAAC,CAAC,CAAC;QACjB,IAAI,EAAE,OAAO,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC;KAClC,CAAC,CACH,CAAC;AACJ,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;IACnB,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IACnB,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;AACvB,CAAC,CAAC,CAAC"}
|
package/dist/core.d.ts
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Quantam Core Implementation
|
|
3
|
+
* Fluent API for composing async pipelines
|
|
4
|
+
*/
|
|
5
|
+
import { AsyncFn, Flow, FlowOptions } from './types';
|
|
6
|
+
export declare class Quantam<T = any> implements Flow<T> {
|
|
7
|
+
private steps;
|
|
8
|
+
private timeoutMs?;
|
|
9
|
+
private abortSignal?;
|
|
10
|
+
step<R>(fn: AsyncFn<T, R>): Quantam<R>;
|
|
11
|
+
parallel<R>(fns: AsyncFn<T, any>[]): Quantam<R[]>;
|
|
12
|
+
retry(count: number, delayMs?: number): Quantam<T>;
|
|
13
|
+
stepTimeout(ms: number): Quantam<T>;
|
|
14
|
+
withSignal(signal: AbortSignal): Quantam<T>;
|
|
15
|
+
timeout(ms: number): Quantam<T>;
|
|
16
|
+
runMany(inputs: T[], options?: FlowOptions & {
|
|
17
|
+
concurrency?: number;
|
|
18
|
+
}): Promise<T[]>;
|
|
19
|
+
run(input: T, options?: FlowOptions): Promise<T>;
|
|
20
|
+
private executeSingleStep;
|
|
21
|
+
private executeParallelSteps;
|
|
22
|
+
private checkAborted;
|
|
23
|
+
private createTimeout;
|
|
24
|
+
private sleep;
|
|
25
|
+
}
|
|
26
|
+
export declare function quantam<T = any>(): Quantam<T>;
|
|
27
|
+
//# sourceMappingURL=core.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"core.d.ts","sourceRoot":"","sources":["../src/core.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,WAAW,EAAoB,MAAM,SAAS,CAAC;AAWvE,qBAAa,OAAO,CAAC,CAAC,GAAG,GAAG,CAAE,YAAW,IAAI,CAAC,CAAC,CAAC;IAC9C,OAAO,CAAC,KAAK,CAAc;IAC3B,OAAO,CAAC,SAAS,CAAC,CAAS;IAC3B,OAAO,CAAC,WAAW,CAAC,CAAc;IAElC,IAAI,CAAC,CAAC,EAAE,EAAE,EAAE,OAAO,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC;IAStC,QAAQ,CAAC,CAAC,EAAE,GAAG,EAAE,OAAO,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,GAAG,OAAO,CAAC,CAAC,EAAE,CAAC;IASjD,KAAK,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,GAAE,MAAY,GAAG,OAAO,CAAC,CAAC,CAAC;IAevD,WAAW,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC;IAcnC,UAAU,CAAC,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,CAAC,CAAC;IAQ3C,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC;IAQzB,OAAO,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,OAAO,CAAC,EAAE,WAAW,GAAG;QAAE,WAAW,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,CAAC,EAAE,CAAC;IAiCpF,GAAG,CAAC,KAAK,EAAE,CAAC,EAAE,OAAO,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,CAAC,CAAC;YAwCxC,iBAAiB;YAsCjB,oBAAoB;IAelC,OAAO,CAAC,YAAY;IAMpB,OAAO,CAAC,aAAa;IAMrB,OAAO,CAAC,KAAK;CAiBd;AAED,wBAAgB,OAAO,CAAC,CAAC,GAAG,GAAG,KAAK,OAAO,CAAC,CAAC,CAAC,CAE7C"}
|
package/dist/core.js
ADDED
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Quantam Core Implementation
|
|
4
|
+
* Fluent API for composing async pipelines
|
|
5
|
+
*/
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.Quantam = void 0;
|
|
8
|
+
exports.quantam = quantam;
|
|
9
|
+
class Quantam {
|
|
10
|
+
constructor() {
|
|
11
|
+
this.steps = [];
|
|
12
|
+
}
|
|
13
|
+
step(fn) {
|
|
14
|
+
const newFlow = new Quantam();
|
|
15
|
+
newFlow.steps = [...this.steps];
|
|
16
|
+
newFlow.timeoutMs = this.timeoutMs;
|
|
17
|
+
newFlow.abortSignal = this.abortSignal;
|
|
18
|
+
newFlow.steps.push({ type: 'single', fn });
|
|
19
|
+
return newFlow;
|
|
20
|
+
}
|
|
21
|
+
parallel(fns) {
|
|
22
|
+
const newFlow = new Quantam();
|
|
23
|
+
newFlow.steps = [...this.steps];
|
|
24
|
+
newFlow.timeoutMs = this.timeoutMs;
|
|
25
|
+
newFlow.abortSignal = this.abortSignal;
|
|
26
|
+
newFlow.steps.push({ type: 'parallel', fns });
|
|
27
|
+
return newFlow;
|
|
28
|
+
}
|
|
29
|
+
retry(count, delayMs = 100) {
|
|
30
|
+
const newFlow = new Quantam();
|
|
31
|
+
newFlow.steps = [...this.steps];
|
|
32
|
+
newFlow.timeoutMs = this.timeoutMs;
|
|
33
|
+
newFlow.abortSignal = this.abortSignal;
|
|
34
|
+
if (newFlow.steps.length > 0) {
|
|
35
|
+
const lastStep = newFlow.steps[newFlow.steps.length - 1];
|
|
36
|
+
lastStep.retries = count;
|
|
37
|
+
lastStep.retryDelay = delayMs;
|
|
38
|
+
}
|
|
39
|
+
return newFlow;
|
|
40
|
+
}
|
|
41
|
+
stepTimeout(ms) {
|
|
42
|
+
const newFlow = new Quantam();
|
|
43
|
+
newFlow.steps = [...this.steps];
|
|
44
|
+
newFlow.timeoutMs = this.timeoutMs;
|
|
45
|
+
newFlow.abortSignal = this.abortSignal;
|
|
46
|
+
if (newFlow.steps.length > 0) {
|
|
47
|
+
const lastStep = newFlow.steps[newFlow.steps.length - 1];
|
|
48
|
+
lastStep.timeout = ms;
|
|
49
|
+
}
|
|
50
|
+
return newFlow;
|
|
51
|
+
}
|
|
52
|
+
withSignal(signal) {
|
|
53
|
+
const newFlow = new Quantam();
|
|
54
|
+
newFlow.steps = [...this.steps];
|
|
55
|
+
newFlow.timeoutMs = this.timeoutMs;
|
|
56
|
+
newFlow.abortSignal = signal;
|
|
57
|
+
return newFlow;
|
|
58
|
+
}
|
|
59
|
+
timeout(ms) {
|
|
60
|
+
const newFlow = new Quantam();
|
|
61
|
+
newFlow.steps = [...this.steps];
|
|
62
|
+
newFlow.timeoutMs = ms;
|
|
63
|
+
newFlow.abortSignal = this.abortSignal;
|
|
64
|
+
return newFlow;
|
|
65
|
+
}
|
|
66
|
+
async runMany(inputs, options) {
|
|
67
|
+
const configuredConcurrency = options?.concurrency;
|
|
68
|
+
const concurrency = configuredConcurrency != null ? configuredConcurrency : inputs.length;
|
|
69
|
+
if (inputs.length === 0) {
|
|
70
|
+
return [];
|
|
71
|
+
}
|
|
72
|
+
if (concurrency <= 0 || concurrency >= inputs.length) {
|
|
73
|
+
return Promise.all(inputs.map((input) => this.run(input, options)));
|
|
74
|
+
}
|
|
75
|
+
const results = new Array(inputs.length);
|
|
76
|
+
let index = 0;
|
|
77
|
+
const worker = async () => {
|
|
78
|
+
while (true) {
|
|
79
|
+
const currentIndex = index++;
|
|
80
|
+
if (currentIndex >= inputs.length) {
|
|
81
|
+
break;
|
|
82
|
+
}
|
|
83
|
+
results[currentIndex] = await this.run(inputs[currentIndex], options);
|
|
84
|
+
}
|
|
85
|
+
};
|
|
86
|
+
const workers = [];
|
|
87
|
+
const workerCount = Math.min(concurrency, inputs.length);
|
|
88
|
+
for (let i = 0; i < workerCount; i++) {
|
|
89
|
+
workers.push(worker());
|
|
90
|
+
}
|
|
91
|
+
await Promise.all(workers);
|
|
92
|
+
return results;
|
|
93
|
+
}
|
|
94
|
+
async run(input, options) {
|
|
95
|
+
const signal = options?.signal || this.abortSignal;
|
|
96
|
+
let result = input;
|
|
97
|
+
const context = {
|
|
98
|
+
signal,
|
|
99
|
+
stepIndex: 0,
|
|
100
|
+
retryCount: 0,
|
|
101
|
+
};
|
|
102
|
+
for (let i = 0; i < this.steps.length; i++) {
|
|
103
|
+
this.checkAborted(signal);
|
|
104
|
+
const step = this.steps[i];
|
|
105
|
+
context.stepIndex = i;
|
|
106
|
+
context.retryCount = 0;
|
|
107
|
+
if (step.type === 'single' && step.fn) {
|
|
108
|
+
result = await this.executeSingleStep(step.fn, result, context, step.retries || 0, step.retryDelay || 100, step.timeout);
|
|
109
|
+
}
|
|
110
|
+
else if (step.type === 'parallel' && step.fns) {
|
|
111
|
+
result = await this.executeParallelSteps(step.fns, result, context, step.retries || 0, step.retryDelay || 100, step.timeout);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
return result;
|
|
115
|
+
}
|
|
116
|
+
async executeSingleStep(fn, input, context, retries, retryDelay, stepTimeout) {
|
|
117
|
+
let lastError = null;
|
|
118
|
+
for (let attempt = 0; attempt <= retries; attempt++) {
|
|
119
|
+
try {
|
|
120
|
+
this.checkAborted(context.signal);
|
|
121
|
+
context.retryCount = attempt;
|
|
122
|
+
const promise = fn(input, context);
|
|
123
|
+
const effectiveTimeout = stepTimeout ?? this.timeoutMs;
|
|
124
|
+
const result = effectiveTimeout
|
|
125
|
+
? await Promise.race([
|
|
126
|
+
promise,
|
|
127
|
+
this.createTimeout(effectiveTimeout),
|
|
128
|
+
])
|
|
129
|
+
: await promise;
|
|
130
|
+
return result;
|
|
131
|
+
}
|
|
132
|
+
catch (error) {
|
|
133
|
+
lastError = error;
|
|
134
|
+
if (attempt < retries) {
|
|
135
|
+
const delay = retryDelay * (1 << attempt);
|
|
136
|
+
await this.sleep(delay, context.signal);
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
throw lastError || new Error('Step execution failed');
|
|
141
|
+
}
|
|
142
|
+
async executeParallelSteps(fns, input, context, retries, retryDelay, stepTimeout) {
|
|
143
|
+
const promises = fns.map((fn) => this.executeSingleStep(fn, input, context, retries, retryDelay, stepTimeout));
|
|
144
|
+
return Promise.all(promises);
|
|
145
|
+
}
|
|
146
|
+
checkAborted(signal) {
|
|
147
|
+
if (signal?.aborted) {
|
|
148
|
+
throw new Error('Pipeline aborted');
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
createTimeout(ms) {
|
|
152
|
+
return new Promise((_, reject) => setTimeout(() => reject(new Error(`Timeout after ${ms}ms`)), ms));
|
|
153
|
+
}
|
|
154
|
+
sleep(ms, signal) {
|
|
155
|
+
return new Promise((resolve, reject) => {
|
|
156
|
+
const timeoutId = setTimeout(resolve, ms);
|
|
157
|
+
if (signal) {
|
|
158
|
+
const onAbort = () => {
|
|
159
|
+
clearTimeout(timeoutId);
|
|
160
|
+
reject(new Error('Sleep aborted'));
|
|
161
|
+
};
|
|
162
|
+
if (signal.aborted) {
|
|
163
|
+
onAbort();
|
|
164
|
+
return;
|
|
165
|
+
}
|
|
166
|
+
signal.addEventListener('abort', onAbort, { once: true });
|
|
167
|
+
}
|
|
168
|
+
});
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
exports.Quantam = Quantam;
|
|
172
|
+
function quantam() {
|
|
173
|
+
return new Quantam();
|
|
174
|
+
}
|
|
175
|
+
//# sourceMappingURL=core.js.map
|
package/dist/core.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"core.js","sourceRoot":"","sources":["../src/core.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"basic.d.ts","sourceRoot":"","sources":["../../src/examples/basic.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const index_1 = require("../index");
|
|
4
|
+
async function main() {
|
|
5
|
+
async function fetchUser(id) {
|
|
6
|
+
return { id, name: 'Alice' };
|
|
7
|
+
}
|
|
8
|
+
async function fetchOrders(user) {
|
|
9
|
+
return { user, orders: [1, 2, 3] };
|
|
10
|
+
}
|
|
11
|
+
async function enrichData(data) {
|
|
12
|
+
return { ...data, enriched: true };
|
|
13
|
+
}
|
|
14
|
+
const flow = (0, index_1.quantam)()
|
|
15
|
+
.step(fetchUser)
|
|
16
|
+
.step(fetchOrders)
|
|
17
|
+
.step(enrichData);
|
|
18
|
+
const result = await flow.run('user-123');
|
|
19
|
+
console.log(result);
|
|
20
|
+
}
|
|
21
|
+
main().catch((err) => {
|
|
22
|
+
console.error(err);
|
|
23
|
+
process.exitCode = 1;
|
|
24
|
+
});
|
|
25
|
+
//# sourceMappingURL=basic.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"basic.js","sourceRoot":"","sources":["../../src/examples/basic.ts"],"names":[],"mappings":";;AAAA,oCAAmC;AAgBnC,KAAK,UAAU,IAAI;IACjB,KAAK,UAAU,SAAS,CAAC,EAAU;QACjC,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;IAC/B,CAAC;IAED,KAAK,UAAU,WAAW,CAAC,IAAU;QACnC,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC;IACrC,CAAC;IAED,KAAK,UAAU,UAAU,CAAC,IAAoB;QAC5C,OAAO,EAAE,GAAG,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;IACrC,CAAC;IAED,MAAM,IAAI,GAAG,IAAA,eAAO,GAAE;SACnB,IAAI,CAAC,SAAS,CAAC;SACf,IAAI,CAAC,WAAW,CAAC;SACjB,IAAI,CAAC,UAAU,CAAC,CAAC;IAEpB,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,UAAiB,CAAC,CAAC;IACjD,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;AACtB,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;IACnB,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IACnB,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;AACvB,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"batch.d.ts","sourceRoot":"","sources":["../../src/examples/batch.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const index_1 = require("../index");
|
|
4
|
+
async function main() {
|
|
5
|
+
const flow = (0, index_1.quantam)().step(async (n) => n + 1);
|
|
6
|
+
const inputs = Array.from({ length: 1000 }, (_, i) => i);
|
|
7
|
+
const results = await flow.runMany(inputs, { concurrency: 64 });
|
|
8
|
+
console.log({
|
|
9
|
+
length: results.length,
|
|
10
|
+
first: results[0],
|
|
11
|
+
last: results[results.length - 1],
|
|
12
|
+
});
|
|
13
|
+
}
|
|
14
|
+
main().catch((err) => {
|
|
15
|
+
console.error(err);
|
|
16
|
+
process.exitCode = 1;
|
|
17
|
+
});
|
|
18
|
+
//# sourceMappingURL=batch.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"batch.js","sourceRoot":"","sources":["../../src/examples/batch.ts"],"names":[],"mappings":";;AAAA,oCAAmC;AAEnC,KAAK,UAAU,IAAI;IACjB,MAAM,IAAI,GAAG,IAAA,eAAO,GAAU,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IAExD,MAAM,MAAM,GAAa,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC;IACnE,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,WAAW,EAAE,EAAE,EAAE,CAAC,CAAC;IAEhE,OAAO,CAAC,GAAG,CAAC;QACV,MAAM,EAAE,OAAO,CAAC,MAAM;QACtB,KAAK,EAAE,OAAO,CAAC,CAAC,CAAC;QACjB,IAAI,EAAE,OAAO,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC;KAClC,CAAC,CAAC;AACL,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;IACnB,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IACnB,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;AACvB,CAAC,CAAC,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AAC1C,YAAY,EAAE,IAAI,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Quantam - A lightweight async workflow engine
|
|
4
|
+
* Core entry point
|
|
5
|
+
*/
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.quantam = exports.Quantam = void 0;
|
|
8
|
+
var core_1 = require("./core");
|
|
9
|
+
Object.defineProperty(exports, "Quantam", { enumerable: true, get: function () { return core_1.Quantam; } });
|
|
10
|
+
Object.defineProperty(exports, "quantam", { enumerable: true, get: function () { return core_1.quantam; } });
|
|
11
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAEH,+BAA0C;AAAjC,+FAAA,OAAO,OAAA;AAAE,+FAAA,OAAO,OAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"quantam.test.d.ts","sourceRoot":"","sources":["../../src/tests/quantam.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const node_test_1 = __importDefault(require("node:test"));
|
|
7
|
+
const strict_1 = __importDefault(require("node:assert/strict"));
|
|
8
|
+
const index_1 = require("../index");
|
|
9
|
+
(0, node_test_1.default)('runs basic sequential pipeline', async () => {
|
|
10
|
+
const flow = (0, index_1.quantam)()
|
|
11
|
+
.step(async (n) => n + 1)
|
|
12
|
+
.step(async (n) => n * 2);
|
|
13
|
+
const result = await flow.run(1);
|
|
14
|
+
strict_1.default.equal(result, 4);
|
|
15
|
+
});
|
|
16
|
+
(0, node_test_1.default)('retries and exposes retryCount', async () => {
|
|
17
|
+
let attempts = 0;
|
|
18
|
+
const flow = (0, index_1.quantam)()
|
|
19
|
+
.step(async (n, ctx) => {
|
|
20
|
+
attempts++;
|
|
21
|
+
if ((ctx?.retryCount ?? 0) < 2) {
|
|
22
|
+
throw new Error('transient');
|
|
23
|
+
}
|
|
24
|
+
return n + (ctx?.retryCount ?? 0);
|
|
25
|
+
})
|
|
26
|
+
.retry(3, 1);
|
|
27
|
+
const result = await flow.run(1);
|
|
28
|
+
strict_1.default.equal(result, 3);
|
|
29
|
+
strict_1.default.equal(attempts, 3);
|
|
30
|
+
});
|
|
31
|
+
(0, node_test_1.default)('stepTimeout rejects slow step', async () => {
|
|
32
|
+
const flow = (0, index_1.quantam)()
|
|
33
|
+
.step(async (n) => {
|
|
34
|
+
await new Promise((resolve) => setTimeout(resolve, 20));
|
|
35
|
+
return n + 1;
|
|
36
|
+
})
|
|
37
|
+
.stepTimeout(5);
|
|
38
|
+
let threw = false;
|
|
39
|
+
try {
|
|
40
|
+
await flow.run(1);
|
|
41
|
+
}
|
|
42
|
+
catch (err) {
|
|
43
|
+
threw = true;
|
|
44
|
+
strict_1.default.match(err.message, /Timeout/);
|
|
45
|
+
}
|
|
46
|
+
strict_1.default.equal(threw, true);
|
|
47
|
+
});
|
|
48
|
+
(0, node_test_1.default)('runMany respects concurrency limit', async () => {
|
|
49
|
+
const concurrencyLimit = 4;
|
|
50
|
+
let inFlight = 0;
|
|
51
|
+
let maxInFlight = 0;
|
|
52
|
+
const flow = (0, index_1.quantam)().step(async (n) => {
|
|
53
|
+
inFlight++;
|
|
54
|
+
if (inFlight > maxInFlight) {
|
|
55
|
+
maxInFlight = inFlight;
|
|
56
|
+
}
|
|
57
|
+
await new Promise((resolve) => setTimeout(resolve, 5));
|
|
58
|
+
inFlight--;
|
|
59
|
+
return n + 1;
|
|
60
|
+
});
|
|
61
|
+
const inputs = Array.from({ length: 16 }, (_, i) => i);
|
|
62
|
+
const results = await flow.runMany(inputs, { concurrency: concurrencyLimit });
|
|
63
|
+
strict_1.default.deepEqual(results, inputs.map((n) => n + 1));
|
|
64
|
+
strict_1.default.ok(maxInFlight <= concurrencyLimit);
|
|
65
|
+
});
|
|
66
|
+
//# sourceMappingURL=quantam.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"quantam.test.js","sourceRoot":"","sources":["../../src/tests/quantam.test.ts"],"names":[],"mappings":"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"}
|