{"version":3,"file":"pipe.cjs","names":["SKIP_ITEM"],"sources":["../src/pipe.ts"],"sourcesContent":["/* eslint-disable jsdoc/check-param-names --\n * We document pipe's function params as a single parameter entry in the docs.\n */\n\nimport type { LazyDefinition } from \"./internal/types/LazyDefinition\";\nimport type { LazyEvaluator } from \"./internal/types/LazyEvaluator\";\nimport type { LazyResult } from \"./internal/types/LazyResult\";\nimport { SKIP_ITEM } from \"./internal/utilityEvaluators\";\n\ntype LazyStep = {\n  readonly lazyEvaluator: LazyEvaluator;\n  readonly isSingle: boolean;\n  // Notice the array is mutable, we will be adding items as the pipe is\n  // evaluating them.\n  readonly items: unknown[];\n};\n\ntype LazyFunction = LazyDefinition & ((input: unknown) => unknown);\n\n/**\n * Performs left-to-right function composition, passing data through functions\n * in sequence. Each function receives the output of the previous function,\n * creating a readable top-to-bottom data flow that matches how the\n * transformation is executed. This enables converting deeply nested function\n * calls into clear, sequential steps without temporary variables.\n *\n * When consecutive functions with a `lazy` tag (e.g., `map`, `filter`, `take`,\n * `drop`, `forEach`, etc...) are used together, they process data item-by-item\n * rather than creating intermediate arrays. This enables early termination\n * when only partial results are needed, improving performance for large\n * datasets and expensive operations.\n *\n * Functions are only evaluated lazily when their data-last form is used\n * directly in the pipe. To disable lazy evaluation, use data-first calls via\n * arrow functions: `($) => map($, callback)` instead of `map(callback)`.\n *\n * Any function can be used in pipes, not just Remeda utilities. For creating\n * custom functions with currying and lazy evaluation support, see the `purry`\n * utility.\n *\n * A \"headless\" variant `piped` is available for creating reusable pipe\n * functions without initial data.\n *\n * IMPORTANT: During lazy evaluation, callbacks using the third parameter (the\n * input array) receive only items processed up to that point, not the complete\n * array.\n *\n * @param data - The input data.\n * @param functions - A sequence of functions that take one argument and\n * return a value.\n * @signature\n *   pipe(data, ...functions);\n * @example\n *    pipe([1, 2, 3], map(multiply(3))); //=> [3, 6, 9]\n *\n *    // = Early termination with lazy evaluation =\n *    pipe(\n *      hugeArray,\n *      map(expensiveComputation),\n *      filter(complexPredicate),\n *      // Only processes items until 2 results are found, then stops.\n *      // Most of hugeArray never gets processed.\n *      take(2),\n *    );\n *\n *    // = Custom logic within a pipe =\n *    pipe(\n *      input,\n *      toLowerCase(),\n *      normalize,\n *      ($) => validate($, CONFIG),\n *      split(\",\"),\n *      unique(),\n *    );\n *\n *    // = Migrating nested transformations to pipes =\n *    // Nested\n *    const result = prop(\n *      mapValues(groupByProp(users, \"department\"), length()),\n *      \"engineering\",\n *    );\n *\n *    // Piped\n *    const result = pipe(\n *      users,\n *      groupByProp(\"department\"),\n *      mapValues(length()),\n *      prop(\"engineering\"),\n *    );\n *\n *    // = Using the 3rd param of a callback =\n *    // The following would print out `data` in its entirety for each value\n *    // of `data`.\n *    forEach([1, 2, 3, 4], (_item, _index, data) => {\n *      console.log(data);\n *    }); //=> \"[1, 2, 3, 4]\" logged 4 times\n *\n *    // But with `pipe` data would only contain the items up to the current\n *    // index\n *    pipe([1, 2, 3, 4], forEach((_item, _index, data) => {\n *      console.log(data);\n *    })); //=> \"[1]\", \"[1, 2]\", \"[1, 2, 3]\", \"[1, 2, 3, 4]\"\n * @dataFirst\n * @category Function\n */\nexport function pipe<A>(data: A): A;\n\nexport function pipe<A, B>(data: A, funcA: (input: A) => B): B;\n\nexport function pipe<A, B, C>(\n  data: A,\n  funcA: (input: A) => B,\n  funcB: (input: B) => C,\n): C;\n\nexport function pipe<A, B, C, D>(\n  data: A,\n  funcA: (input: A) => B,\n  funcB: (input: B) => C,\n  funcC: (input: C) => D,\n): D;\n\nexport function pipe<A, B, C, D, E>(\n  data: A,\n  funcA: (input: A) => B,\n  funcB: (input: B) => C,\n  funcC: (input: C) => D,\n  funcD: (input: D) => E,\n): E;\n\nexport function pipe<A, B, C, D, E, F>(\n  data: A,\n  funcA: (input: A) => B,\n  funcB: (input: B) => C,\n  funcC: (input: C) => D,\n  funcD: (input: D) => E,\n  funcE: (input: E) => F,\n): F;\n\nexport function pipe<A, B, C, D, E, F, G>(\n  data: A,\n  funcA: (input: A) => B,\n  funcB: (input: B) => C,\n  funcC: (input: C) => D,\n  funcD: (input: D) => E,\n  funcE: (input: E) => F,\n  funcF: (input: F) => G,\n): G;\n\nexport function pipe<A, B, C, D, E, F, G, H>(\n  data: A,\n  funcA: (input: A) => B,\n  funcB: (input: B) => C,\n  funcC: (input: C) => D,\n  funcD: (input: D) => E,\n  funcE: (input: E) => F,\n  funcF: (input: F) => G,\n  funcG: (input: G) => H,\n): H;\n\nexport function pipe<A, B, C, D, E, F, G, H, I>(\n  data: A,\n  funcA: (input: A) => B,\n  funcB: (input: B) => C,\n  funcC: (input: C) => D,\n  funcD: (input: D) => E,\n  funcE: (input: E) => F,\n  funcF: (input: F) => G,\n  funcG: (input: G) => H,\n  funcH: (input: H) => I,\n): I;\n\nexport function pipe<A, B, C, D, E, F, G, H, I, J>(\n  data: A,\n  funcA: (input: A) => B,\n  funcB: (input: B) => C,\n  funcC: (input: C) => D,\n  funcD: (input: D) => E,\n  funcE: (input: E) => F,\n  funcF: (input: F) => G,\n  funcG: (input: G) => H,\n  funcH: (input: H) => I,\n  funcI: (input: I) => J,\n): J;\n\nexport function pipe<A, B, C, D, E, F, G, H, I, J, K>(\n  data: A,\n  funcA: (input: A) => B,\n  funcB: (input: B) => C,\n  funcC: (input: C) => D,\n  funcD: (input: D) => E,\n  funcE: (input: E) => F,\n  funcF: (input: F) => G,\n  funcG: (input: G) => H,\n  funcH: (input: H) => I,\n  funcI: (input: I) => J,\n  funcJ: (input: J) => K,\n): K;\n\nexport function pipe<A, B, C, D, E, F, G, H, I, J, K, L>(\n  data: A,\n  funcA: (input: A) => B,\n  funcB: (input: B) => C,\n  funcC: (input: C) => D,\n  funcD: (input: D) => E,\n  funcE: (input: E) => F,\n  funcF: (input: F) => G,\n  funcG: (input: G) => H,\n  funcH: (input: H) => I,\n  funcI: (input: I) => J,\n  funcJ: (input: J) => K,\n  funcK: (input: K) => L,\n): L;\n\nexport function pipe<A, B, C, D, E, F, G, H, I, J, K, L, M>(\n  data: A,\n  funcA: (input: A) => B,\n  funcB: (input: B) => C,\n  funcC: (input: C) => D,\n  funcD: (input: D) => E,\n  funcE: (input: E) => F,\n  funcF: (input: F) => G,\n  funcG: (input: G) => H,\n  funcH: (input: H) => I,\n  funcI: (input: I) => J,\n  funcJ: (input: J) => K,\n  funcK: (input: K) => L,\n  funcL: (input: L) => M,\n): M;\n\nexport function pipe<A, B, C, D, E, F, G, H, I, J, K, L, M, N>(\n  data: A,\n  funcA: (input: A) => B,\n  funcB: (input: B) => C,\n  funcC: (input: C) => D,\n  funcD: (input: D) => E,\n  funcE: (input: E) => F,\n  funcF: (input: F) => G,\n  funcG: (input: G) => H,\n  funcH: (input: H) => I,\n  funcI: (input: I) => J,\n  funcJ: (input: J) => K,\n  funcK: (input: K) => L,\n  funcL: (input: L) => M,\n  funcM: (input: M) => N,\n): N;\n\nexport function pipe<A, B, C, D, E, F, G, H, I, J, K, L, M, N, O>(\n  data: A,\n  funcA: (input: A) => B,\n  funcB: (input: B) => C,\n  funcC: (input: C) => D,\n  funcD: (input: D) => E,\n  funcE: (input: E) => F,\n  funcF: (input: F) => G,\n  funcG: (input: G) => H,\n  funcH: (input: H) => I,\n  funcI: (input: I) => J,\n  funcJ: (input: J) => K,\n  funcK: (input: K) => L,\n  funcL: (input: L) => M,\n  funcM: (input: M) => N,\n  funcN: (input: N) => O,\n): O;\n\nexport function pipe<A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P>(\n  data: A,\n  funcA: (input: A) => B,\n  funcB: (input: B) => C,\n  funcC: (input: C) => D,\n  funcD: (input: D) => E,\n  funcE: (input: E) => F,\n  funcF: (input: F) => G,\n  funcG: (input: G) => H,\n  funcH: (input: H) => I,\n  funcI: (input: I) => J,\n  funcJ: (input: J) => K,\n  funcK: (input: K) => L,\n  funcL: (input: L) => M,\n  funcM: (input: M) => N,\n  funcN: (input: N) => O,\n  funcO: (input: O) => P,\n): P;\n\nexport function pipe(\n  input: unknown,\n  ...functions: readonly (LazyFunction | ((value: unknown) => unknown))[]\n): unknown {\n  let output = input;\n\n  const lazySteps = functions.map((op) =>\n    \"lazy\" in op\n      ? {\n          lazyEvaluator: op.lazy(...op.lazyArgs),\n          isSingle: op.lazy.single ?? false,\n          index: 0,\n          items: [],\n        }\n      : undefined,\n  );\n\n  let functionIndex = 0;\n  while (functionIndex < functions.length) {\n    const lazyStep = lazySteps[functionIndex];\n    if (lazyStep === undefined || !isIterable(output)) {\n      const func = functions[functionIndex]!;\n      output = func(output);\n      functionIndex += 1;\n      continue;\n    }\n\n    const lazySequence = extractLazySequence(lazySteps, functionIndex);\n    const accumulator = processIterable(output, lazySequence);\n\n    const { isSingle } = lazySequence.at(-1)!;\n    output = isSingle ? accumulator[0] : accumulator;\n    functionIndex += lazySequence.length;\n  }\n  return output;\n}\n\nfunction extractLazySequence(\n  // eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types -- The items array is mutable for efficiency.\n  lazySteps: readonly (LazyStep | undefined)[],\n  startIndex: number,\n): readonly LazyStep[] {\n  const lazySequence: LazyStep[] = [];\n\n  for (let index = startIndex; index < lazySteps.length; index++) {\n    const lazyStep = lazySteps[index];\n    if (lazyStep === undefined) {\n      break;\n    }\n\n    lazySequence.push(lazyStep);\n    if (lazyStep.isSingle) {\n      break;\n    }\n  }\n\n  return lazySequence;\n}\n\nfunction processIterable(\n  iterable: Iterable<unknown>,\n  // eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types -- The items array is mutable for efficiency.\n  lazySequence: readonly LazyStep[],\n): unknown[] {\n  const accumulator: unknown[] = [];\n\n  for (const value of iterable) {\n    const shouldExitEarly = processItem(value, accumulator, lazySequence);\n    if (shouldExitEarly) {\n      break;\n    }\n  }\n\n  return accumulator;\n}\n\nfunction processItem(\n  item: unknown,\n  // eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types -- Intentionally mutable, we use the accumulator directly to accumulate the results.\n  accumulator: unknown[],\n  // eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types -- The items array is mutable for efficiency.\n  lazySequence: readonly LazyStep[],\n): boolean {\n  if (lazySequence.length === 0) {\n    accumulator.push(item);\n    return false;\n  }\n\n  let currentItem = item;\n\n  let lazyResult: LazyResult = SKIP_ITEM;\n  let isDone = false;\n  for (const [\n    functionsIndex,\n    { items, lazyEvaluator },\n  ] of lazySequence.entries()) {\n    items.push(currentItem);\n    lazyResult = lazyEvaluator(currentItem, items.length - 1, items);\n\n    if (lazyResult.done) {\n      isDone = true;\n    }\n\n    if (lazyResult.hasNext) {\n      if (lazyResult.hasMany ?? false) {\n        for (const subItem of lazyResult.next as readonly unknown[]) {\n          const shouldExitEarly = processItem(\n            subItem,\n            accumulator,\n            lazySequence.slice(functionsIndex + 1),\n          );\n          if (shouldExitEarly) {\n            return true;\n          }\n        }\n        return isDone;\n      }\n      currentItem = lazyResult.next;\n    } else {\n      break;\n    }\n  }\n\n  if (lazyResult.hasNext) {\n    accumulator.push(currentItem);\n  }\n\n  return isDone;\n}\n\nfunction isIterable(something: unknown): something is Iterable<unknown> {\n  // Check for null and undefined to avoid errors when accessing Symbol.iterator\n  return (\n    typeof something === \"string\" ||\n    (typeof something === \"object\" &&\n      something !== null &&\n      // eslint-disable-next-line unicorn/no-computed-property-existence-check -- The prototype-chain check is intentional: iterables inherit `Symbol.iterator` from their prototype (e.g. `Array.prototype`), and `Object.hasOwn` would reject them all.\n      Symbol.iterator in something)\n  );\n}\n"],"mappings":"uHA4RA,SAAgB,EACd,EACA,GAAG,EACM,CACT,IAAI,EAAS,EAEP,EAAY,EAAU,IAAK,GAC/B,SAAU,EACN,CACE,cAAe,EAAG,KAAK,GAAG,EAAG,QAAQ,EACrC,SAAU,EAAG,KAAK,QAAU,GAC5B,MAAO,EACP,MAAO,CAAC,CACV,EACA,IAAA,EACN,EAEI,EAAgB,EACpB,KAAO,EAAgB,EAAU,QAAQ,CAEvC,GADiB,EAAU,KACV,IAAA,IAAa,CAAC,EAAW,CAAM,EAAG,CACjD,IAAM,EAAO,EAAU,GACvB,EAAS,EAAK,CAAM,EACpB,GAAiB,EACjB,QACF,CAEA,IAAM,EAAe,EAAoB,EAAW,CAAa,EAC3D,EAAc,EAAgB,EAAQ,CAAY,EAElD,CAAE,YAAa,EAAa,GAAG,EAAE,EACvC,EAAS,EAAW,EAAY,GAAK,EACrC,GAAiB,EAAa,MAChC,CACA,OAAO,CACT,CAEA,SAAS,EAEP,EACA,EACqB,CACrB,IAAM,EAA2B,CAAC,EAElC,IAAK,IAAI,EAAQ,EAAY,EAAQ,EAAU,OAAQ,IAAS,CAC9D,IAAM,EAAW,EAAU,GAM3B,GALI,IAAa,IAAA,KAIjB,EAAa,KAAK,CAAQ,EACtB,EAAS,UACX,KAEJ,CAEA,OAAO,CACT,CAEA,SAAS,EACP,EAEA,EACW,CACX,IAAM,EAAyB,CAAC,EAEhC,IAAK,IAAM,KAAS,EAElB,GADwB,EAAY,EAAO,EAAa,CACtC,EAChB,MAIJ,OAAO,CACT,CAEA,SAAS,EACP,EAEA,EAEA,EACS,CACT,GAAI,EAAa,SAAW,EAE1B,OADA,EAAY,KAAK,CAAI,EACd,GAGT,IAAI,EAAc,EAEd,EAAyBA,EAAAA,EACzB,EAAS,GACb,IAAK,GAAM,CACT,EACA,CAAE,QAAO,oBACN,EAAa,QAAQ,EAQxB,GAPA,EAAM,KAAK,CAAW,EACtB,EAAa,EAAc,EAAa,EAAM,OAAS,EAAG,CAAK,EAE3D,EAAW,OACb,EAAS,IAGP,EAAW,QAAS,CACtB,GAAI,EAAW,SAAW,GAAO,CAC/B,IAAK,IAAM,KAAW,EAAW,KAM/B,GALwB,EACtB,EACA,EACA,EAAa,MAAM,EAAiB,CAAC,CAErB,EAChB,MAAO,GAGX,OAAO,CACT,CACA,EAAc,EAAW,IAC3B,MACE,MAQJ,OAJI,EAAW,SACb,EAAY,KAAK,CAAW,EAGvB,CACT,CAEA,SAAS,EAAW,EAAoD,CAEtE,OACE,OAAO,GAAc,UACpB,OAAO,GAAc,YACpB,GAEA,OAAO,YAAY,CAEzB"}