@@ -857,10 +857,15 @@ and so that fields are grouped according to the set of deferred fragments that
857857include them.
858858
859859Information derived from the presence of a ` @defer ` directive on a fragment is
860- returned as a Defer Usage record, unique to the label, a structure containing
861- only:
860+ returned as a Defer Usage record, unique to the label, a structure containing:
862861
863862- {label}: value of the corresponding argument to the ` @defer ` directive.
863+ - {ancestors}: a list, where the first entry is the parent Defer Usage record
864+ corresponding to the deferred fragment enclosing this deferred fragment and
865+ the remaining entries are the values included within the {ancestors} entry of
866+ that parent Defer Usage record, or, if this Defer Usage record is deferred
867+ directly by the initial result, a list containing the single value
868+ {undefined}.
864869
865870A Field Group record is a structure containing:
866871
@@ -943,7 +948,13 @@ parentTarget, newTarget):
943948 - If {deferDirective} is defined:
944949 - Let {label} be the value or the variable to {deferDirective}'s {label}
945950 argument.
946- - Let {target} be a new Defer Usage record created from {label}.
951+ - Let {ancestors} be an empty list.
952+ - Append {parentTarget} to {ancestors}.
953+ - If {parentTarget} is defined:
954+ - Let {parentAncestors} be the {ancestor} entry on {parentTarget}.
955+ - Append all items in {parentAncestors} to {ancestors}.
956+ - Let {target} be a new Defer Usage record created from {label} and
957+ {ancestors}.
947958 - Append {target} to {newDeferUsages}.
948959 - Otherwise:
949960 - Let {target} be {newTarget}.
@@ -978,7 +989,13 @@ parentTarget, newTarget):
978989 - If {deferDirective} is defined:
979990 - Let {label} be the value or the variable to {deferDirective}'s {label}
980991 argument.
981- - Let {target} be a new Defer Usage record created from {label}.
992+ - Let {ancestors} be an empty list.
993+ - Append {parentTarget} to {ancestors}.
994+ - If {parentTarget} is defined:
995+ - Let {parentAncestors} be {ancestor} on {parentTarget}.
996+ - Append all items in {parentAncestors} to {ancestors}.
997+ - Let {target} be a new Defer Usage record created from {label} and
998+ {ancestors}.
982999 - Append {target} to {newDeferUsages}.
9831000 - Otherwise:
9841001 - Let {target} be {newTarget}.
@@ -1033,31 +1050,84 @@ BuildGroupedFieldSets(fieldsByTarget, targetsByKey, parentTargets)
10331050 - Let {fieldDetails} be a new Field Details record created from {node}
10341051 and {target}.
10351052 - Append {fieldDetails} to the {fields} entry on {fieldGroup}.
1036- - Continue to the next entry in {targetsByKey}.
1037- - For each {key} in {groupDetailsMap}:
1038- - If {IsSameSet(targets, key)} is {true}:
1039- - Let {details} be the map in {groupDetailsMap} for {targets}.
1040- - Let {newGroupedFieldSet} be the corresponding entry on {details}.
1041- - If {details} is not defined:
1042- - Initialize {newGroupedFieldSet} to an empty ordered map.
1043- - Initialize {shouldInitiateDefer} to {false}.
1053+ - Initialize {groupDetailsMap} to an empty unordered map.
1054+ - For each {maskingTargets} and {targetSetDetails} in {targetSetDetailsMap}:
1055+ - Initialize {newGroupedFieldSet} to an empty ordered map.
1056+ - Let {keys} be the corresponding entry on {targetSetDetails}.
1057+ - Let {orderedResponseKeys} be the result of
1058+ {GetOrderedResponseKeys(maskingTargets, remainingFieldsByTarget)}.
1059+ - For each {responseKey} in {orderedResponseKeys}:
1060+ - If {keys} does not contain {responseKey}, continue to the next member of
1061+ {orderedResponseKeys}.
1062+ - Let {fieldGroup} be the Field Group record in {newGroupedFieldSet} for
1063+ {responseKey}; if no such record exists, create a new such record from the
1064+ empty list {fields} and the set of {parentTargets}.
1065+ - Let {targets} be the entry in {targetsByKeys} for {responseKey}.
10441066 - For each {target} in {targets}:
1067+ - Let {remainingFieldsForTarget} be the entry in {remainingFieldsByTarget}
1068+ for {target}.
1069+ - Let {nodes} be the list in {remainingFieldsByTarget} for {responseKey}.
1070+ - Remove the entry for {responseKey} from {remainingFieldsByTarget}.
1071+ - For each {node} of {nodes}:
1072+ - Let {fieldDetails} be a new Field Details record created from {node}
1073+ and {target}.
1074+ - Append {fieldDetails} to the {fields} entry on {fieldGroup}.
1075+ - Let {shouldInitiateDefer} be the corresponding entry on {targetSetDetails}.
1076+ - Initialize {details} to an empty unordered map.
1077+ - Set the entry for {groupedFieldSet} in {details} to {newGroupedFieldSet}.
1078+ - Set the corresponding entry in {details} to {shouldInitiateDefer}.
1079+ - Set the entry for {maskingTargets} in {groupDetailsMap} to {details}.
1080+ - Return {groupedFieldSet} and {groupDetailsMap}.
1081+
1082+ Note: entries are always added to Grouped Field Set records in the order in
1083+ which they appear for the first target. Field order for deferred grouped field
1084+ sets never alters the field order for the parent.
1085+
1086+ GetOrderedResponseKeys(targets, fieldsByTarget):
1087+
1088+ - Let {firstTarget} be the first entry in {targets}.
1089+ - Assert that {firstTarget} is defined.
1090+ - Let {firstFields} be the entry for {firstTarget} in {fieldsByTarget}.
1091+ - Assert that {firstFields} is defined.
1092+ - Let {responseKeys} be the keys of {firstFields}.
1093+ - Return {responseKeys}.
1094+
1095+ GetTargetSetDetails(targetsByKey, parentTargets):
1096+
1097+ - Initialize {keysWithParentTargets} to the empty set.
1098+ - Initialize {targetSetDetailsMap} to an empty unordered map.
1099+ - For each {responseKey} and {targets} in {targetsByKey}:
1100+ - Initialize {maskingTargets} to an empty set.
1101+ - For each {target} in {targets}:
1102+ - If {target} is not defined:
1103+ - Add {target} to {maskingTargets}.
1104+ - Continue to the next entry in {targets}.
1105+ - Let {ancestors} be the corresponding entry on {target}.
1106+ - For each {ancestor} of {ancestors}:
1107+ - If {targets} contains {ancestor}, continue to the next member of
1108+ {targets}.
1109+ - Add {target} to {maskingTargets}.
1110+ - If {IsSameSet(maskingTargets, parentTargets)} is {true}:
1111+ - Append {responseKey} to {keysWithParentTargets}.
1112+ - Continue to the next entry in {targetsByKey}.
1113+ - For each {key} in {targetSetDetailsMap}:
1114+ - If {IsSameSet(maskingTargets, key)} is {true}, let {targetSetDetails} be
1115+ the map in {targetSetDetailsMap} for {maskingTargets}.
1116+ - If {targetSetDetails} is defined:
1117+ - Let {keys} be the corresponding entry on {targetSetDetails}.
1118+ - Add {responseKey} to {keys}.
1119+ - Otherwise:
1120+ - Initialize {keys} to the empty set.
1121+ - Add {responseKey} to {keys}.
1122+ - Let {shouldInitiateDefer} be {false}.
1123+ - For each {target} in {maskingTargets}:
10451124 - If {parentTargets} does not contain {target}:
10461125 - Set {shouldInitiateDefer} equal to {true}.
1047- - Initialize {details} to an empty unordered map consisting of
1048- {newGroupedFieldSet} and {shouldInitiateDefer}.
1049- - Set the entry for {targets} in {groupDetailsMap} to {groupDetails}.
1050- - Let {fieldGroup} be the Field Group record in {newGroupedFieldSet} for
1051- {responseKey}; if no such record exists, create a new such record from the
1052- empty list {fields} and the set of {parentTargets}.
1053- - For each {target} in {targets}:
1054- - Let {fields} be the entry in {fieldsByTarget} for {target}.
1055- - Let {nodes} be the list in {fields} for {responseKey}.
1056- - For each {node} of {nodes}:
1057- - Let {fieldDetails} be a new Field Details record created from {node} and
1058- {target}.
1059- - Append {fieldDetails} to the {fields} entry on {fieldGroup}.
1060- - Return {groupedFieldSet} and {groupDetailsMap}.
1126+ - Create {newTargetSetDetails} as an map containing {keys} and
1127+ {shouldInitiateDefer}.
1128+ - Set the entry in {targetSetDetailsMap} for {maskingTargets} to
1129+ {newTargetSetDetails}.
1130+ - Return {keysWithParentTargets} and {targetSetDetailsMap}.
10611131
10621132IsSameSet(setA, setB):
10631133
0 commit comments