LiveStash (LiveStash v0.1.2)

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
end

Stash assigns after state-changing events:

def handle_event("increment", _, socket) do
  socket
  |> assign(:count, socket.assigns.count + 1)
  |> LiveStash.stash_assigns([:count])
  |> 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 the specified assigns from socket.assigns.

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_assigns(socket, keys)

@spec stash_assigns(socket :: Phoenix.LiveView.Socket.t(), keys :: [atom()]) ::
  Phoenix.LiveView.Socket.t()

Stashes the specified assigns from socket.assigns.

Every key must be an atom and should exist in socket.assigns. Call this after assign updates to keep persisted state in sync.

Examples

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