Skip to content

Commit

Permalink
1.4.0
Browse files Browse the repository at this point in the history
  • Loading branch information
flexsurfer committed Apr 9, 2021
1 parent 2d4dae8 commit 60ead92
Show file tree
Hide file tree
Showing 28 changed files with 1,189 additions and 447 deletions.
22 changes: 15 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

Take full control of [re-frame](https://github.com/Day8/re-frame) application.

Latest stable version: [![Clojars](https://img.shields.io/clojars/v/re-frisk.svg)](https://clojars.org/re-frisk) [![Clojars](https://img.shields.io/clojars/v/re-frisk-remote.svg)](https://clojars.org/re-frisk-remote)

## DEMO

https://flexsurfer.github.io/conduit-re-frisk-demo/
Expand All @@ -28,6 +30,14 @@ Render trace is supported only in the re-frisk-remote

<img src="/img/feature-subs.png" height="300">

#### Views sorted by mount order with subscripions

<img src="/img/feature-views.png" height="300">

#### re-frame handlres statistics

<img src="/img/feature-stat.png" height="300">

#### Graph for an epoch

<img src="/img/feature-event-subs-graph.png" height="300">
Expand All @@ -38,10 +48,8 @@ Render trace is supported only in the re-frisk-remote

## Usage

Latest stable version: [![Clojars](https://img.shields.io/clojars/v/re-frisk.svg)](https://clojars.org/re-frisk) [![Clojars](https://img.shields.io/clojars/v/re-frisk-remote.svg)](https://clojars.org/re-frisk-remote)

`[re-frisk "1.3.12"]`
`[re-frisk-remote "1.3.12"]`
`[re-frisk "1.4.0"]`
`[re-frisk-remote "1.4.0"]`

**Important**: Please note the following compatibility table:

Expand All @@ -58,7 +66,7 @@ re-frisk Version | React Version | Reagent Versions

re-frisk will be embedded in the DOM of your application. So my suggestion is to use re-frisk-remote, it doesn't affect your application and has more features

1. Add re-frisk as a dev dependency `[re-frisk "1.3.12"]`
1. Add re-frisk as a dev dependency `[re-frisk "1.4.0"]`

2. Enable re-frisk

Expand All @@ -75,7 +83,7 @@ re-frisk will be embedded in the DOM of your application. So my suggestion is to

[![Clojars](https://img.shields.io/clojars/v/re-frisk-remote.svg)](https://clojars.org/re-frisk-remote)

1. Add re-frisk as a dev dependency `[re-frisk-remote "1.3.12"]`
1. Add re-frisk as a dev dependency `[re-frisk-remote "1.4.0"]`

2. Enable re-frisk on default port (4567):

Expand All @@ -95,7 +103,7 @@ re-frisk will be embedded in the DOM of your application. So my suggestion is to

add in `deps.edn`

`:aliases {:dev {:extra-deps {re-frisk-remote {:mvn/version "1.3.12"}}}}}`
`:aliases {:dev {:extra-deps {re-frisk-remote {:mvn/version "1.4.0"}}}}}`

create `re_frisk.clj`

Expand Down
5 changes: 5 additions & 0 deletions dev/re_frisk/demo.cljs
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,9 @@
(fn []
[:div @text])))

(defn empty-component [])
(defn empty-component-with-param [param])

(defn simple-example
[]
(reagent/create-class
Expand All @@ -203,6 +206,8 @@
(if @form1?
[form1]
[form2])
[empty-component]
[empty-component-with-param form1?]
[:div]
[:div {:style {:background-color "#CCCCCC" :width 150 :margin-top 10}
:on-click #(re-frame/dispatch [::start-time])}
Expand Down
Binary file added img/feature-stat.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added img/feature-views.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@
"dev-remote": "shadow-cljs watch dev-remote",
"client": "shadow-cljs watch client",
"client-release": "shadow-cljs release client-release",
"test": "shadow-cljs compile test"
"test": "shadow-cljs compile test",
"server": "shadow-cljs run re-frisk-remote.core/start"
},
"dependencies": {
"react": "16.13.0",
Expand Down
2 changes: 1 addition & 1 deletion project.clj
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
(defproject re-frisk-remote "1.3.12"
(defproject re-frisk-remote "1.4.0"
:description "Take full control of re-frame app"
:url "https://github.com/flexsurfer/re-frisk"
:license {:name "MIT"
Expand Down
2 changes: 1 addition & 1 deletion re-frisk/project.clj
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
(defproject re-frisk "1.3.12"
(defproject re-frisk "1.4.0"
:description "Take full control of re-frame app"
:url "https://github.com/flexsurfer/re-frisk"
:license {:name "MIT"
Expand Down
24 changes: 21 additions & 3 deletions re-frisk/src/day8/reagent/impl/batching.cljs
Original file line number Diff line number Diff line change
@@ -1,15 +1,18 @@
(ns day8.reagent.impl.batching
(:require
[reagent.impl.batching :as batching]
[re-frame.trace :as trace :include-macros true]))
[re-frame.trace :as trace :include-macros true]
[clojure.string :as string]
[reagent.impl.component :as component]))

(def operation-name (memoize (fn [c] (last (string/split (component/component-name c) #" > ")))))

(defonce original-next-tick reagent.impl.batching/next-tick)

(defn next-tick
[f]
;; Schedule a trace to be emitted after a render if there is nothing else scheduled after that render.
;; This signals the end of the epoch.

(original-next-tick
(fn []
(trace/with-trace
Expand All @@ -19,6 +22,21 @@
(when (false? (.-scheduled? reagent.impl.batching/render-queue))
(trace/with-trace {:op-type :reagent/quiescent}))))))

(defonce original-run-queue reagent.impl.batching/run-queue)

(defn run-queue [a]
;; sort components by mount order, to make sure parents
;; are rendered before children
(.sort a batching/compare-mount-order)
(dotimes [i (alength a)]
(let [^js/React.Component c (aget a i)]
(when (true? (.-cljsIsDirty c))
(trace/with-trace
{:op-type :force-update
:operation (operation-name c)}
(.forceUpdate c))))))

(defn patch-next-tick
[]
(set! reagent.impl.batching/next-tick next-tick))
(set! reagent.impl.batching/next-tick next-tick)
(set! reagent.impl.batching/run-queue run-queue))
80 changes: 47 additions & 33 deletions re-frisk/src/day8/reagent/impl/component.cljs
Original file line number Diff line number Diff line change
Expand Up @@ -34,49 +34,63 @@
:displayName name
:cljsLegacyRender legacy-render
:reagentRender render-fun
:componentDidMount (fn componentDidMount []
(this-as c
(trace/with-trace
{:op-type :componentDidMount
:operation (operation-name c)
:tags {:order (gobj/get c "cljsMountOrder")}})
(when-let [f (:componentDidMount fmap)]
(.call f c))))
:componentWillUnmount (fn componentWillUnmount []
(this-as c
(trace/with-trace
{:op-type :componentWillUnmount
:operation (operation-name c)})
(when-let [f (:componentWillUnmount fmap)]
(.call f c))))
;:shouldComponentUpdate
#_(fn shouldComponentUpdate [nextprops nextstate]
(this-as c
(trace/with-trace
{:op-type :should-upd
:operation (operation-name c)}
(when-let [f (:shouldComponentUpdate fmap)]
(.call f c nextprops nextstate)))))
:render (fn render []
(this-as c
(trace/with-trace
{:op-type :render
:tags (if-let [component-name (component/component-name c)]
{:component-name component-name}
{})
:operation (operation-name c)})
(if util/*non-reactive*
(component/do-render c compiler)
(let [^clj rat (gobj/get c "cljsRatom")
_ (batch/mark-rendered c)
res (if (nil? rat)
(ratom/run-in-reaction #(component/do-render c compiler) c "cljsRatom"
batch/queue-render component/rat-opts)
(._run rat false))
cljs-ratom (gobj/get c "cljsRatom")]
(trace/merge-trace!
{:tags {:reaction (interop/reagent-id cljs-ratom)
:input-signals (when cljs-ratom
(map interop/reagent-id (gobj/get cljs-ratom "watching" :none)))}})
res)))))))
:operation (operation-name c)}
(if util/*non-reactive*
(component/do-render c compiler)
(let [^clj rat (gobj/get c "cljsRatom")
_ (batch/mark-rendered c)
res (if (nil? rat)
(ratom/run-in-reaction #(component/do-render c compiler) c "cljsRatom"
batch/queue-render component/rat-opts)
(._run rat false))
cljs-ratom (gobj/get c "cljsRatom")]
(trace/merge-trace!
{:tags {:reaction (interop/reagent-id cljs-ratom)
:input-signals (when cljs-ratom
(map interop/reagent-id (gobj/get cljs-ratom "watching" :none)))}})
res))))))))

(defn patch-wrap-funs
[]
(set! reagent.impl.component/wrap-funs wrap-funs))

(defonce original-custom-wrapper reagent.impl.component/custom-wrapper)
;(defonce original-create-class reagent.impl.component/create-class)

(defn custom-wrapper
[key f]
(case key
:componentWillUnmount
(fn componentWillUnmount []
(this-as c
(trace/with-trace
{:op-type key
:operation (last (string/split (component/component-name c) #" > "))
:tags {:component-name (component/component-name c)
:reaction (interop/reagent-id (gobj/get c "cljsRatom"))}})
(.call (original-custom-wrapper key f) c c)))
(original-custom-wrapper key f)))

(defn patch-custom-wrapper
[]
(set! reagent.impl.component/custom-wrapper custom-wrapper))
#_(defn create-class
[body compiler]
(trace/with-trace
{:op-type :create-class}
(let [cmp (original-create-class body compiler)]
(trace/merge-trace!
{:operation (.-displayName cmp)})
cmp)))
9 changes: 9 additions & 0 deletions re-frisk/src/re_frisk/clipboard.cljs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
(ns re-frisk.clipboard)

(defn copy-to-clip [text]
(let [el (.createElement js/document "textarea")]
(set! (.-value el) text)
(.appendChild js/document.body el)
(.select el)
(.execCommand js/document "copy")
(.removeChild js/document.body el)))
27 changes: 18 additions & 9 deletions re-frisk/src/re_frisk/core.cljs
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,19 @@
[re-frame.trace]
[re-frisk.trace :as trace]
[re-frisk.subs-graph :as subs-graph]
[re-frame.interop :as interop]))
[re-frame.interop :as interop]
[re-frisk.stat :as stat]
[day8.reagent.impl.batching :refer [patch-next-tick]]))

(defonce initialized (atom false))
(defonce prev-event (atom {}))

(defonce re-frame-data
{:app-db (reagent/atom "not connected")
{:app-db (reagent/atom "no data")
:events (reagent/atom [])
:subs (reagent/atom "not connected")})
:subs (reagent/atom "no data")
:stat (reagent/atom {})
:views (reagent/atom {})})

(defn update-db-and-subs []
;;we need to deref all subscriptions, overwise they won't be deactivated
Expand All @@ -29,12 +33,15 @@
(let [ignore-events (get-in @data/tool-state [:opts :ignore-events])
normalized (trace/normalize-traces traces ignore-events)
first-event (or (first @(:events re-frame-data)) (first normalized))]
(swap! (:events re-frame-data)
concat
(map (trace/normalize-durations first-event)
normalized))
(subs-graph/update-subs (filter :subs? normalized))
(utils/call-and-chill update-db-and-subs 500))))
(when (seq normalized)
(swap! (:events re-frame-data)
concat
(map (trace/normalize-durations first-event)
normalized))
(stat/init-stat re-frame-data)
(stat/update-trace-stat re-frame-data normalized)
(js/setTimeout #(subs-graph/update-subs (filter :subs? normalized)) 100)
(utils/call-and-chill update-db-and-subs 500)))))

(defn- post-event-callback [value queue]
(when-not (:paused? @data/tool-state)
Expand All @@ -44,6 +51,8 @@
;;This diff may be expensive
diff (diff/diff (:app-db @prev-event) app-db)]
(reset! prev-event {:app-db app-db})
(stat/init-stat re-frame-data)
(stat/update-event-stat re-frame-data (first value))
(when (or (not ignore-events) (not (get ignore-events (first value))))
(swap! (:events re-frame-data) conj {:event value
:app-db-diff diff
Expand Down
41 changes: 41 additions & 0 deletions re-frisk/src/re_frisk/stat.cljs
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
(ns re-frisk.stat
(:require [re-frame.registrar :as reg]))

(defn assoc-map [acc key]
(assoc acc key {:cnt 0 :ms 0}))

(defn get-re-frame-handlers []
{:fx (reduce assoc-map {} (keys (dissoc (:fx @reg/kind->id->handler)
:dispatch-later
:fx
:dispatch
:dispatch-n
:deregister-event-handler
:db)))
:cofx (reduce assoc-map {} (keys (dissoc (:cofx @reg/kind->id->handler) :db)))
:event (reduce assoc-map {} (keys (:event @reg/kind->id->handler)))
:sub (reduce assoc-map {} (keys (:sub @reg/kind->id->handler)))})

(defn init-stat [re-frame-data]
(when (empty? @(:stat re-frame-data))
(reset! (:stat re-frame-data) (get-re-frame-handlers))))

(defn update-trace-stat [re-frame-data traces]
(doseq [{:keys [event subs duration effects coeffects]} traces]
(when event
(swap! (:stat re-frame-data) update-in [:event (first event) :cnt] inc)
(swap! (:stat re-frame-data) update-in [:event (first event) :ms] + duration)
(when (pos? (count effects))
(doseq [key (keys effects)]
(swap! (:stat re-frame-data) update-in [:fx key :cnt] inc)))
(when (pos? (count coeffects))
(doseq [key (keys coeffects)]
(swap! (:stat re-frame-data) update-in [:cofx key :cnt] inc))))
(when (seq subs)
(doseq [{:keys [op-type operation duration]} subs]
(when (= op-type :sub/run)
(swap! (:stat re-frame-data) update-in [:sub operation :cnt] inc)
(swap! (:stat re-frame-data) update-in [:sub operation :ms] + duration))))))

(defn update-event-stat [re-frame-data event]
(swap! (:stat re-frame-data) update-in [:event event :cnt] inc))
Loading

0 comments on commit 60ead92

Please sign in to comment.