Skip to content

Commit

Permalink
first step of first class useselected
Browse files Browse the repository at this point in the history
  • Loading branch information
dspiteself committed Dec 9, 2019
1 parent fd430a4 commit 142bb85
Show file tree
Hide file tree
Showing 14 changed files with 1,363 additions and 53 deletions.
16 changes: 16 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"scripts": {
"deps": "yarn install",
"watch": "shadow-cljs watch app;",
"release": "shadow-cljs release app;",
"server": "shadow-cljs server;",
"clean": "rm -rf target; rm -rf public/js/*; touch public/js/main.js"
},
"dependencies": {
"create-react-class": "^15.6.3",
"react": "^16.8.6",
"react-dom": "^16.8.6",
"shadow-cljs": "^2.8.42",
"showdown": "^1.9.0"
}
}
15 changes: 9 additions & 6 deletions project.clj
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
(defproject com.breezeehr/react-hitch "0.3.1"
(defproject com.breezeehr/react-hitch "0.4.0"
:description "A Clojurescript library designed to manage and cache derived data."
:url "https://github.com/Breezeemr/react-hitch"
:license {:name "Eclipse Public License"
Expand All @@ -7,11 +7,14 @@
:repositories [["snapshots" {:url "s3p://breezepackages/snapshots" :creds :gpg}]
["releases" {:url "s3p://breezepackages/releases" :creds :gpg}]]
:dependencies [[org.clojure/clojure "1.9.0" :scope "provided"]
[org.clojure/clojurescript "1.10.339" :scope "provided"]
[cljsjs/react-dom "0.14.0-1"]
[com.breezeehr/hitch2 "0.3.3"]
[com.breezeehr/quiescent "0.2.0"
:exclusions [cljsjs/react-dom cljsjs/react]]]
[org.clojure/clojurescript "1.10.520" :scope "provided"]
[com.google.javascript/closure-compiler-unshaded "v20190325"]
[org.clojure/google-closure-library "0.0-20190213-2033d5d9"]
[com.breezeehr/hitch2 "0.3.5" :exclusions [org.clojure/clojurescript ]]
[crinkle "2.0.0"]
[thheller/shadow-cljs "2.8.40"]
[com.breezeehr/quiescent "0.3.0"
:exclusions [cljsjs/react-dom cljsjs/react cljsjs/create-react-class]]]
:profiles {:dev {
:dependencies [[cider/piggieback "0.3.10"] ; needed by figwheel nrepl
[devcards "0.2.5"]
Expand Down
File renamed without changes.
3 changes: 2 additions & 1 deletion dev-resources/public/devcards.html → public/devcards.html
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
<!--<link href="/css/example.css" rel="stylesheet" type="text/css">-->
</head>
<body>
<script src="cljs-out/dev-main-devcards.js" type="text/javascript"></script>
<script src="js/default.js" type="text/javascript"></script>
<script src="js/devcards.js" type="text/javascript"></script>
</body>
</html>
3 changes: 2 additions & 1 deletion dev-resources/public/test.html → public/test.html
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
</head>
<body>
<div id="app"></div>
<script src="cljs-out/dev-main-test.js" type="text/javascript"></script>
<script src="js/default.js" type="text/javascript"></script>
<script src="js/test.js" type="text/javascript"></script>
</body>
</html>
41 changes: 41 additions & 0 deletions shadow-cljs.edn
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
;; shadow-cljs configuration
{:lein true ;{:profiles "+prod,-dev"}

;; set an nrepl port for connection to a REPL.
:nrepl {:port 8777}

:builds
{:app
{:target :browser
:output-dir "public/js"
:asset-path "/js"

:modules
{:devcards
{:entries [react-hitch.devcards-runner]
:depends-on #{:default}}
:test
{:entries [react-hitch.test-runner]
:depends-on #{:default}}
:default
{}
}
:compiler-options {:source-map true
;; This is done in ribbon and transient_state.
:warnings {:protocol-multiple-impls false
:single-segment-namespace false}
:language-in :ecmascript5
:language-out :ecmascript5
:cache-analysis true}
:dev {:compiler-options {:devcards true}}

:devtools
;; before live-reloading any code call this function
{;:before-load crnklrn-deps.core/stop
;; after live-reloading finishes call this function
; :after-load breeze.jib.main/rerender!
;; serve the public directory over http at port 8700
:http-root "public"
:http-port 8700
;; :handler breeze.jib.server.figwheel-ring-handler/static-ring-handler
:preloads [devtools.preload]}}}}
39 changes: 22 additions & 17 deletions src/react_hitch/curator/react_hook.cljs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@
:refer [def-descriptor-spec]]
[hitch2.descriptor-impl-registry :as reg]
[hitch2.graph :as graph]
[react-hitch.descriptor-specs
:refer [react-hitcher-process-spec
react-hook-spec react-hitcher-process]]
[clojure.set :as set]))

(def initial-node
Expand All @@ -17,10 +20,6 @@
(defn remove-called-hooks [state descriptors]
(reduce dissoc state descriptors))

(def-descriptor-spec react-hook-spec
:curator
:canonical-form :vector)

(defn reset-component-parents [node rc new-parents]
(let [state (:state node)
rc->sel (:rc->sel state)
Expand Down Expand Up @@ -61,13 +60,15 @@
(update :change-focus into (remove (comp false? val)) @shared-parent-delta)
(cond->
(not-empty tounload)
(update :async-effects
(update :outbox
conj
{:type :delay-unload
:tounload tounload})))))
[react-hitcher-process
{:type :delay-unload
:tounload tounload}])))))

(def react-hook-impl
{:hitch2.descriptor.impl/kind :hitch2.descriptor.kind/curator
{:hitch2.descriptor.impl/kind
:hitch2.descriptor.kind/curator

::curator/init
(fn [curator-descriptor] initial-node)
Expand All @@ -81,6 +82,10 @@
:delayed-unload
(let [[_ sels] command]
(update-in node [:state :gcable-sels] into sels))
:subscribe-hook
(let [])
:unsubscribe-hook
(let [])
:gc
(let [{:keys [sel->rc
gc-scheduled?
Expand Down Expand Up @@ -118,16 +123,16 @@
(-> node :state)]
(cond-> (assoc-in node [:state :dirty-rc] #{})
(pos? (count dirty-rc))
(update :async-effects conj
{:type :rerender-components
:components dirty-rc})
(update :outbox conj
[react-hitcher-process
{:type :rerender-components
:components dirty-rc}])
(and (not gc-scheduled?)
(not-empty gcable-sels))
(not-empty gcable-sels))
(->
(update :async-effects conj
{:type :schedule-gc})
(assoc-in [:state :gc-scheduled?] true)))))})
(update :outbox conj
[react-hitcher-process
{:type :schedule-gc}])
(assoc-in [:state :gc-scheduled?] true)))))})

(reg/def-registered-descriptor Rreact-hook react-hook-spec react-hook-impl)

(def react-hooker (graph/positional-dtor Rreact-hook))
15 changes: 15 additions & 0 deletions src/react_hitch/descriptor_specs.cljs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
(ns react-hitch.descriptor-specs
(:require [hitch2.def.spec
:refer [def-descriptor-spec]]
[hitch2.graph :as graph]))

(def-descriptor-spec react-hook-spec
:curator
:canonical-form :vector)

(def-descriptor-spec react-hitcher-process-spec
:process)

(def react-hooker (graph/positional-dtor react-hook-spec))

(def react-hitcher-process (graph/->dtor react-hitcher-process-spec nil) )
20 changes: 20 additions & 0 deletions src/react_hitch/graph.cljs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
(ns react-hitch.graph
(:require
[crinkle.component :as c]
[cljsjs.react :as react]
[goog.object :as gobj]))

(def GraphContext
"The application's graph manager"
(js/React.createContext nil))

(def GraphContext-Provider (.-Provider GraphContext))

(def GraphContext-Consumer (.-Consumer GraphContext))

(defn with-graph
"Return an element which will run body-fn with a single argument: the graph
manager"
[body-fn]
(c/RE GraphContext-Provider nil
(fn [x] (body-fn (gobj/get x "value")))))
85 changes: 85 additions & 0 deletions src/react_hitch/hooks.cljs
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
(ns react-hitch.hooks
(:require
["react" :as react]
[hitch2.graph :as h]
[hitch2.protocols.graph-manager :as graph-proto]
[react-hitch.graph :refer [GraphContext]]
[react-hitch.descriptor-specs :refer [react-hooker]]
[crinkle.component :as c]))

(defonce ^:private LOADING #js{})

(defn loaded? [x]
(not (identical? LOADING x)))

(defn- get-dtor [gm dtor nf]
;; TODO: -get-graph marked deprecated, unsure of replacement
(get (graph-proto/-get-graph gm) dtor nf))
(defn useEquiv
"Takes a value and a comparison function. Returns an equivalent (but not
necessarily identical) value. The comparison function must be hook-static.
The comparison function must take an old and new object and return true if
they are equal and false if they are not.
The identity of the returned object will only change on subsequent renders
if the comparison function returns false; otherwise it will return the
equivalent object from a previous render so that hooks that look for
deps array changes will not detect a change.
This function exists because useMemo, useEffect & company do not accept a
custom comparator, so immutable equal-but-not-identical values retrigger
these hooks unnecessarily. Use this hook on values you intend to include
in a deps array.
Example use:
(let [v (useEquiv v =)
m (react/useMemo #(some-expensive-fn v) #js[v])]
,,,)
Note the comparison function runs during the render phase, so keep it fast.
See also `useEquivDeps`, `use=`, `use=deps`."
[value equal?]
(let [vref (react/useRef value)
oldv (.-current vref)]
(if ^boolean (equal? value oldv)
;; unsure if better to have an always-setting fn and include value in the
;; deps; or to do this.
oldv
(do (set! (.-current vref) value)
value))))

(defn use=
"Like `useEquiv`, but with a hardcoded cljs = comparison function"
[value]
(let [vref (react/useRef value)]
(if (= value (.-current vref))
(.-current vref)
(do (set! (.-current vref) value)
value))))


(defn useSelected
"This hook requires that GraphContext be set."
([dtor]
(useSelected dtor LOADING))
([dtor not-found]
(let [;dtor-ref (react/useRef dtor)
dtor (c/use= dtor)
g (react/useContext GraphContext)
s (react/useState (get-dtor g dtor not-found))
dtorval (aget s 0)
setdtorval (aget s 1)]
(react/useEffect
(fn []

#_(identity g [react-hooker
[:subscribe-hook setdtorval dtor]])
(let [val (get-dtor g dtor not-found)]
(when (and (loaded? val) (not= dtorval val))
(setdtorval val)))
#_(identity g [react-hooker
[:unsubscribe-hook setdtorval dtor]]))
#js[dtor])
dtorval)))
Loading

0 comments on commit 142bb85

Please sign in to comment.