Is this the canonical source for electric changes? -> https://github.com/hyperfiddle/electric A new snapshot is made available when main changes? Experiencing more frequent than expected downloads of snapshots. Accompanied by slower than expected download speed. Asking to aid with isolating what the issue I am experiencing is.
you can find the date of last snapshot here: https://clojars.org/com.hyperfiddle/electric/versions/v3-alpha-SNAPSHOT
no, github is not guaranteed to match the snapshot publication
also, we have started maintaining a https://docs.google.com/document/d/17BE7xpV9bFoPq9scLJHCF8hD5gBm00K0Up45N3XeG5c/edit?tab=t.0#heading=h.ojrtp4t0j7h7 (instead of just a slack announcement)
Hello friends! 👋 A few weeks back, me and @daslu put together an experimental library for rendering https://scicloj.github.io/kindly-noted/kindly visualizations in Electric: https://github.com/itonomi/kindly-electric It is super useful already, thanks to the breadth of visualizations offered by https://github.com/scicloj/kindly-render! We've used it at https://itonomi.com/ for some neat real-time visualizations of our RAG jobs and it worked great right out of the box! 🤓 Please try it out and ping me about any bugs or feedback otherwise!
And here's a quick one-liner to run the playground locally 😄
git clone /tmp/kindly-electric && cd /tmp/kindly-electric/playground && clojure -A:dev -X dev/-main Fantastic
Looks great. I just shared your message at the #kindly-dev channel at Zulip.
https://clojurians.zulipchat.com/#narrow/channel/454856-kindly-dev/topic/electric/near/521773989 electric @ 💬>
Can someone help me understand what I am doing wrong in this cide? It is kind of a lot of code but I don't know how else to ask this question. @dustingetz To save space here I will put the code on a reply to this comment
(e/defn match-brain-activity-server []
(e/server
(match-brain-activity-impl)))
e/defn names must be capitalized, not sure if this is connected with your error somehowi dont think the code in the repo matches the bug report
I suspect a hot code reloading issue actually
the Electric hot code reloader will auto reload all dirty cljc namespaces and also reload the corresponding jvm clojure macro namespace, but it will not auto reload .clj files for example, which can get tricky especially as you refactor code
I follow this pattern to try and match live data streaming from a device:
(e/defn StartStreamingWhenMatching []
(e/client
(let [state (e/watch pong-state/state)
connected? (get-in state [:bci :device-connected?])
matching? (get-in state [:bci :matching?])
streaming? (get-in state [:bci :streaming?])]
;; Start streaming when we start matching (if not already streaming)
(when (and connected? matching? (not streaming?))
(js/console.log "Starting EEG streaming for brain activity matching")
(let [stream-result (e/server (bci/start-eeg-streaming-server "pong"))]
(js/console.log "Stream start result:" (clj->js stream-result))
(when (:success stream-result)
(swap! pong-state/state assoc-in [:bci :streaming?] true)))))))
(e/defn PollBrainActivityWhenMatching []
(e/client
(let [state (e/watch pong-state/state)
connected? (get-in state [:bci :device-connected?])
matching? (get-in state [:bci :matching?])
streaming? (get-in state [:bci :streaming?])]
; Poll when connected, matching, and streaming
(when (and connected? matching? streaming?)
; Should execute whenever the state changes
(let [confidence-data (e/server (bci/match-brain-activity-server))]
(js/console.log "Brain activity confidence:" (clj->js confidence-data))
(when confidence-data
(swap! pong-state/state assoc-in [:bci :confidence] confidence-data)))))))
and then I am trying to extend the same 'BrainControls'
(e/defn BrainControls []
(e/client
(let [state (e/watch pong-state/state)
connected? (get-in state [:bci :device-connected?])
pending-connect? (get-in state [:bci :pending-connect])
pending-disconnect? (get-in state [:bci :pending-disconnect])
active-profile (get-in state [:bci :active-profile])
connection-error (get-in state [:bci :connection-error])
matching? (get-in state [:bci :matching?])
streaming? (get-in state [:bci :streaming?])
confidence (get-in state [:bci :confidence])]
(ConnectWhenPending)
(DisconnectWhenPending)
(StartStreamingWhenMatching)
(StopStreamingWhenNotMatching)
(PollBrainActivityWhenMatching)
...the rest of the code is the same...
; Brain matching toggle (only show when connected)
(when connected?
(dom/button
(dom/props {:class (str "bci-button " (if matching? "stop-matching" "start-matching"))})
(dom/text (if matching? "Stop Brain Control" "Start Brain Control"))
(dom/On "click"
(fn [_]
(swap! pong-state/state assoc-in [:bci :matching?] (not matching?)))
nil)))
; Show active profile info
(when (and connected? active-profile)
(dom/div
(dom/props {:class "profile-info"})
(dom/text (str "Profile: " active-profile))
(when streaming?
(dom/span
(dom/props {:class "streaming-indicator"})
(dom/text " • Streaming")))))
; Show brain activity confidence when matching
(when (and connected? matching? confidence)
(dom/div
(dom/props {:class "confidence-display"})
(dom/div (dom/text (str "Up: " (get confidence :up 0.0))))
(dom/div (dom/text (str "Down: " (get confidence :down 0.0))))
(when-let [error (get confidence :error)]
(dom/div
(dom/props {:class "confidence-error"})
(dom/text (str "Error: " error))))))
....)
I keep running into this error and I don't know how to resolve it:
Caused by: clojure.lang.ExceptionInfo:
brain-pong.components/PollBrainActivityWhenMatching:145:40
I cannot resolve [bci/match-brain-activity-server] {:in PollBrainActivityWhenMatching, :for :server}
Why it can't resolve my function? match-brain-activity-server is a big block of only clojure code:
#?(:clj
(defn match-brain-activity-server
[]
(try
(let [recording? @state/recording?
eeg-data @state/eeg-data]
(println "Recording? value:" recording? "type:" (type recording?))
(println "EEG data value:" (if eeg-data "exists" "nil") "type:" (type eeg-data))
....rest of that function
The following code works for me to connect to the device I am working with:
(e/defn ConnectWhenPending []
(e/client
(let [state (e/watch pong-state/state)]
(when (get-in state [:bci :pending-connect])
(js/console.log "Initiating BCI connection!")
; Clear the pending state first
(swap! pong-state/state assoc-in [:bci :pending-connect] false)
(let [result (e/server (bci/connect-device))]
(js/console.log "Connection result:" (clj->js result))
(if (:connected result)
(do
(swap! pong-state/state update-in [:bci] merge
{:device-connected? (:connected result)
:active-profile (:profile-name result)
:connection-error nil})
(js/console.log "Connection successful"))
(do
(swap! pong-state/state update-in [:bci] merge
{:device-connected? false
:active-profile nil
:connection-error (:error result)})
(js/console.log "Connection failed:" (:error result)))))))))
which calls a bunch of server logic in my bci namespace:
#?(:clj
(defn connect-device []
(try
(initialize-modules!)
(mount/start)
(println "Server: Connecting to BCI device with active profile")
(let [active-profile ((:get-active-profile @state/state))
active-profile-name (:name active-profile)
connected? (api/connect-from-profile! active-profile)]
(println "Connection result:" connected?)
{:connected connected?
:profile-name active-profile-name})
(catch Exception e
(println "Error in connect-device-server:" (.getMessage e))
{:connected false :error (.getMessage e)}))))
I put that and a similar disconnect function into this BCIControlComponent and I just call this in my main function and it works
(e/defn BrainControls []
(e/client
(let [state (e/watch pong-state/state)
connected? (get-in state [:bci :device-connected?])
pending-connect? (get-in state [:bci :pending-connect])
pending-disconnect? (get-in state [:bci :pending-disconnect])
active-profile (get-in state [:bci :active-profile])
connection-error (get-in state [:bci :connection-error])]
(ConnectWhenPending)
(DisconnectWhenPending)
(dom/div
(dom/props {:class "bci-controls"})
; Connection button
(dom/button
(dom/props {:class (str "bci-button " (if connected? "disconnect" "connect"))
:disabled (or pending-connect? pending-disconnect?)})
(dom/text (cond
pending-connect? "Connecting..."
pending-disconnect? "Disconnecting..."
connected? "Disconnect Device"
:else "Connect Device"))
(dom/On "click"
(fn [_]
(if connected?
(swap! pong-state/state assoc-in [:bci :pending-disconnect] true)
(swap! pong-state/state assoc-in [:bci :pending-connect] true)))
nil))
; Show active profile info
(when (and connected? active-profile)
(dom/div
(dom/props {:class "profile-info"})
(dom/text (str "Profile: " active-profile))))
; Show connection error if any
(when connection-error
(dom/div
(dom/props {:class "connection-error"})
(dom/text (str "Error: " connection-error))))))))can you give us a link to the actual file so i can like, c-f it
and see the ns form
thank you for collapsing the inline code snippets out of the OP
@dustingetz @post972
Okay I pushed what I am recently working with but it doesn't work right now because of the issues I shared above. In theory it should work if the StartStreamingWhenMatching, StopStreamingWhenMatching, and PollBrainActivityWhenMatching components are commented out.
If you want to run it, it does require that you set up BrainFlow; but hopefully I have streamlined that process as much as possible -
First it is necessary to run clj -m setup in the root of brainfloj, and that should both download all the necessary BrainFlow files as well as add it to the deps.edn in the root directory.
Secondly, to run the Pong game, which also requires BrainFlow (separately since it is meant to be an 'example application'), Pong itself needs to get setup, and I created a "setup_brainflow.clj" file in the root of the examples namespace. Either running clj -m setup_brainflow or evaluating (-main) in examples/Pong/src/setup_brainflow.clj will add the paths to the Brainflow libs that got downloaded in step one to the Pong game.
then the game can start with clj -A:dev -X dev/-main in the examples/Pong directory; but like I am sort of asking about; it doesn't run with the current code I am trying to get to work. If those 3 components are commented out, then the pong game should be working fine and it should open up in the browser at localhost:8080.
If it would be preferred for debugging purposes, I can push another version right away that just has it commented out and working in a basic way.
https://github.com/TheFakeLorLyons/brainfloj
^I just went ahead and commented out everything that doesn't work so now the page loads as long as all the dependencies are set up.
Oh and the match-brain-activity-server function that is giving me problems is in the middle of bci_integration.cljc, the components are in components.cljc and the entry point to everything is main.cljc. The only other namespaces that are relevant are game_state.cljc and signature.clj. I am not using the other files in the game yet.