import { safePromise } from "ext:core/promises"; import { ArrayBufferPrototypeGetResizable, getter, TypedArrayPrototypeGetBuffer, TypedArrayPrototypeGetByteLength, TypedArrayPrototypeGetTag, TypeError, Uint8Array, Uint8ArrayPrototypeSet, } from "ext:core/primordials"; import { op_stdio_cancel_read, op_stdio_flush, op_stdio_read, op_stdio_write, } from "ext:core/ops"; import { byobRequest as getRequest, close, enqueue, ReadableStream, ReadableStreamBYOBRequest, respond, WritableStream, } from "ext:webstreams/streams.js"; const getView = getter(ReadableStreamBYOBRequest.prototype, "view"); let canceled = false; const stdin = new ReadableStream>({ type: "bytes", async pull(controller) { const request = getRequest(controller); const view = request && getView(request); const bytes = await safePromise(op_stdio_read( view ? TypedArrayPrototypeGetByteLength(view) : 64 * 1024, )); if (canceled) return; if (bytes === null) { close(controller); if (request) respond(request, 0); } else if (request) { Uint8ArrayPrototypeSet(view!, bytes); respond(request, TypedArrayPrototypeGetByteLength(bytes)); } else { enqueue(controller, bytes); } }, cancel() { canceled = true; op_stdio_cancel_read(); }, }, { highWaterMark: 0 }); const output = (stderr: boolean) => new WritableStream>({ write(bytes) { if (TypedArrayPrototypeGetTag(bytes) !== "Uint8Array") { throw new TypeError("Stdio writes require Uint8Array chunks"); } const buffer = TypedArrayPrototypeGetBuffer(bytes); let snapshot: boolean; try { snapshot = ArrayBufferPrototypeGetResizable(buffer); } catch { snapshot = true; // SharedArrayBuffer fails the ArrayBuffer brand check. } // serde_v8 needs fixed, unshared storage; the captured constructor copies only the view. if (snapshot) bytes = new Uint8Array(bytes); return op_stdio_write([stderr, bytes as Uint8Array]); }, close() { return op_stdio_flush(stderr); }, }, { highWaterMark: 64 * 1024, size(bytes) { return TypedArrayPrototypeGetTag(bytes) === "Uint8Array" ? TypedArrayPrototypeGetByteLength(bytes) : 1; }, }); const stdout = output(false), stderr = output(true); export { stderr, stdin, stdout };