@voithos-labs/aragonite 0.10.2 → 0.10.3

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 (255) hide show
  1. package/README.md +6 -21
  2. package/THIRD-PARTY-NOTICES.md +25 -0
  3. package/dist/a11y-strings.d.ts +18 -0
  4. package/dist/a11y-strings.js +18 -0
  5. package/dist/action-contracts.d.ts +7 -1
  6. package/dist/ambient/ambient-dom.js +5 -1
  7. package/dist/block-component.d.ts +14 -0
  8. package/dist/components/BlockDragHandle.svelte +35 -24
  9. package/dist/components/BlockHost.svelte +16 -9
  10. package/dist/components/Editor.svelte +381 -198
  11. package/dist/components/Editor.svelte.d.ts +1 -1
  12. package/dist/components/SelectionOverlay.svelte +17 -3
  13. package/dist/components/TailInsert.svelte +107 -0
  14. package/dist/components/TailInsert.svelte.d.ts +17 -0
  15. package/dist/components/block-content-selector.d.ts +6 -2
  16. package/dist/components/block-content-selector.js +6 -2
  17. package/dist/components/blocks/ThematicBreakBlock.svelte +19 -6
  18. package/dist/components/blocks/ThematicBreakBlock.svelte.d.ts +1 -0
  19. package/dist/components/blocks/code/CodeBlock.svelte +211 -30
  20. package/dist/components/blocks/code/CodeBlockRail.svelte +686 -0
  21. package/dist/components/blocks/code/CodeBlockRail.svelte.d.ts +26 -0
  22. package/dist/components/blocks/code/code-bootstrap.js +4 -0
  23. package/dist/components/blocks/code/code-context-actions.d.ts +1 -0
  24. package/dist/components/blocks/code/code-context-actions.js +24 -0
  25. package/dist/components/blocks/code/code-fence-exit.d.ts +15 -0
  26. package/dist/components/blocks/code/code-fence-exit.js +26 -0
  27. package/dist/components/blocks/code/code-languages.d.ts +6 -0
  28. package/dist/components/blocks/code/code-languages.js +11 -0
  29. package/dist/components/blocks/code/code-renderer.js +11 -0
  30. package/dist/components/blocks/directive/DirectiveContainerBlock.svelte +1 -1
  31. package/dist/components/blocks/editable-leaf.d.ts +37 -6
  32. package/dist/components/blocks/editable-leaf.js +243 -29
  33. package/dist/components/blocks/editable-surface.d.ts +9 -0
  34. package/dist/components/blocks/editable-surface.js +22 -3
  35. package/dist/components/blocks/list/ListItemBlock.svelte +3 -3
  36. package/dist/components/blocks/list/task-checkbox.d.ts +2 -0
  37. package/dist/components/blocks/list/task-checkbox.js +11 -2
  38. package/dist/components/blocks/surface-wiring.svelte.d.ts +4 -0
  39. package/dist/components/blocks/surface-wiring.svelte.js +8 -1
  40. package/dist/components/blocks/table/TableActionMenu.svelte +210 -86
  41. package/dist/components/blocks/table/TableActionMenu.svelte.d.ts +5 -0
  42. package/dist/components/blocks/table/TableBlock.svelte +205 -186
  43. package/dist/components/blocks/table/TableBlock.svelte.d.ts +1 -0
  44. package/dist/components/blocks/table/TableCellBlock.svelte +87 -22
  45. package/dist/components/blocks/table/TableRowBlock.svelte +4 -18
  46. package/dist/components/blocks/table/TableRowBlock.svelte.d.ts +0 -5
  47. package/dist/components/blocks/table/cell-clipboard.d.ts +10 -0
  48. package/dist/components/blocks/table/cell-clipboard.js +34 -1
  49. package/dist/components/blocks/table/cell-keydown-plan.d.ts +1 -1
  50. package/dist/components/blocks/table/cell-keydown-plan.js +3 -1
  51. package/dist/components/blocks/table/table-cell-paste.js +2 -1
  52. package/dist/components/blocks/table/table-menu-model.d.ts +35 -8
  53. package/dist/components/blocks/table/table-menu-model.js +36 -17
  54. package/dist/components/blocks/text/TextEditableBlock.svelte +58 -11
  55. package/dist/components/blocks/text/delimiter-autopair.d.ts +71 -0
  56. package/dist/components/blocks/text/delimiter-autopair.js +216 -0
  57. package/dist/components/blocks/text/edge-policy-dispatch.d.ts +4 -0
  58. package/dist/components/blocks/text/edge-policy-dispatch.js +56 -2
  59. package/dist/components/blocks/text/live-selection-edit.js +27 -0
  60. package/dist/components/blocks/text/text-keydown.d.ts +7 -1
  61. package/dist/components/blocks/text/text-keydown.js +11 -1
  62. package/dist/components/blocks/text/text-render.d.ts +1 -1
  63. package/dist/components/blocks/text/text-render.js +3 -1
  64. package/dist/components/blocks/text/widget-interaction.d.ts +3 -0
  65. package/dist/components/blocks/text/widget-interaction.js +144 -22
  66. package/dist/components/drag-handle.d.ts +35 -0
  67. package/dist/components/drag-handle.js +126 -0
  68. package/dist/components/editor-root-focus.d.ts +19 -0
  69. package/dist/components/editor-root-focus.js +67 -0
  70. package/dist/components/editor-root-geometry.d.ts +39 -0
  71. package/dist/components/editor-root-geometry.js +91 -0
  72. package/dist/components/editor-root-keydown.d.ts +1 -1
  73. package/dist/components/editor-root-keydown.js +12 -3
  74. package/dist/components/editor-root-listeners.d.ts +10 -6
  75. package/dist/components/editor-root-listeners.js +23 -22
  76. package/dist/components/editor-root-mode-flip.d.ts +36 -0
  77. package/dist/components/editor-root-mode-flip.js +92 -0
  78. package/dist/components/image/ImageOverlayHost.svelte +14 -6
  79. package/dist/components/image/ImageProperties.svelte +512 -70
  80. package/dist/components/image/ImageProperties.svelte.d.ts +6 -1
  81. package/dist/components/image/ImageResizeHandles.svelte +59 -34
  82. package/dist/components/image/image-crop.d.ts +39 -0
  83. package/dist/components/image/image-crop.js +74 -0
  84. package/dist/components/image/image-edit-commit.d.ts +1 -0
  85. package/dist/components/image/image-edit-commit.js +21 -5
  86. package/dist/components/image/image-source-bytes.js +10 -3
  87. package/dist/components/image/image-widget-editing.js +1 -0
  88. package/dist/components/image/widget-dom.js +5 -1
  89. package/dist/components/link-card/link-card-commit.js +1 -1
  90. package/dist/components/lrd-map-gate.js +1 -1
  91. package/dist/components/menu/BlockMenu.svelte +315 -0
  92. package/dist/components/menu/BlockMenu.svelte.d.ts +34 -0
  93. package/dist/components/menu/MenuIcon.svelte +153 -0
  94. package/dist/components/menu/MenuIcon.svelte.d.ts +51 -0
  95. package/dist/components/menu/clipboard-actions.d.ts +12 -0
  96. package/dist/components/menu/clipboard-actions.js +42 -0
  97. package/dist/components/menu/default-context-actions.d.ts +15 -0
  98. package/dist/components/menu/default-context-actions.js +76 -0
  99. package/dist/components/menu/flyout-placement.d.ts +6 -0
  100. package/dist/components/menu/flyout-placement.js +25 -0
  101. package/dist/core/inline/format-toggle.d.ts +12 -4
  102. package/dist/core/inline/format-toggle.js +94 -40
  103. package/dist/core/inline/image-dimensions.d.ts +3 -0
  104. package/dist/core/inline/image-dimensions.js +46 -10
  105. package/dist/core/inline/inline-widgets.d.ts +11 -0
  106. package/dist/core/inline/scan/brackets.js +1 -0
  107. package/dist/core/inline/scan/plugin-syntax.d.ts +8 -0
  108. package/dist/core/inline/scan/plugin-syntax.js +15 -1
  109. package/dist/core/inline-render.d.ts +6 -0
  110. package/dist/core/inline-render.js +32 -0
  111. package/dist/core/nodes.d.ts +14 -0
  112. package/dist/cursor/edge-affinity.js +2 -1
  113. package/dist/cursor/overlay-remeasure.js +8 -0
  114. package/dist/cursor/reveal-source.js +7 -2
  115. package/dist/cursor/widget-offset.d.ts +6 -0
  116. package/dist/cursor/widget-offset.js +61 -4
  117. package/dist/debug/interaction-trace.d.ts +4 -0
  118. package/dist/debug/interaction-trace.js +15 -0
  119. package/dist/decorations/decoration-state.svelte.js +1 -1
  120. package/dist/editor-actions/ancestry-folds.d.ts +2 -2
  121. package/dist/editor-actions/ancestry-folds.js +1 -1
  122. package/dist/editor-actions/block-edit-scope.js +1 -1
  123. package/dist/editor-actions/commit/text-batch.d.ts +3 -2
  124. package/dist/editor-actions/commit/text-batch.js +1 -1
  125. package/dist/editor-actions/commit/undo-controller.js +4 -2
  126. package/dist/editor-actions/container-edit.js +2 -1
  127. package/dist/editor-actions/enter-completion.d.ts +2 -0
  128. package/dist/editor-actions/enter-completion.js +23 -2
  129. package/dist/editor-actions/inline-range-commit.js +1 -1
  130. package/dist/editor-actions/reorder-action.js +19 -10
  131. package/dist/editor-actions/reorder-drag.js +29 -1
  132. package/dist/editor-actions/replacement-focus.d.ts +1 -1
  133. package/dist/editor-actions/replacement-focus.js +1 -1
  134. package/dist/editor-actions/search-replace.js +1 -1
  135. package/dist/editor-actions/table-context.d.ts +4 -1
  136. package/dist/editor-actions/table-context.js +57 -1
  137. package/dist/editor-events.d.ts +3 -0
  138. package/dist/editor-keys.d.ts +33 -0
  139. package/dist/editor-props.d.ts +21 -12
  140. package/dist/index.d.ts +1 -1
  141. package/dist/plugin.d.ts +6 -0
  142. package/dist/plugin.js +11 -0
  143. package/dist/plugins/latex/BlockMath.svelte +264 -29
  144. package/dist/plugins/latex/BlockMath.svelte.d.ts +2 -0
  145. package/dist/plugins/latex/index.d.ts +2 -1
  146. package/dist/plugins/latex/latex-kind.js +36 -3
  147. package/dist/plugins/latex/math-completion.js +4 -1
  148. package/dist/plugins/latex/math-layout.d.ts +15 -0
  149. package/dist/plugins/latex/math-layout.js +13 -0
  150. package/dist/plugins/latex/math-source.d.ts +19 -0
  151. package/dist/plugins/latex/math-source.js +97 -0
  152. package/dist/plugins/latex/register.d.ts +11 -2
  153. package/dist/plugins/latex/register.js +3 -1
  154. package/dist/plugins/latex/renderer.d.ts +3 -3
  155. package/dist/plugins/latex/renderer.js +13 -6
  156. package/dist/reactivity/list-windowing.svelte.d.ts +8 -8
  157. package/dist/reactivity/list-windowing.svelte.js +49 -24
  158. package/dist/schema/block-completions.d.ts +8 -0
  159. package/dist/schema/block-completions.js +11 -0
  160. package/dist/schema/context-actions.d.ts +31 -0
  161. package/dist/schema/context-actions.js +23 -0
  162. package/dist/schema/fenced-code-raw.js +31 -1
  163. package/dist/schema/operations.d.ts +8 -1
  164. package/dist/schema/reserved-chords.js +25 -4
  165. package/dist/schema/table-cell-raw.d.ts +1 -1
  166. package/dist/schema/table-cell-raw.js +1 -1
  167. package/dist/selection/block-hit-test.js +3 -2
  168. package/dist/selection/char-endpoint-snap.js +1 -1
  169. package/dist/selection/clipboard-text.js +6 -1
  170. package/dist/selection/covered-block.d.ts +10 -0
  171. package/dist/selection/covered-block.js +24 -0
  172. package/dist/selection/cross-block/dispatch.d.ts +3 -0
  173. package/dist/selection/cross-block/dispatch.js +13 -1
  174. package/dist/selection/cross-block/format-range.d.ts +1 -1
  175. package/dist/selection/cross-block/format-range.js +4 -15
  176. package/dist/selection/cross-block/format-toggle.js +1 -1
  177. package/dist/selection/cross-block/keydown.js +1 -1
  178. package/dist/selection/cross-block/ops.js +1 -1
  179. package/dist/selection/cross-block/paste.js +32 -30
  180. package/dist/selection/cross-block/type-replace.d.ts +3 -2
  181. package/dist/selection/cross-block/type-replace.js +62 -13
  182. package/dist/selection/dead-space-caret.d.ts +10 -0
  183. package/dist/selection/dead-space-caret.js +47 -1
  184. package/dist/selection/double-click-trim.d.ts +17 -0
  185. package/dist/selection/double-click-trim.js +57 -0
  186. package/dist/selection/drag-pointer.d.ts +7 -2
  187. package/dist/selection/drag-pointer.js +61 -2
  188. package/dist/selection/gap-caret.js +1 -1
  189. package/dist/selection/keyboard-extend.js +1 -1
  190. package/dist/selection/path-lookup.js +1 -1
  191. package/dist/selection/range-delete-ceremony.js +4 -2
  192. package/dist/selection/range-delete-chrome.js +2 -1
  193. package/dist/selection/range-delete-table-coverage.js +2 -1
  194. package/dist/selection/range-delete-table.js +3 -2
  195. package/dist/selection/range-delete.js +30 -2
  196. package/dist/selection/selection-restore.js +1 -1
  197. package/dist/selection/selection-state.svelte.d.ts +6 -0
  198. package/dist/selection/selection-state.svelte.js +36 -1
  199. package/dist/selection/table-endpoint-snap.js +1 -1
  200. package/dist/selection/table-rect-extend.js +1 -1
  201. package/dist/styles/editor-theme.css +57 -28
  202. package/dist/styles/editor.css +217 -18
  203. package/dist/testing/container-conformance.js +2 -2
  204. package/dist/testing/inline-conformance.js +2 -1
  205. package/dist/tree-operations/blockquote.js +1 -1
  206. package/dist/tree-operations/chain-rebuild.d.ts +63 -0
  207. package/dist/tree-operations/chain-rebuild.js +142 -0
  208. package/dist/tree-operations/children.d.ts +1 -1
  209. package/dist/tree-operations/children.js +1 -1
  210. package/dist/tree-operations/cleanup.js +1 -1
  211. package/dist/tree-operations/content-write.d.ts +50 -0
  212. package/dist/tree-operations/content-write.js +263 -0
  213. package/dist/tree-operations/index.d.ts +8 -3
  214. package/dist/tree-operations/index.js +6 -2
  215. package/dist/tree-operations/list/exit-replacement.js +1 -1
  216. package/dist/tree-operations/list/unwrap-merge.js +3 -3
  217. package/dist/tree-operations/node-ops.d.ts +17 -234
  218. package/dist/tree-operations/node-ops.js +47 -1113
  219. package/dist/tree-operations/node-primitives.d.ts +75 -0
  220. package/dist/tree-operations/node-primitives.js +117 -0
  221. package/dist/tree-operations/paste/apply.js +1 -1
  222. package/dist/tree-operations/paste/body-write.d.ts +1 -1
  223. package/dist/tree-operations/paste/body-write.js +2 -2
  224. package/dist/tree-operations/paste/container-match.js +4 -2
  225. package/dist/tree-operations/paste/dispatch.js +2 -1
  226. package/dist/tree-operations/paste/find-enclosing-list.js +1 -1
  227. package/dist/tree-operations/paste/focus-target.d.ts +1 -1
  228. package/dist/tree-operations/paste/list-absorb.js +1 -1
  229. package/dist/tree-operations/paste/list-break-out.js +1 -1
  230. package/dist/tree-operations/paste/parent-scope.js +1 -1
  231. package/dist/tree-operations/paste/paste-replacement.js +1 -1
  232. package/dist/tree-operations/paste/replace-block-at-parent.js +1 -1
  233. package/dist/tree-operations/path-mutate.d.ts +1 -1
  234. package/dist/tree-operations/path-mutate.js +2 -1
  235. package/dist/tree-operations/reorder-unit.js +1 -1
  236. package/dist/tree-operations/reorder.d.ts +5 -2
  237. package/dist/tree-operations/reorder.js +55 -2
  238. package/dist/tree-operations/settle.d.ts +105 -0
  239. package/dist/tree-operations/settle.js +660 -0
  240. package/dist/tree-operations/table-grid-clipboard.d.ts +21 -0
  241. package/dist/tree-operations/table-grid-clipboard.js +90 -0
  242. package/dist/tree-operations/unshare.d.ts +15 -77
  243. package/dist/tree-operations/unshare.js +15 -166
  244. package/docs/guide/consumer-guide.md +126 -96
  245. package/docs/guide/plugin-api.md +31 -3
  246. package/docs/guide/plugin-guide.md +26 -3
  247. package/package.json +4 -2
  248. package/dist/components/blocks/code/CodeLanguageChip.svelte +0 -127
  249. package/dist/components/blocks/code/CodeLanguageChip.svelte.d.ts +0 -14
  250. package/dist/components/blocks/table/TableGrip.svelte +0 -91
  251. package/dist/components/blocks/table/TableGrip.svelte.d.ts +0 -8
  252. package/dist/components/blocks/table/table-drop-target.d.ts +0 -1
  253. package/dist/components/blocks/table/table-drop-target.js +0 -16
  254. package/dist/components/blocks/table/table-reorder-drag.d.ts +0 -78
  255. package/dist/components/blocks/table/table-reorder-drag.js +0 -97
@@ -0,0 +1,90 @@
1
+ /**
2
+ * The grid a clipboard payload holds, for a spreadsheet-like paste into a table: tab-separated
3
+ * rows (what Excel and Sheets write to text/plain) or a GFM table (what this editor's own
4
+ * rectangle copy writes). Anything else is not a grid and takes the ordinary paste route. The
5
+ * inverse, an HTML table for the spreadsheets that read text/html, lives here too.
6
+ */
7
+ /** Rows of cell texts, rectangular: every row padded to the widest. Null for a non-grid payload. */
8
+ export function parseClipboardGrid(text) {
9
+ const lines = text.replace(/\r\n?/g, '\n').split('\n');
10
+ while (lines.length && lines[lines.length - 1].trim() === '')
11
+ lines.pop();
12
+ if (lines.length === 0)
13
+ return null;
14
+ const rows = parseGfmRows(lines) ?? parseTsvRows(lines);
15
+ if (!rows || rows.length === 0)
16
+ return null;
17
+ let width = 0;
18
+ for (const row of rows)
19
+ width = Math.max(width, row.length);
20
+ if (width < 2 && rows.length < 2)
21
+ return null;
22
+ return rows.map((row) => [...row, ...Array(width - row.length).fill('')]);
23
+ }
24
+ // Every line a pipe row; the delimiter line (second, all dashes and colons) is dropped.
25
+ function parseGfmRows(lines) {
26
+ if (!lines.every((line) => /^\s*\|.*\|\s*$/.test(line)))
27
+ return null;
28
+ const rows = lines.map(splitPipeRow);
29
+ if (rows.length >= 2 && rows[1].every((cell) => /^:?-+:?$/.test(cell)))
30
+ rows.splice(1, 1);
31
+ return rows;
32
+ }
33
+ function splitPipeRow(line) {
34
+ const inner = line.trim().slice(1, -1);
35
+ const cells = [];
36
+ let cell = '';
37
+ for (let i = 0; i < inner.length; i++) {
38
+ const ch = inner[i];
39
+ if (ch === '\\' && inner[i + 1] === '|') {
40
+ cell += '|';
41
+ i++;
42
+ }
43
+ else if (ch === '|') {
44
+ cells.push(cell.trim());
45
+ cell = '';
46
+ }
47
+ else
48
+ cell += ch;
49
+ }
50
+ cells.push(cell.trim());
51
+ return cells;
52
+ }
53
+ function parseTsvRows(lines) {
54
+ if (!lines.some((line) => line.includes('\t')))
55
+ return null;
56
+ return lines.map((line) => line.split('\t'));
57
+ }
58
+ /** A rectangle's cell texts, pipes unescaped, as the clipboard's grid. */
59
+ export function rectangleGrid(table, a, b) {
60
+ const rows = table.children ?? [];
61
+ const grid = [];
62
+ for (let r = Math.min(a.rowIdx, b.rowIdx); r <= Math.max(a.rowIdx, b.rowIdx); r++) {
63
+ const cells = rows[r]?.children ?? [];
64
+ const line = [];
65
+ for (let c = Math.min(a.colIdx, b.colIdx); c <= Math.max(a.colIdx, b.colIdx); c++) {
66
+ line.push((cells[c]?.raw ?? '').replace(/\\\|/g, '|'));
67
+ }
68
+ grid.push(line);
69
+ }
70
+ return grid;
71
+ }
72
+ /** The grid repeated to fill a selection whose sides are multiples of it (a spreadsheet's
73
+ * tiling); any other selection takes the grid once from its top-left corner. */
74
+ export function tileGridTo(grid, rows, cols) {
75
+ const height = grid.length;
76
+ const width = grid[0]?.length ?? 0;
77
+ if (height === 0 || width === 0)
78
+ return grid;
79
+ if (rows % height !== 0 || cols % width !== 0 || (rows === height && cols === width)) {
80
+ return grid;
81
+ }
82
+ return Array.from({ length: rows }, (_, r) => Array.from({ length: cols }, (_, c) => grid[r % height][c % width]));
83
+ }
84
+ export function gridToHtmlTable(grid) {
85
+ const escape = (text) => text.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;');
86
+ const rows = grid
87
+ .map((row) => `<tr>${row.map((cell) => `<td>${escape(cell)}</td>`).join('')}</tr>`)
88
+ .join('');
89
+ return `<table>${rows}</table>`;
90
+ }
@@ -8,94 +8,32 @@
8
8
  import type { CstNode } from '../core/nodes';
9
9
  import type { NodeParentView, NodeView } from '../core/node-views';
10
10
  import type { SharingState } from './sharing';
11
- import type { NodeParent, TrackedPosition } from './node-ops';
12
- import type { StructuralChange } from './structural-change';
13
- import { type ChildRawChange } from '../schema/child-spans';
14
- import type { GrammarView } from '../schema/block-openers';
11
+ import type { NodeParent } from './node-primitives';
12
+ import type { ChildRawChange } from '../schema/child-spans';
15
13
  /**
16
- * Unshare every node along `path` from `root`; returns the chain outermost-first.
17
- * The caller owns `root.children` (live document, or a commit ceremony's array copy),
18
- * which is what makes the splice safe.
14
+ * The copy-on-write spine walk, returning the owned chain outermost-first. `assertInRange`
15
+ * fires G1.22 for the strict `ensureUnsharedPath` caller and stays silent for tolerant rebuild
16
+ * passes, which legitimately hand short paths; the walk stops at the first gap either way.
19
17
  */
20
- export declare function ensureUnsharedPath(root: NodeParentView, path: number[], sharing: SharingState): CstNode[];
18
+ export declare function walkUnsharing(root: NodeParentView, path: number[], sharing: SharingState, assertInRange: boolean): CstNode[];
21
19
  /**
22
- * Unshare one direct child of an already-unshared parent — a node, or a
23
- * caller-owned `{ children }` view (e.g. a commit ceremony's array copy).
20
+ * Unshare every node along `path` from `root`; returns the chain outermost-first. The caller
21
+ * owns `root.children` (live document, or a commit ceremony's array copy).
24
22
  */
23
+ export declare function ensureUnsharedPath(root: NodeParentView, path: number[], sharing: SharingState): CstNode[];
24
+ /** Unshare one direct child of an already-unshared parent, or of a caller-owned `{ children }`. */
25
25
  export declare function ensureUnsharedChild(parent: CstNode | NodeParent, index: number, sharing: SharingState): CstNode;
26
26
  /**
27
- * Standalone copy for a node being MOVED out of a parent the snapshot keeps: the caller
28
- * attaches the returned copy, the original stays in the old parent untouched. An
29
- * unshared input passes through — unshared already means live-tree-owned.
27
+ * Standalone copy for a node being MOVED out of a parent the snapshot keeps: the caller attaches
28
+ * the copy, the original stays put. An unshared input passes through as live-tree-owned.
30
29
  */
31
30
  export declare function ensureUnsharedNode(node: NodeView, sharing: SharingState): CstNode;
32
31
  /** Unshare every direct child of an owned parent (e.g. table rows before a whole-table rebuild). */
33
32
  export declare function ensureUnsharedChildren(parent: CstNode, sharing: SharingState): void;
34
- /**
35
- * Deep-unshare an owned node's subtree. Intended for small bounded subtrees
36
- * (tables: rows + cells) ahead of ops that write at arbitrary depth.
37
- */
33
+ /** Deep-unshare an owned node's subtree, for small bounded subtrees written at arbitrary depth. */
38
34
  export declare function ensureUnsharedSubtree(node: CstNode, sharing: SharingState): void;
39
35
  /**
40
- * Rebuild one owned container's raw. A grid rebuild rewrites its children's raw, so a
41
- * grid's children are unshared first — keyed off `containerContract`, not a `table` kind
42
- * test, or a plugin grid writes through shared children.
36
+ * Rebuild one owned container's raw. A grid rebuild rewrites its children's raw, so a grid's
37
+ * children are unshared first, keyed off `containerContract` rather than a `table` kind test.
43
38
  */
44
39
  export declare function rebuildOwnedContainer(node: CstNode, sharing: SharingState, changed?: ChildRawChange): void;
45
- /**
46
- * Longest prefix of `chain` still attached under `root`, identity-checked level by level.
47
- * A commit mutation can splice a node out mid-ceremony; rebuilding the detached node's
48
- * raw against its emptied children writes `raw: ''` and trips the commit-time staleness
49
- * check. Ancestors above the detachment still need their rebuild — hence prefix.
50
- */
51
- export declare function attachedChainPrefix(root: NodeParent, chain: CstNode[]): CstNode[];
52
- /**
53
- * One container slot a rebuild re-kinded. `previous` is the rollback register: a commit
54
- * unwinding after the swap has already published `replacement` into a live children
55
- * array, which no other rollback register reaches.
56
- */
57
- export interface ContainerReclassification {
58
- siblings: CstNode[];
59
- index: number;
60
- previous: CstNode;
61
- replacement: CstNode;
62
- }
63
- /**
64
- * A fold the rebuilt container's own slot owed: its bytes stopped interrupting a neighbour, so
65
- * the parent's array reloads as fewer blocks and no scope-local settle reaches that join
66
- * `before` is the pre-splice array — the rollback register, since the splice lands in
67
- * an array no commit descriptor covers. `landing` is where the container's first byte ended up.
68
- */
69
- export interface AncestrySeamFold {
70
- /** Chain level of the folded container, so a caller composes the owner's path from its own. */
71
- depth: number;
72
- siblings: CstNode[];
73
- /** The chain node owning `siblings`, or null when they are the rebuild root's children. */
74
- owner: CstNode | null;
75
- change: StructuralChange;
76
- before: CstNode[];
77
- landing: TrackedPosition;
78
- }
79
- /**
80
- * What the typing door knows and a bare chain does not: where the chain sits in the document,
81
- * and the bytes its leaf carried before the write. Both are guesses the rebuild identity-checks.
82
- */
83
- export interface ChainWriteHint {
84
- path: number[];
85
- leafPreviousRaw: string;
86
- }
87
- /**
88
- * Rebuild raws along an owned spine chain innermost-first, re-deriving each container's kind and
89
- * settling the seams at its own slot; chain- rather than path-based so it survives index shifts.
90
- * Both passes gate on a boundary line of the rebuilt raw moving; the re-derive additionally needs
91
- * `lineOpensAs` not to name the current kind, a positive identification so a declining opener
92
- * parses rather than eliding a real kind change. `folds` is required-nullable: a fold splices the
93
- * PARENT's array, so only a caller that reconciles that scope's ids/refs passes a sink.
94
- */
95
- export declare function rebuildUnsharedChain(root: NodeParent | CstNode, chain: CstNode[], sharing: SharingState, folds: AncestrySeamFold[] | null, grammar: GrammarView | undefined, hint?: ChainWriteHint): ContainerReclassification[];
96
- /**
97
- * Unshare the spine to `path` and rebuild it innermost-first, tolerating paths that ran
98
- * out of range mid-walk (post-delete rebuild passes). Prefer `rebuildUnsharedChain` when
99
- * indices may have shifted since the unshare.
100
- */
101
- export declare function rebuildUnsharedAncestry(root: NodeParent, path: number[], sharing: SharingState, folds: AncestrySeamFold[] | null, grammar: GrammarView | undefined): ContainerReclassification[];
@@ -1,13 +1,8 @@
1
1
  import { assertInvariant } from '../assert';
2
2
  import { checkCloneSafeMetadata } from '../invariants/node-shape';
3
3
  import { rebuildContainerRawIfContainer } from '../schema/container-raw';
4
- import { dropChildSpans } from '../schema/child-spans';
5
4
  import { getBlockKindDescriptor } from '../schema/block-kind-descriptor';
6
- import { trimTrailingLineEnding } from '../core/lines';
7
- import { perfEnabled, recordRebuildDepth } from '../perf/instruments';
8
5
  import { cloneMetadata } from './clone';
9
- import { absorbWindowSeams, lineOpensAs, reclassifyContainer } from './node-ops';
10
- import { settleSublistSeparator } from './list/sublist-separator';
11
6
  function copyNode(node, sharing) {
12
7
  const copy = { ...node };
13
8
  if (node.children)
@@ -25,12 +20,11 @@ function copyNode(node, sharing) {
25
20
  return copy;
26
21
  }
27
22
  /**
28
- * The copy-on-write spine walk, returning the owned chain outermost-first.
29
- * `assertInRange` fires G1.22 for the strict `ensureUnsharedPath` caller and stays
30
- * silent for tolerant rebuild passes, which legitimately hand short paths; the walk
31
- * stops at the first gap either way.
23
+ * The copy-on-write spine walk, returning the owned chain outermost-first. `assertInRange`
24
+ * fires G1.22 for the strict `ensureUnsharedPath` caller and stays silent for tolerant rebuild
25
+ * passes, which legitimately hand short paths; the walk stops at the first gap either way.
32
26
  */
33
- function walkUnsharing(root, path, sharing, assertInRange) {
27
+ export function walkUnsharing(root, path, sharing, assertInRange) {
34
28
  const chain = [];
35
29
  // Root is the live document or a ceremony-owned array — writable by contract (file header).
36
30
  let parentChildren = root.children;
@@ -52,21 +46,17 @@ function walkUnsharing(root, path, sharing, assertInRange) {
52
46
  return chain;
53
47
  }
54
48
  /**
55
- * Unshare every node along `path` from `root`; returns the chain outermost-first.
56
- * The caller owns `root.children` (live document, or a commit ceremony's array copy),
57
- * which is what makes the splice safe.
49
+ * Unshare every node along `path` from `root`; returns the chain outermost-first. The caller
50
+ * owns `root.children` (live document, or a commit ceremony's array copy).
58
51
  */
59
52
  export function ensureUnsharedPath(root, path, sharing) {
60
53
  return walkUnsharing(root, path, sharing, true);
61
54
  }
62
- /**
63
- * Unshare one direct child of an already-unshared parent — a node, or a
64
- * caller-owned `{ children }` view (e.g. a commit ceremony's array copy).
65
- */
55
+ /** Unshare one direct child of an already-unshared parent, or of a caller-owned `{ children }`. */
66
56
  export function ensureUnsharedChild(parent, index, sharing) {
67
57
  const child = parent.children[index];
68
- // G1.22 — an index off the end is a caller bug; fail here rather than
69
- // epoch-dependently inside `isShared`.
58
+ // G1.22: an index off the end is a caller bug, failed here rather than epoch-dependently
59
+ // inside `isShared`.
70
60
  assertInvariant('unshare-path-in-range', () => child ? null : { code: 'unshare-path', message: `child index ${index} out of range` });
71
61
  if (!child || !sharing.isShared(child))
72
62
  return child;
@@ -75,9 +65,8 @@ export function ensureUnsharedChild(parent, index, sharing) {
75
65
  return parent.children[index];
76
66
  }
77
67
  /**
78
- * Standalone copy for a node being MOVED out of a parent the snapshot keeps: the caller
79
- * attaches the returned copy, the original stays in the old parent untouched. An
80
- * unshared input passes through — unshared already means live-tree-owned.
68
+ * Standalone copy for a node being MOVED out of a parent the snapshot keeps: the caller attaches
69
+ * the copy, the original stays put. An unshared input passes through as live-tree-owned.
81
70
  */
82
71
  export function ensureUnsharedNode(node, sharing) {
83
72
  return sharing.isShared(node) ? copyNode(node, sharing) : node;
@@ -88,21 +77,17 @@ export function ensureUnsharedChildren(parent, sharing) {
88
77
  for (let i = 0; i < count; i++)
89
78
  ensureUnsharedChild(parent, i, sharing);
90
79
  }
91
- /**
92
- * Deep-unshare an owned node's subtree. Intended for small bounded subtrees
93
- * (tables: rows + cells) ahead of ops that write at arbitrary depth.
94
- */
80
+ /** Deep-unshare an owned node's subtree, for small bounded subtrees written at arbitrary depth. */
95
81
  export function ensureUnsharedSubtree(node, sharing) {
96
82
  const count = node.children?.length ?? 0;
97
83
  for (let i = 0; i < count; i++) {
98
84
  ensureUnsharedSubtree(ensureUnsharedChild(node, i, sharing), sharing);
99
85
  }
100
86
  }
101
- // ── Sharing-aware raw rebuilds ───────────────────────────────────────────────
87
+ // ── Sharing-aware raw rebuild ───────────────────────────────────────────────
102
88
  /**
103
- * Rebuild one owned container's raw. A grid rebuild rewrites its children's raw, so a
104
- * grid's children are unshared first — keyed off `containerContract`, not a `table` kind
105
- * test, or a plugin grid writes through shared children.
89
+ * Rebuild one owned container's raw. A grid rebuild rewrites its children's raw, so a grid's
90
+ * children are unshared first, keyed off `containerContract` rather than a `table` kind test.
106
91
  */
107
92
  export function rebuildOwnedContainer(node, sharing, changed) {
108
93
  if (getBlockKindDescriptor(node.kind).containerContract === 'grid') {
@@ -110,139 +95,3 @@ export function rebuildOwnedContainer(node, sharing, changed) {
110
95
  }
111
96
  rebuildContainerRawIfContainer(node, changed);
112
97
  }
113
- /**
114
- * Longest prefix of `chain` still attached under `root`, identity-checked level by level.
115
- * A commit mutation can splice a node out mid-ceremony; rebuilding the detached node's
116
- * raw against its emptied children writes `raw: ''` and trips the commit-time staleness
117
- * check. Ancestors above the detachment still need their rebuild — hence prefix.
118
- */
119
- export function attachedChainPrefix(root, chain) {
120
- let parentChildren = root.children;
121
- for (let i = 0; i < chain.length; i++) {
122
- if (!parentChildren.includes(chain[i]))
123
- return chain.slice(0, i);
124
- parentChildren = chain[i].children ?? [];
125
- }
126
- return chain;
127
- }
128
- /**
129
- * Rebuild raws along an owned spine chain innermost-first, re-deriving each container's kind and
130
- * settling the seams at its own slot; chain- rather than path-based so it survives index shifts.
131
- * Both passes gate on a boundary line of the rebuilt raw moving; the re-derive additionally needs
132
- * `lineOpensAs` not to name the current kind, a positive identification so a declining opener
133
- * parses rather than eliding a real kind change. `folds` is required-nullable: a fold splices the
134
- * PARENT's array, so only a caller that reconciles that scope's ids/refs passes a sink.
135
- */
136
- export function rebuildUnsharedChain(root, chain, sharing, folds, grammar, hint) {
137
- const reclassified = [];
138
- // The bytes chain[i + 1] held before this pass, which is what its own level captures on the
139
- // way past. It rides up only from a door that named the leaf's own: a caller passing no hint
140
- // re-derives at every level, which is what makes the structural paths a reseed (editor.md § 9).
141
- let childPreviousRaw;
142
- for (let i = chain.length - 1; i >= 0; i--) {
143
- const node = chain[i];
144
- const rawBefore = node.raw;
145
- const child = chain[i + 1];
146
- rebuildOwnedContainer(node, sharing, child && childPreviousRaw !== undefined
147
- ? childRawChange(node, child, childPreviousRaw, hint?.path[i + 1])
148
- : undefined);
149
- if (hint)
150
- childPreviousRaw = i === chain.length - 1 ? hint.leafPreviousRaw : rawBefore;
151
- const openerMoved = firstLine(rawBefore) !== firstLine(node.raw);
152
- const closerMoved = lastLine(rawBefore) !== lastLine(node.raw);
153
- if (!openerMoved && !closerMoved)
154
- continue;
155
- const owner = i === 0 ? null : chain[i - 1];
156
- const siblings = (owner ?? root).children;
157
- const index = siblings ? childIndexOf(siblings, node, hint?.path[i]) : -1;
158
- if (!siblings || index < 0)
159
- continue;
160
- if (openerMoved && lineOpensAs(firstLine(node.raw), grammar) !== node.kind) {
161
- const replacement = reclassifyContainer({ children: siblings }, index, grammar);
162
- if (replacement) {
163
- sharing.stamp(replacement);
164
- reclassified.push({ siblings, index, previous: node, replacement });
165
- }
166
- }
167
- // Ahead of the seam ask, which then reads the settled bytes: a list rebuilt down to an
168
- // empty marker owes the paragraph above it a separating line.
169
- if (openerMoved)
170
- settleSublistSeparator(siblings, index);
171
- // After the re-derive: the seam reads whatever occupies the slot now.
172
- if (folds) {
173
- const before = folds.length;
174
- settleSlotSeams({ siblings, owner, depth: i, index, openerMoved, closerMoved }, sharing, folds);
175
- // A fold re-tiled the owner's children, so its spans describe a shape that is gone.
176
- if (folds.length > before && owner)
177
- dropChildSpans(owner);
178
- }
179
- }
180
- if (perfEnabled())
181
- recordRebuildDepth(chain.length);
182
- return reclassified;
183
- }
184
- /**
185
- * The changed-child hint for `node`, or undefined when `child` cannot be placed in it. The
186
- * path index is a guess: an identity match is what makes it an answer, and a splice since the
187
- * unshare falls back to the scan.
188
- */
189
- function childRawChange(node, child, previousRaw, guess) {
190
- const siblings = node.children;
191
- if (!siblings)
192
- return undefined;
193
- const index = childIndexOf(siblings, child, guess);
194
- return index < 0 ? undefined : { index, previousRaw };
195
- }
196
- /** `indexOf` with a guess first: the scan is O(children) through the `$state` proxy. */
197
- function childIndexOf(siblings, child, guess) {
198
- if (guess !== undefined && siblings[guess] === child)
199
- return guess;
200
- return siblings.indexOf(child);
201
- }
202
- /**
203
- * Ask the joins at a rebuilt container's slot, since its new bytes can stop interrupting a
204
- * neighbour, which the reload then reads as one block with it. Byte-identical by construction,
205
- * like every other seam absorb. `absorbWindowSeams` walks `at - 1 … at + added - 1`, so the two
206
- * arguments below name exactly the sides whose line moved.
207
- */
208
- function settleSlotSeams(slot, sharing, folds) {
209
- const { siblings, index, openerMoved, closerMoved } = slot;
210
- // The rollback snapshot is captured only once a fold is certain: an eager copy here cost
211
- // O(children) reactive reads on every keystroke inside a large container.
212
- let before = null;
213
- const landing = { index, offset: 0 };
214
- const settled = absorbWindowSeams({ children: siblings }, openerMoved ? index : index + 1, openerMoved && closerMoved ? 1 : 0, index, { op: 'noop' }, sharing, landing, index, () => {
215
- before ??= siblings.slice();
216
- });
217
- if (settled.change.op === 'noop')
218
- return;
219
- folds.push({
220
- depth: slot.depth,
221
- siblings,
222
- owner: slot.owner,
223
- change: settled.change,
224
- // A non-noop change means a splice ran, so the capture ran first.
225
- before: before,
226
- landing
227
- });
228
- }
229
- /** The container's opener line. */
230
- function firstLine(raw) {
231
- const nl = raw.indexOf('\n');
232
- return nl < 0 ? raw : raw.slice(0, nl);
233
- }
234
- /** The container's closing line: its last line carrying bytes, without the ending. */
235
- function lastLine(raw) {
236
- const body = trimTrailingLineEnding(raw);
237
- const nl = body.lastIndexOf('\n');
238
- return nl < 0 ? body : body.slice(nl + 1);
239
- }
240
- /**
241
- * Unshare the spine to `path` and rebuild it innermost-first, tolerating paths that ran
242
- * out of range mid-walk (post-delete rebuild passes). Prefer `rebuildUnsharedChain` when
243
- * indices may have shifted since the unshare.
244
- */
245
- export function rebuildUnsharedAncestry(root, path, sharing, folds, grammar) {
246
- const chain = walkUnsharing(root, path, sharing, false);
247
- return rebuildUnsharedChain(root, chain, sharing, folds, grammar);
248
- }