-
-
Notifications
You must be signed in to change notification settings - Fork 4k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: support document apply remote events
- Loading branch information
Showing
33 changed files
with
370 additions
and
142 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
3 changes: 2 additions & 1 deletion
3
frontend/appflowy_web_app/src/application/folder-yjs/folder.type.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,8 +1,9 @@ | ||
export enum CoverType { | ||
NormalColor = 'color', | ||
GradientColor = 'gradient', | ||
BuildInImage = 'none', | ||
BuildInImage = 'built_in', | ||
CustomImage = 'custom', | ||
LocalImage = 'local', | ||
UpsplashImage = 'unsplash', | ||
None = 'none', | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
67 changes: 67 additions & 0 deletions
67
frontend/appflowy_web_app/src/application/slate-yjs/utils/__tests__/applyRemoteEvents.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
import { | ||
CollabOrigin, | ||
YBlocks, | ||
YChildrenMap, | ||
YjsEditorKey, | ||
YMeta, | ||
YSharedRoot, | ||
YTextMap, | ||
} from '@/application/collab.type'; | ||
import { yDocToSlateContent } from '@/application/slate-yjs/utils/convert'; | ||
import { generateId, withTestingYDoc, withTestingYjsEditor } from './withTestingYjsEditor'; | ||
import { createEditor } from 'slate'; | ||
import { expect } from '@jest/globals'; | ||
import * as Y from 'yjs'; | ||
|
||
export async function runApplyRemoteEventsTest() { | ||
const pageId = generateId(); | ||
const remoteDoc = withTestingYDoc(pageId); | ||
const remote = withTestingYjsEditor(createEditor(), remoteDoc); | ||
|
||
const localDoc = new Y.Doc(); | ||
|
||
Y.applyUpdateV2(localDoc, Y.encodeStateAsUpdateV2(remoteDoc)); | ||
const editor = withTestingYjsEditor(createEditor(), localDoc); | ||
|
||
editor.connect(); | ||
expect(editor.children).toEqual(remote.children); | ||
|
||
// update remote doc | ||
insertBlock(remoteDoc, generateId(), pageId, 0); | ||
remote.children = yDocToSlateContent(remoteDoc)?.children ?? []; | ||
|
||
// apply remote changes to local doc | ||
Y.transact( | ||
localDoc, | ||
() => { | ||
Y.applyUpdateV2(localDoc, Y.encodeStateAsUpdateV2(remoteDoc)); | ||
}, | ||
CollabOrigin.Remote | ||
); | ||
|
||
expect(editor.children).toEqual(remote.children); | ||
} | ||
|
||
function insertBlock(doc: Y.Doc, blockId: string, parentId: string, index: number) { | ||
const sharedRoot = doc.getMap(YjsEditorKey.data_section) as YSharedRoot; | ||
const document = sharedRoot.get(YjsEditorKey.document); | ||
const blocks = document.get(YjsEditorKey.blocks) as YBlocks; | ||
const meta = document.get(YjsEditorKey.meta) as YMeta; | ||
const childrenMap = meta.get(YjsEditorKey.children_map) as YChildrenMap; | ||
const textMap = meta.get(YjsEditorKey.text_map) as YTextMap; | ||
|
||
const block = new Y.Map(); | ||
|
||
block.set(YjsEditorKey.block_id, blockId); | ||
block.set(YjsEditorKey.block_children, blockId); | ||
block.set(YjsEditorKey.block_type, 'paragraph'); | ||
block.set(YjsEditorKey.block_data, '{}'); | ||
block.set(YjsEditorKey.block_external_id, blockId); | ||
blocks.set(blockId, block); | ||
childrenMap.set(blockId, new Y.Array()); | ||
childrenMap.get(parentId).insert(index, [blockId]); | ||
const text = new Y.Text(); | ||
|
||
text.insert(0, 'Hello, World!'); | ||
textMap.set(blockId, text); | ||
} |
41 changes: 41 additions & 0 deletions
41
frontend/appflowy_web_app/src/application/slate-yjs/utils/__tests__/convert.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
import { withTestingYDoc, withTestingYjsEditor } from './withTestingYjsEditor'; | ||
import { yDocToSlateContent } from '../convert'; | ||
import { createEditor, Editor } from 'slate'; | ||
import { expect } from '@jest/globals'; | ||
import * as Y from 'yjs'; | ||
|
||
function normalizedSlateDoc(doc: Y.Doc) { | ||
const editor = createEditor(); | ||
|
||
const yjsEditor = withTestingYjsEditor(editor, doc); | ||
|
||
editor.children = yDocToSlateContent(doc)?.children ?? []; | ||
return yjsEditor.children; | ||
} | ||
|
||
export async function runCollaborationTest() { | ||
const doc = withTestingYDoc('1'); | ||
const editor = createEditor(); | ||
const yjsEditor = withTestingYjsEditor(editor, doc); | ||
|
||
// Keep the 'local' editor state before applying run. | ||
const baseState = Y.encodeStateAsUpdateV2(doc); | ||
|
||
Editor.normalize(editor, { force: true }); | ||
|
||
expect(normalizedSlateDoc(doc)).toEqual(yjsEditor.children); | ||
|
||
// Setup remote editor with input base state | ||
const remoteDoc = new Y.Doc(); | ||
|
||
Y.applyUpdateV2(remoteDoc, baseState); | ||
const remote = withTestingYjsEditor(createEditor(), remoteDoc); | ||
|
||
// Apply changes from 'run' | ||
Y.applyUpdateV2(remoteDoc, Y.encodeStateAsUpdateV2(yjsEditor.sharedRoot.doc!)); | ||
|
||
// Verify remote and editor state are equal | ||
expect(normalizedSlateDoc(remoteDoc)).toEqual(remote.children); | ||
expect(yjsEditor.children).toEqual(remote.children); | ||
expect(normalizedSlateDoc(doc)).toEqual(yjsEditor.children); | ||
} |
12 changes: 12 additions & 0 deletions
12
frontend/appflowy_web_app/src/application/slate-yjs/utils/__tests__/index.test.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
import { runCollaborationTest } from './convert'; | ||
import { runApplyRemoteEventsTest } from './applyRemoteEvents'; | ||
|
||
describe('slate-yjs adapter', () => { | ||
it('should pass the collaboration test', async () => { | ||
await runCollaborationTest(); | ||
}); | ||
|
||
it('should pass the apply remote events test', async () => { | ||
await runApplyRemoteEventsTest(); | ||
}); | ||
}); |
45 changes: 45 additions & 0 deletions
45
frontend/appflowy_web_app/src/application/slate-yjs/utils/__tests__/withTestingYjsEditor.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
import { CollabOrigin, YjsEditorKey, YSharedRoot } from '@/application/collab.type'; | ||
import { withYjs } from '@/application/slate-yjs'; | ||
import { Editor } from 'slate'; | ||
import * as Y from 'yjs'; | ||
import { v4 as uuidv4 } from 'uuid'; | ||
|
||
export function generateId() { | ||
return uuidv4(); | ||
} | ||
|
||
export function withTestingYjsEditor(editor: Editor, doc: Y.Doc) { | ||
const yjdEditor = withYjs(editor, doc, { | ||
localOrigin: CollabOrigin.LocalSync, | ||
}); | ||
|
||
return yjdEditor; | ||
} | ||
|
||
export function withTestingYDoc(docId: string) { | ||
const doc = new Y.Doc(); | ||
const sharedRoot = doc.getMap(YjsEditorKey.data_section) as YSharedRoot; | ||
const document = new Y.Map(); | ||
const blocks = new Y.Map(); | ||
const meta = new Y.Map(); | ||
const children_map = new Y.Map(); | ||
const text_map = new Y.Map(); | ||
const rootBlock = new Y.Map(); | ||
const blockOrders = new Y.Array(); | ||
const pageId = docId; | ||
|
||
sharedRoot.set(YjsEditorKey.document, document); | ||
document.set(YjsEditorKey.page_id, pageId); | ||
document.set(YjsEditorKey.blocks, blocks); | ||
document.set(YjsEditorKey.meta, meta); | ||
meta.set(YjsEditorKey.children_map, children_map); | ||
meta.set(YjsEditorKey.text_map, text_map); | ||
children_map.set(pageId, blockOrders); | ||
blocks.set(pageId, rootBlock); | ||
rootBlock.set(YjsEditorKey.block_id, pageId); | ||
rootBlock.set(YjsEditorKey.block_children, pageId); | ||
rootBlock.set(YjsEditorKey.block_type, 'page'); | ||
rootBlock.set(YjsEditorKey.block_data, '{}'); | ||
rootBlock.set(YjsEditorKey.block_external_id, ''); | ||
return doc; | ||
} |
7 changes: 0 additions & 7 deletions
7
frontend/appflowy_web_app/src/application/slate-yjs/utils/applySlateOpts.ts
This file was deleted.
Oops, something went wrong.
8 changes: 8 additions & 0 deletions
8
frontend/appflowy_web_app/src/application/slate-yjs/utils/applyToYjs.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
import { Operation, Node } from 'slate'; | ||
import * as Y from 'yjs'; | ||
|
||
// transform slate op to yjs op and apply it to ydoc | ||
export function applyToYjs(_ydoc: Y.Doc, _slateRoot: Node, op: Operation) { | ||
if (op.type === 'set_selection') return; | ||
console.log('applySlateOp', op); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
11 changes: 0 additions & 11 deletions
11
frontend/appflowy_web_app/src/application/slate-yjs/utils/translateYjsEvent/arrayEvent.ts
This file was deleted.
Oops, something went wrong.
29 changes: 0 additions & 29 deletions
29
frontend/appflowy_web_app/src/application/slate-yjs/utils/translateYjsEvent/index.ts
This file was deleted.
Oops, something went wrong.
Oops, something went wrong.