@@ -293,14 +293,15 @@ function buildDataResponse(
293293 futures : ReadonlyArray < Future > ,
294294 cancellableStreams : Set < StreamRecord > ,
295295) : ExecutionResult | ExperimentalIncrementalExecutionResults {
296- const filteredFutures = filterFutures ( errorPaths , futures ) ;
296+ const filteredFutures = filterFutures ( undefined , errorPaths , futures ) ;
297297 if ( filteredFutures . length > 0 ) {
298298 return buildIncrementalResponse ( data , errors , futures , cancellableStreams ) ;
299299 }
300300 return errors . length > 0 ? { errors, data } : { data } ;
301301}
302302
303303function filterFutures (
304+ initialPath : Path | undefined ,
304305 errorPaths : ReadonlySet < Path | undefined > ,
305306 futures : ReadonlyArray < Future > ,
306307) : ReadonlyArray < Future > {
@@ -310,19 +311,33 @@ function filterFutures(
310311
311312 const filteredFutures : Array < Future > = [ ] ;
312313 for ( const future of futures ) {
313- let currentPath = isDeferredGroupedFieldSetRecord ( future )
314+ let currentPath : Path | undefined = isDeferredGroupedFieldSetRecord ( future )
314315 ? future . path
315316 : future . streamRecord . path ;
316- while ( currentPath !== undefined ) {
317+
318+ if ( errorPaths . has ( currentPath ) ) {
319+ continue ;
320+ }
321+
322+ const paths : Array < Path | undefined > = [ currentPath ] ;
323+ let filtered = false ;
324+ while ( currentPath !== initialPath ) {
325+ // Because currentPath leads to initialPath or is undefined, and the
326+ // loop will exit if initialPath is undefined, currentPath must be
327+ // defined.
328+ // TODO: Consider, however, adding an invariant.
329+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
330+ currentPath = currentPath ! . prev ;
317331 if ( errorPaths . has ( currentPath ) ) {
332+ filtered = true ;
318333 break ;
319334 }
320- currentPath = currentPath . prev ;
335+ paths . push ( currentPath ) ;
321336 }
322- if ( errorPaths . has ( currentPath ) ) {
323- continue ;
337+
338+ if ( ! filtered ) {
339+ filteredFutures . push ( future ) ;
324340 }
325- filteredFutures . push ( future ) ;
326341 }
327342
328343 return filteredFutures ;
@@ -1966,7 +1981,7 @@ function executeDeferredGroupedFieldSet(
19661981 deferredFragmentRecords,
19671982 path : pathToArray ( path ) ,
19681983 data : resolved ,
1969- futures : filterFutures ( errorPaths , futures ) ,
1984+ futures : filterFutures ( path , errorPaths , futures ) ,
19701985 errors,
19711986 } ) ,
19721987 ( error ) => {
@@ -1985,7 +2000,7 @@ function executeDeferredGroupedFieldSet(
19852000 deferredFragmentRecords,
19862001 path : pathToArray ( path ) ,
19872002 data,
1988- futures : filterFutures ( errorPaths , futures ) ,
2003+ futures : filterFutures ( path , errorPaths , futures ) ,
19892004 errors,
19902005 } ;
19912006}
@@ -2015,6 +2030,7 @@ function firstSyncStreamItems(
20152030
20162031 const firstStreamItems = new StreamItemsRecord ( {
20172032 streamRecord,
2033+ itemPath : initialPath ,
20182034 executor : ( incrementalContext ) =>
20192035 Promise . resolve ( ) . then ( ( ) => {
20202036 const firstResult = executor (
@@ -2033,6 +2049,7 @@ function firstSyncStreamItems(
20332049
20342050 const nextStreamItems = new StreamItemsRecord ( {
20352051 streamRecord,
2052+ itemPath : currentPath ,
20362053 executor : ( nextIncrementalContext ) =>
20372054 executor ( currentPath , item , nextIncrementalContext ) ,
20382055 } ) ;
@@ -2065,8 +2082,10 @@ function firstAsyncStreamItems(
20652082 incrementalContext : IncrementalContext ,
20662083 ) => PromiseOrValue < StreamItemsResult > ,
20672084) : StreamItemsRecord {
2085+ const initialPath = addPath ( path , initialIndex , undefined ) ;
20682086 const firstStreamItems : StreamItemsRecord = new StreamItemsRecord ( {
20692087 streamRecord,
2088+ itemPath : initialPath ,
20702089 executor : ( incrementalContext ) =>
20712090 Promise . resolve ( ) . then ( ( ) =>
20722091 getNextAsyncStreamItemsResult (
@@ -2120,7 +2139,8 @@ async function getNextAsyncStreamItemsResult(
21202139 const nextStreamItems : StreamItemsRecord = nextAsyncStreamItems (
21212140 streamRecord ,
21222141 path ,
2123- index + 1 ,
2142+ itemPath ,
2143+ index ,
21242144 nodes ,
21252145 asyncIterator ,
21262146 executor ,
@@ -2133,6 +2153,7 @@ async function getNextAsyncStreamItemsResult(
21332153function nextAsyncStreamItems (
21342154 streamRecord : StreamRecord ,
21352155 path : Path ,
2156+ initialPath : Path ,
21362157 initialIndex : number ,
21372158 nodes : ReadonlyArray < FieldNode > ,
21382159 asyncIterator : AsyncIterator < unknown > ,
@@ -2144,13 +2165,14 @@ function nextAsyncStreamItems(
21442165) : StreamItemsRecord {
21452166 const nextStreamItems : StreamItemsRecord = new StreamItemsRecord ( {
21462167 streamRecord,
2168+ itemPath : initialPath ,
21472169 executor : ( incrementalContext ) =>
21482170 Promise . resolve ( ) . then ( ( ) =>
21492171 getNextAsyncStreamItemsResult (
21502172 streamRecord ,
21512173 nextStreamItems ,
21522174 path ,
2153- initialIndex ,
2175+ initialIndex + 1 ,
21542176 incrementalContext ,
21552177 nodes ,
21562178 asyncIterator ,
@@ -2171,7 +2193,7 @@ function completeStreamItems(
21712193 info : GraphQLResolveInfo ,
21722194 itemType : GraphQLOutputType ,
21732195) : PromiseOrValue < StreamItemsResult > {
2174- const { errors, errorPaths, futures } = incrementalContext ;
2196+ const { path , errors, errorPaths, futures } = incrementalContext ;
21752197 if ( isPromise ( item ) ) {
21762198 return completePromisedValue (
21772199 exeContext ,
@@ -2186,7 +2208,7 @@ function completeStreamItems(
21862208 ( resolvedItem ) => ( {
21872209 streamRecord,
21882210 items : [ resolvedItem ] ,
2189- futures : filterFutures ( errorPaths , futures ) ,
2211+ futures : filterFutures ( path , errorPaths , futures ) ,
21902212 errors,
21912213 } ) ,
21922214 ( error ) => {
@@ -2250,7 +2272,7 @@ function completeStreamItems(
22502272 ( resolvedItem ) => ( {
22512273 streamRecord,
22522274 items : [ resolvedItem ] ,
2253- futures : filterFutures ( errorPaths , futures ) ,
2275+ futures : filterFutures ( path , errorPaths , futures ) ,
22542276 errors,
22552277 } ) ,
22562278 ( error ) => {
@@ -2267,7 +2289,7 @@ function completeStreamItems(
22672289 return {
22682290 streamRecord,
22692291 items : [ completedItem ] ,
2270- futures : filterFutures ( errorPaths , futures ) ,
2292+ futures : filterFutures ( path , errorPaths , futures ) ,
22712293 errors,
22722294 } ;
22732295}
0 commit comments