Skip to content

Instantly share code, notes, and snippets.

@roman01la
Last active October 21, 2020 11:32
Show Gist options
  • Save roman01la/ac4a8363b0dcb0edafe261b8b7697dfe to your computer and use it in GitHub Desktop.
Save roman01la/ac4a8363b0dcb0edafe261b8b7697dfe to your computer and use it in GitHub Desktop.
Debugging re-frame subscriptions
(ns utils.re-frame
(:require [cljs.compiler :as cljsc]))
(defn- anonymous-function-declaration? [form]
(and (list? form)
(= 'fn (first form))
(vector? (second form))))
(defn- query-id->js-fn-name [query-id]
(let [ns-part (when-let [ns-part (namespace query-id)]
(cljsc/munge ns-part))
name-part (when-let [name-part (name query-id)]
(cljsc/munge name-part))]
(if ns-part
(symbol (str ns-part "$" name-part))
(symbol name-part))))
(defn- anonymous-fn->named-fn [f fn-name]
(let [[_ fn-args & fn-body] f]
`(fn ~fn-name ~fn-args ~@fn-body)))
(defmacro reg-sub
"Generates readbale names for both input signals and computation fns in a subscription"
[query-id & args]
(if (keyword? query-id)
(let [computation-fn (last args)
input-args (butlast args)
deps-fn (first input-args)
named-computation-fn (if (anonymous-function-declaration? computation-fn)
(->> (query-id->js-fn-name query-id)
(anonymous-fn->named-fn computation-fn))
computation-fn)
named-deps-fn (when (and (== 1 (count input-args))
(anonymous-function-declaration? deps-fn))
(->> (str (query-id->js-fn-name query-id) "$deps_fn")
symbol
(anonymous-fn->named-fn deps-fn)))]
(if named-deps-fn
`(utils.re-frame/reg-sub ~query-id ~named-deps-fn ~named-computation-fn)
`(utils.re-frame/reg-sub ~query-id ~@input-args ~named-computation-fn)))
`(utils.re-frame/reg-sub ~query-id ~@args)))
(ns utils.re-frame
(:require [re-frame.core :as rf]))
(def reg-sub
;; wraps computation fn of a subscription with measuring code
(if (and (exists? js/window.performance.mark)
(exists? js/window.performance.measure))
(fn [query-id & args]
(let [query-id-str (str query-id)
computation-fn (last args)
subscription-fn-measure (fn subscription-fn-measure [inputs query]
(.mark js/performance query-id-str)
(let [ret (computation-fn inputs query)]
(.measure js/performance (str "🚂 subscription " query-id-str) query-id-str)
ret))]
(apply rf/reg-sub query-id (concat (butlast args) (list subscription-fn-measure)))))
rf/reg-sub))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment