@hypericon/utils
v0.5.5
Published
Utility and formatting functions with no dependencies
Downloads
4
Readme
Utils
Utility and formatting functions with no dependencies, for the browser and the server, with helpful type definitions*.
*there are a couple of exceptions
npm i @hypericon/utils
Usage
Misc
import { wait } from "@hypericon/utils";
// A simple function returning a promise that resolves after the given number of milliseconds
async func() {
await wait(2000); // waits for 2,000 ms
}
Numbers
import { clamp, sum, toNumberOrUndefined, numberToSigFigs, numberToSigFigsSI, ratioToPercentage, numberToBytes, randomRange, randomIntRange } from "@hypericon/utils";
// Clamp a value to a given range
clamp(-12, 100, 200); // 100
// Find the sum of some number, ignoring undefined, null, and NaN
sum(1, 2, 3); // 6
sum(undefined, null, NaN, 5); // 5
// Parse a value to a number, or undefined if it would be NaN
toNumberOrUndefined(12); // 12
toNumberOrUndefined("12"); // "12"
toNumberOrUndefined(null); // undefined
toNumberOrUndefined("dog"); // undefined
// Round a value to a number of significant figured (default: 3)
numberToSigFigs(3579); // 3580
numberToSigFigs(3579, 2); // 3600
numberToSigFigs(undefined); // undefined
// Convert a number to a string with a number of significant figures (default 3),
// and an appripriate SI suffix from "femto-" (10^-15) to "Peta-" (10^15)
numberToSigFigsSI(123456); // "123k"
numberToSigFigsSI(12345678); // "12.3M"
numberToSigFigsSI(0.000123, 2); // "120µ"
numberToSigFigsSI(undefined); // "undefined"
// Format a ratio as a percentage string, with an optional number of decimal places
ratioToPercentage(0.12); // "12"
ratioToPercentage(-0.12); // "-12"
ratioToPercentage(1.2); // "120"
ratioToPercentage(0.12345, 2); // "12.34"
ratioToPercentage(0.12, 3); // "12.000"
// Format a number as a number of bytes with appropriate units
numberToBytes(0); // "0 Bytes"
numberToBytes(120); // "120 Bytes"
numberToBytes(120_000); // "117 kB"
numberToBytes(120_000_000); // "114 MB"
numberToBytes(120_000_000_000); // "112 GB"
numberToBytes(120_000, { decimals: 2 }); // "117.19 kB"
numberToBytes(120_000, { tenCubed: true }); // "120 kB"
// Generate a random number in a given range
randomRange(10, 100); // e.g. 42.229661111154805
// Generate a random *integer* in a given range
randomIntRange(10, 100); // e.g. 71
Dates & Times
dateToDateStr(new Date("2023-03-17T11:03:44.444Z")); // "2023-03-17"
// see also: dateToDateStrUTC(d: Date)
dateToTime(new Date("2023-03-17T11:03:44.444Z")); // "11:03:44"
dateToTime(new Date("2023-03-17T11:03:44.444Z"), { secs: false }); // "11:03"
// see also: dateToTimeUTC(d: Date, opts?: { secs?: boolean })
dateToDateTime(new Date("2023-03-17T11:03:44.444Z")); // "2023-03-17 11:03:44"
dateToDateTime(new Date("2023-03-17T11:03:44.444Z"), { secs: false }); // "2023-03-17 11:03"
// see also: dateToDateTimeUTC(d: Date, opts?: { secs?: boolean })
dateToDayMonth(new Date("2023-03-17T11:03:44.444Z")); // "17 Mar"
// see also: dateToDayMonthUTC(d: Date)
timestampToDate(1679051024444); // "2023-03-17"
// see also: timestampToDateUTC(timestamp: number)
timestampToTime(1679051024444); // "11:03:44"
timestampToTime(1679051024444, { secs: false }); // "11:03"
// see also: timestampToTimeUTC(timestamp: number, opts?: { secs?: boolean })
timestampToDateTime(1679051024444); // "2023-03-17 11:03:44"
timestampToDateTime(1679051024444, { secs: false }); // "2023-03-17 11:03"
// see also: timestampToDateTimeUTC(timestamp: number, opts?: { secs?: boolean })
Durations
import { prettyRelativeTime, millisTo24Hour, millisToMedia, millisToPrettyDuration } from "@hypericon/utils";
// Build a display string specifying the relative time to a given Date from the current time,
// or specify another Date as the offset point of reference
const now = Date.now();
prettyRelativeTime(now - 100); // "just now"
prettyRelativeTime(now - 50_000); // "50 seconds ago"
prettyRelativeTime(now - 5 * 60 * 1000); // "5 minutes ago"
prettyRelativeTime(now - 1 * 60 * 60 * 1000); // "an hour ago"
prettyRelativeTime(now - 1 * 24 * 60 * 60 * 1000); // "yesterday"
prettyRelativeTime(new Date("2020-01-31"), new Date("2020-02-01")); // "yesterday"
prettyRelativeTime(new Date("2020-02-02"), new Date("2020-02-01")); // "tomorrow"
prettyRelativeTime(new Date("2020-01-25"), new Date("2020-02-01")); // "last week"
prettyRelativeTime(new Date("2020-01-02"), new Date("2020-02-01")); // "last month"
// Convert a number of milliseconds to a 24-hour HH:mm string
millisTo24Hour(123456789); // "10:18"
millisTo24Hour(-123456789); // "13:42"
millisTo24Hour(12345678912345); // "19:15"
// Format a number of milliseconds for a media player
millisToMedia(123456) // "02:03"
millisToMedia(3661000) // "1:01:01"
millisToMedia(123456, true) // "02:03.456"
millisToMedia(-123456) // "-02:03"
millisToMedia(-123456, true) // "-02:03.456"
// Format a number of milliseconds as a human-readable string with appropriate units. Includes up to 2 distinct units be default.
millisToPrettyDuration(12345); // "12 secs, 345 ms"
millisToPrettyDuration(1234567); // "20 mins, 34 secs"
millisToPrettyDuration(123456789); // "1 day, 10 hours"
millisToPrettyDuration(9876543210); // "3 months, 24 days"
millisToPrettyDuration(9876543210, 4); // "3 months, 24 days, 7 hours, 29 mins"
millisToPrettyDuration(123456, 4); // "2 mins, 3 secs, 456 ms"
Objects
import { dereference, isObject, mergeDeep, compareObjects } from "@hypericon/utils";
// Create a copy of an object without a reference to the original
const o = { an: "object" };
const d = dereference(o);
console.log(d); // { an: "object" }
console.log(o === d); // false
console.log(dereference(undefined)); // undefined
// Determine if a value is defined, and an object, and not an array
isObject(undefined); // false
isObject("dog"); // false
isObject(null); // false
isObject([1, 2, 3]); // false
isObject({ an: "object" }); // true
// Deeply merge two or more objects
mergeDeep({ an: "object" }, undefined); // { an: "object" }
mergeDeep(undefined, { an: "object" }); // { an: "object" }
mergeDeep({ a: 1 }, { b: 2 }, { c: 3 }); // { a: 1, b: 2, c: 3 }
mergeDeep(
{
a: {
b: 123,
c: 456, // `c` is unchanged
},
r: 77,
list: [1,2,3],
},
{
a: {
b: 222, // `b` is updated
d: 444, // `d` is added
},
e: 555, // `e` is added
r: undefined, // `r` is removed
list: [10, 20, 30], // `list` is replaced
},
);
// {
// a: {
// b: 222,
// c: 456,
// d: 444
// },
// e: 555,
// list: [10, 20, 30],
// }
// Compare two objects deeply
compareObjects({ an: "object" }, undefined); // false
compareObjects({ an: "object" }, { an: "object" }); // true
compareObjects({ with: { nested: "keys" } }, { with: { nested: "keys" } }); // true
compareObjects({ with: { nested: "keys" } }, { with: { nested: "ERROR" } }); // false
Lists
import { deduplicate, sortByKeyFn, findDuplicates, collapseDuplicates } from "@hypericon/utils";
// Deduplicate a list using strict equality
deduplicate([1, 2, 2, 3, 3, 3]); // [1, 2, 3]
// Build a function to easily sort a list of objects by the value of a specified key
const list = [
{ name: "Adam" },
{ name: "Charlie" },
{ name: "Brian" },
];
list.sort(sortByKeyFn("name"));
// list = [
// { name: "Adam" }
// { name: "Brian" }
// { name: "Charlie" }
// ];
// Find the duplicates in a list
findDuplicates([1, 2, 2, 3, 4, 4, 4]); // [2, 4]
// Optionally supply a custom comparison function
const list = [
{ name: "Dave" },
{ name: "davE" },
{ name: "Brian" },
];
const comparisonFn = (a, b) => a.name.toLowerCase() === b.name.toLowerCase();
findDuplicates(list, comparisonFn); // [{ name: "Dave" }]
// Collapse duplicate items in a list, returning the items in the original order of
// their first occurrence and the number of times they occur in the list
collapseDuplicates([2, 2, 2, 1, 3, 3]);
// [ { item: 2, count: 3 }, { item: 1, count: 1 }, { item: 3, count: 2 } ]]
// Optionally supply a custom comparison function
// (`list` and `comparisonFn` defined above)
expect(collapseDuplicates(list, comparisonFn)).toMatchObject([
{ item: { name: "Dave" }, count: 2 },
{ item: { name: "Brian" }, count: 1 },
]);