Skip to content

Commit

Permalink
Avoid destructively modifying result.data in QueryInfo#markResult.
Browse files Browse the repository at this point in the history
Should help with #9293.
  • Loading branch information
benjamn committed Sep 8, 2023
1 parent 1c74ed4 commit 01b0e72
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 13 deletions.
31 changes: 20 additions & 11 deletions src/core/QueryInfo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -361,7 +361,7 @@ export class QueryInfo {
"variables" | "fetchPolicy" | "errorPolicy"
>,
cacheWriteBehavior: CacheWriteBehavior
) {
): typeof result {
const merger = new DeepMerger();
const graphQLErrors = isNonEmptyArray(result.errors)
? result.errors.slice(0)
Expand Down Expand Up @@ -408,7 +408,10 @@ export class QueryInfo {
});

this.lastWrite = {
result,
// Make a shallow defensive copy of the result object, in case we
// later later modify result.data in place, since we don't want
// that mutation affecting the saved lastWrite.result.data.
result: { ...result },
variables: options.variables,
dmCount: destructiveMethodCounts.get(this.cache),
};
Expand Down Expand Up @@ -448,7 +451,10 @@ export class QueryInfo {
if (this.lastDiff && this.lastDiff.diff.complete) {
// Reuse data from the last good (complete) diff that we
// received, when possible.
result.data = this.lastDiff.diff.result;
result = {
...result,
data: this.lastDiff.diff.result,
};
return;
}
// If the previous this.diff was incomplete, fall through to
Expand All @@ -467,20 +473,23 @@ export class QueryInfo {
this.updateWatch(options.variables);
}

// If we're allowed to write to the cache, and we can read a
// complete result from the cache, update result.data to be the
// result from the cache, rather than the raw network result.
// Set without setDiff to avoid triggering a notify call, since
// we have other ways of notifying for this result.
// If we're allowed to write to the cache, update result.data to be
// the result as re-read from the cache, rather than the raw network
// result. Set without setDiff to avoid triggering a notify call,
// since we have other ways of notifying for this result.
this.updateLastDiff(diff, diffOptions);
if (diff.complete) {
result.data = diff.result;
}
result = {
...result,
// TODO Improve types so we don't need this cast.
data: diff.result as any,
};
});
} else {
this.lastWrite = void 0;
}
}

return result;
}

public markReady() {
Expand Down
4 changes: 2 additions & 2 deletions src/core/QueryManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1176,11 +1176,11 @@ export class QueryManager<TStore> {
// Use linkDocument rather than queryInfo.document so the
// operation/fragments used to write the result are the same as the
// ones used to obtain it from the link.
queryInfo.markResult(
result = queryInfo.markResult(
result,
linkDocument,
options,
cacheWriteBehavior
cacheWriteBehavior,
);
queryInfo.markReady();
}
Expand Down

0 comments on commit 01b0e72

Please sign in to comment.