@@ -319,10 +319,11 @@ CreateSourceEventStream(subscription, schema, variableValues, initialValue):
319
319
- Let {groupedFieldSet} be the result of {CollectFields(subscriptionType,
320
320
selectionSet, variableValues)}.
321
321
- 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.
326
327
- Let {argumentValues} be the result of {CoerceArgumentValues(subscriptionType,
327
328
field, variableValues)}
328
329
- Let {fieldStream} be the result of running
@@ -406,16 +407,32 @@ ExecuteSelectionSet(selectionSet, objectType, objectValue, variableValues):
406
407
- Let {groupedFieldSet} be the result of {CollectFields(objectType,
407
408
selectionSet, variableValues)}.
408
409
- 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.
412
417
- Let {fieldType} be the return type defined for the field {fieldName} of
413
418
{objectType}.
414
419
- 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}.
419
436
420
437
Note: {resultMap} is ordered by which fields appear first in the operation. This
421
438
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()}
559
576
is maintained through execution, ensuring that fields appear in the executed
560
577
response in a stable and predictable order.
561
578
562
- CollectFields(objectType, selectionSet, variableValues, visitedFragments):
579
+ CollectFields(objectType, selectionSet, variableValues, isDeferred,
580
+ visitedFragments):
563
581
582
+ - If {isDeferred} is not provided, initialize it to {false}.
564
583
- If {visitedFragments} is not provided, initialize it to the empty set.
565
584
- Initialize {groupedFields} to an empty ordered map of lists.
566
585
- For each {selection} in {selectionSet}:
@@ -575,11 +594,13 @@ CollectFields(objectType, selectionSet, variableValues, visitedFragments):
575
594
in {variableValues} with the value {true}, continue with the next
576
595
{selection} in {selectionSet}.
577
596
- 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).
580
600
- Let {groupForResponseKey} be the list in {groupedFields} for
581
601
{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}.
583
604
- If {selection} is a {FragmentSpread}:
584
605
- Let {fragmentSpreadName} be the name of {selection}.
585
606
- If {fragmentSpreadName} is in {visitedFragments}, continue with the next
@@ -592,10 +613,16 @@ CollectFields(objectType, selectionSet, variableValues, visitedFragments):
592
613
- Let {fragmentType} be the type condition on {fragment}.
593
614
- If {DoesFragmentTypeApply(objectType, fragmentType)} is false, continue
594
615
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}.
595
622
- Let {fragmentSelectionSet} be the top-level selection set of {fragment}.
596
623
- Let {fragmentGroupedFieldSet} be the result of calling
597
624
{CollectFields(objectType, fragmentSelectionSet, variableValues,
598
- visitedFragments)}.
625
+ fragmentIsDeferred, visitedFragments)}.
599
626
- For each {fragmentGroup} in {fragmentGroupedFieldSet}:
600
627
- Let {responseKey} be the response key shared by all fields in
601
628
{fragmentGroup}.
@@ -607,10 +634,16 @@ CollectFields(objectType, selectionSet, variableValues, visitedFragments):
607
634
- If {fragmentType} is not {null} and {DoesFragmentTypeApply(objectType,
608
635
fragmentType)} is false, continue with the next {selection} in
609
636
{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}.
610
643
- Let {fragmentSelectionSet} be the top-level selection set of {selection}.
611
644
- Let {fragmentGroupedFieldSet} be the result of calling
612
645
{CollectFields(objectType, fragmentSelectionSet, variableValues,
613
- visitedFragments)}.
646
+ fragmentIsDeferred, visitedFragments)}.
614
647
- For each {fragmentGroup} in {fragmentGroupedFieldSet}:
615
648
- Let {responseKey} be the response key shared by all fields in
616
649
{fragmentGroup}.
@@ -740,6 +773,7 @@ field execution process continues recursively.
740
773
741
774
CompleteValue(fieldType, fields, result, variableValues):
742
775
776
+ - TODO: overhaul for incremental!
743
777
- If the {fieldType} is a Non-Null type:
744
778
- Let {innerType} be the inner type of {fieldType}.
745
779
- Let {completedResult} be the result of calling {CompleteValue(innerType,
0 commit comments