@@ -11,6 +11,7 @@ import type {
11
11
import type { GroupedFieldSet } from './collectFields.js' ;
12
12
13
13
interface IncrementalUpdate < TData = unknown , TExtensions = ObjMap < unknown > > {
14
+ pending : ReadonlyArray < PendingResult > ;
14
15
incremental : ReadonlyArray < IncrementalResult < TData , TExtensions > > ;
15
16
completed : ReadonlyArray < CompletedResult > ;
16
17
}
@@ -59,6 +60,7 @@ export interface InitialIncrementalExecutionResult<
59
60
TExtensions = ObjMap < unknown > ,
60
61
> extends ExecutionResult < TData , TExtensions > {
61
62
data : TData ;
63
+ pending : ReadonlyArray < PendingResult > ;
62
64
hasNext : true ;
63
65
extensions ?: TExtensions ;
64
66
}
@@ -68,6 +70,7 @@ export interface FormattedInitialIncrementalExecutionResult<
68
70
TExtensions = ObjMap < unknown > ,
69
71
> extends FormattedExecutionResult < TData , TExtensions > {
70
72
data : TData ;
73
+ pending : ReadonlyArray < PendingResult > ;
71
74
hasNext : boolean ;
72
75
extensions ?: TExtensions ;
73
76
}
@@ -85,6 +88,7 @@ export interface FormattedSubsequentIncrementalExecutionResult<
85
88
TExtensions = ObjMap < unknown > ,
86
89
> {
87
90
hasNext : boolean ;
91
+ pending ?: ReadonlyArray < PendingResult > ;
88
92
incremental ?: ReadonlyArray < FormattedIncrementalResult < TData , TExtensions > > ;
89
93
completed ?: ReadonlyArray < FormattedCompletedResult > ;
90
94
extensions ?: TExtensions ;
@@ -141,6 +145,11 @@ export type FormattedIncrementalResult<
141
145
| FormattedIncrementalDeferResult < TData , TExtensions >
142
146
| FormattedIncrementalStreamResult < TData , TExtensions > ;
143
147
148
+ export interface PendingResult {
149
+ path : ReadonlyArray < string | number > ;
150
+ label ?: string ;
151
+ }
152
+
144
153
export interface CompletedResult {
145
154
path : ReadonlyArray < string | number > ;
146
155
label ?: string ;
@@ -296,10 +305,20 @@ export class IncrementalPublisher {
296
305
297
306
const errors = initialResultRecord . errors ;
298
307
const initialResult = errors . length === 0 ? { data } : { errors, data } ;
299
- if ( this . _pending . size > 0 ) {
308
+ const pending = this . _pending ;
309
+ if ( pending . size > 0 ) {
310
+ const pendingSources = new Set < DeferredFragmentRecord | StreamRecord > ( ) ;
311
+ for ( const subsequentResultRecord of pending ) {
312
+ const pendingSource = isStreamItemsRecord ( subsequentResultRecord )
313
+ ? subsequentResultRecord . streamRecord
314
+ : subsequentResultRecord ;
315
+ pendingSources . add ( pendingSource ) ;
316
+ }
317
+
300
318
return {
301
319
initialResult : {
302
320
...initialResult ,
321
+ pending : this . pendingSourcesToResults ( pendingSources ) ,
303
322
hasNext : true ,
304
323
} ,
305
324
subsequentResults : this . _subscribe ( ) ,
@@ -347,6 +366,23 @@ export class IncrementalPublisher {
347
366
} ) ;
348
367
}
349
368
369
+ pendingSourcesToResults (
370
+ pendingSources : ReadonlySet < DeferredFragmentRecord | StreamRecord > ,
371
+ ) : Array < PendingResult > {
372
+ const pendingResults : Array < PendingResult > = [ ] ;
373
+ for ( const pendingSource of pendingSources ) {
374
+ pendingSource . pendingSent = true ;
375
+ const pendingResult : PendingResult = {
376
+ path : pendingSource . path ,
377
+ } ;
378
+ if ( pendingSource . label !== undefined ) {
379
+ pendingResult . label = pendingSource . label ;
380
+ }
381
+ pendingResults . push ( pendingResult ) ;
382
+ }
383
+ return pendingResults ;
384
+ }
385
+
350
386
private _subscribe ( ) : AsyncGenerator <
351
387
SubsequentIncrementalExecutionResult ,
352
388
void ,
@@ -461,14 +497,18 @@ export class IncrementalPublisher {
461
497
private _getIncrementalResult (
462
498
completedRecords : ReadonlySet < SubsequentResultRecord > ,
463
499
) : SubsequentIncrementalExecutionResult | undefined {
464
- const { incremental, completed } = this . _processPending ( completedRecords ) ;
500
+ const { pending, incremental, completed } =
501
+ this . _processPending ( completedRecords ) ;
465
502
466
503
const hasNext = this . _pending . size > 0 ;
467
504
if ( incremental . length === 0 && completed . length === 0 && hasNext ) {
468
505
return undefined ;
469
506
}
470
507
471
508
const result : SubsequentIncrementalExecutionResult = { hasNext } ;
509
+ if ( pending . length ) {
510
+ result . pending = pending ;
511
+ }
472
512
if ( incremental . length ) {
473
513
result . incremental = incremental ;
474
514
}
@@ -482,17 +522,25 @@ export class IncrementalPublisher {
482
522
private _processPending (
483
523
completedRecords : ReadonlySet < SubsequentResultRecord > ,
484
524
) : IncrementalUpdate {
525
+ const newPendingSources = new Set < DeferredFragmentRecord | StreamRecord > ( ) ;
485
526
const incrementalResults : Array < IncrementalResult > = [ ] ;
486
527
const completedResults : Array < CompletedResult > = [ ] ;
487
528
for ( const subsequentResultRecord of completedRecords ) {
488
529
for ( const child of subsequentResultRecord . children ) {
489
530
if ( child . filtered ) {
490
531
continue ;
491
532
}
533
+ const pendingSource = isStreamItemsRecord ( child )
534
+ ? child . streamRecord
535
+ : child ;
536
+ if ( ! pendingSource . pendingSent ) {
537
+ newPendingSources . add ( pendingSource ) ;
538
+ }
492
539
this . _publish ( child ) ;
493
540
}
494
541
if ( isStreamItemsRecord ( subsequentResultRecord ) ) {
495
542
if ( subsequentResultRecord . isFinalRecord ) {
543
+ newPendingSources . delete ( subsequentResultRecord . streamRecord ) ;
496
544
completedResults . push (
497
545
this . _completedRecordToResult ( subsequentResultRecord . streamRecord ) ,
498
546
) ;
@@ -513,6 +561,7 @@ export class IncrementalPublisher {
513
561
}
514
562
incrementalResults . push ( incrementalResult ) ;
515
563
} else {
564
+ newPendingSources . delete ( subsequentResultRecord ) ;
516
565
completedResults . push (
517
566
this . _completedRecordToResult ( subsequentResultRecord ) ,
518
567
) ;
@@ -537,6 +586,7 @@ export class IncrementalPublisher {
537
586
}
538
587
539
588
return {
589
+ pending : this . pendingSourcesToResults ( newPendingSources ) ,
540
590
incremental : incrementalResults ,
541
591
completed : completedResults ,
542
592
} ;
@@ -690,6 +740,7 @@ export class DeferredFragmentRecord {
690
740
deferredGroupedFieldSetRecords : Set < DeferredGroupedFieldSetRecord > ;
691
741
errors : Array < GraphQLError > ;
692
742
filtered : boolean ;
743
+ pendingSent ?: boolean ;
693
744
_pending : Set < DeferredGroupedFieldSetRecord > ;
694
745
695
746
constructor ( opts : { path : Path | undefined ; label : string | undefined } ) {
@@ -709,6 +760,7 @@ export class StreamRecord {
709
760
path : ReadonlyArray < string | number > ;
710
761
errors : Array < GraphQLError > ;
711
762
earlyReturn ?: ( ( ) => Promise < unknown > ) | undefined ;
763
+ pendingSent ?: boolean ;
712
764
constructor ( opts : {
713
765
label : string | undefined ;
714
766
path : Path ;
0 commit comments