@@ -234,38 +234,103 @@ export function experimentalExecuteIncrementally(
234234 return { errors : exeContext } ;
235235 }
236236
237- return executeImpl ( exeContext ) ;
237+ return executeOperation ( exeContext ) ;
238238}
239239
240- function executeImpl (
240+ /**
241+ * Implements the "Executing operations" section of the spec.
242+ *
243+ * Returns a Promise that will eventually resolve to the data described by
244+ * The "Response" section of the GraphQL specification.
245+ *
246+ * If errors are encountered while executing a GraphQL field, only that
247+ * field and its descendants will be omitted, and sibling fields will still
248+ * be executed. An execution which encounters errors will still result in a
249+ * resolved Promise.
250+ *
251+ * Errors from sub-fields of a NonNull type may propagate to the top level,
252+ * at which point we still log the error and null the parent field, which
253+ * in this case is the entire response.
254+ */
255+ function executeOperation (
241256 exeContext : ExecutionContext ,
242257) : PromiseOrValue < ExecutionResult | ExperimentalIncrementalExecutionResults > {
243- // Return a Promise that will eventually resolve to the data described by
244- // The "Response" section of the GraphQL specification.
245- //
246- // If errors are encountered while executing a GraphQL field, only that
247- // field and its descendants will be omitted, and sibling fields will still
248- // be executed. An execution which encounters errors will still result in a
249- // resolved Promise.
250- //
251- // Errors from sub-fields of a NonNull type may propagate to the top level,
252- // at which point we still log the error and null the parent field, which
253- // in this case is the entire response.
254- const incrementalPublisher = exeContext . incrementalPublisher ;
255258 const initialResultRecord = new InitialResultRecord ( ) ;
256259 try {
257- const data = executeOperation ( exeContext , initialResultRecord ) ;
258- if ( isPromise ( data ) ) {
259- return data . then (
260+ const {
261+ operation,
262+ schema,
263+ fragments,
264+ variableValues,
265+ rootValue,
266+ incrementalPublisher,
267+ } = exeContext ;
268+ const rootType = schema . getRootType ( operation . operation ) ;
269+ if ( rootType == null ) {
270+ throw new GraphQLError (
271+ `Schema is not configured to execute ${ operation . operation } operation.` ,
272+ { nodes : operation } ,
273+ ) ;
274+ }
275+
276+ const { fields, newDeferUsages } = collectFields (
277+ schema ,
278+ fragments ,
279+ variableValues ,
280+ rootType ,
281+ operation ,
282+ ) ;
283+ const { groupedFieldSet, newGroupedFieldSetDetailsMap } =
284+ buildFieldPlan ( fields ) ;
285+
286+ const newDeferMap = addNewDeferredFragments (
287+ incrementalPublisher ,
288+ newDeferUsages ,
289+ initialResultRecord ,
290+ ) ;
291+
292+ const path = undefined ;
293+
294+ const newDeferredGroupedFieldSetRecords = addNewDeferredGroupedFieldSets (
295+ incrementalPublisher ,
296+ newGroupedFieldSetDetailsMap ,
297+ newDeferMap ,
298+ path ,
299+ ) ;
300+
301+ const result = executeRootGroupedFieldSet (
302+ exeContext ,
303+ operation . operation ,
304+ rootType ,
305+ rootValue ,
306+ groupedFieldSet ,
307+ initialResultRecord ,
308+ newDeferMap ,
309+ ) ;
310+
311+ executeDeferredGroupedFieldSets (
312+ exeContext ,
313+ rootType ,
314+ rootValue ,
315+ path ,
316+ newDeferredGroupedFieldSetRecords ,
317+ newDeferMap ,
318+ ) ;
319+
320+ if ( isPromise ( result ) ) {
321+ return result . then (
260322 ( resolved ) =>
261323 incrementalPublisher . buildDataResponse ( initialResultRecord , resolved ) ,
262324 ( error ) =>
263325 incrementalPublisher . buildErrorResponse ( initialResultRecord , error ) ,
264326 ) ;
265327 }
266- return incrementalPublisher . buildDataResponse ( initialResultRecord , data ) ;
328+ return incrementalPublisher . buildDataResponse ( initialResultRecord , result ) ;
267329 } catch ( error ) {
268- return incrementalPublisher . buildErrorResponse ( initialResultRecord , error ) ;
330+ return exeContext . incrementalPublisher . buildErrorResponse (
331+ initialResultRecord ,
332+ error ,
333+ ) ;
269334 }
270335}
271336
@@ -384,102 +449,49 @@ function buildPerEventExecutionContext(
384449 } ;
385450}
386451
387- /**
388- * Implements the "Executing operations" section of the spec.
389- */
390- function executeOperation (
452+ function executeRootGroupedFieldSet (
391453 exeContext : ExecutionContext ,
454+ operation : OperationTypeNode ,
455+ rootType : GraphQLObjectType ,
456+ rootValue : unknown ,
457+ groupedFieldSet : GroupedFieldSet ,
392458 initialResultRecord : InitialResultRecord ,
459+ newDeferMap : ReadonlyMap < DeferUsage , DeferredFragmentRecord > ,
393460) : PromiseOrValue < ObjMap < unknown > > {
394- const {
395- operation,
396- schema,
397- fragments,
398- variableValues,
399- rootValue,
400- incrementalPublisher,
401- } = exeContext ;
402- const rootType = schema . getRootType ( operation . operation ) ;
403- if ( rootType == null ) {
404- throw new GraphQLError (
405- `Schema is not configured to execute ${ operation . operation } operation.` ,
406- { nodes : operation } ,
407- ) ;
408- }
409-
410- const { fields, newDeferUsages } = collectFields (
411- schema ,
412- fragments ,
413- variableValues ,
414- rootType ,
415- operation ,
416- ) ;
417- const { groupedFieldSet, newGroupedFieldSetDetailsMap } =
418- buildFieldPlan ( fields ) ;
419-
420- const newDeferMap = addNewDeferredFragments (
421- incrementalPublisher ,
422- newDeferUsages ,
423- initialResultRecord ,
424- ) ;
425-
426- const path = undefined ;
427-
428- const newDeferredGroupedFieldSetRecords = addNewDeferredGroupedFieldSets (
429- incrementalPublisher ,
430- newGroupedFieldSetDetailsMap ,
431- newDeferMap ,
432- path ,
433- ) ;
434-
435- let result ;
436- switch ( operation . operation ) {
461+ switch ( operation ) {
437462 case OperationTypeNode . QUERY :
438- result = executeFields (
463+ return executeFields (
439464 exeContext ,
440465 rootType ,
441466 rootValue ,
442- path ,
467+ undefined ,
443468 groupedFieldSet ,
444469 initialResultRecord ,
445470 newDeferMap ,
446471 ) ;
447- break ;
448472 case OperationTypeNode . MUTATION :
449- result = executeFieldsSerially (
473+ return executeFieldsSerially (
450474 exeContext ,
451475 rootType ,
452476 rootValue ,
453- path ,
477+ undefined ,
454478 groupedFieldSet ,
455479 initialResultRecord ,
456480 newDeferMap ,
457481 ) ;
458- break ;
459482 case OperationTypeNode . SUBSCRIPTION :
460483 // TODO: deprecate `subscribe` and move all logic here
461484 // Temporary solution until we finish merging execute and subscribe together
462- result = executeFields (
485+ return executeFields (
463486 exeContext ,
464487 rootType ,
465488 rootValue ,
466- path ,
489+ undefined ,
467490 groupedFieldSet ,
468491 initialResultRecord ,
469492 newDeferMap ,
470493 ) ;
471494 }
472-
473- executeDeferredGroupedFieldSets (
474- exeContext ,
475- rootType ,
476- rootValue ,
477- path ,
478- newDeferredGroupedFieldSetRecords ,
479- newDeferMap ,
480- ) ;
481-
482- return result ;
483495}
484496
485497/**
@@ -1725,7 +1737,7 @@ function mapSourceToResponse(
17251737 return mapAsyncIterable (
17261738 resultOrStream ,
17271739 ( payload : unknown ) =>
1728- executeImpl (
1740+ executeOperation (
17291741 buildPerEventExecutionContext ( exeContext , payload ) ,
17301742 // typecast to ExecutionResult, not possible to return
17311743 // ExperimentalIncrementalExecutionResults when
0 commit comments