@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 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. First-Class Cancellation (`AbortSignal`)
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
- ### 4. Telemetry (`stats`)
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: 0,
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
- - `task`: `(context: ITaskContext) => Promise<T> | T`
155
- - `options.strategy`: `"immediate"` (default) or `"delay"`.
156
- - `options.delay`: Delay in milliseconds when strategy is `"delay"`.
157
- - `options.signal`: Optional `AbortSignal` for cancellation.
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?: ErrorOptions);
25
+ constructor(message?: string, options?: IAhkoTimeoutErrorOptions);
13
26
  }