/*! * ======================================================================== * @rzl-zone/utils-js * ------------------------------------------------------------------------ * Version: `3.15.0` * Author: `Rizalvin Dwiky ` * Repository: `https://github.com/rzl-zone/rzl-zone/tree/main/packages/utils-js` * ======================================================================== */ import { o as CustomPromiseType } from "../index-Cr6qFcbC.cjs"; /** ------------------------------------------------------------- * * ***Utility Class: `CustomPromise`.*** * -------------------------------------------------------------- * **A strongly typed extension of the native {@link Promise | **`Promise`**}.** * * --- * 1. **Behaves exactly like a normal Promise** for `then`/`catch` * and `await` semantics. * 2. **Stores the final resolution or rejection internally** so * it can be retrieved by a custom `finish` handler. * 3. **Adds a `finish` method** which runs once after settlement * with access to both the fulfilled value *and* the rejection * reason (only one will be defined). * * --- * - **Key Differences from a Native `Promise`:** * - Every call to `then`/`catch` returns **`CustomPromise`** * again, so the `finish` method remains available on the * entire chain. * - `finish` provides a tuple-like callback: * - `val` ➔ defined when fulfilled. * - `err` ➔ defined when rejected. * * --- * @template Success Type of the resolved value. * @template Error Type of the rejection reason (default `unknown`). * * --- * @example * ```ts * import { CustomPromise, type CustomPromiseType } from "@rzl-zone/utils-js/promises"; * * type User = { id: number; name: string }; * type ApiError = { message: string }; * * function fetchUser(): CustomPromiseType { * return new CustomPromise((resolve, reject) => { * setTimeout( * () => * void (Math.random() > 0.5 * ? resolve({ id: 1, name: "Alice" }) * : reject({ message: "Random failure" })), * 500 * ); * }); * } * * fetchUser() * .then(user => { * console.log("SUCCESS:", user); * return user; * }) * .catch(err => { * console.error("ERROR:", err); * throw err; * }) * .finish((val, err) => { * // Runs once after settle, regardless of outcome * console.log("FINISH:", { val, err }); * }); * ``` * --- * - **Implementation Notes:** * - Uses `Object.setPrototypeOf` to preserve the prototype chain * for environments targeting ES5 or when subclassing Promise. * - Internal settlement state is tracked automatically, * allowing `finish` to access the final result even * when registered after settlement. */ declare class CustomPromise extends Promise implements CustomPromiseType { /** ------------------------------------------------------------ * * ***Constructor: `CustomPromise`.*** * ------------------------------------------------------------- * **Creates a new `CustomPromise` instance using a custom executor.** * * --- * - **Behavior:** * - Behaves similarly to the native * ***`Promise`*** constructor. * - Receives custom `resolve` and `reject` * functions through the executor callback. * - Stores the resolved value or rejection reason * internally for use by `finish`. * - Preserves the `CustomPromise` prototype chain * for subclassed promise behavior. * - Ensures chained `then` and `catch` * operations continue returning * ***`CustomPromise`*** instances. * * --- * @param {(resolve, reject) => void} executor * ***Executor function responsible for controlling the asynchronous operation lifecycle.*** * * @param {(value: Success) => void} executor.resolve * ***Function used to resolve the promise with a value.*** * * @param {(error: Error) => void} executor.reject * ***Function used to reject the promise with an error.*** * * --- * @throws **{@link Error | `Error`}** * Any uncaught exception thrown inside the executor * automatically rejects the promise. * * --- * @example * ```ts * const promise = new CustomPromise( * (resolve) => { * setTimeout( * () => resolve("Done"), * 1000 * ); * } * ); * ``` * --- * @example * ```ts * const promise = new CustomPromise< * string, * Error * >((resolve, reject) => { * Math.random() > 0.5 * ? resolve("Success") * : reject( * new Error("Failed") * ); * }); * ``` */ constructor(executor: (resolve: (value: Success) => void, reject: (error: Failure) => void) => void); /** --------------------------------------------------------------- * * ***Overrides `Promise.then()` while preserving the * `CustomPromise` prototype chain.*** * ---------------------------------------------------------------- * **Registers callbacks for both fulfillment and rejection.** * * --- * Unlike the native `Promise`, this override ensures the returned * value remains a ***`CustomPromise`*** so additional methods * such as `finish()` continue to be available throughout the chain. * * --- * @template TResult1 * ***Result type returned by the fulfillment handler.*** * * @template TResult2 * ***Result type returned by the rejection handler.*** * * --- * @param onfulfilled * ***Callback executed when the promise resolves successfully.*** * * @param onfulfilled.value * ***Resolved value from the current promise.*** * * @param onrejected * ***Callback executed when the promise is rejected.*** * * @param onrejected.reason * ***Rejection reason from the current promise.*** * * --- * @returns A new ***`CustomPromise`*** containing the transformed result. */ override then(onfulfilled?: ((value: Success) => TResult1 | PromiseLike) | null, onrejected?: ((reason: Failure) => TResult2 | PromiseLike) | null): CustomPromise; /** --------------------------------------------------------------- * * ***Overrides `Promise.catch()` while preserving the * `CustomPromise` prototype chain.*** * ---------------------------------------------------------------- * **Registers a callback for promise rejection handling.** * * --- * Unlike the native `Promise`, this override ensures the returned * value remains a ***`CustomPromise`*** so additional methods * such as `finish()` continue to be available throughout the chain. * * --- * @template TResult * ***Result type returned by the rejection handler.*** * * --- * @param onrejected * ***Callback executed when the promise is rejected.*** * * @param onrejected.reason * ***Rejection reason from the current promise.*** * * --- * @returns A new ***`CustomPromise`*** containing either the * original success value or the transformed rejection result. */ override catch(onrejected?: ((reason: Failure) => TResult | PromiseLike) | null): CustomPromise; /** --------------------------------------------------------------- * * ***Registers a callback to be invoked exactly once when the * promise settles.*** * ---------------------------------------------------------------- * *If the promise is already settled when `finish()` is called, * the callback executes immediately on the same tick.* * * --- * @param callback * ***Callback receiving the final settlement result.*** * * @param callback.value * ***Resolved value when the promise is fulfilled.*** * * @param callback.error * ***Rejection reason when the promise is rejected.*** * * --- * @returns `this` for fluent chaining. */ finish(callback: (value?: Success, error?: Failure) => void): this; } /** ------------------------------------------------------------ * * ***Utility: `delay`.*** * ------------------------------------------------------------- * **Creates a Promise-based delay that resolves after a given number * of milliseconds, optionally supports cancellation with `AbortSignal`.** * * --- * - **Behavior:** * - Validates `milliSeconds` is a non-zero, non-negative integer. * - Validates `signal` is an `AbortSignal` instance when provided. * - Cleans up event listeners and timers properly. * * --- * @param {number} [milliSeconds=1000] * The duration of the delay in milliseconds, default is `1000`. * @param {AbortSignal} [signal] * An optional `AbortSignal` that can cancel the delay. * * --- * @throws **{@link TypeError | `TypeError`}** while validates `milliSeconds` and `signal`: * - If `milliSeconds` **is not a valid** an `integer-number`, `NaN`, `negative-number`, or `≤ 0`. * - If `signal` **is not a valid** an`AbortSignal`. * @throws **{@link AbortError | `AbortError`}** if the delay is aborted using the provided signal. * * --- * @returns {Promise} * A promise that resolves after the specified delay or * rejects with an `AbortError` if aborted. * * --- * @example * 1. #### Waits for 2 seconds: * ```ts * await delay(2000); * ``` * --- * 2. #### Delay with AbortSignal: * ```ts * const controller = new AbortController(); * delay(5000, controller.signal).catch(err => { * console.log(err.name) * // ➔ "AbortError:['@rzl-zone/utils-js/promises:delay']" * }); * controller.abort(); * ``` */ declare const delay: (milliSeconds?: number, signal?: AbortSignal) => Promise; export { CustomPromise, type CustomPromiseType, delay };