@@ -739,10 +739,10 @@ Information about all fields sharing a response key are stored within Field
739
739
Group records, structures containing:
740
740
741
741
- {parentType}: the type of the parent object for this field.
742
+ - {fieldName}: the name of this field.
742
743
- {fields}: a map of lists of collected field nodes, indexed by the Defer
743
744
Details record corresponding to the originating enclosing deferred fragment,
744
- or {undefined} if the field is not contained by a deferred fragment.
745
- - {fieldDef}: the field definition for this field.
745
+ or by {undefined} if the field is not contained by a deferred fragment.
746
746
- {streamDetails}: information derived from any ` @stream ` directive on this
747
747
field.
748
748
- {priority}: the overall priority for this field group, equivalent to the
@@ -767,20 +767,18 @@ fragment ExampleFragment on Query {
767
767
subfield2
768
768
}
769
769
b
770
- }
770
+ }run
771
771
```
772
772
773
773
The depth-first-search order of the field groups produced by {CollectFields()}
774
774
is maintained through execution, ensuring that fields appear in the executed
775
775
response in a stable and predictable order.
776
776
777
777
CollectFields(objectType, selectionSet, variableValues, visitedFragments,
778
- deferredGroupedFieldsList ):
778
+ priority, parentFieldGroup, deferredFragment ):
779
779
780
- - If {visitedFragments} is not provided, initialize it to the empty set.
781
- - Initialize {groupedFields} to an empty ordered map of lists.
782
- - If {deferredGroupedFieldsList} is not provided, initialize it to an empty
783
- list.
780
+ - Initialize {groupedFieldSet} to an empty ordered map of Field Group records.
781
+ - Initialize {deferredFragments} to an empty map of Defer Details records.
784
782
- For each {selection} in {selectionSet}:
785
783
- If {selection} provides the directive ` @skip ` , let {skipDirective} be that
786
784
directive.
@@ -795,9 +793,30 @@ deferredGroupedFieldsList):
795
793
- If {selection} is a {Field}:
796
794
- Let {responseKey} be the response key of {selection} (the alias if
797
795
defined, otherwise the field name).
798
- - Let {groupForResponseKey} be the list in {groupedFields} for
799
- {responseKey}; if no such list exists, create it as an empty list.
800
- - Append {selection} to the {groupForResponseKey}.
796
+ - Let {groupForResponseKey} be the entry in in {groupedFieldSet} for
797
+ {responseKey}.
798
+ - If {groupForResponseKey} is {undefined}:
799
+ - Let {fieldName} be the name of {selection}.
800
+ - Initialize {fields} to an empty map of lists of collected field nodes,
801
+ indexed by originating Defer Details record, or by {undefined}.
802
+ - Let {listForDeferredFragment} be a list containing {selection}.
803
+ - Set the entry for {deferredFragment} in {fields} to
804
+ {listForDeferredFragment}.
805
+ - If {selection} provides the directive ` @stream ` and its {if} argument is
806
+ not {false} and is not a variable in {variableValues} with the value
807
+ {false}, let {streamDirective} be that directive.
808
+ - Let {groupForResponseKey} be a new Field Group record created from
809
+ {runtimeType}, {fieldName}, {fields}, {streamDetails}, {priority}, and
810
+ {parentFieldGroup}.
811
+ - Otherwise:
812
+ - Let {fields} be the corresponding entry on {groupForResponseKey}.
813
+ - Let {listForDeferredFragment} be the list in {fields} for
814
+ {deferredFragment}; if no such list exists, create it as an empty list.
815
+ - Append {selection} to {listForDeferredFragment}.
816
+ - Let {fieldGroupPriority} be the value of the {priority} entry on
817
+ {fieldGroup}.
818
+ - If {priority} is less than {fieldGroupPriority}, update the {priority}
819
+ entry on {fieldGroup} to {priority}.
801
820
- If {selection} is a {FragmentSpread}:
802
821
- Let {fragmentSpreadName} be the name of {selection}.
803
822
- If {fragmentSpreadName} provides the directive ` @defer ` and its {if}
@@ -818,24 +837,61 @@ deferredGroupedFieldsList):
818
837
- If {DoesFragmentTypeApply(objectType, fragmentType)} is false, continue
819
838
with the next {selection} in {selectionSet}.
820
839
- Let {fragmentSelectionSet} be the top-level selection set of {fragment}.
840
+ - Let {maybeNewDefer} be equal to {deferDirective}.
841
+ - Let {maybeIncreasedPriority} be equal to {priority}.
821
842
- If {deferDirective} is defined:
843
+ - If {parentFieldGroup} is {undefined}, set {maybeIncreasedPriority} to 1.
844
+ - Otherwise:
845
+ - Let {parentFieldGroupPriority} be the value of the {priority} entry on
846
+ {parentFieldGroup}.
847
+ - If {maybeIncreasedPriority} is equal to {parentFieldGroupPriority},
848
+ set {maybeIncreasedPriority} to {maybeIncreasedPriority} + 1.
822
849
- Let {label} be the value or the variable to {deferDirective}'s {label}
823
850
argument.
824
- - Let {deferredGroupedFields} be the result of calling
825
- {CollectFields(objectType, fragmentSelectionSet, variableValues,
826
- visitedFragments, deferredGroupedFieldsList)}.
827
- - Append a record containing {label} and {deferredGroupedFields} to
828
- {deferredGroupedFieldsList}.
829
- - Continue with the next {selection} in {selectionSet}.
830
- - Let {fragmentGroupedFieldSet} be the result of calling
831
- {CollectFields(objectType, fragmentSelectionSet, variableValues,
832
- visitedFragments, deferredGroupedFieldsList)}.
833
- - For each {fragmentGroup} in {fragmentGroupedFieldSet}:
834
- - Let {responseKey} be the response key shared by all fields in
835
- {fragmentGroup}.
836
- - Let {groupForResponseKey} be the list in {groupedFields} for
837
- {responseKey}; if no such list exists, create it as an empty list.
838
- - Append all items in {fragmentGroup} to {groupForResponseKey}.
851
+ - Let {existingDefer} be the record in {deferredFragments} for {label}.
852
+ - If {existingDefer} is undefined:
853
+ - Set {maybeNewDefer} equal to a new Deferred Details record created
854
+ from {label} and {maybeIncreasedPriority}.
855
+ - Set the record in {deferredFragments} for {label} to {maybeNewDefer}.
856
+ - Otherwise, set {maybeNewDefer} to {existingDefer}.
857
+ - Let {fragmentGroupedFieldSet} and {fragmentDeferredFragments} be the
858
+ result of calling {CollectFields(objectType, fragmentSelectionSet,
859
+ variableValues, visitedFragments, maybeIncreasedPriority,
860
+ parentFieldGroup, maybeNewDefer)}.
861
+ - For each {label} and {fragmentDeferredFragment} in
862
+ {fragmentDeferredFragments}:
863
+ - Let {deferredFragment} be the record in {deferredFragments} for {label}.
864
+ - If {deferredFragment} is {undefined}:
865
+ - Set the record in {deferredFragments} for {label} to
866
+ {fragmentDeferredFragment}.
867
+ - For each {responseKey} and {fragmentGroup} in {fragmentGroupedFieldSet}:
868
+ - Let {groupForResponseKey} be the record in {groupedFieldSet} for
869
+ {responseKey}.
870
+ - If {groupForResponseKey} is {undefined}, set the record in
871
+ {groupedFieldSet} for {responseKey} to {fragmentGroup}.
872
+ - Otherwise:
873
+ - Let {fieldGroupPriority} be equal to the {priority} entry on
874
+ {fragmentGroup}.
875
+ - Let {fragmentGroupPriority} be equal to the {priority} entry on
876
+ {fragmentGroup}.
877
+ - If {fragmentGroupPriority} is less than {fieldGroupPriority}, update
878
+ the {priority} entry on {fieldGroup} to {fragmentGroupPriority}.
879
+ - Let {fields} be the corresponding entry on {groupForResponseKey}.
880
+ - Let {fragmentFields} be equal to the {fields} entry on
881
+ {fragmentGroup}.
882
+ - For each {fragmentDeferredFragment} and
883
+ {fragmentListForDeferredFragment} in {fragmentFields}:
884
+ - Let {label} be the corresponding entry in
885
+ {fragmentDeferredFragment}.
886
+ - Let {deferredFragment} be the record in {deferredFragments} for
887
+ {label}.
888
+ - Let {listForDeferredFragment} be the record in {fields} for
889
+ {deferredFragment}.
890
+ - If {listForDeferredFragment} is {undefined}, set the record in
891
+ {fields} for {deferredFragment} to
892
+ {fragmentListForDeferredFragment}.
893
+ - Otherwise, append all items in {fragmentListForDeferredFragment} to
894
+ {listForDeferredFragment}.
839
895
- If {selection} is an {InlineFragment}:
840
896
- Let {fragmentType} be the type condition on {selection}.
841
897
- If {fragmentType} is not {null} and {DoesFragmentTypeApply(objectType,
@@ -848,24 +904,62 @@ deferredGroupedFieldsList):
848
904
- Let {deferDirective} be that directive.
849
905
- If this execution is for a subscription operation, raise a _ field
850
906
error_ .
907
+ - Let {fragmentSelectionSet} be the top-level selection set of {fragment}.
908
+ - Let {maybeNewDefer} be equal to {deferDirective}.
909
+ - Let {maybeIncreasedPriority} be equal to {priority}.
851
910
- If {deferDirective} is defined:
911
+ - If {parentFieldGroup} is {undefined}, set {maybeIncreasedPriority} to 1.
912
+ - Otherwise:
913
+ - Let {parentFieldGroupPriority} be the value of the {priority} entry on
914
+ {parentFieldGroup}.
915
+ - If {maybeIncreasedPriority} is equal to {parentFieldGroupPriority},
916
+ set {maybeIncreasedPriority} to {maybeIncreasedPriority} + 1.
852
917
- Let {label} be the value or the variable to {deferDirective}'s {label}
853
918
argument.
854
- - Let {deferredGroupedFields} be the result of calling
855
- {CollectFields(objectType, fragmentSelectionSet, variableValues,
856
- visitedFragments, deferredGroupedFieldsList)}.
857
- - Append a record containing {label} and {deferredGroupedFields} to
858
- {deferredGroupedFieldsList}.
859
- - Continue with the next {selection} in {selectionSet}.
860
- - Let {fragmentGroupedFieldSet} be the result of calling
861
- {CollectFields(objectType, fragmentSelectionSet, variableValues,
862
- visitedFragments, deferredGroupedFieldsList)}.
863
- - For each {fragmentGroup} in {fragmentGroupedFieldSet}:
864
- - Let {responseKey} be the response key shared by all fields in
865
- {fragmentGroup}.
866
- - Let {groupForResponseKey} be the list in {groupedFields} for
867
- {responseKey}; if no such list exists, create it as an empty list.
868
- - Append all items in {fragmentGroup} to {groupForResponseKey}.
919
+ - Let {existingDefer} be the record in {deferredFragments} for {label}.
920
+ - If {existingDefer} is undefined:
921
+ - Set {maybeNewDefer} equal to a new Deferred Details record created
922
+ from {label} and {maybeIncreasedPriority}.
923
+ - Set the record in {deferredFragments} for {label} to {maybeNewDefer}.
924
+ - Otherwise, set {maybeNewDefer} to {existingDefer}.
925
+ - Let {fragmentGroupedFieldSet} and {fragmentDeferredFragments} be the
926
+ result of calling {CollectFields(objectType, fragmentSelectionSet,
927
+ variableValues, visitedFragments, maybeIncreasedPriority,
928
+ parentFieldGroup, maybeNewDefer)}.
929
+ - For each {label} and {fragmentDeferredFragment} in
930
+ {fragmentDeferredFragments}:
931
+ - Let {deferredFragment} be the record in {deferredFragments} for {label}.
932
+ - If {deferredFragment} is {undefined}:
933
+ - Set the record in {deferredFragments} for {label} to
934
+ {fragmentDeferredFragment}.
935
+ - For each {responseKey} and {fragmentGroup} in {fragmentGroupedFieldSet}:
936
+ - Let {groupForResponseKey} be the record in {groupedFieldSet} for
937
+ {responseKey}.
938
+ - If {groupForResponseKey} is {undefined}, set the record in
939
+ {groupedFieldSet} for {responseKey} to {fragmentGroup}.
940
+ - Otherwise:
941
+ - Let {fieldGroupPriority} be equal to the {priority} entry on
942
+ {fragmentGroup}.
943
+ - Let {fragmentGroupPriority} be equal to the {priority} entry on
944
+ {fragmentGroup}.
945
+ - If {fragmentGroupPriority} is less than {fieldGroupPriority}, update
946
+ the {priority} entry on {fieldGroup} to {fragmentGroupPriority}.
947
+ - Let {fields} be the corresponding entry on {groupForResponseKey}.
948
+ - Let {fragmentFields} be equal to the {fields} entry on
949
+ {fragmentGroup}.
950
+ - For each {fragmentDeferredFragment} and
951
+ {fragmentListForDeferredFragment} in {fragmentFields}:
952
+ - Let {label} be the corresponding entry in
953
+ {fragmentDeferredFragment}.
954
+ - Let {deferredFragment} be the record in {deferredFragments} for
955
+ {label}.
956
+ - Let {listForDeferredFragment} be the record in {fields} for
957
+ {deferredFragment}.
958
+ - If {listForDeferredFragment} is {undefined}, set the record in
959
+ {fields} for {deferredFragment} to
960
+ {fragmentListForDeferredFragment}.
961
+ - Otherwise, append all items in {fragmentListForDeferredFragment} to
962
+ {listForDeferredFragment}.
869
963
- Return {groupedFields}, {deferredGroupedFieldsList} and {visitedFragments}.
870
964
871
965
Note: The steps in {CollectFields()} evaluating the ` @skip ` and ` @include `
0 commit comments