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