Track if a subscription is unchanged

This commit is contained in:
Daniel Compton 2018-02-09 02:30:57 +13:00
parent 3f94b3c960
commit 4a5b00b713
3 changed files with 57 additions and 39 deletions

View File

@ -289,32 +289,42 @@
(filter (fn [me] (when-not (:disposed? (val me)) me)))
;; Remove transient state
(map (fn [[k v]]
[k (dissoc v :order :created? :run? :disposed? :previous-value)])))
[k (dissoc v :order :created? :run? :disposed? :previous-value :sub/traits)])))
state))
(defn process-sub-traces
[initial-state traces]
(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)
(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))))
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))))
initial-state
traces)
second-pass (reduce (fn [all-state [sub-id sub-state]]
(if (and (contains? sub-state :previous-value)
(contains? sub-state :value)
(= (:previous-value sub-state) (:value sub-state)))
(assoc-in all-state [sub-id :sub/traits :unchanged?] true)
all-state))
first-pass
first-pass)]
second-pass))
(defn subscription-match-state
"Build up the state of re-frame's running subscriptions over each matched epoch.

View File

@ -396,14 +396,15 @@
(s/def :sub/id string!)
(s/def :sub/reagent-id string!)
(s/def :sub/type #{:created :re-run :destroyed :not-run})
(s/def :sub/run-types #{:sub/create :sub/dispose :sub/run :sub/not-run})
(s/def :sub/order (s/nilable (s/coll-of :sub/run-types)))
(s/def :sub/layer (s/nilable pos-int?))
(s/def :sub/path-data any?)
(s/def :sub/path string!)
(s/def :sub/value any?)
(s/def :sub/previous-value any?)
(s/def :subs/view-panel-sub
(s/keys :req-un [:sub/id :sub/reagent-id :sub/type :sub/layer :sub/path-data :sub/path]
(s/keys :req-un [:sub/id :sub/reagent-id :sub/order :sub/layer :sub/path-data :sub/path]
:opt-un [:sub/value :sub/previous-value]))
(s/def :subs/view-subs (s/coll-of :subs/view-panel-sub))
@ -441,11 +442,11 @@
subscription (:subscription state)
sub {:id (key me)
:reagent-id (key me)
:type :created
:layer (get-in sub-info [(first subscription) :layer])
:path-data subscription
:path (pr-str subscription)
:order (:order state)}
:order (:order state)
:sub/traits (:sub/traits state)}
sub (if (contains? state :value)
(assoc sub :value (:value state))
sub)

View File

@ -150,6 +150,9 @@
:margin "0px 3px"}}]]
[rc/gap-f :size common/gs-12s]]])
(def no-prev-value-msg [:p {:style {:font-style "italic"}} "No previous value exists to diff"])
(def unchanged-value-msg [:p {:style {:font-style "italic"}} "Subscription value is unchanged"])
(defn pod [{:keys [id layer path open? diff?] :as pod-info}]
(let [render-diff? (and open? diff?)
value? (contains? pod-info :value)
@ -174,7 +177,7 @@
:style {:margin (css-join pod-padding pod-padding "0px" pod-padding)
:overflow-x "auto"
:overflow-y "hidden"}
:children [(if (or value? previous-value?)
:children [(if (or value? #_ previous-value?)
[components/simple-render
main-value
["sub-path" path]]
@ -185,9 +188,11 @@
:leave-animation "accordionVertical"
:duration animation-duration})
(when render-diff?
(let [diffable? (and value? previous-value?)
[diff-before diff-after _] (clojure.data/diff (:previous-value pod-info)
(:value pod-info))]
(let [diffable? (and value? previous-value?)
previous-value (:previous-value pod-info)
value (:value pod-info)
unchanged-value? (get-in pod-info [:sub/traits :unchanged?] false)
[diff-before diff-after _] (clojure.data/diff previous-value value)]
[rc/v-box
:children [[rc/v-box
:class "app-db-path--link"
@ -203,11 +208,12 @@
:class "data-viewer data-viewer--top-rule"
:style {:overflow-x "auto"
:overflow-y "hidden"}
:children [(if diffable?
[components/simple-render
diff-before
["app-db-diff" path]]
[:p {:style {:font-style "italic"}} "No previous value exists to diff"])]]
:children [(cond
unchanged-value? unchanged-value-msg
diffable? [components/simple-render
diff-before
["app-db-diff" path]]
:else no-prev-value-msg)]]
[rc/v-box
:class "app-db-path--link"
:justify :end
@ -222,11 +228,12 @@
:class "data-viewer data-viewer--top-rule rounded-bottom"
:style {:overflow-x "auto"
:overflow-y "hidden"}
:children [(if diffable?
[components/simple-render
diff-after
["app-db-diff" path]]
[:p {:style {:font-style "italic"}} "No previous value exists to diff"])]]]]))]
:children [(cond
unchanged-value? unchanged-value-msg
diffable? [components/simple-render
diff-after
["app-db-diff" path]]
:else no-prev-value-msg)]]]]))]
(when open?
[rc/gap-f :size pod-padding])]]]]))