This looks like a normal solution to me.
Alternatively, you can store children refs at the level of the parent component right along observer
in another atom (no need for ratom in this case) and just iterate over them and call .observe @observer
on each in the parent's ref.
Did anybody manage to get a working REPL with a Cursive setup in shadow-cljs? I'm following the shadow-cljs guide and set up a remote REPL listening to shadow-watch and everything seems to work, except for the :requires. For example I require "
[shadow.expo :as expo]
When I then try to send the file to the REPL it says:
Syntax error (FileNotFoundException) compiling at (src/app/app.cljs:1:1).
Could not locate shadow/expo__init.class, shadow/expo.clj or shadow/expo.cljc on classpath.
So apparently, the sources from node_modules are not available in the context of the REPL.you are in the Clojure REPL. you need to switch it to the CLJS REPL first. see https://shadow-cljs.github.io/docs/UsersGuide.html#_cursive
There probably isn't any magical solution, but maybe someone has a creative solution. It seems that sharing data with web workers is a growing concern in CLJS. Offloading CPU intensive computations, wanting to draw a canvas from a worker while needing to keep data on the main thread... It is not a CLJS-specific problem (it's a JS one), but it is hard to let go when one is used to sharing complex immutable data across threads in CLJ. How do you cope?
@adam678 FWIW in the shadow-cljs web UI I'm experimenting with workers. In that case all "data" or "state" is living in the worker and the UI just sends small EQL-ish queries for the data it needs. since that data is rather small and pretty declarative in nature the overhead is actually much smaller than I had anticipated
it is working ok but not really something I'd recommend. having all the data in the worker makes all access async which is kinda annoying at times.
shipping small snippets of data back and forth between the worker is fine. transferring big data is not so if you do anything in the worker try to have the worker load the data itself
and not the main thread sending it over there since that may block the main thread too long
big in this case can be as little as 1mb, which may already impact animations you might have on the page
@thheller Yes, I envisioned this kind of async access but then the problem was kind of just shifting away. Suddenly, the worker was responsible of doing "everything"
indeed
there really is no good solution as soon as the worker requires a lot of data to work
My current use case is specific I must admit, I am doing audio which is time sensitive (so I am not fond about adding extra latencies, the browser is already a challenging env) + visualization on top. OTOH, the browser is evolving towards that kind of workloads, so if CLJS would provide a bit of a solution, we would be once again at the forefront
not sure what CLJS could provide over what JS already has. if anything we are always going to pay the extra datastructure cost since JS can just send objects
Yeah I am really not sure, but maybe some macro magic over shared array buffers or something...
Just in case - there are also Transferable
objects that can help with large data sizes since they're not copied but rather, well, transferred.
that doesn't really help anything when working with CLJS data
also the object is handed over to the worker so the main can't use it anymore after
but you can certainly build something that works with native uint8arrays or so and just transfer those. that will be fast and not much overhead.
never really worked with anything audio so no clue what the data looks like
but stuff like the audio worklets are already not a great fit for CLJS
Yep, lots of interop.
kind hard to create small snippets of JS that don't also pull in cljs.core
I work a lot with array buffers which are indeed Transferable
but I didn't come up with a good solution
As soon as the data is truly needed at more than one place, it gets tough...
yeah I can imagine audio being tough in a single threaded world that also has to do a bunch of other stuff
Feels like programming in DOS. Welcome to the web in 2020
Hi Thomas, thanks for the reply. Yes, I am using cljs in the REPL. As a matter of fact, when I switch to clj, this error does not appear (but I cannot eval anything from the active NS either)
why not?
did you read https://shadow-cljs.github.io/docs/UsersGuide.html#repl-troubleshooting?
Did anyone ever try to import a node js package and it didn't work as expected? I'm Using shadow cljs to compile and I'm wondering whether there are some compiler options I might be missing for it to work
Talking about the "roam-client" package. It works for me when I run it in Javascript but as soon as I'm putting it into clojurescript it stops working
There is also a #shadow-cljs channel if you don't get an answer here π
Since docstrings are just metadata in Clojure, which is available at runtime, does that mean a large docstring will actually increase the size of my production JS bundle? Or will the compiler elide it?
Doesn't strictly matter for what I'm using CLJS for, just curious
I donβt believe metadata on defed things are actually emitted as code by default. They exist only at compile time until you call something like meta
what can i do to ensure that a .nrepl-port
file is generated? for reference i'm starting a barebones shadow-cljs project, but i'm not getting an nrepl port file when running npx shadow-cljs server