334
334
335
335
ExecuteSelectionSet(selectionSet, objectType, objectValue, variableValues):
336
336
337
- - Let {groupedFieldSet} be the result of {CollectFields(objectType,
338
- selectionSet, variableValues)}.
337
+ - Let {groupedFieldSet} and {groupedSignals} be the result of
338
+ {CollectFields(objectType, selectionSet, variableValues)}.
339
339
- Initialize {resultMap} to an empty ordered map.
340
340
- For each {groupedFieldSet} as {responseKey} and {fields}:
341
341
- Let {fieldName} be the name of the first entry in {fields}. Note: This value
@@ -346,6 +346,12 @@ ExecuteSelectionSet(selectionSet, objectType, objectValue, variableValues):
346
346
- Let {responseValue} be {ExecuteField(objectType, objectValue, fieldType,
347
347
fields, variableValues)}.
348
348
- Set {responseValue} as the value for {responseKey} in {resultMap}.
349
+ - For each {groupedSignals} as {referenceName} and {requestedSignals}:
350
+ - Initialize {signalValues} to an empty ordered map.
351
+ - For each {signal} in {requestedSignals}:
352
+ - If the signal type of {signal} is ` selected ` :
353
+ - Set {null} as the value for ` selected ` in {signalValues}.
354
+ - Set {signalValues} as the value for {referenceName} in {resultMap}.
349
355
- Return {resultMap}.
350
356
351
357
Note: {resultMap} is ordered by which fields appear first in the operation. This
@@ -461,11 +467,12 @@ A correct executor must generate the following result for that selection set:
461
467
462
468
### Field Collection
463
469
464
- Before execution, the selection set is converted to a grouped field set by
465
- calling {CollectFields()}. Each entry in the grouped field set is a list of
466
- fields that share a response key (the alias if defined, otherwise the field
467
- name). This ensures all fields with the same response key (including those in
468
- referenced fragments) are executed at the same time.
470
+ Before execution, the selection set is converted to a grouped field set and
471
+ grouped reference signal set by calling {CollectFields()}. Each entry in the
472
+ grouped field set is a list of fields that share a response key (the alias if
473
+ defined, otherwise the field name). This ensures all fields with the same
474
+ response key (including those in referenced fragments) are executed at the same
475
+ time.
469
476
470
477
As an example, collecting the fields of this selection set would collect two
471
478
instances of the field ` a ` and one of field ` b ` :
@@ -494,6 +501,7 @@ CollectFields(objectType, selectionSet, variableValues, visitedFragments):
494
501
495
502
- If {visitedFragments} is not provided, initialize it to the empty set.
496
503
- Initialize {groupedFields} to an empty ordered map of lists.
504
+ - Initialize {groupedSignals} to an empty ordered map of sets.
497
505
- For each {selection} in {selectionSet}:
498
506
- If {selection} provides the directive ` @skip ` , let {skipDirective} be that
499
507
directive.
@@ -523,32 +531,52 @@ CollectFields(objectType, selectionSet, variableValues, visitedFragments):
523
531
- Let {fragmentType} be the type condition on {fragment}.
524
532
- If {DoesFragmentTypeApply(objectType, fragmentType)} is false, continue
525
533
with the next {selection} in {selectionSet}.
534
+ - If a {reference} is defined for the given {fragment}:
535
+ - Let {signalsForReference} be the result of calling
536
+ {CollectSignals(reference)}.
537
+ - Let {referenceName} be the name of {reference}.
538
+ - Set the entry for {referenceName} in {groupedSignals} to
539
+ {signalsForReference}.
526
540
- Let {fragmentSelectionSet} be the top-level selection set of {fragment}.
527
- - Let {fragmentGroupedFieldSet} be the result of calling
528
- {CollectFields(objectType, fragmentSelectionSet, variableValues ,
529
- visitedFragments)}.
541
+ - Let {fragmentGroupedFieldSet} and {fragmentRequestedSignals} be the result
542
+ of calling {CollectFields(objectType, fragmentSelectionSet,
543
+ variableValues, visitedFragments)}.
530
544
- For each {fragmentGroup} in {fragmentGroupedFieldSet}:
531
545
- Let {responseKey} be the response key shared by all fields in
532
546
{fragmentGroup}.
533
547
- Let {groupForResponseKey} be the list in {groupedFields} for
534
548
{responseKey}; if no such list exists, create it as an empty list.
535
549
- Append all items in {fragmentGroup} to {groupForResponseKey}.
550
+ - For each {fragmentRequestedSignals} as {referenceName} and
551
+ {signalsForReference}:
552
+ - Set the entry for {referenceName} in {groupedSignals} to
553
+ {signalsForReference}.
536
554
- If {selection} is an {InlineFragment}:
537
555
- Let {fragmentType} be the type condition on {selection}.
538
556
- If {fragmentType} is not {null} and {DoesFragmentTypeApply(objectType,
539
557
fragmentType)} is false, continue with the next {selection} in
540
558
{selectionSet}.
559
+ - If a {reference} is defined for the given {fragment}:
560
+ - Let {signalsForReference} be the result of calling
561
+ {CollectSignals(reference)}.
562
+ - Let {referenceName} be the name of {reference}.
563
+ - Set the entry for {referenceName} in {requestedSignals} to
564
+ {signalsForReference}.
541
565
- Let {fragmentSelectionSet} be the top-level selection set of {selection}.
542
- - Let {fragmentGroupedFieldSet} be the result of calling
543
- {CollectFields(objectType, fragmentSelectionSet, variableValues ,
544
- visitedFragments)}.
566
+ - Let {fragmentGroupedFieldSet} and {fragmentRequestedSignals} be the result
567
+ of calling {CollectFields(objectType, fragmentSelectionSet,
568
+ variableValues, visitedFragments)}.
545
569
- For each {fragmentGroup} in {fragmentGroupedFieldSet}:
546
570
- Let {responseKey} be the response key shared by all fields in
547
571
{fragmentGroup}.
548
572
- Let {groupForResponseKey} be the list in {groupedFields} for
549
573
{responseKey}; if no such list exists, create it as an empty list.
550
574
- Append all items in {fragmentGroup} to {groupForResponseKey}.
551
- - Return {groupedFields}.
575
+ - For each {fragmentRequestedSignals} as {referenceName} and
576
+ {signalsForReference}:
577
+ - Set the entry for {referenceName} in {groupedSignals} to
578
+ {signalsForReference}.
579
+ - Return {groupedFields} and {groupedSignals}.
552
580
553
581
DoesFragmentTypeApply(objectType, fragmentType):
554
582
@@ -562,6 +590,15 @@ DoesFragmentTypeApply(objectType, fragmentType):
562
590
- if {objectType} is a possible type of {fragmentType}, return {true}
563
591
otherwise return {false}.
564
592
593
+ CollectSignals(reference):
594
+
595
+ - Let {signalsForReference} be an empty set.
596
+ - Let {signalSet} be the signal set of {reference}.
597
+ - For each {signal} in {signalSet}:
598
+ - Let {signalType} be the signal type of {signal}.
599
+ - Add {signalType} to {signalsForReference}.
600
+ - Return {signalsForReference}.
601
+
565
602
Note: The steps in {CollectFields()} evaluating the ` @skip ` and ` @include `
566
603
directives may be applied in either order since they apply commutatively.
567
604
0 commit comments