/*
Setting a new state will start a transition from the current state to the target state.
A successful transition will result in the URL being changed.
A failed transition will leave the router in its current state.
function setState(state, params, acc) {
    const fromState = transition
      ? StateWithParams(transition.currentState, transition.toParams)
      : currentState

    const diff = util.objectDiff(fromState && fromState.params, params)

    const toState = StateWithParams(state, params, currentPathQuery, diff)

    if (preventTransition(fromState, toState, diff)) {
      if (transition && transition.exiting) cancelTransition()
      return
    }

    if (transition) cancelTransition()

    // While the transition is running, any code asking the router about the previous/current state should
    // get the end result state.
    previousState = currentState
    currentState = toState
    currentParamsDiff = diff

    transition = Transition(
      fromState,
      toState,
      diff,
      acc,
      router,
      logger
    )

    startingTransition(fromState, toState)

    // In case of a redirect() called from 'startingTransition', the transition already ended.
    if (transition) transition.run()

    // In case of a redirect() called from the transition itself, the transition already ended
    if (transition) {
      if (transition.cancelled) currentState = fromState
      else endingTransition(fromState, toState)
    }

    transition = null
  }