diff --git a/CHANGELOG.md b/CHANGELOG.md index 1f016b8..9407949 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,10 @@ # Changelog -## Unreleased +## [4.0.0] - 2026-09-08 + +This is a major release because input validation and asynchronous request ordering +change observable behavior. See [Upgrading from 3.x](README.md#upgrading-from-3x) +before upgrading. ### Fixed - Reserve interval allowance before asynchronous calls yield; recheck it after waiting. @@ -14,6 +18,11 @@ - Async requests on one instance now run FIFO; synchronous requests can still consume capacity first. - Fractional millisecond clock precision is retained, so remaining balances may differ slightly from earlier versions. +### Maintenance +- Refresh development dependencies within their existing declared ranges; no runtime dependencies are added. +- Build both module distributions in CI and include this changelog in the npm package. +- Exclude test files and TypeScript build caches from the published package. + ## [3.0.0] - 2025-01-24 ### Added - **Dual Module Support:** Distributed as both CommonJS and ES Module, with separate `package.json` files for each format (no need for custom transformers). This improves compatibility with modern bundlers and frameworks. diff --git a/README.md b/README.md index aa8cf75..6f9c9f6 100644 --- a/README.md +++ b/README.md @@ -15,6 +15,36 @@ that can be removed each interval to comply with common API restrictions such as yarn add limiter +## Upgrading from 3.x + +Version 4 fixes concurrent accounting and waiting behavior. It keeps the existing +constructors, methods, CommonJS/ESM imports, and fractional-token support, but is +a major release because these observable behaviors change: + +- Token counts and capacities must be finite, non-negative numbers no greater + than `Number.MAX_SAFE_INTEGER`. Numeric intervals must be finite and positive. + Invalid values now throw `RangeError`, or reject an asynchronous call. Validate + configuration and handle rejected `removeTokens()` promises; do not use + negative values, `NaN`, or `Infinity` as sentinels. +- Waiting `removeTokens()` calls on the same instance run in FIFO order. A large + request at the front can delay smaller requests behind it. Synchronous calls + and `fireImmediately` requests can still consume capacity ahead of the queue; + children sharing a parent do not have a global FIFO order. +- Concurrent requests now respect the interval allowance and charge a hierarchy + only once per successful removal. Workloads that previously exceeded their + configured limits may wait longer or receive an immediate rejection signal. +- Remaining balances retain fractional millisecond timing precision. Avoid exact + equality checks on fractional balances; use `tryRemoveTokens()` to check + whether a request can proceed immediately. + +Zero-value conventions are unchanged: a standalone `TokenBucket` with +`bucketSize: 0` is unlimited and bypasses parents; `tokensPerInterval: 0` refills +a finite bucket on every attempt. A `RateLimiter` with `tokensPerInterval: 0` +accepts only zero-token requests. These settings are not a general off switch. + +See the [changelog](CHANGELOG.md) for the release history and +[Additional Notes](#additional-notes) for the full timing and queue semantics. + ## Usage A simple example allowing 150 requests per hour: diff --git a/package.json b/package.json index 0d6b118..3fad96b 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "limiter", "description": "A generic rate limiter for the web and node.js. Useful for API clients, web crawling, or other tasks that need to be throttled", - "version": "3.0.0", + "version": "4.0.0", "author": "John Hurliman ", "main": "./dist/cjs/index.js", "module": "./dist/esm/index.js", @@ -17,7 +17,10 @@ "license": "MIT", "files": [ "dist", - "src" + "src", + "CHANGELOG.md", + "!**/*.test.*", + "!**/*.tsbuildinfo" ], "jest": { "moduleNameMapper": {