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 🙏

© 2025 – Pkg Stats / Ryan Hefner

@softsky/utils

v2.8.2

Published

JavaScript/TypeScript utilities

Readme

Sky utils

JavaScript/TypeScript utilities

Latest Stable Version NPM Downloads NPM Downloads Bundlephobia Size

npm i @softsky/utils

ZERO DEPENDENCIES utils library. Test coverage 100%.

Usual utils plus more obscure stuff that I've never seen in any library. Also fancy TypeScript generics and types that I often use.

Contribute

I don't know why would you want to, but here's how to:

  1. Install Bun
  2. Install dependencies bun i or npm i
  3. Lint files bun run lint
  4. Run tests bun run test
  5. Update README bun run gen-readme
  6. Create merge request

Don't forget to follow comment style for new exported features:

/** Description of how it works (REQUIRED) */
export function newStuff() {}

Full feature list:

Arrays

Everything array related.

function randomFromArray - Returns random element from non-empty array


function shuffleArray - Create new shuffled array


function swap - Swap two elements in array


function binarySearch - Binary search in sorted array. Compare function should compare your needed value with value on index passed to it. If compare returns 0 it means we found target. If compare returns > 0 it means we have to cut out bigger side of array. If compare returns < 0 it means we have to cut out smaller side of array.


function chunk - Split array into sub arrays of spicified size


function combinations - Return all combinations of items in array


function permutations - Return all permutations of items in array


function pushToSorted - Push data to sorted array. Array will always be kept sorted.

Compare function should compare your needed value with value on index passed to it. If compare returns 0 it means we found target. If compare returns > 0 it means target is smaller. If compare returns < 0 it means target is bigger.

pushToSorted(numArray, 10,  x => x - 10);

function removeFromArray - Delete value from array. Only deletes first encountered.

Returns index of deleted value.


function removeLastFromArray - Delete value from array. Only deletes last encountered.

Returns index of deleted value.


function reverse - Reverse part of array


Consts

Some useful consts. That's it.

const DAY_MS - Milliseconds in a full day


const HOUR_MS - Milliseconds in a hour


const MIN_MS - Milliseconds in a minute


const SEC_MS - Milliseconds in a second


Control

Utils related to code execution flow.

const SESSION_ID - Id generated only once per session


function UUID - Get universally unique string id. You can get information then id was generated using extractUUIDDate(uuid)

  • 13 char - timestamp
  • 13 char - SESSION_ID
  • 4 char - incremental id

30 char total.

USING CUSTOM TIMESTAMP MAY RESULT IN COLLISSIONS


function extractUUIDDate - Extract exact date of uuid generation


function createCashedFunction - Creates cached function. All arguments/results are cached. Returns [ fn [cached function], delete [delete cached result for arguments] hash ]


function createCashedAsyncFunction - Creates cached function. All arguments/results are cached. Will store in cache resolved data. Returns [ fn [cached function], delete [delete cached result for arguments] hash ]


async function retry - Retry async function


function createDebouncedFunction - Create debounced function. Basically adds cooldown to function. Warning: throws!


function createThrottledFunction - Create throttled function. Basically limits function calls in time period. Warning: throws!


function createDelayedFunction - Create debounced function. Basically create function that will be called with delay, but if another call comes in, we reset the timer (previous function isn't called).


class ImmediatePromise - Promise that accepts no callback, but exposes resolve and reject methods


function wait - setTimeout promisify


function timeout - Reject after specified time


function noop - Empty function that does nothing


async function concurrentRun - Run array of async tasks concurrently


class SimpleEventSource - Create simple event source. Consider using signal() for reactive state managment.


class Semaphore - Semaphore is used to limit concurrent tasks by delaying promise.

const semaphore = new Semaphore(2);

async function task() {
await semaphore.acquire();
try {
// This code can only be executed by two tasks at the same time
} finally {
semaphore.release();
}
}
task();
task();
task(); // This task will wait until one of the previous tasks releases the semaphore.

// === SHORTHAND ===
semaphore.run(()=>{
// Your code
})
semaphore.run(()=>{
// Your code
})
// ...

async function withTimeout - Add timeout to a promise


function promisify - Promisify a function with callback


function promisifyEventSource - Create a promise out of EventSource


Errors

Custom errors, finding errors and error handling.

class ValidationError - Use as intended error. Basically 4** errors in HTTP


class TimeoutError - Use as intended error. Basically 4** errors in HTTP


function findErrorText - Find error inside anything recursively. Good for finding human-readable errors. Tries priority keys first. Parses JSON automatically. Returns undefind if nothing found.


Formatting

Anything related to formatting and logging.

type FormatTimeRange - Type for formatTime ranges


const FORMAT_NUMBER_RANGES - Default time range


const FORMAT_NUMBER_RANGES_READABLE - Time range more suitable for readability


const FORMAT_NUMBER_RANGES_BYTES - Bytes range


function formatNumber - Milliseconds to human readable time. Minimum accuracy, if set to 1000 will stop at seconds


function camelToSnakeCase - thisCase to this_case


function snakeToCamelCase - this_case to thisCase


function formatBytes - Bytes to KB,MB,GB,TB


function log - Format logging


function capitalizeFirstLetter - Capitalize first letter


function pipe - pipe() can be called on one or more functions, each of which can take the return of previous value.

// Takes string, converts to int, calc sqrt, convert and return date
pipe(
(x: string) => Number.parseInt(x),
(x) => Math.sqrt(x),
(x) => new Date(x)
)('69')

Graphs

Pos

function unfoldPathfindingResult - Unfold pathfinding result to path array.


function aStar - Pathfind using aStar. Returns a target and map of parents. You can use unfoldPathfindingResult() to get array of nodes.


function bfs - Breadth-first search. Slower than dfs. If isTarget is omitted becomes floodfill. Returns a target and map of parents. You can use unfoldPathfindingResult() to get array of nodes.


function dfs - Depth-first search. Faster than bfs. If isTarget is omitted becomes floodfill. Returns a target and map of parents. You can use unfoldPathfindingResult() to get array of nodes.


function dijkstra - Dijkstra search. Like bfs but supports weight. If isTarget is omitted becomes floodfill (WITH WEIGHT). Returns a target and map of parents. You can use unfoldPathfindingResult() to get array of nodes.


function knapsack - Knapsack find best way to get maximum value in limited capacity


function hamiltonianCycle - Find min path between points. You need to supply 2-dim array where first index is a point and second index is a distance from this point to another. Put infinity if where are no path. Returns cycle (start and end at the same point) Original: https://github.com/qntm/held-karp


function traverseByNearestNeighbor - Traverse all points by nearest neighbor. Should be able to go from any point to any other point.


function twoOpt - 2-opt improvement


Numbers

Numbers, math, etc.

function random - Random number between min and max. May enable float


function parseInt - Same as Number.parseInt but throws if NaN or not safe


function parseFloat - Same as Number.parseFloat but throws if NaN or Infinity


function factorial - Factorial


function fib - Fibonacci


function clamp - Clamp numbers to max and min


function inRange - Is number in range. Inclusive.


function mean - Calucalate avarage from array of numbers


function round - Round with precision.

round(1.2345); // 1
round(1.2345, 2); // 1.23
round(1.2345, 10); // 1.2345

function sum - Sum of array of numbers


Objects

[object Object]

function getPropertyNames - Get all prorerty names, including in prototype


function objectMap - Map function like for arrays, but for objects


function objectFilter - Filter function like for arrays, but for objects


function addPrefixToObject - Adds prefix to every key in object


function deepEquals - Check if objects are deep equal

Supports:

  • All primitives (String, Number, BigNumber, Null, undefined, Symbol)
  • Objects
  • Iterables (Arrays, Map, Sets, Queries, Generators etc.)
  • Dates

Not supported:

  • Functions
  • Async iterables
  • Promises
  • etc

Behavior with types above are not defined, but it will still check them by reference.


function pick - Pick keys from object


class Base - Base class that helps to manage ids and subclasses.

Include next lines when extending this class:

static {
this.registerSubclass()
}

Signals

Reactive signals

function signal - SIGNALS SYSTEM

Signal can hold any data (except functions), when this data has changed any effects containing this signal will be rerun.

const $mySignal = signal<number|undefined>(1) // Create signal with initial value 1
$mySignal(5) // Set to 5
$mySignal(undefined) // Set to undefined
$mySignal(prev=>prev+1) // Increment
// Will print signal on change
effect(()=>{
console.log($mySignal())
})

function effect - SIGNALS SYSTEM

Effects are simplest way to react to signal changes. Returned data from handler function will be passed to it on next signal change. Returns a function that will clear the effect.

// Will print signal on change
effect(()=>{
console.log($mySignal())
})
// Use previous state as a reference
effect((last)=>{
const mySignal = $mySignal()
if(last>mySignal) console.log('Increment!')
return mySignal;
})

function untrack - SIGNALS SYSTEM

Untrack helps to not react to changes in effects.

const $a = signal(1)
const $b = signal(2)
// Will only run on changes to $b
effect(()=>{
console.log(untrack($a)+$b())
})

function computed - SIGNALS SYSTEM

Creates a derived reactive memoized signal.

// Sum of all changes of $a()
const { signal: $sumOfTwo, clear: clearSum } = derived((value) => value + $a(), 0)

function batch - SIGNALS SYSTEM

Batches multiple edits, so they don't call same effects multiple times

const $a = signal(1)
const $b = signal(2)
effect(()=>{
console.log($a()+$b())
})
$a(2); // Prints 4
$b(3); // Prints 5
// Prints only 10
batch(()=>{
$a(5);
$b(5);
})

function when - SIGNALS SYSTEM

Returns ImmediatePromise that is resolved when check function returns truthy value. If you want to, you can resolve or reject promise beforehand.

await when(() => $a()>5)
// With timeout
const promise = when(() => $a() > 5)
const timeout = setTimeout(() => promise.reject('Timeout')}, 5000)
primise.then(() => clearTimeout(timeout))

function resource - SIGNALS SYSTEM

Creates a async resource with outputs:

  1. value$ - return value of function
  2. isLoading$ - whether promise is still running
  3. error$ - error that happened during. Set on error, cleared on refresh
  4. refresh - force rerun handler

MAKE SURE THAT ALL SIGNAL'S VALUES ARE GRABBED BEFORE NEXT TICK!!!

const userId$ = signal(1);

// WRONG
const userResource = resource(async () => {
const res = await fetch(`/api/user`)
const userId = userId$();  // ERROR: Will not subscribe because after Promise i.e. next tick
return res.json().find(x=>x.id===userId);
})

// Correct
const userResource = resource(async () => {
const userId = userId$(); // Correctly subscribed because ran on the same tick
const res = await fetch(`/api/user`)
return res.json().find(x=>x.id===userId);
})

// React to changes
effect(() => {
if (userResource.isLoading$()) {
console.log('loading user...')
} else if (userResource.error$()) {
console.error('failed to load user', userResource.error$())
} else {
console.log('user loaded', userResource.value$())
}
})

// Force a refresh
userResource.refresh()

// Stop automatic updates and cleanup
userResource.clear()

Time

Timers, CRON, etc.

function measurePerformance - Measure performance of a function


function setSafeTimeout - Original setTimeout and setIntval known for accumulating delay and causing problem with timeouts bigger than 32bit integer.

This timeout wrapper fixes them. Returns clear function.


function setSafeInterval - Original setTimeout and setIntval known for accumulating delay and causing problem with timeouts bigger than 32bit integer.

This interval wrapper fixes them. Returns clear function.


function cronInterval - Like setInterval but with cron. Returns clear function. For cron string syntax check getNextCron() description


function getNextCron - Find next cron date after passed date. This function DOES NOT implement regular CRON 1 to 1.

  1. [0-999] Milliseconds
  2. [0-59] Seconds
  3. [0-59] Minutes
  4. [0-23] Hours
  5. [1-31] Dates
  6. [1-12] Months
  7. [0-6] Weekdays

Main differences:

  • Weekdays value only 0 to 6 (0 is Sunday)
  • New supported syntax: 30-60/10 - means 30,40,50,60
  • Second and millisecond support: 0,500 300 - every 30 seconds, two times

class SpeedCalculator - Object that calculates speed, ETA and percent of any measurable task.

push() chunks into speed calculator and then read stats for results. size - a target then task is finished. Without it only speed is calculated. historyTime - is a time period based on which speed will be calculated.


Types

Damn, I love TypeScript.

type Primitive - Values that are copied by value, not by reference


type AnyFunction - Function with any arguments or return type


type Falsy - Values that convert to false


type Optional - Make keys in object optional


type RequiredKey - Make keys in object required


type Constructor - Get contructor type of an instance


type AwaitedObject - Recursively resolves promises in objects and arrays


type JSONSerializable - Anything that can be serialized to JSON


type ObjectAddPrefix - Adds prefix to all keys in object


type CamelToSnakeCase - Convert type of thisCase to this_case


type ObjectCamelToSnakeCase - Convert object keys of thisCase to this_case


type SnakeToCamel - Convert type of this-case to thisCase


type ObjectSnakeToCamel - Convert object keys of this-case to thisCase


type Concat - Concat types of array or objects


type Prettify - Visual only overhaul. Shows final type result on hover.

type a = {a: '1'}
type b = Prettify<a & { b: 'b' }>
// On hovering b it will show
type b = {
a: "1";
b: "b";
}
// instead of
type b = a & {
b: "b";
}

type Tuple - Create a tuple of size.

type a = Tuple<number, 3>
type b = [number, number, number]