Fork me on GitHub
#hyperfiddle
<
2024-01-15
>
Vincent02:01:30

Electric is the juice

🧃 1
Ken CC08:01:18

Hi, I'm trying to have two variables (x, y) but 1. Only x will display. 2. Toggle button for y changes x???

#?(:clj (defonce !x (atom true))) ; server state
(e/def x (e/server (e/watch !x))) ; reactive signal derived from atom

#?(:clj (defonce !y (atom false)))
(e/def y (e/server (e/watch !y)))


(e/defn Hello2 []
    (e/client
      (dom/div (dom/text "X: " x))
      (ui/button (e/fn []
                   (e/server (swap! !x not)))
        (dom/text "toggle client/server x"))

      (dom/div (dom/text "Y: " y))
      (ui/button (e/fn []
                   (e/server (swap! !y not)))
        (dom/text "toggle client/server y"))))

Vincent09:01:10

very close, (ui/button (e/fn []) (dom/props) (dom/text)) your ui/button is closed after e/fn [] and does not include the dom/text in the actual button

(ui/button
  (e/fn []
    (e/server (swap! !y not))
  (dom/text "toggle y"))

Vincent09:01:22

2 parens after not, not 3

Ken CC09:01:29

dom/text is inside of ui/button in my original post no?

Vincent09:01:47

Oh it is lol))

Vincent09:01:00

"the toggle button for y changing x" makes me think there is a paren missing or an invalid def somewhere else, but idk

Ken CC09:01:54

it doesn't even show Y's value on screenshot. (It shows for X)

Vincent09:01:05

did you restart your server since adding the #?(:clj (defonce !y ..))

Vincent09:01:19

seems like it should work, based on the code you provided.

Ken CC09:01:09

I just restarted, and it's still same. I been stuck trying to get this to work for past 3 days, restarted multiple times, created variations to figure it out.

Ken CC09:01:29

I'm running on WSL2. let me try running on Linux just incase

henrik09:01:30

If you flip the order: put the Y stuff before the X stuff, does Y still not display?

henrik10:01:15

If you change (dom/div (dom/text "Y: " y)) to (dom/div (dom/text "Y: " x)), does it display the value for x?

Ken CC10:01:09

yes, that will show x. Also it fixed button to toggle y. doesn't change x (correct behaviour)

henrik10:01:15

What if you (dom/div (dom/text "Y: " (str y)))

henrik10:01:37

I’m not sure how dom/text coerces to strings (if at all).

Ken CC10:01:25

tried (str y), (pr-str y), no difference. y doesn't show up. Also toggle button for y will change value for x again.

Ken CC10:01:37

Tried running on linux (manajaro) and no difference. X shows, Y doesn't show.

Daniel Galvin11:01:46

can make it work by wrapping

(dom/text "Y: " (e/server y))
but im not sure why it works yet 😕

🙌 1
henrik11:01:37

Oh… No, that makes sense actually.

Daniel Galvin11:01:22

it confuses me because x seems to work without such wrapping. but to me it all appears identical

henrik11:01:38

You’re in a client block, hence you’re going to get the value of x/y in the client scope (which is nothing) by default, unless wrapped with e/server. What doesn’t make sense is why x is showing up without being wrapped.

Ken CC11:01:00

wrapping in (`e/server y)` fixed it!!!

Ken CC11:01:18

although unclear why x works as it is, and why Y button triggers X. (fixed once (e/server y) wrap is there)

Vincent12:01:29

It might make more sense if you consider the defonce

(defonce !x #?(:cljs (atom false)) #?(:clj (atom false)))
in principle we ought define a clientside something and serverside something this way. if there is only one, you will have to specify which you are reading. might be a way to think about it/ reason about it

henrik12:01:07

This is all true, but it doesn’t quite explain why the server-side value was available from x. Could be a bug/glitch I suppose.

Dustin Getz14:01:55

Hi, please can you restate the problem crisply now that the workaround is understood? Possibly this is a new regression in the IC release

Daniel Galvin15:01:30

Issue: Y value not rendering yet X value is

#?(:clj (defonce !x (atom true))) ; server state
(e/def x (e/server (e/watch !x))) ; reactive signal derived from atom

#?(:clj (defonce !y (atom false)))
(e/def y (e/server (e/watch !y)))


(e/defn Hello2 []
    (e/client
      (dom/div (dom/text "X: " x))
      (ui/button (e/fn []
                   (e/server (swap! !x not)))
        (dom/text "toggle client/server x"))

      (dom/div (dom/text "Y: " y))
      (ui/button (e/fn []
                   (e/server (swap! !y not)))
        (dom/text "toggle client/server y"))))
In the code snippet you see there are 2 atoms defined
#?(:clj (defonce !x (atom false)))
#?(:clj (defonce !y (atom false)))
these have watch set up on them via e/server like so
(e/def x (e/server (e/watch !x)))
(e/def y (e/server (e/watch !y)))
in the Hello2 fn, we are defining some divs with some text and a couple ui buttons this is all wrapped in (e/client) when ran, the div are rendered. but there is no value given to the second div for 'y' however the first div does succesfully render 'x' By wrapping 'y' in (e/server ..) we can get it to work correctly. The confusion is why 'x' was working without the need to be wrapped in (e/server ..)

Dustin Getz15:01:32

Can you make it complete/self-contained please so I can put this in an issue tracker and pass it on

Daniel Galvin15:01:28

have updated above to contain the full snippet aswell as a breakdown of steps as to why its weird, along with the fix done

Dustin Getz15:01:52

thanks, is it minimized?

Daniel Galvin15:01:15

not sure, its pretty concise apologies if not that useful i was not original raiser. just had a look at resolving it to help.

Dustin Getz15:01:12

ok, i see, we agree that y should be wrapped in e/server because the e/def exists on both sites (this is a known gotcha in Electric v2), the question is then why is x different? [this is incoherent sorry] This looks like a regression to me, I also think x access needs to be wrapped in Electric v2

👍 1
1
Dustin Getz15:01:03

I expect accessing x from the client would result in an exception like "cannot watch nil", in fact it might be a compile time exception because var !x is unresolvable on the client so (e/watch !x) (or the macroexpansion of it) doesn't even pass the clojurescript analyser iiuc this is incoherent sorry

1
Vincent15:01:12

I am wondering if defining the y atom to true would make y also glitchy like that

Ken CC15:01:25

I basically copied "2. Toggle" example in fiddle, and tried to modify slightly (add another variable). if it is case x should be wrapped, fiddle example also should be changed?

Dustin Getz15:01:30

please link to the thing you changed?

Ken CC15:01:35

yep, sec doing it

Ken CC15:01:21

2 problems. a. y will not show. b. pressing button to change y's state will change x.

#?(:clj (defonce !x (atom true))) ; server state
(e/def x (e/server (e/watch !x))) ; reactive signal derived from atom

#?(:clj (defonce !y (atom false)))
(e/def y (e/server (e/watch !y)))

(e/defn Hello2 []
  (e/client
    (dom/div (dom/text "X: " x))
    (ui/button (e/fn []
                 (e/server (swap! !x not)))
      (dom/text "toggle client/server x"))

    (dom/div (dom/text "Y: " y))
    (ui/button (e/fn []
                 (e/server (swap! !y not)))
      (dom/text "toggle client/server y"))))

Ken CC15:01:48

#?(:clj (defonce !x (atom true))) ; server state
(e/def x (e/server (e/watch !x))) ; reactive signal derived from atom

#?(:clj (defonce !y (atom false)))
(e/def y (e/server (e/watch !y)))


(e/defn Hello2 []
    (e/client
      (dom/div (dom/text "X: " x))
      (ui/button (e/fn []
                   (e/server (swap! !x not)))
        (dom/text "toggle client/server x"))

      (dom/div (dom/text "Y: " (e/server y)))  ; <=== wrap y with (e/server)
      (ui/button (e/fn []
                   (e/server (swap! !y not)))
        (dom/text "toggle client/server y")) 
      ))

Dustin Getz15:01:19

you mentioned an existing electric-fiddle example

Dustin Getz15:01:17

Oh geez I may be entirely mistaken in my diagnosis, I need to get this checked by the team at this point

Ken CC15:01:12

I'm slightly off in what I said about example earlier. Example itself never tried to display x itself. However there are usages where it's not wrapped. I was trying to play around with https://electric.hyperfiddle.net/user.demo-toggle!Toggle I attempted to create second variable. In example x doesn't get wrapped when used in (if ) or (when )

Dustin Getz16:01:42

I spoke with @U09FL65DK. Yes we confirm that we can reproduce the issue and we currently believe it's a new regression related to the incremental compilation changeset. As to the semantics of whether or not you should need an e/server to access a global defined like (e/def x (e/server ...)) – the TLDR is it doesn't actually matter, once the former issue is fixed it will "work" both ways. The long term answer is that in Electric v3 (in development) e/def semantics have been reworked and issues like this are gone.

👍 4
Dustin Getz16:01:08

(To be clear, my answers earlier were confused and I have edited them to retract them)

Vincent13:01:21

Hi, is there support for (dom/audio (dom/source ...)) yet?

Vincent13:01:29

nvm it's there it's simpler than the corresponding html 🙂

(dom/audio (dom/props {:controls true :src file-location :type "audio/mpeg"}))

Geoffrey Gaillard13:01:03

(dom/audio (dom/element "source" …)) should work

Tommy Jolly15:01:21

If you didn't know, most dom/foo elements are just convenience macros wrapping dom/element "foo", so that's always there as a fallback

👍 1
Vincent15:01:43

that's super helpful ty

chromalchemy14:01:24

I’m trying to demo electric fiddle. I cloned the repo. When I try to run

git submodule update --init --recursive
` inside i get error..

chromalchemy14:01:42

git submodule update --init --recursive
Submodule 'vendor/electric' ([email protected]:hyperfiddle/electric.git) registered for path 'vendor/electric'
Submodule 'vendor/hfql' ([email protected]:hyperfiddle/hfql.git) registered for path 'vendor/hfql'
Submodule 'vendor/rcf' ([email protected]:hyperfiddle/rcf.git) registered for path 'vendor/rcf'
Cloning into '/Users/ryan/dev/electric-fiddle/vendor/electric'...
: Permission denied (publickey).
fatal: Could not read from remote repository.

Please make sure you have the correct access rights
and the repository exists.
fatal: clone of '[email protected]:hyperfiddle/electric.git' into submodule path '/Users/ryan/dev/electric-fiddle/vendor/electric' failed
Failed to clone 'vendor/electric'. Retry scheduled
Cloning into '/Users/ryan/dev/electric-fiddle/vendor/hfql'...
: Permission denied (publickey).
fatal: Could not read from remote repository.

Please make sure you have the correct access rights
and the repository exists.
fatal: clone of '[email protected]:hyperfiddle/hfql.git' into submodule path '/Users/ryan/dev/electric-fiddle/vendor/hfql' failed
Failed to clone 'vendor/hfql'. Retry scheduled
Cloning into '/Users/ryan/dev/electric-fiddle/vendor/rcf'...
: Permission denied (publickey).
fatal: Could not read from remote repository.

Please make sure you have the correct access rights
and the repository exists.
fatal: clone of '[email protected]:hyperfiddle/rcf.git' into submodule path '/Users/ryan/dev/electric-fiddle/vendor/rcf' failed
Failed to clone 'vendor/rcf'. Retry scheduled
Cloning into '/Users/ryan/dev/electric-fiddle/vendor/electric'...
: Permission denied (publickey).
fatal: Could not read from remote repository.

Please make sure you have the correct access rights
and the repository exists.
fatal: clone of '[email protected]:hyperfiddle/electric.git' into submodule path '/Users/ryan/dev/electric-fiddle/vendor/electric' failed
Failed to clone 'vendor/electric' a second time, aborting

Geoffrey Gaillard14:01:16

Do you get an error running git clone [email protected]:hyperfiddle/electric.git ?

Tommy Jolly15:01:43

(I think I got a similar error until I added an SSH key to github)

Geoffrey Gaillard15:01:22

This is my intuition too.

james15:01:40

I swapped to https: instead of git: to work around it

$ cat .gitmodules 
[submodule "vendor/hfql"]
	path = vendor/hfql
	url = 
[submodule "vendor/electric"]
	path = vendor/electric
	url = 
[submodule "vendor/rcf"]
	path = vendor/rcf
	url = 

👀 1
james16:01:21

corp firewall block or some such

Geoffrey Gaillard16:01:14

Good to know, thank you. We'll look into it

Dustin Getz17:01:27

@U09D96P9B did you clone the https link?

Dustin Getz17:01:31

you can use ssh to test your credentials

Dustin Getz17:01:02

$ ssh 
PTY allocation request failed on channel 0
Hi dustingetz! You've successfully authenticated, but GitHub does not provide shell access.
Connection to  closed.

chromalchemy14:01:07

I finally added an ssh key to GitHub and then the command indeed worked:raised_hands::skin-tone-2:

Vincent23:01:55

tangential to electric: want to add resource-response (audio files) to the starter app... middleware melting my brains )

Dustin Getz23:01:04

start with electric-fiddle, the middleware situation was just streamlined

Dustin Getz23:01:38

not sure if it will help

Vincent00:01:49

cool. middleware always melts my brain it's nothing new

Vincent00:01:35

will check the fresh fiddle now

Vincent00:01:16

you mean this beauty? electric fiddle

🙂 2
Vincent02:01:13

presumably this one? https://github.com/hyperfiddle/electric-fiddle/blob/main/src/electric_fiddle/server_jetty.clj I need ring because I need range queries for audio scrubbing (httpkit no has range query support yet)

Vincent04:01:17

file uploads work out of the box as long as you don't put spaces in file names face palm