{"version":3,"file":"RandomUtils.mjs","sources":["../src/RandomUtils.ts"],"sourcesContent":["/**\n * @module RandomUtils\n * @description A comprehensive collection of utility functions for random number generation.\n * Implements functionality proposed in TC39 Random API proposals including seeded pseudo-random\n * number generation, various distribution methods, and utility functions for common randomness needs.\n * @example\n * ```typescript\n * import { RandomUtils } from 'houser-js-utils';\n *\n * // Generate random integer in range\n * const dice = RandomUtils.int(1, 6);\n *\n * // Create seeded generator for reproducible sequences\n * const seeded = RandomUtils.Seeded.fromFixed(42);\n * const value = seeded.random();\n *\n * // Generate random bytes\n * const bytes = RandomUtils.bytes(16);\n * ```\n */\n\n/**\n * Simple Linear Congruential Generator (LCG) implementation for seeded random numbers.\n * Uses the same constants as Numerical Recipes: a = 1664525, c = 1013904223, m = 2^32\n */\nclass SimpleLCG {\n  private state: number;\n\n  constructor(seed: number) {\n    this.state = seed >>> 0; // Ensure 32-bit unsigned integer\n  }\n\n  /**\n   * Generate next random value and update state\n   * @returns Random number between 0 and 1 (exclusive)\n   */\n  next(): number {\n    this.state = (1664525 * this.state + 1013904223) >>> 0;\n    return this.state / 0x100000000; // Convert to [0,1)\n  }\n\n  /**\n   * Get current state\n   */\n  getState(): number {\n    return this.state;\n  }\n\n  /**\n   * Set state\n   */\n  setState(state: number): void {\n    this.state = state >>> 0;\n  }\n}\n\n/**\n * A seeded pseudo-random number generator that produces reproducible sequences.\n * Based on the TC39 Seeded Random proposal.\n */\nexport class SeededRandom {\n  private readonly prng: SimpleLCG;\n\n  /**\n   * Creates a new seeded random generator\n   * @param seed - Seed value or Uint8Array (up to 32 bytes)\n   */\n  constructor(seed: number | Uint8Array) {\n    if (typeof seed === \"number\") {\n      this.prng = new SimpleLCG(seed);\n    } else if (seed instanceof Uint8Array) {\n      if (seed.length > 32) {\n        throw new RangeError(\"Seed must be 32 bytes or less\");\n      }\n      // Convert Uint8Array to number by taking first 4 bytes\n      let numSeed = 0;\n      for (let i = 0; i < Math.min(4, seed.length); i++) {\n        numSeed = (numSeed << 8) | seed[i];\n      }\n      this.prng = new SimpleLCG(numSeed);\n    } else {\n      throw new TypeError(\"Seed must be a number or Uint8Array\");\n    }\n  }\n\n  /**\n   * Factory method that requires exact 32-byte seed\n   * @param seed - Exactly 32 bytes of seed data\n   * @returns New SeededRandom instance\n   */\n  static fromSeed(seed: Uint8Array): SeededRandom {\n    if (!(seed instanceof Uint8Array)) {\n      throw new TypeError(\"Seed must be a Uint8Array\");\n    }\n    if (seed.length !== 32) {\n      throw new RangeError(\"Seed must be exactly 32 bytes\");\n    }\n    return new SeededRandom(seed);\n  }\n\n  /**\n   * Factory method that creates generator from state\n   * @param state - State data (simplified to number for this implementation)\n   * @returns New SeededRandom instance\n   */\n  static fromState(state: number): SeededRandom {\n    const instance = new SeededRandom(0);\n    instance.prng.setState(state);\n    return instance;\n  }\n\n  /**\n   * Factory method for simple integer seeds\n   * @param byte - Integer between 0-255\n   * @returns New SeededRandom instance\n   */\n  static fromFixed(byte: number): SeededRandom {\n    if (\n      typeof byte !== \"number\" ||\n      !Number.isInteger(byte) ||\n      byte < 0 ||\n      byte > 255\n    ) {\n      throw new RangeError(\"Byte must be an integer between 0 and 255\");\n    }\n    return new SeededRandom(byte);\n  }\n\n  /**\n   * Generate a random number between 0 and 1 (exclusive)\n   * @returns Random number in [0,1)\n   */\n  random(): number {\n    return this.prng.next();\n  }\n\n  /**\n   * Generate a new seed for creating child PRNGs\n   * @returns 32-byte Uint8Array suitable for seeding\n   */\n  seed(): Uint8Array {\n    const seed = new Uint8Array(32);\n    for (let i = 0; i < 32; i++) {\n      seed[i] = Math.floor(this.random() * 256);\n    }\n    return seed;\n  }\n\n  /**\n   * Get current generator state\n   * @returns Current state as number\n   */\n  getState(): number {\n    return this.prng.getState();\n  }\n\n  /**\n   * Set generator state\n   * @param state - State to set\n   * @returns This instance for chaining\n   */\n  setState(state: number): this {\n    this.prng.setState(state);\n    return this;\n  }\n\n  /**\n   * Generate random number in range\n   * @param lo - Lower bound\n   * @param hi - Upper bound\n   * @param step - Optional step size\n   * @returns Random number in specified range\n   */\n  number(lo: number, hi: number, step?: number): number {\n    return RandomUtils.number(lo, hi, step, () => this.random());\n  }\n\n  /**\n   * Generate random integer in range\n   * @param lo - Lower bound (inclusive)\n   * @param hi - Upper bound (inclusive)\n   * @param step - Optional step size\n   * @returns Random integer in specified range\n   */\n  int(lo: number, hi: number, step?: number): number {\n    return RandomUtils.int(lo, hi, step, () => this.random());\n  }\n\n  /**\n   * Generate random BigInt in range\n   * @param lo - Lower bound (inclusive)\n   * @param hi - Upper bound (inclusive)\n   * @param step - Optional step size\n   * @returns Random BigInt in specified range\n   */\n  bigint(lo: bigint, hi: bigint, step?: bigint): bigint {\n    return RandomUtils.bigint(lo, hi, step, () => this.random());\n  }\n\n  /**\n   * Generate random bytes\n   * @param n - Number of bytes to generate\n   * @returns Uint8Array of random bytes\n   */\n  bytes(n: number): Uint8Array {\n    return RandomUtils.bytes(n, () => this.random());\n  }\n\n  /**\n   * Fill buffer with random bytes\n   * @param buffer - Buffer to fill\n   * @param start - Start position (optional)\n   * @param end - End position (optional)\n   * @returns The filled buffer\n   */\n  fillBytes<T extends ArrayBuffer | ArrayBufferView>(\n    buffer: T,\n    start?: number,\n    end?: number\n  ): T {\n    return RandomUtils.fillBytes(buffer, start, end, () => this.random());\n  }\n}\n\n/**\n * Collection of random utility functions\n */\nexport const RandomUtils = {\n  /**\n   * The SeededRandom class for creating reproducible random sequences\n   */\n  Seeded: SeededRandom,\n\n  /**\n   * Generate a random number between 0 and 1 (exclusive)\n   * @returns Random number in [0,1)\n   */\n  random(): number {\n    return Math.random();\n  },\n\n  /**\n   * Generate a random number in a specified range\n   * @param lo - Lower bound\n   * @param hi - Upper bound\n   * @param step - Optional step size\n   * @param randomFn - Optional custom random function\n   * @returns Random number in specified range\n   */\n  number(\n    lo: number,\n    hi: number,\n    step?: number,\n    randomFn: () => number = Math.random\n  ): number {\n    if (typeof lo !== \"number\" || typeof hi !== \"number\") {\n      throw new TypeError(\"Lower and upper bounds must be numbers\");\n    }\n    if (lo >= hi) {\n      throw new RangeError(\"Lower bound must be less than upper bound\");\n    }\n\n    if (step === undefined) {\n      // Return random float in range (lo, hi)\n      return lo + randomFn() * (hi - lo);\n    }\n\n    if (typeof step !== \"number\" || step <= 0) {\n      throw new RangeError(\"Step must be a positive number\");\n    }\n\n    // Return random number of form lo + N*step in range [lo, hi]\n    const maxN = Math.floor((hi - lo) / step);\n    const N = Math.floor(randomFn() * (maxN + 1));\n    const result = lo + N * step;\n    return result > hi ? hi : result;\n  },\n\n  /**\n   * Generate a random integer in a specified range\n   * @param lo - Lower bound (inclusive)\n   * @param hi - Upper bound (inclusive)\n   * @param step - Optional step size\n   * @param randomFn - Optional custom random function\n   * @returns Random integer in specified range\n   */\n  int(\n    lo: number,\n    hi: number,\n    step?: number,\n    randomFn: () => number = Math.random\n  ): number {\n    if (!Number.isInteger(lo) || !Number.isInteger(hi)) {\n      throw new TypeError(\"Lower and upper bounds must be integers\");\n    }\n    if (lo > hi) {\n      throw new RangeError(\n        \"Lower bound must be less than or equal to upper bound\"\n      );\n    }\n\n    if (step === undefined) {\n      // Return random integer in range [lo, hi]\n      return Math.floor(randomFn() * (hi - lo + 1)) + lo;\n    }\n\n    if (!Number.isInteger(step) || step <= 0) {\n      throw new RangeError(\"Step must be a positive integer\");\n    }\n\n    // Return random integer of form lo + N*step in range [lo, hi]\n    const maxN = Math.floor((hi - lo) / step);\n    const N = Math.floor(randomFn() * (maxN + 1));\n    return lo + N * step;\n  },\n\n  /**\n   * Generate a random BigInt in a specified range\n   * @param lo - Lower bound (inclusive)\n   * @param hi - Upper bound (inclusive)\n   * @param step - Optional step size\n   * @param randomFn - Optional custom random function\n   * @returns Random BigInt in specified range\n   */\n  bigint(\n    lo: bigint,\n    hi: bigint,\n    step?: bigint,\n    randomFn: () => number = Math.random\n  ): bigint {\n    if (typeof lo !== \"bigint\" || typeof hi !== \"bigint\") {\n      throw new TypeError(\"Lower and upper bounds must be BigInts\");\n    }\n    if (lo > hi) {\n      throw new RangeError(\n        \"Lower bound must be less than or equal to upper bound\"\n      );\n    }\n\n    const range = hi - lo + 1n;\n\n    if (step === undefined) {\n      // Generate random BigInt in range [lo, hi]\n      const randomValue = BigInt(Math.floor(randomFn() * Number(range)));\n      return lo + randomValue;\n    }\n\n    if (typeof step !== \"bigint\" || step <= 0n) {\n      throw new RangeError(\"Step must be a positive BigInt\");\n    }\n\n    // Return random BigInt of form lo + N*step in range [lo, hi]\n    const maxN = (hi - lo) / step;\n    const N = BigInt(Math.floor(randomFn() * (Number(maxN) + 1)));\n    return lo + N * step;\n  },\n\n  /**\n   * Generate random bytes\n   * @param n - Number of bytes to generate\n   * @param randomFn - Optional custom random function\n   * @returns Uint8Array of random bytes\n   */\n  bytes(n: number, randomFn: () => number = Math.random): Uint8Array {\n    if (!Number.isInteger(n) || n < 0) {\n      throw new RangeError(\"Number of bytes must be a non-negative integer\");\n    }\n\n    const bytes = new Uint8Array(n);\n    for (let i = 0; i < n; i++) {\n      bytes[i] = Math.floor(randomFn() * 256);\n    }\n    return bytes;\n  },\n\n  /**\n   * Fill a buffer with random bytes\n   * @param buffer - Buffer to fill (ArrayBuffer or TypedArray)\n   * @param start - Start position (optional)\n   * @param end - End position (optional)\n   * @param randomFn - Optional custom random function\n   * @returns The filled buffer\n   */\n  fillBytes<T extends ArrayBuffer | ArrayBufferView>(\n    buffer: T,\n    start?: number,\n    end?: number,\n    randomFn: () => number = Math.random\n  ): T {\n    let view: Uint8Array;\n\n    if (buffer instanceof ArrayBuffer) {\n      view = new Uint8Array(buffer);\n    } else if (ArrayBuffer.isView(buffer)) {\n      view = new Uint8Array(\n        buffer.buffer,\n        buffer.byteOffset,\n        buffer.byteLength\n      );\n    } else {\n      throw new TypeError(\"Buffer must be an ArrayBuffer or ArrayBufferView\");\n    }\n\n    const startPos = start ?? 0;\n    const endPos = end ?? view.length;\n\n    if (startPos < 0 || endPos > view.length || startPos > endPos) {\n      throw new RangeError(\"Invalid start or end position\");\n    }\n\n    for (let i = startPos; i < endPos; i++) {\n      view[i] = Math.floor(randomFn() * 256);\n    }\n\n    return buffer;\n  },\n\n  /**\n   * Generate a random boolean value\n   * @param probability - Probability of returning true (0-1, default: 0.5)\n   * @param randomFn - Optional custom random function\n   * @returns Random boolean\n   */\n  boolean(\n    probability: number = 0.5,\n    randomFn: () => number = Math.random\n  ): boolean {\n    if (\n      typeof probability !== \"number\" ||\n      isNaN(probability) ||\n      probability < 0 ||\n      probability > 1\n    ) {\n      throw new RangeError(\"Probability must be a number between 0 and 1\");\n    }\n    return randomFn() < probability;\n  },\n\n  /**\n   * Choose a random element from an array\n   * @param array - Array to choose from\n   * @param randomFn - Optional custom random function\n   * @returns Random element from the array\n   */\n  choice<T>(array: T[], randomFn: () => number = Math.random): T {\n    if (!Array.isArray(array)) {\n      throw new TypeError(\"Input must be an array\");\n    }\n    if (array.length === 0) {\n      throw new RangeError(\"Array cannot be empty\");\n    }\n\n    const index = Math.floor(randomFn() * array.length);\n    return array[index];\n  },\n\n  /**\n   * Choose multiple random elements from an array without replacement\n   * @param array - Array to choose from\n   * @param count - Number of elements to choose\n   * @param randomFn - Optional custom random function\n   * @returns Array of randomly chosen elements\n   */\n  sample<T>(\n    array: T[],\n    count: number,\n    randomFn: () => number = Math.random\n  ): T[] {\n    if (!Array.isArray(array)) {\n      throw new TypeError(\"Input must be an array\");\n    }\n    if (!Number.isInteger(count) || count < 0) {\n      throw new RangeError(\"Count must be a non-negative integer\");\n    }\n    if (count > array.length) {\n      throw new RangeError(\"Count cannot be greater than array length\");\n    }\n\n    const result: T[] = [];\n    const indices = new Set<number>();\n\n    while (result.length < count) {\n      const index = Math.floor(randomFn() * array.length);\n      if (!indices.has(index)) {\n        indices.add(index);\n        result.push(array[index]);\n      }\n    }\n\n    return result;\n  },\n\n  /**\n   * Shuffle an array using Fisher-Yates algorithm\n   * @param array - Array to shuffle\n   * @param randomFn - Optional custom random function\n   * @returns New shuffled array\n   */\n  shuffle<T>(array: T[], randomFn: () => number = Math.random): T[] {\n    if (!Array.isArray(array)) {\n      throw new TypeError(\"Input must be an array\");\n    }\n\n    const result = [...array];\n    for (let i = result.length - 1; i > 0; i--) {\n      const j = Math.floor(randomFn() * (i + 1));\n      [result[i], result[j]] = [result[j], result[i]];\n    }\n    return result;\n  },\n\n  /**\n   * Generate a random string of specified length\n   * @param length - Length of the string to generate\n   * @param charset - Character set to use (default: alphanumeric)\n   * @param randomFn - Optional custom random function\n   * @returns Random string\n   */\n  string(\n    length: number,\n    charset: string = \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\",\n    randomFn: () => number = Math.random\n  ): string {\n    if (!Number.isInteger(length) || length < 0) {\n      throw new RangeError(\"Length must be a non-negative integer\");\n    }\n    if (typeof charset !== \"string\" || charset.length === 0) {\n      throw new TypeError(\"Charset must be a non-empty string\");\n    }\n\n    let result = \"\";\n    for (let i = 0; i < length; i++) {\n      result += charset[Math.floor(randomFn() * charset.length)];\n    }\n    return result;\n  },\n\n  /**\n   * Generate a random UUID v4\n   * @param randomFn - Optional custom random function\n   * @returns Random UUID string\n   */\n  uuid(randomFn: () => number = Math.random): string {\n    const hex = \"0123456789abcdef\";\n    let uuid = \"\";\n\n    for (let i = 0; i < 36; i++) {\n      if (i === 8 || i === 13 || i === 18 || i === 23) {\n        uuid += \"-\";\n      } else if (i === 14) {\n        uuid += \"4\"; // Version 4\n      } else if (i === 19) {\n        uuid += hex[Math.floor(randomFn() * 4) + 8]; // Variant bits\n      } else {\n        uuid += hex[Math.floor(randomFn() * 16)];\n      }\n    }\n\n    return uuid;\n  },\n\n  /**\n   * Generate a weighted random choice\n   * @param items - Array of items to choose from\n   * @param weights - Array of weights corresponding to items\n   * @param randomFn - Optional custom random function\n   * @returns Randomly chosen item based on weights\n   */\n  weightedChoice<T>(\n    items: T[],\n    weights: number[],\n    randomFn: () => number = Math.random\n  ): T {\n    if (!Array.isArray(items) || !Array.isArray(weights)) {\n      throw new TypeError(\"Items and weights must be arrays\");\n    }\n    if (items.length !== weights.length) {\n      throw new RangeError(\n        \"Items and weights arrays must have the same length\"\n      );\n    }\n    if (items.length === 0) {\n      throw new RangeError(\"Arrays cannot be empty\");\n    }\n    if (weights.some((w) => typeof w !== \"number\" || w < 0)) {\n      throw new RangeError(\"All weights must be non-negative numbers\");\n    }\n\n    const totalWeight = weights.reduce((sum, weight) => sum + weight, 0);\n    if (totalWeight === 0) {\n      throw new RangeError(\"Total weight must be greater than 0\");\n    }\n\n    const random = randomFn() * totalWeight;\n    let cumulativeWeight = 0;\n\n    for (let i = 0; i < items.length; i++) {\n      cumulativeWeight += weights[i];\n      if (random <= cumulativeWeight) {\n        return items[i];\n      }\n    }\n\n    // Fallback (should never reach here)\n    return items[items.length - 1];\n  },\n\n  /**\n   * Generate a random number from normal distribution (Box-Muller transform)\n   * @param mean - Mean of the distribution (default: 0)\n   * @param stdDev - Standard deviation (default: 1)\n   * @param randomFn - Optional custom random function\n   * @returns Random number from normal distribution\n   */\n  normal(\n    mean: number = 0,\n    stdDev: number = 1,\n    randomFn: () => number = Math.random\n  ): number {\n    if (typeof mean !== \"number\" || typeof stdDev !== \"number\") {\n      throw new TypeError(\"Mean and standard deviation must be numbers\");\n    }\n    if (stdDev <= 0) {\n      throw new RangeError(\"Standard deviation must be positive\");\n    }\n\n    // Use a simple implementation without static variables\n    const u1 = randomFn();\n    const u2 = randomFn();\n\n    // Box-Muller transform\n    const z0 = Math.sqrt(-2 * Math.log(u1)) * Math.cos(2 * Math.PI * u2);\n    return z0 * stdDev + mean;\n  },\n\n  /**\n   * Generate a random number from exponential distribution\n   * @param rate - Rate parameter (lambda)\n   * @param randomFn - Optional custom random function\n   * @returns Random number from exponential distribution\n   */\n  exponential(rate: number = 1, randomFn: () => number = Math.random): number {\n    if (typeof rate !== \"number\" || rate <= 0) {\n      throw new RangeError(\"Rate must be a positive number\");\n    }\n\n    return -Math.log(1 - randomFn()) / rate;\n  },\n\n  /**\n   * Generate a random seed for seeding PRNGs\n   * @returns 32-byte Uint8Array suitable for seeding\n   */\n  seed(): Uint8Array {\n    return this.bytes(32);\n  },\n};\n"],"names":[],"mappings":"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"}