diff --git a/src/ops/flat.ts b/src/ops/flat.ts index c1bfb695..8dbead0a 100644 --- a/src/ops/flat.ts +++ b/src/ops/flat.ts @@ -5,23 +5,23 @@ import {createOperation} from '../utils'; * @internal */ export type Flatten = -// N < 0 + // N < 0 `${N}` extends `-${string}` ? T : // N = 0 N extends 0 - ? T - : // N = 1 - N extends 1 - ? T extends UnknownIterable - ? E - : T - : // N > 20 or N is unknown - Decrement[number] extends Decrement[N] - ? unknown - : T extends UnknownIterable - ? Flatten - : Flatten; + ? T + : // N = 1 + N extends 1 + ? T extends UnknownIterable + ? E + : T + : // N > 20 or N is unknown + Decrement[number] extends Decrement[N] + ? unknown + : T extends UnknownIterable + ? Flatten + : Flatten; /** * Expands / flattens sub-iterables up to the specified `depth` (default is 1), with optional `skip` logic. @@ -65,7 +65,8 @@ export type Flatten = * @category Sync+Async */ export function flat( - depth?: N, skip?: (value: any, level: number) => boolean + depth?: N, + skip?: (value: any, level: number) => boolean ): Operation>; export function flat(...args: unknown[]) { @@ -75,10 +76,10 @@ export function flat(...args: unknown[]) { function flatSync( iterable: Iterable>, depth = 1, - skip = (value: any, level: number) => false + skip?: (value: any, level: number) => false ): Iterable> { return { - [Symbol.iterator](): Iterator> { + [$S](): Iterator> { const d: Iterator>[] = new Array(depth + 1); d[0] = iterable[$S](); let level = 0; @@ -97,7 +98,10 @@ function flatSync( return v; // maximum depth reached } const i = (v.value as Iterable)?.[$S]?.(); - if (!i || (typeof skip === 'function' && skip(v.value, level))) { + if ( + !i || + (typeof skip === 'function' && skip(v.value, level)) + ) { return v; // non-iterable value or to be skipped } d[++level] = i; // save next iterable @@ -111,12 +115,12 @@ function flatSync( function flatAsync( iterable: AsyncIterable | AsyncIterable>, depth = 1, - skip = (value: any, level: number) => false + skip?: (value: any, level: number) => false ): AsyncIterable | AsyncIterable> { type AnyValue = T | Iterator | AsyncIterator; return { - [Symbol.asyncIterator](): AsyncIterator { - const d: { i: any; sync: boolean }[] = new Array(depth + 1); + [$A](): AsyncIterator { + const d: {i: any; sync: boolean}[] = new Array(depth + 1); d[0] = {i: iterable[$A](), sync: false}; let level = 0; return { @@ -134,7 +138,11 @@ function flatAsync( let sync = true; if (!i) { i = v.value?.[$A]?.(); // then try with async - if (!i || (typeof skip === 'function' && skip(v.value, level))) { + if ( + !i || + (typeof skip === 'function' && + skip(v.value, level)) + ) { return Promise.resolve(v); // non-iterable value } sync = false; @@ -144,7 +152,9 @@ function flatAsync( } return v.then( ( - a: IteratorResult | AsyncIterable> + a: IteratorResult< + T | Iterable | AsyncIterable + > ) => { if (a.done) { if (!level) { @@ -158,11 +168,15 @@ function flatAsync( } let i: AnyValue = (a.value as AsyncIterable)?.[ $A - ]?.(); // first, try with async + ]?.(); // first, try with async let sync = false; if (!i) { i = (a.value as Iterable)?.[$S]?.(); // then try with sync - if (!i || (typeof skip === 'function' && skip(a.value, level))) { + if ( + !i || + (typeof skip === 'function' && + skip(a.value, level)) + ) { return a; // non-iterable value } sync = true; diff --git a/test/ops/flat/sync.ts b/test/ops/flat/sync.ts index 8e7a3ab7..2bd57eaf 100644 --- a/test/ops/flat/sync.ts +++ b/test/ops/flat/sync.ts @@ -8,21 +8,20 @@ export default () => { }); it('must support skip logic', () => { let level; - const output = pipe(['one', 'two'], flat(1, (v, l) => { - level = l; - return v === 'two'; - })); + const output = pipe( + ['one', 'two'], + flat(1, (v, l) => { + level = l; + return v === 'two'; + }) + ); expect([...output]).to.eql(['o', 'n', 'e', 'two']); expect(level).to.eql(0); }); it('must flatten arrays', () => { const output = pipe( - [ - [1, 2], - [3, 4], - 'word!' - ], - flat(1, v => typeof v === 'string') + [[1, 2], [3, 4], 'word!'], + flat(1, (v) => typeof v === 'string') ); expect([...output]).to.eql([1, 2, 3, 4, 'word!']); });