@ecsplico/editor 2.1.2 → 3.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 (692) hide show
  1. package/CHANGELOG.md +68 -1
  2. package/README.md +39 -156
  3. package/dist/adapters/comments/drizzle.d.ts +1 -1
  4. package/dist/adapters/comments/{client.js → rest-model.js} +3 -3
  5. package/dist/adapters/comments/rest-model.js.map +1 -0
  6. package/dist/adapters/comments/types.d.ts +2 -2
  7. package/dist/adapters/document-state.d.ts +23 -0
  8. package/dist/adapters/document-state.js +66 -0
  9. package/dist/adapters/document-state.js.map +1 -0
  10. package/dist/adapters/documents.js +14 -11
  11. package/dist/adapters/documents.js.map +1 -1
  12. package/dist/adapters/drizzle.d.ts +2 -2
  13. package/dist/adapters/drizzle.js +97 -88
  14. package/dist/adapters/drizzle.js.map +1 -1
  15. package/dist/adapters/forge.d.ts +12 -7
  16. package/dist/adapters/forge.js +38 -45
  17. package/dist/adapters/forge.js.map +1 -1
  18. package/dist/adapters/http.d.ts +20 -0
  19. package/dist/adapters/http.js +68 -0
  20. package/dist/adapters/http.js.map +1 -0
  21. package/dist/adapters/index.d.ts +5 -5
  22. package/dist/adapters/json.d.ts +3 -3
  23. package/dist/adapters/json.js +58 -49
  24. package/dist/adapters/json.js.map +1 -1
  25. package/dist/adapters/memory.d.ts +21 -0
  26. package/dist/adapters/memory.js +53 -0
  27. package/dist/adapters/memory.js.map +1 -0
  28. package/dist/adapters/nitro.d.ts +23 -20
  29. package/dist/adapters/nitro.js +58 -163
  30. package/dist/adapters/nitro.js.map +1 -1
  31. package/dist/adapters/react.d.ts +55 -0
  32. package/dist/adapters/react.js +209 -0
  33. package/dist/adapters/react.js.map +1 -0
  34. package/dist/adapters/shared.d.ts +15 -21
  35. package/dist/adapters/shared.js +10 -8
  36. package/dist/adapters/shared.js.map +1 -1
  37. package/dist/adapters/vue.d.ts +15 -30
  38. package/dist/adapters/vue.js +36 -87
  39. package/dist/adapters/vue.js.map +1 -1
  40. package/dist/config/index.d.ts +105 -0
  41. package/dist/config/index.js +95 -0
  42. package/dist/config/index.js.map +1 -0
  43. package/dist/core/abilities.js +1 -0
  44. package/dist/core/abilities.js.map +1 -1
  45. package/dist/{adapters/routes.js → core/api-routes.js} +5 -3
  46. package/dist/core/api-routes.js.map +1 -0
  47. package/dist/core/backend-capability.d.ts +7 -0
  48. package/dist/core/backend-capability.js +17 -0
  49. package/dist/core/backend-capability.js.map +1 -0
  50. package/dist/core/backend-types.d.ts +245 -0
  51. package/dist/core/backend-types.js +17 -0
  52. package/dist/core/backend-types.js.map +1 -0
  53. package/dist/core/backend.d.ts +108 -0
  54. package/dist/core/backend.js +14 -0
  55. package/dist/core/backend.js.map +1 -0
  56. package/dist/core/block-convert.d.ts +7 -5
  57. package/dist/core/block-convert.js +28 -5
  58. package/dist/core/block-convert.js.map +1 -1
  59. package/dist/core/command-types.d.ts +89 -0
  60. package/dist/core/commands.d.ts +40 -0
  61. package/dist/core/commands.js +151 -0
  62. package/dist/core/commands.js.map +1 -0
  63. package/dist/core/context.d.ts +17 -20
  64. package/dist/core/context.js +24 -21
  65. package/dist/core/context.js.map +1 -1
  66. package/dist/core/core-feature.d.ts +22 -7
  67. package/dist/core/core-feature.js +51 -18
  68. package/dist/core/core-feature.js.map +1 -1
  69. package/dist/core/define-editor.d.ts +4 -3
  70. package/dist/core/define-editor.js +14 -7
  71. package/dist/core/define-editor.js.map +1 -1
  72. package/dist/core/document-markdown.js +12 -3
  73. package/dist/core/document-markdown.js.map +1 -1
  74. package/dist/core/editor-ui.d.ts +8 -1
  75. package/dist/core/editor-ui.js +9 -8
  76. package/dist/core/editor-ui.js.map +1 -1
  77. package/dist/core/extension-points.d.ts +3 -15
  78. package/dist/core/feature-context.d.ts +8 -7
  79. package/dist/core/feature-context.js +12 -11
  80. package/dist/core/feature-context.js.map +1 -1
  81. package/dist/core/feature.d.ts +35 -19
  82. package/dist/core/feature.js.map +1 -1
  83. package/dist/core/fences.d.ts +2 -1
  84. package/dist/core/fences.js +3 -2
  85. package/dist/core/fences.js.map +1 -1
  86. package/dist/core/fetch-error.d.ts +1 -1
  87. package/dist/core/fetch-error.js +3 -1
  88. package/dist/core/fetch-error.js.map +1 -1
  89. package/dist/core/hash.d.ts +5 -0
  90. package/dist/core/hash.js +11 -0
  91. package/dist/core/hash.js.map +1 -0
  92. package/dist/core/http-backend.d.ts +11 -0
  93. package/dist/core/http-backend.js +195 -0
  94. package/dist/core/http-backend.js.map +1 -0
  95. package/dist/core/index.d.ts +14 -9
  96. package/dist/core/index.js +12 -9
  97. package/dist/core/palette.d.ts +48 -0
  98. package/dist/core/palette.js +95 -0
  99. package/dist/core/palette.js.map +1 -0
  100. package/dist/core/schema/abilities.d.ts +2 -1
  101. package/dist/core/schema/abilities.js +5 -1
  102. package/dist/core/schema/abilities.js.map +1 -1
  103. package/dist/core/schema/index.d.ts +11 -5
  104. package/dist/core/schema/index.js +13 -8
  105. package/dist/core/schema/index.js.map +1 -1
  106. package/dist/core/schema/mark-flags.d.ts +8 -1
  107. package/dist/core/schema/of-features.d.ts +13 -0
  108. package/dist/core/schema/of-features.js +14 -0
  109. package/dist/core/schema/of-features.js.map +1 -0
  110. package/dist/core/slash.d.ts +8 -6
  111. package/dist/core/slash.js +24 -16
  112. package/dist/core/slash.js.map +1 -1
  113. package/dist/core/surface-session.js +13 -5
  114. package/dist/core/surface-session.js.map +1 -1
  115. package/dist/core/toolbar-items.d.ts +10 -4
  116. package/dist/core/toolbar-items.js +269 -195
  117. package/dist/core/toolbar-items.js.map +1 -1
  118. package/dist/core/util.js +11 -0
  119. package/dist/core/util.js.map +1 -0
  120. package/dist/document/DocumentSurface.d.ts +1 -1
  121. package/dist/features/ai/agent-op-review.d.ts +1 -1
  122. package/dist/features/ai/agent-op-review.js +1 -1
  123. package/dist/features/ai/agent-ops.js +1 -1
  124. package/dist/features/ai/ai-apply.d.ts +2 -2
  125. package/dist/features/ai/ai-apply.js +1 -1
  126. package/dist/features/ai/ai-review.js +1 -1
  127. package/dist/features/ai/ai-sse.d.ts +6 -6
  128. package/dist/features/ai/ai-sse.js +20 -63
  129. package/dist/features/ai/ai-sse.js.map +1 -1
  130. package/dist/features/ai/assistant.d.ts +8 -7
  131. package/dist/features/ai/assistant.js +3 -3
  132. package/dist/features/ai/assistant.js.map +1 -1
  133. package/dist/features/ai/block-actions.d.ts +3 -2
  134. package/dist/features/ai/block-actions.js +3 -2
  135. package/dist/features/ai/block-actions.js.map +1 -1
  136. package/dist/features/ai/components/AiSelectionMenu.js +1 -1
  137. package/dist/features/ai/components/DocumentChatAnswer.js +1 -1
  138. package/dist/features/ai/components/DocumentChatOps.vue.d.ts +1 -1
  139. package/dist/features/ai/components/SettingsModelProfiles.js +8 -8
  140. package/dist/features/ai/components/SettingsModelProfiles.js.map +1 -1
  141. package/dist/features/ai/document-chat-model.d.ts +8 -7
  142. package/dist/features/ai/document-chat-model.js +5 -5
  143. package/dist/features/ai/document-chat-model.js.map +1 -1
  144. package/dist/features/ai/document-chat.js +1 -1
  145. package/dist/features/ai/feature.js +27 -14
  146. package/dist/features/ai/feature.js.map +1 -1
  147. package/dist/features/ai/ghost-autocomplete.d.ts +7 -6
  148. package/dist/features/ai/ghost-autocomplete.js +6 -9
  149. package/dist/features/ai/ghost-autocomplete.js.map +1 -1
  150. package/dist/features/ai/index.d.ts +4 -3
  151. package/dist/features/ai/index.js +10 -10
  152. package/dist/features/ai/model-profiles.d.ts +5 -4
  153. package/dist/features/ai/model-profiles.js +2 -2
  154. package/dist/features/ai/model-profiles.js.map +1 -1
  155. package/dist/features/ai/protocol/block-lines.js +1 -1
  156. package/dist/features/ai/protocol/block-lines.js.map +1 -1
  157. package/dist/features/ai/protocol/chat.js +4 -1
  158. package/dist/features/ai/protocol/chat.js.map +1 -1
  159. package/dist/features/ai/protocol/index.d.ts +3 -2
  160. package/dist/features/ai/protocol/models.d.ts +2 -16
  161. package/dist/features/ai/protocol/models.js.map +1 -1
  162. package/dist/features/ai/rate-limit.d.ts +1 -1
  163. package/dist/features/ai/rate-limit.js +3 -1
  164. package/dist/features/ai/rate-limit.js.map +1 -1
  165. package/dist/features/ai/react/AiSelectionMenu.js +2 -2
  166. package/dist/features/ai/react/AiSidebar.js +4 -4
  167. package/dist/features/ai/react/DocumentChatAnswer.js +1 -1
  168. package/dist/features/ai/react/DocumentChatOps.d.ts +1 -1
  169. package/dist/features/ai/react/DocumentChatOps.js +1 -1
  170. package/dist/features/ai/react/SettingsModelProfiles.js +8 -10
  171. package/dist/features/ai/react/SettingsModelProfiles.js.map +1 -1
  172. package/dist/features/ai/react/use-ai-assistant.d.ts +1 -1
  173. package/dist/features/ai/react/use-ai-assistant.js +3 -3
  174. package/dist/features/ai/react/use-ai-assistant.js.map +1 -1
  175. package/dist/features/ai/react/use-document-chat.js +2 -2
  176. package/dist/features/ai/react/use-document-chat.js.map +1 -1
  177. package/dist/features/ai/react/use-model-profiles.d.ts +2 -1
  178. package/dist/features/ai/selection-flow.d.ts +1 -1
  179. package/dist/features/ai/selection-flow.js +1 -1
  180. package/dist/features/ai/sidebar-flow.d.ts +1 -1
  181. package/dist/features/ai/sidebar-flow.js +1 -1
  182. package/dist/features/ai/use-ai-assistant.d.ts +1 -1
  183. package/dist/features/ai/use-ai-assistant.js +3 -3
  184. package/dist/features/ai/use-ai-assistant.js.map +1 -1
  185. package/dist/features/ai/use-document-chat.js +2 -2
  186. package/dist/features/ai/use-document-chat.js.map +1 -1
  187. package/dist/features/ai/use-model-profiles.d.ts +2 -1
  188. package/dist/features/authors/attribution.d.ts +1 -1
  189. package/dist/features/authors/feature.js +12 -11
  190. package/dist/features/authors/feature.js.map +1 -1
  191. package/dist/features/block-ui/block-actions.d.ts +1 -1
  192. package/dist/features/block-ui/block-actions.js +1 -1
  193. package/dist/features/block-ui/block-actions.js.map +1 -1
  194. package/dist/features/block-ui/components/BlockUi.js +1 -1
  195. package/dist/features/block-ui/feature.js +1 -0
  196. package/dist/features/block-ui/feature.js.map +1 -1
  197. package/dist/features/block-ui/react/BlockUi.js +1 -1
  198. package/dist/features/collab/anchor-resolver.js +1 -1
  199. package/dist/features/collab/feature.js +2 -0
  200. package/dist/features/collab/feature.js.map +1 -1
  201. package/dist/features/comments/components/CommentThreadView.vue.d.ts +2 -1
  202. package/dist/features/comments/feature.js +12 -11
  203. package/dist/features/comments/feature.js.map +1 -1
  204. package/dist/features/comments/index.d.ts +3 -2
  205. package/dist/features/comments/index.js +1 -1
  206. package/dist/features/comments/margin-layout.d.ts +3 -2
  207. package/dist/features/comments/model.d.ts +3 -67
  208. package/dist/features/comments/model.js +2 -2
  209. package/dist/features/comments/model.js.map +1 -1
  210. package/dist/features/comments/react/CommentThreadView.d.ts +3 -2
  211. package/dist/features/comments/react/use-comments.d.ts +2 -1
  212. package/dist/features/comments/react.d.ts +1 -1
  213. package/dist/features/comments/schema.d.ts +2 -52
  214. package/dist/features/comments/schema.js.map +1 -1
  215. package/dist/features/comments/snapshot-equality.js.map +1 -1
  216. package/dist/features/comments/use-comments.d.ts +3 -2
  217. package/dist/features/comments/vue.d.ts +1 -1
  218. package/dist/features/composites/accepted-children.d.ts +1 -0
  219. package/dist/features/composites/accepted-children.js +16 -1
  220. package/dist/features/composites/accepted-children.js.map +1 -1
  221. package/dist/features/composites/ai-brief.js +31 -0
  222. package/dist/features/composites/ai-brief.js.map +1 -1
  223. package/dist/features/composites/bibliography-command.d.ts +11 -0
  224. package/dist/features/composites/bibliography-form.js +90 -0
  225. package/dist/features/composites/bibliography-form.js.map +1 -0
  226. package/dist/features/composites/bibliography.d.ts +33 -0
  227. package/dist/features/composites/bibliography.js +120 -0
  228. package/dist/features/composites/bibliography.js.map +1 -0
  229. package/dist/features/composites/components/BibliographyEditor.js +261 -0
  230. package/dist/features/composites/components/BibliographyEditor.js.map +1 -0
  231. package/dist/features/composites/components/CompositeChrome.js +75 -26
  232. package/dist/features/composites/components/CompositeChrome.js.map +1 -1
  233. package/dist/features/composites/components/CompositeDetails.js +46 -11
  234. package/dist/features/composites/components/CompositeDetails.js.map +1 -1
  235. package/dist/features/composites/components/CompositeDetails.vue.d.ts +2 -1
  236. package/dist/features/composites/components/CompositeFieldEditor.js +37 -4
  237. package/dist/features/composites/components/CompositeFieldEditor.js.map +1 -1
  238. package/dist/features/composites/components/CompositeInspector.js +17 -5
  239. package/dist/features/composites/components/CompositeInspector.js.map +1 -1
  240. package/dist/features/composites/components/CompositeTable.js +13 -4
  241. package/dist/features/composites/components/CompositeTable.js.map +1 -1
  242. package/dist/features/composites/components/CompositeTagsEditor.js +1 -1
  243. package/dist/features/composites/components/CompositeView.js +11 -1
  244. package/dist/features/composites/components/CompositeView.js.map +1 -1
  245. package/dist/features/composites/components/DerivationBadge.js +103 -0
  246. package/dist/features/composites/components/DerivationBadge.js.map +1 -0
  247. package/dist/features/composites/components/ReferenceFieldSelect.js +60 -0
  248. package/dist/features/composites/components/ReferenceFieldSelect.js.map +1 -0
  249. package/dist/features/composites/components/ReferenceView.js +122 -0
  250. package/dist/features/composites/components/ReferenceView.js.map +1 -0
  251. package/dist/features/composites/components/ReferenceView.vue.d.ts +96 -0
  252. package/dist/features/composites/components/SettingsEditingTab.js +1 -1
  253. package/dist/features/composites/convert.js +2 -2
  254. package/dist/features/composites/convert.js.map +1 -1
  255. package/dist/features/composites/derivation.d.ts +61 -0
  256. package/dist/features/composites/derivation.js +98 -0
  257. package/dist/features/composites/derivation.js.map +1 -0
  258. package/dist/features/composites/derived-chrome.js +69 -0
  259. package/dist/features/composites/derived-chrome.js.map +1 -0
  260. package/dist/features/composites/feature.js +159 -109
  261. package/dist/features/composites/feature.js.map +1 -1
  262. package/dist/features/composites/fences.d.ts +4 -3
  263. package/dist/features/composites/fences.js +51 -7
  264. package/dist/features/composites/fences.js.map +1 -1
  265. package/dist/features/composites/index.d.ts +12 -3
  266. package/dist/features/composites/index.js +15 -6
  267. package/dist/features/composites/inspector-model.d.ts +4 -1
  268. package/dist/features/composites/inspector-model.js +8 -4
  269. package/dist/features/composites/inspector-model.js.map +1 -1
  270. package/dist/features/composites/kinds.d.ts +8 -1
  271. package/dist/features/composites/kinds.js +145 -6
  272. package/dist/features/composites/kinds.js.map +1 -1
  273. package/dist/features/composites/legacy.d.ts +4 -1
  274. package/dist/features/composites/legacy.js +56 -1
  275. package/dist/features/composites/legacy.js.map +1 -1
  276. package/dist/features/composites/meta-display.js +40 -1
  277. package/dist/features/composites/meta-display.js.map +1 -1
  278. package/dist/features/composites/meta-keys.d.ts +7 -0
  279. package/dist/features/composites/meta-keys.js +21 -0
  280. package/dist/features/composites/meta-keys.js.map +1 -0
  281. package/dist/features/composites/node-views.d.ts +6 -3
  282. package/dist/features/composites/node-views.js +7 -3
  283. package/dist/features/composites/node-views.js.map +1 -1
  284. package/dist/features/composites/nodes.d.ts +6 -1
  285. package/dist/features/composites/nodes.js +33 -7
  286. package/dist/features/composites/nodes.js.map +1 -1
  287. package/dist/features/composites/react/BibliographyEditor.js +229 -0
  288. package/dist/features/composites/react/BibliographyEditor.js.map +1 -0
  289. package/dist/features/composites/react/CompositeChrome.js +65 -17
  290. package/dist/features/composites/react/CompositeChrome.js.map +1 -1
  291. package/dist/features/composites/react/CompositeDetails.d.ts +2 -1
  292. package/dist/features/composites/react/CompositeDetails.js +45 -6
  293. package/dist/features/composites/react/CompositeDetails.js.map +1 -1
  294. package/dist/features/composites/react/CompositeFieldEditor.d.ts +1 -1
  295. package/dist/features/composites/react/CompositeFieldEditor.js +24 -1
  296. package/dist/features/composites/react/CompositeFieldEditor.js.map +1 -1
  297. package/dist/features/composites/react/CompositeInspector.js +11 -5
  298. package/dist/features/composites/react/CompositeInspector.js.map +1 -1
  299. package/dist/features/composites/react/CompositeStatusMenu.js +1 -1
  300. package/dist/features/composites/react/CompositeSummaryEditor.js +1 -1
  301. package/dist/features/composites/react/CompositeTable.js +16 -2
  302. package/dist/features/composites/react/CompositeTable.js.map +1 -1
  303. package/dist/features/composites/react/CompositeTagsEditor.js +2 -2
  304. package/dist/features/composites/react/CompositeView.js +6 -1
  305. package/dist/features/composites/react/CompositeView.js.map +1 -1
  306. package/dist/features/composites/react/DerivationBadge.js +116 -0
  307. package/dist/features/composites/react/DerivationBadge.js.map +1 -0
  308. package/dist/features/composites/react/ReferenceFieldSelect.js +52 -0
  309. package/dist/features/composites/react/ReferenceFieldSelect.js.map +1 -0
  310. package/dist/features/composites/react/ReferenceView.d.ts +11 -0
  311. package/dist/features/composites/react/ReferenceView.js +115 -0
  312. package/dist/features/composites/react/ReferenceView.js.map +1 -0
  313. package/dist/features/composites/react/SettingsEditingTab.js +2 -2
  314. package/dist/features/composites/react.d.ts +2 -1
  315. package/dist/features/composites/react.js +7 -3
  316. package/dist/features/composites/react.js.map +1 -1
  317. package/dist/features/composites/reference-ai.js +16 -0
  318. package/dist/features/composites/reference-ai.js.map +1 -0
  319. package/dist/features/composites/reference-label.d.ts +19 -0
  320. package/dist/features/composites/reference-label.js +58 -0
  321. package/dist/features/composites/reference-label.js.map +1 -0
  322. package/dist/features/composites/reference-suggestion.d.ts +10 -0
  323. package/dist/features/composites/reference-suggestion.js +41 -0
  324. package/dist/features/composites/reference-suggestion.js.map +1 -0
  325. package/dist/features/composites/reference-text.d.ts +18 -0
  326. package/dist/features/composites/reference-text.js +89 -0
  327. package/dist/features/composites/reference-text.js.map +1 -0
  328. package/dist/features/composites/reference.d.ts +44 -0
  329. package/dist/features/composites/reference.js +148 -0
  330. package/dist/features/composites/reference.js.map +1 -0
  331. package/dist/features/composites/reveal-source.d.ts +32 -0
  332. package/dist/features/composites/reveal-source.js +89 -0
  333. package/dist/features/composites/reveal-source.js.map +1 -0
  334. package/dist/features/composites/rows.d.ts +21 -2
  335. package/dist/features/composites/rows.js +63 -9
  336. package/dist/features/composites/rows.js.map +1 -1
  337. package/dist/features/composites/schema.d.ts +9 -3
  338. package/dist/features/composites/schema.js +11 -4
  339. package/dist/features/composites/schema.js.map +1 -1
  340. package/dist/features/composites/table-model.js +12 -21
  341. package/dist/features/composites/table-model.js.map +1 -1
  342. package/dist/features/composites/vue.d.ts +3 -2
  343. package/dist/features/composites/vue.js +8 -4
  344. package/dist/features/composites/vue.js.map +1 -1
  345. package/dist/features/media/assets.d.ts +2 -0
  346. package/dist/features/media/assets.js +3 -2
  347. package/dist/features/media/assets.js.map +1 -1
  348. package/dist/features/media/components/FileView.js +13 -4
  349. package/dist/features/media/components/FileView.js.map +1 -1
  350. package/dist/features/media/feature.d.ts +3 -3
  351. package/dist/features/media/feature.js +21 -28
  352. package/dist/features/media/feature.js.map +1 -1
  353. package/dist/features/media/file-import.js +2 -2
  354. package/dist/features/media/file-import.js.map +1 -1
  355. package/dist/features/media/index.d.ts +2 -2
  356. package/dist/features/media/index.js +2 -2
  357. package/dist/features/media/react/FileView.js +19 -2
  358. package/dist/features/media/react/FileView.js.map +1 -1
  359. package/dist/features/media/schema.d.ts +8 -0
  360. package/dist/features/media/schema.js +126 -11
  361. package/dist/features/media/schema.js.map +1 -1
  362. package/dist/features/media/upload.d.ts +16 -14
  363. package/dist/features/media/upload.js +13 -19
  364. package/dist/features/media/upload.js.map +1 -1
  365. package/dist/features/mentions/index.d.ts +4 -3
  366. package/dist/features/mentions/index.js +4 -1
  367. package/dist/features/mentions/index.js.map +1 -1
  368. package/dist/features/mentions/mention-text.d.ts +1 -1
  369. package/dist/features/mentions/mention-text.js.map +1 -1
  370. package/dist/features/mentions/mention.d.ts +0 -6
  371. package/dist/features/mentions/mention.js.map +1 -1
  372. package/dist/features/mentions/metadata-defaults.d.ts +2 -2
  373. package/dist/features/mentions/metadata-defaults.js +3 -9
  374. package/dist/features/mentions/metadata-defaults.js.map +1 -1
  375. package/dist/features/mentions/schema.d.ts +2 -1
  376. package/dist/features/mentions/schema.js.map +1 -1
  377. package/dist/features/tables/feature.d.ts +2 -1
  378. package/dist/features/tables/feature.js +90 -70
  379. package/dist/features/tables/feature.js.map +1 -1
  380. package/dist/features/themes/components/SettingsAppearanceTab.js +6 -9
  381. package/dist/features/themes/components/SettingsAppearanceTab.js.map +1 -1
  382. package/dist/features/themes/feature.js +2 -0
  383. package/dist/features/themes/feature.js.map +1 -1
  384. package/dist/features/themes/index.d.ts +2 -1
  385. package/dist/features/themes/react/SettingsAppearanceTab.js +7 -10
  386. package/dist/features/themes/react/SettingsAppearanceTab.js.map +1 -1
  387. package/dist/features/themes/schema.d.ts +2 -6
  388. package/dist/features/themes/schema.js.map +1 -1
  389. package/dist/features/themes/theme-runtime.d.ts +1 -1
  390. package/dist/features/themes/theme-runtime.js +4 -2
  391. package/dist/features/themes/theme-runtime.js.map +1 -1
  392. package/dist/features/transcript/TranscriptSegmentView.js +48 -28
  393. package/dist/features/transcript/TranscriptSegmentView.js.map +1 -1
  394. package/dist/features/transcript/feature.js +21 -19
  395. package/dist/features/transcript/feature.js.map +1 -1
  396. package/dist/features/transcript/react/TranscriptSegmentView.js +55 -36
  397. package/dist/features/transcript/react/TranscriptSegmentView.js.map +1 -1
  398. package/dist/features/transcript/segment-node.d.ts +2 -0
  399. package/dist/features/transcript/segment-node.js +35 -7
  400. package/dist/features/transcript/segment-node.js.map +1 -1
  401. package/dist/i18n/de/composites.js +91 -1
  402. package/dist/i18n/de/composites.js.map +1 -1
  403. package/dist/i18n/de/integrations.js +49 -8
  404. package/dist/i18n/de/integrations.js.map +1 -1
  405. package/dist/i18n/de/media.js +0 -1
  406. package/dist/i18n/de/media.js.map +1 -1
  407. package/dist/i18n/de/palette.js +22 -0
  408. package/dist/i18n/de/palette.js.map +1 -0
  409. package/dist/i18n/de/tables.js +0 -1
  410. package/dist/i18n/de/tables.js.map +1 -1
  411. package/dist/i18n/de/transcript.js +2 -1
  412. package/dist/i18n/de/transcript.js.map +1 -1
  413. package/dist/i18n/de/tree.js +3 -0
  414. package/dist/i18n/de/tree.js.map +1 -1
  415. package/dist/i18n/de.d.ts +157 -11
  416. package/dist/i18n/de.js +3 -1
  417. package/dist/i18n/de.js.map +1 -1
  418. package/dist/i18n/en/composites.js +89 -1
  419. package/dist/i18n/en/composites.js.map +1 -1
  420. package/dist/i18n/en/integrations.js +49 -8
  421. package/dist/i18n/en/integrations.js.map +1 -1
  422. package/dist/i18n/en/media.js +0 -1
  423. package/dist/i18n/en/media.js.map +1 -1
  424. package/dist/i18n/en/palette.js +22 -0
  425. package/dist/i18n/en/palette.js.map +1 -0
  426. package/dist/i18n/en/tables.js +0 -1
  427. package/dist/i18n/en/tables.js.map +1 -1
  428. package/dist/i18n/en/transcript.js +2 -1
  429. package/dist/i18n/en/transcript.js.map +1 -1
  430. package/dist/i18n/en/tree.js +3 -0
  431. package/dist/i18n/en/tree.js.map +1 -1
  432. package/dist/i18n/en.js +3 -1
  433. package/dist/i18n/en.js.map +1 -1
  434. package/dist/index.d.ts +4 -3
  435. package/dist/integrations/composite-ai/bibliography-fetch.d.ts +31 -0
  436. package/dist/integrations/composite-ai/bibliography-fetch.js +159 -0
  437. package/dist/integrations/composite-ai/bibliography-fetch.js.map +1 -0
  438. package/dist/integrations/composite-ai/composite-fill.d.ts +30 -8
  439. package/dist/integrations/composite-ai/composite-fill.js +97 -56
  440. package/dist/integrations/composite-ai/composite-fill.js.map +1 -1
  441. package/dist/integrations/composite-ai/composite-summary.d.ts +4 -12
  442. package/dist/integrations/composite-ai/composite-summary.js +7 -26
  443. package/dist/integrations/composite-ai/composite-summary.js.map +1 -1
  444. package/dist/integrations/composite-ai/derive.d.ts +29 -0
  445. package/dist/integrations/composite-ai/derive.js +173 -0
  446. package/dist/integrations/composite-ai/derive.js.map +1 -0
  447. package/dist/integrations/composite-ai/index.d.ts +11 -7
  448. package/dist/integrations/composite-ai/index.js +72 -14
  449. package/dist/integrations/composite-ai/index.js.map +1 -1
  450. package/dist/integrations/composite-ai/rendition.d.ts +45 -0
  451. package/dist/integrations/composite-ai/rendition.js +314 -0
  452. package/dist/integrations/composite-ai/rendition.js.map +1 -0
  453. package/dist/integrations/composite-media/index.d.ts +7 -5
  454. package/dist/integrations/composite-media/index.js +86 -13
  455. package/dist/integrations/composite-media/index.js.map +1 -1
  456. package/dist/integrations/transcript-ai/index.d.ts +1 -1
  457. package/dist/integrations/transcript-ai/index.js +5 -2
  458. package/dist/integrations/transcript-ai/index.js.map +1 -1
  459. package/dist/integrations/transcript-ai/protocol.d.ts +2 -12
  460. package/dist/integrations/transcript-ai/protocol.js +0 -2
  461. package/dist/integrations/transcript-ai/protocol.js.map +1 -1
  462. package/dist/integrations/transcript-ai/transcript-cleanup.d.ts +5 -5
  463. package/dist/integrations/transcript-ai/transcript-cleanup.js +7 -10
  464. package/dist/integrations/transcript-ai/transcript-cleanup.js.map +1 -1
  465. package/dist/markdown/MarkdownSurface.vue.d.ts +6 -5
  466. package/dist/markdown/MarkdownSurface2.js +3 -6
  467. package/dist/markdown/MarkdownSurface2.js.map +1 -1
  468. package/dist/markdown/document.js +1 -1
  469. package/dist/markdown/source-mode.d.ts +1 -1
  470. package/dist/nuxt/module.d.ts +1402 -54
  471. package/dist/nuxt/module.js +6 -49
  472. package/dist/nuxt/module.js.map +1 -1
  473. package/dist/nuxt/runtime/install-context.d.ts +7 -3
  474. package/dist/nuxt/runtime/install-context.js +14 -8
  475. package/dist/nuxt/runtime/install-context.js.map +1 -1
  476. package/dist/nuxt/runtime/plugins/editor-context-nuxt-ui.client.ts +2 -2
  477. package/dist/nuxt/runtime/server/plugins/editor-server.js +20 -12
  478. package/dist/nuxt/runtime/server/plugins/editor-server.js.map +1 -1
  479. package/dist/presets/compose.d.ts +94 -0
  480. package/dist/presets/compose.js +164 -0
  481. package/dist/presets/compose.js.map +1 -0
  482. package/dist/react/AdvancedEditor.d.ts +15 -15
  483. package/dist/react/AdvancedEditor.js +15 -13
  484. package/dist/react/AdvancedEditor.js.map +1 -1
  485. package/dist/react/EditorCommandPalette.d.ts +13 -0
  486. package/dist/react/EditorCommandPalette.js +118 -0
  487. package/dist/react/EditorCommandPalette.js.map +1 -0
  488. package/dist/react/EditorSettingsModal.d.ts +5 -5
  489. package/dist/react/EditorSettingsModal.js +7 -4
  490. package/dist/react/EditorSettingsModal.js.map +1 -1
  491. package/dist/react/EditorSettingsPanel.d.ts +7 -7
  492. package/dist/react/EditorSettingsPanel.js +8 -5
  493. package/dist/react/EditorSettingsPanel.js.map +1 -1
  494. package/dist/react/EditorSurface.d.ts +7 -7
  495. package/dist/react/EditorSurface.js +10 -6
  496. package/dist/react/EditorSurface.js.map +1 -1
  497. package/dist/react/EditorToolbar.d.ts +4 -6
  498. package/dist/react/EditorToolbar.js +29 -37
  499. package/dist/react/EditorToolbar.js.map +1 -1
  500. package/dist/react/SimpleEditor.d.ts +22 -23
  501. package/dist/react/SimpleEditor.js +21 -7
  502. package/dist/react/SimpleEditor.js.map +1 -1
  503. package/dist/react/advanced.d.ts +4 -3
  504. package/dist/react/advanced.js +2 -2
  505. package/dist/react/compose.d.ts +20 -0
  506. package/dist/react/compose.js +49 -0
  507. package/dist/react/compose.js.map +1 -0
  508. package/dist/react/composed-surface.d.ts +39 -0
  509. package/dist/react/composed-surface.js +71 -0
  510. package/dist/react/composed-surface.js.map +1 -0
  511. package/dist/react/context.js +6 -2
  512. package/dist/react/context.js.map +1 -1
  513. package/dist/react/index.d.ts +2 -1
  514. package/dist/react/index.js +2 -1
  515. package/dist/react/key-labels.js +15 -0
  516. package/dist/react/key-labels.js.map +1 -0
  517. package/dist/react/settings.d.ts +1 -1
  518. package/dist/react/simple.d.ts +2 -2
  519. package/dist/react/ui/command.js +36 -1
  520. package/dist/react/ui/command.js.map +1 -1
  521. package/dist/schema/advanced.d.ts +6 -6
  522. package/dist/schema/advanced.js +26 -29
  523. package/dist/schema/advanced.js.map +1 -1
  524. package/dist/server/ai.d.ts +5 -16
  525. package/dist/server/ai.js.map +1 -1
  526. package/dist/server/auth.d.ts +9 -0
  527. package/dist/server/collab-state.d.ts +1 -1
  528. package/dist/server/collab-state.js.map +1 -1
  529. package/dist/server/collab.d.ts +13 -13
  530. package/dist/server/collab.js +34 -18
  531. package/dist/server/collab.js.map +1 -1
  532. package/dist/server/crossref.js +78 -0
  533. package/dist/server/crossref.js.map +1 -0
  534. package/dist/server/errors.d.ts +1 -1
  535. package/dist/server/errors.js +1 -1
  536. package/dist/server/errors.js.map +1 -1
  537. package/dist/server/extract.js +308 -0
  538. package/dist/server/extract.js.map +1 -0
  539. package/dist/{nuxt/runtime/server/utils/editor-route.js → server/h3.js} +8 -16
  540. package/dist/server/h3.js.map +1 -0
  541. package/dist/server/handlers/ai.d.ts +30 -9
  542. package/dist/server/handlers/ai.js +170 -36
  543. package/dist/server/handlers/ai.js.map +1 -1
  544. package/dist/server/handlers/context.d.ts +12 -5
  545. package/dist/server/handlers/context.js +10 -4
  546. package/dist/server/handlers/context.js.map +1 -1
  547. package/dist/server/handlers/editor.d.ts +19 -13
  548. package/dist/server/handlers/editor.js +49 -38
  549. package/dist/server/handlers/editor.js.map +1 -1
  550. package/dist/server/handlers/index.d.ts +4 -4
  551. package/dist/server/handlers/index.js +4 -4
  552. package/dist/server/host.d.ts +16 -25
  553. package/dist/server/host.js +58 -41
  554. package/dist/server/host.js.map +1 -1
  555. package/dist/server/index.d.ts +6 -4
  556. package/dist/server/index.js +3 -2
  557. package/dist/server/pdf.js +97 -0
  558. package/dist/server/pdf.js.map +1 -0
  559. package/dist/server/{adapter.d.ts → ports.d.ts} +81 -30
  560. package/dist/server/ports.js +29 -0
  561. package/dist/server/ports.js.map +1 -0
  562. package/dist/server/routes.js +144 -0
  563. package/dist/server/routes.js.map +1 -0
  564. package/dist/settings/index.d.ts +1 -1
  565. package/dist/settings/index.js.map +1 -1
  566. package/dist/styles/composites.css +25 -0
  567. package/dist/tree/DocumentTree.js +56 -29
  568. package/dist/tree/DocumentTree.js.map +1 -1
  569. package/dist/tree/react/DocumentTree.js +23 -0
  570. package/dist/tree/react/DocumentTree.js.map +1 -1
  571. package/dist/tree/tree-host.js +2 -2
  572. package/dist/tree/tree-items.js +1 -1
  573. package/dist/vue/AdvancedEditor.js +30 -9
  574. package/dist/vue/AdvancedEditor.js.map +1 -1
  575. package/dist/vue/AdvancedEditor.vue.d.ts +28 -8
  576. package/dist/vue/SimpleEditor.js +62 -16
  577. package/dist/vue/SimpleEditor.js.map +1 -1
  578. package/dist/vue/SimpleEditor.vue.d.ts +37 -7
  579. package/dist/vue/advanced.d.ts +3 -2
  580. package/dist/vue/advanced.js +2 -2
  581. package/dist/vue/components/EditorCommandPalette.js +91 -0
  582. package/dist/vue/components/EditorCommandPalette.js.map +1 -0
  583. package/dist/vue/components/EditorCommandPalette.vue.d.ts +15 -0
  584. package/dist/vue/components/EditorSettingsModal.js +10 -6
  585. package/dist/vue/components/EditorSettingsModal.js.map +1 -1
  586. package/dist/vue/components/EditorSettingsModal.vue.d.ts +4 -4
  587. package/dist/vue/components/EditorSettingsPanel.js +10 -6
  588. package/dist/vue/components/EditorSettingsPanel.js.map +1 -1
  589. package/dist/vue/components/EditorSettingsPanel.vue.d.ts +6 -6
  590. package/dist/vue/components/EditorSurface.js +11 -6
  591. package/dist/vue/components/EditorSurface.js.map +1 -1
  592. package/dist/vue/components/EditorSurface.vue.d.ts +7 -7
  593. package/dist/vue/components/EditorToolbar.js +41 -49
  594. package/dist/vue/components/EditorToolbar.js.map +1 -1
  595. package/dist/vue/components/EditorToolbar.vue.d.ts +2 -4
  596. package/dist/vue/compose.d.ts +17 -0
  597. package/dist/vue/compose.js +51 -0
  598. package/dist/vue/compose.js.map +1 -0
  599. package/dist/vue/context-key.d.ts +6 -0
  600. package/dist/vue/context-key.js +6 -0
  601. package/dist/vue/context-key.js.map +1 -0
  602. package/dist/vue/context.d.ts +8 -6
  603. package/dist/vue/context.js +6 -5
  604. package/dist/vue/context.js.map +1 -1
  605. package/dist/vue/index.d.ts +10 -8
  606. package/dist/vue/index.js +10 -8
  607. package/dist/vue/kit/index.d.ts +2 -2
  608. package/dist/vue/kit/nuxt-ui.js +23 -0
  609. package/dist/vue/kit/nuxt-ui.js.map +1 -1
  610. package/dist/vue/kit/types.d.ts +40 -1
  611. package/package.json +30 -16
  612. package/dist/adapters/comments/client.d.ts +0 -64
  613. package/dist/adapters/comments/client.js.map +0 -1
  614. package/dist/adapters/routes.js.map +0 -1
  615. package/dist/core/toolbar.d.ts +0 -74
  616. package/dist/core/toolbar.js +0 -45
  617. package/dist/core/toolbar.js.map +0 -1
  618. package/dist/integrations/composite-ai/document-transcribe.d.ts +0 -14
  619. package/dist/integrations/composite-ai/document-transcribe.js +0 -89
  620. package/dist/integrations/composite-ai/document-transcribe.js.map +0 -1
  621. package/dist/nuxt/runtime/server/api/ai/chat.post.d.ts +0 -5
  622. package/dist/nuxt/runtime/server/api/ai/chat.post.js +0 -8
  623. package/dist/nuxt/runtime/server/api/ai/chat.post.js.map +0 -1
  624. package/dist/nuxt/runtime/server/api/ai/complete.post.d.ts +0 -5
  625. package/dist/nuxt/runtime/server/api/ai/complete.post.js +0 -8
  626. package/dist/nuxt/runtime/server/api/ai/complete.post.js.map +0 -1
  627. package/dist/nuxt/runtime/server/api/ai/generate.post.d.ts +0 -5
  628. package/dist/nuxt/runtime/server/api/ai/generate.post.js +0 -8
  629. package/dist/nuxt/runtime/server/api/ai/generate.post.js.map +0 -1
  630. package/dist/nuxt/runtime/server/api/ai/models.get.d.ts +0 -5
  631. package/dist/nuxt/runtime/server/api/ai/models.get.js +0 -8
  632. package/dist/nuxt/runtime/server/api/ai/models.get.js.map +0 -1
  633. package/dist/nuxt/runtime/server/api/ai/transcribe.post.d.ts +0 -5
  634. package/dist/nuxt/runtime/server/api/ai/transcribe.post.js +0 -8
  635. package/dist/nuxt/runtime/server/api/ai/transcribe.post.js.map +0 -1
  636. package/dist/nuxt/runtime/server/api/ai/transcript-cleanup.post.d.ts +0 -5
  637. package/dist/nuxt/runtime/server/api/ai/transcript-cleanup.post.js +0 -8
  638. package/dist/nuxt/runtime/server/api/ai/transcript-cleanup.post.js.map +0 -1
  639. package/dist/nuxt/runtime/server/api/editor/assets/[id]/[name].get.d.ts +0 -5
  640. package/dist/nuxt/runtime/server/api/editor/assets/[id]/[name].get.js +0 -8
  641. package/dist/nuxt/runtime/server/api/editor/assets/[id]/[name].get.js.map +0 -1
  642. package/dist/nuxt/runtime/server/api/editor/assets/[id].post.d.ts +0 -5
  643. package/dist/nuxt/runtime/server/api/editor/assets/[id].post.js +0 -8
  644. package/dist/nuxt/runtime/server/api/editor/assets/[id].post.js.map +0 -1
  645. package/dist/nuxt/runtime/server/api/editor/settings.get.d.ts +0 -5
  646. package/dist/nuxt/runtime/server/api/editor/settings.get.js +0 -8
  647. package/dist/nuxt/runtime/server/api/editor/settings.get.js.map +0 -1
  648. package/dist/nuxt/runtime/server/api/editor/settings.put.d.ts +0 -5
  649. package/dist/nuxt/runtime/server/api/editor/settings.put.js +0 -8
  650. package/dist/nuxt/runtime/server/api/editor/settings.put.js.map +0 -1
  651. package/dist/nuxt/runtime/server/api/editor/tags.get.d.ts +0 -5
  652. package/dist/nuxt/runtime/server/api/editor/tags.get.js +0 -8
  653. package/dist/nuxt/runtime/server/api/editor/tags.get.js.map +0 -1
  654. package/dist/nuxt/runtime/server/api/editor/themes/[id].delete.d.ts +0 -5
  655. package/dist/nuxt/runtime/server/api/editor/themes/[id].delete.js +0 -8
  656. package/dist/nuxt/runtime/server/api/editor/themes/[id].delete.js.map +0 -1
  657. package/dist/nuxt/runtime/server/api/editor/themes/[id].get.d.ts +0 -5
  658. package/dist/nuxt/runtime/server/api/editor/themes/[id].get.js +0 -8
  659. package/dist/nuxt/runtime/server/api/editor/themes/[id].get.js.map +0 -1
  660. package/dist/nuxt/runtime/server/api/editor/themes/index.get.d.ts +0 -5
  661. package/dist/nuxt/runtime/server/api/editor/themes/index.get.js +0 -8
  662. package/dist/nuxt/runtime/server/api/editor/themes/index.get.js.map +0 -1
  663. package/dist/nuxt/runtime/server/api/editor/themes/index.post.d.ts +0 -5
  664. package/dist/nuxt/runtime/server/api/editor/themes/index.post.js +0 -8
  665. package/dist/nuxt/runtime/server/api/editor/themes/index.post.js.map +0 -1
  666. package/dist/nuxt/runtime/server/api/editor/users.get.d.ts +0 -5
  667. package/dist/nuxt/runtime/server/api/editor/users.get.js +0 -8
  668. package/dist/nuxt/runtime/server/api/editor/users.get.js.map +0 -1
  669. package/dist/nuxt/runtime/server/plugins/collab.d.ts +0 -5
  670. package/dist/nuxt/runtime/server/plugins/collab.js +0 -10
  671. package/dist/nuxt/runtime/server/plugins/collab.js.map +0 -1
  672. package/dist/nuxt/runtime/server/routes/collab/[id].d.ts +0 -5
  673. package/dist/nuxt/runtime/server/routes/collab/[id].js +0 -35
  674. package/dist/nuxt/runtime/server/routes/collab/[id].js.map +0 -1
  675. package/dist/nuxt/runtime/server/utils/editor-route.d.ts +0 -11
  676. package/dist/nuxt/runtime/server/utils/editor-route.js.map +0 -1
  677. package/dist/presets/advanced.d.ts +0 -33
  678. package/dist/presets/advanced.js +0 -50
  679. package/dist/presets/advanced.js.map +0 -1
  680. package/dist/presets/simple.d.ts +0 -9
  681. package/dist/presets/simple.js +0 -12
  682. package/dist/presets/simple.js.map +0 -1
  683. package/dist/react/advanced-preset.d.ts +0 -11
  684. package/dist/react/advanced-preset.js +0 -31
  685. package/dist/react/advanced-preset.js.map +0 -1
  686. package/dist/vue/advanced-preset.d.ts +0 -13
  687. package/dist/vue/advanced-preset.js +0 -33
  688. package/dist/vue/advanced-preset.js.map +0 -1
  689. package/docs/extending.md +0 -538
  690. package/docs/integration.md +0 -632
  691. package/docs/llms.md +0 -383
  692. package/docs/usage.md +0 -1076
@@ -1,9 +1,48 @@
1
+ import { findBlockById } from "../../core/schema/block-ids.js";
2
+ import { compositeKind } from "./kinds.js";
3
+ import { citeShort } from "./bibliography.js";
4
+ import { derivationMethodLabel } from "./derived-chrome.js";
1
5
  //#region src/features/composites/meta-display.ts
2
6
  /** The stored value of a meta field as editable text (`''` when unset). */
3
7
  function metaText(row, field) {
4
8
  const value = row.meta[field.key];
5
9
  return typeof value === "string" || typeof value === "number" ? String(value) : "";
6
10
  }
11
+ const dateFormat = new Intl.DateTimeFormat("de-DE", {
12
+ day: "2-digit",
13
+ month: "2-digit",
14
+ year: "numeric"
15
+ });
16
+ /** `2026-05-01` → `01.05.2026`; parsed by hand because `new Date('2026-05-01')` is UTC and can show the previous day. */
17
+ function formatDate(value) {
18
+ const match = /^(\d{4})-(\d{2})-(\d{2})/.exec(value);
19
+ const date = match ? new Date(Number(match[1]), Number(match[2]) - 1, Number(match[3])) : new Date(value);
20
+ return Number.isNaN(date.getTime()) ? value : dateFormat.format(date);
21
+ }
22
+ /**
23
+ * The text a field's value stands for in a table cell: `reference` the title of the Baustein it points to (its kind label
24
+ * when untitled, `''` when it is gone or `doc` is unknown), `bibliography` the short citation, `derivation`
25
+ * `method · date` (the method as words when `t` is given, else its stored id); every other type its stored text.
26
+ */
27
+ function fieldDisplay(row, field, doc, kinds, t) {
28
+ const value = row.meta[field.key];
29
+ if (field.type === "reference") {
30
+ if (typeof value !== "string" || !value || !doc) return "";
31
+ const target = findBlockById(doc, value)?.node;
32
+ if (target?.type.name !== "composite") return "";
33
+ return target.child(0).textContent.trim() || compositeKind(kinds, String(target.attrs.kind)).label;
34
+ }
35
+ if (field.type === "bibliography") {
36
+ const bib = value;
37
+ return bib && typeof bib === "object" && typeof bib.type === "string" ? citeShort(bib, row.title) : "";
38
+ }
39
+ if (field.type === "derivation") {
40
+ const derivation = value;
41
+ if (!derivation || typeof derivation !== "object" || typeof derivation.method !== "string") return "";
42
+ return [t ? derivationMethodLabel(t, derivation.method) : derivation.method, derivation.createdAt ? formatDate(derivation.createdAt) : ""].filter(Boolean).join(" · ");
43
+ }
44
+ return metaText(row, field);
45
+ }
7
46
  /** Icon and color class of the known status values; unknown values read as neutral. */
8
47
  const STATUS_STYLE = {
9
48
  open: {
@@ -41,6 +80,6 @@ function rowStatus(row, t) {
41
80
  };
42
81
  }
43
82
  //#endregion
44
- export { metaText, rowStatus, statusStyle };
83
+ export { fieldDisplay, formatDate, metaText, rowStatus, statusStyle };
45
84
 
46
85
  //# sourceMappingURL=meta-display.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"meta-display.js","names":[],"sources":["../../../src/features/composites/meta-display.ts"],"sourcesContent":["import type { Translate } from '../../i18n'\nimport type { CompositeMetaField } from './kinds'\nimport type { CompositeRow } from './rows'\n\n/** The stored value of a meta field as editable text (`''` when unset). */\nexport function metaText(row: Pick<CompositeRow, 'meta'>, field: Pick<CompositeMetaField, 'key'>): string {\n const value = row.meta[field.key]\n return typeof value === 'string' || typeof value === 'number' ? String(value) : ''\n}\n\n/** Icon and color class of the known status values; unknown values read as neutral. */\nconst STATUS_STYLE: Record<string, { icon: string, color: string }> = {\n open: { icon: 'i-lucide-circle', color: 'text-[var(--sk-muted)]' },\n doing: { icon: 'i-lucide-circle-dot', color: 'text-[var(--sk-info)]' },\n done: { icon: 'i-lucide-circle-check', color: 'text-[var(--sk-success)]' },\n}\nconst STATUS_UNSET = { icon: 'i-lucide-circle-dashed', color: 'text-[var(--sk-fg-dimmed)]' }\nconst STATUS_OTHER = { icon: 'i-lucide-circle', color: 'text-[var(--sk-muted)]' }\n\nexport const statusStyle = (value: string) => STATUS_STYLE[value] ?? (value ? STATUS_OTHER : STATUS_UNSET)\n\n/** A row's `status` field with its current value. */\nexport interface RowStatus {\n field: CompositeMetaField\n value: string\n label: string\n icon: string\n color: string\n}\n\n/** The row's `status` select field with its current value, `null` for a kind without one; `t` words an unset status. */\nexport function rowStatus(row: CompositeRow, t: Translate): RowStatus | null {\n const field = row.fields.find(candidate => candidate.key === 'status' && candidate.type === 'select')\n if (!field) return null\n const value = metaText(row, field)\n return { field, value, label: field.options?.find(option => option.value === value)?.label ?? (value || t('composites.status.none')), ...statusStyle(value) }\n}\n"],"mappings":";;AAKA,SAAgB,SAAS,KAAiC,OAAgD;CACxG,MAAM,QAAQ,IAAI,KAAK,MAAM;CAC7B,OAAO,OAAO,UAAU,YAAY,OAAO,UAAU,WAAW,OAAO,KAAK,IAAI;AAClF;;AAGA,MAAM,eAAgE;CACpE,MAAM;EAAE,MAAM;EAAmB,OAAO;CAAyB;CACjE,OAAO;EAAE,MAAM;EAAuB,OAAO;CAAwB;CACrE,MAAM;EAAE,MAAM;EAAyB,OAAO;CAA2B;AAC3E;AACA,MAAM,eAAe;CAAE,MAAM;CAA0B,OAAO;AAA6B;AAC3F,MAAM,eAAe;CAAE,MAAM;CAAmB,OAAO;AAAyB;AAEhF,MAAa,eAAe,UAAkB,aAAa,WAAW,QAAQ,eAAe;;AAY7F,SAAgB,UAAU,KAAmB,GAAgC;CAC3E,MAAM,QAAQ,IAAI,OAAO,MAAK,cAAa,UAAU,QAAQ,YAAY,UAAU,SAAS,QAAQ;CACpG,IAAI,CAAC,OAAO,OAAO;CACnB,MAAM,QAAQ,SAAS,KAAK,KAAK;CACjC,OAAO;EAAE;EAAO;EAAO,OAAO,MAAM,SAAS,MAAK,WAAU,OAAO,UAAU,KAAK,CAAC,EAAE,UAAU,SAAS,EAAE,wBAAwB;EAAI,GAAG,YAAY,KAAK;CAAE;AAC9J"}
1
+ {"version":3,"file":"meta-display.js","names":[],"sources":["../../../src/features/composites/meta-display.ts"],"sourcesContent":["import type { Node as PMNode } from '@tiptap/pm/model'\nimport { findBlockById } from '../../core/schema/block-ids'\nimport type { Translate } from '../../i18n'\nimport { type CslItem, citeShort } from './bibliography'\nimport type { Derivation } from './derivation'\nimport { derivationMethodLabel } from './derived-chrome'\nimport { type CompositeKind, type CompositeMetaField, compositeKind } from './kinds'\nimport type { CompositeRow } from './rows'\n\n/** The stored value of a meta field as editable text (`''` when unset). */\nexport function metaText(row: Pick<CompositeRow, 'meta'>, field: Pick<CompositeMetaField, 'key'>): string {\n const value = row.meta[field.key]\n return typeof value === 'string' || typeof value === 'number' ? String(value) : ''\n}\n\nconst dateFormat = new Intl.DateTimeFormat('de-DE', { day: '2-digit', month: '2-digit', year: 'numeric' })\n\n/** `2026-05-01` → `01.05.2026`; parsed by hand because `new Date('2026-05-01')` is UTC and can show the previous day. */\nexport function formatDate(value: string): string {\n const match = /^(\\d{4})-(\\d{2})-(\\d{2})/.exec(value)\n const date = match ? new Date(Number(match[1]), Number(match[2]) - 1, Number(match[3])) : new Date(value)\n return Number.isNaN(date.getTime()) ? value : dateFormat.format(date)\n}\n\n/**\n * The text a field's value stands for in a table cell: `reference` the title of the Baustein it points to (its kind label\n * when untitled, `''` when it is gone or `doc` is unknown), `bibliography` the short citation, `derivation`\n * `method · date` (the method as words when `t` is given, else its stored id); every other type its stored text.\n */\nexport function fieldDisplay(row: Pick<CompositeRow, 'meta' | 'title'>, field: Pick<CompositeMetaField, 'key' | 'type'>, doc: PMNode | null, kinds: readonly CompositeKind[], t?: Translate): string {\n const value = row.meta[field.key]\n if (field.type === 'reference') {\n if (typeof value !== 'string' || !value || !doc) return ''\n const target = findBlockById(doc, value)?.node\n if (target?.type.name !== 'composite') return ''\n return target.child(0).textContent.trim() || compositeKind(kinds, String(target.attrs.kind)).label\n }\n if (field.type === 'bibliography') {\n const bib = value as Partial<CslItem> | null | undefined\n return bib && typeof bib === 'object' && typeof bib.type === 'string' ? citeShort(bib, row.title) : ''\n }\n if (field.type === 'derivation') {\n const derivation = value as Partial<Derivation> | null | undefined\n if (!derivation || typeof derivation !== 'object' || typeof derivation.method !== 'string') return ''\n return [t ? derivationMethodLabel(t, derivation.method) : derivation.method, derivation.createdAt ? formatDate(derivation.createdAt) : ''].filter(Boolean).join(' · ')\n }\n return metaText(row, field)\n}\n\n/** Icon and color class of the known status values; unknown values read as neutral. */\nconst STATUS_STYLE: Record<string, { icon: string, color: string }> = {\n open: { icon: 'i-lucide-circle', color: 'text-[var(--sk-muted)]' },\n doing: { icon: 'i-lucide-circle-dot', color: 'text-[var(--sk-info)]' },\n done: { icon: 'i-lucide-circle-check', color: 'text-[var(--sk-success)]' },\n}\nconst STATUS_UNSET = { icon: 'i-lucide-circle-dashed', color: 'text-[var(--sk-fg-dimmed)]' }\nconst STATUS_OTHER = { icon: 'i-lucide-circle', color: 'text-[var(--sk-muted)]' }\n\nexport const statusStyle = (value: string) => STATUS_STYLE[value] ?? (value ? STATUS_OTHER : STATUS_UNSET)\n\n/** A row's `status` field with its current value. */\nexport interface RowStatus {\n field: CompositeMetaField\n value: string\n label: string\n icon: string\n color: string\n}\n\n/** The row's `status` select field with its current value, `null` for a kind without one; `t` words an unset status. */\nexport function rowStatus(row: CompositeRow, t: Translate): RowStatus | null {\n const field = row.fields.find(candidate => candidate.key === 'status' && candidate.type === 'select')\n if (!field) return null\n const value = metaText(row, field)\n return { field, value, label: field.options?.find(option => option.value === value)?.label ?? (value || t('composites.status.none')), ...statusStyle(value) }\n}\n"],"mappings":";;;;;;AAUA,SAAgB,SAAS,KAAiC,OAAgD;CACxG,MAAM,QAAQ,IAAI,KAAK,MAAM;CAC7B,OAAO,OAAO,UAAU,YAAY,OAAO,UAAU,WAAW,OAAO,KAAK,IAAI;AAClF;AAEA,MAAM,aAAa,IAAI,KAAK,eAAe,SAAS;CAAE,KAAK;CAAW,OAAO;CAAW,MAAM;AAAU,CAAC;;AAGzG,SAAgB,WAAW,OAAuB;CAChD,MAAM,QAAQ,2BAA2B,KAAK,KAAK;CACnD,MAAM,OAAO,QAAQ,IAAI,KAAK,OAAO,MAAM,EAAE,GAAG,OAAO,MAAM,EAAE,IAAI,GAAG,OAAO,MAAM,EAAE,CAAC,IAAI,IAAI,KAAK,KAAK;CACxG,OAAO,OAAO,MAAM,KAAK,QAAQ,CAAC,IAAI,QAAQ,WAAW,OAAO,IAAI;AACtE;;;;;;AAOA,SAAgB,aAAa,KAA2C,OAAiD,KAAoB,OAAiC,GAAuB;CACnM,MAAM,QAAQ,IAAI,KAAK,MAAM;CAC7B,IAAI,MAAM,SAAS,aAAa;EAC9B,IAAI,OAAO,UAAU,YAAY,CAAC,SAAS,CAAC,KAAK,OAAO;EACxD,MAAM,SAAS,cAAc,KAAK,KAAK,CAAC,EAAE;EAC1C,IAAI,QAAQ,KAAK,SAAS,aAAa,OAAO;EAC9C,OAAO,OAAO,MAAM,CAAC,CAAC,CAAC,YAAY,KAAK,KAAK,cAAc,OAAO,OAAO,OAAO,MAAM,IAAI,CAAC,CAAC,CAAC;CAC/F;CACA,IAAI,MAAM,SAAS,gBAAgB;EACjC,MAAM,MAAM;EACZ,OAAO,OAAO,OAAO,QAAQ,YAAY,OAAO,IAAI,SAAS,WAAW,UAAU,KAAK,IAAI,KAAK,IAAI;CACtG;CACA,IAAI,MAAM,SAAS,cAAc;EAC/B,MAAM,aAAa;EACnB,IAAI,CAAC,cAAc,OAAO,eAAe,YAAY,OAAO,WAAW,WAAW,UAAU,OAAO;EACnG,OAAO,CAAC,IAAI,sBAAsB,GAAG,WAAW,MAAM,IAAI,WAAW,QAAQ,WAAW,YAAY,WAAW,WAAW,SAAS,IAAI,EAAE,CAAC,CAAC,OAAO,OAAO,CAAC,CAAC,KAAK,KAAK;CACvK;CACA,OAAO,SAAS,KAAK,KAAK;AAC5B;;AAGA,MAAM,eAAgE;CACpE,MAAM;EAAE,MAAM;EAAmB,OAAO;CAAyB;CACjE,OAAO;EAAE,MAAM;EAAuB,OAAO;CAAwB;CACrE,MAAM;EAAE,MAAM;EAAyB,OAAO;CAA2B;AAC3E;AACA,MAAM,eAAe;CAAE,MAAM;CAA0B,OAAO;AAA6B;AAC3F,MAAM,eAAe;CAAE,MAAM;CAAmB,OAAO;AAAyB;AAEhF,MAAa,eAAe,UAAkB,aAAa,WAAW,QAAQ,eAAe;;AAY7F,SAAgB,UAAU,KAAmB,GAAgC;CAC3E,MAAM,QAAQ,IAAI,OAAO,MAAK,cAAa,UAAU,QAAQ,YAAY,UAAU,SAAS,QAAQ;CACpG,IAAI,CAAC,OAAO,OAAO;CACnB,MAAM,QAAQ,SAAS,KAAK,KAAK;CACjC,OAAO;EAAE;EAAO;EAAO,OAAO,MAAM,SAAS,MAAK,WAAU,OAAO,UAAU,KAAK,CAAC,EAAE,UAAU,SAAS,EAAE,wBAAwB;EAAI,GAAG,YAAY,KAAK;CAAE;AAC9J"}
@@ -0,0 +1,7 @@
1
+ //#region src/features/composites/meta-keys.d.ts
2
+ /** Key of the derivation (provenance) in a composite's `meta`. */
3
+ export declare const DERIVATION_KEY = "derivation";
4
+ /** Key of the bibliographic record (`CslItem`) in a composite's `meta`. */
5
+ export declare const BIB_KEY = "bib";
6
+ //#endregion
7
+ //# sourceMappingURL=meta-keys.d.ts.map
@@ -0,0 +1,21 @@
1
+ //#region src/features/composites/meta-keys.ts
2
+ /** Key of the derivation (provenance) in a composite's `meta`. */
3
+ const DERIVATION_KEY = "derivation";
4
+ /** Key of the bibliographic record (`CslItem`) in a composite's `meta`. */
5
+ const BIB_KEY = "bib";
6
+ /**
7
+ * Whether a composite of `kind` keeps the `meta` entry `key`: the fields the kind declares, plus provenance
8
+ * (`derivation`) and the bibliographic record (`bib`), which any kind may carry (a kind switch, a conversion and a
9
+ * Markdown round trip must not drop them).
10
+ */
11
+ function keepsMetaKey(kind, key) {
12
+ return key === "derivation" || key === "bib" || kind.fields.some((field) => field.key === key);
13
+ }
14
+ /** `meta` reduced to the entries a composite of `kind` keeps (`keepsMetaKey`). */
15
+ function keptMeta(kind, meta) {
16
+ return Object.fromEntries(Object.entries(meta).filter(([key]) => keepsMetaKey(kind, key)));
17
+ }
18
+ //#endregion
19
+ export { BIB_KEY, DERIVATION_KEY, keepsMetaKey, keptMeta };
20
+
21
+ //# sourceMappingURL=meta-keys.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"meta-keys.js","names":[],"sources":["../../../src/features/composites/meta-keys.ts"],"sourcesContent":["// Vue-free and server-importable: the `meta` keys a Baustein of any kind may carry, and which meta keys a kind keeps.\nimport type { CompositeKind } from './kinds'\n\n/** Key of the derivation (provenance) in a composite's `meta`. */\nexport const DERIVATION_KEY = 'derivation'\n\n/** Key of the bibliographic record (`CslItem`) in a composite's `meta`. */\nexport const BIB_KEY = 'bib'\n\n/**\n * Whether a composite of `kind` keeps the `meta` entry `key`: the fields the kind declares, plus provenance\n * (`derivation`) and the bibliographic record (`bib`), which any kind may carry (a kind switch, a conversion and a\n * Markdown round trip must not drop them).\n */\nexport function keepsMetaKey(kind: Pick<CompositeKind, 'fields'>, key: string): boolean {\n return key === DERIVATION_KEY || key === BIB_KEY || kind.fields.some(field => field.key === key)\n}\n\n/** `meta` reduced to the entries a composite of `kind` keeps (`keepsMetaKey`). */\nexport function keptMeta(kind: Pick<CompositeKind, 'fields'>, meta: Record<string, unknown>): Record<string, unknown> {\n return Object.fromEntries(Object.entries(meta).filter(([key]) => keepsMetaKey(kind, key)))\n}\n"],"mappings":";;AAIA,MAAa,iBAAiB;;AAG9B,MAAa,UAAU;;;;;;AAOvB,SAAgB,aAAa,MAAqC,KAAsB;CACtF,OAAO,QAAA,gBAA0B,QAAA,SAAmB,KAAK,OAAO,MAAK,UAAS,MAAM,QAAQ,GAAG;AACjG;;AAGA,SAAgB,SAAS,MAAqC,MAAwD;CACpH,OAAO,OAAO,YAAY,OAAO,QAAQ,IAAI,CAAC,CAAC,QAAQ,CAAC,SAAS,aAAa,MAAM,GAAG,CAAC,CAAC;AAC3F"}
@@ -1,17 +1,20 @@
1
1
  import { CompositeOptions, CompositeStorage } from "./nodes.js";
2
+ import { ReferenceOptions } from "./reference.js";
2
3
  import { NodeViewRenderer } from "@tiptap/core";
3
4
  //#region src/features/composites/node-views.d.ts
4
- /** The node view renderer a framework binding supplies for the composite block. */
5
+ /** The node view renderers a framework binding supplies for the composite block and the reference chip. */
5
6
  export interface CompositeNodeViews {
6
7
  composite: NodeViewRenderer;
8
+ reference: NodeViewRenderer;
7
9
  }
8
10
  /**
9
- * The composite node with the node view of a framework binding, and the tags row (data: hidden, `CompositeChrome`
10
- * shows and edits it, so it needs no node view). Configure the kinds with `Composite.configure({ kinds: [...defaultCompositeKinds(t), myKind] })`.
11
+ * The composite node with the node view of a framework binding, the tags row (data: hidden, `CompositeChrome`
12
+ * shows and edits it, so it needs no node view) and the reference chip. Configure the kinds with `Composite.configure({ kinds: [...defaultCompositeKinds(t), myKind] })`.
11
13
  */
12
14
  export declare function compositeNodes(nodeViews: CompositeNodeViews): {
13
15
  Composite: import("@tiptap/core").Node<CompositeOptions, CompositeStorage>;
14
16
  CompositeTags: import("@tiptap/core").Node<any, any>;
17
+ Reference: import("@tiptap/core").Node<ReferenceOptions, any>;
15
18
  };
16
19
  //#endregion
17
20
  //# sourceMappingURL=node-views.d.ts.map
@@ -1,15 +1,19 @@
1
1
  import { CompositeNode, CompositeTagsNode } from "./nodes.js";
2
+ import { ReferenceNode } from "./reference.js";
2
3
  //#region src/features/composites/node-views.ts
3
4
  /**
4
- * The composite node with the node view of a framework binding, and the tags row (data: hidden, `CompositeChrome`
5
- * shows and edits it, so it needs no node view). Configure the kinds with `Composite.configure({ kinds: [...defaultCompositeKinds(t), myKind] })`.
5
+ * The composite node with the node view of a framework binding, the tags row (data: hidden, `CompositeChrome`
6
+ * shows and edits it, so it needs no node view) and the reference chip. Configure the kinds with `Composite.configure({ kinds: [...defaultCompositeKinds(t), myKind] })`.
6
7
  */
7
8
  function compositeNodes(nodeViews) {
8
9
  return {
9
10
  Composite: CompositeNode.extend({ addNodeView() {
10
11
  return nodeViews.composite;
11
12
  } }),
12
- CompositeTags: CompositeTagsNode
13
+ CompositeTags: CompositeTagsNode,
14
+ Reference: ReferenceNode.extend({ addNodeView() {
15
+ return nodeViews.reference;
16
+ } })
13
17
  };
14
18
  }
15
19
  //#endregion
@@ -1 +1 @@
1
- {"version":3,"file":"node-views.js","names":[],"sources":["../../../src/features/composites/node-views.ts"],"sourcesContent":["import type { NodeViewRenderer } from '@tiptap/core'\nimport { CompositeNode, CompositeTagsNode } from './nodes'\n\n/** The node view renderer a framework binding supplies for the composite block. */\nexport interface CompositeNodeViews {\n composite: NodeViewRenderer\n}\n\n/**\n * The composite node with the node view of a framework binding, and the tags row (data: hidden, `CompositeChrome`\n * shows and edits it, so it needs no node view). Configure the kinds with `Composite.configure({ kinds: [...defaultCompositeKinds(t), myKind] })`.\n */\nexport function compositeNodes(nodeViews: CompositeNodeViews) {\n return {\n // Explicit return type: the node views import `compositeKindsOf`, so inference would otherwise be circular.\n Composite: CompositeNode.extend({\n addNodeView(): NodeViewRenderer {\n return nodeViews.composite\n },\n }),\n CompositeTags: CompositeTagsNode,\n }\n}\n"],"mappings":";;;;;;AAYA,SAAgB,eAAe,WAA+B;CAC5D,OAAO;EAEL,WAAW,cAAc,OAAO,EAC9B,cAAgC;GAC9B,OAAO,UAAU;EACnB,EACF,CAAC;EACD,eAAe;CACjB;AACF"}
1
+ {"version":3,"file":"node-views.js","names":[],"sources":["../../../src/features/composites/node-views.ts"],"sourcesContent":["import type { NodeViewRenderer } from '@tiptap/core'\nimport { CompositeNode, CompositeTagsNode } from './nodes'\nimport { ReferenceNode } from './reference'\n\n/** The node view renderers a framework binding supplies for the composite block and the reference chip. */\nexport interface CompositeNodeViews {\n composite: NodeViewRenderer\n reference: NodeViewRenderer\n}\n\n/**\n * The composite node with the node view of a framework binding, the tags row (data: hidden, `CompositeChrome`\n * shows and edits it, so it needs no node view) and the reference chip. Configure the kinds with `Composite.configure({ kinds: [...defaultCompositeKinds(t), myKind] })`.\n */\nexport function compositeNodes(nodeViews: CompositeNodeViews) {\n return {\n // Explicit return type: the node views import `compositeKindsOf`, so inference would otherwise be circular.\n Composite: CompositeNode.extend({\n addNodeView(): NodeViewRenderer {\n return nodeViews.composite\n },\n }),\n CompositeTags: CompositeTagsNode,\n Reference: ReferenceNode.extend({\n addNodeView(): NodeViewRenderer {\n return nodeViews.reference\n },\n }),\n }\n}\n"],"mappings":";;;;;;;AAcA,SAAgB,eAAe,WAA+B;CAC5D,OAAO;EAEL,WAAW,cAAc,OAAO,EAC9B,cAAgC;GAC9B,OAAO,UAAU;EACnB,EACF,CAAC;EACD,eAAe;EACf,WAAW,cAAc,OAAO,EAC9B,cAAgC;GAC9B,OAAO,UAAU;EACnB,EACF,CAAC;CACH;AACF"}
@@ -1,3 +1,4 @@
1
+ import { Store } from "../../core/store.js";
1
2
  import { HeadingConversionScope } from "../../settings/values.js";
2
3
  import "../../settings/index.js";
3
4
  import { CompositeKind } from "./kinds.js";
@@ -10,6 +11,8 @@ export interface CompositeOptions {
10
11
  /** Storage of the `composite` node: mirrors `options.kinds` for code that only has the editor. */
11
12
  export interface CompositeStorage {
12
13
  kinds: readonly CompositeKind[];
14
+ /** Ids of the derived Bausteine (those with a `meta.derivation`) the user opened; every other derived Baustein shows collapsed. */
15
+ expanded: Store<ReadonlySet<string>>;
13
16
  }
14
17
  declare module '@tiptap/core' {
15
18
  interface Commands<ReturnType> {
@@ -31,8 +34,10 @@ declare module '@tiptap/core' {
31
34
  recursive: boolean;
32
35
  scope: HeadingConversionScope;
33
36
  }) => ReturnType;
34
- /** Switch the composite at `pos` (default: the caret's innermost composite) to `kind`; `meta` keeps only the target kind's fields. */
37
+ /** Switch the composite at `pos` (default: the caret's innermost composite) to `kind`; `meta` keeps the target kind's fields plus `derivation` and `bib`. */
35
38
  setCompositeKind: (kind: string, pos?: number) => ReturnType;
39
+ /** Open the derived Baustein with block id `id` if it is collapsed, collapse it if it is open. */
40
+ toggleCompositeExpanded: (id: string) => ReturnType;
36
41
  };
37
42
  }
38
43
  interface Storage {
@@ -1,8 +1,11 @@
1
1
  import { ABILITY, TEXT_ABILITIES } from "../../core/schema/abilities.js";
2
- import { isChromeNode } from "../../core/schema/node-flags.js";
3
2
  import { editorEntryOf } from "../../core/editor-ui.js";
3
+ import { isChromeNode } from "../../core/schema/node-flags.js";
4
+ import { createStore } from "../../core/store.js";
4
5
  import { compositeKind, defaultCompositeKinds, fallbackCompositeKinds } from "./kinds.js";
5
- import { compositeFence } from "./fences.js";
6
+ import { keptMeta } from "./meta-keys.js";
7
+ import { compositeFence, withReferencedFenceIds } from "./fences.js";
8
+ import { derivationOf } from "./derivation.js";
6
9
  import { flattenCompositesToHeadings, groupHeadingsIntoComposites, headingGroupRange } from "./heading-composites.js";
7
10
  import { Node, mergeAttributes } from "@tiptap/core";
8
11
  import { Selection, TextSelection } from "@tiptap/pm/state";
@@ -193,12 +196,28 @@ const CompositeNode = Node.create({
193
196
  ABILITY.compositeMeta,
194
197
  ABILITY.compositeSummarize,
195
198
  ABILITY.compositeExport,
196
- ABILITY.compositeTranscribe
199
+ ABILITY.compositeDerive
197
200
  ] },
198
201
  addOptions: () => ({ kinds: fallbackCompositeKinds() }),
199
202
  addStorage() {
200
- return { kinds: this.options.kinds };
203
+ return {
204
+ kinds: this.options.kinds,
205
+ expanded: createStore(/* @__PURE__ */ new Set())
206
+ };
201
207
  },
208
+ onSelectionUpdate() {
209
+ const { expanded } = this.storage;
210
+ const { $head } = this.editor.state.selection;
211
+ let open = null;
212
+ for (let depth = $head.depth; depth > 0; depth--) {
213
+ const node = $head.node(depth);
214
+ const id = node.attrs.id;
215
+ if (node.type.name !== COMPOSITE || typeof id !== "string" || !id || $head.index(depth) < CHROME_COUNT) continue;
216
+ if (derivationOf(node) && !expanded.get().has(id)) (open ??= new Set(expanded.get())).add(id);
217
+ }
218
+ if (open) expanded.set(open);
219
+ },
220
+ markdownPrepare: (json, editor) => withReferencedFenceIds(json, compositeKindsOf(editor)),
202
221
  addAttributes: () => ({
203
222
  kind: {
204
223
  default: DEFAULT_KIND,
@@ -228,10 +247,18 @@ const CompositeNode = Node.create({
228
247
  const kind = typeof node.attrs?.kind === "string" && node.attrs.kind ? node.attrs.kind : DEFAULT_KIND;
229
248
  const meta = node.attrs?.meta;
230
249
  const body = (node.content ?? []).map((child, index) => h.renderChild?.(child, index) ?? h.renderChildren([child])).filter(Boolean).join("\n\n");
231
- return compositeFence(kind, meta && typeof meta === "object" ? meta : {}, body);
250
+ const id = node.attrs?.id;
251
+ return compositeFence(kind, meta && typeof meta === "object" ? meta : {}, body, typeof id === "string" && id ? id : void 0);
232
252
  },
233
253
  addCommands() {
234
254
  return {
255
+ toggleCompositeExpanded: (id) => () => {
256
+ const { expanded } = this.storage;
257
+ const next = new Set(expanded.get());
258
+ if (!next.delete(id)) next.add(id);
259
+ expanded.set(next);
260
+ return true;
261
+ },
235
262
  insertComposite: (kind = DEFAULT_KIND) => ({ state, tr, dispatch }) => {
236
263
  const { $head } = state.selection;
237
264
  let depth = $head.depth;
@@ -278,8 +305,7 @@ const CompositeNode = Node.create({
278
305
  const found = compositeAt(state, pos);
279
306
  if (!found) return false;
280
307
  if (dispatch) {
281
- const keys = new Set(compositeKind(this.options.kinds, kind).fields.map((field) => field.key));
282
- const meta = Object.fromEntries(Object.entries(found.node.attrs.meta).filter(([key]) => keys.has(key)));
308
+ const meta = keptMeta(compositeKind(this.options.kinds, kind), found.node.attrs.meta);
283
309
  tr.setNodeMarkup(found.pos, void 0, {
284
310
  ...found.node.attrs,
285
311
  kind,
@@ -1 +1 @@
1
- {"version":3,"file":"nodes.js","names":[],"sources":["../../../src/features/composites/nodes.ts"],"sourcesContent":["import type { Editor } from '@tiptap/core'\nimport { type JSONContent, mergeAttributes, Node } from '@tiptap/core'\nimport type { Node as PMNode, ResolvedPos } from '@tiptap/pm/model'\nimport { type EditorState, Selection, TextSelection } from '@tiptap/pm/state'\nimport { editorEntryOf } from '../../core/editor-ui'\nimport { ABILITY, isChromeNode, TEXT_ABILITIES } from '../../core/schema'\nimport type { HeadingConversionScope } from '../../settings'\nimport { compositeFence } from './fences'\nimport { flattenCompositesToHeadings, groupHeadingsIntoComposites, headingGroupRange } from './heading-composites'\nimport { type CompositeKind, compositeKind, defaultCompositeKinds, fallbackCompositeKinds } from './kinds'\n\n/** Options of the `composite` node: the kinds its `kind` attribute selects from. */\nexport interface CompositeOptions {\n kinds: readonly CompositeKind[]\n}\n\n/** Storage of the `composite` node: mirrors `options.kinds` for code that only has the editor. */\nexport interface CompositeStorage {\n kinds: readonly CompositeKind[]\n}\n\ndeclare module '@tiptap/core' {\n interface Commands<ReturnType> {\n composite: {\n /** Insert an empty composite of `kind` after the caret's block (replacing an empty paragraph; at the body start from the composite chrome), caret in its title. */\n insertComposite: (kind?: string) => ReturnType\n /** Wrap the selected blocks into a new composite of `kind`, caret in its title. */\n wrapInComposite: (kind?: string) => ReturnType\n /** Leave the caret's innermost composite: new paragraph right after it (a trailing empty body paragraph is moved there). */\n exitComposite: () => ReturnType\n /** Group headings in the selected blocks (or, without a selection, in `scope`) into composites of `kind`; `recursive` nests every heading level. False when the range holds no heading. */\n convertHeadingsToComposites: (options: { recursive: boolean, scope: HeadingConversionScope, kind?: string }) => ReturnType\n /** Turn composites among the selected blocks (or, without a selection, in `scope`) into headings of their nesting level, with description, tags and meta as text lines; `recursive` flattens every level. False when the range holds no composite. */\n convertCompositesToHeadings: (options: { recursive: boolean, scope: HeadingConversionScope }) => ReturnType\n /** Switch the composite at `pos` (default: the caret's innermost composite) to `kind`; `meta` keeps only the target kind's fields. */\n setCompositeKind: (kind: string, pos?: number) => ReturnType\n }\n }\n\n interface Storage {\n composite: CompositeStorage\n }\n}\n\nconst COMPOSITE = 'composite'\nconst TITLE = 'compositeTitle'\nconst DESCRIPTION = 'compositeDescription'\nconst TAGS = 'compositeTags'\n/** Kind of a composite created without an explicit one (also the attribute default). */\nconst DEFAULT_KIND = 'section'\n/** Title, description and tags: the fixed children in front of a composite's body. */\nexport const COMPOSITE_CHROME_COUNT = 3\nconst CHROME_COUNT = COMPOSITE_CHROME_COUNT\n\n/**\n * Composite kinds `editor` was configured with. An editor without the composite node gets the built-in kinds in the\n * language of its surface (the default language without one).\n */\nexport function compositeKindsOf(editor: Editor): readonly CompositeKind[] {\n const configured: readonly CompositeKind[] | undefined = editor.storage.composite?.kinds\n if (configured) return configured\n const entry = editorEntryOf(editor)\n return entry ? defaultCompositeKinds(entry.ctx.t) : fallbackCompositeKinds()\n}\n\n/** JSON of a fresh composite of `kind` (empty title/description/tags, hidden meta) with `body`. */\nexport function compositeJSON(kind: string, body: JSONContent[] = [{ type: 'paragraph' }]): JSONContent {\n return { type: COMPOSITE, attrs: { kind }, content: [{ type: TITLE }, { type: DESCRIPTION }, { type: TAGS }, ...body] }\n}\n\n/** Innermost composite around `$pos`: its depth, position and node. */\nfunction compositeAround($pos: ResolvedPos): { depth: number, pos: number, node: PMNode } | null {\n for (let depth = $pos.depth; depth > 0; depth--) {\n const node = $pos.node(depth)\n if (node.type.name === COMPOSITE) return { depth, pos: $pos.before(depth), node }\n }\n return null\n}\n\n/** The composite starting at `pos`, or without `pos` the caret's innermost composite. */\nfunction compositeAt(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 (= after the tags row) of the composite whose content starts at `start`. */\nfunction bodyStart(composite: PMNode, start: number): number {\n let pos = start\n for (let i = 0; i < CHROME_COUNT; i++) pos += composite.child(i).nodeSize\n return pos\n}\n\nconst isEmptyParagraph = (node: PMNode) => node.type.name === 'paragraph' && node.content.size === 0\n\n/** The caret's block is an empty paragraph, the last child of a composite whose body has more than this one block. */\nfunction inTrailingEmptyParagraph($head: ResolvedPos): boolean {\n if ($head.depth < 2 || !isEmptyParagraph($head.parent)) return false\n const composite = $head.node($head.depth - 1)\n return composite.type.name === COMPOSITE\n && $head.index($head.depth - 1) === composite.childCount - 1\n && composite.childCount > CHROME_COUNT + 1\n}\n\n/** Nothing typed yet: empty title and description, no tags, body is one empty paragraph. */\nfunction isEmptyComposite(composite: PMNode): boolean {\n const tags: unknown = composite.child(2).attrs.tags\n return composite.child(0).content.size === 0\n && composite.child(1).content.size === 0\n && (!Array.isArray(tags) || tags.length === 0)\n && composite.childCount === CHROME_COUNT + 1\n && isEmptyParagraph(composite.child(CHROME_COUNT))\n}\n\n/** Child range of `parent` a structure conversion works on: the selected blocks (composite chrome excluded), or without a selection the `scope` — for `'heading'` the caret's heading group (`'group'`) or innermost composite (`'flatten'`). */\nfunction structureRange(state: EditorState, scope: HeadingConversionScope, direction: 'group' | 'flatten'): { parent: PMNode, parentDepth: number, parentStart: number, fromIndex: number, toIndex: number } | null {\n const { $from, $to, $head, empty } = state.selection\n if (!empty) {\n const range = $from.blockRange($to, node => node.type.name === 'doc' || node.type.name === COMPOSITE)\n if (!range) return null\n const parent = range.parent\n // The composite chrome (title, description, tags) is never part of the converted blocks.\n const fromIndex = Math.max(range.startIndex, parent.type.name === COMPOSITE ? CHROME_COUNT : 0)\n const toIndex = range.endIndex\n if (fromIndex >= toIndex) return null\n return { parent, parentDepth: range.depth, parentStart: range.$from.start(range.depth), fromIndex, toIndex }\n }\n if (scope === 'container') {\n const found = compositeAround($head)\n if (found) return { parent: found.node, parentDepth: found.depth, parentStart: $head.start(found.depth), fromIndex: CHROME_COUNT, toIndex: found.node.childCount }\n return { parent: state.doc, parentDepth: 0, parentStart: 0, fromIndex: 0, toIndex: state.doc.childCount }\n }\n if (scope === 'heading') {\n if (direction === 'flatten') {\n const found = compositeAround($head)\n if (!found) return null\n const depth = found.depth - 1\n const fromIndex = $head.index(depth)\n return { parent: $head.node(depth), parentDepth: depth, parentStart: $head.start(depth), fromIndex, toIndex: fromIndex + 1 }\n }\n let depth = $head.depth\n while (depth > 0 && !['doc', COMPOSITE].includes($head.node(depth - 1).type.name)) depth--\n if (depth === 0) return null\n const parent = $head.node(depth - 1)\n const minIndex = parent.type.name === COMPOSITE ? CHROME_COUNT : 0\n let index = $head.index(depth - 1)\n while (index >= minIndex && parent.child(index).type.name !== 'heading') index--\n if (index < minIndex) return null\n const group = headingGroupRange(parent, index)\n return { parent, parentDepth: depth - 1, parentStart: $head.start(depth - 1), fromIndex: group.from, toIndex: group.to }\n }\n return { parent: state.doc, parentDepth: 0, parentStart: 0, fromIndex: 0, toIndex: state.doc.childCount }\n}\n\n/** Children `fromIndex..toIndex` of `parent` (content starting at `parentStart`) and their document range. */\nfunction rangeBlocks(parent: PMNode, parentStart: number, fromIndex: number, toIndex: number): { blocks: PMNode[], from: number, to: number } {\n const blocks: PMNode[] = []\n let from = parentStart\n let to = parentStart\n parent.forEach((child, _offset, index) => {\n if (index < fromIndex) from += child.nodeSize\n else if (index < toIndex) blocks.push(child)\n if (index < toIndex) to += child.nodeSize\n })\n return { blocks, from, to }\n}\n\n// Revoked inside title and description: they are single lines of text, not containers for blocks.\nconst CHROME_REVOKES = [\n ABILITY.headings, ABILITY.lists, ABILITY.blockquote, ABILITY.codeBlock, ABILITY.rule, ABILITY.composite, ABILITY.transcript,\n ABILITY.media, ABILITY.record, ABILITY.aiGenerate, ABILITY.blockDuplicate,\n]\n\n// Schema-only nodes (no node views): shared by the client editor and the server-side Yjs schema.\n// The client adds the node view of `composite` in `node-views.ts`; `compositeTags` needs none (a hidden data row).\nexport const CompositeNode = Node.create<CompositeOptions, CompositeStorage>({\n name: COMPOSITE,\n // Above StarterKit's default (100) so this Enter / Backspace / Delete keymap runs first,\n // below Paragraph (1000) so the paragraph stays the schema's default block.\n priority: 101,\n group: 'block',\n content: `${TITLE} ${DESCRIPTION} ${TAGS} block+`,\n isolating: true,\n defining: true,\n editorBlockContainer: true,\n abilities: { own: [ABILITY.compositeMeta, ABILITY.compositeSummarize, ABILITY.compositeExport, ABILITY.compositeTranscribe] },\n addOptions: () => ({ kinds: fallbackCompositeKinds() }),\n addStorage() {\n return { kinds: this.options.kinds }\n },\n addAttributes: () => ({\n kind: {\n default: DEFAULT_KIND,\n // `null` (no `data-kind`, e.g. legacy markup) falls back to the default kind.\n parseHTML: el => el.getAttribute('data-kind') || null,\n renderHTML: attrs => ({ 'data-kind': attrs.kind }),\n },\n meta: {\n default: {},\n parseHTML: (el) => {\n try {\n const value: unknown = JSON.parse(el.getAttribute('data-meta') ?? '{}')\n return value && typeof value === 'object' && !Array.isArray(value) ? value : {}\n }\n catch {\n return {}\n }\n },\n renderHTML: attrs => ({ 'data-meta': JSON.stringify(attrs.meta) }),\n },\n }),\n parseHTML: () => [\n { tag: 'section[data-type=\"composite\"]' },\n // Legacy markup of the block the composite family replaced: no `data-kind`, so it parses as kind `section`.\n { tag: 'section[data-type=\"section\"]' },\n ],\n renderHTML: ({ HTMLAttributes }) => ['section', mergeAttributes(HTMLAttributes, { 'data-type': COMPOSITE }), 0],\n // Fenced: `::: <kind> {meta JSON, only when non-empty}`, then title, description, tags and body blocks as separate\n // Markdown blocks (empty description/tags render nothing), then `:::`. Same child iteration as the blockquote's\n // renderMarkdown (keeps list numbering etc. per sibling index).\n renderMarkdown: (node, h) => {\n const kind = typeof node.attrs?.kind === 'string' && node.attrs.kind ? node.attrs.kind : DEFAULT_KIND\n const meta: unknown = node.attrs?.meta\n const body = (node.content ?? [])\n .map((child, index) => h.renderChild?.(child, index) ?? h.renderChildren([child]))\n .filter(Boolean)\n .join('\\n\\n')\n return compositeFence(kind, meta && typeof meta === 'object' ? meta as Record<string, unknown> : {}, body)\n },\n\n addCommands() {\n return {\n insertComposite: (kind = DEFAULT_KIND) => ({ state, tr, dispatch }) => {\n const { $head } = state.selection\n let depth = $head.depth\n while (depth > 0 && !['doc', COMPOSITE].includes($head.node(depth - 1).type.name)) depth--\n let from = $head.pos\n let to = from\n if (depth > 0) {\n const block = $head.node(depth)\n if (isChromeNode(block)) from = to = bodyStart($head.node(depth - 1), $head.start(depth - 1))\n else if (isEmptyParagraph(block)) {\n from = $head.before(depth)\n to = $head.after(depth)\n }\n else from = to = $head.after(depth)\n }\n const $from = state.doc.resolve(from)\n if (!$from.parent.canReplaceWith($from.index(), state.doc.resolve(to).index(), this.type)) return false\n if (dispatch) {\n const json = compositeJSON(kind)\n tr.replaceWith(from, to, state.schema.nodeFromJSON(json))\n tr.setSelection(TextSelection.create(tr.doc, from + 2)).scrollIntoView()\n }\n return true\n },\n\n wrapInComposite: (kind = DEFAULT_KIND) => ({ state, tr, dispatch }) => {\n const { $from, $to } = state.selection\n const range = $from.blockRange($to, node => node.type.name === 'doc' || node.type.name === COMPOSITE)\n if (!range) return false\n if (range.parent.type.name === COMPOSITE && range.startIndex < CHROME_COUNT) return false\n if (!range.parent.canReplaceWith(range.startIndex, range.endIndex, this.type)) return false\n if (dispatch) {\n const { nodes } = state.schema\n const composite = this.type.create({ kind }, [\n nodes[TITLE]!.create(), nodes[DESCRIPTION]!.create(), nodes[TAGS]!.create(),\n ...state.doc.slice(range.start, range.end).content.content,\n ])\n tr.replaceWith(range.start, range.end, composite)\n tr.setSelection(TextSelection.create(tr.doc, range.start + 2)).scrollIntoView()\n }\n return true\n },\n\n setCompositeKind: (kind, pos) => ({ state, tr, dispatch }) => {\n const found = compositeAt(state, pos)\n if (!found) return false\n if (dispatch) {\n const keys = new Set(compositeKind(this.options.kinds, kind).fields.map(field => field.key))\n const meta = Object.fromEntries(Object.entries(found.node.attrs.meta as Record<string, unknown>).filter(([key]) => keys.has(key)))\n tr.setNodeMarkup(found.pos, undefined, { ...found.node.attrs, kind, meta })\n }\n return true\n },\n\n exitComposite: () => ({ state, tr, dispatch }) => {\n const { $head } = state.selection\n const composite = compositeAround($head)\n if (!composite) return false\n if (dispatch) {\n // Leaving from a trailing empty paragraph moves it out instead of leaving an empty line behind.\n if ($head.depth === composite.depth + 1 && inTrailingEmptyParagraph($head)) tr.delete($head.before(), $head.after())\n const after = tr.mapping.map($head.after(composite.depth))\n tr.insert(after, state.schema.nodes.paragraph!.create())\n tr.setSelection(TextSelection.create(tr.doc, after + 1)).scrollIntoView()\n }\n return true\n },\n\n convertHeadingsToComposites: ({ recursive, scope, kind = DEFAULT_KIND }) => ({ state, tr, dispatch }) => {\n const range = structureRange(state, scope, 'group')\n if (!range) return false\n const { blocks, from, to } = rangeBlocks(range.parent, range.parentStart, range.fromIndex, range.toIndex)\n const result = groupHeadingsIntoComposites(state.schema, blocks, recursive, kind)\n if (!result) return false\n if (dispatch) {\n tr.replaceWith(from, to, result)\n tr.setSelection(Selection.near(tr.doc.resolve(from), 1)).scrollIntoView()\n }\n return true\n },\n\n convertCompositesToHeadings: ({ recursive, scope }) => ({ state, tr, dispatch }) => {\n const range = structureRange(state, scope, 'flatten')\n if (!range) return false\n const $pos = state.selection.empty ? state.selection.$head : state.selection.$from\n let level = 1\n for (let depth = 1; depth <= range.parentDepth; depth++) {\n if ($pos.node(depth).type.name === COMPOSITE) level++\n }\n const { blocks, from, to } = rangeBlocks(range.parent, range.parentStart, range.fromIndex, range.toIndex)\n const result = flattenCompositesToHeadings(state.schema, blocks, recursive, level, this.options.kinds)\n if (!result) return false\n if (dispatch) {\n tr.replaceWith(from, to, result)\n tr.setSelection(Selection.near(tr.doc.resolve(from), 1)).scrollIntoView()\n }\n return true\n },\n }\n },\n\n addKeyboardShortcuts() {\n return {\n Enter: () => {\n const { $head } = this.editor.state.selection\n const type = $head.parent.type.name\n if (type === TITLE || type === DESCRIPTION) {\n const depth = $head.depth - 1\n const composite = $head.node(depth)\n const start = $head.start(depth)\n return this.editor.commands.command(({ tr }) => {\n const selection = Selection.findFrom(tr.doc.resolve(bodyStart(composite, start)), 1)\n if (!selection) return false\n tr.setSelection(selection).scrollIntoView()\n return true\n })\n }\n if (this.editor.state.selection.empty && inTrailingEmptyParagraph($head)) return this.editor.commands.exitComposite()\n return false\n },\n\n Backspace: () => {\n const { selection } = this.editor.state\n const { $head } = selection\n if (!selection.empty || !$head.parent.isTextblock || $head.parentOffset !== 0 || $head.depth < 2) return false\n const depth = $head.depth - 1\n const composite = $head.node(depth)\n if (composite.type.name !== COMPOSITE) return false\n const start = $head.start(depth)\n const titleEnd = start + composite.child(0).nodeSize - 1\n const type = $head.parent.type.name\n\n if (type === DESCRIPTION) {\n return this.editor.commands.command(({ tr }) => {\n tr.setSelection(TextSelection.create(tr.doc, titleEnd))\n return true\n })\n }\n if (type === TITLE) {\n // Never joins anything into the title; an untouched composite turns back into a paragraph.\n if (!isEmptyComposite(composite)) return true\n return this.editor.commands.command(({ tr, state }) => {\n const from = $head.before(depth)\n tr.replaceWith(from, $head.after(depth), state.schema.nodes.paragraph!.create())\n tr.setSelection(TextSelection.create(tr.doc, from + 1))\n return true\n })\n }\n // First body block: ProseMirror's joinBackward would delete the tags row (an atom) — move into the chrome instead.\n if ($head.index(depth) !== CHROME_COUNT) return false\n return this.editor.commands.command(({ tr }) => {\n if (isEmptyParagraph($head.parent) && composite.childCount > CHROME_COUNT + 1) tr.delete($head.before(), $head.after())\n tr.setSelection(TextSelection.create(tr.doc, titleEnd))\n return true\n })\n },\n\n // No join of the following block into title or description.\n Delete: () => {\n const { selection } = this.editor.state\n const { $head } = selection\n const type = $head.parent.type.name\n return selection.empty && (type === TITLE || type === DESCRIPTION) && $head.parentOffset === $head.parent.content.size\n },\n\n 'Mod-Shift-a': () => this.editor.commands.insertComposite(DEFAULT_KIND),\n }\n },\n})\n\nexport const CompositeTitleNode = Node.create({\n name: TITLE,\n // Above StarterKit's hard break (100), which also binds Mod-Enter.\n priority: 101,\n content: 'inline*',\n defining: true,\n editorChrome: true,\n abilities: { revokes: CHROME_REVOKES },\n // Above the heading's `h2` rule; the second rule reads legacy markup.\n parseHTML: () => [\n { tag: 'h2[data-type=\"composite-title\"]', priority: 60 },\n { tag: 'h2[data-type=\"section-title\"]', priority: 60 },\n ],\n renderHTML: ({ HTMLAttributes }) => ['h2', mergeAttributes(HTMLAttributes, { 'data-type': 'composite-title', class: 'composite-title' }), 0],\n renderMarkdown: (node, h) => `## ${h.renderChildren(node.content ?? [])}`,\n addKeyboardShortcuts() {\n return {\n // Here rather than on CompositeNode: the ability gate swallows every Mod-/Alt- key of the `composite` type where\n // `format.composite` is missing (title, code blocks, speaker segments), but leaving a composite must work everywhere.\n 'Mod-Enter': () => this.editor.commands.exitComposite(),\n }\n },\n})\n\nexport const CompositeDescriptionNode = Node.create({\n name: DESCRIPTION,\n content: 'inline*',\n defining: true,\n editorChrome: true,\n abilities: { revokes: CHROME_REVOKES },\n // Above the paragraph's `p` rule; the second rule reads legacy markup.\n parseHTML: () => [\n { tag: 'p[data-type=\"composite-description\"]', priority: 60 },\n { tag: 'p[data-type=\"section-summary\"]', priority: 60 },\n ],\n renderHTML: ({ HTMLAttributes }) => ['p', mergeAttributes(HTMLAttributes, { 'data-type': 'composite-description', class: 'composite-description' }), 0],\n renderMarkdown: (node, h) => {\n const text = h.renderChildren(node.content ?? [])\n return text ? `> ${text}` : ''\n },\n})\n\nexport const CompositeTagsNode = Node.create({\n name: TAGS,\n atom: true,\n selectable: false,\n draggable: false,\n allowGapCursor: false,\n editorChrome: true,\n abilities: { revokes: [...TEXT_ABILITIES, ABILITY.blockDelete, ABILITY.blockDuplicate] },\n addAttributes: () => ({\n tags: {\n default: [],\n parseHTML: (el) => {\n try {\n const value: unknown = JSON.parse(el.getAttribute('data-tags') ?? '[]')\n return Array.isArray(value) ? value.filter(tag => typeof tag === 'string') : []\n }\n catch {\n return []\n }\n },\n renderHTML: attrs => ({ 'data-tags': JSON.stringify(attrs.tags) }),\n },\n }),\n // The second rule reads legacy markup.\n parseHTML: () => [{ tag: 'div[data-type=\"composite-tags\"]' }, { tag: 'div[data-type=\"section-tags\"]' }],\n renderHTML: ({ HTMLAttributes }) => ['div', mergeAttributes(HTMLAttributes, { 'data-type': 'composite-tags', class: 'composite-tags' })],\n renderMarkdown: (node) => {\n const tags: unknown = node.attrs?.tags\n return Array.isArray(tags) && tags.length ? `Tags: ${tags.map(tag => `#${tag}`).join(' ')}` : ''\n },\n})\n\nexport const CompositeNodes = [CompositeNode, CompositeTitleNode, CompositeDescriptionNode, CompositeTagsNode]\n"],"mappings":"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"}
1
+ {"version":3,"file":"nodes.js","names":[],"sources":["../../../src/features/composites/nodes.ts"],"sourcesContent":["import type { Editor } from '@tiptap/core'\nimport { type JSONContent, mergeAttributes, Node } from '@tiptap/core'\nimport type { Node as PMNode, ResolvedPos } from '@tiptap/pm/model'\nimport { type EditorState, Selection, TextSelection } from '@tiptap/pm/state'\nimport { editorEntryOf } from '../../core/editor-ui'\nimport { createStore, type Store } from '../../core/store'\nimport { ABILITY, isChromeNode, TEXT_ABILITIES } from '../../core/schema'\nimport type { HeadingConversionScope } from '../../settings'\nimport { compositeFence, withReferencedFenceIds } from './fences'\nimport { derivationOf } from './derivation'\nimport { flattenCompositesToHeadings, groupHeadingsIntoComposites, headingGroupRange } from './heading-composites'\nimport { type CompositeKind, compositeKind, defaultCompositeKinds, fallbackCompositeKinds } from './kinds'\nimport { keptMeta } from './meta-keys'\n\n/** Options of the `composite` node: the kinds its `kind` attribute selects from. */\nexport interface CompositeOptions {\n kinds: readonly CompositeKind[]\n}\n\n/** Storage of the `composite` node: mirrors `options.kinds` for code that only has the editor. */\nexport interface CompositeStorage {\n kinds: readonly CompositeKind[]\n /** Ids of the derived Bausteine (those with a `meta.derivation`) the user opened; every other derived Baustein shows collapsed. */\n expanded: Store<ReadonlySet<string>>\n}\n\ndeclare module '@tiptap/core' {\n interface Commands<ReturnType> {\n composite: {\n /** Insert an empty composite of `kind` after the caret's block (replacing an empty paragraph; at the body start from the composite chrome), caret in its title. */\n insertComposite: (kind?: string) => ReturnType\n /** Wrap the selected blocks into a new composite of `kind`, caret in its title. */\n wrapInComposite: (kind?: string) => ReturnType\n /** Leave the caret's innermost composite: new paragraph right after it (a trailing empty body paragraph is moved there). */\n exitComposite: () => ReturnType\n /** Group headings in the selected blocks (or, without a selection, in `scope`) into composites of `kind`; `recursive` nests every heading level. False when the range holds no heading. */\n convertHeadingsToComposites: (options: { recursive: boolean, scope: HeadingConversionScope, kind?: string }) => ReturnType\n /** Turn composites among the selected blocks (or, without a selection, in `scope`) into headings of their nesting level, with description, tags and meta as text lines; `recursive` flattens every level. False when the range holds no composite. */\n convertCompositesToHeadings: (options: { recursive: boolean, scope: HeadingConversionScope }) => ReturnType\n /** Switch the composite at `pos` (default: the caret's innermost composite) to `kind`; `meta` keeps the target kind's fields plus `derivation` and `bib`. */\n setCompositeKind: (kind: string, pos?: number) => ReturnType\n /** Open the derived Baustein with block id `id` if it is collapsed, collapse it if it is open. */\n toggleCompositeExpanded: (id: string) => ReturnType\n }\n }\n\n interface Storage {\n composite: CompositeStorage\n }\n}\n\nconst COMPOSITE = 'composite'\nconst TITLE = 'compositeTitle'\nconst DESCRIPTION = 'compositeDescription'\nconst TAGS = 'compositeTags'\n/** Kind of a composite created without an explicit one (also the attribute default). */\nconst DEFAULT_KIND = 'section'\n/** Title, description and tags: the fixed children in front of a composite's body. */\nexport const COMPOSITE_CHROME_COUNT = 3\nconst CHROME_COUNT = COMPOSITE_CHROME_COUNT\n\n/**\n * Composite kinds `editor` was configured with. An editor without the composite node gets the built-in kinds in the\n * language of its surface (the default language without one).\n */\nexport function compositeKindsOf(editor: Editor): readonly CompositeKind[] {\n const configured: readonly CompositeKind[] | undefined = editor.storage.composite?.kinds\n if (configured) return configured\n const entry = editorEntryOf(editor)\n return entry ? defaultCompositeKinds(entry.ctx.t) : fallbackCompositeKinds()\n}\n\n/** JSON of a fresh composite of `kind` (empty title/description/tags, hidden meta) with `body`. */\nexport function compositeJSON(kind: string, body: JSONContent[] = [{ type: 'paragraph' }]): JSONContent {\n return { type: COMPOSITE, attrs: { kind }, content: [{ type: TITLE }, { type: DESCRIPTION }, { type: TAGS }, ...body] }\n}\n\n/** Innermost composite around `$pos`: its depth, position and node. */\nfunction compositeAround($pos: ResolvedPos): { depth: number, pos: number, node: PMNode } | null {\n for (let depth = $pos.depth; depth > 0; depth--) {\n const node = $pos.node(depth)\n if (node.type.name === COMPOSITE) return { depth, pos: $pos.before(depth), node }\n }\n return null\n}\n\n/** The composite starting at `pos`, or without `pos` the caret's innermost composite. */\nfunction compositeAt(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 (= after the tags row) of the composite whose content starts at `start`. */\nfunction bodyStart(composite: PMNode, start: number): number {\n let pos = start\n for (let i = 0; i < CHROME_COUNT; i++) pos += composite.child(i).nodeSize\n return pos\n}\n\nconst isEmptyParagraph = (node: PMNode) => node.type.name === 'paragraph' && node.content.size === 0\n\n/** The caret's block is an empty paragraph, the last child of a composite whose body has more than this one block. */\nfunction inTrailingEmptyParagraph($head: ResolvedPos): boolean {\n if ($head.depth < 2 || !isEmptyParagraph($head.parent)) return false\n const composite = $head.node($head.depth - 1)\n return composite.type.name === COMPOSITE\n && $head.index($head.depth - 1) === composite.childCount - 1\n && composite.childCount > CHROME_COUNT + 1\n}\n\n/** Nothing typed yet: empty title and description, no tags, body is one empty paragraph. */\nfunction isEmptyComposite(composite: PMNode): boolean {\n const tags: unknown = composite.child(2).attrs.tags\n return composite.child(0).content.size === 0\n && composite.child(1).content.size === 0\n && (!Array.isArray(tags) || tags.length === 0)\n && composite.childCount === CHROME_COUNT + 1\n && isEmptyParagraph(composite.child(CHROME_COUNT))\n}\n\n/** Child range of `parent` a structure conversion works on: the selected blocks (composite chrome excluded), or without a selection the `scope` — for `'heading'` the caret's heading group (`'group'`) or innermost composite (`'flatten'`). */\nfunction structureRange(state: EditorState, scope: HeadingConversionScope, direction: 'group' | 'flatten'): { parent: PMNode, parentDepth: number, parentStart: number, fromIndex: number, toIndex: number } | null {\n const { $from, $to, $head, empty } = state.selection\n if (!empty) {\n const range = $from.blockRange($to, node => node.type.name === 'doc' || node.type.name === COMPOSITE)\n if (!range) return null\n const parent = range.parent\n // The composite chrome (title, description, tags) is never part of the converted blocks.\n const fromIndex = Math.max(range.startIndex, parent.type.name === COMPOSITE ? CHROME_COUNT : 0)\n const toIndex = range.endIndex\n if (fromIndex >= toIndex) return null\n return { parent, parentDepth: range.depth, parentStart: range.$from.start(range.depth), fromIndex, toIndex }\n }\n if (scope === 'container') {\n const found = compositeAround($head)\n if (found) return { parent: found.node, parentDepth: found.depth, parentStart: $head.start(found.depth), fromIndex: CHROME_COUNT, toIndex: found.node.childCount }\n return { parent: state.doc, parentDepth: 0, parentStart: 0, fromIndex: 0, toIndex: state.doc.childCount }\n }\n if (scope === 'heading') {\n if (direction === 'flatten') {\n const found = compositeAround($head)\n if (!found) return null\n const depth = found.depth - 1\n const fromIndex = $head.index(depth)\n return { parent: $head.node(depth), parentDepth: depth, parentStart: $head.start(depth), fromIndex, toIndex: fromIndex + 1 }\n }\n let depth = $head.depth\n while (depth > 0 && !['doc', COMPOSITE].includes($head.node(depth - 1).type.name)) depth--\n if (depth === 0) return null\n const parent = $head.node(depth - 1)\n const minIndex = parent.type.name === COMPOSITE ? CHROME_COUNT : 0\n let index = $head.index(depth - 1)\n while (index >= minIndex && parent.child(index).type.name !== 'heading') index--\n if (index < minIndex) return null\n const group = headingGroupRange(parent, index)\n return { parent, parentDepth: depth - 1, parentStart: $head.start(depth - 1), fromIndex: group.from, toIndex: group.to }\n }\n return { parent: state.doc, parentDepth: 0, parentStart: 0, fromIndex: 0, toIndex: state.doc.childCount }\n}\n\n/** Children `fromIndex..toIndex` of `parent` (content starting at `parentStart`) and their document range. */\nfunction rangeBlocks(parent: PMNode, parentStart: number, fromIndex: number, toIndex: number): { blocks: PMNode[], from: number, to: number } {\n const blocks: PMNode[] = []\n let from = parentStart\n let to = parentStart\n parent.forEach((child, _offset, index) => {\n if (index < fromIndex) from += child.nodeSize\n else if (index < toIndex) blocks.push(child)\n if (index < toIndex) to += child.nodeSize\n })\n return { blocks, from, to }\n}\n\n// Revoked inside title and description: they are single lines of text, not containers for blocks.\nconst CHROME_REVOKES = [\n ABILITY.headings, ABILITY.lists, ABILITY.blockquote, ABILITY.codeBlock, ABILITY.rule, ABILITY.composite, ABILITY.transcript,\n ABILITY.media, ABILITY.record, ABILITY.aiGenerate, ABILITY.blockDuplicate,\n]\n\n// Schema-only nodes (no node views): shared by the client editor and the server-side Yjs schema.\n// The client adds the node view of `composite` in `node-views.ts`; `compositeTags` needs none (a hidden data row).\nexport const CompositeNode = Node.create<CompositeOptions, CompositeStorage>({\n name: COMPOSITE,\n // Above StarterKit's default (100) so this Enter / Backspace / Delete keymap runs first,\n // below Paragraph (1000) so the paragraph stays the schema's default block.\n priority: 101,\n group: 'block',\n content: `${TITLE} ${DESCRIPTION} ${TAGS} block+`,\n isolating: true,\n defining: true,\n editorBlockContainer: true,\n abilities: { own: [ABILITY.compositeMeta, ABILITY.compositeSummarize, ABILITY.compositeExport, ABILITY.compositeDerive] },\n addOptions: () => ({ kinds: fallbackCompositeKinds() }),\n addStorage() {\n return { kinds: this.options.kinds, expanded: createStore<ReadonlySet<string>>(new Set()) }\n },\n // A caret inside the body of a collapsed derived Baustein (also inside nested ones) opens it: typing into hidden text would be blind.\n onSelectionUpdate() {\n const { expanded } = this.storage\n const { $head } = this.editor.state.selection\n let open: Set<string> | null = null\n for (let depth = $head.depth; depth > 0; depth--) {\n const node = $head.node(depth)\n const id: unknown = node.attrs.id\n if (node.type.name !== COMPOSITE || typeof id !== 'string' || !id || $head.index(depth) < CHROME_COUNT) continue\n if (derivationOf(node) && !expanded.get().has(id)) (open ??= new Set(expanded.get())).add(id)\n }\n if (open) expanded.set(open)\n },\n // Block ids reach the Markdown only for referenced Bausteine (see `fences.ts`): `DocumentMarkdown` runs this on the\n // document JSON before serializing, it drops the ids of unreferenced composites, `renderMarkdown` writes the ones left.\n markdownPrepare: (json, editor) => withReferencedFenceIds(json, compositeKindsOf(editor)),\n addAttributes: () => ({\n kind: {\n default: DEFAULT_KIND,\n // `null` (no `data-kind`, e.g. legacy markup) falls back to the default kind.\n parseHTML: el => el.getAttribute('data-kind') || null,\n renderHTML: attrs => ({ 'data-kind': attrs.kind }),\n },\n meta: {\n default: {},\n parseHTML: (el) => {\n try {\n const value: unknown = JSON.parse(el.getAttribute('data-meta') ?? '{}')\n return value && typeof value === 'object' && !Array.isArray(value) ? value : {}\n }\n catch {\n return {}\n }\n },\n renderHTML: attrs => ({ 'data-meta': JSON.stringify(attrs.meta) }),\n },\n }),\n parseHTML: () => [\n { tag: 'section[data-type=\"composite\"]' },\n // Legacy markup of the block the composite family replaced: no `data-kind`, so it parses as kind `section`.\n { tag: 'section[data-type=\"section\"]' },\n ],\n renderHTML: ({ HTMLAttributes }) => ['section', mergeAttributes(HTMLAttributes, { 'data-type': COMPOSITE }), 0],\n // Fenced: `::: <kind> {meta JSON, only when non-empty}`, then title, description, tags and body blocks as separate\n // Markdown blocks (empty description/tags render nothing), then `:::`. Same child iteration as the blockquote's\n // renderMarkdown (keeps list numbering etc. per sibling index).\n renderMarkdown: (node, h) => {\n const kind = typeof node.attrs?.kind === 'string' && node.attrs.kind ? node.attrs.kind : DEFAULT_KIND\n const meta: unknown = node.attrs?.meta\n const body = (node.content ?? [])\n .map((child, index) => h.renderChild?.(child, index) ?? h.renderChildren([child]))\n .filter(Boolean)\n .join('\\n\\n')\n const id: unknown = node.attrs?.id\n return compositeFence(kind, meta && typeof meta === 'object' ? meta as Record<string, unknown> : {}, body, typeof id === 'string' && id ? id : undefined)\n },\n\n addCommands() {\n return {\n toggleCompositeExpanded: id => () => {\n const { expanded } = this.storage\n const next = new Set(expanded.get())\n if (!next.delete(id)) next.add(id)\n expanded.set(next)\n return true\n },\n\n insertComposite: (kind = DEFAULT_KIND) => ({ state, tr, dispatch }) => {\n const { $head } = state.selection\n let depth = $head.depth\n while (depth > 0 && !['doc', COMPOSITE].includes($head.node(depth - 1).type.name)) depth--\n let from = $head.pos\n let to = from\n if (depth > 0) {\n const block = $head.node(depth)\n if (isChromeNode(block)) from = to = bodyStart($head.node(depth - 1), $head.start(depth - 1))\n else if (isEmptyParagraph(block)) {\n from = $head.before(depth)\n to = $head.after(depth)\n }\n else from = to = $head.after(depth)\n }\n const $from = state.doc.resolve(from)\n if (!$from.parent.canReplaceWith($from.index(), state.doc.resolve(to).index(), this.type)) return false\n if (dispatch) {\n const json = compositeJSON(kind)\n tr.replaceWith(from, to, state.schema.nodeFromJSON(json))\n tr.setSelection(TextSelection.create(tr.doc, from + 2)).scrollIntoView()\n }\n return true\n },\n\n wrapInComposite: (kind = DEFAULT_KIND) => ({ state, tr, dispatch }) => {\n const { $from, $to } = state.selection\n const range = $from.blockRange($to, node => node.type.name === 'doc' || node.type.name === COMPOSITE)\n if (!range) return false\n if (range.parent.type.name === COMPOSITE && range.startIndex < CHROME_COUNT) return false\n if (!range.parent.canReplaceWith(range.startIndex, range.endIndex, this.type)) return false\n if (dispatch) {\n const { nodes } = state.schema\n const composite = this.type.create({ kind }, [\n nodes[TITLE]!.create(), nodes[DESCRIPTION]!.create(), nodes[TAGS]!.create(),\n ...state.doc.slice(range.start, range.end).content.content,\n ])\n tr.replaceWith(range.start, range.end, composite)\n tr.setSelection(TextSelection.create(tr.doc, range.start + 2)).scrollIntoView()\n }\n return true\n },\n\n setCompositeKind: (kind, pos) => ({ state, tr, dispatch }) => {\n const found = compositeAt(state, pos)\n if (!found) return false\n if (dispatch) {\n const meta = keptMeta(compositeKind(this.options.kinds, kind), found.node.attrs.meta as Record<string, unknown>)\n tr.setNodeMarkup(found.pos, undefined, { ...found.node.attrs, kind, meta })\n }\n return true\n },\n\n exitComposite: () => ({ state, tr, dispatch }) => {\n const { $head } = state.selection\n const composite = compositeAround($head)\n if (!composite) return false\n if (dispatch) {\n // Leaving from a trailing empty paragraph moves it out instead of leaving an empty line behind.\n if ($head.depth === composite.depth + 1 && inTrailingEmptyParagraph($head)) tr.delete($head.before(), $head.after())\n const after = tr.mapping.map($head.after(composite.depth))\n tr.insert(after, state.schema.nodes.paragraph!.create())\n tr.setSelection(TextSelection.create(tr.doc, after + 1)).scrollIntoView()\n }\n return true\n },\n\n convertHeadingsToComposites: ({ recursive, scope, kind = DEFAULT_KIND }) => ({ state, tr, dispatch }) => {\n const range = structureRange(state, scope, 'group')\n if (!range) return false\n const { blocks, from, to } = rangeBlocks(range.parent, range.parentStart, range.fromIndex, range.toIndex)\n const result = groupHeadingsIntoComposites(state.schema, blocks, recursive, kind)\n if (!result) return false\n if (dispatch) {\n tr.replaceWith(from, to, result)\n tr.setSelection(Selection.near(tr.doc.resolve(from), 1)).scrollIntoView()\n }\n return true\n },\n\n convertCompositesToHeadings: ({ recursive, scope }) => ({ state, tr, dispatch }) => {\n const range = structureRange(state, scope, 'flatten')\n if (!range) return false\n const $pos = state.selection.empty ? state.selection.$head : state.selection.$from\n let level = 1\n for (let depth = 1; depth <= range.parentDepth; depth++) {\n if ($pos.node(depth).type.name === COMPOSITE) level++\n }\n const { blocks, from, to } = rangeBlocks(range.parent, range.parentStart, range.fromIndex, range.toIndex)\n const result = flattenCompositesToHeadings(state.schema, blocks, recursive, level, this.options.kinds)\n if (!result) return false\n if (dispatch) {\n tr.replaceWith(from, to, result)\n tr.setSelection(Selection.near(tr.doc.resolve(from), 1)).scrollIntoView()\n }\n return true\n },\n }\n },\n\n addKeyboardShortcuts() {\n return {\n Enter: () => {\n const { $head } = this.editor.state.selection\n const type = $head.parent.type.name\n if (type === TITLE || type === DESCRIPTION) {\n const depth = $head.depth - 1\n const composite = $head.node(depth)\n const start = $head.start(depth)\n return this.editor.commands.command(({ tr }) => {\n const selection = Selection.findFrom(tr.doc.resolve(bodyStart(composite, start)), 1)\n if (!selection) return false\n tr.setSelection(selection).scrollIntoView()\n return true\n })\n }\n if (this.editor.state.selection.empty && inTrailingEmptyParagraph($head)) return this.editor.commands.exitComposite()\n return false\n },\n\n Backspace: () => {\n const { selection } = this.editor.state\n const { $head } = selection\n if (!selection.empty || !$head.parent.isTextblock || $head.parentOffset !== 0 || $head.depth < 2) return false\n const depth = $head.depth - 1\n const composite = $head.node(depth)\n if (composite.type.name !== COMPOSITE) return false\n const start = $head.start(depth)\n const titleEnd = start + composite.child(0).nodeSize - 1\n const type = $head.parent.type.name\n\n if (type === DESCRIPTION) {\n return this.editor.commands.command(({ tr }) => {\n tr.setSelection(TextSelection.create(tr.doc, titleEnd))\n return true\n })\n }\n if (type === TITLE) {\n // Never joins anything into the title; an untouched composite turns back into a paragraph.\n if (!isEmptyComposite(composite)) return true\n return this.editor.commands.command(({ tr, state }) => {\n const from = $head.before(depth)\n tr.replaceWith(from, $head.after(depth), state.schema.nodes.paragraph!.create())\n tr.setSelection(TextSelection.create(tr.doc, from + 1))\n return true\n })\n }\n // First body block: ProseMirror's joinBackward would delete the tags row (an atom) — move into the chrome instead.\n if ($head.index(depth) !== CHROME_COUNT) return false\n return this.editor.commands.command(({ tr }) => {\n if (isEmptyParagraph($head.parent) && composite.childCount > CHROME_COUNT + 1) tr.delete($head.before(), $head.after())\n tr.setSelection(TextSelection.create(tr.doc, titleEnd))\n return true\n })\n },\n\n // No join of the following block into title or description.\n Delete: () => {\n const { selection } = this.editor.state\n const { $head } = selection\n const type = $head.parent.type.name\n return selection.empty && (type === TITLE || type === DESCRIPTION) && $head.parentOffset === $head.parent.content.size\n },\n\n 'Mod-Shift-a': () => this.editor.commands.insertComposite(DEFAULT_KIND),\n }\n },\n})\n\nexport const CompositeTitleNode = Node.create({\n name: TITLE,\n // Above StarterKit's hard break (100), which also binds Mod-Enter.\n priority: 101,\n content: 'inline*',\n defining: true,\n editorChrome: true,\n abilities: { revokes: CHROME_REVOKES },\n // Above the heading's `h2` rule; the second rule reads legacy markup.\n parseHTML: () => [\n { tag: 'h2[data-type=\"composite-title\"]', priority: 60 },\n { tag: 'h2[data-type=\"section-title\"]', priority: 60 },\n ],\n renderHTML: ({ HTMLAttributes }) => ['h2', mergeAttributes(HTMLAttributes, { 'data-type': 'composite-title', class: 'composite-title' }), 0],\n renderMarkdown: (node, h) => `## ${h.renderChildren(node.content ?? [])}`,\n addKeyboardShortcuts() {\n return {\n // Here rather than on CompositeNode: the ability gate swallows every Mod-/Alt- key of the `composite` type where\n // `format.composite` is missing (title, code blocks, speaker segments), but leaving a composite must work everywhere.\n 'Mod-Enter': () => this.editor.commands.exitComposite(),\n }\n },\n})\n\nexport const CompositeDescriptionNode = Node.create({\n name: DESCRIPTION,\n content: 'inline*',\n defining: true,\n editorChrome: true,\n abilities: { revokes: CHROME_REVOKES },\n // Above the paragraph's `p` rule; the second rule reads legacy markup.\n parseHTML: () => [\n { tag: 'p[data-type=\"composite-description\"]', priority: 60 },\n { tag: 'p[data-type=\"section-summary\"]', priority: 60 },\n ],\n renderHTML: ({ HTMLAttributes }) => ['p', mergeAttributes(HTMLAttributes, { 'data-type': 'composite-description', class: 'composite-description' }), 0],\n renderMarkdown: (node, h) => {\n const text = h.renderChildren(node.content ?? [])\n return text ? `> ${text}` : ''\n },\n})\n\nexport const CompositeTagsNode = Node.create({\n name: TAGS,\n atom: true,\n selectable: false,\n draggable: false,\n allowGapCursor: false,\n editorChrome: true,\n abilities: { revokes: [...TEXT_ABILITIES, ABILITY.blockDelete, ABILITY.blockDuplicate] },\n addAttributes: () => ({\n tags: {\n default: [],\n parseHTML: (el) => {\n try {\n const value: unknown = JSON.parse(el.getAttribute('data-tags') ?? '[]')\n return Array.isArray(value) ? value.filter(tag => typeof tag === 'string') : []\n }\n catch {\n return []\n }\n },\n renderHTML: attrs => ({ 'data-tags': JSON.stringify(attrs.tags) }),\n },\n }),\n // The second rule reads legacy markup.\n parseHTML: () => [{ tag: 'div[data-type=\"composite-tags\"]' }, { tag: 'div[data-type=\"section-tags\"]' }],\n renderHTML: ({ HTMLAttributes }) => ['div', mergeAttributes(HTMLAttributes, { 'data-type': 'composite-tags', class: 'composite-tags' })],\n renderMarkdown: (node) => {\n const tags: unknown = node.attrs?.tags\n return Array.isArray(tags) && tags.length ? `Tags: ${tags.map(tag => `#${tag}`).join(' ')}` : ''\n },\n})\n\nexport const CompositeNodes = [CompositeNode, CompositeTitleNode, CompositeDescriptionNode, CompositeTagsNode]\n"],"mappings":"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"}