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
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"
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"
@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)
@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}))
@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"}
@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