### Minimal RateLimiter Configuration Source: https://github.com/jhurliman/node-rate-limiter/blob/main/_autodocs/types.md Example demonstrating the minimal required configuration for the RateLimiter constructor. ```typescript import { RateLimiter } from "limiter"; const limiter = new RateLimiter({ tokensPerInterval: 150, interval: "hour" }); ``` -------------------------------- ### TypeScript RateLimiter with Type Annotations Source: https://github.com/jhurliman/node-rate-limiter/blob/main/_autodocs/EXPORT_MANIFEST.md This example demonstrates using TypeScript with explicit type annotations for RateLimiter configuration and instances. Ensure 'limiter' is installed and types are available. ```typescript import { RateLimiter, RateLimiterOpts, Interval } from "limiter"; const config: RateLimiterOpts = { tokensPerInterval: 150, interval: "hour" }; const limiter: RateLimiter = new RateLimiter(config); ``` -------------------------------- ### Initialize RateLimiter with Fire Immediately Mode Source: https://github.com/jhurliman/node-rate-limiter/blob/main/_autodocs/api-reference/RateLimiter.md Enable 'fire immediately' mode to get an immediate response when rate limits are hit, indicated by a return value of -1. This is useful for HTTP handlers to quickly return a 429 status. Ensure the 'limiter' package is installed. ```typescript import { RateLimiter } from "limiter"; const limiter = new RateLimiter({ tokensPerInterval: 150, interval: "hour", fireImmediately: true }); async function requestHandler(request, response) { const remainingRequests = await limiter.removeTokens(1); if (remainingRequests < 0) { response.writeHead(429, { 'Content-Type': 'text/plain' }); response.end('429 Too Many Requests'); } else { // Process the request } } ``` -------------------------------- ### Initialize RateLimiter with tokensPerInterval and interval Source: https://github.com/jhurliman/node-rate-limiter/blob/main/_autodocs/configuration.md Configure the maximum number of tokens and the time interval for rate limiting. This example sets 150 requests per hour. ```typescript import { RateLimiter } from "limiter"; // Allow 150 requests per hour const limiter = new RateLimiter({ tokensPerInterval: 150, interval: "hour" }); ``` -------------------------------- ### Instantiate RateLimiter with Millisecond Interval Source: https://github.com/jhurliman/node-rate-limiter/blob/main/_autodocs/types.md Example of creating a RateLimiter instance using milliseconds for the interval. ```typescript // Using milliseconds const millisecondLimiter = new RateLimiter({ tokensPerInterval: 1, interval: 250 }); ``` -------------------------------- ### Instantiate RateLimiter with Interval Shorthand Source: https://github.com/jhurliman/node-rate-limiter/blob/main/_autodocs/types.md Example of creating a RateLimiter instance using a string shorthand for the interval. ```typescript import { RateLimiter } from "limiter"; // Using string shorthand const hourlyLimiter = new RateLimiter({ tokensPerInterval: 150, interval: "hour" }); ``` -------------------------------- ### Three-Tier Token Bucket Hierarchy Example Source: https://github.com/jhurliman/node-rate-limiter/blob/main/_autodocs/IMPLEMENTATION_NOTES.md Demonstrates setting up a hierarchical token bucket system with three tiers (system, department, user) and shows how to initiate a token removal that respects the constraints of all parent buckets. ```typescript // System level: 10MB/sec const tier1 = new TokenBucket({ bucketSize: 50 * 1024 * 1024, tokensPerInterval: 10 * 1024 * 1024, interval: "second" }); // Department level: 5MB/sec const tier2 = new TokenBucket({ bucketSize: 25 * 1024 * 1024, tokensPerInterval: 5 * 1024 * 1024, interval: "second", parentBucket: tier1 }); // User level: 1MB/sec const tier3 = new TokenBucket({ bucketSize: 5 * 1024 * 1024, tokensPerInterval: 1024 * 1024, interval: "second", parentBucket: tier2 }); // Removal waits for: tier3 AND tier2 AND tier1 await tier3.removeTokens(5000); ``` -------------------------------- ### Manual drip in a monitoring loop example Source: https://github.com/jhurliman/node-rate-limiter/blob/main/_autodocs/api-reference/TokenBucket.md Shows how to use `setInterval` to periodically call `drip()` and log the current token availability. This is useful for observing bucket behavior or implementing custom refill logic. ```typescript import { TokenBucket } from "limiter"; const bucket = new TokenBucket({ bucketSize: 100, tokensPerInterval: 10, interval: "second" }); setInterval(() => { const dripOccurred = bucket.drip(); console.log(`Tokens now available: ${Math.floor(bucket.content)}`); }, 100); ``` -------------------------------- ### Non-blocking token check example Source: https://github.com/jhurliman/node-rate-limiter/blob/main/_autodocs/api-reference/TokenBucket.md Demonstrates how to use `tryRemoveTokens` to conditionally proceed with an operation based on token availability. Ensure the `limiter` package is imported. ```typescript import { TokenBucket } from "limiter"; const bucket = new TokenBucket({ bucketSize: 100, tokensPerInterval: 10, interval: "second" }); if (bucket.tryRemoveTokens(50)) { console.log('Operation proceeding'); } else { console.log('Insufficient tokens, operation rejected'); } ``` -------------------------------- ### Initialize RateLimiter with Millisecond Interval Source: https://github.com/jhurliman/node-rate-limiter/blob/main/_autodocs/api-reference/RateLimiter.md Configure the limiter for a specific millisecond interval, such as allowing 1 request every 250 milliseconds. Ensure the 'limiter' package is installed. ```typescript import { RateLimiter } from "limiter"; // Allow 1 request every 250 milliseconds const limiter = new RateLimiter({ tokensPerInterval: 1, interval: 250 }); ``` -------------------------------- ### TokenBucket Waiting Behavior Example Source: https://github.com/jhurliman/node-rate-limiter/blob/main/_autodocs/api-reference/TokenBucket.md Illustrates how removeTokens handles waiting for token refills. This example shows a scenario where a request for tokens might exceed the current available amount, causing the method to pause until tokens are replenished. ```typescript import { TokenBucket } from "limiter"; const bucket = new TokenBucket({ bucketSize: 100, tokensPerInterval: 10, interval: "second" }); async function processLargeRequest() { // This will wait approximately 1 second for tokens to refill const remaining = await bucket.removeTokens(50); console.log(`Remaining tokens: ${remaining}`); } ``` -------------------------------- ### Import RateLimiter and TokenBucket (CommonJS) Source: https://github.com/jhurliman/node-rate-limiter/blob/main/_autodocs/INDEX.md Use this import statement when working with CommonJS module systems. Ensure the 'limiter' package is installed. ```javascript const { RateLimiter, TokenBucket } = require("limiter"); ``` -------------------------------- ### API Rate Limiting Configuration (150/hour) Source: https://github.com/jhurliman/node-rate-limiter/blob/main/_autodocs/DOCUMENTATION_MANIFEST.txt Example of configuring rate limiting for an API, allowing 150 requests per hour. ```javascript const apiLimiter = new RateLimiter({ tokensPerInterval: 150, interval: "hour" }); ``` -------------------------------- ### Error Handling Example Source: https://github.com/jhurliman/node-rate-limiter/blob/main/_autodocs/README.md Catch and handle errors thrown by the limiter, such as exceeding limits or invalid configurations. ```typescript try { const remaining = await limiter.removeTokens(1000); } catch (error) { if (error.message.includes("exceeds")) { // Request too large } else if (error.message.includes("Invalid interval")) { // Configuration error } } ``` -------------------------------- ### Configure RateLimiter with Numeric Interval (Milliseconds) Source: https://github.com/jhurliman/node-rate-limiter/blob/main/_autodocs/configuration.md Set the rate limiting interval using a numeric millisecond value. This example sets 10 tokens per second. ```typescript import { RateLimiter } from "limiter"; // Numeric milliseconds (1 second) const perSecond = new RateLimiter({ tokensPerInterval: 10, interval: 1000 }); ``` -------------------------------- ### Throttled Data Transmission Example Source: https://github.com/jhurliman/node-rate-limiter/blob/main/_autodocs/api-reference/TokenBucket.md Demonstrates using TokenBucket to limit data transmission rates. It configures a bucket with a burst rate and a sustained fill rate, then uses removeTokens to ensure data does not exceed these limits. ```typescript import { TokenBucket } from "limiter"; const BURST_RATE = 1024 * 1024 * 150; // 150MB burst const FILL_RATE = 1024 * 1024 * 50; // 50MB/sec sustained const bucket = new TokenBucket({ bucketSize: BURST_RATE, tokensPerInterval: FILL_RATE, interval: "second" }); async function sendData(data) { await bucket.removeTokens(data.byteLength); console.log(`Sent ${data.byteLength} bytes`); } ``` -------------------------------- ### Configure RateLimiter with Custom Numeric Interval Source: https://github.com/jhurliman/node-rate-limiter/blob/main/_autodocs/configuration.md Set a custom rate limiting interval using milliseconds. This example allows 1 token every 250 milliseconds. ```typescript import { RateLimiter } from "limiter"; // Custom interval: 250 milliseconds const custom = new RateLimiter({ tokensPerInterval: 1, interval: 250 }); ``` -------------------------------- ### RateLimiter Configuration with fireImmediately Enabled Source: https://github.com/jhurliman/node-rate-limiter/blob/main/_autodocs/types.md Example showing how to configure RateLimiter with `fireImmediately: true` for immediate rejection when rate-limited. When rate-limited, `removeTokens()` will return -1 without waiting. ```typescript import { RateLimiter } from "limiter"; const limiter = new RateLimiter({ tokensPerInterval: 150, interval: "hour", fireImmediately: true }); const remaining = await limiter.removeTokens(1); // When rate-limited, remaining will be -1 without waiting ``` -------------------------------- ### Request dispatch with fallback example Source: https://github.com/jhurliman/node-rate-limiter/blob/main/_autodocs/api-reference/TokenBucket.md Illustrates using `tryRemoveTokens` to manage request processing, falling back to queuing if tokens are insufficient. This pattern helps in rate-limiting incoming requests gracefully. ```typescript import { TokenBucket } from "limiter"; const bucket = new TokenBucket({ bucketSize: 1000, tokensPerInterval: 100, interval: "second" }); async function handleRequest(request) { const size = request.data.length; if (bucket.tryRemoveTokens(size)) { return await processRequest(request); } else { return await queueForLater(request); } } ``` -------------------------------- ### RateLimiter Initial State Source: https://github.com/jhurliman/node-rate-limiter/blob/main/_autodocs/IMPLEMENTATION_NOTES.md Initializes the RateLimiter with a full token bucket and the current interval start time. Allows immediate bursts up to the specified tokens per interval. ```typescript this.tokenBucket.content = tokensPerInterval; // Start bucket full this.curIntervalStart = getMilliseconds(); this.tokensThisInterval = 0; ``` -------------------------------- ### Handling Rate Limit Events with removeTokens Source: https://github.com/jhurliman/node-rate-limiter/blob/main/_autodocs/api-reference/RateLimiter.md Shows how to use removeTokens within a loop to process items while respecting rate limits. This example uses a second interval for replenishment. ```typescript import { RateLimiter } from "limiter"; const limiter = new RateLimiter({ tokensPerInterval: 10, interval: "second" }); async function processItems(items) { for (const item of items) { const remaining = await limiter.removeTokens(1); console.log(`Processing ${item}, ${remaining} requests left`); // process item... } } ``` -------------------------------- ### Bandwidth Throttling Source: https://github.com/jhurliman/node-rate-limiter/blob/main/_autodocs/configuration.md Configure bandwidth throttling using a TokenBucket to limit data transfer rates. This example sets a burst limit of 10MB and a sustained rate of 1MB per second. ```typescript import { TokenBucket } from "limiter"; // Burst: 10MB, sustained: 1MB/sec const bucket = new TokenBucket({ bucketSize: 1024 * 1024 * 10, tokensPerInterval: 1024 * 1024, interval: "second" }); async function sendData(data) { await bucket.removeTokens(data.byteLength); // Send data } ``` -------------------------------- ### Create a Token Bucket Source: https://github.com/jhurliman/node-rate-limiter/blob/main/_autodocs/README.md Set up a TokenBucket for bandwidth limiting, such as MB/sec. Use for byte-level throttling. ```typescript import { TokenBucket } from "limiter"; // Bandwidth limiting: 150MB burst, 50MB/sec sustained const bucket = new TokenBucket({ bucketSize: 1024 * 1024 * 150, tokensPerInterval: 1024 * 1024 * 50, interval: "second" }); // Use for byte-level throttling async function sendData(data) { await bucket.removeTokens(data.byteLength); // Send data } ``` -------------------------------- ### Simple Bandwidth Limiting Source: https://github.com/jhurliman/node-rate-limiter/blob/main/_autodocs/types.md Configure a TokenBucket for basic bandwidth limiting. Ensure the 'limiter' package is imported. ```typescript import { TokenBucket } from "limiter"; const bucket = new TokenBucket({ bucketSize: 1024 * 1024, tokensPerInterval: 1024 * 100, interval: "second" }); ``` -------------------------------- ### Importing RateLimiter and TokenBucket Source: https://github.com/jhurliman/node-rate-limiter/blob/main/_autodocs/INDEX.md Demonstrates the direct import method for RateLimiter and TokenBucket classes from the 'limiter' package. ```typescript import { RateLimiter, TokenBucket } from "limiter"; ``` -------------------------------- ### Import TokenBucket Class Source: https://github.com/jhurliman/node-rate-limiter/blob/main/_autodocs/EXPORT_MANIFEST.md Import the TokenBucket class for implementing the token bucket rate limiting algorithm. It supports hierarchical buckets. ```typescript import { TokenBucket } from "limiter"; ``` -------------------------------- ### Configuration Options Source: https://github.com/jhurliman/node-rate-limiter/blob/main/_autodocs/DOCUMENTATION_MANIFEST.txt Details on the various configuration options available for RateLimiter and TokenBucket, including string shorthands for intervals, millisecond values, burst capacity, and immediate rejection mode. ```APIDOC ## Configuration Options ### Description This section details the configuration options available for initializing `RateLimiter` and `TokenBucket` instances, allowing for flexible control over rate limiting behavior. ### Key Options - **`interval`** (string | number): Defines the time interval for rate limiting. Can be a string shorthand like "second", "minute", "hour", "day", or a numeric value representing milliseconds. - Example: `interval: "minute"` or `intervalMs: 60000` - **`max`** (number): The maximum number of tokens (requests) allowed within the specified `interval`. This is equivalent to `tokensPerInterval` in `TokenBucket`. - Example: `max: 100` - **`capacity`** (number): The maximum number of tokens the bucket can hold at any given time. This controls the burst capacity. - Example: `capacity: 200` - **`fireImmediately`** (boolean): If set to `true`, the rate limiter will reject requests immediately if the limit is exceeded, rather than waiting for tokens to become available. This is useful for HTTP handlers. - Example: `fireImmediately: true` - **`id`** (string): A unique identifier for the rate limiter instance. Useful for debugging or managing multiple limiters. - Example: `id: "api-endpoint-limiter"` - **`parent`** (TokenBucket): For hierarchical limiting, this option assigns a parent bucket to the current bucket. Limits from the parent are enforced on the child. - Example: `parent: parentLimiterInstance` ### Examples ```javascript // Configuration using string shorthands and max requests const limiter = new RateLimiter({ id: "api-requests", interval: "hour", max: 1000 }); // Configuration using millisecond intervals and burst capacity const bandwidthLimiter = new TokenBucket({ capacity: 1024 * 1024, // 1MB burst capacity intervalMs: 1000, // 1 second interval tokensPerInterval: 512 * 1024 // 0.5MB per second rate }); // HTTP handler with immediate rejection const httpLimiter = new RateLimiter({ id: "http-handler", interval: "minute", max: 60, fireImmediately: true }); ``` ``` -------------------------------- ### Get Milliseconds with High Resolution Source: https://github.com/jhurliman/node-rate-limiter/blob/main/_autodocs/IMPLEMENTATION_NOTES.md Returns whole milliseconds derived from high-resolution timers. Uses `performance.now()` for accuracy across environments. ```typescript export function getMilliseconds(): number { const [seconds, nanoseconds] = hrtime(); return seconds * 1e3 + Math.floor(nanoseconds / 1e6); } ``` -------------------------------- ### Basic Bandwidth Limiting with TokenBucket Source: https://github.com/jhurliman/node-rate-limiter/blob/main/_autodocs/api-reference/TokenBucket.md Instantiate a TokenBucket for basic bandwidth limiting. Configure burst capacity and sustained rate per second. ```typescript import { TokenBucket } from "limiter"; // Burst: 1MB, sustained: 100KB/sec const bucket = new TokenBucket({ bucketSize: 1024 * 1024, tokensPerInterval: 1024 * 100, interval: "second" }); ``` -------------------------------- ### TypeScript Type Safety and Configuration Source: https://github.com/jhurliman/node-rate-limiter/blob/main/_autodocs/README.md Demonstrates how to import and use TypeScript definitions for RateLimiter, including configuration options and making a token removal request. ```typescript import { RateLimiter, RateLimiterOpts, Interval } from "limiter"; const config: RateLimiterOpts = { tokensPerInterval: 150, interval: "hour" }; const limiter: RateLimiter = new RateLimiter(config); const remaining: number = await limiter.removeTokens(1); ``` -------------------------------- ### Basic RateLimiter Initialization (String Interval) Source: https://github.com/jhurliman/node-rate-limiter/blob/main/_autodocs/DOCUMENTATION_MANIFEST.txt Initialize a RateLimiter with a string representing the time interval. Supports 'second', 'minute', 'hour', 'day'. ```javascript const limiter = new RateLimiter({ interval: "second", tokensPerInterval: 15 }); ``` -------------------------------- ### TokenBucket Constructor Configuration Source: https://github.com/jhurliman/node-rate-limiter/blob/main/_autodocs/INDEX.md Use this constructor to create a TokenBucket instance. It requires the bucket size, tokens added per interval, and the interval duration. An optional parent bucket can be specified for hierarchical limits. ```typescript new TokenBucket({ bucketSize: number, // Required: max tokens in bucket (0 = infinite) tokensPerInterval: number, // Required: tokens added per interval interval: Interval, // Required: "second"|"minute"|"hour"|"day"|milliseconds parentBucket?: TokenBucket // Optional: parent bucket for hierarchical limits }) ``` -------------------------------- ### Standard TokenBucket Configuration Source: https://github.com/jhurliman/node-rate-limiter/blob/main/_autodocs/configuration.md Configures a TokenBucket with a 100KB burst capacity and a sustained rate of 10KB/sec. ```typescript import { TokenBucket } from "limiter"; // Standard: 100KB burst, 10KB/sec sustained const bucket1 = new TokenBucket({ bucketSize: 1024 * 100, tokensPerInterval: 1024 * 10, interval: "second" }); ``` -------------------------------- ### Get Remaining Tokens Source: https://github.com/jhurliman/node-rate-limiter/blob/main/README.md Retrieve the current number of remaining tokens using the `getTokensRemaining` method. This allows checking the rate limit status without attempting to remove tokens. ```javascript import { RateLimiter } from "limiter"; const limiter = new RateLimiter({ tokensPerInterval: 1, interval: 250 }); // Prints 1 since we did not remove a token and our number of tokens per // interval is 1 console.log(limiter.getTokensRemaining()); ``` -------------------------------- ### Bandwidth Limiting with TokenBucket Source: https://github.com/jhurliman/node-rate-limiter/blob/main/_autodocs/EXPORT_MANIFEST.md Configure bandwidth limiting using the TokenBucket class. Specify bucket size, tokens per interval, and the time interval for token replenishment. ```typescript import { TokenBucket } from "limiter"; const bucket = new TokenBucket({ bucketSize: 1024 * 1024, tokensPerInterval: 1024 * 512, interval: "second" }); ``` -------------------------------- ### Manually add tokens to the bucket Source: https://github.com/jhurliman/node-rate-limiter/blob/main/_autodocs/api-reference/TokenBucket.md The `drip()` method adds new tokens based on elapsed time. It can be called manually to update the bucket's token count, for example, in a monitoring loop. ```typescript drip(): boolean ``` -------------------------------- ### Multi-Tier Hierarchical Token Buckets (3-Level) Source: https://github.com/jhurliman/node-rate-limiter/blob/main/_autodocs/DOCUMENTATION_MANIFEST.txt Demonstrates a three-level hierarchy of TokenBuckets, where each level constrains the one below it, allowing for complex rate-shaping. ```javascript const rootBucket = new TokenBucket({ capacity: 1000, tokensPerInterval: 100, interval: "hour" }); const intermediateBucket = new TokenBucket({ capacity: 100, tokensPerInterval: 10, interval: "hour", parent: rootBucket }); const leafBucket = new TokenBucket({ capacity: 10, tokensPerInterval: 1, interval: "hour", parent: intermediateBucket }); ``` -------------------------------- ### Infinite Bucket Configuration Source: https://github.com/jhurliman/node-rate-limiter/blob/main/_autodocs/types.md Create a TokenBucket with an infinite capacity, useful when only the refill rate matters. The bucketSize is set to 0. ```typescript import { TokenBucket } from "limiter"; // Unlimited tokens, but only drips refill via tokensPerInterval const unlimited = new TokenBucket({ bucketSize: 0, tokensPerInterval: 100, interval: "second" }); ``` -------------------------------- ### TokenBucket Constructor Source: https://github.com/jhurliman/node-rate-limiter/blob/main/_autodocs/api-reference/TokenBucket.md Initializes a new TokenBucket instance. The bucket size defines the maximum capacity (burst rate), tokensPerInterval and interval define the sustained rate, and parentBucket can be used for hierarchical rate limiting. ```APIDOC ## Constructor TokenBucket ### Description Initializes a new TokenBucket instance with the specified options. ### Parameters #### options (`TokenBucketOpts`) - **bucketSize** (`number`) - Required - Maximum number of tokens to hold in the bucket (burst rate). If set to `0`, the bucket is infinite. - **tokensPerInterval** (`number`) - Required - Number of tokens to drip into the bucket per interval, controlling the sustained rate. - **interval** (`Interval`) - Required - The interval length in milliseconds or as a string ('second', 'sec', 'minute', 'min', 'hour', 'hr', 'day'). - **parentBucket** (`TokenBucket`) - Optional - A parent token bucket for hierarchical constraints. ### Throws - `Error` - If an invalid interval string is provided. ### Example: Basic bandwidth limiting ```typescript import { TokenBucket } from "limiter"; // Burst: 1MB, sustained: 100KB/sec const bucket = new TokenBucket({ bucketSize: 1024 * 1024, tokensPerInterval: 1024 * 100, interval: "second" }); ``` ### Example: Hierarchical buckets ```typescript import { TokenBucket } from "limiter"; // Parent bucket: 10MB/sec total const parentBucket = new TokenBucket({ bucketSize: 10 * 1024 * 1024, tokensPerInterval: 10 * 1024 * 1024, interval: "second" }); // Child bucket: 5MB/sec, constrained by parent const childBucket = new TokenBucket({ bucketSize: 5 * 1024 * 1024, tokensPerInterval: 5 * 1024 * 1024, interval: "second", parentBucket: parentBucket }); ``` ### Example: Infinite bucket ```typescript import { TokenBucket } from "limiter"; const infiniteBucket = new TokenBucket({ bucketSize: 0, // 0 means infinite capacity tokensPerInterval: 0, interval: "second" }); ``` ``` -------------------------------- ### RateLimiter Interval Reset Logic Source: https://github.com/jhurliman/node-rate-limiter/blob/main/_autodocs/IMPLEMENTATION_NOTES.md Resets the current interval start time and the count of tokens used in the interval. This logic handles both normal interval elapsing and system clock adjustments (time going backward). ```typescript if (now < this.curIntervalStart || now - this.curIntervalStart >= this.tokenBucket.interval) { this.curIntervalStart = now; this.tokensThisInterval = 0; } ``` -------------------------------- ### TokenBucketOpts Source: https://github.com/jhurliman/node-rate-limiter/blob/main/_autodocs/types.md Configuration options object for the TokenBucket constructor. It defines the parameters for setting up a token bucket for rate limiting. ```APIDOC ## TokenBucketOpts Configuration options object for the `TokenBucket` constructor. ### Field Reference | Field | Type | Required | Default | Description | |---|---|---|---|---| | `bucketSize` | `number` | Yes | — | Maximum tokens the bucket can hold. This is the burst capacity. Set to `0` for unlimited (infinite bucket). | | `tokensPerInterval` | `number` | Yes | — | Rate at which tokens refill per interval. Controls the sustained throughput rate. | | `interval` | `Interval` | Yes | — | Time window for token accumulation. Can be a number (milliseconds) or a string shorthand like `"hour"`, `"minute"`, or `"second"`. | | `parentBucket` | `TokenBucket` | No | `undefined` | Optional parent bucket that enforces an additional rate limit. Both this bucket and the parent must have available tokens for removal to succeed. Enables hierarchical rate limiting. | ### Usage Passed to the `TokenBucket` constructor. ### Example: Simple bandwidth limiting ```typescript import { TokenBucket } from "limiter"; const bucket = new TokenBucket({ bucketSize: 1024 * 1024, tokensPerInterval: 1024 * 100, interval: "second" }); ``` ### Example: Hierarchical buckets with parent constraint ```typescript import { TokenBucket } from "limiter"; // Global limit: 10MB/sec const globalBucket = new TokenBucket({ bucketSize: 10 * 1024 * 1024, tokensPerInterval: 10 * 1024 * 1024, interval: "second" }); // Per-user limit: 2MB/sec, constrained by global limit const userBucket = new TokenBucket({ bucketSize: 2 * 1024 * 1024, tokensPerInterval: 2 * 1024 * 1024, interval: "second", parentBucket: globalBucket }); ``` ### Example: Infinite bucket ```typescript import { TokenBucket } from "limiter"; // Unlimited tokens, but only drips refill via tokensPerInterval const unlimited = new TokenBucket({ bucketSize: 0, tokensPerInterval: 100, interval: "second" }); ``` ``` -------------------------------- ### Illustrate Concurrency Issue with removeTokens Source: https://github.com/jhurliman/node-rate-limiter/blob/main/_autodocs/IMPLEMENTATION_NOTES.md This example demonstrates a potential race condition when multiple concurrent calls to `removeTokens` are made. Both calls might read the initial token count and succeed, leading to a corrupted `tokensThisInterval` count. ```typescript const limiter = new RateLimiter({ tokensPerInterval: 10, interval: "second" }); // Two concurrent calls Promise.all([ limiter.removeTokens(7), limiter.removeTokens(7) ]); // Both see content = 10, both may succeed // tokensThisInterval tracking gets corrupted ``` -------------------------------- ### TokenBucket with Per-Second Interval Source: https://github.com/jhurliman/node-rate-limiter/blob/main/_autodocs/configuration.md Configures a TokenBucket to drip tokens at a rate of 50KB per second. ```typescript import { TokenBucket } from "limiter"; // Drip 50KB over the course of 1 second const perSecond = new TokenBucket({ bucketSize: 1024 * 1024, tokensPerInterval: 1024 * 50, interval: "second" }); ``` -------------------------------- ### Demonstrate Independent Waiting in Concurrent removeTokens Calls Source: https://github.com/jhurliman/node-rate-limiter/blob/main/_autodocs/IMPLEMENTATION_NOTES.md This example shows how multiple concurrent `removeTokens` calls that require waiting will each sleep independently for approximately the same duration. This can lead to race conditions on the token count after the wait, especially if `fireImmediately` is enabled. ```typescript // Three concurrent calls, all waiting await Promise.all([ limiter.removeTokens(5), // waits ~1000ms limiter.removeTokens(5), // waits ~1000ms limiter.removeTokens(5) // waits ~1000ms ]); // After waiting: // First returns with token count // Second-third may get negative count from RateLimiter // if fireImmediately is set ``` -------------------------------- ### TokenBucket Initial State Source: https://github.com/jhurliman/node-rate-limiter/blob/main/_autodocs/IMPLEMENTATION_NOTES.md Initializes the TokenBucket with an empty content and the last drip time. The bucket fills via token accumulation. ```typescript this.content = 0; // Bucket starts empty this.lastDrip = getMilliseconds(); ``` -------------------------------- ### Package.json Entry Points for Module Formats Source: https://github.com/jhurliman/node-rate-limiter/blob/main/_autodocs/EXPORT_MANIFEST.md This JSON configuration in package.json defines the main entry points for different module systems (CommonJS, ESM, browser). It ensures that the appropriate module format is loaded based on how the package is imported. ```json { "main": "./dist/cjs/index.js", "module": "./dist/esm/index.js", "browser": "./dist/esm/index.js", "exports": { "import": "./dist/esm/index.js", "require": "./dist/cjs/index.js" } } ``` -------------------------------- ### Hierarchical TokenBucket Configuration Source: https://github.com/jhurliman/node-rate-limiter/blob/main/_autodocs/configuration.md Sets up a global rate limit and a per-user rate limit, where the user limit is constrained by the global limit. ```typescript import { TokenBucket } from "limiter"; // Global limit: 1MB/sec total const globalBucket = new TokenBucket({ bucketSize: 1024 * 1024 * 10, tokensPerInterval: 1024 * 1024, interval: "second" }); // Per-user limit: 100KB/sec, constrained by global const userBucket = new TokenBucket({ bucketSize: 1024 * 100, tokensPerInterval: 1024 * 100, interval: "second", parentBucket: globalBucket }); // Usage: removing from userBucket respects both limits const remaining = await userBucket.removeTokens(5000); ``` -------------------------------- ### RateLimiter Constructor Source: https://github.com/jhurliman/node-rate-limiter/blob/main/_autodocs/api-reference/RateLimiter.md Initializes a new RateLimiter instance with specified options to control request throttling. ```APIDOC ## Constructor ```typescript constructor(options: RateLimiterOpts): RateLimiter ``` ### Parameters - **options** (`RateLimiterOpts`) - Required - Configuration object for the rate limiter. - **options.tokensPerInterval** (`number`) - Required - Maximum number of tokens that can be removed at any given moment and over the course of one interval. This represents the maximum request rate allowed per interval. - **options.interval** (`Interval`) - Required - The interval length as a number in milliseconds or as one of the following strings: `'second'`, `'sec'`, `'minute'`, `'min'`, `'hour'`, `'hr'`, `'day'`. - **options.fireImmediately** (`boolean`) - Optional - If `true`, the promise from `removeTokens()` will resolve immediately when rate limiting is in effect, with the remaining tokens set to `-1`. If `false` (default), the promise will wait until tokens are available. ### Throws - `Error` — If invalid interval string is provided (only happens if underlying TokenBucket receives invalid input). ### Example: Basic initialization ```typescript import { RateLimiter } from "limiter"; // Allow 150 requests per hour const limiter = new RateLimiter({ tokensPerInterval: 150, interval: "hour" }); ``` ### Example: Custom millisecond interval ```typescript import { RateLimiter } from "limiter"; // Allow 1 request every 250 milliseconds const limiter = new RateLimiter({ tokensPerInterval: 1, interval: 250 }); ``` ### Example: Fire immediately mode for HTTP handlers ```typescript import { RateLimiter } from "limiter"; const limiter = new RateLimiter({ tokensPerInterval: 150, interval: "hour", fireImmediately: true }); async function requestHandler(request, response) { const remainingRequests = await limiter.removeTokens(1); if (remainingRequests < 0) { response.writeHead(429, { 'Content-Type': 'text/plain' }); response.end('429 Too Many Requests'); } else { // Process the request } } ``` ``` -------------------------------- ### TokenBucket Configuration Interface Source: https://github.com/jhurliman/node-rate-limiter/blob/main/_autodocs/configuration.md Defines the structure for the configuration object used when instantiating a TokenBucket. ```typescript interface TokenBucketOpts { bucketSize: number; tokensPerInterval: number; interval: Interval; parentBucket?: TokenBucket; } ``` -------------------------------- ### Configure RateLimiter for Immediate Rejection Source: https://github.com/jhurliman/node-rate-limiter/blob/main/_autodocs/configuration.md Initialize a RateLimiter where `removeTokens` will immediately reject requests if the limit is reached by setting `fireImmediately` to `true`. ```typescript import { RateLimiter } from "limiter"; // Immediate rejection const rejectingLimiter = new RateLimiter({ tokensPerInterval: 10, interval: "second", fireImmediately: true }); async function handleRequest(request, response) { const remaining = await rejectingLimiter.removeTokens(1); if (remaining < 0) { response.status = 429; response.body = 'Too Many Requests'; } else { // Process request } } ``` -------------------------------- ### TokenBucket with Per-Hour Interval Source: https://github.com/jhurliman/node-rate-limiter/blob/main/_autodocs/configuration.md Configures a TokenBucket to drip 100 tokens over the course of one hour. ```typescript import { TokenBucket } from "limiter"; // Drip 100 tokens over 1 hour const perHour = new TokenBucket({ bucketSize: 1000, tokensPerInterval: 100, interval: "hour" }); ``` -------------------------------- ### Basic Usage of removeTokens Source: https://github.com/jhurliman/node-rate-limiter/blob/main/_autodocs/api-reference/RateLimiter.md Demonstrates how to initialize a RateLimiter and use the removeTokens method to consume tokens for a request. Ensure to import RateLimiter from 'limiter'. ```typescript import { RateLimiter } from "limiter"; const limiter = new RateLimiter({ tokensPerInterval: 150, interval: "hour" }); async function sendRequest() { const remainingTokens = await limiter.removeTokens(1); console.log(`Tokens remaining: ${remainingTokens}`); // send request... } ``` -------------------------------- ### Fire Immediately HTTP Handler Pattern Source: https://github.com/jhurliman/node-rate-limiter/blob/main/_autodocs/DOCUMENTATION_MANIFEST.txt Implement an HTTP handler that immediately rejects requests exceeding the rate limit. Useful for preventing unnecessary processing. ```javascript const limiter = new RateLimiter({ interval: "hour", tokensPerInterval: 150, fireImmediately: true }); app.use((req, res, next) => { if (!limiter.tryRemoveTokens(1)) { return res.status(429).send('Too Many Requests'); } next(); }); ``` -------------------------------- ### Exporting RateLimiter and TokenBucket from Index Source: https://github.com/jhurliman/node-rate-limiter/blob/main/_autodocs/INDEX.md This snippet shows how all classes and types are re-exported at the top level of the library's entry point. ```typescript export * from "./RateLimiter.js"; export * from "./TokenBucket.js"; ``` -------------------------------- ### Import RateLimiter Class Source: https://github.com/jhurliman/node-rate-limiter/blob/main/_autodocs/EXPORT_MANIFEST.md Import the RateLimiter class for use in your application. This class combines token bucket with per-interval enforcement. ```typescript import { RateLimiter } from "limiter"; ``` -------------------------------- ### TokenBucket Class Source: https://github.com/jhurliman/node-rate-limiter/blob/main/_autodocs/DOCUMENTATION_MANIFEST.txt Documentation for the TokenBucket class, which represents a single token bucket. It includes methods for token management and dripping. ```APIDOC ## TokenBucket Class ### Description Represents an individual token bucket used for rate limiting. It allows for adding, removing, and dripping tokens. ### Methods #### `removeTokens(count: number): Promise` Removes a specified number of tokens from the bucket. This is an asynchronous operation. - **count** (number) - Required - The number of tokens to remove. ### Response Example (Success) ```json // No explicit response body for success, operation completes. ``` #### `tryRemoveTokens(count: number): boolean` Attempts to remove a specified number of tokens synchronously. Returns `true` if successful, `false` otherwise. - **count** (number) - Required - The number of tokens to attempt to remove. ### Response Example (Success) ```json // Returns true if tokens were removed, false otherwise. ``` #### `drip(): void` Adds tokens to the bucket based on the configured rate, simulating the natural dripping of tokens over time. This is a synchronous operation. ### Response Example (Success) ```json // No explicit response body, operation completes. ``` ### Properties - **[Property Name]** (type) - Description of the property. ``` -------------------------------- ### CommonJS (Node.js) Import Pattern Source: https://github.com/jhurliman/node-rate-limiter/blob/main/_autodocs/EXPORT_MANIFEST.md This snippet shows how to import RateLimiter and TokenBucket using CommonJS syntax for Node.js environments. It's suitable for projects not using ES modules. ```javascript const { RateLimiter, TokenBucket } = require("limiter"); const limiter = new RateLimiter({ tokensPerInterval: 10, interval: "second" }); ``` -------------------------------- ### Configure RateLimiter to Wait for Tokens (Default) Source: https://github.com/jhurliman/node-rate-limiter/blob/main/_autodocs/configuration.md Initialize a RateLimiter where `removeTokens` will wait until tokens are available if the limit is reached. `fireImmediately` defaults to `false`. ```typescript import { RateLimiter } from "limiter"; // Default: wait for tokens const waitingLimiter = new RateLimiter({ tokensPerInterval: 10, interval: "second" // fireImmediately defaults to false }); ``` -------------------------------- ### Infinite Token Buckets Source: https://github.com/jhurliman/node-rate-limiter/blob/main/_autodocs/DOCUMENTATION_MANIFEST.txt Create a TokenBucket that never depletes by setting a very large capacity and/or tokensPerInterval, effectively disabling rate limiting. ```javascript const infiniteBucket = new TokenBucket({ capacity: Infinity, tokensPerInterval: Infinity, interval: "second" }); ``` -------------------------------- ### Configure RateLimiter with String Shorthand Intervals Source: https://github.com/jhurliman/node-rate-limiter/blob/main/_autodocs/configuration.md Set the rate limiting interval using string shorthands like 'hour'. ```typescript import { RateLimiter } from "limiter"; // String shorthand const hourly = new RateLimiter({ tokensPerInterval: 150, interval: "hour" }); ``` -------------------------------- ### Hierarchical Multi-Tenant Limiting Source: https://github.com/jhurliman/node-rate-limiter/blob/main/_autodocs/README.md Implement hierarchical rate limiting by setting a parentBucket on a TokenBucket. This allows for system-wide limits and per-user sub-limits. ```typescript import { TokenBucket } from "limiter"; const systemLimit = new TokenBucket({ bucketSize: 1024 * 1024 * 100, tokensPerInterval: 1024 * 1024 * 10, interval: "second" }); function createUserBucket(userId) { return new TokenBucket({ bucketSize: 1024 * 1024 * 10, tokensPerInterval: 1024 * 1024, interval: "second", parentBucket: systemLimit }); } ``` -------------------------------- ### TokenBucket Class Source: https://github.com/jhurliman/node-rate-limiter/blob/main/_autodocs/DOCUMENTATION_MANIFEST.txt The TokenBucket class implements the token bucket algorithm, allowing for bandwidth limiting and hierarchical rate limiting. It supports manual drip operations and various configurations for capacity and rate. ```APIDOC ## TokenBucket ### Description Implements the token bucket algorithm for rate limiting, supporting bandwidth control, burst capacity, and hierarchical relationships between buckets. ### Methods #### `new TokenBucket(options)` - **Description**: Initializes a new TokenBucket instance. - **Parameters**: - `options` (object) - Configuration options for the token bucket. Key options include: - `capacity` (number): The maximum number of tokens the bucket can hold. - `interval` (string | number): The interval at which tokens are added (e.g., 'second', 'minute', or milliseconds). - `tokensPerInterval` (number): The number of tokens added per interval. - `fireImmediately` (boolean): If true, tokens are immediately available upon creation. - `parent` (TokenBucket): An optional parent bucket for hierarchical limiting. #### `removeTokens(count = 1)` - **Description**: Attempts to remove a specified number of tokens from the bucket. This is a synchronous operation. - **Parameters**: - `count` (number) - The number of tokens to remove. Defaults to 1. - **Returns**: `boolean` - `true` if tokens were successfully removed, `false` otherwise. #### `getAvailableTokens()` - **Description**: Returns the current number of available tokens in the bucket. - **Returns**: `number` - The number of available tokens. #### `drip()` - **Description**: Manually adds tokens to the bucket based on the configured interval and rate. This is typically called internally by the rate limiter but can be used for custom scenarios. ### Examples ```javascript // Bandwidth limiting (bytes/sec) const bandwidthLimiter = new TokenBucket({ capacity: 1024 * 1024, // 1MB capacity interval: 'second', tokensPerInterval: 1024 * 1024, // 1MB per second }); // Infinite buckets (effectively no limit if capacity is very large and interval is long) const infiniteBucket = new TokenBucket({ capacity: Infinity, interval: 'day', tokensPerInterval: Infinity, }); // Hierarchical parent-child relationships const parentBucket = new TokenBucket({ capacity: 100, interval: 'minute', tokensPerInterval: 100 }); const childBucket = new TokenBucket({ capacity: 50, interval: 'minute', tokensPerInterval: 50, parent: parentBucket }); // Manual drip operations (less common for typical use) // parentBucket.drip(); ``` ``` -------------------------------- ### RateLimiter Constructor Configuration Source: https://github.com/jhurliman/node-rate-limiter/blob/main/_autodocs/INDEX.md Use this constructor to create a RateLimiter instance. It requires the maximum tokens per interval and the interval duration. An optional boolean can be set to fire immediately. ```typescript new RateLimiter({ tokensPerInterval: number, // Required: max tokens per interval interval: Interval, // Required: "second"|"minute"|"hour"|"day"|milliseconds fireImmediately?: boolean // Optional: default false }) ``` -------------------------------- ### Create a Rate Limiter Source: https://github.com/jhurliman/node-rate-limiter/blob/main/_autodocs/README.md Instantiate a RateLimiter to control request frequency. Remove tokens before proceeding with an action. ```typescript import { RateLimiter } from "limiter"; // Allow 150 requests per hour const limiter = new RateLimiter({ tokensPerInterval: 150, interval: "hour" }); // Remove tokens before making a request const remainingTokens = await limiter.removeTokens(1); if (remainingTokens >= 0) { // Safe to proceed } ``` -------------------------------- ### RateLimiter Class Source: https://github.com/jhurliman/node-rate-limiter/blob/main/_autodocs/DOCUMENTATION_MANIFEST.txt Documentation for the RateLimiter class, including its constructor, methods like removeTokens, tryRemoveTokens, and getTokensRemaining, and property details. ```APIDOC ## RateLimiter Class ### Description Provides the primary interface for rate limiting operations. It manages token buckets to control the rate at which actions can be performed. ### Methods #### `removeTokens(count: number): Promise` Removes a specified number of tokens from the rate limiter. This operation is asynchronous and may reject if tokens cannot be removed immediately. - **count** (number) - Required - The number of tokens to remove. ### Response Example (Success) ```json // No explicit response body for success, operation completes. ``` #### `tryRemoveTokens(count: number): boolean` Attempts to remove a specified number of tokens from the rate limiter synchronously. Returns `true` if successful, `false` otherwise. - **count** (number) - Required - The number of tokens to attempt to remove. ### Response Example (Success) ```json // Returns true if tokens were removed, false otherwise. ``` #### `getTokensRemaining(): number` Returns the current number of tokens remaining in the rate limiter. ### Response Example (Success) ```json // Returns the number of remaining tokens. ``` ### Properties - **[Property Name]** (type) - Description of the property. ``` -------------------------------- ### TokenBucket Waiting Behavior Source: https://github.com/jhurliman/node-rate-limiter/blob/main/_autodocs/DOCUMENTATION_MANIFEST.txt Illustrates how a TokenBucket can asynchronously wait for tokens to become available when `removeTokens` is called and capacity is insufficient. ```javascript const bucket = new TokenBucket({ capacity: 5, tokensPerInterval: 1, interval: "second" }); async function consumeTokens() { console.log('Attempting to consume tokens...'); // This will wait until tokens are available await bucket.removeTokens(10); console.log('Successfully consumed tokens!'); } consumeTokens(); ``` -------------------------------- ### Byte-Level Throttling with TokenBucket Source: https://github.com/jhurliman/node-rate-limiter/blob/main/README.md Utilize the TokenBucket class for byte-level rate limiting. Configure burst and sustained rates to manage data transfer throughput. ```javascript import { TokenBucket } from "limiter"; const BURST_RATE = 1024 * 1024 * 150; // 150KB/sec burst rate const FILL_RATE = 1024 * 1024 * 50; // 50KB/sec sustained rate // We could also pass a parent token bucket in to create a hierarchical token // bucket // bucketSize, tokensPerInterval, interval const bucket = new TokenBucket({ bucketSize: BURST_RATE, tokensPerInterval: FILL_RATE, interval: "second" }); async function handleData(myData) { await bucket.removeTokens(myData.byteLength); sendMyData(myData); } ``` -------------------------------- ### Bandwidth Throttling Source: https://github.com/jhurliman/node-rate-limiter/blob/main/_autodocs/INDEX.md Implement bandwidth throttling by using TokenBucket to control data transfer rates. This is useful for managing network I/O. ```typescript import { TokenBucket } from "limiter"; const bucket = new TokenBucket({ bucketSize: 1024 * 1024 * 150, tokensPerInterval: 1024 * 1024 * 50, interval: "second" }); async function sendData(data) { await bucket.removeTokens(data.byteLength); // Send data } ``` -------------------------------- ### Token Bucket Algorithm Formula Source: https://github.com/jhurliman/node-rate-limiter/blob/main/_autodocs/IMPLEMENTATION_NOTES.md This formula calculates the amount of tokens to add to the bucket based on elapsed time and configuration. The new content is capped by the bucket size. ```plaintext dripAmount = (milliseconds elapsed) × (tokensPerInterval / interval in milliseconds) newContent = min(content + dripAmount, bucketSize) ``` -------------------------------- ### Multiple Independent Rate Limiters Source: https://github.com/jhurliman/node-rate-limiter/blob/main/_autodocs/README.md Illustrates how to create and manage multiple independent RateLimiter instances for different purposes, such as API and database rate limiting. ```typescript const apiLimiter = new RateLimiter({ /* ... */ }); const dbLimiter = new RateLimiter({ /* ... */ }); await apiLimiter.removeTokens(1); // Check API limit await dbLimiter.removeTokens(1); // Check DB limit ``` -------------------------------- ### Custom Millisecond Intervals for RateLimiter Source: https://github.com/jhurliman/node-rate-limiter/blob/main/_autodocs/DOCUMENTATION_MANIFEST.txt Configure a RateLimiter using custom millisecond values for the interval, offering precise control over rate limits. ```javascript const limiter = new RateLimiter({ interval: 1000, // 1 second in milliseconds tokensPerInterval: 15 }); ``` -------------------------------- ### Manual Token Drip Operations Source: https://github.com/jhurliman/node-rate-limiter/blob/main/_autodocs/DOCUMENTATION_MANIFEST.txt Manually add tokens to a TokenBucket using the `drip()` method, useful for scenarios where tokens are replenished externally or on specific events. ```javascript const bucket = new TokenBucket({ capacity: 10, tokensPerInterval: 2, interval: "minute" }); console.log(`Initial tokens: ${bucket.getAvailableTokens()}`); // Manually add 5 tokens bucket.drip(5); console.log(`Tokens after manual drip: ${bucket.getAvailableTokens()}`); ```