Fork me on GitHub

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


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)

Adam Helins09:10:00

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

Adam Helins09:10:20

@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"


there really is no good solution as soon as the worker requires a lot of data to work

Adam Helins09:10:01

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

Adam Helins09:10:43

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

Adam Helins09:10:51

I work a lot with array buffers which are indeed Transferable but I didn't come up with a good solution

Adam Helins09:10:58

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

Adam Helins09:10:08

Feels like programming in DOS. Welcome to the web in 2020

Rico Meinl14:10:05

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

Jack Arrington18:10:04

There is also a #shadow-cljs channel if you don't get an answer here ๐Ÿ™‚

Rico Meinl14:10:48

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

Jack Arrington18:10:08

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?

Jack Arrington18:10:15

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

๐Ÿ‘ 3

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