JSFiddle - React, Tailwind, and code Playground

by joplomacedo

JavaScript

function createStateMachine(options) {
  const {
    initialState,
    onChange
  } = options;

  let state = initialState;

  return {
    setState(newState) {
      let oldState = state;
      state = newState;

      const oldStateHandlers = onChange[oldState];
      const newStateHandlers = onChange[newState];

      // EXECUTE LEAVE HANDLER
      if (typeof oldStateHandlers === 'object') {
        if (typeof oldStateHandlers.onLeave === 'function') {
          oldStateHandlers.onLeave(newState, oldState);
        }
      }

      // EXECUTE ENTER HANDLER
      if (typeof newStateHandlers === 'object') {
        if (typeof newStateHandlers.onEnter === 'function') {
          newStateHandlers.onEnter(newState, oldState);
        }

      } else if (typeof newStateHandlers === 'function') {
        let newStateHandlersOnEnter = newStateHandlers;
        newStateHandlersOnEnter(newState, oldState);
      }

    },
    getState() {
      return state;
    }
  }

}




stateMachine = createStateMachine({
  initialState: 'first',
  onChange: {
    'second'(state) {
      alert(`Entered state: ${state}`);
    },
    'third': {
      onEnter(state) {
        alert(`Entered state: ${state}`);
      }
    },
    'fourth': {
      onEnter(state) {
        alert(`Entered state: ${state}`);
      },
      onLeave(newState, oldState) {
        alert(`Left state: ${oldState}`);
      },
    },
    'final'(state) {
      alert(`Entered state: ${state}`);
    }
  }
})

function tryIt() {
  alert(stateMachine.getState());
  setTimeout(() => {
    stateMachine.setState('second');

    setTimeout(() => {
      stateMachine.setState('third');


      setTimeout(() => {
        stateMachine.setState('fourth');


        setTimeout(() => {
          stateMachine.setState('final');
        }, 1000)
      }, 1000)


    }, 1000)
  }, 1000)
}


tryIt()