11import { BoxedPromiseOrValue } from '../jsutils/BoxedPromiseOrValue.js' ;
22import { invariant } from '../jsutils/invariant.js' ;
33import { isPromise } from '../jsutils/isPromise.js' ;
4+ import type { Path } from '../jsutils/Path.js' ;
45import { promiseWithResolvers } from '../jsutils/promiseWithResolvers.js' ;
56
67import type { GraphQLError } from '../error/GraphQLError.js' ;
78
9+ import type { DeferUsage } from './collectFields.js' ;
810import type {
911 DeferredFragmentRecord ,
1012 DeliveryGroup ,
13+ } from './DeferredFragments.js' ;
14+ import {
15+ DeferredFragmentFactory ,
16+ isDeferredFragmentRecord ,
17+ } from './DeferredFragments.js' ;
18+ import type {
1119 IncrementalDataRecord ,
1220 IncrementalDataRecordResult ,
1321 PendingExecutionGroup ,
1422 StreamItemRecord ,
1523 StreamRecord ,
1624 SuccessfulExecutionGroup ,
1725} from './types.js' ;
18- import { isDeferredFragmentRecord , isPendingExecutionGroup } from './types.js' ;
26+ import { isPendingExecutionGroup } from './types.js' ;
1927
2028/**
2129 * @internal
2230 */
2331export class IncrementalGraph {
2432 private _rootNodes : Set < DeliveryGroup > ;
25-
33+ private _deferredFragmentFactory : DeferredFragmentFactory ;
2634 private _completedQueue : Array < IncrementalDataRecordResult > ;
2735 private _nextQueue : Array <
2836 ( iterable : Iterable < IncrementalDataRecordResult > | undefined ) => void
2937 > ;
3038
3139 constructor ( ) {
40+ this . _deferredFragmentFactory = new DeferredFragmentFactory ( ) ;
3241 this . _rootNodes = new Set ( ) ;
3342 this . _completedQueue = [ ] ;
3443 this . _nextQueue = [ ] ;
@@ -51,11 +60,15 @@ export class IncrementalGraph {
5160 ) : void {
5261 const { pendingExecutionGroup, incrementalDataRecords } =
5362 successfulExecutionGroup ;
63+ const { deferUsages, path } = pendingExecutionGroup ;
5464
55- const deferredFragmentRecords =
56- pendingExecutionGroup . deferredFragmentRecords ;
57-
58- for ( const deferredFragmentRecord of deferredFragmentRecords ) {
65+ const deferredFragmentRecords : Array < DeferredFragmentRecord > = [ ] ;
66+ for ( const deferUsage of deferUsages ) {
67+ const deferredFragmentRecord = this . _deferredFragmentFactory . get (
68+ deferUsage ,
69+ path ,
70+ ) ;
71+ deferredFragmentRecords . push ( deferredFragmentRecord ) ;
5972 const { pendingExecutionGroups, successfulExecutionGroups } =
6073 deferredFragmentRecord ;
6174 pendingExecutionGroups . delete ( pendingExecutionGroup ) ;
@@ -70,6 +83,26 @@ export class IncrementalGraph {
7083 }
7184 }
7285
86+ getDeepestDeferredFragmentAtRoot (
87+ initialDeferUsage : DeferUsage ,
88+ deferUsages : ReadonlySet < DeferUsage > ,
89+ path : Path | undefined ,
90+ ) : DeferredFragmentRecord {
91+ let bestDeferUsage = initialDeferUsage ;
92+ let maxDepth = initialDeferUsage . depth ;
93+ for ( const deferUsage of deferUsages ) {
94+ if ( deferUsage === initialDeferUsage ) {
95+ continue ;
96+ }
97+ const depth = deferUsage . depth ;
98+ if ( depth > maxDepth ) {
99+ maxDepth = depth ;
100+ bestDeferUsage = deferUsage ;
101+ }
102+ }
103+ return this . _deferredFragmentFactory . get ( bestDeferUsage , path ) ;
104+ }
105+
73106 * currentCompletedBatch ( ) : Generator < IncrementalDataRecordResult > {
74107 let completed ;
75108 while ( ( completed = this . _completedQueue . shift ( ) ) !== undefined ) {
@@ -102,12 +135,20 @@ export class IncrementalGraph {
102135 return this . _rootNodes . size > 0 ;
103136 }
104137
105- completeDeferredFragment ( deferredFragmentRecord : DeferredFragmentRecord ) :
138+ completeDeferredFragment (
139+ deferUsage : DeferUsage ,
140+ path : Path | undefined ,
141+ ) :
106142 | {
143+ deferredFragmentRecord : DeferredFragmentRecord ;
107144 newRootNodes : ReadonlyArray < DeliveryGroup > ;
108145 successfulExecutionGroups : ReadonlyArray < SuccessfulExecutionGroup > ;
109146 }
110147 | undefined {
148+ const deferredFragmentRecord = this . _deferredFragmentFactory . get (
149+ deferUsage ,
150+ path ,
151+ ) ;
111152 if (
112153 ! this . _rootNodes . has ( deferredFragmentRecord ) ||
113154 deferredFragmentRecord . pendingExecutionGroups . size > 0
@@ -119,8 +160,13 @@ export class IncrementalGraph {
119160 ) ;
120161 this . _rootNodes . delete ( deferredFragmentRecord ) ;
121162 for ( const successfulExecutionGroup of successfulExecutionGroups ) {
122- for ( const otherDeferredFragmentRecord of successfulExecutionGroup
123- . pendingExecutionGroup . deferredFragmentRecords ) {
163+ const { deferUsages, path : resultPath } =
164+ successfulExecutionGroup . pendingExecutionGroup ;
165+ for ( const otherDeferUsage of deferUsages ) {
166+ const otherDeferredFragmentRecord = this . _deferredFragmentFactory . get (
167+ otherDeferUsage ,
168+ resultPath ,
169+ ) ;
124170 otherDeferredFragmentRecord . successfulExecutionGroups . delete (
125171 successfulExecutionGroup ,
126172 ) ;
@@ -129,17 +175,22 @@ export class IncrementalGraph {
129175 const newRootNodes = this . _promoteNonEmptyToRoot (
130176 deferredFragmentRecord . children ,
131177 ) ;
132- return { newRootNodes, successfulExecutionGroups } ;
178+ return { deferredFragmentRecord , newRootNodes, successfulExecutionGroups } ;
133179 }
134180
135181 removeDeferredFragment (
136- deferredFragmentRecord : DeferredFragmentRecord ,
137- ) : boolean {
182+ deferUsage : DeferUsage ,
183+ path : Path | undefined ,
184+ ) : DeferredFragmentRecord | undefined {
185+ const deferredFragmentRecord = this . _deferredFragmentFactory . get (
186+ deferUsage ,
187+ path ,
188+ ) ;
138189 if ( ! this . _rootNodes . has ( deferredFragmentRecord ) ) {
139- return false ;
190+ return ;
140191 }
141192 this . _rootNodes . delete ( deferredFragmentRecord ) ;
142- return true ;
193+ return deferredFragmentRecord ;
143194 }
144195
145196 removeStream ( streamRecord : StreamRecord ) : void {
@@ -153,7 +204,12 @@ export class IncrementalGraph {
153204 ) : void {
154205 for ( const incrementalDataRecord of incrementalDataRecords ) {
155206 if ( isPendingExecutionGroup ( incrementalDataRecord ) ) {
156- for ( const deferredFragmentRecord of incrementalDataRecord . deferredFragmentRecords ) {
207+ const { deferUsages, path } = incrementalDataRecord ;
208+ for ( const deferUsage of deferUsages ) {
209+ const deferredFragmentRecord = this . _deferredFragmentFactory . get (
210+ deferUsage ,
211+ path ,
212+ ) ;
157213 this . _addDeferredFragment (
158214 deferredFragmentRecord ,
159215 initialResultChildren ,
@@ -210,9 +266,17 @@ export class IncrementalGraph {
210266 private _completesRootNode (
211267 pendingExecutionGroup : PendingExecutionGroup ,
212268 ) : boolean {
213- return pendingExecutionGroup . deferredFragmentRecords . some (
214- ( deferredFragmentRecord ) => this . _rootNodes . has ( deferredFragmentRecord ) ,
215- ) ;
269+ const { deferUsages, path } = pendingExecutionGroup ;
270+ for ( const deferUsage of deferUsages ) {
271+ const deferredFragmentRecord = this . _deferredFragmentFactory . get (
272+ deferUsage ,
273+ path ,
274+ ) ;
275+ if ( this . _rootNodes . has ( deferredFragmentRecord ) ) {
276+ return true ;
277+ }
278+ }
279+ return false ;
216280 }
217281
218282 private _addDeferredFragment (
@@ -222,12 +286,16 @@ export class IncrementalGraph {
222286 if ( this . _rootNodes . has ( deferredFragmentRecord ) ) {
223287 return ;
224288 }
225- const parent = deferredFragmentRecord . parent ;
226- if ( parent === undefined ) {
289+ const parentDeferUsage = deferredFragmentRecord . parentDeferUsage ;
290+ if ( parentDeferUsage === undefined ) {
227291 invariant ( initialResultChildren !== undefined ) ;
228292 initialResultChildren . add ( deferredFragmentRecord ) ;
229293 return ;
230294 }
295+ const parent = this . _deferredFragmentFactory . get (
296+ parentDeferUsage ,
297+ deferredFragmentRecord . path ,
298+ ) ;
231299 parent . children . add ( deferredFragmentRecord ) ;
232300 this . _addDeferredFragment ( parent , initialResultChildren ) ;
233301 }
0 commit comments