UNPKG

@tempots/std

Version:

Std library for TypeScript. Natural complement to the Tempo libraries.

317 lines (316 loc) 13.4 kB
import { Maybe } from './domain'; /** * Represents the state when a result has not been requested yet. * @public */ export type NotAsked = { readonly type: 'NotAsked'; }; /** * Represents a loading state in an asynchronous result. * @public */ export type Loading<V> = { readonly type: 'Loading'; readonly previousValue?: V; }; /** * Represents a successful result. * @typeParam V - The type of the value. * @public */ export type AsyncSuccess<V> = { readonly type: 'AsyncSuccess'; readonly value: V; }; /** * Represents a failure result. * @typeParam E - - The type of the error. * @public */ export type AsyncFailure<E> = { readonly type: 'AsyncFailure'; readonly error: E; }; /** * Represents the result of an asynchronous operation that can be in one of the following states: * - `NotAsked`: The operation has not been requested yet. * - `Loading`: The operation is currently in progress. * - `Success`: The operation has completed successfully and contains a value of type `V`. * - `Failure`: The operation has completed with an error and contains an error of type `E`. * * @typeParam V - The type of the value on success. * @typeParam E - The type of the error on failure. * @public */ export type AsyncResult<V, E> = NotAsked | Loading<V> | AsyncSuccess<V> | AsyncFailure<E>; /** * Represents a settled state in an asynchronous result. * @public */ export type Settled<V, E> = AsyncSuccess<V> | AsyncFailure<E>; /** * Represents a state in an asynchronous result that is not loading. * @public */ export type NonLoading<V, E> = NotAsked | Settled<V, E>; /** * A set of utility functions for working with `AsyncResult`. * @public */ export declare const AsyncResult: { /** * Creates a loading state. * @param previousValue - The previous value. * @returns A loading state. * @public */ notAsked: { type: "NotAsked"; }; /** * Creates a loading state. * @param previousValue - The previous value. * @returns A loading state. * @public */ loading<V>(previousValue?: Maybe<V>): AsyncResult<V, never>; /** * Creates a successful state. * @param value - The value. * @returns A successful state. * @public */ success<V>(value: V): AsyncResult<V, never>; /** * Creates a failure state. * @param error - The error. * @returns A failure state. * @public */ failure<E>(error: E): AsyncResult<never, E>; /** * Checks if the result is a success. * @param r - The result. * @returns `true` if the result is a success; otherwise, `false`. * @public */ isSuccess<V, E>(r: AsyncResult<V, E>): r is AsyncSuccess<V>; /** * Checks if the result is a failure. * @param r - The result. * @returns `true` if the result is a failure; otherwise, `false`. * @public */ isFailure<V, E>(r: AsyncResult<V, E>): r is AsyncFailure<E>; /** * Checks if the result is a not-asked. * @param r - The result. * @returns `true` if the result is not-asked; otherwise, `false`. * @public */ isNotAsked<V, E>(r: AsyncResult<V, E>): r is NotAsked; /** * Checks if the result is a loading. * @param r - The result. * @returns `true` if the result is loading; otherwise, `false`. * @public */ isLoading<V, E>(r: AsyncResult<V, E>): r is Loading<V>; /** * Gets the value if the result is a success or loading with a previous value; otherwise, returns the alternative value. * @param r - The result. * @param alt - The alternative value. * @returns The value if the result is a success or loading with previous value; otherwise, the alternative value. * @public */ getOrElse<V, E>(r: AsyncResult<V, E>, alt: V): V; /** * Gets the value if the result is a success or loading with a previous value; otherwise, returns the value from the alternative function. * @param r - The result. * @param altf - The alternative function. * @returns The value if the result is a success or loading with previous value; otherwise, the value from the alternative function. * @public */ getOrElseLazy<V, E>(r: AsyncResult<V, E>, altf: () => V): V; /** * Gets the value if the result is a success or loading with a previous value; otherwise, returns `null`. * @param r - The result. * @returns The value if the result is a success or loading with previous value; otherwise, `null`. * @public */ getOrNull<V, E>(r: AsyncResult<V, E>): V | null; /** * Gets the value if the result is a success or loading with a previous value; otherwise, returns `undefined`. * @param r - The result. * @returns The value if the result is a success or loading with previous value; otherwise, `undefined`. * @public */ getOrUndefined<V, E>(r: AsyncResult<V, E>): Maybe<V>; /** * Gets the value of a `AsyncResult` if it is a `Success` or loading with a previous value, otherwise it throws the error contained in the `Failure`. * @param r - The `AsyncResult` to get the value from. * @returns The value of the `AsyncResult` if it is a `Success` or loading with previous value. */ getUnsafe: <V, E>(r: AsyncResult<V, E>) => V; /** * Based on the state of the result, it picks the appropriate function to call and returns the result. * @param success - The function to call if the result is a success. * @param failure - The function to call if the result is a failure. * @param loading - The function to call if the result is loading. * @param notAsked - The function to call if the result is not-asked. * @returns The result of calling the appropriate function based on the state of the result. * @public */ match: <V1, V2, E>(r: AsyncResult<V1, E>, { success, failure, loading, notAsked, }: { success: (value: V1) => V2; failure: (error: E) => V2; loading: (previousValue?: V1) => V2; notAsked: () => V2; }) => V2; /** * Executes side effects based on the state of the result. * Unlike `match`, all handlers are optional, allowing you to react only to specific states. * The `else` handler is called when no specific handler is provided for the current state. * @param r - The result. * @param handlers - An object with optional handlers for each state and an optional `else` fallback. * @returns The result that was passed in, allowing for chaining. * @public */ effect: <V, E>(r: AsyncResult<V, E>, handlers: { success?: (value: V) => void; failure?: (error: E) => void; loading?: (previousValue?: V) => void; notAsked?: () => void; else?: () => void; }) => AsyncResult<V, E>; /** * When the result is a success, it applies the function to the value. * * @param r - The result. * @param apply - The function to apply. * @returns The result that was passed in. * @public */ whenSuccess: <V, E>(r: AsyncResult<V, E>, apply: (v: V) => void) => AsyncResult<V, E>; /** * When the result is a failure, it applies the function to the error. * * @param r - The result. * @param apply - The function to apply. * @returns The result that was passed in. * @public */ whenFailure: <V, E>(r: AsyncResult<V, E>, apply: (e: E) => void) => AsyncResult<V, E>; /** * Compares two results for equality. * @param r1 - The first result. * @param r2 - The second result. * @param options - The options to use for comparison. By default, uses strict equality. * @returns `true` if the results are equal, `false` otherwise. */ equals: <V, E>(r1: AsyncResult<V, E>, r2: AsyncResult<V, E>, options?: { valueEquals: (v1: V, v2: V) => boolean; errorEquals: (e1: E, e2: E) => boolean; }) => boolean; /** * Combines multiple results into a single result. * @param results - The results to combine. * @returns A single result that is a success if all the input results are successes, otherwise a failure. */ all: <V, E>(results: AsyncResult<V, E>[]) => AsyncResult<V[], E>; /** * Converts a Promise to an AsyncResult. * @param p - The Promise to convert. * @returns A Promise that resolves to an AsyncResult. */ ofPromise: <V>(p: Promise<V>) => Promise<AsyncResult<V, Error>>; /** * Maps the value of a successful `AsyncResult` to a new value using the provided function. * For other states (NotAsked, Loading, Failure), the state is preserved. * When mapping a Loading state with a previous value, the previous value is also mapped. * @param result - The `AsyncResult` to map. * @param fn - The mapping function to apply to the success value. * @returns A new `AsyncResult` with the mapped value if successful, otherwise the original state. * @public */ map: <V, U, E>(result: AsyncResult<V, E>, fn: (value: V) => U) => AsyncResult<U, E>; /** * Maps the value of a successful `AsyncResult` to a new `AsyncResult` using the provided function. * This is useful for chaining operations that may also fail. * @param result - The `AsyncResult` to flat map. * @param fn - The mapping function that returns a new `AsyncResult`. * @returns The result of the mapping function if successful, otherwise the original state. * @public */ flatMap: <V, U, E>(result: AsyncResult<V, E>, fn: (value: V) => AsyncResult<U, E>) => AsyncResult<U, E>; /** * Maps the error of a failed `AsyncResult` to a new error using the provided function. * For other states, the state is preserved. * @param result - The `AsyncResult` to map the error of. * @param fn - The mapping function to apply to the error. * @returns A new `AsyncResult` with the mapped error if failed, otherwise the original state. * @public */ mapError: <V, E, F>(result: AsyncResult<V, E>, fn: (error: E) => F) => AsyncResult<V, F>; /** * Maps the error of a failed `AsyncResult` to a new `AsyncResult` using the provided function. * This allows recovery from errors by returning a new successful result. * @param result - The `AsyncResult` to recover from. * @param fn - The recovery function that returns a new `AsyncResult`. * @returns The result of the recovery function if failed, otherwise the original state. * @public */ flatMapError: <V, E, F>(result: AsyncResult<V, E>, fn: (error: E) => AsyncResult<V, F>) => AsyncResult<V, F>; /** * Converts an `AsyncResult` to a `Result`, discarding the loading and not-asked states. * Returns `undefined` if the result is not settled (i.e., NotAsked or Loading). * @param result - The `AsyncResult` to convert. * @returns A `Result` if the `AsyncResult` is settled, otherwise `undefined`. * @public */ toResult: <V, E>(result: AsyncResult<V, E>) => import('./result').Result<V, E> | undefined; /** * Checks if the result is settled (either success or failure). * @param r - The result. * @returns `true` if the result is settled; otherwise, `false`. * @public */ isSettled<V, E>(r: AsyncResult<V, E>): r is Settled<V, E>; /** * Recovers from a failure by providing an alternative value. * @param result - The `AsyncResult` to recover from. * @param fn - The function that provides an alternative value given the error. * @returns A successful `AsyncResult` with the alternative value if failed, otherwise the original state. * @public */ recover: <V, E>(result: AsyncResult<V, E>, fn: (error: E) => V) => AsyncResult<V, never>; /** * Applies a function wrapped in an `AsyncResult` to a value wrapped in an `AsyncResult`. * Useful for applying multiple arguments to a function in a safe way. * @param resultFn - The `AsyncResult` containing the function. * @param resultVal - The `AsyncResult` containing the value. * @returns A new `AsyncResult` with the result of applying the function to the value. * @public */ ap: <V, U, E>(resultFn: AsyncResult<(v: V) => U, E>, resultVal: AsyncResult<V, E>) => AsyncResult<U, E>; /** * Maps two `AsyncResult` values using a function. * @param r1 - The first `AsyncResult`. * @param r2 - The second `AsyncResult`. * @param fn - The function to apply to both values. * @returns A new `AsyncResult` with the result of applying the function to both values. * @public */ map2: <V1, V2, U, E>(r1: AsyncResult<V1, E>, r2: AsyncResult<V2, E>, fn: (v1: V1, v2: V2) => U) => AsyncResult<U, E>; /** * Maps three `AsyncResult` values using a function. * @param r1 - The first `AsyncResult`. * @param r2 - The second `AsyncResult`. * @param r3 - The third `AsyncResult`. * @param fn - The function to apply to all three values. * @returns A new `AsyncResult` with the result of applying the function to all three values. * @public */ map3: <V1, V2, V3, U, E>(r1: AsyncResult<V1, E>, r2: AsyncResult<V2, E>, r3: AsyncResult<V3, E>, fn: (v1: V1, v2: V2, v3: V3) => U) => AsyncResult<U, E>; };