4 ms·
Yes. I now use Rum + Datascript + core.async for event sourcing. Here is the entirety of my reactive event-loop handling, inspired by Tonsky's Cat Chat (https:/
by pgt 7y ago
Yes. I now use Rum + Datascript + core.async for event sourcing. Here is the entirety of my reactive event-loop handling, inspired by Tonsky's Cat Chat (https://tonsky.me/blog/datascript-chat/ https://tonsky.me/blog/datascript-chat/):
; One Macro in events.clj:
(defmacro go-loop-sub [pub key binding & body]
(let [[db-bind & bindings] binding]
`(let [ch# (cljs.core.async/chan)]
(cljs.core.async/sub ~pub ~key ch#)
(go-loop []
(let [event# (rest (cljs.core.async/<! ch#))
~db-bind @yourproject.data.core/conn
~(vec bindings) event#
result# (do ~@body)]
(when result#
(yourproject.data.core/transact! yourproject.data.core/conn result#)))))
(recur)))))
;; Usage (at top of core file)
(defonce conn (d/create-conn schema))
(defonce event-bus (async/chan))
(defonce event-pub (async/pub event-bus first))
;; For each event you want to dispatch on:
(go-loop-sub event-pub :todo/add-item [db {:as data :keys [text]}]
;; Query db here. Any tx-data you return will get transacted.
[{:db/id -1
:todo/text text}])
;; To display some reactive queries in DataScript:
(rum/defc root-component
< rum/reactive [conn]
(let [db (rum/react conn)
todos (d/q '[:find ?todo ?text
:where [?todo :todo/text ?text]]
db)]
[:div "Todos: " (pr-str todos)]))
That's it. You don't need re-frame.
- freshhawk 7y agoI use those same 3 in a similar way, it's great. I do really appreciate the design of the effects/coeffects concept in re-frame, I often use that concept. I just don't find I ever need re-frame.