@ecsplico/editor 3.6.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 (578) hide show
  1. package/CHANGELOG.md +65 -0
  2. package/dist/adapters/direct-ai.d.ts +4 -4
  3. package/dist/adapters/direct-ai.js +2 -2
  4. package/dist/adapters/direct-ai.js.map +1 -1
  5. package/dist/adapters/document-state.d.ts +1 -1
  6. package/dist/adapters/document-state.js.map +1 -1
  7. package/dist/adapters/forge.d.ts +2 -2
  8. package/dist/adapters/forge.js.map +1 -1
  9. package/dist/adapters/nitro.d.ts +11 -3
  10. package/dist/adapters/nitro.js +3 -1
  11. package/dist/adapters/nitro.js.map +1 -1
  12. package/dist/adapters/shared.d.ts +6 -6
  13. package/dist/adapters/shared.js.map +1 -1
  14. package/dist/config/index.d.ts +14 -14
  15. package/dist/config/index.js +8 -8
  16. package/dist/config/index.js.map +1 -1
  17. package/dist/core/backend-types.d.ts +3 -3
  18. package/dist/core/backend-types.js.map +1 -1
  19. package/dist/core/backend.d.ts +4 -4
  20. package/dist/core/backend.js.map +1 -1
  21. package/dist/core/block-convert.d.ts +1 -1
  22. package/dist/core/block-convert.js +5 -5
  23. package/dist/core/block-convert.js.map +1 -1
  24. package/dist/core/block-transfer.d.ts +8 -4
  25. package/dist/core/block-transfer.js +23 -14
  26. package/dist/core/block-transfer.js.map +1 -1
  27. package/dist/core/capabilities.d.ts +113 -0
  28. package/dist/core/capabilities.js +155 -0
  29. package/dist/core/capabilities.js.map +1 -0
  30. package/dist/core/command-types.d.ts +1 -1
  31. package/dist/core/context.js.map +1 -1
  32. package/dist/core/convert.d.ts +5 -5
  33. package/dist/core/convert.js +5 -5
  34. package/dist/core/convert.js.map +1 -1
  35. package/dist/core/core-feature.js +1 -1
  36. package/dist/core/define-editor.d.ts +2 -2
  37. package/dist/core/define-editor.js +34 -6
  38. package/dist/core/define-editor.js.map +1 -1
  39. package/dist/core/derivation.d.ts +119 -0
  40. package/dist/core/derivation.js +187 -0
  41. package/dist/core/derivation.js.map +1 -0
  42. package/dist/core/derive.d.ts +61 -0
  43. package/dist/core/derive.js +69 -0
  44. package/dist/core/derive.js.map +1 -0
  45. package/dist/core/extension-points.d.ts +16 -0
  46. package/dist/core/feature-context.d.ts +5 -1
  47. package/dist/core/feature-context.js +10 -3
  48. package/dist/core/feature-context.js.map +1 -1
  49. package/dist/core/feature.d.ts +41 -19
  50. package/dist/core/feature.js.map +1 -1
  51. package/dist/core/fences.js +1 -1
  52. package/dist/core/fences.js.map +1 -1
  53. package/dist/core/index.d.ts +6 -2
  54. package/dist/core/index.js +5 -1
  55. package/dist/core/pipeline.d.ts +14 -5
  56. package/dist/core/pipeline.js +19 -7
  57. package/dist/core/pipeline.js.map +1 -1
  58. package/dist/core/properties.d.ts +22 -0
  59. package/dist/core/properties.js +17 -0
  60. package/dist/core/properties.js.map +1 -0
  61. package/dist/core/schema/block-ids.js +5 -5
  62. package/dist/core/schema/block-ids.js.map +1 -1
  63. package/dist/core/schema/index.d.ts +2 -1
  64. package/dist/core/schema/index.js +2 -1
  65. package/dist/core/schema/index.js.map +1 -1
  66. package/dist/core/schema/opaque-fence.d.ts +4 -4
  67. package/dist/core/schema/opaque-fence.js +7 -7
  68. package/dist/core/schema/opaque-fence.js.map +1 -1
  69. package/dist/core/schema/persisted-names.d.ts +58 -0
  70. package/dist/core/schema/persisted-names.js +96 -0
  71. package/dist/core/schema/persisted-names.js.map +1 -0
  72. package/dist/core/toolbar-items.js +1 -1
  73. package/dist/core/toolbar-items.js.map +1 -1
  74. package/dist/core/util.js +5 -1
  75. package/dist/core/util.js.map +1 -1
  76. package/dist/features/ai/agent-ops.js +1 -1
  77. package/dist/features/ai/ai-review.js +1 -1
  78. package/dist/features/ai/assistant.d.ts +4 -4
  79. package/dist/features/ai/assistant.js +1 -1
  80. package/dist/features/ai/assistant.js.map +1 -1
  81. package/dist/features/ai/components/AiSelectionMenu.js +1 -1
  82. package/dist/features/ai/components/AiSelectionMenu.js.map +1 -1
  83. package/dist/features/ai/components/ModelQuickSwitch.js +7 -7
  84. package/dist/features/ai/components/ModelQuickSwitch.js.map +1 -1
  85. package/dist/features/ai/components/ModelQuickSwitch.vue.d.ts +4 -4
  86. package/dist/features/ai/components/SettingsAiTab.js +8 -8
  87. package/dist/features/ai/components/SettingsAiTab.js.map +1 -1
  88. package/dist/features/ai/components/SettingsModelProfiles.js +1 -1
  89. package/dist/features/ai/components/SettingsModelProfiles.js.map +1 -1
  90. package/dist/features/ai/document-chat-model.d.ts +2 -2
  91. package/dist/features/ai/document-chat-model.js +5 -5
  92. package/dist/features/ai/document-chat-model.js.map +1 -1
  93. package/dist/features/ai/document-chat.js +2 -2
  94. package/dist/features/ai/document-chat.js.map +1 -1
  95. package/dist/features/ai/feature.d.ts +2 -2
  96. package/dist/features/ai/feature.js +2 -2
  97. package/dist/features/ai/feature.js.map +1 -1
  98. package/dist/features/ai/ghost-autocomplete.d.ts +4 -4
  99. package/dist/features/ai/ghost-autocomplete.js +1 -1
  100. package/dist/features/ai/ghost-autocomplete.js.map +1 -1
  101. package/dist/features/ai/index.d.ts +3 -3
  102. package/dist/features/ai/index.js +2 -2
  103. package/dist/features/ai/model-profiles.d.ts +9 -9
  104. package/dist/features/ai/model-profiles.js +13 -13
  105. package/dist/features/ai/model-profiles.js.map +1 -1
  106. package/dist/features/ai/protocol/agent-ops.d.ts +2 -2
  107. package/dist/features/ai/protocol/agent-ops.js +1 -1
  108. package/dist/features/ai/protocol/agent-ops.js.map +1 -1
  109. package/dist/features/ai/protocol/block-lines.d.ts +7 -7
  110. package/dist/features/ai/protocol/block-lines.js +10 -10
  111. package/dist/features/ai/protocol/block-lines.js.map +1 -1
  112. package/dist/features/ai/protocol/chat.d.ts +5 -5
  113. package/dist/features/ai/protocol/chat.js +12 -12
  114. package/dist/features/ai/protocol/chat.js.map +1 -1
  115. package/dist/features/ai/protocol/generate.d.ts +1 -1
  116. package/dist/features/ai/protocol/generate.js +1 -1
  117. package/dist/features/ai/protocol/generate.js.map +1 -1
  118. package/dist/features/ai/protocol/index.d.ts +3 -3
  119. package/dist/features/ai/protocol/index.js +2 -2
  120. package/dist/features/ai/protocol/models.d.ts +3 -3
  121. package/dist/features/ai/protocol/models.js +3 -3
  122. package/dist/features/ai/protocol/models.js.map +1 -1
  123. package/dist/features/ai/protocol/schemas.d.ts +1 -1
  124. package/dist/features/ai/protocol/schemas.js +1 -1
  125. package/dist/features/ai/protocol/schemas.js.map +1 -1
  126. package/dist/features/ai/protocol/tasks.d.ts +5 -5
  127. package/dist/features/ai/protocol/tasks.js +12 -12
  128. package/dist/features/ai/protocol/tasks.js.map +1 -1
  129. package/dist/features/ai/react/AiSelectionMenu.js.map +1 -1
  130. package/dist/features/ai/react/ModelQuickSwitch.d.ts +4 -4
  131. package/dist/features/ai/react/ModelQuickSwitch.js +6 -6
  132. package/dist/features/ai/react/ModelQuickSwitch.js.map +1 -1
  133. package/dist/features/ai/react/SettingsAiTab.d.ts +1 -1
  134. package/dist/features/ai/react/SettingsAiTab.js +8 -8
  135. package/dist/features/ai/react/SettingsAiTab.js.map +1 -1
  136. package/dist/features/ai/react/SettingsModelProfiles.d.ts +1 -1
  137. package/dist/features/ai/react/SettingsModelProfiles.js +1 -1
  138. package/dist/features/ai/react/SettingsModelProfiles.js.map +1 -1
  139. package/dist/features/ai/react/use-ai-assistant.d.ts +1 -1
  140. package/dist/features/ai/react/use-ai-assistant.js +1 -1
  141. package/dist/features/ai/react/use-ai-assistant.js.map +1 -1
  142. package/dist/features/ai/react/use-model-profiles.d.ts +5 -5
  143. package/dist/features/ai/react/use-model-profiles.js +2 -2
  144. package/dist/features/ai/react/use-model-profiles.js.map +1 -1
  145. package/dist/features/ai/use-ai-assistant.d.ts +1 -1
  146. package/dist/features/ai/use-ai-assistant.js +1 -1
  147. package/dist/features/ai/use-ai-assistant.js.map +1 -1
  148. package/dist/features/ai/use-model-profiles.d.ts +4 -4
  149. package/dist/features/ai/use-model-profiles.js +2 -2
  150. package/dist/features/ai/use-model-profiles.js.map +1 -1
  151. package/dist/features/block-ui/block-actions.d.ts +8 -4
  152. package/dist/features/block-ui/block-actions.js +38 -22
  153. package/dist/features/block-ui/block-actions.js.map +1 -1
  154. package/dist/features/block-ui/block-target.d.ts +29 -0
  155. package/dist/features/block-ui/block-target.js +63 -0
  156. package/dist/features/block-ui/block-target.js.map +1 -0
  157. package/dist/features/block-ui/components/BlockHandles.js +3 -3
  158. package/dist/features/block-ui/components/BlockHandles.js.map +1 -1
  159. package/dist/features/block-ui/components/BlockUi.js +11 -23
  160. package/dist/features/block-ui/components/BlockUi.js.map +1 -1
  161. package/dist/features/block-ui/feature.d.ts +3 -2
  162. package/dist/features/block-ui/feature.js +3 -2
  163. package/dist/features/block-ui/feature.js.map +1 -1
  164. package/dist/features/block-ui/handle-geometry.js +12 -23
  165. package/dist/features/block-ui/handle-geometry.js.map +1 -1
  166. package/dist/features/block-ui/index.d.ts +2 -1
  167. package/dist/features/block-ui/index.js +2 -1
  168. package/dist/features/block-ui/react/BlockHandles.d.ts +1 -1
  169. package/dist/features/block-ui/react/BlockHandles.js +4 -4
  170. package/dist/features/block-ui/react/BlockHandles.js.map +1 -1
  171. package/dist/features/block-ui/react/BlockUi.js +13 -25
  172. package/dist/features/block-ui/react/BlockUi.js.map +1 -1
  173. package/dist/features/comments/model.js +1 -1
  174. package/dist/features/composites/accepted-children.d.ts +5 -4
  175. package/dist/features/composites/accepted-children.js +26 -26
  176. package/dist/features/composites/accepted-children.js.map +1 -1
  177. package/dist/features/composites/ai-brief.d.ts +4 -4
  178. package/dist/features/composites/ai-brief.js +14 -12
  179. package/dist/features/composites/ai-brief.js.map +1 -1
  180. package/dist/features/composites/anchors.d.ts +1 -1
  181. package/dist/features/composites/anchors.js.map +1 -1
  182. package/dist/features/composites/baskets.d.ts +1 -1
  183. package/dist/features/composites/baskets.js.map +1 -1
  184. package/dist/features/composites/bibliography-command.d.ts +1 -1
  185. package/dist/features/composites/bibliography-form.js +1 -1
  186. package/dist/features/composites/bibliography-form.js.map +1 -1
  187. package/dist/features/composites/bibliography.js.map +1 -1
  188. package/dist/features/composites/block-types-json.d.ts +38 -0
  189. package/dist/features/composites/block-types-json.js +122 -0
  190. package/dist/features/composites/block-types-json.js.map +1 -0
  191. package/dist/features/composites/block-types.d.ts +119 -0
  192. package/dist/features/composites/block-types.js +343 -0
  193. package/dist/features/composites/block-types.js.map +1 -0
  194. package/dist/features/composites/capabilities.js +109 -0
  195. package/dist/features/composites/capabilities.js.map +1 -0
  196. package/dist/features/composites/components/BibliographyEditor.js +5 -5
  197. package/dist/features/composites/components/BibliographyEditor.js.map +1 -1
  198. package/dist/features/composites/components/CompositeBasketMenu.js +2 -2
  199. package/dist/features/composites/components/CompositeBasketMenu.js.map +1 -1
  200. package/dist/features/composites/components/CompositeChrome.js +18 -8
  201. package/dist/features/composites/components/CompositeChrome.js.map +1 -1
  202. package/dist/features/composites/components/CompositeChrome.vue.d.ts +1 -1
  203. package/dist/features/composites/components/CompositeDetails.js +11 -10
  204. package/dist/features/composites/components/CompositeDetails.js.map +1 -1
  205. package/dist/features/composites/components/CompositeDetails.vue.d.ts +1 -1
  206. package/dist/features/composites/components/CompositeFieldEditor.js +7 -7
  207. package/dist/features/composites/components/CompositeFieldEditor.js.map +1 -1
  208. package/dist/features/composites/components/CompositeFieldEditor.vue.d.ts +5 -5
  209. package/dist/features/composites/components/CompositeInspector.js +136 -113
  210. package/dist/features/composites/components/CompositeInspector.js.map +1 -1
  211. package/dist/features/composites/components/CompositeInspector.vue.d.ts +3 -3
  212. package/dist/features/composites/components/CompositeStatusMenu.js +2 -2
  213. package/dist/features/composites/components/CompositeStatusMenu.js.map +1 -1
  214. package/dist/features/composites/components/CompositeSummaryEditor.js +1 -1
  215. package/dist/features/composites/components/CompositeSummaryEditor.js.map +1 -1
  216. package/dist/features/composites/components/CompositeSummaryEditor.vue.d.ts +1 -1
  217. package/dist/features/composites/components/CompositeTable.js +2 -2
  218. package/dist/features/composites/components/CompositeTable.js.map +1 -1
  219. package/dist/features/composites/components/CompositeTagsEditor.js +1 -1
  220. package/dist/features/composites/components/CompositeTagsEditor.js.map +1 -1
  221. package/dist/features/composites/components/CompositeTagsEditor.vue.d.ts +1 -1
  222. package/dist/features/composites/components/CompositeView.js +19 -17
  223. package/dist/features/composites/components/CompositeView.js.map +1 -1
  224. package/dist/features/composites/components/DerivationBadge.js +15 -6
  225. package/dist/features/composites/components/DerivationBadge.js.map +1 -1
  226. package/dist/features/composites/components/FocusChip.js +1 -1
  227. package/dist/features/composites/components/FocusChip.js.map +1 -1
  228. package/dist/features/composites/components/FocusChip.vue.d.ts +1 -1
  229. package/dist/features/composites/components/ReferenceFieldSelect.js +3 -3
  230. package/dist/features/composites/components/ReferenceFieldSelect.js.map +1 -1
  231. package/dist/features/composites/components/ReferenceView.js +1 -1
  232. package/dist/features/composites/components/ReferenceView.js.map +1 -1
  233. package/dist/features/composites/components/SettingsEditingTab.js +18 -18
  234. package/dist/features/composites/components/SettingsEditingTab.js.map +1 -1
  235. package/dist/features/composites/components/SettingsEditingTab.vue.d.ts +3 -3
  236. package/dist/features/composites/convert.d.ts +4 -4
  237. package/dist/features/composites/convert.js +27 -28
  238. package/dist/features/composites/convert.js.map +1 -1
  239. package/dist/features/composites/derived-chrome.js +34 -28
  240. package/dist/features/composites/derived-chrome.js.map +1 -1
  241. package/dist/features/composites/editing-settings-keys.js +6 -6
  242. package/dist/features/composites/editing-settings-keys.js.map +1 -1
  243. package/dist/features/composites/feature.d.ts +10 -10
  244. package/dist/features/composites/feature.js +58 -46
  245. package/dist/features/composites/feature.js.map +1 -1
  246. package/dist/features/composites/fences.d.ts +3 -3
  247. package/dist/features/composites/fences.js +18 -13
  248. package/dist/features/composites/fences.js.map +1 -1
  249. package/dist/features/composites/focus.d.ts +10 -10
  250. package/dist/features/composites/focus.js +11 -11
  251. package/dist/features/composites/focus.js.map +1 -1
  252. package/dist/features/composites/heading-composites.d.ts +5 -5
  253. package/dist/features/composites/heading-composites.js +13 -16
  254. package/dist/features/composites/heading-composites.js.map +1 -1
  255. package/dist/features/composites/index.d.ts +20 -18
  256. package/dist/features/composites/index.js +9 -7
  257. package/dist/features/composites/inspector-model.d.ts +45 -22
  258. package/dist/features/composites/inspector-model.js +53 -14
  259. package/dist/features/composites/inspector-model.js.map +1 -1
  260. package/dist/features/composites/legacy.d.ts +5 -4
  261. package/dist/features/composites/legacy.js +16 -23
  262. package/dist/features/composites/legacy.js.map +1 -1
  263. package/dist/features/composites/markdown-export.js +3 -3
  264. package/dist/features/composites/markdown-export.js.map +1 -1
  265. package/dist/features/composites/merge.d.ts +8 -8
  266. package/dist/features/composites/merge.js +23 -22
  267. package/dist/features/composites/merge.js.map +1 -1
  268. package/dist/features/composites/meta-display.js +5 -5
  269. package/dist/features/composites/meta-display.js.map +1 -1
  270. package/dist/features/composites/meta-keys.d.ts +5 -5
  271. package/dist/features/composites/meta-keys.js +8 -8
  272. package/dist/features/composites/meta-keys.js.map +1 -1
  273. package/dist/features/composites/node-views.d.ts +3 -3
  274. package/dist/features/composites/node-views.js +2 -2
  275. package/dist/features/composites/node-views.js.map +1 -1
  276. package/dist/features/composites/nodes.d.ts +13 -13
  277. package/dist/features/composites/nodes.js +100 -77
  278. package/dist/features/composites/nodes.js.map +1 -1
  279. package/dist/features/composites/outline.d.ts +15 -12
  280. package/dist/features/composites/outline.js +24 -21
  281. package/dist/features/composites/outline.js.map +1 -1
  282. package/dist/features/composites/properties.d.ts +51 -0
  283. package/dist/features/composites/properties.js +89 -0
  284. package/dist/features/composites/properties.js.map +1 -0
  285. package/dist/features/composites/react/BibliographyEditor.js +5 -5
  286. package/dist/features/composites/react/BibliographyEditor.js.map +1 -1
  287. package/dist/features/composites/react/CompositeBasketMenu.js +2 -2
  288. package/dist/features/composites/react/CompositeBasketMenu.js.map +1 -1
  289. package/dist/features/composites/react/CompositeChrome.d.ts +1 -1
  290. package/dist/features/composites/react/CompositeChrome.js +15 -6
  291. package/dist/features/composites/react/CompositeChrome.js.map +1 -1
  292. package/dist/features/composites/react/CompositeDetails.d.ts +1 -1
  293. package/dist/features/composites/react/CompositeDetails.js +11 -10
  294. package/dist/features/composites/react/CompositeDetails.js.map +1 -1
  295. package/dist/features/composites/react/CompositeFieldEditor.d.ts +5 -5
  296. package/dist/features/composites/react/CompositeFieldEditor.js +6 -6
  297. package/dist/features/composites/react/CompositeFieldEditor.js.map +1 -1
  298. package/dist/features/composites/react/CompositeInspector.d.ts +3 -3
  299. package/dist/features/composites/react/CompositeInspector.js +142 -128
  300. package/dist/features/composites/react/CompositeInspector.js.map +1 -1
  301. package/dist/features/composites/react/CompositeStatusMenu.js +2 -2
  302. package/dist/features/composites/react/CompositeStatusMenu.js.map +1 -1
  303. package/dist/features/composites/react/CompositeSummaryEditor.d.ts +1 -1
  304. package/dist/features/composites/react/CompositeSummaryEditor.js +1 -1
  305. package/dist/features/composites/react/CompositeSummaryEditor.js.map +1 -1
  306. package/dist/features/composites/react/CompositeTable.d.ts +1 -1
  307. package/dist/features/composites/react/CompositeTable.js +3 -3
  308. package/dist/features/composites/react/CompositeTable.js.map +1 -1
  309. package/dist/features/composites/react/CompositeTagsEditor.d.ts +1 -1
  310. package/dist/features/composites/react/CompositeTagsEditor.js +1 -1
  311. package/dist/features/composites/react/CompositeTagsEditor.js.map +1 -1
  312. package/dist/features/composites/react/CompositeView.js +17 -15
  313. package/dist/features/composites/react/CompositeView.js.map +1 -1
  314. package/dist/features/composites/react/DerivationBadge.js +13 -4
  315. package/dist/features/composites/react/DerivationBadge.js.map +1 -1
  316. package/dist/features/composites/react/FocusChip.d.ts +1 -1
  317. package/dist/features/composites/react/FocusChip.js +1 -1
  318. package/dist/features/composites/react/FocusChip.js.map +1 -1
  319. package/dist/features/composites/react/ReferenceFieldSelect.js +3 -3
  320. package/dist/features/composites/react/ReferenceFieldSelect.js.map +1 -1
  321. package/dist/features/composites/react/ReferenceView.d.ts +1 -1
  322. package/dist/features/composites/react/ReferenceView.js +1 -1
  323. package/dist/features/composites/react/ReferenceView.js.map +1 -1
  324. package/dist/features/composites/react/SettingsEditingTab.d.ts +4 -4
  325. package/dist/features/composites/react/SettingsEditingTab.js +20 -20
  326. package/dist/features/composites/react/SettingsEditingTab.js.map +1 -1
  327. package/dist/features/composites/react.js +1 -1
  328. package/dist/features/composites/react.js.map +1 -1
  329. package/dist/features/composites/reference-ai.js +1 -1
  330. package/dist/features/composites/reference-ai.js.map +1 -1
  331. package/dist/features/composites/reference-label.d.ts +3 -3
  332. package/dist/features/composites/reference-label.js +6 -6
  333. package/dist/features/composites/reference-label.js.map +1 -1
  334. package/dist/features/composites/reference-suggestion.d.ts +1 -1
  335. package/dist/features/composites/reference-suggestion.js +3 -3
  336. package/dist/features/composites/reference-suggestion.js.map +1 -1
  337. package/dist/features/composites/reference-text.d.ts +2 -2
  338. package/dist/features/composites/reference-text.js +4 -4
  339. package/dist/features/composites/reference-text.js.map +1 -1
  340. package/dist/features/composites/reference.d.ts +3 -3
  341. package/dist/features/composites/reference.js +1 -1
  342. package/dist/features/composites/reference.js.map +1 -1
  343. package/dist/features/composites/reveal-source.d.ts +3 -3
  344. package/dist/features/composites/reveal-source.js +6 -6
  345. package/dist/features/composites/reveal-source.js.map +1 -1
  346. package/dist/features/composites/rows-model.d.ts +2 -2
  347. package/dist/features/composites/rows-model.js +4 -3
  348. package/dist/features/composites/rows-model.js.map +1 -1
  349. package/dist/features/composites/rows.d.ts +16 -28
  350. package/dist/features/composites/rows.js +20 -54
  351. package/dist/features/composites/rows.js.map +1 -1
  352. package/dist/features/composites/schema.d.ts +12 -11
  353. package/dist/features/composites/schema.js +10 -9
  354. package/dist/features/composites/schema.js.map +1 -1
  355. package/dist/features/composites/source.d.ts +20 -0
  356. package/dist/features/composites/source.js +40 -0
  357. package/dist/features/composites/source.js.map +1 -0
  358. package/dist/features/composites/split.d.ts +11 -11
  359. package/dist/features/composites/split.js +20 -20
  360. package/dist/features/composites/split.js.map +1 -1
  361. package/dist/features/composites/structure-mode.js +3 -3
  362. package/dist/features/composites/structure-mode.js.map +1 -1
  363. package/dist/features/composites/table-model.js +2 -2
  364. package/dist/features/composites/table-model.js.map +1 -1
  365. package/dist/features/composites/use-composite-inspector.js +3 -1
  366. package/dist/features/composites/use-composite-inspector.js.map +1 -1
  367. package/dist/features/composites/use-composite-rows.d.ts +2 -2
  368. package/dist/features/composites/use-composite-rows.js.map +1 -1
  369. package/dist/features/composites/vue.js +1 -1
  370. package/dist/features/composites/vue.js.map +1 -1
  371. package/dist/features/image-studio/components/ImageStudioDialog.js +1 -1
  372. package/dist/features/image-studio/components/ImageStudioDialog.js.map +1 -1
  373. package/dist/features/image-studio/components/ImageStudioDialog.vue.d.ts +1 -1
  374. package/dist/features/image-studio/components/ImageStudioView.js.map +1 -1
  375. package/dist/features/image-studio/feature.d.ts +1 -1
  376. package/dist/features/image-studio/feature.js +1 -1
  377. package/dist/features/image-studio/feature.js.map +1 -1
  378. package/dist/features/image-studio/node-core.d.ts +3 -3
  379. package/dist/features/image-studio/node-core.js +1 -1
  380. package/dist/features/image-studio/node-core.js.map +1 -1
  381. package/dist/features/image-studio/node-store.d.ts +1 -1
  382. package/dist/features/image-studio/node-store.js +1 -1
  383. package/dist/features/image-studio/node-store.js.map +1 -1
  384. package/dist/features/image-studio/react/ImageStudioDialog.d.ts +1 -1
  385. package/dist/features/image-studio/react/ImageStudioDialog.js +1 -1
  386. package/dist/features/image-studio/react/ImageStudioDialog.js.map +1 -1
  387. package/dist/features/image-studio/react/ImageStudioView.js +1 -1
  388. package/dist/features/image-studio/react/ImageStudioView.js.map +1 -1
  389. package/dist/features/image-studio/react/store.d.ts +3 -3
  390. package/dist/features/image-studio/react/store.js.map +1 -1
  391. package/dist/features/image-studio/react.d.ts +1 -1
  392. package/dist/features/image-studio/react.js +1 -1
  393. package/dist/features/image-studio/react.js.map +1 -1
  394. package/dist/features/image-studio/schema.d.ts +1 -1
  395. package/dist/features/image-studio/schema.js +1 -1
  396. package/dist/features/image-studio/schema.js.map +1 -1
  397. package/dist/features/image-studio/state.d.ts +3 -3
  398. package/dist/features/image-studio/state.js +2 -2
  399. package/dist/features/image-studio/state.js.map +1 -1
  400. package/dist/features/image-studio/store.d.ts +3 -3
  401. package/dist/features/image-studio/vue.d.ts +1 -1
  402. package/dist/features/image-studio/vue.js +1 -1
  403. package/dist/features/image-studio/vue.js.map +1 -1
  404. package/dist/features/media/index.js +1 -1
  405. package/dist/features/media/react/AudioRecorderModal.js +1 -1
  406. package/dist/features/media/react.js +1 -1
  407. package/dist/features/mentions/tag.js +2 -1
  408. package/dist/features/mentions/tag.js.map +1 -1
  409. package/dist/features/themes/components/SettingsAppearanceTab.js +1 -1
  410. package/dist/features/themes/components/SettingsAppearanceTab.js.map +1 -1
  411. package/dist/features/themes/feature.d.ts +1 -1
  412. package/dist/features/themes/feature.js.map +1 -1
  413. package/dist/features/themes/react/SettingsAppearanceTab.d.ts +1 -1
  414. package/dist/features/themes/react/SettingsAppearanceTab.js +1 -1
  415. package/dist/features/themes/react/SettingsAppearanceTab.js.map +1 -1
  416. package/dist/features/themes/theme-runtime.js +1 -1
  417. package/dist/features/themes/theme-runtime.js.map +1 -1
  418. package/dist/features/transcript/TranscriptSegmentView.js +1 -1
  419. package/dist/features/transcript/TranscriptSegmentView.js.map +1 -1
  420. package/dist/features/transcript/react/TranscriptSegmentView.js +1 -1
  421. package/dist/features/transcript/react/TranscriptSegmentView.js.map +1 -1
  422. package/dist/features/transcript/segment-node.js.map +1 -1
  423. package/dist/features/transfer/feature.js +1 -1
  424. package/dist/features/transfer/feature.js.map +1 -1
  425. package/dist/features/transfer/transforms.d.ts +4 -4
  426. package/dist/features/transfer/transforms.js +12 -12
  427. package/dist/features/transfer/transforms.js.map +1 -1
  428. package/dist/i18n/de/ai.js +4 -4
  429. package/dist/i18n/de/ai.js.map +1 -1
  430. package/dist/i18n/de/authors.js +1 -1
  431. package/dist/i18n/de/authors.js.map +1 -1
  432. package/dist/i18n/de/comments.js +1 -1
  433. package/dist/i18n/de/comments.js.map +1 -1
  434. package/dist/i18n/de/composites.js +62 -59
  435. package/dist/i18n/de/composites.js.map +1 -1
  436. package/dist/i18n/de/image-studio.js +2 -2
  437. package/dist/i18n/de/image-studio.js.map +1 -1
  438. package/dist/i18n/de/integrations.js +20 -20
  439. package/dist/i18n/de/integrations.js.map +1 -1
  440. package/dist/i18n/de/markdown.js +1 -1
  441. package/dist/i18n/de/markdown.js.map +1 -1
  442. package/dist/i18n/de/palette.js +1 -1
  443. package/dist/i18n/de/palette.js.map +1 -1
  444. package/dist/i18n/de/themes.js +3 -3
  445. package/dist/i18n/de/themes.js.map +1 -1
  446. package/dist/i18n/de/transfer.js +2 -2
  447. package/dist/i18n/de/transfer.js.map +1 -1
  448. package/dist/i18n/de/tree.js +6 -6
  449. package/dist/i18n/de/tree.js.map +1 -1
  450. package/dist/i18n/de.d.ts +101 -98
  451. package/dist/i18n/en/ai.js +2 -2
  452. package/dist/i18n/en/ai.js.map +1 -1
  453. package/dist/i18n/en/composites.js +64 -61
  454. package/dist/i18n/en/composites.js.map +1 -1
  455. package/dist/i18n/en/integrations.js +9 -9
  456. package/dist/i18n/en/integrations.js.map +1 -1
  457. package/dist/i18n/en/markdown.js +1 -1
  458. package/dist/i18n/en/markdown.js.map +1 -1
  459. package/dist/i18n/en/palette.js +1 -1
  460. package/dist/i18n/en/palette.js.map +1 -1
  461. package/dist/i18n/en/themes.js +4 -4
  462. package/dist/i18n/en/themes.js.map +1 -1
  463. package/dist/i18n/en/tree.js +5 -5
  464. package/dist/i18n/en/tree.js.map +1 -1
  465. package/dist/index.d.ts +4 -1
  466. package/dist/integrations/composite-ai/bibliography-fetch.d.ts +6 -6
  467. package/dist/integrations/composite-ai/bibliography-fetch.js +19 -19
  468. package/dist/integrations/composite-ai/bibliography-fetch.js.map +1 -1
  469. package/dist/integrations/composite-ai/composite-fill.d.ts +4 -4
  470. package/dist/integrations/composite-ai/composite-fill.js +5 -5
  471. package/dist/integrations/composite-ai/composite-fill.js.map +1 -1
  472. package/dist/integrations/composite-ai/composite-summary.d.ts +2 -2
  473. package/dist/integrations/composite-ai/composite-summary.js +5 -5
  474. package/dist/integrations/composite-ai/composite-summary.js.map +1 -1
  475. package/dist/integrations/composite-ai/derive.d.ts +17 -17
  476. package/dist/integrations/composite-ai/derive.js +27 -26
  477. package/dist/integrations/composite-ai/derive.js.map +1 -1
  478. package/dist/integrations/composite-ai/index.d.ts +14 -15
  479. package/dist/integrations/composite-ai/index.js +98 -77
  480. package/dist/integrations/composite-ai/index.js.map +1 -1
  481. package/dist/integrations/composite-ai/outline-sanitize.d.ts +1 -1
  482. package/dist/integrations/composite-ai/outline-sanitize.js +1 -1
  483. package/dist/integrations/composite-ai/outline-sanitize.js.map +1 -1
  484. package/dist/integrations/composite-ai/rendition.d.ts +9 -9
  485. package/dist/integrations/composite-ai/rendition.js +27 -27
  486. package/dist/integrations/composite-ai/rendition.js.map +1 -1
  487. package/dist/integrations/composite-ai/split.d.ts +8 -8
  488. package/dist/integrations/composite-ai/split.js +12 -12
  489. package/dist/integrations/composite-ai/split.js.map +1 -1
  490. package/dist/integrations/composite-ai/transfer-transforms.d.ts +2 -2
  491. package/dist/integrations/composite-ai/transfer-transforms.js +12 -12
  492. package/dist/integrations/composite-ai/transfer-transforms.js.map +1 -1
  493. package/dist/integrations/composite-media/index.d.ts +4 -3
  494. package/dist/integrations/composite-media/index.js +20 -14
  495. package/dist/integrations/composite-media/index.js.map +1 -1
  496. package/dist/markdown/document.js +1 -1
  497. package/dist/markdown/document.js.map +1 -1
  498. package/dist/nuxt/module.d.ts +30 -24
  499. package/dist/nuxt/module.js.map +1 -1
  500. package/dist/nuxt/runtime/server/plugins/editor-server.js +3 -2
  501. package/dist/nuxt/runtime/server/plugins/editor-server.js.map +1 -1
  502. package/dist/presets/compose.d.ts +6 -6
  503. package/dist/presets/compose.js +8 -5
  504. package/dist/presets/compose.js.map +1 -1
  505. package/dist/react/AdvancedEditor.d.ts +2 -2
  506. package/dist/react/AdvancedEditor.js +1 -1
  507. package/dist/react/AdvancedEditor.js.map +1 -1
  508. package/dist/react/compose.d.ts +1 -1
  509. package/dist/react/compose.js +2 -2
  510. package/dist/react/compose.js.map +1 -1
  511. package/dist/react/composed-surface.d.ts +5 -5
  512. package/dist/react/composed-surface.js +2 -2
  513. package/dist/react/composed-surface.js.map +1 -1
  514. package/dist/server/ai.d.ts +7 -7
  515. package/dist/server/ai.js +1 -1
  516. package/dist/server/ai.js.map +1 -1
  517. package/dist/server/auth.d.ts +1 -1
  518. package/dist/server/collab-state.d.ts +1 -1
  519. package/dist/server/collab-state.js.map +1 -1
  520. package/dist/server/collab.d.ts +4 -4
  521. package/dist/server/collab.js +22 -17
  522. package/dist/server/collab.js.map +1 -1
  523. package/dist/server/handlers/ai.d.ts +7 -4
  524. package/dist/server/handlers/ai.js +13 -17
  525. package/dist/server/handlers/ai.js.map +1 -1
  526. package/dist/server/handlers/context.d.ts +4 -0
  527. package/dist/server/handlers/context.js.map +1 -1
  528. package/dist/server/handlers/editor.d.ts +33 -32
  529. package/dist/server/handlers/editor.js +13 -8
  530. package/dist/server/handlers/editor.js.map +1 -1
  531. package/dist/server/handlers/images.d.ts +1 -1
  532. package/dist/server/handlers/images.js +1 -1
  533. package/dist/server/handlers/images.js.map +1 -1
  534. package/dist/server/host.d.ts +4 -0
  535. package/dist/server/host.js +10 -2
  536. package/dist/server/host.js.map +1 -1
  537. package/dist/server/index.d.ts +3 -3
  538. package/dist/server/ports.d.ts +8 -8
  539. package/dist/server/ports.js.map +1 -1
  540. package/dist/settings/index.d.ts +20 -19
  541. package/dist/settings/index.js +25 -24
  542. package/dist/settings/index.js.map +1 -1
  543. package/dist/settings/migrate.d.ts +18 -0
  544. package/dist/settings/migrate.js +46 -0
  545. package/dist/settings/migrate.js.map +1 -0
  546. package/dist/settings/values.d.ts +12 -12
  547. package/dist/settings/values.js +11 -11
  548. package/dist/settings/values.js.map +1 -1
  549. package/dist/styles/composites.css +10 -10
  550. package/dist/tree/DocumentTree.js +12 -5
  551. package/dist/tree/DocumentTree.js.map +1 -1
  552. package/dist/tree/drop-rules.js +5 -5
  553. package/dist/tree/drop-rules.js.map +1 -1
  554. package/dist/tree/react/DocumentTree.js +14 -5
  555. package/dist/tree/react/DocumentTree.js.map +1 -1
  556. package/dist/tree/tree-host.js +6 -6
  557. package/dist/tree/tree-host.js.map +1 -1
  558. package/dist/tree/tree-items.js +34 -28
  559. package/dist/tree/tree-items.js.map +1 -1
  560. package/dist/tree/tree-model.js +16 -16
  561. package/dist/tree/tree-model.js.map +1 -1
  562. package/dist/tree/tree-rows.js +2 -2
  563. package/dist/tree/tree-rows.js.map +1 -1
  564. package/dist/tree/tree-view-model.d.ts +2 -2
  565. package/dist/tree/tree-view-model.js.map +1 -1
  566. package/dist/vue/AdvancedEditor.js +2 -2
  567. package/dist/vue/AdvancedEditor.js.map +1 -1
  568. package/dist/vue/AdvancedEditor.vue.d.ts +6 -6
  569. package/dist/vue/compose.d.ts +1 -1
  570. package/dist/vue/compose.js +2 -2
  571. package/dist/vue/compose.js.map +1 -1
  572. package/package.json +1 -1
  573. package/dist/features/composites/derivation.d.ts +0 -62
  574. package/dist/features/composites/derivation.js +0 -102
  575. package/dist/features/composites/derivation.js.map +0 -1
  576. package/dist/features/composites/kinds.d.ts +0 -89
  577. package/dist/features/composites/kinds.js +0 -285
  578. package/dist/features/composites/kinds.js.map +0 -1
@@ -0,0 +1,17 @@
1
+ //#region src/core/properties.ts
2
+ /** The value types of a Block property. */
3
+ const PROPERTY_TYPES = [
4
+ "text",
5
+ "textarea",
6
+ "date",
7
+ "number",
8
+ "select",
9
+ "multiselect",
10
+ "reference",
11
+ "bibliography",
12
+ "derivation"
13
+ ];
14
+ //#endregion
15
+ export { PROPERTY_TYPES };
16
+
17
+ //# sourceMappingURL=properties.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"properties.js","names":[],"sources":["../../src/core/properties.ts"],"sourcesContent":["// Framework-free and server-importable: the one Property definition type. Block types (`properties` capability config), the\n// inspector, the AI context (`AiContextBlockType.fields`) and the server's request schemas all describe a Block property with it.\n\n/** The value types of a Block property. */\nexport const PROPERTY_TYPES = ['text', 'textarea', 'date', 'number', 'select', 'multiselect', 'reference', 'bibliography', 'derivation'] as const\n\n/** One Property definition: a Block property stored under `key` in the block's `meta` attribute. */\nexport interface PropertyDefinition {\n key: string\n label: string\n /**\n * `bibliography`: CSL-JSON item under `meta.bib`; `derivation`: read-only Derivation of a Derived block; `reference`: block id of another Typed block;\n * `multiselect`: several of `options`, stored as `string[]` (the key is removed when none is chosen).\n */\n type: typeof PROPERTY_TYPES[number]\n /** Choices of a `select` or `multiselect` property (required for `multiselect`). */\n options?: { value: string, label: string }[]\n /** `reference`: Block type ids the property may point to; absent = any Typed block. */\n targets?: readonly string[]\n}\n"],"mappings":";;AAIA,MAAa,iBAAiB;CAAC;CAAQ;CAAY;CAAQ;CAAU;CAAU;CAAe;CAAa;CAAgB;AAAY"}
@@ -20,10 +20,10 @@ const BLOCK_ID_TYPES = [
20
20
  "file",
21
21
  "horizontalRule",
22
22
  "transcriptSegment",
23
- "composite"
23
+ "typedBlock"
24
24
  ];
25
25
  /** The node types among `extensions` that carry a block ID: `editorBlock` declared, else built-in (same rule as `NodeFlags`). */
26
- const blockTypesOf = (extensions) => splitExtensions(extensions).nodeExtensions.filter((ext) => getExtensionField(ext, "editorBlock") ?? BLOCK_ID_TYPES.includes(ext.name)).map((ext) => ext.name);
26
+ const nodeTypeNamesOf = (extensions) => splitExtensions(extensions).nodeExtensions.filter((ext) => getExtensionField(ext, "editorBlock") ?? BLOCK_ID_TYPES.includes(ext.name)).map((ext) => ext.name);
27
27
  const carriesId = (node) => node.type.spec.editorBlock === true;
28
28
  /** A fresh block ID (UUID v4; unlike `crypto.randomUUID()` also available outside secure contexts). */
29
29
  const newBlockId = () => v4();
@@ -109,17 +109,17 @@ const dedupeInserted = () => new Plugin({
109
109
  */
110
110
  const BlockId = UniqueID.extend({
111
111
  addGlobalAttributes() {
112
- this.options.types = blockTypesOf(this.extensions);
112
+ this.options.types = nodeTypeNamesOf(this.extensions);
113
113
  return this.parent?.() ?? [];
114
114
  },
115
115
  onCreate(event) {
116
116
  const { extensions } = this.editor.extensionManager;
117
117
  if (extensions.some((ext) => ext.name === "collaboration")) return;
118
- this.options.types = blockTypesOf(extensions);
118
+ this.options.types = nodeTypeNamesOf(extensions);
119
119
  this.parent?.(event);
120
120
  },
121
121
  addProseMirrorPlugins() {
122
- this.options.types = blockTypesOf(this.editor.extensionManager.extensions);
122
+ this.options.types = nodeTypeNamesOf(this.editor.extensionManager.extensions);
123
123
  const plugins = this.parent?.() ?? [];
124
124
  this.storage.needsInitialIdGeneration = false;
125
125
  return [...plugins, dedupeInserted()];
@@ -1 +1 @@
1
- {"version":3,"file":"block-ids.js","names":["uuidv4"],"sources":["../../../src/core/schema/block-ids.ts"],"sourcesContent":["import { combineTransactionSteps, findChildrenInRange, getChangedRanges, getExtensionField, splitExtensions } from '@tiptap/core'\nimport type { Extensions } from '@tiptap/core'\nimport { UniqueID } from '@tiptap/extension-unique-id'\nimport type { Node as PMNode } from '@tiptap/pm/model'\nimport { Plugin, PluginKey } from '@tiptap/pm/state'\nimport { Transform } from '@tiptap/pm/transform'\nimport { v4 as uuidv4 } from 'uuid'\n\n/** Node attribute holding a block's stable ID; rendered as `data-id`. */\nexport const BLOCK_ID_ATTR = 'id'\n\n/** The built-in block types: every type that can be a top-level block (paragraphs nested in lists and quotes get one too). Other nodes opt in with `editorBlock: true`. */\nexport const BLOCK_ID_TYPES: readonly string[] = ['paragraph', 'heading', 'bulletList', 'orderedList', 'blockquote', 'codeBlock', 'image', 'audio', 'video', 'file', 'horizontalRule', 'transcriptSegment', 'composite']\n\n/** The node types among `extensions` that carry a block ID: `editorBlock` declared, else built-in (same rule as `NodeFlags`). */\nconst blockTypesOf = (extensions: Extensions): string[] => splitExtensions(extensions).nodeExtensions\n .filter(ext => getExtensionField<boolean | undefined>(ext, 'editorBlock') ?? BLOCK_ID_TYPES.includes(ext.name))\n .map(ext => ext.name)\n\n// `NodeFlags` copies `editorBlock` onto the spec; read it there (no import of node-flags: it imports this module).\nconst carriesId = (node: PMNode) => node.type.spec.editorBlock === true\n\n/** A fresh block ID (UUID v4; unlike `crypto.randomUUID()` also available outside secure contexts). */\nexport const newBlockId = (): string => uuidv4()\n\n/** The block ID of `node`; `null` for node types without IDs and for blocks that have none yet. */\nexport function blockIdOf(node: PMNode): string | null {\n const id: unknown = carriesId(node) ? node.attrs[BLOCK_ID_ATTR] : null\n return typeof id === 'string' && id ? id : null\n}\n\n/** The block with ID `id` (top-level or nested) and its position in `doc`, or `null`. */\nexport function findBlockById(doc: PMNode, id: string): { node: PMNode, pos: number } | null {\n let found: { node: PMNode, pos: number } | null = null\n doc.descendants((node, pos) => {\n if (found) return false\n if (blockIdOf(node) === id) found = { node, pos }\n // Inline content never carries block IDs.\n return !found && !node.isTextblock\n })\n return found\n}\n\n/**\n * `doc` with a fresh ID on every block that has none or repeats an earlier block's ID, or `null` when all IDs are\n * present and unique. For content no editor has touched: JSON seeds, Yjs state from before block IDs, server inserts.\n */\nexport function assignBlockIds(doc: PMNode): PMNode | null {\n const tr = new Transform(doc)\n const seen = new Set<string>()\n doc.descendants((node, pos) => {\n if (carriesId(node)) {\n const id = blockIdOf(node)\n if (id && !seen.has(id)) seen.add(id)\n else tr.setNodeAttribute(pos, BLOCK_ID_ATTR, newBlockId()) // attribute steps keep all positions valid\n }\n return !node.isTextblock\n })\n return tr.docChanged ? tr.doc : null\n}\n\n/**\n * UniqueID only compares IDs within the changed ranges, so a block inserted with an ID that exists elsewhere in the\n * document (Alt-drop of a drag-handle drag, `insertContent` of a copied block's JSON) would keep the duplicate. This\n * gives such inserted blocks a fresh ID; the block that was already there keeps its own.\n */\nconst dedupeInserted = () => new Plugin({\n key: new PluginKey('blockIdDedupe'),\n appendTransaction(transactions, oldState, newState) {\n // Remote Yjs changes carry the IDs their author assigned; rewriting them here would make clients diverge.\n if (!transactions.some(tr => tr.docChanged) || transactions.some(tr => tr.getMeta('y-sync$'))) return\n const transform = combineTransactionSteps(oldState.doc, [...transactions])\n const inverse = transform.mapping.invert()\n // Blocks that did not exist before (their start maps into content these transactions inserted), by position.\n const inserted = new Map<number, string>()\n for (const { newRange } of getChangedRanges(transform)) {\n for (const { node, pos } of findChildrenInRange(newState.doc, newRange, carriesId)) {\n const id = blockIdOf(node)\n if (id && inverse.mapResult(pos).deleted) inserted.set(pos, id)\n }\n }\n if (!inserted.size) return // typing and formatting end here, without walking the document\n const total = new Map<string, number>()\n const ofInserted = new Map<string, number>()\n for (const id of inserted.values()) ofInserted.set(id, (ofInserted.get(id) ?? 0) + 1)\n newState.doc.descendants((node) => {\n const id = blockIdOf(node)\n if (id && ofInserted.has(id)) total.set(id, (total.get(id) ?? 0) + 1)\n return !node.isTextblock\n })\n const tr = newState.tr\n const kept = new Set<string>()\n for (const [pos, id] of [...inserted].sort(([a], [b]) => a - b)) {\n if ((total.get(id) ?? 0) < 2) continue\n // Only inserted copies of this ID (e.g. pasted twice in one go): the first one keeps it.\n if (total.get(id) === ofInserted.get(id) && !kept.has(id)) {\n kept.add(id)\n continue\n }\n tr.setNodeAttribute(pos, BLOCK_ID_ATTR, newBlockId())\n }\n if (!tr.docChanged) return\n // Steps reset the stored marks; UniqueID's meta keeps TrailingNode from reacting to this transaction.\n return tr.setStoredMarks(newState.storedMarks).setMeta('__uniqueIDTransaction', true)\n },\n})\n\n/**\n * Stable block IDs. `@tiptap/extension-unique-id` assigns IDs only in the local user's transactions: it skips\n * `y-sync$` (remote Yjs) transactions, gives the new half of a split a fresh ID (also the speaker segment's own Enter,\n * whose new half starts without an ID) and strips IDs from pasted and copy-dropped content. Part of\n * `schemaExtensions()`, so the server schema, the JSON mirror and the Yjs state carry the attribute.\n */\nexport const BlockId = UniqueID.extend({\n // The ID-carrying types are the installed node extensions declaring `editorBlock` (built-ins default true).\n // Upstream reads `options.types` synchronously in each hook below, so each hook resolves them from its own\n // editor's extensions right before delegating: the configured options object is shared by every editor on the page.\n addGlobalAttributes() {\n this.options.types = blockTypesOf(this.extensions)\n return this.parent?.() ?? []\n },\n onCreate(event) {\n // Upstream backfills missing IDs on every client once the provider syncs, so two clients would race to give the\n // same blocks different IDs. The server backfills in `onLoadDocument` instead, before any client syncs.\n // A standalone editor (no Collaboration, content from JSON) is the only writer: upstream's immediate backfill.\n const { extensions } = this.editor.extensionManager\n if (extensions.some(ext => ext.name === 'collaboration')) return\n this.options.types = blockTypesOf(extensions)\n this.parent?.(event)\n },\n addProseMirrorPlugins() {\n this.options.types = blockTypesOf(this.editor.extensionManager.extensions)\n const plugins = this.parent?.() ?? []\n // Same client-side backfill, for a Collaboration setup without a provider (on the first Yjs sync).\n this.storage.needsInitialIdGeneration = false\n return [...plugins, dedupeInserted()]\n },\n}).configure({ attributeName: BLOCK_ID_ATTR, generateID: newBlockId })\n"],"mappings":"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"}
1
+ {"version":3,"file":"block-ids.js","names":["uuidv4"],"sources":["../../../src/core/schema/block-ids.ts"],"sourcesContent":["import { combineTransactionSteps, findChildrenInRange, getChangedRanges, getExtensionField, splitExtensions } from '@tiptap/core'\nimport type { Extensions } from '@tiptap/core'\nimport { UniqueID } from '@tiptap/extension-unique-id'\nimport type { Node as PMNode } from '@tiptap/pm/model'\nimport { Plugin, PluginKey } from '@tiptap/pm/state'\nimport { Transform } from '@tiptap/pm/transform'\nimport { v4 as uuidv4 } from 'uuid'\n\n/** Node attribute holding a block's stable ID; rendered as `data-id`. */\nexport const BLOCK_ID_ATTR = 'id'\n\n/** The built-in block types: every type that can be a top-level block (paragraphs nested in lists and quotes get one too). Other nodes opt in with `editorBlock: true`. */\nexport const BLOCK_ID_TYPES: readonly string[] = ['paragraph', 'heading', 'bulletList', 'orderedList', 'blockquote', 'codeBlock', 'image', 'audio', 'video', 'file', 'horizontalRule', 'transcriptSegment', 'typedBlock']\n\n/** The node types among `extensions` that carry a block ID: `editorBlock` declared, else built-in (same rule as `NodeFlags`). */\nconst nodeTypeNamesOf = (extensions: Extensions): string[] => splitExtensions(extensions).nodeExtensions\n .filter(ext => getExtensionField<boolean | undefined>(ext, 'editorBlock') ?? BLOCK_ID_TYPES.includes(ext.name))\n .map(ext => ext.name)\n\n// `NodeFlags` copies `editorBlock` onto the spec; read it there (no import of node-flags: it imports this module).\nconst carriesId = (node: PMNode) => node.type.spec.editorBlock === true\n\n/** A fresh block ID (UUID v4; unlike `crypto.randomUUID()` also available outside secure contexts). */\nexport const newBlockId = (): string => uuidv4()\n\n/** The block ID of `node`; `null` for node types without IDs and for blocks that have none yet. */\nexport function blockIdOf(node: PMNode): string | null {\n const id: unknown = carriesId(node) ? node.attrs[BLOCK_ID_ATTR] : null\n return typeof id === 'string' && id ? id : null\n}\n\n/** The block with ID `id` (top-level or nested) and its position in `doc`, or `null`. */\nexport function findBlockById(doc: PMNode, id: string): { node: PMNode, pos: number } | null {\n let found: { node: PMNode, pos: number } | null = null\n doc.descendants((node, pos) => {\n if (found) return false\n if (blockIdOf(node) === id) found = { node, pos }\n // Inline content never carries block IDs.\n return !found && !node.isTextblock\n })\n return found\n}\n\n/**\n * `doc` with a fresh ID on every block that has none or repeats an earlier block's ID, or `null` when all IDs are\n * present and unique. For content no editor has touched: JSON seeds, Yjs state from before block IDs, server inserts.\n */\nexport function assignBlockIds(doc: PMNode): PMNode | null {\n const tr = new Transform(doc)\n const seen = new Set<string>()\n doc.descendants((node, pos) => {\n if (carriesId(node)) {\n const id = blockIdOf(node)\n if (id && !seen.has(id)) seen.add(id)\n else tr.setNodeAttribute(pos, BLOCK_ID_ATTR, newBlockId()) // attribute steps keep all positions valid\n }\n return !node.isTextblock\n })\n return tr.docChanged ? tr.doc : null\n}\n\n/**\n * UniqueID only compares IDs within the changed ranges, so a block inserted with an ID that exists elsewhere in the\n * document (Alt-drop of a drag-handle drag, `insertContent` of a copied block's JSON) would keep the duplicate. This\n * gives such inserted blocks a fresh ID; the block that was already there keeps its own.\n */\nconst dedupeInserted = () => new Plugin({\n key: new PluginKey('blockIdDedupe'),\n appendTransaction(transactions, oldState, newState) {\n // Remote Yjs changes carry the IDs their author assigned; rewriting them here would make clients diverge.\n if (!transactions.some(tr => tr.docChanged) || transactions.some(tr => tr.getMeta('y-sync$'))) return\n const transform = combineTransactionSteps(oldState.doc, [...transactions])\n const inverse = transform.mapping.invert()\n // Blocks that did not exist before (their start maps into content these transactions inserted), by position.\n const inserted = new Map<number, string>()\n for (const { newRange } of getChangedRanges(transform)) {\n for (const { node, pos } of findChildrenInRange(newState.doc, newRange, carriesId)) {\n const id = blockIdOf(node)\n if (id && inverse.mapResult(pos).deleted) inserted.set(pos, id)\n }\n }\n if (!inserted.size) return // typing and formatting end here, without walking the document\n const total = new Map<string, number>()\n const ofInserted = new Map<string, number>()\n for (const id of inserted.values()) ofInserted.set(id, (ofInserted.get(id) ?? 0) + 1)\n newState.doc.descendants((node) => {\n const id = blockIdOf(node)\n if (id && ofInserted.has(id)) total.set(id, (total.get(id) ?? 0) + 1)\n return !node.isTextblock\n })\n const tr = newState.tr\n const kept = new Set<string>()\n for (const [pos, id] of [...inserted].sort(([a], [b]) => a - b)) {\n if ((total.get(id) ?? 0) < 2) continue\n // Only inserted copies of this ID (e.g. pasted twice in one go): the first one keeps it.\n if (total.get(id) === ofInserted.get(id) && !kept.has(id)) {\n kept.add(id)\n continue\n }\n tr.setNodeAttribute(pos, BLOCK_ID_ATTR, newBlockId())\n }\n if (!tr.docChanged) return\n // Steps reset the stored marks; UniqueID's meta keeps TrailingNode from reacting to this transaction.\n return tr.setStoredMarks(newState.storedMarks).setMeta('__uniqueIDTransaction', true)\n },\n})\n\n/**\n * Stable block IDs. `@tiptap/extension-unique-id` assigns IDs only in the local user's transactions: it skips\n * `y-sync$` (remote Yjs) transactions, gives the new half of a split a fresh ID (also the speaker segment's own Enter,\n * whose new half starts without an ID) and strips IDs from pasted and copy-dropped content. Part of\n * `schemaExtensions()`, so the server schema, the JSON mirror and the Yjs state carry the attribute.\n */\nexport const BlockId = UniqueID.extend({\n // The ID-carrying types are the installed node extensions declaring `editorBlock` (built-ins default true).\n // Upstream reads `options.types` synchronously in each hook below, so each hook resolves them from its own\n // editor's extensions right before delegating: the configured options object is shared by every editor on the page.\n addGlobalAttributes() {\n this.options.types = nodeTypeNamesOf(this.extensions)\n return this.parent?.() ?? []\n },\n onCreate(event) {\n // Upstream backfills missing IDs on every client once the provider syncs, so two clients would race to give the\n // same blocks different IDs. The server backfills in `onLoadDocument` instead, before any client syncs.\n // A standalone editor (no Collaboration, content from JSON) is the only writer: upstream's immediate backfill.\n const { extensions } = this.editor.extensionManager\n if (extensions.some(ext => ext.name === 'collaboration')) return\n this.options.types = nodeTypeNamesOf(extensions)\n this.parent?.(event)\n },\n addProseMirrorPlugins() {\n this.options.types = nodeTypeNamesOf(this.editor.extensionManager.extensions)\n const plugins = this.parent?.() ?? []\n // Same client-side backfill, for a Collaboration setup without a provider (on the first Yjs sync).\n this.storage.needsInitialIdGeneration = false\n return [...plugins, dedupeInserted()]\n },\n}).configure({ attributeName: BLOCK_ID_ATTR, generateID: newBlockId })\n"],"mappings":"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"}
@@ -3,6 +3,7 @@ import { BLOCK_ID_ATTR, BLOCK_ID_TYPES, BlockId, assignBlockIds, blockIdOf, find
3
3
  import { HEX_COLOR } from "./hex-color.js";
4
4
  import "./mark-flags.js";
5
5
  import { NodeFlags, isBlockContainer, isChromeNode, isEditorBlock } from "./node-flags.js";
6
+ import { BLOCK_TYPE_ATTR, OLD_HTML, PersistedNamesOptions, TYPED_BLOCK, TYPED_BLOCK_CLASS, TYPED_BLOCK_DESCRIPTION, TYPED_BLOCK_TAGS, TYPED_BLOCK_TITLE, isOldPersistedNode, migratePersistedNames } from "./persisted-names.js";
6
7
  import { OpaqueFence } from "./opaque-fence.js";
7
8
  import { StrikeX } from "./strike.js";
8
9
  import { schemaExtensionsOf } from "./of-features.js";
@@ -44,5 +45,5 @@ export declare const coreSchemaExtensions: () => AnyExtension[];
44
45
  /** Content of a fresh, empty document. */
45
46
  export declare const EMPTY_EDITOR_CONTENT: JSONContent;
46
47
  //#endregion
47
- export { ABILITY, Ability, AbilityRule, AbilityRuleSource, BLOCK_ID_ATTR, BLOCK_ID_TYPES, BlockId, HEX_COLOR, NodeFlags, OpaqueFence, ROOT_ABILITIES, StrikeX, TEXT_ABILITIES, TYPE_ABILITIES, assignBlockIds, blockIdOf, findBlockById, isBlockContainer, isChromeNode, isEditorBlock, newBlockId, resolveAbilities, schemaExtensionsOf };
48
+ export { ABILITY, Ability, AbilityRule, AbilityRuleSource, BLOCK_ID_ATTR, BLOCK_ID_TYPES, BLOCK_TYPE_ATTR, BlockId, HEX_COLOR, NodeFlags, OLD_HTML, OpaqueFence, PersistedNamesOptions, ROOT_ABILITIES, StrikeX, TEXT_ABILITIES, TYPED_BLOCK, TYPED_BLOCK_CLASS, TYPED_BLOCK_DESCRIPTION, TYPED_BLOCK_TAGS, TYPED_BLOCK_TITLE, TYPE_ABILITIES, assignBlockIds, blockIdOf, findBlockById, isBlockContainer, isChromeNode, isEditorBlock, isOldPersistedNode, migratePersistedNames, newBlockId, resolveAbilities, schemaExtensionsOf };
48
49
  //# sourceMappingURL=index.d.ts.map
@@ -1,6 +1,7 @@
1
1
  import { ABILITY, ROOT_ABILITIES, TEXT_ABILITIES, TYPE_ABILITIES, resolveAbilities } from "./abilities.js";
2
2
  import { BLOCK_ID_ATTR, BLOCK_ID_TYPES, BlockId, assignBlockIds, blockIdOf, findBlockById, newBlockId } from "./block-ids.js";
3
3
  import { NodeFlags, isBlockContainer, isChromeNode, isEditorBlock } from "./node-flags.js";
4
+ import { BLOCK_TYPE_ATTR, OLD_HTML, TYPED_BLOCK, TYPED_BLOCK_CLASS, TYPED_BLOCK_DESCRIPTION, TYPED_BLOCK_TAGS, TYPED_BLOCK_TITLE, isOldPersistedNode, migratePersistedNames } from "./persisted-names.js";
4
5
  import { OpaqueFence } from "./opaque-fence.js";
5
6
  import { StrikeX } from "./strike.js";
6
7
  import { HEX_COLOR } from "./hex-color.js";
@@ -50,6 +51,6 @@ const EMPTY_EDITOR_CONTENT = {
50
51
  content: [{ type: "paragraph" }]
51
52
  };
52
53
  //#endregion
53
- export { ABILITY, BLOCK_ID_ATTR, BLOCK_ID_TYPES, BlockId, EMPTY_EDITOR_CONTENT, HEX_COLOR, NodeFlags, OpaqueFence, ROOT_ABILITIES, StrikeX, TEXT_ABILITIES, TYPE_ABILITIES, assignBlockIds, blockIdOf, coreContentSchemaExtensions, coreSchemaExtensions, findBlockById, isBlockContainer, isChromeNode, isEditorBlock, newBlockId, resolveAbilities, schemaExtensionsOf, starterKitOf };
54
+ export { ABILITY, BLOCK_ID_ATTR, BLOCK_ID_TYPES, BLOCK_TYPE_ATTR, BlockId, EMPTY_EDITOR_CONTENT, HEX_COLOR, NodeFlags, OLD_HTML, OpaqueFence, ROOT_ABILITIES, StrikeX, TEXT_ABILITIES, TYPED_BLOCK, TYPED_BLOCK_CLASS, TYPED_BLOCK_DESCRIPTION, TYPED_BLOCK_TAGS, TYPED_BLOCK_TITLE, TYPE_ABILITIES, assignBlockIds, blockIdOf, coreContentSchemaExtensions, coreSchemaExtensions, findBlockById, isBlockContainer, isChromeNode, isEditorBlock, isOldPersistedNode, migratePersistedNames, newBlockId, resolveAbilities, schemaExtensionsOf, starterKitOf };
54
55
 
55
56
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../../../src/core/schema/index.ts"],"sourcesContent":["import type { AnyExtension, JSONContent } from '@tiptap/core'\nimport StarterKit, { type StarterKitOptions } from '@tiptap/starter-kit'\nimport { BlockId } from './block-ids'\nimport { NodeFlags } from './node-flags'\nimport { OpaqueFence } from './opaque-fence'\nimport { StrikeX } from './strike'\n\nexport * from './abilities'\nexport * from './block-ids'\nexport * from './hex-color'\nexport * from './mark-flags'\nexport * from './node-flags'\nexport { OpaqueFence } from './opaque-fence'\nexport { StrikeX } from './strike'\nexport { schemaExtensionsOf } from './of-features'\n\n/**\n * Which optional StarterKit structures the content base installs; everything is on by default. A structure that is off\n * is not in the schema, in the editor and on the server alike (one options object feeds both).\n */\nexport interface CoreContentOptions {\n /** `false`: no headings; `{ levels }`: only these heading levels. */\n headings?: false | { levels: (1 | 2 | 3 | 4 | 5 | 6)[] }\n /** `false`: no bullet or ordered lists (and list items). */\n lists?: false\n /** `false`: no blockquote. */\n blockquote?: false\n /** `false`: no code block. */\n codeBlock?: false\n /** `false`: no horizontal rule. */\n rule?: false\n}\n\n/** The StarterKit options `options` stand for: the one mapping the editor feature and the schema-extension list share, so schemas cannot drift. */\nexport function starterKitOf(options: CoreContentOptions = {}): Partial<StarterKitOptions> {\n const kit: Partial<StarterKitOptions> = {}\n if (options.headings === false) kit.heading = false\n else if (options.headings) kit.heading = { levels: options.headings.levels }\n if (options.lists === false) Object.assign(kit, { bulletList: false, orderedList: false, listItem: false, listKeymap: false })\n if (options.blockquote === false) kit.blockquote = false\n if (options.codeBlock === false) kit.codeBlock = false\n if (options.rule === false) kit.horizontalRule = false\n return kit\n}\n\n/**\n * The Vue-free nodes and marks of the content base (`core-content` feature): StarterKit (history off: the surface enables\n * it for standalone editors, collaboration brings its own), StrikeX, the node-flags extension and `OpaqueFence` (Markdown\n * fences of unknown kinds, kept verbatim). `options` drop optional StarterKit structures. Without `BlockId`: `schemaExtensionsOf` appends it last.\n */\nexport const coreContentSchemaExtensions = (options: CoreContentOptions = {}): AnyExtension[] => [StarterKit.configure({ strike: false, undoRedo: false, ...starterKitOf(options) }), StrikeX, NodeFlags, OpaqueFence]\n\n/**\n * Base Vue-free nodes and marks of every editor: `coreContentSchemaExtensions()` and `BlockId`, which adds the `id`\n * attribute to every block type (its ID-assigning plugins only run in an editor). The server builds its schema from\n * these as well (`getSchema(...)`).\n */\nexport const coreSchemaExtensions = (): AnyExtension[] => [...coreContentSchemaExtensions(), BlockId]\n\n/** Content of a fresh, empty document. */\nexport const EMPTY_EDITOR_CONTENT: JSONContent = { type: 'doc', content: [{ type: 'paragraph' }] }\n"],"mappings":";;;;;;;;;;AAkCA,SAAgB,aAAa,UAA8B,CAAC,GAA+B;CACzF,MAAM,MAAkC,CAAC;CACzC,IAAI,QAAQ,aAAa,OAAO,IAAI,UAAU;MACzC,IAAI,QAAQ,UAAU,IAAI,UAAU,EAAE,QAAQ,QAAQ,SAAS,OAAO;CAC3E,IAAI,QAAQ,UAAU,OAAO,OAAO,OAAO,KAAK;EAAE,YAAY;EAAO,aAAa;EAAO,UAAU;EAAO,YAAY;CAAM,CAAC;CAC7H,IAAI,QAAQ,eAAe,OAAO,IAAI,aAAa;CACnD,IAAI,QAAQ,cAAc,OAAO,IAAI,YAAY;CACjD,IAAI,QAAQ,SAAS,OAAO,IAAI,iBAAiB;CACjD,OAAO;AACT;;;;;;AAOA,MAAa,+BAA+B,UAA8B,CAAC,MAAsB;CAAC,WAAW,UAAU;EAAE,QAAQ;EAAO,UAAU;EAAO,GAAG,aAAa,OAAO;CAAE,CAAC;CAAG;CAAS;CAAW;AAAW;;;;;;AAOrN,MAAa,6BAA6C,CAAC,GAAG,4BAA4B,GAAG,OAAO;;AAGpG,MAAa,uBAAoC;CAAE,MAAM;CAAO,SAAS,CAAC,EAAE,MAAM,YAAY,CAAC;AAAE"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../../src/core/schema/index.ts"],"sourcesContent":["import type { AnyExtension, JSONContent } from '@tiptap/core'\nimport StarterKit, { type StarterKitOptions } from '@tiptap/starter-kit'\nimport { BlockId } from './block-ids'\nimport { NodeFlags } from './node-flags'\nimport { OpaqueFence } from './opaque-fence'\nimport { StrikeX } from './strike'\n\nexport * from './abilities'\nexport * from './block-ids'\nexport * from './hex-color'\nexport * from './mark-flags'\nexport * from './node-flags'\nexport * from './persisted-names'\nexport { OpaqueFence } from './opaque-fence'\nexport { StrikeX } from './strike'\nexport { schemaExtensionsOf } from './of-features'\n\n/**\n * Which optional StarterKit structures the content base installs; everything is on by default. A structure that is off\n * is not in the schema, in the editor and on the server alike (one options object feeds both).\n */\nexport interface CoreContentOptions {\n /** `false`: no headings; `{ levels }`: only these heading levels. */\n headings?: false | { levels: (1 | 2 | 3 | 4 | 5 | 6)[] }\n /** `false`: no bullet or ordered lists (and list items). */\n lists?: false\n /** `false`: no blockquote. */\n blockquote?: false\n /** `false`: no code block. */\n codeBlock?: false\n /** `false`: no horizontal rule. */\n rule?: false\n}\n\n/** The StarterKit options `options` stand for: the one mapping the editor feature and the schema-extension list share, so schemas cannot drift. */\nexport function starterKitOf(options: CoreContentOptions = {}): Partial<StarterKitOptions> {\n const kit: Partial<StarterKitOptions> = {}\n if (options.headings === false) kit.heading = false\n else if (options.headings) kit.heading = { levels: options.headings.levels }\n if (options.lists === false) Object.assign(kit, { bulletList: false, orderedList: false, listItem: false, listKeymap: false })\n if (options.blockquote === false) kit.blockquote = false\n if (options.codeBlock === false) kit.codeBlock = false\n if (options.rule === false) kit.horizontalRule = false\n return kit\n}\n\n/**\n * The Vue-free nodes and marks of the content base (`core-content` feature): StarterKit (history off: the surface enables\n * it for standalone editors, collaboration brings its own), StrikeX, the node-flags extension and `OpaqueFence` (Markdown\n * fences of unknown kinds, kept verbatim). `options` drop optional StarterKit structures. Without `BlockId`: `schemaExtensionsOf` appends it last.\n */\nexport const coreContentSchemaExtensions = (options: CoreContentOptions = {}): AnyExtension[] => [StarterKit.configure({ strike: false, undoRedo: false, ...starterKitOf(options) }), StrikeX, NodeFlags, OpaqueFence]\n\n/**\n * Base Vue-free nodes and marks of every editor: `coreContentSchemaExtensions()` and `BlockId`, which adds the `id`\n * attribute to every block type (its ID-assigning plugins only run in an editor). The server builds its schema from\n * these as well (`getSchema(...)`).\n */\nexport const coreSchemaExtensions = (): AnyExtension[] => [...coreContentSchemaExtensions(), BlockId]\n\n/** Content of a fresh, empty document. */\nexport const EMPTY_EDITOR_CONTENT: JSONContent = { type: 'doc', content: [{ type: 'paragraph' }] }\n"],"mappings":";;;;;;;;;;;AAmCA,SAAgB,aAAa,UAA8B,CAAC,GAA+B;CACzF,MAAM,MAAkC,CAAC;CACzC,IAAI,QAAQ,aAAa,OAAO,IAAI,UAAU;MACzC,IAAI,QAAQ,UAAU,IAAI,UAAU,EAAE,QAAQ,QAAQ,SAAS,OAAO;CAC3E,IAAI,QAAQ,UAAU,OAAO,OAAO,OAAO,KAAK;EAAE,YAAY;EAAO,aAAa;EAAO,UAAU;EAAO,YAAY;CAAM,CAAC;CAC7H,IAAI,QAAQ,eAAe,OAAO,IAAI,aAAa;CACnD,IAAI,QAAQ,cAAc,OAAO,IAAI,YAAY;CACjD,IAAI,QAAQ,SAAS,OAAO,IAAI,iBAAiB;CACjD,OAAO;AACT;;;;;;AAOA,MAAa,+BAA+B,UAA8B,CAAC,MAAsB;CAAC,WAAW,UAAU;EAAE,QAAQ;EAAO,UAAU;EAAO,GAAG,aAAa,OAAO;CAAE,CAAC;CAAG;CAAS;CAAW;AAAW;;;;;;AAOrN,MAAa,6BAA6C,CAAC,GAAG,4BAA4B,GAAG,OAAO;;AAGpG,MAAa,uBAAoC;CAAE,MAAM;CAAO,SAAS,CAAC,EAAE,MAAM,YAAY,CAAC;AAAE"}
@@ -1,10 +1,10 @@
1
1
  import { Node } from "@tiptap/core";
2
2
  //#region src/core/schema/opaque-fence.d.ts
3
3
  /**
4
- * A `::: kind` … `:::` fence of a kind the editor has no node for (kinds a composite feature registers parse into
5
- * composites first). The fence's source text is kept in `raw` and written back byte for byte, so documents with fences
6
- * of other tools survive a round trip; the editor shows it as read-only text block, and source mode edits it. `kind`
7
- * is the word after the opening colons.
4
+ * A `::: <block type id>` … `:::` fence of a Block type the editor has no node for (Block types a typed-block feature
5
+ * registers parse into Typed blocks first). The fence's source text is kept in `raw` and written back byte for byte, so
6
+ * documents with fences of other tools survive a round trip; the editor shows it as read-only text block, and source mode
7
+ * edits it. `blockType` is the word after the opening colons.
8
8
  */
9
9
  export declare const OpaqueFence: Node<any, any>;
10
10
  //#endregion
@@ -1,10 +1,10 @@
1
1
  import { Node } from "@tiptap/core";
2
2
  //#region src/core/schema/opaque-fence.ts
3
3
  /**
4
- * A `::: kind` … `:::` fence of a kind the editor has no node for (kinds a composite feature registers parse into
5
- * composites first). The fence's source text is kept in `raw` and written back byte for byte, so documents with fences
6
- * of other tools survive a round trip; the editor shows it as read-only text block, and source mode edits it. `kind`
7
- * is the word after the opening colons.
4
+ * A `::: <block type id>` … `:::` fence of a Block type the editor has no node for (Block types a typed-block feature
5
+ * registers parse into Typed blocks first). The fence's source text is kept in `raw` and written back byte for byte, so
6
+ * documents with fences of other tools survive a round trip; the editor shows it as read-only text block, and source mode
7
+ * edits it. `blockType` is the word after the opening colons.
8
8
  */
9
9
  const OpaqueFence = Node.create({
10
10
  name: "opaqueFence",
@@ -19,7 +19,7 @@ const OpaqueFence = Node.create({
19
19
  default: "",
20
20
  rendered: false
21
21
  },
22
- kind: {
22
+ blockType: {
23
23
  default: null,
24
24
  rendered: false
25
25
  }
@@ -31,7 +31,7 @@ const OpaqueFence = Node.create({
31
31
  priority: 60,
32
32
  getAttrs: (element) => ({
33
33
  raw: element.textContent ?? "",
34
- kind: element.getAttribute("data-opaque-fence") || null
34
+ blockType: element.getAttribute("data-opaque-fence") || null
35
35
  })
36
36
  }];
37
37
  },
@@ -39,7 +39,7 @@ const OpaqueFence = Node.create({
39
39
  return [
40
40
  "pre",
41
41
  {
42
- "data-opaque-fence": node.attrs.kind ?? "",
42
+ "data-opaque-fence": node.attrs.blockType ?? "",
43
43
  class: "sk-opaque-fence"
44
44
  },
45
45
  [
@@ -1 +1 @@
1
- {"version":3,"file":"opaque-fence.js","names":[],"sources":["../../../src/core/schema/opaque-fence.ts"],"sourcesContent":["import { Node } from '@tiptap/core'\n\n/**\n * A `::: kind` … `:::` fence of a kind the editor has no node for (kinds a composite feature registers parse into\n * composites first). The fence's source text is kept in `raw` and written back byte for byte, so documents with fences\n * of other tools survive a round trip; the editor shows it as read-only text block, and source mode edits it. `kind`\n * is the word after the opening colons.\n */\nexport const OpaqueFence = Node.create({\n name: 'opaqueFence',\n group: 'block',\n atom: true,\n selectable: true,\n draggable: true,\n editorBlock: true,\n\n addAttributes() {\n return {\n raw: { default: '', rendered: false },\n kind: { default: null, rendered: false },\n }\n },\n\n parseHTML() {\n return [{\n tag: 'pre[data-opaque-fence]',\n priority: 60,\n getAttrs: element => ({ raw: element.textContent ?? '', kind: element.getAttribute('data-opaque-fence') || null }),\n }]\n },\n\n renderHTML({ node }) {\n // The text sits in a `code` child: ProseMirror's own sheet sets `white-space: normal` on every non-editable element, which a rule on the `pre` cannot beat.\n return ['pre', { 'data-opaque-fence': node.attrs.kind ?? '', class: 'sk-opaque-fence' }, ['code', {}, String(node.attrs.raw ?? '')]]\n },\n\n renderMarkdown: node => String(node.attrs?.raw ?? ''),\n})\n"],"mappings":";;;;;;;;AAQA,MAAa,cAAc,KAAK,OAAO;CACrC,MAAM;CACN,OAAO;CACP,MAAM;CACN,YAAY;CACZ,WAAW;CACX,aAAa;CAEb,gBAAgB;EACd,OAAO;GACL,KAAK;IAAE,SAAS;IAAI,UAAU;GAAM;GACpC,MAAM;IAAE,SAAS;IAAM,UAAU;GAAM;EACzC;CACF;CAEA,YAAY;EACV,OAAO,CAAC;GACN,KAAK;GACL,UAAU;GACV,WAAU,aAAY;IAAE,KAAK,QAAQ,eAAe;IAAI,MAAM,QAAQ,aAAa,mBAAmB,KAAK;GAAK;EAClH,CAAC;CACH;CAEA,WAAW,EAAE,QAAQ;EAEnB,OAAO;GAAC;GAAO;IAAE,qBAAqB,KAAK,MAAM,QAAQ;IAAI,OAAO;GAAkB;GAAG;IAAC;IAAQ,CAAC;IAAG,OAAO,KAAK,MAAM,OAAO,EAAE;GAAC;EAAC;CACrI;CAEA,iBAAgB,SAAQ,OAAO,KAAK,OAAO,OAAO,EAAE;AACtD,CAAC"}
1
+ {"version":3,"file":"opaque-fence.js","names":[],"sources":["../../../src/core/schema/opaque-fence.ts"],"sourcesContent":["import { Node } from '@tiptap/core'\n\n/**\n * A `::: <block type id>` … `:::` fence of a Block type the editor has no node for (Block types a typed-block feature\n * registers parse into Typed blocks first). The fence's source text is kept in `raw` and written back byte for byte, so\n * documents with fences of other tools survive a round trip; the editor shows it as read-only text block, and source mode\n * edits it. `blockType` is the word after the opening colons.\n */\nexport const OpaqueFence = Node.create({\n name: 'opaqueFence',\n group: 'block',\n atom: true,\n selectable: true,\n draggable: true,\n editorBlock: true,\n\n addAttributes() {\n return {\n raw: { default: '', rendered: false },\n blockType: { default: null, rendered: false },\n }\n },\n\n parseHTML() {\n return [{\n tag: 'pre[data-opaque-fence]',\n priority: 60,\n getAttrs: element => ({ raw: element.textContent ?? '', blockType: element.getAttribute('data-opaque-fence') || null }),\n }]\n },\n\n renderHTML({ node }) {\n // The text sits in a `code` child: ProseMirror's own sheet sets `white-space: normal` on every non-editable element, which a rule on the `pre` cannot beat.\n return ['pre', { 'data-opaque-fence': node.attrs.blockType ?? '', class: 'sk-opaque-fence' }, ['code', {}, String(node.attrs.raw ?? '')]]\n },\n\n renderMarkdown: node => String(node.attrs?.raw ?? ''),\n})\n"],"mappings":";;;;;;;;AAQA,MAAa,cAAc,KAAK,OAAO;CACrC,MAAM;CACN,OAAO;CACP,MAAM;CACN,YAAY;CACZ,WAAW;CACX,aAAa;CAEb,gBAAgB;EACd,OAAO;GACL,KAAK;IAAE,SAAS;IAAI,UAAU;GAAM;GACpC,WAAW;IAAE,SAAS;IAAM,UAAU;GAAM;EAC9C;CACF;CAEA,YAAY;EACV,OAAO,CAAC;GACN,KAAK;GACL,UAAU;GACV,WAAU,aAAY;IAAE,KAAK,QAAQ,eAAe;IAAI,WAAW,QAAQ,aAAa,mBAAmB,KAAK;GAAK;EACvH,CAAC;CACH;CAEA,WAAW,EAAE,QAAQ;EAEnB,OAAO;GAAC;GAAO;IAAE,qBAAqB,KAAK,MAAM,aAAa;IAAI,OAAO;GAAkB;GAAG;IAAC;IAAQ,CAAC;IAAG,OAAO,KAAK,MAAM,OAAO,EAAE;GAAC;EAAC;CAC1I;CAEA,iBAAgB,SAAQ,OAAO,KAAK,OAAO,OAAO,EAAE;AACtD,CAAC"}
@@ -0,0 +1,58 @@
1
+ import { JSONContent } from "@tiptap/core";
2
+ //#region src/core/schema/persisted-names.d.ts
3
+ /**
4
+ * The persisted names of Typed blocks before the vocabulary of `CONTEXT.md` (Typed block, Block type) replaced them, and
5
+ * the one load-time migration that maps them to the current names. Stored documents (JSON store, Yjs state, `.cdoc`
6
+ * packages, Markdown-free clipboard and drag payloads) written by earlier releases carry them; the rule is: old names are
7
+ * READ wherever content enters and never written. Nothing else in the code base spells them.
8
+ *
9
+ * Nodes: `composite` -> `typedBlock`, with the chrome nodes `compositeTitle`/`compositeDescription`/`compositeTags` ->
10
+ * `typedBlockTitle`/`typedBlockDescription`/`typedBlockTags`; with `options.earliest` also the single-purpose `section`
11
+ * family of the earliest dev releases (`section`, `sectionTitle`, `sectionSummary`, `sectionTags`), which maps to the same
12
+ * targets (a `section` becomes a Typed block of Block type `section`). Attribute: `kind` -> `blockType` on a Typed block and on an `opaqueFence`.
13
+ */
14
+ /** Node name of a Typed block. */
15
+ export declare const TYPED_BLOCK = "typedBlock";
16
+ export declare const TYPED_BLOCK_TITLE = "typedBlockTitle";
17
+ export declare const TYPED_BLOCK_DESCRIPTION = "typedBlockDescription";
18
+ export declare const TYPED_BLOCK_TAGS = "typedBlockTags";
19
+ /**
20
+ * CSS class of a Typed block's node view root (`section.composite`). Styling, not a persisted name: the shipped sheets, the
21
+ * chrome anchors (`compositeSectionOf`) and host themes select `.composite`, as they did before the rename. It is spelled
22
+ * here because `legacy-names` lets this file (and only this file) quote the word; the BEM children `composite__toggle` and
23
+ * `composite__content` and the title class `composite-title` are no bare quoted name and need no entry. The HTML node
24
+ * name stays `data-type="typedBlock"`.
25
+ */
26
+ export declare const TYPED_BLOCK_CLASS = "composite";
27
+ /** Attribute that holds the id of a Typed block's (and an opaque fence's) Block type. */
28
+ export declare const BLOCK_TYPE_ATTR = "blockType";
29
+ export interface PersistedNamesOptions {
30
+ /** Also map the earliest `section` family (content of an editor with Typed blocks). Default `false`. */
31
+ earliest?: boolean;
32
+ }
33
+ /** The HTML names markup written before the rename carries; the node parse rules read them, nothing writes them (the Markdown fence needs no entry: its keyword is a Block type id and did not change). */
34
+ export declare const OLD_HTML: {
35
+ readonly typedBlock: "composite";
36
+ readonly title: "composite-title";
37
+ readonly description: "composite-description";
38
+ readonly tags: "composite-tags";
39
+ /** The earliest dev releases' single-purpose `section` family: element `data-type`s of the block and its title, summary and tags. */
40
+ readonly earliestBlock: "section";
41
+ readonly earliestTitle: "section-title";
42
+ readonly earliestDescription: "section-summary";
43
+ readonly earliestTags: "section-tags";
44
+ /** Attribute of the Block type id on the Typed block's element. */
45
+ readonly blockTypeAttr: "data-kind";
46
+ };
47
+ /**
48
+ * Whether stored content with a node (or Yjs element) named `nodeName` and these `attributes` still uses an old persisted
49
+ * name: the node name itself, or a Typed block / opaque fence that still has the `kind` attribute.
50
+ */
51
+ export declare function isOldPersistedNode(nodeName: string, attributes: Readonly<Record<string, unknown>>, options?: PersistedNamesOptions): boolean;
52
+ /**
53
+ * `json` with every old persisted name replaced by the current one; recursive, returns a copy. Idempotent (current names
54
+ * pass unchanged) and lossless: block IDs and every other attribute stay, an existing `blockType` wins over a stale `kind`.
55
+ */
56
+ export declare function migratePersistedNames(json: JSONContent, options?: PersistedNamesOptions): JSONContent;
57
+ //#endregion
58
+ //# sourceMappingURL=persisted-names.d.ts.map
@@ -0,0 +1,96 @@
1
+ //#region src/core/schema/persisted-names.ts
2
+ /**
3
+ * The persisted names of Typed blocks before the vocabulary of `CONTEXT.md` (Typed block, Block type) replaced them, and
4
+ * the one load-time migration that maps them to the current names. Stored documents (JSON store, Yjs state, `.cdoc`
5
+ * packages, Markdown-free clipboard and drag payloads) written by earlier releases carry them; the rule is: old names are
6
+ * READ wherever content enters and never written. Nothing else in the code base spells them.
7
+ *
8
+ * Nodes: `composite` -> `typedBlock`, with the chrome nodes `compositeTitle`/`compositeDescription`/`compositeTags` ->
9
+ * `typedBlockTitle`/`typedBlockDescription`/`typedBlockTags`; with `options.earliest` also the single-purpose `section`
10
+ * family of the earliest dev releases (`section`, `sectionTitle`, `sectionSummary`, `sectionTags`), which maps to the same
11
+ * targets (a `section` becomes a Typed block of Block type `section`). Attribute: `kind` -> `blockType` on a Typed block and on an `opaqueFence`.
12
+ */
13
+ /** Node name of a Typed block. */
14
+ const TYPED_BLOCK = "typedBlock";
15
+ const TYPED_BLOCK_TITLE = "typedBlockTitle";
16
+ const TYPED_BLOCK_DESCRIPTION = "typedBlockDescription";
17
+ const TYPED_BLOCK_TAGS = "typedBlockTags";
18
+ /**
19
+ * CSS class of a Typed block's node view root (`section.composite`). Styling, not a persisted name: the shipped sheets, the
20
+ * chrome anchors (`compositeSectionOf`) and host themes select `.composite`, as they did before the rename. It is spelled
21
+ * here because `legacy-names` lets this file (and only this file) quote the word; the BEM children `composite__toggle` and
22
+ * `composite__content` and the title class `composite-title` are no bare quoted name and need no entry. The HTML node
23
+ * name stays `data-type="typedBlock"`.
24
+ */
25
+ const TYPED_BLOCK_CLASS = "composite";
26
+ /** Attribute that holds the id of a Typed block's (and an opaque fence's) Block type. */
27
+ const BLOCK_TYPE_ATTR = "blockType";
28
+ /** Node name stored before -> current node name. */
29
+ const RENAMED_NODES = {
30
+ composite: TYPED_BLOCK,
31
+ compositeTitle: TYPED_BLOCK_TITLE,
32
+ compositeDescription: TYPED_BLOCK_DESCRIPTION,
33
+ compositeTags: TYPED_BLOCK_TAGS
34
+ };
35
+ /**
36
+ * The single-purpose `section` family of the earliest dev releases -> current node name. Only for content of editors
37
+ * with Typed blocks (`options.earliest`): a host may have a node of its own named `section`.
38
+ */
39
+ const EARLIEST_NODES = {
40
+ section: TYPED_BLOCK,
41
+ sectionTitle: TYPED_BLOCK_TITLE,
42
+ sectionSummary: TYPED_BLOCK_DESCRIPTION,
43
+ sectionTags: TYPED_BLOCK_TAGS
44
+ };
45
+ const renamedNode = (nodeName, options) => Object.hasOwn(RENAMED_NODES, nodeName) ? RENAMED_NODES[nodeName] : options.earliest && Object.hasOwn(EARLIEST_NODES, nodeName) ? EARLIEST_NODES[nodeName] : void 0;
46
+ /** The HTML names markup written before the rename carries; the node parse rules read them, nothing writes them (the Markdown fence needs no entry: its keyword is a Block type id and did not change). */
47
+ const OLD_HTML = {
48
+ typedBlock: "composite",
49
+ title: "composite-title",
50
+ description: "composite-description",
51
+ tags: "composite-tags",
52
+ /** The earliest dev releases' single-purpose `section` family: element `data-type`s of the block and its title, summary and tags. */
53
+ earliestBlock: "section",
54
+ earliestTitle: "section-title",
55
+ earliestDescription: "section-summary",
56
+ earliestTags: "section-tags",
57
+ /** Attribute of the Block type id on the Typed block's element. */
58
+ blockTypeAttr: "data-kind"
59
+ };
60
+ /** The former attribute name of the Block type id. */
61
+ const OLD_BLOCK_TYPE_ATTR = "kind";
62
+ /** The former node name of the earliest single-purpose block: it had no type attribute, its Block type is `section`. */
63
+ const EARLIEST_BLOCK = "section";
64
+ /** Node names that carry their Block type id in the attribute `kind` was. */
65
+ const BLOCK_TYPE_NODES = [TYPED_BLOCK, "opaqueFence"];
66
+ /**
67
+ * Whether stored content with a node (or Yjs element) named `nodeName` and these `attributes` still uses an old persisted
68
+ * name: the node name itself, or a Typed block / opaque fence that still has the `kind` attribute.
69
+ */
70
+ function isOldPersistedNode(nodeName, attributes, options = {}) {
71
+ return renamedNode(nodeName, options) !== void 0 || BLOCK_TYPE_NODES.includes(nodeName) && Object.hasOwn(attributes, OLD_BLOCK_TYPE_ATTR);
72
+ }
73
+ /**
74
+ * `json` with every old persisted name replaced by the current one; recursive, returns a copy. Idempotent (current names
75
+ * pass unchanged) and lossless: block IDs and every other attribute stay, an existing `blockType` wins over a stale `kind`.
76
+ */
77
+ function migratePersistedNames(json, options = {}) {
78
+ const result = { ...json };
79
+ const type = json.type;
80
+ const current = type ? renamedNode(type, options) ?? type : void 0;
81
+ if (current && current !== type) result.type = current;
82
+ if (current && BLOCK_TYPE_NODES.includes(current) && (json.attrs || type === EARLIEST_BLOCK)) {
83
+ const { [OLD_BLOCK_TYPE_ATTR]: kind, ...rest } = json.attrs ?? {};
84
+ const blockType = rest["blockType"] ?? kind ?? (type === EARLIEST_BLOCK && options.earliest ? EARLIEST_BLOCK : void 0);
85
+ result.attrs = blockType === void 0 ? rest : {
86
+ ...rest,
87
+ [BLOCK_TYPE_ATTR]: blockType
88
+ };
89
+ }
90
+ if (json.content) result.content = json.content.map((child) => migratePersistedNames(child, options));
91
+ return result;
92
+ }
93
+ //#endregion
94
+ export { BLOCK_TYPE_ATTR, OLD_HTML, TYPED_BLOCK, TYPED_BLOCK_CLASS, TYPED_BLOCK_DESCRIPTION, TYPED_BLOCK_TAGS, TYPED_BLOCK_TITLE, isOldPersistedNode, migratePersistedNames };
95
+
96
+ //# sourceMappingURL=persisted-names.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"persisted-names.js","names":[],"sources":["../../../src/core/schema/persisted-names.ts"],"sourcesContent":["import type { JSONContent } from '@tiptap/core'\n\n/**\n * The persisted names of Typed blocks before the vocabulary of `CONTEXT.md` (Typed block, Block type) replaced them, and\n * the one load-time migration that maps them to the current names. Stored documents (JSON store, Yjs state, `.cdoc`\n * packages, Markdown-free clipboard and drag payloads) written by earlier releases carry them; the rule is: old names are\n * READ wherever content enters and never written. Nothing else in the code base spells them.\n *\n * Nodes: `composite` -> `typedBlock`, with the chrome nodes `compositeTitle`/`compositeDescription`/`compositeTags` ->\n * `typedBlockTitle`/`typedBlockDescription`/`typedBlockTags`; with `options.earliest` also the single-purpose `section`\n * family of the earliest dev releases (`section`, `sectionTitle`, `sectionSummary`, `sectionTags`), which maps to the same\n * targets (a `section` becomes a Typed block of Block type `section`). Attribute: `kind` -> `blockType` on a Typed block and on an `opaqueFence`.\n */\n\n/** Node name of a Typed block. */\nexport const TYPED_BLOCK = 'typedBlock'\nexport const TYPED_BLOCK_TITLE = 'typedBlockTitle'\nexport const TYPED_BLOCK_DESCRIPTION = 'typedBlockDescription'\nexport const TYPED_BLOCK_TAGS = 'typedBlockTags'\n\n/**\n * CSS class of a Typed block's node view root (`section.composite`). Styling, not a persisted name: the shipped sheets, the\n * chrome anchors (`compositeSectionOf`) and host themes select `.composite`, as they did before the rename. It is spelled\n * here because `legacy-names` lets this file (and only this file) quote the word; the BEM children `composite__toggle` and\n * `composite__content` and the title class `composite-title` are no bare quoted name and need no entry. The HTML node\n * name stays `data-type=\"typedBlock\"`.\n */\nexport const TYPED_BLOCK_CLASS = 'composite'\n\n/** Attribute that holds the id of a Typed block's (and an opaque fence's) Block type. */\nexport const BLOCK_TYPE_ATTR = 'blockType'\n\n/** Node name stored before -> current node name. */\nconst RENAMED_NODES: Readonly<Record<string, string>> = {\n composite: TYPED_BLOCK,\n compositeTitle: TYPED_BLOCK_TITLE,\n compositeDescription: TYPED_BLOCK_DESCRIPTION,\n compositeTags: TYPED_BLOCK_TAGS,\n}\n\n/**\n * The single-purpose `section` family of the earliest dev releases -> current node name. Only for content of editors\n * with Typed blocks (`options.earliest`): a host may have a node of its own named `section`.\n */\nconst EARLIEST_NODES: Readonly<Record<string, string>> = {\n section: TYPED_BLOCK,\n sectionTitle: TYPED_BLOCK_TITLE,\n sectionSummary: TYPED_BLOCK_DESCRIPTION,\n sectionTags: TYPED_BLOCK_TAGS,\n}\n\nexport interface PersistedNamesOptions {\n /** Also map the earliest `section` family (content of an editor with Typed blocks). Default `false`. */\n earliest?: boolean\n}\n\nconst renamedNode = (nodeName: string, options: PersistedNamesOptions): string | undefined =>\n Object.hasOwn(RENAMED_NODES, nodeName) ? RENAMED_NODES[nodeName] : options.earliest && Object.hasOwn(EARLIEST_NODES, nodeName) ? EARLIEST_NODES[nodeName] : undefined\n\n/** The HTML names markup written before the rename carries; the node parse rules read them, nothing writes them (the Markdown fence needs no entry: its keyword is a Block type id and did not change). */\nexport const OLD_HTML = {\n typedBlock: 'composite',\n // i18n-ignore: HTML data-type of stored markup, not UI text\n title: 'composite-title',\n // i18n-ignore: HTML data-type of stored markup, not UI text\n description: 'composite-description',\n tags: 'composite-tags',\n /** The earliest dev releases' single-purpose `section` family: element `data-type`s of the block and its title, summary and tags. */\n earliestBlock: 'section',\n // i18n-ignore: HTML data-type of stored markup, not UI text\n earliestTitle: 'section-title',\n // i18n-ignore: HTML data-type of stored markup, not UI text\n earliestDescription: 'section-summary',\n // i18n-ignore: HTML data-type of stored markup, not UI text\n earliestTags: 'section-tags',\n /** Attribute of the Block type id on the Typed block's element. */\n blockTypeAttr: 'data-kind',\n} as const\n\n/** The former attribute name of the Block type id. */\nconst OLD_BLOCK_TYPE_ATTR = 'kind'\n\n/** The former node name of the earliest single-purpose block: it had no type attribute, its Block type is `section`. */\nconst EARLIEST_BLOCK = 'section'\n\n/** Node names that carry their Block type id in the attribute `kind` was. */\nconst BLOCK_TYPE_NODES: readonly string[] = [TYPED_BLOCK, 'opaqueFence']\n\n/**\n * Whether stored content with a node (or Yjs element) named `nodeName` and these `attributes` still uses an old persisted\n * name: the node name itself, or a Typed block / opaque fence that still has the `kind` attribute.\n */\nexport function isOldPersistedNode(nodeName: string, attributes: Readonly<Record<string, unknown>>, options: PersistedNamesOptions = {}): boolean {\n return renamedNode(nodeName, options) !== undefined || (BLOCK_TYPE_NODES.includes(nodeName) && Object.hasOwn(attributes, OLD_BLOCK_TYPE_ATTR))\n}\n\n/**\n * `json` with every old persisted name replaced by the current one; recursive, returns a copy. Idempotent (current names\n * pass unchanged) and lossless: block IDs and every other attribute stay, an existing `blockType` wins over a stale `kind`.\n */\nexport function migratePersistedNames(json: JSONContent, options: PersistedNamesOptions = {}): JSONContent {\n const result: JSONContent = { ...json }\n const type = json.type\n const current = type ? (renamedNode(type, options) ?? type) : undefined\n if (current && current !== type) result.type = current\n if (current && BLOCK_TYPE_NODES.includes(current) && (json.attrs || type === EARLIEST_BLOCK)) {\n const { [OLD_BLOCK_TYPE_ATTR]: kind, ...rest } = json.attrs ?? {}\n const blockType = rest[BLOCK_TYPE_ATTR] ?? kind ?? (type === EARLIEST_BLOCK && options.earliest ? EARLIEST_BLOCK : undefined)\n result.attrs = blockType === undefined ? rest : { ...rest, [BLOCK_TYPE_ATTR]: blockType }\n }\n if (json.content) result.content = json.content.map(child => migratePersistedNames(child, options))\n return result\n}\n"],"mappings":";;;;;;;;;;;;;AAeA,MAAa,cAAc;AAC3B,MAAa,oBAAoB;AACjC,MAAa,0BAA0B;AACvC,MAAa,mBAAmB;;;;;;;;AAShC,MAAa,oBAAoB;;AAGjC,MAAa,kBAAkB;;AAG/B,MAAM,gBAAkD;CACtD,WAAW;CACX,gBAAgB;CAChB,sBAAsB;CACtB,eAAe;AACjB;;;;;AAMA,MAAM,iBAAmD;CACvD,SAAS;CACT,cAAc;CACd,gBAAgB;CAChB,aAAa;AACf;AAOA,MAAM,eAAe,UAAkB,YACrC,OAAO,OAAO,eAAe,QAAQ,IAAI,cAAc,YAAY,QAAQ,YAAY,OAAO,OAAO,gBAAgB,QAAQ,IAAI,eAAe,YAAY,KAAA;;AAG9J,MAAa,WAAW;CACtB,YAAY;CAEZ,OAAO;CAEP,aAAa;CACb,MAAM;;CAEN,eAAe;CAEf,eAAe;CAEf,qBAAqB;CAErB,cAAc;;CAEd,eAAe;AACjB;;AAGA,MAAM,sBAAsB;;AAG5B,MAAM,iBAAiB;;AAGvB,MAAM,mBAAsC,CAAC,aAAa,aAAa;;;;;AAMvE,SAAgB,mBAAmB,UAAkB,YAA+C,UAAiC,CAAC,GAAY;CAChJ,OAAO,YAAY,UAAU,OAAO,MAAM,KAAA,KAAc,iBAAiB,SAAS,QAAQ,KAAK,OAAO,OAAO,YAAY,mBAAmB;AAC9I;;;;;AAMA,SAAgB,sBAAsB,MAAmB,UAAiC,CAAC,GAAgB;CACzG,MAAM,SAAsB,EAAE,GAAG,KAAK;CACtC,MAAM,OAAO,KAAK;CAClB,MAAM,UAAU,OAAQ,YAAY,MAAM,OAAO,KAAK,OAAQ,KAAA;CAC9D,IAAI,WAAW,YAAY,MAAM,OAAO,OAAO;CAC/C,IAAI,WAAW,iBAAiB,SAAS,OAAO,MAAM,KAAK,SAAS,SAAS,iBAAiB;EAC5F,MAAM,GAAG,sBAAsB,MAAM,GAAG,SAAS,KAAK,SAAS,CAAC;EAChE,MAAM,YAAY,KAAA,gBAAyB,SAAS,SAAS,kBAAkB,QAAQ,WAAW,iBAAiB,KAAA;EACnH,OAAO,QAAQ,cAAc,KAAA,IAAY,OAAO;GAAE,GAAG;IAAO,kBAAkB;EAAU;CAC1F;CACA,IAAI,KAAK,SAAS,OAAO,UAAU,KAAK,QAAQ,KAAI,UAAS,sBAAsB,OAAO,OAAO,CAAC;CAClG,OAAO;AACT"}
@@ -43,7 +43,7 @@ const CORE_TOOLBAR_GROUPS = [
43
43
  * types (headings, lists, quote, code block, rule) are also in the `/` menu.
44
44
  */
45
45
  function coreCommands(ctx) {
46
- const headingsShown = (editor) => ctx.settings.get().blocks.structure === "flat" || !editor.schema.nodes.composite;
46
+ const headingsShown = (editor) => ctx.settings.get().blocks.structure === "flat" || !editor.schema.nodes.typedBlock;
47
47
  return [
48
48
  command({
49
49
  id: "undo",
@@ -1 +1 @@
1
- {"version":3,"file":"toolbar-items.js","names":[],"sources":["../../src/core/toolbar-items.ts"],"sourcesContent":["import type { Editor } from '@tiptap/core'\nimport type { CommandDef, ToolbarGroupDef } from './command-types'\nimport type { FeatureContext } from './feature'\nimport { ABILITY } from './schema/abilities'\nimport { command } from './commands'\n\n/**\n * The toolbar groups of the core UI (undo/redo, paragraph and headings, text marks, lists/quote/code block/rule) and the\n * two groups other features' commands name: `inserts` (media, transcript, …) and `collaboration` (comments, authors).\n * Orders leave room for the groups features contribute (composites and tables 60, AI 1000).\n */\nexport const CORE_TOOLBAR_GROUPS: ToolbarGroupDef[] = [\n { id: 'history', order: 10, labelKey: 'palette.group.history' },\n { id: 'block-type', order: 20, labelKey: 'palette.group.blockType' },\n { id: 'marks', order: 30, labelKey: 'palette.group.marks' },\n { id: 'blocks', order: 40, labelKey: 'palette.group.blocks' },\n { id: 'inserts', order: 50, labelKey: 'palette.group.inserts' },\n { id: 'collaboration', order: 1010, labelKey: 'palette.group.collaboration' },\n]\n\n/**\n * The core commands: undo/redo, paragraph and headings, text marks, lists, quote, code block and rule. The five block\n * types (headings, lists, quote, code block, rule) are also in the `/` menu.\n */\nexport function coreCommands(ctx: FeatureContext): CommandDef<never>[] {\n // Headings are the document structure in the flat setting, and always where the schema has no composites to structure with.\n const headingsShown = (editor: Editor) => ctx.settings.get().blocks.structure === 'flat' || !editor.schema.nodes.composite\n return [\n command({ id: 'undo', toolbar: { group: 'history', order: 10 }, icon: 'i-lucide-undo-2', label: ctx.t('toolbar.undo'), kbds: ['meta', 'z'], command: c => c.undo() }),\n command({ id: 'redo', toolbar: { group: 'history', order: 20 }, icon: 'i-lucide-redo-2', label: ctx.t('toolbar.redo'), kbds: ['meta', 'shift', 'z'], command: c => c.redo() }),\n command({ id: 'paragraph', toolbar: { group: 'block-type', order: 10 }, icon: 'i-lucide-pilcrow', label: ctx.t('toolbar.paragraph'), kbds: ['meta', 'alt', '0'], command: c => c.setParagraph(), active: e => e.isActive('paragraph') }),\n // With composites in the schema, the 'composite' structure shows Bausteine instead of H1–H3.\n ...([1, 2, 3] as const).map(level => command({\n id: `heading${level}`,\n toolbar: { group: 'block-type', order: 20 + level },\n slash: { id: `h${level}` },\n creates: { type: 'heading', attrs: { level } },\n icon: `i-lucide-heading-${level}`,\n label: ctx.t('toolbar.heading', { level }),\n kbds: ['meta', 'alt', String(level)],\n ability: ABILITY.headings,\n command: c => c.toggleHeading({ level }),\n active: e => e.isActive('heading', { level }),\n // `coreContent: { headings: { levels } }` limits the levels; the heading extension holds the allowed ones.\n visible: editor => headingsShown(editor) && ((editor.extensionManager.extensions.find(extension => extension.name === 'heading')?.options.levels as number[] | undefined)?.includes(level) ?? true),\n })),\n command({ id: 'bold', toolbar: { group: 'marks', order: 10 }, icon: 'i-lucide-bold', label: ctx.t('toolbar.bold'), kbds: ['meta', 'b'], ability: ABILITY.marks, command: c => c.toggleBold(), active: e => e.isActive('bold') }),\n command({ id: 'italic', toolbar: { group: 'marks', order: 20 }, icon: 'i-lucide-italic', label: ctx.t('toolbar.italic'), kbds: ['meta', 'i'], ability: ABILITY.marks, command: c => c.toggleItalic(), active: e => e.isActive('italic') }),\n command({ id: 'underline', toolbar: { group: 'marks', order: 30 }, icon: 'i-lucide-underline', label: ctx.t('toolbar.underline'), kbds: ['meta', 'u'], ability: ABILITY.marks, command: c => c.toggleUnderline(), active: e => e.isActive('underline') }),\n // Mod-Shift-s is the speaker segment, so strike is rebound to Mod-Shift-x (StrikeX).\n command({ id: 'strike', toolbar: { group: 'marks', order: 40 }, icon: 'i-lucide-strikethrough', label: ctx.t('toolbar.strike'), kbds: ['meta', 'shift', 'x'], ability: ABILITY.marks, command: c => c.toggleStrike(), active: e => e.isActive('strike') }),\n command({ id: 'code', toolbar: { group: 'marks', order: 50 }, icon: 'i-lucide-code', label: ctx.t('toolbar.code'), kbds: ['meta', 'e'], ability: ABILITY.marks, command: c => c.toggleCode(), active: e => e.isActive('code') }),\n command({ id: 'bulletList', toolbar: { group: 'blocks', order: 10 }, slash: { id: 'liste' }, creates: { type: 'bulletList' }, icon: 'i-lucide-list', label: ctx.t('toolbar.bulletList'), kbds: ['meta', 'shift', '8'], ability: ABILITY.lists, command: c => c.toggleBulletList(), active: e => e.isActive('bulletList') }),\n command({ id: 'orderedList', toolbar: { group: 'blocks', order: 20 }, slash: { id: 'nummerierung' }, creates: { type: 'orderedList' }, icon: 'i-lucide-list-ordered', label: ctx.t('toolbar.orderedList'), kbds: ['meta', 'shift', '7'], ability: ABILITY.lists, command: c => c.toggleOrderedList(), active: e => e.isActive('orderedList') }),\n command({ id: 'blockquote', toolbar: { group: 'blocks', order: 30 }, slash: { id: 'zitat' }, creates: { type: 'blockquote' }, icon: 'i-lucide-text-quote', label: ctx.t('toolbar.blockquote'), kbds: ['meta', 'shift', 'b'], ability: ABILITY.blockquote, command: c => c.toggleBlockquote(), active: e => e.isActive('blockquote') }),\n command({ id: 'codeBlock', toolbar: { group: 'blocks', order: 40 }, slash: { id: 'codeblock' }, creates: { type: 'codeBlock' }, icon: 'i-lucide-square-code', label: ctx.t('toolbar.codeBlock'), kbds: ['meta', 'alt', 'c'], ability: ABILITY.codeBlock, command: c => c.toggleCodeBlock(), active: e => e.isActive('codeBlock') }),\n command({ id: 'rule', toolbar: { group: 'blocks', order: 50 }, slash: { id: 'trennlinie' }, creates: { type: 'horizontalRule' }, icon: 'i-lucide-minus', label: ctx.t('toolbar.rule'), ability: ABILITY.rule, command: c => c.setHorizontalRule() }),\n ]\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"toolbar-items.js","names":[],"sources":["../../src/core/toolbar-items.ts"],"sourcesContent":["import type { Editor } from '@tiptap/core'\nimport type { CommandDef, ToolbarGroupDef } from './command-types'\nimport type { FeatureContext } from './feature'\nimport { ABILITY } from './schema/abilities'\nimport { command } from './commands'\n\n/**\n * The toolbar groups of the core UI (undo/redo, paragraph and headings, text marks, lists/quote/code block/rule) and the\n * two groups other features' commands name: `inserts` (media, transcript, …) and `collaboration` (comments, authors).\n * Orders leave room for the groups features contribute (composites and tables 60, AI 1000).\n */\nexport const CORE_TOOLBAR_GROUPS: ToolbarGroupDef[] = [\n { id: 'history', order: 10, labelKey: 'palette.group.history' },\n { id: 'block-type', order: 20, labelKey: 'palette.group.blockType' },\n { id: 'marks', order: 30, labelKey: 'palette.group.marks' },\n { id: 'blocks', order: 40, labelKey: 'palette.group.blocks' },\n { id: 'inserts', order: 50, labelKey: 'palette.group.inserts' },\n { id: 'collaboration', order: 1010, labelKey: 'palette.group.collaboration' },\n]\n\n/**\n * The core commands: undo/redo, paragraph and headings, text marks, lists, quote, code block and rule. The five block\n * types (headings, lists, quote, code block, rule) are also in the `/` menu.\n */\nexport function coreCommands(ctx: FeatureContext): CommandDef<never>[] {\n // Headings are the document structure in the flat setting, and always where the schema has no composites to structure with.\n const headingsShown = (editor: Editor) => ctx.settings.get().blocks.structure === 'flat' || !editor.schema.nodes.typedBlock\n return [\n command({ id: 'undo', toolbar: { group: 'history', order: 10 }, icon: 'i-lucide-undo-2', label: ctx.t('toolbar.undo'), kbds: ['meta', 'z'], command: c => c.undo() }),\n command({ id: 'redo', toolbar: { group: 'history', order: 20 }, icon: 'i-lucide-redo-2', label: ctx.t('toolbar.redo'), kbds: ['meta', 'shift', 'z'], command: c => c.redo() }),\n command({ id: 'paragraph', toolbar: { group: 'block-type', order: 10 }, icon: 'i-lucide-pilcrow', label: ctx.t('toolbar.paragraph'), kbds: ['meta', 'alt', '0'], command: c => c.setParagraph(), active: e => e.isActive('paragraph') }),\n // With composites in the schema, the 'structured' structure shows Typed blocks instead of H1–H3.\n ...([1, 2, 3] as const).map(level => command({\n id: `heading${level}`,\n toolbar: { group: 'block-type', order: 20 + level },\n slash: { id: `h${level}` },\n creates: { type: 'heading', attrs: { level } },\n icon: `i-lucide-heading-${level}`,\n label: ctx.t('toolbar.heading', { level }),\n kbds: ['meta', 'alt', String(level)],\n ability: ABILITY.headings,\n command: c => c.toggleHeading({ level }),\n active: e => e.isActive('heading', { level }),\n // `coreContent: { headings: { levels } }` limits the levels; the heading extension holds the allowed ones.\n visible: editor => headingsShown(editor) && ((editor.extensionManager.extensions.find(extension => extension.name === 'heading')?.options.levels as number[] | undefined)?.includes(level) ?? true),\n })),\n command({ id: 'bold', toolbar: { group: 'marks', order: 10 }, icon: 'i-lucide-bold', label: ctx.t('toolbar.bold'), kbds: ['meta', 'b'], ability: ABILITY.marks, command: c => c.toggleBold(), active: e => e.isActive('bold') }),\n command({ id: 'italic', toolbar: { group: 'marks', order: 20 }, icon: 'i-lucide-italic', label: ctx.t('toolbar.italic'), kbds: ['meta', 'i'], ability: ABILITY.marks, command: c => c.toggleItalic(), active: e => e.isActive('italic') }),\n command({ id: 'underline', toolbar: { group: 'marks', order: 30 }, icon: 'i-lucide-underline', label: ctx.t('toolbar.underline'), kbds: ['meta', 'u'], ability: ABILITY.marks, command: c => c.toggleUnderline(), active: e => e.isActive('underline') }),\n // Mod-Shift-s is the speaker segment, so strike is rebound to Mod-Shift-x (StrikeX).\n command({ id: 'strike', toolbar: { group: 'marks', order: 40 }, icon: 'i-lucide-strikethrough', label: ctx.t('toolbar.strike'), kbds: ['meta', 'shift', 'x'], ability: ABILITY.marks, command: c => c.toggleStrike(), active: e => e.isActive('strike') }),\n command({ id: 'code', toolbar: { group: 'marks', order: 50 }, icon: 'i-lucide-code', label: ctx.t('toolbar.code'), kbds: ['meta', 'e'], ability: ABILITY.marks, command: c => c.toggleCode(), active: e => e.isActive('code') }),\n command({ id: 'bulletList', toolbar: { group: 'blocks', order: 10 }, slash: { id: 'liste' }, creates: { type: 'bulletList' }, icon: 'i-lucide-list', label: ctx.t('toolbar.bulletList'), kbds: ['meta', 'shift', '8'], ability: ABILITY.lists, command: c => c.toggleBulletList(), active: e => e.isActive('bulletList') }),\n command({ id: 'orderedList', toolbar: { group: 'blocks', order: 20 }, slash: { id: 'nummerierung' }, creates: { type: 'orderedList' }, icon: 'i-lucide-list-ordered', label: ctx.t('toolbar.orderedList'), kbds: ['meta', 'shift', '7'], ability: ABILITY.lists, command: c => c.toggleOrderedList(), active: e => e.isActive('orderedList') }),\n command({ id: 'blockquote', toolbar: { group: 'blocks', order: 30 }, slash: { id: 'zitat' }, creates: { type: 'blockquote' }, icon: 'i-lucide-text-quote', label: ctx.t('toolbar.blockquote'), kbds: ['meta', 'shift', 'b'], ability: ABILITY.blockquote, command: c => c.toggleBlockquote(), active: e => e.isActive('blockquote') }),\n command({ id: 'codeBlock', toolbar: { group: 'blocks', order: 40 }, slash: { id: 'codeblock' }, creates: { type: 'codeBlock' }, icon: 'i-lucide-square-code', label: ctx.t('toolbar.codeBlock'), kbds: ['meta', 'alt', 'c'], ability: ABILITY.codeBlock, command: c => c.toggleCodeBlock(), active: e => e.isActive('codeBlock') }),\n command({ id: 'rule', toolbar: { group: 'blocks', order: 50 }, slash: { id: 'trennlinie' }, creates: { type: 'horizontalRule' }, icon: 'i-lucide-minus', label: ctx.t('toolbar.rule'), ability: ABILITY.rule, command: c => c.setHorizontalRule() }),\n ]\n}\n"],"mappings":"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"}
package/dist/core/util.js CHANGED
@@ -5,7 +5,11 @@ function fail(message, scope) {
5
5
  }
6
6
  /** Sort comparator for `{ order?: number }` entries (ascending, unset = 0); `Array.prototype.sort` is stable, so ties keep declaration order. */
7
7
  const byOrder = (a, b) => (a.order ?? 0) - (b.order ?? 0);
8
+ /** `definitions[0].type` for a zod issue path. */
9
+ const pathText = (path) => path.map((part, position) => typeof part === "number" ? `[${part}]` : `${position ? "." : ""}${String(part)}`).join("");
10
+ /** The node that starts at `pos` in `doc`; null when `pos` lies outside the document or no node starts there. */
11
+ const nodeAtPos = (doc, pos) => pos >= 0 && pos <= doc.content.size ? doc.nodeAt(pos) : null;
8
12
  //#endregion
9
- export { byOrder, fail };
13
+ export { byOrder, fail, nodeAtPos, pathText };
10
14
 
11
15
  //# sourceMappingURL=util.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"util.js","names":[],"sources":["../../src/core/util.ts"],"sourcesContent":["/** Throws the library's error: `@ecsplico/editor: [<scope>: ]<message>`. */\nexport function fail(message: string, scope?: string): never {\n throw new Error(`@ecsplico/editor: ${scope ? `${scope}: ` : ''}${message}`)\n}\n\n/** Sort comparator for `{ order?: number }` entries (ascending, unset = 0); `Array.prototype.sort` is stable, so ties keep declaration order. */\nexport const byOrder = <T extends { order?: number }>(a: T, b: T) => (a.order ?? 0) - (b.order ?? 0)\n"],"mappings":";;AACA,SAAgB,KAAK,SAAiB,OAAuB;CAC3D,MAAM,IAAI,MAAM,qBAAqB,QAAQ,GAAG,MAAM,MAAM,KAAK,SAAS;AAC5E;;AAGA,MAAa,WAAyC,GAAM,OAAU,EAAE,SAAS,MAAM,EAAE,SAAS"}
1
+ {"version":3,"file":"util.js","names":[],"sources":["../../src/core/util.ts"],"sourcesContent":["import type { Node as PMNode } from '@tiptap/pm/model'\n\n/** Throws the library's error: `@ecsplico/editor: [<scope>: ]<message>`. */\nexport function fail(message: string, scope?: string): never {\n throw new Error(`@ecsplico/editor: ${scope ? `${scope}: ` : ''}${message}`)\n}\n\n/** Sort comparator for `{ order?: number }` entries (ascending, unset = 0); `Array.prototype.sort` is stable, so ties keep declaration order. */\nexport const byOrder = <T extends { order?: number }>(a: T, b: T) => (a.order ?? 0) - (b.order ?? 0)\n\n/** `definitions[0].type` for a zod issue path. */\nexport const pathText = (path: readonly PropertyKey[]): string =>\n path.map((part, position) => typeof part === 'number' ? `[${part}]` : `${position ? '.' : ''}${String(part)}`).join('')\n\n/** The node that starts at `pos` in `doc`; null when `pos` lies outside the document or no node starts there. */\nexport const nodeAtPos = (doc: PMNode, pos: number): PMNode | null => pos >= 0 && pos <= doc.content.size ? doc.nodeAt(pos) : null\n"],"mappings":";;AAGA,SAAgB,KAAK,SAAiB,OAAuB;CAC3D,MAAM,IAAI,MAAM,qBAAqB,QAAQ,GAAG,MAAM,MAAM,KAAK,SAAS;AAC5E;;AAGA,MAAa,WAAyC,GAAM,OAAU,EAAE,SAAS,MAAM,EAAE,SAAS;;AAGlG,MAAa,YAAY,SACvB,KAAK,KAAK,MAAM,aAAa,OAAO,SAAS,WAAW,IAAI,KAAK,KAAK,GAAG,WAAW,MAAM,KAAK,OAAO,IAAI,GAAG,CAAC,CAAC,KAAK,EAAE;;AAGxH,MAAa,aAAa,KAAa,QAA+B,OAAO,KAAK,OAAO,IAAI,QAAQ,OAAO,IAAI,OAAO,GAAG,IAAI"}
@@ -1,8 +1,8 @@
1
1
  import { stripListMarkerEcho } from "./protocol/block-lines.js";
2
2
  import { agentOpTarget } from "./protocol/agent-ops.js";
3
- import { conversionsOf, parseBlocks } from "../../core/pipeline.js";
4
3
  import { blockIdOf, findBlockById } from "../../core/schema/block-ids.js";
5
4
  import { isBlockContainer, isChromeNode } from "../../core/schema/node-flags.js";
5
+ import { conversionsOf, parseBlocks } from "../../core/pipeline.js";
6
6
  import { isWrapperBlock } from "../../core/convert.js";
7
7
  import { blockConversion, parseConversionTarget } from "../../core/block-convert.js";
8
8
  import { captureRange } from "../../core/doc-anchors.js";
@@ -1,5 +1,5 @@
1
- import { parseBlocks, structureBlocks } from "../../core/pipeline.js";
2
1
  import "../../core/schema/block-ids.js";
2
+ import { parseBlocks, structureBlocks } from "../../core/pipeline.js";
3
3
  import { anchorResolverOf, captureRange, docAnchorsKey, resolveRange } from "../../core/doc-anchors.js";
4
4
  import { inlineReplacement, replaceRangeWithBlocks } from "./ai-apply.js";
5
5
  import { Extension } from "@tiptap/core";
@@ -1,6 +1,6 @@
1
1
  import { ReadonlyStore } from "../../core/store.js";
2
2
  import { Translate } from "../../i18n/index.js";
3
- import { AiLanguage, ModelSlot } from "../../settings/values.js";
3
+ import { AiLanguage, ModelRole } from "../../settings/values.js";
4
4
  import "../../settings/index.js";
5
5
  import { EditorBackend } from "../../core/backend.js";
6
6
  import { Notifier } from "../../core/notify.js";
@@ -27,11 +27,11 @@ export interface AiAssistantState {
27
27
  output: string;
28
28
  error: string | null;
29
29
  }
30
- /** What `createAiAssistant` needs from the app: the AI port, the model of a slot, the notifier and translator for the 429 notice and failures. */
30
+ /** What `createAiAssistant` needs from the app: the AI port, the model of a Model role, the notifier and translator for the 429 notice and failures. */
31
31
  export interface AiAssistantOptions {
32
32
  /** `EditorContext.backend.ai`; without it every run ends in the error state (501), like a server without AI. */
33
33
  ai: EditorBackend['ai'];
34
- modelRef: (slot: ModelSlot) => ModelRef;
34
+ modelRef: (slot: ModelRole) => ModelRef;
35
35
  /** Receives the 429 notice. */
36
36
  notify: Notifier;
37
37
  /** The app's translator (`EditorContext.t`). */
@@ -48,7 +48,7 @@ export interface AiAssistant {
48
48
  /** Clears the error message; the status stays. */
49
49
  clearError: () => void;
50
50
  }
51
- /** Streams the backend's `generate` (SSE: `delta` / `done` / `error` events) into a store, on the task's model slot. */
51
+ /** Streams the backend's `generate` (SSE: `delta` / `done` / `error` events) into a store, on the task's Model role. */
52
52
  export declare function createAiAssistant({ ai, modelRef, notify, t }: AiAssistantOptions): AiAssistant;
53
53
  //#endregion
54
54
  //# sourceMappingURL=assistant.d.ts.map
@@ -8,7 +8,7 @@ const IDLE = {
8
8
  output: "",
9
9
  error: null
10
10
  };
11
- /** Streams the backend's `generate` (SSE: `delta` / `done` / `error` events) into a store, on the task's model slot. */
11
+ /** Streams the backend's `generate` (SSE: `delta` / `done` / `error` events) into a store, on the task's Model role. */
12
12
  function createAiAssistant({ ai, modelRef, notify, t }) {
13
13
  const store = createStore(IDLE);
14
14
  let controller = null;
@@ -1 +1 @@
1
- {"version":3,"file":"assistant.js","names":[],"sources":["../../../src/features/ai/assistant.ts"],"sourcesContent":["import type { EditorBackend } from '../../core/backend'\nimport type { AiBlock } from '../../core/feature'\nimport type { Notifier } from '../../core/notify'\nimport { createStore, type ReadonlyStore } from '../../core/store'\nimport type { Translate } from '../../i18n'\nimport type { AiLanguage, ModelSlot } from '../../settings'\nimport { postAiSse } from './ai-sse'\nimport { AI_TASKS, type AiBlockInput, type AiTaskId, type ModelRef } from './protocol'\nimport { notifyAiRateLimited } from './rate-limit'\n\nexport type AiStatus = 'idle' | 'streaming' | 'done' | 'error'\n\nexport interface AiRunBody {\n task: AiTaskId\n prompt: string\n selection: string\n context: string\n language?: AiLanguage\n /** The editor's host blocks (`aiContextOf(editor).blocks`), listed in the task's system prompt. */\n blocks?: readonly AiBlock[]\n /** The block of a `needsBlock` task (`fill-block`): its brief and material. */\n block?: AiBlockInput\n}\n\n/** Snapshot of the running or last request: its status, the streamed text so far and the error message. */\nexport interface AiAssistantState {\n status: AiStatus\n output: string\n error: string | null\n}\n\n/** What `createAiAssistant` needs from the app: the AI port, the model of a slot, the notifier and translator for the 429 notice and failures. */\nexport interface AiAssistantOptions {\n /** `EditorContext.backend.ai`; without it every run ends in the error state (501), like a server without AI. */\n ai: EditorBackend['ai']\n modelRef: (slot: ModelSlot) => ModelRef\n /** Receives the 429 notice. */\n notify: Notifier\n /** The app's translator (`EditorContext.t`). */\n t: Translate\n}\n\n/** The streaming assistant: observe `state`, `run` a task, `abort`/`reset` it. */\nexport interface AiAssistant {\n state: ReadonlyStore<AiAssistantState>\n run: (body: AiRunBody) => Promise<void>\n /** Stops the running request (its outcome is `idle`). */\n abort: () => void\n /** Aborts and returns to the empty `idle` state. */\n reset: () => void\n /** Clears the error message; the status stays. */\n clearError: () => void\n}\n\nconst IDLE: AiAssistantState = { status: 'idle', output: '', error: null }\n\n/** Streams the backend's `generate` (SSE: `delta` / `done` / `error` events) into a store, on the task's model slot. */\nexport function createAiAssistant({ ai, modelRef, notify, t }: AiAssistantOptions): AiAssistant {\n const store = createStore<AiAssistantState>(IDLE)\n let controller: AbortController | null = null\n\n function abort() {\n controller?.abort()\n }\n\n function reset() {\n abort()\n controller = null\n store.set(IDLE)\n }\n\n function clearError() {\n const state = store.get()\n if (state.error !== null) store.set({ ...state, error: null })\n }\n\n async function run(body: AiRunBody): Promise<void> {\n reset()\n const own = new AbortController()\n controller = own\n store.set({ status: 'streaming', output: '', error: null })\n const outcome = await postAiSse(ai, 'generate', { ...body, model: modelRef(AI_TASKS[body.task].slot) }, {\n signal: own.signal,\n t,\n onDelta: (text) => {\n if (controller === own) store.set({ ...store.get(), output: store.get().output + text })\n },\n })\n if (controller !== own) return // superseded by reset()/another run\n controller = null\n if (outcome.status === 'done') {\n store.set({ ...store.get(), status: 'done' })\n }\n else if (outcome.status === 'error') {\n store.set({ ...store.get(), status: 'error', error: outcome.message })\n }\n else {\n // Notice instead of the error state on 429, so the caller stays ready for another try.\n if (outcome.status === 'rate-limited') notifyAiRateLimited(notify, t)\n store.set({ ...store.get(), status: 'idle' })\n }\n }\n\n return { state: store, run, abort, reset, clearError }\n}\n"],"mappings":";;;;;AAsDA,MAAM,OAAyB;CAAE,QAAQ;CAAQ,QAAQ;CAAI,OAAO;AAAK;;AAGzE,SAAgB,kBAAkB,EAAE,IAAI,UAAU,QAAQ,KAAsC;CAC9F,MAAM,QAAQ,YAA8B,IAAI;CAChD,IAAI,aAAqC;CAEzC,SAAS,QAAQ;EACf,YAAY,MAAM;CACpB;CAEA,SAAS,QAAQ;EACf,MAAM;EACN,aAAa;EACb,MAAM,IAAI,IAAI;CAChB;CAEA,SAAS,aAAa;EACpB,MAAM,QAAQ,MAAM,IAAI;EACxB,IAAI,MAAM,UAAU,MAAM,MAAM,IAAI;GAAE,GAAG;GAAO,OAAO;EAAK,CAAC;CAC/D;CAEA,eAAe,IAAI,MAAgC;EACjD,MAAM;EACN,MAAM,MAAM,IAAI,gBAAgB;EAChC,aAAa;EACb,MAAM,IAAI;GAAE,QAAQ;GAAa,QAAQ;GAAI,OAAO;EAAK,CAAC;EAC1D,MAAM,UAAU,MAAM,UAAU,IAAI,YAAY;GAAE,GAAG;GAAM,OAAO,SAAS,SAAS,KAAK,KAAK,CAAC,IAAI;EAAE,GAAG;GACtG,QAAQ,IAAI;GACZ;GACA,UAAU,SAAS;IACjB,IAAI,eAAe,KAAK,MAAM,IAAI;KAAE,GAAG,MAAM,IAAI;KAAG,QAAQ,MAAM,IAAI,CAAC,CAAC,SAAS;IAAK,CAAC;GACzF;EACF,CAAC;EACD,IAAI,eAAe,KAAK;EACxB,aAAa;EACb,IAAI,QAAQ,WAAW,QACrB,MAAM,IAAI;GAAE,GAAG,MAAM,IAAI;GAAG,QAAQ;EAAO,CAAC;OAEzC,IAAI,QAAQ,WAAW,SAC1B,MAAM,IAAI;GAAE,GAAG,MAAM,IAAI;GAAG,QAAQ;GAAS,OAAO,QAAQ;EAAQ,CAAC;OAElE;GAEH,IAAI,QAAQ,WAAW,gBAAgB,oBAAoB,QAAQ,CAAC;GACpE,MAAM,IAAI;IAAE,GAAG,MAAM,IAAI;IAAG,QAAQ;GAAO,CAAC;EAC9C;CACF;CAEA,OAAO;EAAE,OAAO;EAAO;EAAK;EAAO;EAAO;CAAW;AACvD"}
1
+ {"version":3,"file":"assistant.js","names":[],"sources":["../../../src/features/ai/assistant.ts"],"sourcesContent":["import type { EditorBackend } from '../../core/backend'\nimport type { AiBlock } from '../../core/feature'\nimport type { Notifier } from '../../core/notify'\nimport { createStore, type ReadonlyStore } from '../../core/store'\nimport type { Translate } from '../../i18n'\nimport type { AiLanguage, ModelRole } from '../../settings'\nimport { postAiSse } from './ai-sse'\nimport { AI_TASKS, type AiBlockInput, type AiTaskId, type ModelRef } from './protocol'\nimport { notifyAiRateLimited } from './rate-limit'\n\nexport type AiStatus = 'idle' | 'streaming' | 'done' | 'error'\n\nexport interface AiRunBody {\n task: AiTaskId\n prompt: string\n selection: string\n context: string\n language?: AiLanguage\n /** The editor's host blocks (`aiContextOf(editor).blocks`), listed in the task's system prompt. */\n blocks?: readonly AiBlock[]\n /** The block of a `needsBlock` task (`fill-block`): its brief and material. */\n block?: AiBlockInput\n}\n\n/** Snapshot of the running or last request: its status, the streamed text so far and the error message. */\nexport interface AiAssistantState {\n status: AiStatus\n output: string\n error: string | null\n}\n\n/** What `createAiAssistant` needs from the app: the AI port, the model of a Model role, the notifier and translator for the 429 notice and failures. */\nexport interface AiAssistantOptions {\n /** `EditorContext.backend.ai`; without it every run ends in the error state (501), like a server without AI. */\n ai: EditorBackend['ai']\n modelRef: (slot: ModelRole) => ModelRef\n /** Receives the 429 notice. */\n notify: Notifier\n /** The app's translator (`EditorContext.t`). */\n t: Translate\n}\n\n/** The streaming assistant: observe `state`, `run` a task, `abort`/`reset` it. */\nexport interface AiAssistant {\n state: ReadonlyStore<AiAssistantState>\n run: (body: AiRunBody) => Promise<void>\n /** Stops the running request (its outcome is `idle`). */\n abort: () => void\n /** Aborts and returns to the empty `idle` state. */\n reset: () => void\n /** Clears the error message; the status stays. */\n clearError: () => void\n}\n\nconst IDLE: AiAssistantState = { status: 'idle', output: '', error: null }\n\n/** Streams the backend's `generate` (SSE: `delta` / `done` / `error` events) into a store, on the task's Model role. */\nexport function createAiAssistant({ ai, modelRef, notify, t }: AiAssistantOptions): AiAssistant {\n const store = createStore<AiAssistantState>(IDLE)\n let controller: AbortController | null = null\n\n function abort() {\n controller?.abort()\n }\n\n function reset() {\n abort()\n controller = null\n store.set(IDLE)\n }\n\n function clearError() {\n const state = store.get()\n if (state.error !== null) store.set({ ...state, error: null })\n }\n\n async function run(body: AiRunBody): Promise<void> {\n reset()\n const own = new AbortController()\n controller = own\n store.set({ status: 'streaming', output: '', error: null })\n const outcome = await postAiSse(ai, 'generate', { ...body, model: modelRef(AI_TASKS[body.task].slot) }, {\n signal: own.signal,\n t,\n onDelta: (text) => {\n if (controller === own) store.set({ ...store.get(), output: store.get().output + text })\n },\n })\n if (controller !== own) return // superseded by reset()/another run\n controller = null\n if (outcome.status === 'done') {\n store.set({ ...store.get(), status: 'done' })\n }\n else if (outcome.status === 'error') {\n store.set({ ...store.get(), status: 'error', error: outcome.message })\n }\n else {\n // Notice instead of the error state on 429, so the caller stays ready for another try.\n if (outcome.status === 'rate-limited') notifyAiRateLimited(notify, t)\n store.set({ ...store.get(), status: 'idle' })\n }\n }\n\n return { state: store, run, abort, reset, clearError }\n}\n"],"mappings":";;;;;AAsDA,MAAM,OAAyB;CAAE,QAAQ;CAAQ,QAAQ;CAAI,OAAO;AAAK;;AAGzE,SAAgB,kBAAkB,EAAE,IAAI,UAAU,QAAQ,KAAsC;CAC9F,MAAM,QAAQ,YAA8B,IAAI;CAChD,IAAI,aAAqC;CAEzC,SAAS,QAAQ;EACf,YAAY,MAAM;CACpB;CAEA,SAAS,QAAQ;EACf,MAAM;EACN,aAAa;EACb,MAAM,IAAI,IAAI;CAChB;CAEA,SAAS,aAAa;EACpB,MAAM,QAAQ,MAAM,IAAI;EACxB,IAAI,MAAM,UAAU,MAAM,MAAM,IAAI;GAAE,GAAG;GAAO,OAAO;EAAK,CAAC;CAC/D;CAEA,eAAe,IAAI,MAAgC;EACjD,MAAM;EACN,MAAM,MAAM,IAAI,gBAAgB;EAChC,aAAa;EACb,MAAM,IAAI;GAAE,QAAQ;GAAa,QAAQ;GAAI,OAAO;EAAK,CAAC;EAC1D,MAAM,UAAU,MAAM,UAAU,IAAI,YAAY;GAAE,GAAG;GAAM,OAAO,SAAS,SAAS,KAAK,KAAK,CAAC,IAAI;EAAE,GAAG;GACtG,QAAQ,IAAI;GACZ;GACA,UAAU,SAAS;IACjB,IAAI,eAAe,KAAK,MAAM,IAAI;KAAE,GAAG,MAAM,IAAI;KAAG,QAAQ,MAAM,IAAI,CAAC,CAAC,SAAS;IAAK,CAAC;GACzF;EACF,CAAC;EACD,IAAI,eAAe,KAAK;EACxB,aAAa;EACb,IAAI,QAAQ,WAAW,QACrB,MAAM,IAAI;GAAE,GAAG,MAAM,IAAI;GAAG,QAAQ;EAAO,CAAC;OAEzC,IAAI,QAAQ,WAAW,SAC1B,MAAM,IAAI;GAAE,GAAG,MAAM,IAAI;GAAG,QAAQ;GAAS,OAAO,QAAQ;EAAQ,CAAC;OAElE;GAEH,IAAI,QAAQ,WAAW,gBAAgB,oBAAoB,QAAQ,CAAC;GACpE,MAAM,IAAI;IAAE,GAAG,MAAM,IAAI;IAAG,QAAQ;GAAO,CAAC;EAC9C;CACF;CAEA,OAAO;EAAE,OAAO;EAAO;EAAK;EAAO;EAAO;CAAW;AACvD"}