Skip to content

refactor(runtime): extract resume-repaint tick into useResumeTick (#1237)#1280

Merged
gfargo merged 1 commit into
mainfrom
feat/app-decompose-resume-tick
Jun 15, 2026
Merged

refactor(runtime): extract resume-repaint tick into useResumeTick (#1237)#1280
gfargo merged 1 commit into
mainfrom
feat/app-decompose-resume-tick

Conversation

@gfargo

@gfargo gfargo commented Jun 15, 2026

Copy link
Copy Markdown
Owner

Item 5 — app.ts decomposition (#1237)

Follows #1279. Lifts the SIGCONT resume-repaint cluster into a new useResumeTick hook.

What & why

When the workstation is suspended (Ctrl-Z) and resumed (fg → SIGCONT), Ink comes back on the alternate screen buffer without repainting — the user lands on an empty screen. The runtime installs a resume callback into resumeRef; the SIGCONT handler invokes it, and this cluster's callback bumps a throwaway counter to force a re-render (repaint).

Single combined hook (order-safe)

The throwaway setResumeTick useState and its effect are adjacent in app.ts with no intervening hooks, so they move together into one hook called at the original slot — hook order is preserved. The effect is reproduced verbatim: same !resumeRef guard, resumeRef.current = () => setResumeTick((tick) => tick + 1) assignment, cleanup, and [resumeRef] deps.

resumeRef stays runtime-owned (it's also read by the editor / compose / changelog action hooks to re-arm the screen after shelling out) and is passed in.

Changes

  • New hooks/useResumeTick.ts.
  • app.ts: the useState + effect → useResumeTick(React, {resumeRef}).
  • New hooks/useResumeTick.test.ts — install/cleanup, the tick-bump updater, and the no-resumeRef no-op.

Validation

  • jest (workstation): 112 suites / 1877 tests pass, 68 snapshots no diffs
  • tsc --noEmit: clean · eslint: 0 errors · rollup -c: builds dist/

)

Item 5 of the app.ts decomposition. Lifts the SIGCONT resume-repaint cluster —
the throwaway `setResumeTick` `useState` and the effect that wires
`resumeRef.current` to a tick-bump (forcing the Ink tree to repaint after `fg`
so the user doesn't land on an empty alt-screen) — into a new `useResumeTick`
hook.

The `useState` and effect are adjacent in app.ts with no intervening hooks, so
they move together into one hook called at the original slot; hook order is
preserved. The effect is reproduced verbatim — same `!resumeRef` guard,
`resumeRef.current = () => setResumeTick((tick) => tick + 1)` assignment,
cleanup, and `[resumeRef]` dependency array. `resumeRef` stays owned by the
runtime (also read by the editor / compose / changelog action hooks) and is
passed in. Adds tests for install/cleanup, the tick-bump updater, and the
no-resumeRef no-op.
@gfargo gfargo merged commit 7b411fa into main Jun 15, 2026
16 checks passed
@gfargo gfargo deleted the feat/app-decompose-resume-tick branch June 15, 2026 15:50
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

Successfully merging this pull request may close these issues.

1 participant