<commit_before>import warning from 'warning'
import { pipe, isStr } from './utils'
import { parseHref, env } from './utils-path'
import { createPopstate, push, replace, go } from './history'
import { makeVisit, recalibrate } from './visit'

function dispatcher(actions, msg) {
  let resolved = actions.some(fn => fn(msg))
  warning(resolved, 'Could not resolve location: %s', msg.href)
  return resolved
}

function getDispatcher(matchers) {
  let actions = matchers.map(matcher => pipe(matcher.match, matcher.resolve))
  return recordVisit.bind(null, dispatcher.bind(null, actions))
}

export function recordVisit(dispatch, msg) {
  let { ultra, state } = msg
  let { visited, newState } = makeVisit(ultra, state)
  ultra.visited = visited
  if (newState) {
    msg = Object.assign({}, msg, { state: newState })
    return replace(dispatch, msg)
  }
  return dispatch(msg)
}

function guardDispatch(ultra, dispatch, loc) {
  let [len, pausedHref, confirm] = ultra.pauseRecord, { href } = loc
  let msg = Object.assign({}, loc, { ultra })
  let ok = () => {
    ultra.resume()
    return dispatch(msg)
  }
  let cancel = pipe(recalibrate, go).bind(null, msg)
  if (confirm && len === env.history.length) {
    if (href !== pausedHref) return confirm(ok, cancel, msg)
  } else return ok()
}

function navigate(ultra, dispatch, navAction, loc) {
  loc = isStr(loc) ? parseHref(loc) : loc
  return guardDispatch(ultra, navAction.bind(null, dispatch), loc)
}

function run(matchers, popstate) {
  let _pauseRecord = [], dispatch = getDispatcher(matchers)
  let ultra = {
    get pauseRecord() {
      return _pauseRecord
    },
    resume() {
      return (_pauseRecord = [])
    },
    pause(cb) {
      return (_pauseRecord = [env.history.length, env.href, cb])
    },
    stop: popstate.add(loc => guardDispatch(ultra, dispatch, loc)),
    nav: (action, loc) => navigate(ultra, dispatch, action, loc),
    push: loc => ultra.nav(push, loc),
    replace: loc => ultra.nav(replace, loc),
    popstate,
    matchers
  }
  return ultra
}

function initialize(matchers, ultraOptions = {}) {
  let { stop, matchers: currentMatchers, popstate, preventCurrent } = ultraOptions
  if (stop) stop.call(ultraOptions)
  if (currentMatchers) matchers = currentMatchers.concat(matchers)
  if (!popstate) popstate = createPopstate()
  let ultra = run(matchers, popstate)
  if (!preventCurrent) ultra.nav((cb, msg) => cb(msg), env.href)
  return ultra
}

export function container(...matchers) {
  return initialize.bind(null, matchers)
}
<commit_msg>auto start rotuer if visited is not initialized<commit_after>import warning from 'warning'
import { pipe, isStr } from './utils'
import { parseHref, env } from './utils-path'
import { createPopstate, push, replace, go } from './history'
import { makeVisit, recalibrate } from './visit'

function dispatcher(actions, msg) {
  let resolved = actions.some(fn => fn(msg))
  warning(resolved, 'Could not resolve location: %s', msg.href)
  return resolved
}

function getDispatcher(matchers) {
  let actions = matchers.map(matcher => pipe(matcher.match, matcher.resolve))
  return recordVisit.bind(null, dispatcher.bind(null, actions))
}

export function recordVisit(dispatch, msg) {
  let { ultra, state } = msg
  let { visited, newState } = makeVisit(ultra, state)
  ultra.visited = visited
  if (newState) {
    msg = Object.assign({}, msg, { state: newState })
    return replace(dispatch, msg)
  }
  return dispatch(msg)
}

function guardDispatch(ultra, dispatch, loc) {
  let [len, pausedHref, confirm] = ultra.pauseRecord, { href } = loc
  let msg = Object.assign({}, loc, { ultra })
  let ok = () => {
    ultra.resume()
    return dispatch(msg)
  }
  let cancel = pipe(recalibrate, go).bind(null, msg)
  if (confirm && len === env.history.length) {
    if (href !== pausedHref) return confirm(ok, cancel, msg)
  } else return ok()
}

function navigate(ultra, dispatch, navAction, loc) {
  loc = isStr(loc) ? parseHref(loc) : loc
  return guardDispatch(ultra, navAction.bind(null, dispatch), loc)
}

function run(matchers, popstate) {
  let _pauseRecord = [], dispatch = getDispatcher(matchers)
  let ultra = {
    get pauseRecord() {
      return _pauseRecord
    },
    resume() {
      return (_pauseRecord = [])
    },
    pause(cb) {
      return (_pauseRecord = [env.history.length, env.href, cb])
    },
    stop: popstate.add(loc => guardDispatch(ultra, dispatch, loc)),
    nav: (action, loc) => navigate(ultra, dispatch, action, loc),
    push: loc => ultra.nav(push, loc),
    replace: loc => ultra.nav(replace, loc),
    visited: null,
    popstate,
    matchers
  }
  return ultra
}

function initialize(matchers, ultraOptions = {}) {
  let { stop, matchers: currentMatchers, popstate, visited } = ultraOptions
  if (currentMatchers) matchers = currentMatchers.concat(matchers)
  if (!popstate) popstate = createPopstate()
  if (stop) stop.call(ultraOptions)
  let ultra = run(matchers, popstate)
  if (!visited) ultra.nav((cb, msg) => cb(msg), env.href)
  return ultra
}

export function container(...matchers) {
  return initialize.bind(null, matchers)
}

{'fraction_non_alphanumeric': 0.13986287952987267, 'fraction_numerical': 0.0, 'mean_word_length': 3.986328125, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 19, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1599749', 'n_tokens_mistral': 1638, 'n_tokens_neox': 1634, 'n_words': 447}