-
Notifications
You must be signed in to change notification settings - Fork 2.7k
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
Implement a @nonreactive
directive for selectively skipping reactive comparisons of query result subtrees
#10722
Changes from 11 commits
3cbc475
962c5c4
77025f4
e913767
3030094
1c4e094
18e2ea2
6f68be9
c7e60f8
dfd42b9
c43a547
8ec244f
52d8791
502b424
e9c7334
b814935
bac8325
996c6a6
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
--- | ||
'@apollo/client': minor | ||
--- | ||
|
||
Implement a `@nonreactive` directive for selectively skipping reactive comparisons of query result subtrees |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -7,8 +7,10 @@ import { equal } from '@wry/equality'; | |
|
||
import { ApolloLink, execute, FetchResult } from '../link/core'; | ||
import { | ||
hasDirectives, | ||
isExecutionPatchIncrementalResult, | ||
isExecutionPatchResult, | ||
removeDirectivesFromDocument, | ||
} from '../utilities'; | ||
import { Cache, ApolloCache, canonicalStringify } from '../cache'; | ||
|
||
|
@@ -19,7 +21,6 @@ import { | |
hasClientExports, | ||
graphQLResultHasError, | ||
getGraphQLErrorsFromResult, | ||
removeConnectionDirectiveFromDocument, | ||
canUseWeakMap, | ||
ObservableSubscription, | ||
Observable, | ||
|
@@ -77,6 +78,7 @@ interface TransformCacheEntry { | |
document: DocumentNode; | ||
hasClientExports: boolean; | ||
hasForcedResolvers: boolean; | ||
hasNonreactiveDirective: boolean; | ||
clientQuery: DocumentNode | null; | ||
serverQuery: DocumentNode | null; | ||
defaultVars: OperationVariables; | ||
|
@@ -616,18 +618,23 @@ export class QueryManager<TStore> { | |
|
||
if (!transformCache.has(document)) { | ||
const transformed = this.cache.transformDocument(document); | ||
const noConnection = removeConnectionDirectiveFromDocument(transformed); | ||
const serverQuery = removeDirectivesFromDocument([ | ||
removeClientFields ? { name: 'client', remove: true } : {}, | ||
{ name: 'connection' }, | ||
{ name: 'nonreactive' }, | ||
], transformed); | ||
Comment on lines
+621
to
+625
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Like Thanks to 3030094, all three of these removals can be performed in the same traversal of the AST! |
||
const clientQuery = this.localState.clientQuery(transformed); | ||
const serverQuery = | ||
noConnection && | ||
this.localState.serverQuery(noConnection, { removeClientFields }); | ||
|
||
const cacheEntry: TransformCacheEntry = { | ||
document: transformed, | ||
// TODO These two calls (hasClientExports and shouldForceResolvers) | ||
// could probably be merged into a single traversal. | ||
// TODO These three calls (hasClientExports, shouldForceResolvers, and | ||
// usesNonreactiveDirective) are performing independent full traversals | ||
// of the transformed document. We should consider merging these | ||
// traversals into a single pass in the future, though the work is | ||
// cached after the first time. | ||
hasClientExports: hasClientExports(transformed), | ||
hasForcedResolvers: this.localState.shouldForceResolvers(transformed), | ||
hasNonreactiveDirective: hasDirectives(['nonreactive'], transformed), | ||
clientQuery, | ||
serverQuery, | ||
defaultVars: getDefaultValues( | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is where we handle the backwards compatibility logic of using
compareResultsUsingQuery
only when the query contains one or more@nonreactive
directives.Despite appearances,
this.queryManager.transform(query).hasNonreactiveDirective
is cached after the first timequery
is encountered, so we do not have to keep scanning the query for@nonreactive
directives every time this code runs.