ScalesCmsWeb.Hooks.PersistedState (scales_cms v0.2.0)

Copy Markdown

Generic LiveView on_mount hook for managing persisted UI state.

This hook manages a named piece of state with two-tier storage:

  1. Session storage - persistence across full page refreshes
  2. ETS storage - persistence across LiveView navigations and reconnects

This is useful for UI state like:

  • sidebar open/closed
  • panel expansion
  • selected tabs
  • layout mode
  • filter drawer visibility

Usage

In the router:

live_session :default,
  on_mount: [
    {ScalesCmsWeb.UserAuth, :ensure_authenticated},
    {ScalesCmsWeb.Hooks.PersistedState,
     [name: :sidebar_open, session_key: "sidebar_open", default: true]}
  ],
  session: {ScalesCmsWeb.Hooks.PersistedState, :copy_session, [["sidebar_open"]]} do
  live "/dashboard", DashboardLive
end

In the LiveView or LiveComponent:

push_event(socket, "update_persisted_state", %{
  "name" => "sidebar_open",
  "value" => false
})

Or send a message:

send(self(), {:update_persisted_state, :sidebar_open, false})

Socket assigns

The hook assigns the state directly under its configured name:

socket.assigns.sidebar_open

It also stores internal metadata in:

socket.assigns.__persisted_state_keys__

Summary

Functions

Copies the given session keys from Plug session into LiveView session.

Gets a named state value from ETS, returning default if missing.

Mounts persisted state.

Returns the stable ETS scope for a socket.

Updates a named state value in ETS.

Functions

copy_session(conn, keys)

Copies the given session keys from Plug session into LiveView session.

Example

live_session :default,
  session: {ScalesCmsWeb.Hooks.PersistedState, :copy_session, [["sidebar_open", "filters_open"]]}

get_state(ets_scope, name, default)

Gets a named state value from ETS, returning default if missing.

on_mount(opts, params, session, socket)

Mounts persisted state.

Expected options:

  • :name - atom assign name, e.g. :sidebar_open
  • :session_key - session key string, e.g. "sidebar_open"
  • :default - default value when nothing is stored
  • :normalize - optional 1-arity function for coercing session values

Example

{ScalesCmsWeb.Hooks.PersistedState,
 [name: :sidebar_open, session_key: "sidebar_open", default: true]}

stable_scope(socket)

Returns the stable ETS scope for a socket.

Authenticated users get a stable user-based scope. Unauthenticated users fall back to a socket-based scope.

update_state(ets_scope, name, value)

Updates a named state value in ETS.