Skip to content

Releases

Plain versions published to npm, newest first. Release notes come from the package changelog; development versions stay on the changelog.

v0.5.1latest· beta
  1. v0.5.1

    v0.5.1latest· beta

    Patch Changes

    • maxWait: 0 jobs queued behind an in-flight store call now wait for the valve to send another batch instead of being rejected right away. Previously, with redisStore or another asynchronous store, only the first batch reached the store and every other zero-wait job was rejected with MAX_WAIT_EXCEEDED without an attempt. Zero-wait jobs still reject with MAX_WAIT_EXCEEDED when the store denies them. They reject without an attempt when the valve sends no further batch (after a rate denial, a pause, or a store outage, or with local concurrency full) or when newer higher-priority work keeps them out of every batch.
  2. v0.5.0

    v0.5.0published· beta

    Minor Changes

    • memoryStore() now rejects valves that share an id with different rate rules, global concurrency limit, or lease TTL with INVALID_OPTIONS, as the Redis store does. Mismatched configurations that previously ran with mixed limits now fail. The memory store also forgets an id's static policy once its rate, lease, and pause state expire, so short-lived ids no longer grow memory without bound. ScopedAcquireResult gains an optional pausedMs field. Scoped valves now update stats().pausedUntil and emit pause when the store reports a shared pause, including Redis stores without a subscriber. A direct acquire that asks for more jobs than free lease slots on an empty slot set now returns the lease TTL as its retry hint. The Redis script previously failed with a Lua error, and the memory store returned Infinity.
    • Waiting global valves call the store far less often. AcquireResult and scoped blocked entries gain an optional leaseBlocked field, which the memory and Redis stores set on lease requests, so a valve waits out rate denials for the full retry hint instead of polling every 50ms. Lease waits poll every 50ms only without a subscriber, and at least once a second with one. Release notices are coalesced and answered after a short random delay that widens for valves that keep losing slots, so one release no longer sends every waiting valve to the store at once. A valve no longer polls right after its own job settles, before its lease is released. Aborts and maxWait expiries no longer cut short the store outage backoff under onStoreError: 'wait'.

    Patch Changes

    • ietfRateLimit() and defaultFeedback now split RateLimit fields in linear time and ignore fields longer than 8192 characters, so a malformed header can no longer stall the event loop. Quoted strings may contain escaped quotes and commas. Valves also register their disposer under Symbol.for('nodejs.asyncDispose') on Node 20 releases that lack Symbol.asyncDispose, so await using works across the supported Node 20 range.
    • maxWait: 0 now runs a job when its first admission attempt is granted and rejects it with MAX_WAIT_EXCEEDED otherwise. Previously every such job was rejected, even with free capacity. redisStore now rejects a timeout below 1ms with INVALID_OPTIONS, since a zero timeout failed every store call.
  3. v0.4.1

    v0.4.1published· beta

    Patch Changes

    • With global concurrency, close() now waits up to leaseTtl for an in-flight store admission and releases any leases it grants, so a shutdown no longer strands slots until their TTL. close({ drain: true }) lets accepted wrapFetch requests finish their retries. When a retry cannot be queued, because the valve closed without draining or maxQueue is full, wrapFetch returns the rate limit response unread instead of rejecting. Errors from wrapFetch cost, priority, and scopes resolvers now count as rejections and emit reject.
    • Keep equal-priority jobs in call order when the store denies part of a batch, and keep wrapFetch retries at their original queue position. Denied jobs and retries were previously appended behind later submissions.
  4. v0.4.0

    v0.4.0published· beta

    Minor Changes

    • Introduce atomic scoped rate limits, the headline feature of the 0.4 series. Requests spend shared and per-identity budgets together. Named rules select recipient, tenant, or resource counters through per-job scopes; memory and Redis/Valkey stores spend every applicable budget or none. Blocked identities wait while other eligible jobs proceed, with priority, weighted costs, cancellation, deadlines, and global concurrency leases. Fetch wrappers accept fixed identities or a synchronous resolver. Identities are copied once per logical request and reused across retries; every attempt reacquires all budgets. Missing required identities name the missing dimension and reject before queueing. Inactive Redis scope keys expire automatically. Scoped policies support up to 16 rules and 128 jobs per admission, with a default batch of 32. All keys for one Valve ID share a Redis Cluster slot. Custom stores must implement acquireScoped. Rule and scope changes require a coordinated configuration-fingerprint migration; limits cannot vary dynamically per identity. Provider feedback and pauses still affect the whole Valve ID. Admission does not guarantee provider delivery, and exact rolling windows remain unsupported. Include mixed-algorithm and multi-dimension examples, a Bottleneck chaining comparison, beta migration guidance, correctness tests across memory and Redis/Valkey, and reproducible benchmarks. Larger rule/batch combinations can increase Redis script latency and bundle size; see the scoped benchmark report for measurements and tuning guidance.

    Patch Changes

    • Publish plain version numbers through npm's default channel, starting with 0.4.0. Install with npm install valvejs; Valve remains beta until 1.0, as stated in the READMEs and website. Remove prerelease mode and custom beta-channel publishing from release automation, and keep historical prerelease versions in the full package changelog. Website changelog and release lists show only plain-numbered versions. Update installation, contribution, release, and migration guidance to match.
    • Remove hardcoded release numbers and planned-release wording from the repository and npm READMEs. Use an automatically updated npm badge and links to release history so installation guidance stays accurate across releases.