ExRatatui.Command (ExRatatui v0.8.2)

Copy Markdown View Source

Commands represent one-shot side effects scheduled by an ExRatatui.App.

They are produced from reducer updates and executed by the ExRatatui server runtime after the new state has been committed and rendered.

Available command constructors:

  • message/1 — send an immediate self-message to the app process
  • send_after/2 — schedule a delayed self-message
  • async/2 — run a zero-arity function in the background and map the result back into an app message
  • batch/1 — group multiple commands into one return value

Reducer callbacks can return commands from init/1 or update/2 via commands: [...].

Summary

Functions

Runs fun in the background and maps its result back into an app message.

Groups multiple commands into a single return value.

Schedules an immediate self-message for the app process.

Returns an empty command list.

Schedules a delayed self-message for the app process.

Types

async_fun()

@type async_fun() :: (-> term())

async_mapper()

@type async_mapper() :: (term() -> term())

t()

@type t() ::
  %ExRatatui.Command{
    commands: term(),
    delay_ms: term(),
    fun: term(),
    kind: :message,
    mapper: term(),
    message: term()
  }
  | %ExRatatui.Command{
      commands: term(),
      delay_ms: non_neg_integer(),
      fun: term(),
      kind: :after,
      mapper: term(),
      message: term()
    }
  | %ExRatatui.Command{
      commands: term(),
      delay_ms: term(),
      fun: async_fun(),
      kind: :async,
      mapper: async_mapper(),
      message: term()
    }
  | %ExRatatui.Command{
      commands: [t()],
      delay_ms: term(),
      fun: term(),
      kind: :batch,
      mapper: term(),
      message: term()
    }

Functions

async(fun, mapper)

@spec async(async_fun(), async_mapper()) :: t()

Runs fun in the background and maps its result back into an app message.

On success, the mapper receives the function's return value directly. If the function raises or exits, the mapper receives {:error, reason} where reason is one of {:exception, message}, {:exit, term}, or {:throw | :error, term}. Design the mapper to handle both shapes so a failing task becomes a structured message your update/2 (or handle_info/2) can branch on.

If the mapper itself raises or exits, the app process receives {:error, {:mapper_exception, message}}, {:error, {:mapper_exit, reason}}, or {:error, {:mapper_catch, {kind, reason}}} — distinct tags so you can tell a task failure apart from a bug in the mapper.

Examples

ExRatatui.Command.async(
  fn -> MyAPI.fetch_user(id) end,
  fn
    {:ok, user} -> {:user_loaded, user}
    {:error, reason} -> {:user_load_failed, reason}
  end
)

batch(commands)

@spec batch([t()]) :: t()

Groups multiple commands into a single return value.

Nested batches are flattened by the runtime before execution.

Examples

iex> a = ExRatatui.Command.message(:a)
iex> b = ExRatatui.Command.send_after(10, :b)
iex> ExRatatui.Command.batch([a, b])
%ExRatatui.Command{
  kind: :batch,
  commands: [
    %ExRatatui.Command{kind: :message, message: :a},
    %ExRatatui.Command{kind: :after, delay_ms: 10, message: :b}
  ]
}

message(message)

@spec message(term()) :: t()

Schedules an immediate self-message for the app process.

Examples

iex> ExRatatui.Command.message(:tick)
%ExRatatui.Command{kind: :message, message: :tick}

none()

@spec none() :: []

Returns an empty command list.

Useful when reducer helpers want to return an explicit "no commands" value.

Examples

iex> ExRatatui.Command.none()
[]

send_after(delay_ms, message)

@spec send_after(non_neg_integer(), term()) :: t()

Schedules a delayed self-message for the app process.

delay_ms may be 0 to enqueue the message on the next turn without waiting.

Examples

iex> ExRatatui.Command.send_after(250, :refresh)
%ExRatatui.Command{kind: :after, delay_ms: 250, message: :refresh}