fix(query-core): shallowEqualObjects ignores key-set differences when counts match#10777
Conversation
… counts match `shallowEqualObjects` only iterated the keys of `a` and compared `a[key] !== b[key]`. When both objects have the same number of keys but different key names, a key present on `a` but absent on `b` reads as `undefined` on `b`; if the corresponding value on `a` is also `undefined` (or otherwise equal), the function incorrectly reported the objects as equal. This breaks the documented "shallow compare objects" contract and can suppress an `observerOptionsUpdated` notification when an observer's defaulted options swap one key for another between renders. Fix: require each key of `a` to be an own-property of `b` before comparing values.
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (2)
📝 WalkthroughWalkthroughThis PR fixes ChangesOwn-property shallow equality validation
🎯 2 (Simple) | ⏱️ ~8 minutes Suggested reviewers
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 inconclusive)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
What
shallowEqualObjectsnow returnsfalsewhen two objects have the same number of keys but different key names (e.g.{ a: 1, b: undefined }vs{ a: 1, c: undefined }).Why
The function only iterated over
a's keys and compareda[key] !== b[key]. A key present onabut missing frombreads asundefinedonb; ifa's value for that key is alsoundefined(or otherwise equal), the objects compared as equal despite having different key sets — violating the documented "shallow compare objects" contract. Real call site:QueryObserver.setOptionsgates theobserverOptionsUpdatednotification with this comparison, so swapping one defaulted option key for another between renders could silently suppress that notification.Safety
Pure utility change; an additive own-property guard. No existing test asserted the old (incorrect) behaviour. Result-object comparisons (which use fixed-shape objects) are unaffected, so there is no behavioural or performance regression for the common path.
Testing
Added
should return 'false' for same-length objects with different keystoutils.test.tsx: it fails on the current code (expected true to deeply equal false) and passes after the fix. Full query-core runtime suite green (480/480), typecheck clean.Impact
Tighter, contract-correct shallow equality — restores correct change-detection for option updates that swap keys without changing key count.
Summary by CodeRabbit