@@ -51,7 +51,7 @@ import {
5151 collectFields ,
5252 collectSubfields as _collectSubfields ,
5353} from './collectFields.js' ;
54- import { ResolveInfo } from './ResolveInfo .js' ;
54+ import { buildResolveInfo } from './execute .js' ;
5555import type { VariableValues } from './values.js' ;
5656import { getArgumentValues } from './values.js' ;
5757
@@ -199,13 +199,13 @@ export interface FormattedExecutionResult<
199199export class Executor {
200200 validatedExecutionArgs : ValidatedExecutionArgs ;
201201 finished : boolean ;
202- resolverAbortControllers : Set < AbortController > ;
202+ resolverAbortControllers : Map < Path , AbortController > ;
203203 collectedErrors : CollectedErrors ;
204204
205205 constructor ( validatedExecutionArgs : ValidatedExecutionArgs ) {
206206 this . validatedExecutionArgs = validatedExecutionArgs ;
207207 this . finished = false ;
208- this . resolverAbortControllers = new Set ( ) ;
208+ this . resolverAbortControllers = new Map ( ) ;
209209 this . collectedErrors = new CollectedErrors ( ) ;
210210 }
211211
@@ -306,10 +306,24 @@ export class Executor {
306306 const { resolverAbortControllers } = this ;
307307 const finishReason =
308308 reason ?? new Error ( 'Execution has already completed.' ) ;
309- for ( const abortController of resolverAbortControllers ) {
309+ for ( const abortController of resolverAbortControllers . values ( ) ) {
310310 abortController . abort ( finishReason ) ;
311311 }
312312 }
313+
314+ getAbortSignal ( path : Path ) : AbortSignal {
315+ const resolverAbortSignal = this . resolverAbortControllers . get ( path ) ?. signal ;
316+ if ( resolverAbortSignal !== undefined ) {
317+ return resolverAbortSignal ;
318+ }
319+ const abortController = new AbortController ( ) ;
320+ this . resolverAbortControllers . set ( path , abortController ) ;
321+ if ( this . finished ) {
322+ abortController . abort ( new Error ( 'Execution has already completed.' ) ) ;
323+ }
324+ return abortController . signal ;
325+ }
326+
313327 /**
314328 * Given a completed execution context and data, build the `{ errors, data }`
315329 * response defined by the "Response" section of the GraphQL specification.
@@ -469,26 +483,13 @@ export class Executor {
469483 const returnType = fieldDef . type ;
470484 const resolveFn = fieldDef . resolve ?? validatedExecutionArgs . fieldResolver ;
471485
472- const info = new ResolveInfo (
486+ const info = buildResolveInfo (
473487 validatedExecutionArgs ,
474488 fieldDef ,
475- fieldDetailsList ,
489+ toNodes ( fieldDetailsList ) ,
476490 parentType ,
477491 path ,
478- ( ) => {
479- /* c8 ignore next 3 */
480- if ( this . finished ) {
481- throw new Error ( 'Execution has already completed.' ) ;
482- }
483- const abortController = new AbortController ( ) ;
484- this . resolverAbortControllers . add ( abortController ) ;
485- return {
486- abortSignal : abortController . signal ,
487- unregister : ( ) => {
488- this . resolverAbortControllers . delete ( abortController ) ;
489- } ,
490- } ;
491- } ,
492+ ( ) => this . getAbortSignal ( path ) ,
492493 ) ;
493494
494495 // Get the resolve function, regardless of if its result is normal or abrupt (error).
@@ -533,20 +534,20 @@ export class Executor {
533534 // to take a second callback for the error case.
534535 return completed . then (
535536 ( resolved ) => {
536- info . unregisterAbortSignal ( ) ;
537+ this . resolverAbortControllers . delete ( path ) ;
537538 return resolved ;
538539 } ,
539540 ( rawError : unknown ) => {
540- info . unregisterAbortSignal ( ) ;
541+ this . resolverAbortControllers . delete ( path ) ;
541542 this . handleFieldError ( rawError , returnType , fieldDetailsList , path ) ;
542543 return null ;
543544 } ,
544545 ) ;
545546 }
546- info . unregisterAbortSignal ( ) ;
547+ this . resolverAbortControllers . delete ( path ) ;
547548 return completed ;
548549 } catch ( rawError ) {
549- info . unregisterAbortSignal ( ) ;
550+ this . resolverAbortControllers . delete ( path ) ;
550551 this . handleFieldError ( rawError , returnType , fieldDetailsList , path ) ;
551552 return null ;
552553 }
@@ -606,7 +607,7 @@ export class Executor {
606607 completeValue (
607608 returnType : GraphQLOutputType ,
608609 fieldDetailsList : FieldDetailsList ,
609- info : ResolveInfo ,
610+ info : GraphQLResolveInfo ,
610611 path : Path ,
611612 result : unknown ,
612613 ) : PromiseOrValue < unknown > {
@@ -690,7 +691,7 @@ export class Executor {
690691 async completePromisedValue (
691692 returnType : GraphQLOutputType ,
692693 fieldDetailsList : FieldDetailsList ,
693- info : ResolveInfo ,
694+ info : GraphQLResolveInfo ,
694695 path : Path ,
695696 result : Promise < unknown > ,
696697 isFieldValue ?: boolean ,
@@ -711,12 +712,12 @@ export class Executor {
711712 completed = await completed ;
712713 }
713714 if ( isFieldValue ) {
714- info . unregisterAbortSignal ( ) ;
715+ this . resolverAbortControllers . delete ( path ) ;
715716 }
716717 return completed ;
717718 } catch ( rawError ) {
718719 if ( isFieldValue ) {
719- info . unregisterAbortSignal ( ) ;
720+ this . resolverAbortControllers . delete ( path ) ;
720721 }
721722 this . handleFieldError ( rawError , returnType , fieldDetailsList , path ) ;
722723 return null ;
@@ -730,7 +731,7 @@ export class Executor {
730731 async completeAsyncIterableValue (
731732 itemType : GraphQLOutputType ,
732733 fieldDetailsList : FieldDetailsList ,
733- info : ResolveInfo ,
734+ info : GraphQLResolveInfo ,
734735 path : Path ,
735736 items : AsyncIterable < unknown > ,
736737 ) : Promise < ReadonlyArray < unknown > > {
@@ -806,7 +807,7 @@ export class Executor {
806807 completeListValue (
807808 returnType : GraphQLList < GraphQLOutputType > ,
808809 fieldDetailsList : FieldDetailsList ,
809- info : ResolveInfo ,
810+ info : GraphQLResolveInfo ,
810811 path : Path ,
811812 result : unknown ,
812813 ) : PromiseOrValue < ReadonlyArray < unknown > > {
@@ -840,7 +841,7 @@ export class Executor {
840841 completeIterableValue (
841842 itemType : GraphQLOutputType ,
842843 fieldDetailsList : FieldDetailsList ,
843- info : ResolveInfo ,
844+ info : GraphQLResolveInfo ,
844845 path : Path ,
845846 items : Iterable < unknown > ,
846847 ) : PromiseOrValue < ReadonlyArray < unknown > > {
@@ -905,7 +906,7 @@ export class Executor {
905906 completedResults : Array < unknown > ,
906907 itemType : GraphQLOutputType ,
907908 fieldDetailsList : FieldDetailsList ,
908- info : ResolveInfo ,
909+ info : GraphQLResolveInfo ,
909910 itemPath : Path ,
910911 ) : boolean {
911912 try {
@@ -946,7 +947,7 @@ export class Executor {
946947 item : Promise < unknown > ,
947948 itemType : GraphQLOutputType ,
948949 fieldDetailsList : FieldDetailsList ,
949- info : ResolveInfo ,
950+ info : GraphQLResolveInfo ,
950951 itemPath : Path ,
951952 ) : Promise < unknown > {
952953 try {
0 commit comments