@datalayer/lexical-loro 0.1.0 → 0.2.1

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