Files
bug-em/node_modules/lowdb/index.js
thewesker f8c72a5a29 DMs
2016-06-18 13:24:12 -04:00

142 lines
3.3 KiB
JavaScript

'use strict';
var lodash = require('lodash');
var isPromise = require('is-promise');
// Returns a lodash chain that calls .value()
// automatically after the first .method()
//
// It also returns a promise or value
//
// For example:
// lowChain(_, array, save).method()
//
// is the same as:
// _.chain(array).method().value()
function lowChain(_, array, save) {
var chain = _.chain(array);
_.functionsIn(chain).forEach(function (method) {
chain[method] = _.flow(chain[method], function (arg) {
var v = undefined;
if (arg) {
v = _.isFunction(arg.value) ? arg.value() : arg;
}
var s = save();
if (s) return s.then(function () {
return Promise.resolve(v);
});
return v;
});
});
return chain;
}
function low(source) {
var options = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];
var writeOnChange = arguments.length <= 2 || arguments[2] === undefined ? true : arguments[2];
// Create a fresh copy of lodash
var _ = lodash.runInContext();
if (source) {
if (options.storage) {
(function () {
var storage = options.storage;
if (storage.read) {
db.read = function () {
var s = arguments.length <= 0 || arguments[0] === undefined ? source : arguments[0];
var res = storage.read(s, db.deserialize);
if (isPromise(res)) {
return res.then(function (obj) {
db.object = obj;
db._checksum = JSON.stringify(db.object);
return db;
});
}
db.object = res;
db._checksum = JSON.stringify(db.object);
return db;
};
}
if (storage.write) {
db.write = function () {
var dest = arguments.length <= 0 || arguments[0] === undefined ? source : arguments[0];
return storage.write(dest, db.object, db.serialize);
};
}
})();
}
if (options.format) {
var format = options.format;
db.serialize = format.serialize;
db.deserialize = format.deserialize;
}
}
// Modify value function to call save before returning result
_.prototype.value = _.wrap(_.prototype.value, function (value) {
var v = value.apply(this);
var s = _save();
if (s) return s.then(function () {
return Promise.resolve(v);
});
return v;
});
// Return a promise or nothing in sync mode or if the database hasn't changed
function _save() {
if (db.source && db.write && writeOnChange) {
var str = JSON.stringify(db.object);
if (str !== db._checksum) {
db._checksum = str;
return db.write(db.source, db.object);
}
}
}
function db(key) {
if (typeof db.object[key] === 'undefined') {
db.object[key] = [];
}
var array = db.object[key];
var short = lowChain(_, array, _save);
short.chain = function () {
return _.chain(array);
};
// Prevents db.write being called when just calling db('foo').value()
short.value = function () {
return db.object[key];
};
return short;
}
// Expose
db._ = _;
db.object = {};
db.source = source;
// Init
if (db.read) {
return db.read();
} else {
return db;
}
}
module.exports = low;