@ecsplico/editor 2.1.2 → 3.1.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 (706) hide show
  1. package/CHANGELOG.md +78 -1
  2. package/README.md +39 -156
  3. package/dist/adapters/comments/drizzle.d.ts +1 -1
  4. package/dist/adapters/comments/record.d.ts +15 -0
  5. package/dist/adapters/comments/{client.js → rest-model.js} +3 -3
  6. package/dist/adapters/comments/rest-model.js.map +1 -0
  7. package/dist/adapters/comments/server.d.ts +2 -1
  8. package/dist/adapters/comments/server.js +2 -1
  9. package/dist/adapters/comments/server.js.map +1 -1
  10. package/dist/adapters/comments/types.d.ts +2 -2
  11. package/dist/adapters/document-state.d.ts +23 -0
  12. package/dist/adapters/document-state.js +66 -0
  13. package/dist/adapters/document-state.js.map +1 -0
  14. package/dist/adapters/documents.js +14 -11
  15. package/dist/adapters/documents.js.map +1 -1
  16. package/dist/adapters/drizzle.d.ts +2 -2
  17. package/dist/adapters/drizzle.js +97 -88
  18. package/dist/adapters/drizzle.js.map +1 -1
  19. package/dist/adapters/forge.d.ts +12 -7
  20. package/dist/adapters/forge.js +38 -45
  21. package/dist/adapters/forge.js.map +1 -1
  22. package/dist/adapters/http.d.ts +20 -0
  23. package/dist/adapters/http.js +68 -0
  24. package/dist/adapters/http.js.map +1 -0
  25. package/dist/adapters/index.d.ts +5 -5
  26. package/dist/adapters/json.d.ts +3 -3
  27. package/dist/adapters/json.js +58 -49
  28. package/dist/adapters/json.js.map +1 -1
  29. package/dist/adapters/memory.d.ts +21 -0
  30. package/dist/adapters/memory.js +53 -0
  31. package/dist/adapters/memory.js.map +1 -0
  32. package/dist/adapters/nitro.d.ts +27 -20
  33. package/dist/adapters/nitro.js +59 -163
  34. package/dist/adapters/nitro.js.map +1 -1
  35. package/dist/adapters/react.d.ts +55 -0
  36. package/dist/adapters/react.js +209 -0
  37. package/dist/adapters/react.js.map +1 -0
  38. package/dist/adapters/shared.d.ts +15 -21
  39. package/dist/adapters/shared.js +10 -8
  40. package/dist/adapters/shared.js.map +1 -1
  41. package/dist/adapters/vue.d.ts +15 -30
  42. package/dist/adapters/vue.js +36 -87
  43. package/dist/adapters/vue.js.map +1 -1
  44. package/dist/code/CodeSurface.vue.d.ts +2 -2
  45. package/dist/config/index.d.ts +105 -0
  46. package/dist/config/index.js +95 -0
  47. package/dist/config/index.js.map +1 -0
  48. package/dist/core/abilities.js +1 -0
  49. package/dist/core/abilities.js.map +1 -1
  50. package/dist/{adapters/routes.js → core/api-routes.js} +5 -3
  51. package/dist/core/api-routes.js.map +1 -0
  52. package/dist/core/backend-capability.d.ts +7 -0
  53. package/dist/core/backend-capability.js +17 -0
  54. package/dist/core/backend-capability.js.map +1 -0
  55. package/dist/core/backend-types.d.ts +245 -0
  56. package/dist/core/backend-types.js +17 -0
  57. package/dist/core/backend-types.js.map +1 -0
  58. package/dist/core/backend.d.ts +108 -0
  59. package/dist/core/backend.js +14 -0
  60. package/dist/core/backend.js.map +1 -0
  61. package/dist/core/block-convert.d.ts +7 -5
  62. package/dist/core/block-convert.js +28 -5
  63. package/dist/core/block-convert.js.map +1 -1
  64. package/dist/core/command-types.d.ts +96 -0
  65. package/dist/core/commands.d.ts +40 -0
  66. package/dist/core/commands.js +151 -0
  67. package/dist/core/commands.js.map +1 -0
  68. package/dist/core/context.d.ts +17 -20
  69. package/dist/core/context.js +24 -21
  70. package/dist/core/context.js.map +1 -1
  71. package/dist/core/core-feature.d.ts +22 -7
  72. package/dist/core/core-feature.js +51 -18
  73. package/dist/core/core-feature.js.map +1 -1
  74. package/dist/core/define-editor.d.ts +4 -3
  75. package/dist/core/define-editor.js +14 -7
  76. package/dist/core/define-editor.js.map +1 -1
  77. package/dist/core/document-markdown.js +12 -3
  78. package/dist/core/document-markdown.js.map +1 -1
  79. package/dist/core/editor-ui.d.ts +8 -1
  80. package/dist/core/editor-ui.js +9 -8
  81. package/dist/core/editor-ui.js.map +1 -1
  82. package/dist/core/extension-points.d.ts +3 -15
  83. package/dist/core/feature-context.d.ts +8 -7
  84. package/dist/core/feature-context.js +12 -11
  85. package/dist/core/feature-context.js.map +1 -1
  86. package/dist/core/feature.d.ts +41 -19
  87. package/dist/core/feature.js.map +1 -1
  88. package/dist/core/fences.d.ts +2 -1
  89. package/dist/core/fences.js +3 -2
  90. package/dist/core/fences.js.map +1 -1
  91. package/dist/core/fetch-error.d.ts +1 -1
  92. package/dist/core/fetch-error.js +3 -1
  93. package/dist/core/fetch-error.js.map +1 -1
  94. package/dist/core/hash.d.ts +5 -0
  95. package/dist/core/hash.js +11 -0
  96. package/dist/core/hash.js.map +1 -0
  97. package/dist/core/http-backend.d.ts +11 -0
  98. package/dist/core/http-backend.js +195 -0
  99. package/dist/core/http-backend.js.map +1 -0
  100. package/dist/core/index.d.ts +15 -9
  101. package/dist/core/index.js +13 -9
  102. package/dist/core/palette.d.ts +48 -0
  103. package/dist/core/palette.js +95 -0
  104. package/dist/core/palette.js.map +1 -0
  105. package/dist/core/schema/abilities.d.ts +2 -1
  106. package/dist/core/schema/abilities.js +5 -1
  107. package/dist/core/schema/abilities.js.map +1 -1
  108. package/dist/core/schema/index.d.ts +11 -5
  109. package/dist/core/schema/index.js +13 -8
  110. package/dist/core/schema/index.js.map +1 -1
  111. package/dist/core/schema/mark-flags.d.ts +8 -1
  112. package/dist/core/schema/of-features.d.ts +13 -0
  113. package/dist/core/schema/of-features.js +14 -0
  114. package/dist/core/schema/of-features.js.map +1 -0
  115. package/dist/core/slash.d.ts +8 -6
  116. package/dist/core/slash.js +24 -16
  117. package/dist/core/slash.js.map +1 -1
  118. package/dist/core/surface-session.js +15 -5
  119. package/dist/core/surface-session.js.map +1 -1
  120. package/dist/core/toolbar-items.d.ts +10 -4
  121. package/dist/core/toolbar-items.js +269 -195
  122. package/dist/core/toolbar-items.js.map +1 -1
  123. package/dist/core/transaction-guards.d.ts +21 -0
  124. package/dist/core/transaction-guards.js +49 -0
  125. package/dist/core/transaction-guards.js.map +1 -0
  126. package/dist/core/util.js +11 -0
  127. package/dist/core/util.js.map +1 -0
  128. package/dist/document/DocumentSurface.d.ts +1 -1
  129. package/dist/document/DocumentSurface.vue.d.ts +2 -2
  130. package/dist/features/ai/agent-op-review.d.ts +1 -1
  131. package/dist/features/ai/agent-op-review.js +1 -1
  132. package/dist/features/ai/agent-ops.js +1 -1
  133. package/dist/features/ai/ai-apply.d.ts +2 -2
  134. package/dist/features/ai/ai-apply.js +1 -1
  135. package/dist/features/ai/ai-review.js +1 -1
  136. package/dist/features/ai/ai-sse.d.ts +6 -6
  137. package/dist/features/ai/ai-sse.js +20 -63
  138. package/dist/features/ai/ai-sse.js.map +1 -1
  139. package/dist/features/ai/assistant.d.ts +8 -7
  140. package/dist/features/ai/assistant.js +3 -3
  141. package/dist/features/ai/assistant.js.map +1 -1
  142. package/dist/features/ai/block-actions.d.ts +3 -2
  143. package/dist/features/ai/block-actions.js +3 -2
  144. package/dist/features/ai/block-actions.js.map +1 -1
  145. package/dist/features/ai/components/AiSelectionMenu.js +1 -1
  146. package/dist/features/ai/components/DocumentChatAnswer.js +1 -1
  147. package/dist/features/ai/components/DocumentChatOps.vue.d.ts +1 -1
  148. package/dist/features/ai/components/SettingsModelProfiles.js +8 -8
  149. package/dist/features/ai/components/SettingsModelProfiles.js.map +1 -1
  150. package/dist/features/ai/document-chat-model.d.ts +8 -7
  151. package/dist/features/ai/document-chat-model.js +5 -5
  152. package/dist/features/ai/document-chat-model.js.map +1 -1
  153. package/dist/features/ai/document-chat.js +1 -1
  154. package/dist/features/ai/feature.js +27 -14
  155. package/dist/features/ai/feature.js.map +1 -1
  156. package/dist/features/ai/ghost-autocomplete.d.ts +7 -6
  157. package/dist/features/ai/ghost-autocomplete.js +6 -9
  158. package/dist/features/ai/ghost-autocomplete.js.map +1 -1
  159. package/dist/features/ai/index.d.ts +4 -3
  160. package/dist/features/ai/index.js +10 -10
  161. package/dist/features/ai/model-profiles.d.ts +5 -4
  162. package/dist/features/ai/model-profiles.js +2 -2
  163. package/dist/features/ai/model-profiles.js.map +1 -1
  164. package/dist/features/ai/protocol/block-lines.js +1 -1
  165. package/dist/features/ai/protocol/block-lines.js.map +1 -1
  166. package/dist/features/ai/protocol/chat.js +6 -2
  167. package/dist/features/ai/protocol/chat.js.map +1 -1
  168. package/dist/features/ai/protocol/index.d.ts +3 -2
  169. package/dist/features/ai/protocol/models.d.ts +2 -16
  170. package/dist/features/ai/protocol/models.js.map +1 -1
  171. package/dist/features/ai/rate-limit.d.ts +1 -1
  172. package/dist/features/ai/rate-limit.js +3 -1
  173. package/dist/features/ai/rate-limit.js.map +1 -1
  174. package/dist/features/ai/react/AiSelectionMenu.js +2 -2
  175. package/dist/features/ai/react/AiSidebar.js +4 -4
  176. package/dist/features/ai/react/DocumentChatAnswer.js +1 -1
  177. package/dist/features/ai/react/DocumentChatOps.d.ts +1 -1
  178. package/dist/features/ai/react/DocumentChatOps.js +1 -1
  179. package/dist/features/ai/react/SettingsModelProfiles.js +8 -10
  180. package/dist/features/ai/react/SettingsModelProfiles.js.map +1 -1
  181. package/dist/features/ai/react/use-ai-assistant.d.ts +1 -1
  182. package/dist/features/ai/react/use-ai-assistant.js +3 -3
  183. package/dist/features/ai/react/use-ai-assistant.js.map +1 -1
  184. package/dist/features/ai/react/use-document-chat.js +2 -2
  185. package/dist/features/ai/react/use-document-chat.js.map +1 -1
  186. package/dist/features/ai/react/use-model-profiles.d.ts +2 -1
  187. package/dist/features/ai/selection-flow.d.ts +1 -1
  188. package/dist/features/ai/selection-flow.js +1 -1
  189. package/dist/features/ai/sidebar-flow.d.ts +1 -1
  190. package/dist/features/ai/sidebar-flow.js +1 -1
  191. package/dist/features/ai/use-ai-assistant.d.ts +1 -1
  192. package/dist/features/ai/use-ai-assistant.js +3 -3
  193. package/dist/features/ai/use-ai-assistant.js.map +1 -1
  194. package/dist/features/ai/use-document-chat.js +2 -2
  195. package/dist/features/ai/use-document-chat.js.map +1 -1
  196. package/dist/features/ai/use-model-profiles.d.ts +2 -1
  197. package/dist/features/authors/attribution.d.ts +1 -1
  198. package/dist/features/authors/feature.js +12 -11
  199. package/dist/features/authors/feature.js.map +1 -1
  200. package/dist/features/block-ui/block-actions.d.ts +1 -1
  201. package/dist/features/block-ui/block-actions.js +1 -1
  202. package/dist/features/block-ui/block-actions.js.map +1 -1
  203. package/dist/features/block-ui/components/BlockUi.js +1 -1
  204. package/dist/features/block-ui/feature.js +1 -0
  205. package/dist/features/block-ui/feature.js.map +1 -1
  206. package/dist/features/block-ui/react/BlockUi.js +1 -1
  207. package/dist/features/collab/anchor-resolver.js +1 -1
  208. package/dist/features/collab/feature.js +2 -0
  209. package/dist/features/collab/feature.js.map +1 -1
  210. package/dist/features/comments/components/CommentThreadView.vue.d.ts +2 -1
  211. package/dist/features/comments/feature.js +12 -11
  212. package/dist/features/comments/feature.js.map +1 -1
  213. package/dist/features/comments/index.d.ts +3 -2
  214. package/dist/features/comments/index.js +1 -1
  215. package/dist/features/comments/margin-layout.d.ts +3 -2
  216. package/dist/features/comments/model.d.ts +3 -67
  217. package/dist/features/comments/model.js +2 -2
  218. package/dist/features/comments/model.js.map +1 -1
  219. package/dist/features/comments/react/CommentThreadView.d.ts +3 -2
  220. package/dist/features/comments/react/use-comments.d.ts +2 -1
  221. package/dist/features/comments/react.d.ts +1 -1
  222. package/dist/features/comments/schema.d.ts +2 -52
  223. package/dist/features/comments/schema.js.map +1 -1
  224. package/dist/features/comments/snapshot-equality.js.map +1 -1
  225. package/dist/features/comments/use-comments.d.ts +3 -2
  226. package/dist/features/comments/vue.d.ts +1 -1
  227. package/dist/features/composites/accepted-children.d.ts +1 -0
  228. package/dist/features/composites/accepted-children.js +16 -1
  229. package/dist/features/composites/accepted-children.js.map +1 -1
  230. package/dist/features/composites/ai-brief.js +39 -0
  231. package/dist/features/composites/ai-brief.js.map +1 -1
  232. package/dist/features/composites/bibliography-command.d.ts +11 -0
  233. package/dist/features/composites/bibliography-form.js +90 -0
  234. package/dist/features/composites/bibliography-form.js.map +1 -0
  235. package/dist/features/composites/bibliography.d.ts +33 -0
  236. package/dist/features/composites/bibliography.js +120 -0
  237. package/dist/features/composites/bibliography.js.map +1 -0
  238. package/dist/features/composites/components/BibliographyEditor.js +261 -0
  239. package/dist/features/composites/components/BibliographyEditor.js.map +1 -0
  240. package/dist/features/composites/components/CompositeChrome.js +78 -29
  241. package/dist/features/composites/components/CompositeChrome.js.map +1 -1
  242. package/dist/features/composites/components/CompositeChrome.vue.d.ts +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 +64 -5
  247. package/dist/features/composites/components/CompositeFieldEditor.js.map +1 -1
  248. package/dist/features/composites/components/CompositeInspector.js +20 -7
  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 +16 -2
  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 +45 -2
  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 +67 -19
  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 +43 -1
  306. package/dist/features/composites/react/CompositeFieldEditor.js.map +1 -1
  307. package/dist/features/composites/react/CompositeInspector.js +12 -6
  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 +25 -3
  345. package/dist/features/composites/rows.js +72 -10
  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 +3 -3
  367. package/dist/features/media/react/AudioRecorderModal.js +1 -1
  368. package/dist/features/media/react/FileView.js +19 -2
  369. package/dist/features/media/react/FileView.js.map +1 -1
  370. package/dist/features/media/react.js +1 -1
  371. package/dist/features/media/schema.d.ts +8 -0
  372. package/dist/features/media/schema.js +126 -11
  373. package/dist/features/media/schema.js.map +1 -1
  374. package/dist/features/media/upload.d.ts +16 -14
  375. package/dist/features/media/upload.js +13 -19
  376. package/dist/features/media/upload.js.map +1 -1
  377. package/dist/features/mentions/index.d.ts +4 -3
  378. package/dist/features/mentions/index.js +4 -1
  379. package/dist/features/mentions/index.js.map +1 -1
  380. package/dist/features/mentions/mention-text.d.ts +1 -1
  381. package/dist/features/mentions/mention-text.js.map +1 -1
  382. package/dist/features/mentions/mention.d.ts +0 -6
  383. package/dist/features/mentions/mention.js.map +1 -1
  384. package/dist/features/mentions/metadata-defaults.d.ts +2 -2
  385. package/dist/features/mentions/metadata-defaults.js +3 -9
  386. package/dist/features/mentions/metadata-defaults.js.map +1 -1
  387. package/dist/features/mentions/schema.d.ts +2 -1
  388. package/dist/features/mentions/schema.js.map +1 -1
  389. package/dist/features/tables/feature.d.ts +2 -1
  390. package/dist/features/tables/feature.js +90 -70
  391. package/dist/features/tables/feature.js.map +1 -1
  392. package/dist/features/themes/components/SettingsAppearanceTab.js +6 -9
  393. package/dist/features/themes/components/SettingsAppearanceTab.js.map +1 -1
  394. package/dist/features/themes/feature.js +2 -0
  395. package/dist/features/themes/feature.js.map +1 -1
  396. package/dist/features/themes/index.d.ts +2 -1
  397. package/dist/features/themes/react/SettingsAppearanceTab.js +7 -10
  398. package/dist/features/themes/react/SettingsAppearanceTab.js.map +1 -1
  399. package/dist/features/themes/schema.d.ts +2 -6
  400. package/dist/features/themes/schema.js.map +1 -1
  401. package/dist/features/themes/theme-runtime.d.ts +1 -1
  402. package/dist/features/themes/theme-runtime.js +4 -2
  403. package/dist/features/themes/theme-runtime.js.map +1 -1
  404. package/dist/features/transcript/TranscriptSegmentView.js +48 -28
  405. package/dist/features/transcript/TranscriptSegmentView.js.map +1 -1
  406. package/dist/features/transcript/feature.js +21 -19
  407. package/dist/features/transcript/feature.js.map +1 -1
  408. package/dist/features/transcript/react/TranscriptSegmentView.js +55 -36
  409. package/dist/features/transcript/react/TranscriptSegmentView.js.map +1 -1
  410. package/dist/features/transcript/segment-node.d.ts +2 -0
  411. package/dist/features/transcript/segment-node.js +35 -7
  412. package/dist/features/transcript/segment-node.js.map +1 -1
  413. package/dist/i18n/de/composites.js +91 -1
  414. package/dist/i18n/de/composites.js.map +1 -1
  415. package/dist/i18n/de/integrations.js +49 -8
  416. package/dist/i18n/de/integrations.js.map +1 -1
  417. package/dist/i18n/de/media.js +0 -1
  418. package/dist/i18n/de/media.js.map +1 -1
  419. package/dist/i18n/de/palette.js +22 -0
  420. package/dist/i18n/de/palette.js.map +1 -0
  421. package/dist/i18n/de/tables.js +0 -1
  422. package/dist/i18n/de/tables.js.map +1 -1
  423. package/dist/i18n/de/transcript.js +2 -1
  424. package/dist/i18n/de/transcript.js.map +1 -1
  425. package/dist/i18n/de/tree.js +3 -0
  426. package/dist/i18n/de/tree.js.map +1 -1
  427. package/dist/i18n/de.d.ts +157 -11
  428. package/dist/i18n/de.js +3 -1
  429. package/dist/i18n/de.js.map +1 -1
  430. package/dist/i18n/en/composites.js +89 -1
  431. package/dist/i18n/en/composites.js.map +1 -1
  432. package/dist/i18n/en/integrations.js +49 -8
  433. package/dist/i18n/en/integrations.js.map +1 -1
  434. package/dist/i18n/en/media.js +0 -1
  435. package/dist/i18n/en/media.js.map +1 -1
  436. package/dist/i18n/en/palette.js +22 -0
  437. package/dist/i18n/en/palette.js.map +1 -0
  438. package/dist/i18n/en/tables.js +0 -1
  439. package/dist/i18n/en/tables.js.map +1 -1
  440. package/dist/i18n/en/transcript.js +2 -1
  441. package/dist/i18n/en/transcript.js.map +1 -1
  442. package/dist/i18n/en/tree.js +3 -0
  443. package/dist/i18n/en/tree.js.map +1 -1
  444. package/dist/i18n/en.js +3 -1
  445. package/dist/i18n/en.js.map +1 -1
  446. package/dist/index.d.ts +4 -3
  447. package/dist/integrations/composite-ai/bibliography-fetch.d.ts +31 -0
  448. package/dist/integrations/composite-ai/bibliography-fetch.js +159 -0
  449. package/dist/integrations/composite-ai/bibliography-fetch.js.map +1 -0
  450. package/dist/integrations/composite-ai/composite-fill.d.ts +30 -8
  451. package/dist/integrations/composite-ai/composite-fill.js +97 -56
  452. package/dist/integrations/composite-ai/composite-fill.js.map +1 -1
  453. package/dist/integrations/composite-ai/composite-summary.d.ts +4 -12
  454. package/dist/integrations/composite-ai/composite-summary.js +7 -26
  455. package/dist/integrations/composite-ai/composite-summary.js.map +1 -1
  456. package/dist/integrations/composite-ai/derive.d.ts +29 -0
  457. package/dist/integrations/composite-ai/derive.js +173 -0
  458. package/dist/integrations/composite-ai/derive.js.map +1 -0
  459. package/dist/integrations/composite-ai/index.d.ts +11 -7
  460. package/dist/integrations/composite-ai/index.js +72 -14
  461. package/dist/integrations/composite-ai/index.js.map +1 -1
  462. package/dist/integrations/composite-ai/rendition.d.ts +45 -0
  463. package/dist/integrations/composite-ai/rendition.js +314 -0
  464. package/dist/integrations/composite-ai/rendition.js.map +1 -0
  465. package/dist/integrations/composite-media/index.d.ts +7 -5
  466. package/dist/integrations/composite-media/index.js +86 -13
  467. package/dist/integrations/composite-media/index.js.map +1 -1
  468. package/dist/integrations/transcript-ai/index.d.ts +1 -1
  469. package/dist/integrations/transcript-ai/index.js +5 -2
  470. package/dist/integrations/transcript-ai/index.js.map +1 -1
  471. package/dist/integrations/transcript-ai/protocol.d.ts +2 -12
  472. package/dist/integrations/transcript-ai/protocol.js +0 -2
  473. package/dist/integrations/transcript-ai/protocol.js.map +1 -1
  474. package/dist/integrations/transcript-ai/transcript-cleanup.d.ts +5 -5
  475. package/dist/integrations/transcript-ai/transcript-cleanup.js +7 -10
  476. package/dist/integrations/transcript-ai/transcript-cleanup.js.map +1 -1
  477. package/dist/markdown/MarkdownSurface.vue.d.ts +12 -11
  478. package/dist/markdown/MarkdownSurface2.js +3 -6
  479. package/dist/markdown/MarkdownSurface2.js.map +1 -1
  480. package/dist/markdown/document.js +1 -1
  481. package/dist/markdown/source-mode.d.ts +1 -1
  482. package/dist/nuxt/module.d.ts +1402 -54
  483. package/dist/nuxt/module.js +6 -49
  484. package/dist/nuxt/module.js.map +1 -1
  485. package/dist/nuxt/runtime/install-context.d.ts +7 -3
  486. package/dist/nuxt/runtime/install-context.js +14 -8
  487. package/dist/nuxt/runtime/install-context.js.map +1 -1
  488. package/dist/nuxt/runtime/plugins/editor-context-nuxt-ui.client.ts +2 -2
  489. package/dist/nuxt/runtime/server/plugins/editor-server.js +20 -12
  490. package/dist/nuxt/runtime/server/plugins/editor-server.js.map +1 -1
  491. package/dist/presets/compose.d.ts +94 -0
  492. package/dist/presets/compose.js +164 -0
  493. package/dist/presets/compose.js.map +1 -0
  494. package/dist/react/AdvancedEditor.d.ts +15 -15
  495. package/dist/react/AdvancedEditor.js +15 -13
  496. package/dist/react/AdvancedEditor.js.map +1 -1
  497. package/dist/react/EditorCommandPalette.d.ts +13 -0
  498. package/dist/react/EditorCommandPalette.js +118 -0
  499. package/dist/react/EditorCommandPalette.js.map +1 -0
  500. package/dist/react/EditorSettingsModal.d.ts +5 -5
  501. package/dist/react/EditorSettingsModal.js +7 -4
  502. package/dist/react/EditorSettingsModal.js.map +1 -1
  503. package/dist/react/EditorSettingsPanel.d.ts +7 -7
  504. package/dist/react/EditorSettingsPanel.js +8 -5
  505. package/dist/react/EditorSettingsPanel.js.map +1 -1
  506. package/dist/react/EditorSurface.d.ts +7 -7
  507. package/dist/react/EditorSurface.js +10 -6
  508. package/dist/react/EditorSurface.js.map +1 -1
  509. package/dist/react/EditorToolbar.d.ts +4 -6
  510. package/dist/react/EditorToolbar.js +29 -37
  511. package/dist/react/EditorToolbar.js.map +1 -1
  512. package/dist/react/SimpleEditor.d.ts +22 -23
  513. package/dist/react/SimpleEditor.js +21 -7
  514. package/dist/react/SimpleEditor.js.map +1 -1
  515. package/dist/react/advanced.d.ts +4 -3
  516. package/dist/react/advanced.js +2 -2
  517. package/dist/react/compose.d.ts +20 -0
  518. package/dist/react/compose.js +49 -0
  519. package/dist/react/compose.js.map +1 -0
  520. package/dist/react/composed-surface.d.ts +39 -0
  521. package/dist/react/composed-surface.js +71 -0
  522. package/dist/react/composed-surface.js.map +1 -0
  523. package/dist/react/context.js +6 -2
  524. package/dist/react/context.js.map +1 -1
  525. package/dist/react/index.d.ts +2 -1
  526. package/dist/react/index.js +2 -1
  527. package/dist/react/key-labels.js +15 -0
  528. package/dist/react/key-labels.js.map +1 -0
  529. package/dist/react/settings.d.ts +1 -1
  530. package/dist/react/simple.d.ts +2 -2
  531. package/dist/react/ui/command.js +36 -1
  532. package/dist/react/ui/command.js.map +1 -1
  533. package/dist/schema/advanced.d.ts +6 -6
  534. package/dist/schema/advanced.js +26 -29
  535. package/dist/schema/advanced.js.map +1 -1
  536. package/dist/server/ai.d.ts +5 -16
  537. package/dist/server/ai.js.map +1 -1
  538. package/dist/server/auth.d.ts +9 -0
  539. package/dist/server/collab-state.d.ts +1 -1
  540. package/dist/server/collab-state.js.map +1 -1
  541. package/dist/server/collab.d.ts +13 -13
  542. package/dist/server/collab.js +34 -18
  543. package/dist/server/collab.js.map +1 -1
  544. package/dist/server/crossref.js +78 -0
  545. package/dist/server/crossref.js.map +1 -0
  546. package/dist/server/errors.d.ts +1 -1
  547. package/dist/server/errors.js +1 -1
  548. package/dist/server/errors.js.map +1 -1
  549. package/dist/server/extract.js +308 -0
  550. package/dist/server/extract.js.map +1 -0
  551. package/dist/server/h3.d.ts +8 -0
  552. package/dist/{nuxt/runtime/server/utils/editor-route.js → server/h3.js} +8 -16
  553. package/dist/server/h3.js.map +1 -0
  554. package/dist/server/handlers/ai.d.ts +32 -10
  555. package/dist/server/handlers/ai.js +172 -37
  556. package/dist/server/handlers/ai.js.map +1 -1
  557. package/dist/server/handlers/context.d.ts +12 -5
  558. package/dist/server/handlers/context.js +10 -4
  559. package/dist/server/handlers/context.js.map +1 -1
  560. package/dist/server/handlers/editor.d.ts +19 -13
  561. package/dist/server/handlers/editor.js +49 -38
  562. package/dist/server/handlers/editor.js.map +1 -1
  563. package/dist/server/handlers/index.d.ts +4 -4
  564. package/dist/server/handlers/index.js +4 -4
  565. package/dist/server/host.d.ts +16 -25
  566. package/dist/server/host.js +58 -41
  567. package/dist/server/host.js.map +1 -1
  568. package/dist/server/index.d.ts +6 -4
  569. package/dist/server/index.js +3 -2
  570. package/dist/server/pdf.js +97 -0
  571. package/dist/server/pdf.js.map +1 -0
  572. package/dist/server/{adapter.d.ts → ports.d.ts} +81 -30
  573. package/dist/server/ports.js +29 -0
  574. package/dist/server/ports.js.map +1 -0
  575. package/dist/server/routes.d.ts +22 -0
  576. package/dist/server/routes.js +144 -0
  577. package/dist/server/routes.js.map +1 -0
  578. package/dist/settings/index.d.ts +1 -1
  579. package/dist/settings/index.js.map +1 -1
  580. package/dist/styles/composites.css +25 -0
  581. package/dist/tree/DocumentTree.js +56 -29
  582. package/dist/tree/DocumentTree.js.map +1 -1
  583. package/dist/tree/react/DocumentTree.js +23 -0
  584. package/dist/tree/react/DocumentTree.js.map +1 -1
  585. package/dist/tree/tree-host.js +2 -2
  586. package/dist/tree/tree-items.js +1 -1
  587. package/dist/vue/AdvancedEditor.js +30 -9
  588. package/dist/vue/AdvancedEditor.js.map +1 -1
  589. package/dist/vue/AdvancedEditor.vue.d.ts +32 -12
  590. package/dist/vue/SimpleEditor.js +62 -16
  591. package/dist/vue/SimpleEditor.js.map +1 -1
  592. package/dist/vue/SimpleEditor.vue.d.ts +39 -9
  593. package/dist/vue/advanced.d.ts +3 -2
  594. package/dist/vue/advanced.js +2 -2
  595. package/dist/vue/components/EditorCommandPalette.js +91 -0
  596. package/dist/vue/components/EditorCommandPalette.js.map +1 -0
  597. package/dist/vue/components/EditorCommandPalette.vue.d.ts +15 -0
  598. package/dist/vue/components/EditorSettingsModal.js +10 -6
  599. package/dist/vue/components/EditorSettingsModal.js.map +1 -1
  600. package/dist/vue/components/EditorSettingsModal.vue.d.ts +4 -4
  601. package/dist/vue/components/EditorSettingsPanel.js +10 -6
  602. package/dist/vue/components/EditorSettingsPanel.js.map +1 -1
  603. package/dist/vue/components/EditorSettingsPanel.vue.d.ts +6 -6
  604. package/dist/vue/components/EditorSurface.js +11 -6
  605. package/dist/vue/components/EditorSurface.js.map +1 -1
  606. package/dist/vue/components/EditorSurface.vue.d.ts +11 -11
  607. package/dist/vue/components/EditorToolbar.js +41 -49
  608. package/dist/vue/components/EditorToolbar.js.map +1 -1
  609. package/dist/vue/components/EditorToolbar.vue.d.ts +2 -4
  610. package/dist/vue/compose.d.ts +17 -0
  611. package/dist/vue/compose.js +51 -0
  612. package/dist/vue/compose.js.map +1 -0
  613. package/dist/vue/context-key.d.ts +6 -0
  614. package/dist/vue/context-key.js +6 -0
  615. package/dist/vue/context-key.js.map +1 -0
  616. package/dist/vue/context.d.ts +8 -6
  617. package/dist/vue/context.js +6 -5
  618. package/dist/vue/context.js.map +1 -1
  619. package/dist/vue/index.d.ts +10 -8
  620. package/dist/vue/index.js +10 -8
  621. package/dist/vue/kit/index.d.ts +2 -2
  622. package/dist/vue/kit/nuxt-ui.js +23 -0
  623. package/dist/vue/kit/nuxt-ui.js.map +1 -1
  624. package/dist/vue/kit/types.d.ts +40 -1
  625. package/package.json +30 -16
  626. package/dist/adapters/comments/client.d.ts +0 -64
  627. package/dist/adapters/comments/client.js.map +0 -1
  628. package/dist/adapters/routes.js.map +0 -1
  629. package/dist/core/toolbar.d.ts +0 -74
  630. package/dist/core/toolbar.js +0 -45
  631. package/dist/core/toolbar.js.map +0 -1
  632. package/dist/integrations/composite-ai/document-transcribe.d.ts +0 -14
  633. package/dist/integrations/composite-ai/document-transcribe.js +0 -89
  634. package/dist/integrations/composite-ai/document-transcribe.js.map +0 -1
  635. package/dist/nuxt/runtime/server/api/ai/chat.post.d.ts +0 -5
  636. package/dist/nuxt/runtime/server/api/ai/chat.post.js +0 -8
  637. package/dist/nuxt/runtime/server/api/ai/chat.post.js.map +0 -1
  638. package/dist/nuxt/runtime/server/api/ai/complete.post.d.ts +0 -5
  639. package/dist/nuxt/runtime/server/api/ai/complete.post.js +0 -8
  640. package/dist/nuxt/runtime/server/api/ai/complete.post.js.map +0 -1
  641. package/dist/nuxt/runtime/server/api/ai/generate.post.d.ts +0 -5
  642. package/dist/nuxt/runtime/server/api/ai/generate.post.js +0 -8
  643. package/dist/nuxt/runtime/server/api/ai/generate.post.js.map +0 -1
  644. package/dist/nuxt/runtime/server/api/ai/models.get.d.ts +0 -5
  645. package/dist/nuxt/runtime/server/api/ai/models.get.js +0 -8
  646. package/dist/nuxt/runtime/server/api/ai/models.get.js.map +0 -1
  647. package/dist/nuxt/runtime/server/api/ai/transcribe.post.d.ts +0 -5
  648. package/dist/nuxt/runtime/server/api/ai/transcribe.post.js +0 -8
  649. package/dist/nuxt/runtime/server/api/ai/transcribe.post.js.map +0 -1
  650. package/dist/nuxt/runtime/server/api/ai/transcript-cleanup.post.d.ts +0 -5
  651. package/dist/nuxt/runtime/server/api/ai/transcript-cleanup.post.js +0 -8
  652. package/dist/nuxt/runtime/server/api/ai/transcript-cleanup.post.js.map +0 -1
  653. package/dist/nuxt/runtime/server/api/editor/assets/[id]/[name].get.d.ts +0 -5
  654. package/dist/nuxt/runtime/server/api/editor/assets/[id]/[name].get.js +0 -8
  655. package/dist/nuxt/runtime/server/api/editor/assets/[id]/[name].get.js.map +0 -1
  656. package/dist/nuxt/runtime/server/api/editor/assets/[id].post.d.ts +0 -5
  657. package/dist/nuxt/runtime/server/api/editor/assets/[id].post.js +0 -8
  658. package/dist/nuxt/runtime/server/api/editor/assets/[id].post.js.map +0 -1
  659. package/dist/nuxt/runtime/server/api/editor/settings.get.d.ts +0 -5
  660. package/dist/nuxt/runtime/server/api/editor/settings.get.js +0 -8
  661. package/dist/nuxt/runtime/server/api/editor/settings.get.js.map +0 -1
  662. package/dist/nuxt/runtime/server/api/editor/settings.put.d.ts +0 -5
  663. package/dist/nuxt/runtime/server/api/editor/settings.put.js +0 -8
  664. package/dist/nuxt/runtime/server/api/editor/settings.put.js.map +0 -1
  665. package/dist/nuxt/runtime/server/api/editor/tags.get.d.ts +0 -5
  666. package/dist/nuxt/runtime/server/api/editor/tags.get.js +0 -8
  667. package/dist/nuxt/runtime/server/api/editor/tags.get.js.map +0 -1
  668. package/dist/nuxt/runtime/server/api/editor/themes/[id].delete.d.ts +0 -5
  669. package/dist/nuxt/runtime/server/api/editor/themes/[id].delete.js +0 -8
  670. package/dist/nuxt/runtime/server/api/editor/themes/[id].delete.js.map +0 -1
  671. package/dist/nuxt/runtime/server/api/editor/themes/[id].get.d.ts +0 -5
  672. package/dist/nuxt/runtime/server/api/editor/themes/[id].get.js +0 -8
  673. package/dist/nuxt/runtime/server/api/editor/themes/[id].get.js.map +0 -1
  674. package/dist/nuxt/runtime/server/api/editor/themes/index.get.d.ts +0 -5
  675. package/dist/nuxt/runtime/server/api/editor/themes/index.get.js +0 -8
  676. package/dist/nuxt/runtime/server/api/editor/themes/index.get.js.map +0 -1
  677. package/dist/nuxt/runtime/server/api/editor/themes/index.post.d.ts +0 -5
  678. package/dist/nuxt/runtime/server/api/editor/themes/index.post.js +0 -8
  679. package/dist/nuxt/runtime/server/api/editor/themes/index.post.js.map +0 -1
  680. package/dist/nuxt/runtime/server/api/editor/users.get.d.ts +0 -5
  681. package/dist/nuxt/runtime/server/api/editor/users.get.js +0 -8
  682. package/dist/nuxt/runtime/server/api/editor/users.get.js.map +0 -1
  683. package/dist/nuxt/runtime/server/plugins/collab.d.ts +0 -5
  684. package/dist/nuxt/runtime/server/plugins/collab.js +0 -10
  685. package/dist/nuxt/runtime/server/plugins/collab.js.map +0 -1
  686. package/dist/nuxt/runtime/server/routes/collab/[id].d.ts +0 -5
  687. package/dist/nuxt/runtime/server/routes/collab/[id].js +0 -35
  688. package/dist/nuxt/runtime/server/routes/collab/[id].js.map +0 -1
  689. package/dist/nuxt/runtime/server/utils/editor-route.d.ts +0 -11
  690. package/dist/nuxt/runtime/server/utils/editor-route.js.map +0 -1
  691. package/dist/presets/advanced.d.ts +0 -33
  692. package/dist/presets/advanced.js +0 -50
  693. package/dist/presets/advanced.js.map +0 -1
  694. package/dist/presets/simple.d.ts +0 -9
  695. package/dist/presets/simple.js +0 -12
  696. package/dist/presets/simple.js.map +0 -1
  697. package/dist/react/advanced-preset.d.ts +0 -11
  698. package/dist/react/advanced-preset.js +0 -31
  699. package/dist/react/advanced-preset.js.map +0 -1
  700. package/dist/vue/advanced-preset.d.ts +0 -13
  701. package/dist/vue/advanced-preset.js +0 -33
  702. package/dist/vue/advanced-preset.js.map +0 -1
  703. package/docs/extending.md +0 -538
  704. package/docs/integration.md +0 -632
  705. package/docs/llms.md +0 -383
  706. package/docs/usage.md +0 -1076
@@ -0,0 +1,89 @@
1
+ import { blockIdOf } from "../../core/schema/block-ids.js";
2
+ import { REFERENCE_TOKEN_SOURCE } from "./reference.js";
3
+ //#region src/features/composites/reference-text.ts
4
+ /** `[@<block id>]` or `[@<block id>, <locator>]`; a `]` inside the locator is written `\]`. */
5
+ const TOKEN = new RegExp(REFERENCE_TOKEN_SOURCE, "g");
6
+ /** Block IDs of every composite in a TipTap JSON tree, added to `into`. */
7
+ function collectCompositeIds(content, into) {
8
+ if (!content) return into;
9
+ if (content.type === "composite" && typeof content.attrs?.id === "string" && content.attrs.id) into.add(content.attrs.id);
10
+ for (const child of content.content ?? []) collectCompositeIds(child, into);
11
+ return into;
12
+ }
13
+ /**
14
+ * Turns `[@<id>]` / `[@<id>, <locator>]` tokens in text nodes into `reference` nodes (attrs target, locator, empty
15
+ * `label`: the node view resolves the live label) — for imported and AI-generated Markdown, whose parser keeps the
16
+ * token as text. Only ids in `ids` (the Bausteine of the document) match; unknown ids and text in code blocks, inline
17
+ * code or links stay plain. Returns the input unchanged when nothing matched.
18
+ */
19
+ function referencesFromText(json, ids) {
20
+ if (!ids.size) return json;
21
+ const splitText = (node) => {
22
+ const text = node.text ?? "";
23
+ if (!text.includes("[@") || node.marks?.some((m) => m.type === "code" || m.type === "link")) return [node];
24
+ const out = [];
25
+ let last = 0;
26
+ for (const match of text.matchAll(TOKEN)) {
27
+ const target = match[1];
28
+ if (!ids.has(target)) continue;
29
+ const at = match.index ?? 0;
30
+ if (at > last) out.push({
31
+ ...node,
32
+ text: text.slice(last, at)
33
+ });
34
+ out.push({
35
+ type: "reference",
36
+ attrs: {
37
+ target,
38
+ documentId: null,
39
+ locator: match[2]?.replace(/\\\]/g, "]").trim() || null,
40
+ label: ""
41
+ },
42
+ ...node.marks?.length ? { marks: node.marks } : {}
43
+ });
44
+ last = at + match[0].length;
45
+ }
46
+ if (!out.length) return [node];
47
+ if (last < text.length) out.push({
48
+ ...node,
49
+ text: text.slice(last)
50
+ });
51
+ return out;
52
+ };
53
+ const walk = (node) => {
54
+ if (!node.content || node.type === "codeBlock") return node;
55
+ let changed = false;
56
+ const content = node.content.flatMap((child) => {
57
+ const next = child.type === "text" ? splitText(child) : [walk(child)];
58
+ if (next.length !== 1 || next[0] !== child) changed = true;
59
+ return next;
60
+ });
61
+ return changed ? {
62
+ ...node,
63
+ content
64
+ } : node;
65
+ };
66
+ return walk(json);
67
+ }
68
+ /** Block IDs of the composites of `doc`: the Bausteine a `[@id]` text may point at. */
69
+ function compositeIdsOf(doc) {
70
+ const ids = /* @__PURE__ */ new Set();
71
+ doc.descendants((node) => {
72
+ if (node.type.name !== "composite") return;
73
+ const id = blockIdOf(node);
74
+ if (id) ids.add(id);
75
+ });
76
+ return ids;
77
+ }
78
+ /** The `normalize` stage: the composites of the document (`current`) and of `blocks` themselves may be referenced by text. */
79
+ function normalizeReferences(blocks, current) {
80
+ const doc = {
81
+ type: "doc",
82
+ content: blocks
83
+ };
84
+ return referencesFromText(doc, collectCompositeIds(doc, new Set(current))).content ?? [];
85
+ }
86
+ //#endregion
87
+ export { collectCompositeIds, compositeIdsOf, normalizeReferences, referencesFromText };
88
+
89
+ //# sourceMappingURL=reference-text.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reference-text.js","names":[],"sources":["../../../src/features/composites/reference-text.ts"],"sourcesContent":["import type { JSONContent } from '@tiptap/core'\nimport type { Node as PMNode } from '@tiptap/pm/model'\nimport { blockIdOf } from '../../core/schema'\nimport { REFERENCE_TOKEN_SOURCE } from './reference'\n\n/** `[@<block id>]` or `[@<block id>, <locator>]`; a `]` inside the locator is written `\\]`. */\nconst TOKEN = new RegExp(REFERENCE_TOKEN_SOURCE, 'g')\n\n/** Block IDs of every composite in a TipTap JSON tree, added to `into`. */\nexport function collectCompositeIds(content: JSONContent | null | undefined, into: Set<string>): Set<string> {\n if (!content) return into\n if (content.type === 'composite' && typeof content.attrs?.id === 'string' && content.attrs.id) into.add(content.attrs.id)\n for (const child of content.content ?? []) collectCompositeIds(child, into)\n return into\n}\n\n/**\n * Turns `[@<id>]` / `[@<id>, <locator>]` tokens in text nodes into `reference` nodes (attrs target, locator, empty\n * `label`: the node view resolves the live label) — for imported and AI-generated Markdown, whose parser keeps the\n * token as text. Only ids in `ids` (the Bausteine of the document) match; unknown ids and text in code blocks, inline\n * code or links stay plain. Returns the input unchanged when nothing matched.\n */\nexport function referencesFromText(json: JSONContent, ids: ReadonlySet<string>): JSONContent {\n if (!ids.size) return json\n\n const splitText = (node: JSONContent): JSONContent[] => {\n const text = node.text ?? ''\n if (!text.includes('[@') || node.marks?.some(m => m.type === 'code' || m.type === 'link')) return [node]\n const out: JSONContent[] = []\n let last = 0\n for (const match of text.matchAll(TOKEN)) {\n const target = match[1]!\n if (!ids.has(target)) continue\n const at = match.index ?? 0\n if (at > last) out.push({ ...node, text: text.slice(last, at) })\n out.push({\n type: 'reference',\n attrs: { target, documentId: null, locator: match[2]?.replace(/\\\\\\]/g, ']').trim() || null, label: '' },\n ...(node.marks?.length ? { marks: node.marks } : {}),\n })\n last = at + match[0].length\n }\n if (!out.length) return [node]\n if (last < text.length) out.push({ ...node, text: text.slice(last) })\n return out\n }\n\n const walk = (node: JSONContent): JSONContent => {\n if (!node.content || node.type === 'codeBlock') return node\n let changed = false\n const content = node.content.flatMap((child) => {\n const next = child.type === 'text' ? splitText(child) : [walk(child)]\n if (next.length !== 1 || next[0] !== child) changed = true\n return next\n })\n return changed ? { ...node, content } : node\n }\n return walk(json)\n}\n\n/** Block IDs of the composites of `doc`: the Bausteine a `[@id]` text may point at. */\nexport function compositeIdsOf(doc: PMNode): Set<string> {\n const ids = new Set<string>()\n doc.descendants((node) => {\n if (node.type.name !== 'composite') return\n const id = blockIdOf(node)\n if (id) ids.add(id)\n })\n return ids\n}\n\n/** The `normalize` stage: the composites of the document (`current`) and of `blocks` themselves may be referenced by text. */\nexport function normalizeReferences(blocks: JSONContent[], current: ReadonlySet<string>): JSONContent[] {\n const doc: JSONContent = { type: 'doc', content: blocks }\n return referencesFromText(doc, collectCompositeIds(doc, new Set(current))).content ?? []\n}\n"],"mappings":";;;;AAMA,MAAM,QAAQ,IAAI,OAAO,wBAAwB,GAAG;;AAGpD,SAAgB,oBAAoB,SAAyC,MAAgC;CAC3G,IAAI,CAAC,SAAS,OAAO;CACrB,IAAI,QAAQ,SAAS,eAAe,OAAO,QAAQ,OAAO,OAAO,YAAY,QAAQ,MAAM,IAAI,KAAK,IAAI,QAAQ,MAAM,EAAE;CACxH,KAAK,MAAM,SAAS,QAAQ,WAAW,CAAC,GAAG,oBAAoB,OAAO,IAAI;CAC1E,OAAO;AACT;;;;;;;AAQA,SAAgB,mBAAmB,MAAmB,KAAuC;CAC3F,IAAI,CAAC,IAAI,MAAM,OAAO;CAEtB,MAAM,aAAa,SAAqC;EACtD,MAAM,OAAO,KAAK,QAAQ;EAC1B,IAAI,CAAC,KAAK,SAAS,IAAI,KAAK,KAAK,OAAO,MAAK,MAAK,EAAE,SAAS,UAAU,EAAE,SAAS,MAAM,GAAG,OAAO,CAAC,IAAI;EACvG,MAAM,MAAqB,CAAC;EAC5B,IAAI,OAAO;EACX,KAAK,MAAM,SAAS,KAAK,SAAS,KAAK,GAAG;GACxC,MAAM,SAAS,MAAM;GACrB,IAAI,CAAC,IAAI,IAAI,MAAM,GAAG;GACtB,MAAM,KAAK,MAAM,SAAS;GAC1B,IAAI,KAAK,MAAM,IAAI,KAAK;IAAE,GAAG;IAAM,MAAM,KAAK,MAAM,MAAM,EAAE;GAAE,CAAC;GAC/D,IAAI,KAAK;IACP,MAAM;IACN,OAAO;KAAE;KAAQ,YAAY;KAAM,SAAS,MAAM,EAAE,EAAE,QAAQ,SAAS,GAAG,CAAC,CAAC,KAAK,KAAK;KAAM,OAAO;IAAG;IACtG,GAAI,KAAK,OAAO,SAAS,EAAE,OAAO,KAAK,MAAM,IAAI,CAAC;GACpD,CAAC;GACD,OAAO,KAAK,MAAM,EAAE,CAAC;EACvB;EACA,IAAI,CAAC,IAAI,QAAQ,OAAO,CAAC,IAAI;EAC7B,IAAI,OAAO,KAAK,QAAQ,IAAI,KAAK;GAAE,GAAG;GAAM,MAAM,KAAK,MAAM,IAAI;EAAE,CAAC;EACpE,OAAO;CACT;CAEA,MAAM,QAAQ,SAAmC;EAC/C,IAAI,CAAC,KAAK,WAAW,KAAK,SAAS,aAAa,OAAO;EACvD,IAAI,UAAU;EACd,MAAM,UAAU,KAAK,QAAQ,SAAS,UAAU;GAC9C,MAAM,OAAO,MAAM,SAAS,SAAS,UAAU,KAAK,IAAI,CAAC,KAAK,KAAK,CAAC;GACpE,IAAI,KAAK,WAAW,KAAK,KAAK,OAAO,OAAO,UAAU;GACtD,OAAO;EACT,CAAC;EACD,OAAO,UAAU;GAAE,GAAG;GAAM;EAAQ,IAAI;CAC1C;CACA,OAAO,KAAK,IAAI;AAClB;;AAGA,SAAgB,eAAe,KAA0B;CACvD,MAAM,sBAAM,IAAI,IAAY;CAC5B,IAAI,aAAa,SAAS;EACxB,IAAI,KAAK,KAAK,SAAS,aAAa;EACpC,MAAM,KAAK,UAAU,IAAI;EACzB,IAAI,IAAI,IAAI,IAAI,EAAE;CACpB,CAAC;CACD,OAAO;AACT;;AAGA,SAAgB,oBAAoB,QAAuB,SAA6C;CACtG,MAAM,MAAmB;EAAE,MAAM;EAAO,SAAS;CAAO;CACxD,OAAO,mBAAmB,KAAK,oBAAoB,KAAK,IAAI,IAAI,OAAO,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC;AACzF"}
@@ -0,0 +1,44 @@
1
+ import { Extension, Node } from "@tiptap/core";
2
+ import { PluginKey } from "@tiptap/pm/state";
3
+ import { SuggestionOptions } from "@tiptap/suggestion";
4
+ //#region src/features/composites/reference.d.ts
5
+ /**
6
+ * Attributes of a reference chip. `target` is the block ID of the referenced Baustein; `label` caches its display text
7
+ * for the cases the target cannot be resolved (the node view shows the live label and only falls back to this one).
8
+ */
9
+ export interface ReferenceAttrs {
10
+ target: string;
11
+ /** Document of the target; `null` = this document (cross-document references are not resolved yet). */
12
+ documentId: string | null;
13
+ /** Position inside the target's source: `S. 12` (PDF page), `03:14` (recording time); `null` = the whole Baustein. */
14
+ locator: string | null;
15
+ label: string;
16
+ }
17
+ export declare const REFERENCE_NODE = "reference";
18
+ /** `[@<target>]` / `[@<target>, <locator>]`, the chip's Markdown form; `]` in a locator is escaped as `\]`. */
19
+ export declare function referenceMarkdown(attrs: Pick<ReferenceAttrs, 'target' | 'locator'>): string;
20
+ declare module '@tiptap/core' {
21
+ interface Commands<ReturnType> {
22
+ reference: {
23
+ /** Inserts a reference chip (followed by a space) at the selection. */
24
+ insertReference: (attrs: Partial<ReferenceAttrs> & Pick<ReferenceAttrs, 'target'>) => ReturnType;
25
+ /** Sets the locator of the reference chip at `pos`; an empty text clears it. */
26
+ setReferenceLocator: (pos: number, locator: string) => ReturnType;
27
+ };
28
+ }
29
+ }
30
+ export interface ReferenceOptions {
31
+ HTMLAttributes: Record<string, unknown>;
32
+ /** `[@` popup (client only, see reference-suggestion.ts); `null` = schema only (server, Markdown). */
33
+ suggestion: Omit<SuggestionOptions<ReferenceAttrs, ReferenceAttrs>, 'editor'> | null;
34
+ }
35
+ /** Own key, so the `[@` popup runs next to the `@` mention and `#` tag popups. */
36
+ export declare const ReferenceSuggestionPluginKey: PluginKey<any>;
37
+ /**
38
+ * Inline chip pointing at a Baustein of the document (a paper, a recording, a note): shared by the client editor and
39
+ * the server (collab schema, Markdown). Markdown form `[@<block id>, <locator>]`; text of that form becomes chips again
40
+ * through `referencesFromText` (the composites feature's `normalize` stage). The client adds the node view and the popup.
41
+ */
42
+ export declare const ReferenceNode: Node<ReferenceOptions, any>;
43
+ //#endregion
44
+ //# sourceMappingURL=reference.d.ts.map
@@ -0,0 +1,148 @@
1
+ import { Extension, Node, mergeAttributes } from "@tiptap/core";
2
+ import { PluginKey } from "@tiptap/pm/state";
3
+ import { Suggestion } from "@tiptap/suggestion";
4
+ //#region src/features/composites/reference.ts
5
+ const REFERENCE_NODE = "reference";
6
+ /** `[@<target>]` / `[@<target>, <locator>]`, the chip's Markdown form; `]` in a locator is escaped as `\]`. */
7
+ function referenceMarkdown(attrs) {
8
+ const locator = attrs.locator?.trim();
9
+ return locator ? `[@${attrs.target}, ${locator.replace(/\]/g, "\\]")}]` : `[@${attrs.target}]`;
10
+ }
11
+ /** Pattern of the chip's Markdown form (capture 1: block id, capture 2: locator with `\]` still escaped); compile with `new RegExp(..., 'g')`. */
12
+ const REFERENCE_TOKEN_SOURCE = String.raw`\[@([0-9a-f-]{36})(?:,\s*((?:\\\]|[^\]])+))?\]`;
13
+ /** Own key, so the `[@` popup runs next to the `@` mention and `#` tag popups. */
14
+ const ReferenceSuggestionPluginKey = new PluginKey("referenceSuggestion");
15
+ /**
16
+ * Inline chip pointing at a Baustein of the document (a paper, a recording, a note): shared by the client editor and
17
+ * the server (collab schema, Markdown). Markdown form `[@<block id>, <locator>]`; text of that form becomes chips again
18
+ * through `referencesFromText` (the composites feature's `normalize` stage). The client adds the node view and the popup.
19
+ */
20
+ const ReferenceNode = Node.create({
21
+ name: REFERENCE_NODE,
22
+ group: "inline",
23
+ inline: true,
24
+ atom: true,
25
+ selectable: true,
26
+ priority: 99,
27
+ markdownTokenizer: {
28
+ name: "referenceToken",
29
+ level: "inline",
30
+ start: (src) => src.search(/\[@[0-9a-f-]{36}/),
31
+ tokenize: (src) => {
32
+ const match = new RegExp(`^${REFERENCE_TOKEN_SOURCE}`).exec(src);
33
+ return match ? {
34
+ type: "text",
35
+ raw: match[0],
36
+ text: match[0]
37
+ } : void 0;
38
+ }
39
+ },
40
+ addOptions() {
41
+ return {
42
+ HTMLAttributes: { class: "reference" },
43
+ suggestion: null
44
+ };
45
+ },
46
+ addAttributes() {
47
+ return {
48
+ target: {
49
+ default: "",
50
+ parseHTML: (el) => el.getAttribute("data-target") ?? "",
51
+ renderHTML: (attrs) => ({ "data-target": attrs.target })
52
+ },
53
+ documentId: {
54
+ default: null,
55
+ parseHTML: (el) => el.getAttribute("data-document"),
56
+ renderHTML: (attrs) => attrs.documentId ? { "data-document": attrs.documentId } : {}
57
+ },
58
+ locator: {
59
+ default: null,
60
+ parseHTML: (el) => el.getAttribute("data-locator"),
61
+ renderHTML: (attrs) => attrs.locator ? { "data-locator": attrs.locator } : {}
62
+ },
63
+ label: {
64
+ default: "",
65
+ parseHTML: (el) => el.getAttribute("data-label") ?? el.textContent ?? "",
66
+ renderHTML: (attrs) => ({ "data-label": attrs.label })
67
+ }
68
+ };
69
+ },
70
+ parseHTML() {
71
+ return [{ tag: `span[data-type="${this.name}"]` }];
72
+ },
73
+ renderHTML({ node, HTMLAttributes }) {
74
+ return [
75
+ "span",
76
+ mergeAttributes({ "data-type": this.name }, this.options.HTMLAttributes, HTMLAttributes),
77
+ String(node.attrs.label ?? "")
78
+ ];
79
+ },
80
+ renderText: ({ node }) => referenceMarkdown(node.attrs),
81
+ renderMarkdown: (node) => referenceMarkdown({
82
+ target: String(node.attrs?.target ?? ""),
83
+ locator: typeof node.attrs?.locator === "string" ? node.attrs.locator : null
84
+ }),
85
+ addCommands() {
86
+ return {
87
+ insertReference: (attrs) => ({ commands }) => commands.insertContent([{
88
+ type: this.name,
89
+ attrs
90
+ }, {
91
+ type: "text",
92
+ text: " "
93
+ }]),
94
+ setReferenceLocator: (pos, locator) => ({ tr, dispatch }) => {
95
+ const node = tr.doc.nodeAt(pos);
96
+ if (node?.type.name !== this.name) return false;
97
+ if (dispatch) tr.setNodeMarkup(pos, void 0, {
98
+ ...node.attrs,
99
+ locator: locator.trim() || null
100
+ });
101
+ return true;
102
+ }
103
+ };
104
+ },
105
+ addExtensions() {
106
+ const { suggestion } = this.options;
107
+ return suggestion ? [ReferenceSuggestion.configure({ suggestion })] : [];
108
+ }
109
+ });
110
+ /**
111
+ * The `[@` popup of ReferenceNode. Priority 101 (like TagNode), above core's Keymap (100): extension priority orders
112
+ * the ProseMirror plugins' `handleKeyDown`, and with a lower one Enter would split the paragraph instead of picking.
113
+ */
114
+ const ReferenceSuggestion = Extension.create({
115
+ name: "referenceSuggestion",
116
+ priority: 101,
117
+ addOptions() {
118
+ return { suggestion: null };
119
+ },
120
+ addProseMirrorPlugins() {
121
+ const { suggestion } = this.options;
122
+ if (!suggestion) return [];
123
+ const { allow, ...rest } = suggestion;
124
+ return [Suggestion({
125
+ pluginKey: ReferenceSuggestionPluginKey,
126
+ char: "[@",
127
+ allowSpaces: true,
128
+ allow: (p) => allow?.(p) ?? true,
129
+ command: ({ editor, range, props }) => {
130
+ if (editor.view.state.selection.$to.nodeAfter?.text?.startsWith(" ")) range.to += 1;
131
+ editor.chain().focus().insertContentAt(range, [{
132
+ type: REFERENCE_NODE,
133
+ attrs: props
134
+ }, {
135
+ type: "text",
136
+ text: " "
137
+ }]).run();
138
+ editor.view.dom.ownerDocument.defaultView?.getSelection()?.collapseToEnd();
139
+ },
140
+ ...rest,
141
+ editor: this.editor
142
+ })];
143
+ }
144
+ });
145
+ //#endregion
146
+ export { REFERENCE_NODE, REFERENCE_TOKEN_SOURCE, ReferenceNode, ReferenceSuggestion, ReferenceSuggestionPluginKey, referenceMarkdown };
147
+
148
+ //# sourceMappingURL=reference.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reference.js","names":[],"sources":["../../../src/features/composites/reference.ts"],"sourcesContent":["import { Extension, mergeAttributes, Node } from '@tiptap/core'\nimport { PluginKey } from '@tiptap/pm/state'\nimport { Suggestion, type SuggestionOptions } from '@tiptap/suggestion'\n\n/**\n * Attributes of a reference chip. `target` is the block ID of the referenced Baustein; `label` caches its display text\n * for the cases the target cannot be resolved (the node view shows the live label and only falls back to this one).\n */\nexport interface ReferenceAttrs {\n target: string\n /** Document of the target; `null` = this document (cross-document references are not resolved yet). */\n documentId: string | null\n /** Position inside the target's source: `S. 12` (PDF page), `03:14` (recording time); `null` = the whole Baustein. */\n locator: string | null\n label: string\n}\n\nexport const REFERENCE_NODE = 'reference'\n\n/** Trigger of the popup. Two characters: `[@` is the Markdown form, so typing it by hand and picking from the list agree. */\nexport const REFERENCE_TRIGGER = '[@'\n\n/** `[@<target>]` / `[@<target>, <locator>]`, the chip's Markdown form; `]` in a locator is escaped as `\\]`. */\nexport function referenceMarkdown(attrs: Pick<ReferenceAttrs, 'target' | 'locator'>): string {\n const locator = attrs.locator?.trim()\n return locator ? `[@${attrs.target}, ${locator.replace(/\\]/g, '\\\\]')}]` : `[@${attrs.target}]`\n}\n\n/** Pattern of the chip's Markdown form (capture 1: block id, capture 2: locator with `\\]` still escaped); compile with `new RegExp(..., 'g')`. */\nexport const REFERENCE_TOKEN_SOURCE = String.raw`\\[@([0-9a-f-]{36})(?:,\\s*((?:\\\\\\]|[^\\]])+))?\\]`\n\ndeclare module '@tiptap/core' {\n interface Commands<ReturnType> {\n reference: {\n /** Inserts a reference chip (followed by a space) at the selection. */\n insertReference: (attrs: Partial<ReferenceAttrs> & Pick<ReferenceAttrs, 'target'>) => ReturnType\n /** Sets the locator of the reference chip at `pos`; an empty text clears it. */\n setReferenceLocator: (pos: number, locator: string) => ReturnType\n }\n }\n}\n\nexport interface ReferenceOptions {\n HTMLAttributes: Record<string, unknown>\n /** `[@` popup (client only, see reference-suggestion.ts); `null` = schema only (server, Markdown). */\n suggestion: Omit<SuggestionOptions<ReferenceAttrs, ReferenceAttrs>, 'editor'> | null\n}\n\n/** Own key, so the `[@` popup runs next to the `@` mention and `#` tag popups. */\nexport const ReferenceSuggestionPluginKey = new PluginKey('referenceSuggestion')\n\n/**\n * Inline chip pointing at a Baustein of the document (a paper, a recording, a note): shared by the client editor and\n * the server (collab schema, Markdown). Markdown form `[@<block id>, <locator>]`; text of that form becomes chips again\n * through `referencesFromText` (the composites feature's `normalize` stage). The client adds the node view and the popup.\n */\nexport const ReferenceNode = Node.create<ReferenceOptions>({\n name: REFERENCE_NODE,\n group: 'inline',\n inline: true,\n atom: true,\n selectable: true,\n // Just below Mention (100): TipTap's Markdown manager registers the tokenizers in priority order and marked tries the\n // last registered first, so `markdownTokenizer` below sees `[@<id>]` before Mention's `[@ ...]` shortcode does.\n priority: 99,\n\n // Claims `[@<block id>, <locator>]` as plain text, so Mention's tokenizer (which takes every `[@...]`) leaves it alone;\n // the composites feature's `normalize` stage turns it into a chip when the id belongs to a Baustein of the document.\n markdownTokenizer: {\n name: 'referenceToken',\n level: 'inline',\n start: src => src.search(/\\[@[0-9a-f-]{36}/),\n tokenize: (src) => {\n const match = new RegExp(`^${REFERENCE_TOKEN_SOURCE}`).exec(src)\n return match ? { type: 'text', raw: match[0], text: match[0] } : undefined\n },\n },\n\n addOptions() {\n return { HTMLAttributes: { class: 'reference' }, suggestion: null }\n },\n\n addAttributes() {\n return {\n target: {\n default: '',\n parseHTML: el => el.getAttribute('data-target') ?? '',\n renderHTML: attrs => ({ 'data-target': attrs.target }),\n },\n documentId: {\n default: null,\n parseHTML: el => el.getAttribute('data-document'),\n renderHTML: attrs => attrs.documentId ? { 'data-document': attrs.documentId } : {},\n },\n locator: {\n default: null,\n parseHTML: el => el.getAttribute('data-locator'),\n renderHTML: attrs => attrs.locator ? { 'data-locator': attrs.locator } : {},\n },\n label: {\n default: '',\n parseHTML: el => el.getAttribute('data-label') ?? el.textContent ?? '',\n renderHTML: attrs => ({ 'data-label': attrs.label }),\n },\n }\n },\n\n parseHTML() {\n return [{ tag: `span[data-type=\"${this.name}\"]` }]\n },\n\n renderHTML({ node, HTMLAttributes }) {\n return ['span', mergeAttributes({ 'data-type': this.name }, this.options.HTMLAttributes, HTMLAttributes), String(node.attrs.label ?? '')]\n },\n\n renderText: ({ node }) => referenceMarkdown(node.attrs as ReferenceAttrs),\n\n // Markdown export (editor.getMarkdown(), AI context/selection) writes the chip as `[@<id>, <locator>]`.\n renderMarkdown: node => referenceMarkdown({ target: String(node.attrs?.target ?? ''), locator: typeof node.attrs?.locator === 'string' ? node.attrs.locator : null }),\n\n addCommands() {\n return {\n insertReference: attrs => ({ commands }) =>\n commands.insertContent([{ type: this.name, attrs }, { type: 'text', text: ' ' }]),\n setReferenceLocator: (pos, locator) => ({ tr, dispatch }) => {\n const node = tr.doc.nodeAt(pos)\n if (node?.type.name !== this.name) return false\n if (dispatch) tr.setNodeMarkup(pos, undefined, { ...node.attrs, locator: locator.trim() || null })\n return true\n },\n }\n },\n\n // The popup lives in a companion extension (see `ReferenceSuggestion`): it must rank above TipTap's core keymap\n // (100) to see Enter first, which this node cannot (its priority orders the Markdown tokenizer).\n addExtensions() {\n const { suggestion } = this.options\n return suggestion ? [ReferenceSuggestion.configure({ suggestion })] : []\n },\n})\n\n/**\n * The `[@` popup of ReferenceNode. Priority 101 (like TagNode), above core's Keymap (100): extension priority orders\n * the ProseMirror plugins' `handleKeyDown`, and with a lower one Enter would split the paragraph instead of picking.\n */\nexport const ReferenceSuggestion = Extension.create<{ suggestion: NonNullable<ReferenceOptions['suggestion']> | null }>({\n name: 'referenceSuggestion',\n priority: 101,\n\n addOptions() {\n return { suggestion: null }\n },\n\n addProseMirrorPlugins() {\n const { suggestion } = this.options\n if (!suggestion) return []\n const { allow, ...rest } = suggestion\n return [Suggestion<ReferenceAttrs, ReferenceAttrs>({\n pluginKey: ReferenceSuggestionPluginKey,\n char: REFERENCE_TRIGGER,\n allowSpaces: true,\n allow: p => allow?.(p) ?? true,\n command: ({ editor, range, props }) => {\n // Reuse a following space instead of doubling it (as Mention does).\n const nodeAfter = editor.view.state.selection.$to.nodeAfter\n if (nodeAfter?.text?.startsWith(' ')) range.to += 1\n editor.chain().focus()\n .insertContentAt(range, [{ type: REFERENCE_NODE, attrs: props }, { type: 'text', text: ' ' }])\n .run()\n editor.view.dom.ownerDocument.defaultView?.getSelection()?.collapseToEnd()\n },\n ...rest,\n editor: this.editor,\n })]\n },\n})\n"],"mappings":";;;;AAiBA,MAAa,iBAAiB;;AAM9B,SAAgB,kBAAkB,OAA2D;CAC3F,MAAM,UAAU,MAAM,SAAS,KAAK;CACpC,OAAO,UAAU,KAAK,MAAM,OAAO,IAAI,QAAQ,QAAQ,OAAO,KAAK,EAAE,KAAK,KAAK,MAAM,OAAO;AAC9F;;AAGA,MAAa,yBAAyB,OAAO,GAAG;;AAoBhD,MAAa,+BAA+B,IAAI,UAAU,qBAAqB;;;;;;AAO/E,MAAa,gBAAgB,KAAK,OAAyB;CACzD,MAAM;CACN,OAAO;CACP,QAAQ;CACR,MAAM;CACN,YAAY;CAGZ,UAAU;CAIV,mBAAmB;EACjB,MAAM;EACN,OAAO;EACP,QAAO,QAAO,IAAI,OAAO,kBAAkB;EAC3C,WAAW,QAAQ;GACjB,MAAM,QAAQ,IAAI,OAAO,IAAI,wBAAwB,CAAC,CAAC,KAAK,GAAG;GAC/D,OAAO,QAAQ;IAAE,MAAM;IAAQ,KAAK,MAAM;IAAI,MAAM,MAAM;GAAG,IAAI,KAAA;EACnE;CACF;CAEA,aAAa;EACX,OAAO;GAAE,gBAAgB,EAAE,OAAO,YAAY;GAAG,YAAY;EAAK;CACpE;CAEA,gBAAgB;EACd,OAAO;GACL,QAAQ;IACN,SAAS;IACT,YAAW,OAAM,GAAG,aAAa,aAAa,KAAK;IACnD,aAAY,WAAU,EAAE,eAAe,MAAM,OAAO;GACtD;GACA,YAAY;IACV,SAAS;IACT,YAAW,OAAM,GAAG,aAAa,eAAe;IAChD,aAAY,UAAS,MAAM,aAAa,EAAE,iBAAiB,MAAM,WAAW,IAAI,CAAC;GACnF;GACA,SAAS;IACP,SAAS;IACT,YAAW,OAAM,GAAG,aAAa,cAAc;IAC/C,aAAY,UAAS,MAAM,UAAU,EAAE,gBAAgB,MAAM,QAAQ,IAAI,CAAC;GAC5E;GACA,OAAO;IACL,SAAS;IACT,YAAW,OAAM,GAAG,aAAa,YAAY,KAAK,GAAG,eAAe;IACpE,aAAY,WAAU,EAAE,cAAc,MAAM,MAAM;GACpD;EACF;CACF;CAEA,YAAY;EACV,OAAO,CAAC,EAAE,KAAK,mBAAmB,KAAK,KAAK,IAAI,CAAC;CACnD;CAEA,WAAW,EAAE,MAAM,kBAAkB;EACnC,OAAO;GAAC;GAAQ,gBAAgB,EAAE,aAAa,KAAK,KAAK,GAAG,KAAK,QAAQ,gBAAgB,cAAc;GAAG,OAAO,KAAK,MAAM,SAAS,EAAE;EAAC;CAC1I;CAEA,aAAa,EAAE,WAAW,kBAAkB,KAAK,KAAuB;CAGxE,iBAAgB,SAAQ,kBAAkB;EAAE,QAAQ,OAAO,KAAK,OAAO,UAAU,EAAE;EAAG,SAAS,OAAO,KAAK,OAAO,YAAY,WAAW,KAAK,MAAM,UAAU;CAAK,CAAC;CAEpK,cAAc;EACZ,OAAO;GACL,kBAAiB,WAAU,EAAE,eAC3B,SAAS,cAAc,CAAC;IAAE,MAAM,KAAK;IAAM;GAAM,GAAG;IAAE,MAAM;IAAQ,MAAM;GAAI,CAAC,CAAC;GAClF,sBAAsB,KAAK,aAAa,EAAE,IAAI,eAAe;IAC3D,MAAM,OAAO,GAAG,IAAI,OAAO,GAAG;IAC9B,IAAI,MAAM,KAAK,SAAS,KAAK,MAAM,OAAO;IAC1C,IAAI,UAAU,GAAG,cAAc,KAAK,KAAA,GAAW;KAAE,GAAG,KAAK;KAAO,SAAS,QAAQ,KAAK,KAAK;IAAK,CAAC;IACjG,OAAO;GACT;EACF;CACF;CAIA,gBAAgB;EACd,MAAM,EAAE,eAAe,KAAK;EAC5B,OAAO,aAAa,CAAC,oBAAoB,UAAU,EAAE,WAAW,CAAC,CAAC,IAAI,CAAC;CACzE;AACF,CAAC;;;;;AAMD,MAAa,sBAAsB,UAAU,OAA2E;CACtH,MAAM;CACN,UAAU;CAEV,aAAa;EACX,OAAO,EAAE,YAAY,KAAK;CAC5B;CAEA,wBAAwB;EACtB,MAAM,EAAE,eAAe,KAAK;EAC5B,IAAI,CAAC,YAAY,OAAO,CAAC;EACzB,MAAM,EAAE,OAAO,GAAG,SAAS;EAC3B,OAAO,CAAC,WAA2C;GACjD,WAAW;GACX,MAAA;GACA,aAAa;GACb,QAAO,MAAK,QAAQ,CAAC,KAAK;GAC1B,UAAU,EAAE,QAAQ,OAAO,YAAY;IAGrC,IADkB,OAAO,KAAK,MAAM,UAAU,IAAI,WACnC,MAAM,WAAW,GAAG,GAAG,MAAM,MAAM;IAClD,OAAO,MAAM,CAAC,CAAC,MAAM,CAAC,CACnB,gBAAgB,OAAO,CAAC;KAAE,MAAM;KAAgB,OAAO;IAAM,GAAG;KAAE,MAAM;KAAQ,MAAM;IAAI,CAAC,CAAC,CAAC,CAC7F,IAAI;IACP,OAAO,KAAK,IAAI,cAAc,aAAa,aAAa,CAAC,EAAE,cAAc;GAC3E;GACA,GAAG;GACH,QAAQ,KAAK;EACf,CAAC,CAAC;CACJ;AACF,CAAC"}
@@ -0,0 +1,32 @@
1
+ import { Editor, Extension } from "@tiptap/core";
2
+ //#region src/features/composites/reveal-source.d.ts
3
+ declare module '@tiptap/core' {
4
+ interface Commands<ReturnType> {
5
+ sourceReveal: {
6
+ /** Seek and play the media of the source-holding Baustein enclosing `pos` to `seconds`; silent when there is none. */
7
+ seekSource: (pos: number, seconds: number) => ReturnType;
8
+ };
9
+ }
10
+ }
11
+ /** Where in the source a locator points: a time in seconds (`3:07`) or a PDF page (`S. 12`, `p. 12`, `12`). */
12
+ export type SourceLocator = {
13
+ seconds: number;
14
+ } | {
15
+ page: number;
16
+ };
17
+ /** Parses a reference locator; null for anything that is not a time or a page number. */
18
+ export declare function parseLocator(locator: string | null | undefined): SourceLocator | null;
19
+ /**
20
+ * Seeks and plays the audio/video of the nearest source-holding Baustein around `pos` (a transcript segment inside a
21
+ * rendition reaches the recording that way). Silent when there is no source or no media element.
22
+ */
23
+ export declare function seekSource(editor: Editor, pos: number, seconds: number): void;
24
+ /**
25
+ * Shows the source of Baustein `targetId` at `locator`: a `mm:ss` time seeks the media, a page number opens a PDF source
26
+ * at that page; then the source block flashes. Silent when the target or its source is gone.
27
+ */
28
+ export declare function revealSource(editor: Editor, targetId: string, locator: string | null): void;
29
+ /** Registers `seekSource` as an editor command, so features that must not import composites (transcript) can call it. */
30
+ export declare const SourceReveal: Extension<any, any>;
31
+ //#endregion
32
+ //# sourceMappingURL=reveal-source.d.ts.map
@@ -0,0 +1,89 @@
1
+ import { blockIdOf, findBlockById } from "../../core/schema/block-ids.js";
2
+ import { sourceOf } from "./derivation.js";
3
+ import { compositeKindsOf } from "./nodes.js";
4
+ import { Extension } from "@tiptap/core";
5
+ //#region src/features/composites/reveal-source.ts
6
+ /** DOM event the PDF file view listens for; `detail` is the 1-based page to open the viewer at. */
7
+ const REVEAL_PAGE_EVENT = "sk-reveal-page";
8
+ const TIME_LOCATOR = /^(\d+):(\d{2})$/;
9
+ const PAGE_LOCATOR = /^(?:S\.|p\.)?\s*(\d+)$/i;
10
+ /** Parses a reference locator; null for anything that is not a time or a page number. */
11
+ function parseLocator(locator) {
12
+ const text = locator?.trim();
13
+ if (!text) return null;
14
+ const time = TIME_LOCATOR.exec(text);
15
+ if (time) return { seconds: Number(time[1]) * 60 + Number(time[2]) };
16
+ const page = PAGE_LOCATOR.exec(text);
17
+ if (page && Number(page[1]) > 0) return { page: Number(page[1]) };
18
+ return null;
19
+ }
20
+ /** The source block of the composite `composite` at `pos` with its document position, or null. */
21
+ function sourceAt(editor, composite, pos) {
22
+ const source = sourceOf(composite, compositeKindsOf(editor));
23
+ if (!source) return null;
24
+ let sourcePos = pos + 1;
25
+ for (let i = 0; i < source.index; i++) sourcePos += composite.child(i).nodeSize;
26
+ return {
27
+ node: source.node,
28
+ pos: sourcePos
29
+ };
30
+ }
31
+ /** The element of the node view at `pos` that carries the view's own listeners (the framework's wrapper), or null. */
32
+ function viewElement(editor, pos) {
33
+ const dom = editor.view.nodeDOM(pos);
34
+ if (!(dom instanceof HTMLElement)) return null;
35
+ return dom.matches("[data-node-view-wrapper]") ? dom : dom.querySelector("[data-node-view-wrapper]") ?? dom;
36
+ }
37
+ function playAt(editor, sourcePos, seconds) {
38
+ const dom = editor.view.nodeDOM(sourcePos);
39
+ if (!(dom instanceof HTMLElement)) return false;
40
+ const media = dom.matches("audio,video") ? dom : dom.querySelector("audio,video");
41
+ if (!media) return false;
42
+ media.currentTime = seconds;
43
+ media.play().catch(() => {});
44
+ return true;
45
+ }
46
+ /**
47
+ * Seeks and plays the audio/video of the nearest source-holding Baustein around `pos` (a transcript segment inside a
48
+ * rendition reaches the recording that way). Silent when there is no source or no media element.
49
+ */
50
+ function seekSource(editor, pos, seconds) {
51
+ if (!Number.isFinite(seconds) || seconds < 0) return;
52
+ const $pos = editor.state.doc.resolve(pos);
53
+ for (let depth = $pos.depth; depth >= 0; depth--) {
54
+ const composite = $pos.node(depth);
55
+ if (composite.type.name !== "composite") continue;
56
+ const source = sourceAt(editor, composite, $pos.before(depth));
57
+ if (!source) continue;
58
+ playAt(editor, source.pos, seconds);
59
+ return;
60
+ }
61
+ }
62
+ /**
63
+ * Shows the source of Baustein `targetId` at `locator`: a `mm:ss` time seeks the media, a page number opens a PDF source
64
+ * at that page; then the source block flashes. Silent when the target or its source is gone.
65
+ */
66
+ function revealSource(editor, targetId, locator) {
67
+ const target = findBlockById(editor.state.doc, targetId);
68
+ if (!target) return;
69
+ const source = sourceAt(editor, target.node, target.pos);
70
+ if (!source) return;
71
+ const parsed = parseLocator(locator);
72
+ if (parsed && "seconds" in parsed) playAt(editor, source.pos, parsed.seconds);
73
+ else if (parsed && source.node.type.name === "file" && source.node.attrs.mimeType === "application/pdf") viewElement(editor, source.pos)?.dispatchEvent(new CustomEvent(REVEAL_PAGE_EVENT, { detail: parsed.page }));
74
+ editor.commands.revealBlock(blockIdOf(source.node) ?? targetId);
75
+ }
76
+ /** Registers `seekSource` as an editor command, so features that must not import composites (transcript) can call it. */
77
+ const SourceReveal = Extension.create({
78
+ name: "sourceReveal",
79
+ addCommands() {
80
+ return { seekSource: (pos, seconds) => ({ editor }) => {
81
+ seekSource(editor, pos, seconds);
82
+ return true;
83
+ } };
84
+ }
85
+ });
86
+ //#endregion
87
+ export { REVEAL_PAGE_EVENT, SourceReveal, parseLocator, revealSource, seekSource };
88
+
89
+ //# sourceMappingURL=reveal-source.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reveal-source.js","names":[],"sources":["../../../src/features/composites/reveal-source.ts"],"sourcesContent":["// Client-only: show a Baustein's source (the media block of a source-holding kind) at a spot. A time seeks and plays the\n// audio/video; a page number reloads the PDF viewer at that page. Composites must not import media or transcript, so\n// `seekSource` is also registered as an editor command (`SourceReveal`) for the transcript node view to call.\nimport { Extension, type Editor } from '@tiptap/core'\nimport type { Node as PMNode } from '@tiptap/pm/model'\nimport { blockIdOf, findBlockById } from '../../core/schema'\nimport { sourceOf } from './derivation'\nimport { compositeKindsOf } from './nodes'\n\ndeclare module '@tiptap/core' {\n interface Commands<ReturnType> {\n sourceReveal: {\n /** Seek and play the media of the source-holding Baustein enclosing `pos` to `seconds`; silent when there is none. */\n seekSource: (pos: number, seconds: number) => ReturnType\n }\n }\n}\n\n/** DOM event the PDF file view listens for; `detail` is the 1-based page to open the viewer at. */\nexport const REVEAL_PAGE_EVENT = 'sk-reveal-page'\n\n/** Where in the source a locator points: a time in seconds (`3:07`) or a PDF page (`S. 12`, `p. 12`, `12`). */\nexport type SourceLocator = { seconds: number } | { page: number }\n\nconst TIME_LOCATOR = /^(\\d+):(\\d{2})$/\nconst PAGE_LOCATOR = /^(?:S\\.|p\\.)?\\s*(\\d+)$/i\n\n/** Parses a reference locator; null for anything that is not a time or a page number. */\nexport function parseLocator(locator: string | null | undefined): SourceLocator | null {\n const text = locator?.trim()\n if (!text) return null\n const time = TIME_LOCATOR.exec(text)\n if (time) return { seconds: Number(time[1]) * 60 + Number(time[2]) }\n const page = PAGE_LOCATOR.exec(text)\n if (page && Number(page[1]) > 0) return { page: Number(page[1]) }\n return null\n}\n\n/** The source block of the composite `composite` at `pos` with its document position, or null. */\nfunction sourceAt(editor: Editor, composite: PMNode, pos: number): { node: PMNode, pos: number } | null {\n const source = sourceOf(composite, compositeKindsOf(editor))\n if (!source) return null\n let sourcePos = pos + 1\n for (let i = 0; i < source.index; i++) sourcePos += composite.child(i).nodeSize\n return { node: source.node, pos: sourcePos }\n}\n\n/** The element of the node view at `pos` that carries the view's own listeners (the framework's wrapper), or null. */\nfunction viewElement(editor: Editor, pos: number): HTMLElement | null {\n const dom = editor.view.nodeDOM(pos)\n if (!(dom instanceof HTMLElement)) return null\n return dom.matches('[data-node-view-wrapper]') ? dom : dom.querySelector<HTMLElement>('[data-node-view-wrapper]') ?? dom\n}\n\nfunction playAt(editor: Editor, sourcePos: number, seconds: number): boolean {\n const dom = editor.view.nodeDOM(sourcePos)\n if (!(dom instanceof HTMLElement)) return false\n const media = dom.matches('audio,video') ? dom as HTMLMediaElement : dom.querySelector<HTMLMediaElement>('audio,video')\n if (!media) return false\n media.currentTime = seconds\n media.play().catch(() => { /* autoplay refused: the seek still happened */ })\n return true\n}\n\n/**\n * Seeks and plays the audio/video of the nearest source-holding Baustein around `pos` (a transcript segment inside a\n * rendition reaches the recording that way). Silent when there is no source or no media element.\n */\nexport function seekSource(editor: Editor, pos: number, seconds: number): void {\n if (!Number.isFinite(seconds) || seconds < 0) return\n const $pos = editor.state.doc.resolve(pos)\n for (let depth = $pos.depth; depth >= 0; depth--) {\n const composite = $pos.node(depth)\n if (composite.type.name !== 'composite') continue\n const source = sourceAt(editor, composite, $pos.before(depth))\n if (!source) continue\n playAt(editor, source.pos, seconds)\n return\n }\n}\n\n/**\n * Shows the source of Baustein `targetId` at `locator`: a `mm:ss` time seeks the media, a page number opens a PDF source\n * at that page; then the source block flashes. Silent when the target or its source is gone.\n */\nexport function revealSource(editor: Editor, targetId: string, locator: string | null): void {\n const target = findBlockById(editor.state.doc, targetId)\n if (!target) return\n const source = sourceAt(editor, target.node, target.pos)\n if (!source) return\n const parsed = parseLocator(locator)\n if (parsed && 'seconds' in parsed) {\n playAt(editor, source.pos, parsed.seconds)\n } else if (parsed && source.node.type.name === 'file' && source.node.attrs.mimeType === 'application/pdf') {\n viewElement(editor, source.pos)?.dispatchEvent(new CustomEvent<number>(REVEAL_PAGE_EVENT, { detail: parsed.page }))\n }\n editor.commands.revealBlock(blockIdOf(source.node) ?? targetId)\n}\n\n/** Registers `seekSource` as an editor command, so features that must not import composites (transcript) can call it. */\nexport const SourceReveal = Extension.create({\n name: 'sourceReveal',\n\n addCommands() {\n return {\n // Does not dispatch: a nested dispatch would leave the command's own transaction stale.\n seekSource: (pos, seconds) => ({ editor }) => {\n seekSource(editor, pos, seconds)\n return true\n },\n }\n },\n})\n"],"mappings":";;;;;;AAmBA,MAAa,oBAAoB;AAKjC,MAAM,eAAe;AACrB,MAAM,eAAe;;AAGrB,SAAgB,aAAa,SAA0D;CACrF,MAAM,OAAO,SAAS,KAAK;CAC3B,IAAI,CAAC,MAAM,OAAO;CAClB,MAAM,OAAO,aAAa,KAAK,IAAI;CACnC,IAAI,MAAM,OAAO,EAAE,SAAS,OAAO,KAAK,EAAE,IAAI,KAAK,OAAO,KAAK,EAAE,EAAE;CACnE,MAAM,OAAO,aAAa,KAAK,IAAI;CACnC,IAAI,QAAQ,OAAO,KAAK,EAAE,IAAI,GAAG,OAAO,EAAE,MAAM,OAAO,KAAK,EAAE,EAAE;CAChE,OAAO;AACT;;AAGA,SAAS,SAAS,QAAgB,WAAmB,KAAmD;CACtG,MAAM,SAAS,SAAS,WAAW,iBAAiB,MAAM,CAAC;CAC3D,IAAI,CAAC,QAAQ,OAAO;CACpB,IAAI,YAAY,MAAM;CACtB,KAAK,IAAI,IAAI,GAAG,IAAI,OAAO,OAAO,KAAK,aAAa,UAAU,MAAM,CAAC,CAAC,CAAC;CACvE,OAAO;EAAE,MAAM,OAAO;EAAM,KAAK;CAAU;AAC7C;;AAGA,SAAS,YAAY,QAAgB,KAAiC;CACpE,MAAM,MAAM,OAAO,KAAK,QAAQ,GAAG;CACnC,IAAI,EAAE,eAAe,cAAc,OAAO;CAC1C,OAAO,IAAI,QAAQ,0BAA0B,IAAI,MAAM,IAAI,cAA2B,0BAA0B,KAAK;AACvH;AAEA,SAAS,OAAO,QAAgB,WAAmB,SAA0B;CAC3E,MAAM,MAAM,OAAO,KAAK,QAAQ,SAAS;CACzC,IAAI,EAAE,eAAe,cAAc,OAAO;CAC1C,MAAM,QAAQ,IAAI,QAAQ,aAAa,IAAI,MAA0B,IAAI,cAAgC,aAAa;CACtH,IAAI,CAAC,OAAO,OAAO;CACnB,MAAM,cAAc;CACpB,MAAM,KAAK,CAAC,CAAC,YAAY,CAAkD,CAAC;CAC5E,OAAO;AACT;;;;;AAMA,SAAgB,WAAW,QAAgB,KAAa,SAAuB;CAC7E,IAAI,CAAC,OAAO,SAAS,OAAO,KAAK,UAAU,GAAG;CAC9C,MAAM,OAAO,OAAO,MAAM,IAAI,QAAQ,GAAG;CACzC,KAAK,IAAI,QAAQ,KAAK,OAAO,SAAS,GAAG,SAAS;EAChD,MAAM,YAAY,KAAK,KAAK,KAAK;EACjC,IAAI,UAAU,KAAK,SAAS,aAAa;EACzC,MAAM,SAAS,SAAS,QAAQ,WAAW,KAAK,OAAO,KAAK,CAAC;EAC7D,IAAI,CAAC,QAAQ;EACb,OAAO,QAAQ,OAAO,KAAK,OAAO;EAClC;CACF;AACF;;;;;AAMA,SAAgB,aAAa,QAAgB,UAAkB,SAA8B;CAC3F,MAAM,SAAS,cAAc,OAAO,MAAM,KAAK,QAAQ;CACvD,IAAI,CAAC,QAAQ;CACb,MAAM,SAAS,SAAS,QAAQ,OAAO,MAAM,OAAO,GAAG;CACvD,IAAI,CAAC,QAAQ;CACb,MAAM,SAAS,aAAa,OAAO;CACnC,IAAI,UAAU,aAAa,QACzB,OAAO,QAAQ,OAAO,KAAK,OAAO,OAAO;MACpC,IAAI,UAAU,OAAO,KAAK,KAAK,SAAS,UAAU,OAAO,KAAK,MAAM,aAAa,mBACtF,YAAY,QAAQ,OAAO,GAAG,CAAC,EAAE,cAAc,IAAI,YAAoB,mBAAmB,EAAE,QAAQ,OAAO,KAAK,CAAC,CAAC;CAEpH,OAAO,SAAS,YAAY,UAAU,OAAO,IAAI,KAAK,QAAQ;AAChE;;AAGA,MAAa,eAAe,UAAU,OAAO;CAC3C,MAAM;CAEN,cAAc;EACZ,OAAO,EAEL,aAAa,KAAK,aAAa,EAAE,aAAa;GAC5C,WAAW,QAAQ,KAAK,OAAO;GAC/B,OAAO;EACT,EACF;CACF;AACF,CAAC"}
@@ -27,6 +27,8 @@ export interface CompositeRow {
27
27
  meta: Record<string, unknown>;
28
28
  /** The meta fields of the composite's kind. */
29
29
  fields: readonly CompositeMetaField[];
30
+ /** `false` when the composite's kind hides its tag row (`CompositeKind.chrome.tags === false`): chips, the add-tag control and the tags field stay away. */
31
+ tagsVisible: boolean;
30
32
  /** Nesting level among composites, 0 = outermost. */
31
33
  depth: number;
32
34
  }
@@ -36,14 +38,33 @@ export interface CompositeMention {
36
38
  label: string;
37
39
  color: string | null;
38
40
  }
41
+ /** A reference to a Baustein: a `reference` chip in the text of block `from`, or a `reference` field of the Baustein `from`. */
42
+ export interface CompositeReference {
43
+ /** Block ID of the referenced Baustein. */
44
+ target: string;
45
+ /** Block ID of the nearest block around the chip (the Baustein itself for a field); `null` when that block has no ID yet. */
46
+ from: string | null;
47
+ /** The chip's locator (`S. 12`, `03:14`); `null` for a field or a chip without one. */
48
+ locator: string | null;
49
+ }
39
50
  /**
40
- * Reads every composite of `doc` (also inside quotes and lists) as a row, in document order, and the distinct
41
- * `@mention` chips anywhere in the document. Unknown kinds get the `section` kind's presentation under their own ID.
51
+ * Reads every composite of `doc` (also inside quotes and lists) as a row, in document order, the distinct
52
+ * `@mention` chips anywhere in the document and every reference (`reference` chips and `reference` fields) in document
53
+ * order. Unknown kinds get the `section` kind's presentation under their own ID.
42
54
  */
43
55
  export declare function compositeRows(doc: Node$1, kinds: readonly CompositeKind[]): {
44
56
  rows: CompositeRow[];
45
57
  mentions: CompositeMention[];
58
+ references: CompositeReference[];
46
59
  };
60
+ /** A place that refers to a Baustein: the block holding the chip (or the Baustein with the field) and a short text of it. */
61
+ export interface CompositeBacklink {
62
+ from: string;
63
+ locator: string | null;
64
+ excerpt: string;
65
+ }
66
+ /** Every reference to the Baustein `target` in document order; references whose enclosing block has no ID (or is gone) are left out, as nothing could reveal them. */
67
+ export declare function compositeBacklinks(doc: Node$1, kinds: readonly CompositeKind[], target: string): CompositeBacklink[];
47
68
  /** The innermost row around document position `pos`, `null` outside of any composite. */
48
69
  export declare function compositeRowAt(rows: readonly CompositeRow[], pos: number): CompositeRow | null;
49
70
  /**
@@ -56,7 +77,8 @@ export declare function compositeOfRow(doc: Node$1, row: Pick<CompositeRow, 'id'
56
77
  } | null;
57
78
  /**
58
79
  * `meta` with `value` stored under `field.key`: a number field converts a numeric string, an empty value (`''`,
59
- * `null`, `undefined`, `NaN`) removes the key. Returns a new object; `meta` is not changed.
80
+ * `null`, `undefined`, `NaN`) removes the key. A `multiselect` field keeps the string entries of an array value and
81
+ * removes the key when none is left. Returns a new object; `meta` is not changed.
60
82
  */
61
83
  export declare function compositeMetaWith(meta: Record<string, unknown>, field: Pick<CompositeMetaField, 'key' | 'type'>, value: unknown): Record<string, unknown>;
62
84
  /** Stores `value` under the meta field `key` of the row's composite (see `compositeMetaWith`), in one transaction. */