Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

'process.stdin' in nodejs is not working properly #1358

Open
Anmours opened this issue Feb 5, 2024 · 6 comments
Open

'process.stdin' in nodejs is not working properly #1358

Anmours opened this issue Feb 5, 2024 · 6 comments

Comments

@Anmours
Copy link

Anmours commented Feb 5, 2024

In my program, I need to listen to the information entered by the user in the console and make other responses.
In the past year, everything has been working normally, but today I used '@ inquirer/prompts' to change some programs.
After using this npm package, the original 'process.stdin.on' no longer works

How should I solve it? Please help me

I wrote a simple code to illustrate the problem:

const { input, select } = require('@inquirer/prompts');

async function main() {
  /* When I commented out the first two lines, the following code works properly */
  const text = await input({ message: `your name?\n` });
  console.log('inputText', text);
  /**
   * My code is omitted
   */

  /* When I used 'input', 'process.stdin.on' no longer works */
  process.stdin.on('data', async inputs => {
    let text = inputs.toString().trim();
    if (!text) return;
    switch (text) {
      case 'cls':
        console.clear();
        break;
      case 'bye':
        process.exit(0);
      default:
        console.log('stdinText:', text);
        /* I will do some other logic here, but I just streamlined it out */
        break;
    }
  });
}

main();
@SBoudrias
Copy link
Owner

It's unclear what would cause this - here's what the do when releasing the readline: https://github.com/SBoudrias/Inquirer.js/blob/master/packages/core/src/lib/screen-manager.mts#L125-L129

I think I'm missing a lot of information about what your program is supposed to do to be able to help. You want to listen to data constantly or only after the input prompt is answered?

And can you send a PR with a failing unit test? This would go a long way allowing us to debug this issue.

@LukasLeppich
Copy link

I had the same problem and found this issue. After playing around a bit with the sample code, I got it partially working with the following code.

process.stdin.removeAllListeners();
process.stdin.on('data', async inputs => {

After entering the name, you have to press Enter once before you can make an normal entry.

In my project, I use raw mode to listen for input, with this mode enabled, I don't have to press Enter before receiving user input.

@SBoudrias
Copy link
Owner

@LukasLeppich could you provide a minimal code reproduction?

I'd love to look into this and make sure nothing leaks out of Inquirer - or raise an issue to Node is discarding a readline doesn't reset the stdin properly. But it's a bit hard to go ahead with so few details.

@LukasLeppich
Copy link

@SBoudrias You can use the code @Anmours posted above.

If you execute the script, it will ask for your name and exit afterward.

If you remove the const text = await input({ message: 'your name?\n'}); line, you can type stuff and exit with bye.

If you add the process.stdin.removeAllListeners();line in front of the process.stdin.on('data', ... line and keep the const text = await input({ message: 'your name?\n' }); line, it asks for your name, than you have to press Enter once and after that, you can type stuff and exit with bye again.

The correct behavior would be to ask for your name, than repeat everything you type with stdinText: ..., clear you screen if you type cls and exit the script if you type bye.

@SBoudrias SBoudrias reopened this Mar 27, 2024
@SBoudrias
Copy link
Owner

SBoudrias commented Mar 27, 2024

Thanks! I'm looking into this.

You can also call process.stdin.resume() before setting the event listener. And weirdly enough that's what the Node.js doc recommend: https://nodejs.org/api/process.html#signal-events

Also this interesting quote:

In "old" streams mode the stdin stream is paused by default, so one must call process.stdin.resume() to read from it. Note also that calling process.stdin.resume() itself would switch stream to "old" mode.

@SBoudrias
Copy link
Owner

Yeah, pretty much what happens. In both scenario, if you log process.stdin.isPaused() you'll see it's where the difference lie.

So once a readline instance is closed, it'll pause process.stdin. Calling on won't resume it; this must be done manually. (I'm not quite sure how I could change this behavior, calling resume in Inquirer will prevent scripts from exiting)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants