Optimistic Response/Update Cache #8568
Replies: 4 comments 1 reply
-
This is an interesting problem to solve. 🤔 Relay has a specific directive that you apply on mutation operations for getting the unmasked behavior on the generated type. https://relay.dev/docs/guided-tour/updating-data/graphql-mutations/#optimistic-response We could disable this completely for mutation operations, however, I also see myself heavily using fragment masking on mutation-selection sets for rendering mutation result UI. Thus I am not sure whether we want to disable it for all mutations or only partially via some directive magic. 🤔 Another idea that I have in my mind is to have a manual unmasking function that recursively maps through a DocumenNode. I quickly prototyped something: type ExpandTypeWithFragments<TType> = TType extends Array<infer TItemType>
? Array<ExpandTypeWithFragments<TItemType>>
: TType extends { ' $fragmentRefs': infer TFragmentRefs }
? Exclude<TType, { ' $fragmentRefs': any }> | ExpandTypeWithFragments<TFragmentRefs[keyof TFragmentRefs]>
: { [key in keyof TType]: ExpandTypeWithFragments<TType[key]> };
export type RawType<TDocumentNode extends DocumentNode<any, any>> = TDocumentNode extends DocumentNode<
infer TType,
infer TVariables
>
? DocumentNode<ExpandTypeWithFragments<TType>, TVariables>
: never;
export function raw<TDocumentNode extends DocumentNode<any, any>>(documentNode: TDocumentNode): RawType<TDocumentNode> {
return documentNode as any;
} This, implementation is however pretty primitive and will cause issues as soon as you spread more than one fragment on the same type: import { DocumentType, graphql, raw } from './gql';
const FilmFragment = graphql(/* GraphQL */ `
fragment FilmItem on Film {
id
title
releaseDate
producers
}
`);
const FragTest = graphql(/* GraphQL */ `
fragment FragTest on Film {
director
}
`);
const allFilmsWithVariablesQueryDocument = graphql(/* GraphQL */ `
query allFilmsWithVariablesQuery($first: Int!) {
allFilms(first: $first) {
edges {
node {
...FilmItem
...FragTest
}
}
}
}
`);
const Foo = raw(allFilmsWithVariablesQueryDocument); The issue is that there is no straight-forward way of merging objects (fragments) with the same |
Beta Was this translation helpful? Give feedback.
-
@n1ru4l Did this ever get solved? |
Beta Was this translation helpful? Give feedback.
-
I’m running into exactly this issue, with two fragments (with the same Many thanks! |
Beta Was this translation helpful? Give feedback.
-
How am I supposed to update the cache or return an optimistic response in the new graphql codegen if it thinks the type is 'fragmentRef' etc and not the actual type that GraphQL is returning? I'm currently refactoring some code and I don't see anything in the docs about this. This is for a mutation that uses a fragment btw. Is the easiest solution for now just not using a fragment in the return? Because that seems hacky to me.
Beta Was this translation helpful? Give feedback.
All reactions