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

p-suite

v0.1.0

Published

A collection of useful promise utilities

Downloads

6

Readme

p-suite

A collection of all of sindresorhus promise modules. This is a fork of promise-fun. It will be periodically updated with the latest upstream changes (any package additions/removals etc.).

Contents

Installation

npm install p-suite

Usage

import pMemoize from 'p-suite/p-memoize'

const memoized = pMemoize(myFunction)

Or you can use the barrel file if you are confident in your tree-shaker:

import {pMemoize} from 'p-suite'

const memoized = pMemoize.default(myFunction)

Note that that you need to use .default explicitly - there's no mapping of default to named exports.

When should you use p-suite?

If you're not sure which promise module you want to use yet, or you want to use a combination of them, you can get them all from a single install. However, it's very unlikely that you'll need them all, so if you are concerned about the size of your node_modules, you should install the individual packages.

For browser usage, or if bundle size is a concern for any other reason, you should be able to use the individual exports (for example import pMemoize from 'p-suite/p-memoize') without negatively impacting your bundle size. But make sure to test this using a bundle analyzer if you're concerned.

Packages

Not accepting additions, but happy to take requests.

  • pify: Promisify a callback-style function
  • delay: Delay a promise a specified amount of time
  • yoctodelay: Delay a promise a specified amount of time
  • p-map: Map over promises concurrently
  • p-all: Run promise-returning & async functions concurrently with optional limited concurrency
  • p-event: Promisify an event by waiting for it to be emitted
  • p-debounce: Debounce promise-returning & async functions
  • p-throttle: Throttle promise-returning & async functions
  • p-timeout: Timeout a promise after a specified amount of time
  • p-retry: Retry a promise-returning or async function
  • p-any: Wait for any promise to be fulfilled
  • p-some: Wait for a specified number of promises to be fulfilled
  • p-mutex: Ensure that only one operation accesses a particular resource at a time
  • p-locate: Get the first fulfilled promise that satisfies the provided testing function
  • p-limit: Run multiple promise-returning & async functions with limited concurrency
  • p-series: Run promise-returning & async functions in series
  • p-memoize: Memoize promise-returning & async functions
  • p-pipe: Compose promise-returning & async functions into a reusable pipeline
  • p-props: Like Promise.all() but for Map and Object
  • p-waterfall: Run promise-returning & async functions in series, each passing its result to the next
  • p-cancelable: Create a promise that can be canceled
  • p-progress: Create a promise that reports progress
  • p-reflect: Make a promise always fulfill with its actual fulfillment value or rejection reason
  • p-filter: Filter promises concurrently
  • p-reduce: Reduce a list of values using promises into a promise for a value
  • p-settle: Settle promises concurrently and get their fulfillment value or rejection reason with optional limited concurrency
  • p-map-series: Map over promises serially
  • p-each-series: Iterate over promises serially
  • p-times: Run promise-returning & async functions a specific number of times concurrently
  • p-lazy: Create a lazy promise that defers execution until .then() or .catch() is called
  • p-whilst: While a condition returns true, calls a function repeatedly, and then resolves the promise
  • p-do-whilst: Calls a function repeatedly while a condition returns true and then resolves the promise
  • p-forever: Run promise-returning & async functions repeatedly until you end it
  • p-wait-for: Wait for a condition to be true
  • p-min-delay: Delay a promise a minimum amount of time
  • p-try: Promise.try() ponyfill - Starts a promise chain
  • p-race: A better Promise.race()
  • p-immediate: Returns a promise resolved in the next event loop - think setImmediate()
  • p-time: Measure the time a promise takes to resolve
  • p-defer: Create a deferred promise
  • p-is-promise: Check if something is a promise
  • p-state: Inspect the state of a promise
  • p-queue: Promise queue with concurrency control
  • make-synchronous: Make an asynchronous function synchronous

.then/.catch-based packages

You should generally avoid using .then except in edge cases.

  • p-catch-if: Conditional promise catch handler
  • p-if: Conditional promise chains
  • p-tap: Tap into a promise chain without affecting its value or state
  • p-log: Log the value/error of a promise
  • p-break: Break out of a promise chain

FAQ

How can I run 100 async/promise-returning functions with only 5 running at once?

This is a good use-case for p-map. You might ask why you can't just specify an array of promises. Promises represent values of a computation and not the computation itself - they are eager. So by the time p-map starts reading the array, all the actions creating those promises have already started running. p-map works by executing a promise-returning function in a mapper function. This way the promises are created lazily and can be concurrency limited. Check out p-all instead if you're using different functions to get each promise.

import pMap from 'p-suite/p-map';

const urls = [
	'https://sindresorhus.com',
	'https://avajs.dev',
	'https://github.com',
	…
];

console.log(urls.length);
//=> 100

const mapper = url => fetchStats(url); //=> Promise

const result = await pMap(urls, mapper, {concurrency: 5});

console.log(result);
//=> [{url: 'https://sindresorhus.com', stats: {…}}, …]

Is this affiliated with sindresorhus?

No. It's a fork of the promise-fun repo, but that only consists of a hand-written readme file pointing to the various other packages. Sindre very reasonably did not want to maintain a generated monopackage. It's also worth noting that as JavaScript develops some of the packages are less necessary - a handful of them existed before async/await, so only use as needed.

When is p-suite updated and published?

There is a scheduled GitHub Actions workflow that will update p-suite with the latest versions of all its dependencies, once per day. Publishing is not automated, however, so major version updates will be made ad-hoc. In general, there will likely be a major version update whenever at least one of the dependency packages is updated.

pkg.pr.new is enabled on the repository, so you can try a prerelease version even without an npm publish of p-suite by looking at the checks for the default branch.

Contributing

The package.json dependencies and exports are generated from this readme. So, to add a new package, it should be added to the readme with the same format as the others. There is an automated GitHub Actions workflow that will automatically update the package.json exports and dependencies, as well as the javascript and typescript files.

If you need to change the code in the source/ folder, don't modify it directly. Instead, make the change in generate.js which generates it.

Implementation (what this fork adds to sindresorhus's original repo):

  • adds a package.json (named p-suite rather than promise-fun since that npm package name is taken on npm)
  • add a generate.js script which:
    • parses the readme to get all the packages that should be included
    • installs the latest versions of all packages
    • creates .js and .d.ts files for each package (e.g. export * from 'p-memoize')
    • creates a barrel file re-exporting all the packages (e.g. export * as pMemoize from 'p-memoize')
    • adds an exports definition pointing to each re-export file
    • calculates an engines.node range that satisfies all the sub-packages*
  • add tests (right now, just making sure an example module works at runtime and typescript-compile time)
  • add CI:
    • run the generate script to make sure everything's up to date
    • use autofix.ci to push an update if not
    • run some tests (right now, just makes sure that types + runtime were generated properly for p-memoize)
    • use pkg.pr.new to publish a prerelease version (so you can try this out right now: npm install https://pkg.pr.new/mmkal/p-suite@8c181db - link)

The idea is that everything should be fully automated, so maintenance should be as simple as git pull && pnpm install && pnpm generate.

Personally I would be open to adding some other useful tools that fit well with p-* packages like expiry-map, but I'll hold off on that until there's an indication one way or another whether @sindresorhus would like to co-maintain this!

I'm creating it as a draft since it'd be a reasonably big ask for you to accept this. I'm happy to leave it for a few days and rely on the pkg.pr.new link before publishing to npm.


*note: the algorithm to detect the minimum required node version depends on the semver package's various helpers. It isn't bullet-proof, but from debugging manually it seems good enough. This unfortunately isn't part of semver: https://github.com/npm/node-semver/issues/527. If it breaks down in future it will show up in the generated package.json though.