-
Notifications
You must be signed in to change notification settings - Fork 2.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merge incoming fragment fields before running merge
functions and updating the EntityStore
#8372
Conversation
Fixes #8370 by postponing all context.store.merge updates until after all processSelectionSet work is done, performing the store updates at the end of StoreWriter#writeToStore, whereas previously those updates happened at the end of each StoreWriter#processSelectionSet call. The postponement of store updates gives the StoreWriter a chance to merge together multiple partial objects representing the same logical object (possibly matched by different fragments along different query paths), before running merge functions with applyMerges. Previously, those partial objects would be merged separately into context.store, so later objects might replace earlier objects in cases where the objects are unidentifiable/non-normalized, and there is no merge function (or merge:true) to force the objects to merge. Of course, you could configure merge:true to explicily permit merging unidentified objects with a given __typename. Configuring merge:true for the 'Container' type seems to fixes the reproduction in #8370. But this explicit configuration should not be necessary when we know the objects in question represent the same logical object, because they were derived from the same original result object (same ID, not necessarily ===). In other words, this PR should wipe out a whole class of situations where we used to show "Cache data may be lost..." warnings, since we can now safely merge the fields of unidentifiable objects that share the same original result object, without requiring an explicit merge:true configuration to permit that mixing of fields.
3ba39b6
to
4935d11
Compare
merge
functions and updating the EntityStore
it('correctly merges fragment fields along multiple paths', () => { | ||
const cache = new InMemoryCache({ | ||
typePolicies: { | ||
Container: { | ||
// Uncommenting this line fixes the test, but should not be necessary, | ||
// since the Container response object in question has the same | ||
// identity along both paths. | ||
// merge: true, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As I wrote in #8370 (comment), this merge: true
configuration was going to be my answer to issue #8370, before I realized that it shouldn't be necessary (hence this PR).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Don’t have the full context of writeToStore stuff but that bug should probably be fixed.
Fixes #8370 by postponing all
context.store.merge
updates until after allprocessSelectionSet
work is done, performing the store updates at the end ofStoreWriter#writeToStore
, whereas previously those updates happened at the end of eachStoreWriter#processSelectionSet
call.The postponement of store updates gives the
StoreWriter
a chance to merge together multiple partial objects representing the same logical object (possibly matched by different fragments along different query paths), before runningmerge
functions withapplyMerges
.Previously, those partial objects would be merged separately into
context.store
, so later objects might replace earlier objects in cases where the objects are unidentifiable/non-normalized, and there was nomerge
function (ormerge: true
shorthand) to force the objects to merge.Of course, you could configure
merge: true
to explicitly permit merging unidentified objects with a given__typename
. Configuringmerge: true
for theContainer
type seems to fixes the reproduction in #8370. But this explicit configuration should not be necessary when we know the objects in question represent the same logical object, because they were derived from the same incoming result object (same ID, not necessarily===
objects).In other words, this PR should wipe out a whole class of situations where we used to show
Cache data may be lost...
warnings, since we can now safely merge the fields of unidentifiable objects that share the same original result object, without requiring an explicitmerge: true
configuration to permit that mixing of fields.