char/avril
(wip) why'd you have to go and make things so complicaaaaated?
git clone https://git.t4t.associates/char/avril
f4a0f5b
main
1diff --git a/src/lib/byte-length-queuing-strategy.ts b/src/lib/byte-length-queuing-strategy.ts 2indexc650548 ..b5a9075 100644 3--- a/src/lib/byte-length-queuing-strategy.ts 4+++ b/src/lib/byte-length-queuing-strategy.ts 5@@ -1,3 +1,5 @@ 6+declare function markUncloneable(value: object, transferable?: boolean): void; 7+ 8 import type { QueuingStrategy, QueuingStrategyInit } from './queuing-strategy'; 9 import { setFunctionName, typeIsObject } from './helpers/miscellaneous'; 10 import { assertRequiredArgument } from './validators/basic'; 11@@ -19,6 +21,7 @@ export default class ByteLengthQueuingStrategy implements QueuingStrategy<ArrayB 12 readonly _byteLengthQueuingStrategyHighWaterMark: number; 13 14 constructor(options: QueuingStrategyInit) { 15+ markUncloneable(this); 16 assertRequiredArgument(options, 1, 'ByteLengthQueuingStrategy'); 17 options = convertQueuingStrategyInit(options, 'First parameter'); 18 this._byteLengthQueuingStrategyHighWaterMark = options.highWaterMark; 19diff --git a/src/lib/count-queuing-strategy.ts b/src/lib/count-queuing-strategy.ts 20index3753f99 ..29643c5 100644 21--- a/src/lib/count-queuing-strategy.ts 22+++ b/src/lib/count-queuing-strategy.ts 23@@ -1,3 +1,5 @@ 24+declare function markUncloneable(value: object, transferable?: boolean): void; 25+ 26 import type { QueuingStrategy, QueuingStrategyInit } from './queuing-strategy'; 27 import { setFunctionName, typeIsObject } from './helpers/miscellaneous'; 28 import { assertRequiredArgument } from './validators/basic'; 29@@ -19,6 +21,7 @@ export default class CountQueuingStrategy implements QueuingStrategy<any> { 30 readonly _countQueuingStrategyHighWaterMark!: number; 31 32 constructor(options: QueuingStrategyInit) { 33+ markUncloneable(this); 34 assertRequiredArgument(options, 1, 'CountQueuingStrategy'); 35 options = convertQueuingStrategyInit(options, 'First parameter'); 36 this._countQueuingStrategyHighWaterMark = options.highWaterMark; 37diff --git a/src/lib/helpers/webidl.ts b/src/lib/helpers/webidl.ts 38indexbce6b50 ..0984ee5 100644 39--- a/src/lib/helpers/webidl.ts 40+++ b/src/lib/helpers/webidl.ts 41@@ -1,10 +1,17 @@ 42-import { rethrowAssertionErrorRejection } from './miscellaneous'; 43 import assert from '../../stub/assert'; 44 45-const originalPromise = Promise; 46-const originalPromiseResolve = Promise.resolve.bind(originalPromise); 47-const originalPromiseThen = Promise.prototype.then; 48-const originalPromiseReject = Promise.reject.bind(originalPromise); 49+declare function markPromiseHandled(promise: Promise<unknown>): void; 50+ 51+declare function safeNewPromise<T>(executor: (resolve: (value: T | PromiseLike<T>) => void, reject: (reason?: any) => void) => void): Promise<T>; 52+declare const safePromiseResolve: typeof Promise.resolve; 53+declare const safePromiseReject: typeof Promise.reject; 54+declare const then: <T, R1 = T, R2 = never>(promise: Promise<T>, fulfilled?: (value: T) => R1 | PromiseLike<R1>, rejected?: (reason: any) => R2 | PromiseLike<R2>) => Promise<R1 | R2>; 55+declare const apply: typeof Reflect.apply; 56+ 57+const originalPromise = safeNewPromise; 58+const originalPromiseResolve = safePromiseResolve; 59+const originalPromiseThen = then; 60+const originalPromiseReject = safePromiseReject; 61 62 export const promiseResolve = originalPromiseResolve; 63 64@@ -13,7 +20,7 @@ export function newPromise<T>(executor: ( 65 resolve: (value: T | PromiseLike<T>) => void, 66 reject: (reason?: any) => void 67 ) => void): Promise<T> { 68- return new originalPromise(executor); 69+ return originalPromise(executor); 70 } 71 72 // https://webidl.spec.whatwg.org/#a-promise-resolved-with 73@@ -21,6 +28,15 @@ export function promiseResolvedWith<T>(value: T | PromiseLike<T>): Promise<T> { 74 return newPromise(resolve => resolve(value)); 75 } 76 77+const resolvedUndefinedPromise = originalPromise<undefined>(resolve => resolve(undefined)); 78+// Shadowing constructor would invalidate V8's global promise-species protector. 79+Object.freeze(resolvedUndefinedPromise); 80+ 81+// Only for internal reactions, not public results or promise assimilation. 82+export function promiseResolvedWithUndefined(): Promise<undefined> { 83+ return resolvedUndefinedPromise; 84+} 85+ 86 // https://webidl.spec.whatwg.org/#a-promise-rejected-with 87 export function promiseRejectedWith<T = never>(reason: any): Promise<T> { 88 return originalPromiseReject(reason); 89@@ -33,7 +49,7 @@ export function PerformPromiseThen<T, TResult1 = T, TResult2 = never>( 90 ): Promise<TResult1 | TResult2> { 91 // There doesn't appear to be any way to correctly emulate the behaviour from JavaScript, so this is just an 92 // approximation. 93- return originalPromiseThen.call(promise, onFulfilled, onRejected) as Promise<TResult1 | TResult2>; 94+ return originalPromiseThen(promise, onFulfilled, onRejected); 95 } 96 97 // Bluebird logs a warning when a promise is created within a fulfillment handler, but then isn't returned 98@@ -44,11 +60,7 @@ export function uponPromise<T>( 99 onFulfilled?: (value: T) => null | PromiseLike<null>, 100 onRejected?: (reason: any) => null | PromiseLike<null> 101 ): void { 102- PerformPromiseThen( 103- PerformPromiseThen(promise, onFulfilled, onRejected), 104- undefined, 105- rethrowAssertionErrorRejection 106- ); 107+ setPromiseIsHandledToTrue(PerformPromiseThen(promise, onFulfilled, onRejected)); 108 } 109 110 export function uponFulfillment<T>(promise: Promise<T>, onFulfilled: (value: T) => null | PromiseLike<null>): void { 111@@ -68,7 +80,7 @@ export function transformPromiseWith<T, TResult1 = T, TResult2 = never>( 112 } 113 114 export function setPromiseIsHandledToTrue(promise: Promise<unknown>): void { 115- PerformPromiseThen(promise, undefined, rethrowAssertionErrorRejection); 116+ markPromiseHandled(promise); 117 } 118 119 let _queueMicrotask: (callback: () => void) => void = (callback) => { 120@@ -87,7 +99,7 @@ export function reflectCall<T, A extends any[], R>(F: (this: T, ...fnArgs: A) => 121 if (typeof F !== 'function') { 122 throw new TypeError('Argument is not a function'); 123 } 124- return Function.prototype.apply.call(F, V, args); 125+ return apply(F, V, args); 126 } 127 128 export function promiseCall<T, A extends any[], R>( 129diff --git a/src/lib/readable-stream.ts b/src/lib/readable-stream.ts 130index95a0fb1 ..f420dfa 100644 131--- a/src/lib/readable-stream.ts 132+++ b/src/lib/readable-stream.ts 133@@ -1,3 +1,5 @@ 134+declare function markUncloneable(value: object, transferable?: boolean): void; 135+ 136 import assert from '../stub/assert'; 137 import { 138 promiseRejectedWith, 139@@ -408,6 +410,7 @@ export function CreateReadableStream<R>( 140 InitializeReadableStream(stream); 141 142 const controller: ReadableStreamDefaultController<R> = Object.create(ReadableStreamDefaultController.prototype); 143+ markUncloneable(controller); 144 SetUpReadableStreamDefaultController(stream, controller, startAlgorithm, pullAlgorithm, cancelAlgorithm, highWaterMark, sizeAlgorithm); 145 146 return stream; 147@@ -423,12 +426,14 @@ export function CreateReadableByteStream( 148 InitializeReadableStream(stream); 149 150 const controller: ReadableByteStreamController = Object.create(ReadableByteStreamController.prototype); 151+ markUncloneable(controller); 152 SetUpReadableByteStreamController(stream, controller, startAlgorithm, pullAlgorithm, cancelAlgorithm, 0, undefined); 153 154 return stream; 155 } 156 157 function InitializeReadableStream(stream: ReadableStream) { 158+ markUncloneable(stream, true); 159 stream._state = 'readable'; 160 stream._reader = undefined; 161 stream._storedError = undefined; 162diff --git a/src/lib/readable-stream/async-iterator.ts b/src/lib/readable-stream/async-iterator.ts 163index503472d ..c697e80 100644 164--- a/src/lib/readable-stream/async-iterator.ts 165+++ b/src/lib/readable-stream/async-iterator.ts 166@@ -1,3 +1,5 @@ 167+declare function markUncloneable(value: object, transferable?: boolean): void; 168+ 169 import { ReadableStream } from '../readable-stream'; 170 import { 171 AcquireReadableStreamDefaultReader, 172@@ -58,7 +60,7 @@ export class ReadableStreamAsyncIteratorImpl<R> { 173 174 private _nextSteps(): Promise<ReadableStreamDefaultReadResult<R>> { 175 if (this._isFinished) { 176- return Promise.resolve({ value: undefined, done: true }); 177+ return promiseResolvedWith({ value: undefined, done: true }); 178 } 179 180 const reader = this._reader; 181@@ -71,7 +73,7 @@ export class ReadableStreamAsyncIteratorImpl<R> { 182 183 private _returnSteps(value: any): Promise<ReadableStreamDefaultReadResult<any>> { 184 if (this._isFinished) { 185- return Promise.resolve({ value, done: true }); 186+ return promiseResolvedWith({ value, done: true }); 187 } 188 this._isFinished = true; 189 190@@ -173,6 +175,7 @@ export function AcquireReadableStreamAsyncIterator<R>( 191 const reader = AcquireReadableStreamDefaultReader<R>(stream); 192 const impl = new ReadableStreamAsyncIteratorImpl(reader, preventCancel); 193 const iterator: ReadableStreamAsyncIteratorInstance<R> = Object.create(ReadableStreamAsyncIteratorPrototype); 194+ markUncloneable(iterator); 195 iterator._asyncIteratorImpl = impl; 196 return iterator; 197 } 198diff --git a/src/lib/readable-stream/byob-reader.ts b/src/lib/readable-stream/byob-reader.ts 199indexdfc103f ..5458438 100644 200--- a/src/lib/readable-stream/byob-reader.ts 201+++ b/src/lib/readable-stream/byob-reader.ts 202@@ -1,3 +1,5 @@ 203+declare function markUncloneable(value: object, transferable?: boolean): void; 204+ 205 import assert from '../../stub/assert'; 206 import { SimpleQueue } from '../simple-queue'; 207 import { 208@@ -119,6 +121,7 @@ export class ReadableStreamBYOBReader { 209 _readIntoRequests: SimpleQueue<ReadIntoRequest<any>>; 210 211 constructor(stream: ReadableStream<Uint8Array>) { 212+ markUncloneable(this); 213 assertRequiredArgument(stream, 1, 'ReadableStreamBYOBReader'); 214 assertReadableStream(stream, 'First parameter'); 215 216diff --git a/src/lib/readable-stream/byte-stream-controller.ts b/src/lib/readable-stream/byte-stream-controller.ts 217indexe435b76 ..c44d980 100644 218--- a/src/lib/readable-stream/byte-stream-controller.ts 219+++ b/src/lib/readable-stream/byte-stream-controller.ts 220@@ -1,3 +1,5 @@ 221+declare function markUncloneable(value: object, transferable?: boolean): void; 222+ 223 import assert from '../../stub/assert'; 224 import { SimpleQueue } from '../simple-queue'; 225 import { ResetQueue } from '../abstract-ops/queue-with-sizes'; 226@@ -34,7 +36,7 @@ import { 227 TransferArrayBuffer 228 } from '../abstract-ops/ecmascript'; 229 import { CancelSteps, CanPullSyncSteps, PullSteps, ReleaseSteps } from '../abstract-ops/internal-methods'; 230-import { promiseResolvedWith, uponPromise } from '../helpers/webidl'; 231+import { promiseResolvedWith, promiseResolvedWithUndefined, uponPromise } from '../helpers/webidl'; 232 import { assertRequiredArgument, convertUnsignedLongLongWithEnforceRange } from '../validators/basic'; 233 import { 234 type ArrayBufferViewConstructor, 235@@ -1016,6 +1018,7 @@ export function ReadableByteStreamControllerGetBYOBRequest(controller: ReadableB 236 ); 237 238 const byobRequest: ReadableStreamBYOBRequest = Object.create(ReadableStreamBYOBRequest.prototype); 239+ markUncloneable(byobRequest); 240 SetUpReadableStreamBYOBRequest(byobRequest, controller, view as Uint8Array<ArrayBuffer>); 241 controller._byobRequest = byobRequest; 242 } 243@@ -1161,6 +1164,7 @@ export function SetUpReadableByteStreamControllerFromUnderlyingSource( 244 highWaterMark: number 245 ) { 246 const controller: ReadableByteStreamController = Object.create(ReadableByteStreamController.prototype); 247+ markUncloneable(controller); 248 249 let startAlgorithm: () => void | PromiseLike<void>; 250 let pullAlgorithm: () => Promise<void>; 251@@ -1174,12 +1178,12 @@ export function SetUpReadableByteStreamControllerFromUnderlyingSource( 252 if (underlyingByteSource.pull !== undefined) { 253 pullAlgorithm = () => underlyingByteSource.pull!(controller); 254 } else { 255- pullAlgorithm = () => promiseResolvedWith(undefined); 256+ pullAlgorithm = promiseResolvedWithUndefined; 257 } 258 if (underlyingByteSource.cancel !== undefined) { 259 cancelAlgorithm = reason => underlyingByteSource.cancel!(reason); 260 } else { 261- cancelAlgorithm = () => promiseResolvedWith(undefined); 262+ cancelAlgorithm = promiseResolvedWithUndefined; 263 } 264 265 const autoAllocateChunkSize = underlyingByteSource.autoAllocateChunkSize; 266diff --git a/src/lib/readable-stream/default-controller.ts b/src/lib/readable-stream/default-controller.ts 267index11eb3be ..0f9086e 100644 268--- a/src/lib/readable-stream/default-controller.ts 269+++ b/src/lib/readable-stream/default-controller.ts 270@@ -1,3 +1,5 @@ 271+declare function markUncloneable(value: object, transferable?: boolean): void; 272+ 273 import type { QueuingStrategySizeCallback } from '../queuing-strategy'; 274 import assert from '../../stub/assert'; 275 import { DequeueValue, EnqueueValueWithSize, type QueuePair, ResetQueue } from '../abstract-ops/queue-with-sizes'; 276@@ -12,7 +14,7 @@ import { IsReadableStreamLocked, ReadableStream, ReadableStreamClose, ReadableSt 277 import type { ValidatedUnderlyingSource } from './underlying-source'; 278 import { setFunctionName, typeIsObject } from '../helpers/miscellaneous'; 279 import { CancelSteps, CanPullSyncSteps, PullSteps, ReleaseSteps } from '../abstract-ops/internal-methods'; 280-import { promiseResolvedWith, uponPromise } from '../helpers/webidl'; 281+import { promiseResolvedWith, promiseResolvedWithUndefined, uponPromise } from '../helpers/webidl'; 282 283 /** 284 * Allows control of a {@link ReadableStream | readable stream}'s state and internal queue. 285@@ -387,6 +389,7 @@ export function SetUpReadableStreamDefaultControllerFromUnderlyingSource<R>( 286 sizeAlgorithm: QueuingStrategySizeCallback<R> 287 ) { 288 const controller: ReadableStreamDefaultController<R> = Object.create(ReadableStreamDefaultController.prototype); 289+ markUncloneable(controller); 290 291 let startAlgorithm: () => void | PromiseLike<void>; 292 let pullAlgorithm: () => Promise<void>; 293@@ -400,12 +403,12 @@ export function SetUpReadableStreamDefaultControllerFromUnderlyingSource<R>( 294 if (underlyingSource.pull !== undefined) { 295 pullAlgorithm = () => underlyingSource.pull!(controller); 296 } else { 297- pullAlgorithm = () => promiseResolvedWith(undefined); 298+ pullAlgorithm = promiseResolvedWithUndefined; 299 } 300 if (underlyingSource.cancel !== undefined) { 301 cancelAlgorithm = reason => underlyingSource.cancel!(reason); 302 } else { 303- cancelAlgorithm = () => promiseResolvedWith(undefined); 304+ cancelAlgorithm = promiseResolvedWithUndefined; 305 } 306 307 SetUpReadableStreamDefaultController(stream, controller, startAlgorithm, pullAlgorithm, cancelAlgorithm, highWaterMark, sizeAlgorithm); 308diff --git a/src/lib/readable-stream/default-reader.ts b/src/lib/readable-stream/default-reader.ts 309indexb0a432c ..8d8007c 100644 310--- a/src/lib/readable-stream/default-reader.ts 311+++ b/src/lib/readable-stream/default-reader.ts 312@@ -1,3 +1,5 @@ 313+declare function markUncloneable(value: object, transferable?: boolean): void; 314+ 315 import assert from '../../stub/assert'; 316 import { SimpleQueue } from '../simple-queue'; 317 import { 318@@ -103,6 +105,7 @@ export class ReadableStreamDefaultReader<R = any> { 319 _readRequests: SimpleQueue<ReadRequest<R>>; 320 321 constructor(stream: ReadableStream<R>) { 322+ markUncloneable(this); 323 assertRequiredArgument(stream, 1, 'ReadableStreamDefaultReader'); 324 assertReadableStream(stream, 'First parameter'); 325 326diff --git a/src/lib/readable-stream/from.ts b/src/lib/readable-stream/from.ts 327indexd745178 ..deceee7 100644 328--- a/src/lib/readable-stream/from.ts 329+++ b/src/lib/readable-stream/from.ts 330@@ -6,7 +6,7 @@ import { 331 } from './readable-stream-like'; 332 import { ReadableStreamDefaultControllerClose, ReadableStreamDefaultControllerEnqueue } from './default-controller'; 333 import { GetIterator, GetMethod, IteratorNext } from '../abstract-ops/ecmascript'; 334-import { promiseCall, promiseRejectedWith, promiseResolvedWith, transformPromiseWith } from '../helpers/webidl'; 335+import { promiseCall, promiseRejectedWith, promiseResolvedWith, promiseResolvedWithUndefined, transformPromiseWith } from '../helpers/webidl'; 336 import { typeIsObject } from '../helpers/miscellaneous'; 337 import { noop } from '../../utils'; 338 339@@ -54,7 +54,7 @@ export function ReadableStreamFromIterable<R>(asyncIterable: Iterable<R> | Async 340 return promiseRejectedWith(e); 341 } 342 if (returnMethod === undefined) { 343- return promiseResolvedWith(undefined); 344+ return promiseResolvedWithUndefined(); 345 } 346 const returnPromise = promiseCall(returnMethod, iterator, [reason]); 347 return transformPromiseWith(returnPromise, (iterResult) => { 348diff --git a/src/lib/readable-stream/pipe.ts b/src/lib/readable-stream/pipe.ts 349index8044696 ..e0a4810 100644 350--- a/src/lib/readable-stream/pipe.ts 351+++ b/src/lib/readable-stream/pipe.ts 352@@ -23,6 +23,7 @@ import { 353 newPromise, 354 PerformPromiseThen, 355 promiseResolvedWith, 356+ promiseResolvedWithUndefined, 357 setPromiseIsHandledToTrue, 358 uponFulfillment, 359 uponPromise, 360@@ -32,6 +33,8 @@ import { noop } from '../../utils'; 361 import { type AbortSignal, isAbortSignal } from '../abort-signal'; 362 import { DOMException } from '../../stub/dom-exception'; 363 364+declare const safePromiseAll: typeof Promise.all; 365+ 366 export function ReadableStreamPipeTo<T>( 367 source: ReadableStream<T>, 368 dest: WritableStream<T>, 369@@ -79,7 +82,13 @@ export function ReadableStreamPipeTo<T>( 370 return promiseResolvedWith(undefined); 371 }); 372 } 373- shutdownWithAction(() => Promise.all(actions.map(action => action())), true, error); 374+ shutdownWithAction(() => { 375+ const promises = []; 376+ for (let index = 0; index < actions.length; index++) { 377+ promises[index] = actions[index](); 378+ } 379+ return safePromiseAll(promises); 380+ }, true, error); 381 }; 382 383 if (signal.aborted) { 384@@ -234,7 +243,7 @@ class PipeState<T> { 385 _shuttingDown = false; 386 387 // This is used to keep track of the spec's requirement that we wait for ongoing writes during shutdown. 388- _currentWrite = promiseResolvedWith<void>(undefined); 389+ _currentWrite = promiseResolvedWithUndefined(); 390 391 constructor(readonly _writer: WritableStreamDefaultWriter<T>) {} 392 393diff --git a/src/lib/readable-stream/tee.ts b/src/lib/readable-stream/tee.ts 394index5b05eb1 ..3a82830 100644 395--- a/src/lib/readable-stream/tee.ts 396+++ b/src/lib/readable-stream/tee.ts 397@@ -22,7 +22,7 @@ import { 398 type ReadIntoRequest 399 } from './byob-reader'; 400 import assert from '../../stub/assert'; 401-import { newPromise, promiseResolvedWith, queueMicrotask, uponRejection } from '../helpers/webidl'; 402+import { newPromise, promiseResolvedWithUndefined, queueMicrotask, uponRejection } from '../helpers/webidl'; 403 import { 404 ReadableStreamDefaultControllerClose, 405 ReadableStreamDefaultControllerEnqueue, 406@@ -79,7 +79,7 @@ export function ReadableStreamDefaultTee<R>( 407 function pullAlgorithm(): Promise<void> { 408 if (reading) { 409 readAgain = true; 410- return promiseResolvedWith(undefined); 411+ return promiseResolvedWithUndefined(); 412 } 413 414 reading = true; 415@@ -132,7 +132,7 @@ export function ReadableStreamDefaultTee<R>( 416 }; 417 ReadableStreamDefaultReaderRead(reader, readRequest); 418 419- return promiseResolvedWith(undefined); 420+ return promiseResolvedWithUndefined(); 421 } 422 423 function cancel1Algorithm(reason: any): Promise<void> { 424@@ -369,7 +369,7 @@ export function ReadableByteStreamTee(stream: ReadableByteStream): [ReadableByte 425 function pull1Algorithm(): Promise<void> { 426 if (reading) { 427 readAgainForBranch1 = true; 428- return promiseResolvedWith(undefined); 429+ return promiseResolvedWithUndefined(); 430 } 431 432 reading = true; 433@@ -381,13 +381,13 @@ export function ReadableByteStreamTee(stream: ReadableByteStream): [ReadableByte 434 pullWithBYOBReader(byobRequest._view!, false); 435 } 436 437- return promiseResolvedWith(undefined); 438+ return promiseResolvedWithUndefined(); 439 } 440 441 function pull2Algorithm(): Promise<void> { 442 if (reading) { 443 readAgainForBranch2 = true; 444- return promiseResolvedWith(undefined); 445+ return promiseResolvedWithUndefined(); 446 } 447 448 reading = true; 449@@ -399,7 +399,7 @@ export function ReadableByteStreamTee(stream: ReadableByteStream): [ReadableByte 450 pullWithBYOBReader(byobRequest._view!, true); 451 } 452 453- return promiseResolvedWith(undefined); 454+ return promiseResolvedWithUndefined(); 455 } 456 457 function cancel1Algorithm(reason: any): Promise<void> { 458diff --git a/src/lib/transform-stream.ts b/src/lib/transform-stream.ts 459indexf800382 ..1775e8d 100644 460--- a/src/lib/transform-stream.ts 461+++ b/src/lib/transform-stream.ts 462@@ -1,8 +1,11 @@ 463+declare function markUncloneable(value: object, transferable?: boolean): void; 464+ 465 import assert from '../stub/assert'; 466 import { 467 newPromise, 468 promiseRejectedWith, 469 promiseResolvedWith, 470+ promiseResolvedWithUndefined, 471 setPromiseIsHandledToTrue, 472 transformPromiseWith, 473 uponPromise 474@@ -171,6 +174,7 @@ export function CreateTransformStream<I, O>( 475 ); 476 477 const controller: TransformStreamDefaultController<O> = Object.create(TransformStreamDefaultController.prototype); 478+ markUncloneable(controller); 479 480 SetUpTransformStreamDefaultController(stream, controller, transformAlgorithm, flushAlgorithm, cancelAlgorithm); 481 482@@ -187,6 +191,7 @@ function InitializeTransformStream<I, O>( 483 readableHighWaterMark: number, 484 readableSizeAlgorithm: QueuingStrategySizeCallback<O> 485 ) { 486+ markUncloneable(stream, true); 487 function startAlgorithm(): Promise<void> { 488 return startPromise; 489 } 490@@ -411,6 +416,7 @@ function SetUpTransformStreamDefaultControllerFromTransformer<I, O>( 491 transformer: ValidatedTransformer<I, O> 492 ) { 493 const controller: TransformStreamDefaultController<O> = Object.create(TransformStreamDefaultController.prototype); 494+ markUncloneable(controller); 495 496 let transformAlgorithm: (chunk: I) => Promise<void>; 497 let flushAlgorithm: () => Promise<void>; 498@@ -422,7 +428,7 @@ function SetUpTransformStreamDefaultControllerFromTransformer<I, O>( 499 transformAlgorithm = (chunk) => { 500 try { 501 TransformStreamDefaultControllerEnqueue(controller, chunk as unknown as O); 502- return promiseResolvedWith(undefined); 503+ return promiseResolvedWithUndefined(); 504 } catch (transformResultE) { 505 return promiseRejectedWith(transformResultE); 506 } 507@@ -432,13 +438,13 @@ function SetUpTransformStreamDefaultControllerFromTransformer<I, O>( 508 if (transformer.flush !== undefined) { 509 flushAlgorithm = () => transformer.flush!(controller); 510 } else { 511- flushAlgorithm = () => promiseResolvedWith(undefined); 512+ flushAlgorithm = promiseResolvedWithUndefined; 513 } 514 515 if (transformer.cancel !== undefined) { 516 cancelAlgorithm = reason => transformer.cancel!(reason); 517 } else { 518- cancelAlgorithm = () => promiseResolvedWith(undefined); 519+ cancelAlgorithm = promiseResolvedWithUndefined; 520 } 521 522 SetUpTransformStreamDefaultController(stream, controller, transformAlgorithm, flushAlgorithm, cancelAlgorithm); 523diff --git a/src/lib/writable-stream.ts b/src/lib/writable-stream.ts 524index08966c9 ..bc98b62 100644 525--- a/src/lib/writable-stream.ts 526+++ b/src/lib/writable-stream.ts 527@@ -1,8 +1,11 @@ 528+declare function markUncloneable(value: object, transferable?: boolean): void; 529+ 530 import assert from '../stub/assert'; 531 import { 532 newPromise, 533 promiseRejectedWith, 534 promiseResolvedWith, 535+ promiseResolvedWithUndefined, 536 setPromiseIsHandledToTrue, 537 uponPromise 538 } from './helpers/webidl'; 539@@ -237,6 +240,7 @@ function CreateWritableStream<W>( 540 InitializeWritableStream(stream); 541 542 const controller: WritableStreamDefaultController<W> = Object.create(WritableStreamDefaultController.prototype); 543+ markUncloneable(controller); 544 545 SetUpWritableStreamDefaultController( 546 stream, controller, startAlgorithm, writeAlgorithm, closeAlgorithm, 547@@ -246,6 +250,7 @@ function CreateWritableStream<W>( 548 } 549 550 function InitializeWritableStream<W>(stream: WritableStream<W>) { 551+ markUncloneable(stream, true); 552 stream._state = 'writable'; 553 554 // The error that will be reported by new method calls once the state becomes errored. Only set when [[state]] is 555@@ -616,6 +621,7 @@ export class WritableStreamDefaultWriter<W = any> { 556 _readyPromiseState!: 'pending' | 'fulfilled' | 'rejected'; 557 558 constructor(stream: WritableStream<W>) { 559+ markUncloneable(this); 560 assertRequiredArgument(stream, 1, 'WritableStreamDefaultWriter'); 561 assertWritableStream(stream, 'First parameter'); 562 563@@ -843,7 +849,7 @@ function WritableStreamDefaultWriterCloseWithErrorPropagation(writer: WritableSt 564 565 const state = stream._state; 566 if (WritableStreamCloseQueuedOrInFlight(stream) || state === 'closed') { 567- return promiseResolvedWith(undefined); 568+ return promiseResolvedWithUndefined(); 569 } 570 571 if (state === 'errored') { 572@@ -1124,6 +1130,7 @@ function SetUpWritableStreamDefaultControllerFromUnderlyingSink<W>( 573 sizeAlgorithm: QueuingStrategySizeCallback<W> 574 ) { 575 const controller = Object.create(WritableStreamDefaultController.prototype); 576+ markUncloneable(controller); 577 578 let startAlgorithm: () => void | PromiseLike<void>; 579 let writeAlgorithm: (chunk: W) => Promise<void>; 580@@ -1138,17 +1145,17 @@ function SetUpWritableStreamDefaultControllerFromUnderlyingSink<W>( 581 if (underlyingSink.write !== undefined) { 582 writeAlgorithm = chunk => underlyingSink.write!(chunk, controller); 583 } else { 584- writeAlgorithm = () => promiseResolvedWith(undefined); 585+ writeAlgorithm = promiseResolvedWithUndefined; 586 } 587 if (underlyingSink.close !== undefined) { 588 closeAlgorithm = () => underlyingSink.close!(); 589 } else { 590- closeAlgorithm = () => promiseResolvedWith(undefined); 591+ closeAlgorithm = promiseResolvedWithUndefined; 592 } 593 if (underlyingSink.abort !== undefined) { 594 abortAlgorithm = reason => underlyingSink.abort!(reason); 595 } else { 596- abortAlgorithm = () => promiseResolvedWith(undefined); 597+ abortAlgorithm = promiseResolvedWithUndefined; 598 } 599 600 SetUpWritableStreamDefaultController(stream, controller, startAlgorithm, writeAlgorithm, closeAlgorithm, abortAlgorithm, highWaterMark, sizeAlgorithm);