@@ -1418,41 +1418,70 @@ function invalidReturnTypeError(
1418
1418
) ;
1419
1419
}
1420
1420
1421
+ /**
1422
+ * Instantiates new DeferredFragmentRecords for the given path within an
1423
+ * incremental data record, returning an updated map of DeferUsage
1424
+ * objects to DeferredFragmentRecords.
1425
+ *
1426
+ * Note: As defer directives may be used with operations returning lists,
1427
+ * a DeferUsage object may correspond to many DeferredFragmentRecords.
1428
+ *
1429
+ * DeferredFragmentRecord creation includes the following steps:
1430
+ * 1. The new DeferredFragmentRecord is instantiated at the given path.
1431
+ * 2. The parent result record is calculated from the given incremental data
1432
+ * record.
1433
+ * 3. The IncrementalPublisher is notified that a new DeferredFragmentRecord
1434
+ * with the calculated parent has been added; the record will be released only
1435
+ * after the parent has completed.
1436
+ *
1437
+ */
1421
1438
function addNewDeferredFragments (
1422
1439
incrementalPublisher : IncrementalPublisher ,
1423
1440
newDeferUsages : ReadonlyArray < DeferUsage > ,
1424
1441
incrementalDataRecord : IncrementalDataRecord ,
1425
1442
deferMap ?: ReadonlyMap < DeferUsage , DeferredFragmentRecord > ,
1426
1443
path ?: Path | undefined ,
1427
1444
) : ReadonlyMap < DeferUsage , DeferredFragmentRecord > {
1428
- let newDeferMap ;
1429
1445
if ( newDeferUsages . length === 0 ) {
1430
- newDeferMap = deferMap ?? new Map < DeferUsage , DeferredFragmentRecord > ( ) ;
1431
- } else {
1432
- newDeferMap =
1433
- deferMap === undefined
1434
- ? new Map < DeferUsage , DeferredFragmentRecord > ( )
1435
- : new Map < DeferUsage , DeferredFragmentRecord > ( deferMap ) ;
1436
- for ( const deferUsage of newDeferUsages ) {
1437
- const parentDeferUsage = deferUsage . ancestors [ 0 ] ;
1438
-
1439
- const parent =
1440
- parentDeferUsage === undefined
1441
- ? ( incrementalDataRecord as InitialResultRecord | StreamItemsRecord )
1442
- : deferredFragmentRecordFromDeferUsage ( parentDeferUsage , newDeferMap ) ;
1443
-
1444
- const deferredFragmentRecord = new DeferredFragmentRecord ( {
1445
- path,
1446
- label : deferUsage . label ,
1447
- } ) ;
1446
+ // Given no DeferUsages, return the existing map, creating one if necessary.
1447
+ return deferMap ?? new Map < DeferUsage , DeferredFragmentRecord > ( ) ;
1448
+ }
1448
1449
1449
- incrementalPublisher . reportNewDeferFragmentRecord (
1450
- deferredFragmentRecord ,
1451
- parent ,
1452
- ) ;
1450
+ // Create a copy of the old map.
1451
+ const newDeferMap =
1452
+ deferMap === undefined
1453
+ ? new Map < DeferUsage , DeferredFragmentRecord > ( )
1454
+ : new Map < DeferUsage , DeferredFragmentRecord > ( deferMap ) ;
1455
+
1456
+ // For each new deferUsage object:
1457
+ for ( const newDeferUsage of newDeferUsages ) {
1458
+ // DeferUsage objects track their parent targets; the immediate parent is always the first member of this list.
1459
+ const parentTarget = newDeferUsage . ancestors [ 0 ] ;
1460
+
1461
+ // If the parent target is defined, the parent target is a DeferUsage object and
1462
+ // the parent result record is the DeferredFragmentRecord corresponding to that DeferUsage.
1463
+ // If the parent target is not defined, the parent result record is either:
1464
+ // - the InitialResultRecord, or
1465
+ // - a StreamItemsRecord, as `@defer` may be nested under `@stream`.
1466
+ const parent =
1467
+ parentTarget === undefined
1468
+ ? ( incrementalDataRecord as InitialResultRecord | StreamItemsRecord )
1469
+ : deferredFragmentRecordFromDeferUsage ( parentTarget , newDeferMap ) ;
1470
+
1471
+ // Instantiate the new record.
1472
+ const deferredFragmentRecord = new DeferredFragmentRecord ( {
1473
+ path,
1474
+ label : newDeferUsage . label ,
1475
+ } ) ;
1453
1476
1454
- newDeferMap . set ( deferUsage , deferredFragmentRecord ) ;
1455
- }
1477
+ // Report the new record to the Incremental Publisher.
1478
+ incrementalPublisher . reportNewDeferFragmentRecord (
1479
+ deferredFragmentRecord ,
1480
+ parent ,
1481
+ ) ;
1482
+
1483
+ // Update the map.
1484
+ newDeferMap . set ( newDeferUsage , deferredFragmentRecord ) ;
1456
1485
}
1457
1486
1458
1487
return newDeferMap ;
0 commit comments