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

prutill

v1.2.0

Published

Environment-agnostic production-ready promise utility library for managing promise stacks and race conditions. Supports Node.js, Deno, and browsers.

Readme

🚀 prutill

npm dependencies Coverage Status License contributions welcome

A lightweight, environment-agnostic, production-ready Promise utility library for managing concurrent Promise executions and their side effects.

✨ Features

  • 🌐 Last Promise Resolution - Ensures only the most recent Promise affects your application state
  • 🏃‍♂️ Race Promise Resolution - Acts on the first resolved Promise while managing others
  • 🕒 Timed Promises - Create Promises that resolve after a specified timeout
  • 🔄 Promise Wrapper - Wraps synchronous or asynchronous functions into Promises
  • 🏗️ Zero Dependencies - Lightweight and focused functionality
  • 🔒 Type-Safe - Written in TypeScript with full type definitions
  • 🧪 Well Tested - Comprehensive test coverage

🛠️ Installation

Node.js / Bundlers

# Using npm
npm install prutill

# Using yarn
yarn add prutill

# Using pnpm
pnpm add prutill

Deno

import {
    getLastPromise,
    getRaceWonPromise,
    DelayedPromise,
} from "https://raw.githubusercontent.com/dominikj111/prutill/refs/tags/v1.2.0/mod.js";

📦 Supported Environments

  • ✅ Node.js (CommonJS)
  • ✅ ES Modules
  • ✅ Deno
  • ✅ Browsers

💡 Usage

Last Promise Resolution

Useful for scenarios where you only want to act on the most recent Promise, like in React's useEffect:

import { getLastPromise } from "prutill";

// React example
useEffect(() => {
    getLastPromise("data-fetch", fetchData()).then(data => {
        // Only the latest fetch will update the state
        setState(data);
    });
}, [dependency1, dependency2]);

Race Promise Resolution

When you want to act on the first resolved Promise:

import { getRaceWonPromise } from "prutill";

// Multiple API endpoints example
getRaceWonPromise("fastest-api", fetch("api1")).then(data => {
    // First resolved API response wins
    processData(data);
});
getRaceWonPromise("fastest-api", fetch("api2"));

Timed Promise

Create Promises that resolve after a specific duration:

import { DelayedPromise } from "prutill";

// Resolve after 500ms
new DelayedPromise(500).then(() => {
    console.log("500ms passed");
});

// Resolve with value after 1000ms
new DelayedPromise(1000, "Hello").then(value => {
    console.log(value); // Outputs: "Hello"
});

Promise Wrapper

Wrap any synchronous or asynchronous function into a Promise:

import { promiseWrapper } from "prutill";

// Wrap a synchronous function
const result1 = await promiseWrapper(() => 42);
console.log(result1); // 42

// Wrap an asynchronous function
const result2 = await promiseWrapper(async () => {
    const response = await fetch("https://api.example.com/data");
    return response.json();
});

// Error handling
try {
    await promiseWrapper(() => {
        throw new Error("Something went wrong");
    });
} catch (error) {
    console.error(error); // Error: Something went wrong
}

📚 API Documentation

getLastPromise(key: string, promise: Promise, resolveAllPrevious = true): Promise

  • key: Unique identifier for the promise stack
  • promise: Promise to add to the stack
  • resolveAllPrevious: If true, resolves all previous promises with the latest value

getRaceWonPromise(key: string, promise: Promise, resolveAllOthers = true): Promise

  • key: Unique identifier for the promise race
  • promise: Promise to add to the race
  • resolveAllOthers: If true, resolves all other promises with the winning value

DelayedPromise

  • constructor(timeout: number, passThrough?: T)
  • timeout: Time in milliseconds before the promise resolves
  • passThrough: Optional value to resolve with

🤝 Contributing

We welcome contributions! Please see our Contributing Guide for details.

📄 License

Apache-2.0 © dominikj111

This library is licensed under the Apache License, Version 2.0. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0