diff options
author | 2022-10-12 23:46:15 -0700 | |
---|---|---|
committer | 2022-10-12 23:46:15 -0700 | |
commit | 3fceae807037d97cd6c93d20d87d1ef5a98fdd75 (patch) | |
tree | 4c2f294fc53937f3e1646b9df73a4ec0265ef416 /src/bun.js/builtins/js | |
parent | 8cd8e34719d45ccef3011de7431d066631a6c806 (diff) | |
download | bun-3fceae807037d97cd6c93d20d87d1ef5a98fdd75.tar.gz bun-3fceae807037d97cd6c93d20d87d1ef5a98fdd75.tar.zst bun-3fceae807037d97cd6c93d20d87d1ef5a98fdd75.zip |
Implement `ReadableStream.prototype[Symbol.asyncIterator]`
cc @fabiancook
Diffstat (limited to 'src/bun.js/builtins/js')
-rw-r--r-- | src/bun.js/builtins/js/ReadableStream.js | 21 | ||||
-rw-r--r-- | src/bun.js/builtins/js/ReadableStreamInternals.js | 53 |
2 files changed, 74 insertions, 0 deletions
diff --git a/src/bun.js/builtins/js/ReadableStream.js b/src/bun.js/builtins/js/ReadableStream.js index 42c0fbdbc..8020b024d 100644 --- a/src/bun.js/builtins/js/ReadableStream.js +++ b/src/bun.js/builtins/js/ReadableStream.js @@ -443,3 +443,24 @@ function locked() return @isReadableStreamLocked(this); } + +function values(options) { + "use strict"; + var prototype = this?.constructor?.prototype; + if (!prototype) { + return @undefined; + } + @readableStreamDefineLazyIterators(prototype); + return prototype.values.@call(this, options); +} + +@linkTimeConstant +function lazyAsyncIterator() { + "use strict"; + var prototype = this?.constructor?.prototype; + if (!prototype) { + return @undefined; + } + @readableStreamDefineLazyIterators(prototype); + return prototype[globalThis.Symbol.asyncIterator].@call(this); +}
\ No newline at end of file diff --git a/src/bun.js/builtins/js/ReadableStreamInternals.js b/src/bun.js/builtins/js/ReadableStreamInternals.js index 5321ca922..cbe72c99e 100644 --- a/src/bun.js/builtins/js/ReadableStreamInternals.js +++ b/src/bun.js/builtins/js/ReadableStreamInternals.js @@ -2096,3 +2096,56 @@ async function readableStreamToArrayDirect(stream, underlyingSource) { return capability.@promise; } + + +function readableStreamDefineLazyIterators(prototype) { + "use strict"; + + var asyncIterator = globalThis.Symbol.asyncIterator; + + var ReadableStreamAsyncIterator = async function* ReadableStreamAsyncIterator(stream, preventCancel) { + var reader = stream.getReader(); + var deferredError; + try { + while (true) { + var done, value; + const firstResult = reader.readMany(); + if (@isPromise(firstResult)) { + const result = await firstResult; + done = result.done; + value = result.value; + } else { + done = firstResult.done; + value = firstResult.value; + } + + if (done) { + return; + } + yield* value; + } + } catch(e) { + deferredError = e; + } finally { + reader.releaseLock(); + + if (!preventCancel) { + stream.cancel(deferredError); + } + + if (deferredError) { + throw deferredError; + } + } + }; + + var createAsyncIterator = function asyncIterator() { + return ReadableStreamAsyncIterator(this, false); + }; + var createValues = function values({preventCancel = false} = {preventCancel: false}) { + return ReadableStreamAsyncIterator(this, preventCancel); + }; + @Object.@defineProperty(prototype, asyncIterator, { value: createAsyncIterator }); + @Object.@defineProperty(prototype, "values", { value: createValues }); + return prototype; +}
\ No newline at end of file |