Skip to content

Commit d88c7f8

Browse files
authored
Add subscribeToMore function to useBackgroundQuery, useQueryRefHandlers, and useLoadableQuery (#11923)
1 parent 5ae4876 commit d88c7f8

16 files changed

+602
-38
lines changed

.api-reports/api-report-react.api.md

+7-5
Original file line numberDiff line numberDiff line change
@@ -2089,6 +2089,7 @@ UseBackgroundQueryResult<TData, TVariables>
20892089

20902090
// @public (undocumented)
20912091
export type UseBackgroundQueryResult<TData = unknown, TVariables extends OperationVariables = OperationVariables> = {
2092+
subscribeToMore: SubscribeToMoreFunction<TData, TVariables>;
20922093
fetchMore: FetchMoreFunction<TData, TVariables>;
20932094
refetch: RefetchFunction<TData, TVariables>;
20942095
};
@@ -2148,6 +2149,7 @@ queryRef: QueryRef<TData, TVariables> | null,
21482149
handlers: {
21492150
fetchMore: FetchMoreFunction<TData, TVariables>;
21502151
refetch: RefetchFunction<TData, TVariables>;
2152+
subscribeToMore: SubscribeToMoreFunction<TData, TVariables>;
21512153
reset: ResetFunction;
21522154
}
21532155
];
@@ -2165,6 +2167,7 @@ export function useQueryRefHandlers<TData = unknown, TVariables extends Operatio
21652167
export interface UseQueryRefHandlersResult<TData = unknown, TVariables extends OperationVariables = OperationVariables> {
21662168
fetchMore: FetchMoreFunction<TData, TVariables>;
21672169
refetch: RefetchFunction<TData, TVariables>;
2170+
subscribeToMore: SubscribeToMoreFunction<TData, TVariables>;
21682171
}
21692172

21702173
// Warning: (ae-forgotten-export) The symbol "ReactiveVar" needs to be exported by the entry point index.d.ts
@@ -2240,8 +2243,6 @@ export interface UseSuspenseQueryResult<TData = unknown, TVariables extends Oper
22402243
networkStatus: NetworkStatus;
22412244
// (undocumented)
22422245
refetch: RefetchFunction<TData, TVariables>;
2243-
// Warning: (ae-forgotten-export) The symbol "SubscribeToMoreFunction" needs to be exported by the entry point index.d.ts
2244-
//
22452246
// (undocumented)
22462247
subscribeToMore: SubscribeToMoreFunction<TData, TVariables>;
22472248
}
@@ -2305,9 +2306,10 @@ interface WatchQueryOptions<TVariables extends OperationVariables = OperationVar
23052306
// src/core/types.ts:203:5 - (ae-forgotten-export) The symbol "Resolver" needs to be exported by the entry point index.d.ts
23062307
// src/core/watchQueryOptions.ts:269:2 - (ae-forgotten-export) The symbol "IgnoreModifier" needs to be exported by the entry point index.d.ts
23072308
// src/core/watchQueryOptions.ts:269:2 - (ae-forgotten-export) The symbol "UpdateQueryFn" needs to be exported by the entry point index.d.ts
2308-
// src/react/hooks/useBackgroundQuery.ts:29:3 - (ae-forgotten-export) The symbol "FetchMoreFunction" needs to be exported by the entry point index.d.ts
2309-
// src/react/hooks/useBackgroundQuery.ts:30:3 - (ae-forgotten-export) The symbol "RefetchFunction" needs to be exported by the entry point index.d.ts
2310-
// src/react/hooks/useLoadableQuery.ts:107:1 - (ae-forgotten-export) The symbol "ResetFunction" needs to be exported by the entry point index.d.ts
2309+
// src/react/hooks/useBackgroundQuery.ts:38:3 - (ae-forgotten-export) The symbol "SubscribeToMoreFunction" needs to be exported by the entry point index.d.ts
2310+
// src/react/hooks/useBackgroundQuery.ts:54:3 - (ae-forgotten-export) The symbol "FetchMoreFunction" needs to be exported by the entry point index.d.ts
2311+
// src/react/hooks/useBackgroundQuery.ts:78:4 - (ae-forgotten-export) The symbol "RefetchFunction" needs to be exported by the entry point index.d.ts
2312+
// src/react/hooks/useLoadableQuery.ts:120:9 - (ae-forgotten-export) The symbol "ResetFunction" needs to be exported by the entry point index.d.ts
23112313

23122314
// (No @packageDocumentation comment for this package)
23132315

.api-reports/api-report-react_hooks.api.md

+7-5
Original file line numberDiff line numberDiff line change
@@ -1913,6 +1913,7 @@ UseBackgroundQueryResult<TData, TVariables>
19131913

19141914
// @public (undocumented)
19151915
export type UseBackgroundQueryResult<TData = unknown, TVariables extends OperationVariables = OperationVariables> = {
1916+
subscribeToMore: SubscribeToMoreFunction<TData, TVariables>;
19161917
fetchMore: FetchMoreFunction<TData, TVariables>;
19171918
refetch: RefetchFunction<TData, TVariables>;
19181919
};
@@ -1976,6 +1977,7 @@ queryRef: QueryRef<TData, TVariables> | null,
19761977
handlers: {
19771978
fetchMore: FetchMoreFunction<TData, TVariables>;
19781979
refetch: RefetchFunction<TData, TVariables>;
1980+
subscribeToMore: SubscribeToMoreFunction<TData, TVariables>;
19791981
reset: ResetFunction;
19801982
}
19811983
];
@@ -1996,6 +1998,7 @@ export function useQueryRefHandlers<TData = unknown, TVariables extends Operatio
19961998
export interface UseQueryRefHandlersResult<TData = unknown, TVariables extends OperationVariables = OperationVariables> {
19971999
fetchMore: FetchMoreFunction<TData, TVariables>;
19982000
refetch: RefetchFunction<TData, TVariables>;
2001+
subscribeToMore: SubscribeToMoreFunction<TData, TVariables>;
19992002
}
20002003

20012004
// Warning: (ae-forgotten-export) The symbol "ReactiveVar" needs to be exported by the entry point index.d.ts
@@ -2075,8 +2078,6 @@ export interface UseSuspenseQueryResult<TData = unknown, TVariables extends Oper
20752078
networkStatus: NetworkStatus;
20762079
// (undocumented)
20772080
refetch: RefetchFunction<TData, TVariables>;
2078-
// Warning: (ae-forgotten-export) The symbol "SubscribeToMoreFunction" needs to be exported by the entry point index.d.ts
2079-
//
20802081
// (undocumented)
20812082
subscribeToMore: SubscribeToMoreFunction<TData, TVariables>;
20822083
}
@@ -2129,9 +2130,10 @@ interface WatchQueryOptions<TVariables extends OperationVariables = OperationVar
21292130
// src/core/types.ts:203:5 - (ae-forgotten-export) The symbol "Resolver" needs to be exported by the entry point index.d.ts
21302131
// src/core/watchQueryOptions.ts:269:2 - (ae-forgotten-export) The symbol "IgnoreModifier" needs to be exported by the entry point index.d.ts
21312132
// src/core/watchQueryOptions.ts:269:2 - (ae-forgotten-export) The symbol "UpdateQueryFn" needs to be exported by the entry point index.d.ts
2132-
// src/react/hooks/useBackgroundQuery.ts:29:3 - (ae-forgotten-export) The symbol "FetchMoreFunction" needs to be exported by the entry point index.d.ts
2133-
// src/react/hooks/useBackgroundQuery.ts:30:3 - (ae-forgotten-export) The symbol "RefetchFunction" needs to be exported by the entry point index.d.ts
2134-
// src/react/hooks/useLoadableQuery.ts:107:1 - (ae-forgotten-export) The symbol "ResetFunction" needs to be exported by the entry point index.d.ts
2133+
// src/react/hooks/useBackgroundQuery.ts:38:3 - (ae-forgotten-export) The symbol "SubscribeToMoreFunction" needs to be exported by the entry point index.d.ts
2134+
// src/react/hooks/useBackgroundQuery.ts:54:3 - (ae-forgotten-export) The symbol "FetchMoreFunction" needs to be exported by the entry point index.d.ts
2135+
// src/react/hooks/useBackgroundQuery.ts:78:4 - (ae-forgotten-export) The symbol "RefetchFunction" needs to be exported by the entry point index.d.ts
2136+
// src/react/hooks/useLoadableQuery.ts:120:9 - (ae-forgotten-export) The symbol "ResetFunction" needs to be exported by the entry point index.d.ts
21352137

21362138
// (No @packageDocumentation comment for this package)
21372139

.api-reports/api-report-react_internal.api.md

+5-4
Original file line numberDiff line numberDiff line change
@@ -1923,6 +1923,7 @@ UseBackgroundQueryResult<TData, TVariables>
19231923

19241924
// @public (undocumented)
19251925
type UseBackgroundQueryResult<TData = unknown, TVariables extends OperationVariables = OperationVariables> = {
1926+
subscribeToMore: SubscribeToMoreFunction<TData, TVariables>;
19261927
fetchMore: FetchMoreFunction<TData, TVariables>;
19271928
refetch: RefetchFunction<TData, TVariables>;
19281929
};
@@ -1967,6 +1968,7 @@ function useQueryRefHandlers<TData = unknown, TVariables extends OperationVariab
19671968
interface UseQueryRefHandlersResult<TData = unknown, TVariables extends OperationVariables = OperationVariables> {
19681969
fetchMore: FetchMoreFunction<TData, TVariables>;
19691970
refetch: RefetchFunction<TData, TVariables>;
1971+
subscribeToMore: SubscribeToMoreFunction<TData, TVariables>;
19701972
}
19711973

19721974
// Warning: (ae-forgotten-export) The symbol "UseReadQueryResult" needs to be exported by the entry point index.d.ts
@@ -2039,8 +2041,6 @@ interface UseSuspenseQueryResult<TData = unknown, TVariables extends OperationVa
20392041
networkStatus: NetworkStatus;
20402042
// (undocumented)
20412043
refetch: RefetchFunction<TData, TVariables>;
2042-
// Warning: (ae-forgotten-export) The symbol "SubscribeToMoreFunction" needs to be exported by the entry point index.d.ts
2043-
//
20442044
// (undocumented)
20452045
subscribeToMore: SubscribeToMoreFunction<TData, TVariables>;
20462046
}
@@ -2134,8 +2134,9 @@ export function wrapQueryRef<TData, TVariables extends OperationVariables>(inter
21342134
// src/core/types.ts:203:5 - (ae-forgotten-export) The symbol "Resolver" needs to be exported by the entry point index.d.ts
21352135
// src/core/watchQueryOptions.ts:269:2 - (ae-forgotten-export) The symbol "IgnoreModifier" needs to be exported by the entry point index.d.ts
21362136
// src/core/watchQueryOptions.ts:269:2 - (ae-forgotten-export) The symbol "UpdateQueryFn" needs to be exported by the entry point index.d.ts
2137-
// src/react/hooks/useBackgroundQuery.ts:29:3 - (ae-forgotten-export) The symbol "FetchMoreFunction" needs to be exported by the entry point index.d.ts
2138-
// src/react/hooks/useBackgroundQuery.ts:30:3 - (ae-forgotten-export) The symbol "RefetchFunction" needs to be exported by the entry point index.d.ts
2137+
// src/react/hooks/useBackgroundQuery.ts:38:3 - (ae-forgotten-export) The symbol "SubscribeToMoreFunction" needs to be exported by the entry point index.d.ts
2138+
// src/react/hooks/useBackgroundQuery.ts:54:3 - (ae-forgotten-export) The symbol "FetchMoreFunction" needs to be exported by the entry point index.d.ts
2139+
// src/react/hooks/useBackgroundQuery.ts:78:4 - (ae-forgotten-export) The symbol "RefetchFunction" needs to be exported by the entry point index.d.ts
21392140

21402141
// (No @packageDocumentation comment for this package)
21412142

.api-reports/api-report.api.md

+7-5
Original file line numberDiff line numberDiff line change
@@ -2752,6 +2752,7 @@ UseBackgroundQueryResult<TData, TVariables>
27522752

27532753
// @public (undocumented)
27542754
export type UseBackgroundQueryResult<TData = unknown, TVariables extends OperationVariables = OperationVariables> = {
2755+
subscribeToMore: SubscribeToMoreFunction<TData, TVariables>;
27552756
fetchMore: FetchMoreFunction<TData, TVariables>;
27562757
refetch: RefetchFunction<TData, TVariables>;
27572758
};
@@ -2811,6 +2812,7 @@ queryRef: QueryRef<TData, TVariables> | null,
28112812
handlers: {
28122813
fetchMore: FetchMoreFunction<TData, TVariables>;
28132814
refetch: RefetchFunction<TData, TVariables>;
2815+
subscribeToMore: SubscribeToMoreFunction<TData, TVariables>;
28142816
reset: ResetFunction;
28152817
}
28162818
];
@@ -2828,6 +2830,7 @@ export function useQueryRefHandlers<TData = unknown, TVariables extends Operatio
28282830
export interface UseQueryRefHandlersResult<TData = unknown, TVariables extends OperationVariables = OperationVariables> {
28292831
fetchMore: FetchMoreFunction<TData, TVariables>;
28302832
refetch: RefetchFunction<TData, TVariables>;
2833+
subscribeToMore: SubscribeToMoreFunction<TData, TVariables>;
28312834
}
28322835

28332836
// @public
@@ -2901,8 +2904,6 @@ export interface UseSuspenseQueryResult<TData = unknown, TVariables extends Oper
29012904
networkStatus: NetworkStatus;
29022905
// (undocumented)
29032906
refetch: RefetchFunction<TData, TVariables>;
2904-
// Warning: (ae-forgotten-export) The symbol "SubscribeToMoreFunction" needs to be exported by the entry point index.d.ts
2905-
//
29062907
// (undocumented)
29072908
subscribeToMore: SubscribeToMoreFunction<TData, TVariables>;
29082909
}
@@ -2994,9 +2995,10 @@ interface WriteContext extends ReadMergeModifyContext {
29942995
// src/core/watchQueryOptions.ts:269:2 - (ae-forgotten-export) The symbol "IgnoreModifier" needs to be exported by the entry point index.d.ts
29952996
// src/core/watchQueryOptions.ts:269:2 - (ae-forgotten-export) The symbol "UpdateQueryFn" needs to be exported by the entry point index.d.ts
29962997
// src/link/http/selectHttpOptionsAndBody.ts:128:32 - (ae-forgotten-export) The symbol "HttpQueryOptions" needs to be exported by the entry point index.d.ts
2997-
// src/react/hooks/useBackgroundQuery.ts:29:3 - (ae-forgotten-export) The symbol "FetchMoreFunction" needs to be exported by the entry point index.d.ts
2998-
// src/react/hooks/useBackgroundQuery.ts:30:3 - (ae-forgotten-export) The symbol "RefetchFunction" needs to be exported by the entry point index.d.ts
2999-
// src/react/hooks/useLoadableQuery.ts:107:1 - (ae-forgotten-export) The symbol "ResetFunction" needs to be exported by the entry point index.d.ts
2998+
// src/react/hooks/useBackgroundQuery.ts:38:3 - (ae-forgotten-export) The symbol "SubscribeToMoreFunction" needs to be exported by the entry point index.d.ts
2999+
// src/react/hooks/useBackgroundQuery.ts:54:3 - (ae-forgotten-export) The symbol "FetchMoreFunction" needs to be exported by the entry point index.d.ts
3000+
// src/react/hooks/useBackgroundQuery.ts:78:4 - (ae-forgotten-export) The symbol "RefetchFunction" needs to be exported by the entry point index.d.ts
3001+
// src/react/hooks/useLoadableQuery.ts:120:9 - (ae-forgotten-export) The symbol "ResetFunction" needs to be exported by the entry point index.d.ts
30003002

30013003
// (No @packageDocumentation comment for this package)
30023004

.changeset/angry-ravens-mate.md

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@apollo/client": minor
3+
---
4+
5+
Add support for `subscribeToMore` function to `useQueryRefHandlers`.

.changeset/chilly-dots-shake.md

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@apollo/client": minor
3+
---
4+
5+
Add support for `subscribeToMore` function to `useLoadableQuery`.

.changeset/slimy-balloons-cheat.md

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@apollo/client": minor
3+
---
4+
5+
Add support for `subscribeToMore` function to `useBackgroundQuery`.

.size-limits.json

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
{
2-
"dist/apollo-client.min.cjs": 39825,
3-
"import { ApolloClient, InMemoryCache, HttpLink } from \"dist/index.js\" (production)": 32851
2+
"dist/apollo-client.min.cjs": 39873,
3+
"import { ApolloClient, InMemoryCache, HttpLink } from \"dist/index.js\" (production)": 32865
44
}

src/core/ObservableQuery.ts

+2
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,8 @@ export class ObservableQuery<
163163
this.waitForOwnResult = skipCacheDataFor(options.fetchPolicy);
164164
this.isTornDown = false;
165165

166+
this.subscribeToMore = this.subscribeToMore.bind(this);
167+
166168
const {
167169
watchQuery: { fetchPolicy: defaultFetchPolicy = "cache-first" } = {},
168170
} = queryManager.defaultOptions;

src/react/hooks/__tests__/useBackgroundQuery.test.tsx

+136-1
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import {
1616
TypedDocumentNode,
1717
ApolloLink,
1818
Observable,
19+
split,
1920
} from "../../../core";
2021
import {
2122
MockedResponse,
@@ -29,6 +30,7 @@ import {
2930
concatPagination,
3031
offsetLimitPagination,
3132
DeepPartial,
33+
getMainDefinition,
3234
} from "../../../utilities";
3335
import { useBackgroundQuery } from "../useBackgroundQuery";
3436
import { UseReadQueryResult, useReadQuery } from "../useReadQuery";
@@ -37,7 +39,10 @@ import { QueryRef, QueryReference } from "../../internal";
3739
import { InMemoryCache } from "../../../cache";
3840
import { SuspenseQueryHookFetchPolicy } from "../../types/types";
3941
import equal from "@wry/equality";
40-
import { RefetchWritePolicy } from "../../../core/watchQueryOptions";
42+
import {
43+
RefetchWritePolicy,
44+
SubscribeToMoreOptions,
45+
} from "../../../core/watchQueryOptions";
4146
import { skipToken } from "../constants";
4247
import {
4348
PaginatedCaseData,
@@ -54,6 +59,7 @@ import {
5459
spyOnConsole,
5560
useTrackRenders,
5661
} from "../../../testing/internal";
62+
import { SubscribeToMoreFunction } from "../useSuspenseQuery";
5763

5864
afterEach(() => {
5965
jest.useRealTimers();
@@ -6052,6 +6058,135 @@ describe("fetchMore", () => {
60526058

60536059
await expect(Profiler).not.toRerender();
60546060
});
6061+
6062+
it("can subscribe to subscriptions and react to cache updates via `subscribeToMore`", async () => {
6063+
interface SubscriptionData {
6064+
greetingUpdated: string;
6065+
}
6066+
6067+
type UpdateQueryFn = NonNullable<
6068+
SubscribeToMoreOptions<
6069+
SimpleCaseData,
6070+
Record<string, never>,
6071+
SubscriptionData
6072+
>["updateQuery"]
6073+
>;
6074+
6075+
const subscription: TypedDocumentNode<
6076+
SubscriptionData,
6077+
Record<string, never>
6078+
> = gql`
6079+
subscription {
6080+
greetingUpdated
6081+
}
6082+
`;
6083+
6084+
const { mocks, query } = setupSimpleCase();
6085+
6086+
const wsLink = new MockSubscriptionLink();
6087+
const mockLink = new MockLink(mocks);
6088+
6089+
const link = split(
6090+
({ query }) => {
6091+
const definition = getMainDefinition(query);
6092+
6093+
return (
6094+
definition.kind === "OperationDefinition" &&
6095+
definition.operation === "subscription"
6096+
);
6097+
},
6098+
wsLink,
6099+
mockLink
6100+
);
6101+
6102+
const client = new ApolloClient({ link, cache: new InMemoryCache() });
6103+
6104+
const Profiler = createProfiler({
6105+
initialSnapshot: {
6106+
subscribeToMore: null as SubscribeToMoreFunction<
6107+
SimpleCaseData,
6108+
Record<string, never>
6109+
> | null,
6110+
result: null as UseReadQueryResult<SimpleCaseData> | null,
6111+
},
6112+
});
6113+
6114+
const { SuspenseFallback, ReadQueryHook } =
6115+
createDefaultTrackedComponents(Profiler);
6116+
6117+
function App() {
6118+
useTrackRenders();
6119+
const [queryRef, { subscribeToMore }] = useBackgroundQuery(query);
6120+
6121+
Profiler.mergeSnapshot({ subscribeToMore });
6122+
6123+
return (
6124+
<Suspense fallback={<SuspenseFallback />}>
6125+
<ReadQueryHook queryRef={queryRef} />
6126+
</Suspense>
6127+
);
6128+
}
6129+
6130+
renderWithClient(<App />, { client, wrapper: Profiler });
6131+
6132+
{
6133+
const { renderedComponents } = await Profiler.takeRender();
6134+
6135+
expect(renderedComponents).toStrictEqual([App, SuspenseFallback]);
6136+
}
6137+
6138+
{
6139+
const { renderedComponents, snapshot } = await Profiler.takeRender();
6140+
6141+
expect(renderedComponents).toStrictEqual([ReadQueryHook]);
6142+
expect(snapshot.result).toEqual({
6143+
data: { greeting: "Hello" },
6144+
error: undefined,
6145+
networkStatus: NetworkStatus.ready,
6146+
});
6147+
}
6148+
6149+
const updateQuery = jest.fn<
6150+
ReturnType<UpdateQueryFn>,
6151+
Parameters<UpdateQueryFn>
6152+
>((_, { subscriptionData: { data } }) => {
6153+
return { greeting: data.greetingUpdated };
6154+
});
6155+
6156+
const { snapshot } = Profiler.getCurrentRender();
6157+
6158+
snapshot.subscribeToMore!({ document: subscription, updateQuery });
6159+
6160+
wsLink.simulateResult({
6161+
result: {
6162+
data: {
6163+
greetingUpdated: "Subscription hello",
6164+
},
6165+
},
6166+
});
6167+
6168+
{
6169+
const { snapshot, renderedComponents } = await Profiler.takeRender();
6170+
6171+
expect(renderedComponents).toStrictEqual([ReadQueryHook]);
6172+
expect(snapshot.result).toEqual({
6173+
data: { greeting: "Subscription hello" },
6174+
error: undefined,
6175+
networkStatus: NetworkStatus.ready,
6176+
});
6177+
}
6178+
6179+
expect(updateQuery).toHaveBeenCalledTimes(1);
6180+
expect(updateQuery).toHaveBeenCalledWith(
6181+
{ greeting: "Hello" },
6182+
{
6183+
subscriptionData: {
6184+
data: { greetingUpdated: "Subscription hello" },
6185+
},
6186+
variables: {},
6187+
}
6188+
);
6189+
});
60556190
});
60566191

60576192
describe.skip("type tests", () => {

0 commit comments

Comments
 (0)