import type { Curried } from '../compositions/curry.js'; import { type Purried, purry } from '../compositions/purry.js'; import { _isIterable } from './_guards.js'; import type { Chunked, Series, SyncSeries } from './types.js'; function* _syncChunk(input: SyncSeries, size: L): Generator> { let accumulator: T[] = []; for (const value of input) { accumulator.push(value); if (accumulator.length >= size) { // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion -- Chunked cannot be safely typed yield accumulator as Chunked; accumulator = []; } } // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion -- Chunked cannot be safely typed if (accumulator.length > 0) yield accumulator as Chunked; } async function* _asyncChunk( input: Series, size: L, ): AsyncGenerator, L>> { let accumulator: T[] = []; const awaited = await input; if (_isIterable(awaited)) { for (const value of awaited) { accumulator.push(await value); if (accumulator.length >= size) { // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion -- Chunked cannot be safely typed yield accumulator as Chunked, L>; accumulator = []; } } } else { for await (const value of awaited) { accumulator.push(value); if (accumulator.length >= size) { // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion -- Chunked cannot be safely typed yield accumulator as Chunked, L>; accumulator = []; } } } // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion -- Chunked cannot be safely typed if (accumulator.length > 0) yield accumulator as Chunked, L>; } export function chunkSync( ...args: Parameters> ): ReturnType>; export function chunkSync( ...args: Parameters>> ): ReturnType>>; export function chunkSync( ...args: Parameters>> ): ReturnType>> { return purry(_syncChunk)(...args); } export function chunkAsync( ...args: Parameters> ): ReturnType>; export function chunkAsync( ...args: Parameters>> ): ReturnType>>; export function chunkAsync( ...args: Parameters>> ): ReturnType>> { return purry(_asyncChunk)(...args); } /** Chunks a series into a series of chunks. Each chunk has a length equal to `size`, except the last chunk. */ export namespace chunk { export const sync = chunkSync; export const async = chunkAsync; }