import { isDoddle, type MaybeDoddleAsync, type MaybePromise } from "../utils.js"; import type { Is_Any_Mixed, Is_Any_Pure_Async, Matches_Mixed_Value } from "./helpers.js"; export declare const ownerInstance: unique symbol; /** * A TypeScript-first doddle evaluation primitive. An object that will only evaluate its initializer * function when the {@link pull} method is called. * * The initializer can return another {@link Doddle}, which will be chained like a promise. * * @category Use */ export declare class Doddle { private _cacheName; /** The cached value or error, stored from a previous execution of the initializer. */ private _cached?; private _info; /** * The initializer function that will be called to construct the value. It will be cleared after * the value is constructed. */ private _init; /** @ignore */ constructor(initializer: (...args: any[]) => any); /** Returns metadata about the current state of the Doddle. */ get info(): Readonly; /** * Returns a new {@link Doddle} based on this one. When pulled, it will pull `this` and yield the * same value. If an error occurs, the handler will be called with the error. The doddle then * yields whatever the handler returns. * * You can pass an async handler only if `this` is async too. * * @example * const d = doddle(() => { * throw new Error("Oops") * }) * const handled = d.catch(error => { * console.error(error) * return 42 * }) * const pulled = handled.pull() * console.log(pulled) // 42 * * // async Doddles allow an async handler: * const d = doddle(async () => { * throw new Error("Oops") * }) * const handled = d.catch(async error => { * console.error(error) * return 42 * }) * const pulled = await handled.pull() * console.log(pulled) // 42 * * // @ts-expect-error but passing an async handler for a sync doddle isn't allowed. * const d = doddle(() => 1).catch(async () => 2) * * @param this The Doddle instance. * @param handler The error handler function. */ catch(this: DoddleAsync, handler: (error: any) => Doddle.SomeAsync): DoddleAsync>; catch(this: DoddleAsync, handler: (error: any) => R | Doddle | Doddle.SomeAsync): DoddleAsync>; catch(this: Matches_Mixed_Value, handler: (error: any) => Doddle.SomeAsync): Doddle>; catch(this: Matches_Mixed_Value, handler: (error: any) => R | Doddle): Doddle; catch(handler: R extends PromiseLike ? never : (error: any) => R | Doddle): Doddle; /** * Returns a new {@link Doddle} based on this one. When pulled, it will pull `this` and invoke * the given action function as a side-effect. It will then yield whatever `this` did. * * If the action returns a Promise, it will be awaited before yielding the result, making the * returned Doddle async. * * @param action The action to perform. */ do(this: Matches_Mixed_Value, action: (value: Doddle.PulledAwaited) => Doddle.SomeAsync): DoddleAsync>; do(this: DoddleAsync, action: (value: Doddle.PulledAwaited) => void | Doddle | Doddle.SomeAsync): DoddleAsync; do(this: Matches_Mixed_Value, action: (value: Doddle.PulledAwaited) => void | Doddle | Doddle.SomeAsync): Doddle; do(this: Doddle, action: (value: Doddle.PulledAwaited) => Doddle.SomeAsync): DoddleAsync; do(this: Matches_Mixed_Value>, action: (value: Doddle.PulledAwaited) => R | Doddle): Doddle>; do(this: Doddle, action: (value: Doddle.PulledAwaited) => void | Doddle): Doddle; /** * Creates a new {@link Doddle} based on `this`. When pulled, it will pull `this` and project the * result using the given function. * * When `this` is async, the projection will be passed the awaited value, and the function will * return an async Doddle. It also happens if you pass an async projection. * * @example * // Sync inputs: * const d = doddle(() => 42) * const mapped = d.map(x => x + 1) * const pulled = mapped.pull() * console.log(pulled) // 43 * * // async inputs: * const d = doddle(async () => 42) * const mapped = d.map(x => x + 1) // note that the awaited value is used * const pulled = await mapped.pull() * console.log(pulled) // 43 * * // async projection: * const d = doddle(() => 42) * const mapped = d.map(async x => x + 1) * const pulled = await mapped.pull() * console.log(pulled) // 43 * * @param projection The function to apply to the pulled value. */ map(this: Doddle, projection: (value: Doddle.PulledAwaited) => Doddle.SomeAsync): DoddleAsync; map(this: Matches_Mixed_Value>, projection: (value: Doddle.PulledAwaited) => R | Doddle): DoddleAsync>; map(this: DoddleAsync, projection: (value: Doddle.PulledAwaited) => Doddle | R): DoddleAsync; map(this: Matches_Mixed_Value & Matches_Mixed_Value>, projection: (value: Doddle.PulledAwaited) => R | Doddle): Doddle; map(this: Matches_Mixed_Value, projection: (value: Doddle.PulledAwaited) => R | Doddle): Doddle>; map(this: Doddle, projection: (value: Doddle.PulledAwaited) => R | Doddle): Doddle; /** * Returns a memoized function, which acts like this Doddle while hiding its type. * * @returns A memoized function that pulls `this` and returns its result. */ memoize(): () => T; /** * Evaluates this {@link Doddle} instance, flattening any nested {@link Doddle} or {@link Promise} * types and yielding its value. * * @returns The yielded value. * @throws The error thrown during initialization, if any. */ pull(): Doddle.Pulled; /** Returns a short description of the Doddle value and its state. */ toString(): string; /** * Returns a new Doddle based on this one, together with the input Doddles. When pulled, it will * pull `this` and all `others`, yielding their results in an array. * * If either `this` or any of `others` is async, the resulting Doddle will also be async. * * @param others The other Doddles to zip with. */ zip, ...Doddle[]]>(...others: Others): Is_Any_Pure_Async<[ Doddle, ...Others ], DoddleAsync<[ Doddle.PulledAwaited, ...{ [K in keyof Others]: Doddle.PulledAwaited; } ]>, Is_Any_Mixed<[ Doddle, ...Others ], Doddle, ...{ [K in keyof Others]: Doddle.PulledAwaited; } ]>>, Doddle<[ Doddle.Pulled, ...{ [K in keyof Others]: Doddle.Pulled; } ]>>>; } /** * Creates a {@link Doddle} lazy primitive around a given function. Supports both sync and async * initializers and flattens nested Doddle or {@link Promise} types. * * See examples for usage. * * @category Create * @example * // Simple initializer: * const regular = doddle(() => 1) satisfies Doddle * * // Initializer returning another lazily primitive is flattened: * const lazyNested = doddle(() => doddle(() => 1)) satisfies Doddle * * // Async initializer gives a `DoddleAsync` instance: * const lazyAsync = doddle(async () => 1) satisfies DoddleAsync * * // Async initializer returning another lazily primitive is flattened: * const asyncDoddle = doddle(async () => doddle(() => 1)) satisfies DoddleAsync * * // Async initializer returning another lazily async primitive is flattened: * const asyncDoddleAsync = doddle(async () => * doddle(async () => 1) * ) satisfies DoddleAsync * * @param initializer An initializer that will be called once to produce the value. */ export declare function doddle(initializer: () => PromiseLike>): DoddleAsync; export declare function doddle(initializer: () => PromiseLike>): DoddleAsync; export declare function doddle(initializer: () => PromiseLike): DoddleAsync; export declare function doddle(initializer: () => Doddle): Doddle; export declare function doddle(initializer: () => T | Doddle): Doddle; /** * Doddle utility functions. * * @category Create */ export declare namespace doddle { const is: typeof isDoddle; } /** * Doddle utility types. * * @category Types */ export declare namespace Doddle { /** An metadata object describing the state of a {@link Doddle} instance. */ interface Metadata { /** A human-readable representation of the Doddle's state. */ readonly desc: string; /** Whether the Doddle has already been pulled. */ readonly isReady: boolean; /** The current stage of the Doddle's execution. */ readonly stage: string; /** Whether the Doddle is sync or async (or whether it's unknown). */ readonly syncness: string; } /** * Recursively pulls the result type of a {@link Doddle}, cutting thoruhg any {@link PromiseLike} * types. Returns an async representation if the input as async. */ type Pulled = T extends PromiseLike ? Promise> : T extends Doddle ? Pulled : T; /** Recursively pulls the result type of a {@link Doddle}, cutting through any {@link PromiseLike} */ type PulledAwaited = T extends Doddle ? PulledAwaited : T extends PromiseLike ? PulledAwaited : T; /** An async value or a {@link Doddle} that can be pulled to get an async value. */ type SomeAsync = PromiseLike | DoddleAsync | PromiseLike> | PromiseLike>; /** A value, a promise, a doddle, an async doddle, or similar nestings. */ type MaybePromised = MaybePromise | MaybeDoddleAsync>; } /** * An async {@link Doddle}, which is just a `Doddle>`. * * @category Use */ export type DoddleAsync = Doddle>; /** * Similar to `await`. Pulls a value from a {@link Doddle}, which may be async. The same as calling * {@link Doddle.pull} on the input. * * @category Use * @param input */ export declare function pull(input: 1 extends 0 & T ? T : never): any; /** * Similar to `await`. Pulls a value from a {@link Doddle}, which may be async. The same as calling * {@link Doddle.pull} on the input. * * @param input */ export declare function pull(input: T): Doddle.Pulled; //# sourceMappingURL=index.d.ts.map