@ecsplico/editor 2.1.1 → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +74 -1
- package/README.md +39 -156
- package/dist/adapters/comments/drizzle.d.ts +1 -1
- package/dist/adapters/comments/{client.js → rest-model.js} +3 -3
- package/dist/adapters/comments/rest-model.js.map +1 -0
- package/dist/adapters/comments/types.d.ts +2 -2
- package/dist/adapters/document-state.d.ts +23 -0
- package/dist/adapters/document-state.js +66 -0
- package/dist/adapters/document-state.js.map +1 -0
- package/dist/adapters/documents.js +14 -11
- package/dist/adapters/documents.js.map +1 -1
- package/dist/adapters/drizzle.d.ts +2 -2
- package/dist/adapters/drizzle.js +97 -88
- package/dist/adapters/drizzle.js.map +1 -1
- package/dist/adapters/forge.d.ts +12 -7
- package/dist/adapters/forge.js +38 -45
- package/dist/adapters/forge.js.map +1 -1
- package/dist/adapters/http.d.ts +20 -0
- package/dist/adapters/http.js +68 -0
- package/dist/adapters/http.js.map +1 -0
- package/dist/adapters/index.d.ts +5 -5
- package/dist/adapters/json.d.ts +3 -3
- package/dist/adapters/json.js +58 -49
- package/dist/adapters/json.js.map +1 -1
- package/dist/adapters/memory.d.ts +21 -0
- package/dist/adapters/memory.js +53 -0
- package/dist/adapters/memory.js.map +1 -0
- package/dist/adapters/nitro.d.ts +23 -20
- package/dist/adapters/nitro.js +58 -163
- package/dist/adapters/nitro.js.map +1 -1
- package/dist/adapters/react.d.ts +55 -0
- package/dist/adapters/react.js +209 -0
- package/dist/adapters/react.js.map +1 -0
- package/dist/adapters/shared.d.ts +15 -21
- package/dist/adapters/shared.js +10 -8
- package/dist/adapters/shared.js.map +1 -1
- package/dist/adapters/vue.d.ts +15 -30
- package/dist/adapters/vue.js +36 -87
- package/dist/adapters/vue.js.map +1 -1
- package/dist/code/CodeSurface.vue.d.ts +3 -3
- package/dist/config/index.d.ts +105 -0
- package/dist/config/index.js +95 -0
- package/dist/config/index.js.map +1 -0
- package/dist/core/abilities.js +1 -0
- package/dist/core/abilities.js.map +1 -1
- package/dist/{adapters/routes.js → core/api-routes.js} +5 -3
- package/dist/core/api-routes.js.map +1 -0
- package/dist/core/backend-capability.d.ts +7 -0
- package/dist/core/backend-capability.js +17 -0
- package/dist/core/backend-capability.js.map +1 -0
- package/dist/core/backend-types.d.ts +245 -0
- package/dist/core/backend-types.js +17 -0
- package/dist/core/backend-types.js.map +1 -0
- package/dist/core/backend.d.ts +108 -0
- package/dist/core/backend.js +14 -0
- package/dist/core/backend.js.map +1 -0
- package/dist/core/block-convert.d.ts +7 -5
- package/dist/core/block-convert.js +28 -5
- package/dist/core/block-convert.js.map +1 -1
- package/dist/core/command-types.d.ts +89 -0
- package/dist/core/commands.d.ts +40 -0
- package/dist/core/commands.js +151 -0
- package/dist/core/commands.js.map +1 -0
- package/dist/core/context.d.ts +17 -20
- package/dist/core/context.js +24 -21
- package/dist/core/context.js.map +1 -1
- package/dist/core/core-feature.d.ts +22 -7
- package/dist/core/core-feature.js +51 -18
- package/dist/core/core-feature.js.map +1 -1
- package/dist/core/define-editor.d.ts +4 -3
- package/dist/core/define-editor.js +14 -7
- package/dist/core/define-editor.js.map +1 -1
- package/dist/core/document-markdown.js +12 -3
- package/dist/core/document-markdown.js.map +1 -1
- package/dist/core/editor-ui.d.ts +8 -1
- package/dist/core/editor-ui.js +9 -8
- package/dist/core/editor-ui.js.map +1 -1
- package/dist/core/extension-points.d.ts +3 -15
- package/dist/core/feature-context.d.ts +8 -7
- package/dist/core/feature-context.js +12 -11
- package/dist/core/feature-context.js.map +1 -1
- package/dist/core/feature.d.ts +35 -19
- package/dist/core/feature.js.map +1 -1
- package/dist/core/fences.d.ts +2 -1
- package/dist/core/fences.js +3 -2
- package/dist/core/fences.js.map +1 -1
- package/dist/core/fetch-error.d.ts +1 -1
- package/dist/core/fetch-error.js +3 -1
- package/dist/core/fetch-error.js.map +1 -1
- package/dist/core/hash.d.ts +5 -0
- package/dist/core/hash.js +11 -0
- package/dist/core/hash.js.map +1 -0
- package/dist/core/http-backend.d.ts +11 -0
- package/dist/core/http-backend.js +195 -0
- package/dist/core/http-backend.js.map +1 -0
- package/dist/core/index.d.ts +14 -9
- package/dist/core/index.js +12 -9
- package/dist/core/palette.d.ts +48 -0
- package/dist/core/palette.js +95 -0
- package/dist/core/palette.js.map +1 -0
- package/dist/core/schema/abilities.d.ts +2 -1
- package/dist/core/schema/abilities.js +5 -1
- package/dist/core/schema/abilities.js.map +1 -1
- package/dist/core/schema/index.d.ts +11 -5
- package/dist/core/schema/index.js +13 -8
- package/dist/core/schema/index.js.map +1 -1
- package/dist/core/schema/mark-flags.d.ts +8 -1
- package/dist/core/schema/of-features.d.ts +13 -0
- package/dist/core/schema/of-features.js +14 -0
- package/dist/core/schema/of-features.js.map +1 -0
- package/dist/core/slash.d.ts +8 -6
- package/dist/core/slash.js +24 -16
- package/dist/core/slash.js.map +1 -1
- package/dist/core/surface-session.js +13 -5
- package/dist/core/surface-session.js.map +1 -1
- package/dist/core/toolbar-items.d.ts +10 -4
- package/dist/core/toolbar-items.js +269 -195
- package/dist/core/toolbar-items.js.map +1 -1
- package/dist/core/util.js +11 -0
- package/dist/core/util.js.map +1 -0
- package/dist/document/DocumentSurface.d.ts +1 -1
- package/dist/document/DocumentSurface.vue.d.ts +3 -3
- package/dist/features/ai/agent-op-review.d.ts +1 -1
- package/dist/features/ai/agent-op-review.js +1 -1
- package/dist/features/ai/agent-ops.js +1 -1
- package/dist/features/ai/ai-apply.d.ts +2 -2
- package/dist/features/ai/ai-apply.js +1 -1
- package/dist/features/ai/ai-review.js +1 -1
- package/dist/features/ai/ai-sse.d.ts +6 -6
- package/dist/features/ai/ai-sse.js +20 -63
- package/dist/features/ai/ai-sse.js.map +1 -1
- package/dist/features/ai/assistant.d.ts +8 -7
- package/dist/features/ai/assistant.js +3 -3
- package/dist/features/ai/assistant.js.map +1 -1
- package/dist/features/ai/block-actions.d.ts +3 -2
- package/dist/features/ai/block-actions.js +3 -2
- package/dist/features/ai/block-actions.js.map +1 -1
- package/dist/features/ai/components/AiSelectionMenu.js +1 -1
- package/dist/features/ai/components/DocumentChatAnswer.js +1 -1
- package/dist/features/ai/components/DocumentChatOps.vue.d.ts +1 -1
- package/dist/features/ai/components/SettingsModelProfiles.js +8 -8
- package/dist/features/ai/components/SettingsModelProfiles.js.map +1 -1
- package/dist/features/ai/document-chat-model.d.ts +8 -7
- package/dist/features/ai/document-chat-model.js +5 -5
- package/dist/features/ai/document-chat-model.js.map +1 -1
- package/dist/features/ai/document-chat.js +1 -1
- package/dist/features/ai/feature.js +27 -14
- package/dist/features/ai/feature.js.map +1 -1
- package/dist/features/ai/ghost-autocomplete.d.ts +7 -6
- package/dist/features/ai/ghost-autocomplete.js +6 -9
- package/dist/features/ai/ghost-autocomplete.js.map +1 -1
- package/dist/features/ai/index.d.ts +4 -3
- package/dist/features/ai/index.js +10 -10
- package/dist/features/ai/model-profiles.d.ts +5 -4
- package/dist/features/ai/model-profiles.js +2 -2
- package/dist/features/ai/model-profiles.js.map +1 -1
- package/dist/features/ai/protocol/block-lines.js +1 -1
- package/dist/features/ai/protocol/block-lines.js.map +1 -1
- package/dist/features/ai/protocol/chat.js +4 -1
- package/dist/features/ai/protocol/chat.js.map +1 -1
- package/dist/features/ai/protocol/index.d.ts +3 -2
- package/dist/features/ai/protocol/models.d.ts +2 -16
- package/dist/features/ai/protocol/models.js.map +1 -1
- package/dist/features/ai/rate-limit.d.ts +1 -1
- package/dist/features/ai/rate-limit.js +3 -1
- package/dist/features/ai/rate-limit.js.map +1 -1
- package/dist/features/ai/react/AiSelectionMenu.js +2 -2
- package/dist/features/ai/react/AiSidebar.js +4 -4
- package/dist/features/ai/react/DocumentChatAnswer.js +1 -1
- package/dist/features/ai/react/DocumentChatOps.d.ts +1 -1
- package/dist/features/ai/react/DocumentChatOps.js +1 -1
- package/dist/features/ai/react/SettingsModelProfiles.js +8 -10
- package/dist/features/ai/react/SettingsModelProfiles.js.map +1 -1
- package/dist/features/ai/react/use-ai-assistant.d.ts +1 -1
- package/dist/features/ai/react/use-ai-assistant.js +3 -3
- package/dist/features/ai/react/use-ai-assistant.js.map +1 -1
- package/dist/features/ai/react/use-document-chat.js +2 -2
- package/dist/features/ai/react/use-document-chat.js.map +1 -1
- package/dist/features/ai/react/use-model-profiles.d.ts +2 -1
- package/dist/features/ai/selection-flow.d.ts +1 -1
- package/dist/features/ai/selection-flow.js +1 -1
- package/dist/features/ai/sidebar-flow.d.ts +1 -1
- package/dist/features/ai/sidebar-flow.js +1 -1
- package/dist/features/ai/use-ai-assistant.d.ts +1 -1
- package/dist/features/ai/use-ai-assistant.js +3 -3
- package/dist/features/ai/use-ai-assistant.js.map +1 -1
- package/dist/features/ai/use-document-chat.js +2 -2
- package/dist/features/ai/use-document-chat.js.map +1 -1
- package/dist/features/ai/use-model-profiles.d.ts +2 -1
- package/dist/features/authors/attribution.d.ts +1 -1
- package/dist/features/authors/feature.js +12 -11
- package/dist/features/authors/feature.js.map +1 -1
- package/dist/features/block-ui/block-actions.d.ts +22 -1
- package/dist/features/block-ui/block-actions.js +26 -2
- package/dist/features/block-ui/block-actions.js.map +1 -1
- package/dist/features/block-ui/components/BlockActionsOverlay.js +33 -4
- package/dist/features/block-ui/components/BlockActionsOverlay.js.map +1 -1
- package/dist/features/block-ui/components/BlockActionsOverlay.vue.d.ts +4 -0
- package/dist/features/block-ui/components/BlockUi.js +1 -1
- package/dist/features/block-ui/feature.js +1 -0
- package/dist/features/block-ui/feature.js.map +1 -1
- package/dist/features/block-ui/index.d.ts +2 -2
- package/dist/features/block-ui/index.js +2 -2
- package/dist/features/block-ui/react/BlockActionsOverlay.d.ts +4 -0
- package/dist/features/block-ui/react/BlockActionsOverlay.js +38 -12
- package/dist/features/block-ui/react/BlockActionsOverlay.js.map +1 -1
- package/dist/features/block-ui/react/BlockUi.js +1 -1
- package/dist/features/collab/anchor-resolver.js +1 -1
- package/dist/features/collab/feature.js +2 -0
- package/dist/features/collab/feature.js.map +1 -1
- package/dist/features/comments/components/CommentThreadView.vue.d.ts +2 -1
- package/dist/features/comments/feature.js +12 -11
- package/dist/features/comments/feature.js.map +1 -1
- package/dist/features/comments/index.d.ts +3 -2
- package/dist/features/comments/index.js +1 -1
- package/dist/features/comments/margin-layout.d.ts +3 -2
- package/dist/features/comments/model.d.ts +3 -67
- package/dist/features/comments/model.js +2 -2
- package/dist/features/comments/model.js.map +1 -1
- package/dist/features/comments/react/CommentThreadView.d.ts +3 -2
- package/dist/features/comments/react/use-comments.d.ts +2 -1
- package/dist/features/comments/react.d.ts +1 -1
- package/dist/features/comments/schema.d.ts +2 -52
- package/dist/features/comments/schema.js.map +1 -1
- package/dist/features/comments/snapshot-equality.js.map +1 -1
- package/dist/features/comments/use-comments.d.ts +3 -2
- package/dist/features/comments/vue.d.ts +1 -1
- package/dist/features/composites/accepted-children.d.ts +1 -0
- package/dist/features/composites/accepted-children.js +16 -1
- package/dist/features/composites/accepted-children.js.map +1 -1
- package/dist/features/composites/ai-brief.js +31 -0
- package/dist/features/composites/ai-brief.js.map +1 -1
- package/dist/features/composites/bibliography-command.d.ts +11 -0
- package/dist/features/composites/bibliography-form.js +90 -0
- package/dist/features/composites/bibliography-form.js.map +1 -0
- package/dist/features/composites/bibliography.d.ts +33 -0
- package/dist/features/composites/bibliography.js +120 -0
- package/dist/features/composites/bibliography.js.map +1 -0
- package/dist/features/composites/components/BibliographyEditor.js +261 -0
- package/dist/features/composites/components/BibliographyEditor.js.map +1 -0
- package/dist/features/composites/components/CompositeChrome.js +75 -26
- package/dist/features/composites/components/CompositeChrome.js.map +1 -1
- package/dist/features/composites/components/CompositeDetails.js +46 -11
- package/dist/features/composites/components/CompositeDetails.js.map +1 -1
- package/dist/features/composites/components/CompositeDetails.vue.d.ts +2 -1
- package/dist/features/composites/components/CompositeFieldEditor.js +37 -4
- package/dist/features/composites/components/CompositeFieldEditor.js.map +1 -1
- package/dist/features/composites/components/CompositeInspector.js +17 -5
- package/dist/features/composites/components/CompositeInspector.js.map +1 -1
- package/dist/features/composites/components/CompositeTable.js +13 -4
- package/dist/features/composites/components/CompositeTable.js.map +1 -1
- package/dist/features/composites/components/CompositeTagsEditor.js +1 -1
- package/dist/features/composites/components/CompositeView.js +11 -1
- package/dist/features/composites/components/CompositeView.js.map +1 -1
- package/dist/features/composites/components/DerivationBadge.js +103 -0
- package/dist/features/composites/components/DerivationBadge.js.map +1 -0
- package/dist/features/composites/components/ReferenceFieldSelect.js +60 -0
- package/dist/features/composites/components/ReferenceFieldSelect.js.map +1 -0
- package/dist/features/composites/components/ReferenceView.js +122 -0
- package/dist/features/composites/components/ReferenceView.js.map +1 -0
- package/dist/features/composites/components/ReferenceView.vue.d.ts +96 -0
- package/dist/features/composites/components/SettingsEditingTab.js +1 -1
- package/dist/features/composites/convert.js +2 -2
- package/dist/features/composites/convert.js.map +1 -1
- package/dist/features/composites/derivation.d.ts +61 -0
- package/dist/features/composites/derivation.js +98 -0
- package/dist/features/composites/derivation.js.map +1 -0
- package/dist/features/composites/derived-chrome.js +69 -0
- package/dist/features/composites/derived-chrome.js.map +1 -0
- package/dist/features/composites/feature.js +159 -109
- package/dist/features/composites/feature.js.map +1 -1
- package/dist/features/composites/fences.d.ts +4 -3
- package/dist/features/composites/fences.js +51 -7
- package/dist/features/composites/fences.js.map +1 -1
- package/dist/features/composites/index.d.ts +12 -3
- package/dist/features/composites/index.js +15 -6
- package/dist/features/composites/inspector-model.d.ts +4 -1
- package/dist/features/composites/inspector-model.js +8 -4
- package/dist/features/composites/inspector-model.js.map +1 -1
- package/dist/features/composites/kinds.d.ts +8 -1
- package/dist/features/composites/kinds.js +145 -6
- package/dist/features/composites/kinds.js.map +1 -1
- package/dist/features/composites/legacy.d.ts +4 -1
- package/dist/features/composites/legacy.js +56 -1
- package/dist/features/composites/legacy.js.map +1 -1
- package/dist/features/composites/meta-display.js +40 -1
- package/dist/features/composites/meta-display.js.map +1 -1
- package/dist/features/composites/meta-keys.d.ts +7 -0
- package/dist/features/composites/meta-keys.js +21 -0
- package/dist/features/composites/meta-keys.js.map +1 -0
- package/dist/features/composites/node-views.d.ts +6 -3
- package/dist/features/composites/node-views.js +7 -3
- package/dist/features/composites/node-views.js.map +1 -1
- package/dist/features/composites/nodes.d.ts +6 -1
- package/dist/features/composites/nodes.js +33 -7
- package/dist/features/composites/nodes.js.map +1 -1
- package/dist/features/composites/react/BibliographyEditor.js +229 -0
- package/dist/features/composites/react/BibliographyEditor.js.map +1 -0
- package/dist/features/composites/react/CompositeChrome.js +65 -17
- package/dist/features/composites/react/CompositeChrome.js.map +1 -1
- package/dist/features/composites/react/CompositeDetails.d.ts +2 -1
- package/dist/features/composites/react/CompositeDetails.js +45 -6
- package/dist/features/composites/react/CompositeDetails.js.map +1 -1
- package/dist/features/composites/react/CompositeFieldEditor.d.ts +1 -1
- package/dist/features/composites/react/CompositeFieldEditor.js +24 -1
- package/dist/features/composites/react/CompositeFieldEditor.js.map +1 -1
- package/dist/features/composites/react/CompositeInspector.js +11 -5
- package/dist/features/composites/react/CompositeInspector.js.map +1 -1
- package/dist/features/composites/react/CompositeStatusMenu.js +1 -1
- package/dist/features/composites/react/CompositeSummaryEditor.js +1 -1
- package/dist/features/composites/react/CompositeTable.js +16 -2
- package/dist/features/composites/react/CompositeTable.js.map +1 -1
- package/dist/features/composites/react/CompositeTagsEditor.js +2 -2
- package/dist/features/composites/react/CompositeView.js +6 -1
- package/dist/features/composites/react/CompositeView.js.map +1 -1
- package/dist/features/composites/react/DerivationBadge.js +116 -0
- package/dist/features/composites/react/DerivationBadge.js.map +1 -0
- package/dist/features/composites/react/ReferenceFieldSelect.js +52 -0
- package/dist/features/composites/react/ReferenceFieldSelect.js.map +1 -0
- package/dist/features/composites/react/ReferenceView.d.ts +11 -0
- package/dist/features/composites/react/ReferenceView.js +115 -0
- package/dist/features/composites/react/ReferenceView.js.map +1 -0
- package/dist/features/composites/react/SettingsEditingTab.js +2 -2
- package/dist/features/composites/react.d.ts +2 -1
- package/dist/features/composites/react.js +7 -3
- package/dist/features/composites/react.js.map +1 -1
- package/dist/features/composites/reference-ai.js +16 -0
- package/dist/features/composites/reference-ai.js.map +1 -0
- package/dist/features/composites/reference-label.d.ts +19 -0
- package/dist/features/composites/reference-label.js +58 -0
- package/dist/features/composites/reference-label.js.map +1 -0
- package/dist/features/composites/reference-suggestion.d.ts +10 -0
- package/dist/features/composites/reference-suggestion.js +41 -0
- package/dist/features/composites/reference-suggestion.js.map +1 -0
- package/dist/features/composites/reference-text.d.ts +18 -0
- package/dist/features/composites/reference-text.js +89 -0
- package/dist/features/composites/reference-text.js.map +1 -0
- package/dist/features/composites/reference.d.ts +44 -0
- package/dist/features/composites/reference.js +148 -0
- package/dist/features/composites/reference.js.map +1 -0
- package/dist/features/composites/reveal-source.d.ts +32 -0
- package/dist/features/composites/reveal-source.js +89 -0
- package/dist/features/composites/reveal-source.js.map +1 -0
- package/dist/features/composites/rows.d.ts +21 -2
- package/dist/features/composites/rows.js +63 -9
- package/dist/features/composites/rows.js.map +1 -1
- package/dist/features/composites/schema.d.ts +9 -3
- package/dist/features/composites/schema.js +11 -4
- package/dist/features/composites/schema.js.map +1 -1
- package/dist/features/composites/table-model.js +12 -21
- package/dist/features/composites/table-model.js.map +1 -1
- package/dist/features/composites/vue.d.ts +3 -2
- package/dist/features/composites/vue.js +8 -4
- package/dist/features/composites/vue.js.map +1 -1
- package/dist/features/media/assets.d.ts +2 -0
- package/dist/features/media/assets.js +3 -2
- package/dist/features/media/assets.js.map +1 -1
- package/dist/features/media/components/FileView.js +13 -4
- package/dist/features/media/components/FileView.js.map +1 -1
- package/dist/features/media/feature.d.ts +3 -3
- package/dist/features/media/feature.js +21 -28
- package/dist/features/media/feature.js.map +1 -1
- package/dist/features/media/file-import.js +2 -2
- package/dist/features/media/file-import.js.map +1 -1
- package/dist/features/media/index.d.ts +2 -2
- package/dist/features/media/index.js +2 -2
- package/dist/features/media/react/FileView.js +19 -2
- package/dist/features/media/react/FileView.js.map +1 -1
- package/dist/features/media/schema.d.ts +8 -0
- package/dist/features/media/schema.js +126 -11
- package/dist/features/media/schema.js.map +1 -1
- package/dist/features/media/upload.d.ts +16 -14
- package/dist/features/media/upload.js +13 -19
- package/dist/features/media/upload.js.map +1 -1
- package/dist/features/mentions/index.d.ts +4 -3
- package/dist/features/mentions/index.js +4 -1
- package/dist/features/mentions/index.js.map +1 -1
- package/dist/features/mentions/mention-text.d.ts +1 -1
- package/dist/features/mentions/mention-text.js.map +1 -1
- package/dist/features/mentions/mention.d.ts +0 -6
- package/dist/features/mentions/mention.js.map +1 -1
- package/dist/features/mentions/metadata-defaults.d.ts +2 -2
- package/dist/features/mentions/metadata-defaults.js +3 -9
- package/dist/features/mentions/metadata-defaults.js.map +1 -1
- package/dist/features/mentions/schema.d.ts +2 -1
- package/dist/features/mentions/schema.js.map +1 -1
- package/dist/features/tables/feature.d.ts +2 -1
- package/dist/features/tables/feature.js +90 -70
- package/dist/features/tables/feature.js.map +1 -1
- package/dist/features/themes/components/SettingsAppearanceTab.js +6 -9
- package/dist/features/themes/components/SettingsAppearanceTab.js.map +1 -1
- package/dist/features/themes/feature.js +2 -0
- package/dist/features/themes/feature.js.map +1 -1
- package/dist/features/themes/index.d.ts +2 -1
- package/dist/features/themes/react/SettingsAppearanceTab.js +7 -10
- package/dist/features/themes/react/SettingsAppearanceTab.js.map +1 -1
- package/dist/features/themes/schema.d.ts +2 -6
- package/dist/features/themes/schema.js.map +1 -1
- package/dist/features/themes/theme-runtime.d.ts +1 -1
- package/dist/features/themes/theme-runtime.js +4 -2
- package/dist/features/themes/theme-runtime.js.map +1 -1
- package/dist/features/transcript/TranscriptSegmentView.js +48 -28
- package/dist/features/transcript/TranscriptSegmentView.js.map +1 -1
- package/dist/features/transcript/feature.js +21 -19
- package/dist/features/transcript/feature.js.map +1 -1
- package/dist/features/transcript/react/TranscriptSegmentView.js +55 -36
- package/dist/features/transcript/react/TranscriptSegmentView.js.map +1 -1
- package/dist/features/transcript/segment-node.d.ts +2 -0
- package/dist/features/transcript/segment-node.js +35 -7
- package/dist/features/transcript/segment-node.js.map +1 -1
- package/dist/i18n/de/composites.js +91 -1
- package/dist/i18n/de/composites.js.map +1 -1
- package/dist/i18n/de/integrations.js +49 -8
- package/dist/i18n/de/integrations.js.map +1 -1
- package/dist/i18n/de/media.js +0 -1
- package/dist/i18n/de/media.js.map +1 -1
- package/dist/i18n/de/palette.js +22 -0
- package/dist/i18n/de/palette.js.map +1 -0
- package/dist/i18n/de/tables.js +0 -1
- package/dist/i18n/de/tables.js.map +1 -1
- package/dist/i18n/de/transcript.js +2 -1
- package/dist/i18n/de/transcript.js.map +1 -1
- package/dist/i18n/de/tree.js +3 -0
- package/dist/i18n/de/tree.js.map +1 -1
- package/dist/i18n/de.d.ts +157 -11
- package/dist/i18n/de.js +3 -1
- package/dist/i18n/de.js.map +1 -1
- package/dist/i18n/en/composites.js +89 -1
- package/dist/i18n/en/composites.js.map +1 -1
- package/dist/i18n/en/integrations.js +49 -8
- package/dist/i18n/en/integrations.js.map +1 -1
- package/dist/i18n/en/media.js +0 -1
- package/dist/i18n/en/media.js.map +1 -1
- package/dist/i18n/en/palette.js +22 -0
- package/dist/i18n/en/palette.js.map +1 -0
- package/dist/i18n/en/tables.js +0 -1
- package/dist/i18n/en/tables.js.map +1 -1
- package/dist/i18n/en/transcript.js +2 -1
- package/dist/i18n/en/transcript.js.map +1 -1
- package/dist/i18n/en/tree.js +3 -0
- package/dist/i18n/en/tree.js.map +1 -1
- package/dist/i18n/en.js +3 -1
- package/dist/i18n/en.js.map +1 -1
- package/dist/index.d.ts +4 -3
- package/dist/integrations/composite-ai/bibliography-fetch.d.ts +31 -0
- package/dist/integrations/composite-ai/bibliography-fetch.js +159 -0
- package/dist/integrations/composite-ai/bibliography-fetch.js.map +1 -0
- package/dist/integrations/composite-ai/composite-fill.d.ts +30 -8
- package/dist/integrations/composite-ai/composite-fill.js +97 -56
- package/dist/integrations/composite-ai/composite-fill.js.map +1 -1
- package/dist/integrations/composite-ai/composite-summary.d.ts +4 -12
- package/dist/integrations/composite-ai/composite-summary.js +7 -26
- package/dist/integrations/composite-ai/composite-summary.js.map +1 -1
- package/dist/integrations/composite-ai/derive.d.ts +29 -0
- package/dist/integrations/composite-ai/derive.js +173 -0
- package/dist/integrations/composite-ai/derive.js.map +1 -0
- package/dist/integrations/composite-ai/index.d.ts +11 -7
- package/dist/integrations/composite-ai/index.js +72 -14
- package/dist/integrations/composite-ai/index.js.map +1 -1
- package/dist/integrations/composite-ai/rendition.d.ts +45 -0
- package/dist/integrations/composite-ai/rendition.js +314 -0
- package/dist/integrations/composite-ai/rendition.js.map +1 -0
- package/dist/integrations/composite-media/index.d.ts +7 -5
- package/dist/integrations/composite-media/index.js +86 -13
- package/dist/integrations/composite-media/index.js.map +1 -1
- package/dist/integrations/transcript-ai/index.d.ts +1 -1
- package/dist/integrations/transcript-ai/index.js +5 -2
- package/dist/integrations/transcript-ai/index.js.map +1 -1
- package/dist/integrations/transcript-ai/protocol.d.ts +2 -12
- package/dist/integrations/transcript-ai/protocol.js +0 -2
- package/dist/integrations/transcript-ai/protocol.js.map +1 -1
- package/dist/integrations/transcript-ai/transcript-cleanup.d.ts +5 -5
- package/dist/integrations/transcript-ai/transcript-cleanup.js +7 -10
- package/dist/integrations/transcript-ai/transcript-cleanup.js.map +1 -1
- package/dist/markdown/MarkdownSurface.vue.d.ts +10 -9
- package/dist/markdown/MarkdownSurface2.js +3 -6
- package/dist/markdown/MarkdownSurface2.js.map +1 -1
- package/dist/markdown/document.js +1 -1
- package/dist/markdown/source-mode.d.ts +1 -1
- package/dist/nuxt/module.d.ts +1402 -54
- package/dist/nuxt/module.js +6 -49
- package/dist/nuxt/module.js.map +1 -1
- package/dist/nuxt/runtime/install-context.d.ts +7 -3
- package/dist/nuxt/runtime/install-context.js +14 -8
- package/dist/nuxt/runtime/install-context.js.map +1 -1
- package/dist/nuxt/runtime/plugins/editor-context-nuxt-ui.client.ts +2 -2
- package/dist/nuxt/runtime/server/plugins/editor-server.js +20 -12
- package/dist/nuxt/runtime/server/plugins/editor-server.js.map +1 -1
- package/dist/presets/compose.d.ts +94 -0
- package/dist/presets/compose.js +164 -0
- package/dist/presets/compose.js.map +1 -0
- package/dist/react/AdvancedEditor.d.ts +15 -15
- package/dist/react/AdvancedEditor.js +15 -13
- package/dist/react/AdvancedEditor.js.map +1 -1
- package/dist/react/EditorCommandPalette.d.ts +13 -0
- package/dist/react/EditorCommandPalette.js +118 -0
- package/dist/react/EditorCommandPalette.js.map +1 -0
- package/dist/react/EditorSettingsModal.d.ts +5 -5
- package/dist/react/EditorSettingsModal.js +7 -4
- package/dist/react/EditorSettingsModal.js.map +1 -1
- package/dist/react/EditorSettingsPanel.d.ts +7 -7
- package/dist/react/EditorSettingsPanel.js +8 -5
- package/dist/react/EditorSettingsPanel.js.map +1 -1
- package/dist/react/EditorSurface.d.ts +7 -7
- package/dist/react/EditorSurface.js +10 -6
- package/dist/react/EditorSurface.js.map +1 -1
- package/dist/react/EditorToolbar.d.ts +4 -6
- package/dist/react/EditorToolbar.js +29 -37
- package/dist/react/EditorToolbar.js.map +1 -1
- package/dist/react/SimpleEditor.d.ts +22 -23
- package/dist/react/SimpleEditor.js +21 -7
- package/dist/react/SimpleEditor.js.map +1 -1
- package/dist/react/advanced.d.ts +4 -3
- package/dist/react/advanced.js +2 -2
- package/dist/react/compose.d.ts +20 -0
- package/dist/react/compose.js +49 -0
- package/dist/react/compose.js.map +1 -0
- package/dist/react/composed-surface.d.ts +39 -0
- package/dist/react/composed-surface.js +71 -0
- package/dist/react/composed-surface.js.map +1 -0
- package/dist/react/context.js +6 -2
- package/dist/react/context.js.map +1 -1
- package/dist/react/index.d.ts +2 -1
- package/dist/react/index.js +2 -1
- package/dist/react/key-labels.js +15 -0
- package/dist/react/key-labels.js.map +1 -0
- package/dist/react/settings.d.ts +1 -1
- package/dist/react/simple.d.ts +2 -2
- package/dist/react/ui/command.js +36 -1
- package/dist/react/ui/command.js.map +1 -1
- package/dist/schema/advanced.d.ts +6 -6
- package/dist/schema/advanced.js +26 -29
- package/dist/schema/advanced.js.map +1 -1
- package/dist/server/ai.d.ts +5 -16
- package/dist/server/ai.js.map +1 -1
- package/dist/server/auth.d.ts +9 -0
- package/dist/server/collab-state.d.ts +1 -1
- package/dist/server/collab-state.js.map +1 -1
- package/dist/server/collab.d.ts +13 -13
- package/dist/server/collab.js +34 -18
- package/dist/server/collab.js.map +1 -1
- package/dist/server/crossref.js +78 -0
- package/dist/server/crossref.js.map +1 -0
- package/dist/server/errors.d.ts +1 -1
- package/dist/server/errors.js +1 -1
- package/dist/server/errors.js.map +1 -1
- package/dist/server/extract.js +308 -0
- package/dist/server/extract.js.map +1 -0
- package/dist/{nuxt/runtime/server/utils/editor-route.js → server/h3.js} +8 -16
- package/dist/server/h3.js.map +1 -0
- package/dist/server/handlers/ai.d.ts +30 -9
- package/dist/server/handlers/ai.js +170 -36
- package/dist/server/handlers/ai.js.map +1 -1
- package/dist/server/handlers/context.d.ts +12 -5
- package/dist/server/handlers/context.js +10 -4
- package/dist/server/handlers/context.js.map +1 -1
- package/dist/server/handlers/editor.d.ts +19 -13
- package/dist/server/handlers/editor.js +49 -38
- package/dist/server/handlers/editor.js.map +1 -1
- package/dist/server/handlers/index.d.ts +4 -4
- package/dist/server/handlers/index.js +4 -4
- package/dist/server/host.d.ts +16 -25
- package/dist/server/host.js +58 -41
- package/dist/server/host.js.map +1 -1
- package/dist/server/index.d.ts +6 -4
- package/dist/server/index.js +3 -2
- package/dist/server/pdf.js +97 -0
- package/dist/server/pdf.js.map +1 -0
- package/dist/server/{adapter.d.ts → ports.d.ts} +81 -30
- package/dist/server/ports.js +29 -0
- package/dist/server/ports.js.map +1 -0
- package/dist/server/routes.js +144 -0
- package/dist/server/routes.js.map +1 -0
- package/dist/settings/index.d.ts +1 -1
- package/dist/settings/index.js.map +1 -1
- package/dist/styles/composites.css +25 -0
- package/dist/tree/DocumentTree.js +56 -29
- package/dist/tree/DocumentTree.js.map +1 -1
- package/dist/tree/react/DocumentTree.js +23 -0
- package/dist/tree/react/DocumentTree.js.map +1 -1
- package/dist/tree/tree-host.js +1 -1
- package/dist/vue/AdvancedEditor.js +30 -9
- package/dist/vue/AdvancedEditor.js.map +1 -1
- package/dist/vue/AdvancedEditor.vue.d.ts +32 -12
- package/dist/vue/SimpleEditor.js +62 -16
- package/dist/vue/SimpleEditor.js.map +1 -1
- package/dist/vue/SimpleEditor.vue.d.ts +37 -7
- package/dist/vue/advanced.d.ts +3 -2
- package/dist/vue/advanced.js +2 -2
- package/dist/vue/components/EditorCommandPalette.js +91 -0
- package/dist/vue/components/EditorCommandPalette.js.map +1 -0
- package/dist/vue/components/EditorCommandPalette.vue.d.ts +15 -0
- package/dist/vue/components/EditorSettingsModal.js +10 -6
- package/dist/vue/components/EditorSettingsModal.js.map +1 -1
- package/dist/vue/components/EditorSettingsModal.vue.d.ts +4 -4
- package/dist/vue/components/EditorSettingsPanel.js +10 -6
- package/dist/vue/components/EditorSettingsPanel.js.map +1 -1
- package/dist/vue/components/EditorSettingsPanel.vue.d.ts +6 -6
- package/dist/vue/components/EditorSurface.js +11 -6
- package/dist/vue/components/EditorSurface.js.map +1 -1
- package/dist/vue/components/EditorSurface.vue.d.ts +11 -11
- package/dist/vue/components/EditorToolbar.js +41 -49
- package/dist/vue/components/EditorToolbar.js.map +1 -1
- package/dist/vue/components/EditorToolbar.vue.d.ts +2 -4
- package/dist/vue/compose.d.ts +17 -0
- package/dist/vue/compose.js +51 -0
- package/dist/vue/compose.js.map +1 -0
- package/dist/vue/context-key.d.ts +6 -0
- package/dist/vue/context-key.js +6 -0
- package/dist/vue/context-key.js.map +1 -0
- package/dist/vue/context.d.ts +8 -6
- package/dist/vue/context.js +6 -5
- package/dist/vue/context.js.map +1 -1
- package/dist/vue/index.d.ts +10 -8
- package/dist/vue/index.js +10 -8
- package/dist/vue/kit/index.d.ts +2 -2
- package/dist/vue/kit/nuxt-ui.js +23 -0
- package/dist/vue/kit/nuxt-ui.js.map +1 -1
- package/dist/vue/kit/types.d.ts +40 -1
- package/package.json +30 -16
- package/dist/adapters/comments/client.d.ts +0 -64
- package/dist/adapters/comments/client.js.map +0 -1
- package/dist/adapters/routes.js.map +0 -1
- package/dist/core/toolbar.d.ts +0 -74
- package/dist/core/toolbar.js +0 -45
- package/dist/core/toolbar.js.map +0 -1
- package/dist/integrations/composite-ai/document-transcribe.d.ts +0 -14
- package/dist/integrations/composite-ai/document-transcribe.js +0 -89
- package/dist/integrations/composite-ai/document-transcribe.js.map +0 -1
- package/dist/nuxt/runtime/server/api/ai/chat.post.d.ts +0 -5
- package/dist/nuxt/runtime/server/api/ai/chat.post.js +0 -8
- package/dist/nuxt/runtime/server/api/ai/chat.post.js.map +0 -1
- package/dist/nuxt/runtime/server/api/ai/complete.post.d.ts +0 -5
- package/dist/nuxt/runtime/server/api/ai/complete.post.js +0 -8
- package/dist/nuxt/runtime/server/api/ai/complete.post.js.map +0 -1
- package/dist/nuxt/runtime/server/api/ai/generate.post.d.ts +0 -5
- package/dist/nuxt/runtime/server/api/ai/generate.post.js +0 -8
- package/dist/nuxt/runtime/server/api/ai/generate.post.js.map +0 -1
- package/dist/nuxt/runtime/server/api/ai/models.get.d.ts +0 -5
- package/dist/nuxt/runtime/server/api/ai/models.get.js +0 -8
- package/dist/nuxt/runtime/server/api/ai/models.get.js.map +0 -1
- package/dist/nuxt/runtime/server/api/ai/transcribe.post.d.ts +0 -5
- package/dist/nuxt/runtime/server/api/ai/transcribe.post.js +0 -8
- package/dist/nuxt/runtime/server/api/ai/transcribe.post.js.map +0 -1
- package/dist/nuxt/runtime/server/api/ai/transcript-cleanup.post.d.ts +0 -5
- package/dist/nuxt/runtime/server/api/ai/transcript-cleanup.post.js +0 -8
- package/dist/nuxt/runtime/server/api/ai/transcript-cleanup.post.js.map +0 -1
- package/dist/nuxt/runtime/server/api/editor/assets/[id]/[name].get.d.ts +0 -5
- package/dist/nuxt/runtime/server/api/editor/assets/[id]/[name].get.js +0 -8
- package/dist/nuxt/runtime/server/api/editor/assets/[id]/[name].get.js.map +0 -1
- package/dist/nuxt/runtime/server/api/editor/assets/[id].post.d.ts +0 -5
- package/dist/nuxt/runtime/server/api/editor/assets/[id].post.js +0 -8
- package/dist/nuxt/runtime/server/api/editor/assets/[id].post.js.map +0 -1
- package/dist/nuxt/runtime/server/api/editor/settings.get.d.ts +0 -5
- package/dist/nuxt/runtime/server/api/editor/settings.get.js +0 -8
- package/dist/nuxt/runtime/server/api/editor/settings.get.js.map +0 -1
- package/dist/nuxt/runtime/server/api/editor/settings.put.d.ts +0 -5
- package/dist/nuxt/runtime/server/api/editor/settings.put.js +0 -8
- package/dist/nuxt/runtime/server/api/editor/settings.put.js.map +0 -1
- package/dist/nuxt/runtime/server/api/editor/tags.get.d.ts +0 -5
- package/dist/nuxt/runtime/server/api/editor/tags.get.js +0 -8
- package/dist/nuxt/runtime/server/api/editor/tags.get.js.map +0 -1
- package/dist/nuxt/runtime/server/api/editor/themes/[id].delete.d.ts +0 -5
- package/dist/nuxt/runtime/server/api/editor/themes/[id].delete.js +0 -8
- package/dist/nuxt/runtime/server/api/editor/themes/[id].delete.js.map +0 -1
- package/dist/nuxt/runtime/server/api/editor/themes/[id].get.d.ts +0 -5
- package/dist/nuxt/runtime/server/api/editor/themes/[id].get.js +0 -8
- package/dist/nuxt/runtime/server/api/editor/themes/[id].get.js.map +0 -1
- package/dist/nuxt/runtime/server/api/editor/themes/index.get.d.ts +0 -5
- package/dist/nuxt/runtime/server/api/editor/themes/index.get.js +0 -8
- package/dist/nuxt/runtime/server/api/editor/themes/index.get.js.map +0 -1
- package/dist/nuxt/runtime/server/api/editor/themes/index.post.d.ts +0 -5
- package/dist/nuxt/runtime/server/api/editor/themes/index.post.js +0 -8
- package/dist/nuxt/runtime/server/api/editor/themes/index.post.js.map +0 -1
- package/dist/nuxt/runtime/server/api/editor/users.get.d.ts +0 -5
- package/dist/nuxt/runtime/server/api/editor/users.get.js +0 -8
- package/dist/nuxt/runtime/server/api/editor/users.get.js.map +0 -1
- package/dist/nuxt/runtime/server/plugins/collab.d.ts +0 -5
- package/dist/nuxt/runtime/server/plugins/collab.js +0 -10
- package/dist/nuxt/runtime/server/plugins/collab.js.map +0 -1
- package/dist/nuxt/runtime/server/routes/collab/[id].d.ts +0 -5
- package/dist/nuxt/runtime/server/routes/collab/[id].js +0 -35
- package/dist/nuxt/runtime/server/routes/collab/[id].js.map +0 -1
- package/dist/nuxt/runtime/server/utils/editor-route.d.ts +0 -11
- package/dist/nuxt/runtime/server/utils/editor-route.js.map +0 -1
- package/dist/presets/advanced.d.ts +0 -33
- package/dist/presets/advanced.js +0 -50
- package/dist/presets/advanced.js.map +0 -1
- package/dist/presets/simple.d.ts +0 -9
- package/dist/presets/simple.js +0 -12
- package/dist/presets/simple.js.map +0 -1
- package/dist/react/advanced-preset.d.ts +0 -11
- package/dist/react/advanced-preset.js +0 -31
- package/dist/react/advanced-preset.js.map +0 -1
- package/dist/vue/advanced-preset.d.ts +0 -13
- package/dist/vue/advanced-preset.js +0 -33
- package/dist/vue/advanced-preset.js.map +0 -1
- package/docs/extending.md +0 -538
- package/docs/integration.md +0 -630
- package/docs/llms.md +0 -383
- package/docs/usage.md +0 -1076
|
@@ -1,37 +1,31 @@
|
|
|
1
|
-
import { MentionUser } from "../
|
|
1
|
+
import { MentionUser } from "../core/backend-types.js";
|
|
2
2
|
import "../features/mentions/schema.js";
|
|
3
|
-
import {
|
|
3
|
+
import { AssetStore, CollabStateStore, Directory, DocumentAdmin, DocumentStore, EditorPorts, Identity, SettingsStore } from "../server/ports.js";
|
|
4
4
|
import "../server/index.js";
|
|
5
|
-
import { JSONContent } from "@tiptap/core";
|
|
6
5
|
//#region src/adapters/shared.d.ts
|
|
7
6
|
/**
|
|
8
|
-
* The identity half of every adapter in this package: who the user is, which documents they may open
|
|
9
|
-
*
|
|
7
|
+
* The identity half of every adapter in this package: who the user is, which documents they may open and who can be
|
|
8
|
+
* `@`-mentioned. Storage is the adapter's own business.
|
|
10
9
|
*/
|
|
11
10
|
export interface AdapterHooks {
|
|
12
11
|
/**
|
|
13
|
-
* The user behind a request, `null` = not authenticated (see `
|
|
12
|
+
* The user behind a request, `null` = not authenticated (see `Identity.authenticate`). Default: an anonymous
|
|
14
13
|
* development user outside `NODE_ENV=production`, `null` (everyone refused) in production, so a deployment never
|
|
15
14
|
* serves documents to the world by omission.
|
|
16
15
|
*/
|
|
17
|
-
authenticate?:
|
|
18
|
-
/** Per-document access for the collaboration websocket (see `
|
|
19
|
-
authorize?:
|
|
20
|
-
/** Vue-free TipTap extensions of host-defined nodes and marks for the collaboration schema (see `EditorAdapter.schemaExtensions`). */
|
|
21
|
-
schemaExtensions?: EditorAdapter['schemaExtensions'];
|
|
16
|
+
authenticate?: Identity['authenticate'];
|
|
17
|
+
/** Per-document access for the collaboration websocket (see `Identity.authorize`). Omitted: every authenticated user edits every document. */
|
|
18
|
+
authorize?: Identity['authorize'];
|
|
22
19
|
/** Users that can be `@`-mentioned (`GET /api/editor/users`); no credentials. Default: none. */
|
|
23
20
|
users?: () => MentionUser[] | Promise<MentionUser[]>;
|
|
24
21
|
}
|
|
25
|
-
/**
|
|
26
|
-
export interface
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
listDocumentIds(): Promise<string[]>;
|
|
22
|
+
/** The ports of an adapter that stores documents itself (`json`, `drizzle`): the contract including versioning, settings and document management. */
|
|
23
|
+
export interface StoredPorts extends EditorPorts {
|
|
24
|
+
documents: DocumentStore & DocumentAdmin & Required<Pick<DocumentStore, 'contentVersion'>>;
|
|
25
|
+
collabState: CollabStateStore;
|
|
26
|
+
directory: Directory;
|
|
27
|
+
assets: AssetStore;
|
|
28
|
+
settings: SettingsStore;
|
|
33
29
|
}
|
|
34
|
-
/** An adapter that stores documents itself (`json`, `drizzle`): the full contract including versioning, settings and document management. */
|
|
35
|
-
export type StoredEditorAdapter = EditorAdapter & Required<Pick<EditorAdapter, 'contentVersion' | 'loadSettings' | 'storeSettings'>> & DocumentAdmin;
|
|
36
30
|
//#endregion
|
|
37
31
|
//# sourceMappingURL=shared.d.ts.map
|
package/dist/adapters/shared.js
CHANGED
|
@@ -5,16 +5,18 @@ const DEV_USER = {
|
|
|
5
5
|
color: "#6366f1"
|
|
6
6
|
};
|
|
7
7
|
const authenticateDefault = async () => process.env.NODE_ENV === "production" ? null : { ...DEV_USER };
|
|
8
|
-
/** `
|
|
9
|
-
function
|
|
10
|
-
const { authenticate = authenticateDefault, authorize
|
|
8
|
+
/** The `identity` port of `hooks`; `authorize` is only present when given (the collab server and the document routes test for it). */
|
|
9
|
+
function identityOf(hooks) {
|
|
10
|
+
const { authenticate = authenticateDefault, authorize } = hooks;
|
|
11
11
|
return {
|
|
12
12
|
authenticate: (request) => authenticate(request),
|
|
13
|
-
|
|
14
|
-
...authorize && { authorize: (user, id) => authorize(user, id) },
|
|
15
|
-
...schemaExtensions && { schemaExtensions: () => schemaExtensions() }
|
|
13
|
+
...authorize && { authorize: (user, id) => authorize(user, id) }
|
|
16
14
|
};
|
|
17
15
|
}
|
|
16
|
+
/** The `directory` port of the `users` hook. */
|
|
17
|
+
function directoryOf({ users }) {
|
|
18
|
+
return { listUsers: async () => await users?.() ?? [] };
|
|
19
|
+
}
|
|
18
20
|
/** The key per-user settings are stored under: the user's `id`, else its `username`. */
|
|
19
21
|
function settingsKey(user) {
|
|
20
22
|
const { id, username } = user;
|
|
@@ -24,9 +26,9 @@ function settingsKey(user) {
|
|
|
24
26
|
}
|
|
25
27
|
throw new TypeError("@ecsplico/editor: the authenticated user has neither an `id` nor a `username`, so its settings have no key");
|
|
26
28
|
}
|
|
27
|
-
/** An independent copy of the bytes (a driver's `Buffer` may view a larger pool), as the plain `Uint8Array` the
|
|
29
|
+
/** An independent copy of the bytes (a driver's `Buffer` may view a larger pool), as the plain `Uint8Array` the port contract names. */
|
|
28
30
|
const bytesOf = (data) => new Uint8Array(data);
|
|
29
31
|
//#endregion
|
|
30
|
-
export { bytesOf,
|
|
32
|
+
export { bytesOf, directoryOf, identityOf, settingsKey };
|
|
31
33
|
|
|
32
34
|
//# sourceMappingURL=shared.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"shared.js","names":[],"sources":["../../src/adapters/shared.ts"],"sourcesContent":["import type {
|
|
1
|
+
{"version":3,"file":"shared.js","names":[],"sources":["../../src/adapters/shared.ts"],"sourcesContent":["import type { MentionUser } from '../features/mentions/schema'\nimport type { AssetStore, CollabStateStore, Directory, DocumentAdmin, DocumentStore, EditorPorts, Identity, SettingsStore } from '../server'\n\n/**\n * The identity half of every adapter in this package: who the user is, which documents they may open and who can be\n * `@`-mentioned. Storage is the adapter's own business.\n */\nexport interface AdapterHooks {\n /**\n * The user behind a request, `null` = not authenticated (see `Identity.authenticate`). Default: an anonymous\n * development user outside `NODE_ENV=production`, `null` (everyone refused) in production, so a deployment never\n * serves documents to the world by omission.\n */\n authenticate?: Identity['authenticate']\n /** Per-document access for the collaboration websocket (see `Identity.authorize`). Omitted: every authenticated user edits every document. */\n authorize?: Identity['authorize']\n /** Users that can be `@`-mentioned (`GET /api/editor/users`); no credentials. Default: none. */\n users?: () => MentionUser[] | Promise<MentionUser[]>\n}\n\n/** The ports of an adapter that stores documents itself (`json`, `drizzle`): the contract including versioning, settings and document management. */\nexport interface StoredPorts extends EditorPorts {\n documents: DocumentStore & DocumentAdmin & Required<Pick<DocumentStore, 'contentVersion'>>\n collabState: CollabStateStore\n directory: Directory\n assets: AssetStore\n settings: SettingsStore\n}\n\nconst DEV_USER = { id: 'dev', username: 'dev', color: '#6366f1' } as const\n\nconst authenticateDefault: Identity['authenticate'] = async () => process.env.NODE_ENV === 'production' ? null : { ...DEV_USER }\n\n/** The `identity` port of `hooks`; `authorize` is only present when given (the collab server and the document routes test for it). */\nexport function identityOf(hooks: Pick<AdapterHooks, 'authenticate' | 'authorize'>): Identity {\n const { authenticate = authenticateDefault, authorize } = hooks\n return {\n authenticate: request => authenticate(request),\n ...(authorize && { authorize: (user: object, id: string) => authorize(user, id) }),\n }\n}\n\n/** The `directory` port of the `users` hook. */\nexport function directoryOf({ users }: Pick<AdapterHooks, 'users'>): Directory {\n return { listUsers: async () => (await users?.()) ?? [] }\n}\n\n/** The key per-user settings are stored under: the user's `id`, else its `username`. */\nexport function settingsKey(user: object): string {\n const { id, username } = user as { id?: unknown, username?: unknown }\n for (const candidate of [id, username]) {\n if (typeof candidate === 'string' && candidate !== '') return candidate\n if (typeof candidate === 'number') return String(candidate)\n }\n throw new TypeError('@ecsplico/editor: the authenticated user has neither an `id` nor a `username`, so its settings have no key')\n}\n\n/** An independent copy of the bytes (a driver's `Buffer` may view a larger pool), as the plain `Uint8Array` the port contract names. */\nexport const bytesOf = (data: Uint8Array): Uint8Array => new Uint8Array(data)\n"],"mappings":";AA6BA,MAAM,WAAW;CAAE,IAAI;CAAO,UAAU;CAAO,OAAO;AAAU;AAEhE,MAAM,sBAAgD,YAAY,QAAQ,IAAI,aAAa,eAAe,OAAO,EAAE,GAAG,SAAS;;AAG/H,SAAgB,WAAW,OAAmE;CAC5F,MAAM,EAAE,eAAe,qBAAqB,cAAc;CAC1D,OAAO;EACL,eAAc,YAAW,aAAa,OAAO;EAC7C,GAAI,aAAa,EAAE,YAAY,MAAc,OAAe,UAAU,MAAM,EAAE,EAAE;CAClF;AACF;;AAGA,SAAgB,YAAY,EAAE,SAAiD;CAC7E,OAAO,EAAE,WAAW,YAAa,MAAM,QAAQ,KAAM,CAAC,EAAE;AAC1D;;AAGA,SAAgB,YAAY,MAAsB;CAChD,MAAM,EAAE,IAAI,aAAa;CACzB,KAAK,MAAM,aAAa,CAAC,IAAI,QAAQ,GAAG;EACtC,IAAI,OAAO,cAAc,YAAY,cAAc,IAAI,OAAO;EAC9D,IAAI,OAAO,cAAc,UAAU,OAAO,OAAO,SAAS;CAC5D;CACA,MAAM,IAAI,UAAU,4GAA4G;AAClI;;AAGA,MAAa,WAAW,SAAiC,IAAI,WAAW,IAAI"}
|
package/dist/adapters/vue.d.ts
CHANGED
|
@@ -1,27 +1,10 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { CollaborationSession } from "../core/feature.js";
|
|
2
|
+
import { CommentsModel } from "../core/backend-types.js";
|
|
2
3
|
import "../core/index.js";
|
|
3
|
-
import {
|
|
4
|
+
import { EditorDocumentOptions } from "./document-state.js";
|
|
4
5
|
import { Editor, JSONContent } from "@tiptap/core";
|
|
5
6
|
import { ComputedRef, MaybeRefOrGetter, Ref, ShallowRef } from "vue";
|
|
6
7
|
//#region src/adapters/vue.d.ts
|
|
7
|
-
export interface EditorDocumentOptions {
|
|
8
|
-
/** How requests are sent: `globalThis.fetch`, or a wrapper that adds the base URL and credentials. Used for the content and the comments. */
|
|
9
|
-
fetch: CommentsFetch;
|
|
10
|
-
/**
|
|
11
|
-
* Live collaboration: the collaboration server's websocket URL (`ws://host/collab`; the document id is appended as the
|
|
12
|
-
* provider's `name`) and the optional token its `EditorAdapter.authenticate` receives. With it the Y.Doc is the document:
|
|
13
|
-
* the server loads and stores the content, so the composable neither fetches nor saves it (`modelValue` stays
|
|
14
|
-
* `undefined`, `dirty` stays `false`, `save()` resolves at once).
|
|
15
|
-
*/
|
|
16
|
-
collaboration?: {
|
|
17
|
-
url: string;
|
|
18
|
-
token?: string | (() => string) | (() => Promise<string>);
|
|
19
|
-
};
|
|
20
|
-
/** Who writes: labels remote carets and is the author of new comments; `null` or omitted = nobody (no comments). */
|
|
21
|
-
user?: AuthorIdentity | null | (() => AuthorIdentity | null);
|
|
22
|
-
/** Whether the user may comment now (a reader of a read-only document may be refused); default `true`. */
|
|
23
|
-
canComment?: boolean | (() => boolean);
|
|
24
|
-
}
|
|
25
8
|
/** The props and events of the editor surface (`SimpleEditor`, `AdvancedEditor`, `EditorSurface`) that `useEditorDocument` fills. */
|
|
26
9
|
export interface EditorDocumentBinding {
|
|
27
10
|
/** The document (standalone mode); `undefined` in collaboration mode and until it has loaded. */
|
|
@@ -38,16 +21,16 @@ export interface EditorDocument {
|
|
|
38
21
|
ready: Ref<boolean>;
|
|
39
22
|
/** Edits since the content was loaded or last saved. */
|
|
40
23
|
dirty: ComputedRef<boolean>;
|
|
41
|
-
/** Stores the current content (`
|
|
24
|
+
/** Stores the current content (`backend.documents.save`); several calls run one after another and an edit made while one is in flight stays dirty. Rejects with the backend's refusal. */
|
|
42
25
|
save(): Promise<void>;
|
|
43
|
-
/**
|
|
26
|
+
/** Loads the content again and drops unsaved edits. */
|
|
44
27
|
reload(): Promise<void>;
|
|
45
28
|
/** The last load or save error, `null` while all is well. */
|
|
46
29
|
error: Ref<Error | null>;
|
|
47
30
|
/** The collaboration session for the surface's `collaboration` prop; `undefined` without the `collaboration` option. */
|
|
48
31
|
collaboration: ShallowRef<CollaborationSession | undefined>;
|
|
49
|
-
/** The comments model of this document (`commentsFeature({ model: () => comments.value })`),
|
|
50
|
-
comments: Readonly<ShallowRef<
|
|
32
|
+
/** The comments model of this document (`commentsFeature({ model: () => comments.value! })`), made by `backend.comments`; `undefined` when the backend has none. A new one per id. */
|
|
33
|
+
comments: Readonly<ShallowRef<CommentsModel | undefined>>;
|
|
51
34
|
/** The live editor, once the surface reported it. */
|
|
52
35
|
editor: ShallowRef<Editor | undefined>;
|
|
53
36
|
/** `v-bind` target for the surface: `<AdvancedEditor v-if="ready" :key="id" v-bind="bind" />`. */
|
|
@@ -56,12 +39,14 @@ export interface EditorDocument {
|
|
|
56
39
|
dispose(): void;
|
|
57
40
|
}
|
|
58
41
|
/**
|
|
59
|
-
* Loads document `id`
|
|
60
|
-
*
|
|
61
|
-
*
|
|
62
|
-
*
|
|
42
|
+
* Loads document `id` through `backend.documents` (a missing document starts empty; the first `save()` creates it),
|
|
43
|
+
* tracks edits, saves, and prepares the collaboration session (`backend.collaboration`) and comments model
|
|
44
|
+
* (`backend.comments`) for the editor surface. The backend is `options.backend`, else the editor context's
|
|
45
|
+
* (`createEditor`). `id` may be reactive: a change loads the other document and replaces the session and the comments
|
|
46
|
+
* model. Call it in a component's `setup`; the collaboration session is created synchronously, so the surface mounts in
|
|
47
|
+
* the same tick. Throws when `collaboration` is set and the backend cannot collaborate, or when it keeps no documents.
|
|
63
48
|
*/
|
|
64
|
-
export declare function useEditorDocument(id: MaybeRefOrGetter<string>, options
|
|
49
|
+
export declare function useEditorDocument(id: MaybeRefOrGetter<string>, options?: EditorDocumentOptions): EditorDocument;
|
|
65
50
|
//#endregion
|
|
66
|
-
export type {
|
|
51
|
+
export type { EditorDocumentOptions };
|
|
67
52
|
//# sourceMappingURL=vue.d.ts.map
|
package/dist/adapters/vue.js
CHANGED
|
@@ -1,74 +1,35 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import
|
|
4
|
-
import { HocuspocusProvider } from "@hocuspocus/provider";
|
|
5
|
-
import { computed, getCurrentScope, onScopeDispose, ref, shallowRef, toValue, watch } from "vue";
|
|
1
|
+
import { errorOf, fingerprintToSave, isDirty, loadedDocument, openSession, requireCapability } from "./document-state.js";
|
|
2
|
+
import { EDITOR_CONTEXT } from "../vue/context-key.js";
|
|
3
|
+
import { computed, getCurrentScope, inject, onScopeDispose, ref, shallowRef, toValue, watch } from "vue";
|
|
6
4
|
//#region src/adapters/vue.ts
|
|
7
|
-
const EMPTY_DOCUMENT = {
|
|
8
|
-
type: "doc",
|
|
9
|
-
content: [{ type: "paragraph" }]
|
|
10
|
-
};
|
|
11
5
|
/**
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
6
|
+
* Loads document `id` through `backend.documents` (a missing document starts empty; the first `save()` creates it),
|
|
7
|
+
* tracks edits, saves, and prepares the collaboration session (`backend.collaboration`) and comments model
|
|
8
|
+
* (`backend.comments`) for the editor surface. The backend is `options.backend`, else the editor context's
|
|
9
|
+
* (`createEditor`). `id` may be reactive: a change loads the other document and replaces the session and the comments
|
|
10
|
+
* model. Call it in a component's `setup`; the collaboration session is created synchronously, so the surface mounts in
|
|
11
|
+
* the same tick. Throws when `collaboration` is set and the backend cannot collaborate, or when it keeps no documents.
|
|
15
12
|
*/
|
|
16
|
-
|
|
17
|
-
const
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
...content && { content: content.map(withoutBlockIds) }
|
|
23
|
-
};
|
|
24
|
-
};
|
|
25
|
-
const fingerprint = (content) => JSON.stringify(withoutBlockIds(content));
|
|
26
|
-
/** Document ids are percent-encoded into one path segment; the collab provider's `name` is the plain id. */
|
|
27
|
-
function sessionOf(id, { url, token }, user) {
|
|
28
|
-
const ydoc = new Y.Doc();
|
|
29
|
-
const provider = new HocuspocusProvider({
|
|
30
|
-
url: `${url.replace(/\/+$/, "")}/${encodeURIComponent(id)}`,
|
|
31
|
-
name: id,
|
|
32
|
-
document: ydoc,
|
|
33
|
-
...token !== void 0 && { token }
|
|
34
|
-
});
|
|
35
|
-
return {
|
|
36
|
-
session: {
|
|
37
|
-
ydoc,
|
|
38
|
-
provider,
|
|
39
|
-
...user && { user }
|
|
40
|
-
},
|
|
41
|
-
close() {
|
|
42
|
-
provider.destroy();
|
|
43
|
-
ydoc.destroy();
|
|
44
|
-
}
|
|
45
|
-
};
|
|
46
|
-
}
|
|
47
|
-
const errorOf = (cause) => cause instanceof Error ? cause : new Error(String(cause));
|
|
48
|
-
/**
|
|
49
|
-
* Loads document `id` from `GET /api/editor/documents/<id>` (a `404` starts an empty document that the first `save()`
|
|
50
|
-
* creates), tracks edits, saves with `PUT`, and prepares the collaboration session and comments model for the editor
|
|
51
|
-
* surface. `id` may be reactive: a change loads the other document and replaces the session and the comments model.
|
|
52
|
-
* Call it in a component's `setup`; the collaboration session is created synchronously, so the surface mounts in the same tick.
|
|
53
|
-
*/
|
|
54
|
-
function useEditorDocument(id, options) {
|
|
13
|
+
function useEditorDocument(id, options = {}) {
|
|
14
|
+
const backend = options.backend ?? inject(EDITOR_CONTEXT, null)?.backend;
|
|
15
|
+
if (!backend) throw new Error("@ecsplico/editor: useEditorDocument needs a backend: pass `backend` or install the editor context with app.use(createEditor())");
|
|
16
|
+
const collaborating = Boolean(options.collaboration);
|
|
17
|
+
const documents = collaborating ? void 0 : requireCapability(backend, "documents");
|
|
18
|
+
const collaborationPort = collaborating ? requireCapability(backend, "collaboration") : void 0;
|
|
55
19
|
const userOf = () => toValue(options.user) ?? null;
|
|
56
20
|
const modelValue = ref();
|
|
57
21
|
const ready = ref(false);
|
|
58
22
|
const error = ref(null);
|
|
59
23
|
const collaboration = shallowRef();
|
|
60
24
|
const editor = shallowRef();
|
|
61
|
-
/** Fingerprint (`fingerprint`) of the JSON the
|
|
25
|
+
/** Fingerprint (`fingerprint`) of the JSON the backend holds (the empty document while it does not exist), `null` before the first load. */
|
|
62
26
|
const savedJson = ref(null);
|
|
63
|
-
/** The document does not exist
|
|
27
|
+
/** The document does not exist in the backend yet: the first save creates it even if nothing was typed. */
|
|
64
28
|
let missing = false;
|
|
65
29
|
let closeSession;
|
|
66
30
|
let generation = 0;
|
|
67
31
|
let tail = Promise.resolve();
|
|
68
|
-
const commentsFor = (documentId) =>
|
|
69
|
-
fetch: options.fetch,
|
|
70
|
-
documentId,
|
|
71
|
-
endpoint: commentsUrl(documentId),
|
|
32
|
+
const commentsFor = (documentId) => backend.comments?.(documentId, {
|
|
72
33
|
user: userOf,
|
|
73
34
|
canComment: () => toValue(options.canComment) ?? true,
|
|
74
35
|
getEditor: () => editor.value,
|
|
@@ -90,54 +51,42 @@ function useEditorDocument(id, options) {
|
|
|
90
51
|
closeSession = void 0;
|
|
91
52
|
collaboration.value = void 0;
|
|
92
53
|
if (commentsId !== documentId) {
|
|
93
|
-
comments.value
|
|
54
|
+
comments.value?.dispose();
|
|
94
55
|
comments.value = commentsFor(documentId);
|
|
95
56
|
commentsId = documentId;
|
|
96
57
|
}
|
|
97
|
-
if (
|
|
98
|
-
const { session, close } =
|
|
58
|
+
if (collaborationPort) {
|
|
59
|
+
const { session, close } = openSession(collaborationPort, documentId, options.collaboration, userOf());
|
|
99
60
|
closeSession = close;
|
|
100
61
|
collaboration.value = session;
|
|
101
62
|
ready.value = true;
|
|
102
63
|
return;
|
|
103
64
|
}
|
|
104
65
|
try {
|
|
105
|
-
const
|
|
66
|
+
const content = await documents.load(documentId);
|
|
106
67
|
if (mine !== generation) return;
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
} else if (response.ok) {
|
|
112
|
-
const content = await response.json();
|
|
113
|
-
if (mine !== generation) return;
|
|
114
|
-
modelValue.value = content;
|
|
115
|
-
savedJson.value = fingerprint(content);
|
|
116
|
-
} else throw new Error(`@ecsplico/editor: loading "${documentId}" failed (${response.status})`);
|
|
68
|
+
const loaded = loadedDocument(content);
|
|
69
|
+
modelValue.value = loaded.modelValue;
|
|
70
|
+
savedJson.value = loaded.saved;
|
|
71
|
+
missing = loaded.missing;
|
|
117
72
|
ready.value = true;
|
|
118
73
|
} catch (cause) {
|
|
119
74
|
if (mine === generation) error.value = errorOf(cause);
|
|
120
75
|
}
|
|
121
76
|
}
|
|
122
|
-
const dirty = computed(() =>
|
|
77
|
+
const dirty = computed(() => isDirty(collaborating, modelValue.value, savedJson.value));
|
|
123
78
|
function save() {
|
|
124
|
-
if (
|
|
79
|
+
if (!documents) return Promise.resolve();
|
|
125
80
|
const run = async () => {
|
|
126
81
|
const documentId = toValue(id);
|
|
127
82
|
const content = modelValue.value;
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
body: json
|
|
136
|
-
});
|
|
137
|
-
if (!response.ok) {
|
|
138
|
-
const failure = /* @__PURE__ */ new Error(`@ecsplico/editor: saving "${documentId}" failed (${response.status})`);
|
|
139
|
-
error.value = failure;
|
|
140
|
-
throw failure;
|
|
83
|
+
const saved = fingerprintToSave(content, ready.value, savedJson.value, missing);
|
|
84
|
+
if (content === void 0 || saved === null) return;
|
|
85
|
+
try {
|
|
86
|
+
await documents.save(documentId, content);
|
|
87
|
+
} catch (cause) {
|
|
88
|
+
error.value = errorOf(cause);
|
|
89
|
+
throw cause;
|
|
141
90
|
}
|
|
142
91
|
error.value = null;
|
|
143
92
|
if (documentId === toValue(id)) {
|
|
@@ -154,7 +103,7 @@ function useEditorDocument(id, options) {
|
|
|
154
103
|
closeSession?.();
|
|
155
104
|
closeSession = void 0;
|
|
156
105
|
collaboration.value = void 0;
|
|
157
|
-
comments.value
|
|
106
|
+
comments.value?.dispose();
|
|
158
107
|
}
|
|
159
108
|
watch(() => toValue(id), (documentId) => void load(documentId), { immediate: true });
|
|
160
109
|
if (getCurrentScope()) onScopeDispose(dispose);
|
package/dist/adapters/vue.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"vue.js","names":[],"sources":["../../src/adapters/vue.ts"],"sourcesContent":["import { HocuspocusProvider } from '@hocuspocus/provider'\nimport type { Editor, JSONContent } from '@tiptap/core'\nimport type { AuthorIdentity, CollaborationSession } from '../core'\nimport { computed, type ComputedRef, getCurrentScope, type MaybeRefOrGetter, onScopeDispose, ref, type Ref, shallowRef, type ShallowRef, toValue, watch } from 'vue'\nimport * as Y from 'yjs'\nimport { type CommentsFetch, createRestCommentsModel, type RestCommentsModel } from './comments/client'\nimport { commentsUrl, documentUrl } from './routes'\n\n// The Vue side of an editor document: load it from the host's document endpoint, keep track of unsaved edits, save it,\n// and hand the editor surface what it needs (v-model, collaboration session, comments model). The server side is\n// `installEditorServer` (`./server/nitro`); any server that answers the same two routes works.\n\nexport type { CommentsFetch } from './comments/client'\n\nexport interface EditorDocumentOptions {\n /** How requests are sent: `globalThis.fetch`, or a wrapper that adds the base URL and credentials. Used for the content and the comments. */\n fetch: CommentsFetch\n /**\n * Live collaboration: the collaboration server's websocket URL (`ws://host/collab`; the document id is appended as the\n * provider's `name`) and the optional token its `EditorAdapter.authenticate` receives. With it the Y.Doc is the document:\n * the server loads and stores the content, so the composable neither fetches nor saves it (`modelValue` stays\n * `undefined`, `dirty` stays `false`, `save()` resolves at once).\n */\n collaboration?: { url: string, token?: string | (() => string) | (() => Promise<string>) }\n /** Who writes: labels remote carets and is the author of new comments; `null` or omitted = nobody (no comments). */\n user?: AuthorIdentity | null | (() => AuthorIdentity | null)\n /** Whether the user may comment now (a reader of a read-only document may be refused); default `true`. */\n canComment?: boolean | (() => boolean)\n}\n\n/** The props and events of the editor surface (`SimpleEditor`, `AdvancedEditor`, `EditorSurface`) that `useEditorDocument` fills. */\nexport interface EditorDocumentBinding {\n /** The document (standalone mode); `undefined` in collaboration mode and until it has loaded. */\n modelValue: JSONContent | undefined\n 'onUpdate:modelValue': (content: JSONContent) => void\n /** Hands the live editor to the comments model. */\n onReady: (editor: Editor) => void\n collaboration: CollaborationSession | undefined\n}\n\nexport interface EditorDocument {\n /** The document's TipTap JSON: the surface's `v-model`. `undefined` until loaded, and always in collaboration mode. */\n modelValue: Ref<JSONContent | undefined>\n /** `true` once the surface can be mounted: the content has loaded (a missing document starts empty), or the collaboration session exists. Mount with `:key` = the id, so a changed id remounts it. */\n ready: Ref<boolean>\n /** Edits since the content was loaded or last saved. */\n dirty: ComputedRef<boolean>\n /** Stores the current content (`PUT`); several calls run one after another and an edit made while one is in flight stays dirty. Rejects with the server's refusal. */\n save(): Promise<void>\n /** Fetches the content again and drops unsaved edits. */\n reload(): Promise<void>\n /** The last load or save error, `null` while all is well. */\n error: Ref<Error | null>\n /** The collaboration session for the surface's `collaboration` prop; `undefined` without the `collaboration` option. */\n collaboration: ShallowRef<CollaborationSession | undefined>\n /** The comments model of this document (`commentsFeature({ model: () => comments.value })`), threads behind the host's comments endpoint. A new one per id. */\n comments: Readonly<ShallowRef<RestCommentsModel>>\n /** The live editor, once the surface reported it. */\n editor: ShallowRef<Editor | undefined>\n /** `v-bind` target for the surface: `<AdvancedEditor v-if=\"ready\" :key=\"id\" v-bind=\"bind\" />`. */\n bind: ComputedRef<EditorDocumentBinding>\n /** Closes the collaboration session and the comments model; runs with the effect scope that called `useEditorDocument`. */\n dispose(): void\n}\n\nconst EMPTY_DOCUMENT: JSONContent = { type: 'doc', content: [{ type: 'paragraph' }] }\n\n/**\n * The document as compared for \"unsaved changes\": without block ids. The editor gives every block of loaded content an\n * id the moment it mounts (stored files have none yet); that is not an edit the user made, so it must not mark a\n * freshly opened document dirty. Saving still writes the ids.\n */\nconst withoutBlockIds = (node: JSONContent): JSONContent => {\n const { attrs, content, ...rest } = node\n const kept = attrs && Object.fromEntries(Object.entries(attrs).filter(([name]) => name !== 'id'))\n return {\n ...rest,\n ...(kept && Object.keys(kept).length > 0 && { attrs: kept }),\n ...(content && { content: content.map(withoutBlockIds) }),\n }\n}\nconst fingerprint = (content: JSONContent): string => JSON.stringify(withoutBlockIds(content))\n\n/** Document ids are percent-encoded into one path segment; the collab provider's `name` is the plain id. */\nfunction sessionOf(id: string, { url, token }: NonNullable<EditorDocumentOptions['collaboration']>, user: AuthorIdentity | null): { session: CollaborationSession, close: () => void } {\n const ydoc = new Y.Doc()\n const provider = new HocuspocusProvider({ url: `${url.replace(/\\/+$/, '')}/${encodeURIComponent(id)}`, name: id, document: ydoc, ...(token !== undefined && { token }) })\n return {\n session: { ydoc, provider, ...(user && { user }) },\n close() {\n provider.destroy()\n ydoc.destroy()\n },\n }\n}\n\nconst errorOf = (cause: unknown) => cause instanceof Error ? cause : new Error(String(cause))\n\n/**\n * Loads document `id` from `GET /api/editor/documents/<id>` (a `404` starts an empty document that the first `save()`\n * creates), tracks edits, saves with `PUT`, and prepares the collaboration session and comments model for the editor\n * surface. `id` may be reactive: a change loads the other document and replaces the session and the comments model.\n * Call it in a component's `setup`; the collaboration session is created synchronously, so the surface mounts in the same tick.\n */\nexport function useEditorDocument(id: MaybeRefOrGetter<string>, options: EditorDocumentOptions): EditorDocument {\n const userOf = () => toValue(options.user) ?? null\n const modelValue = ref<JSONContent>()\n const ready = ref(false)\n const error = ref<Error | null>(null)\n const collaboration = shallowRef<CollaborationSession>()\n const editor = shallowRef<Editor>()\n /** Fingerprint (`fingerprint`) of the JSON the server holds (the empty document while it does not exist), `null` before the first load. */\n const savedJson = ref<string | null>(null)\n /** The document does not exist on the server yet: the first save creates it even if nothing was typed. */\n let missing = false\n let closeSession: (() => void) | undefined\n let generation = 0\n let tail: Promise<unknown> = Promise.resolve()\n\n const commentsFor = (documentId: string) => createRestCommentsModel({\n fetch: options.fetch,\n documentId,\n endpoint: commentsUrl(documentId),\n user: userOf,\n canComment: () => toValue(options.canComment) ?? true,\n getEditor: () => editor.value,\n onError: (cause) => { error.value = cause },\n })\n const comments = shallowRef(commentsFor(toValue(id)))\n let commentsId = toValue(id)\n\n async function load(documentId: string): Promise<void> {\n const mine = ++generation\n ready.value = false\n error.value = null\n modelValue.value = undefined\n savedJson.value = null\n missing = false\n editor.value = undefined\n closeSession?.()\n closeSession = undefined\n collaboration.value = undefined\n if (commentsId !== documentId) {\n comments.value.dispose()\n comments.value = commentsFor(documentId)\n commentsId = documentId\n }\n\n if (options.collaboration) {\n const { session, close } = sessionOf(documentId, options.collaboration, userOf())\n closeSession = close\n collaboration.value = session\n ready.value = true\n return\n }\n try {\n const response = await options.fetch(documentUrl(documentId))\n if (mine !== generation) return\n if (response.status === 404) {\n modelValue.value = structuredClone(EMPTY_DOCUMENT)\n savedJson.value = fingerprint(EMPTY_DOCUMENT)\n missing = true\n }\n else if (response.ok) {\n const content = await response.json() as JSONContent\n if (mine !== generation) return\n modelValue.value = content\n savedJson.value = fingerprint(content)\n }\n else {\n throw new Error(`@ecsplico/editor: loading \"${documentId}\" failed (${response.status})`)\n }\n ready.value = true\n }\n catch (cause) {\n if (mine === generation) error.value = errorOf(cause)\n }\n }\n\n const dirty = computed(() => !options.collaboration && modelValue.value !== undefined && savedJson.value !== null && fingerprint(modelValue.value) !== savedJson.value)\n\n function save(): Promise<void> {\n if (options.collaboration) return Promise.resolve()\n const run = async () => {\n const documentId = toValue(id)\n const content = modelValue.value\n if (content === undefined || !ready.value) return\n const saved = fingerprint(content)\n if (saved === savedJson.value && !missing) return\n const json = JSON.stringify(content)\n const response = await options.fetch(documentUrl(documentId), { method: 'PUT', headers: { 'content-type': 'application/json' }, body: json })\n if (!response.ok) {\n const failure = new Error(`@ecsplico/editor: saving \"${documentId}\" failed (${response.status})`)\n error.value = failure\n throw failure\n }\n error.value = null\n // Only if the document did not change to another id while the request was in flight.\n if (documentId === toValue(id)) {\n savedJson.value = saved\n missing = false\n }\n }\n const result = tail.then(run, run)\n tail = result.catch(() => {})\n return result\n }\n\n function dispose() {\n generation++\n closeSession?.()\n closeSession = undefined\n collaboration.value = undefined\n comments.value.dispose()\n }\n\n watch(() => toValue(id), documentId => void load(documentId), { immediate: true })\n if (getCurrentScope()) onScopeDispose(dispose)\n\n const bind = computed<EditorDocumentBinding>(() => ({\n modelValue: modelValue.value,\n 'onUpdate:modelValue': (content) => { modelValue.value = content },\n onReady: (instance) => { editor.value = instance },\n collaboration: collaboration.value,\n }))\n\n return { modelValue, ready, dirty, save, reload: () => load(toValue(id)), error, collaboration, comments, editor, bind, dispose }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"vue.js","names":[],"sources":["../../src/adapters/vue.ts"],"sourcesContent":["import type { Editor, JSONContent } from '@tiptap/core'\nimport type { CollaborationSession } from '../core'\nimport type { CommentsModel } from '../core/backend-types'\nimport { EDITOR_CONTEXT } from '../vue/context-key'\nimport { computed, type ComputedRef, getCurrentScope, inject, type MaybeRefOrGetter, onScopeDispose, ref, type Ref, shallowRef, type ShallowRef, toValue, watch } from 'vue'\nimport { type EditorDocumentOptions, errorOf, fingerprintToSave, isDirty, loadedDocument, openSession, requireCapability } from './document-state'\n\n// The Vue side of an editor document: load it through the backend's `documents`, keep track of unsaved edits, save it,\n// and hand the editor surface what it needs (v-model, collaboration session, comments model). All three go through\n// `EditorBackend` (`createHttpBackend()` for the editor's routes, or the host's own); nothing here knows a URL.\n\nexport type { EditorDocumentOptions } from './document-state'\n\n/** The props and events of the editor surface (`SimpleEditor`, `AdvancedEditor`, `EditorSurface`) that `useEditorDocument` fills. */\nexport interface EditorDocumentBinding {\n /** The document (standalone mode); `undefined` in collaboration mode and until it has loaded. */\n modelValue: JSONContent | undefined\n 'onUpdate:modelValue': (content: JSONContent) => void\n /** Hands the live editor to the comments model. */\n onReady: (editor: Editor) => void\n collaboration: CollaborationSession | undefined\n}\n\nexport interface EditorDocument {\n /** The document's TipTap JSON: the surface's `v-model`. `undefined` until loaded, and always in collaboration mode. */\n modelValue: Ref<JSONContent | undefined>\n /** `true` once the surface can be mounted: the content has loaded (a missing document starts empty), or the collaboration session exists. Mount with `:key` = the id, so a changed id remounts it. */\n ready: Ref<boolean>\n /** Edits since the content was loaded or last saved. */\n dirty: ComputedRef<boolean>\n /** Stores the current content (`backend.documents.save`); several calls run one after another and an edit made while one is in flight stays dirty. Rejects with the backend's refusal. */\n save(): Promise<void>\n /** Loads the content again and drops unsaved edits. */\n reload(): Promise<void>\n /** The last load or save error, `null` while all is well. */\n error: Ref<Error | null>\n /** The collaboration session for the surface's `collaboration` prop; `undefined` without the `collaboration` option. */\n collaboration: ShallowRef<CollaborationSession | undefined>\n /** The comments model of this document (`commentsFeature({ model: () => comments.value! })`), made by `backend.comments`; `undefined` when the backend has none. A new one per id. */\n comments: Readonly<ShallowRef<CommentsModel | undefined>>\n /** The live editor, once the surface reported it. */\n editor: ShallowRef<Editor | undefined>\n /** `v-bind` target for the surface: `<AdvancedEditor v-if=\"ready\" :key=\"id\" v-bind=\"bind\" />`. */\n bind: ComputedRef<EditorDocumentBinding>\n /** Closes the collaboration session and the comments model; runs with the effect scope that called `useEditorDocument`. */\n dispose(): void\n}\n\n/**\n * Loads document `id` through `backend.documents` (a missing document starts empty; the first `save()` creates it),\n * tracks edits, saves, and prepares the collaboration session (`backend.collaboration`) and comments model\n * (`backend.comments`) for the editor surface. The backend is `options.backend`, else the editor context's\n * (`createEditor`). `id` may be reactive: a change loads the other document and replaces the session and the comments\n * model. Call it in a component's `setup`; the collaboration session is created synchronously, so the surface mounts in\n * the same tick. Throws when `collaboration` is set and the backend cannot collaborate, or when it keeps no documents.\n */\nexport function useEditorDocument(id: MaybeRefOrGetter<string>, options: EditorDocumentOptions = {}): EditorDocument {\n const backend = options.backend ?? inject(EDITOR_CONTEXT, null)?.backend\n if (!backend) throw new Error('@ecsplico/editor: useEditorDocument needs a backend: pass `backend` or install the editor context with app.use(createEditor())')\n const collaborating = Boolean(options.collaboration)\n const documents = collaborating ? undefined : requireCapability(backend, 'documents')\n const collaborationPort = collaborating ? requireCapability(backend, 'collaboration') : undefined\n\n const userOf = () => toValue(options.user) ?? null\n const modelValue = ref<JSONContent>()\n const ready = ref(false)\n const error = ref<Error | null>(null)\n const collaboration = shallowRef<CollaborationSession>()\n const editor = shallowRef<Editor>()\n /** Fingerprint (`fingerprint`) of the JSON the backend holds (the empty document while it does not exist), `null` before the first load. */\n const savedJson = ref<string | null>(null)\n /** The document does not exist in the backend yet: the first save creates it even if nothing was typed. */\n let missing = false\n let closeSession: (() => void) | undefined\n let generation = 0\n let tail: Promise<unknown> = Promise.resolve()\n\n const commentsFor = (documentId: string) => backend.comments?.(documentId, {\n user: userOf,\n canComment: () => toValue(options.canComment) ?? true,\n getEditor: () => editor.value,\n onError: (cause) => { error.value = cause },\n })\n const comments = shallowRef(commentsFor(toValue(id)))\n let commentsId = toValue(id)\n\n async function load(documentId: string): Promise<void> {\n const mine = ++generation\n ready.value = false\n error.value = null\n modelValue.value = undefined\n savedJson.value = null\n missing = false\n editor.value = undefined\n closeSession?.()\n closeSession = undefined\n collaboration.value = undefined\n if (commentsId !== documentId) {\n comments.value?.dispose()\n comments.value = commentsFor(documentId)\n commentsId = documentId\n }\n\n if (collaborationPort) {\n const { session, close } = openSession(collaborationPort, documentId, options.collaboration, userOf())\n closeSession = close\n collaboration.value = session\n ready.value = true\n return\n }\n try {\n const content = await documents!.load(documentId)\n if (mine !== generation) return\n const loaded = loadedDocument(content)\n modelValue.value = loaded.modelValue\n savedJson.value = loaded.saved\n missing = loaded.missing\n ready.value = true\n }\n catch (cause) {\n if (mine === generation) error.value = errorOf(cause)\n }\n }\n\n const dirty = computed(() => isDirty(collaborating, modelValue.value, savedJson.value))\n\n function save(): Promise<void> {\n if (!documents) return Promise.resolve()\n const run = async () => {\n const documentId = toValue(id)\n const content = modelValue.value\n const saved = fingerprintToSave(content, ready.value, savedJson.value, missing)\n if (content === undefined || saved === null) return\n try {\n await documents.save(documentId, content)\n }\n catch (cause) {\n error.value = errorOf(cause)\n throw cause\n }\n error.value = null\n // Only if the document did not change to another id while the request was in flight.\n if (documentId === toValue(id)) {\n savedJson.value = saved\n missing = false\n }\n }\n const result = tail.then(run, run)\n tail = result.catch(() => {})\n return result\n }\n\n function dispose() {\n generation++\n closeSession?.()\n closeSession = undefined\n collaboration.value = undefined\n comments.value?.dispose()\n }\n\n watch(() => toValue(id), documentId => void load(documentId), { immediate: true })\n if (getCurrentScope()) onScopeDispose(dispose)\n\n const bind = computed<EditorDocumentBinding>(() => ({\n modelValue: modelValue.value,\n 'onUpdate:modelValue': (content) => { modelValue.value = content },\n onReady: (instance) => { editor.value = instance },\n collaboration: collaboration.value,\n }))\n\n return { modelValue, ready, dirty, save, reload: () => load(toValue(id)), error, collaboration, comments, editor, bind, dispose }\n}\n"],"mappings":";;;;;;;;;;;;AAwDA,SAAgB,kBAAkB,IAA8B,UAAiC,CAAC,GAAmB;CACnH,MAAM,UAAU,QAAQ,WAAW,OAAO,gBAAgB,IAAI,CAAC,EAAE;CACjE,IAAI,CAAC,SAAS,MAAM,IAAI,MAAM,gIAAgI;CAC9J,MAAM,gBAAgB,QAAQ,QAAQ,aAAa;CACnD,MAAM,YAAY,gBAAgB,KAAA,IAAY,kBAAkB,SAAS,WAAW;CACpF,MAAM,oBAAoB,gBAAgB,kBAAkB,SAAS,eAAe,IAAI,KAAA;CAExF,MAAM,eAAe,QAAQ,QAAQ,IAAI,KAAK;CAC9C,MAAM,aAAa,IAAiB;CACpC,MAAM,QAAQ,IAAI,KAAK;CACvB,MAAM,QAAQ,IAAkB,IAAI;CACpC,MAAM,gBAAgB,WAAiC;CACvD,MAAM,SAAS,WAAmB;;CAElC,MAAM,YAAY,IAAmB,IAAI;;CAEzC,IAAI,UAAU;CACd,IAAI;CACJ,IAAI,aAAa;CACjB,IAAI,OAAyB,QAAQ,QAAQ;CAE7C,MAAM,eAAe,eAAuB,QAAQ,WAAW,YAAY;EACzE,MAAM;EACN,kBAAkB,QAAQ,QAAQ,UAAU,KAAK;EACjD,iBAAiB,OAAO;EACxB,UAAU,UAAU;GAAE,MAAM,QAAQ;EAAM;CAC5C,CAAC;CACD,MAAM,WAAW,WAAW,YAAY,QAAQ,EAAE,CAAC,CAAC;CACpD,IAAI,aAAa,QAAQ,EAAE;CAE3B,eAAe,KAAK,YAAmC;EACrD,MAAM,OAAO,EAAE;EACf,MAAM,QAAQ;EACd,MAAM,QAAQ;EACd,WAAW,QAAQ,KAAA;EACnB,UAAU,QAAQ;EAClB,UAAU;EACV,OAAO,QAAQ,KAAA;EACf,eAAe;EACf,eAAe,KAAA;EACf,cAAc,QAAQ,KAAA;EACtB,IAAI,eAAe,YAAY;GAC7B,SAAS,OAAO,QAAQ;GACxB,SAAS,QAAQ,YAAY,UAAU;GACvC,aAAa;EACf;EAEA,IAAI,mBAAmB;GACrB,MAAM,EAAE,SAAS,UAAU,YAAY,mBAAmB,YAAY,QAAQ,eAAe,OAAO,CAAC;GACrG,eAAe;GACf,cAAc,QAAQ;GACtB,MAAM,QAAQ;GACd;EACF;EACA,IAAI;GACF,MAAM,UAAU,MAAM,UAAW,KAAK,UAAU;GAChD,IAAI,SAAS,YAAY;GACzB,MAAM,SAAS,eAAe,OAAO;GACrC,WAAW,QAAQ,OAAO;GAC1B,UAAU,QAAQ,OAAO;GACzB,UAAU,OAAO;GACjB,MAAM,QAAQ;EAChB,SACO,OAAO;GACZ,IAAI,SAAS,YAAY,MAAM,QAAQ,QAAQ,KAAK;EACtD;CACF;CAEA,MAAM,QAAQ,eAAe,QAAQ,eAAe,WAAW,OAAO,UAAU,KAAK,CAAC;CAEtF,SAAS,OAAsB;EAC7B,IAAI,CAAC,WAAW,OAAO,QAAQ,QAAQ;EACvC,MAAM,MAAM,YAAY;GACtB,MAAM,aAAa,QAAQ,EAAE;GAC7B,MAAM,UAAU,WAAW;GAC3B,MAAM,QAAQ,kBAAkB,SAAS,MAAM,OAAO,UAAU,OAAO,OAAO;GAC9E,IAAI,YAAY,KAAA,KAAa,UAAU,MAAM;GAC7C,IAAI;IACF,MAAM,UAAU,KAAK,YAAY,OAAO;GAC1C,SACO,OAAO;IACZ,MAAM,QAAQ,QAAQ,KAAK;IAC3B,MAAM;GACR;GACA,MAAM,QAAQ;GAEd,IAAI,eAAe,QAAQ,EAAE,GAAG;IAC9B,UAAU,QAAQ;IAClB,UAAU;GACZ;EACF;EACA,MAAM,SAAS,KAAK,KAAK,KAAK,GAAG;EACjC,OAAO,OAAO,YAAY,CAAC,CAAC;EAC5B,OAAO;CACT;CAEA,SAAS,UAAU;EACjB;EACA,eAAe;EACf,eAAe,KAAA;EACf,cAAc,QAAQ,KAAA;EACtB,SAAS,OAAO,QAAQ;CAC1B;CAEA,YAAY,QAAQ,EAAE,IAAG,eAAc,KAAK,KAAK,UAAU,GAAG,EAAE,WAAW,KAAK,CAAC;CACjF,IAAI,gBAAgB,GAAG,eAAe,OAAO;CAS7C,OAAO;EAAE;EAAY;EAAO;EAAO;EAAM,cAAc,KAAK,QAAQ,EAAE,CAAC;EAAG;EAAO;EAAe;EAAU;EAAQ,MAPrG,gBAAuC;GAClD,YAAY,WAAW;GACvB,wBAAwB,YAAY;IAAE,WAAW,QAAQ;GAAQ;GACjE,UAAU,aAAa;IAAE,OAAO,QAAQ;GAAS;GACjD,eAAe,cAAc;EAC/B,EAEqH;EAAG;CAAQ;AAClI"}
|
|
@@ -12,16 +12,16 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {
|
|
|
12
12
|
view: import("vue").ShallowRef<EditorView | undefined, EditorView | undefined>;
|
|
13
13
|
}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
14
14
|
"update:modelValue": (text: string) => any;
|
|
15
|
-
save: (text: string) => any;
|
|
16
15
|
ready: (view: EditorView) => any;
|
|
16
|
+
save: (text: string) => any;
|
|
17
17
|
}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
|
|
18
18
|
"onUpdate:modelValue"?: ((text: string) => any) | undefined;
|
|
19
|
-
onSave?: ((text: string) => any) | undefined;
|
|
20
19
|
onReady?: ((view: EditorView) => any) | undefined;
|
|
20
|
+
onSave?: ((text: string) => any) | undefined;
|
|
21
21
|
}>, {
|
|
22
22
|
editable: boolean;
|
|
23
|
-
wordWrap: boolean;
|
|
24
23
|
modelValue: string;
|
|
24
|
+
wordWrap: boolean;
|
|
25
25
|
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
26
26
|
declare const _default: typeof __VLS_export;
|
|
27
27
|
//#endregion
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import { Locale, Messages } from "../i18n/index.js";
|
|
2
|
+
import { ModelSlot } from "../settings/values.js";
|
|
3
|
+
import "../settings/index.js";
|
|
4
|
+
//#region src/config/index.d.ts
|
|
5
|
+
/** Server-defined model preset (any OpenAI-compatible chat completions endpoint); its key falls back to the shared `apiKey`. */
|
|
6
|
+
export interface PresetConfig {
|
|
7
|
+
label: string;
|
|
8
|
+
endpoint: string;
|
|
9
|
+
model: string;
|
|
10
|
+
apiKey?: string;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Speech-to-text endpoint. `provider` `'openai'` (default): any OpenAI-compatible `<endpoint>/audio/transcriptions`
|
|
14
|
+
* (e.g. OpenAI `whisper-1`). `'deepgram'`: Deepgram's pre-recorded `<endpoint>/listen` (endpoint
|
|
15
|
+
* `https://api.deepgram.com/v1`, model e.g. `nova-3`). `language` (e.g. `'de'`) fixes the spoken language; without it
|
|
16
|
+
* OpenAI guesses and Deepgram detects it.
|
|
17
|
+
*/
|
|
18
|
+
export interface TranscriptionConfig {
|
|
19
|
+
provider?: 'openai' | 'deepgram';
|
|
20
|
+
endpoint: string;
|
|
21
|
+
model: string;
|
|
22
|
+
apiKey?: string;
|
|
23
|
+
language?: string;
|
|
24
|
+
}
|
|
25
|
+
export interface EditorConfig {
|
|
26
|
+
/** Language of the editor's strings: `'de'` (default) or `'en'`. Set once per app; a host that switches languages at run time recreates the editor context. */
|
|
27
|
+
locale: Locale;
|
|
28
|
+
/** Overrides of single messages by key (see `MessageKey`), applied on top of the catalog of `locale`; must be JSON-serialisable. */
|
|
29
|
+
messages?: Partial<Messages>;
|
|
30
|
+
ai: {
|
|
31
|
+
/**
|
|
32
|
+
* Server-defined model presets (any OpenAI-compatible chat completions endpoint), keyed by preset id. The key is
|
|
33
|
+
* per preset or the shared `apiKey`, both from env only (Nuxt: `NUXT_TIPTAP_EDITOR_AI_PRESETS_<ID>_API_KEY`, `<ID>` =
|
|
34
|
+
* the preset id in upper snake case, e.g. `flashLite` → `FLASH_LITE`, or `NUXT_TIPTAP_EDITOR_AI_API_KEY`). Preset ids
|
|
35
|
+
* must be camelCase so the env names map onto them. Presets named like a default (`sonnet`, `flashLite`) override its fields.
|
|
36
|
+
*/
|
|
37
|
+
presets: Record<string, PresetConfig>;
|
|
38
|
+
/** Shared key of presets without their own. Default `''` (so the env variable has a key to override). */
|
|
39
|
+
apiKey: string;
|
|
40
|
+
/** Default preset per slot; users may override in settings. The `complete` model must support assistant prefill. */
|
|
41
|
+
slots: Record<ModelSlot, string>;
|
|
42
|
+
/** Per-user limit shared by all AI endpoints: at most `max` requests per sliding `windowMs`. */
|
|
43
|
+
rateLimit: {
|
|
44
|
+
max: number;
|
|
45
|
+
windowMs: number;
|
|
46
|
+
};
|
|
47
|
+
/**
|
|
48
|
+
* Speech-to-text for audio/video Bausteine: an OpenAI-compatible `<endpoint>/audio/transcriptions` or Deepgram
|
|
49
|
+
* (`provider: 'deepgram'`; OpenRouter presets provide neither). Absent = the action and the endpoint are off.
|
|
50
|
+
* The key comes from env only (Nuxt: `NUXT_TIPTAP_EDITOR_AI_TRANSCRIPTION_API_KEY`).
|
|
51
|
+
*/
|
|
52
|
+
transcription?: TranscriptionConfig;
|
|
53
|
+
};
|
|
54
|
+
collab: {
|
|
55
|
+
/**
|
|
56
|
+
* Authenticate the `/collab/:id` websocket upgrade itself (`Identity.authenticate` with the upgrade request's
|
|
57
|
+
* headers) and refuse it with HTTP 401 for an unknown user. Default `false`: the upgrade always succeeds, the user
|
|
58
|
+
* is authenticated afterwards from the headers or the provider's `token`, and an unauthenticated socket is closed
|
|
59
|
+
* with code 4401. Enable only when every client authenticates by cookie/headers: a client that sends its identity
|
|
60
|
+
* as `collaboration.token` (no cookies) cannot connect then. Nuxt env override:
|
|
61
|
+
* `NUXT_TIPTAP_EDITOR_COLLAB_AUTHENTICATE_UPGRADE=true`.
|
|
62
|
+
*/
|
|
63
|
+
authenticateUpgrade: boolean;
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
type DeepPartial<T> = T extends object ? { [K in keyof T]?: DeepPartial<T[K]>; } : T;
|
|
67
|
+
/** What a host writes: every key optional, `undefined` (an unset env variable) means the default. */
|
|
68
|
+
export type EditorConfigInput = DeepPartial<EditorConfig>;
|
|
69
|
+
/**
|
|
70
|
+
* Applies every default once: locale `'de'`, the OpenRouter presets `sonnet` and `flashLite` with the slots that use
|
|
71
|
+
* them, 30 AI requests per user and minute, no upgrade authentication. Every preset and the transcription get an empty
|
|
72
|
+
* `apiKey` unless one is given, so an environment variable has a key to override.
|
|
73
|
+
*/
|
|
74
|
+
export declare function defineEditorConfig(input?: EditorConfigInput): EditorConfig;
|
|
75
|
+
/** What the browser may see: the language and the default model slots, never a key. */
|
|
76
|
+
export interface EditorPublicConfig {
|
|
77
|
+
locale: Locale;
|
|
78
|
+
messages?: Partial<Messages>;
|
|
79
|
+
/** Inert AI configuration: default preset per slot before the models list has answered, and whether transcription is on. */
|
|
80
|
+
ai: {
|
|
81
|
+
slots: Record<ModelSlot, string>;
|
|
82
|
+
transcription: boolean;
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
export declare function publicConfig(config: EditorConfig): EditorPublicConfig;
|
|
86
|
+
/** What the server needs, secrets included: the shape `installEditorServer` takes for `ai`, `rateLimit` and `collab`. */
|
|
87
|
+
export interface EditorServerConfig {
|
|
88
|
+
ai: {
|
|
89
|
+
presets: Record<string, PresetConfig>;
|
|
90
|
+
apiKey: string;
|
|
91
|
+
slots: Record<ModelSlot, string>;
|
|
92
|
+
transcription?: TranscriptionConfig;
|
|
93
|
+
};
|
|
94
|
+
rateLimit: {
|
|
95
|
+
max: number;
|
|
96
|
+
windowMs: number;
|
|
97
|
+
};
|
|
98
|
+
collab: {
|
|
99
|
+
authenticateUpgrade: boolean;
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
export declare function serverConfig(config: EditorConfig): EditorServerConfig;
|
|
103
|
+
//#endregion
|
|
104
|
+
export {};
|
|
105
|
+
//# sourceMappingURL=index.d.ts.map
|