SCI lazy loading namespaces: https://github.com/babashka/sci/blob/master/doc/async.md#lazy-loading-a-namespace
nice, we should give this a spin in nextjournal
could try next week - I assume you mean http://nextjournal.com, the product right?
(sci/add-namespace! ctx libname sci-ns))) ------------^------------------------------------------------------------------- Use of undeclared Var sci.core/add-namespace!
I am getting this warning from shadow-cljs.
weird.
its a normal function.
does clojars babashka 0.3.5 contain this function?
what is weird: clojars says 0.3.5 was published on may 1. but in github releases it says 0.3.5 was published on may 16.
So I fixed it by using sci via git dependency.
But the difference of github releases and clojars is still weird.
yes, it's not in 0.3.5, just on master
I forgot to make a release on github for 0.3.5 so I did that later
thanks for the explaination!
I have one question:
So I am adding lots and lots of extensions,
just with edn metadata.
{:name "js-interop" ; build :lazy false :cljs-namespace [; clojure clojure.string clojure.walk applied-science.js-interop] :cljs-bindings {} :cljs-ns-bindings {'string {'split clojure.string/split 'join clojure.string/join 'escape clojure.string/escape 'blank? clojure.string/blank? 'replace clojure.string/replace 'lower-case clojure.string/lower-case} 'j {'get applied-science.js-interop/get 'call applied-science.js-interop/call 'get-in applied-science.js-interop/get-in 'call-in applied-science.js-interop/call-in 'obj applied-science.js-interop/obj} 'walk {'postwalk clojure.walk/postwalk 'prewalk clojure.walk/prewalk 'keywordize-keys clojure.walk/keywordize-keys 'walk clojure.walk/walk 'postwalk-replace clojure.walk/postwalk-replace 'prewalk-replace clojure.walk/prewalk-replace 'stringify-keys clojure.walk/stringify-keys}} }
this is one example.
lazy:false means this module put into the main js file of the bundle
lazy:true means put this into a separate js module that gets lazy loaded.
the reason why I go with this edn file is,
so that I do not need any sci dependency in libraries that might be used without sci.
I autogenerate the rest based on many of this definitions.
Now I would like to build the sci environment in the best way possible
I understand that macros from clojurescript will not work, and they need to be rewritten.
but most of the other stuff should work.
So this wrappers you use in your sci-namespace definitions,
I guess they are all macros that supply meta data to the sci environment?
Or is there any other reason why an export would better not be defined in an edn module?
clojure string and walk are already included in SCI so it doesn't make sense to make those lazy. you can see the config for js-interop here: https://github.com/babashka/sci.configs/blob/main/src/sci/configs/applied_science/js_interop.cljs in fact, you can use sci.configs as a library to get the config
you can check out nbb's shadow config: https://github.com/babashka/nbb/blob/main/shadow-cljs.edn everything except the core module is loaded lazily
the idea is to just compile separate modules and some are optional. the optional ones add something to the sci context when loaded
you can even make an optional module which first defines the sci context, so you can exclude SCI for a very thin build
and then the other ones add something to the context on load
its an amazing idea! I will start using sci.configs !
Do you plan to add more configs in the future?
Or in other works: do you plan to make sci.configs to somethinig similar to the babashka pods registry?
yes, more configs will be there probably
PERFECT!
Great news!
thanks a lot!
It all works now @borkdude. But there is one edge case:
(ns example3 (:require [funny])) (funny/joke)
(ns example4 (:require [funny :refer [joke]])) (joke)
(ns example5 (:require [funny :as f])) (f/joke)
so all 3 examples work!
when I start a new sci context,
lazy loading works, sci eval works - perfect.
BUT
the example5, whith :as f
that does not work.
can you make a github issue with repro? then I'll take a look tomorrow
sure
ticket done. I kept it really short. But I verified all a couple of times.
ticket solved
Great! Thankd a lot!
Just some report on the async loader: in goldly I have 20 source code files that get evaled on startup. And I have a browser based sci clojurescript repl. I yesterday (before you fixed the issue) changed all requires so that I would avoid :refer and :as. All working perfect! This async loader really is the key issue to loading modules. I still have an async ui renderer loader that works with sync eval only. But I intend to rewrite it as soon as I did some more tests on the async eval.
What I noticed is that even though it is just a very minor interface differene (promise instead of result) I had to change aa lot of code to make it work. So I will migrate 100% to the async loader. This is so that I can use modules. Because module loading does not work in sync eval.
async evals with the async-loader work great. but there are some situations where it does not work: The code below is a snippet which I eval in its entirity in sci in the browser. When I require [funny :as f] then it works, so (f/joke) in the code works. But when I just have [funny] and then I call (funny/joke), then it does NOT work. If my require is [funny :as funny] then (funny/joke) works also. A require with :refer does not work in an circumstance. (I didnt put an example for that into the snippet) this is a link to the async-eval in clojurescript: https://github.com/pink-gorilla/goldly/blob/master/goldly/src/goldly/sci/kernel_cljs.cljs
(ns demo.notebook.lazy
(:require
[r]
[string]
[user :refer [compile-sci-async println]]))
; this is a sci-cljs notebook!
(defn wrap-code [form]
(string/join
"\n"
(map pr-str form)))
(defn show-atom [a]
[:p (pr-str @a)])
(defn async-eval [form]
(let [d (r/atom "async compiling..")
p (compile-sci-async (wrap-code form))]
(.then (:result p)
(fn [result]
(.log js/console "async result: " result)
(reset! d result)))
^:R
[show-atom d]))
^:R
[:div
(async-eval
'[(ns example1 (:require ["some_js_lib" :as my-lib]))
(my-lib/libfn)])
(async-eval
'[(ns example2 (:require [adder :as x]))
(x/add 7 13)])
(async-eval
'[(ns example3 (:require [funny :as f]))
(f/joke)])
#_(async-eval
'[(ns example4 (:require [funny :as funny]))
(funny/joke)])
(async-eval
'[(ns example5 (:require [funny]))
(funny/joke)])]@hoertlehner I see. If you return {:handed true} then SCI does not process any :refer [x y z] and it assumes you have handled that yourself.
Let me work out a scenario where you would like to define a normal Clojure namespace in SCI using async load fn
@hoertlehner voila: https://github.com/babashka/sci/blob/master/doc/async.md#lazy-loading-a-namespace
Perfect!!! Thank you so much!