Rebasely Beta: data may be purged

examples/MCP-tools Public

TypeScript · 48 lines · 1.8 KiB · at 2090b14

import assert from "node:assert/strict";import { test } from "node:test";import { LIMIT, msUntilFull, take, type Bucket } from "../src/rate-limiter/bucket.ts";const limit = { capacity: 3, refillPerSecond: 1 };function drain(n: number, now = 0): Bucket | undefined {  let bucket: Bucket | undefined;  for (let i = 0; i < n; i++) bucket = take(bucket, now, limit).bucket;  return bucket;}test("a new client starts with a full bucket", () => {  assert.deepEqual(take(undefined, 0, limit).decision, { ok: true, remaining: 2 });});test("an empty bucket refuses and says how long to wait", () => {  const { bucket, decision } = take(drain(3), 0, limit);  assert.deepEqual(decision, { ok: false, retryAfterSeconds: 1 });  assert.equal(bucket.tokens, 0, "a refused call costs nothing");});test("tokens come back over time, up to the capacity", () => {  const empty = drain(3);  assert.deepEqual(take(empty, 1000, limit).decision, { ok: true, remaining: 0 });  assert.deepEqual(take(empty, 60_000, limit).decision, { ok: true, remaining: 2 });});test("a partly refilled bucket rounds the wait up", () => {  const empty = drain(3);  const slow = { capacity: 3, refillPerSecond: 0.5 };  assert.deepEqual(take(empty, 500, slow).decision, { ok: false, retryAfterSeconds: 2 });});test("a clock that goes backwards does not mint tokens", () => {  const bucket = drain(3, 10_000);  assert.equal(take(bucket, 5_000, limit).decision.ok, false);});test("knows when a bucket is full again", () => {  assert.equal(msUntilFull({ tokens: 1, updated: 0 }, limit), 2000);  assert.equal(msUntilFull({ tokens: 0, updated: 0 }), 60_000);});test("the default allows a burst of 30 and one call every two seconds after", () => {  assert.equal(LIMIT.capacity, 30);  assert.equal(1 / LIMIT.refillPerSecond, 2);});