export declare class WorkQueue<T> {
    private pending;
    private queue;
    private releaseActive;
    private releaseTask;
    /**
     * The {@link WorkQueue} releases waiting tasks one-per-microtask. This maintains the invariant
     * that every time `wait` returns or resolves, there's at least one item in the queue: otherwise,
     * resolving everything at once might allow other waiters to steal all items.
     */
    private releasePending;
    /**
     * Iterates through the items in this queue _forever_, waiting for more items to appear.
     */
    [Symbol.asyncIterator](): AsyncGenerator<T, void, void>;
    asyncGenerator(): AsyncGenerator<T, void, void>;
    /**
     * Iterates through the items in this queue, stopping when no more are available synchronously.
     */
    [Symbol.iterator](): Generator<NonNullable<T>, void, unknown>;
    /**
     * Waits until there is something in the queue that your task can process. This does _not_ return
     * the item itself. This returns `undefined` if no waiting is required.
     */
    wait(): void | Promise<void>;
    /**
     * Takes a token for the next item from the front of the queue. The returned {@link Promise} will
     * always receive the next item, so don't throw it away.
     */
    next(): Promise<T>;
    /**
     * Push items into the queue. Wakes up any pending requests.
     */
    push(...items: T[]): number;
    pop(): T | undefined;
    /**
     * Push items at the start of the queue. Wakes up any pending requests.
     */
    unshift(...items: T[]): number;
    shift(): T | undefined;
    get length(): number;
}
/**
 * Array-based queue. Faster thank {@link LinkQueue}, but cannot be garbage-collected.
 */
export interface Queue<X> {
    /**
     * Adds more events to the queue. Returns `true` if any listeners were directly woken up.
     */
    push(...all: X[]): boolean;
    /**
     * Returns a listener that provides all events passed with `push` after this call completes.
     *
     * If the signal is cancelled, the listener becomes invalid and returns undefined values.
     */
    join(signal: AbortSignal): Listener<X>;
}
/**
 * Linked-list based queue.
 */
export interface LinkQueue<X> extends Queue<X> {
    /**
     * Returns a listener that provides all events passed with `push` after this call completes.
     *
     * If the signal is cancelled, the listener becomes invalid and returns undefined values.
     *
     * If the listener is garbage collected, it will lose the reference to the back of the queue.
     */
    join(signal?: AbortSignal): Listener<X>;
}
/**
 * Listener for a queue.
 */
export interface Listener<X> {
    /**
     * Determines if there's a pending queue event, returning it if available.
     *
     * Returns `undefined` if there is no event or the listener was aborted. It does not consume the
     * event.
     */
    peek(): X | undefined;
    /**
     * Waits for and returns the next queue event.
     *
     * Returns `undefined` if this listener was aborted.
     */
    next(): Promise<X | undefined>;
    /**
     * Waits for and returns an array of all available queue events.
     *
     * If the array has zero length, the listener was aborted.
     */
    batch(): Promise<X[]>;
    /**
     * Waits for and returns only the last pending event. This can be useful if the event is purely a
     * "high water mark".
     */
    last(): Promise<X | undefined>;
}
/**
 * Builds an async generator over the given {@link Listener}.
 */
export declare function listenerToAsyncGenerator<X>(l: Listener<X>): AsyncGenerator<X, void, void>;
/**
 * Builds a listener that never has any values in it, and resolves immediately. For aborted signals.
 */
export declare function buildEmptyListener<X = any>(): Listener<X>;
/**
 * Builds a {@link LinkQueue}.
 */
export declare function buildLinkQueue<X>(): LinkQueue<X>;
/**
 * Builds a {@link Queue}.
 */
export declare function buildArrayQueue<X>(): Queue<X>;
