StackGenVis: Alignment of Data, Algorithms, and Models for Stacking Ensemble Learning Using Performance Metrics https://doi.org/10.1109/TVCG.2020.3030352
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
StackGenVis/frontend/node_modules/data-store/index.js

390 lines
8.2 KiB

'use strict';
/**
* Module dependencies
*/
var path = require('path');
var util = require('util');
var base = require('cache-base');
var Base = base.namespace('cache');
var debug = require('debug')('data-store');
var proto = Base.prototype;
var utils = require('./utils');
/**
* Expose `Store`
*/
module.exports = Store;
/**
* Initialize a new `Store` with the given `name`
* and `options`.
*
* ```js
* var store = require('data-store')('abc');
* //=> '~/data-store/a.json'
*
* var store = require('data-store')('abc', {
* cwd: 'test/fixtures'
* });
* //=> './test/fixtures/abc.json'
* ```
*
* @param {String} `name` Store name to use for the basename of the `.json` file.
* @param {Object} `options`
* @param {String} `options.cwd` Current working directory for storage. If not defined, the user home directory is used, based on OS. This is the only option currently, other may be added in the future.
* @param {Number} `options.indent` Number passed to `JSON.stringify` when saving the data. Defaults to `2` if `null` or `undefined`
* @api public
*/
function Store(name, options) {
if (!(this instanceof Store)) {
return new Store(name, options);
}
if (typeof name !== 'string') {
options = name;
name = null;
}
Base.call(this);
this.isStore = true;
this.options = options || {};
this.initStore(name);
}
/**
* Inherit `Base`
*/
util.inherits(Store, Base);
/**
* Initialize store defaults
*/
Store.prototype.initStore = function(name) {
this.name = name || utils.project(process.cwd());
this.cwd = utils.resolve(this.options.cwd || '~/.data-store');
this.path = path.resolve(this.cwd, this.name + '.json');
debug('Initializing store <%s>', this.path);
this.data = readFile(this.path);
this.define('cache', utils.clone(this.data));
this.on('set', function() {
this.save();
}.bind(this));
};
/**
* Create a namespaced "sub-store" that persists data to its file
* in a sub-folder of the same directory as the "parent" store.
*
* ```js
* store.create('foo');
* store.foo.set('a', 'b');
* console.log(store.foo.get('a'));
* //=> 'b'
* ```
* @param {String} `name` The name of the sub-store.
* @param {Object} `options`
* @return {Object} Returns the sub-store instance.
* @api public
*/
Store.prototype.create = function(name, options) {
if (utils.isStore(this, name)) {
return this[name];
}
utils.validateName(this, name);
var self = this;
var cwd = path.join(path.dirname(this.path), this.name);
var substore = new Store(name, { cwd: cwd });
this[name] = substore;
substore.on('set', function(key, val) {
self.set([name, key], val);
});
return substore;
};
/**
* Assign `value` to `key` and save to disk. Can be
* a key-value pair or an object.
*
* ```js
* // key, value
* store.set('a', 'b');
* //=> {a: 'b'}
*
* // extend the store with an object
* store.set({a: 'b'});
* //=> {a: 'b'}
*
* // extend the the given value
* store.set('a', {b: 'c'});
* store.set('a', {d: 'e'}, true);
* //=> {a: {b 'c', d: 'e'}}
*
* // overwrite the the given value
* store.set('a', {b: 'c'});
* store.set('a', {d: 'e'});
* //=> {d: 'e'}
* ```
* @name .set
* @param {String} `key`
* @param {any} `val` The value to save to `key`. Must be a valid JSON type: String, Number, Array or Object.
* @return {Object} `Store` for chaining
* @api public
*/
/**
* Add or append an array of unique values to the given `key`.
*
* ```js
* store.union('a', ['a']);
* store.union('a', ['b']);
* store.union('a', ['c']);
* store.get('a');
* //=> ['a', 'b', 'c']
* ```
*
* @param {String} `key`
* @return {any} The array to add or append for `key`.
* @api public
*/
Store.prototype.union = function(key, val) {
utils.union(this.cache, key, val);
this.emit('union', key, val);
this.save();
return this;
};
/**
* Get the stored `value` of `key`, or return the entire store
* if no `key` is defined.
*
* ```js
* store.set('a', {b: 'c'});
* store.get('a');
* //=> {b: 'c'}
*
* store.get();
* //=> {b: 'c'}
* ```
*
* @name .get
* @param {String} `key`
* @return {any} The value to store for `key`.
* @api public
*/
/**
* Returns `true` if the specified `key` has truthy value.
*
* ```js
* store.set('a', 'b');
* store.set('c', null);
* store.has('a'); //=> true
* store.has('c'); //=> false
* store.has('d'); //=> false
* ```
* @name .has
* @param {String} `key`
* @return {Boolean} Returns true if `key` has
* @api public
*/
/**
* Returns `true` if the specified `key` exists.
*
* ```js
* store.set('a', 'b');
* store.set('b', false);
* store.set('c', null);
* store.set('d', true);
*
* store.hasOwn('a'); //=> true
* store.hasOwn('b'); //=> true
* store.hasOwn('c'); //=> true
* store.hasOwn('d'); //=> true
* store.hasOwn('foo'); //=> false
* ```
*
* @param {String} `key`
* @return {Boolean} Returns true if `key` exists
* @api public
*/
Store.prototype.hasOwn = function(key) {
var val;
if (key.indexOf('.') === -1) {
val = this.cache.hasOwnProperty(key);
} else {
val = utils.hasOwn(this.cache, key);
}
return val;
};
/**
* Persist the store to disk.
*
* ```js
* store.save();
* ```
* @param {String} `dest` Optionally define an alternate destination file path.
* @api public
*/
Store.prototype.save = function(dest) {
this.data = this.cache;
writeJson(dest || this.path, this.cache, this.options.indent);
return this;
};
/**
* Clear in-memory cache.
*
* ```js
* store.clear();
* ```
* @api public
*/
Store.prototype.clear = function() {
this.cache = {};
this.data = {};
return this;
};
/**
* Delete `keys` from the store, or delete the entire store
* if no keys are passed. A `del` event is also emitted for each key
* deleted.
*
* **Note that to delete the entire store you must pass `{force: true}`**
*
* ```js
* store.del();
*
* // to delete paths outside cwd
* store.del({force: true});
* ```
*
* @param {String|Array|Object} `keys` Keys to remove, or options.
* @param {Object} `options`
* @api public
*/
Store.prototype.del = function(keys, options) {
var isArray = Array.isArray(keys);
if (typeof keys === 'string' || isArray) {
keys = utils.arrayify(keys);
} else {
options = keys;
keys = null;
}
options = options || {};
if (keys) {
keys.forEach(function(key) {
proto.del.call(this, key);
}.bind(this));
this.save();
return this;
}
if (options.force !== true) {
throw new Error('options.force is required to delete the entire cache.');
}
keys = Object.keys(this.cache);
this.clear();
// if no keys are passed, delete the entire store
utils.del.sync(this.path, options);
keys.forEach(function(key) {
this.emit('del', key);
}.bind(this));
return this;
};
/**
* Returns an array of all Store properties.
*/
utils.define(Store.prototype, 'keys', {
configurable: true,
enumerable: true,
set: function(keys) {
utils.define(this, 'keys', keys);
},
get: function fn() {
if (fn.keys) return fn.keys;
fn.keys = [];
for (var key in this) fn.keys.push(key);
return fn.keys;
}
});
/**
* Define a non-enumerable property on the instance.
*
* @param {String} `key`
* @param {any} `value`
* @return {Object} Returns the instance for chaining.
* @api public
*/
Store.prototype.define = function(key, value) {
utils.define(this, key, value);
return this;
};
/**
* Read JSON files.
*
* @param {String} `fp`
* @return {Object}
*/
function readFile(fp) {
try {
var str = utils.fs.readFileSync(path.resolve(fp), 'utf8');
return JSON.parse(str);
} catch (err) {}
return {};
}
/**
* Synchronously write files to disk, also creating any
* intermediary directories if they don't exist.
*
* @param {String} `dest`
* @param {String} `str`
* @param {Number} `indent` Indent passed to JSON.stringify (default 2)
*/
function writeJson(dest, str, indent) {
if (typeof indent === 'undefined' || indent === null) {
indent = 2;
}
var dir = path.dirname(dest);
try {
if (!utils.fs.existsSync(dir)) {
utils.mkdirp.sync(dir);
}
utils.fs.writeFileSync(dest, JSON.stringify(str, null, indent));
} catch (err) {
err.origin = __filename;
err.reason = 'data-store cannot write to: ' + dest;
throw new Error(err);
}
}