@akala/core
Version:
129 lines • 5.16 kB
JavaScript
/**
* 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