跳到主要内容

复杂前端应用,别再让组件扛全部数据复杂度

RxDB 的重点,是把存储、查询、模型和 UI 绑定拆成清晰层次,让复杂度各归其位。

存储层
SQLite / PGlite 负责落盘、索引、事务和查询执行。
响应式层
RxJS 把查询结果、实体变更和副作用整合成同一条数据流。
模型层
实体元数据统一定义字段、关系、查询构造和生成代码的边界。
协作层
分支、同步和撤销重做建立在本地数据版本之上,可按需叠加。

浏览器就是主执行面

UI、业务规则、查询和本地持久化先在浏览器内闭环执行。远端负责交换版本,不负责接管每一次读写。

浏览器执行面

本地先完成读写查询

界面、本地领域逻辑、查询与事务都在浏览器内闭环运行。离线时照常可用,联网后再按需同步。

Local-first
UI 与交互层

页面状态、表单和详情页直接消费本地查询结果,不必把每次读写都绑在接口往返上。

本地业务与模型层

实体规则、关系约束、查询构造和副作用在浏览器内闭环执行。

本地数据库层

SQLite / PGlite + OPFS 负责事务、索引、查询执行和持久化。

交互优先本地执行
用户体验不依赖网络往返。
版本按分支流转
撤销、重做、分支与本地历史围绕数据版本组织。
同步按需触发
联网后再进行 pull / push,而非每次读写都依赖服务端。
Sync lane
Push

把本地提交、分支状态和需要共享的数据推到远端。

Pull

把远端最新变更拉回浏览器,再合并进本地数据流。

同步的是数据版本,而非页面状态补丁
远端角色

远端同步仓库

远端更像共享数据仓库或同步中继点,负责交换版本与变更,不负责替浏览器执行业务主流程。

保存可共享的版本历史与同步状态
为多设备或多成员提供交换点
通过 pull / push 同步,而不是接管本地业务执行

核心技术选型

每一层都围绕“浏览器内可运行的数据应用”这个目标服务

SQLite
本地存储执行层
轻量、稳定、广泛验证,适合大多数浏览器端结构化数据场景。
PGlite
高级查询执行层
在浏览器内提供更接近 PostgreSQL 的能力,适合复杂查询与扩展需求。
TypeScript
模型与类型约束
让模型定义、生成代码和消费端 API 保持一致,减少运行时错误。
RxJS
核心响应式主线
把查询结果、变更事件和副作用放到同一套响应式主线上处理,这是系统主线,而非可选配件。
OPFS
可选持久化增强
在浏览器支持时提供更可靠的本地文件持久化;不可用时仍可回退到其他 VFS 路径。
ts-morph
代码生成引擎
基于 TypeScript AST 操作,把实体元数据转译为类型定义、查询构建器和框架适配代码,是整个生成链路的执行核心。

已经落地的能力层

这些能力已经能在文档、demo 和源码里直接验证

模型驱动开发
通过元数据定义模型,再把查询、表单和类型安全能力从模型向外延伸。
已实现
实体元数据
关系建模
类型安全 CRUD
响应式查询自动更新
跨框架统一 API
三个主流框架共享相同业务语义,差异只保留在 UI 绑定层。
已实现
Angular Signals 集成
React Hooks 集成
Vue Composables 集成
RxJS Observable 通用支持
代码生成链路
从模型定义自动生成类型和辅助代码,减少重复劳动与手写错误。
已实现
完整类型推断
查询构建器
实体辅助代码
框架封装输出
性能基础设施
围绕浏览器内数据库、Worker 和缓存组织性能边界,而不是只做渲染层优化。
已实现
Worker 支持
OPFS 优先持久化
查询缓存
WASM 数据库执行
版本与同步基础
协作层当前已覆盖版本分支、撤销重做和条件同步,重点是本地版本流转可验证。
MVP 已验证
Branch 管理
撤销重做
跨 Tab 同步
多种同步策略

关键代码路径

从模型到界面,主链路应该短、稳、可重复

1. 定义模型边界
const TodoEntity: EntityMetadataOptions = {
name: 'Todo',
displayName: 'Todo',
repository: 'Repository',
extends: ['EntityBase'],
properties: [
{ name: 'title', type: PropertyType.string },
{ name: 'completed', type: PropertyType.boolean, default: false },
{ name: 'createdAt', type: PropertyType.date }
]
};
2. 生成稳定接口
nx run rxdb-client-generator:generate

# 输出内容包括:
# - 实体类型定义
# - CRUD 与查询辅助代码
# - 框架集成封装
# - 关系映射与表单支持
3. 把查询接入界面
Todo.find({
where: {
combinator: 'and',
rules: [{ field: 'completed', operator: '=', value: false }]
}
}).subscribe(todos => {
console.log('未完成事项:', todos);
});
4. 复用同一套查询语义
React
const { value: todos } =
useFind(Todo, { where: {...} });
Vue
const { value: todos } =
useFind(Todo, { where: {...} });
Angular
const { value: todos } =
useFind(Todo, { where: {...} });

相同的模型与查询语义,不同的 UI 绑定层,差异集中在各框架的接入方式上。

从模型开始

从模型开始,而非从页面状态开始

这套架构要解决的,是复杂前端应用里数据规则无处安放的问题。先体验 demo,再回到文档,会更容易判断它是否适合你的系统。

查看在线演示