@getguru/slate-yjs-core 1.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +67 -0
- package/README.md +3 -0
- package/dist/applyToSlate/index.d.ts +23 -0
- package/dist/applyToSlate/textEvent.d.ts +4 -0
- package/dist/applyToYjs/index.d.ts +4 -0
- package/dist/applyToYjs/node/index.d.ts +4 -0
- package/dist/applyToYjs/node/insertNode.d.ts +4 -0
- package/dist/applyToYjs/node/mergeNode.d.ts +4 -0
- package/dist/applyToYjs/node/moveNode.d.ts +4 -0
- package/dist/applyToYjs/node/removeNode.d.ts +4 -0
- package/dist/applyToYjs/node/setNode.d.ts +4 -0
- package/dist/applyToYjs/node/splitNode.d.ts +4 -0
- package/dist/applyToYjs/text/index.d.ts +4 -0
- package/dist/applyToYjs/text/insertText.d.ts +4 -0
- package/dist/applyToYjs/text/removeText.d.ts +4 -0
- package/dist/applyToYjs/types.d.ts +9 -0
- package/dist/index.cjs +1360 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.global.js +10365 -0
- package/dist/index.global.js.map +1 -0
- package/dist/index.js +1338 -0
- package/dist/index.js.map +1 -0
- package/dist/model/types.d.ts +38 -0
- package/dist/plugins/index.d.ts +4 -0
- package/dist/plugins/withCursors.d.ts +39 -0
- package/dist/plugins/withYHistory.d.ts +20 -0
- package/dist/plugins/withYjs.d.ts +43 -0
- package/dist/utils/clone.d.ts +5 -0
- package/dist/utils/convert.d.ts +8 -0
- package/dist/utils/delta.d.ts +8 -0
- package/dist/utils/errors.d.ts +2 -0
- package/dist/utils/location.d.ts +12 -0
- package/dist/utils/object.d.ts +10 -0
- package/dist/utils/position.d.ts +20 -0
- package/dist/utils/slate.d.ts +3 -0
- package/dist/utils/yjs.d.ts +5 -0
- package/package.json +47 -0
- package/src/applyToSlate/index.ts +118 -0
- package/src/applyToSlate/textEvent.ts +280 -0
- package/src/applyToYjs/index.ts +28 -0
- package/src/applyToYjs/node/index.ts +17 -0
- package/src/applyToYjs/node/insertNode.ts +23 -0
- package/src/applyToYjs/node/mergeNode.ts +82 -0
- package/src/applyToYjs/node/moveNode.ts +57 -0
- package/src/applyToYjs/node/removeNode.ts +16 -0
- package/src/applyToYjs/node/setNode.ts +42 -0
- package/src/applyToYjs/node/splitNode.ts +98 -0
- package/src/applyToYjs/text/index.ts +9 -0
- package/src/applyToYjs/text/insertText.ts +27 -0
- package/src/applyToYjs/text/removeText.ts +16 -0
- package/src/applyToYjs/types.ts +12 -0
- package/src/index.ts +47 -0
- package/src/model/types.ts +50 -0
- package/src/plugins/index.ts +3 -0
- package/src/plugins/withCursors.ts +269 -0
- package/src/plugins/withYHistory.ts +183 -0
- package/src/plugins/withYjs.ts +284 -0
- package/src/utils/clone.ts +29 -0
- package/src/utils/convert.ts +48 -0
- package/src/utils/delta.ts +97 -0
- package/src/utils/errors.ts +20 -0
- package/src/utils/location.ts +157 -0
- package/src/utils/object.ts +93 -0
- package/src/utils/position.ts +300 -0
- package/src/utils/slate.ts +11 -0
- package/src/utils/yjs.ts +10 -0
- package/test/collaboration/addMark/acrossMarks.tsx +40 -0
- package/test/collaboration/addMark/acrossMarksSame.tsx +36 -0
- package/test/collaboration/addMark/atBeginningOfDocument.tsx +27 -0
- package/test/collaboration/addMark/atEndOfDocument.tsx +30 -0
- package/test/collaboration/addMark/withOtherMarks.tsx +31 -0
- package/test/collaboration/insertNode/atBeginningOfDocument.tsx +28 -0
- package/test/collaboration/insertNode/atEndOfDocument.tsx +28 -0
- package/test/collaboration/insertNode/inTheMiddle.tsx +30 -0
- package/test/collaboration/insertText/atBeginningOfBlock.tsx +26 -0
- package/test/collaboration/insertText/atBeginningOfDocument.tsx +26 -0
- package/test/collaboration/insertText/atEndOfBlock.tsx +26 -0
- package/test/collaboration/insertText/atEndOfDocument.tsx +26 -0
- package/test/collaboration/insertText/inTheMiddle.tsx +32 -0
- package/test/collaboration/insertText/inTheMiddleOfNestedBlock.tsx +30 -0
- package/test/collaboration/insertText/insideMarks.tsx +28 -0
- package/test/collaboration/insertText/withEmptyString.tsx +25 -0
- package/test/collaboration/insertText/withEntities.tsx +28 -0
- package/test/collaboration/insertText/withMarks.tsx +25 -0
- package/test/collaboration/insertText/withUnicode.tsx +28 -0
- package/test/collaboration/mergeNode/afterADeleteBackward.tsx +27 -0
- package/test/collaboration/mergeNode/inSameParent.tsx +34 -0
- package/test/collaboration/mergeNode/onMixedNestedNodes.tsx +29 -0
- package/test/collaboration/mergeNode/onMixedTypeNodes.tsx +27 -0
- package/test/collaboration/mergeNode/withUnicode.tsx +25 -0
- package/test/collaboration/moveNode/downward/whenBlockBecomesNested.tsx +43 -0
- package/test/collaboration/moveNode/downward/whenBlockBecomesNonNested.tsx +41 -0
- package/test/collaboration/moveNode/downward/whenBlockStaysNested.tsx +38 -0
- package/test/collaboration/moveNode/downward/whenBlockStaysNonNested.tsx +30 -0
- package/test/collaboration/moveNode/upward/whenBlockBecomesNested.tsx +43 -0
- package/test/collaboration/moveNode/upward/whenBlockBecomesNonNested.tsx +41 -0
- package/test/collaboration/moveNode/upward/whenBlockStaysNested.tsx +38 -0
- package/test/collaboration/moveNode/upward/whenBlockStaysNonNested.tsx +30 -0
- package/test/collaboration/removeMark/inTheMiddleOfText.tsx +43 -0
- package/test/collaboration/removeMark/withAddMark.tsx +31 -0
- package/test/collaboration/removeMark/withOtherMarks.tsx +47 -0
- package/test/collaboration/removeNode/atBeginningOfDocument.tsx +26 -0
- package/test/collaboration/removeNode/atEndOfDocument.tsx +26 -0
- package/test/collaboration/removeNode/nestedBlock.tsx +28 -0
- package/test/collaboration/removeNode/wrapperBlock.tsx +28 -0
- package/test/collaboration/removeText/atBeginningOfDocument.tsx +34 -0
- package/test/collaboration/removeText/atEndOfDocument.tsx +37 -0
- package/test/collaboration/removeText/withUnicode.tsx +29 -0
- package/test/collaboration/setNode/atBeginningOfDocument.tsx +27 -0
- package/test/collaboration/setNode/atEndOfDocument.tsx +27 -0
- package/test/collaboration/setNode/onDataChange.tsx +35 -0
- package/test/collaboration/setNode/onDataChangeOnInline.tsx +35 -0
- package/test/collaboration/setNode/onResetBlock.tsx +27 -0
- package/test/collaboration/setNode/withAChangeOfType.tsx +26 -0
- package/test/collaboration/splitNode/atBeginningOfDocument.tsx +28 -0
- package/test/collaboration/splitNode/atEndOfBlock.tsx +27 -0
- package/test/collaboration/splitNode/atEndOfDocument.tsx +27 -0
- package/test/collaboration/splitNode/onNonDefaultBlock.tsx +27 -0
- package/test/collaboration/splitNode/withMultipleSubNodes.tsx +32 -0
- package/test/collaboration/splitNode/withUnicode.tsx +29 -0
- package/test/index.test.ts +65 -0
- package/test/slate.d.ts +8 -0
- package/test/withTestingElements.ts +46 -0
- package/tsconfig.json +11 -0
- package/tsup.config.ts +32 -0
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/** @jsx jsx */
|
|
2
|
+
import { Editor, Transforms } from 'slate';
|
|
3
|
+
import { jsx } from '../../../../../support/jsx';
|
|
4
|
+
|
|
5
|
+
export const input = (
|
|
6
|
+
<editor>
|
|
7
|
+
<h1 id="block1">
|
|
8
|
+
Hello world!
|
|
9
|
+
<cursor />
|
|
10
|
+
</h1>
|
|
11
|
+
<unstyled>Welcome to slate-yjs!</unstyled>
|
|
12
|
+
</editor>
|
|
13
|
+
);
|
|
14
|
+
|
|
15
|
+
export const expected = (
|
|
16
|
+
<editor>
|
|
17
|
+
<h1 id="block1">Hello world!</h1>
|
|
18
|
+
<h1 id="block1">
|
|
19
|
+
<cursor />
|
|
20
|
+
</h1>
|
|
21
|
+
<unstyled>Welcome to slate-yjs!</unstyled>
|
|
22
|
+
</editor>
|
|
23
|
+
);
|
|
24
|
+
|
|
25
|
+
export function run(editor: Editor) {
|
|
26
|
+
Transforms.splitNodes(editor, { always: true });
|
|
27
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/* eslint-disable react/void-dom-elements-no-children */
|
|
2
|
+
/** @jsx jsx */
|
|
3
|
+
import { Editor, Transforms } from 'slate';
|
|
4
|
+
import { jsx } from '../../../../../support/jsx';
|
|
5
|
+
|
|
6
|
+
export const input = (
|
|
7
|
+
<editor>
|
|
8
|
+
<unstyled id="block1">
|
|
9
|
+
slate-yjs
|
|
10
|
+
<cursor />
|
|
11
|
+
slate-yjs
|
|
12
|
+
<link url="https://slate-yjs.dev">slate-yjs</link>
|
|
13
|
+
<link url="https://slate-yjs.dev">slate-yjs</link>
|
|
14
|
+
</unstyled>
|
|
15
|
+
</editor>
|
|
16
|
+
);
|
|
17
|
+
|
|
18
|
+
export const expected = (
|
|
19
|
+
<editor>
|
|
20
|
+
<unstyled id="block1">slate-yjs</unstyled>
|
|
21
|
+
<unstyled id="block1">
|
|
22
|
+
<cursor />
|
|
23
|
+
slate-yjs
|
|
24
|
+
<link url="https://slate-yjs.dev">slate-yjs</link>
|
|
25
|
+
<link url="https://slate-yjs.dev">slate-yjs</link>
|
|
26
|
+
</unstyled>
|
|
27
|
+
</editor>
|
|
28
|
+
);
|
|
29
|
+
|
|
30
|
+
export function run(editor: Editor) {
|
|
31
|
+
Transforms.splitNodes(editor, { always: true });
|
|
32
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/** @jsx jsx */
|
|
2
|
+
import { Editor, Transforms } from 'slate';
|
|
3
|
+
import { jsx } from '../../../../../support/jsx';
|
|
4
|
+
|
|
5
|
+
export const input = (
|
|
6
|
+
<editor>
|
|
7
|
+
<unstyled id="block1">
|
|
8
|
+
H{'Iñtërnâtiônàlizætiøn☃💩\uFEFF'}
|
|
9
|
+
<cursor />
|
|
10
|
+
{'Iñtërnâtiônàlizætiøn☃💩\uFEFF'}
|
|
11
|
+
</unstyled>
|
|
12
|
+
<unstyled>{'Iñtërnâtiônàlizætiøn☃💩\uFEFF'}</unstyled>
|
|
13
|
+
</editor>
|
|
14
|
+
);
|
|
15
|
+
|
|
16
|
+
export const expected = (
|
|
17
|
+
<editor>
|
|
18
|
+
<unstyled id="block1">H{'Iñtërnâtiônàlizætiøn☃💩\uFEFF'}</unstyled>
|
|
19
|
+
<unstyled id="block1">
|
|
20
|
+
<cursor />
|
|
21
|
+
{'Iñtërnâtiônàlizætiøn☃💩\uFEFF'}
|
|
22
|
+
</unstyled>
|
|
23
|
+
<unstyled>{'Iñtërnâtiônàlizætiøn☃💩\uFEFF'}</unstyled>
|
|
24
|
+
</editor>
|
|
25
|
+
);
|
|
26
|
+
|
|
27
|
+
export function run(editor: Editor) {
|
|
28
|
+
Transforms.splitNodes(editor, { always: true });
|
|
29
|
+
}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/* eslint-disable import/no-extraneous-dependencies */
|
|
2
|
+
import { createEditor, Editor } from 'slate';
|
|
3
|
+
import { describe, expect } from 'vitest';
|
|
4
|
+
import * as Y from 'yjs';
|
|
5
|
+
import { fixtures } from '../../../support/fixtures';
|
|
6
|
+
import { yTextToSlateElement } from '../src';
|
|
7
|
+
import { withTestingElements } from './withTestingElements';
|
|
8
|
+
|
|
9
|
+
export type FixtureModule = {
|
|
10
|
+
module: {
|
|
11
|
+
input: Editor;
|
|
12
|
+
expected: Editor;
|
|
13
|
+
run: (e: Editor) => void;
|
|
14
|
+
};
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
async function normalizedSlateDoc(sharedRoot: Y.XmlText) {
|
|
18
|
+
const editor = createEditor();
|
|
19
|
+
editor.children = yTextToSlateElement(sharedRoot).children;
|
|
20
|
+
const e = await withTestingElements(editor);
|
|
21
|
+
Editor.normalize(e, { force: true });
|
|
22
|
+
return e.children;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
async function runCollaborationTest({ module }: FixtureModule) {
|
|
26
|
+
// Setup 'local' editor
|
|
27
|
+
const { input, run, expected } = module;
|
|
28
|
+
const editor = await withTestingElements(input);
|
|
29
|
+
|
|
30
|
+
// Keep the 'local' editor state before applying run.
|
|
31
|
+
const baseState = Y.encodeStateAsUpdateV2(editor.sharedRoot.doc);
|
|
32
|
+
|
|
33
|
+
Editor.normalize(editor, { force: true });
|
|
34
|
+
|
|
35
|
+
// The normalized editor state should match the shared root.
|
|
36
|
+
expect(await normalizedSlateDoc(editor.sharedRoot)).toEqual(editor.children);
|
|
37
|
+
|
|
38
|
+
run(editor);
|
|
39
|
+
editor.onChange();
|
|
40
|
+
|
|
41
|
+
// Editor state after run should match shared root.
|
|
42
|
+
expect(await normalizedSlateDoc(editor.sharedRoot)).toEqual(editor.children);
|
|
43
|
+
|
|
44
|
+
// Setup remote editor with input base state
|
|
45
|
+
const remoteDoc = new Y.Doc();
|
|
46
|
+
Y.applyUpdateV2(remoteDoc, baseState);
|
|
47
|
+
const remote = await withTestingElements(createEditor(), remoteDoc);
|
|
48
|
+
|
|
49
|
+
// Apply changes from 'run'
|
|
50
|
+
Y.applyUpdateV2(remoteDoc, Y.encodeStateAsUpdateV2(editor.sharedRoot.doc));
|
|
51
|
+
|
|
52
|
+
// Verify remote and editor state are equal
|
|
53
|
+
expect(await normalizedSlateDoc(remote.sharedRoot)).toEqual(remote.children);
|
|
54
|
+
expect(editor.children).toEqual(remote.children);
|
|
55
|
+
expect(await normalizedSlateDoc(editor.sharedRoot)).toEqual(editor.children);
|
|
56
|
+
|
|
57
|
+
// Verify editor is in expected state
|
|
58
|
+
const expectedEditor = await withTestingElements(expected);
|
|
59
|
+
Editor.normalize(expectedEditor, { force: true });
|
|
60
|
+
expect(editor.children).toEqual(expectedEditor.children);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
describe('adapter', () => {
|
|
64
|
+
fixtures(__dirname, 'collaboration', runCollaborationTest);
|
|
65
|
+
});
|
package/test/slate.d.ts
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { Editor, Element, Transforms } from 'slate';
|
|
2
|
+
import * as Y from 'yjs';
|
|
3
|
+
import { wait } from '../../../support/utils';
|
|
4
|
+
import { slateNodesToInsertDelta, withYjs } from '../src';
|
|
5
|
+
|
|
6
|
+
const INLINE_ELEMENTS = ['note-link', 'link'];
|
|
7
|
+
|
|
8
|
+
export async function withTestingElements(
|
|
9
|
+
editor: Editor,
|
|
10
|
+
doc: Y.Doc = new Y.Doc()
|
|
11
|
+
) {
|
|
12
|
+
const { normalizeNode, isInline } = editor;
|
|
13
|
+
|
|
14
|
+
// normalizations needed for nested tests
|
|
15
|
+
editor.normalizeNode = (entry) => {
|
|
16
|
+
const [node, path] = entry;
|
|
17
|
+
|
|
18
|
+
// remove empty list
|
|
19
|
+
if (
|
|
20
|
+
Element.isElement(node) &&
|
|
21
|
+
!Editor.isEditor(node) &&
|
|
22
|
+
node.type === 'unordered-list'
|
|
23
|
+
) {
|
|
24
|
+
if (!node.children.length) {
|
|
25
|
+
return Transforms.removeNodes(editor, { at: path });
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
normalizeNode(entry);
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
editor.isInline = (element) =>
|
|
33
|
+
INLINE_ELEMENTS.includes(element.type as string) || isInline(element);
|
|
34
|
+
|
|
35
|
+
const sharedType = doc.get('sharedRoot', Y.XmlText) as Y.XmlText;
|
|
36
|
+
if (sharedType.toDelta().length === 0) {
|
|
37
|
+
sharedType.applyDelta(slateNodesToInsertDelta(editor.children));
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
const e = withYjs(editor, sharedType, { autoConnect: true });
|
|
41
|
+
|
|
42
|
+
// Wait for editor to be initialized
|
|
43
|
+
await wait();
|
|
44
|
+
|
|
45
|
+
return e;
|
|
46
|
+
}
|
package/tsconfig.json
ADDED
package/tsup.config.ts
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/* eslint-disable import/no-default-export */
|
|
2
|
+
/* eslint-disable import/no-extraneous-dependencies */
|
|
3
|
+
import { defineConfig, Options } from 'tsup';
|
|
4
|
+
|
|
5
|
+
export default defineConfig(
|
|
6
|
+
({ watch }) => <Options[]>[
|
|
7
|
+
{
|
|
8
|
+
entry: ['src/index.ts'],
|
|
9
|
+
outDir: 'dist',
|
|
10
|
+
format: ['cjs', 'iife', 'esm'],
|
|
11
|
+
globalName: 'SlateYjsCore',
|
|
12
|
+
platform: 'browser',
|
|
13
|
+
splitting: false,
|
|
14
|
+
bundle: true,
|
|
15
|
+
sourcemap: true,
|
|
16
|
+
minify: false,
|
|
17
|
+
clean: !watch,
|
|
18
|
+
},
|
|
19
|
+
!!watch && {
|
|
20
|
+
entry: ['src'],
|
|
21
|
+
outDir: 'dist',
|
|
22
|
+
format: [],
|
|
23
|
+
platform: 'browser',
|
|
24
|
+
splitting: false,
|
|
25
|
+
bundle: false,
|
|
26
|
+
sourcemap: true,
|
|
27
|
+
dts: true,
|
|
28
|
+
minify: false,
|
|
29
|
+
clean: false,
|
|
30
|
+
},
|
|
31
|
+
].filter(Boolean)
|
|
32
|
+
);
|