Closed lwhorton closed 6 years ago
I don't know the answer to your question, but I do know that the namespace will not necessarily be 'fsm.0'
if you create multiple fsms from your own extended BehavioralFsm
, then that number will increment.
I had to restore previously saved states, so when I am extending BehavioralFsm
I just gave it an arbitrary namespace, then I won't have to worry about the name changing on me.
var MyFSM = machina.BehavioralFsm.extend({
namespace: "mynamespace"
});
@lwhorton A thousand apologies for showing up 2 years late (see #146). When I added the BehavioralFsm
to machina, I needed a way to "stamp" clients with what machina had done up to that point so that, when given the client state again in the future, the FSM would continue to deal with it as expected. Without this, the FSM wouldn't know that it had seen the client before. I chose to keep this metadata on the client object under __machina__
so that the FSM itself (or machina) wouldn't have to keep track of that state (how would it know when that state could be purged, etc?). Underlying this approach was an overall goal to enable more actor-like scenarios (where state could be persisted for any length, retrieved and acted on later, etc.).
To @george-lin's point, machina gives you a default namespace that it will increment unless you provide your own. If the BehavioralFsm
is hierarchical, you'll see multiple namespaces under machina (one for each FSM in the hierarchy). So - if you're only using one FSM (not hierarchical), the backdoor-ish way to keep track of the state would be to hit stateClient.__machina__.['fsm.0'].state
like you said. However, the more 'official' way to get that state is to call yourBehavioralFsm.compositeState( stateClient )
.
I have (what I hope) is a rather quick question about machina internals, but I want to give a quick shout-out to how useful machina has proven in building robust, complex applications.
A behavioral fsm is exactly what I was looking for in my current experiment with redux and react. For those familiar, the "flux" architecture is certainly a step in the right direction for wrangling event/data flow, and redux is a great improvement over flux, but both implementations are really missing an opportunity to use machina concepts to even further simplify application complexities.
What I'm currently building is a redux "reducer" that simply defers to a machina instance to handle event states and complex (i.e. business requirement heavy) transitions between those states. For those unfamiliar, a reducer is simply an idempotent function that takes state, does stuff to it, and outputs a new state. That's simple enough - I can literally pass-through all the heavy lifting of sorting state transformations to machina:
My question is this; when using a behavioral fsm, machina attaches a
__machina___
key to the state instance, what is the importance of this machina object? Is it stateful such that future invocations offsm.handle(stateClient, inputType, args)
will depend on astateClient.__machina__
?I ask because I would (ideally) like to keep state as lean as possible. Virtually any changes at all in the application (new events, callbacks, promise resolves, etc.) will trigger another call to each reducer in the application, and I don't wan't to carry around
__machina__
knowledge in my state tree if at all possible. Can I short circuit the behavior by maintaining something likestateClient._currState = stateClient.__machina__.['fsm.0'].state
?