Skip to content

Commit 0ebcb2f

Browse files
collectFields: use ES6 collections instead of Object.create(null) (#3082)
1 parent 86523ec commit 0ebcb2f

File tree

3 files changed

+32
-32
lines changed

3 files changed

+32
-32
lines changed

src/execution/execute.js

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -333,8 +333,8 @@ function executeOperation(
333333
exeContext,
334334
type,
335335
operation.selectionSet,
336-
Object.create(null),
337-
Object.create(null),
336+
new Map(),
337+
new Set(),
338338
);
339339

340340
const path = undefined;
@@ -369,12 +369,11 @@ function executeFieldsSerially(
369369
parentType: GraphQLObjectType,
370370
sourceValue: mixed,
371371
path: Path | void,
372-
fields: ObjMap<Array<FieldNode>>,
372+
fields: Map<string, Array<FieldNode>>,
373373
): PromiseOrValue<ObjMap<mixed>> {
374374
return promiseReduce(
375-
Object.keys(fields),
376-
(results, responseName) => {
377-
const fieldNodes = fields[responseName];
375+
fields.entries(),
376+
(results, [responseName, fieldNodes]) => {
378377
const fieldPath = addPath(path, responseName, parentType.name);
379378
const result = resolveField(
380379
exeContext,
@@ -408,13 +407,12 @@ function executeFields(
408407
parentType: GraphQLObjectType,
409408
sourceValue: mixed,
410409
path: Path | void,
411-
fields: ObjMap<Array<FieldNode>>,
410+
fields: Map<string, Array<FieldNode>>,
412411
): PromiseOrValue<ObjMap<mixed>> {
413412
const results = Object.create(null);
414413
let containsPromise = false;
415414

416-
for (const responseName of Object.keys(fields)) {
417-
const fieldNodes = fields[responseName];
415+
for (const [responseName, fieldNodes] of fields.entries()) {
418416
const fieldPath = addPath(path, responseName, parentType.name);
419417
const result = resolveField(
420418
exeContext,
@@ -457,20 +455,22 @@ export function collectFields(
457455
exeContext: ExecutionContext,
458456
runtimeType: GraphQLObjectType,
459457
selectionSet: SelectionSetNode,
460-
fields: ObjMap<Array<FieldNode>>,
461-
visitedFragmentNames: ObjMap<boolean>,
462-
): ObjMap<Array<FieldNode>> {
458+
fields: Map<string, Array<FieldNode>>,
459+
visitedFragmentNames: Set<string>,
460+
): Map<string, Array<FieldNode>> {
463461
for (const selection of selectionSet.selections) {
464462
switch (selection.kind) {
465463
case Kind.FIELD: {
466464
if (!shouldIncludeNode(exeContext, selection)) {
467465
continue;
468466
}
469467
const name = getFieldEntryKey(selection);
470-
if (!fields[name]) {
471-
fields[name] = [];
468+
const fieldList = fields.get(name);
469+
if (fieldList !== undefined) {
470+
fieldList.push(selection);
471+
} else {
472+
fields.set(name, [selection]);
472473
}
473-
fields[name].push(selection);
474474
break;
475475
}
476476
case Kind.INLINE_FRAGMENT: {
@@ -492,12 +492,12 @@ export function collectFields(
492492
case Kind.FRAGMENT_SPREAD: {
493493
const fragName = selection.name.value;
494494
if (
495-
visitedFragmentNames[fragName] ||
495+
visitedFragmentNames.has(fragName) ||
496496
!shouldIncludeNode(exeContext, selection)
497497
) {
498498
continue;
499499
}
500-
visitedFragmentNames[fragName] = true;
500+
visitedFragmentNames.add(fragName);
501501
const fragment = exeContext.fragments[fragName];
502502
if (
503503
!fragment ||
@@ -1085,9 +1085,9 @@ function _collectSubfields(
10851085
exeContext: ExecutionContext,
10861086
returnType: GraphQLObjectType,
10871087
fieldNodes: $ReadOnlyArray<FieldNode>,
1088-
): ObjMap<Array<FieldNode>> {
1089-
let subFieldNodes = Object.create(null);
1090-
const visitedFragmentNames = Object.create(null);
1088+
): Map<string, Array<FieldNode>> {
1089+
let subFieldNodes = new Map();
1090+
const visitedFragmentNames = new Set();
10911091
for (const node of fieldNodes) {
10921092
if (node.selectionSet) {
10931093
subFieldNodes = collectFields(

src/jsutils/promiseReduce.js

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,15 @@ import { isPromise } from './isPromise';
1010
* return a Promise.
1111
*/
1212
export function promiseReduce<T, U>(
13-
values: $ReadOnlyArray<T>,
14-
callback: (accumulator: U, currentValue: T) => PromiseOrValue<U>,
13+
values: Iterable<T>,
14+
callbackFn: (accumulator: U, currentValue: T) => PromiseOrValue<U>,
1515
initialValue: PromiseOrValue<U>,
1616
): PromiseOrValue<U> {
17-
return values.reduce(
18-
(previous, value) =>
19-
isPromise(previous)
20-
? previous.then((resolved) => callback(resolved, value))
21-
: callback(previous, value),
22-
initialValue,
23-
);
17+
let accumulator = initialValue;
18+
for (const value of values) {
19+
accumulator = isPromise(accumulator)
20+
? accumulator.then((resolved) => callbackFn(resolved, value))
21+
: callbackFn(accumulator, value);
22+
}
23+
return accumulator;
2424
}

src/subscription/subscribe.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -195,10 +195,10 @@ async function executeSubscription(
195195
exeContext,
196196
type,
197197
operation.selectionSet,
198-
Object.create(null),
199-
Object.create(null),
198+
new Map(),
199+
new Set(),
200200
);
201-
const [responseName, fieldNodes] = Object.entries(fields)[0];
201+
const [responseName, fieldNodes] = [...fields.entries()][0];
202202
const fieldName = fieldNodes[0].name.value;
203203
const fieldDef = getFieldDef(schema, type, fieldName);
204204

0 commit comments

Comments
 (0)