@@ -100,7 +100,8 @@ export interface IncrementalDeferResult<
100100> {
101101 errors ?: ReadonlyArray < GraphQLError > ;
102102 data : TData ;
103- path : ReadonlyArray < string | number > ;
103+ id : string ;
104+ subPath ?: ReadonlyArray < string | number > ;
104105 extensions ?: TExtensions ;
105106}
106107
@@ -110,7 +111,8 @@ export interface FormattedIncrementalDeferResult<
110111> {
111112 errors ?: ReadonlyArray < GraphQLFormattedError > ;
112113 data : TData ;
113- path : ReadonlyArray < string | number > ;
114+ id : string ;
115+ subPath ?: ReadonlyArray < string | number > ;
114116 extensions ?: TExtensions ;
115117}
116118
@@ -120,7 +122,8 @@ export interface IncrementalStreamResult<
120122> {
121123 errors ?: ReadonlyArray < GraphQLError > ;
122124 items : TData ;
123- path : ReadonlyArray < string | number > ;
125+ id : string ;
126+ subPath ?: ReadonlyArray < string | number > ;
124127 extensions ?: TExtensions ;
125128}
126129
@@ -130,7 +133,8 @@ export interface FormattedIncrementalStreamResult<
130133> {
131134 errors ?: ReadonlyArray < GraphQLFormattedError > ;
132135 items : TData ;
133- path : ReadonlyArray < string | number > ;
136+ id : string ;
137+ subPath ?: ReadonlyArray < string | number > ;
134138 extensions ?: TExtensions ;
135139}
136140
@@ -146,13 +150,13 @@ export type FormattedIncrementalResult<
146150 | FormattedIncrementalStreamResult < TData , TExtensions > ;
147151
148152export interface PendingResult {
153+ id : string ;
149154 path : ReadonlyArray < string | number > ;
150155 label ?: string ;
151156}
152157
153158export interface CompletedResult {
154- path : ReadonlyArray < string | number > ;
155- label ?: string ;
159+ id : string ;
156160 errors ?: ReadonlyArray < GraphQLError > ;
157161}
158162
@@ -178,6 +182,7 @@ export interface FormattedCompletedResult {
178182 * @internal
179183 */
180184export class IncrementalPublisher {
185+ private _nextId = 0 ;
181186 private _released : Set < SubsequentResultRecord > ;
182187 private _pending : Set < SubsequentResultRecord > ;
183188
@@ -372,7 +377,10 @@ export class IncrementalPublisher {
372377 const pendingResults : Array < PendingResult > = [ ] ;
373378 for ( const pendingSource of pendingSources ) {
374379 pendingSource . pendingSent = true ;
380+ const id = this . _getNextId ( ) ;
381+ pendingSource . id = id ;
375382 const pendingResult : PendingResult = {
383+ id,
376384 path : pendingSource . path ,
377385 } ;
378386 if ( pendingSource . label !== undefined ) {
@@ -383,6 +391,10 @@ export class IncrementalPublisher {
383391 return pendingResults ;
384392 }
385393
394+ private _getNextId ( ) : string {
395+ return String ( this . _nextId ++ ) ;
396+ }
397+
386398 private _subscribe ( ) : AsyncGenerator <
387399 SubsequentIncrementalExecutionResult ,
388400 void ,
@@ -554,7 +566,9 @@ export class IncrementalPublisher {
554566 }
555567 const incrementalResult : IncrementalStreamResult = {
556568 items : subsequentResultRecord . items ,
557- path : subsequentResultRecord . streamRecord . path ,
569+ // safe because `id` is defined once the stream has been released as pending
570+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
571+ id : subsequentResultRecord . streamRecord . id ! ,
558572 } ;
559573 if ( subsequentResultRecord . errors . length > 0 ) {
560574 incrementalResult . errors = subsequentResultRecord . errors ;
@@ -571,11 +585,8 @@ export class IncrementalPublisher {
571585 for ( const deferredGroupedFieldSetRecord of subsequentResultRecord . deferredGroupedFieldSetRecords ) {
572586 if ( ! deferredGroupedFieldSetRecord . sent ) {
573587 deferredGroupedFieldSetRecord . sent = true ;
574- const incrementalResult : IncrementalDeferResult = {
575- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
576- data : deferredGroupedFieldSetRecord . data ! ,
577- path : deferredGroupedFieldSetRecord . path ,
578- } ;
588+ const incrementalResult : IncrementalDeferResult =
589+ this . _getIncrementalDeferResult ( deferredGroupedFieldSetRecord ) ;
579590 if ( deferredGroupedFieldSetRecord . errors . length > 0 ) {
580591 incrementalResult . errors = deferredGroupedFieldSetRecord . errors ;
581592 }
@@ -592,15 +603,49 @@ export class IncrementalPublisher {
592603 } ;
593604 }
594605
606+ private _getIncrementalDeferResult (
607+ deferredGroupedFieldSetRecord : DeferredGroupedFieldSetRecord ,
608+ ) : IncrementalDeferResult {
609+ const { data, deferredFragmentRecords } = deferredGroupedFieldSetRecord ;
610+ let maxLength = deferredFragmentRecords [ 0 ] . path . length ;
611+ let maxIndex = 0 ;
612+ for ( let i = 1 ; i < deferredFragmentRecords . length ; i ++ ) {
613+ const deferredFragmentRecord = deferredFragmentRecords [ i ] ;
614+ const length = deferredFragmentRecord . path . length ;
615+ if ( length > maxLength ) {
616+ maxLength = length ;
617+ maxIndex = i ;
618+ }
619+ }
620+ const recordWithLongestPath = deferredFragmentRecords [ maxIndex ] ;
621+ const longestPath = recordWithLongestPath . path ;
622+ const subPath = deferredGroupedFieldSetRecord . path . slice (
623+ longestPath . length ,
624+ ) ;
625+ const id = recordWithLongestPath . id ;
626+ const incrementalDeferResult : IncrementalDeferResult = {
627+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
628+ data : data ! ,
629+ // safe because `id` is defined once the fragment has been released as pending
630+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
631+ id : id ! ,
632+ } ;
633+
634+ if ( subPath . length > 0 ) {
635+ incrementalDeferResult . subPath = subPath ;
636+ }
637+
638+ return incrementalDeferResult ;
639+ }
640+
595641 private _completedRecordToResult (
596642 completedRecord : DeferredFragmentRecord | StreamRecord ,
597643 ) : CompletedResult {
598644 const result : CompletedResult = {
599- path : completedRecord . path ,
645+ // safe because `id` is defined once the stream has been released as pending
646+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
647+ id : completedRecord . id ! ,
600648 } ;
601- if ( completedRecord . label !== undefined ) {
602- result . label = completedRecord . label ;
603- }
604649 if ( completedRecord . errors . length > 0 ) {
605650 result . errors = completedRecord . errors ;
606651 }
@@ -736,6 +781,7 @@ export class DeferredGroupedFieldSetRecord {
736781export class DeferredFragmentRecord {
737782 path : ReadonlyArray < string | number > ;
738783 label : string | undefined ;
784+ id : string | undefined ;
739785 children : Set < SubsequentResultRecord > ;
740786 deferredGroupedFieldSetRecords : Set < DeferredGroupedFieldSetRecord > ;
741787 errors : Array < GraphQLError > ;
@@ -758,6 +804,7 @@ export class DeferredFragmentRecord {
758804export class StreamRecord {
759805 label : string | undefined ;
760806 path : ReadonlyArray < string | number > ;
807+ id : string | undefined ;
761808 errors : Array < GraphQLError > ;
762809 earlyReturn ?: ( ( ) => Promise < unknown > ) | undefined ;
763810 pendingSent ?: boolean ;
0 commit comments