Skip to content
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

Remove excessive cache inside buildClientSchema #1677

Merged
merged 1 commit into from
Jan 21, 2019
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 15 additions & 26 deletions src/utilities/buildClientSchema.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@
* @flow strict
*/

import objectValues from '../polyfills/objectValues';
import inspect from '../jsutils/inspect';
import invariant from '../jsutils/invariant';
import keyMap from '../jsutils/keyMap';
import keyValMap from '../jsutils/keyValMap';
import { valueFromAST } from './valueFromAST';
import { parseValue } from '../language/parser';
Expand Down Expand Up @@ -84,19 +84,18 @@ export function buildClientSchema(
// Get the schema from the introspection result.
const schemaIntrospection = introspection.__schema;

// Converts the list of types into a keyMap based on the type names.
const typeIntrospectionMap = keyMap(
// Iterate through all types, getting the type definition for each.
const typeMap = keyValMap(
schemaIntrospection.types,
type => type.name,
typeIntrospection => typeIntrospection.name,
typeIntrospection => buildType(typeIntrospection),
);

// A cache to use to store the actual GraphQLType definition objects by name.
// Initialize to the GraphQL built in scalars. All functions below are inline
// so that this type def cache is within the scope of the closure.
const typeDefCache = keyMap(
specifiedScalarTypes.concat(introspectionTypes),
type => type.name,
);
for (const stdType of [...specifiedScalarTypes, ...introspectionTypes]) {
if (typeMap[stdType.name]) {
typeMap[stdType.name] = stdType;
}
}

// Given a type reference in introspection, return the GraphQLType instance.
// preferring cached instances before building new instances.
Expand All @@ -123,20 +122,16 @@ export function buildClientSchema(
}

function getNamedType(typeName: string): GraphQLNamedType {
if (typeDefCache[typeName]) {
return typeDefCache[typeName];
}
const typeIntrospection = typeIntrospectionMap[typeName];
if (!typeIntrospection) {
const type = typeMap[typeName];
if (!type) {
throw new Error(
`Invalid or incomplete schema, unknown type: ${typeName}. Ensure ` +
'that a full introspection query is used in order to build a ' +
'client schema.',
);
}
const typeDef = buildType(typeIntrospection);
typeDefCache[typeName] = typeDef;
return typeDef;

return type;
}

function getInputType(typeRef: IntrospectionInputTypeRef): GraphQLInputType {
Expand Down Expand Up @@ -362,12 +357,6 @@ export function buildClientSchema(
});
}

// Iterate through all types, getting the type definition for each, ensuring
// that any type not directly referenced by a field will get created.
const types = schemaIntrospection.types.map(typeIntrospection =>
getNamedType(typeIntrospection.name),
);

// Get the root Query, Mutation, and Subscription types.
const queryType = schemaIntrospection.queryType
? getObjectType(schemaIntrospection.queryType)
Expand All @@ -392,7 +381,7 @@ export function buildClientSchema(
query: queryType,
mutation: mutationType,
subscription: subscriptionType,
types,
types: objectValues(typeMap),
directives,
assumeValid: options && options.assumeValid,
allowedLegacyNames: options && options.allowedLegacyNames,
Expand Down