Deliver the lines a chunk split after a line listener closes the interface

This commit is contained in:
Chris Tate
2026-10-29 03:51:59 -05:00
parent 02d7230c66
commit 82fbe022b4
4 changed files with 33 additions and 1 deletions
@@ -0,0 +1,6 @@
{
"order": [
"<repo>/tests/corpus/readline-close-in-line-listener.ts"
],
"diags": []
}
+3 -1
View File
@@ -339,8 +339,10 @@ static void scr_rl_feed_text(ScrRl *rl, const char *p, size_t n) {
}
rl->line_len = 0;
if (start < n) scr_rl_buf_append(rl, p + start, n - start);
/* Node delivers every line the chunk split, also after a line listener
* closes the interface; an exception a listener throws ends the chunk. */
for (size_t i = 0; i < n_lines; i++) {
if (rl->closed || scr_exc_pending()) {
if (scr_exc_pending()) {
scr_str_release(lines[i]);
continue;
}
@@ -0,0 +1,23 @@
// A 'line' listener that closes the interface: the 'close' event runs at
// once, the rest of the lines already split from the same chunk are still
// delivered, as in Node, and later chunks are not read.
import { createInterface } from "node:readline";
import { Readable } from "node:stream";
const first = createInterface({ input: Readable.from(["x\ny\nz\n", "after\n"]) });
first.on("line", (line: string) => {
console.log("line", line);
if (line === "y") first.close();
});
first.on("close", () => console.log("closed"));
// Two listeners; the second closes on the first line of a chunk of three.
const second = createInterface({ input: Readable.from(["a\nb\nc"]) });
const order: string[] = [];
second.on("line", (line: string) => order.push(`one:${line}`));
second.on("line", (line: string) => {
order.push(`two:${line}`);
if (line === "a") second.close();
});
second.on("close", () => order.push("close"));
setTimeout(() => console.log(order.join(" ")), 20);
@@ -0,0 +1 @@
{ "plain": 4600, "san": 6500 }