Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Redux with basically no effort in clojurescript, plus core.async to handle asynchronous actions
(ns reduxish.state-tools
(:require-macros [cljs.core.async.macros :refer [go go-loop]])
(:require [cljs.core.async.impl.protocols :refer [WritePort ReadPort]]
[cljs.core.async :refer [<!]]))
(defn channel? [ch]
(and (satisfies? WritePort ch) (satisfies? ReadPort ch)))
(defn dispatch! [reducer state value]
(println value)
(if (channel? value)
(go (loop []
(when-let [message (<! value)]
(<! (dispatch! state reducer message))
(recur))))
(go (prn state reducer value) (swap! state reducer value))))
(defn action
([type] { :type type})
([type payload] { :type type :payload payload}))
(defn dispatch-on-type [_ {:keys [type]}] type)
(defn make-store [reducer]
(let [state (atom (reducer))]
{:state state
:dispatch! (partial dispatch! reducer state)}))
(defmulti reducer dispatch-on-type)
(defmethod reducer :default [] 0)
(defmethod reducer :increment [state action] (inc state))
(defmethod reducer :decrement [state action] (dec state))
(let [{:keys [dispatch! state]} (make-store reducer)]
(go
(<! (dispatch! (action :increment)))
(<! (dispatch! (action :increment)))
(println @state)))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.