import { Bert } from "./bert.js"; import { Duplex } from "node:stream"; export class Port extends Duplex { bert; originalStdout; fakeStdout = () => true; constructor(allBinariesAsString, mapKeyAsAtom, decodeUndefinedValues) { super({ objectMode: true }); this.bert = new Bert(allBinariesAsString, mapKeyAsAtom, decodeUndefinedValues); this.originalStdout = process.stdout; process.stdout.write = this.fakeStdout; process.stdin.on("readable", () => { while (this._read()) { } }); } _read() { const lenBytes = process.stdin.read(4); if (lenBytes) { const termLen = this.bert.bytesToInt(lenBytes, 4, true); process.stderr.write(`Got incoming term length: ${termLen} (bytes: <<${lenBytes.toString('hex').match(/../g).map((hex) => parseInt(`0x${hex}`).toString()).join(', ')}>>)\n`); const termBytes = process.stdin.read(termLen); if (termBytes) { const decoded = this.bert.decode(termBytes); this.push(decoded); return decoded; } else { process.stderr.write(`Term read got erroneous null.\n`); return null; } } else return null; } _write(obj, encodingOrCallback, callback) { const actualCallback = callback || typeof encodingOrCallback === "function" ? encodingOrCallback : undefined; try { const term = this.bert.encode(obj, true); const len = Buffer.alloc(4); len.writeUInt32BE(term.length, 0); process.stdout.write = this.originalStdout; process.stdout.write(len); process.stdout.write(term, actualCallback); process.stdout.write = this.fakeStdout; return true; } catch (error) { process.stderr.write(`Error writing: ${error}\n`); return false; } } }