diff options
Diffstat (limited to 'src/js/builtins/ConsoleObject.ts')
-rw-r--r-- | src/js/builtins/ConsoleObject.ts | 84 |
1 files changed, 84 insertions, 0 deletions
diff --git a/src/js/builtins/ConsoleObject.ts b/src/js/builtins/ConsoleObject.ts new file mode 100644 index 000000000..45746459a --- /dev/null +++ b/src/js/builtins/ConsoleObject.ts @@ -0,0 +1,84 @@ +$overriddenName = "[Symbol.asyncIterator]"; +export function asyncIterator(this: Console) { + const Iterator = async function* ConsoleAsyncIterator() { + const stream = Bun.stdin.stream(); + var reader = stream.getReader(); + + // TODO: use builtin + var decoder = new (globalThis as any).TextDecoder("utf-8", { fatal: false }) as TextDecoder; + var deferredError; + var indexOf = Bun.indexOfLine; + + try { + while (true) { + var done, value; + var pendingChunk; + const firstResult = reader.readMany(); + if ($isPromise(firstResult)) { + ({ done, value } = await firstResult); + } else { + ({ done, value } = firstResult); + } + + if (done) { + if (pendingChunk) { + yield decoder.decode(pendingChunk); + } + return; + } + + var actualChunk; + // we assume it was given line-by-line + for (const chunk of value) { + actualChunk = chunk; + if (pendingChunk) { + actualChunk = Buffer.concat([pendingChunk, chunk]); + pendingChunk = null; + } + + var last = 0; + // TODO: "\r", 0x4048, 0x4049, 0x404A, 0x404B, 0x404C, 0x404D, 0x404E, 0x404F + var i = indexOf(actualChunk, last); + while (i !== -1) { + yield decoder.decode(actualChunk.subarray(last, i)); + last = i + 1; + i = indexOf(actualChunk, last); + } + + pendingChunk = actualChunk.subarray(last); + } + } + } catch (e) { + deferredError = e; + } finally { + reader.releaseLock(); + + if (deferredError) { + throw deferredError; + } + } + }; + + const symbol = globalThis.Symbol.asyncIterator; + this[symbol] = Iterator; + return Iterator(); +} + +export function write(this: Console, input) { + var writer = $getByIdDirectPrivate(this, "writer"); + if (!writer) { + var length = $toLength(input?.length ?? 0); + writer = Bun.stdout.writer({ highWaterMark: length > 65536 ? length : 65536 }); + $putByIdDirectPrivate(this, "writer", writer); + } + + var wrote = writer.write(input); + + const count = $argumentCount(); + for (var i = 1; i < count; i++) { + wrote += writer.write($argument(i)); + } + + writer.flush(true); + return wrote; +} |