edytor 2.0.0 → 4.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (346) hide show
  1. package/README.md +19 -4
  2. package/dist/block/block.svelte.js +2 -4
  3. package/dist/clipboard/htmlFlow.d.ts +20 -7
  4. package/dist/clipboard/htmlFlow.js +23 -15
  5. package/dist/clipboard/serializeClipboardFragment.d.ts +37 -4
  6. package/dist/clipboard/serializeClipboardFragment.js +6 -4
  7. package/dist/clipboard/textBlocks.d.ts +8 -0
  8. package/dist/clipboard/textBlocks.js +6 -2
  9. package/dist/cloudflare/DocumentRoom.d.ts +13 -9
  10. package/dist/cloudflare/DocumentRoom.js +10 -6
  11. package/dist/cloudflare/room/admission.js +3 -3
  12. package/dist/cloudflare/room/context.d.ts +28 -27
  13. package/dist/cloudflare/room/context.js +2 -2
  14. package/dist/cloudflare/room/purge.d.ts +6 -3
  15. package/dist/cloudflare/room/purge.js +44 -19
  16. package/dist/cloudflare/room/updates.d.ts +3 -4
  17. package/dist/cloudflare/room/updates.js +6 -8
  18. package/dist/cloudflare/routeDocumentSocket.d.ts +17 -0
  19. package/dist/cloudflare/routeDocumentSocket.js +53 -0
  20. package/dist/collaboration/comments/client.d.ts +1 -1
  21. package/dist/collaboration/comments/client.js +1 -1
  22. package/dist/collaboration/remoteSelection.js +3 -3
  23. package/dist/components/Edytor.svelte +2 -10
  24. package/dist/components/Edytor.svelte.d.ts +1 -3
  25. package/dist/crdt/admission.d.ts +5 -10
  26. package/dist/crdt/admission.js +5 -11
  27. package/dist/crdt/attribution/attribution.d.ts +31 -12
  28. package/dist/crdt/attribution/attribution.js +56 -18
  29. package/dist/crdt/attribution/block.d.ts +3 -3
  30. package/dist/crdt/attribution/block.js +7 -8
  31. package/dist/crdt/attribution/index.d.ts +1 -1
  32. package/dist/crdt/attribution/index.js +1 -1
  33. package/dist/crdt/data.d.ts +62 -31
  34. package/dist/crdt/data.js +211 -103
  35. package/dist/crdt/doc/delete.d.ts +1 -1
  36. package/dist/crdt/doc/delete.js +13 -30
  37. package/dist/crdt/doc/funnel.d.ts +7 -6
  38. package/dist/crdt/doc/funnel.js +39 -33
  39. package/dist/crdt/doc/gate.d.ts +3 -20
  40. package/dist/crdt/doc/gate.js +2 -41
  41. package/dist/crdt/doc/history.d.ts +25 -9
  42. package/dist/crdt/doc/history.js +152 -42
  43. package/dist/crdt/doc/layout.js +11 -22
  44. package/dist/crdt/doc/meta.js +12 -17
  45. package/dist/crdt/doc/moves.d.ts +1 -1
  46. package/dist/crdt/doc/moves.js +52 -32
  47. package/dist/crdt/doc/reads.js +2 -2
  48. package/dist/crdt/doc/seed.js +2 -2
  49. package/dist/crdt/doc/split-merge.js +12 -15
  50. package/dist/crdt/doc/steps.d.ts +25 -13
  51. package/dist/crdt/doc/steps.js +52 -122
  52. package/dist/crdt/doc/types.d.ts +21 -9
  53. package/dist/crdt/document.d.ts +21 -19
  54. package/dist/crdt/document.js +26 -23
  55. package/dist/crdt/edytor-doc.d.ts +66 -68
  56. package/dist/crdt/edytor-doc.js +21 -20
  57. package/dist/crdt/engine-api.d.ts +33 -1
  58. package/dist/crdt/engine.d.ts +0 -1
  59. package/dist/crdt/engine.js +1 -4
  60. package/dist/crdt/flow.d.ts +1 -1
  61. package/dist/crdt/flow.js +25 -27
  62. package/dist/crdt/index.d.ts +29 -28
  63. package/dist/crdt/index.js +3 -3
  64. package/dist/crdt/placement/display.d.ts +5 -30
  65. package/dist/crdt/placement/display.js +39 -144
  66. package/dist/crdt/placement/keys.d.ts +58 -0
  67. package/dist/crdt/placement/keys.js +90 -0
  68. package/dist/crdt/placement/model.d.ts +119 -118
  69. package/dist/crdt/placement/model.js +242 -142
  70. package/dist/crdt/placement/resolve.d.ts +123 -35
  71. package/dist/crdt/placement/resolve.js +187 -153
  72. package/dist/crdt/placement/slots.d.ts +134 -0
  73. package/dist/crdt/placement/slots.js +152 -0
  74. package/dist/crdt/protocol.d.ts +2 -2
  75. package/dist/crdt/protocol.js +2 -2
  76. package/dist/crdt/providers/index.d.ts +1 -1
  77. package/dist/crdt/providers/room.d.ts +26 -11
  78. package/dist/crdt/providers/room.js +77 -27
  79. package/dist/crdt/providers/websocket.d.ts +1 -1
  80. package/dist/crdt/providers/websocket.js +33 -32
  81. package/dist/crdt/purge.d.ts +17 -8
  82. package/dist/crdt/purge.js +236 -126
  83. package/dist/crdt/restore.d.ts +2 -2
  84. package/dist/crdt/restore.js +18 -34
  85. package/dist/crdt/schema.d.ts +22 -21
  86. package/dist/crdt/schema.js +29 -23
  87. package/dist/crdt/semantics.js +3 -1
  88. package/dist/crdt/storage.d.ts +1 -1
  89. package/dist/crdt/storage.js +1 -1
  90. package/dist/crdt/structs.d.ts +15 -15
  91. package/dist/crdt/structs.js +8 -22
  92. package/dist/crdt/text/index/cache.js +4 -0
  93. package/dist/crdt/text/index/claims.js +12 -0
  94. package/dist/crdt/text/index/fold.d.ts +2 -3
  95. package/dist/crdt/text/index/fold.js +194 -44
  96. package/dist/crdt/text/index/layout.js +5 -8
  97. package/dist/crdt/text/index/placement.d.ts +26 -18
  98. package/dist/crdt/text/index/placement.js +404 -138
  99. package/dist/crdt/text/index/records.d.ts +3 -3
  100. package/dist/crdt/text/index/records.js +24 -31
  101. package/dist/crdt/text/index/shared.d.ts +11 -3
  102. package/dist/crdt/text/index/shared.js +12 -3
  103. package/dist/crdt/text/index/state.d.ts +21 -17
  104. package/dist/crdt/text/index/state.js +15 -17
  105. package/dist/crdt/text/index/streams.d.ts +10 -5
  106. package/dist/crdt/text/index/streams.js +78 -27
  107. package/dist/crdt/text/items.d.ts +10 -3
  108. package/dist/crdt/text/items.js +7 -0
  109. package/dist/crdt/text/model.d.ts +77 -62
  110. package/dist/crdt/text/model.js +84 -169
  111. package/dist/crdt/text/ranges.d.ts +1 -1
  112. package/dist/crdt/text/ranges.js +3 -3
  113. package/dist/crdt/text/rows.d.ts +13 -7
  114. package/dist/crdt/text/rows.js +24 -7
  115. package/dist/crdt/text/runs.d.ts +17 -12
  116. package/dist/crdt/text/runs.js +24 -7
  117. package/dist/crdt/text/streams.d.ts +26 -13
  118. package/dist/crdt/text/streams.js +41 -14
  119. package/dist/crdt/vendor/yjs/UPSTREAM.md +568 -21
  120. package/dist/crdt/vendor/yjs/dts/global.d.ts +2 -0
  121. package/dist/crdt/vendor/yjs/dts/index.d.ts +1 -1
  122. package/dist/crdt/vendor/yjs/dts/structs/AbstractStruct.d.ts +7 -0
  123. package/dist/crdt/vendor/yjs/dts/structs/Item.d.ts +194 -10
  124. package/dist/crdt/vendor/yjs/dts/utils/Doc.d.ts +6 -3
  125. package/dist/crdt/vendor/yjs/dts/utils/StructStore.d.ts +5 -18
  126. package/dist/crdt/vendor/yjs/dts/utils/Transaction.d.ts +15 -1
  127. package/dist/crdt/vendor/yjs/dts/utils/UpdateDecoder.d.ts +14 -6
  128. package/dist/crdt/vendor/yjs/dts/utils/UpdateEncoder.d.ts +33 -6
  129. package/dist/crdt/vendor/yjs/dts/utils/ids.d.ts +1 -65
  130. package/dist/crdt/vendor/yjs/dts/utils/marks.d.ts +6 -1
  131. package/dist/crdt/vendor/yjs/dts/ynode.d.ts +43 -7
  132. package/dist/crdt/vendor/yjs/global.d.ts +2 -0
  133. package/dist/crdt/vendor/yjs/src/index.js +1 -1
  134. package/dist/crdt/vendor/yjs/src/structs/AbstractStruct.js +10 -0
  135. package/dist/crdt/vendor/yjs/src/structs/Item.js +610 -51
  136. package/dist/crdt/vendor/yjs/src/utils/BlockSet.js +18 -9
  137. package/dist/crdt/vendor/yjs/src/utils/Doc.js +5 -3
  138. package/dist/crdt/vendor/yjs/src/utils/StructStore.js +5 -0
  139. package/dist/crdt/vendor/yjs/src/utils/Transaction.js +36 -13
  140. package/dist/crdt/vendor/yjs/src/utils/UpdateDecoder.js +88 -18
  141. package/dist/crdt/vendor/yjs/src/utils/UpdateEncoder.js +119 -32
  142. package/dist/crdt/vendor/yjs/src/utils/encoding.js +13 -1
  143. package/dist/crdt/vendor/yjs/src/utils/ids.js +7 -7
  144. package/dist/crdt/vendor/yjs/src/utils/marks.js +193 -8
  145. package/dist/crdt/vendor/yjs/src/utils/redo.js +1 -1
  146. package/dist/crdt/vendor/yjs/src/utils/transaction-helpers.js +1 -1
  147. package/dist/crdt/vendor/yjs/src/utils/updates.js +3 -3
  148. package/dist/crdt/vendor/yjs/src/ynode.js +177 -12
  149. package/dist/dnd/autoScroll.d.ts +15 -7
  150. package/dist/dnd/autoScroll.js +10 -15
  151. package/dist/dnd/dropIndicator.js +2 -5
  152. package/dist/dnd/external.d.ts +6 -0
  153. package/dist/dnd/external.js +17 -0
  154. package/dist/dnd/geometry.d.ts +2 -0
  155. package/dist/dnd/geometry.js +3 -4
  156. package/dist/dnd/placement.d.ts +1 -1
  157. package/dist/dnd/pragmatic.d.ts +3 -1
  158. package/dist/dnd/pragmatic.js +12 -2
  159. package/dist/dnd/vendor/pragmatic/UPSTREAM.md +51 -18
  160. package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop/adapter/drop-target-for-external.d.ts +4 -0
  161. package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop/adapter/drop-target-for-external.js +6 -0
  162. package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop/adapter/element-adapter.d.ts +0 -2
  163. package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop/adapter/element-adapter.js +4 -22
  164. package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop/adapter/external-adapter-types.d.ts +26 -0
  165. package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop/adapter/external-adapter.d.ts +30 -0
  166. package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop/adapter/external-adapter.js +203 -0
  167. package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop/adapter/get-available-items.js +13 -0
  168. package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop/adapter/get-available-types.js +9 -0
  169. package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop/adapter/is-an-available-type.js +19 -0
  170. package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop/adapter/monitor-for-external.d.ts +4 -0
  171. package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop/adapter/monitor-for-external.js +6 -0
  172. package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop/honey-pot-fix/make-honey-pot-fix.js +4 -16
  173. package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop/internal-types.d.ts +1 -8
  174. package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop/make-adapter/make-drop-target.js +5 -6
  175. package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop/make-adapter/make-monitor.js +2 -3
  176. package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop/public-utils/element/custom-native-drag-preview/set-custom-native-drag-preview.d.ts +1 -1
  177. package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop/public-utils/element/custom-native-drag-preview/set-custom-native-drag-preview.js +6 -24
  178. package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop/public-utils/external/contains-files.d.ts +2 -0
  179. package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop/public-utils/external/contains-files.js +5 -0
  180. package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop/public-utils/external/get-files.d.ts +3 -0
  181. package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop/public-utils/external/get-files.js +12 -0
  182. package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop/public-utils/external/native-types.d.ts +12 -0
  183. package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop/util/changing-window/is-entering-window-in-safari.js +10 -0
  184. package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop/util/changing-window/is-entering-window.js +55 -0
  185. package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop-auto-scroll/entry-point/external.d.ts +4 -0
  186. package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop-auto-scroll/entry-point/external.js +8 -0
  187. package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop-auto-scroll/internal-types.d.ts +0 -4
  188. package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop-auto-scroll/over-element/get-scroll-by.js +16 -72
  189. package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop-auto-scroll/over-element/try-scroll.js +1 -9
  190. package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop-auto-scroll/shared/configuration.js +4 -29
  191. package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop-auto-scroll/shared/get-scroll-change.js +2 -3
  192. package/dist/edytor.svelte.d.ts +2 -5
  193. package/dist/edytor.svelte.js +21 -32
  194. package/dist/events/beforeInputCommands.js +2 -2
  195. package/dist/events/onBeforeInput.js +1 -1
  196. package/dist/events/onDrop.d.ts +0 -6
  197. package/dist/events/onDrop.js +10 -23
  198. package/dist/events/onInput.d.ts +0 -12
  199. package/dist/events/onInput.js +1 -67
  200. package/dist/events/onPageHide.d.ts +3 -0
  201. package/dist/events/onPageHide.js +16 -0
  202. package/dist/export/forms.d.ts +627 -0
  203. package/dist/export/forms.js +749 -0
  204. package/dist/export/index.d.ts +170 -0
  205. package/dist/export/index.js +161 -0
  206. package/dist/export/markdown.d.ts +41 -0
  207. package/dist/export/markdown.js +585 -0
  208. package/dist/export/markdownWriter.d.ts +9 -0
  209. package/dist/export/markdownWriter.js +133 -0
  210. package/dist/export/mdx.d.ts +15 -0
  211. package/dist/export/mdx.js +33 -0
  212. package/dist/index.d.ts +3 -3
  213. package/dist/index.js +1 -1
  214. package/dist/kinds.js +1 -1
  215. package/dist/plugins/anchored.svelte.d.ts +21 -25
  216. package/dist/plugins/anchored.svelte.js +23 -39
  217. package/dist/plugins/blockHandles/BlockHandleController.svelte.js +24 -32
  218. package/dist/plugins/blockHandles/dragPreview.d.ts +26 -7
  219. package/dist/plugins/blockHandles/dragPreview.js +33 -0
  220. package/dist/plugins/blockMenu/BlockMenuController.svelte.d.ts +5 -0
  221. package/dist/plugins/blockMenu/BlockMenuController.svelte.js +7 -2
  222. package/dist/plugins/blockMenu/blockMenuPlugin.js +5 -50
  223. package/dist/plugins/chrome.d.ts +27 -5
  224. package/dist/plugins/chrome.js +24 -9
  225. package/dist/plugins/code/CodePlugin.svelte +12 -9
  226. package/dist/plugins/code/header.svelte.js +7 -11
  227. package/dist/plugins/code/languageMenu.svelte.d.ts +5 -2
  228. package/dist/plugins/code/languageMenu.svelte.js +13 -20
  229. package/dist/plugins/columns/ColumnsPlugin.svelte +7 -20
  230. package/dist/plugins/columns/resize.svelte.d.ts +2 -3
  231. package/dist/plugins/columns/resize.svelte.js +2 -5
  232. package/dist/plugins/comments/CommentsController.svelte.d.ts +6 -0
  233. package/dist/plugins/comments/CommentsController.svelte.js +20 -0
  234. package/dist/plugins/equation/EquationPlugin.svelte +12 -22
  235. package/dist/plugins/equation/equation.svelte.d.ts +7 -15
  236. package/dist/plugins/equation/equation.svelte.js +13 -50
  237. package/dist/plugins/equation/tex.d.ts +17 -0
  238. package/dist/plugins/equation/tex.js +42 -0
  239. package/dist/plugins/fileDrop.d.ts +38 -23
  240. package/dist/plugins/fileDrop.js +82 -76
  241. package/dist/plugins/find/FindController.svelte.d.ts +5 -0
  242. package/dist/plugins/find/FindController.svelte.js +14 -14
  243. package/dist/plugins/find/findPlugin.js +1 -15
  244. package/dist/plugins/image/ImageChrome.svelte +8 -2
  245. package/dist/plugins/image/ImagePlugin.svelte +15 -52
  246. package/dist/plugins/image/controls.svelte.js +16 -2
  247. package/dist/plugins/image/toolbar.svelte.d.ts +5 -4
  248. package/dist/plugins/image/toolbar.svelte.js +21 -31
  249. package/dist/plugins/index.d.ts +1 -1
  250. package/dist/plugins/list.svelte.d.ts +9 -0
  251. package/dist/plugins/list.svelte.js +18 -0
  252. package/dist/plugins/marquee/marqueePlugin.js +0 -4
  253. package/dist/plugins/media/AudioPlugin.svelte +1 -1
  254. package/dist/plugins/media/BookmarkPlugin.svelte +6 -97
  255. package/dist/plugins/media/EmbedPlugin.svelte +5 -90
  256. package/dist/plugins/media/EmptySlot.svelte +36 -20
  257. package/dist/plugins/media/EmptySlot.svelte.d.ts +6 -15
  258. package/dist/plugins/media/FilePlugin.svelte +1 -19
  259. package/dist/plugins/media/MediaEmpty.svelte +2 -55
  260. package/dist/plugins/media/MediaEmpty.svelte.d.ts +18 -14
  261. package/dist/plugins/media/SourceBlock.svelte +142 -52
  262. package/dist/plugins/media/SourceBlock.svelte.d.ts +10 -4
  263. package/dist/plugins/media/VideoPlugin.svelte +1 -1
  264. package/dist/plugins/media/empty.svelte.js +2 -7
  265. package/dist/plugins/media/media.d.ts +2 -63
  266. package/dist/plugins/media/media.js +1 -194
  267. package/dist/plugins/media/sources.d.ts +60 -0
  268. package/dist/plugins/media/sources.js +165 -0
  269. package/dist/plugins/media/urlPaste.svelte.d.ts +2 -1
  270. package/dist/plugins/media/urlPaste.svelte.js +12 -21
  271. package/dist/plugins/mention/MentionPlugin.svelte +8 -35
  272. package/dist/plugins/page/PagePlugin.svelte +2 -9
  273. package/dist/plugins/page/page.js +1 -1
  274. package/dist/plugins/pageLink/PageLinkPlugin.svelte +6 -13
  275. package/dist/plugins/richtext/RichTextPlugin.svelte +85 -197
  276. package/dist/plugins/richtext/body.js +1 -1
  277. package/dist/plugins/richtext/calloutIcons.svelte.d.ts +2 -2
  278. package/dist/plugins/richtext/calloutIcons.svelte.js +5 -7
  279. package/dist/plugins/richtext/richTextOperations.d.ts +1 -19
  280. package/dist/plugins/richtext/richTextOperations.js +3 -49
  281. package/dist/plugins/slashMenu/SlashMenuController.svelte.d.ts +2 -0
  282. package/dist/plugins/slashMenu/SlashMenuController.svelte.js +7 -0
  283. package/dist/plugins/slashMenu/slashMenuPlugin.js +5 -14
  284. package/dist/plugins/table/TableChrome.svelte +2 -3
  285. package/dist/plugins/table/TablePlugin.svelte +20 -54
  286. package/dist/plugins/table/chrome.svelte.d.ts +5 -2
  287. package/dist/plugins/table/chrome.svelte.js +30 -54
  288. package/dist/plugins/table/table.js +3 -3
  289. package/dist/plugins/toc/TocPlugin.svelte +2 -4
  290. package/dist/plugins/toolbar/ToolbarController.svelte.d.ts +7 -0
  291. package/dist/plugins/toolbar/ToolbarController.svelte.js +20 -13
  292. package/dist/plugins/toolbar/toolbarPlugin.js +19 -53
  293. package/dist/plugins/triggers/TriggerController.svelte.d.ts +7 -2
  294. package/dist/plugins/triggers/TriggerController.svelte.js +11 -4
  295. package/dist/plugins/triggers/place.js +1 -2
  296. package/dist/plugins/triggers/triggers.d.ts +6 -1
  297. package/dist/plugins/triggers/triggers.js +12 -13
  298. package/dist/plugins/uploads.svelte.d.ts +5 -2
  299. package/dist/plugins/uploads.svelte.js +25 -15
  300. package/dist/plugins.d.ts +26 -0
  301. package/dist/plugins.js +0 -24
  302. package/dist/selection/replaceSelection.js +2 -2
  303. package/dist/selection/selection.svelte.d.ts +4 -10
  304. package/dist/selection/selection.svelte.js +7 -11
  305. package/dist/session/bindings.js +1 -1
  306. package/dist/session/commands.d.ts +7 -11
  307. package/dist/session/commands.js +13 -19
  308. package/dist/session/inputRules.js +1 -1
  309. package/dist/session/navigation.js +1 -1
  310. package/dist/session/suggestions.svelte.d.ts +0 -11
  311. package/dist/session/suggestions.svelte.js +15 -3
  312. package/dist/session/uploads.d.ts +8 -8
  313. package/dist/surface/lines.js +1 -3
  314. package/dist/surface/observer.svelte.d.ts +17 -1
  315. package/dist/surface/observer.svelte.js +74 -19
  316. package/dist/surface/overlay.d.ts +0 -14
  317. package/dist/surface/overlay.js +0 -25
  318. package/dist/surface/projector.svelte.d.ts +15 -3
  319. package/dist/surface/projector.svelte.js +60 -9
  320. package/dist/text/text.svelte.js +3 -13
  321. package/dist/utils/sanitize.d.ts +38 -0
  322. package/dist/utils/sanitize.js +82 -0
  323. package/dist/utils.d.ts +2 -0
  324. package/dist/utils.js +5 -0
  325. package/package.json +19 -2
  326. package/dist/crdt/placement/rank.d.ts +0 -87
  327. package/dist/crdt/placement/rank.js +0 -332
  328. package/dist/crdt/placement/source.d.ts +0 -43
  329. package/dist/crdt/placement/source.js +0 -66
  330. package/dist/crdt/text/delete-index.d.ts +0 -129
  331. package/dist/crdt/text/delete-index.js +0 -365
  332. package/dist/crdt/text/deletes.d.ts +0 -76
  333. package/dist/crdt/text/deletes.js +0 -362
  334. package/dist/crdt/text/index/anchored.d.ts +0 -17
  335. package/dist/crdt/text/index/anchored.js +0 -197
  336. package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop/util/max-z-index.js +0 -3
  337. package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop/util/supports-popover.js +0 -16
  338. package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop-auto-scroll/shared/is-axis-allowed.js +0 -3
  339. package/dist/plugins/code/LanguageMenu.svelte +0 -25
  340. package/dist/plugins/code/LanguageMenu.svelte.d.ts +0 -9
  341. package/dist/plugins/equation/EquationEditor.svelte +0 -27
  342. package/dist/plugins/equation/EquationEditor.svelte.d.ts +0 -9
  343. package/dist/plugins/image/ImageToolbarHost.svelte +0 -37
  344. package/dist/plugins/image/ImageToolbarHost.svelte.d.ts +0 -9
  345. package/dist/plugins/richtext/CalloutIconPicker.svelte +0 -26
  346. package/dist/plugins/richtext/CalloutIconPicker.svelte.d.ts +0 -9
package/README.md CHANGED
@@ -17,11 +17,11 @@
17
17
 
18
18
  Edytor aims to be for Svelte what Slate.js is for React: a heavily customizable editor with an API to build any kind of collaborative rich text editor.
19
19
 
20
- > **2.0.** Edytor `2.0.0` is on npm as `edytor`: its API follows semantic versioning, and every change is listed in the changelog. It has no production track record yet: read the [limitations](https://edytor.dev/docs/reference/limitations) before you build on it. Issues and PRs are welcome: when you report a bug, include the document's JSON value.
20
+ > **4.0.** Edytor `4.0.0` is on npm as `edytor`: its API follows semantic versioning, and every change is listed in the changelog. It has no production track record yet: read the [limitations](https://edytor.dev/docs/reference/limitations) before you build on it. Issues and PRs are welcome: when you report a bug, include the document's JSON value.
21
21
 
22
22
  ## Features
23
23
 
24
- - **Notion-style editing out of the box.** `<Edytor />` alone is a rich text editor with block handles: headings, toggle headings, lists, to-dos, toggles, callouts, quotes, dividers, ten marks and Notion's hotkeys. Add the Notion theme, a block menu (block colours; drag one block, or every block the selection covers), a slash menu, a selection toolbar, markdown shortcuts (`createMarkdownShortcutsPlugin()`) code blocks and images (`createImagePlugin({ upload })`).
24
+ - **Notion-style editing out of the box.** `<Edytor />` alone is a rich text editor: headings, toggle headings, lists, to-dos, toggles, callouts, quotes, dividers, ten marks and Notion's hotkeys. Add the Notion theme and the plugins you want: block handles and a block menu (block colours; drag one block, or every block the selection covers), a slash menu, a selection toolbar, markdown shortcuts (`createMarkdownShortcutsPlugin()`), code blocks and images (`createImagePlugin({ upload })`). The package draws no chrome: each handle and menu is your snippet, or the ready-made registry item.
25
25
  - **Pages and a table of contents, opt-in.** `createPagePlugin` links a block to another document (a page per room, opened and named by your app), and `createTocPlugin()` lists the headings live ([Page](https://edytor.dev/docs/plugins/page), [Table of contents](https://edytor.dev/docs/plugins/table-of-contents)).
26
26
  - **Columns, opt-in.** List `createColumnsPlugin()` for Notion's multi-column layouts: drag a block to the edge of another to put them side by side, or pick "2 columns" to "5 columns"; drag the gap to resize. Layouts converge across collaborators and the room ([Columns](https://edytor.dev/docs/plugins/columns)).
27
27
  - **Tables, opt-in.** List `createTablePlugin()` for Notion's simple table: cells of text, <kbd>Tab</kbd> between them, rows and columns added, moved and deleted from the table's edges and grips, resizable columns, header row and column, HTML tables pasted and copied. Concurrent row and column edits converge on every replica ([Table](https://edytor.dev/docs/plugins/table)).
@@ -35,11 +35,12 @@ Edytor aims to be for Svelte what Slate.js is for React: a heavily customizable
35
35
  - **Real-time collaboration.** One `EdytorDocument` shared by any number of views, or none (headless). Presence cursors, identity-preserving moves, splits and merges, and undo that only takes back your own edits.
36
36
  - **Offline first.** A local IndexedDB copy and cross-tab sync; offline edits survive reloads and reach the server on reconnect.
37
37
  - **A Cloudflare Durable Object room.** `edytor/cloudflare` stores in SQLite, acknowledges after the write, binds identity to the socket and hibernates.
38
+ - **Import and export.** `edytor/export` turns a document into HTML or Markdown and back (`toHTML`, `toMarkdown`, `fromHTML`, `textToBlocks`), by each kind's own forms, in the browser, Node or a Worker; HTML import is sanitized ([Import and export](https://edytor.dev/docs/editor/import-export)).
38
39
  - **Headless and Worker-safe.** `edytor/crdt/edytor` runs in Node and Workers without Svelte.
39
40
 
40
41
  ## Install
41
42
 
42
- The pre-release is on npm under the `next` tag. Name the tag: a bare `edytor` is the old, incompatible `0.0.11`.
43
+ Edytor `4.0.0` is on npm under `latest`:
43
44
 
44
45
  ```bash
45
46
  pnpm add edytor
@@ -65,7 +66,21 @@ pnpm add edytor
65
66
 
66
67
  `<Edytor>` renders on the server and hydrates, so it works in any route. It includes rich text; each other block kind, block moves from the keyboard (`createArrowMovePlugin()`), and file drops (a media plugin given an `upload`) is a plugin you add, here code blocks; nesting blocks (<kbd>Tab</kbd>, drops inside a block) is the `allowNesting` option, off by default. `onChange` hands you the document after every change ([quick start](https://edytor.dev/docs/getting-started/quick-start)).
67
68
 
68
- The package draws no menu, toolbar or block handle: each is a snippet you pass its plugin ([menus and handles](https://edytor.dev/docs/customization/menus)). The demo's Notion-style ones are in [`src/routes/chrome`](https://github.com/beynar/edytor/tree/master/src/routes/chrome), ready to copy into your app ([ready-made menus](https://edytor.dev/docs/customization/ready-made-menus)).
69
+ The package draws no menu, toolbar or block handle: each is a snippet you pass its plugin ([menus and handles](https://edytor.dev/docs/customization/menus)). Notion-style ones, in shadcn-svelte, are a registry item you add to your app (`npx shadcn-svelte@latest add https://edytor.dev/r/edytor-chrome.json`), as plugins for your `<Edytor>` ([ready-made menus](https://edytor.dev/docs/customization/ready-made-menus)).
70
+
71
+ The fastest way to a full editor is the starter, a [shadcn-svelte](https://www.shadcn-svelte.com) registry item: every plugin, the ready-made menus and handles, comments, and a page with a cover, an icon, a title and typed properties, in one component copied into your app (Tailwind v4 and `shadcn-svelte init` first; [starter editor](https://edytor.dev/docs/starter)):
72
+
73
+ ```sh
74
+ npx shadcn-svelte@latest add https://edytor.dev/r/starter.json
75
+ ```
76
+
77
+ ```svelte
78
+ <script>
79
+ import { StarterEditor } from '$lib/components/edytor/starter/index.js';
80
+ </script>
81
+
82
+ <StarterEditor />
83
+ ```
69
84
 
70
85
  To collaborate, name a room and a server running the [`edytor/cloudflare` room](https://edytor.dev/docs/server/quick-start):
71
86
 
@@ -1,3 +1,4 @@
1
+ import { cleanups } from '../utils.js';
1
2
  import { Text } from '../text/text.svelte.js';
2
3
  /** Mark an element inside a block's markup as non-editable chrome (`block.void`, a preview's too). */
3
4
  export const voidChrome = (node) => {
@@ -336,10 +337,7 @@ export class Block {
336
337
  this.edytor.selection.keep(this);
337
338
  // A block laid out again with no commit moves the chrome beside it (the overlay measures).
338
339
  const unobserve = this.edytor.overlay.observe(node);
339
- const onDestroy = this.edytor.plugins.flatMap((plugin) => {
340
- const action = plugin.onBlockAttached?.({ node, block: this });
341
- return typeof action === 'function' ? [action] : [];
342
- });
340
+ const onDestroy = cleanups(this.edytor.plugins, (plugin) => plugin.onBlockAttached?.({ node, block: this }));
343
341
  return {
344
342
  destroy: () => {
345
343
  this.#viewState = read(node);
@@ -1,10 +1,20 @@
1
- import type { Edytor } from '../edytor.svelte.js';
2
1
  import type { Flow } from '../crdt/flow.js';
3
- import type { BlockDefinition } from '../plugins.js';
4
- import { type SerializableContent } from '../utils/json.js';
2
+ import { type JSONBlock, type SerializableContent } from '../utils/json.js';
3
+ import type { AtomForms, BlockForms, MarkForms } from './serializeClipboardFragment.js';
5
4
  /** What HTML import reads: the kind, mark and atom records, and the document's default child. */
6
- export type ImportKinds = Pick<Edytor, 'blocks' | 'marks'> & Partial<Pick<Edytor, 'inlineBlocks'>> & {
7
- document: Pick<Edytor['document'], 'defaultChild'>;
5
+ export type ImportKinds = {
6
+ readonly blocks: ReadonlyMap<string, BlockForms>;
7
+ readonly marks: ReadonlyMap<string, MarkForms>;
8
+ readonly inlineBlocks?: ReadonlyMap<string, AtomForms>;
9
+ readonly document: {
10
+ defaultChild: (parent: string | null) => string;
11
+ };
12
+ };
13
+ /** A `DOMParser` constructor: the browser's, or a server's (`linkedom`, `jsdom`, `happy-dom`). */
14
+ export type HtmlParser = new () => {
15
+ parseFromString(html: string, type: 'text/html'): {
16
+ body: Node | null;
17
+ };
8
18
  };
9
19
  type Values = Record<string, SerializableContent>;
10
20
  /**
@@ -13,9 +23,10 @@ type Values = Record<string, SerializableContent>;
13
23
  * none: an export form written as one (a callout's `<div data-edytor-callout>`)
14
24
  * is found by its `parse` hook only.
15
25
  */
16
- export declare const tagOf: (type: string, kind: BlockDefinition, data: Values) => string | undefined;
26
+ export declare const tagOf: (type: string, kind: BlockForms, data: Values) => string | undefined;
17
27
  /**
18
- * External HTML as a flow: the browser parses (inert: no script
28
+ * External HTML as lines (JSON blocks; a line without a `type` is its
29
+ * parent's default child): `parser` parses (inert: no script
19
30
  * runs, nothing loads), and the tag tables are the records inverted — a
20
31
  * catalogue kind's tag per preset (a content-less container takes its
21
32
  * default child's tag, one child per text line), a value-less mark's
@@ -27,5 +38,7 @@ export declare const tagOf: (type: string, kind: BlockDefinition, data: Values)
27
38
  * atom, never its text. Unknown
28
39
  * elements degrade to text runs; whitespace collapses as HTML renders it. `null` when the HTML carries nothing (`flow.shape`).
29
40
  */
41
+ export declare const linesOfHtml: (kinds: ImportKinds, html: string | undefined, parser?: HtmlParser | undefined) => JSONBlock[] | null;
42
+ /** External HTML as a flow (the paste's): {@link linesOfHtml}, with the browser's parser. */
30
43
  export declare const flowOfHtml: (kinds: ImportKinds, html: string | undefined) => Flow | null;
31
44
  export {};
@@ -1,6 +1,8 @@
1
1
  import { colorsOfClasses } from '../block/colors.js';
2
2
  import { isTextPart } from '../block/contentRange.js';
3
3
  import { jsonBlockToSpec } from '../utils/json.js';
4
+ /** Element and text nodes by their type, not their realm: a server parser's nodes are not this global's. */
5
+ const isElement = (node) => node?.nodeType === 1;
4
6
  /** Never content: their text is code, metadata or form state. */
5
7
  const SKIP = /^(script|style|template|noscript|svg|math|iframe|object|embed|canvas|video|audio|img|input|button|select|textarea|head|title|meta|link|base)$/;
6
8
  /** HTML's block-level elements: they start a line (a kind's tag does too). */
@@ -21,7 +23,7 @@ const sizeOf = (img, side) => {
21
23
  * email's tracking pixel). It is text, its `alt`, never a block.
22
24
  */
23
25
  const isGlyph = (node) => {
24
- if (!(node instanceof HTMLElement) || node.localName !== 'img')
26
+ if (!isElement(node) || node.localName !== 'img')
25
27
  return false;
26
28
  const alt = node.getAttribute('alt')?.trim() ?? '';
27
29
  if (alt && EMOJI_ALT.test(alt) && /[\p{Extended_Pictographic}\p{Regional_Indicator}]/u.test(alt))
@@ -61,7 +63,8 @@ export const tagOf = (type, kind, data) => {
61
63
  return undefined;
62
64
  };
63
65
  /**
64
- * External HTML as a flow: the browser parses (inert: no script
66
+ * External HTML as lines (JSON blocks; a line without a `type` is its
67
+ * parent's default child): `parser` parses (inert: no script
65
68
  * runs, nothing loads), and the tag tables are the records inverted — a
66
69
  * catalogue kind's tag per preset (a content-less container takes its
67
70
  * default child's tag, one child per text line), a value-less mark's
@@ -73,8 +76,8 @@ export const tagOf = (type, kind, data) => {
73
76
  * atom, never its text. Unknown
74
77
  * elements degrade to text runs; whitespace collapses as HTML renders it. `null` when the HTML carries nothing (`flow.shape`).
75
78
  */
76
- export const flowOfHtml = (kinds, html) => {
77
- if (!html || html.length > 8 * 1024 * 1024 || typeof DOMParser === 'undefined')
79
+ export const linesOfHtml = (kinds, html, parser = globalThis.DOMParser) => {
80
+ if (!html || html.length > 8 * 1024 * 1024 || !parser)
78
81
  return null;
79
82
  const { blocks, marks } = kinds;
80
83
  const atoms = kinds.inlineBlocks ?? new Map();
@@ -99,8 +102,9 @@ export const flowOfHtml = (kinds, html) => {
99
102
  return undefined;
100
103
  for (const [type, kind] of blocks) {
101
104
  const data = kind.parse?.(element);
105
+ // A kind of lines (a code block) takes its element's text, one child per line.
102
106
  if (data)
103
- return { type, kind, data };
107
+ return { type, kind, data, lines: kind.lines ? kind.defaultChild : undefined };
104
108
  }
105
109
  return byTag.get(element.localName);
106
110
  };
@@ -124,11 +128,10 @@ export const flowOfHtml = (kinds, html) => {
124
128
  return found;
125
129
  };
126
130
  // A kind's hook may claim an element of another namespace (an equation's MathML `<math>`).
127
- const isBlock = (node) => (node instanceof HTMLElement && BLOCK.test(node.localName)) ||
128
- (node instanceof Element && kindOf(node) !== undefined);
131
+ const isBlock = (node) => isElement(node) && (BLOCK.test(node.localName) || kindOf(node) !== undefined);
129
132
  /** A void kind's element (an image): it shows no text, so a line it is met in ends there. */
130
133
  const isVoid = (node) => {
131
- const claim = node instanceof Element ? kindOf(node) : undefined;
134
+ const claim = isElement(node) ? kindOf(node) : undefined;
132
135
  return claim?.kind.void === true;
133
136
  };
134
137
  const text = (line, value, marks, pre) => {
@@ -148,16 +151,16 @@ export const flowOfHtml = (kinds, html) => {
148
151
  line.content.push(Object.keys(marks).length ? { text: value, marks } : { text: value });
149
152
  };
150
153
  const inline = (node, at, marks, pre) => {
151
- if (node.nodeType === Node.TEXT_NODE)
154
+ if (node.nodeType === 3)
152
155
  return text(at.line(), node.textContent ?? '', marks, pre);
153
156
  if (isGlyph(node))
154
157
  return text(at.line(), node.getAttribute('alt') ?? '', marks, pre);
155
158
  if (isVoid(node))
156
159
  return at.apart(node);
157
- const atom = node instanceof Element ? atomOf(node) : undefined;
160
+ const atom = isElement(node) ? atomOf(node) : undefined;
158
161
  if (atom)
159
162
  return void at.line().content.push(atom);
160
- if (!(node instanceof HTMLElement) || SKIP.test(node.localName))
163
+ if (!isElement(node) || SKIP.test(node.localName))
161
164
  return;
162
165
  if (node.localName === 'br')
163
166
  return text(at.line(), '\n', marks, true);
@@ -286,12 +289,17 @@ export const flowOfHtml = (kinds, html) => {
286
289
  // Split: a text line left empty around a void element is not kept.
287
290
  return parts.filter((part) => !texts.has(part) || end(part).content.length > 0 || part.children !== undefined);
288
291
  };
289
- const body = new DOMParser().parseFromString(html, 'text/html').body;
292
+ const body = new parser().parseFromString(html, 'text/html').body;
293
+ if (!body)
294
+ return null;
290
295
  const lines = linesOf(body, undefined);
291
296
  const carries = (line) => line.content.length > 0 ||
292
297
  Boolean(line.children?.some(carries)) ||
293
298
  Boolean(line.type && blocks.get(line.type)?.void);
294
- return lines.some(carries)
295
- ? { lines: lines.map((line) => jsonBlockToSpec(line, true)) }
296
- : null;
299
+ return lines.some(carries) ? lines : null;
300
+ };
301
+ /** External HTML as a flow (the paste's): {@link linesOfHtml}, with the browser's parser. */
302
+ export const flowOfHtml = (kinds, html) => {
303
+ const lines = linesOfHtml(kinds, html);
304
+ return lines ? { lines: lines.map((line) => jsonBlockToSpec(line, true)) } : null;
297
305
  };
@@ -1,9 +1,42 @@
1
- import type { Edytor } from '../edytor.svelte.js';
2
- import type { EdytorClipboardFragment } from './types.js';
3
- /** The records the export reads: each kind, mark and atom declares its own forms. */
4
- export type ExportKinds = Pick<Edytor, 'blocks' | 'marks' | 'inlineBlocks'>;
1
+ /**
2
+ * The document's export forms, one reading for the clipboard and for
3
+ * `toHTML` / `toMarkdown` (`edytor/export`): each kind, mark and atom
4
+ * declares its own forms (`html`, `plain`, `markdown`; a mark's `tag` and
5
+ * `attributes`), and this module only walks the blocks. Pure: no view, no
6
+ * DOM, no Svelte.
7
+ */
8
+ import type { JSONBlock, SerializableContent } from '../utils/json.js';
9
+ import type { BlockDefinition, InlineBlockDefinition, MarkDefinition } from '../plugins.js';
10
+ import type { EdytorClipboardFragment, JSONContentPart } from './types.js';
11
+ /** A kind's export and import forms: the fields of its record the export and HTML import read. */
12
+ export type BlockForms = Pick<BlockDefinition, 'html' | 'plain' | 'markdown' | 'parse' | 'element' | 'contentElement' | 'void' | 'island' | 'lines' | 'rendersContent' | 'defaultChild' | 'itemKind'> & {
13
+ /** The data of each way to create the kind: HTML import finds a preset's tag. */
14
+ presets?: {
15
+ data?: Record<string, SerializableContent>;
16
+ }[];
17
+ };
18
+ /** A mark's export and import forms. */
19
+ export type MarkForms = Pick<MarkDefinition, 'tag' | 'attributes' | 'parse' | 'markdown'>;
20
+ /** An atom's export and import forms. */
21
+ export type AtomForms = Pick<InlineBlockDefinition, 'html' | 'plain' | 'markdown' | 'parse'>;
22
+ /** The records the export reads: each kind, mark and atom declares its own forms (a view is one). */
23
+ export type ExportKinds = {
24
+ readonly blocks: ReadonlyMap<string, BlockForms>;
25
+ readonly marks: ReadonlyMap<string, MarkForms>;
26
+ readonly inlineBlocks: ReadonlyMap<string, AtomForms>;
27
+ };
5
28
  export declare const encodeClipboardJson: (value: unknown) => string;
6
29
  /** `value` escaped for an HTML text or a double-quoted attribute: every kind's export reads it. */
7
30
  export declare const escapeHtml: (value: string) => string;
31
+ /** The content as HTML, or as plain text: an atom by its kind's form (`html`, `plain`). */
32
+ export declare const contentOf: (content: JSONContentPart[] | undefined, kinds: ExportKinds, html: boolean) => string;
33
+ /**
34
+ * How sibling blocks' HTML joins (`edytor/export` wraps a run of list items
35
+ * in its list): the blocks, their HTML, and their parent's `html` form.
36
+ * Without one, one after another (the clipboard's).
37
+ */
38
+ export type SiblingsHtml = (blocks: JSONBlock[], html: string[], parent?: BlockForms['html']) => string;
39
+ /** Blocks as HTML: the clipboard's and `toHTML`'s one reading of the kinds' forms. */
40
+ export declare const blocksToHtml: (blocks: JSONBlock[], kinds: ExportKinds, wrap: SiblingsHtml) => string;
8
41
  export declare const serializeClipboardFragmentToPlainText: (fragment: EdytorClipboardFragment, kinds: ExportKinds) => string;
9
42
  export declare const serializeClipboardFragmentToHtml: (fragment: EdytorClipboardFragment, kinds: ExportKinds) => string;
@@ -19,7 +19,7 @@ const textHtml = (part, kinds) => {
19
19
  return html;
20
20
  };
21
21
  /** The content as HTML, or as plain text: an atom by its kind's form (`html`, `plain`). */
22
- const contentOf = (content = [], kinds, html) => content
22
+ export const contentOf = (content = [], kinds, html) => content
23
23
  .map((part) => {
24
24
  if (isTextPart(part))
25
25
  return html ? textHtml(part, kinds) : part.text;
@@ -41,9 +41,9 @@ const withClasses = (html, classes) => classes
41
41
  })
42
42
  : html;
43
43
  /** A block and its subtree as HTML (its colours as Notion's classes), or as plain text. */
44
- const blockOf = (block, kinds, html) => {
44
+ const blockOf = (block, kinds, html, wrap) => {
45
45
  const content = contentOf(block.content, kinds, html);
46
- const kids = block.children?.map((child) => blockOf(child, kinds, html)) ?? [];
46
+ const kids = block.children?.map((child) => blockOf(child, kinds, html, wrap)) ?? [];
47
47
  const kind = kinds.blocks.get(block.type);
48
48
  if (!html) {
49
49
  const children = kids.filter(Boolean).join('\n');
@@ -51,8 +51,8 @@ const blockOf = (block, kinds, html) => {
51
51
  ? kind.plain(block, content, children)
52
52
  : [content, children].filter(Boolean).join('\n');
53
53
  }
54
- const children = kids.join('');
55
54
  const form = kind?.html;
55
+ const children = wrap ? wrap(block.children ?? [], kids, form) : kids.join('');
56
56
  const out = !form
57
57
  ? `<p>${content}</p>${children}`
58
58
  : typeof form === 'string'
@@ -61,6 +61,8 @@ const blockOf = (block, kinds, html) => {
61
61
  // A block's colours as Notion's export names them (`block-color-red`).
62
62
  return withClasses(out, colorClasses(block.data));
63
63
  };
64
+ /** Blocks as HTML: the clipboard's and `toHTML`'s one reading of the kinds' forms. */
65
+ export const blocksToHtml = (blocks, kinds, wrap) => wrap(blocks, blocks.map((block) => blockOf(block, kinds, true, wrap)));
64
66
  export const serializeClipboardFragmentToPlainText = (fragment, kinds) => fragment.kind === 'blocks'
65
67
  ? fragment.blocks.map((block) => blockOf(block, kinds, false)).join('\n')
66
68
  : contentOf(fragment.content, kinds, false);
@@ -21,5 +21,13 @@ export type TextToBlocksOptions = {
21
21
  };
22
22
  /** Whether `text` holds block markdown (one line of it is enough), as a paste reads it. */
23
23
  export declare const hasBlockMarkdown: (text: string) => boolean;
24
+ /**
25
+ * One line's kind, data and text, or `null` for a paragraph line: the one
26
+ * reading of a markdown line's block marker (`edytor/export`'s full reader
27
+ * reads its lines with it too).
28
+ */
29
+ export declare const lineKind: (line: string) => (Omit<JSONBlock, "content"> & {
30
+ text: string;
31
+ }) | null;
24
32
  /** `text` as blocks (see the module comment). */
25
33
  export declare const textToBlocks: (text: string, { markdown, type }?: TextToBlocksOptions) => JSONBlock[];
@@ -25,8 +25,12 @@ const runs = (text) => {
25
25
  const BLOCK_LINE = /^\s*(?:#{1,6}\s|[-*+]\s|\d+[.)]\s|>|```|(?:-{3,}|\*{3,}|_{3,})\s*$)/;
26
26
  /** Whether `text` holds block markdown (one line of it is enough), as a paste reads it. */
27
27
  export const hasBlockMarkdown = (text) => text.split(/\r?\n/).some((line) => BLOCK_LINE.test(line));
28
- /** One line's kind, data and text, or `null` for a paragraph line. */
29
- const lineKind = (line) => {
28
+ /**
29
+ * One line's kind, data and text, or `null` for a paragraph line: the one
30
+ * reading of a markdown line's block marker (`edytor/export`'s full reader
31
+ * reads its lines with it too).
32
+ */
33
+ export const lineKind = (line) => {
30
34
  let m = /^(#{1,6})\s+(.*)$/.exec(line);
31
35
  if (m)
32
36
  return { type: 'heading', data: { level: `h${Math.min(3, m[1].length)}` }, text: m[2] };
@@ -121,9 +121,11 @@ export declare const DEFAULT_SAVE_AFTER = 2000;
121
121
  * Room quotas, each refused with `4413` (`quota: <name>`). The
122
122
  * document's size: what its records hold (uncompressed) and the updates the
123
123
  * engine holds waiting. An isolate has 128 MB, and the live document takes
124
- * 18 to 46 bytes of heap per stored byte (prose to one short line per
125
- * block, its index included; `bench/room-memory.mjs`): 2 MiB is
126
- * about 100 MB at worst. Raise it for documents of long text.
124
+ * 15 to 77 bytes of heap per stored byte in Node (prose to one short line
125
+ * per block, its index included; `bench/room-memory.mjs`; a Worker takes
126
+ * less): 2 MiB is about 150 to 160 MB at worst, a list of some 23,000 short
127
+ * blocks (1.25 MiB keeps that near 100 MB). Raise it for documents of long
128
+ * text, lower it for long lists of short blocks.
127
129
  */
128
130
  export declare const DEFAULT_MAX_DOCUMENT_BYTES: number;
129
131
  /** The share of the document quota past which the room logs its size, by default. */
@@ -364,7 +366,7 @@ export type RoomLogEntry = {
364
366
  user: string;
365
367
  } | ({
366
368
  edytor: 'purge';
367
- horizon: number;
369
+ horizon: number | null;
368
370
  bytes: number;
369
371
  } & PurgeReport) | {
370
372
  edytor: 'quota';
@@ -801,12 +803,14 @@ export declare class AttachedDocument {
801
803
  * The purge task, also over RPC (`room.purge.timing`): record an epoch
802
804
  * (the state vector, now) when the document changed since the last one,
803
805
  * purge what was deleted before the horizon — the newest epoch at least
804
- * `purgeAfterDays` old — when it is newer than the last purged, and
805
- * re-arm for the next epoch to pass it. Returns what the purge wrote, or
806
- * `null` when nothing was past the horizon.
806
+ * `purgeAfterDays` old — when it is newer than the last purged, with what
807
+ * the sessions whose history ended deleted (`hist.release.end`; with no
808
+ * epoch due, those alone, `horizon: null`), and re-arm for the next epoch
809
+ * to pass it. Returns what the purge wrote, or `null` when nothing was
810
+ * past the horizon and no session had ended.
807
811
  */
808
812
  purge(): (PurgeReport & {
809
- horizon: number;
813
+ horizon: number | null;
810
814
  }) | null;
811
815
  /** The room's counters, also over RPC — see {@link RoomMetrics}. */
812
816
  metrics(): RoomMetrics;
@@ -968,7 +972,7 @@ export declare class DocumentRoom<Env = DocumentRoomEnv> extends DurableObject<E
968
972
  };
969
973
  /** Run the purge task now, also over RPC — see {@link AttachedDocument.purge}. */
970
974
  purge(): (PurgeReport & {
971
- horizon: number;
975
+ horizon: number | null;
972
976
  }) | null;
973
977
  /** Every comment thread, also over RPC — see {@link AttachedDocument.listComments}. */
974
978
  listComments(): CommentSnapshot;
@@ -130,9 +130,11 @@ export const DEFAULT_SAVE_AFTER = 2000;
130
130
  * Room quotas, each refused with `4413` (`quota: <name>`). The
131
131
  * document's size: what its records hold (uncompressed) and the updates the
132
132
  * engine holds waiting. An isolate has 128 MB, and the live document takes
133
- * 18 to 46 bytes of heap per stored byte (prose to one short line per
134
- * block, its index included; `bench/room-memory.mjs`): 2 MiB is
135
- * about 100 MB at worst. Raise it for documents of long text.
133
+ * 15 to 77 bytes of heap per stored byte in Node (prose to one short line
134
+ * per block, its index included; `bench/room-memory.mjs`; a Worker takes
135
+ * less): 2 MiB is about 150 to 160 MB at worst, a list of some 23,000 short
136
+ * blocks (1.25 MiB keeps that near 100 MB). Raise it for documents of long
137
+ * text, lower it for long lists of short blocks.
136
138
  */
137
139
  export const DEFAULT_MAX_DOCUMENT_BYTES = 2 * 1024 * 1024;
138
140
  /** The share of the document quota past which the room logs its size, by default. */
@@ -480,9 +482,11 @@ export class AttachedDocument {
480
482
  * The purge task, also over RPC (`room.purge.timing`): record an epoch
481
483
  * (the state vector, now) when the document changed since the last one,
482
484
  * purge what was deleted before the horizon — the newest epoch at least
483
- * `purgeAfterDays` old — when it is newer than the last purged, and
484
- * re-arm for the next epoch to pass it. Returns what the purge wrote, or
485
- * `null` when nothing was past the horizon.
485
+ * `purgeAfterDays` old — when it is newer than the last purged, with what
486
+ * the sessions whose history ended deleted (`hist.release.end`; with no
487
+ * epoch due, those alone, `horizon: null`), and re-arm for the next epoch
488
+ * to pass it. Returns what the purge wrote, or `null` when nothing was
489
+ * past the horizon and no session had ended.
486
490
  */
487
491
  purge() {
488
492
  return this.room.purge.tick();
@@ -11,7 +11,7 @@
11
11
  */
12
12
  import { Y } from '../../crdt/engine.js';
13
13
  import * as E from '../../crdt/protocol.js';
14
- import { ChunkLimitError, ChunkSequenceError, CLOSE } from '../../crdt/providers/room.js';
14
+ import { ChunkError, CLOSE } from '../../crdt/providers/room.js';
15
15
  import { MAX_WAITING_DELETES, noTimers } from './shared.js';
16
16
  import { STORAGE_FAILURE, now, sync, tally } from './context.js';
17
17
  import { attributionWrites, BINDING_PREFIX, forgedAttributionDeletes, forgedDeletes, forgedWriters } from './forged.js';
@@ -168,7 +168,7 @@ export class Admission {
168
168
  }
169
169
  catch (error) {
170
170
  this.#chunkReaders.delete(ws);
171
- if (error instanceof ChunkLimitError) {
171
+ if (error instanceof ChunkError && error.limit !== undefined) {
172
172
  return this.#overQuota(ws, attachment.user, 'frame', {
173
173
  bytes: error.total,
174
174
  limit: error.limit
@@ -187,7 +187,7 @@ export class Admission {
187
187
  room.presence.depart(ws);
188
188
  return room.close(ws, CLOSE.fault, 'room busy');
189
189
  }
190
- if (error instanceof ChunkSequenceError) {
190
+ if (error instanceof ChunkError) {
191
191
  room.note({ reason: 'internal', detail: `chunks: ${error.message}` });
192
192
  room.presence.depart(ws);
193
193
  return room.close(ws, CLOSE.fault, 'chunk sequence lost');