
Security News
The Next Open Source Security Race: Triage at Machine Speed
Claude Opus 4.6 has uncovered more than 500 open source vulnerabilities, raising new considerations for disclosure, triage, and patching at scale.
A collection of ES7 async/await utilities. Install via NPM:
npm install asyncbox
Then, behold!
An async/await version of setTimeout
import { sleep } from 'asyncbox';
async function myFn () {
// do some stuff
await sleep(1000); // wait one second
// do some other stuff
};
Sometimes Promise.delay or setTimeout are inaccurate for large wait times. To safely wait for these long times (e.g. in the 5+ minute range), you can use longSleep:
import { longSleep } from 'asyncbox';
async function myFn () {
await longSleep(10 * 60 * 1000); // wait for 10 mins
await longSleep(5000, {thresholdMs: 10000}); // wait for 5s. Anything below the thresholdMs will use a single sleep
await longSleep(5000, {intervalMs: 500}); // check the clock every 500ms to see if waiting should stop
}
You can also pass a progressCb option which is a callback function that receives an object with the properties elapsedMs, timeLeft, and progress. This will be called on every wait interval so you can do your wait logging or whatever.
function progressCb({elapsedMs, timeLeft, progress}) {
console.log(`We are {progress * 100}% complete waiting`);
}
await longSleep(10 * 60 * 1000, {progressCb});
An async/await way of running a method until it doesn't throw an error
import { sleep, retry } from 'asyncbox';
async function flakeyFunction (val1, val2) {
if (val1 < 10) {
throw new Error("this is a flakey value");
}
await sleep(1000);
return val1 + val2;
}
async function myFn () {
let randVals = [Math.random() * 100, Math.random() * 100];
// run flakeyFunction up to 3 times until it succeeds.
// if it doesn't, we'll get the error thrown in this context
let randSum = await retry(3, flakeyFunction, ...randVals);
}
You can also use retryInterval to add a sleep in between retries. This can be
useful if you want to throttle how fast we retry:
await retryInterval(3, 1500, expensiveFunction, ...args);
Filter and map are pretty handy concepts, and now you can write filter and map functions that execute asynchronously!
import { asyncmap, asyncfilter } from 'asyncbox';
Then in your async functions, you can do:
const items = [1, 2, 3, 4];
const slowSquare = async (n) => { await sleep(5); return n * n; };
let newItems = await asyncmap(items, slowSquare);
console.log(newItems); // [1, 4, 9, 16];
const slowEven = async (n) => { await sleep(5); return n % 2 === 0; };
newItems = await asyncfilter(items, slowEven);
console.log(newItems); // [2, 4];
By default, asyncmap and asyncfilter run their operations in parallel, but you
can set the third argument to false to enforce sequential execution, or set a custom
concurrency pool limit using {concurrency: <number>}:
const items = [1, 2, 3, 4];
const slowSquare = async (n) => { await sleep(5); return n * n; };
// this will run sequentially (~20ms)
const newItemsSeq = await asyncmap(items, slowSquare, false);
// this will handle 2 items at a time (~10ms)
const newItemsMaxTwo = await asyncmap(items, slowSquare, {concurrency: 2});
Takes a condition (a function returning a boolean or boolean promise), and waits until the condition is true.
Throws a /Condition unmet/ error if the condition has not been
satisfied within the allocated time, unless an error is provided in
the options, as the error property, which is either thrown itself, or
used as the message.
The condition result is returned if it is not falsy. If the condition throws an error then this exception will be immediately passed through.
The default options are: { waitMs: 5000, intervalMs: 500 }
// define your own condition
function condFn () { return Math.random()*1000 > 995; }
// with default params
await waitForCondition(condFn);
// with options
await waitForCondition(condFn, {
waitMs: 300000,
intervalMs: 10000
});
// pass a logger to get extra debug info
await waitForCondition(condFn, {
waitMs: 300000,
intervalMs: 10000
logger: myLogger // expects a debug method
});
// pass an error string to get that message in the resulting exception
try {
await waitForCondition(condFn, {
error: 'Unable to satisfy condition'
});
} catch (err) {
// err.message === 'Unable to satisfy condition'
}
// pass an error instance to be thrown
const error = new Error('Unable to satisfy condition');
try {
await waitForCondition(condFn, {
error: error
});
} catch (err) {
// err === error
}
npm test
The `async` package provides a collection of functions for working with asynchronous JavaScript. It includes utilities for parallel and sequential execution, as well as flow control. Compared to asyncbox, it offers a broader range of utilities but may be more complex to use.
The `bluebird` package is a fully-featured Promise library that provides additional functionality over native Promises, such as cancellation, progress tracking, and more. While it doesn't focus on utilities like asyncbox, it enhances promise handling and chaining.
The `p-retry` package is a simple utility for retrying failed promises. It is similar to the retry functionality in asyncbox but is more focused and configurable, offering options like exponential backoff.
FAQs
A collection of small async/await utilities
The npm package asyncbox receives a total of 1,144,902 weekly downloads. As such, asyncbox popularity was classified as popular.
We found that asyncbox demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 4 open source maintainers collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
Claude Opus 4.6 has uncovered more than 500 open source vulnerabilities, raising new considerations for disclosure, triage, and patching at scale.

Research
/Security News
Malicious dYdX client packages were published to npm and PyPI after a maintainer compromise, enabling wallet credential theft and remote code execution.

Security News
gem.coop is testing registry-level dependency cooldowns to limit exposure during the brief window when malicious gems are most likely to spread.