Changelog - 2026-06-25
Redis Helpers Refactor - Abstract Base, Interfaces, Sentinel & Factory
Breaking Change New FeatureIn one line. Redis helpers are reorganized by topology (single, cluster, sentinel) with renamed classes, a segregated IRedisHelper interface, and a new factory - existing Single and Cluster connection behavior is unchanged, but every consumer needs an import update.
What changed
- Renamed classes and types -
DefaultRedisHelper->AbstractRedisHelper,RedisHelper->RedisSingleHelper,IRedisHelperOptions->IRedisSingleHelperOptions. No aliases are provided. - New
RedisSentinelHelper- connects through a Redis Sentinel quorum for automatic failover. - New
createRedisHelper({ mode })factory - picks the right helper (RedisModes.SINGLE | CLUSTER | SENTINEL) from config instead of importing all three classes. - New
IRedisHelperinterface - a segregated capability contract composed of nine sub-interfaces (connection, key-value, hash, pub/sub, JSON, raw command, key, set, list). Consumers should type against this instead of a concrete class. - Expanded data API - new key operations (
exists,expire,ttl,incr/decr, ...), set operations (sAdd,sMembers, ...), and list operations (lPush,rPush,lRange, ...); the hash interface gainshGet,hDel,hExists,hKeys,hVals,hIncrBy,hLen. - camelCase-only method names - the lowercase aliases
mset,mget,hset,hgetallare removed; onlymSet,mGet,hSet,hGetAllremain. set()gainsexpiresIn- an optional millisecond TTL (uses RedisPX).onErrorcallback narrowed - theerrorargument is nowunknowninstead ofany, so accessing.messagerequires a type guard.- No behavioral change to the Cluster connection or to any existing data method beyond the renames above.
Who is affected
- Anyone importing
RedisHelper,DefaultRedisHelper, orIRedisHelperOptionsby name - update imports to the new names (breaking, see below). - Anyone calling
mset,mget,hset, orhgetall- switch to the camelCase form (breaking, see below). - Anyone reading
.message(or another property) off theerrorin anonErrorcallback - add a type guard first (breaking, see below). - Anyone using
RedisClusterHelper- no action needed. It is a faithful rename that still passesclusterOptionsstraight to ioredisCluster. - Anyone who wants Sentinel HA - new opt-in feature via
RedisSentinelHelperorcreateRedisHelper({ mode: RedisModes.SENTINEL }). - Anyone using Socket.IO, WebSocket, or the BullMQ queue helper - no action needed. Their internal Redis typing was updated as part of this release.
Breaking changes
WARNING
Public class and type names changed. No aliases are provided.
Renamed exports
| Before | After |
|---|---|
DefaultRedisHelper | AbstractRedisHelper |
RedisHelper | RedisSingleHelper |
IRedisHelperOptions | IRedisSingleHelperOptions |
// Before
import { RedisHelper, DefaultRedisHelper } from '@venizia/ignis-helpers';
import type { IRedisHelperOptions } from '@venizia/ignis-helpers';
const redis = new RedisHelper({ name: 'cache', host, port, password });
if (connection instanceof DefaultRedisHelper) { /* ... */ }
// After
import { RedisSingleHelper, AbstractRedisHelper } from '@venizia/ignis-helpers';
import type { IRedisSingleHelperOptions } from '@venizia/ignis-helpers';
const redis = new RedisSingleHelper({ name: 'cache', host, port, password });
if (connection instanceof AbstractRedisHelper) { /* ... */ }Lowercase method aliases removed
Only the camelCase method names remain.
| Removed | Use instead |
|---|---|
mset | mSet |
mget | mGet |
hset | hSet |
hgetall | hGetAll |
onError callback error is now unknown
// Before
onError: ({ name, helper, error }) => {
console.error(error.message); // compiled fine with `any`
}
// After
onError: ({ name, helper, error }) => {
if (error instanceof Error) {
console.error(error.message); // narrowing required
}
}Type fields against IRedisHelper, not a concrete class
// Before
class MyService {
constructor(private redisConnection: DefaultRedisHelper) {}
}
// After
import type { IRedisHelper } from '@venizia/ignis-helpers';
class MyService {
constructor(private redisConnection: IRedisHelper) {}
}Details
RedisSentinelHelper
import { RedisSentinelHelper } from '@venizia/ignis-helpers';
const redis = new RedisSentinelHelper({
name: 'cache',
masterName: 'mymaster',
sentinels: [
{ host: '10.0.0.1', port: 26379 },
{ host: '10.0.0.2' }, // port defaults to 26379
],
role: 'master',
password: 'data-node-secret',
sentinelPassword: 'sentinel-secret',
autoConnect: false,
});
await redis.connect();masterName maps to the ioredis name field (the Sentinel group name), distinct from the helper's own name. Pass redisOptions for any extra ioredis option; first-class fields always win.
createRedisHelper factory
import { createRedisHelper, RedisModes } from '@venizia/ignis-helpers';
const redis = createRedisHelper({
mode: RedisModes.SINGLE,
name: 'cache',
host: 'localhost',
port: 6379,
password: 'secret',
});
// mode: RedisModes.CLUSTER -> RedisClusterHelper
// mode: RedisModes.SENTINEL -> RedisSentinelHelperThe factory is overloaded so TypeScript infers the concrete return type when mode is a literal.
Segregated IRedisHelper interfaces
| Interface | Methods |
|---|---|
IRedisConnection | getClient, duplicateClient, ping, connect, disconnect |
IRedisKeyValue | set, get, del, keys, getString, getStrings, getObject, getObjects, mSet, mGet |
IRedisHash | hSet, hGetAll, hGet, hDel, hExists, hKeys, hVals, hIncrBy, hLen |
IRedisPubSub | publish, subscribe, unsubscribe |
IRedisJson | jSet, jGet, jDelete, jNumberIncreaseBy, jStringAppend, jPush, jPop |
IRedisCommand | execute |
IRedisKey | exists, expire, expireAt, ttl, persist, incr, decr, incrBy, decrBy |
IRedisSet | sAdd, sRem, sMembers, sIsMember, sCard |
IRedisList | lPush, rPush, lPop, rPop, lRange, lLen |
Edge-case semantics
- Array-input methods (
exists,hDel,sAdd,sRem,lPush,rPush) return0immediately on an empty array, without calling ioredis. - Boolean-returning methods (
expire,expireAt,persist,hExists,sIsMember) compare the ioredis numeric reply=== 1. expireAttakes epoch seconds (ioredisexpireat);set'sexpiresIntakes milliseconds (PX).
Files changed
Helpers package (packages/helpers) - the redis module is restructured folder-per-topology: common/ (interfaces, types, constants), base/abstract.helper.ts (renamed from default.helper.ts), single/, cluster/, sentinel/ (new), and factory.ts (new). queue/bullmq, socket/socket-io, and socket/websocket now type against IRedisHelper. Five new test files under src/__tests__/redis/.
Core package (packages/core) - the Socket.IO, WebSocket, and Auth components type against IRedisHelper/AbstractRedisHelper; the mail BullMQ executor uses RedisSingleHelper and IRedisSingleHelperOptions.
Examples - vert, socket-io-test, and websocket-test updated to RedisSingleHelper.