{"version":3,"file":"find.cjs","names":["purry","toSingle","SKIP_ITEM"],"sources":["../src/find.ts"],"sourcesContent":["import { toSingle } from \"./internal/toSingle\";\nimport type { Assignability } from \"./internal/types/Assignability\";\nimport type { First } from \"./internal/types/First\";\nimport type { IterableContainer } from \"./internal/types/IterableContainer\";\nimport type {\n  LazyCallback,\n  LazyTypePredicate,\n} from \"./internal/types/LazyCallback\";\nimport type { LazyEvaluator } from \"./internal/types/LazyEvaluator\";\nimport type { Narrowed } from \"./internal/types/Narrowed\";\nimport type { TupleParts } from \"./internal/types/TupleParts\";\nimport { SKIP_ITEM } from \"./internal/utilityEvaluators\";\nimport { purry } from \"./purry\";\n\ntype Found<T extends IterableContainer, Condition> =\n  // We distribute the array type to support unions of arrays/tuples.\n  T extends unknown\n    ? FoundInFixedTuple<\n        TupleParts<T>[\"required\"],\n        Condition,\n        // When the required part doesn't have any item that would always match\n        // we fall back to the optional parts of the tuple which might match.\n        | Narrowed<TupleParts<T>[\"optional\"][number], Condition>\n        | Narrowed<TupleParts<T>[\"item\"], Condition>\n        // A non-trivial suffix part can only show up if a non-trivial optional\n        // part or a non-trivial item exists, so it is always part of the\n        // fallback of the required part.\n        | FoundInFixedTuple<\n            TupleParts<T>[\"suffix\"],\n            Condition,\n            // When an item isn't found we need to return `undefined`, but\n            // because it might still always exist in the suffix we set this\n            // return value as the fallback of the suffix part, this way if the\n            // suffix has a match the fallback isn't reached and we don't add\n            // the `undefined`, and in any other case the fallback would make\n            // sure we cover this case too.\n            undefined\n          >\n      >\n    : never;\n\n// This type only works under the assumption that T is a simple fixed tuple (no\n// optional items and no rest items)!\ntype FoundInFixedTuple<T, Condition, Fallback> = T extends readonly [\n  infer Head,\n  ...infer Rest,\n]\n  ? Assignability<\n      Head,\n      Condition,\n      {\n        full: Head;\n\n        // Because the match isn't full we need to also consider the rest of the\n        // items too because in runtime we might skip the current item.\n        partial:\n          | Narrowed<Head, Condition>\n          | FoundInFixedTuple<Rest, Condition, Fallback>;\n        none: FoundInFixedTuple<Rest, Condition, Fallback>;\n      }\n    >\n  : Fallback;\n\n// For non-type-narrowing predicates, we can only provide more refined type when\n// we know the predicate returns a constant literal boolean value.\ntype FoundNonRefined<\n  T extends IterableContainer,\n  IsItemIncluded extends boolean,\n> = boolean extends IsItemIncluded\n  ? T[number] | undefined\n  : IsItemIncluded extends true\n    ? // `find(data, constant(true))` is equivalent to `first(data)`.\n      First<T>\n    : undefined;\n\n/**\n * Returns the first element in the provided array that satisfies the provided\n * testing function. If no values satisfy the testing function, `undefined` is\n * returned.\n *\n * Similar functions:\n * * `findLast` - If you need the last element that satisfies the provided testing function.\n * * `findIndex` - If you need the index of the found element in the array.\n * * `indexOf` - If you need to find the index of a value.\n * * `includes` - If you need to find if a value exists in an array.\n * * `some` - If you need to find if any element satisfies the provided testing function.\n * * `filter` - If you need to find all elements that satisfy the provided testing function.\n *\n * @param data - The items to search in.\n * @param predicate - A function to execute for each element in the array. It\n * should return `true` to indicate a matching element has been found, and\n * `false` otherwise. A type-predicate can also be used to narrow the result.\n * @returns The first element in the array that satisfies the provided testing\n * function. Otherwise, `undefined` is returned.\n * @signature\n *    find(data, predicate)\n * @example\n *    find([1, 3, 4, 6], n => n % 2 === 0) // => 4\n * @dataFirst\n * @lazy\n * @category Array\n */\nexport function find<T extends IterableContainer, Condition>(\n  data: T,\n  predicate: (value: T[number], index: number, data: T) => value is Condition,\n): Found<T, Condition>;\n\nexport function find<\n  T extends IterableContainer,\n  IsItemIncluded extends boolean,\n>(\n  data: T,\n  predicate: (value: T[number], index: number, data: T) => IsItemIncluded,\n): FoundNonRefined<T, IsItemIncluded>;\n\n/**\n * Returns the first element in the provided array that satisfies the provided\n * testing function. If no values satisfy the testing function, `undefined` is\n * returned.\n *\n * Similar functions:\n * * `findLast` - If you need the last element that satisfies the provided testing function.\n * * `findIndex` - If you need the index of the found element in the array.\n * * `indexOf` - If you need to find the index of a value.\n * * `includes` - If you need to find if a value exists in an array.\n * * `some` - If you need to find if any element satisfies the provided testing function.\n * * `filter` - If you need to find all elements that satisfy the provided testing function.\n *\n * @param predicate - A function to execute for each element in the array. It\n * should return `true` to indicate a matching element has been found, and\n * `false` otherwise. A type-predicate can also be used to narrow the result.\n * @returns The first element in the array that satisfies the provided testing\n * function. Otherwise, `undefined` is returned.\n * @signature\n *    find(predicate)(data)\n * @example\n *    pipe(\n *      [1, 3, 4, 6],\n *      find(n => n % 2 === 0)\n *    ) // => 4\n * @dataLast\n * @lazy\n * @category Array\n */\nexport function find<T extends IterableContainer, Condition>(\n  predicate: LazyTypePredicate<T, Condition>,\n): (data: T) => Found<T, Condition>;\n\nexport function find<\n  T extends IterableContainer,\n  IsItemIncluded extends boolean,\n>(\n  predicate: LazyCallback<T, IsItemIncluded>,\n): (data: T) => FoundNonRefined<T, IsItemIncluded>;\n\nexport function find(...args: readonly unknown[]): unknown {\n  return purry(findImplementation, args, toSingle(lazyImplementation));\n}\n\nconst findImplementation = <T, S extends T>(\n  data: readonly T[],\n  predicate: (value: T, index: number, data: readonly T[]) => value is S,\n): S | undefined => data.find(predicate);\n\nconst lazyImplementation =\n  <T, S extends T>(\n    predicate: (value: T, index: number, data: readonly T[]) => value is S,\n  ): LazyEvaluator<T, S> =>\n  (value, index, data) =>\n    predicate(value, index, data)\n      ? { done: true, hasNext: true, next: value }\n      : SKIP_ITEM;\n"],"mappings":"qLA2JA,SAAgB,EAAK,GAAG,EAAmC,CACzD,OAAOA,EAAAA,MAAM,EAAoB,EAAMC,EAAAA,EAAS,CAAkB,CAAC,CACrE,CAEA,MAAM,GACJ,EACA,IACkB,EAAK,KAAK,CAAS,EAEjC,EAEF,IAED,EAAO,EAAO,IACb,EAAU,EAAO,EAAO,CAAI,EACxB,CAAE,KAAM,GAAM,QAAS,GAAM,KAAM,CAAM,EACzCC,EAAAA"}