Hey folks! A question for you.. I'm looking into what it would take to build a Clojure (not ClojureScript) REPL that runs in a browser. The use case is for self-contained learning/education apps, with a key requirement that Clojure & Java-only libs can be used. Please see the attached image for context. As you can see, it includes some JS components, which could be in ClojureScript, but the REPL itself is a Clojure REPL (not ClojureScript). Likely nREPL transport options are 1) JSON over HTTP or 2) Websockets, with the latter probably being a better mapping to sockets as used by nREPL. For the nREPL server piece, the closest existing option I could find is Drawbridge https://github.com/nrepl/drawbridge although it would need some work to add Websockets https://github.com/nrepl/drawbridge/issues/44. For the nREPL client piece, the closest existing option is Weasel https://github.com/nrepl/weasel. I got it running and poked around, however, it seems to be very much for ClojureScript and I haven't yet figured out if I could dissect it to work for my use case. Otherwise I'd need to look elsewhere or more likely, start anew. My understanding of what's going on with Weasel (forgive me if incorrect, I am less familiar with ClojureScript) 1. Piggieback reads repl input and compiles it to JS 2. Weasel nREPL server sends it to Weasel JS nREPL client, using websockets 3. Weasel JS nREPL client evals the JS message 4. Then replies to nREPL server with result, using websockets Whereas I need 1. JS nREPL client sends message to nREPL server, using websockets 2. Clojure nREPL server evals the Clojure message 3. Then replies to the nNREPL client with the result, using websockets I also found Rich4Clojure https://github.com/PEZ/rich4clojure via https://clojureverse.org/t/practice-clojure-in-a-full-editor-based-experience-without-installing-anything/8049 but that seems to use a full VSCode stack running in the browser, whereas I'm looking for something much more basic and lean. Thoughts and opinions welcome :)
Have you seen https://github.com/rksm/node-nrepl-client?
Maybe https://github.com/kanej/parle is also relevant
out of curiosity, what are the particular aspects of nRepl that you need? Like why does it has to be nrepl instead of a websocket server that gets forms and runs them with eval?
Hi @jpmonettas apologies for the delay in responding. Your suggestion of a proxy was insightful, I actually developed this into a working proof of concept. The server is here: https://github.com/alza-bitz/nrepl-ws-server The client is here: https://github.com/alza-bitz/nrepl-ws-client I'm currently in discussions with the Scicloj team about next steps. Thanks again 🙏🙂
I've done a similar thing a while ago for scittle: https://github.com/babashka/scittle/blob/main/src/scittle/nrepl.cljs
also works for clerk viewer functions now (which are evaluated in SCI)
> Maybe https://github.com/kanej/parle is also relevant Hey @alexyakushev thanks for the suggestions, I'm not sure these would fit my criteria however as the JS nREPL client needs to run in the browser JS environment for my case, not in node.js. But I'll take a look 🙏
> out of curiosity, what are the particular aspects of nRepl that you need? Like why does it has to be nrepl instead of a websocket server that gets forms and runs them with eval? Hi @jpmonettas it's a good point, this could also be a valid option. I think I started with nREPL just because it's the defacto solution in Clojure for distributed interactive programming and due to that, I figured there might be some existing components or libs that I could combine or re-use in some way. Off the top of my head, nREPL ops I would likely need: load-file, describe, eval, completions, close..
makes sense, I guess if you need those, or interruptible eval then I guess nrepl is the way to go
@alza-bitz I guess you could also start a websocket server as a proxy which receives nrepl messages as json and forwards them to nrepl first processing function (whatever comes after the transport) since you will be on the same process. Also since nrepl is not request/response, more like request->multiple-responses you will have to account for that, but if the proxy is a websocket server that shouldn't be a problem. Maybe a proxy is easier and simpler?