Fork me on GitHub
#hyperfiddle
<
2024-04-27
>
wei00:04:17

looking to build a stateful ui (multi-step login flow or wizards) and i found this thread about statecharts https://clojurians.slack.com/archives/C7Q9GSHFV/p1699957726323019. anyone have additional experience reports since that thread?

avocade08:04:55

Hey @U066TMAKS, I have an implementation for clj-statecharts inside electric in production so it definitely works, but there are some tricky parts to keep an eye out for when using electric since everything is reactive. Lots of places where I ended up jumping back and forth from cljs -> clj -> cljs to get a normal control flow. This is pretty much the setup:

(let [the-fm-atom  (atom {})
      the-fm       (sc/make-machine-with-store the-fm-atom fsm/file-machine-config)
      the-fm-state (e/watch the-fm-atom)]
  (sc/start-machine the-fm the-fm-atom {:debug true}))
Then I set up an electric fn as a general handler to trigger on state changes (i.e. no use of defined action fns from within the state machine definition, nor entry/exit fns.)

Eric Dvorsak11:04:11

It's still at the "thinking about it" stage for me, but I was looking at doing this using https://fulcrologic.github.io/statecharts/

Eric Dvorsak11:04:09

and someone actually did it in the thread you mentionned https://github.com/roterski/electric-statecharts-demo

🙏 2
avocade14:04:12

Yes I check that demo out before I did my implementation iirc.

Eric Dvorsak11:04:52

@U06KD64RX what are the biggest pros for using statecharts with electric? is there some things that you are able to do with statecharts that you feel like would be worse without in electric?

avocade11:04:43

Well no, statecharts is a good fit for clojure regardless of electric I'd say. We just use electric everywhere now so I had to learn how to make them be friends. Most things relating to state will benefit from a state machine imho, as soon as it graduates to more than 2-3 different states. It's just a much better model to architect programs and to aid in thinking, to actually reify otherwise implicit states.

Eric Dvorsak15:04:49

are you using them on the client, server or both?

avocade07:05:28

In the client-side context only currently, but should work across.

Eric Dvorsak07:05:56

and do you use some viz tools or text only representation of the statecharts?

avocade08:05:02

Just the code. It's clear enough for me.

Eric Dvorsak08:05:22

I kind of like the idea of being able to viz, especially to use statecharts for docs and QA but it seems like the 2 clj libs for it don't have an easy way

avocade08:05:36

Yeah sometimes nice especially when you want to explain to non-coders. There is a SaaS that seems pretty nice for drawing statecharts, haven't used it for realz though and can't remember the name.

avocade08:05:01

Quick google search found it: https://stately.ai/

Eric Dvorsak09:05:15

yes it's the people behind xstate

Eric Dvorsak09:05:28

but it's JS only and it's quite big

avocade13:05:27

Yes to me it's only interesting as a visualisation tool since it doesn't output anything like clojure.

Sigve11:05:45

If anyone is interested: i made a similar demo using clj-statecharts instead of fulcro/statecharts https://github.com/sigvesn/electric-clj-statecharts-demo

grounded_sage17:04:13

How can I avoid this issue?

Exception in thread "missionary blk-1" java.lang.Error: Can't process event - observer is not ready.

grounded_sage17:04:11

I have this

(->> (observe-fn input-val) 
     (m/reductions {} r/pending)
      m/stream)
Do I do it before or after reductions?

nivekuil19:04:36

in your case it might be m/latest after reductions

Hendrik20:04:35

m/relieve after m/reductions

Eric Dvorsak13:04:17

what does r/pending do? m/relieve will drop values you might not want that?

grounded_sage13:04:02

not my code and still yet to deep dive missionary. don't want to drop values

Hendrik14:04:52

As far as I know, r/pending values will be short circuit by electric:

(e/defn foo []
  (let [flow-value (new Flow)
     (do-something flow-value))) ; if flow value is r/pending or r/failure?, then do-something is not called with that value