Remove wrapper modules.

This commit is contained in:
John-David Dalton
2017-01-11 01:08:41 -08:00
parent 454219fbfe
commit c6854fa8fc
16 changed files with 0 additions and 653 deletions

View File

@@ -1,17 +0,0 @@
import identity from './identity.js';
import metaMap from './.internal/metaMap.js';
/**
* The base implementation of `setData` without support for hot loop shorting.
*
* @private
* @param {Function} func The function to associate metadata with.
* @param {*} data The metadata.
* @returns {Function} Returns `func`.
*/
const baseSetData = !metaMap ? identity : (func, data) => {
metaMap.set(func, data);
return func;
};
export default baseSetData;

View File

@@ -1,28 +0,0 @@
import createCtor from './.internal/createCtor.js';
import root from './.internal/root.js';
/** Used to compose bitmasks for function metadata. */
const WRAP_BIND_FLAG = 1;
/**
* Creates a function that wraps `func` to invoke it with the optional `this`
* binding of `thisArg`.
*
* @private
* @param {Function} func The function to wrap.
* @param {number} bitmask The bitmask flags. See `createWrap` for more details.
* @param {*} [thisArg] The `this` binding of `func`.
* @returns {Function} Returns the new wrapped function.
*/
function createBind(func, bitmask, thisArg) {
const isBind = bitmask & WRAP_BIND_FLAG;
const Ctor = createCtor(func);
function wrapper(...args) {
const fn = (this && this !== root && this instanceof wrapper) ? Ctor : func;
return fn.apply(isBind ? thisArg : this, args);
}
return wrapper;
}
export default createBind;

View File

@@ -1,40 +0,0 @@
import apply from './.internal/apply.js';
import createCtor from './.internal/createCtor.js';
import createHybrid from './.internal/createHybrid.js';
import createRecurry from './.internal/createRecurry.js';
import getHolder from './.internal/getHolder.js';
import replaceHolders from './.internal/replaceHolders.js';
import root from './.internal/root.js';
/**
* Creates a function that wraps `func` to enable currying.
*
* @private
* @param {Function} func The function to wrap.
* @param {number} bitmask The bitmask flags. See `createWrap` for more details.
* @param {number} arity The arity of `func`.
* @returns {Function} Returns the new wrapped function.
*/
function createCurry(func, bitmask, arity) {
const Ctor = createCtor(func);
function wrapper(...args) {
let length = args.length;
const placeholder = getHolder(wrapper);
const holders = (length < 3 && args[0] !== placeholder && args[length - 1] !== placeholder)
? []
: replaceHolders(args, placeholder);
length -= holders.length;
if (length < arity) {
return createRecurry(
func, bitmask, createHybrid, wrapper.placeholder, undefined,
args, holders, undefined, undefined, arity - length);
}
const fn = (this && this !== root && this instanceof wrapper) ? Ctor : func;
return apply(fn, this, args);
}
return wrapper;
}
export default createCurry;

View File

@@ -1,94 +0,0 @@
import composeArgs from './.internal/composeArgs.js';
import composeArgsRight from './.internal/composeArgsRight.js';
import countHolders from './.internal/countHolders.js';
import createCtor from './.internal/createCtor.js';
import createRecurry from './.internal/createRecurry.js';
import getHolder from './.internal/getHolder.js';
import reorder from './.internal/reorder.js';
import replaceHolders from './.internal/replaceHolders.js';
import root from './.internal/root.js';
/** Used to compose bitmasks for function metadata. */
const WRAP_BIND_FLAG = 1;
const WRAP_BIND_KEY_FLAG = 2;
const WRAP_CURRY_FLAG = 8;
const WRAP_CURRY_RIGHT_FLAG = 16;
const WRAP_ARY_FLAG = 128;
const WRAP_FLIP_FLAG = 512;
/**
* Creates a function that wraps `func` to invoke it with optional `this`
* binding of `thisArg`, partial application, and currying.
*
* @private
* @param {Function|string} func The function or method name to wrap.
* @param {number} bitmask The bitmask flags. See `createWrap` for more details.
* @param {*} [thisArg] The `this` binding of `func`.
* @param {Array} [partials] The arguments to prepend to those provided to
* the new function.
* @param {Array} [holders] The `partials` placeholder indexes.
* @param {Array} [partialsRight] The arguments to append to those provided
* to the new function.
* @param {Array} [holdersRight] The `partialsRight` placeholder indexes.
* @param {Array} [argPos] The argument positions of the new function.
* @param {number} [ary] The arity cap of `func`.
* @param {number} [arity] The arity of `func`.
* @returns {Function} Returns the new wrapped function.
*/
function createHybrid(func, bitmask, thisArg, partials, holders, partialsRight, holdersRight, argPos, ary, arity) {
const isAry = bitmask & WRAP_ARY_FLAG;
const isBind = bitmask & WRAP_BIND_FLAG;
const isBindKey = bitmask & WRAP_BIND_KEY_FLAG;
const isCurried = bitmask & (WRAP_CURRY_FLAG | WRAP_CURRY_RIGHT_FLAG);
const isFlip = bitmask & WRAP_FLIP_FLAG;
const Ctor = isBindKey ? undefined : createCtor(func);
function wrapper() {
let holderCount;
let placeholder;
let length = arguments.length;
let args = Array(length);
let index = length;
while (index--) {
args[index] = arguments[index];
}
if (isCurried) {
placeholder = getHolder(wrapper);
holdersCount = countHolders(args, placeholder);
}
if (partials) {
args = composeArgs(args, partials, holders, isCurried);
}
if (partialsRight) {
args = composeArgsRight(args, partialsRight, holdersRight, isCurried);
}
length -= holdersCount;
if (isCurried && length < arity) {
const newHolders = replaceHolders(args, placeholder);
return createRecurry(
func, bitmask, createHybrid, wrapper.placeholder, thisArg,
args, newHolders, argPos, ary, arity - length
);
}
const thisBinding = isBind ? thisArg : this;
let fn = isBindKey ? thisBinding[func] : func;
length = args.length;
if (argPos) {
args = reorder(args, argPos);
} else if (isFlip && length > 1) {
args.reverse();
}
if (isAry && ary < length) {
args.length = ary;
}
if (this && this !== root && this instanceof wrapper) {
fn = Ctor || createCtor(fn);
}
return fn.apply(thisBinding, args);
}
return wrapper;
}
export default createHybrid;

View File

@@ -1,44 +0,0 @@
import apply from './.internal/apply.js';
import createCtor from './.internal/createCtor.js';
import root from './.internal/root.js';
/** Used to compose bitmasks for function metadata. */
const WRAP_BIND_FLAG = 1;
/**
* Creates a function that wraps `func` to invoke it with the `this` binding
* of `thisArg` and `partials` prepended to the arguments it receives.
*
* @private
* @param {Function} func The function to wrap.
* @param {number} bitmask The bitmask flags. See `createWrap` for more details.
* @param {*} thisArg The `this` binding of `func`.
* @param {Array} partials The arguments to prepend to those provided to
* the new function.
* @returns {Function} Returns the new wrapped function.
*/
function createPartial(func, bitmask, thisArg, partials) {
const isBind = bitmask & WRAP_BIND_FLAG;
const Ctor = createCtor(func);
function wrapper() {
let argsIndex = -1;
let argsLength = arguments.length;
let leftIndex = -1;
const leftLength = partials.length;
const args = Array(leftLength + argsLength);
const fn = (this && this !== root && this instanceof wrapper) ? Ctor : func;
while (++leftIndex < leftLength) {
args[leftIndex] = partials[leftIndex];
}
while (argsLength--) {
args[leftIndex++] = arguments[++argsIndex];
}
return apply(fn, isBind ? thisArg : this, args);
}
return wrapper;
}
export default createPartial;

View File

@@ -1,56 +0,0 @@
import isLaziable from './.internal/isLaziable.js';
import setData from './.internal/setData.js';
import setWrapToString from './.internal/setWrapToString.js';
/** Used to compose bitmasks for function metadata. */
const WRAP_BIND_FLAG = 1;
const WRAP_BIND_KEY_FLAG = 2;
const WRAP_CURRY_BOUND_FLAG = 4;
const WRAP_CURRY_FLAG = 8;
const WRAP_PARTIAL_FLAG = 32;
const WRAP_PARTIAL_RIGHT_FLAG = 64;
/**
* Creates a function that wraps `func` to continue currying.
*
* @private
* @param {Function} func The function to wrap.
* @param {number} bitmask The bitmask flags. See `createWrap` for more details.
* @param {Function} wrapFunc The function to create the `func` wrapper.
* @param {*} placeholder The placeholder value.
* @param {*} [thisArg] The `this` binding of `func`.
* @param {Array} [partials] The arguments to prepend to those provided to
* the new function.
* @param {Array} [holders] The `partials` placeholder indexes.
* @param {Array} [argPos] The argument positions of the new function.
* @param {number} [ary] The arity cap of `func`.
* @param {number} [arity] The arity of `func`.
* @returns {Function} Returns the new wrapped function.
*/
function createRecurry(func, bitmask, wrapFunc, placeholder, thisArg, partials, holders, argPos, ary, arity) {
const isCurry = bitmask & WRAP_CURRY_FLAG;
const newHolders = isCurry ? holders : undefined;
const newHoldersRight = isCurry ? undefined : holders;
const newPartials = isCurry ? partials : undefined;
const newPartialsRight = isCurry ? undefined : partials;
bitmask |= (isCurry ? WRAP_PARTIAL_FLAG : WRAP_PARTIAL_RIGHT_FLAG);
bitmask &= ~(isCurry ? WRAP_PARTIAL_RIGHT_FLAG : WRAP_PARTIAL_FLAG);
if (!(bitmask & WRAP_CURRY_BOUND_FLAG)) {
bitmask &= ~(WRAP_BIND_FLAG | WRAP_BIND_KEY_FLAG);
}
const newData = [
func, bitmask, thisArg, newPartials, newHolders, newPartialsRight,
newHoldersRight, argPos, ary, arity
];
const result = wrapFunc(...newData);
if (isLaziable(func)) {
setData(result, newData);
}
result.placeholder = placeholder;
return setWrapToString(result, func, bitmask);
}
export default createRecurry;

View File

@@ -1,105 +0,0 @@
import baseSetData from './.internal/baseSetData.js';
import createBind from './.internal/createBind.js';
import createCurry from './.internal/createCurry.js';
import createHybrid from './.internal/createHybrid.js';
import createPartial from './.internal/createPartial.js';
import getData from './.internal/getData.js';
import mergeData from './.internal/mergeData.js';
import setData from './.internal/setData.js';
import setWrapToString from './.internal/setWrapToString.js';
import toInteger from './toInteger.js';
/** Used to compose bitmasks for function metadata. */
const WRAP_BIND_FLAG = 1;
const WRAP_BIND_KEY_FLAG = 2;
const WRAP_CURRY_FLAG = 8;
const WRAP_CURRY_RIGHT_FLAG = 16;
const WRAP_PARTIAL_FLAG = 32;
const WRAP_PARTIAL_RIGHT_FLAG = 64;
/* Built-in method references for those with the same name as other `lodash` methods. */
const nativeMax = Math.max;
/**
* Creates a function that either curries or invokes `func` with optional
* `this` binding and partially applied arguments.
*
* @private
* @param {Function|string} func The function or method name to wrap.
* @param {number} bitmask The bitmask flags.
* 1 - `bind`
* 2 - `bindKey`
* 4 - `curry` or `curryRight` of a bound function
* 8 - `curry`
* 16 - `curryRight`
* 32 - `partial`
* 64 - `partialRight`
* 128 - `rearg`
* 256 - `ary`
* 512 - `flip`
* @param {*} [thisArg] The `this` binding of `func`.
* @param {Array} [partials] The arguments to be partially applied.
* @param {Array} [holders] The `partials` placeholder indexes.
* @param {Array} [argPos] The argument positions of the new function.
* @param {number} [ary] The arity cap of `func`.
* @param {number} [arity] The arity of `func`.
* @returns {Function} Returns the new wrapped function.
*/
function createWrap(func, bitmask, thisArg, partials, holders, argPos, ary, arity) {
const isBindKey = bitmask & WRAP_BIND_KEY_FLAG;
if (!isBindKey && typeof func != 'function') {
throw new TypeError('Expected a function');
}
let length = partials ? partials.length : 0;
if (!length) {
bitmask &= ~(WRAP_PARTIAL_FLAG | WRAP_PARTIAL_RIGHT_FLAG);
partials = holders = undefined;
}
ary = ary === undefined ? ary : nativeMax(toInteger(ary), 0);
arity = arity === undefined ? arity : toInteger(arity);
length -= holders ? holders.length : 0;
let holdersRight;
let partialsRight;
if (bitmask & WRAP_PARTIAL_RIGHT_FLAG) {
partialsRight = partials,
holdersRight = holders;
partials = holders = undefined;
}
const data = isBindKey ? undefined : getData(func);
const newData = [
func, bitmask, thisArg, partials, holders, partialsRight, holdersRight,
argPos, ary, arity
];
if (data) {
mergeData(newData, data);
}
func = newData[0];
bitmask = newData[1];
thisArg = newData[2];
partials = newData[3];
holders = newData[4];
arity = newData[9] = newData[9] === undefined
? (isBindKey ? 0 : func.length)
: nativeMax(newData[9] - length, 0);
if (!arity && bitmask & (WRAP_CURRY_FLAG | WRAP_CURRY_RIGHT_FLAG)) {
bitmask &= ~(WRAP_CURRY_FLAG | WRAP_CURRY_RIGHT_FLAG);
}
let result;
if (!bitmask || bitmask == WRAP_BIND_FLAG) {
result = createBind(func, bitmask, thisArg);
} else if (bitmask == WRAP_CURRY_FLAG || bitmask == WRAP_CURRY_RIGHT_FLAG) {
result = createCurry(func, bitmask, arity);
} else if ((bitmask == WRAP_PARTIAL_FLAG || bitmask == (WRAP_BIND_FLAG | WRAP_PARTIAL_FLAG)) && !holders.length) {
result = createPartial(func, bitmask, thisArg, partials);
} else {
result = createHybrid(...newData);
}
const setter = data ? baseSetData : setData;
return setWrapToString(setter(result, newData), func, bitmask);
}
export default createWrap;

View File

@@ -1,14 +0,0 @@
import metaMap from './.internal/metaMap.js';
/**
* Gets metadata for `func`.
*
* @private
* @param {Function} func The function to query.
* @returns {*} Returns the metadata for `func`.
*/
const getData = metaMap
? func => metaMap.get(func)
: () => {};
export default getData;

View File

@@ -1,17 +0,0 @@
/** Used to match wrap detail comments. */
const reWrapDetails = /\{\n\/\* \[wrapped with (.+)\] \*/;
const reSplitDetails = /,? & /;
/**
* Extracts wrapper details from the `source` body comment.
*
* @private
* @param {string} source The source to inspect.
* @returns {Array} Returns the wrapper details.
*/
function getWrapDetails(source) {
const match = source.match(reWrapDetails);
return match ? match[1].split(reSplitDetails) : [];
}
export default getWrapDetails;

View File

@@ -1,23 +0,0 @@
/** Used to match wrap detail comments. */
const reWrapComment = /\{(?:\n\/\* \[wrapped with .+\] \*\/)?\n?/;
/**
* Inserts wrapper `details` in a comment at the top of the `source` body.
*
* @private
* @param {string} source The source to modify.
* @returns {Array} details The details to insert.
* @returns {string} Returns the modified source.
*/
function insertWrapDetails(source, details) {
const length = details.length;
if (!length) {
return source;
}
const lastIndex = length - 1;
details[lastIndex] = (length > 1 ? '& ' : '') + details[lastIndex];
details = details.join(length > 2 ? ', ' : ' ');
return source.replace(reWrapComment, `{\n/* [wrapped with ${ details }] */\n`);
}
export default insertWrapDetails;

View File

@@ -1,20 +0,0 @@
import baseSetData from './.internal/baseSetData.js';
import shortOut from './.internal/shortOut.js';
/**
* Sets metadata for `func`.
*
* **Note:** If this function becomes hot, i.e. is invoked a lot in a short
* period of time, it will trip its breaker and transition to an identity
* function to avoid garbage collection pauses in V8. See
* [V8 issue 2070](https://bugs.chromium.org/p/v8/issues/detail?id=2070)
* for more details.
*
* @private
* @param {Function} func The function to associate metadata with.
* @param {*} data The metadata.
* @returns {Function} Returns `func`.
*/
const setData = shortOut(baseSetData);
export default setData;

View File

@@ -1,21 +0,0 @@
import getWrapDetails from './.internal/getWrapDetails.js';
import insertWrapDetails from './.internal/insertWrapDetails.js';
import setToString from './.internal/setToString.js';
import updateWrapDetails from './.internal/updateWrapDetails.js';
/**
* Sets the `toString` method of `wrapper` to mimic the source of `reference`
* with wrapper details in a comment at the top of the source body.
*
* @private
* @param {Function} wrapper The function to modify.
* @param {Function} reference The reference function.
* @param {number} bitmask The bitmask flags. See `createWrap` for more details.
* @returns {Function} Returns `wrapper`.
*/
function setWrapToString(wrapper, reference, bitmask) {
const source = `${ reference }`;
return setToString(wrapper, insertWrapDetails(source, updateWrapDetails(getWrapDetails(source), bitmask)));
}
export default setWrapToString;

View File

@@ -1,37 +0,0 @@
/** Used to detect hot functions by number of calls within a span of milliseconds. */
const HOT_COUNT = 800;
const HOT_SPAN = 16;
/* Built-in method references for those with the same name as other `lodash` methods. */
const nativeNow = Date.now;
/**
* Creates a function that'll short out and invoke `identity` instead
* of `func` when it's called `HOT_COUNT` or more times in `HOT_SPAN`
* milliseconds.
*
* @private
* @param {Function} func The function to restrict.
* @returns {Function} Returns the new shortable function.
*/
function shortOut(func) {
let count = 0;
let lastCalled = 0;
return function(...args) {
const stamp = nativeNow();
const remaining = HOT_SPAN - (stamp - lastCalled);
lastCalled = stamp;
if (remaining > 0) {
if (++count >= HOT_COUNT) {
return args[0];
}
} else {
count = 0;
}
return func(...args);
};
}
export default shortOut;

View File

@@ -1,46 +0,0 @@
import arrayEach from './.internal/arrayEach.js';
import arrayIncludes from './.internal/arrayIncludes.js';
/** Used to compose bitmasks for function metadata. */
const WRAP_BIND_FLAG = 1;
const WRAP_BIND_KEY_FLAG = 2;
const WRAP_CURRY_FLAG = 8;
const WRAP_CURRY_RIGHT_FLAG = 16;
const WRAP_PARTIAL_FLAG = 32;
const WRAP_PARTIAL_RIGHT_FLAG = 64;
const WRAP_ARY_FLAG = 128;
const WRAP_REARG_FLAG = 256;
const WRAP_FLIP_FLAG = 512;
/** Used to associate wrap methods with their bit flags. */
const wrapFlags = [
['ary', WRAP_ARY_FLAG],
['bind', WRAP_BIND_FLAG],
['bindKey', WRAP_BIND_KEY_FLAG],
['curry', WRAP_CURRY_FLAG],
['curryRight', WRAP_CURRY_RIGHT_FLAG],
['flip', WRAP_FLIP_FLAG],
['partial', WRAP_PARTIAL_FLAG],
['partialRight', WRAP_PARTIAL_RIGHT_FLAG],
['rearg', WRAP_REARG_FLAG]
];
/**
* Updates wrapper `details` based on `bitmask` flags.
*
* @private
* @returns {Array} details The details to modify.
* @param {number} bitmask The bitmask flags. See `createWrap` for more details.
* @returns {Array} Returns `details`.
*/
function updateWrapDetails(details, bitmask) {
arrayEach(wrapFlags, pair => {
const value = `${ pair[0] }`;
if ((bitmask & pair[1]) && !arrayIncludes(details, value)) {
details.push(value);
}
});
return details.sort();
}
export default updateWrapDetails;

55
bind.js
View File

@@ -1,55 +0,0 @@
import createWrap from './.internal/createWrap.js';
import getHolder from './.internal/getHolder.js';
import replaceHolders from './.internal/replaceHolders.js';
/** Used to compose bitmasks for function metadata. */
const WRAP_BIND_FLAG = 1;
const WRAP_PARTIAL_FLAG = 32;
/**
* Creates a function that invokes `func` with the `this` binding of `thisArg`
* and `partials` prepended to the arguments it receives.
*
* The `bind.placeholder` value, which defaults to `_` in monolithic builds,
* may be used as a placeholder for partially applied arguments.
*
* **Note:** Unlike native `Function#bind`, this method doesn't set the "length"
* property of bound functions.
*
* @since 0.1.0
* @category Function
* @param {Function} func The function to bind.
* @param {*} thisArg The `this` binding of `func`.
* @param {...*} [partials] The arguments to be partially applied.
* @returns {Function} Returns the new bound function.
* @example
*
* function greet(greeting, punctuation) {
* return greeting + ' ' + this.user + punctuation;
* }
*
* const object = { 'user': 'fred' };
*
* const bound = bind(greet, object, 'hi');
* bound('!');
* // => 'hi fred!'
*
* // Bound with placeholders.
* const bound = bind(greet, object, _, '!');
* bound('hi');
* // => 'hi fred!'
*/
function bind(func, thisArg, ...partials) {
let holders;
let bitmask = WRAP_BIND_FLAG;
if (partials.length) {
holders = replaceHolders(partials, getHolder(bind));
bitmask |= WRAP_PARTIAL_FLAG;
}
return createWrap(func, bitmask, thisArg, partials, holders);
}
// Assign default placeholders.
bind.placeholder = {};
export default bind;

View File

@@ -1,36 +0,0 @@
import arrayEach from './.internal/arrayEach.js';
import baseAssignValue from './.internal/baseAssignValue.js';
import bind from './bind.js';
import toKey from './.internal/toKey.js';
/**
* Binds methods of an object to the object itself, overwriting the existing
* method.
*
* **Note:** This method doesn't set the "length" property of bound functions.
*
* @since 0.1.0
* @category Util
* @param {Object} object The object to bind and assign the bound methods to.
* @param {...(string|string[])} methodNames The object method names to bind.
* @returns {Object} Returns `object`.
* @example
*
* const view = {
* 'label': 'docs',
* 'click': () => console.log(`clicked ${ this.label }`)
* };
*
* bindAll(view, ['click']);
* jQuery(element).on('click', view.click);
* // => Logs 'clicked docs' when clicked.
*/
function bindAll(object, ...methodNames) {
arrayEach(methodNames, key => {
key = toKey(key);
baseAssignValue(object, key, bind(object[key], object));
});
return object;
}
export default bindAll;