Sub inter-epoch handling
This commit is contained in:
parent
c427974800
commit
9d90992470
|
@ -9,6 +9,7 @@
|
|||
[binaryage/devtools "0.9.4"]
|
||||
[cljsjs/react-flip-move "2.9.17-0"]
|
||||
[com.yahoo.platform.yui/yuicompressor "2.4.8" :exclusions [rhino/js]]
|
||||
[expound "0.4.0"]
|
||||
]
|
||||
:plugins [[thomasa/mranderson "0.4.7"]
|
||||
[lein-less "RELEASE"]]
|
||||
|
|
|
@ -536,7 +536,7 @@
|
|||
;; like its reagent id, when it was created, run, disposed, what values it returned, e.t.c.
|
||||
subscription-info (metam/subscription-info (get-in db [:epochs :subscription-info] {}) filtered-traces (get-in db [:app-db :reagent-id]))
|
||||
sub-state (get-in db [:epochs :sub-state] metam/initial-sub-state)
|
||||
subscription-match-state (metam/subscription-match-state sub-state filtered-traces new-matches)
|
||||
subscription-match-state (utils/spy "SUB" (metam/subscription-match-state sub-state filtered-traces new-matches))
|
||||
subscription-matches (rest subscription-match-state)
|
||||
new-sub-state (last subscription-match-state)
|
||||
timing (mapv (fn [match]
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
(defn id-between-xf
|
||||
;; Copied here because I got undeclared Var warnings from figwheel when requiring a CLJC utils ns.
|
||||
"Returns a transducer that filters for :id between beginning and ending."
|
||||
"Returns a transducer that filters for :id between beginning and ending. Inclusive on both ends."
|
||||
[beginning ending]
|
||||
(filter #(<= beginning (:id %) ending)))
|
||||
|
||||
|
@ -208,7 +208,7 @@
|
|||
|
||||
(def initial-sub-state
|
||||
{:last-matched-id 0
|
||||
:reaction-state {}})
|
||||
:reaction-state {}})
|
||||
|
||||
(defn parse-traces [parse-state traces]
|
||||
(reduce
|
||||
|
@ -278,42 +278,96 @@
|
|||
3)))
|
||||
initial-state)))
|
||||
|
||||
(defn reset-sub-state
|
||||
"Remove information about the subscription that is transient and specific to a single
|
||||
phase."
|
||||
[state]
|
||||
(into {}
|
||||
(comp
|
||||
(filter (fn [me] (when-not (:disposed? (val me)) me)))
|
||||
(map (fn [[k v]]
|
||||
[k (dissoc v :order :created? :run? :disposed? :previous-value)])))
|
||||
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))
|
||||
|
||||
(defn subscription-match-state
|
||||
"Build up the state of re-frame's running subscriptions over each matched epoch.
|
||||
Returns initial state as first item in list"
|
||||
[sub-state filtered-traces new-matches]
|
||||
;; For each match that we process there are two phases:
|
||||
;; - Phase 1: Update and collect the state of the subscriptions that have trace between the last epoch
|
||||
;; and the new epoch. These traces can be from hover state, local ratom events, figwheel re-renders
|
||||
;; or rft resetting app-db. Most of the time these traces are noisy and not interesting, but we do
|
||||
;; need to use them to maintain our subscription state. We also want to show them down below the main
|
||||
;; subs, in case someone is wondering where they went. If there are no sub traces to process then
|
||||
;; this phase doesn't run.
|
||||
;; - Phase 2: Update and collect the state of the subscription traces within an epoch. These subscription
|
||||
;; traces are going to be changing because of app-db changes.
|
||||
;; We collect and present the state for both phases for consumption in the subs panel
|
||||
|
||||
|
||||
;#?(:cljs (js/console.log "New matches?" (not (empty? new-matches))))
|
||||
(reductions (fn [state match]
|
||||
(let [epoch-traces (into []
|
||||
(comp
|
||||
(id-between-xf (:id (first match)) (:id (last match)))
|
||||
(filter subscription?))
|
||||
filtered-traces)
|
||||
reset-state (into {}
|
||||
(comp
|
||||
(filter (fn [me] (when-not (:disposed? (val me)) me)))
|
||||
(map (fn [[k v]]
|
||||
[k (dissoc v :order :created? :run? :disposed? :previous-value)])))
|
||||
(:reaction-state state))]
|
||||
(->> epoch-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))))
|
||||
reset-state)
|
||||
(assoc state :reaction-state))))
|
||||
(let [previous-id (:last-matched-id state)
|
||||
first-match-id (:id (first match))
|
||||
last-match-id (:id (last match))
|
||||
pre-epoch-traces (into []
|
||||
(comp
|
||||
(id-between-xf (inc previous-id)
|
||||
(dec first-match-id))
|
||||
(filter subscription?))
|
||||
filtered-traces)
|
||||
epoch-traces (into []
|
||||
(comp
|
||||
(id-between-xf first-match-id last-match-id)
|
||||
(filter subscription?))
|
||||
filtered-traces)
|
||||
reset-rx-state (reset-sub-state (:reaction-state state))]
|
||||
(-> (->> epoch-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))))
|
||||
reset-rx-state)
|
||||
(assoc state :reaction-state))
|
||||
(assoc :first-matched-id first-match-id
|
||||
:last-matched-id last-match-id
|
||||
:previous-matched-id previous-id))))
|
||||
sub-state
|
||||
new-matches))
|
||||
|
|
|
@ -2,7 +2,9 @@
|
|||
(:require [mranderson047.re-frame.v0v10v2.re-frame.core :as rf]
|
||||
[day8.re-frame.trace.metamorphic :as metam]
|
||||
[day8.re-frame.trace.utils.utils :as utils]
|
||||
[clojure.string :as str]))
|
||||
[clojure.string :as str]
|
||||
[cljs.spec.alpha :as s]
|
||||
[expound.alpha :as expound]))
|
||||
|
||||
(rf/reg-sub
|
||||
:settings/root
|
||||
|
@ -390,6 +392,38 @@
|
|||
(fn [match-state]
|
||||
(:sub-state match-state)))
|
||||
|
||||
(def string! (s/and string? #(not (empty? %))))
|
||||
|
||||
(s/def :sub/id string!)
|
||||
(s/def :sub/reagent-id string!)
|
||||
(s/def :sub/type #{:created :re-run :destroyed :not-run})
|
||||
(s/def :sub/layer 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]
|
||||
:opt-un [:sub/value :sub/previous-value]))
|
||||
(s/def :subs/view-subs (s/coll-of :subs/view-panel-sub))
|
||||
|
||||
|
||||
(rf/reg-sub
|
||||
:subs/inter-epoch-subs
|
||||
(fn [db]
|
||||
(let [sub
|
||||
[{:id ":test1"
|
||||
:reagent-id "ra87"
|
||||
:type :created
|
||||
:layer 3
|
||||
:path-data [:test/sub]
|
||||
:path (pr-str [:test/sub])
|
||||
:value 5
|
||||
:previous-value 3}]]
|
||||
(when-not (s/valid? :subs/view-subs sub)
|
||||
(js/console.error (expound/expound-str :subs/view-subs sub)))
|
||||
sub)))
|
||||
|
||||
(defn sub-sort-val
|
||||
[sub]
|
||||
(case (:type sub)
|
||||
|
@ -464,8 +498,12 @@
|
|||
(filter (fn [[k v]] (< 1 v)))
|
||||
(frequencies (map :id raw)))
|
||||
|
||||
output (map (fn [sub] (assoc sub :run-times (get run-multiple? (:id sub)))) raw)]
|
||||
(sort-by identity subscription-comparator output))))
|
||||
output (map (fn [sub] (assoc sub :run-times (get run-multiple? (:id sub)))) raw)
|
||||
subs (sort-by identity subscription-comparator output)]
|
||||
(when-not (s/valid? :subs/view-subs subs)
|
||||
(js/console.error (expound/expound-str :subs/view-subs subs)))
|
||||
subs
|
||||
)))
|
||||
|
||||
(rf/reg-sub
|
||||
:subs/visible-subs
|
||||
|
|
|
@ -149,7 +149,7 @@
|
|||
[rc/v-box
|
||||
:size "auto"
|
||||
:style {:margin-left common/gs-19s
|
||||
:overflow-y (if (contains? #{:timing :debug :event} @selected-tab)
|
||||
:overflow-y (if (contains? #{:timing :debug :event :subs} @selected-tab)
|
||||
"auto" "initial")
|
||||
;:overflow "auto" ;; TODO: Might have to put this back or add scrolling within the panels
|
||||
}
|
||||
|
|
|
@ -236,12 +236,13 @@
|
|||
|
||||
(defn pod-section []
|
||||
(let [visible-subs @(rf/subscribe [:subs/visible-subs])
|
||||
inter-epoch-subs @(rf/subscribe [:subs/inter-epoch-subs])
|
||||
sub-expansions @(rf/subscribe [:subs/sub-expansions])
|
||||
all-subs (if @(rf/subscribe [:settings/debug?])
|
||||
(cons {:path [:subs/current-epoch-sub-state] :id "debug" :value @(rf/subscribe [:subs/current-epoch-sub-state])} visible-subs)
|
||||
visible-subs)]
|
||||
[rc/v-box
|
||||
:size "1"
|
||||
;:size "1"
|
||||
;:gap pod-gap
|
||||
|
||||
;:children (if (empty? all-subs)
|
||||
|
@ -253,16 +254,35 @@
|
|||
:children [(if (and (empty? all-subs) @*finished-animation?)
|
||||
[no-pods]
|
||||
[rc/box :width "0px" :height "0px"])
|
||||
[animated/component
|
||||
|
||||
(for [p all-subs]
|
||||
^{:key (:id p)}
|
||||
[pod (merge p (get sub-expansions (:id p)))])
|
||||
#_[animated/component
|
||||
(animated/v-box-options {:on-finish #(reset! *finished-animation? true)
|
||||
:duration animation-duration
|
||||
:style {:flex "1 1 0px"
|
||||
:overflow-x "hidden"
|
||||
:overflow-y "auto"}})
|
||||
|
||||
(for [p all-subs]
|
||||
^{:key (:id p)}
|
||||
[pod (merge p (get sub-expansions (:id p)))])]]
|
||||
]
|
||||
[rc/line :size "5px"
|
||||
:style {:margin "19px 0px"}]
|
||||
[:h2 {:class "bm-heading-text"
|
||||
:style {:margin "19px 0px"}} "Inter-epoch subscriptions"]
|
||||
(for [p inter-epoch-subs]
|
||||
^{:key (:id p)}
|
||||
[pod (merge p (get sub-expansions (:id p)))])
|
||||
|
||||
#_[animated/component
|
||||
(animated/v-box-options {:on-finish #(reset! *finished-animation? true)
|
||||
:duration animation-duration
|
||||
:style {:flex "1 1 0px"
|
||||
:overflow-x "hidden"
|
||||
:overflow-y "auto"}})
|
||||
|
||||
]
|
||||
]
|
||||
|
||||
]))
|
||||
|
||||
|
|
Loading…
Reference in New Issue