| import process from "node:process"; |
| import { ReadBuffer, serializeMessage } from "../shared/stdio.js"; |
| |
| |
| |
| |
| |
| export class StdioServerTransport { |
| constructor(_stdin = process.stdin, _stdout = process.stdout) { |
| this._stdin = _stdin; |
| this._stdout = _stdout; |
| this._readBuffer = new ReadBuffer(); |
| this._started = false; |
| |
| this._ondata = (chunk) => { |
| this._readBuffer.append(chunk); |
| this.processReadBuffer(); |
| }; |
| this._onerror = (error) => { |
| var _a; |
| (_a = this.onerror) === null || _a === void 0 ? void 0 : _a.call(this, error); |
| }; |
| } |
| |
| |
| |
| async start() { |
| if (this._started) { |
| throw new Error("StdioServerTransport already started! If using Server class, note that connect() calls start() automatically."); |
| } |
| this._started = true; |
| this._stdin.on("data", this._ondata); |
| this._stdin.on("error", this._onerror); |
| } |
| processReadBuffer() { |
| var _a, _b; |
| while (true) { |
| try { |
| const message = this._readBuffer.readMessage(); |
| if (message === null) { |
| break; |
| } |
| (_a = this.onmessage) === null || _a === void 0 ? void 0 : _a.call(this, message); |
| } |
| catch (error) { |
| (_b = this.onerror) === null || _b === void 0 ? void 0 : _b.call(this, error); |
| } |
| } |
| } |
| async close() { |
| var _a; |
| |
| this._stdin.off("data", this._ondata); |
| this._stdin.off("error", this._onerror); |
| |
| const remainingDataListeners = this._stdin.listenerCount('data'); |
| if (remainingDataListeners === 0) { |
| |
| |
| this._stdin.pause(); |
| } |
| |
| this._readBuffer.clear(); |
| (_a = this.onclose) === null || _a === void 0 ? void 0 : _a.call(this); |
| } |
| send(message) { |
| return new Promise((resolve) => { |
| const json = serializeMessage(message); |
| if (this._stdout.write(json)) { |
| resolve(); |
| } |
| else { |
| this._stdout.once("drain", resolve); |
| } |
| }); |
| } |
| } |
| |