@apollo/client@4.3.0-alpha.5
Pre-releaseMinor Changes
-
#13390
90e338cThanks @jerelmiller! - Fix issue where sibling@deferfragments were pruned incorrectly when at least one of the@deferfragments wasn't delivered.As a result of this change, a
labelargument is now added to all outgoing@deferdirectives when using theGraphQL17Alpha9Handlerin order to disambiguate the@deferfragments from each other. -
#13393
434d25fThanks @jerelmiller! - Change when@deferfragments and@streamfields are pruned forcache-firstandcache-and-networkfetch policies to better match the network when the initial value contained a partial result:cache-first: prune undelivered@deferfragments or@streamitems when the result is fetched from the network due to a partial resultcache-and-network: prune undelivered@deferfragments or@streamitems if the initial cache value was partial. If the first value emitted from the cache is complete, the results will not be pruned.
This makes the emitted results more predictable by following what the network has delivered and avoids some ambiguity in other edge cases.
For example, with a
cache-firstfetch policy where all@deferfields are written to the cache, but a non-deferred field is partial, the values emitted from the client previously looked like the following:query { user { id name ... @defer { email } } }
// data written to the cache is missing name { user: { id: 1, email: "user.cache@example.com" }} // 1. empty because the result is partial { data: undefined, dataState: "empty", ... } // 2. returns all data because the cache contains a value for email { data: { user: 1, name: "User", email: "user.cache@example.com" }, dataState: "complete" } // 3. email updated from the server { data: { user: 1, name: "User", email: "user.network@example.com" }, dataState: "complete" }
Here the result is confusing because the initial value returned from the query was
undefined, yet a complete result was returned after the initial chunk from the network returned (which did not containemail).The cache values are now pruned if the network hasn't delivered them yet:
// 1. empty because the result is partial { data: undefined, dataState: "empty" } // 2. email hasn't been delivered by the network so it gets pruned { data: { user: 1, name: "User" }, dataState: "streaming" } // 3. full result returned after the network streams the email field { data: { user: 1, name: "User", email: "user.network@example.com" }, dataState: "complete" }
This is especially helpful in situations where
@deferboundaries that are never delivered due to errors prevent an awkward situation where the client would otherwise have to choose whether to serve the stale cache result from the cache, or prune the undelivered fragment on the final chunk.
Patch Changes
-
#13381
9c73762Thanks @jerelmiller! - Fix an issue where anetwork-onlyquery leaked partial cache data for@deferfragments that were not delivered by the network due to an error that bubbled to the@deferfragment boundary. -
#13390
90e338cThanks @jerelmiller! - Fix an issue where a sibling non-deferred fragment might be accidentally pruned when the@deferfragment hadn't been delivered. -
#13403
aaff7a8Thanks @jerelmiller! - Fix issue where the wrongdataStatewas returned when there was nothing written to the cache and a@deferfragment was marked pending. -
#13381
9c73762Thanks @jerelmiller! - Fix an issue where a@deferquery reported thedataStateascompleteinstead ofstreamingwhen an error occurs on a deferred field that bubbled to the defer boundary. -
#13373
2551937Thanks @jerelmiller! - Fix an issue where a cache write in the middle of polling would remain as the query value if future poll requests returned deep equal results to previous polling results. -
#13403
aaff7a8Thanks @jerelmiller! - Fix issue where settingreturnPartialData: truemight report the wrongdataStatewhen partial data was written to the cache and@deferfragments were pending. -
#13381
9c73762Thanks @jerelmiller! - Fix an invariant error thrown when a@deferboundary received a payload after it had already been marked complete.