Skip to content

Instantly share code, notes, and snippets.

@zeitstein
Created April 7, 2022 18:48
Show Gist options
  • Save zeitstein/091dd0a82a743d9c1ae03cd1f9ffd24b to your computer and use it in GitHub Desktop.
Save zeitstein/091dd0a82a743d9c1ae03cd1f9ffd24b to your computer and use it in GitHub Desktop.
(ns grove.effect
(:require
[shadow.experiments.grove :as sg :refer (<< defc)]
[shadow.experiments.grove.runtime :as rt]
[shadow.experiments.grove.db :as db]
[shadow.experiments.grove.eql-query :as eql]
[shadow.experiments.grove.events :as ev]
[shadow.experiments.grove.local :as local]))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; init db
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(def schema
{:block
{:type :entity
:primary-key :uuid
:attrs {}
:joins {:kida [:many :block]
:remote-query-result [:many :block]}}
:remote-query-result
{:type :entity
:primary-key :uuid
:attrs {}
:joins {:mirrors [:one :block]}}})
(def denormalized-data
;; just a minimal example, in principle the tree can have hundreds of nodes
;; but only a few would by of :type :query
[{:uuid 0 :text "0" :open true
:kida {:uuid 1 :text "1" :open true
:kida {:uuid 2 :text "gets results from server" :open true
:type :query}}}
{:uuid :another-possible-root :text "no query here"}])
(defonce data-ref
(-> {:root 0}
(db/configure schema)
(atom)))
(defonce rt-ref
(rt/prepare {} data-ref ::runtime-id))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ui
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(comment
@data-ref
;
)
(defc ui-query [ident]
;; (de)activate-remote! should happen on toggle but also on nav
(hook (sg/mount-effect
(fn [_]
(sg/run-tx! rt-ref {:e ::activate-remote! :id ident})
#(sg/run-tx! rt-ref {:e ::deactivate-remote! :id ident}))))
(render (<< [:div "display results..."])))
(defc ui-block [ident]
(bind {:keys [open text kida type]} (sg/query-ident ident))
(render
(<<
[:div {:style "margin-left: 20px;"}
[:button {:on-click {:e ::toggle! :id ident}} (str open)]
[:span text]
(when open
(if (= type :query)
(ui-query ident)
(when kida (ui-block kida))))])))
(defc ui-root []
(bind {:keys [root]} (sg/query-root [:root]))
(render
(<< [:button {:on-click {:e ::nav!}} "navigate"]
(ui-block (db/make-ident :block root)))))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; event handlers
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(ev/reg-event rt-ref ::nav!
(fn [env ev]
(assoc-in env [:db :root] :another-possible-root)))
(ev/reg-event rt-ref ::activate-remote!
(fn [env {:keys [id]}]
;; simulate notifying the server this component is in ui and getting back results
(update-in env [:db] db/merge-seq
:remote-query-result
[{:uuid 11 :text "q1"}
{:uuid 22 :text "q2"}]
[id :qresult])))
(ev/reg-event rt-ref ::deactivate-remote!
(fn [env {:keys [id]}]
(let [res (get-in env [:db id :qresult])]
(-> env
(update-in [:db id] dissoc :qresult)
(update :db db/remove-idents res)
;; and notify the server component has left ui
))))
(ev/reg-event rt-ref ::toggle!
(fn [env {:keys [id]}]
(update-in env [:db id :open] not)))
(ev/reg-event rt-ref ::load!
(fn [env ev]
(-> env
(update :db db/merge-seq :block denormalized-data))))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; init
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(def root-el
(js/document.getElementById "root"))
(defn ^:dev/after-load start []
(sg/render rt-ref root-el (ui-root)))
(defn init []
(local/init! rt-ref)
(sg/run-tx! rt-ref {:e ::load!})
(start))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment