# @dabble/patches 中文文档

规范地址：https://npmcn.com/package/%40dabble/patches/

版本：0\.34\.2
npm 元数据更新时间：2026-10-26T20:25:24.361Z
中文译文更新时间：2026-11-14T08:00:16.088Z
软件包许可：MIT

本文由上游 README 翻译，可能存在偏差，请结合原文核对 API、命令与配置。版权与许可归原作者所有。

原始 npm 页面：https://www.npmjs.com/package/%40dabble/patches
原文对照：https://npmcn.com/package/%40dabble/patches/?lang=original
项目主页：https://github.com/dabblewriter/patches/
源码仓库：https://github.com/dabblewriter/patches

## 关键信息（来自 npm 元数据）

- 包体积（解压后）：1.5 MB，313 个文件
- 模块格式：ES Module
- TypeScript 类型：包内自带
- 运行依赖：6 个
- peer 依赖：vue ^3\.3\.0，solid-js ^1\.8\.0
- 首次发布：2025-04-18T16:36:22.706Z
- 最新版本发布：2026-10-26T20:25:23.272Z
- 近 30 天下载量：2113（2026-10-11 至 2026-11-09，npm 官方下载统计）
- 已发布版本数：191（近 12 个月 151 个）

## 中文简介

基于RFC 6902支持业务转型和最后写作胜负的不可移动 JSON 补丁执行

## 安装

```sh
npm install @dabble/patches
```

也可以使用：`pnpm add @dabble/patches`、`yarn add @dabble/patches`、`bun add @dabble/patches`

## README

# 补丁

一个用于构建实时协作应用程序的TypeScript库. 您得到了两个同步策略: 协作文本的操作转换, 以及其它的 Last-Write-Wins .

![Patches the Dog](https://npmcn.com/package/%40dabble/patches/patches.png)

## 这能解决什么问题?

建设实时协作功能难度大. 用户同时编辑,连接会降低中位变化,冲突解决速度会很快. 补丁处理这一切,所以你不必.

你的文档状态只是JSON。 用简单的回调更改它 :

```js
doc.change(state => (state.title = 'New Title'));
```

更改立即适用于快速用户界面,然后同步到背景中的服务器。 离线? 没问题 重新上线时更改队列并同步 .

## 范围:补丁是什么和不是

补丁是一个 **一般原始文献库**它为实时系统提供组件(OT,LWW,同步传输,doc-store接口). 把它编成自己的后端和前端.

补丁知道:

-   JSON文件、JSON补丁操作和快照
-   业务转型和最后写出冲突解决办法
-   传送面 (WebSocket, SSE+REST, WebRTC) 移动客户端和服务器之间的变化
-   HTTP 状态代码以 `StatusError` (401, 403, 404, 410) — 如此消耗的应用程序可以在响应上分出

补丁确实如此 **没有** 了解情况:

-   用户、角色、邀请、成员或任何访问控制模式
-   应用软件、项目、书籍、文件成品或任何特定应用术语
-   电子邮件发送、姓名/电子邮件查询或任何身份服务
-   失去访问权限时如何操作的 UX 政策( 耗用应用程序决定 403 是否意味着“ 显示一面旗帜 ” 、 “ 踢出 医生 ” , 或是其它任何内容)

如果一个特性感觉它属于Patches,但提到了一个应用概念(例如"一个项目的邀请"),它不属于这里——它属于一个级别上,在应用自己的客户端SDK或消费应用本身. 帕奇斯表面应该足够通用,可以支持任何实时系统.

## 两个同步策略

补丁给你两种解决冲突的方法。 为工作选择合适的工具.

**[业务转型(OT)](https://npmcn.com/package/%40dabble/patches/docs/operational-transformation.md)** - 当用户同时编辑相同内容时

-   变化被明智地合并
-   需要合作编辑文本
-   示例: Google Docs 类协作

**[最后写- Wins (LWW)](https://npmcn.com/package/%40dabble/patches/docs/last-write-wins.md)** - 当最新的时标获胜

-   更简单,更快,更可预测
-   最适合设置、仪表板、画布对象
-   [图片使用这种方法](https://www.figma.com/blog/how-figmas-multiplayer-technology-works/) 他们的多人游戏

**决定很简单:** 如果用户不编辑相同 _文本_ 合作使用 LWW。 它更快,更容易调试,并完美地处理大多数实时的情景.

需要LWW订购名单吗? 使用 [分数索引](https://npmcn.com/package/%40dabble/patches/docs/fractional-indexing.md) 维持秩序,没有OT.

大多数应用程序都使用两种策略:OT用于文档内容,LWW用于其他一切.

## 目录

-   [为什么是业务转型?](https://npmcn.com/package/%40dabble/patches/#readme-why-operational-transformations)
-   [关键概念](https://npmcn.com/package/%40dabble/patches/#readme-key-concepts)
-   [安装](https://npmcn.com/package/%40dabble/patches/#readme-installation)
-   [开始](https://npmcn.com/package/%40dabble/patches/#readme-getting-started)
    -   [客户端示例](https://npmcn.com/package/%40dabble/patches/#readme-client-example)
    -   [服务器示例](https://npmcn.com/package/%40dabble/patches/#readme-server-example)
    -   [LWW 快速启动](https://npmcn.com/package/%40dabble/patches/#readme-lww-quick-start)
-   [核心组成部分](https://npmcn.com/package/%40dabble/patches/#readme-core-components)
-   [基本工作流程](https://npmcn.com/package/%40dabble/patches/#readme-basic-workflow)
-   [实例](https://npmcn.com/package/%40dabble/patches/#readme-examples)
-   [高级主题](https://npmcn.com/package/%40dabble/patches/#readme-advanced-topics)
-   [捐款](https://npmcn.com/package/%40dabble/patches/#readme-contributing)
-   [许可证](https://npmcn.com/package/%40dabble/patches/#readme-license)

## 为什么是业务转型?

"我不该用CRDT吗?"

还有 [数量](https://thom.ee/blog/crdt-vs-operational-transformation/) 联 合 国 [意见](https://www.tiny.cloud/blog/real-time-collaboration-ot-vs-crdt/) 关于 [这个](https://fiberplane.com/blog/why-we-at-fiberplane-use-operational-transformation-instead-of-crdt/)我们在这里学到了什么 [达布尔作家](https://www.dabblewriter.com/): CRDTs对长寿文档不进行缩放.

我们的一些用户有48万+操作的项目. 这些怪物花了几个小时重建 [叶杰斯](https://yjs.dev/),在最优化的Y.js中负载为~4秒,而~20ms则会添加变化. 我们的OT图书馆? **负载为1-2ms并适用了0.2ms.**

随着文件体积增大或寿命延长,OT性能保持平平而CRDTs减速. 对于大多数使用的案例,CRDTs的工作都很好. 但是,如果你正在建设 规模或长寿,OT赢得.

## 关键概念

**集中式OT** - 一个服务器充当真相的唯一来源。 没有对等复杂,没有向量钟,没有分布式共识头痛. 服务器查看所有变化的顺序,并广播犬科状态.

**重置基础** - 当服务器有新的更改时, 您的客户端还没有看到, 您的待定更改会得到“ 重置” 上面 。 考虑一下 `git rebase`,但用于实时编辑.

**线性历史** - 服务器维持一个直线 没有分支,没有叉子,没有基础设施层面的合并冲突.

**抓图** - OT文档随时间而累积变化。 为了避免重放480k操作载荷,我们定期快照. 装入最新的快照, 应用最近的修改, 完成 .

**不稳定的国家** - 每一个变化都会产生一个新的状态对象。 未改变的部分保持不变。 这使得React/Vue/Solid变得微不足道并能够进行廉价的平等检查.

更多信息: [业务转型深潜](https://npmcn.com/package/%40dabble/patches/docs/operational-transformation.md) | [算法函数](https://npmcn.com/package/%40dabble/patches/docs/algorithms.md)

## 安装

```bash
npm install @dabble/patches
```

## 开始

### 客户端示例

```typescript
import { Patches, OTStrategy, InMemoryStore } from '@dabble/patches';
import { PatchesSync } from '@dabble/patches/net';

interface MyDoc {
  text: string;
  count: number;
}

// 1. Create a strategy with its store
const strategy = new OTStrategy(new InMemoryStore());

// 2. Create the Patches instance
const patches = new Patches({
  strategies: { ot: strategy },
  defaultStrategy: 'ot',
});

// 3. Set up real-time sync
const sync = new PatchesSync(patches, 'wss://your-server-url');
await sync.connect();

// 4. Open a document
const doc = await patches.openDoc<MyDoc>('my-doc-1');

// 5. React to updates
doc.subscribe(newState => {
  console.log('Document updated:', newState);
  // Update your UI here
});

// 6. Make changes - they sync automatically
doc.change(draft => {
  draft.text = 'Hello World!';
  draft.count = (draft.count || 0) + 1;
});
```

见 [补丁](https://npmcn.com/package/%40dabble/patches/docs/Patches.md), (中文(简体) ), [补丁文件](https://npmcn.com/package/%40dabble/patches/docs/PatchesDoc.md),以及 [补丁同步](https://npmcn.com/package/%40dabble/patches/docs/PatchesSync.md) 用于完整的API文档.

### 服务器示例

```typescript
import express from 'express';
import { OTServer } from '@dabble/patches/server';

// Your backend store implementation
const store = new MyOTStoreBackend();
const server = new OTServer(store);

const app = express();
app.use(express.json());

// Get document state
app.get('/docs/:docId', async (req, res) => {
  const { state, rev } = await server.getDoc(req.params.docId);
  res.json({ state: state ?? {}, rev });
});

// Commit changes
app.post('/docs/:docId/changes', async (req, res) => {
  try {
    const changes = await server.commitChanges(req.params.docId, req.body.changes);
    res.json(changes);
    // Broadcast to other clients via WebSocket
  } catch (error) {
    const status = error.message.includes('out of sync') ? 409 : 500;
    res.status(status).json({ error: error.message });
  }
});

app.listen(3000);
```

见 [服务员](https://npmcn.com/package/%40dabble/patches/docs/OTServer.md) 用于完整的API文档.

### LWW 快速启动

对于 Last-Write-Wins 同步, 请使用 LWW 特定商店和战略 :

```typescript
// Client
import { Patches, LWWStrategy, LWWInMemoryStore } from '@dabble/patches';
import { PatchesSync } from '@dabble/patches/net';

const strategy = new LWWStrategy(new LWWInMemoryStore());
const patches = new Patches({
  strategies: { lww: strategy },
  defaultStrategy: 'lww',
});

const sync = new PatchesSync(patches, 'wss://your-server-url');
await sync.connect();

const doc = await patches.openDoc<UserPrefs>('user-prefs');

doc.change(draft => {
  draft.theme = 'dark';
  draft.fontSize = 16;
});
```

```typescript
// Server
import { LWWServer } from '@dabble/patches/server';

const store = new MyLWWStoreBackend();
const server = new LWWServer(store);

app.post('/docs/:docId/changes', async (req, res) => {
  const result = await server.commitChanges(req.params.docId, req.body.changes);
  res.json(result);
});
```

见 [劳工服务员](https://npmcn.com/package/%40dabble/patches/docs/LWWServer.md) 财务报告和审定财务报表 [最后写- Wins 概念](https://npmcn.com/package/%40dabble/patches/docs/last-write-wins.md) 更多细节.

## 核心组成部分

### 客户端

**[补丁](https://npmcn.com/package/%40dabble/patches/docs/Patches.md)** - 主入口点。 管理文档生命周期,协调策略,处理持久性.

**[补丁文件](https://npmcn.com/package/%40dabble/patches/docs/PatchesDoc.md)** - 一份合作文件 音轨状态,乐观地应用变化,发布更新事件.

**[补丁同步](https://npmcn.com/package/%40dabble/patches/docs/PatchesSync.md)** - WebSocket 连接管理器。 处理重接,分批,双向同步.

**战略** - 算法特定逻辑:

-   `OTStrategy` -拥有一个 `OTClientStore`,处理重新定位和变化跟踪
-   `LWWStrategy` -拥有一个 `LWWClientStore`,处理时间戳合并

**存储** - 持久性适配器:

-   `InMemoryStore` 编号 : `LWWInMemoryStore` - 测试和简单的应用
-   `OTIndexedDBStore` 编号 : `LWWIndexedDBStore` - 有离线支持的浏览器持续

### 服务器侧

**[服务员](https://npmcn.com/package/%40dabble/patches/docs/OTServer.md)** - OT授权。 变换并行的更改,分配修改,保持历史.

**[劳工服务员](https://npmcn.com/package/%40dabble/patches/docs/LWWServer.md)** - LWW权威。 比较时间戳,存储当前字段值,没有历史.

**[补丁历史管理器](https://npmcn.com/package/%40dabble/patches/docs/PatchesHistoryManager.md)** - 查询文档版本和历史.

**[补丁缓冲管理器](https://npmcn.com/package/%40dabble/patches/docs/PatchesBranchManager.md)** - 创建、列出和合并分支.

**后端存储** - 为数据库执行这些接口:

-   `OTStoreBackend` - 对OT:更改、快照、版本
-   `LWWStoreBackend` - 关于LWW:有时间戳、快照的字段

见 [持久性](https://npmcn.com/package/%40dabble/patches/docs/persist.md) 用于存储模式和 [后端存储接口](https://npmcn.com/package/%40dabble/patches/docs/operational-transformation.md#backend-store-interface) 详细执行情况.

### 联网

**[WebSocket 运输](https://npmcn.com/package/%40dabble/patches/docs/websocket.md)** - 通过服务器进行的标准通信 `PatchesWebSocket`。 。 。 .

**[WebRTC 运输](https://npmcn.com/package/%40dabble/patches/docs/net.md)** - 提高认识的同龄人(诅咒、在场).

**[JSON-RPC议定书](https://npmcn.com/package/%40dabble/patches/docs/json-rpc.md)** - 客户端和服务器之间的电线协议.

什么时候用? 文档同步的 WebSocket 。 WebRTC 用于存在/ cursers 来减少服务器负载. 见 [联网概况](https://npmcn.com/package/%40dabble/patches/docs/net.md)。 。 。 .

### 意识( 频度和光标)

显示谁在线,光标在哪里,选择什么. `WebRTCAwareness` 在对等对等的WebRTC连接上携带存在,在您已经打开的同步频道上,信号握手多键 `WebSocketTransport` 或者说 `PatchesREST` (SSE+REST) (英语). 没有第二次连接, 相同 `clientId`。 。 。 .

见 [提高认识文件](https://npmcn.com/package/%40dabble/patches/docs/awareness.md) 详细执行情况.

## 基本工作流程

### 客户端

1.  创建一个 `Patches` 战略实例
2.  连接 `PatchesSync` 到您的服务器
3.  打开文档 `patches.openDoc(docId)`
4.  订阅更新 `doc.subscribe()`
5.  以 `doc.change()` - 它们自动同步

### 服务器

1.  创建 `OTServer` 或者说 `LWWServer` 用您的后端存储器
2.  处理 `commitChanges()` 请求
3.  向其他客户广播承诺的更改
4.  可选使用 `PatchesHistoryManager` 用于版本和 `PatchesBranchManager` 用于分支

## 实例

### 完成客户端设置

```typescript
import { Patches, OTStrategy, OTIndexedDBStore } from '@dabble/patches';
import { PatchesSync } from '@dabble/patches/net';

interface MyDoc {
  title: string;
  content: string;
}

// Production setup with IndexedDB for offline support
const strategy = new OTStrategy(new OTIndexedDBStore('my-app'));
const patches = new Patches({
  strategies: { ot: strategy },
});

const sync = new PatchesSync(patches, 'wss://api.example.com/sync');

// Handle connection state
sync.subscribe(state => {
  if (state.connected) {
    console.log('Connected and syncing');
  } else if (!state.online) {
    console.log('Offline - changes saved locally');
  }
});

// Handle errors
sync.onError((error, context) => {
  console.error(`Sync error for ${context?.docId}:`, error);
});

await sync.connect();

// Open and use a document
const doc = await patches.openDoc<MyDoc>('doc-123');

doc.subscribe(state => {
  renderUI(state);
});

doc.change(draft => {
  draft.title = 'My Document';
  draft.content = 'Hello, world!';
});
```

### 使用两种战略

```typescript
import { Patches, OTStrategy, LWWStrategy, InMemoryStore, LWWInMemoryStore } from '@dabble/patches';

// Configure both strategies
const patches = new Patches({
  strategies: {
    ot: new OTStrategy(new InMemoryStore()),
    lww: new LWWStrategy(new LWWInMemoryStore()),
  },
  defaultStrategy: 'ot',
});

// OT for collaborative document editing
const manuscript = await patches.openDoc('manuscript-123'); // Uses default (ot)

// LWW for user settings
const settings = await patches.openDoc('settings-user-456', { strategy: 'lww' });
```

## 高级主题

### 版本历史( H)

文档在30分钟后自动快照. 浏览版本为 `PatchesHistoryManager`。 。 。 .

见 [OTServer 版本](https://npmcn.com/package/%40dabble/patches/docs/OTServer.md#versioning) 财务报告和审定财务报表 [补丁历史管理器](https://npmcn.com/package/%40dabble/patches/docs/PatchesHistoryManager.md)。 。 。 .

### 分支

创建文档分支,在隔离状态下工作,后合并. 用于"如果"情景或舞台编辑.

见 [分支](https://npmcn.com/package/%40dabble/patches/docs/branching.md) 财务报告和审定财务报表 [补丁缓冲管理器](https://npmcn.com/package/%40dabble/patches/docs/PatchesBranchManager.md)。 。 。 .

### 共享工人

在共享工作人中运行补丁,用于交叉调制协调并减少内存使用.

见 [共享工人文档](https://npmcn.com/package/%40dabble/patches/docs/shared-worker.md)。 。 。 .

### 框架整合

-   **第3组**: 见 [弧度/湿度/README.md](https://npmcn.com/package/%40dabble/patches/src/vue/README.md)
-   **实相.js**: 见 [弧/固体/README.md](https://npmcn.com/package/%40dabble/patches/src/solid/README.md)

### 自定义 OT 操作

扩展操作处理器用于特定域的转换.

见 [操作处理器](https://npmcn.com/package/%40dabble/patches/docs/operational-transformation.md#operation-handlers)。 。 。 .

### JSON 补丁

补丁使用JSON Patch (RFC 6902) 在罩下. 你很少需要直接使用它,但它就在那里.

见 [JSON 补丁文档](https://npmcn.com/package/%40dabble/patches/docs/json-patch.md)。 。 。 .

## 捐款

欢迎捐款。 开放问题或提交拉力请求.

## 许可证

[麻省理工学院](https://npmcn.com/package/%40dabble/patches/LICENSE_MIT)

## 常见问题

### @dabble/patches 是什么？

基于RFC 6902支持业务转型和最后写作胜负的不可移动 JSON 补丁执行

### 如何安装 @dabble/patches？

在项目目录运行 npm install @dabble/patches，或使用 pnpm add / yarn add / bun add。

### @dabble/patches 支持 TypeScript 吗？

支持。包内自带 TypeScript 类型声明（package\.json 声明了 types 入口），安装后即可获得类型提示，无需再安装 @types 包。

### @dabble/patches 支持 ESM 还是 CommonJS？

以 ES Module 形式发布，推荐使用 import 引入。在 CommonJS 项目中，Node\.js 20\.19\+ / 22\.12\+ 可以直接 require\(\) 不含顶层 await 的 ES Module，更早的版本需要改用动态 import\(\)。

### @dabble/patches 可以商用吗？

@dabble/patches 使用 MIT 许可。宽松许可：允许商业使用、修改和再分发，通常只需在分发时保留原版权与许可声明。以上为概括，不构成法律意见，请以许可原文为准。

### @dabble/patches 的下载量有多少？

根据 npm 官方下载统计，@dabble/patches 在 2026/10/11 – 2026/11/09 这 30 天内被下载 2,113 次，日均约 70 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入，适合横向比较热度，不能直接等同于使用人数。

### @dabble/patches 还在维护吗？

最新版本 0\.34\.2 发布于 2026/10/27（18 天前）；至今共发布 191 个版本，其中过去 12 个月发布了 151 个；首次发布于 2025/04/19。发布频率只是参考信号：功能稳定的工具可能很少需要更新，建议结合源码仓库的 issue 和提交记录判断。

