@ecsplico/editor 2.1.1 → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +74 -1
- package/README.md +39 -156
- package/dist/adapters/comments/drizzle.d.ts +1 -1
- package/dist/adapters/comments/{client.js → rest-model.js} +3 -3
- package/dist/adapters/comments/rest-model.js.map +1 -0
- package/dist/adapters/comments/types.d.ts +2 -2
- package/dist/adapters/document-state.d.ts +23 -0
- package/dist/adapters/document-state.js +66 -0
- package/dist/adapters/document-state.js.map +1 -0
- package/dist/adapters/documents.js +14 -11
- package/dist/adapters/documents.js.map +1 -1
- package/dist/adapters/drizzle.d.ts +2 -2
- package/dist/adapters/drizzle.js +97 -88
- package/dist/adapters/drizzle.js.map +1 -1
- package/dist/adapters/forge.d.ts +12 -7
- package/dist/adapters/forge.js +38 -45
- package/dist/adapters/forge.js.map +1 -1
- package/dist/adapters/http.d.ts +20 -0
- package/dist/adapters/http.js +68 -0
- package/dist/adapters/http.js.map +1 -0
- package/dist/adapters/index.d.ts +5 -5
- package/dist/adapters/json.d.ts +3 -3
- package/dist/adapters/json.js +58 -49
- package/dist/adapters/json.js.map +1 -1
- package/dist/adapters/memory.d.ts +21 -0
- package/dist/adapters/memory.js +53 -0
- package/dist/adapters/memory.js.map +1 -0
- package/dist/adapters/nitro.d.ts +23 -20
- package/dist/adapters/nitro.js +58 -163
- package/dist/adapters/nitro.js.map +1 -1
- package/dist/adapters/react.d.ts +55 -0
- package/dist/adapters/react.js +209 -0
- package/dist/adapters/react.js.map +1 -0
- package/dist/adapters/shared.d.ts +15 -21
- package/dist/adapters/shared.js +10 -8
- package/dist/adapters/shared.js.map +1 -1
- package/dist/adapters/vue.d.ts +15 -30
- package/dist/adapters/vue.js +36 -87
- package/dist/adapters/vue.js.map +1 -1
- package/dist/code/CodeSurface.vue.d.ts +3 -3
- package/dist/config/index.d.ts +105 -0
- package/dist/config/index.js +95 -0
- package/dist/config/index.js.map +1 -0
- package/dist/core/abilities.js +1 -0
- package/dist/core/abilities.js.map +1 -1
- package/dist/{adapters/routes.js → core/api-routes.js} +5 -3
- package/dist/core/api-routes.js.map +1 -0
- package/dist/core/backend-capability.d.ts +7 -0
- package/dist/core/backend-capability.js +17 -0
- package/dist/core/backend-capability.js.map +1 -0
- package/dist/core/backend-types.d.ts +245 -0
- package/dist/core/backend-types.js +17 -0
- package/dist/core/backend-types.js.map +1 -0
- package/dist/core/backend.d.ts +108 -0
- package/dist/core/backend.js +14 -0
- package/dist/core/backend.js.map +1 -0
- package/dist/core/block-convert.d.ts +7 -5
- package/dist/core/block-convert.js +28 -5
- package/dist/core/block-convert.js.map +1 -1
- package/dist/core/command-types.d.ts +89 -0
- package/dist/core/commands.d.ts +40 -0
- package/dist/core/commands.js +151 -0
- package/dist/core/commands.js.map +1 -0
- package/dist/core/context.d.ts +17 -20
- package/dist/core/context.js +24 -21
- package/dist/core/context.js.map +1 -1
- package/dist/core/core-feature.d.ts +22 -7
- package/dist/core/core-feature.js +51 -18
- package/dist/core/core-feature.js.map +1 -1
- package/dist/core/define-editor.d.ts +4 -3
- package/dist/core/define-editor.js +14 -7
- package/dist/core/define-editor.js.map +1 -1
- package/dist/core/document-markdown.js +12 -3
- package/dist/core/document-markdown.js.map +1 -1
- package/dist/core/editor-ui.d.ts +8 -1
- package/dist/core/editor-ui.js +9 -8
- package/dist/core/editor-ui.js.map +1 -1
- package/dist/core/extension-points.d.ts +3 -15
- package/dist/core/feature-context.d.ts +8 -7
- package/dist/core/feature-context.js +12 -11
- package/dist/core/feature-context.js.map +1 -1
- package/dist/core/feature.d.ts +35 -19
- package/dist/core/feature.js.map +1 -1
- package/dist/core/fences.d.ts +2 -1
- package/dist/core/fences.js +3 -2
- package/dist/core/fences.js.map +1 -1
- package/dist/core/fetch-error.d.ts +1 -1
- package/dist/core/fetch-error.js +3 -1
- package/dist/core/fetch-error.js.map +1 -1
- package/dist/core/hash.d.ts +5 -0
- package/dist/core/hash.js +11 -0
- package/dist/core/hash.js.map +1 -0
- package/dist/core/http-backend.d.ts +11 -0
- package/dist/core/http-backend.js +195 -0
- package/dist/core/http-backend.js.map +1 -0
- package/dist/core/index.d.ts +14 -9
- package/dist/core/index.js +12 -9
- package/dist/core/palette.d.ts +48 -0
- package/dist/core/palette.js +95 -0
- package/dist/core/palette.js.map +1 -0
- package/dist/core/schema/abilities.d.ts +2 -1
- package/dist/core/schema/abilities.js +5 -1
- package/dist/core/schema/abilities.js.map +1 -1
- package/dist/core/schema/index.d.ts +11 -5
- package/dist/core/schema/index.js +13 -8
- package/dist/core/schema/index.js.map +1 -1
- package/dist/core/schema/mark-flags.d.ts +8 -1
- package/dist/core/schema/of-features.d.ts +13 -0
- package/dist/core/schema/of-features.js +14 -0
- package/dist/core/schema/of-features.js.map +1 -0
- package/dist/core/slash.d.ts +8 -6
- package/dist/core/slash.js +24 -16
- package/dist/core/slash.js.map +1 -1
- package/dist/core/surface-session.js +13 -5
- package/dist/core/surface-session.js.map +1 -1
- package/dist/core/toolbar-items.d.ts +10 -4
- package/dist/core/toolbar-items.js +269 -195
- package/dist/core/toolbar-items.js.map +1 -1
- package/dist/core/util.js +11 -0
- package/dist/core/util.js.map +1 -0
- package/dist/document/DocumentSurface.d.ts +1 -1
- package/dist/document/DocumentSurface.vue.d.ts +3 -3
- package/dist/features/ai/agent-op-review.d.ts +1 -1
- package/dist/features/ai/agent-op-review.js +1 -1
- package/dist/features/ai/agent-ops.js +1 -1
- package/dist/features/ai/ai-apply.d.ts +2 -2
- package/dist/features/ai/ai-apply.js +1 -1
- package/dist/features/ai/ai-review.js +1 -1
- package/dist/features/ai/ai-sse.d.ts +6 -6
- package/dist/features/ai/ai-sse.js +20 -63
- package/dist/features/ai/ai-sse.js.map +1 -1
- package/dist/features/ai/assistant.d.ts +8 -7
- package/dist/features/ai/assistant.js +3 -3
- package/dist/features/ai/assistant.js.map +1 -1
- package/dist/features/ai/block-actions.d.ts +3 -2
- package/dist/features/ai/block-actions.js +3 -2
- package/dist/features/ai/block-actions.js.map +1 -1
- package/dist/features/ai/components/AiSelectionMenu.js +1 -1
- package/dist/features/ai/components/DocumentChatAnswer.js +1 -1
- package/dist/features/ai/components/DocumentChatOps.vue.d.ts +1 -1
- package/dist/features/ai/components/SettingsModelProfiles.js +8 -8
- package/dist/features/ai/components/SettingsModelProfiles.js.map +1 -1
- package/dist/features/ai/document-chat-model.d.ts +8 -7
- 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 +1 -1
- package/dist/features/ai/feature.js +27 -14
- package/dist/features/ai/feature.js.map +1 -1
- package/dist/features/ai/ghost-autocomplete.d.ts +7 -6
- package/dist/features/ai/ghost-autocomplete.js +6 -9
- package/dist/features/ai/ghost-autocomplete.js.map +1 -1
- package/dist/features/ai/index.d.ts +4 -3
- package/dist/features/ai/index.js +10 -10
- package/dist/features/ai/model-profiles.d.ts +5 -4
- package/dist/features/ai/model-profiles.js +2 -2
- package/dist/features/ai/model-profiles.js.map +1 -1
- package/dist/features/ai/protocol/block-lines.js +1 -1
- package/dist/features/ai/protocol/block-lines.js.map +1 -1
- package/dist/features/ai/protocol/chat.js +4 -1
- package/dist/features/ai/protocol/chat.js.map +1 -1
- package/dist/features/ai/protocol/index.d.ts +3 -2
- package/dist/features/ai/protocol/models.d.ts +2 -16
- package/dist/features/ai/protocol/models.js.map +1 -1
- package/dist/features/ai/rate-limit.d.ts +1 -1
- package/dist/features/ai/rate-limit.js +3 -1
- package/dist/features/ai/rate-limit.js.map +1 -1
- package/dist/features/ai/react/AiSelectionMenu.js +2 -2
- package/dist/features/ai/react/AiSidebar.js +4 -4
- package/dist/features/ai/react/DocumentChatAnswer.js +1 -1
- package/dist/features/ai/react/DocumentChatOps.d.ts +1 -1
- package/dist/features/ai/react/DocumentChatOps.js +1 -1
- package/dist/features/ai/react/SettingsModelProfiles.js +8 -10
- 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 +3 -3
- package/dist/features/ai/react/use-ai-assistant.js.map +1 -1
- package/dist/features/ai/react/use-document-chat.js +2 -2
- package/dist/features/ai/react/use-document-chat.js.map +1 -1
- package/dist/features/ai/react/use-model-profiles.d.ts +2 -1
- package/dist/features/ai/selection-flow.d.ts +1 -1
- package/dist/features/ai/selection-flow.js +1 -1
- package/dist/features/ai/sidebar-flow.d.ts +1 -1
- package/dist/features/ai/sidebar-flow.js +1 -1
- package/dist/features/ai/use-ai-assistant.d.ts +1 -1
- package/dist/features/ai/use-ai-assistant.js +3 -3
- package/dist/features/ai/use-ai-assistant.js.map +1 -1
- package/dist/features/ai/use-document-chat.js +2 -2
- package/dist/features/ai/use-document-chat.js.map +1 -1
- package/dist/features/ai/use-model-profiles.d.ts +2 -1
- package/dist/features/authors/attribution.d.ts +1 -1
- package/dist/features/authors/feature.js +12 -11
- package/dist/features/authors/feature.js.map +1 -1
- package/dist/features/block-ui/block-actions.d.ts +22 -1
- package/dist/features/block-ui/block-actions.js +26 -2
- package/dist/features/block-ui/block-actions.js.map +1 -1
- package/dist/features/block-ui/components/BlockActionsOverlay.js +33 -4
- package/dist/features/block-ui/components/BlockActionsOverlay.js.map +1 -1
- package/dist/features/block-ui/components/BlockActionsOverlay.vue.d.ts +4 -0
- package/dist/features/block-ui/components/BlockUi.js +1 -1
- package/dist/features/block-ui/feature.js +1 -0
- package/dist/features/block-ui/feature.js.map +1 -1
- package/dist/features/block-ui/index.d.ts +2 -2
- package/dist/features/block-ui/index.js +2 -2
- package/dist/features/block-ui/react/BlockActionsOverlay.d.ts +4 -0
- package/dist/features/block-ui/react/BlockActionsOverlay.js +38 -12
- package/dist/features/block-ui/react/BlockActionsOverlay.js.map +1 -1
- package/dist/features/block-ui/react/BlockUi.js +1 -1
- package/dist/features/collab/anchor-resolver.js +1 -1
- package/dist/features/collab/feature.js +2 -0
- package/dist/features/collab/feature.js.map +1 -1
- package/dist/features/comments/components/CommentThreadView.vue.d.ts +2 -1
- package/dist/features/comments/feature.js +12 -11
- package/dist/features/comments/feature.js.map +1 -1
- package/dist/features/comments/index.d.ts +3 -2
- package/dist/features/comments/index.js +1 -1
- package/dist/features/comments/margin-layout.d.ts +3 -2
- package/dist/features/comments/model.d.ts +3 -67
- package/dist/features/comments/model.js +2 -2
- package/dist/features/comments/model.js.map +1 -1
- package/dist/features/comments/react/CommentThreadView.d.ts +3 -2
- package/dist/features/comments/react/use-comments.d.ts +2 -1
- package/dist/features/comments/react.d.ts +1 -1
- package/dist/features/comments/schema.d.ts +2 -52
- package/dist/features/comments/schema.js.map +1 -1
- package/dist/features/comments/snapshot-equality.js.map +1 -1
- package/dist/features/comments/use-comments.d.ts +3 -2
- package/dist/features/comments/vue.d.ts +1 -1
- package/dist/features/composites/accepted-children.d.ts +1 -0
- package/dist/features/composites/accepted-children.js +16 -1
- package/dist/features/composites/accepted-children.js.map +1 -1
- package/dist/features/composites/ai-brief.js +31 -0
- package/dist/features/composites/ai-brief.js.map +1 -1
- package/dist/features/composites/bibliography-command.d.ts +11 -0
- package/dist/features/composites/bibliography-form.js +90 -0
- package/dist/features/composites/bibliography-form.js.map +1 -0
- package/dist/features/composites/bibliography.d.ts +33 -0
- package/dist/features/composites/bibliography.js +120 -0
- package/dist/features/composites/bibliography.js.map +1 -0
- package/dist/features/composites/components/BibliographyEditor.js +261 -0
- package/dist/features/composites/components/BibliographyEditor.js.map +1 -0
- package/dist/features/composites/components/CompositeChrome.js +75 -26
- package/dist/features/composites/components/CompositeChrome.js.map +1 -1
- package/dist/features/composites/components/CompositeDetails.js +46 -11
- package/dist/features/composites/components/CompositeDetails.js.map +1 -1
- package/dist/features/composites/components/CompositeDetails.vue.d.ts +2 -1
- package/dist/features/composites/components/CompositeFieldEditor.js +37 -4
- package/dist/features/composites/components/CompositeFieldEditor.js.map +1 -1
- package/dist/features/composites/components/CompositeInspector.js +17 -5
- package/dist/features/composites/components/CompositeInspector.js.map +1 -1
- package/dist/features/composites/components/CompositeTable.js +13 -4
- package/dist/features/composites/components/CompositeTable.js.map +1 -1
- package/dist/features/composites/components/CompositeTagsEditor.js +1 -1
- package/dist/features/composites/components/CompositeView.js +11 -1
- package/dist/features/composites/components/CompositeView.js.map +1 -1
- package/dist/features/composites/components/DerivationBadge.js +103 -0
- package/dist/features/composites/components/DerivationBadge.js.map +1 -0
- package/dist/features/composites/components/ReferenceFieldSelect.js +60 -0
- package/dist/features/composites/components/ReferenceFieldSelect.js.map +1 -0
- package/dist/features/composites/components/ReferenceView.js +122 -0
- package/dist/features/composites/components/ReferenceView.js.map +1 -0
- package/dist/features/composites/components/ReferenceView.vue.d.ts +96 -0
- package/dist/features/composites/components/SettingsEditingTab.js +1 -1
- package/dist/features/composites/convert.js +2 -2
- package/dist/features/composites/convert.js.map +1 -1
- package/dist/features/composites/derivation.d.ts +61 -0
- package/dist/features/composites/derivation.js +98 -0
- package/dist/features/composites/derivation.js.map +1 -0
- package/dist/features/composites/derived-chrome.js +69 -0
- package/dist/features/composites/derived-chrome.js.map +1 -0
- package/dist/features/composites/feature.js +159 -109
- package/dist/features/composites/feature.js.map +1 -1
- package/dist/features/composites/fences.d.ts +4 -3
- package/dist/features/composites/fences.js +51 -7
- package/dist/features/composites/fences.js.map +1 -1
- package/dist/features/composites/index.d.ts +12 -3
- package/dist/features/composites/index.js +15 -6
- package/dist/features/composites/inspector-model.d.ts +4 -1
- package/dist/features/composites/inspector-model.js +8 -4
- package/dist/features/composites/inspector-model.js.map +1 -1
- package/dist/features/composites/kinds.d.ts +8 -1
- package/dist/features/composites/kinds.js +145 -6
- package/dist/features/composites/kinds.js.map +1 -1
- package/dist/features/composites/legacy.d.ts +4 -1
- package/dist/features/composites/legacy.js +56 -1
- package/dist/features/composites/legacy.js.map +1 -1
- package/dist/features/composites/meta-display.js +40 -1
- package/dist/features/composites/meta-display.js.map +1 -1
- package/dist/features/composites/meta-keys.d.ts +7 -0
- package/dist/features/composites/meta-keys.js +21 -0
- package/dist/features/composites/meta-keys.js.map +1 -0
- package/dist/features/composites/node-views.d.ts +6 -3
- package/dist/features/composites/node-views.js +7 -3
- package/dist/features/composites/node-views.js.map +1 -1
- package/dist/features/composites/nodes.d.ts +6 -1
- package/dist/features/composites/nodes.js +33 -7
- package/dist/features/composites/nodes.js.map +1 -1
- package/dist/features/composites/react/BibliographyEditor.js +229 -0
- package/dist/features/composites/react/BibliographyEditor.js.map +1 -0
- package/dist/features/composites/react/CompositeChrome.js +65 -17
- package/dist/features/composites/react/CompositeChrome.js.map +1 -1
- package/dist/features/composites/react/CompositeDetails.d.ts +2 -1
- package/dist/features/composites/react/CompositeDetails.js +45 -6
- package/dist/features/composites/react/CompositeDetails.js.map +1 -1
- package/dist/features/composites/react/CompositeFieldEditor.d.ts +1 -1
- package/dist/features/composites/react/CompositeFieldEditor.js +24 -1
- package/dist/features/composites/react/CompositeFieldEditor.js.map +1 -1
- package/dist/features/composites/react/CompositeInspector.js +11 -5
- package/dist/features/composites/react/CompositeInspector.js.map +1 -1
- package/dist/features/composites/react/CompositeStatusMenu.js +1 -1
- package/dist/features/composites/react/CompositeSummaryEditor.js +1 -1
- package/dist/features/composites/react/CompositeTable.js +16 -2
- package/dist/features/composites/react/CompositeTable.js.map +1 -1
- package/dist/features/composites/react/CompositeTagsEditor.js +2 -2
- package/dist/features/composites/react/CompositeView.js +6 -1
- package/dist/features/composites/react/CompositeView.js.map +1 -1
- package/dist/features/composites/react/DerivationBadge.js +116 -0
- package/dist/features/composites/react/DerivationBadge.js.map +1 -0
- package/dist/features/composites/react/ReferenceFieldSelect.js +52 -0
- package/dist/features/composites/react/ReferenceFieldSelect.js.map +1 -0
- package/dist/features/composites/react/ReferenceView.d.ts +11 -0
- package/dist/features/composites/react/ReferenceView.js +115 -0
- package/dist/features/composites/react/ReferenceView.js.map +1 -0
- package/dist/features/composites/react/SettingsEditingTab.js +2 -2
- package/dist/features/composites/react.d.ts +2 -1
- package/dist/features/composites/react.js +7 -3
- package/dist/features/composites/react.js.map +1 -1
- package/dist/features/composites/reference-ai.js +16 -0
- package/dist/features/composites/reference-ai.js.map +1 -0
- package/dist/features/composites/reference-label.d.ts +19 -0
- package/dist/features/composites/reference-label.js +58 -0
- package/dist/features/composites/reference-label.js.map +1 -0
- package/dist/features/composites/reference-suggestion.d.ts +10 -0
- package/dist/features/composites/reference-suggestion.js +41 -0
- package/dist/features/composites/reference-suggestion.js.map +1 -0
- package/dist/features/composites/reference-text.d.ts +18 -0
- package/dist/features/composites/reference-text.js +89 -0
- package/dist/features/composites/reference-text.js.map +1 -0
- package/dist/features/composites/reference.d.ts +44 -0
- package/dist/features/composites/reference.js +148 -0
- package/dist/features/composites/reference.js.map +1 -0
- package/dist/features/composites/reveal-source.d.ts +32 -0
- package/dist/features/composites/reveal-source.js +89 -0
- package/dist/features/composites/reveal-source.js.map +1 -0
- package/dist/features/composites/rows.d.ts +21 -2
- package/dist/features/composites/rows.js +63 -9
- package/dist/features/composites/rows.js.map +1 -1
- package/dist/features/composites/schema.d.ts +9 -3
- package/dist/features/composites/schema.js +11 -4
- package/dist/features/composites/schema.js.map +1 -1
- package/dist/features/composites/table-model.js +12 -21
- package/dist/features/composites/table-model.js.map +1 -1
- package/dist/features/composites/vue.d.ts +3 -2
- package/dist/features/composites/vue.js +8 -4
- package/dist/features/composites/vue.js.map +1 -1
- package/dist/features/media/assets.d.ts +2 -0
- package/dist/features/media/assets.js +3 -2
- package/dist/features/media/assets.js.map +1 -1
- package/dist/features/media/components/FileView.js +13 -4
- package/dist/features/media/components/FileView.js.map +1 -1
- package/dist/features/media/feature.d.ts +3 -3
- package/dist/features/media/feature.js +21 -28
- package/dist/features/media/feature.js.map +1 -1
- package/dist/features/media/file-import.js +2 -2
- package/dist/features/media/file-import.js.map +1 -1
- package/dist/features/media/index.d.ts +2 -2
- package/dist/features/media/index.js +2 -2
- package/dist/features/media/react/FileView.js +19 -2
- package/dist/features/media/react/FileView.js.map +1 -1
- package/dist/features/media/schema.d.ts +8 -0
- package/dist/features/media/schema.js +126 -11
- package/dist/features/media/schema.js.map +1 -1
- package/dist/features/media/upload.d.ts +16 -14
- package/dist/features/media/upload.js +13 -19
- package/dist/features/media/upload.js.map +1 -1
- package/dist/features/mentions/index.d.ts +4 -3
- package/dist/features/mentions/index.js +4 -1
- package/dist/features/mentions/index.js.map +1 -1
- package/dist/features/mentions/mention-text.d.ts +1 -1
- package/dist/features/mentions/mention-text.js.map +1 -1
- package/dist/features/mentions/mention.d.ts +0 -6
- package/dist/features/mentions/mention.js.map +1 -1
- package/dist/features/mentions/metadata-defaults.d.ts +2 -2
- package/dist/features/mentions/metadata-defaults.js +3 -9
- package/dist/features/mentions/metadata-defaults.js.map +1 -1
- package/dist/features/mentions/schema.d.ts +2 -1
- package/dist/features/mentions/schema.js.map +1 -1
- package/dist/features/tables/feature.d.ts +2 -1
- package/dist/features/tables/feature.js +90 -70
- package/dist/features/tables/feature.js.map +1 -1
- package/dist/features/themes/components/SettingsAppearanceTab.js +6 -9
- package/dist/features/themes/components/SettingsAppearanceTab.js.map +1 -1
- package/dist/features/themes/feature.js +2 -0
- package/dist/features/themes/feature.js.map +1 -1
- package/dist/features/themes/index.d.ts +2 -1
- package/dist/features/themes/react/SettingsAppearanceTab.js +7 -10
- package/dist/features/themes/react/SettingsAppearanceTab.js.map +1 -1
- package/dist/features/themes/schema.d.ts +2 -6
- package/dist/features/themes/schema.js.map +1 -1
- package/dist/features/themes/theme-runtime.d.ts +1 -1
- package/dist/features/themes/theme-runtime.js +4 -2
- package/dist/features/themes/theme-runtime.js.map +1 -1
- package/dist/features/transcript/TranscriptSegmentView.js +48 -28
- package/dist/features/transcript/TranscriptSegmentView.js.map +1 -1
- package/dist/features/transcript/feature.js +21 -19
- package/dist/features/transcript/feature.js.map +1 -1
- package/dist/features/transcript/react/TranscriptSegmentView.js +55 -36
- package/dist/features/transcript/react/TranscriptSegmentView.js.map +1 -1
- package/dist/features/transcript/segment-node.d.ts +2 -0
- package/dist/features/transcript/segment-node.js +35 -7
- package/dist/features/transcript/segment-node.js.map +1 -1
- package/dist/i18n/de/composites.js +91 -1
- package/dist/i18n/de/composites.js.map +1 -1
- package/dist/i18n/de/integrations.js +49 -8
- package/dist/i18n/de/integrations.js.map +1 -1
- package/dist/i18n/de/media.js +0 -1
- package/dist/i18n/de/media.js.map +1 -1
- package/dist/i18n/de/palette.js +22 -0
- package/dist/i18n/de/palette.js.map +1 -0
- package/dist/i18n/de/tables.js +0 -1
- package/dist/i18n/de/tables.js.map +1 -1
- package/dist/i18n/de/transcript.js +2 -1
- package/dist/i18n/de/transcript.js.map +1 -1
- package/dist/i18n/de/tree.js +3 -0
- package/dist/i18n/de/tree.js.map +1 -1
- package/dist/i18n/de.d.ts +157 -11
- package/dist/i18n/de.js +3 -1
- package/dist/i18n/de.js.map +1 -1
- package/dist/i18n/en/composites.js +89 -1
- package/dist/i18n/en/composites.js.map +1 -1
- package/dist/i18n/en/integrations.js +49 -8
- package/dist/i18n/en/integrations.js.map +1 -1
- package/dist/i18n/en/media.js +0 -1
- package/dist/i18n/en/media.js.map +1 -1
- package/dist/i18n/en/palette.js +22 -0
- package/dist/i18n/en/palette.js.map +1 -0
- package/dist/i18n/en/tables.js +0 -1
- package/dist/i18n/en/tables.js.map +1 -1
- package/dist/i18n/en/transcript.js +2 -1
- package/dist/i18n/en/transcript.js.map +1 -1
- package/dist/i18n/en/tree.js +3 -0
- package/dist/i18n/en/tree.js.map +1 -1
- package/dist/i18n/en.js +3 -1
- package/dist/i18n/en.js.map +1 -1
- package/dist/index.d.ts +4 -3
- package/dist/integrations/composite-ai/bibliography-fetch.d.ts +31 -0
- package/dist/integrations/composite-ai/bibliography-fetch.js +159 -0
- package/dist/integrations/composite-ai/bibliography-fetch.js.map +1 -0
- package/dist/integrations/composite-ai/composite-fill.d.ts +30 -8
- package/dist/integrations/composite-ai/composite-fill.js +97 -56
- package/dist/integrations/composite-ai/composite-fill.js.map +1 -1
- package/dist/integrations/composite-ai/composite-summary.d.ts +4 -12
- package/dist/integrations/composite-ai/composite-summary.js +7 -26
- package/dist/integrations/composite-ai/composite-summary.js.map +1 -1
- package/dist/integrations/composite-ai/derive.d.ts +29 -0
- package/dist/integrations/composite-ai/derive.js +173 -0
- package/dist/integrations/composite-ai/derive.js.map +1 -0
- package/dist/integrations/composite-ai/index.d.ts +11 -7
- package/dist/integrations/composite-ai/index.js +72 -14
- package/dist/integrations/composite-ai/index.js.map +1 -1
- package/dist/integrations/composite-ai/rendition.d.ts +45 -0
- package/dist/integrations/composite-ai/rendition.js +314 -0
- package/dist/integrations/composite-ai/rendition.js.map +1 -0
- package/dist/integrations/composite-media/index.d.ts +7 -5
- package/dist/integrations/composite-media/index.js +86 -13
- package/dist/integrations/composite-media/index.js.map +1 -1
- package/dist/integrations/transcript-ai/index.d.ts +1 -1
- package/dist/integrations/transcript-ai/index.js +5 -2
- package/dist/integrations/transcript-ai/index.js.map +1 -1
- package/dist/integrations/transcript-ai/protocol.d.ts +2 -12
- package/dist/integrations/transcript-ai/protocol.js +0 -2
- package/dist/integrations/transcript-ai/protocol.js.map +1 -1
- package/dist/integrations/transcript-ai/transcript-cleanup.d.ts +5 -5
- package/dist/integrations/transcript-ai/transcript-cleanup.js +7 -10
- package/dist/integrations/transcript-ai/transcript-cleanup.js.map +1 -1
- package/dist/markdown/MarkdownSurface.vue.d.ts +10 -9
- package/dist/markdown/MarkdownSurface2.js +3 -6
- package/dist/markdown/MarkdownSurface2.js.map +1 -1
- package/dist/markdown/document.js +1 -1
- package/dist/markdown/source-mode.d.ts +1 -1
- package/dist/nuxt/module.d.ts +1402 -54
- package/dist/nuxt/module.js +6 -49
- package/dist/nuxt/module.js.map +1 -1
- package/dist/nuxt/runtime/install-context.d.ts +7 -3
- package/dist/nuxt/runtime/install-context.js +14 -8
- package/dist/nuxt/runtime/install-context.js.map +1 -1
- package/dist/nuxt/runtime/plugins/editor-context-nuxt-ui.client.ts +2 -2
- package/dist/nuxt/runtime/server/plugins/editor-server.js +20 -12
- package/dist/nuxt/runtime/server/plugins/editor-server.js.map +1 -1
- package/dist/presets/compose.d.ts +94 -0
- package/dist/presets/compose.js +164 -0
- package/dist/presets/compose.js.map +1 -0
- package/dist/react/AdvancedEditor.d.ts +15 -15
- package/dist/react/AdvancedEditor.js +15 -13
- package/dist/react/AdvancedEditor.js.map +1 -1
- package/dist/react/EditorCommandPalette.d.ts +13 -0
- package/dist/react/EditorCommandPalette.js +118 -0
- package/dist/react/EditorCommandPalette.js.map +1 -0
- package/dist/react/EditorSettingsModal.d.ts +5 -5
- package/dist/react/EditorSettingsModal.js +7 -4
- package/dist/react/EditorSettingsModal.js.map +1 -1
- package/dist/react/EditorSettingsPanel.d.ts +7 -7
- package/dist/react/EditorSettingsPanel.js +8 -5
- package/dist/react/EditorSettingsPanel.js.map +1 -1
- package/dist/react/EditorSurface.d.ts +7 -7
- package/dist/react/EditorSurface.js +10 -6
- package/dist/react/EditorSurface.js.map +1 -1
- package/dist/react/EditorToolbar.d.ts +4 -6
- package/dist/react/EditorToolbar.js +29 -37
- package/dist/react/EditorToolbar.js.map +1 -1
- package/dist/react/SimpleEditor.d.ts +22 -23
- package/dist/react/SimpleEditor.js +21 -7
- package/dist/react/SimpleEditor.js.map +1 -1
- package/dist/react/advanced.d.ts +4 -3
- package/dist/react/advanced.js +2 -2
- package/dist/react/compose.d.ts +20 -0
- package/dist/react/compose.js +49 -0
- package/dist/react/compose.js.map +1 -0
- package/dist/react/composed-surface.d.ts +39 -0
- package/dist/react/composed-surface.js +71 -0
- package/dist/react/composed-surface.js.map +1 -0
- package/dist/react/context.js +6 -2
- package/dist/react/context.js.map +1 -1
- package/dist/react/index.d.ts +2 -1
- package/dist/react/index.js +2 -1
- package/dist/react/key-labels.js +15 -0
- package/dist/react/key-labels.js.map +1 -0
- package/dist/react/settings.d.ts +1 -1
- package/dist/react/simple.d.ts +2 -2
- package/dist/react/ui/command.js +36 -1
- package/dist/react/ui/command.js.map +1 -1
- package/dist/schema/advanced.d.ts +6 -6
- package/dist/schema/advanced.js +26 -29
- package/dist/schema/advanced.js.map +1 -1
- package/dist/server/ai.d.ts +5 -16
- package/dist/server/ai.js.map +1 -1
- package/dist/server/auth.d.ts +9 -0
- package/dist/server/collab-state.d.ts +1 -1
- package/dist/server/collab-state.js.map +1 -1
- package/dist/server/collab.d.ts +13 -13
- package/dist/server/collab.js +34 -18
- package/dist/server/collab.js.map +1 -1
- package/dist/server/crossref.js +78 -0
- package/dist/server/crossref.js.map +1 -0
- package/dist/server/errors.d.ts +1 -1
- package/dist/server/errors.js +1 -1
- package/dist/server/errors.js.map +1 -1
- package/dist/server/extract.js +308 -0
- package/dist/server/extract.js.map +1 -0
- package/dist/{nuxt/runtime/server/utils/editor-route.js → server/h3.js} +8 -16
- package/dist/server/h3.js.map +1 -0
- package/dist/server/handlers/ai.d.ts +30 -9
- package/dist/server/handlers/ai.js +170 -36
- package/dist/server/handlers/ai.js.map +1 -1
- package/dist/server/handlers/context.d.ts +12 -5
- package/dist/server/handlers/context.js +10 -4
- package/dist/server/handlers/context.js.map +1 -1
- package/dist/server/handlers/editor.d.ts +19 -13
- package/dist/server/handlers/editor.js +49 -38
- package/dist/server/handlers/editor.js.map +1 -1
- package/dist/server/handlers/index.d.ts +4 -4
- package/dist/server/handlers/index.js +4 -4
- package/dist/server/host.d.ts +16 -25
- package/dist/server/host.js +58 -41
- package/dist/server/host.js.map +1 -1
- package/dist/server/index.d.ts +6 -4
- package/dist/server/index.js +3 -2
- package/dist/server/pdf.js +97 -0
- package/dist/server/pdf.js.map +1 -0
- package/dist/server/{adapter.d.ts → ports.d.ts} +81 -30
- package/dist/server/ports.js +29 -0
- package/dist/server/ports.js.map +1 -0
- package/dist/server/routes.js +144 -0
- package/dist/server/routes.js.map +1 -0
- package/dist/settings/index.d.ts +1 -1
- package/dist/settings/index.js.map +1 -1
- package/dist/styles/composites.css +25 -0
- package/dist/tree/DocumentTree.js +56 -29
- package/dist/tree/DocumentTree.js.map +1 -1
- package/dist/tree/react/DocumentTree.js +23 -0
- package/dist/tree/react/DocumentTree.js.map +1 -1
- package/dist/tree/tree-host.js +1 -1
- package/dist/vue/AdvancedEditor.js +30 -9
- package/dist/vue/AdvancedEditor.js.map +1 -1
- package/dist/vue/AdvancedEditor.vue.d.ts +32 -12
- package/dist/vue/SimpleEditor.js +62 -16
- package/dist/vue/SimpleEditor.js.map +1 -1
- package/dist/vue/SimpleEditor.vue.d.ts +37 -7
- package/dist/vue/advanced.d.ts +3 -2
- package/dist/vue/advanced.js +2 -2
- package/dist/vue/components/EditorCommandPalette.js +91 -0
- package/dist/vue/components/EditorCommandPalette.js.map +1 -0
- package/dist/vue/components/EditorCommandPalette.vue.d.ts +15 -0
- package/dist/vue/components/EditorSettingsModal.js +10 -6
- package/dist/vue/components/EditorSettingsModal.js.map +1 -1
- package/dist/vue/components/EditorSettingsModal.vue.d.ts +4 -4
- package/dist/vue/components/EditorSettingsPanel.js +10 -6
- package/dist/vue/components/EditorSettingsPanel.js.map +1 -1
- package/dist/vue/components/EditorSettingsPanel.vue.d.ts +6 -6
- package/dist/vue/components/EditorSurface.js +11 -6
- package/dist/vue/components/EditorSurface.js.map +1 -1
- package/dist/vue/components/EditorSurface.vue.d.ts +11 -11
- package/dist/vue/components/EditorToolbar.js +41 -49
- package/dist/vue/components/EditorToolbar.js.map +1 -1
- package/dist/vue/components/EditorToolbar.vue.d.ts +2 -4
- package/dist/vue/compose.d.ts +17 -0
- package/dist/vue/compose.js +51 -0
- package/dist/vue/compose.js.map +1 -0
- package/dist/vue/context-key.d.ts +6 -0
- package/dist/vue/context-key.js +6 -0
- package/dist/vue/context-key.js.map +1 -0
- package/dist/vue/context.d.ts +8 -6
- package/dist/vue/context.js +6 -5
- package/dist/vue/context.js.map +1 -1
- package/dist/vue/index.d.ts +10 -8
- package/dist/vue/index.js +10 -8
- package/dist/vue/kit/index.d.ts +2 -2
- package/dist/vue/kit/nuxt-ui.js +23 -0
- package/dist/vue/kit/nuxt-ui.js.map +1 -1
- package/dist/vue/kit/types.d.ts +40 -1
- package/package.json +30 -16
- package/dist/adapters/comments/client.d.ts +0 -64
- package/dist/adapters/comments/client.js.map +0 -1
- package/dist/adapters/routes.js.map +0 -1
- package/dist/core/toolbar.d.ts +0 -74
- package/dist/core/toolbar.js +0 -45
- package/dist/core/toolbar.js.map +0 -1
- package/dist/integrations/composite-ai/document-transcribe.d.ts +0 -14
- package/dist/integrations/composite-ai/document-transcribe.js +0 -89
- package/dist/integrations/composite-ai/document-transcribe.js.map +0 -1
- package/dist/nuxt/runtime/server/api/ai/chat.post.d.ts +0 -5
- package/dist/nuxt/runtime/server/api/ai/chat.post.js +0 -8
- package/dist/nuxt/runtime/server/api/ai/chat.post.js.map +0 -1
- package/dist/nuxt/runtime/server/api/ai/complete.post.d.ts +0 -5
- package/dist/nuxt/runtime/server/api/ai/complete.post.js +0 -8
- package/dist/nuxt/runtime/server/api/ai/complete.post.js.map +0 -1
- package/dist/nuxt/runtime/server/api/ai/generate.post.d.ts +0 -5
- package/dist/nuxt/runtime/server/api/ai/generate.post.js +0 -8
- package/dist/nuxt/runtime/server/api/ai/generate.post.js.map +0 -1
- package/dist/nuxt/runtime/server/api/ai/models.get.d.ts +0 -5
- package/dist/nuxt/runtime/server/api/ai/models.get.js +0 -8
- package/dist/nuxt/runtime/server/api/ai/models.get.js.map +0 -1
- package/dist/nuxt/runtime/server/api/ai/transcribe.post.d.ts +0 -5
- package/dist/nuxt/runtime/server/api/ai/transcribe.post.js +0 -8
- package/dist/nuxt/runtime/server/api/ai/transcribe.post.js.map +0 -1
- package/dist/nuxt/runtime/server/api/ai/transcript-cleanup.post.d.ts +0 -5
- package/dist/nuxt/runtime/server/api/ai/transcript-cleanup.post.js +0 -8
- package/dist/nuxt/runtime/server/api/ai/transcript-cleanup.post.js.map +0 -1
- package/dist/nuxt/runtime/server/api/editor/assets/[id]/[name].get.d.ts +0 -5
- package/dist/nuxt/runtime/server/api/editor/assets/[id]/[name].get.js +0 -8
- package/dist/nuxt/runtime/server/api/editor/assets/[id]/[name].get.js.map +0 -1
- package/dist/nuxt/runtime/server/api/editor/assets/[id].post.d.ts +0 -5
- package/dist/nuxt/runtime/server/api/editor/assets/[id].post.js +0 -8
- package/dist/nuxt/runtime/server/api/editor/assets/[id].post.js.map +0 -1
- package/dist/nuxt/runtime/server/api/editor/settings.get.d.ts +0 -5
- package/dist/nuxt/runtime/server/api/editor/settings.get.js +0 -8
- package/dist/nuxt/runtime/server/api/editor/settings.get.js.map +0 -1
- package/dist/nuxt/runtime/server/api/editor/settings.put.d.ts +0 -5
- package/dist/nuxt/runtime/server/api/editor/settings.put.js +0 -8
- package/dist/nuxt/runtime/server/api/editor/settings.put.js.map +0 -1
- package/dist/nuxt/runtime/server/api/editor/tags.get.d.ts +0 -5
- package/dist/nuxt/runtime/server/api/editor/tags.get.js +0 -8
- package/dist/nuxt/runtime/server/api/editor/tags.get.js.map +0 -1
- package/dist/nuxt/runtime/server/api/editor/themes/[id].delete.d.ts +0 -5
- package/dist/nuxt/runtime/server/api/editor/themes/[id].delete.js +0 -8
- package/dist/nuxt/runtime/server/api/editor/themes/[id].delete.js.map +0 -1
- package/dist/nuxt/runtime/server/api/editor/themes/[id].get.d.ts +0 -5
- package/dist/nuxt/runtime/server/api/editor/themes/[id].get.js +0 -8
- package/dist/nuxt/runtime/server/api/editor/themes/[id].get.js.map +0 -1
- package/dist/nuxt/runtime/server/api/editor/themes/index.get.d.ts +0 -5
- package/dist/nuxt/runtime/server/api/editor/themes/index.get.js +0 -8
- package/dist/nuxt/runtime/server/api/editor/themes/index.get.js.map +0 -1
- package/dist/nuxt/runtime/server/api/editor/themes/index.post.d.ts +0 -5
- package/dist/nuxt/runtime/server/api/editor/themes/index.post.js +0 -8
- package/dist/nuxt/runtime/server/api/editor/themes/index.post.js.map +0 -1
- package/dist/nuxt/runtime/server/api/editor/users.get.d.ts +0 -5
- package/dist/nuxt/runtime/server/api/editor/users.get.js +0 -8
- package/dist/nuxt/runtime/server/api/editor/users.get.js.map +0 -1
- package/dist/nuxt/runtime/server/plugins/collab.d.ts +0 -5
- package/dist/nuxt/runtime/server/plugins/collab.js +0 -10
- package/dist/nuxt/runtime/server/plugins/collab.js.map +0 -1
- package/dist/nuxt/runtime/server/routes/collab/[id].d.ts +0 -5
- package/dist/nuxt/runtime/server/routes/collab/[id].js +0 -35
- package/dist/nuxt/runtime/server/routes/collab/[id].js.map +0 -1
- package/dist/nuxt/runtime/server/utils/editor-route.d.ts +0 -11
- package/dist/nuxt/runtime/server/utils/editor-route.js.map +0 -1
- package/dist/presets/advanced.d.ts +0 -33
- package/dist/presets/advanced.js +0 -50
- package/dist/presets/advanced.js.map +0 -1
- package/dist/presets/simple.d.ts +0 -9
- package/dist/presets/simple.js +0 -12
- package/dist/presets/simple.js.map +0 -1
- package/dist/react/advanced-preset.d.ts +0 -11
- package/dist/react/advanced-preset.js +0 -31
- package/dist/react/advanced-preset.js.map +0 -1
- package/dist/vue/advanced-preset.d.ts +0 -13
- package/dist/vue/advanced-preset.js +0 -33
- package/dist/vue/advanced-preset.js.map +0 -1
- package/docs/extending.md +0 -538
- package/docs/integration.md +0 -630
- package/docs/llms.md +0 -383
- package/docs/usage.md +0 -1076
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
import { createTranslator } from "../../i18n/index.js";
|
|
2
2
|
//#region src/features/composites/kinds.ts
|
|
3
|
+
/** Media block types a source-holding kind's source may be (`CompositeKind.source`). */
|
|
4
|
+
const SOURCE_MEDIA_TYPES = [
|
|
5
|
+
"image",
|
|
6
|
+
"audio",
|
|
7
|
+
"video",
|
|
8
|
+
"file"
|
|
9
|
+
];
|
|
3
10
|
/**
|
|
4
11
|
* The built-in kinds in the language of `t`. The default set is produced from the translator (labels, placeholders, field
|
|
5
12
|
* labels and status choices are catalog messages), so it is built per translator and memoized; hosts that pass their own
|
|
@@ -67,7 +74,8 @@ function buildDefaultKinds(t) {
|
|
|
67
74
|
icon: "i-lucide-sticky-note",
|
|
68
75
|
titlePlaceholder: t("composites.kind.note.title"),
|
|
69
76
|
descriptionPlaceholder: t("composites.kind.note.description"),
|
|
70
|
-
fields: []
|
|
77
|
+
fields: [],
|
|
78
|
+
ai: { purpose: "Eigene Notiz zu einer Quelle oder einem Thema: Zusammenfassung, Gedanken, offene Fragen." }
|
|
71
79
|
},
|
|
72
80
|
{
|
|
73
81
|
id: "document",
|
|
@@ -75,6 +83,7 @@ function buildDefaultKinds(t) {
|
|
|
75
83
|
icon: "i-lucide-file-text",
|
|
76
84
|
titlePlaceholder: t("composites.kind.document.title"),
|
|
77
85
|
descriptionPlaceholder: t("composites.kind.document.description"),
|
|
86
|
+
source: [...SOURCE_MEDIA_TYPES],
|
|
78
87
|
fields: [
|
|
79
88
|
{
|
|
80
89
|
key: "filename",
|
|
@@ -95,13 +104,118 @@ function buildDefaultKinds(t) {
|
|
|
95
104
|
key: "importedAt",
|
|
96
105
|
label: t("composites.kind.document.field.importedAt"),
|
|
97
106
|
type: "date"
|
|
107
|
+
}
|
|
108
|
+
]
|
|
109
|
+
},
|
|
110
|
+
{
|
|
111
|
+
id: "recording",
|
|
112
|
+
label: t("composites.kind.recording.label"),
|
|
113
|
+
icon: "i-lucide-mic",
|
|
114
|
+
titlePlaceholder: t("composites.kind.recording.title"),
|
|
115
|
+
descriptionPlaceholder: t("composites.kind.recording.description"),
|
|
116
|
+
accepts: "all",
|
|
117
|
+
source: ["audio", "video"],
|
|
118
|
+
fields: [
|
|
119
|
+
...importFields(t, "recording"),
|
|
120
|
+
{
|
|
121
|
+
key: "recordedAt",
|
|
122
|
+
label: t("composites.kind.recording.field.recordedAt"),
|
|
123
|
+
type: "date"
|
|
124
|
+
},
|
|
125
|
+
{
|
|
126
|
+
key: "participants",
|
|
127
|
+
label: t("composites.kind.recording.field.participants"),
|
|
128
|
+
type: "text"
|
|
98
129
|
},
|
|
99
130
|
{
|
|
100
|
-
key: "
|
|
101
|
-
label: t("composites.kind.
|
|
102
|
-
type: "
|
|
131
|
+
key: "durationSeconds",
|
|
132
|
+
label: t("composites.kind.recording.field.durationSeconds"),
|
|
133
|
+
type: "number"
|
|
103
134
|
}
|
|
104
|
-
]
|
|
135
|
+
],
|
|
136
|
+
ai: { purpose: "Aufnahme (Audio oder Video) als Quelle; der Inhalt hält Lesefassungen wie das Transkript und eigene Notizen." }
|
|
137
|
+
},
|
|
138
|
+
{
|
|
139
|
+
id: "paper",
|
|
140
|
+
label: t("composites.kind.paper.label"),
|
|
141
|
+
icon: "i-lucide-scroll-text",
|
|
142
|
+
titlePlaceholder: t("composites.kind.paper.title"),
|
|
143
|
+
descriptionPlaceholder: t("composites.kind.paper.description"),
|
|
144
|
+
accepts: "all",
|
|
145
|
+
source: ["file"],
|
|
146
|
+
fields: [
|
|
147
|
+
...importFields(t, "paper"),
|
|
148
|
+
{
|
|
149
|
+
key: "bib",
|
|
150
|
+
label: t("composites.kind.paper.field.bib"),
|
|
151
|
+
type: "bibliography"
|
|
152
|
+
},
|
|
153
|
+
{
|
|
154
|
+
key: "doi",
|
|
155
|
+
label: t("composites.kind.paper.field.doi"),
|
|
156
|
+
type: "text"
|
|
157
|
+
}
|
|
158
|
+
],
|
|
159
|
+
ai: { purpose: "Wissenschaftliche Arbeit als Quelle (PDF) mit Literaturangabe; der Inhalt hält Volltext, Zusammenfassungen und Notizen." }
|
|
160
|
+
},
|
|
161
|
+
{
|
|
162
|
+
id: "book",
|
|
163
|
+
label: t("composites.kind.book.label"),
|
|
164
|
+
icon: "i-lucide-book",
|
|
165
|
+
titlePlaceholder: t("composites.kind.book.title"),
|
|
166
|
+
descriptionPlaceholder: t("composites.kind.book.description"),
|
|
167
|
+
accepts: "all",
|
|
168
|
+
source: ["file"],
|
|
169
|
+
fields: [
|
|
170
|
+
...importFields(t, "book"),
|
|
171
|
+
{
|
|
172
|
+
key: "bib",
|
|
173
|
+
label: t("composites.kind.book.field.bib"),
|
|
174
|
+
type: "bibliography"
|
|
175
|
+
},
|
|
176
|
+
{
|
|
177
|
+
key: "isbn",
|
|
178
|
+
label: t("composites.kind.book.field.isbn"),
|
|
179
|
+
type: "text"
|
|
180
|
+
}
|
|
181
|
+
],
|
|
182
|
+
ai: { purpose: "Buch als Quelle (PDF) mit Literaturangabe; der Inhalt hält den Volltext, gegliedert in Kapitel, und Notizen." }
|
|
183
|
+
},
|
|
184
|
+
{
|
|
185
|
+
id: "figure",
|
|
186
|
+
label: t("composites.kind.figure.label"),
|
|
187
|
+
icon: "i-lucide-image",
|
|
188
|
+
titlePlaceholder: t("composites.kind.figure.title"),
|
|
189
|
+
descriptionPlaceholder: t("composites.kind.figure.description"),
|
|
190
|
+
accepts: "all",
|
|
191
|
+
source: ["image"],
|
|
192
|
+
fields: [...importFields(t, "figure"), {
|
|
193
|
+
key: "credit",
|
|
194
|
+
label: t("composites.kind.figure.field.credit"),
|
|
195
|
+
type: "text"
|
|
196
|
+
}],
|
|
197
|
+
ai: { purpose: "Bild als Quelle; der Inhalt hält die Bildbeschreibung und eigene Notizen." }
|
|
198
|
+
},
|
|
199
|
+
{
|
|
200
|
+
id: "rendition",
|
|
201
|
+
label: t("composites.kind.rendition.label"),
|
|
202
|
+
icon: "i-lucide-captions",
|
|
203
|
+
titlePlaceholder: t("composites.kind.rendition.title"),
|
|
204
|
+
descriptionPlaceholder: t("composites.kind.rendition.description"),
|
|
205
|
+
accepts: "all",
|
|
206
|
+
fields: [{
|
|
207
|
+
key: "derivation",
|
|
208
|
+
label: t("composites.kind.rendition.field.derivation"),
|
|
209
|
+
type: "derivation"
|
|
210
|
+
}, {
|
|
211
|
+
key: "language",
|
|
212
|
+
label: t("composites.kind.rendition.field.language"),
|
|
213
|
+
type: "text"
|
|
214
|
+
}],
|
|
215
|
+
ai: {
|
|
216
|
+
purpose: "Lesbare Fassung einer Quelle (Transkript, Volltext, Beschreibung, Übersetzung)",
|
|
217
|
+
instructions: "Übertrage den Inhalt vollständig und gut lesbar; nichts weglassen, nichts hinzuerfinden."
|
|
218
|
+
}
|
|
105
219
|
},
|
|
106
220
|
{
|
|
107
221
|
id: "folder",
|
|
@@ -113,6 +227,31 @@ function buildDefaultKinds(t) {
|
|
|
113
227
|
}
|
|
114
228
|
];
|
|
115
229
|
}
|
|
230
|
+
/** The four fields the import of a file fills in (`wrapImport` of `composite-media`), shared by every source-holding kind. */
|
|
231
|
+
function importFields(t, kind) {
|
|
232
|
+
return [
|
|
233
|
+
{
|
|
234
|
+
key: "filename",
|
|
235
|
+
label: t(`composites.kind.${kind}.field.filename`),
|
|
236
|
+
type: "text"
|
|
237
|
+
},
|
|
238
|
+
{
|
|
239
|
+
key: "mimeType",
|
|
240
|
+
label: t(`composites.kind.${kind}.field.mimeType`),
|
|
241
|
+
type: "text"
|
|
242
|
+
},
|
|
243
|
+
{
|
|
244
|
+
key: "size",
|
|
245
|
+
label: t(`composites.kind.${kind}.field.size`),
|
|
246
|
+
type: "number"
|
|
247
|
+
},
|
|
248
|
+
{
|
|
249
|
+
key: "importedAt",
|
|
250
|
+
label: t(`composites.kind.${kind}.field.importedAt`),
|
|
251
|
+
type: "date"
|
|
252
|
+
}
|
|
253
|
+
];
|
|
254
|
+
}
|
|
116
255
|
/** The built-in kinds in the default language, for server-side and context-free code (`Composite`'s default option, an editor without a context). */
|
|
117
256
|
const fallbackCompositeKinds = () => defaultCompositeKinds(DEFAULT_TRANSLATE);
|
|
118
257
|
const DEFAULT_TRANSLATE = createTranslator();
|
|
@@ -141,6 +280,6 @@ function kindAccepts(kinds, parentKind, childKind) {
|
|
|
141
280
|
return accepts === "all" || accepts.includes(childKind);
|
|
142
281
|
}
|
|
143
282
|
//#endregion
|
|
144
|
-
export { compositeKind, defaultCompositeKinds, fallbackCompositeKinds, kindAccepts };
|
|
283
|
+
export { SOURCE_MEDIA_TYPES, compositeKind, defaultCompositeKinds, fallbackCompositeKinds, kindAccepts };
|
|
145
284
|
|
|
146
285
|
//# sourceMappingURL=kinds.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"kinds.js","names":[],"sources":["../../../src/features/composites/kinds.ts"],"sourcesContent":["// Vue-free and server-importable: the kind registry of the composite block family („Bausteine“).\nimport { createTranslator, type Translate } from '../../i18n'\n\n/** One metadata field of a composite kind, stored under `key` in the composite's `meta` attribute. */\nexport interface CompositeMetaField {\n key: string\n label: string\n type: 'text' | 'textarea' | 'date' | 'number' | 'select'\n /** Choices of a `select` field. */\n options?: { value: string, label: string }[]\n}\n\n/**\n * What a kind tells the model beyond its fields. `purpose` goes into every AI request's block model (chat, generate\n * tasks); `instructions`, `instructionsField` and `skeleton` are read only by „Baustein füllen (KI)“ (`fillComposite`).\n */\nexport interface CompositeKindAi {\n /** One or two German sentences: what a Baustein of this kind is for and what its body holds. */\n purpose: string\n /** Default instruction for filling the body of a Baustein of this kind (what to write, structure, tone). */\n instructions?: string\n /** Key of a `textarea` field of this kind; a Baustein whose value is non-empty replaces `instructions` with it. */\n instructionsField?: string\n /** Target text (Vorlage) as Markdown; `{key}` placeholders are replaced by the Baustein's `meta[key]` before it goes to the model, unknown ones stay. */\n skeleton?: string\n}\n\n/** A composite kind: what its `kind` attribute selects (label, icon, chrome placeholders, meta fields). */\nexport interface CompositeKind {\n id: string\n label: string\n icon: string\n titlePlaceholder: string\n descriptionPlaceholder: string\n fields: CompositeMetaField[]\n /** Absent: the kind has no AI brief; „Baustein füllen (KI)“ is not offered for it. */\n ai?: CompositeKindAi\n /**\n * Baustein kinds this kind accepts as nested Bausteine: a list of kind ids, or `'all'`. Absent: `folder` and `document`\n * accept `'all'`, every other kind accepts none. Non-Baustein content (paragraphs, lists, ...) is always allowed.\n * Only new moves are checked; documents that already nest against it stay as they are.\n */\n accepts?: readonly string[] | 'all'\n}\n\n/**\n * The built-in kinds in the language of `t`. The default set is produced from the translator (labels, placeholders, field\n * labels and status choices are catalog messages), so it is built per translator and memoized; hosts that pass their own\n * kinds (`compositeFeature({ kinds })`, `Composite.configure({ kinds })`) keep their labels untouched. Ids, field keys and\n * stored values (`open`, `doing`, `done`) do not depend on the language.\n */\nexport function defaultCompositeKinds(t: Translate): readonly CompositeKind[] {\n let kinds = DEFAULT_KINDS.get(t)\n if (!kinds) DEFAULT_KINDS.set(t, kinds = buildDefaultKinds(t))\n return kinds\n}\n\nconst DEFAULT_KINDS = new WeakMap<Translate, readonly CompositeKind[]>()\n\nfunction buildDefaultKinds(t: Translate): readonly CompositeKind[] {\n return [\n { id: 'section', label: t('composites.kind.section.label'), icon: 'i-lucide-layers', titlePlaceholder: t('composites.kind.section.title'), descriptionPlaceholder: t('composites.kind.section.description'), fields: [], accepts: 'all' },\n { id: 'task', label: t('composites.kind.task.label'), icon: 'i-lucide-square-check', titlePlaceholder: t('composites.kind.task.title'), descriptionPlaceholder: t('composites.kind.task.description'), fields: [\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 { id: 'note', label: t('composites.kind.note.label'), icon: 'i-lucide-sticky-note', titlePlaceholder: t('composites.kind.note.title'), descriptionPlaceholder: t('composites.kind.note.description'), fields: [] },\n { id: 'document', label: t('composites.kind.document.label'), icon: 'i-lucide-file-text', titlePlaceholder: t('composites.kind.document.title'), descriptionPlaceholder: t('composites.kind.document.description'), fields: [\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 { key: 'transcript', label: t('composites.kind.document.field.transcript'), type: 'textarea' },\n ] },\n { id: 'folder', label: t('composites.kind.folder.label'), icon: 'i-lucide-folder', titlePlaceholder: t('composites.kind.folder.title'), descriptionPlaceholder: t('composites.kind.folder.description'), fields: [] },\n ]\n}\n\n/** The built-in kinds in the default language, for server-side and context-free code (`Composite`'s default option, an editor without a context). */\nexport const fallbackCompositeKinds = (): readonly CompositeKind[] => defaultCompositeKinds(DEFAULT_TRANSLATE)\n\nconst DEFAULT_TRANSLATE = createTranslator()\n\n/** Kind `id` from `kinds`; an unknown id gets the `section` kind's presentation (else the first kind's) under its own id and label. */\nexport function compositeKind(kinds: readonly CompositeKind[], id: string): CompositeKind {\n const known = kinds.find(kind => kind.id === id)\n if (known) return known\n const base = kinds.find(kind => kind.id === 'section') ?? kinds[0] ?? fallbackCompositeKinds()[0]!\n return { ...base, id, label: id }\n}\n\n/** Kinds that accept every Baustein kind when their definition sets no `accepts`. */\nconst ACCEPTS_ALL_BY_DEFAULT: Record<string, true> = { folder: true, document: true }\n\n/**\n * Whether a Baustein of kind `parentKind` accepts one of kind `childKind` as nested Baustein. The `accepts` of the kind\n * in `kinds` decides; without one (or for a kind `kinds` does not list) only `folder` and `document` accept all.\n */\nexport function kindAccepts(kinds: readonly CompositeKind[], parentKind: string, childKind: string): boolean {\n const accepts = kinds.find(kind => kind.id === parentKind)?.accepts\n if (accepts === undefined) return Object.hasOwn(ACCEPTS_ALL_BY_DEFAULT, parentKind)\n return accepts === 'all' || accepts.includes(childKind)\n}\n"],"mappings":";;;;;;;;AAmDA,SAAgB,sBAAsB,GAAwC;CAC5E,IAAI,QAAQ,cAAc,IAAI,CAAC;CAC/B,IAAI,CAAC,OAAO,cAAc,IAAI,GAAG,QAAQ,kBAAkB,CAAC,CAAC;CAC7D,OAAO;AACT;AAEA,MAAM,gCAAgB,IAAI,QAA6C;AAEvE,SAAS,kBAAkB,GAAwC;CACjE,OAAO;EACL;GAAE,IAAI;GAAW,OAAO,EAAE,+BAA+B;GAAG,MAAM;GAAmB,kBAAkB,EAAE,+BAA+B;GAAG,wBAAwB,EAAE,qCAAqC;GAAG,QAAQ,CAAC;GAAG,SAAS;EAAM;EACxO;GAAE,IAAI;GAAQ,OAAO,EAAE,4BAA4B;GAAG,MAAM;GAAyB,kBAAkB,EAAE,4BAA4B;GAAG,wBAAwB,EAAE,kCAAkC;GAAG,QAAQ;IAC7M;KAAE,KAAK;KAAU,OAAO,EAAE,mCAAmC;KAAG,MAAM;KAAU,SAAS;MACvF;OAAE,OAAO;OAAQ,OAAO,EAAE,kCAAkC;MAAE;MAC9D;OAAE,OAAO;OAAS,OAAO,EAAE,mCAAmC;MAAE;MAChE;OAAE,OAAO;OAAQ,OAAO,EAAE,kCAAkC;MAAE;KAChE;IAAE;IACF;KAAE,KAAK;KAAO,OAAO,EAAE,gCAAgC;KAAG,MAAM;IAAO;IACvE;KAAE,KAAK;KAAY,OAAO,EAAE,qCAAqC;KAAG,MAAM;IAAO;GACnF;EAAE;EACF;GAAE,IAAI;GAAQ,OAAO,EAAE,4BAA4B;GAAG,MAAM;GAAwB,kBAAkB,EAAE,4BAA4B;GAAG,wBAAwB,EAAE,kCAAkC;GAAG,QAAQ,CAAC;EAAE;EACjN;GAAE,IAAI;GAAY,OAAO,EAAE,gCAAgC;GAAG,MAAM;GAAsB,kBAAkB,EAAE,gCAAgC;GAAG,wBAAwB,EAAE,sCAAsC;GAAG,QAAQ;IAC1N;KAAE,KAAK;KAAY,OAAO,EAAE,yCAAyC;KAAG,MAAM;IAAO;IACrF;KAAE,KAAK;KAAY,OAAO,EAAE,yCAAyC;KAAG,MAAM;IAAO;IACrF;KAAE,KAAK;KAAQ,OAAO,EAAE,qCAAqC;KAAG,MAAM;IAAS;IAC/E;KAAE,KAAK;KAAc,OAAO,EAAE,2CAA2C;KAAG,MAAM;IAAO;IACzF;KAAE,KAAK;KAAc,OAAO,EAAE,2CAA2C;KAAG,MAAM;IAAW;GAC/F;EAAE;EACF;GAAE,IAAI;GAAU,OAAO,EAAE,8BAA8B;GAAG,MAAM;GAAmB,kBAAkB,EAAE,8BAA8B;GAAG,wBAAwB,EAAE,oCAAoC;GAAG,QAAQ,CAAC;EAAE;CACtN;AACF;;AAGA,MAAa,+BAAyD,sBAAsB,iBAAiB;AAE7G,MAAM,oBAAoB,iBAAiB;;AAG3C,SAAgB,cAAc,OAAiC,IAA2B;CACxF,MAAM,QAAQ,MAAM,MAAK,SAAQ,KAAK,OAAO,EAAE;CAC/C,IAAI,OAAO,OAAO;CAElB,OAAO;EAAE,GADI,MAAM,MAAK,SAAQ,KAAK,OAAO,SAAS,KAAK,MAAM,MAAM,uBAAuB,CAAC,CAAC;EAC7E;EAAI,OAAO;CAAG;AAClC;;AAGA,MAAM,yBAA+C;CAAE,QAAQ;CAAM,UAAU;AAAK;;;;;AAMpF,SAAgB,YAAY,OAAiC,YAAoB,WAA4B;CAC3G,MAAM,UAAU,MAAM,MAAK,SAAQ,KAAK,OAAO,UAAU,CAAC,EAAE;CAC5D,IAAI,YAAY,KAAA,GAAW,OAAO,OAAO,OAAO,wBAAwB,UAAU;CAClF,OAAO,YAAY,SAAS,QAAQ,SAAS,SAAS;AACxD"}
|
|
1
|
+
{"version":3,"file":"kinds.js","names":[],"sources":["../../../src/features/composites/kinds.ts"],"sourcesContent":["// Vue-free and server-importable: the kind registry of the composite block family („Bausteine“).\nimport { createTranslator, type Translate } from '../../i18n'\n\n/** Media block types a source-holding kind's source may be (`CompositeKind.source`). */\nexport const SOURCE_MEDIA_TYPES = ['image', 'audio', 'video', 'file'] as const\n\n/** One metadata field of a composite kind, stored under `key` in the composite's `meta` attribute. */\nexport interface CompositeMetaField {\n key: string\n label: string\n /** `bibliography`: CSL-JSON item under `meta.bib`; `derivation`: read-only provenance of a derived Baustein; `reference`: block id of another Baustein. */\n type: 'text' | 'textarea' | 'date' | 'number' | 'select' | 'reference' | 'bibliography' | 'derivation'\n /** Choices of a `select` field. */\n options?: { value: string, label: string }[]\n /** `reference`: kind ids the field may point to; absent = any Baustein. */\n targets?: readonly string[]\n}\n\n/**\n * What a kind tells the model beyond its fields. `purpose` goes into every AI request's block model (chat, generate\n * tasks); `instructions`, `instructionsField` and `skeleton` are read only by „Baustein füllen (KI)“ (`fillComposite`).\n */\nexport interface CompositeKindAi {\n /** One or two German sentences: what a Baustein of this kind is for and what its body holds. */\n purpose: string\n /** Default instruction for filling the body of a Baustein of this kind (what to write, structure, tone). */\n instructions?: string\n /** Key of a `textarea` field of this kind; a Baustein whose value is non-empty replaces `instructions` with it. */\n instructionsField?: string\n /** Target text (Vorlage) as Markdown; `{key}` placeholders are replaced by the Baustein's `meta[key]` before it goes to the model, unknown ones stay. */\n skeleton?: string\n}\n\n/** A composite kind: what its `kind` attribute selects (label, icon, chrome placeholders, meta fields). */\nexport interface CompositeKind {\n id: string\n label: string\n icon: string\n titlePlaceholder: string\n descriptionPlaceholder: string\n fields: CompositeMetaField[]\n /** Absent: the kind has no AI brief; „Baustein füllen (KI)“ is not offered for it. */\n ai?: CompositeKindAi\n /**\n * Baustein kinds this kind accepts as nested Bausteine: a list of kind ids, or `'all'`. Absent: `folder` and `document`\n * accept `'all'`, every other kind accepts none. Non-Baustein content (paragraphs, lists, ...) is always allowed.\n * Only new moves are checked; documents that already nest against it stay as they are.\n */\n accepts?: readonly string[] | 'all'\n /** Present on source-holding kinds: the media block types the kind's source may be; `sourceOf` returns the first body child of one of these. */\n source?: readonly (typeof SOURCE_MEDIA_TYPES)[number][]\n}\n\n/**\n * The built-in kinds in the language of `t`. The default set is produced from the translator (labels, placeholders, field\n * labels and status choices are catalog messages), so it is built per translator and memoized; hosts that pass their own\n * kinds (`compositeFeature({ kinds })`, `Composite.configure({ kinds })`) keep their labels untouched. Ids, field keys and\n * stored values (`open`, `doing`, `done`) do not depend on the language.\n */\nexport function defaultCompositeKinds(t: Translate): readonly CompositeKind[] {\n let kinds = DEFAULT_KINDS.get(t)\n if (!kinds) DEFAULT_KINDS.set(t, kinds = buildDefaultKinds(t))\n return kinds\n}\n\nconst DEFAULT_KINDS = new WeakMap<Translate, readonly CompositeKind[]>()\n\nfunction buildDefaultKinds(t: Translate): readonly CompositeKind[] {\n return [\n { id: 'section', label: t('composites.kind.section.label'), icon: 'i-lucide-layers', titlePlaceholder: t('composites.kind.section.title'), descriptionPlaceholder: t('composites.kind.section.description'), fields: [], accepts: 'all' },\n { id: 'task', label: t('composites.kind.task.label'), icon: 'i-lucide-square-check', titlePlaceholder: t('composites.kind.task.title'), descriptionPlaceholder: t('composites.kind.task.description'), fields: [\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 { id: 'note', label: t('composites.kind.note.label'), icon: 'i-lucide-sticky-note', titlePlaceholder: t('composites.kind.note.title'), descriptionPlaceholder: t('composites.kind.note.description'), fields: [], ai: { purpose: 'Eigene Notiz zu einer Quelle oder einem Thema: Zusammenfassung, Gedanken, offene Fragen.' } },\n { id: 'document', label: t('composites.kind.document.label'), icon: 'i-lucide-file-text', titlePlaceholder: t('composites.kind.document.title'), descriptionPlaceholder: t('composites.kind.document.description'), source: [...SOURCE_MEDIA_TYPES], fields: [\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 { id: 'recording', label: t('composites.kind.recording.label'), icon: 'i-lucide-mic', titlePlaceholder: t('composites.kind.recording.title'), descriptionPlaceholder: t('composites.kind.recording.description'), accepts: 'all', source: ['audio', 'video'], fields: [\n ...importFields(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 ], ai: { purpose: 'Aufnahme (Audio oder Video) als Quelle; der Inhalt hält Lesefassungen wie das Transkript und eigene Notizen.' } },\n { id: 'paper', label: t('composites.kind.paper.label'), icon: 'i-lucide-scroll-text', titlePlaceholder: t('composites.kind.paper.title'), descriptionPlaceholder: t('composites.kind.paper.description'), accepts: 'all', source: ['file'], fields: [\n ...importFields(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 ], ai: { purpose: 'Wissenschaftliche Arbeit als Quelle (PDF) mit Literaturangabe; der Inhalt hält Volltext, Zusammenfassungen und Notizen.' } },\n { id: 'book', label: t('composites.kind.book.label'), icon: 'i-lucide-book', titlePlaceholder: t('composites.kind.book.title'), descriptionPlaceholder: t('composites.kind.book.description'), accepts: 'all', source: ['file'], fields: [\n ...importFields(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 ], ai: { purpose: 'Buch als Quelle (PDF) mit Literaturangabe; der Inhalt hält den Volltext, gegliedert in Kapitel, und Notizen.' } },\n { id: 'figure', label: t('composites.kind.figure.label'), icon: 'i-lucide-image', titlePlaceholder: t('composites.kind.figure.title'), descriptionPlaceholder: t('composites.kind.figure.description'), accepts: 'all', source: ['image'], fields: [\n ...importFields(t, 'figure'),\n { key: 'credit', label: t('composites.kind.figure.field.credit'), type: 'text' },\n ], ai: { purpose: 'Bild als Quelle; der Inhalt hält die Bildbeschreibung und eigene Notizen.' } },\n { id: 'rendition', label: t('composites.kind.rendition.label'), icon: 'i-lucide-captions', titlePlaceholder: t('composites.kind.rendition.title'), descriptionPlaceholder: t('composites.kind.rendition.description'), accepts: 'all', fields: [\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 ], ai: {\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 { id: 'folder', label: t('composites.kind.folder.label'), icon: 'i-lucide-folder', titlePlaceholder: t('composites.kind.folder.title'), descriptionPlaceholder: t('composites.kind.folder.description'), fields: [] },\n ]\n}\n\n/** The four fields the import of a file fills in (`wrapImport` of `composite-media`), shared by every source-holding kind. */\nfunction importFields(t: Translate, kind: 'recording' | 'paper' | 'book' | 'figure'): CompositeMetaField[] {\n return [\n { key: 'filename', label: t(`composites.kind.${kind}.field.filename`), type: 'text' },\n { key: 'mimeType', label: t(`composites.kind.${kind}.field.mimeType`), type: 'text' },\n { key: 'size', label: t(`composites.kind.${kind}.field.size`), type: 'number' },\n { key: 'importedAt', label: t(`composites.kind.${kind}.field.importedAt`), type: 'date' },\n ]\n}\n\n/** The built-in kinds in the default language, for server-side and context-free code (`Composite`'s default option, an editor without a context). */\nexport const fallbackCompositeKinds = (): readonly CompositeKind[] => defaultCompositeKinds(DEFAULT_TRANSLATE)\n\nconst DEFAULT_TRANSLATE = createTranslator()\n\n/** Kind `id` from `kinds`; an unknown id gets the `section` kind's presentation (else the first kind's) under its own id and label. */\nexport function compositeKind(kinds: readonly CompositeKind[], id: string): CompositeKind {\n const known = kinds.find(kind => kind.id === id)\n if (known) return known\n const base = kinds.find(kind => kind.id === 'section') ?? kinds[0] ?? fallbackCompositeKinds()[0]!\n return { ...base, id, label: id }\n}\n\n/** Kinds that accept every Baustein kind when their definition sets no `accepts`. */\nconst ACCEPTS_ALL_BY_DEFAULT: Record<string, true> = { folder: true, document: true }\n\n/**\n * Whether a Baustein of kind `parentKind` accepts one of kind `childKind` as nested Baustein. The `accepts` of the kind\n * in `kinds` decides; without one (or for a kind `kinds` does not list) only `folder` and `document` accept all.\n */\nexport function kindAccepts(kinds: readonly CompositeKind[], parentKind: string, childKind: string): boolean {\n const accepts = kinds.find(kind => kind.id === parentKind)?.accepts\n if (accepts === undefined) return Object.hasOwn(ACCEPTS_ALL_BY_DEFAULT, parentKind)\n return accepts === 'all' || accepts.includes(childKind)\n}\n"],"mappings":";;;AAIA,MAAa,qBAAqB;CAAC;CAAS;CAAS;CAAS;AAAM;;;;;;;AAuDpE,SAAgB,sBAAsB,GAAwC;CAC5E,IAAI,QAAQ,cAAc,IAAI,CAAC;CAC/B,IAAI,CAAC,OAAO,cAAc,IAAI,GAAG,QAAQ,kBAAkB,CAAC,CAAC;CAC7D,OAAO;AACT;AAEA,MAAM,gCAAgB,IAAI,QAA6C;AAEvE,SAAS,kBAAkB,GAAwC;CACjE,OAAO;EACL;GAAE,IAAI;GAAW,OAAO,EAAE,+BAA+B;GAAG,MAAM;GAAmB,kBAAkB,EAAE,+BAA+B;GAAG,wBAAwB,EAAE,qCAAqC;GAAG,QAAQ,CAAC;GAAG,SAAS;EAAM;EACxO;GAAE,IAAI;GAAQ,OAAO,EAAE,4BAA4B;GAAG,MAAM;GAAyB,kBAAkB,EAAE,4BAA4B;GAAG,wBAAwB,EAAE,kCAAkC;GAAG,QAAQ;IAC7M;KAAE,KAAK;KAAU,OAAO,EAAE,mCAAmC;KAAG,MAAM;KAAU,SAAS;MACvF;OAAE,OAAO;OAAQ,OAAO,EAAE,kCAAkC;MAAE;MAC9D;OAAE,OAAO;OAAS,OAAO,EAAE,mCAAmC;MAAE;MAChE;OAAE,OAAO;OAAQ,OAAO,EAAE,kCAAkC;MAAE;KAChE;IAAE;IACF;KAAE,KAAK;KAAO,OAAO,EAAE,gCAAgC;KAAG,MAAM;IAAO;IACvE;KAAE,KAAK;KAAY,OAAO,EAAE,qCAAqC;KAAG,MAAM;IAAO;GACnF;EAAE;EAEF;GAAE,IAAI;GAAQ,OAAO,EAAE,4BAA4B;GAAG,MAAM;GAAwB,kBAAkB,EAAE,4BAA4B;GAAG,wBAAwB,EAAE,kCAAkC;GAAG,QAAQ,CAAC;GAAG,IAAI,EAAE,SAAS,2FAA2F;EAAE;EAC9T;GAAE,IAAI;GAAY,OAAO,EAAE,gCAAgC;GAAG,MAAM;GAAsB,kBAAkB,EAAE,gCAAgC;GAAG,wBAAwB,EAAE,sCAAsC;GAAG,QAAQ,CAAC,GAAG,kBAAkB;GAAG,QAAQ;IAC3P;KAAE,KAAK;KAAY,OAAO,EAAE,yCAAyC;KAAG,MAAM;IAAO;IACrF;KAAE,KAAK;KAAY,OAAO,EAAE,yCAAyC;KAAG,MAAM;IAAO;IACrF;KAAE,KAAK;KAAQ,OAAO,EAAE,qCAAqC;KAAG,MAAM;IAAS;IAC/E;KAAE,KAAK;KAAc,OAAO,EAAE,2CAA2C;KAAG,MAAM;IAAO;GAC3F;EAAE;EAEF;GAAE,IAAI;GAAa,OAAO,EAAE,iCAAiC;GAAG,MAAM;GAAgB,kBAAkB,EAAE,iCAAiC;GAAG,wBAAwB,EAAE,uCAAuC;GAAG,SAAS;GAAO,QAAQ,CAAC,SAAS,OAAO;GAAG,QAAQ;IACpQ,GAAG,aAAa,GAAG,WAAW;IAC9B;KAAE,KAAK;KAAc,OAAO,EAAE,4CAA4C;KAAG,MAAM;IAAO;IAC1F;KAAE,KAAK;KAAgB,OAAO,EAAE,8CAA8C;KAAG,MAAM;IAAO;IAC9F;KAAE,KAAK;KAAmB,OAAO,EAAE,iDAAiD;KAAG,MAAM;IAAS;GACxG;GAAG,IAAI,EAAE,SAAS,+GAA+G;EAAE;EACnI;GAAE,IAAI;GAAS,OAAO,EAAE,6BAA6B;GAAG,MAAM;GAAwB,kBAAkB,EAAE,6BAA6B;GAAG,wBAAwB,EAAE,mCAAmC;GAAG,SAAS;GAAO,QAAQ,CAAC,MAAM;GAAG,QAAQ;IAClP,GAAG,aAAa,GAAG,OAAO;IAC1B;KAAE,KAAK;KAAO,OAAO,EAAE,iCAAiC;KAAG,MAAM;IAAe;IAChF;KAAE,KAAK;KAAO,OAAO,EAAE,iCAAiC;KAAG,MAAM;IAAO;GAC1E;GAAG,IAAI,EAAE,SAAS,0HAA0H;EAAE;EAC9I;GAAE,IAAI;GAAQ,OAAO,EAAE,4BAA4B;GAAG,MAAM;GAAiB,kBAAkB,EAAE,4BAA4B;GAAG,wBAAwB,EAAE,kCAAkC;GAAG,SAAS;GAAO,QAAQ,CAAC,MAAM;GAAG,QAAQ;IACvO,GAAG,aAAa,GAAG,MAAM;IACzB;KAAE,KAAK;KAAO,OAAO,EAAE,gCAAgC;KAAG,MAAM;IAAe;IAC/E;KAAE,KAAK;KAAQ,OAAO,EAAE,iCAAiC;KAAG,MAAM;IAAO;GAC3E;GAAG,IAAI,EAAE,SAAS,+GAA+G;EAAE;EACnI;GAAE,IAAI;GAAU,OAAO,EAAE,8BAA8B;GAAG,MAAM;GAAkB,kBAAkB,EAAE,8BAA8B;GAAG,wBAAwB,EAAE,oCAAoC;GAAG,SAAS;GAAO,QAAQ,CAAC,OAAO;GAAG,QAAQ,CACjP,GAAG,aAAa,GAAG,QAAQ,GAC3B;IAAE,KAAK;IAAU,OAAO,EAAE,qCAAqC;IAAG,MAAM;GAAO,CACjF;GAAG,IAAI,EAAE,SAAS,4EAA4E;EAAE;EAChG;GAAE,IAAI;GAAa,OAAO,EAAE,iCAAiC;GAAG,MAAM;GAAqB,kBAAkB,EAAE,iCAAiC;GAAG,wBAAwB,EAAE,uCAAuC;GAAG,SAAS;GAAO,QAAQ,CAC7O;IAAE,KAAK;IAAc,OAAO,EAAE,4CAA4C;IAAG,MAAM;GAAa,GAChG;IAAE,KAAK;IAAY,OAAO,EAAE,0CAA0C;IAAG,MAAM;GAAO,CACxF;GAAG,IAAI;IACL,SAAS;IACT,cAAc;GAChB;EAAE;EAEF;GAAE,IAAI;GAAU,OAAO,EAAE,8BAA8B;GAAG,MAAM;GAAmB,kBAAkB,EAAE,8BAA8B;GAAG,wBAAwB,EAAE,oCAAoC;GAAG,QAAQ,CAAC;EAAE;CACtN;AACF;;AAGA,SAAS,aAAa,GAAc,MAAuE;CACzG,OAAO;EACL;GAAE,KAAK;GAAY,OAAO,EAAE,mBAAmB,KAAK,gBAAgB;GAAG,MAAM;EAAO;EACpF;GAAE,KAAK;GAAY,OAAO,EAAE,mBAAmB,KAAK,gBAAgB;GAAG,MAAM;EAAO;EACpF;GAAE,KAAK;GAAQ,OAAO,EAAE,mBAAmB,KAAK,YAAY;GAAG,MAAM;EAAS;EAC9E;GAAE,KAAK;GAAc,OAAO,EAAE,mBAAmB,KAAK,kBAAkB;GAAG,MAAM;EAAO;CAC1F;AACF;;AAGA,MAAa,+BAAyD,sBAAsB,iBAAiB;AAE7G,MAAM,oBAAoB,iBAAiB;;AAG3C,SAAgB,cAAc,OAAiC,IAA2B;CACxF,MAAM,QAAQ,MAAM,MAAK,SAAQ,KAAK,OAAO,EAAE;CAC/C,IAAI,OAAO,OAAO;CAElB,OAAO;EAAE,GADI,MAAM,MAAK,SAAQ,KAAK,OAAO,SAAS,KAAK,MAAM,MAAM,uBAAuB,CAAC,CAAC;EAC7E;EAAI,OAAO;CAAG;AAClC;;AAGA,MAAM,yBAA+C;CAAE,QAAQ;CAAM,UAAU;AAAK;;;;;AAMpF,SAAgB,YAAY,OAAiC,YAAoB,WAA4B;CAC3G,MAAM,UAAU,MAAM,MAAK,SAAQ,KAAK,OAAO,UAAU,CAAC,EAAE;CAC5D,IAAI,YAAY,KAAA,GAAW,OAAO,OAAO,OAAO,wBAAwB,UAAU;CAClF,OAAO,YAAY,SAAS,QAAQ,SAAS,SAAS;AACxD"}
|
|
@@ -2,7 +2,10 @@ import { JSONContent } from "@tiptap/core";
|
|
|
2
2
|
//#region src/features/composites/legacy.d.ts
|
|
3
3
|
/** Legacy node name of the composite block; stored Yjs docs containing it are reseeded from migrated JSON. */
|
|
4
4
|
export declare const LEGACY_COMPOSITE_NODE = "section";
|
|
5
|
-
/**
|
|
5
|
+
/**
|
|
6
|
+
* `json` with legacy node types renamed to the composite family (a legacy block becomes kind `section`) and the flat
|
|
7
|
+
* `meta.transcript` of `document` Bausteine moved into a `rendition` child; recursive, returns a copy.
|
|
8
|
+
*/
|
|
6
9
|
export declare function migrateLegacyContent(json: JSONContent): JSONContent;
|
|
7
10
|
//#endregion
|
|
8
11
|
//# sourceMappingURL=legacy.d.ts.map
|
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
import { DERIVATION_KEY } from "./meta-keys.js";
|
|
2
|
+
import { assetRefOf } from "./derivation.js";
|
|
3
|
+
import { compositeJSON } from "./nodes.js";
|
|
1
4
|
//#region src/features/composites/legacy.ts
|
|
2
5
|
const LEGACY_RENAMES = {
|
|
3
6
|
section: "composite",
|
|
@@ -7,7 +10,50 @@ const LEGACY_RENAMES = {
|
|
|
7
10
|
};
|
|
8
11
|
/** Legacy node name of the composite block; stored Yjs docs containing it are reseeded from migrated JSON. */
|
|
9
12
|
const LEGACY_COMPOSITE_NODE = "section";
|
|
10
|
-
/**
|
|
13
|
+
/**
|
|
14
|
+
* The Lesefassung a `document` Baustein's former `meta.transcript` (a flat string) becomes: a `rendition` child with
|
|
15
|
+
* one paragraph per blank-line-separated chunk, derived by transcription from the asset of the first audio/video body
|
|
16
|
+
* child. Hashes are unknown (`''`), so neither „Quelle geändert“ nor „bearbeitet“ is shown for it.
|
|
17
|
+
*/
|
|
18
|
+
function transcriptRendition(document, transcript) {
|
|
19
|
+
const chunks = transcript.split(/\n\s*\n/).map((chunk) => chunk.replace(/\s*\n\s*/g, " ").trim()).filter(Boolean);
|
|
20
|
+
if (!chunks.length) return null;
|
|
21
|
+
const media = document.content?.find((child) => child.type === "audio" || child.type === "video");
|
|
22
|
+
const importedAt = document.attrs?.meta?.importedAt;
|
|
23
|
+
const derivation = {
|
|
24
|
+
from: { asset: assetRefOf(String(media?.attrs?.src ?? ""))?.name ?? "" },
|
|
25
|
+
method: "transcription",
|
|
26
|
+
createdAt: typeof importedAt === "string" ? importedAt : "",
|
|
27
|
+
inputHash: "",
|
|
28
|
+
outputHash: ""
|
|
29
|
+
};
|
|
30
|
+
const json = compositeJSON("rendition", chunks.map((text) => ({
|
|
31
|
+
type: "paragraph",
|
|
32
|
+
content: [{
|
|
33
|
+
type: "text",
|
|
34
|
+
text
|
|
35
|
+
}]
|
|
36
|
+
})));
|
|
37
|
+
const [title, ...rest] = json.content;
|
|
38
|
+
return {
|
|
39
|
+
...json,
|
|
40
|
+
attrs: {
|
|
41
|
+
...json.attrs,
|
|
42
|
+
meta: { [DERIVATION_KEY]: derivation }
|
|
43
|
+
},
|
|
44
|
+
content: [{
|
|
45
|
+
...title,
|
|
46
|
+
content: [{
|
|
47
|
+
type: "text",
|
|
48
|
+
text: "Transkript"
|
|
49
|
+
}]
|
|
50
|
+
}, ...rest]
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* `json` with legacy node types renamed to the composite family (a legacy block becomes kind `section`) and the flat
|
|
55
|
+
* `meta.transcript` of `document` Bausteine moved into a `rendition` child; recursive, returns a copy.
|
|
56
|
+
*/
|
|
11
57
|
function migrateLegacyContent(json) {
|
|
12
58
|
const renamed = json.type ? LEGACY_RENAMES[json.type] : void 0;
|
|
13
59
|
const result = { ...json };
|
|
@@ -17,6 +63,15 @@ function migrateLegacyContent(json) {
|
|
|
17
63
|
kind: "section"
|
|
18
64
|
};
|
|
19
65
|
if (json.content) result.content = json.content.map(migrateLegacyContent);
|
|
66
|
+
if (result.type === "composite" && result.attrs?.kind === "document" && typeof result.attrs.meta?.transcript === "string") {
|
|
67
|
+
const { transcript, ...meta } = result.attrs.meta;
|
|
68
|
+
result.attrs = {
|
|
69
|
+
...result.attrs,
|
|
70
|
+
meta
|
|
71
|
+
};
|
|
72
|
+
const rendition = transcriptRendition(result, String(transcript));
|
|
73
|
+
if (rendition) result.content = [...result.content ?? [], rendition];
|
|
74
|
+
}
|
|
20
75
|
return result;
|
|
21
76
|
}
|
|
22
77
|
//#endregion
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"legacy.js","names":[],"sources":["../../../src/features/composites/legacy.ts"],"sourcesContent":["import type { JSONContent } from '@tiptap/core'\n\n// Node names of the former single-purpose block that the composite family replaced (dev data only).\nconst LEGACY_RENAMES: Readonly<Record<string, string>> = {\n section: 'composite',\n sectionTitle: 'compositeTitle',\n sectionSummary: 'compositeDescription',\n sectionTags: 'compositeTags',\n}\n\n/** Legacy node name of the composite block; stored Yjs docs containing it are reseeded from migrated JSON. */\nexport const LEGACY_COMPOSITE_NODE = 'section'\n\n
|
|
1
|
+
{"version":3,"file":"legacy.js","names":[],"sources":["../../../src/features/composites/legacy.ts"],"sourcesContent":["import type { JSONContent } from '@tiptap/core'\nimport { assetRefOf, DERIVATION_KEY, type Derivation } from './derivation'\nimport { compositeJSON } from './nodes'\n\n// Node names of the former single-purpose block that the composite family replaced (dev data only).\nconst LEGACY_RENAMES: Readonly<Record<string, string>> = {\n section: 'composite',\n sectionTitle: 'compositeTitle',\n sectionSummary: 'compositeDescription',\n sectionTags: 'compositeTags',\n}\n\n/** Legacy node name of the composite block; stored Yjs docs containing it are reseeded from migrated JSON. */\nexport const LEGACY_COMPOSITE_NODE = 'section'\n\n/**\n * The Lesefassung a `document` Baustein's former `meta.transcript` (a flat string) becomes: a `rendition` child with\n * one paragraph per blank-line-separated chunk, derived by transcription from the asset of the first audio/video body\n * child. Hashes are unknown (`''`), so neither „Quelle geändert“ nor „bearbeitet“ is shown for it.\n */\nfunction transcriptRendition(document: JSONContent, transcript: string): JSONContent | null {\n const chunks = transcript.split(/\\n\\s*\\n/).map(chunk => chunk.replace(/\\s*\\n\\s*/g, ' ').trim()).filter(Boolean)\n if (!chunks.length) return null\n const media = document.content?.find(child => child.type === 'audio' || child.type === 'video')\n const importedAt: unknown = document.attrs?.meta?.importedAt\n const derivation: Derivation = {\n from: { asset: assetRefOf(String(media?.attrs?.src ?? ''))?.name ?? '' },\n method: 'transcription',\n createdAt: typeof importedAt === 'string' ? importedAt : '',\n inputHash: '',\n outputHash: '',\n }\n const json = compositeJSON('rendition', chunks.map(text => ({ type: 'paragraph', content: [{ type: 'text', text }] })))\n const [title, ...rest] = json.content!\n return {\n ...json,\n attrs: { ...json.attrs, meta: { [DERIVATION_KEY]: derivation } },\n // i18n-ignore: title of content migrated out of a stored document, not UI text\n content: [{ ...title!, content: [{ type: 'text', text: 'Transkript' }] }, ...rest],\n }\n}\n\n/**\n * `json` with legacy node types renamed to the composite family (a legacy block becomes kind `section`) and the flat\n * `meta.transcript` of `document` Bausteine moved into a `rendition` child; recursive, returns a copy.\n */\nexport function migrateLegacyContent(json: JSONContent): JSONContent {\n const renamed = json.type ? LEGACY_RENAMES[json.type] : undefined\n const result: JSONContent = { ...json }\n if (renamed) result.type = renamed\n if (json.type === LEGACY_COMPOSITE_NODE) result.attrs = { ...json.attrs, kind: 'section' }\n if (json.content) result.content = json.content.map(migrateLegacyContent)\n if (result.type === 'composite' && result.attrs?.kind === 'document' && typeof result.attrs.meta?.transcript === 'string') {\n const { transcript, ...meta } = result.attrs.meta as Record<string, unknown>\n result.attrs = { ...result.attrs, meta }\n const rendition = transcriptRendition(result, String(transcript))\n if (rendition) result.content = [...(result.content ?? []), rendition]\n }\n return result\n}\n"],"mappings":";;;;AAKA,MAAM,iBAAmD;CACvD,SAAS;CACT,cAAc;CACd,gBAAgB;CAChB,aAAa;AACf;;AAGA,MAAa,wBAAwB;;;;;;AAOrC,SAAS,oBAAoB,UAAuB,YAAwC;CAC1F,MAAM,SAAS,WAAW,MAAM,SAAS,CAAC,CAAC,KAAI,UAAS,MAAM,QAAQ,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,OAAO;CAC9G,IAAI,CAAC,OAAO,QAAQ,OAAO;CAC3B,MAAM,QAAQ,SAAS,SAAS,MAAK,UAAS,MAAM,SAAS,WAAW,MAAM,SAAS,OAAO;CAC9F,MAAM,aAAsB,SAAS,OAAO,MAAM;CAClD,MAAM,aAAyB;EAC7B,MAAM,EAAE,OAAO,WAAW,OAAO,OAAO,OAAO,OAAO,EAAE,CAAC,CAAC,EAAE,QAAQ,GAAG;EACvE,QAAQ;EACR,WAAW,OAAO,eAAe,WAAW,aAAa;EACzD,WAAW;EACX,YAAY;CACd;CACA,MAAM,OAAO,cAAc,aAAa,OAAO,KAAI,UAAS;EAAE,MAAM;EAAa,SAAS,CAAC;GAAE,MAAM;GAAQ;EAAK,CAAC;CAAE,EAAE,CAAC;CACtH,MAAM,CAAC,OAAO,GAAG,QAAQ,KAAK;CAC9B,OAAO;EACL,GAAG;EACH,OAAO;GAAE,GAAG,KAAK;GAAO,MAAM,GAAG,iBAAiB,WAAW;EAAE;EAE/D,SAAS,CAAC;GAAE,GAAG;GAAQ,SAAS,CAAC;IAAE,MAAM;IAAQ,MAAM;GAAa,CAAC;EAAE,GAAG,GAAG,IAAI;CACnF;AACF;;;;;AAMA,SAAgB,qBAAqB,MAAgC;CACnE,MAAM,UAAU,KAAK,OAAO,eAAe,KAAK,QAAQ,KAAA;CACxD,MAAM,SAAsB,EAAE,GAAG,KAAK;CACtC,IAAI,SAAS,OAAO,OAAO;CAC3B,IAAI,KAAK,SAAA,WAAgC,OAAO,QAAQ;EAAE,GAAG,KAAK;EAAO,MAAM;CAAU;CACzF,IAAI,KAAK,SAAS,OAAO,UAAU,KAAK,QAAQ,IAAI,oBAAoB;CACxE,IAAI,OAAO,SAAS,eAAe,OAAO,OAAO,SAAS,cAAc,OAAO,OAAO,MAAM,MAAM,eAAe,UAAU;EACzH,MAAM,EAAE,YAAY,GAAG,SAAS,OAAO,MAAM;EAC7C,OAAO,QAAQ;GAAE,GAAG,OAAO;GAAO;EAAK;EACvC,MAAM,YAAY,oBAAoB,QAAQ,OAAO,UAAU,CAAC;EAChE,IAAI,WAAW,OAAO,UAAU,CAAC,GAAI,OAAO,WAAW,CAAC,GAAI,SAAS;CACvE;CACA,OAAO;AACT"}
|
|
@@ -1,9 +1,48 @@
|
|
|
1
|
+
import { findBlockById } from "../../core/schema/block-ids.js";
|
|
2
|
+
import { compositeKind } from "./kinds.js";
|
|
3
|
+
import { citeShort } from "./bibliography.js";
|
|
4
|
+
import { derivationMethodLabel } from "./derived-chrome.js";
|
|
1
5
|
//#region src/features/composites/meta-display.ts
|
|
2
6
|
/** The stored value of a meta field as editable text (`''` when unset). */
|
|
3
7
|
function metaText(row, field) {
|
|
4
8
|
const value = row.meta[field.key];
|
|
5
9
|
return typeof value === "string" || typeof value === "number" ? String(value) : "";
|
|
6
10
|
}
|
|
11
|
+
const dateFormat = new Intl.DateTimeFormat("de-DE", {
|
|
12
|
+
day: "2-digit",
|
|
13
|
+
month: "2-digit",
|
|
14
|
+
year: "numeric"
|
|
15
|
+
});
|
|
16
|
+
/** `2026-05-01` → `01.05.2026`; parsed by hand because `new Date('2026-05-01')` is UTC and can show the previous day. */
|
|
17
|
+
function formatDate(value) {
|
|
18
|
+
const match = /^(\d{4})-(\d{2})-(\d{2})/.exec(value);
|
|
19
|
+
const date = match ? new Date(Number(match[1]), Number(match[2]) - 1, Number(match[3])) : new Date(value);
|
|
20
|
+
return Number.isNaN(date.getTime()) ? value : dateFormat.format(date);
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* The text a field's value stands for in a table cell: `reference` the title of the Baustein it points to (its kind label
|
|
24
|
+
* when untitled, `''` when it is gone or `doc` is unknown), `bibliography` the short citation, `derivation`
|
|
25
|
+
* `method · date` (the method as words when `t` is given, else its stored id); every other type its stored text.
|
|
26
|
+
*/
|
|
27
|
+
function fieldDisplay(row, field, doc, kinds, t) {
|
|
28
|
+
const value = row.meta[field.key];
|
|
29
|
+
if (field.type === "reference") {
|
|
30
|
+
if (typeof value !== "string" || !value || !doc) return "";
|
|
31
|
+
const target = findBlockById(doc, value)?.node;
|
|
32
|
+
if (target?.type.name !== "composite") return "";
|
|
33
|
+
return target.child(0).textContent.trim() || compositeKind(kinds, String(target.attrs.kind)).label;
|
|
34
|
+
}
|
|
35
|
+
if (field.type === "bibliography") {
|
|
36
|
+
const bib = value;
|
|
37
|
+
return bib && typeof bib === "object" && typeof bib.type === "string" ? citeShort(bib, row.title) : "";
|
|
38
|
+
}
|
|
39
|
+
if (field.type === "derivation") {
|
|
40
|
+
const derivation = value;
|
|
41
|
+
if (!derivation || typeof derivation !== "object" || typeof derivation.method !== "string") return "";
|
|
42
|
+
return [t ? derivationMethodLabel(t, derivation.method) : derivation.method, derivation.createdAt ? formatDate(derivation.createdAt) : ""].filter(Boolean).join(" · ");
|
|
43
|
+
}
|
|
44
|
+
return metaText(row, field);
|
|
45
|
+
}
|
|
7
46
|
/** Icon and color class of the known status values; unknown values read as neutral. */
|
|
8
47
|
const STATUS_STYLE = {
|
|
9
48
|
open: {
|
|
@@ -41,6 +80,6 @@ function rowStatus(row, t) {
|
|
|
41
80
|
};
|
|
42
81
|
}
|
|
43
82
|
//#endregion
|
|
44
|
-
export { metaText, rowStatus, statusStyle };
|
|
83
|
+
export { fieldDisplay, formatDate, metaText, rowStatus, statusStyle };
|
|
45
84
|
|
|
46
85
|
//# sourceMappingURL=meta-display.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"meta-display.js","names":[],"sources":["../../../src/features/composites/meta-display.ts"],"sourcesContent":["import type { Translate } from '../../i18n'\nimport type { CompositeMetaField } from './kinds'\nimport type { CompositeRow } from './rows'\n\n/** The stored value of a meta field as editable text (`''` when unset). */\nexport function metaText(row: Pick<CompositeRow, 'meta'>, field: Pick<CompositeMetaField, 'key'>): string {\n const value = row.meta[field.key]\n return typeof value === 'string' || typeof value === 'number' ? String(value) : ''\n}\n\n/** Icon and color class of the known status values; unknown values read as neutral. */\nconst STATUS_STYLE: Record<string, { icon: string, color: string }> = {\n open: { icon: 'i-lucide-circle', color: 'text-[var(--sk-muted)]' },\n doing: { icon: 'i-lucide-circle-dot', color: 'text-[var(--sk-info)]' },\n done: { icon: 'i-lucide-circle-check', color: 'text-[var(--sk-success)]' },\n}\nconst STATUS_UNSET = { icon: 'i-lucide-circle-dashed', color: 'text-[var(--sk-fg-dimmed)]' }\nconst STATUS_OTHER = { icon: 'i-lucide-circle', color: 'text-[var(--sk-muted)]' }\n\nexport const statusStyle = (value: string) => STATUS_STYLE[value] ?? (value ? STATUS_OTHER : STATUS_UNSET)\n\n/** A row's `status` field with its current value. */\nexport interface RowStatus {\n field: CompositeMetaField\n value: string\n label: string\n icon: string\n color: string\n}\n\n/** The row's `status` select field with its current value, `null` for a kind without one; `t` words an unset status. */\nexport function rowStatus(row: CompositeRow, t: Translate): RowStatus | null {\n const field = row.fields.find(candidate => candidate.key === 'status' && candidate.type === 'select')\n if (!field) return null\n const value = metaText(row, field)\n return { field, value, label: field.options?.find(option => option.value === value)?.label ?? (value || t('composites.status.none')), ...statusStyle(value) }\n}\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"meta-display.js","names":[],"sources":["../../../src/features/composites/meta-display.ts"],"sourcesContent":["import type { Node as PMNode } from '@tiptap/pm/model'\nimport { findBlockById } from '../../core/schema/block-ids'\nimport type { Translate } from '../../i18n'\nimport { type CslItem, citeShort } from './bibliography'\nimport type { Derivation } from './derivation'\nimport { derivationMethodLabel } from './derived-chrome'\nimport { type CompositeKind, type CompositeMetaField, compositeKind } from './kinds'\nimport type { CompositeRow } from './rows'\n\n/** The stored value of a meta field as editable text (`''` when unset). */\nexport function metaText(row: Pick<CompositeRow, 'meta'>, field: Pick<CompositeMetaField, 'key'>): string {\n const value = row.meta[field.key]\n return typeof value === 'string' || typeof value === 'number' ? String(value) : ''\n}\n\nconst dateFormat = new Intl.DateTimeFormat('de-DE', { day: '2-digit', month: '2-digit', year: 'numeric' })\n\n/** `2026-05-01` → `01.05.2026`; parsed by hand because `new Date('2026-05-01')` is UTC and can show the previous day. */\nexport function formatDate(value: string): string {\n const match = /^(\\d{4})-(\\d{2})-(\\d{2})/.exec(value)\n const date = match ? new Date(Number(match[1]), Number(match[2]) - 1, Number(match[3])) : new Date(value)\n return Number.isNaN(date.getTime()) ? value : dateFormat.format(date)\n}\n\n/**\n * The text a field's value stands for in a table cell: `reference` the title of the Baustein it points to (its kind label\n * when untitled, `''` when it is gone or `doc` is unknown), `bibliography` the short citation, `derivation`\n * `method · date` (the method as words when `t` is given, else its stored id); every other type its stored text.\n */\nexport function fieldDisplay(row: Pick<CompositeRow, 'meta' | 'title'>, field: Pick<CompositeMetaField, 'key' | 'type'>, doc: PMNode | null, kinds: readonly CompositeKind[], t?: Translate): string {\n const value = row.meta[field.key]\n if (field.type === 'reference') {\n if (typeof value !== 'string' || !value || !doc) return ''\n const target = findBlockById(doc, value)?.node\n if (target?.type.name !== 'composite') return ''\n return target.child(0).textContent.trim() || compositeKind(kinds, String(target.attrs.kind)).label\n }\n if (field.type === 'bibliography') {\n const bib = value as Partial<CslItem> | null | undefined\n return bib && typeof bib === 'object' && typeof bib.type === 'string' ? citeShort(bib, row.title) : ''\n }\n if (field.type === 'derivation') {\n const derivation = value as Partial<Derivation> | null | undefined\n if (!derivation || typeof derivation !== 'object' || typeof derivation.method !== 'string') return ''\n return [t ? derivationMethodLabel(t, derivation.method) : derivation.method, derivation.createdAt ? formatDate(derivation.createdAt) : ''].filter(Boolean).join(' · ')\n }\n return metaText(row, field)\n}\n\n/** Icon and color class of the known status values; unknown values read as neutral. */\nconst STATUS_STYLE: Record<string, { icon: string, color: string }> = {\n open: { icon: 'i-lucide-circle', color: 'text-[var(--sk-muted)]' },\n doing: { icon: 'i-lucide-circle-dot', color: 'text-[var(--sk-info)]' },\n done: { icon: 'i-lucide-circle-check', color: 'text-[var(--sk-success)]' },\n}\nconst STATUS_UNSET = { icon: 'i-lucide-circle-dashed', color: 'text-[var(--sk-fg-dimmed)]' }\nconst STATUS_OTHER = { icon: 'i-lucide-circle', color: 'text-[var(--sk-muted)]' }\n\nexport const statusStyle = (value: string) => STATUS_STYLE[value] ?? (value ? STATUS_OTHER : STATUS_UNSET)\n\n/** A row's `status` field with its current value. */\nexport interface RowStatus {\n field: CompositeMetaField\n value: string\n label: string\n icon: string\n color: string\n}\n\n/** The row's `status` select field with its current value, `null` for a kind without one; `t` words an unset status. */\nexport function rowStatus(row: CompositeRow, t: Translate): RowStatus | null {\n const field = row.fields.find(candidate => candidate.key === 'status' && candidate.type === 'select')\n if (!field) return null\n const value = metaText(row, field)\n return { field, value, label: field.options?.find(option => option.value === value)?.label ?? (value || t('composites.status.none')), ...statusStyle(value) }\n}\n"],"mappings":";;;;;;AAUA,SAAgB,SAAS,KAAiC,OAAgD;CACxG,MAAM,QAAQ,IAAI,KAAK,MAAM;CAC7B,OAAO,OAAO,UAAU,YAAY,OAAO,UAAU,WAAW,OAAO,KAAK,IAAI;AAClF;AAEA,MAAM,aAAa,IAAI,KAAK,eAAe,SAAS;CAAE,KAAK;CAAW,OAAO;CAAW,MAAM;AAAU,CAAC;;AAGzG,SAAgB,WAAW,OAAuB;CAChD,MAAM,QAAQ,2BAA2B,KAAK,KAAK;CACnD,MAAM,OAAO,QAAQ,IAAI,KAAK,OAAO,MAAM,EAAE,GAAG,OAAO,MAAM,EAAE,IAAI,GAAG,OAAO,MAAM,EAAE,CAAC,IAAI,IAAI,KAAK,KAAK;CACxG,OAAO,OAAO,MAAM,KAAK,QAAQ,CAAC,IAAI,QAAQ,WAAW,OAAO,IAAI;AACtE;;;;;;AAOA,SAAgB,aAAa,KAA2C,OAAiD,KAAoB,OAAiC,GAAuB;CACnM,MAAM,QAAQ,IAAI,KAAK,MAAM;CAC7B,IAAI,MAAM,SAAS,aAAa;EAC9B,IAAI,OAAO,UAAU,YAAY,CAAC,SAAS,CAAC,KAAK,OAAO;EACxD,MAAM,SAAS,cAAc,KAAK,KAAK,CAAC,EAAE;EAC1C,IAAI,QAAQ,KAAK,SAAS,aAAa,OAAO;EAC9C,OAAO,OAAO,MAAM,CAAC,CAAC,CAAC,YAAY,KAAK,KAAK,cAAc,OAAO,OAAO,OAAO,MAAM,IAAI,CAAC,CAAC,CAAC;CAC/F;CACA,IAAI,MAAM,SAAS,gBAAgB;EACjC,MAAM,MAAM;EACZ,OAAO,OAAO,OAAO,QAAQ,YAAY,OAAO,IAAI,SAAS,WAAW,UAAU,KAAK,IAAI,KAAK,IAAI;CACtG;CACA,IAAI,MAAM,SAAS,cAAc;EAC/B,MAAM,aAAa;EACnB,IAAI,CAAC,cAAc,OAAO,eAAe,YAAY,OAAO,WAAW,WAAW,UAAU,OAAO;EACnG,OAAO,CAAC,IAAI,sBAAsB,GAAG,WAAW,MAAM,IAAI,WAAW,QAAQ,WAAW,YAAY,WAAW,WAAW,SAAS,IAAI,EAAE,CAAC,CAAC,OAAO,OAAO,CAAC,CAAC,KAAK,KAAK;CACvK;CACA,OAAO,SAAS,KAAK,KAAK;AAC5B;;AAGA,MAAM,eAAgE;CACpE,MAAM;EAAE,MAAM;EAAmB,OAAO;CAAyB;CACjE,OAAO;EAAE,MAAM;EAAuB,OAAO;CAAwB;CACrE,MAAM;EAAE,MAAM;EAAyB,OAAO;CAA2B;AAC3E;AACA,MAAM,eAAe;CAAE,MAAM;CAA0B,OAAO;AAA6B;AAC3F,MAAM,eAAe;CAAE,MAAM;CAAmB,OAAO;AAAyB;AAEhF,MAAa,eAAe,UAAkB,aAAa,WAAW,QAAQ,eAAe;;AAY7F,SAAgB,UAAU,KAAmB,GAAgC;CAC3E,MAAM,QAAQ,IAAI,OAAO,MAAK,cAAa,UAAU,QAAQ,YAAY,UAAU,SAAS,QAAQ;CACpG,IAAI,CAAC,OAAO,OAAO;CACnB,MAAM,QAAQ,SAAS,KAAK,KAAK;CACjC,OAAO;EAAE;EAAO;EAAO,OAAO,MAAM,SAAS,MAAK,WAAU,OAAO,UAAU,KAAK,CAAC,EAAE,UAAU,SAAS,EAAE,wBAAwB;EAAI,GAAG,YAAY,KAAK;CAAE;AAC9J"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
//#region src/features/composites/meta-keys.d.ts
|
|
2
|
+
/** Key of the derivation (provenance) in a composite's `meta`. */
|
|
3
|
+
export declare const DERIVATION_KEY = "derivation";
|
|
4
|
+
/** Key of the bibliographic record (`CslItem`) in a composite's `meta`. */
|
|
5
|
+
export declare const BIB_KEY = "bib";
|
|
6
|
+
//#endregion
|
|
7
|
+
//# sourceMappingURL=meta-keys.d.ts.map
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
//#region src/features/composites/meta-keys.ts
|
|
2
|
+
/** Key of the derivation (provenance) in a composite's `meta`. */
|
|
3
|
+
const DERIVATION_KEY = "derivation";
|
|
4
|
+
/** Key of the bibliographic record (`CslItem`) in a composite's `meta`. */
|
|
5
|
+
const BIB_KEY = "bib";
|
|
6
|
+
/**
|
|
7
|
+
* Whether a composite of `kind` keeps the `meta` entry `key`: the fields the kind declares, plus provenance
|
|
8
|
+
* (`derivation`) and the bibliographic record (`bib`), which any kind may carry (a kind switch, a conversion and a
|
|
9
|
+
* Markdown round trip must not drop them).
|
|
10
|
+
*/
|
|
11
|
+
function keepsMetaKey(kind, key) {
|
|
12
|
+
return key === "derivation" || key === "bib" || kind.fields.some((field) => field.key === key);
|
|
13
|
+
}
|
|
14
|
+
/** `meta` reduced to the entries a composite of `kind` keeps (`keepsMetaKey`). */
|
|
15
|
+
function keptMeta(kind, meta) {
|
|
16
|
+
return Object.fromEntries(Object.entries(meta).filter(([key]) => keepsMetaKey(kind, key)));
|
|
17
|
+
}
|
|
18
|
+
//#endregion
|
|
19
|
+
export { BIB_KEY, DERIVATION_KEY, keepsMetaKey, keptMeta };
|
|
20
|
+
|
|
21
|
+
//# sourceMappingURL=meta-keys.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"meta-keys.js","names":[],"sources":["../../../src/features/composites/meta-keys.ts"],"sourcesContent":["// Vue-free and server-importable: the `meta` keys a Baustein of any kind may carry, and which meta keys a kind keeps.\nimport type { CompositeKind } from './kinds'\n\n/** Key of the derivation (provenance) in a composite's `meta`. */\nexport const DERIVATION_KEY = 'derivation'\n\n/** Key of the bibliographic record (`CslItem`) in a composite's `meta`. */\nexport const BIB_KEY = 'bib'\n\n/**\n * Whether a composite of `kind` keeps the `meta` entry `key`: the fields the kind declares, plus provenance\n * (`derivation`) and the bibliographic record (`bib`), which any kind may carry (a kind switch, a conversion and a\n * Markdown round trip must not drop them).\n */\nexport function keepsMetaKey(kind: Pick<CompositeKind, 'fields'>, key: string): boolean {\n return key === DERIVATION_KEY || key === BIB_KEY || kind.fields.some(field => field.key === key)\n}\n\n/** `meta` reduced to the entries a composite of `kind` keeps (`keepsMetaKey`). */\nexport function keptMeta(kind: Pick<CompositeKind, 'fields'>, meta: Record<string, unknown>): Record<string, unknown> {\n return Object.fromEntries(Object.entries(meta).filter(([key]) => keepsMetaKey(kind, key)))\n}\n"],"mappings":";;AAIA,MAAa,iBAAiB;;AAG9B,MAAa,UAAU;;;;;;AAOvB,SAAgB,aAAa,MAAqC,KAAsB;CACtF,OAAO,QAAA,gBAA0B,QAAA,SAAmB,KAAK,OAAO,MAAK,UAAS,MAAM,QAAQ,GAAG;AACjG;;AAGA,SAAgB,SAAS,MAAqC,MAAwD;CACpH,OAAO,OAAO,YAAY,OAAO,QAAQ,IAAI,CAAC,CAAC,QAAQ,CAAC,SAAS,aAAa,MAAM,GAAG,CAAC,CAAC;AAC3F"}
|
|
@@ -1,17 +1,20 @@
|
|
|
1
1
|
import { CompositeOptions, CompositeStorage } from "./nodes.js";
|
|
2
|
+
import { ReferenceOptions } from "./reference.js";
|
|
2
3
|
import { NodeViewRenderer } from "@tiptap/core";
|
|
3
4
|
//#region src/features/composites/node-views.d.ts
|
|
4
|
-
/** The node view
|
|
5
|
+
/** The node view renderers a framework binding supplies for the composite block and the reference chip. */
|
|
5
6
|
export interface CompositeNodeViews {
|
|
6
7
|
composite: NodeViewRenderer;
|
|
8
|
+
reference: NodeViewRenderer;
|
|
7
9
|
}
|
|
8
10
|
/**
|
|
9
|
-
* The composite node with the node view of a framework binding,
|
|
10
|
-
* shows and edits it, so it needs no node view). Configure the kinds with `Composite.configure({ kinds: [...defaultCompositeKinds(t), myKind] })`.
|
|
11
|
+
* The composite node with the node view of a framework binding, the tags row (data: hidden, `CompositeChrome`
|
|
12
|
+
* shows and edits it, so it needs no node view) and the reference chip. Configure the kinds with `Composite.configure({ kinds: [...defaultCompositeKinds(t), myKind] })`.
|
|
11
13
|
*/
|
|
12
14
|
export declare function compositeNodes(nodeViews: CompositeNodeViews): {
|
|
13
15
|
Composite: import("@tiptap/core").Node<CompositeOptions, CompositeStorage>;
|
|
14
16
|
CompositeTags: import("@tiptap/core").Node<any, any>;
|
|
17
|
+
Reference: import("@tiptap/core").Node<ReferenceOptions, any>;
|
|
15
18
|
};
|
|
16
19
|
//#endregion
|
|
17
20
|
//# sourceMappingURL=node-views.d.ts.map
|
|
@@ -1,15 +1,19 @@
|
|
|
1
1
|
import { CompositeNode, CompositeTagsNode } from "./nodes.js";
|
|
2
|
+
import { ReferenceNode } from "./reference.js";
|
|
2
3
|
//#region src/features/composites/node-views.ts
|
|
3
4
|
/**
|
|
4
|
-
* The composite node with the node view of a framework binding,
|
|
5
|
-
* shows and edits it, so it needs no node view). Configure the kinds with `Composite.configure({ kinds: [...defaultCompositeKinds(t), myKind] })`.
|
|
5
|
+
* The composite node with the node view of a framework binding, the tags row (data: hidden, `CompositeChrome`
|
|
6
|
+
* shows and edits it, so it needs no node view) and the reference chip. Configure the kinds with `Composite.configure({ kinds: [...defaultCompositeKinds(t), myKind] })`.
|
|
6
7
|
*/
|
|
7
8
|
function compositeNodes(nodeViews) {
|
|
8
9
|
return {
|
|
9
10
|
Composite: CompositeNode.extend({ addNodeView() {
|
|
10
11
|
return nodeViews.composite;
|
|
11
12
|
} }),
|
|
12
|
-
CompositeTags: CompositeTagsNode
|
|
13
|
+
CompositeTags: CompositeTagsNode,
|
|
14
|
+
Reference: ReferenceNode.extend({ addNodeView() {
|
|
15
|
+
return nodeViews.reference;
|
|
16
|
+
} })
|
|
13
17
|
};
|
|
14
18
|
}
|
|
15
19
|
//#endregion
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"node-views.js","names":[],"sources":["../../../src/features/composites/node-views.ts"],"sourcesContent":["import type { NodeViewRenderer } from '@tiptap/core'\nimport { CompositeNode, CompositeTagsNode } from './nodes'\n\n/** The node view
|
|
1
|
+
{"version":3,"file":"node-views.js","names":[],"sources":["../../../src/features/composites/node-views.ts"],"sourcesContent":["import type { NodeViewRenderer } from '@tiptap/core'\nimport { CompositeNode, CompositeTagsNode } from './nodes'\nimport { ReferenceNode } from './reference'\n\n/** The node view renderers a framework binding supplies for the composite block and the reference chip. */\nexport interface CompositeNodeViews {\n composite: NodeViewRenderer\n reference: NodeViewRenderer\n}\n\n/**\n * The composite node with the node view of a framework binding, the tags row (data: hidden, `CompositeChrome`\n * shows and edits it, so it needs no node view) and the reference chip. Configure the kinds with `Composite.configure({ kinds: [...defaultCompositeKinds(t), myKind] })`.\n */\nexport function compositeNodes(nodeViews: CompositeNodeViews) {\n return {\n // Explicit return type: the node views import `compositeKindsOf`, so inference would otherwise be circular.\n Composite: CompositeNode.extend({\n addNodeView(): NodeViewRenderer {\n return nodeViews.composite\n },\n }),\n CompositeTags: CompositeTagsNode,\n Reference: ReferenceNode.extend({\n addNodeView(): NodeViewRenderer {\n return nodeViews.reference\n },\n }),\n }\n}\n"],"mappings":";;;;;;;AAcA,SAAgB,eAAe,WAA+B;CAC5D,OAAO;EAEL,WAAW,cAAc,OAAO,EAC9B,cAAgC;GAC9B,OAAO,UAAU;EACnB,EACF,CAAC;EACD,eAAe;EACf,WAAW,cAAc,OAAO,EAC9B,cAAgC;GAC9B,OAAO,UAAU;EACnB,EACF,CAAC;CACH;AACF"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { Store } from "../../core/store.js";
|
|
1
2
|
import { HeadingConversionScope } from "../../settings/values.js";
|
|
2
3
|
import "../../settings/index.js";
|
|
3
4
|
import { CompositeKind } from "./kinds.js";
|
|
@@ -10,6 +11,8 @@ export interface CompositeOptions {
|
|
|
10
11
|
/** Storage of the `composite` node: mirrors `options.kinds` for code that only has the editor. */
|
|
11
12
|
export interface CompositeStorage {
|
|
12
13
|
kinds: readonly CompositeKind[];
|
|
14
|
+
/** Ids of the derived Bausteine (those with a `meta.derivation`) the user opened; every other derived Baustein shows collapsed. */
|
|
15
|
+
expanded: Store<ReadonlySet<string>>;
|
|
13
16
|
}
|
|
14
17
|
declare module '@tiptap/core' {
|
|
15
18
|
interface Commands<ReturnType> {
|
|
@@ -31,8 +34,10 @@ declare module '@tiptap/core' {
|
|
|
31
34
|
recursive: boolean;
|
|
32
35
|
scope: HeadingConversionScope;
|
|
33
36
|
}) => ReturnType;
|
|
34
|
-
/** Switch the composite at `pos` (default: the caret's innermost composite) to `kind`; `meta` keeps
|
|
37
|
+
/** Switch the composite at `pos` (default: the caret's innermost composite) to `kind`; `meta` keeps the target kind's fields plus `derivation` and `bib`. */
|
|
35
38
|
setCompositeKind: (kind: string, pos?: number) => ReturnType;
|
|
39
|
+
/** Open the derived Baustein with block id `id` if it is collapsed, collapse it if it is open. */
|
|
40
|
+
toggleCompositeExpanded: (id: string) => ReturnType;
|
|
36
41
|
};
|
|
37
42
|
}
|
|
38
43
|
interface Storage {
|
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
import { ABILITY, TEXT_ABILITIES } from "../../core/schema/abilities.js";
|
|
2
|
-
import { isChromeNode } from "../../core/schema/node-flags.js";
|
|
3
2
|
import { editorEntryOf } from "../../core/editor-ui.js";
|
|
3
|
+
import { isChromeNode } from "../../core/schema/node-flags.js";
|
|
4
|
+
import { createStore } from "../../core/store.js";
|
|
4
5
|
import { compositeKind, defaultCompositeKinds, fallbackCompositeKinds } from "./kinds.js";
|
|
5
|
-
import {
|
|
6
|
+
import { keptMeta } from "./meta-keys.js";
|
|
7
|
+
import { compositeFence, withReferencedFenceIds } from "./fences.js";
|
|
8
|
+
import { derivationOf } from "./derivation.js";
|
|
6
9
|
import { flattenCompositesToHeadings, groupHeadingsIntoComposites, headingGroupRange } from "./heading-composites.js";
|
|
7
10
|
import { Node, mergeAttributes } from "@tiptap/core";
|
|
8
11
|
import { Selection, TextSelection } from "@tiptap/pm/state";
|
|
@@ -193,12 +196,28 @@ const CompositeNode = Node.create({
|
|
|
193
196
|
ABILITY.compositeMeta,
|
|
194
197
|
ABILITY.compositeSummarize,
|
|
195
198
|
ABILITY.compositeExport,
|
|
196
|
-
ABILITY.
|
|
199
|
+
ABILITY.compositeDerive
|
|
197
200
|
] },
|
|
198
201
|
addOptions: () => ({ kinds: fallbackCompositeKinds() }),
|
|
199
202
|
addStorage() {
|
|
200
|
-
return {
|
|
203
|
+
return {
|
|
204
|
+
kinds: this.options.kinds,
|
|
205
|
+
expanded: createStore(/* @__PURE__ */ new Set())
|
|
206
|
+
};
|
|
201
207
|
},
|
|
208
|
+
onSelectionUpdate() {
|
|
209
|
+
const { expanded } = this.storage;
|
|
210
|
+
const { $head } = this.editor.state.selection;
|
|
211
|
+
let open = null;
|
|
212
|
+
for (let depth = $head.depth; depth > 0; depth--) {
|
|
213
|
+
const node = $head.node(depth);
|
|
214
|
+
const id = node.attrs.id;
|
|
215
|
+
if (node.type.name !== COMPOSITE || typeof id !== "string" || !id || $head.index(depth) < CHROME_COUNT) continue;
|
|
216
|
+
if (derivationOf(node) && !expanded.get().has(id)) (open ??= new Set(expanded.get())).add(id);
|
|
217
|
+
}
|
|
218
|
+
if (open) expanded.set(open);
|
|
219
|
+
},
|
|
220
|
+
markdownPrepare: (json, editor) => withReferencedFenceIds(json, compositeKindsOf(editor)),
|
|
202
221
|
addAttributes: () => ({
|
|
203
222
|
kind: {
|
|
204
223
|
default: DEFAULT_KIND,
|
|
@@ -228,10 +247,18 @@ const CompositeNode = Node.create({
|
|
|
228
247
|
const kind = typeof node.attrs?.kind === "string" && node.attrs.kind ? node.attrs.kind : DEFAULT_KIND;
|
|
229
248
|
const meta = node.attrs?.meta;
|
|
230
249
|
const body = (node.content ?? []).map((child, index) => h.renderChild?.(child, index) ?? h.renderChildren([child])).filter(Boolean).join("\n\n");
|
|
231
|
-
|
|
250
|
+
const id = node.attrs?.id;
|
|
251
|
+
return compositeFence(kind, meta && typeof meta === "object" ? meta : {}, body, typeof id === "string" && id ? id : void 0);
|
|
232
252
|
},
|
|
233
253
|
addCommands() {
|
|
234
254
|
return {
|
|
255
|
+
toggleCompositeExpanded: (id) => () => {
|
|
256
|
+
const { expanded } = this.storage;
|
|
257
|
+
const next = new Set(expanded.get());
|
|
258
|
+
if (!next.delete(id)) next.add(id);
|
|
259
|
+
expanded.set(next);
|
|
260
|
+
return true;
|
|
261
|
+
},
|
|
235
262
|
insertComposite: (kind = DEFAULT_KIND) => ({ state, tr, dispatch }) => {
|
|
236
263
|
const { $head } = state.selection;
|
|
237
264
|
let depth = $head.depth;
|
|
@@ -278,8 +305,7 @@ const CompositeNode = Node.create({
|
|
|
278
305
|
const found = compositeAt(state, pos);
|
|
279
306
|
if (!found) return false;
|
|
280
307
|
if (dispatch) {
|
|
281
|
-
const
|
|
282
|
-
const meta = Object.fromEntries(Object.entries(found.node.attrs.meta).filter(([key]) => keys.has(key)));
|
|
308
|
+
const meta = keptMeta(compositeKind(this.options.kinds, kind), found.node.attrs.meta);
|
|
283
309
|
tr.setNodeMarkup(found.pos, void 0, {
|
|
284
310
|
...found.node.attrs,
|
|
285
311
|
kind,
|