<commit_before>import fs from 'fs'
import _ from 'lodash'
import {homedir} from 'os'

const HISTORY_SIZE = 30
const HISTORY_FILE = `${homedir()}/.routahe_history`

async function addToHistory(...addresses) {
	let history = await readHistory()
	history = [...addresses, ...history]
	history = _.uniq(history)
	history = history.slice(0, HISTORY_SIZE)
	return writeFileAsync(HISTORY_FILE, JSON.stringify(history))	
}

async function readHistory() {
	try {
		const text = await readFileAsync(HISTORY_FILE)
		return JSON.parse(text)
	} catch (err) {
		if (err.code === 'ENOENT') {  // history does't exist yet
			return []
		} else {
			return err
		}
	}
}

function readFileAsync(file) {
	return new Promise((resolve, reject) => {
		fs.readFile(file, 'utf8', (err, text) => {
			if (err) return reject(err)
			resolve(text)
		})
	})
}

function writeFileAsync(file, data) {
	return new Promise((resolve, reject) => {
		fs.writeFile(file, data, (err) => {
		  if (err) return reject(err)
			resolve()
		})
	})
}

export default {
	add: addToHistory,
	get: readHistory
}<commit_msg>Save routes instead of addresses. Implement queries for latest and top routes.<commit_after>import fs from 'fs'
import {homedir} from 'os'

const HISTORY_FILE = `${homedir()}/.routahe_history`

async function addToHistory(from, to) {
  const history = await readHistory()
  const route = history.find((route) => route.from.toLowerCase() === from.toLowerCase()
                                     && route.to.toLowerCase() === to.toLowerCase() )
  if (route) {
    route.count += 1
    route.timestamp = Date.now()
  } else {
    const newRoute = {
      from,
      to,
      timestamp: Date.now(),
      count: 1
    }
    history.push(newRoute)
  }
  return writeFileAsync(HISTORY_FILE, JSON.stringify(history))  
}

async function readHistory() {
  try {
    const text = await readFileAsync(HISTORY_FILE, 'utf8')
    return JSON.parse(text)
  } catch (err) {
    if (err.code === 'ENOENT') {
      return []
    } else {
      throw err
    }
  }
}

async function latestRoute() {
  return getRouteBy((r1, r2) => r2.timestamp - r1.timestamp)
}

async function topRoute() {
  return getRouteBy((r1, r2) => r2.count - r1.count)  
}

async function getRouteBy(sortFunction) {
  const history = await readHistory()
  history.sort(sortFunction)
  return history[0] || null
}

async function readFileAsync(file, encoding) {
  return new Promise((resolve, reject) => fs.readFile(file, encoding, (err, text) => err ? reject(err) : resolve(text)))
}

async function writeFileAsync(file, data) {
  return new Promise((resolve, reject) => fs.writeFile(file, data, (err) => err ? reject(err) : resolve()))
}

export default {
  add: addToHistory,
  get: readHistory,
  latestRoute,
  topRoute
}
{'fraction_non_alphanumeric': 0.14073806078147613, 'fraction_numerical': 0.005788712011577424, 'mean_word_length': 3.5702479338842976, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 14, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 1, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2171268', 'n_tokens_mistral': 951, 'n_tokens_neox': 931, 'n_words': 234}