UNPKG

remeda

Version:

A utility library for JavaScript and Typescript.

1 lines 6.17 kB
{"version":3,"file":"isShallowEqual.cjs","names":["purry"],"sources":["../src/isShallowEqual.ts"],"sourcesContent":["import { purry } from \"./purry\";\n\n/**\n * Performs a *shallow structural* comparison between two values to determine if\n * they are equivalent. For primitive values this is equivalent to `===`, for\n * arrays a **strict equality** check would be performed on every item, in\n * order, and for objects props will be matched and checked for **strict\n * equality**; Unlike `isDeepEqual` where the function also *recurses* into each\n * item and value.\n *\n * !IMPORTANT: symbol properties of objects are not supported right now and\n * might result in unexpected behavior. Please open an issue in the Remeda\n * github project if you need support for these types.\n *\n * !IMPORTANT: Promise, Date, and RegExp, are shallowly equal, even when they\n * are semantically different (e.g. resolved promises); but `isDeepEqual` does\n * compare the latter 2 semantically by-value.\n *\n * The result would be narrowed to the second value so that the function can be\n * used as a type guard.\n *\n * See:\n * - `isStrictEqual` if you don't need a deep comparison and just want to check\n * for simple (`===`, `Object.is`) equality.\n * - `isDeepEqual` for a recursively deep check of arrays and objects.\n *\n * @param data - The first value to compare.\n * @param other - The second value to compare.\n * @signature\n * R.isShallowEqual(data, other)\n * @example\n * R.isShallowEqual(1, 1) //=> true\n * R.isShallowEqual(1, '1') //=> false\n * R.isShallowEqual([1, 2, 3], [1, 2, 3]) //=> true\n * R.isShallowEqual([[1], [2], [3]], [[1], [2], [3]]) //=> false\n * @dataFirst\n * @category Guard\n */\nexport function isShallowEqual<T, S extends T>(\n data: T,\n other: T extends Exclude<T, S> ? S : never,\n): data is S;\nexport function isShallowEqual<T>(data: T, other: T): boolean;\n\n/**\n * Performs a *shallow structural* comparison between two values to determine if\n * they are equivalent. For primitive values this is equivalent to `===`, for\n * arrays a **strict equality** check would be performed on every item, in\n * order, and for objects props will be matched and checked for **strict\n * equality**; Unlike `isDeepEqual` where the function also *recurses* into each\n * item and value.\n *\n * !IMPORTANT: symbol properties of objects are not supported right now and\n * might result in unexpected behavior. Please open an issue in the Remeda\n * github project if you need support for these types.\n *\n * !IMPORTANT: All built-in objects (Promise, Date, RegExp) are shallowly equal,\n * even when they are semantically different (e.g. resolved promises). Use\n * `isDeepEqual` instead.\n *\n * The result would be narrowed to the second value so that the function can be\n * used as a type guard.\n *\n * See:\n * - `isStrictEqual` if you don't need a deep comparison and just want to check\n * for simple (`===`, `Object.is`) equality.\n * - `isDeepEqual` for a recursively deep check of arrays and objects.\n *\n * @param other - The second value to compare.\n * @signature\n * R.isShallowEqual(other)(data)\n * @example\n * R.pipe(1, R.isShallowEqual(1)) //=> true\n * R.pipe(1, R.isShallowEqual('1')) //=> false\n * R.pipe([1, 2, 3], R.isShallowEqual([1, 2, 3])) //=> true\n * R.pipe([[1], [2], [3]], R.isShallowEqual([[1], [2], [3]])) //=> false\n * @dataFirst\n * @category Guard\n */\nexport function isShallowEqual<T, S extends T>(\n other: T extends Exclude<T, S> ? S : never,\n): (data: T) => data is S;\nexport function isShallowEqual<T>(other: T): (data: T) => boolean;\n\nexport function isShallowEqual(...args: ReadonlyArray<unknown>): unknown {\n return purry(isShallowEqualImplementation, args);\n}\n\nfunction isShallowEqualImplementation<T>(a: T, b: T): boolean {\n if (a === b || Object.is(a, b)) {\n return true;\n }\n\n if (\n typeof a !== \"object\" ||\n a === null ||\n typeof b !== \"object\" ||\n b === null\n ) {\n return false;\n }\n\n if (a instanceof Map && b instanceof Map) {\n return isMapShallowEqual(a, b);\n }\n\n if (a instanceof Set && b instanceof Set) {\n return isSetShallowEqual(a, b);\n }\n\n const keys = Object.keys(a);\n if (keys.length !== Object.keys(b).length) {\n return false;\n }\n\n for (const key of keys) {\n if (!Object.hasOwn(b, key)) {\n return false;\n }\n\n const { [key as keyof T]: valueA } = a;\n const { [key as keyof T]: valueB } = b;\n\n if (valueA !== valueB || !Object.is(valueA, valueB)) {\n return false;\n }\n }\n\n return true;\n}\n\nfunction isMapShallowEqual(\n a: ReadonlyMap<unknown, unknown>,\n b: ReadonlyMap<unknown, unknown>,\n): boolean {\n if (a.size !== b.size) {\n return false;\n }\n\n for (const [key, value] of a) {\n const valueB = b.get(key);\n if (value !== valueB || !Object.is(value, valueB)) {\n return false;\n }\n }\n\n return true;\n}\n\nfunction isSetShallowEqual(\n a: ReadonlySet<unknown>,\n b: ReadonlySet<unknown>,\n): boolean {\n if (a.size !== b.size) {\n return false;\n }\n\n for (const value of a) {\n if (!b.has(value)) {\n return false;\n }\n }\n\n return true;\n}\n"],"mappings":"wCAoFA,SAAgB,EAAe,GAAG,EAAuC,CACvE,OAAOA,EAAAA,EAAM,EAA8B,EAAK,CAGlD,SAAS,EAAgC,EAAM,EAAe,CAC5D,GAAI,IAAM,GAAK,OAAO,GAAG,EAAG,EAAE,CAC5B,MAAO,GAGT,GACE,OAAO,GAAM,WACb,GACA,OAAO,GAAM,WACb,EAEA,MAAO,GAGT,GAAI,aAAa,KAAO,aAAa,IACnC,OAAO,EAAkB,EAAG,EAAE,CAGhC,GAAI,aAAa,KAAO,aAAa,IACnC,OAAO,EAAkB,EAAG,EAAE,CAGhC,IAAM,EAAO,OAAO,KAAK,EAAE,CAC3B,GAAI,EAAK,SAAW,OAAO,KAAK,EAAE,CAAC,OACjC,MAAO,GAGT,IAAK,IAAM,KAAO,EAAM,CACtB,GAAI,CAAC,OAAO,OAAO,EAAG,EAAI,CACxB,MAAO,GAGT,GAAM,EAAG,GAAiB,GAAW,EAC/B,EAAG,GAAiB,GAAW,EAErC,GAAI,IAAW,GAAU,CAAC,OAAO,GAAG,EAAQ,EAAO,CACjD,MAAO,GAIX,MAAO,GAGT,SAAS,EACP,EACA,EACS,CACT,GAAI,EAAE,OAAS,EAAE,KACf,MAAO,GAGT,IAAK,GAAM,CAAC,EAAK,KAAU,EAAG,CAC5B,IAAM,EAAS,EAAE,IAAI,EAAI,CACzB,GAAI,IAAU,GAAU,CAAC,OAAO,GAAG,EAAO,EAAO,CAC/C,MAAO,GAIX,MAAO,GAGT,SAAS,EACP,EACA,EACS,CACT,GAAI,EAAE,OAAS,EAAE,KACf,MAAO,GAGT,IAAK,IAAM,KAAS,EAClB,GAAI,CAAC,EAAE,IAAI,EAAM,CACf,MAAO,GAIX,MAAO"}