Fork me on GitHub
#shadow-cljs
<
2018-02-10
>
Jon09:02:03

Can I connect to shadow-cljs's nREPL with my own code? Since my code is in ClojureScript, while nREPL was built in Java.

Jon09:02:44

I found socket REPL is much easier, guessing it's not in shadow-cljs...

thheller09:02:09

of course socket repl is in shadow-cljs

Jon09:02:30

oh... just not found in docs

thheller09:02:41

in the target/shadow-cljs folder there is a socket-repl.port file

thheller09:02:48

thats the port of the socket repl

thheller09:02:58

also the is a cli-repl.port file

thheller09:02:15

also a socket REPL but it does NOT print a prompt

thheller09:02:21

otherwise its the same

Jon09:02:34

sounds good

thheller09:02:46

cli-port is used by the shadow-cljs script itself to communicate with the server

Jon09:02:49

I hate that prompt, hard to building tools

Jon09:02:18

how are the ports picked? randomly

thheller09:02:40

:socket-repl {:port 123} can be configured

thheller09:02:45

cli-repl is always random

Jon09:02:17

guess I would like to try cli-repl...

Jon09:02:30

anyone used it in building tools before?

thheller09:02:35

bear in mind that the cli-repl is meant for internal use and not officially part of the public API

thheller09:02:09

I don't plan on removing it but its also not super well suited for tooling

thheller09:02:20

the shadow-cljs script is simple since it just sends one thing

thheller09:02:05

after that it just reads

thheller09:02:45

nrepl is used by pretty much all tools

thheller09:02:55

maybe prepl in the future? don't know what that is about yet

Jon09:02:02

actually that's what I need to build a tool...

Jon09:02:25

socket REPL is nice, but I don't know how to deal with the prompts

dominicm10:02:44

Hi, you should check out #unrepl as something which has solved this

dominicm10:02:58

It adds structure to socket repl

Jon09:02:48

maybe trying regular expression... could be tedious.

thheller09:02:56

socket REPL isn't really meant for tools

Jon09:02:05

so nREPL?

thheller09:02:16

nrepl is what all other tools use yes

thheller09:02:41

you can in theory use the cli-repl thing but that is literally just socket repl without prompt

thheller09:02:56

stilll has issues as soon as anything prints to stdout

Jon10:02:05

I was suggested node-nrepl-client last night, tried and it worked, but the message it returned is hard to understand

thheller10:02:33

nrepl is weird yes

Jon10:02:01

nrepl ╮( ̄▽ ̄")╭

thheller10:02:49

that solves some of the issues but nowhere near what nrepl provides

thheller10:02:02

what are you trying to build?

Jon10:02:03

I want to send a piece of Clojure code from my own process, and eval it in the runtime(browser, I mean), what's your suggestion?

Jon10:02:03

"prepl" is so new, no Google results

thheller10:02:25

yeah .. no one knows what that is about yet. it was commited by Rich 2 days ago ...

thheller10:02:55

I can see what it does by reading the code ... I don't know WHY though

thheller10:02:16

so sending things to the browser is complicated

Jon10:02:34

shadow-cljs is already doing that...

Jon10:02:40

in cljs-repl.

thheller10:02:10

yes. but you need a running watch for that and a connected client

Jon10:02:25

I just noticed after using my own editor for so long, I don't even use some basic tool others are using in tools like EMACS.

Jon10:02:43

...trying to script my own version

Jon10:02:19

my tool will base on that, page connected to shadow-cljs.

thheller10:02:41

well if you don't care about the result at all you could just run shadow-cljs cljs-repl your-build and print all stdout somewhere

thheller10:02:55

but parsing the output is painful

thheller10:02:04

but you don't have to parse the output

Jon10:02:05

only thing I can do at current is generate Clojure code, send it somewhere, maybe print the logs also.

Jon10:02:50

output in browser, or in my process, I don't mind.

thheller10:02:57

what the shadow-cljs script does is connect to the cli-repl port

thheller10:02:26

send (shadow.cljs.devtools.cli/from-remote "some-uuid" "another-uuid" ["cljs-repl" "your-build"])

thheller10:02:48

after that the output is just printed

thheller10:02:00

all input is sent to the socket as-is

thheller10:02:25

so the cljs-repl command will read and process it

Jon10:02:34

tried in my nodejs REPL, doesn't know how it works..

Jon10:02:12

where should I get the uuids,

Jon10:02:20

and where to put my code?

thheller10:02:07

there are no docs for this and there probably won't be

thheller10:02:32

but it is very simple code

thheller10:02:55

ALL tools use nrepl. there is a reason for that.

thheller10:02:27

unrepl is newer but not many tools use it (yet). prepl will be something official but nobody knows when this will get adoption. socket-repl still isn't used by anything and thats has been there since 1.7.

Jon10:02:35

strange situation...

thheller10:02:47

not really, just use nrepl

Jon10:02:38

what does this argument do? ["cljs-repl" "your-build"]

thheller10:02:47

just follow the code

thheller10:02:18

these are all internal details that are not part of the public API

thheller10:02:32

and never will be

thheller10:02:53

if you give me a clear definition of what you want to do I can take a look at implementing something to make that work

Jon10:02:57

(>﹏<)

Jon10:02:16

still trying...

thheller10:02:21

but all this is internal stuff I needed.

thheller10:02:42

just saying that you could use it to make something semi reliable

thheller10:02:56

but it has lots of issues and nrepl is far more reliable and tested

Jon10:02:02

I just saw people evaluating code from their editors last night.

thheller10:02:13

also already has reliable middleware configuration and that stuff

thheller10:02:26

yes, everyone does that via nrepl

thheller10:02:56

cursive doesn't even support connecting to remote socket REPLs (yet)

Jon10:02:17

so people don't do that in Cursive?

thheller10:02:37

I do it pretty much always via nrepl

Jon10:02:07

turned out nrepl is the thing I have to code anyway.

thheller10:02:36

I would recommend using that yes

thheller10:02:54

socket repl or even the cli-repl gets destroyed by any print you don't expect

thheller10:02:00

if you attempt to parse the output at all

thheller10:02:23

works fine if you never try to parse the output though

thheller10:02:34

and you don't have to parse the output strictly speaking

Jon10:02:34

no, I don't parse the output

thheller10:02:36

but yeah REPL in my editor is a must have for Clojure. not so much for CLJS though.

thheller10:02:07

then the prompt should not be an issue?

Jon10:02:39

I'm still thinking about if there any way to improve my workflow. I'm the only user, and no one would write plugins for me except myself.

dominicm10:02:17

What editor do you use? :thinking_face:

Jon10:02:56

too many threads ><

dominicm10:02:49

ah, your own

dominicm10:02:58

I would totally recommend using unrepl then!

dominicm10:02:12

Unrepl is a protocol for interacting with Clojure via socket repl

Jon10:02:21

just glanced video on unrepl hours ago,

Jon10:02:36

I didn't find enough docs.

Jon10:02:50

plus, my toolchains is based on shadow-cljs,

dominicm10:02:53

Come join #unrepl, @U3E46Q1DG would be glad to help 🙂

Jon10:02:06

I still have to connect it with shadow-cljs..

dominicm10:02:05

(Live-reload for clojure)

Jon10:02:16

yeah prompt is not a issue for me.

thheller10:02:52

@dominicm I toyed with that idea once but it is horrible in practice 😛

thheller10:02:17

but cursive has a button for this so I guess the only difference is that I can trigger it when I want to

dominicm10:02:43

The cursive user told me they utilized the auto-save on un-focus feature, which surprised me 😂

thheller10:02:46

it is strange though. for clojure I definitely prefer manually requiring/reloading namespaces and doing things via the REPL

thheller10:02:59

in CLJS I just let live-reload do its thing and almost never use the REPL

thheller10:02:19

strange how the workflows can be so different

Jon10:02:26

took me long while to realize ["cljs-repl" "browser"] does nothing but connect me to the REPL in browser..

Jon10:02:01

do people who eval code form EMACS or other editors call this API too?

thheller10:02:37

no one uses this API. no one even knows about this API.

thheller10:02:45

everyone uses nREPL.

Jon10:02:27

but... when they use nREPL, the code is evaluated in your Clojure process, not in the browser?

Jon10:02:20

so.... just used it to start watching...?

thheller10:02:47

I can't answer that. YOU need to decide what you want to do.

thheller10:02:59

you can start the watch yes, you can also assume it is running already

thheller10:02:05

I don't know what your tool needs

Jon10:02:24

I want to click an expression in my editor, and it's evaluated in browser.

Jon10:02:45

also pressing keyboard shortcut probably

Jon10:02:03

after pressed, my editor will generate code and send to shadow-cljs

Jon10:02:29

and let shadow-cljs send that piece of code into the connected browser tab, and eval.

Jon10:02:58

just like people did to eval selected code in a Clojure REPL with nREPL,

Jon10:02:24

difference is my runtime is the browser, too far to send the code.

Jon10:02:50

I think I have got all the code needed to make it happen now..

Jon11:02:51

Thanks for the help. Going out for some hours. I will try add it in my editor later, and gather feedbacks.

schnipseljagd12:02:18

Hi, I have the problem that *target* is set to default instead of nodejs (what I would expect) when the build is configured with :target :node-script. Can anyone give me a hind here where I am running into?

thheller12:02:44

hmm what is *target*?

thheller12:02:01

hehe cljs.core/*target* I presume. Didn't even know that existed

schnipseljagd12:02:47

Yes exactly, before this me neither 😉

thheller12:02:01

You can set :compiler-options {:closure-defines {cljs.core/*target* "nodejs"}} in your build

thheller12:02:40

seems to be a self host thing though?

thheller12:02:10

ah hmm no its used in some places

thheller12:02:36

I can set it to nodejs for :node-script and :node-library builds

schnipseljagd12:02:36

Gosh, thanks, I already tried various combinations to get this set via clojure-defines. Now it works.

schnipseljagd12:02:39

I think that would be the correct solution.

thheller12:02:24

hehe opened while I was writing the commit message. insta-closed 😉

schnipseljagd12:02:11

Thanks a lot! 👍

justinlee18:02:21

by the way @thheller, just to follow up on my sorrows of the past few days: not only was I battling the weird stale state issue, but it turns out that due to a known bug in an old version of nodemon (!!!), my server was restarting without me noticing every time I saved my client code in atom (actually it would restart even when i switched tabs). so the hot code reloading was appearing to break in the most nondeterministic and impossible to debug ways imaginable. talk about bad luck.