Fork me on GitHub
#hyperfiddle
<
2024-01-26
>
wei06:01:08

seeing some unexpected behavior, am I missing something obvious??

(ns app.test
  (:require [hyperfiddle.electric :as e]
            [hyperfiddle.electric-dom2 :as dom :refer [div text]]))

#?(:clj (def !a (atom "a")))
(e/def a (e/server (e/watch !a)))

#?(:clj (def !b (atom "b")))
(e/def b (e/server (e/watch !b)))

#?(:clj (def !c (atom "c")))
(e/def c (e/server (e/watch !c)))

(e/defn Test []
  (e/client
   (div
    (div (text "a: " (pr-str a)))
    (div (text "b: " (pr-str b)))
    (div (text "c: " (pr-str c))))
   (println a)
   (println b)
   (println c)))
this is on latest master (`b32ac9`)

👀 2
wei06:01:05

well this works as expected in electric-fiddle so it must be something screwy in my app. any tips on locating the issue?

wei07:01:56

on my original project, I tried pasting in the Toggle demo code (https://electric-examples-app.fly.dev/(electric-tutorial.demo-toggle!%54oggle)/) and got this error:

22:57:17.316 ERROR [qtp362743760-80] hyperfiddle.electric - #error {
 :cause check failed: (some? (get (aget frame frame-slot-dynamic) symb)) for nil
 :data {:hyperfiddle.electric.debug/trace [{: :, :hyperfiddle.electric.debug/type :eval, :hyperfiddle.electric.debug/fn {}, :hyperfiddle.electric.debug/args [/test2 <exception>], :hyperfiddle.electric.debug/origin #uuid "af9a7076-d898-4b7f-9acb-4aa19cbada54", :hyperfiddle.electric.debug/serializable true} {: :, :hyperfiddle.electric.debug/type :eval, :hyperfiddle.electric.debug/fn {}, :hyperfiddle.electric.debug/args [#object[HTMLBodyElement [object HTMLBodyElement]] <exception>], :hyperfiddle.electric.debug/origin #uuid "af9a7076-d898-4b7f-9acb-4aa19cbada54", :hyperfiddle.electric.debug/serializable true} {: :, :hyperfiddle.electric.debug/origin #uuid "af9a7076-d898-4b7f-9acb-4aa19cbada54", :hyperfiddle.electric.debug/args [], :hyperfiddle.electric.debug/serializable true}], :hyperfiddle.electric/type :hyperfiddle.electric.debug/trace}
 :via
 [{:type hyperfiddle.electric.FailureInfo
   :message check failed: (some? (get (aget frame frame-slot-dynamic) symb)) for nil
   :data {:hyperfiddle.electric.debug/trace [{: :, :hyperfiddle.electric.debug/type :eval, :hyperfiddle.electric.debug/fn {}, :hyperfiddle.electric.debug/args [/test2 <exception>], :hyperfiddle.electric.debug/origin #uuid "af9a7076-d898-4b7f-9acb-4aa19cbada54", :hyperfiddle.electric.debug/serializable true} {: :, :hyperfiddle.electric.debug/type :eval, :hyperfiddle.electric.debug/fn {}, :hyperfiddle.electric.debug/args [#object[HTMLBodyElement [object HTMLBodyElement]] <exception>], :hyperfiddle.electric.debug/origin #uuid "af9a7076-d898-4b7f-9acb-4aa19cbada54", :hyperfiddle.electric.debug/serializable true} {: :, :hyperfiddle.electric.debug/origin #uuid "af9a7076-d898-4b7f-9acb-4aa19cbada54", :hyperfiddle.electric.debug/args [], :hyperfiddle.electric.debug/serializable true}], :hyperfiddle.electric/type :hyperfiddle.electric.debug/trace}}]
 :trace
 []}
in case default branch
in (case 0 ...)
in reactive (defn Main nil ...) line 19
in (try ...)
client logged an exception, too 

wei07:01:58

think I found a minimal repro. seems you can't import watches

(ns app.teststate
  (:require [hyperfiddle.electric :as e]))

#?(:clj (def !a (atom "a")))
(e/def a (e/server (e/watch !a)))

;---

(ns app.test
  (:require [hyperfiddle.electric :as e]
            [hyperfiddle.electric-dom2 :as dom :refer [div text]]
            #?(:cljs [app.teststate :refer [a]])))

(e/defn Test [] (e/client (div (text "a: " (pr-str a)))))

xificurC07:01:24

thanks for the report and minimized repro! The last snippet, you tried it in electric-fiddle?

xificurC08:01:08

I did not reproduce locally. Comparing the code you posted to what I typed, the #?(:cljs conditional on the require is likely the culprit. If a is an electric def the server needs to know that too

xificurC08:01:24

although adding that locally didn't repro either. Might be a stale tab too

wei09:01:29

i see, makes sense that both client and server need to know about the e/def. thanks for following up. as written (with the conditional) it seems to mess up EVERYTHING even outside of that ns. easy for a newbie like me to get confused

👀 1
wei09:01:15

confirmed that it works without the conditional

👍 1
Dustin Getz15:01:40

To summarize, we've learned that #?(:cljs ...) around a namespace that contains electric expressions that have server contents, causes a client/server mismatch under IC. Furthermore, the mismatch is not detected, is allowed to run and we see spooky undefined behavior due to the programs being out of sync. Correct?

wei15:01:40

Yes, great summary!

telekid13:01:52

Thanks for the awesome talk at Clojure NYC yesterday! I learned a ton. Great to hear about the motivation behind differential.

🙂 1
😮 1
👀 1
avocade14:01:50

Video or it didn't happen.

😆 4
xificurC15:01:39

the latter then

1
laughcry 2
avocade12:01:46

I have a feeling a video'll turn up eventually. Looking forward to it :star-struck: