import { DeferredPromise, type MaybePromise } from '@augment-vir/core';
import { type RequireExactlyOne } from 'type-fest';
import { ListenTarget } from 'typed-event-target';
/**
 * An individual item in a {@link PromiseQueue} instance.
 *
 * @category Promise : Util
 * @category Package : @augment-vir/common
 * @package [`@augment-vir/common`](https://www.npmjs.com/package/@augment-vir/common)
 */
export type PromiseQueueItem<T = void> = {
    /** The original queue item that was added. */
    original: () => MaybePromise<T>;
    id: undefined | PropertyKey;
    /**
     * A {@link DeferredPromise} instance with a promise that is resolved once this queue item has
     * met its turn and has finished executing.
     */
    wrapper: DeferredPromise<T>;
};
/**
 * Data contained within an instance of {@link PromiseQueueUpdateEvent}.
 *
 * @category Promise : Util
 * @category Package : @augment-vir/common
 * @package [`@augment-vir/common`](https://www.npmjs.com/package/@augment-vir/common)
 */
export type PromiseQueueUpdate<T = unknown> = {
    queueSize: number;
} & RequireExactlyOne<{
    finishedItem: PromiseQueueItem<T>;
    addedItem: PromiseQueueItem<T>;
}>;
declare const PromiseQueueUpdateEvent_base: (new (eventInitDict: {
    bubbles?: boolean;
    cancelable?: boolean;
    composed?: boolean;
    detail: PromiseQueueUpdate<unknown>;
}) => import("typed-event-target").TypedCustomEvent<PromiseQueueUpdate<unknown>, "promise-queue-update">) & Pick<{
    new (type: string, eventInitDict?: EventInit): Event;
    prototype: Event;
    readonly NONE: 0;
    readonly CAPTURING_PHASE: 1;
    readonly AT_TARGET: 2;
    readonly BUBBLING_PHASE: 3;
}, "prototype" | "NONE" | "CAPTURING_PHASE" | "AT_TARGET" | "BUBBLING_PHASE"> & Pick<import("typed-event-target").TypedCustomEvent<PromiseQueueUpdate<unknown>, "promise-queue-update">, "type">;
/**
 * The event emitted from a {@link PromiseQueue} instance whenever the queue is updated (an item is
 * resolved or an item is added).
 *
 * @category Promise : Util
 * @category Package : @augment-vir/common
 * @package [`@augment-vir/common`](https://www.npmjs.com/package/@augment-vir/common)
 */
export declare class PromiseQueueUpdateEvent extends PromiseQueueUpdateEvent_base {
}
/**
 * A queue that manages its items with promises.
 *
 * @category Promise
 * @category Package : @augment-vir/common
 * @package [`@augment-vir/common`](https://www.npmjs.com/package/@augment-vir/common)
 */
export declare class PromiseQueue extends ListenTarget<PromiseQueueUpdateEvent> {
    protected queue: PromiseQueueItem<any>[];
    protected currentlyAwaiting: undefined | PromiseQueueItem<any>;
    protected queueItemIds: Set<PropertyKey>;
    /** The current size of the queue. */
    get size(): number;
    /**
     * Add an item to the queue. Only await this if you want to wait for the promise to be added
     * _and_ resolved (or rejected).
     *
     * @returns A promise that resolves at the same time as the added item.
     */
    add<T = void>(item: PromiseQueueItem<T>['original'], id?: PropertyKey): Promise<T>;
    /**
     * Checks if the given id is currently in the queue.
     *
     * @returns `true` if the item is in the queue and has not been resolved or rejected. `false` if
     *   the item has never been in the queue or has been resolved / rejected from the queue.
     */
    hasItemById(id: PropertyKey): boolean;
    /** Handles a queue item finishing, whether it be a rejection or a resolution. */
    protected handleItemSettle({ rejection, resolution, }: RequireExactlyOne<{
        rejection: unknown;
        resolution: unknown;
    }>): PromiseQueueItem<any>;
    /**
     * Tries to trigger the next queue item, if there is one.
     *
     * @returns Whether a new queue item was triggered or not. `true` if it was, otherwise `false`.
     */
    protected triggerNextQueueItem(): boolean;
}
export {};
