ix
Version:
The Interactive Extensions for JavaScript
159 lines (157 loc) • 7.36 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.toDOMStreamProto = exports.toDOMStream = void 0;
const tslib_1 = require("tslib");
const publish_js_1 = require("./operators/publish.js");
const fromdomstream_js_1 = require("./fromdomstream.js");
const asynciterablex_js_1 = require("./asynciterablex.js");
/** @ignore */
function memcpy(target, source, targetByteOffset = 0, sourceByteLength = source.byteLength) {
const targetByteLength = target.byteLength;
const dst = new Uint8Array(target.buffer, target.byteOffset, targetByteLength);
const src = new Uint8Array(source.buffer, source.byteOffset, Math.min(sourceByteLength, targetByteLength, source.buffer.byteLength - source.byteOffset));
dst.set(src, targetByteOffset);
return src.byteLength;
}
class AbstractUnderlyingSource {
constructor(_source) {
this._source = _source;
}
cancel() {
return tslib_1.__awaiter(this, void 0, void 0, function* () {
const source = this._source;
if (source && source.return) {
yield source.return();
}
this._source = null;
});
}
}
class UnderlyingAsyncIterableDefaultSource extends AbstractUnderlyingSource {
constructor(source) {
super(source);
}
// eslint-disable-next-line consistent-return
pull(controller) {
return tslib_1.__awaiter(this, void 0, void 0, function* () {
const source = this._source;
if (source) {
const r = yield source.next(controller.desiredSize);
if (!r.done) {
return controller.enqueue(r.value);
}
}
controller.close();
});
}
}
class UnderlyingAsyncIterableByteSource extends AbstractUnderlyingSource {
constructor(reader, opts = {}) {
super(reader);
this.type = 'bytes';
this.autoAllocateChunkSize = opts['autoAllocateChunkSize'];
this.fallbackDefaultSource = new UnderlyingAsyncIterableDefaultSource(reader);
}
// eslint-disable-next-line consistent-return
pull(controller) {
return tslib_1.__awaiter(this, void 0, void 0, function* () {
if (!controller.byobRequest) {
return yield this.fallbackDefaultSource.pull(controller);
}
if (this._source) {
const { view } = controller.byobRequest;
const { done, value } = yield this._source.next(view);
if (!done) {
// Did the source write into the BYOB view itself,
// then yield us the `bytesWritten` value? If so,
// pass that along
if (typeof value === 'number') {
return controller.byobRequest.respond(value);
}
// otherwise if the source is only producing buffers
// but doesn't expect to be given one, we should copy
// the produced buffer into the front of the BYOB view
if (ArrayBuffer.isView(value)) {
return value.buffer === view.buffer
? controller.byobRequest.respondWithNewView(value)
: controller.byobRequest.respond(memcpy(view, value));
}
}
}
controller.close();
});
}
}
// Generate subclasses of ReadableStream that conform to the
// AsyncIterable protocol. These classes are dynamically created
// the first time a ReadableStream is produced because ReadableStream
// is a browser-only API, and closure-compiler won't compile if they're
// statically defined at the module scope.
/** @ignore */
const asyncIterableReadableStream = (() => {
let AsyncIterableReadableByteStream_;
let AsyncIterableDefaultReadableStream_;
// A function that's called the first time someone creates a
// ReadableStream via `toDOMStream()`
const createFirstTime = (source, opts) => {
// Generate the subclasses with [Symbol.asyncIterator]() methods
class AsyncIterableDefaultReadableStream extends ReadableStream {
[Symbol.asyncIterator]() {
return (0, fromdomstream_js_1.fromDOMStream)(this)[Symbol.asyncIterator]();
}
}
class AsyncIterableReadableByteStream extends ReadableStream {
[Symbol.asyncIterator]() {
return (0, fromdomstream_js_1.fromDOMStream)(this, { mode: 'byob' })[Symbol.asyncIterator]();
}
}
AsyncIterableReadableByteStream_ = AsyncIterableReadableByteStream;
AsyncIterableDefaultReadableStream_ = AsyncIterableDefaultReadableStream;
// Now point `createAsyncIterableReadableStream` to the function that
// instantiates the classes we just created
// eslint-disable-next-line @typescript-eslint/no-use-before-define, no-use-before-define
createAsyncIterableReadableStream = createAsyncIterableReadableStreamEveryOtherTime;
// Create and return the first ReadableStream<T> instance
// eslint-disable-next-line @typescript-eslint/no-use-before-define, no-use-before-define
return createAsyncIterableReadableStreamEveryOtherTime(source, opts);
};
// Shared function pointer that's called by the wrapper closure we return
let createAsyncIterableReadableStream = createFirstTime;
// Create instances of the classes generated by `createFirstTime`
const createAsyncIterableReadableStreamEveryOtherTime = (source, opts) => {
return source instanceof UnderlyingAsyncIterableByteSource
? new AsyncIterableReadableByteStream_(source, opts)
: new AsyncIterableDefaultReadableStream_(source, opts);
};
return (source, opts) => createAsyncIterableReadableStream(source, opts);
})();
/**
* Converts an async-iterable stream to a DOM stream.
* @param source The async-iterable stream to convert to a DOM stream.
* @param options The options to apply to the DOM stream.
*/
function toDOMStream(source, options) {
if (!options || !('type' in options) || options['type'] !== 'bytes') {
return asyncIterableReadableStream(new UnderlyingAsyncIterableDefaultSource(source[Symbol.asyncIterator]()), options);
}
return asyncIterableReadableStream(new UnderlyingAsyncIterableByteSource(source[Symbol.asyncIterator](), options), options);
}
exports.toDOMStream = toDOMStream;
asynciterablex_js_1.AsyncIterableX.prototype.tee = function () {
return _getDOMStream(this).tee();
};
asynciterablex_js_1.AsyncIterableX.prototype.pipeTo = function (writable, options) {
return _getDOMStream(this).pipeTo(writable, options);
};
asynciterablex_js_1.AsyncIterableX.prototype.pipeThrough = function (duplex, options) {
return _getDOMStream(this).pipeThrough(duplex, options);
};
function _getDOMStream(self) {
return self._DOMStream || (self._DOMStream = self.pipe((0, publish_js_1.publish)(), toDOMStream));
}
function toDOMStreamProto(options) {
return !options ? toDOMStream(this) : toDOMStream(this, options);
}
exports.toDOMStreamProto = toDOMStreamProto;
asynciterablex_js_1.AsyncIterableX.prototype.toDOMStream = toDOMStreamProto;
//# sourceMappingURL=todomstream.js.map