day8 / re-frame-10x

A debugging dashboard for re-frame. X-ray vision as tooling.
MIT License
630 stars 68 forks source link

React Native support? #75

Closed jeaye closed 6 years ago

jeaye commented 6 years ago

Based on my reading of the source, this seems to be web-focused. The tracing aspect of it, and monkey patching of Reagent, should be portable though, I think. Is there any plan to support React Native, or make this modular so it can be reused by someone looking to build a similar UI for React Native?

I see that re-frame.trace exists, and is used here, but the debugging documentation seems dated and doesn't mention it. I could really use this detailed tracing and would appreciate any suggestions.

danielcompton commented 6 years ago

Hey, I've never used react-native, so I'm not sure how to integrate this with it. Would you want to see re-frame-trace in the same window as your app (seems like it would be too small?), or do you attach a remote debugger to it to step through things? I'd love to support it well, but I don't really know what you'd need to do that.

but the debugging documentation seems dated and doesn't mention it

Yeah, re-frame-trace is still in alpha, so we haven't been promoting it very heavily, but @daiyi and @saskali have been doing good work on it, so hopefully we can start promoting it more heavily soon.

I could really use this detailed tracing and would appreciate any suggestions.

Yep, re-frame-trace really shines on detailed tracing, the big challenge we have is that most of the time that is too much information for people.

jeaye commented 6 years ago

Awesome reply, thank you.

I think that rendering any panel in-app for React Native probably wouldn't work very well, due to the size constraints. The big thing I'm interested in, honestly, is the tracing. If we could get re-frame-trace usable in React Native, so that it just logs all the trace data to stdout with some tag on the front, there could then be a separate tool for reading the stream of logs and building some UI for it.

In how I was originally planning to tackle this (since we have performance issues in our re-frame app and I want a very detailed understanding of where all time is being spent), I would hook all of my subs, event, handlers, etc to print out profile information and then I'd pipe the logs to maybe a ring server which is feeding the info to a cljs client. Since finding re-frame-trace, I think I could ultimately do something similar, if we can get the tracing going.

I'll stress that the UI is less of a concern, probably for everyone, compared to having some really nice tracing data which then can be massaged into whatever.

danielcompton commented 6 years ago

Happy to add support for this in a PR, but unlikely to do anything ourselves on it. Closing this for now, but feel free to open PRs.

jeaye commented 6 years ago

Yep. I have a working version here, with forks and fixes for both re-frame and re-frame-trace. I'll get some PRs going once things stabalize.

danielneal commented 6 years ago

What would be really nice / absolutely amazing is if this worked like re-frisk remote and you could use the same ui, just in a different window.

jeaye commented 6 years ago

I agree, though I'm not sure if you mean re-frisk's UI or re-frame-trace's. Either way, I agree. What I've implemented now is basically the same approach as re-frame-frisk, but focusing on the monkey patched events that we get from re-frame-trace. I'd like to also add in all of the data, like re-frisk, now that I actually have things working, so that both the events + timing and the event data can be logged. Eventually merging my work into re-frisk-* or similar would be ideal, so we don't have yet another solution sitting around.

yenda commented 6 years ago

Hi, I work with @flexsurfer and we would like to add the tracing to re-frisk-remote. What have you done so far @jeaye ?

(re-frisk-remote is on the react-native side, sending re-frame events and subscriptions via a websocket to re-frisk which has a UI that you interact with in your web browser)

jeaye commented 6 years ago

@yenda I have a working version, though it's rough, which does something very similar to re-frisk. I send the events to a server using sente and have a web client which also uses sente to then show those events streaming by. I can follow up with some more info, issues, and PRs this weekend.

It's great to hear that you're interested in adding this to re-frisk-remote; my goal was to ultimately merge into it as well. Hopefully the issues I found in order to get the prototype going will ease the integration. It's late now, but I'll follow up soon.

yenda commented 6 years ago

@jeaye a followup would be awesome, we are definitely interested to add this to re-frisk-remote !

jeaye commented 6 years ago

Ok, I'll follow up with the clearest notes I can.

re-frame-trace

In order to get things preloaded, I followed the preload hack above to get figwheel-bridge.js loading this:

(ns my-app.preload
  (:require [day8.re-frame.trace.preload]))

My tracing just uses sente and is mostly boilerplate, except for the last function:

(ns my-app.trace
  (:require-macros [cljs.core.async.macros :as asyncm :refer [go go-loop]])
  (:require [clojure.core.async :as async :refer [<! >! put! chan]]
            [taoensso.encore :as encore :refer-macros [have have?]]
            [taoensso.sente :as sente :refer [cb-success?]]
            [re-frame.trace :as trace :include-macros true]
            [lets-bet.common.debug :refer [pprint]]))

; Required for sente
(let [{:keys [chsk ch-recv send-fn state]}
      (sente/make-channel-socket! "/chsk" {:host "192.168.0.12:8090"
                                           :protocol :http
                                           :type :ws})]
  (def chsk chsk)
  (def ch-chsk ch-recv) ; ChannelSocket's receive channel
  (def chsk-send! send-fn) ; ChannelSocket's send API fn
  (def chsk-state state) ; Watchable, read-only atom
  )

(defmulti -event-msg-handler
  "Multimethod to handle Sente `event-msg`s"
  :id)

(defn event-msg-handler
  "Wraps `-event-msg-handler` with logging, error catching, etc."
  [{:as ev-msg :keys [id ?data event]}]
  (-event-msg-handler ev-msg))

(defmethod -event-msg-handler
  :default ; Default/fallback case (no other matching handler)
  [{:as ev-msg :keys [event]}]
  (println "Unhandled event:" event))

(defmethod -event-msg-handler :chsk/state
  [{:as ev-msg :keys [?data]}]
  (let [[old-state-map new-state-map] (have vector? ?data)]
    (if (:first-open? new-state-map)
      (println "Channel socket successfully established!:" new-state-map)
      (println "Channel socket state change:" new-state-map))))

(defmethod -event-msg-handler :chsk/recv
  [{:as ev-msg :keys [?data]}]
  (println "Push event from server:" ?data))

(defmethod -event-msg-handler :chsk/handshake
  [{:as ev-msg :keys [?data]}]
  (let [[?uid ?csrf-token ?handshake-data] ?data]
    (println "Handshake:" ?data)))

(defonce router_ (atom nil))
(defn stop-router! []
  (when-let [stop-f @router_]
    (stop-f)))
(defn start-router! []
  (stop-router!)
  (reset! router_
          (sente/start-client-chsk-router! ch-chsk event-msg-handler)))

(defn start! []
  (start-router!)
  (trace/register-trace-cb ::cb (fn [traces]
                                  (.log js/console "Sending traces: " (count traces))
                                  (chsk-send! [:trace/log traces]))))

I call my-app.trace/start! from my-app.core.

danielcompton commented 6 years ago

Does https://github.com/flexsurfer/re-frisk-remote/pull/11 make it possible to use 10x with react native now?

jeaye commented 6 years ago

It sure does!

jeaye commented 6 years ago

I think there are some other PRs which will need to be merged, as mentioned in the one you linked, but the ball is rolling.