UNPKG

irrelon-reactor-autonet

Version:

A module for automatically creating groups of self-networking services.

193 lines (159 loc) 6.14 kB
"use strict"; /** * Allows a method to accept overloaded calls with different parameters controlling * which passed overload function is called. * @param {String=} name A name to provide this overload to help identify * it if any errors occur during the resolving phase of the overload. This * is purely for debug purposes and serves no functional purpose. * @param {Object} def The overload definition. * @returns {Function} * @constructor */ Object.defineProperty(exports, "__esModule", { value: true }); var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol ? "symbol" : typeof obj; }; var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } var Overload = function () { function Overload(name, def) { _classCallCheck(this, Overload); if (!def) { def = name; name = undefined; } if (def) { var self = this, index, count, tmpDef, defNewKey, sigIndex, signatures; if (!(def instanceof Array)) { tmpDef = {}; // Def is an object, make sure all prop names are devoid of spaces for (index in def) { if (def.hasOwnProperty(index)) { defNewKey = index.replace(/ /g, ''); // Check if the definition array has a * string in it if (defNewKey.indexOf('*') === -1) { // No * found tmpDef[defNewKey] = def[index]; } else { // A * was found, generate the different signatures that this // definition could represent signatures = this.generateSignaturePermutations(defNewKey); for (sigIndex = 0; sigIndex < signatures.length; sigIndex++) { if (!tmpDef[signatures[sigIndex]]) { tmpDef[signatures[sigIndex]] = def[index]; } } } } } def = tmpDef; } return function () { var arr = [], lookup, type, overloadName; // Check if we are being passed a key/function object or an array of functions if (def instanceof Array) { // We were passed an array of functions count = def.length; for (index = 0; index < count; index++) { if (def[index].length === arguments.length) { return self.callExtend(this, '$main', def, def[index], arguments); } } } else { // Generate lookup key from arguments // Copy arguments to an array for (index = 0; index < arguments.length; index++) { type = _typeof(arguments[index]); // Handle detecting arrays if (type === 'object' && arguments[index] instanceof Array) { type = 'array'; } // Handle been presented with a single undefined argument if (arguments.length === 1 && type === 'undefined') { break; } // Add the type to the argument types array arr.push(type); } lookup = arr.join(','); // Check for an exact lookup match if (def[lookup]) { return self.callExtend(this, '$main', def, def[lookup], arguments); } else { for (index = arr.length; index >= 0; index--) { // Get the closest match lookup = arr.slice(0, index).join(','); if (def[lookup + ',...']) { // Matched against arguments + "any other" return self.callExtend(this, '$main', def, def[lookup + ',...'], arguments); } } } } overloadName = name !== undefined ? name : typeof this.name === 'function' ? this.name() : 'Unknown'; console.log('Overload Definition:', def); throw 'ForerunnerDB.Overload "' + overloadName + '": Overloaded method does not have a matching signature "' + lookup + '" for the passed arguments: ' + this.jStringify(arr); }; } return function () {}; } /** * Generates an array of all the different definition signatures that can be * created from the passed string with a catch-all wildcard *. E.g. it will * convert the signature: string,*,string to all potentials: * string,string,string * string,number,string * string,object,string, * string,function,string, * string,undefined,string * * @param {String} str Signature string with a wildcard in it. * @returns {Array} An array of signature strings that are generated. */ _createClass(Overload, [{ key: 'generateSignaturePermutations', value: function generateSignaturePermutations(str) { var signatures = [], newSignature, types = ['array', 'string', 'object', 'number', 'function', 'undefined'], index; if (str.indexOf('*') > -1) { // There is at least one "any" type, break out into multiple keys // We could do this at query time with regular expressions but // would be significantly slower for (index = 0; index < types.length; index++) { newSignature = str.replace('*', types[index]); signatures = signatures.concat(this.generateSignaturePermutations(newSignature)); } } else { signatures.push(str); } return signatures; } }, { key: 'callExtend', value: function callExtend(context, prop, propContext, func, args) { var tmp, ret; if (context && propContext[prop]) { tmp = context[prop]; context[prop] = propContext[prop]; ret = func.apply(context, args); context[prop] = tmp; return ret; } else { return func.apply(context, args); } } }]); return Overload; }(); exports.default = Overload;