You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
When partial data is written to the cache and returnPartialData is either false or not set, incremental chunks may still return partial data in a response with a dataState of streaming.
This is primarily due to these lines in QueryInfo:
We unconditionally pull partial data from the cache and apply it with the incremental result which mixes the partial cache data into the final result. See the reproduction in the test case below which demonstrates the issue. What we should get is a result back where the only hole in the data is at the @defer boundary and ensure partial data inside that boundary is omitted.
Note
I (Jerel) plan to implement this fix as it requires code from another pull request and with a specific implementation that will fix this as the cache level. Please do not attempt to fix this yourself.
Link to Reproduction
n/a
Reproduction Steps
The following test demonstrates the issue
test('returns non-deferred cached data with a "cache-first" fetch policy and returnPartialData: false',async()=>{constquery=gql` query { greeting { message ... on Greeting @defer { recipient { name email } } } } `;const{ httpLink, enqueueInitialChunk, enqueueSubsequentChunk }=mockDeferStreamGraphQL17Alpha9();constcache=newInMemoryCache();// We are intentionally writing partial data to the cache. Suppress console// warnings to avoid unnecessary noise in the test.{
using _consoleSpy=spyOnConsole("error");cache.writeQuery({
query,data: {greeting: {__typename: "Greeting",recipient: {email: "test@example.com",},},},});}constclient=newApolloClient({
cache,link: httpLink,incrementalHandler: newGraphQL17Alpha9Handler(),});conststream=newObservableStream(client.watchQuery({ query }));awaitexpect(stream).toEmitTypedValue({data: undefined,dataState: "empty",loading: true,networkStatus: NetworkStatus.loading,partial: true,});enqueueInitialChunk({data: {greeting: {message: "Hello world",__typename: "Greeting"}},pending: [{id: "0",path: ["greeting"]}],hasNext: true,});awaitexpect(stream).toEmitTypedValue({data: markAsStreaming({greeting: {__typename: "Greeting",message: "Hello world",},}),dataState: "streaming",loading: true,networkStatus: NetworkStatus.streaming,partial: true,});enqueueSubsequentChunk({incremental: [{data: {__typename: "Greeting",recipient: {name: "Alice",__typename: "Person"},},id: "0",},],completed: [{id: "0"}],hasNext: false,});awaitexpect(stream).toEmitTypedValue({data: {greeting: {__typename: "Greeting",message: "Hello world",recipient: {__typename: "Person",name: "Alice"},},},dataState: "complete",loading: false,networkStatus: NetworkStatus.ready,partial: false,});awaitexpect(stream).not.toEmitAnything();});
Issue Description
When partial data is written to the cache and
returnPartialDatais eitherfalseor not set, incremental chunks may still return partial data in a response with adataStateofstreaming.This is primarily due to these lines in
QueryInfo:We unconditionally pull partial data from the cache and apply it with the incremental result which mixes the partial cache data into the final result. See the reproduction in the test case below which demonstrates the issue. What we should get is a result back where the only hole in the data is at the
@deferboundary and ensure partial data inside that boundary is omitted.Note
I (Jerel) plan to implement this fix as it requires code from another pull request and with a specific implementation that will fix this as the cache level. Please do not attempt to fix this yourself.
Link to Reproduction
n/a
Reproduction Steps
The following test demonstrates the issue
@apollo/clientversion4.x