[riverford/locket "2019.02.15-05"]
A pocket-sized state machine library for re-frame.
If you've followed the example along at http://blog.cognitect.com/blog/2017/8/14/restate-your-ui-creating-a-user-interface-with-re-frame-and-state-machines, you might find yourself wanting a library to reduce the accompanying boiler-plate a little.
This does exactly that, by adding an interceptor to every state-machine event transition that exists, and generating the ones that don't.
This cuts down on much of the boiler-plate and also reduces the risk of your state getting out of sync (i.e. if you forget to call update-next-state
).
(ns example.core
(:require
[locket.core :as locket]
[re-frame.core :as re-frame]
[example.db :as db]))
;; --- handlers ---
(re-frame/reg-event-fx
::init
(fn [cofx _]
(let [{:keys [db]} cofx]
{:db db/default-db})))
(re-frame/reg-event-fx
:auth/login
(fn [cofx]
{:dispatch-later [{:ms 3000
:dispatch [:auth.login/success]}]}))
(re-frame/reg-event-fx
:auth/logout
(fn [cofx]
{:dispatch-later [{:ms 3000
:dispatch [:auth.logout/success]}]}))
(locket/install-state-machine!
{:id :auth
:initial-state :ready
:transitions {:ready {:auth/login :logging-in}
:logging-in {:auth.login/success :logged-in
:auth.login/failure :error}
:logged-in {:auth/logout :logging-out}
:logging-out {:auth.logout/success :ready}
:error {:auth/login :logging-in}}})
;; --- subscriptions ---
(reg-sub
:auth/state
(fn [db]
(locket/state :auth db)))
(reg-sub
:auth/transitions
(fn [db]
(locket/transitions :auth db)))
;; --- views ---
(defn main-panel []
(let [state (re-frame/subscribe [:auth/state])
transitions (re-frame/subscribe [:auth/transitions])]
[:div {:class "pa5"}
[:p {:class "f3"} "Current state"]
[:div {:class "flex flex-row items-center"}
[:p {:class "f5 mr3"} @state]
(when (contains? #{:logging-in :logging-out} @state)
[:img {:src "https://cdnjs.cloudflare.com/ajax/libs/galleriffic/2.0.1/css/loader.gif"
:style {:width 20
:height 20}}])]
[:p {:class "f3"} "Transitions"]
(for [t @transitions]
[:p {:key (str t)
:class "f5"
:style {:cursor "pointer"}
:on-click (fn [_]
(re-frame/dispatch [t]))}
(name t)])]))
Copyright © 2018 Riverford
Distributed under the Eclipse Public License either version 1.0 or (at your option) any later version.
Can you improve this documentation?Edit on GitHub
cljdoc is a website building & hosting documentation for Clojure/Script libraries
× close