API Reference

ProxyManager

Enterprise-grade proxy pool manager with rotation strategies, automatic failure handling, cooldown recovery, URL-based filtering, and a comprehensive hook system.

Constructor

new ProxyManager(config: ProxyManagerConfig)

ProxyManagerConfig

The config type is a union of ProxyManagerBaseConfig with one of three RotationConfig variants:

type ProxyManagerConfig = ProxyManagerBaseConfig & RotationConfig;

Base Config Properties

PropertyTypeDefaultDescription
proxies(ProxyInfo \| string)[]requiredArray of proxies. Accepts ProxyInfo objects or URL strings.
whitelist(string \| RegExp)[]undefinedURL patterns that should use proxy. If set, only matching URLs use proxy.
blacklist(string \| RegExp)[]undefinedURL patterns that should NOT use proxy (go direct). Checked after whitelist.
autoDisableDeadProxiesbooleanfalseAutomatically disable proxies after consecutive failures.
maxFailuresnumber3Consecutive failures before disabling.
cooldownProxyCooldownConfigundefinedCooldown config for disabled proxies.
cooldownPeriodnumberundefinedShorthand for cooldown: { enabled: true, durationMs: value }.
failWithoutProxybooleantrueThrow error when no proxy available. Set false for direct connection fallback.
retryWithNextProxybooleanfalseRetry failed requests with the next proxy.
maxProxyRetriesnumber3Max retry attempts when retryWithNextProxy is enabled.
debugbooleanfalseEnable debug logging for hook errors.
hooksobjectundefinedEvent hooks (alternative to setting after construction).

RotationStrategy

type RotationStrategy = 'random' | 'sequential' | 'per-proxy-limit';
StrategyConfigDescription
'random'{ rotation: 'random' }Random proxy selection for each request.
'sequential'{ rotation: 'sequential', requestsPerProxy?: number }Cycle through proxies in order. Optional requests per proxy before rotating (default: 1).
'per-proxy-limit'{ rotation: 'per-proxy-limit', limit: number }Use each proxy for limit requests, then permanently remove it.

ProxyCooldownConfig

interface ProxyCooldownConfig {
  enabled: boolean;
  durationMs: number;
}

Example

import { ProxyManager } from 'rezo';

const manager = new ProxyManager({
  rotation: 'random',
  proxies: [
    { protocol: 'http', host: 'proxy1.example.com', port: 8080 },
    'socks5://user:pass@proxy2.example.com:1080',
    'http://proxy3.example.com:3128'
  ],
  whitelist: ['api.example.com', /^https://secure./],
  blacklist: ['localhost', '127.0.0.1'],
  autoDisableDeadProxies: true,
  maxFailures: 3,
  cooldown: { enabled: true, durationMs: 30000 },
  failWithoutProxy: true
});

URL Filtering

shouldProxy(url)

Checks if a URL should use a proxy based on whitelist/blacklist rules.

shouldProxy(url: string): boolean

Example

manager.shouldProxy('https://api.example.com/data'); // true (matches whitelist)
manager.shouldProxy('http://localhost:3000/test');     // false (matches blacklist)

Pool Inspection

getActive()

Returns all active (non-disabled) proxies.

getActive(): ProxyInfo[]

getDisabled()

Returns all permanently disabled proxies (not in cooldown).

getDisabled(): ProxyInfo[]

getCooldown()

Returns proxies currently in cooldown (will auto-re-enable).

getCooldown(): ProxyInfo[]

getAll()

Returns the full internal ProxyState for every proxy in the pool.

getAll(): ProxyState[]

getStatus()

Returns a complete status summary of the proxy pool.

getStatus(): ProxyManagerStatus

Returns:

interface ProxyManagerStatus {
  active: ProxyInfo[];
  disabled: ProxyInfo[];
  cooldown: ProxyInfo[];
  total: number;
  rotation: RotationStrategy;
  totalRequests: number;
  totalSuccesses: number;
  totalFailures: number;
}

Proxy Selection

next(url)

Selects the next proxy based on rotation strategy. Convenience alias for select(url).proxy.

next(url: string): ProxyInfo | null

Returns null if no proxy is available or URL should go direct.

select(url)

Selects a proxy with a detailed reason. Core selection method that fires hooks, applies rotation, and updates state.

select(url: string): ProxySelectionResult

Returns:

interface ProxySelectionResult {
  proxy: ProxyInfo | null;
  reason: 'selected' | 'blacklist-match' | 'whitelist-no-match' | 'no-proxies-available';
}

Example

const proxy = manager.next('https://api.example.com/data');
if (proxy) {
  console.log(`Using ${proxy.protocol}://${proxy.host}:${proxy.port}`);
}

// With detailed reason
const result = manager.select('https://api.example.com/data');
if (result.proxy) {
  console.log('Selected proxy:', result.proxy.host);
} else {
  console.log('No proxy because:', result.reason);
}

Pool Management

add(proxies)

Adds one or more proxies to the pool. Accepts ProxyInfo objects or URL strings.

add(proxies: string | ProxyInfo | (string | ProxyInfo)[]): void

remove(proxies)

Removes one or more proxies from the pool.

remove(proxies: ProxyInfo | ProxyInfo[]): void

removeById(id)

Removes a proxy by its unique ID.

removeById(id: string): void

reset()

Re-enables all proxies and resets all counters. Proxies remain in the pool.

reset(): void

clear()

Removes all proxies and resets the pool entirely. The manager remains usable after clear().

clear(): void

Example

// Add proxies
manager.add('http://new-proxy:8080');
manager.add([
  { protocol: 'socks5', host: '10.0.0.1', port: 1080 },
  'http://10.0.0.2:3128'
]);

// Remove a proxy
const active = manager.getActive();
manager.remove(active[0]);

// Reset all (re-enable disabled, clear counters)
manager.reset();

// Clear everything
manager.clear();

Pool Statistics

size

Total number of proxies in the pool (active + disabled + cooldown).

get size: number

totalRequests

Total requests routed through the manager.

get totalRequests: number

totalSuccesses

Total successful requests.

get totalSuccesses: number

totalFailures

Total failed requests.

get totalFailures: number

Proxy State

getProxyState(proxy)

Returns the internal state for a specific proxy.

getProxyState(proxy: ProxyInfo): ProxyState | undefined

ProxyState includes:

PropertyTypeDescription
proxyProxyInfoThe proxy info.
requestCountnumberTotal requests through this proxy.
failureCountnumberConsecutive failures.
successCountnumberTotal successes.
totalFailuresnumberLifetime failures.
isActivebooleanWhether the proxy is active.
disabledReasonstringReason for disabling ('dead', 'limit-reached', 'manual').
reenableAtnumberTimestamp when cooldown expires.
lastSuccessAtnumberTimestamp of last success.
lastFailureAtnumberTimestamp of last failure.
lastErrorstringLast error message.

has(proxy)

Checks if a proxy exists in the pool (any state).

has(proxy: ProxyInfo): boolean

hasAvailableProxies()

Checks if any proxies are active and ready to use.

hasAvailableProxies(): boolean

Cooldown

isCoolingDown()

Returns true if any proxy is in cooldown (will auto-re-enable).

isCoolingDown(): boolean

nextCooldownMs()

Returns milliseconds until the next proxy exits cooldown. Returns 0 if a proxy is already available, -1 if none are recovering.

nextCooldownMs(): number

waitForProxy()

Returns a promise that resolves with the first proxy to become available. Resolves immediately if a proxy is already active. Rejects if no proxies are in cooldown.

waitForProxy(): Promise<ProxyInfo>

Example

const proxy = manager.next(url);
if (!proxy) {
  if (manager.isCoolingDown()) {
    console.log(`Next proxy in ${manager.nextCooldownMs()}ms`);
    const recovered = await manager.waitForProxy();
    console.log('Recovered:', recovered.host);
  } else {
    console.log('Pool is permanently exhausted');
  }
}

Lifecycle

destroy()

Destroys the manager, clears all cooldown timers, and rejects pending waitForProxy() callers.

destroy(): void

notifyNoProxiesAvailable(url, error)

Triggers the onNoProxiesAvailable hook with detailed pool state information.

notifyNoProxiesAvailable(url: string, error: Error): OnNoProxiesAvailableContext

Hooks

The hooks property provides event hooks for the proxy lifecycle.

manager.hooks: ProxyHooks

Available Hooks

HookSignatureDescription
beforeProxySelect(ctx) => ProxyInfo \| voidOverride proxy selection. Return a ProxyInfo to use it.
afterProxySelect(ctx) => voidNotified after proxy selection.
beforeProxyError(ctx) => voidBefore recording a proxy failure.
afterProxyError(ctx) => voidAfter recording a proxy failure.
beforeProxyDisable(ctx) => boolean \| voidReturn false to prevent disabling.
afterProxyDisable(ctx) => voidAfter a proxy is disabled.
afterProxyRotate(ctx) => voidWhen selection rotates to a new proxy.
afterProxyEnable(ctx) => voidAfter a proxy is re-enabled.
afterProxySuccess(ctx) => voidAfter a successful request through a proxy.
onNoProxiesAvailable(ctx) => voidWhen no proxies are available.

Example

manager.hooks.afterProxyDisable.push((ctx) => {
  console.log(`Proxy ${ctx.proxy.host} disabled: ${ctx.reason}`);
  if (ctx.hasCooldown) {
    console.log(`Will re-enable at ${new Date(ctx.reenableAt)}`);
  }
});

manager.hooks.onNoProxiesAvailable.push((ctx) => {
  console.error(`Pool exhausted for ${ctx.url}`);
  console.log(`Dead: ${ctx.disabledReasons.dead}, Cooldown: ${ctx.cooldownCount}`);
  alertSystem.notify('Proxy pool exhausted', ctx);
});