Liking cljdoc? Tell your friends :D

dev.zeko.stube.kernel

The pure runtime: step, run-effects, dispatch.

Reading guide ─────────────

Everything in this namespace operates on plain values. A handler returns [self' effects]; run-effects folds those effects into the conversation, producing the next conversation value and the list of fragments that must be pushed to the browser. A fragment is just a small map describing one Datastar event — see [[fragment-shape]] for the schema.

No I/O, no atoms, no SSE — that all lives one layer up in dev.zeko.stube.http / dev.zeko.stube.server. This means the entire interaction loop is testable from a REPL with dispatch and a hand-built conversation value, with no server running.

Effect vocabulary ─────────────────

[:call <embed> :resume <k>]   push a child frame; on `:answer` the
                              parent's `:k` function is invoked
[:call-in-slot <slot> <embed> :resume <k>]
                              temporarily swap one embedded slot;
                              the child answers back to the parent
                              without taking over the page
[:answer <value>]             pop this frame; deliver `value` to
                              the parent under its resume key
[:replace <embed>]            pop this frame and push another in
                              its place (Seaside `become:`)
[:patch <hiccup>]             extra DOM patch (no stack change)
[:patch-signals <map>]        push a Datastar signal patch
[:execute-script <js>]        run literal JS in the browser
[:io <fn>]                    call `(fn)` off-thread (fire-and-forget)
[:after ms event]             schedule a future event for this instance
[:subscribe topic event]      subscribe this instance to published messages
[:unsubscribe topic?]         remove this instance's topic subscription(s)
[:back]                       restore the previous conversation
                              from `:conv/history` (slice 3)
[:end <value>]                terminate the conversation

All effects produce zero or more fragments and an updated conversation.

Component lifecycle keys ──────────────────────── Beyond the keys read directly by :render / :handle, a component may include:

:start  (fn [self] [self' effects])
:stop   (fn [self] [self' effects])
:wakeup (fn [self] [self' effects])

:start runs once immediately after instantiation for both stack frames and embedded children, which lets "task" components launch their first :call without a synthetic user event and lets widgets subscribe or schedule timers. :stop runs just before a frame/subtree is removed; :wakeup runs when a persisted or history-restored frame becomes live again.

The pure runtime: `step`, `run-effects`, `dispatch`.

Reading guide
─────────────

Everything in this namespace operates on plain values.  A handler
returns `[self' effects]`; `run-effects` folds those effects into the
conversation, producing the next conversation value and the list of
*fragments* that must be pushed to the browser.  A fragment is just a
small map describing one Datastar event — see [[fragment-shape]] for
the schema.

No I/O, no atoms, no SSE — that all lives one layer up in
[[dev.zeko.stube.http]] / [[dev.zeko.stube.server]].  This means the entire interaction
loop is testable from a REPL with `dispatch` and a hand-built
conversation value, with no server running.

Effect vocabulary
─────────────────

    [:call <embed> :resume <k>]   push a child frame; on `:answer` the
                                  parent's `:k` function is invoked
    [:call-in-slot <slot> <embed> :resume <k>]
                                  temporarily swap one embedded slot;
                                  the child answers back to the parent
                                  without taking over the page
    [:answer <value>]             pop this frame; deliver `value` to
                                  the parent under its resume key
    [:replace <embed>]            pop this frame and push another in
                                  its place (Seaside `become:`)
    [:patch <hiccup>]             extra DOM patch (no stack change)
    [:patch-signals <map>]        push a Datastar signal patch
    [:execute-script <js>]        run literal JS in the browser
    [:io <fn>]                    call `(fn)` off-thread (fire-and-forget)
    [:after ms event]             schedule a future event for this instance
    [:subscribe topic event]      subscribe this instance to published messages
    [:unsubscribe topic?]         remove this instance's topic subscription(s)
    [:back]                       restore the previous conversation
                                  from `:conv/history` (slice 3)
    [:end <value>]                terminate the conversation

All effects produce zero or more fragments and an updated conversation.

Component lifecycle keys
────────────────────────
Beyond the keys read directly by `:render` / `:handle`, a component
may include:

    :start  (fn [self] [self' effects])
    :stop   (fn [self] [self' effects])
    :wakeup (fn [self] [self' effects])

`:start` runs once immediately after instantiation for both stack
frames and embedded children, which lets "task" components launch
their first `:call` without a synthetic user event and lets widgets
subscribe or schedule timers.  `:stop` runs just before a frame/subtree
is removed; `:wakeup` runs when a persisted or history-restored frame
becomes live again.
raw docstring

*schedule-event!*clj

Optional side-effect hook bound by the server while folding effects. The kernel stays ignorant of threads and SSE; it only describes the delayed event that should be sent later.

Optional side-effect hook bound by the server while folding effects.
The kernel stays ignorant of threads and SSE; it only describes the
delayed event that should be sent later.
sourceraw docstring

*subscribe!*clj

Optional side-effect hook bound by the server for [:subscribe …].

Optional side-effect hook bound by the server for `[:subscribe …]`.
sourceraw docstring

*unsubscribe!*clj

Optional side-effect hook bound by the server for [:unsubscribe …].

Optional side-effect hook bound by the server for `[:unsubscribe …]`.
sourceraw docstring

bootclj

(boot flow-id)

Mint the initial set of effects for a freshly minted conversation whose root flow is flow-id. Pulled out so the http layer can ask for them on first SSE connect.

Mint the initial set of effects for a freshly minted conversation
whose root flow is `flow-id`.  Pulled out so the http layer can ask
for them on first SSE connect.
sourceraw docstring

dispatchclj

(dispatch conv {:keys [instance-id event payload signals] :as ev})

Apply one client event to a conversation. event is the map

{:instance-id "ix-7e2"
 :event       :submit         ; or any keyword the component knows
 :payload     any-edn-value   ; optional, from (s/on ... :as [:event v])
 :signals     {:answer "42"}}

Returns [conv' fragments]. Pure: no I/O, no globals.

Stale events — those whose instance-id no longer exists in the conversation — are dropped silently. This matters for buttons that are still in the DOM after their owning frame has been popped (e.g. the user double-clicks an OK button: the first click :answers and removes the instance; the second click arrives with an iid that's already gone). Throwing here would surface as a 500 in the http layer for what is, semantically, a no-op.

Apply one client event to a conversation.  `event` is the map

    {:instance-id "ix-7e2"
     :event       :submit         ; or any keyword the component knows
     :payload     any-edn-value   ; optional, from (s/on ... :as [:event v])
     :signals     {:answer "42"}}

Returns `[conv' fragments]`.  Pure: no I/O, no globals.

Stale events — those whose `instance-id` no longer exists in the
conversation — are dropped silently.  This matters for buttons that
are still in the DOM after their owning frame has been popped (e.g.
the user double-clicks an OK button: the first click `:answer`s and
removes the instance; the second click arrives with an iid that's
already gone).  Throwing here would surface as a 500 in the http
layer for what is, semantically, a no-op.
sourceraw docstring

redraw-topclj

(redraw-top conv)

Re-render the current top frame in-place without running :wakeup or snapshotting. Returns [conv' [frag]]. Used by dev-tooling paths (e.g. enabling halos on a live conversation) that want a fresh frame against the current state.

Re-render the current top frame in-place without running `:wakeup`
or snapshotting.  Returns `[conv' [frag]]`.  Used by dev-tooling
paths (e.g. enabling halos on a live conversation) that want a fresh
frame against the *current* state.
sourceraw docstring

resume-topclj

(resume-top conv)

Run :wakeup for the current top frame and render it as a restored frame. Used by the http layer when a persisted conversation reattaches.

Run `:wakeup` for the current top frame and render it as a restored
frame.  Used by the http layer when a persisted conversation reattaches.
sourceraw docstring

run-effectsclj

(run-effects conv effects)

Apply a sequence of effects to conv left to right, collecting fragments. Returns [conv' fragments].

Apply a sequence of effects to `conv` left to right, collecting
fragments.  Returns `[conv' fragments]`.
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