Liking cljdoc? Tell your friends :D

dev.zeko.stube.core

Public API of the stube framework.

Most users only need this namespace. It re-exports the small set of functions that are intended to be called from application code; the internals live in dev.zeko.stube.kernel, dev.zeko.stube.conversation, dev.zeko.stube.registry, dev.zeko.stube.render, dev.zeko.stube.http and dev.zeko.stube.server.

────────────────────────────────────────────────────────────────────── At a glance ──────────────────────────────────────────────────────────────────────

(require '[dev.zeko.stube.core :as s])

(s/defcomponent :ui/prompt
  :init   (fn [{:keys [text]}] {:text text :answer ""})
  :keep   #{:answer}
  :render (fn [self]
            [:form (s/root-attrs self (s/on self :submit))
             [:label (:text self)]
             [:input (merge {:name "answer"} (s/bind :answer))]
             [:button "OK"]])
  :handle (fn [self _]
            [(s/answer (parse-long (:answer self)))]))

(s/defcomponent :demo/guess
  :init   (fn [_] {:target (rand-int 100)})
  :handle (fn [_ _]
            [(s/call :ui/prompt {:text "Guess 1–100"} :on-guess)])
  :on-guess (fn [self n]
              (cond
                (< n (:target self))
                [(s/call :ui/prompt {:text "Too low"} :on-guess)]
                :else
                [(s/end {:winner true})])))

(s/mount! "/guess" :demo/guess)
(s/start! {:port 8080})

────────────────────────────────────────────────────────────────────── Stability of this surface ────────────────────────────────────────────────────────────────────── Everything in this namespace is intended to remain stable across framework versions. Names and arities outside this namespace are considered internal until the framework reaches 1.0.

Public API of the stube framework.

Most users only need this namespace.  It re-exports the small set of
functions that are intended to be called from application code; the
internals live in [[dev.zeko.stube.kernel]], [[dev.zeko.stube.conversation]],
[[dev.zeko.stube.registry]], [[dev.zeko.stube.render]], [[dev.zeko.stube.http]] and
[[dev.zeko.stube.server]].

──────────────────────────────────────────────────────────────────────
At a glance
──────────────────────────────────────────────────────────────────────

    (require '[dev.zeko.stube.core :as s])

    (s/defcomponent :ui/prompt
      :init   (fn [{:keys [text]}] {:text text :answer ""})
      :keep   #{:answer}
      :render (fn [self]
                [:form (s/root-attrs self (s/on self :submit))
                 [:label (:text self)]
                 [:input (merge {:name "answer"} (s/bind :answer))]
                 [:button "OK"]])
      :handle (fn [self _]
                [(s/answer (parse-long (:answer self)))]))

    (s/defcomponent :demo/guess
      :init   (fn [_] {:target (rand-int 100)})
      :handle (fn [_ _]
                [(s/call :ui/prompt {:text "Guess 1–100"} :on-guess)])
      :on-guess (fn [self n]
                  (cond
                    (< n (:target self))
                    [(s/call :ui/prompt {:text "Too low"} :on-guess)]
                    :else
                    [(s/end {:winner true})])))

    (s/mount! "/guess" :demo/guess)
    (s/start! {:port 8080})

──────────────────────────────────────────────────────────────────────
Stability of this surface
──────────────────────────────────────────────────────────────────────
Everything in this namespace is intended to remain stable across
framework versions.  Names and arities outside this namespace are
considered internal until the framework reaches 1.0.
raw docstring

active-conversationsclj

See [[dev.zeko.stube.server/active-conversations]].
sourceraw docstring

afterclj

Effect: dispatch route-event to the current instance after delay-ms.

[self [(s/after 1000 :tick)]]

If the conversation or instance is gone when the timer fires, the event is dropped. route-event accepts the same keyword/vector shape as (s/on self :click :as route-event).

Effect: dispatch `route-event` to the current instance after
`delay-ms`.

    [self [(s/after 1000 :tick)]]

If the conversation or instance is gone when the timer fires, the event
is dropped.  `route-event` accepts the same keyword/vector shape as
`(s/on self :click :as route-event)`.
sourceraw docstring

answerclj

Pop this frame; deliver value to the parent under its resume key. See dev.zeko.stube.effects/answer.

Pop this frame; deliver `value` to the parent under its
resume key.  See [[dev.zeko.stube.effects/answer]].
sourceraw docstring

backclj

An effect that walks one step backward through the conversation's history. Use it from a handler to wire a "Back" button, or render (s/back-button "Back") for the stock conversation-level button.

When emitted from a top-level handler, it pops the most recent conversation snapshot off :conv/history and re-renders the restored top frame. No-op if the history is empty.

An effect that walks one step backward through the
conversation's history.  Use it from a handler to wire a "Back"
button, or render `(s/back-button "Back")` for the stock
conversation-level button.

When emitted from a top-level handler, it pops the most recent
conversation snapshot off `:conv/history` and re-renders the
restored top frame.  No-op if the history is empty.
sourceraw docstring

back-buttonclj

See [[dev.zeko.stube.render/back-button]].
sourceraw docstring

becomeclj

(become component-id)
(become component-id args)

Pop the current frame and push another in its place (Seaside become:). The replacement inherits the original parent linkage and resume key, so an eventual :answer still flows back to whoever called the original frame.

(s/become :wizard/step-2)
(s/become :wizard/step-2 {:from data})

Named become instead of replace to avoid shadowing clojure.core/replace.

Pop the current frame and push another in its place (Seaside
`become:`).  The replacement inherits the original parent linkage
and resume key, so an eventual `:answer` still flows back to whoever
called the original frame.

    (s/become :wizard/step-2)
    (s/become :wizard/step-2 {:from data})

Named `become` instead of `replace` to avoid shadowing
`clojure.core/replace`.
sourceraw docstring

bindclj

See [[dev.zeko.stube.render/bind]].
sourceraw docstring

bootclj

Pure boot effects for a flow — see dev.zeko.stube.kernel/boot.

Pure boot effects for a flow — see [[dev.zeko.stube.kernel/boot]].
sourceraw docstring

callclj

(call component-id)
(call component-id args-or-resume)
(call component-id args resume)

Push a child onto the stack. On :answer, the parent's resume key is invoked with the answered value.

(s/call :ui/prompt)                  ; no args, no resume
(s/call :ui/prompt :on-pick)         ; no args, resume :on-pick
(s/call :ui/prompt {:text "Hi"})     ; args, no resume
(s/call :ui/prompt {:text "Hi"} :on-pick) ; args + resume

Wraps the component id with embed internally; pass an existing embed spec via dev.zeko.stube.effects/call if you already have one.

Push a child onto the stack.  On `:answer`, the parent's resume key
is invoked with the answered value.

    (s/call :ui/prompt)                  ; no args, no resume
    (s/call :ui/prompt :on-pick)         ; no args, resume :on-pick
    (s/call :ui/prompt {:text "Hi"})     ; args, no resume
    (s/call :ui/prompt {:text "Hi"} :on-pick) ; args + resume

Wraps the component id with [[embed]] internally; pass an existing
embed spec via [[dev.zeko.stube.effects/call]] if you already have one.
sourceraw docstring

call-in-slotclj

(call-in-slot slot component-id)
(call-in-slot slot component-id args-or-resume)
(call-in-slot slot component-id args resume)

Temporarily swap an embedded slot's child; the new child answers back to the parent without taking over the page.

(s/call-in-slot :slot/main :feature/edit)
(s/call-in-slot :slot/main :feature/edit {:id 7} :on-saved)
Temporarily swap an embedded slot's child; the new child answers
back to the parent without taking over the page.

    (s/call-in-slot :slot/main :feature/edit)
    (s/call-in-slot :slot/main :feature/edit {:id 7} :on-saved)
sourceraw docstring

cancelclj

Sentinel returned by cancellable stock UI components.

Sentinel returned by cancellable stock UI components.
sourceraw docstring

chooseclj

(choose options)
(choose options caption)

Return an embed spec for the stock one-of-N choice component.

Return an embed spec for the stock one-of-N choice component.
sourceraw docstring

confirmclj

(confirm question)

Return an embed spec for the stock yes/no confirmation component.

Return an embed spec for the stock yes/no confirmation component.
sourceraw docstring

decorateclj

(decorate base-cdef overrides)

Build a new component definition by overriding keys of base-cdef.

overrides is either:

  • a map that replaces the corresponding entries verbatim, or
  • a function of the base cdef returning such a map (so the override can call into the original :render / :handle etc.).

Returns a fresh map; the caller is responsible for giving it a fresh :component/id and registering it.

(def site-header
  (s/decorate (s/registry-lookup :booking/wizard)
    (fn [base]
      {:component/id     :booking/wizard-with-banner
       :component/render
       (fn [self]
         [:div {:id (:instance/id self)}
          [:header.banner "Welcome"]
          ((:component/render base) self)])})))

No new runtime concept: this is just merge lifted into the framework's vocabulary so the call site reads like Seaside-style behavioural composition.

See decorate! for the register-on-the-way variant.

Build a new component definition by overriding keys of `base-cdef`.

`overrides` is either:

* a **map** that replaces the corresponding entries verbatim, or
* a **function** of the base cdef returning such a map (so the
  override can call into the original `:render` / `:handle` etc.).

Returns a fresh map; the caller is responsible for giving it a fresh
`:component/id` and registering it.

    (def site-header
      (s/decorate (s/registry-lookup :booking/wizard)
        (fn [base]
          {:component/id     :booking/wizard-with-banner
           :component/render
           (fn [self]
             [:div {:id (:instance/id self)}
              [:header.banner "Welcome"]
              ((:component/render base) self)])})))

No new runtime concept: this is just `merge` lifted into the
framework's vocabulary so the call site reads like Seaside-style
behavioural composition.

See [[decorate!]] for the register-on-the-way variant.
sourceraw docstring

decorate!clj

(decorate! base-cdef overrides)

Like decorate but also registers the resulting cdef and returns the registered map. Convenient for the common case:

(s/decorate! (s/registry-lookup :booking/wizard)
  {:component/id     :booking/wizard-with-banner
   :component/render
   (fn [self]
     [:div (s/root-attrs self)
      [:header.banner "Welcome"]
      ((:component/render (s/registry-lookup :booking/wizard)) self)])})

Use decorate when you want to inspect or further modify the cdef before deciding whether to register it.

Like [[decorate]] but also registers the resulting cdef and returns
the registered map.  Convenient for the common case:

    (s/decorate! (s/registry-lookup :booking/wizard)
      {:component/id     :booking/wizard-with-banner
       :component/render
       (fn [self]
         [:div (s/root-attrs self)
          [:header.banner "Welcome"]
          ((:component/render (s/registry-lookup :booking/wizard)) self)])})

Use [[decorate]] when you want to inspect or further modify the cdef
before deciding whether to register it.
sourceraw docstring

defcomponentcljmacro

(defcomponent id & opts)

Define a component and add it to the global registry.

(s/defcomponent :auth/login
  :doc    "Prompt for credentials."
  :init   (fn [args] state-map)
  :keep   #{:signal-keys}            ;; optional
  :render (fn [self] hiccup)
  :handle (fn [self event]           ;; event is {:event …, :signals …}
            [self' effects])
  :on-foo (fn [self answer-value]    ;; resume keys, optional
            [self' effects]))

The macro captures the call-site :file/:line so the halos dev tool can jump to the definition. Use register-component! from data-driven code that prefers a function shape.

Define a component and add it to the global registry.

    (s/defcomponent :auth/login
      :doc    "Prompt for credentials."
      :init   (fn [args] state-map)
      :keep   #{:signal-keys}            ;; optional
      :render (fn [self] hiccup)
      :handle (fn [self event]           ;; event is {:event …, :signals …}
                [self' effects])
      :on-foo (fn [self answer-value]    ;; resume keys, optional
                [self' effects]))

The macro captures the call-site `:file`/`:line` so the halos dev
tool can jump to the definition.  Use [[register-component!]] from
data-driven code that prefers a function shape.
sourceraw docstring

defflowcljmacro

(defflow id bindings & body)

Define a linear flow component. See dev.zeko.stube.flow/defflow for the full docstring; this is a thin re-export so application code only ever needs [dev.zeko.stube.core :as s].

Define a linear flow component.  See [[dev.zeko.stube.flow/defflow]] for the
full docstring; this is a thin re-export so application code only ever
needs `[dev.zeko.stube.core :as s]`.
sourceraw docstring

dispatchclj

Pure event dispatch — (dispatch conv event) → [conv' fragments]. Useful from the REPL or for tests; production code goes through the http layer.

Pure event dispatch — `(dispatch conv event) → [conv' fragments]`.
Useful from the REPL or for tests; production code goes through the http
layer.
sourceraw docstring

embedclj

See [[dev.zeko.stube.conversation/embed]].
sourceraw docstring

endclj

Terminate the conversation with a final value. After this the SSE channel closes and the conversation is forgotten. See dev.zeko.stube.effects/end.

Terminate the conversation with a final value.  After
this the SSE channel closes and the conversation is forgotten.
See [[dev.zeko.stube.effects/end]].
sourceraw docstring

end!clj

See [[dev.zeko.stube.server/end!]].
sourceraw docstring

execute-scriptclj

Run literal JS in the browser. Last-resort escape hatch; prefer Datastar attributes for most needs. See dev.zeko.stube.effects/execute-script.

Run literal JS in the browser.  Last-resort escape hatch;
prefer Datastar attributes for most needs.  See
[[dev.zeko.stube.effects/execute-script]].
sourceraw docstring

file-storeclj

See [[dev.zeko.stube.store/file-store]].
sourceraw docstring

helpclj

Return a registered component's docstring, or nil.

Return a registered component's docstring, or nil.
sourceraw docstring

historyclj

(history cid)

Summarise :conv/history for live conversation cid.

Summarise `:conv/history` for live conversation `cid`.
sourceraw docstring

in-memory-storeclj

See [[dev.zeko.stube.store/in-memory-store]].
sourceraw docstring

infoclj

(info text)

Return an embed spec for the stock informational OK dialog.

Return an embed spec for the stock informational OK dialog.
sourceraw docstring

inspectclj

See [[dev.zeko.stube.server/inspect]].
sourceraw docstring

instanceclj

(instance cid iid)

Return the instance map for iid in live conversation cid.

Return the instance map for `iid` in live conversation `cid`.
sourceraw docstring

ioclj

Fire-and-forget (thunk) off the request thread. See dev.zeko.stube.effects/io.

Fire-and-forget `(thunk)` off the request thread.
See [[dev.zeko.stube.effects/io]].
sourceraw docstring

local-bindclj

See [[dev.zeko.stube.render/local-bind]].
sourceraw docstring

local-signalclj

See [[dev.zeko.stube.render/local-signal]].
sourceraw docstring

mount!clj

See [[dev.zeko.stube.server/mount!]].
sourceraw docstring

mountsclj

See [[dev.zeko.stube.server/mounts]].
sourceraw docstring

onclj

See [[dev.zeko.stube.render/on]].
sourceraw docstring

patchclj

Emit an extra DOM patch without changing the stack. See dev.zeko.stube.effects/patch.

Emit an extra DOM patch without changing the stack.
See [[dev.zeko.stube.effects/patch]].
sourceraw docstring

patch-signalsclj

Push a Datastar signal patch (writes signal values back to the browser). See dev.zeko.stube.effects/patch-signals.

Push a Datastar signal patch (writes signal values back
to the browser).  See [[dev.zeko.stube.effects/patch-signals]].
sourceraw docstring

promptclj

(prompt label)
(prompt label default)

Return an embed spec for the stock text prompt component.

Return an embed spec for the stock text prompt component.
sourceraw docstring

publish!clj

Publish msg to every live instance subscribed to topic. Delivery is asynchronous and cid/iid-scoped; stale subscribers are ignored. Returns the number of subscribers targeted.

Publish `msg` to every live instance subscribed to `topic`.
Delivery is asynchronous and cid/iid-scoped; stale subscribers are
ignored.  Returns the number of subscribers targeted.
sourceraw docstring

register-component!clj

(register-component! id opts)
(register-component! id opts source)

Plain function form of defcomponent. Two arities:

(register-component! id opts)
(register-component! id opts source-map)

source-map is {:file ... :line ...} to be attached under :component/source (so the halos dev tool can jump to a definition). The macro supplies it from call-site &form meta; hand-rolled data-driven callers can pass nil.

Plain function form of [[defcomponent]].  Two arities:

    (register-component! id opts)
    (register-component! id opts source-map)

`source-map` is `{:file ... :line ...}` to be attached under
`:component/source` (so the halos dev tool can jump to a definition).
The macro supplies it from call-site `&form` meta; hand-rolled
data-driven callers can pass nil.
sourceraw docstring

registry-lookupclj

Look up a registered component definition by id (or nil).

Look up a registered component definition by id (or nil).
sourceraw docstring

render-slotclj

See [[dev.zeko.stube.render/render-slot]].
sourceraw docstring

replayclj

(replay events)
(replay baseline events)

Replay events against a baseline conversation or root flow id.

Returns [conv fragments], matching dispatch / boot. When the baseline is a flow id, replay boots a fresh conversation first. Event maps may omit :instance-id to target the current top frame and may omit :signals to use {}. An event may also be a function of the current conversation returning such a map.

Replay `events` against a baseline conversation or root flow id.

Returns `[conv fragments]`, matching [[dispatch]] / [[boot]].  When
the baseline is a flow id, replay boots a fresh conversation first.
Event maps may omit `:instance-id` to target the current top frame and
may omit `:signals` to use `{}`.  An event may also be a function of
the current conversation returning such a map.
sourceraw docstring

root-attrsclj

See [[dev.zeko.stube.render/root-attrs]].
sourceraw docstring

start!clj

See [[dev.zeko.stube.server/start!]].
sourceraw docstring

stop!clj

See [[dev.zeko.stube.server/stop!]].
sourceraw docstring

subscribeclj

Effect: subscribe the current instance to topic.

Published messages arrive as route-event with the published value in :payload. Re-emit this from :wakeup for components that should resubscribe after crash-resume.

Effect: subscribe the current instance to `topic`.

Published messages arrive as `route-event` with the published value in
`:payload`.  Re-emit this from `:wakeup` for components that should
resubscribe after crash-resume.
sourceraw docstring

treeclj

(tree cid)

Pretty-print the component tree for live conversation cid and return the tree data. nil if the conversation is unknown.

Pretty-print the component tree for live conversation `cid` and
return the tree data. nil if the conversation is unknown.
sourceraw docstring

unmount!clj

See [[dev.zeko.stube.server/unmount!]].
sourceraw docstring

unsubscribeclj

Effect: remove this instance's topic subscription(s).

Effect: remove this instance's topic subscription(s).
sourceraw docstring

upload-attrsclj

See [[dev.zeko.stube.render/upload-attrs]].
sourceraw docstring

upload-frameclj

See [[dev.zeko.stube.render/upload-frame]].
sourceraw docstring

whereclj

(where type-kw)

Return the source location captured for component type-kw at defcomponent time, or nil.

Return the source location captured for component `type-kw` at
`defcomponent` time, or nil.
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