Dstar.Signals (dstar v0.1.0-alpha.2)

Copy Markdown View Source

Functions for reading and patching Datastar signals via SSE.

signals = Dstar.Signals.read(conn)
conn |> patch(%{count: 42, message: "Hello"})
conn |> patch(%{count: 42}, only_if_missing: true)
conn |> remove_signals("user.session")

Summary

Functions

Formats a signals patch as an SSE event string (for stateless responses).

Formats a signal removal as an SSE event string (for stateless responses).

Patches signals on the client by sending an SSE event.

Patches signals using a raw JSON string.

Reads signals from a Plug connection.

Removes signals from the client by setting them to nil.

Functions

format_patch(signals, opts \\ [])

@spec format_patch(
  map(),
  keyword()
) :: String.t()

Formats a signals patch as an SSE event string (for stateless responses).

Example

format_patch(%{count: 42})
# => "event: datastar-patch-signals\ndata: signals {\"count\":42}\n\n"

format_remove(paths, opts \\ [])

@spec format_remove(
  String.t() | [String.t()],
  keyword()
) :: String.t()

Formats a signal removal as an SSE event string (for stateless responses).

Examples

format_remove("user.profile")
# => "event: datastar-patch-signals\ndata: signals {\"user\":{\"profile\":null}}\n\n"

format_remove(["user.a", "user.b"])
# => "event: datastar-patch-signals\ndata: signals {\"user\":{\"a\":null,\"b\":null}}\n\n"

patch(conn, signals, opts \\ [])

@spec patch(Plug.Conn.t(), map(), keyword()) :: Plug.Conn.t()

Patches signals on the client by sending an SSE event.

Options

  • :only_if_missing - Only patch signals that don't exist on the client (default: false)
  • :event_id - Event ID for client tracking
  • :retry - Retry duration in milliseconds

Example

conn
|> Dstar.Signals.patch(%{count: 42})
|> Dstar.Signals.patch(%{message: "Hello"}, only_if_missing: true)

patch_raw(conn, json, opts \\ [])

@spec patch_raw(Plug.Conn.t(), String.t(), keyword()) :: Plug.Conn.t()

Patches signals using a raw JSON string.

Example

conn
|> Dstar.Signals.patch_raw(~s({"count": 42}))

read(conn)

@spec read(Plug.Conn.t()) :: map()

Reads signals from a Plug connection.

For GET and DELETE requests, reads from query parameters under the "datastar" key. For other methods, reads from the JSON request body. This matches Datastar v1.0's behavior, where GET and DELETE requests do not carry a body.

Returns a map of signals or an empty map if no signals are present.

Example

signals = Dstar.Signals.read(conn)
# => %{"count" => 10, "message" => "Hello"}

remove_signals(conn, paths, opts \\ [])

@spec remove_signals(Plug.Conn.t(), String.t() | [String.t()], keyword()) ::
  Plug.Conn.t()

Removes signals from the client by setting them to nil.

Accepts a single dot-notated path string or a list of paths. Paths are converted to a nested map with nil values, then passed to patch/3.

Examples

# Remove a single signal
conn |> remove_signals("user.profile.theme")

# Remove multiple signals with shared prefix
conn |> remove_signals(["user.name", "user.email"])

# Remove top-level signal
conn |> remove_signals("count")

Options

  • :only_if_missing - Only remove if signal doesn't exist (default: false)
  • :event_id - Event ID for client tracking
  • :retry - Retry duration in milliseconds