Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit67c16c9

Browse files
authored
keep deferred inFlightLinkObservables until the response is finished (#12338)
1 parent80a68aa commit67c16c9

File tree

5 files changed

+150
-6
lines changed

5 files changed

+150
-6
lines changed

‎.changeset/quiet-apricots-reply.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
"@apollo/client":patch
3+
---
4+
5+
In case of a multipart response (e.g. with`@defer`), query deduplication will
6+
now keep going until the final chunk has been received.

‎.size-limits.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
{
2-
"dist/apollo-client.min.cjs":42196,
3-
"import { ApolloClient, InMemoryCache, HttpLink } from\"dist/index.js\" (production)":34405
2+
"dist/apollo-client.min.cjs":42225,
3+
"import { ApolloClient, InMemoryCache, HttpLink } from\"dist/index.js\" (production)":34432
44
}

‎src/config/jest/setup.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,3 +36,6 @@ if (!Symbol.asyncDispose) {
3636

3737
//@ts-ignore
3838
expect.addEqualityTesters([areApolloErrorsEqual,areGraphQLErrorsEqual]);
39+
40+
// not available in JSDOM 🙄
41+
global.structuredClone=(val)=>JSON.parse(JSON.stringify(val));

‎src/core/QueryManager.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1182,8 +1182,12 @@ export class QueryManager<TStore> {
11821182
]);
11831183
observable=entry.observable=concast;
11841184

1185-
concast.beforeNext(()=>{
1186-
inFlightLinkObservables.remove(printedServerQuery,varJson);
1185+
concast.beforeNext(functioncb(method,arg:FetchResult){
1186+
if(method==="next"&&"hasNext"inarg&&arg.hasNext){
1187+
concast.beforeNext(cb);
1188+
}else{
1189+
inFlightLinkObservables.remove(printedServerQuery,varJson);
1190+
}
11871191
});
11881192
}
11891193
}else{

‎src/core/__tests__/ApolloClient/general.test.ts

Lines changed: 133 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,11 @@ import {
99
Observable,
1010
Observer,
1111
}from"../../../utilities/observables/Observable";
12-
import{ApolloLink,FetchResult}from"../../../link/core";
12+
import{
13+
ApolloLink,
14+
FetchResult,
15+
typeRequestHandler,
16+
}from"../../../link/core";
1317
import{InMemoryCache}from"../../../cache";
1418

1519
// mocks
@@ -31,7 +35,11 @@ import { wait } from "../../../testing/core";
3135
import{ApolloClient}from"../../../core";
3236
import{mockFetchQuery}from"../ObservableQuery";
3337
import{Concast,print}from"../../../utilities";
34-
import{ObservableStream,spyOnConsole}from"../../../testing/internal";
38+
import{
39+
mockDeferStream,
40+
ObservableStream,
41+
spyOnConsole,
42+
}from"../../../testing/internal";
3543

3644
describe("ApolloClient",()=>{
3745
constgetObservableStream=({
@@ -6522,6 +6530,129 @@ describe("ApolloClient", () => {
65226530
)
65236531
).toBeUndefined();
65246532
});
6533+
6534+
it("deduplicates queries as long as a query still has deferred chunks",async()=>{
6535+
constquery=gql`
6536+
query LazyLoadLuke {
6537+
people(id: 1) {
6538+
id
6539+
name
6540+
friends {
6541+
id
6542+
... @defer {
6543+
name
6544+
}
6545+
}
6546+
}
6547+
}
6548+
`;
6549+
6550+
constoutgoingRequestSpy=jest.fn(((operation,forward)=>
6551+
forward(operation))satisfiesRequestHandler);
6552+
constdefer=mockDeferStream();
6553+
constclient=newApolloClient({
6554+
cache:newInMemoryCache({}),
6555+
link:newApolloLink(outgoingRequestSpy).concat(defer.httpLink),
6556+
});
6557+
6558+
constquery1=newObservableStream(
6559+
client.watchQuery({ query,fetchPolicy:"network-only"})
6560+
);
6561+
constquery2=newObservableStream(
6562+
client.watchQuery({ query,fetchPolicy:"network-only"})
6563+
);
6564+
expect(outgoingRequestSpy).toHaveBeenCalledTimes(1);
6565+
6566+
constinitialData={
6567+
people:{
6568+
__typename:"Person",
6569+
id:1,
6570+
name:"Luke",
6571+
friends:[
6572+
{
6573+
__typename:"Person",
6574+
id:5,
6575+
}as{__typename:"Person";id:number;name?:string},
6576+
{
6577+
__typename:"Person",
6578+
id:8,
6579+
}as{__typename:"Person";id:number;name?:string},
6580+
],
6581+
},
6582+
};
6583+
constinitialResult={
6584+
data:initialData,
6585+
loading:false,
6586+
networkStatus:7,
6587+
};
6588+
6589+
defer.enqueueInitialChunk({
6590+
data:initialData,
6591+
hasNext:true,
6592+
});
6593+
6594+
awaitexpect(query1).toEmitFetchResult(initialResult);
6595+
awaitexpect(query2).toEmitFetchResult(initialResult);
6596+
6597+
constquery3=newObservableStream(
6598+
client.watchQuery({ query,fetchPolicy:"network-only"})
6599+
);
6600+
awaitexpect(query3).toEmitFetchResult(initialResult);
6601+
expect(outgoingRequestSpy).toHaveBeenCalledTimes(1);
6602+
6603+
constfirstChunk={
6604+
incremental:[
6605+
{
6606+
data:{
6607+
name:"Leia",
6608+
},
6609+
path:["people","friends",0],
6610+
},
6611+
],
6612+
hasNext:true,
6613+
};
6614+
constresultAfterFirstChunk=structuredClone(initialResult);
6615+
resultAfterFirstChunk.data.people.friends[0].name="Leia";
6616+
6617+
defer.enqueueSubsequentChunk(firstChunk);
6618+
6619+
awaitexpect(query1).toEmitFetchResult(resultAfterFirstChunk);
6620+
awaitexpect(query2).toEmitFetchResult(resultAfterFirstChunk);
6621+
awaitexpect(query3).toEmitFetchResult(resultAfterFirstChunk);
6622+
6623+
constquery4=newObservableStream(
6624+
client.watchQuery({ query,fetchPolicy:"network-only"})
6625+
);
6626+
expect(query4).toEmitFetchResult(resultAfterFirstChunk);
6627+
expect(outgoingRequestSpy).toHaveBeenCalledTimes(1);
6628+
6629+
constsecondChunk={
6630+
incremental:[
6631+
{
6632+
data:{
6633+
name:"Han Solo",
6634+
},
6635+
path:["people","friends",1],
6636+
},
6637+
],
6638+
hasNext:false,
6639+
};
6640+
constresultAfterSecondChunk=structuredClone(resultAfterFirstChunk);
6641+
resultAfterSecondChunk.data.people.friends[1].name="Han Solo";
6642+
6643+
defer.enqueueSubsequentChunk(secondChunk);
6644+
6645+
awaitexpect(query1).toEmitFetchResult(resultAfterSecondChunk);
6646+
awaitexpect(query2).toEmitFetchResult(resultAfterSecondChunk);
6647+
awaitexpect(query3).toEmitFetchResult(resultAfterSecondChunk);
6648+
awaitexpect(query4).toEmitFetchResult(resultAfterSecondChunk);
6649+
6650+
constquery5=newObservableStream(
6651+
client.watchQuery({ query,fetchPolicy:"network-only"})
6652+
);
6653+
expect(query5).not.toEmitAnything();
6654+
expect(outgoingRequestSpy).toHaveBeenCalledTimes(2);
6655+
});
65256656
});
65266657

65276658
describe("missing cache field warnings",()=>{

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp