Files
Peter Meier b122de518c feat: mockly-hono — file-based mock API server (Hono)
File path = route. JSON/JSON5, dynamic .ts handlers + faker, templating,
stateful CRUD (pagination/sort/persist), __variants, sequence, chaos,
rate-limit, auth, validation, per-route + global proxy/record, splat routes,
X-Scenario overlays, SSE. Visual docs (Scalar) at /__docs from a live
OpenAPI 3 spec. OpenAPI import script. Zero-build via tsx.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-23 12:44:31 +02:00

27 lines
941 B
TypeScript

// Per-route runtime state: sequence cursors + rate-limit windows.
// Keyed by route file; reset on server restart.
const seqCursor = new Map<string, number>()
/** Return the next index in a sequence of length n, advancing the cursor. */
export function nextSeqIndex(key: string, n: number): number {
const i = seqCursor.get(key) ?? 0
seqCursor.set(key, i + 1)
return i % n
}
const rlHits = new Map<string, number[]>()
/** Sliding-window rate limit. Returns remaining + whether this call is allowed. */
export function rateCheck(key: string, max: number, windowMs: number, now: number) {
const hits = (rlHits.get(key) ?? []).filter((t) => now - t < windowMs)
if (hits.length >= max) {
rlHits.set(key, hits)
const retryMs = windowMs - (now - hits[0])
return { allowed: false, remaining: 0, retryMs }
}
hits.push(now)
rlHits.set(key, hits)
return { allowed: true, remaining: max - hits.length, retryMs: 0 }
}