Skip to content

Instantly share code, notes, and snippets.

Dustin Getz dustingetz

Block or report user

Report or block dustingetz

Hide content and notifications from this user.

Learn more about blocking users

Contact Support about this user’s behavior.

Learn more about reporting abuse

Report abuse
View GitHub Profile
View hyperfiddle-metamodel.md

This is probably going to be the next iteration of the declarative CRUD metamodel that powers Hyperfiddle. It's just a design sketch, the current metamodel in prod is different. Hyperfiddle is an easy way to make a CRUD app. Hyperfiddle is based on Datomic, a simple graph database with the goal of "enabling declarative data programming in applications."

CRUD UI definition

This extends Datomic pull syntax into something that composes in richer ways. The key idea is that Pull notation expresses implicit joins and thus can be used to declare data dependencies implicitly, without needing to name them. We also handle tempids, named transactions, and hyperlinks to other pages. We satisfy the hypermedia constraint, like HTML and the web.

{identity                                                   ; Pass through URL params to query
 [{:dustingetz/event-registration                           ; virtual attribute identif
View metamodel.clj
; CRUD UI
{identity ; pass through query params, decoded from URL
[{:hfnet/domains ; virtual attribute, resolves to a collection queried
[(:domain/ident {:hf/a :domains/edit}) ; :hf/a means hyperlink to a detail view, not specified here
{:domain/fiddle-database
[:database/uri]}]}
{(hf/new $domains) ; allocates a tempid for a new entity to be created in database $domains
[:db/id
:domain/ident
{:domain/fiddle-database
View datomic-reset-attributes.clj
(def tx-fns
[{:db/ident :db.fn/reset-attribute-values
:db/doc "Transaction function which accepts an entity identifier, attribute identifier
and set of values and expands to any additions and retractions necessary to
make the final post-transaction value of the attribute match the provided
values. Attribute values must be scalars.
If multiple values are provided on a cardinality-one attribute you will get a
datom conflict exception at transaction time."
:db/fn (d/function
@dustingetz
dustingetz / ordering.clj
Created May 30, 2019 — forked from joinr/ordering.clj
examples of composeable ordering functions
View ordering.clj
(ns ordering)
;;We want to pack some information along with
;;our functions so that when our interpreter picks them
;;up, we can determine if the function should be applied
;;directly as a comparator, or if we need to "lift"
;;it into the comparator domain.
(defn ordering? [x] (get (meta x) :ordering))
;;convenience macro to help us create functions with
;;ordering specified in meta
@dustingetz
dustingetz / .cljs
Created May 12, 2019
react virtualized data grid clojurescript
View .cljs
(defn row [ctx k]
^{:key (pr-str k)}
[:> js/ReactVirtualized.Column
{:label (reagent.core/as-element [hyperfiddle.ui/field [k] ctx])
:dataKey (hypercrud.transit/encode k)
:cellDataGetter
(fn [m]
(let [k (hypercrud.transit/decode (aget m "dataKey"))
ctx (aget m "rowData")
#_#_ctx (hypercrud.browser.context/attribute ctx k)]
View seattle-data.edn
[[:db/add "-1000001" :district/region :region/e]
[:db/add "-1000001" :district/name "East"]
[:db/add "-1000002" :neighborhood/name "Capitol Hill"]
[:db/add "-1000002" :neighborhood/district "-1000001"]
[:db/add "-1000003" :community/category "15th avenue residents"]
[:db/add "-1000003" :community/orgtype :community.orgtype/community]
[:db/add "-1000003" :community/type :community.type/email-list]
[:db/add "-1000003" :community/name "15th Ave Community"]
[:db/add "-1000003" :community/url "http://groups.yahoo.com/group/15thAve_Community/"]
[:db/add "-1000003" :community/neighborhood "-1000002"]
View seattle-schema.edn
[[:db/add "-700968933" :db/ident :community/name]
[:db/add "-700968933" :db/valueType :db.type/string]
[:db/add "-700968933" :db/cardinality :db.cardinality/one]
[:db/add "-700968933" :db/fulltext true]
[:db/add "-700968933" :db/doc "A community's name"]
[:db/add "43126449" :db/ident :community/url]
[:db/add "43126449" :db/valueType :db.type/string]
[:db/add "43126449" :db/cardinality :db.cardinality/one]
[:db/add "43126449" :db/doc "A community's url"]
[:db/add "-1305932792" :db/ident :community/neighborhood]
View forall.clj
;; Because in formal logic, ∀x.P(x) = ¬∃x.¬P(x)
(d/q '[:find ?id
:in $ [?interest ...]
:where
[?a :account/id ?id]
(not-join [?a ?interest]
[?a :account/interest ?i]
(not [(= ?i ?interest)]))])
;; It is harder to understand when you bind interest as above if you
View datomic-players-roster-rules.clj
(def players-roster-rules
"Rules to test if a collection of players are a subset of the players
in a roster.
Usage Constraints:
- ?players must always be bound
- ?roster may be bound or unbound
Valid Uses:
- test if a specific ?roster contains all ?players
View Datomic pulling through relations as if ref.md

This is a thought experiment, obviously this is not real datomic!

Why do this? I think it would cancel out data transformation boilerplate currently needed to do something like this.

(defn user-uuid-to-user [user-uuid]
  (d/q [:in $ ?user-uuid
        :find ?user .                          ; no pull here, bind it later
        :where [?user :user/uuid ?user-uuid]]
       *$* user-uuid))
You can’t perform that action at this time.