@@ -53,9 +53,9 @@ import {
5353 collectFields ,
5454 collectSubfields as _collectSubfields ,
5555} from './collectFields.js' ;
56+ import { buildResolveInfo } from './execute.js' ;
5657import type { StreamUsage } from './getStreamUsage.js' ;
5758import { getStreamUsage as _getStreamUsage } from './getStreamUsage.js' ;
58- import { ResolveInfo } from './ResolveInfo.js' ;
5959import { returnIteratorCatchingErrors } from './returnIteratorCatchingErrors.js' ;
6060import type { VariableValues } from './values.js' ;
6161import { getArgumentValues } from './values.js' ;
@@ -218,13 +218,13 @@ export class Executor<
218218 validatedExecutionArgs : ValidatedExecutionArgs ;
219219 finished : boolean ;
220220 initialResponseAbortController : AbortController | undefined ;
221- resolverAbortControllers : Set < AbortController > ;
221+ resolverAbortControllers : Map < Path , AbortController > ;
222222 collectedErrors : CollectedErrors ;
223223
224224 constructor ( validatedExecutionArgs : ValidatedExecutionArgs ) {
225225 this . validatedExecutionArgs = validatedExecutionArgs ;
226226 this . finished = false ;
227- this . resolverAbortControllers = new Set ( ) ;
227+ this . resolverAbortControllers = new Map ( ) ;
228228 this . collectedErrors = new CollectedErrors ( ) ;
229229 }
230230
@@ -333,10 +333,24 @@ export class Executor<
333333 const { resolverAbortControllers } = this ;
334334 const finishReason =
335335 reason ?? new Error ( 'Execution has already completed.' ) ;
336- for ( const abortController of resolverAbortControllers ) {
336+ for ( const abortController of resolverAbortControllers . values ( ) ) {
337337 abortController . abort ( finishReason ) ;
338338 }
339339 }
340+
341+ getAbortSignal ( path : Path ) : AbortSignal {
342+ const resolverAbortSignal = this . resolverAbortControllers . get ( path ) ?. signal ;
343+ if ( resolverAbortSignal !== undefined ) {
344+ return resolverAbortSignal ;
345+ }
346+ const abortController = new AbortController ( ) ;
347+ this . resolverAbortControllers . set ( path , abortController ) ;
348+ if ( this . finished ) {
349+ abortController . abort ( new Error ( 'Execution has already completed.' ) ) ;
350+ }
351+ return abortController . signal ;
352+ }
353+
340354 /**
341355 * Given a completed execution context and data, build the `{ errors, data }`
342356 * response defined by the "Response" section of the GraphQL specification.
@@ -522,26 +536,13 @@ export class Executor<
522536 const returnType = fieldDef . type ;
523537 const resolveFn = fieldDef . resolve ?? validatedExecutionArgs . fieldResolver ;
524538
525- const info = new ResolveInfo (
539+ const info = buildResolveInfo (
526540 validatedExecutionArgs ,
527541 fieldDef ,
528- fieldDetailsList ,
542+ toNodes ( fieldDetailsList ) ,
529543 parentType ,
530544 path ,
531- ( ) => {
532- /* c8 ignore next 3 */
533- if ( this . finished ) {
534- throw new Error ( 'Execution has already completed.' ) ;
535- }
536- const abortController = new AbortController ( ) ;
537- this . resolverAbortControllers . add ( abortController ) ;
538- return {
539- abortSignal : abortController . signal ,
540- unregister : ( ) => {
541- this . resolverAbortControllers . delete ( abortController ) ;
542- } ,
543- } ;
544- } ,
545+ ( ) => this . getAbortSignal ( path ) ,
545546 ) ;
546547
547548 // Get the resolve function, regardless of if its result is normal or abrupt (error).
@@ -588,20 +589,20 @@ export class Executor<
588589 // to take a second callback for the error case.
589590 return completed . then (
590591 ( resolved ) => {
591- info . unregisterAbortSignal ( ) ;
592+ this . resolverAbortControllers . delete ( path ) ;
592593 return resolved ;
593594 } ,
594595 ( rawError : unknown ) => {
595- info . unregisterAbortSignal ( ) ;
596+ this . resolverAbortControllers . delete ( path ) ;
596597 this . handleFieldError ( rawError , returnType , fieldDetailsList , path ) ;
597598 return null ;
598599 } ,
599600 ) ;
600601 }
601- info . unregisterAbortSignal ( ) ;
602+ this . resolverAbortControllers . delete ( path ) ;
602603 return completed ;
603604 } catch ( rawError ) {
604- info . unregisterAbortSignal ( ) ;
605+ this . resolverAbortControllers . delete ( path ) ;
605606 this . handleFieldError ( rawError , returnType , fieldDetailsList , path ) ;
606607 return null ;
607608 }
@@ -661,7 +662,7 @@ export class Executor<
661662 completeValue (
662663 returnType : GraphQLOutputType ,
663664 fieldDetailsList : FieldDetailsList ,
664- info : ResolveInfo ,
665+ info : GraphQLResolveInfo ,
665666 path : Path ,
666667 result : unknown ,
667668 positionContext : TPositionContext | undefined ,
@@ -750,7 +751,7 @@ export class Executor<
750751 async completePromisedValue (
751752 returnType : GraphQLOutputType ,
752753 fieldDetailsList : FieldDetailsList ,
753- info : ResolveInfo ,
754+ info : GraphQLResolveInfo ,
754755 path : Path ,
755756 result : Promise < unknown > ,
756757 positionContext : TPositionContext | undefined ,
@@ -774,12 +775,12 @@ export class Executor<
774775 completed = await completed ;
775776 }
776777 if ( isFieldValue ) {
777- info . unregisterAbortSignal ( ) ;
778+ this . resolverAbortControllers . delete ( path ) ;
778779 }
779780 return completed ;
780781 } catch ( rawError ) {
781782 if ( isFieldValue ) {
782- info . unregisterAbortSignal ( ) ;
783+ this . resolverAbortControllers . delete ( path ) ;
783784 }
784785 this . handleFieldError ( rawError , returnType , fieldDetailsList , path ) ;
785786 return null ;
@@ -793,7 +794,7 @@ export class Executor<
793794 async completeAsyncIterableValue (
794795 itemType : GraphQLOutputType ,
795796 fieldDetailsList : FieldDetailsList ,
796- info : ResolveInfo ,
797+ info : GraphQLResolveInfo ,
797798 path : Path ,
798799 items : AsyncIterable < unknown > ,
799800 positionContext : TPositionContext | undefined ,
@@ -879,7 +880,7 @@ export class Executor<
879880 | { handle : Iterator < unknown > ; isAsync ?: never }
880881 | { handle : AsyncIterator < unknown > ; isAsync : true } ,
881882 _streamUsage : StreamUsage ,
882- _info : ResolveInfo ,
883+ _info : GraphQLResolveInfo ,
883884 _itemType : GraphQLOutputType ,
884885 ) : boolean {
885886 return false ;
@@ -892,7 +893,7 @@ export class Executor<
892893 completeListValue (
893894 returnType : GraphQLList < GraphQLOutputType > ,
894895 fieldDetailsList : FieldDetailsList ,
895- info : ResolveInfo ,
896+ info : GraphQLResolveInfo ,
896897 path : Path ,
897898 result : unknown ,
898899 positionContext : TPositionContext | undefined ,
@@ -929,7 +930,7 @@ export class Executor<
929930 completeIterableValue (
930931 itemType : GraphQLOutputType ,
931932 fieldDetailsList : FieldDetailsList ,
932- info : ResolveInfo ,
933+ info : GraphQLResolveInfo ,
933934 path : Path ,
934935 items : Iterable < unknown > ,
935936 positionContext : TPositionContext | undefined ,
@@ -1002,7 +1003,7 @@ export class Executor<
10021003 completedResults : Array < unknown > ,
10031004 itemType : GraphQLOutputType ,
10041005 fieldDetailsList : FieldDetailsList ,
1005- info : ResolveInfo ,
1006+ info : GraphQLResolveInfo ,
10061007 itemPath : Path ,
10071008 positionContext : TPositionContext | undefined ,
10081009 ) : boolean {
@@ -1044,7 +1045,7 @@ export class Executor<
10441045 completedResults : Array < unknown > ,
10451046 itemType : GraphQLOutputType ,
10461047 fieldDetailsList : FieldDetailsList ,
1047- info : ResolveInfo ,
1048+ info : GraphQLResolveInfo ,
10481049 itemPath : Path ,
10491050 positionContext : TPositionContext | undefined ,
10501051 ) : boolean {
@@ -1087,7 +1088,7 @@ export class Executor<
10871088 item : Promise < unknown > ,
10881089 itemType : GraphQLOutputType ,
10891090 fieldDetailsList : FieldDetailsList ,
1090- info : ResolveInfo ,
1091+ info : GraphQLResolveInfo ,
10911092 itemPath : Path ,
10921093 positionContext : TPositionContext | undefined ,
10931094 ) : Promise < unknown > {
0 commit comments