Skip to content

v0.7.0

Choose a tag to compare

@github-actions github-actions released this 13 Apr 13:43
· 226 commits to main since this release
v0.7.0
0b3d662

Added

  • Reducer runtime for ExRatatui.App via use ExRatatui.App, runtime: :reducer. Reducer apps implement init/1, render/2, and update/2, receive terminal input as {:event, event}, mailbox messages as {:info, msg}, and can declare subscriptions with subscriptions/1
  • ExRatatui.Command — reducer side-effect helpers for immediate messages, delayed messages, async work, and batched command execution
  • ExRatatui.Subscription — reducer timer/subscription helpers for interval and one-shot self-messages reconciled by stable id
  • ExRatatui.Runtime — runtime inspection helpers exposing snapshots, trace events, and trace enable/disable controls for supervised TUI processes
  • ExRatatui.Runtime.inject_event/2 — deterministic synthetic event injection for supervised apps under test_mode
  • Example: examples/reducer_counter_app.exs — simple reducer-driven counter showing update/2 and subscriptions/1

Changed

  • ExRatatui.App now supports two runtime styles: the existing callback runtime and the new reducer runtime selected with runtime: :reducer
  • The internal server now supports reducer runtime options for commands, render suppression, trace state, runtime snapshots, async command tracking, and subscription reconciliation
  • Render-command encoding moved into ExRatatui.Bridge, making ExRatatui.draw/2 and ExRatatui.Session.draw/2 share one validation and encoding path
  • Native render-command decoding was refactored into reusable helpers in native/ex_ratatui/src/decode.rs and shared between local terminal rendering and session rendering

Fixed

  • New subscriptions now store their timer reference correctly instead of keeping the {timer_ref, token} tuple in the timer_ref field, which broke timer cancellation/rearming paths in the reducer runtime
  • Async command mappers are now wrapped the same way as async functions, so mapper exceptions/exits return structured error tuples and active_async_commands bookkeeping is always decremented
  • The mount/1 callback contract now includes the supported {:ok, state, callback_opts} form, which keeps reducer-style startup shims aligned with Dialyzer and the runtime's actual behavior
  • Invalid reducer/runtime payloads and malformed render commands now fail earlier with clearer Elixir-side or Rust-side validation errors
  • Parallel cold compile crash — the NIF bridge no longer loads its NIF via @on_load during dependency compilation. Precompiled/source artifacts are still prepared at compile time, but the NIF now loads lazily on first use, which stops isolated compiler VMs from crashing under parallel cold compiles on this host
  • test_mode input flake — local supervised apps and distributed attach clients no longer poll the real terminal while running headless tests, which removes ambient crossterm events from async test runs and stops spurious renders like the render?: false reducer flake
  • SSH auto_host_key bootstrap — host-key generation now recreates the parent <priv_dir>/ssh/ directory immediately before writing the key, so first boot succeeds even if the app's priv tree was absent or cleaned between runs

Docs

  • README now documents the reducer runtime, reducer example app, command/subscription helpers, and runtime inspection API
  • README and ExRatatui.App docs now call out that mount/1 may return runtime opts and that WidgetList.scroll_offset is row-based with partial clipping semantics
  • Expanded public moduledocs for ExRatatui.App, ExRatatui.Command, ExRatatui.Subscription, and ExRatatui.Runtime
  • HexDocs module grouping now includes reducer-runtime modules
  • README now notes that the native library loads lazily on first use

Tests

  • Added reducer runtime coverage for commands, subscriptions, tracing, render suppression, async failure handling, and invalid runtime return values
  • Added coverage for public Command, Subscription, Runtime, App, and shared bridge validation paths
  • Elixir test coverage remains at 100%