@datalayer/lexical-loro 1.0.3 → 1.0.5
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/README.md +2 -2
- package/lib/Editor.js +3 -2
- package/lib/appSettings.js +1 -1
- package/lib/collab/loro/Bindings.js +7 -7
- package/lib/collab/loro/Debug.js +35 -35
- package/lib/collab/loro/LexicalCollaborationContext.js +1 -1
- package/lib/collab/loro/LexicalCollaborationPlugin.d.ts +6 -1
- package/lib/collab/loro/LexicalCollaborationPlugin.js +41 -13
- package/lib/collab/loro/State.js +1 -1
- package/lib/collab/loro/components/LoroCollaborators.js +7 -19
- package/lib/collab/loro/components/index.js +1 -1
- package/lib/collab/loro/index.js +1 -1
- package/lib/collab/loro/integrators/BaseIntegrator.js +1 -1
- package/lib/collab/loro/integrators/CounterIntegrator.js +1 -1
- package/lib/collab/loro/integrators/ListIntegrator.js +4 -4
- package/lib/collab/loro/integrators/MapIntegrator.js +4 -4
- package/lib/collab/loro/integrators/TextIntegrator.js +2 -2
- package/lib/collab/loro/integrators/TreeIntegrator.d.ts +5 -0
- package/lib/collab/loro/integrators/TreeIntegrator.js +184 -142
- package/lib/collab/loro/nodes/NodeFactory.js +26 -47
- package/lib/collab/loro/nodes/NodesMapper.js +19 -7
- package/lib/collab/loro/propagators/DecoratorNodePropagator.js +1 -1
- package/lib/collab/loro/propagators/ElementNodePropagator.d.ts +1 -1
- package/lib/collab/loro/propagators/ElementNodePropagator.js +102 -35
- package/lib/collab/loro/propagators/LineBreakNodePropagator.js +1 -1
- package/lib/collab/loro/propagators/RootNodePropagator.js +1 -1
- package/lib/collab/loro/propagators/TextNodePropagator.js +55 -45
- package/lib/collab/loro/propagators/index.d.ts +1 -1
- package/lib/collab/loro/propagators/index.js +1 -1
- package/lib/collab/loro/provider/websocket.d.ts +1 -0
- package/lib/collab/loro/provider/websocket.js +47 -12
- package/lib/collab/loro/servers/index.js +1 -1
- package/lib/collab/loro/servers/ws/callback.js +1 -1
- package/lib/collab/loro/servers/ws/server.js +1 -1
- package/lib/collab/loro/servers/ws/utils.js +35 -35
- package/lib/collab/loro/sync/SyncCursors.js +42 -16
- package/lib/collab/loro/sync/SyncLexicalToLoro.js +76 -37
- package/lib/collab/loro/sync/SyncLoroToLexical.js +32 -26
- package/lib/collab/loro/types/LexicalNodeData.js +1 -1
- package/lib/collab/loro/useCollaboration.js +173 -28
- package/lib/collab/loro/utils/InitialContent.js +1 -1
- package/lib/collab/loro/utils/Invariant.d.ts +15 -0
- package/lib/collab/loro/utils/Invariant.js +24 -0
- package/lib/collab/loro/utils/LexicalToLoro.js +1 -1
- package/lib/collab/loro/utils/Utils.js +1 -1
- package/lib/collab/loro/wsProvider.js +21 -4
- package/lib/collab/utils/invariant.js +1 -1
- package/lib/collab/utils/simpleDiffWithCursor.js +1 -1
- package/lib/commenting/index.js +1 -1
- package/lib/demo.js +1 -1
- package/lib/hooks/useFlashMessage.js +1 -1
- package/lib/hooks/useReport.js +1 -1
- package/lib/index.js +1 -1
- package/lib/nodes/AutocompleteNode.js +1 -1
- package/lib/nodes/EmojiNode.js +1 -1
- package/lib/nodes/KeywordNode.js +1 -1
- package/lib/nodes/LayoutContainerNode.js +1 -1
- package/lib/nodes/LayoutItemNode.js +1 -1
- package/lib/nodes/MentionNode.js +1 -1
- package/lib/nodes/PlaygroundNodes.js +1 -1
- package/lib/nodes/SpecialTextNode.js +1 -1
- package/lib/plugins/AutocompletePlugin/index.js +1 -1
- package/lib/plugins/CodeActionMenuPlugin/components/CopyButton/index.js +1 -1
- package/lib/plugins/CodeActionMenuPlugin/components/PrettierButton/index.js +1 -1
- package/lib/plugins/CodeActionMenuPlugin/utils.js +1 -1
- package/lib/plugins/CodeHighlightPrismPlugin/index.js +1 -1
- package/lib/plugins/CodeHighlightShikiPlugin/index.js +1 -1
- package/lib/plugins/CollapsiblePlugin/CollapsibleContainerNode.js +1 -1
- package/lib/plugins/CollapsiblePlugin/CollapsibleContentNode.js +1 -1
- package/lib/plugins/CollapsiblePlugin/CollapsibleTitleNode.js +1 -1
- package/lib/plugins/CollapsiblePlugin/CollapsibleUtils.js +1 -1
- package/lib/plugins/CollapsiblePlugin/index.js +1 -1
- package/lib/plugins/CounterPlugin/index.js +1 -1
- package/lib/plugins/DateTimePlugin/index.js +1 -1
- package/lib/plugins/DebugPlugin/index.js +59 -3
- package/lib/plugins/DragDropPastePlugin/index.js +1 -1
- package/lib/plugins/EmojiPickerPlugin/index.js +1 -1
- package/lib/plugins/EmojisPlugin/index.js +1 -1
- package/lib/plugins/FigmaPlugin/index.js +1 -1
- package/lib/plugins/KeywordsPlugin/index.js +1 -1
- package/lib/plugins/LayoutPlugin/LayoutPlugin.js +1 -1
- package/lib/plugins/MarkdownTransformers/index.js +1 -1
- package/lib/plugins/MaxLengthPlugin/index.js +1 -1
- package/lib/plugins/PageBreakPlugin/index.js +1 -1
- package/lib/plugins/ShortcutsPlugin/index.js +1 -1
- package/lib/plugins/ShortcutsPlugin/shortcuts.js +1 -1
- package/lib/plugins/SpecialTextPlugin/index.js +1 -1
- package/lib/plugins/SpeechToTextPlugin/index.js +1 -1
- package/lib/plugins/StickyPlugin/index.js +1 -1
- package/lib/plugins/TabFocusPlugin/index.js +1 -1
- package/lib/plugins/ToolbarPlugin/fontSize.js +1 -1
- package/lib/plugins/ToolbarPlugin/utils.js +1 -1
- package/lib/plugins/TwitterPlugin/index.js +1 -1
- package/lib/plugins/TypingPerfPlugin/index.js +1 -1
- package/lib/plugins/YouTubePlugin/index.js +1 -1
- package/lib/server/validation.js +1 -1
- package/lib/setupEnv.js +1 -1
- package/lib/themes/CommentEditorTheme.js +1 -1
- package/lib/themes/PlaygroundEditorTheme.js +1 -1
- package/lib/themes/StickyEditorTheme.js +1 -1
- package/lib/tyes.dt.js +1 -1
- package/lib/utils/docSerialization.js +1 -1
- package/lib/utils/emoji-list.js +1 -1
- package/lib/utils/getDOMRangeRect.js +1 -1
- package/lib/utils/getSelectedNode.js +1 -1
- package/lib/utils/getThemeSelector.js +1 -1
- package/lib/utils/isMobileWidth.js +1 -1
- package/lib/utils/joinClasses.js +1 -1
- package/lib/utils/setFloatingElemPosition.js +1 -1
- package/lib/utils/setFloatingElemPositionForLinkEditor.js +1 -1
- package/lib/utils/swipe.js +1 -1
- package/lib/utils/url.js +1 -1
- package/package.json +4 -4
|
@@ -8,6 +8,62 @@ export function DebugPlugin() {
|
|
|
8
8
|
const [selectedTool, setSelectedTool] = useState('');
|
|
9
9
|
const [isLoadingTools, setIsLoadingTools] = useState(false);
|
|
10
10
|
const [toolsError, setToolsError] = useState(null);
|
|
11
|
+
const getCurrentCollabDocId = () => {
|
|
12
|
+
const params = new URLSearchParams(window.location.search);
|
|
13
|
+
return params.get('collabId') || 'main';
|
|
14
|
+
};
|
|
15
|
+
const isInSplitScreen = () => {
|
|
16
|
+
try {
|
|
17
|
+
return window.parent != null && window.parent.location.pathname === '/split/';
|
|
18
|
+
}
|
|
19
|
+
catch {
|
|
20
|
+
return false;
|
|
21
|
+
}
|
|
22
|
+
};
|
|
23
|
+
const navigateToRoom = (roomId, collabId) => {
|
|
24
|
+
const url = new URL(window.location.href);
|
|
25
|
+
url.searchParams.set('roomId', roomId);
|
|
26
|
+
url.searchParams.set('collabId', collabId);
|
|
27
|
+
if (isInSplitScreen()) {
|
|
28
|
+
window.parent.location.href = `/split/${url.search}`;
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
window.location.href = `${url.pathname}${url.search}`;
|
|
32
|
+
};
|
|
33
|
+
const createNewRoomWithDocument = async () => {
|
|
34
|
+
const roomId = Date.now().toString(36);
|
|
35
|
+
const collabId = `room-${roomId}`;
|
|
36
|
+
const seedText = `New room ${roomId} created at ${new Date().toISOString()}`;
|
|
37
|
+
try {
|
|
38
|
+
const response = await fetch('http://localhost:3001/', {
|
|
39
|
+
method: 'POST',
|
|
40
|
+
headers: {
|
|
41
|
+
'Content-Type': 'application/json',
|
|
42
|
+
},
|
|
43
|
+
body: JSON.stringify({
|
|
44
|
+
jsonrpc: '2.0',
|
|
45
|
+
id: Date.now(),
|
|
46
|
+
method: 'append_paragraph',
|
|
47
|
+
params: {
|
|
48
|
+
doc_id: collabId,
|
|
49
|
+
text: seedText,
|
|
50
|
+
},
|
|
51
|
+
}),
|
|
52
|
+
});
|
|
53
|
+
if (!response.ok) {
|
|
54
|
+
throw new Error(`HTTP error! status: ${response.status}`);
|
|
55
|
+
}
|
|
56
|
+
const data = await response.json();
|
|
57
|
+
if (data.error) {
|
|
58
|
+
throw new Error(typeof data.error === 'string' ? data.error : JSON.stringify(data.error));
|
|
59
|
+
}
|
|
60
|
+
console.log('Created new room document:', collabId, data.result || data);
|
|
61
|
+
}
|
|
62
|
+
catch (error) {
|
|
63
|
+
console.warn('Unable to seed room via MCP, continuing with room navigation:', error);
|
|
64
|
+
}
|
|
65
|
+
navigateToRoom(roomId, collabId);
|
|
66
|
+
};
|
|
11
67
|
// Fetch available MCP tools from the server
|
|
12
68
|
const fetchMCPTools = async () => {
|
|
13
69
|
setIsLoadingTools(true);
|
|
@@ -65,7 +121,7 @@ export function DebugPlugin() {
|
|
|
65
121
|
id: Date.now(),
|
|
66
122
|
method: 'get_document',
|
|
67
123
|
params: {
|
|
68
|
-
doc_id:
|
|
124
|
+
doc_id: getCurrentCollabDocId()
|
|
69
125
|
}
|
|
70
126
|
})
|
|
71
127
|
});
|
|
@@ -100,7 +156,7 @@ export function DebugPlugin() {
|
|
|
100
156
|
id: Date.now(),
|
|
101
157
|
method: 'append_paragraph',
|
|
102
158
|
params: {
|
|
103
|
-
doc_id:
|
|
159
|
+
doc_id: getCurrentCollabDocId(),
|
|
104
160
|
text: paragraphText
|
|
105
161
|
}
|
|
106
162
|
})
|
|
@@ -196,7 +252,7 @@ export function DebugPlugin() {
|
|
|
196
252
|
console.log(`First ${keys.length} node keys:`, keys);
|
|
197
253
|
});
|
|
198
254
|
}
|
|
199
|
-
return (_jsxs(_Fragment, { children: [_jsx("button", { onClick: () => { reloadState(editor); }, children: "Reload State" }), _jsx("button", { onClick: () => { addParagraph(editor); }, children: "Add Paragraph" }), _jsx("button", { onClick: () => { first100Keys(editor); }, children: "100 First keys" }), _jsxs("div", { style: { marginLeft: '10px', display: 'inline-block' }, children: [_jsx("label", { htmlFor: "mcp-tools-select", style: { marginRight: '5px', fontSize: '12px' }, children: "MCP Tools:" }), _jsxs("select", { id: "mcp-tools-select", value: selectedTool, onChange: (e) => handleToolChange(e.target.value), disabled: isLoadingTools, style: {
|
|
255
|
+
return (_jsxs(_Fragment, { children: [_jsx("button", { onClick: () => { reloadState(editor); }, children: "Reload State" }), _jsx("button", { onClick: () => { void createNewRoomWithDocument(); }, children: "Create New Room" }), _jsx("button", { onClick: () => { addParagraph(editor); }, children: "Add Paragraph" }), _jsx("button", { onClick: () => { first100Keys(editor); }, children: "100 First keys" }), _jsxs("div", { style: { marginLeft: '10px', display: 'inline-block' }, children: [_jsx("label", { htmlFor: "mcp-tools-select", style: { marginRight: '5px', fontSize: '12px' }, children: "MCP Tools:" }), _jsxs("select", { id: "mcp-tools-select", value: selectedTool, onChange: (e) => handleToolChange(e.target.value), disabled: isLoadingTools, style: {
|
|
200
256
|
padding: '4px 8px',
|
|
201
257
|
borderRadius: '4px',
|
|
202
258
|
border: '1px solid #ccc',
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
/*
|
|
3
|
-
* Copyright (c)
|
|
3
|
+
* Copyright (c) 2025-2026 Datalayer, Inc.
|
|
4
4
|
* Distributed under the terms of the MIT License.
|
|
5
5
|
*/
|
|
6
6
|
import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext';
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*
|
|
2
|
-
* Copyright (c)
|
|
2
|
+
* Copyright (c) 2025-2026 Datalayer, Inc.
|
|
3
3
|
* Distributed under the terms of the MIT License.
|
|
4
4
|
*/
|
|
5
5
|
import { $convertFromMarkdownString, $convertToMarkdownString, CHECK_LIST, ELEMENT_TRANSFORMERS, MULTILINE_ELEMENT_TRANSFORMERS, TEXT_FORMAT_TRANSFORMERS, TEXT_MATCH_TRANSFORMERS, } from '@lexical/markdown';
|
package/lib/server/validation.js
CHANGED
package/lib/setupEnv.js
CHANGED
package/lib/tyes.dt.js
CHANGED
package/lib/utils/emoji-list.js
CHANGED
package/lib/utils/joinClasses.js
CHANGED
package/lib/utils/swipe.js
CHANGED
package/lib/utils/url.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@datalayer/lexical-loro",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.5",
|
|
4
4
|
"main": "lib/index.js",
|
|
5
5
|
"files": [
|
|
6
6
|
"lib/**/*.{css,d.ts,eot,gif,html,jpg,js,js.map,json,png,svg,woff2,ttf}",
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
"scripts": {
|
|
29
29
|
"build": "tsc -b && vite build",
|
|
30
30
|
"dev": "cross-env NODE_ENV=development concurrently \"npm:server:py:ws\" \"npm:server:py:mcp\" \"vite --host --port 3000\"",
|
|
31
|
-
"build:
|
|
31
|
+
"build:lib": "tsc",
|
|
32
32
|
"build:dev": "vite build",
|
|
33
33
|
"build:prod": "vite build --mode production",
|
|
34
34
|
"server:loro": "fkill -s :1235 && cross-env HOST=localhost PORT=1235 YPERSISTENCE=./.wss-loro tsx src/collab/loro/servers/ws/server.ts",
|
|
@@ -52,7 +52,7 @@
|
|
|
52
52
|
"server": "tsx dev/node-server.ts",
|
|
53
53
|
"server:py": "lexical-loro-server",
|
|
54
54
|
"server:py:dev": "python3 -m lexical_loro.cli",
|
|
55
|
-
"server:py:ws": "python3 -m lexical_loro.cli --host localhost --port 3002 --autosave-interval 5",
|
|
55
|
+
"server:py:ws": "fkill -s :3002 || true && python3 -m lexical_loro.cli --host localhost --port 3002 --autosave-interval 5",
|
|
56
56
|
"server:py:mcp": "python3 -m lexical_loro.mcp start --transport streamable-http --host 0.0.0.0 --port 3001 --websocket-url ws://localhost:3002 --documents-path ./documents --log-level DEBUG",
|
|
57
57
|
"test:js": "vitest run",
|
|
58
58
|
"test:py": "python3 -m pytest tests/ -v",
|
|
@@ -60,7 +60,7 @@
|
|
|
60
60
|
"test:py:watch": "python3 -m pytest tests/ -v --tb=short -f"
|
|
61
61
|
},
|
|
62
62
|
"dependencies": {
|
|
63
|
-
"@datalayer/primer-addons": "^1.0.
|
|
63
|
+
"@datalayer/primer-addons": "^1.0.12",
|
|
64
64
|
"@floating-ui/react": "^0.27.8",
|
|
65
65
|
"@lexical/clipboard": "^0.35.0",
|
|
66
66
|
"@lexical/code": "^0.35.0",
|