Skip to content
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

Dispose of the queryRef when changing to previously used variables to allow the InMemoryCache to determine cached behavior #11045

Merged
merged 55 commits into from
Jul 10, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
55 commits
Select commit Hold shift + click to select a range
c7ed0d1
Handle rerendering deferred chunks and resubscribing after error
jerelmiller Jun 30, 2023
f5a715b
Revert change to how promise is created
jerelmiller Jul 3, 2023
d16dc39
Move special handling of data to top of function
jerelmiller Jul 3, 2023
d323e6a
Refactor to use `status` value in `QueryReference`
jerelmiller Jul 3, 2023
11131d8
Update wording for test
jerelmiller Jul 3, 2023
43aeceb
Remove unneeded set of status during refetch
jerelmiller Jul 3, 2023
91f9734
Ensure test uses `errorPolicy: 'all'` for errors in deferred chunks
jerelmiller Jul 3, 2023
1c2fab5
Remove need for resubscribing since errors are thrown
jerelmiller Jul 3, 2023
58a883d
Remove need for setting `result` in `handleError`
jerelmiller Jul 3, 2023
78d3d0a
Add ability to handle incremental rerenders when refetching a `@defer…
jerelmiller Jul 3, 2023
8e1dfb2
Add test to ensure refetch incrementally rerenders deferred query
jerelmiller Jul 3, 2023
5bc220b
Add test to show behavior of `fetchMore` with `@defer` query
jerelmiller Jul 3, 2023
02c9a41
Fix handling of skip option with `@defer` queries
jerelmiller Jul 3, 2023
08caab5
Remove unused import
jerelmiller Jul 3, 2023
52933d9
Add changeset
jerelmiller Jul 3, 2023
3d4e551
Refactor to make `reobserve` like `refetch` and `fetchMore`
jerelmiller Jul 3, 2023
7410262
Refactor refetch/fetchMore/reobserve into common function
jerelmiller Jul 3, 2023
735b702
Filter out observable results with no data
jerelmiller Jul 3, 2023
ba9f142
Move handling fo setting last successful result in .map
jerelmiller Jul 3, 2023
735d57e
Move `.catch` to where the promise is created
jerelmiller Jul 3, 2023
b20734e
Move creation of promise to else
jerelmiller Jul 3, 2023
5864040
Use shortcut for options
jerelmiller Jul 3, 2023
1c5f0a3
Merge remote-tracking branch 'origin/release-3.8' into errors-in-defe…
jerelmiller Jul 6, 2023
f09229b
Remove duplicate equal import
jerelmiller Jul 6, 2023
0f64efa
Update applyOptions to use handleFetch helper
jerelmiller Jul 6, 2023
b748191
Only update result immediately when changing canonizeResults option
jerelmiller Jul 6, 2023
cde08f8
Disable render count check for now
jerelmiller Jul 6, 2023
6eed13f
Use queryRef.promise when setting promise in refetch/fetchMore
jerelmiller Jul 6, 2023
3eeb893
Bump size-limit
jerelmiller Jul 6, 2023
f088d83
Introduce a `tap` helper and refactor QueryReference to use it
jerelmiller Jul 6, 2023
1cabe98
Rename handleFetch to initiateFetch
jerelmiller Jul 6, 2023
a12477b
Use `tap` in `useSuspenseQuery`/`useBackgroundQuery` to return promis…
jerelmiller Jul 6, 2023
aa966d6
Update size-limit
jerelmiller Jul 6, 2023
9a7037c
Run prettier on `tap` utility
jerelmiller Jul 6, 2023
76ba17d
Update snapshot tests
jerelmiller Jul 6, 2023
8e3ce51
Merge remote-tracking branch 'origin/release-3.8' into errors-in-defe…
jerelmiller Jul 6, 2023
fefdbf0
Update size-limit
jerelmiller Jul 6, 2023
0715f6a
Dispose of query references when changing variables to allow InMemory…
jerelmiller Jul 6, 2023
d147fcf
Fix handling of setting last result
jerelmiller Jul 6, 2023
6191081
Remove unneeded checks from test
jerelmiller Jul 6, 2023
e49da7a
Update useBackgroundQuery to retain/dispose of the query ref
jerelmiller Jul 6, 2023
3a7e794
Remove unused useTrackedQueryRefs
jerelmiller Jul 6, 2023
e9857f4
Update changeset
jerelmiller Jul 6, 2023
874eef1
Remove unneeded useStrictModeSafeCleanupEffect hook
jerelmiller Jul 6, 2023
1189a0d
Update size-limit
jerelmiller Jul 6, 2023
61cd153
Revert use of `tap` in `QueryReference` and suspense hooks
jerelmiller Jul 7, 2023
d26d21b
Merge remote-tracking branch 'origin/release-3.8' into errors-in-defe…
jerelmiller Jul 7, 2023
b047048
Update size-limit
jerelmiller Jul 7, 2023
34a2dd7
Add a failing test of the deferred `fetchMore` query.
jerelmiller Jul 7, 2023
c2c0c35
Update snapshot test
jerelmiller Jul 7, 2023
25ae703
Merge remote-tracking branch 'origin/errors-in-deferred-chunks' into …
jerelmiller Jul 7, 2023
94a78b7
Fix updated reference to `useEffect`
jerelmiller Jul 7, 2023
70aa361
Merge remote-tracking branch 'origin/release-3.8' into switch-variabl…
jerelmiller Jul 8, 2023
820d241
Update size-limit
jerelmiller Jul 8, 2023
ed724fb
Refactor to return a dispose function from `retain` instead of `dispo…
jerelmiller Jul 10, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/nice-eyes-return.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@apollo/client': minor
---

When changing variables back to a previously used set of variables, do not automatically cache the result as part of the query reference. Instead, dispose of the query reference so that the `InMemoryCache` can determine the cached behavior. This means that fetch policies that would guarantee a network request are now honored when switching back to previously used variables.
2 changes: 1 addition & 1 deletion .size-limit.cjs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
const checks = [
{
path: "dist/apollo-client.min.cjs",
limit: "37880"
limit: "37890"
},
{
path: "dist/main.cjs",
Expand Down
51 changes: 36 additions & 15 deletions src/react/cache/QueryReference.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,8 @@ export class InternalQueryReference<TData = unknown> {
private resolve: ((result: ApolloQueryResult<TData>) => void) | undefined;
private reject: ((error: unknown) => void) | undefined;

private references = 0;

constructor(
observable: ObservableQuery<TData>,
options: InternalQueryReferenceOptions
Expand Down Expand Up @@ -94,15 +96,6 @@ export class InternalQueryReference<TData = unknown> {
}

this.subscription = observable
.map((result) => {
// Maintain the last successful `data` value if the next result does not
// have one.
if (result.data === void 0) {
result.data = this.result.data;
}

return result;
})
.filter(({ data }) => !equal(data, {}))
.subscribe({
next: this.handleNext,
Expand All @@ -123,6 +116,28 @@ export class InternalQueryReference<TData = unknown> {
return this.observable.options;
}

retain() {
this.references++;
clearTimeout(this.autoDisposeTimeoutId);
let disposed = false;

return () => {
if (disposed) {
return;
}

disposed = true;
this.references--;

// Wait before fully disposing in case the app is running in strict mode.
setTimeout(() => {
if (!this.references) {
this.dispose();
}
});
};
}

didChangeOptions(watchQueryOptions: WatchQueryOptions) {
return OBSERVED_CHANGED_OPTIONS.some(
(option) =>
Expand Down Expand Up @@ -157,11 +172,6 @@ export class InternalQueryReference<TData = unknown> {
}

listen(listener: Listener<TData>) {
// As soon as the component listens for updates, we know it has finished
// suspending and is ready to receive updates, so we can remove the auto
// dispose timer.
clearTimeout(this.autoDisposeTimeoutId);

this.listeners.add(listener);

return () => {
Expand All @@ -185,7 +195,7 @@ export class InternalQueryReference<TData = unknown> {
return promise;
}

dispose() {
private dispose() {
this.subscription.unsubscribe();
this.onDispose();
}
Expand All @@ -197,6 +207,11 @@ export class InternalQueryReference<TData = unknown> {
private handleNext(result: ApolloQueryResult<TData>) {
switch (this.status) {
case 'loading': {
// Maintain the last successful `data` value if the next result does not
// have one.
if (result.data === void 0) {
result.data = this.result.data;
}
this.status = 'idle';
this.result = result;
this.resolve?.(result);
Expand All @@ -207,6 +222,12 @@ export class InternalQueryReference<TData = unknown> {
return;
}

// Maintain the last successful `data` value if the next result does not
// have one.
if (result.data === void 0) {
result.data = this.result.data;
}

this.result = result;
this.promise = createFulfilledPromise(result);
this.deliver(this.promise);
Expand Down
Loading