扫一扫分享
Yjs 是一个CRDT 实现,它将其内部数据结构公开为共享类型。共享类型是常见的数据类型,类似于Map 或Array具有超能力:更改会自动分发到其他对等点并合并而不会发生合并冲突。
Yjs 对使用者提供了如 YText、YArray 和 YMap 等常用数据类型(即所谓的 Shared Types,这里把它们统称为 YModel),可以直接作为应用的 model 层使用:
import * as Y from 'yjs'
// 应用中的全部协作状态均可在单个 YDoc 容器中承载
// 将该实例传入 WebSocket 等协议的 provider 后即可支持网络同步
const doc = new Y.Doc()
// 在 YDoc 上可以创建不同类型的顶层 YModel 实例
// 这里创建了一个顶层名为 root 的 YMap
const yRoot = doc.getMap('root')
// 也可以用 class 构造器来实例化独立的 YMap 等 YModel
// 可直接用 get set delete 等常见 api 对 YModel 增删改查
const yPoint = new Y.Map()
yPoint.set('x', 0)
yPoint.set('y', 0)
// YMap 的值也可以是 YMap,从而构造出嵌套的数据类型
yRoot.set('point', yPoint)
// YMap 中还可以存入 YText 等其他 YModel,形成复合的数据类型
const yName = new Y.Text()
yName.insert(0, 'Wilson Edwards')
yRoot.set('name', yName)
这套 API 表面看起来平淡无奇,但它真正的强大之处在于 Conflict-free,亦即对上层而言,并发更新时潜在的状态冲突已经被 Yjs 自动解决了:
// 可以用 2 份独立的 YDoc 实例来模拟 2 个客户端
const doc1 = new Y.Doc()
const doc2 = new Y.Doc()
const yText1 = doc1.getText()
const yText2 = doc2.getText()
// 在某份 YDoc 更新时,应用二进制的 update 数据到另一份 YDoc 上
doc1.on('update', (update) => Y.applyUpdate(doc2, update))
doc2.on('update', (update) => Y.applyUpdate(doc1, update))
// 制造两次存在潜在冲突的更新
yText1.insert(0, 'Edwards')
yText2.insert(0, 'Wilson')
// CRDT 算法可保证两份客户端中的状态始终一致
yText1.toJSON() // WilsonEdwards
yText2.toJSON() // WilsonEdwards
透过这些 Yjs 表层 API 的例子,我们应该已经可以认识到 CRDT 的威力所在了。
Serenity Notes端到端加密协作笔记应用程序。
Relm一个用于团队合作和社区的协作游戏世界。
Input协作笔记应用程序。
Room.sh具有集成协作绘图、编辑和编码工具的会议应用程序。
https://coronavirustechhandbook.com/一个协作维基,由数千名不同的人编辑,致力于对冠状病毒的爆发和随后的影响做出快速而复杂的反应。
Nimbus Note由 Nimbus Web 设计的笔记应用程序。
JoeDocs一个开放的协作维基。
Pluxbox RadioManager一个基于网络的应用程序,用于协作组织无线电广播。
Alldone下一代项目管理和协作平台。
手机预览