@lucidcms/core
Version:
The core of the Lucid CMS. It's responsible for spinning up the API and serving the CMS.
1 lines • 4.31 kB
Source Map (JSON)
{"version":3,"file":"fractional-order.mjs","names":[],"sources":["../../../src/utils/helpers/fractional-order.ts"],"sourcesContent":["import { copy, translate } from \"../../libs/i18n/index.js\";\nimport { LucidError } from \"../errors/index.js\";\n\n/** Fractional order keys are base-36 strings with room between neighbours. */\n\nconst DIGITS = \"0123456789abcdefghijklmnopqrstuvwxyz\";\n\nconst throwOrderError = (\n\tkey:\n\t\t| \"server:core.documents.order.fractional.bounds.invalid\"\n\t\t| \"server:core.documents.order.fractional.key.invalid\",\n\tdata: Record<string, string>,\n): never => {\n\tthrow new LucidError({\n\t\tmessage: translate(copy(key, { data })),\n\t\tscope: \"fractional-order\",\n\t\tdata,\n\t});\n};\n\nconst isValidOrderKey = (key: string): boolean => {\n\tif (key.length === 0) return false;\n\t//* trailing zero keys cannot be split below\n\tif (key.endsWith(DIGITS[0] as string)) return false;\n\tfor (const char of key) {\n\t\tif (!DIGITS.includes(char)) return false;\n\t}\n\treturn true;\n};\n\n/** Returns a lexicographic midpoint between two bounds. */\nconst midpoint = (a: string, b: string | null): string => {\n\tif (b !== null && a >= b) {\n\t\tthrowOrderError(\"server:core.documents.order.fractional.bounds.invalid\", {\n\t\t\tlower: a,\n\t\t\tupper: b,\n\t\t});\n\t}\n\n\tif (b !== null) {\n\t\t//* split after the shared prefix\n\t\tlet prefixLength = 0;\n\t\twhile ((a.charAt(prefixLength) || DIGITS[0]) === b.charAt(prefixLength)) {\n\t\t\tprefixLength++;\n\t\t}\n\t\tif (prefixLength > 0) {\n\t\t\treturn (\n\t\t\t\tb.slice(0, prefixLength) +\n\t\t\t\tmidpoint(a.slice(prefixLength), b.slice(prefixLength))\n\t\t\t);\n\t\t}\n\t}\n\n\tconst digitA = a ? DIGITS.indexOf(a.charAt(0)) : 0;\n\tconst digitB = b !== null ? DIGITS.indexOf(b.charAt(0)) : DIGITS.length;\n\n\tif (digitB - digitA > 1) {\n\t\tconst midDigit = Math.round(0.5 * (digitA + digitB));\n\t\treturn DIGITS.charAt(midDigit);\n\t}\n\n\t//* keep the upper prefix when first digits are adjacent\n\tif (b !== null && b.length > 1) {\n\t\treturn b.slice(0, 1);\n\t}\n\n\t//* extend the lower bound when no midpoint exists at this depth\n\treturn DIGITS.charAt(digitA) + midpoint(a.slice(1), null);\n};\n\n/** Generates an order key between two neighbouring keys. */\nexport const generateKeyBetween = (\n\ta: string | null,\n\tb: string | null,\n): string => {\n\tif (a !== null && !isValidOrderKey(a)) {\n\t\tthrowOrderError(\"server:core.documents.order.fractional.key.invalid\", {\n\t\t\tkey: a,\n\t\t});\n\t}\n\tif (b !== null && !isValidOrderKey(b)) {\n\t\tthrowOrderError(\"server:core.documents.order.fractional.key.invalid\", {\n\t\t\tkey: b,\n\t\t});\n\t}\n\tif (a !== null && b !== null && a >= b) {\n\t\tthrowOrderError(\"server:core.documents.order.fractional.bounds.invalid\", {\n\t\t\tlower: a,\n\t\t\tupper: b,\n\t\t});\n\t}\n\n\treturn midpoint(a ?? \"\", b);\n};\n\n/** Checks whether a stored order key is usable. */\nexport const isFractionalOrderKey = (value: unknown): value is string =>\n\ttypeof value === \"string\" && isValidOrderKey(value);\n"],"mappings":"mJAKA,MAAM,EAAS,uCAET,GACL,EAGA,IACW,CACX,MAAM,IAAI,EAAW,CACpB,QAAS,EAAU,EAAK,EAAK,CAAE,MAAK,CAAC,CAAC,EACtC,MAAO,mBACP,MACD,CAAC,CACF,EAEM,EAAmB,GAAyB,CAGjD,GAFI,EAAI,SAAW,GAEf,EAAI,SAAS,EAAO,EAAY,EAAG,MAAO,GAC9C,IAAK,IAAM,KAAQ,EAClB,GAAI,CAAC,EAAO,SAAS,CAAI,EAAG,MAAO,GAEpC,MAAO,EACR,EAGM,GAAY,EAAW,IAA6B,CAQzD,GAPI,IAAM,MAAQ,GAAK,GACtB,EAAgB,wDAAyD,CACxE,MAAO,EACP,MAAO,CACR,CAAC,EAGE,IAAM,KAAM,CAEf,IAAI,EAAe,EACnB,MAAQ,EAAE,OAAO,CAAY,GAAK,EAAO,MAAQ,EAAE,OAAO,CAAY,GACrE,IAED,GAAI,EAAe,EAClB,OACC,EAAE,MAAM,EAAG,CAAY,EACvB,EAAS,EAAE,MAAM,CAAY,EAAG,EAAE,MAAM,CAAY,CAAC,CAGxD,CAEA,IAAM,EAAS,EAAI,EAAO,QAAQ,EAAE,OAAO,CAAC,CAAC,EAAI,EAC3C,EAAS,IAAM,KAAqC,GAA9B,EAAO,QAAQ,EAAE,OAAO,CAAC,CAAC,EAEtD,GAAI,EAAS,EAAS,EAAG,CACxB,IAAM,EAAW,KAAK,MAAM,IAAO,EAAS,EAAO,EACnD,OAAO,EAAO,OAAO,CAAQ,CAC9B,CAQA,OALI,IAAM,MAAQ,EAAE,OAAS,EACrB,EAAE,MAAM,EAAG,CAAC,EAIb,EAAO,OAAO,CAAM,EAAI,EAAS,EAAE,MAAM,CAAC,EAAG,IAAI,CACzD,EAGa,GACZ,EACA,KAEI,IAAM,MAAQ,CAAC,EAAgB,CAAC,GACnC,EAAgB,qDAAsD,CACrE,IAAK,CACN,CAAC,EAEE,IAAM,MAAQ,CAAC,EAAgB,CAAC,GACnC,EAAgB,qDAAsD,CACrE,IAAK,CACN,CAAC,EAEE,IAAM,MAAQ,IAAM,MAAQ,GAAK,GACpC,EAAgB,wDAAyD,CACxE,MAAO,EACP,MAAO,CACR,CAAC,EAGK,EAAS,GAAK,GAAI,CAAC,GAId,EAAwB,GACpC,OAAO,GAAU,UAAY,EAAgB,CAAK"}