{"version":3,"file":"factory-BzxNxynZ.cjs","names":["getIntegerLengthSigned","splitParts","incrementInteger","decrementInteger","getMidpointFractional","isValidFractionalIndex","ensureNotUndefined","generateKeyBetweenUnsafe","generateKeyBetween","generateNKeysBetweenUnsafe","generateNKeysBetween","splitParts","getMidpointFractional","decrementInteger","incrementInteger","generateKeyBetweenBinary","generateNKeysBetweenBinary"],"sources":["../../src/lib/errors.ts","../../src/lib/decimal-string.ts","../../src/lib/decimal-binary.ts","../../src/lib/fractional-indexing-binary.ts","../../src/lib/fractional-indexing-string.ts","../../src/lib/utils.ts","../../src/factory.ts"],"sourcesContent":["/**\n * Error codes for the Fraci library.\n *\n * These codes help identify specific error conditions that may occur during library operations.\n *\n * - `INITIALIZATION_FAILED`: Indicates that the library failed to initialize.\n *   Currently seen when the base string does not meet the requirements, or when the specified model or field does not exist in the generated Prisma client.\n * - `INTERNAL_ERROR`: Indicates an internal error in the library. Please file an issue if you see this.\n * - `INVALID_ARGUMENT`: Indicates that a numeric option or generation argument is outside its supported range.\n * - `INVALID_FRACTIONAL_INDEX`: Indicates that an invalid fractional index was provided to `generateKeyBetween` or `generateNKeysBetween` functions.\n * - `MAX_LENGTH_EXCEEDED`: Indicates that the maximum length of the generated key was exceeded.\n * - `MAX_RETRIES_EXCEEDED`: Indicates that the maximum number of retries was exceeded when generating a key.\n *\n * @see {@link FraciError} - The custom error class for the Fraci library\n */\nexport type FraciErrorCode =\n  | \"INITIALIZATION_FAILED\"\n  | \"INTERNAL_ERROR\"\n  | \"INVALID_ARGUMENT\"\n  | \"INVALID_FRACTIONAL_INDEX\"\n  | \"MAX_LENGTH_EXCEEDED\"\n  | \"MAX_RETRIES_EXCEEDED\";\n\n/**\n * Custom error class for the Fraci library.\n *\n * This class encapsulates errors that occur during fractional indexing operations,\n * providing structured error information through error codes and descriptive messages.\n * Use the utility functions {@link isFraciError} and {@link getFraciErrorCode} to safely work with these errors.\n *\n * @see {@link FraciErrorCode} - The error codes for the Fraci library\n * @see {@link isFraciError} - Type guard to check if an error is a FraciError\n * @see {@link getFraciErrorCode} - Function to extract the error code from a FraciError\n */\nexport class FraciError extends Error {\n  readonly name: \"FraciError\";\n\n  constructor(\n    /**\n     * The specific error code identifying the type of error.\n     */\n    readonly code: FraciErrorCode,\n    /**\n     * A descriptive message providing details about the error condition.\n     */\n    readonly message: string,\n  ) {\n    super(`[${code}] ${message}`);\n\n    this.name = \"FraciError\";\n  }\n}\n\n/**\n * Type guard that checks if the given error is an instance of {@link FraciError}.\n *\n * This is useful in error handling blocks to determine if an error originated from the Fraci library.\n *\n * @param error - The error to check\n * @returns `true` if the error is a {@link FraciError}, `false` otherwise\n *\n * @example\n * ```typescript\n * try {\n *   // Some Fraci operation\n * } catch (error) {\n *   if (isFraciError(error)) {\n *     // Handle Fraci-specific error\n *   } else {\n *     // Handle other types of errors\n *   }\n * }\n * ```\n *\n * @see {@link FraciError} - The custom error class for the Fraci library\n * @see {@link getFraciErrorCode} - Function to extract the error code from a {@link FraciError}\n */\nexport function isFraciError(error: unknown): error is FraciError {\n  return error instanceof FraciError;\n}\n\n/**\n * Extracts the error code from a {@link FraciError}.\n *\n * This function safely extracts the error code without requiring type checking first.\n * If the error is not a {@link FraciError}, it returns `undefined`.\n *\n * @param error - The error to extract the code from\n * @returns The {@link FraciErrorCode} if the error is a {@link FraciError}, `undefined` otherwise\n *\n * @example\n * ```typescript\n * try {\n *   // Some Fraci operation\n * } catch (error) {\n *   switch (getFraciErrorCode(error)) {\n *     case \"MAX_LENGTH_EXCEEDED\":\n *     case \"MAX_RETRIES_EXCEEDED\":\n *       // Handle specific error case\n *       break;\n *\n *     default:\n *       // Handle other cases, including unknown errors\n *       // or Fraci errors that are not handled above\n *       break;\n *   }\n * }\n * ```\n *\n * @see {@link FraciError} - The custom error class for the Fraci library\n * @see {@link FraciErrorCode} - The error codes for the Fraci library\n * @see {@link isFraciError} - Type guard to check if an error is a {@link FraciError}\n */\nexport function getFraciErrorCode(error: unknown): FraciErrorCode | undefined {\n  return error instanceof FraciError ? error.code : undefined;\n}\n","/**\n * Gets the signed length of the integer part from a fractional index.\n * This function extracts the length information encoded in the first character\n * of the index string.\n *\n * @param index - The fractional index string\n * @param lenBaseReverse - Map of length encoding characters to their numeric values\n * @returns The signed length of the integer part, or undefined if the first character is invalid\n */\nexport function getIntegerLengthSigned(\n  index: string,\n  lenBaseReverse: ReadonlyMap<string, number>,\n): number | undefined {\n  return lenBaseReverse.get(index[0]);\n}\n\n/**\n * Splits a fractional index string into its integer and fractional parts.\n * This function uses the length information encoded in the first character\n * to determine where to split the string.\n *\n * @param index - The fractional index string to split\n * @param lenBaseReverse - Map of length encoding characters to their numeric values\n * @returns A tuple containing the integer and fractional parts, or undefined if the index is invalid\n */\nexport function splitParts(\n  index: string,\n  lenBaseReverse: ReadonlyMap<string, number>,\n): [integer: string, fractional: string] | undefined {\n  // Get the encoded length from the first character and convert to absolute value\n  // Add 1 because the length includes the length character itself\n  const intLength =\n    Math.abs(getIntegerLengthSigned(index, lenBaseReverse) ?? 0) + 1;\n\n  // Validation: ensure the length is valid and the string is long enough\n  if (intLength < 2 || index.length < intLength) {\n    // Invalid length or string too short\n    return;\n  }\n\n  // Split the string into integer and fractional parts\n  // The integer part includes the length character and the digits\n  // The fractional part is everything after the integer part\n  return [index.slice(0, intLength), index.slice(intLength)];\n}\n\n/**\n * Generates a string representation of the integer zero.\n * This function creates a string that represents the integer zero\n * in the specified digit base and length encoding.\n *\n * @param digBaseForward - Array mapping digit positions to characters\n * @param lenBaseForward - Map of length values to their encoding characters\n * @returns A string representation of the integer zero\n */\nexport function getIntegerZero(\n  digBaseForward: readonly string[],\n  lenBaseForward: ReadonlyMap<number, string>,\n): string {\n  return lenBaseForward.get(1)! + digBaseForward[0];\n}\n\n/**\n * Generates a string representation of the smallest possible integer.\n * This function finds the smallest length value in the length encoding map\n * and creates a string representing the smallest possible integer.\n *\n * @param digBaseForward - Array mapping digit positions to characters\n * @param lenBaseForward - Map of length values to their encoding characters\n * @returns A string representation of the smallest possible integer\n */\nexport function getSmallestInteger(\n  digBaseForward: readonly string[],\n  lenBaseForward: ReadonlyMap<number, string>,\n): string {\n  // Find the smallest length value in the length encoding map\n  // This will be the most negative value, representing the smallest possible integer\n  const minKey = Math.min(...Array.from(lenBaseForward.keys()));\n\n  // Get the character that encodes this smallest length\n  const minLenChar = lenBaseForward.get(minKey)!;\n\n  // Create a string with the length character followed by the smallest digit repeated\n  // The number of repetitions is the absolute value of the length\n  return `${minLenChar}${digBaseForward[0].repeat(Math.abs(minKey))}`;\n}\n\n/**\n * Increments the integer part of a fractional index.\n * This function handles carrying and length changes when incrementing the integer.\n *\n * @param index - The fractional index string whose integer part should be incremented\n * @param digBaseForward - Array mapping digit positions to characters\n * @param digBaseReverse - Map of digit characters to their numeric values\n * @param lenBaseForward - Map of length values to their encoding characters\n * @param lenBaseReverse - Map of length encoding characters to their numeric values\n * @returns\n *   - A new string with the incremented integer part\n *   - null if the integer cannot be incremented (reached maximum value)\n *   - undefined if the input is invalid\n */\nexport function incrementInteger(\n  index: string,\n  digBaseForward: readonly string[],\n  digBaseReverse: ReadonlyMap<string, number>,\n  lenBaseForward: ReadonlyMap<number, string>,\n  lenBaseReverse: ReadonlyMap<string, number>,\n): string | null | undefined {\n  const intLengthSigned = getIntegerLengthSigned(index, lenBaseReverse);\n  if (!intLengthSigned) {\n    return;\n  }\n\n  const smallestDigit = digBaseForward[0];\n\n  // Extract the length character and the actual digits from the integer part\n  const [lenChar, ...digits] = index.slice(0, Math.abs(intLengthSigned) + 1);\n\n  // Try to increment the rightmost digit first, with carrying if needed\n  // This is similar to adding 1 to a number in the custom base system\n  for (let i = digits.length - 1; i >= 0; i--) {\n    const value = digBaseReverse.get(digits[i]);\n    if (value == null) {\n      // Invalid digit\n      return;\n    }\n\n    if (value < digBaseForward.length - 1) {\n      // No carrying needed - we can increment this digit and return\n      // This is the common case for most increments\n      digits[i] = digBaseForward[value + 1];\n      return `${lenChar}${digits.join(\"\")}`;\n    }\n\n    // This digit is at max value (9 in decimal), set to smallest (0) and continue carrying\n    // We need to carry to the next digit to the left\n    digits[i] = smallestDigit;\n  }\n\n  // Special case: transitioning from negative integers to zero\n  // This is like going from -1 to 0 in decimal, which requires special handling\n  if (intLengthSigned === -1) {\n    // The integer is -1. We need to return 0.\n    // This requires changing the length encoding character\n    return `${lenBaseForward.get(1)!}${smallestDigit}`;\n  }\n\n  // If we get here, we've carried through all digits (like 999 + 1 = 1000)\n  // We need to increase the length of the integer representation\n  const newLenSigned = intLengthSigned + 1;\n  const newLenChar = lenBaseForward.get(newLenSigned);\n  if (!newLenChar) {\n    // Reached the limit of representable integers\n    // This is an edge case where we can't represent a larger integer\n    return null;\n  }\n\n  // Create a new integer with increased length (all digits are smallest digit)\n  // For example, in decimal: 999 + 1 = 1000 (all zeros with a 1 at the start)\n  // But in our system, we encode the length separately\n  return `${newLenChar}${smallestDigit.repeat(Math.abs(newLenSigned))}`;\n}\n\n/**\n * Decrements the integer part of a fractional index.\n * This function handles borrowing and length changes when decrementing the integer.\n *\n * @param index - The fractional index string whose integer part should be decremented\n * @param digBaseForward - Array mapping digit positions to characters\n * @param digBaseReverse - Map of digit characters to their numeric values\n * @param lenBaseForward - Map of length values to their encoding characters\n * @param lenBaseReverse - Map of length encoding characters to their numeric values\n * @returns\n *   - A new string with the decremented integer part\n *   - null if the integer cannot be decremented (reached minimum value)\n *   - undefined if the input is invalid\n */\nexport function decrementInteger(\n  index: string,\n  digBaseForward: readonly string[],\n  digBaseReverse: ReadonlyMap<string, number>,\n  lenBaseForward: ReadonlyMap<number, string>,\n  lenBaseReverse: ReadonlyMap<string, number>,\n): string | null | undefined {\n  const intLengthSigned = getIntegerLengthSigned(index, lenBaseReverse);\n  if (!intLengthSigned) {\n    return;\n  }\n\n  const largestDigit = digBaseForward[digBaseForward.length - 1];\n\n  // Extract the length character and the actual digits from the integer part\n  const [lenChar, ...digits] = index.slice(0, Math.abs(intLengthSigned) + 1);\n\n  // Try to decrement the rightmost digit first, with borrowing if needed\n  // This is similar to subtracting 1 from a number in the custom base system\n  for (let i = digits.length - 1; i >= 0; i--) {\n    const value = digBaseReverse.get(digits[i]);\n    if (value == null) {\n      // Invalid digit\n      return;\n    }\n\n    if (value > 0) {\n      // No borrowing needed - we can decrement this digit and return\n      // This is the common case for most decrements\n      digits[i] = digBaseForward[value - 1];\n      return `${lenChar}${digits.join(\"\")}`;\n    }\n\n    // This digit is at min value (0 in decimal), set to largest (9) and continue borrowing\n    // We need to borrow from the next digit to the left\n    digits[i] = largestDigit;\n  }\n\n  // Special case: transitioning from zero to negative integers\n  // This is like going from 0 to -1 in decimal, which requires special handling\n  if (intLengthSigned === 1) {\n    // The integer is 0. We need to return -1.\n    // This requires changing the length encoding character to represent negative length\n    return `${lenBaseForward.get(-1)!}${largestDigit}`;\n  }\n\n  // If we get here, we've borrowed through all digits (like 1000 - 1 = 999)\n  // We need to decrease the length of the integer representation\n  const newLenSigned = intLengthSigned - 1;\n  const newLenChar = lenBaseForward.get(newLenSigned);\n  if (!newLenChar) {\n    // Reached the limit of representable integers\n    // This is an edge case where we can't represent a smaller integer\n    return null;\n  }\n\n  // Create a new integer with decreased length (all digits are largest digit)\n  // For example, in decimal: 1000 - 1 = 999 (all nines)\n  // But in our system, we encode the length separately\n  return `${newLenChar}${largestDigit.repeat(Math.abs(newLenSigned))}`;\n}\n\n/**\n * Calculates the midpoint between two fractional parts.\n * This function recursively finds a string that sorts between two fractional parts.\n * It handles various cases including when one of the inputs is null.\n *\n * @param a - The lower bound fractional part, or empty string if there is no lower bound\n * @param b - The upper bound fractional part, or null if there is no upper bound\n * @param digBaseForward - Array mapping digit positions to characters\n * @param digBaseReverse - Map of digit characters to their numeric values\n * @returns A string that sorts between a and b, or undefined if inputs are invalid\n */\nexport function getMidpointFractional(\n  a: string,\n  b: string | null,\n  digBaseForward: readonly string[],\n  digBaseReverse: ReadonlyMap<string, number>,\n): string | undefined {\n  if (b != null && b <= a) {\n    // Precondition failed.\n    return;\n  }\n\n  const chunks: string[] = [];\n  let aOffset = 0;\n  let bOffset = 0;\n  let upper = b;\n\n  // Use an iterative implementation so adversarially long, but otherwise valid,\n  // fractional parts cannot exhaust the JavaScript call stack.\n  while (true) {\n    if (upper) {\n      const remainingUpperLength = upper.length - bOffset;\n      let prefixLength = 0;\n      while (\n        prefixLength < remainingUpperLength &&\n        upper[bOffset + prefixLength] ===\n          (a[aOffset + prefixLength] ?? digBaseForward[0])\n      ) {\n        prefixLength++;\n      }\n\n      if (prefixLength > 0) {\n        chunks.push(upper.slice(bOffset, bOffset + prefixLength));\n        aOffset += prefixLength;\n        bOffset += prefixLength;\n        continue;\n      }\n    }\n\n    const aChar = a[aOffset];\n    const bChar = upper?.[bOffset];\n    const aDigit = aChar ? digBaseReverse.get(aChar) : 0;\n    const bDigit = bChar\n      ? digBaseReverse.get(bChar)\n      : upper\n        ? undefined\n        : digBaseForward.length;\n    if (aDigit == null || bDigit == null) {\n      return;\n    }\n\n    if (aDigit + 1 !== bDigit) {\n      chunks.push(digBaseForward[Math.floor((aDigit + bDigit) / 2)]);\n      return chunks.join(\"\");\n    }\n\n    if (upper && upper.length - bOffset > 1) {\n      chunks.push(upper[bOffset]);\n      return chunks.join(\"\");\n    }\n\n    chunks.push(digBaseForward[aDigit]);\n    aOffset++;\n    upper = null;\n    bOffset = 0;\n  }\n}\n","export const INTEGER_ZERO = new Uint8Array([128, 0]);\n\nexport const INTEGER_MINUS_ONE = new Uint8Array([127, 255]);\n\n/**\n * Compares two Uint8Arrays.\n *\n * @param a - The first array\n * @param b - The second array\n * @returns A number indicating the comparison result\n *   - Negative if a < b\n *   - Zero if a == b\n *   - Positive if a > b\n */\nexport function compare(a: Uint8Array, b: Uint8Array): number {\n  const len = Math.min(a.length, b.length);\n  let r = 0;\n  for (let i = 0; !r && i < len; i++) {\n    r = a[i] - b[i];\n  }\n  return r || a.length - b.length;\n}\n\n/**\n * Concatenates two Uint8Arrays.\n *\n * @param a - The first array\n * @param b - The second array\n * @returns The concatenated array\n */\nexport function concat(a: Uint8Array, b: Uint8Array): Uint8Array {\n  const result = new Uint8Array(a.length + b.length);\n  result.set(a);\n  result.set(b, a.length);\n  return result;\n}\n\n/**\n * Gets the signed length of the integer part from a binary fractional index.\n * This function extracts the length information encoded in the first byte of the index string.\n *\n * @param index - The fractional index binary\n * @returns The signed length of the integer part, or NaN if the first character is invalid\n */\nexport function getIntegerLengthSigned(index: Uint8Array): number {\n  const [value] = index;\n  return value - (value >= 128 ? 127 : 128);\n}\n\n/**\n * Gets the byte representing the length of the integer part.\n * Reverse operation of {@link getIntegerLengthSigned}.\n *\n * @param signedLength - The signed length of the integer part\n * @returns The byte representing the length of the integer part\n */\nexport function getIntegerLengthByte(signedLength: number): number {\n  return signedLength + (signedLength < 0 ? 128 : 127);\n}\n\n/**\n * Checks if a binary fractional index represents the smallest possible integer.\n *\n * @param index - The fractional index binary to check\n * @returns A boolean indicating if the index represents the smallest integer\n */\nexport function isSmallestInteger(index: Uint8Array): boolean {\n  return index.length === 129 && index.every((v) => v === 0);\n}\n\n/**\n * Splits a fractional index binary into its integer and fractional parts.\n * This function uses the length information encoded in the first character\n * to determine where to split the binary.\n *\n * @param index - The fractional index binary to split\n * @returns A tuple containing the integer and fractional parts, or undefined if the index is invalid\n */\nexport function splitParts(\n  index: Uint8Array,\n): [integer: Uint8Array, fractional: Uint8Array] | undefined {\n  // Get the encoded length from the first character and convert to absolute value\n  // Add 1 because the length includes the length character itself\n  const intLength = Math.abs(getIntegerLengthSigned(index)) + 1;\n\n  // Validation: ensure the length is valid and the binary is long enough\n  if (Number.isNaN(intLength) || index.length < intLength) {\n    // Invalid length or binary too short\n    return;\n  }\n\n  // Split the string into integer and fractional parts\n  // The integer part includes the length character and the digits\n  // The fractional part is everything after the integer part\n  return [index.subarray(0, intLength), index.subarray(intLength)];\n}\n\n/**\n * Increments the integer part of a fractional index.\n * This function handles carrying and length changes when incrementing the integer.\n *\n * @param index - The fractional index binary whose integer part should be incremented\n * @returns\n *   - A new binary with the incremented integer part\n *   - null if the integer cannot be incremented (reached maximum value)\n *   - undefined if the input is invalid\n */\nexport function incrementInteger(\n  index: Uint8Array,\n): Uint8Array | null | undefined {\n  if (!index.length) {\n    return;\n  }\n\n  const intLengthSigned = getIntegerLengthSigned(index);\n\n  // Extract the length character and the actual digits from the integer part\n  const digits = index.slice(0, Math.abs(intLengthSigned) + 1);\n\n  // Try to increment the rightmost digit first, with carrying if needed\n  // This is similar to adding 1 to a number in the custom base system\n  for (let i = digits.length - 1; i >= 1; i--) {\n    // Increment the digit and check for overflow\n    // Note that Uint8Array wraps around on overflow, which is what we want\n    if (digits[i]++ < 255) {\n      // The digit is not 255 before increment, meaning no overflow will occur\n      // This is the common case for most increments\n      return digits;\n    }\n\n    // Overflow occurred - carry to the next digit to the left\n  }\n\n  // Special case: transitioning from negative to zero\n  // This is like going from -1 to 0 in decimal, which requires special handling\n  if (intLengthSigned === -1) {\n    // The integer is -1. We need to return 0.\n    // This requires changing the length encoding character to represent positive length\n    return INTEGER_ZERO.slice();\n  }\n\n  // If we get here, we've carried through all digits (like 999 + 1 = 1000)\n  // We need to increase the length of the integer representation\n  const newLenSigned = intLengthSigned + 1;\n  if (newLenSigned > 128) {\n    // Reached the limit of representable integers\n    // This is an edge case where we can't represent a larger integer\n    return null;\n  }\n\n  // Create a new integer with increased length (all digits are smallest digit)\n  const newBinary = new Uint8Array(Math.abs(newLenSigned) + 1);\n  newBinary[0] = getIntegerLengthByte(newLenSigned);\n  return newBinary;\n}\n\n/**\n * Decrements the integer part of a fractional index.\n * This function handles borrowing and length changes when decrementing the integer.\n *\n * @param index - The fractional index string whose integer part should be decremented\n * @returns\n *   - A new binary with the decremented integer part\n *   - null if the integer cannot be decremented (reached minimum value)\n *   - undefined if the input is invalid\n */\nexport function decrementInteger(\n  index: Uint8Array,\n): Uint8Array | null | undefined {\n  const intLengthSigned = getIntegerLengthSigned(index);\n  if (Number.isNaN(intLengthSigned)) {\n    return;\n  }\n\n  // Extract the length character and the actual digits from the integer part\n  const digits = index.slice(0, Math.abs(intLengthSigned) + 1);\n\n  // Try to decrement the rightmost digit first, with borrowing if needed\n  // This is similar to subtracting 1 from a number in the custom base system\n  for (let i = digits.length - 1; i >= 1; i--) {\n    // Decrement the digit and check for underflow\n    // Note that Uint8Array wraps around on underflow, which is what we want\n    if (digits[i]--) {\n      // The digit is non-zero before decrement, meaning no underflow will occur\n      return digits;\n    }\n\n    // Underflow occurred - borrow from the next digit to the left\n  }\n\n  // Special case: transitioning from zero to negative integers\n  // This is like going from 0 to -1 in decimal, which requires special handling\n  if (intLengthSigned === 1) {\n    // The integer is 0. We need to return -1.\n    // This requires changing the length encoding character to represent negative length\n    return INTEGER_MINUS_ONE.slice();\n  }\n\n  // If we get here, we've borrowed through all digits (like 1000 - 1 = 999)\n  // We need to decrease the length of the integer representation\n  const newLenSigned = intLengthSigned - 1;\n  if (newLenSigned < -128) {\n    // Reached the limit of representable integers\n    // This is an edge case where we can't represent a smaller integer\n    return null;\n  }\n\n  // Create a new integer with decreased length (all digits are largest digit)\n  const newBinary = new Uint8Array(Math.abs(newLenSigned) + 1).fill(255);\n  newBinary[0] = getIntegerLengthByte(newLenSigned);\n  return newBinary;\n}\n\n/**\n * Calculates the midpoint between two fractional parts.\n * This function recursively finds a string that sorts between two fractional parts.\n * It handles various cases including when one of the inputs is null.\n *\n * @param a - The lower bound fractional part, or empty binary if there is no lower bound\n * @param b - The upper bound fractional part, or null if there is no upper bound\n * @returns A binary that sorts between a and b, or undefined if inputs are invalid\n */\nexport function getMidpointFractional(\n  a: Uint8Array,\n  b: Uint8Array | null,\n): Uint8Array | undefined {\n  if (b != null && compare(a, b) >= 0) {\n    // Precondition failed.\n    return;\n  }\n\n  const result: number[] = [];\n  let aOffset = 0;\n  let bOffset = 0;\n  let upper = b;\n\n  // Avoid recursive concatenation, which can otherwise consume quadratic\n  // allocation and exhaust the stack for long fractional parts.\n  while (true) {\n    if (upper) {\n      const remainingUpperLength = upper.length - bOffset;\n      let prefixLength = 0;\n      while (\n        prefixLength < remainingUpperLength &&\n        upper[bOffset + prefixLength] === (a[aOffset + prefixLength] ?? 0)\n      ) {\n        prefixLength++;\n      }\n\n      if (prefixLength > 0) {\n        for (let i = 0; i < prefixLength; i++) {\n          result.push(upper[bOffset + i]);\n        }\n        aOffset += prefixLength;\n        bOffset += prefixLength;\n        continue;\n      }\n    }\n\n    const aDigit = a[aOffset] ?? 0;\n    const bDigit = upper ? upper[bOffset] : 256;\n    if (bDigit == null) {\n      return;\n    }\n\n    if (aDigit + 1 !== bDigit) {\n      result.push(Math.floor((aDigit + bDigit) / 2));\n      return new Uint8Array(result);\n    }\n\n    if (upper && upper.length - bOffset > 1) {\n      result.push(upper[bOffset]);\n      return new Uint8Array(result);\n    }\n\n    result.push(aDigit);\n    aOffset++;\n    upper = null;\n    bOffset = 0;\n  }\n}\n","import {\n  INTEGER_ZERO,\n  compare,\n  concat,\n  decrementInteger,\n  getMidpointFractional,\n  incrementInteger,\n  isSmallestInteger,\n  splitParts,\n} from \"./decimal-binary.js\";\nimport { FraciError } from \"./errors.js\";\n\n/**\n * Converts a Node.js Buffer to a Uint8Array if necessary.\n * Our library is not compatible with Node.js Buffers due to [the difference of the `slice` method](https://nodejs.org/api/buffer.html#bufslicestart-end).\n *\n * @param value - The value to convert to a Uint8Array\n * @returns The original value as a Uint8Array, or null if the value is null\n */\nfunction forceUint8Array(value: Uint8Array | null): Uint8Array | null {\n  return value?.constructor.name === \"Buffer\"\n    ? new Uint8Array(value.buffer, value.byteOffset, value.length)\n    : value;\n}\n\n/**\n * Validates if a binary is a valid fractional index.\n * A valid fractional index must:\n * - Not be empty or equal to the smallest integer\n * - Have a valid integer part with valid digits\n * - Not have trailing zeros in the fractional part\n * - Contain only valid digits in both integer and fractional parts\n *\n * @param index - The string to validate as a fractional index\n * @returns True if the string is a valid fractional index, false otherwise\n */\nexport function isValidFractionalIndex(index: Uint8Array): boolean {\n  if (!index.length || isSmallestInteger(index)) {\n    // The smallest integer is not a valid fractional index. It must have a fractional part.\n    return false;\n  }\n\n  const parts = splitParts(index);\n  if (!parts) {\n    // Invalid integer length character or the integer part is too short.\n    return false;\n  }\n\n  const [, fractional] = parts;\n  if (fractional?.at(-1) === 0) {\n    // Trailing zeros are not allowed in the fractional part.\n    return false;\n  }\n\n  // All bytes in a Uint8Array are valid by definition (0-255),\n  // so we don't need to check each byte like in the string version\n\n  return true;\n}\n\n/**\n * Ensures a value is not undefined, throwing an error if it is.\n * This is a utility function used to handle unexpected undefined values\n * that should have been validated earlier in the code.\n *\n * @param value - The value to check\n * @returns The original value if it's not undefined\n * @throws {FraciError} Throws a {@link FraciError} when the value is undefined (internal error)\n *\n * @see {@link FraciError} - The custom error class for the Fraci library\n */\nfunction ensureNotUndefined<T>(value: T | undefined): T {\n  if (value === undefined) {\n    // This should not happen as we should have validated the value before.\n    if (globalThis.__DEV__) {\n      console.error(\n        \"FraciError: [INTERNAL_ERROR] Unexpected undefined. Please file an issue to report this error.\",\n      );\n    }\n\n    throw new FraciError(\"INTERNAL_ERROR\", \"Unexpected undefined\");\n  }\n  return value;\n}\n\n/**\n * Generates a key between two existing keys without validation.\n * This internal function handles the core algorithm for creating a fractional index\n * between two existing indices. It assumes inputs are valid and doesn't perform validation.\n *\n * The function handles several cases:\n * - When both a and b are null (first key)\n * - When only a is null (key before b)\n * - When only b is null (key after a)\n * - When both a and b are provided (key between a and b)\n *\n * @param a - The lower bound key, or null if there is no lower bound\n * @param b - The upper bound key, or null if there is no upper bound\n * @returns A new key that sorts between a and b\n */\nfunction generateKeyBetweenUnsafe(\n  a: Uint8Array | null,\n  b: Uint8Array | null,\n): Uint8Array {\n  // Strategy: Handle different cases based on bounds\n  if (!a) {\n    if (!b) {\n      // Case: First key (no bounds)\n      return INTEGER_ZERO.slice();\n    }\n\n    // Case: Key before first key\n    const [bInt, bFrac] = ensureNotUndefined(splitParts(b));\n    if (isSmallestInteger(bInt)) {\n      // Edge case: b is already at the smallest possible integer\n      // We can't decrement the integer part further, so we need to use a fractional part\n      // that sorts before b's fractional part\n      return concat(\n        bInt,\n        ensureNotUndefined(getMidpointFractional(new Uint8Array(), bFrac)),\n      );\n    }\n\n    if (bFrac.length) {\n      // Optimization: If b has a fractional part, we can use just its integer part\n      // This creates a shorter key that still sorts correctly before b\n      return bInt.slice();\n    }\n\n    // Standard case: Decrement the integer part of b\n    const decremented = ensureNotUndefined(\n      decrementInteger(bInt),\n    ) as Uint8Array;\n    if (!isSmallestInteger(decremented)) {\n      return decremented;\n    }\n\n    // Edge case: If we hit the smallest integer, add the largest digit as fractional part\n    // This ensures we still have a valid key that sorts before b\n    const result = new Uint8Array(decremented.length + 1);\n    result.set(decremented);\n    result[decremented.length] = 255;\n    return result;\n  }\n\n  if (!b) {\n    // Case: Key after last key\n    const aParts = ensureNotUndefined(splitParts(a));\n    const [aInt, aFrac] = aParts;\n\n    // Try to increment the integer part first (most efficient)\n    const incremented = ensureNotUndefined(incrementInteger(aInt));\n    if (incremented) {\n      // If we can increment the integer part, use that result\n      // This creates a shorter key than using fractional parts\n      return incremented;\n    }\n\n    // Edge case: We've reached the largest possible integer representation\n    // We need to use the fractional part method instead\n    // Calculate a fractional part that sorts after a's fractional part\n    return concat(aInt, ensureNotUndefined(getMidpointFractional(aFrac, null)));\n  }\n\n  // Case: Key between two existing keys\n  const [aInt, aFrac] = ensureNotUndefined(splitParts(a));\n  const [bInt, bFrac] = ensureNotUndefined(splitParts(b));\n\n  // If both keys have the same integer part, we need to find a fractional part between them\n  if (!compare(aInt, bInt)) {\n    // Calculate the midpoint between the two fractional parts\n    return concat(\n      aInt,\n      ensureNotUndefined(getMidpointFractional(aFrac, bFrac)),\n    );\n  }\n\n  // Try to increment a's integer part\n  const cInt = ensureNotUndefined(incrementInteger(aInt));\n\n  // Two possible outcomes:\n  return cInt && compare(cInt, bInt)\n    ? // 1. If incrementing a's integer doesn't reach b's integer,\n      // we can use the incremented value (shorter key)\n      cInt\n    : // 2. If incrementing a's integer equals b's integer or we can't increment,\n      // we need to use a's integer with a fractional part that sorts after a's fractional part\n      concat(aInt, ensureNotUndefined(getMidpointFractional(aFrac, null)));\n}\n\n/**\n * Generates a key between two existing keys with validation.\n * This function validates the input keys before generating a new key between them.\n * It returns undefined if either key is invalid or if b is less than or equal to a.\n *\n * @param a - The lower bound key, or null if there is no lower bound\n * @param b - The upper bound key, or null if there is no upper bound\n * @returns A new key that sorts between a and b, or undefined if inputs are invalid\n */\nexport function generateKeyBetween(\n  a: Uint8Array | null,\n  b: Uint8Array | null,\n): Uint8Array | undefined {\n  return (a != null && !isValidFractionalIndex(a)) ||\n    (b != null && !isValidFractionalIndex(b)) ||\n    (a != null && b != null && compare(a, b) >= 0)\n    ? undefined\n    : generateKeyBetweenUnsafe(forceUint8Array(a), forceUint8Array(b));\n}\n\n/**\n * Generates multiple keys between two existing keys without validation.\n * This internal function creates n evenly distributed keys between a and b.\n * It uses a recursive divide-and-conquer approach for more even distribution.\n *\n * The function handles several cases:\n * - When n < 1 (returns empty array)\n * - When n = 1 (returns a single key between a and b)\n * - When b is null (generates n keys after a)\n * - When a is null (generates n keys before b)\n * - When both a and b are provided (generates n keys between a and b)\n *\n * @param a - The lower bound key, or null if there is no lower bound\n * @param b - The upper bound key, or null if there is no upper bound\n * @param n - Number of keys to generate\n * @returns An array of n new keys that sort between a and b\n */\nfunction generateNKeysBetweenUnsafe(\n  a: Uint8Array | null,\n  b: Uint8Array | null,\n  n: number,\n): Uint8Array[] {\n  if (n < 1) {\n    return [];\n  }\n\n  if (n === 1) {\n    return [generateKeyBetweenUnsafe(a, b)];\n  }\n\n  // Special case: Generate n keys after a (no upper bound)\n  if (b == null) {\n    let c = a;\n    // Sequential generation - each new key is after the previous one\n    return Array.from(\n      { length: n },\n      () => (c = generateKeyBetweenUnsafe(c, b)),\n    );\n  }\n\n  // Special case: Generate n keys before b (no lower bound)\n  if (a == null) {\n    let c = b;\n    // Sequential generation in reverse - each new key is before the previous one\n    // Then reverse the array to get ascending order\n    return Array.from(\n      { length: n },\n      () => (c = generateKeyBetweenUnsafe(a, c)),\n    ).reverse();\n  }\n\n  const result = Array<Uint8Array>(n);\n\n  const fill = (\n    lower: Uint8Array,\n    upper: Uint8Array,\n    start: number,\n    count: number,\n  ): void => {\n    if (count < 1) {\n      return;\n    }\n\n    const leftCount = Math.floor(count / 2);\n    const position = start + leftCount;\n    const midpoint = generateKeyBetweenUnsafe(lower, upper);\n    result[position] = midpoint;\n    fill(lower, midpoint, start, leftCount);\n    fill(midpoint, upper, position + 1, count - leftCount - 1);\n  };\n\n  fill(a, b, 0, n);\n  return result;\n}\n\n/**\n * Generates multiple keys between two existing keys with validation.\n * This function validates the input keys before generating new keys between them.\n * It returns undefined if either key is invalid or if b is less than or equal to a.\n *\n * @param a - The lower bound key, or null if there is no lower bound\n * @param b - The upper bound key, or null if there is no upper bound\n * @param n - Number of keys to generate\n * @returns An array of n new keys that sort between a and b, or undefined if inputs are invalid\n */\nexport function generateNKeysBetween(\n  a: Uint8Array | null,\n  b: Uint8Array | null,\n  n: number,\n): Uint8Array[] | undefined {\n  return (a != null && !isValidFractionalIndex(a)) ||\n    (b != null && !isValidFractionalIndex(b)) ||\n    (a != null && b != null && compare(a, b) >= 0)\n    ? undefined\n    : generateNKeysBetweenUnsafe(forceUint8Array(a), forceUint8Array(b), n);\n}\n\n/**\n * Generates a suffix to avoid conflicts between fractional indices.\n * This function creates a unique suffix based on the count value,\n * converting it to the specified digit base. The suffix is used to\n * ensure uniqueness when multiple indices need to be generated between\n * the same bounds.\n *\n * @param count - The count value to convert to a suffix\n * @returns A binary suffix in the specified digit base\n */\nexport function avoidConflictSuffix(count: number): Uint8Array {\n  const additionalFrac: number[] = [];\n\n  // Convert a number to a binary representation\n  // This works like converting to a different number base,\n  // but we write the digits in reverse order.\n  //\n  // For example, in binary:\n  // - The number 3 would become [3]\n  // - The number 256 would become [0, 1]\n  // - The number 1234 would become bytes representing 1234 in little-endian\n  //\n  // We do this reversed ordering to ensure the array doesn't end with zeros,\n  // which we need to avoid in fractional indices.\n  while (count > 0) {\n    // Add the byte for the current remainder\n    additionalFrac.push(count & 255);\n    // Integer division to get the next byte\n    count = Math.floor(count / 256);\n  }\n\n  // The result is a unique suffix for each count value\n  return new Uint8Array(additionalFrac);\n}\n","import {\n  decrementInteger,\n  getIntegerZero,\n  getMidpointFractional,\n  incrementInteger,\n  splitParts,\n} from \"./decimal-string.js\";\nimport { FraciError } from \"./errors.js\";\n\n/**\n * Validates if a string is a valid fractional index.\n * A valid fractional index must:\n * - Not be empty or equal to the smallest integer\n * - Have a valid integer part with valid digits\n * - Not have trailing zeros in the fractional part\n * - Contain only valid digits in both integer and fractional parts\n *\n * @param index - The string to validate as a fractional index\n * @param digBaseForward - Array mapping digit positions to characters\n * @param digBaseReverse - Map of digit characters to their numeric values\n * @param lenBaseReverse - Map of length encoding characters to their numeric values\n * @param smallestInteger - The smallest possible integer representation\n * @returns True if the string is a valid fractional index, false otherwise\n */\nexport function isValidFractionalIndex(\n  index: string,\n  digBaseForward: readonly string[],\n  digBaseReverse: ReadonlyMap<string, number>,\n  lenBaseReverse: ReadonlyMap<string, number>,\n  smallestInteger: string,\n): boolean {\n  if (!index || index === smallestInteger) {\n    // The smallest integer is not a valid fractional index. It must have a fractional part.\n    return false;\n  }\n\n  const parts = splitParts(index, lenBaseReverse);\n  if (!parts) {\n    // Invalid integer length character or the integer part is too short.\n    return false;\n  }\n\n  const [integer, fractional] = parts;\n  if (fractional.endsWith(digBaseForward[0])) {\n    // Trailing zeros are not allowed in the fractional part.\n    return false;\n  }\n\n  for (const char of integer.slice(1)) {\n    if (!digBaseReverse.has(char)) {\n      return false;\n    }\n  }\n\n  for (const char of fractional) {\n    if (!digBaseReverse.has(char)) {\n      return false;\n    }\n  }\n\n  return true;\n}\n\n/**\n * Ensures a value is not undefined, throwing an error if it is.\n * This is a utility function used to handle unexpected undefined values\n * that should have been validated earlier in the code.\n *\n * @param value - The value to check\n * @returns The original value if it's not undefined\n * @throws {FraciError} Throws a {@link FraciError} when the value is undefined (internal error)\n *\n * @see {@link FraciError} - The custom error class for the Fraci library\n */\nfunction ensureNotUndefined<T>(value: T | undefined): T {\n  if (value === undefined) {\n    // This should not happen as we should have validated the value before.\n    if (globalThis.__DEV__) {\n      console.error(\n        \"FraciError: [INTERNAL_ERROR] Unexpected undefined. Please file an issue to report this error.\",\n      );\n    }\n\n    throw new FraciError(\"INTERNAL_ERROR\", \"Unexpected undefined\");\n  }\n  return value;\n}\n\n/**\n * Generates a key between two existing keys without validation.\n * This internal function handles the core algorithm for creating a fractional index\n * between two existing indices. It assumes inputs are valid and doesn't perform validation.\n *\n * The function handles several cases:\n * - When both a and b are null (first key)\n * - When only a is null (key before b)\n * - When only b is null (key after a)\n * - When both a and b are provided (key between a and b)\n *\n * @param a - The lower bound key, or null if there is no lower bound\n * @param b - The upper bound key, or null if there is no upper bound\n * @param digBaseForward - Array mapping digit positions to characters\n * @param digBaseReverse - Map of digit characters to their numeric values\n * @param lenBaseForward - Map of length values to their encoding characters\n * @param lenBaseReverse - Map of length encoding characters to their numeric values\n * @param smallestInteger - The smallest possible integer representation\n * @returns A new key that sorts between a and b\n */\nfunction generateKeyBetweenUnsafe(\n  a: string | null,\n  b: string | null,\n  digBaseForward: readonly string[],\n  digBaseReverse: ReadonlyMap<string, number>,\n  lenBaseForward: ReadonlyMap<number, string>,\n  lenBaseReverse: ReadonlyMap<string, number>,\n  smallestInteger: string,\n): string {\n  // Strategy: Handle different cases based on bounds\n  if (!a) {\n    if (!b) {\n      // Case: First key (no bounds)\n      return getIntegerZero(digBaseForward, lenBaseForward);\n    }\n\n    // Case: Key before first key\n    const [bInt, bFrac] = ensureNotUndefined(splitParts(b, lenBaseReverse));\n    if (bInt === smallestInteger) {\n      // Edge case: b is already at the smallest possible integer\n      // We can't decrement the integer part further, so we need to use a fractional part\n      // that sorts before b's fractional part\n      return `${bInt}${ensureNotUndefined(\n        getMidpointFractional(\"\", bFrac, digBaseForward, digBaseReverse),\n      )}`;\n    }\n\n    if (bFrac) {\n      // Optimization: If b has a fractional part, we can use just its integer part\n      // This creates a shorter key that still sorts correctly before b\n      return bInt;\n    }\n\n    // Standard case: Decrement the integer part of b\n    const decremented = ensureNotUndefined(\n      decrementInteger(\n        bInt,\n        digBaseForward,\n        digBaseReverse,\n        lenBaseForward,\n        lenBaseReverse,\n      ),\n    ) as string;\n\n    // Edge case: If we hit the smallest integer, add the largest digit as fractional part\n    // This ensures we still have a valid key that sorts before b\n    return decremented === smallestInteger\n      ? `${decremented}${digBaseForward[digBaseForward.length - 1]}`\n      : decremented;\n  }\n\n  if (!b) {\n    // Case: Key after last key\n    const aParts = ensureNotUndefined(splitParts(a, lenBaseReverse));\n    const [aInt, aFrac] = aParts;\n\n    // Try to increment the integer part first (most efficient)\n    const incremented = ensureNotUndefined(\n      incrementInteger(\n        aInt,\n        digBaseForward,\n        digBaseReverse,\n        lenBaseForward,\n        lenBaseReverse,\n      ),\n    );\n\n    if (incremented !== null) {\n      // If we can increment the integer part, use that result\n      // This creates a shorter key than using fractional parts\n      return incremented;\n    }\n\n    // Edge case: We've reached the largest possible integer representation\n    // We need to use the fractional part method instead\n    // Calculate a fractional part that sorts after a's fractional part\n    return `${aInt}${ensureNotUndefined(\n      getMidpointFractional(aFrac, null, digBaseForward, digBaseReverse),\n    )}`;\n  }\n\n  // Case: Key between two existing keys\n  const aParts = ensureNotUndefined(splitParts(a, lenBaseReverse));\n  const bParts = ensureNotUndefined(splitParts(b, lenBaseReverse));\n  const [aInt, aFrac] = aParts;\n  const [bInt, bFrac] = bParts;\n\n  // If both keys have the same integer part, we need to find a fractional part between them\n  if (aInt === bInt) {\n    // Calculate the midpoint between the two fractional parts\n    return `${aInt}${ensureNotUndefined(\n      getMidpointFractional(aFrac, bFrac, digBaseForward, digBaseReverse),\n    )}`;\n  }\n\n  // Try to increment a's integer part\n  const cInt = ensureNotUndefined(\n    incrementInteger(\n      aInt,\n      digBaseForward,\n      digBaseReverse,\n      lenBaseForward,\n      lenBaseReverse,\n    ),\n  );\n\n  // Two possible outcomes:\n  return cInt !== null && cInt !== bInt\n    ? // 1. If incrementing a's integer doesn't reach b's integer,\n      // we can use the incremented value (shorter key)\n      cInt\n    : // 2. If incrementing a's integer equals b's integer or we can't increment,\n      // we need to use a's integer with a fractional part that sorts after a's fractional part\n      `${aInt}${ensureNotUndefined(\n        getMidpointFractional(aFrac, null, digBaseForward, digBaseReverse),\n      )}`;\n}\n\n/**\n * Generates a key between two existing keys with validation.\n * This function validates the input keys before generating a new key between them.\n * It returns undefined if either key is invalid or if b is less than or equal to a.\n *\n * @param a - The lower bound key, or null if there is no lower bound\n * @param b - The upper bound key, or null if there is no upper bound\n * @param digBaseForward - Array mapping digit positions to characters\n * @param digBaseReverse - Map of digit characters to their numeric values\n * @param lenBaseForward - Map of length values to their encoding characters\n * @param lenBaseReverse - Map of length encoding characters to their numeric values\n * @param smallestInteger - The smallest possible integer representation\n * @returns A new key that sorts between a and b, or undefined if inputs are invalid\n */\nexport function generateKeyBetween(\n  a: string | null,\n  b: string | null,\n  digBaseForward: readonly string[],\n  digBaseReverse: ReadonlyMap<string, number>,\n  lenBaseForward: ReadonlyMap<number, string>,\n  lenBaseReverse: ReadonlyMap<string, number>,\n  smallestInteger: string,\n): string | undefined {\n  return (a != null &&\n    !isValidFractionalIndex(\n      a,\n      digBaseForward,\n      digBaseReverse,\n      lenBaseReverse,\n      smallestInteger,\n    )) ||\n    (b != null &&\n      !isValidFractionalIndex(\n        b,\n        digBaseForward,\n        digBaseReverse,\n        lenBaseReverse,\n        smallestInteger,\n      )) ||\n    (a != null && b != null && b <= a)\n    ? undefined\n    : generateKeyBetweenUnsafe(\n        a,\n        b,\n        digBaseForward,\n        digBaseReverse,\n        lenBaseForward,\n        lenBaseReverse,\n        smallestInteger,\n      );\n}\n\n/**\n * Generates multiple keys between two existing keys without validation.\n * This internal function creates n evenly distributed keys between a and b.\n * It uses a recursive divide-and-conquer approach for more even distribution.\n *\n * The function handles several cases:\n * - When n < 1 (returns empty array)\n * - When n = 1 (returns a single key between a and b)\n * - When b is null (generates n keys after a)\n * - When a is null (generates n keys before b)\n * - When both a and b are provided (generates n keys between a and b)\n *\n * @param a - The lower bound key, or null if there is no lower bound\n * @param b - The upper bound key, or null if there is no upper bound\n * @param n - Number of keys to generate\n * @param args - Array containing the base maps and smallest integer value\n * @returns An array of n new keys that sort between a and b\n */\nfunction generateNKeysBetweenUnsafe(\n  a: string | null,\n  b: string | null,\n  n: number,\n  ...args: [\n    readonly string[],\n    ReadonlyMap<string, number>,\n    ReadonlyMap<number, string>,\n    ReadonlyMap<string, number>,\n    string,\n  ]\n): string[] {\n  if (n < 1) {\n    return [];\n  }\n\n  if (n === 1) {\n    return [generateKeyBetweenUnsafe(a, b, ...args)];\n  }\n\n  // Special case: Generate n keys after a (no upper bound)\n  if (b == null) {\n    let c = a;\n    // Sequential generation - each new key is after the previous one\n    return Array.from(\n      { length: n },\n      () => (c = generateKeyBetweenUnsafe(c, b, ...args)),\n    );\n  }\n\n  // Special case: Generate n keys before b (no lower bound)\n  if (a == null) {\n    let c = b;\n    // Sequential generation in reverse - each new key is before the previous one\n    // Then reverse the array to get ascending order\n    return Array.from(\n      { length: n },\n      () => (c = generateKeyBetweenUnsafe(a, c, ...args)),\n    ).reverse();\n  }\n\n  const result = Array<string>(n);\n\n  const fill = (\n    lower: string,\n    upper: string,\n    start: number,\n    count: number,\n  ): void => {\n    if (count < 1) {\n      return;\n    }\n\n    const leftCount = Math.floor(count / 2);\n    const position = start + leftCount;\n    const midpoint = generateKeyBetweenUnsafe(lower, upper, ...args);\n    result[position] = midpoint;\n    fill(lower, midpoint, start, leftCount);\n    fill(midpoint, upper, position + 1, count - leftCount - 1);\n  };\n\n  fill(a, b, 0, n);\n  return result;\n}\n\n/**\n * Generates multiple keys between two existing keys with validation.\n * This function validates the input keys before generating new keys between them.\n * It returns undefined if either key is invalid or if b is less than or equal to a.\n *\n * @param a - The lower bound key, or null if there is no lower bound\n * @param b - The upper bound key, or null if there is no upper bound\n * @param n - Number of keys to generate\n * @param digBaseForward - Array mapping digit positions to characters\n * @param digBaseReverse - Map of digit characters to their numeric values\n * @param lenBaseForward - Map of length values to their encoding characters\n * @param lenBaseReverse - Map of length encoding characters to their numeric values\n * @param smallestInteger - The smallest possible integer representation\n * @returns An array of n new keys that sort between a and b, or undefined if inputs are invalid\n */\nexport function generateNKeysBetween(\n  a: string | null,\n  b: string | null,\n  n: number,\n  digBaseForward: readonly string[],\n  digBaseReverse: ReadonlyMap<string, number>,\n  lenBaseForward: ReadonlyMap<number, string>,\n  lenBaseReverse: ReadonlyMap<string, number>,\n  smallestInteger: string,\n): string[] | undefined {\n  return (a != null &&\n    !isValidFractionalIndex(\n      a,\n      digBaseForward,\n      digBaseReverse,\n      lenBaseReverse,\n      smallestInteger,\n    )) ||\n    (b != null &&\n      !isValidFractionalIndex(\n        b,\n        digBaseForward,\n        digBaseReverse,\n        lenBaseReverse,\n        smallestInteger,\n      )) ||\n    (a != null && b != null && b <= a)\n    ? undefined\n    : generateNKeysBetweenUnsafe(\n        a,\n        b,\n        n,\n        digBaseForward,\n        digBaseReverse,\n        lenBaseForward,\n        lenBaseReverse,\n        smallestInteger,\n      );\n}\n\n/**\n * Generates a suffix to avoid conflicts between fractional indices.\n * This function creates a unique suffix based on the count value,\n * converting it to the specified digit base. The suffix is used to\n * ensure uniqueness when multiple indices need to be generated between\n * the same bounds.\n *\n * @param count - The count value to convert to a suffix\n * @param digBaseForward - Array mapping digit positions to characters\n * @returns A string suffix in the specified digit base\n */\nexport function avoidConflictSuffix(\n  count: number,\n  digBaseForward: readonly string[],\n): string {\n  // Use the digit base length as the radix for conversion\n  const radix = digBaseForward.length;\n  let additionalFrac = \"\";\n\n  // Convert a number to a string representation using our custom digit base\n  // This works like converting to a different number base (like base-10 or base-16),\n  // but we write the digits in reverse order.\n  //\n  // For example, with digit base \"0123456789\":\n  // - The number 3 would become \"3\"\n  // - The number 10 would become \"01\"\n  // - The number 1234 would become \"4321\"\n  //\n  // We do this reversed ordering to ensure the string doesn't end with zeros,\n  // which we need to avoid in fractional indices.\n  while (count > 0) {\n    // Add the digit for the current remainder\n    additionalFrac += digBaseForward[count % radix];\n    // Integer division to get the next digit\n    count = Math.floor(count / radix);\n  }\n\n  // The result is a unique suffix for each count value\n  return additionalFrac;\n}\n","import { FraciError, type FraciErrorCode } from \"./errors.js\";\n\nconst ERROR_CODE_INITIALIZATION_FAILED =\n  \"INITIALIZATION_FAILED\" satisfies FraciErrorCode;\n\n/**\n * Splits a base string into an array of characters and validates it.\n * This function ensures the base string meets the requirements:\n * - Has at least 4 unique characters\n * - Characters are in ascending order (by character code)\n *\n * @param base - The base string to split and validate\n * @returns An array of characters from the base string\n * @throws {FraciError} Throws a {@link FraciError} when the base string has fewer than 4 unique characters\n * @throws {FraciError} Throws a {@link FraciError} when the base string characters are not unique or not in ascending order\n *\n * @see {@link FraciError} - The custom error class for the Fraci library\n */\nfunction splitBase(base: string): string[] {\n  // Intentionally not using a spread operator to ensure consistent splitting behavior.\n  // That means we don't support strings with surrogate pairs.\n  const forward = base.split(\"\");\n\n  if (forward.length < 4) {\n    // Minimum length requirement ensures the system has enough distinct characters:\n    // - We need at least 2 characters to represent +1 and -1 in integer length bases.\n    // - We need at least 3 characters to calculate the middle of fractional parts.\n    // - An extra character provides additional flexibility.\n    throw new FraciError(\n      ERROR_CODE_INITIALIZATION_FAILED,\n      \"Base string must have at least 4 unique characters\",\n    );\n  }\n\n  // Validate that characters are in strictly ascending order\n  // This is essential for correct sorting behavior in the fractional indexing system\n  let lastCode = -1;\n  for (const char of forward) {\n    const code = char.charCodeAt(0);\n    if (code <= lastCode) {\n      throw new FraciError(\n        ERROR_CODE_INITIALIZATION_FAILED,\n        \"Base string characters must be unique and in ascending order\",\n      );\n    }\n    lastCode = code;\n  }\n\n  return forward;\n}\n\n/**\n * Creates forward and reverse mappings for a digit base.\n * This function converts a base string into a pair of data structures:\n * 1. An array mapping positions to characters\n * 2. A map from characters to their positions\n *\n * @param base - The base string containing unique characters in ascending order\n * @returns A tuple containing the forward array and reverse map\n * @throws {FraciError} Throws a {@link FraciError} when the base string has fewer than 4 unique characters (via {@link splitBase})\n * @throws {FraciError} Throws a {@link FraciError} when the base string characters are not unique or not in ascending order (via {@link splitBase})\n *\n * @see {@link FraciError} - The custom error class for the Fraci library\n */\nexport function createDigitBaseMap(\n  base: string,\n): [forward: readonly string[], reverse: ReadonlyMap<string, number>] {\n  // We always convert characters to an array first to ensure consistent splitting behavior.\n  const forward = splitBase(base);\n\n  return [forward, new Map(forward.map((char, index) => [char, index]))];\n}\n\n/**\n * Creates forward and reverse mappings for integer length encoding.\n * This function converts a base string into a pair of maps:\n * 1. A map from integer lengths to their encoding characters\n * 2. A map from encoding characters to their integer lengths\n *\n * The characters are distributed to represent both positive and negative lengths,\n * with the first half of characters representing negative lengths and the second\n * half representing positive lengths (skipping 0).\n *\n * @param base - The base string containing unique characters in ascending order\n * @returns A tuple containing the forward map (length → char) and reverse map (char → length)\n * @throws {FraciError} Throws a {@link FraciError} when the base string has fewer than 4 unique characters (via {@link splitBase})\n * @throws {FraciError} Throws a {@link FraciError} when the base string characters are not unique or not in ascending order (via {@link splitBase})\n *\n * @see {@link FraciError} - The custom error class for the Fraci library\n */\nexport function createIntegerLengthBaseMap(\n  base: string,\n): [\n  forward: ReadonlyMap<number, string>,\n  reverse: ReadonlyMap<string, number>,\n] {\n  // We always convert characters to an array first to ensure consistent splitting behavior.\n  const forward = splitBase(base);\n\n  // Divide the character set in half to represent negative and positive lengths\n  // This is a key design decision that allows representing both positive and negative integers\n  const positiveBegin = forward.length >> 1; // Fast integer division by 2\n\n  // Map each character to a signed integer length value\n  // The first half of characters map to negative lengths, the second half to positive\n  // Important: We deliberately skip 0 as a length value to simplify the algorithm\n  const forwardEntries = forward.map(\n    (char, index) =>\n      [\n        index < positiveBegin\n          ? // For characters in the first half, assign negative values starting from -1\n            index - positiveBegin // This maps to -1, -2, -3, etc.\n          : // For characters in the second half, assign positive values starting from 1\n            index - positiveBegin + 1, // This maps to 1, 2, 3, etc. (skipping 0)\n        char,\n      ] as const,\n  );\n\n  // Create both forward (length → char) and reverse (char → length) maps\n  // This allows efficient lookups in both directions\n  return [\n    new Map(forwardEntries),\n    new Map(forwardEntries.map(([value, char]) => [char, value])),\n  ];\n}\n","import type {\n  BASE10,\n  BASE16L,\n  BASE16U,\n  BASE26L,\n  BASE26U,\n  BASE36L,\n  BASE36U,\n  BASE52,\n  BASE62,\n  BASE64URL,\n  BASE88,\n  BASE95,\n} from \"./bases.js\";\nimport { getSmallestInteger } from \"./lib/decimal-string.js\";\nimport { FraciError, type FraciErrorCode } from \"./lib/errors.js\";\nimport {\n  generateKeyBetween as generateKeyBetweenBinary,\n  generateNKeysBetween as generateNKeysBetweenBinary,\n} from \"./lib/fractional-indexing-binary.js\";\nimport {\n  generateKeyBetween,\n  generateNKeysBetween,\n} from \"./lib/fractional-indexing-string.js\";\nimport type {\n  AnyBinaryFractionalIndexBase,\n  AnyStringFractionalIndexBase,\n  FractionalIndex,\n  FractionalIndexBase,\n} from \"./lib/types.js\";\nimport { createDigitBaseMap, createIntegerLengthBaseMap } from \"./lib/utils.js\";\n\n/**\n * Default maximum length for fractional index keys.\n */\nexport const DEFAULT_MAX_LENGTH = 50;\n\n/**\n * Default maximum number of retry attempts when generating keys.\n */\nexport const DEFAULT_MAX_RETRIES = 5;\n\n/**\n * Maximum number of keys that can be generated in one call.\n *\n * Returning more keys as one in-memory array is not a safe or practical API.\n * Callers that need more should generate them in bounded batches.\n */\nexport const MAX_GENERATED_KEYS = 1_000_000;\n\nconst ERROR_CODE_INVALID_INPUT =\n  \"INVALID_FRACTIONAL_INDEX\" satisfies FraciErrorCode;\nconst ERROR_MESSAGE_INVALID_INPUT = \"Invalid indices provided\";\n\nconst ERROR_CODE_INVALID_ARGUMENT = \"INVALID_ARGUMENT\" satisfies FraciErrorCode;\n\nconst ERROR_CODE_EXCEEDED_MAX_LENGTH =\n  \"MAX_LENGTH_EXCEEDED\" satisfies FraciErrorCode;\nconst ERROR_MESSAGE_EXCEEDED_MAX_LENGTH = \"Exceeded maximum length\";\n\nconst ERROR_CODE_EXCEEDED_MAX_RETRIES =\n  \"MAX_RETRIES_EXCEEDED\" satisfies FraciErrorCode;\nconst ERROR_MESSAGE_EXCEEDED_MAX_RETRIES = \"Exceeded maximum retries\";\n\ntype IndexPairs<T> =\n  | [T | null, T | null]\n  | [T | null, T]\n  | [T | null, null]\n  | [T, T | null]\n  | [T, T]\n  | [T, null]\n  | [null, T | null]\n  | [null, T]\n  | [null, null];\n\n/**\n * Fractional indexing utility that provides methods for generating ordered keys.\n *\n * @template B - The base configuration defining the encoding strategy\n * @template X - The brand type for the fractional index\n *\n * @see {@link fraci} - The unified factory function for creating fractional indexing utilities\n * @see {@link fraciBinary} - The factory function for creating binary-based fractional indexing utilities\n * @see {@link fraciString} - The factory function for creating string-based fractional indexing utilities\n */\nexport interface Fraci<B extends FractionalIndexBase, X> {\n  /**\n   * The character sets used for representing digits in the fractional index.\n   */\n  readonly base: B;\n\n  /**\n   * The brand type for the fractional index. Does not exist at runtime.\n   *\n   * @internal\n   */\n  readonly brand?: X | undefined;\n\n  /**\n   * Generates a key between two existing keys.\n   * Returns a generator that yields new unique keys between the provided bounds.\n   *\n   * @param a - The lower bound key, or null if there is no lower bound\n   * @param b - The upper bound key, or null if there is no upper bound\n   * @param skip - Non-negative safe integer number of conflict avoidance iterations to skip (default: 0)\n   * @returns A generator yielding fractional index keys\n   * @throws {FraciError} Throws a {@link FraciError} when invalid input is provided\n   * @throws {FraciError} Throws a {@link FraciError} when the generated key exceeds the maximum length\n   *\n   * @see {@link FraciError} - The custom error class for the Fraci library\n   */\n  generateKeyBetween(\n    a: FractionalIndex<B, X> | null,\n    b: FractionalIndex<B, X> | null,\n    skip?: number,\n  ): Generator<FractionalIndex<B, X>, never, unknown>;\n\n  /**\n   * Generates a key between two existing keys.\n   * Returns a generator that yields new unique keys between the provided bounds.\n   *\n   * This is an overload to make the spread operator work with conditional tuples.\n   *\n   * @param a - The lower bound key, or null if there is no lower bound\n   * @param b - The upper bound key, or null if there is no upper bound\n   * @param skip - Non-negative safe integer number of conflict avoidance iterations to skip (default: 0)\n   * @returns A generator yielding fractional index keys\n   * @throws {FraciError} Throws a {@link FraciError} when invalid input is provided\n   * @throws {FraciError} Throws a {@link FraciError} when the generated key exceeds the maximum length\n   *\n   * @see {@link FraciError} - The custom error class for the Fraci library\n   *\n   * @ignore Documentation should be ignored for this overload but should not affect functionality and Intellisense\n   */\n  generateKeyBetween(\n    ...[a, b, skip]:\n      | [...IndexPairs<FractionalIndex<B, X>>]\n      | [...IndexPairs<FractionalIndex<B, X>>, number]\n  ): Generator<FractionalIndex<B, X>, never, unknown>;\n\n  /**\n   * Generates multiple keys evenly distributed between two existing keys.\n   * Returns a generator that yields arrays of new unique keys.\n   *\n   * @param a - The lower bound key, or null if there is no lower bound\n   * @param b - The upper bound key, or null if there is no upper bound\n   * @param n - Number of keys to generate, from 0 through {@link MAX_GENERATED_KEYS}\n   * @param skip - Non-negative safe integer number of conflict avoidance iterations to skip (default: 0)\n   * @returns A generator yielding arrays of fractional index keys\n   * @throws {FraciError} Throws a {@link FraciError} when invalid input is provided\n   * @throws {FraciError} Throws a {@link FraciError} when the generated keys would exceed the maximum length\n   *\n   * @see {@link FraciError} - The custom error class for the Fraci library\n   */\n  generateNKeysBetween(\n    a: FractionalIndex<B, X> | null,\n    b: FractionalIndex<B, X> | null,\n    n: number,\n    skip?: number,\n  ): Generator<FractionalIndex<B, X>[], never, unknown>;\n\n  /**\n   * Generates multiple keys evenly distributed between two existing keys.\n   * Returns a generator that yields arrays of new unique keys.\n   *\n   * This is an overload to make the spread operator work with conditional tuples.\n   *\n   * @param a - The lower bound key, or null if there is no lower bound\n   * @param b - The upper bound key, or null if there is no upper bound\n   * @param n - Number of keys to generate, from 0 through {@link MAX_GENERATED_KEYS}\n   * @param skip - Non-negative safe integer number of conflict avoidance iterations to skip (default: 0)\n   * @returns A generator yielding arrays of fractional index keys\n   * @throws {FraciError} Throws a {@link FraciError} when invalid input is provided\n   * @throws {FraciError} Throws a {@link FraciError} when the generated keys would exceed the maximum length\n   *\n   * @ignore Documentation should be ignored for this overload but should not affect functionality and Intellisense\n   *\n   * @see {@link FraciError} - The custom error class for the Fraci library\n   */\n  generateNKeysBetween(\n    ...[a, b, n, skip]:\n      | [...IndexPairs<FractionalIndex<B, X>>, number]\n      | [...IndexPairs<FractionalIndex<B, X>>, number, number]\n  ): Generator<FractionalIndex<B, X>[], never, unknown>;\n}\n\n/**\n * Type alias for any {@link Fraci} instance with a binary digit base.\n *\n * @see {@link Fraci} - The main fractional indexing utility type\n * @see {@link AnyFraci} - A union type of all fractional index types\n * @see {@link AnyStringFraci} - The type of all string fractional index types\n */\nexport type AnyBinaryFraci = Fraci<AnyBinaryFractionalIndexBase, any>;\n\n/**\n * Type alias for any {@link Fraci} instance with a string digit base.\n *\n * @see {@link Fraci} - The main fractional indexing utility type\n * @see {@link AnyFraci} - A union type of all fractional index types\n * @see {@link AnyBinaryFraci} - The type of all binary fractional index types\n */\nexport type AnyStringFraci = Fraci<AnyStringFractionalIndexBase, any>;\n\n/**\n * Type alias for any {@link Fraci} instance with any digit base, length base, and brand.\n * This is useful for cases where the specific parameters don't matter.\n *\n * @see {@link Fraci} - The main fractional indexing utility type\n * @see {@link AnyBinaryFraci} - The type of all binary fractional index types\n * @see {@link AnyStringFraci} - The type of all string fractional index types\n */\nexport type AnyFraci = AnyBinaryFraci | AnyStringFraci;\n\n/**\n * Base options for fractional indexing.\n *\n * This type serves as the base type for the `B` template parameter in the {@link Fraci} type,\n * defining the encoding strategy used by the index.\n *\n * @see {@link FraciOptions} - The main configuration options for fractional indexing\n * @see {@link FraciOptionsBaseToBase} - The type alias for converting options to a more specific type\n */\nexport type FraciOptionsBase =\n  | {\n      /**\n       * The type discriminator identifying this as a string fractional index configuration.\n       *\n       * Must be \"string\" or `undefined` for string fractional indices.\n       */\n      readonly type?: \"string\" | undefined;\n\n      /**\n       * The character set used for encoding the length of the integer part.\n       *\n       * This determines what characters are used to represent the length of the integer\n       * portion of the fractional index. Characters must be in ascending lexicographic order.\n       *\n       * The first character of a fractional index comes from this character set.\n       *\n       * @see {@link BASE10}, {@link BASE16L}, {@link BASE16U}, {@link BASE26L}, {@link BASE26U}, {@link BASE36L}, {@link BASE36U}, {@link BASE52}, {@link BASE62}, {@link BASE64URL}, {@link BASE88}, {@link BASE95}\n       */\n      readonly lengthBase: string;\n\n      /**\n       * The character set used for representing digits in the fractional index.\n       *\n       * These characters form the ordered set used to encode the actual index values,\n       * and must be in ascending lexicographic order.\n       *\n       * The second and all subsequent characters of a fractional index come from this character set.\n       *\n       * @see {@link BASE10}, {@link BASE16L}, {@link BASE16U}, {@link BASE26L}, {@link BASE26U}, {@link BASE36L}, {@link BASE36U}, {@link BASE52}, {@link BASE62}, {@link BASE64URL}, {@link BASE88}, {@link BASE95}\n       */\n      readonly digitBase: string;\n    }\n  | {\n      /**\n       * The type discriminator identifying this as a binary fractional index configuration.\n       *\n       * Must be \"binary\" for binary fractional indices.\n       */\n      readonly type: \"binary\";\n    };\n\n/**\n * Type alias for converting the options to a more specific type.\n *\n * @template B - The base configuration defining the encoding strategy\n *\n * @see {@link FraciOptionsBase} - The base options for fractional indexing\n * @see {@link FractionalIndexBase} - The base configuration for fractional indices\n */\nexport type FraciOptionsBaseToBase<B extends FraciOptionsBase> = B extends {\n  readonly lengthBase: string;\n  readonly digitBase: string;\n}\n  ? {\n      /**\n       * The type discriminator identifying this as a string fractional index configuration.\n       */\n      readonly type: \"string\";\n\n      /**\n       * The character set used for encoding the length of the integer part.\n       *\n       * This determines what characters are used to represent the length of the integer\n       * portion of the fractional index. Characters must be in ascending lexicographic order.\n       *\n       * The first character of a fractional index comes from this character set.\n       *\n       * @see {@link BASE10}, {@link BASE16L}, {@link BASE16U}, {@link BASE26L}, {@link BASE26U}, {@link BASE36L}, {@link BASE36U}, {@link BASE52}, {@link BASE62}, {@link BASE64URL}, {@link BASE88}, {@link BASE95}\n       */\n      readonly lengthBase: B[\"lengthBase\"];\n\n      /**\n       * The character set used for representing digits in the fractional index.\n       *\n       * These characters form the ordered set used to encode the actual index values,\n       * and must be in ascending lexicographic order.\n       *\n       * The second and all subsequent characters of a fractional index come from this character set.\n       *\n       * @see {@link BASE10}, {@link BASE16L}, {@link BASE16U}, {@link BASE26L}, {@link BASE26U}, {@link BASE36L}, {@link BASE36U}, {@link BASE52}, {@link BASE62}, {@link BASE64URL}, {@link BASE88}, {@link BASE95}\n       */\n      readonly digitBase: B[\"digitBase\"];\n    }\n  : {\n      /**\n       * The type discriminator identifying this as a binary fractional index configuration.\n       */\n      readonly type: \"binary\";\n    };\n\n/**\n * Configuration options for creating fractional indexing utilities.\n *\n * @template B - The base configuration defining the encoding strategy\n *\n * @see {@link fraci} - The unified factory function for creating fractional indexing utilities\n * @see {@link FraciOptionsBase} - The base options for fractional indexing\n * @see {@link BinaryFraciOptions} - The options for binary fractional indexing\n * @see {@link StringFraciOptions} - The options for string fractional indexing\n */\nexport type FraciOptions<B extends FraciOptionsBase> = B & {\n  /**\n   * Maximum allowed length for generated keys. Must be a positive safe integer.\n   * @default DEFAULT_MAX_LENGTH (50)\n   */\n  readonly maxLength?: number | undefined;\n\n  /**\n   * Maximum number of retry attempts when generating keys. Must be a positive\n   * safe integer or `Infinity`.\n   * @default DEFAULT_MAX_RETRIES (5)\n   */\n  readonly maxRetries?: number | undefined;\n};\n\n/**\n * Base configuration for creating string-based fractional indexing utilities.\n *\n * Defines the configuration for fractional indices represented using binary encoding,\n * where indices are stored as byte arrays (`Uint8Array`).\n *\n * Binary indices generally provide more compact storage and efficient comparison operations\n * compared to string-based alternatives.\n *\n * @see {@link FraciOptions} - The main configuration options for fractional indexing\n * @see {@link StringFraciOptions} - The options for string fractional indexing\n */\nexport type BinaryFraciOptions = FraciOptions<{\n  /**\n   * The type discriminator identifying this as a binary fractional index configuration.\n   */\n  readonly type: \"binary\";\n}>;\n\n/**\n * Base configuration for creating string-based fractional indexing utilities.\n *\n * Defines the configuration for fractional indices represented using string encoding,\n * where indices are stored as human-readable strings using specified character sets.\n *\n * String indices are useful when human readability or sortability in standard string\n * contexts (like databases) is required.\n *\n * @see {@link FraciOptions} - The main configuration options for fractional indexing\n * @see {@link BinaryFraciOptions} - The options for binary fractional indexing\n */\nexport type StringFraciOptions = FraciOptions<{\n  /**\n   * The type discriminator identifying this as a string fractional index configuration.\n   */\n  readonly type?: \"string\" | undefined;\n\n  /**\n   * The character set used for encoding the length of the integer part.\n   *\n   * This determines what characters are used to represent the length of the integer\n   * portion of the fractional index. Characters must be in ascending lexicographic order.\n   *\n   * The first character of a fractional index comes from this character set.\n   *\n   * @see {@link BASE10}, {@link BASE16L}, {@link BASE16U}, {@link BASE26L}, {@link BASE26U}, {@link BASE36L}, {@link BASE36U}, {@link BASE52}, {@link BASE62}, {@link BASE64URL}, {@link BASE88}, {@link BASE95}\n   */\n  readonly lengthBase: string;\n\n  /**\n   * The character set used for representing digits in the fractional index.\n   *\n   * These characters form the ordered set used to encode the actual index values,\n   * and must be in ascending lexicographic order.\n   *\n   * The second and all subsequent characters of a fractional index come from this character set.\n   *\n   * @see {@link BASE10}, {@link BASE16L}, {@link BASE16U}, {@link BASE26L}, {@link BASE26U}, {@link BASE36L}, {@link BASE36U}, {@link BASE52}, {@link BASE62}, {@link BASE64URL}, {@link BASE88}, {@link BASE95}\n   */\n  readonly digitBase: string;\n}>;\n\n/**\n * Type alias to represent options that can be branded.\n *\n * @template T - The base options type\n * @template X - The brand type\n */\ntype BrandableOptions<T, X> = T & {\n  /**\n   * The brand type for the fractional index.\n   */\n  readonly brand?: X | undefined;\n};\n\n/**\n * Cache for storing computed values to improve performance.\n * Uses a branded type pattern to prevent accidental misuse.\n *\n * @see {@link createFraciCache} - Function to create a new cache\n */\nexport type FraciCache = Map<string, unknown> & { readonly __fraci__: never };\n\n/**\n * Creates a new empty {@link FraciCache} for storing computed values in string-based fractional indexing operations.\n * Using a cache can improve initialization performance when repeatedly using the same base configurations.\n *\n * @returns A new empty FraciCache instance\n *\n * @example\n * ```typescript\n * const cache = createFraciCache();\n * const fraci1 = fraciString({ brand: \"a\", lengthBase: \"abcdefghij\", digitBase: \"0123456789\" }, cache);\n * const fraci2 = fraciString({ brand: \"b\", lengthBase: \"abcdefghij\", digitBase: \"0123456789\" }, cache);\n * // Both instances will share cached computations\n * ```\n */\nexport function createFraciCache(): FraciCache {\n  return new Map() as FraciCache;\n}\n\n/**\n * Retrieves a value from cache or computes it if not present.\n *\n * @template T - The type of the value to cache\n *\n * @param cache - The cache to use, or undefined to bypass caching\n * @param key - The cache key to look up\n * @param fn - Function to execute if the value is not in the cache\n * @returns The cached or newly computed value\n */\nfunction withCache<T>(\n  cache: FraciCache | undefined,\n  key: string,\n  fn: () => T,\n): T {\n  // If no cache is provided, just compute the value directly\n  if (!cache) {\n    return fn();\n  }\n\n  // Try to get the value from the cache\n  let value = cache.get(key) as T | undefined;\n  if (value === undefined) {\n    // Value not found in cache, compute it\n    value = fn();\n    // Store in cache for future use\n    cache.set(key, value);\n  }\n\n  return value;\n}\n\nfunction logInvalidInputError(\n  a: string | Uint8Array | null,\n  b: string | Uint8Array | null,\n  skip: number,\n): void {\n  if (globalThis.__DEV__) {\n    console.error(\n      `FraciError: [INVALID_FRACTIONAL_INDEX] ${ERROR_MESSAGE_INVALID_INPUT}. a = ${a}, b = ${b}, skip = ${skip}\nMake sure that\n- Fractional indices generated by the same fraci instance with the same configuration are being used as-is\n- Indices in different groups have not been mixed up\n- a (the first argument item) comes before b (the second argument item) in the group\nFile an issue if you use the library correctly and still encounter this error.`,\n    );\n  }\n}\n\nfunction assertPositiveSafeInteger(value: number, name: \"maxLength\"): void {\n  if (!Number.isSafeInteger(value) || value < 1) {\n    throw new FraciError(\n      ERROR_CODE_INVALID_ARGUMENT,\n      `${name} must be a positive safe integer`,\n    );\n  }\n}\n\nfunction assertPositiveSafeIntegerOrInfinity(\n  value: number,\n  name: \"maxRetries\",\n): void {\n  if (\n    value !== Number.POSITIVE_INFINITY &&\n    (!Number.isSafeInteger(value) || value < 1)\n  ) {\n    throw new FraciError(\n      ERROR_CODE_INVALID_ARGUMENT,\n      `${name} must be a positive safe integer or Infinity`,\n    );\n  }\n}\n\nfunction assertNonNegativeSafeInteger(value: number, name: \"n\" | \"skip\"): void {\n  if (!Number.isSafeInteger(value) || value < 0) {\n    throw new FraciError(\n      ERROR_CODE_INVALID_ARGUMENT,\n      `${name} must be a non-negative safe integer`,\n    );\n  }\n}\n\nfunction assertGenerationCount(value: number): void {\n  assertNonNegativeSafeInteger(value, \"n\");\n  if (value > MAX_GENERATED_KEYS) {\n    throw new FraciError(\n      ERROR_CODE_INVALID_ARGUMENT,\n      `n must be less than or equal to ${MAX_GENERATED_KEYS}`,\n    );\n  }\n}\n\nfunction validateOptions(maxLength: number, maxRetries: number): void {\n  assertPositiveSafeInteger(maxLength, \"maxLength\");\n  assertPositiveSafeIntegerOrInfinity(maxRetries, \"maxRetries\");\n}\n\nfunction retryCount(iteration: number, skip: number): number {\n  const count = iteration + skip;\n  assertNonNegativeSafeInteger(count, \"skip\");\n  return count;\n}\n\nfunction assertInputLengths(\n  a: { readonly length: number } | null,\n  b: { readonly length: number } | null,\n  maxLength: number,\n): void {\n  if (\n    (a != null && a.length > maxLength) ||\n    (b != null && b.length > maxLength)\n  ) {\n    throw new FraciError(\n      ERROR_CODE_EXCEEDED_MAX_LENGTH,\n      ERROR_MESSAGE_EXCEEDED_MAX_LENGTH,\n    );\n  }\n}\n\nfunction retryDirections(count: number): string {\n  const stage = Math.floor(Math.log2(count));\n  const stageStart = 2n ** BigInt(stage);\n  const offset = BigInt(count) - stageStart;\n  const denominatorPower = 2 * stage + 1;\n  const denominator = 2n ** BigInt(denominatorPower);\n\n  // Allocate each power-of-two stage a disjoint interval approaching 1.\n  // Within a stage, consecutive counts occupy consecutive dyadic points.\n  const target = denominator - 2n ** BigInt(stage + 1) + offset + 1n;\n  let lower = 0n;\n  let upper = denominator;\n  let directions = \"\";\n\n  while (true) {\n    const midpoint = (lower + upper) / 2n;\n    if (target === midpoint) {\n      return directions;\n    }\n\n    if (target < midpoint) {\n      directions += \"0\";\n      upper = midpoint;\n    } else {\n      directions += \"1\";\n      lower = midpoint;\n    }\n  }\n}\n\n/**\n * Selects a stable node from the binary subdivision tree of (base, upper).\n * Count zero preserves the original midpoint. Positive counts map to a\n * strictly increasing dyadic sequence, giving O(log count) conflict retries\n * that are distinct and remain strictly inside the requested interval.\n */\nfunction generateRetryKey<T>(\n  base: T,\n  upper: T | null,\n  count: number,\n  generateBetween: (a: T, b: T | null) => T | undefined,\n): T {\n  if (count === 0) {\n    return base;\n  }\n\n  let lower = base;\n  let currentUpper = upper;\n  let candidate = generateBetween(lower, currentUpper);\n  if (candidate === undefined) {\n    throw new FraciError(\"INTERNAL_ERROR\", \"Unexpected undefined\");\n  }\n\n  for (const direction of retryDirections(count)) {\n    if (direction === \"0\") {\n      currentUpper = candidate;\n    } else {\n      lower = candidate;\n    }\n\n    candidate = generateBetween(lower, currentUpper);\n    if (candidate === undefined) {\n      throw new FraciError(\"INTERNAL_ERROR\", \"Unexpected undefined\");\n    }\n  }\n\n  return candidate;\n}\n\nfunction generateRetryKeys<T>(\n  base: readonly T[],\n  upper: T | null,\n  count: number,\n  generateBetween: (a: T, b: T | null) => T | undefined,\n): T[] {\n  if (count === 0) {\n    return [...base];\n  }\n\n  return base.map((value, index) =>\n    generateRetryKey(value, base[index + 1] ?? upper, count, generateBetween),\n  );\n}\n\n/**\n * Creates a binary-based fractional indexing utility with the specified configuration.\n *\n * @template X - The brand type for the fractional index\n *\n * @param options - Configuration options for the fractional indexing utility\n * @returns A binary-based fractional indexing utility instance\n *\n * @example\n * ```typescript\n * // Create a binary-based fractional indexing utility\n * const binaryFraci = fraciBinary({ brand: \"exampleIndex\" });\n *\n * // Generate a key between null and null (first key)\n * const [key1] = binaryFraci.generateKeyBetween(null, null);\n * // Generate a key between key1 and null (key after key1)\n * const [key2] = binaryFraci.generateKeyBetween(key1, null);\n * // Generate a key between key1 and key2\n * const [key3] = binaryFraci.generateKeyBetween(key1, key2);\n * ```\n *\n * @see {@link Fraci} - The main fractional indexing utility type\n * @see {@link BinaryFraciOptions} - The options for the binary fractional indexing utility\n * @see {@link fraci} - The unified factory function for creating fractional indexing utilities\n * @see {@link fraciString} - The factory function for creating string-based fractional indexing utilities\n */\nexport function fraciBinary<const X = unknown>({\n  maxLength = DEFAULT_MAX_LENGTH,\n  maxRetries = DEFAULT_MAX_RETRIES,\n}: BrandableOptions<\n  Omit<BinaryFraciOptions, \"type\"> & { readonly type?: \"binary\" | undefined },\n  X\n> = {}): Fraci<AnyBinaryFractionalIndexBase, X> {\n  type F = FractionalIndex<AnyBinaryFractionalIndexBase, X>;\n  validateOptions(maxLength, maxRetries);\n\n  return {\n    base: { type: \"binary\" },\n    *generateKeyBetween(a: F | null, b: F | null, skip = 0) {\n      assertNonNegativeSafeInteger(skip, \"skip\");\n      assertInputLengths(a, b, maxLength);\n      // Generate the base key between a and b (without conflict avoidance)\n      const base = generateKeyBetweenBinary(a, b);\n      if (!base) {\n        // Logic Error. Should not happen if a and b are valid (i.e. generated by this library with same lengthBase and digitBase).\n        if (globalThis.__DEV__) {\n          logInvalidInputError(a, b, skip);\n        }\n        throw new FraciError(\n          ERROR_CODE_INVALID_INPUT,\n          ERROR_MESSAGE_INVALID_INPUT,\n        );\n      }\n\n      // Generate stable, distinct candidates within the original interval.\n      for (let i = 0; i < maxRetries; i++) {\n        const value = generateRetryKey(\n          base,\n          b,\n          retryCount(i, skip),\n          generateKeyBetweenBinary,\n        );\n        if (value.length > maxLength) {\n          throw new FraciError(\n            ERROR_CODE_EXCEEDED_MAX_LENGTH,\n            ERROR_MESSAGE_EXCEEDED_MAX_LENGTH,\n          );\n        }\n        yield value as F;\n      }\n\n      // If we reach here, it means we exceeded the maximum retries\n      throw new FraciError(\n        ERROR_CODE_EXCEEDED_MAX_RETRIES,\n        ERROR_MESSAGE_EXCEEDED_MAX_RETRIES,\n      );\n    },\n    *generateNKeysBetween(a: F | null, b: F | null, n: number, skip = 0) {\n      assertGenerationCount(n);\n      assertNonNegativeSafeInteger(skip, \"skip\");\n      assertInputLengths(a, b, maxLength);\n      // Generate n base keys between a and b (without conflict avoidance)\n      const base = generateNKeysBetweenBinary(a, b, n);\n      if (!base) {\n        // Logic Error. Should not happen if a and b are valid (i.e. generated by this library with same lengthBase and digitBase).\n        if (globalThis.__DEV__) {\n          logInvalidInputError(a, b, skip);\n        }\n        throw new FraciError(\n          ERROR_CODE_INVALID_INPUT,\n          ERROR_MESSAGE_INVALID_INPUT,\n        );\n      }\n\n      for (let i = 0; i < maxRetries; i++) {\n        const values = generateRetryKeys(\n          base,\n          b,\n          retryCount(i, skip),\n          generateKeyBetweenBinary,\n        );\n        if (values.some((value) => value.length > maxLength)) {\n          throw new FraciError(\n            ERROR_CODE_EXCEEDED_MAX_LENGTH,\n            ERROR_MESSAGE_EXCEEDED_MAX_LENGTH,\n          );\n        }\n        yield values as F[];\n      }\n\n      // If we reach here, it means we exceeded the maximum retries\n      throw new FraciError(\n        ERROR_CODE_EXCEEDED_MAX_RETRIES,\n        ERROR_MESSAGE_EXCEEDED_MAX_RETRIES,\n      );\n    },\n  };\n}\n\n/**\n * Creates a string-based fractional indexing utility with the specified configuration.\n *\n * @template B - The base configuration defining the character sets\n * @template X - The brand type for the fractional index\n *\n * @param options - Configuration options for the fractional indexing utility\n * @param cache - Optional cache to improve performance by reusing computed values\n * @returns A string-based fractional indexing utility instance\n * @throws {FraciError} Throws a {@link FraciError} when the digit or length base strings are invalid\n *\n * @example\n * ```typescript\n * // Create a decimal-based fractional indexing utility\n * const decimalFraci = fraciString({\n *   brand: \"exampleIndex\",\n *   lengthBase: \"abcdefghij\",\n *   digitBase: \"0123456789\",\n * });\n *\n * // Generate a key between null and null (first key)\n * const [key1] = decimalFraci.generateKeyBetween(null, null);\n * // Generate a key between key1 and null (key after key1)\n * const [key2] = decimalFraci.generateKeyBetween(key1, null);\n * // Generate a key between key1 and key2\n * const [key3] = decimalFraci.generateKeyBetween(key1, key2);\n * ```\n *\n * @see {@link Fraci} - The main fractional indexing utility type\n * @see {@link StringFraciOptions} - The options for the string fractional indexing utility\n * @see {@link FraciCache} - The cache for storing computed values\n * @see {@link fraci} - The unified factory function for creating fractional indexing utilities\n * @see {@link fraciBinary} - The factory function for creating binary-based fractional indexing utilities\n * @see {@link FraciError} - The custom error class for the Fraci library\n */\nexport function fraciString<\n  const B extends StringFraciOptions,\n  const X = unknown,\n>(\n  {\n    lengthBase,\n    digitBase,\n    maxLength = DEFAULT_MAX_LENGTH,\n    maxRetries = DEFAULT_MAX_RETRIES,\n  }: BrandableOptions<B, X>,\n  cache?: FraciCache,\n): Fraci<FraciOptionsBaseToBase<B>, X> {\n  type F = FractionalIndex<FraciOptionsBaseToBase<B>, X>;\n  validateOptions(maxLength, maxRetries);\n\n  // Create and potentially cache the digit and length base maps\n  // This optimization avoids recreating these maps when using the same bases multiple times\n  const [lenBaseForward, lenBaseReverse] = withCache(\n    cache,\n    `L${lengthBase}`,\n    createIntegerLengthBaseMap.bind(null, lengthBase),\n  );\n  const [digBaseForward, digBaseReverse] = withCache(\n    cache,\n    `D${digitBase}`,\n    createDigitBaseMap.bind(null, digitBase),\n  );\n  const smallestInteger = getSmallestInteger(digBaseForward, lenBaseForward);\n\n  return {\n    base: {\n      type: \"string\",\n      lengthBase,\n      digitBase,\n    } as FraciOptionsBaseToBase<B>,\n    *generateKeyBetween(a: F | null, b: F | null, skip = 0) {\n      assertNonNegativeSafeInteger(skip, \"skip\");\n      assertInputLengths(a, b, maxLength);\n      // Generate the base key between a and b (without conflict avoidance)\n      const base = generateKeyBetween(\n        a,\n        b,\n        digBaseForward,\n        digBaseReverse,\n        lenBaseForward,\n        lenBaseReverse,\n        smallestInteger,\n      );\n      if (!base) {\n        // Logic Error. Should not happen if a and b are valid (i.e. generated by this library with same lengthBase and digitBase).\n        if (globalThis.__DEV__) {\n          logInvalidInputError(a, b, skip);\n        }\n        throw new FraciError(\n          ERROR_CODE_INVALID_INPUT,\n          ERROR_MESSAGE_INVALID_INPUT,\n        );\n      }\n\n      // Generate stable, distinct candidates within the original interval.\n      for (let i = 0; i < maxRetries; i++) {\n        const value = generateRetryKey(\n          base,\n          b,\n          retryCount(i, skip),\n          (lower, upper) =>\n            generateKeyBetween(\n              lower,\n              upper,\n              digBaseForward,\n              digBaseReverse,\n              lenBaseForward,\n              lenBaseReverse,\n              smallestInteger,\n            ),\n        );\n        if (value.length > maxLength) {\n          throw new FraciError(\n            ERROR_CODE_EXCEEDED_MAX_LENGTH,\n            ERROR_MESSAGE_EXCEEDED_MAX_LENGTH,\n          );\n        }\n        yield value as F;\n      }\n\n      // If we reach here, it means we exceeded the maximum retries\n      throw new FraciError(\n        ERROR_CODE_EXCEEDED_MAX_RETRIES,\n        ERROR_MESSAGE_EXCEEDED_MAX_RETRIES,\n      );\n    },\n    *generateNKeysBetween(a: F | null, b: F | null, n: number, skip = 0) {\n      assertGenerationCount(n);\n      assertNonNegativeSafeInteger(skip, \"skip\");\n      assertInputLengths(a, b, maxLength);\n      // Generate n base keys between a and b (without conflict avoidance)\n      const base = generateNKeysBetween(\n        a,\n        b,\n        n,\n        digBaseForward,\n        digBaseReverse,\n        lenBaseForward,\n        lenBaseReverse,\n        smallestInteger,\n      );\n      if (!base) {\n        // Logic Error. Should not happen if a and b are valid (i.e. generated by this library with same lengthBase and digitBase).\n        if (globalThis.__DEV__) {\n          logInvalidInputError(a, b, skip);\n        }\n        throw new FraciError(\n          ERROR_CODE_INVALID_INPUT,\n          ERROR_MESSAGE_INVALID_INPUT,\n        );\n      }\n\n      for (let i = 0; i < maxRetries; i++) {\n        const values = generateRetryKeys(\n          base,\n          b,\n          retryCount(i, skip),\n          (lower, upper) =>\n            generateKeyBetween(\n              lower,\n              upper,\n              digBaseForward,\n              digBaseReverse,\n              lenBaseForward,\n              lenBaseReverse,\n              smallestInteger,\n            ),\n        );\n        if (values.some((value) => value.length > maxLength)) {\n          throw new FraciError(\n            ERROR_CODE_EXCEEDED_MAX_LENGTH,\n            ERROR_MESSAGE_EXCEEDED_MAX_LENGTH,\n          );\n        }\n        yield values as F[];\n      }\n\n      // If we reach here, it means we exceeded the maximum retries\n      throw new FraciError(\n        ERROR_CODE_EXCEEDED_MAX_RETRIES,\n        ERROR_MESSAGE_EXCEEDED_MAX_RETRIES,\n      );\n    },\n  };\n}\n\n/**\n * **We recommend using {@link fraciBinary} or {@link fraciString} directly to reduce bundle size whenever possible.**\n *\n * Creates a fractional indexing utility with the specified configuration.\n * This is the main factory function for creating a {@link Fraci} instance that can generate\n * fractional indices between existing values.\n *\n * @template B - The base configuration defining the encoding strategy\n * @template X - The brand type for the fractional index\n *\n * @param options - Configuration options for the fractional indexing utility\n * @param cache - Optional cache to improve performance by reusing computed values\n * @returns A fractional indexing utility instance\n * @throws {FraciError} Throws a {@link FraciError} when the digit or length base strings are invalid\n *\n * @example\n * ```typescript\n * // Create a decimal-based fractional indexing utility\n * const decimalFraci = fraci({\n *   brand: \"exampleIndex\",\n *   lengthBase: \"abcdefghij\",\n *   digitBase: \"0123456789\",\n * });\n *\n * // Generate a key between null and null (first key)\n * const [key1] = decimalFraci.generateKeyBetween(null, null);\n * // Generate a key between key1 and null (key after key1)\n * const [key2] = decimalFraci.generateKeyBetween(key1, null);\n * // Generate a key between key1 and key2\n * const [key3] = decimalFraci.generateKeyBetween(key1, key2);\n * ```\n *\n * @see {@link Fraci} - The main fractional indexing utility type\n * @see {@link fraciBinary} - The factory function for creating binary-based fractional indexing utilities\n * @see {@link fraciString} - The factory function for creating string-based fractional indexing utilities\n * @see {@link FraciError} - The custom error class for the Fraci library\n */\nexport function fraci<const B extends FraciOptionsBase, const X = unknown>(\n  options: FraciOptions<B> | (FraciOptions<B> & { readonly brand: X }),\n  cache?: FraciCache,\n): Fraci<FraciOptionsBaseToBase<B>, X> {\n  if (options.type === \"binary\") {\n    if (globalThis.__DEV__) {\n      if (cache) {\n        console.warn(\"Fraci: Cache is not used for binary base\");\n      }\n    }\n    return fraciBinary(options) as Fraci<FraciOptionsBaseToBase<B>, X>;\n  }\n\n  return fraciString(options, cache) as Fraci<FraciOptionsBaseToBase<B>, X>;\n}\n"],"mappings":"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"}