From de1100ff0583d648bdaf45003e78c0a1b8d160d5 Mon Sep 17 00:00:00 2001 From: Yaacov Rydzinski Date: Wed, 2 Oct 2024 06:24:18 +0300 Subject: [PATCH] perf: optimize replaceVariables --- src/utilities/replaceVariables.ts | 73 +++++++++++++++++++++---------- 1 file changed, 51 insertions(+), 22 deletions(-) diff --git a/src/utilities/replaceVariables.ts b/src/utilities/replaceVariables.ts index 747931fab7..307c987a01 100644 --- a/src/utilities/replaceVariables.ts +++ b/src/utilities/replaceVariables.ts @@ -1,8 +1,11 @@ import type { Maybe } from '../jsutils/Maybe.js'; -import type { ConstValueNode, ValueNode } from '../language/ast.js'; +import type { + ConstValueNode, + ObjectFieldNode, + ValueNode, +} from '../language/ast.js'; import { Kind } from '../language/kinds.js'; -import { visit } from '../language/visitor.js'; import type { VariableValues } from '../execution/values.js'; @@ -21,9 +24,9 @@ export function replaceVariables( variableValues?: Maybe, fragmentVariableValues?: Maybe, ): ConstValueNode { - return visit(valueNode, { - Variable(node) { - const varName = node.name.value; + switch (valueNode.kind) { + case Kind.VARIABLE: { + const varName = valueNode.name.value; const scopedVariableValues = fragmentVariableValues?.sources[varName] ? fragmentVariableValues : variableValues; @@ -36,23 +39,19 @@ export function replaceVariables( if (scopedVariableSource.value === undefined) { const defaultValue = scopedVariableSource.signature.defaultValue; if (defaultValue !== undefined) { - return defaultValue.literal; + return defaultValue.literal as ConstValueNode; } } return valueToLiteral( scopedVariableSource.value, scopedVariableSource.signature.type, - ); - }, - ObjectValue(node) { - return { - ...node, - // Filter out any fields with a missing variable. - fields: node.fields.filter((field) => { - if (field.value.kind !== Kind.VARIABLE) { - return true; - } + ) as ConstValueNode; + } + case Kind.OBJECT: { + const newFields: Array = []; + for (const field of valueNode.fields) { + if (field.value.kind === Kind.VARIABLE) { const scopedVariableSource = fragmentVariableValues?.sources[field.value.name.value] ?? variableValues?.sources[field.value.name.value]; @@ -61,11 +60,41 @@ export function replaceVariables( scopedVariableSource?.value === undefined && scopedVariableSource?.signature.defaultValue === undefined ) { - return false; + continue; } - return true; - }), - }; - }, - }) as ConstValueNode; + } + const newFieldNodeValue = replaceVariables( + field.value, + variableValues, + fragmentVariableValues, + ); + newFields.push({ + ...field, + value: newFieldNodeValue, + }); + } + return { + ...valueNode, + fields: newFields, + } as ConstValueNode; + } + case Kind.LIST: { + const newValues: Array = []; + for (const value of valueNode.values) { + const newItemNodeValue = replaceVariables( + value, + variableValues, + fragmentVariableValues, + ); + newValues.push(newItemNodeValue); + } + return { + ...valueNode, + values: newValues, + } as ConstValueNode; + } + default: { + return valueNode; + } + } }