mirror of
https://github.com/pmndrs/zustand.git
synced 2025-12-08 19:45:52 +00:00
[v5] Rewrite shallow to support iterables (#2427)
This commit is contained in:
parent
bfbbaccfa0
commit
4ac0950e71
@ -1,4 +1,22 @@
|
||||
export function shallow<T>(objA: T, objB: T) {
|
||||
const isIterable = (obj: object): obj is Iterable<unknown> =>
|
||||
Symbol.iterator in obj
|
||||
|
||||
const compareMapLike = (
|
||||
iterableA: Iterable<[unknown, unknown]>,
|
||||
iterableB: Iterable<[unknown, unknown]>,
|
||||
) => {
|
||||
const mapA = iterableA instanceof Map ? iterableA : new Map(iterableA)
|
||||
const mapB = iterableB instanceof Map ? iterableB : new Map(iterableB)
|
||||
if (mapA.size !== mapB.size) return false
|
||||
for (const [key, value] of mapA) {
|
||||
if (!Object.is(value, mapB.get(key))) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
export function shallow<T>(objA: T, objB: T): boolean {
|
||||
if (Object.is(objA, objB)) {
|
||||
return true
|
||||
}
|
||||
@ -11,26 +29,30 @@ export function shallow<T>(objA: T, objB: T) {
|
||||
return false
|
||||
}
|
||||
|
||||
if (objA instanceof Map && objB instanceof Map) {
|
||||
if (objA.size !== objB.size) return false
|
||||
|
||||
for (const [key, value] of objA) {
|
||||
if (!Object.is(value, objB.get(key))) {
|
||||
if (isIterable(objA) && isIterable(objB)) {
|
||||
const iteratorA = objA[Symbol.iterator]()
|
||||
const iteratorB = objB[Symbol.iterator]()
|
||||
let nextA = iteratorA.next()
|
||||
let nextB = iteratorB.next()
|
||||
if (
|
||||
Array.isArray(nextA.value) &&
|
||||
Array.isArray(nextB.value) &&
|
||||
nextA.value.length === 2 &&
|
||||
nextB.value.length === 2
|
||||
) {
|
||||
return compareMapLike(
|
||||
objA as Iterable<[unknown, unknown]>,
|
||||
objB as Iterable<[unknown, unknown]>,
|
||||
)
|
||||
}
|
||||
while (!nextA.done && !nextB.done) {
|
||||
if (!Object.is(nextA.value, nextB.value)) {
|
||||
return false
|
||||
}
|
||||
nextA = iteratorA.next()
|
||||
nextB = iteratorB.next()
|
||||
}
|
||||
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
|
||||
return !!nextA.done && !!nextB.done
|
||||
}
|
||||
|
||||
const keysA = Object.keys(objA)
|
||||
|
||||
@ -91,6 +91,12 @@ describe('shallow', () => {
|
||||
|
||||
expect(shallow(firstFnCompare, secondFnCompare)).toBe(false)
|
||||
})
|
||||
|
||||
it('compares URLSearchParams', () => {
|
||||
const a = new URLSearchParams({ hello: 'world' })
|
||||
const b = new URLSearchParams({ zustand: 'shallow' })
|
||||
expect(shallow(a, b)).toBe(false)
|
||||
})
|
||||
})
|
||||
|
||||
describe('unsupported cases', () => {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user