@datalayer/lexical-loro 0.2.5 → 1.0.0
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/package.json +1 -1
- package/lib/App.d.ts +0 -2
- package/lib/App.js +0 -141
- package/lib/Editor.d.ts +0 -2
- package/lib/Editor.js +0 -115
- package/lib/Settings.d.ts +0 -2
- package/lib/Settings.js +0 -57
- package/lib/appSettings.d.ts +0 -36
- package/lib/appSettings.js +0 -48
- package/lib/collab/loro/Bindings.d.ts +0 -41
- package/lib/collab/loro/Bindings.js +0 -99
- package/lib/collab/loro/Debug.d.ts +0 -33
- package/lib/collab/loro/Debug.js +0 -452
- package/lib/collab/loro/LexicalCollaborationContext.d.ts +0 -19
- package/lib/collab/loro/LexicalCollaborationContext.js +0 -52
- package/lib/collab/loro/LexicalCollaborationPlugin.d.ts +0 -24
- package/lib/collab/loro/LexicalCollaborationPlugin.js +0 -83
- package/lib/collab/loro/State.d.ts +0 -53
- package/lib/collab/loro/State.js +0 -94
- package/lib/collab/loro/components/LoroCollaborationUI.d.ts +0 -13
- package/lib/collab/loro/components/LoroCollaborationUI.js +0 -9
- package/lib/collab/loro/components/LoroCollaborators.d.ts +0 -8
- package/lib/collab/loro/components/LoroCollaborators.js +0 -102
- package/lib/collab/loro/components/index.d.ts +0 -2
- package/lib/collab/loro/components/index.js +0 -6
- package/lib/collab/loro/index.d.ts +0 -6
- package/lib/collab/loro/index.js +0 -10
- package/lib/collab/loro/integrators/BaseIntegrator.d.ts +0 -14
- package/lib/collab/loro/integrators/BaseIntegrator.js +0 -5
- package/lib/collab/loro/integrators/CounterIntegrator.d.ts +0 -23
- package/lib/collab/loro/integrators/CounterIntegrator.js +0 -44
- package/lib/collab/loro/integrators/ListIntegrator.d.ts +0 -23
- package/lib/collab/loro/integrators/ListIntegrator.js +0 -53
- package/lib/collab/loro/integrators/MapIntegrator.d.ts +0 -24
- package/lib/collab/loro/integrators/MapIntegrator.js +0 -235
- package/lib/collab/loro/integrators/TextIntegrator.d.ts +0 -25
- package/lib/collab/loro/integrators/TextIntegrator.js +0 -55
- package/lib/collab/loro/integrators/TreeIntegrator.d.ts +0 -36
- package/lib/collab/loro/integrators/TreeIntegrator.js +0 -251
- package/lib/collab/loro/nodes/NodeFactory.d.ts +0 -15
- package/lib/collab/loro/nodes/NodeFactory.js +0 -101
- package/lib/collab/loro/nodes/NodesMapper.d.ts +0 -120
- package/lib/collab/loro/nodes/NodesMapper.js +0 -277
- package/lib/collab/loro/propagators/DecoratorNodePropagator.d.ts +0 -60
- package/lib/collab/loro/propagators/DecoratorNodePropagator.js +0 -306
- package/lib/collab/loro/propagators/ElementNodePropagator.d.ts +0 -62
- package/lib/collab/loro/propagators/ElementNodePropagator.js +0 -326
- package/lib/collab/loro/propagators/LineBreakNodePropagator.d.ts +0 -57
- package/lib/collab/loro/propagators/LineBreakNodePropagator.js +0 -200
- package/lib/collab/loro/propagators/RootNodePropagator.d.ts +0 -55
- package/lib/collab/loro/propagators/RootNodePropagator.js +0 -174
- package/lib/collab/loro/propagators/TextNodePropagator.d.ts +0 -60
- package/lib/collab/loro/propagators/TextNodePropagator.js +0 -440
- package/lib/collab/loro/propagators/index.d.ts +0 -49
- package/lib/collab/loro/propagators/index.js +0 -30
- package/lib/collab/loro/provider/websocket.d.ts +0 -116
- package/lib/collab/loro/provider/websocket.js +0 -911
- package/lib/collab/loro/servers/index.d.ts +0 -0
- package/lib/collab/loro/servers/index.js +0 -4
- package/lib/collab/loro/servers/ws/callback.d.ts +0 -5
- package/lib/collab/loro/servers/ws/callback.js +0 -89
- package/lib/collab/loro/servers/ws/server.d.ts +0 -2
- package/lib/collab/loro/servers/ws/server.js +0 -29
- package/lib/collab/loro/servers/ws/utils.d.ts +0 -40
- package/lib/collab/loro/servers/ws/utils.js +0 -517
- package/lib/collab/loro/sync/SyncCursors.d.ts +0 -32
- package/lib/collab/loro/sync/SyncCursors.js +0 -475
- package/lib/collab/loro/sync/SyncLexicalToLoro.d.ts +0 -4
- package/lib/collab/loro/sync/SyncLexicalToLoro.js +0 -113
- package/lib/collab/loro/sync/SyncLoroToLexical.d.ts +0 -5
- package/lib/collab/loro/sync/SyncLoroToLexical.js +0 -100
- package/lib/collab/loro/types/LexicalNodeData.d.ts +0 -32
- package/lib/collab/loro/types/LexicalNodeData.js +0 -75
- package/lib/collab/loro/useCollaboration.d.ts +0 -12
- package/lib/collab/loro/useCollaboration.js +0 -260
- package/lib/collab/loro/utils/InitialContent.d.ts +0 -64
- package/lib/collab/loro/utils/InitialContent.js +0 -113
- package/lib/collab/loro/utils/LexicalToLoro.d.ts +0 -18
- package/lib/collab/loro/utils/LexicalToLoro.js +0 -100
- package/lib/collab/loro/utils/Utils.d.ts +0 -44
- package/lib/collab/loro/utils/Utils.js +0 -157
- package/lib/collab/loro/wsProvider.d.ts +0 -8
- package/lib/collab/loro/wsProvider.js +0 -35
- package/lib/collab/utils/invariant.d.ts +0 -1
- package/lib/collab/utils/invariant.js +0 -15
- package/lib/collab/utils/simpleDiffWithCursor.d.ts +0 -5
- package/lib/collab/utils/simpleDiffWithCursor.js +0 -35
- package/lib/collab/yjs/Bindings.d.ts +0 -23
- package/lib/collab/yjs/Bindings.js +0 -26
- package/lib/collab/yjs/Debug.d.ts +0 -23
- package/lib/collab/yjs/Debug.js +0 -213
- package/lib/collab/yjs/LexicalCollaborationContext.d.ts +0 -10
- package/lib/collab/yjs/LexicalCollaborationContext.js +0 -37
- package/lib/collab/yjs/LexicalCollaborationPlugin.d.ts +0 -21
- package/lib/collab/yjs/LexicalCollaborationPlugin.js +0 -63
- package/lib/collab/yjs/State.d.ts +0 -51
- package/lib/collab/yjs/State.js +0 -35
- package/lib/collab/yjs/nodes/AnyCollabNode.d.ts +0 -5
- package/lib/collab/yjs/nodes/AnyCollabNode.js +0 -1
- package/lib/collab/yjs/nodes/CollabDecoratorNode.d.ts +0 -22
- package/lib/collab/yjs/nodes/CollabDecoratorNode.js +0 -64
- package/lib/collab/yjs/nodes/CollabElementNode.d.ts +0 -40
- package/lib/collab/yjs/nodes/CollabElementNode.js +0 -462
- package/lib/collab/yjs/nodes/CollabLineBreakNode.d.ts +0 -19
- package/lib/collab/yjs/nodes/CollabLineBreakNode.js +0 -44
- package/lib/collab/yjs/nodes/CollabTextNode.d.ts +0 -25
- package/lib/collab/yjs/nodes/CollabTextNode.js +0 -103
- package/lib/collab/yjs/provider/websocket.d.ts +0 -88
- package/lib/collab/yjs/provider/websocket.js +0 -415
- package/lib/collab/yjs/servers/index.d.ts +0 -0
- package/lib/collab/yjs/servers/index.js +0 -0
- package/lib/collab/yjs/servers/ws/callback.d.ts +0 -5
- package/lib/collab/yjs/servers/ws/callback.js +0 -72
- package/lib/collab/yjs/servers/ws/server.d.ts +0 -2
- package/lib/collab/yjs/servers/ws/server.js +0 -25
- package/lib/collab/yjs/servers/ws/utils.d.ts +0 -49
- package/lib/collab/yjs/servers/ws/utils.js +0 -284
- package/lib/collab/yjs/sync/SyncCursors.d.ts +0 -39
- package/lib/collab/yjs/sync/SyncCursors.js +0 -351
- package/lib/collab/yjs/sync/SyncEditorStates.d.ts +0 -10
- package/lib/collab/yjs/sync/SyncEditorStates.js +0 -200
- package/lib/collab/yjs/useCollaboration.d.ts +0 -12
- package/lib/collab/yjs/useCollaboration.js +0 -255
- package/lib/collab/yjs/utils/Utils.d.ts +0 -25
- package/lib/collab/yjs/utils/Utils.js +0 -402
- package/lib/collab/yjs/wsProvider.d.ts +0 -3
- package/lib/collab/yjs/wsProvider.js +0 -21
- package/lib/commenting/index.d.ts +0 -41
- package/lib/commenting/index.js +0 -328
- package/lib/context/FlashMessageContext.d.ts +0 -7
- package/lib/context/FlashMessageContext.js +0 -24
- package/lib/context/SettingsContext.d.ts +0 -12
- package/lib/context/SettingsContext.js +0 -38
- package/lib/context/SharedHistoryContext.d.ts +0 -11
- package/lib/context/SharedHistoryContext.js +0 -11
- package/lib/context/ToolbarContext.d.ts +0 -65
- package/lib/context/ToolbarContext.js +0 -84
- package/lib/demo.d.ts +0 -12
- package/lib/demo.js +0 -45
- package/lib/hooks/useFlashMessage.d.ts +0 -2
- package/lib/hooks/useFlashMessage.js +0 -8
- package/lib/hooks/useModal.d.ts +0 -5
- package/lib/hooks/useModal.js +0 -26
- package/lib/hooks/useReport.d.ts +0 -1
- package/lib/hooks/useReport.js +0 -50
- package/lib/index.d.ts +0 -1
- package/lib/index.js +0 -5
- package/lib/nodes/AutocompleteNode.d.ts +0 -27
- package/lib/nodes/AutocompleteNode.js +0 -60
- package/lib/nodes/CounterComponent.d.ts +0 -6
- package/lib/nodes/CounterComponent.js +0 -137
- package/lib/nodes/CounterNode.d.ts +0 -23
- package/lib/nodes/CounterNode.js +0 -47
- package/lib/nodes/DateTimeNode/DateTimeComponent.d.ts +0 -8
- package/lib/nodes/DateTimeNode/DateTimeComponent.js +0 -119
- package/lib/nodes/DateTimeNode/DateTimeNode.d.ts +0 -27
- package/lib/nodes/DateTimeNode/DateTimeNode.js +0 -82
- package/lib/nodes/EmojiNode.d.ts +0 -18
- package/lib/nodes/EmojiNode.js +0 -54
- package/lib/nodes/EquationComponent.d.ts +0 -9
- package/lib/nodes/EquationComponent.js +0 -75
- package/lib/nodes/EquationNode.d.ts +0 -26
- package/lib/nodes/EquationNode.js +0 -109
- package/lib/nodes/ExcalidrawNode/ExcalidrawComponent.d.ts +0 -8
- package/lib/nodes/ExcalidrawNode/ExcalidrawComponent.js +0 -110
- package/lib/nodes/ExcalidrawNode/ExcalidrawImage.d.ts +0 -50
- package/lib/nodes/ExcalidrawNode/ExcalidrawImage.js +0 -55
- package/lib/nodes/ExcalidrawNode/index.d.ts +0 -32
- package/lib/nodes/ExcalidrawNode/index.js +0 -117
- package/lib/nodes/FigmaNode.d.ts +0 -20
- package/lib/nodes/FigmaNode.js +0 -52
- package/lib/nodes/ImageComponent.d.ts +0 -16
- package/lib/nodes/ImageComponent.js +0 -272
- package/lib/nodes/ImageNode.d.ts +0 -50
- package/lib/nodes/ImageNode.js +0 -151
- package/lib/nodes/InlineImageNode/InlineImageComponent.d.ts +0 -26
- package/lib/nodes/InlineImageNode/InlineImageComponent.js +0 -161
- package/lib/nodes/InlineImageNode/InlineImageNode.d.ts +0 -59
- package/lib/nodes/InlineImageNode/InlineImageNode.js +0 -162
- package/lib/nodes/KeywordNode.d.ts +0 -14
- package/lib/nodes/KeywordNode.js +0 -37
- package/lib/nodes/LayoutContainerNode.d.ts +0 -24
- package/lib/nodes/LayoutContainerNode.js +0 -95
- package/lib/nodes/LayoutItemNode.d.ts +0 -16
- package/lib/nodes/LayoutItemNode.js +0 -69
- package/lib/nodes/MentionNode.d.ts +0 -20
- package/lib/nodes/MentionNode.js +0 -85
- package/lib/nodes/PageBreakNode/index.d.ts +0 -17
- package/lib/nodes/PageBreakNode/index.js +0 -83
- package/lib/nodes/PlaygroundNodes.d.ts +0 -3
- package/lib/nodes/PlaygroundNodes.js +0 -75
- package/lib/nodes/PollComponent.d.ts +0 -9
- package/lib/nodes/PollComponent.js +0 -85
- package/lib/nodes/PollNode.d.ts +0 -43
- package/lib/nodes/PollNode.js +0 -153
- package/lib/nodes/SpecialTextNode.d.ts +0 -24
- package/lib/nodes/SpecialTextNode.js +0 -54
- package/lib/nodes/StickyComponent.d.ts +0 -10
- package/lib/nodes/StickyComponent.js +0 -162
- package/lib/nodes/StickyNode.d.ts +0 -31
- package/lib/nodes/StickyNode.js +0 -76
- package/lib/nodes/TweetNode.d.ts +0 -21
- package/lib/nodes/TweetNode.js +0 -119
- package/lib/nodes/YouTubeNode.d.ts +0 -22
- package/lib/nodes/YouTubeNode.js +0 -84
- package/lib/plugins/ActionsPlugin/index.d.ts +0 -5
- package/lib/plugins/ActionsPlugin/index.js +0 -168
- package/lib/plugins/AutoEmbedPlugin/index.d.ts +0 -19
- package/lib/plugins/AutoEmbedPlugin/index.js +0 -158
- package/lib/plugins/AutoLinkPlugin/index.d.ts +0 -2
- package/lib/plugins/AutoLinkPlugin/index.js +0 -15
- package/lib/plugins/AutocompletePlugin/index.d.ts +0 -10
- package/lib/plugins/AutocompletePlugin/index.js +0 -2477
- package/lib/plugins/CodeActionMenuPlugin/components/CopyButton/index.d.ts +0 -7
- package/lib/plugins/CodeActionMenuPlugin/components/CopyButton/index.js +0 -46
- package/lib/plugins/CodeActionMenuPlugin/components/PrettierButton/index.d.ts +0 -17
- package/lib/plugins/CodeActionMenuPlugin/components/PrettierButton/index.js +0 -115
- package/lib/plugins/CodeActionMenuPlugin/index.d.ts +0 -5
- package/lib/plugins/CodeActionMenuPlugin/index.js +0 -104
- package/lib/plugins/CodeActionMenuPlugin/utils.d.ts +0 -1
- package/lib/plugins/CodeActionMenuPlugin/utils.js +0 -22
- package/lib/plugins/CodeHighlightPrismPlugin/index.d.ts +0 -2
- package/lib/plugins/CodeHighlightPrismPlugin/index.js +0 -14
- package/lib/plugins/CodeHighlightShikiPlugin/index.d.ts +0 -2
- package/lib/plugins/CodeHighlightShikiPlugin/index.js +0 -14
- package/lib/plugins/CollapsiblePlugin/CollapsibleContainerNode.d.ts +0 -25
- package/lib/plugins/CollapsiblePlugin/CollapsibleContainerNode.js +0 -135
- package/lib/plugins/CollapsiblePlugin/CollapsibleContentNode.d.ts +0 -16
- package/lib/plugins/CollapsiblePlugin/CollapsibleContentNode.js +0 -83
- package/lib/plugins/CollapsiblePlugin/CollapsibleTitleNode.d.ts +0 -16
- package/lib/plugins/CollapsiblePlugin/CollapsibleTitleNode.js +0 -85
- package/lib/plugins/CollapsiblePlugin/CollapsibleUtils.d.ts +0 -2
- package/lib/plugins/CollapsiblePlugin/CollapsibleUtils.js +0 -12
- package/lib/plugins/CollapsiblePlugin/index.d.ts +0 -3
- package/lib/plugins/CollapsiblePlugin/index.js +0 -132
- package/lib/plugins/CommentPlugin/index.d.ts +0 -9
- package/lib/plugins/CommentPlugin/index.js +0 -460
- package/lib/plugins/ComponentPickerPlugin/index.d.ts +0 -2
- package/lib/plugins/ComponentPickerPlugin/index.js +0 -276
- package/lib/plugins/ContextMenuPlugin/index.d.ts +0 -2
- package/lib/plugins/ContextMenuPlugin/index.js +0 -112
- package/lib/plugins/CounterPlugin/index.d.ts +0 -3
- package/lib/plugins/CounterPlugin/index.js +0 -24
- package/lib/plugins/DateTimePlugin/index.d.ts +0 -8
- package/lib/plugins/DateTimePlugin/index.js +0 -28
- package/lib/plugins/DebugPlugin/index.d.ts +0 -3
- package/lib/plugins/DebugPlugin/index.js +0 -219
- package/lib/plugins/DocsPlugin/index.d.ts +0 -2
- package/lib/plugins/DocsPlugin/index.js +0 -4
- package/lib/plugins/DragDropPastePlugin/index.d.ts +0 -1
- package/lib/plugins/DragDropPastePlugin/index.js +0 -37
- package/lib/plugins/DraggableBlockPlugin/index.d.ts +0 -12
- package/lib/plugins/DraggableBlockPlugin/index.js +0 -36
- package/lib/plugins/EmojiPickerPlugin/index.d.ts +0 -1
- package/lib/plugins/EmojiPickerPlugin/index.js +0 -84
- package/lib/plugins/EmojisPlugin/index.d.ts +0 -2
- package/lib/plugins/EmojisPlugin/index.js +0 -56
- package/lib/plugins/EquationsPlugin/index.d.ts +0 -14
- package/lib/plugins/EquationsPlugin/index.js +0 -34
- package/lib/plugins/ExcalidrawPlugin/index.d.ts +0 -5
- package/lib/plugins/ExcalidrawPlugin/index.js +0 -44
- package/lib/plugins/FigmaPlugin/index.d.ts +0 -4
- package/lib/plugins/FigmaPlugin/index.js +0 -24
- package/lib/plugins/FloatingLinkEditorPlugin/index.d.ts +0 -15
- package/lib/plugins/FloatingLinkEditorPlugin/index.js +0 -280
- package/lib/plugins/FloatingTextFormatToolbarPlugin/index.d.ts +0 -7
- package/lib/plugins/FloatingTextFormatToolbarPlugin/index.js +0 -219
- package/lib/plugins/ImagesPlugin/index.d.ts +0 -24
- package/lib/plugins/ImagesPlugin/index.js +0 -195
- package/lib/plugins/InlineImagePlugin/index.d.ts +0 -17
- package/lib/plugins/InlineImagePlugin/index.js +0 -180
- package/lib/plugins/KeywordsPlugin/index.d.ts +0 -2
- package/lib/plugins/KeywordsPlugin/index.js +0 -35
- package/lib/plugins/LayoutPlugin/InsertLayoutDialog.d.ts +0 -6
- package/lib/plugins/LayoutPlugin/InsertLayoutDialog.js +0 -21
- package/lib/plugins/LayoutPlugin/LayoutPlugin.d.ts +0 -7
- package/lib/plugins/LayoutPlugin/LayoutPlugin.js +0 -135
- package/lib/plugins/LinkPlugin/index.d.ts +0 -6
- package/lib/plugins/LinkPlugin/index.js +0 -11
- package/lib/plugins/MarkdownShortcutPlugin/index.d.ts +0 -2
- package/lib/plugins/MarkdownShortcutPlugin/index.js +0 -6
- package/lib/plugins/MarkdownTransformers/index.d.ts +0 -8
- package/lib/plugins/MarkdownTransformers/index.js +0 -238
- package/lib/plugins/MaxLengthPlugin/index.d.ts +0 -3
- package/lib/plugins/MaxLengthPlugin/index.js +0 -41
- package/lib/plugins/MentionsPlugin/index.d.ts +0 -2
- package/lib/plugins/MentionsPlugin/index.js +0 -564
- package/lib/plugins/PageBreakPlugin/index.d.ts +0 -4
- package/lib/plugins/PageBreakPlugin/index.js +0 -31
- package/lib/plugins/PasteLogPlugin/index.d.ts +0 -2
- package/lib/plugins/PasteLogPlugin/index.js +0 -27
- package/lib/plugins/PollPlugin/index.d.ts +0 -8
- package/lib/plugins/PollPlugin/index.js +0 -38
- package/lib/plugins/ShortcutsPlugin/index.d.ts +0 -6
- package/lib/plugins/ShortcutsPlugin/index.js +0 -116
- package/lib/plugins/ShortcutsPlugin/shortcuts.d.ts +0 -59
- package/lib/plugins/ShortcutsPlugin/shortcuts.js +0 -173
- package/lib/plugins/SpecialTextPlugin/index.d.ts +0 -2
- package/lib/plugins/SpecialTextPlugin/index.js +0 -50
- package/lib/plugins/SpeechToTextPlugin/index.d.ts +0 -5
- package/lib/plugins/SpeechToTextPlugin/index.js +0 -86
- package/lib/plugins/StickyPlugin/index.d.ts +0 -2
- package/lib/plugins/StickyPlugin/index.js +0 -16
- package/lib/plugins/TabFocusPlugin/index.d.ts +0 -1
- package/lib/plugins/TabFocusPlugin/index.js +0 -38
- package/lib/plugins/TableActionMenuPlugin/index.d.ts +0 -5
- package/lib/plugins/TableActionMenuPlugin/index.js +0 -492
- package/lib/plugins/TableCellResizer/index.d.ts +0 -3
- package/lib/plugins/TableCellResizer/index.js +0 -297
- package/lib/plugins/TableHoverActionsPlugin/index.d.ts +0 -4
- package/lib/plugins/TableHoverActionsPlugin/index.js +0 -188
- package/lib/plugins/TableOfContentsPlugin/index.d.ts +0 -2
- package/lib/plugins/TableOfContentsPlugin/index.js +0 -116
- package/lib/plugins/TablePlugin.d.ts +0 -31
- package/lib/plugins/TablePlugin.js +0 -63
- package/lib/plugins/TestRecorderPlugin/index.d.ts +0 -3
- package/lib/plugins/TestRecorderPlugin/index.js +0 -346
- package/lib/plugins/ToolbarPlugin/fontSize.d.ts +0 -9
- package/lib/plugins/ToolbarPlugin/fontSize.js +0 -84
- package/lib/plugins/ToolbarPlugin/index.d.ts +0 -9
- package/lib/plugins/ToolbarPlugin/index.js +0 -500
- package/lib/plugins/ToolbarPlugin/utils.d.ts +0 -26
- package/lib/plugins/ToolbarPlugin/utils.js +0 -247
- package/lib/plugins/TreeViewPlugin/index.d.ts +0 -2
- package/lib/plugins/TreeViewPlugin/index.js +0 -7
- package/lib/plugins/TwitterPlugin/index.d.ts +0 -4
- package/lib/plugins/TwitterPlugin/index.js +0 -24
- package/lib/plugins/TypingPerfPlugin/index.d.ts +0 -2
- package/lib/plugins/TypingPerfPlugin/index.js +0 -97
- package/lib/plugins/YouTubePlugin/index.d.ts +0 -4
- package/lib/plugins/YouTubePlugin/index.js +0 -24
- package/lib/server/validation.d.ts +0 -1
- package/lib/server/validation.js +0 -115
- package/lib/setupEnv.d.ts +0 -2
- package/lib/setupEnv.js +0 -29
- package/lib/themes/CommentEditorTheme.d.ts +0 -4
- package/lib/themes/CommentEditorTheme.js +0 -11
- package/lib/themes/PlaygroundEditorTheme.d.ts +0 -4
- package/lib/themes/PlaygroundEditorTheme.js +0 -124
- package/lib/themes/StickyEditorTheme.d.ts +0 -4
- package/lib/themes/StickyEditorTheme.js +0 -11
- package/lib/tyes.dt.d.ts +0 -12
- package/lib/tyes.dt.js +0 -4
- package/lib/ui/Button.d.ts +0 -12
- package/lib/ui/Button.js +0 -6
- package/lib/ui/ColorPicker.d.ts +0 -14
- package/lib/ui/ColorPicker.js +0 -219
- package/lib/ui/ContentEditable.d.ts +0 -9
- package/lib/ui/ContentEditable.js +0 -6
- package/lib/ui/Dialog.d.ts +0 -10
- package/lib/ui/Dialog.js +0 -8
- package/lib/ui/DropDown.d.ts +0 -18
- package/lib/ui/DropDown.js +0 -133
- package/lib/ui/DropdownColorPicker.d.ts +0 -13
- package/lib/ui/DropdownColorPicker.js +0 -6
- package/lib/ui/EquationEditor.d.ts +0 -8
- package/lib/ui/EquationEditor.js +0 -11
- package/lib/ui/ExcalidrawModal.d.ts +0 -42
- package/lib/ui/ExcalidrawModal.js +0 -103
- package/lib/ui/FileInput.d.ts +0 -10
- package/lib/ui/FileInput.js +0 -5
- package/lib/ui/FlashMessage.d.ts +0 -7
- package/lib/ui/FlashMessage.js +0 -6
- package/lib/ui/ImageResizer.d.ts +0 -17
- package/lib/ui/ImageResizer.js +0 -171
- package/lib/ui/KatexEquationAlterer.d.ts +0 -8
- package/lib/ui/KatexEquationAlterer.js +0 -23
- package/lib/ui/KatexRenderer.d.ts +0 -6
- package/lib/ui/KatexRenderer.js +0 -24
- package/lib/ui/Modal.d.ts +0 -9
- package/lib/ui/Modal.js +0 -48
- package/lib/ui/Select.d.ts +0 -8
- package/lib/ui/Select.js +0 -5
- package/lib/ui/Switch.d.ts +0 -8
- package/lib/ui/Switch.js +0 -6
- package/lib/ui/TextInput.d.ts +0 -13
- package/lib/ui/TextInput.js +0 -7
- package/lib/utils/docSerialization.d.ts +0 -3
- package/lib/utils/docSerialization.js +0 -60
- package/lib/utils/emoji-list.d.ts +0 -20
- package/lib/utils/emoji-list.js +0 -16609
- package/lib/utils/getDOMRangeRect.d.ts +0 -8
- package/lib/utils/getDOMRangeRect.js +0 -26
- package/lib/utils/getSelectedNode.d.ts +0 -2
- package/lib/utils/getSelectedNode.js +0 -28
- package/lib/utils/getThemeSelector.d.ts +0 -2
- package/lib/utils/getThemeSelector.js +0 -14
- package/lib/utils/isMobileWidth.d.ts +0 -7
- package/lib/utils/isMobileWidth.js +0 -11
- package/lib/utils/joinClasses.d.ts +0 -1
- package/lib/utils/joinClasses.js +0 -7
- package/lib/utils/setFloatingElemPosition.d.ts +0 -1
- package/lib/utils/setFloatingElemPosition.js +0 -59
- package/lib/utils/setFloatingElemPositionForLinkEditor.d.ts +0 -1
- package/lib/utils/setFloatingElemPositionForLinkEditor.js +0 -36
- package/lib/utils/swipe.d.ts +0 -4
- package/lib/utils/swipe.js +0 -94
- package/lib/utils/url.d.ts +0 -2
- package/lib/utils/url.js +0 -31
|
@@ -1,517 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
* Copyright (c) 2023-2025 Datalayer, Inc.
|
|
3
|
-
* Distributed under the terms of the MIT License.
|
|
4
|
-
*/
|
|
5
|
-
import { LoroDoc, EphemeralStore } from 'loro-crdt';
|
|
6
|
-
import * as map from 'lib0/map';
|
|
7
|
-
import * as eventloop from 'lib0/eventloop';
|
|
8
|
-
import { messageEphemeral, messageQueryEphemeral, messageQuerySnapshot, messageUpdate, } from '../../provider/websocket';
|
|
9
|
-
import { callbackIntegrator, isCallbackSet } from './callback';
|
|
10
|
-
import { initializeLoroDocWithLexicalContent } from '../../utils/InitialContent';
|
|
11
|
-
const pingTimeout = 30000;
|
|
12
|
-
const CALLBACK_DEBOUNCE_WAIT = parseInt(process.env.CALLBACK_DEBOUNCE_WAIT || '2000');
|
|
13
|
-
const CALLBACK_DEBOUNCE_MAXWAIT = parseInt(process.env.CALLBACK_DEBOUNCE_MAXWAIT || '10000');
|
|
14
|
-
const debouncer = eventloop.createDebouncer(CALLBACK_DEBOUNCE_WAIT, CALLBACK_DEBOUNCE_MAXWAIT);
|
|
15
|
-
const wsReadyStateConnecting = 0;
|
|
16
|
-
const wsReadyStateOpen = 1;
|
|
17
|
-
const wsReadyStateClosing = 2;
|
|
18
|
-
const wsReadyStateClosed = 3;
|
|
19
|
-
const persistenceDir = process.env.YPERSISTENCE;
|
|
20
|
-
// Helper function to log tree structure for debugging
|
|
21
|
-
const logTreeStructure = (doc, context) => {
|
|
22
|
-
try {
|
|
23
|
-
console.log(`[Server] ${context} - Tree Structure Debug:`);
|
|
24
|
-
// Try to get the tree container using getTree method
|
|
25
|
-
try {
|
|
26
|
-
const tree = doc.getTree('tree');
|
|
27
|
-
if (tree) {
|
|
28
|
-
const nodes = tree.nodes();
|
|
29
|
-
console.log(`[Server] Total nodes in tree: ${nodes.length}`);
|
|
30
|
-
// Helper function to recursively log tree structure
|
|
31
|
-
const logTreeStructureRecursive = (node, prefix = '', isLast = true, depth = 0) => {
|
|
32
|
-
const data = Object.fromEntries(node.data.entries());
|
|
33
|
-
const treeId = node.id;
|
|
34
|
-
const elementType = data.elementType || 'no-type';
|
|
35
|
-
const connector = depth === 0 ? '' : (isLast ? '└── ' : '├── ');
|
|
36
|
-
const nodeInfo = `TreeID(${treeId.slice(0, 8)}...) [${elementType}]`;
|
|
37
|
-
console.log(`[Server] ${prefix}${connector}${nodeInfo}`);
|
|
38
|
-
const children = node.children();
|
|
39
|
-
if (children && children.length > 0) {
|
|
40
|
-
children.forEach((child, index) => {
|
|
41
|
-
const isLastChild = index === children.length - 1;
|
|
42
|
-
const childPrefix = prefix + (depth === 0 ? '' : (isLast ? ' ' : '│ '));
|
|
43
|
-
logTreeStructureRecursive(child, childPrefix, isLastChild, depth + 1);
|
|
44
|
-
});
|
|
45
|
-
}
|
|
46
|
-
};
|
|
47
|
-
// Find and display all root nodes
|
|
48
|
-
const rootNodes = nodes.filter((node) => {
|
|
49
|
-
const parent = node.parent();
|
|
50
|
-
const data = Object.fromEntries(node.data.entries());
|
|
51
|
-
return !parent || data.isRoot;
|
|
52
|
-
});
|
|
53
|
-
console.log(`[Server] Root nodes: ${rootNodes.length}`);
|
|
54
|
-
console.log('');
|
|
55
|
-
if (rootNodes.length === 0) {
|
|
56
|
-
console.log('[Server] ⚠️ No root nodes found!');
|
|
57
|
-
}
|
|
58
|
-
else {
|
|
59
|
-
rootNodes.forEach((root, index) => {
|
|
60
|
-
const isLastRoot = index === rootNodes.length - 1;
|
|
61
|
-
logTreeStructureRecursive(root, '', isLastRoot, 0);
|
|
62
|
-
});
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
else {
|
|
66
|
-
console.log(`[Server] No tree container found`);
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
catch (treeError) {
|
|
70
|
-
console.log(`[Server] Error accessing tree container:`, treeError.message);
|
|
71
|
-
}
|
|
72
|
-
// Try export with different modes for debugging
|
|
73
|
-
try {
|
|
74
|
-
const snapshot = doc.export({ mode: 'snapshot' });
|
|
75
|
-
console.log(`[Server] Snapshot size: ${snapshot.length} bytes`);
|
|
76
|
-
const update = doc.export({ mode: 'update' });
|
|
77
|
-
console.log(`[Server] Update size: ${update.length} bytes`);
|
|
78
|
-
}
|
|
79
|
-
catch (exportError) {
|
|
80
|
-
console.log(`[Server] Error exporting:`, exportError.message);
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
catch (error) {
|
|
84
|
-
console.warn(`[Server] Error logging tree structure:`, error);
|
|
85
|
-
}
|
|
86
|
-
};
|
|
87
|
-
/**
|
|
88
|
-
*
|
|
89
|
-
*/
|
|
90
|
-
let persistence = null;
|
|
91
|
-
if (typeof persistenceDir === 'string') {
|
|
92
|
-
console.log('Persistence directory configured: "' + persistenceDir + '" but Loro persistence not yet implemented');
|
|
93
|
-
// TODO: Implement actual Loro document persistence
|
|
94
|
-
// For now, disable persistence to keep documents in memory
|
|
95
|
-
console.log('Disabling persistence - documents will be kept in memory only');
|
|
96
|
-
persistence = null;
|
|
97
|
-
// Uncomment and implement when ready for actual persistence:
|
|
98
|
-
// persistence = {
|
|
99
|
-
// provider: null, // Replace with Loro-compatible persistence provider
|
|
100
|
-
// bindState: async (docName, doc: WSSharedDoc) => {
|
|
101
|
-
// // TODO: Implement Loro document persistence loading
|
|
102
|
-
// console.warn(`Loading state for document: ${docName}`)
|
|
103
|
-
// },
|
|
104
|
-
// writeState: async (docName, doc: WSSharedDoc) => {
|
|
105
|
-
// // TODO: Implement Loro document state writing
|
|
106
|
-
// console.warn(`Saving state for document: ${docName}`)
|
|
107
|
-
// }
|
|
108
|
-
// }
|
|
109
|
-
}
|
|
110
|
-
/**
|
|
111
|
-
*
|
|
112
|
-
*/
|
|
113
|
-
export const setPersistence = persistence_ => {
|
|
114
|
-
persistence = persistence_;
|
|
115
|
-
};
|
|
116
|
-
/**
|
|
117
|
-
*
|
|
118
|
-
*/
|
|
119
|
-
export const getPersistence = () => persistence;
|
|
120
|
-
/**
|
|
121
|
-
*
|
|
122
|
-
*/
|
|
123
|
-
export const docs = new Map();
|
|
124
|
-
/**
|
|
125
|
-
* @type {(ydoc: Y.Doc) => Promise<void>}
|
|
126
|
-
*/
|
|
127
|
-
let contentInitializor = _ydoc => Promise.resolve();
|
|
128
|
-
/**
|
|
129
|
-
* This function is called once every time a Loro document is created. You can
|
|
130
|
-
* use it to pull data from an external source or initialize content.
|
|
131
|
-
*/
|
|
132
|
-
export const setContentInitializor = (f) => {
|
|
133
|
-
contentInitializor = f;
|
|
134
|
-
};
|
|
135
|
-
/**
|
|
136
|
-
* Gets a Doc by name, whether in memory or on disk
|
|
137
|
-
*/
|
|
138
|
-
export const getDoc = (docname) => map.setIfUndefined(docs, docname, () => {
|
|
139
|
-
const doc = new WSSharedDoc(docname);
|
|
140
|
-
if (persistence !== null) {
|
|
141
|
-
persistence.bindState(docname, doc);
|
|
142
|
-
}
|
|
143
|
-
docs.set(docname, doc);
|
|
144
|
-
return doc;
|
|
145
|
-
});
|
|
146
|
-
/**
|
|
147
|
-
*
|
|
148
|
-
*/
|
|
149
|
-
const sendMessage = (doc, conn, message) => {
|
|
150
|
-
if (conn.readyState === wsReadyStateClosing || conn.readyState === wsReadyStateClosed) {
|
|
151
|
-
closeConn(doc, conn);
|
|
152
|
-
}
|
|
153
|
-
try {
|
|
154
|
-
// console.log(`Sending message to ${conn.id || 'unknown'}`)
|
|
155
|
-
conn.send(JSON.stringify(message), {}, err => { if (err != null)
|
|
156
|
-
closeConn(doc, conn); });
|
|
157
|
-
}
|
|
158
|
-
catch (e) {
|
|
159
|
-
console.warn(e);
|
|
160
|
-
closeConn(doc, conn);
|
|
161
|
-
}
|
|
162
|
-
};
|
|
163
|
-
/**
|
|
164
|
-
*
|
|
165
|
-
*/
|
|
166
|
-
const sendMessageBinary = (doc, conn, message) => {
|
|
167
|
-
if (conn.readyState === wsReadyStateClosing || conn.readyState === wsReadyStateClosed) {
|
|
168
|
-
closeConn(doc, conn);
|
|
169
|
-
}
|
|
170
|
-
try {
|
|
171
|
-
// console.log(`Sending message to ${conn.id || 'unknown'}`)
|
|
172
|
-
conn.send(message, {}, err => { if (err != null)
|
|
173
|
-
closeConn(doc, conn); });
|
|
174
|
-
}
|
|
175
|
-
catch (e) {
|
|
176
|
-
console.warn(e);
|
|
177
|
-
closeConn(doc, conn);
|
|
178
|
-
}
|
|
179
|
-
};
|
|
180
|
-
/**
|
|
181
|
-
*
|
|
182
|
-
*/
|
|
183
|
-
const messageListener = (conn, doc, message) => {
|
|
184
|
-
try {
|
|
185
|
-
let messageData = null;
|
|
186
|
-
let messageStr = '';
|
|
187
|
-
if (typeof message === 'string') {
|
|
188
|
-
messageStr = message;
|
|
189
|
-
}
|
|
190
|
-
else if (message instanceof ArrayBuffer) {
|
|
191
|
-
try {
|
|
192
|
-
const decoder = new TextDecoder();
|
|
193
|
-
messageStr = decoder.decode(message);
|
|
194
|
-
}
|
|
195
|
-
catch (decodeError) {
|
|
196
|
-
console.warn(`[Server] messageListener - Failed to decode ArrayBuffer as string, treating as binary Loro update`);
|
|
197
|
-
// If decoding fails, treat as raw binary Loro update
|
|
198
|
-
const updateBytes = new Uint8Array(message);
|
|
199
|
-
doc.doc.import(updateBytes);
|
|
200
|
-
// Broadcast the update to other connections
|
|
201
|
-
doc.conns.forEach((_, c) => {
|
|
202
|
-
if (c !== conn) {
|
|
203
|
-
sendMessageBinary(doc, c, new Uint8Array(message));
|
|
204
|
-
}
|
|
205
|
-
});
|
|
206
|
-
return;
|
|
207
|
-
}
|
|
208
|
-
}
|
|
209
|
-
else if (message instanceof Uint8Array) {
|
|
210
|
-
try {
|
|
211
|
-
const decoder = new TextDecoder();
|
|
212
|
-
messageStr = decoder.decode(message);
|
|
213
|
-
}
|
|
214
|
-
catch (decodeError) {
|
|
215
|
-
console.warn(`[Server] messageListener - Failed to decode Uint8Array as string, treating as binary Loro update`);
|
|
216
|
-
// If decoding fails, treat as raw binary Loro update
|
|
217
|
-
doc.doc.import(message);
|
|
218
|
-
// Broadcast the update to other connections
|
|
219
|
-
doc.conns.forEach((_, c) => {
|
|
220
|
-
if (c !== conn) {
|
|
221
|
-
sendMessageBinary(doc, c, message);
|
|
222
|
-
}
|
|
223
|
-
});
|
|
224
|
-
return;
|
|
225
|
-
}
|
|
226
|
-
}
|
|
227
|
-
else {
|
|
228
|
-
console.warn(`[Server] messageListener - Unknown message type:`, typeof message);
|
|
229
|
-
return;
|
|
230
|
-
}
|
|
231
|
-
if (!messageStr || messageStr.length === 0) {
|
|
232
|
-
return;
|
|
233
|
-
}
|
|
234
|
-
try {
|
|
235
|
-
messageData = JSON.parse(messageStr);
|
|
236
|
-
}
|
|
237
|
-
catch (parseError) {
|
|
238
|
-
console.warn(`[Server] messageListener - JSON parse error:`, parseError.message);
|
|
239
|
-
console.warn(`[Server] messageListener - Raw message:`, messageStr.substring(0, 500));
|
|
240
|
-
return;
|
|
241
|
-
}
|
|
242
|
-
console.log(`[Server] Received message type: ${messageData.type} for doc: ${doc.name}`);
|
|
243
|
-
switch (messageData.type) {
|
|
244
|
-
case messageQuerySnapshot:
|
|
245
|
-
// Client is requesting a snapshot - send current document state
|
|
246
|
-
const requestId = Math.random().toString(36).substr(2, 9);
|
|
247
|
-
console.log(`[Server] Client requesting snapshot for doc: ${doc.name} (Request ID: ${requestId})`);
|
|
248
|
-
// Log tree structure before creating snapshot
|
|
249
|
-
// logTreeStructure(doc.doc, `Before creating snapshot (Request ID: ${requestId})`)
|
|
250
|
-
try {
|
|
251
|
-
const snapshot = doc.doc.export({ mode: 'snapshot' });
|
|
252
|
-
console.log(`[Server] Sending snapshot response: ${snapshot.length} bytes (Request ID: ${requestId})`);
|
|
253
|
-
// Verify the snapshot contains expected content
|
|
254
|
-
const tree = doc.doc.getTree('tree');
|
|
255
|
-
const nodes = tree.nodes();
|
|
256
|
-
console.log(`[Server] Snapshot contains ${nodes.length} nodes from server document`);
|
|
257
|
-
// Send binary snapshot data directly instead of wrapped message
|
|
258
|
-
conn.send(snapshot);
|
|
259
|
-
}
|
|
260
|
-
catch (snapshotError) {
|
|
261
|
-
console.error(`[Server] ERROR creating/sending snapshot:`, snapshotError.message);
|
|
262
|
-
console.error(`[Server] Stack:`, snapshotError.stack);
|
|
263
|
-
}
|
|
264
|
-
break;
|
|
265
|
-
case messageEphemeral:
|
|
266
|
-
try {
|
|
267
|
-
const ephemeralBytes = new Uint8Array(messageData.ephemeral);
|
|
268
|
-
// Mark this connection as the sender to avoid echo
|
|
269
|
-
doc.lastEphemeralSender = conn;
|
|
270
|
-
// Debug: Check ephemeral store state before and after
|
|
271
|
-
const beforeStates = doc.ephemeralStore.getAllStates();
|
|
272
|
-
const beforeKeys = Object.keys(beforeStates);
|
|
273
|
-
doc.ephemeralStore.apply(ephemeralBytes);
|
|
274
|
-
const afterStates = doc.ephemeralStore.getAllStates();
|
|
275
|
-
const afterKeys = Object.keys(afterStates);
|
|
276
|
-
console.log(`📡 SERVER DEBUG - Applied ephemeral update from ${conn.id}:`, {
|
|
277
|
-
bytesLength: ephemeralBytes.length,
|
|
278
|
-
beforeKeys,
|
|
279
|
-
afterKeys,
|
|
280
|
-
newKeys: afterKeys.filter(k => !beforeKeys.includes(k)),
|
|
281
|
-
totalConnections: doc.conns.size
|
|
282
|
-
});
|
|
283
|
-
}
|
|
284
|
-
catch (ephemeralError) {
|
|
285
|
-
console.warn('messageEphemeral - ERROR applying ephemeral update');
|
|
286
|
-
// Clear sender reference on error
|
|
287
|
-
doc.lastEphemeralSender = null;
|
|
288
|
-
}
|
|
289
|
-
break;
|
|
290
|
-
case messageQueryEphemeral:
|
|
291
|
-
// Send current ephemeral state to requesting client
|
|
292
|
-
try {
|
|
293
|
-
const allStates = doc.ephemeralStore.getAllStates();
|
|
294
|
-
const allKeys = Object.keys(allStates);
|
|
295
|
-
const ephemeralUpdate = doc.ephemeralStore.encodeAll();
|
|
296
|
-
console.log(`📡 SERVER DEBUG - Client ${conn.id} requesting ephemeral state:`, {
|
|
297
|
-
allKeysAvailable: allKeys,
|
|
298
|
-
encodedLength: ephemeralUpdate.length,
|
|
299
|
-
totalConnections: doc.conns.size
|
|
300
|
-
});
|
|
301
|
-
const ephemeralResponse = {
|
|
302
|
-
type: 'ephemeral',
|
|
303
|
-
ephemeral: Array.from(ephemeralUpdate),
|
|
304
|
-
docId: doc.name
|
|
305
|
-
};
|
|
306
|
-
sendMessage(doc, conn, ephemeralResponse);
|
|
307
|
-
}
|
|
308
|
-
catch (error) {
|
|
309
|
-
console.warn('[Server] messageQueryEphemeral - ERROR encoding/sending ephemeral state:', error);
|
|
310
|
-
}
|
|
311
|
-
break;
|
|
312
|
-
case messageUpdate:
|
|
313
|
-
// Apply the Loro update to the document.
|
|
314
|
-
const updateBytes = new Uint8Array(messageData.update);
|
|
315
|
-
const i = doc.doc.import(updateBytes);
|
|
316
|
-
// logTreeStructure(doc.doc, `After applying update from client ${conn.id || 'unknown'}`)
|
|
317
|
-
// Create properly formatted message for broadcasting
|
|
318
|
-
// Send the update to all other connections
|
|
319
|
-
let broadcastCount = 0;
|
|
320
|
-
doc.conns.forEach((_, c) => {
|
|
321
|
-
if (c !== conn) {
|
|
322
|
-
console.log(`Broadcasting Update to connection: ${c.id}`);
|
|
323
|
-
sendMessage(doc, c, messageData);
|
|
324
|
-
broadcastCount++;
|
|
325
|
-
}
|
|
326
|
-
});
|
|
327
|
-
// Trigger callback if configured
|
|
328
|
-
if (isCallbackSet) {
|
|
329
|
-
debouncer(() => callbackIntegrator(doc));
|
|
330
|
-
}
|
|
331
|
-
break;
|
|
332
|
-
}
|
|
333
|
-
}
|
|
334
|
-
catch (err) {
|
|
335
|
-
console.warn(err);
|
|
336
|
-
// Note: LoroDoc doesn't have emit method, using console.warn instead
|
|
337
|
-
console.warn('Message handling error:', err);
|
|
338
|
-
}
|
|
339
|
-
};
|
|
340
|
-
/**
|
|
341
|
-
* @param {WSSharedDoc} doc
|
|
342
|
-
* @param {any} conn
|
|
343
|
-
*/
|
|
344
|
-
const closeConn = (doc, conn) => {
|
|
345
|
-
if (doc.conns.has(conn)) {
|
|
346
|
-
console.log(`Closing connection: ${conn.id || 'unknown'} for document: ${doc.name}`);
|
|
347
|
-
/**
|
|
348
|
-
* @type {Set<string>}
|
|
349
|
-
*/
|
|
350
|
-
const controlledKeys = doc.conns.get(conn);
|
|
351
|
-
doc.conns.delete(conn);
|
|
352
|
-
// Remove ephemeral state controlled by this connection
|
|
353
|
-
if (controlledKeys) {
|
|
354
|
-
controlledKeys.forEach(key => {
|
|
355
|
-
doc.ephemeralStore.delete(key);
|
|
356
|
-
});
|
|
357
|
-
}
|
|
358
|
-
console.log(`Remaining connections for document ${doc.name}: ${doc.conns.size}`);
|
|
359
|
-
if (doc.conns.size === 0) {
|
|
360
|
-
if (persistence !== null) {
|
|
361
|
-
// if persisted, we store state and cleanup document
|
|
362
|
-
console.log(`[Server] Persisting document ${doc.name} before cleanup`);
|
|
363
|
-
persistence.writeState(doc.name, doc).then(() => {
|
|
364
|
-
// Cleanup WSSharedDoc resources (no destroy method needed for Loro)
|
|
365
|
-
console.log(`[Server] Document ${doc.name} persisted and cleaned up`);
|
|
366
|
-
});
|
|
367
|
-
docs.delete(doc.name);
|
|
368
|
-
}
|
|
369
|
-
else {
|
|
370
|
-
// No persistence configured - keep document in memory for reconnections
|
|
371
|
-
console.log(`[Server] No persistence configured - keeping document ${doc.name} in memory for future connections`);
|
|
372
|
-
// logTreeStructure(doc.doc, `Document ${doc.name} structure before keeping in memory`)
|
|
373
|
-
}
|
|
374
|
-
}
|
|
375
|
-
}
|
|
376
|
-
conn.close();
|
|
377
|
-
};
|
|
378
|
-
/**
|
|
379
|
-
* @param {import('ws').WebSocket} conn
|
|
380
|
-
* @param {import('http').IncomingMessage} req
|
|
381
|
-
* @param {any} opts
|
|
382
|
-
*/
|
|
383
|
-
export const setupWSConnection = (conn, req, { docName = (req.url || '').slice(1).split('?')[0] } = {}) => {
|
|
384
|
-
conn.binaryType = 'arraybuffer';
|
|
385
|
-
// get doc, initialize if it does not exist yet
|
|
386
|
-
const doc = getDoc(docName);
|
|
387
|
-
// Assign a unique ID to the connection for logging
|
|
388
|
-
conn.id = `conn-${conn._socket?.remoteAddress || 'unknown'}:${conn._socket?.remotePort || Math.random()}`;
|
|
389
|
-
console.log(`New connection established: ${conn.id} for document: ${docName} (LoroDoc peerId: ${doc.doc.peerId})`);
|
|
390
|
-
doc.conns.set(conn, new Set());
|
|
391
|
-
// listen and reply to events
|
|
392
|
-
conn.on('message', message => messageListener(conn, doc, message));
|
|
393
|
-
// Check if connection is still alive
|
|
394
|
-
let pongReceived = true;
|
|
395
|
-
const pingInterval = setInterval(() => {
|
|
396
|
-
if (!pongReceived) {
|
|
397
|
-
if (doc.conns.has(conn)) {
|
|
398
|
-
closeConn(doc, conn);
|
|
399
|
-
}
|
|
400
|
-
clearInterval(pingInterval);
|
|
401
|
-
}
|
|
402
|
-
else if (doc.conns.has(conn)) {
|
|
403
|
-
pongReceived = false;
|
|
404
|
-
try {
|
|
405
|
-
conn.ping();
|
|
406
|
-
}
|
|
407
|
-
catch (e) {
|
|
408
|
-
closeConn(doc, conn);
|
|
409
|
-
clearInterval(pingInterval);
|
|
410
|
-
}
|
|
411
|
-
}
|
|
412
|
-
}, pingTimeout);
|
|
413
|
-
conn.on('close', () => {
|
|
414
|
-
closeConn(doc, conn);
|
|
415
|
-
clearInterval(pingInterval);
|
|
416
|
-
});
|
|
417
|
-
conn.on('pong', () => {
|
|
418
|
-
pongReceived = true;
|
|
419
|
-
});
|
|
420
|
-
// put the following in a variables in a block so the interval integrators don't keep in in
|
|
421
|
-
// scope
|
|
422
|
-
{
|
|
423
|
-
// Send initial snapshot to new client
|
|
424
|
-
// Log tree structure before creating initial snapshot
|
|
425
|
-
// logTreeStructure(doc.doc, `Before creating initial snapshot for new client ${conn.id}`)
|
|
426
|
-
try {
|
|
427
|
-
const snapshot = doc.doc.export({ mode: 'snapshot' });
|
|
428
|
-
console.log(`[Server] Sending initial snapshot to new client: ${snapshot.length} bytes`);
|
|
429
|
-
// Verify the snapshot contains expected content
|
|
430
|
-
const tree = doc.doc.getTree('tree');
|
|
431
|
-
const nodes = tree.nodes();
|
|
432
|
-
console.log(`[Server] Initial snapshot contains ${nodes.length} nodes from server document`);
|
|
433
|
-
// Send binary snapshot data directly instead of wrapped message
|
|
434
|
-
conn.send(snapshot);
|
|
435
|
-
}
|
|
436
|
-
catch (snapshotError) {
|
|
437
|
-
console.error(`[Server] ERROR creating/sending initial snapshot:`, snapshotError.message);
|
|
438
|
-
console.error(`[Server] Stack:`, snapshotError.stack);
|
|
439
|
-
}
|
|
440
|
-
// Send current ephemeral state if any
|
|
441
|
-
const ephemeralUpdate = doc.ephemeralStore.encodeAll();
|
|
442
|
-
if (ephemeralUpdate.length > 0) {
|
|
443
|
-
const ephemeralMessage = {
|
|
444
|
-
type: 'ephemeral',
|
|
445
|
-
ephemeral: Array.from(ephemeralUpdate),
|
|
446
|
-
docId: doc.name
|
|
447
|
-
};
|
|
448
|
-
sendMessage(doc, conn, ephemeralMessage);
|
|
449
|
-
}
|
|
450
|
-
}
|
|
451
|
-
};
|
|
452
|
-
export class WSSharedDoc {
|
|
453
|
-
name;
|
|
454
|
-
doc;
|
|
455
|
-
connections;
|
|
456
|
-
ephemeralStore;
|
|
457
|
-
conns;
|
|
458
|
-
_conns;
|
|
459
|
-
lastEphemeralSender;
|
|
460
|
-
constructor(name) {
|
|
461
|
-
this.name = name;
|
|
462
|
-
this.doc = new LoroDoc();
|
|
463
|
-
// Initialize the document with default Lexical content
|
|
464
|
-
console.log(`[Server] Initializing document '${name}' with default content`);
|
|
465
|
-
initializeLoroDocWithLexicalContent(this.doc);
|
|
466
|
-
/**
|
|
467
|
-
* Maps from conn to set of controlled ephemeral keys. Delete all keys when this conn is closed
|
|
468
|
-
* @type {Map<Object, Set<string>>}
|
|
469
|
-
*/
|
|
470
|
-
this.connections = new Map();
|
|
471
|
-
this.conns = new Map();
|
|
472
|
-
this._conns = new Set();
|
|
473
|
-
/**
|
|
474
|
-
* @type {EphemeralStore}
|
|
475
|
-
*/
|
|
476
|
-
this.ephemeralStore = new EphemeralStore(30000); // 30 second timeout
|
|
477
|
-
// Store the last sender to avoid echo loops
|
|
478
|
-
this.lastEphemeralSender = null;
|
|
479
|
-
/**
|
|
480
|
-
* @type {Array<function>}
|
|
481
|
-
*/
|
|
482
|
-
const ephemeralChangeIntegrator = (event) => {
|
|
483
|
-
// Only broadcast if there are actual changes
|
|
484
|
-
if (event.added.length > 0 || event.updated.length > 0 || event.removed.length > 0) {
|
|
485
|
-
try {
|
|
486
|
-
const encodedData = this.ephemeralStore.encodeAll();
|
|
487
|
-
// Skip broadcast if no actual data to send
|
|
488
|
-
if (encodedData.length === 0) {
|
|
489
|
-
return;
|
|
490
|
-
}
|
|
491
|
-
const message = {
|
|
492
|
-
type: 'ephemeral',
|
|
493
|
-
ephemeral: Array.from(encodedData),
|
|
494
|
-
docId: this.name
|
|
495
|
-
};
|
|
496
|
-
// Broadcast to all connections EXCEPT the one that sent the last ephemeral update
|
|
497
|
-
this.conns.forEach((_, conn) => {
|
|
498
|
-
if (conn !== this.lastEphemeralSender) {
|
|
499
|
-
sendMessage(this, conn, message);
|
|
500
|
-
}
|
|
501
|
-
});
|
|
502
|
-
// Clear the sender reference after broadcast
|
|
503
|
-
this.lastEphemeralSender = null;
|
|
504
|
-
}
|
|
505
|
-
catch (broadcastError) {
|
|
506
|
-
console.warn(`[Server] ephemeralChangeIntegrator - ERROR broadcasting:`, {
|
|
507
|
-
error: broadcastError.message,
|
|
508
|
-
stack: broadcastError.stack
|
|
509
|
-
});
|
|
510
|
-
}
|
|
511
|
-
}
|
|
512
|
-
};
|
|
513
|
-
this.ephemeralStore.subscribe(ephemeralChangeIntegrator);
|
|
514
|
-
// Note: LoroDoc doesn't have 'on' method like Y.Doc
|
|
515
|
-
// Update handling will be done through message processing
|
|
516
|
-
}
|
|
517
|
-
}
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
import type { BaseSelection, NodeKey } from 'lexical';
|
|
2
|
-
import type { Binding } from '../Bindings';
|
|
3
|
-
import { Provider, UserState } from '../State';
|
|
4
|
-
/*****************************************************************************/
|
|
5
|
-
export type CursorSelection = {
|
|
6
|
-
anchor: {
|
|
7
|
-
key: NodeKey;
|
|
8
|
-
offset: number;
|
|
9
|
-
};
|
|
10
|
-
caret: HTMLElement;
|
|
11
|
-
color: string;
|
|
12
|
-
focus: {
|
|
13
|
-
key: NodeKey;
|
|
14
|
-
offset: number;
|
|
15
|
-
};
|
|
16
|
-
name: HTMLSpanElement;
|
|
17
|
-
selections: Array<HTMLElement>;
|
|
18
|
-
};
|
|
19
|
-
export type CollabCursor = {
|
|
20
|
-
color: string;
|
|
21
|
-
name: string;
|
|
22
|
-
selection: null | CursorSelection;
|
|
23
|
-
};
|
|
24
|
-
export type SyncCursorPositionsOptions = {
|
|
25
|
-
getAwarenessStates?: (binding: Binding, provider: Provider) => Map<number, UserState>;
|
|
26
|
-
};
|
|
27
|
-
export type SyncCursorPositionsFn = (binding: Binding, provider: Provider, options?: SyncCursorPositionsOptions) => void;
|
|
28
|
-
/*****************************************************************************/
|
|
29
|
-
export declare function syncCursorPositions(binding: Binding, provider: Provider, options?: SyncCursorPositionsOptions): void;
|
|
30
|
-
export declare function syncLexicalSelectionToLoro(binding: Binding, provider: Provider, prevSelection: null | BaseSelection, nextSelection: null | BaseSelection): void;
|
|
31
|
-
/*****************************************************************************/
|
|
32
|
-
export declare function $syncLocalCursorPosition(binding: Binding, provider: Provider): void;
|