Dstar.Page behaviour (dstar v0.1.0-alpha.2)

Copy Markdown View Source

One module per page: render, event handlers, stream callbacks, and colocated function components.

defmodule MyAppWeb.CounterPage do
  use Dstar.Page

  def mount(conn, _params), do: assign(conn, count: 0)

  def render(assigns) do
    ~H"""
    <div data-signals:count={@count}>
      <button data-on:click={event("increment")}>+1</button>
    </div>
    """
  end

  def handle_event(conn, "increment", signals) do
    patch_signals(conn, %{count: (signals["count"] || 0) + 1})
  end
end

Route it with Dstar.Router.dstar/2:

import Dstar.Router
dstar "/counter", MyAppWeb.CounterPage

All requests are driven by Dstar.Page.Plug — pages contain no control flow, only callbacks. Conn in, conn out.

Options

  • :idle_check — ms between connection liveness checks in the stream loop (default 30_000).

Summary

Callbacks

Stream open: subscribe to topics, assign loop state. Optional — defining it enables POST /path streaming.

Handles a Datastar event POST. SSE is already started. Optional.

Handles one message from the library-owned receive loop. Optional.

GET: load data and assign what render/1 needs. Optional.

The full-page HEEx template. Required.

If defined, the stream opens via Dstar.start_stream/2 keyed on the result. Optional.

Callbacks

handle_connect(t, params)

(optional)
@callback handle_connect(Plug.Conn.t(), params :: map()) :: Plug.Conn.t()

Stream open: subscribe to topics, assign loop state. Optional — defining it enables POST /path streaming.

handle_event(t, event, signals)

(optional)
@callback handle_event(Plug.Conn.t(), event :: String.t(), signals :: map()) ::
  Plug.Conn.t()

Handles a Datastar event POST. SSE is already started. Optional.

handle_info(msg, t)

(optional)
@callback handle_info(msg :: term(), Plug.Conn.t()) ::
  Plug.Conn.t() | {:halt, Plug.Conn.t()}

Handles one message from the library-owned receive loop. Optional.

mount(t, params)

(optional)
@callback mount(Plug.Conn.t(), params :: map()) :: Plug.Conn.t()

GET: load data and assign what render/1 needs. Optional.

render(assigns)

@callback render(assigns :: map()) :: Phoenix.LiveView.Rendered.t()

The full-page HEEx template. Required.

stream_key(t)

(optional)
@callback stream_key(Plug.Conn.t()) :: term()

If defined, the stream opens via Dstar.start_stream/2 keyed on the result. Optional.