Skip to content

Commit

Permalink
Clean up legacy one-time queries after refetching in refetchQueries.
Browse files Browse the repository at this point in the history
Although passing one-time { query, variables } QueryOptions in the
options.include array is discouraged by the type system, it's still
allowed for the refetchQueries option for mutations, so we should make
sure to stop those temporary queries after they've been fetched.

I didn't want to complicate the client.getObservableQueries API to
return additional metadata about which queries are legacy/temporary, so
I'm using query ID strings (the keys of the getObservableQueries Map) to
convey that information.
  • Loading branch information
benjamn committed Jun 4, 2021
1 parent 1c6314c commit 4a8e265
Show file tree
Hide file tree
Showing 2 changed files with 15 additions and 3 deletions.
9 changes: 7 additions & 2 deletions src/core/QueryManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -782,8 +782,9 @@ export class QueryManager<TStore> {
if (legacyQueryOptions.size) {
legacyQueryOptions.forEach((options: QueryOptions) => {
// We will be issuing a fresh network request for this query, so we
// pre-allocate a new query ID here.
const queryId = this.generateQueryId();
// pre-allocate a new query ID here, using a special prefix to enable
// cleaning up these temporary queries later, after fetching.
const queryId = makeUniqueId("legacyOneTimeQuery");
const queryInfo = this.getQuery(queryId).init({
document: options.query,
variables: options.variables,
Expand Down Expand Up @@ -1310,6 +1311,10 @@ export class QueryManager<TStore> {
if (result !== false) {
results.set(oq, result!);
}

if (queryId.indexOf("legacyOneTimeQuery") >= 0) {
this.stopQueryNoBroadcast(queryId);
}
});
}

Expand Down
9 changes: 8 additions & 1 deletion src/core/__tests__/QueryManager/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4916,7 +4916,14 @@ describe('QueryManager', () => {
} else if (count === 2) {
expect(result.data).toEqual(secondReqData);
expect(observable.getCurrentResult().data).toEqual(secondReqData);
setTimeout(resolve, 10);

return new Promise(res => setTimeout(res, 10)).then(() => {
// Make sure the QueryManager cleans up legacy one-time queries like
// the one we requested above using refetchQueries.
queryManager["queries"].forEach((queryInfo, queryId) => {
expect(queryId).not.toContain("legacyOneTimeQuery");
});
}).then(resolve, reject);
} else {
reject("too many results");
}
Expand Down

0 comments on commit 4a8e265

Please sign in to comment.