UNPKG

@akala/core

Version:
129 lines 5.16 kB
/** * Async iteration over array-like and object structures * @module eachAsync */ import { isArrayLike } from './each.js'; /** * Represents an error that aggregates multiple errors from asynchronous iterations. * @class * @extends {Error} * @property {Error[]} errors - The array of errors that occurred during iteration. */ export class AggregateErrors extends Error { errors; constructor(errors) { super('One or more errors occurred. Please see errors field for more details'); this.errors = errors; } } /** * Asynchronously iterates over elements of an array-like structure. * @param {T[] | ArrayLike<T>} array - Array-like structure to iterate over * @param {(element: T, i: number) => Promise<void>} body - Async callback executed for each element * @param {boolean} waitForPrevious - Whether to wait for previous iteration to complete before next * @returns {Promise<void>} Resolves when all iterations complete */ export async function array(array, body, waitForPrevious) { if (typeof waitForPrevious == 'undefined') waitForPrevious = true; if (waitForPrevious) for (let index = 0; index < array.length; index++) { const element = array[index]; await body(element, index); } else if (Array.isArray(array)) return Promise.all(array.map(body)).then(() => { }); else return Promise.all(Array.prototype.map.call(array, body)).then(() => { }); } /** * Asynchronously iterates over key-value pairs of an object. * @param {T} o - Object to iterate over * @param {(element: T[keyof T], i: keyof T) => Promise<void>} body - Async callback for each key-value pair * @param {boolean} waitForPrevious - Whether to wait for previous iteration to complete * @returns {Promise<void>} Resolves when all iterations complete */ export function object(o, body, waitForPrevious) { if (typeof waitForPrevious == 'undefined') waitForPrevious = true; return array(Object.keys(o), (key, i) => body(o[key], key), waitForPrevious); } // eslint-disable-next-line @typescript-eslint/no-explicit-any export function each(it, body, waitForPrevious) { if (typeof waitForPrevious === 'undefined') waitForPrevious = true; if (Array.isArray(it) || isArrayLike(it)) return array(it, body, waitForPrevious); return object(it, body, waitForPrevious); } /** * Asynchronously maps elements of an array-like structure to new values. * @param {T[] | ArrayLike<T>} it - Array-like structure to process * @param {(element: T, i: number) => Promise<U>} body - Async transformation function * @param {boolean} waitForPrevious - Whether to wait for previous iteration * @returns {Promise<U[]>} Promise resolving to transformed elements */ export async function mapArray(it, body, waitForPrevious) { const result = []; await array(it, async function (el, i) { result.push(await body(el, i)); }, waitForPrevious); return result; } // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types export async function mapObject(o, body, asArray, waitForPrevious) { const result = {}; const resultArray = []; await object(o, async function (el, i) { if (asArray) resultArray.push(await body(el, i)); else result[i] = await body(el, i); }, waitForPrevious); if (asArray) return resultArray; return result; } // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types, @typescript-eslint/no-explicit-any export function map(it, body, asArray, waitForPrevious) { if (isArrayLike(it)) return mapArray(it, body, asArray); return mapObject(it, body, asArray, waitForPrevious); } /** * Asynchronously filters elements of an array-like structure. * @param {T[] | ArrayLike<T>} it - Array-like structure to filter * @param {(element: T, i: number) => Promise<boolean>} body - Async predicate function * @param {boolean} waitForPrevious - Whether to wait for previous iteration * @returns {Promise<T[]>} Filtered elements */ export async function grepArray(it, body, waitForPrevious) { const result = []; await array(it, async function (el, i) { if (await body(el, i)) result.push(el); }, waitForPrevious); return result; } // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types export async function grepObject(o, body, asArray, waitForPrevious) { const result = {}; const resultArray = []; await object(o, async function (el, i) { if (await body(el, i)) if (asArray) resultArray.push(el); else result[i] = el; }, waitForPrevious); if (asArray) return resultArray; return result; } // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types, @typescript-eslint/no-explicit-any export function grep(it, body, asArray, waitForPrevious) { if (isArrayLike(it)) return grepArray(it, body, asArray); return grepObject(it, body, asArray, waitForPrevious); } //# sourceMappingURL=eachAsync.js.map