@mrjacket/ahko 0.1.0 → 0.3.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 +24 -0
- package/README.md +116 -28
- package/dist/ahko.d.ts +25 -1
- package/dist/index.cjs +273 -16
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.js +269 -15
- package/dist/index.js.map +1 -1
- package/dist/models/index.d.ts +1 -0
- package/dist/models/options.model.d.ts +11 -0
- package/dist/models/retry.model.d.ts +52 -0
- package/dist/models/strategy.model.d.ts +4 -2
- package/dist/retry/backoff.d.ts +18 -0
- package/dist/retry/index.d.ts +1 -0
- package/dist/scheduler/idle-scheduler.d.ts +28 -0
- package/dist/scheduler/task-queue.d.ts +16 -1
- package/dist/scheduler/task-runner.d.ts +11 -0
- package/dist/version.d.ts +1 -1
- package/package.json +24 -5
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,30 @@ 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.3.0] - 2026-09-22 — Retry & Backoff
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
- Automatic retry engine supporting `attempts`, exponential/linear backoff, and full jitter.
|
|
12
|
+
- Retry filtering via `shouldRetry` predicate `(error, attempt) => boolean | Promise<boolean>`.
|
|
13
|
+
- Concurrency slot release during backoff delay to prevent capacity starvation.
|
|
14
|
+
- Cancellation safety during backoff delay (clears timers immediately, rejects with `AhkoCancellationError`, and halts remaining retries).
|
|
15
|
+
- Public retry models (`IRetryOptions`, `TRetryBackoff`, `TRetryPredicate`) and backoff calculation utilities.
|
|
16
|
+
- Comprehensive unit test suite covering backoff calculations, jitter, slot release, predicates, and cancellations.
|
|
17
|
+
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
## [0.2.0] - 2026-09-22 — Idle Scheduling
|
|
21
|
+
|
|
22
|
+
### Added
|
|
23
|
+
- Platform-agnostic `IdleScheduler` supporting browser `requestIdleCallback`, Node.js `setImmediate`, and universal fallback `setTimeout(..., 0)`.
|
|
24
|
+
- Support for `idle` strategy (`EScheduleStrategy.IDLE`).
|
|
25
|
+
- Optional `idleTimeout` parameter in `IScheduleOptions` forwarding to `requestIdleCallback({ timeout })`.
|
|
26
|
+
- Convenience method `ahko.idle(task, options)`.
|
|
27
|
+
- Immediate resource cleanup and handle cancellation when idle tasks are cancelled prior to callback execution.
|
|
28
|
+
- Comprehensive unit test suite covering cross-runtime execution, fallback paths, cancellation, and concurrency.
|
|
29
|
+
|
|
30
|
+
---
|
|
31
|
+
|
|
8
32
|
## [0.1.0] - 2026-09-22 — Core Scheduler
|
|
9
33
|
|
|
10
34
|
### Added
|
package/README.md
CHANGED
|
@@ -1,21 +1,41 @@
|
|
|
1
|
-
<
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
1
|
+
<p align="center">
|
|
2
|
+
<img src=".github/images/ahko.png" width="120" height="120" alt="ahko">
|
|
3
|
+
</p>
|
|
4
|
+
|
|
5
|
+
<h1 align="center">ahko</h1>
|
|
6
|
+
|
|
7
|
+
<p align="center">
|
|
8
|
+
<strong>Let your code chill.</strong>
|
|
9
|
+
</p>
|
|
10
|
+
|
|
11
|
+
<p align="center">
|
|
12
|
+
<a href="https://www.npmjs.com/package/@mrjacket/ahko">
|
|
13
|
+
<img src="https://img.shields.io/npm/v/@mrjacket/ahko.svg?color=success" alt="npm version">
|
|
14
|
+
</a>
|
|
15
|
+
<a href="https://www.npmjs.com/package/@mrjacket/ahko">
|
|
16
|
+
<img src="https://img.shields.io/npm/dm/@mrjacket/ahko.svg" alt="npm downloads">
|
|
17
|
+
</a>
|
|
18
|
+
<a href="https://www.npmjs.com/package/@mrjacket/ahko">
|
|
19
|
+
<img src="https://img.shields.io/node/v/@mrjacket/ahko.svg" alt="node">
|
|
20
|
+
</a>
|
|
21
|
+
<a href="https://github.com/x-name15/ahko/actions/workflows/ci.yml">
|
|
22
|
+
<img src="https://github.com/x-name15/ahko/actions/workflows/ci.yml/badge.svg" alt="ci">
|
|
23
|
+
</a>
|
|
24
|
+
<a href="https://www.npmjs.com/package/@mrjacket/ahko">
|
|
25
|
+
<img src="https://img.shields.io/npm/types/@mrjacket/ahko.svg" alt="types">
|
|
26
|
+
</a>
|
|
27
|
+
<a href="https://github.com/x-name15/ahko/blob/main/LICENSE">
|
|
28
|
+
<img src="https://img.shields.io/npm/l/@mrjacket/ahko.svg" alt="license">
|
|
29
|
+
</a>
|
|
30
|
+
</p>
|
|
31
|
+
|
|
32
|
+
`ahko` is a low-energy task scheduler for JavaScript and TypeScript.
|
|
33
|
+
|
|
34
|
+
Inspired by Aashii Kedarui / Ahko from *"The 100 Girlfriends Who Really, Really, Really, Really, Really Love You"*, @mrjacket/ahko brings calm, controlled execution to asynchronous workflows without rush, bursts, or unnecessary complexity.
|
|
15
35
|
|
|
16
36
|
---
|
|
17
37
|
|
|
18
|
-
##
|
|
38
|
+
## Installation
|
|
19
39
|
|
|
20
40
|
```bash
|
|
21
41
|
npm install @mrjacket/ahko
|
|
@@ -25,7 +45,7 @@ Requires **Node.js >= 22.12.0** or a modern browser environment. Zero external d
|
|
|
25
45
|
|
|
26
46
|
---
|
|
27
47
|
|
|
28
|
-
##
|
|
48
|
+
## Quick Start
|
|
29
49
|
|
|
30
50
|
```typescript
|
|
31
51
|
import { Ahko } from "@mrjacket/ahko";
|
|
@@ -41,7 +61,7 @@ const data = await ahko.schedule(async ({ signal, taskId }) => {
|
|
|
41
61
|
|
|
42
62
|
---
|
|
43
63
|
|
|
44
|
-
##
|
|
64
|
+
## Core Capabilities
|
|
45
65
|
|
|
46
66
|
### 1. Concurrency Control
|
|
47
67
|
|
|
@@ -77,7 +97,51 @@ await ahko.schedule(
|
|
|
77
97
|
);
|
|
78
98
|
```
|
|
79
99
|
|
|
80
|
-
### 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`)
|
|
81
145
|
|
|
82
146
|
AHKO provides native, cooperative cancellation:
|
|
83
147
|
|
|
@@ -96,7 +160,7 @@ const taskPromise = ahko.schedule(
|
|
|
96
160
|
controller.abort();
|
|
97
161
|
```
|
|
98
162
|
|
|
99
|
-
###
|
|
163
|
+
### 6. Telemetry (`stats`)
|
|
100
164
|
|
|
101
165
|
Inspect real-time scheduler state without synthetic metrics:
|
|
102
166
|
|
|
@@ -117,7 +181,20 @@ console.log(stats);
|
|
|
117
181
|
|
|
118
182
|
---
|
|
119
183
|
|
|
120
|
-
##
|
|
184
|
+
## Documentation
|
|
185
|
+
|
|
186
|
+
Comprehensive guides and technical documentation are available in the [`docs/`](./docs) directory:
|
|
187
|
+
|
|
188
|
+
| Document | Description |
|
|
189
|
+
|---|---|
|
|
190
|
+
| [**Getting Started**](./docs/getting-started.md) | Quickstart guide, installation, and fundamental usage patterns. |
|
|
191
|
+
| [**Library API**](./docs/library.md) | Complete programmatic API reference, TypeScript interfaces, and options. |
|
|
192
|
+
| [**Architecture**](./docs/architecture.md) | Architectural specifications, lifecycle state machine, and design decisions. |
|
|
193
|
+
| [**Roadmap**](./docs/roadmap.md) | Milestone progression from 0.1.0 through 1.0.0. |
|
|
194
|
+
|
|
195
|
+
---
|
|
196
|
+
|
|
197
|
+
## API Reference
|
|
121
198
|
|
|
122
199
|
### `new Ahko(options?: IAhkoOptions)`
|
|
123
200
|
|
|
@@ -131,18 +208,27 @@ Creates an AHKO scheduler instance.
|
|
|
131
208
|
|
|
132
209
|
Schedules an asynchronous task with full return type inference.
|
|
133
210
|
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
211
|
+
| Option | Type | Default | Description |
|
|
212
|
+
|---|---|---|---|
|
|
213
|
+
| `strategy` | `"immediate" \| "delay" \| "idle"` | `"immediate"` | Scheduling execution strategy. |
|
|
214
|
+
| `delay` | `number` | `0` | Delay in milliseconds when strategy is `"delay"`. |
|
|
215
|
+
| `idleTimeout` | `number` | `undefined` | Maximum time to wait for idle window before forcing queue entry. |
|
|
216
|
+
| `retry` | `IRetryOptions` | `undefined` | Automatic retry policy (attempts, backoff, jitter, predicate). |
|
|
217
|
+
| `signal` | `AbortSignal` | `undefined` | Optional external `AbortSignal` for cooperative cancellation. |
|
|
218
|
+
|
|
219
|
+
### `ahko.idle<T>(task: ITask<T>, options?: Omit<IScheduleOptions, "strategy">): Promise<T>`
|
|
220
|
+
|
|
221
|
+
Convenience method scheduling a task under `strategy: "idle"`.
|
|
138
222
|
|
|
139
223
|
### `ahko.stats(): IAhkoStats`
|
|
140
224
|
|
|
141
|
-
Returns a snapshot of current task counters and capacity.
|
|
225
|
+
Returns a snapshot of current task counters and queue capacity.
|
|
142
226
|
|
|
143
227
|
---
|
|
144
228
|
|
|
145
|
-
##
|
|
229
|
+
## Errors
|
|
230
|
+
|
|
231
|
+
All scheduler errors inherit from `AhkoError`:
|
|
146
232
|
|
|
147
233
|
- `AhkoError`: Base class for all scheduler errors.
|
|
148
234
|
- `AhkoCancellationError`: Thrown when a task is aborted.
|
|
@@ -152,6 +238,8 @@ Returns a snapshot of current task counters and capacity.
|
|
|
152
238
|
|
|
153
239
|
---
|
|
154
240
|
|
|
155
|
-
##
|
|
241
|
+
## License
|
|
242
|
+
[GNU General Public License v3.0 (GPL-3.0-only)](LICENSE)
|
|
156
243
|
|
|
157
|
-
|
|
244
|
+
### Credits
|
|
245
|
+
**Author:** Mr Jacket / Felix Manrique / x-name15 (we are all the same person)
|
package/dist/ahko.d.ts
CHANGED
|
@@ -2,7 +2,7 @@ import type { IAhkoOptions, IScheduleOptions } from "./models/options.model.js";
|
|
|
2
2
|
import type { IAhkoStats } from "./models/stats.model.js";
|
|
3
3
|
import type { ITask } from "./models/task.model.js";
|
|
4
4
|
/**
|
|
5
|
-
* Ahko — Low-energy
|
|
5
|
+
* Ahko — Low-energy asynchronous task scheduler.
|
|
6
6
|
*
|
|
7
7
|
* Coordinates execution timing, enforces concurrency limits, and cooperates
|
|
8
8
|
* natively with AbortSignal cancellation.
|
|
@@ -58,6 +58,30 @@ export declare class Ahko {
|
|
|
58
58
|
* ```
|
|
59
59
|
*/
|
|
60
60
|
schedule<T>(task: ITask<T>, options?: IScheduleOptions): Promise<T>;
|
|
61
|
+
/**
|
|
62
|
+
* Convenience method to schedule a task during platform idle opportunities.
|
|
63
|
+
*
|
|
64
|
+
* Equivalent to calling `schedule(task, { ...options, strategy: "idle" })`.
|
|
65
|
+
* In browsers, uses `requestIdleCallback` when available.
|
|
66
|
+
* In Node.js, uses `setImmediate`.
|
|
67
|
+
* Falls back to `setTimeout(..., 0)` if neither is available.
|
|
68
|
+
*
|
|
69
|
+
* @template T - Inferred return type of the task.
|
|
70
|
+
* @param task - Task function to run when idle.
|
|
71
|
+
* @param options - Scheduling options (excluding strategy).
|
|
72
|
+
* @returns A promise resolving to the task's return value.
|
|
73
|
+
*
|
|
74
|
+
* @throws {AhkoConfigurationError} If the task is not a function or options are invalid.
|
|
75
|
+
* @throws {AhkoCancellationError} If the task is cancelled prior to or during execution.
|
|
76
|
+
*
|
|
77
|
+
* @example
|
|
78
|
+
* ```typescript
|
|
79
|
+
* const result = await ahko.idle(async ({ signal }) => {
|
|
80
|
+
* return computeAnalytics();
|
|
81
|
+
* });
|
|
82
|
+
* ```
|
|
83
|
+
*/
|
|
84
|
+
idle<T>(task: ITask<T>, options?: Omit<IScheduleOptions, "strategy">): Promise<T>;
|
|
61
85
|
/**
|
|
62
86
|
* Retrieves real-time telemetry metrics from the scheduler.
|
|
63
87
|
*
|