feature-u
Version:
Feature Based Project Organization for React
1,500 lines (1,318 loc) • 348 kB
JavaScript
(function webpackUniversalModuleDefinition(root, factory) {
if(typeof exports === 'object' && typeof module === 'object')
module.exports = factory();
else if(typeof define === 'function' && define.amd)
define("FeatureU", [], factory);
else if(typeof exports === 'object')
exports["FeatureU"] = factory();
else
root["FeatureU"] = factory();
})(this, function() {
return /******/ (function(modules) { // webpackBootstrap
/******/ // The module cache
/******/ var installedModules = {};
/******/
/******/ // The require function
/******/ function __webpack_require__(moduleId) {
/******/
/******/ // Check if module is in cache
/******/ if(installedModules[moduleId]) {
/******/ return installedModules[moduleId].exports;
/******/ }
/******/ // Create a new module (and put it into the cache)
/******/ var module = installedModules[moduleId] = {
/******/ i: moduleId,
/******/ l: false,
/******/ exports: {}
/******/ };
/******/
/******/ // Execute the module function
/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
/******/
/******/ // Flag the module as loaded
/******/ module.l = true;
/******/
/******/ // Return the exports of the module
/******/ return module.exports;
/******/ }
/******/
/******/
/******/ // expose the modules object (__webpack_modules__)
/******/ __webpack_require__.m = modules;
/******/
/******/ // expose the module cache
/******/ __webpack_require__.c = installedModules;
/******/
/******/ // identity function for calling harmony imports with the correct context
/******/ __webpack_require__.i = function(value) { return value; };
/******/
/******/ // define getter function for harmony exports
/******/ __webpack_require__.d = function(exports, name, getter) {
/******/ if(!__webpack_require__.o(exports, name)) {
/******/ Object.defineProperty(exports, name, {
/******/ configurable: false,
/******/ enumerable: true,
/******/ get: getter
/******/ });
/******/ }
/******/ };
/******/
/******/ // getDefaultExport function for compatibility with non-harmony modules
/******/ __webpack_require__.n = function(module) {
/******/ var getter = module && module.__esModule ?
/******/ function getDefault() { return module['default']; } :
/******/ function getModuleExports() { return module; };
/******/ __webpack_require__.d(getter, 'a', getter);
/******/ return getter;
/******/ };
/******/
/******/ // Object.prototype.hasOwnProperty.call
/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
/******/
/******/ // __webpack_public_path__
/******/ __webpack_require__.p = "";
/******/
/******/ // Load entry module and return exports
/******/ return __webpack_require__(__webpack_require__.s = 35);
/******/ })
/************************************************************************/
/******/ ([
/* 0 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
// shim for using process in browser
var process = module.exports = {};
// cached from whatever global is present so that test runners that stub it
// don't break things. But we need to wrap it in a try catch in case it is
// wrapped in strict mode code which doesn't define any globals. It's inside a
// function because try/catches deoptimize in certain engines.
var cachedSetTimeout;
var cachedClearTimeout;
function defaultSetTimout() {
throw new Error('setTimeout has not been defined');
}
function defaultClearTimeout() {
throw new Error('clearTimeout has not been defined');
}
(function () {
try {
if (typeof setTimeout === 'function') {
cachedSetTimeout = setTimeout;
} else {
cachedSetTimeout = defaultSetTimout;
}
} catch (e) {
cachedSetTimeout = defaultSetTimout;
}
try {
if (typeof clearTimeout === 'function') {
cachedClearTimeout = clearTimeout;
} else {
cachedClearTimeout = defaultClearTimeout;
}
} catch (e) {
cachedClearTimeout = defaultClearTimeout;
}
})();
function runTimeout(fun) {
if (cachedSetTimeout === setTimeout) {
//normal enviroments in sane situations
return setTimeout(fun, 0);
}
// if setTimeout wasn't available but was latter defined
if ((cachedSetTimeout === defaultSetTimout || !cachedSetTimeout) && setTimeout) {
cachedSetTimeout = setTimeout;
return setTimeout(fun, 0);
}
try {
// when when somebody has screwed with setTimeout but no I.E. maddness
return cachedSetTimeout(fun, 0);
} catch (e) {
try {
// When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally
return cachedSetTimeout.call(null, fun, 0);
} catch (e) {
// same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error
return cachedSetTimeout.call(this, fun, 0);
}
}
}
function runClearTimeout(marker) {
if (cachedClearTimeout === clearTimeout) {
//normal enviroments in sane situations
return clearTimeout(marker);
}
// if clearTimeout wasn't available but was latter defined
if ((cachedClearTimeout === defaultClearTimeout || !cachedClearTimeout) && clearTimeout) {
cachedClearTimeout = clearTimeout;
return clearTimeout(marker);
}
try {
// when when somebody has screwed with setTimeout but no I.E. maddness
return cachedClearTimeout(marker);
} catch (e) {
try {
// When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally
return cachedClearTimeout.call(null, marker);
} catch (e) {
// same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error.
// Some versions of I.E. have different rules for clearTimeout vs setTimeout
return cachedClearTimeout.call(this, marker);
}
}
}
var queue = [];
var draining = false;
var currentQueue;
var queueIndex = -1;
function cleanUpNextTick() {
if (!draining || !currentQueue) {
return;
}
draining = false;
if (currentQueue.length) {
queue = currentQueue.concat(queue);
} else {
queueIndex = -1;
}
if (queue.length) {
drainQueue();
}
}
function drainQueue() {
if (draining) {
return;
}
var timeout = runTimeout(cleanUpNextTick);
draining = true;
var len = queue.length;
while (len) {
currentQueue = queue;
queue = [];
while (++queueIndex < len) {
if (currentQueue) {
currentQueue[queueIndex].run();
}
}
queueIndex = -1;
len = queue.length;
}
currentQueue = null;
draining = false;
runClearTimeout(timeout);
}
process.nextTick = function (fun) {
var args = new Array(arguments.length - 1);
if (arguments.length > 1) {
for (var i = 1; i < arguments.length; i++) {
args[i - 1] = arguments[i];
}
}
queue.push(new Item(fun, args));
if (queue.length === 1 && !draining) {
runTimeout(drainQueue);
}
};
// v8 likes predictible objects
function Item(fun, array) {
this.fun = fun;
this.array = array;
}
Item.prototype.run = function () {
this.fun.apply(null, this.array);
};
process.title = 'browser';
process.browser = true;
process.env = {};
process.argv = [];
process.version = ''; // empty string to avoid regexp issues
process.versions = {};
function noop() {}
process.on = noop;
process.addListener = noop;
process.once = noop;
process.off = noop;
process.removeListener = noop;
process.removeAllListeners = noop;
process.emit = noop;
process.prependListener = noop;
process.prependOnceListener = noop;
process.listeners = function (name) {
return [];
};
process.binding = function (name) {
throw new Error('process.binding is not supported');
};
process.cwd = function () {
return '/';
};
process.chdir = function (dir) {
throw new Error('process.chdir is not supported');
};
process.umask = function () {
return 0;
};
/***/ }),
/* 1 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
exports.__esModule = true;
exports.default = verify;
/**
* A convenience assertion utility, typically used to validate
* pre-conditions of a routine.
*
* **Advanced**: verify.prefix(msgPrefix) returns a higher-order
* verify() function where all messages are prefixed.
*
* @param {truthy} condition - a "truthy" condition which
* must be satisfied.
*
* @param {string} msg - a message clarifying the condition being
* checked.
*
* @throws {Error} an Error is thrown when the supplied condition is
* NOT met.
*
* @private
*/
function verify(condition, msg) {
if (!condition) {
// TODO: don't think there is any benefit in logging this console.error
// console.error(`verify() constraint issue: ${msg}`); // supplement exception with error log (for react-native exposure)
throw new Error(msg);
}
}
verify.prefix = function (msgPrefix) {
return function (condition, msg) {
return verify(condition, msgPrefix + msg);
};
};
/***/ }),
/* 2 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
/**
* lodash 4.0.1 (Custom Build) <https://lodash.com/>
* Build: `lodash modularize exports="npm" -o ./`
* Copyright 2012-2016 The Dojo Foundation <http://dojofoundation.org/>
* Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>
* Copyright 2009-2016 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
* Available under MIT license <https://lodash.com/license>
*/
/** `Object#toString` result references. */
var stringTag = '[object String]';
/** Used for built-in method references. */
var objectProto = Object.prototype;
/**
* Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring)
* of values.
*/
var objectToString = objectProto.toString;
/**
* Checks if `value` is classified as an `Array` object.
*
* @static
* @memberOf _
* @type Function
* @category Lang
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
* @example
*
* _.isArray([1, 2, 3]);
* // => true
*
* _.isArray(document.body.children);
* // => false
*
* _.isArray('abc');
* // => false
*
* _.isArray(_.noop);
* // => false
*/
var isArray = Array.isArray;
/**
* Checks if `value` is object-like. A value is object-like if it's not `null`
* and has a `typeof` result of "object".
*
* @static
* @memberOf _
* @category Lang
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is object-like, else `false`.
* @example
*
* _.isObjectLike({});
* // => true
*
* _.isObjectLike([1, 2, 3]);
* // => true
*
* _.isObjectLike(_.noop);
* // => false
*
* _.isObjectLike(null);
* // => false
*/
function isObjectLike(value) {
return !!value && (typeof value === 'undefined' ? 'undefined' : _typeof(value)) == 'object';
}
/**
* Checks if `value` is classified as a `String` primitive or object.
*
* @static
* @memberOf _
* @category Lang
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
* @example
*
* _.isString('abc');
* // => true
*
* _.isString(1);
* // => false
*/
function isString(value) {
return typeof value == 'string' || !isArray(value) && isObjectLike(value) && objectToString.call(value) == stringTag;
}
module.exports = isString;
/***/ }),
/* 3 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/* WEBPACK VAR INJECTION */(function(global) {
var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
/**
* Lodash (Custom Build) <https://lodash.com/>
* Build: `lodash modularize exports="npm" -o ./`
* Copyright JS Foundation and other contributors <https://js.foundation/>
* Released under MIT license <https://lodash.com/license>
* Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>
* Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
*/
/** `Object#toString` result references. */
var asyncTag = '[object AsyncFunction]',
funcTag = '[object Function]',
genTag = '[object GeneratorFunction]',
nullTag = '[object Null]',
proxyTag = '[object Proxy]',
undefinedTag = '[object Undefined]';
/** Detect free variable `global` from Node.js. */
var freeGlobal = (typeof global === 'undefined' ? 'undefined' : _typeof(global)) == 'object' && global && global.Object === Object && global;
/** Detect free variable `self`. */
var freeSelf = (typeof self === 'undefined' ? 'undefined' : _typeof(self)) == 'object' && self && self.Object === Object && self;
/** Used as a reference to the global object. */
var root = freeGlobal || freeSelf || Function('return this')();
/** Used for built-in method references. */
var objectProto = Object.prototype;
/** Used to check objects for own properties. */
var hasOwnProperty = objectProto.hasOwnProperty;
/**
* Used to resolve the
* [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)
* of values.
*/
var nativeObjectToString = objectProto.toString;
/** Built-in value references. */
var _Symbol = root.Symbol,
symToStringTag = _Symbol ? _Symbol.toStringTag : undefined;
/**
* The base implementation of `getTag` without fallbacks for buggy environments.
*
* @private
* @param {*} value The value to query.
* @returns {string} Returns the `toStringTag`.
*/
function baseGetTag(value) {
if (value == null) {
return value === undefined ? undefinedTag : nullTag;
}
return symToStringTag && symToStringTag in Object(value) ? getRawTag(value) : objectToString(value);
}
/**
* A specialized version of `baseGetTag` which ignores `Symbol.toStringTag` values.
*
* @private
* @param {*} value The value to query.
* @returns {string} Returns the raw `toStringTag`.
*/
function getRawTag(value) {
var isOwn = hasOwnProperty.call(value, symToStringTag),
tag = value[symToStringTag];
try {
value[symToStringTag] = undefined;
var unmasked = true;
} catch (e) {}
var result = nativeObjectToString.call(value);
if (unmasked) {
if (isOwn) {
value[symToStringTag] = tag;
} else {
delete value[symToStringTag];
}
}
return result;
}
/**
* Converts `value` to a string using `Object.prototype.toString`.
*
* @private
* @param {*} value The value to convert.
* @returns {string} Returns the converted string.
*/
function objectToString(value) {
return nativeObjectToString.call(value);
}
/**
* Checks if `value` is classified as a `Function` object.
*
* @static
* @memberOf _
* @since 0.1.0
* @category Lang
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is a function, else `false`.
* @example
*
* _.isFunction(_);
* // => true
*
* _.isFunction(/abc/);
* // => false
*/
function isFunction(value) {
if (!isObject(value)) {
return false;
}
// The use of `Object#toString` avoids issues with the `typeof` operator
// in Safari 9 which returns 'object' for typed arrays and other constructors.
var tag = baseGetTag(value);
return tag == funcTag || tag == genTag || tag == asyncTag || tag == proxyTag;
}
/**
* Checks if `value` is the
* [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types)
* of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
*
* @static
* @memberOf _
* @since 0.1.0
* @category Lang
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is an object, else `false`.
* @example
*
* _.isObject({});
* // => true
*
* _.isObject([1, 2, 3]);
* // => true
*
* _.isObject(_.noop);
* // => true
*
* _.isObject(null);
* // => false
*/
function isObject(value) {
var type = typeof value === 'undefined' ? 'undefined' : _typeof(value);
return value != null && (type == 'object' || type == 'function');
}
module.exports = isFunction;
/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(16)))
/***/ }),
/* 4 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
exports.__esModule = true;
exports.default = logf;
var _verify = __webpack_require__(1);
var _verify2 = _interopRequireDefault(_verify);
var _lodash = __webpack_require__(2);
var _lodash2 = _interopRequireDefault(_lodash);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/*--------------------------------------------------------------------------------
feature-u's logging utility:
- can be enabled/disabled at run-time
- all logging probes are prefixed with: ***feature-u***
- a simple layer on top of console.log()
- for internal use only
... selected functions are exposed to the client through the
UNDOCUMENTED launchApp.diag mechanism (for diagnostic purposes)
API:
+ logf(msg [,obj]): void ... conditionally log probe when feature-u logging is enabled
+ logf.force(msg [,obj]): void ... unconditionally log probe
+ logf.isEnabled(): true/false ... is feature-u logging enabled or disabled
+ logf.enable(): void ... enable feature-u logging
+ logf.disable(): void ... disable feature-u logging
+ logf.elm2html(elm): htmlStr ... convert react elm into nicely formatted html markup
> FOR PLUGIN PROJECTS:
- support their own unique prefix by emitting a new higher-order logf function
- STILL undocumented (at this point)
+ logf.newLogger(prefix): logf ... support plugin project logging with their own prefix (a HOF logger)
--------------------------------------------------------------------------------*/
var msgPrefix = '***feature-u*** ';
var _enabled = false;
// API: logf(msg [,obj]): void ... conditionally log probe when feature-u logging is enabled
function logf(msg, obj) {
if (logf.isEnabled()) {
logf.force(msg, obj);
}
}
// API: logf.force(msg [,obj]): void ... unconditionally log probe
logf.force = function (msg, obj) {
msg = msgPrefix + msg;
if (obj) {
console.log(msg, obj);
} else {
console.log(msg);
}
};
// API: logf.isEnabled(): true/false ... is feature-u logging enabled or disabled
logf.isEnabled = function () {
return _enabled;
};
// API: logf.enabled(): void ... enable feature-u logging
logf.enable = function () {
_enabled = true;
logf('enabling logf()');
};
// API: logf.disable(): void ... disable feature-u logging
logf.disable = function () {
logf('disabling logf()');
_enabled = false;
};
var elm2htmlOneTimeWarning = 'WARNING: By default any react element content is OMITTED.\n\nThis can be overridden by doing the following (before launchApp() is invoked):\n\n- To see the (rather verbose) raw object content, do this:\n launchApp.diag.logf.elm2html = (elm) => elm;\n\n- To see nicely formatted html markup, do this:\n import ReactDOMServer from \'react-dom/server\';\n ...\n launchApp.diag.logf.elm2html = (elm) => ReactDOMServer.renderToStaticMarkup(elm);\n\n';
// API: logf.elm2html(elm): htmlStr ... convert react elm into nicely formatted html markup
// the default logf.elm2html() implementation OMITs the elm content
// BECAUSE:
// 1: we don't want to have a dependency on react-dom (for nicely formatted html markup)
// 2: the raw object content is verbose and un-interpretable
// HOWEVER:
// 3: it can be overridden by the client (see one-time log entry above)
logf.elm2html = function (elm) {
// emit one-time warning
if (elm2htmlOneTimeWarning) {
logf(elm2htmlOneTimeWarning);
elm2htmlOneTimeWarning = null;
}
// return indication of omission
return 'OMITTED';
};
// API: logf.newLogger(prefix): logf ... support plugin project logging with their own prefix (a HOF logger)
logf.newLogger = function (prefix) {
var check = _verify2.default.prefix('logf.newLogger() parameter violation: ');
check(prefix, 'prefix is required');
check((0, _lodash2.default)(prefix), 'prefix must be a string');
var newLogger = function newLogger(msg, obj) {
// re-implement to hook into our .force() ... where the prefixing occurs
if (logf.isEnabled()) {
newLogger.force(msg, obj);
}
};
// this is where the magic happens (i.e. the additional prefixing)
newLogger.force = function (msg, obj) {
return logf.force(prefix + msg, obj);
};
// apply all same logf.properties (for consistant API)
// ... referencing original logf master
// >>> NOTE: this means there is ONE enablement and elm2html().
// KIS: Keep it Simple
// EX: by enabling logf, all plugin logging is enabled too
// ALSO: by enabling plugin logging, ALL logging is enabled (logf, and other plugins)
newLogger.isEnabled = logf.isEnabled;
newLogger.enable = logf.enable;
newLogger.disable = logf.disable;
newLogger.elm2html = function (elm) {
return logf.elm2html(elm);
}; // always dereference original logf to pick up any function overrides
//newLogger.newLogger = logf.newLogger; // NOT: we draw the line somewhere (in this simple implementation)
// thats all folks
return newLogger;
};
/***/ }),
/* 5 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
/**
* lodash (Custom Build) <https://lodash.com/>
* Build: `lodash modularize exports="npm" -o ./`
* Copyright jQuery Foundation and other contributors <https://jquery.org/>
* Released under MIT license <https://lodash.com/license>
* Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>
* Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
*/
/** `Object#toString` result references. */
var objectTag = '[object Object]';
/**
* Checks if `value` is a host object in IE < 9.
*
* @private
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is a host object, else `false`.
*/
function isHostObject(value) {
// Many host objects are `Object` objects that can coerce to strings
// despite having improperly defined `toString` methods.
var result = false;
if (value != null && typeof value.toString != 'function') {
try {
result = !!(value + '');
} catch (e) {}
}
return result;
}
/**
* Creates a unary function that invokes `func` with its argument transformed.
*
* @private
* @param {Function} func The function to wrap.
* @param {Function} transform The argument transform.
* @returns {Function} Returns the new function.
*/
function overArg(func, transform) {
return function (arg) {
return func(transform(arg));
};
}
/** Used for built-in method references. */
var funcProto = Function.prototype,
objectProto = Object.prototype;
/** Used to resolve the decompiled source of functions. */
var funcToString = funcProto.toString;
/** Used to check objects for own properties. */
var hasOwnProperty = objectProto.hasOwnProperty;
/** Used to infer the `Object` constructor. */
var objectCtorString = funcToString.call(Object);
/**
* Used to resolve the
* [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)
* of values.
*/
var objectToString = objectProto.toString;
/** Built-in value references. */
var getPrototype = overArg(Object.getPrototypeOf, Object);
/**
* Checks if `value` is object-like. A value is object-like if it's not `null`
* and has a `typeof` result of "object".
*
* @static
* @memberOf _
* @since 4.0.0
* @category Lang
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is object-like, else `false`.
* @example
*
* _.isObjectLike({});
* // => true
*
* _.isObjectLike([1, 2, 3]);
* // => true
*
* _.isObjectLike(_.noop);
* // => false
*
* _.isObjectLike(null);
* // => false
*/
function isObjectLike(value) {
return !!value && (typeof value === 'undefined' ? 'undefined' : _typeof(value)) == 'object';
}
/**
* Checks if `value` is a plain object, that is, an object created by the
* `Object` constructor or one with a `[[Prototype]]` of `null`.
*
* @static
* @memberOf _
* @since 0.8.0
* @category Lang
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is a plain object, else `false`.
* @example
*
* function Foo() {
* this.a = 1;
* }
*
* _.isPlainObject(new Foo);
* // => false
*
* _.isPlainObject([1, 2, 3]);
* // => false
*
* _.isPlainObject({ 'x': 0, 'y': 0 });
* // => true
*
* _.isPlainObject(Object.create(null));
* // => true
*/
function isPlainObject(value) {
if (!isObjectLike(value) || objectToString.call(value) != objectTag || isHostObject(value)) {
return false;
}
var proto = getPrototype(value);
if (proto === null) {
return true;
}
var Ctor = hasOwnProperty.call(proto, 'constructor') && proto.constructor;
return typeof Ctor == 'function' && Ctor instanceof Ctor && funcToString.call(Ctor) == objectCtorString;
}
module.exports = isPlainObject;
/***/ }),
/* 6 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/* WEBPACK VAR INJECTION */(function(process) {
if (process.env.NODE_ENV === 'production') {
module.exports = __webpack_require__(33);
} else {
module.exports = __webpack_require__(32);
}
/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0)))
/***/ }),
/* 7 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
exports.__esModule = true;
var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
exports.default = createFeature;
exports.isFeatureProperty = isFeatureProperty;
exports.extendFeatureProperty = extendFeatureProperty;
var _verify = __webpack_require__(1);
var _verify2 = _interopRequireDefault(_verify);
var _lodash = __webpack_require__(2);
var _lodash2 = _interopRequireDefault(_lodash);
var _lodash3 = __webpack_require__(3);
var _lodash4 = _interopRequireDefault(_lodash3);
var _logf = __webpack_require__(4);
var _logf2 = _interopRequireDefault(_logf);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _objectWithoutProperties(obj, keys) { var target = {}; for (var i in obj) { if (keys.indexOf(i) >= 0) continue; if (!Object.prototype.hasOwnProperty.call(obj, i)) continue; target[i] = obj[i]; } return target; }
/**
* Create a new {{book.api.Feature}} object, cataloging
* {{book.api.AspectContent}} to be consumed by
* {{book.api.launchApp}}. Each feature within an application
* promotes it's own {{book.api.Feature}} object.
*
* For more information, please refer to
* {{book.guide.detail_featureAndAspect}}.
*
* **Please Note** this function uses named parameters.
*
* @param {string} name the identity of the feature. Feature names
* are guaranteed to be unique. Application code can use the Feature
* name in various **single-source-of-truth** operations _(see
* {{book.guide.bestPractices}})_.
*
* @param {boolean} [enabled=true] an indicator as to whether this
* feature is enabled (true) or not (false). When used, this
* indicator is typically based on a dynamic expression, allowing
* packaged code to be dynamically enabled/disabled at run-time
* _(please refer to: {{book.guide.enablement}})_.
*
* @param {fassets} [fassets]
* an optional aspect that promotes feature assets used in
* {{book.guide.crossCom}} (i.e. the Public Face of a feature).
* `fassets` directives can both define resources, and/or declare a
* resource contract (the intention to use a set of fasset resources).
* Resources are accumulated across all features, and exposed through
* the {{book.api.FassetsObject}}, and the {{book.api.withFassets}}
* HoC.
*
* @param {appWillStartCB} [appWillStart] an optional
* {{book.guide.appLifeCycle}} invoked one time, just before the app
* starts up. This life-cycle hook can do any type of initialization,
* and/or optionally supplement the app's top-level content (using a
* non-null return) _(please refer to: {{book.guide.appWillStart}})_.
*
* @param {appInitCB} [appInit] an optional
* {{book.guide.appLifeCycle}} invoked one time, later in the app
* startup process. This life-cycle hook supports blocking async
* initialization (by simply returning a promise) _(please refer to:
* {{book.guide.appInit}})_.
*
* @param {appDidStartCB} [appDidStart] an optional
* {{book.guide.appLifeCycle}} invoked one time, immediately after the
* app has started _(please refer to: {{book.guide.appDidStart}})_.
*
* @param {AspectContent} [extendedAspect] additional aspects, as
* defined by the feature-u's Aspect plugins (please refer to:
* {{book.guide.detail_extendableAspects}} -and-
* {{book.guide.extending}}).
*
* @return {Feature} a new Feature object (to be consumed by
* launchApp()).
*
* @function createFeature
*/
function createFeature() {
var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
var name = _ref.name,
_ref$enabled = _ref.enabled,
enabled = _ref$enabled === undefined ? true : _ref$enabled,
fassets = _ref.fassets,
appWillStart = _ref.appWillStart,
appInit = _ref.appInit,
appDidStart = _ref.appDidStart,
extendedAspect = _objectWithoutProperties(_ref, ['name', 'enabled', 'fassets', 'appWillStart', 'appInit', 'appDidStart']);
// validate createFeature() parameters
var check = _verify2.default.prefix('createFeature() parameter violation: ');
// ... name
check(name, 'name is required');
check((0, _lodash2.default)(name), 'name must be a string');
// ... enabled
check(enabled === true || enabled === false, 'enabled must be a boolean');
// ... fasset: validation occurs in createFasset()
// ... appWillStart
if (appWillStart) {
check((0, _lodash4.default)(appWillStart), 'appWillStart (when supplied) must be a function');
}
// ... appInit
if (appInit) {
check((0, _lodash4.default)(appInit), 'appInit (when supplied) must be a function');
}
// ... appDidStart
if (appDidStart) {
check((0, _lodash4.default)(appDidStart), 'appDidStart (when supplied) must be a function');
}
// ... extendedAspect
// ... this validation occurs by the Aspect itself (via launchApp())
// BECAUSE we don't know the Aspects in use UNTIL run-time (in launchApp)
// create/return our new Feature object
return _extends({
name: name,
enabled: enabled,
fassets: fassets,
appWillStart: appWillStart,
appInit: appInit,
appDidStart: appDidStart
}, extendedAspect);
}
/**
* Maintain all VALID Feature properties.
*
* This is used to restrict Feature properties to ONLY valid ones:
* - preventing user typos
* - validation is employed at run-time in launchApp()
*
* Initially seeded with Feature builtins.
*
* Later, supplemented with extendFeatureProperty(name, owner) at run-time
* (via Aspect plugins).
*
* @private
*/
var validFeatureProps = {
// owner id of extension (ex: aspect's npm package name)
// =========
name: 'builtin',
enabled: 'builtin',
publicFace: 'builtin', // OBSOLETE as of feature-u@1 ... still registered for the sole purpose of generating more specific error (see: createFassets.js)
fassets: 'builtin',
appWillStart: 'builtin',
appInit: 'builtin',
appDidStart: 'builtin'
};
/**
* Is the supplied name a valid Feature property?
*
* @param {string} name the property name to check.
*
* @param {boolean} true: valid Feature property,
* false: NOT a Feature property
*
* @private
*/
function isFeatureProperty(name) {
return validFeatureProps[name] ? true : false;
}
/**
* Extend valid Feature properties to include the supplied name
* ... used when extending APIs for
* {{book.guide.extending_aspectCrossCommunication}}.
*
* **feature-u** keeps track of the agent that owns this extension
* (using the owner parameter). This is used to prevent exceptions
* when duplicate extension requests are made by the same owner. This
* can happen when multiple instances of an aspect type are supported,
* and also in unit testing.
*
* @param {string} name the property name to allow.
*
* @param {string} owner the requesting owner id of this extension
* request. Use any string that uniquely identifies your utility
* _(such as the aspect's npm package name)_.
*
* @throws {Error} when supplied name is already reserved by a different owner
*/
function extendFeatureProperty(name, owner) {
// validate parameters
var check = _verify2.default.prefix('extendFeatureProperty() parameter violation: ');
check(name, 'name is required');
check((0, _lodash2.default)(name), 'name must be a string');
check(owner, 'owner is required');
check((0, _lodash2.default)(owner), 'owner must be a string');
// verify supplied name is NOT already reserved (by a different owner)
if (isFeatureProperty(name) && // already reserved
validFeatureProps[name] !== owner) {
// by a different owner
throw new Error('**ERROR** extendFeatureProperty(\'' + name + '\', \'' + owner + '\') ... \'Feature.' + name + '\' is already reserved by different owner.');
}
// reserve it
validFeatureProps[name] = owner;
(0, _logf2.default)('invoking: extendFeatureProperty(\'' + name + '\', \'' + owner + '\') ... now validFeatureProps: ', validFeatureProps);
}
//***
//*** Specification: Feature
//***
/**
* @typedef {Object} Feature
*
* The Feature object is merely a lightweight container that holds
* {{book.api.AspectContent}} of interest to **feature-u**.
*
* Each feature within an application promotes a Feature object (using
* {{book.api.createFeature}}) which catalogs the aspects of that feature.
*
* Ultimately, all Feature objects are consumed by
* {{book.api.launchApp}}.
*
* Feature content are simple key/value pairs (the key being an
* Aspect.name with values of AspectContent). These aspects can
* either be **built-in** (from core **feature-u**), or **extensions**.
*
* Here is an example:
*
* ```js
* export default createFeature({
* name: 'featureA', // builtin aspect (name must be unique across all features within app)
* enabled: true, // builtin aspect enabling/disabling feature
*
* fassets: { // builtin aspect promoting Public Face - Cross Feature Communication
* define: {
* 'api.openA': () => ...,
* 'api.closeA': () => ...,
* },
* },
*
* appWillStart: (...) => ..., // builtin aspect (Application Life Cycle Hook)
* appInit: (...) => ..., // ditto
* appDidStart: (...) => ..., // ditto
*
* reducer: ..., // feature redux reducer (extended aspect from the feature-redux plugin)
* logic: ..., // feature logic modules (extended aspect from the feature-redux-logic plugin)
* });
* ```
*
* For more information, please refer to
* {{book.guide.detail_featureAndAspect}}.
*/
//***
//*** Specification: appWillStartCB
//***
/**
* An optional {{book.guide.appLifeCycle}} invoked one time, very
* early in the app startup process.
*
* This life-cycle hook can do any type of general app-specific
* initialization _(for example initializing a **PWA service
* worker**)_.
*
* In addition, it can optionally inject static content in the app's
* DOM root. Any return is interpreted as the app's new `rootAppElm`
* _(an accumulative process)_. **IMPORTANT**: When this is used, the
* supplied `curRootAppElm` MUST be included as part of this
* definition (accommodating the accumulative process of other feature
* injections)! **More information is available at
* {{book.guide.injectingDomContent}}**
*
* For more information _(with examples)_, please refer to the
* Guide's {{book.guide.appWillStart}}.
*
* **Please Note** this function uses named parameters.
*
* @callback appWillStartCB
*
* @param {Fassets} fassets the Fassets object used in cross-feature-communication.
*
* @param {reactElm} curRootAppElm - the current react app element
* root.
*
* @return {reactElm|void} optionally, new top-level content (which in turn
* must contain the supplied `curRootAppElm`). Use a void return
* when top-level content is unchanged.
*/
//***
//*** Specification: appInitCB
//***
/**
* An optional {{book.guide.appLifeCycle}} invoked one time, later in
* the app startup process. It supports blocking async
* initialization.
*
* This hook is invoked when the app is **nearly up-and-running**.
*
* - The {{book.guide.detail_reactRegistration}} has already occurred
* _(via the {{book.api.registerRootAppElmCB}} callback)_. As a
* result, you can rely on utilities that require an app-specific
* `rootAppElm` to exist.
*
* - You have access to the `getState()` and `dispatch()` function,
* assuming you are using {{book.ext.redux}} (when detected by
* **feature-u**'s plugable aspects).
*
* These parameters are actually injected by the
* {{book.ext.featureRedux}} Aspect, and are examples of what can be
* injected by any Aspect _(please refer your specific Aspect's
* documentation to determine other parameters)_.
*
* Just like the {{book.api.appWillStartCB}} hook, you may perform any
* type of general initialization that is required by your feature.
*
* However the **hallmark of this hook** is **you can block for any
* asynchronous initialization to complete**. By simply returning a
* promise, **feature-u** will wait for the process to complete.
*
* The user is kept advised of any long-running async processes. By
* default an `'initializing feature: {feature.name}'` message is
* used, but you can customize it through the supplied
* {{book.api.showStatusCB}} function parameter.
*
* For more info with examples, please see the Guide's
* {{book.guide.appInit}}.
*
* **Please Note** this function uses named parameters.
*
* @callback appInitCB
*
* @param {showStatusCB} showStatus the function that (when invoked)
* will communicate a blocking "persistent" status message to the end
* user.
*
* @param {Fassets} fassets the Fassets object used in cross-feature-communication.
*
* @param {Any} [getState] - the redux function returning the top-level
* app state (when redux is in use).
*
* @param {function} [dispatch] - the redux dispatch() function (when
* redux is in use).
*
* @param {any} [injectedAspectParams] - additional parameters
* injected by Aspect plugins _(please refer your specific Aspect's
* documentation to determine other parameters)_. The `getState` and
* `dispatch` params (above) are examples of this.
*
* @return {Promise|void} optionally, a promise (for asynchronous
* processes) - and feature-u will wait for the process to complete.
* Use a void return (for synchronous processes) - and no blocking
* will occur.
*/
//***
//*** Specification: appDidStartCB
//***
/**
* An optional {{book.guide.appLifeCycle}} invoked one time,
* once the app startup process has completed.
*
* This life-cycle hook can be used to trigger **"the app is
* running"** events. A typical usage is to **"kick start"** some
* early application logic.
*
* Because the app is up-and-running at this time, you have access to
* the `getState()` and `dispatch()` function ... assuming you are using
* {{book.ext.redux}} (when detected by **feature-u**'s plugable aspects).
* These parameters are actually injected by the
* {{book.ext.featureRedux}} Aspect, and are examples of what can be
* injected by any Aspect _(please refer your specific Aspect's
* documentation to determine other parameters)_.
*
* For more info with examples, please see the Guide's
* {{book.guide.appDidStart}}.
*
* **Please Note** this function uses named parameters.
*
* @callback appDidStartCB
*
* @param {Fassets} fassets the Fassets object used in cross-feature-communication.
*
* @param {Any} [getState] - the redux function returning the top-level
* app state (when redux is in use).
*
* @param {function} [dispatch] - the redux dispatch() function (when
* redux is in use).
*
* @param {any} [injectedAspectParams] - additional parameters
* injected by Aspect plugins _(please refer your specific Aspect's
* documentation to determine other parameters)_. The `getState` and
* `dispatch` params (above) are examples of this.
*
* @return void
*/
//***
//*** Specification: fassets
//***
/**
* @typedef {BuiltInAspect} fassets
*
* A builtin aspect that publicly promotes feature-based resources
* called `fassets` (feature assets). These resources are the basis
* of {{book.guide.crossCom}}. You can think of this as the Public Face
* of a feature.
*
* **SideBar**: The term `fassets` is a play on words. While it is
* pronounced "facet" _and is loosely related to this term_, it is
* spelled fassets (i.e. feature assets).
*
* Feature resources are accumulated across all features, and exposed
* through the {{book.api.FassetsObject}}. They can also be referenced
* via the {{book.api.withFassets}} HoC.
*
* The `fassets` aspect can both define resources, and/or declare a
* resource contract (i.e. the intention to use a set of fasset
* resources). This is accomplished via three separate `fassets`
* directives: `define`, `use`, and `defineUse`. A good summary of
* these directives can be found at
* {{book.guide.crossCom_fassetsRecapPushOrPull}}.
*
* 1. **define**: define public resources, held in the
* {{book.api.FassetsObject}}
*
* ```js
* fassets: {
* define: {
* '{fassetsKey}': {fassetsValue}
*
* ...
*
* NOTES:
* - fassetsKey MUST be unique
* - are case-sensitive
* - may contain federated namespace (via dots ".")
* ... normalized in fassets object
* ... ex: 'MainPage.launch'
* - may be any valid JS identifier (less $ support)
* - may NOT contain wildcards
* ... i.e. must be defined completely
*
* // examples ...
* 'openView': actions.view.open, // fassets.openView(viewName): Action
*
* // federated namespace example
* 'selector.currentView': selector.currentView, // fassets.selector.currentView(appState): viewName
*
* // UI Component example
* 'MainPage.cart.link': () => <Link to="/cart">Cart</Link>,
* 'MainPage.cart.body': () => <Route path="/cart" component={ShoppingCart}/>,
* }
* }
* ```
*
* 2. **use**: specify public resource keys that will be **used** by the
* containing feature (i.e. a resource contract)
*
* ```js
* fassets: {
* use: [
* '{fassetsKey}',
* -or-
* ['$fassetsKey', {required: true/false, type: $validationFn}],
*
* ...
*
* NOTES:
* - each key will be supplied by other features
* - this is a communication to other features (i.e. a contract)
* ... saying: I plan to "use" these injections
* HOWEVER: feature-u cannot strictly enforce this usage
* ... enclosed feature should reference this
* {fassetsKey} through fassets.get(), or withFassets()
* - is case-sensitive
* - may contain federated namespace (with dots ".")
* ... ex: 'MainPage.launch'
* - may be any valid JS identifier (less $ support)
* - may contain wildcards (with "*")
* ... ex: 'MainPage.*.link'
*
* // examples ...
* 'MainPage.launch',
*
* // may contain wildcards ...
* 'MainPage.*.link',
* 'MainPage.*.body',
*
* // optionally supply options object, controlling optionality and data types
* ['MainPage.*.link', { required: true, type: any }], // same as DEFAULTS
* ['MainPage.*.link', { required: false, }], // optional of any type
* ['MainPage.*.link', { type: comp }], // required of react component type
* ['MainPage.*.link', { required: false, type: comp }], // optional of react component type
* ]
* }
* ```
*
* 3. **defineUse**: define public resources specified by other features (via
* the `use` directive)
*
* ```js
* fassets: {
* defineUse: {
* '{fassetsKey}': {fassetsValue}
*
* ...
*
* NOTES:
* - this is identical to fassets.define EXCEPT:
* - it MUST MATCH a fassets.use directive
* ... using this directive, feature-u will perform additional
* validation to unsure these entries match a use contract
*
* // examples ...
* 'MainPage.cart.link': () => <Link to="/cart">Cart</Link>,
* 'MainPage.cart.body': () => <Route path="/cart" component={ShoppingCart}/>,
* }
* }
* ```
*
* For more information, please refer to {{book.guide.crossCom}},
* {{book.api.FassetsObject}}, the {{book.api.withFassets}} HoC,
* and the {{book.guide.crossCom_fassetsRecapPushOrPull}}.
*/
/***/ }),
/* 8 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
exports.__esModule = true;
exports.FassetsContext = undefined;
var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }();
exports.withFassets = withFassets;
exports.fassetsProps = fassetsProps;
var _react = __webpack_require__(6);
var _react2 = _interopRequireDefault(_react);
var _createReactContext = __webpack_require__(23);
var _createReactContext2 = _interopRequireDefault(_createReactContext);
var _verify = __webpack_require__(1);
var _verify2 = _interopRequireDefault(_verify);
var _lodash = __webpack_require__(3);
var _lodash2 = _interopRequireDefault(_lodash);
var _lodash3 = __webpack_require__(5);
var _lodash4 = _interopRequireDefault(_lodash3);
var _lodash5 = __webpack_require__(2);
var _lodash6 = _interopRequireDefault(_lodash5);
var _mySpace = __webpack_require__(12);
var _isComponent = __webpack_require__(17);
var _isComponent2 = _interopRequireDefault(_isComponent);
var _logf = __webpack_require__(4);
var _logf2 = _interopRequireDefault(_logf);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }
function _objectWithoutProperties(obj, keys) { var target = {}; for (var i in obj) { if (keys.indexOf(i) >= 0) continue; if (!Object.prototype.hasOwnProperty.call(obj, i)) continue; target[i] = obj[i]; } return target; } // ponyfill react context, supporting older version of react
var fassetsNotDefined = 'NO FassetsContext.Provider';
// report the React Context that is in-use
var contextImpl = _react2.default.createContext === _createReactContext2.default ? 'native (React >16.3)' :