Store API

Stores manage rate limit data persistence. All stores implement the Store interface.

Store Interface

interface Store {
  get(key: string): Promise<RateLimitInfo | null>
  increment(key: string, windowMs: number): Promise<RateLimitInfo>
  reset(key: string): Promise<void>
  close?(): Promise<void>
}

Methods

get(key)

Retrieves current rate limit info for a key.

const info = await store.get('user:123')
// Returns: { count: 42, resetTime: 1640000060000 } or null

increment(key, windowMs)

Increments the request count and returns updated info.

const info = await store.increment('user:123', 60000)
// Returns: { count: 43, resetTime: 1640000060000 }

reset(key)

Resets the rate limit for a specific key.

await store.reset('user:123')

close()

Optional cleanup method for closing connections.

await store.close()

Built-in Stores

memoryStore()

In-memory storage, suitable for single-instance deployments.

import { memoryStore } from '@joint-ops/hitlimit'

const store = memoryStore({
  cleanupInterval: 60000  // Clean expired entries every 60s
})

sqliteStore()

Persistent SQLite storage for single-server deployments.

import { sqliteStore } from '@joint-ops/hitlimit/stores/sqlite'

const store = sqliteStore({
  path: './rate-limits.db',
  tableName: 'rate_limits'  // Optional
})

redisStore()

Redis storage for distributed deployments.

import { redisStore } from '@joint-ops/hitlimit/stores/redis'

const store = redisStore({
  url: 'redis://localhost:6379',
  prefix: 'rl:'  // Key prefix
})

Creating a Custom Store

import type { Store, RateLimitInfo } from '@joint-ops/hitlimit'

class MyStore implements Store {
  private data = new Map<string, RateLimitInfo>()

  async get(key: string) {
    return this.data.get(key) || null
  }

  async increment(key: string, windowMs: number) {
    const now = Date.now()
    const existing = this.data.get(key)

    if (existing && existing.resetTime > now) {
      existing.count++
      return existing
    }

    const info = { count: 1, resetTime: now + windowMs }
    this.data.set(key, info)
    return info
  }

  async reset(key: string) {
    this.data.delete(key)
  }
}