@@ -121,7 +121,7 @@ export interface ExecutionContext {
121
121
typeResolver : GraphQLTypeResolver < any , any > ;
122
122
subscribeFieldResolver : GraphQLFieldResolver < any , any > ;
123
123
errors : Array < GraphQLError > ;
124
- subsequentPayloads : Array < AsyncPayloadRecord > ;
124
+ subsequentPayloads : Set < AsyncPayloadRecord > ;
125
125
}
126
126
127
127
/**
@@ -350,7 +350,7 @@ function executeImpl(
350
350
return result . then (
351
351
( data ) => {
352
352
const initialResult = buildResponse ( data , exeContext . errors ) ;
353
- if ( exeContext . subsequentPayloads . length > 0 ) {
353
+ if ( exeContext . subsequentPayloads . size > 0 ) {
354
354
return {
355
355
initialResult : {
356
356
...initialResult ,
@@ -368,7 +368,7 @@ function executeImpl(
368
368
) ;
369
369
}
370
370
const initialResult = buildResponse ( result , exeContext . errors ) ;
371
- if ( exeContext . subsequentPayloads . length > 0 ) {
371
+ if ( exeContext . subsequentPayloads . size > 0 ) {
372
372
return {
373
373
initialResult : {
374
374
...initialResult ,
@@ -496,7 +496,7 @@ export function buildExecutionContext(
496
496
fieldResolver : fieldResolver ?? defaultFieldResolver ,
497
497
typeResolver : typeResolver ?? defaultTypeResolver ,
498
498
subscribeFieldResolver : subscribeFieldResolver ?? defaultFieldResolver ,
499
- subsequentPayloads : [ ] ,
499
+ subsequentPayloads : new Set ( ) ,
500
500
errors : [ ] ,
501
501
} ;
502
502
}
@@ -1808,7 +1808,7 @@ function executeDeferredFragment(
1808
1808
promiseOrData = null ;
1809
1809
}
1810
1810
asyncPayloadRecord . addData ( promiseOrData ) ;
1811
- exeContext . subsequentPayloads . push ( asyncPayloadRecord ) ;
1811
+ exeContext . subsequentPayloads . add ( asyncPayloadRecord ) ;
1812
1812
}
1813
1813
1814
1814
function executeStreamField (
@@ -1873,7 +1873,7 @@ function executeStreamField(
1873
1873
} catch ( error ) {
1874
1874
asyncPayloadRecord . errors . push ( error ) ;
1875
1875
asyncPayloadRecord . addItems ( null ) ;
1876
- exeContext . subsequentPayloads . push ( asyncPayloadRecord ) ;
1876
+ exeContext . subsequentPayloads . add ( asyncPayloadRecord ) ;
1877
1877
return asyncPayloadRecord ;
1878
1878
}
1879
1879
@@ -1890,7 +1890,7 @@ function executeStreamField(
1890
1890
}
1891
1891
1892
1892
asyncPayloadRecord . addItems ( completedItems ) ;
1893
- exeContext . subsequentPayloads . push ( asyncPayloadRecord ) ;
1893
+ exeContext . subsequentPayloads . add ( asyncPayloadRecord ) ;
1894
1894
return asyncPayloadRecord ;
1895
1895
}
1896
1896
@@ -1992,7 +1992,7 @@ async function executeStreamIterator(
1992
1992
} ,
1993
1993
) ,
1994
1994
) ;
1995
- subsequentPayloads . push ( asyncPayloadRecord ) ;
1995
+ subsequentPayloads . add ( asyncPayloadRecord ) ;
1996
1996
try {
1997
1997
// eslint-disable-next-line no-await-in-loop
1998
1998
const { done } = await dataPromise ;
@@ -2015,7 +2015,7 @@ function yieldSubsequentPayloads(
2015
2015
async function race ( ) : Promise <
2016
2016
IteratorResult < SubsequentIncrementalExecutionResult >
2017
2017
> {
2018
- if ( exeContext . subsequentPayloads . length === 0 ) {
2018
+ if ( exeContext . subsequentPayloads . size === 0 ) {
2019
2019
// async iterable resolver just finished and no more pending payloads
2020
2020
return {
2021
2021
value : {
@@ -2041,17 +2041,16 @@ function yieldSubsequentPayloads(
2041
2041
} ,
2042
2042
) ;
2043
2043
2044
- if ( exeContext . subsequentPayloads . length === 0 ) {
2044
+ if ( exeContext . subsequentPayloads . size === 0 ) {
2045
2045
// a different call to next has exhausted all payloads
2046
2046
return { value : undefined , done : true } ;
2047
2047
}
2048
- const index = exeContext . subsequentPayloads . indexOf ( asyncPayloadRecord ) ;
2049
- if ( index === - 1 ) {
2048
+ if ( ! exeContext . subsequentPayloads . has ( asyncPayloadRecord ) ) {
2050
2049
// a different call to next has consumed this payload
2051
2050
return race ( ) ;
2052
2051
}
2053
2052
2054
- exeContext . subsequentPayloads . splice ( index , 1 ) ;
2053
+ exeContext . subsequentPayloads . delete ( asyncPayloadRecord ) ;
2055
2054
2056
2055
const incrementalResult : IncrementalResult = { } ;
2057
2056
if ( isStreamPayload ( asyncPayloadRecord ) ) {
@@ -2079,47 +2078,46 @@ function yieldSubsequentPayloads(
2079
2078
return {
2080
2079
value : {
2081
2080
incremental : [ incrementalResult ] ,
2082
- hasNext : exeContext . subsequentPayloads . length > 0 ,
2081
+ hasNext : exeContext . subsequentPayloads . size > 0 ,
2083
2082
} ,
2084
2083
done : false ,
2085
2084
} ;
2086
2085
}
2087
2086
2087
+ function returnStreamIterators ( ) {
2088
+ const promises : Array < Promise < IteratorResult < unknown > > > = [ ] ;
2089
+ exeContext . subsequentPayloads . forEach ( ( asyncPayloadRecord ) => {
2090
+ if (
2091
+ isStreamPayload ( asyncPayloadRecord ) &&
2092
+ asyncPayloadRecord . iterator ?. return
2093
+ ) {
2094
+ promises . push ( asyncPayloadRecord . iterator . return ( ) ) ;
2095
+ }
2096
+ } ) ;
2097
+ return Promise . all ( promises ) ;
2098
+ }
2099
+
2088
2100
return {
2089
2101
[ Symbol . asyncIterator ] ( ) {
2090
2102
return this ;
2091
2103
} ,
2092
2104
next : ( ) => {
2093
- if ( exeContext . subsequentPayloads . length === 0 || isDone ) {
2105
+ if ( exeContext . subsequentPayloads . size === 0 || isDone ) {
2094
2106
return Promise . resolve ( { value : undefined , done : true } ) ;
2095
2107
}
2096
2108
return race ( ) ;
2097
2109
} ,
2098
2110
async return ( ) : Promise <
2099
2111
IteratorResult < SubsequentIncrementalExecutionResult , void >
2100
2112
> {
2101
- await Promise . all (
2102
- exeContext . subsequentPayloads . map ( ( asyncPayloadRecord ) => {
2103
- if ( isStreamPayload ( asyncPayloadRecord ) ) {
2104
- return asyncPayloadRecord . iterator ?. return ?.( ) ;
2105
- }
2106
- return undefined ;
2107
- } ) ,
2108
- ) ;
2113
+ await returnStreamIterators ( ) ;
2109
2114
isDone = true ;
2110
2115
return { value : undefined , done : true } ;
2111
2116
} ,
2112
2117
async throw (
2113
2118
error ?: unknown ,
2114
2119
) : Promise < IteratorResult < SubsequentIncrementalExecutionResult , void > > {
2115
- await Promise . all (
2116
- exeContext . subsequentPayloads . map ( ( asyncPayloadRecord ) => {
2117
- if ( isStreamPayload ( asyncPayloadRecord ) ) {
2118
- return asyncPayloadRecord . iterator ?. return ?.( ) ;
2119
- }
2120
- return undefined ;
2121
- } ) ,
2122
- ) ;
2120
+ await returnStreamIterators ( ) ;
2123
2121
isDone = true ;
2124
2122
return Promise . reject ( error ) ;
2125
2123
} ,
0 commit comments