/**
 * @module Async
 */
import { type AsyncLazy, type AsyncMiddleware, type Invokable, type InvokableFn, type OneOrMore, type Promisable, type TimeSpan } from "../../../utilities/_module-exports.js";
/**
 *
 * IMPORT_PATH: `"@daiso-tech/core/async"`
 * @group Utilities
 */
export type LazyPromiseResolve<TValue> = InvokableFn<[
    value: Promisable<TValue>
], void>;
/**
 *
 * IMPORT_PATH: `"@daiso-tech/core/async"`
 * @group Utilities
 */
export type LazyPromiseReject = InvokableFn<[error: unknown], void>;
/**
 *
 * IMPORT_PATH: `"@daiso-tech/core/async"`
 * @group Utilities
 */
export type LazyPromiseCallback<TValue> = InvokableFn<[
    resolve: LazyPromiseResolve<TValue>,
    reject: LazyPromiseReject
], Promisable<void>>;
/**
 * The `LazyPromise` class is used for creating lazy {@link PromiseLike | `PromiseLike`} object that will only execute when awaited or when `then` method is called.
 * Note the class is immutable.
 *
 * IMPORT_PATH: `"@daiso-tech/core/async"`
 * @group Utilities
 */
export declare class LazyPromise<TValue> implements PromiseLike<TValue> {
    /**
     * The `wrapFn` is convience method used for wrapping async {@link Invokable | `Invokable`} with a `LazyPromise`.
     * @example
     * ```ts
     * import { LazyPromise, retry } from "@daiso-tech/core/async";
     * import { TimeSpan } from "@daiso-tech/core/utilities";
     * import { readFile as readFileNodeJs } from "node:fs/promises";
     *
     * const readFile = LazyPromise.wrapFn(readFileNodeJs);
     *
     * const file = await readFile("none_existing_file.txt");
     * ```
     */
    static wrapFn<TArgs extends unknown[], TReturn>(fn: Invokable<TArgs, Promisable<TReturn>>): InvokableFn<TArgs, LazyPromise<TReturn>>;
    /**
     * The `delay` method creates a {@link LazyPromise | `LazyPromise`} that will be fulfilled after given `time`.
     *
     * @example
     * ```ts
     * import { LazyPromise } from "@daiso-tech/core/async";
     * import { TimeSpan } from "@daiso-tech/core/utilities";
     *
     * console.log("a");
     * await LazyPromise.delay(TimeSpan.fromSeconds(2));
     * console.log("b");
     * ```
     */
    static delay(time: TimeSpan, abortSignal?: AbortSignal): LazyPromise<void>;
    /**
     * The `all` method works similarly to {@link Promise.all | `Promise.all`} with the key distinction that it operates lazily.
     */
    static all<TValue>(promises: LazyPromise<TValue>[]): LazyPromise<TValue[]>;
    /**
     * The `allSettled` method works similarly to {@link Promise.allSettled | `Promise.allSettled`} with the key distinction that it operates lazily.
     */
    static allSettled<TValue>(promises: LazyPromise<TValue>[]): LazyPromise<PromiseSettledResult<TValue>[]>;
    /**
     * The `race` method works similarly to {@link Promise.race | `Promise.race`} with the key distinction that it operates lazily.
     */
    static race<TValue>(promises: LazyPromise<TValue>[]): LazyPromise<TValue>;
    /**
     * The `any` method works similarly to {@link Promise.any | `Promise.any`} with the key distinction that it operates lazily.
     */
    static any<TValue>(promises: LazyPromise<TValue>[]): LazyPromise<TValue>;
    /**
     * The `fromCallback` is convience method used for wrapping Node js callback functions with a `LazyPromise`.
     * @example
     * ```ts
     * import { LazyPromise } from "@daiso-tech/core/async";
     * import { readFile } from "node:fs";
     *
     * const lazyPromise = LazyPromise.fromCallback<Buffer  | string>((resolve, reject) => {
     *   readFile("FILE_PATH", (err, data) => {
     *     if (err !== null) {
     *       reject(err);
     *       return;
     *     }
     *     resolve(data);
     *   });
     * });
     * const file = await lazyPromise;
     * console.log(file);
     * ```
     */
    static fromCallback<TValue>(callback: LazyPromiseCallback<TValue>): LazyPromise<TValue>;
    private promise;
    private readonly invokable;
    /**
     * @example
     * ```ts
     * import { LazyPromise, retryMiddleware } from "@daiso-tech/core/async";
     *
     * const promise = new LazyPromise(async () => {
     *   console.log("I am lazy");
     * },
     *   // You can also pass in one AsyncMiddleware or multiple (as an Array).
     *   retry()
     * );
     *
     * // "I am lazy" will only logged when awaited or then method i called.
     * await promise;
     * ```
     *
     * You can pass sync or async {@link Invokable | `Invokable`}.
     */
    constructor(invokable: AsyncLazy<TValue>, middlewares?: OneOrMore<AsyncMiddleware<[], TValue>>);
    /**
     * The `pipe` method returns a new `LazyPromise` instance with the additional `middlewares` applied.
     */
    pipe(middlewares: OneOrMore<AsyncMiddleware<[], TValue>>): LazyPromise<TValue>;
    /**
     * The `pipeWhen` method conditionally applies additional `middlewares`, returning a new `LazyPromise` instance only if the specified condition is met.
     */
    pipeWhen(condition: boolean, middlewares: OneOrMore<AsyncMiddleware<[], TValue>>): LazyPromise<TValue>;
    then<TResult1 = TValue, TResult2 = never>(onfulfilled?: ((value: TValue) => TResult1 | PromiseLike<TResult1>) | null, onrejected?: ((reason: any) => TResult2 | PromiseLike<TResult2>) | null): PromiseLike<TResult1 | TResult2>;
    /**
     * The `defer` method executes the `LazyPromise` without awaiting it.
     * @example
     * ```ts
     * import { LazyPromise } from "@daiso-tech/core/async";
     * import { TimeSpan } from "@daiso-tech/core/utilities";
     *
     * const promise =
     *   new LazyPromise(async () => {
     *     await LazyPromise.delay(TimeSpan.fromSeconds(1));
     *     // Will be loged after one second
     *     console.log("Done !");
     *   });
     *
     * promise.defer();
     *
     * // Will be logged immediately
     * console.log("Hello");
     * await LazyPromise.delay(TimeSpan.fromSeconds(2));
     * ```
     */
    defer(): void;
}
