import { useEffect } from 'react' import { AnyStateMachine, InterpreterFrom, StateFrom } from 'xstate' import { createMachineCommand } from '../lib/createMachineCommand' import { useCommandsContext } from './useCommandsContext' import { modelingMachine } from 'machines/modelingMachine' import { authMachine } from 'machines/authMachine' import { settingsMachine } from 'machines/settingsMachine' import { homeMachine } from 'machines/homeMachine' import { Command, CommandSetConfig, CommandSetSchema } from 'lib/commandTypes' // This might not be necessary, AnyStateMachine from xstate is working export type AllMachines = | typeof modelingMachine | typeof settingsMachine | typeof authMachine | typeof homeMachine interface UseStateMachineCommandsArgs< T extends AllMachines, S extends CommandSetSchema > { machineId: T['id'] state: StateFrom send: Function actor?: InterpreterFrom commandBarConfig?: CommandSetConfig onCancel?: () => void } export default function useStateMachineCommands< T extends AnyStateMachine, S extends CommandSetSchema >({ machineId, state, send, actor, commandBarConfig, onCancel, }: UseStateMachineCommandsArgs) { const { commandBarSend } = useCommandsContext() useEffect(() => { const newCommands = state.nextEvents .filter((e) => !['done.', 'error.'].some((n) => e.includes(n))) .map((type) => createMachineCommand({ ownerMachine: machineId, type, state, send, actor, commandBarConfig, onCancel, }) ) .filter((c) => c !== null) as Command[] // TS isn't smart enough to know this filter removes nulls commandBarSend({ type: 'Add commands', data: { commands: newCommands } }) return () => { commandBarSend({ type: 'Remove commands', data: { commands: newCommands }, }) } }, [state]) }