vouch-opensource / krell Goto Github PK
View Code? Open in Web Editor NEWSimple ClojureScript React Native Tooling
License: Eclipse Public License 1.0
Simple ClojureScript React Native Tooling
License: Eclipse Public License 1.0
We can show the prompt early even if it's not quite ready.
Currently images are not supported, these js/require
calls have no special handling. Metro will fail when trying to handle these since they are relative.
If the connection is lost we should update the state of the REPL so that :cljs/quit
can work.
When trying bad forms like (first 1)
we get a strange exception from React Native - obj is not an Object. (evaluating key in obj)
, this is also what's returned from the REPL.
Currently the socket open loop in krell.repl
never times out or bounds retries.
We could use upstream {:npm-deps ...}
support for this. Should verify that ClojureScript supports this a one-liner via clj
.
Watch the depth graph and reload namespaces. There should be a flag for this of some kind?
Connecting to an Android Device does not appear to work because the published service never shows up in the REPL device selector. This is odd because running an OS X Bonjour discovery tool shows the device service immediately.
Indexing node_modules
every build is slow (9 seconds) - instead cache the index to .krellcache
. Only re-index if package-lock.json
newer than the cache.
main.js is the domain of ClojureScript - would need to add that bit there.
We need to collect all library requires even if not in the ns form. Will help transitioning away from re-natal.
Most of the things we're calling in cljs.closure
exist in cljs.build.api
. The signatures are a bit legacy style, but c'est la vie.
Downstream issue fixed Rapsssito/react-native-tcp-socket#36
mDNS while cool is also bound to cause issues in some situations - we should provide an additional way to connect.
It should be possible to start start a Krell REPL via piggieback/nREPL, write basic instructions for Emacs users
Thus (defn foo [a] a)
at the REPL fails.
After successfully starting a REPL and leaving it alone for a couple minutes, I received the following error:
$ clj -m krell.main -co build.edn -c -r
SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.
Waiting for device connection on port 5001
ClojureScript 1.10.741
cljs.user=> #error {
:cause Connection lost
:data {:type :no-ack, :queue-value nil}
:via
[{:type clojure.lang.ExceptionInfo
:message Connection lost
:data {:type :no-ack, :queue-value nil}
:at [krell.repl$rn_eval invokeStatic repl.clj 50]}]
:trace
[[krell.repl$rn_eval invokeStatic repl.clj 50]
[krell.repl$rn_eval invoke repl.clj 30]
[krell.repl$recompile invokeStatic repl.clj 227]
[krell.repl$recompile invoke repl.clj 197]
[krell.repl$setup$fn__450 invoke repl.clj 275]
[clojure.lang.AFn applyToHelper AFn.java 154]
[clojure.lang.AFn applyTo AFn.java 144]
[clojure.core$apply invokeStatic core.clj 665]
[clojure.core$with_bindings_STAR_ invokeStatic core.clj 1973]
[clojure.core$with_bindings_STAR_ doInvoke core.clj 1973]
[clojure.lang.RestFn applyTo RestFn.java 142]
[clojure.core$apply invokeStatic core.clj 669]
[clojure.core$bound_fn_STAR_$fn__5734 doInvoke core.clj 2003]
[clojure.lang.RestFn invoke RestFn.java 408]
[krell.watcher$fn$reify__375 onEvent watcher.clj 16]
[io.methvin.watcher.DirectoryWatcher watch DirectoryWatcher.java 270]
[io.methvin.watcher.DirectoryWatcher lambda$watchAsync$0 DirectoryWatcher.java 195]
[java.util.concurrent.CompletableFuture$AsyncSupply run CompletableFuture.java 1604]
[java.util.concurrent.CompletableFuture$AsyncSupply exec CompletableFuture.java 1596]
[java.util.concurrent.ForkJoinTask doExec ForkJoinTask.java 289]
[java.util.concurrent.ForkJoinPool$WorkQueue runTask ForkJoinPool.java 1056]
[java.util.concurrent.ForkJoinPool runWorker ForkJoinPool.java 1692]
[java.util.concurrent.ForkJoinWorkerThread run ForkJoinWorkerThread.java 157]]}
cljs.user=> (js/alert "test")
Execution error (SocketException) at java.net.SocketOutputStream/socketWrite0 (SocketOutputStream.java:-2).
Broken pipe (Write failed)
cljs.user=>
I think :preloads
aren't being picked up.
My use case is installing binaryage/cljs-devtools via the preloads complier option.
Also tried a simple console statement in a preload namespace but it doesn't appear in the react native debugger (chrome terminal).
It makes it easier for Cursive to detect.
index.js shouldn't actually ever change, we shouldn't write it out except for maybe Krell version changes?
Steps to reproduce are based on the reagent tutorial.
AwesomeProject % cat deps.edn
{:deps {io.vouch/krell {:git/url "https://github.com/vouch-opensource/krell.git"
:sha "b24b3f1c236cf80dda8cd06d949d391b86308ae7"}
io.vouch/reagent-react-native {:git/url "https://github.com/vouch-opensource/reagent-react-native.git"
:sha "54bf52788ab051920ed7641f386177374419e847"}
reagent {:mvn/version "0.10.0"
:exclusions [cljsjs/react cljsjs/react-dom]}}}
AwesomeProject % cat src/awesome_project/core.cljs
(ns awesome-project.core
(:require [reagent.core :as r]
[reagent.react-native :as rn]))
(js/console.log (pr-str ::hello))
(def fsm-state :idle)
(defn helper
[state]
(js/console.log (pr-str ::state state))
(js/console.log (pr-str ::meta (meta state)))
(js/console.log (pr-str ::eq(= state :idle)))
(js/console.log (pr-str ::identical? (identical? state :idle)))
(case state
:idle (js/console.log "GOOD: Case statement matches :idle")
(do (js/console.log (pr-str "BAD: Case statement didn't match :idle against " state))
)))
(defprotocol IEventQueue
(-fsm-trigger [this]))
(defrecord EventQueue []
IEventQueue
(-fsm-trigger
[_]
(helper :idle)
(helper fsm-state)))
(def event-queue (->EventQueue))
(defn runtest [] (-fsm-trigger event-queue))
(defn ^:export -main [& args]
(r/as-element
[rn/view {:style {:flex 1 :align-items "center" :justify-content "center"}}
[rn/text {:style {:font-size 50}} "Hello Krell!"]]))
Steps to repeat:
(awesome-project.core/runtest)
Expect: Metro log shows GOOD twice
Actual: Metro log shows GOOD once, and BAD once
e.g.
[Sun Apr 26 2020 13:25:01.529] LOG :awesome-project.core/state :idle
[Sun Apr 26 2020 13:25:01.530] LOG :awesome-project.core/meta nil
[Sun Apr 26 2020 13:25:01.530] LOG :awesome-project.core/eq true
[Sun Apr 26 2020 13:25:01.530] LOG :awesome-project.core/identical? false
[Sun Apr 26 2020 13:25:01.530] LOG GOOD: Case statement matches :idle
[Sun Apr 26 2020 13:25:01.531] LOG :awesome-project.core/state :idle
[Sun Apr 26 2020 13:25:01.531] LOG :awesome-project.core/meta nil
[Sun Apr 26 2020 13:25:01.531] LOG :awesome-project.core/eq true
[Sun Apr 26 2020 13:25:01.531] LOG :awesome-project.core/identical? false
[Sun Apr 26 2020 13:25:01.532] LOG "BAD: Case statement didn't match :idle against " :idle
The fail case seems to go away once the namespace is reloaded. To repeat the test :cljs/quit and restart the krell REPL (the app refreshes by itself).
Only repeatable on a freshly started REPL.
Infrequently doesn't fail on a freshly started REPL.
establish print fns that write output to the socket before invoking RN console fns
Now that we send a single big message, the receipt of the ack is now tied to the runtime cost of eval.
That is, long evaluations will fail. We should reorganize the code a bit for Android such that the ack can be read immediately w/o re-introducing out of order message arrival
One simple way maybe to schedule the result write via a setTimeout
?
The only tricky thing here is that we probably need to regenerate rt.js
for out of the box parallel dev
We could probably cache files on the device. We probably need some simple library for this and pass some kind of timestamp to the device when loading a file.
Instead of reusing the eval socket for file loads, the Krell REPL could publish a socket for file loading. Then the client could load files in parallel.
Tested against latest commit in master (88c431)
AwesomeProject % cat deps.edn
{:deps {io.vouch/krell {:git/url "https://github.com/vouch-opensource/krell.git"
:sha "88c4319de923e914c6888db54c0644b6f1ab0f2d"}
io.vouch/reagent-react-native {:git/url "https://github.com/vouch-opensource/reagent-react-native.git"
:sha "54bf52788ab051920ed7641f386177374419e847"}
reagent {:mvn/version "0.10.0"
:exclusions [cljsjs/react cljsjs/react-dom]}}}
AwesomeProject % cat build.edn
{:main awesome-project.core
:output-to "target/main.js"
:output-dir "target"}
AwesomeProject % ls -la src/awesome_project/c*
total 32
-rw-r--r--@ 1 olivergeorge staff 11012 22 Apr 10:08 cljs.png
-rw-r--r-- 1 olivergeorge staff 444 22 Apr 10:33 core.cljs
AwesomeProject % cat src/awesome_project/core.cljs
(ns awesome-project.core
(:require [reagent.core :as r]
[reagent.react-native :as rn]))
(def logo (js/require "./cljs.png"))
(defn ^:export -main [& args]
(r/as-element
[rn/view {:style {:flex 1 :align-items "center" :justify-content "center"}}
[rn/image {:source logo :style {:width 80 :height 80 :margin-bottom 30}}]
[rn/text {:style {:font-size 50}} "Hello Krell!"]]))
AwesomeProject % clj -m krell.main -co build.edn -c -r
SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.
In another terminal we see no krell_assets.js
olivergeorge@Condense-iMac AwesomeProject % ls target
awesome_project cljs_deps.js clojure inferred_externs.js main.js process
cljs cljsc_opts.edn goog krell_repl.js npm_deps.js reagent
And Metro reports
Unable to resolve module `./krell_assets.js` from `target/krell_repl.js`:
None of these files exist:
* target/krell_assets.js(.native|.ios.js|.native.js|.js|.ios.json|.native.json|.json|.ios.ts|.native.ts|.ts|.ios.tsx|.native.tsx|.tsx)
* target/krell_assets.js/index(.native|.ios.js|.native.js|.js|.ios.json|.native.json|.json|.ios.ts|.native.ts|.ts|.ios.tsx|.native.tsx|.tsx)
RCTFatal
__28-[RCTCxxBridge handleError:]_block_invoke
_dispatch_call_block_and_release
_dispatch_client_callout
_dispatch_main_queue_callback_4CF
__CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__
__CFRunLoopRun
CFRunLoopRunSpecific
GSEventRunModal
UIApplicationMain
main
start
Should investigate why the REPL takes so much longer to connect than displaying the Krell app root. If the Krell app root appears that means goog.require
etc. is all available.
A post release feature, not for now - but the ability to require images relative to the classpath would be great for creating reusable idiomatic react native components.
All the libraries we're currently using also work for Android. We should verify that everything does in fact work as expected and the dependencies don't create any issues for usage.
Assets & arbitrary lib loads are only collected after a compile, but the ClojureScript compiler skips compile when it can so on a second build this information will not be available.
While testing the tutorial on Android I discovered file requests are not being sent in order. This is likely due to the fact that the underlying tcp socket library uses a new Android task for each write even if it's to the same socket. We should use a queuing mechanism similar to the one we implemented for writing acks for Android.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.