invoke dynamic child machines
sytabaresa opened this issue · comments
Hi robot team!
It's posible this dynamic root/child machine implementation?:
import {
createMachine,
interpret,
invoke,
reduce,
state,
transition
} from "robot3";
// import 'robot3/debug';
let poolOfMachines = {
switch: createMachine({
inactive: state(
transition('toggle', 'active')
),
active: state(
transition('toggle', 'end')
),
end: state(),
}),
stoplight: createMachine({
red: state(
transition('toggle', 'yellow')
),
yellow: state(
transition('toggle', 'green')
),
green: state(
transition('toggle', 'red')
),
})
}
let rootMachine = createMachine({
step1: state(
transition('LOAD', 'step1',
reduce((ctx, ev) => ({
...ctx,
machineName: ev.value
}))
),
transition('RUN', 'step2')
),
// this dynamic kind of invoke
step2: invoke((ctx, ev) => poolOfMachines[ev.value ? ev.vale : ctx.machineName],
transition('done', 'step1')
),
// step2: invoke(poolOfMachines['switch'],
// transition('done', 'step1')
// ),
end: state()
})
let service = interpret(rootMachine, (service) => {
console.log(service.machine.current)
if (service.child)
console.log(service.child.machine.current)
}) // state: step1
service.send({
type: 'LOAD',
value: 'switch'
}) // state: step1
service.send('RUN') // invoke switch machine, state: step2.inactive
// switch child machine
service.child.send('toggle') // state:step3.active
service.child.send('toggle') // state:step3.end -> step1
service.send({
type: 'RUN',
value: 'stoplight'
}) // invoke stoplight machine, state: step2.red
// stoplight child machine
service.child.send('toggle') // state:step3.yellow
service.child.send('toggle') // state:step3.green
service.child.send('toggle') // state:step3.red
//...
I am trying to implement a plugin oriented machine system that can change the child machine based on runtime arguments, like a UI interface that have a root controller machine and many child plugin command machines. I know that its possible to interpret the child machine inside a promise invoked in step3
but that approach miss the nested send mechanism and other things.
Thanks for you attention.
I think this is a valid way to model the behavior yeah. Are you saying it isn't working?
I guess that in step2
the invoke form that I use is not valid, because its a function that returns a machine (dynamic machine) instead a promise. I think that could be a good API but in this moment is not supported
Oh right, sorry. We do treat all functions as being promising-returning at the moment. That's an interesting pattern though. Maybe it's something we could support in the future.
I made a PR to add support to this, hoping that you can review it 😁
Since #183 got merged, this issue should be able to be closed.