@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
@@ -4,30 +4,35 @@ import { NodeFlags, isBlockContainer, isChromeNode, isEditorBlock } from "./node
4
4
  import { OpaqueFence } from "./opaque-fence.js";
5
5
  import { StrikeX } from "./strike.js";
6
6
  import { HEX_COLOR } from "./hex-color.js";
7
+ import { schemaExtensionsOf } from "./of-features.js";
7
8
  import StarterKit from "@tiptap/starter-kit";
8
9
  //#region src/core/schema/index.ts
9
10
  /**
10
- * Base Vue-free nodes and marks of every editor: StarterKit (history off: the surface enables it for standalone
11
- * editors, collaboration brings its own), StrikeX, the node-flags extension, `OpaqueFence` (Markdown fences of unknown
12
- * kinds, kept verbatim) and `BlockId`, which adds the `id` attribute to every block type (its ID-assigning plugins only
13
- * run in an editor). The server builds its schema from these as well (`getSchema(...)`).
11
+ * The Vue-free nodes and marks of the content base (`core-content` feature): StarterKit (history off: the surface enables
12
+ * it for standalone editors, collaboration brings its own), StrikeX, the node-flags extension and `OpaqueFence` (Markdown
13
+ * fences of unknown kinds, kept verbatim). Without `BlockId`: `schemaExtensionsOf` appends it last.
14
14
  */
15
- const coreSchemaExtensions = () => [
15
+ const coreContentSchemaExtensions = () => [
16
16
  StarterKit.configure({
17
17
  strike: false,
18
18
  undoRedo: false
19
19
  }),
20
20
  StrikeX,
21
21
  NodeFlags,
22
- OpaqueFence,
23
- BlockId
22
+ OpaqueFence
24
23
  ];
24
+ /**
25
+ * Base Vue-free nodes and marks of every editor: `coreContentSchemaExtensions()` and `BlockId`, which adds the `id`
26
+ * attribute to every block type (its ID-assigning plugins only run in an editor). The server builds its schema from
27
+ * these as well (`getSchema(...)`).
28
+ */
29
+ const coreSchemaExtensions = () => [...coreContentSchemaExtensions(), BlockId];
25
30
  /** Content of a fresh, empty document. */
26
31
  const EMPTY_EDITOR_CONTENT = {
27
32
  type: "doc",
28
33
  content: [{ type: "paragraph" }]
29
34
  };
30
35
  //#endregion
31
- export { ABILITY, BLOCK_ID_ATTR, BLOCK_ID_TYPES, BlockId, EMPTY_EDITOR_CONTENT, HEX_COLOR, NodeFlags, OpaqueFence, ROOT_ABILITIES, StrikeX, TEXT_ABILITIES, TYPE_ABILITIES, assignBlockIds, blockIdOf, coreSchemaExtensions, findBlockById, isBlockContainer, isChromeNode, isEditorBlock, newBlockId, resolveAbilities };
36
+ export { ABILITY, BLOCK_ID_ATTR, BLOCK_ID_TYPES, BlockId, EMPTY_EDITOR_CONTENT, HEX_COLOR, NodeFlags, OpaqueFence, ROOT_ABILITIES, StrikeX, TEXT_ABILITIES, TYPE_ABILITIES, assignBlockIds, blockIdOf, coreContentSchemaExtensions, coreSchemaExtensions, findBlockById, isBlockContainer, isChromeNode, isEditorBlock, newBlockId, resolveAbilities, schemaExtensionsOf };
32
37
 
33
38
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../../../src/core/schema/index.ts"],"sourcesContent":["import type { AnyExtension, JSONContent } from '@tiptap/core'\nimport StarterKit from '@tiptap/starter-kit'\nimport { BlockId } from './block-ids'\nimport { NodeFlags } from './node-flags'\nimport { OpaqueFence } from './opaque-fence'\nimport { StrikeX } from './strike'\n\nexport * from './abilities'\nexport * from './block-ids'\nexport * from './hex-color'\nexport * from './mark-flags'\nexport * from './node-flags'\nexport { OpaqueFence } from './opaque-fence'\nexport { StrikeX } from './strike'\n\n/**\n * Base Vue-free nodes and marks of every editor: StarterKit (history off: the surface enables it for standalone\n * editors, collaboration brings its own), StrikeX, the node-flags extension, `OpaqueFence` (Markdown fences of unknown\n * kinds, kept verbatim) and `BlockId`, which adds the `id` attribute to every block type (its ID-assigning plugins only\n * run in an editor). The server builds its schema from these as well (`getSchema(...)`).\n */\nexport const coreSchemaExtensions = (): AnyExtension[] => [StarterKit.configure({ strike: false, undoRedo: false }), StrikeX, NodeFlags, OpaqueFence, BlockId]\n\n/** Content of a fresh, empty document. */\nexport const EMPTY_EDITOR_CONTENT: JSONContent = { type: 'doc', content: [{ type: 'paragraph' }] }\n"],"mappings":";;;;;;;;;;;;;;AAqBA,MAAa,6BAA6C;CAAC,WAAW,UAAU;EAAE,QAAQ;EAAO,UAAU;CAAM,CAAC;CAAG;CAAS;CAAW;CAAa;AAAO;;AAG7J,MAAa,uBAAoC;CAAE,MAAM;CAAO,SAAS,CAAC,EAAE,MAAM,YAAY,CAAC;AAAE"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../../src/core/schema/index.ts"],"sourcesContent":["import type { AnyExtension, JSONContent } from '@tiptap/core'\nimport StarterKit from '@tiptap/starter-kit'\nimport { BlockId } from './block-ids'\nimport { NodeFlags } from './node-flags'\nimport { OpaqueFence } from './opaque-fence'\nimport { StrikeX } from './strike'\n\nexport * from './abilities'\nexport * from './block-ids'\nexport * from './hex-color'\nexport * from './mark-flags'\nexport * from './node-flags'\nexport { OpaqueFence } from './opaque-fence'\nexport { StrikeX } from './strike'\nexport { schemaExtensionsOf } from './of-features'\n\n/**\n * The Vue-free nodes and marks of the content base (`core-content` feature): StarterKit (history off: the surface enables\n * it for standalone editors, collaboration brings its own), StrikeX, the node-flags extension and `OpaqueFence` (Markdown\n * fences of unknown kinds, kept verbatim). Without `BlockId`: `schemaExtensionsOf` appends it last.\n */\nexport const coreContentSchemaExtensions = (): AnyExtension[] => [StarterKit.configure({ strike: false, undoRedo: false }), StrikeX, NodeFlags, OpaqueFence]\n\n/**\n * Base Vue-free nodes and marks of every editor: `coreContentSchemaExtensions()` and `BlockId`, which adds the `id`\n * attribute to every block type (its ID-assigning plugins only run in an editor). The server builds its schema from\n * these as well (`getSchema(...)`).\n */\nexport const coreSchemaExtensions = (): AnyExtension[] => [...coreContentSchemaExtensions(), BlockId]\n\n/** Content of a fresh, empty document. */\nexport const EMPTY_EDITOR_CONTENT: JSONContent = { type: 'doc', content: [{ type: 'paragraph' }] }\n"],"mappings":";;;;;;;;;;;;;;AAqBA,MAAa,oCAAoD;CAAC,WAAW,UAAU;EAAE,QAAQ;EAAO,UAAU;CAAM,CAAC;CAAG;CAAS;CAAW;AAAW;;;;;;AAO3J,MAAa,6BAA6C,CAAC,GAAG,4BAA4B,GAAG,OAAO;;AAGpG,MAAa,uBAAoC;CAAE,MAAM;CAAO,SAAS,CAAC,EAAE,MAAM,YAAY,CAAC;AAAE"}
@@ -1,3 +1,4 @@
1
+ import { JSONContent } from "@tiptap/core";
1
2
  //#region src/core/schema/mark-flags.d.ts
2
3
  declare module '@tiptap/core' {
3
4
  interface MarkConfig<Options, Storage> {
@@ -7,6 +8,12 @@ declare module '@tiptap/core' {
7
8
  */
8
9
  markdownInvisible?: boolean;
9
10
  }
11
+ interface NodeConfig<Options, Storage> {
12
+ /**
13
+ * Rewrites the document JSON just before `editor.markdown.serialize` renders it (every node extension that declares it,
14
+ * in extension order), e.g. to drop attributes that must not reach the Markdown. Must not modify its input.
15
+ */
16
+ markdownPrepare?: (json: JSONContent, editor: Editor) => JSONContent;
17
+ }
10
18
  }
11
- export {};
12
19
  //# sourceMappingURL=mark-flags.d.ts.map
@@ -0,0 +1,13 @@
1
+ import { EditorFeature } from "../feature.js";
2
+ import { AnyExtension } from "@tiptap/core";
3
+ //#region src/core/schema/of-features.d.ts
4
+ /**
5
+ * The server schema of a feature list: every feature's Vue-free `schemaExtensions` in feature order, then `BlockId`
6
+ * (it adds the `id` attribute to every block type, so it comes last). The content features carry the document model;
7
+ * an interaction feature may also declare `schemaExtensions` for marks that stored documents contain (`comments`), so
8
+ * the collection looks at the declaration, not at the dimension. Takes the schema-bearing slice of a feature, so
9
+ * server code can pass schema-only sources and never load a feature's UI.
10
+ */
11
+ export declare const schemaExtensionsOf: (features: readonly Pick<EditorFeature, "schemaExtensions">[]) => AnyExtension[];
12
+ //#endregion
13
+ //# sourceMappingURL=of-features.d.ts.map
@@ -0,0 +1,14 @@
1
+ import { BlockId } from "./block-ids.js";
2
+ //#region src/core/schema/of-features.ts
3
+ /**
4
+ * The server schema of a feature list: every feature's Vue-free `schemaExtensions` in feature order, then `BlockId`
5
+ * (it adds the `id` attribute to every block type, so it comes last). The content features carry the document model;
6
+ * an interaction feature may also declare `schemaExtensions` for marks that stored documents contain (`comments`), so
7
+ * the collection looks at the declaration, not at the dimension. Takes the schema-bearing slice of a feature, so
8
+ * server code can pass schema-only sources and never load a feature's UI.
9
+ */
10
+ const schemaExtensionsOf = (features) => [...features.flatMap((feature) => feature.schemaExtensions?.() ?? []), BlockId];
11
+ //#endregion
12
+ export { schemaExtensionsOf };
13
+
14
+ //# sourceMappingURL=of-features.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"of-features.js","names":[],"sources":["../../../src/core/schema/of-features.ts"],"sourcesContent":["import type { AnyExtension } from '@tiptap/core'\nimport type { EditorFeature } from '../feature'\nimport { BlockId } from './block-ids'\n\n/**\n * The server schema of a feature list: every feature's Vue-free `schemaExtensions` in feature order, then `BlockId`\n * (it adds the `id` attribute to every block type, so it comes last). The content features carry the document model;\n * an interaction feature may also declare `schemaExtensions` for marks that stored documents contain (`comments`), so\n * the collection looks at the declaration, not at the dimension. Takes the schema-bearing slice of a feature, so\n * server code can pass schema-only sources and never load a feature's UI.\n */\nexport const schemaExtensionsOf = (features: readonly Pick<EditorFeature, 'schemaExtensions'>[]): AnyExtension[] =>\n [...features.flatMap(feature => feature.schemaExtensions?.() ?? []), BlockId]\n"],"mappings":";;;;;;;;;AAWA,MAAa,sBAAsB,aACjC,CAAC,GAAG,SAAS,SAAQ,YAAW,QAAQ,mBAAmB,KAAK,CAAC,CAAC,GAAG,OAAO"}
@@ -1,10 +1,11 @@
1
- import { SlashCommandItem } from "./extension-points.js";
1
+ import { CommandDef } from "./command-types.js";
2
+ import "./commands.js";
2
3
  import { Extension } from "@tiptap/core";
3
4
  import { PluginKey } from "@tiptap/pm/state";
4
5
  //#region src/core/slash.d.ts
5
6
  export interface SlashCommandOptions {
6
- /** The final `/` menu: features' commands after the host's `slashCommands` transformer. */
7
- items: SlashCommandItem[];
7
+ /** The final command list (features' commands after the host's `commands` transformer); the ones with a `slash` placement make the menu. */
8
+ commands: CommandDef[];
8
9
  /** Popup text while no command matches the typed query (`ctx.t('slash.empty')`). */
9
10
  emptyText: string;
10
11
  /** Popup text while the commands are pending (`ctx.t('common.loading')`). */
@@ -14,9 +15,10 @@ export interface SlashCommandOptions {
14
15
  export declare const SlashCommandPluginKey: PluginKey<any>;
15
16
  /**
16
17
  * `/` menu on an empty line: typing `/` as the only content of a textblock (outside code) opens the shared suggestion
17
- * popup with the commands allowed at the caret (`SlashCommandItem.ability`) whose id or label starts with the typed
18
- * query; picking one deletes `/query` and runs it. A query no allowed command matches (`/foo`) shows nothing and stays
19
- * plain text. The commands come from features and the host; the core feature has none of its own.
18
+ * popup with the commands that have a `slash` placement and are visible and enabled at the caret (`commandState`: ability,
19
+ * structural check, schema and accepted-children fit) whose slash id or label starts with the typed query; picking one
20
+ * deletes `/query` and runs it. A query no such command matches (`/foo`) shows nothing and stays plain text. The commands
21
+ * come from features and the host.
20
22
  * Client-only: not part of the Vue-free schema.
21
23
  */
22
24
  export declare const SlashCommand: Extension<SlashCommandOptions, any>;
@@ -1,33 +1,41 @@
1
- import { abilitiesAt } from "./abilities.js";
1
+ import { commandState } from "./commands.js";
2
2
  import { createSuggestionRender } from "./suggestion-popup.js";
3
3
  import { Extension } from "@tiptap/core";
4
4
  import { PluginKey } from "@tiptap/pm/state";
5
5
  import { Suggestion } from "@tiptap/suggestion";
6
6
  //#region src/core/slash.ts
7
- function matching(items, query, abilities) {
7
+ const slashIdOf = (cmd) => cmd.slash.id ?? cmd.id;
8
+ /** The slash commands that are visible and enabled at the caret (`$at` when the editor state lags, see `commandState`) and whose slash id or label starts with `query`. */
9
+ function matching(editor, commands, query, $at) {
8
10
  const q = query.toLowerCase();
9
- return items.filter((item) => (!item.ability || abilities.has(item.ability)) && (item.id.startsWith(q) || item.label.toLowerCase().startsWith(q)));
11
+ return commands.filter((cmd) => {
12
+ if (!cmd.slash || !("run" in cmd)) return false;
13
+ if (!(slashIdOf(cmd).startsWith(q) || cmd.label.toLowerCase().startsWith(q))) return false;
14
+ const state = commandState(editor, cmd, "caret", $at);
15
+ return state.visible && state.enabled;
16
+ });
10
17
  }
11
18
  /** Own key, so the `/` popup runs next to the `@` and `#` popups. */
12
19
  const SlashCommandPluginKey = new PluginKey("slashCommand");
13
20
  /**
14
21
  * `/` menu on an empty line: typing `/` as the only content of a textblock (outside code) opens the shared suggestion
15
- * popup with the commands allowed at the caret (`SlashCommandItem.ability`) whose id or label starts with the typed
16
- * query; picking one deletes `/query` and runs it. A query no allowed command matches (`/foo`) shows nothing and stays
17
- * plain text. The commands come from features and the host; the core feature has none of its own.
22
+ * popup with the commands that have a `slash` placement and are visible and enabled at the caret (`commandState`: ability,
23
+ * structural check, schema and accepted-children fit) whose slash id or label starts with the typed query; picking one
24
+ * deletes `/query` and runs it. A query no such command matches (`/foo`) shows nothing and stays plain text. The commands
25
+ * come from features and the host.
18
26
  * Client-only: not part of the Vue-free schema.
19
27
  */
20
28
  const SlashCommand = Extension.create({
21
29
  name: "slashCommand",
22
30
  addOptions() {
23
31
  return {
24
- items: [],
32
+ commands: [],
25
33
  emptyText: "",
26
34
  loadingText: ""
27
35
  };
28
36
  },
29
37
  addProseMirrorPlugins() {
30
- const { items, emptyText, loadingText } = this.options;
38
+ const { commands, emptyText, loadingText } = this.options;
31
39
  return [Suggestion({
32
40
  pluginKey: SlashCommandPluginKey,
33
41
  editor: this.editor,
@@ -35,18 +43,18 @@ const SlashCommand = Extension.create({
35
43
  startOfLine: true,
36
44
  shouldShow: ({ editor, range, query, transaction }) => {
37
45
  const $from = transaction.doc.resolve(range.from);
38
- return $from.parentOffset === 0 && range.to === $from.end() && !$from.parent.type.spec.code && matching(items, query, abilitiesAt(editor, $from)).length > 0;
46
+ return $from.parentOffset === 0 && range.to === $from.end() && !$from.parent.type.spec.code && matching(editor, commands, query, $from).length > 0;
39
47
  },
40
- items: ({ editor, query }) => matching(items, query, abilitiesAt(editor, editor.state.selection.$from)),
41
- command: ({ editor, range, props: item }) => {
48
+ items: ({ editor, query }) => matching(editor, commands, query),
49
+ command: ({ editor, range, props: cmd }) => {
42
50
  editor.chain().focus().deleteRange(range).run();
43
- item.run(editor);
51
+ cmd.run(editor);
44
52
  },
45
53
  render: createSuggestionRender({
46
- display: (item) => ({
47
- label: item.label,
48
- description: `/${item.id}`,
49
- icon: item.icon
54
+ display: (cmd) => ({
55
+ label: cmd.label,
56
+ description: `/${slashIdOf(cmd)}`,
57
+ icon: cmd.icon
50
58
  }),
51
59
  emptyText,
52
60
  loadingText
@@ -1 +1 @@
1
- {"version":3,"file":"slash.js","names":[],"sources":["../../src/core/slash.ts"],"sourcesContent":["import { Extension } from '@tiptap/core'\nimport { PluginKey } from '@tiptap/pm/state'\nimport { Suggestion } from '@tiptap/suggestion'\nimport { abilitiesAt } from './abilities'\nimport type { SlashCommandItem } from './extension-points'\nimport type { Ability } from './schema/abilities'\nimport { createSuggestionRender } from './suggestion-popup'\n\nexport interface SlashCommandOptions {\n /** The final `/` menu: features' commands after the host's `slashCommands` transformer. */\n items: SlashCommandItem[]\n /** Popup text while no command matches the typed query (`ctx.t('slash.empty')`). */\n emptyText: string\n /** Popup text while the commands are pending (`ctx.t('common.loading')`). */\n loadingText: string\n}\n\nfunction matching(items: SlashCommandItem[], query: string, abilities: ReadonlySet<Ability>): SlashCommandItem[] {\n const q = query.toLowerCase()\n return items.filter(item => (!item.ability || abilities.has(item.ability))\n && (item.id.startsWith(q) || item.label.toLowerCase().startsWith(q)))\n}\n\n/** Own key, so the `/` popup runs next to the `@` and `#` popups. */\nexport const SlashCommandPluginKey = new PluginKey('slashCommand')\n\n/**\n * `/` menu on an empty line: typing `/` as the only content of a textblock (outside code) opens the shared suggestion\n * popup with the commands allowed at the caret (`SlashCommandItem.ability`) whose id or label starts with the typed\n * query; picking one deletes `/query` and runs it. A query no allowed command matches (`/foo`) shows nothing and stays\n * plain text. The commands come from features and the host; the core feature has none of its own.\n * Client-only: not part of the Vue-free schema.\n */\nexport const SlashCommand = Extension.create<SlashCommandOptions>({\n name: 'slashCommand',\n\n addOptions() {\n return { items: [], emptyText: '', loadingText: '' }\n },\n\n addProseMirrorPlugins() {\n const { items, emptyText, loadingText } = this.options\n return [Suggestion<SlashCommandItem>({\n pluginKey: SlashCommandPluginKey,\n editor: this.editor,\n char: '/',\n startOfLine: true,\n // `shouldShow` runs inside the plugin's `apply`, before `editor.state` is the new state: resolve in the new doc.\n shouldShow: ({ editor, range, query, transaction }) => {\n const $from = transaction.doc.resolve(range.from)\n return $from.parentOffset === 0 && range.to === $from.end() && !$from.parent.type.spec.code\n && matching(items, query, abilitiesAt(editor, $from)).length > 0\n },\n items: ({ editor, query }) => matching(items, query, abilitiesAt(editor, editor.state.selection.$from)),\n command: ({ editor, range, props: item }) => {\n editor.chain().focus().deleteRange(range).run()\n item.run(editor)\n },\n render: createSuggestionRender<SlashCommandItem>({\n display: item => ({ label: item.label, description: `/${item.id}`, icon: item.icon }),\n emptyText,\n loadingText,\n }),\n })]\n },\n})\n"],"mappings":";;;;;;AAiBA,SAAS,SAAS,OAA2B,OAAe,WAAqD;CAC/G,MAAM,IAAI,MAAM,YAAY;CAC5B,OAAO,MAAM,QAAO,UAAS,CAAC,KAAK,WAAW,UAAU,IAAI,KAAK,OAAO,OAClE,KAAK,GAAG,WAAW,CAAC,KAAK,KAAK,MAAM,YAAY,CAAC,CAAC,WAAW,CAAC,EAAE;AACxE;;AAGA,MAAa,wBAAwB,IAAI,UAAU,cAAc;;;;;;;;AASjE,MAAa,eAAe,UAAU,OAA4B;CAChE,MAAM;CAEN,aAAa;EACX,OAAO;GAAE,OAAO,CAAC;GAAG,WAAW;GAAI,aAAa;EAAG;CACrD;CAEA,wBAAwB;EACtB,MAAM,EAAE,OAAO,WAAW,gBAAgB,KAAK;EAC/C,OAAO,CAAC,WAA6B;GACnC,WAAW;GACX,QAAQ,KAAK;GACb,MAAM;GACN,aAAa;GAEb,aAAa,EAAE,QAAQ,OAAO,OAAO,kBAAkB;IACrD,MAAM,QAAQ,YAAY,IAAI,QAAQ,MAAM,IAAI;IAChD,OAAO,MAAM,iBAAiB,KAAK,MAAM,OAAO,MAAM,IAAI,KAAK,CAAC,MAAM,OAAO,KAAK,KAAK,QAClF,SAAS,OAAO,OAAO,YAAY,QAAQ,KAAK,CAAC,CAAC,CAAC,SAAS;GACnE;GACA,QAAQ,EAAE,QAAQ,YAAY,SAAS,OAAO,OAAO,YAAY,QAAQ,OAAO,MAAM,UAAU,KAAK,CAAC;GACtG,UAAU,EAAE,QAAQ,OAAO,OAAO,WAAW;IAC3C,OAAO,MAAM,CAAC,CAAC,MAAM,CAAC,CAAC,YAAY,KAAK,CAAC,CAAC,IAAI;IAC9C,KAAK,IAAI,MAAM;GACjB;GACA,QAAQ,uBAAyC;IAC/C,UAAS,UAAS;KAAE,OAAO,KAAK;KAAO,aAAa,IAAI,KAAK;KAAM,MAAM,KAAK;IAAK;IACnF;IACA;GACF,CAAC;EACH,CAAC,CAAC;CACJ;AACF,CAAC"}
1
+ {"version":3,"file":"slash.js","names":[],"sources":["../../src/core/slash.ts"],"sourcesContent":["import { type Editor, Extension } from '@tiptap/core'\nimport type { ResolvedPos } from '@tiptap/pm/model'\nimport { PluginKey } from '@tiptap/pm/state'\nimport { Suggestion } from '@tiptap/suggestion'\nimport { type CommandDef, commandState } from './commands'\nimport { createSuggestionRender } from './suggestion-popup'\n\n/** A command with a `/` placement: only `run` commands have one. */\ntype SlashCommandDef = CommandDef & { run: (editor: Editor) => void, slash: { id?: string } }\n\nexport interface SlashCommandOptions {\n /** The final command list (features' commands after the host's `commands` transformer); the ones with a `slash` placement make the menu. */\n commands: CommandDef[]\n /** Popup text while no command matches the typed query (`ctx.t('slash.empty')`). */\n emptyText: string\n /** Popup text while the commands are pending (`ctx.t('common.loading')`). */\n loadingText: string\n}\n\nconst slashIdOf = (cmd: SlashCommandDef) => cmd.slash.id ?? cmd.id\n\n/** The slash commands that are visible and enabled at the caret (`$at` when the editor state lags, see `commandState`) and whose slash id or label starts with `query`. */\nfunction matching(editor: Editor, commands: CommandDef[], query: string, $at?: ResolvedPos): SlashCommandDef[] {\n const q = query.toLowerCase()\n return commands.filter((cmd): cmd is SlashCommandDef => {\n if (!cmd.slash || !('run' in cmd)) return false\n if (!(slashIdOf(cmd as SlashCommandDef).startsWith(q) || cmd.label.toLowerCase().startsWith(q))) return false\n const state = commandState(editor, cmd, 'caret', $at)\n return state.visible && state.enabled\n })\n}\n\n/** Own key, so the `/` popup runs next to the `@` and `#` popups. */\nexport const SlashCommandPluginKey = new PluginKey('slashCommand')\n\n/**\n * `/` menu on an empty line: typing `/` as the only content of a textblock (outside code) opens the shared suggestion\n * popup with the commands that have a `slash` placement and are visible and enabled at the caret (`commandState`: ability,\n * structural check, schema and accepted-children fit) whose slash id or label starts with the typed query; picking one\n * deletes `/query` and runs it. A query no such command matches (`/foo`) shows nothing and stays plain text. The commands\n * come from features and the host.\n * Client-only: not part of the Vue-free schema.\n */\nexport const SlashCommand = Extension.create<SlashCommandOptions>({\n name: 'slashCommand',\n\n addOptions() {\n return { commands: [], emptyText: '', loadingText: '' }\n },\n\n addProseMirrorPlugins() {\n const { commands, emptyText, loadingText } = this.options\n return [Suggestion<SlashCommandDef>({\n pluginKey: SlashCommandPluginKey,\n editor: this.editor,\n char: '/',\n startOfLine: true,\n // `shouldShow` runs inside the plugin's `apply`, before `editor.state` is the new state: resolve in the new doc.\n shouldShow: ({ editor, range, query, transaction }) => {\n const $from = transaction.doc.resolve(range.from)\n return $from.parentOffset === 0 && range.to === $from.end() && !$from.parent.type.spec.code\n && matching(editor, commands, query, $from).length > 0\n },\n items: ({ editor, query }) => matching(editor, commands, query),\n command: ({ editor, range, props: cmd }) => {\n editor.chain().focus().deleteRange(range).run()\n cmd.run(editor)\n },\n render: createSuggestionRender<SlashCommandDef>({\n display: cmd => ({ label: cmd.label, description: `/${slashIdOf(cmd)}`, icon: cmd.icon }),\n emptyText,\n loadingText,\n }),\n })]\n },\n})\n"],"mappings":";;;;;;AAmBA,MAAM,aAAa,QAAyB,IAAI,MAAM,MAAM,IAAI;;AAGhE,SAAS,SAAS,QAAgB,UAAwB,OAAe,KAAsC;CAC7G,MAAM,IAAI,MAAM,YAAY;CAC5B,OAAO,SAAS,QAAQ,QAAgC;EACtD,IAAI,CAAC,IAAI,SAAS,EAAE,SAAS,MAAM,OAAO;EAC1C,IAAI,EAAE,UAAU,GAAsB,CAAC,CAAC,WAAW,CAAC,KAAK,IAAI,MAAM,YAAY,CAAC,CAAC,WAAW,CAAC,IAAI,OAAO;EACxG,MAAM,QAAQ,aAAa,QAAQ,KAAK,SAAS,GAAG;EACpD,OAAO,MAAM,WAAW,MAAM;CAChC,CAAC;AACH;;AAGA,MAAa,wBAAwB,IAAI,UAAU,cAAc;;;;;;;;;AAUjE,MAAa,eAAe,UAAU,OAA4B;CAChE,MAAM;CAEN,aAAa;EACX,OAAO;GAAE,UAAU,CAAC;GAAG,WAAW;GAAI,aAAa;EAAG;CACxD;CAEA,wBAAwB;EACtB,MAAM,EAAE,UAAU,WAAW,gBAAgB,KAAK;EAClD,OAAO,CAAC,WAA4B;GAClC,WAAW;GACX,QAAQ,KAAK;GACb,MAAM;GACN,aAAa;GAEb,aAAa,EAAE,QAAQ,OAAO,OAAO,kBAAkB;IACrD,MAAM,QAAQ,YAAY,IAAI,QAAQ,MAAM,IAAI;IAChD,OAAO,MAAM,iBAAiB,KAAK,MAAM,OAAO,MAAM,IAAI,KAAK,CAAC,MAAM,OAAO,KAAK,KAAK,QAClF,SAAS,QAAQ,UAAU,OAAO,KAAK,CAAC,CAAC,SAAS;GACzD;GACA,QAAQ,EAAE,QAAQ,YAAY,SAAS,QAAQ,UAAU,KAAK;GAC9D,UAAU,EAAE,QAAQ,OAAO,OAAO,UAAU;IAC1C,OAAO,MAAM,CAAC,CAAC,MAAM,CAAC,CAAC,YAAY,KAAK,CAAC,CAAC,IAAI;IAC9C,IAAI,IAAI,MAAM;GAChB;GACA,QAAQ,uBAAwC;IAC9C,UAAS,SAAQ;KAAE,OAAO,IAAI;KAAO,aAAa,IAAI,UAAU,GAAG;KAAK,MAAM,IAAI;IAAK;IACvF;IACA;GACF,CAAC;EACH,CAAC,CAAC;CACJ;AACF,CAAC"}
@@ -1,10 +1,12 @@
1
+ import { ROOT_ABILITIES } from "./schema/abilities.js";
1
2
  import { presetExtension } from "./pipeline.js";
2
- import { createMetadataRegistry } from "./metadata.js";
3
- import { SuggestionPopup } from "./suggestion-popup.js";
4
3
  import { contributions } from "./define-editor.js";
4
+ import { createMetadataRegistry } from "./metadata.js";
5
5
  import { registerEditor } from "./editor-ui.js";
6
- import { blockActionsOf, createFeatureContext } from "./feature-context.js";
6
+ import { toolbarOf } from "./commands.js";
7
7
  import { EMPTY_EDITOR_CONTENT } from "./schema/index.js";
8
+ import { SuggestionPopup } from "./suggestion-popup.js";
9
+ import { blockActionsOf, createFeatureContext } from "./feature-context.js";
8
10
  import { getSchema } from "@tiptap/core";
9
11
  //#region src/core/surface-session.ts
10
12
  /**
@@ -17,6 +19,10 @@ import { getSchema } from "@tiptap/core";
17
19
  function createSurfaceSession(options) {
18
20
  const { app, preset, ui, collaboration, getEditor } = options;
19
21
  if (collaboration && !preset.features.some((feature) => feature.id === "collab")) throw new Error("@ecsplico/editor: `collaboration` needs a preset with the collaboration feature");
22
+ for (const feature of preset.features) for (const capability of feature.backend ?? []) {
23
+ if (capability === "collaboration") continue;
24
+ if (!app.backend[capability]) throw new Error(`@ecsplico/editor: feature "${feature.id}" needs backend capability "${capability}", which "${app.backend.name}" lacks`);
25
+ }
20
26
  const registry = createMetadataRegistry({ onCreate: (list, item) => options.onMetadataCreate?.(list, item) });
21
27
  registry.replace({ ...options.metadata });
22
28
  const ctx = createFeatureContext({
@@ -27,11 +33,13 @@ function createSurfaceSession(options) {
27
33
  notify: options.notify,
28
34
  getEditor,
29
35
  ...options.documentId !== void 0 && { documentId: options.documentId },
30
- ...options.upload && { upload: options.upload },
31
36
  ...collaboration && { collaboration },
32
37
  ...options.abilities && { abilities: options.abilities },
33
- ...options.slashCommands && { slashCommands: options.slashCommands }
38
+ ...options.commands && { commands: options.commands }
34
39
  });
40
+ toolbarOf(preset, ctx);
41
+ const root = new Set(options.abilities?.root ?? ROOT_ABILITIES);
42
+ for (const cmd of ctx.commands()) if (cmd.ability && !root.has(cmd.ability)) console.warn(`@ecsplico/editor: command "${cmd.id}" needs ability "${cmd.ability}", which neither ROOT_ABILITIES nor \`abilities.root\` grants; it stays unavailable at document root`);
35
43
  const extensions = [
36
44
  presetExtension(preset),
37
45
  SuggestionPopup.configure({ renderer: options.suggestionRenderer }),
@@ -1 +1 @@
1
- {"version":3,"file":"surface-session.js","names":[],"sources":["../../src/core/surface-session.ts"],"sourcesContent":["import { type AnyExtension, type Editor, type EditorOptions, getSchema, type JSONContent } from '@tiptap/core'\nimport type { EditorContext } from './context'\nimport { contributions } from './define-editor'\nimport { type EditorUi, registerEditor } from './editor-ui'\nimport type { AbilitiesOptions, BlockAction, SlashCommandItem } from './extension-points'\nimport type { CollaborationSession, EditorPreset, UploadFn } from './feature'\nimport { blockActionsOf, createFeatureContext } from './feature-context'\nimport { createMetadataRegistry } from './metadata'\nimport type { EditorMetadata, MetadataItem } from './metadata-types'\nimport type { Notifier } from './notify'\nimport { presetExtension } from './pipeline'\nimport { EMPTY_EDITOR_CONTENT } from './schema'\nimport { SuggestionPopup, type SuggestionPopupRenderer } from './suggestion-popup'\n\n/**\n * What a surface hands its session. The framework layer owns everything that lives in its reactivity: the chrome\n * (`ui`), the notice renderer, the suggestion popup renderer and the editor instance (`getEditor`).\n * `preset`, `collaboration`, `documentId`, `upload`, `abilities`, `extensions`, `blockActions`, `slashCommands`, `value` and\n * `editable` are read once, when the session is created; later changes reach it through `setValue`, `setEditable` and\n * `setMetadata`.\n */\nexport interface SurfaceSessionOptions<C = unknown> {\n app: EditorContext\n /** The features the editor is made of. With `collaboration` it must contain the collaboration feature (else creating the session throws). */\n preset: EditorPreset<C>\n /** The chrome the features reach through `FeatureContext.ui`; registered for the editor by `register`. */\n ui: EditorUi\n /** The surface's notice renderer (`FeatureContext.notify`). */\n notify: Notifier\n /** The framework's popup for `@` / `#` / `/` suggestions. */\n suggestionRenderer: SuggestionPopupRenderer\n /** The mounted editor, `undefined` until the framework layer created it; used by `FeatureContext.getEditor`, `setValue` and `setEditable`. */\n getEditor: () => Editor | undefined\n /** Collaborative mode: the Y.Doc is the document, so there is no `value` and no `onChange`. */\n collaboration?: CollaborationSession | undefined\n /** Standalone initial document (TipTap JSON, unproxied); absent = an empty document. */\n value?: JSONContent | undefined\n /** Default `true`. */\n editable?: boolean | undefined\n /** The host's lists; later ones go through `setMetadata`. */\n metadata?: EditorMetadata | undefined\n documentId?: string | undefined\n upload?: UploadFn | undefined\n abilities?: Partial<AbilitiesOptions> | undefined\n slashCommands?: ((defaults: SlashCommandItem[]) => SlashCommandItem[]) | undefined\n /** Added after the features' extensions. */\n extensions?: readonly AnyExtension[] | undefined\n /** Added after the features' block actions. */\n blockActions?: readonly BlockAction[] | undefined\n /** Standalone: the document after every edit (the JSON the session remembers as its own, see `setValue`). */\n onChange?: ((content: JSONContent) => void) | undefined\n /** A new item was created in a metadata list. */\n onMetadataCreate?: ((list: string, item: MetadataItem) => void) | undefined\n /** A document handed in (initially or through `setValue`) does not fit the schema. */\n onContentError?: ((error: Error) => void) | undefined\n /** A mounted editor was registered for the first time (see `register`). */\n onReady?: ((editor: Editor) => void) | undefined\n}\n\n/**\n * Everything of an `EditorSurface` that does not depend on the UI framework: the preset's extensions and context,\n * the document's validation and echo handling, the features' `setup` lifecycle and the registration of the editor's\n * chrome. The framework layer creates the session once (state of the component instance), mounts a TipTap editor from\n * `editorOptions`, and forwards prop changes and lifecycle moments to it.\n */\nexport interface SurfaceSession<C = unknown> {\n /**\n * Options for the TipTap editor. Standalone mode (no `collaboration`) carries the initial document (`content`, already\n * migrated; an empty document when the given one was rejected) and the `onUpdate` that feeds `onChange`. The framework\n * layer may add its own options (rendering flags) but must not replace these.\n */\n readonly editorOptions: Partial<EditorOptions> & { extensions: AnyExtension[] }\n /** The features' overlay components, in feature order; the framework layer renders them beside the editor with `{ editor }`. */\n readonly overlays: readonly C[]\n /**\n * Starts the features' `setup` contributions, then reports a rejected initial document through `onContentError` (once\n * per session, not per activation). A no-op while active. Pair every activation with `deactivate`: React StrictMode\n * mounts, cleans up and mounts again, which must leave exactly one active setup.\n */\n activate: () => void\n /** Runs the teardowns of the active `setup` contributions, in the order they were started; a no-op while inactive. */\n deactivate: () => void\n /**\n * Registers the chrome of `editor` (the raw instance, see `registerEditor`) and announces it through `onReady` the\n * first time this editor is registered, so a host toolbar that receives it finds the chrome. Returns the unregister\n * function (idempotent). Call it again after the framework layer replaced the editor instance.\n */\n register: (editor: Editor) => () => void\n /**\n * The host's document changed (standalone only; ignored with `collaboration`). Not an edit: no `onChange`, no update\n * event. Ignored when `value` is the very object `onChange` last received (the host handing the surface's own JSON\n * back), is absent, or was already given; otherwise it is migrated and checked against the schema and applied, or\n * reported through `onContentError` with the current document kept. A missing or destroyed editor ignores it.\n */\n setValue: (value: JSONContent | undefined) => void\n /**\n * Switches the editor's editable state; ignored when it equals the last given one, and while no (or a destroyed)\n * editor exists. TipTap's `setEditable(…, false)` changes the flag without any event, so it is followed by an empty\n * `addToHistory: false` transaction: components that follow `isEditable` on `transaction` (block UI, the composite\n * inspector) notice. It has no steps, so nothing syncs and the history is untouched.\n */\n setEditable: (editable: boolean) => void\n /** Replaces the host's metadata lists; ignored when `metadata` is the object that was last given. */\n setMetadata: (metadata: EditorMetadata | undefined) => void\n}\n\n/**\n * Builds the session of one mounted surface: metadata registry, feature context, the extension list, the block actions\n * and the initial document. Throws when `collaboration` is given and the preset has no collaboration feature. Extension\n * order is fixed: the preset extension, the suggestion popup, the features' extensions in feature order, the host's.\n * The document is checked as `preset.pipeline.migrateContent` followed by the schema's `check()`; a failure is an error\n * value, never a throw.\n */\nexport function createSurfaceSession<C = unknown>(options: SurfaceSessionOptions<C>): SurfaceSession<C> {\n const { app, preset, ui, collaboration, getEditor } = options\n if (collaboration && !preset.features.some(feature => feature.id === 'collab')) {\n throw new Error('@ecsplico/editor: `collaboration` needs a preset with the collaboration feature')\n }\n\n const registry = createMetadataRegistry({ onCreate: (list, item) => options.onMetadataCreate?.(list, item) })\n registry.replace({ ...options.metadata })\n\n const ctx = createFeatureContext({\n app,\n preset,\n ui,\n metadata: registry,\n notify: options.notify,\n getEditor,\n ...(options.documentId !== undefined && { documentId: options.documentId }),\n ...(options.upload && { upload: options.upload }),\n ...(collaboration && { collaboration }),\n ...(options.abilities && { abilities: options.abilities }),\n ...(options.slashCommands && { slashCommands: options.slashCommands }),\n })\n\n const extensions: AnyExtension[] = [\n presetExtension(preset),\n SuggestionPopup.configure({ renderer: options.suggestionRenderer }),\n ...contributions(preset, 'extensions').flatMap(factory => factory(ctx)),\n ...(options.extensions ?? []),\n ]\n const schema = getSchema(extensions)\n const overlays = preset.features.flatMap(feature => [...(feature.overlays ?? [])])\n const blockActions = blockActionsOf(preset, ctx, options.blockActions)\n\n const validated = (json: JSONContent): { json: JSONContent } | { error: Error } => {\n try {\n const migrated = preset.pipeline.migrateContent(json)\n schema.nodeFromJSON(migrated).check()\n return { json: migrated }\n }\n catch (error) {\n return { error: error instanceof Error ? error : new Error(String(error)) }\n }\n }\n\n // Standalone: the JSON last sent through `onChange`; the host handing it back is not an external change.\n let lastEmitted: JSONContent | undefined\n let pendingContentError: Error | undefined\n const editorOptions: SurfaceSession<C>['editorOptions'] = {\n extensions,\n editable: options.editable ?? true,\n editorProps: { attributes: { class: 'tiptap' } },\n }\n if (!collaboration) {\n const initial = options.value ? validated(options.value) : { json: EMPTY_EDITOR_CONTENT }\n if ('error' in initial) pendingContentError = initial.error\n editorOptions.content = 'json' in initial ? initial.json : EMPTY_EDITOR_CONTENT\n editorOptions.onUpdate = ({ editor }) => {\n lastEmitted = editor.getJSON()\n options.onChange?.(lastEmitted)\n }\n }\n\n // What the setters below already applied; they only react to a change.\n let appliedValue = options.value\n let appliedEditable = options.editable ?? true\n let appliedMetadata = options.metadata\n // Teardowns of the `setup` contributions that are currently active; undefined while inactive.\n let teardowns: (() => void)[] | undefined\n let announced: Editor | undefined\n\n return {\n editorOptions,\n overlays,\n activate() {\n if (teardowns) return\n const active: (() => void)[] = []\n teardowns = active\n for (const run of contributions(preset, 'setup')) {\n const teardown = run(ctx)\n if (teardown) active.push(teardown)\n }\n if (pendingContentError) {\n const error = pendingContentError\n pendingContentError = undefined\n options.onContentError?.(error)\n }\n },\n deactivate() {\n const active = teardowns\n teardowns = undefined\n for (const teardown of active ?? []) teardown()\n },\n register(editor) {\n const unregister = registerEditor(editor, { ui, preset, ctx, blockActions })\n if (announced !== editor) {\n announced = editor\n options.onReady?.(editor)\n }\n return unregister\n },\n setValue(value) {\n if (value === appliedValue) return\n appliedValue = value\n const editor = getEditor()\n if (collaboration || !value || !editor || editor.isDestroyed || value === lastEmitted) return\n const checked = validated(value)\n if ('error' in checked) {\n options.onContentError?.(checked.error)\n return\n }\n editor.commands.setContent(checked.json, { emitUpdate: false })\n },\n setEditable(editable) {\n if (editable === appliedEditable) return\n appliedEditable = editable\n const editor = getEditor()\n if (!editor || editor.isDestroyed) return\n editor.setEditable(editable, false)\n editor.view.dispatch(editor.state.tr.setMeta('addToHistory', false))\n },\n setMetadata(metadata) {\n if (metadata === appliedMetadata) return\n appliedMetadata = metadata\n registry.replace({ ...metadata })\n },\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"surface-session.js","names":[],"sources":["../../src/core/surface-session.ts"],"sourcesContent":["import { type AnyExtension, type Editor, type EditorOptions, getSchema, type JSONContent } from '@tiptap/core'\nimport type { EditorContext } from './context'\nimport { contributions } from './define-editor'\nimport { type EditorUi, registerEditor } from './editor-ui'\nimport { type CommandDef, toolbarOf } from './commands'\nimport type { AbilitiesOptions, BlockAction } from './extension-points'\nimport type { CollaborationSession, EditorPreset } from './feature'\nimport { blockActionsOf, createFeatureContext } from './feature-context'\nimport { createMetadataRegistry } from './metadata'\nimport type { EditorMetadata, MetadataItem } from './metadata-types'\nimport type { Notifier } from './notify'\nimport { presetExtension } from './pipeline'\nimport { EMPTY_EDITOR_CONTENT } from './schema'\nimport { ROOT_ABILITIES } from './schema/abilities'\nimport { SuggestionPopup, type SuggestionPopupRenderer } from './suggestion-popup'\n\n/**\n * What a surface hands its session. The framework layer owns everything that lives in its reactivity: the chrome\n * (`ui`), the notice renderer, the suggestion popup renderer and the editor instance (`getEditor`).\n * `preset`, `collaboration`, `documentId`, `abilities`, `extensions`, `blockActions`, `commands`, `value` and\n * `editable` are read once, when the session is created; later changes reach it through `setValue`, `setEditable` and\n * `setMetadata`.\n */\nexport interface SurfaceSessionOptions<C = unknown> {\n app: EditorContext\n /** The features the editor is made of. With `collaboration` it must contain the collaboration feature (else creating the session throws). */\n preset: EditorPreset<C>\n /** The chrome the features reach through `FeatureContext.ui`; registered for the editor by `register`. */\n ui: EditorUi\n /** The surface's notice renderer (`FeatureContext.notify`). */\n notify: Notifier\n /** The framework's popup for `@` / `#` / `/` suggestions. */\n suggestionRenderer: SuggestionPopupRenderer\n /** The mounted editor, `undefined` until the framework layer created it; used by `FeatureContext.getEditor`, `setValue` and `setEditable`. */\n getEditor: () => Editor | undefined\n /** Collaborative mode: the Y.Doc is the document, so there is no `value` and no `onChange`. */\n collaboration?: CollaborationSession | undefined\n /** Standalone initial document (TipTap JSON, unproxied); absent = an empty document. */\n value?: JSONContent | undefined\n /** Default `true`. */\n editable?: boolean | undefined\n /** The host's lists; later ones go through `setMetadata`. */\n metadata?: EditorMetadata | undefined\n documentId?: string | undefined\n abilities?: Partial<AbilitiesOptions> | undefined\n commands?: ((defaults: CommandDef[]) => CommandDef[]) | undefined\n /** Added after the features' extensions. */\n extensions?: readonly AnyExtension[] | undefined\n /** Added after the features' block actions. */\n blockActions?: readonly BlockAction[] | undefined\n /** Standalone: the document after every edit (the JSON the session remembers as its own, see `setValue`). */\n onChange?: ((content: JSONContent) => void) | undefined\n /** A new item was created in a metadata list. */\n onMetadataCreate?: ((list: string, item: MetadataItem) => void) | undefined\n /** A document handed in (initially or through `setValue`) does not fit the schema. */\n onContentError?: ((error: Error) => void) | undefined\n /** A mounted editor was registered for the first time (see `register`). */\n onReady?: ((editor: Editor) => void) | undefined\n}\n\n/**\n * Everything of an `EditorSurface` that does not depend on the UI framework: the preset's extensions and context,\n * the document's validation and echo handling, the features' `setup` lifecycle and the registration of the editor's\n * chrome. The framework layer creates the session once (state of the component instance), mounts a TipTap editor from\n * `editorOptions`, and forwards prop changes and lifecycle moments to it.\n */\nexport interface SurfaceSession<C = unknown> {\n /**\n * Options for the TipTap editor. Standalone mode (no `collaboration`) carries the initial document (`content`, already\n * migrated; an empty document when the given one was rejected) and the `onUpdate` that feeds `onChange`. The framework\n * layer may add its own options (rendering flags) but must not replace these.\n */\n readonly editorOptions: Partial<EditorOptions> & { extensions: AnyExtension[] }\n /** The features' overlay components, in feature order; the framework layer renders them beside the editor with `{ editor }`. */\n readonly overlays: readonly C[]\n /**\n * Starts the features' `setup` contributions, then reports a rejected initial document through `onContentError` (once\n * per session, not per activation). A no-op while active. Pair every activation with `deactivate`: React StrictMode\n * mounts, cleans up and mounts again, which must leave exactly one active setup.\n */\n activate: () => void\n /** Runs the teardowns of the active `setup` contributions, in the order they were started; a no-op while inactive. */\n deactivate: () => void\n /**\n * Registers the chrome of `editor` (the raw instance, see `registerEditor`) and announces it through `onReady` the\n * first time this editor is registered, so a host toolbar that receives it finds the chrome. Returns the unregister\n * function (idempotent). Call it again after the framework layer replaced the editor instance.\n */\n register: (editor: Editor) => () => void\n /**\n * The host's document changed (standalone only; ignored with `collaboration`). Not an edit: no `onChange`, no update\n * event. Ignored when `value` is the very object `onChange` last received (the host handing the surface's own JSON\n * back), is absent, or was already given; otherwise it is migrated and checked against the schema and applied, or\n * reported through `onContentError` with the current document kept. A missing or destroyed editor ignores it.\n */\n setValue: (value: JSONContent | undefined) => void\n /**\n * Switches the editor's editable state; ignored when it equals the last given one, and while no (or a destroyed)\n * editor exists. TipTap's `setEditable(…, false)` changes the flag without any event, so it is followed by an empty\n * `addToHistory: false` transaction: components that follow `isEditable` on `transaction` (block UI, the composite\n * inspector) notice. It has no steps, so nothing syncs and the history is untouched.\n */\n setEditable: (editable: boolean) => void\n /** Replaces the host's metadata lists; ignored when `metadata` is the object that was last given. */\n setMetadata: (metadata: EditorMetadata | undefined) => void\n}\n\n/**\n * Builds the session of one mounted surface: metadata registry, feature context, the extension list, the block actions\n * and the initial document. Throws when `collaboration` is given and the preset has no collaboration feature. Extension\n * order is fixed: the preset extension, the suggestion popup, the features' extensions in feature order, the host's.\n * The document is checked as `preset.pipeline.migrateContent` followed by the schema's `check()`; a failure is an error\n * value, never a throw.\n */\nexport function createSurfaceSession<C = unknown>(options: SurfaceSessionOptions<C>): SurfaceSession<C> {\n const { app, preset, ui, collaboration, getEditor } = options\n if (collaboration && !preset.features.some(feature => feature.id === 'collab')) {\n throw new Error('@ecsplico/editor: `collaboration` needs a preset with the collaboration feature')\n }\n // The surface only consumes a `collaboration` session the host opened (`useEditorDocument(id, { collaboration })`\n // opens it through `backend.collaboration` and checks that itself), so the collaboration capability is never needed\n // here: a host with its own provider mounts the collaboration feature over a backend that offers none.\n for (const feature of preset.features) {\n for (const capability of feature.backend ?? []) {\n if (capability === 'collaboration') continue\n if (!app.backend[capability]) {\n throw new Error(`@ecsplico/editor: feature \"${feature.id}\" needs backend capability \"${capability}\", which \"${app.backend.name}\" lacks`)\n }\n }\n }\n\n const registry = createMetadataRegistry({ onCreate: (list, item) => options.onMetadataCreate?.(list, item) })\n registry.replace({ ...options.metadata })\n\n const ctx = createFeatureContext({\n app,\n preset,\n ui,\n metadata: registry,\n notify: options.notify,\n getEditor,\n ...(options.documentId !== undefined && { documentId: options.documentId }),\n ...(collaboration && { collaboration }),\n ...(options.abilities && { abilities: options.abilities }),\n ...(options.commands && { commands: options.commands }),\n })\n // Fails here, not on the first toolbar render, when a command names a toolbar group no feature declares.\n toolbarOf(preset, ctx)\n // A command whose ability the document root does not grant never shows (its state is permanently disabled): say so once.\n const root = new Set<string>(options.abilities?.root ?? ROOT_ABILITIES)\n for (const cmd of ctx.commands()) {\n if (cmd.ability && !root.has(cmd.ability)) {\n console.warn(`@ecsplico/editor: command \"${cmd.id}\" needs ability \"${cmd.ability}\", which neither ROOT_ABILITIES nor \\`abilities.root\\` grants; it stays unavailable at document root`)\n }\n }\n\n const extensions: AnyExtension[] = [\n presetExtension(preset),\n SuggestionPopup.configure({ renderer: options.suggestionRenderer }),\n ...contributions(preset, 'extensions').flatMap(factory => factory(ctx)),\n ...(options.extensions ?? []),\n ]\n const schema = getSchema(extensions)\n const overlays = preset.features.flatMap(feature => [...(feature.overlays ?? [])])\n const blockActions = blockActionsOf(preset, ctx, options.blockActions)\n\n const validated = (json: JSONContent): { json: JSONContent } | { error: Error } => {\n try {\n const migrated = preset.pipeline.migrateContent(json)\n schema.nodeFromJSON(migrated).check()\n return { json: migrated }\n }\n catch (error) {\n return { error: error instanceof Error ? error : new Error(String(error)) }\n }\n }\n\n // Standalone: the JSON last sent through `onChange`; the host handing it back is not an external change.\n let lastEmitted: JSONContent | undefined\n let pendingContentError: Error | undefined\n const editorOptions: SurfaceSession<C>['editorOptions'] = {\n extensions,\n editable: options.editable ?? true,\n editorProps: { attributes: { class: 'tiptap' } },\n }\n if (!collaboration) {\n const initial = options.value ? validated(options.value) : { json: EMPTY_EDITOR_CONTENT }\n if ('error' in initial) pendingContentError = initial.error\n editorOptions.content = 'json' in initial ? initial.json : EMPTY_EDITOR_CONTENT\n editorOptions.onUpdate = ({ editor }) => {\n lastEmitted = editor.getJSON()\n options.onChange?.(lastEmitted)\n }\n }\n\n // What the setters below already applied; they only react to a change.\n let appliedValue = options.value\n let appliedEditable = options.editable ?? true\n let appliedMetadata = options.metadata\n // Teardowns of the `setup` contributions that are currently active; undefined while inactive.\n let teardowns: (() => void)[] | undefined\n let announced: Editor | undefined\n\n return {\n editorOptions,\n overlays,\n activate() {\n if (teardowns) return\n const active: (() => void)[] = []\n teardowns = active\n for (const run of contributions(preset, 'setup')) {\n const teardown = run(ctx)\n if (teardown) active.push(teardown)\n }\n if (pendingContentError) {\n const error = pendingContentError\n pendingContentError = undefined\n options.onContentError?.(error)\n }\n },\n deactivate() {\n const active = teardowns\n teardowns = undefined\n for (const teardown of active ?? []) teardown()\n },\n register(editor) {\n const unregister = registerEditor(editor, { ui, preset, ctx, blockActions })\n if (announced !== editor) {\n announced = editor\n options.onReady?.(editor)\n }\n return unregister\n },\n setValue(value) {\n if (value === appliedValue) return\n appliedValue = value\n const editor = getEditor()\n if (collaboration || !value || !editor || editor.isDestroyed || value === lastEmitted) return\n const checked = validated(value)\n if ('error' in checked) {\n options.onContentError?.(checked.error)\n return\n }\n editor.commands.setContent(checked.json, { emitUpdate: false })\n },\n setEditable(editable) {\n if (editable === appliedEditable) return\n appliedEditable = editable\n const editor = getEditor()\n if (!editor || editor.isDestroyed) return\n editor.setEditable(editable, false)\n editor.view.dispatch(editor.state.tr.setMeta('addToHistory', false))\n },\n setMetadata(metadata) {\n if (metadata === appliedMetadata) return\n appliedMetadata = metadata\n registry.replace({ ...metadata })\n },\n }\n}\n"],"mappings":"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"}
@@ -1,10 +1,16 @@
1
- import { ToolbarGroup } from "./toolbar.js";
1
+ import { CommandDef, ToolbarGroupDef } from "./command-types.js";
2
2
  import { FeatureContext } from "./feature.js";
3
3
  //#region src/core/toolbar-items.d.ts
4
4
  /**
5
- * The core toolbar: undo/redo, paragraph and headings, text marks, lists, quote, code block
6
- * and rule. Orders leave room for the groups features contribute.
5
+ * The toolbar groups of the core UI (undo/redo, paragraph and headings, text marks, lists/quote/code block/rule) and the
6
+ * two groups other features' commands name: `inserts` (media, transcript, …) and `collaboration` (comments, authors).
7
+ * Orders leave room for the groups features contribute (composites and tables 60, AI 1000).
7
8
  */
8
- export declare function coreToolbarGroups(ctx: FeatureContext): ToolbarGroup<never>[];
9
+ export declare const CORE_TOOLBAR_GROUPS: ToolbarGroupDef[];
10
+ /**
11
+ * The core commands: undo/redo, paragraph and headings, text marks, lists, quote, code block and rule. The five block
12
+ * types (headings, lists, quote, code block, rule) are also in the `/` menu.
13
+ */
14
+ export declare function coreCommands(ctx: FeatureContext): CommandDef<never>[];
9
15
  //#endregion
10
16
  //# sourceMappingURL=toolbar-items.d.ts.map