-
I'm trying to create a custom Interpreter that can execute a state machine normally but while doing that it keeps track of the changes (e.g. store changes in DB) in the executed machine and its children (and its children children) I thought of doing something like this export class CustomInterpreter<
TContext,
TStateSchema extends StateSchema = any,
TEvent extends EventObject = EventObject,
TTypestate extends Typestate<TContext> = any
> extends Interpreter<TContext, TStateSchema, TEvent, TTypestate> {
constructor(
public machine: StateMachine<TContext, TStateSchema, TEvent, TTypestate>,
options: Partial<InterpreterOptions> = Interpreter.defaultOptions,
) {
super(machine, options);
this.onTransition(({ value, context, meta }) => {
// TODO: record parent context
});
}
public spawnMachine<
TChildContext,
TChildStateSchema,
TChildEvent extends EventObject
>(
machine: StateMachine<TChildContext, TChildStateSchema, TChildEvent>,
options: { id?: string; autoForward?: boolean; sync?: boolean } = {},
): Interpreter<TChildContext, TChildStateSchema, TChildEvent> {
const childService = super.spawnMachine(machine, options);
childService.onTransition(({ value, context, meta }) => {
// TODO: record child context
});
return childService;
}
} The problem is that this only will keep track of the changes in the parent machine and the first level machine, since spawnMachine calls Maybe I'm going about this the wrong way? Another option could be to spawn some sort of 'proxy' object in my models that forwards all messages to the target object and records the changes in the way. Any suggestions are welcome. |
Beta Was this translation helpful? Give feedback.
Replies: 2 comments
-
Yeah. Imagine that those spawned machines are actually API calls, or some other 3rd-party thing. It shouldn't be possible to track every single thing that is happening within those "entities" (otherwise, that'd be a huge security risk). You have to assume that you don't have access to the internal state of the spawned children; otherwise, that breaks the actor model. One way you can get around this is by iterating over state.children.forEach(child => {
child.subscribe(state => logToDB(child.id, state))
}); |
Beta Was this translation helpful? Give feedback.
-
Thanks for the reply @davidkpiano, I understand. I think I did a poor job explaining what I'm trying to do. I have a system which is a hierarchy of actors, implemented as XState state machines. What I want is to maintain a changeset for each actor, without having to explicitely call the logging function in each state machine. My first thought was to extend Interpreter, in such a way that it is the custom interpreter the one to log the changes for each actor. However, that does not work since I would need My plan now is to create a I think I ended up answering my own question 😅, but just wanted to provide some context. |
Beta Was this translation helpful? Give feedback.
Thanks for the reply @davidkpiano, I understand. I think I did a poor job explaining what I'm trying to do.
I have a system which is a hierarchy of actors, implemented as XState state machines. What I want is to maintain a changeset for each actor, without having to explicitely call the logging function in each state machine.
My first thought was to extend Interpreter, in such a way that it is the custom interpreter the one to log the changes for each actor. However, that does not work since I would need
spawnMachine
to return a custom interpreter as well so all levels of the tree get logged.My plan now is to create a
spawnWithProxy
method, that spawns a "proxy" actor for each child acto…