@lymit/core
v0.1.0
Published
Pure rate-limit algorithms (fixed window, sliding window, token bucket), config resolution and a block cache. Zero dependencies, zero I/O. The algorithms inside @lymit/sdk and the Lymit edge.
Maintainers
Readme
@lymit/core
Pure rate-limit algorithms and shared types. Design: docs/architecture/algorithms.md. Zero runtime dependencies, zero I/O — no clocks, no network, no storage. Every function takes now as an argument, which is what makes the algorithms testable at 0 ms and lets the same code run in the Edge API, the SDK, and any future storage backend.
Algorithms
All three share one shape:
algorithm(state | null, resolvedConfig, now, cost = 1) → { state, response }stateis the next state to persist (input is never mutated;nullmeans "no record yet").responseis aLimitResponse { success, limit, remaining, reset, retryAfter? }.costis a non-negative integer;0peeks without consuming. Rejections never consume.
| Algorithm | State | Notes |
| --------------- | ---------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------- |
| fixedWindow | { windowStart, count } | Epoch-aligned windows, so every node agrees on boundaries with no coordination. |
| slidingWindow | { windowStart, currentCount, previousCount } | Weighted two-window approximation; O(1) state. retryAfter is solved exactly. |
| tokenBucket | { tokens, lastRefill } | Lazy continuous refill; all-or-nothing deduction. reset = time until full (success) or until cost is affordable (rejection). |
All three honour a stored state that is ahead of the local clock rather than resetting it, so a fast-clocked node can never hand out a fresh allowance.
Helpers
resolveConfig(config)— validates a userLimitConfigand converts durations ("30s","1h","1d", or ms) to aResolvedLimitConfig. ThrowsLymitConfigErrornaming the bad field.BlockCache— bounded LRU cache of known-blocked keys. Stores only retryable rejections, so a stale entry can cost a round trip but never leak capacity.toHeaders(response)—X-RateLimit-Limit/Remaining/ResetandRetry-After(whole seconds, never0).keyFor(workspaceId, namespace, identifier)— injective storage/cache key using the ASCII unit separator, which no part may contain.
