@mrjacket/ahko 0.4.0 → 0.6.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.
@@ -1,6 +1,9 @@
1
1
  import type { IScheduleOptions } from "../models/options.model.js";
2
2
  import type { IAhkoStats } from "../models/stats.model.js";
3
+ import { DebounceCoordinator } from "./debounce-coordinator.js";
3
4
  import { TaskRunner } from "./task-runner.js";
5
+ import { ThrottleCoordinator } from "./throttle-coordinator.js";
6
+ import { AhkoEventEmitter } from "../events/event-emitter.js";
4
7
  /**
5
8
  * Memory-safe FIFO task queue managing concurrency allocation,
6
9
  * delayed scheduling, and task lifecycle counters.
@@ -8,6 +11,12 @@ import { TaskRunner } from "./task-runner.js";
8
11
  export declare class TaskQueue {
9
12
  /** Maximum concurrent active tasks */
10
13
  readonly concurrency: number;
14
+ /** Minimum interval in milliseconds between consecutive task starts */
15
+ readonly minIntervalMs: number;
16
+ /** Timestamp of the most recent task start */
17
+ private lastTaskStartTime;
18
+ /** Active rate limit timer for pacing consecutive tasks */
19
+ private rateLimitTimer?;
11
20
  /** Queue of pending task runners waiting for a concurrency slot */
12
21
  private readonly queue;
13
22
  /** Set of task runners currently executing */
@@ -18,6 +27,14 @@ export declare class TaskQueue {
18
27
  private readonly idleEntries;
19
28
  /** Set of tasks currently awaiting a retry backoff timer */
20
29
  private readonly retryEntries;
30
+ /** Coordinator for debounced tasks with key coalescing */
31
+ readonly debounceCoordinator: DebounceCoordinator;
32
+ /** Coordinator for throttled tasks with leading/trailing coalescing */
33
+ readonly throttleCoordinator: ThrottleCoordinator;
34
+ /** Lifecycle event emitter for task and scheduler events */
35
+ readonly emitter: AhkoEventEmitter;
36
+ /** Set of pending resolvers awaiting scheduler idle transition */
37
+ private readonly idleResolvers;
21
38
  /** WeakMap associating task runners with their scheduling options */
22
39
  private readonly runnerOptions;
23
40
  /** Cumulative completed tasks counter */
@@ -28,13 +45,18 @@ export declare class TaskQueue {
28
45
  private cancelledTasks;
29
46
  /** Cumulative timed out tasks counter */
30
47
  private timedOutTasks;
48
+ /** Cumulative count of retry attempts triggered */
49
+ private retriedTasks;
50
+ /** Cumulative count of tasks dispatched to concurrency slots */
51
+ private totalDispatched;
31
52
  /**
32
53
  * Creates a new TaskQueue.
33
54
  *
34
55
  * @param concurrency - Maximum concurrent tasks (defaults to Infinity).
35
- * @throws {AhkoConfigurationError} If concurrency is less than 1 or not a valid number.
56
+ * @param minIntervalMs - Minimum interval in milliseconds between task dispatches.
57
+ * @throws {AhkoConfigurationError} If concurrency is less than 1 or minIntervalMs is invalid.
36
58
  */
37
- constructor(concurrency?: number);
59
+ constructor(concurrency?: number, minIntervalMs?: number);
38
60
  /**
39
61
  * Enqueues a task runner according to the specified schedule options.
40
62
  *
@@ -57,7 +79,7 @@ export declare class TaskQueue {
57
79
  private scheduleIdle;
58
80
  /**
59
81
  * Pumps the queue by picking pending tasks and executing them
60
- * as long as concurrency capacity is available.
82
+ * as long as concurrency capacity is available and minIntervalMs is respected.
61
83
  */
62
84
  private pump;
63
85
  /**
@@ -69,6 +91,27 @@ export declare class TaskQueue {
69
91
  * without holding a concurrency slot.
70
92
  */
71
93
  private scheduleRetry;
94
+ /**
95
+ * Checks whether the scheduler has transitioned to idle and notifies listeners/resolvers.
96
+ */
97
+ checkIdle(): void;
98
+ /**
99
+ * Checks whether the scheduler is currently idle (no active runners and no pending tasks).
100
+ *
101
+ * @returns True if completely idle, false otherwise.
102
+ */
103
+ isIdle(): boolean;
104
+ /**
105
+ * Returns a promise that resolves once the scheduler has processed all tasks and is idle.
106
+ *
107
+ * @returns Promise resolving when idle.
108
+ */
109
+ onIdle(): Promise<void>;
110
+ /**
111
+ * Clears all pending and waiting tasks from the scheduler, cancelling their runners.
112
+ * Active tasks currently in flight will continue to run to completion or abort via signal.
113
+ */
114
+ clear(): void;
72
115
  /**
73
116
  * Returns telemetry snapshot for the scheduler.
74
117
  *
@@ -34,6 +34,8 @@ export declare class TaskRunner<T> {
34
34
  onCancel?: (runner: TaskRunner<T>) => void;
35
35
  /** Current execution attempt count (1-indexed) */
36
36
  attempt: number;
37
+ /** Duration of the most recent execution attempt in milliseconds */
38
+ lastDurationMs: number;
37
39
  /**
38
40
  * Creates a new TaskRunner instance.
39
41
  *
@@ -0,0 +1,43 @@
1
+ import type { IScheduleOptions } from "../models/options.model.js";
2
+ import type { ITask } from "../models/task.model.js";
3
+ /**
4
+ * Coordinates throttle execution with leading execution, trailing execution,
5
+ * and Promise coalescing by explicit key.
6
+ *
7
+ * Incoming calls with the same key within the throttle period coalesce into a
8
+ * single shared trailing execution, preventing overload while ensuring callers
9
+ * receive the final result.
10
+ */
11
+ export declare class ThrottleCoordinator {
12
+ private readonly entries;
13
+ /**
14
+ * Schedules a task under the throttle strategy.
15
+ *
16
+ * @param key - Explicit identity key.
17
+ * @param task - Work to execute.
18
+ * @param waitMs - Throttle interval duration in milliseconds.
19
+ * @param options - Scheduling options.
20
+ * @param dispatchFn - Callback invoked to dispatch task execution into the queue.
21
+ * @returns Promise resolving with the leading execution or coalesced trailing result.
22
+ */
23
+ schedule<T>(key: string | symbol, task: ITask<T>, waitMs: number, options: IScheduleOptions | undefined, dispatchFn: (task: ITask<T>, options?: IScheduleOptions) => Promise<T>): Promise<T>;
24
+ /**
25
+ * Invoked when the throttle interval window timer expires.
26
+ */
27
+ private onWindowExpire;
28
+ /**
29
+ * Cancels any pending trailing throttled task for a given key.
30
+ *
31
+ * @param key - Identity key to cancel.
32
+ * @param reason - Optional cancellation reason.
33
+ */
34
+ cancel(key: string | symbol, reason?: unknown): void;
35
+ /**
36
+ * Number of keys currently actively throttled.
37
+ */
38
+ get size(): number;
39
+ /**
40
+ * Clears all throttled entries and timers.
41
+ */
42
+ clear(): void;
43
+ }
package/dist/version.d.ts CHANGED
@@ -1,4 +1,4 @@
1
1
  /**
2
2
  * Current version of @mrjacket/ahko package.
3
3
  */
4
- export declare const VERSION = "0.4.0";
4
+ export declare const VERSION = "0.6.0";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mrjacket/ahko",
3
- "version": "0.4.0",
3
+ "version": "0.6.0",
4
4
  "description": "A low-energy task scheduler for JavaScript and TypeScript. Let your code chill.",
5
5
  "type": "module",
6
6
  "main": "dist/index.cjs",
@@ -70,6 +70,11 @@
70
70
  "cooperative-scheduling",
71
71
  "low-energy",
72
72
  "typescript",
73
+ "events",
74
+ "telemetry",
75
+ "observability",
76
+ "metrics",
77
+ "dx",
73
78
  "100 kanojo"
74
79
  ],
75
80
  "devDependencies": {