Performance improvements: structural sharing & moderation opts context (#3785)
* Fix: correctly apply structural sharing to preferences object * Move moderation opts into a context * Fix import * Remove log * Pass userdid directly * Pass moderationPrefs directly
This commit is contained in:
parent
39807a8630
commit
31cb3e5422
25 changed files with 231 additions and 120 deletions
|
@ -9,3 +9,90 @@ export function dedupArray<T>(arr: T[]): T[] {
|
|||
const s = new Set(arr)
|
||||
return [...s]
|
||||
}
|
||||
|
||||
/**
|
||||
* Taken from @tanstack/query-core utils.ts
|
||||
* Modified to support Date object comparisons
|
||||
*
|
||||
* This function returns `a` if `b` is deeply equal.
|
||||
* If not, it will replace any deeply equal children of `b` with those of `a`.
|
||||
* This can be used for structural sharing between JSON values for example.
|
||||
*/
|
||||
export function replaceEqualDeep(a: any, b: any): any {
|
||||
if (a === b) {
|
||||
return a
|
||||
}
|
||||
|
||||
if (a instanceof Date && b instanceof Date) {
|
||||
return a.getTime() === b.getTime() ? a : b
|
||||
}
|
||||
|
||||
const array = isPlainArray(a) && isPlainArray(b)
|
||||
|
||||
if (array || (isPlainObject(a) && isPlainObject(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: any = array ? [] : {}
|
||||
|
||||
let equalItems = 0
|
||||
|
||||
for (let i = 0; i < bSize; i++) {
|
||||
const key = array ? i : bItems[i]
|
||||
if (
|
||||
!array &&
|
||||
a[key] === undefined &&
|
||||
b[key] === undefined &&
|
||||
aItems.includes(key)
|
||||
) {
|
||||
copy[key] = undefined
|
||||
equalItems++
|
||||
} else {
|
||||
copy[key] = replaceEqualDeep(a[key], b[key])
|
||||
if (copy[key] === a[key] && a[key] !== undefined) {
|
||||
equalItems++
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return aSize === bSize && equalItems === aSize ? a : copy
|
||||
}
|
||||
|
||||
return b
|
||||
}
|
||||
|
||||
export function isPlainArray(value: unknown) {
|
||||
return Array.isArray(value) && value.length === Object.keys(value).length
|
||||
}
|
||||
|
||||
// Copied from: https://github.com/jonschlinkert/is-plain-object
|
||||
export function isPlainObject(o: any): o is Object {
|
||||
if (!hasObjectPrototype(o)) {
|
||||
return false
|
||||
}
|
||||
|
||||
// If has no constructor
|
||||
const ctor = o.constructor
|
||||
if (ctor === undefined) {
|
||||
return true
|
||||
}
|
||||
|
||||
// If has modified prototype
|
||||
const prot = ctor.prototype
|
||||
if (!hasObjectPrototype(prot)) {
|
||||
return false
|
||||
}
|
||||
|
||||
// If constructor does not have an Object-specific method
|
||||
if (!prot.hasOwnProperty('isPrototypeOf')) {
|
||||
return false
|
||||
}
|
||||
|
||||
// Most likely a plain Object
|
||||
return true
|
||||
}
|
||||
|
||||
function hasObjectPrototype(o: any): boolean {
|
||||
return Object.prototype.toString.call(o) === '[object Object]'
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue