{"version":3,"file":"index.cjs","sources":[""],"sourcesContent":["export type TArrSortDirection = \"asc\" | \"desc\";\n\nexport type TArrSortNulls = \"first\" | \"last\";\n\nexport type TArrSortValue = bigint | boolean | Date | null | number | string | undefined;\n\nexport type TGetArrSortedByOptions<TValue extends TArrSortValue> = {\n  compare?: (left: TValue, right: TValue) => number;\n  direction?: TArrSortDirection;\n  nulls?: TArrSortNulls;\n};\n\nexport type TGetArrSortedByArgs = Parameters<typeof getArrSortedBy>;\n\nexport type TGetArrSortedByReturn = ReturnType<typeof getArrSortedBy>;\n\nconst isEmptySortValue = (value: TArrSortValue): boolean => {\n  return value === null\n    || value === undefined\n    || (typeof value === \"number\" && Number.isNaN(value))\n    || (value instanceof Date && Number.isNaN(value.getTime()));\n};\n\nconst getComparableValue = (value: TArrSortValue): bigint | boolean | number | string => {\n  return value instanceof Date ? value.getTime() : value as bigint | boolean | number | string;\n};\n\nconst compareDefault = (left: TArrSortValue, right: TArrSortValue): number => {\n  const leftValue = getComparableValue(left);\n  const rightValue = getComparableValue(right);\n  if (typeof leftValue === typeof rightValue) {\n    if (leftValue < rightValue) {\n      return -1;\n    }\n    if (leftValue > rightValue) {\n      return 1;\n    }\n    return 0;\n  }\n  return String(leftValue).localeCompare(String(rightValue));\n};\n\n/**\n * Returns a stable, sorted copy of an array using a value selector.\n * Nullish values, `NaN`, and invalid dates are placed according to `nulls`.\n * @template T,TValue\n * @param {readonly T[]} arr Source array\n * @param {(value: T, index: number, array: readonly T[]) => TValue} getValue Sort value selector\n * @param {TGetArrSortedByOptions<TValue>} [options={}] Direction, empty-value placement, and comparator\n * @returns {T[]} Stable sorted copy\n * @throws {TypeError} getArrSortedBy: arguments are invalid\n * @example\n * const productsByPrice = getArrSortedBy(products, (product) => product.price, {\n *   direction: \"desc\",\n * });\n * @example\n * // Sort localized names while keeping missing names at the end\n * const collator = new Intl.Collator(\"ru-RU\", { sensitivity: \"base\" });\n * const usersByName = getArrSortedBy(users, (user) => user.name, {\n *   compare: collator.compare,\n *   nulls: \"last\",\n * });\n */\nexport const getArrSortedBy = <T, TValue extends TArrSortValue>(\n  arr: readonly T[],\n  getValue: (value: T, index: number, array: readonly T[]) => TValue,\n  options: TGetArrSortedByOptions<TValue> = {}\n): T[] => {\n  if (!Array.isArray(arr)) {\n    throw new TypeError(\"getArrSortedBy: arr must be an array\");\n  }\n  if (typeof getValue !== \"function\") {\n    throw new TypeError(\"getArrSortedBy: getValue must be a function\");\n  }\n  if (!options || typeof options !== \"object\" || Array.isArray(options)) {\n    throw new TypeError(\"getArrSortedBy: options must be a plain object\");\n  }\n  const {\n    compare = compareDefault as (left: TValue, right: TValue) => number,\n    direction = \"asc\",\n    nulls = \"last\",\n  } = options;\n  if (typeof compare !== \"function\") {\n    throw new TypeError(\"getArrSortedBy: compare must be a function\");\n  }\n  if (direction !== \"asc\" && direction !== \"desc\") {\n    throw new TypeError('getArrSortedBy: direction must be \"asc\" or \"desc\"');\n  }\n  if (nulls !== \"first\" && nulls !== \"last\") {\n    throw new TypeError('getArrSortedBy: nulls must be \"first\" or \"last\"');\n  }\n\n  return arr\n    .map((value, index, array) => ({ index, sortValue: getValue(value, index, array), value }))\n    .sort((left, right) => {\n      const leftIsEmpty = isEmptySortValue(left.sortValue);\n      const rightIsEmpty = isEmptySortValue(right.sortValue);\n      if (leftIsEmpty || rightIsEmpty) {\n        if (leftIsEmpty && rightIsEmpty) {\n          return left.index - right.index;\n        }\n        return leftIsEmpty === (nulls === \"first\") ? -1 : 1;\n      }\n      const compared = compare(left.sortValue, right.sortValue);\n      if (typeof compared !== \"number\" || !Number.isFinite(compared)) {\n        throw new TypeError(\"getArrSortedBy: compare must return a finite number\");\n      }\n      return compared === 0\n        ? left.index - right.index\n        : compared * (direction === \"asc\" ? 1 : -1);\n    })\n    .map(({ value }) => value);\n};\n"],"names":["isEmptySortValue","value","undefined","Number","isNaN","Date","getTime","getComparableValue","compareDefault","left","right","leftValue","rightValue","String","localeCompare","getArrSortedBy","arr","getValue","options","Array","isArray","TypeError","compare","direction","nulls","map","index","array","sortValue","sort","leftIsEmpty","rightIsEmpty","compared","isFinite"],"mappings":"yDAgBA,MAAMA,iBAAoBC,OACjBA,QAAU,MACZA,aAAUC,UACFD,QAAU,UAAYE,OAAOC,MAAMH,QAC1CA,iBAAiBI,MAAQF,OAAOC,MAAMH,MAAMK,WAGpD,MAAMC,mBAAsBN,OACnBA,iBAAiBI,KAAOJ,MAAMK,UAAYL,MAGnD,MAAMO,eAAiB,CAACC,KAAqBC,SAC3C,MAAMC,UAAYJ,mBAAmBE,MACrC,MAAMG,WAAaL,mBAAmBG,OACtC,UAAWC,mBAAqBC,WAAY,CAC1C,GAAID,UAAYC,WACd,OAAO,EAET,GAAID,UAAYC,WACd,OAAO,EAET,OAAO,CACT,CACA,OAAOC,OAAOF,WAAWG,cAAcD,OAAOD,cAwBzC,MAAMG,eAAiB,CAC5BC,IACAC,SACAC,QAA0C,CAAA,KAE1C,IAAKC,MAAMC,QAAQJ,KACjB,MAAM,IAAIK,UAAU,wCAEtB,UAAWJ,WAAa,WACtB,MAAM,IAAII,UAAU,+CAEtB,IAAKH,gBAAkBA,UAAY,UAAYC,MAAMC,QAAQF,SAC3D,MAAM,IAAIG,UAAU,kDAEtB,MAAMC,QACJA,QAAUd,eAAyDe,UACnEA,UAAY,MAAKC,MACjBA,MAAQ,QACNN,QACJ,UAAWI,UAAY,WACrB,MAAM,IAAID,UAAU,8CAEtB,GAAIE,YAAc,OAASA,YAAc,OACvC,MAAM,IAAIF,UAAU,qDAEtB,GAAIG,QAAU,SAAWA,QAAU,OACjC,MAAM,IAAIH,UAAU,mDAGtB,OAAOL,IACJS,IAAI,CAACxB,MAAOyB,MAAOC,SAAK,CAAQD,YAAOE,UAAWX,SAAShB,MAAOyB,MAAOC,OAAQ1B,eACjF4B,KAAK,CAACpB,KAAMC,SACX,MAAMoB,YAAc9B,iBAAiBS,KAAKmB,WAC1C,MAAMG,aAAe/B,iBAAiBU,MAAMkB,WAC5C,GAAIE,aAAeC,aAAc,CAC/B,GAAID,aAAeC,aACjB,OAAOtB,KAAKiB,MAAQhB,MAAMgB,MAE5B,OAAOI,eAAiBN,QAAU,UAAW,EAAK,CACpD,CACA,MAAMQ,SAAWV,QAAQb,KAAKmB,UAAWlB,MAAMkB,WAC/C,UAAWI,WAAa,WAAa7B,OAAO8B,SAASD,UACnD,MAAM,IAAIX,UAAU,uDAEtB,OAAOW,WAAa,EAChBvB,KAAKiB,MAAQhB,MAAMgB,MACnBM,UAAYT,YAAc,MAAQ,GAAI,KAE3CE,IAAI,EAAGxB,eAAYA"}