Show HN: Solidis – Tiny TS Redis client, no deps, for serverless
Show HN: Solidis - 轻量级无依赖 TS Redis 客户端,专为 Serverless 打造
High-performance, SOLID-structured RESP client for Redis and other RESP-compatible servers
License
MIT license 29 stars 0 forks Branches Tags Activity
vcms-io/solidis
Code
Folders and files
Name| Name| Last commit message| Last commit date
---|---|---|---
Latest commit
History
5 Commits
.github/workflows| .github/workflows
.vscode| .vscode
scripts| scripts
sources| sources
.editorconfig| .editorconfig
.gitattributes| .gitattributes
.gitignore| .gitignore
.npmignore| .npmignore
LICENSE| LICENSE
README.md| README.md
biome.json| biome.json
package-lock.json| package-lock.json
package.json| package.json
tsconfig.json| tsconfig.json
View all files
Repository files navigation
@vcms-io/solidis
高性能、结构化的SOLID原则构建的RESP客户端,适用于Redis和其他兼容RESP的服务器
概述 • 主要特性 • 安装 • 用法 • 配置 • 高级特性 • 错误处理 • 许可
概述
Solidis 是一个基于 SOLID 原则构建的现代 RESP 客户端,零依赖,并以企业级性能为目标。它支持 RESP2 和 RESP3 协议,并为现代 JavaScript/TypeScript 应用程序进行了优化。
该库旨在实现最小的包大小、最大的类型安全和性能:
- Pure ESM/CJS - 支持两种模块系统
- Tree-shakable - 只导入你需要的部分
- Type-safe - 为所有命令提供广泛的 TypeScript 定义
- Dependency-free - 绝对零运行时依赖
主要特性
- 高性能
- 高效的 pipeline 和批量处理
- 最小的内存占用 (自定义优化解析器)
- 零拷贝缓冲区操作
- 智能缓冲区管理
- 协议支持
- RESP2 和 RESP3 协议支持
- 自动协议协商
- 二进制安全操作
- 完全支持多字节字符
- 高级特性
- 事务支持 (MULTI/EXEC)
- Pipeline 操作
- Pub/Sub 功能
- 自动重连
- 命令超时处理
- 类型安全
- 强大的 TypeScript 支持
- 全面的类型定义
- 命令特定的类型保护
- 运行时回复类型检查
- 可扩展性
- 易于使用内部和外部命令扩展客户端
- 可定制的事务处理
- 插件架构支持
- 轻量级
- 零依赖
- 最小的包大小 < 30KB
- 完整的包大小 (包含所有命令) < 105KB
要求
- 运行时 : Node.js 14 或更高版本
- 开发 : 推荐使用 Node.js 22 LTS 以获得最佳稳定性
安装
# 使用 npm
npm install @vcms-io/solidis
# 使用 yarn
yarn add @vcms-io/solidis
# 使用 pnpm
pnpm add @vcms-io/solidis
用法
客户端类型
Solidis 提供了两种客户端实现:
1. 基础客户端 (SolidisClient)
基础客户端包含最少的功能,以减少包大小。你需要使用特定命令扩展它:
import { SolidisClient } from '@vcms-io/solidis';
import { get } from '@vcms-io/solidis/command/get';
import { set } from '@vcms-io/solidis/command/set';
import { multi } from '@vcms-io/solidis/command/multi';
import type { SolidisClientExtensions } from '@vcms-io/solidis';
// 定义带有类型安全性的扩展
const extensions = {
get,
set,
multi
} satisfies SolidisClientExtensions;
// 使用扩展初始化客户端
const client = new SolidisClient({
host: '127.0.0.1',
port: 6379
}).extend(extensions);
// 使用命令
await client.set('key', 'value');
const value = await client.get('key');
2. 特性客户端 (SolidisFeaturedClient)
一个方便的客户端,预加载了所有 RESP 命令:
import { SolidisFeaturedClient } from '@vcms-io/solidis/featured';
// 所有 RESP 命令都已预加载
const client = new SolidisFeaturedClient({
host: '127.0.0.1',
port: 6379
});
// 直接使用任何 RESP 命令
await client.set('key', 'value');
await client.hset('hash', 'field', 'value');
await client.lpush('list', 'item-1', 'item-2');
连接管理
// 创建客户端 (带延迟连接)
const client = new SolidisClient({
host: '127.0.0.1',
port: 6379,
lazyConnect: true
}).extend({ get, set });
// 在需要时显式连接
await client.connect();
// 处理连接事件
client.on('connect', () => console.log('Connected to server'));
client.on('ready', () => console.log('Client is ready for commands'));
client.on('error', (err) => console.error('Error occurred:', err));
client.on('end', () => console.log('Connection closed'));
// 完成后关闭连接
client.quit();
基本操作
// 设置键
await client.set('key', 'value');
// 获取键
const value = await client.get('key');
console.log(value); // 'value'
// 删除键
await client.del('key');
事务
// 启动一个事务
const transaction = client.multi();
// 将命令排队 (不需要 await)
transaction.set('key', 'value');
transaction.incr('counter');
transaction.get('key');
// 执行事务
const results = await transaction.exec();
console.log(results); // [[ 'OK' ], [ 1 ], [ <Buffer 76 61 6c 75 65> ]]
// 或者根据需要放弃事务
const transaction = client.multi();
transaction.set('key', 'value');
transaction.discard(); // 取消事务
Pipelines
// 为 pipeline 创建命令
const commands = [
['set', 'pipeline', 'value'],
['incr', 'counter'],
['get', 'pipeline']
];
// 将命令作为 pipeline 发送
const results = await client.send(commands);
console.log(results); // [[ 'OK' ], [ 1 ], [ <Buffer 76 61 6c 75 65> ]]
Pub/Sub
// 订阅频道
client.on('message', (channel, message) => {
console.log(`Received ${message} from ${channel}`);
});
await client.subscribe('news');
// 从另一个客户端发布
await client.publish('news', 'Hello world!');
配置
Solidis 提供了广泛的配置选项:
const client = new SolidisClient({
// 连接
host: '127.0.0.1',
port: 6379,
useTLS: false,
lazyConnect: false,
// 身份验证
authentication: {
username: 'user',
password: 'password'
},
database: 0,
// 协议 & 恢复
clientName: 'solidis',
protocol: 'RESP2', // 'RESP2' 或 'RESP3'
autoReconnect: true,
enableReadyCheck: true,
maxConnectionRetries: 20,
connectionRetryDelay: 100,
autoRecovery: {
database: true, // 重新连接后自动选择 DB
subscribe: true, // 自动重新订阅频道
ssubscribe: true, // 自动重新订阅分片频道
psubscribe: true, // 自动重新订阅模式
},
// 超时 (毫秒)
commandTimeout: 5000,
connectionTimeout: 2000,
socketWriteTimeout: 1000,
readyCheckInterval: 100,
// 性能调优
maxCommandsPerPipeline: 300,
maxProcessRepliesPerChunk: 4 * 1024, // 4KB
maxSocketWriteSizePerOnce: 64 * 1024, // 64KB
rejectOnPartialPipelineError: false,
// 解析器配置
parser: {
buffer: {
initial: 4 * 1024 * 1024, // 4MB
shiftThreshold: 2 * 1024 * 1024, // 2MB
},
},
// 事件监听器
maxEventListenersForClient: 10 * 1024,
maxEventListenersForSocket: 10 * 1024,
// 调试选项
debug: false,
debugMaxEntries: 10 * 1024,
});
高级特性
自定义命令
import { SolidisClient } from '@vcms-io/solidis';
import { get, set } from '@vcms-io/solidis/command';
import type { SolidisClientExtensions } from '@vcms-io/solidis';
// 定义带有自定义命令的扩展
const extensions = {
get,
set,
// 自定义命令实现
fill: async function(this: typeof client, keys: string[], value: string) {
return await Promise.all(keys.map((key) => this.set(key, value)));
},
} satisfies SolidisClientExtensions;
const client = new SolidisClient({
host: '127.0.0.1',
port: 6379
}).extend(extensions);
// 使用自定义命令
await client.fill(['key1', 'key2', 'key3'], 'value');
原始命令
当您需要使用尚未实现的命令时:
// 使用 send() 的原始命令
const result = await client.send([['command', 'some', 'options']]);
调试
启用详细的调试日志记录:
// 启用调试模式
const client = new SolidisClient({
debug: true
});
// 监听调试事件
client.on('debug', (entry) => {
console.log(`[${entry.type}] ${entry.message}`, entry.data);
});
// 替代方案:环境变量
// DEBUG=solidis node app.js
错误处理
Solidis 为不同的故障模式提供了详细的错误类:
import {
SolidisClientError,
SolidisConnectionError,
SolidisParserError,
SolidisPubSubError,
SolidisRequesterError,
unwrapSolidisError,
} from '@vcms-io/solidis';
try {
await client.set('key', 'value');
} catch (error) {
// 获取带有堆栈跟踪的根本原因
console.error(unwrapSolidisError(error));
// 处理特定的错误类型
if (error instanceof SolidisConnectionError) {
console.error('Connection error:', error.message);
} else if (error instanceof SolidisParserError) {
console.error('Parser error:', error.message);
} else if (error instanceof SolidisClientError) {
console.error('Client error:', error.message);
}
}
结构
┌─────────────────────────────────────────────────┐
│ SolidisClient │
│ │
│ Creates & coordinates all components │
│ │
│ ┌────────────────────────────────────┐ │
│ │ Debug Memory │ │
│ └───────┬───────────────────┬────────┘ │
│ ▼ ▼ │
│ ┌────────────────┐ ┌────────────────┐ │
│ │ Connection │─►│ Requester │─┐ │
│ └────────────────┘ └────────────────┘ │ │
│ ┌────────────────┐ │ │
│ │ Parser │◄┤ │
│ └────────────────┘ │ │
│ ┌────────────────┐ │ │
│ │ PubSub │◄┘ │
│ └────────────────┘ │
│ │
└─────────────────────────────────────────────────┘
┌──────────────┴─────────────┐
▼ ▼
┌─────────────────┐ ┌───────────────────────┐
│ SolidisClient │ │ SolidisFeaturedClient │
│ (needs extend) │ │ (all commands) │
└─────────────────┘ └───────────────────────┘
Solidis 结构遵循清晰的组件分离:
- SolidisClient : 核心入口点,用于创建和协调所有组件
- Debug Memory : 在客户端中创建并注入到其他组件中
- Connection : 管理 TCP/TLS 套接字连接、重新连接和恢复
- Requester : 处理命令流水线和请求状态
- Parser : 使用优化的缓冲区处理来处理 RESP2/RESP3 协议
- PubSub : 维护订阅状态并由 Requester 用于 pub/sub 事件
事件系统
Solidis 发出以下事件:
// 连接事件
client.on('connect', () => console.log('Connected to server'));
client.on('ready', () => console.log('Client is ready'));
client.on('end', () => console.log('Connection closed'));
client.on('error', (err) => console.error('Error:', err));
// Pub/Sub 事件
client.on('message', (channel, message) => console.log(`${channel}: ${message}`));
client.on('pmessage', (pattern, channel, message) => console.log(`${pattern} ${channel}: ${message}`));
client.on('subscribe', (channel, count) => console.log(`Subscribed to ${channel}`));
client.on('unsubscribe', (channel, count) => console.log(`Unsubscribed from ${channel}`));
// 调试事件
client.on('debug', (entry) => console.log(`[${entry.type}] ${entry.message}`));
贡献
Solidis 是一个开源项目,我们欢迎社区的贡献。 以下是如何做出贡献:
开发设置
# 克隆存储库
git clone https://github.com/vcms-io/solidis.git
cd solidis
# 安装依赖
npm install
# 构建项目
npm run build
# 运行测试
npm test
贡献指南
- Fork 存储库 : 首先 fork 存储库,然后克隆你的 fork。
- 创建分支 : 为你的特性或错误修复创建一个分支:
git checkout -b feature/your-feature-name
- 遵循代码风格 :
- 使用 TypeScript 严格模式
- 遵循现有的模式和命名约定
- 提交 Pull Request : 将你的更改推送到你的 fork 并提交一个 pull request。
- 提供对更改的清晰描述
- 引用任何相关问题
- 添加适当的文档
代码质量指南
- TypeScript : 使用严格的类型,并尽可能避免
any
类型和as
强制转换 - 依赖项 : 除非绝对必要,否则避免添加新的依赖项
- 性能 : 考虑更改的性能影响
- 捆绑包大小 : 保持捆绑包大小最小
发布流程
Solidis 遵循语义版本控制 (SemVer):
- Patch (0.0.x) : 不影响 API 的错误修复和小修改
- Minor (0.x.0) : 以向后兼容的方式添加的新功能
- Major (x.0.0) : 对公共 API 的重大更改
许可
在 MIT 许可下获得许可。 有关更多信息,请参阅 LICENSE。
关于
High-performance, SOLID-structured RESP client for Redis and other RESP-compatible servers
Resources
License
MIT license Activity Custom properties
Stars
Watchers
Forks
Releases 1
Release v0.0.1 Latest May 16, 2025
Packages 0
No packages published