{"version":3,"file":"index.modern.mjs","sources":["../src/util.ts","../src/hash.ts"],"sourcesContent":["export function sortNumbers(a: string, b: string) {\n  return a > b ? 1 : -1;\n}\n\nexport function sortPairsByKey(a: [unknown, unknown], b: [unknown, unknown]) {\n  return sortNumbers(String(a[0]), String(b[0]));\n}\n\n/**\n * Fast mixing using DJB2-style algorithm with XOR. Bitwise operations are much faster\n * than modulo.\n */\nexport function mix(h: number, value: number): number {\n  return (h * 33) ^ value;\n}\n\n/**\n * Normalizes special numeric values to prevent collisions. Returns a safe integer\n * representation.\n */\nexport function normalizeNumber(val: number): number {\n  if (Number.isNaN(val)) return 0x7ff80000;\n  if (val === Infinity) return 0x7ff00000;\n  if (val === -Infinity) return 0xfff00000;\n\n  // For very large numbers, hash them as strings to avoid precision loss\n  if (Math.abs(val) > Number.MAX_SAFE_INTEGER) {\n    // Convert to string and hash the string representation\n    const str = String(val);\n    let h = 0;\n    for (let i = 0; i < str.length; i++) {\n      h = mix(h, str.charCodeAt(i));\n    }\n    return h;\n  }\n\n  return val;\n}\n","import { mix, normalizeNumber, sortNumbers, sortPairsByKey } from './util';\n\n/**\n * Hashes a given value into a unique number.\n *\n * This function accepts **ANY** kind of value, like `functions`, `classes`, `objects` and\n * so on.\n *\n * **Note**: Symbols uniqueness are not guaranteed, as they are transformed to strings.\n *\n * @example\n *\n * ```ts\n * class B {}\n *\n * const bHash = hash(B);\n * const bInstanceHash = hash(new B());\n * const bArrayHash = hash([B, new B(), new B(), { b: new B() }]);\n * const bBuilderHash = hash(() => B);\n * const bFactoryHash = hash(() => new B());\n * ```\n *\n * @param val The value to be hashed\n * @returns The signed integer result from the provided value\n * @see https://tinylibs.js.org/packages/object-code/\n */\nexport function hash(val: unknown, seen?: WeakSet<object>): number {\n  let h = 5381; // DJB2 seed\n\n  // Handle objects and array-like structures\n  if (typeof val === 'object' && val !== null) {\n    const hasEntries = typeof (val as any).entries === 'function';\n    const hasEnumerableKeys = Object.keys(val).length > 0;\n    const shouldHashAsObject =\n      val.toString === Object.prototype.toString ||\n      val.toString === Array.prototype.toString;\n\n    // Hash objects with enumerable keys OR entries() method (Map, Set, FormData, etc.)\n    if (shouldHashAsObject || (hasEntries && !hasEnumerableKeys)) {\n      if (!seen) {\n        seen = new WeakSet();\n      }\n      seen.add(val);\n\n      // Get key-value pairs: use entries() for special objects, Object.keys() for regular ones\n      const pairs: [unknown, unknown][] =\n        hasEntries && !hasEnumerableKeys\n          ? Array.from((val as any).entries())\n          : Object.keys(val)\n              .sort(sortNumbers)\n              .map((key) => [key, val[key as keyof typeof val]]);\n\n      // Sort by key for consistent hashing (only needed for entries() path)\n      if (hasEntries && !hasEnumerableKeys) {\n        pairs.sort(sortPairsByKey);\n      }\n\n      // Hash all key-value pairs\n      for (let i = 0; i < pairs.length; i++) {\n        const [key, value] = pairs[i]!;\n\n        h = mix(h, hash(key, seen));\n\n        // Track circular references for object values\n        if (\n          typeof value === 'object' &&\n          value !== null &&\n          (value.toString === Object.prototype.toString ||\n            value.toString === Array.prototype.toString)\n        ) {\n          if (seen.has(value)) {\n            continue;\n          }\n          seen.add(value);\n        }\n\n        h = mix(h, hash(value, seen));\n      }\n\n      // Hash the constructor for type differentiation\n      h = mix(h, hash(val.constructor, seen));\n\n      return h;\n    }\n  }\n\n  // Hash primitives efficiently - avoid string concatenation overhead\n  const type = typeof val;\n\n  // Hash the type first to differentiate types\n  for (let i = 0; i < type.length; i++) {\n    h = mix(h, type.charCodeAt(i));\n  }\n\n  if (val instanceof Date) {\n    // Hash dates by their numeric timestamp directly\n    return mix(h, val.getTime());\n  }\n\n  if (type === 'number') {\n    // Normalize special numbers to prevent collisions\n    return mix(h, normalizeNumber(val as number));\n  }\n\n  if (type === 'boolean') {\n    // Hash booleans as distinct values\n    return mix(h, val ? 1 : 0);\n  }\n\n  // For other types, get string representation\n  let toHash: string;\n\n  // Handles null prototype objects and symbols\n  try {\n    toHash = String(val);\n  } catch {\n    toHash = Object.prototype.toString.call(val);\n  }\n\n  // Hash the string representation\n  for (let i = 0; i < toHash.length; i++) {\n    h = mix(h, toHash.charCodeAt(i));\n  }\n\n  return h;\n}\n"],"names":["sortNumbers","a","b","sortPairsByKey","String","mix","h","value","hash","val","seen","hasEntries","entries","hasEnumerableKeys","Object","keys","length","toString","prototype","Array","WeakSet","add","pairs","from","sort","map","key","i","has","constructor","type","charCodeAt","Date","getTime","Number","isNaN","Infinity","Math","abs","MAX_SAFE_INTEGER","str","normalizeNumber","toHash","_unused","call"],"mappings":"SAAgBA,EAAYC,EAAWC,GACrC,OAAOD,EAAIC,EAAI,GAAK,CACtB,UAEgBC,EAAeF,EAAuBC,GACpD,OAAOF,EAAYI,OAAOH,EAAE,IAAKG,OAAOF,EAAE,IAC5C,CAMgB,SAAAG,EAAIC,EAAWC,GAC7B,OAAY,GAAJD,EAAUC,CACpB,CCYgB,SAAAC,EAAKC,EAAcC,GACjC,IAAIJ,EAAI,KAGR,GAAmB,iBAARG,GAA4B,OAARA,EAAc,CAC3C,MAAME,EAA6C,mBAAxBF,EAAYG,QACjCC,EAAoBC,OAAOC,KAAKN,GAAKO,OAAS,EAMpD,GAJEP,EAAIQ,WAAaH,OAAOI,UAAUD,UAClCR,EAAIQ,WAAaE,MAAMD,UAAUD,UAGRN,IAAeE,EAAoB,CACvDH,IACHA,EAAO,IAAIU,SAEbV,EAAKW,IAAIZ,GAGT,MAAMa,EACJX,IAAeE,EACXM,MAAMI,KAAMd,EAAYG,WACxBE,OAAOC,KAAKN,GACTe,KAAKxB,GACLyB,IAAKC,GAAQ,CAACA,EAAKjB,EAAIiB,KAG5Bf,IAAeE,GACjBS,EAAME,KAAKrB,GAIb,IAAK,IAAIwB,EAAI,EAAGA,EAAIL,EAAMN,OAAQW,IAAK,CACrC,MAAOD,EAAKnB,GAASe,EAAMK,GAK3B,GAHArB,EAAID,EAAIC,EAAGE,EAAKkB,EAAKhB,IAIF,iBAAVH,GACG,OAAVA,IACCA,EAAMU,WAAaH,OAAOI,UAAUD,UACnCV,EAAMU,WAAaE,MAAMD,UAAUD,UACrC,CACA,GAAIP,EAAKkB,IAAIrB,GACX,SAEFG,EAAKW,IAAId,EACX,CAEAD,EAAID,EAAIC,EAAGE,EAAKD,EAAOG,GACzB,CAKA,OAFAJ,EAAID,EAAIC,EAAGE,EAAKC,EAAIoB,YAAanB,IAE1BJ,CACT,CACF,CAGA,MAAMwB,SAAcrB,EAGpB,IAAK,IAAIkB,EAAI,EAAGA,EAAIG,EAAKd,OAAQW,IAC/BrB,EAAID,EAAIC,EAAGwB,EAAKC,WAAWJ,IAG7B,GAAIlB,aAAeuB,KAEjB,OAAO3B,EAAIC,EAAGG,EAAIwB,WAGpB,GAAa,WAATH,EAEF,OAAOzB,EAAIC,EDjFT,SAA0BG,GAC9B,GAAIyB,OAAOC,MAAM1B,GAAM,OAAO,WAC9B,GAAY2B,WAAR3B,EAAkB,OAAO,WAC7B,IAAa2B,WAAT3B,EAAmB,kBAGvB,GAAI4B,KAAKC,IAAI7B,GAAOyB,OAAOK,iBAAkB,CAE3C,MAAMC,EAAMpC,OAAOK,GACnB,IAAIH,EAAI,EACR,IAAK,IAAIqB,EAAI,EAAGA,EAAIa,EAAIxB,OAAQW,IAC9BrB,EAAID,EAAIC,EAAGkC,EAAIT,WAAWJ,IAE5B,OAAOrB,CACT,CAEA,OAAOG,CACT,CCgEkBgC,CAAgBhC,IAGhC,GAAa,YAATqB,EAEF,OAAOzB,EAAIC,EAAGG,EAAM,EAAI,GAI1B,IAAIiC,EAGJ,IACEA,EAAStC,OAAOK,EAClB,CAAE,MAAAkC,GACAD,EAAS5B,OAAOI,UAAUD,SAAS2B,KAAKnC,EAC1C,CAGA,IAAK,IAAIkB,EAAI,EAAGA,EAAIe,EAAO1B,OAAQW,IACjCrB,EAAID,EAAIC,EAAGoC,EAAOX,WAAWJ,IAG/B,OAAOrB,CACT"}