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 🙏

© 2026 – Pkg Stats / Ryan Hefner

@ethanblaisalarms/utils

v1.0.0

Published

Lightweight helpers, primarily focused on array and object manipulation and improved stringification.

Readme

Lightweight helpers, primarily focused on array and object manipulation and improved stringification.

Installation and setup example

npm install @ethanblaisalarms/utils
// ESM
import {merge} from "@ethanblaisalarms/utils";

// CommonJS
const {merge} = require("@ethanblaisalarms/utils");

TypeScript types

Record shorthand types

type TRecord<T = unknown> = Record<string, T>

| TypeScript | Shorthand for string records. |------------|- | JavaScript | Equal to object.

type TNumRecord<T = unknown> = Record<number, T>

| TypeScript | Shorthand for numeric records. |------------|- | JavaScript | Equal to object with numeric keys.

Await until condition

type TCondition = (i?:number)=>boolean;

| TypeScript | A function with an optional iteration parameter, which returns a boolean. |------------|- | JavaScript | Equal to function.

Object utilities

Merge objects

function merge<T extends object>(target:T, ...sources:object[]):T

This function merges two or more objects together. Merging starts from the first object, and moves down the line. This means that in objects which share properties, the last object has priority.

This function will mutate target and may overwrite properties.

This function will:

  • NOT merge any function
  • NOT merge any of the following keys: __proto__, prototype, or constructor
  • NOT merge any symbol keys
  • NOT recursively merge non-plain objects
  • Preserve excluded keys or functions in target
  • Concatenate arrays

Arguments:

| Name | Type | Description |-----------|--------------|------------ | target | object | required, mutated: The object to merge into. | sources | ...object[] | Array of objects to merge into target. If empty, target is unchanged. | @returns | object | A reference to target.

Example:

const x = {
	A: 1,
	B: 2,
	C: 3,
};
const y = {
	A: 10,
	D: 40,
	E: 50,
};
const z = {
	A: 100,
	E: 500,
	F: 600,
};

merge(x, y, z);

// Expected value of x:
{
	A: 100,
	B: 2,
	C: 3,
	D: 40,
	E: 500,
	F: 600,
};

Common Use Case:

import userConfig from "./Config.js";

const CONFIG = {
	debugMode: false,
};

merge(CONFIG, userConfig);

De-comment JSON

function decommentJSON(data:string):string

This function removes comments from JSON strings. This makes it easy to parse JSON files which may contain comments.

Arguments:

| Name | Type | Description |-----------|--------|------------ | data | string | required: The JSON string to remove comments from. | @returns | string | data, but with JSON comments removed.

Example:

const x = `{
	// "A" holds the number of apples.
	"A": 10,
	/* "B" holds the number of bananas.
	Must be greater than 0. */
	"B": 20,
	/*
		"C" holds the number of carrots.
		Must be:
		- An even number
		- Divisible by 3
		- Not divisible by 60
		- The digits must no add up to 6
	*/
	"C": 30,
	"D": "//This is not a JSON comment"
}`;

const y = decommentJSON(x);

// Expected value of y:
`{
	"A": 10,
	"B": 20,
	"C": 30,
	"D": "//This is not a JSON comment"
}`;

Common Use Case:

const rawConfig = fs.readFileSync("config.json");
const CONFIG = JSON.parse(decommentJSON(rawConfig));

Check for plain objects

function checkPlain(data:unknown):data is TRecord

This function checks if a passed value is a plain object. If so, TypeScript will recognize the result as a TRecord.

Arguments:

| Name | Type | Description |----------|---------|------------ | data | unknown | required: The value to check. | @returns | boolean | Whether data is a plain object.

Example:

const x = new Date();
const y = {};
const z = [
	checkPlain(x),
	checkPlain(y),
];

// Expected value of z:
[false, true];

Array utilities

Pull from array

function pull<T>(target:T[], ...elements:T[]):T[]

This function removes the first instance of each of the specified elements from the array.

This function will mutate target and may remove elements.

Arguments:

| Name | Type | Description |------------|---------------|------------ | target | unknown[] | required, mutated: The array to remove elements from. | elements | ...unknown[] | Array of elements to remove from target. If no objects are specified, target is unchanged. | @returns | unknown[] | A reference to target.

Example:

const x = [10, 20, 30, 40, 50, 20];
pull(x, 20, 50);

// Expected value of x:
[10, 30, 40, 20];

Pull all

function pullAll<T>(target:T[], ...elements:T[]):T[]

This function removes all instances of each of the specified elements from the array.

This function will mutate target and may remove elements.

Arguments:

| Name | Type | Description |------------|---------------|------------ | target | unknown[] | required, mutated: The array to remove elements from. | elements | ...unknown[] | Array of elements to remove from target. If no objects are specified, target is unchanged. | @returns | unknown[] | A reference to target.

Example:

const x = [10, 20, 30, 40, 50, 20];
pullAll(x, 20, 50);

// Expected value of x:
[10, 30, 40];

Pull and replace

function replace<T>(target:T[], element:T, ...replace:T[]):T[]

This function removes the first instance of a specified element from the array and replaces it with the specified replacements.

This function will mutate target and may add or remove elements.

Arguments:

| Name | Type | Description |------------|---------------|------------ | target | unknown[] | required, mutated: The array to remove elements from. | element | unknown | required: The element to remove from target. | replace | ...unknown[] | The elements to replace removed elements. If none are specified, behavior matches pull(). | @returns | unknown[] | A reference to target.

Example:

const x = [10, 20, 30, 40, 50, 20];
replace(x, 20, 60, 70);

// Expected value of x:
[10, 60, 70, 30, 40, 50, 20];

Pull and replace all

function replaceAll<T>(target:T[], element:T, ...replace:T[]):T[]

This function removes all instances of a specified element from the array and replaces it with the specified replacements.

This function will mutate target and may add or remove elements.

Arguments:

| Name | Type | Description |------------|---------------|------------ | target | unknown[] | required, mutated: The array to remove elements from. | element | unknown | required: The element to remove from target. | replace | ...unknown[] | The elements to replace removed elements. If none are specified, behavior matches pullAll(). | @returns | unknown[] | A reference to target.

Example:

const x = [10, 20, 30, 40, 50, 20];
replaceAll(x, 20, 60, 70);

// Expected value of x:
[10, 60, 70, 30, 40, 50, 60, 70];

Objectify arrays

function objectify<T>(source:T[]):TNumRecord<T>

This function converts an array to a plain object with numeric keys. The original array is not mutated.

Arguments:

| Name | Type | Description |----------|------------|------------ | source | unknown[] | required: The array to convert to a plain object. | @returns | TNumRecord | The new object created from source.

Example:

const x = ["zero", "one", "two", "three"];
const y = objectify(x);

// Expected value of y:
{
	0: "zero",
	1: "one",
	2: "two",
	3: "three",
};

Stringify values

General stringify

function stringify(data:unknown):string

This function converts any value to a readable string.

The process looks like this:

  • If the value is a bigint, return data + "n";
  • If the value is not an object, return String(data);
  • If the value is null, return "null";
  • If the value is a Map or a Set, convert to an array and stringify() it
  • If the value is an array, return stringifyJSON(data);
  • If the value has a non-default toString method, call it and return the value
  • Otherwise, return stringifyJSON({...data});

Arguments:

| Name | Type | Description |----------|---------|------------ | data | unknown | required: The value to convert to a string. | @returns | string | A string representation of data.

Example:

const x = 500n;
const y = null;
const z = {};

const res = [
	stringify(x),
	stringify(y),
	stringify(z),
];

// Expected value of res:
["500n", "null", "{}"];

Stringify JSON

function stringifyJSON(
	data:object,
	separator:string = " ",
	ignore:string[] = [],
):string

This function converts an object into a string. This function adds additional support to JSON.stringify().

Unlike JSON.stringify() alone, this function can:

  • Handle bigint values
  • Handle instances of Map and Set
  • Handle circular object references
  • Optionally ignore specified key paths

Arguments:

| Name | Type | Description |-------------|----------|------------ | data | object | required: The object to convert to a string. | separator | string | The separator to pass into JSON.stringify(). | ignore | string[] | An array of dot-notation key paths to ignore. | @returns | string | A string representation of data.

Example:

const x = {
	A: 1,
	B: 2,
};
const y = {
	A: 1,
	B: 2,
	C: {
		A: 100n,
		B: 2,
	},
};
const z = {
	X: x,
	C: x,
};
z.Z = z;

const res = {
	x: stringifyJSON(x),
	y: stringifyJSON(y, " ", ["A", "C.B"]),
	z: stringifyJSON(z),
};

// Expected value of res:
{
	x: `{
	 "A": 1,
	 "B": 2
	}`,
	y: `{
	 "B": 2,
	 "C": {
	  "A": "100n"
	 }
	}`,
	z: `{
	 "X": {
	  "A": 1,
	  "B": 2
	 },
	 "C": "[Circular: X]",
	 "Z": "[Circular: ~]"
	}`,
};

Stringify array elements

function stringifyArray(data:unknown[]):string[]

Shorthand for data.map(stringify). Converts all elements of an array into strings, and returns the new array without mutating the existing array.

Arguments:

| Name | Type | Description |----------|------------|------------ | data | unknown[] | required: The array to stringify the elements of. | @returns | string[] | data, but after all elements are converted to strings.

Example:

const x = [null, 20, {}];
const y = stringifyArray(x);

// Expected value of y:
["null", "20", "{}"];

Randomization

Random number

function rand():number

Shorthand for Math.random(). Generates a random number between 0 and 1.

Arguments:

| Name | Type | Description |----------|--------|------------ | @returns | number | The result of Math.random().

Example:

const x = [
	rand(),
	rand(),
	rand(),
	rand(),
	rand(),
]

// Expected value of x:
[
	0.8966649491265986,
	0.18814033044643852,
	0.6812450432610444,
	0.30752727234410016,
	0.6411181322989353,
];

Random number up to

function rand(base:number):number

Generates a random integer between 0 and base (inclusive).

Arguments:

| Name | Type | Description |----------|--------|------------ | base | number | required: The maximum number to generate. | @returns | number | A random number between 0 and base.

Example:

const x = [
	rand(5),
	rand(5),
	rand(5),
	rand(5),
	rand(5),
]

// Expected value of x:
[0, 4, 1, 0, 5];

Random number between

function rand(base:number, max:number):number

Generates a random integer between base and max (inclusive).

Arguments:

| Name | Type | Description |----------|--------|------------ | base | number | required: The minimum number to generate. | max | number | required: The maximum number to generate. | @returns | number | A random number between base and max.

Example:

const x = [
	rand(-5, 5),
	rand(-5, 5),
	rand(-5, 5),
	rand(-5, 5),
	rand(-5, 5),
]

// Expected value of x:
[4, 1, -1, -1, -5];

Random array element

function rand<T>(base:T[]):T|null

Returns a random element from the base array.

Arguments:

| Name | Type | Description |----------|------------|------------ | base | unknown[] | required: The array to search. | @returns | unknown | A random element from base. | @returns | null | If the array is empty.

Example:

const x = "ABCDE".split("");
const y = [
	rand(x),
	rand(x),
	rand(x),
	rand(x),
	rand(x),
];

// Expected value of y:
["C", "B", "B", "A", "E"];

Random object key

function rand(base:TRecord):string|null

Returns a random key from the base object.

Arguments:

| Name | Type | Description |----------|--------|------------ | base | object | required: The object to search. | @returns | string | A random key from base. | @returns | null | If the object is empty.

Example:

const x = {
	A: 10,
	B: 20,
	C: 30,
	D: 40,
	E: 50,
};
const y = [
	rand(x),
	rand(x),
	rand(x),
	rand(x),
	rand(x),
];

// Expected value of y:
["E", "C", "A", "A", "E"];

Random string

function randString(
	len:number = 16,
	charset:string|string[] = "0123456789ABCDEF",
):string

Returns a randomly generated string of the specified length, using the specified charset.

Arguments:

| Name | Type | Description |-----------|-----------|------------ | len | number | The length of the string. | charset | string | The charset to use. | charset | string[] | The array of strings to use. | @returns | string | A random string. | @returns | "" | If charset did not include at least one item.

Example:

const x = [
	randString(4),
	randString(8, "!@$^"),
	randString(4, ["Hey", "Hi", "Hello"]),
];

// Expected value of x:
[
	"9D39",
	"@$!!^@$$",
	"HeyHiHiHello",
];

Async Utilities

Sleep

async function sleep(ms:number):Promise<void>

When awaited, waits (sleeps) for the specified milliseconds.

Arguments:

| Name | Type | Description |----------|---------|------------ | ms | number | required: The duration to sleep for. | @returns | Promise | Resolves after ms milliseconds.

Example:

console.log("Start!");
await sleep(5000);
console.log("Stop!");

// Expected delay between Start and Stop: 5 seconds.

Await Until

async function until(
	condition:TCondition,
	interval:number = 100,
	attempts:number|null = null,
):Promise<number>

When awaited, waits until the specified condition returns true.

Arguments:

| Name | Type | Description |-------------|----------|------------ | condition | function | The function condition. | interval | number | The number of milliseconds between condition calls. | attempts | number | The maximum number of attempts. | attempts | null | Disables the maximum number of attempts. | @returns | Promise | Resolves once condition returns true. Rejects when reaching the maximum attempts.

Example:

const x = {
	value: false,
};
async function setTrue() {
	await sleep(5000);
	x.value = true;
}

console.log("Start!");
setTrue();
await until(() => {
	return x.value;
});
console.log("Stop!");

// Expected delay between Start and Stop: 5 seconds.