核心内容摘要
Smocker未来路线图:即将发布的7个令人期待的新功能
核心定位纯前端 / Node.js 通用的实时协作数据一致性库基于 CRDT无冲突复制数据类型实现核心解决「多人同时修改数据、断网离线修改数据」后的数据自动统一问题是前端开发在线文档、白板、表格等协作类应用的核心工具也是 BlockSuite 实时协作能力的底层内核。
简单说给普通 JS 数据加「协作外挂」改数据时自动同步、自动解决冲突开发者不用写分布式、冲突解决、数据同步的代码专注业务即可。
核心特性大白话版CRDT 底层无需服务端强同步每个客户端存一份完整数据副本冲突本地自动计算最终所有设备数据一致对比 OT 技术不用服务端做复杂操作转换开发更简单。
兼容前端常用数据类型支持数组、键值对、树形结构等操作方法和普通 JS 数据几乎一致低成本替换原有数据。
通信完全解耦只负责「生成同步的小数据片段」不管「数据怎么传」WebSocket、WebRTC、小程序通信等都能适配。
原生支持离线编辑自动将数据存在浏览器 IndexedDB断网修改不丢失联网后自动重连并同步本地修改。
前端无缝集成TS/JS 原生支持体积小和 Vue/React/ 原生前端、Web Components 都能完美搭配。
核心依赖安装bash运行# 核心库必须装 npm install yjs # 官方 WebSocket 通信插件快速实现多人协作无需自己开发服务端推荐必装 npm install y-websocket
核心概念3 个核心记牢即可
Y.Doc - 共享数据容器所有 Yjs 共享数据的根容器是协作的核心入口。
每个协作文档对应一个唯一标识不同客户端用相同标识就能同步数据每个客户端都要创建一份 Y.Doc内部维护分布式共享数据。
共享数据类型 - 替换普通 JS 数据Yjs 提供专属的「共享数据类型」替换原有 JS 数组 / 对象 / 树操作方法几乎一致修改后会自动标记同步片段。
Yjs 共享类型对应普通 JS 类型适用场景Y.Array数组存列表数据如 BlockSuite 块列表Y.Map对象 / Map存键值对数据如用户信息、块属性Y.XmlFragment/Y.XmlElement树形结构存层级数据如 BlockSuite 块树、富文本节点
observe - 数据变化监听监听共享数据的所有修改本地修改 / 远端协作方修改都会触发是「数据驱动视图」的核心通过监听事件实现视图精准更新。
核心代码片段极简实用直接复制可运行片段 1基础使用 - 创建共享数据 本地修改监听实现普通 JS 数据的「共享化」掌握基础的增删改和监听逻辑。
javascript运行import * as Y from yjs; //
创建共享文档容器 const yDoc new Y.Doc(); //
创建共享数据替换普通 JS 数组/Map const yArr yDoc.getArray(myList); // 共享数组 const yMap yDoc.getMap(myInfo); // 共享键值对 //
监听数据变化本地/远端修改统一触发 yArr.observe((event) { console.log(数组数据变化, event); console.log(最新数组转普通 JS, yArr.toArray()); // 转普通 JS 供视图渲染 }); //
操作共享数据和普通 JS 用法几乎一致 yArr.push([苹果, 香蕉]); // 新增元素 yArr.set(0, 红苹果); // 修改元素 yMap.set(author, 张
; // Map 设值 //
转换为普通 JS 数据视图渲染专用Yjs 数据不能直接绑视图 console.log(yArr.toArray()); // [红苹果, 香蕉] console.log(yMap.toJSON()); // { author: 张三 }片段 2多人协作核心 - WebSocket 通信桥接3 行代码实现多端同步不用自己开发服务端打开多个浏览器窗口即可测试协作效果。
javascript运行import * as Y from yjs; import { WebsocketProvider } from y-websocket; //
创建共享文档 const yDoc new Y.Doc(); const yArr yDoc.getArray(collabList); //
连接官方测试服务端一键实现通信无需自己搭服务 // 格式WebsocketProvider(服务端地址, 协作文档唯一标识, Yjs文档) const provider new WebsocketProvider( wss://demos.yjs.dev, // Yjs 官方免费测试服务端 my-first-collab-doc, // 同一协作文档用相同标识不同客户端自动同步 yDoc ); //
监听协作连接状态可选做加载/离线提示 provider.on(status, (event) { console.log(协作连接状态, event.status); // connected / disconnected / connecting }); //
任意客户端修改其他客户端实时同步 yArr.push([协作数据1, 协作数据2]);片段 3精准监听 - 增 / 删 / 改单独处理适配视图精准更新实际开发无需全量渲染视图通过 Yjs 事件精准获取「哪里变了、变了什么」实现 BlockSuite 同款「精准视图更新」。
javascript运行import * as Y from yjs; const yDoc new Y.Doc(); const yBlocks yDoc.getArray(blocks); // 模拟 BlockSuite 块列表 // 精准监听数组的增、删、改 yBlocks.observe((event) { //
新增元素[索引, 元素值] event.changes.added.forEach(([index, value]) { console.log(索引${index}新增, value); // 业务操作新增对应视图节点如 BlockSuite 新增块 }); //
更新元素仅返回索引值从 yBlocks.get(index) 获取 event.changes.updated.forEach((index) { const updateValue yBlocks.get(index); console.log(索引${index}更新为, updateValue); // 业务操作更新对应视图节点精准渲染 }); //
删除元素[索引, 被删值] event.changes.deleted.forEach(([index, value]) { console.log(索引${index}删除, value); // 业务操作删除对应视图节点 }); }); // 测试操作分别触发 added/updated/deleted yBlocks.push([{ id: 1, content: 测试块1 }]); yBlocks.set(0, { id: 1, content: 修改后的块1 }); yBlocks.delete(
;片段 4离线编辑 自动重连原生支持无需额外代码Yjs 自动将数据存在浏览器 IndexedDB断网修改不丢失联网后自动同步全程无需自己写本地存储、重连逻辑。
javascript运行import * as Y from yjs; import { WebsocketProvider } from y-websocket; const yDoc new Y.Doc(); const yArr yDoc.getArray(offlineList); const provider new WebsocketProvider(wss://demos.yjs.dev, offline-doc, yDoc); // 断网后正常修改数据自动存在本地 IndexedDB yArr.push([断网编辑的内容1, 断网编辑的内容2]); // 联网后自动重连将本地修改同步给服务端/其他客户端无需额外代码片段 5树形结构使用和 BlockSuite 块树深度适配BlockSuite 的「块树」是核心Yjs 用Y.XmlFragment/Y.XmlElement实现分布式树形结构完美贴合块的父子层级关系。
javascript运行import * as Y from yjs; const yDoc new Y.Doc(); // 创建共享树形结构模拟 BlockSuite 根块树 const yBlockTree yDoc.getXmlFragment(blockTree); //