New Research: Supply Chain Attack on Axios Pulls Malicious Dependency from npm.Details →
Socket
Book a DemoSign in
Socket

retried

Package Overview
Dependencies
Maintainers
1
Versions
1
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

retried

A minimal, type-safe asynchronous operation retry utility for TypeScript.

latest
npmnpm
Version
1.0.0
Version published
Maintainers
1
Created
Source

retried.ts

A minimal, type-safe asynchronous operation retry utility for TypeScript.

License: MIT

Why retired?

Retrying failed asynchronous operations (like network requests) is a common requirement. While libraries like async-retry existed already in this space, retried.ts aims to provide:

  • Simplicity: The core logic is straightforward and contained within a single, small function.
  • Type Safety: Built with TypeScript, providing clear interfaces and type checking out-of-the-box.
  • Modern Approach: Uses modern async/await syntax.
  • Maintainability: Addresses the fact that async-retry appears less actively maintained and lacks first-class TypeScript support.

Copy, Don't Install

This library is intentionally simple. Instead of adding another dependency to your package.json for such a small utility, I strongly encourage you to copy the src/retry.ts code directly into your project.

Benefits:

  • Zero Dependencies: No extra baggage in your node_modules.
  • Full Control: Easily understand, modify, and adapt the code to your specific needs without waiting for library updates.
  • Transparency: You know exactly what code is running.
  • Reduced Complexity: Avoids potential version conflicts or the overhead of managing another dependency.

Keep your codebase lean and maintain control over simple utilities like this!

Usage

  • Copy: Copy the contents of src/retry.ts (including the RetryConfig interface and the retry function) into your project (e.g., src/utils/retry.ts).
  • Import: Import the retry function where needed.
  • Wrap: Wrap your asynchronous function call with retry.

Basic Example

import { retry } from "./utils/retry"; // Adjust path as needed

async function mightFail(): Promise<string> {
    const random = Math.random();
    if (random < 0.7) {
        console.log("Operation failed, throwing error...");
        throw new Error("Failed to complete operation");
    }
    console.log("Operation succeeded!");
    return "Success!";
}

async function run() {
    try {
        const result = await retry(mightFail);
        console.log(`Final Result: ${result}`);
    } catch (error) {
        console.error(`Operation ultimately failed after retries: ${error}`);
    }
}

run();

Example with Options

import { retry, RetryConfig } from "./utils/retry"; // Adjust path

async function fetchData(url: string): Promise<Response> {
    const response = await fetch(url);
    if (!response.ok) {
        throw new Error(`HTTP error! status: ${response.status}`);
    }
    return response.json();
}

async function getImportantData() {
    const retryOptions: Partial<RetryConfig> = {
        retries: 5, // Try 5 times total (1 initial + 4 retries)
        baseTimeout: 500, // Start with 500ms delay
        strategy: "exponential", // Double the delay each time
        onRetry: (error) => {
            console.warn(`Attempt failed: ${error}. Retrying...`);
        },
    };

    try {
        const data = await retry(() => fetchData("https://api.example.com/data"), retryOptions);
        console.log("Successfully fetched data:", data);
    } catch (error) {
        console.error("Failed to fetch data after multiple retries:", error);
    }
}

getImportantData();

⚙️ Configuration Options (RetryConfig)

You can pass an optional configuration object as the second argument to retry.

OptionTypeDefaultDescription
retriesnumber3Total number of attempts (initial attempt + retries).
baseTimeoutnumber100Initial delay in milliseconds before the first retry.
maxTimeoutnumber300000Maximum delay in milliseconds between retries.
strategy'exponential' | 'fixed'exponential'exponential': Doubles the timeout each retry. 'fixed': Keeps timeout constant.
onRetry(error: unknown) => void | undefinedundefinedCallback function executed before each retry attempt (after a failure).

Note: The actual delay includes a small random jitter (0-1000ms by default) added to the calculated timeout to help prevent thundering herd issues.

Testing

The retry function is designed to be testable. It accepts an optional third argument, delayFn, which defaults to a function using setTimeout. You can provide a mock delay function (e.g., using vi.fn().mockResolvedValue(undefined) from vitest) to test the retry logic without actual delays. See the accompanying test file (retry.test.ts if you copied it) for examples.

Acknowledgements

This utility is heavily inspired by the excellent async-retry library by Vercel. It aims to provide a similar core functionality with a focus on TypeScript and simplicity, encouraging direct integration rather than dependency installation.

License

MIT License - see the LICENSE file for details. (You'll need to add an MIT license file to your repo if you don't have one).

FAQs

Package last updated on 29 Mar 2025

Did you know?

Socket

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.

Install

Related posts