mirror of
https://github.com/wassname/talk.git
synced 2026-07-01 01:44:43 +08:00
Cache resolved fragments (globally)
This commit is contained in:
@@ -19,7 +19,7 @@ import update from 'immutability-helper';
|
||||
import {notify} from 'coral-framework/actions/notification';
|
||||
|
||||
const commentConnectionFragment = gql`
|
||||
fragment CoralAdmin_Moderation_CommentConnection on CommentConnection {
|
||||
fragment CoralAdmin_UserDetail_CommentConnection on CommentConnection {
|
||||
nodes {
|
||||
...${getDefinitionName(UserDetailComment.fragments.comment)}
|
||||
}
|
||||
@@ -155,7 +155,7 @@ export const withUserDetailQuery = withQuery(gql`
|
||||
author_id: $author_id,
|
||||
statuses: $statuses
|
||||
}) {
|
||||
...CoralAdmin_Moderation_CommentConnection
|
||||
...CoralAdmin_UserDetail_CommentConnection
|
||||
}
|
||||
...${getDefinitionName(UserDetailComment.fragments.root)}
|
||||
${getSlotFragmentSpreads(slots, 'root')}
|
||||
|
||||
@@ -63,12 +63,32 @@ export function mergeSelectionSets(a, b) {
|
||||
};
|
||||
}
|
||||
|
||||
function getFragment(name, execContext) {
|
||||
const {
|
||||
rawFragmentMap,
|
||||
fragmentMap,
|
||||
} = execContext;
|
||||
|
||||
if (!(name in fragmentMap)) {
|
||||
const fragment = rawFragmentMap[name];
|
||||
|
||||
if (!fragment) {
|
||||
throw new Error(`fragment ${fragment.name.value} does not exist`);
|
||||
}
|
||||
|
||||
const typeCondition = fragment.typeCondition.name.value;
|
||||
const transformed = transformDefinition(fragment, execContext, `type.${typeCondition}`, typeCondition);
|
||||
fragmentMap[name] = transformed;
|
||||
}
|
||||
|
||||
return fragmentMap[name];
|
||||
}
|
||||
|
||||
/**
|
||||
* Return selections with resolved named fragments and directives.
|
||||
*/
|
||||
function getTransformedSelections(definition, path, gqlType, execContext) {
|
||||
const {
|
||||
fragmentMap,
|
||||
variables,
|
||||
} = execContext;
|
||||
|
||||
@@ -92,7 +112,7 @@ function getTransformedSelections(definition, path, gqlType, execContext) {
|
||||
return o;
|
||||
}
|
||||
|
||||
const fragment = fragmentMap[sel.name.value];
|
||||
const fragment = getFragment(sel.name.value, execContext);
|
||||
|
||||
if (!fragment) {
|
||||
throw new Error(`fragment ${fragment.name.value} does not exist`);
|
||||
@@ -105,20 +125,19 @@ function getTransformedSelections(definition, path, gqlType, execContext) {
|
||||
...fragment,
|
||||
kind: 'InlineFragment',
|
||||
};
|
||||
const transformed = transformDefinition(node, execContext, path, typeCondition);
|
||||
const name = getDefinitionName(node);
|
||||
|
||||
// Merge existing value.
|
||||
if (name in o) {
|
||||
o[name] = mergeDefinitions(o[name], transformed);
|
||||
o[name] = mergeDefinitions(o[name], node);
|
||||
return o;
|
||||
}
|
||||
|
||||
o[name] = transformed;
|
||||
o[name] = node;
|
||||
return o;
|
||||
}
|
||||
|
||||
const fragmentSelections = getTransformedSelections(fragment, path, typeCondition, execContext);
|
||||
const fragmentSelections = fragment.selectionSet.selections;
|
||||
fragmentSelections.forEach((s) => {
|
||||
|
||||
if (variables && !shouldInclude(s, variables)) {
|
||||
@@ -184,7 +203,8 @@ export default function reduceDocument(document, options = {}) {
|
||||
: `type.${mainDefinition.typeCondition.name.value}`;
|
||||
|
||||
const execContext = {
|
||||
fragmentMap: createFragmentMap(fragments),
|
||||
rawFragmentMap: createFragmentMap(fragments),
|
||||
fragmentMap: options.fragmentMap || {},
|
||||
keepFragments: [],
|
||||
variables: options.variables,
|
||||
typeGetter: options.typeGetter || (() => null),
|
||||
|
||||
@@ -9,13 +9,17 @@ import {addTypenameToDocument} from 'apollo-client/queries/queryTransform';
|
||||
export function createGraphQLService(registry, introspectionData) {
|
||||
const typeGetter = createTypeGetter(introspectionData);
|
||||
|
||||
// Use shared fragment map.
|
||||
// Attention: Fragment names must be unique otherwise weird things will happen.
|
||||
const fragmentMap = {};
|
||||
|
||||
return {
|
||||
registry,
|
||||
resolveDocument(documentOrCallback, props, context) {
|
||||
let document = typeof documentOrCallback === 'function'
|
||||
? documentOrCallback(props, context)
|
||||
: documentOrCallback;
|
||||
document = reduceDocument(registry.resolveFragments(document), {typeGetter});
|
||||
document = reduceDocument(registry.resolveFragments(document), {typeGetter, fragmentMap});
|
||||
|
||||
// We also add typenames to the document which apollo would usually do,
|
||||
// but we also use the network interface in subscriptions directly
|
||||
|
||||
Reference in New Issue
Block a user