rxdb-adapter-supabase
RxDB Supabase 适配器 - 基于 PostgreSQL 的远程同步实现。
特性
- ✅ 完整的 CRUD 操作 - 通过 Repository 模式封装 Supabase API
- ✅ 批量操作 -
saveMany/removeMany/mutations高性能批处理 - ✅ 事务支持 - 基于 PostgreSQL RPC 的原子性操作
- ✅ 实时订阅 - Supabase Realtime 自动推送远程变更
- ✅ 变更追踪 - 自动记录所有数据变更到
RxDBChange表 - ✅ 双向同步 - Push/Pull 机制确保本地与远程数据一致
- ✅ 树形结构 -
SupabaseTreeRepository支持树形数据操作
何时使用
- 需要多端数据同步(Web/移动端/桌面端)
- 需要实时协作功能
- 需要云端备份和恢复
- 需要 PostgreSQL 的高级特性(JSONB、全文搜索、RLS)
- 已有 Supabase 基础设施
与其他适配器对比
| 特性 | Supabase | PGlite | wa-sqlite |
|---|---|---|---|
| 部署模式 | 云端/自托管 | 本地 | 本地 |
| 多端同步 | ✅ | ❌ | ❌ |
| 实时订阅 | ✅ | ❌ | ❌ |
| 离线优先 | ✅ (混合) | ✅ | ✅ |
| 数据库 | PostgreSQL | PostgreSQL | SQLite |
| 认证集成 | ✅ | ❌ | ❌ |
安装
pnpm add @aiao/rxdb-adapter-supabase @supabase/supabase-js
快速开始
1. 配置 RxDB
import { createRxdb } from '@aiao/rxdb';
import { createSupabaseAdapter } from '@aiao/rxdb-adapter-supabase';
import { createWaSqliteAdapter } from '@aiao/rxdb-adapter-wa-sqlite';
const db = await createRxdb({
local: createWaSqliteAdapter({ vfs: 'IDBBatchAtomicVFS' }),
remote: createSupabaseAdapter({
supabaseUrl: 'https://your-project.supabase.co',
supabaseKey: 'your-anon-key'
}),
syncType: 'pull-push'
});
2. 数据操作
// 创建
const todo = db.repository(Todo).create();
todo.title = 'Learn RxDB';
await todo.save();
// 查询
const todos = await db.repository(Todo).find({
where: {
combinator: 'and',
rules: [{ field: 'completed', operator: '=', value: false }]
}
});
// 同步
await db.versionManager.push(); // 推送本地变更到远程
await db.versionManager.pull(); // 拉取远程变更到本地
await db.versionManager.sync(); // 双向同步 (pull + push)
测试
前置条件
测试依赖本地 Supabase 环境,确保:
-
Docker 已安装并运行
-
启动 Supabase 测试容器:
cd dockerbash start.sh这会启动并初始化:
- PostgreSQL (端口 5432)
- Kong API Gateway (端口 8000)
- 创建必要的表和函数
-
环境变量配置: 测试自动使用以下配置:
VITE_SUPABASE_URL=http://localhost:8000VITE_SUPABASE_KEY=<anon-key>(见docker/.env)
运行测试
# 确保 Supabase 已启动
cd docker && bash start.sh
# 运行测试
nx test rxdb-adapter-supabase
# 带覆盖率
nx test rxdb-adapter-supabase --coverage
# 停止 Supabase
cd docker && bash stop.sh
常见问题:
-
❌
Could not find the table 'public.RxDBChange' in the schema cache- 原因:Supabase 容器未启动或数据库未初始化
- 解决:
cd docker && bash start.sh
-
❌
Connection refused at localhost:8000- 原因:Kong API Gateway 未就绪
- 解决:等待
start.sh完成健康检查
数据库 Schema
Supabase 适配器需要以下表结构:
RxDBChange (变更追踪表)
CREATE TABLE "RxDBChange" (
"id" BIGSERIAL PRIMARY KEY,
"branchId" TEXT NOT NULL,
"entityType" TEXT NOT NULL,
"entityId" TEXT NOT NULL,
"type" TEXT NOT NULL, -- INSERT/UPDATE/DELETE
"patch" JSONB,
"remoteId" BIGINT,
"revertChangeId" BIGINT,
"createdAt" TIMESTAMPTZ DEFAULT NOW(),
"updatedAt" TIMESTAMPTZ DEFAULT NOW()
);
RxDBBranch (分支元数据)
CREATE TABLE "RxDBBranch" (
"id" TEXT PRIMARY KEY,
"dbName" TEXT NOT NULL,
"context" JSONB,
"lastPushedChangeId" BIGINT,
"lastPullRemoteChangeId" BIGINT,
"createdAt" TIMESTAMPTZ DEFAULT NOW(),
"updatedAt" TIMESTAMPTZ DEFAULT NOW()
);
业务表示例
CREATE TABLE "Todo" (
"id" TEXT PRIMARY KEY,
"title" TEXT NOT NULL,
"completed" BOOLEAN DEFAULT FALSE,
"createdAt" TIMESTAMPTZ DEFAULT NOW(),
"updatedAt" TIMESTAMPTZ DEFAULT NOW()
);
-- 自动创建变更记录的触发器
CREATE TRIGGER rxdb_sync_trigger
AFTER INSERT OR UPDATE OR DELETE ON "Todo"
FOR EACH ROW EXECUTE FUNCTION rxdb_sync_change();
完整 SQL 脚本位于 docs/api/_media/sql/ 目录。
API
RxDBAdapterSupabase
class RxDBAdapterSupabase {
constructor(rxdb: RxDB, options: SupabaseAdapterOptions);
// 连接管理
connect(): Promise<IRxDBAdapter>;
disconnect(): Promise<void>;
// 同步操作
pullChanges(options: PullOptions): Promise<RemoteChange[]>;
pushChanges(changes: LocalChange[]): Promise<PushResult>;
// 批量操作
saveMany<T>(entities: T[]): Promise<T[]>;
removeMany<T>(entities: T[]): Promise<void>;
mutations(map: RxDBMutationsMap): Promise<void>;
}
SupabaseRepository
class SupabaseRepository<T> {
// CRUD
create(): T;
find(options?: FindOptions): Promise<T[]>;
findOne(options?: FindOptions): Promise<T | null>;
count(options?: FindOptions): Promise<number>;
// 批量
saveMany(entities: T[]): Promise<T[]>;
removeMany(entities: T[]): Promise<void>;
}
SupabaseTreeRepository
class SupabaseTreeRepository<T> extends SupabaseRepository<T> {
// 树形操作
findDescendants(entity: T, depth?: number): Promise<T[]>;
findAncestors(entity: T): Promise<T[]>;
findRoots(): Promise<T[]>;
}
架构
┌─────────────────────────────────────────────────────────────┐
│ RxDB Core │
│ ┌────────────┐ ┌────────────┐ ┌──────────────────────┐ │
│ │ Repository │ │VersionMgr │ │ SchemaManager │ │
│ └─────┬──────┘ └─────┬──────┘ └──────────────────────┘ │
└────────┼───────────────┼─────────────────────────────────────┘
│ │
▼ ▼
┌─────────────────────────────────────────────────────────────┐
│ RxDBAdapterSupabase (Remote) │
│ ┌──────────────────────────────────────────────────────┐ │
│ │ SupabaseRepository │ │
│ │ - CRUD 操作 │ │
│ │ - 查询构建 (apply_rule_group) │ │
│ │ - 批量操作 │ │
│ └──────────────────────────────────────────────────────┘ │
│ ┌──────────────────────────────────────────────────────┐ │
│ │ Sync Engine │ │
│ │ - pullChanges: 拉取远程变更 │ │
│ │ - pushChanges: 推送本地变更 (带压缩) │ │
│ │ - mergeChanges: 通过 RPC 原子性写入 │ │
│ └──────────────────────────────────────────────────────┘ │
│ ┌──────────────────────────────────────────────────────┐ │
│ │ Realtime Subscription │ │
│ │ - 监听 RxDBChange 表 INSERT 事件 │ │
│ │ - 自动触发 pull 同步 │ │
│ └──────────────────────────────────────────────────────┘ │
└─────────────┬───────────────────────────────────────────────┘
│
▼
┌─────────────────────┐
│ Supabase (PostgreSQL) │
│ - RxDBChange │
│ - RxDBBranch │
│ - Business Tables │
│ - Triggers/RPCs │
└─────────────────────┘
同步机制
Push 流程
- 收集本地变更:从
RxDBChange表查询remoteId = null的记录 - 变更压缩:
INSERT→UPDATE*→ 单个INSERTINSERT→DELETE→ 丢弃UPDATE*→DELETE→ 单个DELETE
- 调用 RPC:通过
rxdb_mutations()原子性写入 - 更新元数据:记录
lastPushedChangeId
Pull 流程
- 查询远程变更:
id > lastPullRemoteChangeId且branchId != current - 应用到本地实体表:
INSERT→ 插入UPDATE→ 更新DELETE→ 删除
- 写入本地 RxDBChange:标记
remoteId避免重复 push - 更新元数据:记录
lastPullRemoteChangeId
开发
# 构建
nx build rxdb-adapter-supabase
# 格式化
nx format:write --projects=rxdb-adapter-supabase
# Lint
nx lint rxdb-adapter-supabase
完整示例
参考 dev-rxdb-supabase 中的完整集成示例。
License
MIT
Classes
| Class | Description |
|---|---|
| RxDBAdapterSupabase | Supabase 适配器 |
| SupabaseConfigError | 配置错误 |
| SupabaseDataError | 数据错误 |
| SupabaseNetworkError | 网络错误 |
| SupabaseRepository | Supabase Repository 提供对 Supabase 表的 CRUD 操作 |
| SupabaseSyncError | Supabase 同步错误基类 |
| SupabaseTreeRepository | Supabase Tree Repository 提供树形结构的查询操作 |
Interfaces
| Interface | Description |
|---|---|
| SupabaseAdapterOptions | Supabase Adapter 配置选项 |
| SupabaseRlsCheckOptions | - |
| SupabaseRlsCheckTable | - |
Variables
| Variable | Description |
|---|---|
| ADAPTER_NAME | - |