@datalayer/lexical-loro 0.0.7 → 0.1.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.
Files changed (406) hide show
  1. package/README.md +24 -137
  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 +111 -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 +44 -0
  10. package/lib/collab/loro/Bindings.d.ts +41 -0
  11. package/lib/collab/loro/Bindings.js +95 -0
  12. package/lib/collab/loro/Debug.d.ts +33 -0
  13. package/lib/collab/loro/Debug.js +448 -0
  14. package/lib/collab/loro/LexicalCollaborationContext.d.ts +19 -0
  15. package/lib/collab/loro/LexicalCollaborationContext.js +48 -0
  16. package/lib/collab/loro/LexicalCollaborationPlugin.d.ts +24 -0
  17. package/lib/collab/loro/LexicalCollaborationPlugin.js +83 -0
  18. package/lib/collab/loro/State.d.ts +53 -0
  19. package/lib/collab/loro/State.js +90 -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 +97 -0
  24. package/lib/collab/loro/components/index.d.ts +2 -0
  25. package/lib/collab/loro/components/index.js +2 -0
  26. package/lib/collab/loro/index.d.ts +6 -0
  27. package/lib/collab/loro/index.js +6 -0
  28. package/lib/collab/loro/integrators/BaseIntegrator.d.ts +14 -0
  29. package/lib/collab/loro/integrators/BaseIntegrator.js +1 -0
  30. package/lib/collab/loro/integrators/CounterIntegrator.d.ts +23 -0
  31. package/lib/collab/loro/integrators/CounterIntegrator.js +40 -0
  32. package/lib/collab/loro/integrators/ListIntegrator.d.ts +23 -0
  33. package/lib/collab/loro/integrators/ListIntegrator.js +49 -0
  34. package/lib/collab/loro/integrators/MapIntegrator.d.ts +24 -0
  35. package/lib/collab/loro/integrators/MapIntegrator.js +177 -0
  36. package/lib/collab/loro/integrators/TextIntegrator.d.ts +25 -0
  37. package/lib/collab/loro/integrators/TextIntegrator.js +51 -0
  38. package/lib/collab/loro/integrators/TreeIntegrator.d.ts +25 -0
  39. package/lib/collab/loro/integrators/TreeIntegrator.js +201 -0
  40. package/lib/collab/loro/nodes/NodeFactory.d.ts +8 -0
  41. package/lib/collab/loro/nodes/NodeFactory.js +105 -0
  42. package/lib/collab/loro/nodes/NodesMapper.d.ts +111 -0
  43. package/lib/collab/loro/nodes/NodesMapper.js +258 -0
  44. package/lib/collab/loro/propagators/DecoratorNodePropagator.d.ts +60 -0
  45. package/lib/collab/loro/propagators/DecoratorNodePropagator.js +302 -0
  46. package/lib/collab/loro/propagators/ElementNodePropagator.d.ts +62 -0
  47. package/lib/collab/loro/propagators/ElementNodePropagator.js +335 -0
  48. package/lib/collab/loro/propagators/LineBreakNodePropagator.d.ts +57 -0
  49. package/lib/collab/loro/propagators/LineBreakNodePropagator.js +196 -0
  50. package/lib/collab/loro/propagators/RootNodePropagator.d.ts +55 -0
  51. package/lib/collab/loro/propagators/RootNodePropagator.js +168 -0
  52. package/lib/collab/loro/propagators/TextNodePropagator.d.ts +60 -0
  53. package/lib/collab/loro/propagators/TextNodePropagator.js +434 -0
  54. package/lib/collab/loro/propagators/index.d.ts +49 -0
  55. package/lib/collab/loro/propagators/index.js +32 -0
  56. package/lib/collab/loro/provider/websocket.d.ts +116 -0
  57. package/lib/collab/loro/provider/websocket.js +907 -0
  58. package/lib/collab/loro/servers/index.d.ts +0 -0
  59. package/lib/collab/loro/servers/index.js +0 -0
  60. package/lib/collab/loro/servers/ws/callback.d.ts +5 -0
  61. package/lib/collab/loro/servers/ws/callback.js +85 -0
  62. package/lib/collab/loro/servers/ws/server.d.ts +2 -0
  63. package/lib/collab/loro/servers/ws/server.js +25 -0
  64. package/lib/collab/loro/servers/ws/utils.d.ts +40 -0
  65. package/lib/collab/loro/servers/ws/utils.js +513 -0
  66. package/lib/collab/loro/sync/SyncCursors.d.ts +32 -0
  67. package/lib/collab/loro/sync/SyncCursors.js +435 -0
  68. package/lib/collab/loro/sync/SyncLexicalToLoro.d.ts +4 -0
  69. package/lib/collab/loro/sync/SyncLexicalToLoro.js +80 -0
  70. package/lib/collab/loro/sync/SyncLoroToLexical.d.ts +5 -0
  71. package/lib/collab/loro/sync/SyncLoroToLexical.js +96 -0
  72. package/lib/collab/loro/types/LexicalNodeData.d.ts +32 -0
  73. package/lib/collab/loro/types/LexicalNodeData.js +71 -0
  74. package/lib/collab/loro/useCollaboration.d.ts +12 -0
  75. package/lib/collab/loro/useCollaboration.js +248 -0
  76. package/lib/collab/loro/utils/InitialContent.d.ts +64 -0
  77. package/lib/collab/loro/utils/InitialContent.js +109 -0
  78. package/lib/collab/loro/utils/LexicalToLoro.d.ts +18 -0
  79. package/lib/collab/loro/utils/LexicalToLoro.js +96 -0
  80. package/lib/collab/loro/utils/Utils.d.ts +44 -0
  81. package/lib/collab/loro/utils/Utils.js +153 -0
  82. package/lib/collab/loro/wsProvider.d.ts +8 -0
  83. package/lib/collab/loro/wsProvider.js +31 -0
  84. package/lib/collab/utils/invariant.d.ts +1 -0
  85. package/lib/collab/utils/invariant.js +11 -0
  86. package/lib/collab/utils/simpleDiffWithCursor.d.ts +5 -0
  87. package/lib/collab/utils/simpleDiffWithCursor.js +31 -0
  88. package/lib/collab/yjs/Bindings.d.ts +23 -0
  89. package/lib/collab/yjs/Bindings.js +26 -0
  90. package/lib/collab/yjs/Debug.d.ts +23 -0
  91. package/lib/collab/yjs/Debug.js +213 -0
  92. package/lib/collab/yjs/LexicalCollaborationContext.d.ts +10 -0
  93. package/lib/collab/yjs/LexicalCollaborationContext.js +37 -0
  94. package/lib/collab/yjs/LexicalCollaborationPlugin.d.ts +21 -0
  95. package/lib/collab/yjs/LexicalCollaborationPlugin.js +63 -0
  96. package/lib/collab/yjs/State.d.ts +51 -0
  97. package/lib/collab/yjs/State.js +35 -0
  98. package/lib/collab/yjs/nodes/AnyCollabNode.d.ts +5 -0
  99. package/lib/collab/yjs/nodes/AnyCollabNode.js +1 -0
  100. package/lib/collab/yjs/nodes/CollabDecoratorNode.d.ts +22 -0
  101. package/lib/collab/yjs/nodes/CollabDecoratorNode.js +64 -0
  102. package/lib/collab/yjs/nodes/CollabElementNode.d.ts +40 -0
  103. package/lib/collab/yjs/nodes/CollabElementNode.js +462 -0
  104. package/lib/collab/yjs/nodes/CollabLineBreakNode.d.ts +19 -0
  105. package/lib/collab/yjs/nodes/CollabLineBreakNode.js +44 -0
  106. package/lib/collab/yjs/nodes/CollabTextNode.d.ts +25 -0
  107. package/lib/collab/yjs/nodes/CollabTextNode.js +103 -0
  108. package/lib/collab/yjs/provider/websocket.d.ts +88 -0
  109. package/lib/collab/yjs/provider/websocket.js +415 -0
  110. package/lib/collab/yjs/servers/index.d.ts +0 -0
  111. package/lib/collab/yjs/servers/index.js +0 -0
  112. package/lib/collab/yjs/servers/ws/callback.d.ts +5 -0
  113. package/lib/collab/yjs/servers/ws/callback.js +72 -0
  114. package/lib/collab/yjs/servers/ws/server.d.ts +2 -0
  115. package/lib/collab/yjs/servers/ws/server.js +25 -0
  116. package/lib/collab/yjs/servers/ws/utils.d.ts +49 -0
  117. package/lib/collab/yjs/servers/ws/utils.js +284 -0
  118. package/lib/collab/yjs/sync/SyncCursors.d.ts +39 -0
  119. package/lib/collab/yjs/sync/SyncCursors.js +351 -0
  120. package/lib/collab/yjs/sync/SyncEditorStates.d.ts +10 -0
  121. package/lib/collab/yjs/sync/SyncEditorStates.js +200 -0
  122. package/lib/collab/yjs/useCollaboration.d.ts +12 -0
  123. package/lib/collab/yjs/useCollaboration.js +255 -0
  124. package/lib/collab/yjs/utils/Utils.d.ts +25 -0
  125. package/lib/collab/yjs/utils/Utils.js +402 -0
  126. package/lib/collab/yjs/wsProvider.d.ts +3 -0
  127. package/lib/collab/yjs/wsProvider.js +21 -0
  128. package/lib/commenting/index.d.ts +41 -0
  129. package/lib/commenting/index.js +324 -0
  130. package/lib/context/FlashMessageContext.d.ts +7 -0
  131. package/lib/context/FlashMessageContext.js +24 -0
  132. package/lib/context/SettingsContext.d.ts +12 -0
  133. package/lib/context/SettingsContext.js +38 -0
  134. package/lib/context/SharedHistoryContext.d.ts +11 -0
  135. package/lib/context/SharedHistoryContext.js +11 -0
  136. package/lib/context/ToolbarContext.d.ts +65 -0
  137. package/lib/context/ToolbarContext.js +84 -0
  138. package/lib/demo.d.ts +12 -0
  139. package/lib/demo.js +41 -0
  140. package/lib/hooks/useFlashMessage.d.ts +2 -0
  141. package/lib/hooks/useFlashMessage.js +4 -0
  142. package/lib/hooks/useModal.d.ts +5 -0
  143. package/lib/hooks/useModal.js +26 -0
  144. package/lib/hooks/useReport.d.ts +1 -0
  145. package/lib/hooks/useReport.js +46 -0
  146. package/lib/index.d.ts +1 -1
  147. package/lib/index.js +1 -5
  148. package/lib/nodes/AutocompleteNode.d.ts +27 -0
  149. package/lib/nodes/AutocompleteNode.js +56 -0
  150. package/lib/nodes/CounterComponent.d.ts +6 -0
  151. package/lib/nodes/CounterComponent.js +137 -0
  152. package/lib/nodes/CounterNode.d.ts +23 -0
  153. package/lib/nodes/CounterNode.js +47 -0
  154. package/lib/nodes/DateTimeNode/DateTimeComponent.d.ts +8 -0
  155. package/lib/nodes/DateTimeNode/DateTimeComponent.js +119 -0
  156. package/lib/nodes/DateTimeNode/DateTimeNode.d.ts +27 -0
  157. package/lib/nodes/DateTimeNode/DateTimeNode.js +82 -0
  158. package/lib/nodes/EmojiNode.d.ts +18 -0
  159. package/lib/nodes/EmojiNode.js +50 -0
  160. package/lib/nodes/EquationComponent.d.ts +9 -0
  161. package/lib/nodes/EquationComponent.js +75 -0
  162. package/lib/nodes/EquationNode.d.ts +26 -0
  163. package/lib/nodes/EquationNode.js +109 -0
  164. package/lib/nodes/ExcalidrawNode/ExcalidrawComponent.d.ts +8 -0
  165. package/lib/nodes/ExcalidrawNode/ExcalidrawComponent.js +110 -0
  166. package/lib/nodes/ExcalidrawNode/ExcalidrawImage.d.ts +50 -0
  167. package/lib/nodes/ExcalidrawNode/ExcalidrawImage.js +55 -0
  168. package/lib/nodes/ExcalidrawNode/index.d.ts +32 -0
  169. package/lib/nodes/ExcalidrawNode/index.js +117 -0
  170. package/lib/nodes/FigmaNode.d.ts +20 -0
  171. package/lib/nodes/FigmaNode.js +52 -0
  172. package/lib/nodes/ImageComponent.d.ts +16 -0
  173. package/lib/nodes/ImageComponent.js +272 -0
  174. package/lib/nodes/ImageNode.d.ts +50 -0
  175. package/lib/nodes/ImageNode.js +151 -0
  176. package/lib/nodes/InlineImageNode/InlineImageComponent.d.ts +26 -0
  177. package/lib/nodes/InlineImageNode/InlineImageComponent.js +161 -0
  178. package/lib/nodes/InlineImageNode/InlineImageNode.d.ts +59 -0
  179. package/lib/nodes/InlineImageNode/InlineImageNode.js +162 -0
  180. package/lib/nodes/KeywordNode.d.ts +14 -0
  181. package/lib/nodes/KeywordNode.js +33 -0
  182. package/lib/nodes/LayoutContainerNode.d.ts +24 -0
  183. package/lib/nodes/LayoutContainerNode.js +91 -0
  184. package/lib/nodes/LayoutItemNode.d.ts +16 -0
  185. package/lib/nodes/LayoutItemNode.js +65 -0
  186. package/lib/nodes/MentionNode.d.ts +20 -0
  187. package/lib/nodes/MentionNode.js +81 -0
  188. package/lib/nodes/PageBreakNode/index.d.ts +17 -0
  189. package/lib/nodes/PageBreakNode/index.js +83 -0
  190. package/lib/nodes/PlaygroundNodes.d.ts +3 -0
  191. package/lib/nodes/PlaygroundNodes.js +71 -0
  192. package/lib/nodes/PollComponent.d.ts +9 -0
  193. package/lib/nodes/PollComponent.js +85 -0
  194. package/lib/nodes/PollNode.d.ts +43 -0
  195. package/lib/nodes/PollNode.js +153 -0
  196. package/lib/nodes/SpecialTextNode.d.ts +24 -0
  197. package/lib/nodes/SpecialTextNode.js +50 -0
  198. package/lib/nodes/StickyComponent.d.ts +10 -0
  199. package/lib/nodes/StickyComponent.js +162 -0
  200. package/lib/nodes/StickyNode.d.ts +31 -0
  201. package/lib/nodes/StickyNode.js +76 -0
  202. package/lib/nodes/TweetNode.d.ts +21 -0
  203. package/lib/nodes/TweetNode.js +119 -0
  204. package/lib/nodes/YouTubeNode.d.ts +22 -0
  205. package/lib/nodes/YouTubeNode.js +84 -0
  206. package/lib/plugins/ActionsPlugin/index.d.ts +5 -0
  207. package/lib/plugins/ActionsPlugin/index.js +168 -0
  208. package/lib/plugins/AutoEmbedPlugin/index.d.ts +19 -0
  209. package/lib/plugins/AutoEmbedPlugin/index.js +158 -0
  210. package/lib/plugins/AutoLinkPlugin/index.d.ts +2 -0
  211. package/lib/plugins/AutoLinkPlugin/index.js +15 -0
  212. package/lib/plugins/AutocompletePlugin/index.d.ts +10 -0
  213. package/lib/plugins/AutocompletePlugin/index.js +2473 -0
  214. package/lib/plugins/CodeActionMenuPlugin/components/CopyButton/index.d.ts +7 -0
  215. package/lib/plugins/CodeActionMenuPlugin/components/CopyButton/index.js +42 -0
  216. package/lib/plugins/CodeActionMenuPlugin/components/PrettierButton/index.d.ts +17 -0
  217. package/lib/plugins/CodeActionMenuPlugin/components/PrettierButton/index.js +111 -0
  218. package/lib/plugins/CodeActionMenuPlugin/index.d.ts +5 -0
  219. package/lib/plugins/CodeActionMenuPlugin/index.js +104 -0
  220. package/lib/plugins/CodeActionMenuPlugin/utils.d.ts +1 -0
  221. package/lib/plugins/CodeActionMenuPlugin/utils.js +18 -0
  222. package/lib/plugins/CodeHighlightPrismPlugin/index.d.ts +2 -0
  223. package/lib/plugins/CodeHighlightPrismPlugin/index.js +10 -0
  224. package/lib/plugins/CodeHighlightShikiPlugin/index.d.ts +2 -0
  225. package/lib/plugins/CodeHighlightShikiPlugin/index.js +10 -0
  226. package/lib/plugins/CollapsiblePlugin/CollapsibleContainerNode.d.ts +25 -0
  227. package/lib/plugins/CollapsiblePlugin/CollapsibleContainerNode.js +131 -0
  228. package/lib/plugins/CollapsiblePlugin/CollapsibleContentNode.d.ts +16 -0
  229. package/lib/plugins/CollapsiblePlugin/CollapsibleContentNode.js +79 -0
  230. package/lib/plugins/CollapsiblePlugin/CollapsibleTitleNode.d.ts +16 -0
  231. package/lib/plugins/CollapsiblePlugin/CollapsibleTitleNode.js +81 -0
  232. package/lib/plugins/CollapsiblePlugin/CollapsibleUtils.d.ts +2 -0
  233. package/lib/plugins/CollapsiblePlugin/CollapsibleUtils.js +8 -0
  234. package/lib/plugins/CollapsiblePlugin/index.d.ts +3 -0
  235. package/lib/plugins/CollapsiblePlugin/index.js +128 -0
  236. package/lib/plugins/CommentPlugin/index.d.ts +9 -0
  237. package/lib/plugins/CommentPlugin/index.js +460 -0
  238. package/lib/plugins/ComponentPickerPlugin/index.d.ts +2 -0
  239. package/lib/plugins/ComponentPickerPlugin/index.js +276 -0
  240. package/lib/plugins/ContextMenuPlugin/index.d.ts +2 -0
  241. package/lib/plugins/ContextMenuPlugin/index.js +112 -0
  242. package/lib/plugins/CounterPlugin/index.d.ts +3 -0
  243. package/lib/plugins/CounterPlugin/index.js +20 -0
  244. package/lib/plugins/DatalayerPlugin/index.d.ts +2 -0
  245. package/lib/plugins/DatalayerPlugin/index.js +218 -0
  246. package/lib/plugins/DateTimePlugin/index.d.ts +8 -0
  247. package/lib/plugins/DateTimePlugin/index.js +24 -0
  248. package/lib/plugins/DocsPlugin/index.d.ts +2 -0
  249. package/lib/plugins/DocsPlugin/index.js +4 -0
  250. package/lib/plugins/DragDropPastePlugin/index.d.ts +1 -0
  251. package/lib/plugins/DragDropPastePlugin/index.js +33 -0
  252. package/lib/plugins/DraggableBlockPlugin/index.d.ts +12 -0
  253. package/lib/plugins/DraggableBlockPlugin/index.js +36 -0
  254. package/lib/plugins/EmojiPickerPlugin/index.d.ts +1 -0
  255. package/lib/plugins/EmojiPickerPlugin/index.js +80 -0
  256. package/lib/plugins/EmojisPlugin/index.d.ts +2 -0
  257. package/lib/plugins/EmojisPlugin/index.js +52 -0
  258. package/lib/plugins/EquationsPlugin/index.d.ts +14 -0
  259. package/lib/plugins/EquationsPlugin/index.js +34 -0
  260. package/lib/plugins/ExcalidrawPlugin/index.d.ts +5 -0
  261. package/lib/plugins/ExcalidrawPlugin/index.js +44 -0
  262. package/lib/plugins/FigmaPlugin/index.d.ts +4 -0
  263. package/lib/plugins/FigmaPlugin/index.js +20 -0
  264. package/lib/plugins/FloatingLinkEditorPlugin/index.d.ts +15 -0
  265. package/lib/plugins/FloatingLinkEditorPlugin/index.js +280 -0
  266. package/lib/plugins/FloatingTextFormatToolbarPlugin/index.d.ts +7 -0
  267. package/lib/plugins/FloatingTextFormatToolbarPlugin/index.js +219 -0
  268. package/lib/plugins/ImagesPlugin/index.d.ts +24 -0
  269. package/lib/plugins/ImagesPlugin/index.js +195 -0
  270. package/lib/plugins/InlineImagePlugin/index.d.ts +17 -0
  271. package/lib/plugins/InlineImagePlugin/index.js +180 -0
  272. package/lib/plugins/KeywordsPlugin/index.d.ts +2 -0
  273. package/lib/plugins/KeywordsPlugin/index.js +31 -0
  274. package/lib/plugins/LayoutPlugin/InsertLayoutDialog.d.ts +6 -0
  275. package/lib/plugins/LayoutPlugin/InsertLayoutDialog.js +21 -0
  276. package/lib/plugins/LayoutPlugin/LayoutPlugin.d.ts +7 -0
  277. package/lib/plugins/LayoutPlugin/LayoutPlugin.js +131 -0
  278. package/lib/plugins/LinkPlugin/index.d.ts +6 -0
  279. package/lib/plugins/LinkPlugin/index.js +11 -0
  280. package/lib/plugins/MarkdownShortcutPlugin/index.d.ts +2 -0
  281. package/lib/plugins/MarkdownShortcutPlugin/index.js +6 -0
  282. package/lib/plugins/MarkdownTransformers/index.d.ts +8 -0
  283. package/lib/plugins/MarkdownTransformers/index.js +234 -0
  284. package/lib/plugins/MaxLengthPlugin/index.d.ts +3 -0
  285. package/lib/plugins/MaxLengthPlugin/index.js +37 -0
  286. package/lib/plugins/MentionsPlugin/index.d.ts +2 -0
  287. package/lib/plugins/MentionsPlugin/index.js +564 -0
  288. package/lib/plugins/PageBreakPlugin/index.d.ts +4 -0
  289. package/lib/plugins/PageBreakPlugin/index.js +27 -0
  290. package/lib/plugins/PasteLogPlugin/index.d.ts +2 -0
  291. package/lib/plugins/PasteLogPlugin/index.js +27 -0
  292. package/lib/plugins/PollPlugin/index.d.ts +8 -0
  293. package/lib/plugins/PollPlugin/index.js +38 -0
  294. package/lib/plugins/ShortcutsPlugin/index.d.ts +6 -0
  295. package/lib/plugins/ShortcutsPlugin/index.js +112 -0
  296. package/lib/plugins/ShortcutsPlugin/shortcuts.d.ts +59 -0
  297. package/lib/plugins/ShortcutsPlugin/shortcuts.js +169 -0
  298. package/lib/plugins/SpecialTextPlugin/index.d.ts +2 -0
  299. package/lib/plugins/SpecialTextPlugin/index.js +46 -0
  300. package/lib/plugins/SpeechToTextPlugin/index.d.ts +5 -0
  301. package/lib/plugins/SpeechToTextPlugin/index.js +82 -0
  302. package/lib/plugins/StickyPlugin/index.d.ts +2 -0
  303. package/lib/plugins/StickyPlugin/index.js +12 -0
  304. package/lib/plugins/TabFocusPlugin/index.d.ts +1 -0
  305. package/lib/plugins/TabFocusPlugin/index.js +34 -0
  306. package/lib/plugins/TableActionMenuPlugin/index.d.ts +5 -0
  307. package/lib/plugins/TableActionMenuPlugin/index.js +492 -0
  308. package/lib/plugins/TableCellResizer/index.d.ts +3 -0
  309. package/lib/plugins/TableCellResizer/index.js +297 -0
  310. package/lib/plugins/TableHoverActionsPlugin/index.d.ts +4 -0
  311. package/lib/plugins/TableHoverActionsPlugin/index.js +188 -0
  312. package/lib/plugins/TableOfContentsPlugin/index.d.ts +2 -0
  313. package/lib/plugins/TableOfContentsPlugin/index.js +116 -0
  314. package/lib/plugins/TablePlugin.d.ts +31 -0
  315. package/lib/plugins/TablePlugin.js +63 -0
  316. package/lib/plugins/TestRecorderPlugin/index.d.ts +3 -0
  317. package/lib/plugins/TestRecorderPlugin/index.js +346 -0
  318. package/lib/plugins/ToolbarPlugin/fontSize.d.ts +9 -0
  319. package/lib/plugins/ToolbarPlugin/fontSize.js +80 -0
  320. package/lib/plugins/ToolbarPlugin/index.d.ts +9 -0
  321. package/lib/plugins/ToolbarPlugin/index.js +500 -0
  322. package/lib/plugins/ToolbarPlugin/utils.d.ts +26 -0
  323. package/lib/plugins/ToolbarPlugin/utils.js +243 -0
  324. package/lib/plugins/TreeViewPlugin/index.d.ts +2 -0
  325. package/lib/plugins/TreeViewPlugin/index.js +7 -0
  326. package/lib/plugins/TwitterPlugin/index.d.ts +4 -0
  327. package/lib/plugins/TwitterPlugin/index.js +20 -0
  328. package/lib/plugins/TypingPerfPlugin/index.d.ts +2 -0
  329. package/lib/plugins/TypingPerfPlugin/index.js +93 -0
  330. package/lib/plugins/YouTubePlugin/index.d.ts +4 -0
  331. package/lib/plugins/YouTubePlugin/index.js +20 -0
  332. package/lib/server/validation.d.ts +1 -0
  333. package/lib/server/validation.js +111 -0
  334. package/lib/setupEnv.d.ts +2 -0
  335. package/lib/setupEnv.js +25 -0
  336. package/lib/themes/CommentEditorTheme.d.ts +4 -0
  337. package/lib/themes/CommentEditorTheme.js +7 -0
  338. package/lib/themes/PlaygroundEditorTheme.d.ts +4 -0
  339. package/lib/themes/PlaygroundEditorTheme.js +120 -0
  340. package/lib/themes/StickyEditorTheme.d.ts +4 -0
  341. package/lib/themes/StickyEditorTheme.js +7 -0
  342. package/lib/tyes.dt.d.ts +12 -0
  343. package/lib/tyes.dt.js +0 -0
  344. package/lib/ui/Button.d.ts +12 -0
  345. package/lib/ui/Button.js +6 -0
  346. package/lib/ui/ColorPicker.d.ts +14 -0
  347. package/lib/ui/ColorPicker.js +219 -0
  348. package/lib/ui/ContentEditable.d.ts +9 -0
  349. package/lib/ui/ContentEditable.js +6 -0
  350. package/lib/ui/Dialog.d.ts +10 -0
  351. package/lib/ui/Dialog.js +8 -0
  352. package/lib/ui/DropDown.d.ts +18 -0
  353. package/lib/ui/DropDown.js +133 -0
  354. package/lib/ui/DropdownColorPicker.d.ts +13 -0
  355. package/lib/ui/DropdownColorPicker.js +6 -0
  356. package/lib/ui/EquationEditor.d.ts +8 -0
  357. package/lib/ui/EquationEditor.js +11 -0
  358. package/lib/ui/ExcalidrawModal.d.ts +42 -0
  359. package/lib/ui/ExcalidrawModal.js +103 -0
  360. package/lib/ui/FileInput.d.ts +10 -0
  361. package/lib/ui/FileInput.js +5 -0
  362. package/lib/ui/FlashMessage.d.ts +7 -0
  363. package/lib/ui/FlashMessage.js +6 -0
  364. package/lib/ui/ImageResizer.d.ts +17 -0
  365. package/lib/ui/ImageResizer.js +171 -0
  366. package/lib/ui/KatexEquationAlterer.d.ts +8 -0
  367. package/lib/ui/KatexEquationAlterer.js +23 -0
  368. package/lib/ui/KatexRenderer.d.ts +6 -0
  369. package/lib/ui/KatexRenderer.js +24 -0
  370. package/lib/ui/Modal.d.ts +9 -0
  371. package/lib/ui/Modal.js +48 -0
  372. package/lib/ui/Select.d.ts +8 -0
  373. package/lib/ui/Select.js +5 -0
  374. package/lib/ui/Switch.d.ts +8 -0
  375. package/lib/ui/Switch.js +6 -0
  376. package/lib/ui/TextInput.d.ts +13 -0
  377. package/lib/ui/TextInput.js +7 -0
  378. package/lib/utils/docSerialization.d.ts +3 -0
  379. package/lib/utils/docSerialization.js +56 -0
  380. package/lib/utils/emoji-list.d.ts +20 -0
  381. package/lib/utils/emoji-list.js +16605 -0
  382. package/lib/utils/getDOMRangeRect.d.ts +8 -0
  383. package/lib/utils/getDOMRangeRect.js +22 -0
  384. package/lib/utils/getSelectedNode.d.ts +2 -0
  385. package/lib/utils/getSelectedNode.js +24 -0
  386. package/lib/utils/getThemeSelector.d.ts +2 -0
  387. package/lib/utils/getThemeSelector.js +10 -0
  388. package/lib/utils/isMobileWidth.d.ts +7 -0
  389. package/lib/utils/isMobileWidth.js +7 -0
  390. package/lib/utils/joinClasses.d.ts +1 -0
  391. package/lib/utils/joinClasses.js +3 -0
  392. package/lib/utils/setFloatingElemPosition.d.ts +1 -0
  393. package/lib/utils/setFloatingElemPosition.js +55 -0
  394. package/lib/utils/setFloatingElemPositionForLinkEditor.d.ts +1 -0
  395. package/lib/utils/setFloatingElemPositionForLinkEditor.js +32 -0
  396. package/lib/utils/swipe.d.ts +4 -0
  397. package/lib/utils/swipe.js +90 -0
  398. package/lib/utils/url.d.ts +2 -0
  399. package/lib/utils/url.js +27 -0
  400. package/package.json +82 -51
  401. package/lib/DiffMerge.d.ts +0 -39
  402. package/lib/DiffMerge.js +0 -437
  403. package/lib/LoroCollaborativePlugin.d.ts +0 -62
  404. package/lib/LoroCollaborativePlugin.js +0 -2826
  405. package/lib/stableNodeState.d.ts +0 -8
  406. package/lib/stableNodeState.js +0 -15
package/README.md CHANGED
@@ -305,151 +305,38 @@ The examples include:
305
305
 
306
306
  See `src/examples/README.md` for detailed example documentation.
307
307
 
308
- ## Project Structure
309
-
310
- ### Core Components
311
-
312
- ```
313
- src/
314
- ├── LoroCollaborativePlugin.tsx # Main Lexical plugin for collaboration
315
- └── vite-env.d.ts # TypeScript definitions
316
-
317
- lexical_loro/ # Python WebSocket server package
318
- ├── __init__.py # Package exports
319
- ├── server.py # WebSocket server implementation
320
- ├── cli.py # Command line interface
321
- ├── model/
322
- │ └── lexical_model.py # Standalone LexicalModel library
323
- └── tests/ # Python test suite
324
-
325
- docs/
326
- └── LEXICAL_MODEL_GUIDE.md # Comprehensive library documentation
327
-
328
- examples/
329
- ├── memory_only_example.py # Basic LexicalModel usage
330
- ├── file_sync_example.py # File persistence example
331
- ├── collaboration_example.py # Collaborative editing simulation
332
- └── README.md # Examples documentation
333
-
334
- pyproject.toml # Python package configuration
335
- ```
336
-
337
- ### Examples Directory
338
-
339
- ```
340
- src/examples/ # Complete demo application
341
- ├── App.tsx # Demo app with dual editors
342
- ├── LexicalCollaborativeEditor.tsx # Rich text editor example
343
- ├── TextAreaCollaborativeEditor.tsx # Simple text editor example
344
- ├── ServerSelector.tsx # Server selection UI
345
- ├── LexicalToolbar.tsx # Rich text toolbar
346
- ├── main.tsx # Demo app entry point
347
- └── *.css # Styling for examples
348
-
349
- servers/
350
- └── server.ts # Node.js server (for comparison)
351
- ```
352
-
353
- ### Archive
354
-
355
- ```
356
- src/archive/ # Historical plugin implementations
357
- ├── LoroCollaborativePlugin0.tsx # Previous versions for reference
358
- ├── LoroCollaborativePlugin1.tsx
359
- ├── LoroCollaborativePlugin2.tsx
360
- ├── LoroCollaborativePlugin3.tsx
361
- ├── LoroCollaborativePlugin4.tsx
362
- └── LoroCollaborativePlugin5.tsx
363
- ```
364
-
365
308
  ## Architecture
366
309
 
367
- For detailed architecture documentation, see [`docs/ARCHITECTURE.md`](docs/ARCHITECTURE.md).
368
-
369
- ### System Overview
370
-
371
- The collaboration system consists of three main components:
372
-
373
- 1. **LoroCollaborativePlugin** (Client-side) - Lexical integration
374
- 2. **LoroWebSocketServer** (Server-side) - Real-time synchronization
375
- 3. **LexicalModel** (Standalone Library) - Independent document model
376
-
377
- ### Data Flow
378
-
379
310
  ```
380
- User Types → Lexical Editor → Plugin → Loro CRDT → WebSocket
381
-
382
- WebSocket ← Loro CRDT ← Plugin ← Lexical Editor ← Other Users
311
+ EDITOR 1 EDITOR 2
312
+
313
+ loro loro
314
+ - node(data: root(1)) - node(data: root(12))
315
+ - node(data: element(2)) - node(data: element(22))
316
+ - node(data: text(3)) - node(data: text(13))
317
+ - node(data: counter(4)) - node(data: counter(4))
318
+
319
+ <---- loro updates via websocket ------>
320
+ <---- loro node ids are the same ------>
321
+ <---- lexical node keys are different ------>
322
+
323
+ lexical lexical
324
+ - root(1) - root(12)
325
+ - element(2) - element(22)
326
+ - text(3) - text(13)
327
+ - counter(4) - counter(49)
383
328
  ```
384
329
 
385
- ## Configuration
386
-
387
- For detailed configuration options, see [`docs/API.md`](docs/API.md).
388
-
389
- ### Quick Configuration
390
-
391
- ```tsx
392
- // Plugin configuration
393
- <LoroCollaborativePlugin
394
- websocketUrl="ws://localhost:8081"
395
- docId="my-document"
396
- username="user123"
397
- debug={true}
398
- />
399
- ```
400
-
401
- ```bash
402
- # Server configuration
403
- lexical-loro-server --port 8081 --log-level DEBUG
404
- ```
405
-
406
- ## Development
407
-
408
- For comprehensive development guidelines, see [`docs/DEVELOPMENT.md`](docs/DEVELOPMENT.md).
409
-
410
- ### Quick Start
411
-
412
- ```bash
413
- # Install dependencies
414
- npm install
415
- pip install -e ".[dev]"
416
-
417
- # Run tests
418
- npm test
419
- npm run test:py
420
-
421
- # Start development server
422
- lexical-loro-server --log-level DEBUG
423
- ```
424
-
425
- ## Contributing
426
-
427
- We welcome contributions! Please see [`docs/DEVELOPMENT.md`](docs/DEVELOPMENT.md) for detailed guidelines.
428
-
429
- ### Quick Contributing Guide
430
-
431
- 1. Fork the repository
432
- 2. Create a feature branch
433
- 3. Focus changes on core components
434
- 4. Add tests for new functionality
435
- 5. Update documentation as needed
436
- 6. Submit a pull request
330
+ ## Examples
437
331
 
438
- ## Documentation
332
+ Loro examples
439
333
 
440
- - **[API Documentation](docs/API.md)** - Complete API reference
441
- - **[Initialization Guide](docs/INITIALIZATION_GUIDE.md)** - Best practices for setup
442
- - **[Architecture](docs/ARCHITECTURE.md)** - System design and data flow
443
- - **[Development Guide](docs/DEVELOPMENT.md)** - Contributing and development setup
444
- - **[LexicalModel Guide](docs/LEXICAL_MODEL_GUIDE.md)** - Standalone library documentation
334
+ - http://localhost:3000/?isCollab=true
445
335
 
446
- ## License
336
+ - http://localhost:3000/split/?isCollab=true
447
337
 
448
- This project is open source and available under the [MIT License](LICENSE).
338
+ Y.js examples (for reference)
449
339
 
450
- ## Acknowledgments
340
+ - http://localhost:3000/?isCollab=true&useYjs=true
451
341
 
452
- - [Loro CRDT](https://loro.dev/) - The CRDT library powering collaborative editing
453
- - [Lexical](https://lexical.dev/) - Facebook's extensible text editor framework
454
- - [React](https://reactjs.org/) - UI library for plugin hooks
455
- - [WebSocket](https://developer.mozilla.org/en-US/docs/Web/API/WebSockets_API) - Real-time communication
342
+ - http://localhost:3000/split/?isCollab=true&useYjs=true
package/lib/App.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ import type { JSX } from 'react';
2
+ export default function PlaygroundApp(): JSX.Element;
package/lib/App.js ADDED
@@ -0,0 +1,141 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { $createLinkNode } from '@lexical/link';
3
+ import { $createListItemNode, $createListNode } from '@lexical/list';
4
+ import { LexicalComposer } from '@lexical/react/LexicalComposer';
5
+ import { $createHeadingNode, $createQuoteNode } from '@lexical/rich-text';
6
+ import { $createParagraphNode, $createTextNode, $getRoot, $isTextNode, TextNode, } from 'lexical';
7
+ import { isDevPlayground } from './appSettings';
8
+ import { FlashMessageContext } from './context/FlashMessageContext';
9
+ import { SettingsContext, useSettings } from './context/SettingsContext';
10
+ import { SharedHistoryContext } from './context/SharedHistoryContext';
11
+ import { ToolbarContext } from './context/ToolbarContext';
12
+ import Editor from './Editor';
13
+ import PlaygroundNodes from './nodes/PlaygroundNodes';
14
+ import DocsPlugin from './plugins/DocsPlugin';
15
+ import PasteLogPlugin from './plugins/PasteLogPlugin';
16
+ import { TableContext } from './plugins/TablePlugin';
17
+ import TestRecorderPlugin from './plugins/TestRecorderPlugin';
18
+ import { parseAllowedFontSize } from './plugins/ToolbarPlugin/fontSize';
19
+ import TypingPerfPlugin from './plugins/TypingPerfPlugin';
20
+ import Settings from './Settings';
21
+ import PlaygroundEditorTheme from './themes/PlaygroundEditorTheme';
22
+ import { parseAllowedColor } from './ui/ColorPicker';
23
+ import logo from './images/logo.svg';
24
+ console.warn('If you are profiling the playground app, please ensure you turn off the debug view. You can disable it by pressing on the settings control in the bottom-left of your screen and toggling the debug view setting.');
25
+ function $prepopulatedRichText() {
26
+ const root = $getRoot();
27
+ if (root.getFirstChild() === null) {
28
+ const heading = $createHeadingNode('h1');
29
+ heading.append($createTextNode('Welcome to the playground'));
30
+ root.append(heading);
31
+ const quote = $createQuoteNode();
32
+ quote.append($createTextNode(`In case you were wondering what the black box at the bottom is – it's the debug view, showing the current state of the editor. ` +
33
+ `You can disable it by pressing on the settings control in the bottom-left of your screen and toggling the debug view setting.`));
34
+ root.append(quote);
35
+ const paragraph = $createParagraphNode();
36
+ paragraph.append($createTextNode('The playground is a demo environment built with '), $createTextNode('@lexical/react').toggleFormat('code'), $createTextNode('.'), $createTextNode(' Try typing in '), $createTextNode('some text').toggleFormat('bold'), $createTextNode(' with '), $createTextNode('different').toggleFormat('italic'), $createTextNode(' formats.'));
37
+ root.append(paragraph);
38
+ const paragraph2 = $createParagraphNode();
39
+ paragraph2.append($createTextNode('Make sure to check out the various plugins in the toolbar. You can also use #hashtags or @-mentions too!'));
40
+ root.append(paragraph2);
41
+ const paragraph3 = $createParagraphNode();
42
+ paragraph3.append($createTextNode(`If you'd like to find out more about Lexical, you can:`));
43
+ root.append(paragraph3);
44
+ const list = $createListNode('bullet');
45
+ list.append($createListItemNode().append($createTextNode(`Visit the `), $createLinkNode('https://lexical.dev/').append($createTextNode('Lexical website')), $createTextNode(` for documentation and more information.`)), $createListItemNode().append($createTextNode(`Check out the code on our `), $createLinkNode('https://github.com/facebook/lexical').append($createTextNode('GitHub repository')), $createTextNode(`.`)), $createListItemNode().append($createTextNode(`Playground code can be found `), $createLinkNode('https://github.com/facebook/lexical/tree/main/packages/lexical-playground').append($createTextNode('here')), $createTextNode(`.`)), $createListItemNode().append($createTextNode(`Join our `), $createLinkNode('https://discord.com/invite/KmG4wQnnD9').append($createTextNode('Discord Server')), $createTextNode(` and chat with the team.`)));
46
+ root.append(list);
47
+ const paragraph4 = $createParagraphNode();
48
+ paragraph4.append($createTextNode(`Lastly, we're constantly adding cool new features to this playground. So make sure you check back here when you next get a chance :).`));
49
+ root.append(paragraph4);
50
+ }
51
+ }
52
+ function getExtraStyles(element) {
53
+ // Parse styles from pasted input, but only if they match exactly the
54
+ // sort of styles that would be produced by exportDOM
55
+ let extraStyles = '';
56
+ const fontSize = parseAllowedFontSize(element.style.fontSize);
57
+ const backgroundColor = parseAllowedColor(element.style.backgroundColor);
58
+ const color = parseAllowedColor(element.style.color);
59
+ if (fontSize !== '' && fontSize !== '15px') {
60
+ extraStyles += `font-size: ${fontSize};`;
61
+ }
62
+ if (backgroundColor !== '' && backgroundColor !== 'rgb(255, 255, 255)') {
63
+ extraStyles += `background-color: ${backgroundColor};`;
64
+ }
65
+ if (color !== '' && color !== 'rgb(0, 0, 0)') {
66
+ extraStyles += `color: ${color};`;
67
+ }
68
+ return extraStyles;
69
+ }
70
+ function buildImportMap() {
71
+ const importMap = {};
72
+ // Wrap all TextNode importers with a function that also imports
73
+ // the custom styles implemented by the playground
74
+ for (const [tag, fn] of Object.entries(TextNode.importDOM() || {})) {
75
+ importMap[tag] = (importNode) => {
76
+ const importer = fn(importNode);
77
+ if (!importer) {
78
+ return null;
79
+ }
80
+ return {
81
+ ...importer,
82
+ conversion: (element) => {
83
+ const output = importer.conversion(element);
84
+ if (output === null ||
85
+ output.forChild === undefined ||
86
+ output.after !== undefined ||
87
+ output.node !== null) {
88
+ return output;
89
+ }
90
+ const extraStyles = getExtraStyles(element);
91
+ if (extraStyles) {
92
+ const { forChild } = output;
93
+ return {
94
+ ...output,
95
+ forChild: (child, parent) => {
96
+ const textNode = forChild(child, parent);
97
+ if ($isTextNode(textNode)) {
98
+ textNode.setStyle(textNode.getStyle() + extraStyles);
99
+ }
100
+ return textNode;
101
+ },
102
+ };
103
+ }
104
+ return output;
105
+ },
106
+ };
107
+ };
108
+ }
109
+ return importMap;
110
+ }
111
+ function App() {
112
+ const { settings: { isCollab, emptyEditor, measureTypingPerf }, } = useSettings();
113
+ const initialConfig = {
114
+ editorState: isCollab
115
+ ? null
116
+ : emptyEditor
117
+ ? undefined
118
+ : $prepopulatedRichText,
119
+ html: { import: buildImportMap() },
120
+ namespace: 'Lexical Loro Playground',
121
+ nodes: [...PlaygroundNodes],
122
+ onError: (error) => {
123
+ throw error;
124
+ },
125
+ theme: PlaygroundEditorTheme,
126
+ };
127
+ return (_jsx(LexicalComposer, { initialConfig: initialConfig, children: _jsx(SharedHistoryContext, { children: _jsx(TableContext, { children: _jsxs(ToolbarContext, { children: [_jsx("header", { children: _jsx("a", { href: "https://lexical.dev", target: "_blank", rel: "noreferrer", children: _jsx("img", { src: logo, alt: "Lexical Logo" }) }) }), _jsx("div", { className: "editor-shell", children: _jsx(Editor, {}) }), _jsx(Settings, {}), isDevPlayground ? _jsx(DocsPlugin, {}) : null, isDevPlayground ? _jsx(PasteLogPlugin, {}) : null, isDevPlayground ? _jsx(TestRecorderPlugin, {}) : null, measureTypingPerf ? _jsx(TypingPerfPlugin, {}) : null] }) }) }) }));
128
+ }
129
+ export default function PlaygroundApp() {
130
+ return (_jsxs(SettingsContext, { children: [_jsx(FlashMessageContext, { children: _jsx(App, {}) }), _jsx("a", { href: "https://github.com/facebook/lexical/tree/main/packages/lexical-playground", className: "github-corner", "aria-label": "View source on GitHub", children: _jsxs("svg", { width: "80", height: "80", viewBox: "0 0 250 250", style: {
131
+ border: '0',
132
+ color: '#eee',
133
+ fill: '#222',
134
+ left: '0',
135
+ position: 'absolute',
136
+ top: '0',
137
+ transform: 'scale(-1,1)',
138
+ }, "aria-hidden": "true", children: [_jsx("path", { d: "M0,0 L115,115 L130,115 L142,142 L250,250 L250,0 Z" }), _jsx("path", { d: "M128.3,109.0 C113.8,99.7 119.0,89.6 119.0,89.6 C122.0,82.7 120.5,78.6 120.5,78.6 C119.2,72.0 123.4,76.3 123.4,76.3 C127.3,80.9 125.5,87.3 125.5,87.3 C122.9,97.6 130.6,101.9 134.4,103.2", fill: "currentColor", style: {
139
+ transformOrigin: '130px 106px',
140
+ }, className: "octo-arm" }), _jsx("path", { d: "M115.0,115.0 C114.9,115.1 118.7,116.5 119.8,115.4 L133.7,101.6 C136.9,99.2 139.9,98.4 142.2,98.6 C133.8,88.0 127.5,74.4 143.8,58.0 C148.5,53.4 154.0,51.2 159.7,51.0 C160.3,49.4 163.2,43.6 171.4,40.1 C171.4,40.1 176.1,42.5 178.8,56.2 C183.1,58.6 187.2,61.8 190.9,65.4 C194.5,69.0 197.7,73.2 200.1,77.6 C213.8,80.2 216.3,84.9 216.3,84.9 C212.7,93.1 206.9,96.0 205.4,96.6 C205.1,102.4 203.0,107.8 198.3,112.5 C181.9,128.9 168.3,122.5 157.7,114.1 C157.9,116.9 156.7,120.9 152.7,124.9 L141.0,136.5 C139.8,137.7 141.6,141.9 141.8,141.8 Z", fill: "currentColor", className: "octo-body" })] }) })] }));
141
+ }
@@ -0,0 +1,2 @@
1
+ import { type JSX } from 'react';
2
+ export default function Editor(): JSX.Element;
package/lib/Editor.js ADDED
@@ -0,0 +1,111 @@
1
+ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useEffect, useState } from 'react';
3
+ import { AutoFocusPlugin } from '@lexical/react/LexicalAutoFocusPlugin';
4
+ import { CharacterLimitPlugin } from '@lexical/react/LexicalCharacterLimitPlugin';
5
+ import { CheckListPlugin } from '@lexical/react/LexicalCheckListPlugin';
6
+ import { ClearEditorPlugin } from '@lexical/react/LexicalClearEditorPlugin';
7
+ import { ClickableLinkPlugin } from '@lexical/react/LexicalClickableLinkPlugin';
8
+ import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext';
9
+ import { LexicalErrorBoundary } from '@lexical/react/LexicalErrorBoundary';
10
+ import { HashtagPlugin } from '@lexical/react/LexicalHashtagPlugin';
11
+ import { HistoryPlugin } from '@lexical/react/LexicalHistoryPlugin';
12
+ import { HorizontalRulePlugin } from '@lexical/react/LexicalHorizontalRulePlugin';
13
+ import { ListPlugin } from '@lexical/react/LexicalListPlugin';
14
+ import { PlainTextPlugin } from '@lexical/react/LexicalPlainTextPlugin';
15
+ import { RichTextPlugin } from '@lexical/react/LexicalRichTextPlugin';
16
+ import { SelectionAlwaysOnDisplay } from '@lexical/react/LexicalSelectionAlwaysOnDisplay';
17
+ import { TabIndentationPlugin } from '@lexical/react/LexicalTabIndentationPlugin';
18
+ import { TablePlugin } from '@lexical/react/LexicalTablePlugin';
19
+ import { useLexicalEditable } from '@lexical/react/useLexicalEditable';
20
+ import { CAN_USE_DOM } from '@lexical/utils';
21
+ import { useSettings } from './context/SettingsContext';
22
+ import { useSharedHistoryContext } from './context/SharedHistoryContext';
23
+ import ActionsPlugin from './plugins/ActionsPlugin';
24
+ import AutocompletePlugin from './plugins/AutocompletePlugin';
25
+ import AutoEmbedPlugin from './plugins/AutoEmbedPlugin';
26
+ import AutoLinkPlugin from './plugins/AutoLinkPlugin';
27
+ import CodeActionMenuPlugin from './plugins/CodeActionMenuPlugin';
28
+ import CodeHighlightPrismPlugin from './plugins/CodeHighlightPrismPlugin';
29
+ import CodeHighlightShikiPlugin from './plugins/CodeHighlightShikiPlugin';
30
+ import CollapsiblePlugin from './plugins/CollapsiblePlugin';
31
+ import CommentPlugin from './plugins/CommentPlugin';
32
+ import ComponentPickerPlugin from './plugins/ComponentPickerPlugin';
33
+ import ContextMenuPlugin from './plugins/ContextMenuPlugin';
34
+ import CounterPlugin from './plugins/CounterPlugin';
35
+ import DateTimePlugin from './plugins/DateTimePlugin';
36
+ import DragDropPaste from './plugins/DragDropPastePlugin';
37
+ import DraggableBlockPlugin from './plugins/DraggableBlockPlugin';
38
+ import EmojiPickerPlugin from './plugins/EmojiPickerPlugin';
39
+ import EmojisPlugin from './plugins/EmojisPlugin';
40
+ import EquationsPlugin from './plugins/EquationsPlugin';
41
+ import ExcalidrawPlugin from './plugins/ExcalidrawPlugin';
42
+ import FigmaPlugin from './plugins/FigmaPlugin';
43
+ import FloatingLinkEditorPlugin from './plugins/FloatingLinkEditorPlugin';
44
+ import FloatingTextFormatToolbarPlugin from './plugins/FloatingTextFormatToolbarPlugin';
45
+ import ImagesPlugin from './plugins/ImagesPlugin';
46
+ import InlineImagePlugin from './plugins/InlineImagePlugin';
47
+ import KeywordsPlugin from './plugins/KeywordsPlugin';
48
+ import { LayoutPlugin } from './plugins/LayoutPlugin/LayoutPlugin';
49
+ import LinkPlugin from './plugins/LinkPlugin';
50
+ import MarkdownShortcutPlugin from './plugins/MarkdownShortcutPlugin';
51
+ import { MaxLengthPlugin } from './plugins/MaxLengthPlugin';
52
+ import MentionsPlugin from './plugins/MentionsPlugin';
53
+ import PageBreakPlugin from './plugins/PageBreakPlugin';
54
+ import PollPlugin from './plugins/PollPlugin';
55
+ import ShortcutsPlugin from './plugins/ShortcutsPlugin';
56
+ import SpecialTextPlugin from './plugins/SpecialTextPlugin';
57
+ import SpeechToTextPlugin from './plugins/SpeechToTextPlugin';
58
+ import TabFocusPlugin from './plugins/TabFocusPlugin';
59
+ import TableCellActionMenuPlugin from './plugins/TableActionMenuPlugin';
60
+ import TableCellResizer from './plugins/TableCellResizer';
61
+ import TableHoverActionsPlugin from './plugins/TableHoverActionsPlugin';
62
+ import TableOfContentsPlugin from './plugins/TableOfContentsPlugin';
63
+ import ToolbarPlugin from './plugins/ToolbarPlugin';
64
+ import TreeViewPlugin from './plugins/TreeViewPlugin';
65
+ import TwitterPlugin from './plugins/TwitterPlugin';
66
+ import YouTubePlugin from './plugins/YouTubePlugin';
67
+ import ContentEditable from './ui/ContentEditable';
68
+ import DatalayerPlugin from './plugins/DatalayerPlugin';
69
+ import { LoroCollaborationPlugin as LoroCollaborationPlugin } from './collab/loro/LexicalCollaborationPlugin';
70
+ import { createWebsocketProvider as createLoroWebsocketProvider } from './collab/loro/wsProvider';
71
+ import { CollaborationPlugin as YjsCollaborationPlugin } from './collab/yjs/LexicalCollaborationPlugin';
72
+ import { createWebsocketProvider as createYjsWebsocketProvider } from './collab/yjs/wsProvider';
73
+ const skipCollaborationInit =
74
+ // @ts-expect-error
75
+ window.parent != null && window.parent.frames.right === window;
76
+ export default function Editor() {
77
+ const { historyState } = useSharedHistoryContext();
78
+ const { settings: { useYjs, isCodeHighlighted, isCodeShiki, isCollab, isAutocomplete, isMaxLength, isCharLimit, hasLinkAttributes, isCharLimitUtf8, isRichText, showTreeView, showTableOfContents, shouldUseLexicalContextMenu, shouldPreserveNewLinesInMarkdown, tableCellMerge, tableCellBackgroundColor, tableHorizontalScroll, shouldAllowHighlightingWithBrackets, selectionAlwaysOnDisplay, listStrictIndent, }, } = useSettings();
79
+ const isEditable = useLexicalEditable();
80
+ const placeholder = isCollab
81
+ ? 'Enter some collaborative rich text...'
82
+ : isRichText
83
+ ? 'Enter some rich text...'
84
+ : 'Enter some plain text...';
85
+ const [floatingAnchorElem, setFloatingAnchorElem] = useState(null);
86
+ const [isSmallWidthViewport, setIsSmallWidthViewport] = useState(false);
87
+ const [editor] = useLexicalComposerContext();
88
+ const [activeEditor, setActiveEditor] = useState(editor);
89
+ const [isLinkEditMode, setIsLinkEditMode] = useState(false);
90
+ const onRef = (_floatingAnchorElem) => {
91
+ if (_floatingAnchorElem !== null) {
92
+ setFloatingAnchorElem(_floatingAnchorElem);
93
+ }
94
+ };
95
+ useEffect(() => {
96
+ const updateViewPortWidth = () => {
97
+ const isNextSmallWidthViewport = CAN_USE_DOM && window.matchMedia('(max-width: 1025px)').matches;
98
+ if (isNextSmallWidthViewport !== isSmallWidthViewport) {
99
+ setIsSmallWidthViewport(isNextSmallWidthViewport);
100
+ }
101
+ };
102
+ updateViewPortWidth();
103
+ window.addEventListener('resize', updateViewPortWidth);
104
+ return () => {
105
+ window.removeEventListener('resize', updateViewPortWidth);
106
+ };
107
+ }, [isSmallWidthViewport]);
108
+ return (_jsxs(_Fragment, { children: [isRichText && (_jsx(ToolbarPlugin, { editor: editor, activeEditor: activeEditor, setActiveEditor: setActiveEditor, setIsLinkEditMode: setIsLinkEditMode })), isRichText && (_jsx(ShortcutsPlugin, { editor: activeEditor, setIsLinkEditMode: setIsLinkEditMode })), _jsxs("div", { className: `editor-container ${showTreeView ? 'tree-view' : ''} ${!isRichText ? 'plain-text' : ''}`, children: [isMaxLength && _jsx(MaxLengthPlugin, { maxLength: 30 }), _jsx(DragDropPaste, {}), _jsx(DatalayerPlugin, {}), _jsx(AutoFocusPlugin, {}), selectionAlwaysOnDisplay && _jsx(SelectionAlwaysOnDisplay, {}), _jsx(ClearEditorPlugin, {}), _jsx(ComponentPickerPlugin, {}), _jsx(EmojiPickerPlugin, {}), _jsx(AutoEmbedPlugin, {}), _jsx(MentionsPlugin, {}), _jsx(EmojisPlugin, {}), _jsx(HashtagPlugin, {}), _jsx(KeywordsPlugin, {}), _jsx(SpeechToTextPlugin, {}), _jsx(AutoLinkPlugin, {}), _jsx(DateTimePlugin, {}), useYjs &&
109
+ _jsx(CommentPlugin, { providerFactory: isCollab ? createYjsWebsocketProvider : undefined }), isRichText ? (_jsxs(_Fragment, { children: [isCollab ? (useYjs ? (_jsx(YjsCollaborationPlugin, { id: "main", providerFactory: createYjsWebsocketProvider, shouldBootstrap: !skipCollaborationInit })) : (_jsx(LoroCollaborationPlugin, { id: "main", providerFactory: createLoroWebsocketProvider, shouldBootstrap: !skipCollaborationInit }))) : (_jsx(HistoryPlugin, { externalHistoryState: historyState })), _jsx(RichTextPlugin, { contentEditable: _jsx("div", { className: "editor-scroller", children: _jsx("div", { className: "editor", ref: onRef, children: _jsx(ContentEditable, { placeholder: placeholder }) }) }), ErrorBoundary: LexicalErrorBoundary }), _jsx(MarkdownShortcutPlugin, {}), isCodeHighlighted &&
110
+ (isCodeShiki ? (_jsx(CodeHighlightShikiPlugin, {})) : (_jsx(CodeHighlightPrismPlugin, {}))), _jsx(ListPlugin, { hasStrictIndent: listStrictIndent }), _jsx(CheckListPlugin, {}), _jsx(TablePlugin, { hasCellMerge: tableCellMerge, hasCellBackgroundColor: tableCellBackgroundColor, hasHorizontalScroll: tableHorizontalScroll }), _jsx(TableCellResizer, {}), _jsx(ImagesPlugin, {}), _jsx(InlineImagePlugin, {}), _jsx(LinkPlugin, { hasLinkAttributes: hasLinkAttributes }), _jsx(PollPlugin, {}), _jsx(TwitterPlugin, {}), _jsx(YouTubePlugin, {}), _jsx(FigmaPlugin, {}), _jsx(ClickableLinkPlugin, { disabled: isEditable }), _jsx(HorizontalRulePlugin, {}), _jsx(EquationsPlugin, {}), _jsx(ExcalidrawPlugin, {}), _jsx(TabFocusPlugin, {}), _jsx(TabIndentationPlugin, { maxIndent: 7 }), _jsx(CollapsiblePlugin, {}), _jsx(CounterPlugin, {}), _jsx(PageBreakPlugin, {}), _jsx(LayoutPlugin, {}), floatingAnchorElem && (_jsxs(_Fragment, { children: [_jsx(FloatingLinkEditorPlugin, { anchorElem: floatingAnchorElem, isLinkEditMode: isLinkEditMode, setIsLinkEditMode: setIsLinkEditMode }), _jsx(TableCellActionMenuPlugin, { anchorElem: floatingAnchorElem, cellMerge: true })] })), floatingAnchorElem && !isSmallWidthViewport && (_jsxs(_Fragment, { children: [_jsx(DraggableBlockPlugin, { anchorElem: floatingAnchorElem }), _jsx(CodeActionMenuPlugin, { anchorElem: floatingAnchorElem }), _jsx(TableHoverActionsPlugin, { anchorElem: floatingAnchorElem }), _jsx(FloatingTextFormatToolbarPlugin, { anchorElem: floatingAnchorElem, setIsLinkEditMode: setIsLinkEditMode })] }))] })) : (_jsxs(_Fragment, { children: [_jsx(PlainTextPlugin, { contentEditable: _jsx(ContentEditable, { placeholder: placeholder }), ErrorBoundary: LexicalErrorBoundary }), _jsx(HistoryPlugin, { externalHistoryState: historyState })] })), (isCharLimit || isCharLimitUtf8) && (_jsx(CharacterLimitPlugin, { charset: isCharLimit ? 'UTF-16' : 'UTF-8', maxLength: 5 })), isAutocomplete && _jsx(AutocompletePlugin, {}), _jsx("div", { children: showTableOfContents && _jsx(TableOfContentsPlugin, {}) }), shouldUseLexicalContextMenu && _jsx(ContextMenuPlugin, {}), shouldAllowHighlightingWithBrackets && _jsx(SpecialTextPlugin, {}), _jsx(ActionsPlugin, { isRichText: isRichText, shouldPreserveNewLinesInMarkdown: shouldPreserveNewLinesInMarkdown })] }), showTreeView && _jsx(TreeViewPlugin, {})] }));
111
+ }
@@ -0,0 +1,2 @@
1
+ import type { JSX } from 'react';
2
+ export default function Settings(): JSX.Element;
@@ -0,0 +1,57 @@
1
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
+ import { CAN_USE_BEFORE_INPUT } from '@lexical/utils';
3
+ import { useEffect, useMemo, useState } from 'react';
4
+ import { INITIAL_SETTINGS, isDevPlayground } from './appSettings';
5
+ import { useSettings } from './context/SettingsContext';
6
+ import Switch from './ui/Switch';
7
+ export default function Settings() {
8
+ const windowLocation = window.location;
9
+ const { setOption, settings: { measureTypingPerf, isCollab, isRichText, isMaxLength, hasLinkAttributes, isCharLimit, isCharLimitUtf8, isAutocomplete, showTreeView, showNestedEditorTreeView,
10
+ // disableBeforeInput,
11
+ showTableOfContents, shouldUseLexicalContextMenu, shouldPreserveNewLinesInMarkdown, shouldAllowHighlightingWithBrackets,
12
+ // tableHorizontalScroll,
13
+ selectionAlwaysOnDisplay, isCodeHighlighted, isCodeShiki, useYjs, }, } = useSettings();
14
+ useEffect(() => {
15
+ if (INITIAL_SETTINGS.disableBeforeInput && CAN_USE_BEFORE_INPUT) {
16
+ console.error(`Legacy events are enabled (disableBeforeInput) but CAN_USE_BEFORE_INPUT is true`);
17
+ }
18
+ }, []);
19
+ const [showSettings, setShowSettings] = useState(false);
20
+ const [isSplitScreen, search] = useMemo(() => {
21
+ const parentWindow = window.parent;
22
+ const _search = windowLocation.search;
23
+ const _isSplitScreen = parentWindow && parentWindow.location.pathname === '/split/';
24
+ return [_isSplitScreen, _search];
25
+ }, [windowLocation]);
26
+ return (_jsxs(_Fragment, { children: [_jsx("button", { id: "options-button", className: `editor-dev-button ${showSettings ? 'active' : ''}`, onClick: () => setShowSettings(!showSettings) }), showSettings ? (_jsxs("div", { className: "switches", children: [isRichText && isDevPlayground && (_jsx(Switch, { onClick: () => {
27
+ setOption('isCollab', !isCollab);
28
+ window.location.reload();
29
+ }, checked: isCollab, text: "Collaboration" })), isRichText && isDevPlayground && isCollab && (_jsx(Switch, { onClick: () => {
30
+ setOption('useYjs', !useYjs);
31
+ window.location.reload();
32
+ }, checked: useYjs, text: "Use Y.js (vs Loro)" })), isDevPlayground && (_jsx(Switch, { onClick: () => {
33
+ if (isSplitScreen) {
34
+ window.parent.location.href = `/${search}`;
35
+ }
36
+ else {
37
+ window.location.href = `/split/${search}`;
38
+ }
39
+ }, checked: isSplitScreen, text: "Split Screen" })), _jsx(Switch, { onClick: () => setOption('measureTypingPerf', !measureTypingPerf), checked: measureTypingPerf, text: "Measure Perf" }), _jsx(Switch, { onClick: () => setOption('showTreeView', !showTreeView), checked: showTreeView, text: "Debug View" }), _jsx(Switch, { onClick: () => setOption('showNestedEditorTreeView', !showNestedEditorTreeView), checked: showNestedEditorTreeView, text: "Nested Editors Debug View" }), _jsx(Switch, { onClick: () => {
40
+ setOption('isRichText', !isRichText);
41
+ setOption('isCollab', false);
42
+ }, checked: isRichText, text: "Rich Text" }), _jsx(Switch, { onClick: () => setOption('isCharLimit', !isCharLimit), checked: isCharLimit, text: "Char Limit" }), _jsx(Switch, { onClick: () => setOption('isCharLimitUtf8', !isCharLimitUtf8), checked: isCharLimitUtf8, text: "Char Limit (UTF-8)" }), _jsx(Switch, { onClick: () => setOption('hasLinkAttributes', !hasLinkAttributes), checked: hasLinkAttributes, text: "Link Attributes" }), _jsx(Switch, { onClick: () => setOption('isMaxLength', !isMaxLength), checked: isMaxLength, text: "Max Length" }), _jsx(Switch, { onClick: () => setOption('isAutocomplete', !isAutocomplete), checked: isAutocomplete, text: "Autocomplete" }), _jsx(Switch, { onClick: () => {
43
+ setOption('showTableOfContents', !showTableOfContents);
44
+ }, checked: showTableOfContents, text: "Table Of Contents" }), _jsx(Switch, { onClick: () => {
45
+ setOption('shouldUseLexicalContextMenu', !shouldUseLexicalContextMenu);
46
+ }, checked: shouldUseLexicalContextMenu, text: "Use Lexical Context Menu" }), _jsx(Switch, { onClick: () => {
47
+ setOption('shouldPreserveNewLinesInMarkdown', !shouldPreserveNewLinesInMarkdown);
48
+ }, checked: shouldPreserveNewLinesInMarkdown, text: "Preserve newlines in Markdown" }), _jsx(Switch, { onClick: () => {
49
+ setOption('shouldAllowHighlightingWithBrackets', !shouldAllowHighlightingWithBrackets);
50
+ }, checked: shouldAllowHighlightingWithBrackets, text: "Use Brackets for Highlighting" }), _jsx(Switch, { onClick: () => {
51
+ setOption('selectionAlwaysOnDisplay', !selectionAlwaysOnDisplay);
52
+ }, checked: selectionAlwaysOnDisplay, text: "Retain selection" }), _jsx(Switch, { onClick: () => {
53
+ setOption('isCodeHighlighted', !isCodeHighlighted);
54
+ }, checked: isCodeHighlighted, text: "Enable Code Highlighting" }), _jsx(Switch, { onClick: () => {
55
+ setOption('isCodeShiki', !isCodeShiki);
56
+ }, checked: isCodeShiki, text: "Use Shiki for Code Highlighting" })] })) : null] }));
57
+ }
@@ -0,0 +1,36 @@
1
+ export declare const isDevPlayground: boolean;
2
+ export declare const DEFAULT_SETTINGS: {
3
+ readonly useYjs: false;
4
+ readonly disableBeforeInput: false;
5
+ readonly emptyEditor: boolean;
6
+ readonly hasLinkAttributes: false;
7
+ readonly isAutocomplete: false;
8
+ readonly isCharLimit: false;
9
+ readonly isCharLimitUtf8: false;
10
+ readonly isCodeHighlighted: true;
11
+ readonly isCodeShiki: false;
12
+ readonly isCollab: true;
13
+ readonly isMaxLength: false;
14
+ readonly isRichText: true;
15
+ readonly listStrictIndent: false;
16
+ readonly measureTypingPerf: false;
17
+ readonly selectionAlwaysOnDisplay: false;
18
+ readonly shouldAllowHighlightingWithBrackets: false;
19
+ readonly shouldPreserveNewLinesInMarkdown: false;
20
+ readonly shouldUseLexicalContextMenu: false;
21
+ readonly showNestedEditorTreeView: false;
22
+ readonly showTableOfContents: false;
23
+ readonly showTreeView: true;
24
+ readonly tableCellBackgroundColor: true;
25
+ readonly tableCellMerge: true;
26
+ readonly tableHorizontalScroll: true;
27
+ readonly debug: false;
28
+ };
29
+ export declare const INITIAL_SETTINGS: Record<SettingName, boolean>;
30
+ export type SettingName = keyof typeof DEFAULT_SETTINGS;
31
+ export type Settings = typeof INITIAL_SETTINGS;
32
+ /**
33
+ * Check if debug mode is enabled via URL parameter
34
+ * @returns true if ?debug=true is in the URL, false otherwise
35
+ */
36
+ export declare function isDebugEnabled(): boolean;
@@ -0,0 +1,44 @@
1
+ const hostName = window.location.hostname;
2
+ export const isDevPlayground = hostName !== 'playground.lexical.dev' &&
3
+ hostName !== 'lexical-playground.vercel.app';
4
+ export const DEFAULT_SETTINGS = {
5
+ useYjs: false,
6
+ disableBeforeInput: false,
7
+ emptyEditor: isDevPlayground,
8
+ hasLinkAttributes: false,
9
+ isAutocomplete: false,
10
+ isCharLimit: false,
11
+ isCharLimitUtf8: false,
12
+ isCodeHighlighted: true,
13
+ isCodeShiki: false,
14
+ isCollab: true, // Enable collaboration by default for testing
15
+ isMaxLength: false,
16
+ isRichText: true,
17
+ listStrictIndent: false,
18
+ measureTypingPerf: false,
19
+ selectionAlwaysOnDisplay: false,
20
+ shouldAllowHighlightingWithBrackets: false,
21
+ shouldPreserveNewLinesInMarkdown: false,
22
+ shouldUseLexicalContextMenu: false,
23
+ showNestedEditorTreeView: false,
24
+ showTableOfContents: false,
25
+ showTreeView: true,
26
+ tableCellBackgroundColor: true,
27
+ tableCellMerge: true,
28
+ tableHorizontalScroll: true,
29
+ debug: false, // Enable Loro debugging utilities
30
+ };
31
+ // These are mutated in setupEnv
32
+ export const INITIAL_SETTINGS = {
33
+ ...DEFAULT_SETTINGS,
34
+ };
35
+ /**
36
+ * Check if debug mode is enabled via URL parameter
37
+ * @returns true if ?debug=true is in the URL, false otherwise
38
+ */
39
+ export function isDebugEnabled() {
40
+ if (typeof window === 'undefined')
41
+ return false;
42
+ const urlParams = new URLSearchParams(window.location.search);
43
+ return urlParams.get('debug') === 'true';
44
+ }
@@ -0,0 +1,41 @@
1
+ import type { LexicalEditor } from 'lexical';
2
+ import { Klass, LexicalNode } from 'lexical';
3
+ import type { LoroDoc, LoroTree } from 'loro-crdt';
4
+ import type { CollabCursor } from './sync/SyncCursors';
5
+ import { NodeMapper } from './nodes/NodesMapper';
6
+ import { Provider } from './State';
7
+ export type ClientID = number;
8
+ export type Binding = {
9
+ tree: LoroTree;
10
+ clientID: ClientID;
11
+ cursors: Map<ClientID, CollabCursor>;
12
+ cursorsContainer: null | HTMLElement;
13
+ doc: LoroDoc;
14
+ docMap: Map<string, LoroDoc>;
15
+ editor: LexicalEditor;
16
+ id: string;
17
+ nodeProperties: Map<string, Array<string>>;
18
+ excludedProperties: ExcludedProperties;
19
+ nodeMapper: NodeMapper;
20
+ commitTimeout?: NodeJS.Timeout | null;
21
+ pendingCommit?: boolean;
22
+ };
23
+ export type ExcludedProperties = Map<Klass<LexicalNode>, Set<string>>;
24
+ export declare function createBinding(editor: LexicalEditor, provider: Provider, id: string, doc: LoroDoc | null | undefined, docMap: Map<string, LoroDoc>, excludedProperties?: ExcludedProperties): Binding;
25
+ /**
26
+ * Schedules an asynchronous commit for the binding to reduce latency with large documents.
27
+ * Uses debouncing to prevent excessive commits during rapid mutations.
28
+ *
29
+ * @param binding - The binding to commit
30
+ * @param delay - Debounce delay in milliseconds (default: 100ms)
31
+ */
32
+ export declare function scheduleAsyncCommit(binding: Binding, delay?: number): void;
33
+ /**
34
+ * Forces an immediate commit if there are pending changes.
35
+ * Useful for ensuring changes are committed before important operations.
36
+ *
37
+ * @param binding - The binding to commit
38
+ */
39
+ export declare function flushPendingCommit(binding: Binding): void;
40
+ export { LoroCollaborators, type LoroCollaboratorsProps, LoroCollaborationUI, type LoroCollaborationUIProps } from './components';
41
+ export { setupLoroDebugging, addDebugPanel, logTreeStructure, verifyTreeStructure } from './Debug';