Liking cljdoc? Tell your friends :D

hive.events

Unified event system for Clojure/ClojureScript.

Combines:

  • re-frame interceptor chain (portable to JVM)
  • re-frame effects/coeffects system
  • domino-style declarative models with async support

Design principles:

  • Events as data
  • Pure handlers returning effect maps
  • Interceptors for cross-cutting concerns
  • Async-first with core.async

Usage: (require '[hive.events :as ev])

;; Register effect handlers (ev/reg-fx :http (fn [request] ...)) (ev/reg-fx :db (fn [tx] ...))

;; Register event handlers (ev/reg-event-fx :user/login [ev/debug ev/validate] ; interceptors (fn [{:keys [db]} [_ credentials]] {:db (assoc db :loading? true) :http {:method :post :url "/login" :body credentials}}))

;; Dispatch events (ev/dispatch [:user/login {:email "..." :password "..."}])

Unified event system for Clojure/ClojureScript.

Combines:
- re-frame interceptor chain (portable to JVM)
- re-frame effects/coeffects system
- domino-style declarative models with async support

Design principles:
- Events as data
- Pure handlers returning effect maps
- Interceptors for cross-cutting concerns
- Async-first with core.async

Usage:
  (require '[hive.events :as ev])

  ;; Register effect handlers
  (ev/reg-fx :http (fn [request] ...))
  (ev/reg-fx :db (fn [tx] ...))

  ;; Register event handlers
  (ev/reg-event-fx :user/login
    [ev/debug ev/validate]  ; interceptors
    (fn [{:keys [db]} [_ credentials]]
      {:db (assoc db :loading? true)
       :http {:method :post :url "/login" :body credentials}}))

  ;; Dispatch events
  (ev/dispatch [:user/login {:email "..." :password "..."}])
raw docstring

hive.events.async

Async extensions for hive-events.

Provides advanced async patterns beyond basic dispatch:

  • Timeout-wrapped dispatch
  • Retry with backoff
  • Debounced dispatch
  • Event streams (pub/sub)
  • Saga/process manager patterns

JVM-first with core.async, graceful degradation on CLJS.

Async extensions for hive-events.

Provides advanced async patterns beyond basic dispatch:
- Timeout-wrapped dispatch
- Retry with backoff
- Debounced dispatch
- Event streams (pub/sub)
- Saga/process manager patterns

JVM-first with core.async, graceful degradation on CLJS.
raw docstring

hive.events.cofx

Coeffects (cofx) system - dependency injection for event handlers.

Ported from re-frame/cofx.cljc with JVM compatibility.

Coeffects are input data that handlers need but shouldn't fetch themselves. They enable pure handlers by injecting all dependencies.

Built-in coeffects:

  • :db - Current application state
  • :event - The event being processed

Usage: ;; Register a coeffect handler (reg-cofx :now (fn [coeffects] (assoc coeffects :now (System/currentTimeMillis))))

;; Inject into event handler (reg-event-fx :log/timestamp [(inject-cofx :now)] (fn [{:keys [db now]} _] {:db (assoc db :last-timestamp now)}))

Coeffects (cofx) system - dependency injection for event handlers.

Ported from re-frame/cofx.cljc with JVM compatibility.

Coeffects are input data that handlers need but shouldn't fetch themselves.
They enable pure handlers by injecting all dependencies.

Built-in coeffects:
- :db    - Current application state
- :event - The event being processed

Usage:
  ;; Register a coeffect handler
  (reg-cofx :now
    (fn [coeffects]
      (assoc coeffects :now (System/currentTimeMillis))))

  ;; Inject into event handler
  (reg-event-fx :log/timestamp
    [(inject-cofx :now)]
    (fn [{:keys [db now]} _]
      {:db (assoc db :last-timestamp now)}))
raw docstring

hive.events.fsm

Deterministic FSM workflow engine for hive-events.

Adapted from yogthos/maestro — state machine runner for expressing workflows as data. Integrated with hive-events fx/cofx system.

Usage

(require '[hive.events.fsm :as fsm])

;; Define FSM spec
(def my-workflow
  {:fsm {::fsm/start {:handler    (fn [resources data]
                                    (assoc data :step :ready))
                       :dispatches [[::process (constantly true)]]}
         ::process    {:handler    (fn [resources data]
                                    (assoc data :result ((:compute resources) data)))
                       :dispatches [[::fsm/end (fn [{:keys [result]}] (some? result))]
                                    [::fsm/error (constantly true)]]}}
   :opts {:max-trace 100}})

;; Compile and run
(-> (fsm/compile my-workflow)
    (fsm/run {:compute my-fn} {:data {:input 42}}))

Privileged States

  • ::start — initial state
  • ::end — terminal success, returns data
  • ::halt — pausable, returns FSM state for resume
  • ::error — terminal failure

Integration with hive-events

  • Handlers are pure: (fn [resources data] new-data)
  • Handlers may return fx-enhanced results: (fn [resources data] {:data new-data, :fx [[:effect-id params]]}) Effects are processed through the hive.events.fx pipeline after transition.
  • Subscriptions can dispatch events on state path changes
  • Pre/post hooks for interceptor-style concerns
  • EDN specs compiled with SCI
  • Sub-FSM composition via run-sub-fsm and make-sub-fsm-handler

Based on yogthos/maestro v0.2.1 (MIT License).

Deterministic FSM workflow engine for hive-events.

Adapted from yogthos/maestro — state machine runner for expressing
workflows as data. Integrated with hive-events fx/cofx system.

## Usage

```clojure
(require '[hive.events.fsm :as fsm])

;; Define FSM spec
(def my-workflow
  {:fsm {::fsm/start {:handler    (fn [resources data]
                                    (assoc data :step :ready))
                       :dispatches [[::process (constantly true)]]}
         ::process    {:handler    (fn [resources data]
                                    (assoc data :result ((:compute resources) data)))
                       :dispatches [[::fsm/end (fn [{:keys [result]}] (some? result))]
                                    [::fsm/error (constantly true)]]}}
   :opts {:max-trace 100}})

;; Compile and run
(-> (fsm/compile my-workflow)
    (fsm/run {:compute my-fn} {:data {:input 42}}))
```

## Privileged States
- `::start` — initial state
- `::end`   — terminal success, returns data
- `::halt`  — pausable, returns FSM state for resume
- `::error` — terminal failure

## Integration with hive-events
- Handlers are pure: `(fn [resources data] new-data)`
- Handlers may return fx-enhanced results:
  `(fn [resources data] {:data new-data, :fx [[:effect-id params]]})`
  Effects are processed through the hive.events.fx pipeline after transition.
- Subscriptions can dispatch events on state path changes
- Pre/post hooks for interceptor-style concerns
- EDN specs compiled with SCI
- Sub-FSM composition via `run-sub-fsm` and `make-sub-fsm-handler`

Based on yogthos/maestro v0.2.1 (MIT License).
raw docstring

hive.events.fx

Effects (fx) system - side effect handlers.

Ported from re-frame/fx.cljc with JVM compatibility.

Effects are declarative descriptions of side effects. Each effect type has a registered handler that performs the actual work.

Built-in effects:

  • :db - Update application state
  • :dispatch - Dispatch another event
  • :dispatch-n - Dispatch multiple events

Usage: ;; Register a custom effect handler (reg-fx :http (fn [{:keys [method url on-success]}] (http-request method url (fn [response] (dispatch [on-success response])))))

;; Event handler returns effects map (reg-event-fx :user/login (fn [{:keys [db]} [_ credentials]] {:db (assoc db :loading? true) :http {:method :post :url "/api/login" :body credentials}}))

Effects (fx) system - side effect handlers.

Ported from re-frame/fx.cljc with JVM compatibility.

Effects are declarative descriptions of side effects.
Each effect type has a registered handler that performs the actual work.

Built-in effects:
- :db         - Update application state
- :dispatch   - Dispatch another event
- :dispatch-n - Dispatch multiple events

Usage:
  ;; Register a custom effect handler
  (reg-fx :http
    (fn [{:keys [method url on-success]}]
      (http-request method url
        (fn [response]
          (dispatch [on-success response])))))

  ;; Event handler returns effects map
  (reg-event-fx :user/login
    (fn [{:keys [db]} [_ credentials]]
      {:db (assoc db :loading? true)
       :http {:method :post :url "/api/login" :body credentials}}))
raw docstring

hive.events.interceptor

Interceptor chain implementation.

Ported from re-frame/interceptor.cljc with JVM compatibility.

An interceptor is a map with optional keys:

  • :id - keyword identifier
  • :before - fn [context] -> context (pre-processing)
  • :after - fn [context] -> context (post-processing)

Context is a map containing:

  • :coeffects - input data (including :event and :db)
  • :effects - output data (side effects to perform)
  • :queue - interceptors yet to execute
  • :stack - interceptors already executed (for :after phase)
Interceptor chain implementation.

Ported from re-frame/interceptor.cljc with JVM compatibility.

An interceptor is a map with optional keys:
- :id      - keyword identifier
- :before  - fn [context] -> context (pre-processing)
- :after   - fn [context] -> context (post-processing)

Context is a map containing:
- :coeffects - input data (including :event and :db)
- :effects   - output data (side effects to perform)
- :queue     - interceptors yet to execute
- :stack     - interceptors already executed (for :after phase)
raw docstring

hive.events.log

Minimal pluggable logging for hive-events.

Three levels: :debug, :warn, :error

Default behavior:

  • JVM: prints to err (stderr)
  • JS: uses console.log/warn/error

Override: (set-log-fn! (fn [level msg & args] ;; your logging here ))

Disable: (set-log-fn! (fn [& _]))

Restore default: (set-log-fn! nil)

Minimal pluggable logging for hive-events.

Three levels: :debug, :warn, :error

Default behavior:
- JVM: prints to *err* (stderr)
- JS: uses console.log/warn/error

Override:
  (set-log-fn! (fn [level msg & args]
                 ;; your logging here
                 ))

Disable:
  (set-log-fn! (fn [& _]))

Restore default:
  (set-log-fn! nil)
raw docstring

hive.events.multi

Multimethod-based event dispatch + pure orchestration for hive-events.

Two complementary subsystems in one namespace:

1. Handler Dispatch (multimethod-based)

Registration:

  • (register-handler! event-id handler-fn) — register handler (no interceptors)
  • (register-handler! event-id interceptors handler-fn) — with interceptors
  • (remove-handler! event-id) — remove a registered handler

Dispatch:

  • (dispatch-sync event) — synchronous dispatch + fx execution
  • (event-id event) — extract event-id (dispatch fn)

Query:

  • (handler-registered? event-id) — check if handler exists

Handler signature: (fn [coeffects event] effects-map)

2. Pure Orchestration (multi-op compilation)

Compile a batch of cross-tool operations into a wave-based execution plan. Pure functions — no side effects, no IO, no requiring-resolve.

Pipeline: normalize → validate → expand-batch → assign-waves → compile-spec

  • (normalize-op op) — normalize string keys, auto-generate ID
  • (validate-ops ops) — validate IDs, deps, cycles (Kahn's algorithm)
  • (expand-batch-macro ops) — expand 'batch' command into fan-out sub-ops
  • (assign-waves ops) — topological sort into dependency-ordered wave groups
  • (compile-multi-spec ops) — end-to-end: validate → expand → waves → FSM spec

Architecture

hive-events (this ns)  — pure compilation (validate, sort, waves)
  ↓
hive-mcp tools/multi   — bridge (resolve handlers, execute ops, format)
  ↓
hive-mcp consolidated  — MCP facade (JSON schema, tool def)

SOLID: OCP — Open for extension via defmethod handlers SOLID: SRP — Pure orchestration logic, no side effects CLARITY: L — Layered: pure compilation separate from execution

Multimethod-based event dispatch + pure orchestration for hive-events.

Two complementary subsystems in one namespace:

## 1. Handler Dispatch (multimethod-based)

Registration:
- `(register-handler! event-id handler-fn)` — register handler (no interceptors)
- `(register-handler! event-id interceptors handler-fn)` — with interceptors
- `(remove-handler! event-id)` — remove a registered handler

Dispatch:
- `(dispatch-sync event)` — synchronous dispatch + fx execution
- `(event-id event)` — extract event-id (dispatch fn)

Query:
- `(handler-registered? event-id)` — check if handler exists

Handler signature: `(fn [coeffects event] effects-map)`

## 2. Pure Orchestration (multi-op compilation)

Compile a batch of cross-tool operations into a wave-based execution plan.
Pure functions — no side effects, no IO, no requiring-resolve.

Pipeline: normalize → validate → expand-batch → assign-waves → compile-spec

- `(normalize-op op)` — normalize string keys, auto-generate ID
- `(validate-ops ops)` — validate IDs, deps, cycles (Kahn's algorithm)
- `(expand-batch-macro ops)` — expand 'batch' command into fan-out sub-ops
- `(assign-waves ops)` — topological sort into dependency-ordered wave groups
- `(compile-multi-spec ops)` — end-to-end: validate → expand → waves → FSM spec

## Architecture

```
hive-events (this ns)  — pure compilation (validate, sort, waves)
  ↓
hive-mcp tools/multi   — bridge (resolve handlers, execute ops, format)
  ↓
hive-mcp consolidated  — MCP facade (JSON schema, tool def)
```

SOLID: OCP — Open for extension via defmethod handlers
SOLID: SRP — Pure orchestration logic, no side effects
CLARITY: L — Layered: pure compilation separate from execution
raw docstring

hive.events.observer

Observer seam for dispatched events.

The event registry holds ONE handler per event id. Observers are the extension point for cross-cutting side effects that must not own, replace or know about that handler.

Extend by implementing IEventObserver — EventIdObserver (a fixed set of event ids) and GlobalObserver (every event) are supplied; a consumer may register any other implementation.

Contract: observers run AFTER the handler's effects have been applied, in observer-id order, and each is isolated — an observer that throws is logged and never propagates to the handler or to sibling observers.

Observer seam for dispatched events.

The event registry holds ONE handler per event id. Observers are the
extension point for cross-cutting side effects that must not own, replace
or know about that handler.

Extend by implementing IEventObserver — `EventIdObserver` (a fixed set of
event ids) and `GlobalObserver` (every event) are supplied; a consumer may
register any other implementation.

Contract: observers run AFTER the handler's effects have been applied, in
observer-id order, and each is isolated — an observer that throws is logged
and never propagates to the handler or to sibling observers.
raw docstring

hive.events.router

Event router - registration and dispatch.

Ported from re-frame with JVM-first async support via core.async.

Supports two types of event handlers:

  • reg-event-db: Handler receives db, returns new db
  • reg-event-fx: Handler receives coeffects, returns effects map

Dispatch modes:

  • dispatch: Async dispatch (queued, processed in order)
  • dispatch-sync: Synchronous dispatch (immediate processing)

Usage: ;; Initialize with app state atom (init! (atom {}))

;; Register handlers (reg-event-db :counter/inc (fn [db [_ amount]] (update db :count + amount)))

(reg-event-fx :user/fetch (fn [{:keys [db]} [_ user-id]] {:db (assoc db :loading? true) :http {:url (str "/users/" user-id)}}))

;; Dispatch events (dispatch [:counter/inc 5]) (dispatch-sync [:counter/inc 1])

Event router - registration and dispatch.

Ported from re-frame with JVM-first async support via core.async.

Supports two types of event handlers:
- reg-event-db: Handler receives db, returns new db
- reg-event-fx: Handler receives coeffects, returns effects map

Dispatch modes:
- dispatch: Async dispatch (queued, processed in order)
- dispatch-sync: Synchronous dispatch (immediate processing)

Usage:
  ;; Initialize with app state atom
  (init! (atom {}))

  ;; Register handlers
  (reg-event-db :counter/inc
    (fn [db [_ amount]]
      (update db :count + amount)))

  (reg-event-fx :user/fetch
    (fn [{:keys [db]} [_ user-id]]
      {:db (assoc db :loading? true)
       :http {:url (str "/users/" user-id)}}))

  ;; Dispatch events
  (dispatch [:counter/inc 5])
  (dispatch-sync [:counter/inc 1])
raw docstring

hive.events.schema

Schema-driven event registration — the hive-events leg of the malli macro layer. reg-event-schema registers an fx handler whose EVENT PAYLOAD (the second element of the [id payload] event vector) is coerced + validated against ONE registered malli schema-key by a :before interceptor, before the handler runs — declare the event's payload schema once, its guard is wired.

hive-events is cljc/cljs-safe and malli's derive lever is clj-only, so compile-op is resolved LAZILY via requiring-resolve (guarded). When it is unresolvable — cljs, or hive-spi absent — the interceptor is a pass-through, so registration never fails and the module stays platform-safe.

Schema-driven event registration — the hive-events leg of the malli macro
layer. `reg-event-schema` registers an fx handler whose EVENT PAYLOAD (the
second element of the [id payload] event vector) is coerced + validated against
ONE registered malli schema-key by a :before interceptor, before the handler
runs — declare the event's payload schema once, its guard is wired.

hive-events is cljc/cljs-safe and malli's derive lever is clj-only, so
compile-op is resolved LAZILY via requiring-resolve (guarded). When it is
unresolvable — cljs, or hive-spi absent — the interceptor is a pass-through, so
registration never fails and the module stays platform-safe.
raw 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