Open ingesolvoll opened 4 years ago
Sorry for the late reply.
The first "Less functions, more data" sounds reasonable, but it's already doable since the fsm schema only requires the entry/exit/actions/guards functions to satisfy ifn?
, not fn?
, which means it could be any keywords. For vectors it would be ambiguous since for now :entry/:exit/:actions values could be a vector of functions. So we need some special handling.
The second, "Injecting context", I think you can simply put the context under some key in the second argument of fsm/transition
. fsm/transition
is a direct translation of the formula [next-state, actions-to-peform] = F(current-state, input-event)
so anything that could affect the transition shall conceptually be part of the state.
I have a few suggestions on how to make clj-statecharts even more extensible and data oriented. I mostly work in re-frame, so my requirements comes from that field, but these probably apply to other areas equally well. I'll describe them in re-frame terms here.
Desired outcomes
entry
,guard
, etc.1. Less functions, more data
In the app I'm working on at my daily job, sending schema and FSMs over the wire to be shared across the stack is very common. Serializing functions is of course possible, malli can do that, but it's easier if we can avoid it. There are several techniques or APIs that could work:
entry
andguard
, so that they can be vectors or any type instead of functions. First thing that comes to mind is a re-frame event vector asaction
. Could be solved using multimethods.In our malli code, we specifically solved serialization by referring to objects through keywords. Our cljc-implemented registry could then be injected just before you need it, on the server or on the client.
2. Injecting context
It would be very powerful if all functions in the FSM definition could have arbitrary context injected. Imagine the following invocation:
(fsm/transition machine s1 {:type :timer} {:ctx {:db current-re-frame-db})
Which would make a
guard
fn receive the:ctx
value in its args.You may agree or disagree that this particular thing is a good idea, but it really opens up a lot of possibilities. For example: if the app uses an interceptor to integrate the FSM into re-frame, you could use a
guard
to make the FSM reactively transition based on client db changes.