Skip to content

Commit ceec0ce

Browse files
committed
perf: optimize replaceVariables
1 parent fcb1a1d commit ceec0ce

File tree

1 file changed

+51
-22
lines changed

1 file changed

+51
-22
lines changed

src/utilities/replaceVariables.ts

+51-22
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
11
import type { Maybe } from '../jsutils/Maybe.js';
22

3-
import type { ConstValueNode, ValueNode } from '../language/ast.js';
3+
import type {
4+
ConstValueNode,
5+
ObjectFieldNode,
6+
ValueNode,
7+
} from '../language/ast.js';
48
import { Kind } from '../language/kinds.js';
5-
import { visit } from '../language/visitor.js';
69

710
import type { VariableValues } from '../execution/values.js';
811

@@ -21,9 +24,9 @@ export function replaceVariables(
2124
variableValues?: Maybe<VariableValues>,
2225
fragmentVariableValues?: Maybe<VariableValues>,
2326
): ConstValueNode {
24-
return visit(valueNode, {
25-
Variable(node) {
26-
const varName = node.name.value;
27+
switch (valueNode.kind) {
28+
case Kind.VARIABLE: {
29+
const varName = valueNode.name.value;
2730
const scopedVariableValues = fragmentVariableValues?.sources[varName]
2831
? fragmentVariableValues
2932
: variableValues;
@@ -36,23 +39,19 @@ export function replaceVariables(
3639
if (scopedVariableSource.value === undefined) {
3740
const defaultValue = scopedVariableSource.signature.defaultValue;
3841
if (defaultValue !== undefined) {
39-
return defaultValue.literal;
42+
return defaultValue.literal as ConstValueNode;
4043
}
4144
}
4245

4346
return valueToLiteral(
4447
scopedVariableSource.value,
4548
scopedVariableSource.signature.type,
46-
);
47-
},
48-
ObjectValue(node) {
49-
return {
50-
...node,
51-
// Filter out any fields with a missing variable.
52-
fields: node.fields.filter((field) => {
53-
if (field.value.kind !== Kind.VARIABLE) {
54-
return true;
55-
}
49+
) as ConstValueNode;
50+
}
51+
case Kind.OBJECT: {
52+
const newFields: Array<ObjectFieldNode> = [];
53+
for (const field of valueNode.fields) {
54+
if (field.value.kind === Kind.VARIABLE) {
5655
const scopedVariableSource =
5756
fragmentVariableValues?.sources[field.value.name.value] ??
5857
variableValues?.sources[field.value.name.value];
@@ -61,11 +60,41 @@ export function replaceVariables(
6160
scopedVariableSource?.value === undefined &&
6261
scopedVariableSource?.signature.defaultValue === undefined
6362
) {
64-
return false;
63+
continue;
6564
}
66-
return true;
67-
}),
68-
};
69-
},
70-
}) as ConstValueNode;
65+
}
66+
const newFieldNodeValue = replaceVariables(
67+
field.value,
68+
variableValues,
69+
fragmentVariableValues,
70+
);
71+
newFields.push({
72+
...field,
73+
value: newFieldNodeValue,
74+
});
75+
}
76+
return {
77+
...valueNode,
78+
fields: newFields,
79+
} as ConstValueNode;
80+
}
81+
case Kind.LIST: {
82+
const newValues: Array<ValueNode> = [];
83+
for (const value of valueNode.values) {
84+
const newItemNodeValue = replaceVariables(
85+
value,
86+
variableValues,
87+
fragmentVariableValues,
88+
);
89+
newValues.push(newItemNodeValue);
90+
}
91+
return {
92+
...valueNode,
93+
values: newValues,
94+
} as ConstValueNode;
95+
}
96+
default: {
97+
return valueNode;
98+
}
99+
}
71100
}

0 commit comments

Comments
 (0)