Open devanshj opened 3 years ago
You are a machine. This is awesome! Checking the code right now.
We store the state of the machine in form of a tree. Where each node can be thought of a stateful submachine. Each node has children and state which is the identifier of the active child.
✅
So the final "state" ie an sequential array from outermost active node to innermost active node is derived via Node.state and is not the source of truth.
Correct. Are we also representing the state as a array in case of a flat, single-level state machine?
(Might rename the property state of node to be something else because node.state and Node.state(node) read similar but are completely different)
Yeah, makes sense.
So essentially when an event comes we find out the nextStateIdentifier, then compute the nextState from it, then diff it with the currentState for entries and exits.
Yeah, we might need to use a pathfinding algorithm (opposed to just traversing the tree until we find the nodes).
So for the test case something like this happens... got event X resolved nextStateIdentifier to a2 derived nextState to be [a, a2] derived currentState to be [b, b1] Diffed them to compute entries to be [a, a2] and exits to be [a, a2] Run effect cleanups for exits in reverse order Run effects for entries
Correct, assuming you meant that exist would be [b, b1]
You are a machine. This is awesome!
Hahaha thanks a lot!
Are we also representing the state as a array in case of a flat, single-level state machine?
Yep Node.state
always returns an array for all kinds of machines.
Yeah, we might need to use a pathfinding algorithm (opposed to just traversing the tree until we find the nodes)
How would the pathfinding algorithm work without traversing the tree though? This version does a depth-first search (assuming nextState
would be the one that does what you're talking about). We could memoize it, as it's stateless ie does not depend on the state of the node or the machine.
Correct, assuming you meant that exist would be [b, b1]
Right, typo (will edit for posterity)
How would the pathfinding algorithm work without traversing the tree though? This version does a depth-first search (assuming nextState would be the one that does what you're talking about). We could memoize it, as it's stateless ie does not depend on the state of the node or the machine.
We could traverse from the nodes and find the shortest path without necessarily traversing the whole tree from the top - but thinking about it, it seems like a premature optimization - Most likely the state tree won't be complex or big enough to benefit from this...
We could traverse from the nodes and find the shortest path without necessarily traversing the whole tree from the top
Huh? xD I don't follow, wym by "find the shortest path"? To make sure we're on the same page we're taking about an algorithm that takes an input rootNode
and "a1"
and gives output ["a", "a1"]
.
EDIT: Oh wait we have an additional information that the current state is b.b1
so we could start looking for nodes with identifier a1
starting from there, perhaps that's what you meant by "shortest path" -- makes sense.
but thinking about it, it seems like a premature optimization - Most likely the state tree won't be complex or big enough to benefit from this...
Yep exactly, but I think it's a good improvement nonetheless.
Just a little poc I tried (not very tested), wanted to keep it fp let me know if you like it so either of us can take this forward!
I know this is the least important thing right now as it's for 1.2.0 but as usual I was bored and wanted to do something fun xD
(I have based it on
api-change-for-sendt
as you haven't merged it yet)Edit, A gist how it works:
We store the state of the machine in form of a tree. Where each node can be thought of a stateful submachine. Each node has
children
andstate
which is the identifier of the active child.So the final "state" ie an sequential array from outermost active node to innermost active node is derived via
Node.state
and is not the source of truth. (Might rename the propertystate
ofnode
to be something else becausenode.state
andNode.state(node)
read similar but are completely different)So essentially when an event comes we find out the
nextStateIdentifier
, then compute thenextState
from it, then diff it with thecurrentState
for entries and exits.So for the test case something like this happens...
The
Node.transition
part is completely pure (it gives[newNode, entries, exits]
) so it will help with testing (I'm thinking of some snapshot based testing) and also withshouldSend
as we could simply send it and see if the state changes.