Skip to content

Instantly share code, notes, and snippets.

@dustingetz
Last active February 20, 2022 02:06
Show Gist options
  • Save dustingetz/c0c541b4fe3d429a44616ee80ddd9399 to your computer and use it in GitHub Desktop.
Save dustingetz/c0c541b4fe3d429a44616ee80ddd9399 to your computer and use it in GitHub Desktop.
(require '[hyperfiddle.photon :as p]
'[hyperfiddle.api :as hf])
(hfql [{(submissions "")
[{(:dustingetz/shirt-size . {::hf/options (shirt-sizes gender)})
[:db/id :db/ident]}
{(:dustingetz/gender . {::hf/options (genders)})
[:db/id (:db/ident . {::hf/as gender})]}]}
{(genders)
[:db/ident]}])
; HFQL macroexpansion to Photon
; #' is remapped to reactive-quote, it "quotes" down a layer to get a reference to the underlying dataflow typed value
; ~ is mapped to reactive-unquote, which joins a flow value back into the photon execution dataflow
; Here, we are using reactive-quote to control laziness so that expensive database queries
; are only paid for if the client renderer samples them.
(let [>submissions #'(submissions "")
>genders #'(genders)
>dustingetz_gender_options >genders]
(render
#'{'(submissions "")
#'(render
#'(p/for [e ~>submissions]
(let [>dustingetz_shirt-size #'(nav e :dustingetz/shirt-size)
>db_ident_1 #'(nav ~>dustingetz_shirt-size :db/ident)
>db_id_1 #'(nav ~>dustingetz_shirt-size :db/id)
>dustingetz_gender #'(nav e :dustingetz/gender)
>db_ident_2 #'(nav ~>dustingetz_gender :db/ident)
>gender >db_ident_2
>db_id_2 #'(nav ~>dustingetz_gender :db/id)
>dustingetz_shirt-size_options #'(shirt-sizes ~>gender)]
#'(render
#'{:dustingetz/shirt-size
#'(render
#'{:db/id #'(render >db_id_1)
:db/ident #'(render >db_ident_1)}
{::hf/options #'(p/for [e ~>dustingetz_shirt-size_options]
(let [>db_id #'(nav e :db/id)
>db_ident #'(nav e :db/ident)]
(render
#'{:db/id #'(render >db_id)
:db/ident #'(render >db_ident)})))})
:dustingetz/gender
#'(render
#'{:db/id #'(render >db_id_2)
:db/ident #'(render >db_ident_2)}
{::hf/options #'(p/for [e ~>dustingetz_gender_options]
(let [>db_id #'(nav e :db/id)
>db_ident #'(nav e :db/ident)]
#'(render #'{:db/id #'(render >db_id)
:db/ident #'(render >db_ident)})))})}))))
'(genders)
#'(render
#'(p/for [e ~>genders]
(let [>db_ident #'(nav e :db/ident)]
#'(render #'{:db/ident #'(render >db_ident)}))))}))
(p/defn render [>v & [props]]
; renderer decides with ~ which queries to realize (i.e. abstraction-safe infinite scroll)
; this default renderer forces the whole tree
(let [v ~>v]
(cond
(map? v) (into {} (p/for [[k >v] v]
[k ~>v]))
(vector? v) (p/for [row v] ~row)
:else ...)))
; If photon were lazy (v1 is not)
(let [submissions (submissions "")
genders (genders)
dustingetz_gender_options genders]
(render
{'(submissions "")
(render
(p/for [e submissions]
(let [dustingetz_shirt-size (nav e :dustingetz/shirt-size)
db_ident_1 (nav dustingetz_shirt-size :db/ident)
db_id_1 (nav dustingetz_shirt-size :db/id)
dustingetz_gender (nav e :dustingetz/gender)
db_ident_2 (nav dustingetz_gender :db/ident)
gender db_ident_2
db_id_2 (nav dustingetz_gender :db/id)
dustingetz_shirt-size_options (shirt-sizes gender)]
(render
{:dustingetz/shirt-size
(render
{:db/id (render db_id_1)
:db/ident (render db_ident_1)}
{::hf/options (p/for [e dustingetz_shirt-size_options]
(let [db_id (nav e :db/id)
db_ident (nav e :db/ident)]
(render
{:db/id (render db_id)
:db/ident (render db_ident)})))})
:dustingetz/gender
(render
{:db/id (render db_id_2)
:db/ident (render db_ident_2)}
{::hf/options (p/for [e dustingetz_gender_options]
(let [db_id (nav e :db/id)
db_ident (nav e :db/ident)]
(render {:db/id (render db_id)
:db/ident (render db_ident)})))})}))))
'(genders)
(render
(p/for [e genders]
(let [db_ident (nav e :db/ident)]
(render {:db/ident (render db_ident)}))))}))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment