From 58f6b9506980adee30a0208a932d661a27a34995 Mon Sep 17 00:00:00 2001 From: Yaacov Rydzinski Date: Thu, 9 Nov 2023 14:07:49 +0200 Subject: [PATCH] deferred fields should not change ordering of non-deferred --- spec/Section 6 -- Execution.md | 73 +++++++++++++++++++++++++++++++--- 1 file changed, 67 insertions(+), 6 deletions(-) diff --git a/spec/Section 6 -- Execution.md b/spec/Section 6 -- Execution.md index 7de7b4dd9..18f529f65 100644 --- a/spec/Section 6 -- Execution.md +++ b/spec/Section 6 -- Execution.md @@ -1036,16 +1036,30 @@ BuildGroupedFieldSets(fieldsByTarget, targetsByKey, parentTargets) - If {parentTargets} is not provided, initialize it to a set containing the value {undefined}. +- Let {keysWithParentTargets} and {targetSetDetailsMap} be the result of + {GetTargetSetDetails(targetsByKey, parentTargets)}. +- Initialize {remainingFieldsByTarget} to an empty unordered map of ordered + maps. + - For each {target} and {fieldsForTarget} in {fieldsByTarget}: + - Initialize {remainingFieldsForTarget} to an empty ordered map. + - For each {responseKey} and {fieldList} in {fieldsForTarget}: + - Set {responseKey} on {remainingFieldsForTarget} to {fieldList}. - Initialize {groupedFieldSet} to an empty ordered map. -- Initialize {groupDetailsMap} to an empty unordered map. -- For each {responseKey} and {targets} in {targetsByKey}: - - If {IsSameSet(targets, parentTargets)} is {true}: +- If {keysWithParentTargets} is not empty: + - Let {orderedResponseKeys} be the result of + {GetOrderedResponseKeys(parentTargets, remainingFieldsByTarget)}. + - For each {responseKey} in {orderedResponseKeys}: + - If {keysWithParentTargets} does not contain {responseKey}, continue to the + next member of {orderedResponseKeys}. - Let {fieldGroup} be the Field Group record in {groupedFieldSet} for {responseKey}; if no such record exists, create a new such record from the empty list {fields} and the set of {parentTargets}. + - Let {targets} be the entry in {targetsByKeys} for {responseKey}. - For each {target} in {targets}: - - Let {fields} be the entry in {fieldsByTarget} for {target}. - - Let {nodes} be the list in {fields} for {responseKey}. + - Let {remainingFieldsForTarget} be the entry in {remainingFieldsByTarget} + for {target}. + - Let {nodes} be the list in {remainingFieldsByTarget} for {responseKey}. + - Remove the entry for {responseKey} from {remainingFieldsByTarget}. - For each {node} of {nodes}: - Let {fieldDetails} be a new Field Details record created from {node} and {target}. @@ -1076,6 +1090,44 @@ BuildGroupedFieldSets(fieldsByTarget, targetsByKey, parentTargets) - Initialize {details} to an empty unordered map. - Set the entry for {groupedFieldSet} in {details} to {newGroupedFieldSet}. - Set the corresponding entry in {details} to {shouldInitiateDefer}. + - Set the entry for {targets} in {groupDetailsMap} to {details}. +- Return {groupedFieldSet} and {groupDetailsMap}. + +Note: entries are always added to Grouped Field Set records in the order in +which they appear for the first target. Field order for deferred grouped field +sets never alters the field order for the parent. + +GetTargetSetDetails(targetsByKey, parentTargets): + +- Initialize {keysWithParentTargets} to the empty set. +- Initialize {targetSetDetailsMap} to an empty unordered map. +- For each {responseKey} and {targets} in {targetsByKey}: + - If {IsSameSet(targets, parentTargets)} is {true}: + - Append {responseKey} to {keysWithParentTargets}. + - Continue to the next entry in {targetsByKey}. + - For each {key} in {targetSetDetailsMap}: + - If {IsSameSet(targets, key)} is {true}, let {targetSetDetails} be the map + in {targetSetDetailsMap} for {targets}. + - If {targetSetDetails} is defined: + - Let {keys} be the corresponding entry on {targetSetDetails}. + - Add {responseKey} to {keys}. + - Otherwise: + - Initialize {keys} to the empty set. + - Add {responseKey} to {keys}. + - Let {shouldInitiateDefer} be {false}. + - For each {target} in {targets}: + - Let {remainingFieldsForTarget} be the entry in {remainingFieldsByTarget} + for {target}. + - Let {nodes} be the list in {remainingFieldsByTarget} for {responseKey}. + - Remove the entry for {responseKey} from {remainingFieldsByTarget}. + - For each {node} of {nodes}: + - Let {fieldDetails} be a new Field Details record created from {node} + and {target}. + - Append {fieldDetails} to the {fields} entry on {fieldGroup}. + - Let {shouldInitiateDefer} be the corresponding entry on {targetSetDetails}. + - Initialize {details} to an empty unordered map. + - Set the entry for {groupedFieldSet} in {details} to {newGroupedFieldSet}. + - Set the corresponding entry in {details} to {shouldInitiateDefer}. - Set the entry for {maskingTargets} in {groupDetailsMap} to {details}. - Return {groupedFieldSet} and {groupDetailsMap}. @@ -1116,7 +1168,7 @@ GetTargetSetDetails(targetsByKey, parentTargets): - Set {shouldInitiateDefer} equal to {true}. - Create {newTargetSetDetails} as an map containing {keys} and {shouldInitiateDefer}. - - Set the entry in {targetSetDetailsMap} for {maskingTargets} to + - Set the entry in {targetSetDetailsMap} for {targets} to {newTargetSetDetails}. - Return {keysWithParentTargets} and {targetSetDetailsMap}. @@ -1129,6 +1181,15 @@ IsSameSet(setA, setB): - Return {false}. - Return {true}. +GetOrderedResponseKeys(targets, fieldsByTarget): + +- Let {firstTarget} be the first entry in {targets}. +- Assert that {firstTarget} is defined. +- Let {firstFields} be the entry for {firstTarget} in {fieldsByTarget}. +- Assert that {firstFields} is defined. +- Let {responseKeys} be the keys of {firstFields}. +- Return {responseKeys}. + ## Executing Deferred Grouped Field Sets ExecuteDeferredGroupedFieldSets(objectType, objectValue, variableValues, path,