Skip to the content

Capsid menu

rate-limit/durable-object.mjs

27 lines and 2 functions in DrDustinEdwards/site-runtime, at commit 89e9d58 on 2026-10-24. This file on GitHub.

Functions

The functions of durable-object.mjs
FunctionLinesComplexityCoveredCRAPMutation
hit18 to 232No data: no coverage report in this mapNo data: no coverage report in this mapNo data: mutation testing has not run on this repo yet
alarm25 to 282No data: no coverage report in this mapNo data: no coverage report in this mapNo data: mutation testing has not run on this repo yet

Imports

It imports rate-limit/core.mjs. No module of this repo imports it.

Source

// A Workers built-in, not an npm package.
import { DurableObject } from "cloudflare:workers";
import { hitRules, idleDeadline, purgeExpired } from "./core.mjs";

/**
 * The Durable Object class a Worker exports and binds (SQLite-backed). One instance per key holds
 * every window for that key. After the longest window ends an alarm deletes its storage, so an idle
 * key's instance is released.
 *
 * A Worker that already has a Durable Object class it cannot rename can extend this one: the counting
 * lives in its own table, apart from anything the subclass stores.
 */
export class RateLimiter extends DurableObject {
  /**
   * @param {import("./core.mjs").Rule[]} rules
   * @param {number} [nowMs]
   */
  async hit(rules, nowMs = Date.now()) {
    // The count is one synchronous block (hitRules has no await); the alarm write follows it.
    const result = hitRules(this.ctx.storage.sql, rules, nowMs);
    if (result.ok) await this.ctx.storage.setAlarm(idleDeadline(rules, nowMs));
    return result;
  }

  async alarm() {
    const remaining = purgeExpired(this.ctx.storage.sql, Date.now());
    if (remaining !== null) await this.ctx.storage.setAlarm(remaining);
  }
}