Last active
June 25, 2018 14:30
-
-
Save mike-thompson-day8/76812d5452747bc79aac to your computer and use it in GitHub Desktop.
Middleware Which Acts Like A reverse reaction
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(defn on-changes | |
"Middleware factory which acts a bit like \"reaction\" (but it flows into db , rather than out) | |
It observes N inputs (paths into db) and if any of them change (as a result of the | |
handler being run) then it runs 'f' to compute a new value, which is | |
then assoced into the given out=path within app-db. | |
Usage: | |
(defn my-f | |
[a-val b-val] | |
... some computation on a and b in here) | |
(on-changes my-f [:c] [:a] [:b]) | |
" | |
[f out-path & in-paths] | |
(fn on-changed-middleware | |
[handler] | |
(fn on-changed-handler | |
[db v] | |
(let [ ;; run the handler, computing a new generation of db | |
new-db (handler db v) | |
;; work out if any "inputs" have changed | |
new-ins (map #(get-in new-db %) in-paths) | |
old-ins (map #(get-in db %) in-paths) | |
changed-ins? (some false? (map identical? new-ins old-ins))] | |
;; if one of the inputs has changed, then run 'f' | |
(if changed-ins? | |
(assoc-in new-db out-path (apply f new-ins)) | |
new-db))))) | |
;; Testing | |
(defn my-f | |
[a-val b-val] | |
(+ a-val b-val)) | |
;; this event handler just updates path [:a] with a new value | |
(defn handler | |
[db v] | |
(assoc db :a 0)) | |
(def on-change-mid-ware (on-changes my-f [:c] [:a] [:b])) ;; instead of my-f, could just supply '+' | |
;; a handler - middware wrapping the original handler | |
(def mwh (on-change-mid-ware handler)) | |
(mwh {:a 0 :b 2} nil) | |
;; => {:a 0 :b 2} ;; no change | |
(mwh {:a 4 :b 2} nil) | |
;; => {:c 2, :a 0, :b 2} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment