smartrte-core 0.2.0 → 1.0.0-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (329) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/README.md +23 -0
  3. package/dist/command.d.ts +8 -8
  4. package/dist/editor.d.ts +32 -0
  5. package/dist/editor.js +121 -0
  6. package/dist/foundation/annotations/index.d.ts +2 -0
  7. package/dist/foundation/annotations/index.js +2 -0
  8. package/dist/foundation/annotations/range.d.ts +54 -0
  9. package/dist/foundation/annotations/range.js +158 -0
  10. package/dist/foundation/annotations/types.d.ts +33 -0
  11. package/dist/foundation/annotations/types.js +1 -0
  12. package/dist/foundation/atom/commands.d.ts +11 -0
  13. package/dist/foundation/atom/commands.js +118 -0
  14. package/dist/foundation/atom/composition.d.ts +8 -0
  15. package/dist/foundation/atom/composition.js +22 -0
  16. package/dist/foundation/atom/declarations.d.ts +2 -0
  17. package/dist/foundation/atom/declarations.js +17 -0
  18. package/dist/foundation/atom/formats.d.ts +21 -0
  19. package/dist/foundation/atom/formats.js +77 -0
  20. package/dist/foundation/atom/index.d.ts +10 -0
  21. package/dist/foundation/atom/index.js +10 -0
  22. package/dist/foundation/atom/lifecycle.d.ts +12 -0
  23. package/dist/foundation/atom/lifecycle.js +41 -0
  24. package/dist/foundation/atom/persistence.d.ts +3 -0
  25. package/dist/foundation/atom/persistence.js +20 -0
  26. package/dist/foundation/atom/plugin.d.ts +20 -0
  27. package/dist/foundation/atom/plugin.js +55 -0
  28. package/dist/foundation/atom/schema.d.ts +3 -0
  29. package/dist/foundation/atom/schema.js +29 -0
  30. package/dist/foundation/atom/security.d.ts +10 -0
  31. package/dist/foundation/atom/security.js +20 -0
  32. package/dist/foundation/atom/selection.d.ts +3 -0
  33. package/dist/foundation/atom/selection.js +4 -0
  34. package/dist/foundation/atom/types.d.ts +47 -0
  35. package/dist/foundation/atom/types.js +1 -0
  36. package/dist/foundation/block/commands.d.ts +17 -0
  37. package/dist/foundation/block/commands.js +197 -0
  38. package/dist/foundation/block/formats.d.ts +33 -0
  39. package/dist/foundation/block/formats.js +57 -0
  40. package/dist/foundation/block/index.d.ts +5 -0
  41. package/dist/foundation/block/index.js +5 -0
  42. package/dist/foundation/block/input.d.ts +19 -0
  43. package/dist/foundation/block/input.js +67 -0
  44. package/dist/foundation/block/plugin.d.ts +26 -0
  45. package/dist/foundation/block/plugin.js +79 -0
  46. package/dist/foundation/block/schema.d.ts +49 -0
  47. package/dist/foundation/block/schema.js +27 -0
  48. package/dist/foundation/block/types.d.ts +40 -0
  49. package/dist/foundation/block/types.js +1 -0
  50. package/dist/foundation/boundaries.d.ts +11 -0
  51. package/dist/foundation/boundaries.js +117 -0
  52. package/dist/foundation/clipboard/detection.d.ts +3 -0
  53. package/dist/foundation/clipboard/detection.js +29 -0
  54. package/dist/foundation/clipboard/diagnostics.d.ts +24 -0
  55. package/dist/foundation/clipboard/diagnostics.js +59 -0
  56. package/dist/foundation/clipboard/index.d.ts +8 -0
  57. package/dist/foundation/clipboard/index.js +8 -0
  58. package/dist/foundation/clipboard/insertion.d.ts +22 -0
  59. package/dist/foundation/clipboard/insertion.js +210 -0
  60. package/dist/foundation/clipboard/normalizers.d.ts +8 -0
  61. package/dist/foundation/clipboard/normalizers.js +229 -0
  62. package/dist/foundation/clipboard/pipeline.d.ts +13 -0
  63. package/dist/foundation/clipboard/pipeline.js +58 -0
  64. package/dist/foundation/clipboard/sanitizer.d.ts +3 -0
  65. package/dist/foundation/clipboard/sanitizer.js +58 -0
  66. package/dist/foundation/clipboard/serialization.d.ts +5 -0
  67. package/dist/foundation/clipboard/serialization.js +33 -0
  68. package/dist/foundation/clipboard/transfer.d.ts +11 -0
  69. package/dist/foundation/clipboard/transfer.js +108 -0
  70. package/dist/foundation/clipboard/types.d.ts +65 -0
  71. package/dist/foundation/clipboard/types.js +1 -0
  72. package/dist/foundation/collab/index.d.ts +3 -0
  73. package/dist/foundation/collab/index.js +3 -0
  74. package/dist/foundation/collab/rebase.d.ts +28 -0
  75. package/dist/foundation/collab/rebase.js +82 -0
  76. package/dist/foundation/collab/transform.d.ts +73 -0
  77. package/dist/foundation/collab/transform.js +251 -0
  78. package/dist/foundation/collab/types.d.ts +52 -0
  79. package/dist/foundation/collab/types.js +1 -0
  80. package/dist/foundation/comments/fromSelection.d.ts +16 -0
  81. package/dist/foundation/comments/fromSelection.js +24 -0
  82. package/dist/foundation/comments/index.d.ts +3 -0
  83. package/dist/foundation/comments/index.js +3 -0
  84. package/dist/foundation/comments/rebase.d.ts +31 -0
  85. package/dist/foundation/comments/rebase.js +43 -0
  86. package/dist/foundation/comments/types.d.ts +37 -0
  87. package/dist/foundation/comments/types.js +1 -0
  88. package/dist/foundation/diff/documentDiff.d.ts +12 -0
  89. package/dist/foundation/diff/documentDiff.js +148 -0
  90. package/dist/foundation/diff/index.d.ts +3 -0
  91. package/dist/foundation/diff/index.js +3 -0
  92. package/dist/foundation/diff/textDiff.d.ts +12 -0
  93. package/dist/foundation/diff/textDiff.js +114 -0
  94. package/dist/foundation/diff/types.d.ts +74 -0
  95. package/dist/foundation/diff/types.js +1 -0
  96. package/dist/foundation/editor.d.ts +138 -0
  97. package/dist/foundation/editor.js +398 -0
  98. package/dist/foundation/formats/codec.d.ts +45 -0
  99. package/dist/foundation/formats/codec.js +1 -0
  100. package/dist/foundation/formats/docx/export.d.ts +4 -0
  101. package/dist/foundation/formats/docx/export.js +285 -0
  102. package/dist/foundation/formats/docx/import.d.ts +9 -0
  103. package/dist/foundation/formats/docx/import.js +37 -0
  104. package/dist/foundation/formats/docx/nestingGuard.d.ts +40 -0
  105. package/dist/foundation/formats/docx/nestingGuard.js +66 -0
  106. package/dist/foundation/formats/docx/portableAtoms.d.ts +4 -0
  107. package/dist/foundation/formats/docx/portableAtoms.js +66 -0
  108. package/dist/foundation/formats/docx/styledImport.d.ts +10 -0
  109. package/dist/foundation/formats/docx/styledImport.js +205 -0
  110. package/dist/foundation/formats/featureCodecs.d.ts +37 -0
  111. package/dist/foundation/formats/featureCodecs.js +69 -0
  112. package/dist/foundation/formats/fidelity.d.ts +31 -0
  113. package/dist/foundation/formats/fidelity.js +123 -0
  114. package/dist/foundation/formats/index.d.ts +7 -0
  115. package/dist/foundation/formats/index.js +7 -0
  116. package/dist/foundation/formats/pdf/format.d.ts +29 -0
  117. package/dist/foundation/formats/pdf/format.js +190 -0
  118. package/dist/foundation/history.d.ts +20 -0
  119. package/dist/foundation/history.js +121 -0
  120. package/dist/foundation/identity.d.ts +8 -0
  121. package/dist/foundation/identity.js +30 -0
  122. package/dist/foundation/index.d.ts +30 -0
  123. package/dist/foundation/index.js +30 -0
  124. package/dist/foundation/list/commands.d.ts +28 -0
  125. package/dist/foundation/list/commands.js +422 -0
  126. package/dist/foundation/list/formats.d.ts +20 -0
  127. package/dist/foundation/list/formats.js +795 -0
  128. package/dist/foundation/list/index.d.ts +8 -0
  129. package/dist/foundation/list/index.js +8 -0
  130. package/dist/foundation/list/input.d.ts +35 -0
  131. package/dist/foundation/list/input.js +320 -0
  132. package/dist/foundation/list/plugin.d.ts +21 -0
  133. package/dist/foundation/list/plugin.js +71 -0
  134. package/dist/foundation/list/presets.d.ts +16 -0
  135. package/dist/foundation/list/presets.js +21 -0
  136. package/dist/foundation/list/schema.d.ts +35 -0
  137. package/dist/foundation/list/schema.js +29 -0
  138. package/dist/foundation/list/shadow.d.ts +54 -0
  139. package/dist/foundation/list/shadow.js +75 -0
  140. package/dist/foundation/list/shadowCorpus.d.ts +10 -0
  141. package/dist/foundation/list/shadowCorpus.js +41 -0
  142. package/dist/foundation/list/types.d.ts +50 -0
  143. package/dist/foundation/list/types.js +1 -0
  144. package/dist/foundation/mapping.d.ts +11 -0
  145. package/dist/foundation/mapping.js +40 -0
  146. package/dist/foundation/marks/canonical.d.ts +9 -0
  147. package/dist/foundation/marks/canonical.js +72 -0
  148. package/dist/foundation/marks/commands.d.ts +21 -0
  149. package/dist/foundation/marks/commands.js +136 -0
  150. package/dist/foundation/marks/dom.d.ts +2 -0
  151. package/dist/foundation/marks/dom.js +46 -0
  152. package/dist/foundation/marks/editor.d.ts +8 -0
  153. package/dist/foundation/marks/editor.js +50 -0
  154. package/dist/foundation/marks/formats.d.ts +37 -0
  155. package/dist/foundation/marks/formats.js +49 -0
  156. package/dist/foundation/marks/hardBreak.d.ts +8 -0
  157. package/dist/foundation/marks/hardBreak.js +80 -0
  158. package/dist/foundation/marks/index.d.ts +11 -0
  159. package/dist/foundation/marks/index.js +11 -0
  160. package/dist/foundation/marks/normalization.d.ts +2 -0
  161. package/dist/foundation/marks/normalization.js +49 -0
  162. package/dist/foundation/marks/plugin.d.ts +14 -0
  163. package/dist/foundation/marks/plugin.js +63 -0
  164. package/dist/foundation/marks/resolveMarkRun.d.ts +8 -0
  165. package/dist/foundation/marks/resolveMarkRun.js +47 -0
  166. package/dist/foundation/marks/schema.d.ts +167 -0
  167. package/dist/foundation/marks/schema.js +50 -0
  168. package/dist/foundation/marks/stored.d.ts +2 -0
  169. package/dist/foundation/marks/stored.js +31 -0
  170. package/dist/foundation/marks/types.d.ts +40 -0
  171. package/dist/foundation/marks/types.js +1 -0
  172. package/dist/foundation/modelDom.d.ts +38 -0
  173. package/dist/foundation/modelDom.js +327 -0
  174. package/dist/foundation/normalization.d.ts +22 -0
  175. package/dist/foundation/normalization.js +132 -0
  176. package/dist/foundation/operations.d.ts +28 -0
  177. package/dist/foundation/operations.js +568 -0
  178. package/dist/foundation/plugin/builtins.d.ts +10 -0
  179. package/dist/foundation/plugin/builtins.js +27 -0
  180. package/dist/foundation/plugin/dispatch.d.ts +33 -0
  181. package/dist/foundation/plugin/dispatch.js +34 -0
  182. package/dist/foundation/plugin/index.d.ts +4 -0
  183. package/dist/foundation/plugin/index.js +4 -0
  184. package/dist/foundation/plugin/registry.d.ts +36 -0
  185. package/dist/foundation/plugin/registry.js +115 -0
  186. package/dist/foundation/plugin/types.d.ts +141 -0
  187. package/dist/foundation/plugin/types.js +13 -0
  188. package/dist/foundation/positions.d.ts +20 -0
  189. package/dist/foundation/positions.js +121 -0
  190. package/dist/foundation/schema.d.ts +57 -0
  191. package/dist/foundation/schema.js +371 -0
  192. package/dist/foundation/schemaBuilder.d.ts +41 -0
  193. package/dist/foundation/schemaBuilder.js +96 -0
  194. package/dist/foundation/scope/index.d.ts +2 -0
  195. package/dist/foundation/scope/index.js +2 -0
  196. package/dist/foundation/scope/resolveScope.d.ts +13 -0
  197. package/dist/foundation/scope/resolveScope.js +860 -0
  198. package/dist/foundation/scope/types.d.ts +122 -0
  199. package/dist/foundation/scope/types.js +1 -0
  200. package/dist/foundation/security/urlPolicy.d.ts +21 -0
  201. package/dist/foundation/security/urlPolicy.js +75 -0
  202. package/dist/foundation/structural/contentTarget.d.ts +21 -0
  203. package/dist/foundation/structural/contentTarget.js +51 -0
  204. package/dist/foundation/structural/index.d.ts +2 -0
  205. package/dist/foundation/structural/index.js +2 -0
  206. package/dist/foundation/structural/move.d.ts +7 -0
  207. package/dist/foundation/structural/move.js +35 -0
  208. package/dist/foundation/suggestions/index.d.ts +3 -0
  209. package/dist/foundation/suggestions/index.js +3 -0
  210. package/dist/foundation/suggestions/inline.d.ts +64 -0
  211. package/dist/foundation/suggestions/inline.js +116 -0
  212. package/dist/foundation/suggestions/structural.d.ts +40 -0
  213. package/dist/foundation/suggestions/structural.js +47 -0
  214. package/dist/foundation/suggestions/types.d.ts +19 -0
  215. package/dist/foundation/suggestions/types.js +1 -0
  216. package/dist/foundation/surface/index.d.ts +3 -0
  217. package/dist/foundation/surface/index.js +3 -0
  218. package/dist/foundation/surface/input.d.ts +127 -0
  219. package/dist/foundation/surface/input.js +1761 -0
  220. package/dist/foundation/surface/renderer.d.ts +84 -0
  221. package/dist/foundation/surface/renderer.js +974 -0
  222. package/dist/foundation/surface/types.d.ts +48 -0
  223. package/dist/foundation/surface/types.js +1 -0
  224. package/dist/foundation/table/commands.d.ts +31 -0
  225. package/dist/foundation/table/commands.js +470 -0
  226. package/dist/foundation/table/formats.d.ts +26 -0
  227. package/dist/foundation/table/formats.js +40 -0
  228. package/dist/foundation/table/grid.d.ts +8 -0
  229. package/dist/foundation/table/grid.js +178 -0
  230. package/dist/foundation/table/index.d.ts +6 -0
  231. package/dist/foundation/table/index.js +6 -0
  232. package/dist/foundation/table/plugin.d.ts +23 -0
  233. package/dist/foundation/table/plugin.js +119 -0
  234. package/dist/foundation/table/schema.d.ts +2 -0
  235. package/dist/foundation/table/schema.js +38 -0
  236. package/dist/foundation/table/selection.d.ts +7 -0
  237. package/dist/foundation/table/selection.js +35 -0
  238. package/dist/foundation/table/types.d.ts +109 -0
  239. package/dist/foundation/table/types.js +1 -0
  240. package/dist/foundation/transactions.d.ts +41 -0
  241. package/dist/foundation/transactions.js +90 -0
  242. package/dist/foundation/types.d.ts +261 -0
  243. package/dist/foundation/types.js +1 -0
  244. package/dist/foundation/versioning/diffVersions.d.ts +5 -0
  245. package/dist/foundation/versioning/diffVersions.js +3 -0
  246. package/dist/foundation/versioning/index.d.ts +2 -0
  247. package/dist/foundation/versioning/index.js +2 -0
  248. package/dist/foundation/versioning/types.d.ts +17 -0
  249. package/dist/foundation/versioning/types.js +1 -0
  250. package/dist/history.d.ts +20 -0
  251. package/dist/history.js +165 -0
  252. package/dist/html/compatibility.js +7 -1
  253. package/dist/index.d.ts +1 -14
  254. package/dist/index.js +9 -14
  255. package/dist/legacy/index.d.ts +45 -0
  256. package/dist/legacy/index.js +45 -0
  257. package/dist/legacyCommands/alignment.d.ts +20 -0
  258. package/dist/{commands → legacyCommands}/alignment.js +17 -0
  259. package/dist/legacyCommands/blocks.d.ts +14 -0
  260. package/dist/legacyCommands/blocks.js +105 -0
  261. package/dist/legacyCommands/checklist.d.ts +11 -0
  262. package/dist/legacyCommands/checklist.js +45 -0
  263. package/dist/legacyCommands/code.d.ts +15 -0
  264. package/dist/{commands → legacyCommands}/code.js +25 -1
  265. package/dist/legacyCommands/formula.d.ts +7 -0
  266. package/dist/legacyCommands/formula.js +67 -0
  267. package/dist/legacyCommands/inlineAtoms.d.ts +7 -0
  268. package/dist/legacyCommands/inlineAtoms.js +58 -0
  269. package/dist/legacyCommands/list.d.ts +38 -0
  270. package/dist/legacyCommands/list.js +477 -0
  271. package/dist/{commands → legacyCommands}/marks.d.ts +3 -0
  272. package/dist/{commands → legacyCommands}/marks.js +45 -11
  273. package/dist/legacyCommands/media.d.ts +31 -0
  274. package/dist/legacyCommands/media.js +205 -0
  275. package/dist/legacyCommands/move.d.ts +14 -0
  276. package/dist/legacyCommands/move.js +91 -0
  277. package/dist/legacyCommands/table.d.ts +91 -0
  278. package/dist/legacyCommands/table.js +547 -0
  279. package/dist/listPresets.d.ts +12 -0
  280. package/dist/listPresets.js +6 -0
  281. package/dist/listScope.d.ts +27 -0
  282. package/dist/listScope.js +104 -0
  283. package/dist/markdown/compatibility.d.ts +2 -0
  284. package/dist/markdown/compatibility.js +94 -2
  285. package/dist/marks.d.ts +5 -5
  286. package/dist/model.d.ts +65 -9
  287. package/dist/plugin.d.ts +15 -0
  288. package/dist/plugin.js +31 -0
  289. package/dist/plugins/alignment.d.ts +3 -0
  290. package/dist/plugins/alignment.js +6 -0
  291. package/dist/plugins/basicFormatting.d.ts +9 -0
  292. package/dist/plugins/basicFormatting.js +24 -0
  293. package/dist/plugins/blockType.d.ts +3 -0
  294. package/dist/plugins/blockType.js +6 -0
  295. package/dist/plugins/blockquote.d.ts +3 -0
  296. package/dist/plugins/blockquote.js +6 -0
  297. package/dist/plugins/checklist.d.ts +3 -0
  298. package/dist/plugins/checklist.js +10 -0
  299. package/dist/plugins/codeBlock.d.ts +3 -0
  300. package/dist/plugins/codeBlock.js +6 -0
  301. package/dist/plugins/formula.d.ts +3 -0
  302. package/dist/plugins/formula.js +9 -0
  303. package/dist/plugins/list.d.ts +3 -0
  304. package/dist/plugins/list.js +10 -0
  305. package/dist/plugins/media.d.ts +3 -0
  306. package/dist/plugins/media.js +12 -0
  307. package/dist/plugins/move.d.ts +3 -0
  308. package/dist/plugins/move.js +9 -0
  309. package/dist/plugins/table.d.ts +3 -0
  310. package/dist/plugins/table.js +22 -0
  311. package/dist/preset.d.ts +12 -0
  312. package/dist/preset.js +40 -0
  313. package/dist/schema.d.ts +22 -0
  314. package/dist/schema.js +333 -0
  315. package/dist/security/urlPolicy.d.ts +1 -17
  316. package/dist/security/urlPolicy.js +3 -69
  317. package/dist/selection.d.ts +1 -1
  318. package/dist/selectionMapping.d.ts +4 -0
  319. package/dist/selectionMapping.js +222 -0
  320. package/dist/table.d.ts +3 -3
  321. package/dist/transaction.d.ts +35 -12
  322. package/dist/transaction.js +174 -28
  323. package/dist/tree.d.ts +8 -2
  324. package/dist/tree.js +44 -0
  325. package/package.json +27 -8
  326. package/dist/commands/alignment.d.ts +0 -18
  327. package/dist/commands/code.d.ts +0 -13
  328. package/dist/commands/list.d.ts +0 -20
  329. package/dist/commands/list.js +0 -52
@@ -0,0 +1,222 @@
1
+ import { getNodeAtTreePath, isSmartContainer } from "./tree.js";
2
+ const samePath = (left, right) => left.length === right.length && left.every((part, index) => part === right[index]);
3
+ const hasPrefix = (path, prefix) => path.length >= prefix.length && prefix.every((part, index) => path[index] === part);
4
+ const insertionAdjustedPath = (path, insertion) => {
5
+ const parent = insertion.slice(0, -1);
6
+ const depth = parent.length;
7
+ if (!hasPrefix(path, parent) || path.length <= depth)
8
+ return [...path];
9
+ const next = [...path];
10
+ if (next[depth] >= insertion[depth])
11
+ next[depth] += 1;
12
+ return next;
13
+ };
14
+ const removalAdjustedPath = (path, removal) => {
15
+ if (hasPrefix(path, removal))
16
+ return null;
17
+ const parent = removal.slice(0, -1);
18
+ const depth = parent.length;
19
+ if (!hasPrefix(path, parent) || path.length <= depth)
20
+ return [...path];
21
+ const next = [...path];
22
+ if (next[depth] > removal[depth])
23
+ next[depth] -= 1;
24
+ return next;
25
+ };
26
+ const moveDestinationAfterRemoval = (from, to) => {
27
+ const parent = from.slice(0, -1);
28
+ const depth = parent.length;
29
+ const next = [...to];
30
+ if (hasPrefix(to, parent) && to.length > depth && from[depth] < to[depth])
31
+ next[depth] -= 1;
32
+ return next;
33
+ };
34
+ const moveAdjustedPath = (path, from, to) => {
35
+ const destination = moveDestinationAfterRemoval(from, to);
36
+ if (hasPrefix(path, from))
37
+ return [...destination, ...path.slice(from.length)];
38
+ const afterRemoval = removalAdjustedPath(path, from);
39
+ return afterRemoval ? insertionAdjustedPath(afterRemoval, destination) : null;
40
+ };
41
+ const splitAdjustedPath = (path, splitPath, position) => {
42
+ const parent = splitPath.slice(0, -1);
43
+ const depth = splitPath.length - 1;
44
+ const rightPath = [...parent, splitPath[depth] + 1];
45
+ if (hasPrefix(path, splitPath) && path.length > splitPath.length) {
46
+ const childIndex = path[splitPath.length];
47
+ return childIndex >= position
48
+ ? [...rightPath, childIndex - position, ...path.slice(splitPath.length + 1)]
49
+ : [...path];
50
+ }
51
+ if (hasPrefix(path, parent) && path.length > depth && path[depth] > splitPath[depth]) {
52
+ const next = [...path];
53
+ next[depth] += 1;
54
+ return next;
55
+ }
56
+ return [...path];
57
+ };
58
+ const mergeAdjustedPath = (path, rightPath, leftContentLength) => {
59
+ const parent = rightPath.slice(0, -1);
60
+ const depth = rightPath.length - 1;
61
+ const leftPath = [...parent, rightPath[depth] - 1];
62
+ if (hasPrefix(path, rightPath)) {
63
+ if (path.length === rightPath.length)
64
+ return leftPath;
65
+ return [
66
+ ...leftPath,
67
+ path[rightPath.length] + leftContentLength,
68
+ ...path.slice(rightPath.length + 1),
69
+ ];
70
+ }
71
+ if (hasPrefix(path, parent) && path.length > depth && path[depth] > rightPath[depth]) {
72
+ const next = [...path];
73
+ next[depth] -= 1;
74
+ return next;
75
+ }
76
+ return [...path];
77
+ };
78
+ const mapTextSplitPoint = (point, path, start, end, originalLength) => {
79
+ const before = start > 0 ? 1 : 0;
80
+ const selected = end > start ? 1 : 0;
81
+ const pieces = before + selected + (end < originalLength ? 1 : 0);
82
+ const index = path[path.length - 1];
83
+ const parent = path.slice(0, -1);
84
+ if (!samePath(point.path, path)) {
85
+ if (hasPrefix(point.path, parent) &&
86
+ point.path.length > parent.length &&
87
+ point.path[parent.length] > index) {
88
+ const mapped = [...point.path];
89
+ mapped[parent.length] += pieces - 1;
90
+ return { ...point, path: mapped };
91
+ }
92
+ return { ...point, path: [...point.path] };
93
+ }
94
+ if (point.offset <= start) {
95
+ return { path: [...parent, index], offset: point.offset };
96
+ }
97
+ if (point.offset <= end && selected) {
98
+ return { path: [...parent, index + before], offset: point.offset - start };
99
+ }
100
+ return {
101
+ path: [...parent, index + before + selected],
102
+ offset: Math.max(0, point.offset - end),
103
+ };
104
+ };
105
+ const mapPoint = (point, operation, documentBefore) => {
106
+ if (operation.type === "insertNode") {
107
+ return { ...point, path: insertionAdjustedPath(point.path, operation.path) };
108
+ }
109
+ if (operation.type === "removeNode") {
110
+ const path = removalAdjustedPath(point.path, operation.path);
111
+ return path ? { ...point, path } : null;
112
+ }
113
+ if (operation.type === "moveNode") {
114
+ const path = moveAdjustedPath(point.path, operation.from, operation.to);
115
+ return path ? { ...point, path } : null;
116
+ }
117
+ if (operation.type === "splitNode") {
118
+ const node = getNodeAtTreePath(documentBefore, operation.path);
119
+ if (samePath(point.path, operation.path) && node?.type === "text") {
120
+ if (point.offset <= operation.position)
121
+ return { ...point, path: [...point.path] };
122
+ const rightPath = [
123
+ ...operation.path.slice(0, -1),
124
+ operation.path[operation.path.length - 1] + 1,
125
+ ];
126
+ return { path: rightPath, offset: point.offset - operation.position };
127
+ }
128
+ return { ...point, path: splitAdjustedPath(point.path, operation.path, operation.position) };
129
+ }
130
+ if (operation.type === "mergeNode") {
131
+ const right = getNodeAtTreePath(documentBefore, operation.path);
132
+ const leftPath = [
133
+ ...operation.path.slice(0, -1),
134
+ operation.path[operation.path.length - 1] - 1,
135
+ ];
136
+ const left = getNodeAtTreePath(documentBefore, leftPath);
137
+ const leftLength = left?.type === "text"
138
+ ? left.text.length
139
+ : isSmartContainer(left)
140
+ ? left.children.length
141
+ : 0;
142
+ if (samePath(point.path, operation.path) && right?.type === "text") {
143
+ return { path: leftPath, offset: leftLength + point.offset };
144
+ }
145
+ return { ...point, path: mergeAdjustedPath(point.path, operation.path, leftLength) };
146
+ }
147
+ if (operation.type === "replaceText" && samePath(point.path, operation.path)) {
148
+ const replacedLength = operation.end - operation.start;
149
+ const delta = operation.text.length - replacedLength;
150
+ if (point.offset <= operation.start)
151
+ return { ...point, path: [...point.path] };
152
+ if (point.offset <= operation.end) {
153
+ return { ...point, path: [...point.path], offset: operation.start + operation.text.length };
154
+ }
155
+ return { ...point, path: [...point.path], offset: point.offset + delta };
156
+ }
157
+ if ((operation.type === "addMark" || operation.type === "removeMark")) {
158
+ const node = getNodeAtTreePath(documentBefore, operation.path);
159
+ return mapTextSplitPoint(point, operation.path, operation.start, operation.end, node.text.length);
160
+ }
161
+ return { ...point, path: [...point.path] };
162
+ };
163
+ const fallbackForRemovedPath = (path) => ({
164
+ type: "node",
165
+ path: path.length ? path.slice(0, -1) : [],
166
+ });
167
+ export const mapSelectionThroughOperation = (selection, operation, documentBefore) => {
168
+ if (operation.type === "setSelection")
169
+ return operation.selection;
170
+ if (selection.type === "all")
171
+ return selection;
172
+ if (selection.type === "node") {
173
+ let path = selection.path;
174
+ if (operation.type === "insertNode")
175
+ path = insertionAdjustedPath(path, operation.path);
176
+ else if (operation.type === "removeNode")
177
+ path = removalAdjustedPath(path, operation.path);
178
+ else if (operation.type === "moveNode")
179
+ path = moveAdjustedPath(path, operation.from, operation.to);
180
+ else if (operation.type === "splitNode")
181
+ path = splitAdjustedPath(path, operation.path, operation.position);
182
+ else if (operation.type === "mergeNode") {
183
+ const leftPath = [...operation.path.slice(0, -1), operation.path[operation.path.length - 1] - 1];
184
+ const left = getNodeAtTreePath(documentBefore, leftPath);
185
+ const length = isSmartContainer(left) ? left.children.length : 0;
186
+ path = mergeAdjustedPath(path, operation.path, length);
187
+ }
188
+ return path
189
+ ? { type: "node", path }
190
+ : fallbackForRemovedPath(operation.type === "removeNode" ? operation.path : selection.path);
191
+ }
192
+ if (selection.type === "cell") {
193
+ let tablePath = selection.tablePath;
194
+ if (operation.type === "insertNode")
195
+ tablePath = insertionAdjustedPath(tablePath, operation.path);
196
+ else if (operation.type === "removeNode")
197
+ tablePath = removalAdjustedPath(tablePath, operation.path);
198
+ else if (operation.type === "moveNode")
199
+ tablePath = moveAdjustedPath(tablePath, operation.from, operation.to);
200
+ else if (operation.type === "splitNode")
201
+ tablePath = splitAdjustedPath(tablePath, operation.path, operation.position);
202
+ else if (operation.type === "mergeNode") {
203
+ const leftPath = [...operation.path.slice(0, -1), operation.path[operation.path.length - 1] - 1];
204
+ const left = getNodeAtTreePath(documentBefore, leftPath);
205
+ tablePath = mergeAdjustedPath(tablePath, operation.path, isSmartContainer(left) ? left.children.length : 0);
206
+ }
207
+ return tablePath
208
+ ? { ...selection, tablePath }
209
+ : fallbackForRemovedPath(operation.type === "removeNode" ? operation.path : selection.tablePath);
210
+ }
211
+ const anchor = mapPoint(selection.anchor, operation, documentBefore);
212
+ const focus = mapPoint(selection.focus, operation, documentBefore);
213
+ if (!anchor || !focus) {
214
+ const removedPath = operation.type === "removeNode"
215
+ ? operation.path
216
+ : operation.type === "moveNode"
217
+ ? operation.from
218
+ : selection.anchor.path;
219
+ return fallbackForRemovedPath(removedPath);
220
+ }
221
+ return { type: "text", anchor, focus };
222
+ };
package/dist/table.d.ts CHANGED
@@ -1,9 +1,9 @@
1
- import { type SmartBlockNode, type SmartTableCellNode } from "./model.js";
1
+ import { type SmartBlockNode, type SmartListStyle, type SmartTableCellNode } from "./model.js";
2
2
  /** Ensures table cells have blocks even when imported HTML supplied raw lines. */
3
3
  export declare const normalizeTableCell: (cell: SmartTableCellNode, rawLines?: readonly string[]) => SmartTableCellNode;
4
- export declare const listFromBlocks: (blocks: readonly SmartBlockNode[], style?: "disc" | "circle" | "square" | "decimal" | "lower-alpha" | "upper-alpha" | "lower-roman" | "upper-roman") => {
4
+ export declare const listFromBlocks: (blocks: readonly SmartBlockNode[], style?: SmartListStyle) => {
5
5
  type: "list";
6
- style: "disc" | "circle" | "square" | "decimal" | "lower-alpha" | "upper-alpha" | "lower-roman" | "upper-roman";
6
+ style: SmartListStyle;
7
7
  children: {
8
8
  type: "listItem";
9
9
  children: SmartBlockNode[];
@@ -1,7 +1,7 @@
1
- import type { SmartDocument, Path, SmartMark } from "./model.js";
2
- import type { SmartSelection } from "./selection.js";
1
+ import type { LegacySmartDocument, Path, LegacySmartMark } from "./model.js";
2
+ import type { LegacySmartSelection } from "./selection.js";
3
3
  import { type InlineMarkType } from "./marks.js";
4
- export type SmartOperation = {
4
+ export type LegacySmartOperation = {
5
5
  type: "insertNode";
6
6
  path: Path;
7
7
  node: unknown;
@@ -12,16 +12,33 @@ export type SmartOperation = {
12
12
  type: "replaceNode";
13
13
  path: Path;
14
14
  node: unknown;
15
+ } | {
16
+ type: "moveNode";
17
+ from: Path;
18
+ to: Path;
19
+ } | {
20
+ type: "splitNode";
21
+ path: Path;
22
+ position: number;
23
+ } | {
24
+ type: "mergeNode";
25
+ path: Path;
15
26
  } | {
16
27
  type: "setNodeAttrs";
17
28
  path: Path;
18
29
  attrs: Record<string, unknown>;
30
+ } | {
31
+ type: "replaceText";
32
+ path: Path;
33
+ start: number;
34
+ end: number;
35
+ text: string;
19
36
  } | {
20
37
  type: "addMark";
21
38
  path: Path;
22
39
  start: number;
23
40
  end: number;
24
- mark: SmartMark;
41
+ mark: LegacySmartMark;
25
42
  } | {
26
43
  type: "removeMark";
27
44
  path: Path;
@@ -30,19 +47,25 @@ export type SmartOperation = {
30
47
  markType: InlineMarkType;
31
48
  } | {
32
49
  type: "setSelection";
33
- selection: SmartSelection;
50
+ selection: LegacySmartSelection;
34
51
  };
35
- export interface SmartTransaction {
52
+ export interface LegacySmartTransaction {
36
53
  id: string;
37
54
  source: "user" | "paste" | "api" | "history" | "normalizer";
38
- operations: SmartOperation[];
39
- selectionBefore: SmartSelection;
40
- selectionAfter: SmartSelection;
55
+ operations: LegacySmartOperation[];
56
+ selectionBefore: LegacySmartSelection;
57
+ selectionAfter?: LegacySmartSelection;
41
58
  addToHistory: boolean;
59
+ historyGroup?: string;
42
60
  timestamp: number;
43
61
  }
44
62
  export interface SmartEditorState {
45
- document: SmartDocument;
46
- selection: SmartSelection;
63
+ document: LegacySmartDocument;
64
+ selection: LegacySmartSelection;
47
65
  }
48
- export declare const applyTransaction: (state: SmartEditorState, transaction: SmartTransaction) => SmartEditorState;
66
+ export declare const getMoveDestinationAfterRemoval: (from: Path, to: Path) => Path;
67
+ export declare const applyOperationToState: (document: LegacySmartDocument, selection: LegacySmartSelection, operation: LegacySmartOperation) => {
68
+ document: LegacySmartDocument;
69
+ selection: LegacySmartSelection;
70
+ };
71
+ export declare const applyTransaction: (state: SmartEditorState, transaction: LegacySmartTransaction) => SmartEditorState;
@@ -1,5 +1,7 @@
1
+ import { mapSelectionThroughOperation } from "./selectionMapping.js";
2
+ import { normalizeSmartDocument } from "./schema.js";
1
3
  import { addMark, removeMark } from "./marks.js";
2
- import { replaceNodeAtPath } from "./tree.js";
4
+ import { getNodeAtTreePath, insertNodeAtPath, isSmartContainer, removeNodeAtPath, replaceNodeAtPath, } from "./tree.js";
3
5
  const splitTextNode = (node, start, end, mutateMarks) => {
4
6
  if (start < 0 || end < start || end > node.text.length) {
5
7
  throw new Error("Mark operation range is out of bounds.");
@@ -38,36 +40,180 @@ const replaceTextAtPath = (document, path, replacement) => {
38
40
  };
39
41
  return replaceNodeAtPath(document, parentPath, nextParent);
40
42
  };
41
- export const applyTransaction = (state, transaction) => {
42
- let document = state.document;
43
- let selection = state.selection;
44
- transaction.operations.forEach((operation) => {
45
- if (operation.type === "replaceNode") {
46
- document = replaceNodeAtPath(document, operation.path, operation.node);
43
+ const samePath = (left, right) => left.length === right.length && left.every((part, index) => part === right[index]);
44
+ const isAncestorPath = (ancestor, descendant) => ancestor.length < descendant.length && ancestor.every((part, index) => descendant[index] === part);
45
+ export const getMoveDestinationAfterRemoval = (from, to) => {
46
+ const fromParent = from.slice(0, -1);
47
+ const depth = fromParent.length;
48
+ const sharesRemovedParent = fromParent.every((part, index) => to[index] === part);
49
+ if (!sharesRemovedParent || to.length <= depth)
50
+ return [...to];
51
+ const destination = [...to];
52
+ if (from[depth] < destination[depth])
53
+ destination[depth] -= 1;
54
+ return destination;
55
+ };
56
+ const nodeAttributes = (node, contentKey) => {
57
+ const attributes = { ...node };
58
+ delete attributes[contentKey];
59
+ return attributes;
60
+ };
61
+ const sameAttributes = (left, right, contentKey) => JSON.stringify(nodeAttributes(left, contentKey)) === JSON.stringify(nodeAttributes(right, contentKey));
62
+ export const applyOperationToState = (document, selection, operation) => {
63
+ if (operation.type === "insertNode") {
64
+ return { document: insertNodeAtPath(document, operation.path, operation.node), selection };
65
+ }
66
+ if (operation.type === "removeNode") {
67
+ return { document: removeNodeAtPath(document, operation.path).document, selection };
68
+ }
69
+ if (operation.type === "replaceNode") {
70
+ return { document: replaceNodeAtPath(document, operation.path, operation.node), selection };
71
+ }
72
+ if (operation.type === "moveNode") {
73
+ if (operation.from.length === 0 || operation.to.length === 0) {
74
+ throw new Error("Move paths cannot target the document root.");
75
+ }
76
+ if (samePath(operation.from, operation.to))
77
+ return { document, selection };
78
+ if (isAncestorPath(operation.from, operation.to)) {
79
+ throw new Error("A node cannot be moved into its own descendant.");
80
+ }
81
+ const removed = removeNodeAtPath(document, operation.from);
82
+ const destination = getMoveDestinationAfterRemoval(operation.from, operation.to);
83
+ return { document: insertNodeAtPath(removed.document, destination, removed.node), selection };
84
+ }
85
+ if (operation.type === "splitNode") {
86
+ if (operation.path.length === 0)
87
+ throw new Error("The document root cannot be split.");
88
+ const node = getNodeAtTreePath(document, operation.path);
89
+ if (!node || typeof node !== "object")
90
+ throw new Error("Split path does not resolve to a node.");
91
+ const position = operation.position;
92
+ if (!Number.isInteger(position) || position < 0)
93
+ throw new Error("Split position must be a non-negative integer.");
94
+ let left;
95
+ let right;
96
+ if (node.type === "text") {
97
+ const textNode = node;
98
+ if (position > textNode.text.length)
99
+ throw new Error("Text split position is out of bounds.");
100
+ left = { ...textNode, text: textNode.text.slice(0, position) };
101
+ right = { ...textNode, text: textNode.text.slice(position) };
47
102
  }
48
- else if (operation.type === "addMark") {
49
- const node = operation.path.reduce((value, index) => {
50
- if (!value || typeof value !== "object" || !Array.isArray(value.children))
51
- return undefined;
52
- return value.children[index];
53
- }, document);
54
- if (!node || node.type !== "text")
55
- throw new Error("Mark operation path does not resolve to text.");
56
- document = replaceTextAtPath(document, operation.path, splitTextNode(node, operation.start, operation.end, (marks) => addMark(marks, operation.mark)));
103
+ else if (isSmartContainer(node)) {
104
+ if (position > node.children.length)
105
+ throw new Error("Container split position is out of bounds.");
106
+ left = { ...node, children: node.children.slice(0, position) };
107
+ right = { ...node, children: node.children.slice(position) };
108
+ }
109
+ else {
110
+ throw new Error("Only text nodes and container nodes can be split.");
111
+ }
112
+ const replaced = replaceNodeAtPath(document, operation.path, left);
113
+ const rightPath = [...operation.path.slice(0, -1), operation.path[operation.path.length - 1] + 1];
114
+ return { document: insertNodeAtPath(replaced, rightPath, right), selection };
115
+ }
116
+ if (operation.type === "mergeNode") {
117
+ if (operation.path.length === 0)
118
+ throw new Error("The document root cannot be merged.");
119
+ const rightIndex = operation.path[operation.path.length - 1];
120
+ if (rightIndex === 0)
121
+ throw new Error("Merge node has no previous sibling.");
122
+ const leftPath = [...operation.path.slice(0, -1), rightIndex - 1];
123
+ const left = getNodeAtTreePath(document, leftPath);
124
+ const right = getNodeAtTreePath(document, operation.path);
125
+ if (!left || !right || typeof left !== "object" || typeof right !== "object") {
126
+ throw new Error("Merge paths must resolve to nodes.");
57
127
  }
58
- else if (operation.type === "removeMark") {
59
- const node = operation.path.reduce((value, index) => {
60
- if (!value || typeof value !== "object" || !Array.isArray(value.children))
61
- return undefined;
62
- return value.children[index];
63
- }, document);
64
- if (!node || node.type !== "text")
65
- throw new Error("Mark operation path does not resolve to text.");
66
- document = replaceTextAtPath(document, operation.path, splitTextNode(node, operation.start, operation.end, (marks) => removeMark(marks, operation.markType)));
128
+ let merged;
129
+ if (left.type === "text" && right.type === "text") {
130
+ const leftText = left;
131
+ const rightText = right;
132
+ if (!sameAttributes(left, right, "text")) {
133
+ throw new Error("Text nodes with different marks cannot be merged.");
134
+ }
135
+ merged = { ...leftText, text: leftText.text + rightText.text };
67
136
  }
68
- else if (operation.type === "setSelection") {
69
- selection = operation.selection;
137
+ else if (isSmartContainer(left) && isSmartContainer(right)) {
138
+ if (!sameAttributes(left, right, "children")) {
139
+ throw new Error("Container nodes with different attributes cannot be merged.");
140
+ }
141
+ merged = { ...left, children: [...left.children, ...right.children] };
70
142
  }
143
+ else {
144
+ throw new Error("Merge nodes must have compatible structures.");
145
+ }
146
+ const replaced = replaceNodeAtPath(document, leftPath, merged);
147
+ return { document: removeNodeAtPath(replaced, operation.path).document, selection };
148
+ }
149
+ if (operation.type === "setNodeAttrs") {
150
+ const node = getNodeAtTreePath(document, operation.path);
151
+ if (!node || typeof node !== "object")
152
+ throw new Error("Attribute path does not resolve to a node.");
153
+ if ("type" in operation.attrs || "children" in operation.attrs || "text" in operation.attrs) {
154
+ throw new Error("setNodeAttrs cannot replace structural node fields.");
155
+ }
156
+ const replacement = { ...node };
157
+ Object.entries(operation.attrs).forEach(([name, value]) => {
158
+ if (value === undefined)
159
+ delete replacement[name];
160
+ else
161
+ replacement[name] = value;
162
+ });
163
+ return { document: replaceNodeAtPath(document, operation.path, replacement), selection };
164
+ }
165
+ if (operation.type === "replaceText") {
166
+ const node = getNodeAtTreePath(document, operation.path);
167
+ if (!node || node.type !== "text")
168
+ throw new Error("Text operation path does not resolve to text.");
169
+ if (!Number.isInteger(operation.start) ||
170
+ !Number.isInteger(operation.end) ||
171
+ operation.start < 0 ||
172
+ operation.end < operation.start ||
173
+ operation.end > node.text.length) {
174
+ throw new Error("Text replacement range is out of bounds.");
175
+ }
176
+ return {
177
+ document: replaceNodeAtPath(document, operation.path, {
178
+ ...node,
179
+ text: node.text.slice(0, operation.start) + operation.text + node.text.slice(operation.end),
180
+ }),
181
+ selection,
182
+ };
183
+ }
184
+ if (operation.type === "addMark") {
185
+ const node = getNodeAtTreePath(document, operation.path);
186
+ if (!node || node.type !== "text")
187
+ throw new Error("Mark operation path does not resolve to text.");
188
+ return {
189
+ document: replaceTextAtPath(document, operation.path, splitTextNode(node, operation.start, operation.end, (marks) => addMark(marks, operation.mark))),
190
+ selection,
191
+ };
192
+ }
193
+ if (operation.type === "removeMark") {
194
+ const node = getNodeAtTreePath(document, operation.path);
195
+ if (!node || node.type !== "text")
196
+ throw new Error("Mark operation path does not resolve to text.");
197
+ return {
198
+ document: replaceTextAtPath(document, operation.path, splitTextNode(node, operation.start, operation.end, (marks) => removeMark(marks, operation.markType))),
199
+ selection,
200
+ };
201
+ }
202
+ return { document, selection: operation.selection };
203
+ };
204
+ export const applyTransaction = (state, transaction) => {
205
+ let document = state.document;
206
+ let selection = state.selection;
207
+ transaction.operations.forEach((operation) => {
208
+ const documentBefore = document;
209
+ const next = applyOperationToState(document, selection, operation);
210
+ document = next.document;
211
+ selection = operation.type === "setSelection"
212
+ ? next.selection
213
+ : mapSelectionThroughOperation(selection, operation, documentBefore);
71
214
  });
72
- return { document, selection: transaction.selectionAfter || selection };
215
+ return {
216
+ document: normalizeSmartDocument(document),
217
+ selection: transaction.selectionAfter ?? selection,
218
+ };
73
219
  };
package/dist/tree.d.ts CHANGED
@@ -1,6 +1,12 @@
1
- import type { Path, SmartDocument } from "./model.js";
1
+ import type { Path, LegacySmartDocument } from "./model.js";
2
2
  export interface SmartContainer {
3
3
  children: unknown[];
4
4
  }
5
5
  export declare const isSmartContainer: (value: unknown) => value is SmartContainer;
6
- export declare const replaceNodeAtPath: <T>(document: SmartDocument, path: Path, replacement: T) => SmartDocument;
6
+ export declare const getNodeAtTreePath: (document: LegacySmartDocument, path: Path) => unknown;
7
+ export declare const replaceNodeAtPath: <T>(document: LegacySmartDocument, path: Path, replacement: T) => LegacySmartDocument;
8
+ export declare const insertNodeAtPath: <T>(document: LegacySmartDocument, path: Path, node: T) => LegacySmartDocument;
9
+ export declare const removeNodeAtPath: (document: LegacySmartDocument, path: Path) => {
10
+ document: LegacySmartDocument;
11
+ node: unknown;
12
+ };
package/dist/tree.js CHANGED
@@ -1,4 +1,26 @@
1
1
  export const isSmartContainer = (value) => Boolean(value) && typeof value === "object" && Array.isArray(value.children);
2
+ export const getNodeAtTreePath = (document, path) => {
3
+ let node = document;
4
+ for (const index of path) {
5
+ if (!isSmartContainer(node) || !Number.isInteger(index) || index < 0 || index >= node.children.length) {
6
+ throw new Error("Path is out of bounds.");
7
+ }
8
+ node = node.children[index];
9
+ }
10
+ return node;
11
+ };
12
+ const parentAndIndex = (document, path) => {
13
+ if (path.length === 0)
14
+ throw new Error("Operation path cannot target the document root.");
15
+ const index = path[path.length - 1];
16
+ if (!Number.isInteger(index) || index < 0)
17
+ throw new Error("Path index must be a non-negative integer.");
18
+ const parentPath = path.slice(0, -1);
19
+ const parent = getNodeAtTreePath(document, parentPath);
20
+ if (!isSmartContainer(parent))
21
+ throw new Error("Path does not resolve to a document container.");
22
+ return { parent, parentPath, index };
23
+ };
2
24
  export const replaceNodeAtPath = (document, path, replacement) => {
3
25
  if (path.length === 0)
4
26
  return replacement;
@@ -16,3 +38,25 @@ export const replaceNodeAtPath = (document, path, replacement) => {
16
38
  };
17
39
  return replace(document, 0);
18
40
  };
41
+ export const insertNodeAtPath = (document, path, node) => {
42
+ const { parent, parentPath, index } = parentAndIndex(document, path);
43
+ if (index > parent.children.length)
44
+ throw new Error("Insert path is out of bounds.");
45
+ return replaceNodeAtPath(document, parentPath, {
46
+ ...parent,
47
+ children: [...parent.children.slice(0, index), node, ...parent.children.slice(index)],
48
+ });
49
+ };
50
+ export const removeNodeAtPath = (document, path) => {
51
+ const { parent, parentPath, index } = parentAndIndex(document, path);
52
+ if (index >= parent.children.length)
53
+ throw new Error("Remove path is out of bounds.");
54
+ const node = parent.children[index];
55
+ return {
56
+ document: replaceNodeAtPath(document, parentPath, {
57
+ ...parent,
58
+ children: [...parent.children.slice(0, index), ...parent.children.slice(index + 1)],
59
+ }),
60
+ node,
61
+ };
62
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "smartrte-core",
3
- "version": "0.2.0",
3
+ "version": "1.0.0-beta.1",
4
4
  "description": "Framework-agnostic document model and editing primitives for Smart RTE",
5
5
  "repository": {
6
6
  "type": "git",
@@ -15,6 +15,20 @@
15
15
  "main": "dist/index.js",
16
16
  "module": "dist/index.js",
17
17
  "types": "dist/index.d.ts",
18
+ "exports": {
19
+ ".": {
20
+ "types": "./dist/index.d.ts",
21
+ "import": "./dist/index.js"
22
+ },
23
+ "./foundation": {
24
+ "types": "./dist/foundation/index.d.ts",
25
+ "import": "./dist/foundation/index.js"
26
+ },
27
+ "./legacy": {
28
+ "types": "./dist/legacy/index.d.ts",
29
+ "import": "./dist/legacy/index.js"
30
+ }
31
+ },
18
32
  "files": [
19
33
  "dist",
20
34
  "!dist/**/*.test.js",
@@ -22,18 +36,18 @@
22
36
  "README.md",
23
37
  "CHANGELOG.md"
24
38
  ],
25
- "scripts": {
26
- "build": "tsc -p tsconfig.json",
27
- "prepublishOnly": "npm run build",
28
- "test": "vitest run",
29
- "lint": "tsc -p tsconfig.json --noEmit"
30
- },
31
39
  "publishConfig": {
32
40
  "access": "public"
33
41
  },
34
42
  "license": "MIT",
35
43
  "dependencies": {
44
+ "@xmldom/xmldom": "^0.9.11",
45
+ "dompurify": "^3.2.6",
46
+ "jszip": "^3.10.1",
47
+ "katex": "^0.18.4",
48
+ "mammoth": "^1.11.0",
36
49
  "parse5": "^7.2.1",
50
+ "pdfjs-dist": "^5.4.530",
37
51
  "rehype-stringify": "^10.0.1",
38
52
  "remark-gfm": "^4.0.1",
39
53
  "remark-parse": "^11.0.0",
@@ -43,5 +57,10 @@
43
57
  "devDependencies": {
44
58
  "typescript": "^5.6.2",
45
59
  "vitest": "^2.1.4"
60
+ },
61
+ "scripts": {
62
+ "build": "rm -rf dist && tsc -p tsconfig.json",
63
+ "test": "vitest run",
64
+ "lint": "tsc -p tsconfig.json --noEmit"
46
65
  }
47
- }
66
+ }