Files
2026-06-09 21:06:27 +01:00

4.5 KiB

@suaveplan/cache-redis - AbstractCache backend over a minimal RedisLike interface — native SET ... EX, GET, DEL, EXISTS, TTL, SCAN. Reuses @suaveplan/cache-storage codecs (JSON / identity / base64).

AbstractCache<T> backend over a minimal RedisLike interface — native SET ... EX, GET, DEL, EXISTS, TTL, SCAN. Reuses @suaveplan/cache-storage codecs (JSON / identity / base64).

Documentation tree

  • errors — Defines the structured error surface for @suaveplan/cache-redis. Every failure inside the package — connection drops…
    • errors — Defines the structured error surface for @suaveplan/cache-redis. Every failure inside the package — connection drops…
  • redis-cache — RedisCache<T> extends AbstractCache<T> from @suaveplan/cache and adapts a Redis-compatible store (via the minimal…
    • redis-cache — RedisCache<T> extends AbstractCache<T> from @suaveplan/cache and adapts a Redis-compatible store (via the minimal…
  • redis-like — Declares the minimal Redis client surface RedisCache consumes. Any client conforming to this interface — ioredis, `…
    • redis-like — Declares the minimal Redis client surface RedisCache consumes. Any client conforming to this interface — ioredis, `…
  • registry-augment — Augments the CacheProviderRegistry type exported by @suaveplan/cache with a redis entry, and side-effect-register…
    • registry-augment — Augments the CacheProviderRegistry type exported by @suaveplan/cache with a redis entry, and side-effect-register…

Summary

@suaveplan/cache-redis is the server-tier cache backend for the cache family. It plugs any Redis-compatible client (ioredis, node-redis, custom adapters over RESP3, KeyDB, Dragonfly) into the unified AbstractCache<T> surface. TTL is owned by the Redis server via native SET ... EX, so there are no client-side header bytes, no per-read expiry comparisons, and no client-side eviction tables — Redis's own maxmemory-policy decides what to evict. Side-effect import auto-registers RedisCache as the "redis" provider on CacheFactory, so createCache("redis", { redis }) works after a single import.

Installation

bun add @suaveplan/cache-redis

Quick Start

import { RedisCache } from "@suaveplan/cache-redis";
import { Redis } from "ioredis";

const cache = new RedisCache<{ id: string; email: string }>({
  redis: new Redis({ host: "redis.example.com" }),
  namespace: "users",
  defaultTtl: 5 * 60_000,
});

await cache.set("alice", { id: "1", email: "alice@example.com" });
const user = await cache.get("alice");

Modules

Factory registration

import "@suaveplan/cache-redis"; // side-effect: register provider
import { createCache } from "@suaveplan/cache";
import { Redis } from "ioredis";

const cache = createCache("redis", { redis: new Redis() });

Why a separate package, not cache-storage over a future storage-redis?

Redis owns TTL natively (EX, EXPIRE) and eviction natively (maxmemory-policy). Layering the cache over a hypothetical storage-redis would:

  1. Encode TTL into the value bytes (wasted — Redis ignores it).
  2. Require client-side eviction tracking (wasted — Redis evicts per policy).
  3. Lose TTL key introspection (Redis can tell us; the header can't).

So RedisCache talks to Redis directly via RedisLike, and cache-storage is reserved for genuinely byte-oriented stores (filesystem, S3, browser storage).

Dependencies

Dependency Purpose
@suaveplan/cache AbstractCache<T>, CacheFactory, CacheProviderRegistry, CacheEvents.
@suaveplan/cache-storage Shared Codec<T> contract + JsonCodec / IdentityCodec.
@suaveplan/error defineCodes, SuaveplanError.
@suaveplan/types EventBusLike.
tslib TypeScript helpers.