Skip to content

jonathanong/valkyries

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

56 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

valkyries

Valkey utilities for Node.js services: cache helpers, Bloom filters, dynamic configuration, and sliding-window rate limiting.

Install

pnpm add valkyries @valkey/valkey-glide

valkyries is ESM-only and requires Node.js 24 or newer.

Valkey

By default the package reads VALKEY_URL, falling back to redis://localhost:6379.

Specialized URLs can split traffic by data type:

VALKEY_CACHE_URL=redis://localhost:6379
VALKEY_RATE_LIMITER_URL=redis://localhost:6379
VALKEY_DYNAMIC_CONFIG_URL=redis://localhost:6379

Bloom filters require Valkey with the Bloom module. For local development and CI, use Valkey Bundle:

docker run --rm -p 6379:6379 valkey/valkey-bundle:latest

Cache

import { ValkeyCache } from "valkyries";

const cache = new ValkeyCache({ prefix: "users", ttlSeconds: 300 });

const getUser = cache.cacheGetByAny(async (id) => {
  return await loadUserFromDatabase(id);
});

const user = await getUser("user_123");
await cache.invalidateCacheGetByAny("user_123");

Cache keys are normalized with trim().toLowerCase(). Use keySerializer for composite keys.

Bloom Filters

import { ValkeyBloomFilter } from "valkyries";

const filter = new ValkeyBloomFilter({
  name: "users",
  capacity: 1_000_000,
  errorRate: 0.01,
});

await filter.ensureExists();
await filter.add(["user_123"]);

const maybeExists = await filter.existsIfReady("users:ready", "user_123");

null means the filter is missing or not ready and callers should fall back to the authoritative store.

Dynamic Config

import { DynamicConfig } from "valkyries";

const flags = new DynamicConfig({
  key: "feature-flags",
  fieldTypes: { enabled: "boolean", sampleRate: "number" },
  defaultFields: { enabled: false, sampleRate: 0 },
});

await flags.waitForInitialization();
await flags.setField("enabled", true);

Dynamic config stores fields in a Valkey hash and publishes changes over pub/sub.

Rate Limiter

import { RateLimiter } from "valkyries";

const limiter = new RateLimiter({ prefix: "login", ttlSeconds: 60 });
const { limited, counts } = await limiter.addAndCheck(["ip:127.0.0.1"], 10);

addAndCheck() increments first and blocks when any post-add count is greater than or equal to the threshold.

Client Injection

Every class accepts an optional GlideClient for tests or custom connection management:

import { GlideClient } from "@valkey/valkey-glide";
import { ValkeyCache, glideConfigFromUrl } from "valkyries";

const client = await GlideClient.createClient(glideConfigFromUrl("redis://localhost:6379"));
const cache = new ValkeyCache({ prefix: "custom", ttlSeconds: 60, client });

Call closeValkeyClients() to close package-managed clients.

Documentation

About

Valkey Functions - Caching, Bloom Filters, Rate Limiters, and Dynamic Configurations

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors