forked from lix-project/lix-website
1 line
22 KiB
Plaintext
1 line
22 KiB
Plaintext
|
{"version":3,"file":"fast-equals.js","sources":["../src/utils.ts","../src/comparator.ts","../src/index.ts"],"sourcesContent":["import type { EqualityComparator, InternalEqualityComparator } from './types';\n\ninterface Cache {\n delete: (key: object) => void;\n get: (key: object) => object | undefined;\n set: (key: object, value: object) => void;\n}\n\nconst HAS_WEAK_MAP_SUPPORT = typeof WeakMap === 'function';\n\nconst { keys } = Object;\n\n/**\n * are the values passed strictly equal or both NaN\n *\n * @param a the value to compare against\n * @param b the value to test\n * @returns are the values equal by the SameValueZero principle\n */\nexport function sameValueZeroEqual(a: any, b: any) {\n return a === b || (a !== a && b !== b);\n}\n\n/**\n * is the value a plain object\n *\n * @param value the value to test\n * @returns is the value a plain object\n */\nexport function isPlainObject(value: any) {\n return value.constructor === Object || value.constructor == null;\n}\n\n/**\n * is the value promise-like (meaning it is thenable)\n *\n * @param value the value to test\n * @returns is the value promise-like\n */\nexport function isPromiseLike(value: any) {\n return !!value && typeof value.then === 'function';\n}\n\n/**\n * is the value passed a react element\n *\n * @param value the value to test\n * @returns is the value a react element\n */\nexport function isReactElement(value: any) {\n return !!(value && value.$$typeof);\n}\n\n/**\n * in cases where WeakMap is not supported, creates a new custom\n * object that mimics the necessary API aspects for cache purposes\n *\n * @returns the new cache object\n */\nexport function getNewCacheFallback(): Cache {\n const entries: [object, object][] = [];\n\n return {\n delete(key: object) {\n for (let index = 0; index < entries.length; ++index) {\n if (entries[index][0] === key) {\n entries.splice(index, 1);\n return;\n }\n }\n },\n\n get(key: object) {\n for (let index = 0; index < entries.length; ++index) {\n if (entries[index][0] === key) {\n return entries[index][1];\n }\n }\n },\n\n set(key: object, value: object) {\n for (let index = 0; index < entries.length; ++index) {\n if (entries[index][0] === key) {\n entries[index][1] = value;\n return;\n }\n }\n\n entries.push([key, value]);\n }\n };\n}\n\n/**\n * get a new cache object to prevent circular references\n *\n * @returns the new cache object\n */\nexport const getNewCache = ((canUseWeakMap: boolean) => {\n if (canUseWeakMap) {\n return function _getNewCache(): Cache {\n return new WeakMap();\n };\n }\n\n return getNewCacheFallback;\n})(HAS_WEAK_MAP_SUPPORT);\n\n/**\n * create a custom isEqual handler specific to circular objects\n *\n * @param [isEqual] the isEqual comparator to use instead of isDeepEqual\n * @returns the method to create the `isEqual` function\n */\nexport function createCircularEqualCreator(isEqual?: EqualityComparator) {\n return function createCircularEqual(\n comparator: EqualityComparator,\n ): InternalEqualityComparator {\n const _comparator = isEqual || comparator;\n\n return function circularEqual(\n a,\n b,\n indexOrKeyA,\n indexOrKeyB,\n parentA,\n parentB,\n cache: Cache = getNewCache(),\n ) {\n const isCacheableA = !!a && typeof a === 'object';\n const isCacheableB = !!b && typeof b === 'object';\n\n if (isCacheableA !== isCacheableB) {\n return false;\n }\n\n if (!isCacheableA && !isCacheableB) {\n return _comparator(a, b, cache);\n }\n\n const cachedA = cache.get(a);\n \n if(cachedA && cache.get(b)) {\n return cachedA === b;\n }\n\n cache.set(a, b);\n cache.set(b, a);\n\n const result = _comparator(a, b, cache);\n\n cache.delete(a);\n cache.delete(b);\n\n return result;\n };\n };\n}\n\n/**\n * are the arrays equal in value\n *\n * @param a the array to test\n * @param b
|