UNPKG

@akala/core

Version:
145 lines 5.13 kB
import { Event } from "./events/shared.js"; export { isPromiseLike } from './teardown-manager.js'; /** * Converts a Promise to an Event emitter that fires when the Promise resolves * @template T - The type of the Promise resolution value * @param {PromiseLike<T>} promise - The Promise to convert * @returns {IEventSink<[T], void, unknown>} Event emitter that will emit the resolved value */ export function toEvent(promise) { const result = new Event(Event.maxListeners, () => { }); promise.then(v => { try { result.emit(v); } finally { result[Symbol.dispose](); } }); return result; } /** * Converts an Event emitter to a Promise that resolves when the event fires * @template T - The type of the event payload * @param {IEventSink<[T], void, unknown>} event - The event emitter to convert * @returns {PromiseLike<T>} Promise that resolves with the first event payload */ export function fromEvent(event) { const result = new Deferred(); event.addListener(value => result.resolve(value), { once: true }); return result; } /** * Converts an Event emitter to a Promise that resolves when the event fires * @template T - The type of the event payload * @param {IEventSink<[T], void, unknown>} event - The event emitter to convert * @returns {PromiseLike<T>} Promise that resolves with the first event payload */ export function fromEventBus(bus, eventName) { const result = new Deferred(); bus.once(eventName, (value => result.resolve(value))); return result; } /** * Converts an Event emitter to a Promise that resolves when the event fires * @template T - The type of the event payload * @param {IEventSink<[T], void, unknown>} event - The event emitter to convert * @returns {PromiseLike<T>} Promise that resolves with the first event payload */ export async function fromAsyncEventBus(bus, eventName) { const result = new Deferred(); await bus.once(eventName, (value => result.resolve(value))); return result; } /** * A Deferred Promise pattern implementation allowing external resolution control * @template T - The type of the resolved value * @template TError - The type of the rejection reason (defaults to Error) */ export class Deferred { _resolve; _reject; promise; /** * Resolves the deferred Promise with a value * @param {T | PromiseLike<T> | undefined} _value - The resolution value * @throws {Error} If called before Promise initialization */ resolve(_value) { if (typeof (this._resolve) == 'undefined') throw new Error('Not Implemented'); this._resolve(_value); } /** * Rejects the deferred Promise with a reason * @param {TError} _reason - The rejection reason * @throws {Error} If called before Promise initialization */ reject(_reason) { if (typeof (this._reject) == 'undefined') throw new Error('Not Implemented'); this._reject(_reason); } constructor() { let _resolve; let _reject; this.promise = new Promise((resolve, reject) => { _resolve = resolve; _reject = reject; }); this._resolve = _resolve; this._reject = _reject; } then(onfulfilled, onrejected) { return this.promise.then(onfulfilled, onrejected); } catch(onrejected) { return this.promise.catch(onrejected); } finally(onfinally) { return this.promise.finally(onfinally); } get [Symbol.toStringTag]() { return this.promise[Symbol.toStringTag]; } } /** * Creates a Promise that resolves after a specified delay * @param {number} delay - Delay duration in milliseconds * @returns {Promise<void>} Promise that resolves after the delay */ export function delay(delay) { return new Promise((resolve) => { setTimeout(resolve, delay); }); } /** * Wraps a Promise with a timeout, rejecting if it doesn't resolve in time * @template T - The type of the original Promise resolution * @param {PromiseLike<T>} promise - The Promise to wrap * @param {number} timeoutInMs - Timeout duration in milliseconds * @returns {PromiseLike<T>} New Promise that either resolves with the original value or rejects with 'timeout' */ export function whenOrTimeout(promise, timeoutInMs) { return new Promise((resolve, reject) => { const timeOut = setTimeout(function () { reject('timeout'); }, timeoutInMs); promise.then(function (data) { clearTimeout(timeOut); resolve(data); }, function (rejection) { clearTimeout(timeOut); reject(rejection); }); }); } /** * Enum representing the possible states of a Promise * @enum {number} */ export var PromiseStatus; (function (PromiseStatus) { PromiseStatus[PromiseStatus["Pending"] = 0] = "Pending"; PromiseStatus[PromiseStatus["Resolved"] = 1] = "Resolved"; PromiseStatus[PromiseStatus["Rejected"] = 2] = "Rejected"; })(PromiseStatus || (PromiseStatus = {})); //# sourceMappingURL=promiseHelpers.js.map