66 ObjectDefineProperties,
77 ObjectSetPrototypeOf,
88 PromisePrototypeThen,
9- PromiseResolve,
109 SymbolToStringTag,
1110 Symbol,
1211} = primordials ;
@@ -47,6 +46,7 @@ const {
4746 nonOpFlush,
4847 kType,
4948 kState,
49+ nonOpCancel,
5050} = require ( 'internal/webstreams/util' ) ;
5151
5252const {
@@ -384,8 +384,7 @@ function initializeTransformStream(
384384 return transformStreamDefaultSourcePullAlgorithm ( stream ) ;
385385 } ,
386386 cancel ( reason ) {
387- transformStreamErrorWritableAndUnblockWrite ( stream , reason ) ;
388- return PromiseResolve ( ) ;
387+ return transformStreamDefaultSourceCancelAlgorithm ( stream , reason ) ;
389388 } ,
390389 } , {
391390 highWaterMark : readableHighWaterMark ,
@@ -427,6 +426,10 @@ function transformStreamErrorWritableAndUnblockWrite(stream, error) {
427426 writableStreamDefaultControllerErrorIfNeeded (
428427 writable [ kState ] . controller ,
429428 error ) ;
429+ transformStreamUnblockWrite ( stream ) ;
430+ }
431+
432+ function transformStreamUnblockWrite ( stream ) {
430433 if ( stream [ kState ] . backpressure )
431434 transformStreamSetBackpressure ( stream , false ) ;
432435}
@@ -443,13 +446,15 @@ function setupTransformStreamDefaultController(
443446 stream ,
444447 controller ,
445448 transformAlgorithm ,
446- flushAlgorithm ) {
449+ flushAlgorithm ,
450+ cancelAlgorithm ) {
447451 assert ( isTransformStream ( stream ) ) ;
448452 assert ( stream [ kState ] . controller === undefined ) ;
449453 controller [ kState ] = {
450454 stream,
451455 transformAlgorithm,
452456 flushAlgorithm,
457+ cancelAlgorithm,
453458 } ;
454459 stream [ kState ] . controller = controller ;
455460}
@@ -460,21 +465,26 @@ function setupTransformStreamDefaultControllerFromTransformer(
460465 const controller = new TransformStreamDefaultController ( kSkipThrow ) ;
461466 const transform = transformer ?. transform || defaultTransformAlgorithm ;
462467 const flush = transformer ?. flush || nonOpFlush ;
468+ const cancel = transformer ?. cancel || nonOpCancel ;
463469 const transformAlgorithm =
464470 FunctionPrototypeBind ( transform , transformer ) ;
465471 const flushAlgorithm =
466472 FunctionPrototypeBind ( flush , transformer ) ;
473+ const cancelAlgorithm =
474+ FunctionPrototypeBind ( cancel , transformer ) ;
467475
468476 setupTransformStreamDefaultController (
469477 stream ,
470478 controller ,
471479 transformAlgorithm ,
472- flushAlgorithm ) ;
480+ flushAlgorithm ,
481+ cancelAlgorithm ) ;
473482}
474483
475484function transformStreamDefaultControllerClearAlgorithms ( controller ) {
476485 controller [ kState ] . transformAlgorithm = undefined ;
477486 controller [ kState ] . flushAlgorithm = undefined ;
487+ controller [ kState ] . cancelAlgorithm = undefined ;
478488}
479489
480490function transformStreamDefaultControllerEnqueue ( controller , chunk ) {
@@ -563,7 +573,40 @@ function transformStreamDefaultSinkWriteAlgorithm(stream, chunk) {
563573}
564574
565575async function transformStreamDefaultSinkAbortAlgorithm ( stream , reason ) {
566- transformStreamError ( stream , reason ) ;
576+ const {
577+ controller,
578+ readable,
579+ } = stream [ kState ] ;
580+
581+ if ( controller [ kState ] . finishPromise !== undefined ) {
582+ return controller [ kState ] . finishPromise ;
583+ }
584+
585+ const { promise, resolve, reject } = createDeferredPromise ( ) ;
586+ controller [ kState ] . finishPromise = promise ;
587+ const cancelPromise = ensureIsPromise (
588+ controller [ kState ] . cancelAlgorithm ,
589+ controller ,
590+ reason ) ;
591+ transformStreamDefaultControllerClearAlgorithms ( controller ) ;
592+
593+ PromisePrototypeThen (
594+ cancelPromise ,
595+ ( ) => {
596+ if ( readable [ kState ] . state === 'errored' )
597+ reject ( readable [ kState ] . storedError ) ;
598+ else {
599+ readableStreamDefaultControllerError ( readable [ kState ] . controller , reason ) ;
600+ resolve ( ) ;
601+ }
602+ } ,
603+ ( error ) => {
604+ readableStreamDefaultControllerError ( readable [ kState ] . controller , error ) ;
605+ reject ( error ) ;
606+ } ,
607+ ) ;
608+
609+ return controller [ kState ] . finishPromise ;
567610}
568611
569612function transformStreamDefaultSinkCloseAlgorithm ( stream ) {
@@ -572,23 +615,32 @@ function transformStreamDefaultSinkCloseAlgorithm(stream) {
572615 controller,
573616 } = stream [ kState ] ;
574617
618+ if ( controller [ kState ] . finishPromise !== undefined ) {
619+ return controller [ kState ] . finishPromise ;
620+ }
621+ const { promise, resolve, reject } = createDeferredPromise ( ) ;
622+ controller [ kState ] . finishPromise = promise ;
575623 const flushPromise =
576624 ensureIsPromise (
577625 controller [ kState ] . flushAlgorithm ,
578626 controller ,
579627 controller ) ;
580628 transformStreamDefaultControllerClearAlgorithms ( controller ) ;
581- return PromisePrototypeThen (
629+ PromisePrototypeThen (
582630 flushPromise ,
583631 ( ) => {
584632 if ( readable [ kState ] . state === 'errored' )
585- throw readable [ kState ] . storedError ;
586- readableStreamDefaultControllerClose ( readable [ kState ] . controller ) ;
633+ reject ( readable [ kState ] . storedError ) ;
634+ else {
635+ readableStreamDefaultControllerClose ( readable [ kState ] . controller ) ;
636+ resolve ( ) ;
637+ }
587638 } ,
588639 ( error ) => {
589- transformStreamError ( stream , error ) ;
590- throw readable [ kState ] . storedError ;
640+ readableStreamDefaultControllerError ( readable [ kState ] . controller , error ) ;
641+ reject ( error ) ;
591642 } ) ;
643+ return controller [ kState ] . finishPromise ;
592644}
593645
594646function transformStreamDefaultSourcePullAlgorithm ( stream ) {
@@ -598,6 +650,48 @@ function transformStreamDefaultSourcePullAlgorithm(stream) {
598650 return stream [ kState ] . backpressureChange . promise ;
599651}
600652
653+ function transformStreamDefaultSourceCancelAlgorithm ( stream , reason ) {
654+ const {
655+ controller,
656+ writable,
657+ } = stream [ kState ] ;
658+
659+ if ( controller [ kState ] . finishPromise !== undefined ) {
660+ return controller [ kState ] . finishPromise ;
661+ }
662+
663+ const { promise, resolve, reject } = createDeferredPromise ( ) ;
664+ controller [ kState ] . finishPromise = promise ;
665+ const cancelPromise = ensureIsPromise (
666+ controller [ kState ] . cancelAlgorithm ,
667+ controller ,
668+ reason ) ;
669+ transformStreamDefaultControllerClearAlgorithms ( controller ) ;
670+
671+ PromisePrototypeThen ( cancelPromise ,
672+ ( ) => {
673+ if ( writable [ kState ] . state === 'errored' )
674+ reject ( writable [ kState ] . storedError ) ;
675+ else {
676+ writableStreamDefaultControllerErrorIfNeeded (
677+ writable [ kState ] . controller ,
678+ reason ) ;
679+ transformStreamUnblockWrite ( stream ) ;
680+ resolve ( ) ;
681+ }
682+ } ,
683+ ( error ) => {
684+ writableStreamDefaultControllerErrorIfNeeded (
685+ writable [ kState ] . controller ,
686+ error ) ;
687+ transformStreamUnblockWrite ( stream ) ;
688+ reject ( error ) ;
689+ } ,
690+ ) ;
691+
692+ return controller [ kState ] . finishPromise ;
693+ }
694+
601695module . exports = {
602696 TransformStream,
603697 TransformStreamDefaultController,
0 commit comments