UNPKG

contexify

Version:

A TypeScript library providing a powerful dependency injection container with context-based IoC capabilities, inspired by LoopBack's Context system.

292 lines 8.04 kB
var __defProp = Object.defineProperty; var __name = (target, value) => __defProp(target, "name", { value, configurable: true }); class TimeoutError extends Error { static { __name(this, "TimeoutError"); } constructor(message) { super(message); this.name = "TimeoutError"; } } const normalizeEmitter = /* @__PURE__ */ __name((emitter) => { const addListener = emitter.addEventListener || emitter.on || emitter.addListener; const removeListener = emitter.removeEventListener || emitter.off || emitter.removeListener; if (!addListener || !removeListener) { throw new TypeError("Emitter is not compatible"); } return { addListener: addListener.bind(emitter), removeListener: removeListener.bind(emitter) }; }, "normalizeEmitter"); function pEventMultiple(emitter, event, options) { let cancel; const returnValue = new Promise((resolve, reject) => { options = { rejectionEvents: [ "error" ], multiArgs: false, resolveImmediately: false, ...options }; if (!(options.count >= 0 && (options.count === Number.POSITIVE_INFINITY || Number.isInteger(options.count)))) { throw new TypeError("The `count` option should be at least 0 or more"); } options.signal?.throwIfAborted(); const events = Array.isArray(event) ? event : [ event ]; const items = []; const { addListener, removeListener } = normalizeEmitter(emitter); const onItem = /* @__PURE__ */ __name((...arguments_) => { const value = options.multiArgs ? arguments_ : arguments_[0]; if (options.filter && !options.filter(value)) { return; } items.push(value); if (options.count === items.length) { cancel(); resolve(items); } }, "onItem"); const rejectHandler = /* @__PURE__ */ __name((error) => { cancel(); reject(error); }, "rejectHandler"); cancel = /* @__PURE__ */ __name(() => { for (const event2 of events) { removeListener(event2, onItem); } for (const rejectionEvent of options.rejectionEvents || []) { removeListener(rejectionEvent, rejectHandler); } }, "cancel"); for (const event2 of events) { addListener(event2, onItem); } for (const rejectionEvent of options.rejectionEvents || []) { addListener(rejectionEvent, rejectHandler); } if (options.signal) { options.signal.addEventListener("abort", () => { rejectHandler(options.signal.reason); }, { once: true }); } if (options.resolveImmediately) { resolve(items); } }); returnValue.cancel = cancel; if (typeof options.timeout === "number") { const timeoutPromise = new Promise((_, reject) => { const timer = setTimeout(() => { returnValue.cancel(); reject(new TimeoutError(`Promise timed out after ${options.timeout} milliseconds`)); }, options.timeout); returnValue.then(() => clearTimeout(timer), () => clearTimeout(timer)); }); const combinedPromise = Promise.race([ returnValue, timeoutPromise ]); combinedPromise.cancel = cancel; return combinedPromise; } return returnValue; } __name(pEventMultiple, "pEventMultiple"); function pEvent(emitter, event, options) { if (typeof options === "function") { options = { filter: options }; } const multipleOptions = { ...options, count: 1, resolveImmediately: false }; const arrayPromise = pEventMultiple(emitter, event, multipleOptions); const promise = arrayPromise.then((array) => array[0]); promise.cancel = arrayPromise.cancel; return promise; } __name(pEvent, "pEvent"); function pEventIterator(emitter, event, options) { if (typeof options === "function") { options = { filter: options }; } const events = Array.isArray(event) ? event : [ event ]; options = { rejectionEvents: [ "error" ], resolutionEvents: [], limit: Number.POSITIVE_INFINITY, multiArgs: false, ...options }; const { limit } = options; const isValidLimit = limit >= 0 && (limit === Number.POSITIVE_INFINITY || Number.isInteger(limit)); if (!isValidLimit) { throw new TypeError("The `limit` option should be a non-negative integer or Infinity"); } options.signal?.throwIfAborted(); if (limit === 0) { return { [Symbol.asyncIterator]() { return this; }, async next() { return { done: true, value: void 0 }; } }; } const { addListener, removeListener } = normalizeEmitter(emitter); let isDone = false; let error; let hasPendingError = false; const nextQueue = []; const valueQueue = []; let eventCount = 0; let isLimitReached = false; const valueHandler = /* @__PURE__ */ __name((...arguments_) => { eventCount++; isLimitReached = eventCount === limit; const value = options.multiArgs ? arguments_ : arguments_[0]; if (nextQueue.length > 0) { const { resolve } = nextQueue.shift(); resolve({ done: false, value }); if (isLimitReached) { cancel(); } return; } valueQueue.push(value); if (isLimitReached) { cancel(); } }, "valueHandler"); const cancel = /* @__PURE__ */ __name(() => { isDone = true; for (const event2 of events) { removeListener(event2, valueHandler); } for (const rejectionEvent of options.rejectionEvents) { removeListener(rejectionEvent, rejectHandler); } for (const resolutionEvent of options.resolutionEvents) { removeListener(resolutionEvent, resolveHandler); } while (nextQueue.length > 0) { const { resolve } = nextQueue.shift(); resolve({ done: true, value: void 0 }); } }, "cancel"); const rejectHandler = /* @__PURE__ */ __name((...arguments_) => { error = options.multiArgs ? arguments_ : arguments_[0]; if (nextQueue.length > 0) { const { reject } = nextQueue.shift(); reject(error); } else { hasPendingError = true; } cancel(); }, "rejectHandler"); const resolveHandler = /* @__PURE__ */ __name((...arguments_) => { const value = options.multiArgs ? arguments_ : arguments_[0]; if (options.filter && !options.filter(value)) { cancel(); return; } if (nextQueue.length > 0) { const { resolve } = nextQueue.shift(); resolve({ done: true, value }); } else { valueQueue.push(value); } cancel(); }, "resolveHandler"); for (const event2 of events) { addListener(event2, valueHandler); } for (const rejectionEvent of options.rejectionEvents) { addListener(rejectionEvent, rejectHandler); } for (const resolutionEvent of options.resolutionEvents) { addListener(resolutionEvent, resolveHandler); } if (options.signal) { options.signal.addEventListener("abort", () => { rejectHandler(options.signal.reason); }, { once: true }); } return { [Symbol.asyncIterator]() { return this; }, async next() { if (valueQueue.length > 0) { const value = valueQueue.shift(); return { done: isDone && valueQueue.length === 0 && !isLimitReached, value }; } if (hasPendingError) { hasPendingError = false; throw error; } if (isDone) { return { done: true, value: void 0 }; } return new Promise((resolve, reject) => { nextQueue.push({ resolve, reject }); }); }, // eslint-disable-next-line @typescript-eslint/no-explicit-any async return(value) { cancel(); return { done: isDone, value }; } }; } __name(pEventIterator, "pEventIterator"); export { TimeoutError, pEvent, pEventIterator, pEventMultiple }; //# sourceMappingURL=p-event.js.map