@nobrayner/orf
Advanced tools
Comparing version 0.0.3 to 0.0.4
2643
lib/orf.d.ts
interface IResult<T, E> { | ||
/** | ||
* Used to check if the Result is an `Ok`, and if it is, narrows the | ||
* `Result<T, E>` to `Ok<T, E>` | ||
* | ||
* Intended to be used as a type guard | ||
* | ||
* ## Example | ||
* ```ts | ||
* const res = Result.Ok(1); | ||
* const result = res.isOk(); | ||
* // result === true | ||
* | ||
* const res = Result.Error("error"); | ||
* const result = res.isOk(); | ||
* // result === false | ||
* ``` | ||
*/ | ||
isOk(): this is Ok<T, E>; | ||
/** | ||
* Used to check if the Result is an `Error`, and if it is, narrows the | ||
* `Result<T, E>` to `Error<T, E>` | ||
* | ||
* Intended to be used as a type guard | ||
* | ||
* ## Example | ||
* ```ts | ||
* const res = Result.Ok(1); | ||
* const result = res.isError(); | ||
* // result === false | ||
* | ||
* const res = Result.Error("error"); | ||
* const result = res.isError(); | ||
* // result === true | ||
* ``` | ||
*/ | ||
isError(): this is Error<T, E>; | ||
/** | ||
* Runs the function provided in the `Ok` or `Error` branch, passing the value | ||
* or error respectively | ||
* | ||
* ## Example | ||
* ```ts | ||
* const res = Result.Ok(1); | ||
* const result = res.match({ | ||
* Ok: (value) => value, | ||
* Error: (error) => error, | ||
* }); | ||
* // result === 1 | ||
* | ||
* const res = Result.Error("error"); | ||
* const result = res.match({ | ||
* Ok: (value) => value, | ||
* Error: (error) => error, | ||
* }); | ||
* // result === "error" | ||
* ``` | ||
*/ | ||
match<U, V = U>(config: { | ||
Ok: (t: T) => U; | ||
Error: (e: E) => V; | ||
}): U | V; | ||
/** | ||
* Maps `Ok<T, E>` to `Ok<U, E>`, or returns the existing `Error` | ||
* | ||
* ## Example | ||
* ```ts | ||
* const res = Result.Ok(1); | ||
* const result = res.map((value) => value * 2); | ||
* // result === Result.Ok(2) | ||
* | ||
* const res = Result.Error("error"); | ||
* const result = res.map((value) => value * 2); | ||
* // result === Result.Error("error") | ||
* ``` | ||
*/ | ||
map<U>(map_fn: (t: T) => U): Result<U, E>; | ||
/** | ||
* Maps `Ok<T, E>` to `U`, or returns the given `or_value` | ||
* | ||
* ## Example | ||
* ```ts | ||
* const res = Result.Ok(1); | ||
* const result = res.mapOr(0, (value) => value * 2); | ||
* // result === 2 | ||
* | ||
* const res = Result.Error("error"); | ||
* const result = res.mapOr(0, (value) => value * 2); | ||
* // result === 0 | ||
* ``` | ||
*/ | ||
mapOr<U, V = U>(or_value: U, map_fn: (t: T) => V): U | V; | ||
/** | ||
* Maps `Ok<T, E>` to `U`, or returns the result of running `or_fn` | ||
* | ||
* ## Example | ||
* ```ts | ||
* const res = Result.Ok(1); | ||
* const result = res.mapOrElse(() => 0, (value) => value * 2); | ||
* // result === 2 | ||
* | ||
* const res = Result.Error("error"); | ||
* const result = res.mapOrElse(() => 0, (value) => value * 2); | ||
* // result === 0 | ||
* ``` | ||
*/ | ||
mapOrElse<U, V = U>(or_fn: () => U, map_fn: (t: T) => V): U | V; | ||
/** | ||
* Maps `Error<T, E>` to `Error<T, F>`, or returns the existing `Ok` | ||
* | ||
* ## Example | ||
* ```ts | ||
* const res = Result.Error("error"); | ||
* const result = res.mapErr((error) => new Error(error)); | ||
* // result === Result.Error(new Error("error")) | ||
* | ||
* const res = Result.Ok(1); | ||
* const result = res.mapErr((error) => new Error(error)); | ||
* // result === Result.Ok(1) | ||
* ``` | ||
*/ | ||
mapError<F>(map_fn: (e: E) => F): Result<T, F>; | ||
/** | ||
* Returns the existing `Error` if the result is an `Error`, otherwise | ||
* returns `and_value` | ||
* | ||
* ## Example | ||
* ```ts | ||
* const res = Result.Ok(1); | ||
* const result = res.and(Result.Error("new error")); | ||
* // result === Result.Error("new error") | ||
* | ||
* const res = Result.Error("error"); | ||
* const result = res.and(Result.Ok(2)); | ||
* // result === Result.Error("error") | ||
* ``` | ||
*/ | ||
and<U, F = E>(and_value: Result<U, F>): Result<U, E | F>; | ||
/** | ||
* Returns the existing `Error` if the result is an `Error`, otherwise | ||
* returns the result of running `and_fn` with the value held in `Ok` | ||
* | ||
* ## Example | ||
* ```ts | ||
* const res = Result.Ok(1); | ||
* const result = res.andThen((value) => Result.Ok(`${value * 2}`)); | ||
* // result === Result.Ok("2") | ||
* | ||
* const res = Result.Error("error"); | ||
* const result = res.andThen((value) => Result.Ok(2)); | ||
* // result === Result.Error("error") | ||
* ``` | ||
*/ | ||
andThen<R extends Result<any, any>>(and_fn: (t: T) => R): Result<orf.InferOkType<R>, orf.InferErrorType<R> | E>; | ||
/** | ||
* Returns `or_value` if the result is an `Error`, otherwise returns | ||
* the existing `Ok` | ||
* | ||
* ## Example | ||
* ```ts | ||
* const res = Result.Ok(1); | ||
* const result = res.or(Result.Ok(2)); | ||
* // result === Result.Ok(1) | ||
* | ||
* const res = Result.Error("error"); | ||
* const result = res.or(Result.Ok(2)); | ||
* // result === Result.Ok(2) | ||
* ``` | ||
*/ | ||
or<F, U = T>(or_value: Result<U, F>): Result<T | U, F>; | ||
/** | ||
* Returns the existing `Ok<T>` if the result is an `Ok`, otherwise | ||
* returns the result of running `or_fn` with the error held in `Error` | ||
* | ||
* ## Example | ||
* ```ts | ||
* const res = Result.Ok(1); | ||
* const result = res.orElse((error) => Result.Ok(`Not okay: ${error}`)); | ||
* // result === Result.Ok(1) | ||
* | ||
* const res = Result.Error("error"); | ||
* const result = res.orElse((error) => Result.Ok(`Not okay: ${error}`)); | ||
* // result === Result.Ok("Not okay: error") | ||
* ``` | ||
*/ | ||
orElse<R extends Result<unknown, unknown>>(or_fn: (e: E) => R): Result<orf.InferOkType<R> | T, orf.InferErrorType<R>>; | ||
/** | ||
* Runs `fn` with `Readonly<T>` if the result is `Ok`, and then returns | ||
* the existing `Ok`; otherwise does nothing and returns the existing | ||
* `Error` | ||
* | ||
* ## Example | ||
* ```ts | ||
* const res = Result.Ok(1); | ||
* const result = res.tap((value) => console.log(value)); | ||
* // Logs: 1 | ||
* // result === Result.Ok(1) | ||
* | ||
* const res = Result.Error("error"); | ||
* const result = res.tap((value) => console.log(value)); | ||
* // Does not log anything | ||
* // result === Result.Error("error") | ||
* ``` | ||
*/ | ||
tap(fn: (t: Readonly<T>) => void): Result<T, E>; | ||
/** | ||
* Runs `fn` with `Readonly<E>` if the result is `Error`, and then returns | ||
* the existing `Error`; otherwise does nothing and returns the existing | ||
* `Ok` | ||
* | ||
* ## Example | ||
* ```ts | ||
* const res = Result.Ok(1); | ||
* const result = res.tapError((error) => console.error(error)); | ||
* // Does not log anything | ||
* // result === Result.Ok(1) | ||
* | ||
* const res = Result.Error("error"); | ||
* const result = res.tapError((error) => console.error(error)); | ||
* // Logs: "error" | ||
* // result === Result.Error("error") | ||
* ``` | ||
*/ | ||
tapError(fn: (e: Readonly<E>) => void): Result<T, E>; | ||
/** | ||
* Returns the `T` of an `Ok<T, E>`, or throws an exception if the result | ||
* is an `Error` | ||
* | ||
* ## Example | ||
* ```ts | ||
* const res = Result.Ok(1); | ||
* const result = res.unwrap(); | ||
* // result === 1 | ||
* | ||
* const res = Result.Error("error"); | ||
* const result = res.unwrap(); | ||
* // Throws an exception | ||
* ``` | ||
*/ | ||
unwrap(): T; | ||
/** | ||
* Returns the `E` of an `Error<T, E>`, or throws an exception if the result | ||
* is an `Ok` | ||
* | ||
* ## Example | ||
* ```ts | ||
* const res = Result.Error("error"); | ||
* const result = res.unwrapErr(); | ||
* // result === "error" | ||
* | ||
* const res = Result.Ok(1); | ||
* const result = res.unwrapErr(); | ||
* // Throws an exception | ||
* ``` | ||
*/ | ||
unwrapError(): E; | ||
/** | ||
* Returns the `T` of an `Ok<T, E>`, or the `or_value` if the result is | ||
* an `Error` | ||
* | ||
* ## Example | ||
* ```ts | ||
* const res = Result.Ok(1); | ||
* const result = res.unwrapOr(0); | ||
* // result === 1 | ||
* | ||
* const res = Result.Error("error"); | ||
* const result = res.unwrapOr(0); | ||
* // result === 0 | ||
* ``` | ||
*/ | ||
unwrapOr<U = T>(or_value: U): T | U; | ||
/** | ||
* Returns the `T` of an `Ok<T, E>`, or the result of running `or_fn` if | ||
* the result is an `Error` | ||
* | ||
* ## Example | ||
* ```ts | ||
* const res = Result.Ok(1); | ||
* const result = res.unwrapOrElse(() => 0); | ||
* // result === 1 | ||
* | ||
* const res = Result.Error("error"); | ||
* const result = res.unwrapOrElse(() => 0); | ||
* // result === 0 | ||
* ``` | ||
*/ | ||
unwrapOrElse<U = T>(or_fn: (e: E) => U): T | U; | ||
/** | ||
* Converts the `Result<T, E>` to an `Option<T>`, discarding the `Error` | ||
* if the result is an `Error` | ||
* | ||
* ## Example | ||
* ```ts | ||
* const res = Result.Ok(1); | ||
* const result = res.ok(); | ||
* // result === Option.Some(1) | ||
* | ||
* const res = Result.Error("error"); | ||
* const result = res.ok(); | ||
* // result === Option.None() | ||
* ``` | ||
*/ | ||
ok(): Option<T>; | ||
toJSON(): JsonResult<T, E>; | ||
/** | ||
* Used to check if the Result is an `Ok`, and if it is, narrows the | ||
* `Result<T, E>` to `Ok<T, E>` | ||
* | ||
* Intended to be used as a type guard | ||
* | ||
* ## Example | ||
* ```ts | ||
* const res = Result.Ok(1); | ||
* const result = res.isOk(); | ||
* // result === true | ||
* | ||
* const res = Result.Error("error"); | ||
* const result = res.isOk(); | ||
* // result === false | ||
* ``` | ||
*/ | ||
isOk(): this is Ok<T, E>; | ||
/** | ||
* Used to check if the Result is an `Error`, and if it is, narrows the | ||
* `Result<T, E>` to `Error<T, E>` | ||
* | ||
* Intended to be used as a type guard | ||
* | ||
* ## Example | ||
* ```ts | ||
* const res = Result.Ok(1); | ||
* const result = res.isError(); | ||
* // result === false | ||
* | ||
* const res = Result.Error("error"); | ||
* const result = res.isError(); | ||
* // result === true | ||
* ``` | ||
*/ | ||
isError(): this is Error<T, E>; | ||
/** | ||
* Runs the function provided in the `Ok` or `Error` branch, passing the value | ||
* or error respectively | ||
* | ||
* ## Example | ||
* ```ts | ||
* const res = Result.Ok(1); | ||
* const result = res.match({ | ||
* Ok: (value) => value, | ||
* Error: (error) => error, | ||
* }); | ||
* // result === 1 | ||
* | ||
* const res = Result.Error("error"); | ||
* const result = res.match({ | ||
* Ok: (value) => value, | ||
* Error: (error) => error, | ||
* }); | ||
* // result === "error" | ||
* ``` | ||
*/ | ||
match<U, V = U>(config: { | ||
Ok: (t: T) => U; | ||
Error: (e: E) => V; | ||
}): U | V; | ||
/** | ||
* Maps `Ok<T, E>` to `Ok<U, E>`, or returns the existing `Error` | ||
* | ||
* ## Example | ||
* ```ts | ||
* const res = Result.Ok(1); | ||
* const result = res.map((value) => value * 2); | ||
* // result === Result.Ok(2) | ||
* | ||
* const res = Result.Error("error"); | ||
* const result = res.map((value) => value * 2); | ||
* // result === Result.Error("error") | ||
* ``` | ||
*/ | ||
map<U>(map_fn: (t: T) => U): Result<U, E>; | ||
/** | ||
* Maps `Ok<T, E>` to `U`, or returns the given `or_value` | ||
* | ||
* ## Example | ||
* ```ts | ||
* const res = Result.Ok(1); | ||
* const result = res.mapOr(0, (value) => value * 2); | ||
* // result === 2 | ||
* | ||
* const res = Result.Error("error"); | ||
* const result = res.mapOr(0, (value) => value * 2); | ||
* // result === 0 | ||
* ``` | ||
*/ | ||
mapOr<U, V = U>(or_value: U, map_fn: (t: T) => V): U | V; | ||
/** | ||
* Maps `Ok<T, E>` to `U`, or returns the result of running `or_fn` | ||
* | ||
* ## Example | ||
* ```ts | ||
* const res = Result.Ok(1); | ||
* const result = res.mapOrElse(() => 0, (value) => value * 2); | ||
* // result === 2 | ||
* | ||
* const res = Result.Error("error"); | ||
* const result = res.mapOrElse(() => 0, (value) => value * 2); | ||
* // result === 0 | ||
* ``` | ||
*/ | ||
mapOrElse<U, V = U>(or_fn: () => U, map_fn: (t: T) => V): U | V; | ||
/** | ||
* Maps `Error<T, E>` to `Error<T, F>`, or returns the existing `Ok` | ||
* | ||
* ## Example | ||
* ```ts | ||
* const res = Result.Error("error"); | ||
* const result = res.mapErr((error) => new Error(error)); | ||
* // result === Result.Error(new Error("error")) | ||
* | ||
* const res = Result.Ok(1); | ||
* const result = res.mapErr((error) => new Error(error)); | ||
* // result === Result.Ok(1) | ||
* ``` | ||
*/ | ||
mapError<F>(map_fn: (e: E) => F): Result<T, F>; | ||
/** | ||
* Returns the existing `Error` if the result is an `Error`, otherwise | ||
* returns `and_value` | ||
* | ||
* ## Example | ||
* ```ts | ||
* const res = Result.Ok(1); | ||
* const result = res.and(Result.Error("new error")); | ||
* // result === Result.Error("new error") | ||
* | ||
* const res = Result.Error("error"); | ||
* const result = res.and(Result.Ok(2)); | ||
* // result === Result.Error("error") | ||
* ``` | ||
*/ | ||
and<U, F = E>(and_value: Result<U, F>): Result<U, E | F>; | ||
/** | ||
* Returns the existing `Error` if the result is an `Error`, otherwise | ||
* returns the result of running `and_fn` with the value held in `Ok` | ||
* | ||
* ## Example | ||
* ```ts | ||
* const res = Result.Ok(1); | ||
* const result = res.andThen((value) => Result.Ok(`${value * 2}`)); | ||
* // result === Result.Ok("2") | ||
* | ||
* const res = Result.Error("error"); | ||
* const result = res.andThen((value) => Result.Ok(2)); | ||
* // result === Result.Error("error") | ||
* ``` | ||
*/ | ||
andThen<R extends Result<any, any>>(and_fn: (t: T) => R): Result<orf.InferOkType<R>, orf.InferErrorType<R> | E>; | ||
/** | ||
* Returns `or_value` if the result is an `Error`, otherwise returns | ||
* the existing `Ok` | ||
* | ||
* ## Example | ||
* ```ts | ||
* const res = Result.Ok(1); | ||
* const result = res.or(Result.Ok(2)); | ||
* // result === Result.Ok(1) | ||
* | ||
* const res = Result.Error("error"); | ||
* const result = res.or(Result.Ok(2)); | ||
* // result === Result.Ok(2) | ||
* ``` | ||
*/ | ||
or<F, U = T>(or_value: Result<U, F>): Result<T | U, F>; | ||
/** | ||
* Returns the existing `Ok<T>` if the result is an `Ok`, otherwise | ||
* returns the result of running `or_fn` with the error held in `Error` | ||
* | ||
* ## Example | ||
* ```ts | ||
* const res = Result.Ok(1); | ||
* const result = res.orElse((error) => Result.Ok(`Not okay: ${error}`)); | ||
* // result === Result.Ok(1) | ||
* | ||
* const res = Result.Error("error"); | ||
* const result = res.orElse((error) => Result.Ok(`Not okay: ${error}`)); | ||
* // result === Result.Ok("Not okay: error") | ||
* ``` | ||
*/ | ||
orElse<R extends Result<unknown, unknown>>(or_fn: (e: E) => R): Result<orf.InferOkType<R> | T, orf.InferErrorType<R>>; | ||
/** | ||
* Runs `fn` with `Readonly<T>` if the result is `Ok`, and then returns | ||
* the existing `Ok`; otherwise does nothing and returns the existing | ||
* `Error` | ||
* | ||
* ## Example | ||
* ```ts | ||
* const res = Result.Ok(1); | ||
* const result = res.tap((value) => console.log(value)); | ||
* // Logs: 1 | ||
* // result === Result.Ok(1) | ||
* | ||
* const res = Result.Error("error"); | ||
* const result = res.tap((value) => console.log(value)); | ||
* // Does not log anything | ||
* // result === Result.Error("error") | ||
* ``` | ||
*/ | ||
tap(fn: (t: Readonly<T>) => void): Result<T, E>; | ||
/** | ||
* Runs `fn` with `Readonly<E>` if the result is `Error`, and then returns | ||
* the existing `Error`; otherwise does nothing and returns the existing | ||
* `Ok` | ||
* | ||
* ## Example | ||
* ```ts | ||
* const res = Result.Ok(1); | ||
* const result = res.tapError((error) => console.error(error)); | ||
* // Does not log anything | ||
* // result === Result.Ok(1) | ||
* | ||
* const res = Result.Error("error"); | ||
* const result = res.tapError((error) => console.error(error)); | ||
* // Logs: "error" | ||
* // result === Result.Error("error") | ||
* ``` | ||
*/ | ||
tapError(fn: (e: Readonly<E>) => void): Result<T, E>; | ||
/** | ||
* Returns the `T` of an `Ok<T, E>`, or throws an exception if the result | ||
* is an `Error` | ||
* | ||
* ## Example | ||
* ```ts | ||
* const res = Result.Ok(1); | ||
* const result = res.unwrap(); | ||
* // result === 1 | ||
* | ||
* const res = Result.Error("error"); | ||
* const result = res.unwrap(); | ||
* // Throws an exception | ||
* ``` | ||
*/ | ||
unwrap(): T; | ||
/** | ||
* Returns the `E` of an `Error<T, E>`, or throws an exception if the result | ||
* is an `Ok` | ||
* | ||
* ## Example | ||
* ```ts | ||
* const res = Result.Error("error"); | ||
* const result = res.unwrapErr(); | ||
* // result === "error" | ||
* | ||
* const res = Result.Ok(1); | ||
* const result = res.unwrapErr(); | ||
* // Throws an exception | ||
* ``` | ||
*/ | ||
unwrapError(): E; | ||
/** | ||
* Returns the `T` of an `Ok<T, E>`, or the `or_value` if the result is | ||
* an `Error` | ||
* | ||
* ## Example | ||
* ```ts | ||
* const res = Result.Ok(1); | ||
* const result = res.unwrapOr(0); | ||
* // result === 1 | ||
* | ||
* const res = Result.Error("error"); | ||
* const result = res.unwrapOr(0); | ||
* // result === 0 | ||
* ``` | ||
*/ | ||
unwrapOr<U = T>(or_value: U): T | U; | ||
/** | ||
* Returns the `T` of an `Ok<T, E>`, or the result of running `or_fn` if | ||
* the result is an `Error` | ||
* | ||
* ## Example | ||
* ```ts | ||
* const res = Result.Ok(1); | ||
* const result = res.unwrapOrElse(() => 0); | ||
* // result === 1 | ||
* | ||
* const res = Result.Error("error"); | ||
* const result = res.unwrapOrElse(() => 0); | ||
* // result === 0 | ||
* ``` | ||
*/ | ||
unwrapOrElse<U = T>(or_fn: (e: E) => U): T | U; | ||
/** | ||
* Converts the `Result<T, E>` to an `Option<T>`, discarding the `Error` | ||
* if the result is an `Error` | ||
* | ||
* ## Example | ||
* ```ts | ||
* const res = Result.Ok(1); | ||
* const result = res.ok(); | ||
* // result === Option.Some(1) | ||
* | ||
* const res = Result.Error("error"); | ||
* const result = res.ok(); | ||
* // result === Option.None() | ||
* ``` | ||
*/ | ||
ok(): Option<T>; | ||
toJSON(): JsonResult<T, E>; | ||
} | ||
@@ -310,476 +310,471 @@ type Ok<T, E> = __Ok<T, E>; | ||
type JsonResult<T, E> = { | ||
__orf_type__: "Result"; | ||
tag: "Ok"; | ||
value: T; | ||
__orf_type__: "Result"; | ||
tag: "Ok"; | ||
value: T; | ||
} | { | ||
__orf_type__: "Result"; | ||
tag: "Error"; | ||
error: E; | ||
__orf_type__: "Result"; | ||
tag: "Error"; | ||
error: E; | ||
}; | ||
type Result<T, E> = Ok<T, E> | Error<T, E>; | ||
declare namespace Result { | ||
/** | ||
* Creates an `Ok<T, never>` with the provided value | ||
*/ | ||
function Ok<T, E = never>(value: T): Result<T, E>; | ||
/** | ||
* Creates an `Error<never, E>` with the provided error | ||
*/ | ||
function Error<T = never, E = never>(value: E): Result<T, E>; | ||
/** | ||
* Typeguard to check if `thing` is a `Result` | ||
* | ||
* ## Example | ||
* ```ts | ||
* const result = Result.Ok(1); | ||
* if (Result.isResult(result)) { | ||
* // result is a Result | ||
* } | ||
* ``` | ||
*/ | ||
function isResult<T, E>(thing: unknown): thing is Result<T, E>; | ||
/** | ||
* Creates a `Result` from an execution function, catching any errors | ||
* | ||
* Optionally, an error function can be provided to transform the error | ||
* | ||
* ## Example | ||
* ```ts | ||
* const result = Result.fromExecution(() => 1); | ||
* // result === Result.Ok(1) | ||
* | ||
* const result = Result.fromExecution( | ||
* () => { | ||
* return JSON.parse("bobmarley") as number; | ||
* }, | ||
* (error) => { | ||
* return { code: "INVALID_JSON", message: error.message } | ||
* } | ||
* ); | ||
* // result === Result.Error({ code: "INVALID_JSON", message: "..." }) | ||
* ``` | ||
* | ||
*/ | ||
function fromExecution<T, E = unknown>(exec_fn: () => T, err_fn?: (error: unknown) => E): Result<T, E>; | ||
/** | ||
* Creates a `Result` from an awaitable, catching any errors | ||
* | ||
* Optionally, an error function can be provided to transform the error | ||
* | ||
* ## Example | ||
* ```ts | ||
* const result = await Result.fromAwaitable(Promise.resolve(1)); | ||
* // result === Result.Ok(1) | ||
* | ||
* const result = await Result.fromAwaitable(Promise.reject("NOPE")); | ||
* // result === Result.Error("NOPE") | ||
* ``` | ||
*/ | ||
function fromAwaitable<T, E = unknown>(promise: Promise<T>, err_fn?: (error: unknown) => E): Promise<Result<Awaited<T>, never> | Result<never, E>>; | ||
/** | ||
* Creates a `Result<[A, B, ...], E | F | ...>` from an array of `Result`s | ||
* | ||
* If any of the `Result`s are an `Error`, the first `Error` found is returned | ||
* Otherwise, an `Ok` is returned with an array of the values | ||
* | ||
* ## Example | ||
* ```ts | ||
* const result = Result.all([Result.Ok(1), Result.Ok("hi")]); | ||
* // result === Result.Ok([1, "hi"]) | ||
* | ||
* const result = Result.all([Result.Ok(1), Result.Error("error1"), Result.Error("error2")]); | ||
* // result === Result.Error("error1") | ||
*``` | ||
*/ | ||
function all<T extends Array<Result<any, any>>>(array: [...T]): Result<{ | ||
[I in keyof T]: orf.InferOkType<T[I]>; | ||
}, orf.InferErrorType<T[number]>>; | ||
/** | ||
* Creates a `Result<{ a: A, b: B, ... }, E | F | ...>` from a dictionary of `Result`s | ||
* | ||
* If any of the `Result`s are an `Error`, the first `Error` found is returned | ||
* Otherwise, an `Ok` is returned with an object of the values | ||
* | ||
* ## Example | ||
* ```ts | ||
* const result = Result.allFromDict({ | ||
* a: Result.Ok(1), | ||
* b: Result.Ok("hi"), | ||
* }); | ||
* // result === Result.Ok({ a: 1, b: "hi" }) | ||
* | ||
* const result = Result.allFromDict({ | ||
* a: Result.Ok(1), | ||
* b: Result.Error("error1"), | ||
* c: Result.Error("error2"), | ||
* }); | ||
* // result === Result.Error("error1") | ||
* ``` | ||
*/ | ||
function allFromDict<D extends { | ||
[K: PropertyKey]: Result<any, any>; | ||
}>(dict: D): Result<{ | ||
[K in keyof D]: orf.InferOkType<D[K]>; | ||
}, orf.InferErrorType<D[keyof D]>>; | ||
/** | ||
* Converts a JSON representation of a `Result<T, E>` (`JsonResult<T, E>`) back into | ||
* a `Result` or throws an exception if it isn't a valid `JsonResult` | ||
* | ||
* ## Example | ||
* ```ts | ||
* const json = { __orf_type__: "Result", tag: "Ok", value: 1 }; | ||
* const result = Result.fromJSON(json); | ||
* // result === Result.Ok(1) | ||
* ``` | ||
*/ | ||
function fromJSON<T, E>(json: JsonResult<T, E>): Result<T, E>; | ||
/** | ||
* Creates an `Ok<T, never>` with the provided value | ||
*/ | ||
function Ok<T, E = never>(value: T): Result<T, E>; | ||
/** | ||
* Creates an `Error<never, E>` with the provided error | ||
*/ | ||
function Error<T = never, E = never>(value: E): Result<T, E>; | ||
/** | ||
* Typeguard to check if `thing` is a `Result` | ||
* | ||
* ## Example | ||
* ```ts | ||
* const result = Result.Ok(1); | ||
* if (Result.isResult(result)) { | ||
* // result is a Result | ||
* } | ||
* ``` | ||
*/ | ||
function isResult<T, E>(thing: unknown): thing is Result<T, E>; | ||
/** | ||
* Creates a `Result` from an execution function, catching any errors | ||
* | ||
* Optionally, an error function can be provided to transform the error | ||
* | ||
* ## Example | ||
* ```ts | ||
* const result = Result.fromExecution(() => 1); | ||
* // result === Result.Ok(1) | ||
* | ||
* const result = Result.fromExecution( | ||
* () => { | ||
* return JSON.parse("bobmarley") as number; | ||
* }, | ||
* (error) => { | ||
* return { code: "INVALID_JSON", message: error.message } | ||
* } | ||
* ); | ||
* // result === Result.Error({ code: "INVALID_JSON", message: "..." }) | ||
* ``` | ||
* | ||
*/ | ||
function fromExecution<T, E = unknown>(exec_fn: () => T, err_fn?: (error: unknown) => E): Result<T, E>; | ||
/** | ||
* Creates a `Result` from an awaitable, catching any errors | ||
* | ||
* Optionally, an error function can be provided to transform the error | ||
* | ||
* ## Example | ||
* ```ts | ||
* const result = await Result.fromAwaitable(Promise.resolve(1)); | ||
* // result === Result.Ok(1) | ||
* | ||
* const result = await Result.fromAwaitable(Promise.reject("NOPE")); | ||
* // result === Result.Error("NOPE") | ||
* ``` | ||
*/ | ||
function fromAwaitable<T, E = unknown>(promise: Promise<T>, err_fn?: (error: unknown) => E): Promise<Result<Awaited<T>, never> | Result<never, E>>; | ||
/** | ||
* Creates a `Result<[A, B, ...], E | F | ...>` from an array of `Result`s | ||
* | ||
* If any of the `Result`s are an `Error`, the first `Error` found is returned | ||
* Otherwise, an `Ok` is returned with an array of the values | ||
* | ||
* ## Example | ||
* ```ts | ||
* const result = Result.all([Result.Ok(1), Result.Ok("hi")]); | ||
* // result === Result.Ok([1, "hi"]) | ||
* | ||
* const result = Result.all([Result.Ok(1), Result.Error("error1"), Result.Error("error2")]); | ||
* // result === Result.Error("error1") | ||
*``` | ||
*/ | ||
function all<T extends Array<Result<any, any>>>(array: [...T]): Result<{ [I in keyof T]: orf.InferOkType<T[I]> }, orf.InferErrorType<T[number]>>; | ||
/** | ||
* Creates a `Result<{ a: A, b: B, ... }, E | F | ...>` from a dictionary of `Result`s | ||
* | ||
* If any of the `Result`s are an `Error`, the first `Error` found is returned | ||
* Otherwise, an `Ok` is returned with an object of the values | ||
* | ||
* ## Example | ||
* ```ts | ||
* const result = Result.allFromDict({ | ||
* a: Result.Ok(1), | ||
* b: Result.Ok("hi"), | ||
* }); | ||
* // result === Result.Ok({ a: 1, b: "hi" }) | ||
* | ||
* const result = Result.allFromDict({ | ||
* a: Result.Ok(1), | ||
* b: Result.Error("error1"), | ||
* c: Result.Error("error2"), | ||
* }); | ||
* // result === Result.Error("error1") | ||
* ``` | ||
*/ | ||
function allFromDict<D extends { | ||
[K: PropertyKey]: Result<any, any>; | ||
}>(dict: D): Result<{ [K in keyof D]: orf.InferOkType<D[K]> }, orf.InferErrorType<D[keyof D]>>; | ||
/** | ||
* Converts a JSON representation of a `Result<T, E>` (`JsonResult<T, E>`) back into | ||
* a `Result` or throws an exception if it isn't a valid `JsonResult` | ||
* | ||
* ## Example | ||
* ```ts | ||
* const json = { __orf_type__: "Result", tag: "Ok", value: 1 }; | ||
* const result = Result.fromJSON(json); | ||
* // result === Result.Ok(1) | ||
* ``` | ||
*/ | ||
function fromJSON<T, E>(json: JsonResult<T, E>): Result<T, E>; | ||
} | ||
declare class __Ok<T, E> implements IResult<T, E> { | ||
readonly value: T; | ||
constructor(value: T); | ||
isOk(): this is Ok<T, E>; | ||
isError(): this is Error<T, E>; | ||
match<U, V = U>(config: { | ||
Ok: (t: T) => U; | ||
Error: (e: E) => V; | ||
}): U | V; | ||
map<U>(map_fn: (t: T) => U): Result<U, E>; | ||
mapOr<U, V = U>(_or_value: U, map_fn: (t: T) => V): U | V; | ||
mapOrElse<U, V = U>(_or_fn: () => U, map_fn: (t: T) => V): U | V; | ||
mapError<F>(_map_fn: (e: E) => F): Result<T, F>; | ||
and<U, F = E>(and_value: Result<U, F>): Result<U, E | F>; | ||
andThen<R extends Result<any, any>>(and_fn: (t: T) => R): Result<orf.InferOkType<R>, orf.InferErrorType<R> | E>; | ||
or<F, U = T>(_or_value: Result<U, F>): Result<T | U, F>; | ||
orElse<R extends Result<any, any>>(_or_fn: (e: E) => R): Result<orf.InferOkType<R> | T, orf.InferErrorType<R>>; | ||
tap(fn: (t: Readonly<T>) => void): Result<T, E>; | ||
tapError(_fn: (e: Readonly<E>) => void): Result<T, E>; | ||
ok(): Option<T>; | ||
unwrap(): T; | ||
unwrapError(): E; | ||
unwrapOr<U = T>(_or_value: U): T; | ||
unwrapOrElse<U = T>(_or_fn: (e: E) => U): T; | ||
toJSON(): JsonResult<T, E>; | ||
readonly value: T; | ||
constructor(value: T); | ||
isOk(): this is Ok<T, E>; | ||
isError(): this is Error<T, E>; | ||
match<U, V = U>(config: { | ||
Ok: (t: T) => U; | ||
Error: (e: E) => V; | ||
}): U | V; | ||
map<U>(map_fn: (t: T) => U): Result<U, E>; | ||
mapOr<U, V = U>(_or_value: U, map_fn: (t: T) => V): U | V; | ||
mapOrElse<U, V = U>(_or_fn: () => U, map_fn: (t: T) => V): U | V; | ||
mapError<F>(_map_fn: (e: E) => F): Result<T, F>; | ||
and<U, F = E>(and_value: Result<U, F>): Result<U, E | F>; | ||
andThen<R extends Result<any, any>>(and_fn: (t: T) => R): Result<orf.InferOkType<R>, orf.InferErrorType<R> | E>; | ||
or<F, U = T>(_or_value: Result<U, F>): Result<T | U, F>; | ||
orElse<R extends Result<any, any>>(_or_fn: (e: E) => R): Result<orf.InferOkType<R> | T, orf.InferErrorType<R>>; | ||
tap(fn: (t: Readonly<T>) => void): Result<T, E>; | ||
tapError(_fn: (e: Readonly<E>) => void): Result<T, E>; | ||
ok(): Option<T>; | ||
unwrap(): T; | ||
unwrapError(): E; | ||
unwrapOr<U = T>(_or_value: U): T; | ||
unwrapOrElse<U = T>(_or_fn: (e: E) => U): T; | ||
toJSON(): JsonResult<T, E>; | ||
} | ||
declare class __Error<T, E> implements IResult<T, E> { | ||
readonly error: E; | ||
constructor(error: E); | ||
isOk(): this is Ok<T, E>; | ||
isError(): this is Error<T, E>; | ||
match<U, V = U>(config: { | ||
Ok: (t: T) => U; | ||
Error: (e: E) => V; | ||
}): U | V; | ||
map<U>(_map_fn: (t: T) => U): Result<U, E>; | ||
mapOr<U, V = U>(or_value: U, _map_fn: (t: T) => V): U | V; | ||
mapOrElse<U, V = U>(or_fn: () => U, _map_fn: (t: T) => V): U | V; | ||
mapError<F>(map_fn: (e: E) => F): Result<T, F>; | ||
and<U, F = E>(_and_value: Result<U, F>): Result<U, E | F>; | ||
andThen<R extends Result<any, any>>(_and_fn: (t: T) => R): Result<orf.InferOkType<R>, orf.InferErrorType<R> | E>; | ||
or<F, U = T>(or_value: Result<U, F>): Result<T | U, F>; | ||
orElse<R extends Result<any, any>>(or_fn: (e: E) => R): Result<orf.InferOkType<R> | T, orf.InferErrorType<R>>; | ||
tap(_fn: (t: Readonly<T>) => void): Result<T, E>; | ||
tapError(fn: (e: Readonly<E>) => void): Result<T, E>; | ||
ok(): Option<T>; | ||
unwrap(): T; | ||
unwrapError(): E; | ||
unwrapOr<U = T>(or_value: U): U; | ||
unwrapOrElse<U = T>(or_fn: (e: E) => U): U; | ||
toJSON(): JsonResult<T, E>; | ||
readonly error: E; | ||
constructor(error: E); | ||
isOk(): this is Ok<T, E>; | ||
isError(): this is Error<T, E>; | ||
match<U, V = U>(config: { | ||
Ok: (t: T) => U; | ||
Error: (e: E) => V; | ||
}): U | V; | ||
map<U>(_map_fn: (t: T) => U): Result<U, E>; | ||
mapOr<U, V = U>(or_value: U, _map_fn: (t: T) => V): U | V; | ||
mapOrElse<U, V = U>(or_fn: () => U, _map_fn: (t: T) => V): U | V; | ||
mapError<F>(map_fn: (e: E) => F): Result<T, F>; | ||
and<U, F = E>(_and_value: Result<U, F>): Result<U, E | F>; | ||
andThen<R extends Result<any, any>>(_and_fn: (t: T) => R): Result<orf.InferOkType<R>, orf.InferErrorType<R> | E>; | ||
or<F, U = T>(or_value: Result<U, F>): Result<T | U, F>; | ||
orElse<R extends Result<any, any>>(or_fn: (e: E) => R): Result<orf.InferOkType<R> | T, orf.InferErrorType<R>>; | ||
tap(_fn: (t: Readonly<T>) => void): Result<T, E>; | ||
tapError(fn: (e: Readonly<E>) => void): Result<T, E>; | ||
ok(): Option<T>; | ||
unwrap(): T; | ||
unwrapError(): E; | ||
unwrapOr<U = T>(or_value: U): U; | ||
unwrapOrElse<U = T>(or_fn: (e: E) => U): U; | ||
toJSON(): JsonResult<T, E>; | ||
} | ||
interface IOption<T> { | ||
/** | ||
* Used to check if the Option is a `Some`, and if it is, narrows the | ||
* `Option<T>` to `Some<T>` | ||
* | ||
* Intended to be used as a type guard | ||
* | ||
* ## Example | ||
* ```ts | ||
* const opt = Option.Some(1); | ||
* const result = opt.isSome(); | ||
* // result === true | ||
* | ||
* const opt = Option.None<number>(); | ||
* const result = opt.isSome(); | ||
* // result === false | ||
* ``` | ||
*/ | ||
isSome(): this is Some<T>; | ||
/** | ||
* Used to check if the Option is `None`, and if it is, narrows the | ||
* `Option<T>` to `None<T>` | ||
* | ||
* Intended to be used as a type guard | ||
* | ||
* ## Example | ||
* ```ts | ||
* const opt = Option.Some(1); | ||
* const result = opt.isNone(); | ||
* // result === false | ||
* | ||
* const opt = Option.None<number>(); | ||
* const result = opt.isNone(); | ||
* // result === true | ||
* ``` | ||
*/ | ||
isNone(): this is None<T>; | ||
/** | ||
* Runs the function provided in the `Some` or `None` branch, passing the | ||
* value or nothing respectivly | ||
* | ||
* ## Example | ||
* ```ts | ||
* const opt = Option.Some(1); | ||
* const result = opt.match({ | ||
* Some: (value) => value, | ||
* None: () => 0, | ||
* }); | ||
* // result === 1 | ||
* | ||
* | ||
* const opt = Option.None(); | ||
* const result = opt.match({ | ||
* Some: (value) => value, | ||
* None: () => 0, | ||
* }); | ||
* // result === 0 | ||
* ``` | ||
*/ | ||
match<U, V = U>(config: { | ||
Some: (t: T) => U; | ||
None: () => V; | ||
}): U | V; | ||
/** | ||
* Maps `Some<T>` to `Some<U>`, or returns the existing `None` | ||
* | ||
* ## Example | ||
* ```ts | ||
* const opt = Option.Some(1); | ||
* const result = opt.map((val) => `${val * 2}`); | ||
* // result === Option.Some("2") | ||
* | ||
* const opt = Option.None<number>(); | ||
* const result = opt.map((val) => `${val * 2}`); | ||
* // result === Option.None() | ||
* ``` | ||
*/ | ||
map<U>(fn: (t: T) => U): Option<U>; | ||
/** | ||
* Maps `Some<T>` to `V`, or returns the given `or_value` | ||
* | ||
* ## Example | ||
* ```ts | ||
* const opt = Option.Some(1); | ||
* const result = opt.mapOr(0, (val) => `${val * 2}`); | ||
* // result === "2" | ||
* | ||
* const opt = Option.None<number>(); | ||
* const result = opt.mapOr(0, (val) => `${val * 2}`); | ||
* // result === 0 | ||
* ``` | ||
*/ | ||
mapOr<U, V = U>(or_value: U, fn: (t: T) => V): U | V; | ||
/** | ||
* Maps `Some<T>` to `V`, or returns the result of running `or_fn` | ||
* | ||
* ## Example | ||
* ```ts | ||
* const opt = Option.Some(1); | ||
* const result = opt.mapOrElse(() => 0, (val) => `${val * 2}`); | ||
* // result === "2" | ||
* | ||
* const opt = Option.None<number>(); | ||
* const result = opt.mapOrElse(() => 0, (val) => `${val * 2}`); | ||
* // result === 0 | ||
* ``` | ||
*/ | ||
mapOrElse<U, V = U>(or_fn: () => U, map_fn: (t: T) => V): U | V; | ||
/** | ||
* Returns the existing `None` if the option is `None`, otherwise returns `other` | ||
* | ||
* ## Example | ||
* ```ts | ||
* const opt = Option.Some(1); | ||
* const result = opt.and(Option.Some("2")); | ||
* // result === Option.Some("2") | ||
* | ||
* const opt = Option.None<number>(); | ||
* const result = opt.and(Option.Some("2")); | ||
* // result === Option.None() | ||
* ``` | ||
*/ | ||
and<U>(other: Option<U>): Option<U>; | ||
/** | ||
* Returns the existing `None` if the option is `None`, otherwise returns the | ||
* result of running `fn` with the value held in `Some` | ||
* | ||
* ## Examle | ||
* ```ts | ||
* const opt = Option.Some(1); | ||
* const result = opt.andThen((val) => Option.Some(`${val * 2}`)); | ||
* // result === Option.Some("2") | ||
* | ||
* const opt = Option.None<number>(); | ||
* const result = opt.andThen(() => Option.Some("Hi")); | ||
* // result === Option.None() | ||
* ``` | ||
*/ | ||
andThen<O extends Option<any | never>>(fn: (t: T) => O): Option<orf.InferInnerType<O> | T>; | ||
/** | ||
* Returns `other` if the option is `None`, otherwise returns the existing `Some<T>` | ||
* | ||
* ## Example | ||
* ```ts | ||
* const opt = Option.Some(1); | ||
* const result = opt.or(Option.Some(2)); | ||
* // result === Option.Some(1) | ||
* | ||
* const opt = Option.None<number>(); | ||
* const result = opt.or(Option.Some(2)); | ||
* // result === Option.Some(2) | ||
* ``` | ||
*/ | ||
or(other: Option<T>): Option<T>; | ||
/** | ||
* Returns the existing `Some<T>` if the option is `Some`, otherwise returns the | ||
* result of running `fn` | ||
* | ||
* ## Example | ||
* ```ts | ||
* const opt = Option.Some(1); | ||
* const result = opt.orElse(() => Option.Some(2)); | ||
* // result === Option.Some(1) | ||
* | ||
* const opt = Option.None<number>(); | ||
* const result = opt.orElse(() => Option.Some(2)); | ||
* // result === Option.Some(2) | ||
* ``` | ||
*/ | ||
orElse<O extends Option<any | never>>(fn: () => O): Option<orf.InferInnerType<O> | T>; | ||
/** | ||
* Runs the provided function with `Readonly<T>` if the option is `Some`, and then | ||
* returns the existing `Some<T>`; otherwise does nothing and returns the existing | ||
* `None` | ||
* | ||
* ## Example | ||
* ```ts | ||
* const opt = Option.Some(1); | ||
* const result = opt.tap((val) => { | ||
* console.log("original:", val); | ||
* console.log("doubled:", val * 2); | ||
* }); | ||
* // Logs "original: 1" | ||
* // Logs "doubled: 2" | ||
* // result === Option.Some(1) | ||
* | ||
* const opt = Option.None<number>(); | ||
* const result = opt.tap((val) => { | ||
* console.log("original:", val); | ||
* console.log("doubled:", val * 2); | ||
* }); | ||
* // Does not log anything | ||
* // result === Option.None() | ||
* ``` | ||
*/ | ||
tap(fn: (t: Readonly<T>) => void): Option<T>; | ||
/** | ||
* Returns the `T` of a `Some<T>`, or throws an exception if the option is `None` | ||
* | ||
* **Prefer `unwrapOr` or `unwrapOrElse` over this method** | ||
* | ||
* ## Example | ||
* ```ts | ||
* const opt = Option.Some(1); | ||
* const result = opt.unwrap(); | ||
* // result === 1 | ||
* | ||
* const opt = Option.None<number>(); | ||
* const result = opt.unwrap(); | ||
* // Throws an exception | ||
*/ | ||
unwrap(): T; | ||
/** | ||
* Returns the `T` of a `Some<T>`, or returns the provided `or_value` if the | ||
* option is `None` | ||
* | ||
* ## Example | ||
* ```ts | ||
* const opt = Option.Some(1); | ||
* const result = opt.unwrapOr(0); | ||
* // result === 1 | ||
* | ||
* const opt = Option.None<number>(); | ||
* const result = opt.unwrapOr(0); | ||
* // result === 0 | ||
* ``` | ||
*/ | ||
unwrapOr<U = T>(or_value: U): T | U; | ||
/** | ||
* Returns the `T` of a `Some<T>`, or returns the result of running `or_fn` if | ||
* the option is `None` | ||
* | ||
* ## Example | ||
* ```ts | ||
* const opt = Option.Some(1); | ||
* const result = opt.unwrapOrElse(() => 0); | ||
* // result === 1 | ||
* | ||
* const opt = Option.None<number>(); | ||
* const result = opt.unwrapOrElse(() => 0); | ||
* // result === 0 | ||
* ``` | ||
*/ | ||
unwrapOrElse<U = T>(or_fn: () => U): T | U; | ||
/** | ||
* Converts the `Option<T>` to a `Result<T, E>`, using the provided `error` as | ||
* the error value if the option is `None` | ||
* | ||
* ## Example | ||
* ```ts | ||
* const opt = Option.Some(1); | ||
* const result = opt.okOr("error"); | ||
* // result === Result.Ok(1) | ||
* | ||
* const opt = Option.None<number>(); | ||
* const result = opt.okOr("error"); | ||
* // result === Result.Error("error") | ||
* ``` | ||
*/ | ||
okOr<E>(error: E): Result<T, E>; | ||
/** | ||
* Converts the `Option<T>` to a `Result<T, E>`, using the result of running `fn` | ||
* as the error value if the option is `None` | ||
* | ||
* ## Example | ||
* ```ts | ||
* const opt = Option.Some(1); | ||
* const result = opt.okOrElse(() => "error"); | ||
* // result === Result.Ok(1) | ||
* | ||
* const opt = Option.None<number>(); | ||
* const result = opt.okOrElse(() => "error"); | ||
* // result === Result.Error("error") | ||
* ``` | ||
*/ | ||
okOrElse<E>(fn: () => E): Result<T, E>; | ||
/** | ||
* Converts the `Option<T>` to a JSON representation | ||
* | ||
* This is used when calling `JSON.stringify` on an `Option`, but is also | ||
* useful for serialization across network boundaries - e.g. to be returned | ||
* from a React server-action | ||
* | ||
* ## Example | ||
* ```ts | ||
* const opt = Option.Some(1); | ||
* const result = opt.toJSON(); | ||
* // result === { __orf_type__: "Option", tag: "Some", value: 1 } | ||
* | ||
* const opt = Option.None<number>(); | ||
* const result = opt.toJSON(); | ||
* // result === { __orf_type__: "Option", tag: "None" } | ||
* ``` | ||
*/ | ||
toJSON(): JsonOption<T>; | ||
/** | ||
* Used to check if the Option is a `Some`, and if it is, narrows the | ||
* `Option<T>` to `Some<T>` | ||
* | ||
* Intended to be used as a type guard | ||
* | ||
* ## Example | ||
* ```ts | ||
* const opt = Option.Some(1); | ||
* const result = opt.isSome(); | ||
* // result === true | ||
* | ||
* const opt = Option.None<number>(); | ||
* const result = opt.isSome(); | ||
* // result === false | ||
* ``` | ||
*/ | ||
isSome(): this is Some<T>; | ||
/** | ||
* Used to check if the Option is `None`, and if it is, narrows the | ||
* `Option<T>` to `None<T>` | ||
* | ||
* Intended to be used as a type guard | ||
* | ||
* ## Example | ||
* ```ts | ||
* const opt = Option.Some(1); | ||
* const result = opt.isNone(); | ||
* // result === false | ||
* | ||
* const opt = Option.None<number>(); | ||
* const result = opt.isNone(); | ||
* // result === true | ||
* ``` | ||
*/ | ||
isNone(): this is None<T>; | ||
/** | ||
* Runs the function provided in the `Some` or `None` branch, passing the | ||
* value or nothing respectivly | ||
* | ||
* ## Example | ||
* ```ts | ||
* const opt = Option.Some(1); | ||
* const result = opt.match({ | ||
* Some: (value) => value, | ||
* None: () => 0, | ||
* }); | ||
* // result === 1 | ||
* | ||
* | ||
* const opt = Option.None(); | ||
* const result = opt.match({ | ||
* Some: (value) => value, | ||
* None: () => 0, | ||
* }); | ||
* // result === 0 | ||
* ``` | ||
*/ | ||
match<U, V = U>(config: { | ||
Some: (t: T) => U; | ||
None: () => V; | ||
}): U | V; | ||
/** | ||
* Maps `Some<T>` to `Some<U>`, or returns the existing `None` | ||
* | ||
* ## Example | ||
* ```ts | ||
* const opt = Option.Some(1); | ||
* const result = opt.map((val) => `${val * 2}`); | ||
* // result === Option.Some("2") | ||
* | ||
* const opt = Option.None<number>(); | ||
* const result = opt.map((val) => `${val * 2}`); | ||
* // result === Option.None() | ||
* ``` | ||
*/ | ||
map<U>(fn: (t: T) => U): Option<U>; | ||
/** | ||
* Maps `Some<T>` to `V`, or returns the given `or_value` | ||
* | ||
* ## Example | ||
* ```ts | ||
* const opt = Option.Some(1); | ||
* const result = opt.mapOr(0, (val) => `${val * 2}`); | ||
* // result === "2" | ||
* | ||
* const opt = Option.None<number>(); | ||
* const result = opt.mapOr(0, (val) => `${val * 2}`); | ||
* // result === 0 | ||
* ``` | ||
*/ | ||
mapOr<U, V = U>(or_value: U, fn: (t: T) => V): U | V; | ||
/** | ||
* Maps `Some<T>` to `V`, or returns the result of running `or_fn` | ||
* | ||
* ## Example | ||
* ```ts | ||
* const opt = Option.Some(1); | ||
* const result = opt.mapOrElse(() => 0, (val) => `${val * 2}`); | ||
* // result === "2" | ||
* | ||
* const opt = Option.None<number>(); | ||
* const result = opt.mapOrElse(() => 0, (val) => `${val * 2}`); | ||
* // result === 0 | ||
* ``` | ||
*/ | ||
mapOrElse<U, V = U>(or_fn: () => U, map_fn: (t: T) => V): U | V; | ||
/** | ||
* Returns the existing `None` if the option is `None`, otherwise returns `other` | ||
* | ||
* ## Example | ||
* ```ts | ||
* const opt = Option.Some(1); | ||
* const result = opt.and(Option.Some("2")); | ||
* // result === Option.Some("2") | ||
* | ||
* const opt = Option.None<number>(); | ||
* const result = opt.and(Option.Some("2")); | ||
* // result === Option.None() | ||
* ``` | ||
*/ | ||
and<U>(other: Option<U>): Option<U>; | ||
/** | ||
* Returns the existing `None` if the option is `None`, otherwise returns the | ||
* result of running `fn` with the value held in `Some` | ||
* | ||
* ## Examle | ||
* ```ts | ||
* const opt = Option.Some(1); | ||
* const result = opt.andThen((val) => Option.Some(`${val * 2}`)); | ||
* // result === Option.Some("2") | ||
* | ||
* const opt = Option.None<number>(); | ||
* const result = opt.andThen(() => Option.Some("Hi")); | ||
* // result === Option.None() | ||
* ``` | ||
*/ | ||
andThen<O extends Option<any | never>>(fn: (t: T) => O): Option<orf.InferInnerType<O> | T>; | ||
/** | ||
* Returns `other` if the option is `None`, otherwise returns the existing `Some<T>` | ||
* | ||
* ## Example | ||
* ```ts | ||
* const opt = Option.Some(1); | ||
* const result = opt.or(Option.Some(2)); | ||
* // result === Option.Some(1) | ||
* | ||
* const opt = Option.None<number>(); | ||
* const result = opt.or(Option.Some(2)); | ||
* // result === Option.Some(2) | ||
* ``` | ||
*/ | ||
or(other: Option<T>): Option<T>; | ||
/** | ||
* Returns the existing `Some<T>` if the option is `Some`, otherwise returns the | ||
* result of running `fn` | ||
* | ||
* ## Example | ||
* ```ts | ||
* const opt = Option.Some(1); | ||
* const result = opt.orElse(() => Option.Some(2)); | ||
* // result === Option.Some(1) | ||
* | ||
* const opt = Option.None<number>(); | ||
* const result = opt.orElse(() => Option.Some(2)); | ||
* // result === Option.Some(2) | ||
* ``` | ||
*/ | ||
orElse<O extends Option<any | never>>(fn: () => O): Option<orf.InferInnerType<O> | T>; | ||
/** | ||
* Runs the provided function with `Readonly<T>` if the option is `Some`, and then | ||
* returns the existing `Some<T>`; otherwise does nothing and returns the existing | ||
* `None` | ||
* | ||
* ## Example | ||
* ```ts | ||
* const opt = Option.Some(1); | ||
* const result = opt.tap((val) => { | ||
* console.log("original:", val); | ||
* console.log("doubled:", val * 2); | ||
* }); | ||
* // Logs "original: 1" | ||
* // Logs "doubled: 2" | ||
* // result === Option.Some(1) | ||
* | ||
* const opt = Option.None<number>(); | ||
* const result = opt.tap((val) => { | ||
* console.log("original:", val); | ||
* console.log("doubled:", val * 2); | ||
* }); | ||
* // Does not log anything | ||
* // result === Option.None() | ||
* ``` | ||
*/ | ||
tap(fn: (t: Readonly<T>) => void): Option<T>; | ||
/** | ||
* Returns the `T` of a `Some<T>`, or throws an exception if the option is `None` | ||
* | ||
* **Prefer `unwrapOr` or `unwrapOrElse` over this method** | ||
* | ||
* ## Example | ||
* ```ts | ||
* const opt = Option.Some(1); | ||
* const result = opt.unwrap(); | ||
* // result === 1 | ||
* | ||
* const opt = Option.None<number>(); | ||
* const result = opt.unwrap(); | ||
* // Throws an exception | ||
*/ | ||
unwrap(): T; | ||
/** | ||
* Returns the `T` of a `Some<T>`, or returns the provided `or_value` if the | ||
* option is `None` | ||
* | ||
* ## Example | ||
* ```ts | ||
* const opt = Option.Some(1); | ||
* const result = opt.unwrapOr(0); | ||
* // result === 1 | ||
* | ||
* const opt = Option.None<number>(); | ||
* const result = opt.unwrapOr(0); | ||
* // result === 0 | ||
* ``` | ||
*/ | ||
unwrapOr<U = T>(or_value: U): T | U; | ||
/** | ||
* Returns the `T` of a `Some<T>`, or returns the result of running `or_fn` if | ||
* the option is `None` | ||
* | ||
* ## Example | ||
* ```ts | ||
* const opt = Option.Some(1); | ||
* const result = opt.unwrapOrElse(() => 0); | ||
* // result === 1 | ||
* | ||
* const opt = Option.None<number>(); | ||
* const result = opt.unwrapOrElse(() => 0); | ||
* // result === 0 | ||
* ``` | ||
*/ | ||
unwrapOrElse<U = T>(or_fn: () => U): T | U; | ||
/** | ||
* Converts the `Option<T>` to a `Result<T, E>`, using the provided `error` as | ||
* the error value if the option is `None` | ||
* | ||
* ## Example | ||
* ```ts | ||
* const opt = Option.Some(1); | ||
* const result = opt.okOr("error"); | ||
* // result === Result.Ok(1) | ||
* | ||
* const opt = Option.None<number>(); | ||
* const result = opt.okOr("error"); | ||
* // result === Result.Error("error") | ||
* ``` | ||
*/ | ||
okOr<E>(error: E): Result<T, E>; | ||
/** | ||
* Converts the `Option<T>` to a `Result<T, E>`, using the result of running `fn` | ||
* as the error value if the option is `None` | ||
* | ||
* ## Example | ||
* ```ts | ||
* const opt = Option.Some(1); | ||
* const result = opt.okOrElse(() => "error"); | ||
* // result === Result.Ok(1) | ||
* | ||
* const opt = Option.None<number>(); | ||
* const result = opt.okOrElse(() => "error"); | ||
* // result === Result.Error("error") | ||
* ``` | ||
*/ | ||
okOrElse<E>(fn: () => E): Result<T, E>; | ||
/** | ||
* Converts the `Option<T>` to a JSON representation | ||
* | ||
* This is used when calling `JSON.stringify` on an `Option`, but is also | ||
* useful for serialization across network boundaries - e.g. to be returned | ||
* from a React server-action | ||
* | ||
* ## Example | ||
* ```ts | ||
* const opt = Option.Some(1); | ||
* const result = opt.toJSON(); | ||
* // result === { __orf_type__: "Option", tag: "Some", value: 1 } | ||
* | ||
* const opt = Option.None<number>(); | ||
* const result = opt.toJSON(); | ||
* // result === { __orf_type__: "Option", tag: "None" } | ||
* ``` | ||
*/ | ||
toJSON(): JsonOption<T>; | ||
} | ||
@@ -789,243 +784,289 @@ type Some<T> = __Some<T>; | ||
type JsonOption<T> = { | ||
__orf_type__: "Option"; | ||
__orf_type__: "Option"; | ||
} & ({ | ||
tag: "Some"; | ||
value: T; | ||
tag: "Some"; | ||
value: T; | ||
} | { | ||
tag: "None"; | ||
tag: "None"; | ||
}); | ||
type Option<T> = Some<T> | None<T>; | ||
declare namespace Option { | ||
/** | ||
* Creates a `Some<T>` with the provided value | ||
*/ | ||
function Some<T>(t: T): Some<T>; | ||
/** | ||
* Creates a `None<T>` | ||
*/ | ||
function None<T = never>(): None<T>; | ||
/** | ||
* Typeguard to check if `thing` is an `Option` | ||
* | ||
* ## Example | ||
* ```ts | ||
* const opt = Option.Some(1); | ||
* if (Option.isOption(opt)) { | ||
* // opt is an Option<unknown> | ||
* } | ||
* ``` | ||
*/ | ||
function isOption(thing: unknown): thing is Option<unknown>; | ||
/** | ||
* Converts a `T | null | undefined` to an `Option<T>`, where `null` and `undefined` | ||
* become `None`, and any other value becomes `Some` | ||
* | ||
* ## Example | ||
* ```ts | ||
* const opt = Option.from(1); | ||
* // opt === Option.Some(1) | ||
* | ||
* const opt = Option.from(null); | ||
* // opt === Option.None() | ||
* ``` | ||
*/ | ||
function from<T>(thing: T | null | undefined): Option<NonNullable<T>>; | ||
/** | ||
* Converts a JSON representation of an `Option<T>` (`JsonOption<T>`) to an `Option<T>`, | ||
* or throws an exception if it isn't a valid `JsonOption` | ||
* | ||
* ## Example | ||
* ```ts | ||
* const json: JsonOption<number> = { __orf_type__: "Option", tag: "Some", value: 1 }; | ||
* const opt = Option.fromJSON(json); | ||
* // opt === Option.Some(1) | ||
* ``` | ||
*/ | ||
function fromJSON<T>(json: JsonOption<T>): Option<T>; | ||
/** | ||
* Creates a `Some<T>` with the provided value | ||
*/ | ||
function Some<T>(t: T): Some<T>; | ||
/** | ||
* Creates a `None<T>` | ||
*/ | ||
function None<T = never>(): None<T>; | ||
/** | ||
* Typeguard to check if `thing` is an `Option` | ||
* | ||
* ## Example | ||
* ```ts | ||
* const opt = Option.Some(1); | ||
* if (Option.isOption(opt)) { | ||
* // opt is an Option<unknown> | ||
* } | ||
* ``` | ||
*/ | ||
function isOption(thing: unknown): thing is Option<unknown>; | ||
/** | ||
* Converts a `T | null | undefined` to an `Option<T>`, where `null` and `undefined` | ||
* become `None`, and any other value becomes `Some` | ||
* | ||
* ## Example | ||
* ```ts | ||
* const opt = Option.from(1); | ||
* // opt === Option.Some(1) | ||
* | ||
* const opt = Option.from(null); | ||
* // opt === Option.None() | ||
* ``` | ||
*/ | ||
function from<T>(thing: T | null | undefined): Option<NonNullable<T>>; | ||
/** | ||
* Converts a JSON representation of an `Option<T>` (`JsonOption<T>`) to an `Option<T>`, | ||
* or throws an exception if it isn't a valid `JsonOption` | ||
* | ||
* ## Example | ||
* ```ts | ||
* const json: JsonOption<number> = { __orf_type__: "Option", tag: "Some", value: 1 }; | ||
* const opt = Option.fromJSON(json); | ||
* // opt === Option.Some(1) | ||
* ``` | ||
*/ | ||
function fromJSON<T>(json: JsonOption<T>): Option<T>; | ||
} | ||
declare class __Some<T> implements IOption<T> { | ||
readonly value: T; | ||
constructor(value: T); | ||
isSome(): this is Some<T>; | ||
isNone(): this is None<T>; | ||
match<U, V = U>(config: { | ||
Some: (t: T) => U; | ||
None: () => V; | ||
}): U | V; | ||
map<U>(fn: (t: T) => U): Option<U>; | ||
mapOr<U, V = U>(_or_value: U, fn: (t: T) => V): U | V; | ||
mapOrElse<U, V = U>(_or_fn: () => U, map_fn: (t: T) => V): U | V; | ||
and<U>(other: Option<U>): Option<U>; | ||
andThen<O extends Option<any | never>>(fn: (t: T) => O): Option<orf.InferInnerType<O> | T>; | ||
or(_other: Option<T>): Option<T>; | ||
orElse<O extends Option<any | never>>(_fn: () => O): Option<orf.InferInnerType<O> | T>; | ||
tap(fn: (t: Readonly<T>) => void): Option<T>; | ||
unwrap(): T; | ||
unwrapOr<U = T>(_or_value: U): T; | ||
unwrapOrElse<U = T>(_or_fn: () => U): T; | ||
okOr<E>(_error: E): Result<T, E>; | ||
okOrElse<E>(_fn: () => E): Result<T, E>; | ||
toJSON(): JsonOption<T>; | ||
readonly value: T; | ||
constructor(value: T); | ||
isSome(): this is Some<T>; | ||
isNone(): this is None<T>; | ||
match<U, V = U>(config: { | ||
Some: (t: T) => U; | ||
None: () => V; | ||
}): U | V; | ||
map<U>(fn: (t: T) => U): Option<U>; | ||
mapOr<U, V = U>(_or_value: U, fn: (t: T) => V): U | V; | ||
mapOrElse<U, V = U>(_or_fn: () => U, map_fn: (t: T) => V): U | V; | ||
and<U>(other: Option<U>): Option<U>; | ||
andThen<O extends Option<any | never>>(fn: (t: T) => O): Option<orf.InferInnerType<O> | T>; | ||
or(_other: Option<T>): Option<T>; | ||
orElse<O extends Option<any | never>>(_fn: () => O): Option<orf.InferInnerType<O> | T>; | ||
tap(fn: (t: Readonly<T>) => void): Option<T>; | ||
unwrap(): T; | ||
unwrapOr<U = T>(_or_value: U): T; | ||
unwrapOrElse<U = T>(_or_fn: () => U): T; | ||
okOr<E>(_error: E): Result<T, E>; | ||
okOrElse<E>(_fn: () => E): Result<T, E>; | ||
toJSON(): JsonOption<T>; | ||
} | ||
declare class __None<T> implements IOption<T> { | ||
isSome(): this is Some<T>; | ||
isNone(): this is None<T>; | ||
match<U, V = U>(config: { | ||
Some: (t: T) => U; | ||
None: () => V; | ||
}): U | V; | ||
map<U>(_fn: (t: T) => U): Option<U>; | ||
mapOr<U, V = U>(or_value: U, _fn: (t: T) => V): U | V; | ||
mapOrElse<U, V = U>(or_fn: () => U, _map_fn: (t: T) => V): U | V; | ||
and<U>(_other: Option<U>): Option<U>; | ||
andThen<O extends Option<any | never>>(_fn: (t: T) => O): Option<orf.InferInnerType<O> | T>; | ||
or(other: Option<T>): Option<T>; | ||
orElse<O extends Option<any | never>>(fn: () => O): Option<orf.InferInnerType<O> | T>; | ||
tap(_fn: (t: Readonly<T>) => void): Option<T>; | ||
unwrap(): T; | ||
unwrapOr<U = T>(or_value: U): U; | ||
unwrapOrElse<U = T>(or_fn: () => U): U; | ||
okOr<E>(error: E): Result<T, E>; | ||
okOrElse<E>(fn: () => E): Result<T, E>; | ||
toJSON(): JsonOption<T>; | ||
isSome(): this is Some<T>; | ||
isNone(): this is None<T>; | ||
match<U, V = U>(config: { | ||
Some: (t: T) => U; | ||
None: () => V; | ||
}): U | V; | ||
map<U>(_fn: (t: T) => U): Option<U>; | ||
mapOr<U, V = U>(or_value: U, _fn: (t: T) => V): U | V; | ||
mapOrElse<U, V = U>(or_fn: () => U, _map_fn: (t: T) => V): U | V; | ||
and<U>(_other: Option<U>): Option<U>; | ||
andThen<O extends Option<any | never>>(_fn: (t: T) => O): Option<orf.InferInnerType<O> | T>; | ||
or(other: Option<T>): Option<T>; | ||
orElse<O extends Option<any | never>>(fn: () => O): Option<orf.InferInnerType<O> | T>; | ||
tap(_fn: (t: Readonly<T>) => void): Option<T>; | ||
unwrap(): T; | ||
unwrapOr<U = T>(or_value: U): U; | ||
unwrapOrElse<U = T>(or_fn: () => U): U; | ||
okOr<E>(error: E): Result<T, E>; | ||
okOrElse<E>(fn: () => E): Result<T, E>; | ||
toJSON(): JsonOption<T>; | ||
} | ||
declare namespace Future { | ||
/** | ||
* Creates a `Future<T>` that is already resolved with the provided value. | ||
*/ | ||
function value<T>(thing: T): Future<T>; | ||
/** | ||
* Creates a `FallibleFuture<T, never>` that is already resolved with the | ||
* provided value. | ||
*/ | ||
function success<T, E = never>(thing: T): FallibleFuture<T, E>; | ||
/** | ||
* Creates a `FallibleFuture<T, E>` that is already resolved with the | ||
* provided error. | ||
*/ | ||
function fail<T = never, E = never>(error: E): FallibleFuture<T, E>; | ||
/** | ||
* Typeguard to theck if `thing` is a `Future` | ||
* | ||
* ## Example | ||
* ```ts | ||
* const future = Future.value(1); | ||
* if (Future.isFuture(future)) { | ||
* // future is a Future | ||
* } | ||
* ``` | ||
*/ | ||
function isFuture<T = unknown>(thing: unknown): thing is Future<T>; | ||
/** | ||
* Typeguard to theck if `thing` is a `FallibleFuture` | ||
* | ||
* ## Example | ||
* ```ts | ||
* const future = Future.success(1); | ||
* if (Future.isFallibleFuture(future)) { | ||
* // future is a FallibleFuture | ||
* } | ||
* ``` | ||
*/ | ||
function isFallibleFuture<T = unknown, E = unknown>(thing: unknown): thing is FallibleFuture<T, E>; | ||
/** | ||
* Creates a new `FallibleFuture<T, E>` from the given "Fallible": | ||
* - `Result<T, E>` as `FallibleFuture<T, E>` | ||
* - `FallibleFuture<T, E>` as is | ||
* - `Promise<T>` as `FallibleFuture<T, unknown>` | ||
*/ | ||
function fromFallible<T, E = unknown>(fallible: Result<T, E> | FallibleFuture<T, E> | Promise<T>): FallibleFuture<T, E>; | ||
/** | ||
* Creates a new `Future<T>` with the value passed to `execute`s `resolve` function. | ||
* Will immediately start executing the `execute` function, unless `lazy` is set to | ||
* `true` in the options. | ||
* | ||
* @param `execute` - A function that takes a `resolve` function that will be called | ||
* with the value of the future when it is resolved. A cleanup function to call when | ||
* the future is cancelled can be returned. | ||
* | ||
* ## Example | ||
* ```ts | ||
* const future = Future.make<number>((resolve) => { | ||
* setTimeout(() => resolve(1), 1000); | ||
* return () => console.log("cancelled"); | ||
* }); | ||
* ``` | ||
*/ | ||
function make<T>(execute: ExecuteFutureFn<T>, options?: FutureOptions): Future<T>; | ||
/** | ||
* A shortcut for creating a `Future<T>` that is lazily executed. | ||
* | ||
* @param `execute` - A function that takes a `resolve` function that will be called | ||
* with the value of the future when it is resolved. A cleanup function to call when | ||
* the future is cancelled can be returned. | ||
* | ||
* ## Example | ||
* ```ts | ||
* const future = Future.lazy<number>((resolve) => { | ||
* setTimeout(() => resolve(1), 1000); | ||
* return () => console.log("cancelled"); | ||
* }); | ||
* ``` | ||
*/ | ||
function lazy<T>(execute: ExecuteFutureFn<T>): Future<T>; | ||
/** | ||
* Creates a new `FallibleFuture<T, E>` with the value passed to `execute`s `succeed` | ||
* function, or the error passed to `execute`s `fail` function. Will immediately start | ||
* executing the `execute` function, unless `lazy` is set to `true` in the options. | ||
* | ||
* @param `execute` - A function that takes a `succeed` function that will be called | ||
* with the value of the future when it is resolved, and a `fail` function that will | ||
* be called with the error of the future if it fails. A cleanup function to call when | ||
* the future is cancelled can be returned. | ||
* | ||
* ## Example | ||
* ```ts | ||
* const future = Future.makeFallible<number, string>((succeed, fail) => { | ||
* setTimeout(() => Math.random() > 0.5 ? succeed(1) : fail("BOO"), 1000); | ||
* return () => console.log("cancelled"); | ||
* }); | ||
* ``` | ||
*/ | ||
function makeFallible<T, E = unknown>(execute: ExecuteFallibleFutureFn<T, E>, options?: FutureOptions): FallibleFuture<T, E>; | ||
/** | ||
* A shortcut for creating a `FallibleFuture<T, E>` that is lazily executed. | ||
* | ||
* @param `execute` - A function that takes a `succeed` function that will be called | ||
* with the value of the future when it is resolved, and a `fail` function that will | ||
* be called with the error of the future if it fails. A cleanup function to call when | ||
* the future is cancelled can be returned. | ||
* | ||
* ## Example | ||
* ```ts | ||
* const future = Future.lazyFallible<number, string>((succeed, fail) => { | ||
* setTimeout(() => Math.random() > 0.5 ? succeed(1) : fail("BOO"), 1000); | ||
* return () => console.log("cancelled"); | ||
* }); | ||
* ``` | ||
*/ | ||
function lazyFallible<T, E = unknown>(execute: ExecuteFallibleFutureFn<T, E>): FallibleFuture<T, E>; | ||
/** | ||
* Utility function to wait for a number of milliseconds before resolving. | ||
*/ | ||
function wait(milliseconds: number): Future<void>; | ||
function all<T extends Array<Future<any> | FallibleFuture<any, any>>>(array: [...T]): Future<{ | ||
[K in keyof T]: T[K] extends Future<infer U> ? U : T[K] extends FallibleFuture<infer U, infer F> ? Result<U, F> : never; | ||
}>; | ||
function allFromDict<D extends { | ||
[K: PropertyKey]: FallibleFuture<any, any>; | ||
}>(dict: D): FallibleFuture<{ | ||
[K in keyof D]: orf.InferOkType<D[K]>; | ||
}, orf.InferErrorType<D[keyof D]>>; | ||
function allFromDict<D extends { | ||
[K: PropertyKey]: Future<any>; | ||
}>(dict: D): Future<{ | ||
[K in keyof D]: D[K] extends Future<infer U> ? U : never; | ||
}>; | ||
function allFromDict<D extends { | ||
[K: PropertyKey]: Future<any> | FallibleFuture<any, any>; | ||
}>(dict: D): FallibleFuture<{ | ||
[K in keyof D]: D[K] extends FallibleFuture<infer U, infer _> ? U : D[K] extends Future<infer U> ? U : never; | ||
}, orf.InferErrorType<D[keyof D]>>; | ||
/** | ||
* Creates a `Future<T>` that is already resolved with the provided value. | ||
*/ | ||
function value<T>(thing: T): Future<T>; | ||
/** | ||
* Creates a `FallibleFuture<T, never>` that is already resolved with the | ||
* provided value. | ||
*/ | ||
function success<T, E = never>(thing: T): FallibleFuture<T, E>; | ||
/** | ||
* Creates a `FallibleFuture<T, E>` that is already resolved with the | ||
* provided error. | ||
*/ | ||
function fail<T = never, E = never>(error: E): FallibleFuture<T, E>; | ||
/** | ||
* Typeguard to theck if `thing` is a `Future` | ||
* | ||
* ## Example | ||
* ```ts | ||
* const future = Future.value(1); | ||
* if (Future.isFuture(future)) { | ||
* // future is a Future | ||
* } | ||
* ``` | ||
*/ | ||
function isFuture<T = unknown>(thing: unknown): thing is Future<T>; | ||
/** | ||
* Typeguard to theck if `thing` is a `FallibleFuture` | ||
* | ||
* ## Example | ||
* ```ts | ||
* const future = Future.success(1); | ||
* if (Future.isFallibleFuture(future)) { | ||
* // future is a FallibleFuture | ||
* } | ||
* ``` | ||
*/ | ||
function isFallibleFuture<T = unknown, E = unknown>(thing: unknown): thing is FallibleFuture<T, E>; | ||
/** | ||
* Creates a new `FallibleFuture<T, E>` from the given "Fallible": | ||
* - `Result<T, E>` as `FallibleFuture<T, E>` | ||
* - `FallibleFuture<T, E>` as is | ||
* - `Promise<T>` as `FallibleFuture<T, unknown>` | ||
*/ | ||
function fromFallible<T, E = unknown>(fallible: Result<T, E> | FallibleFuture<T, E> | Promise<T>): FallibleFuture<T, E>; | ||
/** | ||
* Creates a new `Future<T>` with the value passed to `execute`s `resolve` function. | ||
* Will immediately start executing the `execute` function, unless `lazy` is set to | ||
* `true` in the options. | ||
* | ||
* @param `execute` - A function that takes a `resolve` function that will be called | ||
* with the value of the future when it is resolved. A cleanup function to call when | ||
* the future is cancelled can be returned. | ||
* | ||
* ## Example | ||
* ```ts | ||
* const future = Future.make<number>((resolve) => { | ||
* setTimeout(() => resolve(1), 1000); | ||
* return () => console.log("cancelled"); | ||
* }); | ||
* ``` | ||
*/ | ||
function make<T>(execute: ExecuteFutureFn<T>, options?: FutureOptions): Future<T>; | ||
/** | ||
* A shortcut for creating a `Future<T>` that is lazily executed. | ||
* | ||
* @param `execute` - A function that takes a `resolve` function that will be called | ||
* with the value of the future when it is resolved. A cleanup function to call when | ||
* the future is cancelled can be returned. | ||
* | ||
* ## Example | ||
* ```ts | ||
* const future = Future.lazy<number>((resolve) => { | ||
* setTimeout(() => resolve(1), 1000); | ||
* return () => console.log("cancelled"); | ||
* }); | ||
* ``` | ||
*/ | ||
function lazy<T>(execute: ExecuteFutureFn<T>): Future<T>; | ||
/** | ||
* Creates a new `FallibleFuture<T, E>` with the value passed to `execute`s `succeed` | ||
* function, or the error passed to `execute`s `fail` function. Will immediately start | ||
* executing the `execute` function, unless `lazy` is set to `true` in the options. | ||
* | ||
* @param `execute` - A function that takes a `succeed` function that will be called | ||
* with the value of the future when it is resolved, and a `fail` function that will | ||
* be called with the error of the future if it fails. A cleanup function to call when | ||
* the future is cancelled can be returned. | ||
* | ||
* ## Example | ||
* ```ts | ||
* const future = Future.makeFallible<number, string>((succeed, fail) => { | ||
* setTimeout(() => Math.random() > 0.5 ? succeed(1) : fail("BOO"), 1000); | ||
* return () => console.log("cancelled"); | ||
* }); | ||
* ``` | ||
*/ | ||
function makeFallible<T, E = unknown>(execute: ExecuteFallibleFutureFn<T, E>, options?: FutureOptions): FallibleFuture<T, E>; | ||
/** | ||
* A shortcut for creating a `FallibleFuture<T, E>` that is lazily executed. | ||
* | ||
* @param `execute` - A function that takes a `succeed` function that will be called | ||
* with the value of the future when it is resolved, and a `fail` function that will | ||
* be called with the error of the future if it fails. A cleanup function to call when | ||
* the future is cancelled can be returned. | ||
* | ||
* ## Example | ||
* ```ts | ||
* const future = Future.lazyFallible<number, string>((succeed, fail) => { | ||
* setTimeout(() => Math.random() > 0.5 ? succeed(1) : fail("BOO"), 1000); | ||
* return () => console.log("cancelled"); | ||
* }); | ||
* ``` | ||
*/ | ||
function lazyFallible<T, E = unknown>(execute: ExecuteFallibleFutureFn<T, E>): FallibleFuture<T, E>; | ||
/** | ||
* Utility function to wait for a number of milliseconds before resolving. | ||
*/ | ||
function wait(milliseconds: number): Future<void>; | ||
/** | ||
* Creates a new `Future` that resolves to a tuple of the passed future's resolved | ||
* values. Similiar to `Promise.all` | ||
* | ||
* ## Example | ||
* ```ts | ||
* const result = await Future.all([Future.value(1), Future.value("hi")]); | ||
* // result === Option.Some([1, "hi"]) | ||
*``` | ||
*/ | ||
function all<A extends Array<Future<any>>>(array: [...A]): Future<{ [K in keyof A]: A[K] extends Future<infer U> ? U : never }>; | ||
/** | ||
* Creates a new `FallibleFuture` that resolves to a tuple of the passed future's | ||
* resolved values. Similiar to `Promise.all` and `Result.all` | ||
* | ||
* If any of the `FallibleFuture`s resolve to an `Error`, the first `Error` found | ||
* is returned. Otherwise, an `Ok` is returned with a tuple of the resolved `Ok` | ||
* values | ||
* | ||
* ## Example | ||
* ```ts | ||
* const result = await Future.all([Future.success(1), Future.success("hi")]); | ||
* // result === Option.Some(Result.Ok([1, "hi"])) | ||
* | ||
* const result = await Future.all([ | ||
* Future.success(1), | ||
* Future.fail("error1"), | ||
* Future.fail("error2"), | ||
*]); | ||
* // result === Option.Some(Result.Error("error1")) | ||
*``` | ||
*/ | ||
function all<A extends Array<FallibleFuture<any, any>>>(array: [...A]): FallibleFuture<{ [K in keyof A]: orf.InferOkType<A[K]> }, orf.InferErrorType<A[number]>>; | ||
/** | ||
* Creates a new `FallibleFuture` that resolves to a tuple of the passed future's | ||
* resolved values. Similiar to `Promise.all` and `Result.all`. For any `Future` | ||
* passed in, it will convert it to a `FallibleFuture<T, never>` | ||
* | ||
* If any of the `FallibleFuture`s resolve to an `Error`, the first `Error` found | ||
* is returned. Otherwise, an `Ok` is returned with a tuple of the resolved `Ok` | ||
* values | ||
* | ||
* ## Example | ||
* ```ts | ||
* const result = await Future.all([Future.success(1), Future.success("hi")]); | ||
* // result === Option.Some(Result.Ok([1, "hi"])) | ||
* | ||
* const result = await Future.all([ | ||
* Future.success(1), | ||
* Future.fail("error1"), | ||
* Future.fail("error2"), | ||
*]); | ||
* // result === Option.Some(Result.Error("error1")) | ||
*``` | ||
*/ | ||
function all<A extends Array<Future<any> | FallibleFuture<any, any>>>(array: [...A]): FallibleFuture<{ [K in keyof A]: A[K] extends FallibleFuture<infer U, infer _> ? U : A[K] extends Future<infer U> ? U : never }, orf.InferErrorType<A[number]>>; | ||
function allFromDict<D extends { | ||
[K: PropertyKey]: FallibleFuture<any, any>; | ||
}>(dict: D): FallibleFuture<{ [K in keyof D]: orf.InferOkType<D[K]> }, orf.InferErrorType<D[keyof D]>>; | ||
function allFromDict<D extends { | ||
[K: PropertyKey]: Future<any>; | ||
}>(dict: D): Future<{ [K in keyof D]: D[K] extends Future<infer U> ? U : never }>; | ||
function allFromDict<D extends { | ||
[K: PropertyKey]: Future<any> | FallibleFuture<any, any>; | ||
}>(dict: D): FallibleFuture<{ [K in keyof D]: D[K] extends FallibleFuture<infer U, infer _> ? U : D[K] extends Future<infer U> ? U : never }, orf.InferErrorType<D[keyof D]>>; | ||
} | ||
@@ -1036,293 +1077,324 @@ type Future<T> = __Future<T>; | ||
type FutureOptions = { | ||
lazy?: boolean; | ||
lazy?: boolean; | ||
}; | ||
type ExecuteFutureFn<T> = (resolve: (t: T) => void) => (() => void) | void; | ||
type FutureState<T> = { | ||
tag: "pending"; | ||
execute: ExecuteFutureFn<T> | null; | ||
resolve_callbacks?: Array<(value: any) => void>; | ||
cancel?: () => void; | ||
cancel_callbacks?: Array<() => void>; | ||
tag: "pending"; | ||
execute: ExecuteFutureFn<T> | null; | ||
resolve_callbacks?: Array<(value: any) => void>; | ||
cancel?: () => void; | ||
cancel_callbacks?: Array<() => void>; | ||
} | { | ||
tag: "completed"; | ||
value: T; | ||
tag: "completed"; | ||
value: T; | ||
} | { | ||
tag: "cancelled"; | ||
tag: "cancelled"; | ||
}; | ||
declare class __Future<T> { | ||
#private; | ||
constructor(state: FutureState<T>, options?: FutureOptions); | ||
onResolved(cb: (t: T) => void): void; | ||
onCancelled(cb: () => void): void; | ||
/** | ||
* Cancels the future if it is still pending. | ||
*/ | ||
cancel(): void; | ||
/** | ||
* **Only to be used internally** | ||
* | ||
* Calls `onResolved` with `Some<T>` if the future resolved, or `None` if | ||
* it was cancelled. | ||
*/ | ||
private then; | ||
/** | ||
* Map this future’s output to a different type, returning a new future of | ||
* the resulting type. | ||
* | ||
* ## Example | ||
* ```ts | ||
* const result = await Future.value(1).map((val) => `${val * 2}`); | ||
* // result === Option.Some("2") | ||
* ``` | ||
*/ | ||
map<U>(map_fn: (t: T) => U): Future<U>; | ||
/** | ||
* Runs the provided function with the resolved value of the future, returning | ||
* the existing future. | ||
* | ||
* ## Example | ||
* ```ts | ||
* const future = await Future.value(1).tap((val) => console.log(val)); | ||
* // future === Option.Some(1) | ||
*/ | ||
tap(tap_fn: (t: T) => void): Future<T>; | ||
/** | ||
* Turns this `Future<T>` into a `FallibleFutuer<T, never>` | ||
* | ||
* ## Example | ||
* ```ts | ||
* const future = await Future.value(1).never_error(); | ||
* // future === Option.Some(Result.Ok(1)) | ||
* ``` | ||
*/ | ||
neverError(): FallibleFuture<T, never>; | ||
/** | ||
* Returns the resolved `T` from this future, or throws an exception if the | ||
* future was cancelled. | ||
* | ||
* **Prefer `unwrapOr` or `unwrapOrElse` over this method** | ||
* | ||
* ## Example | ||
* ```ts | ||
* const value = await Future.value(1).unwrap(); | ||
* // value === 1 | ||
* | ||
* const future = Future.value(1).unwrap(); | ||
* future.cancel(); | ||
* const value = await future; | ||
* // Throws an exception | ||
* ``` | ||
*/ | ||
unwrap(): UnwrappedFuture<T>; | ||
/** | ||
* Returns the resolved `T` from this future, or returns the provided `or_value` | ||
* if the future was cancelled. | ||
* | ||
* ## Example | ||
* ```ts | ||
* const value = await Future.value(1).unwrapOr(0); | ||
* // value === 1 | ||
* | ||
* const future = Future.value(1).unwrapOr(0); | ||
* future.cancel(); | ||
* const value = await future; | ||
* // value === 0 | ||
*/ | ||
unwrapOr<U = T>(or_value: U): UnwrappedFuture<T | U>; | ||
/** | ||
* Returns the resolved `T` from this future, or returns the result | ||
* of running `or_fn` if the future was cancelled. | ||
* | ||
* ## Example | ||
* ```ts | ||
* const value = await Future.value(1).unwrapOrElse(() => 0); | ||
* // value === 1 | ||
* | ||
* const future = Future.value(1).unwrapOrElse(() => 0); | ||
* future.cancel(); | ||
* const value = await future; | ||
* // value === 0 | ||
* ``` | ||
*/ | ||
unwrapOrElse<U = T>(or_fn: () => U): UnwrappedFuture<T | U>; | ||
#private; | ||
constructor(state: FutureState<T>, options?: FutureOptions); | ||
onResolved(cb: (t: T) => void): void; | ||
onCancelled(cb: () => void): void; | ||
/** | ||
* Cancels the future if it is still pending. | ||
*/ | ||
cancel(): void; | ||
/** | ||
* **Only to be used internally** | ||
* | ||
* Calls `onResolved` with `Some<T>` if the future resolved, or `None` if | ||
* it was cancelled. | ||
*/ | ||
private then(onResolved?: (value: Option<T>) => void): Future<T>; | ||
/** | ||
* Map this future’s output to a different type, returning a new future of | ||
* the resulting type. | ||
* | ||
* ## Example | ||
* ```ts | ||
* const value = await Future.value(1).map((val) => `${val * 2}`); | ||
* // value === Option.Some("2") | ||
* ``` | ||
*/ | ||
map<U>(map_fn: (t: T) => U): Future<U>; | ||
/** | ||
* Runs the provided function with the resolved value of the future, returning | ||
* the existing future. | ||
* | ||
* ## Example | ||
* ```ts | ||
* const value = await Future.value(1).tap((val) => console.log(val)); | ||
* // value === Option.Some(1) | ||
* ``` | ||
*/ | ||
tap(tap_fn: (t: T) => void): Future<T>; | ||
/** | ||
* Turns this `Future<T>` into a `FallibleFutuer<T, never>` | ||
* | ||
* ## Example | ||
* ```ts | ||
* const value = await Future.value(1).never_error(); | ||
* // value === Option.Some(Result.Ok(1)) | ||
* ``` | ||
*/ | ||
neverError(): FallibleFuture<T, never>; | ||
/** | ||
* Returns the resolved `T` from this future, or throws an exception if the | ||
* future was cancelled. | ||
* | ||
* **Prefer `unwrapOr` or `unwrapOrElse` over this method** | ||
* | ||
* ## Example | ||
* ```ts | ||
* const value = await Future.value(1).unwrap(); | ||
* // value === 1 | ||
* | ||
* const future = Future.value(1).unwrap(); | ||
* future.cancel(); | ||
* const value = await future; | ||
* // Throws an exception | ||
* ``` | ||
*/ | ||
unwrap(): UnwrappedFuture<T>; | ||
/** | ||
* Returns the resolved `T` from this future, or returns the provided `or_value` | ||
* if the future was cancelled. | ||
* | ||
* ## Example | ||
* ```ts | ||
* const value = await Future.value(1).unwrapOr(0); | ||
* // value === 1 | ||
* | ||
* const future = Future.value(1).unwrapOr(0); | ||
* future.cancel(); | ||
* const value = await future; | ||
* // value === 0 | ||
* ``` | ||
*/ | ||
unwrapOr<U = T>(or_value: U): UnwrappedFuture<T | U>; | ||
/** | ||
* Returns the resolved `T` from this future, or returns the result | ||
* of running `or_fn` if the future was cancelled. | ||
* | ||
* ## Example | ||
* ```ts | ||
* const value = await Future.value(1).unwrapOrElse(() => 0); | ||
* // value === 1 | ||
* | ||
* const future = Future.value(1).unwrapOrElse(() => 0); | ||
* future.cancel(); | ||
* const value = await future; | ||
* // value === 0 | ||
* ``` | ||
*/ | ||
unwrapOrElse<U = T>(or_fn: () => U): UnwrappedFuture<T | U>; | ||
} | ||
type ExecuteFallibleFutureFn<T, E> = (succeed: (t: T) => void, fail: (e: E) => void) => (() => void) | void; | ||
type FallibleFutureState<T, E> = { | ||
tag: "pending"; | ||
execute: ExecuteFallibleFutureFn<T, E> | null; | ||
resolve_callbacks?: Array<(t: any) => void>; | ||
cancel?: () => void; | ||
cancel_callbacks?: Array<() => void>; | ||
tag: "pending"; | ||
execute: ExecuteFallibleFutureFn<T, E> | null; | ||
resolve_callbacks?: Array<(t: any) => void>; | ||
cancel?: () => void; | ||
cancel_callbacks?: Array<() => void>; | ||
} | { | ||
tag: "completed"; | ||
value: Result<T, E>; | ||
tag: "completed"; | ||
value: Result<T, E>; | ||
} | { | ||
tag: "cancelled"; | ||
tag: "cancelled"; | ||
}; | ||
declare class __FallibleFuture<T, E> { | ||
#private; | ||
constructor(state: FallibleFutureState<T, E>, options?: FutureOptions); | ||
onResolved(cb: (result: Result<T, E>) => void): void; | ||
onSucceeded(cb: (value: T) => void): void; | ||
onFailed(cb: (error: E) => void): void; | ||
onCancelled(cb: () => void): void; | ||
cancel(): void; | ||
/** | ||
* **Only to be used internally** | ||
* | ||
* Calls `onResolved` with `Some<Result<T, E>>` if the future resolved, or `None` if | ||
* it was cancelled. | ||
*/ | ||
private then; | ||
/** | ||
* Map this future’s success value `T` to a different type: | ||
* `FallibleFuture<T, E>` to `FallibleFuture<U, E>` | ||
* | ||
* ## Example | ||
* ```ts | ||
* const result = await Future.success(1).map((val) => `${val * 2}`); | ||
* // result === Option.Some(Result.Ok("2")) | ||
* ``` | ||
*/ | ||
map<U>(map_fn: (t: T) => U): FallibleFuture<U, E>; | ||
/** | ||
* Map this future’s error value `E` to a different type: | ||
* `FallibleFuture<T, E>` to `FallibleFuture<T, F>` | ||
* | ||
* ## Example | ||
* ```ts | ||
* const result = await Future.fail(1).map((val) => `${val * 2}`); | ||
* // result === Option.Some(Result.Error("2")) | ||
* ``` | ||
*/ | ||
mapError<F>(map_fn: (e: E) => F): FallibleFuture<T, F>; | ||
/** | ||
* Executes another FallibleFuture after this one resolves successfully. | ||
* The success value `T` is passed to `then_fn` to create this subsequent | ||
* FallibleFuture. | ||
* | ||
* ## Example | ||
* ```ts | ||
* const future = await Future.success(1).andThen((val) => Future.success(`${val * 2}`)); | ||
* // future === Option.Some(Result.Ok("2")) | ||
* | ||
* const future = await Future.fail("ERROR").andThen((val) => Future.success(`${val * 2}`)); | ||
* // future === Option.Some(Result.Error("ERROR")) | ||
* ``` | ||
*/ | ||
andThen<F extends Result<any, any> | FallibleFuture<any, any>>(then_fn: (t: T) => F): FallibleFuture<orf.InferOkType<F>, orf.InferErrorType<F> | E>; | ||
orElse<R extends Result<any, any> | FallibleFuture<any, any>>(or_fn: (e: E) => R): FallibleFuture<orf.InferOkType<R> | T, orf.InferErrorType<R>>; | ||
tap(tap_fn: (t: T) => void): FallibleFuture<T, E>; | ||
tapError(tap_fn: (e: E) => void): FallibleFuture<T, E>; | ||
ok(): Future<Option<T>>; | ||
/** | ||
* Returns the resolved `T` from this future, or throws an exception if the | ||
* future was cancelled or failed. | ||
* | ||
* **Prefer `unwrapOr` or `unwrapOrElse` over this method** | ||
* | ||
* ## Example | ||
* ```ts | ||
* const value = await Future.success(1).unwrap(); | ||
* // value === 1 | ||
* | ||
* const future = Future.success(1).unwrap(); | ||
* future.cancel(); | ||
* const value = await future; | ||
* // Throws an exception | ||
* | ||
* const future = await Future.fail("ERROR").unwrap(); | ||
* // Throws an exception | ||
* ``` | ||
*/ | ||
unwrap(): UnwrappedFuture<T>; | ||
/** | ||
* Returns the resolved `E` from this future, or throws an exception if the | ||
* future was cancelled or succeeded. | ||
* | ||
* ## Example | ||
* ```ts | ||
* const value = await Future.fail("ERROR").unwrapError(); | ||
* // value === "ERROR" | ||
* | ||
* const future = Future.fail("ERROR").unwrapError(); | ||
* future.cancel(); | ||
* const value = await future; | ||
* // Throws an exception | ||
* | ||
* const future = await Future.success(1).unwrapError(); | ||
* // Throws an exception | ||
* ``` | ||
*/ | ||
unwrapError(): UnwrappedFuture<E>; | ||
/** | ||
* Returns the resolved `T` from this future, or returns the provided `or_value` | ||
* if the future was cancelled, or failed. | ||
* | ||
* ## Example | ||
* ```ts | ||
* const value = await Future.success(1).unwrapOr(0); | ||
* // value === 1 | ||
* | ||
* const future = Future.success(1).unwrapOr(0); | ||
* future.cancel(); | ||
* const value = await future; | ||
* // Throws an exception | ||
* | ||
* const future = await Future.fail("ERROR").unwrapOr(0); | ||
* // value === 0 | ||
* ``` | ||
*/ | ||
unwrapOr<U = T>(or_value: U): UnwrappedFuture<T | U>; | ||
/** | ||
* Returns the resolved `T` from this future, or returns the result | ||
* of running `or_fn` if the future was cancelled or failed. | ||
* | ||
* ## Example | ||
* ```ts | ||
* const value = await Future.success(1).unwrapOrElse(() => 0); | ||
* // value === 1 | ||
* | ||
* const future = Future.success(1).unwrapOrElse(() => 0); | ||
* future.cancel(); | ||
* const value = await future; | ||
* // Throws an exception | ||
* | ||
* const future = await Future.fail("ERROR").unwrapOrElse(() => 0); | ||
* // value === 0 | ||
* ``` | ||
*/ | ||
unwrapOrElse<U = T>(or_fn: () => U): UnwrappedFuture<T | U>; | ||
match<U, V = U>(config: { | ||
Ok: (t: T) => U; | ||
Error: (e: E) => V; | ||
}): UnwrappedFuture<U | V>; | ||
#private; | ||
constructor(state: FallibleFutureState<T, E>, options?: FutureOptions); | ||
onResolved(cb: (result: Result<T, E>) => void): void; | ||
onSucceeded(cb: (value: T) => void): void; | ||
onFailed(cb: (error: E) => void): void; | ||
onCancelled(cb: () => void): void; | ||
cancel(): void; | ||
/** | ||
* **Only to be used internally** | ||
* | ||
* Calls `onResolved` with `Some<Result<T, E>>` if the future resolved, or `None` if | ||
* it was cancelled. | ||
*/ | ||
private then(onResolved?: (value: Option<Result<T, E>>) => void): FallibleFuture<T, E>; | ||
/** | ||
* Map this future’s success value `T` to a different type: | ||
* `FallibleFuture<T, E>` to `FallibleFuture<U, E>` | ||
* | ||
* ## Example | ||
* ```ts | ||
* const value = await Future.success(1).map((val) => `${val * 2}`); | ||
* // value === Option.Some(Result.Ok("2")) | ||
* ``` | ||
*/ | ||
map<U>(map_fn: (t: T) => U): FallibleFuture<U, E>; | ||
/** | ||
* Map this future’s error value `E` to a different type: | ||
* `FallibleFuture<T, E>` to `FallibleFuture<T, F>` | ||
* | ||
* ## Example | ||
* ```ts | ||
* const value = await Future.fail(1).map((val) => `${val * 2}`); | ||
* // value === Option.Some(Result.Error("2")) | ||
* ``` | ||
*/ | ||
mapError<F>(map_fn: (e: E) => F): FallibleFuture<T, F>; | ||
/** | ||
* Executes another FallibleFuture after this one resolves successfully. | ||
* The success value `T` is passed to `then_fn` to create this subsequent | ||
* FallibleFuture. | ||
* | ||
* ## Example | ||
* ```ts | ||
* const value = await Future.success(1).andThen((val) => Future.success(`${val * 2}`)); | ||
* // value === Option.Some(Result.Ok("2")) | ||
* | ||
* const value = await Future.fail("ERROR").andThen((val) => Future.success(`${val * 2}`)); | ||
* // value === Option.Some(Result.Error("ERROR")) | ||
* ``` | ||
*/ | ||
andThen<F extends Result<any, any> | FallibleFuture<any, any>>(then_fn: (t: T) => F): FallibleFuture<orf.InferOkType<F>, orf.InferErrorType<F> | E>; | ||
/** | ||
* Executes another FallibleFuture after this one resolves with an error. | ||
* The error value `E` is passed to `or_fn` to create this subsequent | ||
* FallibleFuture. | ||
* | ||
* ## Example | ||
* ```ts | ||
* const value = await Future.fail("ERROR").orElse((error) => Future.success(`${error}!`)); | ||
* // value === Option.Some(Result.Ok("ERROR!")) | ||
* | ||
* const value = await Future.success(1).orElse((error) => Future.success(`${error}!`)); | ||
* // value === Option.Some(Result.Ok(1)) | ||
* ``` | ||
*/ | ||
orElse<R extends Result<any, any> | FallibleFuture<any, any>>(or_fn: (e: E) => R): FallibleFuture<orf.InferOkType<R> | T, orf.InferErrorType<R>>; | ||
/** | ||
* Runs the provided function with the resolved `T` of the future, returning | ||
* the existing future. | ||
* | ||
* ## Example | ||
* ```ts | ||
* const future = Future.success(1); | ||
* const tapped_future = future.tap((val) => console.log(val)); | ||
* // Logs "1" | ||
* // future === tapped_future | ||
* | ||
* const future = Future.fail(1); | ||
* const tapped_future = future.tap((val) => console.log(val)); | ||
* // Logs nothing | ||
* // future === tapped_future | ||
* ``` | ||
*/ | ||
tap(tap_fn: (t: T) => void): FallibleFuture<T, E>; | ||
/** | ||
* Runs the provided function with the resolved `E` of the future, returning | ||
* the existing future. | ||
* | ||
* ## Example | ||
* ```ts | ||
* const future = Future.success(1); | ||
* const tapped_future = future.tap((val) => console.log(val)); | ||
* // Logs nothing | ||
* // future === tapped_future | ||
* | ||
* const future = Future.fail(1); | ||
* const tapped_future = future.tap((val) => console.log(val)); | ||
* // Logs "1" | ||
* // future === tapped_future | ||
* ``` | ||
*/ | ||
tapError(tap_fn: (e: E) => void): FallibleFuture<T, E>; | ||
ok(): Future<Option<T>>; | ||
/** | ||
* Returns the resolved `Result<T, E>` from this future, or throws an exception if the | ||
* future was cancelled. | ||
* | ||
* **Prefer `unwrapOr` or `unwrapOrElse` over this method** | ||
* | ||
* ## Example | ||
* ```ts | ||
* const value = await Future.success(1).unwrap(); | ||
* // value === Result.Ok(1) | ||
* | ||
* const value = await Future.fail("ERROR").unwrap(); | ||
* // value === Result.Error("ERROR") | ||
* | ||
* const value = Future.success(1).unwrap(); | ||
* future.cancel(); | ||
* const value = await future; | ||
* // Throws an exception | ||
* ``` | ||
*/ | ||
unwrap(): UnwrappedFuture<Result<T, E>>; | ||
/** | ||
* Returns the resolved `Result<T, E>` from this future, or returns the provided `or_value` | ||
* if the future was cancelled. | ||
* | ||
* ## Example | ||
* ```ts | ||
* const value = await Future.success(1).unwrapOr(0); | ||
* // value === Result.Ok(1) | ||
* | ||
* const value = await Future.fail("ERROR").unwrapOr(0); | ||
* // value === Result.Error("ERROR") | ||
* | ||
* const value = Future.success(1).unwrapOr(0); | ||
* future.cancel(); | ||
* const value = await future; | ||
* // Throws an exception | ||
* ``` | ||
*/ | ||
unwrapOr<U = T>(or_value: Result<T | U, E>): UnwrappedFuture<Result<T | U, E>>; | ||
/** | ||
* Returns the resolved `Result<T, E>` from this future, or returns the result | ||
* of running `or_fn` if the future was cancelled. | ||
* | ||
* ## Example | ||
* ```ts | ||
* const value = await Future.success(1).unwrapOrElse(() => 0); | ||
* // value === Result.Ok(1) | ||
* | ||
* const value = await Future.fail("ERROR").unwrapOrElse(() => 0); | ||
* // value === Result.Error("ERROR") | ||
* | ||
* const future = Future.success(1).unwrapOrElse(() => 0); | ||
* future.cancel(); | ||
* const value = await future; | ||
* // Throws an exception | ||
* ``` | ||
*/ | ||
unwrapOrElse<U = T>(or_fn: () => Result<T | U, E>): UnwrappedFuture<Result<T | U, E>>; | ||
match<U, V = U>(config: { | ||
Ok: (t: T) => U; | ||
Error: (e: E) => V; | ||
}): UnwrappedFuture<U | V>; | ||
} | ||
type ExecuteUnwrappedFutureFn<T> = (resolve: (t: T) => void) => (() => void) | void; | ||
type UnwrappedFutureState<T> = { | ||
tag: "pending"; | ||
execute: ExecuteUnwrappedFutureFn<T> | null; | ||
resolve_callbacks?: Array<(value: any) => void>; | ||
tag: "pending"; | ||
execute: ExecuteUnwrappedFutureFn<T> | null; | ||
resolve_callbacks?: Array<(value: any) => void>; | ||
} | { | ||
tag: "completed"; | ||
value: T; | ||
tag: "completed"; | ||
value: T; | ||
} | { | ||
tag: "cancelled"; | ||
tag: "cancelled"; | ||
}; | ||
declare class __UnwrappedFuture<T> { | ||
#private; | ||
constructor(state: UnwrappedFutureState<T>); | ||
onResolved(cb: (t: T) => void): void; | ||
onCancelled(cb: (error: any) => void): void; | ||
/** | ||
* Cancels the future if it is still pending. | ||
*/ | ||
cancel(): void; | ||
/** | ||
* **Only to be used internally** | ||
* | ||
* Calls `onResolved` with `Some<T>` if the future resolved, or `None` if | ||
* it was cancelled. | ||
*/ | ||
private then; | ||
#private; | ||
constructor(state: UnwrappedFutureState<T>); | ||
onResolved(cb: (t: T) => void): void; | ||
onCancelled(cb: (error: any) => void): void; | ||
/** | ||
* Cancels the future if it is still pending. | ||
*/ | ||
cancel(): void; | ||
/** | ||
* **Only to be used internally** | ||
* | ||
* Calls `onResolved` with `Some<T>` if the future resolved, or `None` if | ||
* it was cancelled. | ||
*/ | ||
private then(onResolved?: (value: T) => void, onCancelled?: (error: any) => void): UnwrappedFuture<T>; | ||
} | ||
@@ -1334,20 +1406,19 @@ | ||
declare namespace orf { | ||
/** | ||
* Infers the inner type of a Future, FallibleFuture, UnwrappedFuture, or Option | ||
*/ | ||
type InferInnerType<T> = T extends Future<infer U> ? U : T extends FallibleFuture<infer U, infer F> ? Result<U, F> : T extends UnwrappedFuture<infer U> ? U : T extends Option<infer U> ? U : never; | ||
/** | ||
* Infers the `Ok` type of a "fallible" | ||
* - FallibleFuture | ||
* - Result | ||
*/ | ||
type InferOkType<T> = T extends FallibleFuture<infer U, infer _> ? U : T extends Result<infer U, infer _> ? U : never; | ||
/** | ||
* Infers the `Error` type of a "fallible" | ||
* - FallibleFuture | ||
* - Result | ||
*/ | ||
type InferErrorType<T> = T extends FallibleFuture<infer _, infer F> ? F : T extends Result<infer _, infer F> ? F : never; | ||
/** | ||
* Infers the inner type of a Future, FallibleFuture, UnwrappedFuture, or Option | ||
*/ | ||
type InferInnerType<T> = T extends Future<infer U> ? U : T extends FallibleFuture<infer U, infer F> ? Result<U, F> : T extends UnwrappedFuture<infer U> ? U : T extends Option<infer U> ? U : never; | ||
/** | ||
* Infers the `Ok` type of a "fallible" | ||
* - FallibleFuture | ||
* - Result | ||
*/ | ||
type InferOkType<T> = T extends FallibleFuture<infer U, infer _> ? U : T extends Result<infer U, infer _> ? U : never; | ||
/** | ||
* Infers the `Error` type of a "fallible" | ||
* - FallibleFuture | ||
* - Result | ||
*/ | ||
type InferErrorType<T> = T extends FallibleFuture<infer _, infer F> ? F : T extends Result<infer _, infer F> ? F : never; | ||
} | ||
export { FallibleFuture, Future, JsonOption, JsonResult, Option, Result, orf }; | ||
export { FallibleFuture, Future, JsonOption, JsonResult, Option, Result, orf }; |
@@ -1,1 +0,1 @@ | ||
"use strict";var W=Object.defineProperty;var re=Object.getOwnPropertyDescriptor;var ne=Object.getOwnPropertyNames;var oe=Object.prototype.hasOwnProperty;var ue=(o,e)=>{for(var t in e)W(o,t,{get:e[t],enumerable:!0})},ae=(o,e,t,n)=>{if(e&&typeof e=="object"||typeof e=="function")for(let a of ne(e))!oe.call(o,a)&&a!==t&&W(o,a,{get:()=>e[a],enumerable:!(n=re(e,a))||n.enumerable});return o};var ie=o=>ae(W({},"__esModule",{value:!0}),o);var X=(o,e,t)=>{if(!e.has(o))throw TypeError("Cannot "+t)};var r=(o,e,t)=>(X(o,e,"read from private field"),t?t.call(o):e.get(o)),x=(o,e,t)=>{if(e.has(o))throw TypeError("Cannot add the same private member more than once");e instanceof WeakSet?e.add(o):e.set(o,t)},E=(o,e,t,n)=>(X(o,e,"write to private field"),n?n.call(o,t):e.set(o,t),t);var K=(o,e,t)=>(X(o,e,"access private method"),t);var Z=(o,e,t)=>new Promise((n,a)=>{var O=_=>{try{y(t.next(_))}catch(i){a(i)}},s=_=>{try{y(t.throw(_))}catch(i){a(i)}},y=_=>_.done?n(_.value):Promise.resolve(_.value).then(O,s);y((t=t.apply(o,e)).next())});var se={};ue(se,{Future:()=>F,Option:()=>h,Result:()=>f});module.exports=ie(se);var Y=Error,f;(_=>{function o(i){return Object.freeze(new z(i))}_.Ok=o;function e(i){return Object.freeze(new A(i))}_.Error=e;function t(i){return i instanceof z||i instanceof A}_.isResult=t;function n(i,d){var U;try{return o(i())}catch(m){return e((U=d==null?void 0:d(m))!=null?U:m)}}_.fromExecution=n;function a(i,d){return Z(this,null,function*(){var U;try{return o(yield i)}catch(m){return e((U=d==null?void 0:d(m))!=null?U:m)}})}_.fromAwaitable=a;function O(i){let d=[];for(let U of i){if(U.isError())return U;d.push(U.unwrap())}return o(d)}_.all=O;function s(i){let d={};for(let U in i){let m=i[U];if(m.isError())return m;d[U]=m.unwrap()}return o(d)}_.allFromDict=s;function y(i){if(i.__orf_type__!=="Result"&&!("tag"in i))throw new Y("Invalid Result JSON");if(i.tag==="Ok"&&"value"in i)return o(i.value);if(i.tag==="Error"&&"error"in i)return e(i.error);throw new Y("Invalid Result JSON")}_.fromJSON=y})(f||(f={}));var z=class{constructor(e){this.value=e}isOk(){return!0}isError(){return!this.isOk()}match(e){return e.Ok(this.value)}map(e){return f.Ok(e(this.value))}mapOr(e,t){return t(this.value)}mapOrElse(e,t){return t(this.value)}mapError(e){return this}and(e){return e}andThen(e){return e(this.value)}or(e){return this}orElse(e){return this}tap(e){return e(Object.freeze(structuredClone(this.value))),this}tapError(e){return this}ok(){return h.Some(this.value)}unwrap(){return this.value}unwrapError(){throw new Y("Cannot unwrapError an Ok")}unwrapOr(e){return this.value}unwrapOrElse(e){return this.value}toJSON(){return{__orf_type__:"Result",tag:"Ok",value:this.value}}},A=class{constructor(e){this.error=e}isOk(){return!1}isError(){return!this.isOk()}match(e){return e.Error(this.error)}map(e){return this}mapOr(e,t){return e}mapOrElse(e,t){return e()}mapError(e){return f.Error(e(this.error))}and(e){return this}andThen(e){return this}or(e){return e}orElse(e){return e(this.error)}tap(e){return this}tapError(e){return e(Object.freeze(structuredClone(this.error))),this}ok(){return h.None()}unwrap(){throw this.error}unwrapError(){return this.error}unwrapOr(e){return e}unwrapOrElse(e){return e(this.error)}toJSON(){return{__orf_type__:"Result",tag:"Error",error:this.error}}};var h;(O=>{function o(s){return Object.freeze(new P(s))}O.Some=o;function e(){return le}O.None=e;function t(s){return s instanceof P||s instanceof q}O.isOption=t;function n(s){return s?o(s):e()}O.from=n;function a(s){if(s.__orf_type__!=="Option"&&!("tag"in s))throw new Error("Invalid Option JSON");if(s.tag==="Some"&&"value"in s)return o(s.value);if(s.tag==="None")return e();throw new Error("Invalid Option JSON")}O.fromJSON=a})(h||(h={}));var P=class{constructor(e){this.value=e}isSome(){return!0}isNone(){return!this.isSome()}match(e){return e.Some(this.value)}map(e){return h.Some(e(this.value))}mapOr(e,t){return t(this.value)}mapOrElse(e,t){return t(this.value)}and(e){return e}andThen(e){return e(this.value)}or(e){return this}orElse(e){return this}tap(e){return e(Object.freeze(structuredClone(this.value))),this}unwrap(){return this.value}unwrapOr(e){return this.value}unwrapOrElse(e){return this.value}okOr(e){return f.Ok(this.value)}okOrElse(e){return f.Ok(this.value)}toJSON(){return{__orf_type__:"Option",tag:"Some",value:this.value}}},q=class{isSome(){return!1}isNone(){return!this.isSome()}match(e){return e.None()}map(e){return this}mapOr(e,t){return e}mapOrElse(e,t){return e()}and(e){return this}andThen(e){return this}or(e){return e}orElse(e){return e()}tap(e){return this}unwrap(){throw new Error("Cannot unwrap None")}unwrapOr(e){return e}unwrapOrElse(e){return e()}okOr(e){return f.Error(e)}okOrElse(e){return f.Error(e())}toJSON(){return{__orf_type__:"Option",tag:"None"}}},le=Object.freeze(new q);var F;(N=>{function o(u){return new S({tag:"completed",value:u})}N.value=o;function e(u){return new b({tag:"completed",value:f.Ok(u)})}N.success=e;function t(u){return new b({tag:"completed",value:f.Error(u)})}N.fail=t;function n(u){return u instanceof S}N.isFuture=n;function a(u){return u instanceof b}N.isFallibleFuture=a;function O(u){return u instanceof b?u:u instanceof Promise?N.makeFallible((T,R)=>{u.then(T).catch(R)}):u.match({Ok:T=>e(T),Error:T=>t(T)})}N.fromFallible=O;function s(u,T){return new S({tag:"pending",execute:u},T)}N.make=s;function y(u){return new S({tag:"pending",execute:u},{lazy:!0})}N.lazy=y;function _(u,T){return new b({tag:"pending",execute:u},T)}N.makeFallible=_;function i(u){return new b({tag:"pending",execute:u},{lazy:!0})}N.lazyFallible=i;function d(u){return new S({tag:"pending",execute:T=>{let R=setTimeout(T,u);return()=>{clearTimeout(R)}}})}N.wait=d;function U(u){let T=N.make(R=>{let M=new Array(u.length),C=0;return u.forEach((v,V)=>{v.onResolved(I=>{M[V]=I,C+=1,C===u.length&&R(M)})}),()=>u.forEach(v=>v.cancel())});return u.forEach(R=>R.onCancelled(T.cancel.bind(T))),T}N.all=U;function m(u){let T=Object.values(u),R=T.length;if(!T.some(N.isFallibleFuture)){let v=N.make(V=>{let I={},D=0;for(let g in u)u[g].onResolved(Q=>{I[g]=Q,D+=1,D===R&&V(I)});return()=>{for(let g of T)g.cancel()}});for(let V of T)V.onCancelled(v.cancel.bind(v));return v}let C=N.makeFallible((v,V)=>{let I={},D=0;for(let g in u){let J=u[g];N.isFuture(J)&&(J=J.neverError()),J.onResolved(Q=>{I[g]=Q,D+=1,D===R&&f.allFromDict(I).match({Ok:v,Error:V})})}return()=>{for(let g of T)g.cancel()}});for(let v of T)v.onCancelled(C.cancel.bind(C));return C}N.allFromDict=m})(F||(F={}));var c,B,$,S=class{constructor(e,t){x(this,B);x(this,c,void 0);E(this,c,e),t!=null&&t.lazy||this.then()}onResolved(e){var t;r(this,c).tag==="pending"?(r(this,c).resolve_callbacks=(t=r(this,c).resolve_callbacks)!=null?t:[],r(this,c).resolve_callbacks.push(e)):r(this,c).tag==="completed"&&e(r(this,c).value)}onCancelled(e){var t;r(this,c).tag==="pending"?(r(this,c).cancel_callbacks=(t=r(this,c).cancel_callbacks)!=null?t:[],r(this,c).cancel_callbacks.push(e)):r(this,c).tag==="cancelled"&&e()}cancel(){if(r(this,c).tag==="pending"){let{cancel:e,cancel_callbacks:t}=r(this,c);E(this,c,{tag:"cancelled"}),e==null||e(),t==null||t.forEach(n=>n())}}then(e){if(r(this,c).tag==="pending"&&r(this,c).execute){let t=r(this,c).execute(K(this,B,$).bind(this));r(this,c).execute=null,t&&(r(this,c).cancel=t)}return e&&(this.onResolved(t=>e(h.Some(t))),this.onCancelled(()=>e(h.None()))),this}map(e){let t=F.make(n=>(this.onResolved(a=>{n(e(a))}),this.cancel.bind(this)));return this.onCancelled(t.cancel.bind(t)),t}tap(e){return this.onResolved(e),this}neverError(){let e=F.makeFallible((t,n)=>(this.onResolved(t),this.cancel.bind(this)));return this.onCancelled(e.cancel.bind(e)),e}unwrap(){let e=new w({tag:"pending",execute:t=>{this.onResolved(t)}});return this.onCancelled(e.cancel.bind(e)),e}unwrapOr(e){return new w({tag:"pending",execute:n=>(this.onResolved(a=>{n(a)}),this.onCancelled(()=>{n(e)}),()=>{n(e)})})}unwrapOrElse(e){return new w({tag:"pending",execute:n=>(this.onResolved(a=>{n(a)}),this.onCancelled(()=>{n(e())}),()=>{n(e())})})}};c=new WeakMap,B=new WeakSet,$=function(e){if(r(this,c).tag==="pending"){let{resolve_callbacks:t}=r(this,c);E(this,c,{tag:"completed",value:e}),t==null||t.forEach(n=>n(e))}};var l,G,j,H,ee,b=class{constructor(e,t){x(this,G);x(this,H);x(this,l,void 0);E(this,l,e),t!=null&&t.lazy||this.then()}onResolved(e){var t;r(this,l).tag==="pending"?(r(this,l).resolve_callbacks=(t=r(this,l).resolve_callbacks)!=null?t:[],r(this,l).resolve_callbacks.push(e)):r(this,l).tag==="completed"&&e(r(this,l).value)}onSucceeded(e){this.onResolved(t=>{t.match({Ok:e,Error:()=>{}})})}onFailed(e){this.onResolved(t=>{t.match({Ok:()=>{},Error:e})})}onCancelled(e){var t;r(this,l).tag==="pending"?(r(this,l).cancel_callbacks=(t=r(this,l).cancel_callbacks)!=null?t:[],r(this,l).cancel_callbacks.push(e)):r(this,l).tag==="cancelled"&&e()}cancel(){if(r(this,l).tag==="pending"){let{cancel:e,cancel_callbacks:t}=r(this,l);E(this,l,{tag:"cancelled"}),e==null||e(),t==null||t.forEach(n=>n())}}then(e){if(r(this,l).tag==="pending"&&r(this,l).execute){let t=r(this,l).execute(K(this,G,j).bind(this),K(this,H,ee).bind(this));r(this,l).execute=null,t&&(r(this,l).cancel=t)}return e&&(this.onResolved(t=>e(h.Some(t))),this.onCancelled(()=>e(h.None()))),this}map(e){let t=F.makeFallible((n,a)=>(this.onResolved(O=>{O.match({Ok:s=>{n(e(s))},Error:a})}),this.cancel.bind(this)));return this.onCancelled(t.cancel.bind(t)),t}mapError(e){let t=F.makeFallible((n,a)=>(this.onResolved(O=>{O.match({Ok:n,Error:s=>{a(e(s))}})}),this.cancel.bind(this)));return this.onCancelled(t.cancel.bind(t)),t}andThen(e){let t=F.makeFallible((n,a)=>(this.onResolved(O=>{O.match({Ok:s=>{let y=F.fromFallible(e(s));y.onSucceeded(n),y.onFailed(a)},Error:a})}),this.cancel.bind(this)));return this.onCancelled(t.cancel.bind(t)),t}orElse(e){let t=F.makeFallible((n,a)=>(this.onResolved(O=>{O.match({Ok:n,Error:s=>{let y=F.fromFallible(e(s));y.onSucceeded(n),y.onFailed(a)}})}),this.cancel.bind(this)));return this.onCancelled(t.cancel.bind(t)),t}tap(e){return this.onSucceeded(e),this}tapError(e){return this.onFailed(e),this}ok(){let e=F.make(t=>(this.onSucceeded(n=>t(h.Some(n))),this.onFailed(()=>t(h.None())),this.cancel.bind(this)));return this.onCancelled(e.cancel.bind(e)),e}unwrap(){let e=new w({tag:"pending",execute:t=>{this.onResolved(n=>t(n.unwrap()))}});return this.onCancelled(e.cancel.bind(e)),e}unwrapError(){let e=new w({tag:"pending",execute:t=>{this.onResolved(n=>t(n.unwrapError()))}});return this.onCancelled(e.cancel.bind(e)),e}unwrapOr(e){return new w({tag:"pending",execute:n=>(this.onResolved(a=>{n(a.unwrapOr(e))}),this.onCancelled(()=>{n(e)}),()=>{n(e)})})}unwrapOrElse(e){return new w({tag:"pending",execute:n=>(this.onResolved(a=>{n(a.unwrapOrElse(e))}),this.onCancelled(()=>{n(e())}),()=>{n(e())})})}match(e){let t=new w({tag:"pending",execute:n=>{this.onResolved(a=>{n(a.match(e))})}});return this.onCancelled(t.cancel.bind(t)),t}};l=new WeakMap,G=new WeakSet,j=function(e){if(r(this,l).tag==="pending"){let{resolve_callbacks:t}=r(this,l),n=f.Ok(e);E(this,l,{tag:"completed",value:n}),t==null||t.forEach(a=>a(n))}},H=new WeakSet,ee=function(e){if(r(this,l).tag==="pending"){let{resolve_callbacks:t}=r(this,l),n=f.Error(e);E(this,l,{tag:"completed",value:n}),t==null||t.forEach(a=>a(n))}};var p,k,L,te,w=class{constructor(e){x(this,L);x(this,p,void 0);x(this,k,void 0);if(E(this,p,e),r(this,p).tag==="pending"&&r(this,p).execute){let t=r(this,p).execute(K(this,L,te).bind(this));r(this,p).execute=null,t&&!r(this,k)&&E(this,k,t)}}onResolved(e){var t;r(this,p).tag==="pending"?(r(this,p).resolve_callbacks=(t=r(this,p).resolve_callbacks)!=null?t:[],r(this,p).resolve_callbacks.push(e)):r(this,p).tag==="completed"&&e(r(this,p).value)}onCancelled(e){r(this,p).tag==="pending"&&!r(this,k)?E(this,k,e):r(this,p).tag==="cancelled"&&!r(this,k)&&e(new Error("Cannot cancel UnwrappedFuture"))}cancel(){r(this,p).tag==="pending"&&(r(this,k)?(r(this,k).call(this,new Error("Cannot cancel UnwrappedFuture")),r(this,p).tag==="pending"&&E(this,p,{tag:"cancelled"})):E(this,p,{tag:"cancelled"}))}then(e,t){return e&&this.onResolved(e),t&&this.onCancelled(t),this}};p=new WeakMap,k=new WeakMap,L=new WeakSet,te=function(e){if(r(this,p).tag==="pending"){let{resolve_callbacks:t}=r(this,p);E(this,p,{tag:"completed",value:e}),t==null||t.forEach(n=>n(e))}};0&&(module.exports={Future,Option,Result}); | ||
"use strict";var W=Object.defineProperty;var re=Object.getOwnPropertyDescriptor;var ne=Object.getOwnPropertyNames;var oe=Object.prototype.hasOwnProperty;var ue=(u,e)=>{for(var t in e)W(u,t,{get:e[t],enumerable:!0})},le=(u,e,t,n)=>{if(e&&typeof e=="object"||typeof e=="function")for(let l of ne(e))!oe.call(u,l)&&l!==t&&W(u,l,{get:()=>e[l],enumerable:!(n=re(e,l))||n.enumerable});return u};var ae=u=>le(W({},"__esModule",{value:!0}),u);var X=(u,e,t)=>{if(!e.has(u))throw TypeError("Cannot "+t)};var r=(u,e,t)=>(X(u,e,"read from private field"),t?t.call(u):e.get(u)),S=(u,e,t)=>{if(e.has(u))throw TypeError("Cannot add the same private member more than once");e instanceof WeakSet?e.add(u):e.set(u,t)},U=(u,e,t,n)=>(X(u,e,"write to private field"),n?n.call(u,t):e.set(u,t),t);var J=(u,e,t)=>(X(u,e,"access private method"),t);var Z=(u,e,t)=>new Promise((n,l)=>{var R=b=>{try{k(t.next(b))}catch(a){l(a)}},s=b=>{try{k(t.throw(b))}catch(a){l(a)}},k=b=>b.done?n(b.value):Promise.resolve(b.value).then(R,s);k((t=t.apply(u,e)).next())});var se={};ue(se,{Future:()=>v,Option:()=>E,Result:()=>f});module.exports=ae(se);var Y=Error,f;(b=>{function u(a){return Object.freeze(new z(a))}b.Ok=u;function e(a){return Object.freeze(new P(a))}b.Error=e;function t(a){return a instanceof z||a instanceof P}b.isResult=t;function n(a,d){var F;try{return u(a())}catch(x){return e((F=d==null?void 0:d(x))!=null?F:x)}}b.fromExecution=n;function l(a,d){return Z(this,null,function*(){var F;try{return u(yield a)}catch(x){return e((F=d==null?void 0:d(x))!=null?F:x)}})}b.fromAwaitable=l;function R(a){let d=[];for(let F of a){if(F.isError())return F;d.push(F.unwrap())}return u(d)}b.all=R;function s(a){let d={};for(let F in a){let x=a[F];if(x.isError())return x;d[F]=x.unwrap()}return u(d)}b.allFromDict=s;function k(a){if(a.__orf_type__!=="Result"&&!("tag"in a))throw new Y("Invalid Result JSON");if(a.tag==="Ok"&&"value"in a)return u(a.value);if(a.tag==="Error"&&"error"in a)return e(a.error);throw new Y("Invalid Result JSON")}b.fromJSON=k})(f||(f={}));var z=class{constructor(e){this.value=e}isOk(){return!0}isError(){return!this.isOk()}match(e){return e.Ok(this.value)}map(e){return f.Ok(e(this.value))}mapOr(e,t){return t(this.value)}mapOrElse(e,t){return t(this.value)}mapError(e){return this}and(e){return e}andThen(e){return e(this.value)}or(e){return this}orElse(e){return this}tap(e){return e(Object.freeze(structuredClone(this.value))),this}tapError(e){return this}ok(){return E.Some(this.value)}unwrap(){return this.value}unwrapError(){throw new Y("Cannot unwrapError an Ok")}unwrapOr(e){return this.value}unwrapOrElse(e){return this.value}toJSON(){return{__orf_type__:"Result",tag:"Ok",value:this.value}}},P=class{constructor(e){this.error=e}isOk(){return!1}isError(){return!this.isOk()}match(e){return e.Error(this.error)}map(e){return this}mapOr(e,t){return e}mapOrElse(e,t){return e()}mapError(e){return f.Error(e(this.error))}and(e){return this}andThen(e){return this}or(e){return e}orElse(e){return e(this.error)}tap(e){return this}tapError(e){return e(Object.freeze(structuredClone(this.error))),this}ok(){return E.None()}unwrap(){throw this.error}unwrapError(){return this.error}unwrapOr(e){return e}unwrapOrElse(e){return e(this.error)}toJSON(){return{__orf_type__:"Result",tag:"Error",error:this.error}}};var E;(R=>{function u(s){return Object.freeze(new q(s))}R.Some=u;function e(){return ie}R.None=e;function t(s){return s instanceof q||s instanceof B}R.isOption=t;function n(s){return s?u(s):e()}R.from=n;function l(s){if(s.__orf_type__!=="Option"&&!("tag"in s))throw new Error("Invalid Option JSON");if(s.tag==="Some"&&"value"in s)return u(s.value);if(s.tag==="None")return e();throw new Error("Invalid Option JSON")}R.fromJSON=l})(E||(E={}));var q=class{constructor(e){this.value=e}isSome(){return!0}isNone(){return!this.isSome()}match(e){return e.Some(this.value)}map(e){return E.Some(e(this.value))}mapOr(e,t){return t(this.value)}mapOrElse(e,t){return t(this.value)}and(e){return e}andThen(e){return e(this.value)}or(e){return this}orElse(e){return this}tap(e){return e(Object.freeze(structuredClone(this.value))),this}unwrap(){return this.value}unwrapOr(e){return this.value}unwrapOrElse(e){return this.value}okOr(e){return f.Ok(this.value)}okOrElse(e){return f.Ok(this.value)}toJSON(){return{__orf_type__:"Option",tag:"Some",value:this.value}}},B=class{isSome(){return!1}isNone(){return!this.isSome()}match(e){return e.None()}map(e){return this}mapOr(e,t){return e}mapOrElse(e,t){return e()}and(e){return this}andThen(e){return this}or(e){return e}orElse(e){return e()}tap(e){return this}unwrap(){throw new Error("Cannot unwrap None")}unwrapOr(e){return e}unwrapOrElse(e){return e()}okOr(e){return f.Error(e)}okOrElse(e){return f.Error(e())}toJSON(){return{__orf_type__:"Option",tag:"None"}}},ie=Object.freeze(new B);var v;(V=>{function u(o){return new D({tag:"completed",value:o})}V.value=u;function e(o){return new A({tag:"completed",value:f.Ok(o)})}V.success=e;function t(o){return new A({tag:"completed",value:f.Error(o)})}V.fail=t;function n(o){return o instanceof D}V.isFuture=n;function l(o){return o instanceof A}V.isFallibleFuture=l;function R(o){return o instanceof A?o:o instanceof Promise?V.makeFallible((T,g)=>{o.then(T).catch(g)}):o.match({Ok:T=>e(T),Error:T=>t(T)})}V.fromFallible=R;function s(o,T){return new D({tag:"pending",execute:o},T)}V.make=s;function k(o){return new D({tag:"pending",execute:o},{lazy:!0})}V.lazy=k;function b(o,T){return new A({tag:"pending",execute:o},T)}V.makeFallible=b;function a(o){return new A({tag:"pending",execute:o},{lazy:!0})}V.lazyFallible=a;function d(o){return new D({tag:"pending",execute:T=>{let g=setTimeout(T,o);return()=>{clearTimeout(g)}}})}V.wait=d;function F(o){if(!o.some(V.isFallibleFuture)){let C=V.make(I=>{let y=new Array(o.length),_=0;return o.forEach((h,m)=>{h.onResolved(O=>{y[m]=O,_+=1,_===o.length&&I(y)})}),()=>o.forEach(h=>h.cancel())});return o.forEach(I=>I.onCancelled(C.cancel.bind(C))),C}let g=V.makeFallible((C,I)=>{let y=new Array(o.length),_=0;for(let h=0;h<o.length;++h){let m=o[h];V.isFuture(m)&&(m=m.neverError()),m.onResolved(O=>{y[h]=O,_+=1,_===o.length&&f.all(y).match({Ok:C,Error:I})})}return()=>o.forEach(h=>h.cancel())});return o.forEach(C=>C.onCancelled(g.cancel.bind(g))),g}V.all=F;function x(o){let T=Object.values(o),g=T.length;if(!T.some(V.isFallibleFuture)){let y=V.make(_=>{let h={},m=0;for(let O in o)o[O].onResolved(Q=>{h[O]=Q,m+=1,m===g&&_(h)});return()=>{for(let O of T)O.cancel()}});for(let _ of T)_.onCancelled(y.cancel.bind(y));return y}let I=V.makeFallible((y,_)=>{let h={},m=0;for(let O in o){let K=o[O];V.isFuture(K)&&(K=K.neverError()),K.onResolved(Q=>{h[O]=Q,m+=1,m===g&&f.allFromDict(h).match({Ok:y,Error:_})})}return()=>{for(let O of T)O.cancel()}});for(let y of T)y.onCancelled(I.cancel.bind(I));return I}V.allFromDict=x})(v||(v={}));var c,G,$,D=class{constructor(e,t){S(this,G);S(this,c,void 0);U(this,c,e),t!=null&&t.lazy||this.then()}onResolved(e){var t;r(this,c).tag==="pending"?(r(this,c).resolve_callbacks=(t=r(this,c).resolve_callbacks)!=null?t:[],r(this,c).resolve_callbacks.push(e)):r(this,c).tag==="completed"&&e(r(this,c).value)}onCancelled(e){var t;r(this,c).tag==="pending"?(r(this,c).cancel_callbacks=(t=r(this,c).cancel_callbacks)!=null?t:[],r(this,c).cancel_callbacks.push(e)):r(this,c).tag==="cancelled"&&e()}cancel(){if(r(this,c).tag==="pending"){let{cancel:e,cancel_callbacks:t}=r(this,c);U(this,c,{tag:"cancelled"}),e==null||e(),t==null||t.forEach(n=>n())}}then(e){if(r(this,c).tag==="pending"&&r(this,c).execute){let t=r(this,c).execute(J(this,G,$).bind(this));r(this,c).execute=null,t&&(r(this,c).cancel=t)}return e&&(this.onResolved(t=>e(E.Some(t))),this.onCancelled(()=>e(E.None()))),this}map(e){let t=v.make(n=>(this.onResolved(l=>{n(e(l))}),this.cancel.bind(this)));return this.onCancelled(t.cancel.bind(t)),t}tap(e){return this.onResolved(e),this}neverError(){let e=v.makeFallible((t,n)=>(this.onResolved(t),this.cancel.bind(this)));return this.onCancelled(e.cancel.bind(e)),e}unwrap(){let e=new N({tag:"pending",execute:t=>{this.onResolved(t)}});return this.onCancelled(e.cancel.bind(e)),e}unwrapOr(e){return new N({tag:"pending",execute:n=>(this.onResolved(l=>{n(l)}),this.onCancelled(()=>{n(e)}),()=>{n(e)})})}unwrapOrElse(e){return new N({tag:"pending",execute:n=>(this.onResolved(l=>{n(l)}),this.onCancelled(()=>{n(e())}),()=>{n(e())})})}};c=new WeakMap,G=new WeakSet,$=function(e){if(r(this,c).tag==="pending"){let{resolve_callbacks:t}=r(this,c);U(this,c,{tag:"completed",value:e}),t==null||t.forEach(n=>n(e))}};var i,H,j,L,ee,A=class{constructor(e,t){S(this,H);S(this,L);S(this,i,void 0);U(this,i,e),t!=null&&t.lazy||this.then()}onResolved(e){var t;r(this,i).tag==="pending"?(r(this,i).resolve_callbacks=(t=r(this,i).resolve_callbacks)!=null?t:[],r(this,i).resolve_callbacks.push(e)):r(this,i).tag==="completed"&&e(r(this,i).value)}onSucceeded(e){this.onResolved(t=>{t.match({Ok:e,Error:()=>{}})})}onFailed(e){this.onResolved(t=>{t.match({Ok:()=>{},Error:e})})}onCancelled(e){var t;r(this,i).tag==="pending"?(r(this,i).cancel_callbacks=(t=r(this,i).cancel_callbacks)!=null?t:[],r(this,i).cancel_callbacks.push(e)):r(this,i).tag==="cancelled"&&e()}cancel(){if(r(this,i).tag==="pending"){let{cancel:e,cancel_callbacks:t}=r(this,i);U(this,i,{tag:"cancelled"}),e==null||e(),t==null||t.forEach(n=>n())}}then(e){if(r(this,i).tag==="pending"&&r(this,i).execute){let t=r(this,i).execute(J(this,H,j).bind(this),J(this,L,ee).bind(this));r(this,i).execute=null,t&&(r(this,i).cancel=t)}return e&&(this.onResolved(t=>e(E.Some(t))),this.onCancelled(()=>e(E.None()))),this}map(e){let t=v.makeFallible((n,l)=>(this.onResolved(R=>{R.match({Ok:s=>{n(e(s))},Error:l})}),this.cancel.bind(this)));return this.onCancelled(t.cancel.bind(t)),t}mapError(e){let t=v.makeFallible((n,l)=>(this.onResolved(R=>{R.match({Ok:n,Error:s=>{l(e(s))}})}),this.cancel.bind(this)));return this.onCancelled(t.cancel.bind(t)),t}andThen(e){let t=v.makeFallible((n,l)=>(this.onResolved(R=>{R.match({Ok:s=>{let k=v.fromFallible(e(s));k.onSucceeded(n),k.onFailed(l)},Error:l})}),this.cancel.bind(this)));return this.onCancelled(t.cancel.bind(t)),t}orElse(e){let t=v.makeFallible((n,l)=>(this.onResolved(R=>{R.match({Ok:n,Error:s=>{let k=v.fromFallible(e(s));k.onSucceeded(n),k.onFailed(l)}})}),this.cancel.bind(this)));return this.onCancelled(t.cancel.bind(t)),t}tap(e){return this.onSucceeded(e),this}tapError(e){return this.onFailed(e),this}ok(){let e=v.make(t=>(this.onSucceeded(n=>t(E.Some(n))),this.onFailed(()=>t(E.None())),this.cancel.bind(this)));return this.onCancelled(e.cancel.bind(e)),e}unwrap(){let e=new N({tag:"pending",execute:t=>{this.onResolved(t)}});return this.onCancelled(e.cancel.bind(e)),e}unwrapOr(e){return new N({tag:"pending",execute:n=>(this.onResolved(n),this.onCancelled(()=>{n(e)}),()=>{n(e)})})}unwrapOrElse(e){return new N({tag:"pending",execute:n=>(this.onResolved(n),this.onCancelled(()=>{n(e())}),()=>{n(e())})})}match(e){let t=new N({tag:"pending",execute:n=>{this.onResolved(l=>{n(l.match(e))})}});return this.onCancelled(t.cancel.bind(t)),t}};i=new WeakMap,H=new WeakSet,j=function(e){if(r(this,i).tag==="pending"){let{resolve_callbacks:t}=r(this,i),n=f.Ok(e);U(this,i,{tag:"completed",value:n}),t==null||t.forEach(l=>l(n))}},L=new WeakSet,ee=function(e){if(r(this,i).tag==="pending"){let{resolve_callbacks:t}=r(this,i),n=f.Error(e);U(this,i,{tag:"completed",value:n}),t==null||t.forEach(l=>l(n))}};var p,w,M,te,N=class{constructor(e){S(this,M);S(this,p,void 0);S(this,w,void 0);if(U(this,p,e),r(this,p).tag==="pending"&&r(this,p).execute){let t=r(this,p).execute(J(this,M,te).bind(this));r(this,p).execute=null,t&&!r(this,w)&&U(this,w,t)}}onResolved(e){var t;r(this,p).tag==="pending"?(r(this,p).resolve_callbacks=(t=r(this,p).resolve_callbacks)!=null?t:[],r(this,p).resolve_callbacks.push(e)):r(this,p).tag==="completed"&&e(r(this,p).value)}onCancelled(e){r(this,p).tag==="pending"&&!r(this,w)?U(this,w,e):r(this,p).tag==="cancelled"&&!r(this,w)&&e(new Error("Cannot cancel UnwrappedFuture"))}cancel(){r(this,p).tag==="pending"&&(r(this,w)?(r(this,w).call(this,new Error("Cannot cancel UnwrappedFuture")),r(this,p).tag==="pending"&&U(this,p,{tag:"cancelled"})):U(this,p,{tag:"cancelled"}))}then(e,t){return e&&this.onResolved(e),t&&this.onCancelled(t),this}};p=new WeakMap,w=new WeakMap,M=new WeakSet,te=function(e){if(r(this,p).tag==="pending"){let{resolve_callbacks:t}=r(this,p);U(this,p,{tag:"completed",value:e}),t==null||t.forEach(n=>n(e))}};0&&(module.exports={Future,Option,Result}); |
{ | ||
"name": "@nobrayner/orf", | ||
"version": "0.0.3", | ||
"version": "0.0.4", | ||
"description": "Option. Result. Future", | ||
@@ -25,2 +25,6 @@ "sideEffect": false, | ||
"devDependencies": { | ||
"@babel/generator": "^7.26.2", | ||
"@babel/parser": "^7.26.2", | ||
"@babel/traverse": "^7.25.9", | ||
"@babel/types": "^7.26.0", | ||
"@changesets/changelog-github": "^0.4.6", | ||
@@ -32,2 +36,3 @@ "@changesets/cli": "^2.24.4", | ||
"typescript": "^5.7.2", | ||
"vite-node": "^2.1.6", | ||
"vitest": "^2.1.5" | ||
@@ -45,3 +50,4 @@ }, | ||
"test": "vitest", | ||
"build": "tsup", | ||
"build": "tsup && pnpm cleanup-build", | ||
"cleanup-build": "vite-node ./build_cleanup.ts", | ||
"format": "prettier --write \"src/**/*.ts\"", | ||
@@ -48,0 +54,0 @@ "changeset": "changeset", |
Sorry, the diff of this file is not supported yet
71651
1512
12