Raxol.Gateway.Handler.Lifecycle (RaxolGateway v0.2.0)

Copy Markdown View Source

A Raxol.Gateway.Handler that runs a full TEA app per chat under environment: :gateway.

init/2 starts a Raxol.Core.Runtime.Lifecycle for the configured :app_module. The :gateway environment starts no terminal driver and no plugin manager, and registers no process names, so any number of chats can run the same app module concurrently. Each inbound gateway event is translated to a Raxol event, dispatched into the app's update cycle, and the reply is the app's next rendered frame as plain text (the engine delivers frames through an io_writer closure pointing at the session process).

Requires the optional :raxol dependency; init/2 returns {:error, :raxol_not_loaded} without it.

Options

  • :app_module (required) - the TEA app module
  • :width / :height - frame dimensions (default 80x24)
  • :render_timeout_ms - budget for the post-event fold barrier and the synchronous render (default 5000); on timeout the event is absorbed with no reply
  • :event_fn - (gateway_event -> raxol_event | nil); default maps %{text: t} to a char key event (single grapheme) or a paste event, mirroring the Telegram input adapter. nil skips the event.

  • :format_fn - (render_data -> binary | nil); default renders the delivered buffer to plain text. nil (or an empty result) skips the reply.

  • :lifecycle_opts - extra options appended to Raxol.Core.Runtime.Lifecycle.start_link/2

Turn semantics

The handler runs inside the per-chat Raxol.Gateway.Session process, so the render io_writer targets that process. A turn is collected deterministically: stale frames (startup renders, a late frame from a previous turn) are flushed, the event is cast to the dispatcher, a :sys barrier confirms the model fold, and a synchronous engine render produces the reply frame (the newest wins if several arrive). Frames the app renders BETWEEN turns are consumed and discarded by the session's catch-all handle_info -- a chat surface replies to messages; spontaneous pushes are Raxol.Gateway.Delivery's job.

Teardown

The Lifecycle GenServer is linked to the session, but a session's idle timeout is a :normal exit, which does not propagate over links. The handler's terminate/2 (invoked by the session on clean stops) stops the Lifecycle explicitly so per-chat apps never outlive their chat.