There's a project I am working on. It involves headlessly manipulating canvas data/state (think excalidraw/tldraw) on the server. UI is in cljs (re-frame). I know some work has been done on server/node cljs but I don't have enough experience to judge the fit. Also, SDKs for headless manipulation are typically typescript. I decided to write PoCs in typescript. But I'm kind of getting concerned about my codebase fragmentation: cljs UI, ts/js server. Python for ML/data stuff, clj for orchestration and more. I would love it somehow cljs could go all the way down (sans the ML stuff), the way it would be if did it in typescript. I guess with intelligent boundaries and interop and so on, cljs might just do what I want but I'm not certain. Any ideas?
Personally, I'd go with Clojure on the server, CLJS on the frontend, Python for ML via libpython-clj.
But that's without knowing all that you have to do.
What exactly do you mean by "headlessly manipulating canvas data/state"? Manipulating bitmap image? Or a series of commands that aren't really tied to a JS canvas object? Or some "mock" object that does exactly what <canvas> does but without displaying it?
Imagine for example you have an agent that is brainstorming with you. You might write some text or draw. The server agent also "writes" and "draws" on the canvas, but it does so through manipulating the server representation of the canvas state - More or less structured JSON-ish representation.
But, for exalidraw for example, there is manipulation API. You may try and manipulat the data structur edirectly but that would be too cumbersome or reinventing the wheel
Well, if you want to keep using a JS library then yeah, you'd have to use something that talks to JS - JS itself, CLJS, TS. CLJS on the server is fine, plenty of people use it. But the way you describe it doesn't make it sound as if you need Excalidraw specifically. In that case, I'd probably come up with my own EDN-based grammar that encodes the required canvas operations in a nice way and work with that. It's a trivial task, in some sense more trivial than learning and using a thirdparty JS API.
The UI is already running excalidraw. It's safe to say I'm stuck with it, at least unless something else surfaces. Straightforward bet to minimize fragmentation is just use TS. CLJS would be my fav because of alignment but I'll see.
"EDN-based grammar that encodes the required canvas operations in a nice way and work with that" - Sounds like an interesting direction. Saved for potential later experimentation.
Unless you have bazillions of objects and unless Excalidraw's API is slow, you can even have that grammar on top of that API. So all the opaque stuff could be fully contained within a running web page.
Yes, def an interesting idea! I'll need to see the implications.