Filament.Observable.GenServer
(filament v0.2.1)
Copy Markdown
Macro that makes a GenServer observable by Filament components.
use Filament.Observable.GenServer injects:
handle_call({:filament_subscribe, subscriber}, from, state)— subscriber registration; callshandle_subscribe/2(overridable)handle_cast({:filament_remove_projection, owner_pid, proj_key}, state)— projection removal; auto-unsubscribes when the last projection is removedhandle_info({:DOWN, ref, :process, pid, reason}, state)— automatic subscriber cleanup when a LiveView process terminatesnotify_observers/1— call this from your handlers whenever state changes to push raw state to all subscribed components
Subscribers are keyed by owner_pid. All fibers within the same LiveView that
subscribe to the same server share one subscriber entry. Each fiber registers a
named projection key; notify_observers/1 sends one
{:filament_observable_updates, [{fiber_id, slot_index, raw_state}]} message
per subscriber whenever the raw state changes (change-or-bust at subscriber level).
Projection fns run client-side on each re-render, so closures over local component
state (filters, selections, etc.) always see the current value.
Example
defmodule MyApp.Counter do
use Filament.Observable.GenServer
def start_link(opts \\ []) do
GenServer.start_link(__MODULE__, 0, name: Keyword.get(opts, :name, __MODULE__))
end
@impl GenServer
def init(initial), do: {:ok, initial}
@impl Filament.Observable
def handle_subscribe(_subscriber, state) do
{:ok, state, state}
end
@impl GenServer
def handle_call(:increment, _from, count) do
new_count = count + 1
notify_observers(new_count)
{:reply, new_count, new_count}
end
end