@@ -431,56 +431,82 @@ class TracingChannel {
431431 } ) ;
432432 }
433433
434- * traceGenerator ( fn , context = { } , thisArg , ...args ) {
434+ traceIterator ( fn , context = { } , thisArg , ...args ) {
435435 if ( ! this . hasSubscribers ) {
436436 return ReflectApply ( fn , thisArg , args ) ;
437437 }
438438
439- const { start, end, asyncStart, asyncEnd, error } = this ;
439+ const { channel , start, end, asyncStart, asyncEnd, error } = this ;
440440
441- if ( ! this . #generatorChannel ) {
442- this . #generatorChannel = this . tracingChannel ( {
443- start : this . channel ( start . name . slice ( 0 , - 6 ) + ':next:start' ) ,
444- end : this . channel ( end . name . slice ( 0 , - 4 ) + ':next:end' ) ,
445- asyncStart : this . channel ( asyncStart . name . slice ( 0 , - 11 ) + ':next:asyncStart' ) ,
446- asyncEnd : this . channel ( asyncEnd . name . slice ( 0 , - 9 ) + ':next:asyncEnd' ) ,
447- error : this . channel ( error . name . slice ( 0 , - 6 ) + ':next:error' ) ,
441+ if ( ! this . #nextChannel ) {
442+ this . #nextChannel = this . tracingChannel ( {
443+ start : channel ( start . name . slice ( 0 , - 6 ) + ':next:start' ) ,
444+ end : channel ( end . name . slice ( 0 , - 4 ) + ':next:end' ) ,
445+ asyncStart : channel ( asyncStart . name . slice ( 0 , - 11 ) + ':next:asyncStart' ) ,
446+ asyncEnd : channel ( asyncEnd . name . slice ( 0 , - 9 ) + ':next:asyncEnd' ) ,
447+ error : channel ( error . name . slice ( 0 , - 6 ) + ':next:error' ) ,
448448 } ) ;
449449 }
450450
451- const gen = this . traceSync ( fn , context , thisArg , ...args ) ;
451+ const iter = this . #traceMaybePromise( fn , context , thisArg , ...args ) ;
452+
453+ return iter instanceof Promise
454+ ? iter . then ( ( iter , method ) => {
455+ const { next : iterNext , return : iterReturn , throw : iterThrow } = iter ;
452456
453- gen . next = ( ...args ) => this . traceSync ( gen . next , context , gen , ...args ) ;
454- gen . return = ( ...args ) => this . traceSync ( gen . return , context , gen , ...args ) ;
455- gen . throw = ( ...args ) => this . traceSync ( gen . throw , context , gen , ...args ) ;
457+ iter . next = ( ...args ) =>
458+ this . #nextChannel. #traceMaybePromise( iterNext , ctx , iter , ...args ) ;
459+ iter . return = ( ...args ) =>
460+ this . #nextChannel. #traceMaybePromise( iterReturn , ctx , iter , ...args ) ;
461+ iter . throw = ( ...args ) =>
462+ this . #nextChannel. #traceMaybePromise( iterThrow , ctx , iter , ...args ) ;
456463
457- yield * gen ;
464+ return iter ;
465+ } )
466+ : iter ;
458467 }
459468
460- async * traceAsyncGenerator ( fn , context = { } , thisArg , ...args ) {
469+ #traceMaybePromise ( fn , context = { } , thisArg , ...args ) {
461470 if ( ! this . hasSubscribers ) {
462471 return ReflectApply ( fn , thisArg , args ) ;
463472 }
464473
465474 const { start, end, asyncStart, asyncEnd, error } = this ;
466475
467- if ( ! this . #generatorChannel) {
468- this . #generatorChannel = this . tracingChannel ( {
469- start : this . channel ( start . name . slice ( 0 , - 6 ) + ':next:start' ) ,
470- end : this . channel ( end . name . slice ( 0 , - 4 ) + ':next:end' ) ,
471- asyncStart : this . channel ( asyncStart . name . slice ( 0 , - 11 ) + ':next:asyncStart' ) ,
472- asyncEnd : this . channel ( asyncEnd . name . slice ( 0 , - 9 ) + ':next:asyncEnd' ) ,
473- error : this . channel ( error . name . slice ( 0 , - 6 ) + ':next:error' ) ,
474- } ) ;
476+ function reject ( err ) {
477+ context . error = err ;
478+ error . publish ( context ) ;
479+ asyncStart . publish ( context ) ;
480+ // TODO: Is there a way to have asyncEnd _after_ the continuation?
481+ asyncEnd . publish ( context ) ;
482+ return PromiseReject ( err ) ;
475483 }
476484
477- const gen = this . traceSync ( fn , context , thisArg , ...args ) ;
478-
479- gen . next = ( ...args ) => this . tracePromise ( gen . next , context , gen , ...args ) ;
480- gen . return = ( ...args ) => this . tracePromise ( gen . return , context , gen , ...args ) ;
481- gen . throw = ( ...args ) => this . tracePromise ( gen . throw , context , gen , ...args ) ;
485+ function resolve ( result ) {
486+ context . result = result ;
487+ asyncStart . publish ( context ) ;
488+ // TODO: Is there a way to have asyncEnd _after_ the continuation?
489+ asyncEnd . publish ( context ) ;
490+ return result ;
491+ }
482492
483- yield * gen ;
493+ return start . runStores ( context , ( ) => {
494+ try {
495+ const result = ReflectApply ( fn , thisArg , args ) ;
496+ // TODO: Should tracePromise just always do this?
497+ if ( ! ( result instanceof Promise ) ) {
498+ context . result = result
499+ return result
500+ }
501+ return PromisePrototypeThen ( result , resolve , reject ) ;
502+ } catch ( err ) {
503+ context . error = err ;
504+ error . publish ( context ) ;
505+ throw err ;
506+ } finally {
507+ end . publish ( context ) ;
508+ }
509+ } ) ;
484510 }
485511}
486512
0 commit comments