Skip to content

Instantly share code, notes, and snippets.

@dustingetz
Last active June 2, 2020 12:51
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dustingetz/96c928f755c736d2b525bb61a0c60b9e to your computer and use it in GitHub Desktop.
Save dustingetz/96c928f755c736d2b525bb61a0c60b9e to your computer and use it in GitHub Desktop.

Hyperfiddle DSL, 2020 April iteration

This DSL generates client/server UI for Datomic entities. The UI is transactional, secure, reactive, includes data sync, etc.

image

(ns user.hello-world
  (:require
    [hyperfiddle.api :as hf]))

(def submissions-master
  '[{`submissions [(:dustingetz/email
                     ; Three hypermedia controls on ::email (which is :db.unique/identity)
                     {:hf/a `submissions-detail}            ; hyperlink
                     {:hf/tx `remove}                       ; transaction

                     {:hf/class :hf/new                     ; classes are semantic, this allocates a tempid
                      :hf/prompt `submissions-detail})      ; prompt for more edits as part of the transaction

                   {:dustingetz/gender [:db/ident
                                        #_`f                ; Hyperfiddle can "pull" through functions, as if keywords
                                        {`shirt-sizes [:db/ident]}]}
                   {:dustingetz/shirt-size [:db/ident]}]}
    `genders])

(defn remove [ctx [e a v] props]
  [[:db/retractEntity v]])

(defn submissions [$ & args]
  (q '[:find [?e ...]                                       ; they must return FindColl for now
       :where [?e :dustingetz/email]] $))

(defn genders [$ & args]
  (q '[:find [(pull ?e [:db/ident]) ...]
       :where [?e :dustingetz/type :dustingetz/gender]]
    $))

(defn shirt-sizes [$ & [gender]]
  (q '[:in $ ?gender
       :find [?e ...]
       :where
       [?e :dustingetz/type :dustingetz/shirt-size]
       [?e :dustingetz/gender ?gender]]
    $ gender))

(def submissions-detail
  [:dustingetz/email
   {:dustingetz/gender [:db/ident
                        {`shirt-sizes [:db/ident]}]}
   {:dustingetz/shirt-size [:db/ident]}
   `genders])
   
(hf/init-routes
  [`submissions-master
   `submissions-detail])

(def config {:domain {:databases {"$" {:database/uri #uri "datomic:mem://app-db"}}}})
(def config (hf/get-config config))
(def domain (hf/get-domain config))
(def conn (hf/connect domain "$"))
(def $ (-> (hf/db conn)
         (hf/with [{:db/ident :dustingetz/email :db/valueType :db.type/string :db/cardinality :db.cardinality/one  :db/unique :db.unique/identity}
                   {:db/ident :dustingetz/gender :db/valueType :db.type/ref :db/cardinality :db.cardinality/one}
                   {:db/ident :dustingetz/shirt-size :db/valueType :db.type/ref :db/cardinality :db.cardinality/one}
                   {:db/ident :dustingetz/type :db/valueType :db.type/keyword :db/cardinality :db.cardinality/one}])
         (hf/with [{:dustingetz/type :dustingetz/gender :db/ident :dustingetz/male}
                   {:dustingetz/type :dustingetz/gender :db/ident :dustingetz/female}])
         (hf/with [{:dustingetz/type :dustingetz/shirt-size :db/ident :dustingetz/mens-small :dustingetz/gender :dustingetz/male}
                   {:dustingetz/type :dustingetz/shirt-size :db/ident :dustingetz/mens-medium :dustingetz/gender :dustingetz/male}
                   {:dustingetz/type :dustingetz/shirt-size :db/ident :dustingetz/mens-large :dustingetz/gender :dustingetz/male}
                   {:dustingetz/type :dustingetz/shirt-size :db/ident :dustingetz/womens-small :dustingetz/gender :dustingetz/female}
                   {:dustingetz/type :dustingetz/shirt-size :db/ident :dustingetz/womens-medium :dustingetz/gender :dustingetz/female}
                   {:dustingetz/type :dustingetz/shirt-size :db/ident :dustingetz/womens-large :dustingetz/gender :dustingetz/female}])
         (hf/with [{:dustingetz/email "alice@example.com" :dustingetz/gender :dustingetz/female :dustingetz/shirt-size :dustingetz/womens-large}
                   {:dustingetz/email "bob@example.com" :dustingetz/gender :dustingetz/male :dustingetz/shirt-size :dustingetz/mens-large}
                   {:dustingetz/email "charlie@example.com" :dustingetz/gender :dustingetz/male :dustingetz/shirt-size :dustingetz/mens-medium}])))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment