Compile-time DSL entrypoint, behaviour contract, and runtime facade for Musubi store modules.
Stores use Musubi.Store and implement init/1, render/1,
update/2, handle_command/3, handle_async/3, handle_info/2,
and terminate/2. Root stores opt in with use Musubi.Store, root: true
and may also implement mount/2 to receive client mount params before
init/1 runs.
render/1 returns the resolved Elixir-shaped term; wire conversion happens
separately via Musubi.Wire.to_wire/1.
Runtime facade
use Musubi.Store blanket-imports this module so every helper below is
available bare inside a store's callbacks. Each helper is a defdelegate
to the underlying implementation module (Musubi.Socket, Musubi.Stream,
Musubi.Lifecycle, Musubi.Child, Musubi.DSL.Render) or a defmacro
that lowers to a runtime call (the async lifecycle helpers).
| Surface | Helpers |
|---|---|
| Socket | assign/2,3, assign_new/3, update/3, changed?/2, get_private/2,3, put_private/3 |
| Streams | stream/3,4, stream_configure/3, stream_insert/3,4, stream_delete/3, stream_delete_by_item_key/3 |
| Lifecycle | attach_hook/4, detach_hook/3 |
| Async | assign_async/3,4, start_async/3,4, stream_async/3,4, cancel_async/2,3 |
| Render builders | child/2, stream/1, async_stream/1 |
The fully-qualified module forms remain available — the facade is purely
additive — so Musubi.Socket.assign(...) keeps working alongside the bare
assign(...) form preferred inside store modules.
Summary
Callbacks
Handles an async result routed to the current store.
Handles a declared command for the current store.
Handles an in-process message routed to the current store.
Optional. Invoked when a chunk has been received (channel mode) or a
client upload_progress message arrived (external mode) for an
upload-tracked entry.
Initializes a freshly-created store socket.
Initializes a freshly-mounted store socket.
Mounts a root store with client-supplied params.
Produces the resolved Elixir-shaped render output for the current store.
Handles store teardown after the page runtime begins terminating.
Updates a mounted store socket from new parent-supplied assigns.
Optional. When defined for an upload name, the preflight switches to
external mode and forwards the returned meta map to the client
uploader. Musubi treats meta opaquely.
Functions
See Musubi.Async.assign_async/3,4.
See Musubi.DSL.Render.async_stream/1. Render-time placeholder.
See Musubi.Async.cancel_async/2,3.
Cancels a single upload entry by ref, emitting {op: cancel}.
Consumes the completed upload entries for name via fun.
See Musubi.Async.start_async/3,4.
See Musubi.DSL.Render.stream/1. Render-time placeholder.
See Musubi.Async.stream_async/3,4.
Returns {completed, in_progress} for the upload named name.
Types
@type assigns() :: %{optional(Musubi.Socket.assign_key()) => value()}
@type async_name() :: Musubi.Async.name_arg()
@type command_name() :: atom()
@type command_reply() :: map()
@type message() :: value()
Callbacks
@callback handle_async( name :: async_name(), async_fun_result :: async_result(), socket :: Musubi.Socket.t() ) :: {:noreply, Musubi.Socket.t()}
Handles an async result routed to the current store.
@callback handle_command( name :: command_name(), payload :: command_payload(), socket :: Musubi.Socket.t() ) :: {:noreply, Musubi.Socket.t()} | {:reply, command_reply(), Musubi.Socket.t()}
Handles a declared command for the current store.
@callback handle_info(message :: message(), socket :: Musubi.Socket.t()) :: {:noreply, Musubi.Socket.t()}
Handles an in-process message routed to the current store.
@callback handle_progress( name :: atom(), entry :: Musubi.Upload.Entry.t(), socket :: Musubi.Socket.t() ) :: {:noreply, Musubi.Socket.t()}
Optional. Invoked when a chunk has been received (channel mode) or a
client upload_progress message arrived (external mode) for an
upload-tracked entry.
@callback init(socket :: Musubi.Socket.t()) :: {:ok, Musubi.Socket.t()}
Initializes a freshly-created store socket.
@callback mount(socket :: Musubi.Socket.t()) :: {:ok, Musubi.Socket.t()}
Initializes a freshly-mounted store socket.
This callback is kept for compatibility with pre-session stores. Prefer
init/1 for child stores and mount/2 for root-only client params.
@callback mount(params :: root_params(), socket :: Musubi.Socket.t()) :: {:ok, Musubi.Socket.t()}
Mounts a root store with client-supplied params.
Only modules declared with use Musubi.Store, root: true receive this
callback. Child stores use init/1.
@callback render(socket :: Musubi.Socket.t()) :: rendered()
Produces the resolved Elixir-shaped render output for the current store.
The returned term is still in Musubi's Elixir form. The runtime converts it
to wire form later with Musubi.Wire.to_wire/1.
@callback terminate(reason :: terminate_reason(), socket :: Musubi.Socket.t()) :: :ok
Handles store teardown after the page runtime begins terminating.
@callback update(assigns :: assigns(), socket :: Musubi.Socket.t()) :: {:ok, Musubi.Socket.t()}
Updates a mounted store socket from new parent-supplied assigns.
@callback upload_external( name :: atom(), entry :: Musubi.Upload.Entry.t(), socket :: Musubi.Socket.t() ) :: {:ok, map(), Musubi.Socket.t()}
Optional. When defined for an upload name, the preflight switches to
external mode and forwards the returned meta map to the client
uploader. Musubi treats meta opaquely.
Functions
See Musubi.Async.assign_async/3,4.
See Musubi.DSL.Render.async_stream/1. Render-time placeholder.
See Musubi.Async.cancel_async/2,3.
Cancels a single upload entry by ref, emitting {op: cancel}.
See Musubi.Child.child/2.
Consumes the completed upload entries for name via fun.
fun receives (meta, entry) where meta is %{path: path} in
channel mode or %{external: meta} in external mode. Returns
{:ok, val} to consume the entry (removing it from internal state)
or {:postpone, val} to leave it in place.
Returns the updated socket and the list of vals produced.
Must be called from a command handler.
See Musubi.Async.start_async/3,4.
See Musubi.DSL.Render.stream/1. Render-time placeholder.
See Musubi.Async.stream_async/3,4.
Returns {completed, in_progress} for the upload named name.
Examples
{completed, _in_progress} = uploaded_entries(socket, :avatar)