@@ -1347,12 +1347,12 @@ async function completeAsyncIteratorValue(
1347
1347
index ,
1348
1348
iterator ,
1349
1349
exeContext ,
1350
+ itemType ,
1350
1351
getStreamedFieldGroup ( fieldGroup , streamUsage ) ,
1351
1352
info ,
1352
- itemType ,
1353
1353
path ,
1354
- streamContext ,
1355
1354
deferMap ,
1355
+ streamContext ,
1356
1356
parentRecords ,
1357
1357
) ;
1358
1358
break ;
@@ -2280,99 +2280,17 @@ function executeStreamField(
2280
2280
return currentParents ;
2281
2281
}
2282
2282
2283
- async function executeStreamAsyncIteratorItem (
2284
- iterator : AsyncIterator < unknown > ,
2285
- exeContext : ExecutionContext ,
2286
- fieldGroup : FieldGroup ,
2287
- info : GraphQLResolveInfo ,
2288
- itemType : GraphQLOutputType ,
2289
- streamRecord : StreamRecord ,
2290
- itemPath : Path < FieldGroup > ,
2291
- deferMap : Map < DeferUsage , DeferredFragmentRecord > ,
2292
- parentRecords : Array < AsyncPayloadRecord > ,
2293
- ) : Promise < IteratorResult < unknown > > {
2294
- let item ;
2295
- try {
2296
- const iteration = await iterator . next ( ) ;
2297
- if ( ! exeContext . streams . has ( streamRecord . streamContext ) ) {
2298
- streamRecord . remove ( ) ;
2299
- return { done : true , value : undefined } ;
2300
- }
2301
- const { value, done } = iteration ;
2302
- if ( done ) {
2303
- streamRecord . remove ( ) ;
2304
- return { done, value : undefined } ;
2305
- }
2306
- item = value ;
2307
- } catch ( rawError ) {
2308
- handleFieldError (
2309
- rawError ,
2310
- exeContext ,
2311
- itemType ,
2312
- fieldGroup ,
2313
- itemPath ,
2314
- deferMap ,
2315
- streamRecord ,
2316
- ) ;
2317
- // don't continue if iterator throws
2318
- return { done : true , value : null } ;
2319
- }
2320
- let completedItem ;
2321
- try {
2322
- completedItem = completeValue (
2323
- exeContext ,
2324
- itemType ,
2325
- fieldGroup ,
2326
- info ,
2327
- itemPath ,
2328
- item ,
2329
- deferMap ,
2330
- streamRecord ,
2331
- parentRecords ,
2332
- ) ;
2333
-
2334
- if ( isPromise ( completedItem ) ) {
2335
- completedItem = completedItem . then ( undefined , ( rawError ) => {
2336
- handleFieldError (
2337
- rawError ,
2338
- exeContext ,
2339
- itemType ,
2340
- fieldGroup ,
2341
- itemPath ,
2342
- deferMap ,
2343
- streamRecord ,
2344
- ) ;
2345
- filterSubsequentPayloads ( exeContext , itemPath , parentRecords ) ;
2346
- return null ;
2347
- } ) ;
2348
- }
2349
- return { done : false , value : completedItem } ;
2350
- } catch ( rawError ) {
2351
- handleFieldError (
2352
- rawError ,
2353
- exeContext ,
2354
- itemType ,
2355
- fieldGroup ,
2356
- itemPath ,
2357
- deferMap ,
2358
- streamRecord ,
2359
- ) ;
2360
- filterSubsequentPayloads ( exeContext , itemPath , parentRecords ) ;
2361
- return { done : false , value : null } ;
2362
- }
2363
- }
2364
-
2365
2283
async function executeStreamAsyncIterator (
2366
2284
initialIndex : number ,
2367
2285
iterator : AsyncIterator < unknown > ,
2368
2286
exeContext : ExecutionContext ,
2287
+ itemType : GraphQLOutputType ,
2369
2288
fieldGroup : FieldGroup ,
2370
2289
info : GraphQLResolveInfo ,
2371
- itemType : GraphQLOutputType ,
2372
2290
path : Path < FieldGroup > ,
2373
- streamContext : StreamContext ,
2374
2291
deferMap : Map < DeferUsage , DeferredFragmentRecord > ,
2375
- parents ?: Array < AsyncPayloadRecord > | undefined ,
2292
+ streamContext : StreamContext ,
2293
+ parents : Array < AsyncPayloadRecord > | undefined ,
2376
2294
) : Promise < void > {
2377
2295
let index = initialIndex ;
2378
2296
let currentParents = parents ;
@@ -2387,55 +2305,135 @@ async function executeStreamAsyncIterator(
2387
2305
} ) ;
2388
2306
currentParents = [ streamRecord ] ;
2389
2307
2390
- let iteration ;
2308
+ currentParents = [ streamRecord ] ;
2309
+
2310
+ let item ;
2391
2311
try {
2392
2312
// eslint-disable-next-line no-await-in-loop
2393
- iteration = await executeStreamAsyncIteratorItem (
2394
- iterator ,
2313
+ const iteration = await iterator . next ( ) ;
2314
+ if ( iteration . done ) {
2315
+ streamRecord . remove ( ) ;
2316
+ return ;
2317
+ }
2318
+ item = iteration . value ;
2319
+ } catch ( rawError ) {
2320
+ handleFieldError (
2321
+ rawError ,
2395
2322
exeContext ,
2396
- fieldGroup ,
2397
- info ,
2398
2323
itemType ,
2399
- streamRecord ,
2324
+ fieldGroup ,
2400
2325
itemPath ,
2401
2326
deferMap ,
2402
- currentParents ,
2327
+ streamRecord ,
2403
2328
) ;
2329
+ // don't continue if iterator throws
2330
+ streamRecord . addItems ( [ null ] ) ;
2331
+ exeContext . streams . delete ( streamContext ) ;
2332
+ return ;
2333
+ }
2334
+
2335
+ try {
2336
+ let completedItem ;
2337
+ try {
2338
+ completedItem = completeValue (
2339
+ exeContext ,
2340
+ itemType ,
2341
+ fieldGroup ,
2342
+ info ,
2343
+ itemPath ,
2344
+ item ,
2345
+ deferMap ,
2346
+ streamRecord ,
2347
+ currentParents ,
2348
+ ) ;
2349
+
2350
+ if ( isPromise ( completedItem ) ) {
2351
+ // eslint-disable-next-line @typescript-eslint/no-floating-promises
2352
+ handlePromisedStreamResult (
2353
+ completedItem ,
2354
+ streamRecord ,
2355
+ exeContext ,
2356
+ itemType ,
2357
+ fieldGroup ,
2358
+ path ,
2359
+ itemPath ,
2360
+ deferMap ,
2361
+ streamContext ,
2362
+ ) ;
2363
+ } else {
2364
+ streamRecord . addItems ( [ completedItem ] ) ;
2365
+ }
2366
+ } catch ( rawError ) {
2367
+ handleFieldError (
2368
+ rawError ,
2369
+ exeContext ,
2370
+ itemType ,
2371
+ fieldGroup ,
2372
+ itemPath ,
2373
+ deferMap ,
2374
+ streamRecord ,
2375
+ ) ;
2376
+ filterSubsequentPayloads ( exeContext , itemPath , currentParents ) ;
2377
+ streamRecord . addItems ( [ null ] ) ;
2378
+ }
2404
2379
} catch ( error ) {
2405
- streamRecord . errors . push ( error ) ;
2380
+ if ( fieldGroup . inInitialResult ) {
2381
+ streamRecord . errors . push ( error ) ;
2382
+ }
2383
+ returnStreamIteratorIgnoringError ( streamContext ) ;
2384
+ exeContext . streams . delete ( streamContext ) ;
2406
2385
filterSubsequentPayloads ( exeContext , path , currentParents ) ;
2407
2386
streamRecord . addItems ( null ) ;
2408
- // entire stream has errored and bubbled upwards
2409
- if ( iterator ?. return ) {
2410
- iterator . return ( ) . catch ( ( ) => {
2411
- // ignore errors
2412
- } ) ;
2413
- }
2414
2387
return ;
2415
2388
}
2416
2389
2417
- const { done, value : completedItem } = iteration ;
2418
-
2419
- let completedItems : PromiseOrValue < Array < unknown > | null > ;
2420
- if ( isPromise ( completedItem ) ) {
2421
- completedItems = completedItem . then (
2422
- ( value ) => [ value ] ,
2423
- ( error ) => {
2424
- streamRecord . errors . push ( error ) ;
2425
- filterSubsequentPayloads ( exeContext , path , [ streamRecord ] ) ;
2426
- return null ;
2427
- } ,
2428
- ) ;
2429
- } else {
2430
- completedItems = [ completedItem ] ;
2390
+ if ( ! exeContext . streams . has ( streamContext ) ) {
2391
+ // stream was filtered
2392
+ returnStreamIteratorIgnoringError ( streamContext ) ;
2393
+ break ;
2431
2394
}
2432
2395
2433
- streamRecord . addItems ( completedItems ) ;
2396
+ index ++ ;
2397
+ }
2398
+ }
2434
2399
2435
- if ( done ) {
2436
- break ;
2400
+ async function handlePromisedStreamResult (
2401
+ result : Promise < unknown > ,
2402
+ streamRecord : StreamRecord ,
2403
+ exeContext : ExecutionContext ,
2404
+ itemType : GraphQLOutputType ,
2405
+ fieldGroup : FieldGroup ,
2406
+ path : Path < FieldGroup > ,
2407
+ itemPath : Path < FieldGroup > ,
2408
+ deferMap : Map < DeferUsage , DeferredFragmentRecord > ,
2409
+ streamContext : StreamContext ,
2410
+ ) : Promise < void > {
2411
+ try {
2412
+ let resolved ;
2413
+ try {
2414
+ resolved = await result ;
2415
+ } catch ( rawError ) {
2416
+ handleFieldError (
2417
+ rawError ,
2418
+ exeContext ,
2419
+ itemType ,
2420
+ fieldGroup ,
2421
+ itemPath ,
2422
+ deferMap ,
2423
+ streamRecord ,
2424
+ ) ;
2425
+ filterSubsequentPayloads ( exeContext , itemPath , [ streamRecord ] ) ;
2426
+ resolved = null ;
2437
2427
}
2438
- index ++ ;
2428
+ streamRecord . addItems ( [ resolved ] ) ;
2429
+ } catch ( error ) {
2430
+ if ( fieldGroup . inInitialResult ) {
2431
+ streamRecord . errors . push ( error ) ;
2432
+ }
2433
+ returnStreamIteratorIgnoringError ( streamContext ) ;
2434
+ exeContext . streams . delete ( streamContext ) ;
2435
+ filterSubsequentPayloads ( exeContext , path , [ streamRecord ] ) ;
2436
+ streamRecord . addItems ( null ) ;
2439
2437
}
2440
2438
}
2441
2439
@@ -2533,10 +2531,6 @@ function yieldSubsequentPayloads(
2533
2531
const incremental = getCompletedIncrementalResults ( exeContext ) ;
2534
2532
const hasNext = exeContext . subsequentPayloads . size > 0 ;
2535
2533
2536
- if ( ! incremental . length && hasNext ) {
2537
- return next ( ) ;
2538
- }
2539
-
2540
2534
if ( ! hasNext ) {
2541
2535
isDone = true ;
2542
2536
}
0 commit comments