Files
simple-mail-cleaner/backend/node_modules/remeda/dist/purryOrderRules-Si4oUxGJ.cjs.map
2026-01-23 01:33:35 +01:00

1 line
7.6 KiB
Plaintext

{"version":3,"file":"purryOrderRules-Si4oUxGJ.cjs","names":["arg: unknown","argRemoved: readonly unknown[]"],"sources":["../src/internal/purryOrderRules.ts"],"sourcesContent":["import type { CompareFunction } from \"./types/CompareFunction\";\nimport type { NonEmptyArray } from \"./types/NonEmptyArray\";\n\n// We define the comparators in a global const so that they are only\n// instantiated once, and so we can couple a label (string) for them that could\n// be used in runtime to refer to them (e.g. \"asc\", \"desc\").\nconst COMPARATORS = {\n asc: <T>(x: T, y: T) => x > y,\n desc: <T>(x: T, y: T) => x < y,\n} as const;\n\n/**\n * An order rule defines a projection/extractor that returns a comparable from\n * the data being compared. It would be run on each item being compared, and a\n * comparator would then be used on the results to determine the order.\n *\n * There are 2 forms of the order rule, a simple one which only provides the\n * projection function and assumes ordering is ascending, and a 2-tuple where\n * the first element is the projection function and the second is the direction;\n * this allows changing the direction without defining a more complex projection\n * to simply negate the value (e.g. `(x) => -x`).\n *\n * We rely on the javascript implementation of `<` and `>` for comparison, which\n * will attempt to transform both operands into a primitive comparable value via\n * the built in `valueOf` function (and then `toString`). It's up to the caller\n * to make sure that the projection is returning a value that makes sense for\n * this logic.\n *\n * It's important to note that there is no built-in caching/memoization of\n * projection function and therefore no guarantee that it would only be called\n * once.\n */\nexport type OrderRule<T> =\n | Projection<T>\n | readonly [projection: Projection<T>, direction: keyof typeof COMPARATORS];\n\ntype Projection<T> = (x: T) => Comparable;\n\n// We define the Comparable based on how JS coerces values into primitives when\n// used with the `<` and `>` operators.\n// @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#type_coercion\ntype Comparable =\n | ComparablePrimitive\n | { [Symbol.toPrimitive]: (hint: string) => ComparablePrimitive }\n | { toString: () => string }\n | { valueOf: () => ComparablePrimitive };\n\n// Notice that `boolean` is special in that it is coerced as a number (0 for\n// `false`, 1 for `true`) implicitly.\ntype ComparablePrimitive = bigint | boolean | number | string;\n\n/**\n * Allows functions that want to handle a variadic number of order rules a\n * a simplified API that hides most of the implementation details. The only\n * thing users of this function need to do is provide a function that would take\n * the data, and a compare function that can be used to determine the order\n * between the items of the array.\n * This functions takes care of the rest; it will parse rules, built the\n * comparer, and manage the purrying of the input arguments.\n */\nexport function purryOrderRules<T>(\n func: (data: readonly T[], compareFn: CompareFunction<T>) => unknown,\n inputArgs: readonly unknown[],\n): unknown {\n // We rely on casting blindly here, but we rely on casting blindly everywhere\n // else when we call purry so it's fine...\n const [dataOrRule, ...rules] = inputArgs as\n | Readonly<NonEmptyArray<OrderRule<T>>>\n | [\n data: OrderRule<T> | readonly T[],\n ...rules: Readonly<NonEmptyArray<OrderRule<T>>>,\n ];\n\n if (!isOrderRule<T>(dataOrRule)) {\n // dataFirst!\n\n // @ts-expect-error [ts2556]: Typescript is failing to infer the type of rules\n // correctly here after the type refinement above, rules should be non-empty\n // when we get here.\n const compareFn = orderRuleComparer(...rules);\n return func(dataOrRule, compareFn);\n }\n\n // dataLast!\n\n // Important: initialize the comparer outside of the returned function so it\n // it's constructed and shared everywhere (it's stateless so should be safe\n // if used multiple times).\n const compareFn = orderRuleComparer(dataOrRule, ...rules);\n return (data: readonly T[]) => func(data, compareFn);\n}\n\n/**\n * Some functions need an extra number argument, this helps facilitate that.\n */\nexport function purryOrderRulesWithArgument(\n func: <T>(\n data: readonly T[],\n compareFn: CompareFunction<T>,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any -- Function inference in typescript relies on `any` to work, it doesn't work with `unknown`\n arg: any,\n ) => unknown,\n [first, second, ...rest]: readonly unknown[],\n): unknown {\n // We need to pull the `n` argument out to make it work with purryOrderRules.\n let arg: unknown;\n let argRemoved: readonly unknown[];\n if (isOrderRule(second)) {\n // dataLast!\n arg = first;\n argRemoved = [second, ...rest];\n } else {\n // dataFirst!\n arg = second;\n argRemoved = [first, ...rest];\n }\n\n return purryOrderRules((...args) => func(...args, arg), argRemoved);\n}\n\nfunction orderRuleComparer<T>(\n primaryRule: OrderRule<T>,\n secondaryRule?: OrderRule<T>,\n ...otherRules: readonly OrderRule<T>[]\n): (a: T, b: T) => number {\n const projector =\n typeof primaryRule === \"function\" ? primaryRule : primaryRule[0];\n\n const direction = typeof primaryRule === \"function\" ? \"asc\" : primaryRule[1];\n const { [direction]: comparator } = COMPARATORS;\n\n const nextComparer =\n secondaryRule === undefined\n ? undefined\n : orderRuleComparer(secondaryRule, ...otherRules);\n\n return (a, b) => {\n const projectedA = projector(a);\n const projectedB = projector(b);\n\n if (comparator(projectedA, projectedB)) {\n return 1;\n }\n\n if (comparator(projectedB, projectedA)) {\n return -1;\n }\n\n // The elements are equal base on the current comparator and projection. So\n // we need to check the elements using the next comparer, if one exists,\n // otherwise we consider them as true equal (returning 0).\n return nextComparer?.(a, b) ?? 0;\n };\n}\n\nfunction isOrderRule<T>(x: unknown): x is OrderRule<T> {\n if (isProjection(x)) {\n return true;\n }\n\n if (typeof x !== \"object\" || !Array.isArray(x)) {\n return false;\n }\n\n const [maybeProjection, maybeDirection, ...rest] = x as readonly unknown[];\n\n return (\n isProjection(maybeProjection) &&\n typeof maybeDirection === \"string\" &&\n maybeDirection in COMPARATORS &&\n // Has to be a 2-tuple\n rest.length === 0\n );\n}\n\nconst isProjection = <T>(x: unknown): x is Projection<T> =>\n typeof x === \"function\" && x.length === 1;\n"],"mappings":"AAMA,MAAM,EAAc,CAClB,KAAS,EAAM,IAAS,EAAI,EAC5B,MAAU,EAAM,IAAS,EAAI,EAC9B,CAmDD,SAAgB,EACd,EACA,EACS,CAGT,GAAM,CAAC,EAAY,GAAG,GAAS,EAO/B,GAAI,CAAC,EAAe,EAAW,CAO7B,OAAO,EAAK,EADM,EAAkB,GAAG,EAAM,CACX,CAQpC,IAAM,EAAY,EAAkB,EAAY,GAAG,EAAM,CACzD,MAAQ,IAAuB,EAAK,EAAM,EAAU,CAMtD,SAAgB,EACd,EAMA,CAAC,EAAO,EAAQ,GAAG,GACV,CAET,IAAIA,EACAC,EAWJ,OAVI,EAAY,EAAO,EAErB,EAAM,EACN,EAAa,CAAC,EAAQ,GAAG,EAAK,GAG9B,EAAM,EACN,EAAa,CAAC,EAAO,GAAG,EAAK,EAGxB,GAAiB,GAAG,IAAS,EAAK,GAAG,EAAM,EAAI,CAAE,EAAW,CAGrE,SAAS,EACP,EACA,EACA,GAAG,EACqB,CACxB,IAAM,EACJ,OAAO,GAAgB,WAAa,EAAc,EAAY,GAE1D,EAAY,OAAO,GAAgB,WAAa,MAAQ,EAAY,GACpE,EAAG,GAAY,GAAe,EAE9B,EACJ,IAAkB,IAAA,GACd,IAAA,GACA,EAAkB,EAAe,GAAG,EAAW,CAErD,OAAQ,EAAG,IAAM,CACf,IAAM,EAAa,EAAU,EAAE,CACzB,EAAa,EAAU,EAAE,CAa/B,OAXI,EAAW,EAAY,EAAW,CAC7B,EAGL,EAAW,EAAY,EAAW,CAC7B,GAMF,IAAe,EAAG,EAAE,EAAI,GAInC,SAAS,EAAe,EAA+B,CACrD,GAAI,EAAa,EAAE,CACjB,MAAO,GAGT,GAAI,OAAO,GAAM,UAAY,CAAC,MAAM,QAAQ,EAAE,CAC5C,MAAO,GAGT,GAAM,CAAC,EAAiB,EAAgB,GAAG,GAAQ,EAEnD,OACE,EAAa,EAAgB,EAC7B,OAAO,GAAmB,UAC1B,KAAkB,GAElB,EAAK,SAAW,EAIpB,MAAM,EAAmB,GACvB,OAAO,GAAM,YAAc,EAAE,SAAW"}