first commit

This commit is contained in:
2026-05-29 08:20:56 +01:00
commit 949299f58d
6368 changed files with 527176 additions and 0 deletions

View File

@@ -0,0 +1,80 @@
# @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).
<!-- begin:auto-docs -->
## Documentation tree
- [errors](./src/errors/errors.md) — Defines the structured error surface for `@suaveplan/cache-redis`. Every failure inside the package — connection drops…
- [errors](./src/errors/errors.md) — Defines the structured error surface for `@suaveplan/cache-redis`. Every failure inside the package — connection drops…
- [redis-cache](./src/redis-cache/redis-cache.md) — `RedisCache<T>` extends `AbstractCache<T>` from `@suaveplan/cache` and adapts a Redis-compatible store (via the minimal…
- [redis-cache](./src/redis-cache/redis-cache.md) — `RedisCache<T>` extends `AbstractCache<T>` from `@suaveplan/cache` and adapts a Redis-compatible store (via the minimal…
- [redis-like](./src/redis-like/redis-like.md) — Declares the minimal Redis client surface `RedisCache` consumes. Any client conforming to this interface — `ioredis`, `…
- [redis-like](./src/redis-like/redis-like.md) — Declares the minimal Redis client surface `RedisCache` consumes. Any client conforming to this interface — `ioredis`, `…
- [registry-augment](./src/registry-augment/registry-augment.md) — Augments the `CacheProviderRegistry` type exported by `@suaveplan/cache` with a `redis` entry, and side-effect-register…
- [registry-augment](./src/registry-augment/registry-augment.md) — Augments the `CacheProviderRegistry` type exported by `@suaveplan/cache` with a `redis` entry, and side-effect-register…
<!-- end:auto-docs -->
## 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
```bash
bun add @suaveplan/cache-redis
```
## Quick Start
```ts
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
- [errors](./src/errors/errors.md) — `CACHE_REDIS_CODES`, `RedisCacheError`.
- [redis-like](./src/redis-like/redis-like.md) — minimal `RedisLike` client surface.
- [redis-cache](./src/redis-cache/redis-cache.md) — `RedisCache<T>` class.
- [registry-augment](./src/registry-augment/registry-augment.md) — `CacheProviderRegistry` augmentation + auto-registration.
## Factory registration
```ts
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. |