Liking cljdoc? Tell your friends :D

co.multiply.tropical.shared

State on the server that islands share across sessions: every island that reads a state with the same key reads one value, and renders again when it changes. It sits between what an island keeps, which a page load ends, and a def, which nothing ends.

(defshared toasts
  "The toasts a user's tabs show."
  {:init []})

(defisland toast-list
  []
  (let [{:keys [uid]} (island/use-session)
        [messages swap-messages!] (use-shared toasts uid)]
    [:ul (for [m messages] [:li (:text m)])]))

;; Anywhere: an action, a resource, a task of the app's own.
(shared/swap! toasts uid conj {:text "Saved."})

The key decides how shared a state is: a user's id makes it the user's, in every tab and across page loads; a document's id makes it everyone's who has the document open; nil, everyone's.

An instance, a state with a key, is created with the state's :init by the first island to read it, ready in that render. It is held while any island reads it, in any session, and lingers after the last stops, as a resource does (co.multiply.tropical.resource, whose registry holds it), so a page load finds it as the last page left it. Then it is gone, and a swap! finds nothing to change.

It lives in this JVM's memory: a restart loses it, and each server behind a balancer holds its own. What must last, or reach a user wherever they are connected, belongs in a database or a stream the app reads with observe.

The key is the access: whoever reads a state with a key reads its value. Build it from what the session vouches for, such as use-session's :uid, never from signals or an action's value.

State on the server that islands share across sessions: every island that
reads a state with the same key reads one value, and renders again when it
changes. It sits between what an island keeps, which a page load ends, and a
`def`, which nothing ends.

    (defshared toasts
      "The toasts a user's tabs show."
      {:init []})

    (defisland toast-list
      []
      (let [{:keys [uid]} (island/use-session)
            [messages swap-messages!] (use-shared toasts uid)]
        [:ul (for [m messages] [:li (:text m)])]))

    ;; Anywhere: an action, a resource, a task of the app's own.
    (shared/swap! toasts uid conj {:text "Saved."})

The key decides how shared a state is: a user's id makes it the user's, in
every tab and across page loads; a document's id makes it everyone's who has
the document open; nil, everyone's.

An instance, a state with a key, is created with the state's `:init` by the
first island to read it, ready in that render. It is held while any island
reads it, in any session, and lingers after the last stops, as a resource
does (`co.multiply.tropical.resource`, whose registry holds it), so a page
load finds it as the last page left it. Then it is gone, and a `swap!` finds
nothing to change.

It lives in this JVM's memory: a restart loses it, and each server behind a
balancer holds its own. What must last, or reach a user wherever they are
connected, belongs in a database or a stream the app reads with `observe`.

The key is the access: whoever reads a state with a key reads its value. Build
it from what the session vouches for, such as `use-session`'s `:uid`, never
from signals or an action's value.
raw docstring

defsharedcljmacro

(defshared state-name & decl)

Defines a shared state: (defshared name doc? {:init v, :linger-ms n}). :init is the value of an instance when it is created, nil if absent. :linger-ms is how long an instance outlasts its last reader, by default a resource's (resource/linger-ms): long enough for a page load.

The var is the state's identity, so two states never share an instance, whatever their keys. Evaluated again, as on a reload, it keeps its instances, and a changed :init applies to those created after.

Defines a shared state: `(defshared name doc? {:init v, :linger-ms n})`.
`:init` is the value of an instance when it is created, nil if absent.
`:linger-ms` is how long an instance outlasts its last reader, by default a
resource's (`resource/linger-ms`): long enough for a page load.

The var is the state's identity, so two states never share an instance,
whatever their keys. Evaluated again, as on a reload, it keeps its instances,
and a changed `:init` applies to those created after.
sourceraw docstring

swap!clj

(swap! state key f & args)

Sets the instance of state for key to (apply f value args), if there is one: one an island reads, or one lingering after. Every island reading it renders again. Returns whether there was one: a value no island reads would be seen by nobody, so it is dropped.

f runs once, under the instance's lock: keep it quick.

Sets the instance of `state` for `key` to `(apply f value args)`, if there is
one: one an island reads, or one lingering after. Every island reading it
renders again. Returns whether there was one: a value no island reads would
be seen by nobody, so it is dropped.

`f` runs once, under the instance's lock: keep it quick.
sourceraw docstring

use-sharedclj

(use-shared state)
(use-shared state key)

The instance of state for key, nil if omitted, created with its :init if there is none, and held while the island reads it. Returns [value swap-value!], where (swap-value! f & args) is (swap! state key f & args). The island renders again when the value changes.

key is a value, compared with =: a fresh closure would be a new instance each render. A hook: read again in one render, with an equal key, it returns the same instance.

The instance of `state` for `key`, nil if omitted, created with its `:init`
if there is none, and held while the island reads it. Returns
`[value swap-value!]`, where `(swap-value! f & args)` is
`(swap! state key f & args)`. The island renders again when the value
changes.

`key` is a value, compared with `=`: a fresh closure would be a new instance
each render. A hook: read again in one render, with an equal `key`, it
returns the same instance.
sourceraw docstring

cljdoc builds & hosts documentation for Clojure/Script libraries

Keyboard shortcuts
Ctrl+kJump to recent docs
←Move to previous article
→Move to next article
Ctrl+/Jump to the search field
× close