@fr0st/core
v3.0.4
Published
Small, focused utility library for arrays, functions, math, objects, strings, and type checks.
Maintainers
Readme
FrostCore
Small, focused utilities for arrays, functions, math, objects, strings, and type checks. FrostCore has zero runtime dependencies, works in Node and bundlers, and also ships a browser-friendly UMD bundle that exposes globalThis._.
Highlights
- Named exports for tree-shaking
- Browser UMD bundle in
dist/ - No runtime dependencies
- JSDoc-powered IntelliSense
Installation
Node / bundlers
npm i @fr0st/coreFrostCore is ESM-only. Use import syntax in Node and bundlers.
Browser (UMD)
Load the bundle from your own copy or a CDN:
<script src="/path/to/dist/frost-core.min.js"></script>
<!-- or -->
<script src="https://cdn.jsdelivr.net/npm/@fr0st/core@latest/dist/frost-core.min.js"></script>
<script>
const { clamp, randomInt } = globalThis._;
console.log(clamp(randomInt(10), 0, 9));
</script>Quick Start
import {
clamp,
debounce,
humanize,
range,
setDot,
} from '@fr0st/core';
const state = { user: { profile: { name: 'Ada' } } };
setDot(state, 'user.profile.name', 'Ada Lovelace');
const values = range(0, 10, 2);
const label = humanize('favoriteColor');
const save = debounce(() => {
console.log('saving', state, values, label);
}, 250);
console.log(clamp(14, 0, 10)); // 10
save();TypeScript note: FrostCore is written in JavaScript and uses JSDoc types, which most editors surface as IntelliSense.
API
All utilities are exported from @fr0st/core as named ESM exports.
Arrays
diff(array, ...arrays): values that exist only in the first arrayintersect(...arrays): unique values shared by all arraysmerge(array, ...arrays): appends arrays or array-like values into the first arrayrandomValue(array): random element from an array, ornullfor an empty arrayrange(start, end, step = 1): numeric sequence fromstarttowardendunique(array): remove duplicate valueswrap(value): normalize a value into an array
import { diff, merge, range, unique, wrap } from '@fr0st/core';
diff([1, 2, 3], [2]); // [1, 3]
range(0, 5); // [0, 1, 2, 3, 4, 5]
unique([1, 1, 2]); // [1, 2]
wrap(undefined); // []
const out = [1];
merge(out, [2, 3]);
// out === [1, 2, 3]Functions
animation(callback, options): run at most once per animation framecompose(...callbacks): right-to-left function compositioncurry(callback): curry a function until its arity is satisfieddebounce(callback, wait, options): delay execution until calls settleevaluate(value): call a function or return a non-function as-isonce(callback): run a function once and cache the resultpartial(callback, ...defaultArgs): partially apply argumentspipe(...callbacks): left-to-right function compositionthrottle(callback, wait, options): run at most once per wait periodtimes(callback, amount): execute a callback repeatedly
import { compose, debounce, once, partial, pipe, throttle } from '@fr0st/core';
const add1 = (n) => n + 1;
const double = (n) => n * 2;
compose(add1, double)(3); // 7
pipe(add1, double)(3); // 8
const init = once(() => Math.random());
init() === init(); // true
partial((a, b) => [a, b], undefined, 2)(1); // [1, 2]
const debounced = debounce((value) => console.log(value), 100);
const throttled = throttle(() => console.log('tick'), 100);
debounced('last');
throttled();Math
clamp(value, min, max): clamp a number between boundsclampPercent(value): clamp a number between0and100dist(x1, y1, x2, y2): distance between two pointsinverseLerp(v1, v2, value): interpolation amount between two valueslen(x, y): vector lengthlerp(v1, v2, amount): linear interpolationmap(value, fromMin, fromMax, toMin, toMax): remap a value from one range to anotherrandom(a, b): random floating-point valuerandomInt(a, b): random integertoStep(value, step): round a number to a step size
import { clamp, dist, lerp, map, random, randomInt, toStep } from '@fr0st/core';
clamp(10, 0, 1); // 1
dist(0, 0, 3, 4); // 5
lerp(0, 10, 0.25); // 2.5
map(0.5, 0, 1, 0, 10); // 5
random(10); // 0 <= n < 10
randomInt(10, 50); // 10 <= n < 50
toStep(0.123, 0.05); // 0.1Objects
extend(object, ...objects): deep-merge values into the first objectflatten(object): flatten plain-object paths into dot notationforgetDot(object, key): delete a path from an objectgetDot(object, key, defaultValue): read a path from an objecthasDot(object, key): test whether a path existspluckDot(objects, key, defaultValue): read the same path from many objectssetDot(object, key, value, options): assign a path in an object
import { extend, flatten, getDot, pluckDot, setDot } from '@fr0st/core';
const obj = extend({ a: 1 }, { b: { c: 2 } });
getDot(obj, 'b.c'); // 2
flatten({ a: { b: 1 } }); // { 'a.b': 1 }
pluckDot([{ a: { b: 1 } }, { a: { b: 2 } }], 'a.b'); // [1, 2]
setDot(obj, 'b.c', 3);Strings
camelCase(string): convert text tocamelCasecapitalize(string): upper-case the first character and lower-case the restescape(string): escape HTML entitiesescapeRegExp(string): escape RegExp control charactershumanize(string): convert identifiers into readable wordskebabCase(string): convert text tokebab-casepascalCase(string): convert text toPascalCaserandomString(length, chars): create a random stringsnakeCase(string): convert text tosnake_caseunescape(string): unescape HTML entities
import { camelCase, escape, humanize, kebabCase, randomString, snakeCase } from '@fr0st/core';
camelCase('hello world'); // 'helloWorld'
humanize('helloWorld'); // 'Hello world'
kebabCase('helloWorld'); // 'hello-world'
snakeCase('helloWorld'); // 'hello_world'
escape('<div class="x">'); // '<div class="x">'
randomString(8); // e.g. 'aZ02kLmP'Testing
isArray(value)isArrayLike(value)isBoolean(value)isDocument(value)isElement(value)isFragment(value)isFunction(value)isNaN(value)isNode(value)isNull(value)isNumeric(value)isObject(value)isPlainObject(value)isShadow(value)isString(value)isText(value)isUndefined(value)isWindow(value)
import {
isArray,
isArrayLike,
isFunction,
isNumeric,
isPlainObject,
} from '@fr0st/core';
isArray([]); // true
isArrayLike({ 0: 'a', length: 1 }); // true
isFunction(() => {}); // true
isNumeric('123.45'); // true
isPlainObject({}); // trueBehavior Notes
merge()andextend()mutate and return the first argument.debounce(),throttle(), andanimation()return wrapped functions withcancel().range()uses the absolute value ofstep, returns[]forstep === 0, and includesendwhen the step lands on it exactly.setDot()supports*wildcard segments and an{ overwrite }option.random()andrandomInt()use an exclusive upper bound.
Development
npm test
npm run js-lint
npm run buildLicense
FrostCore is released under the MIT License.
