///
/**
* This file contains the Promise algebraic data type. Promise is the javascript
* built in data structure for asynchronous computation.
*
* @module Promise
* @since 2.0.0
*/
import "./_dnt.polyfills.js";
import type { Kind, Out } from "./kind.js";
import type { Applicable } from "./applicable.js";
import type { Combinable } from "./combinable.js";
import type { Either } from "./either.js";
import type { Initializable } from "./initializable.js";
import type { Mappable } from "./mappable.js";
import type { Flatmappable } from "./flatmappable.js";
import type { Wrappable } from "./wrappable.js";
/**
* A type for Promise over any, useful as an extension target for
* functions that take any Promise and do not need to
* unwrap the type.
* @since 2.0.0
*/
export type AnyPromise = Promise;
/**
* A type level unwrapor, used to pull the inner type from a Promise.
*
* @since 2.0.0
*/
export type TypeOf = T extends Promise ? A : never;
/**
* Specifies Promise as a Higher Kinded Type, with
* covariant parameter A corresponding to the 0th
* index of any Substitutions.
*
* @since 2.0.0
*/
export interface KindPromise extends Kind {
readonly kind: Promise>;
}
/**
* A Promise with the inner resolve function
* hoisted and attached to itself.
*
* @since 2.0.0
*/
export type Deferred = Promise & {
readonly resolve: (a: A | PromiseLike) => void;
};
/**
* Create a Deferred from a type.
*
* @example
* ```ts
* import { deferred } from "./promise.ts";
*
* const promise = deferred();
*
* // Logs 1 after a second
* promise.then(console.log);
* setTimeout(() => promise.resolve(1), 1000);
* ```
*
* @since 2.0.0
*/
export declare function deferred(): Deferred;
/**
* Make an existing Promise somewhat abortable. While
* the returned promise does resolve when the abort signal
* occurs, the existing promise continues running in the
* background. For this reason it is important to
* catch any errors associated with the original promise and
* to not implement side effects in the aborted promise.
*
* @example
* ```ts
* import { abortable, wait } from "./promise.ts";
* import { pipe } from "./fn.ts";
*
* const controller = new AbortController();
* const slow = wait(1000).then(() => 1);
* const wrapped = pipe(
* slow,
* abortable(controller.signal, msg => msg),
* );
*
* setTimeout(() => controller.abort("Hi"), 500);
*
* // After 500ms result contains the following
* // { tag: "Left", left: "Hi" }
* const result = await wrapped;
* ```
*
* @since 2.0.0
*/
export declare function abortable(signal: AbortSignal, onAbort: (reason: unknown) => B): (ua: Promise) => Promise>;
/**
* Create a Promise that resolve after ms milliseconds.
*
* @example
* ```ts
* import { wait, map } from "./promise.ts";
* import { pipe } from "./fn.ts";
*
* const delayed = pipe(
* wait(1000),
* map(() => "Hello World"),
* );
*
* // After 1 second
* const result = await delayed; // "Hello World"
* ```
*
* @since 2.0.0
*/
export declare function wait(ms: number): Promise;
/**
* Delay the resolution of an existing Promise. This does not
* affect the original promise directly, it only waits for
* a ms milliseconds before flatmaping into the original promise.
*
* @example
* ```ts
* import { wrap, delay } from "./promise.ts";
* import { pipe } from "./fn.ts";
*
* // Waits 250 milliseconds before returning
* const result = await pipe(
* wrap(1),
* delay(250),
* ); // 1
* ```
*
* @since 2.0.0
*/
export declare function delay(ms: number): (ua: Promise) => Promise;
/**
* An alias for Promise.resolve.
*
* @example
* ```ts
* import { resolve } from "./promise.ts";
*
* const result = await resolve(1); // 1
* ```
*
* @since 2.0.0
*/
export declare function resolve(a: A | PromiseLike): Promise;
/**
* An alias for Promise.reject.
*
* @example
* ```ts
* import { reject } from "./promise.ts";
*
* const result = await reject(1).catch(x => x); // 1
* ```
*
* @since 2.0.0
*/
export declare function reject(rejection: unknown): Promise;
/**
* An alias for Promise.then
*
* @example
* ```ts
* import { wrap, then } from "./promise.ts";
* import { pipe } from "./fn.ts";
*
* const result = await pipe(
* wrap(1),
* then(n => n + 1),
* ); // 2
* ```
*
* @since 2.0.0
*/
export declare function then(fai: (a: A) => I | Promise): (ua: Promise) => Promise;
/**
* An alias for Promise.catch
*
* @example
* ```ts
* import { reject, catchError } from "./promise.ts";
* import { pipe } from "./fn.ts";
*
* const result = await pipe(
* reject(1),
* catchError(() => "Uhoh"),
* ); // "UhOh"
* ```
*
* @since 2.0.0
*/
export declare function catchError(fua: (u: unknown) => A): (ta: Promise) => Promise;
/**
* An alias for Promise.all
*
* @example
* ```ts
* import { all, wrap } from "./promise.ts";
*
* const result = await all(wrap(1), wrap("Hello")); // [1, "Hello"]
* ```
*
* @since 2.0.0
*/
export declare function all(...ua: T): Promise<{
[K in keyof T]: Awaited;
}>;
/**
* An alias for Promise.race. Note that Promise.race leaks
* async operations in most runtimes. This means that the
* slower promise does not stop when the faster promise
* resolves/rejects. In effect Promise.race does not
* handle cancellation.
*
* @example
* ```ts
* import { wait, map, race, wrap } from "./promise.ts";
* import { pipe } from "./fn.ts";
*
* const one = pipe(wait(200), map(() => "one"));
* const two = pipe(wait(300), map(() => "two"));
*
* // After 200 milliseconds resolves from one
* const result = await race(one, two); // "one"
* ```
*
* @since 2.0.0
*/
export declare function race(...ua: T): Promise>;
/**
* Create a Promise from a value A or another PromiseLike. This
* is essentially an alias of Promise.resolve.
*
* @example
* ```ts
* import { wrap } from "./promise.ts";
*
* const result = await wrap(1); // 1
* ```
*
* @since 2.0.0
*/
export declare function wrap(a: A | PromiseLike): Promise;
/**
* Create a new Promise from a Promise<(a: A) => I> and
* a Promise. Although Promises encapsulate
* asynchrony, there is no way defer a Promise once created,
* thus this ap function always evaluates both input Promises
* in parallel.
*
* @example
* ```ts
* import { wrap, apply } from "./promise.ts";
* import { pipe } from "./fn.ts";
*
* type Person = { name: string, age: number };
*
* const person = (name: string) => (age: number): Person => ({ name, age });
*
* const result = pipe(
* wrap(person),
* apply(wrap("Brandon")),
* apply(wrap(37)),
* ); // Promise
* ```
*
* @since 2.0.0
*/
export declare function apply(ua: Promise): (ufai: Promise<(a: A) => I>) => Promise;
/**
* Create a new Promise by mapping over the result of an existing Promise.
* This is effectively Promise.then, but narrowed to non-promise returning
* functions. If the mapping function returns a Promise then the type
* for this function will be incorrect, as there is no way to create a
* Promise>.
*
* @example
* ```ts
* import { wrap, map } from "./promise.ts";
* import { pipe } from "./fn.ts";
*
* const result = await pipe(
* wrap(1),
* map(n => n + 1),
* ); // 2
* ```
*
* @since 2.0.0
*/
export declare function map(fai: (a: A) => I): (ua: Promise) => Promise;
/**
* Create a new Promise by flatmaping over the result of an existing Promise.
* This is effectively Promise.then.
*
* @example
* ```ts
* import { wrap, flatmap } from "./promise.ts";
* import { pipe } from "./fn.ts";
*
* const result = await pipe(
* wrap(1),
* flatmap(n => wrap(n + 1)),
* ); // 2
* ```
*
* @since 2.0.0
*/
export declare function flatmap(faui: (a: A) => Promise): (ua: Promise) => Promise;
/**
* @since 2.0.0
*/
export declare function fail(b: unknown): Promise;
/**
* Wrap a function that potentially throws in a try/catch block,
* handling any thrown errors and returning the result inside
* of a Promise.
*
* @example
* ```ts
* import { tryCatch, reject, wrap } from "./promise.ts";
* import { pipe, todo } from "./fn.ts";
* // Note that todo will always throw synchronously.
*
* const add = (n: number) => n + 1;
* const throwSync = (_: number): number => todo();
* const throwAsync = (_: number): Promise => reject("Ha!");
*
* const catchAdd = tryCatch(add, () => -1);
* const catchSync = tryCatch(throwSync, () => -1);
* const catchAsync = tryCatch(throwAsync, () => -1);
*
* const resultAdd = await catchAdd(1); // 2
* const resultSync = await catchSync(1); // -1
* const resultAsync = await catchAsync(1); // -1
* ```
* @since 2.0.0
*/
export declare function tryCatch(handle: (...args: D) => A | PromiseLike, onThrow: (error: unknown, args: D) => A): (...args: D) => Promise;
/**
* @since 2.0.0
*/
export declare function getCombinablePromise({ combine }: Combinable): Combinable>;
/**
* @since 2.0.0
*/
export declare function getInitializablePromise(I: Initializable): Initializable>;
/**
* The canonical implementation of Applicable for Promise. It contains
* the methods wrap, apply, and map.
*
* @since 2.0.0
*/
export declare const ApplicablePromise: Applicable;
/**
* The canonical implementation of Mappable for Promise. It contains
* the method map.
*
* @since 2.0.0
*/
export declare const MappablePromise: Mappable;
/**
* The canonical implementation of Flatmappable for Promise. It contains
* the methods wrap, apply, map, and flatmap.
*
* @since 2.0.0
*/
export declare const FlatmappablePromise: Flatmappable;
/**
* @since 2.0.0
*/
export declare const WrappablePromise: Wrappable;
/**
* @since 2.0.0
*/
export declare const tap: (fn: (value: A) => void) => (ua: Promise) => Promise;
/**
* @since 2.0.0
*/
export declare const bind: (name: Exclude, faui: (a: A) => Promise) => (ua: Promise) => Promise<{ readonly [K_1 in N | keyof A]: K_1 extends keyof A ? A[K_1] : I; }>;
/**
* @since 2.0.0
*/
export declare const bindTo: (name: N) => (ua: Promise) => Promise<{ readonly [K in N]: A; }>;