1
1
// @flow strict
2
2
3
3
import arrayFrom from '../polyfills/arrayFrom' ;
4
+ import { SYMBOL_ASYNC_ITERATOR } from '../polyfills/symbols' ;
4
5
5
6
import type { Path } from '../jsutils/Path' ;
6
7
import type { ObjMap } from '../jsutils/ObjMap' ;
@@ -10,6 +11,7 @@ import memoize3 from '../jsutils/memoize3';
10
11
import invariant from '../jsutils/invariant' ;
11
12
import devAssert from '../jsutils/devAssert' ;
12
13
import isPromise from '../jsutils/isPromise' ;
14
+ import isAsyncIterable from '../jsutils/isAsyncIterable' ;
13
15
import isObjectLike from '../jsutils/isObjectLike' ;
14
16
import isCollection from '../jsutils/isCollection' ;
15
17
import promiseReduce from '../jsutils/promiseReduce' ;
@@ -916,6 +918,56 @@ function completeValue(
916
918
);
917
919
}
918
920
921
+ /**
922
+ * Complete a async iterable value by completing each item in the list with
923
+ * the inner type
924
+ */
925
+
926
+ function completeAsyncIterableValue (
927
+ exeContext : ExecutionContext ,
928
+ returnType : GraphQLList < GraphQLOutputType > ,
929
+ fieldNodes: $ReadOnlyArray< FieldNode > ,
930
+ info: GraphQLResolveInfo,
931
+ path: Path,
932
+ result: AsyncIterable< mixed > ,
933
+ ): Promise< $ReadOnlyArray < mixed > > {
934
+ // $FlowFixMe
935
+ const iteratorMethod = result [ SYMBOL_ASYNC_ITERATOR ] ;
936
+ const iterator = iteratorMethod . call ( result ) ;
937
+
938
+ const completedResults = [ ] ;
939
+ let index = 0 ;
940
+
941
+ const itemType = returnType . ofType ;
942
+
943
+ const handleNext = ( ) => {
944
+ const fieldPath = addPath ( path , index ) ;
945
+ return iterator . next ( ) . then (
946
+ ( { value, done } ) => {
947
+ if ( done ) {
948
+ return ;
949
+ }
950
+ completedResults . push (
951
+ completeValue (
952
+ exeContext ,
953
+ itemType ,
954
+ fieldNodes ,
955
+ info ,
956
+ fieldPath ,
957
+ value ,
958
+ ) ,
959
+ ) ;
960
+ index ++ ;
961
+ return handleNext ( ) ;
962
+ } ,
963
+ ( error ) =>
964
+ handleFieldError ( error , fieldNodes , fieldPath , itemType , exeContext ) ,
965
+ ) ;
966
+ } ;
967
+
968
+ return handleNext ( ) . then ( ( ) => completedResults ) ;
969
+ }
970
+
919
971
/**
920
972
* Complete a list value by completing each item in the list with the
921
973
* inner type
@@ -928,6 +980,17 @@ function completeListValue(
928
980
path: Path,
929
981
result: mixed,
930
982
): PromiseOrValue< $ReadOnlyArray < mixed > > {
983
+ if ( isAsyncIterable ( result ) ) {
984
+ return completeAsyncIterableValue (
985
+ exeContext ,
986
+ returnType ,
987
+ fieldNodes ,
988
+ info ,
989
+ path ,
990
+ result ,
991
+ ) ;
992
+ }
993
+
931
994
if (!isCollection(result)) {
932
995
throw new GraphQLError (
933
996
`Expected Iterable, but did not find one for field "${ info . parentType . name } .${ info . fieldName } ".` ,
0 commit comments