README.md
Rendering markdown...
// Copy of TanStack's replaceEqualDeep
function isPlainObject(o) {
return Object.prototype.toString.call(o) === '[object Object]'
&& Object.getPrototypeOf(o) === Object.prototype;
}
function isPlainArray(value) {
return Array.isArray(value) && value.length === Object.keys(value).length;
}
function replaceEqualDeep(a, b) {
if (a === b) return a;
const array = isPlainArray(a) && isPlainArray(b);
if (!array && !(isPlainObject(a) && isPlainObject(b))) return b;
const aItems = array ? a : Object.keys(a);
const aSize = aItems.length;
const bItems = array ? b : Object.keys(b);
const bSize = bItems.length;
const copy = array ? new Array(bSize) : {};
let equalItems = 0;
for (let i = 0; i < bSize; i++) {
const key = array ? i : bItems[i];
if (a[key] === b[key]) {
copy[key] = a[key];
equalItems++;
continue;
}
if (a[key] === null || b[key] === null ||
typeof a[key] !== 'object' || typeof b[key] !== 'object') {
copy[key] = b[key];
continue;
}
const v = replaceEqualDeep(a[key], b[key]);
copy[key] = v;
if (v === a[key]) equalItems++;
}
return aSize === bSize && equalItems === aSize ? a : copy;
}
// Generate deeply nested object
function generateDeep(depth) {
let obj = { value: 'end' };
for (let i = 0; i < depth; i++) {
obj = { nested: obj };
}
return obj;
}
// TEST
console.log('Testing replaceEqualDeep with deep nesting...');
const depths = [100, 1000, 5000, 10000];
for (const depth of depths) {
const oldData = generateDeep(depth);
const newData = generateDeep(depth); // Different object, same structure
console.log(`\nDepth: ${depth}`);
const start = Date.now();
try {
replaceEqualDeep(oldData, newData);
console.log(` OK - ${Date.now() - start}ms`);
} catch (e) {
console.log(` CRASH - ${e.message}`);
}
}