re-xstate
is a thin re-frame wrapper over XState. It provides the power of XState state machines and statecharts to
re-frame applications. Unlike directly using XState, re-xstate
doesn't use XState for context management. Instead, it
manages context on its own to work seamlessly with EDN data. This approach avoids the need to convert context from EDN
to JSON and vice versa, which can lead to loss of information.
To include re-xstate
in your project, add the following to your deps.edn
:
io.github.drbuchkov/re-xstate {:mvn/version "0.0.13"}
- State Management: Define and manage application state using state machines and statecharts.
- EDN Compatibility: Works seamlessly with EDN data without the need for JSON conversion.
- Re-frame Integration: Provides re-frame events and subscriptions for state management.
::rxs/initialize-fsm
: Initializes a finite state machine.::rxs/send
: Sends an event to a state machine.::rxs/stop
: Stops a state machine.::rxs/reset
: Resets a state machine to its initial state.::rxs/assign
: Assigns new context to a state machine.::rxs/update-context
: Given actx-action
(created ) function and an event, updates the context of the FSM in the db. This is used instead of the default xstate context updating, because the default xstate context updating doesn't work with re-frame subscriptions, and converting from edn to json and back results in a loss of data.
::rxs/fsm
: Retrieves the entire state machine.::rxs/fsm-state
: Retrieves the current state of a state machine.::rxs/fsm-state-value
: Retrieves the current state value of a state machine.::rxs/fsm-context
: Retrieves the context of a state machine.::rxs/fsm-state-map
: Retrieves the current state value and context of a state machine.
ctx-action
: Given a context action function, returns a 2-arity callback that can be used as an xstate action. The event is converted to edn before being passed to the action function.effectful-action
: Given an effectful action function, returns a 2-arity callback that can be used as an xstate action. The event is converted to edn before being passed to the action function.guard
: Given a guard function, returns a 2-arity callback that can be used as an xstate guard. The event is converted to edn before being passed to the guard function.
Here's a simple example from the /examples
folder showcasing a toggle functionality:
Namespace and Requirements:
(ns toggle.views
(:require
[drbuchkov.re-xstate.core :as rxs]
[re-frame.core :as rf]))
Machine Configuration:
(def toggle-state-machine-config
{:id "toggle-state-machine"
:initial :inactive
:context {:count 0}
:states {:inactive {:on {:TOGGLE {:target :active
:actions [:increment]}}}
:active {:on {:TOGGLE :inactive}}}})
(def toggle-state-machine-options
{:actions {:increment (rxs/ctx-action
(fn [{:keys [ctx] :as evt}]
(update ctx :count inc)))
:log-ctx (rxs/effectful-action
(fn [{:keys [ctx]}]
#p ctx))}})
Machine Initialization:
(rf/dispatch [::rxs/initialize-fsm toggle-state-machine-config toggle-state-machine-options])
Usage:
(defn toggle-view []
(let [state (rf/subscribe [::rxs/fsm-state :toggle])]
[:div
[:h1 (str "Toggle is " @state)]
[:button {:on-click #(rf/dispatch [::rxs/send :toggle {:type :TOGGLE}])}
"Toggle"]]))
For more examples and detailed usage, refer to the provided example namespaces: