|
9 | 9 |
|
10 | 10 | ## 在线协同演示 |
11 | 11 |
|
12 | | -整个协同编辑系统由三部分组成:前端 `TinyEditor`、中间层协作引擎 `Yjs` 和后端服务(用于数据同步和持久化)。前端编辑器将操作传递给 `Yjs`,`Yjs` 通过不同的连接协议(如 `WebSocket` 或 `WebRTC`)实现多端同步, 并支持将数据持久化到后端数据库(如 `MongoDB`)。 |
| 12 | +整个协同编辑系统由三部分组成:前端 `TinyEditor`、中间层协作引擎 `Yjs` 和后端服务(用于数据同步和持久化)。前端编辑器将操作传递给 `Yjs`,`Yjs` 通过不同的连接协议(如 `WebSocket` 或 `WebRTC`)实现多端同步, 并支持将数据持久化到后端数据库(如 `MongoDB`). |
| 13 | + |
13 | 14 | <img src="/Collab-arch.png" alt="Tiny-editor-demo"> |
14 | 15 |
|
15 | 16 | 下面是一个完整的协同编辑演示: |
|
29 | 30 | pnpm i quill-cursors y-protocols y-quill yjs y-indexeddb y-websocket |
30 | 31 | ``` |
31 | 32 |
|
32 | | -引入协同编辑模块 |
33 | | - |
34 | | -```javascript |
35 | | -import FluentEditor, { CollaborationModule } from '@opentiny/fluent-editor' |
36 | | -FluentEditor.register('modules/collaborative-editing', CollaborationModule, true) |
37 | | -``` |
38 | | - |
39 | | -编辑器基础配置: |
| 33 | +引入协同编辑模块和依赖 |
40 | 34 |
|
41 | 35 | ```javascript |
42 | | -const editor = new FluentEditor('#editor', { |
43 | | - theme: 'snow', |
44 | | - modules: { |
45 | | - 'collaborative-editing': { |
46 | | - provider: { |
47 | | - type: 'websocket', |
48 | | - options: { |
49 | | - serverUrl: 'ws://localhost:1234', |
50 | | - roomName: 'Tiny-Editor-Demo', |
| 36 | +import FluentEditor from '@opentiny/fluent-editor' |
| 37 | + |
| 38 | +let editor |
| 39 | +const editorRef = document.querySelector('#editor') |
| 40 | + |
| 41 | +Promise.all([ |
| 42 | + import('@opentiny/fluent-editor'), |
| 43 | + import('yjs'), |
| 44 | + import('y-protocols/awareness'), |
| 45 | + import('y-quill'), |
| 46 | + import('y-websocket'), |
| 47 | + import('y-indexeddb'), |
| 48 | + import('quill-cursors'), |
| 49 | +]).then( |
| 50 | + ([ |
| 51 | + { default: FluentEditor, CollaborationModule }, |
| 52 | + Y, |
| 53 | + { Awareness }, |
| 54 | + { QuillBinding }, |
| 55 | + { WebsocketProvider }, |
| 56 | + { IndexeddbPersistence }, |
| 57 | + { default: QuillCursors }, |
| 58 | + ]) => { |
| 59 | + FluentEditor.register('modules/collaborative-editing', CollaborationModule, true) |
| 60 | + |
| 61 | + editor = new FluentEditor(editorRef, { |
| 62 | + theme: 'snow', |
| 63 | + modules: { |
| 64 | + 'collaborative-editing': { |
| 65 | + deps: { Y, Awareness, QuillBinding, QuillCursors, WebsocketProvider, IndexeddbPersistence }, |
| 66 | + provider: { |
| 67 | + type: 'websocket', |
| 68 | + options: { |
| 69 | + serverUrl: 'wss://demos.yjs.dev/ws', |
| 70 | + roomName: 'Tiny-Editor-Demo', |
| 71 | + }, |
| 72 | + }, |
51 | 73 | }, |
52 | 74 | }, |
53 | | - }, |
| 75 | + }) |
54 | 76 | }, |
| 77 | +).catch((error) => { |
| 78 | + console.error('Failed to initialize FluentEditor:', error) |
55 | 79 | }) |
56 | 80 | ``` |
57 | 81 |
|
@@ -192,6 +216,7 @@ const editor = new FluentEditor('#editor', { |
192 | 216 | theme: 'snow', |
193 | 217 | modules: { |
194 | 218 | 'collaborative-editing': { |
| 219 | + deps: { Y, Awareness, QuillBinding, QuillCursors, WebsocketProvider, IndexeddbPersistence }, |
195 | 220 | provider: { |
196 | 221 | type: 'websocket', |
197 | 222 | options: { |
@@ -229,19 +254,49 @@ const editor = new FluentEditor('#editor', { |
229 | 254 | #### WebRTC 前端配置示例 |
230 | 255 |
|
231 | 256 | ```javascript |
232 | | -const editor = new FluentEditor('#editor', { |
233 | | - theme: 'snow', |
234 | | - modules: { |
235 | | - 'collaborative-editing': { |
236 | | - provider: { |
237 | | - type: 'webrtc', |
238 | | - options: { |
239 | | - roomName: 'Tiny-Editor-WebRTC', |
240 | | - signaling: ['wss://signaling.yjs.dev'], |
| 257 | +import FluentEditor from '@opentiny/fluent-editor' |
| 258 | +
|
| 259 | +let editor |
| 260 | +const editorRef = document.querySelector('#editor') |
| 261 | +
|
| 262 | +Promise.all([ |
| 263 | + import('@opentiny/fluent-editor'), |
| 264 | + import('yjs'), |
| 265 | + import('y-protocols/awareness'), |
| 266 | + import('y-quill'), |
| 267 | + import('y-webrtc'), |
| 268 | + import('y-indexeddb'), |
| 269 | + import('quill-cursors'), |
| 270 | +]).then( |
| 271 | + ([ |
| 272 | + { default: FluentEditor, CollaborationModule }, |
| 273 | + Y, |
| 274 | + { Awareness }, |
| 275 | + { QuillBinding }, |
| 276 | + { WebrtcProvider }, |
| 277 | + { IndexeddbPersistence }, |
| 278 | + { default: QuillCursors }, |
| 279 | + ]) => { |
| 280 | + FluentEditor.register('modules/collaborative-editing', CollaborationModule, true) |
| 281 | +
|
| 282 | + editor = new FluentEditor(editorRef, { |
| 283 | + theme: 'snow', |
| 284 | + modules: { |
| 285 | + 'collaborative-editing': { |
| 286 | + deps: { Y, Awareness, QuillBinding, QuillCursors, WebrtcProvider, IndexeddbPersistence }, |
| 287 | + provider: { |
| 288 | + type: 'webrtc', |
| 289 | + options: { |
| 290 | + roomName: 'Tiny-Editor-WebRTC', |
| 291 | + signaling: ['wss://signaling.yjs.dev'], |
| 292 | + }, |
| 293 | + }, |
241 | 294 | }, |
242 | 295 | }, |
243 | | - }, |
| 296 | + }) |
244 | 297 | }, |
| 298 | +).catch((error) => { |
| 299 | + console.error('Failed to initialize FluentEditor:', error) |
245 | 300 | }) |
246 | 301 | ``` |
247 | 302 |
|
@@ -425,6 +480,7 @@ const editor = new FluentEditor('#editor', { |
425 | 480 | theme: 'snow', |
426 | 481 | modules: { |
427 | 482 | 'collaborative-editing': { |
| 483 | + deps: { Y, Awareness, QuillBinding, QuillCursors, WebsocketProvider, IndexeddbPersistence }, |
428 | 484 | cursors: { |
429 | 485 | template: ` |
430 | 486 | <span class="${CURSOR_CLASSES.SELECTION_CLASS}"></span> |
|
0 commit comments