feat(runtime)!: replace useExit() with Ink-aligned useAppContext() (#69)

Ink's `useApp()` returns `{ exit, waitUntilRenderFlush }`. vue-tui previously
exposed only `exit()` via `useExit()` and kept `waitUntilRenderFlush` on the
`TuiApp` handle alone. Align the public surface with Ink: add `useAppContext()`
returning the same pair, and remove `useExit()`.

- thread `waitUntilRenderFlush` into the injected `AppContext` via a hoisted
  impl shared by the `TuiApp` handle and the composable, so both resolve
  identically
- add `useAppContext()`; delete `useExit()`; migrate all call sites, PTY
  fixtures, examples, READMEs and the public-API surface test
- port Ink's two "useApp waitUntilRenderFlush" tests; Ink's third relies on
  React concurrent mode (N/A in Vue)
- rewrite the ink-divergences entry: this is now a *naming* divergence
  (`useAppContext` vs `useApp`, mirroring `createApp` vs `render`), not a
  surface one — and fix the prior wrong claim that Ink's `useApp` returns
  stdin/stdout/stderr

The name is qualified (`useAppContext`, not `useApp`) so it doesn't read as the
Vue application instance (`createApp`/`app.mount`) — the same Vue-native naming
choice vue-tui already makes with `createApp()` vs Ink's `render()`.

BREAKING CHANGE: `useExit()` is removed. Replace `const exit = useExit()` with
`const { exit } = useAppContext()`.

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Yunfei He
2026-05-30 19:57:52 +08:00
committed by GitHub
parent 6edc51b925
commit 9d1e4d7805
38 changed files with 226 additions and 122 deletions
+8 -7
View File
@@ -31,14 +31,15 @@ deliberate. Divergences fall into a few kinds:
- **Why:** mirrors Vue's own `createApp` mental model — a Vue developer expects an app
object they mount, not a one-shot render call.
### App composable — `useExit()` instead of `useApp()`
### App composable — `useAppContext()` instead of `useApp()`
- **Ink:** `useApp()` returns the full AppContext (`exit`, `waitUntilRenderFlush`,
stdin/stdout/stderr, …).
- **vue-tui:** `useExit()` returns only the `exit` function; the rest is reached through
dedicated composables (`useStdin`, `useStdout`, `useStderr`, …).
- **Why:** intentionally minimal, single-purpose composables. `waitUntilRenderFlush` is
deliberately **not** exposed.
- **Ink:** `useApp()` returns `{ exit, waitUntilRenderFlush }` — stdin/stdout/stderr are
separate hooks (`useStdin`/`useStdout`/`useStderr`), not part of it.
- **vue-tui:** `useAppContext()` returns the same `{ exit, waitUntilRenderFlush }`, with
streams on those same peer composables.
- **Why:** only the name differs — `useApp` reads as "the Vue application instance"
(`createApp`, `app.mount`), so vue-tui qualifies it as `useAppContext`. The shape is
identical to Ink; a naming divergence, not a surface one.
### Named type / prop re-exports