Client-side Datastar signals for hyper.
Signals are reactive client-side variables backed by Datastar's signal system. They integrate with hyper's server-rendered model:
Local signals (prefixed with underscore in Datastar) are client-only: they cannot be read or written from the server.
Client-side Datastar signals for hyper. Signals are reactive client-side variables backed by Datastar's signal system. They integrate with hyper's server-rendered model: - During render, deref returns a Datastar expression string (e.g. "$userName") suitable for use in data-text, data-show, data-bind, etc. - During action execution, deref returns the live value sent by Datastar in the @post() request body. - reset! / swap! update the signal value in tab state, which triggers a datastar-patch-signals SSE event on the next render cycle. Local signals (prefixed with underscore in Datastar) are client-only: they cannot be read or written from the server.
(any-signal? x)True when x is any signal object — Signal, LocalSignal, or Optimistic.
True when x is any signal object — Signal, LocalSignal, or Optimistic.
(auto-commit! app-state* tab-id signals)Commit the client-reported value for every registered auto-commit optimistic whose signal rode this request's signals map.
Commit the client-reported value for every registered auto-commit optimistic whose signal rode this request's signals map.
(base-sig-path sig-path)The companion base-signal path for a derived signal path. :session-col-w → :session-col-w-base ($sessionColWBase).
The companion base-signal path for a derived signal path. :session-col-w → :session-col-w-base ($sessionColWBase).
(changed-signals old-signals new-signals)Return a map of signal names whose values differ between old-signals and new-signals. Values are taken from new-signals. Signals present in old-signals but absent from new-signals are included with nil values (Datastar removes signals set to null).
Return a map of signal names whose values differ between old-signals and new-signals. Values are taken from new-signals. Signals present in old-signals but absent from new-signals are included with nil values (Datastar removes signals set to null).
(clj->js-literal v)Convert a Clojure value to a JavaScript literal string suitable for use in Datastar expressions and data-signals attributes.
Convert a Clojure value to a JavaScript literal string suitable for use in Datastar expressions and data-signals attributes.
(commit! o)Make the client-reported value of an optimistic official: run its conflict policy and write the result to the backing cursor. Returns the committed value. Action-only.
Make the client-reported value of an optimistic official: run its conflict policy and write the result to the backing cursor. Returns the committed value. Action-only.
Static client-only boolean signal: true while the SSE connection is healthy.
Sugar for the common case; equivalent to (= @connection* :open).
[:div {:data-show (h/expr (not @h/connected?*))} "Offline"]
Static client-only boolean signal: true while the SSE connection is healthy.
Sugar for the common case; equivalent to `(= @connection* :open)`.
[:div {:data-show (h/expr (not @h/connected?*))} "Offline"]Static client-only signal holding the current SSE connection status as a
keyword token (one of connection-states). Client-maintained from
Datastar's fetch lifecycle.
Compare it with keyword tokens in render/expr — keywords compile to the same JS string the wire uses:
[:span {:data-show (h/expr (= @h/connection* :reconnecting))} "Reconnecting…"]
Static client-only signal holding the current SSE connection status as a
keyword token (one of `connection-states`). Client-maintained from
Datastar's fetch lifecycle.
Compare it with keyword tokens in render/expr — keywords compile to the
same JS string the wire uses:
[:span {:data-show (h/expr (= @h/connection* :reconnecting))} "Reconnecting…"](connection-attrs)Hiccup attribute map for the page <body> that declares the client-only
connection signals (with their defaults) and wires Datastar's fetch
lifecycle to keep them current. Returns a map merged into the body attrs
by the page scaffolding.
Hiccup attribute map for the page `<body>` that declares the client-only connection signals (with their defaults) and wires Datastar's fetch lifecycle to keep them current. Returns a map merged into the body attrs by the page scaffolding.
The set of connection status tokens connection* can hold.
:open-when-hidden? false)The set of connection status tokens `connection*` can hold.
- :connecting — first connection attempt in progress (initial paint)
- :open — connected and streaming
- :reconnecting — dropped; Datastar is retrying
- :error — retries exhausted / terminal failure
- :closed — intentionally closed (e.g. a hidden tab under
`:open-when-hidden? false`)(create-local-signal path default-val)Create a LocalSignal for the given path. Local signals are client-only (underscore-prefixed in Datastar) and cannot be read or written from the server.
Create a LocalSignal for the given path. Local signals are client-only (underscore-prefixed in Datastar) and cannot be read or written from the server.
(create-optimistic app-state* tab-id cursor opts)Create an Optimistic pairing a scoped cursor with a derived client signal, registering the signal declaration and the pairing in tab state.
Create an Optimistic pairing a scoped cursor with a derived client signal, registering the signal declaration and the pairing in tab state.
(create-signal app-state* tab-id path default-val)Create a Signal for the given path and register it in tab state and the render-time declaration accumulator.
Create a Signal for the given path and register it in tab state and the render-time declaration accumulator.
(current-value sig)The signal's current server-side value from tab state, falling back to its default. Used to seed signal-linked component attributes on first paint, before Datastar's reactive attributes take over.
The signal's current server-side value from tab state, falling back to its default. Used to seed signal-linked component attributes on first paint, before Datastar's reactive attributes take over.
(derived-signal-path scope path)The flat signal path derived from a cursor's scope and logical path. (:session, [:cols 0 :width]) → :session-cols-0-width ($sessionCols0Width).
The flat signal path derived from a cursor's scope and logical path. (:session, [:cols 0 :width]) → :session-cols-0-width ($sessionCols0Width).
(drop-ifmissing-covered-patches sig-patches declared-signals sent-signals)Return the signal patches still worth sending after dropping those the
body fragment's data-signals:NAME__ifmissing declarations already
cover on a fresh client.
The body fragment declares each signal via
data-signals:NAME__ifmissing=DEFAULT, which initializes the signal to
DEFAULT when the client does not already have it. A patch leaf is kept
only when it adds information the declaration cannot supply: the signal
was already sent to the client before (present in sent-signals), or
its value differs from the declared default. Dropping the rest lets
Datastar keep state it materializes from the DOM — e.g. a checkbox group
whose array signal Datastar builds from the checkboxes (issue #44).
Suppression is per declared signal path, so both top-level and nested signals are covered; branches emptied by a drop are pruned.
sig-patches map of {kebab-keyword → value} about to be sentdeclared-signals declared-signal maps for this rendersent-signals signals the client already holds — last sent merged
with client-reported (nil on first render)Return the signal patches still worth sending after dropping those the
body fragment's `data-signals:NAME__ifmissing` declarations already
cover on a fresh client.
The body fragment declares each signal via
`data-signals:NAME__ifmissing=DEFAULT`, which initializes the signal to
DEFAULT when the client does not already have it. A patch leaf is kept
only when it adds information the declaration cannot supply: the signal
was already sent to the client before (present in `sent-signals`), or
its value differs from the declared default. Dropping the rest lets
Datastar keep state it materializes from the DOM — e.g. a checkbox group
whose array signal Datastar builds from the checkboxes (issue #44).
Suppression is per declared signal path, so both top-level and nested
signals are covered; branches emptied by a drop are pruned.
- `sig-patches` map of {kebab-keyword → value} about to be sent
- `declared-signals` declared-signal maps for this render
- `sent-signals` signals the client already holds — last sent merged
with client-reported (nil on first render)(format-patch-signals-event signal-patches)Format a map of {kebab-keyword → value} as a Datastar datastar-patch-signals SSE event. Keys are converted to camelCase strings for the wire format. Nil values become JSON null (Datastar removes signals set to null).
Format a map of {kebab-keyword → value} as a Datastar
datastar-patch-signals SSE event. Keys are converted to
camelCase strings for the wire format. Nil values become
JSON null (Datastar removes signals set to null).(format-signal-attrs declared-signals)Build a hiccup attribute map declaring signals on an element using data-signals:NAME__ifmissing attributes.
declared-signals is a sequence of maps with :html-name, :default-val, and :local? keys.
Build a hiccup attribute map declaring signals on an element using data-signals:NAME__ifmissing attributes. declared-signals is a sequence of maps with :html-name, :default-val, and :local? keys.
(js-name sig)The signal's Datastar JS name, e.g. "userName", "user.name" or "_open" (local signals carry their underscore prefix).
The signal's Datastar JS name, e.g. "userName", "user.name" or "_open" (local signals carry their underscore prefix).
(js-ref sig)The Datastar expression reference for a signal, e.g. "$userName".
The Datastar expression reference for a signal, e.g. "$userName".
(local-signal? x)True when x is a client-only (underscore-prefixed) local signal.
True when x is a client-only (underscore-prefixed) local signal.
(optimistic-signal o)The client Signal paired inside an Optimistic.
The client Signal paired inside an Optimistic.
(optimistic? x)True when x is an Optimistic (a cursor paired with a client signal).
True when x is an Optimistic (a cursor paired with a client signal).
(parse-signals json-str)Parse a JSON signal body from a Datastar @post() request, converting camelCase keys to kebab-case keywords recursively. Returns a keyword-keyed map or nil.
Parse a JSON signal body from a Datastar @post() request, converting camelCase keys to kebab-case keywords recursively. Returns a keyword-keyed map or nil.
(resolve-commit policy {:keys [base committed reported] :as ctx})The value to commit for an optimistic, given its conflict policy and the commit context {:base :committed :reported}. A commit is clean when base = committed; a nil base with a differing committed value counts as a conflict (unknown base cannot prove freshness).
The value to commit for an optimistic, given its conflict policy and the
commit context {:base :committed :reported}. A commit is clean when
base = committed; a nil base with a differing committed value counts as
a conflict (unknown base cannot prove freshness).(signal-html-name path)Convert a keyword or keyword vector path to the HTML attribute suffix for data-signals. Datastar auto-converts hyphens to camelCase. :user-name → "user-name" [:user :name] → "user.name" [:user-profile :first-name] → "user-profile.first-name"
Convert a keyword or keyword vector path to the HTML attribute suffix for data-signals. Datastar auto-converts hyphens to camelCase. :user-name → "user-name" [:user :name] → "user.name" [:user-profile :first-name] → "user-profile.first-name"
(signal-js-name path)Convert a keyword or keyword vector path to the Datastar signal JS name. :user-name → "userName" [:user :name] → "user.name" [:user-profile :first-name] → "userProfile.firstName"
Convert a keyword or keyword vector path to the Datastar signal JS name. :user-name → "userName" [:user :name] → "user.name" [:user-profile :first-name] → "userProfile.firstName"
(signal? x)True when x is a (non-local) Datastar signal.
True when x is a (non-local) Datastar signal.
cljdoc builds & hosts documentation for Clojure/Script libraries
| Ctrl+k | Jump to recent docs |
| ← | Move to previous article |
| → | Move to next article |
| Ctrl+/ | Jump to the search field |