import { TypedEventEmitter } from 'main-event';
import { Job } from './job.ts';
import type { AbortOptions, Metrics } from '@libp2p/interface';
import type { ProgressOptions } from 'progress-events';
export type { Job, JobTimeline } from './job.ts';
export type { JobRecipient } from './recipient.ts';
export interface Comparator<T> {
    (a: T, b: T): -1 | 0 | 1;
}
export interface QueueInit<JobReturnType, JobOptions extends AbortOptions = AbortOptions> {
    /**
     * Concurrency limit.
     *
     * Minimum: `1`.
     *
     * @default Infinity
     */
    concurrency?: number;
    /**
     * If the queue size grows to larger than this number the promise returned
     * from the add function will reject
     *
     * @default Infinity
     */
    maxSize?: number;
    /**
     * The name of the metric for the queue length
     */
    metricName?: string;
    /**
     * An implementation of the libp2p Metrics interface
     */
    metrics?: Metrics;
    /**
     * An optional function that will sort the queue after a job has been added
     */
    sort?: Comparator<Job<JobOptions, JobReturnType>>;
}
export type JobStatus = 'queued' | 'running' | 'errored' | 'complete';
export interface RunFunction<Options extends AbortOptions = AbortOptions, ReturnType = void> {
    (options: Options): Promise<ReturnType>;
}
export interface JobMatcher<JobOptions extends AbortOptions = AbortOptions> {
    (options?: Partial<JobOptions>): boolean;
}
export interface QueueJobSuccess<JobReturnType, JobOptions extends AbortOptions = AbortOptions> {
    job: Job<JobOptions, JobReturnType>;
    result: JobReturnType;
}
export interface QueueJobFailure<JobReturnType, JobOptions extends AbortOptions = AbortOptions> {
    job: Job<JobOptions, JobReturnType>;
    error: Error;
}
export interface QueueEvents<JobReturnType, JobOptions extends AbortOptions = AbortOptions> {
    /**
     * A job is about to start running
     */
    active: CustomEvent;
    /**
     * All jobs have finished and the queue is empty
     */
    idle: CustomEvent;
    /**
     * The queue is empty, jobs may be running
     */
    empty: CustomEvent;
    /**
     * A job was added to the queue
     */
    add: CustomEvent;
    /**
     * A job has finished or failed
     */
    next: CustomEvent;
    /**
     * A job has finished successfully
     */
    completed: CustomEvent<JobReturnType>;
    /**
     * Emitted just after `"completed", a job has finished successfully - this
     * event gives access to the job and it's result
     */
    success: CustomEvent<QueueJobSuccess<JobReturnType, JobOptions>>;
    /**
     * Emitted just after `"error", a job has failed - this event gives access to
     * the job and the thrown error
     */
    failure: CustomEvent<QueueJobFailure<JobReturnType, JobOptions>>;
}
/**
 * Heavily influence by `p-queue` with the following differences:
 *
 * 1. Items remain at the head of the queue while they are running so `queue.size` includes `queue.pending` items - this is so interested parties can join the results of a queue item while it is running
 * 2. The options for a job are stored separately to the job in order for them to be modified while they are still in the queue
 */
export declare class Queue<JobReturnType = unknown, JobOptions extends AbortOptions & ProgressOptions = AbortOptions> extends TypedEventEmitter<QueueEvents<JobReturnType, JobOptions>> {
    concurrency: number;
    maxSize: number;
    queue: Array<Job<JobOptions, JobReturnType>>;
    private pending;
    private readonly sort?;
    private paused;
    constructor(init?: QueueInit<JobReturnType, JobOptions>);
    emitEmpty(): void;
    emitIdle(): void;
    pause(): void;
    resume(): void;
    private tryToStartAnother;
    private enqueue;
    /**
     * Adds a sync or async task to the queue. Always returns a promise.
     */
    add(fn: RunFunction<JobOptions, JobReturnType>, options?: JobOptions): Promise<JobReturnType>;
    /**
     * Clear the queue
     */
    clear(): void;
    /**
     * Abort all jobs in the queue and clear it
     */
    abort(): void;
    /**
     * Can be called multiple times. Useful if you for example add additional items at a later time.
     *
     * @returns A promise that settles when the queue becomes empty.
     */
    onEmpty(options?: AbortOptions): Promise<void>;
    /**
     * @returns A promise that settles when the queue size is less than the given
     * limit: `queue.size < limit`.
     *
     * If you want to avoid having the queue grow beyond a certain size you can
     * `await queue.onSizeLessThan()` before adding a new item.
     *
     * Note that this only limits the number of items waiting to start. There
     * could still be up to `concurrency` jobs already running that this call does
     * not include in its calculation.
     */
    onSizeLessThan(limit: number, options?: AbortOptions): Promise<void>;
    /**
     * The difference with `.onEmpty` is that `.onIdle` guarantees that all work
     * from the queue has finished. `.onEmpty` merely signals that the queue is
     * empty, but it could mean that some promises haven't completed yet.
     *
     * @returns A promise that settles when the queue becomes empty, and all
     * promises have completed; `queue.size === 0 && queue.pending === 0`.
     */
    onIdle(options?: AbortOptions): Promise<void>;
    /**
     * Size of the queue including running items
     */
    get size(): number;
    /**
     * The number of queued items waiting to run.
     */
    get queued(): number;
    /**
     * The number of items currently running.
     */
    get running(): number;
    /**
     * Returns an async generator that makes it easy to iterate over the results
     * of jobs added to the queue.
     *
     * The generator will end when the queue becomes idle, that is there are no
     * jobs running and no jobs that have yet to run.
     *
     * If you need to keep the queue open indefinitely, consider using it-pushable
     * instead.
     */
    toGenerator(options?: AbortOptions): AsyncGenerator<JobReturnType, void, unknown>;
}
//# sourceMappingURL=index.d.ts.map