@datalayer/lexical-loro 1.0.2 → 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.
Files changed (402) hide show
  1. package/README.md +2 -2
  2. package/lib/App.d.ts +2 -0
  3. package/lib/App.js +141 -0
  4. package/lib/Editor.d.ts +2 -0
  5. package/lib/Editor.js +116 -0
  6. package/lib/Settings.d.ts +2 -0
  7. package/lib/Settings.js +57 -0
  8. package/lib/appSettings.d.ts +36 -0
  9. package/lib/appSettings.js +48 -0
  10. package/lib/collab/loro/Bindings.d.ts +41 -0
  11. package/lib/collab/loro/Bindings.js +99 -0
  12. package/lib/collab/loro/Debug.d.ts +33 -0
  13. package/lib/collab/loro/Debug.js +452 -0
  14. package/lib/collab/loro/LexicalCollaborationContext.d.ts +19 -0
  15. package/lib/collab/loro/LexicalCollaborationContext.js +52 -0
  16. package/lib/collab/loro/LexicalCollaborationPlugin.d.ts +29 -0
  17. package/lib/collab/loro/LexicalCollaborationPlugin.js +111 -0
  18. package/lib/collab/loro/State.d.ts +53 -0
  19. package/lib/collab/loro/State.js +94 -0
  20. package/lib/collab/loro/components/LoroCollaborationUI.d.ts +13 -0
  21. package/lib/collab/loro/components/LoroCollaborationUI.js +9 -0
  22. package/lib/collab/loro/components/LoroCollaborators.d.ts +8 -0
  23. package/lib/collab/loro/components/LoroCollaborators.js +90 -0
  24. package/lib/collab/loro/components/index.d.ts +2 -0
  25. package/lib/collab/loro/components/index.js +6 -0
  26. package/lib/collab/loro/index.d.ts +6 -0
  27. package/lib/collab/loro/index.js +10 -0
  28. package/lib/collab/loro/integrators/BaseIntegrator.d.ts +14 -0
  29. package/lib/collab/loro/integrators/BaseIntegrator.js +5 -0
  30. package/lib/collab/loro/integrators/CounterIntegrator.d.ts +23 -0
  31. package/lib/collab/loro/integrators/CounterIntegrator.js +44 -0
  32. package/lib/collab/loro/integrators/ListIntegrator.d.ts +23 -0
  33. package/lib/collab/loro/integrators/ListIntegrator.js +53 -0
  34. package/lib/collab/loro/integrators/MapIntegrator.d.ts +24 -0
  35. package/lib/collab/loro/integrators/MapIntegrator.js +235 -0
  36. package/lib/collab/loro/integrators/TextIntegrator.d.ts +25 -0
  37. package/lib/collab/loro/integrators/TextIntegrator.js +55 -0
  38. package/lib/collab/loro/integrators/TreeIntegrator.d.ts +41 -0
  39. package/lib/collab/loro/integrators/TreeIntegrator.js +293 -0
  40. package/lib/collab/loro/nodes/NodeFactory.d.ts +15 -0
  41. package/lib/collab/loro/nodes/NodeFactory.js +80 -0
  42. package/lib/collab/loro/nodes/NodesMapper.d.ts +120 -0
  43. package/lib/collab/loro/nodes/NodesMapper.js +289 -0
  44. package/lib/collab/loro/propagators/DecoratorNodePropagator.d.ts +60 -0
  45. package/lib/collab/loro/propagators/DecoratorNodePropagator.js +306 -0
  46. package/lib/collab/loro/propagators/ElementNodePropagator.d.ts +62 -0
  47. package/lib/collab/loro/propagators/ElementNodePropagator.js +393 -0
  48. package/lib/collab/loro/propagators/LineBreakNodePropagator.d.ts +57 -0
  49. package/lib/collab/loro/propagators/LineBreakNodePropagator.js +200 -0
  50. package/lib/collab/loro/propagators/RootNodePropagator.d.ts +55 -0
  51. package/lib/collab/loro/propagators/RootNodePropagator.js +174 -0
  52. package/lib/collab/loro/propagators/TextNodePropagator.d.ts +60 -0
  53. package/lib/collab/loro/propagators/TextNodePropagator.js +450 -0
  54. package/lib/collab/loro/propagators/index.d.ts +49 -0
  55. package/lib/collab/loro/propagators/index.js +30 -0
  56. package/lib/collab/loro/provider/websocket.d.ts +117 -0
  57. package/lib/collab/loro/provider/websocket.js +946 -0
  58. package/lib/collab/loro/servers/index.d.ts +0 -0
  59. package/lib/collab/loro/servers/index.js +4 -0
  60. package/lib/collab/loro/servers/ws/callback.d.ts +5 -0
  61. package/lib/collab/loro/servers/ws/callback.js +89 -0
  62. package/lib/collab/loro/servers/ws/server.d.ts +2 -0
  63. package/lib/collab/loro/servers/ws/server.js +29 -0
  64. package/lib/collab/loro/servers/ws/utils.d.ts +40 -0
  65. package/lib/collab/loro/servers/ws/utils.js +517 -0
  66. package/lib/collab/loro/sync/SyncCursors.d.ts +32 -0
  67. package/lib/collab/loro/sync/SyncCursors.js +501 -0
  68. package/lib/collab/loro/sync/SyncLexicalToLoro.d.ts +4 -0
  69. package/lib/collab/loro/sync/SyncLexicalToLoro.js +152 -0
  70. package/lib/collab/loro/sync/SyncLoroToLexical.d.ts +5 -0
  71. package/lib/collab/loro/sync/SyncLoroToLexical.js +106 -0
  72. package/lib/collab/loro/types/LexicalNodeData.d.ts +32 -0
  73. package/lib/collab/loro/types/LexicalNodeData.js +75 -0
  74. package/lib/collab/loro/useCollaboration.d.ts +12 -0
  75. package/lib/collab/loro/useCollaboration.js +405 -0
  76. package/lib/collab/loro/utils/InitialContent.d.ts +64 -0
  77. package/lib/collab/loro/utils/InitialContent.js +113 -0
  78. package/lib/collab/loro/utils/Invariant.d.ts +15 -0
  79. package/lib/collab/loro/utils/Invariant.js +24 -0
  80. package/lib/collab/loro/utils/LexicalToLoro.d.ts +18 -0
  81. package/lib/collab/loro/utils/LexicalToLoro.js +100 -0
  82. package/lib/collab/loro/utils/Utils.d.ts +44 -0
  83. package/lib/collab/loro/utils/Utils.js +157 -0
  84. package/lib/collab/loro/wsProvider.d.ts +8 -0
  85. package/lib/collab/loro/wsProvider.js +52 -0
  86. package/lib/collab/utils/invariant.d.ts +1 -0
  87. package/lib/collab/utils/invariant.js +15 -0
  88. package/lib/collab/utils/simpleDiffWithCursor.d.ts +5 -0
  89. package/lib/collab/utils/simpleDiffWithCursor.js +35 -0
  90. package/lib/collab/yjs/Bindings.d.ts +23 -0
  91. package/lib/collab/yjs/Bindings.js +26 -0
  92. package/lib/collab/yjs/Debug.d.ts +23 -0
  93. package/lib/collab/yjs/Debug.js +213 -0
  94. package/lib/collab/yjs/LexicalCollaborationContext.d.ts +10 -0
  95. package/lib/collab/yjs/LexicalCollaborationContext.js +37 -0
  96. package/lib/collab/yjs/LexicalCollaborationPlugin.d.ts +21 -0
  97. package/lib/collab/yjs/LexicalCollaborationPlugin.js +63 -0
  98. package/lib/collab/yjs/State.d.ts +51 -0
  99. package/lib/collab/yjs/State.js +35 -0
  100. package/lib/collab/yjs/nodes/AnyCollabNode.d.ts +5 -0
  101. package/lib/collab/yjs/nodes/AnyCollabNode.js +1 -0
  102. package/lib/collab/yjs/nodes/CollabDecoratorNode.d.ts +22 -0
  103. package/lib/collab/yjs/nodes/CollabDecoratorNode.js +64 -0
  104. package/lib/collab/yjs/nodes/CollabElementNode.d.ts +40 -0
  105. package/lib/collab/yjs/nodes/CollabElementNode.js +462 -0
  106. package/lib/collab/yjs/nodes/CollabLineBreakNode.d.ts +19 -0
  107. package/lib/collab/yjs/nodes/CollabLineBreakNode.js +44 -0
  108. package/lib/collab/yjs/nodes/CollabTextNode.d.ts +25 -0
  109. package/lib/collab/yjs/nodes/CollabTextNode.js +103 -0
  110. package/lib/collab/yjs/provider/websocket.d.ts +88 -0
  111. package/lib/collab/yjs/provider/websocket.js +415 -0
  112. package/lib/collab/yjs/servers/index.d.ts +0 -0
  113. package/lib/collab/yjs/servers/index.js +0 -0
  114. package/lib/collab/yjs/servers/ws/callback.d.ts +5 -0
  115. package/lib/collab/yjs/servers/ws/callback.js +72 -0
  116. package/lib/collab/yjs/servers/ws/server.d.ts +2 -0
  117. package/lib/collab/yjs/servers/ws/server.js +25 -0
  118. package/lib/collab/yjs/servers/ws/utils.d.ts +49 -0
  119. package/lib/collab/yjs/servers/ws/utils.js +284 -0
  120. package/lib/collab/yjs/sync/SyncCursors.d.ts +39 -0
  121. package/lib/collab/yjs/sync/SyncCursors.js +351 -0
  122. package/lib/collab/yjs/sync/SyncEditorStates.d.ts +10 -0
  123. package/lib/collab/yjs/sync/SyncEditorStates.js +200 -0
  124. package/lib/collab/yjs/useCollaboration.d.ts +12 -0
  125. package/lib/collab/yjs/useCollaboration.js +255 -0
  126. package/lib/collab/yjs/utils/Utils.d.ts +25 -0
  127. package/lib/collab/yjs/utils/Utils.js +402 -0
  128. package/lib/collab/yjs/wsProvider.d.ts +3 -0
  129. package/lib/collab/yjs/wsProvider.js +21 -0
  130. package/lib/commenting/index.d.ts +41 -0
  131. package/lib/commenting/index.js +328 -0
  132. package/lib/context/FlashMessageContext.d.ts +7 -0
  133. package/lib/context/FlashMessageContext.js +24 -0
  134. package/lib/context/SettingsContext.d.ts +12 -0
  135. package/lib/context/SettingsContext.js +38 -0
  136. package/lib/context/SharedHistoryContext.d.ts +11 -0
  137. package/lib/context/SharedHistoryContext.js +11 -0
  138. package/lib/context/ToolbarContext.d.ts +65 -0
  139. package/lib/context/ToolbarContext.js +84 -0
  140. package/lib/demo.d.ts +12 -0
  141. package/lib/demo.js +45 -0
  142. package/lib/hooks/useFlashMessage.d.ts +2 -0
  143. package/lib/hooks/useFlashMessage.js +8 -0
  144. package/lib/hooks/useModal.d.ts +5 -0
  145. package/lib/hooks/useModal.js +26 -0
  146. package/lib/hooks/useReport.d.ts +1 -0
  147. package/lib/hooks/useReport.js +50 -0
  148. package/lib/index.d.ts +1 -0
  149. package/lib/index.js +5 -0
  150. package/lib/nodes/AutocompleteNode.d.ts +27 -0
  151. package/lib/nodes/AutocompleteNode.js +60 -0
  152. package/lib/nodes/CounterComponent.d.ts +6 -0
  153. package/lib/nodes/CounterComponent.js +137 -0
  154. package/lib/nodes/CounterNode.d.ts +23 -0
  155. package/lib/nodes/CounterNode.js +47 -0
  156. package/lib/nodes/DateTimeNode/DateTimeComponent.d.ts +8 -0
  157. package/lib/nodes/DateTimeNode/DateTimeComponent.js +119 -0
  158. package/lib/nodes/DateTimeNode/DateTimeNode.d.ts +27 -0
  159. package/lib/nodes/DateTimeNode/DateTimeNode.js +82 -0
  160. package/lib/nodes/EmojiNode.d.ts +18 -0
  161. package/lib/nodes/EmojiNode.js +54 -0
  162. package/lib/nodes/EquationComponent.d.ts +9 -0
  163. package/lib/nodes/EquationComponent.js +75 -0
  164. package/lib/nodes/EquationNode.d.ts +26 -0
  165. package/lib/nodes/EquationNode.js +109 -0
  166. package/lib/nodes/ExcalidrawNode/ExcalidrawComponent.d.ts +8 -0
  167. package/lib/nodes/ExcalidrawNode/ExcalidrawComponent.js +110 -0
  168. package/lib/nodes/ExcalidrawNode/ExcalidrawImage.d.ts +50 -0
  169. package/lib/nodes/ExcalidrawNode/ExcalidrawImage.js +55 -0
  170. package/lib/nodes/ExcalidrawNode/index.d.ts +32 -0
  171. package/lib/nodes/ExcalidrawNode/index.js +117 -0
  172. package/lib/nodes/FigmaNode.d.ts +20 -0
  173. package/lib/nodes/FigmaNode.js +52 -0
  174. package/lib/nodes/ImageComponent.d.ts +16 -0
  175. package/lib/nodes/ImageComponent.js +272 -0
  176. package/lib/nodes/ImageNode.d.ts +50 -0
  177. package/lib/nodes/ImageNode.js +151 -0
  178. package/lib/nodes/InlineImageNode/InlineImageComponent.d.ts +26 -0
  179. package/lib/nodes/InlineImageNode/InlineImageComponent.js +161 -0
  180. package/lib/nodes/InlineImageNode/InlineImageNode.d.ts +59 -0
  181. package/lib/nodes/InlineImageNode/InlineImageNode.js +162 -0
  182. package/lib/nodes/KeywordNode.d.ts +14 -0
  183. package/lib/nodes/KeywordNode.js +37 -0
  184. package/lib/nodes/LayoutContainerNode.d.ts +24 -0
  185. package/lib/nodes/LayoutContainerNode.js +95 -0
  186. package/lib/nodes/LayoutItemNode.d.ts +16 -0
  187. package/lib/nodes/LayoutItemNode.js +69 -0
  188. package/lib/nodes/MentionNode.d.ts +20 -0
  189. package/lib/nodes/MentionNode.js +85 -0
  190. package/lib/nodes/PageBreakNode/index.d.ts +17 -0
  191. package/lib/nodes/PageBreakNode/index.js +83 -0
  192. package/lib/nodes/PlaygroundNodes.d.ts +3 -0
  193. package/lib/nodes/PlaygroundNodes.js +75 -0
  194. package/lib/nodes/PollComponent.d.ts +9 -0
  195. package/lib/nodes/PollComponent.js +85 -0
  196. package/lib/nodes/PollNode.d.ts +43 -0
  197. package/lib/nodes/PollNode.js +153 -0
  198. package/lib/nodes/SpecialTextNode.d.ts +24 -0
  199. package/lib/nodes/SpecialTextNode.js +54 -0
  200. package/lib/nodes/StickyComponent.d.ts +10 -0
  201. package/lib/nodes/StickyComponent.js +162 -0
  202. package/lib/nodes/StickyNode.d.ts +31 -0
  203. package/lib/nodes/StickyNode.js +76 -0
  204. package/lib/nodes/TweetNode.d.ts +21 -0
  205. package/lib/nodes/TweetNode.js +119 -0
  206. package/lib/nodes/YouTubeNode.d.ts +22 -0
  207. package/lib/nodes/YouTubeNode.js +84 -0
  208. package/lib/plugins/ActionsPlugin/index.d.ts +5 -0
  209. package/lib/plugins/ActionsPlugin/index.js +168 -0
  210. package/lib/plugins/AutoEmbedPlugin/index.d.ts +19 -0
  211. package/lib/plugins/AutoEmbedPlugin/index.js +158 -0
  212. package/lib/plugins/AutoLinkPlugin/index.d.ts +2 -0
  213. package/lib/plugins/AutoLinkPlugin/index.js +15 -0
  214. package/lib/plugins/AutocompletePlugin/index.d.ts +10 -0
  215. package/lib/plugins/AutocompletePlugin/index.js +2477 -0
  216. package/lib/plugins/CodeActionMenuPlugin/components/CopyButton/index.d.ts +7 -0
  217. package/lib/plugins/CodeActionMenuPlugin/components/CopyButton/index.js +46 -0
  218. package/lib/plugins/CodeActionMenuPlugin/components/PrettierButton/index.d.ts +17 -0
  219. package/lib/plugins/CodeActionMenuPlugin/components/PrettierButton/index.js +115 -0
  220. package/lib/plugins/CodeActionMenuPlugin/index.d.ts +5 -0
  221. package/lib/plugins/CodeActionMenuPlugin/index.js +104 -0
  222. package/lib/plugins/CodeActionMenuPlugin/utils.d.ts +1 -0
  223. package/lib/plugins/CodeActionMenuPlugin/utils.js +22 -0
  224. package/lib/plugins/CodeHighlightPrismPlugin/index.d.ts +2 -0
  225. package/lib/plugins/CodeHighlightPrismPlugin/index.js +14 -0
  226. package/lib/plugins/CodeHighlightShikiPlugin/index.d.ts +2 -0
  227. package/lib/plugins/CodeHighlightShikiPlugin/index.js +14 -0
  228. package/lib/plugins/CollapsiblePlugin/CollapsibleContainerNode.d.ts +25 -0
  229. package/lib/plugins/CollapsiblePlugin/CollapsibleContainerNode.js +135 -0
  230. package/lib/plugins/CollapsiblePlugin/CollapsibleContentNode.d.ts +16 -0
  231. package/lib/plugins/CollapsiblePlugin/CollapsibleContentNode.js +83 -0
  232. package/lib/plugins/CollapsiblePlugin/CollapsibleTitleNode.d.ts +16 -0
  233. package/lib/plugins/CollapsiblePlugin/CollapsibleTitleNode.js +85 -0
  234. package/lib/plugins/CollapsiblePlugin/CollapsibleUtils.d.ts +2 -0
  235. package/lib/plugins/CollapsiblePlugin/CollapsibleUtils.js +12 -0
  236. package/lib/plugins/CollapsiblePlugin/index.d.ts +3 -0
  237. package/lib/plugins/CollapsiblePlugin/index.js +132 -0
  238. package/lib/plugins/CommentPlugin/index.d.ts +9 -0
  239. package/lib/plugins/CommentPlugin/index.js +460 -0
  240. package/lib/plugins/ComponentPickerPlugin/index.d.ts +2 -0
  241. package/lib/plugins/ComponentPickerPlugin/index.js +276 -0
  242. package/lib/plugins/ContextMenuPlugin/index.d.ts +2 -0
  243. package/lib/plugins/ContextMenuPlugin/index.js +112 -0
  244. package/lib/plugins/CounterPlugin/index.d.ts +3 -0
  245. package/lib/plugins/CounterPlugin/index.js +24 -0
  246. package/lib/plugins/DateTimePlugin/index.d.ts +8 -0
  247. package/lib/plugins/DateTimePlugin/index.js +28 -0
  248. package/lib/plugins/DebugPlugin/index.d.ts +3 -0
  249. package/lib/plugins/DebugPlugin/index.js +275 -0
  250. package/lib/plugins/DocsPlugin/index.d.ts +2 -0
  251. package/lib/plugins/DocsPlugin/index.js +4 -0
  252. package/lib/plugins/DragDropPastePlugin/index.d.ts +1 -0
  253. package/lib/plugins/DragDropPastePlugin/index.js +37 -0
  254. package/lib/plugins/DraggableBlockPlugin/index.d.ts +12 -0
  255. package/lib/plugins/DraggableBlockPlugin/index.js +36 -0
  256. package/lib/plugins/EmojiPickerPlugin/index.d.ts +1 -0
  257. package/lib/plugins/EmojiPickerPlugin/index.js +84 -0
  258. package/lib/plugins/EmojisPlugin/index.d.ts +2 -0
  259. package/lib/plugins/EmojisPlugin/index.js +56 -0
  260. package/lib/plugins/EquationsPlugin/index.d.ts +14 -0
  261. package/lib/plugins/EquationsPlugin/index.js +34 -0
  262. package/lib/plugins/ExcalidrawPlugin/index.d.ts +5 -0
  263. package/lib/plugins/ExcalidrawPlugin/index.js +44 -0
  264. package/lib/plugins/FigmaPlugin/index.d.ts +4 -0
  265. package/lib/plugins/FigmaPlugin/index.js +24 -0
  266. package/lib/plugins/FloatingLinkEditorPlugin/index.d.ts +15 -0
  267. package/lib/plugins/FloatingLinkEditorPlugin/index.js +280 -0
  268. package/lib/plugins/FloatingTextFormatToolbarPlugin/index.d.ts +7 -0
  269. package/lib/plugins/FloatingTextFormatToolbarPlugin/index.js +219 -0
  270. package/lib/plugins/ImagesPlugin/index.d.ts +24 -0
  271. package/lib/plugins/ImagesPlugin/index.js +195 -0
  272. package/lib/plugins/InlineImagePlugin/index.d.ts +17 -0
  273. package/lib/plugins/InlineImagePlugin/index.js +180 -0
  274. package/lib/plugins/KeywordsPlugin/index.d.ts +2 -0
  275. package/lib/plugins/KeywordsPlugin/index.js +35 -0
  276. package/lib/plugins/LayoutPlugin/InsertLayoutDialog.d.ts +6 -0
  277. package/lib/plugins/LayoutPlugin/InsertLayoutDialog.js +21 -0
  278. package/lib/plugins/LayoutPlugin/LayoutPlugin.d.ts +7 -0
  279. package/lib/plugins/LayoutPlugin/LayoutPlugin.js +135 -0
  280. package/lib/plugins/LinkPlugin/index.d.ts +6 -0
  281. package/lib/plugins/LinkPlugin/index.js +11 -0
  282. package/lib/plugins/MarkdownShortcutPlugin/index.d.ts +2 -0
  283. package/lib/plugins/MarkdownShortcutPlugin/index.js +6 -0
  284. package/lib/plugins/MarkdownTransformers/index.d.ts +8 -0
  285. package/lib/plugins/MarkdownTransformers/index.js +238 -0
  286. package/lib/plugins/MaxLengthPlugin/index.d.ts +3 -0
  287. package/lib/plugins/MaxLengthPlugin/index.js +41 -0
  288. package/lib/plugins/MentionsPlugin/index.d.ts +2 -0
  289. package/lib/plugins/MentionsPlugin/index.js +564 -0
  290. package/lib/plugins/PageBreakPlugin/index.d.ts +4 -0
  291. package/lib/plugins/PageBreakPlugin/index.js +31 -0
  292. package/lib/plugins/PasteLogPlugin/index.d.ts +2 -0
  293. package/lib/plugins/PasteLogPlugin/index.js +27 -0
  294. package/lib/plugins/PollPlugin/index.d.ts +8 -0
  295. package/lib/plugins/PollPlugin/index.js +38 -0
  296. package/lib/plugins/ShortcutsPlugin/index.d.ts +6 -0
  297. package/lib/plugins/ShortcutsPlugin/index.js +116 -0
  298. package/lib/plugins/ShortcutsPlugin/shortcuts.d.ts +59 -0
  299. package/lib/plugins/ShortcutsPlugin/shortcuts.js +173 -0
  300. package/lib/plugins/SpecialTextPlugin/index.d.ts +2 -0
  301. package/lib/plugins/SpecialTextPlugin/index.js +50 -0
  302. package/lib/plugins/SpeechToTextPlugin/index.d.ts +5 -0
  303. package/lib/plugins/SpeechToTextPlugin/index.js +86 -0
  304. package/lib/plugins/StickyPlugin/index.d.ts +2 -0
  305. package/lib/plugins/StickyPlugin/index.js +16 -0
  306. package/lib/plugins/TabFocusPlugin/index.d.ts +1 -0
  307. package/lib/plugins/TabFocusPlugin/index.js +38 -0
  308. package/lib/plugins/TableActionMenuPlugin/index.d.ts +5 -0
  309. package/lib/plugins/TableActionMenuPlugin/index.js +492 -0
  310. package/lib/plugins/TableCellResizer/index.d.ts +3 -0
  311. package/lib/plugins/TableCellResizer/index.js +297 -0
  312. package/lib/plugins/TableHoverActionsPlugin/index.d.ts +4 -0
  313. package/lib/plugins/TableHoverActionsPlugin/index.js +188 -0
  314. package/lib/plugins/TableOfContentsPlugin/index.d.ts +2 -0
  315. package/lib/plugins/TableOfContentsPlugin/index.js +116 -0
  316. package/lib/plugins/TablePlugin.d.ts +31 -0
  317. package/lib/plugins/TablePlugin.js +63 -0
  318. package/lib/plugins/TestRecorderPlugin/index.d.ts +3 -0
  319. package/lib/plugins/TestRecorderPlugin/index.js +346 -0
  320. package/lib/plugins/ToolbarPlugin/fontSize.d.ts +9 -0
  321. package/lib/plugins/ToolbarPlugin/fontSize.js +84 -0
  322. package/lib/plugins/ToolbarPlugin/index.d.ts +9 -0
  323. package/lib/plugins/ToolbarPlugin/index.js +500 -0
  324. package/lib/plugins/ToolbarPlugin/utils.d.ts +26 -0
  325. package/lib/plugins/ToolbarPlugin/utils.js +247 -0
  326. package/lib/plugins/TreeViewPlugin/index.d.ts +2 -0
  327. package/lib/plugins/TreeViewPlugin/index.js +7 -0
  328. package/lib/plugins/TwitterPlugin/index.d.ts +4 -0
  329. package/lib/plugins/TwitterPlugin/index.js +24 -0
  330. package/lib/plugins/TypingPerfPlugin/index.d.ts +2 -0
  331. package/lib/plugins/TypingPerfPlugin/index.js +97 -0
  332. package/lib/plugins/YouTubePlugin/index.d.ts +4 -0
  333. package/lib/plugins/YouTubePlugin/index.js +24 -0
  334. package/lib/server/validation.d.ts +1 -0
  335. package/lib/server/validation.js +115 -0
  336. package/lib/setupEnv.d.ts +2 -0
  337. package/lib/setupEnv.js +29 -0
  338. package/lib/themes/CommentEditorTheme.d.ts +4 -0
  339. package/lib/themes/CommentEditorTheme.js +11 -0
  340. package/lib/themes/PlaygroundEditorTheme.d.ts +4 -0
  341. package/lib/themes/PlaygroundEditorTheme.js +124 -0
  342. package/lib/themes/StickyEditorTheme.d.ts +4 -0
  343. package/lib/themes/StickyEditorTheme.js +11 -0
  344. package/lib/tyes.dt.d.ts +12 -0
  345. package/lib/tyes.dt.js +4 -0
  346. package/lib/ui/Button.d.ts +12 -0
  347. package/lib/ui/Button.js +6 -0
  348. package/lib/ui/ColorPicker.d.ts +14 -0
  349. package/lib/ui/ColorPicker.js +219 -0
  350. package/lib/ui/ContentEditable.d.ts +9 -0
  351. package/lib/ui/ContentEditable.js +6 -0
  352. package/lib/ui/Dialog.d.ts +10 -0
  353. package/lib/ui/Dialog.js +8 -0
  354. package/lib/ui/DropDown.d.ts +18 -0
  355. package/lib/ui/DropDown.js +133 -0
  356. package/lib/ui/DropdownColorPicker.d.ts +13 -0
  357. package/lib/ui/DropdownColorPicker.js +6 -0
  358. package/lib/ui/EquationEditor.d.ts +8 -0
  359. package/lib/ui/EquationEditor.js +11 -0
  360. package/lib/ui/ExcalidrawModal.d.ts +42 -0
  361. package/lib/ui/ExcalidrawModal.js +103 -0
  362. package/lib/ui/FileInput.d.ts +10 -0
  363. package/lib/ui/FileInput.js +5 -0
  364. package/lib/ui/FlashMessage.d.ts +7 -0
  365. package/lib/ui/FlashMessage.js +6 -0
  366. package/lib/ui/ImageResizer.d.ts +17 -0
  367. package/lib/ui/ImageResizer.js +171 -0
  368. package/lib/ui/KatexEquationAlterer.d.ts +8 -0
  369. package/lib/ui/KatexEquationAlterer.js +23 -0
  370. package/lib/ui/KatexRenderer.d.ts +6 -0
  371. package/lib/ui/KatexRenderer.js +24 -0
  372. package/lib/ui/Modal.d.ts +9 -0
  373. package/lib/ui/Modal.js +48 -0
  374. package/lib/ui/Select.d.ts +8 -0
  375. package/lib/ui/Select.js +5 -0
  376. package/lib/ui/Switch.d.ts +8 -0
  377. package/lib/ui/Switch.js +6 -0
  378. package/lib/ui/TextInput.d.ts +13 -0
  379. package/lib/ui/TextInput.js +7 -0
  380. package/lib/utils/docSerialization.d.ts +3 -0
  381. package/lib/utils/docSerialization.js +60 -0
  382. package/lib/utils/emoji-list.d.ts +20 -0
  383. package/lib/utils/emoji-list.js +16609 -0
  384. package/lib/utils/getDOMRangeRect.d.ts +8 -0
  385. package/lib/utils/getDOMRangeRect.js +26 -0
  386. package/lib/utils/getSelectedNode.d.ts +2 -0
  387. package/lib/utils/getSelectedNode.js +28 -0
  388. package/lib/utils/getThemeSelector.d.ts +2 -0
  389. package/lib/utils/getThemeSelector.js +14 -0
  390. package/lib/utils/isMobileWidth.d.ts +7 -0
  391. package/lib/utils/isMobileWidth.js +11 -0
  392. package/lib/utils/joinClasses.d.ts +1 -0
  393. package/lib/utils/joinClasses.js +7 -0
  394. package/lib/utils/setFloatingElemPosition.d.ts +1 -0
  395. package/lib/utils/setFloatingElemPosition.js +59 -0
  396. package/lib/utils/setFloatingElemPositionForLinkEditor.d.ts +1 -0
  397. package/lib/utils/setFloatingElemPositionForLinkEditor.js +36 -0
  398. package/lib/utils/swipe.d.ts +4 -0
  399. package/lib/utils/swipe.js +94 -0
  400. package/lib/utils/url.d.ts +2 -0
  401. package/lib/utils/url.js +31 -0
  402. package/package.json +4 -4
@@ -0,0 +1,450 @@
1
+ /*
2
+ * Copyright (c) 2025-2026 Datalayer, Inc.
3
+ * Distributed under the terms of the MIT License.
4
+ */
5
+ import { $createTextNode, $isTextNode } from 'lexical';
6
+ import { getNodeMapper } from '../nodes/NodesMapper';
7
+ import { $diffTextContentAndApplyDelta } from '../utils/Utils';
8
+ import { invariant } from '../utils/Invariant';
9
+ /**
10
+ * Create TextNode in Loro tree
11
+ */
12
+ export function createTextNodeInLoro(nodeKey, textContent, format, mode, parentId, index, lexicalNodeJSON, // JSON object from exportJSON()
13
+ options) {
14
+ const mapper = getNodeMapper();
15
+ // A text node is always a leaf with a parent element. A missing parent means
16
+ // the parent element was not synced first — surface it instead of creating an
17
+ // orphaned (unrenderable) node.
18
+ invariant(parentId !== undefined, 'createTextNodeInLoro: text node has no parent in Loro tree', { nodeKey });
19
+ // Use mapper to get or create the tree node
20
+ // Note: We can't pass lexicalNode directly due to context issues, but parentId should be sufficient
21
+ const treeNode = mapper.getLoroNodeByLexicalKey(nodeKey, undefined, // don't pass lexicalNode to avoid context issues
22
+ parentId, index);
23
+ // Store complete lexical node data as clean JSON if provided
24
+ if (lexicalNodeJSON) {
25
+ try {
26
+ // Store complete lexical JSON without the key
27
+ if ('key' in lexicalNodeJSON || '__key' in lexicalNodeJSON || 'lexicalKey' in lexicalNodeJSON) {
28
+ const { key, __key, lexicalKey, children, ...cleanedData } = lexicalNodeJSON;
29
+ treeNode.data.set('lexical', cleanedData);
30
+ }
31
+ else {
32
+ const { children, ...cleanedData } = lexicalNodeJSON;
33
+ treeNode.data.set('lexical', cleanedData);
34
+ }
35
+ }
36
+ catch (error) {
37
+ console.warn('Failed to store lexical node JSON for TextNode:', error);
38
+ }
39
+ }
40
+ // Store only essential metadata (elementType for debug panel)
41
+ treeNode.data.set('elementType', 'text');
42
+ treeNode.data.set('createdAt', Date.now());
43
+ // Return the TreeID from the node's ID
44
+ return treeNode.id;
45
+ }
46
+ /**
47
+ * Update TextNode in Loro tree
48
+ */
49
+ export function updateTextNodeInLoro(nodeKey, newTextContent, format, mode, lexicalNodeJSON, // JSON object from exportJSON()
50
+ options) {
51
+ const mapper = getNodeMapper();
52
+ // Updates must target an existing mapped node. Creating on update can
53
+ // accidentally create inline nodes at root when parent info is unavailable.
54
+ const treeID = mapper.getTreeIDByLexicalKey(nodeKey);
55
+ if (!treeID || !options?.tree.has(treeID)) {
56
+ return;
57
+ }
58
+ const treeNode = options.tree.getNodeByID(treeID);
59
+ if (!treeNode) {
60
+ return;
61
+ }
62
+ // Store complete lexical node data as clean JSON if provided.
63
+ if (lexicalNodeJSON) {
64
+ if ('key' in lexicalNodeJSON || '__key' in lexicalNodeJSON || 'lexicalKey' in lexicalNodeJSON) {
65
+ const { key, __key, lexicalKey, children, ...cleanedData } = lexicalNodeJSON;
66
+ treeNode.data.set('lexical', cleanedData);
67
+ }
68
+ else {
69
+ const { children, ...cleanedData } = lexicalNodeJSON;
70
+ treeNode.data.set('lexical', cleanedData);
71
+ }
72
+ }
73
+ // Update only essential metadata.
74
+ treeNode.data.set('elementType', 'text');
75
+ treeNode.data.set('updatedAt', Date.now());
76
+ }
77
+ /**
78
+ * Delete TextNode from Loro tree
79
+ */
80
+ export function deleteTextNodeInLoro(nodeKey, options) {
81
+ const mapper = getNodeMapper();
82
+ mapper.deleteMapping(nodeKey);
83
+ }
84
+ /**
85
+ * Create TextNode in Lexical from Loro tree data
86
+ */
87
+ export function createTextNodeFromLoro(treeId, parentNode, index, options) {
88
+ const { tree } = options;
89
+ if (!tree.has(treeId)) {
90
+ return null;
91
+ }
92
+ const treeNode = tree.getNodeByID(treeId);
93
+ if (!treeNode) {
94
+ return null;
95
+ }
96
+ // Get LexicalNodeData (JSON object format only)
97
+ const lexicalData = treeNode.data.get('lexical');
98
+ let textNode;
99
+ if (lexicalData && typeof lexicalData === 'object') {
100
+ try {
101
+ // lexicalData is a direct JSON object, use it to create a TextNode
102
+ const lexicalDataObj = lexicalData;
103
+ const textContent = lexicalDataObj.text || lexicalDataObj.__text || '';
104
+ const format = lexicalDataObj.format || lexicalDataObj.__format || 0;
105
+ const mode = lexicalDataObj.mode || lexicalDataObj.__mode || 0;
106
+ textNode = $createTextNode(textContent);
107
+ textNode.setFormat(format);
108
+ textNode.setMode(mode);
109
+ }
110
+ catch (error) {
111
+ console.warn('Failed to create TextNode from JSON data for TreeID:', treeId, error);
112
+ return null;
113
+ }
114
+ }
115
+ else {
116
+ // No lexical JSON data found - cannot create TextNode
117
+ console.warn('No lexical JSON data found for TextNode TreeID:', treeId);
118
+ return null;
119
+ }
120
+ // Apply mode if present (only for old format)
121
+ if (!lexicalData || typeof lexicalData !== 'string') {
122
+ // const mode = treeNode.data.get('mode');
123
+ // if (mode && typeof textNode.setMode === 'function') {
124
+ // textNode.setMode(mode);
125
+ // }
126
+ }
127
+ // Insert into the parent at the specified index
128
+ if (index !== undefined && index >= 0) {
129
+ parentNode.splice(index, 0, [textNode]);
130
+ }
131
+ else {
132
+ parentNode.append(textNode);
133
+ }
134
+ return textNode;
135
+ }
136
+ /**
137
+ * Update TextNode in Lexical from Loro tree data
138
+ */
139
+ export function updateTextNodeFromLoro(treeId, textNode, newParentNode, newIndex, options) {
140
+ const { tree } = options;
141
+ if (!tree.has(treeId)) {
142
+ return;
143
+ }
144
+ const treeNode = tree.getNodeByID(treeId);
145
+ if (!treeNode || treeNode.data.get('nodeType') !== 'text') {
146
+ return;
147
+ }
148
+ // Update text content if it has changed
149
+ const textContent = treeNode.data.get('textContent');
150
+ if (textContent !== undefined && typeof textContent === 'string' &&
151
+ textNode.getTextContent() !== textContent) {
152
+ const currentText = textNode.getTextContent();
153
+ $diffTextContentAndApplyDelta(textNode, textNode.getKey(), currentText, textContent);
154
+ }
155
+ // Update format if it has changed
156
+ const format = treeNode.data.get('format');
157
+ if (format !== undefined && typeof format === 'number') {
158
+ textNode.setFormat(format);
159
+ }
160
+ // Update mode if it has changed (skip for now due to type complexity)
161
+ // const mode = treeNode.data.get('mode');
162
+ // if (mode !== undefined && typeof lexicalNode.setMode === 'function') {
163
+ // lexicalNode.setMode(mode);
164
+ // }
165
+ // If parent or position changed, move the node
166
+ if (newParentNode && newIndex !== undefined) {
167
+ // Remove from current location
168
+ textNode.remove();
169
+ // Insert at new location
170
+ newParentNode.splice(newIndex, 0, [textNode]);
171
+ }
172
+ }
173
+ /**
174
+ * Delete TextNode from Lexical
175
+ */
176
+ export function deleteTextNodeFromLoro(treeId, lexicalNode, options) {
177
+ if ($isTextNode(lexicalNode)) {
178
+ lexicalNode.remove();
179
+ }
180
+ }
181
+ /**
182
+ * Utility to check if a tree node represents a TextNode
183
+ */
184
+ export function isTextNodeInTree(treeId, tree) {
185
+ if (!tree.has(treeId)) {
186
+ return false;
187
+ }
188
+ const treeNode = tree.getNodeByID(treeId);
189
+ return treeNode?.data.get('nodeType') === 'text';
190
+ }
191
+ /**
192
+ * Get TextNode data from Loro tree
193
+ */
194
+ export function getTextNodeDataFromTree(treeId, tree) {
195
+ if (!tree.has(treeId)) {
196
+ return null;
197
+ }
198
+ const treeNode = tree.getNodeByID(treeId);
199
+ if (!treeNode || treeNode.data.get('nodeType') !== 'text') {
200
+ return null;
201
+ }
202
+ return {
203
+ nodeType: 'text',
204
+ textContent: treeNode.data.get('textContent'),
205
+ format: treeNode.data.get('format'),
206
+ mode: treeNode.data.get('mode'),
207
+ createdAt: treeNode.data.get('createdAt'),
208
+ lastUpdated: treeNode.data.get('lastUpdated'),
209
+ };
210
+ }
211
+ /**
212
+ * Apply text formatting operations (bold, italic, etc.)
213
+ */
214
+ export function applyTextFormatInLoro(nodeKey, formatType, apply, options) {
215
+ const mapper = getNodeMapper();
216
+ // Get the existing Loro node from the mapper
217
+ const treeNode = mapper.getLoroNodeByLexicalKey(nodeKey);
218
+ if (!treeNode) {
219
+ return;
220
+ }
221
+ if (!treeNode || treeNode.data.get('nodeType') !== 'text') {
222
+ return;
223
+ }
224
+ // Check if the TreeNode's container is still valid
225
+ try {
226
+ // Try a simple read operation to verify the container is accessible
227
+ treeNode.data.get('format');
228
+ }
229
+ catch (error) {
230
+ console.warn(` TextNode ${nodeKey} container deleted during format check (normal during text operations):`, error.message);
231
+ return;
232
+ }
233
+ let currentFormat = treeNode.data.get('format') || 0;
234
+ const formatNumber = formatType;
235
+ if (apply) {
236
+ // Add the format flag
237
+ currentFormat = currentFormat | formatNumber;
238
+ }
239
+ else {
240
+ // Remove the format flag
241
+ currentFormat = currentFormat & ~formatNumber;
242
+ }
243
+ try {
244
+ treeNode.data.set('format', currentFormat);
245
+ treeNode.data.set('lastUpdated', Date.now());
246
+ }
247
+ catch (error) {
248
+ console.warn(` TextNode ${nodeKey} container deleted during format update (normal during text operations):`, error.message);
249
+ return;
250
+ }
251
+ }
252
+ /**
253
+ * Main propagate method for TextNode - propagates all mutation types
254
+ */
255
+ export function propagateTextNode(update, mutation, nodeKey, options) {
256
+ const { tree, peerId } = options;
257
+ switch (mutation) {
258
+ case 'created': {
259
+ const currentNode = update.editorState._nodeMap.get(nodeKey);
260
+ // Check if this node already exists in Loro
261
+ const mapper = getNodeMapper();
262
+ const existingTreeID = mapper.getTreeIDByLexicalKey(nodeKey);
263
+ if (existingTreeID && currentNode && $isTextNode(currentNode)) {
264
+ // Check if the existing text node has the correct parent relationship
265
+ const { currentParentId, expectedParentId } = update.editorState.read(() => {
266
+ const parent = currentNode.getParent();
267
+ const expectedParentId = parent ? mapper.getTreeIDByLexicalKey(parent.getKey()) : undefined;
268
+ // Get the current parent from Loro tree
269
+ let currentParentId;
270
+ try {
271
+ const treeNode = tree.getNodeByID(existingTreeID);
272
+ if (treeNode) {
273
+ const parentNode = treeNode.parent();
274
+ currentParentId = parentNode ? parentNode.id.toString() : undefined;
275
+ }
276
+ }
277
+ catch (error) {
278
+ console.warn(` Failed to get parent for existing TreeID ${existingTreeID}:`, error);
279
+ }
280
+ return { currentParentId, expectedParentId };
281
+ });
282
+ if (currentParentId === expectedParentId) {
283
+ return; // Skip creation since the parent relationship is correct
284
+ }
285
+ else {
286
+ // Get the actual TreeNode and its ID before deleting
287
+ let actualTreeID = existingTreeID;
288
+ try {
289
+ const treeNode = tree.getNodeByID(existingTreeID);
290
+ if (treeNode) {
291
+ actualTreeID = treeNode.id;
292
+ }
293
+ }
294
+ catch (error) {
295
+ console.warn(` Could not get TreeNode for ${existingTreeID} during creation:`, error);
296
+ }
297
+ // Clear the old mapping first to avoid conflicts
298
+ mapper.deleteMapping(nodeKey);
299
+ // Then delete the TreeNode from Loro tree
300
+ try {
301
+ if (tree.has(actualTreeID)) {
302
+ tree.delete(actualTreeID);
303
+ }
304
+ }
305
+ catch (error) {
306
+ console.warn(` Failed to delete TreeNode ${actualTreeID} during creation:`, error);
307
+ }
308
+ }
309
+ }
310
+ if (currentNode && $isTextNode(currentNode)) {
311
+ // Get parent, positioning, content, and serialized data using editor state context
312
+ const { parent, parentId, index, textContent, format, mode, lexicalNodeJSON } = update.editorState.read(() => {
313
+ const parent = currentNode.getParent();
314
+ // Get parentId from the mapper instead of constructing it manually
315
+ const mapper = getNodeMapper();
316
+ const parentId = parent ? mapper.getTreeIDByLexicalKey(parent.getKey()) : undefined;
317
+ const index = currentNode.getIndexWithinParent();
318
+ const textContent = currentNode.getTextContent();
319
+ const format = currentNode.getFormat();
320
+ const mode = currentNode.getMode();
321
+ // Export node data as JSON object within editor context where node methods are available
322
+ let lexicalNodeJSON = undefined;
323
+ try {
324
+ lexicalNodeJSON = currentNode.exportJSON();
325
+ }
326
+ catch (error) {
327
+ console.warn('Failed to export node JSON in propagateTextNode created:', error);
328
+ }
329
+ return { parent, parentId, index, textContent, format, mode, lexicalNodeJSON };
330
+ });
331
+ createTextNodeInLoro(nodeKey, textContent, format, mode, parentId, index, lexicalNodeJSON, options);
332
+ }
333
+ break;
334
+ }
335
+ case 'updated': {
336
+ const currentNode = update.editorState._nodeMap.get(nodeKey);
337
+ if (currentNode && $isTextNode(currentNode)) {
338
+ // First, check if this TextNode's parent has changed (like during double Enter)
339
+ const mapper = getNodeMapper();
340
+ const existingTreeID = mapper.getTreeIDByLexicalKey(nodeKey);
341
+ if (existingTreeID) {
342
+ const { currentParentId, expectedParentId, parent } = update.editorState.read(() => {
343
+ const parent = currentNode.getParent();
344
+ const expectedParentId = parent ? mapper.getTreeIDByLexicalKey(parent.getKey()) : undefined;
345
+ // Get the current parent from Loro tree
346
+ let currentParentId;
347
+ try {
348
+ const treeNode = tree.getNodeByID(existingTreeID);
349
+ if (treeNode) {
350
+ const parentNode = treeNode.parent();
351
+ currentParentId = parentNode ? parentNode.id.toString() : undefined;
352
+ }
353
+ }
354
+ catch (error) {
355
+ console.warn(` Failed to get parent for existing TreeID ${existingTreeID} during update:`, error);
356
+ }
357
+ return { currentParentId, expectedParentId, parent };
358
+ });
359
+ if (currentParentId !== expectedParentId) {
360
+ // Get the actual TreeNode and its ID before deleting
361
+ let actualTreeID = existingTreeID;
362
+ try {
363
+ const treeNode = tree.getNodeByID(existingTreeID);
364
+ if (treeNode) {
365
+ actualTreeID = treeNode.id;
366
+ }
367
+ }
368
+ catch (error) {
369
+ console.warn(` Could not get TreeNode for ${existingTreeID}:`, error);
370
+ }
371
+ // Clear the old mapping first to avoid conflicts
372
+ mapper.deleteMapping(nodeKey);
373
+ // Then delete the TreeNode from Loro tree
374
+ try {
375
+ if (tree.has(actualTreeID)) {
376
+ tree.delete(actualTreeID);
377
+ }
378
+ }
379
+ catch (error) {
380
+ console.warn(` Failed to delete TreeNode ${actualTreeID} during update:`, error);
381
+ }
382
+ // Now recreate the TextNode with the new parent (treat as "created")
383
+ const { parentId, index, textContent, format, mode, lexicalNodeJSON } = update.editorState.read(() => {
384
+ const parentId = parent ? mapper.getTreeIDByLexicalKey(parent.getKey()) : undefined;
385
+ const index = currentNode.getIndexWithinParent();
386
+ const textContent = currentNode.getTextContent();
387
+ const format = currentNode.getFormat();
388
+ const mode = currentNode.getMode();
389
+ let lexicalNodeJSON = undefined;
390
+ try {
391
+ lexicalNodeJSON = currentNode.exportJSON();
392
+ }
393
+ catch (error) {
394
+ console.warn('Failed to export node JSON during TextNode recreation:', error);
395
+ }
396
+ return { parentId, index, textContent, format, mode, lexicalNodeJSON };
397
+ });
398
+ createTextNodeInLoro(nodeKey, textContent, format, mode, parentId, index, lexicalNodeJSON, options);
399
+ return; // Exit early since we recreated the node
400
+ }
401
+ }
402
+ // If a text node emits only an "updated" mutation before we have a
403
+ // mapping, treat it as a create so parent/index are explicit.
404
+ if (!existingTreeID) {
405
+ const { parent, parentId, index, textContent, format, mode, lexicalNodeJSON } = update.editorState.read(() => {
406
+ const parent = currentNode.getParent();
407
+ const parentId = parent ? mapper.getTreeIDByLexicalKey(parent.getKey()) : undefined;
408
+ const index = currentNode.getIndexWithinParent();
409
+ const textContent = currentNode.getTextContent();
410
+ const format = currentNode.getFormat();
411
+ const mode = currentNode.getMode();
412
+ let lexicalNodeJSON = undefined;
413
+ try {
414
+ lexicalNodeJSON = currentNode.exportJSON();
415
+ }
416
+ catch (error) {
417
+ console.warn('Failed to export node JSON in propagateTextNode updated(create fallback):', error);
418
+ }
419
+ return { parent, parentId, index, textContent, format, mode, lexicalNodeJSON };
420
+ });
421
+ if (parentId !== undefined) {
422
+ createTextNodeInLoro(nodeKey, textContent, format, mode, parentId, index, lexicalNodeJSON, options);
423
+ }
424
+ return;
425
+ }
426
+ // Normal update case - parent hasn't changed
427
+ const { textContent, format, mode, lexicalNodeJSON } = update.editorState.read(() => {
428
+ const textContent = currentNode.getTextContent();
429
+ const format = currentNode.getFormat();
430
+ const mode = currentNode.getMode();
431
+ // Export node data as JSON object within editor context where node methods are available
432
+ let lexicalNodeJSON = undefined;
433
+ try {
434
+ lexicalNodeJSON = currentNode.exportJSON();
435
+ }
436
+ catch (error) {
437
+ console.warn('Failed to export node JSON in propagateTextNode updated:', error);
438
+ }
439
+ return { textContent, format, mode, lexicalNodeJSON };
440
+ });
441
+ updateTextNodeInLoro(nodeKey, textContent, format, mode, lexicalNodeJSON, options);
442
+ }
443
+ break;
444
+ }
445
+ case 'destroyed': {
446
+ deleteTextNodeInLoro(nodeKey, options);
447
+ break;
448
+ }
449
+ }
450
+ }
@@ -0,0 +1,49 @@
1
+ /**
2
+ * Lexical Node Propagator for Loro Tree Collaboration
3
+ *
4
+ * This module exports mutator functions for all Lexical node types
5
+ * to enable bidirectional synchronization with Loro Tree Loro.
6
+ */
7
+ import { ElementNode, NodeKey } from 'lexical';
8
+ import { Binding } from '../Bindings';
9
+ import type { LoroTree } from 'loro-crdt';
10
+ export * from './RootNodePropagator';
11
+ export * from './LineBreakNodePropagator';
12
+ export * from './ElementNodePropagator';
13
+ export * from './TextNodePropagator';
14
+ export * from './DecoratorNodePropagator';
15
+ export { propagateRootNode } from './RootNodePropagator';
16
+ export { propagateLineBreakNode } from './LineBreakNodePropagator';
17
+ export { propagateElementNode } from './ElementNodePropagator';
18
+ export { propagateTextNode } from './TextNodePropagator';
19
+ export { propagateDecoratorNode } from './DecoratorNodePropagator';
20
+ /**
21
+ * Type definitions for mutator options
22
+ */
23
+ export interface BasePropagatorOptions {
24
+ binding: Binding;
25
+ tree: LoroTree;
26
+ peerId: number;
27
+ }
28
+ /**
29
+ * Unified mutator interface for all node types
30
+ */
31
+ export interface NodePropagator<T = any> {
32
+ create: (nodeKey: NodeKey, ...args: any[]) => string;
33
+ update: (nodeKey: NodeKey, ...args: any[]) => void;
34
+ delete: (nodeKey: NodeKey, options: BasePropagatorOptions) => void;
35
+ createFromLoro: (treeId: string, parentNode: ElementNode, index?: number, options?: BasePropagatorOptions) => T | null;
36
+ updateFromLoro: (treeId: string, lexicalNode: T, newParentNode?: ElementNode, newIndex?: number, options?: BasePropagatorOptions) => void;
37
+ deleteFromLoro: (treeId: string, lexicalNode: T, options?: BasePropagatorOptions) => void;
38
+ }
39
+ /**
40
+ * Node type constants for identifying different Lexical node types in Loro tree
41
+ */
42
+ export declare const NODE_TYPES: {
43
+ readonly ROOT: "root";
44
+ readonly ELEMENT: "element";
45
+ readonly TEXT: "text";
46
+ readonly LINEBREAK: "linebreak";
47
+ readonly DECORATOR: "decorator";
48
+ };
49
+ export type NodeType = typeof NODE_TYPES[keyof typeof NODE_TYPES];
@@ -0,0 +1,30 @@
1
+ /*
2
+ * Copyright (c) 2025-2026 Datalayer, Inc.
3
+ * Distributed under the terms of the MIT License.
4
+ */
5
+ // Root Node Propagator
6
+ export * from './RootNodePropagator';
7
+ // Line Break Node Propagator
8
+ export * from './LineBreakNodePropagator';
9
+ // Element Node Propagator
10
+ export * from './ElementNodePropagator';
11
+ // Text Node Propagator
12
+ export * from './TextNodePropagator';
13
+ // Decorator Node Propagator
14
+ export * from './DecoratorNodePropagator';
15
+ // Main mutator functions for delegation
16
+ export { propagateRootNode } from './RootNodePropagator';
17
+ export { propagateLineBreakNode } from './LineBreakNodePropagator';
18
+ export { propagateElementNode } from './ElementNodePropagator';
19
+ export { propagateTextNode } from './TextNodePropagator';
20
+ export { propagateDecoratorNode } from './DecoratorNodePropagator';
21
+ /**
22
+ * Node type constants for identifying different Lexical node types in Loro tree
23
+ */
24
+ export const NODE_TYPES = {
25
+ ROOT: 'root',
26
+ ELEMENT: 'element',
27
+ TEXT: 'text',
28
+ LINEBREAK: 'linebreak',
29
+ DECORATOR: 'decorator',
30
+ };
@@ -0,0 +1,117 @@
1
+ import { LoroDoc, EphemeralStore, VersionVector } from 'loro-crdt';
2
+ import { ObservableV2 } from 'lib0/observable';
3
+ export declare const messageUpdate = "update";
4
+ export declare const messageQuerySnapshot = "query-snapshot";
5
+ export declare const messageEphemeral = "ephemeral";
6
+ export declare const messageQueryEphemeral = "query-ephemeral";
7
+ export interface LoroUpdateMessage {
8
+ type: 'update';
9
+ update: number[];
10
+ docId: string;
11
+ }
12
+ export interface EphemeralMessage {
13
+ type: 'ephemeral';
14
+ ephemeral: number[];
15
+ docId: string;
16
+ }
17
+ export interface QueryEphemeralMessage {
18
+ type: 'query-ephemeral';
19
+ docId: string;
20
+ clientId?: string;
21
+ }
22
+ export interface QuerySnapshotMessage {
23
+ type: 'query-snapshot';
24
+ docId: string;
25
+ clientId?: string;
26
+ }
27
+ export type LoroWebSocketMessage = LoroUpdateMessage | EphemeralMessage | QueryEphemeralMessage | QuerySnapshotMessage;
28
+ /**
29
+ * Websocket Provider for Loro. Creates a websocket connection to sync the shared document.
30
+ * The document name is attached to the provided url. I.e. the following example
31
+ * creates a websocket connection to http://localhost:1235/my-document-name
32
+ */
33
+ export declare class WebsocketProvider extends ObservableV2<any> {
34
+ static globalEphemeralStore: EphemeralStore | null;
35
+ wsServerUrl: string;
36
+ docId: string;
37
+ doc: LoroDoc | null;
38
+ _WS: any;
39
+ protocols: any[];
40
+ params: {};
41
+ ephemeralStore: any;
42
+ awareness: any;
43
+ ws: any;
44
+ wsconnected: boolean;
45
+ wsconnecting: boolean;
46
+ bcconnected: boolean;
47
+ disableBc: boolean;
48
+ bcChannel: string;
49
+ maxBackoffTime: number;
50
+ wsUnsuccessfulReconnects: number;
51
+ messageHandlers: any[];
52
+ _synced: boolean;
53
+ wsLastMessageReceived: number;
54
+ shouldConnect: boolean;
55
+ snapshotLoaded: boolean;
56
+ _checkInterval: any;
57
+ _resyncInterval: any;
58
+ _updateHandler: any;
59
+ _ephemeralUpdateIntegrator: any;
60
+ _exitIntegrator: any;
61
+ _bcSubscriber: any;
62
+ _lastExportedVersion: VersionVector;
63
+ _pendingUpdates: Uint8Array[];
64
+ /**
65
+ * @param {string} wsServerUrl
66
+ * @param {string} docId
67
+ * @param {LoroDoc} doc
68
+ * @param {object} opts
69
+ * @param {boolean} [opts.connect]
70
+ * @param {EphemeralStore} [opts.ephemeralStore]
71
+ * @param {Object<string,string>} [opts.params] specify url parameters
72
+ * @param {Array<string>} [opts.protocols] specify websocket protocols
73
+ * @param {typeof WebSocket} [opts.WebSocketPolyfill] Optionally provide a WebSocket polyfill
74
+ * @param {number} [opts.resyncInterval] Request server state every `resyncInterval` milliseconds
75
+ * @param {number} [opts.maxBackoffTime] Maximum amount of time to wait before trying to reconnect (we try to reconnect using exponential backoff)
76
+ * @param {boolean} [opts.disableBc] Disable cross-tab BroadcastChannel communication
77
+ */
78
+ constructor(wsServerUrl: string, docId: string, doc: LoroDoc, { connect, ephemeralStore, params, protocols, WebSocketPolyfill, resyncInterval, maxBackoffTime, disableBc }?: {
79
+ connect?: boolean;
80
+ ephemeralStore?: any;
81
+ params?: {};
82
+ protocols?: any[];
83
+ WebSocketPolyfill?: {
84
+ new (url: string | URL, protocols?: string | string[]): WebSocket;
85
+ prototype: WebSocket;
86
+ readonly CONNECTING: 0;
87
+ readonly OPEN: 1;
88
+ readonly CLOSING: 2;
89
+ readonly CLOSED: 3;
90
+ };
91
+ resyncInterval?: number;
92
+ maxBackoffTime?: number;
93
+ disableBc?: boolean;
94
+ });
95
+ get url(): string;
96
+ /**
97
+ * @type {boolean}
98
+ */
99
+ get synced(): boolean;
100
+ set synced(state: boolean);
101
+ destroy(): void;
102
+ connectBc(): void;
103
+ disconnectBc(): void;
104
+ disconnect(): void;
105
+ connect(): void;
106
+ /**
107
+ * Manually send a Loro document update to connected peers
108
+ * Call this method after making changes to the LoroDoc
109
+ * @param {Uint8Array} update The update bytes from LoroDoc
110
+ */
111
+ sendUpdate(update: Uint8Array): void;
112
+ /**
113
+ * Force cleanup of stale ephemeral states (for debugging)
114
+ * Removes user states that haven't been active for more than 5 minutes
115
+ */
116
+ cleanupStaleStates(): void;
117
+ }