UNPKG

te-flow

Version:

A function pipeline of sorts to control flow.

605 lines (581 loc) 19.8 kB
(function webpackUniversalModuleDefinition(root, factory) { if(typeof exports === 'object' && typeof module === 'object') module.exports = factory(require("defclass"), require("lodash.defaults"), require("lodash.isfunction"), require("lodash.isobject"), require("lodash.memoize")); else if(typeof define === 'function' && define.amd) define(["defclass", "lodash.defaults", "lodash.isfunction", "lodash.isobject", "lodash.memoize"], factory); else if(typeof exports === 'object') exports["te-flow"] = factory(require("defclass"), require("lodash.defaults"), require("lodash.isfunction"), require("lodash.isobject"), require("lodash.memoize")); else root["te-flow"] = factory(root["defclass"], root["lodash.defaults"], root["lodash.isfunction"], root["lodash.isobject"], root["lodash.memoize"]); })(this, function(__WEBPACK_EXTERNAL_MODULE_0__, __WEBPACK_EXTERNAL_MODULE_1__, __WEBPACK_EXTERNAL_MODULE_2__, __WEBPACK_EXTERNAL_MODULE_3__, __WEBPACK_EXTERNAL_MODULE_4__) { 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 = 5); /******/ }) /************************************************************************/ /******/ ([ /* 0 */ /***/ (function(module, exports) { module.exports = require("defclass"); /***/ }), /* 1 */ /***/ (function(module, exports) { module.exports = require("lodash.defaults"); /***/ }), /* 2 */ /***/ (function(module, exports) { module.exports = require("lodash.isfunction"); /***/ }), /* 3 */ /***/ (function(module, exports) { module.exports = require("lodash.isobject"); /***/ }), /* 4 */ /***/ (function(module, exports) { module.exports = require("lodash.memoize"); /***/ }), /* 5 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; function _toArray(arr) { return Array.isArray(arr) ? arr : Array.from(arr); } var isFunction = __webpack_require__(2); var isObject = __webpack_require__(3); var _memoize = __webpack_require__(4); var _defaults2 = __webpack_require__(1); var defclass = __webpack_require__(0); /* teFlow */ var TeFlow = defclass({ constructor: function constructor(initArgOpt) { var self = this; self._self = self; self.userOptions = {}; //no opts return if (!initArgOpt) { return; } //set opts var allOpts = ['initArgs', 'args', 'this', 'stream', 'objReturn', 'objKeep', 'flow', 'flatten', 'start', 'res', 'end']; allOpts.forEach(function (val) { if (!self._L.isUdf(initArgOpt[val])) { self.userOptions[val] = initArgOpt[val]; } }); //check memoize sep if (!self._L.isUdf(initArgOpt.memoize)) { self._memoize = initArgOpt.memoize; } }, invoke: function invoke() { var self = this; //set args var args = new Array(arguments.length); for (var i = 0; i < args.length; ++i) { args[i] = arguments[i]; } self.args = args; self.argsToApply = { _fnArgs: [] }; //init precheck for options if (!self.count) { self.count = 1; var optConfig = self.checkOpts(self.args); self.args = optConfig.args; self.argsToApply = optConfig.argsToApply; } //set fns self.first = self.args.length ? self.args.shift() : null; self.rest = self.args; self.firstIsFn = self._L.isFn(self.first); self.firstIsUdf = self._L.isUdf(self.first); //check for args to apply var _argsToApply = self.rest[self.rest.length - 1]; if (!self._L.isUdf(_argsToApply) && _argsToApply._fnArgs) { self.argsToApply._fnArgs = self.rest.pop()._fnArgs; } return self.process(); }, /* Checks for special options */ checkOpts: function checkOpts(args) { var self = this; var userOptions = Object.keys(self.userOptions); var car = args[0]; var carIsObj = self._L.isFn(car) ? false : self._L.isObj(car); var fnOpts = ['_stream', '_objReturn', '_objKeep', '_flow', '_args', '_flatten', '_start', '_res', '_end', '_option', '_this']; //check to make sure if an object is as first arg it has an opt var hasOpt = false; if (carIsObj) { car = car._option ? car._option : car; var keys = Object.keys(car); for (var i = 0; i < keys.length && !hasOpt; i++) { if (fnOpts.indexOf(keys[i]) !== -1) { hasOpt = true; } } } //will contain any stream opts to be applied self.streamOpt = []; //default helper var setOptD = function setOptD(constOpt, fnOpt, def) { //check for cunstructor options first if (!self._L.isUdf(self.userOptions[constOpt])) { return self.userOptions[constOpt]; } return self._L.isUdf(car[fnOpt]) ? def : car[fnOpt]; }; //availible options and corresponding actions self.optList = { _kill: setOptD('kill', '_kill', false), _return: setOptD('return', '_return', false), _stream: setOptD('stream', '_stream', true), _objReturn: setOptD('objReturn', '_objReturn', true), _objKeep: setOptD('objKeep', '_objKeep', false), _flow: setOptD('flow', '_flow', false), _flatten: setOptD('flatten', '_flatten', false) }; //stream options self.optStreamList = { _start: setOptD('start', '_start', null), _res: setOptD('res', '_res', null), _end: setOptD('end', '_end', null) }; //checks for opts, and pushes if (carIsObj && hasOpt || userOptions.length) { //hardcoded opts //this ref to be applied to funks //set this for ref chain if (self.userOptions['this']) { //constOpt self._this = self.userOptions['this']; } else { //fnOpt self._this = car._this ? car._this : null; } //Initail args //helper to invoke args if methods var invokeArgs = function invokeArgs(initArgs) { //args in method if (self._L.isFn(initArgs)) { return initArgs(); } //assume args is obj return Object.keys(initArgs).reduce(function (prv, cur) { var curArg = initArgs[cur]; prv[cur] = !self._L.isFn(curArg) ? initArgs[cur] : curArg(); return prv; }, {}); }; //gate for init args if (self.userOptions.initArgs || self.userOptions.args) { //constOpt var _args = self.userOptions.args || self.userOptions.initArgs; self.applyArgs(invokeArgs(_args), true); } else if (car._args) { self.applyArgs(invokeArgs(car._args), true); } else if (car._initArgs) { //fnOpt self.applyArgs(invokeArgs(car._initArgs), true); } //memorize - true by default if (!self._memoize) { self._memoize = car._memoize === false ? false : true; } //cylce through opt list Object.keys(self.optStreamList).forEach(function (key) { //if key push the be applied when the time comes if (car[key]) { //push to array ref self.streamOpt.push(key); //assign if need be if (self.optStreamList[key] === null) { self.optStreamList[key] = car[key]; } } }); //shift off to return if (!userOptions.length) { args.shift(); } } //not the cleanest way to handle this but //oh well return { args: args, argsToApply: self.argsToApply }; }, /* Applys any opts to val if set */ applyOpts: function applyOpts(valueArr, funcOpt) { var self = this; /** * cycle through opts to apply * applys fns to said arg through some recursion * @param {arg} arg -indv arg * @param {fn} firstFn -current fn * @param {arr} restFn -rest of funks to be invoked * @return {arr} -arg val with appled fns */ var applyFn = function applyFn(arg, _ref) { var _ref2 = _toArray(_ref), firstFn = _ref2[0], restFn = _ref2.slice(1); if (arg === undefined) { return; } else if (!self._L.isArr(arg)) { arg = [arg]; } return firstFn === undefined ? arg : applyFn(firstFn.apply(self._this, arg), restFn); }; /** * Cycles through the vals and fns to apply * and then invokes thoese * @param {arr} argArr - arg stream * @param {fn} fns - funks to be appled * @return {arr} ->stream */ var mapApply = function mapApply(argArr, fns) { //memoize to avodie repeat var _memApplyFn = self._L.memoize(function (a) { return applyFn(a, fns); }); var _applyFn = self._memoize ? _memApplyFn : applyFn; return argArr.map(function (a) { var res = _applyFn(a, fns); if (!self._L.isUdf(res) && res[0]) { return res[0]; } }); }; //handels apply option to value /** * Handles and appies options to args stream vals * @param {argArr} argArr -arg stream * @param {fn || obj} optToApply -are the fn opts to be applied * @return {arr} ->stream */ var applyOpt = function applyOpt(argArr, optToApply) { //function if (self._L.isFn(optToApply)) { return mapApply(argArr, optToApply); } else if (self._L.isObj(optToApply)) { //object return mapApply(argArr, Object.keys(optToApply).map(function (opt) { return optToApply[opt]; })); } else if (self._L.isArr(optToApply)) { //array return mapApply(argArr, optToApply); } }; /** * Cycles through opts and invokes opts that * pass through the gates * @param {arr} val -stream value * @param {obj} fnOpt -funk options * @param {obj} streamOpt -stream option from this.streamOpt * @return {arr} ->stream */ var optCycle = function optCycle(argArr, fnOpt, streamOpt) { //filter out stage apply opts streamOpt = streamOpt.filter(function (opt) { if (opt !== '_start' && opt !== '_res' && opt !== '_end') { return opt; } else if (opt === '_start' && fnOpt._start) { return opt; } else if (opt === '_res' && fnOpt._res) { return opt; } else if (opt === '_end' && fnOpt._end) { return opt; } }); //Go through option list to see what needs //to be applied return streamOpt.reduce(function (prv, cur) { return applyOpt(prv, self.optStreamList[cur]); }, argArr); }; /** * Sets the default gate options * @param {obj} val -the current stream value * @param {obj} opts -options * @return {arr} ->stream */ var setOptions = function setOptions(valArr, fnOpt, streamOpt) { var _defaults = { _start: false, _end: false, _res: false }; return optCycle.apply(self, [valArr, self._L.defaults(fnOpt, _defaults), streamOpt]); }; //stream opt return this.streamOpt.length ? setOptions(valueArr, funcOpt, this.streamOpt) : valueArr; }, /** * Applies any fn args if specifed by user * @param {dependant on res} value * @param {Boolean} initRun if inital run no to trip shit up */ applyArgs: function applyArgs(value) { var initRun = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; var self = this; var keepOveride = false; if (value === undefined) { return; } var pushApply = function pushApply(val) { if (self.optList._flow) { //Flow push self.argsToApply._fnArgs.push(val); } else if (self.optList._objReturn && self._L.isObj(val)) { var keepKey = self.optList._objKeep; //keep override check keepKey = keepOveride ? !keepKey : keepKey; //Object assign self.argsToApply._fnArgs = Object.keys(val).map(function (key) { var objKey = void 0; if (keepKey) { objKey = {}; objKey[key] = val[key]; } return keepKey ? objKey : val[key]; }); } else { //Reassign Stream val = self._L.isArr(val) ? val : [val]; self.argsToApply._fnArgs = val; } }; //apply res option //pushes val for next invoke if (!initRun) { //check to see if the user has specified a new this val //of overrided keep obj var checkAux = function checkAux(val) { if (!self._L.isUdf(val)) { //this if (val._this) { self._this = val._this; delete val._this; } //keep if (!self._L.isUdf(val._objKeep)) { keepOveride = true; delete val._objKeep; } //kill if (val._kill === true) { self.optList._kill = true; delete val._kill; } //early return if (val._return === true) { self.optList._return = true; delete val._return; } } return val; }; //res push pushApply(function () { //need to send val as an array to have opts applied if (!self._L.isArr(value)) { value = [checkAux(value)]; var res = self.applyOpts(value, { _res: true }); return res[0]; } return self.applyOpts(checkAux(value), { _res: true }); }()); //apply end stream opts //check flatten stream - might be a better way to handle this but fuck it. self.argsToApply._fnArgs = !self.optList._flatten ? self.argsToApply._fnArgs : self._L.flatten(self.argsToApply._fnArgs); self.argsToApply._fnArgs = self.applyOpts(self.argsToApply._fnArgs, { _end: true }); } else { //inial run, forget about factoring options pushApply(value); } }, /* Processes and shit */ process: function process() { var self = this; //if killed undefined if (self.optList._kill) { return undefined; } else if (self.optList._return) { var last = self.rest[self.rest.length - 1]; //check for return obj as last arg if (self._L.isObj(last) && Object.keys(last)[0] === 'return') { return last.return.apply(self._this, self.argsToApply._fnArgs || []); } //early return return self.argsToApply._fnArgs || []; } //first is func if (self.firstIsFn) { var res = Object.keys(self.argsToApply).length ? self.first.apply(self._this, self.applyOpts(self.argsToApply._fnArgs, { //apply start strams opts _start: true })) : self.first.call(self._this); self.applyArgs(res); //return if (Object.keys(self.argsToApply).length) { self.rest.push(self.argsToApply); } return self.invoke.apply(self, self.rest); } else if (self._L.isObj(self.first) && self.first.return) { var rtn = self.first.return; //return object, if func all and return return self._L.isFn(rtn) ? rtn.apply(self._this, self.argsToApply._fnArgs || []) : rtn; } else if (self._L.isObj(self.first) && self.first._fnArgs) { //first is return fn obj return self.first._fnArgs.length ? self.first._fnArgs : undefined; } else if (!self.firstIsFn && !self.firstIsUdf && self.first !== null) { //if first non-func assume args to be applied self.applyArgs(self.first); if (Object.keys(self.argsToApply).length) { self.rest.push(self.argsToApply); } return self.invoke.apply(self, self.rest); } else if (self._L.isUdf(self.first) && self.rest.length) { //first is undefined but still args to be called if (Object.keys(self.argsToApply).length) { //push args to arg chain self.rest.push(self.argsToApply); } return self.invoke.apply(self, self.rest); } else if (!self.rest.length) { //end call, no args to left to call //return args or undefined return Object.keys(self.argsToApply).length ? self.argsToApply._fnArgs : undefined; } return undefined; }, _L: { flatten: function flatten(val) { var flatten = function flatten(array, result) { for (var i = 0; i < array.length; i++) { var value = array[i]; if (Array.isArray(value)) { flatten(value, result); } else { result.push(value); } } return result; }; return flatten(val, []); }, defaults: function defaults() { var args = new Array(arguments.length); for (var i = 0; i < args.length; ++i) { args[i] = arguments[i]; } var orgObj = args.shift(); return _defaults2(orgObj, args); }, memoize: function memoize(fn) { return _memoize(fn); }, isFn: function isFn(val) { return isFunction(val); }, isObj: function isObj(val) { return isObject(val); }, isArr: function isArr(val) { return Array.isArray(val); }, isUdf: function isUdf(val) { return val === undefined; } } }); /* Export */ module.exports = function () { var args = new Array(arguments.length); for (var i = 0; i < args.length; ++i) { args[i] = arguments[i]; } if (!args.length) { return undefined; } var teFlow = new TeFlow(this); return teFlow.invoke.apply(teFlow._self, args); }; /***/ }) /******/ ]); }); //# sourceMappingURL=te-flow.js.map