Provide not run subscriptions and avoid subs with a nil path

This commit is contained in:
Daniel Compton 2018-02-09 04:11:52 +13:00
parent 0259ef0a58
commit e4ee6ce567
2 changed files with 31 additions and 18 deletions

View File

@ -293,30 +293,43 @@
state))
(defn process-sub-traces
[initial-state traces]
(let [first-pass (reduce (fn [state trace]
(let [tags (get trace :tags)
reaction-id (:reaction tags)]
(case (:op-type trace)
:sub/create (assoc state reaction-id {:created? true
:subscription (:query-v tags)
:order [:sub/create]})
:sub/run (update state reaction-id (fn [sub-state]
(-> (if (contains? sub-state :value)
;; TODO: this should only update once per phase, even if a sub runs multiple times
(assoc sub-state :previous-value (:value sub-state))
sub-state)
(assoc :run? true
:value (:value tags))
(update :order (fnil conj []) :sub/run))))
:sub/dispose (-> (assoc-in state [reaction-id :disposed?] true)
(update-in [reaction-id :order] (fnil conj []) :sub/dispose))
(do #?(:cljs (js/console.warn "Unhandled sub trace, this is a bug, report to re-frame-trace please" trace))
state))))
reaction-id (:reaction tags)
state (-> state
(update-in [reaction-id :order] (fnil conj []) (:op-type trace))
;; In a perfect world we could provide this only in the :sub/create branch, but we have
;; zombie reactions roaming the DOM, so we re-add it on every trace in case a sub was
;; disposed of previously (and removed from the sub state).
(assoc-in [reaction-id :subscription] (:query-v tags)))
new-state
(case (:op-type trace)
:sub/create (-> state
(assoc-in [reaction-id :created?] true)
(assoc-in [reaction-id :subscription] (:query-v tags)))
:sub/run (update state reaction-id (fn [sub-state]
;; TODO: should we keep track of subscriptions that have been disposed
;; so we can detect zombies?
;; TODO: this should only update once per phase, even if a sub runs multiple times
(-> (if (contains? sub-state :value)
(assoc sub-state :previous-value (:value sub-state))
sub-state)
(assoc :run? true
:value (:value tags)))))
:sub/dispose (assoc-in state [reaction-id :disposed?] true))]
(when-not (contains? (get new-state reaction-id) :subscription)
#?(:cljs (js/console.warn trace (get new-state reaction-id))))
new-state))
initial-state
traces)
second-pass (reduce (fn [all-state [sub-id sub-state]]
;; TODO: integrate this into the first pass for efficiency
(if (and (contains? sub-state :previous-value)
(contains? sub-state :value)
(= (:previous-value sub-state) (:value sub-state)))

View File

@ -446,7 +446,7 @@
:layer (get-in sub-info [(first subscription) :layer])
:path-data subscription
:path (pr-str subscription)
:order (:order state)
:order (or (:order state) [:sub/not-run])
:sub/traits (:sub/traits state)}
sub (if (contains? state :value)
(assoc sub :value (:value state))