shadow-cljs

pez 2025-09-21T16:19:29.216369Z

Hello. I am trying to implement shadow-remote runtime notifications in Calva, over nrepl. It fails silently for me when sending the shadow-remote-init op. I can see the message being sent in Calva’s nrepl log:

1758470993749 -> sent 
{
  op: 'shadow-remote-init',
  id: '6',
  session: '3db2fcfa-4a90-4f9d-90e4-0cc86d57a253',
  'data-type': 'edn'
}
But there is never any response received. If i send an invalid data-type, I get an error response, though:
1758471269107 <- received 5ms
{
  err: 'Invalid :data-type, edn|transit expected.',
  id: '6',
  session: '9ef83d51-fa73-4684-872a-f1ded541db70'
}
I don’t know how to proceed. Am I not supposed to receive a response?

thheller 2025-09-21T19:13:10.126699Z

"response" no, you'll just get new shadow remote messages, which in itself all require their own trigger. its all message based, so technically not RPC

thheller 2025-09-21T19:14:06.687579Z

for example, after the shadow-remote-init you can send

{:op "shadow-remote-msg"
 :data "{:op :request-clients :notify true :query [:eq :type :runtime]}"}

thheller 2025-09-21T19:14:41.503019Z

that'll send you all the active connected runtimes and notify you when new ones connect or disconnect

thheller 2025-09-21T19:16:01.423539Z

technically you should already receive a shadow-remote-msg nrepl msg with welcome

thheller 2025-09-21T19:16:25.750249Z

but if you are only setup to listen for RPC type things then that'll maybe not work

thheller 2025-09-21T19:17:56.484969Z

I'll see about setting up an example tommorrow

pez 2025-09-21T20:13:45.776259Z

Thanks. I got past this hurdle by not assuming I would get a response. 1. I’m not receiving any welcome message, but 2. I get the message with the clients 3. I get the notifications on disconnect and connect 4. I don’t get a connect notification for the initial connect. 4 would be nice, but if I can assume that I always initially connect to the first client in the list, then I’m good.

pez 2025-09-22T07:26:29.578819Z

I have it working now. It was first by accident, because I added debug prints of the return promises from my nrepl message sender. That introduced enough delay for the init to be finished when i sent the notify-me message. Then when removing the debug prints, things stopped working. I replaced the prints with an explicit delay., but it doesn’t feel super comfortable to rely on such tricks. I think that the best for Calva, was if both the shadow-remote-init and shadow-remote-msg messages had corresponding status: [ 'done' ] messages sent back to Calva, when whatever shadow needs to do to be ready for the next step is done. That would fit perfectly into how Calva’s message handler works. And I imagine most nrepl clients are wired to handle this particular exchange well.

thheller 2025-09-22T09:32:38.938299Z

how hard would it be for you to do a websocket connection? might make things much easier than having this nrepl thing in the middle with all its quirks

thheller 2025-09-22T09:35:35.541119Z

dunno if this makes any sense but this is a dummy example websocket client I used for testing https://github.com/thheller/shadow-cljs/blob/master/src/dev/shadow/remote_example_ws.clj

thheller 2025-09-22T09:36:00.866119Z

basically uses a multi method for the variety of messages it may receive and in the comment block below I can trigger some sends via the REPL

thheller 2025-09-22T09:36:38.007469Z

basically if you look at the web UI REPL I started building http://localhost:9630/repl

thheller 2025-09-22T09:37:03.693939Z

everything it does happens over the shadow.remote websocket and thus is available to you either directly via ws or over nrepl

thheller 2025-09-22T09:38:59.643509Z

I re-opened https://github.com/thheller/shadow-cljs/issues/990. if you don't mind lets continue the discussion there please

👍 1
pez 2025-09-22T11:05:49.810399Z

I continued the nrepl discussion at the issue. As for websockets, I will take a look and have a think and get back about it. It should enable more cool shadow-cljs support in Calva, even if for this notification thing, nrepl suffices pretty well.