@ecsplico/editor 2.1.1 → 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 (701) hide show
  1. package/CHANGELOG.md +74 -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/code/CodeSurface.vue.d.ts +3 -3
  41. package/dist/config/index.d.ts +105 -0
  42. package/dist/config/index.js +95 -0
  43. package/dist/config/index.js.map +1 -0
  44. package/dist/core/abilities.js +1 -0
  45. package/dist/core/abilities.js.map +1 -1
  46. package/dist/{adapters/routes.js → core/api-routes.js} +5 -3
  47. package/dist/core/api-routes.js.map +1 -0
  48. package/dist/core/backend-capability.d.ts +7 -0
  49. package/dist/core/backend-capability.js +17 -0
  50. package/dist/core/backend-capability.js.map +1 -0
  51. package/dist/core/backend-types.d.ts +245 -0
  52. package/dist/core/backend-types.js +17 -0
  53. package/dist/core/backend-types.js.map +1 -0
  54. package/dist/core/backend.d.ts +108 -0
  55. package/dist/core/backend.js +14 -0
  56. package/dist/core/backend.js.map +1 -0
  57. package/dist/core/block-convert.d.ts +7 -5
  58. package/dist/core/block-convert.js +28 -5
  59. package/dist/core/block-convert.js.map +1 -1
  60. package/dist/core/command-types.d.ts +89 -0
  61. package/dist/core/commands.d.ts +40 -0
  62. package/dist/core/commands.js +151 -0
  63. package/dist/core/commands.js.map +1 -0
  64. package/dist/core/context.d.ts +17 -20
  65. package/dist/core/context.js +24 -21
  66. package/dist/core/context.js.map +1 -1
  67. package/dist/core/core-feature.d.ts +22 -7
  68. package/dist/core/core-feature.js +51 -18
  69. package/dist/core/core-feature.js.map +1 -1
  70. package/dist/core/define-editor.d.ts +4 -3
  71. package/dist/core/define-editor.js +14 -7
  72. package/dist/core/define-editor.js.map +1 -1
  73. package/dist/core/document-markdown.js +12 -3
  74. package/dist/core/document-markdown.js.map +1 -1
  75. package/dist/core/editor-ui.d.ts +8 -1
  76. package/dist/core/editor-ui.js +9 -8
  77. package/dist/core/editor-ui.js.map +1 -1
  78. package/dist/core/extension-points.d.ts +3 -15
  79. package/dist/core/feature-context.d.ts +8 -7
  80. package/dist/core/feature-context.js +12 -11
  81. package/dist/core/feature-context.js.map +1 -1
  82. package/dist/core/feature.d.ts +35 -19
  83. package/dist/core/feature.js.map +1 -1
  84. package/dist/core/fences.d.ts +2 -1
  85. package/dist/core/fences.js +3 -2
  86. package/dist/core/fences.js.map +1 -1
  87. package/dist/core/fetch-error.d.ts +1 -1
  88. package/dist/core/fetch-error.js +3 -1
  89. package/dist/core/fetch-error.js.map +1 -1
  90. package/dist/core/hash.d.ts +5 -0
  91. package/dist/core/hash.js +11 -0
  92. package/dist/core/hash.js.map +1 -0
  93. package/dist/core/http-backend.d.ts +11 -0
  94. package/dist/core/http-backend.js +195 -0
  95. package/dist/core/http-backend.js.map +1 -0
  96. package/dist/core/index.d.ts +14 -9
  97. package/dist/core/index.js +12 -9
  98. package/dist/core/palette.d.ts +48 -0
  99. package/dist/core/palette.js +95 -0
  100. package/dist/core/palette.js.map +1 -0
  101. package/dist/core/schema/abilities.d.ts +2 -1
  102. package/dist/core/schema/abilities.js +5 -1
  103. package/dist/core/schema/abilities.js.map +1 -1
  104. package/dist/core/schema/index.d.ts +11 -5
  105. package/dist/core/schema/index.js +13 -8
  106. package/dist/core/schema/index.js.map +1 -1
  107. package/dist/core/schema/mark-flags.d.ts +8 -1
  108. package/dist/core/schema/of-features.d.ts +13 -0
  109. package/dist/core/schema/of-features.js +14 -0
  110. package/dist/core/schema/of-features.js.map +1 -0
  111. package/dist/core/slash.d.ts +8 -6
  112. package/dist/core/slash.js +24 -16
  113. package/dist/core/slash.js.map +1 -1
  114. package/dist/core/surface-session.js +13 -5
  115. package/dist/core/surface-session.js.map +1 -1
  116. package/dist/core/toolbar-items.d.ts +10 -4
  117. package/dist/core/toolbar-items.js +269 -195
  118. package/dist/core/toolbar-items.js.map +1 -1
  119. package/dist/core/util.js +11 -0
  120. package/dist/core/util.js.map +1 -0
  121. package/dist/document/DocumentSurface.d.ts +1 -1
  122. package/dist/document/DocumentSurface.vue.d.ts +3 -3
  123. package/dist/features/ai/agent-op-review.d.ts +1 -1
  124. package/dist/features/ai/agent-op-review.js +1 -1
  125. package/dist/features/ai/agent-ops.js +1 -1
  126. package/dist/features/ai/ai-apply.d.ts +2 -2
  127. package/dist/features/ai/ai-apply.js +1 -1
  128. package/dist/features/ai/ai-review.js +1 -1
  129. package/dist/features/ai/ai-sse.d.ts +6 -6
  130. package/dist/features/ai/ai-sse.js +20 -63
  131. package/dist/features/ai/ai-sse.js.map +1 -1
  132. package/dist/features/ai/assistant.d.ts +8 -7
  133. package/dist/features/ai/assistant.js +3 -3
  134. package/dist/features/ai/assistant.js.map +1 -1
  135. package/dist/features/ai/block-actions.d.ts +3 -2
  136. package/dist/features/ai/block-actions.js +3 -2
  137. package/dist/features/ai/block-actions.js.map +1 -1
  138. package/dist/features/ai/components/AiSelectionMenu.js +1 -1
  139. package/dist/features/ai/components/DocumentChatAnswer.js +1 -1
  140. package/dist/features/ai/components/DocumentChatOps.vue.d.ts +1 -1
  141. package/dist/features/ai/components/SettingsModelProfiles.js +8 -8
  142. package/dist/features/ai/components/SettingsModelProfiles.js.map +1 -1
  143. package/dist/features/ai/document-chat-model.d.ts +8 -7
  144. package/dist/features/ai/document-chat-model.js +5 -5
  145. package/dist/features/ai/document-chat-model.js.map +1 -1
  146. package/dist/features/ai/document-chat.js +1 -1
  147. package/dist/features/ai/feature.js +27 -14
  148. package/dist/features/ai/feature.js.map +1 -1
  149. package/dist/features/ai/ghost-autocomplete.d.ts +7 -6
  150. package/dist/features/ai/ghost-autocomplete.js +6 -9
  151. package/dist/features/ai/ghost-autocomplete.js.map +1 -1
  152. package/dist/features/ai/index.d.ts +4 -3
  153. package/dist/features/ai/index.js +10 -10
  154. package/dist/features/ai/model-profiles.d.ts +5 -4
  155. package/dist/features/ai/model-profiles.js +2 -2
  156. package/dist/features/ai/model-profiles.js.map +1 -1
  157. package/dist/features/ai/protocol/block-lines.js +1 -1
  158. package/dist/features/ai/protocol/block-lines.js.map +1 -1
  159. package/dist/features/ai/protocol/chat.js +4 -1
  160. package/dist/features/ai/protocol/chat.js.map +1 -1
  161. package/dist/features/ai/protocol/index.d.ts +3 -2
  162. package/dist/features/ai/protocol/models.d.ts +2 -16
  163. package/dist/features/ai/protocol/models.js.map +1 -1
  164. package/dist/features/ai/rate-limit.d.ts +1 -1
  165. package/dist/features/ai/rate-limit.js +3 -1
  166. package/dist/features/ai/rate-limit.js.map +1 -1
  167. package/dist/features/ai/react/AiSelectionMenu.js +2 -2
  168. package/dist/features/ai/react/AiSidebar.js +4 -4
  169. package/dist/features/ai/react/DocumentChatAnswer.js +1 -1
  170. package/dist/features/ai/react/DocumentChatOps.d.ts +1 -1
  171. package/dist/features/ai/react/DocumentChatOps.js +1 -1
  172. package/dist/features/ai/react/SettingsModelProfiles.js +8 -10
  173. package/dist/features/ai/react/SettingsModelProfiles.js.map +1 -1
  174. package/dist/features/ai/react/use-ai-assistant.d.ts +1 -1
  175. package/dist/features/ai/react/use-ai-assistant.js +3 -3
  176. package/dist/features/ai/react/use-ai-assistant.js.map +1 -1
  177. package/dist/features/ai/react/use-document-chat.js +2 -2
  178. package/dist/features/ai/react/use-document-chat.js.map +1 -1
  179. package/dist/features/ai/react/use-model-profiles.d.ts +2 -1
  180. package/dist/features/ai/selection-flow.d.ts +1 -1
  181. package/dist/features/ai/selection-flow.js +1 -1
  182. package/dist/features/ai/sidebar-flow.d.ts +1 -1
  183. package/dist/features/ai/sidebar-flow.js +1 -1
  184. package/dist/features/ai/use-ai-assistant.d.ts +1 -1
  185. package/dist/features/ai/use-ai-assistant.js +3 -3
  186. package/dist/features/ai/use-ai-assistant.js.map +1 -1
  187. package/dist/features/ai/use-document-chat.js +2 -2
  188. package/dist/features/ai/use-document-chat.js.map +1 -1
  189. package/dist/features/ai/use-model-profiles.d.ts +2 -1
  190. package/dist/features/authors/attribution.d.ts +1 -1
  191. package/dist/features/authors/feature.js +12 -11
  192. package/dist/features/authors/feature.js.map +1 -1
  193. package/dist/features/block-ui/block-actions.d.ts +22 -1
  194. package/dist/features/block-ui/block-actions.js +26 -2
  195. package/dist/features/block-ui/block-actions.js.map +1 -1
  196. package/dist/features/block-ui/components/BlockActionsOverlay.js +33 -4
  197. package/dist/features/block-ui/components/BlockActionsOverlay.js.map +1 -1
  198. package/dist/features/block-ui/components/BlockActionsOverlay.vue.d.ts +4 -0
  199. package/dist/features/block-ui/components/BlockUi.js +1 -1
  200. package/dist/features/block-ui/feature.js +1 -0
  201. package/dist/features/block-ui/feature.js.map +1 -1
  202. package/dist/features/block-ui/index.d.ts +2 -2
  203. package/dist/features/block-ui/index.js +2 -2
  204. package/dist/features/block-ui/react/BlockActionsOverlay.d.ts +4 -0
  205. package/dist/features/block-ui/react/BlockActionsOverlay.js +38 -12
  206. package/dist/features/block-ui/react/BlockActionsOverlay.js.map +1 -1
  207. package/dist/features/block-ui/react/BlockUi.js +1 -1
  208. package/dist/features/collab/anchor-resolver.js +1 -1
  209. package/dist/features/collab/feature.js +2 -0
  210. package/dist/features/collab/feature.js.map +1 -1
  211. package/dist/features/comments/components/CommentThreadView.vue.d.ts +2 -1
  212. package/dist/features/comments/feature.js +12 -11
  213. package/dist/features/comments/feature.js.map +1 -1
  214. package/dist/features/comments/index.d.ts +3 -2
  215. package/dist/features/comments/index.js +1 -1
  216. package/dist/features/comments/margin-layout.d.ts +3 -2
  217. package/dist/features/comments/model.d.ts +3 -67
  218. package/dist/features/comments/model.js +2 -2
  219. package/dist/features/comments/model.js.map +1 -1
  220. package/dist/features/comments/react/CommentThreadView.d.ts +3 -2
  221. package/dist/features/comments/react/use-comments.d.ts +2 -1
  222. package/dist/features/comments/react.d.ts +1 -1
  223. package/dist/features/comments/schema.d.ts +2 -52
  224. package/dist/features/comments/schema.js.map +1 -1
  225. package/dist/features/comments/snapshot-equality.js.map +1 -1
  226. package/dist/features/comments/use-comments.d.ts +3 -2
  227. package/dist/features/comments/vue.d.ts +1 -1
  228. package/dist/features/composites/accepted-children.d.ts +1 -0
  229. package/dist/features/composites/accepted-children.js +16 -1
  230. package/dist/features/composites/accepted-children.js.map +1 -1
  231. package/dist/features/composites/ai-brief.js +31 -0
  232. package/dist/features/composites/ai-brief.js.map +1 -1
  233. package/dist/features/composites/bibliography-command.d.ts +11 -0
  234. package/dist/features/composites/bibliography-form.js +90 -0
  235. package/dist/features/composites/bibliography-form.js.map +1 -0
  236. package/dist/features/composites/bibliography.d.ts +33 -0
  237. package/dist/features/composites/bibliography.js +120 -0
  238. package/dist/features/composites/bibliography.js.map +1 -0
  239. package/dist/features/composites/components/BibliographyEditor.js +261 -0
  240. package/dist/features/composites/components/BibliographyEditor.js.map +1 -0
  241. package/dist/features/composites/components/CompositeChrome.js +75 -26
  242. package/dist/features/composites/components/CompositeChrome.js.map +1 -1
  243. package/dist/features/composites/components/CompositeDetails.js +46 -11
  244. package/dist/features/composites/components/CompositeDetails.js.map +1 -1
  245. package/dist/features/composites/components/CompositeDetails.vue.d.ts +2 -1
  246. package/dist/features/composites/components/CompositeFieldEditor.js +37 -4
  247. package/dist/features/composites/components/CompositeFieldEditor.js.map +1 -1
  248. package/dist/features/composites/components/CompositeInspector.js +17 -5
  249. package/dist/features/composites/components/CompositeInspector.js.map +1 -1
  250. package/dist/features/composites/components/CompositeTable.js +13 -4
  251. package/dist/features/composites/components/CompositeTable.js.map +1 -1
  252. package/dist/features/composites/components/CompositeTagsEditor.js +1 -1
  253. package/dist/features/composites/components/CompositeView.js +11 -1
  254. package/dist/features/composites/components/CompositeView.js.map +1 -1
  255. package/dist/features/composites/components/DerivationBadge.js +103 -0
  256. package/dist/features/composites/components/DerivationBadge.js.map +1 -0
  257. package/dist/features/composites/components/ReferenceFieldSelect.js +60 -0
  258. package/dist/features/composites/components/ReferenceFieldSelect.js.map +1 -0
  259. package/dist/features/composites/components/ReferenceView.js +122 -0
  260. package/dist/features/composites/components/ReferenceView.js.map +1 -0
  261. package/dist/features/composites/components/ReferenceView.vue.d.ts +96 -0
  262. package/dist/features/composites/components/SettingsEditingTab.js +1 -1
  263. package/dist/features/composites/convert.js +2 -2
  264. package/dist/features/composites/convert.js.map +1 -1
  265. package/dist/features/composites/derivation.d.ts +61 -0
  266. package/dist/features/composites/derivation.js +98 -0
  267. package/dist/features/composites/derivation.js.map +1 -0
  268. package/dist/features/composites/derived-chrome.js +69 -0
  269. package/dist/features/composites/derived-chrome.js.map +1 -0
  270. package/dist/features/composites/feature.js +159 -109
  271. package/dist/features/composites/feature.js.map +1 -1
  272. package/dist/features/composites/fences.d.ts +4 -3
  273. package/dist/features/composites/fences.js +51 -7
  274. package/dist/features/composites/fences.js.map +1 -1
  275. package/dist/features/composites/index.d.ts +12 -3
  276. package/dist/features/composites/index.js +15 -6
  277. package/dist/features/composites/inspector-model.d.ts +4 -1
  278. package/dist/features/composites/inspector-model.js +8 -4
  279. package/dist/features/composites/inspector-model.js.map +1 -1
  280. package/dist/features/composites/kinds.d.ts +8 -1
  281. package/dist/features/composites/kinds.js +145 -6
  282. package/dist/features/composites/kinds.js.map +1 -1
  283. package/dist/features/composites/legacy.d.ts +4 -1
  284. package/dist/features/composites/legacy.js +56 -1
  285. package/dist/features/composites/legacy.js.map +1 -1
  286. package/dist/features/composites/meta-display.js +40 -1
  287. package/dist/features/composites/meta-display.js.map +1 -1
  288. package/dist/features/composites/meta-keys.d.ts +7 -0
  289. package/dist/features/composites/meta-keys.js +21 -0
  290. package/dist/features/composites/meta-keys.js.map +1 -0
  291. package/dist/features/composites/node-views.d.ts +6 -3
  292. package/dist/features/composites/node-views.js +7 -3
  293. package/dist/features/composites/node-views.js.map +1 -1
  294. package/dist/features/composites/nodes.d.ts +6 -1
  295. package/dist/features/composites/nodes.js +33 -7
  296. package/dist/features/composites/nodes.js.map +1 -1
  297. package/dist/features/composites/react/BibliographyEditor.js +229 -0
  298. package/dist/features/composites/react/BibliographyEditor.js.map +1 -0
  299. package/dist/features/composites/react/CompositeChrome.js +65 -17
  300. package/dist/features/composites/react/CompositeChrome.js.map +1 -1
  301. package/dist/features/composites/react/CompositeDetails.d.ts +2 -1
  302. package/dist/features/composites/react/CompositeDetails.js +45 -6
  303. package/dist/features/composites/react/CompositeDetails.js.map +1 -1
  304. package/dist/features/composites/react/CompositeFieldEditor.d.ts +1 -1
  305. package/dist/features/composites/react/CompositeFieldEditor.js +24 -1
  306. package/dist/features/composites/react/CompositeFieldEditor.js.map +1 -1
  307. package/dist/features/composites/react/CompositeInspector.js +11 -5
  308. package/dist/features/composites/react/CompositeInspector.js.map +1 -1
  309. package/dist/features/composites/react/CompositeStatusMenu.js +1 -1
  310. package/dist/features/composites/react/CompositeSummaryEditor.js +1 -1
  311. package/dist/features/composites/react/CompositeTable.js +16 -2
  312. package/dist/features/composites/react/CompositeTable.js.map +1 -1
  313. package/dist/features/composites/react/CompositeTagsEditor.js +2 -2
  314. package/dist/features/composites/react/CompositeView.js +6 -1
  315. package/dist/features/composites/react/CompositeView.js.map +1 -1
  316. package/dist/features/composites/react/DerivationBadge.js +116 -0
  317. package/dist/features/composites/react/DerivationBadge.js.map +1 -0
  318. package/dist/features/composites/react/ReferenceFieldSelect.js +52 -0
  319. package/dist/features/composites/react/ReferenceFieldSelect.js.map +1 -0
  320. package/dist/features/composites/react/ReferenceView.d.ts +11 -0
  321. package/dist/features/composites/react/ReferenceView.js +115 -0
  322. package/dist/features/composites/react/ReferenceView.js.map +1 -0
  323. package/dist/features/composites/react/SettingsEditingTab.js +2 -2
  324. package/dist/features/composites/react.d.ts +2 -1
  325. package/dist/features/composites/react.js +7 -3
  326. package/dist/features/composites/react.js.map +1 -1
  327. package/dist/features/composites/reference-ai.js +16 -0
  328. package/dist/features/composites/reference-ai.js.map +1 -0
  329. package/dist/features/composites/reference-label.d.ts +19 -0
  330. package/dist/features/composites/reference-label.js +58 -0
  331. package/dist/features/composites/reference-label.js.map +1 -0
  332. package/dist/features/composites/reference-suggestion.d.ts +10 -0
  333. package/dist/features/composites/reference-suggestion.js +41 -0
  334. package/dist/features/composites/reference-suggestion.js.map +1 -0
  335. package/dist/features/composites/reference-text.d.ts +18 -0
  336. package/dist/features/composites/reference-text.js +89 -0
  337. package/dist/features/composites/reference-text.js.map +1 -0
  338. package/dist/features/composites/reference.d.ts +44 -0
  339. package/dist/features/composites/reference.js +148 -0
  340. package/dist/features/composites/reference.js.map +1 -0
  341. package/dist/features/composites/reveal-source.d.ts +32 -0
  342. package/dist/features/composites/reveal-source.js +89 -0
  343. package/dist/features/composites/reveal-source.js.map +1 -0
  344. package/dist/features/composites/rows.d.ts +21 -2
  345. package/dist/features/composites/rows.js +63 -9
  346. package/dist/features/composites/rows.js.map +1 -1
  347. package/dist/features/composites/schema.d.ts +9 -3
  348. package/dist/features/composites/schema.js +11 -4
  349. package/dist/features/composites/schema.js.map +1 -1
  350. package/dist/features/composites/table-model.js +12 -21
  351. package/dist/features/composites/table-model.js.map +1 -1
  352. package/dist/features/composites/vue.d.ts +3 -2
  353. package/dist/features/composites/vue.js +8 -4
  354. package/dist/features/composites/vue.js.map +1 -1
  355. package/dist/features/media/assets.d.ts +2 -0
  356. package/dist/features/media/assets.js +3 -2
  357. package/dist/features/media/assets.js.map +1 -1
  358. package/dist/features/media/components/FileView.js +13 -4
  359. package/dist/features/media/components/FileView.js.map +1 -1
  360. package/dist/features/media/feature.d.ts +3 -3
  361. package/dist/features/media/feature.js +21 -28
  362. package/dist/features/media/feature.js.map +1 -1
  363. package/dist/features/media/file-import.js +2 -2
  364. package/dist/features/media/file-import.js.map +1 -1
  365. package/dist/features/media/index.d.ts +2 -2
  366. package/dist/features/media/index.js +2 -2
  367. package/dist/features/media/react/FileView.js +19 -2
  368. package/dist/features/media/react/FileView.js.map +1 -1
  369. package/dist/features/media/schema.d.ts +8 -0
  370. package/dist/features/media/schema.js +126 -11
  371. package/dist/features/media/schema.js.map +1 -1
  372. package/dist/features/media/upload.d.ts +16 -14
  373. package/dist/features/media/upload.js +13 -19
  374. package/dist/features/media/upload.js.map +1 -1
  375. package/dist/features/mentions/index.d.ts +4 -3
  376. package/dist/features/mentions/index.js +4 -1
  377. package/dist/features/mentions/index.js.map +1 -1
  378. package/dist/features/mentions/mention-text.d.ts +1 -1
  379. package/dist/features/mentions/mention-text.js.map +1 -1
  380. package/dist/features/mentions/mention.d.ts +0 -6
  381. package/dist/features/mentions/mention.js.map +1 -1
  382. package/dist/features/mentions/metadata-defaults.d.ts +2 -2
  383. package/dist/features/mentions/metadata-defaults.js +3 -9
  384. package/dist/features/mentions/metadata-defaults.js.map +1 -1
  385. package/dist/features/mentions/schema.d.ts +2 -1
  386. package/dist/features/mentions/schema.js.map +1 -1
  387. package/dist/features/tables/feature.d.ts +2 -1
  388. package/dist/features/tables/feature.js +90 -70
  389. package/dist/features/tables/feature.js.map +1 -1
  390. package/dist/features/themes/components/SettingsAppearanceTab.js +6 -9
  391. package/dist/features/themes/components/SettingsAppearanceTab.js.map +1 -1
  392. package/dist/features/themes/feature.js +2 -0
  393. package/dist/features/themes/feature.js.map +1 -1
  394. package/dist/features/themes/index.d.ts +2 -1
  395. package/dist/features/themes/react/SettingsAppearanceTab.js +7 -10
  396. package/dist/features/themes/react/SettingsAppearanceTab.js.map +1 -1
  397. package/dist/features/themes/schema.d.ts +2 -6
  398. package/dist/features/themes/schema.js.map +1 -1
  399. package/dist/features/themes/theme-runtime.d.ts +1 -1
  400. package/dist/features/themes/theme-runtime.js +4 -2
  401. package/dist/features/themes/theme-runtime.js.map +1 -1
  402. package/dist/features/transcript/TranscriptSegmentView.js +48 -28
  403. package/dist/features/transcript/TranscriptSegmentView.js.map +1 -1
  404. package/dist/features/transcript/feature.js +21 -19
  405. package/dist/features/transcript/feature.js.map +1 -1
  406. package/dist/features/transcript/react/TranscriptSegmentView.js +55 -36
  407. package/dist/features/transcript/react/TranscriptSegmentView.js.map +1 -1
  408. package/dist/features/transcript/segment-node.d.ts +2 -0
  409. package/dist/features/transcript/segment-node.js +35 -7
  410. package/dist/features/transcript/segment-node.js.map +1 -1
  411. package/dist/i18n/de/composites.js +91 -1
  412. package/dist/i18n/de/composites.js.map +1 -1
  413. package/dist/i18n/de/integrations.js +49 -8
  414. package/dist/i18n/de/integrations.js.map +1 -1
  415. package/dist/i18n/de/media.js +0 -1
  416. package/dist/i18n/de/media.js.map +1 -1
  417. package/dist/i18n/de/palette.js +22 -0
  418. package/dist/i18n/de/palette.js.map +1 -0
  419. package/dist/i18n/de/tables.js +0 -1
  420. package/dist/i18n/de/tables.js.map +1 -1
  421. package/dist/i18n/de/transcript.js +2 -1
  422. package/dist/i18n/de/transcript.js.map +1 -1
  423. package/dist/i18n/de/tree.js +3 -0
  424. package/dist/i18n/de/tree.js.map +1 -1
  425. package/dist/i18n/de.d.ts +157 -11
  426. package/dist/i18n/de.js +3 -1
  427. package/dist/i18n/de.js.map +1 -1
  428. package/dist/i18n/en/composites.js +89 -1
  429. package/dist/i18n/en/composites.js.map +1 -1
  430. package/dist/i18n/en/integrations.js +49 -8
  431. package/dist/i18n/en/integrations.js.map +1 -1
  432. package/dist/i18n/en/media.js +0 -1
  433. package/dist/i18n/en/media.js.map +1 -1
  434. package/dist/i18n/en/palette.js +22 -0
  435. package/dist/i18n/en/palette.js.map +1 -0
  436. package/dist/i18n/en/tables.js +0 -1
  437. package/dist/i18n/en/tables.js.map +1 -1
  438. package/dist/i18n/en/transcript.js +2 -1
  439. package/dist/i18n/en/transcript.js.map +1 -1
  440. package/dist/i18n/en/tree.js +3 -0
  441. package/dist/i18n/en/tree.js.map +1 -1
  442. package/dist/i18n/en.js +3 -1
  443. package/dist/i18n/en.js.map +1 -1
  444. package/dist/index.d.ts +4 -3
  445. package/dist/integrations/composite-ai/bibliography-fetch.d.ts +31 -0
  446. package/dist/integrations/composite-ai/bibliography-fetch.js +159 -0
  447. package/dist/integrations/composite-ai/bibliography-fetch.js.map +1 -0
  448. package/dist/integrations/composite-ai/composite-fill.d.ts +30 -8
  449. package/dist/integrations/composite-ai/composite-fill.js +97 -56
  450. package/dist/integrations/composite-ai/composite-fill.js.map +1 -1
  451. package/dist/integrations/composite-ai/composite-summary.d.ts +4 -12
  452. package/dist/integrations/composite-ai/composite-summary.js +7 -26
  453. package/dist/integrations/composite-ai/composite-summary.js.map +1 -1
  454. package/dist/integrations/composite-ai/derive.d.ts +29 -0
  455. package/dist/integrations/composite-ai/derive.js +173 -0
  456. package/dist/integrations/composite-ai/derive.js.map +1 -0
  457. package/dist/integrations/composite-ai/index.d.ts +11 -7
  458. package/dist/integrations/composite-ai/index.js +72 -14
  459. package/dist/integrations/composite-ai/index.js.map +1 -1
  460. package/dist/integrations/composite-ai/rendition.d.ts +45 -0
  461. package/dist/integrations/composite-ai/rendition.js +314 -0
  462. package/dist/integrations/composite-ai/rendition.js.map +1 -0
  463. package/dist/integrations/composite-media/index.d.ts +7 -5
  464. package/dist/integrations/composite-media/index.js +86 -13
  465. package/dist/integrations/composite-media/index.js.map +1 -1
  466. package/dist/integrations/transcript-ai/index.d.ts +1 -1
  467. package/dist/integrations/transcript-ai/index.js +5 -2
  468. package/dist/integrations/transcript-ai/index.js.map +1 -1
  469. package/dist/integrations/transcript-ai/protocol.d.ts +2 -12
  470. package/dist/integrations/transcript-ai/protocol.js +0 -2
  471. package/dist/integrations/transcript-ai/protocol.js.map +1 -1
  472. package/dist/integrations/transcript-ai/transcript-cleanup.d.ts +5 -5
  473. package/dist/integrations/transcript-ai/transcript-cleanup.js +7 -10
  474. package/dist/integrations/transcript-ai/transcript-cleanup.js.map +1 -1
  475. package/dist/markdown/MarkdownSurface.vue.d.ts +10 -9
  476. package/dist/markdown/MarkdownSurface2.js +3 -6
  477. package/dist/markdown/MarkdownSurface2.js.map +1 -1
  478. package/dist/markdown/document.js +1 -1
  479. package/dist/markdown/source-mode.d.ts +1 -1
  480. package/dist/nuxt/module.d.ts +1402 -54
  481. package/dist/nuxt/module.js +6 -49
  482. package/dist/nuxt/module.js.map +1 -1
  483. package/dist/nuxt/runtime/install-context.d.ts +7 -3
  484. package/dist/nuxt/runtime/install-context.js +14 -8
  485. package/dist/nuxt/runtime/install-context.js.map +1 -1
  486. package/dist/nuxt/runtime/plugins/editor-context-nuxt-ui.client.ts +2 -2
  487. package/dist/nuxt/runtime/server/plugins/editor-server.js +20 -12
  488. package/dist/nuxt/runtime/server/plugins/editor-server.js.map +1 -1
  489. package/dist/presets/compose.d.ts +94 -0
  490. package/dist/presets/compose.js +164 -0
  491. package/dist/presets/compose.js.map +1 -0
  492. package/dist/react/AdvancedEditor.d.ts +15 -15
  493. package/dist/react/AdvancedEditor.js +15 -13
  494. package/dist/react/AdvancedEditor.js.map +1 -1
  495. package/dist/react/EditorCommandPalette.d.ts +13 -0
  496. package/dist/react/EditorCommandPalette.js +118 -0
  497. package/dist/react/EditorCommandPalette.js.map +1 -0
  498. package/dist/react/EditorSettingsModal.d.ts +5 -5
  499. package/dist/react/EditorSettingsModal.js +7 -4
  500. package/dist/react/EditorSettingsModal.js.map +1 -1
  501. package/dist/react/EditorSettingsPanel.d.ts +7 -7
  502. package/dist/react/EditorSettingsPanel.js +8 -5
  503. package/dist/react/EditorSettingsPanel.js.map +1 -1
  504. package/dist/react/EditorSurface.d.ts +7 -7
  505. package/dist/react/EditorSurface.js +10 -6
  506. package/dist/react/EditorSurface.js.map +1 -1
  507. package/dist/react/EditorToolbar.d.ts +4 -6
  508. package/dist/react/EditorToolbar.js +29 -37
  509. package/dist/react/EditorToolbar.js.map +1 -1
  510. package/dist/react/SimpleEditor.d.ts +22 -23
  511. package/dist/react/SimpleEditor.js +21 -7
  512. package/dist/react/SimpleEditor.js.map +1 -1
  513. package/dist/react/advanced.d.ts +4 -3
  514. package/dist/react/advanced.js +2 -2
  515. package/dist/react/compose.d.ts +20 -0
  516. package/dist/react/compose.js +49 -0
  517. package/dist/react/compose.js.map +1 -0
  518. package/dist/react/composed-surface.d.ts +39 -0
  519. package/dist/react/composed-surface.js +71 -0
  520. package/dist/react/composed-surface.js.map +1 -0
  521. package/dist/react/context.js +6 -2
  522. package/dist/react/context.js.map +1 -1
  523. package/dist/react/index.d.ts +2 -1
  524. package/dist/react/index.js +2 -1
  525. package/dist/react/key-labels.js +15 -0
  526. package/dist/react/key-labels.js.map +1 -0
  527. package/dist/react/settings.d.ts +1 -1
  528. package/dist/react/simple.d.ts +2 -2
  529. package/dist/react/ui/command.js +36 -1
  530. package/dist/react/ui/command.js.map +1 -1
  531. package/dist/schema/advanced.d.ts +6 -6
  532. package/dist/schema/advanced.js +26 -29
  533. package/dist/schema/advanced.js.map +1 -1
  534. package/dist/server/ai.d.ts +5 -16
  535. package/dist/server/ai.js.map +1 -1
  536. package/dist/server/auth.d.ts +9 -0
  537. package/dist/server/collab-state.d.ts +1 -1
  538. package/dist/server/collab-state.js.map +1 -1
  539. package/dist/server/collab.d.ts +13 -13
  540. package/dist/server/collab.js +34 -18
  541. package/dist/server/collab.js.map +1 -1
  542. package/dist/server/crossref.js +78 -0
  543. package/dist/server/crossref.js.map +1 -0
  544. package/dist/server/errors.d.ts +1 -1
  545. package/dist/server/errors.js +1 -1
  546. package/dist/server/errors.js.map +1 -1
  547. package/dist/server/extract.js +308 -0
  548. package/dist/server/extract.js.map +1 -0
  549. package/dist/{nuxt/runtime/server/utils/editor-route.js → server/h3.js} +8 -16
  550. package/dist/server/h3.js.map +1 -0
  551. package/dist/server/handlers/ai.d.ts +30 -9
  552. package/dist/server/handlers/ai.js +170 -36
  553. package/dist/server/handlers/ai.js.map +1 -1
  554. package/dist/server/handlers/context.d.ts +12 -5
  555. package/dist/server/handlers/context.js +10 -4
  556. package/dist/server/handlers/context.js.map +1 -1
  557. package/dist/server/handlers/editor.d.ts +19 -13
  558. package/dist/server/handlers/editor.js +49 -38
  559. package/dist/server/handlers/editor.js.map +1 -1
  560. package/dist/server/handlers/index.d.ts +4 -4
  561. package/dist/server/handlers/index.js +4 -4
  562. package/dist/server/host.d.ts +16 -25
  563. package/dist/server/host.js +58 -41
  564. package/dist/server/host.js.map +1 -1
  565. package/dist/server/index.d.ts +6 -4
  566. package/dist/server/index.js +3 -2
  567. package/dist/server/pdf.js +97 -0
  568. package/dist/server/pdf.js.map +1 -0
  569. package/dist/server/{adapter.d.ts → ports.d.ts} +81 -30
  570. package/dist/server/ports.js +29 -0
  571. package/dist/server/ports.js.map +1 -0
  572. package/dist/server/routes.js +144 -0
  573. package/dist/server/routes.js.map +1 -0
  574. package/dist/settings/index.d.ts +1 -1
  575. package/dist/settings/index.js.map +1 -1
  576. package/dist/styles/composites.css +25 -0
  577. package/dist/tree/DocumentTree.js +56 -29
  578. package/dist/tree/DocumentTree.js.map +1 -1
  579. package/dist/tree/react/DocumentTree.js +23 -0
  580. package/dist/tree/react/DocumentTree.js.map +1 -1
  581. package/dist/tree/tree-host.js +1 -1
  582. package/dist/vue/AdvancedEditor.js +30 -9
  583. package/dist/vue/AdvancedEditor.js.map +1 -1
  584. package/dist/vue/AdvancedEditor.vue.d.ts +32 -12
  585. package/dist/vue/SimpleEditor.js +62 -16
  586. package/dist/vue/SimpleEditor.js.map +1 -1
  587. package/dist/vue/SimpleEditor.vue.d.ts +37 -7
  588. package/dist/vue/advanced.d.ts +3 -2
  589. package/dist/vue/advanced.js +2 -2
  590. package/dist/vue/components/EditorCommandPalette.js +91 -0
  591. package/dist/vue/components/EditorCommandPalette.js.map +1 -0
  592. package/dist/vue/components/EditorCommandPalette.vue.d.ts +15 -0
  593. package/dist/vue/components/EditorSettingsModal.js +10 -6
  594. package/dist/vue/components/EditorSettingsModal.js.map +1 -1
  595. package/dist/vue/components/EditorSettingsModal.vue.d.ts +4 -4
  596. package/dist/vue/components/EditorSettingsPanel.js +10 -6
  597. package/dist/vue/components/EditorSettingsPanel.js.map +1 -1
  598. package/dist/vue/components/EditorSettingsPanel.vue.d.ts +6 -6
  599. package/dist/vue/components/EditorSurface.js +11 -6
  600. package/dist/vue/components/EditorSurface.js.map +1 -1
  601. package/dist/vue/components/EditorSurface.vue.d.ts +11 -11
  602. package/dist/vue/components/EditorToolbar.js +41 -49
  603. package/dist/vue/components/EditorToolbar.js.map +1 -1
  604. package/dist/vue/components/EditorToolbar.vue.d.ts +2 -4
  605. package/dist/vue/compose.d.ts +17 -0
  606. package/dist/vue/compose.js +51 -0
  607. package/dist/vue/compose.js.map +1 -0
  608. package/dist/vue/context-key.d.ts +6 -0
  609. package/dist/vue/context-key.js +6 -0
  610. package/dist/vue/context-key.js.map +1 -0
  611. package/dist/vue/context.d.ts +8 -6
  612. package/dist/vue/context.js +6 -5
  613. package/dist/vue/context.js.map +1 -1
  614. package/dist/vue/index.d.ts +10 -8
  615. package/dist/vue/index.js +10 -8
  616. package/dist/vue/kit/index.d.ts +2 -2
  617. package/dist/vue/kit/nuxt-ui.js +23 -0
  618. package/dist/vue/kit/nuxt-ui.js.map +1 -1
  619. package/dist/vue/kit/types.d.ts +40 -1
  620. package/package.json +30 -16
  621. package/dist/adapters/comments/client.d.ts +0 -64
  622. package/dist/adapters/comments/client.js.map +0 -1
  623. package/dist/adapters/routes.js.map +0 -1
  624. package/dist/core/toolbar.d.ts +0 -74
  625. package/dist/core/toolbar.js +0 -45
  626. package/dist/core/toolbar.js.map +0 -1
  627. package/dist/integrations/composite-ai/document-transcribe.d.ts +0 -14
  628. package/dist/integrations/composite-ai/document-transcribe.js +0 -89
  629. package/dist/integrations/composite-ai/document-transcribe.js.map +0 -1
  630. package/dist/nuxt/runtime/server/api/ai/chat.post.d.ts +0 -5
  631. package/dist/nuxt/runtime/server/api/ai/chat.post.js +0 -8
  632. package/dist/nuxt/runtime/server/api/ai/chat.post.js.map +0 -1
  633. package/dist/nuxt/runtime/server/api/ai/complete.post.d.ts +0 -5
  634. package/dist/nuxt/runtime/server/api/ai/complete.post.js +0 -8
  635. package/dist/nuxt/runtime/server/api/ai/complete.post.js.map +0 -1
  636. package/dist/nuxt/runtime/server/api/ai/generate.post.d.ts +0 -5
  637. package/dist/nuxt/runtime/server/api/ai/generate.post.js +0 -8
  638. package/dist/nuxt/runtime/server/api/ai/generate.post.js.map +0 -1
  639. package/dist/nuxt/runtime/server/api/ai/models.get.d.ts +0 -5
  640. package/dist/nuxt/runtime/server/api/ai/models.get.js +0 -8
  641. package/dist/nuxt/runtime/server/api/ai/models.get.js.map +0 -1
  642. package/dist/nuxt/runtime/server/api/ai/transcribe.post.d.ts +0 -5
  643. package/dist/nuxt/runtime/server/api/ai/transcribe.post.js +0 -8
  644. package/dist/nuxt/runtime/server/api/ai/transcribe.post.js.map +0 -1
  645. package/dist/nuxt/runtime/server/api/ai/transcript-cleanup.post.d.ts +0 -5
  646. package/dist/nuxt/runtime/server/api/ai/transcript-cleanup.post.js +0 -8
  647. package/dist/nuxt/runtime/server/api/ai/transcript-cleanup.post.js.map +0 -1
  648. package/dist/nuxt/runtime/server/api/editor/assets/[id]/[name].get.d.ts +0 -5
  649. package/dist/nuxt/runtime/server/api/editor/assets/[id]/[name].get.js +0 -8
  650. package/dist/nuxt/runtime/server/api/editor/assets/[id]/[name].get.js.map +0 -1
  651. package/dist/nuxt/runtime/server/api/editor/assets/[id].post.d.ts +0 -5
  652. package/dist/nuxt/runtime/server/api/editor/assets/[id].post.js +0 -8
  653. package/dist/nuxt/runtime/server/api/editor/assets/[id].post.js.map +0 -1
  654. package/dist/nuxt/runtime/server/api/editor/settings.get.d.ts +0 -5
  655. package/dist/nuxt/runtime/server/api/editor/settings.get.js +0 -8
  656. package/dist/nuxt/runtime/server/api/editor/settings.get.js.map +0 -1
  657. package/dist/nuxt/runtime/server/api/editor/settings.put.d.ts +0 -5
  658. package/dist/nuxt/runtime/server/api/editor/settings.put.js +0 -8
  659. package/dist/nuxt/runtime/server/api/editor/settings.put.js.map +0 -1
  660. package/dist/nuxt/runtime/server/api/editor/tags.get.d.ts +0 -5
  661. package/dist/nuxt/runtime/server/api/editor/tags.get.js +0 -8
  662. package/dist/nuxt/runtime/server/api/editor/tags.get.js.map +0 -1
  663. package/dist/nuxt/runtime/server/api/editor/themes/[id].delete.d.ts +0 -5
  664. package/dist/nuxt/runtime/server/api/editor/themes/[id].delete.js +0 -8
  665. package/dist/nuxt/runtime/server/api/editor/themes/[id].delete.js.map +0 -1
  666. package/dist/nuxt/runtime/server/api/editor/themes/[id].get.d.ts +0 -5
  667. package/dist/nuxt/runtime/server/api/editor/themes/[id].get.js +0 -8
  668. package/dist/nuxt/runtime/server/api/editor/themes/[id].get.js.map +0 -1
  669. package/dist/nuxt/runtime/server/api/editor/themes/index.get.d.ts +0 -5
  670. package/dist/nuxt/runtime/server/api/editor/themes/index.get.js +0 -8
  671. package/dist/nuxt/runtime/server/api/editor/themes/index.get.js.map +0 -1
  672. package/dist/nuxt/runtime/server/api/editor/themes/index.post.d.ts +0 -5
  673. package/dist/nuxt/runtime/server/api/editor/themes/index.post.js +0 -8
  674. package/dist/nuxt/runtime/server/api/editor/themes/index.post.js.map +0 -1
  675. package/dist/nuxt/runtime/server/api/editor/users.get.d.ts +0 -5
  676. package/dist/nuxt/runtime/server/api/editor/users.get.js +0 -8
  677. package/dist/nuxt/runtime/server/api/editor/users.get.js.map +0 -1
  678. package/dist/nuxt/runtime/server/plugins/collab.d.ts +0 -5
  679. package/dist/nuxt/runtime/server/plugins/collab.js +0 -10
  680. package/dist/nuxt/runtime/server/plugins/collab.js.map +0 -1
  681. package/dist/nuxt/runtime/server/routes/collab/[id].d.ts +0 -5
  682. package/dist/nuxt/runtime/server/routes/collab/[id].js +0 -35
  683. package/dist/nuxt/runtime/server/routes/collab/[id].js.map +0 -1
  684. package/dist/nuxt/runtime/server/utils/editor-route.d.ts +0 -11
  685. package/dist/nuxt/runtime/server/utils/editor-route.js.map +0 -1
  686. package/dist/presets/advanced.d.ts +0 -33
  687. package/dist/presets/advanced.js +0 -50
  688. package/dist/presets/advanced.js.map +0 -1
  689. package/dist/presets/simple.d.ts +0 -9
  690. package/dist/presets/simple.js +0 -12
  691. package/dist/presets/simple.js.map +0 -1
  692. package/dist/react/advanced-preset.d.ts +0 -11
  693. package/dist/react/advanced-preset.js +0 -31
  694. package/dist/react/advanced-preset.js.map +0 -1
  695. package/dist/vue/advanced-preset.d.ts +0 -13
  696. package/dist/vue/advanced-preset.js +0 -33
  697. package/dist/vue/advanced-preset.js.map +0 -1
  698. package/docs/extending.md +0 -538
  699. package/docs/integration.md +0 -630
  700. package/docs/llms.md +0 -383
  701. package/docs/usage.md +0 -1076
@@ -1,5 +1,5 @@
1
1
  import { Ability, AbilityRuleSource } from "./schema/abilities.js";
2
- import { MenuItem } from "./toolbar.js";
2
+ import { MenuItem } from "./command-types.js";
3
3
  import { Editor } from "@tiptap/core";
4
4
  import { Node as Node$1 } from "@tiptap/pm/model";
5
5
  //#region src/core/extension-points.d.ts
@@ -19,8 +19,8 @@ interface BlockActionBase {
19
19
  label: string;
20
20
  /** Iconify name, e.g. `i-lucide-copy`. */
21
21
  icon: string;
22
- /** Shown only on blocks that have this ability. */
23
- ability: Ability;
22
+ /** Shown only on blocks that have this ability; shown on every block when unset. */
23
+ ability?: Ability;
24
24
  /** Further condition; hidden when it returns false. */
25
25
  isVisible?: (ctx: BlockActionContext) => boolean;
26
26
  /** Position among the actions (ascending, stable); built-ins use their visual sequence, host actions follow them. */
@@ -37,18 +37,6 @@ export type BlockAction = BlockActionBase & ({
37
37
  menu: (ctx: BlockActionContext) => MenuItem[];
38
38
  run?: never;
39
39
  });
40
- /** A row of the `/` menu. */
41
- export interface SlashCommandItem {
42
- /** Typed after `/` (`/ai`); the query matches it or the label as prefix, case-insensitively. */
43
- id: string;
44
- label: string;
45
- /** Iconify name, e.g. `i-lucide-sparkles`. */
46
- icon: string;
47
- /** Runs once the `/query` text is deleted; the caret is then in the (now empty) textblock. */
48
- run: (editor: Editor) => void;
49
- /** Listed only where the caret has this ability; always listed when unset. */
50
- ability?: Ability;
51
- }
52
40
  export interface AbilitiesOptions {
53
41
  /** Abilities at document root, before any node rule applies. */
54
42
  root: readonly Ability[];
@@ -1,9 +1,11 @@
1
- import { AbilitiesOptions, BlockAction, SlashCommandItem } from "./extension-points.js";
2
1
  import { Notifier } from "./notify.js";
3
2
  import { EditorContext } from "./context.js";
3
+ import { CommandDef } from "./command-types.js";
4
+ import { AbilitiesOptions, BlockAction } from "./extension-points.js";
4
5
  import { EditorUi } from "./editor-ui.js";
5
6
  import { MetadataRegistry } from "./metadata.js";
6
- import { CollaborationSession, EditorPreset, FeatureContext, UploadFn } from "./feature.js";
7
+ import { CollaborationSession, EditorPreset, FeatureContext } from "./feature.js";
8
+ import "./commands.js";
7
9
  import { Editor } from "@tiptap/core";
8
10
  //#region src/core/feature-context.d.ts
9
11
  export interface FeatureContextOptions {
@@ -15,15 +17,14 @@ export interface FeatureContextOptions {
15
17
  notify: Notifier;
16
18
  getEditor: () => Editor | undefined;
17
19
  documentId?: string;
18
- upload?: UploadFn;
19
20
  collaboration?: CollaborationSession;
20
21
  abilities?: Partial<AbilitiesOptions>;
21
- /** Host transformer of the `/` menu: receives the features' commands, returns the final list. */
22
- slashCommands?: (defaults: SlashCommandItem[]) => SlashCommandItem[];
22
+ /** Host transformer of the command list (and with it the `/` menu): receives the features' commands, returns the final list. */
23
+ commands?: (defaults: CommandDef[]) => CommandDef[];
23
24
  }
24
25
  /**
25
- * The context of one mounted surface (see `FeatureContext`). Resolves the preset's anchor resolver and builds the `/`
26
- * menu lazily (features' commands, then the host's transformer), once. Call it during component setup.
26
+ * The context of one mounted surface (see `FeatureContext`). Resolves the preset's anchor resolver and builds the command
27
+ * list lazily (features' commands, then the host's transformer), once. Call it during component setup.
27
28
  */
28
29
  export declare function createFeatureContext(options: FeatureContextOptions): FeatureContext;
29
30
  /** The features' block actions in `order` (stable), followed by the host's. */
@@ -1,13 +1,14 @@
1
+ import { byOrder } from "./util.js";
1
2
  import { contributions } from "./define-editor.js";
3
+ import { assertUniqueCommandIds, commandsOf } from "./commands.js";
2
4
  //#region src/core/feature-context.ts
3
- const byOrder = (a, b) => (a.order ?? 0) - (b.order ?? 0);
4
5
  /**
5
- * The context of one mounted surface (see `FeatureContext`). Resolves the preset's anchor resolver and builds the `/`
6
- * menu lazily (features' commands, then the host's transformer), once. Call it during component setup.
6
+ * The context of one mounted surface (see `FeatureContext`). Resolves the preset's anchor resolver and builds the command
7
+ * list lazily (features' commands, then the host's transformer), once. Call it during component setup.
7
8
  */
8
9
  function createFeatureContext(options) {
9
10
  const { app, preset } = options;
10
- let slash;
11
+ let list;
11
12
  const ctx = {
12
13
  app,
13
14
  settings: app.settings,
@@ -16,19 +17,19 @@ function createFeatureContext(options) {
16
17
  notify: options.notify,
17
18
  locale: app.locale,
18
19
  t: app.t,
19
- fetch: app.fetch,
20
+ backend: app.backend,
20
21
  ai: app.ai,
21
22
  documentId: options.documentId,
22
- upload: options.upload,
23
23
  collaboration: options.collaboration,
24
24
  anchorResolver: null,
25
25
  abilities: options.abilities ?? {},
26
- slashCommands: () => {
27
- if (!slash) {
28
- const defaults = contributions(preset, "slashCommands").flatMap((factory) => factory(ctx));
29
- slash = options.slashCommands ? options.slashCommands(defaults) : defaults;
26
+ commands: () => {
27
+ if (!list) {
28
+ const defaults = commandsOf(preset, ctx);
29
+ list = options.commands ? options.commands(defaults) : defaults;
30
+ if (options.commands) assertUniqueCommandIds(list);
30
31
  }
31
- return slash;
32
+ return list;
32
33
  },
33
34
  getEditor: options.getEditor
34
35
  };
@@ -1 +1 @@
1
- {"version":3,"file":"feature-context.js","names":[],"sources":["../../src/core/feature-context.ts"],"sourcesContent":["import type { Editor } from '@tiptap/core'\nimport type { EditorContext } from './context'\nimport { contributions } from './define-editor'\nimport type { EditorUi } from './editor-ui'\nimport type { AbilitiesOptions, BlockAction, SlashCommandItem } from './extension-points'\nimport type { CollaborationSession, EditorPreset, FeatureContext, UploadFn } from './feature'\nimport type { MetadataRegistry } from './metadata'\nimport type { Notifier } from './notify'\n\nexport interface FeatureContextOptions {\n app: EditorContext\n preset: EditorPreset\n ui: EditorUi\n metadata: MetadataRegistry\n /** The surface's notice renderer (Nuxt UI toast, sonner). */\n notify: Notifier\n getEditor: () => Editor | undefined\n documentId?: string\n upload?: UploadFn\n collaboration?: CollaborationSession\n abilities?: Partial<AbilitiesOptions>\n /** Host transformer of the `/` menu: receives the features' commands, returns the final list. */\n slashCommands?: (defaults: SlashCommandItem[]) => SlashCommandItem[]\n}\n\nconst byOrder = <T extends { order?: number }>(a: T, b: T) => (a.order ?? 0) - (b.order ?? 0)\n\n/**\n * The context of one mounted surface (see `FeatureContext`). Resolves the preset's anchor resolver and builds the `/`\n * menu lazily (features' commands, then the host's transformer), once. Call it during component setup.\n */\nexport function createFeatureContext(options: FeatureContextOptions): FeatureContext {\n const { app, preset } = options\n let slash: SlashCommandItem[] | undefined\n const ctx: { -readonly [K in keyof FeatureContext]: FeatureContext[K] } = {\n app,\n settings: app.settings,\n metadata: options.metadata,\n ui: options.ui,\n notify: options.notify,\n locale: app.locale,\n t: app.t,\n fetch: app.fetch,\n ai: app.ai,\n documentId: options.documentId,\n upload: options.upload,\n collaboration: options.collaboration,\n anchorResolver: null,\n abilities: options.abilities ?? {},\n slashCommands: () => {\n if (!slash) {\n const defaults = contributions(preset, 'slashCommands').flatMap(factory => factory(ctx))\n slash = options.slashCommands ? options.slashCommands(defaults) : defaults\n }\n return slash\n },\n getEditor: options.getEditor,\n }\n ctx.anchorResolver = contributions(preset, 'anchorResolver')[0]?.(ctx) ?? null\n for (const defaults of contributions(preset, 'metadataDefaults')) ctx.metadata.defaults(defaults(ctx))\n return ctx\n}\n\n/** The features' block actions in `order` (stable), followed by the host's. */\nexport function blockActionsOf(preset: EditorPreset, ctx: FeatureContext, hostActions: readonly BlockAction[] = []): BlockAction[] {\n return [...contributions(preset, 'blockActions').flatMap(factory => factory(ctx)).sort(byOrder), ...hostActions]\n}\n"],"mappings":";;AAyBA,MAAM,WAAyC,GAAM,OAAU,EAAE,SAAS,MAAM,EAAE,SAAS;;;;;AAM3F,SAAgB,qBAAqB,SAAgD;CACnF,MAAM,EAAE,KAAK,WAAW;CACxB,IAAI;CACJ,MAAM,MAAoE;EACxE;EACA,UAAU,IAAI;EACd,UAAU,QAAQ;EAClB,IAAI,QAAQ;EACZ,QAAQ,QAAQ;EAChB,QAAQ,IAAI;EACZ,GAAG,IAAI;EACP,OAAO,IAAI;EACX,IAAI,IAAI;EACR,YAAY,QAAQ;EACpB,QAAQ,QAAQ;EAChB,eAAe,QAAQ;EACvB,gBAAgB;EAChB,WAAW,QAAQ,aAAa,CAAC;EACjC,qBAAqB;GACnB,IAAI,CAAC,OAAO;IACV,MAAM,WAAW,cAAc,QAAQ,eAAe,CAAC,CAAC,SAAQ,YAAW,QAAQ,GAAG,CAAC;IACvF,QAAQ,QAAQ,gBAAgB,QAAQ,cAAc,QAAQ,IAAI;GACpE;GACA,OAAO;EACT;EACA,WAAW,QAAQ;CACrB;CACA,IAAI,iBAAiB,cAAc,QAAQ,gBAAgB,CAAC,CAAC,EAAE,GAAG,GAAG,KAAK;CAC1E,KAAK,MAAM,YAAY,cAAc,QAAQ,kBAAkB,GAAG,IAAI,SAAS,SAAS,SAAS,GAAG,CAAC;CACrG,OAAO;AACT;;AAGA,SAAgB,eAAe,QAAsB,KAAqB,cAAsC,CAAC,GAAkB;CACjI,OAAO,CAAC,GAAG,cAAc,QAAQ,cAAc,CAAC,CAAC,SAAQ,YAAW,QAAQ,GAAG,CAAC,CAAC,CAAC,KAAK,OAAO,GAAG,GAAG,WAAW;AACjH"}
1
+ {"version":3,"file":"feature-context.js","names":[],"sources":["../../src/core/feature-context.ts"],"sourcesContent":["import type { Editor } from '@tiptap/core'\nimport type { EditorContext } from './context'\nimport { assertUniqueCommandIds, type CommandDef, commandsOf } from './commands'\nimport { contributions } from './define-editor'\nimport type { EditorUi } from './editor-ui'\nimport type { AbilitiesOptions, BlockAction } from './extension-points'\nimport type { CollaborationSession, EditorPreset, FeatureContext } from './feature'\nimport type { MetadataRegistry } from './metadata'\nimport type { Notifier } from './notify'\nimport { byOrder } from './util'\n\nexport interface FeatureContextOptions {\n app: EditorContext\n preset: EditorPreset\n ui: EditorUi\n metadata: MetadataRegistry\n /** The surface's notice renderer (Nuxt UI toast, sonner). */\n notify: Notifier\n getEditor: () => Editor | undefined\n documentId?: string\n collaboration?: CollaborationSession\n abilities?: Partial<AbilitiesOptions>\n /** Host transformer of the command list (and with it the `/` menu): receives the features' commands, returns the final list. */\n commands?: (defaults: CommandDef[]) => CommandDef[]\n}\n\n/**\n * The context of one mounted surface (see `FeatureContext`). Resolves the preset's anchor resolver and builds the command\n * list lazily (features' commands, then the host's transformer), once. Call it during component setup.\n */\nexport function createFeatureContext(options: FeatureContextOptions): FeatureContext {\n const { app, preset } = options\n let list: CommandDef[] | undefined\n const ctx: { -readonly [K in keyof FeatureContext]: FeatureContext[K] } = {\n app,\n settings: app.settings,\n metadata: options.metadata,\n ui: options.ui,\n notify: options.notify,\n locale: app.locale,\n t: app.t,\n backend: app.backend,\n ai: app.ai,\n documentId: options.documentId,\n collaboration: options.collaboration,\n anchorResolver: null,\n abilities: options.abilities ?? {},\n commands: () => {\n if (!list) {\n const defaults = commandsOf(preset, ctx)\n list = options.commands ? options.commands(defaults) : defaults\n if (options.commands) assertUniqueCommandIds(list)\n }\n return list\n },\n getEditor: options.getEditor,\n }\n ctx.anchorResolver = contributions(preset, 'anchorResolver')[0]?.(ctx) ?? null\n for (const defaults of contributions(preset, 'metadataDefaults')) ctx.metadata.defaults(defaults(ctx))\n return ctx\n}\n\n/** The features' block actions in `order` (stable), followed by the host's. */\nexport function blockActionsOf(preset: EditorPreset, ctx: FeatureContext, hostActions: readonly BlockAction[] = []): BlockAction[] {\n return [...contributions(preset, 'blockActions').flatMap(factory => factory(ctx)).sort(byOrder), ...hostActions]\n}\n"],"mappings":";;;;;;;;AA8BA,SAAgB,qBAAqB,SAAgD;CACnF,MAAM,EAAE,KAAK,WAAW;CACxB,IAAI;CACJ,MAAM,MAAoE;EACxE;EACA,UAAU,IAAI;EACd,UAAU,QAAQ;EAClB,IAAI,QAAQ;EACZ,QAAQ,QAAQ;EAChB,QAAQ,IAAI;EACZ,GAAG,IAAI;EACP,SAAS,IAAI;EACb,IAAI,IAAI;EACR,YAAY,QAAQ;EACpB,eAAe,QAAQ;EACvB,gBAAgB;EAChB,WAAW,QAAQ,aAAa,CAAC;EACjC,gBAAgB;GACd,IAAI,CAAC,MAAM;IACT,MAAM,WAAW,WAAW,QAAQ,GAAG;IACvC,OAAO,QAAQ,WAAW,QAAQ,SAAS,QAAQ,IAAI;IACvD,IAAI,QAAQ,UAAU,uBAAuB,IAAI;GACnD;GACA,OAAO;EACT;EACA,WAAW,QAAQ;CACrB;CACA,IAAI,iBAAiB,cAAc,QAAQ,gBAAgB,CAAC,CAAC,EAAE,GAAG,GAAG,KAAK;CAC1E,KAAK,MAAM,YAAY,cAAc,QAAQ,kBAAkB,GAAG,IAAI,SAAS,SAAS,SAAS,GAAG,CAAC;CACrG,OAAO;AACT;;AAGA,SAAgB,eAAe,QAAsB,KAAqB,cAAsC,CAAC,GAAkB;CACjI,OAAO,CAAC,GAAG,cAAc,QAAQ,cAAc,CAAC,CAAC,SAAQ,YAAW,QAAQ,GAAG,CAAC,CAAC,CAAC,KAAK,OAAO,GAAG,GAAG,WAAW;AACjH"}
@@ -1,25 +1,22 @@
1
- import { ToolbarGroup } from "./toolbar.js";
2
- import { AbilitiesOptions, BlockAction, SlashCommandItem } from "./extension-points.js";
3
- import { ConvertTarget } from "./convert.js";
1
+ import { Store } from "./store.js";
4
2
  import { Locale, Translate } from "../i18n/index.js";
5
3
  import { EditorSettings } from "../settings/index.js";
4
+ import { BackendCapability } from "./backend-capability.js";
5
+ import { EditorBackend } from "./backend.js";
6
6
  import { Notifier } from "./notify.js";
7
- import { Store } from "./store.js";
8
7
  import { EditorAiConfig, EditorContext } from "./context.js";
8
+ import { ConvertTarget } from "./convert.js";
9
+ import { CommandDef, InsertGuard, ToolbarGroupDef } from "./command-types.js";
10
+ import { AbilitiesOptions, BlockAction } from "./extension-points.js";
9
11
  import { EditorUi } from "./editor-ui.js";
10
12
  import { EditorMetadata } from "./metadata-types.js";
11
13
  import { MetadataRegistry } from "./metadata.js";
12
14
  import { AnyExtension, Editor, JSONContent } from "@tiptap/core";
13
15
  import { EditorState, Transaction } from "@tiptap/pm/state";
14
16
  import { Node as Node$1, ResolvedPos } from "@tiptap/pm/model";
15
- import { $Fetch } from "ofetch";
16
- import * as Y from "yjs";
17
17
  import { HocuspocusProvider } from "@hocuspocus/provider";
18
+ import * as Y from "yjs";
18
19
  //#region src/core/feature.d.ts
19
- /** Stores an uploaded file and returns its URL (media feature). */
20
- export type UploadFn = (file: File) => Promise<{
21
- url: string;
22
- }>;
23
20
  /**
24
21
  * The user writing in an editor: the collaboration session's `user`, labelled on remote carets, and (authors and comments
25
22
  * features) copied into the author mark of every text run and into every comment the user writes.
@@ -35,7 +32,7 @@ export interface CollaborationSession {
35
32
  provider?: HocuspocusProvider;
36
33
  user?: AuthorIdentity;
37
34
  /**
38
- * Token the collaboration server's `EditorAdapter.authenticate` receives (`{ headers, token }`), for clients without
35
+ * Token the collaboration server's `Identity.authenticate` receives (`{ headers, token }`), for clients without
39
36
  * the session cookie of the server's origin (scripts, agents, cross-origin hosts). A string, or a function called
40
37
  * every time the socket opens (so it can refresh an expired token). Applied to `provider`'s configuration when the
41
38
  * surface is set up, which the provider reads when its socket opens: create the provider and mount the surface in the
@@ -79,19 +76,19 @@ export interface FeatureContext {
79
76
  readonly locale: Locale;
80
77
  /** Renders a catalog message in the app's language; every label a feature contributes goes through it. */
81
78
  readonly t: Translate;
82
- readonly fetch: $Fetch;
79
+ /** The data layer of the app (`createEditorContext({ backend })`): uploads, mention lookups, themes, AI. */
80
+ readonly backend: EditorBackend;
83
81
  /** Inert public AI configuration of the app context; absent when none was supplied. */
84
82
  readonly ai: EditorAiConfig | undefined;
85
83
  /** Document whose package stores uploads (media feature). */
86
84
  readonly documentId: string | undefined;
87
- readonly upload: UploadFn | undefined;
88
85
  readonly collaboration: CollaborationSession | undefined;
89
86
  /** The collaboration-aware position mapping of the preset's `anchorResolver` feature; null means local mapping only. */
90
87
  readonly anchorResolver: AnchorResolver | null;
91
88
  /** Host options for the ability extension (`abilities` prop). */
92
89
  readonly abilities: Partial<AbilitiesOptions>;
93
- /** The final `/` menu (features' commands run through the host's `slashCommands` transformer). */
94
- readonly slashCommands: () => SlashCommandItem[];
90
+ /** The final command list: the features' commands after the host's `commands` transformer. The `/` menu lists the ones with a `slash` placement. */
91
+ readonly commands: () => CommandDef[];
95
92
  /** Undefined while extensions are constructed; set once the editor exists. Use it in event handlers. */
96
93
  getEditor: () => Editor | undefined;
97
94
  }
@@ -149,7 +146,7 @@ export interface AiContextKind {
149
146
  fields: readonly {
150
147
  key: string;
151
148
  label: string;
152
- type?: 'text' | 'textarea' | 'date' | 'number' | 'select';
149
+ type?: 'text' | 'textarea' | 'date' | 'number' | 'select' | 'reference' | 'bibliography' | 'derivation';
153
150
  options?: readonly {
154
151
  value: string;
155
152
  label: string;
@@ -187,15 +184,34 @@ export interface AiBlockDataRequest {
187
184
  }
188
185
  /** Material for one block; `signal` aborts when the editor is destroyed or the run is cancelled. */
189
186
  export type AiBlockDataProvider = (request: AiBlockDataRequest) => Promise<readonly AiBlockDatum[]> | readonly AiBlockDatum[];
190
- /** One independently importable capability. Every member is optional; identity and ordering come from the feature list. */
187
+ /**
188
+ * The axis a feature belongs to: `content` (nodes, marks and structure rules the document stores: the server schema comes
189
+ * from here), `interaction` (editing UX, backend-bound UI such as comments and collaboration) or `ai`. A feature
190
+ * belongs to the dimension without which it makes no sense.
191
+ */
192
+ export type Dimension = 'content' | 'interaction' | 'ai';
193
+ /** One named contribution to an editor (blocks, toolbar entries, menus, settings, AI knowledge). Every member is optional but `dimension`; identity and ordering come from the feature list. */
191
194
  export interface EditorFeature<C = unknown> {
192
195
  id: string;
196
+ /** The feature's primary dimension. */
197
+ dimension: Dimension;
198
+ /**
199
+ * The Vue-free schema-bearing extensions of this feature (no node views, no UI), collected by `schemaExtensionsOf` for
200
+ * the server schema. Present on every feature whose nodes or marks the stored document can contain.
201
+ */
202
+ schemaExtensions?: () => AnyExtension[];
193
203
  /** Ids of features that must also be installed (`defineEditor` does not install them). */
194
204
  requires?: readonly string[];
205
+ /** Backend capabilities the feature cannot work without; a surface session over a backend lacking one throws. Optional capabilities (users and tags for mentions) are not listed. */
206
+ backend?: readonly BackendCapability[];
195
207
  extensions?: (ctx: FeatureContext) => AnyExtension[];
196
- toolbar?: (ctx: FeatureContext) => ToolbarGroup<C>[];
197
208
  blockActions?: (ctx: FeatureContext) => BlockAction[];
198
- slashCommands?: (ctx: FeatureContext) => SlashCommandItem[];
209
+ /** The feature's commands, each declared once with its toolbar and `/` placements (see `CommandDef`). */
210
+ commands?: (ctx: FeatureContext) => CommandDef<C>[];
211
+ /** Toolbar groups the feature declares; every command's `toolbar.group` must be declared by some feature. Ids are unique across features. */
212
+ toolbarGroups?: ToolbarGroupDef[];
213
+ /** Rules a command's `creates` must pass at the caret besides the schema (e.g. a Baustein's accepted children). */
214
+ insertGuards?: (ctx: FeatureContext) => InsertGuard[];
199
215
  /** Components mounted beside the editor content; they receive `{ editor }`. `C` is the component type of the framework layer that renders them. */
200
216
  overlays?: readonly C[];
201
217
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"feature.js","names":[],"sources":["../../src/core/feature.ts"],"sourcesContent":["import type { HocuspocusProvider } from '@hocuspocus/provider'\nimport type { AnyExtension, Editor, JSONContent } from '@tiptap/core'\nimport type { Node as PMNode, ResolvedPos } from '@tiptap/pm/model'\nimport type { EditorState, Transaction } from '@tiptap/pm/state'\nimport type { $Fetch } from 'ofetch'\nimport type * as Y from 'yjs'\nimport type { Locale, Translate } from '../i18n'\nimport type { EditorSettings } from '../settings'\nimport type { EditorAiConfig, EditorContext } from './context'\nimport type { ConvertTarget } from './convert'\nimport type { EditorUi } from './editor-ui'\nimport type { AbilitiesOptions, BlockAction, SlashCommandItem } from './extension-points'\nimport type { MetadataRegistry } from './metadata'\nimport type { Notifier } from './notify'\nimport type { EditorMetadata } from './metadata-types'\nimport type { Store } from './store'\nimport type { ToolbarGroup } from './toolbar'\n\n// The composition contracts: an `EditorFeature` contributes extensions and descriptors, `defineEditor` validates a\n// feature list into an immutable `EditorPreset`, and `EditorSurface` mounts one. Everything here is inert data and\n// types; features only differ by which of these seams they fill.\n\n/** Stores an uploaded file and returns its URL (media feature). */\nexport type UploadFn = (file: File) => Promise<{ url: string }>\n\n/**\n * The user writing in an editor: the collaboration session's `user`, labelled on remote carets, and (authors and comments\n * features) copied into the author mark of every text run and into every comment the user writes.\n */\nexport interface AuthorIdentity {\n id: string\n name: string\n color: string\n}\n\n/** A host-owned collaboration session handed to the surface; only the collab feature turns it into extensions. */\nexport interface CollaborationSession {\n ydoc: Y.Doc\n provider?: HocuspocusProvider\n user?: AuthorIdentity\n /**\n * Token the collaboration server's `EditorAdapter.authenticate` receives (`{ headers, token }`), for clients without\n * the session cookie of the server's origin (scripts, agents, cross-origin hosts). A string, or a function called\n * every time the socket opens (so it can refresh an expired token). Applied to `provider`'s configuration when the\n * surface is set up, which the provider reads when its socket opens: create the provider and mount the surface in the\n * same tick, or give the provider its own `token` option instead.\n */\n token?: string | (() => string) | (() => Promise<string>)\n}\n\n/**\n * A mapping between document positions and positions that survive collaborative edits. The collab feature supplies\n * the Yjs implementation; without one, `DocAnchors` maps positions through local transactions only.\n */\nexport interface AnchorResolver {\n /** The transaction applies a Yjs change to the document: remote edits and Yjs undo/redo. */\n isYSync: (tr: Transaction) => boolean\n /** The transaction applies an edit of another client (excludes Yjs undo/redo). */\n isRemoteChange: (tr: Transaction) => boolean\n /** Opaque token of `range` that `resolve` can turn back into positions after remote changes; null when unavailable. */\n capture: (state: EditorState, range: { from: number, to: number }, startInside: boolean) => unknown | null\n resolve: (state: EditorState, token: unknown) => { from: number, to: number } | null\n /** Stops undo capturing around a programmatic change; true iff a Yjs undo manager exists. */\n stopUndoCapture: (state: EditorState) => boolean\n}\n\n/** Per-surface dependencies of a feature's factories. Created when a surface is set up; never shared between editors. */\nexport interface FeatureContext {\n /** The app context the surface belongs to (shared by all editors of the app): app-level models key on it. */\n readonly app: EditorContext\n /** The app's shared settings (see `createEditorContext`): read with `get()`, write with `update()`, observe with `subscribe()`. */\n readonly settings: Store<EditorSettings>\n readonly metadata: MetadataRegistry\n /** Chrome of the editor this context belongs to (settings, sidebar). */\n readonly ui: EditorUi\n /** Shows a notice through the surface's framework (Nuxt UI toast, sonner). */\n readonly notify: Notifier\n /** The app's UI language (`createEditorContext({ locale })`). */\n readonly locale: Locale\n /** Renders a catalog message in the app's language; every label a feature contributes goes through it. */\n readonly t: Translate\n readonly fetch: $Fetch\n /** Inert public AI configuration of the app context; absent when none was supplied. */\n readonly ai: EditorAiConfig | undefined\n /** Document whose package stores uploads (media feature). */\n readonly documentId: string | undefined\n readonly upload: UploadFn | undefined\n readonly collaboration: CollaborationSession | undefined\n /** The collaboration-aware position mapping of the preset's `anchorResolver` feature; null means local mapping only. */\n readonly anchorResolver: AnchorResolver | null\n /** Host options for the ability extension (`abilities` prop). */\n readonly abilities: Partial<AbilitiesOptions>\n /** The final `/` menu (features' commands run through the host's `slashCommands` transformer). */\n readonly slashCommands: () => SlashCommandItem[]\n /** Undefined while extensions are constructed; set once the editor exists. Use it in event handlers. */\n getEditor: () => Editor | undefined\n}\n\n/** A tab of the settings panel/modal, contributed by the feature that owns those settings. */\nexport interface SettingsTab<C = unknown> {\n id: string\n /** Already translated (`ctx.t(...)` in the feature's `settingsTabs` factory). */\n label: string\n icon?: string\n component: C\n /** Props handed to `component`, e.g. the configured composite kinds. */\n props?: Record<string, unknown>\n}\n\n/** The stages `parseBlocks` and the import/AI insertion paths run; features replace stages, defaults are identity/Markdown. */\nexport interface BlockPipeline {\n parseMarkdown: (editor: Editor, markdown: string) => JSONContent[]\n normalize: (editor: Editor, blocks: JSONContent[]) => JSONContent[]\n segment: (editor: Editor, blocks: JSONContent[]) => JSONContent[]\n structure: (editor: Editor, blocks: JSONContent[]) => JSONContent[]\n wrapImport: (editor: Editor, file: File, blocks: JSONContent[]) => JSONContent[]\n migrateContent: (content: JSONContent) => JSONContent\n}\n\n/** Pipeline hooks that allow a single contributor; `normalize` chains instead. */\nexport const SINGLETON_PIPELINE_HOOKS = ['parseMarkdown', 'segment', 'structure', 'wrapImport', 'migrateContent'] as const satisfies readonly (keyof BlockPipeline)[]\n\n/**\n * A feature's block conversions. Targets keep the inert `ConvertTarget` shapes; the provider that parses a target id\n * owns that target (labels, execution). `handlesSource` claims all conversions of source blocks it understands.\n */\nexport interface ConversionProvider {\n /** Source blocks this provider converts to any target it can; the first provider claiming a node executes. */\n handlesSource?: (node: PMNode) => boolean\n /** Targets offered for `node` in menus (excluding its current type). */\n targets: (editor: Editor, node: PMNode) => ConvertTarget[]\n /** The target of `id` when this provider owns it, else null. */\n parseTarget: (id: string) => ConvertTarget | null\n /** Menu label (in the language of `t`) and icon of a target this provider owns. */\n label: (target: ConvertTarget, t: Translate) => { label: string, icon: string } | null\n /** The conversion of the block after `start` into `target` (absolute range replaced and the converted blocks), or null. */\n convert: (state: EditorState, start: ResolvedPos, target: ConvertTarget) => { from: number, to: number, blocks: PMNode[] } | null\n}\n\n/**\n * Inert public data AI reads about the editor's document model. A kind's `fields` carry what the model needs to write\n * them (`type`, and the choices of a `select`).\n */\nexport interface AiContextKind {\n id: string\n label: string\n fields: readonly { key: string, label: string, type?: 'text' | 'textarea' | 'date' | 'number' | 'select', options?: readonly { value: string, label: string }[] }[]\n /** The kind's `ai.purpose`, when configured. */\n purpose?: string\n}\n\n/** A host block as AI learns it: what it is for, its Markdown form and one example. `id` is the node type name and the `convert` target id. */\nexport interface AiBlock {\n id: string\n label: string\n /** One or two German sentences: purpose and what it may contain. */\n description: string\n /** The Markdown form, placeholders in angle brackets, e.g. `!!! <info|warning|success>\\n<Inhalt>`. */\n syntax: string\n /** One complete Markdown example of the block. */\n example: string\n}\n\nexport interface AiContext {\n kinds?: readonly AiContextKind[]\n blocks?: readonly AiBlock[]\n structure?: 'flat' | 'composite'\n}\n\n/** One piece of material a feature fetched for a block before the model fills it (a host's examples, a record). */\nexport interface AiBlockDatum { label: string, text: string }\nexport interface AiBlockDataRequest { editor: Editor, node: PMNode, pos: number, signal: AbortSignal }\n/** Material for one block; `signal` aborts when the editor is destroyed or the run is cancelled. */\nexport type AiBlockDataProvider = (request: AiBlockDataRequest) => Promise<readonly AiBlockDatum[]> | readonly AiBlockDatum[]\n\n/** One independently importable capability. Every member is optional; identity and ordering come from the feature list. */\nexport interface EditorFeature<C = unknown> {\n id: string\n /** Ids of features that must also be installed (`defineEditor` does not install them). */\n requires?: readonly string[]\n extensions?: (ctx: FeatureContext) => AnyExtension[]\n toolbar?: (ctx: FeatureContext) => ToolbarGroup<C>[]\n blockActions?: (ctx: FeatureContext) => BlockAction[]\n slashCommands?: (ctx: FeatureContext) => SlashCommandItem[]\n /** Components mounted beside the editor content; they receive `{ editor }`. `C` is the component type of the framework layer that renders them. */\n overlays?: readonly C[]\n /**\n * Runs once when a surface mounts (per-app side effects, e.g. a theme runtime; dedupe inside). Returns the teardown,\n * called when the surface unmounts; it must be idempotent (React StrictMode mounts twice).\n */\n setup?: (ctx: FeatureContext) => void | (() => void)\n /** The feature's settings tabs. A factory over the app context, so labels render in the context's language. */\n settingsTabs?: (ctx: EditorContext) => readonly SettingsTab<C>[]\n /** Built-in metadata lists (`mentions`, `hashtags`, `speakers`, …) used for every list name the host does not supply; searched only when a suggestion uses them. */\n metadataDefaults?: (ctx: FeatureContext) => EditorMetadata\n blocks?: Partial<BlockPipeline>\n conversions?: readonly ConversionProvider[]\n /** At most one contributor: supplies the collaboration-aware position mapping to `DocAnchors`. */\n anchorResolver?: (ctx: FeatureContext) => AnchorResolver\n /** Additive: the contributions of all features are merged (`kinds` and `blocks` concatenated in feature order; `structure` may be set by one feature only). Reads AI's view of the document model. */\n aiContext?: (editor: Editor) => AiContext\n /** Additive: every contributor runs for the block (in parallel), their data concatenate in feature order; one rejection fails the whole fill. Read by „Baustein füllen (KI)“. */\n aiBlockData?: AiBlockDataProvider\n /** At most one contributor: formats an AI result's markdown before the generic pipeline. */\n formatAiResult?: (editor: Editor, markdown: string, heading?: string) => string\n}\n\n/** An immutable, validated feature list with its resolved pipeline, conversion providers and AI hooks. */\nexport interface EditorPreset<C = unknown> {\n readonly features: readonly EditorFeature<C>[]\n readonly pipeline: BlockPipeline\n readonly conversions: readonly ConversionProvider[]\n /** All `aiContext` contributions merged (`aiContextOf`). */\n readonly aiContext?: EditorFeature['aiContext']\n /** All `aiBlockData` contributions merged (`aiBlockDataOf`). */\n readonly aiBlockData?: AiBlockDataProvider\n /** The single `formatAiResult` contributor, if any. */\n readonly formatAiResult?: EditorFeature['formatAiResult']\n}\n"],"mappings":";;AAwHA,MAAa,2BAA2B;CAAC;CAAiB;CAAW;CAAa;CAAc;AAAgB"}
1
+ {"version":3,"file":"feature.js","names":[],"sources":["../../src/core/feature.ts"],"sourcesContent":["import type { HocuspocusProvider } from '@hocuspocus/provider'\nimport type { AnyExtension, Editor, JSONContent } from '@tiptap/core'\nimport type { Node as PMNode, ResolvedPos } from '@tiptap/pm/model'\nimport type { EditorState, Transaction } from '@tiptap/pm/state'\nimport type * as Y from 'yjs'\nimport type { Locale, Translate } from '../i18n'\nimport type { EditorSettings } from '../settings'\nimport type { EditorBackend } from './backend'\nimport type { BackendCapability } from './backend-capability'\nimport type { EditorAiConfig, EditorContext } from './context'\nimport type { ConvertTarget } from './convert'\nimport type { EditorUi } from './editor-ui'\nimport type { AbilitiesOptions, BlockAction } from './extension-points'\nimport type { MetadataRegistry } from './metadata'\nimport type { CommandDef, InsertGuard, ToolbarGroupDef } from './command-types'\nimport type { Notifier } from './notify'\nimport type { EditorMetadata } from './metadata-types'\nimport type { Store } from './store'\n\n// The composition contracts: an `EditorFeature` contributes extensions and descriptors, `defineEditor` validates a\n// feature list into an immutable `EditorPreset`, and `EditorSurface` mounts one. Everything here is inert data and\n// types; features only differ by which of these seams they fill.\n\n/**\n * The user writing in an editor: the collaboration session's `user`, labelled on remote carets, and (authors and comments\n * features) copied into the author mark of every text run and into every comment the user writes.\n */\nexport interface AuthorIdentity {\n id: string\n name: string\n color: string\n}\n\n/** A host-owned collaboration session handed to the surface; only the collab feature turns it into extensions. */\nexport interface CollaborationSession {\n ydoc: Y.Doc\n provider?: HocuspocusProvider\n user?: AuthorIdentity\n /**\n * Token the collaboration server's `Identity.authenticate` receives (`{ headers, token }`), for clients without\n * the session cookie of the server's origin (scripts, agents, cross-origin hosts). A string, or a function called\n * every time the socket opens (so it can refresh an expired token). Applied to `provider`'s configuration when the\n * surface is set up, which the provider reads when its socket opens: create the provider and mount the surface in the\n * same tick, or give the provider its own `token` option instead.\n */\n token?: string | (() => string) | (() => Promise<string>)\n}\n\n/**\n * A mapping between document positions and positions that survive collaborative edits. The collab feature supplies\n * the Yjs implementation; without one, `DocAnchors` maps positions through local transactions only.\n */\nexport interface AnchorResolver {\n /** The transaction applies a Yjs change to the document: remote edits and Yjs undo/redo. */\n isYSync: (tr: Transaction) => boolean\n /** The transaction applies an edit of another client (excludes Yjs undo/redo). */\n isRemoteChange: (tr: Transaction) => boolean\n /** Opaque token of `range` that `resolve` can turn back into positions after remote changes; null when unavailable. */\n capture: (state: EditorState, range: { from: number, to: number }, startInside: boolean) => unknown | null\n resolve: (state: EditorState, token: unknown) => { from: number, to: number } | null\n /** Stops undo capturing around a programmatic change; true iff a Yjs undo manager exists. */\n stopUndoCapture: (state: EditorState) => boolean\n}\n\n/** Per-surface dependencies of a feature's factories. Created when a surface is set up; never shared between editors. */\nexport interface FeatureContext {\n /** The app context the surface belongs to (shared by all editors of the app): app-level models key on it. */\n readonly app: EditorContext\n /** The app's shared settings (see `createEditorContext`): read with `get()`, write with `update()`, observe with `subscribe()`. */\n readonly settings: Store<EditorSettings>\n readonly metadata: MetadataRegistry\n /** Chrome of the editor this context belongs to (settings, sidebar). */\n readonly ui: EditorUi\n /** Shows a notice through the surface's framework (Nuxt UI toast, sonner). */\n readonly notify: Notifier\n /** The app's UI language (`createEditorContext({ locale })`). */\n readonly locale: Locale\n /** Renders a catalog message in the app's language; every label a feature contributes goes through it. */\n readonly t: Translate\n /** The data layer of the app (`createEditorContext({ backend })`): uploads, mention lookups, themes, AI. */\n readonly backend: EditorBackend\n /** Inert public AI configuration of the app context; absent when none was supplied. */\n readonly ai: EditorAiConfig | undefined\n /** Document whose package stores uploads (media feature). */\n readonly documentId: string | undefined\n readonly collaboration: CollaborationSession | undefined\n /** The collaboration-aware position mapping of the preset's `anchorResolver` feature; null means local mapping only. */\n readonly anchorResolver: AnchorResolver | null\n /** Host options for the ability extension (`abilities` prop). */\n readonly abilities: Partial<AbilitiesOptions>\n /** The final command list: the features' commands after the host's `commands` transformer. The `/` menu lists the ones with a `slash` placement. */\n readonly commands: () => CommandDef[]\n /** Undefined while extensions are constructed; set once the editor exists. Use it in event handlers. */\n getEditor: () => Editor | undefined\n}\n\n/** A tab of the settings panel/modal, contributed by the feature that owns those settings. */\nexport interface SettingsTab<C = unknown> {\n id: string\n /** Already translated (`ctx.t(...)` in the feature's `settingsTabs` factory). */\n label: string\n icon?: string\n component: C\n /** Props handed to `component`, e.g. the configured composite kinds. */\n props?: Record<string, unknown>\n}\n\n/** The stages `parseBlocks` and the import/AI insertion paths run; features replace stages, defaults are identity/Markdown. */\nexport interface BlockPipeline {\n parseMarkdown: (editor: Editor, markdown: string) => JSONContent[]\n normalize: (editor: Editor, blocks: JSONContent[]) => JSONContent[]\n segment: (editor: Editor, blocks: JSONContent[]) => JSONContent[]\n structure: (editor: Editor, blocks: JSONContent[]) => JSONContent[]\n wrapImport: (editor: Editor, file: File, blocks: JSONContent[]) => JSONContent[]\n migrateContent: (content: JSONContent) => JSONContent\n}\n\n/** Pipeline hooks that allow a single contributor; `normalize` chains instead. */\nexport const SINGLETON_PIPELINE_HOOKS = ['parseMarkdown', 'segment', 'structure', 'wrapImport', 'migrateContent'] as const satisfies readonly (keyof BlockPipeline)[]\n\n/**\n * A feature's block conversions. Targets keep the inert `ConvertTarget` shapes; the provider that parses a target id\n * owns that target (labels, execution). `handlesSource` claims all conversions of source blocks it understands.\n */\nexport interface ConversionProvider {\n /** Source blocks this provider converts to any target it can; the first provider claiming a node executes. */\n handlesSource?: (node: PMNode) => boolean\n /** Targets offered for `node` in menus (excluding its current type). */\n targets: (editor: Editor, node: PMNode) => ConvertTarget[]\n /** The target of `id` when this provider owns it, else null. */\n parseTarget: (id: string) => ConvertTarget | null\n /** Menu label (in the language of `t`) and icon of a target this provider owns. */\n label: (target: ConvertTarget, t: Translate) => { label: string, icon: string } | null\n /** The conversion of the block after `start` into `target` (absolute range replaced and the converted blocks), or null. */\n convert: (state: EditorState, start: ResolvedPos, target: ConvertTarget) => { from: number, to: number, blocks: PMNode[] } | null\n}\n\n/**\n * Inert public data AI reads about the editor's document model. A kind's `fields` carry what the model needs to write\n * them (`type`, and the choices of a `select`).\n */\nexport interface AiContextKind {\n id: string\n label: string\n fields: readonly { key: string, label: string, type?: 'text' | 'textarea' | 'date' | 'number' | 'select' | 'reference' | 'bibliography' | 'derivation', options?: readonly { value: string, label: string }[] }[]\n /** The kind's `ai.purpose`, when configured. */\n purpose?: string\n}\n\n/** A host block as AI learns it: what it is for, its Markdown form and one example. `id` is the node type name and the `convert` target id. */\nexport interface AiBlock {\n id: string\n label: string\n /** One or two German sentences: purpose and what it may contain. */\n description: string\n /** The Markdown form, placeholders in angle brackets, e.g. `!!! <info|warning|success>\\n<Inhalt>`. */\n syntax: string\n /** One complete Markdown example of the block. */\n example: string\n}\n\nexport interface AiContext {\n kinds?: readonly AiContextKind[]\n blocks?: readonly AiBlock[]\n structure?: 'flat' | 'composite'\n}\n\n/** One piece of material a feature fetched for a block before the model fills it (a host's examples, a record). */\nexport interface AiBlockDatum { label: string, text: string }\nexport interface AiBlockDataRequest { editor: Editor, node: PMNode, pos: number, signal: AbortSignal }\n/** Material for one block; `signal` aborts when the editor is destroyed or the run is cancelled. */\nexport type AiBlockDataProvider = (request: AiBlockDataRequest) => Promise<readonly AiBlockDatum[]> | readonly AiBlockDatum[]\n\n/**\n * The axis a feature belongs to: `content` (nodes, marks and structure rules the document stores: the server schema comes\n * from here), `interaction` (editing UX, backend-bound UI such as comments and collaboration) or `ai`. A feature\n * belongs to the dimension without which it makes no sense.\n */\nexport type Dimension = 'content' | 'interaction' | 'ai'\n\n/** One named contribution to an editor (blocks, toolbar entries, menus, settings, AI knowledge). Every member is optional but `dimension`; identity and ordering come from the feature list. */\nexport interface EditorFeature<C = unknown> {\n id: string\n /** The feature's primary dimension. */\n dimension: Dimension\n /**\n * The Vue-free schema-bearing extensions of this feature (no node views, no UI), collected by `schemaExtensionsOf` for\n * the server schema. Present on every feature whose nodes or marks the stored document can contain.\n */\n schemaExtensions?: () => AnyExtension[]\n /** Ids of features that must also be installed (`defineEditor` does not install them). */\n requires?: readonly string[]\n /** Backend capabilities the feature cannot work without; a surface session over a backend lacking one throws. Optional capabilities (users and tags for mentions) are not listed. */\n backend?: readonly BackendCapability[]\n extensions?: (ctx: FeatureContext) => AnyExtension[]\n blockActions?: (ctx: FeatureContext) => BlockAction[]\n /** The feature's commands, each declared once with its toolbar and `/` placements (see `CommandDef`). */\n commands?: (ctx: FeatureContext) => CommandDef<C>[]\n /** Toolbar groups the feature declares; every command's `toolbar.group` must be declared by some feature. Ids are unique across features. */\n toolbarGroups?: ToolbarGroupDef[]\n /** Rules a command's `creates` must pass at the caret besides the schema (e.g. a Baustein's accepted children). */\n insertGuards?: (ctx: FeatureContext) => InsertGuard[]\n /** Components mounted beside the editor content; they receive `{ editor }`. `C` is the component type of the framework layer that renders them. */\n overlays?: readonly C[]\n /**\n * Runs once when a surface mounts (per-app side effects, e.g. a theme runtime; dedupe inside). Returns the teardown,\n * called when the surface unmounts; it must be idempotent (React StrictMode mounts twice).\n */\n setup?: (ctx: FeatureContext) => void | (() => void)\n /** The feature's settings tabs. A factory over the app context, so labels render in the context's language. */\n settingsTabs?: (ctx: EditorContext) => readonly SettingsTab<C>[]\n /** Built-in metadata lists (`mentions`, `hashtags`, `speakers`, …) used for every list name the host does not supply; searched only when a suggestion uses them. */\n metadataDefaults?: (ctx: FeatureContext) => EditorMetadata\n blocks?: Partial<BlockPipeline>\n conversions?: readonly ConversionProvider[]\n /** At most one contributor: supplies the collaboration-aware position mapping to `DocAnchors`. */\n anchorResolver?: (ctx: FeatureContext) => AnchorResolver\n /** Additive: the contributions of all features are merged (`kinds` and `blocks` concatenated in feature order; `structure` may be set by one feature only). Reads AI's view of the document model. */\n aiContext?: (editor: Editor) => AiContext\n /** Additive: every contributor runs for the block (in parallel), their data concatenate in feature order; one rejection fails the whole fill. Read by „Baustein füllen (KI)“. */\n aiBlockData?: AiBlockDataProvider\n /** At most one contributor: formats an AI result's markdown before the generic pipeline. */\n formatAiResult?: (editor: Editor, markdown: string, heading?: string) => string\n}\n\n/** An immutable, validated feature list with its resolved pipeline, conversion providers and AI hooks. */\nexport interface EditorPreset<C = unknown> {\n readonly features: readonly EditorFeature<C>[]\n readonly pipeline: BlockPipeline\n readonly conversions: readonly ConversionProvider[]\n /** All `aiContext` contributions merged (`aiContextOf`). */\n readonly aiContext?: EditorFeature['aiContext']\n /** All `aiBlockData` contributions merged (`aiBlockDataOf`). */\n readonly aiBlockData?: AiBlockDataProvider\n /** The single `formatAiResult` contributor, if any. */\n readonly formatAiResult?: EditorFeature['formatAiResult']\n}\n"],"mappings":";;AAsHA,MAAa,2BAA2B;CAAC;CAAiB;CAAW;CAAa;CAAc;AAAgB"}
@@ -1,8 +1,9 @@
1
1
  import { JSONContent } from "@tiptap/core";
2
2
  //#region src/core/fences.d.ts
3
- /** A well-formed fence: its kind, JSON meta, inner text and the exact source text, opener line through closer line. */
3
+ /** A well-formed fence: its kind, optional block id (`#id` after the kind), JSON meta, inner text and the exact source text, opener line through closer line. */
4
4
  export interface CompositeFence {
5
5
  kind: string;
6
+ id?: string;
6
7
  meta: Record<string, unknown>;
7
8
  inner: string;
8
9
  raw: string;
@@ -1,5 +1,5 @@
1
1
  //#region src/core/fences.ts
2
- const OPENER = /^\s*:::[ \t]*([\p{L}\p{N}_-]+)[ \t]*(\{.*\})?[ \t]*$/u;
2
+ const OPENER = /^\s*:::[ \t]*([\p{L}\p{N}_-]+)(?:[ \t]+#([0-9a-f-]{36}))?[ \t]*(\{.*\})?[ \t]*$/u;
3
3
  const CLOSER = /^\s*:::\s*$/;
4
4
  const CODE_FENCE = /^ {0,3}(`{3,}|~{3,})/;
5
5
  function parseMeta(json) {
@@ -46,7 +46,7 @@ function splitFences(markdown) {
46
46
  while (i < lines.length) {
47
47
  const line = lines[i];
48
48
  const match = code[i] ? null : OPENER.exec(line);
49
- const meta = match ? parseMeta(match[2]) : null;
49
+ const meta = match ? parseMeta(match[3]) : null;
50
50
  if (!match || !meta) {
51
51
  if (match) problems.push({
52
52
  code: "invalid-fence-meta",
@@ -77,6 +77,7 @@ function splitFences(markdown) {
77
77
  flush();
78
78
  segments.push({
79
79
  kind: match[1],
80
+ ...match[2] && { id: match[2] },
80
81
  meta,
81
82
  inner: lines.slice(i + 1, end).join("\n"),
82
83
  raw: lines.slice(i, end + 1).join("\n")
@@ -1 +1 @@
1
- {"version":3,"file":"fences.js","names":[],"sources":["../../src/core/fences.ts"],"sourcesContent":["import type { JSONContent } from '@tiptap/core'\n\n// The `::: kind {meta}` … `:::` fence grammar of Markdown documents, shared by the composite feature (registered kinds\n// become composites) and the Markdown entry (every other kind stays an `opaqueFence`). Nested fences close with the\n// same bare `:::`, so a closer always ends the innermost open fence. Lines inside ``` / ~~~ code fences are never fence\n// syntax.\n\n/** A well-formed fence: its kind, JSON meta, inner text and the exact source text, opener line through closer line. */\nexport interface CompositeFence { kind: string, meta: Record<string, unknown>, inner: string, raw: string }\nexport type FenceSegment = { markdown: string } | CompositeFence\n\n/** A fence-like construct that did not become a fence: `invalid-fence-meta` (the `{…}` after the kind is no JSON object) or `unclosed-fence` (no matching `:::`). `line` is 1-based. */\nexport interface FenceProblem { code: 'invalid-fence-meta' | 'unclosed-fence', line: number, kind: string }\n\nconst OPENER = /^\\s*:::[ \\t]*([\\p{L}\\p{N}_-]+)[ \\t]*(\\{.*\\})?[ \\t]*$/u\nconst CLOSER = /^\\s*:::\\s*$/\nconst CODE_FENCE = /^ {0,3}(`{3,}|~{3,})/\n\nfunction parseMeta(json: string | undefined): Record<string, unknown> | null {\n if (!json) return {}\n try {\n const value: unknown = JSON.parse(json)\n return value && typeof value === 'object' && !Array.isArray(value) ? value as Record<string, unknown> : null\n }\n catch {\n return null\n }\n}\n\n/** For every line whether it is part of a ``` / ~~~ code fence (the fence lines included). */\nfunction codeLines(lines: readonly string[]): boolean[] {\n const inside: boolean[] = []\n let open: { char: string, length: number } | null = null\n for (const line of lines) {\n const match = CODE_FENCE.exec(line)\n if (!open) {\n if (match) open = { char: match[1]![0]!, length: match[1]!.length }\n inside.push(open !== null)\n continue\n }\n inside.push(true)\n const closing = /^ {0,3}(`{3,}|~{3,})\\s*$/.exec(line)\n if (closing && closing[1]![0] === open.char && closing[1]!.length >= open.length) open = null\n }\n return inside\n}\n\n/** Splits `::: kind {json}` … `:::` fences (nestable) into segments; text outside fences stays markdown. `problems` lists the opener lines that stayed plain text. */\nexport function splitFences(markdown: string): { segments: FenceSegment[], problems: FenceProblem[] } {\n const lines = markdown.split('\\n')\n const code = codeLines(lines)\n const segments: FenceSegment[] = []\n const problems: FenceProblem[] = []\n let plain: string[] = []\n const flush = () => {\n if (plain.join('').trim()) segments.push({ markdown: plain.join('\\n') })\n plain = []\n }\n let i = 0\n while (i < lines.length) {\n const line = lines[i]!\n const match = code[i] ? null : OPENER.exec(line)\n const meta = match ? parseMeta(match[2]) : null\n if (!match || !meta) {\n if (match) problems.push({ code: 'invalid-fence-meta', line: i + 1, kind: match[1]! })\n plain.push(line)\n i++\n continue\n }\n // Find the matching closer, counting nested openers; none → the opener line stays plain text.\n let depth = 1\n let end = i + 1\n for (; end < lines.length; end++) {\n if (code[end]) continue\n if (OPENER.test(lines[end]!)) depth++\n else if (CLOSER.test(lines[end]!) && --depth === 0) break\n }\n if (depth) {\n problems.push({ code: 'unclosed-fence', line: i + 1, kind: match[1]! })\n plain.push(line)\n i++\n continue\n }\n flush()\n segments.push({ kind: match[1]!, meta, inner: lines.slice(i + 1, end).join('\\n'), raw: lines.slice(i, end + 1).join('\\n') })\n i = end + 1\n }\n flush()\n return { segments, problems }\n}\n\n/** The fences of `markdown` (see `splitFences`) without the problem report. */\nexport const splitCompositeFences = (markdown: string): FenceSegment[] => splitFences(markdown).segments\n\n/** An opaque fence node: `raw` is the fence's source text, written back verbatim by the Markdown serializer. */\nexport const opaqueFenceJSON = (fence: CompositeFence): JSONContent => ({ type: 'opaqueFence', attrs: { kind: fence.kind, raw: fence.raw } })\n"],"mappings":";AAcA,MAAM,SAAS;AACf,MAAM,SAAS;AACf,MAAM,aAAa;AAEnB,SAAS,UAAU,MAA0D;CAC3E,IAAI,CAAC,MAAM,OAAO,CAAC;CACnB,IAAI;EACF,MAAM,QAAiB,KAAK,MAAM,IAAI;EACtC,OAAO,SAAS,OAAO,UAAU,YAAY,CAAC,MAAM,QAAQ,KAAK,IAAI,QAAmC;CAC1G,QACM;EACJ,OAAO;CACT;AACF;;AAGA,SAAS,UAAU,OAAqC;CACtD,MAAM,SAAoB,CAAC;CAC3B,IAAI,OAAgD;CACpD,KAAK,MAAM,QAAQ,OAAO;EACxB,MAAM,QAAQ,WAAW,KAAK,IAAI;EAClC,IAAI,CAAC,MAAM;GACT,IAAI,OAAO,OAAO;IAAE,MAAM,MAAM,EAAE,CAAE;IAAK,QAAQ,MAAM,EAAE,CAAE;GAAO;GAClE,OAAO,KAAK,SAAS,IAAI;GACzB;EACF;EACA,OAAO,KAAK,IAAI;EAChB,MAAM,UAAU,2BAA2B,KAAK,IAAI;EACpD,IAAI,WAAW,QAAQ,EAAE,CAAE,OAAO,KAAK,QAAQ,QAAQ,EAAE,CAAE,UAAU,KAAK,QAAQ,OAAO;CAC3F;CACA,OAAO;AACT;;AAGA,SAAgB,YAAY,UAA0E;CACpG,MAAM,QAAQ,SAAS,MAAM,IAAI;CACjC,MAAM,OAAO,UAAU,KAAK;CAC5B,MAAM,WAA2B,CAAC;CAClC,MAAM,WAA2B,CAAC;CAClC,IAAI,QAAkB,CAAC;CACvB,MAAM,cAAc;EAClB,IAAI,MAAM,KAAK,EAAE,CAAC,CAAC,KAAK,GAAG,SAAS,KAAK,EAAE,UAAU,MAAM,KAAK,IAAI,EAAE,CAAC;EACvE,QAAQ,CAAC;CACX;CACA,IAAI,IAAI;CACR,OAAO,IAAI,MAAM,QAAQ;EACvB,MAAM,OAAO,MAAM;EACnB,MAAM,QAAQ,KAAK,KAAK,OAAO,OAAO,KAAK,IAAI;EAC/C,MAAM,OAAO,QAAQ,UAAU,MAAM,EAAE,IAAI;EAC3C,IAAI,CAAC,SAAS,CAAC,MAAM;GACnB,IAAI,OAAO,SAAS,KAAK;IAAE,MAAM;IAAsB,MAAM,IAAI;IAAG,MAAM,MAAM;GAAI,CAAC;GACrF,MAAM,KAAK,IAAI;GACf;GACA;EACF;EAEA,IAAI,QAAQ;EACZ,IAAI,MAAM,IAAI;EACd,OAAO,MAAM,MAAM,QAAQ,OAAO;GAChC,IAAI,KAAK,MAAM;GACf,IAAI,OAAO,KAAK,MAAM,IAAK,GAAG;QACzB,IAAI,OAAO,KAAK,MAAM,IAAK,KAAK,EAAE,UAAU,GAAG;EACtD;EACA,IAAI,OAAO;GACT,SAAS,KAAK;IAAE,MAAM;IAAkB,MAAM,IAAI;IAAG,MAAM,MAAM;GAAI,CAAC;GACtE,MAAM,KAAK,IAAI;GACf;GACA;EACF;EACA,MAAM;EACN,SAAS,KAAK;GAAE,MAAM,MAAM;GAAK;GAAM,OAAO,MAAM,MAAM,IAAI,GAAG,GAAG,CAAC,CAAC,KAAK,IAAI;GAAG,KAAK,MAAM,MAAM,GAAG,MAAM,CAAC,CAAC,CAAC,KAAK,IAAI;EAAE,CAAC;EAC3H,IAAI,MAAM;CACZ;CACA,MAAM;CACN,OAAO;EAAE;EAAU;CAAS;AAC9B;;AAGA,MAAa,wBAAwB,aAAqC,YAAY,QAAQ,CAAC,CAAC;;AAGhG,MAAa,mBAAmB,WAAwC;CAAE,MAAM;CAAe,OAAO;EAAE,MAAM,MAAM;EAAM,KAAK,MAAM;CAAI;AAAE"}
1
+ {"version":3,"file":"fences.js","names":[],"sources":["../../src/core/fences.ts"],"sourcesContent":["import type { JSONContent } from '@tiptap/core'\n\n// The `::: kind #id {meta}` … `:::` fence grammar of Markdown documents, shared by the composite feature (registered kinds\n// become composites) and the Markdown entry (every other kind stays an `opaqueFence`). `#id` (optional, Pandoc-like) is\n// the block id of the fenced composite; `{meta}` is a JSON object. Nested fences close with the\n// same bare `:::`, so a closer always ends the innermost open fence. Lines inside ``` / ~~~ code fences are never fence\n// syntax.\n\n/** A well-formed fence: its kind, optional block id (`#id` after the kind), JSON meta, inner text and the exact source text, opener line through closer line. */\nexport interface CompositeFence { kind: string, id?: string, meta: Record<string, unknown>, inner: string, raw: string }\nexport type FenceSegment = { markdown: string } | CompositeFence\n\n/** A fence-like construct that did not become a fence: `invalid-fence-meta` (the `{…}` after the kind is no JSON object) or `unclosed-fence` (no matching `:::`). `line` is 1-based. */\nexport interface FenceProblem { code: 'invalid-fence-meta' | 'unclosed-fence', line: number, kind: string }\n\nconst OPENER = /^\\s*:::[ \\t]*([\\p{L}\\p{N}_-]+)(?:[ \\t]+#([0-9a-f-]{36}))?[ \\t]*(\\{.*\\})?[ \\t]*$/u\nconst CLOSER = /^\\s*:::\\s*$/\nconst CODE_FENCE = /^ {0,3}(`{3,}|~{3,})/\n\nfunction parseMeta(json: string | undefined): Record<string, unknown> | null {\n if (!json) return {}\n try {\n const value: unknown = JSON.parse(json)\n return value && typeof value === 'object' && !Array.isArray(value) ? value as Record<string, unknown> : null\n }\n catch {\n return null\n }\n}\n\n/** For every line whether it is part of a ``` / ~~~ code fence (the fence lines included). */\nfunction codeLines(lines: readonly string[]): boolean[] {\n const inside: boolean[] = []\n let open: { char: string, length: number } | null = null\n for (const line of lines) {\n const match = CODE_FENCE.exec(line)\n if (!open) {\n if (match) open = { char: match[1]![0]!, length: match[1]!.length }\n inside.push(open !== null)\n continue\n }\n inside.push(true)\n const closing = /^ {0,3}(`{3,}|~{3,})\\s*$/.exec(line)\n if (closing && closing[1]![0] === open.char && closing[1]!.length >= open.length) open = null\n }\n return inside\n}\n\n/** Splits `::: kind {json}` … `:::` fences (nestable) into segments; text outside fences stays markdown. `problems` lists the opener lines that stayed plain text. */\nexport function splitFences(markdown: string): { segments: FenceSegment[], problems: FenceProblem[] } {\n const lines = markdown.split('\\n')\n const code = codeLines(lines)\n const segments: FenceSegment[] = []\n const problems: FenceProblem[] = []\n let plain: string[] = []\n const flush = () => {\n if (plain.join('').trim()) segments.push({ markdown: plain.join('\\n') })\n plain = []\n }\n let i = 0\n while (i < lines.length) {\n const line = lines[i]!\n const match = code[i] ? null : OPENER.exec(line)\n const meta = match ? parseMeta(match[3]) : null\n if (!match || !meta) {\n if (match) problems.push({ code: 'invalid-fence-meta', line: i + 1, kind: match[1]! })\n plain.push(line)\n i++\n continue\n }\n // Find the matching closer, counting nested openers; none → the opener line stays plain text.\n let depth = 1\n let end = i + 1\n for (; end < lines.length; end++) {\n if (code[end]) continue\n if (OPENER.test(lines[end]!)) depth++\n else if (CLOSER.test(lines[end]!) && --depth === 0) break\n }\n if (depth) {\n problems.push({ code: 'unclosed-fence', line: i + 1, kind: match[1]! })\n plain.push(line)\n i++\n continue\n }\n flush()\n segments.push({ kind: match[1]!, ...(match[2] && { id: match[2] }), meta, inner: lines.slice(i + 1, end).join('\\n'), raw: lines.slice(i, end + 1).join('\\n') })\n i = end + 1\n }\n flush()\n return { segments, problems }\n}\n\n/** The fences of `markdown` (see `splitFences`) without the problem report. */\nexport const splitCompositeFences = (markdown: string): FenceSegment[] => splitFences(markdown).segments\n\n/** An opaque fence node: `raw` is the fence's source text, written back verbatim by the Markdown serializer. */\nexport const opaqueFenceJSON = (fence: CompositeFence): JSONContent => ({ type: 'opaqueFence', attrs: { kind: fence.kind, raw: fence.raw } })\n"],"mappings":";AAeA,MAAM,SAAS;AACf,MAAM,SAAS;AACf,MAAM,aAAa;AAEnB,SAAS,UAAU,MAA0D;CAC3E,IAAI,CAAC,MAAM,OAAO,CAAC;CACnB,IAAI;EACF,MAAM,QAAiB,KAAK,MAAM,IAAI;EACtC,OAAO,SAAS,OAAO,UAAU,YAAY,CAAC,MAAM,QAAQ,KAAK,IAAI,QAAmC;CAC1G,QACM;EACJ,OAAO;CACT;AACF;;AAGA,SAAS,UAAU,OAAqC;CACtD,MAAM,SAAoB,CAAC;CAC3B,IAAI,OAAgD;CACpD,KAAK,MAAM,QAAQ,OAAO;EACxB,MAAM,QAAQ,WAAW,KAAK,IAAI;EAClC,IAAI,CAAC,MAAM;GACT,IAAI,OAAO,OAAO;IAAE,MAAM,MAAM,EAAE,CAAE;IAAK,QAAQ,MAAM,EAAE,CAAE;GAAO;GAClE,OAAO,KAAK,SAAS,IAAI;GACzB;EACF;EACA,OAAO,KAAK,IAAI;EAChB,MAAM,UAAU,2BAA2B,KAAK,IAAI;EACpD,IAAI,WAAW,QAAQ,EAAE,CAAE,OAAO,KAAK,QAAQ,QAAQ,EAAE,CAAE,UAAU,KAAK,QAAQ,OAAO;CAC3F;CACA,OAAO;AACT;;AAGA,SAAgB,YAAY,UAA0E;CACpG,MAAM,QAAQ,SAAS,MAAM,IAAI;CACjC,MAAM,OAAO,UAAU,KAAK;CAC5B,MAAM,WAA2B,CAAC;CAClC,MAAM,WAA2B,CAAC;CAClC,IAAI,QAAkB,CAAC;CACvB,MAAM,cAAc;EAClB,IAAI,MAAM,KAAK,EAAE,CAAC,CAAC,KAAK,GAAG,SAAS,KAAK,EAAE,UAAU,MAAM,KAAK,IAAI,EAAE,CAAC;EACvE,QAAQ,CAAC;CACX;CACA,IAAI,IAAI;CACR,OAAO,IAAI,MAAM,QAAQ;EACvB,MAAM,OAAO,MAAM;EACnB,MAAM,QAAQ,KAAK,KAAK,OAAO,OAAO,KAAK,IAAI;EAC/C,MAAM,OAAO,QAAQ,UAAU,MAAM,EAAE,IAAI;EAC3C,IAAI,CAAC,SAAS,CAAC,MAAM;GACnB,IAAI,OAAO,SAAS,KAAK;IAAE,MAAM;IAAsB,MAAM,IAAI;IAAG,MAAM,MAAM;GAAI,CAAC;GACrF,MAAM,KAAK,IAAI;GACf;GACA;EACF;EAEA,IAAI,QAAQ;EACZ,IAAI,MAAM,IAAI;EACd,OAAO,MAAM,MAAM,QAAQ,OAAO;GAChC,IAAI,KAAK,MAAM;GACf,IAAI,OAAO,KAAK,MAAM,IAAK,GAAG;QACzB,IAAI,OAAO,KAAK,MAAM,IAAK,KAAK,EAAE,UAAU,GAAG;EACtD;EACA,IAAI,OAAO;GACT,SAAS,KAAK;IAAE,MAAM;IAAkB,MAAM,IAAI;IAAG,MAAM,MAAM;GAAI,CAAC;GACtE,MAAM,KAAK,IAAI;GACf;GACA;EACF;EACA,MAAM;EACN,SAAS,KAAK;GAAE,MAAM,MAAM;GAAK,GAAI,MAAM,MAAM,EAAE,IAAI,MAAM,GAAG;GAAI;GAAM,OAAO,MAAM,MAAM,IAAI,GAAG,GAAG,CAAC,CAAC,KAAK,IAAI;GAAG,KAAK,MAAM,MAAM,GAAG,MAAM,CAAC,CAAC,CAAC,KAAK,IAAI;EAAE,CAAC;EAC9J,IAAI,MAAM;CACZ;CACA,MAAM;CACN,OAAO;EAAE;EAAU;CAAS;AAC9B;;AAGA,MAAa,wBAAwB,aAAqC,YAAY,QAAQ,CAAC,CAAC;;AAGhG,MAAa,mBAAmB,WAAwC;CAAE,MAAM;CAAe,OAAO;EAAE,MAAM,MAAM;EAAM,KAAK,MAAM;CAAI;AAAE"}
@@ -1,5 +1,5 @@
1
1
  //#region src/core/fetch-error.d.ts
2
- /** Human-readable message for a failed HTTP request: the server's error message if it sent one. */
2
+ /** Human-readable message for a failed request: a `BackendError`'s message, else the server's error message if it sent one. */
3
3
  export declare function fetchErrorMessage(error: unknown): string;
4
4
  //#endregion
5
5
  //# sourceMappingURL=fetch-error.d.ts.map
@@ -1,6 +1,8 @@
1
+ import { BackendError } from "./backend.js";
1
2
  //#region src/core/fetch-error.ts
2
- /** Human-readable message for a failed HTTP request: the server's error message if it sent one. */
3
+ /** Human-readable message for a failed request: a `BackendError`'s message, else the server's error message if it sent one. */
3
4
  function fetchErrorMessage(error) {
5
+ if (error instanceof BackendError) return error.message;
4
6
  const serverMessage = error?.data?.message;
5
7
  if (typeof serverMessage === "string" && serverMessage) return serverMessage;
6
8
  return error instanceof Error ? error.message : String(error);
@@ -1 +1 @@
1
- {"version":3,"file":"fetch-error.js","names":[],"sources":["../../src/core/fetch-error.ts"],"sourcesContent":["/** Human-readable message for a failed HTTP request: the server's error message if it sent one. */\nexport function fetchErrorMessage(error: unknown): string {\n const serverMessage = (error as { data?: { message?: unknown } } | null)?.data?.message\n if (typeof serverMessage === 'string' && serverMessage) return serverMessage\n return error instanceof Error ? error.message : String(error)\n}\n"],"mappings":";;AACA,SAAgB,kBAAkB,OAAwB;CACxD,MAAM,gBAAiB,OAAmD,MAAM;CAChF,IAAI,OAAO,kBAAkB,YAAY,eAAe,OAAO;CAC/D,OAAO,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAC9D"}
1
+ {"version":3,"file":"fetch-error.js","names":[],"sources":["../../src/core/fetch-error.ts"],"sourcesContent":["import { BackendError } from './backend'\n\n/** Human-readable message for a failed request: a `BackendError`'s message, else the server's error message if it sent one. */\nexport function fetchErrorMessage(error: unknown): string {\n if (error instanceof BackendError) return error.message\n const serverMessage = (error as { data?: { message?: unknown } } | null)?.data?.message\n if (typeof serverMessage === 'string' && serverMessage) return serverMessage\n return error instanceof Error ? error.message : String(error)\n}\n"],"mappings":";;;AAGA,SAAgB,kBAAkB,OAAwB;CACxD,IAAI,iBAAiB,cAAc,OAAO,MAAM;CAChD,MAAM,gBAAiB,OAAmD,MAAM;CAChF,IAAI,OAAO,kBAAkB,YAAY,eAAe,OAAO;CAC/D,OAAO,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAC9D"}
@@ -0,0 +1,5 @@
1
+ //#region src/core/hash.d.ts
2
+ /** SHA-256 of the UTF-8 bytes of `text`, as lowercase hex. */
3
+ export declare function sha256Hex(text: string): string;
4
+ //#endregion
5
+ //# sourceMappingURL=hash.d.ts.map
@@ -0,0 +1,11 @@
1
+ import { sha256 } from "@noble/hashes/sha2.js";
2
+ import { bytesToHex, utf8ToBytes } from "@noble/hashes/utils.js";
3
+ //#region src/core/hash.ts
4
+ /** SHA-256 of the UTF-8 bytes of `text`, as lowercase hex. */
5
+ function sha256Hex(text) {
6
+ return bytesToHex(sha256(utf8ToBytes(text)));
7
+ }
8
+ //#endregion
9
+ export { sha256Hex };
10
+
11
+ //# sourceMappingURL=hash.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hash.js","names":[],"sources":["../../src/core/hash.ts"],"sourcesContent":["import { sha256 } from '@noble/hashes/sha2.js'\nimport { bytesToHex, utf8ToBytes } from '@noble/hashes/utils.js'\n\n// Pure JS on purpose: WebCrypto's `crypto.subtle` is unavailable outside secure contexts (plain-http dev hosts), same\n// reason block ids use `uuid` instead of `crypto.randomUUID`.\n\n/** SHA-256 of the UTF-8 bytes of `text`, as lowercase hex. */\nexport function sha256Hex(text: string): string {\n return bytesToHex(sha256(utf8ToBytes(text)))\n}\n"],"mappings":";;;;AAOA,SAAgB,UAAU,MAAsB;CAC9C,OAAO,WAAW,OAAO,YAAY,IAAI,CAAC,CAAC;AAC7C"}
@@ -0,0 +1,11 @@
1
+ import "./backend.js";
2
+ import { $Fetch } from "ofetch";
3
+ //#region src/core/http-backend.d.ts
4
+ export interface FetchBackendOptions {
5
+ /** HTTP client (default: the platform `fetch`); Nuxt hosts pass `useNuxtApp().$fetch` (it resolves relative paths while rendering on the server). */
6
+ fetch?: $Fetch;
7
+ /** Prefix of every path (`https://api.example.com`); default `''` (same origin). */
8
+ base?: string;
9
+ }
10
+ //#endregion
11
+ //# sourceMappingURL=http-backend.d.ts.map