foop
Version:
interfaces that describe their intentions.
193 lines (170 loc) • 17.1 kB
JavaScript
/**
* @file without it, the arguments & caller are uglier when debugging
* @TODO freeze store props
* @TODO callsites are super polymorphic
*/
var ENV_DEBUG = require('../env/debug')
var EMPTY_ARRAY = require('../native/EMPTY_ARRAY')
var isSet = require('../is/set')
var hasOwnProperty = require('../util/hasOwnProperty')
var iteratorToArray = require('../cast/iteratorToArray')
var ArrayFrom = require('../util/from')
var isUndefined = require('../is/undefined')
var concat = require('../array/concat')
var toarr = require('../to-arr')
var size = require('../util/size')
var TRANSFORMERS_KEY = require('./TRANSFORMERS_KEY')
var OBSERVERS_KEY = require('./OBSERVERS_KEY')
var SHORTHANDS_KEY = require('./SHORTHANDS_KEY')
var DECORATED_KEY = require('./DECORATED_KEY')
// 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 (hasOwnProperty(_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 !!size(store[key]) }
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)
: EMPTY_ARRAY
); }
/**
* @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) {
/* prettier-ignore */
if (isUndefined(value)) {
// when we want to just access the property, return an array
// @example `.meta('transformers')`
if (isUndefined(prop)) {
if (ENV_DEBUG) {
console.log('META_CALL_GETTER', {[key]: store[key]})
}
if (isUndefined(store[key])) { return EMPTY_ARRAY }
else { return size(store[key]) === 0
? EMPTY_ARRAY
: ArrayFrom(store[key]) }
}
// we have `key, prop`
//
// 1: should `prop` be a value, (isSet?)
else if (isInKeyMapAsSet(key)) {
ensureInitialized(key)
set(key, prop)
if (ENV_DEBUG) {
console.log('META_CALL_SET_SETTER', {key: key, value: prop, store: store})
}
}
// 2: prop is a key, we want to return the [..] for that specific property
// @example `.meta('transformers', 'eh')`
else if (isUndefined(store[key])) { return EMPTY_ARRAY }
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)
if (ENV_DEBUG) {
console.log('META_CALL_MAP_SETTER', {key: key, prop: prop, value: value, store: store})
}
}
return _this
}
// for debugging
meta.store = store
// @NOTE not really needed, can just do `meta.store.[prop].clear`
// meta.clear = prop => meta.store[prop].clear()
// @TODO use `remove` here, so it will delete say, index
//
// @example store.transformers = Map({eh: [transformer, anotherTransformer]})
// store.delete('transformers.eh[0]')
//
// @example store.observers = Map({eh: [transformer, anotherTransformer]})
// store.delete('observers[-1]')
//
// eslint-disable-next-line
// meta['delete'] = (prop, valueOrKey) => meta.store[prop].delete(valueOrKey)
// default value
// meta.debug = false
return meta
}
module.exports = getMeta
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWV0YS5qcyIsInNvdXJjZXMiOlsibWV0YS5qcyJdLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEBmaWxlIHdpdGhvdXQgaXQsIHRoZSBhcmd1bWVudHMgJiBjYWxsZXIgYXJlIHVnbGllciB3aGVuIGRlYnVnZ2luZ1xuICogQFRPRE8gZnJlZXplIHN0b3JlIHByb3BzXG4gKiBAVE9ETyBjYWxsc2l0ZXMgYXJlIHN1cGVyIHBvbHltb3JwaGljXG4gKi9cblxuY29uc3QgRU5WX0RFQlVHID0gcmVxdWlyZSgnLi4vZW52L2RlYnVnJylcbmNvbnN0IEVNUFRZX0FSUkFZID0gcmVxdWlyZSgnLi4vbmF0aXZlL0VNUFRZX0FSUkFZJylcbmNvbnN0IGlzU2V0ID0gcmVxdWlyZSgnLi4vaXMvc2V0JylcbmNvbnN0IGhhc093blByb3BlcnR5ID0gcmVxdWlyZSgnLi4vdXRpbC9oYXNPd25Qcm9wZXJ0eScpXG5jb25zdCBpdGVyYXRvclRvQXJyYXkgPSByZXF1aXJlKCcuLi9jYXN0L2l0ZXJhdG9yVG9BcnJheScpXG5jb25zdCBBcnJheUZyb20gPSByZXF1aXJlKCcuLi91dGlsL2Zyb20nKVxuY29uc3QgaXNVbmRlZmluZWQgPSByZXF1aXJlKCcuLi9pcy91bmRlZmluZWQnKVxuY29uc3QgY29uY2F0ID0gcmVxdWlyZSgnLi4vYXJyYXkvY29uY2F0JylcbmNvbnN0IHRvYXJyID0gcmVxdWlyZSgnLi4vdG8tYXJyJylcbmNvbnN0IHNpemUgPSByZXF1aXJlKCcuLi91dGlsL3NpemUnKVxuY29uc3QgVFJBTlNGT1JNRVJTX0tFWSA9IHJlcXVpcmUoJy4vVFJBTlNGT1JNRVJTX0tFWScpXG5jb25zdCBPQlNFUlZFUlNfS0VZID0gcmVxdWlyZSgnLi9PQlNFUlZFUlNfS0VZJylcbmNvbnN0IFNIT1JUSEFORFNfS0VZID0gcmVxdWlyZSgnLi9TSE9SVEhBTkRTX0tFWScpXG5jb25zdCBERUNPUkFURURfS0VZID0gcmVxdWlyZSgnLi9ERUNPUkFURURfS0VZJylcblxuLy8gd2lsbCBleHBhbmQgdGhpcyBsYXRlclxuY29uc3QgaXNJbktleU1hcEFzU2V0ID0geCA9PiB4ID09PSBPQlNFUlZFUlNfS0VZXG5cbi8vIEBOT1RFOiB1c2luZyBgW11gIGRlb3B0cyBvLm9cbi8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZVxuLy8gdGhpcy5zaG9ydGhhbmRzID0gbmV3IEFycmF5KClcblxuLyoqXG4gKiBAc2luY2UgIDQuMC4wXG4gKiBAcGFyYW0gIHtDaGFpbn0gX3RoaXNcbiAqIEByZXR1cm4ge0NoYWlufVxuICovXG5mdW5jdGlvbiBnZXRNZXRhKF90aGlzKSB7XG4gIC8vIGlmIHdlIGFscmVhZHkgaGF2ZSBpdCwga2VlcCBpdFxuICBpZiAoaGFzT3duUHJvcGVydHkoX3RoaXMsICdtZXRhJykpIHJldHVybiBfdGhpcy5tZXRhXG5cbiAgLy8gdGhlIHN0b3JlXG4gIC8vIHNob3J0aGFuZHM6IGtleSAtPiBtZXRob2RcbiAgY29uc3Qgc3RvcmUgPSB7fVxuXG4gIC8vIC0tLSB1Z2xpZmlhYmxlIGZ1bmN0aW9uc1xuXG4gIC8qKiBAZGVzYyBpbml0aWFsaXplIHRoZSBzdG9yZSBtYXBzIHdoZW4gd2UgbmVlZCB0aGVtICovXG4gIC8qIHByZXR0aWVyLWlnbm9yZSAqL1xuICBjb25zdCBlbnN1cmVJbml0aWFsaXplZCA9IChuYW1lLCB2YWx1ZSkgPT4ge1xuICAgIGlmICghaXNVbmRlZmluZWQoc3RvcmVbbmFtZV0pKSByZXR1cm5cblxuICAgIC8vIGlmIChcbiAgICAvLyAgIG5hbWUgPT09IFRSQU5TRk9STUVSU19LRVkgfHxcbiAgICAvLyAgIG5hbWUgPT09IFNIT1JUSEFORFNfS0VZIHx8XG4gICAgLy8gICBuYW1lID09PSBERUNPUkFURURfS0VZXG4gICAgLy8gKSB7XG4gICAgLy8gICBzdG9yZVtuYW1lXSA9IG5ldyBNYXAoKVxuICAgIC8vIH1cbiAgICAvLyBlbHNlXG4gICAgaWYgKGlzSW5LZXlNYXBBc1NldChuYW1lKSkge1xuICAgICAgc3RvcmVbbmFtZV0gPSBuZXcgU2V0KClcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICBzdG9yZVtuYW1lXSA9IG5ldyBNYXAoKVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBAc2luY2UgIDQuMC4wXG4gICAqIEBwYXJhbSAge1ByaW1pdGl2ZX0ga2V5XG4gICAqIEBwYXJhbSAge1ByaW1pdGl2ZSB8IHVuZGVmaW5lZH0gW3Byb3A9dW5kZWZpbmVkXVxuICAgKiBAcmV0dXJuIHtib29sZWFufVxuICAgKi9cbiAgY29uc3QgaGFzID0gKGtleSwgcHJvcCkgPT4ge1xuICAgIGlmIChpc1VuZGVmaW5lZChwcm9wKSkgcmV0dXJuICEhc2l6ZShzdG9yZVtrZXldKVxuICAgIGVsc2UgcmV0dXJuIHN0b3JlW2tleV0uaGFzKHByb3ApXG4gIH1cbiAgLyoqXG4gICAqIEBzaW5jZSAgNC4wLjBcbiAgICogQHBhcmFtICB7UHJpbWl0aXZlfSBrZXlcbiAgICogQHBhcmFtICB7UHJpbWl0aXZlIHwgdW5kZWZpbmVkfSBbcHJvcD11bmRlZmluZWRdXG4gICAqIEByZXR1cm4ge2FueX1cbiAgICovXG4gIGNvbnN0IGdldCA9IChrZXksIHByb3ApID0+IChcbiAgICBoYXMoa2V5LCBwcm9wKVxuICAgICAgPyBzdG9yZVtrZXldLmdldChwcm9wKVxuICAgICAgOiBFTVBUWV9BUlJBWVxuICApXG5cbiAgLyoqXG4gICAqIEBzaW5jZSAgNC4wLjBcbiAgICogQHBhcmFtICB7UHJpbWl0aXZlfSBrZXlcbiAgICogQHBhcmFtICB7UHJpbWl0aXZlIHwgdW5kZWZpbmVkfSBbcHJvcD11bmRlZmluZWRdXG4gICAqIEBwYXJhbSAge1ByaW1pdGl2ZSB8IHVuZGVmaW5lZH0gW3ZhbHVlPXVuZGVmaW5lZF1cbiAgICogQHJldHVybiB7dm9pZH1cbiAgICovXG4gIGNvbnN0IHNldCA9IChrZXksIHByb3AsIHZhbHVlKSA9PiB7XG4gICAgY29uc3Qgc3RvcmFnZSA9IHN0b3JlW2tleV1cblxuICAgIC8vIHdoZW4gaXQncyBhIHNldCwgd2UgaGF2ZSBubyBgcHJvcGAsIHdlIGp1c3QgaGF2ZSAuYWRkXG4gICAgLy8gc28gYHByb3AgPSB2YWx1ZWAgJiYgYHZhbHVlID0gdW5kZWZpbmVkYFxuICAgIGlmIChpc1NldChzdG9yYWdlKSkge1xuICAgICAgc3RvcmFnZS5hZGQocHJvcClcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICAvLyBpZiAoIWhhcyhrZXksIHByb3ApKSByZXR1cm5cbiAgICAgIGNvbnN0IGV4aXN0aW5nID0gc3RvcmFnZS5nZXQocHJvcClcbiAgICAgIGNvbnN0IHZhbCA9IGNvbmNhdChleGlzdGluZywgdmFsdWUpXG4gICAgICBzdG9yYWdlLnNldChwcm9wLCB2YWwpXG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEBzaW5jZSA0LjAuMFxuICAgKlxuICAgKiBAZGVzYyBhIHNpbmdsZSBlYXNpbHkgbWluaWZpYWJsZSBmdW5jdGlvbixcbiAgICogICAgICAgZHluYW1pY2FsbHkgc2V0dGluZyAmIGdldHRpbmcgZGVwZW5kaW5nIG9uIGFyZ3VtZW50c1xuICAgKiAgICAgICB0byBhdm9pZCBuZXN0ZWQgcHJvcGVydHkgYWNjZXNzaW5nXG4gICAqICAgICAgIG9ubHkgaW5zdGFudGlhdGluZyB3aGVuIHZhbHVlcyBhcmUgKiphZGRkZWQqKlxuICAgKlxuICAgKiBAcGFyYW0ge1ByaW1pdGl2ZX0ga2V5XG4gICAqIEBwYXJhbSB7UHJpbWl0aXZlIHwgdW5kZWZpbmVkfSBbcHJvcD11bmRlZmluZWRdXG4gICAqIEBwYXJhbSB7dW5kZWZpbmVkIHwgYW55fSBbdmFsdWU9dW5kZWZpbmVkXSAod2hlbiBubyB2YWx1ZSwgaXQncyBhIGdldHRlcilcbiAgICogQHJldHVybiB7QXJyYXkgfCBDaGFpbn0gZGVwZW5kaW5nIG9uIGFyZ3NcbiAgICovXG4gIGZ1bmN0aW9uIG1ldGEoa2V5LCBwcm9wLCB2YWx1ZSkge1xuICAgIC8qIHByZXR0aWVyLWlnbm9yZSAqL1xuICAgIGlmIChpc1VuZGVmaW5lZCh2YWx1ZSkpIHtcbiAgICAgIC8vIHdoZW4gd2Ugd2FudCB0byBqdXN0IGFjY2VzcyB0aGUgcHJvcGVydHksIHJldHVybiBhbiBhcnJheVxuICAgICAgLy8gQGV4YW1wbGUgYC5tZXRhKCd0cmFuc2Zvcm1lcnMnKWBcbiAgICAgIGlmIChpc1VuZGVmaW5lZChwcm9wKSkge1xuICAgICAgICBpZiAoRU5WX0RFQlVHKSB7XG4gICAgICAgICAgY29uc29sZS5sb2coJ01FVEFfQ0FMTF9HRVRURVInLCB7W2tleV06IHN0b3JlW2tleV19KVxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGlzVW5kZWZpbmVkKHN0b3JlW2tleV0pKSByZXR1cm4gRU1QVFlfQVJSQVlcbiAgICAgICAgZWxzZSByZXR1cm4gc2l6ZShzdG9yZVtrZXldKSA9PT0gMFxuICAgICAgICAgID8gRU1QVFlfQVJSQVlcbiAgICAgICAgICA6IEFycmF5RnJvbShzdG9yZVtrZXldKVxuICAgICAgfVxuICAgICAgLy8gd2UgaGF2ZSBga2V5LCBwcm9wYFxuICAgICAgLy9cbiAgICAgIC8vIDE6IHNob3VsZCBgcHJvcGAgYmUgYSB2YWx1ZSwgKGlzU2V0PylcbiAgICAgIGVsc2UgaWYgKGlzSW5LZXlNYXBBc1NldChrZXkpKSB7XG4gICAgICAgIGVuc3VyZUluaXRpYWxpemVkKGtleSlcbiAgICAgICAgc2V0KGtleSwgcHJvcClcbiAgICAgICAgaWYgKEVOVl9ERUJVRykge1xuICAgICAgICAgIGNvbnNvbGUubG9nKCdNRVRBX0NBTExfU0VUX1NFVFRFUicsIHtrZXksIHZhbHVlOiBwcm9wLCBzdG9yZX0pXG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIC8vIDI6IHByb3AgaXMgYSBrZXksIHdlIHdhbnQgdG8gcmV0dXJuIHRoZSBbLi5dIGZvciB0aGF0IHNwZWNpZmljIHByb3BlcnR5XG4gICAgICAvLyBAZXhhbXBsZSBgLm1ldGEoJ3RyYW5zZm9ybWVycycsICdlaCcpYFxuICAgICAgZWxzZSBpZiAoaXNVbmRlZmluZWQoc3RvcmVba2V5XSkpIHJldHVybiBFTVBUWV9BUlJBWVxuICAgICAgZWxzZSByZXR1cm4gdG9hcnIoZ2V0KGtleSwgcHJvcCkpXG4gICAgfVxuICAgIC8vIHdlIGhhdmUgYGtleSwgcHJvcCwgdmFsdWVgXG4gICAgZWxzZSB7XG4gICAgICBlbnN1cmVJbml0aWFsaXplZChrZXkpXG5cbiAgICAgIC8vIHdlIGhhdmUgYSB2YWx1ZSwgbGV0J3MgYWRkIGl0XG4gICAgICBzZXQoa2V5LCBwcm9wLCB2YWx1ZSlcblxuICAgICAgaWYgKEVOVl9ERUJVRykge1xuICAgICAgICBjb25zb2xlLmxvZygnTUVUQV9DQUxMX01BUF9TRVRURVInLCB7a2V5LCBwcm9wLCB2YWx1ZSwgc3RvcmV9KVxuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBfdGhpc1xuICB9XG5cbiAgLy8gZm9yIGRlYnVnZ2luZ1xuICBtZXRhLnN0b3JlID0gc3RvcmVcblxuICAvLyBATk9URSBub3QgcmVhbGx5IG5lZWRlZCwgY2FuIGp1c3QgZG8gYG1ldGEuc3RvcmUuW3Byb3BdLmNsZWFyYFxuICAvLyBtZXRhLmNsZWFyID0gcHJvcCA9PiBtZXRhLnN0b3JlW3Byb3BdLmNsZWFyKClcblxuICAvLyBAVE9ETyB1c2UgYHJlbW92ZWAgaGVyZSwgc28gaXQgd2lsbCBkZWxldGUgc2F5LCBpbmRleFxuICAvL1xuICAvLyBAZXhhbXBsZSBzdG9yZS50cmFuc2Zvcm1lcnMgPSBNYXAoe2VoOiBbdHJhbnNmb3JtZXIsIGFub3RoZXJUcmFuc2Zvcm1lcl19KVxuICAvLyAgICAgICAgICBzdG9yZS5kZWxldGUoJ3RyYW5zZm9ybWVycy5laFswXScpXG4gIC8vXG4gIC8vIEBleGFtcGxlIHN0b3JlLm9ic2VydmVycyA9IE1hcCh7ZWg6IFt0cmFuc2Zvcm1lciwgYW5vdGhlclRyYW5zZm9ybWVyXX0pXG4gIC8vICAgICAgICAgIHN0b3JlLmRlbGV0ZSgnb2JzZXJ2ZXJzWy0xXScpXG4gIC8vXG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZVxuICAvLyBtZXRhWydkZWxldGUnXSA9IChwcm9wLCB2YWx1ZU9yS2V5KSA9PiBtZXRhLnN0b3JlW3Byb3BdLmRlbGV0ZSh2YWx1ZU9yS2V5KVxuXG4gIC8vIGRlZmF1bHQgdmFsdWVcbiAgLy8gbWV0YS5kZWJ1ZyA9IGZhbHNlXG5cbiAgcmV0dXJuIG1ldGFcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBnZXRNZXRhXG4iXSwibmFtZXMiOlsiY29uc3QiXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7QUFNQUEsR0FBSyxDQUFDLFNBQVMsR0FBRyxPQUFPLENBQUMsY0FBYyxDQUFDO0FBQ3pDQSxHQUFLLENBQUMsV0FBVyxHQUFHLE9BQU8sQ0FBQyx1QkFBdUIsQ0FBQztBQUNwREEsR0FBSyxDQUFDLEtBQUssR0FBRyxPQUFPLENBQUMsV0FBVyxDQUFDO0FBQ2xDQSxHQUFLLENBQUMsY0FBYyxHQUFHLE9BQU8sQ0FBQyx3QkFBd0IsQ0FBQztBQUN4REEsR0FBSyxDQUFDLGVBQWUsR0FBRyxPQUFPLENBQUMseUJBQXlCLENBQUM7QUFDMURBLEdBQUssQ0FBQyxTQUFTLEdBQUcsT0FBTyxDQUFDLGNBQWMsQ0FBQztBQUN6Q0EsR0FBSyxDQUFDLFdBQVcsR0FBRyxPQUFPLENBQUMsaUJBQWlCLENBQUM7QUFDOUNBLEdBQUssQ0FBQyxNQUFNLEdBQUcsT0FBTyxDQUFDLGlCQUFpQixDQUFDO0FBQ3pDQSxHQUFLLENBQUMsS0FBSyxHQUFHLE9BQU8sQ0FBQyxXQUFXLENBQUM7QUFDbENBLEdBQUssQ0FBQyxJQUFJLEdBQUcsT0FBTyxDQUFDLGNBQWMsQ0FBQztBQUNwQ0EsR0FBSyxDQUFDLGdCQUFnQixHQUFHLE9BQU8sQ0FBQyxvQkFBb0IsQ0FBQztBQUN0REEsR0FBSyxDQUFDLGFBQWEsR0FBRyxPQUFPLENBQUMsaUJBQWlCLENBQUM7QUFDaERBLEdBQUssQ0FBQyxjQUFjLEdBQUcsT0FBTyxDQUFDLGtCQUFrQixDQUFDO0FBQ2xEQSxHQUFLLENBQUMsYUFBYSxHQUFHLE9BQU8sQ0FBQyxpQkFBaUIsQ0FBQzs7O0FBR2hEQSxHQUFLLENBQUMsZUFBZSxHQUFHLFVBQUEsQ0FBQyxDQUFBLENBQUMs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