This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2024-02-06
Channels
- # aleph (43)
- # announcements (11)
- # babashka (35)
- # beginners (70)
- # calva (4)
- # cider (8)
- # clerk (15)
- # clojure (192)
- # clojure-dev (7)
- # clojure-europe (44)
- # clojure-nl (2)
- # clojure-norway (65)
- # clojure-uk (4)
- # code-reviews (4)
- # conjure (1)
- # cursive (41)
- # data-science (1)
- # datomic (8)
- # emacs (7)
- # fulcro (13)
- # humbleui (17)
- # hyperfiddle (53)
- # kaocha (4)
- # malli (7)
- # missionary (17)
- # music (1)
- # obb (1)
- # off-topic (8)
- # polylith (1)
- # portal (3)
- # releases (11)
- # shadow-cljs (36)
- # squint (4)
- # tools-deps (4)
Electric is still dope, the saga continues. The engineering team at http://Shomp.co has bloomed from zero engineers to one. That is, zero-indexed array-counting, from just myself to myself and Kurt who is absolutely amazing. Prototyping is super fast with electric, and I have been able to bring an experienced engineer up to speed in one zoom call. It's miraculous. Of course, now that we are actually coordinating on work we are making more strategic development priorities/prioritization. Right now we are working on integrating some cljsjs libraries and are having mixed success loading the javascript from the index dot html while also requiring the cljsjs namespace which ought in theory be redundant but there are difficulties or challenges present in invoking the constructor for the cljsjs stuff in the / via the native clojure cljc file So from my personal experience some amazing takeaways: + getting a senior engineer up to speed with electric, especially if they have used clojure(script) and some sort of SPA (single page application) framework [fb/"React" or whatever] takes as many zoom calls as it takes to cover the fundamentals which is typically one. + Wolking through an elaborate code demo or a living project (like my actively developed application Shomp) is a great way to get someone up to speed fast and you can focus on the salient changes from what the norm was. + When recruiting for help, get people excited about the mission and the vision.
How can I run this (stolen) example:
(tests "switch on dom effect"
(def !div (atom nil))
(def !x (atom true))
(with (e/run
(e/client
(binding [dom/node (.-body js/document)]
(dom/div
(reset! !div dom/node)
(dom/text "a")
(dom/text (if (e/watch !x) "b" "c"))
(dom/text "d")))
(.-textContent @!div) := "abd"
(swap! !x not)
(.-textContent @!div) := "acd"
(swap! !x not)
(.-textContent @!div) := "abd"))))
in a browser connected cljs REPL or with a cljs test runner. The electric main repo has some https://github.com/hyperfiddle/electric/blob/master/ci/run_tests_browser.sh
Hey, trying to update from electric 428 to 540, following current electric-starter as my setup reference. I think I'm close but something seems to go wrong in the late client boot:
1. server starts and build succeeds
2. > 👉 http://0.0.0.0:8080
3. server prints (println)
up to first (e/client ...)
in my electric entrypoint
4. client prints shadow-cljs: #3 ready!
, Connecting....
, Connected.
but not (println)
in first (e/client)
i.e. with my entrypoint (`seshat.core/App`):
(e/defn App [ring-request]
(println "who?")
(e/server
(println "server"
(e/client
(println "client")
....
and src-dev/dev.cljc:
#?(:cljs ;; Client Entrypoint
(do
(println "client-entry")
(def electric-entrypoint (e/boot-client {} seshat.core/App nil))
(defonce reactor nil)
(defn ^:dev/after-load ^:export start! []
(println "starting")
(set! reactor (electric-entrypoint
#(js/console.log "Reactor success:" %)
#(js/console.error "Reactor failure:" %))))
(defn ^:dev/before-load stop! []
(when reactor (reactor)) ; stop the reactor
(set! reactor nil))))
on the server I read
> who?
> server
and on the client
> client-entry
> browser.cljs:20 shadow-cljs: call dev/start!
> dev.cljc:48 starting
> dev.cljc:49 Connecting...
> electric_client.cljs:117 Connected.attempt checked into branch electric-540 of my repo, @U09K620SG and @U09FL65DK you still have pull access (git@git. MY-NAME .nu:seshat.git)
paste your app root e/fn into a clean starter app and see if it works
the code snippet pasted above does not reference any other namespaces
okay, some progress - i removed all my old code from App and have only exactly this:
(e/defn App [ring-request]
(println "server")
(e/client
(println "client")))
and that works as expectedhowever adding dom:
(e/defn App [ring-request]
(println "server")
(e/client
(println "client1")
(binding [dom/node js/document.body]
(dom/header
(dom/h1 (dom/text "seshat banking inc"))
(dom/span (dom/text ""it's only money"")))
(println "client2"))))
I see a quick flash of the dom, then I get a reactor errorwhat is this ""it's only money""
server log:
#error {
:cause "Index 0 out of bounds for length 0"
:via
[{:type java.lang.ArrayIndexOutOfBoundsException
:message "Index 0 out of bounds for length 0"
:at [clojure.lang.RT aget "RT.java" 2377]}]
:trace
[[clojure.lang.RT aget "RT.java" 2377]
[hyperfiddle.electric.impl.runtime$eval_tree_inst invokeStatic "runtime.cljc" 808]
[hyperfiddle.electric.impl.runtime$eval_tree_inst invoke "runtime.cljc" 800]
[clojure.lang.PersistentVector reduce "PersistentVector.java" 343]
[clojure.core$reduce invokeStatic "core.clj" 6885]
[clojure.core$reduce invoke "core.clj" 6868]
[hyperfiddle.electric.impl.runtime$parse_event invokeStatic "runtime.cljc" 842]
[hyperfiddle.electric.impl.runtime$parse_event invoke "runtime.cljc" 840]
[clojure.lang.PersistentVector reduce "PersistentVector.java" 343]
[clojure.core$reduce invokeStatic "core.clj" 6885]
[clojure.core$reduce invoke "core.clj" 6868]
[clojure.core$partial$fn__5910 invoke "core.clj" 2648]
[missionary.impl.Util apply "Util.java" 29]
[missionary.impl.Sample transfer "Sample.java" 84]
[missionary.impl.Sample$Process deref "Sample.java" 34]
[missionary.impl.Reactor pull "Reactor.java" 183]
[missionary.impl.Reactor touch "Reactor.java" 222]
[missionary.impl.Reactor propagate "Reactor.java" 242]
[missionary.impl.Reactor event "Reactor.java" 398]
[missionary.impl.Reactor$1 invoke "Reactor.java" 480]
[missionary.impl.Relieve$1 invoke "Relieve.java" 86]
[missionary.impl.Sample$3 invoke "Sample.java" 146]
[missionary.impl.Observe$1 invoke "Observe.java" 74]
[clojure.core$comp$fn__5876 invoke "core.clj" 2586]
[hyperfiddle.electric_ring_adapter$electric_ws_handler$on_message__25601 invoke "electric_ring_adapter.clj" 160]
[clojure.lang.AFn applyToHelper "AFn.java" 156]
[clojure.lang.AFn applyTo "AFn.java" 144]
[clojure.core$apply invokeStatic "core.clj" 669]
[clojure.core$apply invoke "core.clj" 662]
[hyperfiddle.electric_ring_adapter$ring_ws_handler$fn__25609$fn__25610 doInvoke "electric_ring_adapter.clj" 181]
[clojure.lang.RestFn invoke "RestFn.java" 423]
[ring.websocket$eval25348$fn__25352 invoke "websocket.clj" 13]
[ring.websocket.protocols$eval25113$fn__25114$G__25098__25123 invoke "protocols.clj" 3]
[ring.adapter.jetty$websocket_listener$reify__25960 onWebSocketText "jetty.clj" 76]
[org.eclipse.jetty.websocket.core.internal.messages.StringMessageSink accept "StringMessageSink.java" 53]
[org.eclipse.jetty.websocket.common.JettyWebSocketFrameHandler acceptMessage "JettyWebSocketFrameHandler.java" 348]
[org.eclipse.jetty.websocket.common.JettyWebSocketFrameHandler onTextFrame "JettyWebSocketFrameHandler.java" 436]
[org.eclipse.jetty.websocket.common.JettyWebSocketFrameHandler onFrame "JettyWebSocketFrameHandler.java" 241]
[org.eclipse.jetty.websocket.core.internal.WebSocketCoreSession$IncomingAdaptor lambda$onFrame$1 "WebSocketCoreSession.java" 671]
[org.eclipse.jetty.server.handler.ContextHandler handle "ContextHandler.java" 1466]
[org.eclipse.jetty.server.handler.ContextHandler handle "ContextHandler.java" 1485]
[org.eclipse.jetty.websocket.core.server.internal.AbstractHandshaker$1 handle "AbstractHandshaker.java" 212]
[org.eclipse.jetty.websocket.core.internal.WebSocketCoreSession$IncomingAdaptor onFrame "WebSocketCoreSession.java" 671]
[org.eclipse.jetty.websocket.core.AbstractExtension nextIncomingFrame "AbstractExtension.java" 145]
[org.eclipse.jetty.websocket.core.internal.PerMessageDeflateExtension nextIncomingFrame "PerMessageDeflateExtension.java" 236]
[org.eclipse.jetty.websocket.core.internal.DemandingFlusher emitFrame "DemandingFlusher.java" 145]
[org.eclipse.jetty.websocket.core.internal.PerMessageDeflateExtension$IncomingFlusher inflate "PerMessageDeflateExtension.java" 487]
[org.eclipse.jetty.websocket.core.internal.PerMessageDeflateExtension$IncomingFlusher handle "PerMessageDeflateExtension.java" 413]
[org.eclipse.jetty.websocket.core.internal.DemandingFlusher process "DemandingFlusher.java" 169]
[org.eclipse.jetty.util.IteratingCallback processing "IteratingCallback.java" 243]
[org.eclipse.jetty.util.IteratingCallback succeeded "IteratingCallback.java" 369]
[org.eclipse.jetty.websocket.core.internal.DemandingFlusher onFrame "DemandingFlusher.java" 104]
[org.eclipse.jetty.websocket.core.internal.PerMessageDeflateExtension onFrame "PerMessageDeflateExtension.java" 93]
[org.eclipse.jetty.websocket.core.internal.ExtensionStack onFrame "ExtensionStack.java" 120]
[org.eclipse.jetty.websocket.core.internal.WebSocketCoreSession onFrame "WebSocketCoreSession.java" 481]
[org.eclipse.jetty.websocket.core.internal.WebSocketConnection onFrame "WebSocketConnection.java" 271]
[org.eclipse.jetty.websocket.core.internal.WebSocketConnection fillAndParse "WebSocketConnection.java" 464]
[org.eclipse.jetty.websocket.core.internal.WebSocketConnection onFillable "WebSocketConnection.java" 349]
[org.eclipse.jetty.io.AbstractConnection$ReadCallback succeeded "AbstractConnection.java" 314]
[org.eclipse.jetty.io.FillInterest fillable "FillInterest.java" 100]
[org.eclipse.jetty.io.SelectableChannelEndPoint$1 run "SelectableChannelEndPoint.java" 53]
[org.eclipse.jetty.util.thread.strategy.AdaptiveExecutionStrategy runTask "AdaptiveExecutionStrategy.java" 421]
[org.eclipse.jetty.util.thread.strategy.AdaptiveExecutionStrategy consumeTask "AdaptiveExecutionStrategy.java" 390]
[org.eclipse.jetty.util.thread.strategy.AdaptiveExecutionStrategy tryProduce "AdaptiveExecutionStrategy.java" 277]
[org.eclipse.jetty.util.thread.strategy.AdaptiveExecutionStrategy run "AdaptiveExecutionStrategy.java" 199]
[org.eclipse.jetty.util.thread.ReservedThreadExecutor$ReservedThread run "ReservedThreadExecutor.java" 411]
[org.eclipse.jetty.util.thread.QueuedThreadPool runJob "QueuedThreadPool.java" 969]
[org.eclipse.jetty.util.thread.QueuedThreadPool$Runner doRunJob "QueuedThreadPool.java" 1194]
[org.eclipse.jetty.util.thread.QueuedThreadPool$Runner run "QueuedThreadPool.java" 1149]
[java.lang.Thread run "Thread.java" 840]]}
ERROR hyperfiddle.electric-ring-adapter: Websocket handler failure. nil
java.lang.ArrayIndexOutOfBoundsException: Index 0 out of bounds for length 0
at clojure.lang.RT.aget(RT.java:2377)
at hyperfiddle.electric.impl.runtime$eval_tree_inst.invokeStatic(runtime.cljc:808)
at hyperfiddle.electric.impl.runtime$eval_tree_inst.invoke(runtime.cljc:800)
at clojure.lang.PersistentVector.reduce(PersistentVector.java:343)
at clojure.core$reduce.invokeStatic(core.clj:6885)
at clojure.core$reduce.invoke(core.clj:6868)
at hyperfiddle.electric.impl.runtime$parse_event.invokeStatic(runtime.cljc:842)
at hyperfiddle.electric.impl.runtime$parse_event.invoke(runtime.cljc:840)
at clojure.lang.PersistentVector.reduce(PersistentVector.java:343)
at clojure.core$reduce.invokeStatic(core.clj:6885)
at clojure.core$reduce.invoke(core.clj:6868)
at clojure.core$partial$fn__5910.invoke(core.clj:2648)
at missionary.impl.Util.apply(Util.java:29)
at missionary.impl.Sample.transfer(Sample.java:84)
at missionary.impl.Sample$Process.deref(Sample.java:34)
at missionary.impl.Reactor.pull(Reactor.java:183)
at missionary.impl.Reactor.touch(Reactor.java:222)
at missionary.impl.Reactor.propagate(Reactor.java:242)
at missionary.impl.Reactor.event(Reactor.java:398)
at missionary.impl.Reactor$1.invoke(Reactor.java:480)
at missionary.impl.Relieve$1.invoke(Relieve.java:86)
at missionary.impl.Sample$3.invoke(Sample.java:146)
at missionary.impl.Observe$1.invoke(Observe.java:74)
at clojure.core$comp$fn__5876.invoke(core.clj:2586)
at hyperfiddle.electric_ring_adapter$electric_ws_handler$on_message__25601.invoke(electric_ring_adapter.clj:160)
at clojure.lang.AFn.applyToHelper(AFn.java:156)
at clojure.lang.AFn.applyTo(AFn.java:144)
at clojure.core$apply.invokeStatic(core.clj:669)
at clojure.core$apply.invoke(core.clj:662)
at hyperfiddle.electric_ring_adapter$ring_ws_handler$fn__25609$fn__25610.doInvoke(electric_ring_adapter.clj:181)
at clojure.lang.RestFn.invoke(RestFn.java:423)
at ring.websocket$eval25348$fn__25352.invoke(websocket.clj:13)
at ring.websocket.protocols$eval25113$fn__25114$G__25098__25123.invoke(protocols.clj:3)
at ring.adapter.jetty$websocket_listener$reify__25960.onWebSocketText(jetty.clj:76)
at org.eclipse.jetty.websocket.core.internal.messages.StringMessageSink.accept(StringMessageSink.java:53)
at org.eclipse.jetty.websocket.common.JettyWebSocketFrameHandler.acceptMessage(JettyWebSocketFrameHandler.java:348)
at org.eclipse.jetty.websocket.common.JettyWebSocketFrameHandler.onTextFrame(JettyWebSocketFrameHandler.java:436)
at org.eclipse.jetty.websocket.common.JettyWebSocketFrameHandler.onFrame(JettyWebSocketFrameHandler.java:241)
at org.eclipse.jetty.websocket.core.internal.WebSocketCoreSession$IncomingAdaptor.lambda$onFrame$1(WebSocketCoreSession.java:671)
at org.eclipse.jetty.server.handler.ContextHandler.handle(ContextHandler.java:1466)
at org.eclipse.jetty.server.handler.ContextHandler.handle(ContextHandler.java:1485)
at org.eclipse.jetty.websocket.core.server.internal.AbstractHandshaker$1.handle(AbstractHandshaker.java:212)
at org.eclipse.jetty.websocket.core.internal.WebSocketCoreSession$IncomingAdaptor.onFrame(WebSocketCoreSession.java:671)
at org.eclipse.jetty.websocket.core.AbstractExtension.nextIncomingFrame(AbstractExtension.java:145)
at org.eclipse.jetty.websocket.core.internal.PerMessageDeflateExtension.nextIncomingFrame(PerMessageDeflateExtension.java:236)
at org.eclipse.jetty.websocket.core.internal.DemandingFlusher.emitFrame(DemandingFlusher.java:145)
at org.eclipse.jetty.websocket.core.internal.PerMessageDeflateExtension$IncomingFlusher.inflate(PerMessageDeflateExtension.java:487)
at org.eclipse.jetty.websocket.core.internal.PerMessageDeflateExtension$IncomingFlusher.handle(PerMessageDeflateExtension.java:413)
at org.eclipse.jetty.websocket.core.internal.DemandingFlusher.process(DemandingFlusher.java:169)
at org.eclipse.jetty.util.IteratingCallback.processing(IteratingCallback.java:243)
at org.eclipse.jetty.util.IteratingCallback.succeeded(IteratingCallback.java:369)
at org.eclipse.jetty.websocket.core.internal.DemandingFlusher.onFrame(DemandingFlusher.java:104)
at org.eclipse.jetty.websocket.core.internal.PerMessageDeflateExtension.onFrame(PerMessageDeflateExtension.java:93)
at org.eclipse.jetty.websocket.core.internal.ExtensionStack.onFrame(ExtensionStack.java:120)
at org.eclipse.jetty.websocket.core.internal.WebSocketCoreSession.onFrame(WebSocketCoreSession.java:481)
at org.eclipse.jetty.websocket.core.internal.WebSocketConnection.onFrame(WebSocketConnection.java:271)
at org.eclipse.jetty.websocket.core.internal.WebSocketConnection.fillAndParse(WebSocketConnection.java:464
Anyway I think you can bisect this by commenting out pieces of your app
@U09K620SG its only that block i posted now, everything else is commented out or not called (although i am still requiring other stuff)
same thing with just
(e/defn App [ring-request]
(e/client
(binding [dom/node js/document.body]
(dom/h1 "test"))))
could be an issue with your hot code reloading setup?
client and server must compile simultaneously
(dom/h1 "test")
is missing dom/text
only difference is that I removed electric_starter_app from all the resources/public/... paths, but the js code is being loaded so don't think that matters
electric-starter-app references hyperfiddle.electric via git sha, i'm using 540 from maven. Is my copied code from electric-stater-app maybe mismatched?
at this point i recommend you fork the starter app and migrate your app in one function at a time
i can't figure out how to find corresponding electric or electric-starter hash for mvn versions
I can't check your configs, there's not a lot we can do for you other than wait for you to produce a minimized repro if you think you have a bug
sorry that the errors suck, IC made it worse, still working out the kinks
it was super not clear that you had a bunch of requires as part of this reproduction
index out of bounds errors typically mean misaligned server/client code. Known reasons for that
• different versions compiled on server/client. This can be a case from e.g. browser cache or evaling a change in the CLJ REPL but not saving it (shadow not recompiling)
• peer-dependent macroexpansion, e.g. assert
elided on client and kept on server
• some users reported tools.namespace refresh issues
• conditionally requiring electric code, e.g. (:require #?(:cljs my-electric-ns))
Compilation is e/def by e/def, so all :requires with electric code inside are in play
sorry, i wrote this earlier, but the thread got very crowded > its only that block i posted now, everything else is commented out or not called (although i am still requiring other stuff)
*if they contain e/server code
(:require #?(:cljs your-ns-with-electric-code))
is not allowed