@@ -8,13 +8,7 @@ import type {
8
8
GraphQLFormattedError ,
9
9
} from '../error/GraphQLError.js' ;
10
10
11
- import type {
12
- DeferUsage ,
13
- DeferUsageSet ,
14
- GroupedFieldSet ,
15
- GroupedFieldSetDetails ,
16
- } from './collectFields.js' ;
17
- import type { StreamUsage } from './execute.js' ;
11
+ import type { GroupedFieldSet } from './collectFields.js' ;
18
12
19
13
interface IncrementalUpdate < TData = unknown , TExtensions = ObjMap < unknown > > {
20
14
incremental : ReadonlyArray < IncrementalResult < TData , TExtensions > > ;
@@ -188,112 +182,38 @@ export class IncrementalPublisher {
188
182
this . _reset ( ) ;
189
183
}
190
184
191
- prepareInitialResultRecord ( ) : InitialResultRecord {
192
- return new InitialResultRecord ( ) ;
185
+ reportNewDeferFragmentRecord (
186
+ deferredFragmentRecord : DeferredFragmentRecord ,
187
+ parentIncrementalResultRecord :
188
+ | InitialResultRecord
189
+ | DeferredFragmentRecord
190
+ | StreamItemsRecord ,
191
+ ) : void {
192
+ parentIncrementalResultRecord . children . add ( deferredFragmentRecord ) ;
193
193
}
194
194
195
- prepareNewDeferRecords (
196
- newGroupedFieldSetDetails : Map < DeferUsageSet , GroupedFieldSetDetails > ,
197
- newDeferUsages : ReadonlyArray < DeferUsage > ,
198
- incrementalDataRecord : IncrementalDataRecord ,
199
- deferMap ?: ReadonlyMap < DeferUsage , DeferredFragmentRecord > ,
200
- path ?: Path | undefined ,
201
- ) : {
202
- newDeferMap : ReadonlyMap < DeferUsage , DeferredFragmentRecord > ;
203
- newDeferredGroupedFieldSetRecords : ReadonlyArray < DeferredGroupedFieldSetRecord > ;
204
- } {
205
- let newDeferMap ;
206
- if ( newDeferUsages . length === 0 ) {
207
- newDeferMap = deferMap ?? new Map < DeferUsage , DeferredFragmentRecord > ( ) ;
208
- } else {
209
- newDeferMap =
210
- deferMap === undefined
211
- ? new Map < DeferUsage , DeferredFragmentRecord > ( )
212
- : new Map < DeferUsage , DeferredFragmentRecord > ( deferMap ) ;
213
- for ( const deferUsage of newDeferUsages ) {
214
- const deferredFragmentRecord = new DeferredFragmentRecord ( {
215
- path,
216
- label : deferUsage . label ,
217
- } ) ;
218
-
219
- const parentDeferUsage = deferUsage . ancestors [ 0 ] ;
220
-
221
- const parent =
222
- parentDeferUsage === undefined
223
- ? ( incrementalDataRecord as InitialResultRecord | StreamItemsRecord )
224
- : this . _deferredFragmentRecordFromDeferUsage (
225
- parentDeferUsage ,
226
- newDeferMap ,
227
- ) ;
228
- parent . children . add ( deferredFragmentRecord ) ;
229
-
230
- newDeferMap . set ( deferUsage , deferredFragmentRecord ) ;
231
- }
232
- }
233
-
234
- const newDeferredGroupedFieldSetRecords : Array < DeferredGroupedFieldSetRecord > =
235
- [ ] ;
236
-
237
- for ( const [
238
- newGroupedFieldSetDeferUsages ,
239
- { groupedFieldSet, shouldInitiateDefer } ,
240
- ] of newGroupedFieldSetDetails ) {
241
- const deferredFragmentRecords = this . _getDeferredFragmentRecords (
242
- newGroupedFieldSetDeferUsages ,
243
- newDeferMap ,
195
+ reportNewDeferredGroupedFieldSetRecord (
196
+ deferredGroupedFieldSetRecord : DeferredGroupedFieldSetRecord ,
197
+ ) : void {
198
+ for ( const deferredFragmentRecord of deferredGroupedFieldSetRecord . deferredFragmentRecords ) {
199
+ deferredFragmentRecord . _pending . add ( deferredGroupedFieldSetRecord ) ;
200
+ deferredFragmentRecord . deferredGroupedFieldSetRecords . add (
201
+ deferredGroupedFieldSetRecord ,
244
202
) ;
245
- const deferredGroupedFieldSetRecord = new DeferredGroupedFieldSetRecord ( {
246
- path,
247
- deferredFragmentRecords,
248
- groupedFieldSet,
249
- shouldInitiateDefer,
250
- } ) ;
251
- for ( const deferredFragmentRecord of deferredFragmentRecords ) {
252
- deferredFragmentRecord . _pending . add ( deferredGroupedFieldSetRecord ) ;
253
- deferredFragmentRecord . deferredGroupedFieldSetRecords . add (
254
- deferredGroupedFieldSetRecord ,
255
- ) ;
256
- }
257
- newDeferredGroupedFieldSetRecords . push ( deferredGroupedFieldSetRecord ) ;
258
203
}
259
-
260
- return {
261
- newDeferMap,
262
- newDeferredGroupedFieldSetRecords,
263
- } ;
264
204
}
265
205
266
- prepareNewStreamRecord (
267
- streamUsage : StreamUsage ,
268
- path : Path ,
269
- asyncIterator ?: AsyncIterator < unknown > | undefined ,
270
- ) : StreamRecord {
271
- return new StreamRecord ( {
272
- label : streamUsage . label ,
273
- path,
274
- asyncIterator,
275
- } ) ;
276
- }
277
-
278
- prepareNewStreamItemsRecord (
279
- streamRecord : StreamRecord ,
280
- path : Path | undefined ,
281
- incrementalDataRecord : IncrementalDataRecord ,
282
- ) : StreamItemsRecord {
283
- const streamItemsRecord = new StreamItemsRecord ( {
284
- streamRecord,
285
- path,
286
- } ) ;
287
-
288
- if ( isDeferredGroupedFieldSetRecord ( incrementalDataRecord ) ) {
289
- for ( const parent of incrementalDataRecord . deferredFragmentRecords ) {
206
+ reportNewStreamItemsRecord (
207
+ streamItemsRecord : StreamItemsRecord ,
208
+ parentIncrementalDataRecord : IncrementalDataRecord ,
209
+ ) : void {
210
+ if ( isDeferredGroupedFieldSetRecord ( parentIncrementalDataRecord ) ) {
211
+ for ( const parent of parentIncrementalDataRecord . deferredFragmentRecords ) {
290
212
parent . children . add ( streamItemsRecord ) ;
291
213
}
292
214
} else {
293
- incrementalDataRecord . children . add ( streamItemsRecord ) ;
215
+ parentIncrementalDataRecord . children . add ( streamItemsRecord ) ;
294
216
}
295
-
296
- return streamItemsRecord ;
297
217
}
298
218
299
219
completeDeferredGroupedFieldSet (
@@ -341,6 +261,9 @@ export class IncrementalPublisher {
341
261
streamItemsRecord . streamRecord . errors . push ( error ) ;
342
262
this . setIsFinalRecord ( streamItemsRecord ) ;
343
263
streamItemsRecord . isCompleted = true ;
264
+ streamItemsRecord . streamRecord . earlyReturn ?.( ) . catch ( ( ) => {
265
+ // ignore error
266
+ } ) ;
344
267
this . _release ( streamItemsRecord ) ;
345
268
}
346
269
@@ -418,7 +341,7 @@ export class IncrementalPublisher {
418
341
}
419
342
420
343
streams . forEach ( ( stream ) => {
421
- stream . asyncIterator ?. return ?.( ) . catch ( ( ) => {
344
+ stream . earlyReturn ?.( ) . catch ( ( ) => {
422
345
// ignore error
423
346
} ) ;
424
347
} ) ;
@@ -469,10 +392,10 @@ export class IncrementalPublisher {
469
392
streams . add ( subsequentResultRecord . streamRecord ) ;
470
393
}
471
394
}
472
- const promises : Array < Promise < IteratorResult < unknown > > > = [ ] ;
395
+ const promises : Array < Promise < unknown > > = [ ] ;
473
396
streams . forEach ( ( streamRecord ) => {
474
- if ( streamRecord . asyncIterator ?. return ) {
475
- promises . push ( streamRecord . asyncIterator . return ( ) ) ;
397
+ if ( streamRecord . earlyReturn ) {
398
+ promises . push ( streamRecord . earlyReturn ( ) ) ;
476
399
}
477
400
} ) ;
478
401
await Promise . all ( promises ) ;
@@ -569,31 +492,26 @@ export class IncrementalPublisher {
569
492
this . _publish ( child ) ;
570
493
}
571
494
if ( isStreamItemsRecord ( subsequentResultRecord ) ) {
572
- if ( ! subsequentResultRecord . sent ) {
573
- subsequentResultRecord . sent = true ;
574
- if ( subsequentResultRecord . isFinalRecord ) {
575
- completedResults . push (
576
- this . _completedRecordToResult (
577
- subsequentResultRecord . streamRecord ,
578
- ) ,
579
- ) ;
580
- }
581
- if ( subsequentResultRecord . isCompletedAsyncIterator ) {
582
- // async iterable resolver just finished but there may be pending payloads
583
- continue ;
584
- }
585
- if ( subsequentResultRecord . streamRecord . errors . length > 0 ) {
586
- continue ;
587
- }
588
- const incrementalResult : IncrementalStreamResult = {
589
- items : subsequentResultRecord . items ,
590
- path : subsequentResultRecord . streamRecord . path ,
591
- } ;
592
- if ( subsequentResultRecord . errors . length > 0 ) {
593
- incrementalResult . errors = subsequentResultRecord . errors ;
594
- }
595
- incrementalResults . push ( incrementalResult ) ;
495
+ if ( subsequentResultRecord . isFinalRecord ) {
496
+ completedResults . push (
497
+ this . _completedRecordToResult ( subsequentResultRecord . streamRecord ) ,
498
+ ) ;
499
+ }
500
+ if ( subsequentResultRecord . isCompletedAsyncIterator ) {
501
+ // async iterable resolver just finished but there may be pending payloads
502
+ continue ;
596
503
}
504
+ if ( subsequentResultRecord . streamRecord . errors . length > 0 ) {
505
+ continue ;
506
+ }
507
+ const incrementalResult : IncrementalStreamResult = {
508
+ items : subsequentResultRecord . items ,
509
+ path : subsequentResultRecord . streamRecord . path ,
510
+ } ;
511
+ if ( subsequentResultRecord . errors . length > 0 ) {
512
+ incrementalResult . errors = subsequentResultRecord . errors ;
513
+ }
514
+ incrementalResults . push ( incrementalResult ) ;
597
515
} else {
598
516
completedResults . push (
599
517
this . _completedRecordToResult ( subsequentResultRecord ) ,
@@ -639,23 +557,6 @@ export class IncrementalPublisher {
639
557
return result ;
640
558
}
641
559
642
- private _getDeferredFragmentRecords (
643
- deferUsages : DeferUsageSet ,
644
- deferMap : ReadonlyMap < DeferUsage , DeferredFragmentRecord > ,
645
- ) : ReadonlyArray < DeferredFragmentRecord > {
646
- return Array . from ( deferUsages ) . map ( ( deferUsage ) =>
647
- this . _deferredFragmentRecordFromDeferUsage ( deferUsage , deferMap ) ,
648
- ) ;
649
- }
650
-
651
- private _deferredFragmentRecordFromDeferUsage (
652
- deferUsage : DeferUsage ,
653
- deferMap : ReadonlyMap < DeferUsage , DeferredFragmentRecord > ,
654
- ) : DeferredFragmentRecord {
655
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
656
- return deferMap . get ( deferUsage ) ! ;
657
- }
658
-
659
560
private _publish ( subsequentResultRecord : SubsequentResultRecord ) : void {
660
561
if ( isStreamItemsRecord ( subsequentResultRecord ) ) {
661
562
if ( subsequentResultRecord . isCompleted ) {
@@ -734,6 +635,18 @@ export class IncrementalPublisher {
734
635
}
735
636
}
736
637
638
+ function isDeferredGroupedFieldSetRecord (
639
+ incrementalDataRecord : unknown ,
640
+ ) : incrementalDataRecord is DeferredGroupedFieldSetRecord {
641
+ return incrementalDataRecord instanceof DeferredGroupedFieldSetRecord ;
642
+ }
643
+
644
+ function isStreamItemsRecord (
645
+ subsequentResultRecord : unknown ,
646
+ ) : subsequentResultRecord is StreamItemsRecord {
647
+ return subsequentResultRecord instanceof StreamItemsRecord ;
648
+ }
649
+
737
650
/** @internal */
738
651
export class InitialResultRecord {
739
652
errors : Array < GraphQLError > ;
@@ -795,16 +708,16 @@ export class StreamRecord {
795
708
label : string | undefined ;
796
709
path : ReadonlyArray < string | number > ;
797
710
errors : Array < GraphQLError > ;
798
- asyncIterator ?: AsyncIterator < unknown > | undefined ;
711
+ earlyReturn ?: ( ( ) => Promise < unknown > ) | undefined ;
799
712
constructor ( opts : {
800
713
label : string | undefined ;
801
714
path : Path ;
802
- asyncIterator ?: AsyncIterator < unknown > | undefined ;
715
+ earlyReturn ?: ( ( ) => Promise < unknown > ) | undefined ;
803
716
} ) {
804
717
this . label = opts . label ;
805
718
this . path = pathToArray ( opts . path ) ;
806
719
this . errors = [ ] ;
807
- this . asyncIterator = opts . asyncIterator ;
720
+ this . earlyReturn = opts . earlyReturn ;
808
721
}
809
722
}
810
723
@@ -819,7 +732,6 @@ export class StreamItemsRecord {
819
732
isCompletedAsyncIterator ?: boolean ;
820
733
isCompleted : boolean ;
821
734
filtered : boolean ;
822
- sent : boolean ;
823
735
824
736
constructor ( opts : { streamRecord : StreamRecord ; path : Path | undefined } ) {
825
737
this . streamRecord = opts . streamRecord ;
@@ -829,7 +741,6 @@ export class StreamItemsRecord {
829
741
this . isCompleted = false ;
830
742
this . filtered = false ;
831
743
this . items = [ ] ;
832
- this . sent = false ;
833
744
}
834
745
}
835
746
@@ -839,15 +750,3 @@ export type IncrementalDataRecord =
839
750
| StreamItemsRecord ;
840
751
841
752
type SubsequentResultRecord = DeferredFragmentRecord | StreamItemsRecord ;
842
-
843
- function isDeferredGroupedFieldSetRecord (
844
- incrementalDataRecord : unknown ,
845
- ) : incrementalDataRecord is DeferredGroupedFieldSetRecord {
846
- return incrementalDataRecord instanceof DeferredGroupedFieldSetRecord ;
847
- }
848
-
849
- function isStreamItemsRecord (
850
- subsequentResultRecord : unknown ,
851
- ) : subsequentResultRecord is StreamItemsRecord {
852
- return subsequentResultRecord instanceof StreamItemsRecord ;
853
- }
0 commit comments