// TODO: delete when this is merged: https://github.com/pmndrs/zustand/pull/1825/files export function isEqual(objA: T, objB: T) { return Object.is(objA, objB); } interface Keyed { id: string; } function instanceChecks(objA: T, objB: T, checkId = false) { if (objA instanceof Map && objB instanceof Map) { if (objA.size !== objB.size) return false; for (const [key, value] of objA) { if (!shallow(value, objB.get(key), checkId)) { return false; } } return true; } if (objA instanceof Set && objB instanceof Set) { if (objA.size !== objB.size) return false; for (const value of objA) { if (!objB.has(value)) { return false; } } return true; } if (objA instanceof Date && objB instanceof Date) { return objA.getTime() === objB.getTime(); } if ( checkId && (objA as unknown as Keyed)?.id && (objB as unknown as Keyed)?.id && (objA as unknown as Keyed)?.id === (objB as unknown as Keyed)?.id ) { return true; } return null; } export function shallow(objA: T, objB: T, checkId = false) { if (Object.is(objA, objB)) { return true; } if ( typeof objA !== "object" || objA === null || typeof objB !== "object" || objB === null ) { return false; } const known = instanceChecks(objA, objB, checkId); if (known !== null) { return known; } const keysA = Object.keys(objA); if (keysA.length !== Object.keys(objB).length) { return false; } for (let i = 0; i < keysA.length; i++) { const key = keysA[i] as keyof T; if ( !Object.prototype.hasOwnProperty.call(objB, keysA[i] as string) || !shallow(objA[key], objB[key], checkId) ) { return false; } } return true; } // this function checks to see if the subject is at least equal with the base but permits the base to have additional fields export function partialShallow( subject: Partial, base: T, checkId = false, ) { if (Object.is(subject, base)) { return true; } if ( typeof subject !== "object" || subject === null || typeof base !== "object" || base === null ) { return false; } const known = instanceChecks(subject, base, checkId); if (known !== null) { return known; } const keysSubject = Object.keys(subject); if (keysSubject.length > Object.keys(base as Record).length) { return false; } for (let i = 0; i < keysSubject.length; i++) { const key = keysSubject[i] as keyof T; if ( !Object.prototype.hasOwnProperty.call(base, keysSubject[i] as string) || !shallow(subject[key], base[key], checkId) ) { return false; } } return true; }