From c8f85c1c0d62f20f2090f32682bf3b13836a59a5 Mon Sep 17 00:00:00 2001 From: Ryan Quinn Date: Fri, 7 Jul 2023 12:18:04 -0400 Subject: [PATCH 1/2] Remove uses of reduce/spread which causes significant latency to large middlewares (maticzav/graphql-middleware#567) --- src/applicator.ts | 53 +++++++++++++++++++++++------------------------ 1 file changed, 26 insertions(+), 27 deletions(-) diff --git a/src/applicator.ts b/src/applicator.ts index a27d198..71251bd 100644 --- a/src/applicator.ts +++ b/src/applicator.ts @@ -42,11 +42,10 @@ function wrapResolverInMiddleware( function parseField(field: GraphQLField) { const argsMap = field.args.reduce( - (acc, cur) => ({ - ...acc, - [cur.name]: cur, - }), - {} as Record, + (acc, cur) => { + acc[cur.name] = cur; + return acc; + }, {} as Record, ) return { ...field, @@ -135,28 +134,28 @@ function applyMiddlewareToType( if (isMiddlewareFunction(middleware)) { const resolvers = Object.keys(fieldMap).reduce( - (resolvers, fieldName) => ({ - ...resolvers, - [fieldName]: applyMiddlewareToField( + (resolvers, fieldName) => { + resolvers[fieldName] = applyMiddlewareToField( fieldMap[fieldName], options, middleware as IMiddlewareFunction, - ), - }), + ); + return resolvers; + }, {}, ) return resolvers } else { const resolvers = Object.keys(middleware).reduce( - (resolvers, field) => ({ - ...resolvers, - [field]: applyMiddlewareToField( - fieldMap[field], + (resolvers, fieldName) => { + resolvers[fieldName] = applyMiddlewareToField( + fieldMap[fieldName], options, - middleware[field], - ), - }), + middleware[fieldName], + ); + return resolvers; + }, {}, ) @@ -178,14 +177,14 @@ function applyMiddlewareToSchema( !isIntrospectionType(typeMap[type]), ) .reduce( - (resolvers, type) => ({ - ...resolvers, - [type]: applyMiddlewareToType( + (resolvers, type) => { + resolvers[type] = applyMiddlewareToType( typeMap[type] as GraphQLObjectType, options, middleware, - ), - }), + ); + return resolvers; + }, {}, ) @@ -213,14 +212,14 @@ export function generateResolverFromSchemaAndMiddleware< const typeMap = schema.getTypeMap() const resolvers = Object.keys(middleware).reduce( - (resolvers, type) => ({ - ...resolvers, - [type]: applyMiddlewareToType( + (resolvers, type) => { + resolvers[type] = applyMiddlewareToType( typeMap[type] as GraphQLObjectType, options, middleware[type], - ), - }), + ); + return resolvers; + }, {}, ) From bdcb52a77d80ea8a2f6622a135fa1276d47cb65b Mon Sep 17 00:00:00 2001 From: Emily M Klassen Date: Thu, 11 Jul 2024 19:27:57 -0700 Subject: [PATCH 2/2] refactor: switch from object.keys/reduce to object.entries/map/object.fromEntries --- src/applicator.ts | 88 +++++++++++++++++++++-------------------------- 1 file changed, 39 insertions(+), 49 deletions(-) diff --git a/src/applicator.ts b/src/applicator.ts index 71251bd..e8332d1 100644 --- a/src/applicator.ts +++ b/src/applicator.ts @@ -41,11 +41,10 @@ function wrapResolverInMiddleware( } function parseField(field: GraphQLField) { - const argsMap = field.args.reduce( - (acc, cur) => { - acc[cur.name] = cur; - return acc; - }, {} as Record, + const argsMap = Object.fromEntries( + field.args.map( + (cur) => [cur.name, cur] + ) ) return { ...field, @@ -129,34 +128,28 @@ function applyMiddlewareToType( middleware: | IMiddlewareFunction | IMiddlewareFieldMap, -): IResolvers { +): Record { const fieldMap = type.getFields() if (isMiddlewareFunction(middleware)) { - const resolvers = Object.keys(fieldMap).reduce( - (resolvers, fieldName) => { - resolvers[fieldName] = applyMiddlewareToField( - fieldMap[fieldName], + const resolvers = Object.fromEntries( + Object.entries(fieldMap).map(([fieldName, field]) => [ + fieldName, + applyMiddlewareToField( + field, options, middleware as IMiddlewareFunction, - ); - return resolvers; - }, - {}, + ), + ]), ) return resolvers } else { - const resolvers = Object.keys(middleware).reduce( - (resolvers, fieldName) => { - resolvers[fieldName] = applyMiddlewareToField( - fieldMap[fieldName], - options, - middleware[fieldName], - ); - return resolvers; - }, - {}, + const resolvers = Object.fromEntries( + Object.entries(middleware).map(([fieldName, middlewareFn]) => [ + fieldName, + applyMiddlewareToField(fieldMap[fieldName], options, middlewareFn), + ]), ) return resolvers @@ -170,23 +163,21 @@ function applyMiddlewareToSchema( ): IResolvers { const typeMap = schema.getTypeMap() - const resolvers = Object.keys(typeMap) - .filter( - (type) => - isGraphQLObjectType(typeMap[type]) && - !isIntrospectionType(typeMap[type]), - ) - .reduce( - (resolvers, type) => { - resolvers[type] = applyMiddlewareToType( - typeMap[type] as GraphQLObjectType, + const resolvers = Object.fromEntries( + Object.entries(typeMap) + .filter( + ([, typeValue]) => + isGraphQLObjectType(typeValue) && !isIntrospectionType(typeValue), + ) + .map(([typeName, type]) => [ + typeName, + applyMiddlewareToType( + type as GraphQLObjectType, options, middleware, - ); - return resolvers; - }, - {}, - ) + ), + ]), + ) return resolvers } @@ -211,18 +202,17 @@ export function generateResolverFromSchemaAndMiddleware< } else { const typeMap = schema.getTypeMap() - const resolvers = Object.keys(middleware).reduce( - (resolvers, type) => { - resolvers[type] = applyMiddlewareToType( - typeMap[type] as GraphQLObjectType, + const resolvers = Object.fromEntries( + Object.entries(middleware).map(([typeName, middlewareFn]) => [ + typeName, + applyMiddlewareToType( + typeMap[typeName] as GraphQLObjectType, options, - middleware[type], - ); - return resolvers; - }, - {}, + middlewareFn, + ), + ]), ) return resolvers } -} \ No newline at end of file +}