From 183ff32bee4bc23eb23657f79f414c2400ecb06a Mon Sep 17 00:00:00 2001 From: Ivan Goncharov Date: Mon, 21 Jan 2019 16:49:54 +0200 Subject: [PATCH] Remove excessive cache inside buildClientSchema (#1677) --- src/utilities/buildClientSchema.js | 41 +++++++++++------------------- 1 file changed, 15 insertions(+), 26 deletions(-) diff --git a/src/utilities/buildClientSchema.js b/src/utilities/buildClientSchema.js index 9d541e3e07..09f0d6ffbf 100644 --- a/src/utilities/buildClientSchema.js +++ b/src/utilities/buildClientSchema.js @@ -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'; @@ -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. @@ -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 { @@ -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) @@ -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,