@resolute/std v0.2.1
Standard TypeScript Development
Well tested TypeScript functions suitable for use in browser, service worker, and Node.js contexts.
Installation
npm i @resolute/stdUsage
import { fetchOk } from '@resolute/std/http';
try {
await fetchOk('https://httpstat.us/500');
} catch (error) {
// `fetch` doesn’t throw on 500 responses.
// `fetchOk` does :)
}./coerce
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.
Utility Functions
to
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))(' '); // undefinedor
Provide 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: foois
Type 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); // falsenot
Negate 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); // trueType Guard Functions
string
Returns the input if it is a string. Throws otherwise.
number
Returns the input if it is a finite number. Throws otherwise including when input is NaN or
Infinity.
./color
Convert between hex, RGB array, and integer representations of colors. Additionally blend between colors.
parse
Convert a hex color string #xxxxxx or rgb array r, g, b to an integer.
import { parse } from '@resolute/std/color';
parse('#888'); // 8947848fromHex
#XXXXXX → integer
fromRgb
r, g, b → integer
toHex
integer → #XXXXXX
toRgb
integer → r, g, b
blend
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%)./control
Runtime and control flow helpers.
retry
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');sleep
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());
// ~1000defer
Create 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;once
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)(); // 1throttle
Limit 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 laterdebounce
Returns 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 === 1./cookie
Parse and stringify cookies. Methods available for DOM and service worker contexts.
./ease
Easing functions from easings.net.
./http
Helpers for interacting with Request and Response objects.
fetchOk
Throw if value is not in list.
import { fetchOk } from '@resolute/std/http';
await fetchOk('https://httpstat.us/500'); // HttpError: HTTP 500 Errormethod
Throw 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]readBody
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
Intl helpers.
conjunction
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'./math
Ranging, scaling, random integers, and more.
range
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); // -5scale
Define 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.5clamp
Define 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); // 0divide
Generate 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
// ]randomIntInclusive
Generate a random number inclusively between min and max.
randomIntExclusiveMax
Generate a random number between min (inclusively) and max (exclusively).
./mime
Validate mime types and file extensions as well as convert from mime to extension and visa versa.
extToMime
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.mimeToExt
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../misc
Miscellaneous utilities without a home.
mapKeyAValB
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 }mapKeys
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 }properName
Composite coerce function to fix the capitalization of proper nouns.
cleanEmail
Composite coerce function to sanitize an email address.
cleanPhone
Composite coerce function to sanitize and format a 10-digit US phone number.
./promise
Promise keeper utility.
keeper
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
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago