@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.
Files changed (126) hide show
  1. package/CHANGELOG.md +67 -0
  2. package/README.md +3 -0
  3. package/dist/applyToSlate/index.d.ts +23 -0
  4. package/dist/applyToSlate/textEvent.d.ts +4 -0
  5. package/dist/applyToYjs/index.d.ts +4 -0
  6. package/dist/applyToYjs/node/index.d.ts +4 -0
  7. package/dist/applyToYjs/node/insertNode.d.ts +4 -0
  8. package/dist/applyToYjs/node/mergeNode.d.ts +4 -0
  9. package/dist/applyToYjs/node/moveNode.d.ts +4 -0
  10. package/dist/applyToYjs/node/removeNode.d.ts +4 -0
  11. package/dist/applyToYjs/node/setNode.d.ts +4 -0
  12. package/dist/applyToYjs/node/splitNode.d.ts +4 -0
  13. package/dist/applyToYjs/text/index.d.ts +4 -0
  14. package/dist/applyToYjs/text/insertText.d.ts +4 -0
  15. package/dist/applyToYjs/text/removeText.d.ts +4 -0
  16. package/dist/applyToYjs/types.d.ts +9 -0
  17. package/dist/index.cjs +1360 -0
  18. package/dist/index.cjs.map +1 -0
  19. package/dist/index.d.ts +6 -0
  20. package/dist/index.global.js +10365 -0
  21. package/dist/index.global.js.map +1 -0
  22. package/dist/index.js +1338 -0
  23. package/dist/index.js.map +1 -0
  24. package/dist/model/types.d.ts +38 -0
  25. package/dist/plugins/index.d.ts +4 -0
  26. package/dist/plugins/withCursors.d.ts +39 -0
  27. package/dist/plugins/withYHistory.d.ts +20 -0
  28. package/dist/plugins/withYjs.d.ts +43 -0
  29. package/dist/utils/clone.d.ts +5 -0
  30. package/dist/utils/convert.d.ts +8 -0
  31. package/dist/utils/delta.d.ts +8 -0
  32. package/dist/utils/errors.d.ts +2 -0
  33. package/dist/utils/location.d.ts +12 -0
  34. package/dist/utils/object.d.ts +10 -0
  35. package/dist/utils/position.d.ts +20 -0
  36. package/dist/utils/slate.d.ts +3 -0
  37. package/dist/utils/yjs.d.ts +5 -0
  38. package/package.json +47 -0
  39. package/src/applyToSlate/index.ts +118 -0
  40. package/src/applyToSlate/textEvent.ts +280 -0
  41. package/src/applyToYjs/index.ts +28 -0
  42. package/src/applyToYjs/node/index.ts +17 -0
  43. package/src/applyToYjs/node/insertNode.ts +23 -0
  44. package/src/applyToYjs/node/mergeNode.ts +82 -0
  45. package/src/applyToYjs/node/moveNode.ts +57 -0
  46. package/src/applyToYjs/node/removeNode.ts +16 -0
  47. package/src/applyToYjs/node/setNode.ts +42 -0
  48. package/src/applyToYjs/node/splitNode.ts +98 -0
  49. package/src/applyToYjs/text/index.ts +9 -0
  50. package/src/applyToYjs/text/insertText.ts +27 -0
  51. package/src/applyToYjs/text/removeText.ts +16 -0
  52. package/src/applyToYjs/types.ts +12 -0
  53. package/src/index.ts +47 -0
  54. package/src/model/types.ts +50 -0
  55. package/src/plugins/index.ts +3 -0
  56. package/src/plugins/withCursors.ts +269 -0
  57. package/src/plugins/withYHistory.ts +183 -0
  58. package/src/plugins/withYjs.ts +284 -0
  59. package/src/utils/clone.ts +29 -0
  60. package/src/utils/convert.ts +48 -0
  61. package/src/utils/delta.ts +97 -0
  62. package/src/utils/errors.ts +20 -0
  63. package/src/utils/location.ts +157 -0
  64. package/src/utils/object.ts +93 -0
  65. package/src/utils/position.ts +300 -0
  66. package/src/utils/slate.ts +11 -0
  67. package/src/utils/yjs.ts +10 -0
  68. package/test/collaboration/addMark/acrossMarks.tsx +40 -0
  69. package/test/collaboration/addMark/acrossMarksSame.tsx +36 -0
  70. package/test/collaboration/addMark/atBeginningOfDocument.tsx +27 -0
  71. package/test/collaboration/addMark/atEndOfDocument.tsx +30 -0
  72. package/test/collaboration/addMark/withOtherMarks.tsx +31 -0
  73. package/test/collaboration/insertNode/atBeginningOfDocument.tsx +28 -0
  74. package/test/collaboration/insertNode/atEndOfDocument.tsx +28 -0
  75. package/test/collaboration/insertNode/inTheMiddle.tsx +30 -0
  76. package/test/collaboration/insertText/atBeginningOfBlock.tsx +26 -0
  77. package/test/collaboration/insertText/atBeginningOfDocument.tsx +26 -0
  78. package/test/collaboration/insertText/atEndOfBlock.tsx +26 -0
  79. package/test/collaboration/insertText/atEndOfDocument.tsx +26 -0
  80. package/test/collaboration/insertText/inTheMiddle.tsx +32 -0
  81. package/test/collaboration/insertText/inTheMiddleOfNestedBlock.tsx +30 -0
  82. package/test/collaboration/insertText/insideMarks.tsx +28 -0
  83. package/test/collaboration/insertText/withEmptyString.tsx +25 -0
  84. package/test/collaboration/insertText/withEntities.tsx +28 -0
  85. package/test/collaboration/insertText/withMarks.tsx +25 -0
  86. package/test/collaboration/insertText/withUnicode.tsx +28 -0
  87. package/test/collaboration/mergeNode/afterADeleteBackward.tsx +27 -0
  88. package/test/collaboration/mergeNode/inSameParent.tsx +34 -0
  89. package/test/collaboration/mergeNode/onMixedNestedNodes.tsx +29 -0
  90. package/test/collaboration/mergeNode/onMixedTypeNodes.tsx +27 -0
  91. package/test/collaboration/mergeNode/withUnicode.tsx +25 -0
  92. package/test/collaboration/moveNode/downward/whenBlockBecomesNested.tsx +43 -0
  93. package/test/collaboration/moveNode/downward/whenBlockBecomesNonNested.tsx +41 -0
  94. package/test/collaboration/moveNode/downward/whenBlockStaysNested.tsx +38 -0
  95. package/test/collaboration/moveNode/downward/whenBlockStaysNonNested.tsx +30 -0
  96. package/test/collaboration/moveNode/upward/whenBlockBecomesNested.tsx +43 -0
  97. package/test/collaboration/moveNode/upward/whenBlockBecomesNonNested.tsx +41 -0
  98. package/test/collaboration/moveNode/upward/whenBlockStaysNested.tsx +38 -0
  99. package/test/collaboration/moveNode/upward/whenBlockStaysNonNested.tsx +30 -0
  100. package/test/collaboration/removeMark/inTheMiddleOfText.tsx +43 -0
  101. package/test/collaboration/removeMark/withAddMark.tsx +31 -0
  102. package/test/collaboration/removeMark/withOtherMarks.tsx +47 -0
  103. package/test/collaboration/removeNode/atBeginningOfDocument.tsx +26 -0
  104. package/test/collaboration/removeNode/atEndOfDocument.tsx +26 -0
  105. package/test/collaboration/removeNode/nestedBlock.tsx +28 -0
  106. package/test/collaboration/removeNode/wrapperBlock.tsx +28 -0
  107. package/test/collaboration/removeText/atBeginningOfDocument.tsx +34 -0
  108. package/test/collaboration/removeText/atEndOfDocument.tsx +37 -0
  109. package/test/collaboration/removeText/withUnicode.tsx +29 -0
  110. package/test/collaboration/setNode/atBeginningOfDocument.tsx +27 -0
  111. package/test/collaboration/setNode/atEndOfDocument.tsx +27 -0
  112. package/test/collaboration/setNode/onDataChange.tsx +35 -0
  113. package/test/collaboration/setNode/onDataChangeOnInline.tsx +35 -0
  114. package/test/collaboration/setNode/onResetBlock.tsx +27 -0
  115. package/test/collaboration/setNode/withAChangeOfType.tsx +26 -0
  116. package/test/collaboration/splitNode/atBeginningOfDocument.tsx +28 -0
  117. package/test/collaboration/splitNode/atEndOfBlock.tsx +27 -0
  118. package/test/collaboration/splitNode/atEndOfDocument.tsx +27 -0
  119. package/test/collaboration/splitNode/onNonDefaultBlock.tsx +27 -0
  120. package/test/collaboration/splitNode/withMultipleSubNodes.tsx +32 -0
  121. package/test/collaboration/splitNode/withUnicode.tsx +29 -0
  122. package/test/index.test.ts +65 -0
  123. package/test/slate.d.ts +8 -0
  124. package/test/withTestingElements.ts +46 -0
  125. package/tsconfig.json +11 -0
  126. 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
+ });
@@ -0,0 +1,8 @@
1
+ import { BaseElement, BaseText } from 'slate';
2
+
3
+ declare module 'slate' {
4
+ interface CustomTypes {
5
+ Element: BaseElement & Record<string, unknown>;
6
+ Text: BaseText & Record<string, unknown>;
7
+ }
8
+ }
@@ -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
@@ -0,0 +1,11 @@
1
+ {
2
+ "extends": "../../config/typescript/tsconfig.json",
3
+ "include": ["src/**/*"],
4
+ "compilerOptions": {
5
+ "rootDir": "./src",
6
+ "outDir": "./dist",
7
+ "declarationDir": "./dist",
8
+ "composite": true
9
+ },
10
+ "references": []
11
+ }
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
+ );