@@ -317,6 +317,7 @@ const _controller = Symbol("[[controller]]");
317317const _detached = Symbol ( "[[Detached]]" ) ;
318318const _disturbed = Symbol ( "[[disturbed]]" ) ;
319319const _errorSteps = Symbol ( "[[ErrorSteps]]" ) ;
320+ const _finishPromise = Symbol ( "[[finishPromise]]" ) ;
320321const _flushAlgorithm = Symbol ( "[[flushAlgorithm]]" ) ;
321322const _globalObject = Symbol ( "[[globalObject]]" ) ;
322323const _highWaterMark = Symbol ( "[[highWaterMark]]" ) ;
@@ -609,8 +610,7 @@ function initializeTransformStream(
609610 }
610611
611612 function cancelAlgorithm ( reason ) {
612- transformStreamErrorWritableAndUnblockWrite ( stream , reason ) ;
613- return resolvePromiseWith ( undefined ) ;
613+ return transformStreamDefaultSourceCancelAlgorithm ( stream , reason ) ;
614614 }
615615
616616 stream [ _readable ] = createReadableStream (
@@ -3690,19 +3690,22 @@ function setUpReadableStreamDefaultReader(reader, stream) {
36903690 * @param {TransformStreamDefaultController<O> } controller
36913691 * @param {(chunk: O, controller: TransformStreamDefaultController<O>) => Promise<void> } transformAlgorithm
36923692 * @param {(controller: TransformStreamDefaultController<O>) => Promise<void> } flushAlgorithm
3693+ * @param {(reason: any) => Promise<void> } cancelAlgorithm
36933694 */
36943695function setUpTransformStreamDefaultController (
36953696 stream ,
36963697 controller ,
36973698 transformAlgorithm ,
36983699 flushAlgorithm ,
3700+ cancelAlgorithm ,
36993701) {
37003702 assert ( ObjectPrototypeIsPrototypeOf ( TransformStreamPrototype , stream ) ) ;
37013703 assert ( stream [ _controller ] === undefined ) ;
37023704 controller [ _stream ] = stream ;
37033705 stream [ _controller ] = controller ;
37043706 controller [ _transformAlgorithm ] = transformAlgorithm ;
37053707 controller [ _flushAlgorithm ] = flushAlgorithm ;
3708+ controller [ _cancelAlgorithm ] = cancelAlgorithm ;
37063709}
37073710
37083711/**
@@ -3730,6 +3733,8 @@ function setUpTransformStreamDefaultControllerFromTransformer(
37303733 } ;
37313734 /** @type {(controller: TransformStreamDefaultController<O>) => Promise<void> } */
37323735 let flushAlgorithm = ( ) => resolvePromiseWith ( undefined ) ;
3736+ /** @type {(reason: any) => Promise<void> } */
3737+ let cancelAlgorithm = ( ) => resolvePromiseWith ( undefined ) ;
37333738 if ( transformerDict . transform !== undefined ) {
37343739 transformAlgorithm = ( chunk , controller ) =>
37353740 webidl . invokeCallbackFunction (
@@ -3752,11 +3757,23 @@ function setUpTransformStreamDefaultControllerFromTransformer(
37523757 true ,
37533758 ) ;
37543759 }
3760+ if ( transformerDict . cancel !== undefined ) {
3761+ cancelAlgorithm = ( reason ) =>
3762+ webidl . invokeCallbackFunction (
3763+ transformerDict . cancel ,
3764+ [ reason ] ,
3765+ transformer ,
3766+ webidl . converters [ "Promise<undefined>" ] ,
3767+ "Failed to call 'cancelAlgorithm' on 'TransformStreamDefaultController'" ,
3768+ true ,
3769+ ) ;
3770+ }
37553771 setUpTransformStreamDefaultController (
37563772 stream ,
37573773 controller ,
37583774 transformAlgorithm ,
37593775 flushAlgorithm ,
3776+ cancelAlgorithm ,
37603777 ) ;
37613778}
37623779
@@ -3938,6 +3955,7 @@ function setUpWritableStreamDefaultWriter(writer, stream) {
39383955function transformStreamDefaultControllerClearAlgorithms ( controller ) {
39393956 controller [ _transformAlgorithm ] = undefined ;
39403957 controller [ _flushAlgorithm ] = undefined ;
3958+ controller [ _cancelAlgorithm ] = undefined ;
39413959}
39423960
39433961/**
@@ -4007,13 +4025,33 @@ function transformStreamDefaultControllerTerminate(controller) {
40074025}
40084026
40094027/**
4010- * @param {TransformStream } stream
4028+ * @template I
4029+ * @template O
4030+ * @param {TransformStream<I, O> } stream
40114031 * @param {any= } reason
40124032 * @returns {Promise<void> }
40134033 */
40144034function transformStreamDefaultSinkAbortAlgorithm ( stream , reason ) {
4015- transformStreamError ( stream , reason ) ;
4016- return resolvePromiseWith ( undefined ) ;
4035+ const controller = stream [ _controller ] ;
4036+ if ( controller [ _finishPromise ] !== undefined ) {
4037+ return controller [ _finishPromise ] . promise ;
4038+ }
4039+ const readable = stream [ _readable ] ;
4040+ controller [ _finishPromise ] = new Deferred ( ) ;
4041+ const cancelPromise = controller [ _cancelAlgorithm ] ( reason ) ;
4042+ transformStreamDefaultControllerClearAlgorithms ( controller ) ;
4043+ transformPromiseWith ( cancelPromise , ( ) => {
4044+ if ( readable [ _state ] === "errored" ) {
4045+ controller [ _finishPromise ] . reject ( readable [ _storedError ] ) ;
4046+ } else {
4047+ readableStreamDefaultControllerError ( readable [ _controller ] , reason ) ;
4048+ controller [ _finishPromise ] . resolve ( undefined ) ;
4049+ }
4050+ } , ( r ) => {
4051+ readableStreamDefaultControllerError ( readable [ _controller ] , r ) ;
4052+ controller [ _finishPromise ] . reject ( r ) ;
4053+ } ) ;
4054+ return controller [ _finishPromise ] . promise ;
40174055}
40184056
40194057/**
@@ -4023,21 +4061,26 @@ function transformStreamDefaultSinkAbortAlgorithm(stream, reason) {
40234061 * @returns {Promise<void> }
40244062 */
40254063function transformStreamDefaultSinkCloseAlgorithm ( stream ) {
4026- const readable = stream [ _readable ] ;
40274064 const controller = stream [ _controller ] ;
4065+ if ( controller [ _finishPromise ] !== undefined ) {
4066+ return controller [ _finishPromise ] . promise ;
4067+ }
4068+ const readable = stream [ _readable ] ;
4069+ controller [ _finishPromise ] = new Deferred ( ) ;
40284070 const flushPromise = controller [ _flushAlgorithm ] ( controller ) ;
40294071 transformStreamDefaultControllerClearAlgorithms ( controller ) ;
4030- return transformPromiseWith ( flushPromise , ( ) => {
4072+ transformPromiseWith ( flushPromise , ( ) => {
40314073 if ( readable [ _state ] === "errored" ) {
4032- throw readable [ _storedError ] ;
4074+ controller [ _finishPromise ] . reject ( readable [ _storedError ] ) ;
4075+ } else {
4076+ readableStreamDefaultControllerClose ( readable [ _controller ] ) ;
4077+ controller [ _finishPromise ] . resolve ( undefined ) ;
40334078 }
4034- readableStreamDefaultControllerClose (
4035- /** @type {ReadableStreamDefaultController } */ readable [ _controller ] ,
4036- ) ;
40374079 } , ( r ) => {
4038- transformStreamError ( stream , r ) ;
4039- throw readable [ _storedError ] ;
4080+ readableStreamDefaultControllerError ( readable [ _controller ] , r ) ;
4081+ controller [ _finishPromise ] . reject ( r ) ;
40404082 } ) ;
4083+ return controller [ _finishPromise ] . promise ;
40414084}
40424085
40434086/**
@@ -4069,6 +4112,41 @@ function transformStreamDefaultSinkWriteAlgorithm(stream, chunk) {
40694112 return transformStreamDefaultControllerPerformTransform ( controller , chunk ) ;
40704113}
40714114
4115+ /**
4116+ * @template I
4117+ * @template O
4118+ * @param {TransformStream<I, O> } stream
4119+ * @param {any= } reason
4120+ * @returns {Promise<void> }
4121+ */
4122+ function transformStreamDefaultSourceCancelAlgorithm ( stream , reason ) {
4123+ const controller = stream [ _controller ] ;
4124+ if ( controller [ _finishPromise ] !== undefined ) {
4125+ return controller [ _finishPromise ] . promise ;
4126+ }
4127+ const writable = stream [ _writable ] ;
4128+ controller [ _finishPromise ] = new Deferred ( ) ;
4129+ const cancelPromise = controller [ _cancelAlgorithm ] ( reason ) ;
4130+ transformStreamDefaultControllerClearAlgorithms ( controller ) ;
4131+ transformPromiseWith ( cancelPromise , ( ) => {
4132+ if ( writable [ _state ] === "errored" ) {
4133+ controller [ _finishPromise ] . reject ( writable [ _storedError ] ) ;
4134+ } else {
4135+ writableStreamDefaultControllerErrorIfNeeded (
4136+ writable [ _controller ] ,
4137+ reason ,
4138+ ) ;
4139+ transformStreamUnblockWrite ( stream ) ;
4140+ controller [ _finishPromise ] . resolve ( undefined ) ;
4141+ }
4142+ } , ( r ) => {
4143+ writableStreamDefaultControllerErrorIfNeeded ( writable [ _controller ] , r ) ;
4144+ transformStreamUnblockWrite ( stream ) ;
4145+ controller [ _finishPromise ] . reject ( r ) ;
4146+ } ) ;
4147+ return controller [ _finishPromise ] . promise ;
4148+ }
4149+
40724150/**
40734151 * @param {TransformStream } stream
40744152 * @returns {Promise<void> }
@@ -4104,9 +4182,7 @@ function transformStreamErrorWritableAndUnblockWrite(stream, e) {
41044182 stream [ _writable ] [ _controller ] ,
41054183 e ,
41064184 ) ;
4107- if ( stream [ _backpressure ] === true ) {
4108- transformStreamSetBackpressure ( stream , false ) ;
4109- }
4185+ transformStreamUnblockWrite ( stream ) ;
41104186}
41114187
41124188/**
@@ -4122,6 +4198,15 @@ function transformStreamSetBackpressure(stream, backpressure) {
41224198 stream [ _backpressure ] = backpressure ;
41234199}
41244200
4201+ /**
4202+ * @param {TransformStream } stream
4203+ */
4204+ function transformStreamUnblockWrite ( stream ) {
4205+ if ( stream [ _backpressure ] === true ) {
4206+ transformStreamSetBackpressure ( stream , false ) ;
4207+ }
4208+ }
4209+
41254210/**
41264211 * @param {WritableStream } stream
41274212 * @param {any= } reason
@@ -6007,6 +6092,10 @@ const TransformStreamPrototype = TransformStream.prototype;
60076092
60086093/** @template O */
60096094class TransformStreamDefaultController {
6095+ /** @type {(reason: any) => Promise<void> } */
6096+ [ _cancelAlgorithm ] ;
6097+ /** @type {Promise<void> | undefined } */
6098+ [ _finishPromise ] ;
60106099 /** @type {(controller: this) => Promise<void> } */
60116100 [ _flushAlgorithm ] ;
60126101 /** @type {TransformStream<O> } */
0 commit comments