
Security News
The Hidden Blast Radius of the Axios Compromise
The Axios compromise shows how time-dependent dependency resolution makes exposure harder to detect and contain.
@webinmove/nyuma
Advanced tools
Nyuma means "back" in Swahili. It is an async retry implementation with fibonacci or exponential strategy.
All the backoff implementation I came accross where missing on key feature: a maximum overall time option.
$ npm install @webinmove/nyuma
const { fibonacci } = require('@webinmove/nyuma');
const fetch = require('node-fetch');
const main = async () => {
const nyuma = fibonacci({ initialDelay: 100, maxTime: 60000 });
try {
// Here we'll only retry on real network error
const response = await nyuma.start(() =>
fetch('https://api.github.com/repos/webinmove/nyuma')
);
console.log(await response.json());
} catch (err) {
// Couldn't get the response in less than a minute...
console.error(err);
}
};
main();
const { exponential } = require('@webinmove/nyuma');
const fetch = require('node-fetch');
const main = async () => {
const nyuma = exponential({
initialDelay: 100,
maxDelay: 10000,
maxRetries: 3,
maxTime: 60000,
maxTimeError: 'First fetch was too long',
factor: 3
});
try {
const body = await nyuma
.retryHook(({ error, retryCount, lastDelay, duration }) =>
console.log('Retry with:', { error, retryCount, lastDelay, duration })
)
.failHook(({ reason, retryCount, lastDelay, duration }) =>
console.log('Failed with:', { reason, retryCount, lastDelay, duration })
)
.start(async () => {
const response = await fetch('https://api.github.com/repos/webinmove/nyuma');
if (response.status >= 400) {
throw new Error(`Call responded with status ${response.status}`);
}
return response.json();
});
console.log(body);
} catch (err) {
// Couldn't get the response in less than a minute or 5 retries...
console.error(err);
}
};
main();
const { Nyuma, ExponentialStrategy } = require('@webinmove/nyuma');
const fetch = require('node-fetch');
const main = async () => {
const strategy = new ExponentialStrategy({ factor: 3 });
const nyuma = new Nyuma({
strategy,
initialDelay: 100,
maxDelay: 10000,
maxRetries: 3,
maxTime: 60000
});
nyuma.failHook(({ reason, retryCount, lastDelay, duration }) =>
console.log({ reason, retryCount, lastDelay, duration })
);
try {
const body = await nyuma.start(async () => {
const response = await fetch('https://api.github.com/repos/webinmove/nyuma');
if (response.status >= 400) {
throw new Error(`Call responded with status ${response.status}`);
}
return response.json();
});
console.log(body);
} catch (err) {
// Couldn't get the response in less than a minute or 5 retries...
console.error(err);
}
};
main();
Returns a Nyuma instance initialized with the fibonacci strategy and the params.
params
Note: you should specify at least a maxRetries or a maxTime
Returns a Nyuma instance initialized with the exponential strategy and the params.
params
Note: you should specify at least a maxRetries or a maxTime
Returns a Nyuma instance initialized with the params.
params
Note: you should specify at least a maxRetries or a maxTime
Start the retry process retruning a promise of the fn result.
When called this function will have 2 arguments:
exemple:
const { Nyuma, FibonacciStrategy } = require('@webinmove/nyuma');
const main = async () => {
const strategy = new FibonacciStrategy();
const nyuma = new Nyuma({ strategy, initialDelay: 10, maxRetries: 10 });
await nyuma.start(async (retryCount, lastDelay) => {
console.log(`${retryCount} ${lastDelay} ms`);
throw new Error('Try again!');
}
);
};
main();
will output:
0 0 ms
1 10 ms
2 10 ms
3 20 ms
4 30 ms
5 50 ms
6 80 ms
7 130 ms
8 210 ms
9 340 ms
10 550 ms
(node:51869) UnhandledPromiseRejectionWarning: Error: Try again!
Set a function on fail hook function.
When called this function will have 1 argument:
Returns a ExponentialStrategy instance initialized with the params.
params
Retruns the next iteration of the exponential sequence (e.g.: 1, 2, 4, 8, ...).
Returns a FibonacciStrategy instance initialized with the params.
Retruns the next iteration of the fibonacci sequence (e.g.: 1, 1, 2, 3, 5, 8, ...).
$ npm run format
$ npm run test:spec
$ npm run test:lint
$ npm run test:cover
This will create a coverage folder with all the report in coverage/index.html
$ npm test
Note: that's the one you want to use most of the time
If you want to report a bug or request a feature, please open an issue.
If want to help us improve nyuma, fork and make a pull request.
Please use commit format as described here.
And don't forget to run npm run format before pushing commit.
FAQs
Retry an async function with different strategies
We found that @webinmove/nyuma demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 2 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
The Axios compromise shows how time-dependent dependency resolution makes exposure harder to detect and contain.

Research
A supply chain attack on Axios introduced a malicious dependency, plain-crypto-js@4.2.1, published minutes earlier and absent from the project’s GitHub releases.

Research
Malicious versions of the Telnyx Python SDK on PyPI delivered credential-stealing malware via a multi-stage supply chain attack.