Skip to content

stevenleep/rate-limiter

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

3 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

@stevenleep/rate-limiter

npm version TypeScript License: MIT

A production-ready toolkit for rate limiting, task queuing, and resource management with zero dependencies.

Features

  • 🎯 Rate Limiter: Sliding window algorithm with configurable time windows
  • ⚑ Handler Queue: Priority-based concurrent task processing
  • πŸ”„ Resource Pool: Automatic lifecycle management for any resource type
  • πŸ”§ Iterator Support: Native iteration protocol for monitoring and inspection
  • πŸ“¦ Zero Dependencies: Lightweight with no external dependencies

Installation

npm install @stevenleep/rate-limiter

Quick Start

Rate Limiter

import { createRateLimiter, RateLimiterPresets } from '@stevenleep/rate-limiter';

const limiter = createRateLimiter(RateLimiterPresets.API_STANDARD);

if (limiter.isAllowed('user-123')) {
  console.log('βœ… Request approved');
} else {
  console.log('❌ Rate limit exceeded');
}

// Iterator support
for (const record of limiter) {
  console.log(`Active: ${record.key} at ${record.timestamp}`);
}

Handler Queue

import { createHandlerQueue, HandlerQueuePresets } from '@stevenleep/rate-limiter';

const queue = createHandlerQueue(HandlerQueuePresets.STANDARD);

const taskId = await queue.addTask({
  handler: async (data) => processData(data),
  priority: 10,
  data: { input: 'example' },
  timeout: 30000
});

// Monitor tasks
for (const task of queue) {
  console.log(`Task ${task.id}: ${task.status}`);
}

Resource Pool

import { createResourcePool } from '@stevenleep/rate-limiter';

const dbPool = createResourcePool({
  name: 'database-connections',
  minSize: 5,
  maxSize: 20,
  factory: async () => createConnection(),
  validator: async (conn) => conn.ping(),
  destroyer: async (conn) => conn.close()
});

const connection = await dbPool.acquire();
try {
  const result = await connection.query('SELECT * FROM users');
} finally {
  dbPool.release(connection);
}

API Reference

RateLimiter

interface RateLimiter<TKey = string> extends Iterable<RequestRecord<TKey>> {
  isAllowed(key: TKey): boolean;
  cleanup(): number;
  updateConfig(config: Partial<RateLimiterConfig<TKey>>): void;
  reset(): void;
  getRequestCount(key: TKey): number;
}

Presets: API_STANDARD, API_BURST, BASIC_WEB, CONSERVATIVE, HIGH_FREQUENCY

HandlerQueue<TData, TResult>

interface HandlerQueue<TData, TResult> extends Iterable<HandlerTask<TData, TResult>> {
  addTask(config: TaskConfig<TData, TResult>): Promise<string>;
  getTask(taskId: string): HandlerTask<TData, TResult> | undefined;
  cancelTask(taskId: string): boolean;
  pause(): void;
  resume(): void;
}

Presets: STANDARD, HIGH_CONCURRENCY, LIGHT_PROCESSING, HEAVY_PROCESSING

ResourcePool

interface ResourcePool<TResource> extends Iterable<ResourceStatus<TResource>> {
  acquire(): Promise<TResource>;
  release(resource: TResource): void;
  destroy(resource: TResource): Promise<void>;
  resize(newSize: number): Promise<void>;
  getTotalResources(): number;
  getAvailableCount(): number;
}

Advanced Examples

API Gateway

import { createRateLimiter, createHandlerQueue, createResourcePool } from '@stevenleep/rate-limiter';

class ApiGateway {
  private limiter = createRateLimiter(RateLimiterPresets.API_STANDARD);
  private queue = createHandlerQueue(HandlerQueuePresets.HIGH_CONCURRENCY);
  private dbPool = createResourcePool({
    name: 'database-pool',
    minSize: 5,
    maxSize: 20,
    factory: async () => createDbConnection(),
    validator: async (conn) => conn.ping(),
    destroyer: async (conn) => conn.close()
  });

  async handleRequest(userId: string, data: any) {
    if (!this.limiter.isAllowed(userId)) {
      throw new Error('Rate limit exceeded');
    }

    return await this.queue.addTask({
      handler: async () => {
        const db = await this.dbPool.acquire();
        try {
          return await db.processRequest(data);
        } finally {
          this.dbPool.release(db);
        }
      },
      priority: 5,
      data
    });
  }

  getSystemHealth() {
    return {
      activeRequests: [...this.limiter].length,
      queuedTasks: [...this.queue].filter(t => t.status === 'pending').length,
      availableConnections: this.dbPool.getAvailableCount()
    };
  }
}

License

MIT License - see the LICENSE file for details.

Links

About

A production-ready toolkit for rate limiting, task queuing, and resource management with zero dependencies.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published