shadow-cljs

tony.kay 2025-03-25T15:17:34.114379Z

Is anyone else having problems with hot code reload in react native using the latest expo go? Things were working well for me, and I upgraded to the latest expo go, and now I get no REPL or hot reload on my react native app. It says there was an internal change to fiber and looking around I see that this can affect websocket stuff. I get zero messages in logs from shadow-cljs about connecting (ios simulator)…I went to the js debugger for react native, and was able to do (from the js console) a low-level fetch of localhost:9630 to get a status 200, so I don’t think it is a firewall/permissions/macos blockage. I am using a large and complicated app, though, so there is some chance that is a local issue and not one with shadow, but I’m curious if anyone has the latest expo go working with cljs and hot reload from shadow?

thheller 2025-03-25T16:40:18.939729Z

is this with the 2.28.22 upgrade I made earlier today or before?

tony.kay 2025-03-25T17:09:19.344349Z

I was using 2.28.21

tony.kay 2025-03-25T17:09:41.064969Z

is there a change to 22 that might matter? I looked at the commit log and it didn’t ring bells

tony.kay 2025-03-25T17:11:12.685439Z

I’ll try the latest, sorry for not trying that aleady…the commit log didn’t look immediately obvious for changes that would matter

thheller 2025-03-25T17:11:14.083639Z

yeah I changed quite a bit of REPL code, so that could totally blow things up 😛

thheller 2025-03-25T17:11:32.712429Z

nah just wanted to check if I screwed something up with that upgrade

thheller 2025-03-25T17:11:41.679189Z

but if you don't use that I can rule that out as a cause for your problem

tony.kay 2025-03-25T17:12:11.753459Z

I think I tried bouncing back to 2.20.20, FYI…I think it didn’t help. I was trying to rule out shadow breaking

thheller 2025-03-25T17:13:24.817389Z

the connect logic for react-native in theory hasn't changed in many years, at least not intentionally

tony.kay 2025-03-25T17:13:32.681509Z

(problem is I tried so many things, and I didn’t keep great notes)

thheller 2025-03-25T17:13:40.270239Z

should at least get some kind of log if the connect fails or times out

tony.kay 2025-03-25T17:14:07.929129Z

yeah, that was what was weird…and I couldn’t figure out if maybe they had borked the logging…my log messages are coming out though

tony.kay 2025-03-25T17:16:14.544089Z

but my project is complex….which is why I asked if anyone else has it working. there is a non-zero chance it is something in what I have…but for the life of me I don’t see how shadow can compile, and I get a loaded app, but no shadow messages in logs

tony.kay 2025-03-25T17:16:19.259649Z

:native          {:target           :react-native
                              :init-fn          mobile.client-native/init
                              :output-dir       "mobile/native-apps/app"
                              :compiler-options {:output-feature-set :es5
es5 and react native target.

thheller 2025-03-25T17:17:59.935359Z

you can try setting a fixed :devtools-url https://shadow-cljs.github.io/docs/UsersGuide.html#proxy-support

tony.kay 2025-03-25T17:18:08.465909Z

I did

tony.kay 2025-03-25T17:18:13.747419Z

also tried top-level local-ip

thheller 2025-03-25T17:18:16.448019Z

otherwise it'll try npx shadow-cljs clj-repl (shadow/get-server-addrs) to connect

thheller 2025-03-25T17:18:55.601439Z

if the correct ip is in there the connect logic should find it

tony.kay 2025-03-25T17:19:06.311429Z

which is why I then dumped into the js console and tried a fetch from within the app to see that localhost:9630 was reachable

tony.kay 2025-03-25T17:19:26.780359Z

cause I was trying to eliminate the latest line of macos security nightmares

thheller 2025-03-25T17:21:15.384929Z

unless you explicitely set :devtools {:enabled false} there should be at least some kind of log telling you what failed

💯 1
thheller 2025-03-25T17:21:55.899949Z

did you check http://localhost:9630/runtimes if any runtime shows up if you load the app? maybe it connects just fine but fails elsewhere

tony.kay 2025-03-25T17:22:22.427979Z

I only see the CLJ runtime of shadow

tony.kay 2025-03-25T17:23:24.986469Z

I’ll try again later. I wasted most of a Sunday on it already and had given up…I was hoping I would at least hear from someone here “Yes, I’m using the latest expo go and it works perfectly”

thheller 2025-03-25T17:23:26.276519Z

any kind of exception during load maybe?

tony.kay 2025-03-25T17:23:42.731849Z

nothing…it was strangely silent. maddening actually

tony.kay 2025-03-25T17:24:03.765029Z

just log messages from my app saying it was starting, etc.

tony.kay 2025-03-25T17:24:21.237029Z

it was as if the shadow repl connection code just wasn’t even being tried

tony.kay 2025-03-25T17:25:19.719829Z

so I thought some exception might be swallowed…but if so it is silent. I looking in the macos console for the low-level messages and I see some TCP fails, but they were rather vague and could have been associated with my app trying othger things

thheller 2025-03-25T17:25:45.336499Z

did you try wiping the cache and old output files? maybe the expo build parts are some on something old?

tony.kay 2025-03-25T17:26:01.490699Z

yeah, when I downgraded to 2.20.20

tony.kay 2025-03-25T17:26:29.958819Z

wiped .shadow-cljs and everything. Like I said, what I’ll do is try again with some kind of blank slate project and see what I see.

tony.kay 2025-03-25T17:26:50.783819Z

maybe just try your demo app

thheller 2025-03-25T17:27:01.833139Z

hmm yeah I haven't been anywhere near a react-native project in many years, so no clue whats going on in that area

thheller 2025-03-25T17:27:18.209709Z

don't even know what expo go is 😛

tony.kay 2025-03-25T17:27:54.128849Z

they did some kind of internal refactor to use a “bridgeless” internals, which I find suspect. Expo Go is a pre-build native app that can run react native and has built-in features

tony.kay 2025-03-25T17:28:14.002849Z

it’s the “standard” way to sstart react native these days

thheller 2025-03-25T17:35:20.538949Z

you can try copying this file into your classpath and just adding some logging https://github.com/thheller/shadow-cljs/blob/d12811cfb7884d86dcecb3a16cf61c9e89bb8b05/src/main/shadow/cljs/devtools/client/react_native.cljs#L98

thheller 2025-03-25T17:35:33.728049Z

if needs to get past this when to start the connect process

thheller 2025-03-25T17:36:13.219719Z

maybe that can provide a clue somewhere if its even loaded/trying to connect

tony.kay 2025-03-25T17:51:06.719459Z

great, thanks

tony.kay 2025-03-25T20:05:31.157869Z

I get these warnings, and the first one at least is true…sounds bad

tony.kay 2025-03-25T20:06:00.826979Z

second one as well

tony.kay 2025-03-25T20:06:17.487469Z

looks like protocols changed?

thheller 2025-03-25T20:07:55.128239Z

yeah thats the part I changed in 2.28.22

tony.kay 2025-03-25T20:09:16.279899Z

oh, did I get the wrong version?

thheller 2025-03-25T20:10:03.272109Z

I linked you the latest version, use the one from 2.28.21 instead. not much changed in the implementation aspect. nothing that should affect this issue at least

tony.kay 2025-03-25T20:10:15.984399Z

sorry, I set the deps wrong

tony.kay 2025-03-25T20:10:18.560399Z

I thought I was on latest

tony.kay 2025-03-25T20:18:57.492739Z

I can confirm it loads the shadow react-native ns. It looks like it all runs, and the when gets true, and it calls the setTmeout, but the function in the setTimeout never runs…

tony.kay 2025-03-25T20:20:40.534729Z

confirmed…if I change the setTimeout to a do everything starts working 🧩

tony.kay 2025-03-25T20:20:55.060449Z

why the heck would setTimeout not work?

🤷 1
tony.kay 2025-03-25T20:21:50.625689Z

WTF…I can do setTimeout from the debug window and it’s fine

tony.kay 2025-03-25T20:22:13.411439Z

this is bizzarre

tony.kay 2025-03-25T20:22:46.106929Z

ok, did I do something stupid somewhere and break setTimeout somehow…

tony.kay 2025-03-25T20:23:02.404059Z

(thanks for this tip, BTW, makes it trivial to debug my issue)

thheller 2025-03-25T20:23:02.415799Z

hehe

tony.kay 2025-03-25T20:23:23.628019Z

I didn’t realize it was this easy to muck with your injected code

thheller 2025-03-25T20:23:57.365379Z

you can mess around with pretty much everything in shadow-cljs this way. any ns will do 😛 CLJ included

tony.kay 2025-03-25T20:25:37.050369Z

yeah, I knew that about clojure in general, I just meant I didn’t realize your injected code wasn’t generated in some complex way

thheller 2025-03-25T20:26:00.665109Z

hehe yeah its all very basic

thheller 2025-03-25T20:26:15.988199Z

basically just adds an entry to :preloads

👍 1
tony.kay 2025-03-25T20:26:47.680329Z

so

(js/console.log js/setTimeout)
says setTimeout is a Function….

tony.kay 2025-03-25T20:27:12.244959Z

so it MUST be someething about the Expo system startup

thheller 2025-03-25T20:28:47.662269Z

you can in theory remove that setTimeout, it is just there for error cases anyway

thheller 2025-03-25T20:29:04.733099Z

or maybe increase the timeout?

thheller 2025-03-25T20:29:25.677959Z

if you have a big app maybe it is just busy and something in expo decides to not fire it because too old?

tony.kay 2025-03-25T20:30:35.300419Z

I tried increasing the time…no help. Turning it into a do seems fine, though

thheller 2025-03-25T20:30:51.948179Z

there is another setTimeout use in the connect loop

thheller 2025-03-25T20:31:22.768319Z

but yeah seems like an expo issue if setTimeout doesn't work

tony.kay 2025-03-25T20:31:43.332929Z

I’m using core async…I wonder if something in core async is messing with it

tony.kay 2025-03-25T20:32:00.042899Z

I know they have to hook into that to do async/timeout

thheller 2025-03-25T20:32:20.084329Z

but it doesn't modify setTimeout

tony.kay 2025-03-25T20:32:55.237459Z

nope…removed async stuff still no timeout

tony.kay 2025-03-25T20:34:43.183269Z

hm…actually, now that I removed some of my code it DID start doing setTmeout…I think this HAS to be my fault in here somewhere…at least I know how it is broken. Thanks so much for the help!

👍 1
tony.kay 2025-03-25T20:44:14.755049Z

yeah, if I start my core async loop on load, then it breaks the setTimeout from your preload. If I delay my core async loop (which immediately has a async/timeout) to happen later, then your setTimeout is ok

thheller 2025-03-25T20:45:06.842729Z

strange. maybe expo has a limit on how many setTimeout can be pending?

tony.kay 2025-03-25T20:45:15.899679Z

yeah, gotta be an expo-ism

Yaw Odame 2025-03-26T20:38:02.890479Z

What version of expo are you running?

Yaw Odame 2025-03-26T20:41:18.283449Z

I have get hot code and js repl working just fine. I am running "expo": "^52.0.41" with latest shadow-cljs 2.28.22 and fulcro 3.8.3

tony.kay 2025-03-26T23:33:20.746419Z

It's the latest. Works fine unless I start State charts too early

Yaw Odame 2025-03-27T00:13:25.468719Z

Oh yea I noticed that as well working with statecharts. I didn’t factor in that variable. When did you end up starting the statecharts?

tony.kay 2025-03-27T03:49:58.920319Z

I put it in a deferred call like 500ms later

tony.kay 2025-03-27T03:50:45.341269Z

no idea why it is borked…I vaguely remember having to do some kind of patch for sente where at one point I was trying to fix setTimeout, I’ll have to look through the libs and make sure I didn’t so something stupid

thheller 2025-03-27T08:01:42.003159Z

searching for setTimeout and react-native has quite a few hits, so seems like a rather longstanding unfixed issue. guess its hard to reproduce and figure out what exactly the problem is 😛