npm package: @pingpong-js/plugin-retry
Description: Advanced retry plugin for @pingpong-js/fetch with circuit breaker, rate limiting, and backoff strategies
Author: Devendra Pratap
Latest version: 1.0.1

# @pingpong-js/plugin-retry

Advanced retry strategies and resilience patterns for [@pingpong-js/fetch](https://www.npmjs.com/package/@pingpong-js/fetch).

## Installation

```bash
npm install @pingpong-js/plugin-retry
# peer dependency
npm install @pingpong-js/fetch
```

## Features

- 🔄 **Advanced Retry**: Exponential, linear, fibonacci, decorrelated backoff
- ⚡ **Circuit Breaker**: Prevent cascading failures
- 🚦 **Rate Limiting**: Client-side request throttling
- ⏱️ **Configurable Timeout**: Per-method timeout settings
- 🎯 **Fallback Handler**: Return fallback data on failure
- 🛡️ **Jitter Support**: Prevent thundering herd

## Usage

### Advanced Retry

```typescript
import pingpong from '@pingpong-js/fetch';
import { withAdvancedRetry } from '@pingpong-js/plugin-retry';

pingpong.onRetry(withAdvancedRetry({
  maxRetries: 5,
  backoff: 'exponential',
  jitter: 'full',
  onRetry: (attempt, delay, response) => {
    console.log(`Retry ${attempt}, waiting ${delay}ms`);
  },
}));
```

### Circuit Breaker

```typescript
import pingpong from '@pingpong-js/fetch';
import { createCircuitBreaker, CircuitOpenError } from '@pingpong-js/plugin-retry';

const breaker = createCircuitBreaker({
  failureThreshold: 5, // Open after 5 failures
  timeout: 30000, // Try again after 30s
  onStateChange: (state, prev) => {
    console.log(`Circuit: ${prev} -> ${state}`);
  },
});

pingpong.onRequest(breaker.request);
pingpong.onResponse(breaker.response);
pingpong.onError(breaker.error);

try {
  await pingpong.get('/api/unreliable');
} catch (error) {
  if (error instanceof CircuitOpenError) {
    console.log('Circuit is open, try again later');
  }
}
```

### Rate Limiting

```typescript
import pingpong from '@pingpong-js/fetch';
import { withRateLimit } from '@pingpong-js/plugin-retry';

// 10 requests per second
pingpong.onRequest(withRateLimit({
  maxRequests: 10,
  window: 1000,
  strategy: 'delay', // 'delay' | 'reject' | 'queue'
}));
```

### Fallback Handler

```typescript
import pingpong from '@pingpong-js/fetch';
import { withFallback } from '@pingpong-js/plugin-retry';

// Static fallback
pingpong.onError(withFallback({
  fallbackData: { users: [], error: true },
  onFallback: (error) => console.warn('Using fallback:', error.message),
}));

// Dynamic fallback
pingpong.onError(withFallback({
  fallbackFn: async (error, request) => {
    return getCachedData(request.url);
  },
}));
```

### Configurable Timeout

```typescript
import pingpong from '@pingpong-js/fetch';
import { withTimeoutPlugin } from '@pingpong-js/plugin-retry';

pingpong.onRequest(withTimeoutPlugin({
  timeout: 5000,
  methodTimeouts: {
    POST: 30000, // POST gets 30s
    GET: 5000,   // GET gets 5s
  },
}));
```

## API Reference

### `withAdvancedRetry(options?)`

Advanced retry with configurable backoff strategies.

**Options:**
- `maxRetries`: Maximum retry attempts (default: `3`)
- `baseDelay`: Base delay in ms (default: `1000`)
- `maxDelay`: Maximum delay in ms (default: `30000`)
- `backoff`: `'exponential'` | `'linear'` | `'constant'` | `'fibonacci'` | `'decorrelated'`
- `jitter`: `'full'` | `'equal'` | `'none'`
- `retryStatusCodes`: Status codes to retry (default: `[408, 429, 500, 502, 503, 504]`)
- `respectRetryAfter`: Honor Retry-After header (default: `true`)

### `createCircuitBreaker(options?)`

Circuit breaker pattern implementation.

**Options:**
- `failureThreshold`: Failures before opening (default: `5`)
- `successThreshold`: Successes to close from half-open (default: `2`)
- `timeout`: Time before trying half-open (default: `30000`)
- `failureStatusCodes`: Status codes considered failures
- `onStateChange`: Callback when state changes

### `withRateLimit(options?)`

Client-side rate limiting.

**Options:**
- `maxRequests`: Requests per window (default: `10`)
- `window`: Window size in ms (default: `1000`)
- `strategy`: `'delay'` | `'reject'` | `'queue'`

### `withFallback(options)`

Return fallback data on failure.

### `withTimeoutPlugin(options?)`

Add configurable timeout to requests.

## License

MIT