import { isntChar } from 'extra-utils' import { Awaitable } from 'justypes' import { isIterable } from '@src/is-iterable.js' export async function* flattenByAsync( iterable: Iterable | AsyncIterable , predicate: (element: unknown, level: number) => Awaitable ): AsyncIterableIterator { const level = 1 for await (const element of iterable) { if (isFiniteIterable(element) && await predicate(element, level)) { yield* flatten(element, predicate, level + 1) } else { yield element as T } } } async function* flatten( iterable: Iterable , predicate: (element: unknown, level: number) => Awaitable , level: number ): AsyncIterableIterator { for (const element of iterable) { if (isFiniteIterable(element) && await predicate(element, level)) { yield* flatten(element, predicate, level + 1) } else { yield element as T } } } function isFiniteIterable(val: unknown): val is Iterable { return isIterable(val) && isntChar(val) }