@ecsplico/editor 2.1.1 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (701) hide show
  1. package/CHANGELOG.md +74 -1
  2. package/README.md +39 -156
  3. package/dist/adapters/comments/drizzle.d.ts +1 -1
  4. package/dist/adapters/comments/{client.js → rest-model.js} +3 -3
  5. package/dist/adapters/comments/rest-model.js.map +1 -0
  6. package/dist/adapters/comments/types.d.ts +2 -2
  7. package/dist/adapters/document-state.d.ts +23 -0
  8. package/dist/adapters/document-state.js +66 -0
  9. package/dist/adapters/document-state.js.map +1 -0
  10. package/dist/adapters/documents.js +14 -11
  11. package/dist/adapters/documents.js.map +1 -1
  12. package/dist/adapters/drizzle.d.ts +2 -2
  13. package/dist/adapters/drizzle.js +97 -88
  14. package/dist/adapters/drizzle.js.map +1 -1
  15. package/dist/adapters/forge.d.ts +12 -7
  16. package/dist/adapters/forge.js +38 -45
  17. package/dist/adapters/forge.js.map +1 -1
  18. package/dist/adapters/http.d.ts +20 -0
  19. package/dist/adapters/http.js +68 -0
  20. package/dist/adapters/http.js.map +1 -0
  21. package/dist/adapters/index.d.ts +5 -5
  22. package/dist/adapters/json.d.ts +3 -3
  23. package/dist/adapters/json.js +58 -49
  24. package/dist/adapters/json.js.map +1 -1
  25. package/dist/adapters/memory.d.ts +21 -0
  26. package/dist/adapters/memory.js +53 -0
  27. package/dist/adapters/memory.js.map +1 -0
  28. package/dist/adapters/nitro.d.ts +23 -20
  29. package/dist/adapters/nitro.js +58 -163
  30. package/dist/adapters/nitro.js.map +1 -1
  31. package/dist/adapters/react.d.ts +55 -0
  32. package/dist/adapters/react.js +209 -0
  33. package/dist/adapters/react.js.map +1 -0
  34. package/dist/adapters/shared.d.ts +15 -21
  35. package/dist/adapters/shared.js +10 -8
  36. package/dist/adapters/shared.js.map +1 -1
  37. package/dist/adapters/vue.d.ts +15 -30
  38. package/dist/adapters/vue.js +36 -87
  39. package/dist/adapters/vue.js.map +1 -1
  40. package/dist/code/CodeSurface.vue.d.ts +3 -3
  41. package/dist/config/index.d.ts +105 -0
  42. package/dist/config/index.js +95 -0
  43. package/dist/config/index.js.map +1 -0
  44. package/dist/core/abilities.js +1 -0
  45. package/dist/core/abilities.js.map +1 -1
  46. package/dist/{adapters/routes.js → core/api-routes.js} +5 -3
  47. package/dist/core/api-routes.js.map +1 -0
  48. package/dist/core/backend-capability.d.ts +7 -0
  49. package/dist/core/backend-capability.js +17 -0
  50. package/dist/core/backend-capability.js.map +1 -0
  51. package/dist/core/backend-types.d.ts +245 -0
  52. package/dist/core/backend-types.js +17 -0
  53. package/dist/core/backend-types.js.map +1 -0
  54. package/dist/core/backend.d.ts +108 -0
  55. package/dist/core/backend.js +14 -0
  56. package/dist/core/backend.js.map +1 -0
  57. package/dist/core/block-convert.d.ts +7 -5
  58. package/dist/core/block-convert.js +28 -5
  59. package/dist/core/block-convert.js.map +1 -1
  60. package/dist/core/command-types.d.ts +89 -0
  61. package/dist/core/commands.d.ts +40 -0
  62. package/dist/core/commands.js +151 -0
  63. package/dist/core/commands.js.map +1 -0
  64. package/dist/core/context.d.ts +17 -20
  65. package/dist/core/context.js +24 -21
  66. package/dist/core/context.js.map +1 -1
  67. package/dist/core/core-feature.d.ts +22 -7
  68. package/dist/core/core-feature.js +51 -18
  69. package/dist/core/core-feature.js.map +1 -1
  70. package/dist/core/define-editor.d.ts +4 -3
  71. package/dist/core/define-editor.js +14 -7
  72. package/dist/core/define-editor.js.map +1 -1
  73. package/dist/core/document-markdown.js +12 -3
  74. package/dist/core/document-markdown.js.map +1 -1
  75. package/dist/core/editor-ui.d.ts +8 -1
  76. package/dist/core/editor-ui.js +9 -8
  77. package/dist/core/editor-ui.js.map +1 -1
  78. package/dist/core/extension-points.d.ts +3 -15
  79. package/dist/core/feature-context.d.ts +8 -7
  80. package/dist/core/feature-context.js +12 -11
  81. package/dist/core/feature-context.js.map +1 -1
  82. package/dist/core/feature.d.ts +35 -19
  83. package/dist/core/feature.js.map +1 -1
  84. package/dist/core/fences.d.ts +2 -1
  85. package/dist/core/fences.js +3 -2
  86. package/dist/core/fences.js.map +1 -1
  87. package/dist/core/fetch-error.d.ts +1 -1
  88. package/dist/core/fetch-error.js +3 -1
  89. package/dist/core/fetch-error.js.map +1 -1
  90. package/dist/core/hash.d.ts +5 -0
  91. package/dist/core/hash.js +11 -0
  92. package/dist/core/hash.js.map +1 -0
  93. package/dist/core/http-backend.d.ts +11 -0
  94. package/dist/core/http-backend.js +195 -0
  95. package/dist/core/http-backend.js.map +1 -0
  96. package/dist/core/index.d.ts +14 -9
  97. package/dist/core/index.js +12 -9
  98. package/dist/core/palette.d.ts +48 -0
  99. package/dist/core/palette.js +95 -0
  100. package/dist/core/palette.js.map +1 -0
  101. package/dist/core/schema/abilities.d.ts +2 -1
  102. package/dist/core/schema/abilities.js +5 -1
  103. package/dist/core/schema/abilities.js.map +1 -1
  104. package/dist/core/schema/index.d.ts +11 -5
  105. package/dist/core/schema/index.js +13 -8
  106. package/dist/core/schema/index.js.map +1 -1
  107. package/dist/core/schema/mark-flags.d.ts +8 -1
  108. package/dist/core/schema/of-features.d.ts +13 -0
  109. package/dist/core/schema/of-features.js +14 -0
  110. package/dist/core/schema/of-features.js.map +1 -0
  111. package/dist/core/slash.d.ts +8 -6
  112. package/dist/core/slash.js +24 -16
  113. package/dist/core/slash.js.map +1 -1
  114. package/dist/core/surface-session.js +13 -5
  115. package/dist/core/surface-session.js.map +1 -1
  116. package/dist/core/toolbar-items.d.ts +10 -4
  117. package/dist/core/toolbar-items.js +269 -195
  118. package/dist/core/toolbar-items.js.map +1 -1
  119. package/dist/core/util.js +11 -0
  120. package/dist/core/util.js.map +1 -0
  121. package/dist/document/DocumentSurface.d.ts +1 -1
  122. package/dist/document/DocumentSurface.vue.d.ts +3 -3
  123. package/dist/features/ai/agent-op-review.d.ts +1 -1
  124. package/dist/features/ai/agent-op-review.js +1 -1
  125. package/dist/features/ai/agent-ops.js +1 -1
  126. package/dist/features/ai/ai-apply.d.ts +2 -2
  127. package/dist/features/ai/ai-apply.js +1 -1
  128. package/dist/features/ai/ai-review.js +1 -1
  129. package/dist/features/ai/ai-sse.d.ts +6 -6
  130. package/dist/features/ai/ai-sse.js +20 -63
  131. package/dist/features/ai/ai-sse.js.map +1 -1
  132. package/dist/features/ai/assistant.d.ts +8 -7
  133. package/dist/features/ai/assistant.js +3 -3
  134. package/dist/features/ai/assistant.js.map +1 -1
  135. package/dist/features/ai/block-actions.d.ts +3 -2
  136. package/dist/features/ai/block-actions.js +3 -2
  137. package/dist/features/ai/block-actions.js.map +1 -1
  138. package/dist/features/ai/components/AiSelectionMenu.js +1 -1
  139. package/dist/features/ai/components/DocumentChatAnswer.js +1 -1
  140. package/dist/features/ai/components/DocumentChatOps.vue.d.ts +1 -1
  141. package/dist/features/ai/components/SettingsModelProfiles.js +8 -8
  142. package/dist/features/ai/components/SettingsModelProfiles.js.map +1 -1
  143. package/dist/features/ai/document-chat-model.d.ts +8 -7
  144. package/dist/features/ai/document-chat-model.js +5 -5
  145. package/dist/features/ai/document-chat-model.js.map +1 -1
  146. package/dist/features/ai/document-chat.js +1 -1
  147. package/dist/features/ai/feature.js +27 -14
  148. package/dist/features/ai/feature.js.map +1 -1
  149. package/dist/features/ai/ghost-autocomplete.d.ts +7 -6
  150. package/dist/features/ai/ghost-autocomplete.js +6 -9
  151. package/dist/features/ai/ghost-autocomplete.js.map +1 -1
  152. package/dist/features/ai/index.d.ts +4 -3
  153. package/dist/features/ai/index.js +10 -10
  154. package/dist/features/ai/model-profiles.d.ts +5 -4
  155. package/dist/features/ai/model-profiles.js +2 -2
  156. package/dist/features/ai/model-profiles.js.map +1 -1
  157. package/dist/features/ai/protocol/block-lines.js +1 -1
  158. package/dist/features/ai/protocol/block-lines.js.map +1 -1
  159. package/dist/features/ai/protocol/chat.js +4 -1
  160. package/dist/features/ai/protocol/chat.js.map +1 -1
  161. package/dist/features/ai/protocol/index.d.ts +3 -2
  162. package/dist/features/ai/protocol/models.d.ts +2 -16
  163. package/dist/features/ai/protocol/models.js.map +1 -1
  164. package/dist/features/ai/rate-limit.d.ts +1 -1
  165. package/dist/features/ai/rate-limit.js +3 -1
  166. package/dist/features/ai/rate-limit.js.map +1 -1
  167. package/dist/features/ai/react/AiSelectionMenu.js +2 -2
  168. package/dist/features/ai/react/AiSidebar.js +4 -4
  169. package/dist/features/ai/react/DocumentChatAnswer.js +1 -1
  170. package/dist/features/ai/react/DocumentChatOps.d.ts +1 -1
  171. package/dist/features/ai/react/DocumentChatOps.js +1 -1
  172. package/dist/features/ai/react/SettingsModelProfiles.js +8 -10
  173. package/dist/features/ai/react/SettingsModelProfiles.js.map +1 -1
  174. package/dist/features/ai/react/use-ai-assistant.d.ts +1 -1
  175. package/dist/features/ai/react/use-ai-assistant.js +3 -3
  176. package/dist/features/ai/react/use-ai-assistant.js.map +1 -1
  177. package/dist/features/ai/react/use-document-chat.js +2 -2
  178. package/dist/features/ai/react/use-document-chat.js.map +1 -1
  179. package/dist/features/ai/react/use-model-profiles.d.ts +2 -1
  180. package/dist/features/ai/selection-flow.d.ts +1 -1
  181. package/dist/features/ai/selection-flow.js +1 -1
  182. package/dist/features/ai/sidebar-flow.d.ts +1 -1
  183. package/dist/features/ai/sidebar-flow.js +1 -1
  184. package/dist/features/ai/use-ai-assistant.d.ts +1 -1
  185. package/dist/features/ai/use-ai-assistant.js +3 -3
  186. package/dist/features/ai/use-ai-assistant.js.map +1 -1
  187. package/dist/features/ai/use-document-chat.js +2 -2
  188. package/dist/features/ai/use-document-chat.js.map +1 -1
  189. package/dist/features/ai/use-model-profiles.d.ts +2 -1
  190. package/dist/features/authors/attribution.d.ts +1 -1
  191. package/dist/features/authors/feature.js +12 -11
  192. package/dist/features/authors/feature.js.map +1 -1
  193. package/dist/features/block-ui/block-actions.d.ts +22 -1
  194. package/dist/features/block-ui/block-actions.js +26 -2
  195. package/dist/features/block-ui/block-actions.js.map +1 -1
  196. package/dist/features/block-ui/components/BlockActionsOverlay.js +33 -4
  197. package/dist/features/block-ui/components/BlockActionsOverlay.js.map +1 -1
  198. package/dist/features/block-ui/components/BlockActionsOverlay.vue.d.ts +4 -0
  199. package/dist/features/block-ui/components/BlockUi.js +1 -1
  200. package/dist/features/block-ui/feature.js +1 -0
  201. package/dist/features/block-ui/feature.js.map +1 -1
  202. package/dist/features/block-ui/index.d.ts +2 -2
  203. package/dist/features/block-ui/index.js +2 -2
  204. package/dist/features/block-ui/react/BlockActionsOverlay.d.ts +4 -0
  205. package/dist/features/block-ui/react/BlockActionsOverlay.js +38 -12
  206. package/dist/features/block-ui/react/BlockActionsOverlay.js.map +1 -1
  207. package/dist/features/block-ui/react/BlockUi.js +1 -1
  208. package/dist/features/collab/anchor-resolver.js +1 -1
  209. package/dist/features/collab/feature.js +2 -0
  210. package/dist/features/collab/feature.js.map +1 -1
  211. package/dist/features/comments/components/CommentThreadView.vue.d.ts +2 -1
  212. package/dist/features/comments/feature.js +12 -11
  213. package/dist/features/comments/feature.js.map +1 -1
  214. package/dist/features/comments/index.d.ts +3 -2
  215. package/dist/features/comments/index.js +1 -1
  216. package/dist/features/comments/margin-layout.d.ts +3 -2
  217. package/dist/features/comments/model.d.ts +3 -67
  218. package/dist/features/comments/model.js +2 -2
  219. package/dist/features/comments/model.js.map +1 -1
  220. package/dist/features/comments/react/CommentThreadView.d.ts +3 -2
  221. package/dist/features/comments/react/use-comments.d.ts +2 -1
  222. package/dist/features/comments/react.d.ts +1 -1
  223. package/dist/features/comments/schema.d.ts +2 -52
  224. package/dist/features/comments/schema.js.map +1 -1
  225. package/dist/features/comments/snapshot-equality.js.map +1 -1
  226. package/dist/features/comments/use-comments.d.ts +3 -2
  227. package/dist/features/comments/vue.d.ts +1 -1
  228. package/dist/features/composites/accepted-children.d.ts +1 -0
  229. package/dist/features/composites/accepted-children.js +16 -1
  230. package/dist/features/composites/accepted-children.js.map +1 -1
  231. package/dist/features/composites/ai-brief.js +31 -0
  232. package/dist/features/composites/ai-brief.js.map +1 -1
  233. package/dist/features/composites/bibliography-command.d.ts +11 -0
  234. package/dist/features/composites/bibliography-form.js +90 -0
  235. package/dist/features/composites/bibliography-form.js.map +1 -0
  236. package/dist/features/composites/bibliography.d.ts +33 -0
  237. package/dist/features/composites/bibliography.js +120 -0
  238. package/dist/features/composites/bibliography.js.map +1 -0
  239. package/dist/features/composites/components/BibliographyEditor.js +261 -0
  240. package/dist/features/composites/components/BibliographyEditor.js.map +1 -0
  241. package/dist/features/composites/components/CompositeChrome.js +75 -26
  242. package/dist/features/composites/components/CompositeChrome.js.map +1 -1
  243. package/dist/features/composites/components/CompositeDetails.js +46 -11
  244. package/dist/features/composites/components/CompositeDetails.js.map +1 -1
  245. package/dist/features/composites/components/CompositeDetails.vue.d.ts +2 -1
  246. package/dist/features/composites/components/CompositeFieldEditor.js +37 -4
  247. package/dist/features/composites/components/CompositeFieldEditor.js.map +1 -1
  248. package/dist/features/composites/components/CompositeInspector.js +17 -5
  249. package/dist/features/composites/components/CompositeInspector.js.map +1 -1
  250. package/dist/features/composites/components/CompositeTable.js +13 -4
  251. package/dist/features/composites/components/CompositeTable.js.map +1 -1
  252. package/dist/features/composites/components/CompositeTagsEditor.js +1 -1
  253. package/dist/features/composites/components/CompositeView.js +11 -1
  254. package/dist/features/composites/components/CompositeView.js.map +1 -1
  255. package/dist/features/composites/components/DerivationBadge.js +103 -0
  256. package/dist/features/composites/components/DerivationBadge.js.map +1 -0
  257. package/dist/features/composites/components/ReferenceFieldSelect.js +60 -0
  258. package/dist/features/composites/components/ReferenceFieldSelect.js.map +1 -0
  259. package/dist/features/composites/components/ReferenceView.js +122 -0
  260. package/dist/features/composites/components/ReferenceView.js.map +1 -0
  261. package/dist/features/composites/components/ReferenceView.vue.d.ts +96 -0
  262. package/dist/features/composites/components/SettingsEditingTab.js +1 -1
  263. package/dist/features/composites/convert.js +2 -2
  264. package/dist/features/composites/convert.js.map +1 -1
  265. package/dist/features/composites/derivation.d.ts +61 -0
  266. package/dist/features/composites/derivation.js +98 -0
  267. package/dist/features/composites/derivation.js.map +1 -0
  268. package/dist/features/composites/derived-chrome.js +69 -0
  269. package/dist/features/composites/derived-chrome.js.map +1 -0
  270. package/dist/features/composites/feature.js +159 -109
  271. package/dist/features/composites/feature.js.map +1 -1
  272. package/dist/features/composites/fences.d.ts +4 -3
  273. package/dist/features/composites/fences.js +51 -7
  274. package/dist/features/composites/fences.js.map +1 -1
  275. package/dist/features/composites/index.d.ts +12 -3
  276. package/dist/features/composites/index.js +15 -6
  277. package/dist/features/composites/inspector-model.d.ts +4 -1
  278. package/dist/features/composites/inspector-model.js +8 -4
  279. package/dist/features/composites/inspector-model.js.map +1 -1
  280. package/dist/features/composites/kinds.d.ts +8 -1
  281. package/dist/features/composites/kinds.js +145 -6
  282. package/dist/features/composites/kinds.js.map +1 -1
  283. package/dist/features/composites/legacy.d.ts +4 -1
  284. package/dist/features/composites/legacy.js +56 -1
  285. package/dist/features/composites/legacy.js.map +1 -1
  286. package/dist/features/composites/meta-display.js +40 -1
  287. package/dist/features/composites/meta-display.js.map +1 -1
  288. package/dist/features/composites/meta-keys.d.ts +7 -0
  289. package/dist/features/composites/meta-keys.js +21 -0
  290. package/dist/features/composites/meta-keys.js.map +1 -0
  291. package/dist/features/composites/node-views.d.ts +6 -3
  292. package/dist/features/composites/node-views.js +7 -3
  293. package/dist/features/composites/node-views.js.map +1 -1
  294. package/dist/features/composites/nodes.d.ts +6 -1
  295. package/dist/features/composites/nodes.js +33 -7
  296. package/dist/features/composites/nodes.js.map +1 -1
  297. package/dist/features/composites/react/BibliographyEditor.js +229 -0
  298. package/dist/features/composites/react/BibliographyEditor.js.map +1 -0
  299. package/dist/features/composites/react/CompositeChrome.js +65 -17
  300. package/dist/features/composites/react/CompositeChrome.js.map +1 -1
  301. package/dist/features/composites/react/CompositeDetails.d.ts +2 -1
  302. package/dist/features/composites/react/CompositeDetails.js +45 -6
  303. package/dist/features/composites/react/CompositeDetails.js.map +1 -1
  304. package/dist/features/composites/react/CompositeFieldEditor.d.ts +1 -1
  305. package/dist/features/composites/react/CompositeFieldEditor.js +24 -1
  306. package/dist/features/composites/react/CompositeFieldEditor.js.map +1 -1
  307. package/dist/features/composites/react/CompositeInspector.js +11 -5
  308. package/dist/features/composites/react/CompositeInspector.js.map +1 -1
  309. package/dist/features/composites/react/CompositeStatusMenu.js +1 -1
  310. package/dist/features/composites/react/CompositeSummaryEditor.js +1 -1
  311. package/dist/features/composites/react/CompositeTable.js +16 -2
  312. package/dist/features/composites/react/CompositeTable.js.map +1 -1
  313. package/dist/features/composites/react/CompositeTagsEditor.js +2 -2
  314. package/dist/features/composites/react/CompositeView.js +6 -1
  315. package/dist/features/composites/react/CompositeView.js.map +1 -1
  316. package/dist/features/composites/react/DerivationBadge.js +116 -0
  317. package/dist/features/composites/react/DerivationBadge.js.map +1 -0
  318. package/dist/features/composites/react/ReferenceFieldSelect.js +52 -0
  319. package/dist/features/composites/react/ReferenceFieldSelect.js.map +1 -0
  320. package/dist/features/composites/react/ReferenceView.d.ts +11 -0
  321. package/dist/features/composites/react/ReferenceView.js +115 -0
  322. package/dist/features/composites/react/ReferenceView.js.map +1 -0
  323. package/dist/features/composites/react/SettingsEditingTab.js +2 -2
  324. package/dist/features/composites/react.d.ts +2 -1
  325. package/dist/features/composites/react.js +7 -3
  326. package/dist/features/composites/react.js.map +1 -1
  327. package/dist/features/composites/reference-ai.js +16 -0
  328. package/dist/features/composites/reference-ai.js.map +1 -0
  329. package/dist/features/composites/reference-label.d.ts +19 -0
  330. package/dist/features/composites/reference-label.js +58 -0
  331. package/dist/features/composites/reference-label.js.map +1 -0
  332. package/dist/features/composites/reference-suggestion.d.ts +10 -0
  333. package/dist/features/composites/reference-suggestion.js +41 -0
  334. package/dist/features/composites/reference-suggestion.js.map +1 -0
  335. package/dist/features/composites/reference-text.d.ts +18 -0
  336. package/dist/features/composites/reference-text.js +89 -0
  337. package/dist/features/composites/reference-text.js.map +1 -0
  338. package/dist/features/composites/reference.d.ts +44 -0
  339. package/dist/features/composites/reference.js +148 -0
  340. package/dist/features/composites/reference.js.map +1 -0
  341. package/dist/features/composites/reveal-source.d.ts +32 -0
  342. package/dist/features/composites/reveal-source.js +89 -0
  343. package/dist/features/composites/reveal-source.js.map +1 -0
  344. package/dist/features/composites/rows.d.ts +21 -2
  345. package/dist/features/composites/rows.js +63 -9
  346. package/dist/features/composites/rows.js.map +1 -1
  347. package/dist/features/composites/schema.d.ts +9 -3
  348. package/dist/features/composites/schema.js +11 -4
  349. package/dist/features/composites/schema.js.map +1 -1
  350. package/dist/features/composites/table-model.js +12 -21
  351. package/dist/features/composites/table-model.js.map +1 -1
  352. package/dist/features/composites/vue.d.ts +3 -2
  353. package/dist/features/composites/vue.js +8 -4
  354. package/dist/features/composites/vue.js.map +1 -1
  355. package/dist/features/media/assets.d.ts +2 -0
  356. package/dist/features/media/assets.js +3 -2
  357. package/dist/features/media/assets.js.map +1 -1
  358. package/dist/features/media/components/FileView.js +13 -4
  359. package/dist/features/media/components/FileView.js.map +1 -1
  360. package/dist/features/media/feature.d.ts +3 -3
  361. package/dist/features/media/feature.js +21 -28
  362. package/dist/features/media/feature.js.map +1 -1
  363. package/dist/features/media/file-import.js +2 -2
  364. package/dist/features/media/file-import.js.map +1 -1
  365. package/dist/features/media/index.d.ts +2 -2
  366. package/dist/features/media/index.js +2 -2
  367. package/dist/features/media/react/FileView.js +19 -2
  368. package/dist/features/media/react/FileView.js.map +1 -1
  369. package/dist/features/media/schema.d.ts +8 -0
  370. package/dist/features/media/schema.js +126 -11
  371. package/dist/features/media/schema.js.map +1 -1
  372. package/dist/features/media/upload.d.ts +16 -14
  373. package/dist/features/media/upload.js +13 -19
  374. package/dist/features/media/upload.js.map +1 -1
  375. package/dist/features/mentions/index.d.ts +4 -3
  376. package/dist/features/mentions/index.js +4 -1
  377. package/dist/features/mentions/index.js.map +1 -1
  378. package/dist/features/mentions/mention-text.d.ts +1 -1
  379. package/dist/features/mentions/mention-text.js.map +1 -1
  380. package/dist/features/mentions/mention.d.ts +0 -6
  381. package/dist/features/mentions/mention.js.map +1 -1
  382. package/dist/features/mentions/metadata-defaults.d.ts +2 -2
  383. package/dist/features/mentions/metadata-defaults.js +3 -9
  384. package/dist/features/mentions/metadata-defaults.js.map +1 -1
  385. package/dist/features/mentions/schema.d.ts +2 -1
  386. package/dist/features/mentions/schema.js.map +1 -1
  387. package/dist/features/tables/feature.d.ts +2 -1
  388. package/dist/features/tables/feature.js +90 -70
  389. package/dist/features/tables/feature.js.map +1 -1
  390. package/dist/features/themes/components/SettingsAppearanceTab.js +6 -9
  391. package/dist/features/themes/components/SettingsAppearanceTab.js.map +1 -1
  392. package/dist/features/themes/feature.js +2 -0
  393. package/dist/features/themes/feature.js.map +1 -1
  394. package/dist/features/themes/index.d.ts +2 -1
  395. package/dist/features/themes/react/SettingsAppearanceTab.js +7 -10
  396. package/dist/features/themes/react/SettingsAppearanceTab.js.map +1 -1
  397. package/dist/features/themes/schema.d.ts +2 -6
  398. package/dist/features/themes/schema.js.map +1 -1
  399. package/dist/features/themes/theme-runtime.d.ts +1 -1
  400. package/dist/features/themes/theme-runtime.js +4 -2
  401. package/dist/features/themes/theme-runtime.js.map +1 -1
  402. package/dist/features/transcript/TranscriptSegmentView.js +48 -28
  403. package/dist/features/transcript/TranscriptSegmentView.js.map +1 -1
  404. package/dist/features/transcript/feature.js +21 -19
  405. package/dist/features/transcript/feature.js.map +1 -1
  406. package/dist/features/transcript/react/TranscriptSegmentView.js +55 -36
  407. package/dist/features/transcript/react/TranscriptSegmentView.js.map +1 -1
  408. package/dist/features/transcript/segment-node.d.ts +2 -0
  409. package/dist/features/transcript/segment-node.js +35 -7
  410. package/dist/features/transcript/segment-node.js.map +1 -1
  411. package/dist/i18n/de/composites.js +91 -1
  412. package/dist/i18n/de/composites.js.map +1 -1
  413. package/dist/i18n/de/integrations.js +49 -8
  414. package/dist/i18n/de/integrations.js.map +1 -1
  415. package/dist/i18n/de/media.js +0 -1
  416. package/dist/i18n/de/media.js.map +1 -1
  417. package/dist/i18n/de/palette.js +22 -0
  418. package/dist/i18n/de/palette.js.map +1 -0
  419. package/dist/i18n/de/tables.js +0 -1
  420. package/dist/i18n/de/tables.js.map +1 -1
  421. package/dist/i18n/de/transcript.js +2 -1
  422. package/dist/i18n/de/transcript.js.map +1 -1
  423. package/dist/i18n/de/tree.js +3 -0
  424. package/dist/i18n/de/tree.js.map +1 -1
  425. package/dist/i18n/de.d.ts +157 -11
  426. package/dist/i18n/de.js +3 -1
  427. package/dist/i18n/de.js.map +1 -1
  428. package/dist/i18n/en/composites.js +89 -1
  429. package/dist/i18n/en/composites.js.map +1 -1
  430. package/dist/i18n/en/integrations.js +49 -8
  431. package/dist/i18n/en/integrations.js.map +1 -1
  432. package/dist/i18n/en/media.js +0 -1
  433. package/dist/i18n/en/media.js.map +1 -1
  434. package/dist/i18n/en/palette.js +22 -0
  435. package/dist/i18n/en/palette.js.map +1 -0
  436. package/dist/i18n/en/tables.js +0 -1
  437. package/dist/i18n/en/tables.js.map +1 -1
  438. package/dist/i18n/en/transcript.js +2 -1
  439. package/dist/i18n/en/transcript.js.map +1 -1
  440. package/dist/i18n/en/tree.js +3 -0
  441. package/dist/i18n/en/tree.js.map +1 -1
  442. package/dist/i18n/en.js +3 -1
  443. package/dist/i18n/en.js.map +1 -1
  444. package/dist/index.d.ts +4 -3
  445. package/dist/integrations/composite-ai/bibliography-fetch.d.ts +31 -0
  446. package/dist/integrations/composite-ai/bibliography-fetch.js +159 -0
  447. package/dist/integrations/composite-ai/bibliography-fetch.js.map +1 -0
  448. package/dist/integrations/composite-ai/composite-fill.d.ts +30 -8
  449. package/dist/integrations/composite-ai/composite-fill.js +97 -56
  450. package/dist/integrations/composite-ai/composite-fill.js.map +1 -1
  451. package/dist/integrations/composite-ai/composite-summary.d.ts +4 -12
  452. package/dist/integrations/composite-ai/composite-summary.js +7 -26
  453. package/dist/integrations/composite-ai/composite-summary.js.map +1 -1
  454. package/dist/integrations/composite-ai/derive.d.ts +29 -0
  455. package/dist/integrations/composite-ai/derive.js +173 -0
  456. package/dist/integrations/composite-ai/derive.js.map +1 -0
  457. package/dist/integrations/composite-ai/index.d.ts +11 -7
  458. package/dist/integrations/composite-ai/index.js +72 -14
  459. package/dist/integrations/composite-ai/index.js.map +1 -1
  460. package/dist/integrations/composite-ai/rendition.d.ts +45 -0
  461. package/dist/integrations/composite-ai/rendition.js +314 -0
  462. package/dist/integrations/composite-ai/rendition.js.map +1 -0
  463. package/dist/integrations/composite-media/index.d.ts +7 -5
  464. package/dist/integrations/composite-media/index.js +86 -13
  465. package/dist/integrations/composite-media/index.js.map +1 -1
  466. package/dist/integrations/transcript-ai/index.d.ts +1 -1
  467. package/dist/integrations/transcript-ai/index.js +5 -2
  468. package/dist/integrations/transcript-ai/index.js.map +1 -1
  469. package/dist/integrations/transcript-ai/protocol.d.ts +2 -12
  470. package/dist/integrations/transcript-ai/protocol.js +0 -2
  471. package/dist/integrations/transcript-ai/protocol.js.map +1 -1
  472. package/dist/integrations/transcript-ai/transcript-cleanup.d.ts +5 -5
  473. package/dist/integrations/transcript-ai/transcript-cleanup.js +7 -10
  474. package/dist/integrations/transcript-ai/transcript-cleanup.js.map +1 -1
  475. package/dist/markdown/MarkdownSurface.vue.d.ts +10 -9
  476. package/dist/markdown/MarkdownSurface2.js +3 -6
  477. package/dist/markdown/MarkdownSurface2.js.map +1 -1
  478. package/dist/markdown/document.js +1 -1
  479. package/dist/markdown/source-mode.d.ts +1 -1
  480. package/dist/nuxt/module.d.ts +1402 -54
  481. package/dist/nuxt/module.js +6 -49
  482. package/dist/nuxt/module.js.map +1 -1
  483. package/dist/nuxt/runtime/install-context.d.ts +7 -3
  484. package/dist/nuxt/runtime/install-context.js +14 -8
  485. package/dist/nuxt/runtime/install-context.js.map +1 -1
  486. package/dist/nuxt/runtime/plugins/editor-context-nuxt-ui.client.ts +2 -2
  487. package/dist/nuxt/runtime/server/plugins/editor-server.js +20 -12
  488. package/dist/nuxt/runtime/server/plugins/editor-server.js.map +1 -1
  489. package/dist/presets/compose.d.ts +94 -0
  490. package/dist/presets/compose.js +164 -0
  491. package/dist/presets/compose.js.map +1 -0
  492. package/dist/react/AdvancedEditor.d.ts +15 -15
  493. package/dist/react/AdvancedEditor.js +15 -13
  494. package/dist/react/AdvancedEditor.js.map +1 -1
  495. package/dist/react/EditorCommandPalette.d.ts +13 -0
  496. package/dist/react/EditorCommandPalette.js +118 -0
  497. package/dist/react/EditorCommandPalette.js.map +1 -0
  498. package/dist/react/EditorSettingsModal.d.ts +5 -5
  499. package/dist/react/EditorSettingsModal.js +7 -4
  500. package/dist/react/EditorSettingsModal.js.map +1 -1
  501. package/dist/react/EditorSettingsPanel.d.ts +7 -7
  502. package/dist/react/EditorSettingsPanel.js +8 -5
  503. package/dist/react/EditorSettingsPanel.js.map +1 -1
  504. package/dist/react/EditorSurface.d.ts +7 -7
  505. package/dist/react/EditorSurface.js +10 -6
  506. package/dist/react/EditorSurface.js.map +1 -1
  507. package/dist/react/EditorToolbar.d.ts +4 -6
  508. package/dist/react/EditorToolbar.js +29 -37
  509. package/dist/react/EditorToolbar.js.map +1 -1
  510. package/dist/react/SimpleEditor.d.ts +22 -23
  511. package/dist/react/SimpleEditor.js +21 -7
  512. package/dist/react/SimpleEditor.js.map +1 -1
  513. package/dist/react/advanced.d.ts +4 -3
  514. package/dist/react/advanced.js +2 -2
  515. package/dist/react/compose.d.ts +20 -0
  516. package/dist/react/compose.js +49 -0
  517. package/dist/react/compose.js.map +1 -0
  518. package/dist/react/composed-surface.d.ts +39 -0
  519. package/dist/react/composed-surface.js +71 -0
  520. package/dist/react/composed-surface.js.map +1 -0
  521. package/dist/react/context.js +6 -2
  522. package/dist/react/context.js.map +1 -1
  523. package/dist/react/index.d.ts +2 -1
  524. package/dist/react/index.js +2 -1
  525. package/dist/react/key-labels.js +15 -0
  526. package/dist/react/key-labels.js.map +1 -0
  527. package/dist/react/settings.d.ts +1 -1
  528. package/dist/react/simple.d.ts +2 -2
  529. package/dist/react/ui/command.js +36 -1
  530. package/dist/react/ui/command.js.map +1 -1
  531. package/dist/schema/advanced.d.ts +6 -6
  532. package/dist/schema/advanced.js +26 -29
  533. package/dist/schema/advanced.js.map +1 -1
  534. package/dist/server/ai.d.ts +5 -16
  535. package/dist/server/ai.js.map +1 -1
  536. package/dist/server/auth.d.ts +9 -0
  537. package/dist/server/collab-state.d.ts +1 -1
  538. package/dist/server/collab-state.js.map +1 -1
  539. package/dist/server/collab.d.ts +13 -13
  540. package/dist/server/collab.js +34 -18
  541. package/dist/server/collab.js.map +1 -1
  542. package/dist/server/crossref.js +78 -0
  543. package/dist/server/crossref.js.map +1 -0
  544. package/dist/server/errors.d.ts +1 -1
  545. package/dist/server/errors.js +1 -1
  546. package/dist/server/errors.js.map +1 -1
  547. package/dist/server/extract.js +308 -0
  548. package/dist/server/extract.js.map +1 -0
  549. package/dist/{nuxt/runtime/server/utils/editor-route.js → server/h3.js} +8 -16
  550. package/dist/server/h3.js.map +1 -0
  551. package/dist/server/handlers/ai.d.ts +30 -9
  552. package/dist/server/handlers/ai.js +170 -36
  553. package/dist/server/handlers/ai.js.map +1 -1
  554. package/dist/server/handlers/context.d.ts +12 -5
  555. package/dist/server/handlers/context.js +10 -4
  556. package/dist/server/handlers/context.js.map +1 -1
  557. package/dist/server/handlers/editor.d.ts +19 -13
  558. package/dist/server/handlers/editor.js +49 -38
  559. package/dist/server/handlers/editor.js.map +1 -1
  560. package/dist/server/handlers/index.d.ts +4 -4
  561. package/dist/server/handlers/index.js +4 -4
  562. package/dist/server/host.d.ts +16 -25
  563. package/dist/server/host.js +58 -41
  564. package/dist/server/host.js.map +1 -1
  565. package/dist/server/index.d.ts +6 -4
  566. package/dist/server/index.js +3 -2
  567. package/dist/server/pdf.js +97 -0
  568. package/dist/server/pdf.js.map +1 -0
  569. package/dist/server/{adapter.d.ts → ports.d.ts} +81 -30
  570. package/dist/server/ports.js +29 -0
  571. package/dist/server/ports.js.map +1 -0
  572. package/dist/server/routes.js +144 -0
  573. package/dist/server/routes.js.map +1 -0
  574. package/dist/settings/index.d.ts +1 -1
  575. package/dist/settings/index.js.map +1 -1
  576. package/dist/styles/composites.css +25 -0
  577. package/dist/tree/DocumentTree.js +56 -29
  578. package/dist/tree/DocumentTree.js.map +1 -1
  579. package/dist/tree/react/DocumentTree.js +23 -0
  580. package/dist/tree/react/DocumentTree.js.map +1 -1
  581. package/dist/tree/tree-host.js +1 -1
  582. package/dist/vue/AdvancedEditor.js +30 -9
  583. package/dist/vue/AdvancedEditor.js.map +1 -1
  584. package/dist/vue/AdvancedEditor.vue.d.ts +32 -12
  585. package/dist/vue/SimpleEditor.js +62 -16
  586. package/dist/vue/SimpleEditor.js.map +1 -1
  587. package/dist/vue/SimpleEditor.vue.d.ts +37 -7
  588. package/dist/vue/advanced.d.ts +3 -2
  589. package/dist/vue/advanced.js +2 -2
  590. package/dist/vue/components/EditorCommandPalette.js +91 -0
  591. package/dist/vue/components/EditorCommandPalette.js.map +1 -0
  592. package/dist/vue/components/EditorCommandPalette.vue.d.ts +15 -0
  593. package/dist/vue/components/EditorSettingsModal.js +10 -6
  594. package/dist/vue/components/EditorSettingsModal.js.map +1 -1
  595. package/dist/vue/components/EditorSettingsModal.vue.d.ts +4 -4
  596. package/dist/vue/components/EditorSettingsPanel.js +10 -6
  597. package/dist/vue/components/EditorSettingsPanel.js.map +1 -1
  598. package/dist/vue/components/EditorSettingsPanel.vue.d.ts +6 -6
  599. package/dist/vue/components/EditorSurface.js +11 -6
  600. package/dist/vue/components/EditorSurface.js.map +1 -1
  601. package/dist/vue/components/EditorSurface.vue.d.ts +11 -11
  602. package/dist/vue/components/EditorToolbar.js +41 -49
  603. package/dist/vue/components/EditorToolbar.js.map +1 -1
  604. package/dist/vue/components/EditorToolbar.vue.d.ts +2 -4
  605. package/dist/vue/compose.d.ts +17 -0
  606. package/dist/vue/compose.js +51 -0
  607. package/dist/vue/compose.js.map +1 -0
  608. package/dist/vue/context-key.d.ts +6 -0
  609. package/dist/vue/context-key.js +6 -0
  610. package/dist/vue/context-key.js.map +1 -0
  611. package/dist/vue/context.d.ts +8 -6
  612. package/dist/vue/context.js +6 -5
  613. package/dist/vue/context.js.map +1 -1
  614. package/dist/vue/index.d.ts +10 -8
  615. package/dist/vue/index.js +10 -8
  616. package/dist/vue/kit/index.d.ts +2 -2
  617. package/dist/vue/kit/nuxt-ui.js +23 -0
  618. package/dist/vue/kit/nuxt-ui.js.map +1 -1
  619. package/dist/vue/kit/types.d.ts +40 -1
  620. package/package.json +30 -16
  621. package/dist/adapters/comments/client.d.ts +0 -64
  622. package/dist/adapters/comments/client.js.map +0 -1
  623. package/dist/adapters/routes.js.map +0 -1
  624. package/dist/core/toolbar.d.ts +0 -74
  625. package/dist/core/toolbar.js +0 -45
  626. package/dist/core/toolbar.js.map +0 -1
  627. package/dist/integrations/composite-ai/document-transcribe.d.ts +0 -14
  628. package/dist/integrations/composite-ai/document-transcribe.js +0 -89
  629. package/dist/integrations/composite-ai/document-transcribe.js.map +0 -1
  630. package/dist/nuxt/runtime/server/api/ai/chat.post.d.ts +0 -5
  631. package/dist/nuxt/runtime/server/api/ai/chat.post.js +0 -8
  632. package/dist/nuxt/runtime/server/api/ai/chat.post.js.map +0 -1
  633. package/dist/nuxt/runtime/server/api/ai/complete.post.d.ts +0 -5
  634. package/dist/nuxt/runtime/server/api/ai/complete.post.js +0 -8
  635. package/dist/nuxt/runtime/server/api/ai/complete.post.js.map +0 -1
  636. package/dist/nuxt/runtime/server/api/ai/generate.post.d.ts +0 -5
  637. package/dist/nuxt/runtime/server/api/ai/generate.post.js +0 -8
  638. package/dist/nuxt/runtime/server/api/ai/generate.post.js.map +0 -1
  639. package/dist/nuxt/runtime/server/api/ai/models.get.d.ts +0 -5
  640. package/dist/nuxt/runtime/server/api/ai/models.get.js +0 -8
  641. package/dist/nuxt/runtime/server/api/ai/models.get.js.map +0 -1
  642. package/dist/nuxt/runtime/server/api/ai/transcribe.post.d.ts +0 -5
  643. package/dist/nuxt/runtime/server/api/ai/transcribe.post.js +0 -8
  644. package/dist/nuxt/runtime/server/api/ai/transcribe.post.js.map +0 -1
  645. package/dist/nuxt/runtime/server/api/ai/transcript-cleanup.post.d.ts +0 -5
  646. package/dist/nuxt/runtime/server/api/ai/transcript-cleanup.post.js +0 -8
  647. package/dist/nuxt/runtime/server/api/ai/transcript-cleanup.post.js.map +0 -1
  648. package/dist/nuxt/runtime/server/api/editor/assets/[id]/[name].get.d.ts +0 -5
  649. package/dist/nuxt/runtime/server/api/editor/assets/[id]/[name].get.js +0 -8
  650. package/dist/nuxt/runtime/server/api/editor/assets/[id]/[name].get.js.map +0 -1
  651. package/dist/nuxt/runtime/server/api/editor/assets/[id].post.d.ts +0 -5
  652. package/dist/nuxt/runtime/server/api/editor/assets/[id].post.js +0 -8
  653. package/dist/nuxt/runtime/server/api/editor/assets/[id].post.js.map +0 -1
  654. package/dist/nuxt/runtime/server/api/editor/settings.get.d.ts +0 -5
  655. package/dist/nuxt/runtime/server/api/editor/settings.get.js +0 -8
  656. package/dist/nuxt/runtime/server/api/editor/settings.get.js.map +0 -1
  657. package/dist/nuxt/runtime/server/api/editor/settings.put.d.ts +0 -5
  658. package/dist/nuxt/runtime/server/api/editor/settings.put.js +0 -8
  659. package/dist/nuxt/runtime/server/api/editor/settings.put.js.map +0 -1
  660. package/dist/nuxt/runtime/server/api/editor/tags.get.d.ts +0 -5
  661. package/dist/nuxt/runtime/server/api/editor/tags.get.js +0 -8
  662. package/dist/nuxt/runtime/server/api/editor/tags.get.js.map +0 -1
  663. package/dist/nuxt/runtime/server/api/editor/themes/[id].delete.d.ts +0 -5
  664. package/dist/nuxt/runtime/server/api/editor/themes/[id].delete.js +0 -8
  665. package/dist/nuxt/runtime/server/api/editor/themes/[id].delete.js.map +0 -1
  666. package/dist/nuxt/runtime/server/api/editor/themes/[id].get.d.ts +0 -5
  667. package/dist/nuxt/runtime/server/api/editor/themes/[id].get.js +0 -8
  668. package/dist/nuxt/runtime/server/api/editor/themes/[id].get.js.map +0 -1
  669. package/dist/nuxt/runtime/server/api/editor/themes/index.get.d.ts +0 -5
  670. package/dist/nuxt/runtime/server/api/editor/themes/index.get.js +0 -8
  671. package/dist/nuxt/runtime/server/api/editor/themes/index.get.js.map +0 -1
  672. package/dist/nuxt/runtime/server/api/editor/themes/index.post.d.ts +0 -5
  673. package/dist/nuxt/runtime/server/api/editor/themes/index.post.js +0 -8
  674. package/dist/nuxt/runtime/server/api/editor/themes/index.post.js.map +0 -1
  675. package/dist/nuxt/runtime/server/api/editor/users.get.d.ts +0 -5
  676. package/dist/nuxt/runtime/server/api/editor/users.get.js +0 -8
  677. package/dist/nuxt/runtime/server/api/editor/users.get.js.map +0 -1
  678. package/dist/nuxt/runtime/server/plugins/collab.d.ts +0 -5
  679. package/dist/nuxt/runtime/server/plugins/collab.js +0 -10
  680. package/dist/nuxt/runtime/server/plugins/collab.js.map +0 -1
  681. package/dist/nuxt/runtime/server/routes/collab/[id].d.ts +0 -5
  682. package/dist/nuxt/runtime/server/routes/collab/[id].js +0 -35
  683. package/dist/nuxt/runtime/server/routes/collab/[id].js.map +0 -1
  684. package/dist/nuxt/runtime/server/utils/editor-route.d.ts +0 -11
  685. package/dist/nuxt/runtime/server/utils/editor-route.js.map +0 -1
  686. package/dist/presets/advanced.d.ts +0 -33
  687. package/dist/presets/advanced.js +0 -50
  688. package/dist/presets/advanced.js.map +0 -1
  689. package/dist/presets/simple.d.ts +0 -9
  690. package/dist/presets/simple.js +0 -12
  691. package/dist/presets/simple.js.map +0 -1
  692. package/dist/react/advanced-preset.d.ts +0 -11
  693. package/dist/react/advanced-preset.js +0 -31
  694. package/dist/react/advanced-preset.js.map +0 -1
  695. package/dist/vue/advanced-preset.d.ts +0 -13
  696. package/dist/vue/advanced-preset.js +0 -33
  697. package/dist/vue/advanced-preset.js.map +0 -1
  698. package/docs/extending.md +0 -538
  699. package/docs/integration.md +0 -630
  700. package/docs/llms.md +0 -383
  701. package/docs/usage.md +0 -1076
@@ -1,2 +1,2 @@
1
- import { SimpleEditor, SimpleEditorProps } from "./SimpleEditor.js";
2
- export { SimpleEditor, type SimpleEditorProps };
1
+ import { SimpleEditor, SimpleEditorHandle, SimpleEditorProps } from "./SimpleEditor.js";
2
+ export { SimpleEditor, type SimpleEditorHandle, type SimpleEditorProps };
@@ -1,4 +1,5 @@
1
1
  import { cn } from "./utils.js";
2
+ import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle } from "./dialog.js";
2
3
  import { InputGroup, InputGroupAddon } from "./input-group.js";
3
4
  import "react";
4
5
  import { jsx, jsxs } from "react/jsx-runtime";
@@ -12,6 +13,19 @@ function Command$1({ className, ...props }) {
12
13
  ...props
13
14
  });
14
15
  }
16
+ function CommandDialog({ title = "Command Palette", description = "Search for a command to run...", children, className, showCloseButton = false, ...props }) {
17
+ return /* @__PURE__ */ jsxs(Dialog, {
18
+ ...props,
19
+ children: [/* @__PURE__ */ jsxs(DialogHeader, {
20
+ className: "sr-only",
21
+ children: [/* @__PURE__ */ jsx(DialogTitle, { children: title }), /* @__PURE__ */ jsx(DialogDescription, { children: description })]
22
+ }), /* @__PURE__ */ jsx(DialogContent, {
23
+ className: cn("top-1/3 translate-y-0 overflow-hidden rounded-xl! p-0", className),
24
+ showCloseButton,
25
+ children
26
+ })]
27
+ });
28
+ }
15
29
  function CommandInput({ className, ...props }) {
16
30
  return /* @__PURE__ */ jsx("div", {
17
31
  "data-slot": "command-input-wrapper",
@@ -33,6 +47,20 @@ function CommandList({ className, ...props }) {
33
47
  ...props
34
48
  });
35
49
  }
50
+ function CommandEmpty({ className, ...props }) {
51
+ return /* @__PURE__ */ jsx(Command.Empty, {
52
+ "data-slot": "command-empty",
53
+ className: cn("py-6 text-center text-sm", className),
54
+ ...props
55
+ });
56
+ }
57
+ function CommandGroup({ className, ...props }) {
58
+ return /* @__PURE__ */ jsx(Command.Group, {
59
+ "data-slot": "command-group",
60
+ className: cn("overflow-hidden p-1 text-foreground **:[[cmdk-group-heading]]:px-2 **:[[cmdk-group-heading]]:py-1.5 **:[[cmdk-group-heading]]:text-xs **:[[cmdk-group-heading]]:font-medium **:[[cmdk-group-heading]]:text-muted-foreground", className),
61
+ ...props
62
+ });
63
+ }
36
64
  function CommandItem({ className, children, ...props }) {
37
65
  return /* @__PURE__ */ jsxs(Command.Item, {
38
66
  "data-slot": "command-item",
@@ -41,7 +69,14 @@ function CommandItem({ className, children, ...props }) {
41
69
  children: [children, /* @__PURE__ */ jsx(CheckIcon, { className: "ml-auto opacity-0 group-has-data-[slot=command-shortcut]/command-item:hidden group-data-[checked=true]/command-item:opacity-100" })]
42
70
  });
43
71
  }
72
+ function CommandShortcut({ className, ...props }) {
73
+ return /* @__PURE__ */ jsx("span", {
74
+ "data-slot": "command-shortcut",
75
+ className: cn("ml-auto text-xs tracking-widest text-muted-foreground group-data-selected/command-item:text-foreground", className),
76
+ ...props
77
+ });
78
+ }
44
79
  //#endregion
45
- export { Command$1 as Command, CommandInput, CommandItem, CommandList };
80
+ export { Command$1 as Command, CommandDialog, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, CommandShortcut };
46
81
 
47
82
  //# sourceMappingURL=command.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"command.js","names":["Command","CommandPrimitive"],"sources":["../../../src/react/ui/command.tsx"],"sourcesContent":["import * as React from \"react\"\nimport { Command as CommandPrimitive } from \"cmdk\"\nimport { cn } from \"./utils\"\n\nimport {\n Dialog,\n DialogContent,\n DialogDescription,\n DialogHeader,\n DialogTitle,\n} from \"./dialog\"\nimport {\n InputGroup,\n InputGroupAddon,\n} from \"./input-group\"\nimport { SearchIcon, CheckIcon } from \"lucide-react\"\n\nfunction Command({\n className,\n ...props\n}: React.ComponentProps<typeof CommandPrimitive>) {\n return (\n <CommandPrimitive\n data-slot=\"command\"\n className={cn(\n \"flex size-full flex-col overflow-hidden rounded-xl! bg-popover p-1 text-popover-foreground\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction CommandDialog({\n title = \"Command Palette\",\n description = \"Search for a command to run...\",\n children,\n className,\n showCloseButton = false,\n ...props\n}: React.ComponentProps<typeof Dialog> & {\n title?: string\n description?: string\n className?: string\n showCloseButton?: boolean\n}) {\n return (\n <Dialog {...props}>\n <DialogHeader className=\"sr-only\">\n <DialogTitle>{title}</DialogTitle>\n <DialogDescription>{description}</DialogDescription>\n </DialogHeader>\n <DialogContent\n className={cn(\n \"top-1/3 translate-y-0 overflow-hidden rounded-xl! p-0\",\n className\n )}\n showCloseButton={showCloseButton}\n >\n {children}\n </DialogContent>\n </Dialog>\n )\n}\n\nfunction CommandInput({\n className,\n ...props\n}: React.ComponentProps<typeof CommandPrimitive.Input>) {\n return (\n <div data-slot=\"command-input-wrapper\" className=\"p-1 pb-0\">\n <InputGroup className=\"h-8! rounded-lg! border-input/30 bg-input/30 shadow-none! *:data-[slot=input-group-addon]:pl-2!\">\n <CommandPrimitive.Input\n data-slot=\"command-input\"\n className={cn(\n \"w-full text-sm outline-hidden disabled:cursor-not-allowed disabled:opacity-50\",\n className\n )}\n {...props}\n />\n <InputGroupAddon>\n <SearchIcon className=\"size-4 shrink-0 opacity-50\" />\n </InputGroupAddon>\n </InputGroup>\n </div>\n )\n}\n\nfunction CommandList({\n className,\n ...props\n}: React.ComponentProps<typeof CommandPrimitive.List>) {\n return (\n <CommandPrimitive.List\n data-slot=\"command-list\"\n className={cn(\n \"no-scrollbar max-h-72 scroll-py-1 overflow-x-hidden overflow-y-auto outline-none\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction CommandEmpty({\n className,\n ...props\n}: React.ComponentProps<typeof CommandPrimitive.Empty>) {\n return (\n <CommandPrimitive.Empty\n data-slot=\"command-empty\"\n className={cn(\"py-6 text-center text-sm\", className)}\n {...props}\n />\n )\n}\n\nfunction CommandGroup({\n className,\n ...props\n}: React.ComponentProps<typeof CommandPrimitive.Group>) {\n return (\n <CommandPrimitive.Group\n data-slot=\"command-group\"\n className={cn(\n \"overflow-hidden p-1 text-foreground **:[[cmdk-group-heading]]:px-2 **:[[cmdk-group-heading]]:py-1.5 **:[[cmdk-group-heading]]:text-xs **:[[cmdk-group-heading]]:font-medium **:[[cmdk-group-heading]]:text-muted-foreground\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction CommandSeparator({\n className,\n ...props\n}: React.ComponentProps<typeof CommandPrimitive.Separator>) {\n return (\n <CommandPrimitive.Separator\n data-slot=\"command-separator\"\n className={cn(\"-mx-1 h-px bg-border\", className)}\n {...props}\n />\n )\n}\n\nfunction CommandItem({\n className,\n children,\n ...props\n}: React.ComponentProps<typeof CommandPrimitive.Item>) {\n return (\n <CommandPrimitive.Item\n data-slot=\"command-item\"\n className={cn(\n \"group/command-item relative flex cursor-default items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-hidden select-none in-data-[slot=dialog-content]:rounded-lg! data-[disabled=true]:pointer-events-none data-[disabled=true]:opacity-50 data-selected:bg-muted data-selected:text-foreground [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 data-selected:*:[svg]:text-foreground\",\n className\n )}\n {...props}\n >\n {children}\n <CheckIcon className=\"ml-auto opacity-0 group-has-data-[slot=command-shortcut]/command-item:hidden group-data-[checked=true]/command-item:opacity-100\" />\n </CommandPrimitive.Item>\n )\n}\n\nfunction CommandShortcut({\n className,\n ...props\n}: React.ComponentProps<\"span\">) {\n return (\n <span\n data-slot=\"command-shortcut\"\n className={cn(\n \"ml-auto text-xs tracking-widest text-muted-foreground group-data-selected/command-item:text-foreground\",\n className\n )}\n {...props}\n />\n )\n}\n\nexport {\n Command,\n CommandDialog,\n CommandInput,\n CommandList,\n CommandEmpty,\n CommandGroup,\n CommandItem,\n CommandShortcut,\n CommandSeparator,\n}\n"],"mappings":";;;;;;;AAiBA,SAASA,UAAQ,EACf,WACA,GAAG,SAC6C;CAChD,OACE,oBAACC,SAAD;EACE,aAAU;EACV,WAAW,GACT,8FACA,SACF;EACA,GAAI;CACL,CAAA;AAEL;AAkCA,SAAS,aAAa,EACpB,WACA,GAAG,SACmD;CACtD,OACE,oBAAC,OAAD;EAAK,aAAU;EAAwB,WAAU;EAC/C,UAAA,qBAAC,YAAD;GAAY,WAAU;GAAtB,UAAA,CACE,oBAACA,QAAiB,OAAlB;IACE,aAAU;IACV,WAAW,GACT,iFACA,SACF;IACA,GAAI;GACL,CAAA,GACD,oBAAC,iBAAD,EAAA,UACE,oBAAC,YAAD,EAAY,WAAU,6BAA8B,CAAA,EACrC,CAAA,CACP;;CACT,CAAA;AAET;AAEA,SAAS,YAAY,EACnB,WACA,GAAG,SACkD;CACrD,OACE,oBAACA,QAAiB,MAAlB;EACE,aAAU;EACV,WAAW,GACT,oFACA,SACF;EACA,GAAI;CACL,CAAA;AAEL;AA4CA,SAAS,YAAY,EACnB,WACA,UACA,GAAG,SACkD;CACrD,OACE,qBAACA,QAAiB,MAAlB;EACE,aAAU;EACV,WAAW,GACT,gaACA,SACF;EACA,GAAI;EANN,UAAA,CAQG,UACD,oBAAC,WAAD,EAAW,WAAU,kIAAmI,CAAA,CACnI;;AAE3B"}
1
+ {"version":3,"file":"command.js","names":["Command","CommandPrimitive"],"sources":["../../../src/react/ui/command.tsx"],"sourcesContent":["import * as React from \"react\"\nimport { Command as CommandPrimitive } from \"cmdk\"\nimport { cn } from \"./utils\"\n\nimport {\n Dialog,\n DialogContent,\n DialogDescription,\n DialogHeader,\n DialogTitle,\n} from \"./dialog\"\nimport {\n InputGroup,\n InputGroupAddon,\n} from \"./input-group\"\nimport { SearchIcon, CheckIcon } from \"lucide-react\"\n\nfunction Command({\n className,\n ...props\n}: React.ComponentProps<typeof CommandPrimitive>) {\n return (\n <CommandPrimitive\n data-slot=\"command\"\n className={cn(\n \"flex size-full flex-col overflow-hidden rounded-xl! bg-popover p-1 text-popover-foreground\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction CommandDialog({\n title = \"Command Palette\",\n description = \"Search for a command to run...\",\n children,\n className,\n showCloseButton = false,\n ...props\n}: React.ComponentProps<typeof Dialog> & {\n title?: string\n description?: string\n className?: string\n showCloseButton?: boolean\n}) {\n return (\n <Dialog {...props}>\n <DialogHeader className=\"sr-only\">\n <DialogTitle>{title}</DialogTitle>\n <DialogDescription>{description}</DialogDescription>\n </DialogHeader>\n <DialogContent\n className={cn(\n \"top-1/3 translate-y-0 overflow-hidden rounded-xl! p-0\",\n className\n )}\n showCloseButton={showCloseButton}\n >\n {children}\n </DialogContent>\n </Dialog>\n )\n}\n\nfunction CommandInput({\n className,\n ...props\n}: React.ComponentProps<typeof CommandPrimitive.Input>) {\n return (\n <div data-slot=\"command-input-wrapper\" className=\"p-1 pb-0\">\n <InputGroup className=\"h-8! rounded-lg! border-input/30 bg-input/30 shadow-none! *:data-[slot=input-group-addon]:pl-2!\">\n <CommandPrimitive.Input\n data-slot=\"command-input\"\n className={cn(\n \"w-full text-sm outline-hidden disabled:cursor-not-allowed disabled:opacity-50\",\n className\n )}\n {...props}\n />\n <InputGroupAddon>\n <SearchIcon className=\"size-4 shrink-0 opacity-50\" />\n </InputGroupAddon>\n </InputGroup>\n </div>\n )\n}\n\nfunction CommandList({\n className,\n ...props\n}: React.ComponentProps<typeof CommandPrimitive.List>) {\n return (\n <CommandPrimitive.List\n data-slot=\"command-list\"\n className={cn(\n \"no-scrollbar max-h-72 scroll-py-1 overflow-x-hidden overflow-y-auto outline-none\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction CommandEmpty({\n className,\n ...props\n}: React.ComponentProps<typeof CommandPrimitive.Empty>) {\n return (\n <CommandPrimitive.Empty\n data-slot=\"command-empty\"\n className={cn(\"py-6 text-center text-sm\", className)}\n {...props}\n />\n )\n}\n\nfunction CommandGroup({\n className,\n ...props\n}: React.ComponentProps<typeof CommandPrimitive.Group>) {\n return (\n <CommandPrimitive.Group\n data-slot=\"command-group\"\n className={cn(\n \"overflow-hidden p-1 text-foreground **:[[cmdk-group-heading]]:px-2 **:[[cmdk-group-heading]]:py-1.5 **:[[cmdk-group-heading]]:text-xs **:[[cmdk-group-heading]]:font-medium **:[[cmdk-group-heading]]:text-muted-foreground\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction CommandSeparator({\n className,\n ...props\n}: React.ComponentProps<typeof CommandPrimitive.Separator>) {\n return (\n <CommandPrimitive.Separator\n data-slot=\"command-separator\"\n className={cn(\"-mx-1 h-px bg-border\", className)}\n {...props}\n />\n )\n}\n\nfunction CommandItem({\n className,\n children,\n ...props\n}: React.ComponentProps<typeof CommandPrimitive.Item>) {\n return (\n <CommandPrimitive.Item\n data-slot=\"command-item\"\n className={cn(\n \"group/command-item relative flex cursor-default items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-hidden select-none in-data-[slot=dialog-content]:rounded-lg! data-[disabled=true]:pointer-events-none data-[disabled=true]:opacity-50 data-selected:bg-muted data-selected:text-foreground [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 data-selected:*:[svg]:text-foreground\",\n className\n )}\n {...props}\n >\n {children}\n <CheckIcon className=\"ml-auto opacity-0 group-has-data-[slot=command-shortcut]/command-item:hidden group-data-[checked=true]/command-item:opacity-100\" />\n </CommandPrimitive.Item>\n )\n}\n\nfunction CommandShortcut({\n className,\n ...props\n}: React.ComponentProps<\"span\">) {\n return (\n <span\n data-slot=\"command-shortcut\"\n className={cn(\n \"ml-auto text-xs tracking-widest text-muted-foreground group-data-selected/command-item:text-foreground\",\n className\n )}\n {...props}\n />\n )\n}\n\nexport {\n Command,\n CommandDialog,\n CommandInput,\n CommandList,\n CommandEmpty,\n CommandGroup,\n CommandItem,\n CommandShortcut,\n CommandSeparator,\n}\n"],"mappings":";;;;;;;;AAiBA,SAASA,UAAQ,EACf,WACA,GAAG,SAC6C;CAChD,OACE,oBAACC,SAAD;EACE,aAAU;EACV,WAAW,GACT,8FACA,SACF;EACA,GAAI;CACL,CAAA;AAEL;AAEA,SAAS,cAAc,EACrB,QAAQ,mBACR,cAAc,kCACd,UACA,WACA,kBAAkB,OAClB,GAAG,SAMF;CACD,OACE,qBAAC,QAAD;EAAQ,GAAI;EAAZ,UAAA,CACE,qBAAC,cAAD;GAAc,WAAU;GAAxB,UAAA,CACE,oBAAC,aAAD,EAAA,UAAc,MAAmB,CAAA,GACjC,oBAAC,mBAAD,EAAA,UAAoB,YAA+B,CAAA,CACvC;EACd,CAAA,GAAA,oBAAC,eAAD;GACE,WAAW,GACT,yDACA,SACF;GACiB;GAEhB;EACY,CAAA,CACT;;AAEZ;AAEA,SAAS,aAAa,EACpB,WACA,GAAG,SACmD;CACtD,OACE,oBAAC,OAAD;EAAK,aAAU;EAAwB,WAAU;EAC/C,UAAA,qBAAC,YAAD;GAAY,WAAU;GAAtB,UAAA,CACE,oBAACA,QAAiB,OAAlB;IACE,aAAU;IACV,WAAW,GACT,iFACA,SACF;IACA,GAAI;GACL,CAAA,GACD,oBAAC,iBAAD,EAAA,UACE,oBAAC,YAAD,EAAY,WAAU,6BAA8B,CAAA,EACrC,CAAA,CACP;;CACT,CAAA;AAET;AAEA,SAAS,YAAY,EACnB,WACA,GAAG,SACkD;CACrD,OACE,oBAACA,QAAiB,MAAlB;EACE,aAAU;EACV,WAAW,GACT,oFACA,SACF;EACA,GAAI;CACL,CAAA;AAEL;AAEA,SAAS,aAAa,EACpB,WACA,GAAG,SACmD;CACtD,OACE,oBAACA,QAAiB,OAAlB;EACE,aAAU;EACV,WAAW,GAAG,4BAA4B,SAAS;EACnD,GAAI;CACL,CAAA;AAEL;AAEA,SAAS,aAAa,EACpB,WACA,GAAG,SACmD;CACtD,OACE,oBAACA,QAAiB,OAAlB;EACE,aAAU;EACV,WAAW,GACT,+NACA,SACF;EACA,GAAI;CACL,CAAA;AAEL;AAeA,SAAS,YAAY,EACnB,WACA,UACA,GAAG,SACkD;CACrD,OACE,qBAACA,QAAiB,MAAlB;EACE,aAAU;EACV,WAAW,GACT,gaACA,SACF;EACA,GAAI;EANN,UAAA,CAQG,UACD,oBAAC,WAAD,EAAW,WAAU,kIAAmI,CAAA,CACnI;;AAE3B;AAEA,SAAS,gBAAgB,EACvB,WACA,GAAG,SAC4B;CAC/B,OACE,oBAAC,QAAD;EACE,aAAU;EACV,WAAW,GACT,0GACA,SACF;EACA,GAAI;CACL,CAAA;AAEL"}
@@ -2,12 +2,12 @@ import { AnyExtension } from "@tiptap/core";
2
2
  //#region src/schema/advanced.d.ts
3
3
  /**
4
4
  * The Vue-free schema of the advanced editor, free of node views, UI and collaboration runtime: the server builds the
5
- * same schema with `getSchema(advancedSchemaExtensions())` to convert between TipTap JSON and Yjs. The order is the
6
- * order of the client's schema-bearing extensions: StarterKit/StrikeX, the generic node flags, the opaque fence, media (image, audio,
7
- * video, file), transcript, the composite family, mentions/tags, the author and comment marks, the GFM table and task-list
8
- * nodes (for hosts whose preset adds `tablesFeature()`; the advanced preset itself has none) and last `BlockId`, which
9
- * adds the `id` attribute to every block type (its ID-assigning plugins only run in an editor). `undoRedo: false`:
10
- * under collaboration the Collaboration extension provides the (per-user) undo manager.
5
+ * same schema with `getSchema(advancedSchemaExtensions())` to convert between TipTap JSON and Yjs. Derived with
6
+ * `schemaExtensionsOf` from the schema-bearing features: StarterKit/StrikeX, the generic node flags, the opaque fence,
7
+ * media (image, audio, video, file), transcript, the composite family, mentions/tags, the author and comment marks, the
8
+ * GFM table and task-list nodes (for hosts whose preset adds `tablesFeature()`; the advanced preset itself has none) and
9
+ * last `BlockId`, which adds the `id` attribute to every block type (its ID-assigning plugins only run in an editor).
10
+ * `undoRedo: false`: under collaboration the Collaboration extension provides the (per-user) undo manager.
11
11
  */
12
12
  export declare const advancedSchemaExtensions: () => AnyExtension[];
13
13
  //#endregion
@@ -1,42 +1,39 @@
1
- import { BlockId } from "../core/schema/block-ids.js";
2
- import { NodeFlags } from "../core/schema/node-flags.js";
3
- import { OpaqueFence } from "../core/schema/opaque-fence.js";
4
- import { StrikeX } from "../core/schema/strike.js";
1
+ import { schemaExtensionsOf } from "../core/schema/of-features.js";
2
+ import { coreContentSchemaExtensions } from "../core/schema/index.js";
3
+ import { commentsSchemaExtensions } from "../features/comments/schema.js";
5
4
  import { compositeSchemaExtensions } from "../features/composites/schema.js";
6
5
  import { authorsSchemaExtensions } from "../features/authors/schema.js";
7
- import { commentsSchemaExtensions } from "../features/comments/schema.js";
8
6
  import { mediaSchemaExtensions } from "../features/media/schema.js";
9
7
  import { mentionsSchemaExtensions } from "../features/mentions/schema.js";
10
8
  import { tablesSchemaExtensions } from "../features/tables/schema.js";
11
9
  import { transcriptSchemaExtensions } from "../features/transcript/schema.js";
12
- import StarterKit from "@tiptap/starter-kit";
13
10
  //#region src/schema/advanced.ts
14
11
  /**
15
- * The Vue-free schema of the advanced editor, free of node views, UI and collaboration runtime: the server builds the
16
- * same schema with `getSchema(advancedSchemaExtensions())` to convert between TipTap JSON and Yjs. The order is the
17
- * order of the client's schema-bearing extensions: StarterKit/StrikeX, the generic node flags, the opaque fence, media (image, audio,
18
- * video, file), transcript, the composite family, mentions/tags, the author and comment marks, the GFM table and task-list
19
- * nodes (for hosts whose preset adds `tablesFeature()`; the advanced preset itself has none) and last `BlockId`, which
20
- * adds the `id` attribute to every block type (its ID-assigning plugins only run in an editor). `undoRedo: false`:
21
- * under collaboration the Collaboration extension provides the (per-user) undo manager.
12
+ * The schema-bearing slice of the rich content features, in schema order: `core-content`, media, transcript, composites,
13
+ * mentions, authors, the comment mark (`comments` is an interaction feature, but stored documents contain its mark), and
14
+ * tables. Each entry is the very `schemaExtensions` function the feature of that id declares; the features themselves
15
+ * are not imported, because they carry node views and UI that a server must never load.
22
16
  */
23
- const advancedSchemaExtensions = () => [
24
- StarterKit.configure({
25
- strike: false,
26
- undoRedo: false
27
- }),
28
- StrikeX,
29
- NodeFlags,
30
- OpaqueFence,
31
- ...mediaSchemaExtensions(),
32
- ...transcriptSchemaExtensions(),
33
- ...compositeSchemaExtensions(),
34
- ...mentionsSchemaExtensions(),
35
- ...authorsSchemaExtensions(),
36
- ...commentsSchemaExtensions(),
37
- ...tablesSchemaExtensions(),
38
- BlockId
17
+ const RICH_CONTENT_SCHEMA = [
18
+ { schemaExtensions: coreContentSchemaExtensions },
19
+ { schemaExtensions: mediaSchemaExtensions },
20
+ { schemaExtensions: transcriptSchemaExtensions },
21
+ { schemaExtensions: () => compositeSchemaExtensions() },
22
+ { schemaExtensions: mentionsSchemaExtensions },
23
+ { schemaExtensions: authorsSchemaExtensions },
24
+ { schemaExtensions: commentsSchemaExtensions },
25
+ { schemaExtensions: tablesSchemaExtensions }
39
26
  ];
27
+ /**
28
+ * The Vue-free schema of the advanced editor, free of node views, UI and collaboration runtime: the server builds the
29
+ * same schema with `getSchema(advancedSchemaExtensions())` to convert between TipTap JSON and Yjs. Derived with
30
+ * `schemaExtensionsOf` from the schema-bearing features: StarterKit/StrikeX, the generic node flags, the opaque fence,
31
+ * media (image, audio, video, file), transcript, the composite family, mentions/tags, the author and comment marks, the
32
+ * GFM table and task-list nodes (for hosts whose preset adds `tablesFeature()`; the advanced preset itself has none) and
33
+ * last `BlockId`, which adds the `id` attribute to every block type (its ID-assigning plugins only run in an editor).
34
+ * `undoRedo: false`: under collaboration the Collaboration extension provides the (per-user) undo manager.
35
+ */
36
+ const advancedSchemaExtensions = () => schemaExtensionsOf(RICH_CONTENT_SCHEMA);
40
37
  //#endregion
41
38
  export { advancedSchemaExtensions };
42
39
 
@@ -1 +1 @@
1
- {"version":3,"file":"advanced.js","names":[],"sources":["../../src/schema/advanced.ts"],"sourcesContent":["import type { AnyExtension } from '@tiptap/core'\nimport StarterKit from '@tiptap/starter-kit'\nimport { BlockId, NodeFlags, OpaqueFence, StrikeX } from '../core/schema'\nimport { authorsSchemaExtensions } from '../features/authors/schema'\nimport { commentsSchemaExtensions } from '../features/comments/schema'\nimport { compositeSchemaExtensions } from '../features/composites/schema'\nimport { mediaSchemaExtensions } from '../features/media/schema'\nimport { mentionsSchemaExtensions } from '../features/mentions/schema'\nimport { tablesSchemaExtensions } from '../features/tables/schema'\nimport { transcriptSchemaExtensions } from '../features/transcript/schema'\n\n/**\n * The Vue-free schema of the advanced editor, free of node views, UI and collaboration runtime: the server builds the\n * same schema with `getSchema(advancedSchemaExtensions())` to convert between TipTap JSON and Yjs. The order is the\n * order of the client's schema-bearing extensions: StarterKit/StrikeX, the generic node flags, the opaque fence, media (image, audio,\n * video, file), transcript, the composite family, mentions/tags, the author and comment marks, the GFM table and task-list\n * nodes (for hosts whose preset adds `tablesFeature()`; the advanced preset itself has none) and last `BlockId`, which\n * adds the `id` attribute to every block type (its ID-assigning plugins only run in an editor). `undoRedo: false`:\n * under collaboration the Collaboration extension provides the (per-user) undo manager.\n */\nexport const advancedSchemaExtensions = (): AnyExtension[] => [\n StarterKit.configure({ strike: false, undoRedo: false }),\n StrikeX,\n NodeFlags,\n OpaqueFence,\n ...mediaSchemaExtensions(),\n ...transcriptSchemaExtensions(),\n ...compositeSchemaExtensions(),\n ...mentionsSchemaExtensions(),\n ...authorsSchemaExtensions(),\n ...commentsSchemaExtensions(),\n ...tablesSchemaExtensions(),\n BlockId,\n]\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;AAoBA,MAAa,iCAAiD;CAC5D,WAAW,UAAU;EAAE,QAAQ;EAAO,UAAU;CAAM,CAAC;CACvD;CACA;CACA;CACA,GAAG,sBAAsB;CACzB,GAAG,2BAA2B;CAC9B,GAAG,0BAA0B;CAC7B,GAAG,yBAAyB;CAC5B,GAAG,wBAAwB;CAC3B,GAAG,yBAAyB;CAC5B,GAAG,uBAAuB;CAC1B;AACF"}
1
+ {"version":3,"file":"advanced.js","names":[],"sources":["../../src/schema/advanced.ts"],"sourcesContent":["import type { AnyExtension } from '@tiptap/core'\nimport { coreContentSchemaExtensions, schemaExtensionsOf } from '../core/schema'\nimport { authorsSchemaExtensions } from '../features/authors/schema'\nimport { commentsSchemaExtensions } from '../features/comments/schema'\nimport { compositeSchemaExtensions } from '../features/composites/schema'\nimport { mediaSchemaExtensions } from '../features/media/schema'\nimport { mentionsSchemaExtensions } from '../features/mentions/schema'\nimport { tablesSchemaExtensions } from '../features/tables/schema'\nimport { transcriptSchemaExtensions } from '../features/transcript/schema'\n\n/**\n * The schema-bearing slice of the rich content features, in schema order: `core-content`, media, transcript, composites,\n * mentions, authors, the comment mark (`comments` is an interaction feature, but stored documents contain its mark), and\n * tables. Each entry is the very `schemaExtensions` function the feature of that id declares; the features themselves\n * are not imported, because they carry node views and UI that a server must never load.\n */\nconst RICH_CONTENT_SCHEMA = [\n { schemaExtensions: coreContentSchemaExtensions },\n { schemaExtensions: mediaSchemaExtensions },\n { schemaExtensions: transcriptSchemaExtensions },\n { schemaExtensions: () => compositeSchemaExtensions() },\n { schemaExtensions: mentionsSchemaExtensions },\n { schemaExtensions: authorsSchemaExtensions },\n { schemaExtensions: commentsSchemaExtensions },\n { schemaExtensions: tablesSchemaExtensions },\n]\n\n/**\n * The Vue-free schema of the advanced editor, free of node views, UI and collaboration runtime: the server builds the\n * same schema with `getSchema(advancedSchemaExtensions())` to convert between TipTap JSON and Yjs. Derived with\n * `schemaExtensionsOf` from the schema-bearing features: StarterKit/StrikeX, the generic node flags, the opaque fence,\n * media (image, audio, video, file), transcript, the composite family, mentions/tags, the author and comment marks, the\n * GFM table and task-list nodes (for hosts whose preset adds `tablesFeature()`; the advanced preset itself has none) and\n * last `BlockId`, which adds the `id` attribute to every block type (its ID-assigning plugins only run in an editor).\n * `undoRedo: false`: under collaboration the Collaboration extension provides the (per-user) undo manager.\n */\nexport const advancedSchemaExtensions = (): AnyExtension[] => schemaExtensionsOf(RICH_CONTENT_SCHEMA)\n"],"mappings":";;;;;;;;;;;;;;;;AAgBA,MAAM,sBAAsB;CAC1B,EAAE,kBAAkB,4BAA4B;CAChD,EAAE,kBAAkB,sBAAsB;CAC1C,EAAE,kBAAkB,2BAA2B;CAC/C,EAAE,wBAAwB,0BAA0B,EAAE;CACtD,EAAE,kBAAkB,yBAAyB;CAC7C,EAAE,kBAAkB,wBAAwB;CAC5C,EAAE,kBAAkB,yBAAyB;CAC7C,EAAE,kBAAkB,uBAAuB;AAC7C;;;;;;;;;;AAWA,MAAa,iCAAiD,mBAAmB,mBAAmB"}
@@ -1,6 +1,7 @@
1
1
  import { ModelSlot } from "../settings/values.js";
2
2
  import "../settings/index.js";
3
- import { ModelProfile, ModelRef } from "../features/ai/protocol/models.js";
3
+ import { PresetConfig, TranscriptionConfig } from "../config/index.js";
4
+ import { ModelProfile, ModelRef } from "../core/backend-types.js";
4
5
  import "../features/ai/protocol/index.js";
5
6
  import { HttpError } from "./errors.js";
6
7
  import { LanguageModel, ModelMessage, ToolChoice, ToolSet } from "ai";
@@ -20,19 +21,6 @@ export type ChatTurnPart = {
20
21
  input: unknown;
21
22
  invalid: boolean;
22
23
  };
23
- /** Server-defined model preset (any OpenAI-compatible chat completions endpoint); its key falls back to the shared `apiKey`. */
24
- export interface PresetConfig {
25
- label: string;
26
- endpoint: string;
27
- model: string;
28
- apiKey?: string;
29
- }
30
- /** Speech-to-text endpoint: any OpenAI-compatible `<endpoint>/audio/transcriptions`. */
31
- export interface TranscriptionConfig {
32
- endpoint: string;
33
- model: string;
34
- apiKey?: string;
35
- }
36
24
  /** Everything the AI endpoints need, passed explicitly: no runtime config, no globals. */
37
25
  export interface AiModelsConfig {
38
26
  /** Server-defined model presets, keyed by preset id. */
@@ -44,11 +32,11 @@ export interface AiModelsConfig {
44
32
  /** Speech-to-text for audio/video composites; absent = the transcription endpoint answers 501. */
45
33
  transcription?: TranscriptionConfig;
46
34
  /**
47
- * The host's own language model for `ref` (`EditorAdapter.languageModel`), consulted before the presets for every
35
+ * The host's own language model for `ref` (`ModelProvider.languageModel`), consulted before the presets for every
48
36
  * model reference; `user` is what `authenticate` returned. `null` or nothing falls through to the presets.
49
37
  */
50
38
  languageModel?: (ref: ModelRef, user: object | null) => Promise<LanguageModel | null | undefined>;
51
- /** The models listed for `user` instead of the presets (`EditorAdapter.listModels`); `null` or nothing lists the presets. */
39
+ /** The models listed for `user` instead of the presets (`ModelProvider.listModels`); `null` or nothing lists the presets. */
52
40
  listModels?: (user: object | null) => Promise<ModelProfile[] | null | undefined>;
53
41
  /** Appended to the error of a preset without key, e.g. the environment variable names that set it. */
54
42
  missingKeyHint?: (presetId: string) => string;
@@ -98,4 +86,5 @@ export declare function streamChatTurn(opts: {
98
86
  toolChoice?: ToolChoice<ToolSet>;
99
87
  }): AsyncGenerator<ChatTurnPart>;
100
88
  //#endregion
89
+ export type { PresetConfig, TranscriptionConfig };
101
90
  //# sourceMappingURL=ai.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"ai.js","names":[],"sources":["../../src/server/ai.ts"],"sourcesContent":["import { createOpenAICompatible } from '@ai-sdk/openai-compatible'\nimport { APICallError, type LanguageModel, type ModelMessage, streamText, type ToolChoice, type ToolSet } from 'ai'\nimport type { ModelProfile, ModelRef } from '../features/ai/protocol'\nimport type { ModelSlot } from '../settings'\nimport { HttpError } from './errors'\n\nexport interface ChatMessage { role: 'system' | 'user' | 'assistant', content: string }\n\n/** A streamed text delta, or a finished tool call (`invalid`: unparsable input or unknown tool). */\nexport type ChatTurnPart =\n | { type: 'text', text: string }\n | { type: 'tool-call', toolCallId: string, toolName: string, input: unknown, invalid: boolean }\n\n/** Server-defined model preset (any OpenAI-compatible chat completions endpoint); its key falls back to the shared `apiKey`. */\nexport interface PresetConfig { label: string, endpoint: string, model: string, apiKey?: string }\n\n/** Speech-to-text endpoint: any OpenAI-compatible `<endpoint>/audio/transcriptions`. */\nexport interface TranscriptionConfig { endpoint: string, model: string, apiKey?: string }\n\n/** Everything the AI endpoints need, passed explicitly: no runtime config, no globals. */\nexport interface AiModelsConfig {\n /** Server-defined model presets, keyed by preset id. */\n presets: Record<string, PresetConfig>\n /** Shared key of presets without their own. */\n apiKey?: string\n /** Default preset per model slot, answered by `GET /api/ai/models`. */\n slots?: Record<ModelSlot, string>\n /** Speech-to-text for audio/video composites; absent = the transcription endpoint answers 501. */\n transcription?: TranscriptionConfig\n /**\n * The host's own language model for `ref` (`EditorAdapter.languageModel`), consulted before the presets for every\n * model reference; `user` is what `authenticate` returned. `null` or nothing falls through to the presets.\n */\n languageModel?: (ref: ModelRef, user: object | null) => Promise<LanguageModel | null | undefined>\n /** The models listed for `user` instead of the presets (`EditorAdapter.listModels`); `null` or nothing lists the presets. */\n listModels?: (user: object | null) => Promise<ModelProfile[] | null | undefined>\n /** Appended to the error of a preset without key, e.g. the environment variable names that set it. */\n missingKeyHint?: (presetId: string) => string\n}\n\nexport interface AiModels {\n /**\n * AI SDK language model for `ref` (an OpenAI-compatible chat completions endpoint), for direct `ai` calls. The\n * host's `languageModel(ref, user)` is asked first (`user`: what `authenticate` returned); a model it returns is\n * used as is, `null` (or no such hook) falls through to the configured presets. A preset uses its own key or the\n * shared `apiKey`; a user ref brings its own. Throws `HttpError` 400 for an unknown preset and 500 for a preset\n * without key, so routes can call it before streaming starts.\n */\n resolveModel(ref: ModelRef, user: object | null): Promise<LanguageModel>\n /**\n * The configured presets as the client may see them: without their keys. `user` is what the host's `authenticate`\n * returned; the `listModels` hook supplies the list when it returns one (replacing the presets).\n */\n listModels(user: object | null): Promise<ModelProfile[]>\n readonly slots: Record<ModelSlot, string> | undefined\n readonly transcription: TranscriptionConfig | undefined\n streamChat: typeof streamChat\n streamChatTurn: typeof streamChatTurn\n}\n\n/** The AI model utilities over an explicit configuration. */\nexport function createAiModels(config: AiModelsConfig): AiModels {\n return {\n async resolveModel(ref, user) {\n const hosted = await config.languageModel?.(ref, user)\n if (hosted) return hosted\n if (!('preset' in ref)) return createOpenAICompatible({ name: 'tiptap-editor', baseURL: ref.endpoint, apiKey: ref.apiKey }).chatModel(ref.model)\n const preset = config.presets[ref.preset]\n if (!preset) throw new HttpError(400, 'Unbekanntes Modell-Preset')\n const apiKey = preset.apiKey || config.apiKey\n if (!apiKey) throw new HttpError(500, `API-Key für Preset „${ref.preset}“ fehlt${config.missingKeyHint?.(ref.preset) ?? ''}`)\n return createOpenAICompatible({ name: 'tiptap-editor', baseURL: preset.endpoint, apiKey }).chatModel(preset.model)\n },\n async listModels(user) {\n const listed = await config.listModels?.(user)\n if (listed) return listed\n return Object.entries(config.presets).map(([id, { label, endpoint, model }]) => ({ id, label, endpoint, model, source: 'preset' }))\n },\n slots: config.slots,\n transcription: config.transcription,\n streamChat,\n streamChatTurn,\n }\n}\n\nexport function upstreamError(error: unknown) {\n let detail: string\n if (APICallError.isInstance(error)) detail = [error.statusCode, error.responseBody || error.message].filter(Boolean).join(' ')\n else if (error instanceof Error) detail = error.message\n else detail = (error as { message?: string } | null)?.message ?? JSON.stringify(error)\n return new HttpError(502, `KI-Endpunkt: ${detail}`.slice(0, 500))\n}\n\n/**\n * Streams the text deltas of a chat completion (AI SDK `streamText`) on the resolved language model `model` (see\n * `resolveModel`). System messages may appear in `messages`; a trailing assistant message is a prefill the model\n * continues. Upstream failures throw a 502 `HttpError`; aborting `signal` cancels the upstream request and makes the\n * generator throw.\n */\nexport async function* streamChat(opts: { model: LanguageModel, messages: ChatMessage[], signal: AbortSignal }): AsyncGenerator<string> {\n for await (const part of streamChatTurn(opts)) {\n if (part.type === 'text') yield part.text\n }\n}\n\n/**\n * Like `streamChat`, with `tools` the model may call (tools without `execute`: the turn ends with the calls, which are\n * yielded for the caller to handle) and structured `messages` (tool calls and results in the history).\n */\nexport async function* streamChatTurn(opts: {\n model: LanguageModel\n messages: ModelMessage[]\n signal: AbortSignal\n tools?: ToolSet\n toolChoice?: ToolChoice<ToolSet>\n}): AsyncGenerator<ChatTurnPart> {\n const { model } = opts\n // Also cancels the upstream request when the consumer stops iterating early (break / return).\n const upstream = new AbortController()\n const onAbort = () => upstream.abort(opts.signal.reason)\n if (opts.signal.aborted) onAbort()\n else opts.signal.addEventListener('abort', onAbort, { once: true })\n try {\n const result = streamText({\n model,\n messages: opts.messages,\n tools: opts.tools,\n toolChoice: opts.toolChoice,\n allowSystemInMessages: true,\n abortSignal: upstream.signal,\n maxRetries: 0,\n // Errors surface as `error` parts below and are rethrown; the default handler would only log them.\n onError: () => {},\n })\n for await (const part of result.stream) {\n if (part.type === 'text-delta') {\n if (part.text) yield { type: 'text', text: part.text }\n }\n else if (part.type === 'tool-call') {\n yield { type: 'tool-call', toolCallId: part.toolCallId, toolName: part.toolName, input: part.input, invalid: part.invalid === true }\n }\n else if (part.type === 'error') {\n if (opts.signal.aborted) break\n throw upstreamError(part.error)\n }\n else if (part.type === 'abort') {\n break\n }\n }\n opts.signal.throwIfAborted()\n }\n finally {\n opts.signal.removeEventListener('abort', onAbort)\n upstream.abort()\n }\n}\n"],"mappings":";;;;;AA6DA,SAAgB,eAAe,QAAkC;CAC/D,OAAO;EACL,MAAM,aAAa,KAAK,MAAM;GAC5B,MAAM,SAAS,MAAM,OAAO,gBAAgB,KAAK,IAAI;GACrD,IAAI,QAAQ,OAAO;GACnB,IAAI,EAAE,YAAY,MAAM,OAAO,uBAAuB;IAAE,MAAM;IAAiB,SAAS,IAAI;IAAU,QAAQ,IAAI;GAAO,CAAC,CAAC,CAAC,UAAU,IAAI,KAAK;GAC/I,MAAM,SAAS,OAAO,QAAQ,IAAI;GAClC,IAAI,CAAC,QAAQ,MAAM,IAAI,UAAU,KAAK,2BAA2B;GACjE,MAAM,SAAS,OAAO,UAAU,OAAO;GACvC,IAAI,CAAC,QAAQ,MAAM,IAAI,UAAU,KAAK,uBAAuB,IAAI,OAAO,SAAS,OAAO,iBAAiB,IAAI,MAAM,KAAK,IAAI;GAC5H,OAAO,uBAAuB;IAAE,MAAM;IAAiB,SAAS,OAAO;IAAU;GAAO,CAAC,CAAC,CAAC,UAAU,OAAO,KAAK;EACnH;EACA,MAAM,WAAW,MAAM;GACrB,MAAM,SAAS,MAAM,OAAO,aAAa,IAAI;GAC7C,IAAI,QAAQ,OAAO;GACnB,OAAO,OAAO,QAAQ,OAAO,OAAO,CAAC,CAAC,KAAK,CAAC,IAAI,EAAE,OAAO,UAAU,cAAc;IAAE;IAAI;IAAO;IAAU;IAAO,QAAQ;GAAS,EAAE;EACpI;EACA,OAAO,OAAO;EACd,eAAe,OAAO;EACtB;EACA;CACF;AACF;AAEA,SAAgB,cAAc,OAAgB;CAC5C,IAAI;CACJ,IAAI,aAAa,WAAW,KAAK,GAAG,SAAS,CAAC,MAAM,YAAY,MAAM,gBAAgB,MAAM,OAAO,CAAC,CAAC,OAAO,OAAO,CAAC,CAAC,KAAK,GAAG;MACxH,IAAI,iBAAiB,OAAO,SAAS,MAAM;MAC3C,SAAU,OAAuC,WAAW,KAAK,UAAU,KAAK;CACrF,OAAO,IAAI,UAAU,KAAK,gBAAgB,SAAS,MAAM,GAAG,GAAG,CAAC;AAClE;;;;;;;AAQA,gBAAuB,WAAW,MAAsG;CACtI,WAAW,MAAM,QAAQ,eAAe,IAAI,GAC1C,IAAI,KAAK,SAAS,QAAQ,MAAM,KAAK;AAEzC;;;;;AAMA,gBAAuB,eAAe,MAML;CAC/B,MAAM,EAAE,UAAU;CAElB,MAAM,WAAW,IAAI,gBAAgB;CACrC,MAAM,gBAAgB,SAAS,MAAM,KAAK,OAAO,MAAM;CACvD,IAAI,KAAK,OAAO,SAAS,QAAQ;MAC5B,KAAK,OAAO,iBAAiB,SAAS,SAAS,EAAE,MAAM,KAAK,CAAC;CAClE,IAAI;EACF,MAAM,SAAS,WAAW;GACxB;GACA,UAAU,KAAK;GACf,OAAO,KAAK;GACZ,YAAY,KAAK;GACjB,uBAAuB;GACvB,aAAa,SAAS;GACtB,YAAY;GAEZ,eAAe,CAAC;EAClB,CAAC;EACD,WAAW,MAAM,QAAQ,OAAO,QAC9B,IAAI,KAAK,SAAS,cACZ;OAAA,KAAK,MAAM,MAAM;IAAE,MAAM;IAAQ,MAAM,KAAK;GAAK;EAAA,OAElD,IAAI,KAAK,SAAS,aACrB,MAAM;GAAE,MAAM;GAAa,YAAY,KAAK;GAAY,UAAU,KAAK;GAAU,OAAO,KAAK;GAAO,SAAS,KAAK,YAAY;EAAK;OAEhI,IAAI,KAAK,SAAS,SAAS;GAC9B,IAAI,KAAK,OAAO,SAAS;GACzB,MAAM,cAAc,KAAK,KAAK;EAChC,OACK,IAAI,KAAK,SAAS,SACrB;EAGJ,KAAK,OAAO,eAAe;CAC7B,UACQ;EACN,KAAK,OAAO,oBAAoB,SAAS,OAAO;EAChD,SAAS,MAAM;CACjB;AACF"}
1
+ {"version":3,"file":"ai.js","names":[],"sources":["../../src/server/ai.ts"],"sourcesContent":["import { createOpenAICompatible } from '@ai-sdk/openai-compatible'\nimport { APICallError, type LanguageModel, type ModelMessage, streamText, type ToolChoice, type ToolSet } from 'ai'\nimport type { ModelProfile, ModelRef } from '../features/ai/protocol'\nimport type { ModelSlot } from '../settings'\nimport type { PresetConfig, TranscriptionConfig } from '../config'\nimport { HttpError } from './errors'\n\nexport interface ChatMessage { role: 'system' | 'user' | 'assistant', content: string }\n\n/** A streamed text delta, or a finished tool call (`invalid`: unparsable input or unknown tool). */\nexport type ChatTurnPart =\n | { type: 'text', text: string }\n | { type: 'tool-call', toolCallId: string, toolName: string, input: unknown, invalid: boolean }\n\nexport type { PresetConfig, TranscriptionConfig }\n\n/** Everything the AI endpoints need, passed explicitly: no runtime config, no globals. */\nexport interface AiModelsConfig {\n /** Server-defined model presets, keyed by preset id. */\n presets: Record<string, PresetConfig>\n /** Shared key of presets without their own. */\n apiKey?: string\n /** Default preset per model slot, answered by `GET /api/ai/models`. */\n slots?: Record<ModelSlot, string>\n /** Speech-to-text for audio/video composites; absent = the transcription endpoint answers 501. */\n transcription?: TranscriptionConfig\n /**\n * The host's own language model for `ref` (`ModelProvider.languageModel`), consulted before the presets for every\n * model reference; `user` is what `authenticate` returned. `null` or nothing falls through to the presets.\n */\n languageModel?: (ref: ModelRef, user: object | null) => Promise<LanguageModel | null | undefined>\n /** The models listed for `user` instead of the presets (`ModelProvider.listModels`); `null` or nothing lists the presets. */\n listModels?: (user: object | null) => Promise<ModelProfile[] | null | undefined>\n /** Appended to the error of a preset without key, e.g. the environment variable names that set it. */\n missingKeyHint?: (presetId: string) => string\n}\n\nexport interface AiModels {\n /**\n * AI SDK language model for `ref` (an OpenAI-compatible chat completions endpoint), for direct `ai` calls. The\n * host's `languageModel(ref, user)` is asked first (`user`: what `authenticate` returned); a model it returns is\n * used as is, `null` (or no such hook) falls through to the configured presets. A preset uses its own key or the\n * shared `apiKey`; a user ref brings its own. Throws `HttpError` 400 for an unknown preset and 500 for a preset\n * without key, so routes can call it before streaming starts.\n */\n resolveModel(ref: ModelRef, user: object | null): Promise<LanguageModel>\n /**\n * The configured presets as the client may see them: without their keys. `user` is what the host's `authenticate`\n * returned; the `listModels` hook supplies the list when it returns one (replacing the presets).\n */\n listModels(user: object | null): Promise<ModelProfile[]>\n readonly slots: Record<ModelSlot, string> | undefined\n readonly transcription: TranscriptionConfig | undefined\n streamChat: typeof streamChat\n streamChatTurn: typeof streamChatTurn\n}\n\n/** The AI model utilities over an explicit configuration. */\nexport function createAiModels(config: AiModelsConfig): AiModels {\n return {\n async resolveModel(ref, user) {\n const hosted = await config.languageModel?.(ref, user)\n if (hosted) return hosted\n if (!('preset' in ref)) return createOpenAICompatible({ name: 'tiptap-editor', baseURL: ref.endpoint, apiKey: ref.apiKey }).chatModel(ref.model)\n const preset = config.presets[ref.preset]\n if (!preset) throw new HttpError(400, 'Unbekanntes Modell-Preset')\n const apiKey = preset.apiKey || config.apiKey\n if (!apiKey) throw new HttpError(500, `API-Key für Preset „${ref.preset}“ fehlt${config.missingKeyHint?.(ref.preset) ?? ''}`)\n return createOpenAICompatible({ name: 'tiptap-editor', baseURL: preset.endpoint, apiKey }).chatModel(preset.model)\n },\n async listModels(user) {\n const listed = await config.listModels?.(user)\n if (listed) return listed\n return Object.entries(config.presets).map(([id, { label, endpoint, model }]) => ({ id, label, endpoint, model, source: 'preset' }))\n },\n slots: config.slots,\n transcription: config.transcription,\n streamChat,\n streamChatTurn,\n }\n}\n\nexport function upstreamError(error: unknown) {\n let detail: string\n if (APICallError.isInstance(error)) detail = [error.statusCode, error.responseBody || error.message].filter(Boolean).join(' ')\n else if (error instanceof Error) detail = error.message\n else detail = (error as { message?: string } | null)?.message ?? JSON.stringify(error)\n return new HttpError(502, `KI-Endpunkt: ${detail}`.slice(0, 500))\n}\n\n/**\n * Streams the text deltas of a chat completion (AI SDK `streamText`) on the resolved language model `model` (see\n * `resolveModel`). System messages may appear in `messages`; a trailing assistant message is a prefill the model\n * continues. Upstream failures throw a 502 `HttpError`; aborting `signal` cancels the upstream request and makes the\n * generator throw.\n */\nexport async function* streamChat(opts: { model: LanguageModel, messages: ChatMessage[], signal: AbortSignal }): AsyncGenerator<string> {\n for await (const part of streamChatTurn(opts)) {\n if (part.type === 'text') yield part.text\n }\n}\n\n/**\n * Like `streamChat`, with `tools` the model may call (tools without `execute`: the turn ends with the calls, which are\n * yielded for the caller to handle) and structured `messages` (tool calls and results in the history).\n */\nexport async function* streamChatTurn(opts: {\n model: LanguageModel\n messages: ModelMessage[]\n signal: AbortSignal\n tools?: ToolSet\n toolChoice?: ToolChoice<ToolSet>\n}): AsyncGenerator<ChatTurnPart> {\n const { model } = opts\n // Also cancels the upstream request when the consumer stops iterating early (break / return).\n const upstream = new AbortController()\n const onAbort = () => upstream.abort(opts.signal.reason)\n if (opts.signal.aborted) onAbort()\n else opts.signal.addEventListener('abort', onAbort, { once: true })\n try {\n const result = streamText({\n model,\n messages: opts.messages,\n tools: opts.tools,\n toolChoice: opts.toolChoice,\n allowSystemInMessages: true,\n abortSignal: upstream.signal,\n maxRetries: 0,\n // Errors surface as `error` parts below and are rethrown; the default handler would only log them.\n onError: () => {},\n })\n for await (const part of result.stream) {\n if (part.type === 'text-delta') {\n if (part.text) yield { type: 'text', text: part.text }\n }\n else if (part.type === 'tool-call') {\n yield { type: 'tool-call', toolCallId: part.toolCallId, toolName: part.toolName, input: part.input, invalid: part.invalid === true }\n }\n else if (part.type === 'error') {\n if (opts.signal.aborted) break\n throw upstreamError(part.error)\n }\n else if (part.type === 'abort') {\n break\n }\n }\n opts.signal.throwIfAborted()\n }\n finally {\n opts.signal.removeEventListener('abort', onAbort)\n upstream.abort()\n }\n}\n"],"mappings":";;;;;AA0DA,SAAgB,eAAe,QAAkC;CAC/D,OAAO;EACL,MAAM,aAAa,KAAK,MAAM;GAC5B,MAAM,SAAS,MAAM,OAAO,gBAAgB,KAAK,IAAI;GACrD,IAAI,QAAQ,OAAO;GACnB,IAAI,EAAE,YAAY,MAAM,OAAO,uBAAuB;IAAE,MAAM;IAAiB,SAAS,IAAI;IAAU,QAAQ,IAAI;GAAO,CAAC,CAAC,CAAC,UAAU,IAAI,KAAK;GAC/I,MAAM,SAAS,OAAO,QAAQ,IAAI;GAClC,IAAI,CAAC,QAAQ,MAAM,IAAI,UAAU,KAAK,2BAA2B;GACjE,MAAM,SAAS,OAAO,UAAU,OAAO;GACvC,IAAI,CAAC,QAAQ,MAAM,IAAI,UAAU,KAAK,uBAAuB,IAAI,OAAO,SAAS,OAAO,iBAAiB,IAAI,MAAM,KAAK,IAAI;GAC5H,OAAO,uBAAuB;IAAE,MAAM;IAAiB,SAAS,OAAO;IAAU;GAAO,CAAC,CAAC,CAAC,UAAU,OAAO,KAAK;EACnH;EACA,MAAM,WAAW,MAAM;GACrB,MAAM,SAAS,MAAM,OAAO,aAAa,IAAI;GAC7C,IAAI,QAAQ,OAAO;GACnB,OAAO,OAAO,QAAQ,OAAO,OAAO,CAAC,CAAC,KAAK,CAAC,IAAI,EAAE,OAAO,UAAU,cAAc;IAAE;IAAI;IAAO;IAAU;IAAO,QAAQ;GAAS,EAAE;EACpI;EACA,OAAO,OAAO;EACd,eAAe,OAAO;EACtB;EACA;CACF;AACF;AAEA,SAAgB,cAAc,OAAgB;CAC5C,IAAI;CACJ,IAAI,aAAa,WAAW,KAAK,GAAG,SAAS,CAAC,MAAM,YAAY,MAAM,gBAAgB,MAAM,OAAO,CAAC,CAAC,OAAO,OAAO,CAAC,CAAC,KAAK,GAAG;MACxH,IAAI,iBAAiB,OAAO,SAAS,MAAM;MAC3C,SAAU,OAAuC,WAAW,KAAK,UAAU,KAAK;CACrF,OAAO,IAAI,UAAU,KAAK,gBAAgB,SAAS,MAAM,GAAG,GAAG,CAAC;AAClE;;;;;;;AAQA,gBAAuB,WAAW,MAAsG;CACtI,WAAW,MAAM,QAAQ,eAAe,IAAI,GAC1C,IAAI,KAAK,SAAS,QAAQ,MAAM,KAAK;AAEzC;;;;;AAMA,gBAAuB,eAAe,MAML;CAC/B,MAAM,EAAE,UAAU;CAElB,MAAM,WAAW,IAAI,gBAAgB;CACrC,MAAM,gBAAgB,SAAS,MAAM,KAAK,OAAO,MAAM;CACvD,IAAI,KAAK,OAAO,SAAS,QAAQ;MAC5B,KAAK,OAAO,iBAAiB,SAAS,SAAS,EAAE,MAAM,KAAK,CAAC;CAClE,IAAI;EACF,MAAM,SAAS,WAAW;GACxB;GACA,UAAU,KAAK;GACf,OAAO,KAAK;GACZ,YAAY,KAAK;GACjB,uBAAuB;GACvB,aAAa,SAAS;GACtB,YAAY;GAEZ,eAAe,CAAC;EAClB,CAAC;EACD,WAAW,MAAM,QAAQ,OAAO,QAC9B,IAAI,KAAK,SAAS,cACZ;OAAA,KAAK,MAAM,MAAM;IAAE,MAAM;IAAQ,MAAM,KAAK;GAAK;EAAA,OAElD,IAAI,KAAK,SAAS,aACrB,MAAM;GAAE,MAAM;GAAa,YAAY,KAAK;GAAY,UAAU,KAAK;GAAU,OAAO,KAAK;GAAO,SAAS,KAAK,YAAY;EAAK;OAEhI,IAAI,KAAK,SAAS,SAAS;GAC9B,IAAI,KAAK,OAAO,SAAS;GACzB,MAAM,cAAc,KAAK,KAAK;EAChC,OACK,IAAI,KAAK,SAAS,SACrB;EAGJ,KAAK,OAAO,eAAe;CAC7B,UACQ;EACN,KAAK,OAAO,oBAAoB,SAAS,OAAO;EAChD,SAAS,MAAM;CACjB;AACF"}
@@ -0,0 +1,9 @@
1
+ //#region src/server/auth.d.ts
2
+ /** What `Identity.authenticate` gets: the headers of the request (the websocket upgrade for collaboration) and the connection's `token`. */
3
+ export interface AuthenticateRequest {
4
+ headers: Headers;
5
+ /** The collaboration client's token (`HocuspocusProvider` `token`, sent right after the socket opened); absent for plain HTTP requests and token-less clients. */
6
+ token?: string;
7
+ }
8
+ //#endregion
9
+ //# sourceMappingURL=auth.d.ts.map
@@ -1,6 +1,6 @@
1
1
  //#region src/server/collab-state.d.ts
2
2
  export interface CollabState {
3
- /** `EditorAdapter.contentVersion` of the content the update was stored with; `null` = none known (also: legacy payload). */
3
+ /** `DocumentStore.contentVersion` of the content the update was stored with; `null` = none known (also: legacy payload). */
4
4
  version: string | null;
5
5
  update: Uint8Array;
6
6
  }
@@ -1 +1 @@
1
- {"version":3,"file":"collab-state.js","names":[],"sources":["../../src/server/collab-state.ts"],"sourcesContent":["// Stored Yjs state payload and the re-seed decision of the collab server. Pure: no Hocuspocus, no adapter, no Yjs.\n//\n// The adapter stores opaque bytes (`loadState`/`storeState` keep their signature); the server prefixes the Yjs update\n// with the content version it was written against:\n//\n// [0xFF, 0x76] marker (cannot start a legacy payload: a Yjs update opens with the varuint number of client groups,\n// and two continuation bytes would mean 16384 or more clients)\n// utf8 version empty = `null`\n// 0x00 terminator, so a version never contains NUL\n// update bytes `Y.encodeStateAsUpdate`\n//\n// Payloads without the marker are legacy raw updates and decode as `version: null`.\n\nconst MARKER = [0xFF, 0x76] as const\nconst TERMINATOR = 0\n\nconst encoder = new TextEncoder()\nconst decoder = new TextDecoder()\n\nexport interface CollabState {\n /** `EditorAdapter.contentVersion` of the content the update was stored with; `null` = none known (also: legacy payload). */\n version: string | null\n update: Uint8Array\n}\n\nexport function encodeCollabState({ version, update }: CollabState): Uint8Array {\n const label = encoder.encode(version ?? '')\n if (label.includes(TERMINATOR)) throw new Error('tiptap-editor: contentVersion darf kein NUL-Zeichen enthalten')\n const out = new Uint8Array(MARKER.length + label.length + 1 + update.length)\n out.set(MARKER, 0)\n out.set(label, MARKER.length)\n out[MARKER.length + label.length] = TERMINATOR\n out.set(update, MARKER.length + label.length + 1)\n return out\n}\n\nexport function decodeCollabState(payload: Uint8Array): CollabState {\n if (payload[0] !== MARKER[0] || payload[1] !== MARKER[1]) return { version: null, update: payload }\n const end = payload.indexOf(TERMINATOR, MARKER.length)\n // A marker without terminator is no payload this module wrote: treat it as an opaque legacy update.\n if (end === -1) return { version: null, update: payload }\n const label = decoder.decode(payload.subarray(MARKER.length, end))\n return { version: label === '' ? null : label, update: payload.subarray(end + 1) }\n}\n\n/**\n * Whether stored collaborative state is stale against the content behind it. Only hosts that implement\n * `contentVersion` opt in (`live === undefined`: the adapter has no such method, state is never discarded). A legacy\n * payload (`stored: null`) against a known live version counts as stale: it cannot prove it matches the content.\n */\nexport function isStateStale(stored: string | null, live: string | null | undefined): boolean {\n return live !== undefined && stored !== live\n}\n"],"mappings":";AAaA,MAAM,SAAS,CAAC,KAAM,GAAI;AAC1B,MAAM,aAAa;AAEnB,MAAM,UAAU,IAAI,YAAY;AAChC,MAAM,UAAU,IAAI,YAAY;AAQhC,SAAgB,kBAAkB,EAAE,SAAS,UAAmC;CAC9E,MAAM,QAAQ,QAAQ,OAAO,WAAW,EAAE;CAC1C,IAAI,MAAM,SAAS,UAAU,GAAG,MAAM,IAAI,MAAM,+DAA+D;CAC/G,MAAM,MAAM,IAAI,WAAW,OAAO,SAAS,MAAM,SAAS,IAAI,OAAO,MAAM;CAC3E,IAAI,IAAI,QAAQ,CAAC;CACjB,IAAI,IAAI,OAAO,OAAO,MAAM;CAC5B,IAAI,OAAO,SAAS,MAAM,UAAU;CACpC,IAAI,IAAI,QAAQ,OAAO,SAAS,MAAM,SAAS,CAAC;CAChD,OAAO;AACT;AAEA,SAAgB,kBAAkB,SAAkC;CAClE,IAAI,QAAQ,OAAO,OAAO,MAAM,QAAQ,OAAO,OAAO,IAAI,OAAO;EAAE,SAAS;EAAM,QAAQ;CAAQ;CAClG,MAAM,MAAM,QAAQ,QAAQ,YAAY,OAAO,MAAM;CAErD,IAAI,QAAQ,IAAI,OAAO;EAAE,SAAS;EAAM,QAAQ;CAAQ;CACxD,MAAM,QAAQ,QAAQ,OAAO,QAAQ,SAAS,OAAO,QAAQ,GAAG,CAAC;CACjE,OAAO;EAAE,SAAS,UAAU,KAAK,OAAO;EAAO,QAAQ,QAAQ,SAAS,MAAM,CAAC;CAAE;AACnF;;;;;;AAOA,SAAgB,aAAa,QAAuB,MAA0C;CAC5F,OAAO,SAAS,KAAA,KAAa,WAAW;AAC1C"}
1
+ {"version":3,"file":"collab-state.js","names":[],"sources":["../../src/server/collab-state.ts"],"sourcesContent":["// Stored Yjs state payload and the re-seed decision of the collab server. Pure: no Hocuspocus, no adapter, no Yjs.\n//\n// The adapter stores opaque bytes (`loadState`/`storeState` keep their signature); the server prefixes the Yjs update\n// with the content version it was written against:\n//\n// [0xFF, 0x76] marker (cannot start a legacy payload: a Yjs update opens with the varuint number of client groups,\n// and two continuation bytes would mean 16384 or more clients)\n// utf8 version empty = `null`\n// 0x00 terminator, so a version never contains NUL\n// update bytes `Y.encodeStateAsUpdate`\n//\n// Payloads without the marker are legacy raw updates and decode as `version: null`.\n\nconst MARKER = [0xFF, 0x76] as const\nconst TERMINATOR = 0\n\nconst encoder = new TextEncoder()\nconst decoder = new TextDecoder()\n\nexport interface CollabState {\n /** `DocumentStore.contentVersion` of the content the update was stored with; `null` = none known (also: legacy payload). */\n version: string | null\n update: Uint8Array\n}\n\nexport function encodeCollabState({ version, update }: CollabState): Uint8Array {\n const label = encoder.encode(version ?? '')\n if (label.includes(TERMINATOR)) throw new Error('tiptap-editor: contentVersion darf kein NUL-Zeichen enthalten')\n const out = new Uint8Array(MARKER.length + label.length + 1 + update.length)\n out.set(MARKER, 0)\n out.set(label, MARKER.length)\n out[MARKER.length + label.length] = TERMINATOR\n out.set(update, MARKER.length + label.length + 1)\n return out\n}\n\nexport function decodeCollabState(payload: Uint8Array): CollabState {\n if (payload[0] !== MARKER[0] || payload[1] !== MARKER[1]) return { version: null, update: payload }\n const end = payload.indexOf(TERMINATOR, MARKER.length)\n // A marker without terminator is no payload this module wrote: treat it as an opaque legacy update.\n if (end === -1) return { version: null, update: payload }\n const label = decoder.decode(payload.subarray(MARKER.length, end))\n return { version: label === '' ? null : label, update: payload.subarray(end + 1) }\n}\n\n/**\n * Whether stored collaborative state is stale against the content behind it. Only hosts that implement\n * `contentVersion` opt in (`live === undefined`: the adapter has no such method, state is never discarded). A legacy\n * payload (`stored: null`) against a known live version counts as stale: it cannot prove it matches the content.\n */\nexport function isStateStale(stored: string | null, live: string | null | undefined): boolean {\n return live !== undefined && stored !== live\n}\n"],"mappings":";AAaA,MAAM,SAAS,CAAC,KAAM,GAAI;AAC1B,MAAM,aAAa;AAEnB,MAAM,UAAU,IAAI,YAAY;AAChC,MAAM,UAAU,IAAI,YAAY;AAQhC,SAAgB,kBAAkB,EAAE,SAAS,UAAmC;CAC9E,MAAM,QAAQ,QAAQ,OAAO,WAAW,EAAE;CAC1C,IAAI,MAAM,SAAS,UAAU,GAAG,MAAM,IAAI,MAAM,+DAA+D;CAC/G,MAAM,MAAM,IAAI,WAAW,OAAO,SAAS,MAAM,SAAS,IAAI,OAAO,MAAM;CAC3E,IAAI,IAAI,QAAQ,CAAC;CACjB,IAAI,IAAI,OAAO,OAAO,MAAM;CAC5B,IAAI,OAAO,SAAS,MAAM,UAAU;CACpC,IAAI,IAAI,QAAQ,OAAO,SAAS,MAAM,SAAS,CAAC;CAChD,OAAO;AACT;AAEA,SAAgB,kBAAkB,SAAkC;CAClE,IAAI,QAAQ,OAAO,OAAO,MAAM,QAAQ,OAAO,OAAO,IAAI,OAAO;EAAE,SAAS;EAAM,QAAQ;CAAQ;CAClG,MAAM,MAAM,QAAQ,QAAQ,YAAY,OAAO,MAAM;CAErD,IAAI,QAAQ,IAAI,OAAO;EAAE,SAAS;EAAM,QAAQ;CAAQ;CACxD,MAAM,QAAQ,QAAQ,OAAO,QAAQ,SAAS,OAAO,QAAQ,GAAG,CAAC;CACjE,OAAO;EAAE,SAAS,UAAU,KAAK,OAAO;EAAO,QAAQ,QAAQ,SAAS,MAAM,CAAC;CAAE;AACnF;;;;;;AAOA,SAAgB,aAAa,QAAuB,MAA0C;CAC5F,OAAO,SAAS,KAAA,KAAa,WAAW;AAC1C"}
@@ -1,4 +1,4 @@
1
- import { EditorAdapter } from "./adapter.js";
1
+ import { DocumentStore, EditorPorts, Identity } from "./ports.js";
2
2
  import { AnyExtension, JSONContent } from "@tiptap/core";
3
3
  import { Schema } from "@tiptap/pm/model";
4
4
  import { Configuration, Hocuspocus, WebSocketLike } from "@hocuspocus/server";
@@ -6,14 +6,14 @@ import { Configuration, Hocuspocus, WebSocketLike } from "@hocuspocus/server";
6
6
  /** Y.XmlFragment the TipTap Collaboration extension binds to (its default `field`). */
7
7
  export declare const COLLAB_FIELD = "default";
8
8
  export interface CollabServerOptions {
9
- /** Storage and identity of the editor backend. */
10
- adapter: EditorAdapter;
11
- /** Extensions of host-defined nodes and marks appended to `advancedSchemaExtensions()`; defaults to `adapter.schemaExtensions`. */
12
- schemaExtensions?: () => AnyExtension[];
13
- /** Per-document access and content versioning; each defaults to the adapter's method of the same name. */
9
+ /** Identity, documents and Yjs state of the editor backend; `collabState` is required. */
10
+ ports: EditorPorts;
11
+ /** TipTap extensions of the collaboration schema; default `advancedSchemaExtensions()`. Host-defined nodes and marks: `() => [...advancedSchemaExtensions(), HostNode]` (Vue-free node files only, no node views). */
12
+ schema?: () => AnyExtension[];
13
+ /** Per-document access and content versioning; each defaults to the port's method of the same name. */
14
14
  hooks?: {
15
- authorize?: NonNullable<EditorAdapter['authorize']>;
16
- contentVersion?: NonNullable<EditorAdapter['contentVersion']>;
15
+ authorize?: NonNullable<Identity['authorize']>;
16
+ contentVersion?: NonNullable<DocumentStore['contentVersion']>;
17
17
  };
18
18
  /** Further Hocuspocus configuration (`debounce`, `timeout`, `quiet`, …); the editor's hooks win over equally named ones. */
19
19
  configuration?: Partial<Configuration>;
@@ -25,11 +25,11 @@ export interface CollabConnection {
25
25
  }
26
26
  export interface CollabServer {
27
27
  /**
28
- * The Hocuspocus instance of this server. The Yjs state (via the adapter's `loadState`/`storeState`) is the source of
29
- * truth for content, the host's JSON content (via the adapter) is a mirror kept up to date on every store.
28
+ * The Hocuspocus instance of this server. The Yjs state (via the `collabState` port's `loadState`/`storeState`) is the
29
+ * source of truth for content, the host's JSON content (via the `documents` port) is a mirror kept up to date on every store.
30
30
  */
31
31
  hocuspocus: Hocuspocus;
32
- /** Schema of the collab server: `advancedSchemaExtensions()` plus the host's extensions, built on first use. */
32
+ /** Schema of the collab server: `options.schema()` (default `advancedSchemaExtensions()`), built on first use. */
33
33
  schema(): Schema;
34
34
  /**
35
35
  * Serves one websocket connection (any transport: crossws, `ws`, Bun, Deno). The user is authenticated in Hocuspocus'
@@ -46,7 +46,7 @@ export interface CollabServer {
46
46
  /**
47
47
  * The host rewrote the content behind the editor's back (an agent wrote the file): merge it into the open document now,
48
48
  * as a diff-update connected clients see as an ordinary edit. Without this the merge waits for the document's next store.
49
- * No-op when nobody has the document open or the content version is unchanged; needs the adapter's `contentVersion`.
49
+ * No-op when nobody has the document open or the content version is unchanged; needs the documents port's `contentVersion`.
50
50
  */
51
51
  contentChanged(id: string): Promise<void>;
52
52
  /** Open collaboration connections and loaded documents of this server. */
@@ -59,7 +59,7 @@ export interface CollabServer {
59
59
  }
60
60
  /**
61
61
  * The editor's collaboration server, independent of any web framework: Hocuspocus with the editor's hooks (seeding from
62
- * the adapter's JSON, versioned state, block-ID backfill, debounced `storeContent`/`storeState`) over `adapter`.
62
+ * the stored JSON, versioned state, block-ID backfill, debounced `storeContent`/`storeState`) over `options.ports`.
63
63
  * `/nuxt` mounts one in Nitro; any Node/Bun/Deno process can serve `handleConnection` on its own websocket transport.
64
64
  */
65
65
  export declare function createCollabServer(options: CollabServerOptions): CollabServer;
@@ -4,9 +4,9 @@ import { migrateLegacyContent } from "../features/composites/legacy.js";
4
4
  import { advancedSchemaExtensions } from "../schema/advanced.js";
5
5
  import { decodeCollabState, encodeCollabState, isStateStale } from "./collab-state.js";
6
6
  import { getSchema } from "@tiptap/core";
7
+ import * as Y from "yjs";
7
8
  import { Hocuspocus } from "@hocuspocus/server";
8
9
  import { prosemirrorToYDoc, prosemirrorToYXmlFragment, yDocToProsemirrorJSON, yXmlFragmentToProsemirror } from "@tiptap/y-tiptap";
9
- import * as Y from "yjs";
10
10
  //#region src/server/collab.ts
11
11
  /** Y.XmlFragment the TipTap Collaboration extension binds to (its default `field`). */
12
12
  const COLLAB_FIELD = "default";
@@ -23,44 +23,58 @@ function contentNode(schema, loaded) {
23
23
  const node = schema.nodeFromJSON(content.type === "doc" && content.content?.length ? content : EMPTY_EDITOR_CONTENT);
24
24
  return assignBlockIds(node) ?? node;
25
25
  }
26
+ /** Whether a `document` Baustein of the stored Yjs content still carries the flat `meta.transcript` that `migrateLegacyContent` turns into a `rendition` child. */
27
+ function hasFlatTranscript(fragment) {
28
+ return !fragment.createTreeWalker((node) => {
29
+ if (!(node instanceof Y.XmlElement) || node.nodeName !== "composite" || node.getAttribute("kind") !== "document") return false;
30
+ const meta = node.getAttribute("meta");
31
+ return typeof meta === "object" && meta !== null && "transcript" in meta && typeof meta.transcript === "string";
32
+ }).next().done;
33
+ }
26
34
  /** Hocuspocus answers a thrown error's `reason` as permission-denied. */
27
35
  const denied = (message, reason) => Object.assign(new Error(message), { reason });
36
+ /** The `collabState` port; the collaboration server cannot run without it. */
37
+ function collabStateOf(ports) {
38
+ if (!ports.collabState) throw new Error("@ecsplico/editor: collaboration needs the collabState port");
39
+ return ports.collabState;
40
+ }
28
41
  /**
29
42
  * The editor's collaboration server, independent of any web framework: Hocuspocus with the editor's hooks (seeding from
30
- * the adapter's JSON, versioned state, block-ID backfill, debounced `storeContent`/`storeState`) over `adapter`.
43
+ * the stored JSON, versioned state, block-ID backfill, debounced `storeContent`/`storeState`) over `options.ports`.
31
44
  * `/nuxt` mounts one in Nitro; any Node/Bun/Deno process can serve `handleConnection` on its own websocket transport.
32
45
  */
33
46
  function createCollabServer(options) {
34
- const { adapter } = options;
35
- const authorize = (user, id) => options.hooks?.authorize ? options.hooks.authorize(user, id) : adapter.authorize?.(user, id);
36
- const contentVersion = (id) => options.hooks?.contentVersion ? options.hooks.contentVersion(id) : adapter.contentVersion?.(id);
47
+ const { identity, documents } = options.ports;
48
+ const state = collabStateOf(options.ports);
49
+ const authorize = (user, id) => options.hooks?.authorize ? options.hooks.authorize(user, id) : identity.authorize?.(user, id);
50
+ const contentVersion = (id) => options.hooks?.contentVersion ? options.hooks.contentVersion(id) : documents.contentVersion?.(id);
37
51
  let schema;
38
- const collabSchema = () => schema ??= getSchema([...advancedSchemaExtensions(), ...(options.schemaExtensions ?? adapter.schemaExtensions?.bind(adapter))?.() ?? []]);
52
+ const collabSchema = () => schema ??= getSchema((options.schema ?? advancedSchemaExtensions)());
39
53
  /** Loaded documents deleted via `forgetDocument`; a store still pending for them must not write their Yjs state back. */
40
54
  const forgotten = /* @__PURE__ */ new Set();
41
- /** `contentVersion` the loaded document's content mirror had when it was last read or written; only tracked for adapters with `contentVersion`. */
55
+ /** `contentVersion` the loaded document's content mirror had when it was last read or written; only tracked for documents ports with `contentVersion`. */
42
56
  const loadedVersions = /* @__PURE__ */ new Map();
43
57
  /** Resolvers of `close()` waiting for the last document to unload. */
44
58
  const idle = [];
45
59
  let closed = false;
46
60
  /** Merges content rewritten behind the editor's back into the open document and stores its state against `version`. */
47
61
  async function mergeRewrite(id, document, version) {
48
- const rewritten = await adapter.loadContent(id);
62
+ const rewritten = await documents.loadContent(id);
49
63
  if (!rewritten) return;
50
64
  prosemirrorToYXmlFragment(contentNode(collabSchema(), rewritten), document.getXmlFragment(COLLAB_FIELD));
51
65
  loadedVersions.set(id, version);
52
- await adapter.storeState(id, encodeCollabState({
66
+ await state.storeState(id, encodeCollabState({
53
67
  version,
54
68
  update: Y.encodeStateAsUpdate(document)
55
69
  }));
56
70
  }
57
71
  /** Stored state of a document, `null` when there is none usable: it was written against another content version and is removed. */
58
72
  async function loadCurrentState(id, liveVersion) {
59
- const payload = await adapter.loadState(id);
73
+ const payload = await state.loadState(id);
60
74
  if (!payload) return null;
61
75
  const { version, update } = decodeCollabState(payload);
62
76
  if (isStateStale(version, liveVersion)) {
63
- await adapter.removeState(id);
77
+ await state.removeState(id);
64
78
  return null;
65
79
  }
66
80
  return update;
@@ -69,7 +83,7 @@ function createCollabServer(options) {
69
83
  ...options.configuration,
70
84
  async onAuthenticate({ context, token, requestHeaders, documentName, connectionConfig }) {
71
85
  let user = context.user;
72
- if (!user) user = await adapter.authenticate({
86
+ if (!user) user = await identity.authenticate({
73
87
  headers: requestHeaders,
74
88
  ...token && { token }
75
89
  });
@@ -88,7 +102,7 @@ function createCollabServer(options) {
88
102
  const version = await contentVersion(documentName);
89
103
  const stored = await loadCurrentState(documentName, version);
90
104
  if (version !== void 0) loadedVersions.set(documentName, version);
91
- const persist = (doc) => adapter.storeState(documentName, encodeCollabState({
105
+ const persist = (doc) => state.storeState(documentName, encodeCollabState({
92
106
  version: version ?? null,
93
107
  update: Y.encodeStateAsUpdate(doc)
94
108
  }));
@@ -97,7 +111,9 @@ function createCollabServer(options) {
97
111
  Y.applyUpdate(doc, stored);
98
112
  const fragment = doc.getXmlFragment(COLLAB_FIELD);
99
113
  if (!!fragment.createTreeWalker((node) => node instanceof Y.XmlElement && node.nodeName === "section").next().done) {
100
- const withIds = assignBlockIds(yXmlFragmentToProsemirror(currentSchema, fragment));
114
+ const current = yXmlFragmentToProsemirror(currentSchema, fragment);
115
+ const migrated = hasFlatTranscript(fragment) ? currentSchema.nodeFromJSON(migrateLegacyContent(current.toJSON())) : current;
116
+ const withIds = assignBlockIds(migrated) ?? (migrated === current ? null : migrated);
101
117
  if (withIds) {
102
118
  prosemirrorToYXmlFragment(withIds, fragment);
103
119
  await persist(doc);
@@ -105,7 +121,7 @@ function createCollabServer(options) {
105
121
  return doc;
106
122
  }
107
123
  }
108
- const loaded = await adapter.loadContent(documentName);
124
+ const loaded = await documents.loadContent(documentName);
109
125
  if (!loaded) throw new Error("Dokument nicht gefunden");
110
126
  const seeded = prosemirrorToYDoc(contentNode(currentSchema, loaded), COLLAB_FIELD);
111
127
  await persist(seeded);
@@ -119,10 +135,10 @@ function createCollabServer(options) {
119
135
  await mergeRewrite(documentName, document, current);
120
136
  return;
121
137
  }
122
- await adapter.storeContent(documentName, yDocToProsemirrorJSON(document, COLLAB_FIELD));
138
+ await documents.storeContent(documentName, yDocToProsemirrorJSON(document, COLLAB_FIELD));
123
139
  const version = await contentVersion(documentName);
124
140
  if (version !== void 0) loadedVersions.set(documentName, version);
125
- await adapter.storeState(documentName, encodeCollabState({
141
+ await state.storeState(documentName, encodeCollabState({
126
142
  version: version ?? null,
127
143
  update: Y.encodeStateAsUpdate(document)
128
144
  }));
@@ -151,7 +167,7 @@ function createCollabServer(options) {
151
167
  doc.broadcastStateless("deleted");
152
168
  hocuspocus.closeConnections(id);
153
169
  }
154
- await adapter.removeState(id);
170
+ await state.removeState(id);
155
171
  },
156
172
  liveContent(id) {
157
173
  const doc = hocuspocus.documents.get(id);