@CommonOperationsU­ (function(global, binding, v8) { 'use strict'; const _queue = v8.createPrivateSymbol('[[queue]]'); const _queueTotalSize = v8.createPrivateSymbol('[[queueTotalSize]]'); const _isSettled = v8.createPrivateSymbol('isSettled'); const Boolean = global.Boolean; const Number = global.Number; const Number_isFinite = Number.isFinite; const Number_isNaN = Number.isNaN; const RangeError = global.RangeError; const TypeError = global.TypeError; const TypeError_prototype = TypeError.prototype; const hasOwnProperty = v8.uncurryThis(global.Object.hasOwnProperty); const getPrototypeOf = global.Object.getPrototypeOf.bind(global.Object); const getOwnPropertyDescriptor = global.Object.getOwnPropertyDescriptor.bind(global.Object); const thenPromise = v8.uncurryThis(Promise.prototype.then); const JSON_parse = global.JSON.parse.bind(global.JSON); const JSON_stringify = global.JSON.stringify.bind(global.JSON); function hasOwnPropertyNoThrow(x, property) { return Boolean(x) && hasOwnProperty(x, property); } function streamInternalError() { throw new RangeError('Stream API Internal Error'); } function createPromise() { const p = v8.createPromise(); p[_isSettled] = false; return p; } function rejectPromise(p, reason) { if (!v8.isPromise(p)) { streamInternalError(); } if (p[_isSettled] !== false) { return; } p[_isSettled] = true; v8.rejectPromise(p, reason); } function createRejectedPromise(reason) { const p = createPromise(); rejectPromise(p, reason); return p; } function resolvePromise(p, value) { if (!v8.isPromise(p)) { streamInternalError(); } if (p[_isSettled] !== false) { return; } p[_isSettled] = true; v8.resolvePromise(p, value); } function createResolvedPromise(value) { if (v8.isPromise(value)) { return value; } const p = createPromise(); resolvePromise(p, value); return p; } function markPromiseAsHandled(p) { if (!v8.isPromise(p)) { streamInternalError(); } v8.markPromiseAsHandled(p); } function promiseState(p) { if (!v8.isPromise(p)) { streamInternalError(); } return v8.promiseState(p); } function DequeueValue(container) { const pair = container[_queue].shift(); container[_queueTotalSize] -= pair.size; if (container[_queueTotalSize] < 0) { container[_queueTotalSize] = 0; } return pair.value; } function EnqueueValueWithSize(container, value, size) { size = Number(size); if (!IsFiniteNonNegativeNumber(size)) { throw new RangeError(binding.streamErrors.invalidSize); } container[_queue].push({value, size}); container[_queueTotalSize] += size; } function PeekQueueValue(container) { const pair = container[_queue].peek(); return pair.value; } function ResetQueue(container) { container[_queue] = new binding.SimpleQueue(); container[_queueTotalSize] = 0; } function IsFiniteNonNegativeNumber(v) { return Number_isFinite(v) && v >= 0; } function ValidateAndNormalizeHighWaterMark(highWaterMark) { highWaterMark = Number(highWaterMark); if (Number_isNaN(highWaterMark)) { throw new RangeError(binding.streamErrors.invalidHWM); } if (highWaterMark < 0) { throw new RangeError(binding.streamErrors.invalidHWM); } return highWaterMark; } function MakeSizeAlgorithmFromSizeFunction(size) { if (size === undefined) { return () => 1; } if (typeof size !== 'function') { throw new TypeError(binding.streamErrors.sizeNotAFunction); } return size; } const callFunction = v8.uncurryThis(global.Function.prototype.call); const errTmplMustBeFunctionOrUndefined = name => `${name} must be a function or undefined`; const Function_bind = v8.uncurryThis(global.Function.prototype.bind); function resolveMethod(O, P, nameForError) { const method = O[P]; if (typeof method !== 'function' && typeof method !== 'undefined') { throw new TypeError(errTmplMustBeFunctionOrUndefined(nameForError)); } return method; } function CreateAlgorithmFromUnderlyingMethod( underlyingObject, methodName, algoArgCount, methodNameForError) { const method = resolveMethod(underlyingObject, methodName, methodNameForError); if (method === undefined) { return () => createResolvedPromise(); } if (algoArgCount === 0) { return Function_bind(PromiseCall0, undefined, method, underlyingObject); } return Function_bind(PromiseCall1, undefined, method, underlyingObject); } function CreateAlgorithmFromUnderlyingMethodPassingController( underlyingObject, methodName, algoArgCount, controller, methodNameForError) { const method = resolveMethod(underlyingObject, methodName, methodNameForError); if (method === undefined) { return () => createResolvedPromise(); } if (algoArgCount === 0) { return Function_bind( PromiseCall1, undefined, method, underlyingObject, controller); } return arg => PromiseCall2(method, underlyingObject, arg, controller); } function CallOrNoop1(O, P, arg0, nameForError) { const method = resolveMethod(O, P, nameForError); if (method === undefined) { return undefined; } return callFunction(method, O, arg0); } function PromiseCall0(F, V) { try { return createResolvedPromise(callFunction(F, V)); } catch (e) { return createRejectedPromise(e); } } function PromiseCall1(F, V, arg0) { try { return createResolvedPromise(callFunction(F, V, arg0)); } catch (e) { return createRejectedPromise(e); } } function PromiseCall2(F, V, arg0, arg1) { try { return createResolvedPromise(callFunction(F, V, arg0, arg1)); } catch (e) { return createRejectedPromise(e); } } const kPull = 1; const kCancel = 2; const kChunk = 3; const kClose = 4; const kAbort = 5; const kError = 6; function isATypeError(object) { return object !== null && getPrototypeOf(object) === TypeError_prototype; } function isADOMException(object) { try { callFunction(binding.DOMException_name_get, object); return true; } catch (e) { return false; } } function packReason(reason) { switch (typeof reason) { case 'string': case 'number': case 'boolean': return {encoder: 'json', string: JSON_stringify(reason)}; case 'object': try { if (isATypeError(reason)) { let message; const descriptor = getOwnPropertyDescriptor(reason, 'message'); if (descriptor) { message = descriptor.value; if (typeof message !== 'string') { message = undefined; } } return {encoder: 'typeerror', string: message}; } if (isADOMException(reason)) { const message = callFunction(binding.DOMException_message_get, reason); const name = callFunction(binding.DOMException_name_get, reason); return { encoder: 'domexception', string: JSON_stringify({message, name}) }; } return {encoder: 'json', string: JSON_stringify(reason)}; } catch (e) { return {encoder: 'typeerror', string: 'Cannot transfer message'}; } default: return {encoder: 'undefined', string: undefined}; } } function unpackReason(packedReason) { const {encoder, string} = packedReason; switch (encoder) { case 'json': return JSON_parse(string); case 'typeerror': return new TypeError(string); case 'domexception': const {message, name} = JSON_parse(string); return new binding.DOMException(message, name); case 'undefined': return undefined; } } function CreateCrossRealmTransformWritable(port) { let backpressurePromise = createPromise(); callFunction(binding.EventTarget_addEventListener, port, 'message', evt => { const {type, value} = callFunction(binding.MessageEvent_data_get, evt); switch (type) { case kPull: resolvePromise(backpressurePromise); backpressurePromise = undefined; break; case kCancel: case kError: binding.WritableStreamDefaultControllerErrorIfNeeded( controller, unpackReason(value)); if (backpressurePromise !== undefined) { resolvePromise(backpressurePromise); backpressurePromise = undefined; } break; } }); callFunction( binding.EventTarget_addEventListener, port, 'messageerror', () => { const error = new binding.DOMException('chunk could not be cloned', 'DataCloneError'); callFunction(binding.MessagePort_postMessage, port, {type: kError, value: packReason(error)}); callFunction(binding.MessagePort_close, port); binding.WritableStreamDefaultControllerErrorIfNeeded(controller, error); }); callFunction(binding.MessagePort_start, port); function doWrite(chunk) { backpressurePromise = createPromise(); try { callFunction( binding.MessagePort_postMessage, port, {type: kChunk, value: chunk}); } catch (e) { callFunction( binding.MessagePort_postMessage, port, {type: kError, value: packReason(e)}); callFunction(binding.MessagePort_close, port); throw e; } } const stream = binding.CreateWritableStream( () => undefined, chunk => { if (!backpressurePromise) { return PromiseCall1(doWrite, null, chunk); } return thenPromise(backpressurePromise, () => doWrite(chunk)); }, () => { callFunction( binding.MessagePort_postMessage, port, {type: kClose, value: undefined}); callFunction(binding.MessagePort_close, port); return createResolvedPromise(); }, reason => { callFunction( binding.MessagePort_postMessage, port, {type: kAbort, value: packReason(reason)}); callFunction(binding.MessagePort_close, port); return createResolvedPromise(); }); const controller = binding.getWritableStreamController(stream); return stream; } function CreateCrossRealmTransformReadable(port) { let backpressurePromise = createPromise(); let finished = false; callFunction(binding.EventTarget_addEventListener, port, 'message', evt => { const {type, value} = callFunction(binding.MessageEvent_data_get, evt); if (finished) { return; } switch (type) { case kChunk: binding.ReadableStreamDefaultControllerEnqueue(controller, value); resolvePromise(backpressurePromise); backpressurePromise = createPromise(); break; case kClose: finished = true; binding.ReadableStreamDefaultControllerClose(controller); callFunction(binding.MessagePort_close, port); break; case kAbort: case kError: finished = true; binding.ReadableStreamDefaultControllerError( controller, unpackReason(value)); callFunction(binding.MessagePort_close, port); break; } }); callFunction( binding.EventTarget_addEventListener, port, 'messageerror', () => { const error = new binding.DOMException('chunk could not be cloned', 'DataCloneError'); callFunction(binding.MessagePort_postMessage, port, {type: kError, value: packReason(error)}); callFunction(binding.MessagePort_close, port); binding.ReadableStreamDefaultControllerError(controller, error); }); callFunction(binding.MessagePort_start, port); const stream = binding.CreateReadableStream( () => undefined, () => { callFunction( binding.MessagePort_postMessage, port, {type: kPull, value: undefined}); return backpressurePromise; }, reason => { finished = true; callFunction( binding.MessagePort_postMessage, port, {type: kCancel, value: packReason(reason)}); callFunction(binding.MessagePort_close, port); return createResolvedPromise(); }, 0); const controller = binding.getReadableStreamController(stream); return stream; } binding.streamOperations = { _queue, _queueTotalSize, createPromise, createRejectedPromise, createResolvedPromise, hasOwnPropertyNoThrow, rejectPromise, resolvePromise, markPromiseAsHandled, promiseState, CreateAlgorithmFromUnderlyingMethod, CreateAlgorithmFromUnderlyingMethodPassingController, CreateCrossRealmTransformWritable, CreateCrossRealmTransformReadable, DequeueValue, EnqueueValueWithSize, PeekQueueValue, ResetQueue, ValidateAndNormalizeHighWaterMark, MakeSizeAlgorithmFromSizeFunction, CallOrNoop1, PromiseCall2 }; }); 4CommonStringså (function(global, binding, v8) { 'use strict'; binding.streamErrors = { cannotTransferLockedStream: 'Cannot transfer a locked stream', cannotTransferContext: 'Cannot transfer from this context', illegalInvocation: 'Illegal invocation', illegalConstructor: 'Illegal constructor', invalidType: 'Invalid type is specified', invalidSize: 'The return value of a queuing strategy\'s size function ' + 'must be a finite, non-NaN, non-negative number', sizeNotAFunction: 'A queuing strategy\'s size property must be a function', invalidHWM: 'A queueing strategy\'s highWaterMark property must be a nonnegative, ' + 'non-NaN number', }; }); ,SimpleQueueý (function(global, binding, v8) { 'use strict'; const _front = v8.createPrivateSymbol('front'); const _back = v8.createPrivateSymbol('back'); const _cursor = v8.createPrivateSymbol('cursor'); const _size = v8.createPrivateSymbol('size'); const _elements = v8.createPrivateSymbol('elements'); const _next = v8.createPrivateSymbol('next'); const RangeError = global.RangeError; function requireNonEmptyQueue(queue, functionName) { if (queue[_size] === 0) { throw new RangeError( `${functionName}() must not be called on an empty queue`); } } const QUEUE_MAX_ARRAY_SIZE = 16384; class SimpleQueue { constructor() { this[_front] = { [_elements]: new v8.InternalPackedArray(), [_next]: undefined, }; this[_back] = this[_front]; this[_cursor] = 0; this[_size] = 0; } get length() { return this[_size]; } push(element) { const oldBack = this[_back]; let newBack = oldBack; if (oldBack[_elements].length === QUEUE_MAX_ARRAY_SIZE - 1) { newBack = { [_elements]: new v8.InternalPackedArray(), [_next]: undefined, }; } oldBack[_elements].push(element); if (newBack !== oldBack) { this[_back] = newBack; oldBack[_next] = newBack; } ++this[_size]; } shift() { requireNonEmptyQueue(this, 'shift'); const oldFront = this[_front]; let newFront = oldFront; const oldCursor = this[_cursor]; let newCursor = oldCursor + 1; const elements = oldFront[_elements]; const element = elements[oldCursor]; if (newCursor === QUEUE_MAX_ARRAY_SIZE) { newFront = oldFront[_next]; newCursor = 0; } --this[_size]; this[_cursor] = newCursor; if (oldFront !== newFront) { this[_front] = newFront; } elements[oldCursor] = undefined; return element; } forEach(callback) { let i = this[_cursor]; let node = this[_front]; let elements = node[_elements]; while (i !== elements.length || node[_next] !== undefined) { if (i === elements.length) { node = node[_next]; elements = node[_elements]; i = 0; if (elements.length === 0) { break; } } callback(elements[i]); ++i; } } peek() { requireNonEmptyQueue(this, 'peek'); const front = this[_front]; const cursor = this[_cursor]; return front[_elements][cursor]; } } binding.SimpleQueue = SimpleQueue; }); dByteLengthQueuingStrategy (function(global, binding, v8) { 'use strict'; const defineProperty = global.Object.defineProperty; class ByteLengthQueuingStrategy { constructor(options) { defineProperty(this, 'highWaterMark', { value: options.highWaterMark, enumerable: true, configurable: true, writable: true }); } size(chunk) { return chunk.byteLength; } } defineProperty(global, 'ByteLengthQueuingStrategy', { value: ByteLengthQueuingStrategy, enumerable: false, configurable: true, writable: true }); }); PCountQueuingStrategy (function(global, binding, v8) { 'use strict'; const defineProperty = global.Object.defineProperty; class CountQueuingStrategy { constructor(options) { defineProperty(this, 'highWaterMark', { value: options.highWaterMark, enumerable: true, configurable: true, writable: true }); } size() { return 1; } } defineProperty(global, 'CountQueuingStrategy', { value: CountQueuingStrategy, enumerable: false, configurable: true, writable: true }); class BuiltInCountQueuingStrategy { constructor(highWaterMark) { defineProperty(this, 'highWaterMark', {value: highWaterMark}); } size() { return 1; } } binding.createBuiltInCountQueuingStrategy = highWaterMark => new BuiltInCountQueuingStrategy(highWaterMark); }); 8ReadableStream¸ (function(global, binding, v8) { 'use strict'; const _reader = v8.createPrivateSymbol('[[reader]]'); const _storedError = v8.createPrivateSymbol('[[storedError]]'); const _controller = v8.createPrivateSymbol('[[controller]]'); const _closedPromise = v8.createPrivateSymbol('[[closedPromise]]'); const _ownerReadableStream = v8.createPrivateSymbol('[[ownerReadableStream]]'); const _readRequests = v8.createPrivateSymbol('[[readRequests]]'); const createWithExternalControllerSentinel = v8.createPrivateSymbol('flag for UA-created ReadableStream to pass'); const _readableStreamBits = v8.createPrivateSymbol('bit field for [[state]] and [[disturbed]]'); const DISTURBED = 0b1; const STATE_MASK = 0b110; const STATE_BITS_OFFSET = 1; const STATE_READABLE = 0; const STATE_CLOSED = 1; const STATE_ERRORED = 2; const _controlledReadableStream = v8.createPrivateSymbol('[[controlledReadableStream]]'); const _strategyHWM = v8.createPrivateSymbol('[[strategyHWM]]'); const _readableStreamDefaultControllerBits = v8.createPrivateSymbol( 'bit field for [[started]], [[closeRequested]], [[pulling]], ' + '[[pullAgain]]'); const internalReadableStreamSymbol = v8.createPrivateSymbol( 'internal ReadableStream in exposed ReadableStream interface'); const _lockNotifyTarget = v8.createPrivateSymbol('[[lockNotifyTarget]]'); const _strategySizeAlgorithm = v8.createPrivateSymbol( '[[strategySizeAlgorithm]]'); const _pullAlgorithm = v8.createPrivateSymbol('[[pullAlgorithm]]'); const _cancelAlgorithm = v8.createPrivateSymbol('[[cancelAlgorithm]]'); const STARTED = 0b1; const CLOSE_REQUESTED = 0b10; const PULLING = 0b100; const PULL_AGAIN = 0b1000; const BLINK_LOCK_NOTIFICATIONS = 0b10000; const ObjectCreate = global.Object.create; const callFunction = v8.uncurryThis(global.Function.prototype.call); const applyFunction = v8.uncurryThis(global.Function.prototype.apply); const TypeError = global.TypeError; const RangeError = global.RangeError; const String = global.String; const Promise = global.Promise; const thenPromise = v8.uncurryThis(Promise.prototype.then); const { _queue, _queueTotalSize, createPromise, createRejectedPromise, createResolvedPromise, hasOwnPropertyNoThrow, rejectPromise, resolvePromise, markPromiseAsHandled, CallOrNoop1, CreateAlgorithmFromUnderlyingMethod, CreateAlgorithmFromUnderlyingMethodPassingController, CreateCrossRealmTransformReadable, CreateCrossRealmTransformWritable, DequeueValue, EnqueueValueWithSize, MakeSizeAlgorithmFromSizeFunction, ValidateAndNormalizeHighWaterMark, } = binding.streamOperations; const streamErrors = binding.streamErrors; const errEnqueueCloseRequestedStream = 'Cannot enqueue a chunk into a readable stream that is closed or ' + 'has been requested to be closed'; const errCancelReleasedReader = 'This readable stream reader has been released and cannot be used ' + 'to cancel its previous owner stream'; const errReadReleasedReader = 'This readable stream reader has been released and cannot be used ' + 'to read from its previous owner stream'; const errCloseCloseRequestedStream = 'Cannot close a readable stream that has already been requested to ' + 'be closed'; const errEnqueueClosedStream = 'Cannot enqueue a chunk into a closed readable stream'; const errEnqueueErroredStream = 'Cannot enqueue a chunk into an errored readable stream'; const errCloseClosedStream = 'Cannot close a closed readable stream'; const errCloseErroredStream = 'Cannot close an errored readable stream'; const errReaderConstructorBadArgument = 'ReadableStreamReader constructor argument is not a readable stream'; const errReaderConstructorStreamAlreadyLocked = 'ReadableStreamReader constructor can only accept readable streams ' + 'that are not yet locked to a reader'; const errReleaseReaderWithPendingRead = 'Cannot release a readable stream reader when it still has ' + 'outstanding read() calls that have not yet settled'; const errReleasedReaderClosedPromise = 'This readable stream reader has been released and cannot be used ' + 'to monitor the stream\'s state'; const errDestinationStreamClosed = 'Destination stream closed'; let useCounted = false; class ReadableStream { constructor(underlyingSource = {}, strategy = {}, internalArgument = undefined) { const enableBlinkLockNotifications = internalArgument === createWithExternalControllerSentinel; if (!useCounted && !enableBlinkLockNotifications) { binding.countUse('ReadableStreamConstructor'); useCounted = true; } InitializeReadableStream(this); const size = strategy.size; let highWaterMark = strategy.highWaterMark; const type = underlyingSource.type; const typeString = String(type); if (typeString === 'bytes') { throw new RangeError('bytes type is not yet implemented'); } if (type !== undefined) { throw new RangeError(streamErrors.invalidType); } const sizeAlgorithm = MakeSizeAlgorithmFromSizeFunction(size); if (highWaterMark === undefined) { highWaterMark = 1; } highWaterMark = ValidateAndNormalizeHighWaterMark(highWaterMark); SetUpReadableStreamDefaultControllerFromUnderlyingSource( this, underlyingSource, highWaterMark, sizeAlgorithm, enableBlinkLockNotifications); } } const ReadableStream_prototype = ReadableStream.prototype; function ReadableStreamPipeTo( readable, dest, preventClose, preventAbort, preventCancel) { const reader = AcquireReadableStreamDefaultReader(readable); const writer = binding.AcquireWritableStreamDefaultWriter(dest); let shuttingDown = false; const promise = createPromise(); let reading = false; let lastWrite; if (checkInitialState()) { thenPromise(reader[_closedPromise], onReaderClosed, readableError); thenPromise( binding.getWritableStreamDefaultWriterClosedPromise(writer), undefined, writableError); pump(); } function checkInitialState() { const state = ReadableStreamGetState(readable); if (state === STATE_ERRORED) { readableError(readable[_storedError]); return false; } if (binding.isWritableStreamErrored(dest)) { writableError(binding.getWritableStreamStoredError(dest)); return false; } if (state === STATE_CLOSED) { readableClosed(); return false; } if (binding.isWritableStreamClosingOrClosed(dest)) { writableStartedClosed(); return false; } return true; } function pump() { if (shuttingDown) { return; } const desiredSize = binding.WritableStreamDefaultWriterGetDesiredSize(writer); if (desiredSize === null) { return; } if (desiredSize <= 0) { thenPromise( binding.getWritableStreamDefaultWriterReadyPromise(writer), pump, writableError); return; } reading = true; thenPromise( ReadableStreamDefaultReaderRead(reader), readFulfilled, readRejected); } function readFulfilled({value, done}) { reading = false; if (done) { readableClosed(); return; } const write = binding.WritableStreamDefaultWriterWrite(writer, value); lastWrite = write; thenPromise(write, undefined, writableError); pump(); } function readRejected() { reading = false; readableError(readable[_storedError]); } function onReaderClosed() { if (!reading) { readableClosed(); } } function readableError(error) { if (!preventAbort) { shutdownWithAction( binding.WritableStreamAbort, [dest, error], error, true); } else { shutdown(error, true); } } function writableError(error) { if (!preventCancel) { shutdownWithAction( ReadableStreamCancel, [readable, error], error, true); } else { shutdown(error, true); } } function readableClosed() { if (!preventClose) { shutdownWithAction( binding.WritableStreamDefaultWriterCloseWithErrorPropagation, [writer]); } else { shutdown(); } } function writableStartedClosed() { const destClosed = new TypeError(errDestinationStreamClosed); if (!preventCancel) { shutdownWithAction( ReadableStreamCancel, [readable, destClosed], destClosed, true); } else { shutdown(destClosed, true); } } function shutdownWithAction( action, args, originalError = undefined, errorGiven = false) { if (shuttingDown) { return; } shuttingDown = true; let p; if (shouldWriteQueuedChunks()) { p = thenPromise(writeQueuedChunks(), () => applyFunction(action, undefined, args)); } else { p = applyFunction(action, undefined, args); } thenPromise( p, () => finalize(originalError, errorGiven), newError => finalize(newError, true)); } function shutdown(error = undefined, errorGiven = false) { if (shuttingDown) { return; } shuttingDown = true; if (shouldWriteQueuedChunks()) { thenPromise(writeQueuedChunks(), () => finalize(error, errorGiven)); } else { finalize(error, errorGiven); } } function finalize(error, errorGiven) { binding.WritableStreamDefaultWriterRelease(writer); ReadableStreamReaderGenericRelease(reader); if (errorGiven) { rejectPromise(promise, error); } else { resolvePromise(promise, undefined); } } function shouldWriteQueuedChunks() { return binding.isWritableStreamWritable(dest) && !binding.WritableStreamCloseQueuedOrInFlight(dest); } function writeQueuedChunks() { if (lastWrite) { return thenPromise(lastWrite, () => undefined, () => undefined); } return createResolvedPromise(undefined); } return promise; } function AcquireReadableStreamDefaultReader(stream) { return new ReadableStreamDefaultReader(stream); } function CreateReadableStream(startAlgorithm, pullAlgorithm, cancelAlgorithm, highWaterMark, sizeAlgorithm, enableBlinkLockNotifications) { if (highWaterMark === undefined) { highWaterMark = 1; } if (sizeAlgorithm === undefined) { sizeAlgorithm = () => 1; } const stream = ObjectCreate(ReadableStream_prototype); InitializeReadableStream(stream); const controller = ObjectCreate(ReadableStreamDefaultController_prototype); SetUpReadableStreamDefaultController( stream, controller, startAlgorithm, pullAlgorithm, cancelAlgorithm, highWaterMark, sizeAlgorithm, enableBlinkLockNotifications); return stream; } function InitializeReadableStream(stream) { stream[_readableStreamBits] = 0b0; ReadableStreamSetState(stream, STATE_READABLE); stream[_reader] = undefined; stream[_storedError] = undefined; } function IsReadableStream(x) { return hasOwnPropertyNoThrow(x, _controller); } function IsReadableStreamDisturbed(stream) { return stream[_readableStreamBits] & DISTURBED; } function IsReadableStreamLocked(stream) { return stream[_reader] !== undefined; } function ReadableStreamTee(stream) { const reader = AcquireReadableStreamDefaultReader(stream); let closedOrErrored = false; let canceled1 = false; let canceled2 = false; let reason1; let reason2; const cancelPromise = createPromise(); function pullAlgorithm() { return thenPromise( ReadableStreamDefaultReaderRead(reader), ({value, done}) => { if (done && !closedOrErrored) { if (!canceled1) { ReadableStreamDefaultControllerClose(branch1controller); } if (!canceled2) { ReadableStreamDefaultControllerClose(branch2controller); } closedOrErrored = true; } if (closedOrErrored) { return; } if (!canceled1) { ReadableStreamDefaultControllerEnqueue(branch1controller, value); } if (!canceled2) { ReadableStreamDefaultControllerEnqueue(branch2controller, value); } }); } function cancel1Algorithm(reason) { canceled1 = true; reason1 = reason; if (canceled2) { const cancelResult = ReadableStreamCancel(stream, [reason1, reason2]); resolvePromise(cancelPromise, cancelResult); } return cancelPromise; } function cancel2Algorithm(reason) { canceled2 = true; reason2 = reason; if (canceled1) { const cancelResult = ReadableStreamCancel(stream, [reason1, reason2]); resolvePromise(cancelPromise, cancelResult); } return cancelPromise; } const startAlgorithm = () => undefined; const branch1Stream = CreateReadableStream( startAlgorithm, pullAlgorithm, cancel1Algorithm, undefined, undefined, false); const branch2Stream = CreateReadableStream( startAlgorithm, pullAlgorithm, cancel2Algorithm, undefined, undefined, false); const branch1controller = branch1Stream[_controller]; const branch2controller = branch2Stream[_controller]; thenPromise(reader[_closedPromise], undefined, r => { if (closedOrErrored === true) { return; } ReadableStreamDefaultControllerError(branch1controller, r); ReadableStreamDefaultControllerError(branch2controller, r); closedOrErrored = true; }); return [branch1Stream, branch2Stream]; } function ReadableStreamAddReadRequest(stream, forAuthorCode) { const promise = createPromise(); stream[_reader][_readRequests].push({promise, forAuthorCode}); return promise; } function ReadableStreamCancel(stream, reason) { stream[_readableStreamBits] |= DISTURBED; const state = ReadableStreamGetState(stream); if (state === STATE_CLOSED) { return createResolvedPromise(undefined); } if (state === STATE_ERRORED) { return createRejectedPromise(stream[_storedError]); } ReadableStreamClose(stream); const sourceCancelPromise = ReadableStreamDefaultControllerCancel(stream[_controller], reason); return thenPromise(sourceCancelPromise, () => undefined); } function ReadableStreamClose(stream) { ReadableStreamSetState(stream, STATE_CLOSED); const reader = stream[_reader]; if (reader === undefined) { return; } if (IsReadableStreamDefaultReader(reader) === true) { reader[_readRequests].forEach( request => resolvePromise( request.promise, ReadableStreamCreateReadResult(undefined, true, request.forAuthorCode))); reader[_readRequests] = new binding.SimpleQueue(); } resolvePromise(reader[_closedPromise], undefined); } function ReadableStreamCreateReadResult(value, done, forAuthorCode) { if (forAuthorCode) { return {value, done}; } const obj = ObjectCreate(null); obj.value = value; obj.done = done; return obj; } function ReadableStreamError(stream, e) { ReadableStreamSetState(stream, STATE_ERRORED); stream[_storedError] = e; const reader = stream[_reader]; if (reader === undefined) { return; } if (IsReadableStreamDefaultReader(reader) === true) { reader[_readRequests].forEach(request => rejectPromise(request.promise, e)); reader[_readRequests] = new binding.SimpleQueue(); } rejectPromise(reader[_closedPromise], e); markPromiseAsHandled(reader[_closedPromise]); } function ReadableStreamFulfillReadRequest(stream, chunk, done) { const readRequest = stream[_reader][_readRequests].shift(); resolvePromise(readRequest.promise, ReadableStreamCreateReadResult(chunk, done, readRequest.forAuthorCode)); } function ReadableStreamGetNumReadRequests(stream) { const reader = stream[_reader]; const readRequests = reader[_readRequests]; return readRequests.length; } class ReadableStreamDefaultReader { constructor(stream) { if (stream[internalReadableStreamSymbol] !== undefined) { stream = stream[internalReadableStreamSymbol]; } if (IsReadableStream(stream) === false) { throw new TypeError(errReaderConstructorBadArgument); } if (IsReadableStreamLocked(stream) === true) { throw new TypeError(errReaderConstructorStreamAlreadyLocked); } ReadableStreamReaderGenericInitialize(this, stream); this[_readRequests] = new binding.SimpleQueue(); } get closed() { if (IsReadableStreamDefaultReader(this) === false) { return createRejectedPromise( new TypeError(streamErrors.illegalInvocation)); } return this[_closedPromise]; } cancel(reason) { if (IsReadableStreamDefaultReader(this) === false) { return createRejectedPromise( new TypeError(streamErrors.illegalInvocation)); } if (this[_ownerReadableStream] === undefined) { return createRejectedPromise(new TypeError(errCancelReleasedReader)); } return ReadableStreamReaderGenericCancel(this, reason); } read() { if (IsReadableStreamDefaultReader(this) === false) { return createRejectedPromise( new TypeError(streamErrors.illegalInvocation)); } if (this[_ownerReadableStream] === undefined) { return createRejectedPromise(new TypeError(errReadReleasedReader)); } return ReadableStreamDefaultReaderRead(this, true); } releaseLock() { if (IsReadableStreamDefaultReader(this) === false) { throw new TypeError(streamErrors.illegalInvocation); } if (this[_ownerReadableStream] === undefined) { return; } if (this[_readRequests].length > 0) { throw new TypeError(errReleaseReaderWithPendingRead); } ReadableStreamReaderGenericRelease(this); } } function IsReadableStreamDefaultReader(x) { return hasOwnPropertyNoThrow(x, _readRequests); } function ReadableStreamReaderGenericCancel(reader, reason) { return ReadableStreamCancel(reader[_ownerReadableStream], reason); } function ReadableStreamReaderGenericInitialize(reader, stream) { const controller = stream[_controller]; if (controller[_readableStreamDefaultControllerBits] & BLINK_LOCK_NOTIFICATIONS) { const lockNotifyTarget = controller[_lockNotifyTarget]; callFunction(lockNotifyTarget.notifyLockAcquired, lockNotifyTarget); } reader[_ownerReadableStream] = stream; stream[_reader] = reader; switch (ReadableStreamGetState(stream)) { case STATE_READABLE: reader[_closedPromise] = createPromise(); break; case STATE_CLOSED: reader[_closedPromise] = createResolvedPromise(undefined); break; case STATE_ERRORED: reader[_closedPromise] = createRejectedPromise(stream[_storedError]); markPromiseAsHandled(reader[_closedPromise]); break; } } function ReadableStreamReaderGenericRelease(reader) { const controller = reader[_ownerReadableStream][_controller]; if (controller[_readableStreamDefaultControllerBits] & BLINK_LOCK_NOTIFICATIONS) { const lockNotifyTarget = controller[_lockNotifyTarget]; callFunction(lockNotifyTarget.notifyLockReleased, lockNotifyTarget); } if (ReadableStreamGetState(reader[_ownerReadableStream]) === STATE_READABLE) { rejectPromise( reader[_closedPromise], new TypeError(errReleasedReaderClosedPromise)); } else { reader[_closedPromise] = createRejectedPromise(new TypeError(errReleasedReaderClosedPromise)); } markPromiseAsHandled(reader[_closedPromise]); reader[_ownerReadableStream][_reader] = undefined; reader[_ownerReadableStream] = undefined; } function ReadableStreamDefaultReaderRead(reader, forAuthorCode = false) { const stream = reader[_ownerReadableStream]; stream[_readableStreamBits] |= DISTURBED; switch (ReadableStreamGetState(stream)) { case STATE_CLOSED: return createResolvedPromise( ReadableStreamCreateReadResult(undefined, true, forAuthorCode)); case STATE_ERRORED: return createRejectedPromise(stream[_storedError]); default: return ReadableStreamDefaultControllerPull(stream[_controller], forAuthorCode); } } class ReadableStreamDefaultController { constructor() { throw new TypeError(streamErrors.illegalConstructor); } get desiredSize() { if (IsReadableStreamDefaultController(this) === false) { throw new TypeError(streamErrors.illegalInvocation); } return ReadableStreamDefaultControllerGetDesiredSize(this); } close() { if (IsReadableStreamDefaultController(this) === false) { throw new TypeError(streamErrors.illegalInvocation); } if (ReadableStreamDefaultControllerCanCloseOrEnqueue(this) === false) { let errorDescription; if (this[_readableStreamDefaultControllerBits] & CLOSE_REQUESTED) { errorDescription = errCloseCloseRequestedStream; } else { const stream = this[_controlledReadableStream]; switch (ReadableStreamGetState(stream)) { case STATE_ERRORED: errorDescription = errCloseErroredStream; break; case STATE_CLOSED: errorDescription = errCloseClosedStream; break; } } throw new TypeError(errorDescription); } return ReadableStreamDefaultControllerClose(this); } enqueue(chunk) { if (IsReadableStreamDefaultController(this) === false) { throw new TypeError(streamErrors.illegalInvocation); } if (!ReadableStreamDefaultControllerCanCloseOrEnqueue(this)) { const stream = this[_controlledReadableStream]; throw getReadableStreamEnqueueError(stream, this); } return ReadableStreamDefaultControllerEnqueue(this, chunk); } error(e) { if (IsReadableStreamDefaultController(this) === false) { throw new TypeError(streamErrors.illegalInvocation); } return ReadableStreamDefaultControllerError(this, e); } } const ReadableStreamDefaultController_prototype = ReadableStreamDefaultController.prototype; function ReadableStreamDefaultControllerCancel(controller, reason) { controller[_queue] = new binding.SimpleQueue(); return controller[_cancelAlgorithm](reason); } function ReadableStreamDefaultControllerPull(controller, forAuthorCode) { const stream = controller[_controlledReadableStream]; if (controller[_queue].length > 0) { const chunk = DequeueValue(controller); if ((controller[_readableStreamDefaultControllerBits] & CLOSE_REQUESTED) && controller[_queue].length === 0) { ReadableStreamClose(stream); } else { ReadableStreamDefaultControllerCallPullIfNeeded(controller); } return createResolvedPromise( ReadableStreamCreateReadResult(chunk, false, forAuthorCode)); } const pendingPromise = ReadableStreamAddReadRequest(stream, forAuthorCode); ReadableStreamDefaultControllerCallPullIfNeeded(controller); return pendingPromise; } function IsReadableStreamDefaultController(x) { return hasOwnPropertyNoThrow(x, _controlledReadableStream); } function ReadableStreamDefaultControllerCallPullIfNeeded(controller) { const shouldPull = ReadableStreamDefaultControllerShouldCallPull(controller); if (shouldPull === false) { return; } if (controller[_readableStreamDefaultControllerBits] & PULLING) { controller[_readableStreamDefaultControllerBits] |= PULL_AGAIN; return; } controller[_readableStreamDefaultControllerBits] |= PULLING; thenPromise( controller[_pullAlgorithm](), () => { controller[_readableStreamDefaultControllerBits] &= ~PULLING; if (controller[_readableStreamDefaultControllerBits] & PULL_AGAIN) { controller[_readableStreamDefaultControllerBits] &= ~PULL_AGAIN; ReadableStreamDefaultControllerCallPullIfNeeded(controller); } }, e => { ReadableStreamDefaultControllerError(controller, e); }); } function ReadableStreamDefaultControllerShouldCallPull(controller) { if (!ReadableStreamDefaultControllerCanCloseOrEnqueue(controller)) { return false; } if (!(controller[_readableStreamDefaultControllerBits] & STARTED)) { return false; } const stream = controller[_controlledReadableStream]; if (IsReadableStreamLocked(stream) === true && ReadableStreamGetNumReadRequests(stream) > 0) { return true; } const desiredSize = ReadableStreamDefaultControllerGetDesiredSize(controller); return desiredSize > 0; } function ReadableStreamDefaultControllerClose(controller) { controller[_readableStreamDefaultControllerBits] |= CLOSE_REQUESTED; if (controller[_queue].length === 0) { ReadableStreamClose(controller[_controlledReadableStream]); } } function ReadableStreamDefaultControllerEnqueue(controller, chunk) { const stream = controller[_controlledReadableStream]; if (IsReadableStreamLocked(stream) === true && ReadableStreamGetNumReadRequests(stream) > 0) { ReadableStreamFulfillReadRequest(stream, chunk, false); } else { let chunkSize; try { chunkSize = callFunction(controller[_strategySizeAlgorithm], undefined, chunk); } catch (chunkSizeE) { ReadableStreamDefaultControllerError(controller, chunkSizeE); throw chunkSizeE; } try { EnqueueValueWithSize(controller, chunk, chunkSize); } catch (enqueueE) { ReadableStreamDefaultControllerError(controller, enqueueE); throw enqueueE; } } ReadableStreamDefaultControllerCallPullIfNeeded(controller); } function ReadableStreamDefaultControllerError(controller, e) { const stream = controller[_controlledReadableStream]; if (ReadableStreamGetState(stream) !== STATE_READABLE) { return; } controller[_queue] = new binding.SimpleQueue(); ReadableStreamError(stream, e); } function ReadableStreamDefaultControllerGetDesiredSize(controller) { switch (ReadableStreamGetState(controller[_controlledReadableStream])) { case STATE_ERRORED: return null; case STATE_CLOSED: return 0; default: return controller[_strategyHWM] - controller[_queueTotalSize]; } } function ReadableStreamDefaultControllerHasBackpressure(controller) { return !ReadableStreamDefaultControllerShouldCallPull(controller); } function ReadableStreamDefaultControllerCanCloseOrEnqueue(controller) { if (controller[_readableStreamDefaultControllerBits] & CLOSE_REQUESTED) { return false; } const state = ReadableStreamGetState(controller[_controlledReadableStream]); return state === STATE_READABLE; } function SetUpReadableStreamDefaultController( stream, controller, startAlgorithm, pullAlgorithm, cancelAlgorithm, highWaterMark, sizeAlgorithm, enableBlinkLockNotifications) { controller[_controlledReadableStream] = stream; controller[_queue] = new binding.SimpleQueue(); controller[_queueTotalSize] = 0; controller[_readableStreamDefaultControllerBits] = enableBlinkLockNotifications ? BLINK_LOCK_NOTIFICATIONS : 0b0; controller[_strategySizeAlgorithm] = sizeAlgorithm; controller[_strategyHWM] = highWaterMark; controller[_pullAlgorithm] = pullAlgorithm; controller[_cancelAlgorithm] = cancelAlgorithm; stream[_controller] = controller; thenPromise(createResolvedPromise(startAlgorithm()), () => { controller[_readableStreamDefaultControllerBits] |= STARTED; ReadableStreamDefaultControllerCallPullIfNeeded(controller); }, r => ReadableStreamDefaultControllerError(controller, r)); } function SetUpReadableStreamDefaultControllerFromUnderlyingSource( stream, underlyingSource, highWaterMark, sizeAlgorithm, enableBlinkLockNotifications) { const controller = ObjectCreate(ReadableStreamDefaultController_prototype); const startAlgorithm = () => CallOrNoop1(underlyingSource, 'start', controller, 'underlyingSource.start'); const pullAlgorithm = CreateAlgorithmFromUnderlyingMethodPassingController( underlyingSource, 'pull', 0, controller, 'underlyingSource.pull'); const cancelAlgorithm = CreateAlgorithmFromUnderlyingMethod( underlyingSource, 'cancel', 1, 'underlyingSource.cancel'); if (enableBlinkLockNotifications) { controller[_lockNotifyTarget] = underlyingSource; } SetUpReadableStreamDefaultController( stream, controller, startAlgorithm, pullAlgorithm, cancelAlgorithm, highWaterMark, sizeAlgorithm, enableBlinkLockNotifications); } function ReadableStreamSerialize(readable, port) { if (IsReadableStreamLocked(readable)) { throw new TypeError(streamErrors.cannotTransferLockedStream); } if (!binding.MessagePort_postMessage) { throw new TypeError(streamErrors.cannotTransferContext); } const writable = CreateCrossRealmTransformWritable(port); const promise = ReadableStreamPipeTo(readable, writable, false, false, false); markPromiseAsHandled(promise); } function ReadableStreamDeserialize(port) { return CreateCrossRealmTransformReadable(port); } function ReadableStreamGetState(stream) { return (stream[_readableStreamBits] & STATE_MASK) >> STATE_BITS_OFFSET; } function ReadableStreamSetState(stream, state) { stream[_readableStreamBits] = (stream[_readableStreamBits] & ~STATE_MASK) | (state << STATE_BITS_OFFSET); } function IsReadableStreamReadable(stream) { return ReadableStreamGetState(stream) === STATE_READABLE; } function IsReadableStreamClosed(stream) { return ReadableStreamGetState(stream) === STATE_CLOSED; } function IsReadableStreamErrored(stream) { return ReadableStreamGetState(stream) === STATE_ERRORED; } function getReadableStreamEnqueueError(stream, controller) { if (controller[_readableStreamDefaultControllerBits] & CLOSE_REQUESTED) { return new TypeError(errEnqueueCloseRequestedStream); } const state = ReadableStreamGetState(stream); if (state === STATE_ERRORED) { return new TypeError(errEnqueueErroredStream); } return new TypeError(errEnqueueClosedStream); } function getReadableStreamController(stream) { return stream[_controller]; } function getReadableStreamStoredError(stream) { return stream[_storedError]; } function createReadableStream(underlyingSource, strategy) { return new ReadableStream(underlyingSource, strategy); } function createReadableStreamWithExternalController( underlyingSource, strategy) { return new ReadableStream( underlyingSource, strategy, createWithExternalControllerSentinel); } Object.assign(binding, { AcquireReadableStreamDefaultReader, createReadableStream, createReadableStreamWithExternalController, IsReadableStream, IsReadableStreamDisturbed, IsReadableStreamLocked, IsReadableStreamReadable, IsReadableStreamClosed, IsReadableStreamErrored, IsReadableStreamDefaultReader, ReadableStreamDefaultReaderRead, ReadableStreamCancel, ReadableStreamTee, ReadableStreamPipeTo, ReadableStreamSerialize, ReadableStreamDeserialize, internalReadableStreamSymbol, ReadableStreamDefaultControllerClose, ReadableStreamDefaultControllerGetDesiredSize, ReadableStreamDefaultControllerEnqueue, ReadableStreamDefaultControllerError, CreateReadableStream, ReadableStreamDefaultControllerCanCloseOrEnqueue, ReadableStreamDefaultControllerHasBackpressure, getReadableStreamEnqueueError, getReadableStreamController, getReadableStreamStoredError, }); }); 8WritableStreamº£ (function(global, binding, v8) { 'use strict'; const _abortAlgorithm = v8.createPrivateSymbol('[[abortAlgorithm]]'); const _closeAlgorithm = v8.createPrivateSymbol('[[closeAlgorithm]]'); const _closeRequest = v8.createPrivateSymbol('[[closeRequest]]'); const _inFlightWriteRequest = v8.createPrivateSymbol('[[inFlightWriteRequest]]'); const _inFlightCloseRequest = v8.createPrivateSymbol('[[inFlightCloseRequest]]'); const _pendingAbortRequest = v8.createPrivateSymbol('[[pendingAbortRequest]]'); const _stateAndFlags = v8.createPrivateSymbol('[[state]] and flags'); const _storedError = v8.createPrivateSymbol('[[storedError]]'); const _writableStreamController = v8.createPrivateSymbol('[[writableStreamController]]'); const _writer = v8.createPrivateSymbol('[[writer]]'); const _writeRequests = v8.createPrivateSymbol('[[writeRequests]]'); const _closedPromise = v8.createPrivateSymbol('[[closedPromise]]'); const _ownerWritableStream = v8.createPrivateSymbol('[[ownerWritableStream]]'); const _readyPromise = v8.createPrivateSymbol('[[readyPromise]]'); const _controlledWritableStream = v8.createPrivateSymbol('[[controlledWritableStream]]'); const _started = v8.createPrivateSymbol('[[started]]'); const _strategyHWM = v8.createPrivateSymbol('[[strategyHWM]]'); const _strategySizeAlgorithm = v8.createPrivateSymbol('[[strategySizeAlgorithm]]'); const _writeAlgorithm = v8.createPrivateSymbol('[[writeAlgorithm]]'); const internalWritableStreamSymbol = v8.createPrivateSymbol( 'internal WritableStream in exposed WritableStream interface'); const WRITABLE = 0; const CLOSED = 1; const ERRORING = 2; const ERRORED = 3; const STATE_MASK = 0xF; const BACKPRESSURE_FLAG = 0x10; const ObjectCreate = global.Object.create; const Function_call = v8.uncurryThis(global.Function.prototype.call); const TypeError = global.TypeError; const RangeError = global.RangeError; const Boolean = global.Boolean; const Promise = global.Promise; const thenPromise = v8.uncurryThis(Promise.prototype.then); const { _queue, _queueTotalSize, createPromise, createRejectedPromise, createResolvedPromise, hasOwnPropertyNoThrow, rejectPromise, resolvePromise, markPromiseAsHandled, promiseState, CreateAlgorithmFromUnderlyingMethod, CreateAlgorithmFromUnderlyingMethodPassingController, DequeueValue, EnqueueValueWithSize, MakeSizeAlgorithmFromSizeFunction, PeekQueueValue, ResetQueue, ValidateAndNormalizeHighWaterMark, CreateCrossRealmTransformReadable, CreateCrossRealmTransformWritable, CallOrNoop1, } = binding.streamOperations; const streamErrors = binding.streamErrors; const errWriterLockReleasedPrefix = 'This writable stream writer has been released and cannot be '; const errCloseCloseRequestedStream = 'Cannot close a writable stream that ' + 'has already been requested to be closed'; const templateErrorCannotActionOnStateStream = (action, state) => `Cannot ${action} a ${state} writable stream`; const errReleasedWriterClosedPromise = 'This writable stream writer has ' + 'been released and cannot be used to monitor the stream\'s state'; const verbUsedToGetTheDesiredSize = 'used to get the desiredSize'; const verbAborted = 'aborted'; const verbClosed = 'closed'; const verbWrittenTo = 'written to'; function createWriterLockReleasedError(verb) { return new TypeError(errWriterLockReleasedPrefix + verb); } const stateNames = { [CLOSED]: 'closed', [ERRORED]: 'errored' }; function createCannotActionOnStateStreamError(action, state) { return new TypeError( templateErrorCannotActionOnStateStream(action, stateNames[state])); } function rejectPromises(queue, e) { queue.forEach(promise => rejectPromise(promise, e)); } class WritableStream { constructor(underlyingSink = {}, strategy = {}) { InitializeWritableStream(this); const size = strategy.size; let highWaterMark = strategy.highWaterMark; const type = underlyingSink.type; if (type !== undefined) { throw new RangeError(streamErrors.invalidType); } const sizeAlgorithm = MakeSizeAlgorithmFromSizeFunction(size); if (highWaterMark === undefined) { highWaterMark = 1; } highWaterMark = ValidateAndNormalizeHighWaterMark(highWaterMark); SetUpWritableStreamDefaultControllerFromUnderlyingSink( this, underlyingSink, highWaterMark, sizeAlgorithm); } } const WritableStream_prototype = WritableStream.prototype; function createWritableStream(underlyingSink, strategy) { return new WritableStream(underlyingSink, strategy); } function AcquireWritableStreamDefaultWriter(stream) { return new WritableStreamDefaultWriter(stream); } function CreateWritableStream( startAlgorithm, writeAlgorithm, closeAlgorithm, abortAlgorithm, highWaterMark, sizeAlgorithm) { if (highWaterMark === undefined) { highWaterMark = 1; } if (sizeAlgorithm === undefined) { sizeAlgorithm = () => 1; } const stream = ObjectCreate(WritableStream_prototype); InitializeWritableStream(stream); const controller = ObjectCreate(WritableStreamDefaultController_prototype); SetUpWritableStreamDefaultController( stream, controller, startAlgorithm, writeAlgorithm, closeAlgorithm, abortAlgorithm, highWaterMark, sizeAlgorithm); return stream; } function InitializeWritableStream(stream) { stream[_stateAndFlags] = WRITABLE; stream[_storedError] = undefined; stream[_writer] = undefined; stream[_writableStreamController] = undefined; stream[_inFlightWriteRequest] = undefined; stream[_closeRequest] = undefined; stream[_inFlightCloseRequest] = undefined; stream[_pendingAbortRequest] = undefined; stream[_writeRequests] = new binding.SimpleQueue(); } function IsWritableStream(x) { return hasOwnPropertyNoThrow(x, _writableStreamController); } function IsWritableStreamLocked(stream) { return stream[_writer] !== undefined; } function WritableStreamAbort(stream, reason) { const state = stream[_stateAndFlags] & STATE_MASK; if (state === CLOSED || state === ERRORED) { return createResolvedPromise(undefined); } if (stream[_pendingAbortRequest] !== undefined) { return stream[_pendingAbortRequest].promise; } const wasAlreadyErroring = state === ERRORING; if (wasAlreadyErroring) { reason = undefined; } const promise = createPromise(); stream[_pendingAbortRequest] = {promise, reason, wasAlreadyErroring}; if (!wasAlreadyErroring) { WritableStreamStartErroring(stream, reason); } return promise; } function WritableStreamAddWriteRequest(stream) { const promise = createPromise(); stream[_writeRequests].push(promise); return promise; } function WritableStreamDealWithRejection(stream, error) { const state = stream[_stateAndFlags] & STATE_MASK; if (state === WRITABLE) { WritableStreamStartErroring(stream, error); return; } WritableStreamFinishErroring(stream); } function WritableStreamStartErroring(stream, reason) { const controller = stream[_writableStreamController]; stream[_stateAndFlags] = (stream[_stateAndFlags] & ~STATE_MASK) | ERRORING; stream[_storedError] = reason; const writer = stream[_writer]; if (writer !== undefined) { WritableStreamDefaultWriterEnsureReadyPromiseRejected(writer, reason); } if (!WritableStreamHasOperationMarkedInFlight(stream) && controller[_started]) { WritableStreamFinishErroring(stream); } } function WritableStreamFinishErroring(stream) { stream[_stateAndFlags] = (stream[_stateAndFlags] & ~STATE_MASK) | ERRORED; WritableStreamDefaultControllerErrorSteps( stream[_writableStreamController]); const storedError = stream[_storedError]; rejectPromises(stream[_writeRequests], storedError); stream[_writeRequests] = new binding.SimpleQueue(); if (stream[_pendingAbortRequest] === undefined) { WritableStreamRejectCloseAndClosedPromiseIfNeeded(stream); return; } const abortRequest = stream[_pendingAbortRequest]; stream[_pendingAbortRequest] = undefined; if (abortRequest.wasAlreadyErroring === true) { rejectPromise(abortRequest.promise, storedError); WritableStreamRejectCloseAndClosedPromiseIfNeeded(stream); return; } const promise = WritableStreamDefaultControllerAbortSteps( stream[_writableStreamController], abortRequest.reason); thenPromise( promise, () => { resolvePromise(abortRequest.promise, undefined); WritableStreamRejectCloseAndClosedPromiseIfNeeded(stream); }, reason => { rejectPromise(abortRequest.promise, reason); WritableStreamRejectCloseAndClosedPromiseIfNeeded(stream); }); } function WritableStreamFinishInFlightWrite(stream) { resolvePromise(stream[_inFlightWriteRequest], undefined); stream[_inFlightWriteRequest] = undefined; } function WritableStreamFinishInFlightWriteWithError(stream, error) { rejectPromise(stream[_inFlightWriteRequest], error); stream[_inFlightWriteRequest] = undefined; WritableStreamDealWithRejection(stream, error); } function WritableStreamFinishInFlightClose(stream) { resolvePromise(stream[_inFlightCloseRequest], undefined); stream[_inFlightCloseRequest] = undefined; const state = stream[_stateAndFlags] & STATE_MASK; if (state === ERRORING) { stream[_storedError] = undefined; if (stream[_pendingAbortRequest] !== undefined) { resolvePromise(stream[_pendingAbortRequest].promise, undefined); stream[_pendingAbortRequest] = undefined; } } stream[_stateAndFlags] = (stream[_stateAndFlags] & ~STATE_MASK) | CLOSED; const writer = stream[_writer]; if (writer !== undefined) { resolvePromise(writer[_closedPromise], undefined); } } function WritableStreamFinishInFlightCloseWithError(stream, error) { rejectPromise(stream[_inFlightCloseRequest], error); stream[_inFlightCloseRequest] = undefined; if (stream[_pendingAbortRequest] !== undefined) { rejectPromise(stream[_pendingAbortRequest].promise, error); stream[_pendingAbortRequest] = undefined; } WritableStreamDealWithRejection(stream, error); } function WritableStreamCloseQueuedOrInFlight(stream) { return stream[_closeRequest] !== undefined || stream[_inFlightCloseRequest] !== undefined; } function WritableStreamHasOperationMarkedInFlight(stream) { return stream[_inFlightWriteRequest] !== undefined || stream[_inFlightCloseRequest] !== undefined; } function WritableStreamMarkCloseRequestInFlight(stream) { stream[_inFlightCloseRequest] = stream[_closeRequest]; stream[_closeRequest] = undefined; } function WritableStreamMarkFirstWriteRequestInFlight(stream) { const writeRequest = stream[_writeRequests].shift(); stream[_inFlightWriteRequest] = writeRequest; } function WritableStreamRejectCloseAndClosedPromiseIfNeeded(stream) { if (stream[_closeRequest] !== undefined) { rejectPromise(stream[_closeRequest], stream[_storedError]); stream[_closeRequest] = undefined; } const writer = stream[_writer]; if (writer !== undefined) { rejectPromise(writer[_closedPromise], stream[_storedError]); markPromiseAsHandled(writer[_closedPromise]); } } function WritableStreamUpdateBackpressure(stream, backpressure) { const writer = stream[_writer]; if (writer !== undefined && backpressure !== Boolean(stream[_stateAndFlags] & BACKPRESSURE_FLAG)) { if (backpressure) { writer[_readyPromise] = createPromise(); } else { resolvePromise(writer[_readyPromise], undefined); } } if (backpressure) { stream[_stateAndFlags] |= BACKPRESSURE_FLAG; } else { stream[_stateAndFlags] &= ~BACKPRESSURE_FLAG; } } function WritableStreamSerialize(writable, port) { if (IsWritableStreamLocked(writable)) { throw new TypeError(streamErrors.cannotTransferLockedStream); } if (!binding.MessagePort_postMessage) { throw new TypeError(streamErrors.cannotTransferContext); } const readable = CreateCrossRealmTransformReadable(port); const promise = binding.ReadableStreamPipeTo(readable, writable, false, false, false); markPromiseAsHandled(promise); } function WritableStreamDeserialize(port) { return CreateCrossRealmTransformWritable(port); } function isWritableStreamErrored(stream) { return (stream[_stateAndFlags] & STATE_MASK) === ERRORED; } function isWritableStreamClosingOrClosed(stream) { return WritableStreamCloseQueuedOrInFlight(stream) || (stream[_stateAndFlags] & STATE_MASK) === CLOSED; } function getWritableStreamStoredError(stream) { return stream[_storedError]; } function isWritableStreamWritable(stream) { return (stream[_stateAndFlags] & STATE_MASK) === WRITABLE; } function isWritableStreamErroring(stream) { return (stream[_stateAndFlags] & STATE_MASK) === ERRORING; } function getWritableStreamController(stream) { return stream[_writableStreamController]; } class WritableStreamDefaultWriter { constructor(stream) { if (stream[internalWritableStreamSymbol] !== undefined) { stream = stream[internalWritableStreamSymbol]; } if (!IsWritableStream(stream)) { throw new TypeError(streamErrors.illegalConstructor); } if (IsWritableStreamLocked(stream)) { throw new TypeError(streamErrors.illegalConstructor); } this[_ownerWritableStream] = stream; stream[_writer] = this; const state = stream[_stateAndFlags] & STATE_MASK; switch (state) { case WRITABLE: { if (!WritableStreamCloseQueuedOrInFlight(stream) && stream[_stateAndFlags] & BACKPRESSURE_FLAG) { this[_readyPromise] = createPromise(); } else { this[_readyPromise] = createResolvedPromise(undefined); } this[_closedPromise] = createPromise(); break; } case ERRORING: { this[_readyPromise] = createRejectedPromise(stream[_storedError]); markPromiseAsHandled(this[_readyPromise]); this[_closedPromise] = createPromise(); break; } case CLOSED: { this[_readyPromise] = createResolvedPromise(undefined); this[_closedPromise] = createResolvedPromise(undefined); break; } default: { const storedError = stream[_storedError]; this[_readyPromise] = createRejectedPromise(storedError); markPromiseAsHandled(this[_readyPromise]); this[_closedPromise] = createRejectedPromise(storedError); markPromiseAsHandled(this[_closedPromise]); break; } } } get closed() { if (!IsWritableStreamDefaultWriter(this)) { return createRejectedPromise( new TypeError(streamErrors.illegalInvocation)); } return this[_closedPromise]; } get desiredSize() { if (!IsWritableStreamDefaultWriter(this)) { throw new TypeError(streamErrors.illegalInvocation); } if (this[_ownerWritableStream] === undefined) { throw createWriterLockReleasedError(verbUsedToGetTheDesiredSize); } return WritableStreamDefaultWriterGetDesiredSize(this); } get ready() { if (!IsWritableStreamDefaultWriter(this)) { return createRejectedPromise( new TypeError(streamErrors.illegalInvocation)); } return this[_readyPromise]; } abort(reason) { if (!IsWritableStreamDefaultWriter(this)) { return createRejectedPromise( new TypeError(streamErrors.illegalInvocation)); } if (this[_ownerWritableStream] === undefined) { return createRejectedPromise( createWriterLockReleasedError(verbAborted)); } return WritableStreamDefaultWriterAbort(this, reason); } close() { if (!IsWritableStreamDefaultWriter(this)) { return createRejectedPromise( new TypeError(streamErrors.illegalInvocation)); } const stream = this[_ownerWritableStream]; if (stream === undefined) { return createRejectedPromise(createWriterLockReleasedError(verbClosed)); } if (WritableStreamCloseQueuedOrInFlight(stream)) { return createRejectedPromise( new TypeError(errCloseCloseRequestedStream)); } return WritableStreamDefaultWriterClose(this); } releaseLock() { if (!IsWritableStreamDefaultWriter(this)) { throw new TypeError(streamErrors.illegalInvocation); } const stream = this[_ownerWritableStream]; if (stream === undefined) { return; } WritableStreamDefaultWriterRelease(this); } write(chunk) { if (!IsWritableStreamDefaultWriter(this)) { return createRejectedPromise( new TypeError(streamErrors.illegalInvocation)); } if (this[_ownerWritableStream] === undefined) { return createRejectedPromise( createWriterLockReleasedError(verbWrittenTo)); } return WritableStreamDefaultWriterWrite(this, chunk); } } function IsWritableStreamDefaultWriter(x) { return hasOwnPropertyNoThrow(x, _ownerWritableStream); } function WritableStreamDefaultWriterAbort(writer, reason) { const stream = writer[_ownerWritableStream]; return WritableStreamAbort(stream, reason); } function WritableStreamDefaultWriterClose(writer) { const stream = writer[_ownerWritableStream]; const state = stream[_stateAndFlags] & STATE_MASK; if (state === CLOSED || state === ERRORED) { return createRejectedPromise( createCannotActionOnStateStreamError('close', state)); } const promise = createPromise(); stream[_closeRequest] = promise; if ((stream[_stateAndFlags] & BACKPRESSURE_FLAG) && state === WRITABLE) { resolvePromise(writer[_readyPromise], undefined); } WritableStreamDefaultControllerClose(stream[_writableStreamController]); return promise; } function WritableStreamDefaultWriterCloseWithErrorPropagation(writer) { const stream = writer[_ownerWritableStream]; const state = stream[_stateAndFlags] & STATE_MASK; if (WritableStreamCloseQueuedOrInFlight(stream) || state === CLOSED) { return createResolvedPromise(undefined); } if (state === ERRORED) { return createRejectedPromise(stream[_storedError]); } return WritableStreamDefaultWriterClose(writer); } function WritableStreamDefaultWriterEnsureClosedPromiseRejected( writer, error) { if (promiseState(writer[_closedPromise]) === v8.kPROMISE_PENDING) { rejectPromise(writer[_closedPromise], error); } else { writer[_closedPromise] = createRejectedPromise(error); } markPromiseAsHandled(writer[_closedPromise]); } function WritableStreamDefaultWriterEnsureReadyPromiseRejected( writer, error) { if (promiseState(writer[_readyPromise]) === v8.kPROMISE_PENDING) { rejectPromise(writer[_readyPromise], error); } else { writer[_readyPromise] = createRejectedPromise(error); } markPromiseAsHandled(writer[_readyPromise]); } function WritableStreamDefaultWriterGetDesiredSize(writer) { const stream = writer[_ownerWritableStream]; const state = stream[_stateAndFlags] & STATE_MASK; if (state === ERRORED || state === ERRORING) { return null; } if (state === CLOSED) { return 0; } return WritableStreamDefaultControllerGetDesiredSize( stream[_writableStreamController]); } function WritableStreamDefaultWriterRelease(writer) { const stream = writer[_ownerWritableStream]; const releasedError = new TypeError(errReleasedWriterClosedPromise); WritableStreamDefaultWriterEnsureReadyPromiseRejected( writer, releasedError); WritableStreamDefaultWriterEnsureClosedPromiseRejected( writer, releasedError); stream[_writer] = undefined; writer[_ownerWritableStream] = undefined; } function WritableStreamDefaultWriterWrite(writer, chunk) { const stream = writer[_ownerWritableStream]; const controller = stream[_writableStreamController]; const chunkSize = WritableStreamDefaultControllerGetChunkSize(controller, chunk); if (stream !== writer[_ownerWritableStream]) { return createRejectedPromise( createWriterLockReleasedError(verbWrittenTo)); } const state = stream[_stateAndFlags] & STATE_MASK; if (state === ERRORED) { return createRejectedPromise(stream[_storedError]); } if (WritableStreamCloseQueuedOrInFlight(stream)) { return createRejectedPromise(new TypeError( templateErrorCannotActionOnStateStream('write to', 'closing'))); } if (state === CLOSED) { return createRejectedPromise( createCannotActionOnStateStreamError('write to', CLOSED)); } if (state === ERRORING) { return createRejectedPromise(stream[_storedError]); } const promise = WritableStreamAddWriteRequest(stream); WritableStreamDefaultControllerWrite(controller, chunk, chunkSize); return promise; } function getWritableStreamDefaultWriterClosedPromise(writer) { return writer[_closedPromise]; } function getWritableStreamDefaultWriterReadyPromise(writer) { return writer[_readyPromise]; } class WritableStreamDefaultController { constructor() { throw new TypeError(streamErrors.illegalConstructor); } error(e) { if (!IsWritableStreamDefaultController(this)) { throw new TypeError(streamErrors.illegalInvocation); } const state = this[_controlledWritableStream][_stateAndFlags] & STATE_MASK; if (state !== WRITABLE) { return; } WritableStreamDefaultControllerError(this, e); } } const WritableStreamDefaultController_prototype = WritableStreamDefaultController.prototype; function WritableStreamDefaultControllerAbortSteps(controller, reason) { const result = controller[_abortAlgorithm](reason); WritableStreamDefaultControllerClearAlgorithms(controller); return result; } function WritableStreamDefaultControllerErrorSteps(controller) { ResetQueue(controller); } function IsWritableStreamDefaultController(x) { return hasOwnPropertyNoThrow(x, _controlledWritableStream); } function SetUpWritableStreamDefaultController( stream, controller, startAlgorithm, writeAlgorithm, closeAlgorithm, abortAlgorithm, highWaterMark, sizeAlgorithm) { controller[_controlledWritableStream] = stream; stream[_writableStreamController] = controller; controller[_queue] = undefined; controller[_queueTotalSize] = undefined; ResetQueue(controller); controller[_started] = false; controller[_strategySizeAlgorithm] = sizeAlgorithm; controller[_strategyHWM] = highWaterMark; controller[_writeAlgorithm] = writeAlgorithm; controller[_closeAlgorithm] = closeAlgorithm; controller[_abortAlgorithm] = abortAlgorithm; const backpressure = WritableStreamDefaultControllerGetBackpressure(controller); WritableStreamUpdateBackpressure(stream, backpressure); const startResult = startAlgorithm(); const startPromise = createResolvedPromise(startResult); thenPromise( startPromise, () => { controller[_started] = true; WritableStreamDefaultControllerAdvanceQueueIfNeeded(controller); }, r => { controller[_started] = true; WritableStreamDealWithRejection(stream, r); }); } function SetUpWritableStreamDefaultControllerFromUnderlyingSink( stream, underlyingSink, highWaterMark, sizeAlgorithm) { const controller = ObjectCreate(WritableStreamDefaultController_prototype); const startAlgorithm = () => CallOrNoop1(underlyingSink, 'start', controller, 'underlyingSink.start'); const writeAlgorithm = CreateAlgorithmFromUnderlyingMethodPassingController( underlyingSink, 'write', 1, controller, 'underlyingSink.write'); const closeAlgorithm = CreateAlgorithmFromUnderlyingMethod( underlyingSink, 'close', 0, 'underlyingSink.close'); const abortAlgorithm = CreateAlgorithmFromUnderlyingMethod( underlyingSink, 'abort', 1, 'underlyingSink.abort'); SetUpWritableStreamDefaultController(stream, controller, startAlgorithm, writeAlgorithm, closeAlgorithm, abortAlgorithm, highWaterMark, sizeAlgorithm); } function WritableStreamDefaultControllerClearAlgorithms(controller) { controller[_writeAlgorithm] = undefined; controller[_closeAlgorithm] = undefined; controller[_abortAlgorithm] = undefined; } function WritableStreamDefaultControllerClose(controller) { EnqueueValueWithSize(controller, 'close', 0); WritableStreamDefaultControllerAdvanceQueueIfNeeded(controller); } function WritableStreamDefaultControllerGetChunkSize(controller, chunk) { try { return Function_call(controller[_strategySizeAlgorithm], undefined, chunk); } catch (e) { WritableStreamDefaultControllerErrorIfNeeded(controller, e); return 1; } } function WritableStreamDefaultControllerGetDesiredSize(controller) { return controller[_strategyHWM] - controller[_queueTotalSize]; } function WritableStreamDefaultControllerWrite(controller, chunk, chunkSize) { const writeRecord = {chunk}; try { EnqueueValueWithSize(controller, writeRecord, chunkSize); } catch (e) { WritableStreamDefaultControllerErrorIfNeeded(controller, e); return; } const stream = controller[_controlledWritableStream]; if (!WritableStreamCloseQueuedOrInFlight(stream) && (stream[_stateAndFlags] & STATE_MASK) === WRITABLE) { const backpressure = WritableStreamDefaultControllerGetBackpressure(controller); WritableStreamUpdateBackpressure(stream, backpressure); } WritableStreamDefaultControllerAdvanceQueueIfNeeded(controller); } function WritableStreamDefaultControllerAdvanceQueueIfNeeded(controller) { const stream = controller[_controlledWritableStream]; if (!controller[_started]) { return; } if (stream[_inFlightWriteRequest] !== undefined) { return; } const state = stream[_stateAndFlags] & STATE_MASK; if (state === CLOSED || state === ERRORED) { return; } if (state === ERRORING) { WritableStreamFinishErroring(stream); return; } if (controller[_queue].length === 0) { return; } const writeRecord = PeekQueueValue(controller); if (writeRecord === 'close') { WritableStreamDefaultControllerProcessClose(controller); } else { WritableStreamDefaultControllerProcessWrite( controller, writeRecord.chunk); } } function WritableStreamDefaultControllerErrorIfNeeded(controller, error) { const state = controller[_controlledWritableStream][_stateAndFlags] & STATE_MASK; if (state === WRITABLE) { WritableStreamDefaultControllerError(controller, error); } } function WritableStreamDefaultControllerProcessClose(controller) { const stream = controller[_controlledWritableStream]; WritableStreamMarkCloseRequestInFlight(stream); DequeueValue(controller); const sinkClosePromise = controller[_closeAlgorithm](); WritableStreamDefaultControllerClearAlgorithms(controller); thenPromise( sinkClosePromise, () => WritableStreamFinishInFlightClose(stream), reason => WritableStreamFinishInFlightCloseWithError(stream, reason)); } function WritableStreamDefaultControllerProcessWrite(controller, chunk) { const stream = controller[_controlledWritableStream]; WritableStreamMarkFirstWriteRequestInFlight(stream); const sinkWritePromise = controller[_writeAlgorithm](chunk); thenPromise( sinkWritePromise, () => { WritableStreamFinishInFlightWrite(stream); const state = stream[_stateAndFlags] & STATE_MASK; DequeueValue(controller); if (!WritableStreamCloseQueuedOrInFlight(stream) && state === WRITABLE) { const backpressure = WritableStreamDefaultControllerGetBackpressure(controller); WritableStreamUpdateBackpressure(stream, backpressure); } WritableStreamDefaultControllerAdvanceQueueIfNeeded(controller); }, reason => { const state = stream[_stateAndFlags] & STATE_MASK; if (state === WRITABLE) { WritableStreamDefaultControllerClearAlgorithms(controller); } WritableStreamFinishInFlightWriteWithError(stream, reason); }); } function WritableStreamDefaultControllerGetBackpressure(controller) { const desiredSize = WritableStreamDefaultControllerGetDesiredSize(controller); return desiredSize <= 0; } function WritableStreamDefaultControllerError(controller, error) { const stream = controller[_controlledWritableStream]; WritableStreamDefaultControllerClearAlgorithms(controller); WritableStreamStartErroring(stream, error); } Object.assign(binding, { AcquireWritableStreamDefaultWriter, IsWritableStream, isWritableStreamClosingOrClosed, isWritableStreamErrored, isWritableStreamWritable, IsWritableStreamLocked, WritableStreamAbort, WritableStreamCloseQueuedOrInFlight, WritableStreamDefaultWriterCloseWithErrorPropagation, getWritableStreamDefaultWriterClosedPromise, WritableStreamDefaultWriterGetDesiredSize, getWritableStreamDefaultWriterReadyPromise, WritableStreamDefaultWriterRelease, WritableStreamDefaultWriterWrite, getWritableStreamStoredError, createWritableStream, internalWritableStreamSymbol, WritableStreamSerialize, WritableStreamDeserialize, CreateWritableStream, WritableStream, WritableStreamDefaultControllerErrorIfNeeded, isWritableStreamErroring, getWritableStreamController, WritableStreamDefaultControllerClose, }); }); 1; } if (readableHighWaterMark === undefined) { readableHighWaterMark = 0; } if (readableSizeAlgorithm === undefined) { readableSizeAlgorithm = () => 1; } const stream = ObjectCreate(TransformStream_prototype); const startPromise = createPromise(); InitializeTransformStream( stream, startPromise, writableHighWaterMark, writableSizeAlgorithm, readableHighWaterMark, readableSizeAlgorithm); const controller = ObjectCreate(TransformStreamDefaultController_prototype); SetUpTransformStreamDefaultController( stream, controller, transformAlgorithm, flushAlgorithm); const startResult = startAlgorithm(); resolvePromise(startPromise, startResult); return stream; } function InitializeTransformStream( stream, startPromise, writableHighWaterMark, writableSizeAlgorithm, readableHighWaterMark, readableSizeAlgorithm) { const startAlgorithm = () => startPromise; const writeAlgorithm = chunk => TransformStreamDefaultSinkWriteAlgorithm(stream, chunk); const abortAlgorithm = reason => TransformStreamDefaultSinkAbortAlgorithm(stream, reason); const closeAlgorithm = () => TransformStreamDefaultSinkCloseAlgorithm(stream); stream[_writable] = binding.CreateWritableStream( startAlgorithm, writeAlgorithm, closeAlgorithm, abortAlgorithm, writableHighWaterMark, writableSizeAlgorithm); const pullAlgorithm = () => TransformStreamDefaultSourcePullAlgorithm(stream); const cancelAlgorithm = reason => { TransformStreamErrorWritableAndUnblockWrite(stream, reason); return createResolvedPromise(undefined); }; stream[_readable] = binding.CreateReadableStream( startAlgorithm, pullAlgorithm, cancelAlgorithm, readableHighWaterMark, readableSizeAlgorithm, false); stream[_backpressure] = undefined; stream[_backpressureChangePromise] = undefined; TransformStreamSetBackpressure(stream, true); stream[_transformStreamController] = undefined; } function IsTransformStream(x) { return hasOwnPropertyNoThrow(x, _transformStreamController); } function TransformStreamError(stream, e) { const readable = stream[_readable]; if (binding.IsReadableStreamReadable(readable)) { binding.ReadableStreamDefaultControllerError( binding.getReadableStreamController(readable), e); } TransformStreamErrorWritableAndUnblockWrite(stream, e); } function TransformStreamErrorWritableAndUnblockWrite(stream, e) { TransformStreamDefaultControllerClearAlgorithms( stream[_transformStreamController]); binding.WritableStreamDefaultControllerErrorIfNeeded( binding.getWritableStreamController(stream[_writable]), e); if (stream[_backpressure]) { TransformStreamSetBackpressure(stream, false); } } function TransformStreamSetBackpressure(stream, backpressure) { if (stream[_backpressureChangePromise] !== undefined) { resolvePromise(stream[_backpressureChangePromise], undefined); } stream[_backpressureChangePromise] = createPromise(); stream[_backpressure] = backpressure; } class TransformStreamDefaultController { constructor() { throw new TypeError(streamErrors.illegalConstructor); } get desiredSize() { if (!IsTransformStreamDefaultController(this)) { throw new TypeError(streamErrors.illegalInvocation); } const readableController = binding.getReadableStreamController( this[_controlledTransformStream][_readable]); return binding.ReadableStreamDefaultControllerGetDesiredSize( readableController); } enqueue(chunk) { if (!IsTransformStreamDefaultController(this)) { throw new TypeError(streamErrors.illegalInvocation); } TransformStreamDefaultControllerEnqueue(this, chunk); } error(reason) { if (!IsTransformStreamDefaultController(this)) { throw new TypeError(streamErrors.illegalInvocation); } TransformStreamDefaultControllerError(this, reason); } terminate() { if (!IsTransformStreamDefaultController(this)) { throw new TypeError(streamErrors.illegalInvocation); } TransformStreamDefaultControllerTerminate(this); } } const TransformStreamDefaultController_prototype = TransformStreamDefaultController.prototype; function IsTransformStreamDefaultController(x) { return hasOwnPropertyNoThrow(x, _controlledTransformStream); } function SetUpTransformStreamDefaultController( stream, controller, transformAlgorithm, flushAlgorithm) { controller[_controlledTransformStream] = stream; stream[_transformStreamController] = controller; controller[_transformAlgorithm] = transformAlgorithm; controller[_flushAlgorithm] = flushAlgorithm; } function SetUpTransformStreamDefaultControllerFromTransformer( stream, transformer) { const controller = ObjectCreate(TransformStreamDefaultController_prototype); let transformAlgorithm; const transformMethod = transformer.transform; if (transformMethod !== undefined) { if (typeof transformMethod !== 'function') { throw new TypeError('transformer.transform is not a function'); } transformAlgorithm = chunk => PromiseCall2(transformMethod, transformer, chunk, controller); } else { transformAlgorithm = chunk => { try { TransformStreamDefaultControllerEnqueue(controller, chunk); return createResolvedPromise(); } catch (resultValue) { return createRejectedPromise(resultValue); } }; } const flushAlgorithm = CreateAlgorithmFromUnderlyingMethod( transformer, 'flush', 1, 'transformer.flush'); SetUpTransformStreamDefaultController( stream, controller, transformAlgorithm, flushAlgorithm); } function TransformStreamDefaultControllerClearAlgorithms(controller) { controller[_transformAlgorithm] = undefined; controller[_flushAlgorithm] = undefined; } function TransformStreamDefaultControllerEnqueue(controller, chunk) { const stream = controller[_controlledTransformStream]; const readableController = binding.getReadableStreamController(stream[_readable]); if (!binding.ReadableStreamDefaultControllerCanCloseOrEnqueue( readableController)) { throw binding.getReadableStreamEnqueueError(stream[_readable], readableController); } try { binding.ReadableStreamDefaultControllerEnqueue(readableController, chunk); } catch (e) { TransformStreamErrorWritableAndUnblockWrite(stream, e); throw binding.getReadableStreamStoredError(stream[_readable]); } const backpressure = binding.ReadableStreamDefaultControllerHasBackpressure( readableController); if (backpressure !== stream[_backpressure]) { TransformStreamSetBackpressure(stream, true); } } function TransformStreamDefaultControllerError(controller, e) { TransformStreamError(controller[_controlledTransformStream], e); } function TransformStreamDefaultControllerPerformTransform(controller, chunk) { const transformPromise = controller[_transformAlgorithm](chunk, controller); return thenPromise(transformPromise, undefined, r => { TransformStreamError(controller[_controlledTransformStream], r); throw r; }); } function TransformStreamDefaultControllerTerminate(controller) { const stream = controller[_controlledTransformStream]; const readableController = binding.getReadableStreamController(stream[_readable]); if (binding.ReadableStreamDefaultControllerCanCloseOrEnqueue( readableController)) { binding.ReadableStreamDefaultControllerClose(readableController); } const error = new TypeError(errStreamTerminated); TransformStreamErrorWritableAndUnblockWrite(stream, error); } function TransformStreamDefaultSinkWriteAlgorithm(stream, chunk) { const controller = stream[_transformStreamController]; if (stream[_backpressure]) { const backpressureChangePromise = stream[_backpressureChangePromise]; return thenPromise(backpressureChangePromise, () => { const writable = stream[_writable]; if (binding.isWritableStreamErroring(writable)) { throw binding.getWritableStreamStoredError(writable); } return TransformStreamDefaultControllerPerformTransform(controller, chunk); }); } return TransformStreamDefaultControllerPerformTransform(controller, chunk); } function TransformStreamDefaultSinkAbortAlgorithm(stream, reason) { TransformStreamError(stream, reason); return createResolvedPromise(); } function TransformStreamDefaultSinkCloseAlgorithm(stream) { const readable = stream[_readable]; const controller = stream[_transformStreamController]; const flushPromise = controller[_flushAlgorithm](controller); TransformStreamDefaultControllerClearAlgorithms(controller); return thenPromise( flushPromise, () => { if (binding.IsReadableStreamErrored(readable)) { throw binding.getReadableStreamStoredError(readable); } const readableController = binding.getReadableStreamController(readable); if (binding.ReadableStreamDefaultControllerCanCloseOrEnqueue( readableController)) { binding.ReadableStreamDefaultControllerClose(readableController); } }, r => { TransformStreamError(stream, r); throw binding.getReadableStreamStoredError(readable); }); } function TransformStreamDefaultSourcePullAlgorithm(stream) { TransformStreamSetBackpressure(stream, false); return stream[_backpressureChangePromise]; } function createTransformStreamSimple(transformAlgorithm, flushAlgorithm) { return CreateTransformStream(() => createResolvedPromise(), transformAlgorithm, flushAlgorithm); } function createTransformStream( transformer, writableStrategy, readableStrategy) { if (transformer === undefined) { transformer = ObjectCreate(null); } if (writableStrategy === undefined) { writableStrategy = ObjectCreate(null); } if (readableStrategy === undefined) { readableStrategy = ObjectCreate(null); } return new TransformStream(transformer, writableStrategy, readableStrategy); } function getTransformStreamReadable(stream) { return stream[_readable]; } function getTransformStreamWritable(stream) { return stream[_writable]; } Object.assign(binding, { createTransformStreamSimple, createTransformStream, TransformStreamDefaultControllerEnqueue, getTransformStreamReadable, getTransformStreamWritable }); });