@formicoidea/labre-core 0.41.0 → 0.42.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 (252) hide show
  1. package/LICENSE +384 -0
  2. package/dist/_pkgs/affine-block-bookmark/bookmark-block.js +2 -2
  3. package/dist/_pkgs/affine-block-edgeless-text/edgeless-toolbar/config.js +7 -1
  4. package/dist/_pkgs/affine-block-embed/embed-figma-block/embed-figma-block.js +2 -1
  5. package/dist/_pkgs/affine-block-embed/embed-github-block/embed-github-block.js +2 -1
  6. package/dist/_pkgs/affine-block-embed/embed-iframe-block/consts.d.ts +2 -0
  7. package/dist/_pkgs/affine-block-embed/embed-iframe-block/consts.js +5 -0
  8. package/dist/_pkgs/affine-block-embed/embed-iframe-block/embed-iframe-block.d.ts +1 -0
  9. package/dist/_pkgs/affine-block-embed/embed-iframe-block/embed-iframe-block.js +30 -8
  10. package/dist/_pkgs/affine-block-embed/embed-iframe-block/utils.d.ts +8 -0
  11. package/dist/_pkgs/affine-block-embed/embed-iframe-block/utils.js +19 -0
  12. package/dist/_pkgs/affine-block-embed/embed-loom-block/embed-loom-block.js +2 -1
  13. package/dist/_pkgs/affine-block-embed/embed-youtube-block/embed-youtube-block.js +2 -1
  14. package/dist/_pkgs/affine-block-frame/frame-manager.js +1 -1
  15. package/dist/_pkgs/affine-block-frame/frame-tool.js +1 -1
  16. package/dist/_pkgs/affine-block-frame/frame-toolbar.js +6 -1
  17. package/dist/_pkgs/affine-block-list/list-keymap.js +7 -0
  18. package/dist/_pkgs/affine-block-note/note-keymap.js +7 -1
  19. package/dist/_pkgs/affine-block-paragraph/paragraph-keymap.js +7 -1
  20. package/dist/_pkgs/affine-block-root/commands/pivot-commands.js +1 -8
  21. package/dist/_pkgs/affine-block-root/commands/tag-commands.js +1 -8
  22. package/dist/_pkgs/affine-block-root/edgeless/edgeless-keyboard.d.ts +9 -0
  23. package/dist/_pkgs/affine-block-root/edgeless/edgeless-keyboard.js +51 -0
  24. package/dist/_pkgs/affine-block-root/edgeless/edgeless-root-block.d.ts +22 -0
  25. package/dist/_pkgs/affine-block-root/edgeless/edgeless-root-block.js +46 -0
  26. package/dist/_pkgs/affine-block-root/edgeless/utils/pinch-zoom.d.ts +21 -0
  27. package/dist/_pkgs/affine-block-root/edgeless/utils/pinch-zoom.js +24 -0
  28. package/dist/_pkgs/affine-block-root/edgeless/utils/query.js +8 -0
  29. package/dist/_pkgs/affine-block-root/keyboard/keymap.js +1 -16
  30. package/dist/_pkgs/affine-block-surface/element-model/index.d.ts +21 -3
  31. package/dist/_pkgs/affine-block-surface/element-model/index.js +14 -2
  32. package/dist/_pkgs/affine-block-surface/extensions/export-svg/command.d.ts +23 -0
  33. package/dist/_pkgs/affine-block-surface/extensions/export-svg/command.js +89 -0
  34. package/dist/_pkgs/affine-block-surface/extensions/export-svg/index.d.ts +7 -0
  35. package/dist/_pkgs/affine-block-surface/extensions/export-svg/index.js +5 -0
  36. package/dist/_pkgs/affine-block-surface/extensions/export-svg/render.d.ts +41 -0
  37. package/dist/_pkgs/affine-block-surface/extensions/export-svg/render.js +70 -0
  38. package/dist/_pkgs/affine-block-surface/extensions/export-svg/svg-context.d.ts +49 -0
  39. package/dist/_pkgs/affine-block-surface/extensions/export-svg/svg-context.js +257 -0
  40. package/dist/_pkgs/affine-block-surface/extensions/export-svg/tagged-path.d.ts +16 -0
  41. package/dist/_pkgs/affine-block-surface/extensions/export-svg/tagged-path.js +24 -0
  42. package/dist/_pkgs/affine-block-surface/extensions/export-svg/toolbar.d.ts +24 -0
  43. package/dist/_pkgs/affine-block-surface/extensions/export-svg/toolbar.js +66 -0
  44. package/dist/_pkgs/affine-block-surface/extensions/index.d.ts +4 -0
  45. package/dist/_pkgs/affine-block-surface/extensions/index.js +4 -0
  46. package/dist/_pkgs/affine-block-surface/extensions/interchange-import.d.ts +66 -4
  47. package/dist/_pkgs/affine-block-surface/extensions/interchange-import.js +241 -11
  48. package/dist/_pkgs/affine-block-surface/extensions/interchange.d.ts +18 -0
  49. package/dist/_pkgs/affine-block-surface/extensions/legend-toolbar.d.ts +81 -0
  50. package/dist/_pkgs/affine-block-surface/extensions/legend-toolbar.js +81 -0
  51. package/dist/_pkgs/affine-block-surface/extensions/legend.d.ts +136 -0
  52. package/dist/_pkgs/affine-block-surface/extensions/legend.js +439 -0
  53. package/dist/_pkgs/affine-block-surface/extensions/reading-widget.d.ts +17 -3
  54. package/dist/_pkgs/affine-block-surface/extensions/reading-widget.js +35 -13
  55. package/dist/_pkgs/affine-block-surface/extensions/reading.d.ts +61 -1
  56. package/dist/_pkgs/affine-block-surface/extensions/reading.js +85 -39
  57. package/dist/_pkgs/affine-block-surface/extensions/record-action.d.ts +66 -0
  58. package/dist/_pkgs/affine-block-surface/extensions/record-action.js +145 -0
  59. package/dist/_pkgs/affine-block-surface/extensions/validation.d.ts +253 -28
  60. package/dist/_pkgs/affine-block-surface/extensions/validation.js +489 -41
  61. package/dist/_pkgs/affine-block-surface/framework-background/background-view.d.ts +115 -0
  62. package/dist/_pkgs/affine-block-surface/framework-background/background-view.js +185 -0
  63. package/dist/_pkgs/affine-block-surface/framework-background/index.d.ts +1 -0
  64. package/dist/_pkgs/affine-block-surface/framework-background/index.js +1 -0
  65. package/dist/_pkgs/affine-block-surface/framework-background/labels.d.ts +16 -1
  66. package/dist/_pkgs/affine-block-surface/framework-background/labels.js +31 -21
  67. package/dist/_pkgs/affine-block-surface/framework-background/renderer.js +29 -5
  68. package/dist/_pkgs/affine-block-surface/framework-background/stacking.d.ts +6 -4
  69. package/dist/_pkgs/affine-block-surface/framework-background/stacking.js +56 -8
  70. package/dist/_pkgs/affine-block-surface/renderer/canvas-renderer.d.ts +12 -0
  71. package/dist/_pkgs/affine-block-surface/renderer/canvas-renderer.js +15 -0
  72. package/dist/_pkgs/affine-block-surface/view.js +8 -1
  73. package/dist/_pkgs/affine-block-surface-ref/configs/slash-menu.js +1 -1
  74. package/dist/_pkgs/affine-components/color-picker/button.d.ts +56 -1
  75. package/dist/_pkgs/affine-components/color-picker/button.js +168 -23
  76. package/dist/_pkgs/affine-components/color-picker/framework-palette.d.ts +106 -0
  77. package/dist/_pkgs/affine-components/color-picker/framework-palette.js +177 -0
  78. package/dist/_pkgs/affine-components/color-picker/index.d.ts +2 -0
  79. package/dist/_pkgs/affine-components/color-picker/index.js +2 -0
  80. package/dist/_pkgs/affine-components/color-picker/palette-carousel.d.ts +85 -0
  81. package/dist/_pkgs/affine-components/color-picker/palette-carousel.js +440 -0
  82. package/dist/_pkgs/affine-components/edgeless-shape-color-picker/color-picker.d.ts +31 -1
  83. package/dist/_pkgs/affine-components/edgeless-shape-color-picker/color-picker.js +189 -63
  84. package/dist/_pkgs/affine-components/resource/resource.js +29 -16
  85. package/dist/_pkgs/affine-components/translations.d.ts +8 -0
  86. package/dist/_pkgs/affine-components/translations.js +17 -0
  87. package/dist/_pkgs/affine-foundation/view.js +2 -1
  88. package/dist/_pkgs/affine-gfx-brush/element-renderer.js +2 -2
  89. package/dist/_pkgs/affine-gfx-brush/toolbar/configs/brush.js +6 -1
  90. package/dist/_pkgs/affine-gfx-brush/toolbar/configs/highlighter.js +6 -1
  91. package/dist/_pkgs/affine-gfx-connector/connector-manager.d.ts +9 -1
  92. package/dist/_pkgs/affine-gfx-connector/connector-manager.js +61 -0
  93. package/dist/_pkgs/affine-gfx-connector/element-renderer/connector-dom/index.d.ts +7 -1
  94. package/dist/_pkgs/affine-gfx-connector/element-renderer/connector-dom/index.js +87 -17
  95. package/dist/_pkgs/affine-gfx-connector/element-renderer/index.js +78 -17
  96. package/dist/_pkgs/affine-gfx-connector/element-renderer/utils.d.ts +24 -2
  97. package/dist/_pkgs/affine-gfx-connector/element-renderer/utils.js +31 -8
  98. package/dist/_pkgs/affine-gfx-connector/text/edgeless-connector-label-editor.d.ts +124 -3
  99. package/dist/_pkgs/affine-gfx-connector/text/edgeless-connector-label-editor.js +216 -54
  100. package/dist/_pkgs/affine-gfx-connector/text/text.d.ts +13 -4
  101. package/dist/_pkgs/affine-gfx-connector/text/text.js +13 -44
  102. package/dist/_pkgs/affine-gfx-connector/toolbar/config.d.ts +56 -0
  103. package/dist/_pkgs/affine-gfx-connector/toolbar/config.js +72 -4
  104. package/dist/_pkgs/affine-gfx-connector/toolbar/hollow-endpoint-icons.d.ts +8 -0
  105. package/dist/_pkgs/affine-gfx-connector/toolbar/hollow-endpoint-icons.js +118 -0
  106. package/dist/_pkgs/affine-gfx-connector/view/view.d.ts +37 -1
  107. package/dist/_pkgs/affine-gfx-connector/view/view.js +97 -8
  108. package/dist/_pkgs/affine-gfx-group/command/group-api.js +1 -1
  109. package/dist/_pkgs/affine-gfx-group/store.js +0 -2
  110. package/dist/_pkgs/affine-gfx-group/translations.d.ts +9 -10
  111. package/dist/_pkgs/affine-gfx-group/translations.js +9 -13
  112. package/dist/_pkgs/affine-gfx-mindmap/templates/index.js +1 -1
  113. package/dist/_pkgs/affine-gfx-mindmap/toolbar/basket-elements.js +1 -1
  114. package/dist/_pkgs/affine-gfx-mindmap/toolbar/utils/import-mindmap.js +2 -2
  115. package/dist/_pkgs/affine-gfx-mindmap/translations.d.ts +1 -1
  116. package/dist/_pkgs/affine-gfx-mindmap/translations.js +1 -1
  117. package/dist/_pkgs/affine-gfx-shape/element-renderer/highlighter.js +2 -2
  118. package/dist/_pkgs/affine-gfx-shape/overlay/polygon-drawing-overlay.d.ts +6 -0
  119. package/dist/_pkgs/affine-gfx-shape/overlay/polygon-drawing-overlay.js +30 -1
  120. package/dist/_pkgs/affine-gfx-shape/polygon-tool.d.ts +20 -1
  121. package/dist/_pkgs/affine-gfx-shape/polygon-tool.js +9 -1
  122. package/dist/_pkgs/affine-gfx-shape/toolbar/config.js +6 -1
  123. package/dist/_pkgs/affine-gfx-shape/toolbar/palette-color-action.js +11 -1
  124. package/dist/_pkgs/affine-gfx-template/builtin/other.js +1 -1
  125. package/dist/_pkgs/affine-gfx-template/snapshot-from-action.js +32 -119
  126. package/dist/_pkgs/affine-gfx-template/toolbar/template-type.d.ts +1 -1
  127. package/dist/_pkgs/affine-gfx-text/dblclick-add-edgeless-text.d.ts +13 -1
  128. package/dist/_pkgs/affine-gfx-text/dblclick-add-edgeless-text.js +19 -4
  129. package/dist/_pkgs/affine-gfx-text/edgeless-text-editor.d.ts +41 -0
  130. package/dist/_pkgs/affine-gfx-text/edgeless-text-editor.js +57 -2
  131. package/dist/_pkgs/affine-gfx-text/toolbar/actions.d.ts +8 -1
  132. package/dist/_pkgs/affine-gfx-text/toolbar/actions.js +12 -2
  133. package/dist/_pkgs/affine-gfx-text/translations.d.ts +1 -0
  134. package/dist/_pkgs/affine-gfx-text/translations.js +2 -1
  135. package/dist/_pkgs/affine-inline-preset/markdown.js +5 -1
  136. package/dist/_pkgs/affine-model/consts/connector.d.ts +28 -2
  137. package/dist/_pkgs/affine-model/consts/connector.js +26 -0
  138. package/dist/_pkgs/affine-model/elements/bpmn/pool.js +1 -1
  139. package/dist/_pkgs/affine-model/elements/brush/brush.js +1 -1
  140. package/dist/_pkgs/affine-model/elements/c4/board.js +1 -1
  141. package/dist/_pkgs/affine-model/elements/c4/boundary.js +1 -1
  142. package/dist/_pkgs/affine-model/elements/connector/connector.d.ts +135 -0
  143. package/dist/_pkgs/affine-model/elements/connector/connector.js +246 -5
  144. package/dist/_pkgs/affine-model/elements/connector/end-label.d.ts +83 -0
  145. package/dist/_pkgs/affine-model/elements/connector/end-label.js +119 -0
  146. package/dist/_pkgs/affine-model/elements/connector/index.d.ts +1 -0
  147. package/dist/_pkgs/affine-model/elements/connector/index.js +1 -0
  148. package/dist/_pkgs/affine-model/elements/context-map/context-map.js +1 -1
  149. package/dist/_pkgs/affine-model/elements/core-domain/core-domain.d.ts +28 -0
  150. package/dist/_pkgs/affine-model/elements/core-domain/core-domain.js +129 -2
  151. package/dist/_pkgs/affine-model/elements/cynefin/cynefin.d.ts +8 -0
  152. package/dist/_pkgs/affine-model/elements/cynefin/cynefin.js +45 -2
  153. package/dist/_pkgs/affine-model/elements/edgy/board.js +1 -1
  154. package/dist/_pkgs/affine-model/elements/edgy/facets.js +1 -1
  155. package/dist/_pkgs/affine-model/elements/estuarine/estuarine.d.ts +6 -0
  156. package/dist/_pkgs/affine-model/elements/estuarine/estuarine.js +36 -2
  157. package/dist/_pkgs/affine-model/elements/event-storming/event-storming.d.ts +18 -7
  158. package/dist/_pkgs/affine-model/elements/event-storming/event-storming.js +23 -8
  159. package/dist/_pkgs/affine-model/elements/framework-background/background.d.ts +16 -0
  160. package/dist/_pkgs/affine-model/elements/framework-background/background.js +18 -0
  161. package/dist/_pkgs/affine-model/elements/highlighter/highlighter.js +1 -1
  162. package/dist/_pkgs/affine-model/elements/index.d.ts +8 -0
  163. package/dist/_pkgs/affine-model/elements/index.js +1 -0
  164. package/dist/_pkgs/affine-model/elements/shape/shape.js +1 -1
  165. package/dist/_pkgs/affine-model/elements/text/text.js +1 -1
  166. package/dist/_pkgs/affine-model/elements/uml/band.d.ts +39 -0
  167. package/dist/_pkgs/affine-model/elements/uml/band.js +31 -0
  168. package/dist/_pkgs/affine-model/elements/uml/diagram.d.ts +158 -0
  169. package/dist/_pkgs/affine-model/elements/uml/diagram.js +229 -0
  170. package/dist/_pkgs/affine-model/elements/uml/fragment.d.ts +161 -0
  171. package/dist/_pkgs/affine-model/elements/uml/fragment.js +205 -0
  172. package/dist/_pkgs/affine-model/elements/uml/index.d.ts +8 -0
  173. package/dist/_pkgs/affine-model/elements/uml/index.js +8 -0
  174. package/dist/_pkgs/affine-model/elements/uml/lifeline.d.ts +77 -0
  175. package/dist/_pkgs/affine-model/elements/uml/lifeline.js +89 -0
  176. package/dist/_pkgs/affine-model/elements/uml/node.d.ts +142 -0
  177. package/dist/_pkgs/affine-model/elements/uml/node.js +190 -0
  178. package/dist/_pkgs/affine-model/elements/uml/partition.d.ts +106 -0
  179. package/dist/_pkgs/affine-model/elements/uml/partition.js +172 -0
  180. package/dist/_pkgs/affine-model/elements/uml/region.d.ts +75 -0
  181. package/dist/_pkgs/affine-model/elements/uml/region.js +150 -0
  182. package/dist/_pkgs/affine-model/elements/uml/subject.d.ts +37 -0
  183. package/dist/_pkgs/affine-model/elements/uml/subject.js +108 -0
  184. package/dist/_pkgs/affine-model/elements/wardley/wardley.js +1 -1
  185. package/dist/_pkgs/affine-shared/services/embed-iframe/embed-iframe-config.d.ts +1 -0
  186. package/dist/_pkgs/affine-shared/services/font-loader/config.d.ts +7 -0
  187. package/dist/_pkgs/affine-shared/services/font-loader/config.js +43 -0
  188. package/dist/_pkgs/affine-shared/services/pivot-materiality-publisher.js +1 -9
  189. package/dist/_pkgs/affine-shared/services/telemetry-service/document-damage-watcher.d.ts +53 -0
  190. package/dist/_pkgs/affine-shared/services/telemetry-service/document-damage-watcher.js +95 -0
  191. package/dist/_pkgs/affine-shared/services/telemetry-service/index.d.ts +1 -0
  192. package/dist/_pkgs/affine-shared/services/telemetry-service/index.js +1 -0
  193. package/dist/_pkgs/affine-shared/services/telemetry-service/lifecycle.d.ts +26 -1
  194. package/dist/_pkgs/affine-shared/services/telemetry-service/telemetry-service.d.ts +2 -2
  195. package/dist/_pkgs/affine-shared/services/toolbar-service/command-action.d.ts +34 -0
  196. package/dist/_pkgs/affine-shared/services/toolbar-service/command-action.js +63 -0
  197. package/dist/_pkgs/affine-shared/services/toolbar-service/index.d.ts +1 -0
  198. package/dist/_pkgs/affine-shared/services/toolbar-service/index.js +1 -0
  199. package/dist/_pkgs/affine-shared/services/translation-service/chrome.d.ts +77 -7
  200. package/dist/_pkgs/affine-shared/services/translation-service/chrome.js +97 -7
  201. package/dist/_pkgs/affine-shared/styles/index.d.ts +1 -0
  202. package/dist/_pkgs/affine-shared/styles/index.js +1 -0
  203. package/dist/_pkgs/affine-shared/styles/motion.d.ts +14 -0
  204. package/dist/_pkgs/affine-shared/styles/motion.js +38 -0
  205. package/dist/_pkgs/affine-shared/utils/event.d.ts +10 -0
  206. package/dist/_pkgs/affine-shared/utils/event.js +20 -0
  207. package/dist/_pkgs/affine-shared/utils/file/filesys.d.ts +16 -0
  208. package/dist/_pkgs/affine-shared/utils/file/filesys.js +25 -0
  209. package/dist/_pkgs/affine-shared/utils/index.d.ts +1 -0
  210. package/dist/_pkgs/affine-shared/utils/index.js +1 -0
  211. package/dist/_pkgs/affine-shared/utils/link-preview-refresh.d.ts +12 -0
  212. package/dist/_pkgs/affine-shared/utils/link-preview-refresh.js +13 -0
  213. package/dist/_pkgs/affine-widget-edgeless-toolbar/catalogue/artefact-catalogue-widget.d.ts +12 -4
  214. package/dist/_pkgs/affine-widget-edgeless-toolbar/catalogue/artefact-catalogue-widget.js +27 -4
  215. package/dist/_pkgs/affine-widget-edgeless-toolbar/create-popper.js +13 -0
  216. package/dist/_pkgs/affine-widget-edgeless-toolbar/index.d.ts +2 -0
  217. package/dist/_pkgs/affine-widget-edgeless-toolbar/index.js +2 -0
  218. package/dist/_pkgs/affine-widget-edgeless-toolbar/menu/command-menu.d.ts +80 -0
  219. package/dist/_pkgs/affine-widget-edgeless-toolbar/menu/command-menu.js +270 -81
  220. package/dist/_pkgs/affine-widget-edgeless-toolbar/menu/senior-menu-selection.d.ts +15 -0
  221. package/dist/_pkgs/affine-widget-edgeless-toolbar/menu/senior-menu-selection.js +15 -0
  222. package/dist/_pkgs/affine-widget-edgeless-toolbar/panel/font-weight-and-style-panel.js +8 -1
  223. package/dist/_pkgs/affine-widget-edgeless-toolbar/placement/artefact-ghost-overlay.d.ts +42 -0
  224. package/dist/_pkgs/affine-widget-edgeless-toolbar/placement/artefact-ghost-overlay.js +100 -0
  225. package/dist/_pkgs/affine-widget-edgeless-toolbar/placement/artefact-placement-tool.d.ts +100 -0
  226. package/dist/_pkgs/affine-widget-edgeless-toolbar/placement/artefact-placement-tool.js +274 -0
  227. package/dist/_pkgs/affine-widget-edgeless-toolbar/placement/index.d.ts +3 -0
  228. package/dist/_pkgs/affine-widget-edgeless-toolbar/placement/index.js +3 -0
  229. package/dist/_pkgs/affine-widget-edgeless-toolbar/placement/translate-created.d.ts +25 -0
  230. package/dist/_pkgs/affine-widget-edgeless-toolbar/placement/translate-created.js +67 -0
  231. package/dist/_pkgs/affine-widget-edgeless-toolbar/view.js +5 -0
  232. package/dist/_pkgs/global/gfx/xywh.js +7 -0
  233. package/dist/_pkgs/std/extension/command-registry.d.ts +158 -1
  234. package/dist/_pkgs/std/extension/command-registry.js +22 -0
  235. package/dist/_pkgs/std/gfx/index.d.ts +1 -1
  236. package/dist/_pkgs/std/gfx/interactivity/gfx-view-event-handler.d.ts +12 -0
  237. package/dist/_pkgs/std/gfx/interactivity/gfx-view-event-handler.js +20 -1
  238. package/dist/_pkgs/std/gfx/interactivity/manager.d.ts +10 -0
  239. package/dist/_pkgs/std/gfx/interactivity/manager.js +12 -0
  240. package/dist/_pkgs/std/gfx/model/surface/element-model.js +12 -7
  241. package/dist/_pkgs/std/gfx/model/surface/surface-model.d.ts +56 -0
  242. package/dist/_pkgs/std/gfx/model/surface/surface-model.js +84 -3
  243. package/dist/_pkgs/std/gfx/view/view.d.ts +11 -2
  244. package/dist/_pkgs/std/gfx/view/view.js +16 -2
  245. package/dist/commands.d.ts +6 -0
  246. package/dist/commands.js +8 -1
  247. package/dist/frameworks.d.ts +9 -0
  248. package/dist/frameworks.js +19 -0
  249. package/dist/translations.js +16 -0
  250. package/package.json +9 -4
  251. package/dist/_pkgs/affine-gfx-group/group-watcher.d.ts +0 -1
  252. package/dist/_pkgs/affine-gfx-group/group-watcher.js +0 -20
@@ -40,7 +40,7 @@ import { css, html, nothing } from 'lit';
40
40
  import { state } from 'lit/decorators.js';
41
41
  import { literal, unsafeStatic } from 'lit/static-html.js';
42
42
  import { EditorAnchoredPanel, editorAnchoredPanelStyles, } from './editor-anchored-panel.js';
43
- import { PivotRecordPickerProvider, ReadingManager, readRecord, readValueFlows, } from './reading.js';
43
+ import { PivotRecordPickerProvider, ReadingManager, readingRelationDefs, readRecord, readValueFlows, } from './reading.js';
44
44
  export const READING_PROPOSAL_WIDGET = 'affine-reading-proposal-widget';
45
45
  /** The two commands the confirmations drive. Spelled once. */
46
46
  const TAG_SET_ID = 'tag.set';
@@ -411,37 +411,59 @@ let ReadingProposalWidget = (() => {
411
411
  : nothing}`);
412
412
  }
413
413
  /**
414
- * The typed edges touching the subject, grouped by side and named with the
415
- * FRAMEWORK's own two words (`ReadingRelationDef.sides`).
414
+ * The typed edges touching the subject, grouped by TABLE and then by side,
415
+ * and named with the FRAMEWORK's own two words
416
+ * (`ReadingRelationDef.sides`).
417
+ *
418
+ * One line per (table, side) rather than per side, since a profile may
419
+ * declare several tables (`ReadingProfile.alsoRelations`): a UML use case
420
+ * associated with an actor and including another use case has two sentences
421
+ * to say and they are not the same sentence. A framework declaring one table
422
+ * — which is every framework but UML — renders exactly what it did before.
416
423
  *
417
424
  * The `data-testid` keeps the shape it shipped with — `reading-consumers`,
418
425
  * `reading-suppliers` — because it names the SIDE, which is generic, and not
419
- * the wording, which is now the framework's.
426
+ * the wording, which is the framework's. `data-relation-role` is what tells
427
+ * two lines of the same side apart.
428
+ *
429
+ * The FAR end's label rides with the name, in parentheses: a UML association
430
+ * writes its multiplicity there (ADR 0020) and "Associated with: OrderLine
431
+ * (1..*)" is the sentence an author drew. The subject's OWN end label is read
432
+ * too ({@link ReadingRelation.ownEndLabel}) and deliberately not printed —
433
+ * one line about the other end, not a transcription of the connector.
420
434
  */
421
435
  _renderRelations(reading, profile) {
422
- const sides = profile.relation?.sides;
423
- const line = (side) => {
424
- const relations = reading.relations.filter(r => r.side === side);
425
- const wording = sides?.[side];
436
+ const named = (relation) => {
437
+ const name = relation.otherName || relation.otherId;
438
+ return relation.otherEndLabel
439
+ ? `${name} (${relation.otherEndLabel})`
440
+ : name;
441
+ };
442
+ const line = (edgeRole, side) => {
443
+ const relations = reading.relations.filter(r => r.side === side && r.relationRole === edgeRole);
444
+ const wording = readingRelationDefs(profile).find(def => def.edgeRole === edgeRole)?.sides[side];
426
445
  // No wording means the framework declared no relation at all, in which
427
446
  // case there is nothing to list either. Silence rather than a heading
428
447
  // this library would have had to invent.
429
448
  if (!relations.length || !wording)
430
449
  return nothing;
431
- return html `<div class="reading-value" data-testid=${`reading-${side}s`}>
450
+ return html `<div
451
+ class="reading-value"
452
+ data-testid=${`reading-${side}s`}
453
+ data-relation-role=${edgeRole}
454
+ >
432
455
  ${translateKey(this.std, wording.labelKey, wording.labelFallback)}:
433
- ${relations
434
- .map(relation => relation.otherName || relation.otherId)
435
- .join(', ')}
456
+ ${relations.map(named).join(', ')}
436
457
  </div>`;
437
458
  };
459
+ const lines = readingRelationDefs(profile).flatMap(def => RELATION_SIDES.map(side => line(def.edgeRole, side)));
438
460
  const contradictions = reading.relations.filter(r => r.contradictsGeometry);
439
461
  return this._field('reading-relations', translateKey(this.std, 'com.labre.reading.field.relations', 'Parent-child relations'), html `${reading.relations.length === 0
440
462
  ? html `<div class="reading-empty">
441
463
  ${translateKey(this.std, 'com.labre.reading.relations.none', 'No typed link touches this component.')}
442
464
  </div>`
443
465
  : nothing}
444
- ${RELATION_SIDES.map(line)}
466
+ ${lines}
445
467
  ${contradictions.length
446
468
  ? html `<div class="reading-note" data-testid="reading-contradiction">
447
469
  ${translateKey(this.std, 'com.labre.reading.relations.contradiction', 'A link states the opposite of what the positions show')}:
@@ -155,8 +155,36 @@ export interface ReadingProfile {
155
155
  tagId: string;
156
156
  conventions: readonly ReadingNamingConvention[];
157
157
  };
158
- /** The typed edge whose two ends the relation reading walks. */
158
+ /**
159
+ * The typed edge whose two ends the relation reading walks — the one the
160
+ * artefact is read THROUGH, and the one the panel lists first.
161
+ */
159
162
  relation?: ReadingRelationDef;
163
+ /**
164
+ * The OTHER typed edges the same artefact is read through, read after
165
+ * {@link relation} and listed under their own wordings.
166
+ *
167
+ * Absent for every framework whose artefacts carry one kind of line: a
168
+ * Wardley component has a dependency, a BPMN task a sequence flow, and a
169
+ * second table there would be a heading with nothing under it.
170
+ *
171
+ * It exists because UML's artefacts carry a DOZEN kinds of line, and the
172
+ * panel answering with one of them reads as an answer rather than as a
173
+ * selection: the PO's recette of 2026-09-14 (O8) opened the reading on a use
174
+ * case whose only link was an `«include»` and was told "No typed link touches
175
+ * this component", which the drawing plainly contradicted. One relation per
176
+ * profile was a deliberate narrowing (`gfx/uml/src/reading.ts` argued it and
177
+ * named what it left unread); what the recette established is that a reader
178
+ * cannot tell a narrowing from a failure, because the panel says the same
179
+ * thing in both cases.
180
+ *
181
+ * Every table is INDEPENDENT: its own `edgeRole`, its own two wordings, its
182
+ * own `geometry` claim. `roleIsA` still applies to each, so a table declared
183
+ * on a parent role reaches its children and two tables must not overlap — an
184
+ * edge matching both would be listed twice. Order is the order the panel
185
+ * reads them in, so the first is the question the artefact answers first.
186
+ */
187
+ alsoRelations?: readonly ReadingRelationDef[];
160
188
  /** The frame the phase is read from. */
161
189
  frame?: {
162
190
  backgroundRole: RoleId;
@@ -181,14 +209,46 @@ export interface ReadingProfile {
181
209
  }
182
210
  /** Where the other end of a typed edge sits, relative to the subject. */
183
211
  export type ReadingRelationSide = 'consumer' | 'supplier';
212
+ /**
213
+ * Every relation table a profile declares, in reading order.
214
+ *
215
+ * One function so the engine and the panel cannot disagree about what a profile
216
+ * declares — the bug that shape of duplication always produces is a table read
217
+ * into {@link ElementReading.relations} and never drawn, or a heading drawn
218
+ * over nothing.
219
+ */
220
+ export declare function readingRelationDefs(profile: ReadingProfile): readonly ReadingRelationDef[];
184
221
  /** One typed edge touching the subject, read with the ADR 0010 convention. */
185
222
  export interface ReadingRelation {
186
223
  /** The edge element. */
187
224
  edgeId: string;
225
+ /**
226
+ * The `edgeRole` of the TABLE that matched — the role the profile DECLARED,
227
+ * never the edge's own, which may be a specialisation of it (a UML
228
+ * composition read through `uml:association`, §11.5.4).
229
+ *
230
+ * It is what lets the panel put each relation under the wording it was read
231
+ * with once a profile declares several tables. One reading, one table, and
232
+ * the tables never overlap: {@link readingRelationDefs} documents that as the
233
+ * declaring framework's obligation.
234
+ */
235
+ relationRole: RoleId;
188
236
  /** The element at the other end. */
189
237
  otherId: string;
190
238
  /** Its name, when it has one — for the panel, which must not print ids. */
191
239
  otherName: string;
240
+ /**
241
+ * What the connector writes at the SUBJECT's end, and at the other end —
242
+ * `undefined` when the author wrote nothing there, which is the ordinary
243
+ * case (ADR 0020).
244
+ *
245
+ * Two spellings of the same fact rather than `sourceLabel`/`targetLabel`,
246
+ * because the reading is written from the subject outwards and a panel
247
+ * saying "Associated with: OrderLine (1..*)" must not have to work out which
248
+ * end of the arrow it is standing on.
249
+ */
250
+ ownEndLabel?: string;
251
+ otherEndLabel?: string;
192
252
  /**
193
253
  * What the OTHER element is to the subject. ADR 0010 § 2 tier 2: on a
194
254
  * `wardley:dependency`, `source` is the consumer and `target` is what it
@@ -9,6 +9,21 @@ import { effect, signal } from '@preact/signals-core';
9
9
  // canvas in.
10
10
  import { backgroundPlot, } from '../framework-background/def.js';
11
11
  import { backgroundTransitionBands, containingFrame, } from '../framework-background/facts.js';
12
+ /**
13
+ * Every relation table a profile declares, in reading order.
14
+ *
15
+ * One function so the engine and the panel cannot disagree about what a profile
16
+ * declares — the bug that shape of duplication always produces is a table read
17
+ * into {@link ElementReading.relations} and never drawn, or a heading drawn
18
+ * over nothing.
19
+ */
20
+ export function readingRelationDefs(profile) {
21
+ const first = profile.relation;
22
+ const rest = profile.alsoRelations ?? [];
23
+ if (!first)
24
+ return rest;
25
+ return rest.length === 0 ? [first] : [first, ...rest];
26
+ }
12
27
  /** Deepest role chain reported by {@link ReadingNodeType.specialises}. */
13
28
  const MAX_ROLE_DEPTH = 32;
14
29
  /** Numeric slack on the two geometry comparisons. Model units. */
@@ -218,55 +233,86 @@ function endpointsOf(element) {
218
233
  return { source: source.id, target: target.id };
219
234
  }
220
235
  /**
221
- * Every typed edge touching the subject, read as a relation.
236
+ * What a connector writes at one of its two ends, when it writes anything.
237
+ *
238
+ * A UML multiplicity is the case this exists for (`0..*` on the far end of an
239
+ * association), and the shape is ADR 0020's: two optional `Y.Text` props on the
240
+ * connector, empty when the author never opened the editor. Read defensively —
241
+ * the reading is handed plain element models by unit tests as readily as live
242
+ * ones — and blank-trimmed, because a text the user emptied is not a label.
243
+ */
244
+ function endLabelOf(edge, end) {
245
+ const raw = edge[end === 'source' ? 'sourceLabel' : 'targetLabel'];
246
+ if (raw === undefined || raw === null)
247
+ return undefined;
248
+ const text = String(raw).trim();
249
+ return text.length > 0 ? text : undefined;
250
+ }
251
+ /**
252
+ * Every typed edge touching the subject, read as a relation — one pass per
253
+ * table the profile declares ({@link readingRelationDefs}).
254
+ *
255
+ * The tables are walked in DECLARATION order rather than the elements being
256
+ * walked once and each edge matched against every table, so the panel's
257
+ * sections come out in the order their framework wrote them and an artefact
258
+ * read through four kinds of line reads its first kind first. The cost is one
259
+ * pass over the surface per table, which is what it already was when a profile
260
+ * could only declare one.
222
261
  *
223
262
  * An edge with an unbound end is skipped, exactly as ADR 0010 requires of W4:
224
263
  * releasing the link tool over empty canvas produces one, and a stroke that
225
264
  * links nothing states nothing.
226
265
  */
227
266
  function readRelations(element, elements, profile) {
228
- const relation = profile.relation;
229
- if (!relation)
267
+ const defs = readingRelationDefs(profile);
268
+ if (defs.length === 0)
230
269
  return [];
231
270
  const byId = new Map(elements.map(el => [el.id, el]));
232
271
  const [, subjectY] = centreOf(element.elementBound);
233
272
  const relations = [];
234
- for (const edge of elements) {
235
- if (edge.role === undefined)
236
- continue;
237
- if (!roleIsA(edge.role, relation.edgeRole, profile.roles))
238
- continue;
239
- const ends = endpointsOf(edge);
240
- if (!ends)
241
- continue;
242
- const isSource = ends.source === element.id;
243
- const isTarget = ends.target === element.id;
244
- // A self-loop states nothing about an order and would report the subject as
245
- // its own supplier.
246
- if (isSource === isTarget)
247
- continue;
248
- const otherId = isSource ? ends.target : ends.source;
249
- const other = byId.get(otherId);
250
- if (!other)
251
- continue;
252
- const side = isSource ? 'supplier' : 'consumer';
253
- const [, otherY] = centreOf(other.elementBound);
254
- // `y` grows downwards, so "higher on the map" is a SMALLER y. A supplier is
255
- // expected below the subject, a consumer above it — but only on a board
256
- // whose framework CLAIMED that axis says something (`geometry`). Two BPMN
257
- // tasks side by side contradict nothing.
258
- const contradictsGeometry = relation.geometry !== 'vertical'
259
- ? false
260
- : side === 'supplier'
261
- ? otherY < subjectY - GEOMETRY_EPSILON
262
- : otherY > subjectY + GEOMETRY_EPSILON;
263
- relations.push({
264
- edgeId: edge.id,
265
- otherId,
266
- otherName: readName(other, profile),
267
- side,
268
- contradictsGeometry,
269
- });
273
+ for (const relation of defs) {
274
+ for (const edge of elements) {
275
+ if (edge.role === undefined)
276
+ continue;
277
+ if (!roleIsA(edge.role, relation.edgeRole, profile.roles))
278
+ continue;
279
+ const ends = endpointsOf(edge);
280
+ if (!ends)
281
+ continue;
282
+ const isSource = ends.source === element.id;
283
+ const isTarget = ends.target === element.id;
284
+ // A self-loop states nothing about an order and would report the subject
285
+ // as its own supplier.
286
+ if (isSource === isTarget)
287
+ continue;
288
+ const otherId = isSource ? ends.target : ends.source;
289
+ const other = byId.get(otherId);
290
+ if (!other)
291
+ continue;
292
+ const side = isSource ? 'supplier' : 'consumer';
293
+ const [, otherY] = centreOf(other.elementBound);
294
+ // `y` grows downwards, so "higher on the map" is a SMALLER y. A supplier
295
+ // is expected below the subject, a consumer above it — but only on a
296
+ // board whose framework CLAIMED that axis says something (`geometry`).
297
+ // Two BPMN tasks side by side contradict nothing.
298
+ const contradictsGeometry = relation.geometry !== 'vertical'
299
+ ? false
300
+ : side === 'supplier'
301
+ ? otherY < subjectY - GEOMETRY_EPSILON
302
+ : otherY > subjectY + GEOMETRY_EPSILON;
303
+ const ownEndLabel = endLabelOf(edge, isSource ? 'source' : 'target');
304
+ const otherEndLabel = endLabelOf(edge, isSource ? 'target' : 'source');
305
+ relations.push({
306
+ edgeId: edge.id,
307
+ relationRole: relation.edgeRole,
308
+ otherId,
309
+ otherName: readName(other, profile),
310
+ side,
311
+ contradictsGeometry,
312
+ ...(ownEndLabel !== undefined ? { ownEndLabel } : {}),
313
+ ...(otherEndLabel !== undefined ? { otherEndLabel } : {}),
314
+ });
315
+ }
270
316
  }
271
317
  return relations;
272
318
  }
@@ -0,0 +1,66 @@
1
+ import { Bound } from '../../global/gfx/index.js';
2
+ import type { BlockStdScope } from '../../std/index.js';
3
+ /** What {@link recordAction} saw a creation action ask the surface for. */
4
+ export interface RecordedAction {
5
+ /**
6
+ * One plain record per element the action added, in creation order, holding
7
+ * the props it passed. `id` is the recording's own (`el-0`, `el-1`, …), not
8
+ * an id any document will ever carry.
9
+ */
10
+ records: Record<string, unknown>[];
11
+ /**
12
+ * The union of the records' `xywh`, relative to the fake viewport's centre —
13
+ * which sits at the ORIGIN, so this is the footprint the same action would
14
+ * draw around whatever centre a real viewport has. `null` when no record
15
+ * carries a box at all.
16
+ */
17
+ bound: Bound | null;
18
+ /**
19
+ * The name of the tool the action armed, other than the default one it may
20
+ * return to after placing — `connector` for a command that lets the user
21
+ * DRAW a relation. Such a command creates nothing on its own and must be
22
+ * declared `kind: 'tool'`, or the placement tool wraps it and cancels the
23
+ * drawing it armed. `null` when nothing was armed.
24
+ */
25
+ armedTool: string | null;
26
+ /**
27
+ * The OPTIONS the action armed that tool with — where a typed edge's `role`
28
+ * lives, since a command that arms the connector tool creates nothing and
29
+ * therefore stamps nothing on any record. `null` when nothing was armed.
30
+ */
31
+ armedToolOptions: Record<string, unknown> | null;
32
+ }
33
+ /** Hook applied to a finished record before it is kept. See {@link recordAction}. */
34
+ export type RecordEncoder = (record: Record<string, unknown>) => void;
35
+ export interface RecordActionOptions {
36
+ /**
37
+ * The editor the recording is being run FOR. Its `TranslationProvider`, and
38
+ * nothing else from it, is handed to the action, so the seeds the action
39
+ * writes come out in the user's language. Without one, the action writes its
40
+ * English fallbacks.
41
+ */
42
+ host?: BlockStdScope;
43
+ /**
44
+ * Last chance to rewrite a record before it is kept — how a caller that needs
45
+ * a SNAPSHOT converts the `Y.Text` / `Y.Map` props into their serialized
46
+ * form. A caller that only measures the drawing passes nothing.
47
+ */
48
+ encode?: RecordEncoder;
49
+ }
50
+ /**
51
+ * Run a creation action against a recording fake, and hand back what it asked
52
+ * the surface for — so a framework's artefact can be measured, previewed or
53
+ * serialized without ever touching a document.
54
+ *
55
+ * The `std` handed to `run` answers the members placement actions actually
56
+ * touch and THROWS on anything else, so an unsupported action fails loudly
57
+ * instead of yielding a half-empty drawing. Callers that can carry on without a
58
+ * measure catch it; callers that cannot (a template derived at build time) let
59
+ * it through.
60
+ *
61
+ * Extracted from `snapshotFromAction` (`@labre/affine-gfx-template`), which is
62
+ * still its first caller: the placement tool needs the same recording and lives
63
+ * in the toolbar widget, which the template package depends ON — so the
64
+ * recording had to move down here, where both can reach it.
65
+ */
66
+ export declare function recordAction(run: (std: BlockStdScope) => void, { host, encode }?: RecordActionOptions): RecordedAction;
@@ -0,0 +1,145 @@
1
+ import { Bound } from '../../global/gfx/index.js';
2
+ import { TranslationProvider } from '../../affine-shared/services/index.js';
3
+ import { generateKeyBetween, GfxControllerIdentifier } from '../../std/gfx/index.js';
4
+ import { EdgelessCRUDIdentifier } from './crud-extension.js';
5
+ /**
6
+ * Run a creation action against a recording fake, and hand back what it asked
7
+ * the surface for — so a framework's artefact can be measured, previewed or
8
+ * serialized without ever touching a document.
9
+ *
10
+ * The `std` handed to `run` answers the members placement actions actually
11
+ * touch and THROWS on anything else, so an unsupported action fails loudly
12
+ * instead of yielding a half-empty drawing. Callers that can carry on without a
13
+ * measure catch it; callers that cannot (a template derived at build time) let
14
+ * it through.
15
+ *
16
+ * Extracted from `snapshotFromAction` (`@labre/affine-gfx-template`), which is
17
+ * still its first caller: the placement tool needs the same recording and lives
18
+ * in the toolbar widget, which the template package depends ON — so the
19
+ * recording had to move down here, where both can reach it.
20
+ */
21
+ export function recordAction(run, { host, encode } = {}) {
22
+ const elements = new Map();
23
+ let n = 0;
24
+ let lastIndex = null;
25
+ const nextIndex = () => (lastIndex = generateKeyBetween(lastIndex, null));
26
+ const addElement = (props) => {
27
+ const id = `el-${n++}`;
28
+ const record = {};
29
+ for (const [key, value] of Object.entries(props)) {
30
+ if (value !== undefined)
31
+ record[key] = value;
32
+ }
33
+ record['id'] = id;
34
+ encode?.(record);
35
+ if (record['index'] === undefined)
36
+ record['index'] = nextIndex();
37
+ // The model members an action reads back off `getElementById`, kept
38
+ // non-enumerable so they never leak into a snapshot built from the record.
39
+ Object.defineProperties(record, {
40
+ group: { value: null },
41
+ deserializedXYWH: {
42
+ get: () => typeof record['xywh'] === 'string'
43
+ ? Bound.deserialize(record['xywh'])
44
+ : null,
45
+ },
46
+ });
47
+ elements.set(id, record);
48
+ return id;
49
+ };
50
+ const records = () => [...elements.values()];
51
+ let armedTool = null;
52
+ let armedToolOptions = null;
53
+ const setTool = (tool, options) => {
54
+ const name = typeof tool === 'string' ? tool : tool?.toolName;
55
+ if (name && name !== 'default') {
56
+ armedTool = name;
57
+ armedToolOptions = options ?? null;
58
+ }
59
+ };
60
+ const surface = {
61
+ addElement,
62
+ getElementById: (id) => elements.get(id) ?? null,
63
+ getElementsByType: (type) => records().filter(el => el['type'] === type),
64
+ get elementModels() {
65
+ return records();
66
+ },
67
+ };
68
+ const gfx = {
69
+ surface,
70
+ // The centre at the ORIGIN is what makes `bound` a footprint rather than a
71
+ // position: an action that creates "at the viewport centre" records a box
72
+ // around (0, 0), which is exactly the offset to re-apply around a real one.
73
+ viewport: { centerX: 0, centerY: 0, zoom: 1, center: { x: 0, y: 0 } },
74
+ doc: { captureSync: () => { } },
75
+ selection: { set: () => { }, selectedElements: [] },
76
+ tool: { setTool },
77
+ layer: {
78
+ generateIndex: () => nextIndex(),
79
+ getReorderedIndex: (_model, direction) => {
80
+ const sorted = records()
81
+ .map(el => String(el['index']))
82
+ .sort();
83
+ return direction === 'back'
84
+ ? generateKeyBetween(null, sorted[0] ?? null)
85
+ : generateKeyBetween(sorted[sorted.length - 1] ?? null, null);
86
+ },
87
+ get canvasElements() {
88
+ return records();
89
+ },
90
+ },
91
+ std: null,
92
+ };
93
+ const crud = {
94
+ addElement: (type, props) => addElement({ ...props, type }),
95
+ };
96
+ const std = {
97
+ get: (identifier) => {
98
+ if (identifier === GfxControllerIdentifier)
99
+ return gfx;
100
+ if (identifier === EdgelessCRUDIdentifier)
101
+ return crud;
102
+ throw new Error(`recordAction: unsupported service "${identifier?.identifierName ?? String(identifier)}"`);
103
+ },
104
+ getOptional: (identifier) => identifier === TranslationProvider
105
+ ? host?.getOptional(TranslationProvider)
106
+ : undefined,
107
+ command: {
108
+ // Really run the command, so a group built by `createGroupCommand` is
109
+ // whatever that command says a group is — no second definition here.
110
+ exec: (cmd, payload) => {
111
+ let out;
112
+ cmd({ std: gfx.std, ...payload }, r => {
113
+ out = r;
114
+ });
115
+ return [{}, out ?? {}];
116
+ },
117
+ },
118
+ store: {
119
+ readonly: false,
120
+ captureSync: () => { },
121
+ id: 'doc:template',
122
+ workspace: { meta: { getDocMeta: () => undefined } },
123
+ },
124
+ };
125
+ gfx.std = std;
126
+ run(gfx.std);
127
+ return {
128
+ records: records(),
129
+ bound: uniteBounds(records()),
130
+ armedTool,
131
+ armedToolOptions,
132
+ };
133
+ }
134
+ /** The union of whatever boxes the records carry. */
135
+ function uniteBounds(records) {
136
+ let union = null;
137
+ for (const record of records) {
138
+ const xywh = record['xywh'];
139
+ if (typeof xywh !== 'string')
140
+ continue;
141
+ const bound = Bound.deserialize(xywh);
142
+ union = union ? union.unite(bound) : bound;
143
+ }
144
+ return union;
145
+ }