Lifecycle hook helpers for Musubi runtime stages.
Stages
| Stage | Arity | Hook arguments |
|---|---|---|
:before_command | 3 | (command_name, payload, socket) |
:after_command | 4 | (command_name, payload, reply, socket) |
:handle_async | 3 | (name, async_result, socket) |
:handle_info | 2 | (message, socket) |
:after_render | 2 | (resolved_elixir_term, socket) |
:after_serialize | 2 | (wire_term, socket) |
:after_render runs after Musubi.Resolver substitutes child placeholders;
it sees the Elixir-form output (atom keys, structs, atom values).
:after_serialize runs after Musubi.Wire.to_wire/1 converts the resolved
output to wire form (string keys, plain maps, atoms-as-strings).
Summary
Functions
Attaches a lifecycle hook for the given stage.
Detaches a lifecycle hook when one is present.
Runs every hook registered for a stage until one halts or all continue.
Returns the required hook function arity for a lifecycle stage.
Returns the supported lifecycle stages in execution order.
Types
@type hook_fun() :: function()
@type hook_id() :: term()
@type hook_result() :: {:cont, Musubi.Socket.t()} | {:halt, Musubi.Socket.t()} | {:halt, term(), Musubi.Socket.t()}
@type hook_table() :: %{optional(stage()) => [hook_entry()]}
@type stage() ::
:before_command
| :after_command
| :handle_async
| :handle_info
| :after_render
| :after_serialize
Functions
@spec attach_hook(Musubi.Socket.t(), hook_id(), stage(), hook_fun()) :: Musubi.Socket.t()
Attaches a lifecycle hook for the given stage.
Examples
iex> socket = %Musubi.Socket{}
iex> socket =
...> Musubi.Lifecycle.attach_hook(socket, :audit, :after_render, fn _output, socket ->
...> {:cont, socket}
...> end)
iex> Musubi.Socket.get_private(socket, :hooks)[:after_render] |> length()
1
@spec detach_hook(Musubi.Socket.t(), hook_id(), stage()) :: Musubi.Socket.t()
Detaches a lifecycle hook when one is present.
Examples
iex> socket =
...> Musubi.Lifecycle.attach_hook(%Musubi.Socket{}, :audit, :after_render, fn _output, socket ->
...> {:cont, socket}
...> end)
iex> socket = Musubi.Lifecycle.detach_hook(socket, :audit, :after_render)
iex> Musubi.Socket.get_private(socket, :hooks)
%{}
@spec run_hooks(Musubi.Socket.t(), stage(), list(), boolean()) :: {:cont, Musubi.Socket.t()} | {:halt, Musubi.Socket.t()} | {:halt, term(), Musubi.Socket.t()}
Runs every hook registered for a stage until one halts or all continue.
Examples
iex> socket =
...> Musubi.Lifecycle.attach_hook(%Musubi.Socket{}, :mark, :after_render, fn _output, socket ->
...> {:cont, Musubi.Socket.assign(socket, :seen?, true)}
...> end)
iex> {:cont, socket} = Musubi.Lifecycle.run_hooks(socket, :after_render, [%{title: "Inbox"}], false)
iex> socket.assigns.seen?
true
@spec stage_arity(stage()) :: 2 | 3 | 4
Returns the required hook function arity for a lifecycle stage.
| Stage | Arity | Hook arguments |
|---|---|---|
:before_command | 3 | (command_name, payload, socket) |
:after_command | 4 | (command_name, payload, reply, socket) |
:handle_async | 3 | (name, async_result, socket) |
:handle_info | 2 | (message, socket) |
:after_render | 2 | (resolved_elixir_term, socket) |
:after_serialize | 2 | (wire_term, socket) |
Examples
iex> Musubi.Lifecycle.stage_arity(:before_command)
3
iex> Musubi.Lifecycle.stage_arity(:after_command)
4
iex> Musubi.Lifecycle.stage_arity(:after_serialize)
2
@spec stages() :: [stage()]
Returns the supported lifecycle stages in execution order.
Examples
iex> Musubi.Lifecycle.stages()
[:before_command, :after_command, :handle_async, :handle_info, :after_render, :after_serialize]