I want to asynchronously process keyboard events in a Node.js application. It was recommended to me to use readline.emitKeypressEvents which leads to code like this:
import readline from "node:readline";
readline.emitKeypressEvents(process.stdin);
process.stdin.setRawMode(true);
process.stdin.on("keypress", (str, key) => {
if (key.name === "q") {
process.exit(0);
} else {
console.log(key);
}
});
So readline is told to send keypress events to stdin, stdin is switched to raw mode and then a keypress event listener is registered. When a key is pressed, it is logged to console. When Q is pressed the application exits.
What I really don't like about this approach is the destruction of this keyboard listener by explicitly terminating the application. I want to gracefully undo the stuff done by this code.
The keypress event listener can be unregistered with process.stdin.off. The raw mode can be disabled with process.stdin.setRawMode(false) but so far I was not able to find out how to tell readline to STOP emitting keypress events. And it looks to me that this part prevents Node.js from exiting on its own.
So here is a simple test case:
const listener = () => {};
// Start listening
readline.emitKeypressEvents(process.stdin);
process.stdin.setRawMode(true);
process.stdin.on("keypress", listener);
// Stop listening
process.stdin.off("keypress", listener);
process.stdin.setRawMode(false);
// TODO Tell readline to stop emitting keypress events to stdin
// Node.js should exit now on its own
So is there a way to tell readline to stop emitting keypress events to restore the original state so Node.js can exit without a manual call to process.exit?