Well tested TypeScript functions suitable for use in browser, service worker, and Node.js contexts.
npm i @resolute/stdimport { fetchOk } from '@resolute/std/http';
try {
await fetchOk('https://httpstat.us/500');
} catch (error) {
// `fetch` doesn’t throw on 500 responses.
// `fetchOk` does :)
}Type validation and sanitization. This module contains a handful of utility functions and
“coercers.” Coercers are unary functions that return validated/mutated input, or throw. The
utility function to (alias coerce) allow you to chain these coercers. The or utility function
may be used in the chain in order to specify a backup value to be returned instead of throwing an
error.
Additionally, the is and not utility functions return true if a coercer or chain of coercers
(to(…)) passes or false if it throws.
Chain unary coercing functions.
import { nonempty, or, string, to, trim } from '@resolute/std/coerce';
to(string, trim, nonempty)(' foo '); // 'foo'
to(string, trim, nonempty)(' '); // throws TypeError
to(string, trim, nonempty, or(undefined))(' '); // undefinedProvide a backup value to be used when a coercer fails. If instanceof Error, then that error will
be thrown. For any other value, it will be returned. The or(…) utility function must be the last
parameter in to.
import { or, string, to } from '@resolute/std/coerce';
to(string, or(null))('foo'); // 'foo'
to(string, or(null))(1); // null
to(string, or(new Error('foo')))(1); // throws Error: fooType guard test. Use with any type guard or mutating function that throws on failure (almost all
functions here do). The is function will catch the error and return false, otherwise it will
return true.
import { is, string } from '@resolute/std/coerce';
is(string)('foo'); // true
is(string)(12345); // falseNegate type guard test. Use with any type guard or mutating function that throws on failure
(almost all functions here do). The not function will catch the error and return true, otherwise
it will return false. @example
import { not, string } from '@resolute/std/coerce';
not(string)('foo'); // false
not(string)(12345); // trueReturns the input if it is a string. Throws otherwise.
Returns the input if it is a finite number. Throws otherwise including when input is NaN or
Infinity.
Convert between hex, RGB array, and integer representations of colors. Additionally blend between colors.
Convert a hex color string #xxxxxx or rgb array [r, g, b] to an integer.
import { parse } from '@resolute/std/color';
parse('#888'); // 8947848#XXXXXX → integer
[r, g, b] → integer
integer → #XXXXXX
integer → [r, g, b]
Blend two colors using a percent.
import { blend, toHex } from '@resolute/std/color';
const blender = blend('#000', '#888');
toHex(blender(0.0)); // #000000 (0%)
toHex(blender(0.5)); // #444444 (50%)
toHex(blender(1.0)); // #888888 (100%)Runtime and control flow helpers.
Wrap an async or promise-returning function that when called will retry up to retries times or
until it resolves, whichever comes first.
import { retry } from '@resolute/std/control';
await retry(fetch)('https://httpstat.us/200');Promisify setTimeout. Returns a Promise that settles with the return of the passed function after
delay milliseconds.
import { sleep } from '@resolute/std/control';
await sleep(1000, (then) => Date.now() - then, Date.now());
// ~1000Create and return a new promise along with its resolve and reject parameters. Especially useful when “promisifying” a callback style API.
import { defer } from '@resolute/std/control';
const [promise, resolve, reject] = defer();
addEventListener('success', resolve);
addEventListener('error', reject);
await promise;Wrap a function that to be executed once. Subsequent calls will return the value of the first (and only) invocation.
import { once } from '@resolute/std/control';
let value = 0;
const incr = () => ++value;
once(incr)(); // 1
once(incr)(); // 1
incr(); // 2
once(incr)(); // 1Limit the number of invocations of a given function (or different functions) within an interval window. Useful for avoiding API rate limits.
import { throttle } from '@resolute/std/control';
const throttled = throttle(1, 1_000)(async () => {});
await throttled();
await throttled(); // 1s laterReturns a function, that, as long as it continues to be invoked (.), will not be triggered (*). The
function will be called after it stops being called for threshold milliseconds.
// /-- 10s --\ /-- 10s --\ /-- 10s --\
// . . . . . . . . . . . . . *
import { debounce } from '@resolute/std/control';
let state = 0;
const fn = (value: number) => state += value;
const debounced = debounce(fn, 50);
debounced(1);
debounced(1);
debounced(1);
// state === 1Parse and stringify cookies. Methods available for DOM and service worker contexts.
Easing functions from easings.net.
Helpers for interacting with Request and Response objects.
Throw if value is not in list.
import { fetchOk } from '@resolute/std/http';
await fetchOk('https://httpstat.us/500'); // HttpError: HTTP 500 ErrorThrow if value is not in list.
import { method } from '@resolute/std/http';
method(['GET', 'POST'])(new Request('/', { method: 'POST' })); // 'POST'
method(['GET', 'POST'])(new Request('/', { method: 'PUT' })); // HttpError: Method must be within [GET, POST]Invoke the correct Request/Response body reading method (json/text/formData/arrayBuffer) based on the content-type header.
import { readBody } from '@resolute/std/http';
const body = await readBody(new Response());Intl helpers.
Transform an array to a en/US grammar list.
import { conjunction } from '@resolute/std/intl';
conjunction('1'); // '1'
conjunction(['1', '2']); // '1 and 2'
conjunction(['1', '2', '3']); // '1, 2, and 3'Ranging, scaling, random integers, and more.
Define a ranging function to calculate the number bound by min and max and a percent or fraction
(0 through 1). Note: percents (fractions) less than 0 or greater than 1 will return values outside
of the min–max range.
import { range } from '@resolute/std/math';
range(0, 10)(0.5); // 5
range(0, 10)(1.5); // 15
range(0, 10)(-0.5); // -5Define a scaling function to calculate the percentage of value relative to min and max.
import { scale } from '@resolute/std/math';
scale(0, 10)(5); // 0.5
scale(0, 10)(15); // 1.5
scale(0, 10)(-5); // -0.5Define a clamping function to keep a value bound to the min and max.
import { clamp } from '@resolute/std/math';
clamp(0, 1)(0.5); // 0.5
clamp(0, 1)(5); // 1
clamp(0, 1)(-5); // 0Generate a scale for each member of an array with (optional) overlap. Use with array.map() to
generate the divided scales.
import { divide } from '@resolute/std/math';
[1, 2, 3]
.map(divide())
.map(([value, scaler]) => [
scaler(0), // 0%
scaler(1 / 3), // 33%
scaler(2 / 3), // 66%
scaler(3 / 3), // 100%
]);
// [
// [ 0, 1, 2, 3 ], // 1
// [ -1, 0, 1, 2 ], // 2
// [ -2, -1, 0, 1 ] // 3
// ]Generate a random number inclusively between min and max.
Generate a random number between min (inclusively) and max (exclusively).
Validate mime types and file extensions as well as convert from mime to extension and visa versa.
Convert a file extension to a mime type.
import { extToMime } from '@resolute/std/mime';
extToMime('avif'); // 'image/avif'
extToMime('.avif'); // 'image/avif'
extToMime('foo'); // TypeError “foo” is not a valid extension.Convert a mime type to a file extension.
import { mimeToExt } from '@resolute/std/mime';
mimeToExt('image/avif'); // 'avif'
mimeToExt('text/html; charset=utf-8'); // 'html'
mimeToExt('foo/bar'); // TypeError “foo/bar” is not a valid mime type.Miscellaneous utilities without a home.
Match the keys of a to the values of b by matching the values of a to the keys of b and
eliminate undefined/null values.
import { mapKeyAValB } from '@resolute/std/misc';
const a = { foo: 'a', bar: 'b', baz: 'c' };
const b = { a: 1, b: 2 };
mapKeyAValB(a, b); // { foo: 1, bar: 2 }Match the keys of a to the values of b by matching the values of a to the keys of b and
eliminate undefined/null values.
import { mapKeys } from '@resolute/std/misc';
const a = { a: 'foo', b: 'bar', c: 'baz' };
const b = { a: 1, b: 2 };
mapKeys(a, b); // { foo: 1, bar: 2 }Composite coerce function to fix the capitalization of proper nouns.
Composite coerce function to sanitize an email address.
Composite coerce function to sanitize and format a 10-digit US phone number.
Promise keeper utility.
Provides caching behavior to an expensive function. Can perform periodic background refresh.
.stale(): sync return what is in the cache; throws if empty.get(): async return cache or new invocation if cache is empty.fresh(): async return a new invocation of the expensive function.start(delay): continuously invoke expensive function.stop(): continuous invocation
import { keeper } from '@resolute/std/promise';
const expensive = async () => Math.random() ** Math.random();
const kept = keeper(expensive);
kept.stale(); // sync; throws because cache is empty
await kept.get(); // invokes expensive() because cache is empty
kept.stale(); // sync; returns the resolved value of expensive()
kept.fresh(); // forces a new expensive() invocationTODO: document missing items