@ecsplico/editor 3.5.1 → 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 (583) hide show
  1. package/CHANGELOG.md +71 -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/code/CodeSurface.vue.d.ts +3 -3
  15. package/dist/config/index.d.ts +14 -14
  16. package/dist/config/index.js +8 -8
  17. package/dist/config/index.js.map +1 -1
  18. package/dist/core/backend-types.d.ts +3 -3
  19. package/dist/core/backend-types.js.map +1 -1
  20. package/dist/core/backend.d.ts +4 -4
  21. package/dist/core/backend.js.map +1 -1
  22. package/dist/core/block-convert.d.ts +1 -1
  23. package/dist/core/block-convert.js +5 -5
  24. package/dist/core/block-convert.js.map +1 -1
  25. package/dist/core/block-transfer.d.ts +8 -4
  26. package/dist/core/block-transfer.js +23 -14
  27. package/dist/core/block-transfer.js.map +1 -1
  28. package/dist/core/capabilities.d.ts +113 -0
  29. package/dist/core/capabilities.js +155 -0
  30. package/dist/core/capabilities.js.map +1 -0
  31. package/dist/core/command-types.d.ts +1 -1
  32. package/dist/core/context.js.map +1 -1
  33. package/dist/core/convert.d.ts +5 -5
  34. package/dist/core/convert.js +5 -5
  35. package/dist/core/convert.js.map +1 -1
  36. package/dist/core/core-feature.js +1 -1
  37. package/dist/core/define-editor.d.ts +2 -2
  38. package/dist/core/define-editor.js +34 -6
  39. package/dist/core/define-editor.js.map +1 -1
  40. package/dist/core/derivation.d.ts +119 -0
  41. package/dist/core/derivation.js +187 -0
  42. package/dist/core/derivation.js.map +1 -0
  43. package/dist/core/derive.d.ts +61 -0
  44. package/dist/core/derive.js +69 -0
  45. package/dist/core/derive.js.map +1 -0
  46. package/dist/core/extension-points.d.ts +16 -0
  47. package/dist/core/feature-context.d.ts +5 -1
  48. package/dist/core/feature-context.js +10 -3
  49. package/dist/core/feature-context.js.map +1 -1
  50. package/dist/core/feature.d.ts +41 -19
  51. package/dist/core/feature.js.map +1 -1
  52. package/dist/core/fences.js +1 -1
  53. package/dist/core/fences.js.map +1 -1
  54. package/dist/core/index.d.ts +6 -2
  55. package/dist/core/index.js +5 -1
  56. package/dist/core/pipeline.d.ts +14 -5
  57. package/dist/core/pipeline.js +19 -7
  58. package/dist/core/pipeline.js.map +1 -1
  59. package/dist/core/properties.d.ts +22 -0
  60. package/dist/core/properties.js +17 -0
  61. package/dist/core/properties.js.map +1 -0
  62. package/dist/core/schema/block-ids.js +5 -5
  63. package/dist/core/schema/block-ids.js.map +1 -1
  64. package/dist/core/schema/index.d.ts +2 -1
  65. package/dist/core/schema/index.js +2 -1
  66. package/dist/core/schema/index.js.map +1 -1
  67. package/dist/core/schema/opaque-fence.d.ts +4 -4
  68. package/dist/core/schema/opaque-fence.js +7 -7
  69. package/dist/core/schema/opaque-fence.js.map +1 -1
  70. package/dist/core/schema/persisted-names.d.ts +58 -0
  71. package/dist/core/schema/persisted-names.js +96 -0
  72. package/dist/core/schema/persisted-names.js.map +1 -0
  73. package/dist/core/toolbar-items.js +1 -1
  74. package/dist/core/toolbar-items.js.map +1 -1
  75. package/dist/core/util.js +5 -1
  76. package/dist/core/util.js.map +1 -1
  77. package/dist/document/DocumentSurface.vue.d.ts +3 -3
  78. package/dist/features/ai/agent-ops.js +1 -1
  79. package/dist/features/ai/ai-review.js +1 -1
  80. package/dist/features/ai/assistant.d.ts +4 -4
  81. package/dist/features/ai/assistant.js +1 -1
  82. package/dist/features/ai/assistant.js.map +1 -1
  83. package/dist/features/ai/components/AiSelectionMenu.js +1 -1
  84. package/dist/features/ai/components/AiSelectionMenu.js.map +1 -1
  85. package/dist/features/ai/components/ModelQuickSwitch.js +7 -7
  86. package/dist/features/ai/components/ModelQuickSwitch.js.map +1 -1
  87. package/dist/features/ai/components/ModelQuickSwitch.vue.d.ts +4 -4
  88. package/dist/features/ai/components/SettingsAiTab.js +8 -8
  89. package/dist/features/ai/components/SettingsAiTab.js.map +1 -1
  90. package/dist/features/ai/components/SettingsModelProfiles.js +1 -1
  91. package/dist/features/ai/components/SettingsModelProfiles.js.map +1 -1
  92. package/dist/features/ai/document-chat-model.d.ts +2 -2
  93. package/dist/features/ai/document-chat-model.js +5 -5
  94. package/dist/features/ai/document-chat-model.js.map +1 -1
  95. package/dist/features/ai/document-chat.js +2 -2
  96. package/dist/features/ai/document-chat.js.map +1 -1
  97. package/dist/features/ai/feature.d.ts +2 -2
  98. package/dist/features/ai/feature.js +2 -2
  99. package/dist/features/ai/feature.js.map +1 -1
  100. package/dist/features/ai/ghost-autocomplete.d.ts +4 -4
  101. package/dist/features/ai/ghost-autocomplete.js +1 -1
  102. package/dist/features/ai/ghost-autocomplete.js.map +1 -1
  103. package/dist/features/ai/index.d.ts +3 -3
  104. package/dist/features/ai/index.js +2 -2
  105. package/dist/features/ai/model-profiles.d.ts +9 -9
  106. package/dist/features/ai/model-profiles.js +13 -13
  107. package/dist/features/ai/model-profiles.js.map +1 -1
  108. package/dist/features/ai/protocol/agent-ops.d.ts +2 -2
  109. package/dist/features/ai/protocol/agent-ops.js +1 -1
  110. package/dist/features/ai/protocol/agent-ops.js.map +1 -1
  111. package/dist/features/ai/protocol/block-lines.d.ts +7 -7
  112. package/dist/features/ai/protocol/block-lines.js +10 -10
  113. package/dist/features/ai/protocol/block-lines.js.map +1 -1
  114. package/dist/features/ai/protocol/chat.d.ts +5 -5
  115. package/dist/features/ai/protocol/chat.js +12 -12
  116. package/dist/features/ai/protocol/chat.js.map +1 -1
  117. package/dist/features/ai/protocol/generate.d.ts +1 -1
  118. package/dist/features/ai/protocol/generate.js +1 -1
  119. package/dist/features/ai/protocol/generate.js.map +1 -1
  120. package/dist/features/ai/protocol/index.d.ts +3 -3
  121. package/dist/features/ai/protocol/index.js +2 -2
  122. package/dist/features/ai/protocol/models.d.ts +3 -3
  123. package/dist/features/ai/protocol/models.js +3 -3
  124. package/dist/features/ai/protocol/models.js.map +1 -1
  125. package/dist/features/ai/protocol/schemas.d.ts +1 -1
  126. package/dist/features/ai/protocol/schemas.js +1 -1
  127. package/dist/features/ai/protocol/schemas.js.map +1 -1
  128. package/dist/features/ai/protocol/tasks.d.ts +5 -5
  129. package/dist/features/ai/protocol/tasks.js +12 -12
  130. package/dist/features/ai/protocol/tasks.js.map +1 -1
  131. package/dist/features/ai/react/AiSelectionMenu.js.map +1 -1
  132. package/dist/features/ai/react/ModelQuickSwitch.d.ts +4 -4
  133. package/dist/features/ai/react/ModelQuickSwitch.js +6 -6
  134. package/dist/features/ai/react/ModelQuickSwitch.js.map +1 -1
  135. package/dist/features/ai/react/SettingsAiTab.d.ts +1 -1
  136. package/dist/features/ai/react/SettingsAiTab.js +8 -8
  137. package/dist/features/ai/react/SettingsAiTab.js.map +1 -1
  138. package/dist/features/ai/react/SettingsModelProfiles.d.ts +1 -1
  139. package/dist/features/ai/react/SettingsModelProfiles.js +1 -1
  140. package/dist/features/ai/react/SettingsModelProfiles.js.map +1 -1
  141. package/dist/features/ai/react/use-ai-assistant.d.ts +1 -1
  142. package/dist/features/ai/react/use-ai-assistant.js +1 -1
  143. package/dist/features/ai/react/use-ai-assistant.js.map +1 -1
  144. package/dist/features/ai/react/use-model-profiles.d.ts +5 -5
  145. package/dist/features/ai/react/use-model-profiles.js +2 -2
  146. package/dist/features/ai/react/use-model-profiles.js.map +1 -1
  147. package/dist/features/ai/use-ai-assistant.d.ts +1 -1
  148. package/dist/features/ai/use-ai-assistant.js +1 -1
  149. package/dist/features/ai/use-ai-assistant.js.map +1 -1
  150. package/dist/features/ai/use-model-profiles.d.ts +4 -4
  151. package/dist/features/ai/use-model-profiles.js +2 -2
  152. package/dist/features/ai/use-model-profiles.js.map +1 -1
  153. package/dist/features/block-ui/block-actions.d.ts +8 -4
  154. package/dist/features/block-ui/block-actions.js +38 -22
  155. package/dist/features/block-ui/block-actions.js.map +1 -1
  156. package/dist/features/block-ui/block-target.d.ts +29 -0
  157. package/dist/features/block-ui/block-target.js +63 -0
  158. package/dist/features/block-ui/block-target.js.map +1 -0
  159. package/dist/features/block-ui/components/BlockHandles.js +3 -3
  160. package/dist/features/block-ui/components/BlockHandles.js.map +1 -1
  161. package/dist/features/block-ui/components/BlockUi.js +11 -23
  162. package/dist/features/block-ui/components/BlockUi.js.map +1 -1
  163. package/dist/features/block-ui/feature.d.ts +3 -2
  164. package/dist/features/block-ui/feature.js +3 -2
  165. package/dist/features/block-ui/feature.js.map +1 -1
  166. package/dist/features/block-ui/handle-geometry.js +12 -23
  167. package/dist/features/block-ui/handle-geometry.js.map +1 -1
  168. package/dist/features/block-ui/index.d.ts +2 -1
  169. package/dist/features/block-ui/index.js +2 -1
  170. package/dist/features/block-ui/react/BlockHandles.d.ts +1 -1
  171. package/dist/features/block-ui/react/BlockHandles.js +4 -4
  172. package/dist/features/block-ui/react/BlockHandles.js.map +1 -1
  173. package/dist/features/block-ui/react/BlockUi.js +13 -25
  174. package/dist/features/block-ui/react/BlockUi.js.map +1 -1
  175. package/dist/features/comments/model.js +1 -1
  176. package/dist/features/composites/accepted-children.d.ts +5 -4
  177. package/dist/features/composites/accepted-children.js +26 -26
  178. package/dist/features/composites/accepted-children.js.map +1 -1
  179. package/dist/features/composites/ai-brief.d.ts +4 -4
  180. package/dist/features/composites/ai-brief.js +14 -12
  181. package/dist/features/composites/ai-brief.js.map +1 -1
  182. package/dist/features/composites/anchors.d.ts +1 -1
  183. package/dist/features/composites/anchors.js.map +1 -1
  184. package/dist/features/composites/baskets.d.ts +1 -1
  185. package/dist/features/composites/baskets.js.map +1 -1
  186. package/dist/features/composites/bibliography-command.d.ts +1 -1
  187. package/dist/features/composites/bibliography-form.js +1 -1
  188. package/dist/features/composites/bibliography-form.js.map +1 -1
  189. package/dist/features/composites/bibliography.js.map +1 -1
  190. package/dist/features/composites/block-types-json.d.ts +38 -0
  191. package/dist/features/composites/block-types-json.js +122 -0
  192. package/dist/features/composites/block-types-json.js.map +1 -0
  193. package/dist/features/composites/block-types.d.ts +119 -0
  194. package/dist/features/composites/block-types.js +343 -0
  195. package/dist/features/composites/block-types.js.map +1 -0
  196. package/dist/features/composites/capabilities.js +109 -0
  197. package/dist/features/composites/capabilities.js.map +1 -0
  198. package/dist/features/composites/components/BibliographyEditor.js +5 -5
  199. package/dist/features/composites/components/BibliographyEditor.js.map +1 -1
  200. package/dist/features/composites/components/CompositeBasketMenu.js +2 -2
  201. package/dist/features/composites/components/CompositeBasketMenu.js.map +1 -1
  202. package/dist/features/composites/components/CompositeChrome.js +18 -8
  203. package/dist/features/composites/components/CompositeChrome.js.map +1 -1
  204. package/dist/features/composites/components/CompositeChrome.vue.d.ts +1 -1
  205. package/dist/features/composites/components/CompositeDetails.js +11 -10
  206. package/dist/features/composites/components/CompositeDetails.js.map +1 -1
  207. package/dist/features/composites/components/CompositeDetails.vue.d.ts +1 -1
  208. package/dist/features/composites/components/CompositeFieldEditor.js +7 -7
  209. package/dist/features/composites/components/CompositeFieldEditor.js.map +1 -1
  210. package/dist/features/composites/components/CompositeFieldEditor.vue.d.ts +5 -5
  211. package/dist/features/composites/components/CompositeInspector.js +136 -113
  212. package/dist/features/composites/components/CompositeInspector.js.map +1 -1
  213. package/dist/features/composites/components/CompositeInspector.vue.d.ts +3 -3
  214. package/dist/features/composites/components/CompositeStatusMenu.js +2 -2
  215. package/dist/features/composites/components/CompositeStatusMenu.js.map +1 -1
  216. package/dist/features/composites/components/CompositeSummaryEditor.js +1 -1
  217. package/dist/features/composites/components/CompositeSummaryEditor.js.map +1 -1
  218. package/dist/features/composites/components/CompositeSummaryEditor.vue.d.ts +1 -1
  219. package/dist/features/composites/components/CompositeTable.js +2 -2
  220. package/dist/features/composites/components/CompositeTable.js.map +1 -1
  221. package/dist/features/composites/components/CompositeTagsEditor.js +1 -1
  222. package/dist/features/composites/components/CompositeTagsEditor.js.map +1 -1
  223. package/dist/features/composites/components/CompositeTagsEditor.vue.d.ts +1 -1
  224. package/dist/features/composites/components/CompositeView.js +19 -17
  225. package/dist/features/composites/components/CompositeView.js.map +1 -1
  226. package/dist/features/composites/components/DerivationBadge.js +15 -6
  227. package/dist/features/composites/components/DerivationBadge.js.map +1 -1
  228. package/dist/features/composites/components/FocusChip.js +1 -1
  229. package/dist/features/composites/components/FocusChip.js.map +1 -1
  230. package/dist/features/composites/components/FocusChip.vue.d.ts +1 -1
  231. package/dist/features/composites/components/ReferenceFieldSelect.js +3 -3
  232. package/dist/features/composites/components/ReferenceFieldSelect.js.map +1 -1
  233. package/dist/features/composites/components/ReferenceView.js +1 -1
  234. package/dist/features/composites/components/ReferenceView.js.map +1 -1
  235. package/dist/features/composites/components/SettingsEditingTab.js +18 -18
  236. package/dist/features/composites/components/SettingsEditingTab.js.map +1 -1
  237. package/dist/features/composites/components/SettingsEditingTab.vue.d.ts +3 -3
  238. package/dist/features/composites/convert.d.ts +4 -4
  239. package/dist/features/composites/convert.js +27 -28
  240. package/dist/features/composites/convert.js.map +1 -1
  241. package/dist/features/composites/derived-chrome.js +34 -28
  242. package/dist/features/composites/derived-chrome.js.map +1 -1
  243. package/dist/features/composites/editing-settings-keys.js +6 -6
  244. package/dist/features/composites/editing-settings-keys.js.map +1 -1
  245. package/dist/features/composites/feature.d.ts +10 -10
  246. package/dist/features/composites/feature.js +58 -46
  247. package/dist/features/composites/feature.js.map +1 -1
  248. package/dist/features/composites/fences.d.ts +3 -3
  249. package/dist/features/composites/fences.js +18 -13
  250. package/dist/features/composites/fences.js.map +1 -1
  251. package/dist/features/composites/focus.d.ts +10 -10
  252. package/dist/features/composites/focus.js +11 -11
  253. package/dist/features/composites/focus.js.map +1 -1
  254. package/dist/features/composites/heading-composites.d.ts +5 -5
  255. package/dist/features/composites/heading-composites.js +13 -16
  256. package/dist/features/composites/heading-composites.js.map +1 -1
  257. package/dist/features/composites/index.d.ts +20 -18
  258. package/dist/features/composites/index.js +9 -7
  259. package/dist/features/composites/inspector-model.d.ts +45 -22
  260. package/dist/features/composites/inspector-model.js +53 -14
  261. package/dist/features/composites/inspector-model.js.map +1 -1
  262. package/dist/features/composites/legacy.d.ts +5 -4
  263. package/dist/features/composites/legacy.js +16 -23
  264. package/dist/features/composites/legacy.js.map +1 -1
  265. package/dist/features/composites/markdown-export.js +3 -3
  266. package/dist/features/composites/markdown-export.js.map +1 -1
  267. package/dist/features/composites/merge.d.ts +8 -7
  268. package/dist/features/composites/merge.js +39 -12
  269. package/dist/features/composites/merge.js.map +1 -1
  270. package/dist/features/composites/meta-display.js +5 -5
  271. package/dist/features/composites/meta-display.js.map +1 -1
  272. package/dist/features/composites/meta-keys.d.ts +5 -5
  273. package/dist/features/composites/meta-keys.js +8 -8
  274. package/dist/features/composites/meta-keys.js.map +1 -1
  275. package/dist/features/composites/node-views.d.ts +3 -3
  276. package/dist/features/composites/node-views.js +2 -2
  277. package/dist/features/composites/node-views.js.map +1 -1
  278. package/dist/features/composites/nodes.d.ts +13 -13
  279. package/dist/features/composites/nodes.js +100 -77
  280. package/dist/features/composites/nodes.js.map +1 -1
  281. package/dist/features/composites/outline.d.ts +15 -12
  282. package/dist/features/composites/outline.js +24 -21
  283. package/dist/features/composites/outline.js.map +1 -1
  284. package/dist/features/composites/properties.d.ts +51 -0
  285. package/dist/features/composites/properties.js +89 -0
  286. package/dist/features/composites/properties.js.map +1 -0
  287. package/dist/features/composites/react/BibliographyEditor.js +5 -5
  288. package/dist/features/composites/react/BibliographyEditor.js.map +1 -1
  289. package/dist/features/composites/react/CompositeBasketMenu.js +2 -2
  290. package/dist/features/composites/react/CompositeBasketMenu.js.map +1 -1
  291. package/dist/features/composites/react/CompositeChrome.d.ts +1 -1
  292. package/dist/features/composites/react/CompositeChrome.js +15 -6
  293. package/dist/features/composites/react/CompositeChrome.js.map +1 -1
  294. package/dist/features/composites/react/CompositeDetails.d.ts +1 -1
  295. package/dist/features/composites/react/CompositeDetails.js +11 -10
  296. package/dist/features/composites/react/CompositeDetails.js.map +1 -1
  297. package/dist/features/composites/react/CompositeFieldEditor.d.ts +5 -5
  298. package/dist/features/composites/react/CompositeFieldEditor.js +6 -6
  299. package/dist/features/composites/react/CompositeFieldEditor.js.map +1 -1
  300. package/dist/features/composites/react/CompositeInspector.d.ts +3 -3
  301. package/dist/features/composites/react/CompositeInspector.js +142 -128
  302. package/dist/features/composites/react/CompositeInspector.js.map +1 -1
  303. package/dist/features/composites/react/CompositeStatusMenu.js +2 -2
  304. package/dist/features/composites/react/CompositeStatusMenu.js.map +1 -1
  305. package/dist/features/composites/react/CompositeSummaryEditor.d.ts +1 -1
  306. package/dist/features/composites/react/CompositeSummaryEditor.js +1 -1
  307. package/dist/features/composites/react/CompositeSummaryEditor.js.map +1 -1
  308. package/dist/features/composites/react/CompositeTable.d.ts +1 -1
  309. package/dist/features/composites/react/CompositeTable.js +3 -3
  310. package/dist/features/composites/react/CompositeTable.js.map +1 -1
  311. package/dist/features/composites/react/CompositeTagsEditor.d.ts +1 -1
  312. package/dist/features/composites/react/CompositeTagsEditor.js +1 -1
  313. package/dist/features/composites/react/CompositeTagsEditor.js.map +1 -1
  314. package/dist/features/composites/react/CompositeView.js +17 -15
  315. package/dist/features/composites/react/CompositeView.js.map +1 -1
  316. package/dist/features/composites/react/DerivationBadge.js +13 -4
  317. package/dist/features/composites/react/DerivationBadge.js.map +1 -1
  318. package/dist/features/composites/react/FocusChip.d.ts +1 -1
  319. package/dist/features/composites/react/FocusChip.js +1 -1
  320. package/dist/features/composites/react/FocusChip.js.map +1 -1
  321. package/dist/features/composites/react/ReferenceFieldSelect.js +3 -3
  322. package/dist/features/composites/react/ReferenceFieldSelect.js.map +1 -1
  323. package/dist/features/composites/react/ReferenceView.d.ts +1 -1
  324. package/dist/features/composites/react/ReferenceView.js +1 -1
  325. package/dist/features/composites/react/ReferenceView.js.map +1 -1
  326. package/dist/features/composites/react/SettingsEditingTab.d.ts +4 -4
  327. package/dist/features/composites/react/SettingsEditingTab.js +20 -20
  328. package/dist/features/composites/react/SettingsEditingTab.js.map +1 -1
  329. package/dist/features/composites/react.js +1 -1
  330. package/dist/features/composites/react.js.map +1 -1
  331. package/dist/features/composites/reference-ai.js +1 -1
  332. package/dist/features/composites/reference-ai.js.map +1 -1
  333. package/dist/features/composites/reference-label.d.ts +3 -3
  334. package/dist/features/composites/reference-label.js +6 -6
  335. package/dist/features/composites/reference-label.js.map +1 -1
  336. package/dist/features/composites/reference-suggestion.d.ts +1 -1
  337. package/dist/features/composites/reference-suggestion.js +3 -3
  338. package/dist/features/composites/reference-suggestion.js.map +1 -1
  339. package/dist/features/composites/reference-text.d.ts +2 -2
  340. package/dist/features/composites/reference-text.js +4 -4
  341. package/dist/features/composites/reference-text.js.map +1 -1
  342. package/dist/features/composites/reference.d.ts +3 -3
  343. package/dist/features/composites/reference.js +1 -1
  344. package/dist/features/composites/reference.js.map +1 -1
  345. package/dist/features/composites/reveal-source.d.ts +3 -3
  346. package/dist/features/composites/reveal-source.js +6 -6
  347. package/dist/features/composites/reveal-source.js.map +1 -1
  348. package/dist/features/composites/rows-model.d.ts +2 -2
  349. package/dist/features/composites/rows-model.js +4 -3
  350. package/dist/features/composites/rows-model.js.map +1 -1
  351. package/dist/features/composites/rows.d.ts +16 -28
  352. package/dist/features/composites/rows.js +20 -54
  353. package/dist/features/composites/rows.js.map +1 -1
  354. package/dist/features/composites/schema.d.ts +12 -11
  355. package/dist/features/composites/schema.js +10 -9
  356. package/dist/features/composites/schema.js.map +1 -1
  357. package/dist/features/composites/source.d.ts +20 -0
  358. package/dist/features/composites/source.js +40 -0
  359. package/dist/features/composites/source.js.map +1 -0
  360. package/dist/features/composites/split.d.ts +11 -11
  361. package/dist/features/composites/split.js +20 -20
  362. package/dist/features/composites/split.js.map +1 -1
  363. package/dist/features/composites/structure-mode.js +3 -3
  364. package/dist/features/composites/structure-mode.js.map +1 -1
  365. package/dist/features/composites/table-model.js +2 -2
  366. package/dist/features/composites/table-model.js.map +1 -1
  367. package/dist/features/composites/use-composite-inspector.js +3 -1
  368. package/dist/features/composites/use-composite-inspector.js.map +1 -1
  369. package/dist/features/composites/use-composite-rows.d.ts +2 -2
  370. package/dist/features/composites/use-composite-rows.js.map +1 -1
  371. package/dist/features/composites/vue.js +1 -1
  372. package/dist/features/composites/vue.js.map +1 -1
  373. package/dist/features/image-studio/components/ImageStudioDialog.js +1 -1
  374. package/dist/features/image-studio/components/ImageStudioDialog.js.map +1 -1
  375. package/dist/features/image-studio/components/ImageStudioDialog.vue.d.ts +1 -1
  376. package/dist/features/image-studio/components/ImageStudioView.js.map +1 -1
  377. package/dist/features/image-studio/feature.d.ts +1 -1
  378. package/dist/features/image-studio/feature.js +1 -1
  379. package/dist/features/image-studio/feature.js.map +1 -1
  380. package/dist/features/image-studio/node-core.d.ts +3 -3
  381. package/dist/features/image-studio/node-core.js +1 -1
  382. package/dist/features/image-studio/node-core.js.map +1 -1
  383. package/dist/features/image-studio/node-store.d.ts +1 -1
  384. package/dist/features/image-studio/node-store.js +1 -1
  385. package/dist/features/image-studio/node-store.js.map +1 -1
  386. package/dist/features/image-studio/react/ImageStudioDialog.d.ts +1 -1
  387. package/dist/features/image-studio/react/ImageStudioDialog.js +1 -1
  388. package/dist/features/image-studio/react/ImageStudioDialog.js.map +1 -1
  389. package/dist/features/image-studio/react/ImageStudioView.js +1 -1
  390. package/dist/features/image-studio/react/ImageStudioView.js.map +1 -1
  391. package/dist/features/image-studio/react/store.d.ts +3 -3
  392. package/dist/features/image-studio/react/store.js.map +1 -1
  393. package/dist/features/image-studio/react.d.ts +1 -1
  394. package/dist/features/image-studio/react.js +1 -1
  395. package/dist/features/image-studio/react.js.map +1 -1
  396. package/dist/features/image-studio/schema.d.ts +1 -1
  397. package/dist/features/image-studio/schema.js +1 -1
  398. package/dist/features/image-studio/schema.js.map +1 -1
  399. package/dist/features/image-studio/state.d.ts +3 -3
  400. package/dist/features/image-studio/state.js +2 -2
  401. package/dist/features/image-studio/state.js.map +1 -1
  402. package/dist/features/image-studio/store.d.ts +3 -3
  403. package/dist/features/image-studio/vue.d.ts +1 -1
  404. package/dist/features/image-studio/vue.js +1 -1
  405. package/dist/features/image-studio/vue.js.map +1 -1
  406. package/dist/features/media/index.js +1 -1
  407. package/dist/features/media/react/AudioRecorderModal.js +1 -1
  408. package/dist/features/media/react.js +1 -1
  409. package/dist/features/mentions/tag.js +2 -1
  410. package/dist/features/mentions/tag.js.map +1 -1
  411. package/dist/features/themes/components/SettingsAppearanceTab.js +1 -1
  412. package/dist/features/themes/components/SettingsAppearanceTab.js.map +1 -1
  413. package/dist/features/themes/feature.d.ts +1 -1
  414. package/dist/features/themes/feature.js.map +1 -1
  415. package/dist/features/themes/react/SettingsAppearanceTab.d.ts +1 -1
  416. package/dist/features/themes/react/SettingsAppearanceTab.js +1 -1
  417. package/dist/features/themes/react/SettingsAppearanceTab.js.map +1 -1
  418. package/dist/features/themes/theme-runtime.js +1 -1
  419. package/dist/features/themes/theme-runtime.js.map +1 -1
  420. package/dist/features/transcript/TranscriptSegmentView.js +1 -1
  421. package/dist/features/transcript/TranscriptSegmentView.js.map +1 -1
  422. package/dist/features/transcript/react/TranscriptSegmentView.js +1 -1
  423. package/dist/features/transcript/react/TranscriptSegmentView.js.map +1 -1
  424. package/dist/features/transcript/segment-node.js.map +1 -1
  425. package/dist/features/transfer/feature.js +1 -1
  426. package/dist/features/transfer/feature.js.map +1 -1
  427. package/dist/features/transfer/transforms.d.ts +4 -4
  428. package/dist/features/transfer/transforms.js +12 -12
  429. package/dist/features/transfer/transforms.js.map +1 -1
  430. package/dist/i18n/de/ai.js +4 -4
  431. package/dist/i18n/de/ai.js.map +1 -1
  432. package/dist/i18n/de/authors.js +1 -1
  433. package/dist/i18n/de/authors.js.map +1 -1
  434. package/dist/i18n/de/comments.js +1 -1
  435. package/dist/i18n/de/comments.js.map +1 -1
  436. package/dist/i18n/de/composites.js +62 -59
  437. package/dist/i18n/de/composites.js.map +1 -1
  438. package/dist/i18n/de/image-studio.js +2 -2
  439. package/dist/i18n/de/image-studio.js.map +1 -1
  440. package/dist/i18n/de/integrations.js +20 -20
  441. package/dist/i18n/de/integrations.js.map +1 -1
  442. package/dist/i18n/de/markdown.js +1 -1
  443. package/dist/i18n/de/markdown.js.map +1 -1
  444. package/dist/i18n/de/palette.js +1 -1
  445. package/dist/i18n/de/palette.js.map +1 -1
  446. package/dist/i18n/de/themes.js +3 -3
  447. package/dist/i18n/de/themes.js.map +1 -1
  448. package/dist/i18n/de/transfer.js +2 -2
  449. package/dist/i18n/de/transfer.js.map +1 -1
  450. package/dist/i18n/de/tree.js +6 -6
  451. package/dist/i18n/de/tree.js.map +1 -1
  452. package/dist/i18n/de.d.ts +101 -98
  453. package/dist/i18n/en/ai.js +2 -2
  454. package/dist/i18n/en/ai.js.map +1 -1
  455. package/dist/i18n/en/composites.js +64 -61
  456. package/dist/i18n/en/composites.js.map +1 -1
  457. package/dist/i18n/en/integrations.js +9 -9
  458. package/dist/i18n/en/integrations.js.map +1 -1
  459. package/dist/i18n/en/markdown.js +1 -1
  460. package/dist/i18n/en/markdown.js.map +1 -1
  461. package/dist/i18n/en/palette.js +1 -1
  462. package/dist/i18n/en/palette.js.map +1 -1
  463. package/dist/i18n/en/themes.js +4 -4
  464. package/dist/i18n/en/themes.js.map +1 -1
  465. package/dist/i18n/en/tree.js +5 -5
  466. package/dist/i18n/en/tree.js.map +1 -1
  467. package/dist/index.d.ts +4 -1
  468. package/dist/integrations/composite-ai/bibliography-fetch.d.ts +6 -6
  469. package/dist/integrations/composite-ai/bibliography-fetch.js +19 -19
  470. package/dist/integrations/composite-ai/bibliography-fetch.js.map +1 -1
  471. package/dist/integrations/composite-ai/composite-fill.d.ts +4 -4
  472. package/dist/integrations/composite-ai/composite-fill.js +5 -5
  473. package/dist/integrations/composite-ai/composite-fill.js.map +1 -1
  474. package/dist/integrations/composite-ai/composite-summary.d.ts +2 -2
  475. package/dist/integrations/composite-ai/composite-summary.js +5 -5
  476. package/dist/integrations/composite-ai/composite-summary.js.map +1 -1
  477. package/dist/integrations/composite-ai/derive.d.ts +17 -17
  478. package/dist/integrations/composite-ai/derive.js +27 -26
  479. package/dist/integrations/composite-ai/derive.js.map +1 -1
  480. package/dist/integrations/composite-ai/index.d.ts +14 -15
  481. package/dist/integrations/composite-ai/index.js +98 -77
  482. package/dist/integrations/composite-ai/index.js.map +1 -1
  483. package/dist/integrations/composite-ai/outline-sanitize.d.ts +1 -1
  484. package/dist/integrations/composite-ai/outline-sanitize.js +1 -1
  485. package/dist/integrations/composite-ai/outline-sanitize.js.map +1 -1
  486. package/dist/integrations/composite-ai/rendition.d.ts +9 -9
  487. package/dist/integrations/composite-ai/rendition.js +27 -27
  488. package/dist/integrations/composite-ai/rendition.js.map +1 -1
  489. package/dist/integrations/composite-ai/split.d.ts +8 -8
  490. package/dist/integrations/composite-ai/split.js +12 -12
  491. package/dist/integrations/composite-ai/split.js.map +1 -1
  492. package/dist/integrations/composite-ai/transfer-transforms.d.ts +2 -2
  493. package/dist/integrations/composite-ai/transfer-transforms.js +12 -12
  494. package/dist/integrations/composite-ai/transfer-transforms.js.map +1 -1
  495. package/dist/integrations/composite-media/index.d.ts +4 -3
  496. package/dist/integrations/composite-media/index.js +20 -14
  497. package/dist/integrations/composite-media/index.js.map +1 -1
  498. package/dist/markdown/MarkdownSurface.vue.d.ts +7 -7
  499. package/dist/markdown/document.js +1 -1
  500. package/dist/markdown/document.js.map +1 -1
  501. package/dist/nuxt/module.d.ts +30 -24
  502. package/dist/nuxt/module.js.map +1 -1
  503. package/dist/nuxt/runtime/server/plugins/editor-server.js +3 -2
  504. package/dist/nuxt/runtime/server/plugins/editor-server.js.map +1 -1
  505. package/dist/presets/compose.d.ts +6 -6
  506. package/dist/presets/compose.js +8 -5
  507. package/dist/presets/compose.js.map +1 -1
  508. package/dist/react/AdvancedEditor.d.ts +2 -2
  509. package/dist/react/AdvancedEditor.js +1 -1
  510. package/dist/react/AdvancedEditor.js.map +1 -1
  511. package/dist/react/compose.d.ts +1 -1
  512. package/dist/react/compose.js +2 -2
  513. package/dist/react/compose.js.map +1 -1
  514. package/dist/react/composed-surface.d.ts +5 -5
  515. package/dist/react/composed-surface.js +2 -2
  516. package/dist/react/composed-surface.js.map +1 -1
  517. package/dist/server/ai.d.ts +7 -7
  518. package/dist/server/ai.js +1 -1
  519. package/dist/server/ai.js.map +1 -1
  520. package/dist/server/auth.d.ts +1 -1
  521. package/dist/server/collab-state.d.ts +1 -1
  522. package/dist/server/collab-state.js.map +1 -1
  523. package/dist/server/collab.d.ts +4 -4
  524. package/dist/server/collab.js +22 -17
  525. package/dist/server/collab.js.map +1 -1
  526. package/dist/server/handlers/ai.d.ts +9 -6
  527. package/dist/server/handlers/ai.js +13 -17
  528. package/dist/server/handlers/ai.js.map +1 -1
  529. package/dist/server/handlers/context.d.ts +4 -0
  530. package/dist/server/handlers/context.js.map +1 -1
  531. package/dist/server/handlers/editor.d.ts +33 -32
  532. package/dist/server/handlers/editor.js +13 -8
  533. package/dist/server/handlers/editor.js.map +1 -1
  534. package/dist/server/handlers/images.d.ts +1 -1
  535. package/dist/server/handlers/images.js +1 -1
  536. package/dist/server/handlers/images.js.map +1 -1
  537. package/dist/server/host.d.ts +4 -0
  538. package/dist/server/host.js +10 -2
  539. package/dist/server/host.js.map +1 -1
  540. package/dist/server/index.d.ts +3 -3
  541. package/dist/server/ports.d.ts +8 -8
  542. package/dist/server/ports.js.map +1 -1
  543. package/dist/settings/index.d.ts +20 -19
  544. package/dist/settings/index.js +25 -24
  545. package/dist/settings/index.js.map +1 -1
  546. package/dist/settings/migrate.d.ts +18 -0
  547. package/dist/settings/migrate.js +46 -0
  548. package/dist/settings/migrate.js.map +1 -0
  549. package/dist/settings/values.d.ts +12 -12
  550. package/dist/settings/values.js +11 -11
  551. package/dist/settings/values.js.map +1 -1
  552. package/dist/styles/composites.css +10 -10
  553. package/dist/tree/DocumentTree.js +12 -5
  554. package/dist/tree/DocumentTree.js.map +1 -1
  555. package/dist/tree/drop-rules.js +5 -5
  556. package/dist/tree/drop-rules.js.map +1 -1
  557. package/dist/tree/react/DocumentTree.js +14 -5
  558. package/dist/tree/react/DocumentTree.js.map +1 -1
  559. package/dist/tree/tree-host.js +6 -6
  560. package/dist/tree/tree-host.js.map +1 -1
  561. package/dist/tree/tree-items.js +34 -28
  562. package/dist/tree/tree-items.js.map +1 -1
  563. package/dist/tree/tree-model.js +16 -16
  564. package/dist/tree/tree-model.js.map +1 -1
  565. package/dist/tree/tree-rows.js +2 -2
  566. package/dist/tree/tree-rows.js.map +1 -1
  567. package/dist/tree/tree-view-model.d.ts +2 -2
  568. package/dist/tree/tree-view-model.js.map +1 -1
  569. package/dist/vue/AdvancedEditor.js +2 -2
  570. package/dist/vue/AdvancedEditor.js.map +1 -1
  571. package/dist/vue/AdvancedEditor.vue.d.ts +10 -10
  572. package/dist/vue/SimpleEditor.vue.d.ts +4 -4
  573. package/dist/vue/components/EditorSurface.vue.d.ts +4 -4
  574. package/dist/vue/compose.d.ts +1 -1
  575. package/dist/vue/compose.js +2 -2
  576. package/dist/vue/compose.js.map +1 -1
  577. package/package.json +1 -1
  578. package/dist/features/composites/derivation.d.ts +0 -62
  579. package/dist/features/composites/derivation.js +0 -102
  580. package/dist/features/composites/derivation.js.map +0 -1
  581. package/dist/features/composites/kinds.d.ts +0 -83
  582. package/dist/features/composites/kinds.js +0 -285
  583. package/dist/features/composites/kinds.js.map +0 -1
@@ -0,0 +1,40 @@
1
+ import { assetRefOf } from "../../core/derivation.js";
2
+ import { blockTypeOf, sourceMediaOf } from "./block-types.js";
3
+ import "./nodes.js";
4
+ //#region src/features/composites/source.ts
5
+ /** First body child of `composite` whose node type is one of `media` (the `source` capability's config), as a `SourceBlock`; null when there is none. */
6
+ function sourceIn(composite, media) {
7
+ for (let index = 3; index < composite.childCount; index++) {
8
+ const node = composite.child(index);
9
+ if (!media.includes(node.type.name)) continue;
10
+ const hash = node.attrs.hash;
11
+ return {
12
+ node,
13
+ index,
14
+ asset: assetRefOf(String(node.attrs.src ?? "")),
15
+ hash: typeof hash === "string" && hash ? hash : null
16
+ };
17
+ }
18
+ return null;
19
+ }
20
+ /** The media block a source-holding Block type keeps its original in: first body child of a type in the `media` of the Block type's `source` capability. */
21
+ function sourceOf(composite, blockTypes) {
22
+ if (composite.type.name !== "typedBlock") return null;
23
+ const media = sourceMediaOf(blockTypeOf(blockTypes, String(composite.attrs.blockType)));
24
+ return media ? sourceIn(composite, media) : null;
25
+ }
26
+ /** Markdown of the body of `composite` (everything after title, description and tags). */
27
+ function bodyMarkdown(editor, composite) {
28
+ const content = [];
29
+ composite.forEach((child, _offset, index) => {
30
+ if (index >= 3) content.push(child.toJSON());
31
+ });
32
+ return editor.markdown.serialize({
33
+ type: "doc",
34
+ content
35
+ });
36
+ }
37
+ //#endregion
38
+ export { bodyMarkdown, sourceIn, sourceOf };
39
+
40
+ //# sourceMappingURL=source.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"source.js","names":[],"sources":["../../../src/features/composites/source.ts"],"sourcesContent":["// Vue-free and server-importable: where a Typed block's original lives. A source-holding Typed block (`recording`, `paper`,\n// `book`, `figure`, `document`) carries its original as an `image|audio|video|file` block in the body (the `source` capability).\n// What a Derived block records about its original (`Derivation`, `derivationOf`, `derivationState`) lives in `core/derivation`.\nimport type { Editor, JSONContent } from '@tiptap/core'\n// Types only: brings in the `editor.markdown` augmentation of `@tiptap/markdown` for contexts that do not otherwise load it.\nimport type {} from '@tiptap/markdown'\nimport type { Node as PMNode } from '@tiptap/pm/model'\nimport { assetRefOf } from '../../core/derivation'\nimport { type BlockType, blockTypeOf, sourceMediaOf } from './block-types'\nimport { COMPOSITE_CHROME_COUNT } from './nodes'\n\n/** The media block a source-holding Typed block keeps its original in, with its position among the children, the stored asset behind its `src` and its content hash. */\nexport interface SourceBlock { node: PMNode, index: number, asset: { documentId: string, name: string } | null, hash: string | null }\n\n/** First body child of `composite` whose node type is one of `media` (the `source` capability's config), as a `SourceBlock`; null when there is none. */\nexport function sourceIn(composite: PMNode, media: readonly string[]): SourceBlock | null {\n for (let index = COMPOSITE_CHROME_COUNT; index < composite.childCount; index++) {\n const node = composite.child(index)\n if (!media.includes(node.type.name)) continue\n const hash: unknown = node.attrs.hash\n return { node, index, asset: assetRefOf(String(node.attrs.src ?? '')), hash: typeof hash === 'string' && hash ? hash : null }\n }\n return null\n}\n\n/** The media block a source-holding Block type keeps its original in: first body child of a type in the `media` of the Block type's `source` capability. */\nexport function sourceOf(composite: PMNode, blockTypes: readonly BlockType[]): SourceBlock | null {\n if (composite.type.name !== 'typedBlock') return null\n const media = sourceMediaOf(blockTypeOf(blockTypes, String(composite.attrs.blockType)))\n return media ? sourceIn(composite, media) : null\n}\n\n/** Markdown of the body of `composite` (everything after title, description and tags). */\nexport function bodyMarkdown(editor: Editor, composite: PMNode): string {\n const content: JSONContent[] = []\n composite.forEach((child, _offset, index) => {\n if (index >= COMPOSITE_CHROME_COUNT) content.push(child.toJSON() as JSONContent)\n })\n return editor.markdown!.serialize({ type: 'doc', content })\n}\n"],"mappings":";;;;;AAeA,SAAgB,SAAS,WAAmB,OAA8C;CACxF,KAAK,IAAI,QAAA,GAAgC,QAAQ,UAAU,YAAY,SAAS;EAC9E,MAAM,OAAO,UAAU,MAAM,KAAK;EAClC,IAAI,CAAC,MAAM,SAAS,KAAK,KAAK,IAAI,GAAG;EACrC,MAAM,OAAgB,KAAK,MAAM;EACjC,OAAO;GAAE;GAAM;GAAO,OAAO,WAAW,OAAO,KAAK,MAAM,OAAO,EAAE,CAAC;GAAG,MAAM,OAAO,SAAS,YAAY,OAAO,OAAO;EAAK;CAC9H;CACA,OAAO;AACT;;AAGA,SAAgB,SAAS,WAAmB,YAAsD;CAChG,IAAI,UAAU,KAAK,SAAS,cAAc,OAAO;CACjD,MAAM,QAAQ,cAAc,YAAY,YAAY,OAAO,UAAU,MAAM,SAAS,CAAC,CAAC;CACtF,OAAO,QAAQ,SAAS,WAAW,KAAK,IAAI;AAC9C;;AAGA,SAAgB,aAAa,QAAgB,WAA2B;CACtE,MAAM,UAAyB,CAAC;CAChC,UAAU,SAAS,OAAO,SAAS,UAAU;EAC3C,IAAI,SAAA,GAAiC,QAAQ,KAAK,MAAM,OAAO,CAAgB;CACjF,CAAC;CACD,OAAO,OAAO,SAAU,UAAU;EAAE,MAAM;EAAO;CAAQ,CAAC;AAC5D"}
@@ -1,8 +1,8 @@
1
- import { CompositeKind } from "./kinds.js";
1
+ import { BlockType } from "./block-types.js";
2
2
  import { Extension } from "@tiptap/core";
3
3
  import { Node as Node$1, Schema } from "@tiptap/pm/model";
4
4
  //#region src/features/composites/split.d.ts
5
- /** Where the parts of a split go: next to the split Baustein (`siblings`) or into it as sub-Bausteine (`children`). */
5
+ /** Where the parts of a split go: next to the split Typed block (`siblings`) or into it as nested Typed blocks (`children`). */
6
6
  export type SplitMode = 'siblings' | 'children';
7
7
  /**
8
8
  * Groups `blocks` in order so that no group exceeds `targetChars` text characters, never splitting inside a block: a
@@ -17,15 +17,15 @@ export declare function splitBodyByLength(blocks: readonly Node$1[], targetChars
17
17
  */
18
18
  export declare function generatedTitle(blocks: readonly Node$1[]): string;
19
19
  /**
20
- * Kind of the sub-Bausteine a split of a `parentKind` Baustein creates: `defaultKind` when the parent accepts it, else
20
+ * Kind of the nested Typed blocks a split of a `parentKind` Typed block creates: `defaultBlockType` when the parent accepts it, else
21
21
  * the parent's own kind when it accepts itself, else null (the split is refused).
22
22
  */
23
- export declare function childKindFor(kinds: readonly CompositeKind[], parentKind: string, defaultKind: string): string | null;
23
+ export declare function childKindFor(kinds: readonly BlockType[], parentKind: string, defaultBlockType: string): string | null;
24
24
  /**
25
25
  * The nodes that replace `composite` once its body is cut into `groups` (in order, each non-empty).
26
- * - `children`: one node, `composite` with its own title, description, tags and meta whose body is one new Baustein of
26
+ * - `children`: one node, `composite` with its own title, description, tags and meta whose body is one new Typed block of
27
27
  * `childKind` per group.
28
- * - `siblings`: `composite` itself keeping the first group, then one new Baustein of the same kind per further group.
28
+ * - `siblings`: `composite` itself keeping the first group, then one new Typed block of the same Block type per further group.
29
29
  * New parts carry a generated title, hidden when `hideTitles`, and no block id.
30
30
  */
31
31
  export declare function splitComposite(schema: Schema, composite: Node$1, groups: readonly (readonly Node$1[])[], mode: SplitMode, childKind: string, hideTitles: boolean): Node$1[];
@@ -33,13 +33,13 @@ declare module '@tiptap/core' {
33
33
  interface Commands<ReturnType> {
34
34
  compositeSplit: {
35
35
  /**
36
- * Split the caret's innermost Baustein in front of the body block holding the caret (refused when that is the first body block or the caret is not in a body): the part before and the part from the caret on become sibling Bausteine or sub-Bausteine (`children`, of the default kind or the parent's own; refused when neither is accepted). The caret moves into the new part.
36
+ * Split the caret's innermost Typed block in front of the body block holding the caret (refused when that is the first body block or the caret is not in a body): the part before and the part from the caret on become sibling Typed blocks or nested Typed blocks (`children`, of the default Block type or the parent's own; refused when neither is accepted). The caret moves into the new part.
37
37
  */
38
38
  splitCompositeAtCaret: (options: {
39
39
  mode: SplitMode;
40
40
  }) => ReturnType;
41
41
  /**
42
- * Split the Baustein at `pos` (default: the caret's innermost one) into parts of about `targetChars` characters (default: setting `blocks.splitTargetChars`) without cutting inside a block. Refused with fewer than two parts, or in `children` mode when no child kind is accepted. The generated titles are hidden.
42
+ * Split the Typed block at `pos` (default: the caret's innermost one) into parts of about `targetChars` characters (default: setting `blocks.splitTargetChars`) without cutting inside a block. Refused with fewer than two parts, or in `children` mode when no child Block type is accepted. The generated titles are hidden.
43
43
  */
44
44
  splitCompositeByLength: (options: {
45
45
  mode: SplitMode;
@@ -51,12 +51,12 @@ declare module '@tiptap/core' {
51
51
  }
52
52
  /** Options of `CompositeSplit`: read on every use, so a changed setting applies without recreating the editor. */
53
53
  export interface CompositeSplitOptions {
54
- /** Kind of the sub-Bausteine a `children` split creates when the parent accepts it (setting `blocks.defaultKind`). */
55
- defaultKind: () => string;
54
+ /** Kind of the nested Typed blocks a `children` split creates when the parent accepts it (setting `blocks.defaultBlockType`). */
55
+ defaultBlockType: () => string;
56
56
  /** Target size in characters of a length split (setting `blocks.splitTargetChars`). */
57
57
  targetChars: () => number;
58
58
  }
59
- /** Client-only, no schema: the split commands of Bausteine. */
59
+ /** Client-only, no schema: the split commands of Typed blocks. */
60
60
  export declare const CompositeSplit: Extension<CompositeSplitOptions, any>;
61
61
  //#endregion
62
62
  //# sourceMappingURL=split.d.ts.map
@@ -1,7 +1,7 @@
1
1
  import { EDITOR_SETTINGS_DEFAULTS } from "../../settings/index.js";
2
- import { kindAccepts } from "./kinds.js";
2
+ import { acceptsChild } from "./block-types.js";
3
3
  import { TITLE_HIDDEN_KEY } from "./meta-keys.js";
4
- import { compositeAround, compositeKindsOf } from "./nodes.js";
4
+ import { blockTypesOf, compositeAround } from "./nodes.js";
5
5
  import { Extension } from "@tiptap/core";
6
6
  import { TextSelection } from "@tiptap/pm/state";
7
7
  import { Fragment } from "@tiptap/pm/model";
@@ -56,12 +56,12 @@ function generatedTitle(blocks) {
56
56
  return sentence.length > TITLE_MAX_CHARS ? `${sentence.slice(0, TITLE_MAX_CHARS).trimEnd()}…` : sentence;
57
57
  }
58
58
  /**
59
- * Kind of the sub-Bausteine a split of a `parentKind` Baustein creates: `defaultKind` when the parent accepts it, else
59
+ * Kind of the nested Typed blocks a split of a `parentKind` Typed block creates: `defaultBlockType` when the parent accepts it, else
60
60
  * the parent's own kind when it accepts itself, else null (the split is refused).
61
61
  */
62
- function childKindFor(kinds, parentKind, defaultKind) {
63
- if (kindAccepts(kinds, parentKind, defaultKind)) return defaultKind;
64
- if (kindAccepts(kinds, parentKind, parentKind)) return parentKind;
62
+ function childKindFor(kinds, parentKind, defaultBlockType) {
63
+ if (acceptsChild(kinds, parentKind, defaultBlockType)) return defaultBlockType;
64
+ if (acceptsChild(kinds, parentKind, parentKind)) return parentKind;
65
65
  return null;
66
66
  }
67
67
  function chromeOf(composite) {
@@ -76,38 +76,38 @@ function bodyOf(composite) {
76
76
  });
77
77
  return body;
78
78
  }
79
- /** A new Baustein of `kind` holding `group`, titled by `generatedTitle(group)`. */
79
+ /** A new Typed block of `kind` holding `group`, titled by `generatedTitle(group)`. */
80
80
  function newPart(schema, kind, group, hideTitle) {
81
81
  const { nodes } = schema;
82
82
  const title = generatedTitle(group);
83
- return nodes.composite.create({
84
- kind,
83
+ return nodes.typedBlock.create({
84
+ blockType: kind,
85
85
  meta: hideTitle ? { [TITLE_HIDDEN_KEY]: true } : {}
86
86
  }, [
87
- nodes.compositeTitle.create(null, title ? schema.text(title) : null),
88
- nodes.compositeDescription.create(),
89
- nodes.compositeTags.create(),
87
+ nodes.typedBlockTitle.create(null, title ? schema.text(title) : null),
88
+ nodes.typedBlockDescription.create(),
89
+ nodes.typedBlockTags.create(),
90
90
  ...group.length ? group : [nodes.paragraph.create()]
91
91
  ]);
92
92
  }
93
93
  /**
94
94
  * The nodes that replace `composite` once its body is cut into `groups` (in order, each non-empty).
95
- * - `children`: one node, `composite` with its own title, description, tags and meta whose body is one new Baustein of
95
+ * - `children`: one node, `composite` with its own title, description, tags and meta whose body is one new Typed block of
96
96
  * `childKind` per group.
97
- * - `siblings`: `composite` itself keeping the first group, then one new Baustein of the same kind per further group.
97
+ * - `siblings`: `composite` itself keeping the first group, then one new Typed block of the same Block type per further group.
98
98
  * New parts carry a generated title, hidden when `hideTitles`, and no block id.
99
99
  */
100
100
  function splitComposite(schema, composite, groups, mode, childKind, hideTitles) {
101
101
  const chrome = chromeOf(composite);
102
102
  if (mode === "children") return [composite.copy(Fragment.from([...chrome, ...groups.map((group) => newPart(schema, childKind, group, hideTitles))]))];
103
103
  const [first = [], ...rest] = groups;
104
- return [composite.copy(Fragment.from([...chrome, ...first.length ? first : [schema.nodes.paragraph.create()]])), ...rest.map((group) => newPart(schema, composite.attrs.kind, group, hideTitles))];
104
+ return [composite.copy(Fragment.from([...chrome, ...first.length ? first : [schema.nodes.paragraph.create()]])), ...rest.map((group) => newPart(schema, composite.attrs.blockType, group, hideTitles))];
105
105
  }
106
106
  /** The composite whose content starts at `pos` in `state`, or the caret's innermost one when `pos` is undefined. */
107
107
  function targetComposite(state, pos) {
108
108
  if (pos === void 0) return compositeAround(state.selection.$head);
109
109
  const node = state.doc.nodeAt(pos);
110
- return node?.type.name === "composite" ? {
110
+ return node?.type.name === "typedBlock" ? {
111
111
  pos,
112
112
  node
113
113
  } : null;
@@ -126,16 +126,16 @@ function lastPartBodyStart(pos, nodes, mode) {
126
126
  const last = nodes[nodes.length - 1];
127
127
  return bodyStartOf(pos + nodes.reduce((size, node) => size + node.nodeSize, 0) - last.nodeSize, last);
128
128
  }
129
- /** Client-only, no schema: the split commands of Bausteine. */
129
+ /** Client-only, no schema: the split commands of Typed blocks. */
130
130
  const CompositeSplit = Extension.create({
131
131
  name: "compositeSplit",
132
132
  addOptions: () => ({
133
- defaultKind: () => EDITOR_SETTINGS_DEFAULTS.blocks.defaultKind,
133
+ defaultBlockType: () => EDITOR_SETTINGS_DEFAULTS.blocks.defaultBlockType,
134
134
  targetChars: () => EDITOR_SETTINGS_DEFAULTS.blocks.splitTargetChars
135
135
  }),
136
136
  addCommands() {
137
- /** The kind of the sub-Bausteine (`children`) or of the composite itself (`siblings`); null when a `children` split has no accepted kind. */
138
- const partKind = (composite, mode) => mode === "siblings" ? composite.attrs.kind : childKindFor(compositeKindsOf(this.editor), composite.attrs.kind, this.options.defaultKind());
137
+ /** The Block type of the nested Typed blocks (`children`) or of the composite itself (`siblings`); null when a `children` split has no accepted Block type. */
138
+ const partKind = (composite, mode) => mode === "siblings" ? composite.attrs.blockType : childKindFor(blockTypesOf(this.editor), composite.attrs.blockType, this.options.defaultBlockType());
139
139
  return {
140
140
  splitCompositeAtCaret: ({ mode }) => ({ state, tr, dispatch }) => {
141
141
  const { $head } = state.selection;
@@ -1 +1 @@
1
- {"version":3,"file":"split.js","names":[],"sources":["../../../src/features/composites/split.ts"],"sourcesContent":["// Splitting a Baustein: at the caret or by length, into sibling Bausteine or into sub-Bausteine. The pure parts\n// (`splitBodyByLength`, `generatedTitle`, `childKindFor`, `splitComposite`) know nothing about the editor; the\n// `CompositeSplit` extension wraps them into commands. Generated parts get a title from their first sentence and hide it.\nimport { Extension } from '@tiptap/core'\nimport { Fragment, type Node as PMNode, type Schema } from '@tiptap/pm/model'\nimport { type EditorState, TextSelection } from '@tiptap/pm/state'\nimport { EDITOR_SETTINGS_DEFAULTS } from '../../settings'\nimport { type CompositeKind, kindAccepts } from './kinds'\nimport { TITLE_HIDDEN_KEY } from './meta-keys'\nimport { COMPOSITE_CHROME_COUNT, compositeAround, compositeKindsOf } from './nodes'\n\n/** Where the parts of a split go: next to the split Baustein (`siblings`) or into it as sub-Bausteine (`children`). */\nexport type SplitMode = 'siblings' | 'children'\n\n/** Longest generated title; a longer first sentence is cut and ends in `…`. */\nconst TITLE_MAX_CHARS = 60\n\n/**\n * Groups `blocks` in order so that no group exceeds `targetChars` text characters, never splitting inside a block: a\n * new group starts when adding the block would exceed the target and the group is not empty, so a single block longer\n * than the target forms a group of its own.\n */\nexport function splitBodyByLength(blocks: readonly PMNode[], targetChars: number): PMNode[][] {\n const groups: PMNode[][] = []\n let current: PMNode[] = []\n let size = 0\n for (const block of blocks) {\n const chars = block.textContent.length\n if (current.length && size + chars > targetChars) {\n groups.push(current)\n current = []\n size = 0\n }\n current.push(block)\n size += chars\n }\n if (current.length) groups.push(current)\n return groups\n}\n\n/** Text of the first non-empty textblock in `blocks` (nested ones included), or ''. */\nfunction firstText(blocks: readonly PMNode[]): string {\n let found = ''\n for (const block of blocks) {\n if (block.isTextblock) found = block.textContent.trim()\n else block.descendants((node) => {\n if (found) return false\n if (node.isTextblock) found = node.textContent.trim()\n return !node.isTextblock\n })\n if (found) return found\n }\n return ''\n}\n\n/**\n * Title for a part holding `blocks`: the first sentence of its first textblock (up to the first `.`, `!` or `?` that\n * is followed by white space or ends the text; the mark itself is left out), at most 60 characters, `…` appended when\n * cut. '' when the blocks hold no text.\n */\nexport function generatedTitle(blocks: readonly PMNode[]): string {\n const text = firstText(blocks).replace(/\\s+/g, ' ')\n const end = text.search(/[.!?](?=\\s|$)/)\n const sentence = (end === -1 ? text : text.slice(0, end)).trim()\n return sentence.length > TITLE_MAX_CHARS ? `${sentence.slice(0, TITLE_MAX_CHARS).trimEnd()}…` : sentence\n}\n\n/**\n * Kind of the sub-Bausteine a split of a `parentKind` Baustein creates: `defaultKind` when the parent accepts it, else\n * the parent's own kind when it accepts itself, else null (the split is refused).\n */\nexport function childKindFor(kinds: readonly CompositeKind[], parentKind: string, defaultKind: string): string | null {\n if (kindAccepts(kinds, parentKind, defaultKind)) return defaultKind\n if (kindAccepts(kinds, parentKind, parentKind)) return parentKind\n return null\n}\n\nfunction chromeOf(composite: PMNode): PMNode[] {\n const chrome: PMNode[] = []\n for (let i = 0; i < COMPOSITE_CHROME_COUNT; i++) chrome.push(composite.child(i))\n return chrome\n}\n\nfunction bodyOf(composite: PMNode): PMNode[] {\n const body: PMNode[] = []\n composite.forEach((child, _offset, index) => {\n if (index >= COMPOSITE_CHROME_COUNT) body.push(child)\n })\n return body\n}\n\n/** A new Baustein of `kind` holding `group`, titled by `generatedTitle(group)`. */\nfunction newPart(schema: Schema, kind: string, group: readonly PMNode[], hideTitle: boolean): PMNode {\n const { nodes } = schema\n const title = generatedTitle(group)\n return nodes.composite!.create({ kind, meta: hideTitle ? { [TITLE_HIDDEN_KEY]: true } : {} }, [\n nodes.compositeTitle!.create(null, title ? schema.text(title) : null),\n nodes.compositeDescription!.create(),\n nodes.compositeTags!.create(),\n ...(group.length ? group : [nodes.paragraph!.create()]),\n ])\n}\n\n/**\n * The nodes that replace `composite` once its body is cut into `groups` (in order, each non-empty).\n * - `children`: one node, `composite` with its own title, description, tags and meta whose body is one new Baustein of\n * `childKind` per group.\n * - `siblings`: `composite` itself keeping the first group, then one new Baustein of the same kind per further group.\n * New parts carry a generated title, hidden when `hideTitles`, and no block id.\n */\nexport function splitComposite(schema: Schema, composite: PMNode, groups: readonly (readonly PMNode[])[], mode: SplitMode, childKind: string, hideTitles: boolean): PMNode[] {\n const chrome = chromeOf(composite)\n if (mode === 'children') return [composite.copy(Fragment.from([...chrome, ...groups.map(group => newPart(schema, childKind, group, hideTitles))]))]\n const [first = [], ...rest] = groups\n return [\n composite.copy(Fragment.from([...chrome, ...(first.length ? first : [schema.nodes.paragraph!.create()])])),\n ...rest.map(group => newPart(schema, composite.attrs.kind as string, group, hideTitles)),\n ]\n}\n\ndeclare module '@tiptap/core' {\n interface Commands<ReturnType> {\n compositeSplit: {\n /**\n * Split the caret's innermost Baustein in front of the body block holding the caret (refused when that is the first body block or the caret is not in a body): the part before and the part from the caret on become sibling Bausteine or sub-Bausteine (`children`, of the default kind or the parent's own; refused when neither is accepted). The caret moves into the new part.\n */\n splitCompositeAtCaret: (options: { mode: SplitMode }) => ReturnType\n /**\n * Split the Baustein at `pos` (default: the caret's innermost one) into parts of about `targetChars` characters (default: setting `blocks.splitTargetChars`) without cutting inside a block. Refused with fewer than two parts, or in `children` mode when no child kind is accepted. The generated titles are hidden.\n */\n splitCompositeByLength: (options: { mode: SplitMode, targetChars?: number, pos?: number }) => ReturnType\n }\n }\n}\n\n/** Options of `CompositeSplit`: read on every use, so a changed setting applies without recreating the editor. */\nexport interface CompositeSplitOptions {\n /** Kind of the sub-Bausteine a `children` split creates when the parent accepts it (setting `blocks.defaultKind`). */\n defaultKind: () => string\n /** Target size in characters of a length split (setting `blocks.splitTargetChars`). */\n targetChars: () => number\n}\n\n/** The composite whose content starts at `pos` in `state`, or the caret's innermost one when `pos` is undefined. */\nfunction targetComposite(state: EditorState, pos: number | undefined): { pos: number, node: PMNode } | null {\n if (pos === undefined) return compositeAround(state.selection.$head)\n const node = state.doc.nodeAt(pos)\n return node?.type.name === 'composite' ? { pos, node } : null\n}\n\n/** Position right in front of the body of `composite`, which starts at `pos`. */\nfunction bodyStartOf(pos: number, composite: PMNode): number {\n return pos + 1 + chromeOf(composite).reduce((size, child) => size + child.nodeSize, 0)\n}\n\n/** Position in front of the body of the last part among `nodes`, which replaced a composite starting at `pos`. */\nfunction lastPartBodyStart(pos: number, nodes: readonly PMNode[], mode: SplitMode): number {\n if (mode === 'children') {\n const parent = nodes[0]!\n const last = parent.lastChild!\n return bodyStartOf(pos + parent.nodeSize - 1 - last.nodeSize, last)\n }\n const last = nodes[nodes.length - 1]!\n return bodyStartOf(pos + nodes.reduce((size, node) => size + node.nodeSize, 0) - last.nodeSize, last)\n}\n\n/** Client-only, no schema: the split commands of Bausteine. */\nexport const CompositeSplit = Extension.create<CompositeSplitOptions>({\n name: 'compositeSplit',\n addOptions: () => ({\n defaultKind: () => EDITOR_SETTINGS_DEFAULTS.blocks.defaultKind,\n targetChars: () => EDITOR_SETTINGS_DEFAULTS.blocks.splitTargetChars,\n }),\n addCommands() {\n /** The kind of the sub-Bausteine (`children`) or of the composite itself (`siblings`); null when a `children` split has no accepted kind. */\n const partKind = (composite: PMNode, mode: SplitMode): string | null =>\n mode === 'siblings' ? composite.attrs.kind as string : childKindFor(compositeKindsOf(this.editor), composite.attrs.kind as string, this.options.defaultKind())\n\n return {\n splitCompositeAtCaret: ({ mode }) => ({ state, tr, dispatch }) => {\n const { $head } = state.selection\n const found = compositeAround($head)\n if (!found) return false\n const index = $head.index(found.depth) - COMPOSITE_CHROME_COUNT\n if (index < 1) return false\n const kind = partKind(found.node, mode)\n if (kind === null) return false\n if (dispatch) {\n const body = bodyOf(found.node)\n const nodes = splitComposite(state.schema, found.node, [body.slice(0, index), body.slice(index)], mode, kind, true)\n tr.replaceWith(found.pos, found.pos + found.node.nodeSize, nodes)\n tr.setSelection(TextSelection.near(tr.doc.resolve(lastPartBodyStart(found.pos, nodes, mode))))\n }\n return true\n },\n\n splitCompositeByLength: ({ mode, targetChars, pos }) => ({ state, tr, dispatch }) => {\n const found = targetComposite(state, pos)\n if (!found) return false\n const groups = splitBodyByLength(bodyOf(found.node), targetChars ?? this.options.targetChars())\n if (groups.length < 2) return false\n const kind = partKind(found.node, mode)\n if (kind === null) return false\n if (dispatch) tr.replaceWith(found.pos, found.pos + found.node.nodeSize, splitComposite(state.schema, found.node, groups, mode, kind, true))\n return true\n },\n }\n },\n})\n"],"mappings":"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"}
1
+ {"version":3,"file":"split.js","names":[],"sources":["../../../src/features/composites/split.ts"],"sourcesContent":["// Splitting a Typed block: at the caret or by length, into sibling Typed blocks or into nested Typed blocks. The pure parts\n// (`splitBodyByLength`, `generatedTitle`, `childKindFor`, `splitComposite`) know nothing about the editor; the\n// `CompositeSplit` extension wraps them into commands. Generated parts get a title from their first sentence and hide it.\nimport { Extension } from '@tiptap/core'\nimport { Fragment, type Node as PMNode, type Schema } from '@tiptap/pm/model'\nimport { type EditorState, TextSelection } from '@tiptap/pm/state'\nimport { EDITOR_SETTINGS_DEFAULTS } from '../../settings'\nimport { acceptsChild, type BlockType } from './block-types'\nimport { TITLE_HIDDEN_KEY } from './meta-keys'\nimport { COMPOSITE_CHROME_COUNT, compositeAround, blockTypesOf } from './nodes'\n\n/** Where the parts of a split go: next to the split Typed block (`siblings`) or into it as nested Typed blocks (`children`). */\nexport type SplitMode = 'siblings' | 'children'\n\n/** Longest generated title; a longer first sentence is cut and ends in `…`. */\nconst TITLE_MAX_CHARS = 60\n\n/**\n * Groups `blocks` in order so that no group exceeds `targetChars` text characters, never splitting inside a block: a\n * new group starts when adding the block would exceed the target and the group is not empty, so a single block longer\n * than the target forms a group of its own.\n */\nexport function splitBodyByLength(blocks: readonly PMNode[], targetChars: number): PMNode[][] {\n const groups: PMNode[][] = []\n let current: PMNode[] = []\n let size = 0\n for (const block of blocks) {\n const chars = block.textContent.length\n if (current.length && size + chars > targetChars) {\n groups.push(current)\n current = []\n size = 0\n }\n current.push(block)\n size += chars\n }\n if (current.length) groups.push(current)\n return groups\n}\n\n/** Text of the first non-empty textblock in `blocks` (nested ones included), or ''. */\nfunction firstText(blocks: readonly PMNode[]): string {\n let found = ''\n for (const block of blocks) {\n if (block.isTextblock) found = block.textContent.trim()\n else block.descendants((node) => {\n if (found) return false\n if (node.isTextblock) found = node.textContent.trim()\n return !node.isTextblock\n })\n if (found) return found\n }\n return ''\n}\n\n/**\n * Title for a part holding `blocks`: the first sentence of its first textblock (up to the first `.`, `!` or `?` that\n * is followed by white space or ends the text; the mark itself is left out), at most 60 characters, `…` appended when\n * cut. '' when the blocks hold no text.\n */\nexport function generatedTitle(blocks: readonly PMNode[]): string {\n const text = firstText(blocks).replace(/\\s+/g, ' ')\n const end = text.search(/[.!?](?=\\s|$)/)\n const sentence = (end === -1 ? text : text.slice(0, end)).trim()\n return sentence.length > TITLE_MAX_CHARS ? `${sentence.slice(0, TITLE_MAX_CHARS).trimEnd()}…` : sentence\n}\n\n/**\n * Kind of the nested Typed blocks a split of a `parentKind` Typed block creates: `defaultBlockType` when the parent accepts it, else\n * the parent's own kind when it accepts itself, else null (the split is refused).\n */\nexport function childKindFor(kinds: readonly BlockType[], parentKind: string, defaultBlockType: string): string | null {\n if (acceptsChild(kinds, parentKind, defaultBlockType)) return defaultBlockType\n if (acceptsChild(kinds, parentKind, parentKind)) return parentKind\n return null\n}\n\nfunction chromeOf(composite: PMNode): PMNode[] {\n const chrome: PMNode[] = []\n for (let i = 0; i < COMPOSITE_CHROME_COUNT; i++) chrome.push(composite.child(i))\n return chrome\n}\n\nfunction bodyOf(composite: PMNode): PMNode[] {\n const body: PMNode[] = []\n composite.forEach((child, _offset, index) => {\n if (index >= COMPOSITE_CHROME_COUNT) body.push(child)\n })\n return body\n}\n\n/** A new Typed block of `kind` holding `group`, titled by `generatedTitle(group)`. */\nfunction newPart(schema: Schema, kind: string, group: readonly PMNode[], hideTitle: boolean): PMNode {\n const { nodes } = schema\n const title = generatedTitle(group)\n return nodes.typedBlock!.create({ blockType: kind, meta: hideTitle ? { [TITLE_HIDDEN_KEY]: true } : {} }, [\n nodes.typedBlockTitle!.create(null, title ? schema.text(title) : null),\n nodes.typedBlockDescription!.create(),\n nodes.typedBlockTags!.create(),\n ...(group.length ? group : [nodes.paragraph!.create()]),\n ])\n}\n\n/**\n * The nodes that replace `composite` once its body is cut into `groups` (in order, each non-empty).\n * - `children`: one node, `composite` with its own title, description, tags and meta whose body is one new Typed block of\n * `childKind` per group.\n * - `siblings`: `composite` itself keeping the first group, then one new Typed block of the same Block type per further group.\n * New parts carry a generated title, hidden when `hideTitles`, and no block id.\n */\nexport function splitComposite(schema: Schema, composite: PMNode, groups: readonly (readonly PMNode[])[], mode: SplitMode, childKind: string, hideTitles: boolean): PMNode[] {\n const chrome = chromeOf(composite)\n if (mode === 'children') return [composite.copy(Fragment.from([...chrome, ...groups.map(group => newPart(schema, childKind, group, hideTitles))]))]\n const [first = [], ...rest] = groups\n return [\n composite.copy(Fragment.from([...chrome, ...(first.length ? first : [schema.nodes.paragraph!.create()])])),\n ...rest.map(group => newPart(schema, composite.attrs.blockType as string, group, hideTitles)),\n ]\n}\n\ndeclare module '@tiptap/core' {\n interface Commands<ReturnType> {\n compositeSplit: {\n /**\n * Split the caret's innermost Typed block in front of the body block holding the caret (refused when that is the first body block or the caret is not in a body): the part before and the part from the caret on become sibling Typed blocks or nested Typed blocks (`children`, of the default Block type or the parent's own; refused when neither is accepted). The caret moves into the new part.\n */\n splitCompositeAtCaret: (options: { mode: SplitMode }) => ReturnType\n /**\n * Split the Typed block at `pos` (default: the caret's innermost one) into parts of about `targetChars` characters (default: setting `blocks.splitTargetChars`) without cutting inside a block. Refused with fewer than two parts, or in `children` mode when no child Block type is accepted. The generated titles are hidden.\n */\n splitCompositeByLength: (options: { mode: SplitMode, targetChars?: number, pos?: number }) => ReturnType\n }\n }\n}\n\n/** Options of `CompositeSplit`: read on every use, so a changed setting applies without recreating the editor. */\nexport interface CompositeSplitOptions {\n /** Kind of the nested Typed blocks a `children` split creates when the parent accepts it (setting `blocks.defaultBlockType`). */\n defaultBlockType: () => string\n /** Target size in characters of a length split (setting `blocks.splitTargetChars`). */\n targetChars: () => number\n}\n\n/** The composite whose content starts at `pos` in `state`, or the caret's innermost one when `pos` is undefined. */\nfunction targetComposite(state: EditorState, pos: number | undefined): { pos: number, node: PMNode } | null {\n if (pos === undefined) return compositeAround(state.selection.$head)\n const node = state.doc.nodeAt(pos)\n return node?.type.name === 'typedBlock' ? { pos, node } : null\n}\n\n/** Position right in front of the body of `composite`, which starts at `pos`. */\nfunction bodyStartOf(pos: number, composite: PMNode): number {\n return pos + 1 + chromeOf(composite).reduce((size, child) => size + child.nodeSize, 0)\n}\n\n/** Position in front of the body of the last part among `nodes`, which replaced a composite starting at `pos`. */\nfunction lastPartBodyStart(pos: number, nodes: readonly PMNode[], mode: SplitMode): number {\n if (mode === 'children') {\n const parent = nodes[0]!\n const last = parent.lastChild!\n return bodyStartOf(pos + parent.nodeSize - 1 - last.nodeSize, last)\n }\n const last = nodes[nodes.length - 1]!\n return bodyStartOf(pos + nodes.reduce((size, node) => size + node.nodeSize, 0) - last.nodeSize, last)\n}\n\n/** Client-only, no schema: the split commands of Typed blocks. */\nexport const CompositeSplit = Extension.create<CompositeSplitOptions>({\n name: 'compositeSplit',\n addOptions: () => ({\n defaultBlockType: () => EDITOR_SETTINGS_DEFAULTS.blocks.defaultBlockType,\n targetChars: () => EDITOR_SETTINGS_DEFAULTS.blocks.splitTargetChars,\n }),\n addCommands() {\n /** The Block type of the nested Typed blocks (`children`) or of the composite itself (`siblings`); null when a `children` split has no accepted Block type. */\n const partKind = (composite: PMNode, mode: SplitMode): string | null =>\n mode === 'siblings' ? composite.attrs.blockType as string : childKindFor(blockTypesOf(this.editor), composite.attrs.blockType as string, this.options.defaultBlockType())\n\n return {\n splitCompositeAtCaret: ({ mode }) => ({ state, tr, dispatch }) => {\n const { $head } = state.selection\n const found = compositeAround($head)\n if (!found) return false\n const index = $head.index(found.depth) - COMPOSITE_CHROME_COUNT\n if (index < 1) return false\n const kind = partKind(found.node, mode)\n if (kind === null) return false\n if (dispatch) {\n const body = bodyOf(found.node)\n const nodes = splitComposite(state.schema, found.node, [body.slice(0, index), body.slice(index)], mode, kind, true)\n tr.replaceWith(found.pos, found.pos + found.node.nodeSize, nodes)\n tr.setSelection(TextSelection.near(tr.doc.resolve(lastPartBodyStart(found.pos, nodes, mode))))\n }\n return true\n },\n\n splitCompositeByLength: ({ mode, targetChars, pos }) => ({ state, tr, dispatch }) => {\n const found = targetComposite(state, pos)\n if (!found) return false\n const groups = splitBodyByLength(bodyOf(found.node), targetChars ?? this.options.targetChars())\n if (groups.length < 2) return false\n const kind = partKind(found.node, mode)\n if (kind === null) return false\n if (dispatch) tr.replaceWith(found.pos, found.pos + found.node.nodeSize, splitComposite(state.schema, found.node, groups, mode, kind, true))\n return true\n },\n }\n },\n})\n"],"mappings":"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"}
@@ -5,9 +5,9 @@ const STRUCTURE_MODE_KEYS = {
5
5
  labelKey: "composites.settings.structure.flat.label",
6
6
  descriptionKey: "composites.settings.structure.flat.description"
7
7
  },
8
- composite: {
9
- labelKey: "composites.settings.structure.composite.label",
10
- descriptionKey: "composites.settings.structure.composite.description"
8
+ structured: {
9
+ labelKey: "composites.settings.structure.structured.label",
10
+ descriptionKey: "composites.settings.structure.structured.description"
11
11
  }
12
12
  };
13
13
  //#endregion
@@ -1 +1 @@
1
- {"version":3,"file":"structure-mode.js","names":[],"sources":["../../../src/features/composites/structure-mode.ts"],"sourcesContent":["import type { MessageKey } from '../../i18n'\nimport type { StructureMode } from '../../settings'\n\n/** Message keys of the labels of the settings radio and the toolbar's „Gliederung“ dropdown; resolve them with `t`. */\nexport const STRUCTURE_MODE_KEYS: Record<StructureMode, { labelKey: MessageKey, descriptionKey: MessageKey }> = {\n flat: { labelKey: 'composites.settings.structure.flat.label', descriptionKey: 'composites.settings.structure.flat.description' },\n composite: { labelKey: 'composites.settings.structure.composite.label', descriptionKey: 'composites.settings.structure.composite.description' },\n}\n"],"mappings":";;AAIA,MAAa,sBAAmG;CAC9G,MAAM;EAAE,UAAU;EAA4C,gBAAgB;CAAiD;CAC/H,WAAW;EAAE,UAAU;EAAiD,gBAAgB;CAAsD;AAChJ"}
1
+ {"version":3,"file":"structure-mode.js","names":[],"sources":["../../../src/features/composites/structure-mode.ts"],"sourcesContent":["import type { MessageKey } from '../../i18n'\nimport type { StructureMode } from '../../settings'\n\n/** Message keys of the labels of the settings radio and the toolbar's „Gliederung“ dropdown; resolve them with `t`. */\nexport const STRUCTURE_MODE_KEYS: Record<StructureMode, { labelKey: MessageKey, descriptionKey: MessageKey }> = {\n flat: { labelKey: 'composites.settings.structure.flat.label', descriptionKey: 'composites.settings.structure.flat.description' },\n structured: { labelKey: 'composites.settings.structure.structured.label', descriptionKey: 'composites.settings.structure.structured.description' },\n}\n"],"mappings":";;AAIA,MAAa,sBAAmG;CAC9G,MAAM;EAAE,UAAU;EAA4C,gBAAgB;CAAiD;CAC/H,YAAY;EAAE,UAAU;EAAkD,gBAAgB;CAAuD;AACnJ"}
@@ -14,7 +14,7 @@ const numberFormat = new Intl.NumberFormat("de-DE");
14
14
  /** German, numeric-aware ordering of two sort keys' text. */
15
15
  const collator = new Intl.Collator("de", { numeric: true });
16
16
  /** The field of `row`'s kind with key `key`. */
17
- const fieldOf = (row, key) => row.fields.find((field) => field.key === key);
17
+ const fieldOf = (row, key) => row.definitions.find((field) => field.key === key);
18
18
  /** The cell text of `row`'s field `key`; empty when the value is unset or the row's kind does not have the field. Without `context`, `reference` fields read empty. */
19
19
  function fieldText(row, key, context) {
20
20
  const field = fieldOf(row, key);
@@ -46,7 +46,7 @@ function fieldColumnsOf(rows, kinds, context) {
46
46
  const firstRowOfKind = /* @__PURE__ */ new Map();
47
47
  for (const row of rows) if (!firstRowOfKind.has(row.kind)) firstRowOfKind.set(row.kind, row);
48
48
  const seen = /* @__PURE__ */ new Map();
49
- for (const kind of kinds) for (const field of firstRowOfKind.get(kind.id)?.fields ?? []) {
49
+ for (const kind of kinds) for (const field of firstRowOfKind.get(kind.id)?.definitions ?? []) {
50
50
  if (field.type === "textarea" || seen.has(field.key)) continue;
51
51
  seen.set(field.key, {
52
52
  id: `${FIELD_PREFIX}${field.key}`,
@@ -1 +1 @@
1
- {"version":3,"file":"table-model.js","names":[],"sources":["../../../src/features/composites/table-model.ts"],"sourcesContent":["import type { Node as PMNode } from '@tiptap/pm/model'\nimport type { Translate } from '../../i18n'\nimport type { CompositeKind, CompositeMetaField } from './kinds'\nimport { fieldDisplay, formatDate } from './meta-display'\nimport type { CompositeRow } from './rows'\n\n// The framework-free part of the Bausteine table (`CompositeTable` on Vue and React): column specs, cell text and sort\n// keys. Columns beyond the fixed ones derive from the meta fields of the kinds present in the document.\n\n/** A sort key; `null` is an empty value, which sorts last in either direction. */\nexport type SortValue = string | number | null\n\nexport interface ColumnSpec {\n id: string\n label: string\n /** Number columns read better flush right, next to their tabular numerals. */\n align?: 'end'\n sort: (row: CompositeRow) => SortValue\n}\n\nexport interface FieldColumn extends ColumnSpec {\n field: CompositeMetaField\n}\n\n/** Id prefix of the columns derived from meta fields. */\nexport const FIELD_PREFIX = 'meta:'\n\n/** The \"no filter\" value of a field's select filter. */\nexport const FILTER_ALL = '__all__'\n\nconst isEmpty = (value: unknown): boolean => value === undefined || value === null || value === ''\nconst finiteNumber = (value: unknown): number | null => {\n if (isEmpty(value)) return null\n const number = Number(value)\n return Number.isFinite(number) ? number : null\n}\nconst numberFormat = new Intl.NumberFormat('de-DE')\n\n/** What a cell needs beyond its row to resolve `reference` fields and word `derivation` methods: the document, its kinds and the translator. */\nexport interface FieldContext {\n doc: PMNode\n kinds: readonly CompositeKind[]\n t: Translate\n}\n\n/** German, numeric-aware ordering of two sort keys' text. */\nexport const collator = new Intl.Collator('de', { numeric: true })\n\n/** The field of `row`'s kind with key `key`. */\nexport const fieldOf = (row: CompositeRow, key: string): CompositeMetaField | undefined => row.fields.find(field => field.key === key)\n\n/** The cell text of `row`'s field `key`; empty when the value is unset or the row's kind does not have the field. Without `context`, `reference` fields read empty. */\nexport function fieldText(row: CompositeRow, key: string, context?: FieldContext): string {\n const field = fieldOf(row, key)\n const value = row.meta[key]\n if (!field || isEmpty(value)) return ''\n if (field.type === 'select') return field.options?.find(option => option.value === value)?.label ?? String(value)\n if (field.type === 'date') return formatDate(String(value))\n if (field.type === 'number') {\n const number = finiteNumber(value)\n return number === null ? String(value) : numberFormat.format(number)\n }\n return fieldDisplay(row, field, context?.doc ?? null, context?.kinds ?? [], context?.t)\n}\n\n/** The sort key of `row`'s field `key`: numbers as numbers, selects, references, citations and provenance by their cell text, everything else as text. */\nexport function fieldSort(row: CompositeRow, key: string, context?: FieldContext): SortValue {\n const field = fieldOf(row, key)\n const value = row.meta[key]\n if (!field || isEmpty(value)) return null\n if (field.type === 'number') return finiteNumber(value) ?? String(value)\n // ISO dates order correctly as plain strings; select values are ordered by what the user reads.\n if (field.type === 'select' || field.type === 'multiselect' || field.type === 'reference' || field.type === 'bibliography' || field.type === 'derivation') return fieldText(row, key, context) || null\n return String(value)\n}\n\n/**\n * One column per field key in use, in kind order; the first kind that has the key decides label and type.\n * `textarea` fields (long text such as a transcript) get no column: a table cell can only show a truncated fragment.\n * `context` resolves `reference` cells and sort keys.\n */\nexport function fieldColumnsOf(rows: readonly CompositeRow[], kinds: readonly { id: string }[], context?: FieldContext): FieldColumn[] {\n const firstRowOfKind = new Map<string, CompositeRow>()\n for (const row of rows) if (!firstRowOfKind.has(row.kind)) firstRowOfKind.set(row.kind, row)\n const seen = new Map<string, FieldColumn>()\n for (const kind of kinds) {\n for (const field of firstRowOfKind.get(kind.id)?.fields ?? []) {\n if (field.type === 'textarea' || seen.has(field.key)) continue\n seen.set(field.key, {\n id: `${FIELD_PREFIX}${field.key}`,\n label: field.label,\n align: field.type === 'number' ? 'end' : undefined,\n sort: row => fieldSort(row, field.key, context),\n field,\n })\n }\n }\n return [...seen.values()]\n}\n\n/** All columns: title and kind, then the field columns, then tags and summary. */\nexport function columnSpecsOf(fieldColumns: readonly FieldColumn[], t: Translate): ColumnSpec[] {\n return [\n { id: 'title', label: t('composites.table.column.composite'), sort: row => row.title.trim() || null },\n { id: 'kind', label: t('composites.table.column.kind'), sort: row => row.kindLabel },\n ...fieldColumns,\n { id: 'tags', label: t('composites.table.column.tags'), sort: row => row.tags.join(', ') || null },\n // Never empty: absence is a value here, so descending puts the summarized Bausteine first.\n { id: 'summary', label: t('composites.table.column.summary'), sort: row => (row.description.trim() ? 1 : 0) },\n ]\n}\n\n/** `rows` ordered by `sort`, descending when `desc`; empty values last whatever the direction. */\nexport function sortRows(rows: readonly CompositeRow[], sort: ColumnSpec['sort'], desc: boolean): CompositeRow[] {\n const factor = desc ? -1 : 1\n return [...rows].sort((a, b) => {\n const x = sort(a)\n const y = sort(b)\n if (x === null || y === null) return x === y ? 0 : x === null ? 1 : -1\n if (typeof x === 'number' && typeof y === 'number') return (x - y) * factor\n return collator.compare(String(x), String(y)) * factor\n })\n}\n\n/** `list` with `value` added, or removed when present. Pure: returns the new list, the caller assigns it. */\nexport function toggled(list: readonly string[], value: string): string[] {\n return list.includes(value) ? list.filter(item => item !== value) : [...list, value]\n}\n\nexport const hasText = (value: string) => value.trim() !== ''\n\n/** Long text fields (and the citation or provenance summaries) show a truncated fragment in a cell, with the full text as its title. */\nexport const isLongText = (field: CompositeMetaField) => field.type === 'text' || field.type === 'textarea' || field.type === 'multiselect' || field.type === 'reference' || field.type === 'bibliography' || field.type === 'derivation'\n"],"mappings":"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"}
1
+ {"version":3,"file":"table-model.js","names":[],"sources":["../../../src/features/composites/table-model.ts"],"sourcesContent":["import type { Node as PMNode } from '@tiptap/pm/model'\nimport type { Translate } from '../../i18n'\nimport type { PropertyDefinition } from '../../core/properties'\nimport type { BlockType } from './block-types'\nimport { fieldDisplay, formatDate } from './meta-display'\nimport type { CompositeRow } from './rows'\n\n// The framework-free part of the Typed blocks table (`CompositeTable` on Vue and React): column specs, cell text and sort\n// keys. Columns beyond the fixed ones derive from the meta fields of the kinds present in the document.\n\n/** A sort key; `null` is an empty value, which sorts last in either direction. */\nexport type SortValue = string | number | null\n\nexport interface ColumnSpec {\n id: string\n label: string\n /** Number columns read better flush right, next to their tabular numerals. */\n align?: 'end'\n sort: (row: CompositeRow) => SortValue\n}\n\nexport interface FieldColumn extends ColumnSpec {\n field: PropertyDefinition\n}\n\n/** Id prefix of the columns derived from meta fields. */\nexport const FIELD_PREFIX = 'meta:'\n\n/** The \"no filter\" value of a field's select filter. */\nexport const FILTER_ALL = '__all__'\n\nconst isEmpty = (value: unknown): boolean => value === undefined || value === null || value === ''\nconst finiteNumber = (value: unknown): number | null => {\n if (isEmpty(value)) return null\n const number = Number(value)\n return Number.isFinite(number) ? number : null\n}\nconst numberFormat = new Intl.NumberFormat('de-DE')\n\n/** What a cell needs beyond its row to resolve `reference` fields and word `derivation` methods: the document, its kinds and the translator. */\nexport interface FieldContext {\n doc: PMNode\n kinds: readonly BlockType[]\n t: Translate\n}\n\n/** German, numeric-aware ordering of two sort keys' text. */\nexport const collator = new Intl.Collator('de', { numeric: true })\n\n/** The field of `row`'s kind with key `key`. */\nexport const fieldOf = (row: CompositeRow, key: string): PropertyDefinition | undefined => row.definitions.find(field => field.key === key)\n\n/** The cell text of `row`'s field `key`; empty when the value is unset or the row's kind does not have the field. Without `context`, `reference` fields read empty. */\nexport function fieldText(row: CompositeRow, key: string, context?: FieldContext): string {\n const field = fieldOf(row, key)\n const value = row.meta[key]\n if (!field || isEmpty(value)) return ''\n if (field.type === 'select') return field.options?.find(option => option.value === value)?.label ?? String(value)\n if (field.type === 'date') return formatDate(String(value))\n if (field.type === 'number') {\n const number = finiteNumber(value)\n return number === null ? String(value) : numberFormat.format(number)\n }\n return fieldDisplay(row, field, context?.doc ?? null, context?.kinds ?? [], context?.t)\n}\n\n/** The sort key of `row`'s field `key`: numbers as numbers, selects, references, citations and provenance by their cell text, everything else as text. */\nexport function fieldSort(row: CompositeRow, key: string, context?: FieldContext): SortValue {\n const field = fieldOf(row, key)\n const value = row.meta[key]\n if (!field || isEmpty(value)) return null\n if (field.type === 'number') return finiteNumber(value) ?? String(value)\n // ISO dates order correctly as plain strings; select values are ordered by what the user reads.\n if (field.type === 'select' || field.type === 'multiselect' || field.type === 'reference' || field.type === 'bibliography' || field.type === 'derivation') return fieldText(row, key, context) || null\n return String(value)\n}\n\n/**\n * One column per field key in use, in kind order; the first kind that has the key decides label and type.\n * `textarea` fields (long text such as a transcript) get no column: a table cell can only show a truncated fragment.\n * `context` resolves `reference` cells and sort keys.\n */\nexport function fieldColumnsOf(rows: readonly CompositeRow[], kinds: readonly { id: string }[], context?: FieldContext): FieldColumn[] {\n const firstRowOfKind = new Map<string, CompositeRow>()\n for (const row of rows) if (!firstRowOfKind.has(row.kind)) firstRowOfKind.set(row.kind, row)\n const seen = new Map<string, FieldColumn>()\n for (const kind of kinds) {\n for (const field of firstRowOfKind.get(kind.id)?.definitions ?? []) {\n if (field.type === 'textarea' || seen.has(field.key)) continue\n seen.set(field.key, {\n id: `${FIELD_PREFIX}${field.key}`,\n label: field.label,\n align: field.type === 'number' ? 'end' : undefined,\n sort: row => fieldSort(row, field.key, context),\n field,\n })\n }\n }\n return [...seen.values()]\n}\n\n/** All columns: title and kind, then the field columns, then tags and summary. */\nexport function columnSpecsOf(fieldColumns: readonly FieldColumn[], t: Translate): ColumnSpec[] {\n return [\n { id: 'title', label: t('composites.table.column.composite'), sort: row => row.title.trim() || null },\n { id: 'kind', label: t('composites.table.column.kind'), sort: row => row.kindLabel },\n ...fieldColumns,\n { id: 'tags', label: t('composites.table.column.tags'), sort: row => row.tags.join(', ') || null },\n // Never empty: absence is a value here, so descending puts the summarized Typed blocks first.\n { id: 'summary', label: t('composites.table.column.summary'), sort: row => (row.description.trim() ? 1 : 0) },\n ]\n}\n\n/** `rows` ordered by `sort`, descending when `desc`; empty values last whatever the direction. */\nexport function sortRows(rows: readonly CompositeRow[], sort: ColumnSpec['sort'], desc: boolean): CompositeRow[] {\n const factor = desc ? -1 : 1\n return [...rows].sort((a, b) => {\n const x = sort(a)\n const y = sort(b)\n if (x === null || y === null) return x === y ? 0 : x === null ? 1 : -1\n if (typeof x === 'number' && typeof y === 'number') return (x - y) * factor\n return collator.compare(String(x), String(y)) * factor\n })\n}\n\n/** `list` with `value` added, or removed when present. Pure: returns the new list, the caller assigns it. */\nexport function toggled(list: readonly string[], value: string): string[] {\n return list.includes(value) ? list.filter(item => item !== value) : [...list, value]\n}\n\nexport const hasText = (value: string) => value.trim() !== ''\n\n/** Long text fields (and the citation or provenance summaries) show a truncated fragment in a cell, with the full text as its title. */\nexport const isLongText = (field: PropertyDefinition) => field.type === 'text' || field.type === 'textarea' || field.type === 'multiselect' || field.type === 'reference' || field.type === 'bibliography' || field.type === 'derivation'\n"],"mappings":"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"}
@@ -32,7 +32,9 @@ function useCompositeInspector(editor, documentFocused) {
32
32
  tags: computed(() => state.value.tags),
33
33
  kinds: computed(() => state.value.kinds),
34
34
  mentions: computed(() => state.value.mentions),
35
- focused: computed(() => state.value.focused)
35
+ focused: computed(() => state.value.focused),
36
+ properties: computed(() => state.value.properties),
37
+ derivation: computed(() => state.value.derivation)
36
38
  };
37
39
  }
38
40
  //#endregion
@@ -1 +1 @@
1
- {"version":3,"file":"use-composite-inspector.js","names":[],"sources":["../../../src/features/composites/use-composite-inspector.ts"],"sourcesContent":["import type { Editor } from '@tiptap/core'\nimport { computed, type ComputedRef, type MaybeRefOrGetter, shallowRef, type ShallowRef, toValue, watch } from 'vue'\nimport { useStoreRef } from '../../vue/store-ref'\nimport { type CompositeInspector, type CompositeInspectorSection, type CompositeKindOption, createCompositeInspector } from './inspector-model'\nimport type { CompositeMention, CompositeRow } from './rows'\nimport type { CompositeKindCount } from './rows-model'\n\n/** The state of an editor's `createCompositeInspector` model as Vue refs, with the model for its actions. */\nexport interface CompositeInspectorRefs {\n /** The model of the current editor; replaced when the editor changes, so call its actions through this ref. */\n inspector: Readonly<ShallowRef<CompositeInspector>>\n section: ComputedRef<CompositeInspectorSection>\n editable: ComputedRef<boolean>\n draft: ComputedRef<string>\n searchTerm: ComputedRef<string>\n tagItems: ComputedRef<string[]>\n kindOptions: ComputedRef<CompositeKindOption[]>\n summarized: ComputedRef<number>\n hasSummary: ComputedRef<boolean>\n rows: ComputedRef<readonly CompositeRow[]>\n tags: ComputedRef<readonly string[]>\n kinds: ComputedRef<readonly CompositeKindCount[]>\n mentions: ComputedRef<readonly CompositeMention[]>\n focused: ComputedRef<CompositeRow | null>\n}\n\n/**\n * The inspector model of `editor` (see `createCompositeInspector`) as Vue refs. Follows the editor when the source\n * changes (the previous model commits its pending description draft and is disposed); a missing editor yields empty\n * state. `documentFocused` is forwarded to the model, also to the model of a new editor. Call during component setup:\n * the model is disposed with the scope.\n */\nexport function useCompositeInspector(editor: MaybeRefOrGetter<Editor | undefined>, documentFocused: MaybeRefOrGetter<boolean | undefined>): CompositeInspectorRefs {\n const inspector = shallowRef(createCompositeInspector(undefined))\n const state = useStoreRef(() => inspector.value.state)\n\n watch(() => toValue(editor), (instance, _previous, onCleanup) => {\n const next = createCompositeInspector(instance)\n next.setDocumentFocused(!!toValue(documentFocused))\n inspector.value = next\n onCleanup(() => next.dispose())\n }, { immediate: true })\n watch(() => !!toValue(documentFocused), focused => inspector.value.setDocumentFocused(focused))\n\n return {\n inspector,\n section: computed(() => state.value.section),\n editable: computed(() => state.value.editable),\n draft: computed(() => state.value.draft),\n searchTerm: computed(() => state.value.searchTerm),\n tagItems: computed(() => state.value.tagItems),\n kindOptions: computed(() => state.value.kindOptions),\n summarized: computed(() => state.value.summarized),\n hasSummary: computed(() => state.value.hasSummary),\n rows: computed(() => state.value.rows),\n tags: computed(() => state.value.tags),\n kinds: computed(() => state.value.kinds),\n mentions: computed(() => state.value.mentions),\n focused: computed(() => state.value.focused),\n }\n}\n"],"mappings":";;;;;;;;;;AAgCA,SAAgB,sBAAsB,QAA8C,iBAAgF;CAClK,MAAM,YAAY,WAAW,yBAAyB,KAAA,CAAS,CAAC;CAChE,MAAM,QAAQ,kBAAkB,UAAU,MAAM,KAAK;CAErD,YAAY,QAAQ,MAAM,IAAI,UAAU,WAAW,cAAc;EAC/D,MAAM,OAAO,yBAAyB,QAAQ;EAC9C,KAAK,mBAAmB,CAAC,CAAC,QAAQ,eAAe,CAAC;EAClD,UAAU,QAAQ;EAClB,gBAAgB,KAAK,QAAQ,CAAC;CAChC,GAAG,EAAE,WAAW,KAAK,CAAC;CACtB,YAAY,CAAC,CAAC,QAAQ,eAAe,IAAG,YAAW,UAAU,MAAM,mBAAmB,OAAO,CAAC;CAE9F,OAAO;EACL;EACA,SAAS,eAAe,MAAM,MAAM,OAAO;EAC3C,UAAU,eAAe,MAAM,MAAM,QAAQ;EAC7C,OAAO,eAAe,MAAM,MAAM,KAAK;EACvC,YAAY,eAAe,MAAM,MAAM,UAAU;EACjD,UAAU,eAAe,MAAM,MAAM,QAAQ;EAC7C,aAAa,eAAe,MAAM,MAAM,WAAW;EACnD,YAAY,eAAe,MAAM,MAAM,UAAU;EACjD,YAAY,eAAe,MAAM,MAAM,UAAU;EACjD,MAAM,eAAe,MAAM,MAAM,IAAI;EACrC,MAAM,eAAe,MAAM,MAAM,IAAI;EACrC,OAAO,eAAe,MAAM,MAAM,KAAK;EACvC,UAAU,eAAe,MAAM,MAAM,QAAQ;EAC7C,SAAS,eAAe,MAAM,MAAM,OAAO;CAC7C;AACF"}
1
+ {"version":3,"file":"use-composite-inspector.js","names":[],"sources":["../../../src/features/composites/use-composite-inspector.ts"],"sourcesContent":["import type { Editor } from '@tiptap/core'\nimport { computed, type ComputedRef, type MaybeRefOrGetter, shallowRef, type ShallowRef, toValue, watch } from 'vue'\nimport { useStoreRef } from '../../vue/store-ref'\nimport { type CompositeInspector, type CompositeInspectorSection, type BlockTypeOption, createCompositeInspector, type InspectorDerivation } from './inspector-model'\nimport type { BlockProperties } from './properties'\nimport type { CompositeMention, CompositeRow } from './rows'\nimport type { BlockTypeCount } from './rows-model'\n\n/** The state of an editor's `createCompositeInspector` model as Vue refs, with the model for its actions. */\nexport interface CompositeInspectorRefs {\n /** The model of the current editor; replaced when the editor changes, so call its actions through this ref. */\n inspector: Readonly<ShallowRef<CompositeInspector>>\n section: ComputedRef<CompositeInspectorSection>\n editable: ComputedRef<boolean>\n draft: ComputedRef<string>\n searchTerm: ComputedRef<string>\n tagItems: ComputedRef<string[]>\n kindOptions: ComputedRef<BlockTypeOption[]>\n summarized: ComputedRef<number>\n hasSummary: ComputedRef<boolean>\n rows: ComputedRef<readonly CompositeRow[]>\n tags: ComputedRef<readonly string[]>\n kinds: ComputedRef<readonly BlockTypeCount[]>\n mentions: ComputedRef<readonly CompositeMention[]>\n focused: ComputedRef<CompositeRow | null>\n /** The Block properties at the caret (see `CompositeInspectorState.properties`). */\n properties: ComputedRef<BlockProperties | null>\n /** The Derivation of that block when it is a Derived block without its own `derivation` definition (see `CompositeInspectorState.derivation`). */\n derivation: ComputedRef<InspectorDerivation | null>\n}\n\n/**\n * The inspector model of `editor` (see `createCompositeInspector`) as Vue refs. Follows the editor when the source\n * changes (the previous model commits its pending description draft and is disposed); a missing editor yields empty\n * state. `documentFocused` is forwarded to the model, also to the model of a new editor. Call during component setup:\n * the model is disposed with the scope.\n */\nexport function useCompositeInspector(editor: MaybeRefOrGetter<Editor | undefined>, documentFocused: MaybeRefOrGetter<boolean | undefined>): CompositeInspectorRefs {\n const inspector = shallowRef(createCompositeInspector(undefined))\n const state = useStoreRef(() => inspector.value.state)\n\n watch(() => toValue(editor), (instance, _previous, onCleanup) => {\n const next = createCompositeInspector(instance)\n next.setDocumentFocused(!!toValue(documentFocused))\n inspector.value = next\n onCleanup(() => next.dispose())\n }, { immediate: true })\n watch(() => !!toValue(documentFocused), focused => inspector.value.setDocumentFocused(focused))\n\n return {\n inspector,\n section: computed(() => state.value.section),\n editable: computed(() => state.value.editable),\n draft: computed(() => state.value.draft),\n searchTerm: computed(() => state.value.searchTerm),\n tagItems: computed(() => state.value.tagItems),\n kindOptions: computed(() => state.value.kindOptions),\n summarized: computed(() => state.value.summarized),\n hasSummary: computed(() => state.value.hasSummary),\n rows: computed(() => state.value.rows),\n tags: computed(() => state.value.tags),\n kinds: computed(() => state.value.kinds),\n mentions: computed(() => state.value.mentions),\n focused: computed(() => state.value.focused),\n properties: computed(() => state.value.properties),\n derivation: computed(() => state.value.derivation),\n }\n}\n"],"mappings":";;;;;;;;;;AAqCA,SAAgB,sBAAsB,QAA8C,iBAAgF;CAClK,MAAM,YAAY,WAAW,yBAAyB,KAAA,CAAS,CAAC;CAChE,MAAM,QAAQ,kBAAkB,UAAU,MAAM,KAAK;CAErD,YAAY,QAAQ,MAAM,IAAI,UAAU,WAAW,cAAc;EAC/D,MAAM,OAAO,yBAAyB,QAAQ;EAC9C,KAAK,mBAAmB,CAAC,CAAC,QAAQ,eAAe,CAAC;EAClD,UAAU,QAAQ;EAClB,gBAAgB,KAAK,QAAQ,CAAC;CAChC,GAAG,EAAE,WAAW,KAAK,CAAC;CACtB,YAAY,CAAC,CAAC,QAAQ,eAAe,IAAG,YAAW,UAAU,MAAM,mBAAmB,OAAO,CAAC;CAE9F,OAAO;EACL;EACA,SAAS,eAAe,MAAM,MAAM,OAAO;EAC3C,UAAU,eAAe,MAAM,MAAM,QAAQ;EAC7C,OAAO,eAAe,MAAM,MAAM,KAAK;EACvC,YAAY,eAAe,MAAM,MAAM,UAAU;EACjD,UAAU,eAAe,MAAM,MAAM,QAAQ;EAC7C,aAAa,eAAe,MAAM,MAAM,WAAW;EACnD,YAAY,eAAe,MAAM,MAAM,UAAU;EACjD,YAAY,eAAe,MAAM,MAAM,UAAU;EACjD,MAAM,eAAe,MAAM,MAAM,IAAI;EACrC,MAAM,eAAe,MAAM,MAAM,IAAI;EACrC,OAAO,eAAe,MAAM,MAAM,KAAK;EACvC,UAAU,eAAe,MAAM,MAAM,QAAQ;EAC7C,SAAS,eAAe,MAAM,MAAM,OAAO;EAC3C,YAAY,eAAe,MAAM,MAAM,UAAU;EACjD,YAAY,eAAe,MAAM,MAAM,UAAU;CACnD;AACF"}
@@ -1,5 +1,5 @@
1
1
  import { CompositeMention, CompositeRow } from "./rows.js";
2
- import { CompositeKindCount } from "./rows-model.js";
2
+ import { BlockTypeCount } from "./rows-model.js";
3
3
  import { Editor } from "@tiptap/core";
4
4
  import { ComputedRef, MaybeRefOrGetter } from "vue";
5
5
  //#region src/features/composites/use-composite-rows.d.ts
@@ -10,7 +10,7 @@ export interface CompositeRowsModel {
10
10
  /** Distinct tags of all composites, sorted (German collation). */
11
11
  tags: ComputedRef<readonly string[]>;
12
12
  /** Kinds in use with their counts: configured kinds in their configured order, then unknown ones in order of appearance. */
13
- kinds: ComputedRef<readonly CompositeKindCount[]>;
13
+ kinds: ComputedRef<readonly BlockTypeCount[]>;
14
14
  /** Distinct `@mention` chips of the document. */
15
15
  mentions: ComputedRef<readonly CompositeMention[]>;
16
16
  /** The innermost composite around the selection head, `null` outside of any. */
@@ -1 +1 @@
1
- {"version":3,"file":"use-composite-rows.js","names":[],"sources":["../../../src/features/composites/use-composite-rows.ts"],"sourcesContent":["import type { Editor } from '@tiptap/core'\nimport { computed, type ComputedRef, type MaybeRefOrGetter, shallowRef, toValue, watch } from 'vue'\nimport { useStoreRef } from '../../vue/store-ref'\nimport type { CompositeMention, CompositeRow } from './rows'\nimport { type CompositeKindCount, createCompositeRows } from './rows-model'\n\n/** The live metadata read model of an editor's document as Vue refs (see `useCompositeRows`). */\nexport interface CompositeRowsModel {\n /** Every composite in document order. */\n rows: ComputedRef<readonly CompositeRow[]>\n /** Distinct tags of all composites, sorted (German collation). */\n tags: ComputedRef<readonly string[]>\n /** Kinds in use with their counts: configured kinds in their configured order, then unknown ones in order of appearance. */\n kinds: ComputedRef<readonly CompositeKindCount[]>\n /** Distinct `@mention` chips of the document. */\n mentions: ComputedRef<readonly CompositeMention[]>\n /** The innermost composite around the selection head, `null` outside of any. */\n focused: ComputedRef<CompositeRow | null>\n}\n\n/**\n * The composites of `editor`'s document as rows, kept current (see `createCompositeRows`). Follows the editor when the\n * source changes; a missing editor yields empty lists. Use the `setComposite*` helpers to write.\n */\nexport function useCompositeRows(editor: MaybeRefOrGetter<Editor | undefined>): CompositeRowsModel {\n const model = shallowRef(createCompositeRows(undefined))\n const state = useStoreRef(() => model.value.state)\n\n watch(() => toValue(editor), (instance, _previous, onCleanup) => {\n const next = createCompositeRows(instance)\n model.value = next\n onCleanup(() => next.dispose())\n }, { immediate: true })\n\n return {\n rows: computed(() => state.value.rows),\n tags: computed(() => state.value.tags),\n kinds: computed(() => state.value.kinds),\n mentions: computed(() => state.value.mentions),\n focused: computed(() => state.value.focused),\n }\n}\n"],"mappings":";;;;;;;;AAwBA,SAAgB,iBAAiB,QAAkE;CACjG,MAAM,QAAQ,WAAW,oBAAoB,KAAA,CAAS,CAAC;CACvD,MAAM,QAAQ,kBAAkB,MAAM,MAAM,KAAK;CAEjD,YAAY,QAAQ,MAAM,IAAI,UAAU,WAAW,cAAc;EAC/D,MAAM,OAAO,oBAAoB,QAAQ;EACzC,MAAM,QAAQ;EACd,gBAAgB,KAAK,QAAQ,CAAC;CAChC,GAAG,EAAE,WAAW,KAAK,CAAC;CAEtB,OAAO;EACL,MAAM,eAAe,MAAM,MAAM,IAAI;EACrC,MAAM,eAAe,MAAM,MAAM,IAAI;EACrC,OAAO,eAAe,MAAM,MAAM,KAAK;EACvC,UAAU,eAAe,MAAM,MAAM,QAAQ;EAC7C,SAAS,eAAe,MAAM,MAAM,OAAO;CAC7C;AACF"}
1
+ {"version":3,"file":"use-composite-rows.js","names":[],"sources":["../../../src/features/composites/use-composite-rows.ts"],"sourcesContent":["import type { Editor } from '@tiptap/core'\nimport { computed, type ComputedRef, type MaybeRefOrGetter, shallowRef, toValue, watch } from 'vue'\nimport { useStoreRef } from '../../vue/store-ref'\nimport type { CompositeMention, CompositeRow } from './rows'\nimport { type BlockTypeCount, createCompositeRows } from './rows-model'\n\n/** The live metadata read model of an editor's document as Vue refs (see `useCompositeRows`). */\nexport interface CompositeRowsModel {\n /** Every composite in document order. */\n rows: ComputedRef<readonly CompositeRow[]>\n /** Distinct tags of all composites, sorted (German collation). */\n tags: ComputedRef<readonly string[]>\n /** Kinds in use with their counts: configured kinds in their configured order, then unknown ones in order of appearance. */\n kinds: ComputedRef<readonly BlockTypeCount[]>\n /** Distinct `@mention` chips of the document. */\n mentions: ComputedRef<readonly CompositeMention[]>\n /** The innermost composite around the selection head, `null` outside of any. */\n focused: ComputedRef<CompositeRow | null>\n}\n\n/**\n * The composites of `editor`'s document as rows, kept current (see `createCompositeRows`). Follows the editor when the\n * source changes; a missing editor yields empty lists. Use the `setComposite*` helpers to write.\n */\nexport function useCompositeRows(editor: MaybeRefOrGetter<Editor | undefined>): CompositeRowsModel {\n const model = shallowRef(createCompositeRows(undefined))\n const state = useStoreRef(() => model.value.state)\n\n watch(() => toValue(editor), (instance, _previous, onCleanup) => {\n const next = createCompositeRows(instance)\n model.value = next\n onCleanup(() => next.dispose())\n }, { immediate: true })\n\n return {\n rows: computed(() => state.value.rows),\n tags: computed(() => state.value.tags),\n kinds: computed(() => state.value.kinds),\n mentions: computed(() => state.value.mentions),\n focused: computed(() => state.value.focused),\n }\n}\n"],"mappings":";;;;;;;;AAwBA,SAAgB,iBAAiB,QAAkE;CACjG,MAAM,QAAQ,WAAW,oBAAoB,KAAA,CAAS,CAAC;CACvD,MAAM,QAAQ,kBAAkB,MAAM,MAAM,KAAK;CAEjD,YAAY,QAAQ,MAAM,IAAI,UAAU,WAAW,cAAc;EAC/D,MAAM,OAAO,oBAAoB,QAAQ;EACzC,MAAM,QAAQ;EACd,gBAAgB,KAAK,QAAQ,CAAC;CAChC,GAAG,EAAE,WAAW,KAAK,CAAC;CAEtB,OAAO;EACL,MAAM,eAAe,MAAM,MAAM,IAAI;EACrC,MAAM,eAAe,MAAM,MAAM,IAAI;EACrC,OAAO,eAAe,MAAM,MAAM,KAAK;EACvC,UAAU,eAAe,MAAM,MAAM,QAAQ;EAC7C,SAAS,eAAe,MAAM,MAAM,OAAO;CAC7C;AACF"}
@@ -25,7 +25,7 @@ function compositeFeature(options = {}) {
25
25
  focusChip: _sfc_main$9,
26
26
  settingsTab: _sfc_main$11,
27
27
  nodeViews: {
28
- composite: VueNodeViewRenderer(_sfc_main$8),
28
+ typedBlock: VueNodeViewRenderer(_sfc_main$8),
29
29
  reference: VueNodeViewRenderer(_sfc_main$10)
30
30
  }
31
31
  }, options);
@@ -1 +1 @@
1
- {"version":3,"file":"vue.js","names":["CompositeChrome","FocusChip","SettingsEditingTab","CompositeView","ReferenceView"],"sources":["../../../src/features/composites/vue.ts"],"sourcesContent":["import { VueNodeViewRenderer } from '@tiptap/vue-3'\nimport type { Component } from 'vue'\nimport type { VueFeature } from '../../vue'\nimport CompositeChrome from './components/CompositeChrome.vue'\nimport CompositeView from './components/CompositeView.vue'\nimport FocusChip from './components/FocusChip.vue'\nimport ReferenceView from './components/ReferenceView.vue'\nimport SettingsEditingTab from './components/SettingsEditingTab.vue'\nimport { type CompositeFeatureOptions, compositeFeatureCore } from './feature'\n\nexport { default as CompositeChrome } from './components/CompositeChrome.vue'\nexport { default as CompositeDetails } from './components/CompositeDetails.vue'\nexport { default as CompositeFieldEditor } from './components/CompositeFieldEditor.vue'\nexport { default as CompositeInspector } from './components/CompositeInspector.vue'\nexport { default as CompositeStatusMenu } from './components/CompositeStatusMenu.vue'\nexport { default as CompositeSummaryEditor } from './components/CompositeSummaryEditor.vue'\nexport { default as CompositeTable } from './components/CompositeTable.vue'\nexport { default as CompositeTagsEditor } from './components/CompositeTagsEditor.vue'\nexport { default as CompositeView } from './components/CompositeView.vue'\nexport { default as FocusChip } from './components/FocusChip.vue'\nexport { default as ReferenceView } from './components/ReferenceView.vue'\nexport { default as SettingsEditingTab } from './components/SettingsEditingTab.vue'\nexport { useCompositeAnchors } from './use-composite-anchors'\nexport { type CompositeRowsModel, useCompositeRows } from './use-composite-rows'\n\n/**\n * The Vue composites feature (Nuxt UI): see `compositeFeatureCore`. The host places `CompositeTable` and\n * `CompositeInspector` beside the editor.\n */\nexport function compositeFeature(options: CompositeFeatureOptions = {}): VueFeature {\n return compositeFeatureCore<Component>({\n chrome: CompositeChrome,\n focusChip: FocusChip,\n settingsTab: SettingsEditingTab,\n nodeViews: { composite: VueNodeViewRenderer(CompositeView), reference: VueNodeViewRenderer(ReferenceView) },\n }, options)\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;AA6BA,SAAgB,iBAAiB,UAAmC,CAAC,GAAe;CAClF,OAAO,qBAAgC;EACrC,QAAQA;EACR,WAAWC;EACX,aAAaC;EACb,WAAW;GAAE,WAAW,oBAAoBC,WAAa;GAAG,WAAW,oBAAoBC,YAAa;EAAE;CAC5G,GAAG,OAAO;AACZ"}
1
+ {"version":3,"file":"vue.js","names":["CompositeChrome","FocusChip","SettingsEditingTab","CompositeView","ReferenceView"],"sources":["../../../src/features/composites/vue.ts"],"sourcesContent":["import { VueNodeViewRenderer } from '@tiptap/vue-3'\nimport type { Component } from 'vue'\nimport type { VueFeature } from '../../vue'\nimport CompositeChrome from './components/CompositeChrome.vue'\nimport CompositeView from './components/CompositeView.vue'\nimport FocusChip from './components/FocusChip.vue'\nimport ReferenceView from './components/ReferenceView.vue'\nimport SettingsEditingTab from './components/SettingsEditingTab.vue'\nimport { type CompositeFeatureOptions, compositeFeatureCore } from './feature'\n\nexport { default as CompositeChrome } from './components/CompositeChrome.vue'\nexport { default as CompositeDetails } from './components/CompositeDetails.vue'\nexport { default as CompositeFieldEditor } from './components/CompositeFieldEditor.vue'\nexport { default as CompositeInspector } from './components/CompositeInspector.vue'\nexport { default as CompositeStatusMenu } from './components/CompositeStatusMenu.vue'\nexport { default as CompositeSummaryEditor } from './components/CompositeSummaryEditor.vue'\nexport { default as CompositeTable } from './components/CompositeTable.vue'\nexport { default as CompositeTagsEditor } from './components/CompositeTagsEditor.vue'\nexport { default as CompositeView } from './components/CompositeView.vue'\nexport { default as FocusChip } from './components/FocusChip.vue'\nexport { default as ReferenceView } from './components/ReferenceView.vue'\nexport { default as SettingsEditingTab } from './components/SettingsEditingTab.vue'\nexport { useCompositeAnchors } from './use-composite-anchors'\nexport { type CompositeRowsModel, useCompositeRows } from './use-composite-rows'\n\n/**\n * The Vue composites feature (Nuxt UI): see `compositeFeatureCore`. The host places `CompositeTable` and\n * `CompositeInspector` beside the editor.\n */\nexport function compositeFeature(options: CompositeFeatureOptions = {}): VueFeature {\n return compositeFeatureCore<Component>({\n chrome: CompositeChrome,\n focusChip: FocusChip,\n settingsTab: SettingsEditingTab,\n nodeViews: { typedBlock: VueNodeViewRenderer(CompositeView), reference: VueNodeViewRenderer(ReferenceView) },\n }, options)\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;AA6BA,SAAgB,iBAAiB,UAAmC,CAAC,GAAe;CAClF,OAAO,qBAAgC;EACrC,QAAQA;EACR,WAAWC;EACX,aAAaC;EACb,WAAW;GAAE,YAAY,oBAAoBC,WAAa;GAAG,WAAW,oBAAoBC,YAAa;EAAE;CAC7G,GAAG,OAAO;AACZ"}
@@ -56,7 +56,7 @@ const _hoisted_24 = {
56
56
  class: "text-sm text-[var(--sk-muted)]"
57
57
  };
58
58
  /**
59
- * The Bild-Studio: description and Prompt-Bausteine on the left, references and previous generations in the middle,
59
+ * The Bild-Studio: description and prompt blocks on the left, references and previous generations in the middle,
60
60
  * the block's image and the chat on the right. The dialog applies the reducers of `../state` to `store.state` and
61
61
  * hands every result to `store.update`; the store only generates, uploads and persists (see `ImageStudioStore`).
62
62
  *
@@ -1 +1 @@
1
- {"version":3,"file":"ImageStudioDialog.js","names":["_openBlock","_createBlock","_unref","_withCtx","_createElementVNode","_createCommentVNode","_toDisplayString","_createVNode","_createElementBlock","_Fragment","_renderList","_withModifiers","ImageStudioTile","ImageStudioChat"],"sources":["../../../../src/features/image-studio/components/ImageStudioDialog.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed, onBeforeUnmount, ref, useId, useTemplateRef, watch } from 'vue'\nimport { fetchErrorMessage } from '../../../core'\nimport { useUiKit } from '../../../vue/kit/use-ui-kit'\nimport { useEditorI18n } from '../../../vue/use-editor-i18n'\nimport {\n addGeneration,\n addReference,\n type ImageStudioState,\n type ImageStudioTurn,\n removeImage,\n select,\n selectedImage,\n setDescription,\n toggleImage,\n togglePromptBlock,\n} from '../state'\nimport type { ImageStudioStore } from '../store'\nimport ImageStudioChat from './ImageStudioChat.vue'\nimport ImageStudioTile from './ImageStudioTile.vue'\n\n/**\n * The Bild-Studio: description and Prompt-Bausteine on the left, references and previous generations in the middle,\n * the block's image and the chat on the right. The dialog applies the reducers of `../state` to `store.state` and\n * hands every result to `store.update`; the store only generates, uploads and persists (see `ImageStudioStore`).\n *\n * The description is committed 500 ms after the last keystroke and at once on blur, on „Erzeugen“ and on close, so the\n * host never builds a prompt from a stale text. Closing (or unmounting) aborts a running generation; an aborted\n * generation adds no turn, a failed one adds a turn with the problem.\n */\nconst props = defineProps<{ open: boolean, store: ImageStudioStore, title?: string }>()\nconst emit = defineEmits<{ 'update:open': [open: boolean] }>()\n\nconst { Alert: UAlert, Button: UButton, Modal: UModal, Switch: USwitch, Textarea: UTextarea } = useUiKit()\nconst { t } = useEditorI18n()\n\nconst uid = useId()\nconst state = computed(() => props.store.state.value)\nconst promptBlocks = computed(() => props.store.promptBlocks.value)\nconst problem = computed(() => props.store.problem.value)\nconst images = computed(() => [...state.value.generations, ...state.value.references])\nconst picture = computed(() => selectedImage(state.value))\n\n// --- Description ----------------------------------------------------------------------------------------------------\n\nconst COMMIT_DELAY_MS = 500\nconst draft = ref(state.value.description)\n/** The description as last committed or received: the host's echo of our own commit must not overwrite a newer draft. */\nlet known = state.value.description\nlet commitTimer: ReturnType<typeof setTimeout> | undefined\n\nfunction commitDescription() {\n clearTimeout(commitTimer)\n commitTimer = undefined\n if (draft.value === props.store.state.value.description) return\n known = draft.value\n props.store.update(setDescription(props.store.state.value, draft.value))\n}\n\nwatch(draft, (text) => {\n if (text === props.store.state.value.description) return\n clearTimeout(commitTimer)\n commitTimer = setTimeout(commitDescription, COMMIT_DELAY_MS)\n})\n// A change of the host (undo, another tab) shows unless the user has typed something that is not committed yet.\nwatch(() => state.value.description, (description) => {\n if (description === known) return\n known = description\n if (commitTimer === undefined) draft.value = description\n})\n\n// --- Reducers -------------------------------------------------------------------------------------------------------\n\nconst update = (next: ImageStudioState) => props.store.update(next)\nconst toggleBlock = (id: string) => update(togglePromptBlock(props.store.state.value, id))\nconst toggle = (id: string) => update(toggleImage(props.store.state.value, id))\nconst use = (id: string) => update(select(props.store.state.value, id))\nconst remove = (id: string) => update(removeImage(props.store.state.value, id))\n\n// --- References: upload and drop ------------------------------------------------------------------------------------\n\nconst fileInputRef = useTemplateRef<HTMLInputElement>('fileInput')\nconst uploading = ref(0)\nconst uploadProblem = ref<string>()\nconst dragging = ref(false)\n\nasync function upload(files: readonly File[]) {\n const pictures = files.filter(file => file.type.startsWith('image/'))\n if (!pictures.length) return\n uploadProblem.value = undefined\n uploading.value += pictures.length\n await Promise.all(pictures.map(async (file) => {\n try {\n const image = await props.store.upload(file)\n update(addReference(props.store.state.value, image))\n } catch (error) {\n uploadProblem.value = t('imageStudio.dialog.references.failed', { message: fetchErrorMessage(error) })\n } finally {\n uploading.value -= 1\n }\n }))\n}\n\nfunction onFilesChosen(event: Event) {\n const input = event.target as HTMLInputElement\n const files = [...(input.files ?? [])]\n input.value = '' // the same file can be chosen again\n void upload(files)\n}\n\nfunction onDrop(event: DragEvent) {\n dragging.value = false\n void upload([...(event.dataTransfer?.files ?? [])])\n}\n\n// --- Generation -----------------------------------------------------------------------------------------------------\n\nconst running = ref(false)\nlet controller: AbortController | undefined\n\nfunction abortGeneration() {\n controller?.abort()\n controller = undefined\n running.value = false\n}\n\nasync function generate(instruction: string) {\n if (controller) return\n commitDescription()\n const own = new AbortController()\n controller = own\n running.value = true\n const turn: ImageStudioTurn = { id: crypto.randomUUID(), instruction, imageId: null, createdAt: new Date().toISOString() }\n try {\n const image = await props.store.generate(instruction, own.signal)\n if (own.signal.aborted) return\n props.store.update(addGeneration(props.store.state.value, image, turn))\n } catch (error) {\n if (own.signal.aborted) return\n const current = props.store.state.value\n props.store.update({ ...current, turns: [...current.turns, { ...turn, problem: fetchErrorMessage(error) }] })\n } finally {\n if (controller === own) {\n controller = undefined\n running.value = false\n }\n }\n}\n\n// --- Closing --------------------------------------------------------------------------------------------------------\n\nfunction close() {\n commitDescription()\n abortGeneration()\n emit('update:open', false)\n}\n\nwatch(() => props.open, (open) => {\n if (open) return\n commitDescription()\n abortGeneration()\n})\n\nonBeforeUnmount(() => {\n commitDescription()\n abortGeneration()\n})\n</script>\n\n<template>\n <UModal\n :open=\"open\"\n :title=\"title ?? t('imageStudio.dialog.title')\"\n :ui=\"{ content: 'sm:w-[72rem] sm:max-w-[calc(100vw-2rem)]' }\"\n @update:open=\"(value: boolean) => { if (!value) close() }\"\n >\n <template #body>\n <div class=\"flex flex-col gap-3\" data-image-studio-dialog>\n <UAlert v-if=\"problem\" color=\"error\" variant=\"subtle\" :title=\"problem\" />\n <div class=\"grid gap-4 lg:h-[68vh] lg:grid-cols-[17rem_minmax(0,1fr)_minmax(0,22rem)]\">\n <!-- Left: what the picture shows. -->\n <section class=\"flex min-h-0 flex-col gap-3 lg:overflow-y-auto\" :aria-labelledby=\"`${uid}-description`\">\n <h3 :id=\"`${uid}-description`\" class=\"text-sm font-medium text-[var(--sk-fg-highlighted)]\">\n {{ t('imageStudio.dialog.description.heading') }}\n </h3>\n <UTextarea\n v-model=\"draft\"\n :rows=\"6\"\n :maxrows=\"14\"\n autoresize\n :placeholder=\"t('imageStudio.dialog.description.placeholder')\"\n :aria-label=\"t('imageStudio.dialog.description.heading')\"\n @blur=\"commitDescription\"\n />\n <h3 :id=\"`${uid}-blocks`\" class=\"mt-2 text-sm font-medium text-[var(--sk-fg-highlighted)]\">\n {{ t('imageStudio.dialog.blocks.heading') }}\n </h3>\n <ul v-if=\"promptBlocks.length\" class=\"flex flex-col gap-3\" :aria-labelledby=\"`${uid}-blocks`\">\n <li v-for=\"block in promptBlocks\" :key=\"block.id\">\n <USwitch\n :model-value=\"state.promptBlockIds.includes(block.id)\"\n :label=\"block.label\"\n :description=\"block.text\"\n @update:model-value=\"toggleBlock(block.id)\"\n />\n </li>\n </ul>\n <p v-else class=\"text-sm text-[var(--sk-muted)]\">\n {{ t('imageStudio.dialog.blocks.empty') }}\n </p>\n </section>\n\n <!-- Middle: references and previous generations. -->\n <div class=\"flex min-h-0 flex-col gap-4 lg:overflow-y-auto\">\n <section\n class=\"flex flex-col gap-2 rounded-md border border-dashed border-transparent p-1 data-[dragging=true]:border-[var(--sk-primary)]\"\n :data-dragging=\"dragging\"\n :aria-labelledby=\"`${uid}-references`\"\n data-image-studio-drop\n @dragenter.prevent=\"dragging = true\"\n @dragover.prevent=\"dragging = true\"\n @dragleave=\"dragging = false\"\n @drop.prevent=\"onDrop\"\n >\n <div class=\"flex items-center justify-between gap-2\">\n <h3 :id=\"`${uid}-references`\" class=\"text-sm font-medium text-[var(--sk-fg-highlighted)]\">\n {{ t('imageStudio.dialog.references.heading') }}\n </h3>\n <UButton\n :label=\"t('imageStudio.dialog.references.upload')\"\n icon=\"i-lucide-upload\"\n size=\"xs\"\n color=\"neutral\"\n variant=\"outline\"\n :loading=\"uploading > 0\"\n @click=\"fileInputRef?.click()\"\n />\n <input ref=\"fileInput\" type=\"file\" accept=\"image/*\" multiple hidden data-image-studio-file @change=\"onFilesChosen\">\n </div>\n <p v-if=\"uploading\" class=\"text-xs text-[var(--sk-muted)]\" role=\"status\">\n {{ t('imageStudio.dialog.references.uploading') }}\n </p>\n <UAlert v-if=\"uploadProblem\" color=\"error\" variant=\"subtle\" :title=\"uploadProblem\" />\n <ul v-if=\"state.references.length\" class=\"grid grid-cols-2 gap-2 sm:grid-cols-3\">\n <ImageStudioTile\n v-for=\"image in state.references\"\n :key=\"image.id\"\n :image=\"image\"\n :selected=\"state.selected === image.id\"\n @toggle=\"toggle(image.id)\"\n @select=\"use(image.id)\"\n @remove=\"remove(image.id)\"\n />\n </ul>\n <p v-else class=\"text-sm text-[var(--sk-muted)]\">\n {{ t('imageStudio.dialog.references.drop') }}\n </p>\n </section>\n\n <section class=\"flex flex-col gap-2 p-1\" :aria-labelledby=\"`${uid}-generations`\">\n <h3 :id=\"`${uid}-generations`\" class=\"text-sm font-medium text-[var(--sk-fg-highlighted)]\">\n {{ t('imageStudio.dialog.generations.heading') }}\n </h3>\n <ul v-if=\"state.generations.length\" class=\"grid grid-cols-2 gap-2 sm:grid-cols-3\">\n <ImageStudioTile\n v-for=\"image in state.generations\"\n :key=\"image.id\"\n :image=\"image\"\n :selected=\"state.selected === image.id\"\n @toggle=\"toggle(image.id)\"\n @select=\"use(image.id)\"\n @remove=\"remove(image.id)\"\n />\n </ul>\n <p v-else class=\"text-sm text-[var(--sk-muted)]\">\n {{ t('imageStudio.dialog.generations.empty') }}\n </p>\n </section>\n </div>\n\n <!-- Right: the block's image and the chat. -->\n <div class=\"flex min-h-0 flex-col gap-3\">\n <section class=\"flex flex-col gap-2\" :aria-labelledby=\"`${uid}-preview`\">\n <h3 :id=\"`${uid}-preview`\" class=\"text-sm font-medium text-[var(--sk-fg-highlighted)]\">\n {{ t('imageStudio.dialog.preview.heading') }}\n </h3>\n <div class=\"flex aspect-square items-center justify-center overflow-hidden rounded-md border border-[var(--sk-border)] bg-[var(--sk-bg-elevated)]\">\n <img\n v-if=\"picture\"\n :src=\"picture.url\"\n :alt=\"picture.title || t('imageStudio.dialog.tile.untitled')\"\n class=\"size-full object-contain\"\n data-image-studio-preview\n >\n <p v-else class=\"text-sm text-[var(--sk-muted)]\">\n {{ t('imageStudio.dialog.preview.empty') }}\n </p>\n </div>\n </section>\n <ImageStudioChat\n :turns=\"state.turns\"\n :images=\"images\"\n :running=\"running\"\n :empty-allowed=\"draft.trim() !== ''\"\n @send=\"generate\"\n />\n </div>\n </div>\n </div>\n </template>\n </UModal>\n</template>\n"],"mappings":"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"}
1
+ {"version":3,"file":"ImageStudioDialog.js","names":["_openBlock","_createBlock","_unref","_withCtx","_createElementVNode","_createCommentVNode","_toDisplayString","_createVNode","_createElementBlock","_Fragment","_renderList","_withModifiers","ImageStudioTile","ImageStudioChat"],"sources":["../../../../src/features/image-studio/components/ImageStudioDialog.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed, onBeforeUnmount, ref, useId, useTemplateRef, watch } from 'vue'\nimport { fetchErrorMessage } from '../../../core'\nimport { useUiKit } from '../../../vue/kit/use-ui-kit'\nimport { useEditorI18n } from '../../../vue/use-editor-i18n'\nimport {\n addGeneration,\n addReference,\n type ImageStudioState,\n type ImageStudioTurn,\n removeImage,\n select,\n selectedImage,\n setDescription,\n toggleImage,\n togglePromptBlock,\n} from '../state'\nimport type { ImageStudioStore } from '../store'\nimport ImageStudioChat from './ImageStudioChat.vue'\nimport ImageStudioTile from './ImageStudioTile.vue'\n\n/**\n * The Bild-Studio: description and prompt blocks on the left, references and previous generations in the middle,\n * the block's image and the chat on the right. The dialog applies the reducers of `../state` to `store.state` and\n * hands every result to `store.update`; the store only generates, uploads and persists (see `ImageStudioStore`).\n *\n * The description is committed 500 ms after the last keystroke and at once on blur, on „Erzeugen“ and on close, so the\n * host never builds a prompt from a stale text. Closing (or unmounting) aborts a running generation; an aborted\n * generation adds no turn, a failed one adds a turn with the problem.\n */\nconst props = defineProps<{ open: boolean, store: ImageStudioStore, title?: string }>()\nconst emit = defineEmits<{ 'update:open': [open: boolean] }>()\n\nconst { Alert: UAlert, Button: UButton, Modal: UModal, Switch: USwitch, Textarea: UTextarea } = useUiKit()\nconst { t } = useEditorI18n()\n\nconst uid = useId()\nconst state = computed(() => props.store.state.value)\nconst promptBlocks = computed(() => props.store.promptBlocks.value)\nconst problem = computed(() => props.store.problem.value)\nconst images = computed(() => [...state.value.generations, ...state.value.references])\nconst picture = computed(() => selectedImage(state.value))\n\n// --- Description ----------------------------------------------------------------------------------------------------\n\nconst COMMIT_DELAY_MS = 500\nconst draft = ref(state.value.description)\n/** The description as last committed or received: the host's echo of our own commit must not overwrite a newer draft. */\nlet known = state.value.description\nlet commitTimer: ReturnType<typeof setTimeout> | undefined\n\nfunction commitDescription() {\n clearTimeout(commitTimer)\n commitTimer = undefined\n if (draft.value === props.store.state.value.description) return\n known = draft.value\n props.store.update(setDescription(props.store.state.value, draft.value))\n}\n\nwatch(draft, (text) => {\n if (text === props.store.state.value.description) return\n clearTimeout(commitTimer)\n commitTimer = setTimeout(commitDescription, COMMIT_DELAY_MS)\n})\n// A change of the host (undo, another tab) shows unless the user has typed something that is not committed yet.\nwatch(() => state.value.description, (description) => {\n if (description === known) return\n known = description\n if (commitTimer === undefined) draft.value = description\n})\n\n// --- Reducers -------------------------------------------------------------------------------------------------------\n\nconst update = (next: ImageStudioState) => props.store.update(next)\nconst toggleBlock = (id: string) => update(togglePromptBlock(props.store.state.value, id))\nconst toggle = (id: string) => update(toggleImage(props.store.state.value, id))\nconst use = (id: string) => update(select(props.store.state.value, id))\nconst remove = (id: string) => update(removeImage(props.store.state.value, id))\n\n// --- References: upload and drop ------------------------------------------------------------------------------------\n\nconst fileInputRef = useTemplateRef<HTMLInputElement>('fileInput')\nconst uploading = ref(0)\nconst uploadProblem = ref<string>()\nconst dragging = ref(false)\n\nasync function upload(files: readonly File[]) {\n const pictures = files.filter(file => file.type.startsWith('image/'))\n if (!pictures.length) return\n uploadProblem.value = undefined\n uploading.value += pictures.length\n await Promise.all(pictures.map(async (file) => {\n try {\n const image = await props.store.upload(file)\n update(addReference(props.store.state.value, image))\n } catch (error) {\n uploadProblem.value = t('imageStudio.dialog.references.failed', { message: fetchErrorMessage(error) })\n } finally {\n uploading.value -= 1\n }\n }))\n}\n\nfunction onFilesChosen(event: Event) {\n const input = event.target as HTMLInputElement\n const files = [...(input.files ?? [])]\n input.value = '' // the same file can be chosen again\n void upload(files)\n}\n\nfunction onDrop(event: DragEvent) {\n dragging.value = false\n void upload([...(event.dataTransfer?.files ?? [])])\n}\n\n// --- Generation -----------------------------------------------------------------------------------------------------\n\nconst running = ref(false)\nlet controller: AbortController | undefined\n\nfunction abortGeneration() {\n controller?.abort()\n controller = undefined\n running.value = false\n}\n\nasync function generate(instruction: string) {\n if (controller) return\n commitDescription()\n const own = new AbortController()\n controller = own\n running.value = true\n const turn: ImageStudioTurn = { id: crypto.randomUUID(), instruction, imageId: null, createdAt: new Date().toISOString() }\n try {\n const image = await props.store.generate(instruction, own.signal)\n if (own.signal.aborted) return\n props.store.update(addGeneration(props.store.state.value, image, turn))\n } catch (error) {\n if (own.signal.aborted) return\n const current = props.store.state.value\n props.store.update({ ...current, turns: [...current.turns, { ...turn, problem: fetchErrorMessage(error) }] })\n } finally {\n if (controller === own) {\n controller = undefined\n running.value = false\n }\n }\n}\n\n// --- Closing --------------------------------------------------------------------------------------------------------\n\nfunction close() {\n commitDescription()\n abortGeneration()\n emit('update:open', false)\n}\n\nwatch(() => props.open, (open) => {\n if (open) return\n commitDescription()\n abortGeneration()\n})\n\nonBeforeUnmount(() => {\n commitDescription()\n abortGeneration()\n})\n</script>\n\n<template>\n <UModal\n :open=\"open\"\n :title=\"title ?? t('imageStudio.dialog.title')\"\n :ui=\"{ content: 'sm:w-[72rem] sm:max-w-[calc(100vw-2rem)]' }\"\n @update:open=\"(value: boolean) => { if (!value) close() }\"\n >\n <template #body>\n <div class=\"flex flex-col gap-3\" data-image-studio-dialog>\n <UAlert v-if=\"problem\" color=\"error\" variant=\"subtle\" :title=\"problem\" />\n <div class=\"grid gap-4 lg:h-[68vh] lg:grid-cols-[17rem_minmax(0,1fr)_minmax(0,22rem)]\">\n <!-- Left: what the picture shows. -->\n <section class=\"flex min-h-0 flex-col gap-3 lg:overflow-y-auto\" :aria-labelledby=\"`${uid}-description`\">\n <h3 :id=\"`${uid}-description`\" class=\"text-sm font-medium text-[var(--sk-fg-highlighted)]\">\n {{ t('imageStudio.dialog.description.heading') }}\n </h3>\n <UTextarea\n v-model=\"draft\"\n :rows=\"6\"\n :maxrows=\"14\"\n autoresize\n :placeholder=\"t('imageStudio.dialog.description.placeholder')\"\n :aria-label=\"t('imageStudio.dialog.description.heading')\"\n @blur=\"commitDescription\"\n />\n <h3 :id=\"`${uid}-blocks`\" class=\"mt-2 text-sm font-medium text-[var(--sk-fg-highlighted)]\">\n {{ t('imageStudio.dialog.blocks.heading') }}\n </h3>\n <ul v-if=\"promptBlocks.length\" class=\"flex flex-col gap-3\" :aria-labelledby=\"`${uid}-blocks`\">\n <li v-for=\"block in promptBlocks\" :key=\"block.id\">\n <USwitch\n :model-value=\"state.promptBlockIds.includes(block.id)\"\n :label=\"block.label\"\n :description=\"block.text\"\n @update:model-value=\"toggleBlock(block.id)\"\n />\n </li>\n </ul>\n <p v-else class=\"text-sm text-[var(--sk-muted)]\">\n {{ t('imageStudio.dialog.blocks.empty') }}\n </p>\n </section>\n\n <!-- Middle: references and previous generations. -->\n <div class=\"flex min-h-0 flex-col gap-4 lg:overflow-y-auto\">\n <section\n class=\"flex flex-col gap-2 rounded-md border border-dashed border-transparent p-1 data-[dragging=true]:border-[var(--sk-primary)]\"\n :data-dragging=\"dragging\"\n :aria-labelledby=\"`${uid}-references`\"\n data-image-studio-drop\n @dragenter.prevent=\"dragging = true\"\n @dragover.prevent=\"dragging = true\"\n @dragleave=\"dragging = false\"\n @drop.prevent=\"onDrop\"\n >\n <div class=\"flex items-center justify-between gap-2\">\n <h3 :id=\"`${uid}-references`\" class=\"text-sm font-medium text-[var(--sk-fg-highlighted)]\">\n {{ t('imageStudio.dialog.references.heading') }}\n </h3>\n <UButton\n :label=\"t('imageStudio.dialog.references.upload')\"\n icon=\"i-lucide-upload\"\n size=\"xs\"\n color=\"neutral\"\n variant=\"outline\"\n :loading=\"uploading > 0\"\n @click=\"fileInputRef?.click()\"\n />\n <input ref=\"fileInput\" type=\"file\" accept=\"image/*\" multiple hidden data-image-studio-file @change=\"onFilesChosen\">\n </div>\n <p v-if=\"uploading\" class=\"text-xs text-[var(--sk-muted)]\" role=\"status\">\n {{ t('imageStudio.dialog.references.uploading') }}\n </p>\n <UAlert v-if=\"uploadProblem\" color=\"error\" variant=\"subtle\" :title=\"uploadProblem\" />\n <ul v-if=\"state.references.length\" class=\"grid grid-cols-2 gap-2 sm:grid-cols-3\">\n <ImageStudioTile\n v-for=\"image in state.references\"\n :key=\"image.id\"\n :image=\"image\"\n :selected=\"state.selected === image.id\"\n @toggle=\"toggle(image.id)\"\n @select=\"use(image.id)\"\n @remove=\"remove(image.id)\"\n />\n </ul>\n <p v-else class=\"text-sm text-[var(--sk-muted)]\">\n {{ t('imageStudio.dialog.references.drop') }}\n </p>\n </section>\n\n <section class=\"flex flex-col gap-2 p-1\" :aria-labelledby=\"`${uid}-generations`\">\n <h3 :id=\"`${uid}-generations`\" class=\"text-sm font-medium text-[var(--sk-fg-highlighted)]\">\n {{ t('imageStudio.dialog.generations.heading') }}\n </h3>\n <ul v-if=\"state.generations.length\" class=\"grid grid-cols-2 gap-2 sm:grid-cols-3\">\n <ImageStudioTile\n v-for=\"image in state.generations\"\n :key=\"image.id\"\n :image=\"image\"\n :selected=\"state.selected === image.id\"\n @toggle=\"toggle(image.id)\"\n @select=\"use(image.id)\"\n @remove=\"remove(image.id)\"\n />\n </ul>\n <p v-else class=\"text-sm text-[var(--sk-muted)]\">\n {{ t('imageStudio.dialog.generations.empty') }}\n </p>\n </section>\n </div>\n\n <!-- Right: the block's image and the chat. -->\n <div class=\"flex min-h-0 flex-col gap-3\">\n <section class=\"flex flex-col gap-2\" :aria-labelledby=\"`${uid}-preview`\">\n <h3 :id=\"`${uid}-preview`\" class=\"text-sm font-medium text-[var(--sk-fg-highlighted)]\">\n {{ t('imageStudio.dialog.preview.heading') }}\n </h3>\n <div class=\"flex aspect-square items-center justify-center overflow-hidden rounded-md border border-[var(--sk-border)] bg-[var(--sk-bg-elevated)]\">\n <img\n v-if=\"picture\"\n :src=\"picture.url\"\n :alt=\"picture.title || t('imageStudio.dialog.tile.untitled')\"\n class=\"size-full object-contain\"\n data-image-studio-preview\n >\n <p v-else class=\"text-sm text-[var(--sk-muted)]\">\n {{ t('imageStudio.dialog.preview.empty') }}\n </p>\n </div>\n </section>\n <ImageStudioChat\n :turns=\"state.turns\"\n :images=\"images\"\n :running=\"running\"\n :empty-allowed=\"draft.trim() !== ''\"\n @send=\"generate\"\n />\n </div>\n </div>\n </div>\n </template>\n </UModal>\n</template>\n"],"mappings":"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"}