UNPKG

5.37 kBJavaScriptView Raw
1import { fromDOMStream } from './fromdomstream';
2/** @ignore */
3function memcpy(target, source, targetByteOffset = 0, sourceByteLength = source.byteLength) {
4 const targetByteLength = target.byteLength;
5 const dst = new Uint8Array(target.buffer, target.byteOffset, targetByteLength);
6 const src = new Uint8Array(source.buffer, source.byteOffset, Math.min(sourceByteLength, targetByteLength));
7 dst.set(src, targetByteOffset);
8 return src.byteLength;
9}
10class AbstractUnderlyingSource {
11 constructor(_source) {
12 this._source = _source;
13 }
14 async cancel() {
15 const source = this._source;
16 if (source && source.return) {
17 await source.return();
18 }
19 this._source = null;
20 }
21}
22class UnderlyingAsyncIterableDefaultSource extends AbstractUnderlyingSource {
23 constructor(source) {
24 super(source);
25 }
26 async pull(controller) {
27 const source = this._source;
28 if (source) {
29 const r = await source.next(controller.desiredSize);
30 if (!r.done) {
31 return controller.enqueue(r.value);
32 }
33 }
34 controller.close();
35 }
36}
37class UnderlyingAsyncIterableByteSource extends AbstractUnderlyingSource {
38 constructor(reader, opts = {}) {
39 super(reader);
40 this.type = 'bytes';
41 this.autoAllocateChunkSize = opts.autoAllocateChunkSize;
42 this.fallbackDefaultSource = new UnderlyingAsyncIterableDefaultSource(reader);
43 }
44 async pull(controller) {
45 if (!controller.byobRequest) {
46 return await this.fallbackDefaultSource.pull(controller);
47 }
48 if (this._source) {
49 const { view } = controller.byobRequest;
50 const { done, value } = await this._source.next(view);
51 if (!done) {
52 // Did the source write into the BYOB view itself,
53 // then yield us the `bytesWritten` value? If so,
54 // pass that along
55 if (typeof value === 'number') {
56 return controller.byobRequest.respond(value);
57 }
58 // otherwise if the source is only producing buffers
59 // but doesn't expect to be given one, we should copy
60 // the produced buffer into the front of the BYOB view
61 if (ArrayBuffer.isView(value)) {
62 return value.buffer === view.buffer
63 ? controller.byobRequest.respondWithNewView(value)
64 : controller.byobRequest.respond(memcpy(view, value));
65 }
66 }
67 }
68 controller.close();
69 }
70}
71// Generate subclasses of ReadableStream that conform to the
72// AsyncIterable protocol. These classes are dynamically created
73// the first time a ReadableStream is produced because ReadableStream
74// is a browser-only API, and closure-compiler won't compile if they're
75// statically defined at the module scope.
76/** @ignore */
77const asyncIterableReadableStream = (() => {
78 let AsyncIterableReadableByteStream_;
79 let AsyncIterableDefaultReadableStream_;
80 // A function that's called the first time someone creates a
81 // ReadableStream via `toDOMStream()`
82 let createFirstTime = (source, opts) => {
83 // Generate the subclasses with [Symbol.asyncIterator]() methods
84 class AsyncIterableDefaultReadableStream extends ReadableStream {
85 [Symbol.asyncIterator]() {
86 return fromDOMStream(this)[Symbol.asyncIterator]();
87 }
88 }
89 class AsyncIterableReadableByteStream extends ReadableStream {
90 [Symbol.asyncIterator]() {
91 return fromDOMStream(this, { mode: 'byob' })[Symbol.asyncIterator]();
92 }
93 }
94 AsyncIterableReadableByteStream_ = AsyncIterableReadableByteStream;
95 AsyncIterableDefaultReadableStream_ = AsyncIterableDefaultReadableStream;
96 // Now point `createAsyncIterableReadableStream` to the function that
97 // instantiates the classes we just created
98 //tslint:disable-next-line
99 createAsyncIterableReadableStream = createAsyncIterableReadableStreamEveryOtherTime;
100 // Create and return the first ReadableStream<T> instance
101 //tslint:disable-next-line
102 return createAsyncIterableReadableStreamEveryOtherTime(source, opts);
103 };
104 // Shared function pointer that's called by the wrapper closure we return
105 //tslint:disable-next-line
106 let createAsyncIterableReadableStream = createFirstTime;
107 // Create instances of the classes generated by `createFirstTime`
108 let createAsyncIterableReadableStreamEveryOtherTime = (source, opts) => {
109 return source instanceof UnderlyingAsyncIterableByteSource
110 ? new AsyncIterableReadableByteStream_(source, opts)
111 : new AsyncIterableDefaultReadableStream_(source, opts);
112 };
113 return (source, opts) => createAsyncIterableReadableStream(source, opts);
114})();
115export function toDOMStream(source, options) {
116 if (!options || options.type !== 'bytes') {
117 return asyncIterableReadableStream(new UnderlyingAsyncIterableDefaultSource(source[Symbol.asyncIterator]()), options);
118 }
119 return asyncIterableReadableStream(new UnderlyingAsyncIterableByteSource(source[Symbol.asyncIterator]()), options);
120}
121
122//# sourceMappingURL=todomstream.mjs.map