Provide an example of a coeffect-ing interceptor

This commit is contained in:
Mike Thompson 2016-08-03 17:19:28 +10:00
parent 86b555a86c
commit 600c12a285
2 changed files with 47 additions and 16 deletions

View File

@ -191,17 +191,46 @@
"An interceptor which injects/extracts the value of app-db intto/from a context.
Used for XXXX "
(->interceptor
:name :base
:before (fn before
:name :base
:before (fn base-before
[context]
(assoc-coeffect context :db @app-db)) ;; a coeffect for the handler
:after (fn base-after
[context]
(->> (:effects context)
(map (fn [[key val]]
(if-let [effect-fn (registrar/get-handler :fx key)] ;; XXX shouldn't be using raw :fx
(effect-fn val))))
doall))))
:after (fn after [context]
(->> (:effects context)
(map (fn [[key val]]
(if-let [effect-fn (registrar/get-handler :fx key)] ;; XXX shouldn't be using raw :fx
(effect-fn val))))
doall))))
;; XXX how to stub this out for testing purposes??
#_(def now
"An example interceptor (of dubious utility) which is an example of adding
to a handler's coeffects. This interceptor adds the current datetime to coeffects under
the `:now` key.
Why? We want out handlers to be as pure as possible. If a handler calls `js/Date.` then
it stops being as pure. What if it needs a random number? These kinds of needed
\"inputs\" are referred to `coeffects` (sometimes called side-causes).
usage:
(reg-event-fx ;; notice use of `-fx` registration
:some-id
[i1 i2 now] ;; notice use of `now` as one of the handler's interceptors
(fn [world event] ;; world is the handler's coeffect
(let [dt (:now world)] ;; `:now` is available becaue `now` put it there.
...)))
As an exercise, consider how you would write a `random` interceptor which adds a random
number into a handler's coeffect?
"
(->interceptor
:name :now
:before (fn now-before
[context]
(assoc-coeffect context :now (js/Date.)))))
(def debug

View File

@ -3,7 +3,7 @@
[re-frame.db :refer [app-db]]
[re-frame.interop :refer [add-on-dispose! debug-enabled? make-reaction ratom?]]
[re-frame.loggers :refer [console]]
[re-frame.registrar :refer [get-handler register-handler]]
[re-frame.registrar :refer [get-handler clear-handlers register-handler]]
[re-frame.utils :refer [first-in-vector]]))
@ -27,7 +27,7 @@
(defn clear-all-handlers!
"Unregisters all existing subscription handlers"
[]
; (reset! qid->fn {}) XXX
(clear-handlers kind)
(reset! query->reaction {}))
(defn cache-and-return
@ -36,10 +36,9 @@
(let [cache-key [query-v dynv]]
;; when this reaction is nolonger being used, remove it from the cache
(add-on-dispose! r #(do (swap! query->reaction dissoc cache-key)
(console :log "Removing subscription: " cache-key)))
;; cache this reaction, so it can be used to deduplicate other, identical subscriptions
(console :log "Removing subscription: " cache-key))) ;; XXX remove console debug
;; cache this reaction, so it can be used to deduplicate other, later "=" subscriptions
(swap! query->reaction assoc cache-key r)
r)) ;; return the actual reaction
(defn cache-lookup
@ -148,7 +147,8 @@
(map last))]
(cond
sub-fn ;; first case the user provides a custom sub-fn
(register
(register-handler
kind
sub-id
(fn subs-handler-fn ;; multi-arity to match the arities `subscribe` might invoke.
([db q-vec]
@ -161,7 +161,8 @@
(fn [] (f (multi-deref subscriptions) q-vec d-vec)))))))
(seq arrow-args) ;; the user uses the :<- sugar
(register
(register-handler
kind
sub-id
(letfn [(get-subscriptions []
(let [subscriptions (map subscribe arrow-subs)]
@ -179,7 +180,8 @@
(fn [] (f (multi-deref subscriptions) q-vec d-vec))))))))
:else
(register ;; the simple case with no subs
(register-handler ;; the simple case with no subs
kind
sub-id
(fn subs-handler-fn
([db q-vec]