@@ -545,6 +545,22 @@ serial):
545
545
- Let {hasNext} be {true}.
546
546
- Let {update} be an unordered map consisting of {errors}, {data},
547
547
{pending}, and {hasNext}.
548
+ - Otherwise, if {result} incrementally completes a Stream:
549
+ - Let {stream}, {items}, {errors}, {newPendingResults}, and {futures} be
550
+ the corresponding entries on {result}.
551
+ - Let {id} be the entry on {ids} for {stream}.
552
+ - If {items} is not defined or is {null}:
553
+ - Let {completedEntry} be an unordered map containing {id}.
554
+ - If {items} is {null}, set the corresponding entry on {completedEntry}
555
+ to {errors}.
556
+ - Append {completedEntry} to {completed}.
557
+ - Remove {stream} from {pendingResults}.
558
+ - Let {update} be an unordered map consisting of {completed}.
559
+ - Otherwise:
560
+ - Let {incrementalEntry} be an unordered map containing {id}, {items},
561
+ and {errors}.
562
+ - Append {incrementalEntry} to {incremental}.
563
+ - Let {update} be an unordered map consisting of {incremental}.
548
564
- Otherwise, {result} incrementally completes Deferred Fragments:
549
565
- Let {deferredFragments} be those Deferred Fragments.
550
566
- If {data} is {null}:
@@ -582,13 +598,19 @@ serial):
582
598
- Append {completedEntry} to {completed}.
583
599
- Remove {deferredFragment} from {pendingResults}.
584
600
- For each {newPendingResult} in {newPendingResults}:
585
- - Let {parent} be the corresponding entry on {newPendingResult}.
586
- - Add {newPendingResult} to {pendingResults} as a new node directed from
587
- {parent}, if it is also present in {pendingResults}.
601
+ - If {newPendingResult} represents a Stream:
602
+ - Add {newPendingResult} to {pendingResults}.
603
+ - Otherwise:
604
+ - Let {parent} be the corresponding entry on {newPendingResult}.
605
+ - Add {newPendingResult} to {pendingResults} as a new node directed from
606
+ {parent}, if it is also present in {pendingResults}.
588
607
- For each {future} of {futures}:
589
- - Let {deferredFragments} be the Deferred Fragments completed by {future}.
590
- - Add {future} to {pendingResults} as a node directed from each of
591
- {deferredFragments}.
608
+ - If {future} incrementally completes a Stream:
609
+ - If {future} has not been initiated, initiate {future}.
610
+ - Otherwise:
611
+ - Let {deferredFragments} be the Deferred Fragments completed by {future}.
612
+ - Add {future} to {pendingResults} as a node directed from each of
613
+ {deferredFragments}.
592
614
- While any root nodes in {pendingResults} representing Deferred Fragments
593
615
contain no direct child Futures, remove those root nodes from
594
616
{pendingResults}.
@@ -1025,8 +1047,37 @@ pendingResults, path, deferUsageSet, deferMap):
1025
1047
- Initialize {newPendingResults} and {futures} to empty lists.
1026
1048
- Let {fieldDetails} be the first entry in {fieldDetailsList}.
1027
1049
- Let {field} be the corresponding entry on {fieldDetails}.
1050
+ - If {field} provides the directive ` @stream ` and its {if} argument is not
1051
+ {false} and is not a variable in {variableValues} with the value {false} and
1052
+ {innerType} is the outermost inner type of the list type defined for
1053
+ {fieldDetailsList}:
1054
+ - Let {streamDirective} be that directive.
1055
+ - If this execution is for a subscription operation, raise a _ field error_ .
1056
+ - Let {initialCount} be the value or variable provided to {streamDirective}'s
1057
+ {initialCount} argument.
1058
+ - If {initialCount} is less than zero, raise a _ field error_ .
1059
+ - Let {label} be the value or variable provided to {streamDirective}'s {label}
1060
+ argument.
1061
+ - Let {iterator} be an iterator for {result}.
1028
1062
- Let {items} be an empty list.
1029
- - For each {resultItem} of {result}:
1063
+ - Let {index} be zero.
1064
+ - While {result} is not closed:
1065
+ - If {streamDirective} is defined and {index} is greater than or equal to
1066
+ {initialCount}:
1067
+ - Let {stream} be an unordered map containing {path} and {label}.
1068
+ - Let {streamFieldDetails} be the result of
1069
+ {GetStreamFieldDetailsList(fieldDetailsList)}.
1070
+ - Let {future} represent the future execution of {ExecuteStreamField(stream,
1071
+ iterator, streamFieldDetailsList, index, innerType, variableValues,
1072
+ pendingResults)}.
1073
+ - If early execution is desired, following any implementation specific
1074
+ deferral, whichever occurs first.
1075
+ - Append {future} to {futures}.
1076
+ - Return {items}, {newPendingResults}, and {futures}.
1077
+ - Wait for the next item from {result} via the {iterator}.
1078
+ - If an item is not retrieved because of an error, raise a _ field error_ .
1079
+ - Let {item} be the item retrieved from {result}.
1080
+ - Let {itemPath} be {path} with {index} appended.
1030
1081
- Let {completedItem}, {itemNewPendingResults}, and {itemFutures} be the
1031
1082
result of calling {CompleteValue(innerType, fieldDetailsList, item,
1032
1083
variableValues, pendingResults, itemPath)}.
@@ -1035,6 +1086,42 @@ pendingResults, path, deferUsageSet, deferMap):
1035
1086
{newPendingResults}, and {futures}, respectively.
1036
1087
- Return {items}, {newPendingResults}, and {futures}.
1037
1088
1089
+ GetStreamFieldDetailsList(fieldDetailsList):
1090
+
1091
+ - Let {streamFields} be an empty list.
1092
+ - For each {fieldDetails} in {fieldDetailsList}:
1093
+ - Let {field} be the corresponding entry on {fieldDetails}.
1094
+ - Let {newFieldDetails} be a new Field Details record created from {field}.
1095
+ - Append {newFieldDetails} to {streamFields}.
1096
+ - Return {streamFields}.
1097
+
1098
+ #### Execute Stream Field
1099
+
1100
+ ExecuteStreamField(stream, iterator, fieldDetailsList, index, innerType,
1101
+ variableValues, pendingResults):
1102
+
1103
+ - Let {path} be the corresponding entry on {stream}.
1104
+ - Let {itemPath} be {path} with {index} appended.
1105
+ - Wait for the next item from {iterator}.
1106
+ - If {iterator} is closed, complete this data stream and return.
1107
+ - Let {item} be the next item retrieved via {iterator}.
1108
+ - Let {nextIndex} be {index} plus one.
1109
+ - Let {completedItem}, {newPendingResults}, and {futures} be the result of
1110
+ {CompleteValue(innerType, fields, item, variableValues, itemPath)}.
1111
+ - Initialize {items} to an empty list.
1112
+ - Append {completedItem} to {items}.
1113
+ - Let {errors} be the list of all _ field error_ raised while completing the
1114
+ item.
1115
+ - Let {future} represent the future execution of {ExecuteStreamField(stream,
1116
+ path, iterator, fieldDetailsList, nextIndex, innerType, variableValues,
1117
+ pendingResults)}.
1118
+ - If early execution of streamed fields is desired:
1119
+ - Following any implementation specific deferral of further execution,
1120
+ initiate {future}.
1121
+ - Append {future} to {futures}.
1122
+ - Return an unordered map containing {items}, {errors}, {newPendingResults}, and
1123
+ {futures}.
1124
+
1038
1125
** Coercing Results**
1039
1126
1040
1127
The primary purpose of value completion is to ensure that the values returned by
0 commit comments