{"version":3,"file":"is-equal.mjs","names":[],"sources":["../src/is-equal.ts"],"sourcesContent":["/* -------------------------------------------------------------------\n\n                       🗲 Storm Software - Stryke\n\n This code was released as part of the Stryke project. Stryke\n is maintained by Storm Software under the Apache-2.0 license, and is\n free for commercial and private use. For more information, please visit\n our licensing page at https://stormsoftware.com/licenses/projects/stryke.\n\n Website:                  https://stormsoftware.com\n Repository:               https://github.com/storm-software/stryke\n Documentation:            https://docs.stormsoftware.com/projects/stryke\n Contact:                  https://stormsoftware.com/contact\n\n SPDX-License-Identifier:  Apache-2.0\n\n ------------------------------------------------------------------- */\n\nimport { isSet } from \"@stryke/type-checks/is-set\";\nimport { isSetString } from \"@stryke/type-checks/is-set-string\";\n\nconst hasMap = typeof Map === \"function\";\nconst hasSet = typeof Set === \"function\";\nconst hasArrayBuffer =\n  typeof ArrayBuffer === \"function\" && ArrayBuffer.isView !== undefined;\n\nfunction equal(a: any, b: any) {\n  if (a === b) {\n    return true;\n  }\n\n  if (a && b && typeof a === \"object\" && typeof b === \"object\") {\n    if (a.constructor !== b.constructor) {\n      return false;\n    }\n\n    let length;\n    if (Array.isArray(a)) {\n      length = a.length;\n\n      if (length != b.length) return false;\n      for (let i = length; i-- !== 0; ) if (!equal(a[i], b[i])) return false;\n      return true;\n    }\n\n    let it;\n    if (hasMap && a instanceof Map && b instanceof Map) {\n      if (a.size !== b.size) return false;\n      it = a.entries();\n      let i;\n      while (!(i = it.next()).done) if (!b.has(i.value[0])) return false;\n      it = a.entries();\n      while (!(i = it.next()).done) {\n        if (!equal(i.value[1], b.get(i.value[0]))) return false;\n      }\n      return true;\n    }\n\n    if (hasSet && a instanceof Set && b instanceof Set) {\n      if (a.size !== b.size) return false;\n      it = a.entries();\n      let i;\n      while (!(i = it.next()).done) if (!b.has(i.value[0])) return false;\n      return true;\n    }\n\n    if (\n      Array.isArray(a) &&\n      Array.isArray(b) &&\n      hasArrayBuffer &&\n      ArrayBuffer.isView(a) &&\n      ArrayBuffer.isView(b)\n    ) {\n      length = a.length;\n\n      if (length != b.length) return false;\n      for (let i = length; i-- !== 0; ) if (a[i] !== b[i]) return false;\n      return true;\n    }\n\n    if (a.constructor === RegExp) {\n      return a.source === b.source && a.flags === b.flags;\n    }\n\n    if (\n      a.valueOf !== Object.prototype.valueOf &&\n      typeof a.valueOf === \"function\" &&\n      typeof b.valueOf === \"function\"\n    ) {\n      // eslint-disable-next-line ts/no-unsafe-call\n      return a.valueOf() === b.valueOf();\n    }\n    if (\n      a.toString !== Object.prototype.toString &&\n      typeof a.toString === \"function\" &&\n      typeof b.toString === \"function\"\n    ) {\n      // eslint-disable-next-line ts/no-unsafe-call\n      return a.toString() === b.toString();\n    }\n\n    const keys = Object.keys(a);\n    length = keys.length;\n    if (length !== Object.keys(b).length) {\n      return false;\n    }\n\n    for (let i = length; i-- !== 0; ) {\n      if (\n        !isSet(i) ||\n        !isSetString(keys[i]) ||\n        !Object.prototype.hasOwnProperty.call(b, keys[i] as any)\n      ) {\n        return false;\n      }\n    }\n\n    for (let i = length; i-- !== 0; ) {\n      if (\n        Array.isArray(keys) &&\n        (keys[i] === \"_owner\" || keys[i] === \"__v\" || keys[i] === \"__o\") &&\n        a.$$typeof\n      ) {\n        continue;\n      }\n\n      if (\n        !isSet(i) ||\n        !isSetString(keys[i]) ||\n        !equal(a[keys[i] as any], b[keys[i] as any])\n      ) {\n        return false;\n      }\n    }\n\n    return true;\n  }\n\n  // eslint-disable-next-line no-self-compare\n  return a !== a && b !== b;\n}\n\n/**\n * Checks if two values are equal, including support for `Date`, `RegExp`, and deep object comparison.\n *\n * @example\n * ```ts\n * isEqual(1, 1); // true\n * isEqual({ a: 1 }, { a: 1 }); // true\n * isEqual(/abc/g, /abc/g); // true\n * isEqual(new Date('2020-01-01'), new Date('2020-01-01')); // true\n * isEqual([1, 2, 3], [1, 2, 3]); // true\n * isEqual({ a: 1, b: { c: 2 } }, { a: 1, b: { c: 2 } }); // true\n * ```\n *\n * @param a - The first value to compare.\n * @param b - The second value to compare.\n * @returns `true` if the values are equal, otherwise `false`.\n */\nexport function isEqual(a: any, b: any): boolean {\n  try {\n    return equal(a, b);\n  } catch (error) {\n    if (/stack|recursion/i.test((error as any)?.message || \"\")) {\n      // eslint-disable-next-line no-console\n      console.warn(\"isEqual cannot handle circular refs\");\n\n      return false;\n    }\n\n    throw error;\n  }\n}\n"],"mappings":";;;;AAqBA,MAAM,SAAS,OAAO,QAAQ;AAC9B,MAAM,SAAS,OAAO,QAAQ;AAC9B,MAAM,iBACJ,OAAO,gBAAgB,cAAc,YAAY,WAAW;AAE9D,SAAS,MAAM,GAAQ,GAAQ;AAC7B,KAAI,MAAM,EACR,QAAO;AAGT,KAAI,KAAK,KAAK,OAAO,MAAM,YAAY,OAAO,MAAM,UAAU;AAC5D,MAAI,EAAE,gBAAgB,EAAE,YACtB,QAAO;EAGT,IAAI;AACJ,MAAI,MAAM,QAAQ,EAAE,EAAE;AACpB,YAAS,EAAE;AAEX,OAAI,UAAU,EAAE,OAAQ,QAAO;AAC/B,QAAK,IAAI,IAAI,QAAQ,QAAQ,GAAK,KAAI,CAAC,MAAM,EAAE,IAAI,EAAE,GAAG,CAAE,QAAO;AACjE,UAAO;;EAGT,IAAI;AACJ,MAAI,UAAU,aAAa,OAAO,aAAa,KAAK;AAClD,OAAI,EAAE,SAAS,EAAE,KAAM,QAAO;AAC9B,QAAK,EAAE,SAAS;GAChB,IAAI;AACJ,UAAO,EAAE,IAAI,GAAG,MAAM,EAAE,KAAM,KAAI,CAAC,EAAE,IAAI,EAAE,MAAM,GAAG,CAAE,QAAO;AAC7D,QAAK,EAAE,SAAS;AAChB,UAAO,EAAE,IAAI,GAAG,MAAM,EAAE,KACtB,KAAI,CAAC,MAAM,EAAE,MAAM,IAAI,EAAE,IAAI,EAAE,MAAM,GAAG,CAAC,CAAE,QAAO;AAEpD,UAAO;;AAGT,MAAI,UAAU,aAAa,OAAO,aAAa,KAAK;AAClD,OAAI,EAAE,SAAS,EAAE,KAAM,QAAO;AAC9B,QAAK,EAAE,SAAS;GAChB,IAAI;AACJ,UAAO,EAAE,IAAI,GAAG,MAAM,EAAE,KAAM,KAAI,CAAC,EAAE,IAAI,EAAE,MAAM,GAAG,CAAE,QAAO;AAC7D,UAAO;;AAGT,MACE,MAAM,QAAQ,EAAE,IAChB,MAAM,QAAQ,EAAE,IAChB,kBACA,YAAY,OAAO,EAAE,IACrB,YAAY,OAAO,EAAE,EACrB;AACA,YAAS,EAAE;AAEX,OAAI,UAAU,EAAE,OAAQ,QAAO;AAC/B,QAAK,IAAI,IAAI,QAAQ,QAAQ,GAAK,KAAI,EAAE,OAAO,EAAE,GAAI,QAAO;AAC5D,UAAO;;AAGT,MAAI,EAAE,gBAAgB,OACpB,QAAO,EAAE,WAAW,EAAE,UAAU,EAAE,UAAU,EAAE;AAGhD,MACE,EAAE,YAAY,OAAO,UAAU,WAC/B,OAAO,EAAE,YAAY,cACrB,OAAO,EAAE,YAAY,WAGrB,QAAO,EAAE,SAAS,KAAK,EAAE,SAAS;AAEpC,MACE,EAAE,aAAa,OAAO,UAAU,YAChC,OAAO,EAAE,aAAa,cACtB,OAAO,EAAE,aAAa,WAGtB,QAAO,EAAE,UAAU,KAAK,EAAE,UAAU;EAGtC,MAAM,OAAO,OAAO,KAAK,EAAE;AAC3B,WAAS,KAAK;AACd,MAAI,WAAW,OAAO,KAAK,EAAE,CAAC,OAC5B,QAAO;AAGT,OAAK,IAAI,IAAI,QAAQ,QAAQ,GAC3B,KACE,CAAC,MAAM,EAAE,IACT,CAAC,YAAY,KAAK,GAAG,IACrB,CAAC,OAAO,UAAU,eAAe,KAAK,GAAG,KAAK,GAAU,CAExD,QAAO;AAIX,OAAK,IAAI,IAAI,QAAQ,QAAQ,IAAK;AAChC,OACE,MAAM,QAAQ,KAAK,KAClB,KAAK,OAAO,YAAY,KAAK,OAAO,SAAS,KAAK,OAAO,UAC1D,EAAE,SAEF;AAGF,OACE,CAAC,MAAM,EAAE,IACT,CAAC,YAAY,KAAK,GAAG,IACrB,CAAC,MAAM,EAAE,KAAK,KAAY,EAAE,KAAK,IAAW,CAE5C,QAAO;;AAIX,SAAO;;AAIT,QAAO,MAAM,KAAK,MAAM;;;;;;;;;;;;;;;;;;;AAoB1B,SAAgB,QAAQ,GAAQ,GAAiB;AAC/C,KAAI;AACF,SAAO,MAAM,GAAG,EAAE;UACX,OAAO;AACd,MAAI,mBAAmB,KAAM,OAAe,WAAW,GAAG,EAAE;AAE1D,WAAQ,KAAK,sCAAsC;AAEnD,UAAO;;AAGT,QAAM"}