Skip to content

feat(client): expose RedisClient, RedisCluster, RedisSentinel and pool classes#3251

Merged
nkaradzhov merged 1 commit into
redis:masterfrom
aarond-sp:feat/expose-client-classes
Apr 23, 2026
Merged

feat(client): expose RedisClient, RedisCluster, RedisSentinel and pool classes#3251
nkaradzhov merged 1 commit into
redis:masterfrom
aarond-sp:feat/expose-client-classes

Conversation

@aarond-sp
Copy link
Copy Markdown
Contributor

@aarond-sp aarond-sp commented Apr 23, 2026

Description

Expose the underlying RedisClient, RedisCluster, RedisSentinel, RedisSentinelClient and RedisClientPool classes (plus the RedisSentinelClientType type) as named exports from @redis/client. Today only the factory functions (createClient, createCluster, createSentinel, createClientPool) are exported, which forces consumers reaching for instanceof checks or prototype-level stubbing in tests to import from internal paths like @redis/client/dist/lib/client — fragile, and not covered by the public API contract.

Why

  • instanceof checks: frameworks, DI containers and user code frequently want x instanceof RedisClient / instanceof RedisSentinel. This already works at runtime (the factory returns an Object.create(new Subclass(...)) whose prototype chain terminates at RedisClient.prototype) — it just wasn't reachable via the public API.
  • Prototype stubbing in tests: Sinon / Jest mocks on RedisClient.prototype.<method> work for methods defined directly on the base class (connect, quit, _executeCommand, EventEmitter methods).
  • Strictly additive; no existing exports removed or renamed.

Caveat worth flagging

Command methods (get, set, hGet, …) are not on RedisClient.prototype. They are attached to a dynamic subclass produced per config by RedisClient.factory() via attachConfig() and cached in a SingleEntryCache. That subclass isn't exported. Implications:

  • instanceof RedisClient — ✅ works (prototype chain: proxy → subclass instance → subclass.prototype → RedisClient.prototype → EventEmitter.prototype).
  • Stubbing methods defined on RedisClient itself (connect/quit/_executeCommand/EventEmitter) via RedisClient.prototype.X = … — ✅ works.
  • Stubbing command methods via RedisClient.prototype.get = … — ❌ not found; command methods live on the subclass. For those, stub the instance or hook _executeCommand on the base prototype.

Same applies to RedisSentinel and RedisCluster (same factory pattern).

Changes

packages/client/index.ts:

  • Add RedisClient, RedisCluster, RedisSentinel, RedisSentinelClient, RedisClientPool as named exports.
  • Add RedisSentinelClientType to the existing type re-export from ./lib/sentinel/types.

Because packages/redis/index.ts already does export * from '@redis/client', these also propagate to the top-level redis package.

Checklist

  • Does npm test pass with this change (including linting)? Build (tsc --build) is clean; existing test suite couldn't run locally due to an unrelated arm64 / Docker image availability issue for redislabs/client-libs-test — CI should exercise it on a supported platform.
  • Is the new or changed code fully tested? No behavior change — this is a pure re-export of already-exercised classes.
  • Is a documentation update included (if this change modifies existing APIs, or introduces new ones)? Happy to add README coverage for the new named exports if you'd like it in the same PR.

Note

Low Risk
Low risk: this is a strictly additive surface-area change that only re-exports existing classes/types, with no runtime logic changes. Main risk is minor API/typing impact from new named exports (e.g., potential name collisions for consumers).

Overview
Adds new public named exports from @redis/client. packages/client/index.ts now re-exports the underlying RedisClient, RedisClientPool, RedisCluster, RedisSentinel, and RedisSentinelClient classes (alongside existing factory functions).

Also extends the Sentinel type exports to include RedisSentinelClientType, and these new exports automatically propagate through the top-level redis package via export * from '@redis/client'.

Reviewed by Cursor Bugbot for commit 6bb2277. Bugbot is set up for automated code reviews on this repo. Configure here.

…l classes

Re-export the underlying classes (previously only accessible as default
exports on internal paths) alongside the existing factory functions, so
consumers can use `instanceof` checks and stub methods on the prototype
without reaching into `@redis/client/dist/...`.

Also exposes `RedisClientPool`, `RedisSentinelClient` and the
`RedisSentinelClientType` type.

The factories (`createClient`, `createCluster`, `createSentinel`,
`createClientPool`) remain unchanged, so existing code keeps working.

Note: command methods (get, set, etc.) are attached to a dynamic
subclass produced by the `factory()` call per config, not to
`RedisClient.prototype` itself. `instanceof RedisClient` still works
(prototype chain: proxy -> subclass instance -> subclass.prototype ->
RedisClient.prototype), and methods defined directly on the base class
(connect, quit, _executeCommand, EventEmitter methods) can be stubbed
via the prototype; command-level stubs still need to target the
instance or `_executeCommand`.
@jit-ci
Copy link
Copy Markdown

jit-ci Bot commented Apr 23, 2026

Hi, I’m Jit, a friendly security platform designed to help developers build secure applications from day zero with an MVS (Minimal viable security) mindset.

In case there are security findings, they will be communicated to you as a comment inside the PR.

Hope you’ll enjoy using Jit.

Questions? Comments? Want to learn more? Get in touch with us.

@nkaradzhov
Copy link
Copy Markdown
Collaborator

@aarond-sp thanks, this looks good!

@nkaradzhov nkaradzhov self-requested a review April 23, 2026 17:36
@nkaradzhov nkaradzhov merged commit b57a81d into redis:master Apr 23, 2026
16 checks passed
@aarond-sp aarond-sp deleted the feat/expose-client-classes branch April 23, 2026 18:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants