LiveStash (LiveStash v0.2.0)

Copy Markdown View Source

Main public API for stashing and recovering Phoenix.LiveView assigns.

LiveStash helps preserve selected server-side assigns across reconnects. You explicitly choose which assigns to persist and when to persist them.

This module:

  • integrates with on_mount via use LiveStash
  • initializes the selected adapter
  • delegates persistence and recovery operations to that adapter

Quick start

Add use LiveStash to your LiveView:

defmodule MyAppWeb.CounterLive do
  use MyAppWeb, :live_view
  use LiveStash, stored_keys: [:count]
end

Stash assigns after state-changing events:

def handle_event("increment", _, socket) do
  socket
  |> assign(:count, socket.assigns.count + 1)
  |> LiveStash.stash()
  |> then(&{:noreply, &1})
end

Recover stashed state in mount/3:

def mount(_params, _session, socket) do
  socket
  |> LiveStash.recover_state()
  |> case do
    {:recovered, recovered_socket} ->
      # socket with previously stashed assigns is recovered
      recovered_socket

    {_, socket} ->
      # could not recover assigns, proceed with standard setup using returned socket
      # ...
  end
  |> then(&{:ok, &1})
end

Recovery statuses

recover_state/1 returns {status, socket} where status is one of:

  • :new - fresh LiveView process, with no previously stashed state
  • :recovered - state was found and applied
  • :not_found - state was not found for this LiveView
  • :error - adapter failed to recover state

Adapter selection

The default adapter is LiveStash.Adapters.BrowserMemory. You can override it per LiveView:

use LiveStash, adapter: LiveStash.Adapters.ETS

Adapters used by your app must also be enabled in config:

config :live_stash,
  adapters: [LiveStash.Adapters.BrowserMemory, LiveStash.Adapters.ETS]

Summary

Functions

Injects LiveStash support into a Phoenix.LiveView. This macro expands to

Initializes stash support for a socket using the configured adapter.

LiveView on_mount callback used by use LiveStash.

Recovers previously stashed state and returns {status, socket}.

Clears stashed state for the current LiveView socket.

Stashes assigns from socket.assigns declared at the module level.

Types

recovery_status()

@type recovery_status() :: :recovered | :not_found | :new | :error

Functions

__using__(opts)

(macro)

Injects LiveStash support into a Phoenix.LiveView. This macro expands to:

on_mount({LiveStash, opts})

so that LiveStash can initialize stash handling during the LiveView mount/3 lifecycle.

Options

The opts are forwarded to LiveStash.on_mount/4 and ultimately to the configured adapter. Most adapters use :adapter to select the persistence backend:

use LiveStash, adapter: LiveStash.Adapters.ETS

Note: adapters must also be enabled in config :live_stash, :adapters.

Example

defmodule MyAppWeb.CounterLive do
  use MyAppWeb, :live_view
  use LiveStash, adapter: LiveStash.Adapters.BrowserMemory
end

init_stash(socket, session, opts \\ [])

@spec init_stash(
  socket :: Phoenix.LiveView.Socket.t(),
  session :: Keyword.t(),
  opts :: Keyword.t()
) ::
  Phoenix.LiveView.Socket.t()

Initializes stash support for a socket using the configured adapter.

This function is called from on_mount/4. In normal usage, prefer use LiveStash and do not call this function directly.

It validates that the selected adapter is active in config :live_stash, :adapters.

on_mount(opts, params, session, socket)

LiveView on_mount callback used by use LiveStash.

It initializes stash handling for the current socket and continues the mount lifecycle.

recover_state(socket)

@spec recover_state(socket :: Phoenix.LiveView.Socket.t()) ::
  {recovery_status(), Phoenix.LiveView.Socket.t()}

Recovers previously stashed state and returns {status, socket}.

This function is typically called in mount/3. Recovery does not clear the stored state; use reset_stash/1 when you want to remove it explicitly.

Examples

def mount(_params, _session, socket) do
  socket
  |> LiveStash.recover_state()
  |> case do
    {:recovered, recovered_socket} ->
      recovered_socket

    {_, socket} ->
      start_new_game(socket)
  end
  |> then(&{:ok, &1})
end

reset_stash(socket)

@spec reset_stash(socket :: Phoenix.LiveView.Socket.t()) ::
  Phoenix.LiveView.Socket.t()

Clears stashed state for the current LiveView socket.

Examples

def handle_event("restart_game", _params, socket) do
  socket
  |> LiveStash.reset_stash()
  |> start_new_game()
  |> then(&{:noreply, &1})
end

stash(socket)

Stashes assigns from socket.assigns declared at the module level.

Examples

use LiveStash, stored_keys: [:count, :username] # assigns are declared at the module level

def handle_event("increment", _, socket) do
  socket
  |> assign(:count, socket.assigns.count + 1)
  |> LiveStash.stash()
  |> then(&{:noreply, &1})
end