chain-able
Version:
interfaces that describe their intentions.
153 lines (137 loc) • 13.5 kB
JavaScript
// without it, the arguments & caller are uglier when drbugging
var isSet = require('../is/set')
var ArrayFrom = require('../util/from')
var isUndefined = require('../is/undefined')
var concat = require('../concat')
var toarr = require('../to-arr')
var TRANSFORMERS_KEY = require('./transformers')
var OBSERVERS_KEY = require('./observers')
var SHORTHANDS_KEY = require('./shorthands')
var DECORATED_KEY = require('./decorated')
// will expand this later
var isInKeyMapAsSet = function (x) { return x === OBSERVERS_KEY; }
// @NOTE: using `[]` deopts o.o
// eslint-disable-next-line
// this.shorthands = new Array()
/**
* @since 4.0.0
* @param {Chain} _this
* @return {Chain}
*/
function getMeta(_this) {
// if we already have it, keep it
if (_this.meta) { return _this.meta }
// the store
// shorthands: key -> method
var store = {}
// --- uglifiable functions
/** @desc initialize the store maps when we need them */
/* prettier-ignore */
var ensureInitialized = function (name, value) {
if (!isUndefined(store[name])) { return }
// if (
// name === TRANSFORMERS_KEY ||
// name === SHORTHANDS_KEY ||
// name === DECORATED_KEY
// ) {
// store[name] = new Map()
// }
// else
if (isInKeyMapAsSet(name)) {
store[name] = new Set()
}
else {
store[name] = new Map()
}
}
/**
* @since 4.0.0
* @param {Primitive} key
* @param {Primitive | undefined} [prop=undefined]
* @return {boolean}
*/
var has = function (key, prop) {
if (isUndefined(prop)) { return !!store[key].size }
else { return store[key].has(prop) }
}
/**
* @since 4.0.0
* @param {Primitive} key
* @param {Primitive | undefined} [prop=undefined]
* @return {any}
*/
var get = function (key, prop) { return (has(key, prop) ? store[key].get(prop) : []); }
/**
* @since 4.0.0
* @param {Primitive} key
* @param {Primitive | undefined} [prop=undefined]
* @param {Primitive | undefined} [value=undefined]
* @return {void}
*/
var set = function (key, prop, value) {
var storage = store[key]
// when it's a set, we have no `prop`, we just have .add
// so `prop = value` && `value = undefined`
if (isSet(storage)) {
storage.add(prop)
}
else {
// if (!has(key, prop)) return
var existing = storage.get(prop)
var val = concat(existing, value)
storage.set(prop, val)
}
}
/**
* @since 4.0.0
*
* @desc a single easily minifiable function,
* dynamically setting & getting depending on arguments
* to avoid nested property accessing
* only instantiating when values are **addded**
*
* @param {Primitive} key
* @param {Primitive | undefined} [prop=undefined]
* @param {undefined | any} [value=undefined] (when no value, it's a getter)
* @return {Array | Chain} depending on args
*/
function meta(key, prop, value) {
if (process.env.NODE_ENV === 'DEBUG') {
console.log('USING META', {key: key, prop: prop, value: value})
}
/* prettier-ignore */
if (isUndefined(value)) {
// when we want to just access the property, return an array
// @example `.meta('transformers')`
if (isUndefined(prop)) {
if (isUndefined(store[key])) { return [] }
else { return store[key].size === 0 ? [] : ArrayFrom(store[key].values()) }
}
// we have `key, prop`
//
// 1: should `prop` be a value, (isSet?)
else if (isInKeyMapAsSet(key)) {
ensureInitialized(key)
set(key, prop)
}
// 2: prop is a key, we want to return the [..] for that specific property
// @example `.meta('transformers', 'eh')`
else if (isUndefined(store[key])) { return [] }
else { return toarr(get(key, prop)) }
}
// we have `key, prop, value`
else {
ensureInitialized(key)
// we have a value, let's add it
set(key, prop, value)
}
return _this
}
// for debugging
meta.store = store
// meta.debug = false
return meta
}
module.exports = getMeta
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWV0YS5qcyIsInNvdXJjZXMiOlsibWV0YS5qcyJdLCJzb3VyY2VzQ29udGVudCI6WyIvLyB3aXRob3V0IGl0LCB0aGUgYXJndW1lbnRzICYgY2FsbGVyIGFyZSB1Z2xpZXIgd2hlbiBkcmJ1Z2dpbmdcbid1c2Ugc3RyaWN0J1xuXG5jb25zdCBpc1NldCA9IHJlcXVpcmUoJy4uL2lzL3NldCcpXG5jb25zdCBBcnJheUZyb20gPSByZXF1aXJlKCcuLi91dGlsL2Zyb20nKVxuY29uc3QgaXNVbmRlZmluZWQgPSByZXF1aXJlKCcuLi9pcy91bmRlZmluZWQnKVxuY29uc3QgY29uY2F0ID0gcmVxdWlyZSgnLi4vY29uY2F0JylcbmNvbnN0IHRvYXJyID0gcmVxdWlyZSgnLi4vdG8tYXJyJylcbmNvbnN0IFRSQU5TRk9STUVSU19LRVkgPSByZXF1aXJlKCcuL3RyYW5zZm9ybWVycycpXG5jb25zdCBPQlNFUlZFUlNfS0VZID0gcmVxdWlyZSgnLi9vYnNlcnZlcnMnKVxuY29uc3QgU0hPUlRIQU5EU19LRVkgPSByZXF1aXJlKCcuL3Nob3J0aGFuZHMnKVxuY29uc3QgREVDT1JBVEVEX0tFWSA9IHJlcXVpcmUoJy4vZGVjb3JhdGVkJylcblxuLy8gd2lsbCBleHBhbmQgdGhpcyBsYXRlclxuY29uc3QgaXNJbktleU1hcEFzU2V0ID0geCA9PiB4ID09PSBPQlNFUlZFUlNfS0VZXG5cbi8vIEBOT1RFOiB1c2luZyBgW11gIGRlb3B0cyBvLm9cbi8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZVxuLy8gdGhpcy5zaG9ydGhhbmRzID0gbmV3IEFycmF5KClcblxuLyoqXG4gKiBAc2luY2UgIDQuMC4wXG4gKiBAcGFyYW0gIHtDaGFpbn0gX3RoaXNcbiAqIEByZXR1cm4ge0NoYWlufVxuICovXG5mdW5jdGlvbiBnZXRNZXRhKF90aGlzKSB7XG4gIC8vIGlmIHdlIGFscmVhZHkgaGF2ZSBpdCwga2VlcCBpdFxuICBpZiAoX3RoaXMubWV0YSkgcmV0dXJuIF90aGlzLm1ldGFcblxuICAvLyB0aGUgc3RvcmVcbiAgLy8gc2hvcnRoYW5kczoga2V5IC0+IG1ldGhvZFxuICBjb25zdCBzdG9yZSA9IHt9XG5cbiAgLy8gLS0tIHVnbGlmaWFibGUgZnVuY3Rpb25zXG5cbiAgLyoqIEBkZXNjIGluaXRpYWxpemUgdGhlIHN0b3JlIG1hcHMgd2hlbiB3ZSBuZWVkIHRoZW0gKi9cbiAgLyogcHJldHRpZXItaWdub3JlICovXG4gIGNvbnN0IGVuc3VyZUluaXRpYWxpemVkID0gKG5hbWUsIHZhbHVlKSA9PiB7XG4gICAgaWYgKCFpc1VuZGVmaW5lZChzdG9yZVtuYW1lXSkpIHJldHVyblxuXG4gICAgLy8gaWYgKFxuICAgIC8vICAgbmFtZSA9PT0gVFJBTlNGT1JNRVJTX0tFWSB8fFxuICAgIC8vICAgbmFtZSA9PT0gU0hPUlRIQU5EU19LRVkgfHxcbiAgICAvLyAgIG5hbWUgPT09IERFQ09SQVRFRF9LRVlcbiAgICAvLyApIHtcbiAgICAvLyAgIHN0b3JlW25hbWVdID0gbmV3IE1hcCgpXG4gICAgLy8gfVxuICAgIC8vIGVsc2VcbiAgICBpZiAoaXNJbktleU1hcEFzU2V0KG5hbWUpKSB7XG4gICAgICBzdG9yZVtuYW1lXSA9IG5ldyBTZXQoKVxuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgIHN0b3JlW25hbWVdID0gbmV3IE1hcCgpXG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEBzaW5jZSAgNC4wLjBcbiAgICogQHBhcmFtICB7UHJpbWl0aXZlfSBrZXlcbiAgICogQHBhcmFtICB7UHJpbWl0aXZlIHwgdW5kZWZpbmVkfSBbcHJvcD11bmRlZmluZWRdXG4gICAqIEByZXR1cm4ge2Jvb2xlYW59XG4gICAqL1xuICBjb25zdCBoYXMgPSAoa2V5LCBwcm9wKSA9PiB7XG4gICAgaWYgKGlzVW5kZWZpbmVkKHByb3ApKSByZXR1cm4gISFzdG9yZVtrZXldLnNpemVcbiAgICBlbHNlIHJldHVybiBzdG9yZVtrZXldLmhhcyhwcm9wKVxuICB9XG4gIC8qKlxuICAgKiBAc2luY2UgIDQuMC4wXG4gICAqIEBwYXJhbSAge1ByaW1pdGl2ZX0ga2V5XG4gICAqIEBwYXJhbSAge1ByaW1pdGl2ZSB8IHVuZGVmaW5lZH0gW3Byb3A9dW5kZWZpbmVkXVxuICAgKiBAcmV0dXJuIHthbnl9XG4gICAqL1xuICBjb25zdCBnZXQgPSAoa2V5LCBwcm9wKSA9PiAoaGFzKGtleSwgcHJvcCkgPyBzdG9yZVtrZXldLmdldChwcm9wKSA6IFtdKVxuXG4gIC8qKlxuICAgKiBAc2luY2UgIDQuMC4wXG4gICAqIEBwYXJhbSAge1ByaW1pdGl2ZX0ga2V5XG4gICAqIEBwYXJhbSAge1ByaW1pdGl2ZSB8IHVuZGVmaW5lZH0gW3Byb3A9dW5kZWZpbmVkXVxuICAgKiBAcGFyYW0gIHtQcmltaXRpdmUgfCB1bmRlZmluZWR9IFt2YWx1ZT11bmRlZmluZWRdXG4gICAqIEByZXR1cm4ge3ZvaWR9XG4gICAqL1xuICBjb25zdCBzZXQgPSAoa2V5LCBwcm9wLCB2YWx1ZSkgPT4ge1xuICAgIGNvbnN0IHN0b3JhZ2UgPSBzdG9yZVtrZXldXG4gICAgLy8gd2hlbiBpdCdzIGEgc2V0LCB3ZSBoYXZlIG5vIGBwcm9wYCwgd2UganVzdCBoYXZlIC5hZGRcbiAgICAvLyBzbyBgcHJvcCA9IHZhbHVlYCAmJiBgdmFsdWUgPSB1bmRlZmluZWRgXG4gICAgaWYgKGlzU2V0KHN0b3JhZ2UpKSB7XG4gICAgICBzdG9yYWdlLmFkZChwcm9wKVxuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgIC8vIGlmICghaGFzKGtleSwgcHJvcCkpIHJldHVyblxuICAgICAgY29uc3QgZXhpc3RpbmcgPSBzdG9yYWdlLmdldChwcm9wKVxuICAgICAgY29uc3QgdmFsID0gY29uY2F0KGV4aXN0aW5nLCB2YWx1ZSlcbiAgICAgIHN0b3JhZ2Uuc2V0KHByb3AsIHZhbClcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQHNpbmNlIDQuMC4wXG4gICAqXG4gICAqIEBkZXNjIGEgc2luZ2xlIGVhc2lseSBtaW5pZmlhYmxlIGZ1bmN0aW9uLFxuICAgKiAgICAgICBkeW5hbWljYWxseSBzZXR0aW5nICYgZ2V0dGluZyBkZXBlbmRpbmcgb24gYXJndW1lbnRzXG4gICAqICAgICAgIHRvIGF2b2lkIG5lc3RlZCBwcm9wZXJ0eSBhY2Nlc3NpbmdcbiAgICogICAgICAgb25seSBpbnN0YW50aWF0aW5nIHdoZW4gdmFsdWVzIGFyZSAqKmFkZGRlZCoqXG4gICAqXG4gICAqIEBwYXJhbSB7UHJpbWl0aXZlfSBrZXlcbiAgICogQHBhcmFtIHtQcmltaXRpdmUgfCB1bmRlZmluZWR9IFtwcm9wPXVuZGVmaW5lZF1cbiAgICogQHBhcmFtIHt1bmRlZmluZWQgfCBhbnl9IFt2YWx1ZT11bmRlZmluZWRdICh3aGVuIG5vIHZhbHVlLCBpdCdzIGEgZ2V0dGVyKVxuICAgKiBAcmV0dXJuIHtBcnJheSB8IENoYWlufSBkZXBlbmRpbmcgb24gYXJnc1xuICAgKi9cbiAgZnVuY3Rpb24gbWV0YShrZXksIHByb3AsIHZhbHVlKSB7XG4gICAgaWYgKHByb2Nlc3MuZW52Lk5PREVfRU5WID09PSAnREVCVUcnKSB7XG4gICAgICBjb25zb2xlLmxvZygnVVNJTkcgTUVUQScsIHtrZXksIHByb3AsIHZhbHVlfSlcbiAgICB9XG5cbiAgICAvKiBwcmV0dGllci1pZ25vcmUgKi9cbiAgICBpZiAoaXNVbmRlZmluZWQodmFsdWUpKSB7XG4gICAgICAvLyB3aGVuIHdlIHdhbnQgdG8ganVzdCBhY2Nlc3MgdGhlIHByb3BlcnR5LCByZXR1cm4gYW4gYXJyYXlcbiAgICAgIC8vIEBleGFtcGxlIGAubWV0YSgndHJhbnNmb3JtZXJzJylgXG4gICAgICBpZiAoaXNVbmRlZmluZWQocHJvcCkpIHtcbiAgICAgICAgaWYgKGlzVW5kZWZpbmVkKHN0b3JlW2tleV0pKSByZXR1cm4gW11cbiAgICAgICAgZWxzZSByZXR1cm4gc3RvcmVba2V5XS5zaXplID09PSAwID8gW10gOiBBcnJheUZyb20oc3RvcmVba2V5XS52YWx1ZXMoKSlcbiAgICAgIH1cbiAgICAgIC8vIHdlIGhhdmUgYGtleSwgcHJvcGBcbiAgICAgIC8vXG4gICAgICAvLyAxOiBzaG91bGQgYHByb3BgIGJlIGEgdmFsdWUsIChpc1NldD8pXG4gICAgICBlbHNlIGlmIChpc0luS2V5TWFwQXNTZXQoa2V5KSkge1xuICAgICAgICBlbnN1cmVJbml0aWFsaXplZChrZXkpXG4gICAgICAgIHNldChrZXksIHByb3ApXG4gICAgICB9XG4gICAgICAvLyAyOiBwcm9wIGlzIGEga2V5LCB3ZSB3YW50IHRvIHJldHVybiB0aGUgWy4uXSBmb3IgdGhhdCBzcGVjaWZpYyBwcm9wZXJ0eVxuICAgICAgLy8gQGV4YW1wbGUgYC5tZXRhKCd0cmFuc2Zvcm1lcnMnLCAnZWgnKWBcbiAgICAgIGVsc2UgaWYgKGlzVW5kZWZpbmVkKHN0b3JlW2tleV0pKSByZXR1cm4gW11cbiAgICAgIGVsc2UgcmV0dXJuIHRvYXJyKGdldChrZXksIHByb3ApKVxuICAgIH1cbiAgICAvLyB3ZSBoYXZlIGBrZXksIHByb3AsIHZhbHVlYFxuICAgIGVsc2Uge1xuICAgICAgZW5zdXJlSW5pdGlhbGl6ZWQoa2V5KVxuICAgICAgLy8gd2UgaGF2ZSBhIHZhbHVlLCBsZXQncyBhZGQgaXRcbiAgICAgIHNldChrZXksIHByb3AsIHZhbHVlKVxuICAgIH1cbiAgICByZXR1cm4gX3RoaXNcbiAgfVxuXG4gIC8vIGZvciBkZWJ1Z2dpbmdcbiAgbWV0YS5zdG9yZSA9IHN0b3JlXG4gIC8vIG1ldGEuZGVidWcgPSBmYWxzZVxuXG4gIHJldHVybiBtZXRhXG59XG5cbm1vZHVsZS5leHBvcnRzID0gZ2V0TWV0YVxuIl0sIm5hbWVzIjpbImNvbnN0Il0sIm1hcHBpbmdzIjoiQUFBQTtBQUNBLFlBQVk7O0FBRVpBLEdBQUssQ0FBQyxLQUFLLEdBQUcsT0FBTyxDQUFDLFdBQVcsQ0FBQztBQUNsQ0EsR0FBSyxDQUFDLFNBQVMsR0FBRyxPQUFPLENBQUMsY0FBYyxDQUFDO0FBQ3pDQSxHQUFLLENBQUMsV0FBVyxHQUFHLE9BQU8sQ0FBQyxpQkFBaUIsQ0FBQztBQUM5Q0EsR0FBSyxDQUFDLE1BQU0sR0FBRyxPQUFP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