@mrjacket/ahko 0.2.0 → 0.4.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/CHANGELOG.md +26 -0
- package/README.md +94 -8
- package/dist/errors/timeout.error.d.ts +15 -2
- package/dist/index.cjs +346 -26
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +4 -2
- package/dist/index.js +341 -25
- package/dist/index.js.map +1 -1
- package/dist/models/index.d.ts +1 -0
- package/dist/models/options.model.d.ts +12 -0
- package/dist/models/retry.model.d.ts +52 -0
- package/dist/retry/backoff.d.ts +18 -0
- package/dist/retry/index.d.ts +1 -0
- package/dist/scheduler/signal.d.ts +20 -0
- package/dist/scheduler/task-queue.d.ts +9 -1
- package/dist/scheduler/task-runner.d.ts +25 -5
- package/dist/version.d.ts +1 -1
- package/package.json +21 -2
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,32 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [0.4.0] - 2026-09-22 — Timeout & Robust Cancellation
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
- Execution timeout control via `timeoutMs` in `IScheduleOptions`.
|
|
12
|
+
- Rejection with `AhkoTimeoutError` containing exceeded `timeoutMs` threshold and descriptive message.
|
|
13
|
+
- Immediate rejection and slot recovery for hanging, uncooperative tasks via `Promise.race`.
|
|
14
|
+
- Active execution timeout isolation (queued waiting time and backoff delays do not consume execution timeout).
|
|
15
|
+
- Fresh `timeoutMs` window allocation on retry attempts.
|
|
16
|
+
- Unified signal coordination via `combineSignals` utility with deterministic listener detachment.
|
|
17
|
+
- Strict configuration validation for `timeoutMs` (positive finite numbers).
|
|
18
|
+
- Comprehensive unit test suite covering execution timeouts, cancellation precedence, uncooperative tasks, retries, and signal combination.
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
## [0.3.0] - 2026-09-22 — Retry & Backoff
|
|
23
|
+
|
|
24
|
+
### Added
|
|
25
|
+
- Automatic retry engine supporting `attempts`, exponential/linear backoff, and full jitter.
|
|
26
|
+
- Retry filtering via `shouldRetry` predicate `(error, attempt) => boolean | Promise<boolean>`.
|
|
27
|
+
- Concurrency slot release during backoff delay to prevent capacity starvation.
|
|
28
|
+
- Cancellation safety during backoff delay (clears timers immediately, rejects with `AhkoCancellationError`, and halts remaining retries).
|
|
29
|
+
- Public retry models (`IRetryOptions`, `TRetryBackoff`, `TRetryPredicate`) and backoff calculation utilities.
|
|
30
|
+
- Comprehensive unit test suite covering backoff calculations, jitter, slot release, predicates, and cancellations.
|
|
31
|
+
|
|
32
|
+
---
|
|
33
|
+
|
|
8
34
|
## [0.2.0] - 2026-09-22 — Idle Scheduling
|
|
9
35
|
|
|
10
36
|
### Added
|
package/README.md
CHANGED
|
@@ -97,7 +97,51 @@ await ahko.schedule(
|
|
|
97
97
|
);
|
|
98
98
|
```
|
|
99
99
|
|
|
100
|
-
### 3.
|
|
100
|
+
### 3. Opportunistic Idle Execution
|
|
101
|
+
|
|
102
|
+
Schedule work to run when the runtime is idle (using browser `requestIdleCallback`, Node.js `setImmediate`, or universal fallback):
|
|
103
|
+
|
|
104
|
+
```typescript
|
|
105
|
+
// Dedicated convenience method
|
|
106
|
+
await ahko.idle(async ({ signal }) => {
|
|
107
|
+
await computeBackgroundAnalytics({ signal });
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
// Or via schedule options with maximum wait timeout
|
|
111
|
+
await ahko.schedule(
|
|
112
|
+
async ({ signal }) => {
|
|
113
|
+
await performLowPriorityWork({ signal });
|
|
114
|
+
},
|
|
115
|
+
{
|
|
116
|
+
strategy: "idle",
|
|
117
|
+
idleTimeout: 5000, // Forces execution if idle window doesn't appear in 5s
|
|
118
|
+
}
|
|
119
|
+
);
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
### 4. Resilient Retries & Backoff
|
|
123
|
+
|
|
124
|
+
Automatically retry failed tasks with configurable exponential or linear backoff and full jitter:
|
|
125
|
+
|
|
126
|
+
```typescript
|
|
127
|
+
const result = await ahko.schedule(
|
|
128
|
+
async ({ signal }) => {
|
|
129
|
+
return callExternalService({ signal });
|
|
130
|
+
},
|
|
131
|
+
{
|
|
132
|
+
retry: {
|
|
133
|
+
attempts: 3, // 1 initial run + up to 2 retries
|
|
134
|
+
backoff: "exponential", // "exponential" | "linear" | "none"
|
|
135
|
+
baseDelay: 250, // starting delay in ms
|
|
136
|
+
maxDelay: 5000, // maximum delay cap in ms
|
|
137
|
+
jitter: true, // randomize backoff to prevent thundering herds
|
|
138
|
+
shouldRetry: (error) => isNetworkError(error),
|
|
139
|
+
},
|
|
140
|
+
}
|
|
141
|
+
);
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
### 5. First-Class Cancellation (`AbortSignal`)
|
|
101
145
|
|
|
102
146
|
AHKO provides native, cooperative cancellation:
|
|
103
147
|
|
|
@@ -116,7 +160,26 @@ const taskPromise = ahko.schedule(
|
|
|
116
160
|
controller.abort();
|
|
117
161
|
```
|
|
118
162
|
|
|
119
|
-
###
|
|
163
|
+
### 6. Execution Deadlines & Timeouts (`timeoutMs`)
|
|
164
|
+
|
|
165
|
+
Enforce deadlines per attempt. If a task exceeds `timeoutMs`, its context signal is aborted and the task rejects with `AhkoTimeoutError`:
|
|
166
|
+
|
|
167
|
+
```typescript
|
|
168
|
+
try {
|
|
169
|
+
await ahko.schedule(
|
|
170
|
+
async ({ signal }) => {
|
|
171
|
+
return callLongRunningApi({ signal });
|
|
172
|
+
},
|
|
173
|
+
{ timeoutMs: 3000 } // aborts and rejects if running longer than 3 seconds
|
|
174
|
+
);
|
|
175
|
+
} catch (error) {
|
|
176
|
+
if (error instanceof AhkoTimeoutError) {
|
|
177
|
+
console.error(`Timed out after ${error.timeoutMs}ms`);
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
### 7. Telemetry (`stats`)
|
|
120
183
|
|
|
121
184
|
Inspect real-time scheduler state without synthetic metrics:
|
|
122
185
|
|
|
@@ -130,13 +193,26 @@ console.log(stats);
|
|
|
130
193
|
// completedTasks: 42,
|
|
131
194
|
// failedTasks: 1,
|
|
132
195
|
// cancelledTasks: 2,
|
|
133
|
-
// timedOutTasks:
|
|
196
|
+
// timedOutTasks: 1,
|
|
134
197
|
// capacity: 3
|
|
135
198
|
// }
|
|
136
199
|
```
|
|
137
200
|
|
|
138
201
|
---
|
|
139
202
|
|
|
203
|
+
## Documentation
|
|
204
|
+
|
|
205
|
+
Comprehensive guides and technical documentation are available in the [`docs/`](./docs) directory:
|
|
206
|
+
|
|
207
|
+
| Document | Description |
|
|
208
|
+
|---|---|
|
|
209
|
+
| [**Getting Started**](./docs/getting-started.md) | Quickstart guide, installation, and fundamental usage patterns. |
|
|
210
|
+
| [**Library API**](./docs/library.md) | Complete programmatic API reference, TypeScript interfaces, and options. |
|
|
211
|
+
| [**Architecture**](./docs/architecture.md) | Architectural specifications, lifecycle state machine, and design decisions. |
|
|
212
|
+
| [**Roadmap**](./docs/roadmap.md) | Milestone progression from 0.1.0 through 1.0.0. |
|
|
213
|
+
|
|
214
|
+
---
|
|
215
|
+
|
|
140
216
|
## API Reference
|
|
141
217
|
|
|
142
218
|
### `new Ahko(options?: IAhkoOptions)`
|
|
@@ -151,19 +227,29 @@ Creates an AHKO scheduler instance.
|
|
|
151
227
|
|
|
152
228
|
Schedules an asynchronous task with full return type inference.
|
|
153
229
|
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
230
|
+
| Option | Type | Default | Description |
|
|
231
|
+
|---|---|---|---|
|
|
232
|
+
| `strategy` | `"immediate" \| "delay" \| "idle"` | `"immediate"` | Scheduling execution strategy. |
|
|
233
|
+
| `delay` | `number` | `0` | Delay in milliseconds when strategy is `"delay"`. |
|
|
234
|
+
| `idleTimeout` | `number` | `undefined` | Maximum time to wait for idle window before forcing queue entry. |
|
|
235
|
+
| `retry` | `IRetryOptions` | `undefined` | Automatic retry policy (attempts, backoff, jitter, predicate). |
|
|
236
|
+
| `timeoutMs` | `number` | `undefined` | Maximum execution duration in milliseconds per attempt before aborting with `AhkoTimeoutError`. |
|
|
237
|
+
| `signal` | `AbortSignal` | `undefined` | Optional external `AbortSignal` for cooperative cancellation. |
|
|
238
|
+
|
|
239
|
+
### `ahko.idle<T>(task: ITask<T>, options?: Omit<IScheduleOptions, "strategy">): Promise<T>`
|
|
240
|
+
|
|
241
|
+
Convenience method scheduling a task under `strategy: "idle"`.
|
|
158
242
|
|
|
159
243
|
### `ahko.stats(): IAhkoStats`
|
|
160
244
|
|
|
161
|
-
Returns a snapshot of current task counters and capacity.
|
|
245
|
+
Returns a snapshot of current task counters and queue capacity.
|
|
162
246
|
|
|
163
247
|
---
|
|
164
248
|
|
|
165
249
|
## Errors
|
|
166
250
|
|
|
251
|
+
All scheduler errors inherit from `AhkoError`:
|
|
252
|
+
|
|
167
253
|
- `AhkoError`: Base class for all scheduler errors.
|
|
168
254
|
- `AhkoCancellationError`: Thrown when a task is aborted.
|
|
169
255
|
- `AhkoConfigurationError`: Thrown when invalid options are provided.
|
|
@@ -1,13 +1,26 @@
|
|
|
1
1
|
import { AhkoError } from "./ahko.error.js";
|
|
2
|
+
/**
|
|
3
|
+
* Options for constructing an AhkoTimeoutError.
|
|
4
|
+
*/
|
|
5
|
+
export interface IAhkoTimeoutErrorOptions extends ErrorOptions {
|
|
6
|
+
/**
|
|
7
|
+
* The timeout threshold in milliseconds that was exceeded.
|
|
8
|
+
*/
|
|
9
|
+
timeoutMs?: number;
|
|
10
|
+
}
|
|
2
11
|
/**
|
|
3
12
|
* Thrown when a task exceeds its allotted timeout duration.
|
|
4
13
|
*/
|
|
5
14
|
export declare class AhkoTimeoutError extends AhkoError {
|
|
15
|
+
/**
|
|
16
|
+
* The timeout threshold in milliseconds that was exceeded, if configured.
|
|
17
|
+
*/
|
|
18
|
+
readonly timeoutMs?: number;
|
|
6
19
|
/**
|
|
7
20
|
* Creates a new AhkoTimeoutError.
|
|
8
21
|
*
|
|
9
22
|
* @param message - Explanation of timeout expiry.
|
|
10
|
-
* @param options - Standard Error options including cause.
|
|
23
|
+
* @param options - Standard Error options including optional timeoutMs and cause.
|
|
11
24
|
*/
|
|
12
|
-
constructor(message?: string, options?:
|
|
25
|
+
constructor(message?: string, options?: IAhkoTimeoutErrorOptions);
|
|
13
26
|
}
|