vadimdemedes / ink

🌈 React for interactive command-line apps
https://term.ink
MIT License
27.29k stars 613 forks source link

Document when the app exits #446

Open MrToph opened 3 years ago

MrToph commented 3 years ago

It's not clear to me when the app exits or what keeps it alive. I tried the example with the counter that uses setInterval and the app keeps running. In my code, I'm using some async calls but the app immediately exits.

I couldn't find any documentation regarding what keeps the app alive or how to disable it from exiting.

vadimdemedes commented 3 years ago

Can you create a minimal reproduction of the problem you're seeing?

chrisdrackett commented 2 years ago

I'm also curious how this works. In the base example if I have the counter running the app won't exit, but if I replace it with a Text it does, I'm also unclear what causes the app to keep running or exit.

mAAdhaTTah commented 2 years ago

This is less an Ink-specific thing and more a Node thing. The CLI stays alive as long as there are open tasks/processes for Node to run. Once those complete, it closes. setInternal keeps it alive because it continuously adds new tasks. Depending on what your async calls are doing, they could be the cause of the issue.

mabasic commented 9 months ago

I am totally confused here. When running the counter example I can't kill the program even if I use the kill command. I have to close the entire terminal in order for it to stop. WTF

tuler commented 9 months ago

I'm also having issues with the program not exiting. I wonder what are the tools and strategies to use to find what is the real issue.

neverstew commented 1 week ago

For anyone else coming across this issue, I don't think there's anything wrong with ink. It's more about the tooling and documentation. Here's what I learnt using the standard app produced by the command in the getting started docs...

Typescript builds

Ignore this section if you used javascript.

When you run npm run build or npm run dev, tsc compiles your app. If there are any errors within the project, including linting errors, the build will fail.

This can be a silent source of issues. Check the build process and make sure there are 0 errors.

CLI parsing

Understanding the structure of the directory can help you diagnose issues. Your app runs via source/cli.tsx, which parses the command line options and renders your app. Making sure your CLI parser is set up correctly will allow you to pass the right options to your rendered app.

Rendering cycle

Ink runs in a node process, the same as every other node program. When there is no more work scheduled, the program will exit. Or in other words, to keep your ink app alive, you must make sure there is continuously work scheduled. In practice, this means that there must be some kind of asynchronous process occurring in order for your app to stay open - something like: setTimeout, setInterval, an unresolved promise or anything else asynchronous.

If you look at the counter example, you'll see that there is an interval running, keeping the ink app open. In other examples where there is no asynchronous work occurring, the app exits immediately.

To keep your app alive indefinitely, you can use this minimal snippet

import React, { useEffect } from 'react';
import { Text } from 'ink';

// refresh the app every 100ms
const useKeepAlive = () => useEffect(() => { setInterval(() => {}, 100) }, []);

export const AliveApp = () => {
    useKeepAlive();
    return <Text color="green">Hi there</Text>;
};

To exit the app, use CTRL + C.

vdawg-git commented 1 week ago

The setInterval-solution freezes the program and I cannot exit with CTRL+C anymore :/

vdawg-git commented 1 week ago

This works and is elegant: https://stackoverflow.com/a/50873242