@formicoidea/labre-core 0.31.0 → 0.32.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.
- package/dist/_pkgs/affine-block-callout/callout-block.d.ts +6 -0
- package/dist/_pkgs/affine-block-callout/callout-block.js +25 -3
- package/dist/_pkgs/affine-block-callout/callout-keymap.js +59 -19
- package/dist/_pkgs/affine-block-callout/commands/callout-to-paragraph.d.ts +20 -0
- package/dist/_pkgs/affine-block-callout/commands/callout-to-paragraph.js +60 -0
- package/dist/_pkgs/affine-block-callout/commands/split-callout.d.ts +17 -0
- package/dist/_pkgs/affine-block-callout/commands/split-callout.js +42 -0
- package/dist/_pkgs/affine-block-callout/configs/slash-menu.js +9 -6
- package/dist/_pkgs/affine-block-callout/emoji-margin.d.ts +9 -0
- package/dist/_pkgs/affine-block-callout/emoji-margin.js +36 -0
- package/dist/_pkgs/affine-block-callout/emoji-menu.d.ts +5 -1
- package/dist/_pkgs/affine-block-callout/emoji-menu.js +5 -0
- package/dist/_pkgs/affine-block-code/code-block.d.ts +14 -0
- package/dist/_pkgs/affine-block-code/code-block.js +44 -6
- package/dist/_pkgs/affine-block-code/code-toolbar/components/code-toolbar.d.ts +2 -0
- package/dist/_pkgs/affine-block-code/code-toolbar/components/code-toolbar.js +23 -14
- package/dist/_pkgs/affine-block-code/code-toolbar/components/more-menu.d.ts +16 -0
- package/dist/_pkgs/affine-block-code/code-toolbar/components/more-menu.js +93 -0
- package/dist/_pkgs/affine-block-code/code-toolbar/config.js +52 -5
- package/dist/_pkgs/affine-block-code/effects.d.ts +2 -0
- package/dist/_pkgs/affine-block-code/effects.js +2 -0
- package/dist/_pkgs/affine-block-code/highlight/affine-code-unit.js +6 -1
- package/dist/_pkgs/affine-block-code/index.d.ts +1 -0
- package/dist/_pkgs/affine-block-code/index.js +1 -0
- package/dist/_pkgs/affine-block-code/line-numbers.d.ts +25 -0
- package/dist/_pkgs/affine-block-code/line-numbers.js +27 -0
- package/dist/_pkgs/affine-block-code/styles.js +31 -0
- package/dist/_pkgs/affine-block-data-view/data-view-block.js +1 -0
- package/dist/_pkgs/affine-block-database/components/title/index.js +4 -1
- package/dist/_pkgs/affine-block-database/configs/slash-menu.js +28 -1
- package/dist/_pkgs/affine-block-database/database-block.js +13 -0
- package/dist/_pkgs/affine-block-database/properties/paste-url.d.ts +24 -0
- package/dist/_pkgs/affine-block-database/properties/paste-url.js +98 -0
- package/dist/_pkgs/affine-block-database/properties/rich-text/cell-renderer.js +9 -19
- package/dist/_pkgs/affine-block-database/properties/title/text.js +20 -25
- package/dist/_pkgs/affine-block-database/views/index.js +1 -0
- package/dist/_pkgs/affine-block-edgeless-text/edgeless-text-block.js +10 -0
- package/dist/_pkgs/affine-block-edgeless-text/edgeless-toolbar/config.d.ts +3 -0
- package/dist/_pkgs/affine-block-edgeless-text/edgeless-toolbar/config.js +48 -1
- package/dist/_pkgs/affine-block-edgeless-text/edgeless-toolbar/font-size.d.ts +17 -0
- package/dist/_pkgs/affine-block-edgeless-text/edgeless-toolbar/font-size.js +24 -0
- package/dist/_pkgs/affine-block-embed-doc/common/doc-trashed.d.ts +9 -0
- package/dist/_pkgs/affine-block-embed-doc/common/doc-trashed.js +10 -0
- package/dist/_pkgs/affine-block-embed-doc/embed-linked-doc-block/embed-linked-doc-block.js +8 -4
- package/dist/_pkgs/affine-block-embed-doc/embed-synced-doc-block/embed-synced-doc-block.d.ts +4 -0
- package/dist/_pkgs/affine-block-embed-doc/embed-synced-doc-block/embed-synced-doc-block.js +22 -3
- package/dist/_pkgs/affine-block-frame/frame-manager.d.ts +13 -0
- package/dist/_pkgs/affine-block-frame/frame-manager.js +32 -2
- package/dist/_pkgs/affine-block-latex/styles.js +6 -1
- package/dist/_pkgs/affine-block-note/note-edgeless-block.d.ts +9 -0
- package/dist/_pkgs/affine-block-note/note-edgeless-block.js +29 -1
- package/dist/_pkgs/affine-block-root/commands/pivot-commands.d.ts +37 -0
- package/dist/_pkgs/affine-block-root/commands/pivot-commands.js +168 -0
- package/dist/_pkgs/affine-block-root/commands/reading-commands.d.ts +23 -0
- package/dist/_pkgs/affine-block-root/commands/reading-commands.js +107 -0
- package/dist/_pkgs/affine-block-root/commands/tag-commands.d.ts +47 -0
- package/dist/_pkgs/affine-block-root/commands/tag-commands.js +159 -0
- package/dist/_pkgs/affine-block-root/configs/toolbar.d.ts +1 -0
- package/dist/_pkgs/affine-block-root/edgeless/configs/toolbar/more.js +9 -2
- package/dist/_pkgs/affine-block-root/edgeless/configs/toolbar/render-linked-doc.js +1 -1
- package/dist/_pkgs/affine-block-root/edgeless/edgeless-keyboard.js +26 -1
- package/dist/_pkgs/affine-block-root/edgeless/edgeless-root-block.js +11 -2
- package/dist/_pkgs/affine-block-root/edgeless/edgeless-root-service.js +14 -0
- package/dist/_pkgs/affine-block-root/edgeless/index.d.ts +1 -0
- package/dist/_pkgs/affine-block-root/edgeless/index.js +1 -0
- package/dist/_pkgs/affine-block-root/edgeless/reserved-keys.d.ts +21 -0
- package/dist/_pkgs/affine-block-root/edgeless/reserved-keys.js +34 -0
- package/dist/_pkgs/affine-block-root/edgeless/utils/clone-utils.d.ts +7 -1
- package/dist/_pkgs/affine-block-root/edgeless/utils/clone-utils.js +11 -2
- package/dist/_pkgs/affine-block-root/index.d.ts +4 -1
- package/dist/_pkgs/affine-block-root/index.js +4 -1
- package/dist/_pkgs/affine-block-root/keyboard/commands.d.ts +2 -0
- package/dist/_pkgs/affine-block-root/keyboard/commands.js +147 -0
- package/dist/_pkgs/affine-block-root/view.js +13 -4
- package/dist/_pkgs/affine-block-surface/commands/reassociate-connectors.js +0 -1
- package/dist/_pkgs/affine-block-surface/effects.js +6 -0
- package/dist/_pkgs/affine-block-surface/element-model/index.d.ts +5 -2
- package/dist/_pkgs/affine-block-surface/element-model/index.js +4 -2
- package/dist/_pkgs/affine-block-surface/extensions/audit.d.ts +107 -0
- package/dist/_pkgs/affine-block-surface/extensions/audit.js +472 -0
- package/dist/_pkgs/affine-block-surface/extensions/crud-extension.d.ts +14 -0
- package/dist/_pkgs/affine-block-surface/extensions/crud-extension.js +27 -0
- package/dist/_pkgs/affine-block-surface/extensions/editor-anchored-panel.d.ts +133 -0
- package/dist/_pkgs/affine-block-surface/extensions/editor-anchored-panel.js +326 -0
- package/dist/_pkgs/affine-block-surface/extensions/index.d.ts +13 -0
- package/dist/_pkgs/affine-block-surface/extensions/index.js +13 -0
- package/dist/_pkgs/affine-block-surface/extensions/map-quality-widget.d.ts +146 -0
- package/dist/_pkgs/affine-block-surface/extensions/map-quality-widget.js +528 -0
- package/dist/_pkgs/affine-block-surface/extensions/map-quality.d.ts +109 -0
- package/dist/_pkgs/affine-block-surface/extensions/map-quality.js +84 -0
- package/dist/_pkgs/affine-block-surface/extensions/reading-toolbar.d.ts +15 -0
- package/dist/_pkgs/affine-block-surface/extensions/reading-toolbar.js +158 -0
- package/dist/_pkgs/affine-block-surface/extensions/reading-widget.d.ts +145 -0
- package/dist/_pkgs/affine-block-surface/extensions/reading-widget.js +590 -0
- package/dist/_pkgs/affine-block-surface/extensions/reading.d.ts +494 -0
- package/dist/_pkgs/affine-block-surface/extensions/reading.js +767 -0
- package/dist/_pkgs/affine-block-surface/extensions/spotlight.d.ts +45 -0
- package/dist/_pkgs/affine-block-surface/extensions/spotlight.js +177 -0
- package/dist/_pkgs/affine-block-surface/extensions/tags-toolbar.d.ts +10 -0
- package/dist/_pkgs/affine-block-surface/extensions/tags-toolbar.js +295 -0
- package/dist/_pkgs/affine-block-surface/extensions/validation-toolbar.d.ts +27 -0
- package/dist/_pkgs/affine-block-surface/extensions/validation-toolbar.js +361 -0
- package/dist/_pkgs/affine-block-surface/extensions/validation.d.ts +1340 -0
- package/dist/_pkgs/affine-block-surface/extensions/validation.js +3009 -0
- package/dist/_pkgs/affine-block-surface/extensions/violation-detail-widget.d.ts +286 -0
- package/dist/_pkgs/affine-block-surface/extensions/violation-detail-widget.js +907 -0
- package/dist/_pkgs/affine-block-surface/extensions/violation-timeline.d.ts +80 -0
- package/dist/_pkgs/affine-block-surface/extensions/violation-timeline.js +123 -0
- package/dist/_pkgs/affine-block-surface/framework-background/def.d.ts +321 -0
- package/dist/_pkgs/affine-block-surface/framework-background/def.js +81 -0
- package/dist/_pkgs/affine-block-surface/framework-background/facts.d.ts +188 -0
- package/dist/_pkgs/affine-block-surface/framework-background/facts.js +284 -0
- package/dist/_pkgs/affine-block-surface/framework-background/index.d.ts +5 -0
- package/dist/_pkgs/affine-block-surface/framework-background/index.js +5 -0
- package/dist/_pkgs/affine-block-surface/framework-background/interaction.d.ts +12 -0
- package/dist/_pkgs/affine-block-surface/framework-background/interaction.js +24 -0
- package/dist/_pkgs/affine-block-surface/framework-background/labels.d.ts +59 -0
- package/dist/_pkgs/affine-block-surface/framework-background/labels.js +117 -0
- package/dist/_pkgs/affine-block-surface/framework-background/renderer.d.ts +8 -0
- package/dist/_pkgs/affine-block-surface/framework-background/renderer.js +238 -0
- package/dist/_pkgs/affine-block-surface/index.d.ts +1 -0
- package/dist/_pkgs/affine-block-surface/index.js +1 -0
- package/dist/_pkgs/affine-block-surface/renderer/canvas-renderer.d.ts +69 -3
- package/dist/_pkgs/affine-block-surface/renderer/canvas-renderer.js +333 -44
- package/dist/_pkgs/affine-block-surface/renderer/dom-renderer.js +18 -2
- package/dist/_pkgs/affine-block-surface/tool/default-tool.js +8 -0
- package/dist/_pkgs/affine-block-surface/utils/font.js +9 -3
- package/dist/_pkgs/affine-block-surface/view.d.ts +17 -0
- package/dist/_pkgs/affine-block-surface/view.js +57 -2
- package/dist/_pkgs/affine-block-table/selection-controller.d.ts +6 -0
- package/dist/_pkgs/affine-block-table/selection-controller.js +24 -1
- package/dist/_pkgs/affine-block-table/table-block.js +8 -2
- package/dist/_pkgs/affine-block-table/table-cell.js +5 -6
- package/dist/_pkgs/affine-block-table/table-keymap.d.ts +18 -0
- package/dist/_pkgs/affine-block-table/table-keymap.js +41 -0
- package/dist/_pkgs/affine-block-table/utils.d.ts +7 -0
- package/dist/_pkgs/affine-block-table/utils.js +12 -0
- package/dist/_pkgs/affine-block-table/view.js +2 -0
- package/dist/_pkgs/affine-components/caption/captioned-block-component.js +2 -1
- package/dist/_pkgs/affine-components/context-menu/button.d.ts +7 -0
- package/dist/_pkgs/affine-components/context-menu/button.js +7 -2
- package/dist/_pkgs/affine-components/context-menu/input.d.ts +4 -0
- package/dist/_pkgs/affine-components/context-menu/input.js +12 -0
- package/dist/_pkgs/affine-components/context-menu/menu-all.d.ts +2 -0
- package/dist/_pkgs/affine-components/context-menu/menu-renderer.js +8 -1
- package/dist/_pkgs/affine-components/context-menu/sub-menu.js +3 -0
- package/dist/_pkgs/affine-components/highlight-dropdown-menu/highlight-duotone-icon.js +8 -8
- package/dist/_pkgs/affine-components/highlight-dropdown-menu/text-duotone-icon.js +11 -11
- package/dist/_pkgs/affine-components/icon-picker/affine-icon-picker-panel.d.ts +28 -0
- package/dist/_pkgs/affine-components/icon-picker/affine-icon-picker-panel.js +231 -0
- package/dist/_pkgs/affine-components/icon-picker/emoji-data.d.ts +40 -0
- package/dist/_pkgs/affine-components/icon-picker/emoji-data.js +99 -0
- package/dist/_pkgs/affine-components/icon-picker/emoji-picker-panel.d.ts +32 -0
- package/dist/_pkgs/affine-components/icon-picker/emoji-picker-panel.js +276 -0
- package/dist/_pkgs/affine-components/icon-picker/icon-data.d.ts +34 -0
- package/dist/_pkgs/affine-components/icon-picker/icon-data.js +83 -0
- package/dist/_pkgs/affine-components/icon-picker/icon-picker.d.ts +39 -0
- package/dist/_pkgs/affine-components/icon-picker/icon-picker.js +233 -0
- package/dist/_pkgs/affine-components/icon-picker/index.d.ts +8 -0
- package/dist/_pkgs/affine-components/icon-picker/index.js +15 -0
- package/dist/_pkgs/affine-components/icon-picker/recent-store.d.ts +8 -0
- package/dist/_pkgs/affine-components/icon-picker/recent-store.js +41 -0
- package/dist/_pkgs/affine-components/icon-picker/styles.d.ts +5 -0
- package/dist/_pkgs/affine-components/icon-picker/styles.js +166 -0
- package/dist/_pkgs/affine-components/icon-picker/types.d.ts +22 -0
- package/dist/_pkgs/affine-components/icon-picker/types.js +10 -0
- package/dist/_pkgs/affine-components/icons/text.js +426 -426
- package/dist/_pkgs/affine-components/open-doc-dropdown-menu/dropdown-menu.d.ts +1 -0
- package/dist/_pkgs/affine-components/portal/portal.d.ts +1 -1
- package/dist/_pkgs/affine-components/toolbar/menu-button.js +1 -0
- package/dist/_pkgs/affine-components/toolbar/toolbar.js +11 -10
- package/dist/_pkgs/affine-foundation/view.js +11 -2
- package/dist/_pkgs/affine-gfx-brush/index.d.ts +1 -0
- package/dist/_pkgs/affine-gfx-brush/index.js +1 -0
- package/dist/_pkgs/affine-gfx-brush/renderer/dom/brush.d.ts +1 -0
- package/dist/_pkgs/affine-gfx-brush/renderer/dom/brush.js +11 -0
- package/dist/_pkgs/affine-gfx-brush/renderer/dom/highlighter.d.ts +1 -0
- package/dist/_pkgs/affine-gfx-brush/renderer/dom/highlighter.js +11 -0
- package/dist/_pkgs/affine-gfx-brush/renderer/dom/index.d.ts +2 -0
- package/dist/_pkgs/affine-gfx-brush/renderer/dom/index.js +2 -0
- package/dist/_pkgs/affine-gfx-brush/renderer/dom/shared.d.ts +14 -0
- package/dist/_pkgs/affine-gfx-brush/renderer/dom/shared.js +54 -0
- package/dist/_pkgs/affine-gfx-brush/renderer/index.d.ts +1 -0
- package/dist/_pkgs/affine-gfx-brush/renderer/index.js +4 -0
- package/dist/_pkgs/affine-gfx-brush/view.d.ts +14 -0
- package/dist/_pkgs/affine-gfx-brush/view.js +29 -3
- package/dist/_pkgs/affine-gfx-connector/connector-manager.js +32 -6
- package/dist/_pkgs/affine-gfx-connector/connector-tool.d.ts +7 -0
- package/dist/_pkgs/affine-gfx-connector/connector-tool.js +2 -1
- package/dist/_pkgs/affine-gfx-connector/direction/direction-reveal.d.ts +123 -0
- package/dist/_pkgs/affine-gfx-connector/direction/direction-reveal.js +281 -0
- package/dist/_pkgs/affine-gfx-connector/direction/direction-widget.d.ts +65 -0
- package/dist/_pkgs/affine-gfx-connector/direction/direction-widget.js +395 -0
- package/dist/_pkgs/affine-gfx-connector/direction/index.d.ts +4 -0
- package/dist/_pkgs/affine-gfx-connector/direction/index.js +4 -0
- package/dist/_pkgs/affine-gfx-connector/direction/invert-direction.d.ts +72 -0
- package/dist/_pkgs/affine-gfx-connector/direction/invert-direction.js +187 -0
- package/dist/_pkgs/affine-gfx-connector/direction/typed-edge.d.ts +69 -0
- package/dist/_pkgs/affine-gfx-connector/direction/typed-edge.js +66 -0
- package/dist/_pkgs/affine-gfx-connector/effects.d.ts +2 -0
- package/dist/_pkgs/affine-gfx-connector/effects.js +2 -0
- package/dist/_pkgs/affine-gfx-connector/element-renderer/connector-dom/index.js +78 -41
- package/dist/_pkgs/affine-gfx-connector/index.d.ts +1 -0
- package/dist/_pkgs/affine-gfx-connector/index.js +1 -0
- package/dist/_pkgs/affine-gfx-connector/toolbar/config.d.ts +50 -0
- package/dist/_pkgs/affine-gfx-connector/toolbar/config.js +67 -1
- package/dist/_pkgs/affine-gfx-connector/view.js +16 -0
- package/dist/_pkgs/affine-gfx-group/command/group-api.js +150 -62
- package/dist/_pkgs/affine-gfx-group/text/edgeless-group-title-editor.js +4 -1
- package/dist/_pkgs/affine-gfx-pointer/tools/pan-tool.d.ts +16 -0
- package/dist/_pkgs/affine-gfx-pointer/tools/pan-tool.js +102 -32
- package/dist/_pkgs/affine-gfx-shape/commands.d.ts +2 -0
- package/dist/_pkgs/affine-gfx-shape/commands.js +33 -0
- package/dist/_pkgs/affine-gfx-shape/element-renderer/shape-dom/index.js +48 -19
- package/dist/_pkgs/affine-gfx-shape/index.d.ts +1 -1
- package/dist/_pkgs/affine-gfx-shape/index.js +1 -1
- package/dist/_pkgs/affine-gfx-shape/text/edgeless-shape-text-editor.d.ts +26 -0
- package/dist/_pkgs/affine-gfx-shape/text/edgeless-shape-text-editor.js +124 -13
- package/dist/_pkgs/affine-gfx-shape/view.js +3 -3
- package/dist/_pkgs/affine-gfx-template/toolbar/template-tool-button.d.ts +2 -0
- package/dist/_pkgs/affine-gfx-template/toolbar/template-tool-button.js +18 -1
- package/dist/_pkgs/affine-gfx-text/edgeless-text-editor.js +9 -5
- package/dist/_pkgs/affine-inline-latex/command.js +46 -26
- package/dist/_pkgs/affine-inline-latex/latex-node/latex-node.d.ts +10 -0
- package/dist/_pkgs/affine-inline-latex/latex-node/latex-node.js +23 -0
- package/dist/_pkgs/affine-inline-link/link-node/affine-link.js +4 -1
- package/dist/_pkgs/affine-inline-preset/adapters/html/html-inline.d.ts +3 -0
- package/dist/_pkgs/affine-inline-preset/adapters/html/html-inline.js +29 -1
- package/dist/_pkgs/affine-model/blocks/code/code-model.d.ts +1 -0
- package/dist/_pkgs/affine-model/blocks/code/code-model.js +1 -0
- package/dist/_pkgs/affine-model/elements/connector/connector.js +24 -0
- package/dist/_pkgs/affine-model/elements/edgy/board.d.ts +32 -0
- package/dist/_pkgs/affine-model/elements/edgy/board.js +112 -0
- package/dist/_pkgs/affine-model/elements/edgy/facets.d.ts +12 -0
- package/dist/_pkgs/affine-model/elements/edgy/facets.js +25 -1
- package/dist/_pkgs/affine-model/elements/edgy/index.d.ts +1 -0
- package/dist/_pkgs/affine-model/elements/edgy/index.js +1 -0
- package/dist/_pkgs/affine-model/elements/framework-background/background.d.ts +42 -0
- package/dist/_pkgs/affine-model/elements/framework-background/background.js +42 -0
- package/dist/_pkgs/affine-model/elements/framework-background/index.d.ts +1 -0
- package/dist/_pkgs/affine-model/elements/framework-background/index.js +1 -0
- package/dist/_pkgs/affine-model/elements/index.d.ts +3 -1
- package/dist/_pkgs/affine-model/elements/index.js +1 -0
- package/dist/_pkgs/affine-model/elements/mindmap/mindmap.js +8 -3
- package/dist/_pkgs/affine-model/elements/mindmap/style.d.ts +10 -0
- package/dist/_pkgs/affine-model/elements/mindmap/style.js +8 -0
- package/dist/_pkgs/affine-model/elements/wardley/wardley.d.ts +21 -29
- package/dist/_pkgs/affine-model/elements/wardley/wardley.js +41 -48
- package/dist/_pkgs/affine-shared/adapters/markdown/delta-converter.d.ts +6 -1
- package/dist/_pkgs/affine-shared/adapters/markdown/delta-converter.js +160 -2
- package/dist/_pkgs/affine-shared/adapters/markdown/markdown.js +5 -1
- package/dist/_pkgs/affine-shared/adapters/types/delta-converter.d.ts +1 -0
- package/dist/_pkgs/affine-shared/adapters/utils/color.d.ts +24 -0
- package/dist/_pkgs/affine-shared/adapters/utils/color.js +280 -0
- package/dist/_pkgs/affine-shared/adapters/utils/index.d.ts +1 -0
- package/dist/_pkgs/affine-shared/adapters/utils/index.js +1 -0
- package/dist/_pkgs/affine-shared/commands/block-crud/get-selected-blocks.js +10 -2
- package/dist/_pkgs/affine-shared/services/audit-service.d.ts +300 -0
- package/dist/_pkgs/affine-shared/services/audit-service.js +228 -0
- package/dist/_pkgs/affine-shared/services/edit-props-store.d.ts +7 -0
- package/dist/_pkgs/affine-shared/services/edit-props-store.js +11 -0
- package/dist/_pkgs/affine-shared/services/font-loader/font-loader-service.d.ts +26 -1
- package/dist/_pkgs/affine-shared/services/font-loader/font-loader-service.js +124 -7
- package/dist/_pkgs/affine-shared/services/index.d.ts +5 -0
- package/dist/_pkgs/affine-shared/services/index.js +5 -0
- package/dist/_pkgs/affine-shared/services/pivot-materiality-publisher.d.ts +129 -0
- package/dist/_pkgs/affine-shared/services/pivot-materiality-publisher.js +311 -0
- package/dist/_pkgs/affine-shared/services/pivot-properties-service.d.ts +217 -0
- package/dist/_pkgs/affine-shared/services/pivot-properties-service.js +114 -0
- package/dist/_pkgs/affine-shared/services/telemetry-service/code-block.d.ts +1 -1
- package/dist/_pkgs/affine-shared/services/telemetry-service/lifecycle.d.ts +182 -0
- package/dist/_pkgs/affine-shared/services/telemetry-service/telemetry-service.d.ts +2 -2
- package/dist/_pkgs/affine-shared/services/telemetry-service/types.d.ts +6 -1
- package/dist/_pkgs/affine-shared/services/toolbar-service/action.d.ts +10 -0
- package/dist/_pkgs/affine-shared/services/toolbar-service/index.d.ts +1 -0
- package/dist/_pkgs/affine-shared/services/toolbar-service/index.js +1 -0
- package/dist/_pkgs/affine-shared/services/toolbar-service/layout.d.ts +134 -0
- package/dist/_pkgs/affine-shared/services/toolbar-service/layout.js +146 -0
- package/dist/_pkgs/affine-shared/services/translation-service/index.d.ts +68 -0
- package/dist/_pkgs/affine-shared/services/translation-service/index.js +39 -0
- package/dist/_pkgs/affine-shared/services/universe-tag-defs-service.d.ts +155 -0
- package/dist/_pkgs/affine-shared/services/universe-tag-defs-service.js +254 -0
- package/dist/_pkgs/affine-shared/utils/dom/point-to-range.d.ts +4 -0
- package/dist/_pkgs/affine-shared/utils/dom/point-to-range.js +58 -2
- package/dist/_pkgs/affine-shared/utils/dom/viewport.d.ts +60 -0
- package/dist/_pkgs/affine-shared/utils/dom/viewport.js +58 -0
- package/dist/_pkgs/affine-shared/utils/print-to-pdf.d.ts +21 -0
- package/dist/_pkgs/affine-shared/utils/print-to-pdf.js +166 -32
- package/dist/_pkgs/affine-shared/utils/zod-schema.d.ts +7 -0
- package/dist/_pkgs/affine-shared/utils/zod-schema.js +27 -1
- package/dist/_pkgs/affine-widget-drag-handle/watchers/edgeless-watcher.d.ts +19 -10
- package/dist/_pkgs/affine-widget-drag-handle/watchers/edgeless-watcher.js +122 -23
- package/dist/_pkgs/affine-widget-drag-handle/watchers/pointer-event-watcher.d.ts +2 -0
- package/dist/_pkgs/affine-widget-drag-handle/watchers/pointer-event-watcher.js +25 -4
- package/dist/_pkgs/affine-widget-edgeless-selected-rect/auto-complete-panel.js +10 -5
- package/dist/_pkgs/affine-widget-edgeless-selected-rect/edgeless-auto-complete.d.ts +15 -1
- package/dist/_pkgs/affine-widget-edgeless-selected-rect/edgeless-auto-complete.js +37 -32
- package/dist/_pkgs/affine-widget-edgeless-selected-rect/edgeless-element-link.js +5 -4
- package/dist/_pkgs/affine-widget-edgeless-selected-rect/edgeless-selected-rect.js +19 -9
- package/dist/_pkgs/affine-widget-edgeless-selected-rect/utils.d.ts +16 -2
- package/dist/_pkgs/affine-widget-edgeless-selected-rect/utils.js +19 -2
- package/dist/_pkgs/affine-widget-edgeless-toolbar/index.d.ts +1 -0
- package/dist/_pkgs/affine-widget-edgeless-toolbar/index.js +1 -0
- package/dist/_pkgs/affine-widget-edgeless-toolbar/menu/command-menu.d.ts +38 -0
- package/dist/_pkgs/affine-widget-edgeless-toolbar/menu/command-menu.js +99 -0
- package/dist/_pkgs/affine-widget-frame-title/edgeless-frame-title-editor.js +4 -1
- package/dist/_pkgs/affine-widget-keyboard-toolbar/icons.js +98 -98
- package/dist/_pkgs/affine-widget-linked-doc/linked-doc-popover.js +2 -15
- package/dist/_pkgs/affine-widget-linked-doc/transformers/markdown.d.ts +10 -1
- package/dist/_pkgs/affine-widget-linked-doc/transformers/markdown.js +133 -6
- package/dist/_pkgs/affine-widget-linked-doc/transformers/utils.d.ts +10 -0
- package/dist/_pkgs/affine-widget-linked-doc/transformers/utils.js +120 -3
- package/dist/_pkgs/affine-widget-linked-doc/utils.d.ts +12 -0
- package/dist/_pkgs/affine-widget-linked-doc/utils.js +33 -0
- package/dist/_pkgs/affine-widget-remote-selection/edgeless/index.js +6 -4
- package/dist/_pkgs/affine-widget-slash-menu/slash-menu-popover.js +8 -4
- package/dist/_pkgs/affine-widget-slash-menu/utils.d.ts +9 -0
- package/dist/_pkgs/affine-widget-slash-menu/utils.js +24 -0
- package/dist/_pkgs/affine-widget-toolbar/toolbar.d.ts +6 -0
- package/dist/_pkgs/affine-widget-toolbar/toolbar.js +34 -6
- package/dist/_pkgs/affine-widget-toolbar/utils.d.ts +146 -3
- package/dist/_pkgs/affine-widget-toolbar/utils.js +738 -56
- package/dist/_pkgs/data-view/core/common/property-menu.js +3 -16
- package/dist/_pkgs/data-view/core/component/tags/multi-tag-select.d.ts +4 -0
- package/dist/_pkgs/data-view/core/component/tags/multi-tag-select.js +28 -1
- package/dist/_pkgs/data-view/core/data-view.d.ts +3 -1
- package/dist/_pkgs/data-view/core/data-view.js +25 -3
- package/dist/_pkgs/data-view/core/detail/field.js +2 -2
- package/dist/_pkgs/data-view/core/detail/selection.d.ts +4 -2
- package/dist/_pkgs/data-view/core/detail/selection.js +23 -7
- package/dist/_pkgs/data-view/core/effect.js +2 -0
- package/dist/_pkgs/data-view/core/filter/eval.js +36 -23
- package/dist/_pkgs/data-view/core/filter/filter-fn/matcher.d.ts +7 -0
- package/dist/_pkgs/data-view/core/filter/filter-fn/matcher.js +12 -0
- package/dist/_pkgs/data-view/core/group-by/compare-date-keys.d.ts +11 -0
- package/dist/_pkgs/data-view/core/group-by/compare-date-keys.js +55 -0
- package/dist/_pkgs/data-view/core/group-by/define.d.ts +6 -0
- package/dist/_pkgs/data-view/core/group-by/define.js +114 -0
- package/dist/_pkgs/data-view/core/group-by/matcher.d.ts +7 -0
- package/dist/_pkgs/data-view/core/group-by/matcher.js +13 -0
- package/dist/_pkgs/data-view/core/group-by/renderer/boolean-group.js +11 -11
- package/dist/_pkgs/data-view/core/group-by/renderer/date-group.d.ts +9 -0
- package/dist/_pkgs/data-view/core/group-by/renderer/date-group.js +97 -0
- package/dist/_pkgs/data-view/core/group-by/setting.js +86 -7
- package/dist/_pkgs/data-view/core/group-by/trait.d.ts +34 -0
- package/dist/_pkgs/data-view/core/group-by/trait.js +106 -10
- package/dist/_pkgs/data-view/core/utils/menu-title.js +17 -17
- package/dist/_pkgs/data-view/property-presets/multi-select/cell-renderer.js +3 -1
- package/dist/_pkgs/data-view/property-presets/number/define.js +2 -1
- package/dist/_pkgs/data-view/property-presets/select/cell-renderer.js +3 -1
- package/dist/_pkgs/data-view/view-presets/calendar/calendar-view-manager.d.ts +70 -0
- package/dist/_pkgs/data-view/view-presets/calendar/calendar-view-manager.js +449 -0
- package/dist/_pkgs/data-view/view-presets/calendar/define.d.ts +10 -0
- package/dist/_pkgs/data-view/view-presets/calendar/define.js +27 -0
- package/dist/_pkgs/data-view/view-presets/calendar/effect.d.ts +1 -0
- package/dist/_pkgs/data-view/view-presets/calendar/effect.js +4 -0
- package/dist/_pkgs/data-view/view-presets/calendar/index.d.ts +6 -0
- package/dist/_pkgs/data-view/view-presets/calendar/index.js +6 -0
- package/dist/_pkgs/data-view/view-presets/calendar/layout.d.ts +37 -0
- package/dist/_pkgs/data-view/view-presets/calendar/layout.js +138 -0
- package/dist/_pkgs/data-view/view-presets/calendar/pc/actions.d.ts +7 -0
- package/dist/_pkgs/data-view/view-presets/calendar/pc/actions.js +68 -0
- package/dist/_pkgs/data-view/view-presets/calendar/pc/dnd.d.ts +32 -0
- package/dist/_pkgs/data-view/view-presets/calendar/pc/dnd.js +159 -0
- package/dist/_pkgs/data-view/view-presets/calendar/pc/effect.d.ts +1 -0
- package/dist/_pkgs/data-view/view-presets/calendar/pc/effect.js +7 -0
- package/dist/_pkgs/data-view/view-presets/calendar/pc/hit-test.d.ts +1 -0
- package/dist/_pkgs/data-view/view-presets/calendar/pc/hit-test.js +28 -0
- package/dist/_pkgs/data-view/view-presets/calendar/pc/styles.d.ts +1 -0
- package/dist/_pkgs/data-view/view-presets/calendar/pc/styles.js +707 -0
- package/dist/_pkgs/data-view/view-presets/calendar/pc/view.d.ts +89 -0
- package/dist/_pkgs/data-view/view-presets/calendar/pc/view.js +837 -0
- package/dist/_pkgs/data-view/view-presets/calendar/renderer.d.ts +2 -0
- package/dist/_pkgs/data-view/view-presets/calendar/renderer.js +8 -0
- package/dist/_pkgs/data-view/view-presets/calendar/source.d.ts +8 -0
- package/dist/_pkgs/data-view/view-presets/calendar/source.js +3 -0
- package/dist/_pkgs/data-view/view-presets/calendar/types.d.ts +79 -0
- package/dist/_pkgs/data-view/view-presets/calendar/types.js +1 -0
- package/dist/_pkgs/data-view/view-presets/convert.js +28 -0
- package/dist/_pkgs/data-view/view-presets/effect.js +2 -0
- package/dist/_pkgs/data-view/view-presets/index.d.ts +2 -0
- package/dist/_pkgs/data-view/view-presets/index.js +3 -0
- package/dist/_pkgs/data-view/view-presets/kanban/kanban-view-manager.js +3 -1
- package/dist/_pkgs/data-view/view-presets/kanban/mobile/cell.js +2 -2
- package/dist/_pkgs/data-view/view-presets/table/collapsed-state.d.ts +18 -0
- package/dist/_pkgs/data-view/view-presets/table/collapsed-state.js +36 -0
- package/dist/_pkgs/data-view/view-presets/table/mobile/cell.js +2 -2
- package/dist/_pkgs/data-view/view-presets/table/mobile/group.d.ts +11 -0
- package/dist/_pkgs/data-view/view-presets/table/mobile/group.js +87 -4
- package/dist/_pkgs/data-view/view-presets/table/pc/cell.d.ts +3 -0
- package/dist/_pkgs/data-view/view-presets/table/pc/cell.js +11 -2
- package/dist/_pkgs/data-view/view-presets/table/pc/controller/hotkeys.d.ts +1 -0
- package/dist/_pkgs/data-view/view-presets/table/pc/controller/hotkeys.js +39 -33
- package/dist/_pkgs/data-view/view-presets/table/pc/group.d.ts +10 -0
- package/dist/_pkgs/data-view/view-presets/table/pc/group.js +84 -5
- package/dist/_pkgs/data-view/view-presets/table/pc-virtual/controller/hotkeys.d.ts +1 -0
- package/dist/_pkgs/data-view/view-presets/table/pc-virtual/controller/hotkeys.js +39 -33
- package/dist/_pkgs/data-view/view-presets/table/pc-virtual/group/top/group-title.js +18 -18
- package/dist/_pkgs/data-view/view-presets/table/pc-virtual/row/cell.d.ts +3 -0
- package/dist/_pkgs/data-view/view-presets/table/pc-virtual/row/cell.js +8 -0
- package/dist/_pkgs/data-view/view-presets/table/table-view-manager.js +3 -1
- package/dist/_pkgs/data-view/view-presets/table/utils.d.ts +3 -0
- package/dist/_pkgs/data-view/view-presets/table/utils.js +16 -1
- package/dist/_pkgs/data-view/widget-presets/tools/presets/view-options/view-options.js +3 -1
- package/dist/_pkgs/global/gfx/curve.js +4 -3
- package/dist/_pkgs/std/clipboard/clipboard.js +13 -3
- package/dist/_pkgs/std/clipboard/utils.d.ts +5 -0
- package/dist/_pkgs/std/clipboard/utils.js +7 -0
- package/dist/_pkgs/std/event/dispatcher.js +27 -1
- package/dist/_pkgs/std/event/keymap.js +16 -6
- package/dist/_pkgs/std/extension/command-registry.d.ts +321 -0
- package/dist/_pkgs/std/extension/command-registry.js +233 -0
- package/dist/_pkgs/std/extension/dnd/index.d.ts +1 -1
- package/dist/_pkgs/std/extension/index.d.ts +2 -0
- package/dist/_pkgs/std/extension/index.js +2 -0
- package/dist/_pkgs/std/extension/translation-manifest.d.ts +49 -0
- package/dist/_pkgs/std/extension/translation-manifest.js +71 -0
- package/dist/_pkgs/std/gfx/index.d.ts +7 -3
- package/dist/_pkgs/std/gfx/index.js +6 -2
- package/dist/_pkgs/std/gfx/interactivity/gfx-view-event-handler.js +6 -1
- package/dist/_pkgs/std/gfx/interactivity/manager.d.ts +8 -0
- package/dist/_pkgs/std/gfx/interactivity/manager.js +18 -0
- package/dist/_pkgs/std/gfx/layer.d.ts +1 -1
- package/dist/_pkgs/std/gfx/layer.js +1 -2
- package/dist/_pkgs/std/gfx/model/surface/decorators/field.js +9 -0
- package/dist/_pkgs/std/gfx/model/surface/decorators/index.d.ts +2 -2
- package/dist/_pkgs/std/gfx/model/surface/decorators/index.js +2 -2
- package/dist/_pkgs/std/gfx/model/surface/decorators/local.d.ts +14 -0
- package/dist/_pkgs/std/gfx/model/surface/decorators/local.js +22 -0
- package/dist/_pkgs/std/gfx/model/surface/decorators/observer.d.ts +2 -0
- package/dist/_pkgs/std/gfx/model/surface/decorators/observer.js +40 -1
- package/dist/_pkgs/std/gfx/model/surface/element-model.d.ts +282 -0
- package/dist/_pkgs/std/gfx/model/surface/element-model.js +436 -25
- package/dist/_pkgs/std/gfx/model/surface/pivot.d.ts +48 -0
- package/dist/_pkgs/std/gfx/model/surface/pivot.js +34 -0
- package/dist/_pkgs/std/gfx/model/surface/role.d.ts +153 -0
- package/dist/_pkgs/std/gfx/model/surface/role.js +115 -0
- package/dist/_pkgs/std/gfx/model/surface/surface-model.d.ts +70 -0
- package/dist/_pkgs/std/gfx/model/surface/surface-model.js +304 -17
- package/dist/_pkgs/std/gfx/model/surface/tags.d.ts +77 -0
- package/dist/_pkgs/std/gfx/model/surface/tags.js +246 -0
- package/dist/_pkgs/std/gfx/perf.d.ts +10 -0
- package/dist/_pkgs/std/gfx/perf.js +30 -0
- package/dist/_pkgs/std/gfx/tool/tool-controller.d.ts +13 -0
- package/dist/_pkgs/std/gfx/tool/tool-controller.js +26 -0
- package/dist/_pkgs/std/gfx/viewport.d.ts +12 -0
- package/dist/_pkgs/std/gfx/viewport.js +19 -1
- package/dist/_pkgs/std/inline/services/event.d.ts +2 -0
- package/dist/_pkgs/std/inline/services/event.js +96 -21
- package/dist/_pkgs/std/utils/layer.js +2 -6
- package/dist/_pkgs/std/utils/tree.d.ts +14 -0
- package/dist/_pkgs/std/utils/tree.js +59 -8
- package/dist/_pkgs/std/view/element/gfx-block-component.js +23 -13
- package/dist/_pkgs/store/extension/workspace/workspace-meta.d.ts +10 -0
- package/dist/_pkgs/store/model/block/flat-sync-controller.js +2 -12
- package/dist/_pkgs/store/model/store/crud.js +7 -4
- package/dist/_pkgs/store/reactive/flat-native-y/index.d.ts +1 -1
- package/dist/_pkgs/store/reactive/flat-native-y/index.js +24 -2
- package/dist/commands.d.ts +58 -0
- package/dist/commands.js +66 -0
- package/dist/extensions/command-telemetry.d.ts +21 -0
- package/dist/extensions/command-telemetry.js +89 -0
- package/dist/extensions/store.d.ts +9 -4
- package/dist/extensions/store.js +27 -24
- package/dist/extensions/view.d.ts +9 -4
- package/dist/extensions/view.js +23 -8
- package/dist/flags.d.ts +98 -21
- package/dist/flags.js +103 -22
- package/dist/frameworks.d.ts +45 -0
- package/dist/frameworks.js +154 -0
- package/dist/schemas.d.ts +8 -5
- package/dist/schemas.js +28 -32
- package/dist/shortcuts.d.ts +16 -16
- package/dist/shortcuts.js +8 -36
- package/dist/translations.d.ts +56 -0
- package/dist/translations.js +112 -0
- package/package.json +16 -4
- package/dist/_pkgs/affine-block-root/keyboard/shortcuts.d.ts +0 -8
- package/dist/_pkgs/affine-block-root/keyboard/shortcuts.js +0 -48
- package/dist/_pkgs/affine-gfx-shape/shortcuts.d.ts +0 -6
- package/dist/_pkgs/affine-gfx-shape/shortcuts.js +0 -28
- package/dist/_pkgs/data-view/core/utils/cache.d.ts +0 -5
- package/dist/_pkgs/data-view/core/utils/cache.js +0 -28
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `map.audit` — the command the **Labre Assistant** invokes to audit a
|
|
3
|
+
* framework map (PF14.1).
|
|
4
|
+
*
|
|
5
|
+
* ## Where the work happens, and where it does not
|
|
6
|
+
*
|
|
7
|
+
* The library does no auditing. It collects the FACTS of the board, hands them
|
|
8
|
+
* to the host's `AuditProvider` with the criteria the frameworks declared, and
|
|
9
|
+
* files whatever comes back into a signal nothing on the real-time path reads.
|
|
10
|
+
* If no provider is registered the command refuses cleanly and levels 1 and 2
|
|
11
|
+
* are exactly as they were.
|
|
12
|
+
*
|
|
13
|
+
* ## Three gates, and they are independent on purpose
|
|
14
|
+
*
|
|
15
|
+
* 1. **`ai-audit`** (`packages/affine/all/src/flags.ts`) — the capability
|
|
16
|
+
* switch. Off, `AuditViewExtension` is never registered, so the command is
|
|
17
|
+
* absent from the registry, from both manifests and from the keymap. Same
|
|
18
|
+
* contract as a block flag: it gates TOOLING and never data — nothing this
|
|
19
|
+
* command touches is persisted, so switching it off cannot lose anything
|
|
20
|
+
* even in principle.
|
|
21
|
+
* 2. **The framework's own flag** — the criteria are registered by the
|
|
22
|
+
* flag-gated view extension (`AuditCriterionExtension`), so a disabled
|
|
23
|
+
* Wardley contributes no criterion and an audit has nothing to ask about.
|
|
24
|
+
* 3. **The provider** — absent, the command is still enumerable but refuses.
|
|
25
|
+
* Per ADR 0008, injected-provider presence is deliberately NOT an
|
|
26
|
+
* `Availability` member; its assigned fallback is "displayed available,
|
|
27
|
+
* `run` degrades". Making it a fourth availability value would have meant
|
|
28
|
+
* reopening a closed union for a state the caller can simply be told about.
|
|
29
|
+
*/
|
|
30
|
+
import { type AuditFacts, type AuditProgress, type AuditResult } from '../../affine-shared/services/index.js';
|
|
31
|
+
import type { AnyCommandDescriptor, BlockStdScope } from '../../std/index.js';
|
|
32
|
+
import { z } from 'zod';
|
|
33
|
+
/**
|
|
34
|
+
* `map.audit` takes no required parameter: the assistant audits what is
|
|
35
|
+
* selected. `criterionIds` narrows the run to a subset — an assistant
|
|
36
|
+
* re-checking one criterion after a fix should not pay for the other two — and
|
|
37
|
+
* an EMPTY array means "these zero criteria", i.e. nothing to do, never "all of
|
|
38
|
+
* them". Same reading as `pivot.bind`'s `elementIds`, for the same reason: a
|
|
39
|
+
* caller that filtered a list and came up empty must not have its request
|
|
40
|
+
* silently widened.
|
|
41
|
+
*/
|
|
42
|
+
export declare const auditParams: z.ZodObject<{
|
|
43
|
+
criterionIds: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
44
|
+
}, "strip", z.ZodTypeAny, {
|
|
45
|
+
criterionIds?: string[] | undefined;
|
|
46
|
+
}, {
|
|
47
|
+
criterionIds?: string[] | undefined;
|
|
48
|
+
}>;
|
|
49
|
+
export type AuditParams = z.infer<typeof auditParams>;
|
|
50
|
+
/**
|
|
51
|
+
* Everything the assistant is told about the board — **render-free** and
|
|
52
|
+
* serializable end to end (ADR 0006 § 5): plain objects, numbers and strings,
|
|
53
|
+
* no element model, no `Bound`, no `TemplateResult`, no function. A test round
|
|
54
|
+
* -trips the whole thing through `JSON.parse(JSON.stringify(...))` and compares.
|
|
55
|
+
*
|
|
56
|
+
* Role-carrying elements only. A neutral rectangle is not an artefact of any
|
|
57
|
+
* framework, so it is not a fact about the map — the same proportionality the
|
|
58
|
+
* engine applies (PRD principle 8), and the reason a board full of free
|
|
59
|
+
* drawings does not turn into a wall of tokens.
|
|
60
|
+
*/
|
|
61
|
+
export declare function collectAuditFacts(std: BlockStdScope): AuditFacts;
|
|
62
|
+
/**
|
|
63
|
+
* The audit run itself, split out of the descriptor so a caller that already
|
|
64
|
+
* has an `AbortSignal` (a host panel with a Cancel button, a test) can drive it
|
|
65
|
+
* directly and await the result. `run` cannot: `CommandDescriptor.run` returns
|
|
66
|
+
* `void | Promise<void>` and `runCommand` fires and forgets.
|
|
67
|
+
*/
|
|
68
|
+
export declare function runMapAudit(std: BlockStdScope, options?: {
|
|
69
|
+
criterionIds?: string[];
|
|
70
|
+
onProgress?: (progress: AuditProgress) => void;
|
|
71
|
+
signal?: AbortSignal;
|
|
72
|
+
}): Promise<AuditResult>;
|
|
73
|
+
/**
|
|
74
|
+
* ## Read-only (the `pivot.bind` pattern, PR #89 — and its one deliberate
|
|
75
|
+
* difference)
|
|
76
|
+
*
|
|
77
|
+
* `pivot.bind` guards `!std.store.readonly` inside `run`, because `runCommand`
|
|
78
|
+
* consults neither `when` nor `availability` and `clearField` carries no
|
|
79
|
+
* read-only guard of its own — without it, a palette invocation would mutate a
|
|
80
|
+
* document the user cannot edit.
|
|
81
|
+
*
|
|
82
|
+
* `map.audit` needs no such guard, and adding one would be wrong rather than
|
|
83
|
+
* merely redundant: **it writes nothing**. It reads element geometry and roles,
|
|
84
|
+
* copies the engine's verdict, and stores the answer in a session signal that
|
|
85
|
+
* never reaches a `Y.Doc`. A read-only document is not an edge case for an
|
|
86
|
+
* audit — it is the CASE: reviewing a map you have been given, and cannot
|
|
87
|
+
* change, is what a reviewer does.
|
|
88
|
+
*
|
|
89
|
+
* The invariant `pivot.bind` protects with a guard is protected here by a test
|
|
90
|
+
* instead: `map.audit` on a read-only store runs to completion, publishes its
|
|
91
|
+
* findings, and leaves the document byte-identical. Recorded loudly because
|
|
92
|
+
* "no read-only check" reads like an omission and is a decision.
|
|
93
|
+
*
|
|
94
|
+
* ## ponytail: the day a finding can be ACCEPTED, the guard comes back
|
|
95
|
+
*
|
|
96
|
+
* The invariant holds only while findings stay READ-ONLY. `validationExceptions`
|
|
97
|
+
* is a persisted field, so a future slice letting a user accept an audit finding
|
|
98
|
+
* as an exception — the obvious next gesture — would put a write on this path,
|
|
99
|
+
* and that write would need exactly the `pivot.bind` guard: checked inside
|
|
100
|
+
* `run`, because `runCommand` consults neither `when` nor `availability`.
|
|
101
|
+
*
|
|
102
|
+
* The trigger is precise: **the first code under `map.audit` that touches
|
|
103
|
+
* `std.store` or an element field.** Until then a guard would be false, not
|
|
104
|
+
* merely redundant — it would remove the capability exactly where it is most
|
|
105
|
+
* useful.
|
|
106
|
+
*/
|
|
107
|
+
export declare const auditCommands: AnyCommandDescriptor[];
|
|
@@ -0,0 +1,472 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `map.audit` — the command the **Labre Assistant** invokes to audit a
|
|
3
|
+
* framework map (PF14.1).
|
|
4
|
+
*
|
|
5
|
+
* ## Where the work happens, and where it does not
|
|
6
|
+
*
|
|
7
|
+
* The library does no auditing. It collects the FACTS of the board, hands them
|
|
8
|
+
* to the host's `AuditProvider` with the criteria the frameworks declared, and
|
|
9
|
+
* files whatever comes back into a signal nothing on the real-time path reads.
|
|
10
|
+
* If no provider is registered the command refuses cleanly and levels 1 and 2
|
|
11
|
+
* are exactly as they were.
|
|
12
|
+
*
|
|
13
|
+
* ## Three gates, and they are independent on purpose
|
|
14
|
+
*
|
|
15
|
+
* 1. **`ai-audit`** (`packages/affine/all/src/flags.ts`) — the capability
|
|
16
|
+
* switch. Off, `AuditViewExtension` is never registered, so the command is
|
|
17
|
+
* absent from the registry, from both manifests and from the keymap. Same
|
|
18
|
+
* contract as a block flag: it gates TOOLING and never data — nothing this
|
|
19
|
+
* command touches is persisted, so switching it off cannot lose anything
|
|
20
|
+
* even in principle.
|
|
21
|
+
* 2. **The framework's own flag** — the criteria are registered by the
|
|
22
|
+
* flag-gated view extension (`AuditCriterionExtension`), so a disabled
|
|
23
|
+
* Wardley contributes no criterion and an audit has nothing to ask about.
|
|
24
|
+
* 3. **The provider** — absent, the command is still enumerable but refuses.
|
|
25
|
+
* Per ADR 0008, injected-provider presence is deliberately NOT an
|
|
26
|
+
* `Availability` member; its assigned fallback is "displayed available,
|
|
27
|
+
* `run` degrades". Making it a fourth availability value would have meant
|
|
28
|
+
* reopening a closed union for a state the caller can simply be told about.
|
|
29
|
+
*/
|
|
30
|
+
import { getAuditCriteria, requestAudit, TelemetryProvider, } from '../../affine-shared/services/index.js';
|
|
31
|
+
import { GfxControllerIdentifier, GfxPrimitiveElementModel, roleIsA, } from '../../std/gfx/index.js';
|
|
32
|
+
import { z } from 'zod';
|
|
33
|
+
import { backgroundPlot } from '../framework-background/def.js';
|
|
34
|
+
import { backgroundAxisFacts } from '../framework-background/facts.js';
|
|
35
|
+
import { ValidationManager, ValidationRuleIdentifier, } from './validation.js';
|
|
36
|
+
/**
|
|
37
|
+
* `map.audit` takes no required parameter: the assistant audits what is
|
|
38
|
+
* selected. `criterionIds` narrows the run to a subset — an assistant
|
|
39
|
+
* re-checking one criterion after a fix should not pay for the other two — and
|
|
40
|
+
* an EMPTY array means "these zero criteria", i.e. nothing to do, never "all of
|
|
41
|
+
* them". Same reading as `pivot.bind`'s `elementIds`, for the same reason: a
|
|
42
|
+
* caller that filtered a list and came up empty must not have its request
|
|
43
|
+
* silently widened.
|
|
44
|
+
*/
|
|
45
|
+
export const auditParams = z.object({
|
|
46
|
+
criterionIds: z.array(z.string()).optional(),
|
|
47
|
+
});
|
|
48
|
+
/**
|
|
49
|
+
* The rules registered in this assembly, whatever their framework.
|
|
50
|
+
*
|
|
51
|
+
* Read straight off the DI identifier rather than through `ValidationManager`:
|
|
52
|
+
* the manager resolves the same list once and caches it, but its copy is
|
|
53
|
+
* private and the audit has no business widening the engine's API to read it.
|
|
54
|
+
* Registration is the gate either way — a framework flagged off registered no
|
|
55
|
+
* rule, so both answers are empty for the same reason.
|
|
56
|
+
*/
|
|
57
|
+
function activeRules(std) {
|
|
58
|
+
return [...std.provider.getAll(ValidationRuleIdentifier).values()];
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* The role vocabulary in play, de-duplicated across every registered rule.
|
|
62
|
+
*
|
|
63
|
+
* Read off the RULES rather than from a second registry, exactly as
|
|
64
|
+
* `ValidationManager.profilesFor` does: a rule already carries its framework's
|
|
65
|
+
* `RoleDefs`, so a framework flagged off contributes no vocabulary for free.
|
|
66
|
+
*/
|
|
67
|
+
function collectRoles(rules) {
|
|
68
|
+
const byId = new Map();
|
|
69
|
+
for (const rule of rules) {
|
|
70
|
+
for (const def of Object.values(rule.roles)) {
|
|
71
|
+
if (!def || byId.has(def.id))
|
|
72
|
+
continue;
|
|
73
|
+
byId.set(def.id, {
|
|
74
|
+
id: def.id,
|
|
75
|
+
kind: def.kind,
|
|
76
|
+
...(def.parent !== undefined ? { parent: def.parent } : {}),
|
|
77
|
+
...(def.labelKey !== undefined ? { labelKey: def.labelKey } : {}),
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
return [...byId.values()];
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Every framework frame on the surface, as facts.
|
|
85
|
+
*
|
|
86
|
+
* A frame is an element carrying some rule's `backgroundRole` — the same
|
|
87
|
+
* definition the rule families use, so the audit sees exactly the maps the
|
|
88
|
+
* engine sees, and a background authored before its role existed is invisible
|
|
89
|
+
* to both.
|
|
90
|
+
*/
|
|
91
|
+
function collectFrames(rules, elements) {
|
|
92
|
+
const frames = [];
|
|
93
|
+
const seen = new Set();
|
|
94
|
+
for (const rule of rules) {
|
|
95
|
+
const backgroundRole = rule.backgroundRole;
|
|
96
|
+
const def = rule.background;
|
|
97
|
+
if (backgroundRole === undefined || def === undefined)
|
|
98
|
+
continue;
|
|
99
|
+
for (const el of elements) {
|
|
100
|
+
if (el.role === undefined || seen.has(el.id))
|
|
101
|
+
continue;
|
|
102
|
+
if (!roleIsA(el.role, backgroundRole, rule.roles))
|
|
103
|
+
continue;
|
|
104
|
+
seen.add(el.id);
|
|
105
|
+
const profileId = el.validationProfile;
|
|
106
|
+
frames.push({
|
|
107
|
+
def,
|
|
108
|
+
bound: el.elementBound,
|
|
109
|
+
fact: {
|
|
110
|
+
elementId: el.id,
|
|
111
|
+
framework: rule.framework,
|
|
112
|
+
type: def.type,
|
|
113
|
+
...(typeof profileId === 'string' ? { profileId } : {}),
|
|
114
|
+
axes: backgroundAxisFacts(def),
|
|
115
|
+
zones: (def.zones ?? []).map(zone => ({
|
|
116
|
+
id: zone.id,
|
|
117
|
+
rect: { ...zone.rect },
|
|
118
|
+
})),
|
|
119
|
+
},
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
return frames;
|
|
124
|
+
}
|
|
125
|
+
/** Squared edge-to-edge gap — the same attribution heuristic the engine uses. */
|
|
126
|
+
function gapSquared(frame, bound) {
|
|
127
|
+
const dx = Math.max(frame.x - bound.maxX, bound.x - frame.maxX, 0);
|
|
128
|
+
const dy = Math.max(frame.y - bound.maxY, bound.y - frame.maxY, 0);
|
|
129
|
+
return dx * dx + dy * dy;
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* The frame an element belongs to: the one that CONTAINS it, failing that the
|
|
133
|
+
* nearest by edge-to-edge gap, ties broken by the smaller id.
|
|
134
|
+
*
|
|
135
|
+
* Deliberately the same answer `attributeBackground` gives inside the engine —
|
|
136
|
+
* an audit that attributed an element to a different map than the rule that
|
|
137
|
+
* indicted it would produce two findings about one component that disagree
|
|
138
|
+
* about which map it is on.
|
|
139
|
+
*/
|
|
140
|
+
function attribute(bound, frames) {
|
|
141
|
+
let nearest = null;
|
|
142
|
+
let nearestDistance = Infinity;
|
|
143
|
+
for (const frame of frames) {
|
|
144
|
+
if (frame.bound.contains(bound))
|
|
145
|
+
return frame;
|
|
146
|
+
const distance = gapSquared(frame.bound, bound);
|
|
147
|
+
if (distance < nearestDistance ||
|
|
148
|
+
(distance === nearestDistance &&
|
|
149
|
+
nearest !== null &&
|
|
150
|
+
frame.fact.elementId < nearest.fact.elementId)) {
|
|
151
|
+
nearestDistance = distance;
|
|
152
|
+
nearest = frame;
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
return nearest;
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* Where an element's centre sits inside a frame's PLOT, as ratios.
|
|
159
|
+
*
|
|
160
|
+
* Ratios of the plot and not of the element box: a Wardley transition drawn at
|
|
161
|
+
* `0.4` is 40 % of the PLOT, not of the map element, and the margin between the
|
|
162
|
+
* two is exactly where the axis titles live. `backgroundPlot` is the one place
|
|
163
|
+
* that knows the difference, and this is the only reason this function exists
|
|
164
|
+
* rather than a subtraction at the call site.
|
|
165
|
+
*
|
|
166
|
+
* Not clamped: an element just off the left edge reads as `-0.03`, which is a
|
|
167
|
+
* true and useful thing to say. `null` for a degenerate plot.
|
|
168
|
+
*/
|
|
169
|
+
function plotRatios(frame, bound) {
|
|
170
|
+
const plot = backgroundPlot(frame.def, frame.bound.w, frame.bound.h);
|
|
171
|
+
if (!(plot.width > 0) || !(plot.height > 0))
|
|
172
|
+
return null;
|
|
173
|
+
const cx = bound.x + bound.w / 2;
|
|
174
|
+
const cy = bound.y + bound.h / 2;
|
|
175
|
+
return [
|
|
176
|
+
(cx - frame.bound.x - plot.x0) / plot.width,
|
|
177
|
+
(cy - frame.bound.y - plot.y0) / plot.height,
|
|
178
|
+
];
|
|
179
|
+
}
|
|
180
|
+
/** The declared zone a plot-ratio point falls in, if any. */
|
|
181
|
+
function zoneAt(frame, at) {
|
|
182
|
+
for (const zone of frame.fact.zones) {
|
|
183
|
+
const { x, y, w, h } = zone.rect;
|
|
184
|
+
if (at[0] >= x && at[0] <= x + w && at[1] >= y && at[1] <= y + h) {
|
|
185
|
+
return zone.id;
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
return undefined;
|
|
189
|
+
}
|
|
190
|
+
/**
|
|
191
|
+
* Levels 1 and 2, copied out of the engine's verdict.
|
|
192
|
+
*
|
|
193
|
+
* `audit` findings are excluded, and not merely because none exist today: the
|
|
194
|
+
* facts handed to an assistant must never contain a previous assistant's
|
|
195
|
+
* opinions, or a second run would start agreeing with itself.
|
|
196
|
+
*/
|
|
197
|
+
function collectViolations(violations) {
|
|
198
|
+
const facts = [];
|
|
199
|
+
for (const violation of violations) {
|
|
200
|
+
if (violation.severity === 'audit')
|
|
201
|
+
continue;
|
|
202
|
+
facts.push({
|
|
203
|
+
ruleId: violation.ruleId,
|
|
204
|
+
severity: violation.severity,
|
|
205
|
+
elementIds: [...violation.elementIds],
|
|
206
|
+
messageKey: violation.messageKey,
|
|
207
|
+
...(violation.backgroundId !== undefined
|
|
208
|
+
? { backgroundId: violation.backgroundId }
|
|
209
|
+
: {}),
|
|
210
|
+
...(violation.exemption !== undefined
|
|
211
|
+
? { exemption: violation.exemption }
|
|
212
|
+
: {}),
|
|
213
|
+
});
|
|
214
|
+
}
|
|
215
|
+
return facts;
|
|
216
|
+
}
|
|
217
|
+
/**
|
|
218
|
+
* Everything the assistant is told about the board — **render-free** and
|
|
219
|
+
* serializable end to end (ADR 0006 § 5): plain objects, numbers and strings,
|
|
220
|
+
* no element model, no `Bound`, no `TemplateResult`, no function. A test round
|
|
221
|
+
* -trips the whole thing through `JSON.parse(JSON.stringify(...))` and compares.
|
|
222
|
+
*
|
|
223
|
+
* Role-carrying elements only. A neutral rectangle is not an artefact of any
|
|
224
|
+
* framework, so it is not a fact about the map — the same proportionality the
|
|
225
|
+
* engine applies (PRD principle 8), and the reason a board full of free
|
|
226
|
+
* drawings does not turn into a wall of tokens.
|
|
227
|
+
*/
|
|
228
|
+
export function collectAuditFacts(std) {
|
|
229
|
+
const rules = activeRules(std);
|
|
230
|
+
const surface = std.get(GfxControllerIdentifier).surface;
|
|
231
|
+
const elements = surface?.elementModels ?? [];
|
|
232
|
+
// No rule registered means every framework is switched off, and the exact
|
|
233
|
+
// same length check `ValidationManager.mounted` exits on. Without it a dark
|
|
234
|
+
// board still reported its role-carrying elements — ids sent to an assistant
|
|
235
|
+
// with no vocabulary to read them by and no criterion to ask about them.
|
|
236
|
+
// Empty facts, one comparison, nothing walked.
|
|
237
|
+
if (rules.length === 0) {
|
|
238
|
+
return { roles: [], frames: [], elements: [], violations: [] };
|
|
239
|
+
}
|
|
240
|
+
const frames = collectFrames(rules, elements);
|
|
241
|
+
const frameIds = new Set(frames.map(frame => frame.fact.elementId));
|
|
242
|
+
const elementFacts = [];
|
|
243
|
+
for (const el of elements) {
|
|
244
|
+
const role = el.role;
|
|
245
|
+
if (role === undefined || frameIds.has(el.id))
|
|
246
|
+
continue;
|
|
247
|
+
const bound = el.elementBound;
|
|
248
|
+
const frame = attribute(bound, frames);
|
|
249
|
+
if (frame === null) {
|
|
250
|
+
elementFacts.push({ id: el.id, role });
|
|
251
|
+
continue;
|
|
252
|
+
}
|
|
253
|
+
const at = plotRatios(frame, bound);
|
|
254
|
+
const zone = at === null ? undefined : zoneAt(frame, at);
|
|
255
|
+
elementFacts.push({
|
|
256
|
+
id: el.id,
|
|
257
|
+
role,
|
|
258
|
+
frameId: frame.fact.elementId,
|
|
259
|
+
...(at !== null ? { at } : {}),
|
|
260
|
+
...(zone !== undefined ? { zone } : {}),
|
|
261
|
+
});
|
|
262
|
+
}
|
|
263
|
+
return {
|
|
264
|
+
roles: collectRoles(rules),
|
|
265
|
+
frames: frames.map(frame => frame.fact),
|
|
266
|
+
elements: elementFacts,
|
|
267
|
+
violations: collectViolations(std.getOptional(ValidationManager)?.violations$.peek() ?? []),
|
|
268
|
+
};
|
|
269
|
+
}
|
|
270
|
+
/**
|
|
271
|
+
* The criteria this run carries: every registered one, or the requested subset.
|
|
272
|
+
*
|
|
273
|
+
* An unknown id is silently skipped rather than refused — an assistant pinned
|
|
274
|
+
* to a criterion a later release retired should degrade to auditing the rest,
|
|
275
|
+
* not fail the whole run over a string.
|
|
276
|
+
*/
|
|
277
|
+
function selectCriteria(std, criterionIds) {
|
|
278
|
+
const all = getAuditCriteria(std);
|
|
279
|
+
if (criterionIds === undefined)
|
|
280
|
+
return all;
|
|
281
|
+
const wanted = new Set(criterionIds);
|
|
282
|
+
return all.filter(criterion => wanted.has(criterion.id));
|
|
283
|
+
}
|
|
284
|
+
/** The single framework of a criteria set, or `undefined` if they disagree. */
|
|
285
|
+
function unanimousFramework(criteria) {
|
|
286
|
+
const distinct = new Set(criteria.map(criterion => criterion.framework));
|
|
287
|
+
return distinct.size === 1 ? criteria[0].framework : undefined;
|
|
288
|
+
}
|
|
289
|
+
/**
|
|
290
|
+
* Whether the current selection is a framework FRAME.
|
|
291
|
+
*
|
|
292
|
+
* The narrowing behind `availability: 'selection:framework'`: an audit is about
|
|
293
|
+
* a map, so the gesture is "select the map, ask for an audit" — the background,
|
|
294
|
+
* not one of the components on it. `isCommandAvailable` currently evaluates
|
|
295
|
+
* `'selection:framework'` as plain `'selection'` (ADR 0008), so the real
|
|
296
|
+
* predicate lives here, which is exactly what `when` is for.
|
|
297
|
+
*/
|
|
298
|
+
function selectedFrames(std) {
|
|
299
|
+
const rules = activeRules(std);
|
|
300
|
+
if (rules.length === 0)
|
|
301
|
+
return [];
|
|
302
|
+
const selected = std
|
|
303
|
+
.get(GfxControllerIdentifier)
|
|
304
|
+
.selection.selectedElements.filter((el) => el instanceof GfxPrimitiveElementModel);
|
|
305
|
+
return selected.filter(el => rules.some(rule => rule.backgroundRole !== undefined &&
|
|
306
|
+
el.role !== undefined &&
|
|
307
|
+
roleIsA(el.role, rule.backgroundRole, rule.roles)));
|
|
308
|
+
}
|
|
309
|
+
/**
|
|
310
|
+
* The generation of the latest audit asked for, per editor.
|
|
311
|
+
*
|
|
312
|
+
* An audit is a network call to a model and takes SECONDS, so two runs
|
|
313
|
+
* overlapping is not an exotic case — it is what happens when a user asks
|
|
314
|
+
* again because the first one is slow. Without a guard, `setAuditFindings` is
|
|
315
|
+
* unconditional and the two runs publish in order of RESOLUTION rather than
|
|
316
|
+
* order of request: the slow, stale answer overwrites the fresh one, and a
|
|
317
|
+
* `MapAuditCompleted` reports a `findingCount` for findings that were thrown
|
|
318
|
+
* away.
|
|
319
|
+
*
|
|
320
|
+
* Same shape as `ValidationManager`'s `_checkupGeneration`: take a number
|
|
321
|
+
* before, compare after, publish only if still the latest. It lives here rather
|
|
322
|
+
* than on the manager because it is the COMMAND's arbitration between two of
|
|
323
|
+
* its own invocations, and `validation.ts` is not the audit's file — a `WeakMap`
|
|
324
|
+
* keyed on the editor scope is exactly as correct and touches nothing.
|
|
325
|
+
*
|
|
326
|
+
* Newest wins, rather than "refuse the second": the second request is the one
|
|
327
|
+
* the user just made, and telling them to wait for an answer they have already
|
|
328
|
+
* decided is late would be the wrong half to keep.
|
|
329
|
+
*/
|
|
330
|
+
const auditGenerations = new WeakMap();
|
|
331
|
+
/**
|
|
332
|
+
* The audit run itself, split out of the descriptor so a caller that already
|
|
333
|
+
* has an `AbortSignal` (a host panel with a Cancel button, a test) can drive it
|
|
334
|
+
* directly and await the result. `run` cannot: `CommandDescriptor.run` returns
|
|
335
|
+
* `void | Promise<void>` and `runCommand` fires and forgets.
|
|
336
|
+
*/
|
|
337
|
+
export async function runMapAudit(std, options = {}) {
|
|
338
|
+
const criteria = selectCriteria(std, options.criterionIds);
|
|
339
|
+
const facts = collectAuditFacts(std);
|
|
340
|
+
const telemetry = std.getOptional(TelemetryProvider);
|
|
341
|
+
const base = {
|
|
342
|
+
page: 'whiteboard editor',
|
|
343
|
+
framework: unanimousFramework(criteria),
|
|
344
|
+
criterionCount: criteria.length,
|
|
345
|
+
frameCount: facts.frames.length,
|
|
346
|
+
};
|
|
347
|
+
const startedAt = performance.now();
|
|
348
|
+
const generation = (auditGenerations.get(std) ?? 0) + 1;
|
|
349
|
+
auditGenerations.set(std, generation);
|
|
350
|
+
telemetry?.track('MapAuditStarted', base);
|
|
351
|
+
const result = await requestAudit(std, { criteria, facts }, {
|
|
352
|
+
...(options.onProgress ? { onProgress: options.onProgress } : {}),
|
|
353
|
+
...(options.signal ? { signal: options.signal } : {}),
|
|
354
|
+
});
|
|
355
|
+
const durationMs = performance.now() - startedAt;
|
|
356
|
+
// Somebody asked again while this was in flight. Their answer is the one that
|
|
357
|
+
// describes the board the user is looking at, so this one is dropped whole —
|
|
358
|
+
// not published, and not counted as a completion either, because a
|
|
359
|
+
// `findingCount` for findings nobody will see is a metric that lies.
|
|
360
|
+
//
|
|
361
|
+
// The findings are dropped from the RETURN VALUE too, not just from the
|
|
362
|
+
// signal. `runMapAudit` is exported and awaited directly by a host panel; one
|
|
363
|
+
// that renders `result.findings` without first testing `result.status` would
|
|
364
|
+
// otherwise display precisely the stale answer this guard exists to suppress
|
|
365
|
+
// — and "the caller should have checked" is a poor defence for a field that
|
|
366
|
+
// is easier to read than the status beside it. Superseded means superseded on
|
|
367
|
+
// both channels.
|
|
368
|
+
if (auditGenerations.get(std) !== generation) {
|
|
369
|
+
telemetry?.track('MapAuditInterrupted', {
|
|
370
|
+
...base,
|
|
371
|
+
reason: 'superseded',
|
|
372
|
+
durationMs,
|
|
373
|
+
});
|
|
374
|
+
return { ...result, status: 'superseded', findings: [] };
|
|
375
|
+
}
|
|
376
|
+
// Published even for a partial run: an audit interrupted halfway has still
|
|
377
|
+
// said something true, and throwing it away would punish the user for
|
|
378
|
+
// pressing Cancel. `unavailable` and `error` publish an EMPTY list, which
|
|
379
|
+
// clears whatever a previous run left — a stale opinion is worse than none.
|
|
380
|
+
std.getOptional(ValidationManager)?.setAuditFindings(result.findings);
|
|
381
|
+
if (result.status === 'complete') {
|
|
382
|
+
telemetry?.track('MapAuditCompleted', {
|
|
383
|
+
...base,
|
|
384
|
+
findingCount: result.findings.length,
|
|
385
|
+
durationMs,
|
|
386
|
+
});
|
|
387
|
+
}
|
|
388
|
+
else {
|
|
389
|
+
telemetry?.track('MapAuditInterrupted', {
|
|
390
|
+
...base,
|
|
391
|
+
reason: result.status,
|
|
392
|
+
durationMs,
|
|
393
|
+
});
|
|
394
|
+
}
|
|
395
|
+
return result;
|
|
396
|
+
}
|
|
397
|
+
const mapAudit = {
|
|
398
|
+
id: 'map.audit',
|
|
399
|
+
// `'core'`, not `'wardley'`: the command is framework-agnostic — it audits
|
|
400
|
+
// whatever frame is selected against whatever criteria are registered — and a
|
|
401
|
+
// `'wardley'` owner would have forced the id prefix `wardley.` and made a
|
|
402
|
+
// second, identical command necessary for every framework that follows.
|
|
403
|
+
// `'core'` owners are exempt from the id-prefix rule (ADR 0008).
|
|
404
|
+
owner: 'core',
|
|
405
|
+
kind: 'action',
|
|
406
|
+
labelKey: 'com.labre.command.map.audit',
|
|
407
|
+
labelFallback: 'Audit this map',
|
|
408
|
+
descriptionKey: 'com.labre.command.map.audit.description',
|
|
409
|
+
// `'agent'` is the point of the whole slice — consumer 5 of ADR 0008 — and
|
|
410
|
+
// `'palette'` because a human asking for a review by name is the same
|
|
411
|
+
// request. Deliberately NOT `'senior-menu'`: the 14 slots are for artefacts,
|
|
412
|
+
// and an audit is not one.
|
|
413
|
+
surfaces: ['palette', 'agent'],
|
|
414
|
+
scope: 'edgeless',
|
|
415
|
+
// Keyless by intent. Still bindable from Settings › Shortcuts.
|
|
416
|
+
defaultKeys: { mac: [], other: [] },
|
|
417
|
+
// The serializable half a host catalogue shows: this command needs a frame
|
|
418
|
+
// selected. Narrowed below to "and that frame is a framework background".
|
|
419
|
+
availability: 'selection:framework',
|
|
420
|
+
when: std => selectedFrames(std).length > 0,
|
|
421
|
+
params: auditParams,
|
|
422
|
+
run: (std, _invocation, params) => {
|
|
423
|
+
const parsed = auditParams.safeParse(params ?? {});
|
|
424
|
+
if (!parsed.success) {
|
|
425
|
+
console.error('map.audit: invalid params', parsed.error.issues);
|
|
426
|
+
return;
|
|
427
|
+
}
|
|
428
|
+
// `runCommand` fires and forgets, so the rejection has to die here. It
|
|
429
|
+
// cannot reject — `requestAudit` guards the provider — but a `void` promise
|
|
430
|
+
// escaping a command is how an unhandled rejection reaches a user's console.
|
|
431
|
+
return runMapAudit(std, {
|
|
432
|
+
...(parsed.data.criterionIds !== undefined
|
|
433
|
+
? { criterionIds: parsed.data.criterionIds }
|
|
434
|
+
: {}),
|
|
435
|
+
}).then(() => undefined);
|
|
436
|
+
},
|
|
437
|
+
};
|
|
438
|
+
/**
|
|
439
|
+
* ## Read-only (the `pivot.bind` pattern, PR #89 — and its one deliberate
|
|
440
|
+
* difference)
|
|
441
|
+
*
|
|
442
|
+
* `pivot.bind` guards `!std.store.readonly` inside `run`, because `runCommand`
|
|
443
|
+
* consults neither `when` nor `availability` and `clearField` carries no
|
|
444
|
+
* read-only guard of its own — without it, a palette invocation would mutate a
|
|
445
|
+
* document the user cannot edit.
|
|
446
|
+
*
|
|
447
|
+
* `map.audit` needs no such guard, and adding one would be wrong rather than
|
|
448
|
+
* merely redundant: **it writes nothing**. It reads element geometry and roles,
|
|
449
|
+
* copies the engine's verdict, and stores the answer in a session signal that
|
|
450
|
+
* never reaches a `Y.Doc`. A read-only document is not an edge case for an
|
|
451
|
+
* audit — it is the CASE: reviewing a map you have been given, and cannot
|
|
452
|
+
* change, is what a reviewer does.
|
|
453
|
+
*
|
|
454
|
+
* The invariant `pivot.bind` protects with a guard is protected here by a test
|
|
455
|
+
* instead: `map.audit` on a read-only store runs to completion, publishes its
|
|
456
|
+
* findings, and leaves the document byte-identical. Recorded loudly because
|
|
457
|
+
* "no read-only check" reads like an omission and is a decision.
|
|
458
|
+
*
|
|
459
|
+
* ## ponytail: the day a finding can be ACCEPTED, the guard comes back
|
|
460
|
+
*
|
|
461
|
+
* The invariant holds only while findings stay READ-ONLY. `validationExceptions`
|
|
462
|
+
* is a persisted field, so a future slice letting a user accept an audit finding
|
|
463
|
+
* as an exception — the obvious next gesture — would put a write on this path,
|
|
464
|
+
* and that write would need exactly the `pivot.bind` guard: checked inside
|
|
465
|
+
* `run`, because `runCommand` consults neither `when` nor `availability`.
|
|
466
|
+
*
|
|
467
|
+
* The trigger is precise: **the first code under `map.audit` that touches
|
|
468
|
+
* `std.store` or an element field.** Until then a guard would be false, not
|
|
469
|
+
* merely redundant — it would remove the capability exactly where it is most
|
|
470
|
+
* useful.
|
|
471
|
+
*/
|
|
472
|
+
export const auditCommands = [mapAudit];
|
|
@@ -10,6 +10,20 @@ export declare class EdgelessCRUDExtension extends Extension {
|
|
|
10
10
|
static setup(di: Container): void;
|
|
11
11
|
private get _gfx();
|
|
12
12
|
private get _surface();
|
|
13
|
+
/**
|
|
14
|
+
* `SurfaceBlockModel` already REFUSES element writes on a readonly document —
|
|
15
|
+
* it throws (`Cannot add / remove / update element in readonly mode`). This
|
|
16
|
+
* guard does not plug a hole: it turns those throws into a quiet refusal at
|
|
17
|
+
* the layer callers actually use, which is what the store's block CRUD does
|
|
18
|
+
* (`updateBlock` / `deleteBlock` / `moveBlocks` all `console.error` and
|
|
19
|
+
* return). Hence the log — a silent `return` would be the only refusal in the
|
|
20
|
+
* repo with no signal at all.
|
|
21
|
+
*
|
|
22
|
+
* Callers that consume the return value all test it (`clipboard/canvas.ts`,
|
|
23
|
+
* `group-api.ts`, `shape-draggable.ts` guard on `if (!id) return`), so
|
|
24
|
+
* `addElement` returning `undefined` introduces no new dereference.
|
|
25
|
+
*/
|
|
26
|
+
private _refuseOnReadonly;
|
|
13
27
|
deleteElements: (elements: GfxModel[]) => void;
|
|
14
28
|
addBlock: (flavour: string, props: Record<string, unknown>, parentId?: string | BlockModel, parentIndex?: number) => string;
|
|
15
29
|
addElement: <T extends Record<string, unknown>>(type: string, props: T) => string | undefined;
|
|
@@ -11,6 +11,8 @@ export class EdgelessCRUDExtension extends Extension {
|
|
|
11
11
|
super();
|
|
12
12
|
this.std = std;
|
|
13
13
|
this.deleteElements = (elements) => {
|
|
14
|
+
if (this._refuseOnReadonly('delete elements'))
|
|
15
|
+
return;
|
|
14
16
|
const surface = this._surface;
|
|
15
17
|
if (!surface) {
|
|
16
18
|
console.error('surface is not initialized');
|
|
@@ -49,6 +51,8 @@ export class EdgelessCRUDExtension extends Extension {
|
|
|
49
51
|
return this.std.store.addBlock(flavour, nProps, parentId, parentIndex);
|
|
50
52
|
};
|
|
51
53
|
this.addElement = (type, props) => {
|
|
54
|
+
if (this._refuseOnReadonly('add an element'))
|
|
55
|
+
return;
|
|
52
56
|
const surface = this._surface;
|
|
53
57
|
if (!surface) {
|
|
54
58
|
console.error('surface is not initialized');
|
|
@@ -67,6 +71,8 @@ export class EdgelessCRUDExtension extends Extension {
|
|
|
67
71
|
return surface.addElement(nProps);
|
|
68
72
|
};
|
|
69
73
|
this.updateElement = (id, props) => {
|
|
74
|
+
if (this._refuseOnReadonly('update an element'))
|
|
75
|
+
return;
|
|
70
76
|
const surface = this._surface;
|
|
71
77
|
if (!surface) {
|
|
72
78
|
console.error('surface is not initialized');
|
|
@@ -103,6 +109,25 @@ export class EdgelessCRUDExtension extends Extension {
|
|
|
103
109
|
get _surface() {
|
|
104
110
|
return this._gfx.surface;
|
|
105
111
|
}
|
|
112
|
+
/**
|
|
113
|
+
* `SurfaceBlockModel` already REFUSES element writes on a readonly document —
|
|
114
|
+
* it throws (`Cannot add / remove / update element in readonly mode`). This
|
|
115
|
+
* guard does not plug a hole: it turns those throws into a quiet refusal at
|
|
116
|
+
* the layer callers actually use, which is what the store's block CRUD does
|
|
117
|
+
* (`updateBlock` / `deleteBlock` / `moveBlocks` all `console.error` and
|
|
118
|
+
* return). Hence the log — a silent `return` would be the only refusal in the
|
|
119
|
+
* repo with no signal at all.
|
|
120
|
+
*
|
|
121
|
+
* Callers that consume the return value all test it (`clipboard/canvas.ts`,
|
|
122
|
+
* `group-api.ts`, `shape-draggable.ts` guard on `if (!id) return`), so
|
|
123
|
+
* `addElement` returning `undefined` introduces no new dereference.
|
|
124
|
+
*/
|
|
125
|
+
_refuseOnReadonly(action) {
|
|
126
|
+
if (!this.std.store.readonly)
|
|
127
|
+
return false;
|
|
128
|
+
console.error(`cannot ${action} in readonly mode`);
|
|
129
|
+
return true;
|
|
130
|
+
}
|
|
106
131
|
getElementById(id) {
|
|
107
132
|
const surface = this._surface;
|
|
108
133
|
if (!surface) {
|
|
@@ -118,6 +143,8 @@ export class EdgelessCRUDExtension extends Extension {
|
|
|
118
143
|
return this._surface.getElementsByType(type);
|
|
119
144
|
}
|
|
120
145
|
removeElement(id) {
|
|
146
|
+
if (this._refuseOnReadonly('remove an element'))
|
|
147
|
+
return;
|
|
121
148
|
id = typeof id === 'string' ? id : id.id;
|
|
122
149
|
const el = this.getElementById(id);
|
|
123
150
|
if (isGfxGroupCompatibleModel(el)) {
|