I have a task which prints “Hello world!” (def hello-world-task (m/sp (println "Hello world!"))) . When I call this task with (e/Task hello-world-task) it works correctly on both the client and the server. If however I inline the definition of hello-world-task in e/Task like so: (e/Task (m/sp (println "Hello world!"))) it fails to compile.
I cannot repro locally. But there's a long standing design issue wrt inlining m/sp, m/ap, m/cp in electric and would strongly advise to extract them into clj(s) definitions for now. The underlying reason is missionary generates cloroutine code using object arrays. These are always pointer equal, resulting in electric work skipping subsequent calls
Thank you
In the webview2 tutorial
https://electric.hyperfiddle.net/tutorial/webview2
I understand that online 26 we need to use e/call because the return value of (get m k) is an Electric thunk. But why don't we need to use e/call on line 19 when we call (Query), when Query is also an Electric thunk?
v3 adopts a new shorthand calling convention. In v2 we used (Query.) for the shorthand, or (new Query). In v3 if the symbol starts with an uppercase char we interpret that as an electric call.
;; v2
(Query.)
(new Query)
;; v3
(Query)
(e/call Query)as you pointed out this shorthand is not possible with dynamic lookups like (get m k), so there one has to fall back to e/call
Ah, that makes sense, thanks!
I have a task factory: (defn print-task [s] (m/sp (println s)))
which is used by some Electric code:
(let [test {:foo :bar}]
;; This prints:
(e/Task (print-task test))
;; This does not print:
(e/server (e/Task (print-task test))))
How come the server-side task invocation does not print anything? There’s no errors.it should. What is the surrounding context?
(when-some [event (dom/On "keydown" identity nil)]
(when-some [[t _err] (e/Token event)]
(when t
(when (= (.-key event) "Enter")
(let [test {:foo :bar}]
;; This prints:
(e/Task (print-task test))
;; This does not print:
(e/server (e/Task (print-task test)))))
(t))))
calling (t) will turn the token nil and unmount the when branch before the server finishes it, cancelling it. Does that explanation make sense?
you have 2 effects, (t) and (print-task test), and you need to sequence them. Electric is concurrent, so the 2 are currently racing
since one of them is on the server, due to latency it loses the race and gets unmounted
the simplest way to sequence is to use case
(case (e/server (e/Task (print-task test)))
(t))this (ab?)uses the conditional, it will only run the default branch when the test value transfers
I see. I’ve usually tried to sequence things with (apply last <code>)
Although that causes unintended transfers I think. So I’ll try the case-approach. Then I would need to consume the token in each branch right?
that is valid too, I often write the equivalent of ((fn [_] (t)) (e/server (print-task test)))
> Then I would need to consume the token in each branch right? I don't see branches in your sample, but sure. Depending on the structure you might be able to lift the case out, around the branches
I often write the equivalent@xifi give me an example please. I have the following code and I want each action to be executed synchronously step by step. Now I see that (conn/init-conn) (connection to db) is ignored
(e/defn Main [ring-request]
(e/client
(binding [dom/node js/document.body
e/http-request (e/server ring-request)]
#?(:cljs (glogi-console/install!))
(routes/init!)
#?(:cljs auth/listen-auth-state)
(e/server #?(:clj (conn/init-conn)))
(sh/Shell))))reader conditionals in electric code will break. The electric compiler needs to see the whole definition on both peers in order to correctly orchestrate. I don't see why all steps need sequencing here, but if they really do I guess I'd write it as below
Thank you!:)
Good morning. Learning the simple stuff. How do I attach an onclick handler to a button that will print a message to the browser console? And then how would I extend that to manipulate the DOM? No reactive stuff, just DOM actions.
recommend going through the tutorials one at a time and replicating them on your machine
https://electric.hyperfiddle.net/tutorial/token_explainer has a button
https://electric.hyperfiddle.net/tutorial/webview_column_picker has checkboxes
Wild. I thought I'd tried the simplest possible way to do this and it didn't work. But now it does. I thought I must have missed something in the tutorial.
Ah. It seems there's some real jankiness with shadow-cljs. I got it working, but then it stopped working with the exact same code. And I get "stale output" warning.
you may need to hard refresh. the shadow "stale output" warning can be trusted. Chrome disrespecting cache headers has historically been an issue (idk if still is) and also having dev tools open gives you more options when you right click on the refresh button, as if to say "I'm a developer and I really mean it"
Using Brave. And things are totally horked. Going to have to come back to this later.
In webview2 tutorial
https://electric.hyperfiddle.net/tutorial/webview2
why does the code use e/Partial on line 54?
(e/Partial Teeshirt-orders db search (e/client (e/watch !sort-key)))
It seems like we supplied all the arguments so we don't need partial? Is it just a shorthand way of writing the following?
(e/fn [] (Teeshirt-orders db search (e/client (e/watch !sort-key))))yes
Also in webview2 tutorial, on line 29, what does the ! signify in the naming of the variable !e? I'm used to seeing that naming convention for atoms but I think in this case !e is just a map?
it's a datomic entity object. Calling (:foo !e) can invoke IO, i.e. the object is "impure" and doesn't serialize
Got it, thanks!
we generally use !e bang prefix to mean "reference" because in electric it's extra important to keep track of things that can't or shouldn't cross wire
Is there a way for the compiler to know when things are crossing the wire and mark them accordingly? Like with a little zigzag orange underline for example?
I think because incremental compilation works, this can in theory be created/made. Thoughts?