evnty 5.3.3 → 5.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/utils.ts"],"sourcesContent":["import { Sequence } from './sequence.js';\nimport { AnyIterator, AnyIterable, MaybePromise } from './types.js';\n\n/**\n * @internal\n */\nexport function isThenable(value: unknown): value is PromiseLike<unknown> {\n return value !== null && typeof value === 'object' && typeof (value as PromiseLike<unknown>).then === 'function';\n}\n\n/**\n * @internal\n * A no-operation function. Useful as a default callback or placeholder.\n */\nexport const noop = () => {};\n\n/**\n * @internal\n * Returns the minimum value from an iterable, or a fallback if empty.\n */\nexport function min(values: Iterable<number>, fallback: number): number {\n let result = Infinity;\n for (const value of values) {\n if (value < result) result = value;\n }\n return result === Infinity ? fallback : result;\n}\n\n/**\n * @internal\n * Indicates which iterator method triggered a mapping operation.\n */\nexport enum MapIteratorType {\n /** The next() method was called */\n NEXT,\n /** The return() method was called */\n RETURN,\n /** The throw() method was called */\n THROW,\n}\n\n/**\n * @internal\n * A mapping function for transforming iterator results.\n * @template T - The input value type\n * @template U - The output value type\n * @template TReturn - The iterator return type\n */\nexport interface MapNext<T, U, TReturn> {\n (result: MaybePromise<IteratorResult<T, TReturn>>, type: MapIteratorType): MaybePromise<IteratorResult<U, TReturn>>;\n}\n\n/**\n * @internal\n * Wraps an iterator with a mapping function applied to each result.\n * @template U - The output value type\n * @template T - The input value type\n * @template TReturn - The iterator return type\n * @template TNext - The type passed to next()\n * @param iterator - The source iterator to wrap\n * @param map - The mapping function to apply to each result\n * @returns An async iterator with mapped results\n */\nexport const mapIterator = <U, T, TReturn, TNext>(iterator: AnyIterator<T, TReturn, TNext>, map: MapNext<T, U, TReturn>): AsyncIterator<U, TReturn, TNext> => {\n const subIterator: AsyncIterator<U, TReturn, TNext> = {\n next: async (...args: [] | [TNext]) => {\n const result = await iterator.next(...args);\n return map(result, MapIteratorType.NEXT);\n },\n };\n if (iterator.return) {\n subIterator.return = async (...args: [] | [TReturn]) => {\n const result = await iterator.return!(...args);\n return map(result, MapIteratorType.RETURN);\n };\n } else {\n subIterator.return = async (value: TReturn) => {\n return map({ done: true, value }, MapIteratorType.RETURN);\n };\n }\n if (iterator.throw) {\n subIterator.throw = async (...args: [] | [unknown]) => {\n const result = await iterator.throw!(...args);\n return map(result, MapIteratorType.THROW);\n };\n }\n\n return subIterator;\n};\n\n/**\n * Wraps an async iterable with abort signal support.\n * Each iteration creates a fresh iterator with scoped abort handling.\n * Listener is added at iteration start and removed on completion/abort/return.\n *\n * @template T - The yielded value type\n * @template TReturn - The return value type\n * @template TNext - The type passed to next()\n * @param iterable - The source async iterable to wrap\n * @param signal - AbortSignal to cancel iteration\n * @returns An async iterable with abort support\n *\n * @example\n * ```typescript\n * const controller = new AbortController();\n * const source = async function*() { yield 1; yield 2; yield 3; };\n *\n * for await (const value of abortableIterable(source(), controller.signal)) {\n * console.log(value);\n * if (value === 2) controller.abort();\n * }\n * ```\n */\nexport function abortableIterable<T, TReturn, TNext>(iterable: AsyncIterable<T, TReturn, TNext>, signal: AbortSignal): AsyncIterable<T, TReturn, TNext> {\n return {\n [Symbol.asyncIterator](): AsyncIterator<T, TReturn, TNext> {\n const iterator = iterable[Symbol.asyncIterator]();\n const { promise, resolve } = Promise.withResolvers<void>();\n const onAbort = () => resolve();\n let closed = false;\n\n const finish = (value?: TReturn): Promise<IteratorResult<T, TReturn>> => {\n if (closed) {\n return Promise.resolve({ done: true, value: value as TReturn });\n }\n closed = true;\n signal.removeEventListener('abort', onAbort);\n return iterator.return?.(value) ?? Promise.resolve({ done: true, value: value as TReturn });\n };\n\n if (signal.aborted) {\n onAbort();\n } else {\n signal.addEventListener('abort', onAbort);\n }\n\n const race = [promise, undefined] as unknown as [Promise<void>, Promise<IteratorResult<T, TReturn>>];\n\n return {\n async next(...args: [] | [TNext]): Promise<IteratorResult<T, TReturn>> {\n race[1] = iterator.next(...args);\n const result = await Promise.race(race);\n if (result === undefined) {\n void finish();\n return { done: true, value: undefined as TReturn };\n }\n if (result.done) {\n closed = true;\n signal.removeEventListener('abort', onAbort);\n }\n return result;\n },\n async return(value?: TReturn): Promise<IteratorResult<T, TReturn>> {\n return finish(value);\n },\n };\n },\n };\n}\n\n/**\n * Interface for creating iterable number sequences with various parameter combinations.\n * Supports infinite sequences, counted sequences, and sequences with custom start and step values.\n */\nexport interface Iterate {\n (): Iterable<number, void, unknown>;\n (count: number): Iterable<number, void, unknown>;\n (start: number, count: number): Iterable<number, void, unknown>;\n (start: number, count: number, step: number): Iterable<number, void, unknown>;\n}\n\n/**\n * Creates an iterable sequence of numbers with flexible parameters.\n * Can generate infinite sequences, finite sequences, or sequences with custom start and step values.\n *\n * @param args Variable arguments to configure the sequence:\n * - No args: Infinite sequence starting at 0 with step 1\n * - 1 arg (count): Sequence from 0 to count-1\n * - 2 args (start, count): Sequence starting at 'start' for 'count' iterations\n * - 3 args (start, count, step): Custom start, count, and step value\n * @returns An iterable that generates numbers according to the parameters\n *\n * @example\n * ```typescript\n * // Infinite sequence: 0, 1, 2, 3, ...\n * for (const n of iterate()) { }\n *\n * // Count only: 0, 1, 2, 3, 4\n * for (const n of iterate(5)) { }\n *\n * // Start and count: 10, 11, 12, 13, 14\n * for (const n of iterate(10, 5)) { }\n *\n * // Start, count, and step: 0, 2, 4, 6, 8\n * for (const n of iterate(0, 5, 2)) { }\n * ```\n */\nexport const iterate: Iterate = (startOrCount?: number, countWhenTwoArgs?: number, step: number = 1): Iterable<number, void, unknown> => {\n const hasStartArg = countWhenTwoArgs !== undefined;\n const start = hasStartArg ? startOrCount! : 0;\n const count = startOrCount === undefined ? Infinity : hasStartArg ? countWhenTwoArgs : startOrCount;\n\n return {\n [Symbol.iterator]() {\n let idx = 0;\n let current = start;\n return {\n next() {\n if (idx < count) {\n const value = current;\n current += step;\n idx++;\n return { value, done: false };\n }\n return { value: undefined, done: true };\n },\n return(value) {\n idx = count;\n return { value, done: true };\n },\n throw(error?: unknown) {\n idx = count;\n throw error;\n },\n } satisfies Iterator<number, void, unknown>;\n },\n };\n};\n\n/**\n * @internal\n * Creates a promise that resolves after a specified timeout. If an `AbortSignal` is provided and triggered,\n * the timeout is cleared, and the promise resolves to `false`.\n *\n * @param {number} timeout - The time in milliseconds to wait before resolving the promise.\n * @param {AbortSignal} [signal] - An optional `AbortSignal` that can abort the timeout.\n * @returns {Promise<boolean>} A promise that resolves to `true` if the timeout completed, or `false` if it was aborted.\n *\n * @example\n * ```typescript\n * const controller = new AbortController();\n * setTimeout(() => controller.abort(), 500);\n * const result = await setTimeoutAsync(1000, controller.signal);\n * console.log(result); // false\n * ```\n */\nexport const setTimeoutAsync = async (timeout: number, signal?: AbortSignal): Promise<boolean> => {\n if (signal?.aborted) {\n return false;\n }\n const { promise, resolve } = Promise.withResolvers<boolean>();\n const timerId = setTimeout(resolve, timeout, true);\n const onAbort = () => {\n clearTimeout(timerId);\n resolve(false);\n };\n signal?.addEventListener('abort', onAbort);\n\n return promise.finally(() => signal?.removeEventListener('abort', onAbort));\n};\n\n/**\n * Converts a synchronous iterable to an asynchronous iterable.\n * Wraps the sync iterator methods to return promises, enabling uniform async handling.\n *\n * @template T The type of values yielded by the iterator\n * @template TReturn The return type of the iterator\n * @template TNext The type of value that can be passed to next()\n * @param iterable A synchronous iterable to convert\n * @returns An async iterable that yields the same values as the input\n *\n * @example\n * ```typescript\n * const syncArray = [1, 2, 3, 4, 5];\n * const asyncIterable = toAsyncIterable(syncArray);\n *\n * for await (const value of asyncIterable) {\n * console.log(value); // 1, 2, 3, 4, 5\n * }\n * ```\n */\nexport const toAsyncIterable = <T, TReturn, TNext>(iterable: Iterable<T, TReturn, TNext>): AsyncIterable<T, TReturn, TNext> => {\n return {\n [Symbol.asyncIterator]() {\n const iterator = iterable[Symbol.iterator]();\n return {\n async next(...args: [TNext] | []) {\n return iterator.next(...args);\n },\n async return(maybeValue) {\n const value = await maybeValue;\n return iterator.return?.(value) ?? ({ value, done: true } as IteratorResult<T, TReturn>);\n },\n async throw(error) {\n if (iterator.throw) {\n return iterator.throw(error);\n }\n throw error;\n },\n } satisfies AsyncIterator<T, TReturn, TNext>;\n },\n };\n};\n\n/**\n * @internal\n * Pipes values from an async iterable through a generator transformation.\n * Applies a generator function to each value, yielding all resulting values.\n * Supports cancellation via AbortSignal for early termination.\n *\n * @template T The input value type\n * @template U The output value type\n * @param iterable The source async iterable\n * @param generatorFactory A factory that returns a generator function for transforming values\n * @param signal Optional AbortSignal to cancel the operation\n * @returns An async generator yielding transformed values\n *\n * @example\n * ```typescript\n * async function* source() {\n * yield 1; yield 2; yield 3;\n * }\n *\n * const doubled = pipe(source(), () => async function*(n) {\n * yield n * 2;\n * });\n *\n * for await (const value of doubled) {\n * console.log(value); // 2, 4, 6\n * }\n * ```\n */\nconst isAsyncIterable = <T, TReturn, TNext>(value: AnyIterable<T, TReturn, TNext>): value is AsyncIterable<T, TReturn, TNext> => {\n return typeof (value as AsyncIterable<T, TReturn, TNext>)[Symbol.asyncIterator] === 'function';\n};\n\n/**\n * @internal\n */\nexport async function* pipe<T, U>(\n iterable: AsyncIterable<T>,\n generatorFactory: () => (value: T) => AnyIterable<U, void, unknown>,\n signal?: AbortSignal,\n): AsyncGenerator<Awaited<U>, void, unknown> {\n const source = signal ? abortableIterable(iterable, signal) : iterable;\n const generator = generatorFactory();\n\n for await (const value of source) {\n const produced = generator(value);\n const subIterable = isAsyncIterable(produced) ? produced : toAsyncIterable(produced);\n const abortableSub = signal ? abortableIterable(subIterable, signal) : subIterable;\n\n for await (const subValue of abortableSub) {\n yield subValue;\n }\n }\n}\n\n/**\n * @internal\n * Merges multiple async iterables into a single stream.\n * Values are yielded as they become available from any source.\n * Completes when all sources complete; aborts all on error.\n * @template T - The value type yielded by all iterables\n * @param iterables - The async iterables to merge\n * @returns A merged async iterable\n */\nexport const mergeIterables = <T>(...iterables: AsyncIterable<T, void, unknown>[]): AsyncIterable<T, void, unknown> => {\n return {\n [Symbol.asyncIterator]() {\n if (iterables.length === 0) {\n return {\n next: async () => ({ value: undefined, done: true }),\n };\n }\n\n const exit = Symbol('mergeIterables.exit');\n const ctrl = new AbortController();\n const sequence = new Sequence<T>(ctrl.signal);\n let remaining = iterables.length;\n\n const pump = async (iterable: AsyncIterable<T, void, unknown>) => {\n try {\n for await (const value of abortableIterable(iterable, ctrl.signal)) {\n if (!sequence.emit(value)) {\n break;\n }\n }\n } catch (error) {\n ctrl.abort(error);\n } finally {\n remaining -= 1;\n if (remaining === 0 && !ctrl.signal.aborted) {\n ctrl.abort(exit);\n }\n }\n };\n\n for (const iterable of iterables) {\n void pump(iterable);\n }\n\n return {\n next: async () => {\n try {\n const value = await sequence.receive();\n return { value, done: false };\n } catch {\n if (ctrl.signal.aborted && ctrl.signal.reason === exit) {\n return { value: undefined, done: true };\n }\n throw ctrl.signal.reason;\n }\n },\n return: async () => {\n ctrl.abort(exit);\n return { value: undefined, done: true };\n },\n throw: async (error?: unknown) => {\n ctrl.abort(error);\n return { value: undefined, done: true };\n },\n };\n },\n };\n};\n"],"names":["MapIteratorType","abortableIterable","isThenable","iterate","mapIterator","mergeIterables","min","noop","pipe","setTimeoutAsync","toAsyncIterable","value","then","values","fallback","result","Infinity","iterator","map","subIterator","next","args","return","done","throw","iterable","signal","Symbol","asyncIterator","promise","resolve","Promise","withResolvers","onAbort","closed","finish","removeEventListener","aborted","addEventListener","race","undefined","startOrCount","countWhenTwoArgs","step","hasStartArg","start","count","idx","current","error","timeout","timerId","setTimeout","clearTimeout","finally","maybeValue","isAsyncIterable","generatorFactory","source","generator","produced","subIterable","abortableSub","subValue","iterables","length","exit","ctrl","AbortController","sequence","Sequence","remaining","pump","emit","abort","receive","reason"],"mappings":"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"}
1
+ {"version":3,"sources":["../src/utils.ts"],"sourcesContent":["import { Sequence } from './sequence.js';\nimport { ITERATOR_DONE } from './async.js';\nimport { AnyIterator, AnyIterable, MaybePromise } from './types.js';\n\n/**\n * @internal\n */\nexport function isThenable(value: unknown): value is PromiseLike<unknown> {\n return value !== null && typeof value === 'object' && typeof (value as PromiseLike<unknown>).then === 'function';\n}\n\n/**\n * @internal\n * A no-operation function. Useful as a default callback or placeholder.\n */\nexport const noop = () => {};\n\n/**\n * @internal\n * Returns the minimum value from an iterable, or a fallback if empty.\n */\nexport function min(values: Iterable<number>, fallback: number): number {\n let result = Infinity;\n for (const value of values) {\n if (value < result) result = value;\n }\n return result === Infinity ? fallback : result;\n}\n\n/**\n * @internal\n * Indicates which iterator method triggered a mapping operation.\n */\nexport enum MapIteratorType {\n /** The next() method was called */\n NEXT,\n /** The return() method was called */\n RETURN,\n /** The throw() method was called */\n THROW,\n}\n\n/**\n * @internal\n * A mapping function for transforming iterator results.\n * @template T - The input value type\n * @template U - The output value type\n * @template TReturn - The iterator return type\n */\nexport interface MapNext<T, U, TReturn> {\n (result: MaybePromise<IteratorResult<T, TReturn>>, type: MapIteratorType): MaybePromise<IteratorResult<U, TReturn>>;\n}\n\n/**\n * @internal\n * Wraps an iterator with a mapping function applied to each result.\n * @template U - The output value type\n * @template T - The input value type\n * @template TReturn - The iterator return type\n * @template TNext - The type passed to next()\n * @param iterator - The source iterator to wrap\n * @param map - The mapping function to apply to each result\n * @returns An async iterator with mapped results\n */\nexport const mapIterator = <U, T, TReturn, TNext>(iterator: AnyIterator<T, TReturn, TNext>, map: MapNext<T, U, TReturn>): AsyncIterator<U, TReturn, TNext> => {\n const subIterator: AsyncIterator<U, TReturn, TNext> = {\n next: async (...args: [] | [TNext]) => {\n const result = await iterator.next(...args);\n return map(result, MapIteratorType.NEXT);\n },\n };\n if (iterator.return) {\n subIterator.return = async (...args: [] | [TReturn]) => {\n const result = await iterator.return!(...args);\n return map(result, MapIteratorType.RETURN);\n };\n } else {\n subIterator.return = async (value: TReturn) => {\n return map({ done: true, value }, MapIteratorType.RETURN);\n };\n }\n if (iterator.throw) {\n subIterator.throw = async (...args: [] | [unknown]) => {\n const result = await iterator.throw!(...args);\n return map(result, MapIteratorType.THROW);\n };\n }\n\n return subIterator;\n};\n\n/**\n * Wraps an async iterable with abort signal support.\n * Each iteration creates a fresh iterator with scoped abort handling.\n * Listener is added at iteration start and removed on completion/abort/return.\n *\n * @template T - The yielded value type\n * @template TReturn - The return value type\n * @template TNext - The type passed to next()\n * @param iterable - The source async iterable to wrap\n * @param signal - AbortSignal to cancel iteration\n * @returns An async iterable with abort support\n *\n * @example\n * ```typescript\n * const controller = new AbortController();\n * const source = async function*() { yield 1; yield 2; yield 3; };\n *\n * for await (const value of abortableIterable(source(), controller.signal)) {\n * console.log(value);\n * if (value === 2) controller.abort();\n * }\n * ```\n */\nexport function abortableIterable<T, TReturn, TNext>(iterable: AsyncIterable<T, TReturn, TNext>, signal: AbortSignal): AsyncIterable<T, TReturn, TNext> {\n return {\n [Symbol.asyncIterator](): AsyncIterator<T, TReturn, TNext> {\n const iterator = iterable[Symbol.asyncIterator]();\n const { promise, resolve } = Promise.withResolvers<void>();\n const onAbort = () => resolve();\n let closed = false;\n\n const finish = (value?: TReturn): Promise<IteratorResult<T, TReturn>> => {\n if (closed) {\n return Promise.resolve({ done: true, value: value as TReturn });\n }\n closed = true;\n signal.removeEventListener('abort', onAbort);\n return iterator.return?.(value) ?? Promise.resolve({ done: true, value: value as TReturn });\n };\n\n if (signal.aborted) {\n onAbort();\n } else {\n signal.addEventListener('abort', onAbort);\n }\n\n const race = [promise, undefined] as unknown as [Promise<void>, Promise<IteratorResult<T, TReturn>>];\n\n return {\n next(...args: [] | [TNext]): Promise<IteratorResult<T, TReturn>> {\n race[1] = iterator.next(...args);\n return Promise.race(race).then((result) => {\n if (result === undefined) {\n void finish();\n return { done: true, value: undefined as TReturn } as IteratorResult<T, TReturn>;\n }\n if (result.done) {\n closed = true;\n signal.removeEventListener('abort', onAbort);\n }\n return result;\n });\n },\n return(value?: TReturn): Promise<IteratorResult<T, TReturn>> {\n return finish(value);\n },\n };\n },\n };\n}\n\n/**\n * Interface for creating iterable number sequences with various parameter combinations.\n * Supports infinite sequences, counted sequences, and sequences with custom start and step values.\n */\nexport interface Iterate {\n (): Iterable<number, void, unknown>;\n (count: number): Iterable<number, void, unknown>;\n (start: number, count: number): Iterable<number, void, unknown>;\n (start: number, count: number, step: number): Iterable<number, void, unknown>;\n}\n\n/**\n * Creates an iterable sequence of numbers with flexible parameters.\n * Can generate infinite sequences, finite sequences, or sequences with custom start and step values.\n *\n * @param args Variable arguments to configure the sequence:\n * - No args: Infinite sequence starting at 0 with step 1\n * - 1 arg (count): Sequence from 0 to count-1\n * - 2 args (start, count): Sequence starting at 'start' for 'count' iterations\n * - 3 args (start, count, step): Custom start, count, and step value\n * @returns An iterable that generates numbers according to the parameters\n *\n * @example\n * ```typescript\n * // Infinite sequence: 0, 1, 2, 3, ...\n * for (const n of iterate()) { }\n *\n * // Count only: 0, 1, 2, 3, 4\n * for (const n of iterate(5)) { }\n *\n * // Start and count: 10, 11, 12, 13, 14\n * for (const n of iterate(10, 5)) { }\n *\n * // Start, count, and step: 0, 2, 4, 6, 8\n * for (const n of iterate(0, 5, 2)) { }\n * ```\n */\nexport const iterate: Iterate = (startOrCount?: number, countWhenTwoArgs?: number, step: number = 1): Iterable<number, void, unknown> => {\n const hasStartArg = countWhenTwoArgs !== undefined;\n const start = hasStartArg ? startOrCount! : 0;\n const count = startOrCount === undefined ? Infinity : hasStartArg ? countWhenTwoArgs : startOrCount;\n\n return {\n [Symbol.iterator]() {\n let idx = 0;\n let current = start;\n return {\n next() {\n if (idx < count) {\n const value = current;\n current += step;\n idx++;\n return { value, done: false };\n }\n return ITERATOR_DONE;\n },\n return(value) {\n idx = count;\n return { value, done: true };\n },\n throw(error?: unknown) {\n idx = count;\n throw error;\n },\n } satisfies Iterator<number, void, unknown>;\n },\n };\n};\n\n/**\n * @internal\n * Creates a promise that resolves after a specified timeout. If an `AbortSignal` is provided and triggered,\n * the timeout is cleared, and the promise resolves to `false`.\n *\n * @param {number} timeout - The time in milliseconds to wait before resolving the promise.\n * @param {AbortSignal} [signal] - An optional `AbortSignal` that can abort the timeout.\n * @returns {Promise<boolean>} A promise that resolves to `true` if the timeout completed, or `false` if it was aborted.\n *\n * @example\n * ```typescript\n * const controller = new AbortController();\n * setTimeout(() => controller.abort(), 500);\n * const result = await setTimeoutAsync(1000, controller.signal);\n * console.log(result); // false\n * ```\n */\nexport const setTimeoutAsync = async (timeout: number, signal?: AbortSignal): Promise<boolean> => {\n if (signal?.aborted) {\n return false;\n }\n const { promise, resolve } = Promise.withResolvers<boolean>();\n const timerId = setTimeout(resolve, timeout, true);\n const onAbort = () => {\n clearTimeout(timerId);\n resolve(false);\n };\n signal?.addEventListener('abort', onAbort);\n\n return promise.finally(() => signal?.removeEventListener('abort', onAbort));\n};\n\n/**\n * Converts a synchronous iterable to an asynchronous iterable.\n * Wraps the sync iterator methods to return promises, enabling uniform async handling.\n *\n * @template T The type of values yielded by the iterator\n * @template TReturn The return type of the iterator\n * @template TNext The type of value that can be passed to next()\n * @param iterable A synchronous iterable to convert\n * @returns An async iterable that yields the same values as the input\n *\n * @example\n * ```typescript\n * const syncArray = [1, 2, 3, 4, 5];\n * const asyncIterable = toAsyncIterable(syncArray);\n *\n * for await (const value of asyncIterable) {\n * console.log(value); // 1, 2, 3, 4, 5\n * }\n * ```\n */\nexport const toAsyncIterable = <T, TReturn, TNext>(iterable: Iterable<T, TReturn, TNext>): AsyncIterable<T, TReturn, TNext> => {\n return {\n [Symbol.asyncIterator]() {\n const iterator = iterable[Symbol.iterator]();\n return {\n next(...args: [TNext] | []) {\n return Promise.resolve(iterator.next(...args));\n },\n return(maybeValue) {\n return Promise.resolve(maybeValue).then((value) => iterator.return?.(value) ?? ({ value, done: true } as IteratorResult<T, TReturn>));\n },\n throw(error) {\n if (iterator.throw) {\n return Promise.resolve(iterator.throw(error));\n }\n return Promise.reject(error);\n },\n } satisfies AsyncIterator<T, TReturn, TNext>;\n },\n };\n};\n\n/**\n * @internal\n * Pipes values from an async iterable through a generator transformation.\n * Applies a generator function to each value, yielding all resulting values.\n * Supports cancellation via AbortSignal for early termination.\n *\n * @template T The input value type\n * @template U The output value type\n * @param iterable The source async iterable\n * @param generatorFactory A factory that returns a generator function for transforming values\n * @param signal Optional AbortSignal to cancel the operation\n * @returns An async generator yielding transformed values\n *\n * @example\n * ```typescript\n * async function* source() {\n * yield 1; yield 2; yield 3;\n * }\n *\n * const doubled = pipe(source(), () => async function*(n) {\n * yield n * 2;\n * });\n *\n * for await (const value of doubled) {\n * console.log(value); // 2, 4, 6\n * }\n * ```\n */\nconst isAsyncIterable = <T, TReturn, TNext>(value: AnyIterable<T, TReturn, TNext>): value is AsyncIterable<T, TReturn, TNext> => {\n return typeof (value as AsyncIterable<T, TReturn, TNext>)[Symbol.asyncIterator] === 'function';\n};\n\n/**\n * @internal\n */\nexport async function* pipe<T, U>(\n iterable: AsyncIterable<T>,\n generatorFactory: () => (value: T) => AnyIterable<U, void, unknown>,\n signal?: AbortSignal,\n): AsyncGenerator<Awaited<U>, void, unknown> {\n const source = signal ? abortableIterable(iterable, signal) : iterable;\n const generator = generatorFactory();\n\n for await (const value of source) {\n const produced = generator(value);\n const subIterable = isAsyncIterable(produced) ? produced : toAsyncIterable(produced);\n const abortableSub = signal ? abortableIterable(subIterable, signal) : subIterable;\n\n for await (const subValue of abortableSub) {\n yield subValue;\n }\n }\n}\n\n/**\n * @internal\n * Merges multiple async iterables into a single stream.\n * Values are yielded as they become available from any source.\n * Completes when all sources complete; aborts all on error.\n * @template T - The value type yielded by all iterables\n * @param iterables - The async iterables to merge\n * @returns A merged async iterable\n */\nexport const mergeIterables = <T>(...iterables: AsyncIterable<T, void, unknown>[]): AsyncIterable<T, void, unknown> => {\n return {\n [Symbol.asyncIterator]() {\n if (iterables.length === 0) {\n return {\n next: () => Promise.resolve(ITERATOR_DONE),\n };\n }\n\n const exit = Symbol('mergeIterables.exit');\n const ctrl = new AbortController();\n const sequence = new Sequence<T>(ctrl.signal);\n let remaining = iterables.length;\n\n const pump = async (iterable: AsyncIterable<T, void, unknown>) => {\n try {\n for await (const value of abortableIterable(iterable, ctrl.signal)) {\n if (!sequence.emit(value)) {\n break;\n }\n }\n } catch (error) {\n ctrl.abort(error);\n } finally {\n remaining -= 1;\n if (remaining === 0 && !ctrl.signal.aborted) {\n ctrl.abort(exit);\n }\n }\n };\n\n for (const iterable of iterables) {\n void pump(iterable);\n }\n\n return {\n next: async () => {\n try {\n const value = await sequence.receive();\n return { value, done: false };\n } catch {\n if (ctrl.signal.aborted && ctrl.signal.reason === exit) {\n return ITERATOR_DONE;\n }\n throw ctrl.signal.reason;\n }\n },\n return: async () => {\n ctrl.abort(exit);\n return ITERATOR_DONE;\n },\n throw: async (error?: unknown) => {\n ctrl.abort(error);\n return ITERATOR_DONE;\n },\n };\n },\n };\n};\n"],"names":["MapIteratorType","abortableIterable","isThenable","iterate","mapIterator","mergeIterables","min","noop","pipe","setTimeoutAsync","toAsyncIterable","value","then","values","fallback","result","Infinity","iterator","map","subIterator","next","args","return","done","throw","iterable","signal","Symbol","asyncIterator","promise","resolve","Promise","withResolvers","onAbort","closed","finish","removeEventListener","aborted","addEventListener","race","undefined","startOrCount","countWhenTwoArgs","step","hasStartArg","start","count","idx","current","ITERATOR_DONE","error","timeout","timerId","setTimeout","clearTimeout","finally","maybeValue","reject","isAsyncIterable","generatorFactory","source","generator","produced","subIterable","abortableSub","subValue","iterables","length","exit","ctrl","AbortController","sequence","Sequence","remaining","pump","emit","abort","receive","reason"],"mappings":"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"}
package/build/utils.js CHANGED
@@ -1,4 +1,5 @@
1
1
  import { Sequence } from "./sequence.js";
2
+ import { ITERATOR_DONE } from "./async.js";
2
3
  export function isThenable(value) {
3
4
  return value !== null && typeof value === 'object' && typeof value.then === 'function';
4
5
  }
@@ -75,23 +76,24 @@ export function abortableIterable(iterable, signal) {
75
76
  undefined
76
77
  ];
77
78
  return {
78
- async next (...args) {
79
+ next (...args) {
79
80
  race[1] = iterator.next(...args);
80
- const result = await Promise.race(race);
81
- if (result === undefined) {
82
- void finish();
83
- return {
84
- done: true,
85
- value: undefined
86
- };
87
- }
88
- if (result.done) {
89
- closed = true;
90
- signal.removeEventListener('abort', onAbort);
91
- }
92
- return result;
81
+ return Promise.race(race).then((result)=>{
82
+ if (result === undefined) {
83
+ void finish();
84
+ return {
85
+ done: true,
86
+ value: undefined
87
+ };
88
+ }
89
+ if (result.done) {
90
+ closed = true;
91
+ signal.removeEventListener('abort', onAbort);
92
+ }
93
+ return result;
94
+ });
93
95
  },
94
- async return (value) {
96
+ return (value) {
95
97
  return finish(value);
96
98
  }
97
99
  };
@@ -117,10 +119,7 @@ export const iterate = (startOrCount, countWhenTwoArgs, step = 1)=>{
117
119
  done: false
118
120
  };
119
121
  }
120
- return {
121
- value: undefined,
122
- done: true
123
- };
122
+ return ITERATOR_DONE;
124
123
  },
125
124
  return (value) {
126
125
  idx = count;
@@ -155,21 +154,20 @@ export const toAsyncIterable = (iterable)=>{
155
154
  [Symbol.asyncIterator] () {
156
155
  const iterator = iterable[Symbol.iterator]();
157
156
  return {
158
- async next (...args) {
159
- return iterator.next(...args);
157
+ next (...args) {
158
+ return Promise.resolve(iterator.next(...args));
160
159
  },
161
- async return (maybeValue) {
162
- const value = await maybeValue;
163
- return iterator.return?.(value) ?? {
164
- value,
165
- done: true
166
- };
160
+ return (maybeValue) {
161
+ return Promise.resolve(maybeValue).then((value)=>iterator.return?.(value) ?? {
162
+ value,
163
+ done: true
164
+ });
167
165
  },
168
- async throw (error) {
166
+ throw (error) {
169
167
  if (iterator.throw) {
170
- return iterator.throw(error);
168
+ return Promise.resolve(iterator.throw(error));
171
169
  }
172
- throw error;
170
+ return Promise.reject(error);
173
171
  }
174
172
  };
175
173
  }
@@ -195,10 +193,7 @@ export const mergeIterables = (...iterables)=>{
195
193
  [Symbol.asyncIterator] () {
196
194
  if (iterables.length === 0) {
197
195
  return {
198
- next: async ()=>({
199
- value: undefined,
200
- done: true
201
- })
196
+ next: ()=>Promise.resolve(ITERATOR_DONE)
202
197
  };
203
198
  }
204
199
  const exit = Symbol('mergeIterables.exit');
@@ -234,27 +229,18 @@ export const mergeIterables = (...iterables)=>{
234
229
  };
235
230
  } catch {
236
231
  if (ctrl.signal.aborted && ctrl.signal.reason === exit) {
237
- return {
238
- value: undefined,
239
- done: true
240
- };
232
+ return ITERATOR_DONE;
241
233
  }
242
234
  throw ctrl.signal.reason;
243
235
  }
244
236
  },
245
237
  return: async ()=>{
246
238
  ctrl.abort(exit);
247
- return {
248
- value: undefined,
249
- done: true
250
- };
239
+ return ITERATOR_DONE;
251
240
  },
252
241
  throw: async (error)=>{
253
242
  ctrl.abort(error);
254
- return {
255
- value: undefined,
256
- done: true
257
- };
243
+ return ITERATOR_DONE;
258
244
  }
259
245
  };
260
246
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/utils.ts"],"sourcesContent":["import { Sequence } from './sequence.js';\nimport { AnyIterator, AnyIterable, MaybePromise } from './types.js';\n\n/**\n * @internal\n */\nexport function isThenable(value: unknown): value is PromiseLike<unknown> {\n return value !== null && typeof value === 'object' && typeof (value as PromiseLike<unknown>).then === 'function';\n}\n\n/**\n * @internal\n * A no-operation function. Useful as a default callback or placeholder.\n */\nexport const noop = () => {};\n\n/**\n * @internal\n * Returns the minimum value from an iterable, or a fallback if empty.\n */\nexport function min(values: Iterable<number>, fallback: number): number {\n let result = Infinity;\n for (const value of values) {\n if (value < result) result = value;\n }\n return result === Infinity ? fallback : result;\n}\n\n/**\n * @internal\n * Indicates which iterator method triggered a mapping operation.\n */\nexport enum MapIteratorType {\n /** The next() method was called */\n NEXT,\n /** The return() method was called */\n RETURN,\n /** The throw() method was called */\n THROW,\n}\n\n/**\n * @internal\n * A mapping function for transforming iterator results.\n * @template T - The input value type\n * @template U - The output value type\n * @template TReturn - The iterator return type\n */\nexport interface MapNext<T, U, TReturn> {\n (result: MaybePromise<IteratorResult<T, TReturn>>, type: MapIteratorType): MaybePromise<IteratorResult<U, TReturn>>;\n}\n\n/**\n * @internal\n * Wraps an iterator with a mapping function applied to each result.\n * @template U - The output value type\n * @template T - The input value type\n * @template TReturn - The iterator return type\n * @template TNext - The type passed to next()\n * @param iterator - The source iterator to wrap\n * @param map - The mapping function to apply to each result\n * @returns An async iterator with mapped results\n */\nexport const mapIterator = <U, T, TReturn, TNext>(iterator: AnyIterator<T, TReturn, TNext>, map: MapNext<T, U, TReturn>): AsyncIterator<U, TReturn, TNext> => {\n const subIterator: AsyncIterator<U, TReturn, TNext> = {\n next: async (...args: [] | [TNext]) => {\n const result = await iterator.next(...args);\n return map(result, MapIteratorType.NEXT);\n },\n };\n if (iterator.return) {\n subIterator.return = async (...args: [] | [TReturn]) => {\n const result = await iterator.return!(...args);\n return map(result, MapIteratorType.RETURN);\n };\n } else {\n subIterator.return = async (value: TReturn) => {\n return map({ done: true, value }, MapIteratorType.RETURN);\n };\n }\n if (iterator.throw) {\n subIterator.throw = async (...args: [] | [unknown]) => {\n const result = await iterator.throw!(...args);\n return map(result, MapIteratorType.THROW);\n };\n }\n\n return subIterator;\n};\n\n/**\n * Wraps an async iterable with abort signal support.\n * Each iteration creates a fresh iterator with scoped abort handling.\n * Listener is added at iteration start and removed on completion/abort/return.\n *\n * @template T - The yielded value type\n * @template TReturn - The return value type\n * @template TNext - The type passed to next()\n * @param iterable - The source async iterable to wrap\n * @param signal - AbortSignal to cancel iteration\n * @returns An async iterable with abort support\n *\n * @example\n * ```typescript\n * const controller = new AbortController();\n * const source = async function*() { yield 1; yield 2; yield 3; };\n *\n * for await (const value of abortableIterable(source(), controller.signal)) {\n * console.log(value);\n * if (value === 2) controller.abort();\n * }\n * ```\n */\nexport function abortableIterable<T, TReturn, TNext>(iterable: AsyncIterable<T, TReturn, TNext>, signal: AbortSignal): AsyncIterable<T, TReturn, TNext> {\n return {\n [Symbol.asyncIterator](): AsyncIterator<T, TReturn, TNext> {\n const iterator = iterable[Symbol.asyncIterator]();\n const { promise, resolve } = Promise.withResolvers<void>();\n const onAbort = () => resolve();\n let closed = false;\n\n const finish = (value?: TReturn): Promise<IteratorResult<T, TReturn>> => {\n if (closed) {\n return Promise.resolve({ done: true, value: value as TReturn });\n }\n closed = true;\n signal.removeEventListener('abort', onAbort);\n return iterator.return?.(value) ?? Promise.resolve({ done: true, value: value as TReturn });\n };\n\n if (signal.aborted) {\n onAbort();\n } else {\n signal.addEventListener('abort', onAbort);\n }\n\n const race = [promise, undefined] as unknown as [Promise<void>, Promise<IteratorResult<T, TReturn>>];\n\n return {\n async next(...args: [] | [TNext]): Promise<IteratorResult<T, TReturn>> {\n race[1] = iterator.next(...args);\n const result = await Promise.race(race);\n if (result === undefined) {\n void finish();\n return { done: true, value: undefined as TReturn };\n }\n if (result.done) {\n closed = true;\n signal.removeEventListener('abort', onAbort);\n }\n return result;\n },\n async return(value?: TReturn): Promise<IteratorResult<T, TReturn>> {\n return finish(value);\n },\n };\n },\n };\n}\n\n/**\n * Interface for creating iterable number sequences with various parameter combinations.\n * Supports infinite sequences, counted sequences, and sequences with custom start and step values.\n */\nexport interface Iterate {\n (): Iterable<number, void, unknown>;\n (count: number): Iterable<number, void, unknown>;\n (start: number, count: number): Iterable<number, void, unknown>;\n (start: number, count: number, step: number): Iterable<number, void, unknown>;\n}\n\n/**\n * Creates an iterable sequence of numbers with flexible parameters.\n * Can generate infinite sequences, finite sequences, or sequences with custom start and step values.\n *\n * @param args Variable arguments to configure the sequence:\n * - No args: Infinite sequence starting at 0 with step 1\n * - 1 arg (count): Sequence from 0 to count-1\n * - 2 args (start, count): Sequence starting at 'start' for 'count' iterations\n * - 3 args (start, count, step): Custom start, count, and step value\n * @returns An iterable that generates numbers according to the parameters\n *\n * @example\n * ```typescript\n * // Infinite sequence: 0, 1, 2, 3, ...\n * for (const n of iterate()) { }\n *\n * // Count only: 0, 1, 2, 3, 4\n * for (const n of iterate(5)) { }\n *\n * // Start and count: 10, 11, 12, 13, 14\n * for (const n of iterate(10, 5)) { }\n *\n * // Start, count, and step: 0, 2, 4, 6, 8\n * for (const n of iterate(0, 5, 2)) { }\n * ```\n */\nexport const iterate: Iterate = (startOrCount?: number, countWhenTwoArgs?: number, step: number = 1): Iterable<number, void, unknown> => {\n const hasStartArg = countWhenTwoArgs !== undefined;\n const start = hasStartArg ? startOrCount! : 0;\n const count = startOrCount === undefined ? Infinity : hasStartArg ? countWhenTwoArgs : startOrCount;\n\n return {\n [Symbol.iterator]() {\n let idx = 0;\n let current = start;\n return {\n next() {\n if (idx < count) {\n const value = current;\n current += step;\n idx++;\n return { value, done: false };\n }\n return { value: undefined, done: true };\n },\n return(value) {\n idx = count;\n return { value, done: true };\n },\n throw(error?: unknown) {\n idx = count;\n throw error;\n },\n } satisfies Iterator<number, void, unknown>;\n },\n };\n};\n\n/**\n * @internal\n * Creates a promise that resolves after a specified timeout. If an `AbortSignal` is provided and triggered,\n * the timeout is cleared, and the promise resolves to `false`.\n *\n * @param {number} timeout - The time in milliseconds to wait before resolving the promise.\n * @param {AbortSignal} [signal] - An optional `AbortSignal` that can abort the timeout.\n * @returns {Promise<boolean>} A promise that resolves to `true` if the timeout completed, or `false` if it was aborted.\n *\n * @example\n * ```typescript\n * const controller = new AbortController();\n * setTimeout(() => controller.abort(), 500);\n * const result = await setTimeoutAsync(1000, controller.signal);\n * console.log(result); // false\n * ```\n */\nexport const setTimeoutAsync = async (timeout: number, signal?: AbortSignal): Promise<boolean> => {\n if (signal?.aborted) {\n return false;\n }\n const { promise, resolve } = Promise.withResolvers<boolean>();\n const timerId = setTimeout(resolve, timeout, true);\n const onAbort = () => {\n clearTimeout(timerId);\n resolve(false);\n };\n signal?.addEventListener('abort', onAbort);\n\n return promise.finally(() => signal?.removeEventListener('abort', onAbort));\n};\n\n/**\n * Converts a synchronous iterable to an asynchronous iterable.\n * Wraps the sync iterator methods to return promises, enabling uniform async handling.\n *\n * @template T The type of values yielded by the iterator\n * @template TReturn The return type of the iterator\n * @template TNext The type of value that can be passed to next()\n * @param iterable A synchronous iterable to convert\n * @returns An async iterable that yields the same values as the input\n *\n * @example\n * ```typescript\n * const syncArray = [1, 2, 3, 4, 5];\n * const asyncIterable = toAsyncIterable(syncArray);\n *\n * for await (const value of asyncIterable) {\n * console.log(value); // 1, 2, 3, 4, 5\n * }\n * ```\n */\nexport const toAsyncIterable = <T, TReturn, TNext>(iterable: Iterable<T, TReturn, TNext>): AsyncIterable<T, TReturn, TNext> => {\n return {\n [Symbol.asyncIterator]() {\n const iterator = iterable[Symbol.iterator]();\n return {\n async next(...args: [TNext] | []) {\n return iterator.next(...args);\n },\n async return(maybeValue) {\n const value = await maybeValue;\n return iterator.return?.(value) ?? ({ value, done: true } as IteratorResult<T, TReturn>);\n },\n async throw(error) {\n if (iterator.throw) {\n return iterator.throw(error);\n }\n throw error;\n },\n } satisfies AsyncIterator<T, TReturn, TNext>;\n },\n };\n};\n\n/**\n * @internal\n * Pipes values from an async iterable through a generator transformation.\n * Applies a generator function to each value, yielding all resulting values.\n * Supports cancellation via AbortSignal for early termination.\n *\n * @template T The input value type\n * @template U The output value type\n * @param iterable The source async iterable\n * @param generatorFactory A factory that returns a generator function for transforming values\n * @param signal Optional AbortSignal to cancel the operation\n * @returns An async generator yielding transformed values\n *\n * @example\n * ```typescript\n * async function* source() {\n * yield 1; yield 2; yield 3;\n * }\n *\n * const doubled = pipe(source(), () => async function*(n) {\n * yield n * 2;\n * });\n *\n * for await (const value of doubled) {\n * console.log(value); // 2, 4, 6\n * }\n * ```\n */\nconst isAsyncIterable = <T, TReturn, TNext>(value: AnyIterable<T, TReturn, TNext>): value is AsyncIterable<T, TReturn, TNext> => {\n return typeof (value as AsyncIterable<T, TReturn, TNext>)[Symbol.asyncIterator] === 'function';\n};\n\n/**\n * @internal\n */\nexport async function* pipe<T, U>(\n iterable: AsyncIterable<T>,\n generatorFactory: () => (value: T) => AnyIterable<U, void, unknown>,\n signal?: AbortSignal,\n): AsyncGenerator<Awaited<U>, void, unknown> {\n const source = signal ? abortableIterable(iterable, signal) : iterable;\n const generator = generatorFactory();\n\n for await (const value of source) {\n const produced = generator(value);\n const subIterable = isAsyncIterable(produced) ? produced : toAsyncIterable(produced);\n const abortableSub = signal ? abortableIterable(subIterable, signal) : subIterable;\n\n for await (const subValue of abortableSub) {\n yield subValue;\n }\n }\n}\n\n/**\n * @internal\n * Merges multiple async iterables into a single stream.\n * Values are yielded as they become available from any source.\n * Completes when all sources complete; aborts all on error.\n * @template T - The value type yielded by all iterables\n * @param iterables - The async iterables to merge\n * @returns A merged async iterable\n */\nexport const mergeIterables = <T>(...iterables: AsyncIterable<T, void, unknown>[]): AsyncIterable<T, void, unknown> => {\n return {\n [Symbol.asyncIterator]() {\n if (iterables.length === 0) {\n return {\n next: async () => ({ value: undefined, done: true }),\n };\n }\n\n const exit = Symbol('mergeIterables.exit');\n const ctrl = new AbortController();\n const sequence = new Sequence<T>(ctrl.signal);\n let remaining = iterables.length;\n\n const pump = async (iterable: AsyncIterable<T, void, unknown>) => {\n try {\n for await (const value of abortableIterable(iterable, ctrl.signal)) {\n if (!sequence.emit(value)) {\n break;\n }\n }\n } catch (error) {\n ctrl.abort(error);\n } finally {\n remaining -= 1;\n if (remaining === 0 && !ctrl.signal.aborted) {\n ctrl.abort(exit);\n }\n }\n };\n\n for (const iterable of iterables) {\n void pump(iterable);\n }\n\n return {\n next: async () => {\n try {\n const value = await sequence.receive();\n return { value, done: false };\n } catch {\n if (ctrl.signal.aborted && ctrl.signal.reason === exit) {\n return { value: undefined, done: true };\n }\n throw ctrl.signal.reason;\n }\n },\n return: async () => {\n ctrl.abort(exit);\n return { value: undefined, done: true };\n },\n throw: async (error?: unknown) => {\n ctrl.abort(error);\n return { value: undefined, done: true };\n },\n };\n },\n };\n};\n"],"names":["Sequence","isThenable","value","then","noop","min","values","fallback","result","Infinity","MapIteratorType","mapIterator","iterator","map","subIterator","next","args","return","done","throw","abortableIterable","iterable","signal","Symbol","asyncIterator","promise","resolve","Promise","withResolvers","onAbort","closed","finish","removeEventListener","aborted","addEventListener","race","undefined","iterate","startOrCount","countWhenTwoArgs","step","hasStartArg","start","count","idx","current","error","setTimeoutAsync","timeout","timerId","setTimeout","clearTimeout","finally","toAsyncIterable","maybeValue","isAsyncIterable","pipe","generatorFactory","source","generator","produced","subIterable","abortableSub","subValue","mergeIterables","iterables","length","exit","ctrl","AbortController","sequence","remaining","pump","emit","abort","receive","reason"],"mappings":"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"}
1
+ {"version":3,"sources":["../src/utils.ts"],"sourcesContent":["import { Sequence } from './sequence.js';\nimport { ITERATOR_DONE } from './async.js';\nimport { AnyIterator, AnyIterable, MaybePromise } from './types.js';\n\n/**\n * @internal\n */\nexport function isThenable(value: unknown): value is PromiseLike<unknown> {\n return value !== null && typeof value === 'object' && typeof (value as PromiseLike<unknown>).then === 'function';\n}\n\n/**\n * @internal\n * A no-operation function. Useful as a default callback or placeholder.\n */\nexport const noop = () => {};\n\n/**\n * @internal\n * Returns the minimum value from an iterable, or a fallback if empty.\n */\nexport function min(values: Iterable<number>, fallback: number): number {\n let result = Infinity;\n for (const value of values) {\n if (value < result) result = value;\n }\n return result === Infinity ? fallback : result;\n}\n\n/**\n * @internal\n * Indicates which iterator method triggered a mapping operation.\n */\nexport enum MapIteratorType {\n /** The next() method was called */\n NEXT,\n /** The return() method was called */\n RETURN,\n /** The throw() method was called */\n THROW,\n}\n\n/**\n * @internal\n * A mapping function for transforming iterator results.\n * @template T - The input value type\n * @template U - The output value type\n * @template TReturn - The iterator return type\n */\nexport interface MapNext<T, U, TReturn> {\n (result: MaybePromise<IteratorResult<T, TReturn>>, type: MapIteratorType): MaybePromise<IteratorResult<U, TReturn>>;\n}\n\n/**\n * @internal\n * Wraps an iterator with a mapping function applied to each result.\n * @template U - The output value type\n * @template T - The input value type\n * @template TReturn - The iterator return type\n * @template TNext - The type passed to next()\n * @param iterator - The source iterator to wrap\n * @param map - The mapping function to apply to each result\n * @returns An async iterator with mapped results\n */\nexport const mapIterator = <U, T, TReturn, TNext>(iterator: AnyIterator<T, TReturn, TNext>, map: MapNext<T, U, TReturn>): AsyncIterator<U, TReturn, TNext> => {\n const subIterator: AsyncIterator<U, TReturn, TNext> = {\n next: async (...args: [] | [TNext]) => {\n const result = await iterator.next(...args);\n return map(result, MapIteratorType.NEXT);\n },\n };\n if (iterator.return) {\n subIterator.return = async (...args: [] | [TReturn]) => {\n const result = await iterator.return!(...args);\n return map(result, MapIteratorType.RETURN);\n };\n } else {\n subIterator.return = async (value: TReturn) => {\n return map({ done: true, value }, MapIteratorType.RETURN);\n };\n }\n if (iterator.throw) {\n subIterator.throw = async (...args: [] | [unknown]) => {\n const result = await iterator.throw!(...args);\n return map(result, MapIteratorType.THROW);\n };\n }\n\n return subIterator;\n};\n\n/**\n * Wraps an async iterable with abort signal support.\n * Each iteration creates a fresh iterator with scoped abort handling.\n * Listener is added at iteration start and removed on completion/abort/return.\n *\n * @template T - The yielded value type\n * @template TReturn - The return value type\n * @template TNext - The type passed to next()\n * @param iterable - The source async iterable to wrap\n * @param signal - AbortSignal to cancel iteration\n * @returns An async iterable with abort support\n *\n * @example\n * ```typescript\n * const controller = new AbortController();\n * const source = async function*() { yield 1; yield 2; yield 3; };\n *\n * for await (const value of abortableIterable(source(), controller.signal)) {\n * console.log(value);\n * if (value === 2) controller.abort();\n * }\n * ```\n */\nexport function abortableIterable<T, TReturn, TNext>(iterable: AsyncIterable<T, TReturn, TNext>, signal: AbortSignal): AsyncIterable<T, TReturn, TNext> {\n return {\n [Symbol.asyncIterator](): AsyncIterator<T, TReturn, TNext> {\n const iterator = iterable[Symbol.asyncIterator]();\n const { promise, resolve } = Promise.withResolvers<void>();\n const onAbort = () => resolve();\n let closed = false;\n\n const finish = (value?: TReturn): Promise<IteratorResult<T, TReturn>> => {\n if (closed) {\n return Promise.resolve({ done: true, value: value as TReturn });\n }\n closed = true;\n signal.removeEventListener('abort', onAbort);\n return iterator.return?.(value) ?? Promise.resolve({ done: true, value: value as TReturn });\n };\n\n if (signal.aborted) {\n onAbort();\n } else {\n signal.addEventListener('abort', onAbort);\n }\n\n const race = [promise, undefined] as unknown as [Promise<void>, Promise<IteratorResult<T, TReturn>>];\n\n return {\n next(...args: [] | [TNext]): Promise<IteratorResult<T, TReturn>> {\n race[1] = iterator.next(...args);\n return Promise.race(race).then((result) => {\n if (result === undefined) {\n void finish();\n return { done: true, value: undefined as TReturn } as IteratorResult<T, TReturn>;\n }\n if (result.done) {\n closed = true;\n signal.removeEventListener('abort', onAbort);\n }\n return result;\n });\n },\n return(value?: TReturn): Promise<IteratorResult<T, TReturn>> {\n return finish(value);\n },\n };\n },\n };\n}\n\n/**\n * Interface for creating iterable number sequences with various parameter combinations.\n * Supports infinite sequences, counted sequences, and sequences with custom start and step values.\n */\nexport interface Iterate {\n (): Iterable<number, void, unknown>;\n (count: number): Iterable<number, void, unknown>;\n (start: number, count: number): Iterable<number, void, unknown>;\n (start: number, count: number, step: number): Iterable<number, void, unknown>;\n}\n\n/**\n * Creates an iterable sequence of numbers with flexible parameters.\n * Can generate infinite sequences, finite sequences, or sequences with custom start and step values.\n *\n * @param args Variable arguments to configure the sequence:\n * - No args: Infinite sequence starting at 0 with step 1\n * - 1 arg (count): Sequence from 0 to count-1\n * - 2 args (start, count): Sequence starting at 'start' for 'count' iterations\n * - 3 args (start, count, step): Custom start, count, and step value\n * @returns An iterable that generates numbers according to the parameters\n *\n * @example\n * ```typescript\n * // Infinite sequence: 0, 1, 2, 3, ...\n * for (const n of iterate()) { }\n *\n * // Count only: 0, 1, 2, 3, 4\n * for (const n of iterate(5)) { }\n *\n * // Start and count: 10, 11, 12, 13, 14\n * for (const n of iterate(10, 5)) { }\n *\n * // Start, count, and step: 0, 2, 4, 6, 8\n * for (const n of iterate(0, 5, 2)) { }\n * ```\n */\nexport const iterate: Iterate = (startOrCount?: number, countWhenTwoArgs?: number, step: number = 1): Iterable<number, void, unknown> => {\n const hasStartArg = countWhenTwoArgs !== undefined;\n const start = hasStartArg ? startOrCount! : 0;\n const count = startOrCount === undefined ? Infinity : hasStartArg ? countWhenTwoArgs : startOrCount;\n\n return {\n [Symbol.iterator]() {\n let idx = 0;\n let current = start;\n return {\n next() {\n if (idx < count) {\n const value = current;\n current += step;\n idx++;\n return { value, done: false };\n }\n return ITERATOR_DONE;\n },\n return(value) {\n idx = count;\n return { value, done: true };\n },\n throw(error?: unknown) {\n idx = count;\n throw error;\n },\n } satisfies Iterator<number, void, unknown>;\n },\n };\n};\n\n/**\n * @internal\n * Creates a promise that resolves after a specified timeout. If an `AbortSignal` is provided and triggered,\n * the timeout is cleared, and the promise resolves to `false`.\n *\n * @param {number} timeout - The time in milliseconds to wait before resolving the promise.\n * @param {AbortSignal} [signal] - An optional `AbortSignal` that can abort the timeout.\n * @returns {Promise<boolean>} A promise that resolves to `true` if the timeout completed, or `false` if it was aborted.\n *\n * @example\n * ```typescript\n * const controller = new AbortController();\n * setTimeout(() => controller.abort(), 500);\n * const result = await setTimeoutAsync(1000, controller.signal);\n * console.log(result); // false\n * ```\n */\nexport const setTimeoutAsync = async (timeout: number, signal?: AbortSignal): Promise<boolean> => {\n if (signal?.aborted) {\n return false;\n }\n const { promise, resolve } = Promise.withResolvers<boolean>();\n const timerId = setTimeout(resolve, timeout, true);\n const onAbort = () => {\n clearTimeout(timerId);\n resolve(false);\n };\n signal?.addEventListener('abort', onAbort);\n\n return promise.finally(() => signal?.removeEventListener('abort', onAbort));\n};\n\n/**\n * Converts a synchronous iterable to an asynchronous iterable.\n * Wraps the sync iterator methods to return promises, enabling uniform async handling.\n *\n * @template T The type of values yielded by the iterator\n * @template TReturn The return type of the iterator\n * @template TNext The type of value that can be passed to next()\n * @param iterable A synchronous iterable to convert\n * @returns An async iterable that yields the same values as the input\n *\n * @example\n * ```typescript\n * const syncArray = [1, 2, 3, 4, 5];\n * const asyncIterable = toAsyncIterable(syncArray);\n *\n * for await (const value of asyncIterable) {\n * console.log(value); // 1, 2, 3, 4, 5\n * }\n * ```\n */\nexport const toAsyncIterable = <T, TReturn, TNext>(iterable: Iterable<T, TReturn, TNext>): AsyncIterable<T, TReturn, TNext> => {\n return {\n [Symbol.asyncIterator]() {\n const iterator = iterable[Symbol.iterator]();\n return {\n next(...args: [TNext] | []) {\n return Promise.resolve(iterator.next(...args));\n },\n return(maybeValue) {\n return Promise.resolve(maybeValue).then((value) => iterator.return?.(value) ?? ({ value, done: true } as IteratorResult<T, TReturn>));\n },\n throw(error) {\n if (iterator.throw) {\n return Promise.resolve(iterator.throw(error));\n }\n return Promise.reject(error);\n },\n } satisfies AsyncIterator<T, TReturn, TNext>;\n },\n };\n};\n\n/**\n * @internal\n * Pipes values from an async iterable through a generator transformation.\n * Applies a generator function to each value, yielding all resulting values.\n * Supports cancellation via AbortSignal for early termination.\n *\n * @template T The input value type\n * @template U The output value type\n * @param iterable The source async iterable\n * @param generatorFactory A factory that returns a generator function for transforming values\n * @param signal Optional AbortSignal to cancel the operation\n * @returns An async generator yielding transformed values\n *\n * @example\n * ```typescript\n * async function* source() {\n * yield 1; yield 2; yield 3;\n * }\n *\n * const doubled = pipe(source(), () => async function*(n) {\n * yield n * 2;\n * });\n *\n * for await (const value of doubled) {\n * console.log(value); // 2, 4, 6\n * }\n * ```\n */\nconst isAsyncIterable = <T, TReturn, TNext>(value: AnyIterable<T, TReturn, TNext>): value is AsyncIterable<T, TReturn, TNext> => {\n return typeof (value as AsyncIterable<T, TReturn, TNext>)[Symbol.asyncIterator] === 'function';\n};\n\n/**\n * @internal\n */\nexport async function* pipe<T, U>(\n iterable: AsyncIterable<T>,\n generatorFactory: () => (value: T) => AnyIterable<U, void, unknown>,\n signal?: AbortSignal,\n): AsyncGenerator<Awaited<U>, void, unknown> {\n const source = signal ? abortableIterable(iterable, signal) : iterable;\n const generator = generatorFactory();\n\n for await (const value of source) {\n const produced = generator(value);\n const subIterable = isAsyncIterable(produced) ? produced : toAsyncIterable(produced);\n const abortableSub = signal ? abortableIterable(subIterable, signal) : subIterable;\n\n for await (const subValue of abortableSub) {\n yield subValue;\n }\n }\n}\n\n/**\n * @internal\n * Merges multiple async iterables into a single stream.\n * Values are yielded as they become available from any source.\n * Completes when all sources complete; aborts all on error.\n * @template T - The value type yielded by all iterables\n * @param iterables - The async iterables to merge\n * @returns A merged async iterable\n */\nexport const mergeIterables = <T>(...iterables: AsyncIterable<T, void, unknown>[]): AsyncIterable<T, void, unknown> => {\n return {\n [Symbol.asyncIterator]() {\n if (iterables.length === 0) {\n return {\n next: () => Promise.resolve(ITERATOR_DONE),\n };\n }\n\n const exit = Symbol('mergeIterables.exit');\n const ctrl = new AbortController();\n const sequence = new Sequence<T>(ctrl.signal);\n let remaining = iterables.length;\n\n const pump = async (iterable: AsyncIterable<T, void, unknown>) => {\n try {\n for await (const value of abortableIterable(iterable, ctrl.signal)) {\n if (!sequence.emit(value)) {\n break;\n }\n }\n } catch (error) {\n ctrl.abort(error);\n } finally {\n remaining -= 1;\n if (remaining === 0 && !ctrl.signal.aborted) {\n ctrl.abort(exit);\n }\n }\n };\n\n for (const iterable of iterables) {\n void pump(iterable);\n }\n\n return {\n next: async () => {\n try {\n const value = await sequence.receive();\n return { value, done: false };\n } catch {\n if (ctrl.signal.aborted && ctrl.signal.reason === exit) {\n return ITERATOR_DONE;\n }\n throw ctrl.signal.reason;\n }\n },\n return: async () => {\n ctrl.abort(exit);\n return ITERATOR_DONE;\n },\n throw: async (error?: unknown) => {\n ctrl.abort(error);\n return ITERATOR_DONE;\n },\n };\n },\n };\n};\n"],"names":["Sequence","ITERATOR_DONE","isThenable","value","then","noop","min","values","fallback","result","Infinity","MapIteratorType","mapIterator","iterator","map","subIterator","next","args","return","done","throw","abortableIterable","iterable","signal","Symbol","asyncIterator","promise","resolve","Promise","withResolvers","onAbort","closed","finish","removeEventListener","aborted","addEventListener","race","undefined","iterate","startOrCount","countWhenTwoArgs","step","hasStartArg","start","count","idx","current","error","setTimeoutAsync","timeout","timerId","setTimeout","clearTimeout","finally","toAsyncIterable","maybeValue","reject","isAsyncIterable","pipe","generatorFactory","source","generator","produced","subIterable","abortableSub","subValue","mergeIterables","iterables","length","exit","ctrl","AbortController","sequence","remaining","pump","emit","abort","receive","reason"],"mappings":"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"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "evnty",
3
3
  "description": "Async-first, reactive event handling library for complex event flows in browser and Node.js",
4
- "version": "5.3.3",
4
+ "version": "5.4.1",
5
5
  "type": "module",
6
6
  "types": "build/index.d.ts",
7
7
  "main": "build/index.cjs",
@@ -51,27 +51,26 @@
51
51
  "devDependencies": {
52
52
  "@eslint/js": "^10.0.1",
53
53
  "@fast-check/vitest": "^0.4.0",
54
- "@stryker-mutator/core": "^9.6.0",
55
- "@stryker-mutator/typescript-checker": "^9.6.0",
56
- "@stryker-mutator/vitest-runner": "^9.6.0",
57
- "@types/node": "^25.5.2",
58
- "@typescript-eslint/eslint-plugin": "^8.58.1",
59
- "@typescript-eslint/parser": "^8.58.1",
60
- "@typescript-eslint/typescript-estree": "^8.58.1",
54
+ "@stryker-mutator/core": "^9.6.1",
55
+ "@stryker-mutator/typescript-checker": "^9.6.1",
56
+ "@stryker-mutator/vitest-runner": "^9.6.1",
57
+ "@types/node": "^25.6.0",
58
+ "@typescript-eslint/eslint-plugin": "^8.58.2",
59
+ "@typescript-eslint/parser": "^8.58.2",
60
+ "@typescript-eslint/typescript-estree": "^8.58.2",
61
61
  "@vitest/coverage-v8": "^4.1.4",
62
62
  "@vuepress/bundler-vite": "2.0.0-rc.28",
63
63
  "@vuepress/theme-default": "2.0.0-rc.128",
64
64
  "eslint": "^10.2.0",
65
65
  "eslint-config-prettier": "^10.1.8",
66
66
  "eslint-plugin-prettier": "^5.5.5",
67
- "evnty-release": "npm:evnty@^5.3.2",
68
67
  "inop": "^0.9.0",
69
68
  "overtake": "2.1.1",
70
- "prettier": "^3.8.1",
69
+ "prettier": "^3.8.2",
71
70
  "recast": "^0.23.11",
72
71
  "sass-embedded": "^1.99.0",
73
72
  "typescript": "^6.0.2",
74
- "typescript-eslint": "^8.58.1",
73
+ "typescript-eslint": "^8.58.2",
75
74
  "vitest": "^4.1.4",
76
75
  "vue": "^3.5.32",
77
76
  "vuepress": "2.0.0-rc.28"
@@ -86,6 +85,8 @@
86
85
  "docs:dev": "vuepress dev docs",
87
86
  "docs:gen": "node ./scripts/docgen.ts src/*.ts",
88
87
  "docs:update-package": "pnpm dlx vp-update",
89
- "bench": "overtake src/__bench__/event.ts --progress"
88
+ "bench": "overtake src/__bench__/event.ts --pin-cores --progress -w 1",
89
+ "bench:test": "pnpm bench --compare-baseline .bench-baseline.json",
90
+ "bench:save": "pnpm bench --save-baseline .bench-baseline.json"
90
91
  }
91
92
  }
package/src/async.ts CHANGED
@@ -38,6 +38,16 @@ export class Disposer {
38
38
  }
39
39
  }
40
40
 
41
+ /**
42
+ * @internal
43
+ */
44
+ export const ITERATOR_DONE: IteratorResult<never, void> = Object.freeze({ value: undefined, done: true });
45
+
46
+ /**
47
+ * @internal
48
+ */
49
+ export const ITERATOR_DONE_PROMISE: Promise<IteratorResult<never, void>> = Promise.resolve(ITERATOR_DONE);
50
+
41
51
  /**
42
52
  * @internal
43
53
  */
@@ -84,19 +94,17 @@ export abstract class Async<T, R> implements Emitter<T, R>, Promiseable<T>, Prom
84
94
  return this.receive().then(onfulfilled, onrejected);
85
95
  }
86
96
 
87
- async next(): Promise<IteratorResult<T, void>> {
88
- try {
89
- const value = await this.receive();
90
- return { value, done: false };
91
- } catch {
92
- return { value: undefined, done: true };
93
- }
97
+ next(): Promise<IteratorResult<T, void>> {
98
+ return this.receive().then(
99
+ (value) => ({ value, done: false }),
100
+ () => ITERATOR_DONE,
101
+ );
94
102
  }
95
103
 
96
- async return(): Promise<IteratorResult<T, void>> {
104
+ return(): Promise<IteratorResult<T, void>> {
97
105
  // Stryker disable next-line OptionalChaining: all subclasses define dispose()
98
106
  this.dispose?.();
99
- return { value: undefined, done: true };
107
+ return ITERATOR_DONE_PROMISE;
100
108
  }
101
109
 
102
110
  [Symbol.asyncIterator](): AsyncIterator<T, void, void> {
package/src/broadcast.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { RingBuffer } from './ring-buffer.js';
2
2
  import { Signal } from './signal.js';
3
- import { Disposer } from './async.js';
3
+ import { Disposer, ITERATOR_DONE, ITERATOR_DONE_PROMISE } from './async.js';
4
4
  import { min } from './utils.js';
5
5
  import { Action, Fn, Emitter, MaybePromise, Promiseable } from './types.js';
6
6
 
@@ -63,13 +63,13 @@ export class BroadcastIterator<T> implements AsyncIterator<T, void, void> {
63
63
  await this.#signal.receive();
64
64
  }
65
65
  } catch {
66
- return { value: undefined, done: true };
66
+ return ITERATOR_DONE;
67
67
  }
68
68
  }
69
69
 
70
- async return(): Promise<IteratorResult<T, void>> {
70
+ return(): Promise<IteratorResult<T, void>> {
71
71
  this.#broadcast.leave(this.#handle);
72
- return { value: undefined, done: true };
72
+ return ITERATOR_DONE_PROMISE;
73
73
  }
74
74
  }
75
75
 
@@ -302,7 +302,7 @@ export class Broadcast<T> implements Emitter<T, boolean>, Promiseable<T>, Promis
302
302
  const cursor = this.#cursors.get(id);
303
303
  if (cursor === undefined) throw new Error('Invalid handle');
304
304
  if (cursor >= this.#buffer.right) {
305
- return { value: undefined, done: true };
305
+ return ITERATOR_DONE;
306
306
  }
307
307
 
308
308
  const value = this.#buffer.peekAt(cursor)!;
package/src/event.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { Callback, Listener, FilterFunction, Predicate, Mapper, Reducer, Action, Fn, Emitter, MaybePromise, Promiseable } from './types.js';
2
- import { Disposer } from './async.js';
2
+ import { Disposer, ITERATOR_DONE, ITERATOR_DONE_PROMISE } from './async.js';
3
3
  import { Signal } from './signal.js';
4
4
  import { ListenerRegistry } from './listener-registry.js';
5
5
  import { DispatchResult } from './dispatch-result.js';
@@ -16,17 +16,15 @@ export class EventIterator<T> implements AsyncIterator<T, void, void> {
16
16
  this.#signal = signal;
17
17
  }
18
18
 
19
- async next(): Promise<IteratorResult<T, void>> {
20
- try {
21
- const value = await this.#signal.receive();
22
- return { value, done: false };
23
- } catch {
24
- return { value: undefined, done: true };
25
- }
19
+ next(): Promise<IteratorResult<T, void>> {
20
+ return this.#signal.receive().then(
21
+ (value): IteratorResult<T, void> => ({ value, done: false }),
22
+ (): IteratorResult<T, void> => ITERATOR_DONE,
23
+ );
26
24
  }
27
25
 
28
- async return(): Promise<IteratorResult<T, void>> {
29
- return { value: undefined, done: true };
26
+ return(): Promise<IteratorResult<T, void>> {
27
+ return ITERATOR_DONE_PROMISE;
30
28
  }
31
29
  }
32
30
 
package/src/iterator.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  import { mergeIterables, toAsyncIterable, pipe, isThenable } from './utils.js';
2
+ import { ITERATOR_DONE } from './async.js';
2
3
  import { AnyIterable } from './types.js';
3
4
 
4
5
  const enum OpKind {
@@ -344,30 +345,30 @@ function createSimpleIterable(source: AsyncIterable<unknown, unknown, unknown>,
344
345
  if (checkTakeExhausted(takeStates)) {
345
346
  done = true;
346
347
  await iterator.return?.();
347
- return { value: undefined, done: true };
348
+ return ITERATOR_DONE;
348
349
  }
349
350
 
350
351
  const sourceResult = await iterator.next();
351
352
  if (sourceResult.done) {
352
353
  done = true;
353
- return { value: undefined, done: true };
354
+ return ITERATOR_DONE;
354
355
  }
355
356
 
356
357
  const result = await processOpsSimple(sourceResult.value, ops, opStates);
357
358
  if (result.done) {
358
359
  done = true;
359
360
  await iterator.return?.();
360
- return { value: undefined, done: true };
361
+ return ITERATOR_DONE;
361
362
  }
362
363
  if (result.shouldYield) return { value: result.value, done: false };
363
364
  }
364
- return { value: undefined, done: true };
365
+ return ITERATOR_DONE;
365
366
  },
366
367
 
367
368
  async return(returnValue?: unknown): Promise<IteratorResult<unknown, void>> {
368
369
  done = true;
369
370
  await iterator.return?.(returnValue);
370
- return { value: undefined, done: true };
371
+ return ITERATOR_DONE;
371
372
  },
372
373
 
373
374
  async throw(error?: unknown): Promise<IteratorResult<unknown, void>> {
@@ -408,7 +409,7 @@ function createExpandingIterable(source: AsyncIterable<unknown, unknown, unknown
408
409
  done = true;
409
410
  await closeInnerIterators();
410
411
  await iterator.return?.();
411
- return { value: undefined, done: true };
412
+ return ITERATOR_DONE;
412
413
  }
413
414
  if (result.expandIterator) {
414
415
  innerStack.push({ type: 'expand', iterator: result.expandIterator, opIndex: result.expandOpIndex });
@@ -455,13 +456,13 @@ function createExpandingIterable(source: AsyncIterable<unknown, unknown, unknown
455
456
  if (checkTakeExhausted(takeStates)) {
456
457
  done = true;
457
458
  await iterator.return?.();
458
- return { value: undefined, done: true };
459
+ return ITERATOR_DONE;
459
460
  }
460
461
 
461
462
  const sourceResult = await iterator.next();
462
463
  if (sourceResult.done) {
463
464
  done = true;
464
- return { value: undefined, done: true };
465
+ return ITERATOR_DONE;
465
466
  }
466
467
 
467
468
  const result = await processOps(sourceResult.value, ops, opStates, 0);
@@ -469,14 +470,14 @@ function createExpandingIterable(source: AsyncIterable<unknown, unknown, unknown
469
470
  if (handled) return handled;
470
471
  }
471
472
 
472
- return { value: undefined, done: true };
473
+ return ITERATOR_DONE;
473
474
  },
474
475
 
475
476
  async return(returnValue?: unknown): Promise<IteratorResult<unknown, void>> {
476
477
  done = true;
477
478
  await closeInnerIterators();
478
479
  await iterator.return?.(returnValue);
479
- return { value: undefined, done: true };
480
+ return ITERATOR_DONE;
480
481
  },
481
482
 
482
483
  async throw(error?: unknown): Promise<IteratorResult<unknown, void>> {
package/src/sequence.ts CHANGED
@@ -122,10 +122,9 @@ export class Sequence<T> extends Async<T, boolean> {
122
122
  * sequence.emit('new item'); // Safe to add, queue has space
123
123
  * ```
124
124
  */
125
- async reserve(capacity: number): Promise<void> {
126
- while (this.#queue.length > capacity) {
127
- await this.#sendSignal;
128
- }
125
+ reserve(capacity: number): Promise<void> {
126
+ if (this.#queue.length <= capacity) return Promise.resolve();
127
+ return this.#sendSignal.receive().then(() => this.reserve(capacity));
129
128
  }
130
129
 
131
130
  /**
@@ -165,12 +164,12 @@ export class Sequence<T> extends Async<T, boolean> {
165
164
  * const value = await valuePromise; // 42
166
165
  * ```
167
166
  */
168
- async receive(): Promise<T> {
169
- while (!this.#queue.length) {
170
- await this.#nextSignal;
167
+ receive(): Promise<T> {
168
+ if (this.#queue.length) {
169
+ this.#sendSignal.emit();
170
+ return Promise.resolve(this.#queue.shift()!);
171
171
  }
172
- this.#sendSignal.emit();
173
- return this.#queue.shift()!;
172
+ return this.#nextSignal.receive().then(() => this.receive());
174
173
  }
175
174
 
176
175
  /**