import {error, ok} from '../result/misc'; import type {Result} from '../result/models'; import { CancelablePromise, PROMISE_ABORT_EVENT, PROMISE_MESSAGE_EXPECTATION_RESULT, PROMISE_TYPE_FULFILLED, PROMISE_TYPE_REJECTED, type PromiseParameters, } from './models'; // #region Functions /** * Create a cancelable _Promise_ * * @param executor Executor function for the _Promise_ * @returns Cancelable _Promise_ */ export function cancelable( executor: (resolve: (value: Value) => void, reject: (reason: unknown) => void) => void, ): CancelablePromise { return new CancelablePromise(executor); } export function handleResult(status: string, parameters: PromiseParameters): void { const {abort, complete, data, handlers, index, signal, value} = parameters; if (signal?.aborted ?? false) { return; } if (!complete && status === PROMISE_TYPE_REJECTED) { settlePromise(abort, handlers.reject, value, signal); return; } (data.result as unknown[])[index] = !complete ? value : status === PROMISE_TYPE_FULFILLED ? {status, value} : {status, reason: value}; if (index === data.last) { settlePromise(abort, handlers.resolve, data.result, signal); } } export function settlePromise( aborter: () => void, settler: (value: any) => void, value: unknown, signal?: AbortSignal, ): void { signal?.removeEventListener(PROMISE_ABORT_EVENT, aborter); settler(value); } /** * Converts a _Promise_ to a promised result * * @param callback _Promise_ callback * @returns Promised result */ export async function toResult(callback: () => Promise): Promise>; /** * Converts a _Promise_ to a promised result * * @param promise _Promise_ to convert * @returns Promised result */ export async function toResult(promise: Promise): Promise>; export async function toResult( value: Promise | (() => Promise), ): Promise> { const actual = typeof value === 'function' ? value() : value; if (!(actual instanceof Promise)) { return Promise.reject(new TypeError(PROMISE_MESSAGE_EXPECTATION_RESULT)); } return actual.then(result => ok(result)).catch(reason => error(reason)); } // #endregion // #region Exports export {toPromise as fromResult} from '../result/misc'; export {isFulfilled, isRejected} from './helpers'; // #endregion