npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@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 (scoped)

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 },
]);