export type PromiseArray = | Array | Array> | PromiseLike> | PromiseLike>> | Array> | PromiseLike>>; export type AsyncFlatIterable = IterableIterator< Awaited>[number] >; export type AsyncFlatMappable = | AsyncFlatIterable | PromiseLike> | PromiseArray; export type AwaitedArrayMember = Awaited; export type AsyncMemberNP = T extends | Array | Array> | Array> ? AwaitedArrayMember : T; export type AsyncMember = AsyncMemberNP>; export type Transform = (_a: A) => B | PromiseLike | PromiseArray; export async function asyncFlatMap( self: AsyncFlatMappable, transform: Transform ): Promise { const awaited = await self; const items = awaited?.[Symbol.iterator] ? await Promise.all(awaited) : ([awaited] as [A]); const transformed: Array> = []; for (const item of items) { if (Array.isArray(item)) { for (const subitem of item.map(transform)) { transformed.push(await subitem); } } else { transformed.push(await transform(item)); } } const final = new Array(); for (const item of transformed) { const awaited = await item; if (Array.isArray(awaited)) { for (const subitem of awaited) { final.push(await subitem); } } else { final.push(awaited); } } return final; } export default asyncFlatMap; Object.defineProperties(asyncFlatMap, { default: { get: () => asyncFlatMap }, asyncFlatMap: { get: () => asyncFlatMap }, }); if (!Object.prototype.hasOwnProperty.call(Array.prototype, 'asyncFlatMap')) { Object.defineProperty(Array.prototype, 'asyncFlatMap', { configurable: true, enumerable: false, value: function asyncFlatMapThis( this: PromiseArray, transform: Transform ) { return asyncFlatMap(this, transform); }, }); } if (!Object.prototype.hasOwnProperty.call(Promise.prototype, 'asyncFlatMap')) { Object.defineProperty(Promise.prototype, 'asyncFlatMap', { configurable: true, enumerable: false, value: function asyncFlatMapThis( this: PromiseArray, transform: Transform ) { return asyncFlatMap(this, transform); }, }); }