@@ -48,7 +48,6 @@ import {
4848 cancellablePromise ,
4949} from './AbortSignalListener.js' ;
5050import type { DeferUsageSet , ExecutionPlan } from './buildExecutionPlan.js' ;
51- import { buildExecutionPlan } from './buildExecutionPlan.js' ;
5251import { buildResolveInfo } from './buildResolveInfo.js' ;
5352import type {
5453 DeferUsage ,
@@ -57,17 +56,20 @@ import type {
5756 GroupedFieldSet ,
5857} from './collectFields.js' ;
5958import { collectFields , collectSubfields } from './collectFields.js' ;
59+ import type { ExperimentalIncrementalExecutionResults } from './IncrementalPublisher.js' ;
6060import { buildIncrementalResponse } from './IncrementalPublisher.js' ;
61+ import type { PayloadPublisher } from './PayloadPublisher.js' ;
6162import type {
6263 CancellableStreamRecord ,
6364 CompletedExecutionGroup ,
6465 ExecutionResult ,
65- ExperimentalIncrementalExecutionResults ,
6666 IncrementalDataRecord ,
67+ InitialIncrementalExecutionResult ,
6768 PendingExecutionGroup ,
6869 StreamItemRecord ,
6970 StreamItemResult ,
7071 StreamRecord ,
72+ SubsequentIncrementalExecutionResult ,
7173} from './types.js' ;
7274import { DeferredFragmentRecord } from './types.js' ;
7375import type { VariableValues } from './values.js' ;
@@ -150,8 +152,22 @@ interface GraphQLWrappedResult<T> {
150152}
151153
152154/** @internal */
153- export class Executor {
155+ export class Executor <
156+ TInitialPayload = InitialIncrementalExecutionResult ,
157+ TSubsequentPayload = SubsequentIncrementalExecutionResult ,
158+ > {
154159 validatedExecutionArgs : ValidatedExecutionArgs ;
160+
161+ buildExecutionPlan : (
162+ originalGroupedFieldSet : GroupedFieldSet ,
163+ parentDeferUsages ?: DeferUsageSet | undefined ,
164+ ) => ExecutionPlan ;
165+
166+ getPayloadPublisher : ( ) => PayloadPublisher <
167+ TInitialPayload ,
168+ TSubsequentPayload
169+ > ;
170+
155171 exeContext : ExecutionContext ;
156172
157173 /**
@@ -167,8 +183,21 @@ export class Executor {
167183 newDeferUsages : ReadonlyArray < DeferUsage > ;
168184 } ;
169185
170- constructor ( validatedExecutionArgs : ValidatedExecutionArgs ) {
186+ constructor (
187+ validatedExecutionArgs : ValidatedExecutionArgs ,
188+ buildExecutionPlan : (
189+ originalGroupedFieldSet : GroupedFieldSet ,
190+ parentDeferUsages ?: DeferUsageSet | undefined ,
191+ ) => ExecutionPlan ,
192+ getPayloadPublisher : ( ) => PayloadPublisher <
193+ TInitialPayload ,
194+ TSubsequentPayload
195+ > ,
196+ ) {
171197 this . validatedExecutionArgs = validatedExecutionArgs ;
198+ this . buildExecutionPlan = buildExecutionPlan ;
199+ this . getPayloadPublisher = getPayloadPublisher ;
200+
172201 const abortSignal = validatedExecutionArgs . abortSignal ;
173202 this . exeContext = {
174203 errors : undefined ,
@@ -196,7 +225,11 @@ export class Executor {
196225 }
197226
198227 executeQueryOrMutationOrSubscriptionEvent ( ) : PromiseOrValue <
199- ExecutionResult | ExperimentalIncrementalExecutionResults
228+ | ExecutionResult
229+ | ExperimentalIncrementalExecutionResults <
230+ TInitialPayload ,
231+ TSubsequentPayload
232+ >
200233 > {
201234 try {
202235 const {
@@ -277,19 +310,36 @@ export class Executor {
277310
278311 buildDataResponse (
279312 graphqlWrappedResult : GraphQLWrappedResult < ObjMap < unknown > > ,
280- ) : ExecutionResult | ExperimentalIncrementalExecutionResults {
313+ ) :
314+ | ExecutionResult
315+ | ExperimentalIncrementalExecutionResults <
316+ TInitialPayload ,
317+ TSubsequentPayload
318+ > {
281319 const { rawResult : data , incrementalDataRecords } = graphqlWrappedResult ;
282320 const errors = this . exeContext . errors ;
283321 if ( incrementalDataRecords === undefined ) {
284322 this . exeContext . abortSignalListener ?. disconnect ( ) ;
285323 return errors !== undefined ? { errors, data } : { data } ;
286324 }
287325
326+ return this . buildIncrementalResponse ( data , errors , incrementalDataRecords ) ;
327+ }
328+
329+ buildIncrementalResponse (
330+ data : ObjMap < unknown > ,
331+ errors : ReadonlyArray < GraphQLError > | undefined ,
332+ incrementalDataRecords : ReadonlyArray < IncrementalDataRecord > ,
333+ ) : ExperimentalIncrementalExecutionResults <
334+ TInitialPayload ,
335+ TSubsequentPayload
336+ > {
288337 return buildIncrementalResponse (
289338 this . exeContext ,
290339 data ,
291340 errors ,
292341 incrementalDataRecords ,
342+ this . getPayloadPublisher ( ) ,
293343 ) ;
294344 }
295345
@@ -315,7 +365,7 @@ export class Executor {
315365 undefined ,
316366 ) ;
317367
318- const { groupedFieldSet, newGroupedFieldSets } = buildExecutionPlan (
368+ const { groupedFieldSet, newGroupedFieldSets } = this . buildExecutionPlan (
319369 originalGroupedFieldSet ,
320370 ) ;
321371
@@ -1582,13 +1632,7 @@ export class Executor {
15821632 ) ;
15831633 const { groupedFieldSet, newDeferUsages } = collectedSubfields ;
15841634
1585- if ( newDeferUsages . length > 0 ) {
1586- invariant (
1587- this . validatedExecutionArgs . operation . operation !==
1588- OperationTypeNode . SUBSCRIPTION ,
1589- '`@defer` directive not supported on subscription operations. Disable `@defer` by setting the `if` argument to `false`.' ,
1590- ) ;
1591- }
1635+ this . assertValidOperationTypeForDefer ( newDeferUsages ) ;
15921636
15931637 return this . executeSubExecutionPlan (
15941638 returnType ,
@@ -1601,6 +1645,18 @@ export class Executor {
16011645 ) ;
16021646 }
16031647
1648+ assertValidOperationTypeForDefer (
1649+ newDeferUsages : ReadonlyArray < DeferUsage > ,
1650+ ) : void {
1651+ if ( newDeferUsages . length > 0 ) {
1652+ invariant (
1653+ this . validatedExecutionArgs . operation . operation !==
1654+ OperationTypeNode . SUBSCRIPTION ,
1655+ '`@defer` directive not supported on subscription operations. Disable `@defer` by setting the `if` argument to `false`.' ,
1656+ ) ;
1657+ }
1658+ }
1659+
16041660 executeSubExecutionPlan (
16051661 returnType : GraphQLObjectType ,
16061662 sourceValue : unknown ,
@@ -1665,7 +1721,10 @@ export class Executor {
16651721 if ( executionPlan !== undefined ) {
16661722 return executionPlan ;
16671723 }
1668- executionPlan = buildExecutionPlan ( originalGroupedFieldSet , deferUsageSet ) ;
1724+ executionPlan = this . buildExecutionPlan (
1725+ originalGroupedFieldSet ,
1726+ deferUsageSet ,
1727+ ) ;
16691728 (
16701729 originalGroupedFieldSet as unknown as { _executionPlan : ExecutionPlan }
16711730 ) . _executionPlan = executionPlan ;
0 commit comments