@ecsplico/editor 2.1.2 → 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 +68 -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/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/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 +1 -1
- package/dist/features/block-ui/block-actions.js +1 -1
- package/dist/features/block-ui/block-actions.js.map +1 -1
- 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/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 +6 -5
- 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 +2 -2
- package/dist/tree/tree-items.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 +28 -8
- 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 +7 -7
- 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 -632
- package/docs/llms.md +0 -383
- package/docs/usage.md +0 -1076
|
@@ -1,15 +1,20 @@
|
|
|
1
|
+
import { CSL_TYPES, CslDate, CslItem, CslName, CslType } from "../../core/backend-types.js";
|
|
1
2
|
import { CompositeAiBrief, compositeAiBrief } from "./ai-brief.js";
|
|
2
|
-
import { CompositeKind, CompositeKindAi, CompositeMetaField, compositeKind, defaultCompositeKinds, kindAccepts } from "./kinds.js";
|
|
3
|
-
import { CompositeMention, CompositeRow, compositeDescriptionText, compositeMetaWith, compositeOfRow, compositeRowAt, compositeRows, setCompositeDescription, setCompositeMetaField, setCompositeTags } from "./rows.js";
|
|
3
|
+
import { CompositeKind, CompositeKindAi, CompositeMetaField, SOURCE_MEDIA_TYPES, compositeKind, defaultCompositeKinds, kindAccepts } from "./kinds.js";
|
|
4
|
+
import { CompositeBacklink, CompositeMention, CompositeReference, CompositeRow, compositeBacklinks, compositeDescriptionText, compositeMetaWith, compositeOfRow, compositeRowAt, compositeRows, setCompositeDescription, setCompositeMetaField, setCompositeTags } from "./rows.js";
|
|
4
5
|
import { CompositeAnchor, CompositeAnchorsHandle, CompositeFrame, compositeSectionOf, observeCompositeAnchors } from "./anchors.js";
|
|
5
6
|
import { COMPOSITE_CHROME_COUNT, CompositeDescriptionNode, CompositeNode, CompositeOptions, CompositeStorage, CompositeTagsNode, CompositeTitleNode, compositeJSON, compositeKindsOf } from "./nodes.js";
|
|
7
|
+
import { REFERENCE_NODE, ReferenceAttrs, ReferenceNode, ReferenceOptions, ReferenceSuggestionPluginKey, referenceMarkdown } from "./reference.js";
|
|
6
8
|
import { CompositeNodeViews, compositeNodes } from "./node-views.js";
|
|
7
9
|
import { CompositeFeatureOptions, CompositesUi, compositeFeatureCore } from "./feature.js";
|
|
8
10
|
import { documentCompositeMarkdown, headingsMarkdown, markdownFileName } from "./markdown-export.js";
|
|
9
11
|
import { MoveVerdict, OutlineNode, canMoveBlockInto, compositeOutline, moveBlockInto, moveIntoVerdict } from "./outline.js";
|
|
12
|
+
import { SourceLocator, SourceReveal, parseLocator, revealSource, seekSource } from "./reveal-source.js";
|
|
10
13
|
import { AcceptedChildren, AcceptedChildrenOptions } from "./accepted-children.js";
|
|
11
14
|
import { CompositeKindCount, CompositeRowsHandle, CompositeRowsState, createCompositeRows } from "./rows-model.js";
|
|
12
15
|
import { CompositeInspector, CompositeInspectorSection, CompositeInspectorState, CompositeKindOption, compositeFieldText, createCompositeInspector } from "./inspector-model.js";
|
|
16
|
+
import { ReferenceTarget, referenceLabel, referenceTarget, referenceTitle } from "./reference-label.js";
|
|
17
|
+
import { referenceSuggestion } from "./reference-suggestion.js";
|
|
13
18
|
import { Structure, StructureStorage, structureOf } from "./structure.js";
|
|
14
19
|
import { STRUCTURE_MODE_KEYS } from "./structure-mode.js";
|
|
15
20
|
import { TREE_ROOT_KEYS } from "./tree-root.js";
|
|
@@ -17,6 +22,10 @@ import { compositeConversions, convertCompositeBlocks } from "./convert.js";
|
|
|
17
22
|
import { CompositeFence, FenceSegment, splitCompositeFences } from "../../core/fences.js";
|
|
18
23
|
import { blocksFromMarkdown, compositeFence, compositeFromMarkdown } from "./fences.js";
|
|
19
24
|
import { compositeChromeBlocks, flattenCompositesToHeadings, groupHeadingsIntoComposites, headingGroupRange, structureBlocks } from "./heading-composites.js";
|
|
25
|
+
import { BIB_KEY, DERIVATION_KEY } from "./meta-keys.js";
|
|
26
|
+
import { bibOf, bibtexOf, citeFull, citeShort, cslOf, cslTypeOptions, yearOf } from "./bibliography.js";
|
|
27
|
+
import { Derivation, DerivationMethod, DerivationSource, bodyMarkdown, derivationOf, derivationState, renditionsOf, sourceOf } from "./derivation.js";
|
|
20
28
|
import { LEGACY_COMPOSITE_NODE, migrateLegacyContent } from "./legacy.js";
|
|
29
|
+
import { normalizeReferences, referencesFromText } from "./reference-text.js";
|
|
21
30
|
import { compositeSchemaExtensions } from "./schema.js";
|
|
22
|
-
export { AcceptedChildren, type AcceptedChildrenOptions, COMPOSITE_CHROME_COUNT, type CompositeAiBrief, type CompositeAnchor, type CompositeAnchorsHandle, CompositeDescriptionNode, type CompositeFeatureOptions, type CompositeFence, type CompositeFrame, type CompositeInspector, type CompositeInspectorSection, type CompositeInspectorState, type CompositeKind, type CompositeKindAi, type CompositeKindCount, type CompositeKindOption, type CompositeMention, type CompositeMetaField, CompositeNode, type CompositeNodeViews, type CompositeOptions, type CompositeRow, type CompositeRowsHandle, type CompositeRowsState, type CompositeStorage, CompositeTagsNode, CompositeTitleNode, type CompositesUi, type FenceSegment, LEGACY_COMPOSITE_NODE, type MoveVerdict, type OutlineNode, STRUCTURE_MODE_KEYS, Structure, type StructureStorage, TREE_ROOT_KEYS, blocksFromMarkdown, canMoveBlockInto, compositeAiBrief, compositeChromeBlocks, compositeConversions, compositeDescriptionText, compositeFeatureCore, compositeFence, compositeFieldText, compositeFromMarkdown, compositeJSON, compositeKind, compositeKindsOf, compositeMetaWith, compositeNodes, compositeOfRow, compositeOutline, compositeRowAt, compositeRows, compositeSchemaExtensions, compositeSectionOf, convertCompositeBlocks, createCompositeInspector, createCompositeRows, defaultCompositeKinds, documentCompositeMarkdown, flattenCompositesToHeadings, groupHeadingsIntoComposites, headingGroupRange, headingsMarkdown, kindAccepts, markdownFileName, migrateLegacyContent, moveBlockInto, moveIntoVerdict, observeCompositeAnchors, setCompositeDescription, setCompositeMetaField, setCompositeTags, splitCompositeFences, structureBlocks as structureCompositeBlocks, structureOf };
|
|
31
|
+
export { AcceptedChildren, type AcceptedChildrenOptions, BIB_KEY, COMPOSITE_CHROME_COUNT, CSL_TYPES, type CompositeAiBrief, type CompositeAnchor, type CompositeAnchorsHandle, type CompositeBacklink, CompositeDescriptionNode, type CompositeFeatureOptions, type CompositeFence, type CompositeFrame, type CompositeInspector, type CompositeInspectorSection, type CompositeInspectorState, type CompositeKind, type CompositeKindAi, type CompositeKindCount, type CompositeKindOption, type CompositeMention, type CompositeMetaField, CompositeNode, type CompositeNodeViews, type CompositeOptions, type CompositeReference, type CompositeRow, type CompositeRowsHandle, type CompositeRowsState, type CompositeStorage, CompositeTagsNode, CompositeTitleNode, type CompositesUi, type CslDate, type CslItem, type CslName, type CslType, DERIVATION_KEY, type Derivation, type DerivationMethod, type DerivationSource, type FenceSegment, LEGACY_COMPOSITE_NODE, type MoveVerdict, type OutlineNode, REFERENCE_NODE, type ReferenceAttrs, ReferenceNode, type ReferenceOptions, ReferenceSuggestionPluginKey, type ReferenceTarget, SOURCE_MEDIA_TYPES, STRUCTURE_MODE_KEYS, type SourceLocator, SourceReveal, Structure, type StructureStorage, TREE_ROOT_KEYS, bibOf, bibtexOf, blocksFromMarkdown, bodyMarkdown, canMoveBlockInto, citeFull, citeShort, compositeAiBrief, compositeBacklinks, compositeChromeBlocks, compositeConversions, compositeDescriptionText, compositeFeatureCore, compositeFence, compositeFieldText, compositeFromMarkdown, compositeJSON, compositeKind, compositeKindsOf, compositeMetaWith, compositeNodes, compositeOfRow, compositeOutline, compositeRowAt, compositeRows, compositeSchemaExtensions, compositeSectionOf, convertCompositeBlocks, createCompositeInspector, createCompositeRows, cslOf, cslTypeOptions, defaultCompositeKinds, derivationOf, derivationState, documentCompositeMarkdown, flattenCompositesToHeadings, groupHeadingsIntoComposites, headingGroupRange, headingsMarkdown, kindAccepts, markdownFileName, migrateLegacyContent, moveBlockInto, moveIntoVerdict, normalizeReferences, observeCompositeAnchors, parseLocator, referenceLabel, referenceMarkdown, referenceSuggestion, referenceTarget, referenceTitle, referencesFromText, renditionsOf, revealSource, seekSource, setCompositeDescription, setCompositeMetaField, setCompositeTags, sourceOf, splitCompositeFences, structureBlocks as structureCompositeBlocks, structureOf, yearOf };
|
|
@@ -1,22 +1,31 @@
|
|
|
1
1
|
import { splitCompositeFences } from "../../core/fences.js";
|
|
2
|
-
import { compositeKind, defaultCompositeKinds, kindAccepts } from "./kinds.js";
|
|
2
|
+
import { SOURCE_MEDIA_TYPES, compositeKind, defaultCompositeKinds, kindAccepts } from "./kinds.js";
|
|
3
|
+
import { BIB_KEY, DERIVATION_KEY } from "./meta-keys.js";
|
|
3
4
|
import { blocksFromMarkdown, compositeFence, compositeFromMarkdown } from "./fences.js";
|
|
5
|
+
import { bodyMarkdown, derivationOf, derivationState, renditionsOf, sourceOf } from "./derivation.js";
|
|
4
6
|
import { compositeChromeBlocks, flattenCompositesToHeadings, groupHeadingsIntoComposites, headingGroupRange, structureBlocks } from "./heading-composites.js";
|
|
5
7
|
import { COMPOSITE_CHROME_COUNT, CompositeDescriptionNode, CompositeNode, CompositeTagsNode, CompositeTitleNode, compositeJSON, compositeKindsOf } from "./nodes.js";
|
|
8
|
+
import { REFERENCE_NODE, ReferenceNode, ReferenceSuggestionPluginKey, referenceMarkdown } from "./reference.js";
|
|
9
|
+
import { CSL_TYPES } from "../../core/backend-types.js";
|
|
10
|
+
import { bibOf, bibtexOf, citeFull, citeShort, cslOf, cslTypeOptions, yearOf } from "./bibliography.js";
|
|
6
11
|
import { compositeAiBrief } from "./ai-brief.js";
|
|
7
12
|
import { compositeConversions, convertCompositeBlocks } from "./convert.js";
|
|
8
13
|
import { LEGACY_COMPOSITE_NODE, migrateLegacyContent } from "./legacy.js";
|
|
14
|
+
import { normalizeReferences, referencesFromText } from "./reference-text.js";
|
|
9
15
|
import { compositeSchemaExtensions } from "./schema.js";
|
|
10
|
-
import { compositeDescriptionText, compositeMetaWith, compositeOfRow, compositeRowAt, compositeRows, setCompositeDescription, setCompositeMetaField, setCompositeTags } from "./rows.js";
|
|
11
|
-
import { compositeSectionOf, observeCompositeAnchors } from "./anchors.js";
|
|
12
16
|
import { AcceptedChildren } from "./accepted-children.js";
|
|
13
17
|
import { documentCompositeMarkdown, headingsMarkdown, markdownFileName } from "./markdown-export.js";
|
|
14
18
|
import { compositeNodes } from "./node-views.js";
|
|
19
|
+
import { referenceLabel, referenceTarget, referenceTitle } from "./reference-label.js";
|
|
20
|
+
import { compositeBacklinks, compositeDescriptionText, compositeMetaWith, compositeOfRow, compositeRowAt, compositeRows, setCompositeDescription, setCompositeMetaField, setCompositeTags } from "./rows.js";
|
|
21
|
+
import { referenceSuggestion } from "./reference-suggestion.js";
|
|
22
|
+
import { SourceReveal, parseLocator, revealSource, seekSource } from "./reveal-source.js";
|
|
15
23
|
import { Structure, structureOf } from "./structure.js";
|
|
16
24
|
import { STRUCTURE_MODE_KEYS } from "./structure-mode.js";
|
|
17
25
|
import { compositeFeatureCore } from "./feature.js";
|
|
18
|
-
import {
|
|
26
|
+
import { compositeSectionOf, observeCompositeAnchors } from "./anchors.js";
|
|
19
27
|
import { createCompositeRows } from "./rows-model.js";
|
|
20
|
-
import { compositeFieldText, createCompositeInspector } from "./inspector-model.js";
|
|
21
28
|
import { TREE_ROOT_KEYS } from "./tree-root.js";
|
|
22
|
-
|
|
29
|
+
import { compositeFieldText, createCompositeInspector } from "./inspector-model.js";
|
|
30
|
+
import { canMoveBlockInto, compositeOutline, moveBlockInto, moveIntoVerdict } from "./outline.js";
|
|
31
|
+
export { AcceptedChildren, BIB_KEY, COMPOSITE_CHROME_COUNT, CSL_TYPES, CompositeDescriptionNode, CompositeNode, CompositeTagsNode, CompositeTitleNode, DERIVATION_KEY, LEGACY_COMPOSITE_NODE, REFERENCE_NODE, ReferenceNode, ReferenceSuggestionPluginKey, SOURCE_MEDIA_TYPES, STRUCTURE_MODE_KEYS, SourceReveal, Structure, TREE_ROOT_KEYS, bibOf, bibtexOf, blocksFromMarkdown, bodyMarkdown, canMoveBlockInto, citeFull, citeShort, compositeAiBrief, compositeBacklinks, compositeChromeBlocks, compositeConversions, compositeDescriptionText, compositeFeatureCore, compositeFence, compositeFieldText, compositeFromMarkdown, compositeJSON, compositeKind, compositeKindsOf, compositeMetaWith, compositeNodes, compositeOfRow, compositeOutline, compositeRowAt, compositeRows, compositeSchemaExtensions, compositeSectionOf, convertCompositeBlocks, createCompositeInspector, createCompositeRows, cslOf, cslTypeOptions, defaultCompositeKinds, derivationOf, derivationState, documentCompositeMarkdown, flattenCompositesToHeadings, groupHeadingsIntoComposites, headingGroupRange, headingsMarkdown, kindAccepts, markdownFileName, migrateLegacyContent, moveBlockInto, moveIntoVerdict, normalizeReferences, observeCompositeAnchors, parseLocator, referenceLabel, referenceMarkdown, referenceSuggestion, referenceTarget, referenceTitle, referencesFromText, renditionsOf, revealSource, seekSource, setCompositeDescription, setCompositeMetaField, setCompositeTags, sourceOf, splitCompositeFences, structureBlocks as structureCompositeBlocks, structureOf, yearOf };
|
|
@@ -60,7 +60,10 @@ export interface CompositeInspector {
|
|
|
60
60
|
setSearchTerm: (term: string) => void;
|
|
61
61
|
/** Schedules a tag search for the current term (the picker opened). */
|
|
62
62
|
searchTags: () => void;
|
|
63
|
-
/**
|
|
63
|
+
/**
|
|
64
|
+
* Writes the text `value` to the meta `field` of the focused Baustein; ignored while the editor is not editable and
|
|
65
|
+
* for structured fields (`isStructuredField`), whose values are not text and have their own editors.
|
|
66
|
+
*/
|
|
64
67
|
setField: (field: CompositeMetaField, value: unknown) => void;
|
|
65
68
|
/** Commits a pending description draft and detaches from the editor. Idempotent; the model is inert afterwards. */
|
|
66
69
|
dispose: () => void;
|
|
@@ -1,15 +1,19 @@
|
|
|
1
|
-
import { createStore } from "../../core/store.js";
|
|
2
1
|
import { metadataOf } from "../../core/metadata.js";
|
|
2
|
+
import { createStore } from "../../core/store.js";
|
|
3
3
|
import { METADATA_LIST } from "../../core/metadata-types.js";
|
|
4
|
+
import { normalizeTagName } from "../../core/tag-name.js";
|
|
4
5
|
import { compositeKindsOf } from "./nodes.js";
|
|
5
6
|
import { compositeDescriptionText, compositeOfRow, setCompositeDescription, setCompositeMetaField, setCompositeTags } from "./rows.js";
|
|
6
|
-
import { normalizeTagName } from "../../core/tag-name.js";
|
|
7
7
|
import { createCompositeRows } from "./rows-model.js";
|
|
8
8
|
//#region src/features/composites/inspector-model.ts
|
|
9
9
|
/** Pause after the last keystroke in the description before the draft is written to the document. */
|
|
10
10
|
const COMMIT_DELAY_MS = 600;
|
|
11
11
|
/** Pause after the last change of the tag search term before the metadata source is asked. */
|
|
12
12
|
const SEARCH_DELAY_MS = 150;
|
|
13
|
+
/** Fields whose value is not text (a block ID, a CSL item, a provenance record): the inspector hands them to `CompositeFieldEditor` and never writes a string to them. */
|
|
14
|
+
function isStructuredField(field) {
|
|
15
|
+
return field.type === "reference" || field.type === "bibliography" || field.type === "derivation";
|
|
16
|
+
}
|
|
13
17
|
/** The text of `field` in `row`'s meta as an input shows it: strings and numbers, otherwise empty. */
|
|
14
18
|
function compositeFieldText(row, field) {
|
|
15
19
|
const value = row?.meta[field.key];
|
|
@@ -232,7 +236,7 @@ function createCompositeInspector(editor) {
|
|
|
232
236
|
},
|
|
233
237
|
setField(field, value) {
|
|
234
238
|
const row = focusedRow();
|
|
235
|
-
if (editor && isEditable() && row) setCompositeMetaField(editor, row, field.key, value);
|
|
239
|
+
if (editor && isEditable() && row && !isStructuredField(field)) setCompositeMetaField(editor, row, field.key, value);
|
|
236
240
|
},
|
|
237
241
|
dispose() {
|
|
238
242
|
if (disposed) return;
|
|
@@ -250,6 +254,6 @@ function createCompositeInspector(editor) {
|
|
|
250
254
|
};
|
|
251
255
|
}
|
|
252
256
|
//#endregion
|
|
253
|
-
export { compositeFieldText, createCompositeInspector };
|
|
257
|
+
export { compositeFieldText, createCompositeInspector, isStructuredField };
|
|
254
258
|
|
|
255
259
|
//# sourceMappingURL=inspector-model.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"inspector-model.js","names":[],"sources":["../../../src/features/composites/inspector-model.ts"],"sourcesContent":["import type { Editor } from '@tiptap/core'\nimport { metadataOf } from '../../core/metadata'\nimport { METADATA_LIST } from '../../core/metadata-types'\nimport { createStore, type ReadonlyStore } from '../../core/store'\nimport { normalizeTagName } from '../../core/tag-name'\nimport type { CompositeMetaField } from './kinds'\nimport { compositeKindsOf } from './nodes'\nimport { compositeDescriptionText, compositeOfRow, type CompositeRow, setCompositeDescription, setCompositeMetaField, setCompositeTags } from './rows'\nimport { type CompositeRowsState, createCompositeRows } from './rows-model'\n\n/** Pause after the last keystroke in the description before the draft is written to the document. */\nconst COMMIT_DELAY_MS = 600\n/** Pause after the last change of the tag search term before the metadata source is asked. */\nconst SEARCH_DELAY_MS = 150\n\n/** Which section of the inspector shows: the document's facts, or the properties of the Baustein under the caret. */\nexport type CompositeInspectorSection = 'document' | 'composite'\n\n/** A kind the Baustein can be switched to, as the kind select lists it. */\nexport interface CompositeKindOption {\n value: string\n label: string\n icon: string\n}\n\n/** Everything the inspector renders (see `createCompositeInspector`): the live rows plus the inspector's own state. */\nexport interface CompositeInspectorState extends CompositeRowsState {\n /** `'composite'` only while the caret last was in the editor and a Baustein is focused, else `'document'`. */\n section: CompositeInspectorSection\n /** Whether the editor accepts edits; follows `setEditable` (see `createCompositeInspector`). */\n editable: boolean\n /** The description text as the user sees it in the focused Baustein's textarea; may be ahead of the document until it is committed. */\n draft: string\n /** The text typed into the tag search. */\n searchTerm: string\n /** Tag names the metadata source suggested for the latest search that was not superseded. */\n tagItems: string[]\n /** The kinds the editor was configured with, in configured order; empty without an editor. */\n kindOptions: CompositeKindOption[]\n /** How many Bausteine have a description. */\n summarized: number\n /** The focused Baustein has a description. */\n hasSummary: boolean\n}\n\n/** The inspector model of an editor: observable `state`, the actions of the panel, and `dispose()`. */\nexport interface CompositeInspector {\n readonly state: ReadonlyStore<CompositeInspectorState>\n /**\n * Reports whether the host's document-level input (its title field) has the focus. Only the rising edge switches\n * the section to `'document'`; the section stays there after the input blurs, until the editor takes the focus.\n */\n setDocumentFocused: (focused: boolean) => void\n /** Switches the focused Baustein to `kind`; ignored when it already has it or no Baustein is focused. */\n setKind: (kind: string) => void\n /**\n * The user typed `text` into the description. The draft is written to the document 600 ms after the last call and\n * on `blurDescription`; the Baustein focused at the first call of a pending draft is the one that is written.\n */\n inputDescription: (text: string) => void\n /**\n * The description textarea lost focus: writes the pending draft, then shows what the document holds. The draft\n * shows the normalized text after a write; after a refused write (a peer changed the description since the draft\n * started) it shows the peer's text.\n */\n blurDescription: () => void\n /** Replaces the tags of the focused Baustein. */\n setTags: (tags: readonly string[]) => void\n /** Creates the tag `raw` (normalized) on the focused Baustein and registers it with the metadata source; clears the search term. */\n createTag: (raw: string) => void\n /** Sets the tag search term and schedules a search for it. */\n setSearchTerm: (term: string) => void\n /** Schedules a tag search for the current term (the picker opened). */\n searchTags: () => void\n /** Writes `value` to the meta `field` of the focused Baustein; ignored while the editor is not editable. */\n setField: (field: CompositeMetaField, value: unknown) => void\n /** Commits a pending description draft and detaches from the editor. Idempotent; the model is inert afterwards. */\n dispose: () => void\n}\n\n/** The text of `field` in `row`'s meta as an input shows it: strings and numbers, otherwise empty. */\nexport function compositeFieldText(row: Pick<CompositeRow, 'meta'> | null, field: Pick<CompositeMetaField, 'key'>): string {\n const value = row?.meta[field.key]\n return typeof value === 'string' || typeof value === 'number' ? String(value) : ''\n}\n\nfunction sameState(a: CompositeInspectorState, b: CompositeInspectorState): boolean {\n return (Object.keys(a) as (keyof CompositeInspectorState)[]).every(key => Object.is(a[key], b[key]))\n}\n\n/**\n * The properties panel of `editor`: which section shows, the focused Baustein's description draft, the tag search\n * and the writes. Owns its own `createCompositeRows(editor)`, so a focus change and the rows it refers to arrive in\n * one notification and the draft is committed before it is replaced. Create one model per editor (a framework hook\n * follows an editor that changes); without an editor the state is empty and every action is ignored.\n *\n * Section: the caret is either in the host's input (`setDocumentFocused`) or in the editor. Only the editor's `focus`\n * event moves it to the editor (not `selectionUpdate`: collaboration sync moves the selection while the host's input\n * has the focus). A deleted Baustein falls back to the document section.\n *\n * `isEditable` is not reactive: `editable` follows it on every editor `transaction`, so whoever calls `setEditable`\n * must dispatch a transaction afterwards (`EditorSurface` does).\n *\n * Description: edits go to a local `draft` so the asynchronous re-read of the document never overwrites the text\n * (and moves the caret) while it is typed. `base` is the document text the draft started from; the write lands only\n * while the description still holds it, so a peer's change made meanwhile is never replaced. The draft is committed\n * 600 ms after typing pauses, on blur, when another Baustein takes the focus (before the draft is replaced), when\n * the panel leaves the Baustein section, and on `dispose()`. A commit is skipped when the editor is destroyed or not\n * editable, and refused when a peer changed the description; the draft then reloads the live text. A draft that is\n * not dirty follows every change of the focused description.\n *\n * Tag search: each term change restarts a 150 ms debounce; when it fires, the previous search is aborted and the\n * source is asked with a fresh `AbortSignal`. Results of aborted searches are dropped, errors of aborted searches\n * are silent, other errors are logged and keep the old suggestions.\n */\nexport function createCompositeInspector(editor: Editor | undefined): CompositeInspector {\n const rows = createCompositeRows(editor)\n const kindOptions: CompositeKindOption[] = editor && !editor.isDestroyed\n ? compositeKindsOf(editor).map(kind => ({ value: kind.id, label: kind.label, icon: kind.icon }))\n : []\n const isEditable = () => !!editor && !editor.isDestroyed && editor.isEditable\n const focusedRow = () => rows.state.get().focused\n\n let disposed = false\n\n // --- Section ---\n let caretIn: 'document' | 'editor' = 'document'\n let documentFocused = false\n let section: CompositeInspectorSection = 'document'\n let editable = isEditable()\n\n // --- Description draft ---\n let draft = ''\n let base = ''\n let dirty = false\n let pendingRow: CompositeRow | null = null\n let commitTimer: ReturnType<typeof setTimeout> | undefined\n // What the focused Baustein looked like at the last rows notification: a change of the key is a switch, a change of the description a peer's (or our own) write.\n let focusKey = focusedRow()?.key\n let focusDescription = focusedRow()?.description\n\n // --- Tag search ---\n let searchTerm = ''\n let tagItems: string[] = []\n let searchTimer: ReturnType<typeof setTimeout> | undefined\n let pendingSearch: AbortController | undefined\n\n let summarizedRows: CompositeRowsState['rows'] | undefined\n let summarized = 0\n const store = createStore<CompositeInspectorState>(snapshot())\n\n function snapshot(): CompositeInspectorState {\n const read = rows.state.get()\n if (read.rows !== summarizedRows) {\n summarizedRows = read.rows\n summarized = read.rows.filter(row => row.description.trim()).length\n }\n return {\n ...read,\n section,\n editable,\n draft,\n searchTerm,\n tagItems,\n kindOptions,\n summarized,\n hasSummary: !!read.focused?.description.trim(),\n }\n }\n\n function publish() {\n const next = snapshot()\n if (!sameState(store.get(), next)) store.set(next)\n }\n\n function load() {\n dirty = false\n pendingRow = null\n base = focusedRow()?.description ?? ''\n draft = base\n }\n\n /** Writes the pending draft; `false` when there was nothing to write or the write was refused. Does not touch `draft`. */\n function commit(): boolean {\n clearTimeout(commitTimer)\n if (!dirty || !pendingRow) return false\n dirty = false\n const row = pendingRow\n pendingRow = null\n if (!editor || editor.isDestroyed || !editor.isEditable) return false\n if (!setCompositeDescription(editor, row, draft, base)) return false\n base = compositeDescriptionText(draft)\n return true\n }\n\n function refreshSection() {\n const next = caretIn === 'editor' && focusedRow() ? 'composite' : 'document'\n if (section === 'composite' && next !== 'composite') commit()\n section = next\n }\n\n // A switch commits the draft of the previous Baustein first (`draft` still holds its text), then loads the new one.\n // A change of the description reaches an untouched draft, also while the textarea has focus. A draft with unsaved\n // typing keeps it; if a peer changed the description meanwhile, its commit is refused and the peer's text is\n // loaded instead.\n function followRows() {\n const focused = focusedRow()\n const key = focused?.key\n const description = focused?.description\n if (key !== focusKey) {\n focusKey = key\n focusDescription = description\n commit()\n load()\n }\n else if (description !== focusDescription) {\n focusDescription = description\n if (dirty) {\n if (description !== base && !commit()) load()\n }\n else if (description !== base) {\n load()\n }\n }\n refreshSection()\n publish()\n }\n\n function scheduleSearch() {\n clearTimeout(searchTimer)\n searchTimer = setTimeout(async () => {\n if (!editor || editor.isDestroyed) return\n pendingSearch?.abort()\n const controller = pendingSearch = new AbortController()\n try {\n const found = await metadataOf(editor).search(METADATA_LIST.hashtags, { query: searchTerm, editor, signal: controller.signal })\n if (controller.signal.aborted) return\n tagItems = found.map(item => item.label)\n publish()\n }\n catch (error) {\n if (!controller.signal.aborted) console.warn('Tag-Vorschläge konnten nicht geladen werden', error)\n }\n }, SEARCH_DELAY_MS)\n }\n\n function setSearchTerm(term: string) {\n if (disposed || term === searchTerm) return\n searchTerm = term\n scheduleSearch()\n publish()\n }\n\n const syncEditable = () => {\n const next = isEditable()\n if (next === editable) return\n editable = next\n publish()\n }\n const toEditor = () => {\n caretIn = 'editor'\n refreshSection()\n publish()\n }\n\n load()\n refreshSection()\n const stopRows = rows.state.subscribe(followRows)\n if (editor && !editor.isDestroyed) {\n editor.on('transaction', syncEditable)\n // Only `focus`, not `selectionUpdate`: a collaboration sync can move the selection while the host's input has the focus.\n editor.on('focus', toEditor)\n }\n publish()\n\n return {\n state: store,\n\n setDocumentFocused(focused) {\n if (disposed) return\n const rising = focused && !documentFocused\n documentFocused = focused\n if (!rising) return\n caretIn = 'document'\n refreshSection()\n publish()\n },\n\n setKind(kind) {\n const row = focusedRow()\n const found = editor && row ? compositeOfRow(editor.state.doc, row) : null\n if (!editor || !found || kind === row?.kind) return\n editor.commands.setCompositeKind(kind, found.pos)\n },\n\n inputDescription(text) {\n if (disposed) return\n draft = text\n dirty = true\n pendingRow ??= focusedRow()\n clearTimeout(commitTimer)\n commitTimer = setTimeout(commit, COMMIT_DELAY_MS)\n publish()\n },\n\n blurDescription() {\n if (disposed) return\n if (commit()) draft = base\n else load()\n publish()\n },\n\n setTags(tags) {\n const row = focusedRow()\n if (editor && row) setCompositeTags(editor, row, tags)\n },\n\n // „Neu Tag“ → `neu-tag`. A name that normalizes to an already chosen tag is ignored; only unknown names are reported as created.\n createTag(raw) {\n const row = focusedRow()\n const name = normalizeTagName(raw)\n setSearchTerm('')\n if (!editor || !row || !name || row.tags.includes(name)) return\n setCompositeTags(editor, row, [...row.tags, name])\n if (!tagItems.includes(name)) metadataOf(editor).create(METADATA_LIST.hashtags, { id: name, label: name })\n },\n\n setSearchTerm,\n\n searchTags() {\n if (!disposed) scheduleSearch()\n },\n\n setField(field, value) {\n const row = focusedRow()\n if (editor && isEditable() && row) setCompositeMetaField(editor, row, field.key, value)\n },\n\n dispose() {\n if (disposed) return\n commit()\n disposed = true\n clearTimeout(searchTimer)\n pendingSearch?.abort()\n stopRows()\n if (editor && !editor.isDestroyed) {\n editor.off('transaction', syncEditable)\n editor.off('focus', toEditor)\n }\n rows.dispose()\n },\n }\n}\n"],"mappings":";;;;;;;;;AAWA,MAAM,kBAAkB;;AAExB,MAAM,kBAAkB;;AAoExB,SAAgB,mBAAmB,KAAwC,OAAgD;CACzH,MAAM,QAAQ,KAAK,KAAK,MAAM;CAC9B,OAAO,OAAO,UAAU,YAAY,OAAO,UAAU,WAAW,OAAO,KAAK,IAAI;AAClF;AAEA,SAAS,UAAU,GAA4B,GAAqC;CAClF,OAAQ,OAAO,KAAK,CAAC,CAAC,CAAuC,OAAM,QAAO,OAAO,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC;AACrG;;;;;;;;;;;;;;;;;;;;;;;;;;AA2BA,SAAgB,yBAAyB,QAAgD;CACvF,MAAM,OAAO,oBAAoB,MAAM;CACvC,MAAM,cAAqC,UAAU,CAAC,OAAO,cACzD,iBAAiB,MAAM,CAAC,CAAC,KAAI,UAAS;EAAE,OAAO,KAAK;EAAI,OAAO,KAAK;EAAO,MAAM,KAAK;CAAK,EAAE,IAC7F,CAAC;CACL,MAAM,mBAAmB,CAAC,CAAC,UAAU,CAAC,OAAO,eAAe,OAAO;CACnE,MAAM,mBAAmB,KAAK,MAAM,IAAI,CAAC,CAAC;CAE1C,IAAI,WAAW;CAGf,IAAI,UAAiC;CACrC,IAAI,kBAAkB;CACtB,IAAI,UAAqC;CACzC,IAAI,WAAW,WAAW;CAG1B,IAAI,QAAQ;CACZ,IAAI,OAAO;CACX,IAAI,QAAQ;CACZ,IAAI,aAAkC;CACtC,IAAI;CAEJ,IAAI,WAAW,WAAW,CAAC,EAAE;CAC7B,IAAI,mBAAmB,WAAW,CAAC,EAAE;CAGrC,IAAI,aAAa;CACjB,IAAI,WAAqB,CAAC;CAC1B,IAAI;CACJ,IAAI;CAEJ,IAAI;CACJ,IAAI,aAAa;CACjB,MAAM,QAAQ,YAAqC,SAAS,CAAC;CAE7D,SAAS,WAAoC;EAC3C,MAAM,OAAO,KAAK,MAAM,IAAI;EAC5B,IAAI,KAAK,SAAS,gBAAgB;GAChC,iBAAiB,KAAK;GACtB,aAAa,KAAK,KAAK,QAAO,QAAO,IAAI,YAAY,KAAK,CAAC,CAAC,CAAC;EAC/D;EACA,OAAO;GACL,GAAG;GACH;GACA;GACA;GACA;GACA;GACA;GACA;GACA,YAAY,CAAC,CAAC,KAAK,SAAS,YAAY,KAAK;EAC/C;CACF;CAEA,SAAS,UAAU;EACjB,MAAM,OAAO,SAAS;EACtB,IAAI,CAAC,UAAU,MAAM,IAAI,GAAG,IAAI,GAAG,MAAM,IAAI,IAAI;CACnD;CAEA,SAAS,OAAO;EACd,QAAQ;EACR,aAAa;EACb,OAAO,WAAW,CAAC,EAAE,eAAe;EACpC,QAAQ;CACV;;CAGA,SAAS,SAAkB;EACzB,aAAa,WAAW;EACxB,IAAI,CAAC,SAAS,CAAC,YAAY,OAAO;EAClC,QAAQ;EACR,MAAM,MAAM;EACZ,aAAa;EACb,IAAI,CAAC,UAAU,OAAO,eAAe,CAAC,OAAO,YAAY,OAAO;EAChE,IAAI,CAAC,wBAAwB,QAAQ,KAAK,OAAO,IAAI,GAAG,OAAO;EAC/D,OAAO,yBAAyB,KAAK;EACrC,OAAO;CACT;CAEA,SAAS,iBAAiB;EACxB,MAAM,OAAO,YAAY,YAAY,WAAW,IAAI,cAAc;EAClE,IAAI,YAAY,eAAe,SAAS,aAAa,OAAO;EAC5D,UAAU;CACZ;CAMA,SAAS,aAAa;EACpB,MAAM,UAAU,WAAW;EAC3B,MAAM,MAAM,SAAS;EACrB,MAAM,cAAc,SAAS;EAC7B,IAAI,QAAQ,UAAU;GACpB,WAAW;GACX,mBAAmB;GACnB,OAAO;GACP,KAAK;EACP,OACK,IAAI,gBAAgB,kBAAkB;GACzC,mBAAmB;GACnB,IAAI,OACE;QAAA,gBAAgB,QAAQ,CAAC,OAAO,GAAG,KAAK;GAAA,OAEzC,IAAI,gBAAgB,MACvB,KAAK;EAET;EACA,eAAe;EACf,QAAQ;CACV;CAEA,SAAS,iBAAiB;EACxB,aAAa,WAAW;EACxB,cAAc,WAAW,YAAY;GACnC,IAAI,CAAC,UAAU,OAAO,aAAa;GACnC,eAAe,MAAM;GACrB,MAAM,aAAa,gBAAgB,IAAI,gBAAgB;GACvD,IAAI;IACF,MAAM,QAAQ,MAAM,WAAW,MAAM,CAAC,CAAC,OAAO,cAAc,UAAU;KAAE,OAAO;KAAY;KAAQ,QAAQ,WAAW;IAAO,CAAC;IAC9H,IAAI,WAAW,OAAO,SAAS;IAC/B,WAAW,MAAM,KAAI,SAAQ,KAAK,KAAK;IACvC,QAAQ;GACV,SACO,OAAO;IACZ,IAAI,CAAC,WAAW,OAAO,SAAS,QAAQ,KAAK,+CAA+C,KAAK;GACnG;EACF,GAAG,eAAe;CACpB;CAEA,SAAS,cAAc,MAAc;EACnC,IAAI,YAAY,SAAS,YAAY;EACrC,aAAa;EACb,eAAe;EACf,QAAQ;CACV;CAEA,MAAM,qBAAqB;EACzB,MAAM,OAAO,WAAW;EACxB,IAAI,SAAS,UAAU;EACvB,WAAW;EACX,QAAQ;CACV;CACA,MAAM,iBAAiB;EACrB,UAAU;EACV,eAAe;EACf,QAAQ;CACV;CAEA,KAAK;CACL,eAAe;CACf,MAAM,WAAW,KAAK,MAAM,UAAU,UAAU;CAChD,IAAI,UAAU,CAAC,OAAO,aAAa;EACjC,OAAO,GAAG,eAAe,YAAY;EAErC,OAAO,GAAG,SAAS,QAAQ;CAC7B;CACA,QAAQ;CAER,OAAO;EACL,OAAO;EAEP,mBAAmB,SAAS;GAC1B,IAAI,UAAU;GACd,MAAM,SAAS,WAAW,CAAC;GAC3B,kBAAkB;GAClB,IAAI,CAAC,QAAQ;GACb,UAAU;GACV,eAAe;GACf,QAAQ;EACV;EAEA,QAAQ,MAAM;GACZ,MAAM,MAAM,WAAW;GACvB,MAAM,QAAQ,UAAU,MAAM,eAAe,OAAO,MAAM,KAAK,GAAG,IAAI;GACtE,IAAI,CAAC,UAAU,CAAC,SAAS,SAAS,KAAK,MAAM;GAC7C,OAAO,SAAS,iBAAiB,MAAM,MAAM,GAAG;EAClD;EAEA,iBAAiB,MAAM;GACrB,IAAI,UAAU;GACd,QAAQ;GACR,QAAQ;GACR,eAAe,WAAW;GAC1B,aAAa,WAAW;GACxB,cAAc,WAAW,QAAQ,eAAe;GAChD,QAAQ;EACV;EAEA,kBAAkB;GAChB,IAAI,UAAU;GACd,IAAI,OAAO,GAAG,QAAQ;QACjB,KAAK;GACV,QAAQ;EACV;EAEA,QAAQ,MAAM;GACZ,MAAM,MAAM,WAAW;GACvB,IAAI,UAAU,KAAK,iBAAiB,QAAQ,KAAK,IAAI;EACvD;EAGA,UAAU,KAAK;GACb,MAAM,MAAM,WAAW;GACvB,MAAM,OAAO,iBAAiB,GAAG;GACjC,cAAc,EAAE;GAChB,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,QAAQ,IAAI,KAAK,SAAS,IAAI,GAAG;GACzD,iBAAiB,QAAQ,KAAK,CAAC,GAAG,IAAI,MAAM,IAAI,CAAC;GACjD,IAAI,CAAC,SAAS,SAAS,IAAI,GAAG,WAAW,MAAM,CAAC,CAAC,OAAO,cAAc,UAAU;IAAE,IAAI;IAAM,OAAO;GAAK,CAAC;EAC3G;EAEA;EAEA,aAAa;GACX,IAAI,CAAC,UAAU,eAAe;EAChC;EAEA,SAAS,OAAO,OAAO;GACrB,MAAM,MAAM,WAAW;GACvB,IAAI,UAAU,WAAW,KAAK,KAAK,sBAAsB,QAAQ,KAAK,MAAM,KAAK,KAAK;EACxF;EAEA,UAAU;GACR,IAAI,UAAU;GACd,OAAO;GACP,WAAW;GACX,aAAa,WAAW;GACxB,eAAe,MAAM;GACrB,SAAS;GACT,IAAI,UAAU,CAAC,OAAO,aAAa;IACjC,OAAO,IAAI,eAAe,YAAY;IACtC,OAAO,IAAI,SAAS,QAAQ;GAC9B;GACA,KAAK,QAAQ;EACf;CACF;AACF"}
|
|
1
|
+
{"version":3,"file":"inspector-model.js","names":[],"sources":["../../../src/features/composites/inspector-model.ts"],"sourcesContent":["import type { Editor } from '@tiptap/core'\nimport { metadataOf } from '../../core/metadata'\nimport { METADATA_LIST } from '../../core/metadata-types'\nimport { createStore, type ReadonlyStore } from '../../core/store'\nimport { normalizeTagName } from '../../core/tag-name'\nimport type { CompositeMetaField } from './kinds'\nimport { compositeKindsOf } from './nodes'\nimport { compositeDescriptionText, compositeOfRow, type CompositeRow, setCompositeDescription, setCompositeMetaField, setCompositeTags } from './rows'\nimport { type CompositeRowsState, createCompositeRows } from './rows-model'\n\n/** Pause after the last keystroke in the description before the draft is written to the document. */\nconst COMMIT_DELAY_MS = 600\n/** Pause after the last change of the tag search term before the metadata source is asked. */\nconst SEARCH_DELAY_MS = 150\n\n/** Which section of the inspector shows: the document's facts, or the properties of the Baustein under the caret. */\nexport type CompositeInspectorSection = 'document' | 'composite'\n\n/** A kind the Baustein can be switched to, as the kind select lists it. */\nexport interface CompositeKindOption {\n value: string\n label: string\n icon: string\n}\n\n/** Everything the inspector renders (see `createCompositeInspector`): the live rows plus the inspector's own state. */\nexport interface CompositeInspectorState extends CompositeRowsState {\n /** `'composite'` only while the caret last was in the editor and a Baustein is focused, else `'document'`. */\n section: CompositeInspectorSection\n /** Whether the editor accepts edits; follows `setEditable` (see `createCompositeInspector`). */\n editable: boolean\n /** The description text as the user sees it in the focused Baustein's textarea; may be ahead of the document until it is committed. */\n draft: string\n /** The text typed into the tag search. */\n searchTerm: string\n /** Tag names the metadata source suggested for the latest search that was not superseded. */\n tagItems: string[]\n /** The kinds the editor was configured with, in configured order; empty without an editor. */\n kindOptions: CompositeKindOption[]\n /** How many Bausteine have a description. */\n summarized: number\n /** The focused Baustein has a description. */\n hasSummary: boolean\n}\n\n/** The inspector model of an editor: observable `state`, the actions of the panel, and `dispose()`. */\nexport interface CompositeInspector {\n readonly state: ReadonlyStore<CompositeInspectorState>\n /**\n * Reports whether the host's document-level input (its title field) has the focus. Only the rising edge switches\n * the section to `'document'`; the section stays there after the input blurs, until the editor takes the focus.\n */\n setDocumentFocused: (focused: boolean) => void\n /** Switches the focused Baustein to `kind`; ignored when it already has it or no Baustein is focused. */\n setKind: (kind: string) => void\n /**\n * The user typed `text` into the description. The draft is written to the document 600 ms after the last call and\n * on `blurDescription`; the Baustein focused at the first call of a pending draft is the one that is written.\n */\n inputDescription: (text: string) => void\n /**\n * The description textarea lost focus: writes the pending draft, then shows what the document holds. The draft\n * shows the normalized text after a write; after a refused write (a peer changed the description since the draft\n * started) it shows the peer's text.\n */\n blurDescription: () => void\n /** Replaces the tags of the focused Baustein. */\n setTags: (tags: readonly string[]) => void\n /** Creates the tag `raw` (normalized) on the focused Baustein and registers it with the metadata source; clears the search term. */\n createTag: (raw: string) => void\n /** Sets the tag search term and schedules a search for it. */\n setSearchTerm: (term: string) => void\n /** Schedules a tag search for the current term (the picker opened). */\n searchTags: () => void\n /**\n * Writes the text `value` to the meta `field` of the focused Baustein; ignored while the editor is not editable and\n * for structured fields (`isStructuredField`), whose values are not text and have their own editors.\n */\n setField: (field: CompositeMetaField, value: unknown) => void\n /** Commits a pending description draft and detaches from the editor. Idempotent; the model is inert afterwards. */\n dispose: () => void\n}\n\n/** Fields whose value is not text (a block ID, a CSL item, a provenance record): the inspector hands them to `CompositeFieldEditor` and never writes a string to them. */\nexport function isStructuredField(field: Pick<CompositeMetaField, 'type'>): boolean {\n return field.type === 'reference' || field.type === 'bibliography' || field.type === 'derivation'\n}\n\n/** The text of `field` in `row`'s meta as an input shows it: strings and numbers, otherwise empty. */\nexport function compositeFieldText(row: Pick<CompositeRow, 'meta'> | null, field: Pick<CompositeMetaField, 'key'>): string {\n const value = row?.meta[field.key]\n return typeof value === 'string' || typeof value === 'number' ? String(value) : ''\n}\n\nfunction sameState(a: CompositeInspectorState, b: CompositeInspectorState): boolean {\n return (Object.keys(a) as (keyof CompositeInspectorState)[]).every(key => Object.is(a[key], b[key]))\n}\n\n/**\n * The properties panel of `editor`: which section shows, the focused Baustein's description draft, the tag search\n * and the writes. Owns its own `createCompositeRows(editor)`, so a focus change and the rows it refers to arrive in\n * one notification and the draft is committed before it is replaced. Create one model per editor (a framework hook\n * follows an editor that changes); without an editor the state is empty and every action is ignored.\n *\n * Section: the caret is either in the host's input (`setDocumentFocused`) or in the editor. Only the editor's `focus`\n * event moves it to the editor (not `selectionUpdate`: collaboration sync moves the selection while the host's input\n * has the focus). A deleted Baustein falls back to the document section.\n *\n * `isEditable` is not reactive: `editable` follows it on every editor `transaction`, so whoever calls `setEditable`\n * must dispatch a transaction afterwards (`EditorSurface` does).\n *\n * Description: edits go to a local `draft` so the asynchronous re-read of the document never overwrites the text\n * (and moves the caret) while it is typed. `base` is the document text the draft started from; the write lands only\n * while the description still holds it, so a peer's change made meanwhile is never replaced. The draft is committed\n * 600 ms after typing pauses, on blur, when another Baustein takes the focus (before the draft is replaced), when\n * the panel leaves the Baustein section, and on `dispose()`. A commit is skipped when the editor is destroyed or not\n * editable, and refused when a peer changed the description; the draft then reloads the live text. A draft that is\n * not dirty follows every change of the focused description.\n *\n * Tag search: each term change restarts a 150 ms debounce; when it fires, the previous search is aborted and the\n * source is asked with a fresh `AbortSignal`. Results of aborted searches are dropped, errors of aborted searches\n * are silent, other errors are logged and keep the old suggestions.\n */\nexport function createCompositeInspector(editor: Editor | undefined): CompositeInspector {\n const rows = createCompositeRows(editor)\n const kindOptions: CompositeKindOption[] = editor && !editor.isDestroyed\n ? compositeKindsOf(editor).map(kind => ({ value: kind.id, label: kind.label, icon: kind.icon }))\n : []\n const isEditable = () => !!editor && !editor.isDestroyed && editor.isEditable\n const focusedRow = () => rows.state.get().focused\n\n let disposed = false\n\n // --- Section ---\n let caretIn: 'document' | 'editor' = 'document'\n let documentFocused = false\n let section: CompositeInspectorSection = 'document'\n let editable = isEditable()\n\n // --- Description draft ---\n let draft = ''\n let base = ''\n let dirty = false\n let pendingRow: CompositeRow | null = null\n let commitTimer: ReturnType<typeof setTimeout> | undefined\n // What the focused Baustein looked like at the last rows notification: a change of the key is a switch, a change of the description a peer's (or our own) write.\n let focusKey = focusedRow()?.key\n let focusDescription = focusedRow()?.description\n\n // --- Tag search ---\n let searchTerm = ''\n let tagItems: string[] = []\n let searchTimer: ReturnType<typeof setTimeout> | undefined\n let pendingSearch: AbortController | undefined\n\n let summarizedRows: CompositeRowsState['rows'] | undefined\n let summarized = 0\n const store = createStore<CompositeInspectorState>(snapshot())\n\n function snapshot(): CompositeInspectorState {\n const read = rows.state.get()\n if (read.rows !== summarizedRows) {\n summarizedRows = read.rows\n summarized = read.rows.filter(row => row.description.trim()).length\n }\n return {\n ...read,\n section,\n editable,\n draft,\n searchTerm,\n tagItems,\n kindOptions,\n summarized,\n hasSummary: !!read.focused?.description.trim(),\n }\n }\n\n function publish() {\n const next = snapshot()\n if (!sameState(store.get(), next)) store.set(next)\n }\n\n function load() {\n dirty = false\n pendingRow = null\n base = focusedRow()?.description ?? ''\n draft = base\n }\n\n /** Writes the pending draft; `false` when there was nothing to write or the write was refused. Does not touch `draft`. */\n function commit(): boolean {\n clearTimeout(commitTimer)\n if (!dirty || !pendingRow) return false\n dirty = false\n const row = pendingRow\n pendingRow = null\n if (!editor || editor.isDestroyed || !editor.isEditable) return false\n if (!setCompositeDescription(editor, row, draft, base)) return false\n base = compositeDescriptionText(draft)\n return true\n }\n\n function refreshSection() {\n const next = caretIn === 'editor' && focusedRow() ? 'composite' : 'document'\n if (section === 'composite' && next !== 'composite') commit()\n section = next\n }\n\n // A switch commits the draft of the previous Baustein first (`draft` still holds its text), then loads the new one.\n // A change of the description reaches an untouched draft, also while the textarea has focus. A draft with unsaved\n // typing keeps it; if a peer changed the description meanwhile, its commit is refused and the peer's text is\n // loaded instead.\n function followRows() {\n const focused = focusedRow()\n const key = focused?.key\n const description = focused?.description\n if (key !== focusKey) {\n focusKey = key\n focusDescription = description\n commit()\n load()\n }\n else if (description !== focusDescription) {\n focusDescription = description\n if (dirty) {\n if (description !== base && !commit()) load()\n }\n else if (description !== base) {\n load()\n }\n }\n refreshSection()\n publish()\n }\n\n function scheduleSearch() {\n clearTimeout(searchTimer)\n searchTimer = setTimeout(async () => {\n if (!editor || editor.isDestroyed) return\n pendingSearch?.abort()\n const controller = pendingSearch = new AbortController()\n try {\n const found = await metadataOf(editor).search(METADATA_LIST.hashtags, { query: searchTerm, editor, signal: controller.signal })\n if (controller.signal.aborted) return\n tagItems = found.map(item => item.label)\n publish()\n }\n catch (error) {\n if (!controller.signal.aborted) console.warn('Tag-Vorschläge konnten nicht geladen werden', error)\n }\n }, SEARCH_DELAY_MS)\n }\n\n function setSearchTerm(term: string) {\n if (disposed || term === searchTerm) return\n searchTerm = term\n scheduleSearch()\n publish()\n }\n\n const syncEditable = () => {\n const next = isEditable()\n if (next === editable) return\n editable = next\n publish()\n }\n const toEditor = () => {\n caretIn = 'editor'\n refreshSection()\n publish()\n }\n\n load()\n refreshSection()\n const stopRows = rows.state.subscribe(followRows)\n if (editor && !editor.isDestroyed) {\n editor.on('transaction', syncEditable)\n // Only `focus`, not `selectionUpdate`: a collaboration sync can move the selection while the host's input has the focus.\n editor.on('focus', toEditor)\n }\n publish()\n\n return {\n state: store,\n\n setDocumentFocused(focused) {\n if (disposed) return\n const rising = focused && !documentFocused\n documentFocused = focused\n if (!rising) return\n caretIn = 'document'\n refreshSection()\n publish()\n },\n\n setKind(kind) {\n const row = focusedRow()\n const found = editor && row ? compositeOfRow(editor.state.doc, row) : null\n if (!editor || !found || kind === row?.kind) return\n editor.commands.setCompositeKind(kind, found.pos)\n },\n\n inputDescription(text) {\n if (disposed) return\n draft = text\n dirty = true\n pendingRow ??= focusedRow()\n clearTimeout(commitTimer)\n commitTimer = setTimeout(commit, COMMIT_DELAY_MS)\n publish()\n },\n\n blurDescription() {\n if (disposed) return\n if (commit()) draft = base\n else load()\n publish()\n },\n\n setTags(tags) {\n const row = focusedRow()\n if (editor && row) setCompositeTags(editor, row, tags)\n },\n\n // „Neu Tag“ → `neu-tag`. A name that normalizes to an already chosen tag is ignored; only unknown names are reported as created.\n createTag(raw) {\n const row = focusedRow()\n const name = normalizeTagName(raw)\n setSearchTerm('')\n if (!editor || !row || !name || row.tags.includes(name)) return\n setCompositeTags(editor, row, [...row.tags, name])\n if (!tagItems.includes(name)) metadataOf(editor).create(METADATA_LIST.hashtags, { id: name, label: name })\n },\n\n setSearchTerm,\n\n searchTags() {\n if (!disposed) scheduleSearch()\n },\n\n setField(field, value) {\n const row = focusedRow()\n if (editor && isEditable() && row && !isStructuredField(field)) setCompositeMetaField(editor, row, field.key, value)\n },\n\n dispose() {\n if (disposed) return\n commit()\n disposed = true\n clearTimeout(searchTimer)\n pendingSearch?.abort()\n stopRows()\n if (editor && !editor.isDestroyed) {\n editor.off('transaction', syncEditable)\n editor.off('focus', toEditor)\n }\n rows.dispose()\n },\n }\n}\n"],"mappings":"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"}
|
|
@@ -1,15 +1,20 @@
|
|
|
1
1
|
import { Translate } from "../../i18n/index.js";
|
|
2
2
|
//#region src/features/composites/kinds.d.ts
|
|
3
|
+
/** Media block types a source-holding kind's source may be (`CompositeKind.source`). */
|
|
4
|
+
export declare const SOURCE_MEDIA_TYPES: readonly ["image", "audio", "video", "file"];
|
|
3
5
|
/** One metadata field of a composite kind, stored under `key` in the composite's `meta` attribute. */
|
|
4
6
|
export interface CompositeMetaField {
|
|
5
7
|
key: string;
|
|
6
8
|
label: string;
|
|
7
|
-
|
|
9
|
+
/** `bibliography`: CSL-JSON item under `meta.bib`; `derivation`: read-only provenance of a derived Baustein; `reference`: block id of another Baustein. */
|
|
10
|
+
type: 'text' | 'textarea' | 'date' | 'number' | 'select' | 'reference' | 'bibliography' | 'derivation';
|
|
8
11
|
/** Choices of a `select` field. */
|
|
9
12
|
options?: {
|
|
10
13
|
value: string;
|
|
11
14
|
label: string;
|
|
12
15
|
}[];
|
|
16
|
+
/** `reference`: kind ids the field may point to; absent = any Baustein. */
|
|
17
|
+
targets?: readonly string[];
|
|
13
18
|
}
|
|
14
19
|
/**
|
|
15
20
|
* What a kind tells the model beyond its fields. `purpose` goes into every AI request's block model (chat, generate
|
|
@@ -41,6 +46,8 @@ export interface CompositeKind {
|
|
|
41
46
|
* Only new moves are checked; documents that already nest against it stay as they are.
|
|
42
47
|
*/
|
|
43
48
|
accepts?: readonly string[] | 'all';
|
|
49
|
+
/** 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. */
|
|
50
|
+
source?: readonly (typeof SOURCE_MEDIA_TYPES)[number][];
|
|
44
51
|
}
|
|
45
52
|
/**
|
|
46
53
|
* The built-in kinds in the language of `t`. The default set is produced from the translator (labels, placeholders, field
|
|
@@ -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"}
|