import type { ImmutableArray } from "./array.js";
import { type ErrorCallback, type ValueCallback } from "./function.js";
/** Is a value an asynchronous value implementing a `then()` function. */
export declare function isAsync<T>(value: PromiseLike<T> | T): value is PromiseLike<T>;
/** Is a value a synchronous value. */
export declare function notAsync<T>(value: PromiseLike<T> | T): value is T;
/**
 * Throw the value if it's an async (promised) value.
 * @returns Synchronous (not promised) value.
 * @throws Promise if value is an asynchronous (promised) value.
 */
export declare function throwAsync<T>(value: PromiseLike<T> | T): T;
/** Assert an unknown value is synchronous (i.e. does not have a `.then()` method). */
export declare function assertNotAsync<T>(value: PromiseLike<T> | T): asserts value is T;
/** Assert an unknown value is asynchronous (i.e. has a `.then()` method). */
export declare function assertAsync<T>(value: PromiseLike<T> | T): asserts value is PromiseLike<T>;
/** Assert that an unknown value is a `Promise` */
export declare function assertPromise<T>(value: Promise<T> | T): asserts value is Promise<T>;
/** Run any queued microtasks now. */
export declare function runMicrotasks(): Promise<void>;
/**
 * Get the result of multiple promises concurrently.
 *
 * DH: An issue with `Promise.all()` is: if _one_ of its promises rejects, the parent promise rejects immediately.
 * - This leaves all of the other promises lost in unhandled purgatory.
 * - The program may then have dangling open threads that prevent the program from exiting, even after it has returned its main result.
 * - This function waits for the resolution of *all* promises before rejecting.
 *
 * @param promises Values (usually async, but not necessarily) that we need to wait for.
 * @returns Array of values of all promises (in the same order/positions as input).
 * @throws {Errors} If one or more promises throws all rejection reasons after resolving all of the promises.
 */
export declare function awaitValues<T extends ImmutableArray<unknown>>(...promises: T): Promise<{
    readonly [P in keyof T]: Awaited<T[P]>;
}>;
/**
 * Get the rejection reasons of multiple promises (concurrently).
 *
 * @param promises Values (usually async, but not necessarily) that we need to wait for.
 * @returns Array of rejection reasons of all promises (or empty array if no promises threw).
 */
export declare function awaitErrors(...promises: PromiseLike<unknown>[]): Promise<ImmutableArray<unknown>>;
/** `Promise` designed for extending with `._resolve()` and `._reject()` methods that can be accessed by subclasses. */
export declare abstract class BasePromise<T> extends Promise<T> {
    static get [Symbol.species](): PromiseConstructor;
    /** Resolve this promise with a value. */
    protected readonly _resolve: ValueCallback<T>;
    /** Reject this promise with a reason. */
    protected readonly _reject: ErrorCallback;
    constructor();
}
/** Deferred allows you to access the internal resolve/reject callbacks of a `Promise` */
export type Deferred<T = unknown> = {
    promise: Promise<T>;
    resolve: ValueCallback<T>;
    reject: ErrorCallback;
};
/**
 * Create a deferred to access the `resolve()` and `reject()` functions of a promise.
 * - See https://github.com/tc39/proposal-promise-with-resolvers/
 */
export declare function createDeferred<T = void>(): Deferred<T>;
/** Get a promise that automatically resolves after a delay. */
export declare function getDelay(ms: number): Promise<void>;
/**
 * Get a promise that rejects with the signal's reason when an `AbortSignal` fires.
 * - Rejects immediately if the signal is already aborted.
 * - Use with `awaitRace()` to cancel a concurrent operation when a signal fires.
 *
 * @example await awaitRace(getDelay(300), awaitAbort(signal));
 */
export declare function awaitAbort(signal: AbortSignal): Promise<never>;
/**
 * Race promises like `Promise.race()` but silently swallow rejections from the losers.
 * - Returns a promise that settles with the first input to settle, exactly like `Promise.race()`.
 * - The losing inputs keep running (Promises cannot be cancelled), but their eventual rejection — if any — is silently absorbed instead of bubbling up as an unhandled rejection.
 * - Built for cancellation/timeout patterns, where the loser's eventual fate is genuinely uninteresting once another arm has settled. Do not use when both arms might surface meaningful errors that the caller should see.
 *
 * @example await awaitRace(getDelay(300), awaitAbort(signal)); // delay or abort, no leaked ABORT rejection if delay wins
 */
export declare function awaitRace<T>(...promises: Promise<T>[]): Promise<T>;
