import { useMachine as useXStateMachine } from '@xstate/react'; const getStateStat = (state: any): string => { if (typeof state === 'string') { return state; } if (Object.keys(state).length > 1) { throw new Error('useMachine does not support emitting stats for parallel states'); } const key = Object.keys(state)[0]; return `${key}.${getStateStat(state[key])}`; }; const sendTransitionStat = (state: any, machineId: string) => { const metric = `machines.${machineId}.${getStateStat(state.value)}`; const tags = state.history ? { fromState: getStateStat(state.history.value) } : undefined; stats.sendStats({ metric, method: StatsMethod.INCREMENT, tags, }); }; const getStateAnalytics = (state: any): string => { if (typeof state === 'string') { return state; } if (Object.keys(state).length > 1) { throw new Error('useMachine does not support emitting stats for parallel states'); } const key = Object.keys(state)[0]; return `${key}.${getStateAnalytics(state[key])}`; }; const sendAnalyticsOnTransition = () => { analytics.send('STATECHARTS_ANALYTICS_EVENT', { fromState: getStateAnalytics(get(state, 'history.value', '')), currentState: getStateAnalytics(get(state, 'value', '')), machineName: machine.id, }); }; export const useMachine = (machine, options) => { const { statOnTransition, analyticsOnTransition, ...rest } = options; const [current, send, service] = useMachine(machine, options); useEffect(() => { service.onTransition(state => { if (state.changed) { if (statOnTransition) { sendTransitionStat(state, machine.id); } if (analyticsOnTransition) { sendAnalyticsOnTransition(state, machine.id); } } }); }, []); return [current, send, service]; };