{"version":3,"file":"flat.cjs","names":["lazyDataLastImpl","lazyIdentityEvaluator"],"sources":["../src/flat.ts"],"sourcesContent":["import type { IsNumericLiteral } from \"type-fest\";\nimport { lazyDataLastImpl } from \"./internal/lazyDataLastImpl\";\nimport type { IterableContainer } from \"./internal/types/IterableContainer\";\nimport type { LazyEvaluator } from \"./internal/types/LazyEvaluator\";\nimport type { LazyResult } from \"./internal/types/LazyResult\";\nimport { lazyIdentityEvaluator } from \"./internal/utilityEvaluators\";\n\ntype FlatArray<\n  T,\n  Depth extends number,\n  Iteration extends readonly unknown[] = [],\n> = Depth extends Iteration[\"length\"]\n  ? // Stopping condition for the recursion when the array is a tuple.\n    T\n  : T extends readonly []\n    ? // Trivial result when the array is empty.\n      []\n    : T extends readonly [infer Item, ...infer Rest]\n      ? // Tuples could be special-cased by \"iterating\" over each item\n        // separately so that we maintain more information from the input type,\n        // instead of putting all values in a union.\n        [\n          ...(Item extends IterableContainer\n            ? // If the item itself is an array we continue going deeper\n              FlatArray<Item, Depth, [...Iteration, unknown]>\n            : // But if it isn't we add it to the output tuple\n              [Item]),\n          // And we merge this with the result from the rest of the tuple.\n          ...FlatArray<Rest, Depth, Iteration>,\n        ]\n      : // For simple arrays we compute the item type, and wrap it with an\n        // array.\n        FlatSimpleArrayItems<T, Depth, Iteration>[];\n\n// This type is based on the built-in type for `Array.prototype.flat` from the\n// ES2019 Array typescript library, but we improved it to handle any depth\n// (avoiding the fixed `20` in the built-in type).\n// @see https://github.com/microsoft/TypeScript/blob/main/src/lib/es2019.array.d.ts#L1-L5\ntype FlatSimpleArrayItems<\n  T,\n  Depth extends number,\n  Iteration extends readonly unknown[] = [],\n  IsDone extends boolean = false,\n> = {\n  done: T;\n  recur: T extends readonly (infer InnerArr)[]\n    ? FlatSimpleArrayItems<\n        InnerArr,\n        Depth,\n        [...Iteration, unknown],\n        // This trick allows us to continue 1 iteration more than the depth,\n        // which is required to flatten the array up to depth.\n        Iteration[\"length\"] extends Depth ? true : false\n      >\n    : T;\n}[IsDone extends true ? \"done\" : \"recur\"];\n\n/**\n * Creates a new array with all sub-array elements concatenated into it\n * recursively up to the specified depth. Equivalent to the built-in\n * `Array.prototype.flat` method.\n *\n * @param data - The items to flatten.\n * @param depth - The depth level specifying how deep a nested array structure\n * should be flattened. Defaults to 1. Non literal values (those typed as\n * `number`cannot be used. `Infinity`, `Number.POSITIVE_INFINITY` and\n * `Number.MAX_VALUE` are all typed as `number` and can't be used either. For\n * \"unlimited\" depth use a literal value that would exceed your expected\n * practical maximum nesting level.\n * @signature\n *   flat(data)\n *   flat(data, depth)\n * @example\n *   flat([[1, 2], [3, 4], [5], [[6]]]); // => [1, 2, 3, 4, 5, [6]]\n *   flat([[[1]], [[2]]], 2); // => [1, 2]\n * @dataFirst\n * @lazy\n * @category Array\n */\nexport function flat<T extends IterableContainer, Depth extends number = 1>(\n  data: T,\n  depth?: IsNumericLiteral<Depth> extends true ? Depth : never,\n): FlatArray<T, Depth>;\n\n/**\n * Creates a new array with all sub-array elements concatenated into it\n * recursively up to the specified depth. Equivalent to the built-in\n * `Array.prototype.flat` method.\n *\n * @param depth - The depth level specifying how deep a nested array structure\n * should be flattened. Defaults to 1.\n * @signature\n *   flat()(data)\n *   flat(depth)(data)\n * @example\n *   pipe([[1, 2], [3, 4], [5], [[6]]], flat()); // => [1, 2, 3, 4, 5, [6]]\n *   pipe([[[1]], [[2]]], flat(2)); // => [1, 2]\n * @dataLast\n * @lazy\n * @category Array\n */\nexport function flat<Depth extends number = 1>(\n  depth?: IsNumericLiteral<Depth> extends true ? Depth : never,\n): <T extends IterableContainer>(data: T) => FlatArray<T, Depth>;\n\nexport function flat(\n  dataOrDepth?: IterableContainer | number,\n  depth?: number,\n): unknown {\n  if (typeof dataOrDepth === \"object\") {\n    return flatImplementation(dataOrDepth, depth);\n  }\n\n  return lazyDataLastImpl(\n    flatImplementation,\n    dataOrDepth === undefined ? [] : [dataOrDepth],\n    lazyImplementation,\n  );\n}\n\nconst flatImplementation = (\n  data: IterableContainer,\n  depth?: number,\n): IterableContainer => (depth === undefined ? data.flat() : data.flat(depth));\n\nconst lazyImplementation = (depth?: number): LazyEvaluator =>\n  depth === undefined || depth === 1\n    ? lazyShallow\n    : depth <= 0\n      ? lazyIdentityEvaluator\n      : (value) =>\n          Array.isArray(value)\n            ? {\n                next: value.flat(depth - 1),\n                hasNext: true,\n                hasMany: true,\n                done: false,\n              }\n            : { next: value, hasNext: true, done: false };\n\n// This function is pulled out so that we don't generate a new arrow function\n// each time. Because it doesn't need to run with recursion it could be pulled\n// out from the lazyImplementation and be reused for all invocations.\nconst lazyShallow = <T>(value: T): LazyResult<T> =>\n  Array.isArray(value)\n    ? { next: value, hasNext: true, hasMany: true, done: false }\n    : { next: value, hasNext: true, done: false };\n"],"mappings":"oKAyGA,SAAgB,EACd,EACA,EACS,CAKT,OAJI,OAAO,GAAgB,SAClB,EAAmB,EAAa,EAAM,CAGxCA,EAAAA,EACL,EACA,IAAgB,IAAA,GAAY,EAAE,CAAG,CAAC,EAAY,CAC9C,EACD,CAGH,MAAM,GACJ,EACA,IACuB,IAAU,IAAA,GAAY,EAAK,MAAM,CAAG,EAAK,KAAK,EAAM,CAEvE,EAAsB,GAC1B,IAAU,IAAA,IAAa,IAAU,EAC7B,EACA,GAAS,EACPC,EAAAA,EACC,GACC,MAAM,QAAQ,EAAM,CAChB,CACE,KAAM,EAAM,KAAK,EAAQ,EAAE,CAC3B,QAAS,GACT,QAAS,GACT,KAAM,GACP,CACD,CAAE,KAAM,EAAO,QAAS,GAAM,KAAM,GAAO,CAKnD,EAAkB,GACtB,MAAM,QAAQ,EAAM,CAChB,CAAE,KAAM,EAAO,QAAS,GAAM,QAAS,GAAM,KAAM,GAAO,CAC1D,CAAE,KAAM,EAAO,QAAS,GAAM,KAAM,GAAO"}