Currently, using a JS tagged literal i.e. #js [] inside of a hook will bust the react-refresh cache every time.
This is due to the fact that #js [] emits a value created via deftype, and then helix coverts this at compile time to a string to use as the cache key. The stringified object contains a memory reference, which is different every time.
Copying @SevereOverfl0w 's slack investigation here for posterity:
dominicm 1:09 PM
Ah, string/join runs in clojure-lang. Derp! Right, I bet it's getting something that looks very different then!
dominicm 1:10 PM
"hooks-key" "(hooks/use-state (do #object[cljs.tagged_literals.JSValue 0x73ca9fc4 \"cljs.tagged_literals.JSValue@73ca9fc4\"] \"Lisa\"))" That's why! It's printing out the object using the JSValue, which is an object so has a memory reference associated @Alex J Henderson @lilactown here's the bug :smile:
dominicm 1:21 PM
(string/join (map cljs.compiler/emit-constant hooks)) does the trick. But it's pretty verbose. Based on a cursory look around the source, you might only need to solve for regex/JSValue (based on the fact those are both things that broke Cljs' own caching in the past, and are still the only 2 custom ones: https://github.com/clojure/clojurescript/blob/9d3dfc369a01b31244eb925fef4c9fafa3824e24/src/main/clojure/cljs/analyzer.cljc#L94-L103).
As far as I can tell, JSValue is the only deftype in a cljc file in ClojureScript, so special casing JSValue probably makes sense.
Currently, using a JS tagged literal i.e.
#js []
inside of a hook will bust the react-refresh cache every time.This is due to the fact that
#js []
emits a value created viadeftype
, and then helix coverts this at compile time to a string to use as the cache key. The stringified object contains a memory reference, which is different every time.Copying @SevereOverfl0w 's slack investigation here for posterity:
dominicm 1:09 PM Ah, string/join runs in clojure-lang. Derp! Right, I bet it's getting something that looks very different then!
dominicm 1:10 PM
"hooks-key" "(hooks/use-state (do #object[cljs.tagged_literals.JSValue 0x73ca9fc4 \"cljs.tagged_literals.JSValue@73ca9fc4\"] \"Lisa\"))"
That's why! It's printing out the object using the JSValue, which is an object so has a memory reference associated @Alex J Henderson @lilactown here's the bug :smile:dominicm 1:21 PM
(string/join (map cljs.compiler/emit-constant hooks))
does the trick. But it's pretty verbose. Based on a cursory look around the source, you might only need to solve for regex/JSValue (based on the fact those are both things that broke Cljs' own caching in the past, and are still the only 2 custom ones: https://github.com/clojure/clojurescript/blob/9d3dfc369a01b31244eb925fef4c9fafa3824e24/src/main/clojure/cljs/analyzer.cljc#L94-L103). As far as I can tell, JSValue is the only deftype in a cljc file in ClojureScript, so special casing JSValue probably makes sense.Also works if you just special case JSValue types. (edited)