Multi-Machine Coordination
Problem
A session transition must update a separate notification workflow without machines importing each other.
Solution
Subscribe at the application boundary and send a domain event to the other actor after the source commits.
ts
import { defineMachine } from '@vielzeug/clockwork';
type SessionEvent = { type: 'LOGIN' } | { type: 'LOGOUT' };
type NoticeEvent = { type: 'HIDE' } | { type: 'SHOW' };
const session = defineMachine<Record<string, never>, SessionEvent>()({
initial: 'idle',
states: { idle: { on: { LOGIN: { target: 'active' } } }, active: { on: { LOGOUT: { target: 'idle' } } } },
}).createActor();
const notice = defineMachine<Record<string, never>, NoticeEvent>()({
initial: 'hidden',
states: { hidden: { on: { SHOW: { target: 'visible' } } }, visible: { on: { HIDE: { target: 'hidden' } } } },
}).createActor();
const stop = session.subscribe((snapshot) => {
if (snapshot.state === 'active') notice.send({ type: 'SHOW' });
});
session.send({ type: 'LOGIN' });
console.log(notice.snapshot.state); // 'visible'
stop();
session.dispose();
notice.dispose();Pitfalls
- Keep event flow directed; cyclic subscriptions can create feedback loops.
maxTransitionsprotects an actor from loops but is not normal control flow.