{"version":3,"file":"index.mjs","sources":[""],"sourcesContent":["export type TIsObjEqualArgs = Parameters<typeof isObjEqual>;\n\nexport type TIsObjEqualReturn = ReturnType<typeof isObjEqual>;\n\n/**\n * Checks if two objects are deeply equal by keys and values (not by reference),\n * including collections and binary data.\n * @param {unknown} obj1 First object\n * @param {unknown} obj2 Second object\n * @returns {boolean} True if objects are deeply equal\n * @throws {TypeError} isObjEqual: obj1 must be an object\n * @throws {TypeError} isObjEqual: obj2 must be an object\n * @example\n * // How to compare two objects by content?\n * const a = { foo: { bar: 1 } };\n * const b = { foo: { bar: 1 } };\n * const isEqual = isObjEqual(a, b);\n * console.log(isEqual); // => true\n * @example\n * // Enable a save button only when a form draft has changed\n * const hasUnsavedChanges = !isObjEqual(initialValues, formValues);\n */\nexport const isObjEqual = (obj1: unknown, obj2: unknown): boolean => {\n  const isObject = (obj: unknown): obj is object => obj !== null && typeof obj === \"object\";\n\n  if (!isObject(obj1)) {\n    throw new TypeError(\"isObjEqual: obj1 must be an object\");\n  }\n  if (!isObject(obj2)) {\n    throw new TypeError(\"isObjEqual: obj2 must be an object\");\n  }\n\n  const deepCompare = (\n    value1: unknown,\n    value2: unknown,\n    visitedValue1: Map<object, object>,\n    visitedValue2: Map<object, object>\n  ): boolean => {\n    if (Object.is(value1, value2)) {\n      return true;\n    }\n    if (!isObject(value1) || !isObject(value2)) {\n      return false;\n    }\n\n    if (visitedValue1.has(value1) || visitedValue2.has(value2)) {\n      return visitedValue1.get(value1) === value2 && visitedValue2.get(value2) === value1;\n    }\n\n    visitedValue1.set(value1, value2);\n    visitedValue2.set(value2, value1);\n\n    if (Array.isArray(value1) || Array.isArray(value2)) {\n      if (!Array.isArray(value1) || !Array.isArray(value2) || value1.length !== value2.length) {\n        return false;\n      }\n      for (let i = 0; i < value1.length; i += 1) {\n        if (!deepCompare(value1[i], value2[i], visitedValue1, visitedValue2)) {\n          return false;\n        }\n      }\n      return true;\n    }\n\n    if (value1 instanceof Date || value2 instanceof Date) {\n      return value1 instanceof Date && value2 instanceof Date && Object.is(value1.getTime(), value2.getTime());\n    }\n\n    if (value1 instanceof RegExp || value2 instanceof RegExp) {\n      return value1 instanceof RegExp\n        && value2 instanceof RegExp\n        && value1.source === value2.source\n        && value1.flags === value2.flags;\n    }\n\n    if (value1 instanceof ArrayBuffer || value2 instanceof ArrayBuffer) {\n      if (!(value1 instanceof ArrayBuffer) || !(value2 instanceof ArrayBuffer)) {\n        return false;\n      }\n      const bytes1 = new Uint8Array(value1);\n      const bytes2 = new Uint8Array(value2);\n      return bytes1.length === bytes2.length && bytes1.every((byte, index) => byte === bytes2[index]);\n    }\n\n    if (ArrayBuffer.isView(value1) || ArrayBuffer.isView(value2)) {\n      if (!ArrayBuffer.isView(value1)\n        || !ArrayBuffer.isView(value2)\n        || value1.constructor !== value2.constructor\n        || value1.byteLength !== value2.byteLength) {\n        return false;\n      }\n      const bytes1 = new Uint8Array(value1.buffer, value1.byteOffset, value1.byteLength);\n      const bytes2 = new Uint8Array(value2.buffer, value2.byteOffset, value2.byteLength);\n      return bytes1.every((byte, index) => byte === bytes2[index]);\n    }\n\n    if (value1 instanceof Map || value2 instanceof Map) {\n      if (!(value1 instanceof Map) || !(value2 instanceof Map) || value1.size !== value2.size) {\n        return false;\n      }\n      for (const [ key, mapValue1 ] of value1.entries()) {\n        if (!value2.has(key)) {\n          return false;\n        }\n        const mapValue2 = value2.get(key);\n        if (!deepCompare(mapValue1, mapValue2, visitedValue1, visitedValue2)) {\n          return false;\n        }\n      }\n      return true;\n    }\n\n    if (value1 instanceof Set || value2 instanceof Set) {\n      if (!(value1 instanceof Set) || !(value2 instanceof Set) || value1.size !== value2.size) {\n        return false;\n      }\n      const value2Items = [ ...value2.values() ];\n      for (const setItem1 of value1.values()) {\n        let matchIndex = -1;\n        let matchedValue1: Map<object, object> | null = null;\n        let matchedValue2: Map<object, object> | null = null;\n        for (let index = 0; index < value2Items.length; index += 1) {\n          const branchValue1 = new Map(visitedValue1);\n          const branchValue2 = new Map(visitedValue2);\n          if (deepCompare(setItem1, value2Items[index], branchValue1, branchValue2)) {\n            matchIndex = index;\n            matchedValue1 = branchValue1;\n            matchedValue2 = branchValue2;\n            break;\n          }\n        }\n        if (matchIndex === -1) {\n          return false;\n        }\n        matchedValue1?.forEach((mappedValue, key) => visitedValue1.set(key, mappedValue));\n        matchedValue2?.forEach((mappedValue, key) => visitedValue2.set(key, mappedValue));\n        value2Items.splice(matchIndex, 1);\n      }\n      return true;\n    }\n\n    const value1Keys = Reflect.ownKeys(value1);\n    const value2Keys = Reflect.ownKeys(value2);\n\n    if (value1Keys.length !== value2Keys.length) {\n      return false;\n    }\n\n    const value1Record = value1 as Record<PropertyKey, unknown>;\n    const value2Record = value2 as Record<PropertyKey, unknown>;\n\n    return value1Keys.every((key) => {\n      if (!Object.prototype.hasOwnProperty.call(value2Record, key)) {\n        return false;\n      }\n      return deepCompare(value1Record[key], value2Record[key], visitedValue1, visitedValue2);\n    });\n  };\n\n  return deepCompare(obj1, obj2, new Map<object, object>(), new Map<object, object>());\n};\n"],"names":["isObjEqual","obj1","obj2","isObject","obj","TypeError","deepCompare","value1","value2","visitedValue1","visitedValue2","Object","is","has","get","set","Array","isArray","length","i","Date","getTime","RegExp","source","flags","ArrayBuffer","bytes1","Uint8Array","bytes2","every","byte","index","isView","constructor","byteLength","buffer","byteOffset","Map","size","key","mapValue1","entries","mapValue2","Set","value2Items","values","setItem1","matchIndex","matchedValue1","matchedValue2","branchValue1","branchValue2","forEach","mappedValue","splice","value1Keys","Reflect","ownKeys","value2Keys","value1Record","value2Record","prototype","hasOwnProperty","call"],"mappings":"MAsBaA,WAAa,CAACC,KAAeC,QACxC,MAAMC,SAAYC,KAAgCA,MAAQ,aAAeA,MAAQ,SAEjF,IAAKD,SAASF,MACZ,MAAM,IAAII,UAAU,sCAEtB,IAAKF,SAASD,MACZ,MAAM,IAAIG,UAAU,sCAGtB,MAAMC,YAAc,CAClBC,OACAC,OACAC,cACAC,iBAEA,GAAIC,OAAOC,GAAGL,OAAQC,QACpB,OAAO,KAET,IAAKL,SAASI,UAAYJ,SAASK,QACjC,OAAO,MAGT,GAAIC,cAAcI,IAAIN,SAAWG,cAAcG,IAAIL,QACjD,OAAOC,cAAcK,IAAIP,UAAYC,QAAUE,cAAcI,IAAIN,UAAYD,OAG/EE,cAAcM,IAAIR,OAAQC,QAC1BE,cAAcK,IAAIP,OAAQD,QAE1B,GAAIS,MAAMC,QAAQV,SAAWS,MAAMC,QAAQT,QAAS,CAClD,IAAKQ,MAAMC,QAAQV,UAAYS,MAAMC,QAAQT,SAAWD,OAAOW,SAAWV,OAAOU,OAC/E,OAAO,MAET,IAAK,IAAIC,EAAI,EAAGA,EAAIZ,OAAOW,OAAQC,GAAK,EACtC,IAAKb,YAAYC,OAAOY,GAAIX,OAAOW,GAAIV,cAAeC,eACpD,OAAO,MAGX,OAAO,IACT,CAEA,GAAIH,kBAAkBa,MAAQZ,kBAAkBY,KAC9C,OAAOb,kBAAkBa,MAAQZ,kBAAkBY,MAAQT,OAAOC,GAAGL,OAAOc,UAAWb,OAAOa,WAGhG,GAAId,kBAAkBe,QAAUd,kBAAkBc,OAChD,OAAOf,kBAAkBe,QACpBd,kBAAkBc,QAClBf,OAAOgB,SAAWf,OAAOe,QACzBhB,OAAOiB,QAAUhB,OAAOgB,MAG/B,GAAIjB,kBAAkBkB,aAAejB,kBAAkBiB,YAAa,CAClE,KAAMlB,kBAAkBkB,gBAAkBjB,kBAAkBiB,aAC1D,OAAO,MAET,MAAMC,OAAS,IAAIC,WAAWpB,QAC9B,MAAMqB,OAAS,IAAID,WAAWnB,QAC9B,OAAOkB,OAAOR,SAAWU,OAAOV,QAAUQ,OAAOG,MAAM,CAACC,KAAMC,QAAUD,OAASF,OAAOG,OAC1F,CAEA,GAAIN,YAAYO,OAAOzB,SAAWkB,YAAYO,OAAOxB,QAAS,CAC5D,IAAKiB,YAAYO,OAAOzB,UAClBkB,YAAYO,OAAOxB,SACpBD,OAAO0B,cAAgBzB,OAAOyB,aAC9B1B,OAAO2B,aAAe1B,OAAO0B,WAChC,OAAO,MAET,MAAMR,OAAS,IAAIC,WAAWpB,OAAO4B,OAAQ5B,OAAO6B,WAAY7B,OAAO2B,YACvE,MAAMN,OAAS,IAAID,WAAWnB,OAAO2B,OAAQ3B,OAAO4B,WAAY5B,OAAO0B,YACvE,OAAOR,OAAOG,MAAM,CAACC,KAAMC,QAAUD,OAASF,OAAOG,OACvD,CAEA,GAAIxB,kBAAkB8B,KAAO7B,kBAAkB6B,IAAK,CAClD,KAAM9B,kBAAkB8B,QAAU7B,kBAAkB6B,MAAQ9B,OAAO+B,OAAS9B,OAAO8B,KACjF,OAAO,MAET,IAAK,MAAQC,IAAKC,aAAejC,OAAOkC,UAAW,CACjD,IAAKjC,OAAOK,IAAI0B,KACd,OAAO,MAET,MAAMG,UAAYlC,OAAOM,IAAIyB,KAC7B,IAAKjC,YAAYkC,UAAWE,UAAWjC,cAAeC,eACpD,OAAO,KAEX,CACA,OAAO,IACT,CAEA,GAAIH,kBAAkBoC,KAAOnC,kBAAkBmC,IAAK,CAClD,KAAMpC,kBAAkBoC,QAAUnC,kBAAkBmC,MAAQpC,OAAO+B,OAAS9B,OAAO8B,KACjF,OAAO,MAET,MAAMM,YAAc,IAAKpC,OAAOqC,UAChC,IAAK,MAAMC,YAAYvC,OAAOsC,SAAU,CACtC,IAAIE,YAAa,EACjB,IAAIC,cAA4C,KAChD,IAAIC,cAA4C,KAChD,IAAK,IAAIlB,MAAQ,EAAGA,MAAQa,YAAY1B,OAAQa,OAAS,EAAG,CAC1D,MAAMmB,aAAe,IAAIb,IAAI5B,eAC7B,MAAM0C,aAAe,IAAId,IAAI3B,eAC7B,GAAIJ,YAAYwC,SAAUF,YAAYb,OAAQmB,aAAcC,cAAe,CACzEJ,WAAahB,MACbiB,cAAgBE,aAChBD,cAAgBE,aAChB,KACF,CACF,CACA,GAAIJ,cAAe,EACjB,OAAO,MAETC,eAAeI,QAAQ,CAACC,YAAad,MAAQ9B,cAAcM,IAAIwB,IAAKc,cACpEJ,eAAeG,QAAQ,CAACC,YAAad,MAAQ7B,cAAcK,IAAIwB,IAAKc,cACpET,YAAYU,OAAOP,WAAY,EACjC,CACA,OAAO,IACT,CAEA,MAAMQ,WAAaC,QAAQC,QAAQlD,QACnC,MAAMmD,WAAaF,QAAQC,QAAQjD,QAEnC,GAAI+C,WAAWrC,SAAWwC,WAAWxC,OACnC,OAAO,MAGT,MAAMyC,aAAepD,OACrB,MAAMqD,aAAepD,OAErB,OAAO+C,WAAW1B,MAAOU,MACvB,IAAK5B,OAAOkD,UAAUC,eAAeC,KAAKH,aAAcrB,KACtD,OAAO,MAET,OAAOjC,YAAYqD,aAAapB,KAAMqB,aAAarB,KAAM9B,cAAeC,kBAI5E,OAAOJ,YAAYL,KAAMC,KAAM,IAAImC,IAAuB,IAAIA"}