@@ -17,6 +17,7 @@ import type {
17
17
import type { StreamUsage } from './execute.js' ;
18
18
19
19
interface IncrementalUpdate < TData = unknown , TExtensions = ObjMap < unknown > > {
20
+ pending : ReadonlyArray < PendingResult > ;
20
21
incremental : ReadonlyArray < IncrementalResult < TData , TExtensions > > ;
21
22
completed : ReadonlyArray < CompletedResult > ;
22
23
}
@@ -34,6 +35,7 @@ export interface FormattedSubsequentIncrementalExecutionResult<
34
35
TExtensions = ObjMap < unknown > ,
35
36
> {
36
37
hasNext : boolean ;
38
+ pending ?: ReadonlyArray < PendingResult > ;
37
39
incremental ?: ReadonlyArray < FormattedIncrementalResult < TData , TExtensions > > ;
38
40
completed ?: ReadonlyArray < FormattedCompletedResult > ;
39
41
extensions ?: TExtensions ;
@@ -90,6 +92,11 @@ export type FormattedIncrementalResult<
90
92
| FormattedIncrementalDeferResult < TData , TExtensions >
91
93
| FormattedIncrementalStreamResult < TData , TExtensions > ;
92
94
95
+ export interface PendingResult {
96
+ path : ReadonlyArray < string | number > ;
97
+ label ?: string ;
98
+ }
99
+
93
100
export interface CompletedResult {
94
101
path : ReadonlyArray < string | number > ;
95
102
label ?: string ;
@@ -148,6 +155,10 @@ export class IncrementalPublisher {
148
155
this . _reset ( ) ;
149
156
}
150
157
158
+ getPending ( ) : ReadonlySet < SubsequentResultRecord > {
159
+ return this . _pending ;
160
+ }
161
+
151
162
hasNext ( ) : boolean {
152
163
return this . _pending . size > 0 ;
153
164
}
@@ -419,6 +430,23 @@ export class IncrementalPublisher {
419
430
incrementalDataRecord . errors . push ( error ) ;
420
431
}
421
432
433
+ pendingSourcesToResults (
434
+ pendingSources : ReadonlySet < DeferredFragmentRecord | StreamRecord > ,
435
+ ) : Array < PendingResult > {
436
+ const pendingResults : Array < PendingResult > = [ ] ;
437
+ for ( const pendingSource of pendingSources ) {
438
+ pendingSource . pendingSent = true ;
439
+ const pendingResult : PendingResult = {
440
+ path : pendingSource . path ,
441
+ } ;
442
+ if ( pendingSource . label !== undefined ) {
443
+ pendingResult . label = pendingSource . label ;
444
+ }
445
+ pendingResults . push ( pendingResult ) ;
446
+ }
447
+ return pendingResults ;
448
+ }
449
+
422
450
publishInitial ( ) : void {
423
451
this . _initialResult . isCompleted = true ;
424
452
for ( const child of this . _initialResult . children ) {
@@ -507,14 +535,18 @@ export class IncrementalPublisher {
507
535
private _getIncrementalResult (
508
536
completedRecords : ReadonlySet < SubsequentResultRecord > ,
509
537
) : SubsequentIncrementalExecutionResult | undefined {
510
- const { incremental, completed } = this . _processPending ( completedRecords ) ;
538
+ const { pending, incremental, completed } =
539
+ this . _processPending ( completedRecords ) ;
511
540
512
541
const hasNext = this . hasNext ( ) ;
513
542
if ( incremental . length === 0 && completed . length === 0 && hasNext ) {
514
543
return undefined ;
515
544
}
516
545
517
546
const result : SubsequentIncrementalExecutionResult = { hasNext } ;
547
+ if ( pending . length ) {
548
+ result . pending = pending ;
549
+ }
518
550
if ( incremental . length ) {
519
551
result . incremental = incremental ;
520
552
}
@@ -528,16 +560,24 @@ export class IncrementalPublisher {
528
560
private _processPending (
529
561
completedRecords : ReadonlySet < SubsequentResultRecord > ,
530
562
) : IncrementalUpdate {
563
+ const newPendingSources = new Set < DeferredFragmentRecord | StreamRecord > ( ) ;
531
564
const incrementalResults : Array < IncrementalResult > = [ ] ;
532
565
const completedResults : Array < CompletedResult > = [ ] ;
533
566
for ( const subsequentResultRecord of completedRecords ) {
534
567
for ( const child of subsequentResultRecord . children ) {
568
+ const pendingSource = isStreamItemsRecord ( child )
569
+ ? child . streamRecord
570
+ : child ;
571
+ if ( ! pendingSource . pendingSent ) {
572
+ newPendingSources . add ( pendingSource ) ;
573
+ }
535
574
this . _publish ( child ) ;
536
575
}
537
576
if ( isStreamItemsRecord ( subsequentResultRecord ) ) {
538
577
if ( ! subsequentResultRecord . sent ) {
539
578
subsequentResultRecord . sent = true ;
540
579
if ( subsequentResultRecord . isFinalRecord ) {
580
+ newPendingSources . delete ( subsequentResultRecord . streamRecord ) ;
541
581
completedResults . push (
542
582
this . _completedRecordToResult (
543
583
subsequentResultRecord . streamRecord ,
@@ -561,6 +601,7 @@ export class IncrementalPublisher {
561
601
incrementalResults . push ( incrementalResult ) ;
562
602
}
563
603
} else {
604
+ newPendingSources . delete ( subsequentResultRecord ) ;
564
605
completedResults . push (
565
606
this . _completedRecordToResult ( subsequentResultRecord ) ,
566
607
) ;
@@ -585,6 +626,7 @@ export class IncrementalPublisher {
585
626
}
586
627
587
628
return {
629
+ pending : this . pendingSourcesToResults ( newPendingSources ) ,
588
630
incremental : incrementalResults ,
589
631
completed : completedResults ,
590
632
} ;
@@ -738,6 +780,7 @@ export class DeferredFragmentRecord {
738
780
deferredGroupedFieldSetRecords : Set < DeferredGroupedFieldSetRecord > ;
739
781
errors : Array < GraphQLError > ;
740
782
isCompleted : boolean ;
783
+ pendingSent ?: boolean ;
741
784
_pending : Set < DeferredGroupedFieldSetRecord > ;
742
785
743
786
constructor ( opts : {
@@ -762,6 +805,7 @@ export class StreamRecord {
762
805
path : ReadonlyArray < string | number > ;
763
806
errors : Array < GraphQLError > ;
764
807
asyncIterator ?: AsyncIterator < unknown > | undefined ;
808
+ pendingSent ?: boolean ;
765
809
constructor ( opts : {
766
810
label : string | undefined ;
767
811
path : Path ;
@@ -807,7 +851,7 @@ export type IncrementalDataRecord =
807
851
| DeferredGroupedFieldSetRecord
808
852
| StreamItemsRecord ;
809
853
810
- type SubsequentResultRecord = DeferredFragmentRecord | StreamItemsRecord ;
854
+ export type SubsequentResultRecord = DeferredFragmentRecord | StreamItemsRecord ;
811
855
812
856
function getSubsequentResultRecords (
813
857
incrementalDataRecord : IncrementalDataRecord | undefined ,
@@ -823,7 +867,7 @@ function getSubsequentResultRecords(
823
867
return incrementalDataRecord . deferredFragmentRecords ;
824
868
}
825
869
826
- function isStreamItemsRecord (
870
+ export function isStreamItemsRecord (
827
871
subsequentResultRecord : unknown ,
828
872
) : subsequentResultRecord is StreamItemsRecord {
829
873
return subsequentResultRecord instanceof StreamItemsRecord ;
0 commit comments