Skip to content

Commit e4be72f

Browse files
committed
Start thinking about tracking deferred
1 parent c58adce commit e4be72f

File tree

1 file changed

+51
-17
lines changed

1 file changed

+51
-17
lines changed

spec/Section 6 -- Execution.md

Lines changed: 51 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -319,10 +319,11 @@ CreateSourceEventStream(subscription, schema, variableValues, initialValue):
319319
- Let {groupedFieldSet} be the result of {CollectFields(subscriptionType,
320320
selectionSet, variableValues)}.
321321
- If {groupedFieldSet} does not have exactly one entry, raise a _request error_.
322-
- Let {fields} be the value of the first entry in {groupedFieldSet}.
323-
- Let {fieldName} be the name of the first entry in {fields}. Note: This value
324-
is unaffected if an alias is used.
325-
- Let {field} be the first entry in {fields}.
322+
- Let {fieldDetails} be the value of the first entry in {groupedFieldSet}.
323+
- Let {fieldDetail} be the first entry in {fieldDetails}.
324+
- Let {field} be the value for the key {field} in {fieldDetail}.
325+
- Let {fieldName} be the name of {field}. Note: This value is unaffected if an
326+
alias is used.
326327
- Let {argumentValues} be the result of {CoerceArgumentValues(subscriptionType,
327328
field, variableValues)}
328329
- Let {fieldStream} be the result of running
@@ -406,16 +407,32 @@ ExecuteSelectionSet(selectionSet, objectType, objectValue, variableValues):
406407
- Let {groupedFieldSet} be the result of {CollectFields(objectType,
407408
selectionSet, variableValues)}.
408409
- Initialize {resultMap} to an empty ordered map.
409-
- For each {groupedFieldSet} as {responseKey} and {fields}:
410-
- Let {fieldName} be the name of the first entry in {fields}. Note: This value
411-
is unaffected if an alias is used.
410+
- Let {deferred} be an empty list.
411+
- Let {streams} be an empty list.
412+
- For each {groupedFieldSet} as {responseKey} and {fieldDetails}:
413+
- Let {fieldDetail} be the first entry in {fieldDetails}.
414+
- Let {field} be the value for the key {field} in {fieldDetail}.
415+
- Let {fieldName} be the name of {field}. Note: This value is unaffected if an
416+
alias is used.
412417
- Let {fieldType} be the return type defined for the field {fieldName} of
413418
{objectType}.
414419
- If {fieldType} is defined:
415-
- Let {responseValue} be {ExecuteField(objectType, objectValue, fieldType,
416-
fields, variableValues)}.
417-
- Set {responseValue} as the value for {responseKey} in {resultMap}.
418-
- Return {resultMap}.
420+
- If {fieldType} is a list type and {field} provides the directive
421+
`@stream`, let {streamDirective} be that directive.
422+
- TODO: `@stream(if:)`
423+
- Add {fieldDetails} to {streams}.
424+
- Else if every entry in {fieldDetails} has {isDeferred} set to {true}:
425+
- Add {fieldDetails} to {deferred}.
426+
- Else:
427+
- Let {responseValue} be {ExecuteField(objectType, objectValue, fieldType,
428+
fieldDetails, variableValues)}.
429+
- Set {responseValue} as the value for {responseKey} in {resultMap}.
430+
- Let {pendings} be an empty list.
431+
- If {deferred} is not empty:
432+
- Add a single entry to {pendings}.
433+
- For each {stream} in {streams}:
434+
- Add {something} to {pendings}.
435+
- Return {resultMap} and {pendings}.
419436

420437
Note: {resultMap} is ordered by which fields appear first in the operation. This
421438
is explained in greater detail in the Field Collection section below.
@@ -559,8 +576,10 @@ The depth-first-search order of the field groups produced by {CollectFields()}
559576
is maintained through execution, ensuring that fields appear in the executed
560577
response in a stable and predictable order.
561578

562-
CollectFields(objectType, selectionSet, variableValues, visitedFragments):
579+
CollectFields(objectType, selectionSet, variableValues, isDeferred,
580+
visitedFragments):
563581

582+
- If {isDeferred} is not provided, initialize it to {false}.
564583
- If {visitedFragments} is not provided, initialize it to the empty set.
565584
- Initialize {groupedFields} to an empty ordered map of lists.
566585
- For each {selection} in {selectionSet}:
@@ -575,11 +594,13 @@ CollectFields(objectType, selectionSet, variableValues, visitedFragments):
575594
in {variableValues} with the value {true}, continue with the next
576595
{selection} in {selectionSet}.
577596
- If {selection} is a {Field}:
578-
- Let {responseKey} be the response key of {selection} (the alias if
579-
defined, otherwise the field name).
597+
- Let {field} be {selection}.
598+
- Let {responseKey} be the response key of {field} (the alias if defined,
599+
otherwise the field name).
580600
- Let {groupForResponseKey} be the list in {groupedFields} for
581601
{responseKey}; if no such list exists, create it as an empty list.
582-
- Append {selection} to the {groupForResponseKey}.
602+
- Let {fieldDetail} be an unordered map containing {field} and {isDeferred}.
603+
- Append {fieldDetail} to the {groupForResponseKey}.
583604
- If {selection} is a {FragmentSpread}:
584605
- Let {fragmentSpreadName} be the name of {selection}.
585606
- If {fragmentSpreadName} is in {visitedFragments}, continue with the next
@@ -592,10 +613,16 @@ CollectFields(objectType, selectionSet, variableValues, visitedFragments):
592613
- Let {fragmentType} be the type condition on {fragment}.
593614
- If {DoesFragmentTypeApply(objectType, fragmentType)} is false, continue
594615
with the next {selection} in {selectionSet}.
616+
- Let {fragmentIsDeferred} be {isDeferred}.
617+
- If {selection} provides the directive `@defer`, let {deferDirective} be
618+
that directive.
619+
- If {deferDirective}'s {if} argument is not {false} and is not a variable
620+
in {variableValues} with the value {false}:
621+
- Let {fragmentIsDeferred} be {true}.
595622
- Let {fragmentSelectionSet} be the top-level selection set of {fragment}.
596623
- Let {fragmentGroupedFieldSet} be the result of calling
597624
{CollectFields(objectType, fragmentSelectionSet, variableValues,
598-
visitedFragments)}.
625+
fragmentIsDeferred, visitedFragments)}.
599626
- For each {fragmentGroup} in {fragmentGroupedFieldSet}:
600627
- Let {responseKey} be the response key shared by all fields in
601628
{fragmentGroup}.
@@ -607,10 +634,16 @@ CollectFields(objectType, selectionSet, variableValues, visitedFragments):
607634
- If {fragmentType} is not {null} and {DoesFragmentTypeApply(objectType,
608635
fragmentType)} is false, continue with the next {selection} in
609636
{selectionSet}.
637+
- Let {fragmentIsDeferred} be {isDeferred}.
638+
- If {selection} provides the directive `@defer`, let {deferDirective} be
639+
that directive.
640+
- If {deferDirective}'s {if} argument is not {false} and is not a variable
641+
in {variableValues} with the value {false}:
642+
- Let {fragmentIsDeferred} be {true}.
610643
- Let {fragmentSelectionSet} be the top-level selection set of {selection}.
611644
- Let {fragmentGroupedFieldSet} be the result of calling
612645
{CollectFields(objectType, fragmentSelectionSet, variableValues,
613-
visitedFragments)}.
646+
fragmentIsDeferred, visitedFragments)}.
614647
- For each {fragmentGroup} in {fragmentGroupedFieldSet}:
615648
- Let {responseKey} be the response key shared by all fields in
616649
{fragmentGroup}.
@@ -740,6 +773,7 @@ field execution process continues recursively.
740773

741774
CompleteValue(fieldType, fields, result, variableValues):
742775

776+
- TODO: overhaul for incremental!
743777
- If the {fieldType} is a Non-Null type:
744778
- Let {innerType} be the inner type of {fieldType}.
745779
- Let {completedResult} be the result of calling {CompleteValue(innerType,

0 commit comments

Comments
 (0)