Musubi.Store behaviour (musubi v0.1.0)

Copy Markdown View Source

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).

SurfaceHelpers
Socketassign/2,3, assign_new/3, update/3, changed?/2, get_private/2,3, put_private/3
Streamsstream/3,4, stream_configure/3, stream_insert/3,4, stream_delete/3, stream_delete_by_item_key/3
Lifecycleattach_hook/4, detach_hook/3
Asyncassign_async/3,4, start_async/3,4, stream_async/3,4, cancel_async/2,3
Render builderschild/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.

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.

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.

See Musubi.Async.start_async/3,4.

See Musubi.DSL.Render.stream/1. Render-time placeholder.

See Musubi.Async.stream_async/3,4.

Types

assigns()

@type assigns() :: %{optional(Musubi.Socket.assign_key()) => value()}

async_name()

@type async_name() :: Musubi.Async.name_arg()

async_result()

@type async_result() :: {:ok, value()} | {:exit, value()}

command_name()

@type command_name() :: atom()

command_payload()

@type command_payload() :: %{optional(String.t() | atom()) => value()}

command_reply()

@type command_reply() :: map()

message()

@type message() :: value()

rendered()

@type rendered() ::
  nil
  | boolean()
  | number()
  | String.t()
  | atom()
  | [rendered()]
  | %{optional(String.t() | atom()) => rendered()}

root_params()

@type root_params() :: %{optional(String.t()) => value()}

terminate_reason()

@type terminate_reason() :: :normal | :shutdown | {:shutdown, value()} | value()

value()

@type value() ::
  nil
  | boolean()
  | number()
  | String.t()
  | atom()
  | pid()
  | reference()
  | port()
  | tuple()
  | [value()]
  | %{optional(value()) => value()}

Callbacks

handle_async(name, async_fun_result, socket)

(optional)
@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.

handle_command(name, payload, socket)

@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.

handle_info(message, socket)

(optional)
@callback handle_info(message :: message(), socket :: Musubi.Socket.t()) ::
  {:noreply, Musubi.Socket.t()}

Handles an in-process message routed to the current store.

init(socket)

(optional)
@callback init(socket :: Musubi.Socket.t()) :: {:ok, Musubi.Socket.t()}

Initializes a freshly-created store socket.

mount(socket)

(optional)
@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.

mount(params, socket)

(optional)
@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.

render(socket)

@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.

terminate(reason, socket)

(optional)
@callback terminate(reason :: terminate_reason(), socket :: Musubi.Socket.t()) :: :ok

Handles store teardown after the page runtime begins terminating.

update(assigns, socket)

(optional)
@callback update(assigns :: assigns(), socket :: Musubi.Socket.t()) ::
  {:ok, Musubi.Socket.t()}

Updates a mounted store socket from new parent-supplied assigns.

Functions

assign(socket, attrs)

See Musubi.Socket.assign/2.

assign(socket, key, value)

See Musubi.Socket.assign/3.

assign_async(socket, key_or_keys, fun)

(macro)

See Musubi.Async.assign_async/3,4.

assign_async(socket, key_or_keys, fun, opts)

(macro)

assign_new(socket, key, fun)

See Musubi.Socket.assign_new/3.

async_stream(name)

(macro)

See Musubi.DSL.Render.async_stream/1. Render-time placeholder.

attach_hook(socket, name, stage, fun)

See Musubi.Lifecycle.attach_hook/4.

cancel_async(socket, target)

See Musubi.Async.cancel_async/2,3.

cancel_async(socket, target, reason)

See Musubi.Async.cancel_async/3.

changed?(socket, key)

See Musubi.Socket.changed?/2.

child(module, opts)

See Musubi.Child.child/2.

detach_hook(socket, name, stage)

See Musubi.Lifecycle.detach_hook/3.

get_private(socket, key, default \\ nil)

See Musubi.Socket.get_private/3.

put_private(socket, key, value)

See Musubi.Socket.put_private/3.

start_async(socket, name, fun)

(macro)

See Musubi.Async.start_async/3,4.

start_async(socket, name, fun, opts)

(macro)

stream(name)

(macro)

See Musubi.DSL.Render.stream/1. Render-time placeholder.

stream(socket, name, items, opts \\ [])

See Musubi.Stream.stream/4.

stream_async(socket, name, fun)

(macro)

See Musubi.Async.stream_async/3,4.

stream_async(socket, name, fun, opts)

(macro)

stream_configure(socket, name, opts)

See Musubi.Stream.stream_configure/3.

stream_delete(socket, name, item)

See Musubi.Stream.stream_delete/3.

stream_delete_by_item_key(socket, name, item_key)

See Musubi.Stream.stream_delete_by_item_key/3.

stream_insert(socket, name, item, opts \\ [])

See Musubi.Stream.stream_insert/4.

update(socket, key, fun)

See Musubi.Socket.update/3.