import { PeriodicJob, CalculateDelayTillNextExecution } from './types';
/**
 * NonOverlappingPeriodicJobScheduler
 *
 * This class implements a slim periodic-job scheduler, focusing on three aspects often overlooked:
 * 1. **Non-overlapping executions**.
 * 2. **Deterministic termination**.
 * 3. **Dynamic delay between executions**.
 *
 * ## Non-Overlapping Executions
 * Ensures that executions do not overlap. This is suitable for scenarios where overlapping executions
 * may cause race conditions or negatively impact performance.
 *
 * ## Deterministic / Graceful Termination
 * When stopping periodic executions, it is crucial to ensure that any ongoing execution is completed
 * before termination. This deterministic termination approach ensures that no unfinished executions
 * leave objects in memory, which could otherwise lead to unexpected behavior.
 * Without deterministic termination, leftover references from incomplete executions can cause
 * issues, such as unexpected behavior during unit tests. A clean state is necessary for each test,
 * and ongoing jobs from a previous test can interfere with subsequent tests.
 *
 * ## Dynamic Execution Interval
 * User provides a custom calculator function, to determine the delay until the next execution, based on
 * the runtime metadata of the just-finished execution (duration, error if thrown).
 * This calculator is invoked at the **end** of each execution, enabling flexible interval policies based
 * on user-defined criteria. This approach ensures that the scheduler remains agnostic of scheduling-policy
 * preferences, focusing solely on the scheduling process. In this way, we adhere to the following principles:
 * 1. **Information Expert Principle**: The interval policy is defined by the user.
 * 2. **Single Responsibility Principle**: The scheduler's sole responsibility is to manage the scheduling
 *    process.
 *
 * ## Zero Over-Engineering, No External Dependencies
 * `setInterval` often falls short with fixed intervals, overlapping executions, and non-deterministic
 * termination of the last execution. Custom solutions or external libraries usually come with numerous
 * runtime dependencies, which can unnecessarily increase the project's size.
 * This class offers a lightweight, dependency-free solution. It can also serve as a building block for
 * more advanced implementations, if necessary.
 *
 * ## Error Handling
 * If a periodic job throws an error, the error will be passed to the calculator function. The scheduler
 * does *not* perform any logging, as it is designed to be agnostic of user preferences, such as specific
 * loggers or logging styles.
 *
 * ## Tests
 * This class is fully covered by extensive unit tests.
 *
 */
export declare class NonOverlappingPeriodicJobScheduler<JobError = Error> {
    private readonly _periodicJob;
    private readonly _calculateDelayTillNextExecution;
    private _isStopped;
    private _nextExecutionTimer;
    private _currentExecutionPromise;
    private readonly _triggerExecution;
    /**
     * constructor
     *
     * @param _periodicJob A periodic job.
     * @param _calculateDelayTillNextExecution Function to calculate the delay until the
     *                                         next execution, based on the duration and
     *                                         any error thrown by the previous execution.
     */
    constructor(_periodicJob: PeriodicJob, _calculateDelayTillNextExecution: CalculateDelayTillNextExecution<JobError>);
    /**
     * isCurrentlyExecuting
     *
     * Indicates whether the periodic job is actively running, as opposed to being between executions.
     *
     * @returns `true` if the periodic job is currently executing, otherwise `false`.
     */
    get isCurrentlyExecuting(): boolean;
    /**
     * isStopped
     *
     * Indicates whether the instance is currently *not* managing periodic executions.
     *
     * @returns `true` if the instance has no periodic executions currently scheduled
     *          or in progress, otherwise `false`.
     */
    get isStopped(): boolean;
    /**
     * start
     *
     * Initiates the scheduling of periodic jobs.
     */
    start(): void;
    /**
     * waitUntilCurrentExecutionCompletes
     *
     * Resolves when the current execution completes, whether it resolves or rejects, if
     * called during an ongoing execution. If no execution is in progress, it resolves immediately.
     */
    waitUntilCurrentExecutionCompletes(): Promise<void>;
    /**
     * stop
     *
     * Stops the scheduling of periodic jobs. If this method is invoked during an ongoing execution,
     * it resolves once the current execution is complete. This guarantee provides determinism and
     * allows for graceful termination.
     */
    stop(): Promise<void>;
    private _triggerCurrentExecutionAndScheduleNext;
}
