Skip to content

refactor: retain renderer state in a frame context - #169

Open
cowboyd wants to merge 1 commit into
feat/state-only-updatefrom
spike/frame-ownership
Open

cowboyd wants to merge 1 commit into
feat/state-only-updatefrom
spike/frame-ownership

Conversation

@cowboyd

@cowboyd cowboyd commented Oct 27, 2026 •

Copy link
Copy Markdown
Collaborator

What does this PR do?

Lays the groundwork re-using element renders from previous frames. What this does is split the architecture into two separate frames, the current frame and the previous frame. This also fixes stale bounds for removed elements and caret cursors remaining visible after a resize. What it allows us to do is to "look back" at previous renders and just byte-copy entire rendered descriptions of elements.

There is already a bunch of "look back" happening already such as what the caret and the pointer were doing in the previous frame, so this just make a lot of that explicit.

Details

FrameContext owns the two frames, their current/previous roles, and the shared open-element stack and output buffer.

Rendering prepares the runlist, executes layout, resolves metadata and pointer hits, draws cells, emits differences, then swaps the frames. Bounds remain lazy. Resize rebuilds viewport storage while retaining directive bytes and emitted state.

This does almost double the amount of memory used because we store two runlists instead of one so that we can crib off the previous runlets. However, this is because we preallocate the entire maximum runlets size for the maximum number of elements. We could grow this memory according to usage, but that would be a separate change.

Type of change

  • Bug fix
  • Feature
  • Refactor (no behavior change)
  • Documentation
  • Performance improvement
  • Tests
  • Chore (dependencies, CI, tooling)

Checklist

  • All tests pass (deno task test: 29 suites, 400 steps)
  • Files are formatted (deno task fmt)
  • I have added/updated tests for my changes
  • I have added a changeset

Also checked the WASM build, deno task verify, deno lint, and targeted native
checks for rejected-input preservation, resize and capacity recovery, and
allocation boundaries.

AI-generated code disclosure

  • This PR includes AI-generated code

@bombshell-cooper

bombshell-cooper Bot commented Oct 27, 2026 •

Copy link
Copy Markdown
Contributor

Changeset review

  • warning: Changeset package scope does not match the affected packages confidently.
  • warning: Changeset is not sufficiently consumer-focused.
  • warning: Changeset contains unsupported consumer-facing claims.

@cowboyd
cowboyd added this pull request to stack #165 October 27, 2026 14:42
@@ -0,0 +1,7 @@
---

@bombshell-cooper bombshell-cooper Bot Oct 27, 2026 •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changeset review

  • warning: Changeset package scope does not match the affected packages confidently.
  • warning: Changeset is not sufficiently consumer-focused.
  • warning: Changeset contains unsupported consumer-facing claims.

@pkg-pr-new

pkg-pr-new Bot commented Oct 27, 2026

Copy link
Copy Markdown

Open in StackBlitz

npm i https://pkg.pr.new/@bomb.sh/tty@169

commit: 6269f98

@github-actions

Copy link
Copy Markdown

Size Increased — +2.3 KB

130.4 KB unpacked

@cowboyd
cowboyd force-pushed the spike/frame-ownership branch 2 times, most recently from ec55feb to dd5d958 Compare October 27, 2026 15:15
@cowboyd
cowboyd force-pushed the spike/frame-ownership branch from dd5d958 to 201083e Compare October 27, 2026 15:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant