Browser repl (#24)
This commit is contained in:
parent
0d204c7ae6
commit
2a93334a43
53
README.md
53
README.md
|
@ -13,6 +13,57 @@ for a minimal full stack web application.
|
||||||
See [releases](https://github.com/babashka/scittle/releases) for links to
|
See [releases](https://github.com/babashka/scittle/releases) for links to
|
||||||
[JSDelivr](https://www.jsdelivr.com) to get versioned artifacts.
|
[JSDelivr](https://www.jsdelivr.com) to get versioned artifacts.
|
||||||
|
|
||||||
|
## Serving assets
|
||||||
|
|
||||||
|
To serve assets you can use the
|
||||||
|
[babashka.http-server](https://github.com/babashka/http-server) dependency (with
|
||||||
|
babashka or Clojure JVM):
|
||||||
|
|
||||||
|
``` clojure
|
||||||
|
(require '[babashka.http-server :as http])
|
||||||
|
(http/serve {:port 1341 :dir "resoures/public"}
|
||||||
|
@(promise) ;; wait until process is killed
|
||||||
|
```
|
||||||
|
|
||||||
|
### REPL
|
||||||
|
|
||||||
|
To connect to a Scittle REPL from your editor, scittle provides an nREPL
|
||||||
|
implementation. To run the nREPL server you need to follow these steps:
|
||||||
|
|
||||||
|
In babashka or Clojure JVM, use the
|
||||||
|
[sci.nrepl](https://github.com/babashka/sci.nrepl) dependency and run:
|
||||||
|
|
||||||
|
```
|
||||||
|
(require 'sci.nrepl.browser-server :as nrepl)
|
||||||
|
(nrepl/start! {:nrepl-port 1339 :websocket-port 1340})
|
||||||
|
```
|
||||||
|
|
||||||
|
This will run an nREPL server on port 1339 and a websocket server on port 1340.
|
||||||
|
Your editor's nREPL client will connect to port 1339 and your browser, running
|
||||||
|
scittle, will connect to port 1340. The nREPL server forwards messages to the
|
||||||
|
browser via the websocket connection.
|
||||||
|
|
||||||
|
In your scittle website, you will need to include the following, in addition to
|
||||||
|
the normal routine:
|
||||||
|
|
||||||
|
```
|
||||||
|
<script>var SCITTLE_NREPL_WEBSOCKET_PORT = 1340;</script>
|
||||||
|
<script src="https://cdn.jsdelivr.net/npm/scittle@0.2.0/dist/scittle.nrepl.js" type="application/javascript"></script>
|
||||||
|
```
|
||||||
|
|
||||||
|
Also include the CLJS file that you want to evaluate with nREPL:
|
||||||
|
|
||||||
|
```
|
||||||
|
<script src="cljs/script.cljs" type="application/x-scittle"></script>
|
||||||
|
```
|
||||||
|
|
||||||
|
Then visit `cljs/script.cljs` in your editor and connect to the nREPL server,
|
||||||
|
and start evaluating!
|
||||||
|
|
||||||
|
See the `resources/public/nrepl.html` file for an example. When you run `bb dev`
|
||||||
|
in this repository, and then open `http://localhost:1341/nrepl.html` you should
|
||||||
|
be able evaluate expressions in `resources/public/cljs/nrepl_playground.cljs`.
|
||||||
|
|
||||||
## Tasks
|
## Tasks
|
||||||
|
|
||||||
Run `bb tasks` to see all available tasks:
|
Run `bb tasks` to see all available tasks:
|
||||||
|
@ -33,6 +84,6 @@ Idea by Arne Brasseur a.k.a [plexus](https://github.com/plexus).
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
Copyright © 2021 Michiel Borkent
|
Copyright © 2021 - 2022 Michiel Borkent
|
||||||
|
|
||||||
Distributed under the EPL License. See LICENSE.
|
Distributed under the EPL License. See LICENSE.
|
||||||
|
|
25
bb.edn
25
bb.edn
|
@ -1,4 +1,10 @@
|
||||||
{:tasks
|
{:deps {io.github.babashka/sci.nrepl
|
||||||
|
#_{:local/root "../sci.nrepl"}
|
||||||
|
{:git/sha "c14b5b4ef4390ff206cdb71f763f327799f5e853"}
|
||||||
|
io.github.babashka/http-server
|
||||||
|
{:git/sha "b38c1f16ad2c618adae2c3b102a5520c261a7dd3"}}
|
||||||
|
|
||||||
|
:tasks
|
||||||
{:requires ([babashka.fs :as fs]
|
{:requires ([babashka.fs :as fs]
|
||||||
[cheshire.core :as json]
|
[cheshire.core :as json]
|
||||||
[babashka.process :as p :refer [process]])
|
[babashka.process :as p :refer [process]])
|
||||||
|
@ -8,9 +14,24 @@
|
||||||
(fs/delete-tree ".cpcache")
|
(fs/delete-tree ".cpcache")
|
||||||
(fs/delete-tree ".shadow-cljs"))}
|
(fs/delete-tree ".shadow-cljs"))}
|
||||||
|
|
||||||
dev {:doc "Development build. Starts webserver and watches for changes."
|
shadow:watch {:doc "Development build. Starts webserver and watches for changes."
|
||||||
:task (clojure "-M:dev -m shadow.cljs.devtools.cli watch main")}
|
:task (clojure "-M:dev -m shadow.cljs.devtools.cli watch main")}
|
||||||
|
|
||||||
|
http-server {:doc "Starts http server for serving static files"
|
||||||
|
:requires ([babashka.http-server :as http])
|
||||||
|
:task (do (http/serve {:port 1341 :dir "resources/public"})
|
||||||
|
(println "Serving static assets at http://localhost:1341"))}
|
||||||
|
|
||||||
|
browser-nrepl {:doc "Start browser nREPL"
|
||||||
|
:requires ([sci.nrepl.browser-server :as bp])
|
||||||
|
:task (bp/start! {})}
|
||||||
|
|
||||||
|
-dev {:depends [shadow:watch browser-nrepl http-server]}
|
||||||
|
|
||||||
|
dev {:doc "Development build. Starts webserver and watches for changes."
|
||||||
|
:task (do (run '-dev {:parallel true})
|
||||||
|
(deref (promise)))}
|
||||||
|
|
||||||
prod {:doc "Builds production artifacts."
|
prod {:doc "Builds production artifacts."
|
||||||
:task (clojure {:extra-env {"SCI_ELIDE_VARS" "true"}}
|
:task (clojure {:extra-env {"SCI_ELIDE_VARS" "true"}}
|
||||||
"-M:dev -m shadow.cljs.devtools.cli release main")}
|
"-M:dev -m shadow.cljs.devtools.cli release main")}
|
||||||
|
|
10
deps.edn
10
deps.edn
|
@ -2,12 +2,18 @@
|
||||||
|
|
||||||
:deps
|
:deps
|
||||||
{org.clojure/clojure {:mvn/version "1.10.3"}
|
{org.clojure/clojure {:mvn/version "1.10.3"}
|
||||||
org.babashka/sci {:mvn/version "0.3.1"}
|
org.babashka/sci {:mvn/version "0.3.5"}
|
||||||
reagent/reagent {:mvn/version "1.1.0"}
|
reagent/reagent {:mvn/version "1.1.0"}
|
||||||
cljsjs/react {:mvn/version "17.0.2-0"}
|
cljsjs/react {:mvn/version "17.0.2-0"}
|
||||||
cljsjs/react-dom {:mvn/version "17.0.2-0"}
|
cljsjs/react-dom {:mvn/version "17.0.2-0"}
|
||||||
cljsjs/react-dom-server {:mvn/version "17.0.2-0"}
|
cljsjs/react-dom-server {:mvn/version "17.0.2-0"}
|
||||||
cljs-ajax/cljs-ajax {:mvn/version "0.8.3"}}
|
cljs-ajax/cljs-ajax {:mvn/version "0.8.3"}
|
||||||
|
|
||||||
|
io.github.babashka/sci.nrepl
|
||||||
|
#_{:local/root "../sci.nrepl"}
|
||||||
|
{:git/sha "e83421ce9349c36df56a2eb936196dbb65b0de63"}
|
||||||
|
io.github.babashka/sci.configs
|
||||||
|
{:git/sha "fcd367c6a6115c5c4e41f3a08ee5a8d5b3387a18"}}
|
||||||
|
|
||||||
:aliases
|
:aliases
|
||||||
{:dev
|
{:dev
|
||||||
|
|
15
resources/public/cljs/nrepl_playground.cljs
Normal file
15
resources/public/cljs/nrepl_playground.cljs
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
(ns nrepl-playground)
|
||||||
|
|
||||||
|
(+ 1 2 3)
|
||||||
|
|
||||||
|
(->
|
||||||
|
(js/document.getElementsByTagName "body")
|
||||||
|
first
|
||||||
|
(.append
|
||||||
|
(doto (js/document.createElement "p")
|
||||||
|
(.append
|
||||||
|
(js/document.createTextNode "there")))))
|
||||||
|
|
||||||
|
(defn foo [])
|
||||||
|
|
||||||
|
(js/alert "Isn't this cool? :)")
|
|
@ -90,7 +90,7 @@
|
||||||
When you have a file on your server, say <tt>cljs/script.cljs</tt>, you can load it using the <tt>src</tt> attribute:
|
When you have a file on your server, say <tt>cljs/script.cljs</tt>, you can load it using the <tt>src</tt> attribute:
|
||||||
|
|
||||||
<pre><code id="scittle-tag-example" class="html">
|
<pre><code id="scittle-tag-example" class="html">
|
||||||
<script src="cljs/script.cljs" type="application/x-scittle"></script>
|
<script src="cljs/script.cljs" type="application/x-scittle"></script>
|
||||||
</code></pre>
|
</code></pre>
|
||||||
|
|
||||||
<script type="text/javascript">hljs.highlightElement(document.getElementById("scittle-tag-example"));</script>
|
<script type="text/javascript">hljs.highlightElement(document.getElementById("scittle-tag-example"));</script>
|
||||||
|
@ -118,6 +118,12 @@
|
||||||
Click me!
|
Click me!
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
|
<a name="repl"></a>
|
||||||
|
<h2><a href="#nrepl">REPL</a></h2>
|
||||||
|
|
||||||
|
To connect to a REPL with Scittle,
|
||||||
|
see <a href="https://github.com/babashka/scittle/blob/main/README.md#repl">README.md</a>
|
||||||
|
|
||||||
<a name="examples"></a>
|
<a name="examples"></a>
|
||||||
<h2><a href="#examples">Examples</a></h2>
|
<h2><a href="#examples">Examples</a></h2>
|
||||||
<ul>
|
<ul>
|
||||||
|
|
14
resources/public/nrepl.html
Normal file
14
resources/public/nrepl.html
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<link rel="stylesheet" href="css/style.css">
|
||||||
|
<script src="js/scittle.js" type="application/javascript"></script>
|
||||||
|
<script>var SCITTLE_BROWSER_REPL_PROXY_PORT = 1340;</script>
|
||||||
|
<script src="js/scittle.nrepl.js" type="application/javascript"></script>
|
||||||
|
<script type="application/x-scittle" src="cljs/nrepl_playground.cljs"></script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1>Scittle</h1>
|
||||||
|
<h2>What is this?</h2>
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -14,6 +14,8 @@
|
||||||
:global "ReactDOM"}}}
|
:global "ReactDOM"}}}
|
||||||
:modules
|
:modules
|
||||||
{:scittle {:entries [scittle.core]}
|
{:scittle {:entries [scittle.core]}
|
||||||
|
:scittle.nrepl {:entries [scittle.nrepl]
|
||||||
|
:depends-on #{:scittle}}
|
||||||
:scittle.reagent {:entries [scittle.reagent]
|
:scittle.reagent {:entries [scittle.reagent]
|
||||||
:depends-on #{:scittle}}
|
:depends-on #{:scittle}}
|
||||||
:scittle.cljs-ajax {:entries [scittle.cljs-ajax]
|
:scittle.cljs-ajax {:entries [scittle.cljs-ajax]
|
||||||
|
|
|
@ -29,15 +29,29 @@
|
||||||
'goog.object {'set gobject/set
|
'goog.object {'set gobject/set
|
||||||
'get gobject/get}})
|
'get gobject/get}})
|
||||||
|
|
||||||
(def ctx (atom (sci/init {:namespaces namespaces
|
(def !sci-ctx (atom (sci/init {:namespaces namespaces
|
||||||
:classes {'js js/window
|
:classes {'js js/window
|
||||||
:allow :all}
|
:allow :all}
|
||||||
:disable-arity-checks true})))
|
:disable-arity-checks true})))
|
||||||
|
|
||||||
|
|
||||||
|
(def !last-ns (volatile! @sci/ns))
|
||||||
|
|
||||||
|
(defn- -eval-string [s]
|
||||||
|
(sci/binding [sci/ns @!last-ns]
|
||||||
|
(let [rdr (sci/reader s)]
|
||||||
|
(loop [res nil]
|
||||||
|
(let [form (sci/parse-next @!sci-ctx rdr)]
|
||||||
|
(if (= :sci.core/eof form)
|
||||||
|
(do
|
||||||
|
(vreset! !last-ns @sci/ns)
|
||||||
|
res)
|
||||||
|
(recur (sci/eval-form @!sci-ctx form))))))))
|
||||||
|
|
||||||
(defn ^:export eval-string [s]
|
(defn ^:export eval-string [s]
|
||||||
(try (sci/eval-string* @ctx s)
|
(try (-eval-string s)
|
||||||
(catch :default e
|
(catch :default e
|
||||||
(error/error-handler e (:src @ctx))
|
(error/error-handler e (:src @!sci-ctx))
|
||||||
(let [sci-error? (isa? (:type (ex-data e)) :sci/error)]
|
(let [sci-error? (isa? (:type (ex-data e)) :sci/error)]
|
||||||
(throw (if sci-error?
|
(throw (if sci-error?
|
||||||
(or (ex-cause e) e)
|
(or (ex-cause e) e)
|
||||||
|
@ -45,14 +59,14 @@
|
||||||
|
|
||||||
(defn register-plugin! [plug-in-name sci-opts]
|
(defn register-plugin! [plug-in-name sci-opts]
|
||||||
plug-in-name ;; unused for now
|
plug-in-name ;; unused for now
|
||||||
(swap! ctx sci/merge-opts sci-opts))
|
(swap! !sci-ctx sci/merge-opts sci-opts))
|
||||||
|
|
||||||
(defn- eval-script-tags* [script-tags]
|
(defn- eval-script-tags* [script-tags]
|
||||||
(when-let [tag (first script-tags)]
|
(when-let [tag (first script-tags)]
|
||||||
(if-let [text (not-empty (gobject/get tag "textContent"))]
|
(if-let [text (not-empty (gobject/get tag "textContent"))]
|
||||||
(let [scittle-id (str (gensym "scittle-tag-"))]
|
(let [scittle-id (str (gensym "scittle-tag-"))]
|
||||||
(gobject/set tag "scittle_id" scittle-id)
|
(gobject/set tag "scittle_id" scittle-id)
|
||||||
(swap! ctx assoc-in [:src scittle-id] text)
|
(swap! !sci-ctx assoc-in [:src scittle-id] text)
|
||||||
(sci/binding [sci/file scittle-id]
|
(sci/binding [sci/file scittle-id]
|
||||||
(eval-string text))
|
(eval-string text))
|
||||||
(eval-script-tags* (rest script-tags)))
|
(eval-script-tags* (rest script-tags)))
|
||||||
|
@ -64,7 +78,7 @@
|
||||||
(let [response (gobject/get this "response")]
|
(let [response (gobject/get this "response")]
|
||||||
(gobject/set tag "scittle_id" src)
|
(gobject/set tag "scittle_id" src)
|
||||||
;; save source for error messages
|
;; save source for error messages
|
||||||
(swap! ctx assoc-in [:src src] response)
|
(swap! !sci-ctx assoc-in [:src src] response)
|
||||||
(sci/binding [sci/file src]
|
(sci/binding [sci/file src]
|
||||||
(eval-string response)))
|
(eval-string response)))
|
||||||
(eval-script-tags* (rest script-tags)))))]
|
(eval-script-tags* (rest script-tags)))))]
|
||||||
|
@ -89,3 +103,4 @@
|
||||||
|
|
||||||
(enable-console-print!)
|
(enable-console-print!)
|
||||||
(sci/alter-var-root sci/print-fn (constantly *print-fn*))
|
(sci/alter-var-root sci/print-fn (constantly *print-fn*))
|
||||||
|
|
||||||
|
|
45
src/scittle/nrepl.cljs
Normal file
45
src/scittle/nrepl.cljs
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
(ns scittle.nrepl
|
||||||
|
(:require
|
||||||
|
[clojure.edn :as edn]
|
||||||
|
[sci.nrepl.completions :refer [completions]]
|
||||||
|
[scittle.core :refer [!last-ns eval-string !sci-ctx]]))
|
||||||
|
|
||||||
|
(defn nrepl-websocket []
|
||||||
|
(.-ws_nrepl js/window))
|
||||||
|
|
||||||
|
(defn nrepl-reply [{:keys [id session]} payload]
|
||||||
|
(.send (nrepl-websocket)
|
||||||
|
(str (assoc payload :id id :session session :ns (str @!last-ns)))))
|
||||||
|
|
||||||
|
(defn handle-nrepl-eval [{:keys [code] :as msg}]
|
||||||
|
(let [[kind val] (try [::success (eval-string code)]
|
||||||
|
(catch :default e
|
||||||
|
[::error (str e)]))]
|
||||||
|
(case kind
|
||||||
|
::success
|
||||||
|
(do (nrepl-reply msg {:value (pr-str val)})
|
||||||
|
(nrepl-reply msg {:status ["done"]}))
|
||||||
|
::error
|
||||||
|
(do
|
||||||
|
(nrepl-reply msg {:err (pr-str val)})
|
||||||
|
(nrepl-reply msg {:ex (pr-str val)
|
||||||
|
:status ["error" "done"]})))))
|
||||||
|
|
||||||
|
(defn handle-nrepl-message [msg]
|
||||||
|
(case (:op msg)
|
||||||
|
:eval (handle-nrepl-eval msg)
|
||||||
|
:complete (let [completions (completions (assoc msg :ctx @!sci-ctx))]
|
||||||
|
(nrepl-reply msg completions))))
|
||||||
|
|
||||||
|
(when (.-SCITTLE_NREPL_WEBSOCKET_PORT js/window)
|
||||||
|
(set! (.-ws_nrepl js/window)
|
||||||
|
(new js/WebSocket "ws://localhost:1340/_nrepl")))
|
||||||
|
|
||||||
|
(when-let [ws (nrepl-websocket)]
|
||||||
|
(prn :ws ws)
|
||||||
|
(set! (.-onmessage ws)
|
||||||
|
(fn [event]
|
||||||
|
(handle-nrepl-message (edn/read-string (.-data event)))))
|
||||||
|
(set! (.-onerror ws)
|
||||||
|
(fn [event]
|
||||||
|
(js/console.log event))))
|
|
@ -1,107 +1,11 @@
|
||||||
(ns scittle.reagent
|
(ns scittle.reagent
|
||||||
(:require [reagent.core :as r]
|
(:require
|
||||||
[reagent.debug :as d :refer-macros [dev?]]
|
|
||||||
[reagent.dom :as rdom]
|
[reagent.dom :as rdom]
|
||||||
[reagent.ratom :as ratom]
|
[sci.configs.reagent.reagent :refer [reagent-debug-namespace
|
||||||
|
reagent-namespace reagent-ratom-namespace]]
|
||||||
[sci.core :as sci]
|
[sci.core :as sci]
|
||||||
[scittle.core :as scittle]))
|
[scittle.core :as scittle]))
|
||||||
|
|
||||||
;; The with-let macro from reagent.core. The only change is that the
|
|
||||||
;; interop/unchecked-aget+set were replaced by aget and aset.
|
|
||||||
(defn ^:macro with-let [_ _ bindings & body]
|
|
||||||
(assert (vector? bindings)
|
|
||||||
(str "with-let bindings must be a vector, not "
|
|
||||||
(pr-str bindings)))
|
|
||||||
(let [v (gensym "with-let")
|
|
||||||
k (keyword v)
|
|
||||||
init (gensym "init")
|
|
||||||
;; V is a reaction, which holds a JS array.
|
|
||||||
;; If the array is empty, initialize values and store to the
|
|
||||||
;; array, using binding index % 2 to access the array.
|
|
||||||
;; After init, the bindings are just bound to the values in the array.
|
|
||||||
bs (into [init `(zero? (alength ~v))]
|
|
||||||
(map-indexed (fn [i x]
|
|
||||||
(if (even? i)
|
|
||||||
x
|
|
||||||
(let [j (quot i 2)]
|
|
||||||
;; Issue 525
|
|
||||||
;; If binding value is not yet set,
|
|
||||||
;; try setting it again. This should
|
|
||||||
;; also throw errors for each render
|
|
||||||
;; and prevent the body being called
|
|
||||||
;; if bindings throw errors.
|
|
||||||
`(if (or ~init
|
|
||||||
(not (.hasOwnProperty ~v ~j)))
|
|
||||||
(aset ~v ~j ~x)
|
|
||||||
(aget ~v ~j)))))
|
|
||||||
bindings))
|
|
||||||
[forms destroy] (let [fin (last body)]
|
|
||||||
(if (and (list? fin)
|
|
||||||
(= 'finally (first fin)))
|
|
||||||
[(butlast body) `(fn [] ~@(rest fin))]
|
|
||||||
[body nil]))
|
|
||||||
add-destroy (when destroy
|
|
||||||
(list
|
|
||||||
`(let [destroy# ~destroy]
|
|
||||||
(if (reagent.ratom/reactive?)
|
|
||||||
(when (nil? (.-destroy ~v))
|
|
||||||
(set! (.-destroy ~v) destroy#))
|
|
||||||
(destroy#)))))
|
|
||||||
asserting (dev?) #_(if *assert* true false)
|
|
||||||
res (gensym "res")]
|
|
||||||
`(let [~v (reagent.ratom/with-let-values ~k)]
|
|
||||||
~(when asserting
|
|
||||||
`(when-some [c# (reagent.ratom/-ratom-context)]
|
|
||||||
(when (== (.-generation ~v) (.-ratomGeneration c#))
|
|
||||||
(d/error "Warning: The same with-let is being used more "
|
|
||||||
"than once in the same reactive context."))
|
|
||||||
(set! (.-generation ~v) (.-ratomGeneration c#))))
|
|
||||||
(let ~(into bs [res `(do ~@forms)])
|
|
||||||
~@add-destroy
|
|
||||||
~res))))
|
|
||||||
|
|
||||||
(def rns (sci/create-ns 'reagent.core nil))
|
|
||||||
|
|
||||||
(def reagent-namespace
|
|
||||||
{'atom (sci/copy-var r/atom rns)
|
|
||||||
'as-element (sci/copy-var r/as-element rns)
|
|
||||||
'with-let (sci/copy-var with-let rns)
|
|
||||||
'cursor (sci/copy-var r/cursor rns)
|
|
||||||
'create-class (sci/copy-var r/create-class rns)
|
|
||||||
'create-compiler (sci/copy-var r/create-compiler rns)})
|
|
||||||
|
|
||||||
(def rtmns (sci/create-ns 'reagent.ratom nil))
|
|
||||||
|
|
||||||
(defn -ratom-context
|
|
||||||
"Read-only access to the ratom context."
|
|
||||||
[]
|
|
||||||
ratom/*ratom-context*)
|
|
||||||
|
|
||||||
(def reagent-ratom-namespace
|
|
||||||
{'with-let-values (sci/copy-var ratom/with-let-values rtmns)
|
|
||||||
'reactive? (sci/copy-var ratom/reactive? rtmns)
|
|
||||||
'-ratom-context (sci/copy-var -ratom-context rtmns)})
|
|
||||||
|
|
||||||
(def rdbgns (sci/create-ns 'reagent.debug nil))
|
|
||||||
|
|
||||||
(defn -tracking? []
|
|
||||||
reagent.debug/tracking)
|
|
||||||
|
|
||||||
(defn ^:macro error
|
|
||||||
"Print with console.error."
|
|
||||||
[_ _ & forms]
|
|
||||||
(when *assert*
|
|
||||||
`(when (some? js/console)
|
|
||||||
(.error (if (reagent.debug/-tracking?)
|
|
||||||
reagent.debug/track-console
|
|
||||||
js/console)
|
|
||||||
(str ~@forms)))))
|
|
||||||
|
|
||||||
(def reagent-debug-namespace
|
|
||||||
{'error (sci/copy-var error rdbgns)
|
|
||||||
'-tracking? (sci/copy-var -tracking? rdbgns)
|
|
||||||
'track-console (sci/copy-var d/track-console rdbgns)})
|
|
||||||
|
|
||||||
(def rdns (sci/create-ns 'reagent.dom nil))
|
(def rdns (sci/create-ns 'reagent.dom nil))
|
||||||
|
|
||||||
(def reagent-dom-namespace
|
(def reagent-dom-namespace
|
||||||
|
|
Loading…
Reference in a new issue