@mathigon/core
Advanced tools
Comparing version 0.1.1 to 0.1.2
{ | ||
"name": "@mathigon/core", | ||
"version": "0.1.1", | ||
"version": "0.1.2", | ||
"description": "JavaScript utilities library containing function wrappers, string and array helper functions, type checking and event classes.", | ||
@@ -21,3 +21,15 @@ "keywords": [ | ||
"jsnext:main": "index", | ||
"repository": "mathigon/core.js" | ||
"repository": "mathigon/core.js", | ||
"scripts": { | ||
"install": "mkdir build && rollup -c build.js", | ||
"pretest": "rollup -c build.js", | ||
"test": "tape 'test/**/*-test.js' && eslint index.js src", | ||
"prepublish": "npm run test" | ||
}, | ||
"devDependencies": { | ||
"eslint": "^4.1.1", | ||
"rollup": "^0.43.0", | ||
"rollup-plugin-node-resolve": "^3.0.0", | ||
"tape": "^4.7.0" | ||
} | ||
} |
@@ -11,10 +11,10 @@ # Core.js | ||
Core.js is not intended to be used on its own, but as a dependency of another | ||
module or application. You can install it easily using `npm install m-core`. | ||
module or application. You can install it easily using | ||
`npm install @mathigon/core`. | ||
Now use [ES6 imports](http://2ality.com/2014/09/es6-modules-final.html) to | ||
require specific classes or functions. For example, | ||
require specific classes or functions: | ||
```js | ||
import average from 'core.arrays' | ||
import utilities from 'core' | ||
import { average, Evented } from '@mathigon/core' | ||
``` | ||
@@ -21,0 +21,0 @@ |
@@ -11,9 +11,6 @@ // ============================================================================= | ||
// ----------------------------------------------------------------------------- | ||
// Array Generators | ||
function _tabulateWith(fn, vals, args) { | ||
if (!args.length) return run(fn, vals); | ||
if (!args.length) return run(fn, ...vals); | ||
let newArgs = Array.prototype.slice.call(args, 0); | ||
let newArgs = args.slice(0); | ||
let x = newArgs.shift(); | ||
@@ -28,2 +25,11 @@ | ||
/** | ||
* Creates a multi-dimensional array contains fn(i1, i2, ..., in) in cell | ||
* [i1][i2]...[in]. If the first argument is not a function, every item in the | ||
* resulting array will have that static value. | ||
* | ||
* @param {Function|*} fn | ||
* @param {...number} dimensions | ||
* @returns {Array} | ||
*/ | ||
export function tabulate(fn, ...dimensions) { | ||
@@ -33,2 +39,9 @@ return _tabulateWith(fn, [], dimensions); | ||
/** | ||
* @param {number} a | ||
* @param {?number} b | ||
* @param {?number} step | ||
* @returns {Array} | ||
*/ | ||
export function list(a, b, step = 1) { | ||
@@ -51,5 +64,7 @@ let arr = []; | ||
// ----------------------------------------------------------------------------- | ||
// Array Utilities | ||
/** | ||
* Returns the last item in an array. | ||
* @param {Array} array | ||
* @returns {*} | ||
*/ | ||
export function last(array) { | ||
@@ -59,7 +74,22 @@ return array[array.length - 1]; | ||
/** | ||
* Maps a function over multiple arrays, the entries of which are passed as | ||
* multiple arguments. | ||
* @param {Function} fn | ||
* @param {...Array} args | ||
* @returns {Array} | ||
*/ | ||
export function map(fn, ...args) { | ||
let length = Math.max(...args.map(a => a.length)); | ||
return tabulate(i => fn(...arrays.map(a => a[i])), length); | ||
return tabulate(i => fn(...args.map(a => a[i])), length); | ||
} | ||
/** | ||
* Finds the sum of all elements in an numeric array. This operation is safe, | ||
* i.e. any values that can't be cast to a number are counted as 0. | ||
* @param {Array} array | ||
* @returns {number} | ||
*/ | ||
export function total(array) { | ||
@@ -70,2 +100,8 @@ if (!array.length) return 0; | ||
/** | ||
* Evaluates the average of all the elements in an array. | ||
* @param {Array} array | ||
* @returns {number} | ||
*/ | ||
export function average(array) { | ||
@@ -75,2 +111,9 @@ return array.total / array.length; | ||
/** | ||
* Checks if an array contains a specific value. | ||
* @param {Array} array | ||
* @param {*} value | ||
* @returns {boolean} | ||
*/ | ||
export function contains(array, value) { | ||
@@ -80,2 +123,8 @@ return array.indexOf(value) >= 0; | ||
/** | ||
* | ||
* @param array | ||
* @param id | ||
*/ | ||
export function extract(array, id) { | ||
@@ -85,2 +134,9 @@ return array.map(a => a[id]); | ||
/** | ||
* | ||
* @param keys | ||
* @param values | ||
* @returns {{}} | ||
*/ | ||
export function zip(keys, values) { | ||
@@ -93,2 +149,10 @@ let obj = {}; | ||
/** | ||
* | ||
* @param {Array} array | ||
* @param {string} id | ||
* @param {?boolean} reverse | ||
* @returns {Array} | ||
*/ | ||
export function sortBy(array, id, reverse = false) { | ||
@@ -101,2 +165,10 @@ return array.slice(0).sort((a, b) => { | ||
/** | ||
* | ||
* @param {Array} array | ||
* @param {Function} fn | ||
* @param {?boolean} reverse | ||
* @returns {Array} | ||
*/ | ||
export function sortByFn(array, fn, reverse = false) { | ||
@@ -110,2 +182,9 @@ return array.slice(0).sort((a, b) => { | ||
/** | ||
* Returns a function that can be called repeatedly, and returns items of the | ||
* array, continuously looping | ||
* @param {Array} array | ||
* @returns {Function} | ||
*/ | ||
export function loop(array) { | ||
@@ -117,5 +196,7 @@ let i = -1; | ||
// ----------------------------------------------------------------------------- | ||
// Array Modifiers | ||
/** | ||
* | ||
* @param array | ||
* @returns {Function} | ||
*/ | ||
export function unique(array) { | ||
@@ -126,3 +207,8 @@ return array.filter((a, i, _this) => _this.indexOf(a) == i); | ||
// Removes any null or undefined values in array a | ||
/** | ||
* Removes any null or undefined values in array a. | ||
* @param {Array} array | ||
* @return {Array} | ||
*/ | ||
export function clean(array) { | ||
@@ -132,3 +218,9 @@ return array.filter(a => a != null); | ||
// Removes all occurrences of x from the array a | ||
/** | ||
* Removes all occurrences of x from an array. | ||
* @param {Array} array | ||
* @param {*} x | ||
* @return {Array} | ||
*/ | ||
export function without(array, x) { | ||
@@ -138,2 +230,7 @@ return array.filter(a => a !== x); | ||
/** | ||
* | ||
* @param array | ||
*/ | ||
export function flatten(array) { | ||
@@ -144,2 +241,7 @@ return array.reduce((a, b) => | ||
/** | ||
* | ||
* @param array | ||
*/ | ||
export function cumulative(array) { | ||
@@ -150,3 +252,9 @@ let total = 0; | ||
// Breaks an array into chunks of size at most n | ||
/** | ||
* Breaks an array into chunks of size at most n. | ||
* @param array | ||
* @param n | ||
* @returns {Array} | ||
*/ | ||
export function chunk(array, n) { | ||
@@ -160,3 +268,8 @@ let chunks = []; | ||
// Rotates the elements of an array by offset | ||
/** | ||
* Rotates the elements of an array by offset. | ||
* @param array | ||
* @param offset | ||
*/ | ||
export function rotate(array, offset) { | ||
@@ -172,5 +285,8 @@ let n = array.length; | ||
// ----------------------------------------------------------------------------- | ||
// Array Combinations | ||
/** | ||
* | ||
* @param a1 | ||
* @param a2 | ||
* @returns {Array} | ||
*/ | ||
export function intersect(a1, a2) { | ||
@@ -184,2 +300,9 @@ let result = []; | ||
/** | ||
* | ||
* @param a1 | ||
* @param a2 | ||
* @returns {[*,*]} | ||
*/ | ||
export function difference(a1, a2) { | ||
@@ -186,0 +309,0 @@ let notIn1 = a2.filter(a => !a1.includes(a)); |
@@ -13,4 +13,12 @@ // ============================================================================= | ||
/** | ||
* This is our base class for event management. It is rarely used on its own, | ||
* but many other classes inherit from Evented. | ||
*/ | ||
export default class Evented { | ||
/** | ||
* @param {string} split | ||
* @param {boolean} lowercase | ||
*/ | ||
constructor({ split = ' ', lowercase = false } = {}) { | ||
@@ -21,5 +29,7 @@ this._options = { split, lowercase }; | ||
// --------------------------------------------------------------------------- | ||
// Events | ||
/** | ||
* Adds an event listener for one or more events. | ||
* @param {string} events | ||
* @param {Function} fn | ||
*/ | ||
on(events, fn) { | ||
@@ -32,2 +42,7 @@ for (let e of process(events, this._options)) { | ||
/** | ||
* Adds a one-time event listener to one or more events. | ||
* @param {string} events | ||
* @param {Function} fn | ||
*/ | ||
one(events, fn) { | ||
@@ -43,2 +58,7 @@ let _this = this; | ||
/** | ||
* Removes an event listener from one or more events. | ||
* @param {string} events | ||
* @param {Function} fn | ||
*/ | ||
off(events, fn) { | ||
@@ -51,2 +71,8 @@ for (let e of process(events, this._options)) { | ||
/** | ||
* Triggers one or more events, and executes all bound event listeners with | ||
* the given arguments. | ||
* @param {string} events | ||
* @param {...*} args | ||
*/ | ||
trigger(events, ...args) { | ||
@@ -53,0 +79,0 @@ for (let e of process(events, this._options)) { |
@@ -11,2 +11,7 @@ // ============================================================================= | ||
/** | ||
* Splits a string into space separated words. | ||
* @param {string} str | ||
* @returns {Array<string>} | ||
*/ | ||
export function words(str) { | ||
@@ -17,8 +22,18 @@ if (!str) return []; | ||
/** | ||
* Converts a string to title case. | ||
* @param {string} str | ||
* @returns {string} | ||
*/ | ||
export function toTitleCase(str) { | ||
return str.replace(/\S+/g, function(a){ | ||
return a.charAt(0).toUpperCase() + a.slice(1); | ||
}); | ||
return str.replace(/\S+/g, a => a.charAt(0).toUpperCase() + a.slice(1)); | ||
} | ||
/** | ||
* Converts a string to camel case. | ||
* @param {string} str | ||
* @returns {string} | ||
*/ | ||
export function toCamelCase(str) { | ||
@@ -29,2 +44,9 @@ return str.toLowerCase().replace(/^-/,'') | ||
/** | ||
* Repeats a string n times. | ||
* @param {string} str | ||
* @param {?number} n | ||
* @returns {string} | ||
*/ | ||
export function repeat(str, n = 1) { | ||
@@ -35,2 +57,9 @@ for (let i=1; i<n; ++i) str += str; | ||
/** | ||
* Determines the Levenshtein distance between two strings. | ||
* @param {string} s1 | ||
* @param {string} s2 | ||
* @returns {number} | ||
*/ | ||
export function stringDistance(s1, s2) { | ||
@@ -50,2 +79,9 @@ let arr = tabulate(0, s1.length + 1, s2.length + 1); | ||
/** | ||
* Tries to autocorrect a word from a dictionary. | ||
* @param {string} word | ||
* @param {Array<string>} dict | ||
* @returns {string|null} | ||
*/ | ||
export function autocorrect(word, dict) { | ||
@@ -52,0 +88,0 @@ let maxDistance = word.length / 2; |
@@ -10,2 +10,9 @@ // ============================================================================= | ||
/** | ||
* Returns the type of an object. Possible values are 'number', 'string', | ||
* 'boolean', 'array', 'object', 'date', 'function', 'NaN', 'null', 'undefined', | ||
* as well as class names like 'htmldocument'. | ||
* @param {*} obj | ||
* @returns {string} | ||
*/ | ||
export function typeOf(obj) { | ||
@@ -18,2 +25,8 @@ if (obj == null) return '' + obj; | ||
/** | ||
* Checks if an object has a specific type. | ||
* @param {*} x | ||
* @param {string} type | ||
* @returns {boolean} | ||
*/ | ||
export function isType(x, type) { | ||
@@ -20,0 +33,0 @@ return typeOf(x) === type; |
@@ -8,4 +8,13 @@ // ============================================================================= | ||
/** | ||
* Empty Function. | ||
*/ | ||
export function noop() {} | ||
/** | ||
* Creates a random UID string of a given length. | ||
* @param {?number} n | ||
* @returns {string} | ||
*/ | ||
export function uid(n = 10) { | ||
@@ -15,10 +24,22 @@ return Math.random().toString(36).substr(2, n); | ||
export function run(obj, args = [], _this = null) { | ||
if (obj instanceof Function) { | ||
return obj.apply(_this, args); | ||
} | ||
/** | ||
* If obj is a function, it evaluates it with a given set of attributes. | ||
* Otherwise it just returns obj directly. | ||
* @param {Function|*} obj | ||
* @param {...*} args | ||
* @returns {*} | ||
*/ | ||
export function run(obj, ...args) { | ||
if (obj instanceof Function) return obj(...args); | ||
return obj; | ||
} | ||
// Checks if x is strictly equal to any one of the following arguments | ||
/** | ||
* Checks if x is strictly equal to any one of the following arguments | ||
* @param {*} x | ||
* @param {...*} values | ||
* @returns {boolean} | ||
*/ | ||
export function isOneOf(x, ...values) { | ||
@@ -31,3 +52,8 @@ for (let v of values) { | ||
// Merges multiple objects into a single one | ||
/** | ||
* Merges multiple objects into the first one. | ||
* @param {Object} first | ||
* @param {...Object} others | ||
*/ | ||
export function extend(first, ...others) { | ||
@@ -39,5 +65,10 @@ for (let obj of others) { | ||
} | ||
return first; | ||
} | ||
/** | ||
* Deep extends obj1 using th | ||
* @param obj1 | ||
* @param obj2 | ||
*/ | ||
export function deepExtend(obj1, obj2) { | ||
@@ -56,2 +87,10 @@ for (let i of Object.keys(obj2)) { | ||
/** | ||
* Bounds a number between a lower and an upper limit. | ||
* @param {number} x | ||
* @param {number} min | ||
* @param {number} max | ||
* @returns {number} | ||
*/ | ||
export function clamp(x, min = -Infinity, max = Infinity) { | ||
@@ -61,2 +100,10 @@ return Math.min(max, Math.max(min, x)); | ||
/** | ||
* Checks if a number is in between two limits. | ||
* @param {number} x | ||
* @param {number} a | ||
* @param {number} b | ||
* @returns {boolean} | ||
*/ | ||
export function isBetween(x, a, b) { | ||
@@ -66,16 +113,9 @@ return x >= a && x <= b; | ||
export function timer(fn) { | ||
window.performance.clearMarks(); | ||
window.performance.clearMeasures(); | ||
window.performance.mark('start'); | ||
let result = fn(); | ||
window.performance.mark('end'); | ||
window.performance.measure('time', 'start', 'end'); | ||
let time = window.performance.getEntriesByName('time')[0].duration; | ||
return { result, time }; | ||
} | ||
/** | ||
* Checks the average speed of a function by running it n times. | ||
* @param {Function} fn | ||
* @param {?number} n | ||
* @returns {number} | ||
*/ | ||
export function performance(fn, n = 100) { | ||
@@ -94,2 +134,8 @@ window.performance.clearMarks(); | ||
/** | ||
* Squares a number. | ||
* @param {number} x | ||
* @returns {number} | ||
*/ | ||
export function square(x) { | ||
@@ -99,2 +145,8 @@ return x * x; | ||
/** | ||
* Cubes a number. | ||
* @param {number} x | ||
* @returns {number} | ||
*/ | ||
export function cube(x) { | ||
@@ -104,2 +156,8 @@ return x * x * x; | ||
/** | ||
* Replacement for setTimeout() that is synchronous for time 0. | ||
* @param {Function} fn | ||
* @param {?number} t | ||
*/ | ||
export function delay(fn, t = 0) { | ||
@@ -110,5 +168,6 @@ if (t) { setTimeout(fn, t); } else { fn(); } | ||
// ----------------------------------------------------------------------------- | ||
// Promises | ||
/** | ||
* Creates a new promise together with functions to resolve or reject. | ||
* @returns {{promise: Promise, resolve: Function, reject: Function}} | ||
*/ | ||
export function defer() { | ||
@@ -129,5 +188,8 @@ let resolve, reject; | ||
// ----------------------------------------------------------------------------- | ||
// Object/Array Iterating | ||
/** | ||
* Checks if an object contains a property. | ||
* @param {Object} obj | ||
* @param {number} key | ||
* @returns {boolean} | ||
*/ | ||
export function has(obj, key) { | ||
@@ -137,2 +199,8 @@ return Object.prototype.hasOwnProperty.call(obj, key); | ||
/** | ||
* @param {Object} collection | ||
* @param {Function} fn | ||
* @returns {Object} | ||
*/ | ||
export function each(collection, fn) { | ||
@@ -147,2 +215,8 @@ let newCollection = Array.isArray(collection) ? [] : {}; | ||
/** | ||
* @param {Object} collection | ||
* @param {Function} fn | ||
* @returns {*} | ||
*/ | ||
export function some(collection, fn) { | ||
@@ -163,6 +237,12 @@ if (Array.isArray(collection)) { | ||
// ----------------------------------------------------------------------------- | ||
// Function Wrappers | ||
/** | ||
* Function wrapper that modifies a function to cache its return values. This | ||
* is useful for performance intensive functions which are called repeatedly | ||
* with the same arguments. However it can reduce performance for functions | ||
* which are always called with different arguments. Note that argument | ||
* comparison doesn't not work with Objects or nested arrays. | ||
// Wrapper for functions to cache their result based on arguments | ||
* @param {Function} fn | ||
* @returns {Function} | ||
*/ | ||
export function cache(fn) { | ||
@@ -177,4 +257,12 @@ let cached = new Map(); | ||
// Wrapper that prevents a function `fn` from being triggered more than once | ||
// every `t` ms. | ||
/** | ||
* Function wrapper that prevents a function from being executed more than once | ||
* every t ms. This is particularly useful for optimising callbacks for | ||
* continues events like scroll, resize or slider move. | ||
* | ||
* @param {Function} fn | ||
* @param {?number} t | ||
* @returns {Function} | ||
*/ | ||
export function throttle(fn, t = 0) { | ||
@@ -199,5 +287,7 @@ let delay = false; | ||
// ----------------------------------------------------------------------------- | ||
// Copying | ||
/** | ||
* Shallow copies any JavaScript object. | ||
* @param {*} obj | ||
* @returns {*} | ||
*/ | ||
export function shallowCopy(obj) { | ||
@@ -219,2 +309,3 @@ // Handle (simple) strings, numbers, booleans, null and undefined | ||
let DEEP_COPY_STORE = null; | ||
@@ -250,2 +341,7 @@ | ||
/** | ||
* Deep copies any JavaScript object. | ||
* @param {*} obj | ||
* @returns {*} | ||
*/ | ||
export function deepCopy(obj) { | ||
@@ -252,0 +348,0 @@ DEEP_COPY_STORE = new WeakMap(); |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Install scripts
Supply chain riskInstall scripts are run when the package is installed. The majority of malware in npm is hidden in install scripts.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
727
23632
4
14
1