UNPKG

156 kBJavaScriptView Raw
1/**
2 * web-streams-polyfill v3.0.2
3 */
4/// <reference lib="es2015.symbol" />
5const SymbolPolyfill = typeof Symbol === 'function' && typeof Symbol.iterator === 'symbol' ?
6 Symbol :
7 description => `Symbol(${description})`;
8
9/// <reference lib="dom" />
10function noop() {
11 // do nothing
12}
13function getGlobals() {
14 if (typeof self !== 'undefined') {
15 return self;
16 }
17 else if (typeof window !== 'undefined') {
18 return window;
19 }
20 else if (typeof global !== 'undefined') {
21 return global;
22 }
23 return undefined;
24}
25const globals = getGlobals();
26
27function typeIsObject(x) {
28 return (typeof x === 'object' && x !== null) || typeof x === 'function';
29}
30const rethrowAssertionErrorRejection = noop;
31
32const originalPromise = Promise;
33const originalPromiseThen = Promise.prototype.then;
34const originalPromiseResolve = Promise.resolve.bind(originalPromise);
35const originalPromiseReject = Promise.reject.bind(originalPromise);
36function newPromise(executor) {
37 return new originalPromise(executor);
38}
39function promiseResolvedWith(value) {
40 return originalPromiseResolve(value);
41}
42function promiseRejectedWith(reason) {
43 return originalPromiseReject(reason);
44}
45function PerformPromiseThen(promise, onFulfilled, onRejected) {
46 // There doesn't appear to be any way to correctly emulate the behaviour from JavaScript, so this is just an
47 // approximation.
48 return originalPromiseThen.call(promise, onFulfilled, onRejected);
49}
50function uponPromise(promise, onFulfilled, onRejected) {
51 PerformPromiseThen(PerformPromiseThen(promise, onFulfilled, onRejected), undefined, rethrowAssertionErrorRejection);
52}
53function uponFulfillment(promise, onFulfilled) {
54 uponPromise(promise, onFulfilled);
55}
56function uponRejection(promise, onRejected) {
57 uponPromise(promise, undefined, onRejected);
58}
59function transformPromiseWith(promise, fulfillmentHandler, rejectionHandler) {
60 return PerformPromiseThen(promise, fulfillmentHandler, rejectionHandler);
61}
62function setPromiseIsHandledToTrue(promise) {
63 PerformPromiseThen(promise, undefined, rethrowAssertionErrorRejection);
64}
65const queueMicrotask = (() => {
66 const globalQueueMicrotask = globals && globals.queueMicrotask;
67 if (typeof globalQueueMicrotask === 'function') {
68 return globalQueueMicrotask;
69 }
70 const resolvedPromise = promiseResolvedWith(undefined);
71 return (fn) => PerformPromiseThen(resolvedPromise, fn);
72})();
73function reflectCall(F, V, args) {
74 if (typeof F !== 'function') {
75 throw new TypeError('Argument is not a function');
76 }
77 return Function.prototype.apply.call(F, V, args);
78}
79function promiseCall(F, V, args) {
80 try {
81 return promiseResolvedWith(reflectCall(F, V, args));
82 }
83 catch (value) {
84 return promiseRejectedWith(value);
85 }
86}
87
88// Original from Chromium
89// https://chromium.googlesource.com/chromium/src/+/0aee4434a4dba42a42abaea9bfbc0cd196a63bc1/third_party/blink/renderer/core/streams/SimpleQueue.js
90const QUEUE_MAX_ARRAY_SIZE = 16384;
91/**
92 * Simple queue structure.
93 *
94 * Avoids scalability issues with using a packed array directly by using
95 * multiple arrays in a linked list and keeping the array size bounded.
96 */
97class SimpleQueue {
98 constructor() {
99 this._cursor = 0;
100 this._size = 0;
101 // _front and _back are always defined.
102 this._front = {
103 _elements: [],
104 _next: undefined
105 };
106 this._back = this._front;
107 // The cursor is used to avoid calling Array.shift().
108 // It contains the index of the front element of the array inside the
109 // front-most node. It is always in the range [0, QUEUE_MAX_ARRAY_SIZE).
110 this._cursor = 0;
111 // When there is only one node, size === elements.length - cursor.
112 this._size = 0;
113 }
114 get length() {
115 return this._size;
116 }
117 // For exception safety, this method is structured in order:
118 // 1. Read state
119 // 2. Calculate required state mutations
120 // 3. Perform state mutations
121 push(element) {
122 const oldBack = this._back;
123 let newBack = oldBack;
124 if (oldBack._elements.length === QUEUE_MAX_ARRAY_SIZE - 1) {
125 newBack = {
126 _elements: [],
127 _next: undefined
128 };
129 }
130 // push() is the mutation most likely to throw an exception, so it
131 // goes first.
132 oldBack._elements.push(element);
133 if (newBack !== oldBack) {
134 this._back = newBack;
135 oldBack._next = newBack;
136 }
137 ++this._size;
138 }
139 // Like push(), shift() follows the read -> calculate -> mutate pattern for
140 // exception safety.
141 shift() { // must not be called on an empty queue
142 const oldFront = this._front;
143 let newFront = oldFront;
144 const oldCursor = this._cursor;
145 let newCursor = oldCursor + 1;
146 const elements = oldFront._elements;
147 const element = elements[oldCursor];
148 if (newCursor === QUEUE_MAX_ARRAY_SIZE) {
149 newFront = oldFront._next;
150 newCursor = 0;
151 }
152 // No mutations before this point.
153 --this._size;
154 this._cursor = newCursor;
155 if (oldFront !== newFront) {
156 this._front = newFront;
157 }
158 // Permit shifted element to be garbage collected.
159 elements[oldCursor] = undefined;
160 return element;
161 }
162 // The tricky thing about forEach() is that it can be called
163 // re-entrantly. The queue may be mutated inside the callback. It is easy to
164 // see that push() within the callback has no negative effects since the end
165 // of the queue is checked for on every iteration. If shift() is called
166 // repeatedly within the callback then the next iteration may return an
167 // element that has been removed. In this case the callback will be called
168 // with undefined values until we either "catch up" with elements that still
169 // exist or reach the back of the queue.
170 forEach(callback) {
171 let i = this._cursor;
172 let node = this._front;
173 let elements = node._elements;
174 while (i !== elements.length || node._next !== undefined) {
175 if (i === elements.length) {
176 node = node._next;
177 elements = node._elements;
178 i = 0;
179 if (elements.length === 0) {
180 break;
181 }
182 }
183 callback(elements[i]);
184 ++i;
185 }
186 }
187 // Return the element that would be returned if shift() was called now,
188 // without modifying the queue.
189 peek() { // must not be called on an empty queue
190 const front = this._front;
191 const cursor = this._cursor;
192 return front._elements[cursor];
193 }
194}
195
196function ReadableStreamReaderGenericInitialize(reader, stream) {
197 reader._ownerReadableStream = stream;
198 stream._reader = reader;
199 if (stream._state === 'readable') {
200 defaultReaderClosedPromiseInitialize(reader);
201 }
202 else if (stream._state === 'closed') {
203 defaultReaderClosedPromiseInitializeAsResolved(reader);
204 }
205 else {
206 defaultReaderClosedPromiseInitializeAsRejected(reader, stream._storedError);
207 }
208}
209// A client of ReadableStreamDefaultReader and ReadableStreamBYOBReader may use these functions directly to bypass state
210// check.
211function ReadableStreamReaderGenericCancel(reader, reason) {
212 const stream = reader._ownerReadableStream;
213 return ReadableStreamCancel(stream, reason);
214}
215function ReadableStreamReaderGenericRelease(reader) {
216 if (reader._ownerReadableStream._state === 'readable') {
217 defaultReaderClosedPromiseReject(reader, new TypeError(`Reader was released and can no longer be used to monitor the stream's closedness`));
218 }
219 else {
220 defaultReaderClosedPromiseResetToRejected(reader, new TypeError(`Reader was released and can no longer be used to monitor the stream's closedness`));
221 }
222 reader._ownerReadableStream._reader = undefined;
223 reader._ownerReadableStream = undefined;
224}
225// Helper functions for the readers.
226function readerLockException(name) {
227 return new TypeError('Cannot ' + name + ' a stream using a released reader');
228}
229// Helper functions for the ReadableStreamDefaultReader.
230function defaultReaderClosedPromiseInitialize(reader) {
231 reader._closedPromise = newPromise((resolve, reject) => {
232 reader._closedPromise_resolve = resolve;
233 reader._closedPromise_reject = reject;
234 });
235}
236function defaultReaderClosedPromiseInitializeAsRejected(reader, reason) {
237 defaultReaderClosedPromiseInitialize(reader);
238 defaultReaderClosedPromiseReject(reader, reason);
239}
240function defaultReaderClosedPromiseInitializeAsResolved(reader) {
241 defaultReaderClosedPromiseInitialize(reader);
242 defaultReaderClosedPromiseResolve(reader);
243}
244function defaultReaderClosedPromiseReject(reader, reason) {
245 if (reader._closedPromise_reject === undefined) {
246 return;
247 }
248 setPromiseIsHandledToTrue(reader._closedPromise);
249 reader._closedPromise_reject(reason);
250 reader._closedPromise_resolve = undefined;
251 reader._closedPromise_reject = undefined;
252}
253function defaultReaderClosedPromiseResetToRejected(reader, reason) {
254 defaultReaderClosedPromiseInitializeAsRejected(reader, reason);
255}
256function defaultReaderClosedPromiseResolve(reader) {
257 if (reader._closedPromise_resolve === undefined) {
258 return;
259 }
260 reader._closedPromise_resolve(undefined);
261 reader._closedPromise_resolve = undefined;
262 reader._closedPromise_reject = undefined;
263}
264
265const AbortSteps = SymbolPolyfill('[[AbortSteps]]');
266const ErrorSteps = SymbolPolyfill('[[ErrorSteps]]');
267const CancelSteps = SymbolPolyfill('[[CancelSteps]]');
268const PullSteps = SymbolPolyfill('[[PullSteps]]');
269
270/// <reference lib="es2015.core" />
271// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/isFinite#Polyfill
272const NumberIsFinite = Number.isFinite || function (x) {
273 return typeof x === 'number' && isFinite(x);
274};
275
276/// <reference lib="es2015.core" />
277// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/trunc#Polyfill
278const MathTrunc = Math.trunc || function (v) {
279 return v < 0 ? Math.ceil(v) : Math.floor(v);
280};
281
282// https://heycam.github.io/webidl/#idl-dictionaries
283function isDictionary(x) {
284 return typeof x === 'object' || typeof x === 'function';
285}
286function assertDictionary(obj, context) {
287 if (obj !== undefined && !isDictionary(obj)) {
288 throw new TypeError(`${context} is not an object.`);
289 }
290}
291// https://heycam.github.io/webidl/#idl-callback-functions
292function assertFunction(x, context) {
293 if (typeof x !== 'function') {
294 throw new TypeError(`${context} is not a function.`);
295 }
296}
297// https://heycam.github.io/webidl/#idl-object
298function isObject(x) {
299 return (typeof x === 'object' && x !== null) || typeof x === 'function';
300}
301function assertObject(x, context) {
302 if (!isObject(x)) {
303 throw new TypeError(`${context} is not an object.`);
304 }
305}
306function assertRequiredArgument(x, position, context) {
307 if (x === undefined) {
308 throw new TypeError(`Parameter ${position} is required in '${context}'.`);
309 }
310}
311function assertRequiredField(x, field, context) {
312 if (x === undefined) {
313 throw new TypeError(`${field} is required in '${context}'.`);
314 }
315}
316// https://heycam.github.io/webidl/#idl-unrestricted-double
317function convertUnrestrictedDouble(value) {
318 return Number(value);
319}
320function censorNegativeZero(x) {
321 return x === 0 ? 0 : x;
322}
323function integerPart(x) {
324 return censorNegativeZero(MathTrunc(x));
325}
326// https://heycam.github.io/webidl/#idl-unsigned-long-long
327function convertUnsignedLongLongWithEnforceRange(value, context) {
328 const lowerBound = 0;
329 const upperBound = Number.MAX_SAFE_INTEGER;
330 let x = Number(value);
331 x = censorNegativeZero(x);
332 if (!NumberIsFinite(x)) {
333 throw new TypeError(`${context} is not a finite number`);
334 }
335 x = integerPart(x);
336 if (x < lowerBound || x > upperBound) {
337 throw new TypeError(`${context} is outside the accepted range of ${lowerBound} to ${upperBound}, inclusive`);
338 }
339 if (!NumberIsFinite(x) || x === 0) {
340 return 0;
341 }
342 // TODO Use BigInt if supported?
343 // let xBigInt = BigInt(integerPart(x));
344 // xBigInt = BigInt.asUintN(64, xBigInt);
345 // return Number(xBigInt);
346 return x;
347}
348
349function assertReadableStream(x, context) {
350 if (!IsReadableStream(x)) {
351 throw new TypeError(`${context} is not a ReadableStream.`);
352 }
353}
354
355// Abstract operations for the ReadableStream.
356function AcquireReadableStreamDefaultReader(stream) {
357 return new ReadableStreamDefaultReader(stream);
358}
359// ReadableStream API exposed for controllers.
360function ReadableStreamAddReadRequest(stream, readRequest) {
361 stream._reader._readRequests.push(readRequest);
362}
363function ReadableStreamFulfillReadRequest(stream, chunk, done) {
364 const reader = stream._reader;
365 const readRequest = reader._readRequests.shift();
366 if (done) {
367 readRequest._closeSteps();
368 }
369 else {
370 readRequest._chunkSteps(chunk);
371 }
372}
373function ReadableStreamGetNumReadRequests(stream) {
374 return stream._reader._readRequests.length;
375}
376function ReadableStreamHasDefaultReader(stream) {
377 const reader = stream._reader;
378 if (reader === undefined) {
379 return false;
380 }
381 if (!IsReadableStreamDefaultReader(reader)) {
382 return false;
383 }
384 return true;
385}
386/**
387 * A default reader vended by a {@link ReadableStream}.
388 *
389 * @public
390 */
391class ReadableStreamDefaultReader {
392 constructor(stream) {
393 assertRequiredArgument(stream, 1, 'ReadableStreamDefaultReader');
394 assertReadableStream(stream, 'First parameter');
395 if (IsReadableStreamLocked(stream)) {
396 throw new TypeError('This stream has already been locked for exclusive reading by another reader');
397 }
398 ReadableStreamReaderGenericInitialize(this, stream);
399 this._readRequests = new SimpleQueue();
400 }
401 /**
402 * Returns a promise that will be fulfilled when the stream becomes closed,
403 * or rejected if the stream ever errors or the reader's lock is released before the stream finishes closing.
404 */
405 get closed() {
406 if (!IsReadableStreamDefaultReader(this)) {
407 return promiseRejectedWith(defaultReaderBrandCheckException('closed'));
408 }
409 return this._closedPromise;
410 }
411 /**
412 * If the reader is active, behaves the same as {@link ReadableStream.cancel | stream.cancel(reason)}.
413 */
414 cancel(reason = undefined) {
415 if (!IsReadableStreamDefaultReader(this)) {
416 return promiseRejectedWith(defaultReaderBrandCheckException('cancel'));
417 }
418 if (this._ownerReadableStream === undefined) {
419 return promiseRejectedWith(readerLockException('cancel'));
420 }
421 return ReadableStreamReaderGenericCancel(this, reason);
422 }
423 /**
424 * Returns a promise that allows access to the next chunk from the stream's internal queue, if available.
425 *
426 * If reading a chunk causes the queue to become empty, more data will be pulled from the underlying source.
427 */
428 read() {
429 if (!IsReadableStreamDefaultReader(this)) {
430 return promiseRejectedWith(defaultReaderBrandCheckException('read'));
431 }
432 if (this._ownerReadableStream === undefined) {
433 return promiseRejectedWith(readerLockException('read from'));
434 }
435 let resolvePromise;
436 let rejectPromise;
437 const promise = newPromise((resolve, reject) => {
438 resolvePromise = resolve;
439 rejectPromise = reject;
440 });
441 const readRequest = {
442 _chunkSteps: chunk => resolvePromise({ value: chunk, done: false }),
443 _closeSteps: () => resolvePromise({ value: undefined, done: true }),
444 _errorSteps: e => rejectPromise(e)
445 };
446 ReadableStreamDefaultReaderRead(this, readRequest);
447 return promise;
448 }
449 /**
450 * Releases the reader's lock on the corresponding stream. After the lock is released, the reader is no longer active.
451 * If the associated stream is errored when the lock is released, the reader will appear errored in the same way
452 * from now on; otherwise, the reader will appear closed.
453 *
454 * A reader's lock cannot be released while it still has a pending read request, i.e., if a promise returned by
455 * the reader's {@link ReadableStreamDefaultReader.read | read()} method has not yet been settled. Attempting to
456 * do so will throw a `TypeError` and leave the reader locked to the stream.
457 */
458 releaseLock() {
459 if (!IsReadableStreamDefaultReader(this)) {
460 throw defaultReaderBrandCheckException('releaseLock');
461 }
462 if (this._ownerReadableStream === undefined) {
463 return;
464 }
465 if (this._readRequests.length > 0) {
466 throw new TypeError('Tried to release a reader lock when that reader has pending read() calls un-settled');
467 }
468 ReadableStreamReaderGenericRelease(this);
469 }
470}
471Object.defineProperties(ReadableStreamDefaultReader.prototype, {
472 cancel: { enumerable: true },
473 read: { enumerable: true },
474 releaseLock: { enumerable: true },
475 closed: { enumerable: true }
476});
477if (typeof SymbolPolyfill.toStringTag === 'symbol') {
478 Object.defineProperty(ReadableStreamDefaultReader.prototype, SymbolPolyfill.toStringTag, {
479 value: 'ReadableStreamDefaultReader',
480 configurable: true
481 });
482}
483// Abstract operations for the readers.
484function IsReadableStreamDefaultReader(x) {
485 if (!typeIsObject(x)) {
486 return false;
487 }
488 if (!Object.prototype.hasOwnProperty.call(x, '_readRequests')) {
489 return false;
490 }
491 return true;
492}
493function ReadableStreamDefaultReaderRead(reader, readRequest) {
494 const stream = reader._ownerReadableStream;
495 stream._disturbed = true;
496 if (stream._state === 'closed') {
497 readRequest._closeSteps();
498 }
499 else if (stream._state === 'errored') {
500 readRequest._errorSteps(stream._storedError);
501 }
502 else {
503 stream._readableStreamController[PullSteps](readRequest);
504 }
505}
506// Helper functions for the ReadableStreamDefaultReader.
507function defaultReaderBrandCheckException(name) {
508 return new TypeError(`ReadableStreamDefaultReader.prototype.${name} can only be used on a ReadableStreamDefaultReader`);
509}
510
511/// <reference lib="es2018.asynciterable" />
512let AsyncIteratorPrototype;
513if (typeof SymbolPolyfill.asyncIterator === 'symbol') {
514 // We're running inside a ES2018+ environment, but we're compiling to an older syntax.
515 // We cannot access %AsyncIteratorPrototype% without non-ES2018 syntax, but we can re-create it.
516 AsyncIteratorPrototype = {
517 // 25.1.3.1 %AsyncIteratorPrototype% [ @@asyncIterator ] ( )
518 // https://tc39.github.io/ecma262/#sec-asynciteratorprototype-asynciterator
519 [SymbolPolyfill.asyncIterator]() {
520 return this;
521 }
522 };
523 Object.defineProperty(AsyncIteratorPrototype, SymbolPolyfill.asyncIterator, { enumerable: false });
524}
525
526/// <reference lib="es2018.asynciterable" />
527class ReadableStreamAsyncIteratorImpl {
528 constructor(reader, preventCancel) {
529 this._ongoingPromise = undefined;
530 this._isFinished = false;
531 this._reader = reader;
532 this._preventCancel = preventCancel;
533 }
534 next() {
535 const nextSteps = () => this._nextSteps();
536 this._ongoingPromise = this._ongoingPromise ?
537 transformPromiseWith(this._ongoingPromise, nextSteps, nextSteps) :
538 nextSteps();
539 return this._ongoingPromise;
540 }
541 return(value) {
542 const returnSteps = () => this._returnSteps(value);
543 return this._ongoingPromise ?
544 transformPromiseWith(this._ongoingPromise, returnSteps, returnSteps) :
545 returnSteps();
546 }
547 _nextSteps() {
548 if (this._isFinished) {
549 return Promise.resolve({ value: undefined, done: true });
550 }
551 const reader = this._reader;
552 if (reader._ownerReadableStream === undefined) {
553 return promiseRejectedWith(readerLockException('iterate'));
554 }
555 let resolvePromise;
556 let rejectPromise;
557 const promise = newPromise((resolve, reject) => {
558 resolvePromise = resolve;
559 rejectPromise = reject;
560 });
561 const readRequest = {
562 _chunkSteps: chunk => {
563 this._ongoingPromise = undefined;
564 // This needs to be delayed by one microtask, otherwise we stop pulling too early which breaks a test.
565 // FIXME Is this a bug in the specification, or in the test?
566 queueMicrotask(() => resolvePromise({ value: chunk, done: false }));
567 },
568 _closeSteps: () => {
569 this._ongoingPromise = undefined;
570 this._isFinished = true;
571 ReadableStreamReaderGenericRelease(reader);
572 resolvePromise({ value: undefined, done: true });
573 },
574 _errorSteps: reason => {
575 this._ongoingPromise = undefined;
576 this._isFinished = true;
577 ReadableStreamReaderGenericRelease(reader);
578 rejectPromise(reason);
579 }
580 };
581 ReadableStreamDefaultReaderRead(reader, readRequest);
582 return promise;
583 }
584 _returnSteps(value) {
585 if (this._isFinished) {
586 return Promise.resolve({ value, done: true });
587 }
588 this._isFinished = true;
589 const reader = this._reader;
590 if (reader._ownerReadableStream === undefined) {
591 return promiseRejectedWith(readerLockException('finish iterating'));
592 }
593 if (!this._preventCancel) {
594 const result = ReadableStreamReaderGenericCancel(reader, value);
595 ReadableStreamReaderGenericRelease(reader);
596 return transformPromiseWith(result, () => ({ value, done: true }));
597 }
598 ReadableStreamReaderGenericRelease(reader);
599 return promiseResolvedWith({ value, done: true });
600 }
601}
602const ReadableStreamAsyncIteratorPrototype = {
603 next() {
604 if (!IsReadableStreamAsyncIterator(this)) {
605 return promiseRejectedWith(streamAsyncIteratorBrandCheckException('next'));
606 }
607 return this._asyncIteratorImpl.next();
608 },
609 return(value) {
610 if (!IsReadableStreamAsyncIterator(this)) {
611 return promiseRejectedWith(streamAsyncIteratorBrandCheckException('return'));
612 }
613 return this._asyncIteratorImpl.return(value);
614 }
615};
616if (AsyncIteratorPrototype !== undefined) {
617 Object.setPrototypeOf(ReadableStreamAsyncIteratorPrototype, AsyncIteratorPrototype);
618}
619// Abstract operations for the ReadableStream.
620function AcquireReadableStreamAsyncIterator(stream, preventCancel) {
621 const reader = AcquireReadableStreamDefaultReader(stream);
622 const impl = new ReadableStreamAsyncIteratorImpl(reader, preventCancel);
623 const iterator = Object.create(ReadableStreamAsyncIteratorPrototype);
624 iterator._asyncIteratorImpl = impl;
625 return iterator;
626}
627function IsReadableStreamAsyncIterator(x) {
628 if (!typeIsObject(x)) {
629 return false;
630 }
631 if (!Object.prototype.hasOwnProperty.call(x, '_asyncIteratorImpl')) {
632 return false;
633 }
634 return true;
635}
636// Helper functions for the ReadableStream.
637function streamAsyncIteratorBrandCheckException(name) {
638 return new TypeError(`ReadableStreamAsyncIterator.${name} can only be used on a ReadableSteamAsyncIterator`);
639}
640
641/// <reference lib="es2015.core" />
642// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/isNaN#Polyfill
643const NumberIsNaN = Number.isNaN || function (x) {
644 // eslint-disable-next-line no-self-compare
645 return x !== x;
646};
647
648function IsFiniteNonNegativeNumber(v) {
649 if (!IsNonNegativeNumber(v)) {
650 return false;
651 }
652 if (v === Infinity) {
653 return false;
654 }
655 return true;
656}
657function IsNonNegativeNumber(v) {
658 if (typeof v !== 'number') {
659 return false;
660 }
661 if (NumberIsNaN(v)) {
662 return false;
663 }
664 if (v < 0) {
665 return false;
666 }
667 return true;
668}
669
670function DequeueValue(container) {
671 const pair = container._queue.shift();
672 container._queueTotalSize -= pair.size;
673 if (container._queueTotalSize < 0) {
674 container._queueTotalSize = 0;
675 }
676 return pair.value;
677}
678function EnqueueValueWithSize(container, value, size) {
679 size = Number(size);
680 if (!IsFiniteNonNegativeNumber(size)) {
681 throw new RangeError('Size must be a finite, non-NaN, non-negative number.');
682 }
683 container._queue.push({ value, size });
684 container._queueTotalSize += size;
685}
686function PeekQueueValue(container) {
687 const pair = container._queue.peek();
688 return pair.value;
689}
690function ResetQueue(container) {
691 container._queue = new SimpleQueue();
692 container._queueTotalSize = 0;
693}
694
695function CreateArrayFromList(elements) {
696 // We use arrays to represent lists, so this is basically a no-op.
697 // Do a slice though just in case we happen to depend on the unique-ness.
698 return elements.slice();
699}
700function CopyDataBlockBytes(dest, destOffset, src, srcOffset, n) {
701 new Uint8Array(dest).set(new Uint8Array(src, srcOffset, n), destOffset);
702}
703// Not implemented correctly
704function TransferArrayBuffer(O) {
705 return O;
706}
707// Not implemented correctly
708function IsDetachedBuffer(O) {
709 return false;
710}
711
712/**
713 * A pull-into request in a {@link ReadableByteStreamController}.
714 *
715 * @public
716 */
717class ReadableStreamBYOBRequest {
718 constructor() {
719 throw new TypeError('Illegal constructor');
720 }
721 /**
722 * Returns the view for writing in to, or `null` if the BYOB request has already been responded to.
723 */
724 get view() {
725 if (!IsReadableStreamBYOBRequest(this)) {
726 throw byobRequestBrandCheckException('view');
727 }
728 return this._view;
729 }
730 respond(bytesWritten) {
731 if (!IsReadableStreamBYOBRequest(this)) {
732 throw byobRequestBrandCheckException('respond');
733 }
734 assertRequiredArgument(bytesWritten, 1, 'respond');
735 bytesWritten = convertUnsignedLongLongWithEnforceRange(bytesWritten, 'First parameter');
736 if (this._associatedReadableByteStreamController === undefined) {
737 throw new TypeError('This BYOB request has been invalidated');
738 }
739 if (IsDetachedBuffer(this._view.buffer)) ;
740 ReadableByteStreamControllerRespond(this._associatedReadableByteStreamController, bytesWritten);
741 }
742 respondWithNewView(view) {
743 if (!IsReadableStreamBYOBRequest(this)) {
744 throw byobRequestBrandCheckException('respondWithNewView');
745 }
746 assertRequiredArgument(view, 1, 'respondWithNewView');
747 if (!ArrayBuffer.isView(view)) {
748 throw new TypeError('You can only respond with array buffer views');
749 }
750 if (view.byteLength === 0) {
751 throw new TypeError('chunk must have non-zero byteLength');
752 }
753 if (view.buffer.byteLength === 0) {
754 throw new TypeError(`chunk's buffer must have non-zero byteLength`);
755 }
756 if (this._associatedReadableByteStreamController === undefined) {
757 throw new TypeError('This BYOB request has been invalidated');
758 }
759 ReadableByteStreamControllerRespondWithNewView(this._associatedReadableByteStreamController, view);
760 }
761}
762Object.defineProperties(ReadableStreamBYOBRequest.prototype, {
763 respond: { enumerable: true },
764 respondWithNewView: { enumerable: true },
765 view: { enumerable: true }
766});
767if (typeof SymbolPolyfill.toStringTag === 'symbol') {
768 Object.defineProperty(ReadableStreamBYOBRequest.prototype, SymbolPolyfill.toStringTag, {
769 value: 'ReadableStreamBYOBRequest',
770 configurable: true
771 });
772}
773/**
774 * Allows control of a {@link ReadableStream | readable byte stream}'s state and internal queue.
775 *
776 * @public
777 */
778class ReadableByteStreamController {
779 constructor() {
780 throw new TypeError('Illegal constructor');
781 }
782 /**
783 * Returns the current BYOB pull request, or `null` if there isn't one.
784 */
785 get byobRequest() {
786 if (!IsReadableByteStreamController(this)) {
787 throw byteStreamControllerBrandCheckException('byobRequest');
788 }
789 if (this._byobRequest === null && this._pendingPullIntos.length > 0) {
790 const firstDescriptor = this._pendingPullIntos.peek();
791 const view = new Uint8Array(firstDescriptor.buffer, firstDescriptor.byteOffset + firstDescriptor.bytesFilled, firstDescriptor.byteLength - firstDescriptor.bytesFilled);
792 const byobRequest = Object.create(ReadableStreamBYOBRequest.prototype);
793 SetUpReadableStreamBYOBRequest(byobRequest, this, view);
794 this._byobRequest = byobRequest;
795 }
796 return this._byobRequest;
797 }
798 /**
799 * Returns the desired size to fill the controlled stream's internal queue. It can be negative, if the queue is
800 * over-full. An underlying byte source ought to use this information to determine when and how to apply backpressure.
801 */
802 get desiredSize() {
803 if (!IsReadableByteStreamController(this)) {
804 throw byteStreamControllerBrandCheckException('desiredSize');
805 }
806 return ReadableByteStreamControllerGetDesiredSize(this);
807 }
808 /**
809 * Closes the controlled readable stream. Consumers will still be able to read any previously-enqueued chunks from
810 * the stream, but once those are read, the stream will become closed.
811 */
812 close() {
813 if (!IsReadableByteStreamController(this)) {
814 throw byteStreamControllerBrandCheckException('close');
815 }
816 if (this._closeRequested) {
817 throw new TypeError('The stream has already been closed; do not close it again!');
818 }
819 const state = this._controlledReadableByteStream._state;
820 if (state !== 'readable') {
821 throw new TypeError(`The stream (in ${state} state) is not in the readable state and cannot be closed`);
822 }
823 ReadableByteStreamControllerClose(this);
824 }
825 enqueue(chunk) {
826 if (!IsReadableByteStreamController(this)) {
827 throw byteStreamControllerBrandCheckException('enqueue');
828 }
829 assertRequiredArgument(chunk, 1, 'enqueue');
830 if (!ArrayBuffer.isView(chunk)) {
831 throw new TypeError('chunk must be an array buffer view');
832 }
833 if (chunk.byteLength === 0) {
834 throw new TypeError('chunk must have non-zero byteLength');
835 }
836 if (chunk.buffer.byteLength === 0) {
837 throw new TypeError(`chunk's buffer must have non-zero byteLength`);
838 }
839 if (this._closeRequested) {
840 throw new TypeError('stream is closed or draining');
841 }
842 const state = this._controlledReadableByteStream._state;
843 if (state !== 'readable') {
844 throw new TypeError(`The stream (in ${state} state) is not in the readable state and cannot be enqueued to`);
845 }
846 ReadableByteStreamControllerEnqueue(this, chunk);
847 }
848 /**
849 * Errors the controlled readable stream, making all future interactions with it fail with the given error `e`.
850 */
851 error(e = undefined) {
852 if (!IsReadableByteStreamController(this)) {
853 throw byteStreamControllerBrandCheckException('error');
854 }
855 ReadableByteStreamControllerError(this, e);
856 }
857 /** @internal */
858 [CancelSteps](reason) {
859 if (this._pendingPullIntos.length > 0) {
860 const firstDescriptor = this._pendingPullIntos.peek();
861 firstDescriptor.bytesFilled = 0;
862 }
863 ResetQueue(this);
864 const result = this._cancelAlgorithm(reason);
865 ReadableByteStreamControllerClearAlgorithms(this);
866 return result;
867 }
868 /** @internal */
869 [PullSteps](readRequest) {
870 const stream = this._controlledReadableByteStream;
871 if (this._queueTotalSize > 0) {
872 const entry = this._queue.shift();
873 this._queueTotalSize -= entry.byteLength;
874 ReadableByteStreamControllerHandleQueueDrain(this);
875 const view = new Uint8Array(entry.buffer, entry.byteOffset, entry.byteLength);
876 readRequest._chunkSteps(view);
877 return;
878 }
879 const autoAllocateChunkSize = this._autoAllocateChunkSize;
880 if (autoAllocateChunkSize !== undefined) {
881 let buffer;
882 try {
883 buffer = new ArrayBuffer(autoAllocateChunkSize);
884 }
885 catch (bufferE) {
886 readRequest._errorSteps(bufferE);
887 return;
888 }
889 const pullIntoDescriptor = {
890 buffer,
891 byteOffset: 0,
892 byteLength: autoAllocateChunkSize,
893 bytesFilled: 0,
894 elementSize: 1,
895 viewConstructor: Uint8Array,
896 readerType: 'default'
897 };
898 this._pendingPullIntos.push(pullIntoDescriptor);
899 }
900 ReadableStreamAddReadRequest(stream, readRequest);
901 ReadableByteStreamControllerCallPullIfNeeded(this);
902 }
903}
904Object.defineProperties(ReadableByteStreamController.prototype, {
905 close: { enumerable: true },
906 enqueue: { enumerable: true },
907 error: { enumerable: true },
908 byobRequest: { enumerable: true },
909 desiredSize: { enumerable: true }
910});
911if (typeof SymbolPolyfill.toStringTag === 'symbol') {
912 Object.defineProperty(ReadableByteStreamController.prototype, SymbolPolyfill.toStringTag, {
913 value: 'ReadableByteStreamController',
914 configurable: true
915 });
916}
917// Abstract operations for the ReadableByteStreamController.
918function IsReadableByteStreamController(x) {
919 if (!typeIsObject(x)) {
920 return false;
921 }
922 if (!Object.prototype.hasOwnProperty.call(x, '_controlledReadableByteStream')) {
923 return false;
924 }
925 return true;
926}
927function IsReadableStreamBYOBRequest(x) {
928 if (!typeIsObject(x)) {
929 return false;
930 }
931 if (!Object.prototype.hasOwnProperty.call(x, '_associatedReadableByteStreamController')) {
932 return false;
933 }
934 return true;
935}
936function ReadableByteStreamControllerCallPullIfNeeded(controller) {
937 const shouldPull = ReadableByteStreamControllerShouldCallPull(controller);
938 if (!shouldPull) {
939 return;
940 }
941 if (controller._pulling) {
942 controller._pullAgain = true;
943 return;
944 }
945 controller._pulling = true;
946 // TODO: Test controller argument
947 const pullPromise = controller._pullAlgorithm();
948 uponPromise(pullPromise, () => {
949 controller._pulling = false;
950 if (controller._pullAgain) {
951 controller._pullAgain = false;
952 ReadableByteStreamControllerCallPullIfNeeded(controller);
953 }
954 }, e => {
955 ReadableByteStreamControllerError(controller, e);
956 });
957}
958function ReadableByteStreamControllerClearPendingPullIntos(controller) {
959 ReadableByteStreamControllerInvalidateBYOBRequest(controller);
960 controller._pendingPullIntos = new SimpleQueue();
961}
962function ReadableByteStreamControllerCommitPullIntoDescriptor(stream, pullIntoDescriptor) {
963 let done = false;
964 if (stream._state === 'closed') {
965 done = true;
966 }
967 const filledView = ReadableByteStreamControllerConvertPullIntoDescriptor(pullIntoDescriptor);
968 if (pullIntoDescriptor.readerType === 'default') {
969 ReadableStreamFulfillReadRequest(stream, filledView, done);
970 }
971 else {
972 ReadableStreamFulfillReadIntoRequest(stream, filledView, done);
973 }
974}
975function ReadableByteStreamControllerConvertPullIntoDescriptor(pullIntoDescriptor) {
976 const bytesFilled = pullIntoDescriptor.bytesFilled;
977 const elementSize = pullIntoDescriptor.elementSize;
978 return new pullIntoDescriptor.viewConstructor(pullIntoDescriptor.buffer, pullIntoDescriptor.byteOffset, bytesFilled / elementSize);
979}
980function ReadableByteStreamControllerEnqueueChunkToQueue(controller, buffer, byteOffset, byteLength) {
981 controller._queue.push({ buffer, byteOffset, byteLength });
982 controller._queueTotalSize += byteLength;
983}
984function ReadableByteStreamControllerFillPullIntoDescriptorFromQueue(controller, pullIntoDescriptor) {
985 const elementSize = pullIntoDescriptor.elementSize;
986 const currentAlignedBytes = pullIntoDescriptor.bytesFilled - pullIntoDescriptor.bytesFilled % elementSize;
987 const maxBytesToCopy = Math.min(controller._queueTotalSize, pullIntoDescriptor.byteLength - pullIntoDescriptor.bytesFilled);
988 const maxBytesFilled = pullIntoDescriptor.bytesFilled + maxBytesToCopy;
989 const maxAlignedBytes = maxBytesFilled - maxBytesFilled % elementSize;
990 let totalBytesToCopyRemaining = maxBytesToCopy;
991 let ready = false;
992 if (maxAlignedBytes > currentAlignedBytes) {
993 totalBytesToCopyRemaining = maxAlignedBytes - pullIntoDescriptor.bytesFilled;
994 ready = true;
995 }
996 const queue = controller._queue;
997 while (totalBytesToCopyRemaining > 0) {
998 const headOfQueue = queue.peek();
999 const bytesToCopy = Math.min(totalBytesToCopyRemaining, headOfQueue.byteLength);
1000 const destStart = pullIntoDescriptor.byteOffset + pullIntoDescriptor.bytesFilled;
1001 CopyDataBlockBytes(pullIntoDescriptor.buffer, destStart, headOfQueue.buffer, headOfQueue.byteOffset, bytesToCopy);
1002 if (headOfQueue.byteLength === bytesToCopy) {
1003 queue.shift();
1004 }
1005 else {
1006 headOfQueue.byteOffset += bytesToCopy;
1007 headOfQueue.byteLength -= bytesToCopy;
1008 }
1009 controller._queueTotalSize -= bytesToCopy;
1010 ReadableByteStreamControllerFillHeadPullIntoDescriptor(controller, bytesToCopy, pullIntoDescriptor);
1011 totalBytesToCopyRemaining -= bytesToCopy;
1012 }
1013 return ready;
1014}
1015function ReadableByteStreamControllerFillHeadPullIntoDescriptor(controller, size, pullIntoDescriptor) {
1016 ReadableByteStreamControllerInvalidateBYOBRequest(controller);
1017 pullIntoDescriptor.bytesFilled += size;
1018}
1019function ReadableByteStreamControllerHandleQueueDrain(controller) {
1020 if (controller._queueTotalSize === 0 && controller._closeRequested) {
1021 ReadableByteStreamControllerClearAlgorithms(controller);
1022 ReadableStreamClose(controller._controlledReadableByteStream);
1023 }
1024 else {
1025 ReadableByteStreamControllerCallPullIfNeeded(controller);
1026 }
1027}
1028function ReadableByteStreamControllerInvalidateBYOBRequest(controller) {
1029 if (controller._byobRequest === null) {
1030 return;
1031 }
1032 controller._byobRequest._associatedReadableByteStreamController = undefined;
1033 controller._byobRequest._view = null;
1034 controller._byobRequest = null;
1035}
1036function ReadableByteStreamControllerProcessPullIntoDescriptorsUsingQueue(controller) {
1037 while (controller._pendingPullIntos.length > 0) {
1038 if (controller._queueTotalSize === 0) {
1039 return;
1040 }
1041 const pullIntoDescriptor = controller._pendingPullIntos.peek();
1042 if (ReadableByteStreamControllerFillPullIntoDescriptorFromQueue(controller, pullIntoDescriptor)) {
1043 ReadableByteStreamControllerShiftPendingPullInto(controller);
1044 ReadableByteStreamControllerCommitPullIntoDescriptor(controller._controlledReadableByteStream, pullIntoDescriptor);
1045 }
1046 }
1047}
1048function ReadableByteStreamControllerPullInto(controller, view, readIntoRequest) {
1049 const stream = controller._controlledReadableByteStream;
1050 let elementSize = 1;
1051 if (view.constructor !== DataView) {
1052 elementSize = view.constructor.BYTES_PER_ELEMENT;
1053 }
1054 const ctor = view.constructor;
1055 const buffer = TransferArrayBuffer(view.buffer);
1056 const pullIntoDescriptor = {
1057 buffer,
1058 byteOffset: view.byteOffset,
1059 byteLength: view.byteLength,
1060 bytesFilled: 0,
1061 elementSize,
1062 viewConstructor: ctor,
1063 readerType: 'byob'
1064 };
1065 if (controller._pendingPullIntos.length > 0) {
1066 controller._pendingPullIntos.push(pullIntoDescriptor);
1067 // No ReadableByteStreamControllerCallPullIfNeeded() call since:
1068 // - No change happens on desiredSize
1069 // - The source has already been notified of that there's at least 1 pending read(view)
1070 ReadableStreamAddReadIntoRequest(stream, readIntoRequest);
1071 return;
1072 }
1073 if (stream._state === 'closed') {
1074 const emptyView = new ctor(pullIntoDescriptor.buffer, pullIntoDescriptor.byteOffset, 0);
1075 readIntoRequest._closeSteps(emptyView);
1076 return;
1077 }
1078 if (controller._queueTotalSize > 0) {
1079 if (ReadableByteStreamControllerFillPullIntoDescriptorFromQueue(controller, pullIntoDescriptor)) {
1080 const filledView = ReadableByteStreamControllerConvertPullIntoDescriptor(pullIntoDescriptor);
1081 ReadableByteStreamControllerHandleQueueDrain(controller);
1082 readIntoRequest._chunkSteps(filledView);
1083 return;
1084 }
1085 if (controller._closeRequested) {
1086 const e = new TypeError('Insufficient bytes to fill elements in the given buffer');
1087 ReadableByteStreamControllerError(controller, e);
1088 readIntoRequest._errorSteps(e);
1089 return;
1090 }
1091 }
1092 controller._pendingPullIntos.push(pullIntoDescriptor);
1093 ReadableStreamAddReadIntoRequest(stream, readIntoRequest);
1094 ReadableByteStreamControllerCallPullIfNeeded(controller);
1095}
1096function ReadableByteStreamControllerRespondInClosedState(controller, firstDescriptor) {
1097 firstDescriptor.buffer = TransferArrayBuffer(firstDescriptor.buffer);
1098 const stream = controller._controlledReadableByteStream;
1099 if (ReadableStreamHasBYOBReader(stream)) {
1100 while (ReadableStreamGetNumReadIntoRequests(stream) > 0) {
1101 const pullIntoDescriptor = ReadableByteStreamControllerShiftPendingPullInto(controller);
1102 ReadableByteStreamControllerCommitPullIntoDescriptor(stream, pullIntoDescriptor);
1103 }
1104 }
1105}
1106function ReadableByteStreamControllerRespondInReadableState(controller, bytesWritten, pullIntoDescriptor) {
1107 if (pullIntoDescriptor.bytesFilled + bytesWritten > pullIntoDescriptor.byteLength) {
1108 throw new RangeError('bytesWritten out of range');
1109 }
1110 ReadableByteStreamControllerFillHeadPullIntoDescriptor(controller, bytesWritten, pullIntoDescriptor);
1111 if (pullIntoDescriptor.bytesFilled < pullIntoDescriptor.elementSize) {
1112 // TODO: Figure out whether we should detach the buffer or not here.
1113 return;
1114 }
1115 ReadableByteStreamControllerShiftPendingPullInto(controller);
1116 const remainderSize = pullIntoDescriptor.bytesFilled % pullIntoDescriptor.elementSize;
1117 if (remainderSize > 0) {
1118 const end = pullIntoDescriptor.byteOffset + pullIntoDescriptor.bytesFilled;
1119 const remainder = pullIntoDescriptor.buffer.slice(end - remainderSize, end);
1120 ReadableByteStreamControllerEnqueueChunkToQueue(controller, remainder, 0, remainder.byteLength);
1121 }
1122 pullIntoDescriptor.buffer = TransferArrayBuffer(pullIntoDescriptor.buffer);
1123 pullIntoDescriptor.bytesFilled -= remainderSize;
1124 ReadableByteStreamControllerCommitPullIntoDescriptor(controller._controlledReadableByteStream, pullIntoDescriptor);
1125 ReadableByteStreamControllerProcessPullIntoDescriptorsUsingQueue(controller);
1126}
1127function ReadableByteStreamControllerRespondInternal(controller, bytesWritten) {
1128 const firstDescriptor = controller._pendingPullIntos.peek();
1129 const state = controller._controlledReadableByteStream._state;
1130 if (state === 'closed') {
1131 if (bytesWritten !== 0) {
1132 throw new TypeError('bytesWritten must be 0 when calling respond() on a closed stream');
1133 }
1134 ReadableByteStreamControllerRespondInClosedState(controller, firstDescriptor);
1135 }
1136 else {
1137 ReadableByteStreamControllerRespondInReadableState(controller, bytesWritten, firstDescriptor);
1138 }
1139 ReadableByteStreamControllerCallPullIfNeeded(controller);
1140}
1141function ReadableByteStreamControllerShiftPendingPullInto(controller) {
1142 const descriptor = controller._pendingPullIntos.shift();
1143 ReadableByteStreamControllerInvalidateBYOBRequest(controller);
1144 return descriptor;
1145}
1146function ReadableByteStreamControllerShouldCallPull(controller) {
1147 const stream = controller._controlledReadableByteStream;
1148 if (stream._state !== 'readable') {
1149 return false;
1150 }
1151 if (controller._closeRequested) {
1152 return false;
1153 }
1154 if (!controller._started) {
1155 return false;
1156 }
1157 if (ReadableStreamHasDefaultReader(stream) && ReadableStreamGetNumReadRequests(stream) > 0) {
1158 return true;
1159 }
1160 if (ReadableStreamHasBYOBReader(stream) && ReadableStreamGetNumReadIntoRequests(stream) > 0) {
1161 return true;
1162 }
1163 const desiredSize = ReadableByteStreamControllerGetDesiredSize(controller);
1164 if (desiredSize > 0) {
1165 return true;
1166 }
1167 return false;
1168}
1169function ReadableByteStreamControllerClearAlgorithms(controller) {
1170 controller._pullAlgorithm = undefined;
1171 controller._cancelAlgorithm = undefined;
1172}
1173// A client of ReadableByteStreamController may use these functions directly to bypass state check.
1174function ReadableByteStreamControllerClose(controller) {
1175 const stream = controller._controlledReadableByteStream;
1176 if (controller._closeRequested || stream._state !== 'readable') {
1177 return;
1178 }
1179 if (controller._queueTotalSize > 0) {
1180 controller._closeRequested = true;
1181 return;
1182 }
1183 if (controller._pendingPullIntos.length > 0) {
1184 const firstPendingPullInto = controller._pendingPullIntos.peek();
1185 if (firstPendingPullInto.bytesFilled > 0) {
1186 const e = new TypeError('Insufficient bytes to fill elements in the given buffer');
1187 ReadableByteStreamControllerError(controller, e);
1188 throw e;
1189 }
1190 }
1191 ReadableByteStreamControllerClearAlgorithms(controller);
1192 ReadableStreamClose(stream);
1193}
1194function ReadableByteStreamControllerEnqueue(controller, chunk) {
1195 const stream = controller._controlledReadableByteStream;
1196 if (controller._closeRequested || stream._state !== 'readable') {
1197 return;
1198 }
1199 const buffer = chunk.buffer;
1200 const byteOffset = chunk.byteOffset;
1201 const byteLength = chunk.byteLength;
1202 const transferredBuffer = TransferArrayBuffer(buffer);
1203 if (ReadableStreamHasDefaultReader(stream)) {
1204 if (ReadableStreamGetNumReadRequests(stream) === 0) {
1205 ReadableByteStreamControllerEnqueueChunkToQueue(controller, transferredBuffer, byteOffset, byteLength);
1206 }
1207 else {
1208 const transferredView = new Uint8Array(transferredBuffer, byteOffset, byteLength);
1209 ReadableStreamFulfillReadRequest(stream, transferredView, false);
1210 }
1211 }
1212 else if (ReadableStreamHasBYOBReader(stream)) {
1213 // TODO: Ideally in this branch detaching should happen only if the buffer is not consumed fully.
1214 ReadableByteStreamControllerEnqueueChunkToQueue(controller, transferredBuffer, byteOffset, byteLength);
1215 ReadableByteStreamControllerProcessPullIntoDescriptorsUsingQueue(controller);
1216 }
1217 else {
1218 ReadableByteStreamControllerEnqueueChunkToQueue(controller, transferredBuffer, byteOffset, byteLength);
1219 }
1220 ReadableByteStreamControllerCallPullIfNeeded(controller);
1221}
1222function ReadableByteStreamControllerError(controller, e) {
1223 const stream = controller._controlledReadableByteStream;
1224 if (stream._state !== 'readable') {
1225 return;
1226 }
1227 ReadableByteStreamControllerClearPendingPullIntos(controller);
1228 ResetQueue(controller);
1229 ReadableByteStreamControllerClearAlgorithms(controller);
1230 ReadableStreamError(stream, e);
1231}
1232function ReadableByteStreamControllerGetDesiredSize(controller) {
1233 const state = controller._controlledReadableByteStream._state;
1234 if (state === 'errored') {
1235 return null;
1236 }
1237 if (state === 'closed') {
1238 return 0;
1239 }
1240 return controller._strategyHWM - controller._queueTotalSize;
1241}
1242function ReadableByteStreamControllerRespond(controller, bytesWritten) {
1243 bytesWritten = Number(bytesWritten);
1244 if (!IsFiniteNonNegativeNumber(bytesWritten)) {
1245 throw new RangeError('bytesWritten must be a finite');
1246 }
1247 ReadableByteStreamControllerRespondInternal(controller, bytesWritten);
1248}
1249function ReadableByteStreamControllerRespondWithNewView(controller, view) {
1250 const firstDescriptor = controller._pendingPullIntos.peek();
1251 if (firstDescriptor.byteOffset + firstDescriptor.bytesFilled !== view.byteOffset) {
1252 throw new RangeError('The region specified by view does not match byobRequest');
1253 }
1254 if (firstDescriptor.byteLength !== view.byteLength) {
1255 throw new RangeError('The buffer of view has different capacity than byobRequest');
1256 }
1257 firstDescriptor.buffer = view.buffer;
1258 ReadableByteStreamControllerRespondInternal(controller, view.byteLength);
1259}
1260function SetUpReadableByteStreamController(stream, controller, startAlgorithm, pullAlgorithm, cancelAlgorithm, highWaterMark, autoAllocateChunkSize) {
1261 controller._controlledReadableByteStream = stream;
1262 controller._pullAgain = false;
1263 controller._pulling = false;
1264 controller._byobRequest = null;
1265 // Need to set the slots so that the assert doesn't fire. In the spec the slots already exist implicitly.
1266 controller._queue = controller._queueTotalSize = undefined;
1267 ResetQueue(controller);
1268 controller._closeRequested = false;
1269 controller._started = false;
1270 controller._strategyHWM = highWaterMark;
1271 controller._pullAlgorithm = pullAlgorithm;
1272 controller._cancelAlgorithm = cancelAlgorithm;
1273 controller._autoAllocateChunkSize = autoAllocateChunkSize;
1274 controller._pendingPullIntos = new SimpleQueue();
1275 stream._readableStreamController = controller;
1276 const startResult = startAlgorithm();
1277 uponPromise(promiseResolvedWith(startResult), () => {
1278 controller._started = true;
1279 ReadableByteStreamControllerCallPullIfNeeded(controller);
1280 }, r => {
1281 ReadableByteStreamControllerError(controller, r);
1282 });
1283}
1284function SetUpReadableByteStreamControllerFromUnderlyingSource(stream, underlyingByteSource, highWaterMark) {
1285 const controller = Object.create(ReadableByteStreamController.prototype);
1286 let startAlgorithm = () => undefined;
1287 let pullAlgorithm = () => promiseResolvedWith(undefined);
1288 let cancelAlgorithm = () => promiseResolvedWith(undefined);
1289 if (underlyingByteSource.start !== undefined) {
1290 startAlgorithm = () => underlyingByteSource.start(controller);
1291 }
1292 if (underlyingByteSource.pull !== undefined) {
1293 pullAlgorithm = () => underlyingByteSource.pull(controller);
1294 }
1295 if (underlyingByteSource.cancel !== undefined) {
1296 cancelAlgorithm = reason => underlyingByteSource.cancel(reason);
1297 }
1298 const autoAllocateChunkSize = underlyingByteSource.autoAllocateChunkSize;
1299 if (autoAllocateChunkSize === 0) {
1300 throw new TypeError('autoAllocateChunkSize must be greater than 0');
1301 }
1302 SetUpReadableByteStreamController(stream, controller, startAlgorithm, pullAlgorithm, cancelAlgorithm, highWaterMark, autoAllocateChunkSize);
1303}
1304function SetUpReadableStreamBYOBRequest(request, controller, view) {
1305 request._associatedReadableByteStreamController = controller;
1306 request._view = view;
1307}
1308// Helper functions for the ReadableStreamBYOBRequest.
1309function byobRequestBrandCheckException(name) {
1310 return new TypeError(`ReadableStreamBYOBRequest.prototype.${name} can only be used on a ReadableStreamBYOBRequest`);
1311}
1312// Helper functions for the ReadableByteStreamController.
1313function byteStreamControllerBrandCheckException(name) {
1314 return new TypeError(`ReadableByteStreamController.prototype.${name} can only be used on a ReadableByteStreamController`);
1315}
1316
1317// Abstract operations for the ReadableStream.
1318function AcquireReadableStreamBYOBReader(stream) {
1319 return new ReadableStreamBYOBReader(stream);
1320}
1321// ReadableStream API exposed for controllers.
1322function ReadableStreamAddReadIntoRequest(stream, readIntoRequest) {
1323 stream._reader._readIntoRequests.push(readIntoRequest);
1324}
1325function ReadableStreamFulfillReadIntoRequest(stream, chunk, done) {
1326 const reader = stream._reader;
1327 const readIntoRequest = reader._readIntoRequests.shift();
1328 if (done) {
1329 readIntoRequest._closeSteps(chunk);
1330 }
1331 else {
1332 readIntoRequest._chunkSteps(chunk);
1333 }
1334}
1335function ReadableStreamGetNumReadIntoRequests(stream) {
1336 return stream._reader._readIntoRequests.length;
1337}
1338function ReadableStreamHasBYOBReader(stream) {
1339 const reader = stream._reader;
1340 if (reader === undefined) {
1341 return false;
1342 }
1343 if (!IsReadableStreamBYOBReader(reader)) {
1344 return false;
1345 }
1346 return true;
1347}
1348/**
1349 * A BYOB reader vended by a {@link ReadableStream}.
1350 *
1351 * @public
1352 */
1353class ReadableStreamBYOBReader {
1354 constructor(stream) {
1355 assertRequiredArgument(stream, 1, 'ReadableStreamBYOBReader');
1356 assertReadableStream(stream, 'First parameter');
1357 if (IsReadableStreamLocked(stream)) {
1358 throw new TypeError('This stream has already been locked for exclusive reading by another reader');
1359 }
1360 if (!IsReadableByteStreamController(stream._readableStreamController)) {
1361 throw new TypeError('Cannot construct a ReadableStreamBYOBReader for a stream not constructed with a byte ' +
1362 'source');
1363 }
1364 ReadableStreamReaderGenericInitialize(this, stream);
1365 this._readIntoRequests = new SimpleQueue();
1366 }
1367 /**
1368 * Returns a promise that will be fulfilled when the stream becomes closed, or rejected if the stream ever errors or
1369 * the reader's lock is released before the stream finishes closing.
1370 */
1371 get closed() {
1372 if (!IsReadableStreamBYOBReader(this)) {
1373 return promiseRejectedWith(byobReaderBrandCheckException('closed'));
1374 }
1375 return this._closedPromise;
1376 }
1377 /**
1378 * If the reader is active, behaves the same as {@link ReadableStream.cancel | stream.cancel(reason)}.
1379 */
1380 cancel(reason = undefined) {
1381 if (!IsReadableStreamBYOBReader(this)) {
1382 return promiseRejectedWith(byobReaderBrandCheckException('cancel'));
1383 }
1384 if (this._ownerReadableStream === undefined) {
1385 return promiseRejectedWith(readerLockException('cancel'));
1386 }
1387 return ReadableStreamReaderGenericCancel(this, reason);
1388 }
1389 /**
1390 * Attempts to reads bytes into view, and returns a promise resolved with the result.
1391 *
1392 * If reading a chunk causes the queue to become empty, more data will be pulled from the underlying source.
1393 */
1394 read(view) {
1395 if (!IsReadableStreamBYOBReader(this)) {
1396 return promiseRejectedWith(byobReaderBrandCheckException('read'));
1397 }
1398 if (!ArrayBuffer.isView(view)) {
1399 return promiseRejectedWith(new TypeError('view must be an array buffer view'));
1400 }
1401 if (view.byteLength === 0) {
1402 return promiseRejectedWith(new TypeError('view must have non-zero byteLength'));
1403 }
1404 if (view.buffer.byteLength === 0) {
1405 return promiseRejectedWith(new TypeError(`view's buffer must have non-zero byteLength`));
1406 }
1407 if (this._ownerReadableStream === undefined) {
1408 return promiseRejectedWith(readerLockException('read from'));
1409 }
1410 let resolvePromise;
1411 let rejectPromise;
1412 const promise = newPromise((resolve, reject) => {
1413 resolvePromise = resolve;
1414 rejectPromise = reject;
1415 });
1416 const readIntoRequest = {
1417 _chunkSteps: chunk => resolvePromise({ value: chunk, done: false }),
1418 _closeSteps: chunk => resolvePromise({ value: chunk, done: true }),
1419 _errorSteps: e => rejectPromise(e)
1420 };
1421 ReadableStreamBYOBReaderRead(this, view, readIntoRequest);
1422 return promise;
1423 }
1424 /**
1425 * Releases the reader's lock on the corresponding stream. After the lock is released, the reader is no longer active.
1426 * If the associated stream is errored when the lock is released, the reader will appear errored in the same way
1427 * from now on; otherwise, the reader will appear closed.
1428 *
1429 * A reader's lock cannot be released while it still has a pending read request, i.e., if a promise returned by
1430 * the reader's {@link ReadableStreamBYOBReader.read | read()} method has not yet been settled. Attempting to
1431 * do so will throw a `TypeError` and leave the reader locked to the stream.
1432 */
1433 releaseLock() {
1434 if (!IsReadableStreamBYOBReader(this)) {
1435 throw byobReaderBrandCheckException('releaseLock');
1436 }
1437 if (this._ownerReadableStream === undefined) {
1438 return;
1439 }
1440 if (this._readIntoRequests.length > 0) {
1441 throw new TypeError('Tried to release a reader lock when that reader has pending read() calls un-settled');
1442 }
1443 ReadableStreamReaderGenericRelease(this);
1444 }
1445}
1446Object.defineProperties(ReadableStreamBYOBReader.prototype, {
1447 cancel: { enumerable: true },
1448 read: { enumerable: true },
1449 releaseLock: { enumerable: true },
1450 closed: { enumerable: true }
1451});
1452if (typeof SymbolPolyfill.toStringTag === 'symbol') {
1453 Object.defineProperty(ReadableStreamBYOBReader.prototype, SymbolPolyfill.toStringTag, {
1454 value: 'ReadableStreamBYOBReader',
1455 configurable: true
1456 });
1457}
1458// Abstract operations for the readers.
1459function IsReadableStreamBYOBReader(x) {
1460 if (!typeIsObject(x)) {
1461 return false;
1462 }
1463 if (!Object.prototype.hasOwnProperty.call(x, '_readIntoRequests')) {
1464 return false;
1465 }
1466 return true;
1467}
1468function ReadableStreamBYOBReaderRead(reader, view, readIntoRequest) {
1469 const stream = reader._ownerReadableStream;
1470 stream._disturbed = true;
1471 if (stream._state === 'errored') {
1472 readIntoRequest._errorSteps(stream._storedError);
1473 }
1474 else {
1475 ReadableByteStreamControllerPullInto(stream._readableStreamController, view, readIntoRequest);
1476 }
1477}
1478// Helper functions for the ReadableStreamBYOBReader.
1479function byobReaderBrandCheckException(name) {
1480 return new TypeError(`ReadableStreamBYOBReader.prototype.${name} can only be used on a ReadableStreamBYOBReader`);
1481}
1482
1483function ExtractHighWaterMark(strategy, defaultHWM) {
1484 const { highWaterMark } = strategy;
1485 if (highWaterMark === undefined) {
1486 return defaultHWM;
1487 }
1488 if (NumberIsNaN(highWaterMark) || highWaterMark < 0) {
1489 throw new RangeError('Invalid highWaterMark');
1490 }
1491 return highWaterMark;
1492}
1493function ExtractSizeAlgorithm(strategy) {
1494 const { size } = strategy;
1495 if (!size) {
1496 return () => 1;
1497 }
1498 return size;
1499}
1500
1501function convertQueuingStrategy(init, context) {
1502 assertDictionary(init, context);
1503 const highWaterMark = init === null || init === void 0 ? void 0 : init.highWaterMark;
1504 const size = init === null || init === void 0 ? void 0 : init.size;
1505 return {
1506 highWaterMark: highWaterMark === undefined ? undefined : convertUnrestrictedDouble(highWaterMark),
1507 size: size === undefined ? undefined : convertQueuingStrategySize(size, `${context} has member 'size' that`)
1508 };
1509}
1510function convertQueuingStrategySize(fn, context) {
1511 assertFunction(fn, context);
1512 return chunk => convertUnrestrictedDouble(fn(chunk));
1513}
1514
1515function convertUnderlyingSink(original, context) {
1516 assertDictionary(original, context);
1517 const abort = original === null || original === void 0 ? void 0 : original.abort;
1518 const close = original === null || original === void 0 ? void 0 : original.close;
1519 const start = original === null || original === void 0 ? void 0 : original.start;
1520 const type = original === null || original === void 0 ? void 0 : original.type;
1521 const write = original === null || original === void 0 ? void 0 : original.write;
1522 return {
1523 abort: abort === undefined ?
1524 undefined :
1525 convertUnderlyingSinkAbortCallback(abort, original, `${context} has member 'abort' that`),
1526 close: close === undefined ?
1527 undefined :
1528 convertUnderlyingSinkCloseCallback(close, original, `${context} has member 'close' that`),
1529 start: start === undefined ?
1530 undefined :
1531 convertUnderlyingSinkStartCallback(start, original, `${context} has member 'start' that`),
1532 write: write === undefined ?
1533 undefined :
1534 convertUnderlyingSinkWriteCallback(write, original, `${context} has member 'write' that`),
1535 type
1536 };
1537}
1538function convertUnderlyingSinkAbortCallback(fn, original, context) {
1539 assertFunction(fn, context);
1540 return (reason) => promiseCall(fn, original, [reason]);
1541}
1542function convertUnderlyingSinkCloseCallback(fn, original, context) {
1543 assertFunction(fn, context);
1544 return () => promiseCall(fn, original, []);
1545}
1546function convertUnderlyingSinkStartCallback(fn, original, context) {
1547 assertFunction(fn, context);
1548 return (controller) => reflectCall(fn, original, [controller]);
1549}
1550function convertUnderlyingSinkWriteCallback(fn, original, context) {
1551 assertFunction(fn, context);
1552 return (chunk, controller) => promiseCall(fn, original, [chunk, controller]);
1553}
1554
1555function assertWritableStream(x, context) {
1556 if (!IsWritableStream(x)) {
1557 throw new TypeError(`${context} is not a WritableStream.`);
1558 }
1559}
1560
1561/**
1562 * A writable stream represents a destination for data, into which you can write.
1563 *
1564 * @public
1565 */
1566class WritableStream {
1567 constructor(rawUnderlyingSink = {}, rawStrategy = {}) {
1568 if (rawUnderlyingSink === undefined) {
1569 rawUnderlyingSink = null;
1570 }
1571 else {
1572 assertObject(rawUnderlyingSink, 'First parameter');
1573 }
1574 const strategy = convertQueuingStrategy(rawStrategy, 'Second parameter');
1575 const underlyingSink = convertUnderlyingSink(rawUnderlyingSink, 'First parameter');
1576 InitializeWritableStream(this);
1577 const type = underlyingSink.type;
1578 if (type !== undefined) {
1579 throw new RangeError('Invalid type is specified');
1580 }
1581 const sizeAlgorithm = ExtractSizeAlgorithm(strategy);
1582 const highWaterMark = ExtractHighWaterMark(strategy, 1);
1583 SetUpWritableStreamDefaultControllerFromUnderlyingSink(this, underlyingSink, highWaterMark, sizeAlgorithm);
1584 }
1585 /**
1586 * Returns whether or not the writable stream is locked to a writer.
1587 */
1588 get locked() {
1589 if (!IsWritableStream(this)) {
1590 throw streamBrandCheckException('locked');
1591 }
1592 return IsWritableStreamLocked(this);
1593 }
1594 /**
1595 * Aborts the stream, signaling that the producer can no longer successfully write to the stream and it is to be
1596 * immediately moved to an errored state, with any queued-up writes discarded. This will also execute any abort
1597 * mechanism of the underlying sink.
1598 *
1599 * The returned promise will fulfill if the stream shuts down successfully, or reject if the underlying sink signaled
1600 * that there was an error doing so. Additionally, it will reject with a `TypeError` (without attempting to cancel
1601 * the stream) if the stream is currently locked.
1602 */
1603 abort(reason = undefined) {
1604 if (!IsWritableStream(this)) {
1605 return promiseRejectedWith(streamBrandCheckException('abort'));
1606 }
1607 if (IsWritableStreamLocked(this)) {
1608 return promiseRejectedWith(new TypeError('Cannot abort a stream that already has a writer'));
1609 }
1610 return WritableStreamAbort(this, reason);
1611 }
1612 /**
1613 * Closes the stream. The underlying sink will finish processing any previously-written chunks, before invoking its
1614 * close behavior. During this time any further attempts to write will fail (without erroring the stream).
1615 *
1616 * The method returns a promise that will fulfill if all remaining chunks are successfully written and the stream
1617 * successfully closes, or rejects if an error is encountered during this process. Additionally, it will reject with
1618 * a `TypeError` (without attempting to cancel the stream) if the stream is currently locked.
1619 */
1620 close() {
1621 if (!IsWritableStream(this)) {
1622 return promiseRejectedWith(streamBrandCheckException('close'));
1623 }
1624 if (IsWritableStreamLocked(this)) {
1625 return promiseRejectedWith(new TypeError('Cannot close a stream that already has a writer'));
1626 }
1627 if (WritableStreamCloseQueuedOrInFlight(this)) {
1628 return promiseRejectedWith(new TypeError('Cannot close an already-closing stream'));
1629 }
1630 return WritableStreamClose(this);
1631 }
1632 /**
1633 * Creates a {@link WritableStreamDefaultWriter | writer} and locks the stream to the new writer. While the stream
1634 * is locked, no other writer can be acquired until this one is released.
1635 *
1636 * This functionality is especially useful for creating abstractions that desire the ability to write to a stream
1637 * without interruption or interleaving. By getting a writer for the stream, you can ensure nobody else can write at
1638 * the same time, which would cause the resulting written data to be unpredictable and probably useless.
1639 */
1640 getWriter() {
1641 if (!IsWritableStream(this)) {
1642 throw streamBrandCheckException('getWriter');
1643 }
1644 return AcquireWritableStreamDefaultWriter(this);
1645 }
1646}
1647Object.defineProperties(WritableStream.prototype, {
1648 abort: { enumerable: true },
1649 close: { enumerable: true },
1650 getWriter: { enumerable: true },
1651 locked: { enumerable: true }
1652});
1653if (typeof SymbolPolyfill.toStringTag === 'symbol') {
1654 Object.defineProperty(WritableStream.prototype, SymbolPolyfill.toStringTag, {
1655 value: 'WritableStream',
1656 configurable: true
1657 });
1658}
1659// Abstract operations for the WritableStream.
1660function AcquireWritableStreamDefaultWriter(stream) {
1661 return new WritableStreamDefaultWriter(stream);
1662}
1663// Throws if and only if startAlgorithm throws.
1664function CreateWritableStream(startAlgorithm, writeAlgorithm, closeAlgorithm, abortAlgorithm, highWaterMark = 1, sizeAlgorithm = () => 1) {
1665 const stream = Object.create(WritableStream.prototype);
1666 InitializeWritableStream(stream);
1667 const controller = Object.create(WritableStreamDefaultController.prototype);
1668 SetUpWritableStreamDefaultController(stream, controller, startAlgorithm, writeAlgorithm, closeAlgorithm, abortAlgorithm, highWaterMark, sizeAlgorithm);
1669 return stream;
1670}
1671function InitializeWritableStream(stream) {
1672 stream._state = 'writable';
1673 // The error that will be reported by new method calls once the state becomes errored. Only set when [[state]] is
1674 // 'erroring' or 'errored'. May be set to an undefined value.
1675 stream._storedError = undefined;
1676 stream._writer = undefined;
1677 // Initialize to undefined first because the constructor of the controller checks this
1678 // variable to validate the caller.
1679 stream._writableStreamController = undefined;
1680 // This queue is placed here instead of the writer class in order to allow for passing a writer to the next data
1681 // producer without waiting for the queued writes to finish.
1682 stream._writeRequests = new SimpleQueue();
1683 // Write requests are removed from _writeRequests when write() is called on the underlying sink. This prevents
1684 // them from being erroneously rejected on error. If a write() call is in-flight, the request is stored here.
1685 stream._inFlightWriteRequest = undefined;
1686 // The promise that was returned from writer.close(). Stored here because it may be fulfilled after the writer
1687 // has been detached.
1688 stream._closeRequest = undefined;
1689 // Close request is removed from _closeRequest when close() is called on the underlying sink. This prevents it
1690 // from being erroneously rejected on error. If a close() call is in-flight, the request is stored here.
1691 stream._inFlightCloseRequest = undefined;
1692 // The promise that was returned from writer.abort(). This may also be fulfilled after the writer has detached.
1693 stream._pendingAbortRequest = undefined;
1694 // The backpressure signal set by the controller.
1695 stream._backpressure = false;
1696}
1697function IsWritableStream(x) {
1698 if (!typeIsObject(x)) {
1699 return false;
1700 }
1701 if (!Object.prototype.hasOwnProperty.call(x, '_writableStreamController')) {
1702 return false;
1703 }
1704 return true;
1705}
1706function IsWritableStreamLocked(stream) {
1707 if (stream._writer === undefined) {
1708 return false;
1709 }
1710 return true;
1711}
1712function WritableStreamAbort(stream, reason) {
1713 const state = stream._state;
1714 if (state === 'closed' || state === 'errored') {
1715 return promiseResolvedWith(undefined);
1716 }
1717 if (stream._pendingAbortRequest !== undefined) {
1718 return stream._pendingAbortRequest._promise;
1719 }
1720 let wasAlreadyErroring = false;
1721 if (state === 'erroring') {
1722 wasAlreadyErroring = true;
1723 // reason will not be used, so don't keep a reference to it.
1724 reason = undefined;
1725 }
1726 const promise = newPromise((resolve, reject) => {
1727 stream._pendingAbortRequest = {
1728 _promise: undefined,
1729 _resolve: resolve,
1730 _reject: reject,
1731 _reason: reason,
1732 _wasAlreadyErroring: wasAlreadyErroring
1733 };
1734 });
1735 stream._pendingAbortRequest._promise = promise;
1736 if (!wasAlreadyErroring) {
1737 WritableStreamStartErroring(stream, reason);
1738 }
1739 return promise;
1740}
1741function WritableStreamClose(stream) {
1742 const state = stream._state;
1743 if (state === 'closed' || state === 'errored') {
1744 return promiseRejectedWith(new TypeError(`The stream (in ${state} state) is not in the writable state and cannot be closed`));
1745 }
1746 const promise = newPromise((resolve, reject) => {
1747 const closeRequest = {
1748 _resolve: resolve,
1749 _reject: reject
1750 };
1751 stream._closeRequest = closeRequest;
1752 });
1753 const writer = stream._writer;
1754 if (writer !== undefined && stream._backpressure && state === 'writable') {
1755 defaultWriterReadyPromiseResolve(writer);
1756 }
1757 WritableStreamDefaultControllerClose(stream._writableStreamController);
1758 return promise;
1759}
1760// WritableStream API exposed for controllers.
1761function WritableStreamAddWriteRequest(stream) {
1762 const promise = newPromise((resolve, reject) => {
1763 const writeRequest = {
1764 _resolve: resolve,
1765 _reject: reject
1766 };
1767 stream._writeRequests.push(writeRequest);
1768 });
1769 return promise;
1770}
1771function WritableStreamDealWithRejection(stream, error) {
1772 const state = stream._state;
1773 if (state === 'writable') {
1774 WritableStreamStartErroring(stream, error);
1775 return;
1776 }
1777 WritableStreamFinishErroring(stream);
1778}
1779function WritableStreamStartErroring(stream, reason) {
1780 const controller = stream._writableStreamController;
1781 stream._state = 'erroring';
1782 stream._storedError = reason;
1783 const writer = stream._writer;
1784 if (writer !== undefined) {
1785 WritableStreamDefaultWriterEnsureReadyPromiseRejected(writer, reason);
1786 }
1787 if (!WritableStreamHasOperationMarkedInFlight(stream) && controller._started) {
1788 WritableStreamFinishErroring(stream);
1789 }
1790}
1791function WritableStreamFinishErroring(stream) {
1792 stream._state = 'errored';
1793 stream._writableStreamController[ErrorSteps]();
1794 const storedError = stream._storedError;
1795 stream._writeRequests.forEach(writeRequest => {
1796 writeRequest._reject(storedError);
1797 });
1798 stream._writeRequests = new SimpleQueue();
1799 if (stream._pendingAbortRequest === undefined) {
1800 WritableStreamRejectCloseAndClosedPromiseIfNeeded(stream);
1801 return;
1802 }
1803 const abortRequest = stream._pendingAbortRequest;
1804 stream._pendingAbortRequest = undefined;
1805 if (abortRequest._wasAlreadyErroring) {
1806 abortRequest._reject(storedError);
1807 WritableStreamRejectCloseAndClosedPromiseIfNeeded(stream);
1808 return;
1809 }
1810 const promise = stream._writableStreamController[AbortSteps](abortRequest._reason);
1811 uponPromise(promise, () => {
1812 abortRequest._resolve();
1813 WritableStreamRejectCloseAndClosedPromiseIfNeeded(stream);
1814 }, (reason) => {
1815 abortRequest._reject(reason);
1816 WritableStreamRejectCloseAndClosedPromiseIfNeeded(stream);
1817 });
1818}
1819function WritableStreamFinishInFlightWrite(stream) {
1820 stream._inFlightWriteRequest._resolve(undefined);
1821 stream._inFlightWriteRequest = undefined;
1822}
1823function WritableStreamFinishInFlightWriteWithError(stream, error) {
1824 stream._inFlightWriteRequest._reject(error);
1825 stream._inFlightWriteRequest = undefined;
1826 WritableStreamDealWithRejection(stream, error);
1827}
1828function WritableStreamFinishInFlightClose(stream) {
1829 stream._inFlightCloseRequest._resolve(undefined);
1830 stream._inFlightCloseRequest = undefined;
1831 const state = stream._state;
1832 if (state === 'erroring') {
1833 // The error was too late to do anything, so it is ignored.
1834 stream._storedError = undefined;
1835 if (stream._pendingAbortRequest !== undefined) {
1836 stream._pendingAbortRequest._resolve();
1837 stream._pendingAbortRequest = undefined;
1838 }
1839 }
1840 stream._state = 'closed';
1841 const writer = stream._writer;
1842 if (writer !== undefined) {
1843 defaultWriterClosedPromiseResolve(writer);
1844 }
1845}
1846function WritableStreamFinishInFlightCloseWithError(stream, error) {
1847 stream._inFlightCloseRequest._reject(error);
1848 stream._inFlightCloseRequest = undefined;
1849 // Never execute sink abort() after sink close().
1850 if (stream._pendingAbortRequest !== undefined) {
1851 stream._pendingAbortRequest._reject(error);
1852 stream._pendingAbortRequest = undefined;
1853 }
1854 WritableStreamDealWithRejection(stream, error);
1855}
1856// TODO(ricea): Fix alphabetical order.
1857function WritableStreamCloseQueuedOrInFlight(stream) {
1858 if (stream._closeRequest === undefined && stream._inFlightCloseRequest === undefined) {
1859 return false;
1860 }
1861 return true;
1862}
1863function WritableStreamHasOperationMarkedInFlight(stream) {
1864 if (stream._inFlightWriteRequest === undefined && stream._inFlightCloseRequest === undefined) {
1865 return false;
1866 }
1867 return true;
1868}
1869function WritableStreamMarkCloseRequestInFlight(stream) {
1870 stream._inFlightCloseRequest = stream._closeRequest;
1871 stream._closeRequest = undefined;
1872}
1873function WritableStreamMarkFirstWriteRequestInFlight(stream) {
1874 stream._inFlightWriteRequest = stream._writeRequests.shift();
1875}
1876function WritableStreamRejectCloseAndClosedPromiseIfNeeded(stream) {
1877 if (stream._closeRequest !== undefined) {
1878 stream._closeRequest._reject(stream._storedError);
1879 stream._closeRequest = undefined;
1880 }
1881 const writer = stream._writer;
1882 if (writer !== undefined) {
1883 defaultWriterClosedPromiseReject(writer, stream._storedError);
1884 }
1885}
1886function WritableStreamUpdateBackpressure(stream, backpressure) {
1887 const writer = stream._writer;
1888 if (writer !== undefined && backpressure !== stream._backpressure) {
1889 if (backpressure) {
1890 defaultWriterReadyPromiseReset(writer);
1891 }
1892 else {
1893 defaultWriterReadyPromiseResolve(writer);
1894 }
1895 }
1896 stream._backpressure = backpressure;
1897}
1898/**
1899 * A default writer vended by a {@link WritableStream}.
1900 *
1901 * @public
1902 */
1903class WritableStreamDefaultWriter {
1904 constructor(stream) {
1905 assertRequiredArgument(stream, 1, 'WritableStreamDefaultWriter');
1906 assertWritableStream(stream, 'First parameter');
1907 if (IsWritableStreamLocked(stream)) {
1908 throw new TypeError('This stream has already been locked for exclusive writing by another writer');
1909 }
1910 this._ownerWritableStream = stream;
1911 stream._writer = this;
1912 const state = stream._state;
1913 if (state === 'writable') {
1914 if (!WritableStreamCloseQueuedOrInFlight(stream) && stream._backpressure) {
1915 defaultWriterReadyPromiseInitialize(this);
1916 }
1917 else {
1918 defaultWriterReadyPromiseInitializeAsResolved(this);
1919 }
1920 defaultWriterClosedPromiseInitialize(this);
1921 }
1922 else if (state === 'erroring') {
1923 defaultWriterReadyPromiseInitializeAsRejected(this, stream._storedError);
1924 defaultWriterClosedPromiseInitialize(this);
1925 }
1926 else if (state === 'closed') {
1927 defaultWriterReadyPromiseInitializeAsResolved(this);
1928 defaultWriterClosedPromiseInitializeAsResolved(this);
1929 }
1930 else {
1931 const storedError = stream._storedError;
1932 defaultWriterReadyPromiseInitializeAsRejected(this, storedError);
1933 defaultWriterClosedPromiseInitializeAsRejected(this, storedError);
1934 }
1935 }
1936 /**
1937 * Returns a promise that will be fulfilled when the stream becomes closed, or rejected if the stream ever errors or
1938 * the writer’s lock is released before the stream finishes closing.
1939 */
1940 get closed() {
1941 if (!IsWritableStreamDefaultWriter(this)) {
1942 return promiseRejectedWith(defaultWriterBrandCheckException('closed'));
1943 }
1944 return this._closedPromise;
1945 }
1946 /**
1947 * Returns the desired size to fill the stream’s internal queue. It can be negative, if the queue is over-full.
1948 * A producer can use this information to determine the right amount of data to write.
1949 *
1950 * It will be `null` if the stream cannot be successfully written to (due to either being errored, or having an abort
1951 * queued up). It will return zero if the stream is closed. And the getter will throw an exception if invoked when
1952 * the writer’s lock is released.
1953 */
1954 get desiredSize() {
1955 if (!IsWritableStreamDefaultWriter(this)) {
1956 throw defaultWriterBrandCheckException('desiredSize');
1957 }
1958 if (this._ownerWritableStream === undefined) {
1959 throw defaultWriterLockException('desiredSize');
1960 }
1961 return WritableStreamDefaultWriterGetDesiredSize(this);
1962 }
1963 /**
1964 * Returns a promise that will be fulfilled when the desired size to fill the stream’s internal queue transitions
1965 * from non-positive to positive, signaling that it is no longer applying backpressure. Once the desired size dips
1966 * back to zero or below, the getter will return a new promise that stays pending until the next transition.
1967 *
1968 * If the stream becomes errored or aborted, or the writer’s lock is released, the returned promise will become
1969 * rejected.
1970 */
1971 get ready() {
1972 if (!IsWritableStreamDefaultWriter(this)) {
1973 return promiseRejectedWith(defaultWriterBrandCheckException('ready'));
1974 }
1975 return this._readyPromise;
1976 }
1977 /**
1978 * If the reader is active, behaves the same as {@link WritableStream.abort | stream.abort(reason)}.
1979 */
1980 abort(reason = undefined) {
1981 if (!IsWritableStreamDefaultWriter(this)) {
1982 return promiseRejectedWith(defaultWriterBrandCheckException('abort'));
1983 }
1984 if (this._ownerWritableStream === undefined) {
1985 return promiseRejectedWith(defaultWriterLockException('abort'));
1986 }
1987 return WritableStreamDefaultWriterAbort(this, reason);
1988 }
1989 /**
1990 * If the reader is active, behaves the same as {@link WritableStream.close | stream.close()}.
1991 */
1992 close() {
1993 if (!IsWritableStreamDefaultWriter(this)) {
1994 return promiseRejectedWith(defaultWriterBrandCheckException('close'));
1995 }
1996 const stream = this._ownerWritableStream;
1997 if (stream === undefined) {
1998 return promiseRejectedWith(defaultWriterLockException('close'));
1999 }
2000 if (WritableStreamCloseQueuedOrInFlight(stream)) {
2001 return promiseRejectedWith(new TypeError('Cannot close an already-closing stream'));
2002 }
2003 return WritableStreamDefaultWriterClose(this);
2004 }
2005 /**
2006 * Releases the writer’s lock on the corresponding stream. After the lock is released, the writer is no longer active.
2007 * If the associated stream is errored when the lock is released, the writer will appear errored in the same way from
2008 * now on; otherwise, the writer will appear closed.
2009 *
2010 * Note that the lock can still be released even if some ongoing writes have not yet finished (i.e. even if the
2011 * promises returned from previous calls to {@link WritableStreamDefaultWriter.write | write()} have not yet settled).
2012 * It’s not necessary to hold the lock on the writer for the duration of the write; the lock instead simply prevents
2013 * other producers from writing in an interleaved manner.
2014 */
2015 releaseLock() {
2016 if (!IsWritableStreamDefaultWriter(this)) {
2017 throw defaultWriterBrandCheckException('releaseLock');
2018 }
2019 const stream = this._ownerWritableStream;
2020 if (stream === undefined) {
2021 return;
2022 }
2023 WritableStreamDefaultWriterRelease(this);
2024 }
2025 write(chunk = undefined) {
2026 if (!IsWritableStreamDefaultWriter(this)) {
2027 return promiseRejectedWith(defaultWriterBrandCheckException('write'));
2028 }
2029 if (this._ownerWritableStream === undefined) {
2030 return promiseRejectedWith(defaultWriterLockException('write to'));
2031 }
2032 return WritableStreamDefaultWriterWrite(this, chunk);
2033 }
2034}
2035Object.defineProperties(WritableStreamDefaultWriter.prototype, {
2036 abort: { enumerable: true },
2037 close: { enumerable: true },
2038 releaseLock: { enumerable: true },
2039 write: { enumerable: true },
2040 closed: { enumerable: true },
2041 desiredSize: { enumerable: true },
2042 ready: { enumerable: true }
2043});
2044if (typeof SymbolPolyfill.toStringTag === 'symbol') {
2045 Object.defineProperty(WritableStreamDefaultWriter.prototype, SymbolPolyfill.toStringTag, {
2046 value: 'WritableStreamDefaultWriter',
2047 configurable: true
2048 });
2049}
2050// Abstract operations for the WritableStreamDefaultWriter.
2051function IsWritableStreamDefaultWriter(x) {
2052 if (!typeIsObject(x)) {
2053 return false;
2054 }
2055 if (!Object.prototype.hasOwnProperty.call(x, '_ownerWritableStream')) {
2056 return false;
2057 }
2058 return true;
2059}
2060// A client of WritableStreamDefaultWriter may use these functions directly to bypass state check.
2061function WritableStreamDefaultWriterAbort(writer, reason) {
2062 const stream = writer._ownerWritableStream;
2063 return WritableStreamAbort(stream, reason);
2064}
2065function WritableStreamDefaultWriterClose(writer) {
2066 const stream = writer._ownerWritableStream;
2067 return WritableStreamClose(stream);
2068}
2069function WritableStreamDefaultWriterCloseWithErrorPropagation(writer) {
2070 const stream = writer._ownerWritableStream;
2071 const state = stream._state;
2072 if (WritableStreamCloseQueuedOrInFlight(stream) || state === 'closed') {
2073 return promiseResolvedWith(undefined);
2074 }
2075 if (state === 'errored') {
2076 return promiseRejectedWith(stream._storedError);
2077 }
2078 return WritableStreamDefaultWriterClose(writer);
2079}
2080function WritableStreamDefaultWriterEnsureClosedPromiseRejected(writer, error) {
2081 if (writer._closedPromiseState === 'pending') {
2082 defaultWriterClosedPromiseReject(writer, error);
2083 }
2084 else {
2085 defaultWriterClosedPromiseResetToRejected(writer, error);
2086 }
2087}
2088function WritableStreamDefaultWriterEnsureReadyPromiseRejected(writer, error) {
2089 if (writer._readyPromiseState === 'pending') {
2090 defaultWriterReadyPromiseReject(writer, error);
2091 }
2092 else {
2093 defaultWriterReadyPromiseResetToRejected(writer, error);
2094 }
2095}
2096function WritableStreamDefaultWriterGetDesiredSize(writer) {
2097 const stream = writer._ownerWritableStream;
2098 const state = stream._state;
2099 if (state === 'errored' || state === 'erroring') {
2100 return null;
2101 }
2102 if (state === 'closed') {
2103 return 0;
2104 }
2105 return WritableStreamDefaultControllerGetDesiredSize(stream._writableStreamController);
2106}
2107function WritableStreamDefaultWriterRelease(writer) {
2108 const stream = writer._ownerWritableStream;
2109 const releasedError = new TypeError(`Writer was released and can no longer be used to monitor the stream's closedness`);
2110 WritableStreamDefaultWriterEnsureReadyPromiseRejected(writer, releasedError);
2111 // The state transitions to "errored" before the sink abort() method runs, but the writer.closed promise is not
2112 // rejected until afterwards. This means that simply testing state will not work.
2113 WritableStreamDefaultWriterEnsureClosedPromiseRejected(writer, releasedError);
2114 stream._writer = undefined;
2115 writer._ownerWritableStream = undefined;
2116}
2117function WritableStreamDefaultWriterWrite(writer, chunk) {
2118 const stream = writer._ownerWritableStream;
2119 const controller = stream._writableStreamController;
2120 const chunkSize = WritableStreamDefaultControllerGetChunkSize(controller, chunk);
2121 if (stream !== writer._ownerWritableStream) {
2122 return promiseRejectedWith(defaultWriterLockException('write to'));
2123 }
2124 const state = stream._state;
2125 if (state === 'errored') {
2126 return promiseRejectedWith(stream._storedError);
2127 }
2128 if (WritableStreamCloseQueuedOrInFlight(stream) || state === 'closed') {
2129 return promiseRejectedWith(new TypeError('The stream is closing or closed and cannot be written to'));
2130 }
2131 if (state === 'erroring') {
2132 return promiseRejectedWith(stream._storedError);
2133 }
2134 const promise = WritableStreamAddWriteRequest(stream);
2135 WritableStreamDefaultControllerWrite(controller, chunk, chunkSize);
2136 return promise;
2137}
2138const closeSentinel = {};
2139/**
2140 * Allows control of a {@link WritableStream | writable stream}'s state and internal queue.
2141 *
2142 * @public
2143 */
2144class WritableStreamDefaultController {
2145 constructor() {
2146 throw new TypeError('Illegal constructor');
2147 }
2148 /**
2149 * Closes the controlled writable stream, making all future interactions with it fail with the given error `e`.
2150 *
2151 * This method is rarely used, since usually it suffices to return a rejected promise from one of the underlying
2152 * sink's methods. However, it can be useful for suddenly shutting down a stream in response to an event outside the
2153 * normal lifecycle of interactions with the underlying sink.
2154 */
2155 error(e = undefined) {
2156 if (!IsWritableStreamDefaultController(this)) {
2157 throw new TypeError('WritableStreamDefaultController.prototype.error can only be used on a WritableStreamDefaultController');
2158 }
2159 const state = this._controlledWritableStream._state;
2160 if (state !== 'writable') {
2161 // The stream is closed, errored or will be soon. The sink can't do anything useful if it gets an error here, so
2162 // just treat it as a no-op.
2163 return;
2164 }
2165 WritableStreamDefaultControllerError(this, e);
2166 }
2167 /** @internal */
2168 [AbortSteps](reason) {
2169 const result = this._abortAlgorithm(reason);
2170 WritableStreamDefaultControllerClearAlgorithms(this);
2171 return result;
2172 }
2173 /** @internal */
2174 [ErrorSteps]() {
2175 ResetQueue(this);
2176 }
2177}
2178Object.defineProperties(WritableStreamDefaultController.prototype, {
2179 error: { enumerable: true }
2180});
2181if (typeof SymbolPolyfill.toStringTag === 'symbol') {
2182 Object.defineProperty(WritableStreamDefaultController.prototype, SymbolPolyfill.toStringTag, {
2183 value: 'WritableStreamDefaultController',
2184 configurable: true
2185 });
2186}
2187// Abstract operations implementing interface required by the WritableStream.
2188function IsWritableStreamDefaultController(x) {
2189 if (!typeIsObject(x)) {
2190 return false;
2191 }
2192 if (!Object.prototype.hasOwnProperty.call(x, '_controlledWritableStream')) {
2193 return false;
2194 }
2195 return true;
2196}
2197function SetUpWritableStreamDefaultController(stream, controller, startAlgorithm, writeAlgorithm, closeAlgorithm, abortAlgorithm, highWaterMark, sizeAlgorithm) {
2198 controller._controlledWritableStream = stream;
2199 stream._writableStreamController = controller;
2200 // Need to set the slots so that the assert doesn't fire. In the spec the slots already exist implicitly.
2201 controller._queue = undefined;
2202 controller._queueTotalSize = undefined;
2203 ResetQueue(controller);
2204 controller._started = false;
2205 controller._strategySizeAlgorithm = sizeAlgorithm;
2206 controller._strategyHWM = highWaterMark;
2207 controller._writeAlgorithm = writeAlgorithm;
2208 controller._closeAlgorithm = closeAlgorithm;
2209 controller._abortAlgorithm = abortAlgorithm;
2210 const backpressure = WritableStreamDefaultControllerGetBackpressure(controller);
2211 WritableStreamUpdateBackpressure(stream, backpressure);
2212 const startResult = startAlgorithm();
2213 const startPromise = promiseResolvedWith(startResult);
2214 uponPromise(startPromise, () => {
2215 controller._started = true;
2216 WritableStreamDefaultControllerAdvanceQueueIfNeeded(controller);
2217 }, r => {
2218 controller._started = true;
2219 WritableStreamDealWithRejection(stream, r);
2220 });
2221}
2222function SetUpWritableStreamDefaultControllerFromUnderlyingSink(stream, underlyingSink, highWaterMark, sizeAlgorithm) {
2223 const controller = Object.create(WritableStreamDefaultController.prototype);
2224 let startAlgorithm = () => undefined;
2225 let writeAlgorithm = () => promiseResolvedWith(undefined);
2226 let closeAlgorithm = () => promiseResolvedWith(undefined);
2227 let abortAlgorithm = () => promiseResolvedWith(undefined);
2228 if (underlyingSink.start !== undefined) {
2229 startAlgorithm = () => underlyingSink.start(controller);
2230 }
2231 if (underlyingSink.write !== undefined) {
2232 writeAlgorithm = chunk => underlyingSink.write(chunk, controller);
2233 }
2234 if (underlyingSink.close !== undefined) {
2235 closeAlgorithm = () => underlyingSink.close();
2236 }
2237 if (underlyingSink.abort !== undefined) {
2238 abortAlgorithm = reason => underlyingSink.abort(reason);
2239 }
2240 SetUpWritableStreamDefaultController(stream, controller, startAlgorithm, writeAlgorithm, closeAlgorithm, abortAlgorithm, highWaterMark, sizeAlgorithm);
2241}
2242// ClearAlgorithms may be called twice. Erroring the same stream in multiple ways will often result in redundant calls.
2243function WritableStreamDefaultControllerClearAlgorithms(controller) {
2244 controller._writeAlgorithm = undefined;
2245 controller._closeAlgorithm = undefined;
2246 controller._abortAlgorithm = undefined;
2247 controller._strategySizeAlgorithm = undefined;
2248}
2249function WritableStreamDefaultControllerClose(controller) {
2250 EnqueueValueWithSize(controller, closeSentinel, 0);
2251 WritableStreamDefaultControllerAdvanceQueueIfNeeded(controller);
2252}
2253function WritableStreamDefaultControllerGetChunkSize(controller, chunk) {
2254 try {
2255 return controller._strategySizeAlgorithm(chunk);
2256 }
2257 catch (chunkSizeE) {
2258 WritableStreamDefaultControllerErrorIfNeeded(controller, chunkSizeE);
2259 return 1;
2260 }
2261}
2262function WritableStreamDefaultControllerGetDesiredSize(controller) {
2263 return controller._strategyHWM - controller._queueTotalSize;
2264}
2265function WritableStreamDefaultControllerWrite(controller, chunk, chunkSize) {
2266 try {
2267 EnqueueValueWithSize(controller, chunk, chunkSize);
2268 }
2269 catch (enqueueE) {
2270 WritableStreamDefaultControllerErrorIfNeeded(controller, enqueueE);
2271 return;
2272 }
2273 const stream = controller._controlledWritableStream;
2274 if (!WritableStreamCloseQueuedOrInFlight(stream) && stream._state === 'writable') {
2275 const backpressure = WritableStreamDefaultControllerGetBackpressure(controller);
2276 WritableStreamUpdateBackpressure(stream, backpressure);
2277 }
2278 WritableStreamDefaultControllerAdvanceQueueIfNeeded(controller);
2279}
2280// Abstract operations for the WritableStreamDefaultController.
2281function WritableStreamDefaultControllerAdvanceQueueIfNeeded(controller) {
2282 const stream = controller._controlledWritableStream;
2283 if (!controller._started) {
2284 return;
2285 }
2286 if (stream._inFlightWriteRequest !== undefined) {
2287 return;
2288 }
2289 const state = stream._state;
2290 if (state === 'erroring') {
2291 WritableStreamFinishErroring(stream);
2292 return;
2293 }
2294 if (controller._queue.length === 0) {
2295 return;
2296 }
2297 const value = PeekQueueValue(controller);
2298 if (value === closeSentinel) {
2299 WritableStreamDefaultControllerProcessClose(controller);
2300 }
2301 else {
2302 WritableStreamDefaultControllerProcessWrite(controller, value);
2303 }
2304}
2305function WritableStreamDefaultControllerErrorIfNeeded(controller, error) {
2306 if (controller._controlledWritableStream._state === 'writable') {
2307 WritableStreamDefaultControllerError(controller, error);
2308 }
2309}
2310function WritableStreamDefaultControllerProcessClose(controller) {
2311 const stream = controller._controlledWritableStream;
2312 WritableStreamMarkCloseRequestInFlight(stream);
2313 DequeueValue(controller);
2314 const sinkClosePromise = controller._closeAlgorithm();
2315 WritableStreamDefaultControllerClearAlgorithms(controller);
2316 uponPromise(sinkClosePromise, () => {
2317 WritableStreamFinishInFlightClose(stream);
2318 }, reason => {
2319 WritableStreamFinishInFlightCloseWithError(stream, reason);
2320 });
2321}
2322function WritableStreamDefaultControllerProcessWrite(controller, chunk) {
2323 const stream = controller._controlledWritableStream;
2324 WritableStreamMarkFirstWriteRequestInFlight(stream);
2325 const sinkWritePromise = controller._writeAlgorithm(chunk);
2326 uponPromise(sinkWritePromise, () => {
2327 WritableStreamFinishInFlightWrite(stream);
2328 const state = stream._state;
2329 DequeueValue(controller);
2330 if (!WritableStreamCloseQueuedOrInFlight(stream) && state === 'writable') {
2331 const backpressure = WritableStreamDefaultControllerGetBackpressure(controller);
2332 WritableStreamUpdateBackpressure(stream, backpressure);
2333 }
2334 WritableStreamDefaultControllerAdvanceQueueIfNeeded(controller);
2335 }, reason => {
2336 if (stream._state === 'writable') {
2337 WritableStreamDefaultControllerClearAlgorithms(controller);
2338 }
2339 WritableStreamFinishInFlightWriteWithError(stream, reason);
2340 });
2341}
2342function WritableStreamDefaultControllerGetBackpressure(controller) {
2343 const desiredSize = WritableStreamDefaultControllerGetDesiredSize(controller);
2344 return desiredSize <= 0;
2345}
2346// A client of WritableStreamDefaultController may use these functions directly to bypass state check.
2347function WritableStreamDefaultControllerError(controller, error) {
2348 const stream = controller._controlledWritableStream;
2349 WritableStreamDefaultControllerClearAlgorithms(controller);
2350 WritableStreamStartErroring(stream, error);
2351}
2352// Helper functions for the WritableStream.
2353function streamBrandCheckException(name) {
2354 return new TypeError(`WritableStream.prototype.${name} can only be used on a WritableStream`);
2355}
2356// Helper functions for the WritableStreamDefaultWriter.
2357function defaultWriterBrandCheckException(name) {
2358 return new TypeError(`WritableStreamDefaultWriter.prototype.${name} can only be used on a WritableStreamDefaultWriter`);
2359}
2360function defaultWriterLockException(name) {
2361 return new TypeError('Cannot ' + name + ' a stream using a released writer');
2362}
2363function defaultWriterClosedPromiseInitialize(writer) {
2364 writer._closedPromise = newPromise((resolve, reject) => {
2365 writer._closedPromise_resolve = resolve;
2366 writer._closedPromise_reject = reject;
2367 writer._closedPromiseState = 'pending';
2368 });
2369}
2370function defaultWriterClosedPromiseInitializeAsRejected(writer, reason) {
2371 defaultWriterClosedPromiseInitialize(writer);
2372 defaultWriterClosedPromiseReject(writer, reason);
2373}
2374function defaultWriterClosedPromiseInitializeAsResolved(writer) {
2375 defaultWriterClosedPromiseInitialize(writer);
2376 defaultWriterClosedPromiseResolve(writer);
2377}
2378function defaultWriterClosedPromiseReject(writer, reason) {
2379 if (writer._closedPromise_reject === undefined) {
2380 return;
2381 }
2382 setPromiseIsHandledToTrue(writer._closedPromise);
2383 writer._closedPromise_reject(reason);
2384 writer._closedPromise_resolve = undefined;
2385 writer._closedPromise_reject = undefined;
2386 writer._closedPromiseState = 'rejected';
2387}
2388function defaultWriterClosedPromiseResetToRejected(writer, reason) {
2389 defaultWriterClosedPromiseInitializeAsRejected(writer, reason);
2390}
2391function defaultWriterClosedPromiseResolve(writer) {
2392 if (writer._closedPromise_resolve === undefined) {
2393 return;
2394 }
2395 writer._closedPromise_resolve(undefined);
2396 writer._closedPromise_resolve = undefined;
2397 writer._closedPromise_reject = undefined;
2398 writer._closedPromiseState = 'resolved';
2399}
2400function defaultWriterReadyPromiseInitialize(writer) {
2401 writer._readyPromise = newPromise((resolve, reject) => {
2402 writer._readyPromise_resolve = resolve;
2403 writer._readyPromise_reject = reject;
2404 });
2405 writer._readyPromiseState = 'pending';
2406}
2407function defaultWriterReadyPromiseInitializeAsRejected(writer, reason) {
2408 defaultWriterReadyPromiseInitialize(writer);
2409 defaultWriterReadyPromiseReject(writer, reason);
2410}
2411function defaultWriterReadyPromiseInitializeAsResolved(writer) {
2412 defaultWriterReadyPromiseInitialize(writer);
2413 defaultWriterReadyPromiseResolve(writer);
2414}
2415function defaultWriterReadyPromiseReject(writer, reason) {
2416 if (writer._readyPromise_reject === undefined) {
2417 return;
2418 }
2419 setPromiseIsHandledToTrue(writer._readyPromise);
2420 writer._readyPromise_reject(reason);
2421 writer._readyPromise_resolve = undefined;
2422 writer._readyPromise_reject = undefined;
2423 writer._readyPromiseState = 'rejected';
2424}
2425function defaultWriterReadyPromiseReset(writer) {
2426 defaultWriterReadyPromiseInitialize(writer);
2427}
2428function defaultWriterReadyPromiseResetToRejected(writer, reason) {
2429 defaultWriterReadyPromiseInitializeAsRejected(writer, reason);
2430}
2431function defaultWriterReadyPromiseResolve(writer) {
2432 if (writer._readyPromise_resolve === undefined) {
2433 return;
2434 }
2435 writer._readyPromise_resolve(undefined);
2436 writer._readyPromise_resolve = undefined;
2437 writer._readyPromise_reject = undefined;
2438 writer._readyPromiseState = 'fulfilled';
2439}
2440
2441function isAbortSignal(value) {
2442 if (typeof value !== 'object' || value === null) {
2443 return false;
2444 }
2445 try {
2446 return typeof value.aborted === 'boolean';
2447 }
2448 catch (_a) {
2449 // AbortSignal.prototype.aborted throws if its brand check fails
2450 return false;
2451 }
2452}
2453
2454/// <reference lib="dom" />
2455const NativeDOMException = typeof DOMException !== 'undefined' ? DOMException : undefined;
2456
2457/// <reference types="node" />
2458function isDOMExceptionConstructor(ctor) {
2459 if (!(typeof ctor === 'function' || typeof ctor === 'object')) {
2460 return false;
2461 }
2462 try {
2463 new ctor();
2464 return true;
2465 }
2466 catch (_a) {
2467 return false;
2468 }
2469}
2470function createDOMExceptionPolyfill() {
2471 const ctor = function DOMException(message, name) {
2472 this.message = message || '';
2473 this.name = name || 'Error';
2474 if (Error.captureStackTrace) {
2475 Error.captureStackTrace(this, this.constructor);
2476 }
2477 };
2478 ctor.prototype = Object.create(Error.prototype);
2479 Object.defineProperty(ctor.prototype, 'constructor', { value: ctor, writable: true, configurable: true });
2480 return ctor;
2481}
2482const DOMException$1 = isDOMExceptionConstructor(NativeDOMException) ? NativeDOMException : createDOMExceptionPolyfill();
2483
2484function ReadableStreamPipeTo(source, dest, preventClose, preventAbort, preventCancel, signal) {
2485 const reader = AcquireReadableStreamDefaultReader(source);
2486 const writer = AcquireWritableStreamDefaultWriter(dest);
2487 source._disturbed = true;
2488 let shuttingDown = false;
2489 // This is used to keep track of the spec's requirement that we wait for ongoing writes during shutdown.
2490 let currentWrite = promiseResolvedWith(undefined);
2491 return newPromise((resolve, reject) => {
2492 let abortAlgorithm;
2493 if (signal !== undefined) {
2494 abortAlgorithm = () => {
2495 const error = new DOMException$1('Aborted', 'AbortError');
2496 const actions = [];
2497 if (!preventAbort) {
2498 actions.push(() => {
2499 if (dest._state === 'writable') {
2500 return WritableStreamAbort(dest, error);
2501 }
2502 return promiseResolvedWith(undefined);
2503 });
2504 }
2505 if (!preventCancel) {
2506 actions.push(() => {
2507 if (source._state === 'readable') {
2508 return ReadableStreamCancel(source, error);
2509 }
2510 return promiseResolvedWith(undefined);
2511 });
2512 }
2513 shutdownWithAction(() => Promise.all(actions.map(action => action())), true, error);
2514 };
2515 if (signal.aborted) {
2516 abortAlgorithm();
2517 return;
2518 }
2519 signal.addEventListener('abort', abortAlgorithm);
2520 }
2521 // Using reader and writer, read all chunks from this and write them to dest
2522 // - Backpressure must be enforced
2523 // - Shutdown must stop all activity
2524 function pipeLoop() {
2525 return newPromise((resolveLoop, rejectLoop) => {
2526 function next(done) {
2527 if (done) {
2528 resolveLoop();
2529 }
2530 else {
2531 // Use `PerformPromiseThen` instead of `uponPromise` to avoid
2532 // adding unnecessary `.catch(rethrowAssertionErrorRejection)` handlers
2533 PerformPromiseThen(pipeStep(), next, rejectLoop);
2534 }
2535 }
2536 next(false);
2537 });
2538 }
2539 function pipeStep() {
2540 if (shuttingDown) {
2541 return promiseResolvedWith(true);
2542 }
2543 return PerformPromiseThen(writer._readyPromise, () => {
2544 return newPromise((resolveRead, rejectRead) => {
2545 ReadableStreamDefaultReaderRead(reader, {
2546 _chunkSteps: chunk => {
2547 currentWrite = PerformPromiseThen(WritableStreamDefaultWriterWrite(writer, chunk), undefined, noop);
2548 resolveRead(false);
2549 },
2550 _closeSteps: () => resolveRead(true),
2551 _errorSteps: rejectRead
2552 });
2553 });
2554 });
2555 }
2556 // Errors must be propagated forward
2557 isOrBecomesErrored(source, reader._closedPromise, storedError => {
2558 if (!preventAbort) {
2559 shutdownWithAction(() => WritableStreamAbort(dest, storedError), true, storedError);
2560 }
2561 else {
2562 shutdown(true, storedError);
2563 }
2564 });
2565 // Errors must be propagated backward
2566 isOrBecomesErrored(dest, writer._closedPromise, storedError => {
2567 if (!preventCancel) {
2568 shutdownWithAction(() => ReadableStreamCancel(source, storedError), true, storedError);
2569 }
2570 else {
2571 shutdown(true, storedError);
2572 }
2573 });
2574 // Closing must be propagated forward
2575 isOrBecomesClosed(source, reader._closedPromise, () => {
2576 if (!preventClose) {
2577 shutdownWithAction(() => WritableStreamDefaultWriterCloseWithErrorPropagation(writer));
2578 }
2579 else {
2580 shutdown();
2581 }
2582 });
2583 // Closing must be propagated backward
2584 if (WritableStreamCloseQueuedOrInFlight(dest) || dest._state === 'closed') {
2585 const destClosed = new TypeError('the destination writable stream closed before all data could be piped to it');
2586 if (!preventCancel) {
2587 shutdownWithAction(() => ReadableStreamCancel(source, destClosed), true, destClosed);
2588 }
2589 else {
2590 shutdown(true, destClosed);
2591 }
2592 }
2593 setPromiseIsHandledToTrue(pipeLoop());
2594 function waitForWritesToFinish() {
2595 // Another write may have started while we were waiting on this currentWrite, so we have to be sure to wait
2596 // for that too.
2597 const oldCurrentWrite = currentWrite;
2598 return PerformPromiseThen(currentWrite, () => oldCurrentWrite !== currentWrite ? waitForWritesToFinish() : undefined);
2599 }
2600 function isOrBecomesErrored(stream, promise, action) {
2601 if (stream._state === 'errored') {
2602 action(stream._storedError);
2603 }
2604 else {
2605 uponRejection(promise, action);
2606 }
2607 }
2608 function isOrBecomesClosed(stream, promise, action) {
2609 if (stream._state === 'closed') {
2610 action();
2611 }
2612 else {
2613 uponFulfillment(promise, action);
2614 }
2615 }
2616 function shutdownWithAction(action, originalIsError, originalError) {
2617 if (shuttingDown) {
2618 return;
2619 }
2620 shuttingDown = true;
2621 if (dest._state === 'writable' && !WritableStreamCloseQueuedOrInFlight(dest)) {
2622 uponFulfillment(waitForWritesToFinish(), doTheRest);
2623 }
2624 else {
2625 doTheRest();
2626 }
2627 function doTheRest() {
2628 uponPromise(action(), () => finalize(originalIsError, originalError), newError => finalize(true, newError));
2629 }
2630 }
2631 function shutdown(isError, error) {
2632 if (shuttingDown) {
2633 return;
2634 }
2635 shuttingDown = true;
2636 if (dest._state === 'writable' && !WritableStreamCloseQueuedOrInFlight(dest)) {
2637 uponFulfillment(waitForWritesToFinish(), () => finalize(isError, error));
2638 }
2639 else {
2640 finalize(isError, error);
2641 }
2642 }
2643 function finalize(isError, error) {
2644 WritableStreamDefaultWriterRelease(writer);
2645 ReadableStreamReaderGenericRelease(reader);
2646 if (signal !== undefined) {
2647 signal.removeEventListener('abort', abortAlgorithm);
2648 }
2649 if (isError) {
2650 reject(error);
2651 }
2652 else {
2653 resolve(undefined);
2654 }
2655 }
2656 });
2657}
2658
2659/**
2660 * Allows control of a {@link ReadableStream | readable stream}'s state and internal queue.
2661 *
2662 * @public
2663 */
2664class ReadableStreamDefaultController {
2665 constructor() {
2666 throw new TypeError('Illegal constructor');
2667 }
2668 /**
2669 * Returns the desired size to fill the controlled stream's internal queue. It can be negative, if the queue is
2670 * over-full. An underlying source ought to use this information to determine when and how to apply backpressure.
2671 */
2672 get desiredSize() {
2673 if (!IsReadableStreamDefaultController(this)) {
2674 throw defaultControllerBrandCheckException('desiredSize');
2675 }
2676 return ReadableStreamDefaultControllerGetDesiredSize(this);
2677 }
2678 /**
2679 * Closes the controlled readable stream. Consumers will still be able to read any previously-enqueued chunks from
2680 * the stream, but once those are read, the stream will become closed.
2681 */
2682 close() {
2683 if (!IsReadableStreamDefaultController(this)) {
2684 throw defaultControllerBrandCheckException('close');
2685 }
2686 if (!ReadableStreamDefaultControllerCanCloseOrEnqueue(this)) {
2687 throw new TypeError('The stream is not in a state that permits close');
2688 }
2689 ReadableStreamDefaultControllerClose(this);
2690 }
2691 enqueue(chunk = undefined) {
2692 if (!IsReadableStreamDefaultController(this)) {
2693 throw defaultControllerBrandCheckException('enqueue');
2694 }
2695 if (!ReadableStreamDefaultControllerCanCloseOrEnqueue(this)) {
2696 throw new TypeError('The stream is not in a state that permits enqueue');
2697 }
2698 return ReadableStreamDefaultControllerEnqueue(this, chunk);
2699 }
2700 /**
2701 * Errors the controlled readable stream, making all future interactions with it fail with the given error `e`.
2702 */
2703 error(e = undefined) {
2704 if (!IsReadableStreamDefaultController(this)) {
2705 throw defaultControllerBrandCheckException('error');
2706 }
2707 ReadableStreamDefaultControllerError(this, e);
2708 }
2709 /** @internal */
2710 [CancelSteps](reason) {
2711 ResetQueue(this);
2712 const result = this._cancelAlgorithm(reason);
2713 ReadableStreamDefaultControllerClearAlgorithms(this);
2714 return result;
2715 }
2716 /** @internal */
2717 [PullSteps](readRequest) {
2718 const stream = this._controlledReadableStream;
2719 if (this._queue.length > 0) {
2720 const chunk = DequeueValue(this);
2721 if (this._closeRequested && this._queue.length === 0) {
2722 ReadableStreamDefaultControllerClearAlgorithms(this);
2723 ReadableStreamClose(stream);
2724 }
2725 else {
2726 ReadableStreamDefaultControllerCallPullIfNeeded(this);
2727 }
2728 readRequest._chunkSteps(chunk);
2729 }
2730 else {
2731 ReadableStreamAddReadRequest(stream, readRequest);
2732 ReadableStreamDefaultControllerCallPullIfNeeded(this);
2733 }
2734 }
2735}
2736Object.defineProperties(ReadableStreamDefaultController.prototype, {
2737 close: { enumerable: true },
2738 enqueue: { enumerable: true },
2739 error: { enumerable: true },
2740 desiredSize: { enumerable: true }
2741});
2742if (typeof SymbolPolyfill.toStringTag === 'symbol') {
2743 Object.defineProperty(ReadableStreamDefaultController.prototype, SymbolPolyfill.toStringTag, {
2744 value: 'ReadableStreamDefaultController',
2745 configurable: true
2746 });
2747}
2748// Abstract operations for the ReadableStreamDefaultController.
2749function IsReadableStreamDefaultController(x) {
2750 if (!typeIsObject(x)) {
2751 return false;
2752 }
2753 if (!Object.prototype.hasOwnProperty.call(x, '_controlledReadableStream')) {
2754 return false;
2755 }
2756 return true;
2757}
2758function ReadableStreamDefaultControllerCallPullIfNeeded(controller) {
2759 const shouldPull = ReadableStreamDefaultControllerShouldCallPull(controller);
2760 if (!shouldPull) {
2761 return;
2762 }
2763 if (controller._pulling) {
2764 controller._pullAgain = true;
2765 return;
2766 }
2767 controller._pulling = true;
2768 const pullPromise = controller._pullAlgorithm();
2769 uponPromise(pullPromise, () => {
2770 controller._pulling = false;
2771 if (controller._pullAgain) {
2772 controller._pullAgain = false;
2773 ReadableStreamDefaultControllerCallPullIfNeeded(controller);
2774 }
2775 }, e => {
2776 ReadableStreamDefaultControllerError(controller, e);
2777 });
2778}
2779function ReadableStreamDefaultControllerShouldCallPull(controller) {
2780 const stream = controller._controlledReadableStream;
2781 if (!ReadableStreamDefaultControllerCanCloseOrEnqueue(controller)) {
2782 return false;
2783 }
2784 if (!controller._started) {
2785 return false;
2786 }
2787 if (IsReadableStreamLocked(stream) && ReadableStreamGetNumReadRequests(stream) > 0) {
2788 return true;
2789 }
2790 const desiredSize = ReadableStreamDefaultControllerGetDesiredSize(controller);
2791 if (desiredSize > 0) {
2792 return true;
2793 }
2794 return false;
2795}
2796function ReadableStreamDefaultControllerClearAlgorithms(controller) {
2797 controller._pullAlgorithm = undefined;
2798 controller._cancelAlgorithm = undefined;
2799 controller._strategySizeAlgorithm = undefined;
2800}
2801// A client of ReadableStreamDefaultController may use these functions directly to bypass state check.
2802function ReadableStreamDefaultControllerClose(controller) {
2803 if (!ReadableStreamDefaultControllerCanCloseOrEnqueue(controller)) {
2804 return;
2805 }
2806 const stream = controller._controlledReadableStream;
2807 controller._closeRequested = true;
2808 if (controller._queue.length === 0) {
2809 ReadableStreamDefaultControllerClearAlgorithms(controller);
2810 ReadableStreamClose(stream);
2811 }
2812}
2813function ReadableStreamDefaultControllerEnqueue(controller, chunk) {
2814 if (!ReadableStreamDefaultControllerCanCloseOrEnqueue(controller)) {
2815 return;
2816 }
2817 const stream = controller._controlledReadableStream;
2818 if (IsReadableStreamLocked(stream) && ReadableStreamGetNumReadRequests(stream) > 0) {
2819 ReadableStreamFulfillReadRequest(stream, chunk, false);
2820 }
2821 else {
2822 let chunkSize;
2823 try {
2824 chunkSize = controller._strategySizeAlgorithm(chunk);
2825 }
2826 catch (chunkSizeE) {
2827 ReadableStreamDefaultControllerError(controller, chunkSizeE);
2828 throw chunkSizeE;
2829 }
2830 try {
2831 EnqueueValueWithSize(controller, chunk, chunkSize);
2832 }
2833 catch (enqueueE) {
2834 ReadableStreamDefaultControllerError(controller, enqueueE);
2835 throw enqueueE;
2836 }
2837 }
2838 ReadableStreamDefaultControllerCallPullIfNeeded(controller);
2839}
2840function ReadableStreamDefaultControllerError(controller, e) {
2841 const stream = controller._controlledReadableStream;
2842 if (stream._state !== 'readable') {
2843 return;
2844 }
2845 ResetQueue(controller);
2846 ReadableStreamDefaultControllerClearAlgorithms(controller);
2847 ReadableStreamError(stream, e);
2848}
2849function ReadableStreamDefaultControllerGetDesiredSize(controller) {
2850 const state = controller._controlledReadableStream._state;
2851 if (state === 'errored') {
2852 return null;
2853 }
2854 if (state === 'closed') {
2855 return 0;
2856 }
2857 return controller._strategyHWM - controller._queueTotalSize;
2858}
2859// This is used in the implementation of TransformStream.
2860function ReadableStreamDefaultControllerHasBackpressure(controller) {
2861 if (ReadableStreamDefaultControllerShouldCallPull(controller)) {
2862 return false;
2863 }
2864 return true;
2865}
2866function ReadableStreamDefaultControllerCanCloseOrEnqueue(controller) {
2867 const state = controller._controlledReadableStream._state;
2868 if (!controller._closeRequested && state === 'readable') {
2869 return true;
2870 }
2871 return false;
2872}
2873function SetUpReadableStreamDefaultController(stream, controller, startAlgorithm, pullAlgorithm, cancelAlgorithm, highWaterMark, sizeAlgorithm) {
2874 controller._controlledReadableStream = stream;
2875 controller._queue = undefined;
2876 controller._queueTotalSize = undefined;
2877 ResetQueue(controller);
2878 controller._started = false;
2879 controller._closeRequested = false;
2880 controller._pullAgain = false;
2881 controller._pulling = false;
2882 controller._strategySizeAlgorithm = sizeAlgorithm;
2883 controller._strategyHWM = highWaterMark;
2884 controller._pullAlgorithm = pullAlgorithm;
2885 controller._cancelAlgorithm = cancelAlgorithm;
2886 stream._readableStreamController = controller;
2887 const startResult = startAlgorithm();
2888 uponPromise(promiseResolvedWith(startResult), () => {
2889 controller._started = true;
2890 ReadableStreamDefaultControllerCallPullIfNeeded(controller);
2891 }, r => {
2892 ReadableStreamDefaultControllerError(controller, r);
2893 });
2894}
2895function SetUpReadableStreamDefaultControllerFromUnderlyingSource(stream, underlyingSource, highWaterMark, sizeAlgorithm) {
2896 const controller = Object.create(ReadableStreamDefaultController.prototype);
2897 let startAlgorithm = () => undefined;
2898 let pullAlgorithm = () => promiseResolvedWith(undefined);
2899 let cancelAlgorithm = () => promiseResolvedWith(undefined);
2900 if (underlyingSource.start !== undefined) {
2901 startAlgorithm = () => underlyingSource.start(controller);
2902 }
2903 if (underlyingSource.pull !== undefined) {
2904 pullAlgorithm = () => underlyingSource.pull(controller);
2905 }
2906 if (underlyingSource.cancel !== undefined) {
2907 cancelAlgorithm = reason => underlyingSource.cancel(reason);
2908 }
2909 SetUpReadableStreamDefaultController(stream, controller, startAlgorithm, pullAlgorithm, cancelAlgorithm, highWaterMark, sizeAlgorithm);
2910}
2911// Helper functions for the ReadableStreamDefaultController.
2912function defaultControllerBrandCheckException(name) {
2913 return new TypeError(`ReadableStreamDefaultController.prototype.${name} can only be used on a ReadableStreamDefaultController`);
2914}
2915
2916function ReadableStreamTee(stream, cloneForBranch2) {
2917 const reader = AcquireReadableStreamDefaultReader(stream);
2918 let reading = false;
2919 let canceled1 = false;
2920 let canceled2 = false;
2921 let reason1;
2922 let reason2;
2923 let branch1;
2924 let branch2;
2925 let resolveCancelPromise;
2926 const cancelPromise = newPromise(resolve => {
2927 resolveCancelPromise = resolve;
2928 });
2929 function pullAlgorithm() {
2930 if (reading) {
2931 return promiseResolvedWith(undefined);
2932 }
2933 reading = true;
2934 const readRequest = {
2935 _chunkSteps: value => {
2936 // This needs to be delayed a microtask because it takes at least a microtask to detect errors (using
2937 // reader._closedPromise below), and we want errors in stream to error both branches immediately. We cannot let
2938 // successful synchronously-available reads get ahead of asynchronously-available errors.
2939 queueMicrotask(() => {
2940 reading = false;
2941 const value1 = value;
2942 const value2 = value;
2943 // There is no way to access the cloning code right now in the reference implementation.
2944 // If we add one then we'll need an implementation for serializable objects.
2945 // if (!canceled2 && cloneForBranch2) {
2946 // value2 = StructuredDeserialize(StructuredSerialize(value2));
2947 // }
2948 if (!canceled1) {
2949 ReadableStreamDefaultControllerEnqueue(branch1._readableStreamController, value1);
2950 }
2951 if (!canceled2) {
2952 ReadableStreamDefaultControllerEnqueue(branch2._readableStreamController, value2);
2953 }
2954 resolveCancelPromise(undefined);
2955 });
2956 },
2957 _closeSteps: () => {
2958 reading = false;
2959 if (!canceled1) {
2960 ReadableStreamDefaultControllerClose(branch1._readableStreamController);
2961 }
2962 if (!canceled2) {
2963 ReadableStreamDefaultControllerClose(branch2._readableStreamController);
2964 }
2965 },
2966 _errorSteps: () => {
2967 reading = false;
2968 }
2969 };
2970 ReadableStreamDefaultReaderRead(reader, readRequest);
2971 return promiseResolvedWith(undefined);
2972 }
2973 function cancel1Algorithm(reason) {
2974 canceled1 = true;
2975 reason1 = reason;
2976 if (canceled2) {
2977 const compositeReason = CreateArrayFromList([reason1, reason2]);
2978 const cancelResult = ReadableStreamCancel(stream, compositeReason);
2979 resolveCancelPromise(cancelResult);
2980 }
2981 return cancelPromise;
2982 }
2983 function cancel2Algorithm(reason) {
2984 canceled2 = true;
2985 reason2 = reason;
2986 if (canceled1) {
2987 const compositeReason = CreateArrayFromList([reason1, reason2]);
2988 const cancelResult = ReadableStreamCancel(stream, compositeReason);
2989 resolveCancelPromise(cancelResult);
2990 }
2991 return cancelPromise;
2992 }
2993 function startAlgorithm() {
2994 // do nothing
2995 }
2996 branch1 = CreateReadableStream(startAlgorithm, pullAlgorithm, cancel1Algorithm);
2997 branch2 = CreateReadableStream(startAlgorithm, pullAlgorithm, cancel2Algorithm);
2998 uponRejection(reader._closedPromise, (r) => {
2999 ReadableStreamDefaultControllerError(branch1._readableStreamController, r);
3000 ReadableStreamDefaultControllerError(branch2._readableStreamController, r);
3001 resolveCancelPromise(undefined);
3002 });
3003 return [branch1, branch2];
3004}
3005
3006function convertUnderlyingDefaultOrByteSource(source, context) {
3007 assertDictionary(source, context);
3008 const original = source;
3009 const autoAllocateChunkSize = original === null || original === void 0 ? void 0 : original.autoAllocateChunkSize;
3010 const cancel = original === null || original === void 0 ? void 0 : original.cancel;
3011 const pull = original === null || original === void 0 ? void 0 : original.pull;
3012 const start = original === null || original === void 0 ? void 0 : original.start;
3013 const type = original === null || original === void 0 ? void 0 : original.type;
3014 return {
3015 autoAllocateChunkSize: autoAllocateChunkSize === undefined ?
3016 undefined :
3017 convertUnsignedLongLongWithEnforceRange(autoAllocateChunkSize, `${context} has member 'autoAllocateChunkSize' that`),
3018 cancel: cancel === undefined ?
3019 undefined :
3020 convertUnderlyingSourceCancelCallback(cancel, original, `${context} has member 'cancel' that`),
3021 pull: pull === undefined ?
3022 undefined :
3023 convertUnderlyingSourcePullCallback(pull, original, `${context} has member 'pull' that`),
3024 start: start === undefined ?
3025 undefined :
3026 convertUnderlyingSourceStartCallback(start, original, `${context} has member 'start' that`),
3027 type: type === undefined ? undefined : convertReadableStreamType(type, `${context} has member 'type' that`)
3028 };
3029}
3030function convertUnderlyingSourceCancelCallback(fn, original, context) {
3031 assertFunction(fn, context);
3032 return (reason) => promiseCall(fn, original, [reason]);
3033}
3034function convertUnderlyingSourcePullCallback(fn, original, context) {
3035 assertFunction(fn, context);
3036 return (controller) => promiseCall(fn, original, [controller]);
3037}
3038function convertUnderlyingSourceStartCallback(fn, original, context) {
3039 assertFunction(fn, context);
3040 return (controller) => reflectCall(fn, original, [controller]);
3041}
3042function convertReadableStreamType(type, context) {
3043 type = `${type}`;
3044 if (type !== 'bytes') {
3045 throw new TypeError(`${context} '${type}' is not a valid enumeration value for ReadableStreamType`);
3046 }
3047 return type;
3048}
3049
3050function convertReaderOptions(options, context) {
3051 assertDictionary(options, context);
3052 const mode = options === null || options === void 0 ? void 0 : options.mode;
3053 return {
3054 mode: mode === undefined ? undefined : convertReadableStreamReaderMode(mode, `${context} has member 'mode' that`)
3055 };
3056}
3057function convertReadableStreamReaderMode(mode, context) {
3058 mode = `${mode}`;
3059 if (mode !== 'byob') {
3060 throw new TypeError(`${context} '${mode}' is not a valid enumeration value for ReadableStreamReaderMode`);
3061 }
3062 return mode;
3063}
3064
3065function convertIteratorOptions(options, context) {
3066 assertDictionary(options, context);
3067 const preventCancel = options === null || options === void 0 ? void 0 : options.preventCancel;
3068 return { preventCancel: Boolean(preventCancel) };
3069}
3070
3071function convertPipeOptions(options, context) {
3072 assertDictionary(options, context);
3073 const preventAbort = options === null || options === void 0 ? void 0 : options.preventAbort;
3074 const preventCancel = options === null || options === void 0 ? void 0 : options.preventCancel;
3075 const preventClose = options === null || options === void 0 ? void 0 : options.preventClose;
3076 const signal = options === null || options === void 0 ? void 0 : options.signal;
3077 if (signal !== undefined) {
3078 assertAbortSignal(signal, `${context} has member 'signal' that`);
3079 }
3080 return {
3081 preventAbort: Boolean(preventAbort),
3082 preventCancel: Boolean(preventCancel),
3083 preventClose: Boolean(preventClose),
3084 signal
3085 };
3086}
3087function assertAbortSignal(signal, context) {
3088 if (!isAbortSignal(signal)) {
3089 throw new TypeError(`${context} is not an AbortSignal.`);
3090 }
3091}
3092
3093function convertReadableWritablePair(pair, context) {
3094 assertDictionary(pair, context);
3095 const readable = pair === null || pair === void 0 ? void 0 : pair.readable;
3096 assertRequiredField(readable, 'readable', 'ReadableWritablePair');
3097 assertReadableStream(readable, `${context} has member 'readable' that`);
3098 const writable = pair === null || pair === void 0 ? void 0 : pair.writable;
3099 assertRequiredField(writable, 'writable', 'ReadableWritablePair');
3100 assertWritableStream(writable, `${context} has member 'writable' that`);
3101 return { readable, writable };
3102}
3103
3104/**
3105 * A readable stream represents a source of data, from which you can read.
3106 *
3107 * @public
3108 */
3109class ReadableStream {
3110 constructor(rawUnderlyingSource = {}, rawStrategy = {}) {
3111 if (rawUnderlyingSource === undefined) {
3112 rawUnderlyingSource = null;
3113 }
3114 else {
3115 assertObject(rawUnderlyingSource, 'First parameter');
3116 }
3117 const strategy = convertQueuingStrategy(rawStrategy, 'Second parameter');
3118 const underlyingSource = convertUnderlyingDefaultOrByteSource(rawUnderlyingSource, 'First parameter');
3119 InitializeReadableStream(this);
3120 if (underlyingSource.type === 'bytes') {
3121 if (strategy.size !== undefined) {
3122 throw new RangeError('The strategy for a byte stream cannot have a size function');
3123 }
3124 const highWaterMark = ExtractHighWaterMark(strategy, 0);
3125 SetUpReadableByteStreamControllerFromUnderlyingSource(this, underlyingSource, highWaterMark);
3126 }
3127 else {
3128 const sizeAlgorithm = ExtractSizeAlgorithm(strategy);
3129 const highWaterMark = ExtractHighWaterMark(strategy, 1);
3130 SetUpReadableStreamDefaultControllerFromUnderlyingSource(this, underlyingSource, highWaterMark, sizeAlgorithm);
3131 }
3132 }
3133 /**
3134 * Whether or not the readable stream is locked to a {@link ReadableStreamDefaultReader | reader}.
3135 */
3136 get locked() {
3137 if (!IsReadableStream(this)) {
3138 throw streamBrandCheckException$1('locked');
3139 }
3140 return IsReadableStreamLocked(this);
3141 }
3142 /**
3143 * Cancels the stream, signaling a loss of interest in the stream by a consumer.
3144 *
3145 * The supplied `reason` argument will be given to the underlying source's {@link UnderlyingSource.cancel | cancel()}
3146 * method, which might or might not use it.
3147 */
3148 cancel(reason = undefined) {
3149 if (!IsReadableStream(this)) {
3150 return promiseRejectedWith(streamBrandCheckException$1('cancel'));
3151 }
3152 if (IsReadableStreamLocked(this)) {
3153 return promiseRejectedWith(new TypeError('Cannot cancel a stream that already has a reader'));
3154 }
3155 return ReadableStreamCancel(this, reason);
3156 }
3157 getReader(rawOptions = undefined) {
3158 if (!IsReadableStream(this)) {
3159 throw streamBrandCheckException$1('getReader');
3160 }
3161 const options = convertReaderOptions(rawOptions, 'First parameter');
3162 if (options.mode === undefined) {
3163 return AcquireReadableStreamDefaultReader(this);
3164 }
3165 return AcquireReadableStreamBYOBReader(this);
3166 }
3167 pipeThrough(rawTransform, rawOptions = {}) {
3168 if (!IsReadableStream(this)) {
3169 throw streamBrandCheckException$1('pipeThrough');
3170 }
3171 assertRequiredArgument(rawTransform, 1, 'pipeThrough');
3172 const transform = convertReadableWritablePair(rawTransform, 'First parameter');
3173 const options = convertPipeOptions(rawOptions, 'Second parameter');
3174 if (IsReadableStreamLocked(this)) {
3175 throw new TypeError('ReadableStream.prototype.pipeThrough cannot be used on a locked ReadableStream');
3176 }
3177 if (IsWritableStreamLocked(transform.writable)) {
3178 throw new TypeError('ReadableStream.prototype.pipeThrough cannot be used on a locked WritableStream');
3179 }
3180 const promise = ReadableStreamPipeTo(this, transform.writable, options.preventClose, options.preventAbort, options.preventCancel, options.signal);
3181 setPromiseIsHandledToTrue(promise);
3182 return transform.readable;
3183 }
3184 pipeTo(destination, rawOptions = {}) {
3185 if (!IsReadableStream(this)) {
3186 return promiseRejectedWith(streamBrandCheckException$1('pipeTo'));
3187 }
3188 if (destination === undefined) {
3189 return promiseRejectedWith(`Parameter 1 is required in 'pipeTo'.`);
3190 }
3191 if (!IsWritableStream(destination)) {
3192 return promiseRejectedWith(new TypeError(`ReadableStream.prototype.pipeTo's first argument must be a WritableStream`));
3193 }
3194 let options;
3195 try {
3196 options = convertPipeOptions(rawOptions, 'Second parameter');
3197 }
3198 catch (e) {
3199 return promiseRejectedWith(e);
3200 }
3201 if (IsReadableStreamLocked(this)) {
3202 return promiseRejectedWith(new TypeError('ReadableStream.prototype.pipeTo cannot be used on a locked ReadableStream'));
3203 }
3204 if (IsWritableStreamLocked(destination)) {
3205 return promiseRejectedWith(new TypeError('ReadableStream.prototype.pipeTo cannot be used on a locked WritableStream'));
3206 }
3207 return ReadableStreamPipeTo(this, destination, options.preventClose, options.preventAbort, options.preventCancel, options.signal);
3208 }
3209 /**
3210 * Tees this readable stream, returning a two-element array containing the two resulting branches as
3211 * new {@link ReadableStream} instances.
3212 *
3213 * Teeing a stream will lock it, preventing any other consumer from acquiring a reader.
3214 * To cancel the stream, cancel both of the resulting branches; a composite cancellation reason will then be
3215 * propagated to the stream's underlying source.
3216 *
3217 * Note that the chunks seen in each branch will be the same object. If the chunks are not immutable,
3218 * this could allow interference between the two branches.
3219 */
3220 tee() {
3221 if (!IsReadableStream(this)) {
3222 throw streamBrandCheckException$1('tee');
3223 }
3224 const branches = ReadableStreamTee(this);
3225 return CreateArrayFromList(branches);
3226 }
3227 values(rawOptions = undefined) {
3228 if (!IsReadableStream(this)) {
3229 throw streamBrandCheckException$1('values');
3230 }
3231 const options = convertIteratorOptions(rawOptions, 'First parameter');
3232 return AcquireReadableStreamAsyncIterator(this, options.preventCancel);
3233 }
3234}
3235Object.defineProperties(ReadableStream.prototype, {
3236 cancel: { enumerable: true },
3237 getReader: { enumerable: true },
3238 pipeThrough: { enumerable: true },
3239 pipeTo: { enumerable: true },
3240 tee: { enumerable: true },
3241 values: { enumerable: true },
3242 locked: { enumerable: true }
3243});
3244if (typeof SymbolPolyfill.toStringTag === 'symbol') {
3245 Object.defineProperty(ReadableStream.prototype, SymbolPolyfill.toStringTag, {
3246 value: 'ReadableStream',
3247 configurable: true
3248 });
3249}
3250if (typeof SymbolPolyfill.asyncIterator === 'symbol') {
3251 Object.defineProperty(ReadableStream.prototype, SymbolPolyfill.asyncIterator, {
3252 value: ReadableStream.prototype.values,
3253 writable: true,
3254 configurable: true
3255 });
3256}
3257// Abstract operations for the ReadableStream.
3258// Throws if and only if startAlgorithm throws.
3259function CreateReadableStream(startAlgorithm, pullAlgorithm, cancelAlgorithm, highWaterMark = 1, sizeAlgorithm = () => 1) {
3260 const stream = Object.create(ReadableStream.prototype);
3261 InitializeReadableStream(stream);
3262 const controller = Object.create(ReadableStreamDefaultController.prototype);
3263 SetUpReadableStreamDefaultController(stream, controller, startAlgorithm, pullAlgorithm, cancelAlgorithm, highWaterMark, sizeAlgorithm);
3264 return stream;
3265}
3266function InitializeReadableStream(stream) {
3267 stream._state = 'readable';
3268 stream._reader = undefined;
3269 stream._storedError = undefined;
3270 stream._disturbed = false;
3271}
3272function IsReadableStream(x) {
3273 if (!typeIsObject(x)) {
3274 return false;
3275 }
3276 if (!Object.prototype.hasOwnProperty.call(x, '_readableStreamController')) {
3277 return false;
3278 }
3279 return true;
3280}
3281function IsReadableStreamLocked(stream) {
3282 if (stream._reader === undefined) {
3283 return false;
3284 }
3285 return true;
3286}
3287// ReadableStream API exposed for controllers.
3288function ReadableStreamCancel(stream, reason) {
3289 stream._disturbed = true;
3290 if (stream._state === 'closed') {
3291 return promiseResolvedWith(undefined);
3292 }
3293 if (stream._state === 'errored') {
3294 return promiseRejectedWith(stream._storedError);
3295 }
3296 ReadableStreamClose(stream);
3297 const sourceCancelPromise = stream._readableStreamController[CancelSteps](reason);
3298 return transformPromiseWith(sourceCancelPromise, noop);
3299}
3300function ReadableStreamClose(stream) {
3301 stream._state = 'closed';
3302 const reader = stream._reader;
3303 if (reader === undefined) {
3304 return;
3305 }
3306 defaultReaderClosedPromiseResolve(reader);
3307 if (IsReadableStreamDefaultReader(reader)) {
3308 reader._readRequests.forEach(readRequest => {
3309 readRequest._closeSteps();
3310 });
3311 reader._readRequests = new SimpleQueue();
3312 }
3313}
3314function ReadableStreamError(stream, e) {
3315 stream._state = 'errored';
3316 stream._storedError = e;
3317 const reader = stream._reader;
3318 if (reader === undefined) {
3319 return;
3320 }
3321 defaultReaderClosedPromiseReject(reader, e);
3322 if (IsReadableStreamDefaultReader(reader)) {
3323 reader._readRequests.forEach(readRequest => {
3324 readRequest._errorSteps(e);
3325 });
3326 reader._readRequests = new SimpleQueue();
3327 }
3328 else {
3329 reader._readIntoRequests.forEach(readIntoRequest => {
3330 readIntoRequest._errorSteps(e);
3331 });
3332 reader._readIntoRequests = new SimpleQueue();
3333 }
3334}
3335// Helper functions for the ReadableStream.
3336function streamBrandCheckException$1(name) {
3337 return new TypeError(`ReadableStream.prototype.${name} can only be used on a ReadableStream`);
3338}
3339
3340function convertQueuingStrategyInit(init, context) {
3341 assertDictionary(init, context);
3342 const highWaterMark = init === null || init === void 0 ? void 0 : init.highWaterMark;
3343 assertRequiredField(highWaterMark, 'highWaterMark', 'QueuingStrategyInit');
3344 return {
3345 highWaterMark: convertUnrestrictedDouble(highWaterMark)
3346 };
3347}
3348
3349const byteLengthSizeFunction = function size(chunk) {
3350 return chunk.byteLength;
3351};
3352/**
3353 * A queuing strategy that counts the number of bytes in each chunk.
3354 *
3355 * @public
3356 */
3357class ByteLengthQueuingStrategy {
3358 constructor(options) {
3359 assertRequiredArgument(options, 1, 'ByteLengthQueuingStrategy');
3360 options = convertQueuingStrategyInit(options, 'First parameter');
3361 this._byteLengthQueuingStrategyHighWaterMark = options.highWaterMark;
3362 }
3363 /**
3364 * Returns the high water mark provided to the constructor.
3365 */
3366 get highWaterMark() {
3367 if (!IsByteLengthQueuingStrategy(this)) {
3368 throw byteLengthBrandCheckException('highWaterMark');
3369 }
3370 return this._byteLengthQueuingStrategyHighWaterMark;
3371 }
3372 /**
3373 * Measures the size of `chunk` by returning the value of its `byteLength` property.
3374 */
3375 get size() {
3376 if (!IsByteLengthQueuingStrategy(this)) {
3377 throw byteLengthBrandCheckException('size');
3378 }
3379 return byteLengthSizeFunction;
3380 }
3381}
3382Object.defineProperties(ByteLengthQueuingStrategy.prototype, {
3383 highWaterMark: { enumerable: true },
3384 size: { enumerable: true }
3385});
3386if (typeof SymbolPolyfill.toStringTag === 'symbol') {
3387 Object.defineProperty(ByteLengthQueuingStrategy.prototype, SymbolPolyfill.toStringTag, {
3388 value: 'ByteLengthQueuingStrategy',
3389 configurable: true
3390 });
3391}
3392// Helper functions for the ByteLengthQueuingStrategy.
3393function byteLengthBrandCheckException(name) {
3394 return new TypeError(`ByteLengthQueuingStrategy.prototype.${name} can only be used on a ByteLengthQueuingStrategy`);
3395}
3396function IsByteLengthQueuingStrategy(x) {
3397 if (!typeIsObject(x)) {
3398 return false;
3399 }
3400 if (!Object.prototype.hasOwnProperty.call(x, '_byteLengthQueuingStrategyHighWaterMark')) {
3401 return false;
3402 }
3403 return true;
3404}
3405
3406const countSizeFunction = function size() {
3407 return 1;
3408};
3409/**
3410 * A queuing strategy that counts the number of chunks.
3411 *
3412 * @public
3413 */
3414class CountQueuingStrategy {
3415 constructor(options) {
3416 assertRequiredArgument(options, 1, 'CountQueuingStrategy');
3417 options = convertQueuingStrategyInit(options, 'First parameter');
3418 this._countQueuingStrategyHighWaterMark = options.highWaterMark;
3419 }
3420 /**
3421 * Returns the high water mark provided to the constructor.
3422 */
3423 get highWaterMark() {
3424 if (!IsCountQueuingStrategy(this)) {
3425 throw countBrandCheckException('highWaterMark');
3426 }
3427 return this._countQueuingStrategyHighWaterMark;
3428 }
3429 /**
3430 * Measures the size of `chunk` by always returning 1.
3431 * This ensures that the total queue size is a count of the number of chunks in the queue.
3432 */
3433 get size() {
3434 if (!IsCountQueuingStrategy(this)) {
3435 throw countBrandCheckException('size');
3436 }
3437 return countSizeFunction;
3438 }
3439}
3440Object.defineProperties(CountQueuingStrategy.prototype, {
3441 highWaterMark: { enumerable: true },
3442 size: { enumerable: true }
3443});
3444if (typeof SymbolPolyfill.toStringTag === 'symbol') {
3445 Object.defineProperty(CountQueuingStrategy.prototype, SymbolPolyfill.toStringTag, {
3446 value: 'CountQueuingStrategy',
3447 configurable: true
3448 });
3449}
3450// Helper functions for the CountQueuingStrategy.
3451function countBrandCheckException(name) {
3452 return new TypeError(`CountQueuingStrategy.prototype.${name} can only be used on a CountQueuingStrategy`);
3453}
3454function IsCountQueuingStrategy(x) {
3455 if (!typeIsObject(x)) {
3456 return false;
3457 }
3458 if (!Object.prototype.hasOwnProperty.call(x, '_countQueuingStrategyHighWaterMark')) {
3459 return false;
3460 }
3461 return true;
3462}
3463
3464function convertTransformer(original, context) {
3465 assertDictionary(original, context);
3466 const flush = original === null || original === void 0 ? void 0 : original.flush;
3467 const readableType = original === null || original === void 0 ? void 0 : original.readableType;
3468 const start = original === null || original === void 0 ? void 0 : original.start;
3469 const transform = original === null || original === void 0 ? void 0 : original.transform;
3470 const writableType = original === null || original === void 0 ? void 0 : original.writableType;
3471 return {
3472 flush: flush === undefined ?
3473 undefined :
3474 convertTransformerFlushCallback(flush, original, `${context} has member 'flush' that`),
3475 readableType,
3476 start: start === undefined ?
3477 undefined :
3478 convertTransformerStartCallback(start, original, `${context} has member 'start' that`),
3479 transform: transform === undefined ?
3480 undefined :
3481 convertTransformerTransformCallback(transform, original, `${context} has member 'transform' that`),
3482 writableType
3483 };
3484}
3485function convertTransformerFlushCallback(fn, original, context) {
3486 assertFunction(fn, context);
3487 return (controller) => promiseCall(fn, original, [controller]);
3488}
3489function convertTransformerStartCallback(fn, original, context) {
3490 assertFunction(fn, context);
3491 return (controller) => reflectCall(fn, original, [controller]);
3492}
3493function convertTransformerTransformCallback(fn, original, context) {
3494 assertFunction(fn, context);
3495 return (chunk, controller) => promiseCall(fn, original, [chunk, controller]);
3496}
3497
3498// Class TransformStream
3499/**
3500 * A transform stream consists of a pair of streams: a {@link WritableStream | writable stream},
3501 * known as its writable side, and a {@link ReadableStream | readable stream}, known as its readable side.
3502 * In a manner specific to the transform stream in question, writes to the writable side result in new data being
3503 * made available for reading from the readable side.
3504 *
3505 * @public
3506 */
3507class TransformStream {
3508 constructor(rawTransformer = {}, rawWritableStrategy = {}, rawReadableStrategy = {}) {
3509 if (rawTransformer === undefined) {
3510 rawTransformer = null;
3511 }
3512 const writableStrategy = convertQueuingStrategy(rawWritableStrategy, 'Second parameter');
3513 const readableStrategy = convertQueuingStrategy(rawReadableStrategy, 'Third parameter');
3514 const transformer = convertTransformer(rawTransformer, 'First parameter');
3515 if (transformer.readableType !== undefined) {
3516 throw new RangeError('Invalid readableType specified');
3517 }
3518 if (transformer.writableType !== undefined) {
3519 throw new RangeError('Invalid writableType specified');
3520 }
3521 const readableHighWaterMark = ExtractHighWaterMark(readableStrategy, 0);
3522 const readableSizeAlgorithm = ExtractSizeAlgorithm(readableStrategy);
3523 const writableHighWaterMark = ExtractHighWaterMark(writableStrategy, 1);
3524 const writableSizeAlgorithm = ExtractSizeAlgorithm(writableStrategy);
3525 let startPromise_resolve;
3526 const startPromise = newPromise(resolve => {
3527 startPromise_resolve = resolve;
3528 });
3529 InitializeTransformStream(this, startPromise, writableHighWaterMark, writableSizeAlgorithm, readableHighWaterMark, readableSizeAlgorithm);
3530 SetUpTransformStreamDefaultControllerFromTransformer(this, transformer);
3531 if (transformer.start !== undefined) {
3532 startPromise_resolve(transformer.start(this._transformStreamController));
3533 }
3534 else {
3535 startPromise_resolve(undefined);
3536 }
3537 }
3538 /**
3539 * The readable side of the transform stream.
3540 */
3541 get readable() {
3542 if (!IsTransformStream(this)) {
3543 throw streamBrandCheckException$2('readable');
3544 }
3545 return this._readable;
3546 }
3547 /**
3548 * The writable side of the transform stream.
3549 */
3550 get writable() {
3551 if (!IsTransformStream(this)) {
3552 throw streamBrandCheckException$2('writable');
3553 }
3554 return this._writable;
3555 }
3556}
3557Object.defineProperties(TransformStream.prototype, {
3558 readable: { enumerable: true },
3559 writable: { enumerable: true }
3560});
3561if (typeof SymbolPolyfill.toStringTag === 'symbol') {
3562 Object.defineProperty(TransformStream.prototype, SymbolPolyfill.toStringTag, {
3563 value: 'TransformStream',
3564 configurable: true
3565 });
3566}
3567function InitializeTransformStream(stream, startPromise, writableHighWaterMark, writableSizeAlgorithm, readableHighWaterMark, readableSizeAlgorithm) {
3568 function startAlgorithm() {
3569 return startPromise;
3570 }
3571 function writeAlgorithm(chunk) {
3572 return TransformStreamDefaultSinkWriteAlgorithm(stream, chunk);
3573 }
3574 function abortAlgorithm(reason) {
3575 return TransformStreamDefaultSinkAbortAlgorithm(stream, reason);
3576 }
3577 function closeAlgorithm() {
3578 return TransformStreamDefaultSinkCloseAlgorithm(stream);
3579 }
3580 stream._writable = CreateWritableStream(startAlgorithm, writeAlgorithm, closeAlgorithm, abortAlgorithm, writableHighWaterMark, writableSizeAlgorithm);
3581 function pullAlgorithm() {
3582 return TransformStreamDefaultSourcePullAlgorithm(stream);
3583 }
3584 function cancelAlgorithm(reason) {
3585 TransformStreamErrorWritableAndUnblockWrite(stream, reason);
3586 return promiseResolvedWith(undefined);
3587 }
3588 stream._readable = CreateReadableStream(startAlgorithm, pullAlgorithm, cancelAlgorithm, readableHighWaterMark, readableSizeAlgorithm);
3589 // The [[backpressure]] slot is set to undefined so that it can be initialised by TransformStreamSetBackpressure.
3590 stream._backpressure = undefined;
3591 stream._backpressureChangePromise = undefined;
3592 stream._backpressureChangePromise_resolve = undefined;
3593 TransformStreamSetBackpressure(stream, true);
3594 stream._transformStreamController = undefined;
3595}
3596function IsTransformStream(x) {
3597 if (!typeIsObject(x)) {
3598 return false;
3599 }
3600 if (!Object.prototype.hasOwnProperty.call(x, '_transformStreamController')) {
3601 return false;
3602 }
3603 return true;
3604}
3605// This is a no-op if both sides are already errored.
3606function TransformStreamError(stream, e) {
3607 ReadableStreamDefaultControllerError(stream._readable._readableStreamController, e);
3608 TransformStreamErrorWritableAndUnblockWrite(stream, e);
3609}
3610function TransformStreamErrorWritableAndUnblockWrite(stream, e) {
3611 TransformStreamDefaultControllerClearAlgorithms(stream._transformStreamController);
3612 WritableStreamDefaultControllerErrorIfNeeded(stream._writable._writableStreamController, e);
3613 if (stream._backpressure) {
3614 // Pretend that pull() was called to permit any pending write() calls to complete. TransformStreamSetBackpressure()
3615 // cannot be called from enqueue() or pull() once the ReadableStream is errored, so this will will be the final time
3616 // _backpressure is set.
3617 TransformStreamSetBackpressure(stream, false);
3618 }
3619}
3620function TransformStreamSetBackpressure(stream, backpressure) {
3621 // Passes also when called during construction.
3622 if (stream._backpressureChangePromise !== undefined) {
3623 stream._backpressureChangePromise_resolve();
3624 }
3625 stream._backpressureChangePromise = newPromise(resolve => {
3626 stream._backpressureChangePromise_resolve = resolve;
3627 });
3628 stream._backpressure = backpressure;
3629}
3630// Class TransformStreamDefaultController
3631/**
3632 * Allows control of the {@link ReadableStream} and {@link WritableStream} of the associated {@link TransformStream}.
3633 *
3634 * @public
3635 */
3636class TransformStreamDefaultController {
3637 constructor() {
3638 throw new TypeError('Illegal constructor');
3639 }
3640 /**
3641 * Returns the desired size to fill the readable side’s internal queue. It can be negative, if the queue is over-full.
3642 */
3643 get desiredSize() {
3644 if (!IsTransformStreamDefaultController(this)) {
3645 throw defaultControllerBrandCheckException$1('desiredSize');
3646 }
3647 const readableController = this._controlledTransformStream._readable._readableStreamController;
3648 return ReadableStreamDefaultControllerGetDesiredSize(readableController);
3649 }
3650 enqueue(chunk = undefined) {
3651 if (!IsTransformStreamDefaultController(this)) {
3652 throw defaultControllerBrandCheckException$1('enqueue');
3653 }
3654 TransformStreamDefaultControllerEnqueue(this, chunk);
3655 }
3656 /**
3657 * Errors both the readable side and the writable side of the controlled transform stream, making all future
3658 * interactions with it fail with the given error `e`. Any chunks queued for transformation will be discarded.
3659 */
3660 error(reason = undefined) {
3661 if (!IsTransformStreamDefaultController(this)) {
3662 throw defaultControllerBrandCheckException$1('error');
3663 }
3664 TransformStreamDefaultControllerError(this, reason);
3665 }
3666 /**
3667 * Closes the readable side and errors the writable side of the controlled transform stream. This is useful when the
3668 * transformer only needs to consume a portion of the chunks written to the writable side.
3669 */
3670 terminate() {
3671 if (!IsTransformStreamDefaultController(this)) {
3672 throw defaultControllerBrandCheckException$1('terminate');
3673 }
3674 TransformStreamDefaultControllerTerminate(this);
3675 }
3676}
3677Object.defineProperties(TransformStreamDefaultController.prototype, {
3678 enqueue: { enumerable: true },
3679 error: { enumerable: true },
3680 terminate: { enumerable: true },
3681 desiredSize: { enumerable: true }
3682});
3683if (typeof SymbolPolyfill.toStringTag === 'symbol') {
3684 Object.defineProperty(TransformStreamDefaultController.prototype, SymbolPolyfill.toStringTag, {
3685 value: 'TransformStreamDefaultController',
3686 configurable: true
3687 });
3688}
3689// Transform Stream Default Controller Abstract Operations
3690function IsTransformStreamDefaultController(x) {
3691 if (!typeIsObject(x)) {
3692 return false;
3693 }
3694 if (!Object.prototype.hasOwnProperty.call(x, '_controlledTransformStream')) {
3695 return false;
3696 }
3697 return true;
3698}
3699function SetUpTransformStreamDefaultController(stream, controller, transformAlgorithm, flushAlgorithm) {
3700 controller._controlledTransformStream = stream;
3701 stream._transformStreamController = controller;
3702 controller._transformAlgorithm = transformAlgorithm;
3703 controller._flushAlgorithm = flushAlgorithm;
3704}
3705function SetUpTransformStreamDefaultControllerFromTransformer(stream, transformer) {
3706 const controller = Object.create(TransformStreamDefaultController.prototype);
3707 let transformAlgorithm = (chunk) => {
3708 try {
3709 TransformStreamDefaultControllerEnqueue(controller, chunk);
3710 return promiseResolvedWith(undefined);
3711 }
3712 catch (transformResultE) {
3713 return promiseRejectedWith(transformResultE);
3714 }
3715 };
3716 let flushAlgorithm = () => promiseResolvedWith(undefined);
3717 if (transformer.transform !== undefined) {
3718 transformAlgorithm = chunk => transformer.transform(chunk, controller);
3719 }
3720 if (transformer.flush !== undefined) {
3721 flushAlgorithm = () => transformer.flush(controller);
3722 }
3723 SetUpTransformStreamDefaultController(stream, controller, transformAlgorithm, flushAlgorithm);
3724}
3725function TransformStreamDefaultControllerClearAlgorithms(controller) {
3726 controller._transformAlgorithm = undefined;
3727 controller._flushAlgorithm = undefined;
3728}
3729function TransformStreamDefaultControllerEnqueue(controller, chunk) {
3730 const stream = controller._controlledTransformStream;
3731 const readableController = stream._readable._readableStreamController;
3732 if (!ReadableStreamDefaultControllerCanCloseOrEnqueue(readableController)) {
3733 throw new TypeError('Readable side is not in a state that permits enqueue');
3734 }
3735 // We throttle transform invocations based on the backpressure of the ReadableStream, but we still
3736 // accept TransformStreamDefaultControllerEnqueue() calls.
3737 try {
3738 ReadableStreamDefaultControllerEnqueue(readableController, chunk);
3739 }
3740 catch (e) {
3741 // This happens when readableStrategy.size() throws.
3742 TransformStreamErrorWritableAndUnblockWrite(stream, e);
3743 throw stream._readable._storedError;
3744 }
3745 const backpressure = ReadableStreamDefaultControllerHasBackpressure(readableController);
3746 if (backpressure !== stream._backpressure) {
3747 TransformStreamSetBackpressure(stream, true);
3748 }
3749}
3750function TransformStreamDefaultControllerError(controller, e) {
3751 TransformStreamError(controller._controlledTransformStream, e);
3752}
3753function TransformStreamDefaultControllerPerformTransform(controller, chunk) {
3754 const transformPromise = controller._transformAlgorithm(chunk);
3755 return transformPromiseWith(transformPromise, undefined, r => {
3756 TransformStreamError(controller._controlledTransformStream, r);
3757 throw r;
3758 });
3759}
3760function TransformStreamDefaultControllerTerminate(controller) {
3761 const stream = controller._controlledTransformStream;
3762 const readableController = stream._readable._readableStreamController;
3763 ReadableStreamDefaultControllerClose(readableController);
3764 const error = new TypeError('TransformStream terminated');
3765 TransformStreamErrorWritableAndUnblockWrite(stream, error);
3766}
3767// TransformStreamDefaultSink Algorithms
3768function TransformStreamDefaultSinkWriteAlgorithm(stream, chunk) {
3769 const controller = stream._transformStreamController;
3770 if (stream._backpressure) {
3771 const backpressureChangePromise = stream._backpressureChangePromise;
3772 return transformPromiseWith(backpressureChangePromise, () => {
3773 const writable = stream._writable;
3774 const state = writable._state;
3775 if (state === 'erroring') {
3776 throw writable._storedError;
3777 }
3778 return TransformStreamDefaultControllerPerformTransform(controller, chunk);
3779 });
3780 }
3781 return TransformStreamDefaultControllerPerformTransform(controller, chunk);
3782}
3783function TransformStreamDefaultSinkAbortAlgorithm(stream, reason) {
3784 // abort() is not called synchronously, so it is possible for abort() to be called when the stream is already
3785 // errored.
3786 TransformStreamError(stream, reason);
3787 return promiseResolvedWith(undefined);
3788}
3789function TransformStreamDefaultSinkCloseAlgorithm(stream) {
3790 // stream._readable cannot change after construction, so caching it across a call to user code is safe.
3791 const readable = stream._readable;
3792 const controller = stream._transformStreamController;
3793 const flushPromise = controller._flushAlgorithm();
3794 TransformStreamDefaultControllerClearAlgorithms(controller);
3795 // Return a promise that is fulfilled with undefined on success.
3796 return transformPromiseWith(flushPromise, () => {
3797 if (readable._state === 'errored') {
3798 throw readable._storedError;
3799 }
3800 ReadableStreamDefaultControllerClose(readable._readableStreamController);
3801 }, r => {
3802 TransformStreamError(stream, r);
3803 throw readable._storedError;
3804 });
3805}
3806// TransformStreamDefaultSource Algorithms
3807function TransformStreamDefaultSourcePullAlgorithm(stream) {
3808 // Invariant. Enforced by the promises returned by start() and pull().
3809 TransformStreamSetBackpressure(stream, false);
3810 // Prevent the next pull() call until there is backpressure.
3811 return stream._backpressureChangePromise;
3812}
3813// Helper functions for the TransformStreamDefaultController.
3814function defaultControllerBrandCheckException$1(name) {
3815 return new TypeError(`TransformStreamDefaultController.prototype.${name} can only be used on a TransformStreamDefaultController`);
3816}
3817// Helper functions for the TransformStream.
3818function streamBrandCheckException$2(name) {
3819 return new TypeError(`TransformStream.prototype.${name} can only be used on a TransformStream`);
3820}
3821
3822const exports = {
3823 ReadableStream,
3824 ReadableStreamDefaultController,
3825 ReadableByteStreamController,
3826 ReadableStreamBYOBRequest,
3827 ReadableStreamDefaultReader,
3828 ReadableStreamBYOBReader,
3829 WritableStream,
3830 WritableStreamDefaultController,
3831 WritableStreamDefaultWriter,
3832 ByteLengthQueuingStrategy,
3833 CountQueuingStrategy,
3834 TransformStream,
3835 TransformStreamDefaultController
3836};
3837// Add classes to global scope
3838if (typeof globals !== 'undefined') {
3839 for (const prop in exports) {
3840 if (Object.prototype.hasOwnProperty.call(exports, prop)) {
3841 Object.defineProperty(globals, prop, {
3842 value: exports[prop],
3843 writable: true,
3844 configurable: true
3845 });
3846 }
3847 }
3848}
3849
3850export { ByteLengthQueuingStrategy, CountQueuingStrategy, ReadableByteStreamController, ReadableStream, ReadableStreamBYOBReader, ReadableStreamBYOBRequest, ReadableStreamDefaultController, ReadableStreamDefaultReader, TransformStream, TransformStreamDefaultController, WritableStream, WritableStreamDefaultController, WritableStreamDefaultWriter };
3851//# sourceMappingURL=polyfill.es6.mjs.map