import type { Curried } from '../../compositions/curry.js'; import { type Purried, purry } from '../../compositions/purry.js'; import { _isIterable } from '../../controls/_guards.js'; import type { Series, SyncSeries } from '../../controls/types.js'; function* _syncFlatMap( input: SyncSeries, mapper: (value: I) => SyncSeries, ): Generator { for (const value of input) { for (const output of mapper(value)) { yield output; } } } async function* _asyncFlatMap( input: Series, mapper: (value: Awaited) => Series, ): AsyncGenerator> { const awaited = await input; if (_isIterable(awaited)) { for (const value of awaited) { const results = await mapper(await value); if (_isIterable(results)) { for (const output of results) { yield output; } } else { for await (const output of results) { yield output; } } } } else { for await (const value of awaited) { const results = await mapper(value); if (_isIterable(results)) { for (const output of results) { yield output; } } else { for await (const output of results) { yield output; } } } } } export function flatMapSync( ...args: Parameters> ): ReturnType>; export function flatMapSync( ...args: Parameters>> ): ReturnType>>; export function flatMapSync( ...args: Parameters>> ): ReturnType>> { return purry(_syncFlatMap)(...args); } export function flatMapAsync( ...args: Parameters> ): ReturnType>; export function flatMapAsync( ...args: Parameters>> ): ReturnType>>; export function flatMapAsync( ...args: Parameters>> ): ReturnType>> { return purry(_asyncFlatMap)(...args); } /** Identical to a map followed by flatten. */ export namespace flatMap { export const sync = flatMapSync; export const async = flatMapAsync; }