@mrjacket/ahko 1.1.0 → 1.1.5
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 +29 -0
- package/README.md +90 -1
- package/dist/ahko.d.ts +75 -0
- package/dist/index.cjs +495 -31
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.js +494 -31
- package/dist/index.js.map +1 -1
- package/dist/models/adaptive.model.d.ts +47 -0
- package/dist/models/batch.model.d.ts +22 -0
- package/dist/models/events.model.d.ts +6 -0
- package/dist/models/index.d.ts +2 -0
- package/dist/models/options.model.d.ts +9 -0
- package/dist/models/stats.model.d.ts +3 -0
- package/dist/scheduler/adaptive-coordinator.d.ts +45 -0
- package/dist/scheduler/task-queue.d.ts +47 -3
- package/dist/scheduler/task-runner.d.ts +4 -1
- package/dist/version.d.ts +1 -1
- package/package.json +1 -1
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/errors/ahko.error.ts","../src/errors/configuration.error.ts","../src/config/config-loader.ts","../src/models/strategy.model.ts","../src/errors/circuit-breaker.error.ts","../src/errors/timeout.error.ts","../src/models/priority.model.ts","../src/models/state.model.ts","../src/retry/backoff.ts","../src/models/circuit-breaker.model.ts","../src/scheduler/circuit-breaker.ts","../src/errors/cancellation.error.ts","../src/scheduler/debounce-coordinator.ts","../src/scheduler/idle-scheduler.ts","../src/scheduler/throttle-coordinator.ts","../src/events/event-emitter.ts","../src/scheduler/task-queue.ts","../src/scheduler/task-runner.ts","../src/ahko.ts","../src/version.ts","../src/errors/queue.error.ts","../src/scheduler/signal.ts"],"sourcesContent":["export { Ahko } from \"./ahko.js\";\nexport { VERSION } from \"./version.js\";\n\n// Errors\nexport {\n AhkoError,\n AhkoCancellationError,\n AhkoConfigurationError,\n AhkoQueueError,\n AhkoTimeoutError,\n AhkoCircuitBreakerOpenError,\n type IAhkoTimeoutErrorOptions,\n type IAhkoCircuitBreakerErrorOptions,\n} from \"./errors/index.js\";\n\n// Models and interfaces\nexport {\n ETaskState,\n EScheduleStrategy,\n ECircuitState,\n TASK_PRIORITY_WEIGHTS,\n resolvePriorityWeight,\n} from \"./models/index.js\";\n\nexport type {\n ITask,\n ITaskContext,\n IScheduleOptions,\n IAhkoOptions,\n IAhkoStats,\n TScheduleStrategy,\n IRetryOptions,\n TRetryBackoff,\n TRetryPredicate,\n IAhkoEventMap,\n TAhkoEventName,\n TAhkoEventHandler,\n TAhkoUnsubscribe,\n TCircuitState,\n ICircuitBreakerOptions,\n ICircuitBreakerStats,\n TTaskPriority,\n IAhkoFileConfig,\n IAhkoProfileConfig,\n} from \"./models/index.js\";\n\n// Config utilities\nexport {\n loadConfig,\n resetConfig,\n loadConfigFile,\n getActiveConfig,\n getProfileConfig,\n} from \"./config/index.js\";\n\n// Circuit Breaker Coordinator\nexport { CircuitBreakerCoordinator } from \"./scheduler/circuit-breaker.js\";\n\n// Retry utilities\nexport {\n calculateBackoff,\n DEFAULT_BASE_DELAY,\n DEFAULT_MAX_DELAY,\n} from \"./retry/index.js\";\n\n// Signal utilities\nexport {\n combineSignals,\n type ICombinedSignal,\n} from \"./scheduler/signal.js\";\n","/**\n * Base error class for all errors originating from the Ahko scheduler.\n */\nexport class AhkoError extends Error {\n /**\n * Creates a new AhkoError instance.\n *\n * @param message - Descriptive error message.\n * @param options - Standard Error options including cause.\n */\n constructor(message: string, options?: ErrorOptions) {\n super(message, options);\n this.name = \"AhkoError\";\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n","import { AhkoError } from \"./ahko.error.js\";\n\n/**\n * Thrown when invalid configuration or scheduling options are provided.\n */\nexport class AhkoConfigurationError extends AhkoError {\n /**\n * Creates a new AhkoConfigurationError.\n *\n * @param message - Explanation of the invalid configuration parameter.\n * @param options - Standard Error options including cause.\n */\n constructor(message: string, options?: ErrorOptions) {\n super(message, options);\n this.name = \"AhkoConfigurationError\";\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n","import type { IAhkoFileConfig, IAhkoProfileConfig } from \"../models/config.model.js\";\n\nlet activeConfig: IAhkoFileConfig | undefined;\n\n/**\n * Programmatically loads and activates a declarative configuration.\n * Universal across Node.js, browsers, and edge environments.\n *\n * @param config - Complete configuration object conforming to `IAhkoFileConfig`.\n */\nexport function loadConfig(config: IAhkoFileConfig): void {\n activeConfig = { ...config };\n}\n\n/**\n * Resets the currently active configuration in memory to undefined.\n */\nexport function resetConfig(): void {\n activeConfig = undefined;\n}\n\n/**\n * Asynchronously loads a `config.ahko.json` or custom config file from the filesystem in Node.js.\n * Sets the active configuration in memory upon successful read and parse.\n *\n * @param filePath - Optional relative or absolute path to the configuration file (default: \"config.ahko.json\").\n * @returns The parsed configuration object, or `undefined` if not running in Node.js or if file cannot be read.\n */\nexport async function loadConfigFile(filePath = \"config.ahko.json\"): Promise<IAhkoFileConfig | undefined> {\n if (typeof process === \"undefined\" || !process.versions?.node) {\n return undefined;\n }\n\n try {\n const { readFile } = await import(\"node:fs/promises\");\n const { resolve } = await import(\"node:path\");\n const resolvedPath = resolve(process.cwd(), filePath);\n const content = await readFile(resolvedPath, \"utf-8\");\n const parsed = JSON.parse(content) as IAhkoFileConfig;\n activeConfig = parsed;\n return parsed;\n } catch {\n return undefined;\n }\n}\n\n/**\n * Safely inspects the local filesystem synchronously if running in a Node.js CJS/compatible environment.\n */\nfunction tryAutoDiscoverSync(): void {\n if (activeConfig !== undefined || typeof process === \"undefined\" || !process.versions?.node) {\n return;\n }\n\n try {\n let fs: { existsSync(p: string): boolean; readFileSync(p: string, enc: string): string } | null = null;\n let path: { resolve(...paths: string[]): string } | null = null;\n\n if (typeof (process as unknown as { getBuiltinModule?: (mod: string) => unknown }).getBuiltinModule === \"function\") {\n const getBuiltin = (process as unknown as { getBuiltinModule: (mod: string) => unknown }).getBuiltinModule;\n fs = getBuiltin(\"node:fs\") as typeof fs;\n path = getBuiltin(\"node:path\") as typeof path;\n } else if (typeof require === \"function\") {\n // eslint-disable-next-line @typescript-eslint/no-require-imports\n fs = require(\"node:fs\");\n // eslint-disable-next-line @typescript-eslint/no-require-imports\n path = require(\"node:path\");\n }\n\n if (fs && path) {\n const configPath = path.resolve(process.cwd(), \"config.ahko.json\");\n if (fs.existsSync(configPath)) {\n const raw = fs.readFileSync(configPath, \"utf-8\");\n activeConfig = JSON.parse(raw) as IAhkoFileConfig;\n }\n }\n } catch {\n // Non-critical auto-discovery failure; fallback to programmatic configuration\n }\n}\n\n/**\n * Returns the currently active declarative configuration, attempting auto-discovery if in Node.js.\n */\nexport function getActiveConfig(): IAhkoFileConfig | undefined {\n if (activeConfig === undefined) {\n tryAutoDiscoverSync();\n }\n return activeConfig;\n}\n\n/**\n * Retrieves a specific profile configuration by name, or the default profile if no name is provided.\n *\n * @param profileName - Optional name of the profile (e.g. \"api\", \"background\").\n * @returns The profile configuration if defined, or undefined.\n */\nexport function getProfileConfig(profileName?: string): IAhkoProfileConfig | undefined {\n const config = getActiveConfig();\n if (!config) {\n return undefined;\n }\n\n if (profileName) {\n return config.profiles?.[profileName];\n }\n\n return config.default;\n}\n","/**\n * Fundamental scheduling strategies supported by the Ahko scheduler.\n */\nexport enum EScheduleStrategy {\n /** Execute as soon as a concurrency slot is available */\n IMMEDIATE = \"immediate\",\n /** Delay execution for a designated duration before queuing */\n DELAY = \"delay\",\n /** Execute during platform idle opportunities (requestIdleCallback in browser, setImmediate in Node.js) */\n IDLE = \"idle\",\n /** Enforce maximum execution frequency for tasks sharing the same key */\n THROTTLE = \"throttle\",\n /** Delay execution until calls sharing the same key stop arriving */\n DEBOUNCE = \"debounce\",\n}\n\n/**\n * Union type representing valid scheduling strategy identifiers.\n */\nexport type TScheduleStrategy =\n | EScheduleStrategy\n | \"immediate\"\n | \"delay\"\n | \"idle\"\n | \"throttle\"\n | \"debounce\";\n","import { AhkoError } from \"./ahko.error.js\";\n\n/**\n * Options describing the circuit breaker open state.\n */\nexport interface IAhkoCircuitBreakerErrorOptions {\n /** Time remaining in milliseconds before the circuit attempts half-open trial */\n resetTimeoutMs?: number;\n /** Timestamp when the circuit tripped open */\n trippedAt?: number;\n /** Consecutive failures that caused the trip */\n consecutiveFailures?: number;\n}\n\n/**\n * Thrown when attempting to execute a task while the scheduler's circuit breaker is in OPEN state.\n */\nexport class AhkoCircuitBreakerOpenError extends AhkoError {\n /** Time remaining in milliseconds before trial execution is allowed */\n public readonly resetTimeoutMs?: number;\n\n /** Timestamp when the circuit tripped open */\n public readonly trippedAt?: number;\n\n /** Total consecutive failures that caused the trip */\n public readonly consecutiveFailures?: number;\n\n constructor(\n message = \"Circuit breaker is open. Fast-failing task execution to protect downstream resources.\",\n options?: IAhkoCircuitBreakerErrorOptions\n ) {\n super(message);\n this.name = \"AhkoCircuitBreakerOpenError\";\n this.resetTimeoutMs = options?.resetTimeoutMs;\n this.trippedAt = options?.trippedAt;\n this.consecutiveFailures = options?.consecutiveFailures;\n }\n}\n","import { AhkoError } from \"./ahko.error.js\";\n\n/**\n * Options for constructing an AhkoTimeoutError.\n */\nexport interface IAhkoTimeoutErrorOptions extends ErrorOptions {\n /**\n * The timeout threshold in milliseconds that was exceeded.\n */\n timeoutMs?: number;\n}\n\n/**\n * Thrown when a task exceeds its allotted timeout duration.\n */\nexport class AhkoTimeoutError extends AhkoError {\n /**\n * The timeout threshold in milliseconds that was exceeded, if configured.\n */\n public readonly timeoutMs?: number;\n\n /**\n * Creates a new AhkoTimeoutError.\n *\n * @param message - Explanation of timeout expiry.\n * @param options - Standard Error options including optional timeoutMs and cause.\n */\n constructor(\n message = \"Task execution timed out\",\n options?: IAhkoTimeoutErrorOptions\n ) {\n super(message, options);\n this.name = \"AhkoTimeoutError\";\n this.timeoutMs = options?.timeoutMs;\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n","/**\n * Named priority level or explicit numeric priority for scheduled tasks.\n * Higher numeric values indicate higher execution priority.\n */\nexport type TTaskPriority = \"high\" | \"normal\" | \"low\" | number;\n\n/** Default priority weight mappings */\nexport const TASK_PRIORITY_WEIGHTS = {\n high: 10,\n normal: 0,\n low: -10,\n} as const;\n\n/**\n * Resolves a task priority into a normalized numeric weight.\n *\n * @param priority - Named or numeric priority.\n * @returns Numeric weight (default 0 for normal).\n */\nexport function resolvePriorityWeight(priority?: TTaskPriority): number {\n if (priority === undefined) {\n return TASK_PRIORITY_WEIGHTS.normal;\n }\n if (typeof priority === \"number\") {\n return Number.isFinite(priority) ? priority : TASK_PRIORITY_WEIGHTS.normal;\n }\n if (priority === \"high\") {\n return TASK_PRIORITY_WEIGHTS.high;\n }\n if (priority === \"low\") {\n return TASK_PRIORITY_WEIGHTS.low;\n }\n return TASK_PRIORITY_WEIGHTS.normal;\n}\n","/**\n * Represents the discrete lifecycle states of an Ahko task.\n */\nexport enum ETaskState {\n /** Task has been scheduled and is awaiting execution in queue or timer */\n PENDING = \"pending\",\n /** Task is currently executing within an allocated concurrency slot */\n RUNNING = \"running\",\n /** Task successfully finished execution */\n COMPLETED = \"completed\",\n /** Task execution threw an error or rejected */\n FAILED = \"failed\",\n /** Task was cancelled via AbortSignal before or during execution */\n CANCELLED = \"cancelled\",\n /** Task was terminated because its execution exceeded the timeout */\n TIMED_OUT = \"timed_out\",\n}\n","import type { IRetryOptions } from \"../models/retry.model.js\";\n\n/**\n * Default base delay for backoff calculations in milliseconds.\n */\nexport const DEFAULT_BASE_DELAY = 250;\n\n/**\n * Default maximum delay ceiling for backoff calculations in milliseconds.\n */\nexport const DEFAULT_MAX_DELAY = 10_000;\n\n/**\n * Computes backoff delay in milliseconds for a retry attempt based on configured policy.\n *\n * @param attempt - 1-based index of the attempt that failed (1 for first failure, 2 for second, etc.).\n * @param options - Retry configuration options.\n * @param randomFn - Injectable random generator function (defaults to Math.random) for deterministic testing.\n * @returns Delay duration in milliseconds before next attempt.\n */\nexport function calculateBackoff(\n attempt: number,\n options?: IRetryOptions,\n randomFn: () => number = Math.random\n): number {\n const backoff = options?.backoff ?? \"exponential\";\n\n if (backoff === \"none\") {\n return 0;\n }\n\n const baseDelay =\n typeof options?.baseDelay === \"number\" && !Number.isNaN(options.baseDelay) && options.baseDelay >= 0\n ? options.baseDelay\n : DEFAULT_BASE_DELAY;\n\n const maxDelay =\n typeof options?.maxDelay === \"number\" && !Number.isNaN(options.maxDelay) && options.maxDelay >= baseDelay\n ? options.maxDelay\n : Math.max(DEFAULT_MAX_DELAY, baseDelay);\n\n let calculatedDelay: number;\n\n if (backoff === \"linear\") {\n calculatedDelay = baseDelay * Math.max(1, attempt);\n } else {\n // exponential: baseDelay * 2^(attempt - 1)\n const exponent = Math.max(0, attempt - 1);\n // Prevent 2^exponent overflow\n const factor = exponent > 30 ? 2 ** 30 : 2 ** exponent;\n calculatedDelay = baseDelay * factor;\n }\n\n const cappedDelay = Math.min(calculatedDelay, maxDelay);\n\n if (options?.jitter) {\n // Full jitter: uniformly random between 0 and cappedDelay\n return Math.floor(randomFn() * (cappedDelay + 1));\n }\n\n return Math.floor(cappedDelay);\n}\n","/**\n * Discrete lifecycle states of the circuit breaker.\n */\nexport enum ECircuitState {\n /** Normal operation: calls pass through to execution */\n CLOSED = \"closed\",\n /** Failure threshold exceeded: calls fast-fail immediately */\n OPEN = \"open\",\n /** Cool-down timer elapsed: trial call allowed to test recovery */\n HALF_OPEN = \"half_open\",\n}\n\n/** Union type representing circuit breaker states */\nexport type TCircuitState = `${ECircuitState}`;\n\n/**\n * Configuration options for the circuit breaker policy.\n */\nexport interface ICircuitBreakerOptions {\n /**\n * Number of consecutive task failures required to trip the circuit to OPEN state.\n * Must be an integer greater than or equal to 1.\n */\n failureThreshold: number;\n\n /**\n * Time in milliseconds the circuit remains OPEN before transitioning to HALF_OPEN\n * to attempt a recovery trial call. Must be a positive finite number.\n */\n resetTimeoutMs: number;\n}\n\n/**\n * Telemetry snapshot of circuit breaker status.\n */\nexport interface ICircuitBreakerStats {\n /** Current state of the breaker */\n state: ECircuitState;\n /** Number of consecutive errors recorded */\n consecutiveFailures: number;\n /** Timestamp in ms when the breaker tripped to OPEN, if open */\n lastFailureTime?: number;\n}\n","import { AhkoCircuitBreakerOpenError } from \"../errors/circuit-breaker.error.js\";\nimport { AhkoConfigurationError } from \"../errors/configuration.error.js\";\nimport {\n ECircuitState,\n type ICircuitBreakerOptions,\n type ICircuitBreakerStats,\n} from \"../models/circuit-breaker.model.js\";\n\n/**\n * Manages circuit breaker failure tracking, state transitions, and fast-fail enforcement.\n *\n * Implements standard Martin Fowler Circuit Breaker state machine:\n * - CLOSED: All operations execute normally.\n * - OPEN: All operations fast-fail immediately with AhkoCircuitBreakerOpenError.\n * - HALF_OPEN: Probe execution allowed to verify recovery.\n */\nexport class CircuitBreakerCoordinator {\n private _state = ECircuitState.CLOSED;\n private _consecutiveFailures = 0;\n private _lastFailureTime: number | undefined;\n public readonly failureThreshold: number;\n public readonly resetTimeoutMs: number;\n\n /**\n * Initializes a new CircuitBreakerCoordinator.\n *\n * @param options - Configuration options for threshold and cool-down window.\n * @throws {AhkoConfigurationError} If options are invalid.\n */\n constructor(options: ICircuitBreakerOptions) {\n if (\n typeof options.failureThreshold !== \"number\" ||\n Number.isNaN(options.failureThreshold) ||\n !Number.isInteger(options.failureThreshold) ||\n options.failureThreshold < 1\n ) {\n throw new AhkoConfigurationError(\n `Invalid failureThreshold \"${options.failureThreshold}\". failureThreshold must be an integer greater than or equal to 1.`\n );\n }\n\n if (\n typeof options.resetTimeoutMs !== \"number\" ||\n Number.isNaN(options.resetTimeoutMs) ||\n !Number.isFinite(options.resetTimeoutMs) ||\n options.resetTimeoutMs <= 0\n ) {\n throw new AhkoConfigurationError(\n `Invalid resetTimeoutMs \"${options.resetTimeoutMs}\". resetTimeoutMs must be a positive finite number greater than 0.`\n );\n }\n\n this.failureThreshold = options.failureThreshold;\n this.resetTimeoutMs = options.resetTimeoutMs;\n }\n\n /** Current state of the circuit breaker */\n public get state(): ECircuitState {\n this.refreshState();\n return this._state;\n }\n\n /**\n * Checks whether an execution is currently allowed.\n * If the circuit is OPEN and cool-down has not elapsed, fast-fails immediately.\n *\n * @throws {AhkoCircuitBreakerOpenError} If the circuit is currently OPEN.\n */\n public checkAllowed(): void {\n this.refreshState();\n\n if (this._state === ECircuitState.OPEN) {\n const remainingMs = this._lastFailureTime\n ? Math.max(0, this.resetTimeoutMs - (Date.now() - this._lastFailureTime))\n : this.resetTimeoutMs;\n\n throw new AhkoCircuitBreakerOpenError(\n `Circuit breaker is open. Fast-failing task execution. Remaining cool-down: ${remainingMs}ms.`,\n {\n resetTimeoutMs: remainingMs,\n trippedAt: this._lastFailureTime,\n consecutiveFailures: this._consecutiveFailures,\n }\n );\n }\n }\n\n /**\n * Records a successful task execution.\n * Heals HALF_OPEN state back to CLOSED and resets consecutive failure counters.\n */\n public recordSuccess(): void {\n this._consecutiveFailures = 0;\n this._state = ECircuitState.CLOSED;\n }\n\n /**\n * Records a failed task execution.\n * Trips CLOSED to OPEN when threshold is met, or re-trips HALF_OPEN immediately.\n *\n * @param _error - Optional error that caused the failure.\n */\n public recordFailure(_error?: unknown): void {\n this._consecutiveFailures++;\n this._lastFailureTime = Date.now();\n\n if (this._state === ECircuitState.HALF_OPEN) {\n this._state = ECircuitState.OPEN;\n return;\n }\n\n if (this._consecutiveFailures >= this.failureThreshold) {\n this._state = ECircuitState.OPEN;\n }\n }\n\n /**\n * Evaluates if enough time has passed to transition from OPEN to HALF_OPEN.\n */\n private refreshState(): void {\n if (this._state === ECircuitState.OPEN && this._lastFailureTime !== undefined) {\n const elapsed = Date.now() - this._lastFailureTime;\n if (elapsed >= this.resetTimeoutMs) {\n this._state = ECircuitState.HALF_OPEN;\n }\n }\n }\n\n /**\n * Resets the circuit breaker back to initial CLOSED state.\n */\n public reset(): void {\n this._state = ECircuitState.CLOSED;\n this._consecutiveFailures = 0;\n this._lastFailureTime = undefined;\n }\n\n /**\n * Returns a snapshot of circuit breaker telemetry.\n */\n public getStats(): ICircuitBreakerStats {\n this.refreshState();\n return {\n state: this._state,\n consecutiveFailures: this._consecutiveFailures,\n lastFailureTime: this._lastFailureTime,\n };\n }\n}\n","import { AhkoError } from \"./ahko.error.js\";\n\n/**\n * Thrown when a task is cancelled before or during execution.\n */\nexport class AhkoCancellationError extends AhkoError {\n /**\n * Creates a new AhkoCancellationError.\n *\n * @param message - Reason for cancellation.\n * @param options - Standard Error options including cause.\n */\n constructor(message = \"Task was cancelled\", options?: ErrorOptions) {\n super(message, options);\n this.name = \"AhkoCancellationError\";\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n","import { AhkoCancellationError } from \"../errors/cancellation.error.js\";\nimport type { IScheduleOptions } from \"../models/options.model.js\";\nimport type { ITask } from \"../models/task.model.js\";\n\n/**\n * Internal tracking entry for a coalesced debounced task.\n */\ninterface IDebounceEntry<T = unknown> {\n readonly key: string | symbol;\n task: ITask<T>;\n options?: IScheduleOptions;\n timerId: ReturnType<typeof setTimeout>;\n resolve: (value: T) => void;\n reject: (reason: unknown) => void;\n readonly promise: Promise<T>;\n abortListener?: () => void;\n}\n\n/**\n * Coordinates debounce execution with Promise coalescing by explicit key.\n *\n * Incoming calls with the same key extend the quiet window and share the\n * eventual execution Promise, guaranteeing that all callers receive the final result.\n */\nexport class DebounceCoordinator {\n private readonly entries = new Map<string | symbol, IDebounceEntry<unknown>>();\n\n /** Optional callback invoked whenever entries are settled or removed from coordinator */\n public onSettled?: () => void;\n\n /**\n * Schedules a task under the debounce strategy.\n *\n * @param key - Explicit identity key.\n * @param task - Work to execute once calls stop arriving.\n * @param waitMs - Quiet window duration in milliseconds.\n * @param options - Scheduling options.\n * @param dispatchFn - Callback invoked when the debounce window expires to dispatch the task to the queue.\n * @returns Shared promise that resolves/rejects with the final execution outcome.\n */\n public schedule<T>(\n key: string | symbol,\n task: ITask<T>,\n waitMs: number,\n options: IScheduleOptions | undefined,\n dispatchFn: (task: ITask<T>, options?: IScheduleOptions) => Promise<T>\n ): Promise<T> {\n const existing = this.entries.get(key) as IDebounceEntry<T> | undefined;\n\n if (existing) {\n clearTimeout(existing.timerId);\n if (existing.options?.signal && existing.abortListener) {\n existing.options.signal.removeEventListener(\"abort\", existing.abortListener);\n }\n\n existing.task = task;\n existing.options = options;\n\n if (options?.signal?.aborted) {\n this.entries.delete(key);\n const err = new AhkoCancellationError(\n typeof options.signal.reason === \"string\"\n ? options.signal.reason\n : \"Debounced task was cancelled prior to execution\",\n { cause: options.signal.reason instanceof Error ? options.signal.reason : undefined }\n );\n existing.reject(err);\n return existing.promise;\n }\n\n if (options?.signal) {\n const listener = () => {\n this.cancel(key, options.signal?.reason);\n };\n existing.abortListener = listener;\n options.signal.addEventListener(\"abort\", listener, { once: true });\n }\n\n existing.timerId = setTimeout(() => {\n void this.flush(key, dispatchFn);\n }, waitMs);\n\n return existing.promise;\n }\n\n let resolvePromise!: (value: T) => void;\n let rejectPromise!: (reason: unknown) => void;\n\n const promise = new Promise<T>((resolve, reject) => {\n resolvePromise = resolve;\n rejectPromise = reject;\n });\n\n if (options?.signal?.aborted) {\n const err = new AhkoCancellationError(\n typeof options.signal.reason === \"string\"\n ? options.signal.reason\n : \"Debounced task was cancelled prior to execution\",\n { cause: options.signal.reason instanceof Error ? options.signal.reason : undefined }\n );\n rejectPromise(err);\n return promise;\n }\n\n let abortListener: (() => void) | undefined;\n if (options?.signal) {\n abortListener = () => {\n this.cancel(key, options.signal?.reason);\n };\n options.signal.addEventListener(\"abort\", abortListener, { once: true });\n }\n\n const timerId = setTimeout(() => {\n void this.flush(key, dispatchFn);\n }, waitMs);\n\n const entry: IDebounceEntry<T> = {\n key,\n task,\n options,\n timerId,\n resolve: resolvePromise,\n reject: rejectPromise,\n promise,\n abortListener,\n };\n\n this.entries.set(key, entry as IDebounceEntry<unknown>);\n return promise;\n }\n\n /**\n * Dispatches the coalesced task when the quiet window expires.\n */\n private async flush<T>(\n key: string | symbol,\n dispatchFn: (task: ITask<T>, options?: IScheduleOptions) => Promise<T>\n ): Promise<void> {\n const entry = this.entries.get(key) as IDebounceEntry<T> | undefined;\n if (!entry) {\n return;\n }\n\n this.entries.delete(key);\n this.onSettled?.();\n if (entry.options?.signal && entry.abortListener) {\n entry.options.signal.removeEventListener(\"abort\", entry.abortListener);\n }\n\n try {\n const result = await dispatchFn(entry.task, entry.options);\n entry.resolve(result);\n } catch (error) {\n entry.reject(error);\n }\n }\n\n /**\n * Cancels a pending debounced task by key.\n *\n * @param key - Identity key to cancel.\n * @param reason - Optional cancellation reason.\n */\n public cancel(key: string | symbol, reason?: unknown): void {\n const entry = this.entries.get(key);\n if (!entry) {\n return;\n }\n\n clearTimeout(entry.timerId);\n this.entries.delete(key);\n this.onSettled?.();\n\n if (entry.options?.signal && entry.abortListener) {\n entry.options.signal.removeEventListener(\"abort\", entry.abortListener);\n }\n\n const cancelError = new AhkoCancellationError(\n typeof reason === \"string\" ? reason : \"Debounced task was cancelled prior to execution\",\n { cause: reason instanceof Error ? reason : undefined }\n );\n entry.reject(cancelError);\n }\n\n /**\n * Number of pending debounced tasks waiting for quiet window expiry.\n */\n public get size(): number {\n return this.entries.size;\n }\n\n /**\n * Cancels all pending debounced entries and clears the map.\n */\n public clear(): void {\n for (const entry of this.entries.values()) {\n clearTimeout(entry.timerId);\n if (entry.options?.signal && entry.abortListener) {\n entry.options.signal.removeEventListener(\"abort\", entry.abortListener);\n }\n entry.reject(new AhkoCancellationError(\"Debounced tasks cleared\"));\n }\n this.entries.clear();\n this.onSettled?.();\n }\n}\n","/**\n * Handle returned by the IdleScheduler allowing cancellation of an idle request.\n */\nexport interface IIdleHandle {\n /**\n * Cancels the scheduled idle callback and cleans up platform resources.\n */\n cancel(): void;\n}\n\n/**\n * Platform-agnostic scheduler for opportunistic idle task execution.\n *\n * Automatically detects and selects platform capabilities:\n * 1. Browser: `requestIdleCallback` / `cancelIdleCallback` (with optional timeout)\n * 2. Node.js: `setImmediate` / `clearImmediate` as low-priority primitive\n * 3. Fallback: `setTimeout(..., 0)` / `clearTimeout`\n */\nexport class IdleScheduler {\n /**\n * Schedules a callback to execute during the next idle opportunity.\n *\n * @param callback - Function to invoke when idle opportunity arises.\n * @param timeout - Optional max deadline in milliseconds to wait before invoking (browser only).\n * @param runtime - Target runtime scope providing scheduling primitives (defaults to globalThis).\n * @returns An {@link IIdleHandle} with a `cancel()` method for cleanup.\n */\n public static schedule(\n callback: () => void,\n timeout?: number,\n runtime: typeof globalThis = globalThis\n ): IIdleHandle {\n // 1. Browser requestIdleCallback\n if (\n typeof (runtime as Record<string, unknown>).requestIdleCallback === \"function\" &&\n typeof (runtime as Record<string, unknown>).cancelIdleCallback === \"function\"\n ) {\n const requestFn = (runtime as Record<string, unknown>).requestIdleCallback as (\n cb: (deadline?: unknown) => void,\n opts?: { timeout?: number }\n ) => number;\n\n const cancelFn = (runtime as Record<string, unknown>).cancelIdleCallback as (\n handle: number\n ) => void;\n\n const id = requestFn(\n () => callback(),\n typeof timeout === \"number\" && !Number.isNaN(timeout) && timeout >= 0\n ? { timeout }\n : undefined\n );\n\n return {\n cancel: () => cancelFn(id),\n };\n }\n\n // 2. Node.js setImmediate\n if (\n typeof (runtime as Record<string, unknown>).setImmediate === \"function\" &&\n typeof (runtime as Record<string, unknown>).clearImmediate === \"function\"\n ) {\n const setImmFn = (runtime as Record<string, unknown>).setImmediate as (\n cb: () => void\n ) => ReturnType<typeof setImmediate>;\n\n const clearImmFn = (runtime as Record<string, unknown>).clearImmediate as (\n handle: ReturnType<typeof setImmediate>\n ) => void;\n\n const handle = setImmFn(() => callback());\n\n return {\n cancel: () => clearImmFn(handle),\n };\n }\n\n // 3. Universal fallback setTimeout(0)\n const setTimerFn = runtime.setTimeout.bind(runtime);\n const clearTimerFn = runtime.clearTimeout.bind(runtime);\n\n const timerId = setTimerFn(() => callback(), 0);\n\n return {\n cancel: () => clearTimerFn(timerId),\n };\n }\n}\n","import { AhkoCancellationError } from \"../errors/cancellation.error.js\";\nimport type { IScheduleOptions } from \"../models/options.model.js\";\nimport type { ITask } from \"../models/task.model.js\";\n\n/**\n * Internal tracking entry for throttled executions.\n */\ninterface IThrottleEntry<T = unknown> {\n readonly key: string | symbol;\n windowTimerId?: ReturnType<typeof setTimeout>;\n trailingTask?: ITask<T>;\n trailingOptions?: IScheduleOptions;\n trailingResolve?: (value: T) => void;\n trailingReject?: (reason: unknown) => void;\n trailingPromise?: Promise<T>;\n abortListener?: () => void;\n}\n\n/**\n * Coordinates throttle execution with leading execution, trailing execution,\n * and Promise coalescing by explicit key.\n *\n * Incoming calls with the same key within the throttle period coalesce into a\n * single shared trailing execution, preventing overload while ensuring callers\n * receive the final result.\n */\nexport class ThrottleCoordinator {\n private readonly entries = new Map<string | symbol, IThrottleEntry<unknown>>();\n\n /** Optional callback invoked whenever entries are settled or removed from coordinator */\n public onSettled?: () => void;\n\n /**\n * Schedules a task under the throttle strategy.\n *\n * @param key - Explicit identity key.\n * @param task - Work to execute.\n * @param waitMs - Throttle interval duration in milliseconds.\n * @param options - Scheduling options.\n * @param dispatchFn - Callback invoked to dispatch task execution into the queue.\n * @returns Promise resolving with the leading execution or coalesced trailing result.\n */\n public schedule<T>(\n key: string | symbol,\n task: ITask<T>,\n waitMs: number,\n options: IScheduleOptions | undefined,\n dispatchFn: (task: ITask<T>, options?: IScheduleOptions) => Promise<T>\n ): Promise<T> {\n const existing = this.entries.get(key) as IThrottleEntry<T> | undefined;\n\n if (!existing) {\n // Leading execution: runs immediately\n const entry: IThrottleEntry<T> = {\n key,\n };\n\n entry.windowTimerId = setTimeout(() => {\n void this.onWindowExpire(key, waitMs, dispatchFn);\n }, waitMs);\n\n this.entries.set(key, entry as IThrottleEntry<unknown>);\n\n return dispatchFn(task, options);\n }\n\n // Trailing call within active window: coalesce with latest work\n existing.trailingTask = task;\n existing.trailingOptions = options;\n\n if (existing.trailingPromise) {\n return existing.trailingPromise;\n }\n\n let resolvePromise!: (value: T) => void;\n let rejectPromise!: (reason: unknown) => void;\n\n existing.trailingPromise = new Promise<T>((resolve, reject) => {\n resolvePromise = resolve;\n rejectPromise = reject;\n });\n existing.trailingResolve = resolvePromise;\n existing.trailingReject = rejectPromise;\n\n if (options?.signal) {\n const listener = () => {\n if (existing.trailingReject) {\n existing.trailingReject(\n new AhkoCancellationError(\"Throttled trailing task was cancelled\", {\n cause: options.signal?.reason instanceof Error ? options.signal.reason : undefined,\n })\n );\n existing.trailingTask = undefined;\n existing.trailingOptions = undefined;\n existing.trailingPromise = undefined;\n existing.trailingResolve = undefined;\n existing.trailingReject = undefined;\n }\n };\n existing.abortListener = listener;\n options.signal.addEventListener(\"abort\", listener, { once: true });\n }\n\n return existing.trailingPromise;\n }\n\n /**\n * Invoked when the throttle interval window timer expires.\n */\n private async onWindowExpire<T>(\n key: string | symbol,\n waitMs: number,\n dispatchFn: (task: ITask<T>, options?: IScheduleOptions) => Promise<T>\n ): Promise<void> {\n const entry = this.entries.get(key) as IThrottleEntry<T> | undefined;\n if (!entry) {\n return;\n }\n\n if (entry.trailingTask) {\n const task = entry.trailingTask;\n const options = entry.trailingOptions;\n const resolve = entry.trailingResolve;\n const reject = entry.trailingReject;\n\n // Reset trailing slots for subsequent calls\n entry.trailingTask = undefined;\n entry.trailingOptions = undefined;\n entry.trailingPromise = undefined;\n entry.trailingResolve = undefined;\n entry.trailingReject = undefined;\n\n // Re-arm window timer for the trailing run\n entry.windowTimerId = setTimeout(() => {\n void this.onWindowExpire(key, waitMs, dispatchFn);\n }, waitMs);\n\n try {\n const result = await dispatchFn(task, options);\n resolve?.(result);\n } catch (error) {\n reject?.(error);\n }\n return;\n }\n\n // No trailing task arrived during the window: settle and delete key\n this.entries.delete(key);\n this.onSettled?.();\n }\n\n /**\n * Cancels any pending trailing throttled task for a given key.\n *\n * @param key - Identity key to cancel.\n * @param reason - Optional cancellation reason.\n */\n public cancel(key: string | symbol, reason?: unknown): void {\n const entry = this.entries.get(key);\n if (!entry) {\n return;\n }\n\n if (entry.windowTimerId !== undefined) {\n clearTimeout(entry.windowTimerId);\n }\n this.entries.delete(key);\n this.onSettled?.();\n\n if (entry.trailingReject) {\n const cancelError = new AhkoCancellationError(\n typeof reason === \"string\" ? reason : \"Throttled task was cancelled\",\n { cause: reason instanceof Error ? reason : undefined }\n );\n entry.trailingReject(cancelError);\n }\n }\n\n /**\n * Number of keys currently actively throttled.\n */\n public get size(): number {\n return this.entries.size;\n }\n\n /**\n * Clears all throttled entries and timers.\n */\n public clear(): void {\n for (const entry of this.entries.values()) {\n if (entry.windowTimerId !== undefined) {\n clearTimeout(entry.windowTimerId);\n }\n if (entry.trailingReject) {\n entry.trailingReject(new AhkoCancellationError(\"Throttled tasks cleared\"));\n }\n }\n this.entries.clear();\n this.onSettled?.();\n }\n}\n","import type {\n IAhkoEventMap,\n TAhkoEventHandler,\n TAhkoEventName,\n TAhkoUnsubscribe,\n} from \"../models/events.model.js\";\n\n/**\n * Lightweight, zero-dependency typed event emitter with safe error containment.\n */\nexport class AhkoEventEmitter {\n private readonly listeners = new Map<\n TAhkoEventName,\n Set<TAhkoEventHandler<any>>\n >();\n\n /**\n * Subscribes a listener to a specific Ahko lifecycle event.\n *\n * @param event - The event name to subscribe to.\n * @param handler - The callback function to invoke when the event is emitted.\n * @returns An unsubscribe function to remove the listener.\n */\n public on<K extends TAhkoEventName>(\n event: K,\n handler: TAhkoEventHandler<K>\n ): TAhkoUnsubscribe {\n let set = this.listeners.get(event);\n if (!set) {\n set = new Set();\n this.listeners.set(event, set);\n }\n\n set.add(handler);\n\n return () => {\n this.off(event, handler);\n };\n }\n\n /**\n * Unsubscribes a listener from a specific Ahko lifecycle event.\n *\n * @param event - The event name.\n * @param handler - The callback function to remove.\n */\n public off<K extends TAhkoEventName>(\n event: K,\n handler: TAhkoEventHandler<K>\n ): void {\n const set = this.listeners.get(event);\n if (set) {\n set.delete(handler);\n if (set.size === 0) {\n this.listeners.delete(event);\n }\n }\n }\n\n /**\n * Emits an event with the corresponding typed payload to all subscribed listeners.\n * Listener invocations are safely isolated in try/catch to protect scheduler integrity.\n *\n * @param event - The event name to emit.\n * @param payload - The event-specific payload data.\n */\n public emit<K extends TAhkoEventName>(\n event: K,\n payload: IAhkoEventMap[K]\n ): void {\n const set = this.listeners.get(event);\n if (!set || set.size === 0) {\n return;\n }\n\n // Iterate over shallow copy to tolerate in-flight unsubscriptions\n const handlers = Array.from(set);\n for (const handler of handlers) {\n try {\n const result = handler(payload);\n if (result && typeof (result as Promise<void>).catch === \"function\") {\n (result as Promise<void>).catch(() => {});\n }\n } catch {\n // Error containment: listener exceptions do not disrupt scheduler operation\n }\n }\n }\n\n /**\n * Removes all registered event listeners.\n */\n public clear(): void {\n this.listeners.clear();\n }\n}\n","import { AhkoCircuitBreakerOpenError } from \"../errors/circuit-breaker.error.js\";\nimport { AhkoConfigurationError } from \"../errors/configuration.error.js\";\nimport { AhkoTimeoutError } from \"../errors/timeout.error.js\";\nimport type { ICircuitBreakerOptions } from \"../models/circuit-breaker.model.js\";\nimport type { IScheduleOptions } from \"../models/options.model.js\";\nimport { resolvePriorityWeight } from \"../models/priority.model.js\";\nimport type { IAhkoStats } from \"../models/stats.model.js\";\nimport { ETaskState } from \"../models/state.model.js\";\nimport { EScheduleStrategy } from \"../models/strategy.model.js\";\nimport { calculateBackoff } from \"../retry/backoff.js\";\nimport { CircuitBreakerCoordinator } from \"./circuit-breaker.js\";\nimport { DebounceCoordinator } from \"./debounce-coordinator.js\";\nimport { IdleScheduler, type IIdleHandle } from \"./idle-scheduler.js\";\nimport { TaskRunner } from \"./task-runner.js\";\nimport { ThrottleCoordinator } from \"./throttle-coordinator.js\";\nimport { AhkoEventEmitter } from \"../events/event-emitter.js\";\n\n/**\n * Entry tracking delayed task timers for deterministic cancellation and memory cleanup.\n */\ninterface IDelayedEntry {\n runner: TaskRunner<unknown>;\n timerId: ReturnType<typeof setTimeout>;\n}\n\n/**\n * Entry tracking idle callback handles for deterministic cancellation and cleanup.\n */\ninterface IIdleEntry {\n runner: TaskRunner<unknown>;\n handle: IIdleHandle;\n}\n\n/**\n * Entry tracking backoff delay timers for retry attempts.\n */\ninterface IRetryEntry {\n runner: TaskRunner<unknown>;\n timerId: ReturnType<typeof setTimeout>;\n}\n\n/**\n * Memory-safe priority-aware task queue managing concurrency allocation,\n * rate limiting, circuit breaker protection, flow control (pause/resume), and task lifecycle counters.\n */\nexport class TaskQueue {\n /** Maximum concurrent active tasks */\n public readonly concurrency: number;\n\n /** Minimum interval in milliseconds between consecutive task starts */\n public readonly minIntervalMs: number;\n\n /** Timestamp of the most recent task start */\n private lastTaskStartTime = 0;\n\n /** Active rate limit timer for pacing consecutive tasks */\n private rateLimitTimer?: ReturnType<typeof setTimeout>;\n\n /** Queue of pending task runners waiting for a concurrency slot */\n private readonly queue: TaskRunner<unknown>[] = [];\n\n /** Set of task runners currently executing */\n private readonly activeRunners = new Set<TaskRunner<unknown>>();\n\n /** Set of tasks currently in delay phase */\n private readonly delayedEntries = new Set<IDelayedEntry>();\n\n /** Set of tasks currently awaiting an idle opportunity */\n private readonly idleEntries = new Set<IIdleEntry>();\n\n /** Set of tasks currently awaiting a retry backoff timer */\n private readonly retryEntries = new Set<IRetryEntry>();\n\n /** Coordinator for debounced tasks with key coalescing */\n public readonly debounceCoordinator = new DebounceCoordinator();\n\n /** Coordinator for throttled tasks with leading/trailing coalescing */\n public readonly throttleCoordinator = new ThrottleCoordinator();\n\n /** Lifecycle event emitter for task and scheduler events */\n public readonly emitter = new AhkoEventEmitter();\n\n /** Circuit breaker coordinator if configured */\n public readonly circuitBreakerCoordinator?: CircuitBreakerCoordinator;\n\n /** Pause state flag */\n private _isPaused = false;\n\n /** Set of pending resolvers awaiting scheduler idle transition */\n private readonly idleResolvers = new Set<() => void>();\n\n /** WeakMap associating task runners with their scheduling options */\n private readonly runnerOptions = new WeakMap<TaskRunner<unknown>, IScheduleOptions>();\n\n /** Cumulative completed tasks counter */\n private completedTasks = 0;\n\n /** Cumulative failed tasks counter */\n private failedTasks = 0;\n\n /** Cumulative cancelled tasks counter */\n private cancelledTasks = 0;\n\n /** Cumulative timed out tasks counter */\n private timedOutTasks = 0;\n\n /** Cumulative count of retry attempts triggered */\n private retriedTasks = 0;\n\n /** Cumulative count of tasks dispatched to concurrency slots */\n private totalDispatched = 0;\n\n /**\n * Creates a new TaskQueue.\n *\n * @param concurrency - Maximum concurrent tasks (defaults to Infinity).\n * @param minIntervalMs - Minimum interval in milliseconds between task dispatches.\n * @param circuitBreakerOptions - Optional circuit breaker policy configuration.\n * @throws {AhkoConfigurationError} If concurrency is less than 1 or minIntervalMs is invalid.\n */\n constructor(concurrency = Infinity, minIntervalMs = 0, circuitBreakerOptions?: ICircuitBreakerOptions) {\n if (Number.isNaN(concurrency) || concurrency < 1) {\n throw new AhkoConfigurationError(\n `Invalid concurrency \"${concurrency}\". Must be a number greater than or equal to 1.`\n );\n }\n if (\n typeof minIntervalMs !== \"number\" ||\n Number.isNaN(minIntervalMs) ||\n !Number.isFinite(minIntervalMs) ||\n minIntervalMs < 0\n ) {\n throw new AhkoConfigurationError(\n `Invalid minIntervalMs \"${minIntervalMs}\". minIntervalMs must be a non-negative finite number.`\n );\n }\n this.concurrency = concurrency;\n this.minIntervalMs = minIntervalMs;\n\n if (circuitBreakerOptions) {\n this.circuitBreakerCoordinator = new CircuitBreakerCoordinator(circuitBreakerOptions);\n }\n\n this.debounceCoordinator.onSettled = () => this.checkIdle();\n this.throttleCoordinator.onSettled = () => this.checkIdle();\n }\n\n /**\n * Pauses queue execution. Running tasks will complete normally, but no new pending tasks will be dispatched.\n */\n public pause(): void {\n this._isPaused = true;\n }\n\n /**\n * Resumes queue execution, immediately dispatching waiting tasks up to available concurrency.\n */\n public resume(): void {\n if (this._isPaused) {\n this._isPaused = false;\n this.pump();\n }\n }\n\n /**\n * Checks whether the task queue is currently paused.\n */\n public isPaused(): boolean {\n return this._isPaused;\n }\n\n /**\n * Inserts a task runner into the queue based on priority weight (descending).\n * Preserves FIFO ordering among tasks with identical priority.\n */\n private insertIntoQueue(runner: TaskRunner<unknown>): void {\n const options = this.runnerOptions.get(runner);\n const targetWeight = resolvePriorityWeight(options?.priority);\n\n let insertIndex = this.queue.length;\n for (let i = 0; i < this.queue.length; i++) {\n const existingOptions = this.runnerOptions.get(this.queue[i]);\n const existingWeight = resolvePriorityWeight(existingOptions?.priority);\n if (existingWeight < targetWeight) {\n insertIndex = i;\n break;\n }\n }\n\n this.queue.splice(insertIndex, 0, runner);\n }\n\n /**\n * Enqueues a task runner according to the specified schedule options.\n *\n * @template T - The return type produced by the task.\n * @param runner - The task runner instance.\n * @param options - Scheduling options.\n * @returns The deferred promise associated with the task runner.\n * @throws {AhkoConfigurationError} If scheduling options are invalid.\n */\n public enqueue<T>(runner: TaskRunner<T>, options?: IScheduleOptions): Promise<T> {\n const strategy = options?.strategy ?? EScheduleStrategy.IMMEDIATE;\n\n if (\n strategy !== EScheduleStrategy.IMMEDIATE &&\n strategy !== EScheduleStrategy.DELAY &&\n strategy !== EScheduleStrategy.IDLE &&\n strategy !== EScheduleStrategy.THROTTLE &&\n strategy !== EScheduleStrategy.DEBOUNCE\n ) {\n throw new AhkoConfigurationError(\n `Unsupported schedule strategy \"${String(strategy)}\". Supported strategies: \"immediate\", \"delay\", \"idle\", \"throttle\", \"debounce\".`\n );\n }\n\n if (strategy === EScheduleStrategy.THROTTLE || strategy === EScheduleStrategy.DEBOUNCE) {\n if (!options?.key || (typeof options.key !== \"string\" && typeof options.key !== \"symbol\")) {\n throw new AhkoConfigurationError(\n `Strategy \"${strategy}\" requires a valid \"key\" of type string or symbol.`\n );\n }\n const waitMs = options.waitMs ?? options.delay;\n if (typeof waitMs !== \"number\" || Number.isNaN(waitMs) || !Number.isFinite(waitMs) || waitMs < 0) {\n throw new AhkoConfigurationError(\n `Strategy \"${strategy}\" requires a non-negative finite \"waitMs\" or \"delay\" in milliseconds.`\n );\n }\n }\n\n if (options?.retry) {\n if (\n typeof options.retry.attempts !== \"number\" ||\n Number.isNaN(options.retry.attempts) ||\n options.retry.attempts < 1 ||\n !Number.isInteger(options.retry.attempts)\n ) {\n throw new AhkoConfigurationError(\n `Invalid retry attempts \"${options.retry.attempts}\". attempts must be an integer greater than or equal to 1.`\n );\n }\n\n if (\n options.retry.baseDelay !== undefined &&\n (typeof options.retry.baseDelay !== \"number\" ||\n Number.isNaN(options.retry.baseDelay) ||\n options.retry.baseDelay < 0)\n ) {\n throw new AhkoConfigurationError(\n `Invalid retry baseDelay \"${options.retry.baseDelay}\". baseDelay must be a non-negative number in milliseconds.`\n );\n }\n\n if (\n options.retry.maxDelay !== undefined &&\n (typeof options.retry.maxDelay !== \"number\" ||\n Number.isNaN(options.retry.maxDelay) ||\n options.retry.maxDelay < 0)\n ) {\n throw new AhkoConfigurationError(\n `Invalid retry maxDelay \"${options.retry.maxDelay}\". maxDelay must be a non-negative number in milliseconds.`\n );\n }\n }\n\n if (options?.timeoutMs !== undefined) {\n if (\n typeof options.timeoutMs !== \"number\" ||\n Number.isNaN(options.timeoutMs) ||\n !Number.isFinite(options.timeoutMs) ||\n options.timeoutMs <= 0\n ) {\n throw new AhkoConfigurationError(\n `Invalid timeoutMs \"${options.timeoutMs}\". timeoutMs must be a positive finite number greater than 0.`\n );\n }\n }\n\n if (options?.totalTimeoutMs !== undefined) {\n if (\n typeof options.totalTimeoutMs !== \"number\" ||\n Number.isNaN(options.totalTimeoutMs) ||\n !Number.isFinite(options.totalTimeoutMs) ||\n options.totalTimeoutMs <= 0\n ) {\n throw new AhkoConfigurationError(\n `Invalid totalTimeoutMs \"${options.totalTimeoutMs}\". totalTimeoutMs must be a positive finite number greater than 0.`\n );\n }\n }\n\n if (options) {\n this.runnerOptions.set(runner as TaskRunner<unknown>, options);\n }\n\n if (runner.state === ETaskState.CANCELLED) {\n this.cancelledTasks++;\n return runner.promise;\n }\n\n // Attach totalTimeoutMs overall execution budget if configured\n if (options?.totalTimeoutMs !== undefined) {\n const budgetMs = options.totalTimeoutMs;\n const totalTimerId = setTimeout(() => {\n runner.timeout(budgetMs, `Task total execution deadline exceeded after ${budgetMs}ms`);\n }, budgetMs);\n\n runner.promise\n .finally(() => {\n clearTimeout(totalTimerId);\n })\n .catch(() => {});\n }\n\n if (strategy === EScheduleStrategy.DELAY) {\n const delayMs = options?.delay ?? 0;\n if (typeof delayMs !== \"number\" || Number.isNaN(delayMs) || delayMs < 0) {\n throw new AhkoConfigurationError(\n `Invalid delay \"${delayMs}\". Delay must be a non-negative number in milliseconds.`\n );\n }\n\n this.scheduleDelayed(runner as TaskRunner<unknown>, delayMs);\n return runner.promise;\n }\n\n if (strategy === EScheduleStrategy.IDLE) {\n if (\n options?.idleTimeout !== undefined &&\n (typeof options.idleTimeout !== \"number\" ||\n Number.isNaN(options.idleTimeout) ||\n options.idleTimeout < 0)\n ) {\n throw new AhkoConfigurationError(\n `Invalid idleTimeout \"${options.idleTimeout}\". idleTimeout must be a non-negative number in milliseconds.`\n );\n }\n\n this.scheduleIdle(runner as TaskRunner<unknown>, options?.idleTimeout);\n return runner.promise;\n }\n\n // Attach immediate onCancel handler to dequeue without consuming concurrency\n runner.onCancel = () => {\n const index = this.queue.indexOf(runner as TaskRunner<unknown>);\n if (index !== -1) {\n this.queue.splice(index, 1);\n if (runner.totalTimedOut || runner.state === ETaskState.TIMED_OUT) {\n this.timedOutTasks++;\n this.emitter.emit(\"task:timeout\", {\n taskId: runner.taskId,\n timeoutMs: options?.totalTimeoutMs ?? runner.timeoutMs,\n });\n } else {\n this.cancelledTasks++;\n this.emitter.emit(\"task:cancel\", {\n taskId: runner.taskId,\n reason: \"Task cancelled while queued\",\n });\n }\n this.checkIdle();\n }\n };\n\n // Immediate strategy: add to pending queue and pump\n this.insertIntoQueue(runner as TaskRunner<unknown>);\n this.pump();\n\n return runner.promise;\n }\n\n /**\n * Schedules a task to be placed into the queue after a delay,\n * handling early cancellation safely.\n */\n private scheduleDelayed(runner: TaskRunner<unknown>, delayMs: number): void {\n const delayedEntry: IDelayedEntry = {\n runner,\n timerId: setTimeout(() => {\n this.delayedEntries.delete(delayedEntry);\n if (runner.state === ETaskState.CANCELLED || runner.state === ETaskState.TIMED_OUT) {\n return;\n }\n\n runner.onCancel = () => {\n const index = this.queue.indexOf(runner);\n if (index !== -1) {\n this.queue.splice(index, 1);\n if (runner.totalTimedOut || runner.state === ETaskState.TIMED_OUT) {\n this.timedOutTasks++;\n this.emitter.emit(\"task:timeout\", {\n taskId: runner.taskId,\n timeoutMs: this.runnerOptions.get(runner)?.totalTimeoutMs ?? runner.timeoutMs,\n });\n } else {\n this.cancelledTasks++;\n this.emitter.emit(\"task:cancel\", {\n taskId: runner.taskId,\n reason: \"Task cancelled while queued\",\n });\n }\n this.checkIdle();\n }\n };\n\n this.insertIntoQueue(runner);\n this.pump();\n }, delayMs),\n };\n\n this.delayedEntries.add(delayedEntry);\n\n runner.onCancel = () => {\n if (this.delayedEntries.has(delayedEntry)) {\n clearTimeout(delayedEntry.timerId);\n this.delayedEntries.delete(delayedEntry);\n if (runner.totalTimedOut || runner.state === ETaskState.TIMED_OUT) {\n this.timedOutTasks++;\n this.emitter.emit(\"task:timeout\", {\n taskId: runner.taskId,\n timeoutMs: this.runnerOptions.get(runner)?.totalTimeoutMs ?? runner.timeoutMs,\n });\n } else {\n this.cancelledTasks++;\n this.emitter.emit(\"task:cancel\", {\n taskId: runner.taskId,\n reason: \"Task cancelled while waiting in delay\",\n });\n }\n this.checkIdle();\n }\n };\n }\n\n /**\n * Schedules a task to be placed into the queue during an idle opportunity,\n * handling early cancellation safely.\n */\n private scheduleIdle(runner: TaskRunner<unknown>, idleTimeout?: number): void {\n let idleEntry!: IIdleEntry;\n\n const handle = IdleScheduler.schedule(() => {\n this.idleEntries.delete(idleEntry);\n if (runner.state === ETaskState.CANCELLED || runner.state === ETaskState.TIMED_OUT) {\n return;\n }\n\n runner.onCancel = () => {\n const index = this.queue.indexOf(runner);\n if (index !== -1) {\n this.queue.splice(index, 1);\n if (runner.totalTimedOut || runner.state === ETaskState.TIMED_OUT) {\n this.timedOutTasks++;\n this.emitter.emit(\"task:timeout\", {\n taskId: runner.taskId,\n timeoutMs: this.runnerOptions.get(runner)?.totalTimeoutMs ?? runner.timeoutMs,\n });\n } else {\n this.cancelledTasks++;\n this.emitter.emit(\"task:cancel\", {\n taskId: runner.taskId,\n reason: \"Task cancelled while queued\",\n });\n }\n this.checkIdle();\n }\n };\n\n this.insertIntoQueue(runner);\n this.pump();\n }, idleTimeout);\n\n idleEntry = { runner, handle };\n this.idleEntries.add(idleEntry);\n\n runner.onCancel = () => {\n if (this.idleEntries.has(idleEntry)) {\n handle.cancel();\n this.idleEntries.delete(idleEntry);\n if (runner.totalTimedOut || runner.state === ETaskState.TIMED_OUT) {\n this.timedOutTasks++;\n this.emitter.emit(\"task:timeout\", {\n taskId: runner.taskId,\n timeoutMs: this.runnerOptions.get(runner)?.totalTimeoutMs ?? runner.timeoutMs,\n });\n } else {\n this.cancelledTasks++;\n this.emitter.emit(\"task:cancel\", {\n taskId: runner.taskId,\n reason: \"Task cancelled while waiting for idle\",\n });\n }\n this.checkIdle();\n }\n };\n }\n\n /**\n * Pumps the queue by picking pending tasks and executing them\n * as long as concurrency capacity is available, minIntervalMs is respected,\n * and queue is not paused.\n */\n private pump(): void {\n if (this._isPaused || this.queue.length === 0 || this.activeRunners.size >= this.concurrency) {\n return;\n }\n\n if (this.minIntervalMs > 0 && this.lastTaskStartTime > 0) {\n const now = Date.now();\n const elapsed = now - this.lastTaskStartTime;\n if (elapsed < this.minIntervalMs) {\n if (this.rateLimitTimer === undefined) {\n const delay = this.minIntervalMs - elapsed;\n this.rateLimitTimer = setTimeout(() => {\n this.rateLimitTimer = undefined;\n this.pump();\n }, delay);\n }\n return;\n }\n }\n\n while (!this._isPaused && this.activeRunners.size < this.concurrency && this.queue.length > 0) {\n if (this.minIntervalMs > 0 && this.lastTaskStartTime > 0) {\n const now = Date.now();\n const elapsed = now - this.lastTaskStartTime;\n if (elapsed < this.minIntervalMs) {\n if (this.rateLimitTimer === undefined) {\n const delay = this.minIntervalMs - elapsed;\n this.rateLimitTimer = setTimeout(() => {\n this.rateLimitTimer = undefined;\n this.pump();\n }, delay);\n }\n break;\n }\n }\n\n const runner = this.queue.shift();\n if (!runner) {\n break;\n }\n\n if (runner.state === ETaskState.CANCELLED || runner.state === ETaskState.TIMED_OUT) {\n continue;\n }\n\n // Fast-fail check with circuit breaker coordinator\n if (this.circuitBreakerCoordinator) {\n try {\n this.circuitBreakerCoordinator.checkAllowed();\n } catch (cbError) {\n this.failedTasks++;\n this.runnerOptions.delete(runner);\n this.emitter.emit(\"task:fail\", {\n taskId: runner.taskId,\n attempt: runner.attempt,\n error: cbError,\n willRetry: false,\n });\n runner.reject(cbError);\n continue;\n }\n }\n\n this.activeRunners.add(runner);\n this.lastTaskStartTime = Date.now();\n\n // Execute runner without unhandled rejection risk\n void this.executeRunner(runner);\n\n if (this.minIntervalMs > 0) {\n if (this.queue.length > 0 && this.activeRunners.size < this.concurrency) {\n if (this.rateLimitTimer === undefined) {\n this.rateLimitTimer = setTimeout(() => {\n this.rateLimitTimer = undefined;\n this.pump();\n }, this.minIntervalMs);\n }\n }\n break;\n }\n }\n }\n\n /**\n * Internal execution of an active task runner.\n */\n private async executeRunner(runner: TaskRunner<unknown>): Promise<void> {\n const options = this.runnerOptions.get(runner);\n\n this.totalDispatched++;\n this.emitter.emit(\"task:start\", {\n taskId: runner.taskId,\n attempt: runner.attempt,\n });\n\n try {\n const result = await runner.run();\n this.circuitBreakerCoordinator?.recordSuccess();\n this.completedTasks++;\n this.activeRunners.delete(runner);\n this.runnerOptions.delete(runner);\n this.emitter.emit(\"task:complete\", {\n taskId: runner.taskId,\n attempt: runner.attempt,\n durationMs: runner.lastDurationMs,\n result,\n });\n runner.resolve(result);\n } catch (error) {\n if (runner.state === ETaskState.CANCELLED) {\n this.cancelledTasks++;\n this.activeRunners.delete(runner);\n this.runnerOptions.delete(runner);\n this.emitter.emit(\"task:cancel\", {\n taskId: runner.taskId,\n reason: error,\n });\n runner.reject(error);\n return;\n }\n\n const shouldRetry = await runner.canRetry(error, options?.retry);\n if (shouldRetry) {\n this.retriedTasks++;\n // Free concurrency slot immediately during backoff\n this.activeRunners.delete(runner);\n this.emitter.emit(\"task:fail\", {\n taskId: runner.taskId,\n attempt: runner.attempt - 1,\n error,\n willRetry: true,\n });\n this.scheduleRetry(runner, options);\n return;\n }\n\n // Record permanent failure in circuit breaker\n if (this.circuitBreakerCoordinator && !(error instanceof AhkoCircuitBreakerOpenError)) {\n this.circuitBreakerCoordinator.recordFailure(error);\n }\n\n if (runner.state === ETaskState.TIMED_OUT || error instanceof AhkoTimeoutError) {\n this.timedOutTasks++;\n this.emitter.emit(\"task:timeout\", {\n taskId: runner.taskId,\n timeoutMs: options?.totalTimeoutMs ?? runner.timeoutMs,\n });\n } else {\n this.failedTasks++;\n }\n this.activeRunners.delete(runner);\n this.runnerOptions.delete(runner);\n this.emitter.emit(\"task:fail\", {\n taskId: runner.taskId,\n attempt: runner.attempt,\n error,\n willRetry: false,\n });\n runner.reject(error);\n } finally {\n this.pump();\n this.checkIdle();\n }\n }\n\n /**\n * Schedules a retry attempt following backoff delay,\n * without holding a concurrency slot.\n */\n private scheduleRetry(runner: TaskRunner<unknown>, options?: IScheduleOptions): void {\n const backoffDelay = calculateBackoff(runner.attempt - 1, options?.retry);\n\n if (backoffDelay === 0) {\n runner.onCancel = () => {\n const index = this.queue.indexOf(runner);\n if (index !== -1) {\n this.queue.splice(index, 1);\n if (runner.totalTimedOut || runner.state === ETaskState.TIMED_OUT) {\n this.timedOutTasks++;\n this.emitter.emit(\"task:timeout\", {\n taskId: runner.taskId,\n timeoutMs: options?.totalTimeoutMs ?? runner.timeoutMs,\n });\n } else {\n this.cancelledTasks++;\n this.emitter.emit(\"task:cancel\", {\n taskId: runner.taskId,\n reason: \"Task cancelled while queued\",\n });\n }\n this.checkIdle();\n }\n };\n this.insertIntoQueue(runner);\n this.pump();\n return;\n }\n\n const retryEntry: IRetryEntry = {\n runner,\n timerId: setTimeout(() => {\n this.retryEntries.delete(retryEntry);\n if (runner.state === ETaskState.CANCELLED || runner.state === ETaskState.TIMED_OUT) {\n return;\n }\n\n runner.onCancel = () => {\n const index = this.queue.indexOf(runner);\n if (index !== -1) {\n this.queue.splice(index, 1);\n if (runner.totalTimedOut || runner.state === ETaskState.TIMED_OUT) {\n this.timedOutTasks++;\n this.emitter.emit(\"task:timeout\", {\n taskId: runner.taskId,\n timeoutMs: options?.totalTimeoutMs ?? runner.timeoutMs,\n });\n } else {\n this.cancelledTasks++;\n this.emitter.emit(\"task:cancel\", {\n taskId: runner.taskId,\n reason: \"Task cancelled while queued\",\n });\n }\n this.checkIdle();\n }\n };\n\n this.insertIntoQueue(runner);\n this.pump();\n }, backoffDelay),\n };\n\n this.retryEntries.add(retryEntry);\n\n runner.onCancel = () => {\n if (this.retryEntries.has(retryEntry)) {\n clearTimeout(retryEntry.timerId);\n this.retryEntries.delete(retryEntry);\n if (runner.totalTimedOut || runner.state === ETaskState.TIMED_OUT) {\n this.timedOutTasks++;\n this.emitter.emit(\"task:timeout\", {\n taskId: runner.taskId,\n timeoutMs: options?.totalTimeoutMs ?? runner.timeoutMs,\n });\n } else {\n this.cancelledTasks++;\n this.emitter.emit(\"task:cancel\", {\n taskId: runner.taskId,\n reason: \"Task cancelled during retry backoff\",\n });\n }\n this.checkIdle();\n }\n };\n }\n\n /**\n * Checks whether the scheduler has transitioned to idle and notifies listeners/resolvers.\n */\n public checkIdle(): void {\n if (this.isIdle()) {\n if (this.idleResolvers.size > 0) {\n for (const resolve of this.idleResolvers) {\n resolve();\n }\n this.idleResolvers.clear();\n }\n this.emitter.emit(\"idle\", { timestamp: Date.now() });\n }\n }\n\n /**\n * Checks whether the scheduler is currently idle (no active runners and no pending tasks).\n *\n * @returns True if completely idle, false otherwise.\n */\n public isIdle(): boolean {\n return (\n this.activeRunners.size === 0 &&\n this.queue.length === 0 &&\n this.delayedEntries.size === 0 &&\n this.idleEntries.size === 0 &&\n this.retryEntries.size === 0 &&\n this.debounceCoordinator.size === 0 &&\n this.throttleCoordinator.size === 0\n );\n }\n\n /**\n * Returns a promise that resolves once the scheduler has processed all tasks and is idle.\n *\n * @returns Promise resolving when idle.\n */\n public onIdle(): Promise<void> {\n if (this.isIdle()) {\n return Promise.resolve();\n }\n return new Promise<void>((resolve) => {\n this.idleResolvers.add(resolve);\n });\n }\n\n /**\n * Clears all pending and waiting tasks from the scheduler, cancelling their runners.\n * Active tasks currently in flight will continue to run to completion or abort via signal.\n */\n public clear(): void {\n while (this.queue.length > 0) {\n const runner = this.queue.shift();\n if (runner && runner.state !== ETaskState.CANCELLED && runner.state !== ETaskState.TIMED_OUT) {\n runner.cancel(\"Scheduler cleared\");\n this.cancelledTasks++;\n this.emitter.emit(\"task:cancel\", { taskId: runner.taskId, reason: \"Scheduler cleared\" });\n }\n }\n\n for (const entry of this.delayedEntries.values()) {\n clearTimeout(entry.timerId);\n entry.runner.cancel(\"Scheduler cleared\");\n this.cancelledTasks++;\n this.emitter.emit(\"task:cancel\", { taskId: entry.runner.taskId, reason: \"Scheduler cleared\" });\n }\n this.delayedEntries.clear();\n\n for (const entry of this.idleEntries.values()) {\n entry.handle.cancel();\n entry.runner.cancel(\"Scheduler cleared\");\n this.cancelledTasks++;\n this.emitter.emit(\"task:cancel\", { taskId: entry.runner.taskId, reason: \"Scheduler cleared\" });\n }\n this.idleEntries.clear();\n\n for (const entry of this.retryEntries.values()) {\n clearTimeout(entry.timerId);\n entry.runner.cancel(\"Scheduler cleared\");\n this.cancelledTasks++;\n this.emitter.emit(\"task:cancel\", { taskId: entry.runner.taskId, reason: \"Scheduler cleared\" });\n }\n this.retryEntries.clear();\n\n this.debounceCoordinator.clear();\n this.throttleCoordinator.clear();\n\n if (this.rateLimitTimer !== undefined) {\n clearTimeout(this.rateLimitTimer);\n this.rateLimitTimer = undefined;\n }\n\n this.checkIdle();\n }\n\n /**\n * Returns telemetry snapshot for the scheduler.\n *\n * @returns Frozen snapshot of current task metrics.\n */\n public getStats(): IAhkoStats {\n return Object.freeze({\n activeTasks: this.activeRunners.size,\n pendingTasks:\n this.queue.length +\n this.delayedEntries.size +\n this.idleEntries.size +\n this.retryEntries.size +\n this.debounceCoordinator.size +\n this.throttleCoordinator.size,\n completedTasks: this.completedTasks,\n failedTasks: this.failedTasks,\n cancelledTasks: this.cancelledTasks,\n timedOutTasks: this.timedOutTasks,\n retriedTasks: this.retriedTasks,\n totalDispatched: this.totalDispatched,\n capacity: this.concurrency,\n isPaused: this._isPaused,\n circuitState: this.circuitBreakerCoordinator?.state,\n });\n }\n}\n","import { AhkoCancellationError } from \"../errors/cancellation.error.js\";\nimport { AhkoTimeoutError } from \"../errors/timeout.error.js\";\nimport type { ITaskContext } from \"../models/context.model.js\";\nimport type { IRetryOptions } from \"../models/retry.model.js\";\nimport { ETaskState } from \"../models/state.model.js\";\nimport type { ITask } from \"../models/task.model.js\";\n\nlet taskIdCounter = 0;\n\n/**\n * Internal task lifecycle manager responsible for execution, state transitions,\n * AbortSignal coordination, timeout enforcement, and deterministic resource cleanup.\n *\n * @template T - The return type produced by the underlying task.\n */\nexport class TaskRunner<T> {\n /** Unique task identifier */\n public readonly taskId: string;\n\n /** Current lifecycle state */\n private _state: ETaskState = ETaskState.PENDING;\n\n /** Internal AbortController whose signal is passed to the task context */\n private abortController: AbortController;\n\n /** The user task function to execute */\n private readonly task: ITask<T>;\n\n /** User-supplied AbortSignal for external cancellation */\n public readonly externalSignal?: AbortSignal;\n\n /** Maximum execution duration allowed in milliseconds */\n public readonly timeoutMs?: number;\n\n /** Active timeout timer identifier */\n private timeoutTimerId?: ReturnType<typeof setTimeout>;\n\n /** Abort event listener reference for clean detachment */\n private readonly abortListener?: () => void;\n\n /** Promise resolve handler */\n private resolvePromise!: (value: T | PromiseLike<T>) => void;\n\n /** Promise reject handler */\n private rejectPromise!: (reason?: unknown) => void;\n\n /** Deferred promise exposed to the caller */\n public readonly promise: Promise<T>;\n\n /** Callback invoked when runner is cancelled while pending */\n public onCancel?: (runner: TaskRunner<T>) => void;\n\n /** Current execution attempt count (1-indexed) */\n public attempt = 1;\n\n /** Duration of the most recent execution attempt in milliseconds */\n public lastDurationMs = 0;\n\n /**\n * Creates a new TaskRunner instance.\n *\n * @param task - The asynchronous work unit to run.\n * @param externalSignal - Optional external AbortSignal to propagate.\n * @param timeoutMs - Optional maximum execution time in milliseconds.\n */\n constructor(task: ITask<T>, externalSignal?: AbortSignal, timeoutMs?: number) {\n this.taskId = `task_${Date.now().toString(36)}_${(++taskIdCounter).toString(36)}_${Math.random().toString(36).slice(2, 6)}`;\n this.task = task;\n this.externalSignal = externalSignal;\n this.timeoutMs = timeoutMs;\n this.abortController = new AbortController();\n\n this.promise = new Promise<T>((resolve, reject) => {\n this.resolvePromise = resolve;\n this.rejectPromise = reject;\n });\n\n if (this.externalSignal) {\n if (this.externalSignal.aborted) {\n this._state = ETaskState.CANCELLED;\n const reason = this.externalSignal.reason;\n const cancelError = new AhkoCancellationError(\n typeof reason === \"string\" ? reason : \"Task was cancelled prior to execution\",\n { cause: reason instanceof Error ? reason : undefined }\n );\n this.abortController.abort(cancelError);\n this.rejectPromise(cancelError);\n } else {\n this.abortListener = () => {\n this.handleExternalAbort();\n };\n this.externalSignal.addEventListener(\"abort\", this.abortListener, { once: true });\n }\n }\n }\n\n /** Flag indicating if runner was aborted by an overall total timeout deadline */\n public totalTimedOut = false;\n\n /**\n * Gets the current lifecycle state of the task.\n */\n public get state(): ETaskState {\n return this._state;\n }\n\n /**\n * Resolves the deferred promise.\n *\n * @param value - Value to resolve with.\n */\n public resolve(value: T): void {\n this.cleanup();\n this.resolvePromise(value);\n }\n\n /**\n * Rejects the deferred promise.\n *\n * @param reason - Reason to reject with.\n */\n public reject(reason: unknown): void {\n this.cleanup();\n this.rejectPromise(reason);\n }\n\n /**\n * Evaluates if the task should be retried following an execution failure or timeout.\n *\n * @param error - The error encountered during the attempt.\n * @param retryOptions - Configured retry policy.\n * @returns A promise resolving to true if retry should proceed, false otherwise.\n */\n public async canRetry(error: unknown, retryOptions?: IRetryOptions): Promise<boolean> {\n if (\n this.totalTimedOut ||\n this._state === ETaskState.CANCELLED ||\n (this.externalSignal?.aborted ?? false)\n ) {\n return false;\n }\n\n if (!retryOptions || typeof retryOptions.attempts !== \"number\") {\n return false;\n }\n\n if (this.attempt >= retryOptions.attempts) {\n return false;\n }\n\n if (typeof retryOptions.shouldRetry === \"function\") {\n try {\n const allowed = await retryOptions.shouldRetry(error, this.attempt);\n if (!allowed) {\n return false;\n }\n } catch {\n return false;\n }\n }\n\n this.attempt++;\n this._state = ETaskState.PENDING;\n this.abortController = new AbortController();\n return true;\n }\n\n /**\n * Executes the task within an allocated concurrency slot.\n *\n * @returns A promise resolving to the task result or rejecting on failure/cancellation/timeout.\n */\n public async run(): Promise<T> {\n if (this._state === ETaskState.CANCELLED) {\n throw new AhkoCancellationError(\"Task was cancelled prior to execution\");\n }\n\n this._state = ETaskState.RUNNING;\n\n const context: ITaskContext = {\n signal: this.abortController.signal,\n taskId: this.taskId,\n };\n\n let abortListener: (() => void) | undefined;\n\n const abortPromise = new Promise<never>((_, reject) => {\n abortListener = () => {\n const reason = this.abortController.signal.reason;\n if (this._state === ETaskState.TIMED_OUT || reason instanceof AhkoTimeoutError) {\n this._state = ETaskState.TIMED_OUT;\n reject(\n reason instanceof AhkoTimeoutError\n ? reason\n : new AhkoTimeoutError(\n `Task execution timed out after ${this.timeoutMs}ms`,\n { timeoutMs: this.timeoutMs }\n )\n );\n } else {\n reject(\n new AhkoCancellationError(\"Task was cancelled during execution\", {\n cause: reason instanceof Error ? reason : undefined,\n })\n );\n }\n };\n this.abortController.signal.addEventListener(\"abort\", abortListener, { once: true });\n });\n\n let timeoutPromise: Promise<never> | undefined;\n if (this.timeoutMs !== undefined) {\n timeoutPromise = new Promise<never>((_, reject) => {\n this.timeoutTimerId = setTimeout(() => {\n if (this._state !== ETaskState.RUNNING) {\n return;\n }\n this._state = ETaskState.TIMED_OUT;\n const timeoutError = new AhkoTimeoutError(\n `Task execution timed out after ${this.timeoutMs}ms`,\n { timeoutMs: this.timeoutMs }\n );\n this.abortController.abort(timeoutError);\n reject(timeoutError);\n }, this.timeoutMs);\n });\n }\n\n let taskExecutionPromise: Promise<T>;\n try {\n taskExecutionPromise = Promise.resolve(this.task(context));\n } catch (syncError) {\n taskExecutionPromise = Promise.reject(syncError);\n }\n\n // Suppress unhandled rejection in background if task finishes or fails after timeout/cancellation\n taskExecutionPromise.catch(() => {});\n abortPromise.catch(() => {});\n timeoutPromise?.catch(() => {});\n\n const racePromises: Array<Promise<T | never>> = [\n taskExecutionPromise,\n abortPromise,\n ];\n if (timeoutPromise) {\n racePromises.push(timeoutPromise);\n }\n\n const startTime = Date.now();\n\n try {\n const result = await Promise.race(racePromises);\n this.clearTimeoutTimer();\n this.lastDurationMs = Math.max(0, Date.now() - startTime);\n if (abortListener) {\n this.abortController.signal.removeEventListener(\"abort\", abortListener);\n }\n\n if ((this._state as ETaskState) === ETaskState.TIMED_OUT) {\n throw new AhkoTimeoutError(\n `Task execution timed out after ${this.timeoutMs}ms`,\n { timeoutMs: this.timeoutMs }\n );\n }\n\n if ((this._state as ETaskState) === ETaskState.CANCELLED) {\n throw new AhkoCancellationError(\"Task was cancelled during execution\");\n }\n\n this._state = ETaskState.COMPLETED;\n return result;\n } catch (error) {\n this.clearTimeoutTimer();\n this.lastDurationMs = Math.max(0, Date.now() - startTime);\n if (abortListener) {\n this.abortController.signal.removeEventListener(\"abort\", abortListener);\n }\n\n if ((this._state as ETaskState) === ETaskState.TIMED_OUT || error instanceof AhkoTimeoutError) {\n this._state = ETaskState.TIMED_OUT;\n if (error instanceof AhkoTimeoutError) {\n throw error;\n }\n throw new AhkoTimeoutError(\n `Task execution timed out after ${this.timeoutMs}ms`,\n {\n timeoutMs: this.timeoutMs,\n cause: error instanceof Error ? error : undefined,\n }\n );\n }\n\n const isCancelled =\n (this._state as ETaskState) === ETaskState.CANCELLED ||\n this.abortController.signal.aborted ||\n (this.externalSignal?.aborted ?? false);\n\n if (isCancelled) {\n this._state = ETaskState.CANCELLED;\n if (error instanceof AhkoCancellationError) {\n throw error;\n }\n throw new AhkoCancellationError(\"Task was cancelled during execution\", {\n cause: error instanceof Error ? error : undefined,\n });\n }\n\n this._state = ETaskState.FAILED;\n throw error;\n }\n }\n\n /**\n * Clears the active timeout timer.\n */\n private clearTimeoutTimer(): void {\n if (this.timeoutTimerId !== undefined) {\n clearTimeout(this.timeoutTimerId);\n this.timeoutTimerId = undefined;\n }\n }\n\n /**\n * Cancels the task, aborting pending or running execution.\n *\n * @param reason - Optional cancellation reason.\n */\n public cancel(reason?: unknown): void {\n if (\n this._state === ETaskState.COMPLETED ||\n this._state === ETaskState.FAILED ||\n this._state === ETaskState.CANCELLED ||\n this._state === ETaskState.TIMED_OUT\n ) {\n return;\n }\n\n const wasPending = this._state === ETaskState.PENDING;\n this._state = ETaskState.CANCELLED;\n this.clearTimeoutTimer();\n this.abortController.abort(reason);\n this.cleanup();\n\n if (wasPending) {\n const cancellationError = new AhkoCancellationError(\n typeof reason === \"string\" ? reason : \"Task was cancelled prior to execution\",\n { cause: reason instanceof Error ? reason : undefined }\n );\n this.rejectPromise(cancellationError);\n this.onCancel?.(this);\n }\n }\n\n /**\n * Times out the task, aborting pending or running execution with AhkoTimeoutError.\n *\n * @param timeoutMs - Timeout duration in milliseconds.\n * @param message - Optional custom timeout message.\n */\n public timeout(timeoutMs: number, message?: string): void {\n if (\n this._state === ETaskState.COMPLETED ||\n this._state === ETaskState.FAILED ||\n this._state === ETaskState.CANCELLED ||\n this._state === ETaskState.TIMED_OUT\n ) {\n return;\n }\n\n const wasPending = this._state === ETaskState.PENDING;\n this._state = ETaskState.TIMED_OUT;\n this.totalTimedOut = true;\n this.clearTimeoutTimer();\n const timeoutError = new AhkoTimeoutError(\n message ?? `Task execution timed out after ${timeoutMs}ms`,\n { timeoutMs }\n );\n this.abortController.abort(timeoutError);\n this.cleanup();\n\n if (wasPending) {\n this.rejectPromise(timeoutError);\n this.onCancel?.(this);\n }\n }\n\n /**\n * Handles external AbortSignal trigger.\n */\n private handleExternalAbort(): void {\n this.cancel(this.externalSignal?.reason);\n }\n\n /**\n * Detaches event listeners from external signal to guarantee memory safety.\n */\n public cleanup(): void {\n this.clearTimeoutTimer();\n if (this.externalSignal && this.abortListener) {\n this.externalSignal.removeEventListener(\"abort\", this.abortListener);\n }\n }\n}\n","import { AhkoConfigurationError } from \"./errors/configuration.error.js\";\nimport {\n getActiveConfig,\n getProfileConfig,\n loadConfig,\n loadConfigFile,\n resetConfig,\n} from \"./config/config-loader.js\";\nimport type { ECircuitState } from \"./models/circuit-breaker.model.js\";\nimport type { IAhkoFileConfig, IAhkoProfileConfig } from \"./models/config.model.js\";\nimport type { TAhkoEventName, TAhkoEventHandler, TAhkoUnsubscribe } from \"./models/events.model.js\";\nimport type { IAhkoOptions, IScheduleOptions } from \"./models/options.model.js\";\nimport type { IAhkoStats } from \"./models/stats.model.js\";\nimport { EScheduleStrategy } from \"./models/strategy.model.js\";\nimport type { ITask } from \"./models/task.model.js\";\nimport type { CircuitBreakerCoordinator } from \"./scheduler/circuit-breaker.js\";\nimport { TaskQueue } from \"./scheduler/task-queue.js\";\nimport { TaskRunner } from \"./scheduler/task-runner.js\";\n\n/**\n * Ahko — Low-energy asynchronous task scheduler.\n *\n * Coordinates execution timing, enforces concurrency limits, manages priorities,\n * provides circuit-breaker stability, supports pause/resume flow control,\n * and cooperates natively with AbortSignal cancellation.\n *\n * @example\n * ```typescript\n * import { Ahko } from \"@mrjacket/ahko\";\n *\n * const ahko = new Ahko({ concurrency: 2 });\n *\n * const result = await ahko.schedule(async ({ signal, taskId }) => {\n * const res = await fetch(\"https://api.example.com\", { signal });\n * return res.json();\n * });\n * ```\n */\nexport class Ahko {\n /** Internal queue and concurrency manager */\n private readonly queue: TaskQueue;\n\n /** Default schedule options inherited from profile if configured */\n private readonly defaultScheduleOptions?: Partial<IScheduleOptions>;\n\n /**\n * Programmatically loads a declarative configuration into memory.\n * Works universally across Node.js, browsers, and edge runtimes.\n *\n * @param config - File configuration object containing default and named profiles.\n */\n public static loadConfig(config: IAhkoFileConfig): void {\n loadConfig(config);\n }\n\n /**\n * Asynchronously loads a configuration file from disk (Node.js).\n *\n * @param filePath - Path to configuration file (default: \"config.ahko.json\").\n */\n public static async loadConfigFile(filePath?: string): Promise<IAhkoFileConfig | undefined> {\n return loadConfigFile(filePath);\n }\n\n /**\n * Resets the active declarative configuration.\n */\n public static resetConfig(): void {\n resetConfig();\n }\n\n /**\n * Retrieves the currently active declarative configuration.\n */\n public static getActiveConfig(): IAhkoFileConfig | undefined {\n return getActiveConfig();\n }\n\n /**\n * Instantiates an Ahko scheduler initialized with settings from a declarative profile.\n *\n * @param profileName - Optional name of the profile (e.g. \"api\", \"background\").\n * @param overrides - Optional scheduler options overriding profile values.\n * @returns A new configured Ahko instance.\n */\n public static fromProfile(profileName?: string, overrides?: IAhkoOptions): Ahko {\n const profile = getProfileConfig(profileName);\n return new Ahko({\n ...profile,\n ...overrides,\n circuitBreaker: overrides?.circuitBreaker ?? profile?.circuitBreaker,\n });\n }\n\n /**\n * Initializes a new Ahko scheduler instance.\n *\n * @param options - Optional scheduler configuration.\n * @throws {AhkoConfigurationError} If concurrency is invalid (less than 1 or NaN).\n *\n * @example\n * ```typescript\n * const ahko = new Ahko({ concurrency: 4 });\n * ```\n */\n constructor(options?: IAhkoOptions) {\n const profile = options?.profile ? getProfileConfig(options.profile) : getProfileConfig();\n\n const mergedOptions: IAhkoOptions = {\n ...profile,\n ...options,\n circuitBreaker: options?.circuitBreaker ?? profile?.circuitBreaker,\n };\n\n if (profile) {\n this.defaultScheduleOptions = {\n priority: profile.priority,\n retry: profile.retry,\n timeoutMs: profile.timeoutMs,\n totalTimeoutMs: profile.totalTimeoutMs,\n };\n }\n\n this.queue = new TaskQueue(\n mergedOptions.concurrency,\n mergedOptions.minIntervalMs,\n mergedOptions.circuitBreaker\n );\n }\n\n /**\n * Pauses scheduler dispatch. In-flight tasks run to completion, but pending tasks remain queued.\n */\n public pause(): void {\n this.queue.pause();\n }\n\n /**\n * Resumes scheduler dispatch, immediately executing waiting tasks up to available concurrency.\n */\n public resume(): void {\n this.queue.resume();\n }\n\n /**\n * Checks whether the scheduler is currently paused.\n */\n public isPaused(): boolean {\n return this.queue.isPaused();\n }\n\n /**\n * Current circuit breaker state if circuit breaker protection is configured.\n */\n public get circuitState(): ECircuitState | undefined {\n return this.queue.circuitBreakerCoordinator?.state;\n }\n\n /**\n * Access to the underlying circuit breaker coordinator instance if configured.\n */\n public get circuitBreaker(): CircuitBreakerCoordinator | undefined {\n return this.queue.circuitBreakerCoordinator;\n }\n\n /**\n * Wraps an async function so every execution is automatically routed through this Ahko scheduler.\n *\n * @template TArgs - Parameter types of the wrapped function.\n * @template TReturn - Return type of the wrapped function.\n * @param fn - The function to wrap.\n * @param options - Optional scheduling options applied to every wrapped call.\n * @returns A wrapped function returning a Promise.\n *\n * @example\n * ```typescript\n * const fetchUser = ahko.wrap(async (id: string) => api.getUser(id), { priority: \"high\" });\n * const user = await fetchUser(\"usr_123\");\n * ```\n */\n public wrap<TArgs extends unknown[], TReturn>(\n fn: (...args: TArgs) => Promise<TReturn> | TReturn,\n options?: IScheduleOptions\n ): (...args: TArgs) => Promise<TReturn> {\n if (typeof fn !== \"function\") {\n throw new AhkoConfigurationError(\"Target to wrap must be a valid function.\");\n }\n return (...args: TArgs) => {\n return this.schedule(() => fn(...args), options);\n };\n }\n\n /**\n * Schedules a task for execution with full return type inference.\n *\n * @template T - Inferred return type of the task.\n * @param task - Asynchronous or synchronous task function accepting an {@link ITaskContext}.\n * @param options - Task-specific scheduling options such as strategy, priority, delay, and cancellation signal.\n * @returns A promise that resolves with the task's return value.\n *\n * @throws {AhkoConfigurationError} If the task is not a function or options are invalid.\n * @throws {AhkoCancellationError} If the task is cancelled prior to or during execution.\n * @throws {AhkoTimeoutError} If task execution exceeds timeoutMs or totalTimeoutMs.\n * @throws {AhkoCircuitBreakerOpenError} If the circuit breaker is OPEN and rejects the execution.\n *\n * @example\n * ```typescript\n * // Immediate execution (subject to concurrency)\n * const count = await ahko.schedule(async () => 42);\n *\n * // High priority task\n * await ahko.schedule(doUrgentWork, { priority: \"high\" });\n * ```\n */\n public schedule<T>(task: ITask<T>, options?: IScheduleOptions): Promise<T> {\n if (typeof task !== \"function\") {\n throw new AhkoConfigurationError(\"Task must be a valid function.\");\n }\n\n const mergedOptions: IScheduleOptions = {\n ...this.defaultScheduleOptions,\n ...options,\n };\n\n const strategy = mergedOptions.strategy ?? EScheduleStrategy.IMMEDIATE;\n\n if (strategy === EScheduleStrategy.DEBOUNCE) {\n if (!mergedOptions.key || (typeof mergedOptions.key !== \"string\" && typeof mergedOptions.key !== \"symbol\")) {\n throw new AhkoConfigurationError(\n `Strategy \"debounce\" requires a valid \"key\" of type string or symbol.`\n );\n }\n const waitMs = mergedOptions.waitMs ?? mergedOptions.delay;\n if (typeof waitMs !== \"number\" || Number.isNaN(waitMs) || !Number.isFinite(waitMs) || waitMs < 0) {\n throw new AhkoConfigurationError(\n `Strategy \"debounce\" requires a non-negative finite \"waitMs\" or \"delay\" in milliseconds.`\n );\n }\n return this.queue.debounceCoordinator.schedule(\n mergedOptions.key,\n task,\n waitMs,\n mergedOptions,\n (t, opts) => this.schedule(t, { ...opts, strategy: EScheduleStrategy.IMMEDIATE })\n );\n }\n\n if (strategy === EScheduleStrategy.THROTTLE) {\n if (!mergedOptions.key || (typeof mergedOptions.key !== \"string\" && typeof mergedOptions.key !== \"symbol\")) {\n throw new AhkoConfigurationError(\n `Strategy \"throttle\" requires a valid \"key\" of type string or symbol.`\n );\n }\n const waitMs = mergedOptions.waitMs ?? mergedOptions.delay;\n if (typeof waitMs !== \"number\" || Number.isNaN(waitMs) || !Number.isFinite(waitMs) || waitMs < 0) {\n throw new AhkoConfigurationError(\n `Strategy \"throttle\" requires a non-negative finite \"waitMs\" or \"delay\" in milliseconds.`\n );\n }\n return this.queue.throttleCoordinator.schedule(\n mergedOptions.key,\n task,\n waitMs,\n mergedOptions,\n (t, opts) => this.schedule(t, { ...opts, strategy: EScheduleStrategy.IMMEDIATE })\n );\n }\n\n const runner = new TaskRunner<T>(task, mergedOptions.signal, mergedOptions.timeoutMs);\n return this.queue.enqueue(runner, mergedOptions);\n }\n\n /**\n * Convenience method to schedule a task during platform idle opportunities.\n *\n * Equivalent to calling `schedule(task, { ...options, strategy: \"idle\" })`.\n * In browsers, uses `requestIdleCallback` when available.\n * In Node.js, uses `setImmediate`.\n * Falls back to `setTimeout(..., 0)` if neither is available.\n *\n * @template T - Inferred return type of the task.\n * @param task - Task function to run when idle.\n * @param options - Scheduling options (excluding strategy).\n * @returns A promise resolving to the task's return value.\n *\n * @throws {AhkoConfigurationError} If the task is not a function or options are invalid.\n * @throws {AhkoCancellationError} If the task is cancelled prior to or during execution.\n */\n public idle<T>(\n task: ITask<T>,\n options?: Omit<IScheduleOptions, \"strategy\">\n ): Promise<T> {\n return this.schedule(task, {\n ...options,\n strategy: EScheduleStrategy.IDLE,\n });\n }\n\n /**\n * Convenience method to schedule a debounced task with key-based Promise coalescing.\n *\n * @template T - Inferred return type of the task.\n * @param key - Explicit identity key.\n * @param task - Work to execute once calls stop arriving.\n * @param waitMs - Quiet window duration in milliseconds.\n * @param options - Additional schedule options.\n * @returns Shared promise resolving with the final execution outcome.\n */\n public debounce<T>(\n key: string | symbol,\n task: ITask<T>,\n waitMs: number,\n options?: Omit<IScheduleOptions, \"strategy\" | \"key\" | \"waitMs\">\n ): Promise<T> {\n return this.schedule(task, {\n ...options,\n strategy: EScheduleStrategy.DEBOUNCE,\n key,\n waitMs,\n });\n }\n\n /**\n * Convenience method to schedule a throttled task with leading execution and coalesced trailing run.\n *\n * @template T - Inferred return type of the task.\n * @param key - Explicit identity key.\n * @param task - Work to execute.\n * @param waitMs - Throttle interval duration in milliseconds.\n * @param options - Additional schedule options.\n * @returns Promise resolving with the leading or coalesced trailing result.\n */\n public throttle<T>(\n key: string | symbol,\n task: ITask<T>,\n waitMs: number,\n options?: Omit<IScheduleOptions, \"strategy\" | \"key\" | \"waitMs\">\n ): Promise<T> {\n return this.schedule(task, {\n ...options,\n strategy: EScheduleStrategy.THROTTLE,\n key,\n waitMs,\n });\n }\n\n /**\n * Retrieves real-time telemetry metrics from the scheduler.\n *\n * @returns An {@link IAhkoStats} snapshot of active, pending, completed, failed, cancelled, timed out tasks, pause status, and circuit state.\n *\n * @example\n * ```typescript\n * const stats = ahko.stats();\n * console.log(`Active: ${stats.activeTasks}, Pending: ${stats.pendingTasks}, Paused: ${stats.isPaused}`);\n * ```\n */\n public stats(): IAhkoStats {\n return this.queue.getStats();\n }\n\n /**\n * Subscribes to a scheduler lifecycle event.\n *\n * @param event - Event name to listen for.\n * @param handler - Callback function invoked when the event is emitted.\n * @returns Unsubscribe function to remove the listener.\n *\n * @example\n * ```typescript\n * const unsubscribe = ahko.on(\"task:start\", ({ taskId, attempt }) => {\n * console.log(`Task ${taskId} started attempt ${attempt}`);\n * });\n * ```\n */\n public on<K extends TAhkoEventName>(event: K, handler: TAhkoEventHandler<K>): TAhkoUnsubscribe {\n return this.queue.emitter.on(event, handler);\n }\n\n /**\n * Unsubscribes an event listener from a scheduler lifecycle event.\n *\n * @param event - Event name.\n * @param handler - The exact listener callback to remove.\n */\n public off<K extends TAhkoEventName>(event: K, handler: TAhkoEventHandler<K>): void {\n this.queue.emitter.off(event, handler);\n }\n\n /**\n * Checks whether the scheduler is currently idle (no active runners and no pending tasks).\n *\n * @returns True if completely idle, false otherwise.\n */\n public isIdle(): boolean {\n return this.queue.isIdle();\n }\n\n /**\n * Returns a promise that resolves once the scheduler has completed all tasks and is idle.\n *\n * @returns Promise resolving when the scheduler is idle.\n *\n * @example\n * ```typescript\n * ahko.schedule(doWork);\n * await ahko.onIdle();\n * console.log(\"All work finished!\");\n * ```\n */\n public onIdle(): Promise<void> {\n return this.queue.onIdle();\n }\n\n /**\n * Clears all pending, delayed, and throttled/debounced tasks from the scheduler.\n * In-flight active tasks will continue executing to completion or abort via signal.\n */\n public clear(): void {\n this.queue.clear();\n }\n\n /**\n * Returns the delightful Ahko mascot battery telemetry status.\n *\n * Low energy, completely chill.\n */\n public battery(): { level: number; chill: boolean; status: string; quote: string } {\n return {\n level: 3,\n chill: true,\n status: \"low-energy\",\n quote: \"Mwee... my battery is low, but all your tasks are handled completely chill.\",\n };\n }\n\n /**\n * Delightful alias for `onIdle()`: wait for all tasks to settle chill and relaxed.\n *\n * @returns Promise resolving when all tasks have finished.\n */\n public chill(): Promise<void> {\n return this.onIdle();\n }\n}\n","/**\n * Current version of @mrjacket/ahko package.\n */\nexport const VERSION = \"1.1.0\";\n","import { AhkoError } from \"./ahko.error.js\";\n\n/**\n * Thrown when an internal queue invariant is violated or queue limits are breached.\n */\nexport class AhkoQueueError extends AhkoError {\n /**\n * Creates a new AhkoQueueError.\n *\n * @param message - Explanation of the queue failure.\n * @param options - Standard Error options including cause.\n */\n constructor(message: string, options?: ErrorOptions) {\n super(message, options);\n this.name = \"AhkoQueueError\";\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n","/**\n * Result of combining multiple AbortSignals.\n */\nexport interface ICombinedSignal {\n /**\n * The unified AbortSignal that aborts when any source signal aborts.\n */\n readonly signal: AbortSignal;\n\n /**\n * Detaches all registered event listeners from source signals to prevent memory leaks.\n */\n cleanup: () => void;\n}\n\n/**\n * Combines multiple AbortSignals into a single coordinated AbortSignal with deterministic cleanup.\n *\n * @param signals - Array of source AbortSignals (undefined entries are ignored).\n * @returns A unified signal interface with explicit cleanup callback.\n */\nexport function combineSignals(\n signals: ReadonlyArray<AbortSignal | undefined>\n): ICombinedSignal {\n const activeSignals = signals.filter(\n (signal): signal is AbortSignal => signal !== undefined\n );\n\n if (activeSignals.length === 0) {\n const controller = new AbortController();\n return {\n signal: controller.signal,\n cleanup: () => {},\n };\n }\n\n // Check if any source signal is already aborted\n const alreadyAborted = activeSignals.find((s) => s.aborted);\n if (alreadyAborted) {\n const controller = new AbortController();\n controller.abort(alreadyAborted.reason);\n return {\n signal: controller.signal,\n cleanup: () => {},\n };\n }\n\n if (activeSignals.length === 1) {\n return {\n signal: activeSignals[0],\n cleanup: () => {},\n };\n }\n\n const controller = new AbortController();\n const cleanupFns: Array<() => void> = [];\n\n const onAbort = (event: Event): void => {\n const target = event.target as AbortSignal;\n cleanup();\n controller.abort(target.reason);\n };\n\n for (const sig of activeSignals) {\n sig.addEventListener(\"abort\", onAbort, { once: true });\n cleanupFns.push(() => {\n sig.removeEventListener(\"abort\", onAbort);\n });\n }\n\n const cleanup = (): void => {\n for (const fn of cleanupFns) {\n fn();\n }\n cleanupFns.length = 0;\n };\n\n return {\n signal: controller.signal,\n cleanup,\n };\n}\n"],"mappings":"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","names":["EScheduleStrategy","ETaskState","ECircuitState","controller"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/errors/ahko.error.ts","../src/errors/cancellation.error.ts","../src/errors/configuration.error.ts","../src/config/config-loader.ts","../src/models/strategy.model.ts","../src/errors/circuit-breaker.error.ts","../src/errors/timeout.error.ts","../src/models/priority.model.ts","../src/models/state.model.ts","../src/retry/backoff.ts","../src/scheduler/adaptive-coordinator.ts","../src/models/circuit-breaker.model.ts","../src/scheduler/circuit-breaker.ts","../src/scheduler/debounce-coordinator.ts","../src/scheduler/idle-scheduler.ts","../src/scheduler/throttle-coordinator.ts","../src/events/event-emitter.ts","../src/scheduler/task-queue.ts","../src/scheduler/task-runner.ts","../src/ahko.ts","../src/version.ts","../src/errors/queue.error.ts","../src/scheduler/signal.ts"],"sourcesContent":["export { Ahko } from \"./ahko.js\";\nexport { VERSION } from \"./version.js\";\n\n// Errors\nexport {\n AhkoError,\n AhkoCancellationError,\n AhkoConfigurationError,\n AhkoQueueError,\n AhkoTimeoutError,\n AhkoCircuitBreakerOpenError,\n type IAhkoTimeoutErrorOptions,\n type IAhkoCircuitBreakerErrorOptions,\n} from \"./errors/index.js\";\n\n// Models and interfaces\nexport {\n ETaskState,\n EScheduleStrategy,\n ECircuitState,\n TASK_PRIORITY_WEIGHTS,\n resolvePriorityWeight,\n} from \"./models/index.js\";\n\nexport type {\n ITask,\n ITaskContext,\n IScheduleOptions,\n IAhkoOptions,\n IAhkoStats,\n TScheduleStrategy,\n IRetryOptions,\n TRetryBackoff,\n TRetryPredicate,\n IAhkoEventMap,\n TAhkoEventName,\n TAhkoEventHandler,\n TAhkoUnsubscribe,\n TCircuitState,\n ICircuitBreakerOptions,\n ICircuitBreakerStats,\n TTaskPriority,\n IAhkoFileConfig,\n IAhkoProfileConfig,\n IBatchOptions,\n IBatchMapOptions,\n IAdaptiveConcurrencyOptions,\n IAdaptiveStats,\n} from \"./models/index.js\";\n\n// Config utilities\nexport {\n loadConfig,\n resetConfig,\n loadConfigFile,\n getActiveConfig,\n getProfileConfig,\n} from \"./config/index.js\";\n\n// Circuit Breaker & Adaptive Coordinators\nexport { CircuitBreakerCoordinator } from \"./scheduler/circuit-breaker.js\";\nexport { AdaptiveCoordinator } from \"./scheduler/adaptive-coordinator.js\";\n\n// Retry utilities\nexport {\n calculateBackoff,\n DEFAULT_BASE_DELAY,\n DEFAULT_MAX_DELAY,\n} from \"./retry/index.js\";\n\n// Signal utilities\nexport {\n combineSignals,\n type ICombinedSignal,\n} from \"./scheduler/signal.js\";\n","/**\n * Base error class for all errors originating from the Ahko scheduler.\n */\nexport class AhkoError extends Error {\n /**\n * Creates a new AhkoError instance.\n *\n * @param message - Descriptive error message.\n * @param options - Standard Error options including cause.\n */\n constructor(message: string, options?: ErrorOptions) {\n super(message, options);\n this.name = \"AhkoError\";\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n","import { AhkoError } from \"./ahko.error.js\";\n\n/**\n * Thrown when a task is cancelled before or during execution.\n */\nexport class AhkoCancellationError extends AhkoError {\n /**\n * Creates a new AhkoCancellationError.\n *\n * @param message - Reason for cancellation.\n * @param options - Standard Error options including cause.\n */\n constructor(message = \"Task was cancelled\", options?: ErrorOptions) {\n super(message, options);\n this.name = \"AhkoCancellationError\";\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n","import { AhkoError } from \"./ahko.error.js\";\n\n/**\n * Thrown when invalid configuration or scheduling options are provided.\n */\nexport class AhkoConfigurationError extends AhkoError {\n /**\n * Creates a new AhkoConfigurationError.\n *\n * @param message - Explanation of the invalid configuration parameter.\n * @param options - Standard Error options including cause.\n */\n constructor(message: string, options?: ErrorOptions) {\n super(message, options);\n this.name = \"AhkoConfigurationError\";\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n","import type { IAhkoFileConfig, IAhkoProfileConfig } from \"../models/config.model.js\";\n\nlet activeConfig: IAhkoFileConfig | undefined;\n\n/**\n * Programmatically loads and activates a declarative configuration.\n * Universal across Node.js, browsers, and edge environments.\n *\n * @param config - Complete configuration object conforming to `IAhkoFileConfig`.\n */\nexport function loadConfig(config: IAhkoFileConfig): void {\n activeConfig = { ...config };\n}\n\n/**\n * Resets the currently active configuration in memory to undefined.\n */\nexport function resetConfig(): void {\n activeConfig = undefined;\n}\n\n/**\n * Asynchronously loads a `config.ahko.json` or custom config file from the filesystem in Node.js.\n * Sets the active configuration in memory upon successful read and parse.\n *\n * @param filePath - Optional relative or absolute path to the configuration file (default: \"config.ahko.json\").\n * @returns The parsed configuration object, or `undefined` if not running in Node.js or if file cannot be read.\n */\nexport async function loadConfigFile(filePath = \"config.ahko.json\"): Promise<IAhkoFileConfig | undefined> {\n if (typeof process === \"undefined\" || !process.versions?.node) {\n return undefined;\n }\n\n try {\n const { readFile } = await import(\"node:fs/promises\");\n const { resolve } = await import(\"node:path\");\n const resolvedPath = resolve(process.cwd(), filePath);\n const content = await readFile(resolvedPath, \"utf-8\");\n const parsed = JSON.parse(content) as IAhkoFileConfig;\n activeConfig = parsed;\n return parsed;\n } catch {\n return undefined;\n }\n}\n\n/**\n * Safely inspects the local filesystem synchronously if running in a Node.js CJS/compatible environment.\n */\nfunction tryAutoDiscoverSync(): void {\n if (activeConfig !== undefined || typeof process === \"undefined\" || !process.versions?.node) {\n return;\n }\n\n try {\n let fs: { existsSync(p: string): boolean; readFileSync(p: string, enc: string): string } | null = null;\n let path: { resolve(...paths: string[]): string } | null = null;\n\n if (typeof (process as unknown as { getBuiltinModule?: (mod: string) => unknown }).getBuiltinModule === \"function\") {\n const getBuiltin = (process as unknown as { getBuiltinModule: (mod: string) => unknown }).getBuiltinModule;\n fs = getBuiltin(\"node:fs\") as typeof fs;\n path = getBuiltin(\"node:path\") as typeof path;\n } else if (typeof require === \"function\") {\n // eslint-disable-next-line @typescript-eslint/no-require-imports\n fs = require(\"node:fs\");\n // eslint-disable-next-line @typescript-eslint/no-require-imports\n path = require(\"node:path\");\n }\n\n if (fs && path) {\n const configPath = path.resolve(process.cwd(), \"config.ahko.json\");\n if (fs.existsSync(configPath)) {\n const raw = fs.readFileSync(configPath, \"utf-8\");\n activeConfig = JSON.parse(raw) as IAhkoFileConfig;\n }\n }\n } catch {\n // Non-critical auto-discovery failure; fallback to programmatic configuration\n }\n}\n\n/**\n * Returns the currently active declarative configuration, attempting auto-discovery if in Node.js.\n */\nexport function getActiveConfig(): IAhkoFileConfig | undefined {\n if (activeConfig === undefined) {\n tryAutoDiscoverSync();\n }\n return activeConfig;\n}\n\n/**\n * Retrieves a specific profile configuration by name, or the default profile if no name is provided.\n *\n * @param profileName - Optional name of the profile (e.g. \"api\", \"background\").\n * @returns The profile configuration if defined, or undefined.\n */\nexport function getProfileConfig(profileName?: string): IAhkoProfileConfig | undefined {\n const config = getActiveConfig();\n if (!config) {\n return undefined;\n }\n\n if (profileName) {\n return config.profiles?.[profileName];\n }\n\n return config.default;\n}\n","/**\n * Fundamental scheduling strategies supported by the Ahko scheduler.\n */\nexport enum EScheduleStrategy {\n /** Execute as soon as a concurrency slot is available */\n IMMEDIATE = \"immediate\",\n /** Delay execution for a designated duration before queuing */\n DELAY = \"delay\",\n /** Execute during platform idle opportunities (requestIdleCallback in browser, setImmediate in Node.js) */\n IDLE = \"idle\",\n /** Enforce maximum execution frequency for tasks sharing the same key */\n THROTTLE = \"throttle\",\n /** Delay execution until calls sharing the same key stop arriving */\n DEBOUNCE = \"debounce\",\n}\n\n/**\n * Union type representing valid scheduling strategy identifiers.\n */\nexport type TScheduleStrategy =\n | EScheduleStrategy\n | \"immediate\"\n | \"delay\"\n | \"idle\"\n | \"throttle\"\n | \"debounce\";\n","import { AhkoError } from \"./ahko.error.js\";\n\n/**\n * Options describing the circuit breaker open state.\n */\nexport interface IAhkoCircuitBreakerErrorOptions {\n /** Time remaining in milliseconds before the circuit attempts half-open trial */\n resetTimeoutMs?: number;\n /** Timestamp when the circuit tripped open */\n trippedAt?: number;\n /** Consecutive failures that caused the trip */\n consecutiveFailures?: number;\n}\n\n/**\n * Thrown when attempting to execute a task while the scheduler's circuit breaker is in OPEN state.\n */\nexport class AhkoCircuitBreakerOpenError extends AhkoError {\n /** Time remaining in milliseconds before trial execution is allowed */\n public readonly resetTimeoutMs?: number;\n\n /** Timestamp when the circuit tripped open */\n public readonly trippedAt?: number;\n\n /** Total consecutive failures that caused the trip */\n public readonly consecutiveFailures?: number;\n\n constructor(\n message = \"Circuit breaker is open. Fast-failing task execution to protect downstream resources.\",\n options?: IAhkoCircuitBreakerErrorOptions\n ) {\n super(message);\n this.name = \"AhkoCircuitBreakerOpenError\";\n this.resetTimeoutMs = options?.resetTimeoutMs;\n this.trippedAt = options?.trippedAt;\n this.consecutiveFailures = options?.consecutiveFailures;\n }\n}\n","import { AhkoError } from \"./ahko.error.js\";\n\n/**\n * Options for constructing an AhkoTimeoutError.\n */\nexport interface IAhkoTimeoutErrorOptions extends ErrorOptions {\n /**\n * The timeout threshold in milliseconds that was exceeded.\n */\n timeoutMs?: number;\n}\n\n/**\n * Thrown when a task exceeds its allotted timeout duration.\n */\nexport class AhkoTimeoutError extends AhkoError {\n /**\n * The timeout threshold in milliseconds that was exceeded, if configured.\n */\n public readonly timeoutMs?: number;\n\n /**\n * Creates a new AhkoTimeoutError.\n *\n * @param message - Explanation of timeout expiry.\n * @param options - Standard Error options including optional timeoutMs and cause.\n */\n constructor(\n message = \"Task execution timed out\",\n options?: IAhkoTimeoutErrorOptions\n ) {\n super(message, options);\n this.name = \"AhkoTimeoutError\";\n this.timeoutMs = options?.timeoutMs;\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n","/**\n * Named priority level or explicit numeric priority for scheduled tasks.\n * Higher numeric values indicate higher execution priority.\n */\nexport type TTaskPriority = \"high\" | \"normal\" | \"low\" | number;\n\n/** Default priority weight mappings */\nexport const TASK_PRIORITY_WEIGHTS = {\n high: 10,\n normal: 0,\n low: -10,\n} as const;\n\n/**\n * Resolves a task priority into a normalized numeric weight.\n *\n * @param priority - Named or numeric priority.\n * @returns Numeric weight (default 0 for normal).\n */\nexport function resolvePriorityWeight(priority?: TTaskPriority): number {\n if (priority === undefined) {\n return TASK_PRIORITY_WEIGHTS.normal;\n }\n if (typeof priority === \"number\") {\n return Number.isFinite(priority) ? priority : TASK_PRIORITY_WEIGHTS.normal;\n }\n if (priority === \"high\") {\n return TASK_PRIORITY_WEIGHTS.high;\n }\n if (priority === \"low\") {\n return TASK_PRIORITY_WEIGHTS.low;\n }\n return TASK_PRIORITY_WEIGHTS.normal;\n}\n","/**\n * Represents the discrete lifecycle states of an Ahko task.\n */\nexport enum ETaskState {\n /** Task has been scheduled and is awaiting execution in queue or timer */\n PENDING = \"pending\",\n /** Task is currently executing within an allocated concurrency slot */\n RUNNING = \"running\",\n /** Task successfully finished execution */\n COMPLETED = \"completed\",\n /** Task execution threw an error or rejected */\n FAILED = \"failed\",\n /** Task was cancelled via AbortSignal before or during execution */\n CANCELLED = \"cancelled\",\n /** Task was terminated because its execution exceeded the timeout */\n TIMED_OUT = \"timed_out\",\n}\n","import type { IRetryOptions } from \"../models/retry.model.js\";\n\n/**\n * Default base delay for backoff calculations in milliseconds.\n */\nexport const DEFAULT_BASE_DELAY = 250;\n\n/**\n * Default maximum delay ceiling for backoff calculations in milliseconds.\n */\nexport const DEFAULT_MAX_DELAY = 10_000;\n\n/**\n * Computes backoff delay in milliseconds for a retry attempt based on configured policy.\n *\n * @param attempt - 1-based index of the attempt that failed (1 for first failure, 2 for second, etc.).\n * @param options - Retry configuration options.\n * @param randomFn - Injectable random generator function (defaults to Math.random) for deterministic testing.\n * @returns Delay duration in milliseconds before next attempt.\n */\nexport function calculateBackoff(\n attempt: number,\n options?: IRetryOptions,\n randomFn: () => number = Math.random\n): number {\n const backoff = options?.backoff ?? \"exponential\";\n\n if (backoff === \"none\") {\n return 0;\n }\n\n const baseDelay =\n typeof options?.baseDelay === \"number\" && !Number.isNaN(options.baseDelay) && options.baseDelay >= 0\n ? options.baseDelay\n : DEFAULT_BASE_DELAY;\n\n const maxDelay =\n typeof options?.maxDelay === \"number\" && !Number.isNaN(options.maxDelay) && options.maxDelay >= baseDelay\n ? options.maxDelay\n : Math.max(DEFAULT_MAX_DELAY, baseDelay);\n\n let calculatedDelay: number;\n\n if (backoff === \"linear\") {\n calculatedDelay = baseDelay * Math.max(1, attempt);\n } else {\n // exponential: baseDelay * 2^(attempt - 1)\n const exponent = Math.max(0, attempt - 1);\n // Prevent 2^exponent overflow\n const factor = exponent > 30 ? 2 ** 30 : 2 ** exponent;\n calculatedDelay = baseDelay * factor;\n }\n\n const cappedDelay = Math.min(calculatedDelay, maxDelay);\n\n if (options?.jitter) {\n // Full jitter: uniformly random between 0 and cappedDelay\n return Math.floor(randomFn() * (cappedDelay + 1));\n }\n\n return Math.floor(cappedDelay);\n}\n","import { AhkoConfigurationError } from \"../errors/configuration.error.js\";\nimport type {\n IAdaptiveConcurrencyOptions,\n IAdaptiveStats,\n} from \"../models/adaptive.model.js\";\n\n/**\n * Controller implementing Additive Increase / Multiplicative Decrease (AIMD)\n * dynamic concurrency adjustment based on real-time task latency metrics.\n */\nexport class AdaptiveCoordinator {\n private _currentConcurrency: number;\n public readonly minConcurrency: number;\n public readonly maxConcurrency: number;\n public readonly targetLatencyMs: number;\n public readonly sampleWindowSize: number;\n public readonly backoffFactor: number;\n\n private recentDurations: number[] = [];\n private lastAverageLatencyMs = 0;\n private readonly onConcurrencyChange: (\n previous: number,\n current: number,\n reason: string\n ) => void;\n\n /**\n * Initializes a new AdaptiveCoordinator instance.\n *\n * @param options - Adaptive concurrency configuration options.\n * @param initialConcurrency - Starting scheduler concurrency limit.\n * @param onConcurrencyChange - Callback invoked when concurrency changes.\n * @throws {AhkoConfigurationError} If options are invalid.\n */\n constructor(\n options: IAdaptiveConcurrencyOptions,\n initialConcurrency: number,\n onConcurrencyChange: (previous: number, current: number, reason: string) => void\n ) {\n if (\n typeof options.targetLatencyMs !== \"number\" ||\n Number.isNaN(options.targetLatencyMs) ||\n !Number.isFinite(options.targetLatencyMs) ||\n options.targetLatencyMs <= 0\n ) {\n throw new AhkoConfigurationError(\n `Invalid targetLatencyMs \"${options.targetLatencyMs}\". targetLatencyMs must be a positive number greater than 0.`\n );\n }\n\n const min = options.minConcurrency ?? 1;\n if (typeof min !== \"number\" || Number.isNaN(min) || min < 1 || !Number.isInteger(min)) {\n throw new AhkoConfigurationError(\n `Invalid minConcurrency \"${min}\". minConcurrency must be an integer greater than or equal to 1.`\n );\n }\n\n const defaultMax = Number.isFinite(initialConcurrency)\n ? Math.max(min, initialConcurrency * 2)\n : Math.max(min, 10);\n const max = options.maxConcurrency ?? defaultMax;\n if (typeof max !== \"number\" || Number.isNaN(max) || max < min || !Number.isInteger(max)) {\n throw new AhkoConfigurationError(\n `Invalid maxConcurrency \"${max}\". maxConcurrency must be an integer greater than or equal to minConcurrency (${min}).`\n );\n }\n\n const windowSize = options.sampleWindowSize ?? 5;\n if (typeof windowSize !== \"number\" || Number.isNaN(windowSize) || windowSize < 1 || !Number.isInteger(windowSize)) {\n throw new AhkoConfigurationError(\n `Invalid sampleWindowSize \"${windowSize}\". sampleWindowSize must be an integer greater than or equal to 1.`\n );\n }\n\n const factor = options.backoffFactor ?? 0.7;\n if (typeof factor !== \"number\" || Number.isNaN(factor) || factor <= 0.1 || factor >= 0.99) {\n throw new AhkoConfigurationError(\n `Invalid backoffFactor \"${factor}\". backoffFactor must be a number between 0.1 and 0.99.`\n );\n }\n\n this.minConcurrency = min;\n this.maxConcurrency = max;\n this.targetLatencyMs = options.targetLatencyMs;\n this.sampleWindowSize = windowSize;\n this.backoffFactor = factor;\n this.onConcurrencyChange = onConcurrencyChange;\n\n const clampedInitial = Number.isFinite(initialConcurrency)\n ? Math.min(Math.max(initialConcurrency, min), max)\n : min;\n this._currentConcurrency = clampedInitial;\n }\n\n /**\n * Current effective concurrency limit dictated by the adaptive controller.\n */\n public get currentConcurrency(): number {\n return this._currentConcurrency;\n }\n\n /**\n * Manually overrides the current concurrency within [minConcurrency, maxConcurrency].\n *\n * @param concurrency - New concurrency limit to set.\n */\n public setConcurrency(concurrency: number): void {\n const clamped = Math.min(Math.max(concurrency, this.minConcurrency), this.maxConcurrency);\n if (clamped !== this._currentConcurrency) {\n const prev = this._currentConcurrency;\n this._currentConcurrency = clamped;\n this.onConcurrencyChange(prev, clamped, \"Manual concurrency override\");\n }\n }\n\n /**\n * Records a task execution duration sample and triggers AIMD adjustment if window is filled.\n *\n * @param durationMs - Execution duration in milliseconds of the completed task.\n */\n public recordDuration(durationMs: number): void {\n this.recentDurations.push(durationMs);\n\n if (this.recentDurations.length < this.sampleWindowSize) {\n return;\n }\n\n const total = this.recentDurations.reduce((sum, val) => sum + val, 0);\n const average = total / this.recentDurations.length;\n this.lastAverageLatencyMs = average;\n this.recentDurations = [];\n\n if (average > this.targetLatencyMs) {\n // Multiplicative Decrease (back off)\n const decreased = Math.max(\n this.minConcurrency,\n Math.floor(this._currentConcurrency * this.backoffFactor)\n );\n\n if (decreased !== this._currentConcurrency) {\n const prev = this._currentConcurrency;\n this._currentConcurrency = decreased;\n this.onConcurrencyChange(\n prev,\n decreased,\n `Average latency (${Math.round(average)}ms) exceeded target (${this.targetLatencyMs}ms). Scaled down.`\n );\n }\n } else if (average < this.targetLatencyMs * 0.75) {\n // Additive Increase (scale up)\n const increased = Math.min(this.maxConcurrency, this._currentConcurrency + 1);\n\n if (increased !== this._currentConcurrency) {\n const prev = this._currentConcurrency;\n this._currentConcurrency = increased;\n this.onConcurrencyChange(\n prev,\n increased,\n `Average latency (${Math.round(average)}ms) below target threshold. Scaled up.`\n );\n }\n }\n }\n\n /**\n * Returns a snapshot of adaptive telemetry metrics.\n */\n public getStats(): IAdaptiveStats {\n return {\n currentConcurrency: this._currentConcurrency,\n averageLatencyMs: this.lastAverageLatencyMs,\n samplesRecorded: this.recentDurations.length,\n };\n }\n}\n","/**\n * Discrete lifecycle states of the circuit breaker.\n */\nexport enum ECircuitState {\n /** Normal operation: calls pass through to execution */\n CLOSED = \"closed\",\n /** Failure threshold exceeded: calls fast-fail immediately */\n OPEN = \"open\",\n /** Cool-down timer elapsed: trial call allowed to test recovery */\n HALF_OPEN = \"half_open\",\n}\n\n/** Union type representing circuit breaker states */\nexport type TCircuitState = `${ECircuitState}`;\n\n/**\n * Configuration options for the circuit breaker policy.\n */\nexport interface ICircuitBreakerOptions {\n /**\n * Number of consecutive task failures required to trip the circuit to OPEN state.\n * Must be an integer greater than or equal to 1.\n */\n failureThreshold: number;\n\n /**\n * Time in milliseconds the circuit remains OPEN before transitioning to HALF_OPEN\n * to attempt a recovery trial call. Must be a positive finite number.\n */\n resetTimeoutMs: number;\n}\n\n/**\n * Telemetry snapshot of circuit breaker status.\n */\nexport interface ICircuitBreakerStats {\n /** Current state of the breaker */\n state: ECircuitState;\n /** Number of consecutive errors recorded */\n consecutiveFailures: number;\n /** Timestamp in ms when the breaker tripped to OPEN, if open */\n lastFailureTime?: number;\n}\n","import { AhkoCircuitBreakerOpenError } from \"../errors/circuit-breaker.error.js\";\nimport { AhkoConfigurationError } from \"../errors/configuration.error.js\";\nimport {\n ECircuitState,\n type ICircuitBreakerOptions,\n type ICircuitBreakerStats,\n} from \"../models/circuit-breaker.model.js\";\n\n/**\n * Manages circuit breaker failure tracking, state transitions, and fast-fail enforcement.\n *\n * Implements standard Martin Fowler Circuit Breaker state machine:\n * - CLOSED: All operations execute normally.\n * - OPEN: All operations fast-fail immediately with AhkoCircuitBreakerOpenError.\n * - HALF_OPEN: Probe execution allowed to verify recovery.\n */\nexport class CircuitBreakerCoordinator {\n private _state = ECircuitState.CLOSED;\n private _consecutiveFailures = 0;\n private _lastFailureTime: number | undefined;\n public readonly failureThreshold: number;\n public readonly resetTimeoutMs: number;\n\n /**\n * Initializes a new CircuitBreakerCoordinator.\n *\n * @param options - Configuration options for threshold and cool-down window.\n * @throws {AhkoConfigurationError} If options are invalid.\n */\n constructor(options: ICircuitBreakerOptions) {\n if (\n typeof options.failureThreshold !== \"number\" ||\n Number.isNaN(options.failureThreshold) ||\n !Number.isInteger(options.failureThreshold) ||\n options.failureThreshold < 1\n ) {\n throw new AhkoConfigurationError(\n `Invalid failureThreshold \"${options.failureThreshold}\". failureThreshold must be an integer greater than or equal to 1.`\n );\n }\n\n if (\n typeof options.resetTimeoutMs !== \"number\" ||\n Number.isNaN(options.resetTimeoutMs) ||\n !Number.isFinite(options.resetTimeoutMs) ||\n options.resetTimeoutMs <= 0\n ) {\n throw new AhkoConfigurationError(\n `Invalid resetTimeoutMs \"${options.resetTimeoutMs}\". resetTimeoutMs must be a positive finite number greater than 0.`\n );\n }\n\n this.failureThreshold = options.failureThreshold;\n this.resetTimeoutMs = options.resetTimeoutMs;\n }\n\n /** Current state of the circuit breaker */\n public get state(): ECircuitState {\n this.refreshState();\n return this._state;\n }\n\n /**\n * Checks whether an execution is currently allowed.\n * If the circuit is OPEN and cool-down has not elapsed, fast-fails immediately.\n *\n * @throws {AhkoCircuitBreakerOpenError} If the circuit is currently OPEN.\n */\n public checkAllowed(): void {\n this.refreshState();\n\n if (this._state === ECircuitState.OPEN) {\n const remainingMs = this._lastFailureTime\n ? Math.max(0, this.resetTimeoutMs - (Date.now() - this._lastFailureTime))\n : this.resetTimeoutMs;\n\n throw new AhkoCircuitBreakerOpenError(\n `Circuit breaker is open. Fast-failing task execution. Remaining cool-down: ${remainingMs}ms.`,\n {\n resetTimeoutMs: remainingMs,\n trippedAt: this._lastFailureTime,\n consecutiveFailures: this._consecutiveFailures,\n }\n );\n }\n }\n\n /**\n * Records a successful task execution.\n * Heals HALF_OPEN state back to CLOSED and resets consecutive failure counters.\n */\n public recordSuccess(): void {\n this._consecutiveFailures = 0;\n this._state = ECircuitState.CLOSED;\n }\n\n /**\n * Records a failed task execution.\n * Trips CLOSED to OPEN when threshold is met, or re-trips HALF_OPEN immediately.\n *\n * @param _error - Optional error that caused the failure.\n */\n public recordFailure(_error?: unknown): void {\n this._consecutiveFailures++;\n this._lastFailureTime = Date.now();\n\n if (this._state === ECircuitState.HALF_OPEN) {\n this._state = ECircuitState.OPEN;\n return;\n }\n\n if (this._consecutiveFailures >= this.failureThreshold) {\n this._state = ECircuitState.OPEN;\n }\n }\n\n /**\n * Evaluates if enough time has passed to transition from OPEN to HALF_OPEN.\n */\n private refreshState(): void {\n if (this._state === ECircuitState.OPEN && this._lastFailureTime !== undefined) {\n const elapsed = Date.now() - this._lastFailureTime;\n if (elapsed >= this.resetTimeoutMs) {\n this._state = ECircuitState.HALF_OPEN;\n }\n }\n }\n\n /**\n * Resets the circuit breaker back to initial CLOSED state.\n */\n public reset(): void {\n this._state = ECircuitState.CLOSED;\n this._consecutiveFailures = 0;\n this._lastFailureTime = undefined;\n }\n\n /**\n * Returns a snapshot of circuit breaker telemetry.\n */\n public getStats(): ICircuitBreakerStats {\n this.refreshState();\n return {\n state: this._state,\n consecutiveFailures: this._consecutiveFailures,\n lastFailureTime: this._lastFailureTime,\n };\n }\n}\n","import { AhkoCancellationError } from \"../errors/cancellation.error.js\";\nimport type { IScheduleOptions } from \"../models/options.model.js\";\nimport type { ITask } from \"../models/task.model.js\";\n\n/**\n * Internal tracking entry for a coalesced debounced task.\n */\ninterface IDebounceEntry<T = unknown> {\n readonly key: string | symbol;\n task: ITask<T>;\n options?: IScheduleOptions;\n timerId: ReturnType<typeof setTimeout>;\n resolve: (value: T) => void;\n reject: (reason: unknown) => void;\n readonly promise: Promise<T>;\n abortListener?: () => void;\n}\n\n/**\n * Coordinates debounce execution with Promise coalescing by explicit key.\n *\n * Incoming calls with the same key extend the quiet window and share the\n * eventual execution Promise, guaranteeing that all callers receive the final result.\n */\nexport class DebounceCoordinator {\n private readonly entries = new Map<string | symbol, IDebounceEntry<unknown>>();\n\n /** Optional callback invoked whenever entries are settled or removed from coordinator */\n public onSettled?: () => void;\n\n /**\n * Schedules a task under the debounce strategy.\n *\n * @param key - Explicit identity key.\n * @param task - Work to execute once calls stop arriving.\n * @param waitMs - Quiet window duration in milliseconds.\n * @param options - Scheduling options.\n * @param dispatchFn - Callback invoked when the debounce window expires to dispatch the task to the queue.\n * @returns Shared promise that resolves/rejects with the final execution outcome.\n */\n public schedule<T>(\n key: string | symbol,\n task: ITask<T>,\n waitMs: number,\n options: IScheduleOptions | undefined,\n dispatchFn: (task: ITask<T>, options?: IScheduleOptions) => Promise<T>\n ): Promise<T> {\n const existing = this.entries.get(key) as IDebounceEntry<T> | undefined;\n\n if (existing) {\n clearTimeout(existing.timerId);\n if (existing.options?.signal && existing.abortListener) {\n existing.options.signal.removeEventListener(\"abort\", existing.abortListener);\n }\n\n existing.task = task;\n existing.options = options;\n\n if (options?.signal?.aborted) {\n this.entries.delete(key);\n const err = new AhkoCancellationError(\n typeof options.signal.reason === \"string\"\n ? options.signal.reason\n : \"Debounced task was cancelled prior to execution\",\n { cause: options.signal.reason instanceof Error ? options.signal.reason : undefined }\n );\n existing.reject(err);\n return existing.promise;\n }\n\n if (options?.signal) {\n const listener = () => {\n this.cancel(key, options.signal?.reason);\n };\n existing.abortListener = listener;\n options.signal.addEventListener(\"abort\", listener, { once: true });\n }\n\n existing.timerId = setTimeout(() => {\n void this.flush(key, dispatchFn);\n }, waitMs);\n\n return existing.promise;\n }\n\n let resolvePromise!: (value: T) => void;\n let rejectPromise!: (reason: unknown) => void;\n\n const promise = new Promise<T>((resolve, reject) => {\n resolvePromise = resolve;\n rejectPromise = reject;\n });\n\n if (options?.signal?.aborted) {\n const err = new AhkoCancellationError(\n typeof options.signal.reason === \"string\"\n ? options.signal.reason\n : \"Debounced task was cancelled prior to execution\",\n { cause: options.signal.reason instanceof Error ? options.signal.reason : undefined }\n );\n rejectPromise(err);\n return promise;\n }\n\n let abortListener: (() => void) | undefined;\n if (options?.signal) {\n abortListener = () => {\n this.cancel(key, options.signal?.reason);\n };\n options.signal.addEventListener(\"abort\", abortListener, { once: true });\n }\n\n const timerId = setTimeout(() => {\n void this.flush(key, dispatchFn);\n }, waitMs);\n\n const entry: IDebounceEntry<T> = {\n key,\n task,\n options,\n timerId,\n resolve: resolvePromise,\n reject: rejectPromise,\n promise,\n abortListener,\n };\n\n this.entries.set(key, entry as IDebounceEntry<unknown>);\n return promise;\n }\n\n /**\n * Dispatches the coalesced task when the quiet window expires.\n */\n private async flush<T>(\n key: string | symbol,\n dispatchFn: (task: ITask<T>, options?: IScheduleOptions) => Promise<T>\n ): Promise<void> {\n const entry = this.entries.get(key) as IDebounceEntry<T> | undefined;\n if (!entry) {\n return;\n }\n\n this.entries.delete(key);\n this.onSettled?.();\n if (entry.options?.signal && entry.abortListener) {\n entry.options.signal.removeEventListener(\"abort\", entry.abortListener);\n }\n\n try {\n const result = await dispatchFn(entry.task, entry.options);\n entry.resolve(result);\n } catch (error) {\n entry.reject(error);\n }\n }\n\n /**\n * Cancels a pending debounced task by key.\n *\n * @param key - Identity key to cancel.\n * @param reason - Optional cancellation reason.\n */\n public cancel(key: string | symbol, reason?: unknown): void {\n const entry = this.entries.get(key);\n if (!entry) {\n return;\n }\n\n clearTimeout(entry.timerId);\n this.entries.delete(key);\n this.onSettled?.();\n\n if (entry.options?.signal && entry.abortListener) {\n entry.options.signal.removeEventListener(\"abort\", entry.abortListener);\n }\n\n const cancelError = new AhkoCancellationError(\n typeof reason === \"string\" ? reason : \"Debounced task was cancelled prior to execution\",\n { cause: reason instanceof Error ? reason : undefined }\n );\n entry.reject(cancelError);\n }\n\n /**\n * Number of pending debounced tasks waiting for quiet window expiry.\n */\n public get size(): number {\n return this.entries.size;\n }\n\n /**\n * Cancels all pending debounced entries and clears the map.\n */\n public clear(): void {\n for (const entry of this.entries.values()) {\n clearTimeout(entry.timerId);\n if (entry.options?.signal && entry.abortListener) {\n entry.options.signal.removeEventListener(\"abort\", entry.abortListener);\n }\n entry.reject(new AhkoCancellationError(\"Debounced tasks cleared\"));\n }\n this.entries.clear();\n this.onSettled?.();\n }\n}\n","/**\n * Handle returned by the IdleScheduler allowing cancellation of an idle request.\n */\nexport interface IIdleHandle {\n /**\n * Cancels the scheduled idle callback and cleans up platform resources.\n */\n cancel(): void;\n}\n\n/**\n * Platform-agnostic scheduler for opportunistic idle task execution.\n *\n * Automatically detects and selects platform capabilities:\n * 1. Browser: `requestIdleCallback` / `cancelIdleCallback` (with optional timeout)\n * 2. Node.js: `setImmediate` / `clearImmediate` as low-priority primitive\n * 3. Fallback: `setTimeout(..., 0)` / `clearTimeout`\n */\nexport class IdleScheduler {\n /**\n * Schedules a callback to execute during the next idle opportunity.\n *\n * @param callback - Function to invoke when idle opportunity arises.\n * @param timeout - Optional max deadline in milliseconds to wait before invoking (browser only).\n * @param runtime - Target runtime scope providing scheduling primitives (defaults to globalThis).\n * @returns An {@link IIdleHandle} with a `cancel()` method for cleanup.\n */\n public static schedule(\n callback: () => void,\n timeout?: number,\n runtime: typeof globalThis = globalThis\n ): IIdleHandle {\n // 1. Browser requestIdleCallback\n if (\n typeof (runtime as Record<string, unknown>).requestIdleCallback === \"function\" &&\n typeof (runtime as Record<string, unknown>).cancelIdleCallback === \"function\"\n ) {\n const requestFn = (runtime as Record<string, unknown>).requestIdleCallback as (\n cb: (deadline?: unknown) => void,\n opts?: { timeout?: number }\n ) => number;\n\n const cancelFn = (runtime as Record<string, unknown>).cancelIdleCallback as (\n handle: number\n ) => void;\n\n const id = requestFn(\n () => callback(),\n typeof timeout === \"number\" && !Number.isNaN(timeout) && timeout >= 0\n ? { timeout }\n : undefined\n );\n\n return {\n cancel: () => cancelFn(id),\n };\n }\n\n // 2. Node.js setImmediate\n if (\n typeof (runtime as Record<string, unknown>).setImmediate === \"function\" &&\n typeof (runtime as Record<string, unknown>).clearImmediate === \"function\"\n ) {\n const setImmFn = (runtime as Record<string, unknown>).setImmediate as (\n cb: () => void\n ) => ReturnType<typeof setImmediate>;\n\n const clearImmFn = (runtime as Record<string, unknown>).clearImmediate as (\n handle: ReturnType<typeof setImmediate>\n ) => void;\n\n const handle = setImmFn(() => callback());\n\n return {\n cancel: () => clearImmFn(handle),\n };\n }\n\n // 3. Universal fallback setTimeout(0)\n const setTimerFn = runtime.setTimeout.bind(runtime);\n const clearTimerFn = runtime.clearTimeout.bind(runtime);\n\n const timerId = setTimerFn(() => callback(), 0);\n\n return {\n cancel: () => clearTimerFn(timerId),\n };\n }\n}\n","import { AhkoCancellationError } from \"../errors/cancellation.error.js\";\nimport type { IScheduleOptions } from \"../models/options.model.js\";\nimport type { ITask } from \"../models/task.model.js\";\n\n/**\n * Internal tracking entry for throttled executions.\n */\ninterface IThrottleEntry<T = unknown> {\n readonly key: string | symbol;\n windowTimerId?: ReturnType<typeof setTimeout>;\n trailingTask?: ITask<T>;\n trailingOptions?: IScheduleOptions;\n trailingResolve?: (value: T) => void;\n trailingReject?: (reason: unknown) => void;\n trailingPromise?: Promise<T>;\n abortListener?: () => void;\n}\n\n/**\n * Coordinates throttle execution with leading execution, trailing execution,\n * and Promise coalescing by explicit key.\n *\n * Incoming calls with the same key within the throttle period coalesce into a\n * single shared trailing execution, preventing overload while ensuring callers\n * receive the final result.\n */\nexport class ThrottleCoordinator {\n private readonly entries = new Map<string | symbol, IThrottleEntry<unknown>>();\n\n /** Optional callback invoked whenever entries are settled or removed from coordinator */\n public onSettled?: () => void;\n\n /**\n * Schedules a task under the throttle strategy.\n *\n * @param key - Explicit identity key.\n * @param task - Work to execute.\n * @param waitMs - Throttle interval duration in milliseconds.\n * @param options - Scheduling options.\n * @param dispatchFn - Callback invoked to dispatch task execution into the queue.\n * @returns Promise resolving with the leading execution or coalesced trailing result.\n */\n public schedule<T>(\n key: string | symbol,\n task: ITask<T>,\n waitMs: number,\n options: IScheduleOptions | undefined,\n dispatchFn: (task: ITask<T>, options?: IScheduleOptions) => Promise<T>\n ): Promise<T> {\n const existing = this.entries.get(key) as IThrottleEntry<T> | undefined;\n\n if (!existing) {\n // Leading execution: runs immediately\n const entry: IThrottleEntry<T> = {\n key,\n };\n\n entry.windowTimerId = setTimeout(() => {\n void this.onWindowExpire(key, waitMs, dispatchFn);\n }, waitMs);\n\n this.entries.set(key, entry as IThrottleEntry<unknown>);\n\n return dispatchFn(task, options);\n }\n\n // Trailing call within active window: coalesce with latest work\n existing.trailingTask = task;\n existing.trailingOptions = options;\n\n if (existing.trailingPromise) {\n return existing.trailingPromise;\n }\n\n let resolvePromise!: (value: T) => void;\n let rejectPromise!: (reason: unknown) => void;\n\n existing.trailingPromise = new Promise<T>((resolve, reject) => {\n resolvePromise = resolve;\n rejectPromise = reject;\n });\n existing.trailingResolve = resolvePromise;\n existing.trailingReject = rejectPromise;\n\n if (options?.signal) {\n const listener = () => {\n if (existing.trailingReject) {\n existing.trailingReject(\n new AhkoCancellationError(\"Throttled trailing task was cancelled\", {\n cause: options.signal?.reason instanceof Error ? options.signal.reason : undefined,\n })\n );\n existing.trailingTask = undefined;\n existing.trailingOptions = undefined;\n existing.trailingPromise = undefined;\n existing.trailingResolve = undefined;\n existing.trailingReject = undefined;\n }\n };\n existing.abortListener = listener;\n options.signal.addEventListener(\"abort\", listener, { once: true });\n }\n\n return existing.trailingPromise;\n }\n\n /**\n * Invoked when the throttle interval window timer expires.\n */\n private async onWindowExpire<T>(\n key: string | symbol,\n waitMs: number,\n dispatchFn: (task: ITask<T>, options?: IScheduleOptions) => Promise<T>\n ): Promise<void> {\n const entry = this.entries.get(key) as IThrottleEntry<T> | undefined;\n if (!entry) {\n return;\n }\n\n if (entry.trailingTask) {\n const task = entry.trailingTask;\n const options = entry.trailingOptions;\n const resolve = entry.trailingResolve;\n const reject = entry.trailingReject;\n\n // Reset trailing slots for subsequent calls\n entry.trailingTask = undefined;\n entry.trailingOptions = undefined;\n entry.trailingPromise = undefined;\n entry.trailingResolve = undefined;\n entry.trailingReject = undefined;\n\n // Re-arm window timer for the trailing run\n entry.windowTimerId = setTimeout(() => {\n void this.onWindowExpire(key, waitMs, dispatchFn);\n }, waitMs);\n\n try {\n const result = await dispatchFn(task, options);\n resolve?.(result);\n } catch (error) {\n reject?.(error);\n }\n return;\n }\n\n // No trailing task arrived during the window: settle and delete key\n this.entries.delete(key);\n this.onSettled?.();\n }\n\n /**\n * Cancels any pending trailing throttled task for a given key.\n *\n * @param key - Identity key to cancel.\n * @param reason - Optional cancellation reason.\n */\n public cancel(key: string | symbol, reason?: unknown): void {\n const entry = this.entries.get(key);\n if (!entry) {\n return;\n }\n\n if (entry.windowTimerId !== undefined) {\n clearTimeout(entry.windowTimerId);\n }\n this.entries.delete(key);\n this.onSettled?.();\n\n if (entry.trailingReject) {\n const cancelError = new AhkoCancellationError(\n typeof reason === \"string\" ? reason : \"Throttled task was cancelled\",\n { cause: reason instanceof Error ? reason : undefined }\n );\n entry.trailingReject(cancelError);\n }\n }\n\n /**\n * Number of keys currently actively throttled.\n */\n public get size(): number {\n return this.entries.size;\n }\n\n /**\n * Clears all throttled entries and timers.\n */\n public clear(): void {\n for (const entry of this.entries.values()) {\n if (entry.windowTimerId !== undefined) {\n clearTimeout(entry.windowTimerId);\n }\n if (entry.trailingReject) {\n entry.trailingReject(new AhkoCancellationError(\"Throttled tasks cleared\"));\n }\n }\n this.entries.clear();\n this.onSettled?.();\n }\n}\n","import type {\n IAhkoEventMap,\n TAhkoEventHandler,\n TAhkoEventName,\n TAhkoUnsubscribe,\n} from \"../models/events.model.js\";\n\n/**\n * Lightweight, zero-dependency typed event emitter with safe error containment.\n */\nexport class AhkoEventEmitter {\n private readonly listeners = new Map<\n TAhkoEventName,\n Set<TAhkoEventHandler<any>>\n >();\n\n /**\n * Subscribes a listener to a specific Ahko lifecycle event.\n *\n * @param event - The event name to subscribe to.\n * @param handler - The callback function to invoke when the event is emitted.\n * @returns An unsubscribe function to remove the listener.\n */\n public on<K extends TAhkoEventName>(\n event: K,\n handler: TAhkoEventHandler<K>\n ): TAhkoUnsubscribe {\n let set = this.listeners.get(event);\n if (!set) {\n set = new Set();\n this.listeners.set(event, set);\n }\n\n set.add(handler);\n\n return () => {\n this.off(event, handler);\n };\n }\n\n /**\n * Unsubscribes a listener from a specific Ahko lifecycle event.\n *\n * @param event - The event name.\n * @param handler - The callback function to remove.\n */\n public off<K extends TAhkoEventName>(\n event: K,\n handler: TAhkoEventHandler<K>\n ): void {\n const set = this.listeners.get(event);\n if (set) {\n set.delete(handler);\n if (set.size === 0) {\n this.listeners.delete(event);\n }\n }\n }\n\n /**\n * Emits an event with the corresponding typed payload to all subscribed listeners.\n * Listener invocations are safely isolated in try/catch to protect scheduler integrity.\n *\n * @param event - The event name to emit.\n * @param payload - The event-specific payload data.\n */\n public emit<K extends TAhkoEventName>(\n event: K,\n payload: IAhkoEventMap[K]\n ): void {\n const set = this.listeners.get(event);\n if (!set || set.size === 0) {\n return;\n }\n\n // Iterate over shallow copy to tolerate in-flight unsubscriptions\n const handlers = Array.from(set);\n for (const handler of handlers) {\n try {\n const result = handler(payload);\n if (result && typeof (result as Promise<void>).catch === \"function\") {\n (result as Promise<void>).catch(() => {});\n }\n } catch {\n // Error containment: listener exceptions do not disrupt scheduler operation\n }\n }\n }\n\n /**\n * Removes all registered event listeners.\n */\n public clear(): void {\n this.listeners.clear();\n }\n}\n","import { AhkoCircuitBreakerOpenError } from \"../errors/circuit-breaker.error.js\";\nimport { AhkoConfigurationError } from \"../errors/configuration.error.js\";\nimport { AhkoTimeoutError } from \"../errors/timeout.error.js\";\nimport type { IAdaptiveConcurrencyOptions } from \"../models/adaptive.model.js\";\nimport type { ICircuitBreakerOptions } from \"../models/circuit-breaker.model.js\";\nimport type { IScheduleOptions } from \"../models/options.model.js\";\nimport { resolvePriorityWeight } from \"../models/priority.model.js\";\nimport type { IAhkoStats } from \"../models/stats.model.js\";\nimport { ETaskState } from \"../models/state.model.js\";\nimport { EScheduleStrategy } from \"../models/strategy.model.js\";\nimport { calculateBackoff } from \"../retry/backoff.js\";\nimport { AdaptiveCoordinator } from \"./adaptive-coordinator.js\";\nimport { CircuitBreakerCoordinator } from \"./circuit-breaker.js\";\nimport { DebounceCoordinator } from \"./debounce-coordinator.js\";\nimport { IdleScheduler, type IIdleHandle } from \"./idle-scheduler.js\";\nimport { TaskRunner } from \"./task-runner.js\";\nimport { ThrottleCoordinator } from \"./throttle-coordinator.js\";\nimport { AhkoEventEmitter } from \"../events/event-emitter.js\";\n\n/**\n * Entry tracking delayed task timers for deterministic cancellation and memory cleanup.\n */\ninterface IDelayedEntry {\n runner: TaskRunner<unknown>;\n timerId: ReturnType<typeof setTimeout>;\n}\n\n/**\n * Entry tracking idle callback handles for deterministic cancellation and cleanup.\n */\ninterface IIdleEntry {\n runner: TaskRunner<unknown>;\n handle: IIdleHandle;\n}\n\n/**\n * Entry tracking backoff delay timers for retry attempts.\n */\ninterface IRetryEntry {\n runner: TaskRunner<unknown>;\n timerId: ReturnType<typeof setTimeout>;\n}\n\n/**\n * Memory-safe priority-aware task queue managing concurrency allocation,\n * rate limiting, circuit breaker protection, dynamic & adaptive concurrency,\n * tags, flow control (pause/resume), and task lifecycle counters.\n */\nexport class TaskQueue {\n /** Maximum concurrent active tasks */\n private _concurrency: number;\n\n /** Minimum interval in milliseconds between consecutive task starts */\n public readonly minIntervalMs: number;\n\n /** Timestamp of the most recent task start */\n private lastTaskStartTime = 0;\n\n /** Active rate limit timer for pacing consecutive tasks */\n private rateLimitTimer?: ReturnType<typeof setTimeout>;\n\n /** Queue of pending task runners waiting for a concurrency slot */\n private readonly queue: TaskRunner<unknown>[] = [];\n\n /** Set of task runners currently executing */\n private readonly activeRunners = new Set<TaskRunner<unknown>>();\n\n /** Set of tasks currently in delay phase */\n private readonly delayedEntries = new Set<IDelayedEntry>();\n\n /** Set of tasks currently awaiting an idle opportunity */\n private readonly idleEntries = new Set<IIdleEntry>();\n\n /** Set of tasks currently awaiting a retry backoff timer */\n private readonly retryEntries = new Set<IRetryEntry>();\n\n /** Tag index for selective cancellation and task classification */\n private readonly tagIndex = new Map<string, Set<TaskRunner<unknown>>>();\n\n /** Coordinator for debounced tasks with key coalescing */\n public readonly debounceCoordinator = new DebounceCoordinator();\n\n /** Coordinator for throttled tasks with leading/trailing coalescing */\n public readonly throttleCoordinator = new ThrottleCoordinator();\n\n /** Lifecycle event emitter for task and scheduler events */\n public readonly emitter = new AhkoEventEmitter();\n\n /** Circuit breaker coordinator if configured */\n public readonly circuitBreakerCoordinator?: CircuitBreakerCoordinator;\n\n /** Adaptive concurrency coordinator if configured */\n public readonly adaptiveCoordinator?: AdaptiveCoordinator;\n\n /** Pause state flag */\n private _isPaused = false;\n\n /** Set of pending resolvers awaiting scheduler idle transition */\n private readonly idleResolvers = new Set<() => void>();\n\n /** WeakMap associating task runners with their scheduling options */\n private readonly runnerOptions = new WeakMap<TaskRunner<unknown>, IScheduleOptions>();\n\n /** Cumulative completed tasks counter */\n private completedTasks = 0;\n\n /** Cumulative failed tasks counter */\n private failedTasks = 0;\n\n /** Cumulative cancelled tasks counter */\n private cancelledTasks = 0;\n\n /** Cumulative timed out tasks counter */\n private timedOutTasks = 0;\n\n /** Cumulative count of retry attempts triggered */\n private retriedTasks = 0;\n\n /** Cumulative count of tasks dispatched to concurrency slots */\n private totalDispatched = 0;\n\n /**\n * Creates a new TaskQueue.\n *\n * @param concurrency - Maximum concurrent tasks (defaults to Infinity).\n * @param minIntervalMs - Minimum interval in milliseconds between task dispatches.\n * @param circuitBreakerOptions - Optional circuit breaker policy configuration.\n * @param adaptiveOptions - Optional adaptive concurrency policy configuration.\n * @throws {AhkoConfigurationError} If concurrency is less than 1 or minIntervalMs is invalid.\n */\n constructor(\n concurrency = Infinity,\n minIntervalMs = 0,\n circuitBreakerOptions?: ICircuitBreakerOptions,\n adaptiveOptions?: IAdaptiveConcurrencyOptions\n ) {\n if (Number.isNaN(concurrency) || concurrency < 1) {\n throw new AhkoConfigurationError(\n `Invalid concurrency \"${concurrency}\". Must be a number greater than or equal to 1.`\n );\n }\n if (\n typeof minIntervalMs !== \"number\" ||\n Number.isNaN(minIntervalMs) ||\n !Number.isFinite(minIntervalMs) ||\n minIntervalMs < 0\n ) {\n throw new AhkoConfigurationError(\n `Invalid minIntervalMs \"${minIntervalMs}\". minIntervalMs must be a non-negative finite number.`\n );\n }\n this._concurrency = concurrency;\n this.minIntervalMs = minIntervalMs;\n\n if (circuitBreakerOptions) {\n this.circuitBreakerCoordinator = new CircuitBreakerCoordinator(circuitBreakerOptions);\n }\n\n if (adaptiveOptions) {\n this.adaptiveCoordinator = new AdaptiveCoordinator(\n adaptiveOptions,\n this._concurrency,\n (previous, current, reason) => {\n this._concurrency = current;\n this.emitter.emit(\"concurrency:change\", {\n previousConcurrency: previous,\n currentConcurrency: current,\n reason,\n });\n this.pump();\n }\n );\n this._concurrency = this.adaptiveCoordinator.currentConcurrency;\n }\n\n this.debounceCoordinator.onSettled = () => this.checkIdle();\n this.throttleCoordinator.onSettled = () => this.checkIdle();\n }\n\n /**\n * Current concurrency capacity limit.\n */\n public get concurrency(): number {\n return this._concurrency;\n }\n\n /**\n * Dynamically adjusts the concurrency limit at runtime.\n *\n * @param newConcurrency - New maximum concurrency (must be >= 1).\n * @throws {AhkoConfigurationError} If newConcurrency is less than 1.\n */\n public setConcurrency(newConcurrency: number): void {\n if (Number.isNaN(newConcurrency) || newConcurrency < 1) {\n throw new AhkoConfigurationError(\n `Invalid concurrency \"${newConcurrency}\". Must be a number greater than or equal to 1.`\n );\n }\n\n const previous = this._concurrency;\n this._concurrency = newConcurrency;\n\n if (this.adaptiveCoordinator) {\n this.adaptiveCoordinator.setConcurrency(newConcurrency);\n }\n\n if (newConcurrency !== previous) {\n this.emitter.emit(\"concurrency:change\", {\n previousConcurrency: previous,\n currentConcurrency: newConcurrency,\n reason: \"Manual concurrency update\",\n });\n }\n\n this.pump();\n }\n\n /**\n * Pauses queue execution. Running tasks will complete normally, but no new pending tasks will be dispatched.\n */\n public pause(): void {\n this._isPaused = true;\n }\n\n /**\n * Resumes queue execution, immediately dispatching waiting tasks up to available concurrency.\n */\n public resume(): void {\n if (this._isPaused) {\n this._isPaused = false;\n this.pump();\n }\n }\n\n /**\n * Checks whether the task queue is currently paused.\n */\n public isPaused(): boolean {\n return this._isPaused;\n }\n\n /**\n * Cancels all pending, delayed, and active tasks marked with the specified tag.\n *\n * @param tag - Tag identifier to match.\n * @param reason - Optional cancellation reason.\n * @returns Total count of tasks cancelled.\n */\n public cancelByTag(tag: string, reason?: unknown): number {\n const runners = this.tagIndex.get(tag);\n if (!runners || runners.size === 0) {\n return 0;\n }\n\n const list = Array.from(runners);\n let count = 0;\n for (const runner of list) {\n if (\n runner.state === ETaskState.PENDING ||\n runner.state === ETaskState.RUNNING\n ) {\n runner.cancel(reason ?? `Task cancelled by tag \"${tag}\"`);\n count++;\n }\n }\n return count;\n }\n\n /**\n * Returns active and pending task counts for a given tag.\n *\n * @param tag - Tag identifier.\n */\n public getStatsByTag(tag: string): { activeTasks: number; pendingTasks: number } {\n const runners = this.tagIndex.get(tag);\n if (!runners) {\n return { activeTasks: 0, pendingTasks: 0 };\n }\n let active = 0;\n let pending = 0;\n for (const runner of runners) {\n if (runner.state === ETaskState.RUNNING) {\n active++;\n } else if (runner.state === ETaskState.PENDING) {\n pending++;\n }\n }\n return { activeTasks: active, pendingTasks: pending };\n }\n\n /**\n * Indexes a runner under all its associated tags.\n */\n private indexTaskTags(runner: TaskRunner<unknown>): void {\n for (const tag of runner.tags) {\n let set = this.tagIndex.get(tag);\n if (!set) {\n set = new Set();\n this.tagIndex.set(tag, set);\n }\n set.add(runner);\n }\n }\n\n /**\n * Removes a runner from the tag index upon settlement.\n */\n private cleanupTaskTags(runner: TaskRunner<unknown>): void {\n for (const tag of runner.tags) {\n const set = this.tagIndex.get(tag);\n if (set) {\n set.delete(runner);\n if (set.size === 0) {\n this.tagIndex.delete(tag);\n }\n }\n }\n }\n\n /**\n * Inserts a task runner into the queue based on priority weight (descending).\n * Preserves FIFO ordering among tasks with identical priority.\n */\n private insertIntoQueue(runner: TaskRunner<unknown>): void {\n const options = this.runnerOptions.get(runner);\n const targetWeight = resolvePriorityWeight(options?.priority);\n\n let insertIndex = this.queue.length;\n for (let i = 0; i < this.queue.length; i++) {\n const existingOptions = this.runnerOptions.get(this.queue[i]);\n const existingWeight = resolvePriorityWeight(existingOptions?.priority);\n if (existingWeight < targetWeight) {\n insertIndex = i;\n break;\n }\n }\n\n this.queue.splice(insertIndex, 0, runner);\n }\n\n /**\n * Enqueues a task runner according to the specified schedule options.\n *\n * @template T - The return type produced by the task.\n * @param runner - The task runner instance.\n * @param options - Scheduling options.\n * @returns The deferred promise associated with the task runner.\n * @throws {AhkoConfigurationError} If scheduling options are invalid.\n */\n public enqueue<T>(runner: TaskRunner<T>, options?: IScheduleOptions): Promise<T> {\n const strategy = options?.strategy ?? EScheduleStrategy.IMMEDIATE;\n\n if (\n strategy !== EScheduleStrategy.IMMEDIATE &&\n strategy !== EScheduleStrategy.DELAY &&\n strategy !== EScheduleStrategy.IDLE &&\n strategy !== EScheduleStrategy.THROTTLE &&\n strategy !== EScheduleStrategy.DEBOUNCE\n ) {\n throw new AhkoConfigurationError(\n `Unsupported schedule strategy \"${String(strategy)}\". Supported strategies: \"immediate\", \"delay\", \"idle\", \"throttle\", \"debounce\".`\n );\n }\n\n if (strategy === EScheduleStrategy.THROTTLE || strategy === EScheduleStrategy.DEBOUNCE) {\n if (!options?.key || (typeof options.key !== \"string\" && typeof options.key !== \"symbol\")) {\n throw new AhkoConfigurationError(\n `Strategy \"${strategy}\" requires a valid \"key\" of type string or symbol.`\n );\n }\n const waitMs = options.waitMs ?? options.delay;\n if (typeof waitMs !== \"number\" || Number.isNaN(waitMs) || !Number.isFinite(waitMs) || waitMs < 0) {\n throw new AhkoConfigurationError(\n `Strategy \"${strategy}\" requires a non-negative finite \"waitMs\" or \"delay\" in milliseconds.`\n );\n }\n }\n\n if (options?.retry) {\n if (\n typeof options.retry.attempts !== \"number\" ||\n Number.isNaN(options.retry.attempts) ||\n options.retry.attempts < 1 ||\n !Number.isInteger(options.retry.attempts)\n ) {\n throw new AhkoConfigurationError(\n `Invalid retry attempts \"${options.retry.attempts}\". attempts must be an integer greater than or equal to 1.`\n );\n }\n\n if (\n options.retry.baseDelay !== undefined &&\n (typeof options.retry.baseDelay !== \"number\" ||\n Number.isNaN(options.retry.baseDelay) ||\n options.retry.baseDelay < 0)\n ) {\n throw new AhkoConfigurationError(\n `Invalid retry baseDelay \"${options.retry.baseDelay}\". baseDelay must be a non-negative number in milliseconds.`\n );\n }\n\n if (\n options.retry.maxDelay !== undefined &&\n (typeof options.retry.maxDelay !== \"number\" ||\n Number.isNaN(options.retry.maxDelay) ||\n options.retry.maxDelay < 0)\n ) {\n throw new AhkoConfigurationError(\n `Invalid retry maxDelay \"${options.retry.maxDelay}\". maxDelay must be a non-negative number in milliseconds.`\n );\n }\n }\n\n if (options?.timeoutMs !== undefined) {\n if (\n typeof options.timeoutMs !== \"number\" ||\n Number.isNaN(options.timeoutMs) ||\n !Number.isFinite(options.timeoutMs) ||\n options.timeoutMs <= 0\n ) {\n throw new AhkoConfigurationError(\n `Invalid timeoutMs \"${options.timeoutMs}\". timeoutMs must be a positive finite number greater than 0.`\n );\n }\n }\n\n if (options?.totalTimeoutMs !== undefined) {\n if (\n typeof options.totalTimeoutMs !== \"number\" ||\n Number.isNaN(options.totalTimeoutMs) ||\n !Number.isFinite(options.totalTimeoutMs) ||\n options.totalTimeoutMs <= 0\n ) {\n throw new AhkoConfigurationError(\n `Invalid totalTimeoutMs \"${options.totalTimeoutMs}\". totalTimeoutMs must be a positive finite number greater than 0.`\n );\n }\n }\n\n if (options) {\n this.runnerOptions.set(runner as TaskRunner<unknown>, options);\n }\n\n // Index runner by tags\n this.indexTaskTags(runner as TaskRunner<unknown>);\n\n // Clean up tag index as soon as runner settles\n runner.promise\n .finally(() => {\n this.cleanupTaskTags(runner as TaskRunner<unknown>);\n })\n .catch(() => {});\n\n if (runner.state === ETaskState.CANCELLED) {\n this.cancelledTasks++;\n return runner.promise;\n }\n\n // Attach totalTimeoutMs overall execution budget if configured\n if (options?.totalTimeoutMs !== undefined) {\n const budgetMs = options.totalTimeoutMs;\n const totalTimerId = setTimeout(() => {\n runner.timeout(budgetMs, `Task total execution deadline exceeded after ${budgetMs}ms`);\n }, budgetMs);\n\n runner.promise\n .finally(() => {\n clearTimeout(totalTimerId);\n })\n .catch(() => {});\n }\n\n if (strategy === EScheduleStrategy.DELAY) {\n const delayMs = options?.delay ?? 0;\n if (typeof delayMs !== \"number\" || Number.isNaN(delayMs) || delayMs < 0) {\n throw new AhkoConfigurationError(\n `Invalid delay \"${delayMs}\". Delay must be a non-negative number in milliseconds.`\n );\n }\n\n this.scheduleDelayed(runner as TaskRunner<unknown>, delayMs);\n return runner.promise;\n }\n\n if (strategy === EScheduleStrategy.IDLE) {\n if (\n options?.idleTimeout !== undefined &&\n (typeof options.idleTimeout !== \"number\" ||\n Number.isNaN(options.idleTimeout) ||\n options.idleTimeout < 0)\n ) {\n throw new AhkoConfigurationError(\n `Invalid idleTimeout \"${options.idleTimeout}\". idleTimeout must be a non-negative number in milliseconds.`\n );\n }\n\n this.scheduleIdle(runner as TaskRunner<unknown>, options?.idleTimeout);\n return runner.promise;\n }\n\n // Attach immediate onCancel handler to dequeue without consuming concurrency\n runner.onCancel = () => {\n const index = this.queue.indexOf(runner as TaskRunner<unknown>);\n if (index !== -1) {\n this.queue.splice(index, 1);\n if (runner.totalTimedOut || runner.state === ETaskState.TIMED_OUT) {\n this.timedOutTasks++;\n this.emitter.emit(\"task:timeout\", {\n taskId: runner.taskId,\n timeoutMs: options?.totalTimeoutMs ?? runner.timeoutMs,\n });\n } else {\n this.cancelledTasks++;\n this.emitter.emit(\"task:cancel\", {\n taskId: runner.taskId,\n reason: \"Task cancelled while queued\",\n });\n }\n this.checkIdle();\n }\n };\n\n // Immediate strategy: add to pending queue and pump\n this.insertIntoQueue(runner as TaskRunner<unknown>);\n this.pump();\n\n return runner.promise;\n }\n\n /**\n * Schedules a task to be placed into the queue after a delay,\n * handling early cancellation safely.\n */\n private scheduleDelayed(runner: TaskRunner<unknown>, delayMs: number): void {\n const delayedEntry: IDelayedEntry = {\n runner,\n timerId: setTimeout(() => {\n this.delayedEntries.delete(delayedEntry);\n if (runner.state === ETaskState.CANCELLED || runner.state === ETaskState.TIMED_OUT) {\n return;\n }\n\n runner.onCancel = () => {\n const index = this.queue.indexOf(runner);\n if (index !== -1) {\n this.queue.splice(index, 1);\n if (runner.totalTimedOut || runner.state === ETaskState.TIMED_OUT) {\n this.timedOutTasks++;\n this.emitter.emit(\"task:timeout\", {\n taskId: runner.taskId,\n timeoutMs: this.runnerOptions.get(runner)?.totalTimeoutMs ?? runner.timeoutMs,\n });\n } else {\n this.cancelledTasks++;\n this.emitter.emit(\"task:cancel\", {\n taskId: runner.taskId,\n reason: \"Task cancelled while queued\",\n });\n }\n this.checkIdle();\n }\n };\n\n this.insertIntoQueue(runner);\n this.pump();\n }, delayMs),\n };\n\n this.delayedEntries.add(delayedEntry);\n\n runner.onCancel = () => {\n if (this.delayedEntries.has(delayedEntry)) {\n clearTimeout(delayedEntry.timerId);\n this.delayedEntries.delete(delayedEntry);\n if (runner.totalTimedOut || runner.state === ETaskState.TIMED_OUT) {\n this.timedOutTasks++;\n this.emitter.emit(\"task:timeout\", {\n taskId: runner.taskId,\n timeoutMs: this.runnerOptions.get(runner)?.totalTimeoutMs ?? runner.timeoutMs,\n });\n } else {\n this.cancelledTasks++;\n this.emitter.emit(\"task:cancel\", {\n taskId: runner.taskId,\n reason: \"Task cancelled while waiting in delay\",\n });\n }\n this.checkIdle();\n }\n };\n }\n\n /**\n * Schedules a task to be placed into the queue during an idle opportunity,\n * handling early cancellation safely.\n */\n private scheduleIdle(runner: TaskRunner<unknown>, idleTimeout?: number): void {\n let idleEntry!: IIdleEntry;\n\n const handle = IdleScheduler.schedule(() => {\n this.idleEntries.delete(idleEntry);\n if (runner.state === ETaskState.CANCELLED || runner.state === ETaskState.TIMED_OUT) {\n return;\n }\n\n runner.onCancel = () => {\n const index = this.queue.indexOf(runner);\n if (index !== -1) {\n this.queue.splice(index, 1);\n if (runner.totalTimedOut || runner.state === ETaskState.TIMED_OUT) {\n this.timedOutTasks++;\n this.emitter.emit(\"task:timeout\", {\n taskId: runner.taskId,\n timeoutMs: this.runnerOptions.get(runner)?.totalTimeoutMs ?? runner.timeoutMs,\n });\n } else {\n this.cancelledTasks++;\n this.emitter.emit(\"task:cancel\", {\n taskId: runner.taskId,\n reason: \"Task cancelled while queued\",\n });\n }\n this.checkIdle();\n }\n };\n\n this.insertIntoQueue(runner);\n this.pump();\n }, idleTimeout);\n\n idleEntry = { runner, handle };\n this.idleEntries.add(idleEntry);\n\n runner.onCancel = () => {\n if (this.idleEntries.has(idleEntry)) {\n handle.cancel();\n this.idleEntries.delete(idleEntry);\n if (runner.totalTimedOut || runner.state === ETaskState.TIMED_OUT) {\n this.timedOutTasks++;\n this.emitter.emit(\"task:timeout\", {\n taskId: runner.taskId,\n timeoutMs: this.runnerOptions.get(runner)?.totalTimeoutMs ?? runner.timeoutMs,\n });\n } else {\n this.cancelledTasks++;\n this.emitter.emit(\"task:cancel\", {\n taskId: runner.taskId,\n reason: \"Task cancelled while waiting for idle\",\n });\n }\n this.checkIdle();\n }\n };\n }\n\n /**\n * Pumps the queue by picking pending tasks and executing them\n * as long as concurrency capacity is available, minIntervalMs is respected,\n * and queue is not paused.\n */\n private pump(): void {\n if (this._isPaused || this.queue.length === 0 || this.activeRunners.size >= this._concurrency) {\n return;\n }\n\n if (this.minIntervalMs > 0 && this.lastTaskStartTime > 0) {\n const now = Date.now();\n const elapsed = now - this.lastTaskStartTime;\n if (elapsed < this.minIntervalMs) {\n if (this.rateLimitTimer === undefined) {\n const delay = this.minIntervalMs - elapsed;\n this.rateLimitTimer = setTimeout(() => {\n this.rateLimitTimer = undefined;\n this.pump();\n }, delay);\n }\n return;\n }\n }\n\n while (!this._isPaused && this.activeRunners.size < this._concurrency && this.queue.length > 0) {\n if (this.minIntervalMs > 0 && this.lastTaskStartTime > 0) {\n const now = Date.now();\n const elapsed = now - this.lastTaskStartTime;\n if (elapsed < this.minIntervalMs) {\n if (this.rateLimitTimer === undefined) {\n const delay = this.minIntervalMs - elapsed;\n this.rateLimitTimer = setTimeout(() => {\n this.rateLimitTimer = undefined;\n this.pump();\n }, delay);\n }\n break;\n }\n }\n\n const runner = this.queue.shift();\n if (!runner) {\n break;\n }\n\n if (runner.state === ETaskState.CANCELLED || runner.state === ETaskState.TIMED_OUT) {\n continue;\n }\n\n // Fast-fail check with circuit breaker coordinator\n if (this.circuitBreakerCoordinator) {\n try {\n this.circuitBreakerCoordinator.checkAllowed();\n } catch (cbError) {\n this.failedTasks++;\n this.runnerOptions.delete(runner);\n this.emitter.emit(\"task:fail\", {\n taskId: runner.taskId,\n attempt: runner.attempt,\n error: cbError,\n willRetry: false,\n });\n runner.reject(cbError);\n continue;\n }\n }\n\n this.activeRunners.add(runner);\n this.lastTaskStartTime = Date.now();\n\n // Execute runner without unhandled rejection risk\n void this.executeRunner(runner);\n\n if (this.minIntervalMs > 0) {\n if (this.queue.length > 0 && this.activeRunners.size < this._concurrency) {\n if (this.rateLimitTimer === undefined) {\n this.rateLimitTimer = setTimeout(() => {\n this.rateLimitTimer = undefined;\n this.pump();\n }, this.minIntervalMs);\n }\n }\n break;\n }\n }\n }\n\n /**\n * Internal execution of an active task runner.\n */\n private async executeRunner(runner: TaskRunner<unknown>): Promise<void> {\n const options = this.runnerOptions.get(runner);\n\n this.totalDispatched++;\n this.emitter.emit(\"task:start\", {\n taskId: runner.taskId,\n attempt: runner.attempt,\n });\n\n try {\n const result = await runner.run();\n this.circuitBreakerCoordinator?.recordSuccess();\n this.adaptiveCoordinator?.recordDuration(runner.lastDurationMs);\n this.completedTasks++;\n this.activeRunners.delete(runner);\n this.runnerOptions.delete(runner);\n this.emitter.emit(\"task:complete\", {\n taskId: runner.taskId,\n attempt: runner.attempt,\n durationMs: runner.lastDurationMs,\n result,\n });\n runner.resolve(result);\n } catch (error) {\n if (runner.state === ETaskState.CANCELLED) {\n this.cancelledTasks++;\n this.activeRunners.delete(runner);\n this.runnerOptions.delete(runner);\n this.emitter.emit(\"task:cancel\", {\n taskId: runner.taskId,\n reason: error,\n });\n runner.reject(error);\n return;\n }\n\n const shouldRetry = await runner.canRetry(error, options?.retry);\n if (shouldRetry) {\n this.retriedTasks++;\n // Free concurrency slot immediately during backoff\n this.activeRunners.delete(runner);\n this.emitter.emit(\"task:fail\", {\n taskId: runner.taskId,\n attempt: runner.attempt - 1,\n error,\n willRetry: true,\n });\n this.scheduleRetry(runner, options);\n return;\n }\n\n // Record permanent failure in circuit breaker\n if (this.circuitBreakerCoordinator && !(error instanceof AhkoCircuitBreakerOpenError)) {\n this.circuitBreakerCoordinator.recordFailure(error);\n }\n\n // Record duration in adaptive coordinator\n this.adaptiveCoordinator?.recordDuration(runner.lastDurationMs);\n\n if (runner.state === ETaskState.TIMED_OUT || error instanceof AhkoTimeoutError) {\n this.timedOutTasks++;\n this.emitter.emit(\"task:timeout\", {\n taskId: runner.taskId,\n timeoutMs: options?.totalTimeoutMs ?? runner.timeoutMs,\n });\n } else {\n this.failedTasks++;\n }\n this.activeRunners.delete(runner);\n this.runnerOptions.delete(runner);\n this.emitter.emit(\"task:fail\", {\n taskId: runner.taskId,\n attempt: runner.attempt,\n error,\n willRetry: false,\n });\n runner.reject(error);\n } finally {\n this.pump();\n this.checkIdle();\n }\n }\n\n /**\n * Schedules a retry attempt following backoff delay,\n * without holding a concurrency slot.\n */\n private scheduleRetry(runner: TaskRunner<unknown>, options?: IScheduleOptions): void {\n const backoffDelay = calculateBackoff(runner.attempt - 1, options?.retry);\n\n if (backoffDelay === 0) {\n runner.onCancel = () => {\n const index = this.queue.indexOf(runner);\n if (index !== -1) {\n this.queue.splice(index, 1);\n if (runner.totalTimedOut || runner.state === ETaskState.TIMED_OUT) {\n this.timedOutTasks++;\n this.emitter.emit(\"task:timeout\", {\n taskId: runner.taskId,\n timeoutMs: options?.totalTimeoutMs ?? runner.timeoutMs,\n });\n } else {\n this.cancelledTasks++;\n this.emitter.emit(\"task:cancel\", {\n taskId: runner.taskId,\n reason: \"Task cancelled while queued\",\n });\n }\n this.checkIdle();\n }\n };\n this.insertIntoQueue(runner);\n this.pump();\n return;\n }\n\n const retryEntry: IRetryEntry = {\n runner,\n timerId: setTimeout(() => {\n this.retryEntries.delete(retryEntry);\n if (runner.state === ETaskState.CANCELLED || runner.state === ETaskState.TIMED_OUT) {\n return;\n }\n\n runner.onCancel = () => {\n const index = this.queue.indexOf(runner);\n if (index !== -1) {\n this.queue.splice(index, 1);\n if (runner.totalTimedOut || runner.state === ETaskState.TIMED_OUT) {\n this.timedOutTasks++;\n this.emitter.emit(\"task:timeout\", {\n taskId: runner.taskId,\n timeoutMs: options?.totalTimeoutMs ?? runner.timeoutMs,\n });\n } else {\n this.cancelledTasks++;\n this.emitter.emit(\"task:cancel\", {\n taskId: runner.taskId,\n reason: \"Task cancelled while queued\",\n });\n }\n this.checkIdle();\n }\n };\n\n this.insertIntoQueue(runner);\n this.pump();\n }, backoffDelay),\n };\n\n this.retryEntries.add(retryEntry);\n\n runner.onCancel = () => {\n if (this.retryEntries.has(retryEntry)) {\n clearTimeout(retryEntry.timerId);\n this.retryEntries.delete(retryEntry);\n if (runner.totalTimedOut || runner.state === ETaskState.TIMED_OUT) {\n this.timedOutTasks++;\n this.emitter.emit(\"task:timeout\", {\n taskId: runner.taskId,\n timeoutMs: options?.totalTimeoutMs ?? runner.timeoutMs,\n });\n } else {\n this.cancelledTasks++;\n this.emitter.emit(\"task:cancel\", {\n taskId: runner.taskId,\n reason: \"Task cancelled during retry backoff\",\n });\n }\n this.checkIdle();\n }\n };\n }\n\n /**\n * Checks whether the scheduler has transitioned to idle and notifies listeners/resolvers.\n */\n public checkIdle(): void {\n if (this.isIdle()) {\n if (this.idleResolvers.size > 0) {\n for (const resolve of this.idleResolvers) {\n resolve();\n }\n this.idleResolvers.clear();\n }\n this.emitter.emit(\"idle\", { timestamp: Date.now() });\n }\n }\n\n /**\n * Checks whether the scheduler is currently idle (no active runners and no pending tasks).\n *\n * @returns True if completely idle, false otherwise.\n */\n public isIdle(): boolean {\n return (\n this.activeRunners.size === 0 &&\n this.queue.length === 0 &&\n this.delayedEntries.size === 0 &&\n this.idleEntries.size === 0 &&\n this.retryEntries.size === 0 &&\n this.debounceCoordinator.size === 0 &&\n this.throttleCoordinator.size === 0\n );\n }\n\n /**\n * Returns a promise that resolves once the scheduler has processed all tasks and is idle.\n *\n * @returns Promise resolving when idle.\n */\n public onIdle(): Promise<void> {\n if (this.isIdle()) {\n return Promise.resolve();\n }\n return new Promise<void>((resolve) => {\n this.idleResolvers.add(resolve);\n });\n }\n\n /**\n * Clears all pending and waiting tasks from the scheduler, cancelling their runners.\n * Active tasks currently in flight will continue to run to completion or abort via signal.\n */\n public clear(): void {\n while (this.queue.length > 0) {\n const runner = this.queue.shift();\n if (runner && runner.state !== ETaskState.CANCELLED && runner.state !== ETaskState.TIMED_OUT) {\n runner.cancel(\"Scheduler cleared\");\n this.cancelledTasks++;\n this.emitter.emit(\"task:cancel\", { taskId: runner.taskId, reason: \"Scheduler cleared\" });\n }\n }\n\n for (const entry of this.delayedEntries.values()) {\n clearTimeout(entry.timerId);\n entry.runner.cancel(\"Scheduler cleared\");\n this.cancelledTasks++;\n this.emitter.emit(\"task:cancel\", { taskId: entry.runner.taskId, reason: \"Scheduler cleared\" });\n }\n this.delayedEntries.clear();\n\n for (const entry of this.idleEntries.values()) {\n entry.handle.cancel();\n entry.runner.cancel(\"Scheduler cleared\");\n this.cancelledTasks++;\n this.emitter.emit(\"task:cancel\", { taskId: entry.runner.taskId, reason: \"Scheduler cleared\" });\n }\n this.idleEntries.clear();\n\n for (const entry of this.retryEntries.values()) {\n clearTimeout(entry.timerId);\n entry.runner.cancel(\"Scheduler cleared\");\n this.cancelledTasks++;\n this.emitter.emit(\"task:cancel\", { taskId: entry.runner.taskId, reason: \"Scheduler cleared\" });\n }\n this.retryEntries.clear();\n\n this.debounceCoordinator.clear();\n this.throttleCoordinator.clear();\n\n if (this.rateLimitTimer !== undefined) {\n clearTimeout(this.rateLimitTimer);\n this.rateLimitTimer = undefined;\n }\n\n this.checkIdle();\n }\n\n /**\n * Returns telemetry snapshot for the scheduler.\n *\n * @returns Frozen snapshot of current task metrics.\n */\n public getStats(): IAhkoStats {\n return Object.freeze({\n activeTasks: this.activeRunners.size,\n pendingTasks:\n this.queue.length +\n this.delayedEntries.size +\n this.idleEntries.size +\n this.retryEntries.size +\n this.debounceCoordinator.size +\n this.throttleCoordinator.size,\n completedTasks: this.completedTasks,\n failedTasks: this.failedTasks,\n cancelledTasks: this.cancelledTasks,\n timedOutTasks: this.timedOutTasks,\n retriedTasks: this.retriedTasks,\n totalDispatched: this.totalDispatched,\n capacity: this._concurrency,\n isPaused: this._isPaused,\n circuitState: this.circuitBreakerCoordinator?.state,\n adaptive: this.adaptiveCoordinator?.getStats(),\n });\n }\n}\n","import { AhkoCancellationError } from \"../errors/cancellation.error.js\";\nimport { AhkoTimeoutError } from \"../errors/timeout.error.js\";\nimport type { ITaskContext } from \"../models/context.model.js\";\nimport type { IRetryOptions } from \"../models/retry.model.js\";\nimport { ETaskState } from \"../models/state.model.js\";\nimport type { ITask } from \"../models/task.model.js\";\n\nlet taskIdCounter = 0;\n\n/**\n * Internal task lifecycle manager responsible for execution, state transitions,\n * AbortSignal coordination, timeout enforcement, and deterministic resource cleanup.\n *\n * @template T - The return type produced by the underlying task.\n */\nexport class TaskRunner<T> {\n /** Unique task identifier */\n public readonly taskId: string;\n\n /** Current lifecycle state */\n private _state: ETaskState = ETaskState.PENDING;\n\n /** Internal AbortController whose signal is passed to the task context */\n private abortController: AbortController;\n\n /** The user task function to execute */\n private readonly task: ITask<T>;\n\n /** User-supplied AbortSignal for external cancellation */\n public readonly externalSignal?: AbortSignal;\n\n /** Maximum execution duration allowed in milliseconds */\n public readonly timeoutMs?: number;\n\n /** Active timeout timer identifier */\n private timeoutTimerId?: ReturnType<typeof setTimeout>;\n\n /** Abort event listener reference for clean detachment */\n private readonly abortListener?: () => void;\n\n /** Promise resolve handler */\n private resolvePromise!: (value: T | PromiseLike<T>) => void;\n\n /** Promise reject handler */\n private rejectPromise!: (reason?: unknown) => void;\n\n /** Deferred promise exposed to the caller */\n public readonly promise: Promise<T>;\n\n /** Callback invoked when runner is cancelled while pending */\n public onCancel?: (runner: TaskRunner<T>) => void;\n\n /** Current execution attempt count (1-indexed) */\n public attempt = 1;\n\n /** Duration of the most recent execution attempt in milliseconds */\n public lastDurationMs = 0;\n\n /** Set of classification tags associated with this task */\n public readonly tags: ReadonlySet<string>;\n\n /**\n * Creates a new TaskRunner instance.\n *\n * @param task - The asynchronous work unit to run.\n * @param externalSignal - Optional external AbortSignal to propagate.\n * @param timeoutMs - Optional maximum execution time in milliseconds.\n * @param tags - Optional array of tags for classifying and selectively cancelling tasks.\n */\n constructor(\n task: ITask<T>,\n externalSignal?: AbortSignal,\n timeoutMs?: number,\n tags?: string[]\n ) {\n this.taskId = `task_${Date.now().toString(36)}_${(++taskIdCounter).toString(36)}_${Math.random().toString(36).slice(2, 6)}`;\n this.task = task;\n this.externalSignal = externalSignal;\n this.timeoutMs = timeoutMs;\n this.tags = new Set(tags ?? []);\n this.abortController = new AbortController();\n\n this.promise = new Promise<T>((resolve, reject) => {\n this.resolvePromise = resolve;\n this.rejectPromise = reject;\n });\n\n if (this.externalSignal) {\n if (this.externalSignal.aborted) {\n this._state = ETaskState.CANCELLED;\n const reason = this.externalSignal.reason;\n const cancelError = new AhkoCancellationError(\n typeof reason === \"string\" ? reason : \"Task was cancelled prior to execution\",\n { cause: reason instanceof Error ? reason : undefined }\n );\n this.abortController.abort(cancelError);\n this.rejectPromise(cancelError);\n } else {\n this.abortListener = () => {\n this.handleExternalAbort();\n };\n this.externalSignal.addEventListener(\"abort\", this.abortListener, { once: true });\n }\n }\n }\n\n /** Flag indicating if runner was aborted by an overall total timeout deadline */\n public totalTimedOut = false;\n\n /**\n * Gets the current lifecycle state of the task.\n */\n public get state(): ETaskState {\n return this._state;\n }\n\n /**\n * Resolves the deferred promise.\n *\n * @param value - Value to resolve with.\n */\n public resolve(value: T): void {\n this.cleanup();\n this.resolvePromise(value);\n }\n\n /**\n * Rejects the deferred promise.\n *\n * @param reason - Reason to reject with.\n */\n public reject(reason: unknown): void {\n this.cleanup();\n this.rejectPromise(reason);\n }\n\n /**\n * Evaluates if the task should be retried following an execution failure or timeout.\n *\n * @param error - The error encountered during the attempt.\n * @param retryOptions - Configured retry policy.\n * @returns A promise resolving to true if retry should proceed, false otherwise.\n */\n public async canRetry(error: unknown, retryOptions?: IRetryOptions): Promise<boolean> {\n if (\n this.totalTimedOut ||\n this._state === ETaskState.CANCELLED ||\n (this.externalSignal?.aborted ?? false)\n ) {\n return false;\n }\n\n if (!retryOptions || typeof retryOptions.attempts !== \"number\") {\n return false;\n }\n\n if (this.attempt >= retryOptions.attempts) {\n return false;\n }\n\n if (typeof retryOptions.shouldRetry === \"function\") {\n try {\n const allowed = await retryOptions.shouldRetry(error, this.attempt);\n if (!allowed) {\n return false;\n }\n } catch {\n return false;\n }\n }\n\n this.attempt++;\n this._state = ETaskState.PENDING;\n this.abortController = new AbortController();\n return true;\n }\n\n /**\n * Executes the task within an allocated concurrency slot.\n *\n * @returns A promise resolving to the task result or rejecting on failure/cancellation/timeout.\n */\n public async run(): Promise<T> {\n if (this._state === ETaskState.CANCELLED) {\n throw new AhkoCancellationError(\"Task was cancelled prior to execution\");\n }\n\n this._state = ETaskState.RUNNING;\n\n const context: ITaskContext = {\n signal: this.abortController.signal,\n taskId: this.taskId,\n };\n\n let abortListener: (() => void) | undefined;\n\n const abortPromise = new Promise<never>((_, reject) => {\n abortListener = () => {\n const reason = this.abortController.signal.reason;\n if (this._state === ETaskState.TIMED_OUT || reason instanceof AhkoTimeoutError) {\n this._state = ETaskState.TIMED_OUT;\n reject(\n reason instanceof AhkoTimeoutError\n ? reason\n : new AhkoTimeoutError(\n `Task execution timed out after ${this.timeoutMs}ms`,\n { timeoutMs: this.timeoutMs }\n )\n );\n } else {\n reject(\n new AhkoCancellationError(\"Task was cancelled during execution\", {\n cause: reason instanceof Error ? reason : undefined,\n })\n );\n }\n };\n this.abortController.signal.addEventListener(\"abort\", abortListener, { once: true });\n });\n\n let timeoutPromise: Promise<never> | undefined;\n if (this.timeoutMs !== undefined) {\n timeoutPromise = new Promise<never>((_, reject) => {\n this.timeoutTimerId = setTimeout(() => {\n if (this._state !== ETaskState.RUNNING) {\n return;\n }\n this._state = ETaskState.TIMED_OUT;\n const timeoutError = new AhkoTimeoutError(\n `Task execution timed out after ${this.timeoutMs}ms`,\n { timeoutMs: this.timeoutMs }\n );\n this.abortController.abort(timeoutError);\n reject(timeoutError);\n }, this.timeoutMs);\n });\n }\n\n let taskExecutionPromise: Promise<T>;\n try {\n taskExecutionPromise = Promise.resolve(this.task(context));\n } catch (syncError) {\n taskExecutionPromise = Promise.reject(syncError);\n }\n\n // Suppress unhandled rejection in background if task finishes or fails after timeout/cancellation\n taskExecutionPromise.catch(() => {});\n abortPromise.catch(() => {});\n timeoutPromise?.catch(() => {});\n\n const racePromises: Array<Promise<T | never>> = [\n taskExecutionPromise,\n abortPromise,\n ];\n if (timeoutPromise) {\n racePromises.push(timeoutPromise);\n }\n\n const startTime = Date.now();\n\n try {\n const result = await Promise.race(racePromises);\n this.clearTimeoutTimer();\n this.lastDurationMs = Math.max(0, Date.now() - startTime);\n if (abortListener) {\n this.abortController.signal.removeEventListener(\"abort\", abortListener);\n }\n\n if ((this._state as ETaskState) === ETaskState.TIMED_OUT) {\n throw new AhkoTimeoutError(\n `Task execution timed out after ${this.timeoutMs}ms`,\n { timeoutMs: this.timeoutMs }\n );\n }\n\n if ((this._state as ETaskState) === ETaskState.CANCELLED) {\n throw new AhkoCancellationError(\"Task was cancelled during execution\");\n }\n\n this._state = ETaskState.COMPLETED;\n return result;\n } catch (error) {\n this.clearTimeoutTimer();\n this.lastDurationMs = Math.max(0, Date.now() - startTime);\n if (abortListener) {\n this.abortController.signal.removeEventListener(\"abort\", abortListener);\n }\n\n if ((this._state as ETaskState) === ETaskState.TIMED_OUT || error instanceof AhkoTimeoutError) {\n this._state = ETaskState.TIMED_OUT;\n if (error instanceof AhkoTimeoutError) {\n throw error;\n }\n throw new AhkoTimeoutError(\n `Task execution timed out after ${this.timeoutMs}ms`,\n {\n timeoutMs: this.timeoutMs,\n cause: error instanceof Error ? error : undefined,\n }\n );\n }\n\n const isCancelled =\n (this._state as ETaskState) === ETaskState.CANCELLED ||\n this.abortController.signal.aborted ||\n (this.externalSignal?.aborted ?? false);\n\n if (isCancelled) {\n this._state = ETaskState.CANCELLED;\n if (error instanceof AhkoCancellationError) {\n throw error;\n }\n throw new AhkoCancellationError(\"Task was cancelled during execution\", {\n cause: error instanceof Error ? error : undefined,\n });\n }\n\n this._state = ETaskState.FAILED;\n throw error;\n }\n }\n\n /**\n * Clears the active timeout timer.\n */\n private clearTimeoutTimer(): void {\n if (this.timeoutTimerId !== undefined) {\n clearTimeout(this.timeoutTimerId);\n this.timeoutTimerId = undefined;\n }\n }\n\n /**\n * Cancels the task, aborting pending or running execution.\n *\n * @param reason - Optional cancellation reason.\n */\n public cancel(reason?: unknown): void {\n if (\n this._state === ETaskState.COMPLETED ||\n this._state === ETaskState.FAILED ||\n this._state === ETaskState.CANCELLED ||\n this._state === ETaskState.TIMED_OUT\n ) {\n return;\n }\n\n const wasPending = this._state === ETaskState.PENDING;\n this._state = ETaskState.CANCELLED;\n this.clearTimeoutTimer();\n this.abortController.abort(reason);\n this.cleanup();\n\n if (wasPending) {\n const cancellationError = new AhkoCancellationError(\n typeof reason === \"string\" ? reason : \"Task was cancelled prior to execution\",\n { cause: reason instanceof Error ? reason : undefined }\n );\n this.rejectPromise(cancellationError);\n this.onCancel?.(this);\n }\n }\n\n /**\n * Times out the task, aborting pending or running execution with AhkoTimeoutError.\n *\n * @param timeoutMs - Timeout duration in milliseconds.\n * @param message - Optional custom timeout message.\n */\n public timeout(timeoutMs: number, message?: string): void {\n if (\n this._state === ETaskState.COMPLETED ||\n this._state === ETaskState.FAILED ||\n this._state === ETaskState.CANCELLED ||\n this._state === ETaskState.TIMED_OUT\n ) {\n return;\n }\n\n const wasPending = this._state === ETaskState.PENDING;\n this._state = ETaskState.TIMED_OUT;\n this.totalTimedOut = true;\n this.clearTimeoutTimer();\n const timeoutError = new AhkoTimeoutError(\n message ?? `Task execution timed out after ${timeoutMs}ms`,\n { timeoutMs }\n );\n this.abortController.abort(timeoutError);\n this.cleanup();\n\n if (wasPending) {\n this.rejectPromise(timeoutError);\n this.onCancel?.(this);\n }\n }\n\n /**\n * Handles external AbortSignal trigger.\n */\n private handleExternalAbort(): void {\n this.cancel(this.externalSignal?.reason);\n }\n\n /**\n * Detaches event listeners from external signal to guarantee memory safety.\n */\n public cleanup(): void {\n this.clearTimeoutTimer();\n if (this.externalSignal && this.abortListener) {\n this.externalSignal.removeEventListener(\"abort\", this.abortListener);\n }\n }\n}\n","import { AhkoCancellationError } from \"./errors/cancellation.error.js\";\nimport { AhkoConfigurationError } from \"./errors/configuration.error.js\";\nimport {\n getActiveConfig,\n getProfileConfig,\n loadConfig,\n loadConfigFile,\n resetConfig,\n} from \"./config/config-loader.js\";\nimport type { IBatchOptions, IBatchMapOptions } from \"./models/batch.model.js\";\nimport type { ECircuitState } from \"./models/circuit-breaker.model.js\";\nimport type { IAhkoFileConfig, IAhkoProfileConfig } from \"./models/config.model.js\";\nimport type { ITaskContext } from \"./models/context.model.js\";\nimport type { TAhkoEventName, TAhkoEventHandler, TAhkoUnsubscribe } from \"./models/events.model.js\";\nimport type { IAhkoOptions, IScheduleOptions } from \"./models/options.model.js\";\nimport type { IAhkoStats } from \"./models/stats.model.js\";\nimport { EScheduleStrategy } from \"./models/strategy.model.js\";\nimport type { ITask } from \"./models/task.model.js\";\nimport type { CircuitBreakerCoordinator } from \"./scheduler/circuit-breaker.js\";\nimport { TaskQueue } from \"./scheduler/task-queue.js\";\nimport { TaskRunner } from \"./scheduler/task-runner.js\";\n\n/**\n * Ahko — Low-energy asynchronous task scheduler.\n *\n * Coordinates execution timing, enforces concurrency limits, manages priorities,\n * provides circuit-breaker stability, supports pause/resume flow control,\n * and cooperates natively with AbortSignal cancellation.\n *\n * @example\n * ```typescript\n * import { Ahko } from \"@mrjacket/ahko\";\n *\n * const ahko = new Ahko({ concurrency: 2 });\n *\n * const result = await ahko.schedule(async ({ signal, taskId }) => {\n * const res = await fetch(\"https://api.example.com\", { signal });\n * return res.json();\n * });\n * ```\n */\nexport class Ahko {\n /** Internal queue and concurrency manager */\n private readonly queue: TaskQueue;\n\n /** Default schedule options inherited from profile if configured */\n private readonly defaultScheduleOptions?: Partial<IScheduleOptions>;\n\n /**\n * Programmatically loads a declarative configuration into memory.\n * Works universally across Node.js, browsers, and edge runtimes.\n *\n * @param config - File configuration object containing default and named profiles.\n */\n public static loadConfig(config: IAhkoFileConfig): void {\n loadConfig(config);\n }\n\n /**\n * Asynchronously loads a configuration file from disk (Node.js).\n *\n * @param filePath - Path to configuration file (default: \"config.ahko.json\").\n */\n public static async loadConfigFile(filePath?: string): Promise<IAhkoFileConfig | undefined> {\n return loadConfigFile(filePath);\n }\n\n /**\n * Resets the active declarative configuration.\n */\n public static resetConfig(): void {\n resetConfig();\n }\n\n /**\n * Retrieves the currently active declarative configuration.\n */\n public static getActiveConfig(): IAhkoFileConfig | undefined {\n return getActiveConfig();\n }\n\n /**\n * Instantiates an Ahko scheduler initialized with settings from a declarative profile.\n *\n * @param profileName - Optional name of the profile (e.g. \"api\", \"background\").\n * @param overrides - Optional scheduler options overriding profile values.\n * @returns A new configured Ahko instance.\n */\n public static fromProfile(profileName?: string, overrides?: IAhkoOptions): Ahko {\n const profile = getProfileConfig(profileName);\n return new Ahko({\n ...profile,\n ...overrides,\n circuitBreaker: overrides?.circuitBreaker ?? profile?.circuitBreaker,\n adaptive: overrides?.adaptive ?? profile?.adaptive,\n });\n }\n\n /**\n * Initializes a new Ahko scheduler instance.\n *\n * @param options - Optional scheduler configuration.\n * @throws {AhkoConfigurationError} If concurrency is invalid (less than 1 or NaN).\n *\n * @example\n * ```typescript\n * const ahko = new Ahko({ concurrency: 4 });\n * ```\n */\n constructor(options?: IAhkoOptions) {\n const profile = options?.profile ? getProfileConfig(options.profile) : getProfileConfig();\n\n const mergedOptions: IAhkoOptions = {\n ...profile,\n ...options,\n circuitBreaker: options?.circuitBreaker ?? profile?.circuitBreaker,\n adaptive: options?.adaptive ?? profile?.adaptive,\n };\n\n if (profile) {\n this.defaultScheduleOptions = {\n priority: profile.priority,\n retry: profile.retry,\n timeoutMs: profile.timeoutMs,\n totalTimeoutMs: profile.totalTimeoutMs,\n tags: profile.tags,\n };\n }\n\n this.queue = new TaskQueue(\n mergedOptions.concurrency,\n mergedOptions.minIntervalMs,\n mergedOptions.circuitBreaker,\n mergedOptions.adaptive\n );\n }\n\n /**\n * Current concurrency limit.\n */\n public get concurrency(): number {\n return this.queue.concurrency;\n }\n\n /**\n * Dynamically updates the concurrency limit of the scheduler.\n *\n * @param concurrency - New maximum concurrency (must be >= 1).\n * @throws {AhkoConfigurationError} If concurrency is invalid.\n */\n public setConcurrency(concurrency: number): void {\n this.queue.setConcurrency(concurrency);\n }\n\n /**\n * Pauses scheduler dispatch. In-flight tasks run to completion, but pending tasks remain queued.\n */\n public pause(): void {\n this.queue.pause();\n }\n\n /**\n * Resumes scheduler dispatch, immediately executing waiting tasks up to available concurrency.\n */\n public resume(): void {\n this.queue.resume();\n }\n\n /**\n * Checks whether the scheduler is currently paused.\n */\n public isPaused(): boolean {\n return this.queue.isPaused();\n }\n\n /**\n * Current circuit breaker state if circuit breaker protection is configured.\n */\n public get circuitState(): ECircuitState | undefined {\n return this.queue.circuitBreakerCoordinator?.state;\n }\n\n /**\n * Access to the underlying circuit breaker coordinator instance if configured.\n */\n public get circuitBreaker(): CircuitBreakerCoordinator | undefined {\n return this.queue.circuitBreakerCoordinator;\n }\n\n /**\n * Wraps an async function so every execution is automatically routed through this Ahko scheduler.\n *\n * @template TArgs - Parameter types of the wrapped function.\n * @template TReturn - Return type of the wrapped function.\n * @param fn - The function to wrap.\n * @param options - Optional scheduling options applied to every wrapped call.\n * @returns A wrapped function returning a Promise.\n *\n * @example\n * ```typescript\n * const fetchUser = ahko.wrap(async (id: string) => api.getUser(id), { priority: \"high\" });\n * const user = await fetchUser(\"usr_123\");\n * ```\n */\n public wrap<TArgs extends unknown[], TReturn>(\n fn: (...args: TArgs) => Promise<TReturn> | TReturn,\n options?: IScheduleOptions\n ): (...args: TArgs) => Promise<TReturn> {\n if (typeof fn !== \"function\") {\n throw new AhkoConfigurationError(\"Target to wrap must be a valid function.\");\n }\n return (...args: TArgs) => {\n return this.schedule(() => fn(...args), options);\n };\n }\n\n /**\n * Schedules a task for execution with full return type inference.\n *\n * @template T - Inferred return type of the task.\n * @param task - Asynchronous or synchronous task function accepting an {@link ITaskContext}.\n * @param options - Task-specific scheduling options such as strategy, priority, delay, and cancellation signal.\n * @returns A promise that resolves with the task's return value.\n *\n * @throws {AhkoConfigurationError} If the task is not a function or options are invalid.\n * @throws {AhkoCancellationError} If the task is cancelled prior to or during execution.\n * @throws {AhkoTimeoutError} If task execution exceeds timeoutMs or totalTimeoutMs.\n * @throws {AhkoCircuitBreakerOpenError} If the circuit breaker is OPEN and rejects the execution.\n *\n * @example\n * ```typescript\n * // Immediate execution (subject to concurrency)\n * const count = await ahko.schedule(async () => 42);\n *\n * // High priority task\n * await ahko.schedule(doUrgentWork, { priority: \"high\" });\n * ```\n */\n public schedule<T>(task: ITask<T>, options?: IScheduleOptions): Promise<T> {\n if (typeof task !== \"function\") {\n throw new AhkoConfigurationError(\"Task must be a valid function.\");\n }\n\n const mergedTags = options?.tags ?? this.defaultScheduleOptions?.tags;\n const mergedOptions: IScheduleOptions = {\n ...this.defaultScheduleOptions,\n ...options,\n tags: mergedTags,\n };\n\n const strategy = mergedOptions.strategy ?? EScheduleStrategy.IMMEDIATE;\n\n if (strategy === EScheduleStrategy.DEBOUNCE) {\n if (!mergedOptions.key || (typeof mergedOptions.key !== \"string\" && typeof mergedOptions.key !== \"symbol\")) {\n throw new AhkoConfigurationError(\n `Strategy \"debounce\" requires a valid \"key\" of type string or symbol.`\n );\n }\n const waitMs = mergedOptions.waitMs ?? mergedOptions.delay;\n if (typeof waitMs !== \"number\" || Number.isNaN(waitMs) || !Number.isFinite(waitMs) || waitMs < 0) {\n throw new AhkoConfigurationError(\n `Strategy \"debounce\" requires a non-negative finite \"waitMs\" or \"delay\" in milliseconds.`\n );\n }\n return this.queue.debounceCoordinator.schedule(\n mergedOptions.key,\n task,\n waitMs,\n mergedOptions,\n (t, opts) => this.schedule(t, { ...opts, strategy: EScheduleStrategy.IMMEDIATE })\n );\n }\n\n if (strategy === EScheduleStrategy.THROTTLE) {\n if (!mergedOptions.key || (typeof mergedOptions.key !== \"string\" && typeof mergedOptions.key !== \"symbol\")) {\n throw new AhkoConfigurationError(\n `Strategy \"throttle\" requires a valid \"key\" of type string or symbol.`\n );\n }\n const waitMs = mergedOptions.waitMs ?? mergedOptions.delay;\n if (typeof waitMs !== \"number\" || Number.isNaN(waitMs) || !Number.isFinite(waitMs) || waitMs < 0) {\n throw new AhkoConfigurationError(\n `Strategy \"throttle\" requires a non-negative finite \"waitMs\" or \"delay\" in milliseconds.`\n );\n }\n return this.queue.throttleCoordinator.schedule(\n mergedOptions.key,\n task,\n waitMs,\n mergedOptions,\n (t, opts) => this.schedule(t, { ...opts, strategy: EScheduleStrategy.IMMEDIATE })\n );\n }\n\n const runner = new TaskRunner<T>(\n task,\n mergedOptions.signal,\n mergedOptions.timeoutMs,\n mergedOptions.tags\n );\n return this.queue.enqueue(runner, mergedOptions);\n }\n\n /**\n * Convenience method to schedule a task during platform idle opportunities.\n *\n * Equivalent to calling `schedule(task, { ...options, strategy: \"idle\" })`.\n * In browsers, uses `requestIdleCallback` when available.\n * In Node.js, uses `setImmediate`.\n * Falls back to `setTimeout(..., 0)` if neither is available.\n *\n * @template T - Inferred return type of the task.\n * @param task - Task function to run when idle.\n * @param options - Scheduling options (excluding strategy).\n * @returns A promise resolving to the task's return value.\n *\n * @throws {AhkoConfigurationError} If the task is not a function or options are invalid.\n * @throws {AhkoCancellationError} If the task is cancelled prior to or during execution.\n */\n public idle<T>(\n task: ITask<T>,\n options?: Omit<IScheduleOptions, \"strategy\">\n ): Promise<T> {\n return this.schedule(task, {\n ...options,\n strategy: EScheduleStrategy.IDLE,\n });\n }\n\n /**\n * Convenience method to schedule a debounced task with key-based Promise coalescing.\n *\n * @template T - Inferred return type of the task.\n * @param key - Explicit identity key.\n * @param task - Work to execute once calls stop arriving.\n * @param waitMs - Quiet window duration in milliseconds.\n * @param options - Additional schedule options.\n * @returns Shared promise resolving with the final execution outcome.\n */\n public debounce<T>(\n key: string | symbol,\n task: ITask<T>,\n waitMs: number,\n options?: Omit<IScheduleOptions, \"strategy\" | \"key\" | \"waitMs\">\n ): Promise<T> {\n return this.schedule(task, {\n ...options,\n strategy: EScheduleStrategy.DEBOUNCE,\n key,\n waitMs,\n });\n }\n\n /**\n * Convenience method to schedule a throttled task with leading execution and coalesced trailing run.\n *\n * @template T - Inferred return type of the task.\n * @param key - Explicit identity key.\n * @param task - Work to execute.\n * @param waitMs - Throttle interval duration in milliseconds.\n * @param options - Additional schedule options.\n * @returns Promise resolving with the leading or coalesced trailing result.\n */\n public throttle<T>(\n key: string | symbol,\n task: ITask<T>,\n waitMs: number,\n options?: Omit<IScheduleOptions, \"strategy\" | \"key\" | \"waitMs\">\n ): Promise<T> {\n return this.schedule(task, {\n ...options,\n strategy: EScheduleStrategy.THROTTLE,\n key,\n waitMs,\n });\n }\n\n /**\n * Transforms an iterable of items concurrently using an asynchronous mapping function.\n *\n * Results are guaranteed to be returned in the original index order.\n * Concurrency can be capped per-batch or fall back to the scheduler's global limit.\n *\n * @template TItem - Type of input elements.\n * @template TResult - Type of mapped elements.\n * @param items - Iterable sequence of items to process.\n * @param fn - Mapper callback receiving item, index, and task context.\n * @param options - Batch execution options (concurrency, stopOnError, retry, signal, tags, etc.).\n * @returns Array of transformed results in index order.\n *\n * @throws {AhkoConfigurationError} If fn is not a function or concurrency is invalid.\n * @throws {AhkoCancellationError} If batch or item is cancelled.\n *\n * @example\n * ```typescript\n * const urls = [\"/api/1\", \"/api/2\", \"/api/3\"];\n * const data = await ahko.map(urls, async (url, i, { signal }) => {\n * const res = await fetch(url, { signal });\n * return res.json();\n * }, { concurrency: 2 });\n * ```\n */\n public async map<TItem, TResult>(\n items: Iterable<TItem>,\n fn: (item: TItem, index: number, context: ITaskContext) => Promise<TResult> | TResult,\n options?: IBatchMapOptions<TItem, TResult>\n ): Promise<TResult[]> {\n if (typeof fn !== \"function\") {\n throw new AhkoConfigurationError(\"Mapper function must be a valid function.\");\n }\n\n if (\n options?.concurrency !== undefined &&\n (typeof options.concurrency !== \"number\" ||\n Number.isNaN(options.concurrency) ||\n options.concurrency < 1)\n ) {\n throw new AhkoConfigurationError(\n `Invalid concurrency \"${options.concurrency}\". Must be a number greater than or equal to 1.`\n );\n }\n\n const list = Array.from(items);\n if (list.length === 0) {\n return [];\n }\n\n const { concurrency, stopOnError = false, signal: externalSignal, ...scheduleOpts } =\n options ?? {};\n\n if (externalSignal?.aborted) {\n throw new AhkoCancellationError(\n externalSignal.reason ? `Batch cancelled: ${String(externalSignal.reason)}` : \"Batch cancelled\"\n );\n }\n\n const abortController = new AbortController();\n\n const results = new Array<TResult>(list.length);\n let firstError: unknown = undefined;\n let hasAborted = false;\n\n const localizedLimit =\n concurrency !== undefined\n ? Math.floor(concurrency)\n : Number.isFinite(this.concurrency)\n ? this.concurrency\n : Infinity;\n\n return new Promise<TResult[]>((resolve, reject) => {\n let currentIndex = 0;\n let activeCount = 0;\n let settledCount = 0;\n\n const onExternalAbort = () => {\n const reason = externalSignal?.reason ?? \"Batch cancelled by external signal\";\n const err = new AhkoCancellationError(\n typeof reason === \"string\" ? reason : \"Batch cancelled by external signal\"\n );\n cleanupAndReject(err);\n };\n\n if (externalSignal) {\n externalSignal.addEventListener(\"abort\", onExternalAbort, { once: true });\n }\n\n const cleanupAndReject = (err: unknown) => {\n if (!hasAborted) {\n hasAborted = true;\n abortController.abort(err);\n }\n if (externalSignal) {\n externalSignal.removeEventListener(\"abort\", onExternalAbort);\n }\n reject(err);\n };\n\n const checkCompletion = () => {\n if (settledCount === list.length) {\n if (externalSignal) {\n externalSignal.removeEventListener(\"abort\", onExternalAbort);\n }\n if (firstError !== undefined) {\n reject(firstError);\n } else {\n resolve(results);\n }\n }\n };\n\n const launchNext = () => {\n if (hasAborted && stopOnError) {\n return;\n }\n\n while (\n currentIndex < list.length &&\n activeCount < localizedLimit &&\n !(hasAborted && stopOnError)\n ) {\n const index = currentIndex++;\n const item = list[index];\n activeCount++;\n\n const taskPromise = this.schedule(\n (context) => fn(item, index, context),\n {\n ...scheduleOpts,\n signal: abortController.signal,\n }\n );\n\n taskPromise\n .then((result) => {\n results[index] = result;\n })\n .catch((err) => {\n if (firstError === undefined) {\n firstError = err;\n }\n if (stopOnError && !hasAborted) {\n cleanupAndReject(err);\n return;\n }\n })\n .finally(() => {\n activeCount--;\n settledCount++;\n if (hasAborted && stopOnError) {\n return;\n }\n if (currentIndex < list.length) {\n launchNext();\n } else {\n checkCompletion();\n }\n });\n }\n };\n\n if (abortController.signal.aborted) {\n cleanupAndReject(abortController.signal.reason);\n return;\n }\n\n launchNext();\n });\n }\n\n /**\n * Iterates sequentially or concurrently over an iterable sequence of items,\n * executing the callback function for each element.\n *\n * @template TItem - Type of input elements.\n * @param items - Iterable sequence of items to process.\n * @param fn - Callback receiving item, index, and task context.\n * @param options - Batch execution options.\n * @returns Promise resolving once all items have finished executing.\n *\n * @example\n * ```typescript\n * await ahko.each(userQueue, async (user, index, { signal }) => {\n * await sendWelcomeEmail(user, { signal });\n * }, { concurrency: 5 });\n * ```\n */\n public async each<TItem>(\n items: Iterable<TItem>,\n fn: (item: TItem, index: number, context: ITaskContext) => Promise<void> | void,\n options?: IBatchOptions\n ): Promise<void> {\n await this.map(items, fn, options);\n }\n\n /**\n * Cancels all pending, delayed, and active tasks tagged with the given tag.\n *\n * @param tag - Tag identifier.\n * @param reason - Optional cancellation reason.\n * @returns Total number of tasks cancelled.\n */\n public cancelByTag(tag: string, reason?: unknown): number {\n return this.queue.cancelByTag(tag, reason);\n }\n\n /**\n * Retrieves active and pending task counts for a given tag.\n *\n * @param tag - Tag identifier.\n * @returns Object with activeTasks and pendingTasks counts.\n */\n public statsByTag(tag: string): { activeTasks: number; pendingTasks: number } {\n return this.queue.getStatsByTag(tag);\n }\n\n /**\n * Retrieves real-time telemetry metrics from the scheduler.\n *\n * @returns An {@link IAhkoStats} snapshot of active, pending, completed, failed, cancelled, timed out tasks, pause status, and circuit state.\n *\n * @example\n * ```typescript\n * const stats = ahko.stats();\n * console.log(`Active: ${stats.activeTasks}, Pending: ${stats.pendingTasks}, Paused: ${stats.isPaused}`);\n * ```\n */\n public stats(): IAhkoStats {\n return this.queue.getStats();\n }\n\n /**\n * Subscribes to a scheduler lifecycle event.\n *\n * @param event - Event name to listen for.\n * @param handler - Callback function invoked when the event is emitted.\n * @returns Unsubscribe function to remove the listener.\n *\n * @example\n * ```typescript\n * const unsubscribe = ahko.on(\"task:start\", ({ taskId, attempt }) => {\n * console.log(`Task ${taskId} started attempt ${attempt}`);\n * });\n * ```\n */\n public on<K extends TAhkoEventName>(event: K, handler: TAhkoEventHandler<K>): TAhkoUnsubscribe {\n return this.queue.emitter.on(event, handler);\n }\n\n /**\n * Unsubscribes an event listener from a scheduler lifecycle event.\n *\n * @param event - Event name.\n * @param handler - The exact listener callback to remove.\n */\n public off<K extends TAhkoEventName>(event: K, handler: TAhkoEventHandler<K>): void {\n this.queue.emitter.off(event, handler);\n }\n\n /**\n * Checks whether the scheduler is currently idle (no active runners and no pending tasks).\n *\n * @returns True if completely idle, false otherwise.\n */\n public isIdle(): boolean {\n return this.queue.isIdle();\n }\n\n /**\n * Returns a promise that resolves once the scheduler has completed all tasks and is idle.\n *\n * @returns Promise resolving when the scheduler is idle.\n *\n * @example\n * ```typescript\n * ahko.schedule(doWork);\n * await ahko.onIdle();\n * console.log(\"All work finished!\");\n * ```\n */\n public onIdle(): Promise<void> {\n return this.queue.onIdle();\n }\n\n /**\n * Clears all pending, delayed, and throttled/debounced tasks from the scheduler.\n * In-flight active tasks will continue executing to completion or abort via signal.\n */\n public clear(): void {\n this.queue.clear();\n }\n\n /**\n * Returns the delightful Ahko mascot battery telemetry status.\n *\n * Low energy, completely chill.\n */\n public battery(): { level: number; chill: boolean; status: string; quote: string } {\n return {\n level: 3,\n chill: true,\n status: \"low-energy\",\n quote: \"Mwee... my battery is low, but all your tasks are handled completely chill.\",\n };\n }\n\n /**\n * Delightful alias for `onIdle()`: wait for all tasks to settle chill and relaxed.\n *\n * @returns Promise resolving when all tasks have finished.\n */\n public chill(): Promise<void> {\n return this.onIdle();\n }\n}\n","/**\n * Current version of @mrjacket/ahko package.\n */\nexport const VERSION = \"1.1.5\";\n","import { AhkoError } from \"./ahko.error.js\";\n\n/**\n * Thrown when an internal queue invariant is violated or queue limits are breached.\n */\nexport class AhkoQueueError extends AhkoError {\n /**\n * Creates a new AhkoQueueError.\n *\n * @param message - Explanation of the queue failure.\n * @param options - Standard Error options including cause.\n */\n constructor(message: string, options?: ErrorOptions) {\n super(message, options);\n this.name = \"AhkoQueueError\";\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n","/**\n * Result of combining multiple AbortSignals.\n */\nexport interface ICombinedSignal {\n /**\n * The unified AbortSignal that aborts when any source signal aborts.\n */\n readonly signal: AbortSignal;\n\n /**\n * Detaches all registered event listeners from source signals to prevent memory leaks.\n */\n cleanup: () => void;\n}\n\n/**\n * Combines multiple AbortSignals into a single coordinated AbortSignal with deterministic cleanup.\n *\n * @param signals - Array of source AbortSignals (undefined entries are ignored).\n * @returns A unified signal interface with explicit cleanup callback.\n */\nexport function combineSignals(\n signals: ReadonlyArray<AbortSignal | undefined>\n): ICombinedSignal {\n const activeSignals = signals.filter(\n (signal): signal is AbortSignal => signal !== undefined\n );\n\n if (activeSignals.length === 0) {\n const controller = new AbortController();\n return {\n signal: controller.signal,\n cleanup: () => {},\n };\n }\n\n // Check if any source signal is already aborted\n const alreadyAborted = activeSignals.find((s) => s.aborted);\n if (alreadyAborted) {\n const controller = new AbortController();\n controller.abort(alreadyAborted.reason);\n return {\n signal: controller.signal,\n cleanup: () => {},\n };\n }\n\n if (activeSignals.length === 1) {\n return {\n signal: activeSignals[0],\n cleanup: () => {},\n };\n }\n\n const controller = new AbortController();\n const cleanupFns: Array<() => void> = [];\n\n const onAbort = (event: Event): void => {\n const target = event.target as AbortSignal;\n cleanup();\n controller.abort(target.reason);\n };\n\n for (const sig of activeSignals) {\n sig.addEventListener(\"abort\", onAbort, { once: true });\n cleanupFns.push(() => {\n sig.removeEventListener(\"abort\", onAbort);\n });\n }\n\n const cleanup = (): void => {\n for (const fn of cleanupFns) {\n fn();\n }\n cleanupFns.length = 0;\n };\n\n return {\n signal: controller.signal,\n cleanup,\n };\n}\n"],"mappings":"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","names":["EScheduleStrategy","ETaskState","ECircuitState","controller"]}
|