import {TimeoutError} from '../common/Errors.js'; /** * @internal */ export interface DeferredPromise extends Promise { finished: () => boolean; resolved: () => boolean; resolve: (value: T) => void; reject: (reason?: unknown) => void; value: () => T | undefined; } /** * @internal */ export interface DeferredPromiseOptions { message: string; timeout: number; } /** * Creates and returns a promise along with the resolve/reject functions. * * If the promise has not been resolved/rejected within the `timeout` period, * the promise gets rejected with a timeout error. `timeout` has to be greater than 0 or * it is ignored. * * @internal */ export function createDeferredPromise( opts?: DeferredPromiseOptions ): DeferredPromise { let isResolved = false; let isRejected = false; let _value: T | undefined; let resolver: (value: T) => void; let rejector: (reason?: unknown) => void; const taskPromise = new Promise((resolve, reject) => { resolver = resolve; rejector = reject; }); const timeoutId = opts && opts.timeout > 0 ? setTimeout(() => { isRejected = true; rejector(new TimeoutError(opts.message)); }, opts.timeout) : undefined; return Object.assign(taskPromise, { resolved: () => { return isResolved; }, finished: () => { return isResolved || isRejected; }, resolve: (value: T) => { if (timeoutId) { clearTimeout(timeoutId); } isResolved = true; _value = value; resolver(value); }, reject: (err?: unknown) => { clearTimeout(timeoutId); isRejected = true; rejector(err); }, value: () => { return _value; }, }); }