Skip to content

Commit 1bb1417

Browse files
authored
buildClientSchema: build enum type value maps lazily (#4424)
The option of passing a thunk was made available by: #4018 . Always passing the thunk helps contribute to a "lazy" build process, which gives the following performance boost: ![image](https://github.com/user-attachments/assets/569b9b79-e6d9-44b6-b073-045d2df72c3c) Lazy evaluation results in bad names for enum values not being checked until `type.getValues()` is called, similar to how bad names for fields are not checked until `type.getFields()` is called. Explicit validation validates enum value names just as with field names.
1 parent 9e6c0e2 commit 1bb1417

File tree

2 files changed

+24
-21
lines changed

2 files changed

+24
-21
lines changed

src/type/__tests__/definition-test.ts

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -794,15 +794,15 @@ describe('Type System: Enums', () => {
794794
});
795795

796796
it('rejects an Enum type with incorrectly named values', () => {
797-
expect(
798-
() =>
799-
new GraphQLEnumType({
800-
name: 'SomeEnum',
801-
values: {
802-
'bad-name': {},
803-
},
804-
}),
805-
).to.throw('Names must only contain [_a-zA-Z0-9] but "bad-name" does not.');
797+
const enumType = new GraphQLEnumType({
798+
name: 'SomeEnum',
799+
values: {
800+
'bad-name': {},
801+
},
802+
});
803+
expect(() => enumType.getValues()).to.throw(
804+
'Names must only contain [_a-zA-Z0-9] but "bad-name" does not.',
805+
);
806806
});
807807
});
808808

src/type/definition.ts

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1563,7 +1563,7 @@ export class GraphQLEnumType /* <T> */ implements GraphQLSchemaElement {
15631563

15641564
private _values:
15651565
| ReadonlyArray<GraphQLEnumValue /* <T> */>
1566-
| (() => GraphQLEnumValueConfigMap);
1566+
| (() => ReadonlyArray<GraphQLEnumValue>) /* <T> */;
15671567

15681568
private _valueLookup: ReadonlyMap<any /* T */, GraphQLEnumValue> | null;
15691569
private _nameLookup: ObjMap<GraphQLEnumValue> | null;
@@ -1576,13 +1576,7 @@ export class GraphQLEnumType /* <T> */ implements GraphQLSchemaElement {
15761576
this.astNode = config.astNode;
15771577
this.extensionASTNodes = config.extensionASTNodes ?? [];
15781578

1579-
this._values =
1580-
typeof config.values === 'function'
1581-
? config.values
1582-
: Object.entries(config.values).map(
1583-
([valueName, valueConfig]) =>
1584-
new GraphQLEnumValue(this, valueName, valueConfig),
1585-
);
1579+
this._values = defineEnumValues.bind(undefined, this, config.values);
15861580
this._valueLookup = null;
15871581
this._nameLookup = null;
15881582
}
@@ -1593,10 +1587,7 @@ export class GraphQLEnumType /* <T> */ implements GraphQLSchemaElement {
15931587

15941588
getValues(): ReadonlyArray<GraphQLEnumValue /* <T> */> {
15951589
if (typeof this._values === 'function') {
1596-
this._values = Object.entries(this._values()).map(
1597-
([valueName, valueConfig]) =>
1598-
new GraphQLEnumValue(this, valueName, valueConfig),
1599-
);
1590+
this._values = this._values();
16001591
}
16011592
return this._values;
16021593
}
@@ -1722,6 +1713,18 @@ export class GraphQLEnumType /* <T> */ implements GraphQLSchemaElement {
17221713
}
17231714
}
17241715

1716+
function defineEnumValues(
1717+
parentEnum: GraphQLEnumType,
1718+
values: ThunkObjMap<GraphQLEnumValueConfig /* <T> */>,
1719+
): ReadonlyArray<GraphQLEnumValue> {
1720+
const valueMap = resolveObjMapThunk(values);
1721+
1722+
return Object.entries(valueMap).map(
1723+
([valueName, valueConfig]) =>
1724+
new GraphQLEnumValue(parentEnum, valueName, valueConfig),
1725+
);
1726+
}
1727+
17251728
function didYouMeanEnumValue(
17261729
enumType: GraphQLEnumType,
17271730
unknownValueStr: string,

0 commit comments

Comments
 (0)