-
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
DO NOT MERGE: (WIP) Adds support for Link preprocessing #10290
Conversation
For users of the @apollo/client that use client side schemas, this PR allows the users to provide an ApolloLink for preprocessing that allows configurable modification to the query/mutation DocumentNode before the client performs its own caching and execution. An example of modifying the DocumentNode to swap a @Persistent directive for a @client directive when the application is offline, or removing it entirely if it online. ```js const client = new ApolloClient({ cache, uri: 'http://someserver.com/graphql', preprocessorLink: new ApolloLink((operation) => { let newOpSDL = parse(print(operation.query)) newOpSDL = swapDirective( newOpSDL, 'persistent', () => online() ? undefined : 'client' ) return { data: newOpSDL } }) }) client.query({ query: gql`query { your { heart { away }}}`}) client.mutate({ mutation: gql`mutation { or { change { things }}}`}) function swapDirective(document, searchFor, replaceWith) { let alteredDocument = document const isFn = (o) => /Function/.test(Object.prototype.toString.call(o)) const target = isFn(searchFor) ? searchFor() : String(searchFor) const newValue = isFn(replaceWith) ? replaceWith() : replaceWith && String(replaceWith) | undefined const getter = (n) => n?.name?.value || null const setter = (n, v) => { if (n?.name) n.name.value = v; return n } const hasTarget = (n) => new RegExp(target, 'i').test(getter(n)) alteredDocument = visit(document, { Field: { enter(node, key, parent, path, ancestors) { if (node.directives?.length && node.directives.some(hasTarget)) { if (!!!newValue) { for (let i = 0; i < node.directives.length; i++) { if (new RegExp(target, 'i').test(getter(node.directives[i]))) { node.directives.splice(i, 1) i-- } } } else { // Thought process here is to swap @Persistent for @client // when we are offline. node.directives = node.directives .filter(directive => new RegExp(target, 'i').test(getter(directive))) .map(directive => { return setter(directive, newValue) }) } return node } }, } }) return alteredDocument || document } ```
@nyteshade: Thank you for submitting a pull request! Before we can merge it, you'll need to sign the Apollo Contributor License Agreement here: https://contribute.apollographql.com/ |
if (modifiedMutation) { | ||
mutation = modifiedMutation; | ||
} | ||
|
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.
What I don't understand is why this await
within QueryManager.mutate
is causing so many tests to fail. Logic says it shouldn't otherwise cause such issues.
Per this comment, we plan to do this work as part of #10303. Thanks for the discussion and helping us think through a solution! |
For users of the @apollo/client that use client side schemas, this PR allows the users to provide an ApolloLink for preprocessing that allows configurable modification to the query/mutation DocumentNode before the client performs its own caching and execution.
An example of modifying the DocumentNode to swap a @Persistent directive for a @client directive when the application is offline, or removing it entirely if it online.
RFC: #10228
Checklist: