@mrjacket/ahko 1.0.0 → 1.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.
@@ -0,0 +1,39 @@
1
+ /**
2
+ * Discrete lifecycle states of the circuit breaker.
3
+ */
4
+ export declare enum ECircuitState {
5
+ /** Normal operation: calls pass through to execution */
6
+ CLOSED = "closed",
7
+ /** Failure threshold exceeded: calls fast-fail immediately */
8
+ OPEN = "open",
9
+ /** Cool-down timer elapsed: trial call allowed to test recovery */
10
+ HALF_OPEN = "half_open"
11
+ }
12
+ /** Union type representing circuit breaker states */
13
+ export type TCircuitState = `${ECircuitState}`;
14
+ /**
15
+ * Configuration options for the circuit breaker policy.
16
+ */
17
+ export interface ICircuitBreakerOptions {
18
+ /**
19
+ * Number of consecutive task failures required to trip the circuit to OPEN state.
20
+ * Must be an integer greater than or equal to 1.
21
+ */
22
+ failureThreshold: number;
23
+ /**
24
+ * Time in milliseconds the circuit remains OPEN before transitioning to HALF_OPEN
25
+ * to attempt a recovery trial call. Must be a positive finite number.
26
+ */
27
+ resetTimeoutMs: number;
28
+ }
29
+ /**
30
+ * Telemetry snapshot of circuit breaker status.
31
+ */
32
+ export interface ICircuitBreakerStats {
33
+ /** Current state of the breaker */
34
+ state: ECircuitState;
35
+ /** Number of consecutive errors recorded */
36
+ consecutiveFailures: number;
37
+ /** Timestamp in ms when the breaker tripped to OPEN, if open */
38
+ lastFailureTime?: number;
39
+ }
@@ -0,0 +1,23 @@
1
+ import type { ICircuitBreakerOptions } from "./circuit-breaker.model.js";
2
+ import type { IAhkoOptions, IScheduleOptions } from "./options.model.js";
3
+ import type { TTaskPriority } from "./priority.model.js";
4
+ /**
5
+ * Pre-configured profile containing scheduler defaults and task scheduling policies.
6
+ */
7
+ export interface IAhkoProfileConfig extends IAhkoOptions, Partial<IScheduleOptions> {
8
+ /** Optional default task priority for tasks scheduled under this profile */
9
+ priority?: TTaskPriority;
10
+ /** Optional circuit breaker policy for the scheduler */
11
+ circuitBreaker?: ICircuitBreakerOptions;
12
+ }
13
+ /**
14
+ * Structure of `config.ahko.json` declarative configuration file.
15
+ */
16
+ export interface IAhkoFileConfig {
17
+ /** Optional JSON schema URL */
18
+ $schema?: string;
19
+ /** Default profile applied when no named profile is requested */
20
+ default?: IAhkoProfileConfig;
21
+ /** Named profiles for distinct workloads (e.g. "api", "background", "critical") */
22
+ profiles?: Record<string, IAhkoProfileConfig>;
23
+ }
@@ -6,3 +6,6 @@ export * from "./stats.model.js";
6
6
  export * from "./strategy.model.js";
7
7
  export * from "./task.model.js";
8
8
  export * from "./events.model.js";
9
+ export * from "./circuit-breaker.model.js";
10
+ export * from "./priority.model.js";
11
+ export * from "./config.model.js";
@@ -1,3 +1,5 @@
1
+ import type { ICircuitBreakerOptions } from "./circuit-breaker.model.js";
2
+ import type { TTaskPriority } from "./priority.model.js";
1
3
  import type { IRetryOptions } from "./retry.model.js";
2
4
  import type { TScheduleStrategy } from "./strategy.model.js";
3
5
  /**
@@ -31,6 +33,19 @@ export interface IScheduleOptions {
31
33
  * Must be a positive finite number greater than 0 if provided.
32
34
  */
33
35
  timeoutMs?: number;
36
+ /**
37
+ * Overall budget in milliseconds allowed for the entire task lifecycle,
38
+ * including queue wait times, execution durations, and retry backoffs.
39
+ * If exceeded, the task rejects with an AhkoTimeoutError.
40
+ */
41
+ totalTimeoutMs?: number;
42
+ /**
43
+ * Priority assigned to the task ("high", "normal", "low", or explicit numeric value).
44
+ * High priority tasks jump ahead of lower priority tasks in the pending queue.
45
+ * FIFO ordering is strictly preserved among tasks of equal priority.
46
+ * @default "normal" (0)
47
+ */
48
+ priority?: TTaskPriority;
34
49
  /**
35
50
  * Explicit identity key for "debounce" and "throttle" strategies.
36
51
  * Tasks sharing the same key coalesce into shared executions.
@@ -65,4 +80,12 @@ export interface IAhkoOptions {
65
80
  * @default 0
66
81
  */
67
82
  minIntervalMs?: number;
83
+ /**
84
+ * Optional circuit breaker policy to guard against cascading failures.
85
+ */
86
+ circuitBreaker?: ICircuitBreakerOptions;
87
+ /**
88
+ * Optional named profile from `config.ahko.json` to inherit configuration defaults from.
89
+ */
90
+ profile?: string;
68
91
  }
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Named priority level or explicit numeric priority for scheduled tasks.
3
+ * Higher numeric values indicate higher execution priority.
4
+ */
5
+ export type TTaskPriority = "high" | "normal" | "low" | number;
6
+ /** Default priority weight mappings */
7
+ export declare const TASK_PRIORITY_WEIGHTS: {
8
+ readonly high: 10;
9
+ readonly normal: 0;
10
+ readonly low: -10;
11
+ };
12
+ /**
13
+ * Resolves a task priority into a normalized numeric weight.
14
+ *
15
+ * @param priority - Named or numeric priority.
16
+ * @returns Numeric weight (default 0 for normal).
17
+ */
18
+ export declare function resolvePriorityWeight(priority?: TTaskPriority): number;
@@ -1,3 +1,4 @@
1
+ import type { ECircuitState } from "./circuit-breaker.model.js";
1
2
  /**
2
3
  * Telemetry snapshot of the Ahko scheduler.
3
4
  */
@@ -20,4 +21,8 @@ export interface IAhkoStats {
20
21
  totalDispatched: number;
21
22
  /** Maximum concurrent execution capacity */
22
23
  capacity: number;
24
+ /** Whether task dispatching is currently paused */
25
+ isPaused: boolean;
26
+ /** Current state of the scheduler circuit breaker, if configured */
27
+ circuitState?: ECircuitState;
23
28
  }
@@ -0,0 +1,56 @@
1
+ import { ECircuitState, type ICircuitBreakerOptions, type ICircuitBreakerStats } from "../models/circuit-breaker.model.js";
2
+ /**
3
+ * Manages circuit breaker failure tracking, state transitions, and fast-fail enforcement.
4
+ *
5
+ * Implements standard Martin Fowler Circuit Breaker state machine:
6
+ * - CLOSED: All operations execute normally.
7
+ * - OPEN: All operations fast-fail immediately with AhkoCircuitBreakerOpenError.
8
+ * - HALF_OPEN: Probe execution allowed to verify recovery.
9
+ */
10
+ export declare class CircuitBreakerCoordinator {
11
+ private _state;
12
+ private _consecutiveFailures;
13
+ private _lastFailureTime;
14
+ readonly failureThreshold: number;
15
+ readonly resetTimeoutMs: number;
16
+ /**
17
+ * Initializes a new CircuitBreakerCoordinator.
18
+ *
19
+ * @param options - Configuration options for threshold and cool-down window.
20
+ * @throws {AhkoConfigurationError} If options are invalid.
21
+ */
22
+ constructor(options: ICircuitBreakerOptions);
23
+ /** Current state of the circuit breaker */
24
+ get state(): ECircuitState;
25
+ /**
26
+ * Checks whether an execution is currently allowed.
27
+ * If the circuit is OPEN and cool-down has not elapsed, fast-fails immediately.
28
+ *
29
+ * @throws {AhkoCircuitBreakerOpenError} If the circuit is currently OPEN.
30
+ */
31
+ checkAllowed(): void;
32
+ /**
33
+ * Records a successful task execution.
34
+ * Heals HALF_OPEN state back to CLOSED and resets consecutive failure counters.
35
+ */
36
+ recordSuccess(): void;
37
+ /**
38
+ * Records a failed task execution.
39
+ * Trips CLOSED to OPEN when threshold is met, or re-trips HALF_OPEN immediately.
40
+ *
41
+ * @param _error - Optional error that caused the failure.
42
+ */
43
+ recordFailure(_error?: unknown): void;
44
+ /**
45
+ * Evaluates if enough time has passed to transition from OPEN to HALF_OPEN.
46
+ */
47
+ private refreshState;
48
+ /**
49
+ * Resets the circuit breaker back to initial CLOSED state.
50
+ */
51
+ reset(): void;
52
+ /**
53
+ * Returns a snapshot of circuit breaker telemetry.
54
+ */
55
+ getStats(): ICircuitBreakerStats;
56
+ }
@@ -1,12 +1,14 @@
1
+ import type { ICircuitBreakerOptions } from "../models/circuit-breaker.model.js";
1
2
  import type { IScheduleOptions } from "../models/options.model.js";
2
3
  import type { IAhkoStats } from "../models/stats.model.js";
4
+ import { CircuitBreakerCoordinator } from "./circuit-breaker.js";
3
5
  import { DebounceCoordinator } from "./debounce-coordinator.js";
4
6
  import { TaskRunner } from "./task-runner.js";
5
7
  import { ThrottleCoordinator } from "./throttle-coordinator.js";
6
8
  import { AhkoEventEmitter } from "../events/event-emitter.js";
7
9
  /**
8
- * Memory-safe FIFO task queue managing concurrency allocation,
9
- * delayed scheduling, and task lifecycle counters.
10
+ * Memory-safe priority-aware task queue managing concurrency allocation,
11
+ * rate limiting, circuit breaker protection, flow control (pause/resume), and task lifecycle counters.
10
12
  */
11
13
  export declare class TaskQueue {
12
14
  /** Maximum concurrent active tasks */
@@ -33,6 +35,10 @@ export declare class TaskQueue {
33
35
  readonly throttleCoordinator: ThrottleCoordinator;
34
36
  /** Lifecycle event emitter for task and scheduler events */
35
37
  readonly emitter: AhkoEventEmitter;
38
+ /** Circuit breaker coordinator if configured */
39
+ readonly circuitBreakerCoordinator?: CircuitBreakerCoordinator;
40
+ /** Pause state flag */
41
+ private _isPaused;
36
42
  /** Set of pending resolvers awaiting scheduler idle transition */
37
43
  private readonly idleResolvers;
38
44
  /** WeakMap associating task runners with their scheduling options */
@@ -54,9 +60,27 @@ export declare class TaskQueue {
54
60
  *
55
61
  * @param concurrency - Maximum concurrent tasks (defaults to Infinity).
56
62
  * @param minIntervalMs - Minimum interval in milliseconds between task dispatches.
63
+ * @param circuitBreakerOptions - Optional circuit breaker policy configuration.
57
64
  * @throws {AhkoConfigurationError} If concurrency is less than 1 or minIntervalMs is invalid.
58
65
  */
59
- constructor(concurrency?: number, minIntervalMs?: number);
66
+ constructor(concurrency?: number, minIntervalMs?: number, circuitBreakerOptions?: ICircuitBreakerOptions);
67
+ /**
68
+ * Pauses queue execution. Running tasks will complete normally, but no new pending tasks will be dispatched.
69
+ */
70
+ pause(): void;
71
+ /**
72
+ * Resumes queue execution, immediately dispatching waiting tasks up to available concurrency.
73
+ */
74
+ resume(): void;
75
+ /**
76
+ * Checks whether the task queue is currently paused.
77
+ */
78
+ isPaused(): boolean;
79
+ /**
80
+ * Inserts a task runner into the queue based on priority weight (descending).
81
+ * Preserves FIFO ordering among tasks with identical priority.
82
+ */
83
+ private insertIntoQueue;
60
84
  /**
61
85
  * Enqueues a task runner according to the specified schedule options.
62
86
  *
@@ -79,7 +103,8 @@ export declare class TaskQueue {
79
103
  private scheduleIdle;
80
104
  /**
81
105
  * Pumps the queue by picking pending tasks and executing them
82
- * as long as concurrency capacity is available and minIntervalMs is respected.
106
+ * as long as concurrency capacity is available, minIntervalMs is respected,
107
+ * and queue is not paused.
83
108
  */
84
109
  private pump;
85
110
  /**
@@ -44,6 +44,8 @@ export declare class TaskRunner<T> {
44
44
  * @param timeoutMs - Optional maximum execution time in milliseconds.
45
45
  */
46
46
  constructor(task: ITask<T>, externalSignal?: AbortSignal, timeoutMs?: number);
47
+ /** Flag indicating if runner was aborted by an overall total timeout deadline */
48
+ totalTimedOut: boolean;
47
49
  /**
48
50
  * Gets the current lifecycle state of the task.
49
51
  */
@@ -84,6 +86,13 @@ export declare class TaskRunner<T> {
84
86
  * @param reason - Optional cancellation reason.
85
87
  */
86
88
  cancel(reason?: unknown): void;
89
+ /**
90
+ * Times out the task, aborting pending or running execution with AhkoTimeoutError.
91
+ *
92
+ * @param timeoutMs - Timeout duration in milliseconds.
93
+ * @param message - Optional custom timeout message.
94
+ */
95
+ timeout(timeoutMs: number, message?: string): void;
87
96
  /**
88
97
  * Handles external AbortSignal trigger.
89
98
  */
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 = "1.0.0";
4
+ export declare const VERSION = "1.1.0";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mrjacket/ahko",
3
- "version": "1.0.0",
3
+ "version": "1.1.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",