From cc44098a84134662473798a00f85b60a13c22969 Mon Sep 17 00:00:00 2001 From: Yunfei He Date: Sun, 31 May 2026 00:28:31 +0800 Subject: [PATCH] docs: resolve Vue-vs-React semantics placeholder (all 3 are idioms, not divergences) (#76) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The placeholder listed three candidates to evaluate as by-design divergences: v-if/null comment host nodes, reactivity-driven re-render timing, and keyed reconciliation order. Grounding each in the runtime code shows all three produce byte-identical terminal output vs Ink — a commit always paints f(current host tree), so *how* the tree was built never reaches the terminal. None is a divergence, so the placeholder is removed and the three are recorded as concise one-liners under "Framework idioms (noted, not behavioral divergences)": - v-if=false / null|false|undefined children become an inert Comment vnode (TuiComment) — no yoga node, paints nothing, doesn't shift a sibling's yoga index, skipped for the positional index (G52); output equals omitting the element. - Commit timing is deliberately Ink-aligned (~32ms ceil(1000/maxFps) throttle, sync resize), so Vue's fine-grained re-render granularity stays unobservable. - Keyed lists use Vue core's patchKeyedChildren, not React's fiber diff; output depends on the final tree, not the move order. Co-authored-by: Claude Opus 4.8 (1M context) --- .agents/docs/ink-divergences.md | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/.agents/docs/ink-divergences.md b/.agents/docs/ink-divergences.md index a831c12..f2b3970 100644 --- a/.agents/docs/ink-divergences.md +++ b/.agents/docs/ink-divergences.md @@ -98,12 +98,6 @@ deliberate. Divergences fall into a few kinds: Keeping a previous render's value, as Ink does for these two props, is the anomaly — and an inconsistent one, since every other flex prop resets. Maintainer decision (2026-05-30): KEEP. -### Other Vue-vs-React semantics _(placeholder)_ - -- _(maintainer: candidates to document — `v-if`/`null` rendering as comment host nodes; - reactivity-driven re-render timing vs React's render cycle; keyed reconciliation order. - Add the ones that are genuinely by-design.)_ - ## Not applicable in Vue ### React concurrent mode @@ -120,6 +114,20 @@ Surface conventions, listed so they aren't mistaken for gaps: - kebab-case filenames; `.ts` over `.tsx` where there's no JSX. - `shallowRef` by default for reactive state. +Reconciler/runtime mechanics that differ from React internally yet produce **byte-identical** +terminal output, because a commit always paints `f(current host tree)` — _how_ the tree was +built never reaches the terminal: + +- **A `v-if=false` branch (or a `null`/`false`/`undefined` child) leaves a comment anchor + (`TuiComment`)** where Ink emits no node, but it is inert: no yoga node, paints nothing, + never shifts a sibling's yoga index, and is skipped for the positional `` index + in all three squash paths (`G52`). Output equals omitting the element. +- **Commit timing is deliberately Ink-aligned** — leading+trailing throttle at + `ceil(1000/maxFps)` ≈ 32 ms (Ink's `renderThrottleMs`), synchronous resize — even though + re-renders are Vue's fine-grained reactivity, not a React subtree re-render. +- **Keyed lists use Vue core's `patchKeyedChildren`** (LIS), not React's fiber diff; output + depends on the final tree, not the move order. + --- ## Maintainer additions