Packages
phoenix_live_state
0.1.0
PhoenixLiveState enables LiveView processes to share reactive state across a cluster of nodes. Attach LiveViews to a state server and get automatic assign synchronization.
Current section
Files
Jump to
Current section
Files
lib/phoenix_live_state/state_server.ex
defmodule PhoenixLiveState.StateServer do
@moduledoc """
Client API for the state server implementation.
"""
@moduledoc since: "0.1.0"
alias PhoenixLiveState.StateServer.Settings
alias PhoenixLiveState.StateSpec
def child_spec(opts) do
%{
id: __MODULE__,
start: {__MODULE__, :start_link, [opts]},
type: :worker,
restart: :permanent,
shutdown: 500
}
end
@doc """
Starts a new state server with the given key and options.
"""
@doc since: "0.1.0"
def start_link(start_opts) when is_list(start_opts) do
key = Keyword.fetch!(start_opts, :key)
state_spec = Keyword.fetch!(start_opts, :state_spec)
init_opts =
if is_atom(state_spec) do
case StateSpec.mount(state_spec, key) do
{:ok, spec} ->
[
key: key,
initial_state: spec.initial_state || %{},
state_spec: state_spec,
settings: Settings.new(spec)
]
error ->
raise "Could not initialize state server: #{inspect(error)}"
end
else
start_opts
end
GenServer.start_link(__MODULE__.ServerImpl, init_opts, name: process_name(key))
end
@doc """
Attaches the current pid to the given state server.
"""
@doc since: "0.1.0"
def attach(key) do
key
|> process_name()
|> GenServer.call(:attach)
end
@doc """
Returns the value of the given property from the state server.
If no property is given, returns the entire state.
"""
@doc since: "0.1.0"
def get(key, property \\ nil) do
key
|> process_name()
|> GenServer.call({:get, property})
end
@doc """
Puts a new key-value pair into the state server.
If the key already exists, the value will be updated.
"""
@doc since: "0.1.0"
def put(key, property_name, property_value) do
key
|> process_name()
|> GenServer.call({:put, property_name, property_value})
end
@doc """
Deletes the given property from the state server.
If no property is given, deletes the entire state.
"""
@doc since: "0.1.0"
def delete(key, property_name) do
key
|> process_name()
|> GenServer.call({:delete, property_name})
end
@doc """
Resets the server to the initial state, if a state init function is available.
"""
@doc since: "0.1.0"
def reset(key) do
key
|> process_name()
|> GenServer.call(:reset)
end
defp process_name(key) do
{:global, {__MODULE__, key}}
end
end