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
@@ -3,41 +3,42 @@
3
3
  * ownership the display reads (`ownShim`), and THE shown-kind rule
4
4
  * (`typeOf`).
5
5
  *
6
- * A structural change re-decides only what it can change: the winning
7
- * placement of the blocks whose candidates (or whose parent's
8
- * registry entry) changed, and the display slot of every block whose
9
- * slot walk (`displaySlotOf`) reads one that changed — its stored
10
- * subtree, through the blocks it displays — patched into the parents'
11
- * child lists. While every block shows its winning candidate (no
12
- * cycle rejected, none rehomed), a block's placement is its argmax
13
- * (`resolvePlacements` accepts it), so only a cycle through a changed
14
- * display edge needs the global resolution, which then runs whole.
15
- * The layout rules re-run only on the layouts a change reaches.
6
+ * A structural change re-decides only what it can change: the display
7
+ * edge of the blocks whose slot, record or mover changed (fork patch
8
+ * YP22), and the display slot of every block whose slot walk
9
+ * (`displaySlotOf`) reads one that changed — its stored subtree, through
10
+ * the blocks it displays — patched into the parents' child lists. A
11
+ * block's candidate edges are its live move records, strongest first, then
12
+ * its home slot; it shows at the first that closes no cycle through the
13
+ * accepted edges (`settle`): the later move wins, and the block whose edge
14
+ * is the oldest of a cycle falls back to its next candidate, back where it
15
+ * stood (its previous record, else home; the root's tail only when every
16
+ * candidate closes a cycle), so a cycle resolves locally: no global pass.
17
+ * The first build places every block the same way (their unique acyclic
18
+ * acceptance, whatever the order; the tests' greedy rebuild,
19
+ * `src/tests/oracles/placements.ts`, is what the self-checks compare). A
20
+ * placed block's order key is found from its sequence neighbours
21
+ * (`placement/keys.ts`), never by walking the parent's sequence; a rebuild
22
+ * keys every list once, in its sequence's order. The layout rules re-run
23
+ * only on the layouts a change reaches.
16
24
  */
17
- import { bySlot, childrenIndex, displaySlotOf, documentOrder, resolvePlacements, textRanker } from '../../placement/model.js';
25
+ import { bySlot, childrenIndex, displaySlotOf, documentOrder } from '../../placement/model.js';
26
+ import { denseKey, keyBetween } from '../../placement/keys.js';
27
+ import { NO_SLOT, byTail, candidatesOf, cycleThrough, edgeParentOf, collectSlots, homeOf, registryOwners, ownerOfNode, positionsOfItem, slotOwner, slotsBefore } from '../../placement/resolve.js';
28
+ import { cmpStamp, sameUnit } from '../../placement/slots.js';
29
+ import { Y } from '../../engine.js';
30
+ import { engineOps, firstItem } from '../../structs.js';
18
31
  import { DEAD, displayOf } from '../model.js';
19
- import { addTo, dropFrom } from './shared.js';
20
32
  /** Placement maintenance of one doc's index, over its state, claims, streams and layout rules. */
21
33
  export const indexPlacement = (ix) => {
22
- const { blocks, displaysMap, ownerChanged, streamIx, placed, placementsMap, regroup, byArgParent, following, dirtyLists, leftLists, placementSeeds, stateSeeds, kindsOf, ensureOwners, ownerOf, top, streamOf, streamsIn, streamAt, role, lineKind, itemKind, rowKind, rowOfTable, declaredRows, cellKind, cellRank, declaredItems, dissolve, redissolve } = ix;
34
+ const { doc, registry, blocks, displaysMap, ownerChanged, placementsMap, following, dirtyLists, leftLists, placementSeeds, stateSeeds, kindsOf, slotsByBlock, rawOrder, edges, fallen, rejected, ensureOwners, ownerOf, top, streamOf, streamsIn, streamAt, role, lineKind, itemKind, rowKind, rowOfTable, declaredRows, cellKind, cellRank, declaredItems, dissolve, redissolve } = ix;
35
+ const kept = engineOps(Y).isKeptReplaced;
23
36
  // ── placements and the children index (maintained) ────────────
24
- /** The blocks of `home`'s text, in text order (segment 0's first). */
25
- const rowBlocks = (home) => {
26
- const at = placed.get(home);
27
- if (at === undefined)
28
- return [];
29
- return at.head === null ? at.blocks : [at.head, ...at.blocks];
30
- };
31
- const ranker = textRanker(blocks, placementsMap, (b) => streamIx.get(b)?.home, rowBlocks);
32
- /** Resolved parent → the blocks placed under it. */
33
- const kidsOf = new Map();
34
37
  /** The document holds a layout or an item kind: `kids0` and `kidsMap` differ. */
35
38
  let layoutMode = false;
36
39
  /** The line kinds the roles declare, and those of the lines islands the document holds. */
37
40
  let lineKinds = new Set();
38
41
  let orderCache = null;
39
- /** Some block shows no argmax candidate (a cycle rejected one, or none): passes run whole. */
40
- let irregular = false;
41
42
  let layoutBlocks = 0;
42
43
  let itemBlocks = 0;
43
44
  /** Tables, rows and cells (`table.*`): their rules run in the layout pass. */
@@ -58,11 +59,11 @@ export const indexPlacement = (ix) => {
58
59
  },
59
60
  slotRank: (owner, id) => cellRank(owner, id),
60
61
  top,
62
+ claimIndex: (holder, m) => blocks.get(holder)?.claims.findIndex((c) => c.m === m) ?? -1,
61
63
  streamOf,
62
64
  streamsIn,
63
65
  streamAt,
64
- display: (b) => displayOf(b, blocks, ownShim),
65
- textRank: (id, parent, rank) => ranker.rank(id, parent, rank)
66
+ display: (b) => displayOf(b, blocks, ownShim)
66
67
  };
67
68
  /** Re-count `id`'s kind facts; a fact the roles never declared forces a full pass. */
68
69
  const noteKind = (id) => {
@@ -108,17 +109,6 @@ export const indexPlacement = (ix) => {
108
109
  if (layoutMode !== layoutBlocks + itemBlocks + tableBlocks > 0)
109
110
  ix.placementFull = true;
110
111
  };
111
- /** The argmax candidate's parent (a registry entry or the root), and its index entry. */
112
- const argParent = (rec) => rec?.cands[0]?.p;
113
- const noteCands = (id, before) => {
114
- const after = argParent(blocks.get(id));
115
- if (before === after)
116
- return;
117
- if (typeof before === 'string')
118
- dropFrom(byArgParent, before, id);
119
- if (typeof after === 'string')
120
- addTo(byArgParent, after, id);
121
- };
122
112
  /** The ownership the layout rules read: none of their decisions applied. */
123
113
  const own0 = {
124
114
  ...ownShim,
@@ -210,12 +200,12 @@ export const indexPlacement = (ix) => {
210
200
  if (out.has(x))
211
201
  continue;
212
202
  out.add(x);
213
- for (const c of kidsOf.get(x) ?? [])
214
- stack.push(c);
203
+ for (const c of rawOrder.get(x) ?? [])
204
+ stack.push(c.id);
215
205
  for (const d of displaysMap.get(x) ?? [])
216
206
  if (d !== x)
217
- for (const c of kidsOf.get(d) ?? [])
218
- stack.push(c);
207
+ for (const c of rawOrder.get(d) ?? [])
208
+ stack.push(c.id);
219
209
  }
220
210
  return out;
221
211
  };
@@ -231,48 +221,282 @@ export const indexPlacement = (ix) => {
231
221
  else
232
222
  following.delete(id);
233
223
  };
234
- /** The placement `resolvePlacements` gives `id` while every block shows its argmax. */
235
- const argmaxOf = (id) => {
236
- const rec = blocks.get(id);
237
- if (rec === undefined)
238
- return undefined;
239
- const c = rec.cands[0];
240
- if (c === undefined)
241
- return null;
242
- const p = c.p !== null && !blocks.has(c.p) ? null : c.p;
243
- return { parent: p, rank: c.r };
224
+ // ── edges, keys and acceptance ─────────────────────────────────
225
+ /**
226
+ * Whether the slot map has been read from the sequences: once, before the
227
+ * first rebuild (a shell settled on the first fold asks for a home), then
228
+ * the fold keeps it and every rebuild fills it again.
229
+ */
230
+ let slotsRead = false;
231
+ /** What the first read collected, for a rebuild while no sequence changed since (one scan). */
232
+ let collected = null;
233
+ let collectedAt = -1;
234
+ const readSlots = () => {
235
+ slotsRead = true;
236
+ slotsByBlock.clear();
237
+ // Every registry node, its kept incarnations too (the records may not all be built yet).
238
+ collected = collectSlots(doc, registryOwners(registry, kept));
239
+ collectedAt = ix.seqEpoch;
240
+ for (const [b, refs] of collected.slots)
241
+ slotsByBlock.set(b, refs);
244
242
  };
245
- /** A display edge walk from `id`'s parent reaches `id` (or loops): the argmax graph has a cycle. */
246
- const cyclic = (id) => {
247
- let steps = 0;
248
- for (let cur = placementsMap.get(id)?.parent ?? null; cur !== null;) {
249
- const o = ownerOf(cur);
250
- const at = o === DEAD ? cur : o;
251
- if (at === id || ++steps > blocks.size)
252
- return true;
253
- const cp = placementsMap.get(at);
254
- if (cp === undefined)
255
- return false;
256
- cur = cp.parent;
257
- }
258
- return false;
243
+ /** Put `ref` (`null`: none) where the slot map holds unit `u` of the slots naming id `b`. */
244
+ const putSlot = (b, u, ref) => {
245
+ const list = (slotsByBlock.get(b) ?? []).filter((x) => !sameUnit(x, u));
246
+ if (ref !== null)
247
+ list.push(ref);
248
+ if (list.length === 0)
249
+ slotsByBlock.delete(b);
250
+ else
251
+ slotsByBlock.set(b, list);
252
+ };
253
+ /** `id`'s home slot among the slots naming its registry id (`null`: none). */
254
+ const homeFor = (id) => {
255
+ if (!slotsRead)
256
+ readSlots();
257
+ return homeOf(registry, kept, slotsByBlock, id);
259
258
  };
259
+ /**
260
+ * Re-own the home slots of `node`'s sequence after the registry value it
261
+ * stands for changed (a concurrent creation of one id won or lost, its
262
+ * losing incarnation shown or not): each slot's parent is the node's owner
263
+ * now, and its block re-placed; a node that is no block of the document
264
+ * any more holds no slot (as a rebuild reads it).
265
+ */
266
+ const reslot = (node) => {
267
+ if (!slotsRead)
268
+ return; // the first read collects them as they are
269
+ const owner = ownerOfNode(registry, kept, node);
270
+ for (let it = firstItem(node); it !== null; it = it.right)
271
+ for (const { value, unit, via } of positionsOfItem(doc, it)) {
272
+ if (via !== null)
273
+ continue; // a record's unit is another sequence's slot
274
+ const b = value.b;
275
+ putSlot(b, unit, owner === undefined ? null : { parent: owner, ...unit });
276
+ for (const id of new Set([b, slotOwner(registry, kept, b, unit.c)])) {
277
+ const rec = blocks.get(id);
278
+ if (rec !== undefined)
279
+ rec.home = homeOf(registry, kept, slotsByBlock, id);
280
+ placementSeeds.add(id);
281
+ }
282
+ }
283
+ };
284
+ /** The slot items a rebuild collected (its homes' items, read once), while it places every block. */
285
+ let known = null;
286
+ /** `id`'s candidate edges, read from the engine: its live records, strongest first, then home (`[]`: no slot, or gone). */
287
+ const candidatesFor = (id) => {
288
+ const home = blocks.get(id)?.home ?? homeFor(id);
289
+ return home === null ? [] : candidatesOf(doc, registry, kept, home, known?.get(home));
290
+ };
291
+ /** The owner of the sequence `id`'s slot shows in as the engine stands (its mover's, else home's; `null`: the root). */
292
+ const edgeParent = (id) => {
293
+ const home = blocks.get(id)?.home ?? homeFor(id);
294
+ return home === null ? undefined : edgeParentOf(doc, registry, kept, home);
295
+ };
296
+ /** The raw children of `parent` in order (every block whose edge parent it is), kept sorted by key. */
297
+ const rawList = (parent) => {
298
+ let l = rawOrder.get(parent);
299
+ if (l === undefined)
300
+ rawOrder.set(parent, (l = []));
301
+ return l;
302
+ };
303
+ /** Counts the placement writes: a key's walk that saw one happen under it walks again. */
304
+ let placedEpoch = 0;
305
+ /** Whether a placement is keyed as it is decided: not while a rebuild places every block (it keys them after, in one pass). */
306
+ let keyed = true;
260
307
  const setPlacement = (id, pl) => {
308
+ ix.foldStats.placed++;
309
+ placedEpoch++;
261
310
  const old = placementsMap.get(id);
262
- if (old !== undefined)
263
- dropFrom(kidsOf, old.parent, id);
311
+ if (keyed && old !== undefined) {
312
+ const l = rawList(old.parent);
313
+ const at = seek(l, { id, rank: old.rank });
314
+ if (l[at]?.id === id)
315
+ l.splice(at, 1);
316
+ if (l.length === 0)
317
+ rawOrder.delete(old.parent);
318
+ }
264
319
  if (pl === undefined)
265
320
  placementsMap.delete(id);
266
321
  else {
267
322
  placementsMap.set(id, pl);
268
- addTo(kidsOf, pl.parent, id);
323
+ if (!keyed)
324
+ return;
325
+ const l = rawList(pl.parent);
326
+ const slot = { id, rank: pl.rank };
327
+ l.splice(seek(l, slot), 0, slot);
328
+ }
329
+ };
330
+ /**
331
+ * The key `id` takes under `edge.parent`: between the key of the nearest
332
+ * block shown where it stands before `id`'s place in the sequence (placed
333
+ * first when it is a pending seed; walked past when it shows elsewhere)
334
+ * and the next key of that list. Placing a pending neighbour can drop a
335
+ * block the walk already passed back into that stretch (a cycle's
336
+ * fallback, back where it stood): a walk under which a placement changed
337
+ * walks again, so the key it returns reads one state.
338
+ */
339
+ const keyFor = (id, edge, place) => {
340
+ for (;;) {
341
+ const before = placedEpoch;
342
+ const lrank = leftKey(id, edge, place);
343
+ if (placedEpoch !== before)
344
+ continue;
345
+ const list = rawOrder.get(edge.parent) ?? [];
346
+ const i = lrank === undefined ? 0 : seek(list, { id: '', rank: lrank }) + 1;
347
+ return keyBetween(lrank, list[i]?.rank);
348
+ }
349
+ };
350
+ /** The key of the nearest block shown before `id`'s place at `edge`, under its parent (`undefined`: none). */
351
+ const leftKey = (id, edge, place) => {
352
+ const home = blocks.get(id)?.home ?? homeFor(id);
353
+ for (const e of slotsBefore(doc, edge, home)) {
354
+ const b = slotOwner(registry, kept, e.value.b, e.unit.c);
355
+ // `id` itself (its place before this one) keys nothing.
356
+ if (b === id)
357
+ continue;
358
+ // A slot that is not its block's home (a second creation of one id) places nothing.
359
+ const h = blocks.get(b)?.home ?? homeFor(b);
360
+ if (h === null || !sameUnit(h, e.unit))
361
+ continue;
362
+ place(b);
363
+ const pl = placementsMap.get(b);
364
+ const shows = edges.get(b);
365
+ if (pl !== undefined &&
366
+ pl.parent === edge.parent &&
367
+ !rejected.has(b) &&
368
+ shows != null &&
369
+ shows.via === e.via)
370
+ return pl.rank;
371
+ }
372
+ return undefined;
373
+ };
374
+ /** The key of `id` at the root's tail, among the rejected by stamp then id, after the last top-level block. */
375
+ const tailKey = (id, stamp) => {
376
+ const tail = [...rejected]
377
+ .filter((x) => x !== id)
378
+ .map((x) => ({ id: x, stamp: edges.get(x)?.stamp ?? NO_SLOT }))
379
+ .sort(byTail);
380
+ const list = rawOrder.get(null) ?? [];
381
+ const me = { id, stamp };
382
+ let at = 0;
383
+ while (at < tail.length && byTail(tail[at], me) < 0)
384
+ at++;
385
+ const prev = at > 0
386
+ ? placementsMap.get(tail[at - 1].id)?.rank
387
+ : list[list.length - tail.length - 1]?.rank;
388
+ const next = at < tail.length ? placementsMap.get(tail[at].id)?.rank : undefined;
389
+ return keyBetween(prev, next);
390
+ };
391
+ /** Show `id` at the root's tail: every edge closes a cycle, or none. */
392
+ const reject = (id, edge) => {
393
+ edges.set(id, edge);
394
+ if (placementsMap.has(id))
395
+ setPlacement(id, undefined);
396
+ fallen.delete(id);
397
+ rejected.add(id);
398
+ const rank = keyed ? tailKey(id, edge?.stamp ?? NO_SLOT) : '';
399
+ setPlacement(id, { parent: null, rank });
400
+ };
401
+ /** The same display edge: the same sequence, the same record, the same stamp. */
402
+ const sameEdge = (a, b) => a.parent === b.parent && a.via === b.via && cmpStamp(a.stamp, b.stamp) === 0;
403
+ /** Whether `edge` (of `id`) is a place `id` may take now: a live parent, and no cycle it would be the oldest edge of. */
404
+ const admits = (id, edge) => {
405
+ const parent = edge.parent;
406
+ if (parent === undefined || (parent !== null && !blocks.has(parent)))
407
+ return { ok: false, drop: null };
408
+ const cycle = cycleThrough(placementsMap, ownerOf, id, parent);
409
+ if (cycle === null)
410
+ return { ok: true, drop: null };
411
+ let [min, minStamp] = [id, edge.stamp];
412
+ for (const m of cycle) {
413
+ const e = m === id ? edge : edges.get(m);
414
+ if (m !== id && e && cmpStamp(e.stamp, minStamp) < 0)
415
+ [min, minStamp] = [m, e.stamp];
416
+ }
417
+ return min === id ? { ok: false, drop: null } : { ok: true, drop: min };
418
+ };
419
+ /**
420
+ * Place `id` at its strongest candidate edge from `from` on that closes no
421
+ * cycle it would be the oldest edge of (the later move wins). When the
422
+ * edge closes a cycle through an older edge, that edge's block is dropped
423
+ * to its next candidate (back where it stood before that move), and so on
424
+ * down its records to home; a block every candidate of which fails shows
425
+ * at the root's tail. `place` places a pending neighbour first. Returns
426
+ * the blocks whose placement changed.
427
+ */
428
+ const settle = (id, place, from = 0) => {
429
+ const changed = [id];
430
+ const cands = candidatesFor(id);
431
+ for (let n = from; n < cands.length; n++) {
432
+ const edge = cands[n];
433
+ // The key first: its walk places the pending neighbours, so the cycle
434
+ // check reads them placed (a neighbour placed after it could close a
435
+ // cycle through `id` that no check saw).
436
+ const rank = keyed ? keyFor(id, edge, place) : '';
437
+ const { ok, drop } = admits(id, edge);
438
+ if (!ok)
439
+ continue;
440
+ edges.set(id, edge);
441
+ rejected.delete(id);
442
+ if (n > 0)
443
+ fallen.add(id);
444
+ else
445
+ fallen.delete(id);
446
+ if (placementsMap.has(id))
447
+ setPlacement(id, undefined);
448
+ setPlacement(id, { parent: edge.parent, rank });
449
+ if (drop !== null) {
450
+ const now = edges.get(drop);
451
+ const at = now ? candidatesFor(drop).findIndex((c) => sameEdge(c, now)) : -1;
452
+ changed.push(...settle(drop, () => { }, at + 1));
453
+ }
454
+ return changed;
455
+ }
456
+ reject(id, cands[0] ?? null);
457
+ return changed;
458
+ };
459
+ /** Whether a candidate stronger than `id`'s accepted edge would take it now. */
460
+ const canRise = (id) => {
461
+ const cands = candidatesFor(id);
462
+ const now = edges.get(id);
463
+ const at = rejected.has(id) || !now ? cands.length : cands.findIndex((c) => sameEdge(c, now));
464
+ for (let n = 0; n < (at < 0 ? cands.length : at); n++)
465
+ if (admits(id, cands[n]).ok)
466
+ return true;
467
+ return false;
468
+ };
469
+ /**
470
+ * Try every block below its strongest edge again (a changed edge may have
471
+ * broken its cycle, or made another the one to drop): those that rise join
472
+ * `moved`.
473
+ */
474
+ const retryFallen = (moved) => {
475
+ for (let round = 0; round < fallen.size + rejected.size + 2; round++) {
476
+ let changed = false;
477
+ const below = [...rejected, ...fallen]
478
+ .map((x) => ({ id: x, stamp: candidatesFor(x)[0]?.stamp ?? NO_SLOT }))
479
+ .sort((a, b) => -byTail(a, b));
480
+ for (const { id } of below) {
481
+ if (!canRise(id))
482
+ continue;
483
+ for (const x of settle(id, () => { }))
484
+ moved.add(x);
485
+ changed = true;
486
+ }
487
+ if (!changed)
488
+ break;
269
489
  }
270
490
  };
271
- /** Everything rebuilt from the records (the first build, roles, an irregular state). */
491
+ /**
492
+ * Everything rebuilt from the sequences (the first build, roles): every
493
+ * block placed as an edit places one (`settle`, then `retryFallen`) —
494
+ * the one acyclic acceptance, whatever the order the blocks come in —
495
+ * then keyed in one pass over each sequence's places (dense keys in its
496
+ * order), the root's tail after the last top-level block.
497
+ */
272
498
  const rebuildPlacements = () => {
273
499
  ix.placementFull = false;
274
- ranker.forget();
275
- regroup.clear();
276
500
  placementSeeds.clear();
277
501
  stateSeeds.clear();
278
502
  ownerChanged.clear();
@@ -299,32 +523,60 @@ export const indexPlacement = (ix) => {
299
523
  for (const line of lineCounts.keys())
300
524
  lineKinds.add(line);
301
525
  ix.placementFull = false;
302
- const resolved = resolvePlacements(blocks, ownerOf);
526
+ // The first read's slots while no sequence changed since (one scan).
527
+ const { slots, items, places } = collected !== null && collectedAt === ix.seqEpoch
528
+ ? collected
529
+ : collectSlots(doc, blocks.values());
530
+ collected = null;
531
+ slotsByBlock.clear();
532
+ for (const [b, refs] of slots)
533
+ slotsByBlock.set(b, refs);
534
+ slotsRead = true;
303
535
  placementsMap.clear();
304
- kidsOf.clear();
305
- irregular = false;
306
- for (const [id, pl] of resolved) {
307
- setPlacement(id, pl);
308
- const arg = argmaxOf(id);
309
- if (!arg || arg.parent !== pl.parent || arg.rank !== pl.rank)
310
- irregular = true;
311
- }
536
+ edges.clear();
537
+ rawOrder.clear();
538
+ fallen.clear();
539
+ rejected.clear();
540
+ [keyed, known] = [false, items];
541
+ for (const id of blocks.keys())
542
+ settle(id, () => { });
543
+ if (fallen.size + rejected.size > 0)
544
+ retryFallen(new Set());
545
+ [keyed, known] = [true, null];
546
+ // The lists in key order: a block where its edge shows it, in its sequence's order.
547
+ for (const [owner, list] of places)
548
+ for (const e of list) {
549
+ const b = slotOwner(registry, kept, e.value.b, e.unit.c);
550
+ const pl = placementsMap.get(b);
551
+ const h = blocks.get(b)?.home;
552
+ if (pl?.parent !== owner || rejected.has(b) || !h || !sameUnit(h, e.unit))
553
+ continue;
554
+ if (edges.get(b)?.via !== e.via)
555
+ continue;
556
+ const l = rawList(owner);
557
+ pl.rank = denseKey(l.length);
558
+ l.push({ id: b, rank: pl.rank });
559
+ }
560
+ // The root's tail, keyed as an edit keys a rejected block, in its order.
561
+ const tail = [...rejected].map((x) => ({ id: x, stamp: edges.get(x)?.stamp ?? NO_SLOT }));
562
+ rejected.clear();
563
+ for (const { id } of tail.sort(byTail))
564
+ reject(id, edges.get(id) ?? null);
312
565
  layoutMode = layoutBlocks + itemBlocks + tableBlocks > 0;
313
566
  ix.dissolved = new Set();
314
- const index = (own, map) => {
567
+ const index = (map) => {
315
568
  const at = new Map();
316
569
  for (const [parent, list] of map)
317
570
  for (const { id, rank, reset } of list)
318
571
  at.set(id, reset === undefined ? { parent, rank } : { parent, rank, reset });
319
- void own;
320
572
  return at;
321
573
  };
322
574
  ix.kids0 = childrenIndex(placementsMap, own0);
323
- ix.slots0 = index(own0, ix.kids0);
575
+ ix.slots0 = index(ix.kids0);
324
576
  if (layoutMode) {
325
577
  ix.dissolved = dissolve(ix.kids0);
326
578
  ix.kidsMap = childrenIndex(placementsMap, ownShim);
327
- ix.slots = index(ownShim, ix.kidsMap);
579
+ ix.slots = index(ix.kidsMap);
328
580
  }
329
581
  else
330
582
  [ix.kidsMap, ix.slots] = [ix.kids0, ix.slots0];
@@ -337,48 +589,61 @@ export const indexPlacement = (ix) => {
337
589
  };
338
590
  const ensurePlacements = () => {
339
591
  ensureOwners();
340
- if (ix.placementFull || irregular) {
341
- if (ix.placementFull || placementSeeds.size + stateSeeds.size + ownerChanged.size > 0)
342
- rebuildPlacements();
343
- return;
344
- }
345
- if (placementSeeds.size + stateSeeds.size + ownerChanged.size + regroup.size === 0)
592
+ if (ix.placementFull)
593
+ return rebuildPlacements();
594
+ if (placementSeeds.size + stateSeeds.size + ownerChanged.size === 0)
346
595
  return;
347
596
  const moved = new Set();
348
- for (const id of placementSeeds) {
349
- // A candidate change (a move, even to the same slot) re-decides its text's order.
350
- const home = streamIx.get(id)?.home;
351
- if (home !== undefined)
352
- regroup.add(home);
353
- const next = argmaxOf(id);
354
- if (next === null)
355
- return rebuildPlacements();
356
- const old = placementsMap.get(id);
357
- if (old?.parent === next?.parent && old?.rank === next?.rank)
358
- continue;
359
- setPlacement(id, next);
360
- moved.add(id);
361
- }
362
- // A changed display edge closing a cycle needs the global resolution.
363
- for (const id of moved)
364
- if (cyclic(id))
365
- return rebuildPlacements();
597
+ const seeds = new Set(placementSeeds);
598
+ const done = new Set();
599
+ /** Place one seed (its left neighbour first, when it is a seed too). */
600
+ const place = (id) => {
601
+ if (done.has(id) || !seeds.has(id))
602
+ return;
603
+ done.add(id);
604
+ if (!blocks.has(id)) {
605
+ if (placementsMap.has(id)) {
606
+ setPlacement(id, undefined);
607
+ edges.delete(id);
608
+ fallen.delete(id);
609
+ rejected.delete(id);
610
+ moved.add(id);
611
+ }
612
+ return;
613
+ }
614
+ const top = candidatesFor(id)[0] ?? null;
615
+ const old = edges.get(id);
616
+ // The same edge, placed at its strongest: its key still orders it (its neighbours' keys are theirs).
617
+ if (top !== null &&
618
+ old &&
619
+ !rejected.has(id) &&
620
+ !fallen.has(id) &&
621
+ placementsMap.has(id) &&
622
+ sameEdge(top, old))
623
+ return;
624
+ for (const x of settle(id, place))
625
+ moved.add(x);
626
+ };
627
+ for (const id of [...seeds])
628
+ place(id);
629
+ // A changed claim owner can close a cycle through a display edge that did not change.
366
630
  for (const o of ownerChanged)
367
- for (const c of kidsOf.get(o) ?? [])
368
- if (cyclic(c))
369
- return rebuildPlacements();
370
- const seeds = new Set([...moved, ...stateSeeds, ...ownerChanged]);
371
- // Every block of a text whose pieces' order may have changed re-reads its slot.
372
- for (const home of regroup)
373
- for (const b of ranker.regroup(home))
374
- if (placementsMap.has(b))
375
- seeds.add(b);
376
- regroup.clear();
631
+ for (const c of [...(rawOrder.get(o) ?? [])]) {
632
+ const edge = edges.get(c.id);
633
+ if (!edge || rejected.has(c.id) || edge.parent === undefined)
634
+ continue;
635
+ if (cycleThrough(placementsMap, ownerOf, c.id, edge.parent) !== null)
636
+ for (const x of settle(c.id, () => { }))
637
+ moved.add(x);
638
+ }
639
+ if (rejected.size + fallen.size > 0 && (moved.size > 0 || ownerChanged.size > 0))
640
+ retryFallen(moved);
641
+ const seeds2 = new Set([...moved, ...stateSeeds, ...ownerChanged]);
377
642
  const kinds = [...stateSeeds];
378
643
  placementSeeds.clear();
379
644
  stateSeeds.clear();
380
645
  ownerChanged.clear();
381
- const affected = reach(seeds);
646
+ const affected = reach(seeds2);
382
647
  let touched = affected;
383
648
  const changed = patch(ix.kids0, ix.slots0, own0, affected);
384
649
  let any = changed.size > 0;
@@ -395,6 +660,21 @@ export const indexPlacement = (ix) => {
395
660
  ix.kidsVersion++;
396
661
  }
397
662
  };
663
+ /**
664
+ * A plain block (the document's default kind) directly in a container
665
+ * whose item is a kind of its own that renders content (a list) shows
666
+ * as that item — the read-time side of the facade's `fitted`: a race
667
+ * (a peer's lift of an item another peer's outdent moves, a concurrent
668
+ * undo of a retype) or an explicit write never shows a bare paragraph
669
+ * in a list. Anywhere else it shows `plain`.
670
+ */
671
+ const itemOf = (under, plain) => {
672
+ const parent = typeOf(under);
673
+ if (!ix.roles.container(parent))
674
+ return plain;
675
+ const item = ix.roles.defaultChild(parent);
676
+ return ix.roles.rendersContent(item) ? item : plain;
677
+ };
398
678
  /**
399
679
  * The kind `id` displays as — THE shown-kind rule, read from its slot
400
680
  * and the role table. A block directly in an island declared `lines`
@@ -411,21 +691,6 @@ export const indexPlacement = (ix) => {
411
691
  * (`itemOf`). Any other shows its stored kind (a retype shows). Read from the stored kinds
412
692
  * at call time: a retype rebuilds no placement.
413
693
  */
414
- /**
415
- * A plain block (the document's default kind) directly in a container
416
- * whose item is a kind of its own that renders content (a list) shows
417
- * as that item — the read-time side of the facade's `fitted`: a race
418
- * (a peer's lift of an item another peer's outdent moves, a concurrent
419
- * undo of a retype) or an explicit write never shows a bare paragraph
420
- * in a list. Anywhere else it shows `plain`.
421
- */
422
- const itemOf = (under, plain) => {
423
- const parent = typeOf(under);
424
- if (!ix.roles.container(parent))
425
- return plain;
426
- const item = ix.roles.defaultChild(parent);
427
- return ix.roles.rendersContent(item) ? item : plain;
428
- };
429
694
  const typeOf = (id) => {
430
695
  const stored = blocks.get(id)?.type ?? 'unknown';
431
696
  const slot = ix.slots.get(id);
@@ -461,14 +726,15 @@ export const indexPlacement = (ix) => {
461
726
  /** The document order, cached until a child list changes. */
462
727
  const order = () => (orderCache ??= documentOrder(ix.kidsMap));
463
728
  return {
464
- ranker,
465
729
  ownShim,
466
730
  own0,
467
731
  noteKind,
468
- argParent,
469
- noteCands,
732
+ homeFor,
733
+ putSlot,
734
+ edgeParent,
470
735
  noteFollowing,
471
736
  ensurePlacements,
737
+ reslot,
472
738
  typeOf,
473
739
  order
474
740
  };