Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIP: Reactive queries #70

Open
wants to merge 9 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion src/uxbox/core.cljs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
[uxbox.ui :as ui]
[uxbox.ui.navigation :as nav]
[uxbox.data.db :as db]
[uxbox.data.schema :as sch]
[hodgepodge.core :refer [local-storage]]))

(enable-console-print!)
Expand All @@ -11,7 +12,7 @@

(defn start!
[location]
(let [conn (db/create)
(let [conn (db/create sch/schema)
storage local-storage]
(nav/start-history!)
(db/init! conn storage)
Expand Down
7 changes: 4 additions & 3 deletions src/uxbox/data/db.cljs
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,10 @@
[uxbox.data.schema :as sch]))

(defn create
[]
(let [conn (d/create-conn sch/schema)]
conn))
([]
(create sch/schema))
([schema]
(d/create-conn schema)))

(defn restore!
[conn storage]
Expand Down
13 changes: 6 additions & 7 deletions src/uxbox/data/schema.cljs
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,7 @@
:shape/visible? {:db/cardinality :db.cardinality/one}})

(def user-schema
{:user/uuid {:db/unique :db.unique/identity}
:user/fullname {:db/cardinality :db.cardinality/one
{:user/fullname {:db/cardinality :db.cardinality/one
:db/valueType :db.type/string}
:user/avatar {:db/cardinality :db.cardinality/one
:db/valueType :db.type/string}})
Expand All @@ -50,8 +49,8 @@
:event/user {:db/cardinality :db.cardinality/one}})

(def schema
{:uxbox/project project-schema
:uxbox/page page-schema
:uxbox/shape shape-schema
:uxbox/user user-schema
:uxbox/event event-schema})
{:project project-schema
:page page-schema
:shape shape-schema
:user user-schema
:event event-schema})
4 changes: 4 additions & 0 deletions src/uxbox/log/queries.cljs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@
[uxbox.log.core :as log]
[datascript :as d]))

(def events-query
'[:find [?e ...]
:where [?e :event/type ?t]])

(defn all-events
[db]
(map :e (d/datoms db :avet :event/timestamp)))
Expand Down
4 changes: 0 additions & 4 deletions src/uxbox/projects/queries.cljs
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,3 @@
[db]
(let [eids (all-projects db)]
(d/pull-many db '[*] eids)))

(defn project-count
[db]
(count (d/q projects-query db)))
79 changes: 79 additions & 0 deletions src/uxbox/queries.cljs
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
(ns uxbox.queries
(:require
[datascript :as d]
[uxbox.streams :as s]))

(defn- query
[q db]
(d/q q db))

;; reactive query

(defn- eids-changed?
[q tx-report]
(let [before (query q (:db-before tx-report))
after (query q (:db-after tx-report))]
(when (not= before after)
after)))

(defn rquery
[q conn]
(let [k (gensym)
a (atom (query q @conn))
sink #(reset! a %)]
(d/listen! conn
k
(fn [txr]
(when-let [after (eids-changed? q txr)]
(sink after))))
a))

;; reactive pull

(defn- pull-one-or-many
[eids p db]
(cond
(sequential? eids)
(d/pull-many db p eids)

(not (nil? eids))
(d/pull db p eids)))

(defn rpull
[q p conn]
(let [k (gensym)
a (atom (pull-one-or-many (query q @conn) p @conn))
sink #(reset! a %)]
(d/listen! conn
k
(fn [txr]
(let [after (query q (:db-after txr))]
(sink (pull-one-or-many after p (:db-after txr))))))
a))

;; reactive entity

(defn- pull-entity
[id p db]
(d/pull db p id))

(defn- entity-changed?
[id p tx-report]
(let [before (pull-entity id p (:db-before tx-report))
after (pull-entity id p (:db-after tx-report))]
(when (not= before after)
after)))

(defn rentity
([id conn]
(rentity id '[*] conn))
([id p conn]
(let [k (gensym)
a (atom (pull-entity id p @conn))
sink #(reset! a %)]
(d/listen! conn
k
(fn [txr]
(when-let [e (entity-changed? id p txr)]
(sink e))))
a)))
2 changes: 1 addition & 1 deletion src/uxbox/ui/activity.cljs
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@
(create-project-activity ev))])

(rum/defcs timeline < (mx/pull-query :events
q/all-events
q/events-query
'[:event/type
:event/payload
:event/author
Expand Down
28 changes: 13 additions & 15 deletions src/uxbox/ui/dashboard.cljs
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,8 @@

(rum/defc project-count < rum/static
[n]
[:span.dashboard-projects n " projects"])
[:span.dashboard-projects
(str n " projects")])

(rum/defc project-sort-selector < rum/reactive
[sort-order]
Expand Down Expand Up @@ -192,12 +193,12 @@
{:on-click #(set-lightbox! :new-project)}
[:span "+ New project"]])

(defn sorted-projects
[conn projects sort-order]
(let [project-cards (map (partial project-card conn) (sort-by sort-order projects))]
(defn sort-projects
[projects sort-order]
(let [sorted (sort-by sort-order projects)]
(if (= sort-order :project/name)
project-cards
(reverse project-cards))))
sorted
(reverse sorted))))

(rum/defc dashboard-grid < rum/reactive
[conn projects sort-order]
Expand All @@ -206,23 +207,20 @@
[:div.dashboard-grid-content
(vec
(concat [:div.dashboard-grid-content
(new-project conn)]
(sorted-projects conn
projects
(rum/react sort-order))))]])
(new-project)]
(map (partial project-card conn)
(sort-projects projects (rum/react sort-order)))))]])

(rum/defcs dashboard* < (rum/local :project/name :project-sort-order)
(mx/pull-query :projects
q/all-projects
q/projects-query
'[*])
(mx/query :project-count q/project-count)
[{sort-order :project-sort-order
projects :projects
project-count :project-count} conn]
projects :projects} conn]
[:main.dashboard-main
(header conn)
[:section.dashboard-content
(dashboard-bar sort-order @project-count)
(dashboard-bar sort-order (count @projects))
(dashboard-grid conn @projects sort-order)]
(timeline conn)])

Expand Down
29 changes: 11 additions & 18 deletions src/uxbox/ui/mixins.cljs
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
(ns uxbox.ui.mixins
(:require [rum]
[datascript :as d]))
(:require
[rum]
[datascript :as d]
[uxbox.queries :as qs]))

;; ================================================================================
;; Queries


(defn query
[key query]
{ :transfer-state
Expand Down Expand Up @@ -39,30 +42,20 @@
:will-mount
(fn [state]
(let [[conn] (:rum/args state)
query! (fn [db]
(let [eids (query db)]
(cond
(sequential? eids)
(d/pull-many db pull eids)

(not (nil? eids))
(d/pull db pull eids))))
local-state (atom (query! @conn))
local-state (qs/rpull query pull conn)
component (:rum/react-component state)]
;; sub
(d/listen! conn
(add-watch local-state
key
(fn [tx-report]
(when-let [r (query! (:db-after tx-report))]
(when (not= @local-state r)
(reset! local-state r)
(rum/request-render component)))))
(fn [_ _ old new]
(when-not (= old new)
(rum/request-render component))))
(assoc state key local-state)))
:will-unmount
(fn [state]
(let [[conn] (:rum/args state)]
;; unsub
(d/unlisten! conn key)
(remove-watch (state key) key)
(dissoc state key)))})

;; ================================================================================
Expand Down
3 changes: 1 addition & 2 deletions src/uxbox/users/queries.cljs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,5 @@

(defn pull-current-user
[_]
{:user/uuid (random-uuid)
:user/fullname "Michael Buchannon"
{:user/fullname "Michael Buchannon"
:user/avatar "/images/avatar.jpg"})
2 changes: 2 additions & 0 deletions test/uxbox/runner.cljs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
(ns uxbox.runner
(:require [cljs.test :as test]
[uxbox.test.data-test]
[uxbox.test.queries-test]
[uxbox.test.projects.data-test]
[uxbox.test.shapes.data-test]
[uxbox.test.streams-test]))
Expand All @@ -13,6 +14,7 @@
'uxbox.test.data-test
'uxbox.test.projects.data-test
'uxbox.test.shapes.data-test
'uxbox.test.queries-test
'uxbox.test.streams-test))

(set! *main-cli-fn* main)
Loading