Skip to content

Instantly share code, notes, and snippets.

@inre
Last active November 3, 2017 08:05
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save inre/4a8a25b33923ff73299e1acd1b540057 to your computer and use it in GitHub Desktop.
Save inre/4a8a25b33923ff73299e1acd1b540057 to your computer and use it in GitHub Desktop.
const levelup = require('levelup')
const leveldown = require('leveldown')
const config = require('../config')('persistent')
const path = require('path')
const lodash = require('lodash')
const { promisify } = require('util')
const { decode, encode } = require('./de')
const openDatabase = (file, options) =>
promisify(levelup)(leveldown(file, options))
const createPersistent = async (base) => {
const file = path.format({
dir: path.normalize(config.path),
base
})
const db = await openDatabase(file)
const getDecoded = (key) =>
db.get(key, {asBuffer: false}).then((data) => decode(data))
const setEncoded = (key, value) =>
db.put(key, encode(value))
const get = async (path, options) => {
let localPath = lodash.toPath(path)
const key = localPath.shift()
try {
const hash = await getDecoded(key, options)
if (localPath.length === 0) {
return hash
}
return lodash.get(hash, localPath)
} catch (err) {
if (err.type === 'NotFoundError') {
return undefined
} else {
throw err
}
}
}
const set = async (path, value, options) => {
let localPath = lodash.toPath(path)
const key = localPath.shift()
if (localPath.length === 0) {
await setEncoded(key, value, options)
} else {
try {
let currValue = await getDecoded(key, options)
lodash.set(currValue, localPath, value)
await setEncoded(key, currValue)
} catch (err) {
if (err.type === 'NotFoundError') {
await setEncoded(key, lodash.set({}, localPath, value), options)
} else {
throw err
}
}
}
}
return {
get,
set
}
}
module.exports = createPersistent
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment