Why Gemfury? Push, build, and install  RubyGems npm packages Python packages Maven artifacts PHP packages Go Modules Debian packages RPM packages NuGet packages

Repository URL to install this package:

Details    
Size: Mime:
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = exports.composeClass = exports.ChainSnippet = exports.ContainerBase = void 0;

var _exotic = require("../../exotic");

var _dopemerge = _interopRequireDefault(require("../src/deps/dopemerge"));

var _keys = _interopRequireDefault(require("../src/deps/util/keys"));

var _entries = _interopRequireDefault(require("../src/deps/reduce/entries"));

var _reduce = _interopRequireDefault(require("../src/deps/reduce/reduce"));

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

// almost all lodash/ramda/underscore style utils
// operation helper functions
// import { merge, ObjectKeys, reduceEntries, reduce } from 'chain
// all typechecks, all type corersions

/**
 * @param {*} value
 * @return {Boolean}
 */
const hasStore = value => (0, _exotic.hasOwnProp)(value, 'store');
/**
 * @param {String | Primitive} key
 * @param {*} value
 * @return {Boolean}
 * @see hasStore
 */


const shouldClear = (key, value) => (0, _exotic.isSet)(value) || (0, _exotic.isMap)(value) || hasStore(value);
/**
 * ------------ additional resources -----------
 * # internal @IMPORTANT @README
 * https://jira.skava.net/confluence/display/ux/Exporting+in+es4-5-6-7
 *
 * # external
 *
 * https://blog.prototypr.io/design-system-ac88c6740f53
 * http://demo.patternlab.io/?p=atoms-button
 *
 * https://github.com/acdlite/recompose/blob/master/src/packages/recompose/renameProps.js
 *
 *
 * @todo tutorial on weakmap, weakset, set, map, symbol, exotic
 * https://github.com/jonschlinkert/kind-of
 * https://www.ecma-international.org/ecma-262/8.0/index.html#sec-weakmap-objects
 * https://www.ecma-international.org/ecma-262/8.0/index.html#sec-symbol-objects
 * https://www.ecma-international.org/ecma-262/8.0/index.html#sec-map-objects
 * https://www.ecma-international.org/ecma-262/8.0/index.html#sec-set-objects
 *
 *
 * @todo tutorial on container interface specification
 */


let Generic = class Generic {}; // eslint-disable-next-line

const composeClass = (Klass = Generic) => {
  /**
   * {@link https://tc39.github.io/ecma262/#sec-map-objects emca-map}
   * {@link https://ponyfoo.com/articles/es6-maps-in-depth pony-map}
   * {@link https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Map mozilla-map}
   *
   * @docs https://jira.skava.net/confluence/display/ux/Sprint+8+-+container
   * @docs https://jira.skava.net/confluence/display/ux/Container+Layer
   * @tutorial https://github.com/fluents/chain-able/wiki
   *
   * libs (large very powerful toolsets to built anything)
   * @see modules/chain-able
   * @see modules/exotic
   *
   * utils (small tools for solving some more specific problems)
   * @see modules/deps
   * @see modules/thisless
   *
   * our containers built with libs & utils ^:
   * @see modules/router
   * @see modules/state-tree
   * @see modules/view-container
   *
   * ---
   *
   * @classdesc this class is a slice of chain-able container builders
   * @see https://github.com/fluents/chain-able/wiki/ContainerBase
   *
   * it focuses on a very specific container, that has the most/best
   * - easiest,
   * - powerful
   * - reusable
   * - standard
   *
   * @prop {Map} store
   *
   */
  let ContainerBase = class ContainerBase extends Klass {
    constructor(...args) {
      super(...args);
      /**
       * @type {Map}
       * @description we put all of our properties on this store
       * this is the fastest, most consistent way to deal with all property storage
       * and conforms to our common interface
       */

      this.store = new Map();
    }

    setDebug(shouldDebug = true) {
      return this.set('debug', shouldDebug);
    }

    getDebug() {
      return this.get('debug');
    }

  };
  /**
   * @desc get value for key path in the Map store
   *
   * @param  {Primitive} key Primitive data key used as map property to reference the value
   * @return {any} value in .store at key
   *
   * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/get mozilla-map-get}
   * @see {@link mozilla-map-get}
   *
   * @example
   *
   *    const chain = new Chain()
   *    chain.set('eh', true)
   *    chain.get('eh')
   *    //=> true
   *
   *    chain.get('nope')
   *    //=> undefined
   *
   * @example
   *    // if it was an obj
   *    this.store[name]
   */

  ContainerBase.prototype.get = function (name) {
    return this.store.get(name);
  };
  /**
   * @desc sets the value using the key on store
   *       adds or updates an element with a specified key and value
   *
   * @memberOf ContainerBase
   * @since 0.4.0
   *
   * @param {Primitive} key Primitive to reference the value
   * @param {any} value any data to store
   * @return {ContainerBase} @ContainerBase
   *
   * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/set mozilla-map-set}
   * @see {@link mozilla-map-set}
   * @see ContainerBase.store
   *
   * @example
   *
   *    const chain = new Chain()
   *    chain.set('eh', true)
   *    chain.get('eh')
   *    //=> true
   *
   */


  ContainerBase.prototype.set = function (name, value) {
    this.store[name] = value;
    return this;
  };
  /**
   * @desc checks each property of the object
   *       calls the chains accordingly
   *
   * @param {Object} obj object with functions to hydrate from
   * @return {ContainerBase} @ContainerBase
   *
   * @example
   *
   *     const from = new Chain().from({eh: true})
   *     const eh = new Chain().set('eh', true)
   *     eq(from, eh)
   *     //=> true
   *
   */


  ContainerBase.prototype.from = function (obj) {
    const keys = (0, _keys.default)(obj);

    for (let keyIndex = 0; keyIndex < keys.length; keyIndex++) {
      const key = keys[keyIndex];
      const value = obj[key];
      const fn = this[key];

      if ((0, _exotic.isFunction)(fn)) {
        fn.call(this, value);
      } else {
        this.set(key, value);
      }
    }

    return this;
  };
  /**
   * @desc spreads the entries from ContainerBase.store (Map)
   *       return store.entries, plus all chain properties if they exist
   *
   * @memberOf ContainerBase
   * @version 4.0.0 <- improved reducing
   * @since 0.4.0
   *
   * @param  {boolean} [chains=false] if true, returns all properties that are chains
   * @return {Object} reduced object containing all properties from the store, and when `chains` is true, all instance properties, and recursive chains
   *
   * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/entries mozilla-map-entries}
   * @see {@link mozilla-map-entries}
   * @see deps/reduce/entries
   *
   * @example
   *
   *    map.set('a', 'alpha').set('b', 'beta').entries()
   *    //=> {a: 'alpha', b: 'beta'}
   *
   */


  ContainerBase.prototype.entries = function (chains) {
    const reduced = (0, _reduce.default)(this.store);

    if ((0, _exotic.isUndefined)(chains)) {
      return reduced;
    }

    const reducer = (0, _entries.default)(reduced);
    reducer(this);
    reducer(reduced);
    return reduced;
  };
  /**
   * @desc tap a value with a function
   *       @modifies this.store.get(name)
   *       Invokes interceptor with the obj, and then returns obj.
   *       The primary purpose of this method is to "tap into" a method chain, in
   *       order to perform operations on intermediate results within the chain.
   *
   * @param  {string | any} name key to `.get`
   * @param  {Function} fn function to tap with
   * @return {Chain} @ContainerBase
   *
   * {@link https://github.com/jashkenas/underscore/blob/master/underscore.js#L1161 underscore-tap}
   * {@link https://github.com/ramda/ramda/blob/master/src/internal/_xtap.js ramda-xtap}
   * {@link https://github.com/ramda/ramda/blob/master/src/tap.js ramda-tap}
   * {@link https://github.com/sindresorhus/awesome-tap awesome-tap}
   * {@link https://github.com/midknight41/map-factory map-factory}
   * {@link https://github.com/webpack/tapable tapable}
   * @see {@link underscore-tap}
   * @see {@link tapable}
   * @see {@link ramda-tap}
   *
   * @see ContainerBase.set
   * @see ContainerBase.get
   *
   * @example
   *
   *    chain
   *      .set('moose', {eh: true})
   *      .tap('moose', moose => {moose.eh = false; return moose})
   *      .get('moose')
   *
   *    //=> {eh: false}
   *
   * @example
   *
   *   const entries = new Chain()
   *     .set('str', 'emptyish')
   *     .tap('str', str => str + '+')
   *     .set('arr', [1])
   *     .tap('arr', arr => arr.concat([2]))
   *     .entries()
   *
   *   //=> {str: 'emptyish+', arr: [1, 2]}
   *
   */


  ContainerBase.prototype.tap = function (name, fn) {
    // get value, tap it, set it
    return this.set(name, fn(this.get(name), _dopemerge.default));
  };
  /**
   * @return {Array<number | string | *>} keys
   *
   * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set/keys mozilla-set-keys}
   * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/keys mozilla-map-keys}
   * @see {@link mozilla-map-keys}
   * @see {@link mozilla-set-keys}
   *
   * @example
   *
   *    Chain.set('eh', 1).keys()
   *    //=> ['eh']
   *
   */


  ContainerBase.prototype.keys = function () {
    return (0, _exotic.toArray)(this.store.keys());
  };
  /**
   * @desc clears the map,
   *       goes through this properties,
   *       calls .clear if they are instanceof ContainerBase or Map
   *
   * @memberOf ContainerBase
   * @since 4.0.0 (moved only to ContainerBase, added option to clear this keys)
   * @since 0.4.0 (in ContainerBase)
   * @since 0.3.0 (in ContainerBase)
   *
   * @param {boolean | undefined} [clearPropertiesThatAreChainLike=true] checks properties on the object, if they are `chain-like`, clears them as well
   * @return {ContainerBase} @ContainerBase
   *
   * @see https://github.com/fliphub/flipchain/issues/2
   * @see ChainedSet
   * @see ContainerBase
   *
   * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/clear map-clear}
   * @see {@link map-clear}
   *
   * @example
   *
   *    const chain = new Chain()
   *    chain.set('eh', 1)
   *    chain.entries()
   *    //=> {eh: 1}
   *    chain.clear()
   *    chain.entries()
   *    //=> {}
   *
   */


  ContainerBase.prototype.clear = function (clearPropertiesThatAreChainLike = true) {
    this.store.clear();

    if (clearPropertiesThatAreChainLike === false) {
      return this;
    }

    const keys = (0, _keys.default)(this);

    for (let keyIndex = 0; keyIndex < keys.length; keyIndex++) {
      const key = keys[keyIndex];
      const property = this[key];

      if (shouldClear(key, property)) {
        this[key].clear();
      }
    }

    return this;
  };
  /**
   * @desc calls .delete on this.store.map
   * @since 0.3.0
   * @memberOf ContainerBase
   *
   * @param {Primitive} key on a Map: key referencing the value. on a Set: the index
   * @return {ContainerBase}
   *
   * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/delete mozilla-map-delete}
   * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set/delete mozilla-set-delete}
   * @see {@link mozilla-map-delete}
   * @see {@link mozilla-set-delete}
   * @see ChainedSet
   * @see ContainerBase
   *
   * @example
   *
   *    const chain = new Chain()
   *    chain.set('eh', 1)
   *    chain.get('eh')
   *    //=> 1
   *
   *    chain.delete('eh', 1)
   *    chain.get('eh')
   *    //=> undefined
   *
   */


  ContainerBase.prototype.delete = function (key) {
    this.store.delete(key);
    return this;
  };
  /**
   * @desc checks whether the store has a value for a given key
   * @memberOf ContainerBase
   * @since 0.3.0
   *
   * @param {any} keyOrValue key when Map, value when Set
   * @return {boolean} `this.store.has(keyOrValue)`
   *
   * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/has mozilla-map-has}
   * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set/has mozilla-set-has}
   * @see {@link mozilla-map-has}
   * @see {@link mozilla-set-has}
   *
   * @example
   *
   *   const chain = new Chain()
   *   chain.set('eh', 1).has('eh')
   *   //=> true
   *   chain.has('canada')
   *   //=> false
   *
   */


  ContainerBase.prototype.has = function (keyOrValue) {
    return this.store.has(keyOrValue);
  };
  /**
   * @desc spreads the entries from ContainerBase.store.values
   *       allocates a new array, adds the values from the iterator
   *
   * @memberOf ContainerBase
   * @since 0.4.0
   *
   * @return {Array<any>} toArr(this.store.values())
   *
   * @NOTE look at ContainerBase.constructor to ensure not to use `new Array...`
   * @NOTE moved from ContainerBase and ChainedSet to ContainerBase @2.0.2
   * @NOTE this was [...] & Array.from(this.store.values())
   *
   * {@link https://kangax.github.io/compat-table/es6/#test-Array_static_methods compat-array-static-methods}
   * {@link https://stackoverflow.com/questions/20069828/how-to-convert-set-to-array set-to-array}
   * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/values mozilla-map-values}
   * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set/values mozilla-set-values}
   *
   * @see {@link mozilla-map-values}
   * @see {@link mozilla-set-values}
   * @see {@link compat-array-static-methods}
   * @see {@link set-to-array}
   *
   *
   * @example
   *
   *  const chain = new Chain()
   *  chain.set('eh', 1)
   *  chain.values()
   *  //=> [1]
   *
   */


  ContainerBase.prototype.values = function () {
    return (0, _exotic.toArray)(this.store.values());
  }; // --- symbols ---

  /**
   * @desc Iterator for looping values in the store
   *
   * @type {generator}
   * @return {Object} {value: undefined | any, done: true | false}
   *
   * @NOTE assigned to a variable so buble ignores it
   * @NOTE both Map & Set collections iterate with `[key, val]`
   *
   * @see https://www.typescriptlang.org/docs/handbook/iterators-and-generators.html
   * @see http://exploringjs.com/es6/ch_iteration.html#_maps-1
   * @see https://github.com/sindresorhus/quick-lru/blob/master/index.js
   * @see https://stackoverflow.com/questions/36976832/what-is-the-meaning-of-symbol-iterator-in-this-context
   * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol/iterator
   * @see this.store
   *
   * @example
   *
   *    const chain = new Chain().set('eh', 1)
   *    for (var [key, val] of chain) console.log({[key]: val})
   *    //=> {eh: 1}
   *
   * @example
   *
   *    *[Symbol.iterator](): void { for (const item of this.store) yield item }
   *
   * @example
   *
   *    const {ChainedSet} = require('chain-able')
   *    const set = new ChainedSet()
   *    set.add('eh')
   *
   *    for (const arr of set) {
   *      const [key, val] = arr
   *
   *      key        //=> 0
   *      val        //=> 'eh'
   *      arr.length //=> 2
   *    }
   *
   */


  ContainerBase.prototype[Symbol.iterator] = function () {
    return (0, _exotic.fromKeyValueToIterator)(this.keys(), this.values(), this.store.size);
  };
  /**
   * @desc symbol method for toString, toJSON, toNumber
   * @memberOf ContainerBase
   * @since 1.0.2
   * @version 2
   *
   * @param {string} hint enum[default, string, number]
   * @return {Primitive}
   *
   * {@link http://2ality.com/2015/09/well-known-symbols-es6.html#default-tostring-tags well-known-symbols-es6}
   * @see {@link well-known-symbols-es6}
   *
   * @example
   *
   *  const chain = new Chain()
   *  chain.toNumber = () => 1
   *  +chain;
   *  //=> 1
   *  chain + 1
   *  //=>
   *
   * @example
   *
   *  const chain = new Chain()
   *  chain.toString = () => 'eh'
   *  chain + ''
   *  //=> 'eh'
   *
   */


  ContainerBase.prototype[Symbol.toPrimitive] = function (hint) {
    /* prettier-ignore */

    /**
     * hint === 'number'
     * `s`tring is 115
     * `n`umber is 110
     * 110 & 4 = 1
     * 115 & 4 = 0
     *
     * if (hint === 'string' && this.toJSON) return this.toJSON()
     * else if (hint === 'number' && this.toNumber) return this.toNumber()
     */
    if (hint === 'number' && this.toNumber) {
      return this.toNumber();
    } // hint === 'string'


    if (this.toJSON) {
      return this.toJSON();
    } // hint === 'default'


    return this.toString();
  };
  /**
   * @see https://jira.skava.net/confluence/display/ux/getters+and+setters+in+es5-6
   * @name length
   * @method length
   * @readonly
   * @see ContainerBase.store
   * @return {number}
   * @example for (var i = 0; i < chain.length; i++)
   */


  Object.defineProperty(ContainerBase.prototype, 'length', {
    enumerable: false,

    get() {
      return this.store.size;
    }

  });
  Object.defineProperty(ContainerBase.prototype, Symbol.hasInstance, {
    enumerable: false,
    value: instance => (0, _exotic.isObj)(instance) === false ? false : isPrototypeOf(ContainerBase.prototype, instance) || hasStore(instance)
  });
  return ContainerBase;
};

exports.composeClass = composeClass;
const ContainerBase = composeClass();
exports.ChainSnippet = exports.ContainerBase = ContainerBase;
ContainerBase.composeClass = composeClass;
var _default = ContainerBase;
exports.default = _default;