@ecsplico/editor 3.6.0 → 4.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +73 -0
- package/dist/adapters/direct-ai.d.ts +4 -4
- package/dist/adapters/direct-ai.js +2 -2
- package/dist/adapters/direct-ai.js.map +1 -1
- package/dist/adapters/document-state.d.ts +1 -1
- package/dist/adapters/document-state.js.map +1 -1
- package/dist/adapters/forge.d.ts +2 -2
- package/dist/adapters/forge.js.map +1 -1
- package/dist/adapters/nitro.d.ts +11 -3
- package/dist/adapters/nitro.js +3 -1
- package/dist/adapters/nitro.js.map +1 -1
- package/dist/adapters/shared.d.ts +6 -6
- package/dist/adapters/shared.js.map +1 -1
- package/dist/code/CodeSurface.vue.d.ts +3 -3
- package/dist/config/index.d.ts +14 -14
- package/dist/config/index.js +8 -8
- package/dist/config/index.js.map +1 -1
- package/dist/core/backend-types.d.ts +3 -3
- package/dist/core/backend-types.js.map +1 -1
- package/dist/core/backend.d.ts +4 -4
- package/dist/core/backend.js.map +1 -1
- package/dist/core/block-convert.d.ts +1 -1
- package/dist/core/block-convert.js +5 -5
- package/dist/core/block-convert.js.map +1 -1
- package/dist/core/block-transfer.d.ts +8 -4
- package/dist/core/block-transfer.js +23 -14
- package/dist/core/block-transfer.js.map +1 -1
- package/dist/core/capabilities.d.ts +113 -0
- package/dist/core/capabilities.js +155 -0
- package/dist/core/capabilities.js.map +1 -0
- package/dist/core/command-types.d.ts +1 -1
- package/dist/core/context.js.map +1 -1
- package/dist/core/convert.d.ts +5 -5
- package/dist/core/convert.js +5 -5
- package/dist/core/convert.js.map +1 -1
- package/dist/core/core-feature.js +1 -1
- package/dist/core/define-editor.d.ts +2 -2
- package/dist/core/define-editor.js +34 -6
- package/dist/core/define-editor.js.map +1 -1
- package/dist/core/derivation.d.ts +119 -0
- package/dist/core/derivation.js +187 -0
- package/dist/core/derivation.js.map +1 -0
- package/dist/core/derive.d.ts +61 -0
- package/dist/core/derive.js +69 -0
- package/dist/core/derive.js.map +1 -0
- package/dist/core/extension-points.d.ts +16 -0
- package/dist/core/feature-context.d.ts +5 -1
- package/dist/core/feature-context.js +10 -3
- package/dist/core/feature-context.js.map +1 -1
- package/dist/core/feature.d.ts +41 -19
- package/dist/core/feature.js.map +1 -1
- package/dist/core/fences.js +1 -1
- package/dist/core/fences.js.map +1 -1
- package/dist/core/index.d.ts +6 -2
- package/dist/core/index.js +5 -1
- package/dist/core/pipeline.d.ts +14 -5
- package/dist/core/pipeline.js +19 -7
- package/dist/core/pipeline.js.map +1 -1
- package/dist/core/properties.d.ts +22 -0
- package/dist/core/properties.js +17 -0
- package/dist/core/properties.js.map +1 -0
- package/dist/core/schema/block-ids.js +5 -5
- package/dist/core/schema/block-ids.js.map +1 -1
- package/dist/core/schema/index.d.ts +2 -1
- package/dist/core/schema/index.js +2 -1
- package/dist/core/schema/index.js.map +1 -1
- package/dist/core/schema/opaque-fence.d.ts +4 -4
- package/dist/core/schema/opaque-fence.js +7 -7
- package/dist/core/schema/opaque-fence.js.map +1 -1
- package/dist/core/schema/persisted-names.d.ts +58 -0
- package/dist/core/schema/persisted-names.js +96 -0
- package/dist/core/schema/persisted-names.js.map +1 -0
- package/dist/core/toolbar-items.js +1 -1
- package/dist/core/toolbar-items.js.map +1 -1
- package/dist/core/util.js +5 -1
- package/dist/core/util.js.map +1 -1
- package/dist/document/DocumentSurface.vue.d.ts +3 -3
- package/dist/features/ai/agent-ops.js +1 -1
- package/dist/features/ai/ai-review.js +1 -1
- package/dist/features/ai/assistant.d.ts +4 -4
- package/dist/features/ai/assistant.js +1 -1
- package/dist/features/ai/assistant.js.map +1 -1
- package/dist/features/ai/components/AiSelectionMenu.js +1 -1
- package/dist/features/ai/components/AiSelectionMenu.js.map +1 -1
- package/dist/features/ai/components/ModelQuickSwitch.js +7 -7
- package/dist/features/ai/components/ModelQuickSwitch.js.map +1 -1
- package/dist/features/ai/components/ModelQuickSwitch.vue.d.ts +4 -4
- package/dist/features/ai/components/SettingsAiTab.js +8 -8
- package/dist/features/ai/components/SettingsAiTab.js.map +1 -1
- package/dist/features/ai/components/SettingsModelProfiles.js +1 -1
- package/dist/features/ai/components/SettingsModelProfiles.js.map +1 -1
- package/dist/features/ai/document-chat-model.d.ts +2 -2
- package/dist/features/ai/document-chat-model.js +5 -5
- package/dist/features/ai/document-chat-model.js.map +1 -1
- package/dist/features/ai/document-chat.js +2 -2
- package/dist/features/ai/document-chat.js.map +1 -1
- package/dist/features/ai/feature.d.ts +2 -2
- package/dist/features/ai/feature.js +2 -2
- package/dist/features/ai/feature.js.map +1 -1
- package/dist/features/ai/ghost-autocomplete.d.ts +4 -4
- package/dist/features/ai/ghost-autocomplete.js +1 -1
- package/dist/features/ai/ghost-autocomplete.js.map +1 -1
- package/dist/features/ai/index.d.ts +3 -3
- package/dist/features/ai/index.js +2 -2
- package/dist/features/ai/model-profiles.d.ts +9 -9
- package/dist/features/ai/model-profiles.js +13 -13
- package/dist/features/ai/model-profiles.js.map +1 -1
- package/dist/features/ai/protocol/agent-ops.d.ts +2 -2
- package/dist/features/ai/protocol/agent-ops.js +1 -1
- package/dist/features/ai/protocol/agent-ops.js.map +1 -1
- package/dist/features/ai/protocol/block-lines.d.ts +7 -7
- package/dist/features/ai/protocol/block-lines.js +10 -10
- package/dist/features/ai/protocol/block-lines.js.map +1 -1
- package/dist/features/ai/protocol/chat.d.ts +5 -5
- package/dist/features/ai/protocol/chat.js +12 -12
- package/dist/features/ai/protocol/chat.js.map +1 -1
- package/dist/features/ai/protocol/generate.d.ts +1 -1
- package/dist/features/ai/protocol/generate.js +1 -1
- package/dist/features/ai/protocol/generate.js.map +1 -1
- package/dist/features/ai/protocol/index.d.ts +3 -3
- package/dist/features/ai/protocol/index.js +2 -2
- package/dist/features/ai/protocol/models.d.ts +3 -3
- package/dist/features/ai/protocol/models.js +3 -3
- package/dist/features/ai/protocol/models.js.map +1 -1
- package/dist/features/ai/protocol/schemas.d.ts +1 -1
- package/dist/features/ai/protocol/schemas.js +1 -1
- package/dist/features/ai/protocol/schemas.js.map +1 -1
- package/dist/features/ai/protocol/tasks.d.ts +5 -5
- package/dist/features/ai/protocol/tasks.js +12 -12
- package/dist/features/ai/protocol/tasks.js.map +1 -1
- package/dist/features/ai/react/AiSelectionMenu.js.map +1 -1
- package/dist/features/ai/react/ModelQuickSwitch.d.ts +4 -4
- package/dist/features/ai/react/ModelQuickSwitch.js +6 -6
- package/dist/features/ai/react/ModelQuickSwitch.js.map +1 -1
- package/dist/features/ai/react/SettingsAiTab.d.ts +1 -1
- package/dist/features/ai/react/SettingsAiTab.js +8 -8
- package/dist/features/ai/react/SettingsAiTab.js.map +1 -1
- package/dist/features/ai/react/SettingsModelProfiles.d.ts +1 -1
- package/dist/features/ai/react/SettingsModelProfiles.js +1 -1
- package/dist/features/ai/react/SettingsModelProfiles.js.map +1 -1
- package/dist/features/ai/react/use-ai-assistant.d.ts +1 -1
- package/dist/features/ai/react/use-ai-assistant.js +1 -1
- package/dist/features/ai/react/use-ai-assistant.js.map +1 -1
- package/dist/features/ai/react/use-model-profiles.d.ts +5 -5
- package/dist/features/ai/react/use-model-profiles.js +2 -2
- package/dist/features/ai/react/use-model-profiles.js.map +1 -1
- package/dist/features/ai/use-ai-assistant.d.ts +1 -1
- package/dist/features/ai/use-ai-assistant.js +1 -1
- package/dist/features/ai/use-ai-assistant.js.map +1 -1
- package/dist/features/ai/use-model-profiles.d.ts +4 -4
- package/dist/features/ai/use-model-profiles.js +2 -2
- package/dist/features/ai/use-model-profiles.js.map +1 -1
- package/dist/features/block-ui/block-actions.d.ts +8 -4
- package/dist/features/block-ui/block-actions.js +38 -22
- package/dist/features/block-ui/block-actions.js.map +1 -1
- package/dist/features/block-ui/block-target.d.ts +29 -0
- package/dist/features/block-ui/block-target.js +63 -0
- package/dist/features/block-ui/block-target.js.map +1 -0
- package/dist/features/block-ui/components/BlockHandles.js +3 -3
- package/dist/features/block-ui/components/BlockHandles.js.map +1 -1
- package/dist/features/block-ui/components/BlockUi.js +11 -23
- package/dist/features/block-ui/components/BlockUi.js.map +1 -1
- package/dist/features/block-ui/feature.d.ts +3 -2
- package/dist/features/block-ui/feature.js +3 -2
- package/dist/features/block-ui/feature.js.map +1 -1
- package/dist/features/block-ui/handle-geometry.js +12 -23
- package/dist/features/block-ui/handle-geometry.js.map +1 -1
- package/dist/features/block-ui/index.d.ts +2 -1
- package/dist/features/block-ui/index.js +2 -1
- package/dist/features/block-ui/react/BlockHandles.d.ts +1 -1
- package/dist/features/block-ui/react/BlockHandles.js +4 -4
- package/dist/features/block-ui/react/BlockHandles.js.map +1 -1
- package/dist/features/block-ui/react/BlockUi.js +13 -25
- package/dist/features/block-ui/react/BlockUi.js.map +1 -1
- package/dist/features/comments/model.js +1 -1
- package/dist/features/composites/accepted-children.d.ts +5 -4
- package/dist/features/composites/accepted-children.js +26 -26
- package/dist/features/composites/accepted-children.js.map +1 -1
- package/dist/features/composites/ai-brief.d.ts +4 -4
- package/dist/features/composites/ai-brief.js +14 -12
- package/dist/features/composites/ai-brief.js.map +1 -1
- package/dist/features/composites/anchors.d.ts +1 -1
- package/dist/features/composites/anchors.js.map +1 -1
- package/dist/features/composites/baskets.d.ts +1 -1
- package/dist/features/composites/baskets.js.map +1 -1
- package/dist/features/composites/bibliography-command.d.ts +1 -1
- package/dist/features/composites/bibliography-form.js +1 -1
- package/dist/features/composites/bibliography-form.js.map +1 -1
- package/dist/features/composites/bibliography.js.map +1 -1
- package/dist/features/composites/block-types-json.d.ts +38 -0
- package/dist/features/composites/block-types-json.js +122 -0
- package/dist/features/composites/block-types-json.js.map +1 -0
- package/dist/features/composites/block-types.d.ts +119 -0
- package/dist/features/composites/block-types.js +343 -0
- package/dist/features/composites/block-types.js.map +1 -0
- package/dist/features/composites/capabilities.js +109 -0
- package/dist/features/composites/capabilities.js.map +1 -0
- package/dist/features/composites/components/BibliographyEditor.js +5 -5
- package/dist/features/composites/components/BibliographyEditor.js.map +1 -1
- package/dist/features/composites/components/CompositeBasketMenu.js +2 -2
- package/dist/features/composites/components/CompositeBasketMenu.js.map +1 -1
- package/dist/features/composites/components/CompositeChrome.js +18 -8
- package/dist/features/composites/components/CompositeChrome.js.map +1 -1
- package/dist/features/composites/components/CompositeChrome.vue.d.ts +1 -1
- package/dist/features/composites/components/CompositeDetails.js +11 -10
- package/dist/features/composites/components/CompositeDetails.js.map +1 -1
- package/dist/features/composites/components/CompositeDetails.vue.d.ts +1 -1
- package/dist/features/composites/components/CompositeFieldEditor.js +7 -7
- package/dist/features/composites/components/CompositeFieldEditor.js.map +1 -1
- package/dist/features/composites/components/CompositeFieldEditor.vue.d.ts +5 -5
- package/dist/features/composites/components/CompositeInspector.js +136 -113
- package/dist/features/composites/components/CompositeInspector.js.map +1 -1
- package/dist/features/composites/components/CompositeInspector.vue.d.ts +3 -3
- package/dist/features/composites/components/CompositeStatusMenu.js +2 -2
- package/dist/features/composites/components/CompositeStatusMenu.js.map +1 -1
- package/dist/features/composites/components/CompositeSummaryEditor.js +1 -1
- package/dist/features/composites/components/CompositeSummaryEditor.js.map +1 -1
- package/dist/features/composites/components/CompositeSummaryEditor.vue.d.ts +1 -1
- package/dist/features/composites/components/CompositeTable.js +2 -2
- package/dist/features/composites/components/CompositeTable.js.map +1 -1
- package/dist/features/composites/components/CompositeTagsEditor.js +1 -1
- package/dist/features/composites/components/CompositeTagsEditor.js.map +1 -1
- package/dist/features/composites/components/CompositeTagsEditor.vue.d.ts +1 -1
- package/dist/features/composites/components/CompositeView.js +19 -17
- package/dist/features/composites/components/CompositeView.js.map +1 -1
- package/dist/features/composites/components/DerivationBadge.js +15 -6
- package/dist/features/composites/components/DerivationBadge.js.map +1 -1
- package/dist/features/composites/components/FocusChip.js +1 -1
- package/dist/features/composites/components/FocusChip.js.map +1 -1
- package/dist/features/composites/components/FocusChip.vue.d.ts +1 -1
- package/dist/features/composites/components/ReferenceFieldSelect.js +3 -3
- package/dist/features/composites/components/ReferenceFieldSelect.js.map +1 -1
- package/dist/features/composites/components/ReferenceView.js +1 -1
- package/dist/features/composites/components/ReferenceView.js.map +1 -1
- package/dist/features/composites/components/SettingsEditingTab.js +18 -18
- package/dist/features/composites/components/SettingsEditingTab.js.map +1 -1
- package/dist/features/composites/components/SettingsEditingTab.vue.d.ts +3 -3
- package/dist/features/composites/convert.d.ts +4 -4
- package/dist/features/composites/convert.js +27 -28
- package/dist/features/composites/convert.js.map +1 -1
- package/dist/features/composites/derived-chrome.js +34 -28
- package/dist/features/composites/derived-chrome.js.map +1 -1
- package/dist/features/composites/editing-settings-keys.js +6 -6
- package/dist/features/composites/editing-settings-keys.js.map +1 -1
- package/dist/features/composites/feature.d.ts +10 -10
- package/dist/features/composites/feature.js +58 -46
- package/dist/features/composites/feature.js.map +1 -1
- package/dist/features/composites/fences.d.ts +3 -3
- package/dist/features/composites/fences.js +18 -13
- package/dist/features/composites/fences.js.map +1 -1
- package/dist/features/composites/focus.d.ts +10 -10
- package/dist/features/composites/focus.js +11 -11
- package/dist/features/composites/focus.js.map +1 -1
- package/dist/features/composites/heading-composites.d.ts +5 -5
- package/dist/features/composites/heading-composites.js +13 -16
- package/dist/features/composites/heading-composites.js.map +1 -1
- package/dist/features/composites/index.d.ts +20 -18
- package/dist/features/composites/index.js +9 -7
- package/dist/features/composites/inspector-model.d.ts +45 -22
- package/dist/features/composites/inspector-model.js +53 -14
- package/dist/features/composites/inspector-model.js.map +1 -1
- package/dist/features/composites/legacy.d.ts +5 -4
- package/dist/features/composites/legacy.js +16 -23
- package/dist/features/composites/legacy.js.map +1 -1
- package/dist/features/composites/markdown-export.js +3 -3
- package/dist/features/composites/markdown-export.js.map +1 -1
- package/dist/features/composites/merge.d.ts +8 -8
- package/dist/features/composites/merge.js +23 -22
- package/dist/features/composites/merge.js.map +1 -1
- package/dist/features/composites/meta-display.js +5 -5
- package/dist/features/composites/meta-display.js.map +1 -1
- package/dist/features/composites/meta-keys.d.ts +5 -5
- package/dist/features/composites/meta-keys.js +8 -8
- package/dist/features/composites/meta-keys.js.map +1 -1
- package/dist/features/composites/node-views.d.ts +3 -3
- package/dist/features/composites/node-views.js +2 -2
- package/dist/features/composites/node-views.js.map +1 -1
- package/dist/features/composites/nodes.d.ts +13 -13
- package/dist/features/composites/nodes.js +100 -77
- package/dist/features/composites/nodes.js.map +1 -1
- package/dist/features/composites/outline.d.ts +15 -12
- package/dist/features/composites/outline.js +24 -21
- package/dist/features/composites/outline.js.map +1 -1
- package/dist/features/composites/properties.d.ts +51 -0
- package/dist/features/composites/properties.js +89 -0
- package/dist/features/composites/properties.js.map +1 -0
- package/dist/features/composites/react/BibliographyEditor.js +5 -5
- package/dist/features/composites/react/BibliographyEditor.js.map +1 -1
- package/dist/features/composites/react/CompositeBasketMenu.js +2 -2
- package/dist/features/composites/react/CompositeBasketMenu.js.map +1 -1
- package/dist/features/composites/react/CompositeChrome.d.ts +1 -1
- package/dist/features/composites/react/CompositeChrome.js +15 -6
- package/dist/features/composites/react/CompositeChrome.js.map +1 -1
- package/dist/features/composites/react/CompositeDetails.d.ts +1 -1
- package/dist/features/composites/react/CompositeDetails.js +11 -10
- package/dist/features/composites/react/CompositeDetails.js.map +1 -1
- package/dist/features/composites/react/CompositeFieldEditor.d.ts +5 -5
- package/dist/features/composites/react/CompositeFieldEditor.js +6 -6
- package/dist/features/composites/react/CompositeFieldEditor.js.map +1 -1
- package/dist/features/composites/react/CompositeInspector.d.ts +3 -3
- package/dist/features/composites/react/CompositeInspector.js +142 -128
- package/dist/features/composites/react/CompositeInspector.js.map +1 -1
- package/dist/features/composites/react/CompositeStatusMenu.js +2 -2
- package/dist/features/composites/react/CompositeStatusMenu.js.map +1 -1
- package/dist/features/composites/react/CompositeSummaryEditor.d.ts +1 -1
- package/dist/features/composites/react/CompositeSummaryEditor.js +1 -1
- package/dist/features/composites/react/CompositeSummaryEditor.js.map +1 -1
- package/dist/features/composites/react/CompositeTable.d.ts +1 -1
- package/dist/features/composites/react/CompositeTable.js +3 -3
- package/dist/features/composites/react/CompositeTable.js.map +1 -1
- package/dist/features/composites/react/CompositeTagsEditor.d.ts +1 -1
- package/dist/features/composites/react/CompositeTagsEditor.js +1 -1
- package/dist/features/composites/react/CompositeTagsEditor.js.map +1 -1
- package/dist/features/composites/react/CompositeView.js +17 -15
- package/dist/features/composites/react/CompositeView.js.map +1 -1
- package/dist/features/composites/react/DerivationBadge.js +13 -4
- package/dist/features/composites/react/DerivationBadge.js.map +1 -1
- package/dist/features/composites/react/FocusChip.d.ts +1 -1
- package/dist/features/composites/react/FocusChip.js +1 -1
- package/dist/features/composites/react/FocusChip.js.map +1 -1
- package/dist/features/composites/react/ReferenceFieldSelect.js +3 -3
- package/dist/features/composites/react/ReferenceFieldSelect.js.map +1 -1
- package/dist/features/composites/react/ReferenceView.d.ts +1 -1
- package/dist/features/composites/react/ReferenceView.js +1 -1
- package/dist/features/composites/react/ReferenceView.js.map +1 -1
- package/dist/features/composites/react/SettingsEditingTab.d.ts +4 -4
- package/dist/features/composites/react/SettingsEditingTab.js +20 -20
- package/dist/features/composites/react/SettingsEditingTab.js.map +1 -1
- package/dist/features/composites/react.js +1 -1
- package/dist/features/composites/react.js.map +1 -1
- package/dist/features/composites/reference-ai.js +1 -1
- package/dist/features/composites/reference-ai.js.map +1 -1
- package/dist/features/composites/reference-label.d.ts +3 -3
- package/dist/features/composites/reference-label.js +6 -6
- package/dist/features/composites/reference-label.js.map +1 -1
- package/dist/features/composites/reference-suggestion.d.ts +1 -1
- package/dist/features/composites/reference-suggestion.js +3 -3
- package/dist/features/composites/reference-suggestion.js.map +1 -1
- package/dist/features/composites/reference-text.d.ts +2 -2
- package/dist/features/composites/reference-text.js +4 -4
- package/dist/features/composites/reference-text.js.map +1 -1
- package/dist/features/composites/reference.d.ts +3 -3
- package/dist/features/composites/reference.js +1 -1
- package/dist/features/composites/reference.js.map +1 -1
- package/dist/features/composites/reveal-source.d.ts +3 -3
- package/dist/features/composites/reveal-source.js +6 -6
- package/dist/features/composites/reveal-source.js.map +1 -1
- package/dist/features/composites/rows-model.d.ts +2 -2
- package/dist/features/composites/rows-model.js +4 -3
- package/dist/features/composites/rows-model.js.map +1 -1
- package/dist/features/composites/rows.d.ts +16 -28
- package/dist/features/composites/rows.js +20 -54
- package/dist/features/composites/rows.js.map +1 -1
- package/dist/features/composites/schema.d.ts +12 -11
- package/dist/features/composites/schema.js +10 -9
- package/dist/features/composites/schema.js.map +1 -1
- package/dist/features/composites/source.d.ts +20 -0
- package/dist/features/composites/source.js +40 -0
- package/dist/features/composites/source.js.map +1 -0
- package/dist/features/composites/split.d.ts +11 -11
- package/dist/features/composites/split.js +20 -20
- package/dist/features/composites/split.js.map +1 -1
- package/dist/features/composites/structure-mode.js +3 -3
- package/dist/features/composites/structure-mode.js.map +1 -1
- package/dist/features/composites/table-model.js +2 -2
- package/dist/features/composites/table-model.js.map +1 -1
- package/dist/features/composites/use-composite-inspector.js +3 -1
- package/dist/features/composites/use-composite-inspector.js.map +1 -1
- package/dist/features/composites/use-composite-rows.d.ts +2 -2
- package/dist/features/composites/use-composite-rows.js.map +1 -1
- package/dist/features/composites/vue.js +1 -1
- package/dist/features/composites/vue.js.map +1 -1
- package/dist/features/image-studio/components/ImageStudioDialog.js +150 -87
- package/dist/features/image-studio/components/ImageStudioDialog.js.map +1 -1
- package/dist/features/image-studio/components/ImageStudioDialog.vue.d.ts +5 -1
- package/dist/features/image-studio/components/ImageStudioLibraryPanel.js +186 -0
- package/dist/features/image-studio/components/ImageStudioLibraryPanel.js.map +1 -0
- package/dist/features/image-studio/components/ImageStudioLibraryTile.js +134 -0
- package/dist/features/image-studio/components/ImageStudioLibraryTile.js.map +1 -0
- package/dist/features/image-studio/components/ImageStudioView.js.map +1 -1
- package/dist/features/image-studio/feature.d.ts +1 -1
- package/dist/features/image-studio/feature.js +1 -1
- package/dist/features/image-studio/feature.js.map +1 -1
- package/dist/features/image-studio/index.d.ts +3 -2
- package/dist/features/image-studio/index.js +2 -2
- package/dist/features/image-studio/library.d.ts +35 -0
- package/dist/features/image-studio/node-core.d.ts +3 -3
- package/dist/features/image-studio/node-core.js +1 -1
- package/dist/features/image-studio/node-core.js.map +1 -1
- package/dist/features/image-studio/node-store.d.ts +1 -1
- package/dist/features/image-studio/node-store.js +1 -1
- package/dist/features/image-studio/node-store.js.map +1 -1
- package/dist/features/image-studio/react/ImageStudioDialog.d.ts +1 -1
- package/dist/features/image-studio/react/ImageStudioDialog.js +46 -5
- package/dist/features/image-studio/react/ImageStudioDialog.js.map +1 -1
- package/dist/features/image-studio/react/ImageStudioLibraryPanel.js +141 -0
- package/dist/features/image-studio/react/ImageStudioLibraryPanel.js.map +1 -0
- package/dist/features/image-studio/react/ImageStudioLibraryTile.js +105 -0
- package/dist/features/image-studio/react/ImageStudioLibraryTile.js.map +1 -0
- package/dist/features/image-studio/react/ImageStudioView.js +1 -1
- package/dist/features/image-studio/react/ImageStudioView.js.map +1 -1
- package/dist/features/image-studio/react/store.d.ts +8 -3
- package/dist/features/image-studio/react/store.js.map +1 -1
- package/dist/features/image-studio/react.d.ts +4 -3
- package/dist/features/image-studio/react.js +3 -3
- package/dist/features/image-studio/react.js.map +1 -1
- package/dist/features/image-studio/schema.d.ts +1 -1
- package/dist/features/image-studio/schema.js +1 -1
- package/dist/features/image-studio/schema.js.map +1 -1
- package/dist/features/image-studio/state.d.ts +8 -3
- package/dist/features/image-studio/state.js +11 -3
- package/dist/features/image-studio/state.js.map +1 -1
- package/dist/features/image-studio/store.d.ts +8 -3
- package/dist/features/image-studio/vue.d.ts +4 -3
- package/dist/features/image-studio/vue.js +3 -3
- package/dist/features/image-studio/vue.js.map +1 -1
- package/dist/features/mentions/tag.js +2 -1
- package/dist/features/mentions/tag.js.map +1 -1
- package/dist/features/themes/components/SettingsAppearanceTab.js +1 -1
- package/dist/features/themes/components/SettingsAppearanceTab.js.map +1 -1
- package/dist/features/themes/feature.d.ts +1 -1
- package/dist/features/themes/feature.js.map +1 -1
- package/dist/features/themes/react/SettingsAppearanceTab.d.ts +1 -1
- package/dist/features/themes/react/SettingsAppearanceTab.js +1 -1
- package/dist/features/themes/react/SettingsAppearanceTab.js.map +1 -1
- package/dist/features/themes/theme-runtime.js +1 -1
- package/dist/features/themes/theme-runtime.js.map +1 -1
- package/dist/features/transcript/TranscriptSegmentView.js +1 -1
- package/dist/features/transcript/TranscriptSegmentView.js.map +1 -1
- package/dist/features/transcript/react/TranscriptSegmentView.js +1 -1
- package/dist/features/transcript/react/TranscriptSegmentView.js.map +1 -1
- package/dist/features/transcript/segment-node.js.map +1 -1
- package/dist/features/transfer/feature.js +1 -1
- package/dist/features/transfer/feature.js.map +1 -1
- package/dist/features/transfer/transforms.d.ts +4 -4
- package/dist/features/transfer/transforms.js +12 -12
- package/dist/features/transfer/transforms.js.map +1 -1
- package/dist/i18n/de/ai.js +4 -4
- package/dist/i18n/de/ai.js.map +1 -1
- package/dist/i18n/de/authors.js +1 -1
- package/dist/i18n/de/authors.js.map +1 -1
- package/dist/i18n/de/comments.js +1 -1
- package/dist/i18n/de/comments.js.map +1 -1
- package/dist/i18n/de/composites.js +62 -59
- package/dist/i18n/de/composites.js.map +1 -1
- package/dist/i18n/de/image-studio.js +11 -2
- package/dist/i18n/de/image-studio.js.map +1 -1
- package/dist/i18n/de/integrations.js +20 -20
- package/dist/i18n/de/integrations.js.map +1 -1
- package/dist/i18n/de/markdown.js +1 -1
- package/dist/i18n/de/markdown.js.map +1 -1
- package/dist/i18n/de/palette.js +1 -1
- package/dist/i18n/de/palette.js.map +1 -1
- package/dist/i18n/de/themes.js +3 -3
- package/dist/i18n/de/themes.js.map +1 -1
- package/dist/i18n/de/transfer.js +2 -2
- package/dist/i18n/de/transfer.js.map +1 -1
- package/dist/i18n/de/tree.js +6 -6
- package/dist/i18n/de/tree.js.map +1 -1
- package/dist/i18n/de.d.ts +110 -98
- package/dist/i18n/en/ai.js +2 -2
- package/dist/i18n/en/ai.js.map +1 -1
- package/dist/i18n/en/composites.js +64 -61
- package/dist/i18n/en/composites.js.map +1 -1
- package/dist/i18n/en/image-studio.js +9 -0
- package/dist/i18n/en/image-studio.js.map +1 -1
- package/dist/i18n/en/integrations.js +9 -9
- package/dist/i18n/en/integrations.js.map +1 -1
- package/dist/i18n/en/markdown.js +1 -1
- package/dist/i18n/en/markdown.js.map +1 -1
- package/dist/i18n/en/palette.js +1 -1
- package/dist/i18n/en/palette.js.map +1 -1
- package/dist/i18n/en/themes.js +4 -4
- package/dist/i18n/en/themes.js.map +1 -1
- package/dist/i18n/en/tree.js +5 -5
- package/dist/i18n/en/tree.js.map +1 -1
- package/dist/index.d.ts +4 -1
- package/dist/integrations/composite-ai/bibliography-fetch.d.ts +6 -6
- package/dist/integrations/composite-ai/bibliography-fetch.js +19 -19
- package/dist/integrations/composite-ai/bibliography-fetch.js.map +1 -1
- package/dist/integrations/composite-ai/composite-fill.d.ts +4 -4
- package/dist/integrations/composite-ai/composite-fill.js +5 -5
- package/dist/integrations/composite-ai/composite-fill.js.map +1 -1
- package/dist/integrations/composite-ai/composite-summary.d.ts +2 -2
- package/dist/integrations/composite-ai/composite-summary.js +5 -5
- package/dist/integrations/composite-ai/composite-summary.js.map +1 -1
- package/dist/integrations/composite-ai/derive.d.ts +17 -17
- package/dist/integrations/composite-ai/derive.js +27 -26
- package/dist/integrations/composite-ai/derive.js.map +1 -1
- package/dist/integrations/composite-ai/index.d.ts +14 -15
- package/dist/integrations/composite-ai/index.js +98 -77
- package/dist/integrations/composite-ai/index.js.map +1 -1
- package/dist/integrations/composite-ai/outline-sanitize.d.ts +1 -1
- package/dist/integrations/composite-ai/outline-sanitize.js +1 -1
- package/dist/integrations/composite-ai/outline-sanitize.js.map +1 -1
- package/dist/integrations/composite-ai/rendition.d.ts +9 -9
- package/dist/integrations/composite-ai/rendition.js +27 -27
- package/dist/integrations/composite-ai/rendition.js.map +1 -1
- package/dist/integrations/composite-ai/split.d.ts +8 -8
- package/dist/integrations/composite-ai/split.js +12 -12
- package/dist/integrations/composite-ai/split.js.map +1 -1
- package/dist/integrations/composite-ai/transfer-transforms.d.ts +2 -2
- package/dist/integrations/composite-ai/transfer-transforms.js +11 -11
- package/dist/integrations/composite-ai/transfer-transforms.js.map +1 -1
- package/dist/integrations/composite-media/index.d.ts +4 -3
- package/dist/integrations/composite-media/index.js +20 -14
- package/dist/integrations/composite-media/index.js.map +1 -1
- package/dist/markdown/MarkdownSurface.vue.d.ts +7 -7
- package/dist/markdown/document.js +1 -1
- package/dist/markdown/document.js.map +1 -1
- package/dist/nuxt/module.d.ts +48 -24
- package/dist/nuxt/module.js.map +1 -1
- package/dist/nuxt/runtime/server/plugins/editor-server.js +3 -2
- package/dist/nuxt/runtime/server/plugins/editor-server.js.map +1 -1
- package/dist/presets/compose.d.ts +6 -6
- package/dist/presets/compose.js +7 -4
- package/dist/presets/compose.js.map +1 -1
- package/dist/react/AdvancedEditor.d.ts +2 -2
- package/dist/react/AdvancedEditor.js +1 -1
- package/dist/react/AdvancedEditor.js.map +1 -1
- package/dist/react/compose.d.ts +1 -1
- package/dist/react/compose.js +1 -1
- package/dist/react/compose.js.map +1 -1
- package/dist/react/composed-surface.d.ts +5 -5
- package/dist/react/composed-surface.js +2 -2
- package/dist/react/composed-surface.js.map +1 -1
- package/dist/server/ai.d.ts +7 -7
- package/dist/server/ai.js +1 -1
- package/dist/server/ai.js.map +1 -1
- package/dist/server/auth.d.ts +1 -1
- package/dist/server/collab-state.d.ts +1 -1
- package/dist/server/collab-state.js.map +1 -1
- package/dist/server/collab.d.ts +4 -4
- package/dist/server/collab.js +22 -17
- package/dist/server/collab.js.map +1 -1
- package/dist/server/handlers/ai.d.ts +9 -6
- package/dist/server/handlers/ai.js +13 -17
- package/dist/server/handlers/ai.js.map +1 -1
- package/dist/server/handlers/context.d.ts +4 -0
- package/dist/server/handlers/context.js.map +1 -1
- package/dist/server/handlers/editor.d.ts +33 -32
- package/dist/server/handlers/editor.js +13 -8
- package/dist/server/handlers/editor.js.map +1 -1
- package/dist/server/handlers/images.d.ts +1 -1
- package/dist/server/handlers/images.js +1 -1
- package/dist/server/handlers/images.js.map +1 -1
- package/dist/server/host.d.ts +4 -0
- package/dist/server/host.js +10 -2
- package/dist/server/host.js.map +1 -1
- package/dist/server/index.d.ts +3 -3
- package/dist/server/ports.d.ts +8 -8
- package/dist/server/ports.js.map +1 -1
- package/dist/settings/index.d.ts +20 -19
- package/dist/settings/index.js +25 -24
- package/dist/settings/index.js.map +1 -1
- package/dist/settings/migrate.d.ts +18 -0
- package/dist/settings/migrate.js +46 -0
- package/dist/settings/migrate.js.map +1 -0
- package/dist/settings/values.d.ts +12 -12
- package/dist/settings/values.js +11 -11
- package/dist/settings/values.js.map +1 -1
- package/dist/styles/composites.css +10 -10
- package/dist/tree/DocumentTree.js +12 -5
- package/dist/tree/DocumentTree.js.map +1 -1
- package/dist/tree/drop-rules.js +5 -5
- package/dist/tree/drop-rules.js.map +1 -1
- package/dist/tree/react/DocumentTree.js +14 -5
- package/dist/tree/react/DocumentTree.js.map +1 -1
- package/dist/tree/tree-host.js +5 -5
- package/dist/tree/tree-host.js.map +1 -1
- package/dist/tree/tree-items.js +34 -28
- package/dist/tree/tree-items.js.map +1 -1
- package/dist/tree/tree-model.js +16 -16
- package/dist/tree/tree-model.js.map +1 -1
- package/dist/tree/tree-rows.js +2 -2
- package/dist/tree/tree-rows.js.map +1 -1
- package/dist/tree/tree-view-model.d.ts +2 -2
- package/dist/tree/tree-view-model.js.map +1 -1
- package/dist/vue/AdvancedEditor.js +2 -2
- package/dist/vue/AdvancedEditor.js.map +1 -1
- package/dist/vue/AdvancedEditor.vue.d.ts +10 -10
- package/dist/vue/SimpleEditor.vue.d.ts +4 -4
- package/dist/vue/components/EditorSurface.vue.d.ts +4 -4
- package/dist/vue/compose.d.ts +1 -1
- package/dist/vue/compose.js +1 -1
- package/dist/vue/compose.js.map +1 -1
- package/package.json +1 -1
- package/dist/features/composites/derivation.d.ts +0 -62
- package/dist/features/composites/derivation.js +0 -102
- package/dist/features/composites/derivation.js.map +0 -1
- package/dist/features/composites/kinds.d.ts +0 -89
- package/dist/features/composites/kinds.js +0 -285
- package/dist/features/composites/kinds.js.map +0 -1
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import { Translate } from "../../i18n/index.js";
|
|
2
|
+
import { BlockTypeData } from "../../core/capabilities.js";
|
|
3
|
+
import { PropertyDefinition } from "../../core/properties.js";
|
|
4
|
+
import { AiContextBlockType } from "../../core/feature.js";
|
|
5
|
+
//#region src/features/composites/block-types.d.ts
|
|
6
|
+
/** Media block types a Block type's `source` capability may name. */
|
|
7
|
+
export declare const SOURCE_MEDIA_TYPES: readonly ["image", "audio", "video", "file"];
|
|
8
|
+
/**
|
|
9
|
+
* What a Block type tells the model beyond its properties. `purpose` goes into every AI request's block model (chat, generate
|
|
10
|
+
* tasks); `instructions`, `instructionsField` and `contentTemplate` are read only by the AI fill of a Typed block (`fillComposite`).
|
|
11
|
+
*/
|
|
12
|
+
export interface BlockTypeAi {
|
|
13
|
+
/** One or two German sentences: what a Typed block of this type is for and what its body holds. */
|
|
14
|
+
purpose: string;
|
|
15
|
+
/** Default instruction for filling the body of a Typed block of this type (what to write, structure, tone). */
|
|
16
|
+
instructions?: string;
|
|
17
|
+
/** Key of a `textarea` property of this type; a Typed block whose value is non-empty replaces `instructions` with it. */
|
|
18
|
+
instructionsField?: string;
|
|
19
|
+
/** AI content template: target text as Markdown; `{key}` placeholders are replaced by the Typed block's `meta[key]` before it goes to the model, unknown ones stay. */
|
|
20
|
+
contentTemplate?: string;
|
|
21
|
+
}
|
|
22
|
+
/** Config of the `properties` capability: the Property definitions of the type (its Block properties live in the Typed block's `meta`). */
|
|
23
|
+
export interface PropertiesConfig {
|
|
24
|
+
definitions: readonly PropertyDefinition[];
|
|
25
|
+
}
|
|
26
|
+
/** Config of the `source` capability: the media block types the type's source may be; `sourceOf` returns the first body child of one of these. */
|
|
27
|
+
export interface SourceConfig {
|
|
28
|
+
media: readonly SourceMedia[];
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Config of the `import` capability: the media an imported file may have for the type to take it (a recording takes audio and
|
|
32
|
+
* video, a figure an image). Absent or empty: the type takes every imported file no other type takes, text and Markdown included.
|
|
33
|
+
*/
|
|
34
|
+
export interface ImportConfig {
|
|
35
|
+
media?: readonly SourceMedia[];
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Config of the built-in `container` capability. `accepts`: the Block types the type accepts as nested Typed blocks, a list of type ids
|
|
39
|
+
* or `'all'`; absent: none (the built-in Folder and Document types declare `'all'`). Content that is no Typed block (paragraphs,
|
|
40
|
+
* lists, ...) is always allowed. Only new moves are checked; documents that already nest against it stay as they are.
|
|
41
|
+
* `nestedAfterContent`: the nested Typed blocks of a Typed block of this type follow its own content, and a merge keeps that order:
|
|
42
|
+
* `mergeCompositeWithNext` merging A = [Ca, Na] and B = [Cb, Nb] (C the leading blocks of the body that are not Typed blocks, N the
|
|
43
|
+
* rest from the first nested Typed block on) gives [Ca, Cb, Na, Nb] instead of [Ca, Na, Cb, Nb]. Default `false`.
|
|
44
|
+
* `root`: the type stands for the file of a document tree: the document tree takes it as the Block type of the store's document rows
|
|
45
|
+
* (its filter lists it with its label and icon). Set on the built-in Document type; default `false`.
|
|
46
|
+
*/
|
|
47
|
+
export interface ContainerConfig {
|
|
48
|
+
accepts?: readonly string[] | 'all';
|
|
49
|
+
nestedAfterContent?: boolean;
|
|
50
|
+
root?: boolean;
|
|
51
|
+
}
|
|
52
|
+
/** The media block types a `source` capability's `media` names. */
|
|
53
|
+
export type SourceMedia = (typeof SOURCE_MEDIA_TYPES)[number];
|
|
54
|
+
/**
|
|
55
|
+
* A Block type: what the `blockType` attribute of a Typed block selects. Data: its presentation (label, icon, chrome placeholders) and
|
|
56
|
+
* the capabilities it lists with their config (`capabilities`), each declared by the Feature that owns the mechanism
|
|
57
|
+
* (`properties`, `source`, `bibliography`, `basket`, `ai-brief`, `references`; the built-in `container`). A capability a type does
|
|
58
|
+
* not list is absent from its Typed blocks; no field on the type itself switches a behaviour.
|
|
59
|
+
*/
|
|
60
|
+
export interface BlockType extends BlockTypeData {
|
|
61
|
+
label: string;
|
|
62
|
+
icon: string;
|
|
63
|
+
/** Placeholder of the empty title row; absent: none. */
|
|
64
|
+
titlePlaceholder?: string;
|
|
65
|
+
/** Placeholder of the empty description row; absent: none. */
|
|
66
|
+
descriptionPlaceholder?: string;
|
|
67
|
+
/**
|
|
68
|
+
* How much of the chrome the type shows. Absent: all of it. `tags: false` hides the tag row of this type (the node stays in the schema, empty).
|
|
69
|
+
* `tone`: a CSS colour or `var(...)` that sets the type apart: a Typed block of this type gets `data-block-type-tone` and `--sk-block-type-tone` on its wrapper
|
|
70
|
+
* (a tinted surface and a left border in the tone) and its tree rows tint the type icon with it. Absent: the type looks as before.
|
|
71
|
+
* `controls: false` makes the chrome of a Typed block of this type read-only although the editor is editable (for a type whose attributes a
|
|
72
|
+
* host guard refuses to change): no basket menu, status menu, title-visibility toggle, tag editing or drag handle on the type icon, and a
|
|
73
|
+
* read-only details popover; an existing basket, status and tags still show as chips. Default `true`.
|
|
74
|
+
*/
|
|
75
|
+
chrome?: {
|
|
76
|
+
tags?: boolean;
|
|
77
|
+
tone?: string;
|
|
78
|
+
controls?: boolean;
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
/** The Property definitions of `type` (its `properties` capability); none when it does not list the capability. */
|
|
82
|
+
export declare const propertiesOf: (type: BlockTypeData) => readonly PropertyDefinition[];
|
|
83
|
+
/** The media block types `type`'s source may be (its `source` capability); undefined when it keeps no source. */
|
|
84
|
+
export declare const sourceMediaOf: (type: BlockTypeData) => readonly SourceMedia[] | undefined;
|
|
85
|
+
/** The AI brief of `type` (its `ai-brief` capability); undefined when it has none: the AI fill of a Typed block is not offered for it. */
|
|
86
|
+
export declare const aiBriefOf: (type: BlockTypeData) => BlockTypeAi | undefined;
|
|
87
|
+
/** The Block types as the AI chat model learns them: id, label, Property definitions as fields and the `ai-brief` purpose. The editor's `aiContext` and the server's own resolution (`EditorServerOptions.blockTypes`) both build it here. */
|
|
88
|
+
export declare const aiBlockTypesOf: (blockTypes: readonly BlockType[]) => AiContextBlockType[];
|
|
89
|
+
/** The nested Typed blocks `type` accepts (the `accepts` of its `container` config); undefined: none. */
|
|
90
|
+
export declare const acceptsOf: (type: BlockTypeData) => readonly string[] | "all" | undefined;
|
|
91
|
+
/** Whether the nested Typed blocks of `type` follow its own content (the `nestedAfterContent` of its `container` config). */
|
|
92
|
+
export declare const nestedAfterContentOf: (type: BlockTypeData) => boolean;
|
|
93
|
+
/** Whether `type` stands for the file of a document tree (the `root` of its `container` config): the Block type of the store's document rows. */
|
|
94
|
+
export declare const isRootBlockType: (type: BlockTypeData) => boolean;
|
|
95
|
+
/**
|
|
96
|
+
* The built-in Block types in the language of `t`. The default set is produced from the translator (labels, placeholders, property
|
|
97
|
+
* labels and status choices are catalog messages), so it is built per translator and memoized; hosts that pass their own
|
|
98
|
+
* types (`compositeFeature({ blockTypes })`, `Composite.configure({ blockTypes })`) keep their labels untouched. Ids, property keys and
|
|
99
|
+
* stored values (`open`, `doing`, `done`) do not depend on the language.
|
|
100
|
+
*/
|
|
101
|
+
export declare function defaultBlockTypes(t: Translate): readonly BlockType[];
|
|
102
|
+
/** Block type `id` from `blockTypes`; an unknown id gets the `section` type's presentation (else the first type's) under its own id and label. */
|
|
103
|
+
export declare function blockTypeOf(blockTypes: readonly BlockType[], id: string): BlockType;
|
|
104
|
+
/**
|
|
105
|
+
* Whether a Typed block of type `parentType` accepts one of type `childType` as nested Typed block. The `accepts` of the type's
|
|
106
|
+
* `container` config in `blockTypes` decides; without one (or for a type `blockTypes` does not list) it accepts none. The built-in Folder and
|
|
107
|
+
* Document types declare `accepts: 'all'` themselves.
|
|
108
|
+
*/
|
|
109
|
+
export declare function acceptsChild(blockTypes: readonly BlockType[], parentType: string, childType: string): boolean;
|
|
110
|
+
/** Whether a Typed block of type `parentType` accepts at least one Block type an imported file can become (one that lists `import`), i.e. whether files can be imported into it. */
|
|
111
|
+
export declare function acceptsImport(blockTypes: readonly BlockType[], parentType: string): boolean;
|
|
112
|
+
/**
|
|
113
|
+
* The Block type an imported file of media `media` (null: text, Markdown or another file the media pipeline does not know) becomes:
|
|
114
|
+
* the first type in `blockTypes` whose `import` capability names `media`, else the first that lists `import` without media (the
|
|
115
|
+
* catch-all). Undefined when no type takes the file; the import then inserts its blocks as they are.
|
|
116
|
+
*/
|
|
117
|
+
export declare function importTypeOf(blockTypes: readonly BlockType[], media: SourceMedia | null): string | undefined;
|
|
118
|
+
//#endregion
|
|
119
|
+
//# sourceMappingURL=block-types.d.ts.map
|
|
@@ -0,0 +1,343 @@
|
|
|
1
|
+
import { blockTypeConfigOf, listsCapability } from "../../core/capabilities.js";
|
|
2
|
+
import { createTranslator } from "../../i18n/index.js";
|
|
3
|
+
//#region src/features/composites/block-types.ts
|
|
4
|
+
/** Media block types a Block type's `source` capability may name. */
|
|
5
|
+
const SOURCE_MEDIA_TYPES = [
|
|
6
|
+
"image",
|
|
7
|
+
"audio",
|
|
8
|
+
"video",
|
|
9
|
+
"file"
|
|
10
|
+
];
|
|
11
|
+
/** The Property definitions of `type` (its `properties` capability); none when it does not list the capability. */
|
|
12
|
+
const propertiesOf = (type) => blockTypeConfigOf(type, "properties")?.definitions ?? [];
|
|
13
|
+
/** The media block types `type`'s source may be (its `source` capability); undefined when it keeps no source. */
|
|
14
|
+
const sourceMediaOf = (type) => blockTypeConfigOf(type, "source")?.media;
|
|
15
|
+
/** The AI brief of `type` (its `ai-brief` capability); undefined when it has none: the AI fill of a Typed block is not offered for it. */
|
|
16
|
+
const aiBriefOf = (type) => blockTypeConfigOf(type, "ai-brief");
|
|
17
|
+
/** The Block types as the AI chat model learns them: id, label, Property definitions as fields and the `ai-brief` purpose. The editor's `aiContext` and the server's own resolution (`EditorServerOptions.blockTypes`) both build it here. */
|
|
18
|
+
const aiBlockTypesOf = (blockTypes) => blockTypes.map((type) => {
|
|
19
|
+
const purpose = aiBriefOf(type)?.purpose;
|
|
20
|
+
return {
|
|
21
|
+
id: type.id,
|
|
22
|
+
label: type.label,
|
|
23
|
+
fields: propertiesOf(type),
|
|
24
|
+
...purpose && { purpose }
|
|
25
|
+
};
|
|
26
|
+
});
|
|
27
|
+
/** The nested Typed blocks `type` accepts (the `accepts` of its `container` config); undefined: none. */
|
|
28
|
+
const acceptsOf = (type) => blockTypeConfigOf(type, "container")?.accepts;
|
|
29
|
+
/** Whether the nested Typed blocks of `type` follow its own content (the `nestedAfterContent` of its `container` config). */
|
|
30
|
+
const nestedAfterContentOf = (type) => blockTypeConfigOf(type, "container")?.nestedAfterContent === true;
|
|
31
|
+
/** Whether `type` stands for the file of a document tree (the `root` of its `container` config): the Block type of the store's document rows. */
|
|
32
|
+
const isRootBlockType = (type) => blockTypeConfigOf(type, "container")?.root === true;
|
|
33
|
+
/**
|
|
34
|
+
* The built-in Block types in the language of `t`. The default set is produced from the translator (labels, placeholders, property
|
|
35
|
+
* labels and status choices are catalog messages), so it is built per translator and memoized; hosts that pass their own
|
|
36
|
+
* types (`compositeFeature({ blockTypes })`, `Composite.configure({ blockTypes })`) keep their labels untouched. Ids, property keys and
|
|
37
|
+
* stored values (`open`, `doing`, `done`) do not depend on the language.
|
|
38
|
+
*/
|
|
39
|
+
function defaultBlockTypes(t) {
|
|
40
|
+
let blockTypes = DEFAULT_BLOCK_TYPES.get(t);
|
|
41
|
+
if (!blockTypes) DEFAULT_BLOCK_TYPES.set(t, blockTypes = buildDefaultBlockTypes(t));
|
|
42
|
+
return blockTypes;
|
|
43
|
+
}
|
|
44
|
+
const DEFAULT_BLOCK_TYPES = /* @__PURE__ */ new WeakMap();
|
|
45
|
+
const container = (accepts, extra = {}) => ({
|
|
46
|
+
id: "container",
|
|
47
|
+
config: {
|
|
48
|
+
accepts,
|
|
49
|
+
...extra
|
|
50
|
+
}
|
|
51
|
+
});
|
|
52
|
+
const properties = (definitions) => ({
|
|
53
|
+
id: "properties",
|
|
54
|
+
config: { definitions }
|
|
55
|
+
});
|
|
56
|
+
const source = (...media) => ({
|
|
57
|
+
id: "source",
|
|
58
|
+
config: { media }
|
|
59
|
+
});
|
|
60
|
+
const aiBrief = (config) => ({
|
|
61
|
+
id: "ai-brief",
|
|
62
|
+
config
|
|
63
|
+
});
|
|
64
|
+
const importing = (...media) => ({
|
|
65
|
+
id: "import",
|
|
66
|
+
config: { media }
|
|
67
|
+
});
|
|
68
|
+
const EXPORT = { id: "export" };
|
|
69
|
+
const BIBLIOGRAPHY = { id: "bibliography" };
|
|
70
|
+
const BASKET = { id: "basket" };
|
|
71
|
+
function buildDefaultBlockTypes(t) {
|
|
72
|
+
const presentation = (id) => ({
|
|
73
|
+
id,
|
|
74
|
+
label: t(`composites.kind.${id}.label`),
|
|
75
|
+
titlePlaceholder: t(`composites.kind.${id}.title`),
|
|
76
|
+
descriptionPlaceholder: t(`composites.kind.${id}.description`)
|
|
77
|
+
});
|
|
78
|
+
return [
|
|
79
|
+
{
|
|
80
|
+
...presentation("section"),
|
|
81
|
+
icon: "i-lucide-layers",
|
|
82
|
+
capabilities: [container("all"), BASKET]
|
|
83
|
+
},
|
|
84
|
+
{
|
|
85
|
+
...presentation("task"),
|
|
86
|
+
icon: "i-lucide-square-check",
|
|
87
|
+
capabilities: [BASKET, properties([
|
|
88
|
+
{
|
|
89
|
+
key: "status",
|
|
90
|
+
label: t("composites.kind.task.field.status"),
|
|
91
|
+
type: "select",
|
|
92
|
+
options: [
|
|
93
|
+
{
|
|
94
|
+
value: "open",
|
|
95
|
+
label: t("composites.kind.task.status.open")
|
|
96
|
+
},
|
|
97
|
+
{
|
|
98
|
+
value: "doing",
|
|
99
|
+
label: t("composites.kind.task.status.doing")
|
|
100
|
+
},
|
|
101
|
+
{
|
|
102
|
+
value: "done",
|
|
103
|
+
label: t("composites.kind.task.status.done")
|
|
104
|
+
}
|
|
105
|
+
]
|
|
106
|
+
},
|
|
107
|
+
{
|
|
108
|
+
key: "due",
|
|
109
|
+
label: t("composites.kind.task.field.due"),
|
|
110
|
+
type: "date"
|
|
111
|
+
},
|
|
112
|
+
{
|
|
113
|
+
key: "assignee",
|
|
114
|
+
label: t("composites.kind.task.field.assignee"),
|
|
115
|
+
type: "text"
|
|
116
|
+
}
|
|
117
|
+
])]
|
|
118
|
+
},
|
|
119
|
+
{
|
|
120
|
+
...presentation("note"),
|
|
121
|
+
icon: "i-lucide-sticky-note",
|
|
122
|
+
capabilities: [BASKET, aiBrief({ purpose: "Eigene Notiz zu einer Quelle oder einem Thema: Zusammenfassung, Gedanken, offene Fragen." })]
|
|
123
|
+
},
|
|
124
|
+
{
|
|
125
|
+
...presentation("document"),
|
|
126
|
+
icon: "i-lucide-file-text",
|
|
127
|
+
capabilities: [
|
|
128
|
+
container("all", { root: true }),
|
|
129
|
+
source(...SOURCE_MEDIA_TYPES),
|
|
130
|
+
importing(),
|
|
131
|
+
EXPORT,
|
|
132
|
+
BASKET,
|
|
133
|
+
properties([
|
|
134
|
+
{
|
|
135
|
+
key: "filename",
|
|
136
|
+
label: t("composites.kind.document.field.filename"),
|
|
137
|
+
type: "text"
|
|
138
|
+
},
|
|
139
|
+
{
|
|
140
|
+
key: "mimeType",
|
|
141
|
+
label: t("composites.kind.document.field.mimeType"),
|
|
142
|
+
type: "text"
|
|
143
|
+
},
|
|
144
|
+
{
|
|
145
|
+
key: "size",
|
|
146
|
+
label: t("composites.kind.document.field.size"),
|
|
147
|
+
type: "number"
|
|
148
|
+
},
|
|
149
|
+
{
|
|
150
|
+
key: "importedAt",
|
|
151
|
+
label: t("composites.kind.document.field.importedAt"),
|
|
152
|
+
type: "date"
|
|
153
|
+
}
|
|
154
|
+
])
|
|
155
|
+
]
|
|
156
|
+
},
|
|
157
|
+
{
|
|
158
|
+
...presentation("recording"),
|
|
159
|
+
icon: "i-lucide-mic",
|
|
160
|
+
capabilities: [
|
|
161
|
+
container("all"),
|
|
162
|
+
source("audio", "video"),
|
|
163
|
+
importing("audio", "video"),
|
|
164
|
+
BASKET,
|
|
165
|
+
properties([
|
|
166
|
+
...importProperties(t, "recording"),
|
|
167
|
+
{
|
|
168
|
+
key: "recordedAt",
|
|
169
|
+
label: t("composites.kind.recording.field.recordedAt"),
|
|
170
|
+
type: "date"
|
|
171
|
+
},
|
|
172
|
+
{
|
|
173
|
+
key: "participants",
|
|
174
|
+
label: t("composites.kind.recording.field.participants"),
|
|
175
|
+
type: "text"
|
|
176
|
+
},
|
|
177
|
+
{
|
|
178
|
+
key: "durationSeconds",
|
|
179
|
+
label: t("composites.kind.recording.field.durationSeconds"),
|
|
180
|
+
type: "number"
|
|
181
|
+
}
|
|
182
|
+
]),
|
|
183
|
+
aiBrief({ purpose: "Aufnahme (Audio oder Video) als Quelle; der Inhalt hält lesbare Fassungen wie das Transkript und eigene Notizen." })
|
|
184
|
+
]
|
|
185
|
+
},
|
|
186
|
+
{
|
|
187
|
+
...presentation("paper"),
|
|
188
|
+
icon: "i-lucide-scroll-text",
|
|
189
|
+
capabilities: [
|
|
190
|
+
container("all"),
|
|
191
|
+
source("file"),
|
|
192
|
+
BIBLIOGRAPHY,
|
|
193
|
+
BASKET,
|
|
194
|
+
properties([
|
|
195
|
+
...importProperties(t, "paper"),
|
|
196
|
+
{
|
|
197
|
+
key: "bib",
|
|
198
|
+
label: t("composites.kind.paper.field.bib"),
|
|
199
|
+
type: "bibliography"
|
|
200
|
+
},
|
|
201
|
+
{
|
|
202
|
+
key: "doi",
|
|
203
|
+
label: t("composites.kind.paper.field.doi"),
|
|
204
|
+
type: "text"
|
|
205
|
+
}
|
|
206
|
+
]),
|
|
207
|
+
aiBrief({ purpose: "Wissenschaftliche Arbeit als Quelle (PDF) mit Literaturangabe; der Inhalt hält Volltext, Zusammenfassungen und Notizen." })
|
|
208
|
+
]
|
|
209
|
+
},
|
|
210
|
+
{
|
|
211
|
+
...presentation("book"),
|
|
212
|
+
icon: "i-lucide-book",
|
|
213
|
+
capabilities: [
|
|
214
|
+
container("all"),
|
|
215
|
+
source("file"),
|
|
216
|
+
BIBLIOGRAPHY,
|
|
217
|
+
BASKET,
|
|
218
|
+
properties([
|
|
219
|
+
...importProperties(t, "book"),
|
|
220
|
+
{
|
|
221
|
+
key: "bib",
|
|
222
|
+
label: t("composites.kind.book.field.bib"),
|
|
223
|
+
type: "bibliography"
|
|
224
|
+
},
|
|
225
|
+
{
|
|
226
|
+
key: "isbn",
|
|
227
|
+
label: t("composites.kind.book.field.isbn"),
|
|
228
|
+
type: "text"
|
|
229
|
+
}
|
|
230
|
+
]),
|
|
231
|
+
aiBrief({ purpose: "Buch als Quelle (PDF) mit Literaturangabe; der Inhalt hält den Volltext, gegliedert in Kapitel, und Notizen." })
|
|
232
|
+
]
|
|
233
|
+
},
|
|
234
|
+
{
|
|
235
|
+
...presentation("figure"),
|
|
236
|
+
icon: "i-lucide-image",
|
|
237
|
+
capabilities: [
|
|
238
|
+
container("all"),
|
|
239
|
+
source("image"),
|
|
240
|
+
importing("image"),
|
|
241
|
+
BASKET,
|
|
242
|
+
properties([...importProperties(t, "figure"), {
|
|
243
|
+
key: "credit",
|
|
244
|
+
label: t("composites.kind.figure.field.credit"),
|
|
245
|
+
type: "text"
|
|
246
|
+
}]),
|
|
247
|
+
aiBrief({ purpose: "Bild als Quelle; der Inhalt hält die Bildbeschreibung und eigene Notizen." })
|
|
248
|
+
]
|
|
249
|
+
},
|
|
250
|
+
{
|
|
251
|
+
...presentation("rendition"),
|
|
252
|
+
icon: "i-lucide-captions",
|
|
253
|
+
capabilities: [
|
|
254
|
+
container("all"),
|
|
255
|
+
BASKET,
|
|
256
|
+
properties([{
|
|
257
|
+
key: "derivation",
|
|
258
|
+
label: t("composites.kind.rendition.field.derivation"),
|
|
259
|
+
type: "derivation"
|
|
260
|
+
}, {
|
|
261
|
+
key: "language",
|
|
262
|
+
label: t("composites.kind.rendition.field.language"),
|
|
263
|
+
type: "text"
|
|
264
|
+
}]),
|
|
265
|
+
aiBrief({
|
|
266
|
+
purpose: "Lesbare Fassung einer Quelle (Transkript, Volltext, Beschreibung, Übersetzung)",
|
|
267
|
+
instructions: "Übertrage den Inhalt vollständig und gut lesbar; nichts weglassen, nichts hinzuerfinden."
|
|
268
|
+
})
|
|
269
|
+
]
|
|
270
|
+
},
|
|
271
|
+
{
|
|
272
|
+
...presentation("folder"),
|
|
273
|
+
icon: "i-lucide-folder",
|
|
274
|
+
capabilities: [container("all"), BASKET]
|
|
275
|
+
}
|
|
276
|
+
];
|
|
277
|
+
}
|
|
278
|
+
/** The four Property definitions the import of a file fills in (`wrapImport` of `composite-media`), shared by every source-holding Block type. */
|
|
279
|
+
function importProperties(t, type) {
|
|
280
|
+
return [
|
|
281
|
+
{
|
|
282
|
+
key: "filename",
|
|
283
|
+
label: t(`composites.kind.${type}.field.filename`),
|
|
284
|
+
type: "text"
|
|
285
|
+
},
|
|
286
|
+
{
|
|
287
|
+
key: "mimeType",
|
|
288
|
+
label: t(`composites.kind.${type}.field.mimeType`),
|
|
289
|
+
type: "text"
|
|
290
|
+
},
|
|
291
|
+
{
|
|
292
|
+
key: "size",
|
|
293
|
+
label: t(`composites.kind.${type}.field.size`),
|
|
294
|
+
type: "number"
|
|
295
|
+
},
|
|
296
|
+
{
|
|
297
|
+
key: "importedAt",
|
|
298
|
+
label: t(`composites.kind.${type}.field.importedAt`),
|
|
299
|
+
type: "date"
|
|
300
|
+
}
|
|
301
|
+
];
|
|
302
|
+
}
|
|
303
|
+
/** The built-in Block types in the default language, for server-side and context-free code (`Composite`'s default option, an editor without a context). */
|
|
304
|
+
const fallbackBlockTypes = () => defaultBlockTypes(DEFAULT_TRANSLATE);
|
|
305
|
+
const DEFAULT_TRANSLATE = createTranslator();
|
|
306
|
+
/** Block type `id` from `blockTypes`; an unknown id gets the `section` type's presentation (else the first type's) under its own id and label. */
|
|
307
|
+
function blockTypeOf(blockTypes, id) {
|
|
308
|
+
const known = blockTypes.find((type) => type.id === id);
|
|
309
|
+
if (known) return known;
|
|
310
|
+
return {
|
|
311
|
+
...blockTypes.find((type) => type.id === "section") ?? blockTypes[0] ?? fallbackBlockTypes()[0],
|
|
312
|
+
id,
|
|
313
|
+
label: id
|
|
314
|
+
};
|
|
315
|
+
}
|
|
316
|
+
/**
|
|
317
|
+
* Whether a Typed block of type `parentType` accepts one of type `childType` as nested Typed block. The `accepts` of the type's
|
|
318
|
+
* `container` config in `blockTypes` decides; without one (or for a type `blockTypes` does not list) it accepts none. The built-in Folder and
|
|
319
|
+
* Document types declare `accepts: 'all'` themselves.
|
|
320
|
+
*/
|
|
321
|
+
function acceptsChild(blockTypes, parentType, childType) {
|
|
322
|
+
const type = blockTypes.find((candidate) => candidate.id === parentType);
|
|
323
|
+
const accepts = type && acceptsOf(type);
|
|
324
|
+
if (accepts === void 0) return false;
|
|
325
|
+
return accepts === "all" || accepts.includes(childType);
|
|
326
|
+
}
|
|
327
|
+
/** Whether a Typed block of type `parentType` accepts at least one Block type an imported file can become (one that lists `import`), i.e. whether files can be imported into it. */
|
|
328
|
+
function acceptsImport(blockTypes, parentType) {
|
|
329
|
+
return blockTypes.some((type) => listsCapability(type, "import") && acceptsChild(blockTypes, parentType, type.id));
|
|
330
|
+
}
|
|
331
|
+
/**
|
|
332
|
+
* The Block type an imported file of media `media` (null: text, Markdown or another file the media pipeline does not know) becomes:
|
|
333
|
+
* the first type in `blockTypes` whose `import` capability names `media`, else the first that lists `import` without media (the
|
|
334
|
+
* catch-all). Undefined when no type takes the file; the import then inserts its blocks as they are.
|
|
335
|
+
*/
|
|
336
|
+
function importTypeOf(blockTypes, media) {
|
|
337
|
+
const importing = blockTypes.filter((type) => listsCapability(type, "import"));
|
|
338
|
+
return ((media && importing.find((type) => blockTypeConfigOf(type, "import")?.media?.includes(media))) ?? importing.find((type) => !blockTypeConfigOf(type, "import")?.media?.length))?.id;
|
|
339
|
+
}
|
|
340
|
+
//#endregion
|
|
341
|
+
export { SOURCE_MEDIA_TYPES, acceptsChild, acceptsImport, acceptsOf, aiBlockTypesOf, aiBriefOf, blockTypeOf, defaultBlockTypes, fallbackBlockTypes, importTypeOf, isRootBlockType, nestedAfterContentOf, propertiesOf, sourceMediaOf };
|
|
342
|
+
|
|
343
|
+
//# sourceMappingURL=block-types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"block-types.js","names":[],"sources":["../../../src/features/composites/block-types.ts"],"sourcesContent":["// Vue-free and server-importable: the Block type registry of Typed blocks (node `typedBlock`, type id in `attrs.blockType`).\nimport { type BlockTypeCapability, type BlockTypeData, blockTypeConfigOf, listsCapability } from '../../core/capabilities'\nimport type { AiContextBlockType } from '../../core/feature'\nimport type { PropertyDefinition } from '../../core/properties'\nimport { createTranslator, type Translate } from '../../i18n'\n\n/** Media block types a Block type's `source` capability may name. */\nexport const SOURCE_MEDIA_TYPES = ['image', 'audio', 'video', 'file'] as const\n\n/**\n * What a Block type tells the model beyond its properties. `purpose` goes into every AI request's block model (chat, generate\n * tasks); `instructions`, `instructionsField` and `contentTemplate` are read only by the AI fill of a Typed block (`fillComposite`).\n */\nexport interface BlockTypeAi {\n /** One or two German sentences: what a Typed block of this type is for and what its body holds. */\n purpose: string\n /** Default instruction for filling the body of a Typed block of this type (what to write, structure, tone). */\n instructions?: string\n /** Key of a `textarea` property of this type; a Typed block whose value is non-empty replaces `instructions` with it. */\n instructionsField?: string\n /** AI content template: target text as Markdown; `{key}` placeholders are replaced by the Typed block's `meta[key]` before it goes to the model, unknown ones stay. */\n contentTemplate?: string\n}\n\n/** Config of the `properties` capability: the Property definitions of the type (its Block properties live in the Typed block's `meta`). */\nexport interface PropertiesConfig {\n definitions: readonly PropertyDefinition[]\n}\n\n/** Config of the `source` capability: the media block types the type's source may be; `sourceOf` returns the first body child of one of these. */\nexport interface SourceConfig {\n media: readonly SourceMedia[]\n}\n\n/**\n * Config of the `import` capability: the media an imported file may have for the type to take it (a recording takes audio and\n * video, a figure an image). Absent or empty: the type takes every imported file no other type takes, text and Markdown included.\n */\nexport interface ImportConfig {\n media?: readonly SourceMedia[]\n}\n\n/**\n * Config of the built-in `container` capability. `accepts`: the Block types the type accepts as nested Typed blocks, a list of type ids\n * or `'all'`; absent: none (the built-in Folder and Document types declare `'all'`). Content that is no Typed block (paragraphs,\n * lists, ...) is always allowed. Only new moves are checked; documents that already nest against it stay as they are.\n * `nestedAfterContent`: the nested Typed blocks of a Typed block of this type follow its own content, and a merge keeps that order:\n * `mergeCompositeWithNext` merging A = [Ca, Na] and B = [Cb, Nb] (C the leading blocks of the body that are not Typed blocks, N the\n * rest from the first nested Typed block on) gives [Ca, Cb, Na, Nb] instead of [Ca, Na, Cb, Nb]. Default `false`.\n * `root`: the type stands for the file of a document tree: the document tree takes it as the Block type of the store's document rows\n * (its filter lists it with its label and icon). Set on the built-in Document type; default `false`.\n */\nexport interface ContainerConfig {\n accepts?: readonly string[] | 'all'\n nestedAfterContent?: boolean\n root?: boolean\n}\n\n/** The media block types a `source` capability's `media` names. */\nexport type SourceMedia = (typeof SOURCE_MEDIA_TYPES)[number]\n\n/**\n * A Block type: what the `blockType` attribute of a Typed block selects. Data: its presentation (label, icon, chrome placeholders) and\n * the capabilities it lists with their config (`capabilities`), each declared by the Feature that owns the mechanism\n * (`properties`, `source`, `bibliography`, `basket`, `ai-brief`, `references`; the built-in `container`). A capability a type does\n * not list is absent from its Typed blocks; no field on the type itself switches a behaviour.\n */\nexport interface BlockType extends BlockTypeData {\n label: string\n icon: string\n /** Placeholder of the empty title row; absent: none. */\n titlePlaceholder?: string\n /** Placeholder of the empty description row; absent: none. */\n descriptionPlaceholder?: string\n /**\n * How much of the chrome the type shows. Absent: all of it. `tags: false` hides the tag row of this type (the node stays in the schema, empty).\n * `tone`: a CSS colour or `var(...)` that sets the type apart: a Typed block of this type gets `data-block-type-tone` and `--sk-block-type-tone` on its wrapper\n * (a tinted surface and a left border in the tone) and its tree rows tint the type icon with it. Absent: the type looks as before.\n * `controls: false` makes the chrome of a Typed block of this type read-only although the editor is editable (for a type whose attributes a\n * host guard refuses to change): no basket menu, status menu, title-visibility toggle, tag editing or drag handle on the type icon, and a\n * read-only details popover; an existing basket, status and tags still show as chips. Default `true`.\n */\n chrome?: { tags?: boolean, tone?: string, controls?: boolean }\n}\n\n/** The Property definitions of `type` (its `properties` capability); none when it does not list the capability. */\nexport const propertiesOf = (type: BlockTypeData): readonly PropertyDefinition[] => blockTypeConfigOf<PropertiesConfig>(type, 'properties')?.definitions ?? []\n\n/** The media block types `type`'s source may be (its `source` capability); undefined when it keeps no source. */\nexport const sourceMediaOf = (type: BlockTypeData): readonly SourceMedia[] | undefined => blockTypeConfigOf<SourceConfig>(type, 'source')?.media\n\n/** The AI brief of `type` (its `ai-brief` capability); undefined when it has none: the AI fill of a Typed block is not offered for it. */\nexport const aiBriefOf = (type: BlockTypeData): BlockTypeAi | undefined => blockTypeConfigOf<BlockTypeAi>(type, 'ai-brief')\n\n/** The Block types as the AI chat model learns them: id, label, Property definitions as fields and the `ai-brief` purpose. The editor's `aiContext` and the server's own resolution (`EditorServerOptions.blockTypes`) both build it here. */\nexport const aiBlockTypesOf = (blockTypes: readonly BlockType[]): AiContextBlockType[] =>\n blockTypes.map((type) => {\n const purpose = aiBriefOf(type)?.purpose\n return { id: type.id, label: type.label, fields: propertiesOf(type), ...(purpose && { purpose }) }\n })\n\n/** The nested Typed blocks `type` accepts (the `accepts` of its `container` config); undefined: none. */\nexport const acceptsOf = (type: BlockTypeData): readonly string[] | 'all' | undefined => blockTypeConfigOf<ContainerConfig>(type, 'container')?.accepts\n\n/** Whether the nested Typed blocks of `type` follow its own content (the `nestedAfterContent` of its `container` config). */\nexport const nestedAfterContentOf = (type: BlockTypeData): boolean => blockTypeConfigOf<ContainerConfig>(type, 'container')?.nestedAfterContent === true\n\n/** Whether `type` stands for the file of a document tree (the `root` of its `container` config): the Block type of the store's document rows. */\nexport const isRootBlockType = (type: BlockTypeData): boolean => blockTypeConfigOf<ContainerConfig>(type, 'container')?.root === true\n\n/**\n * The built-in Block types in the language of `t`. The default set is produced from the translator (labels, placeholders, property\n * labels and status choices are catalog messages), so it is built per translator and memoized; hosts that pass their own\n * types (`compositeFeature({ blockTypes })`, `Composite.configure({ blockTypes })`) keep their labels untouched. Ids, property keys and\n * stored values (`open`, `doing`, `done`) do not depend on the language.\n */\nexport function defaultBlockTypes(t: Translate): readonly BlockType[] {\n let blockTypes = DEFAULT_BLOCK_TYPES.get(t)\n if (!blockTypes) DEFAULT_BLOCK_TYPES.set(t, blockTypes = buildDefaultBlockTypes(t))\n return blockTypes\n}\n\nconst DEFAULT_BLOCK_TYPES = new WeakMap<Translate, readonly BlockType[]>()\n\nconst container = (accepts: ContainerConfig['accepts'], extra: Omit<ContainerConfig, 'accepts'> = {}): BlockTypeCapability => ({ id: 'container', config: { accepts, ...extra } satisfies ContainerConfig })\nconst properties = (definitions: PropertyDefinition[]): BlockTypeCapability => ({ id: 'properties', config: { definitions } satisfies PropertiesConfig })\nconst source = (...media: SourceMedia[]): BlockTypeCapability => ({ id: 'source', config: { media } satisfies SourceConfig })\nconst aiBrief = (config: BlockTypeAi): BlockTypeCapability => ({ id: 'ai-brief', config })\nconst importing = (...media: SourceMedia[]): BlockTypeCapability => ({ id: 'import', config: { media } satisfies ImportConfig })\nconst EXPORT: BlockTypeCapability = { id: 'export' }\nconst BIBLIOGRAPHY: BlockTypeCapability = { id: 'bibliography' }\nconst BASKET: BlockTypeCapability = { id: 'basket' }\n\nfunction buildDefaultBlockTypes(t: Translate): readonly BlockType[] {\n const presentation = (id: 'section' | 'task' | 'note' | 'document' | 'recording' | 'paper' | 'book' | 'figure' | 'rendition' | 'folder') => ({\n id,\n label: t(`composites.kind.${id}.label`),\n titlePlaceholder: t(`composites.kind.${id}.title`),\n descriptionPlaceholder: t(`composites.kind.${id}.description`),\n })\n return [\n { ...presentation('section'), icon: 'i-lucide-layers', capabilities: [container('all'), BASKET] },\n { ...presentation('task'), icon: 'i-lucide-square-check', capabilities: [BASKET, properties([\n { key: 'status', label: t('composites.kind.task.field.status'), type: 'select', options: [\n { value: 'open', label: t('composites.kind.task.status.open') },\n { value: 'doing', label: t('composites.kind.task.status.doing') },\n { value: 'done', label: t('composites.kind.task.status.done') },\n ] },\n { key: 'due', label: t('composites.kind.task.field.due'), type: 'date' },\n { key: 'assignee', label: t('composites.kind.task.field.assignee'), type: 'text' },\n ])] },\n // i18n-ignore: model-facing kind purpose (German prompt text, not UI)\n { ...presentation('note'), icon: 'i-lucide-sticky-note', capabilities: [BASKET, aiBrief({ purpose: 'Eigene Notiz zu einer Quelle oder einem Thema: Zusammenfassung, Gedanken, offene Fragen.' })] },\n { ...presentation('document'), icon: 'i-lucide-file-text', capabilities: [container('all', { root: true }), source(...SOURCE_MEDIA_TYPES), importing(), EXPORT, BASKET, properties([\n { key: 'filename', label: t('composites.kind.document.field.filename'), type: 'text' },\n { key: 'mimeType', label: t('composites.kind.document.field.mimeType'), type: 'text' },\n { key: 'size', label: t('composites.kind.document.field.size'), type: 'number' },\n { key: 'importedAt', label: t('composites.kind.document.field.importedAt'), type: 'date' },\n ])] },\n // i18n-ignore-start: model-facing kind purposes and instructions (German prompt text, not UI)\n { ...presentation('recording'), icon: 'i-lucide-mic', capabilities: [container('all'), source('audio', 'video'), importing('audio', 'video'), BASKET, properties([\n ...importProperties(t, 'recording'),\n { key: 'recordedAt', label: t('composites.kind.recording.field.recordedAt'), type: 'date' },\n { key: 'participants', label: t('composites.kind.recording.field.participants'), type: 'text' },\n { key: 'durationSeconds', label: t('composites.kind.recording.field.durationSeconds'), type: 'number' },\n ]), aiBrief({ purpose: 'Aufnahme (Audio oder Video) als Quelle; der Inhalt hält lesbare Fassungen wie das Transkript und eigene Notizen.' })] },\n { ...presentation('paper'), icon: 'i-lucide-scroll-text', capabilities: [container('all'), source('file'), BIBLIOGRAPHY, BASKET, properties([\n ...importProperties(t, 'paper'),\n { key: 'bib', label: t('composites.kind.paper.field.bib'), type: 'bibliography' },\n { key: 'doi', label: t('composites.kind.paper.field.doi'), type: 'text' },\n ]), aiBrief({ purpose: 'Wissenschaftliche Arbeit als Quelle (PDF) mit Literaturangabe; der Inhalt hält Volltext, Zusammenfassungen und Notizen.' })] },\n { ...presentation('book'), icon: 'i-lucide-book', capabilities: [container('all'), source('file'), BIBLIOGRAPHY, BASKET, properties([\n ...importProperties(t, 'book'),\n { key: 'bib', label: t('composites.kind.book.field.bib'), type: 'bibliography' },\n { key: 'isbn', label: t('composites.kind.book.field.isbn'), type: 'text' },\n ]), aiBrief({ purpose: 'Buch als Quelle (PDF) mit Literaturangabe; der Inhalt hält den Volltext, gegliedert in Kapitel, und Notizen.' })] },\n { ...presentation('figure'), icon: 'i-lucide-image', capabilities: [container('all'), source('image'), importing('image'), BASKET, properties([\n ...importProperties(t, 'figure'),\n { key: 'credit', label: t('composites.kind.figure.field.credit'), type: 'text' },\n ]), aiBrief({ purpose: 'Bild als Quelle; der Inhalt hält die Bildbeschreibung und eigene Notizen.' })] },\n { ...presentation('rendition'), icon: 'i-lucide-captions', capabilities: [container('all'), BASKET, properties([\n { key: 'derivation', label: t('composites.kind.rendition.field.derivation'), type: 'derivation' },\n { key: 'language', label: t('composites.kind.rendition.field.language'), type: 'text' },\n ]), aiBrief({\n purpose: 'Lesbare Fassung einer Quelle (Transkript, Volltext, Beschreibung, Übersetzung)',\n instructions: 'Übertrage den Inhalt vollständig und gut lesbar; nichts weglassen, nichts hinzuerfinden.',\n })] },\n // i18n-ignore-end\n { ...presentation('folder'), icon: 'i-lucide-folder', capabilities: [container('all'), BASKET] },\n ]\n}\n\n/** The four Property definitions the import of a file fills in (`wrapImport` of `composite-media`), shared by every source-holding Block type. */\nfunction importProperties(t: Translate, type: 'recording' | 'paper' | 'book' | 'figure'): PropertyDefinition[] {\n return [\n { key: 'filename', label: t(`composites.kind.${type}.field.filename`), type: 'text' },\n { key: 'mimeType', label: t(`composites.kind.${type}.field.mimeType`), type: 'text' },\n { key: 'size', label: t(`composites.kind.${type}.field.size`), type: 'number' },\n { key: 'importedAt', label: t(`composites.kind.${type}.field.importedAt`), type: 'date' },\n ]\n}\n\n/** The built-in Block types in the default language, for server-side and context-free code (`Composite`'s default option, an editor without a context). */\nexport const fallbackBlockTypes = (): readonly BlockType[] => defaultBlockTypes(DEFAULT_TRANSLATE)\n\nconst DEFAULT_TRANSLATE = createTranslator()\n\n/** Block type `id` from `blockTypes`; an unknown id gets the `section` type's presentation (else the first type's) under its own id and label. */\nexport function blockTypeOf(blockTypes: readonly BlockType[], id: string): BlockType {\n const known = blockTypes.find(type => type.id === id)\n if (known) return known\n const base = blockTypes.find(type => type.id === 'section') ?? blockTypes[0] ?? fallbackBlockTypes()[0]!\n return { ...base, id, label: id }\n}\n\n/**\n * Whether a Typed block of type `parentType` accepts one of type `childType` as nested Typed block. The `accepts` of the type's\n * `container` config in `blockTypes` decides; without one (or for a type `blockTypes` does not list) it accepts none. The built-in Folder and\n * Document types declare `accepts: 'all'` themselves.\n */\nexport function acceptsChild(blockTypes: readonly BlockType[], parentType: string, childType: string): boolean {\n const type = blockTypes.find(candidate => candidate.id === parentType)\n const accepts = type && acceptsOf(type)\n if (accepts === undefined) return false\n return accepts === 'all' || accepts.includes(childType)\n}\n\n/** Whether a Typed block of type `parentType` accepts at least one Block type an imported file can become (one that lists `import`), i.e. whether files can be imported into it. */\nexport function acceptsImport(blockTypes: readonly BlockType[], parentType: string): boolean {\n return blockTypes.some(type => listsCapability(type, 'import') && acceptsChild(blockTypes, parentType, type.id))\n}\n\n/**\n * The Block type an imported file of media `media` (null: text, Markdown or another file the media pipeline does not know) becomes:\n * the first type in `blockTypes` whose `import` capability names `media`, else the first that lists `import` without media (the\n * catch-all). Undefined when no type takes the file; the import then inserts its blocks as they are.\n */\nexport function importTypeOf(blockTypes: readonly BlockType[], media: SourceMedia | null): string | undefined {\n const importing = blockTypes.filter(type => listsCapability(type, 'import'))\n const named = media && importing.find(type => blockTypeConfigOf<ImportConfig>(type, 'import')?.media?.includes(media))\n return (named ?? importing.find(type => !blockTypeConfigOf<ImportConfig>(type, 'import')?.media?.length))?.id\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import { isBlockContainer } from "../../core/schema/node-flags.js";
|
|
2
|
+
import { listsCapability } from "../../core/capabilities.js";
|
|
3
|
+
import { DERIVATION_KEY, derivationOf } from "../../core/derivation.js";
|
|
4
|
+
import { PROPERTY_TYPES } from "../../core/properties.js";
|
|
5
|
+
import { SOURCE_MEDIA_TYPES } from "./block-types.js";
|
|
6
|
+
import { BASKET_KEY } from "./meta-keys.js";
|
|
7
|
+
import { basketOf } from "./baskets.js";
|
|
8
|
+
import { bibOf } from "./bibliography.js";
|
|
9
|
+
import { sourceIn } from "./source.js";
|
|
10
|
+
import { carriesProperties } from "./properties.js";
|
|
11
|
+
import { z } from "zod";
|
|
12
|
+
//#region src/features/composites/capabilities.ts
|
|
13
|
+
const propertyDefinitionSchema = z.strictObject({
|
|
14
|
+
key: z.string().min(1),
|
|
15
|
+
label: z.string(),
|
|
16
|
+
type: z.enum(PROPERTY_TYPES),
|
|
17
|
+
options: z.array(z.strictObject({
|
|
18
|
+
value: z.string(),
|
|
19
|
+
label: z.string()
|
|
20
|
+
})).optional(),
|
|
21
|
+
targets: z.array(z.string()).optional()
|
|
22
|
+
}).superRefine((definition, ctx) => {
|
|
23
|
+
if (definition.type === "multiselect" && !definition.options?.length) ctx.addIssue({
|
|
24
|
+
code: "custom",
|
|
25
|
+
message: "a multiselect property needs options",
|
|
26
|
+
path: ["options"]
|
|
27
|
+
});
|
|
28
|
+
});
|
|
29
|
+
const propertiesConfigSchema = z.strictObject({ definitions: z.array(propertyDefinitionSchema) });
|
|
30
|
+
const sourceConfigSchema = z.strictObject({ media: z.array(z.enum(SOURCE_MEDIA_TYPES)).min(1) });
|
|
31
|
+
const importConfigSchema = z.strictObject({ media: z.array(z.enum(SOURCE_MEDIA_TYPES)).optional() });
|
|
32
|
+
const aiBriefConfigSchema = z.strictObject({
|
|
33
|
+
purpose: z.string(),
|
|
34
|
+
instructions: z.string().optional(),
|
|
35
|
+
instructionsField: z.string().optional(),
|
|
36
|
+
contentTemplate: z.string().optional()
|
|
37
|
+
});
|
|
38
|
+
/**
|
|
39
|
+
* The capabilities of the composites feature, in the order Block types usually list them. None is structural: each applies to a
|
|
40
|
+
* Typed block whose Block type lists it (`references` also to one with a `reference` property), and only to a node that can hold
|
|
41
|
+
* its data (`meta` attribute, container body).
|
|
42
|
+
*/
|
|
43
|
+
function compositeBlockCapabilities() {
|
|
44
|
+
return [
|
|
45
|
+
{
|
|
46
|
+
id: "properties",
|
|
47
|
+
configSchema: propertiesConfigSchema,
|
|
48
|
+
appliesTo: (node, ctx) => carriesProperties(node) && listsCapability(ctx.blockTypeOf(node), "properties"),
|
|
49
|
+
read: (node, ctx) => {
|
|
50
|
+
const definitions = ctx.configOf(node, "properties")?.definitions ?? [];
|
|
51
|
+
const meta = node.attrs.meta;
|
|
52
|
+
if (!meta || typeof meta !== "object") return {};
|
|
53
|
+
return Object.fromEntries(definitions.flatMap(({ key }) => key in meta ? [[key, meta[key]]] : []));
|
|
54
|
+
}
|
|
55
|
+
},
|
|
56
|
+
{
|
|
57
|
+
id: "source",
|
|
58
|
+
configSchema: sourceConfigSchema,
|
|
59
|
+
appliesTo: (node, ctx) => isBlockContainer(node) && listsCapability(ctx.blockTypeOf(node), "source"),
|
|
60
|
+
read: (node, ctx) => {
|
|
61
|
+
const media = ctx.configOf(node, "source")?.media;
|
|
62
|
+
return media ? sourceIn(node, media) : null;
|
|
63
|
+
},
|
|
64
|
+
storage: { childTypes: SOURCE_MEDIA_TYPES }
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
id: "bibliography",
|
|
68
|
+
appliesTo: (node, ctx) => carriesProperties(node) && listsCapability(ctx.blockTypeOf(node), "bibliography"),
|
|
69
|
+
read: (node) => bibOf(node),
|
|
70
|
+
storage: { metaKeys: ["bib"] }
|
|
71
|
+
},
|
|
72
|
+
{
|
|
73
|
+
id: "basket",
|
|
74
|
+
appliesTo: (node, ctx) => carriesProperties(node) && listsCapability(ctx.blockTypeOf(node), "basket"),
|
|
75
|
+
read: (node) => basketOf(node),
|
|
76
|
+
storage: { metaKeys: [BASKET_KEY] }
|
|
77
|
+
},
|
|
78
|
+
{
|
|
79
|
+
id: "ai-brief",
|
|
80
|
+
configSchema: aiBriefConfigSchema,
|
|
81
|
+
appliesTo: (node, ctx) => listsCapability(ctx.blockTypeOf(node), "ai-brief")
|
|
82
|
+
},
|
|
83
|
+
{
|
|
84
|
+
id: "references",
|
|
85
|
+
appliesTo: (node, ctx) => carriesProperties(node) && (listsCapability(ctx.blockTypeOf(node), "references") || (ctx.configOf(node, "properties")?.definitions.some((definition) => definition.type === "reference") ?? false)),
|
|
86
|
+
storage: { childTypes: ["reference"] }
|
|
87
|
+
},
|
|
88
|
+
{
|
|
89
|
+
id: "import",
|
|
90
|
+
configSchema: importConfigSchema,
|
|
91
|
+
appliesTo: (node, ctx) => isBlockContainer(node) && listsCapability(ctx.blockTypeOf(node), "import")
|
|
92
|
+
},
|
|
93
|
+
{
|
|
94
|
+
id: "export",
|
|
95
|
+
appliesTo: (node, ctx) => isBlockContainer(node) && listsCapability(ctx.blockTypeOf(node), "export")
|
|
96
|
+
},
|
|
97
|
+
{
|
|
98
|
+
id: "derived",
|
|
99
|
+
perNode: true,
|
|
100
|
+
appliesTo: (node) => carriesProperties(node) && derivationOf(node) !== null,
|
|
101
|
+
read: (node) => derivationOf(node),
|
|
102
|
+
storage: { metaKeys: [DERIVATION_KEY] }
|
|
103
|
+
}
|
|
104
|
+
];
|
|
105
|
+
}
|
|
106
|
+
//#endregion
|
|
107
|
+
export { compositeBlockCapabilities };
|
|
108
|
+
|
|
109
|
+
//# sourceMappingURL=capabilities.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"capabilities.js","names":[],"sources":["../../../src/features/composites/capabilities.ts"],"sourcesContent":["// Vue-free and server-importable: the block capabilities the composites feature owns. A Block type (`block-types.ts`) lists them\n// with their config; each answers \"does a Typed block of this type have it\" from the type alone (`appliesTo` is memoised per\n// node type and Block type id) and, where there is per-block data, reads it through `read`: the source child, the basket, the\n// bibliography record, the Block properties. The capability describes; the node, the node views and the commands stay with the feature.\nimport { z } from 'zod'\nimport { type BlockCapability, listsCapability } from '../../core/capabilities'\nimport { isBlockContainer } from '../../core/schema/node-flags'\nimport { basketOf } from './baskets'\nimport { bibOf } from './bibliography'\nimport { type ImportConfig, type PropertiesConfig, type SourceConfig, SOURCE_MEDIA_TYPES } from './block-types'\nimport { derivationOf } from '../../core/derivation'\nimport { PROPERTY_TYPES, type PropertyDefinition } from '../../core/properties'\nimport { sourceIn } from './source'\nimport { BASKET_KEY, BIB_KEY, DERIVATION_KEY } from './meta-keys'\nimport { carriesProperties } from './properties'\n\nconst propertyDefinitionSchema: z.ZodType<PropertyDefinition> = z.strictObject({\n key: z.string().min(1),\n label: z.string(),\n type: z.enum(PROPERTY_TYPES),\n options: z.array(z.strictObject({ value: z.string(), label: z.string() })).optional(),\n targets: z.array(z.string()).optional(),\n}).superRefine((definition, ctx) => {\n // i18n-ignore: developer-facing Block type config error, not UI text\n if (definition.type === 'multiselect' && !definition.options?.length) ctx.addIssue({ code: 'custom', message: 'a multiselect property needs options', path: ['options'] })\n})\n\nconst propertiesConfigSchema: z.ZodType<PropertiesConfig> = z.strictObject({ definitions: z.array(propertyDefinitionSchema) })\n\nconst sourceConfigSchema: z.ZodType<SourceConfig> = z.strictObject({ media: z.array(z.enum(SOURCE_MEDIA_TYPES)).min(1) })\n\nconst importConfigSchema: z.ZodType<ImportConfig> = z.strictObject({ media: z.array(z.enum(SOURCE_MEDIA_TYPES)).optional() })\n\nconst aiBriefConfigSchema = z.strictObject({\n purpose: z.string(),\n instructions: z.string().optional(),\n instructionsField: z.string().optional(),\n contentTemplate: z.string().optional(),\n})\n\n/**\n * The capabilities of the composites feature, in the order Block types usually list them. None is structural: each applies to a\n * Typed block whose Block type lists it (`references` also to one with a `reference` property), and only to a node that can hold\n * its data (`meta` attribute, container body).\n */\nexport function compositeBlockCapabilities(): BlockCapability[] {\n return [\n {\n id: 'properties',\n configSchema: propertiesConfigSchema,\n // The node type carries property values (`meta` attribute, whatever it is called) and the Block type declares Property definitions;\n // the Block properties are the `meta` values of the keys the definitions name.\n appliesTo: (node, ctx) => carriesProperties(node) && listsCapability(ctx.blockTypeOf(node), 'properties'),\n read: (node, ctx) => {\n const definitions = ctx.configOf<PropertiesConfig>(node, 'properties')?.definitions ?? []\n const meta: unknown = node.attrs.meta\n if (!meta || typeof meta !== 'object') return {}\n return Object.fromEntries(definitions.flatMap(({ key }) => key in meta ? [[key, (meta as Record<string, unknown>)[key]]] : []))\n },\n },\n {\n id: 'source',\n configSchema: sourceConfigSchema,\n // The Typed block holds its original as a media block in the body, so the type must give it a container body.\n appliesTo: (node, ctx) => isBlockContainer(node) && listsCapability(ctx.blockTypeOf(node), 'source'),\n // The source block itself (with its asset and hash), or null while the body holds none: the capability is the type's, the child is the block's.\n read: (node, ctx) => {\n const media = ctx.configOf<SourceConfig>(node, 'source')?.media\n return media ? sourceIn(node, media) : null\n },\n storage: { childTypes: SOURCE_MEDIA_TYPES },\n },\n {\n id: 'bibliography',\n appliesTo: (node, ctx) => carriesProperties(node) && listsCapability(ctx.blockTypeOf(node), 'bibliography'),\n // The CSL-JSON item, or null while the block has none.\n read: node => bibOf(node),\n storage: { metaKeys: [BIB_KEY] },\n },\n {\n id: 'basket',\n appliesTo: (node, ctx) => carriesProperties(node) && listsCapability(ctx.blockTypeOf(node), 'basket'),\n // The id of the basket the block is in, or null.\n read: node => basketOf(node),\n storage: { metaKeys: [BASKET_KEY] },\n },\n {\n id: 'ai-brief',\n configSchema: aiBriefConfigSchema,\n appliesTo: (node, ctx) => listsCapability(ctx.blockTypeOf(node), 'ai-brief'),\n },\n {\n id: 'references',\n // Listed explicitly, or implied by a property that points to another Typed block.\n appliesTo: (node, ctx) => carriesProperties(node) && (listsCapability(ctx.blockTypeOf(node), 'references') || (ctx.configOf<PropertiesConfig>(node, 'properties')?.definitions.some(definition => definition.type === 'reference') ?? false)),\n storage: { childTypes: ['reference'] },\n },\n {\n id: 'import',\n configSchema: importConfigSchema,\n // An imported file's blocks go into the container body of a Typed block of this type, which keeps the file's name, type and size as Block properties.\n appliesTo: (node, ctx) => isBlockContainer(node) && listsCapability(ctx.blockTypeOf(node), 'import'),\n },\n {\n id: 'export',\n // The Typed block's contents can be downloaded as a Markdown file (the block action „Exportieren“).\n appliesTo: (node, ctx) => isBlockContainer(node) && listsCapability(ctx.blockTypeOf(node), 'export'),\n },\n {\n id: 'derived',\n // The block was made from another block or an asset (`meta.derivation`). Read from the node, not from the Block type: any Typed block can be derived.\n perNode: true,\n appliesTo: node => carriesProperties(node) && derivationOf(node) !== null,\n // The Derivation: method, original (asset name or block id), model, time and hashes. Where the original is now is `derivationState` / `derivedOf`.\n read: node => derivationOf(node),\n storage: { metaKeys: [DERIVATION_KEY] },\n },\n ]\n}\n"],"mappings":"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"}
|