Skip to content

Instantly share code, notes, and snippets.

@mbertheau
Created July 26, 2017 12:02
Show Gist options
  • Save mbertheau/5235deb2f26fb3e26290b0a03a0dbc32 to your computer and use it in GitHub Desktop.
Save mbertheau/5235deb2f26fb3e26290b0a03a0dbc32 to your computer and use it in GitHub Desktop.
(defmacro listen [[sub-name & args]]
(let [ns-name (str *ns*)
ns-prefix (str (subs ns-name 0 (s/index-of ns-name \.)) "/")]
`(deref (re-frame.core/subscribe [(keyword (str ~ns-prefix (name ~sub-name)))
~@args]))))
(defmacro r-sub
[sub-name args inputs body]
(let [query-v (into ['_] args)
partitioned-inputs (partition 2 inputs)
input-query-vectors (mapv second partitioned-inputs)
input-names* (mapv first partitioned-inputs)
input-names (if (empty? input-names*) 'db input-names*)
ns-name (str *ns*)
ns-prefix (str (subs ns-name 0 (s/index-of ns-name \.)) "/")
input-fn `(fn [~query-v ~'_]
[~@(for [[input-sub-name & input-sub-args] input-query-vectors]
`(re-frame.core/subscribe [(keyword (str ~ns-prefix (name ~input-sub-name))) ~@input-sub-args]))])
value-fn `(fn [~input-names ~query-v ~'_] ~body)
sub-name* `(keyword (str ~ns-prefix (name ~sub-name)))]
(if (empty? input-query-vectors)
`(re-frame.core/reg-sub ~sub-name* ~value-fn)
`(re-frame.core/reg-sub ~sub-name* ~input-fn ~value-fn))))
(defmacro reg-many-subs
[m prefix]
(let [path->kw #(->> % (map name) (clojure.string/join "-"))
prefix* (path->kw prefix)
input-v (if (empty? prefix) [] [(symbol prefix*) [(keyword prefix*)]])
input-symbol (if (empty? prefix) 'db (symbol prefix*))
make-sub-name #(-> prefix (conj %) path->kw keyword)]
`(do ~@(cond
(vector? m) (for [key m]
(let [sub-name (make-sub-name key)
body `(~key ~input-symbol)]
`(r-sub ~sub-name [] ~input-v ~body)))
(map? m) (for [[key children] m]
(let [sub-name (make-sub-name key)
body `(~key ~input-symbol)]
`(do (r-sub ~sub-name [] ~input-v ~body)
(reg-many-subs ~children ~(conj prefix key)))))))))
(comment
(reg-many-subs {:data [:settlement-receivers
:employees]} [])
(r-sub :place-of-business [n] [places-of-business [:places-of-business]]
(get places-of-business n))
; see also https://github.com/Day8/re-frame/issues/354
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment