@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 +1 @@
|
|
|
1
|
-
{"version":3,"file":"forge.js","names":[],"sources":["../../src/adapters/forge.ts"],"sourcesContent":["import { type AnyExtension, Editor } from '@tiptap/core'\nimport { DocumentMarkdown } from '../core'\nimport { contentToMarkdown, hasFatalDiagnostics, joinFrontmatter, type MarkdownDiagnostic, type MarkdownPolicy, markdownToContent, splitFrontmatter } from '../markdown'\nimport type {
|
|
1
|
+
{"version":3,"file":"forge.js","names":[],"sources":["../../src/adapters/forge.ts"],"sourcesContent":["import { type AnyExtension, Editor } from '@tiptap/core'\nimport { DocumentMarkdown } from '../core'\nimport { contentToMarkdown, hasFatalDiagnostics, joinFrontmatter, type MarkdownDiagnostic, type MarkdownPolicy, markdownToContent, splitFrontmatter } from '../markdown'\nimport type { CollabStateStore, AssetStore, EditorPorts, Identity, SettingsStore, ThemeStore } from '../server'\nimport { type AdapterHooks, directoryOf, identityOf } from './shared'\n\n/** A Markdown file of the host, as the host stores it: the whole text with its frontmatter, and an opaque version of that file. */\nexport interface ForgeFile {\n markdown: string\n /** Changes whenever the file's content changes (mtime and size, a hash, a revision); no NUL character. Becomes `contentVersion`. */\n version: string\n}\n\n/** Where the host keeps its Markdown documents. The adapter never touches a file system itself. */\nexport interface ForgeContent {\n /** The file behind a document id, `null` = it does not exist. */\n read(id: string): Promise<ForgeFile | null>\n /** Writes the file (frontmatter included). Only called for documents that exist. */\n write(id: string, markdown: string): Promise<void>\n /** Called after every `write` the adapter made (change notifications, indexes). */\n onWritten?(id: string): void | Promise<void>\n /** Ids of all documents, for `listContents` (the tag index). Omitted: `listContents` is empty. */\n list?(): Promise<string[]>\n}\n\n/** What the adapter delegates to a storage adapter that has no use for Markdown: the `collabState`, `assets`, `settings` and `themes` ports (the result of `createJsonAdapter` or `createDrizzleAdapter` fits). */\nexport interface ForgeState {\n collabState: CollabStateStore\n assets: AssetStore\n settings?: SettingsStore\n themes?: ThemeStore\n}\n\nexport interface ForgeAdapterOptions extends Omit<AdapterHooks, 'authenticate'> {\n content: ForgeContent\n state: ForgeState\n /**\n * The complete TipTap extension list of the Markdown conversion, e.g. `[...advancedSchemaExtensions(), MermaidBlock]`:\n * nodes and marks with their Markdown handlers. Host nodes also go to the collaboration schema through the server's\n * `schema` option (`() => [...advancedSchemaExtensions(), MermaidBlock]`).\n */\n schema: AnyExtension[]\n /** The host's session check; there is no default for a host that owns its Markdown files. */\n authenticate: Identity['authenticate']\n /** Markdown policy of the conversion (raw HTML, data URLs); the default drops both. */\n policy?: MarkdownPolicy\n /** Called with the diagnostics of every load that produced some (dropped HTML or URLs, unknown fences kept verbatim). */\n onDiagnostics?(id: string, diagnostics: MarkdownDiagnostic[]): void\n}\n\n/**\n * The editor's adapter over the host's Markdown files (concept documents, vault pages). The host keeps owning the\n * files, their locations, change notifications and access rules and passes them in as functions; this adapter does the\n * Markdown ↔ TipTap JSON conversion and the contract:\n *\n * - `loadContent` splits off the frontmatter and parses the body (`markdownToContent`); a body the conversion could not\n * keep intact (unclosed fence, malformed fence metadata) is refused with an error instead of loaded lossy.\n * - `storeContent` re-reads the file, keeps its current frontmatter verbatim, writes the serialized body and calls\n * `onWritten`. A file that is gone is not recreated, and an unchanged result is not rewritten.\n * - `contentVersion` is the file's own version, read after the write so it reflects what the editor stored.\n *\n * Yjs state, assets and settings are `state`'s. The converter is one headless editor per adapter, built on first use.\n */\nexport function createForgeAdapter(options: ForgeAdapterOptions): EditorPorts {\n const { content, state, schema, policy, onDiagnostics, authenticate, authorize } = options\n\n let converter: Editor | undefined\n // No `window` is needed as long as the editor starts from JSON content, not an HTML string.\n const editor = () => converter ??= new Editor({ content: { type: 'doc', content: [{ type: 'paragraph' }] }, extensions: [DocumentMarkdown, ...schema] })\n\n function parse(id: string, file: ForgeFile) {\n const { content: json, diagnostics } = markdownToContent(editor(), splitFrontmatter(file.markdown).body, policy ? { policy } : {})\n if (diagnostics.length) onDiagnostics?.(id, diagnostics)\n if (hasFatalDiagnostics(diagnostics)) {\n const problems = diagnostics.filter(diagnostic => diagnostic.severity === 'error').map(diagnostic => diagnostic.message)\n throw new Error(`@ecsplico/editor: document \"${id}\" cannot be converted without losing content: ${problems.join(' ')}`)\n }\n return json\n }\n\n return {\n identity: identityOf({ authenticate, authorize }),\n directory: directoryOf(options),\n\n documents: {\n async loadContent(id) {\n const file = await content.read(id)\n return file && parse(id, file)\n },\n async storeContent(id, json) {\n const current = await content.read(id)\n if (!current) return // deleted while a store was pending\n const instance = editor()\n instance.commands.setContent(json, { emitUpdate: false })\n const body = contentToMarkdown(instance)\n const markdown = joinFrontmatter(splitFrontmatter(current.markdown).frontmatter, body && `${body}\\n`)\n if (markdown === current.markdown) return\n await content.write(id, markdown)\n await content.onWritten?.(id)\n },\n async contentVersion(id) {\n return (await content.read(id))?.version ?? null\n },\n async listContents() {\n const entries = await Promise.all((await content.list?.() ?? []).map(async (id) => {\n const file = await content.read(id)\n return file && { id, content: parse(id, file) }\n }))\n return entries.filter((entry): entry is NonNullable<typeof entry> => entry !== null)\n },\n },\n\n collabState: state.collabState,\n assets: state.assets,\n // Present only when `state` has them: the routes and the settings client test for the ports.\n ...(state.settings && { settings: state.settings }),\n ...(state.themes && { themes: state.themes }),\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AA+DA,SAAgB,mBAAmB,SAA2C;CAC5E,MAAM,EAAE,SAAS,OAAO,QAAQ,QAAQ,eAAe,cAAc,cAAc;CAEnF,IAAI;CAEJ,MAAM,eAAe,cAAc,IAAI,OAAO;EAAE,SAAS;GAAE,MAAM;GAAO,SAAS,CAAC,EAAE,MAAM,YAAY,CAAC;EAAE;EAAG,YAAY,CAAC,kBAAkB,GAAG,MAAM;CAAE,CAAC;CAEvJ,SAAS,MAAM,IAAY,MAAiB;EAC1C,MAAM,EAAE,SAAS,MAAM,gBAAgB,kBAAkB,OAAO,GAAG,iBAAiB,KAAK,QAAQ,CAAC,CAAC,MAAM,SAAS,EAAE,OAAO,IAAI,CAAC,CAAC;EACjI,IAAI,YAAY,QAAQ,gBAAgB,IAAI,WAAW;EACvD,IAAI,oBAAoB,WAAW,GAAG;GACpC,MAAM,WAAW,YAAY,QAAO,eAAc,WAAW,aAAa,OAAO,CAAC,CAAC,KAAI,eAAc,WAAW,OAAO;GACvH,MAAM,IAAI,MAAM,+BAA+B,GAAG,gDAAgD,SAAS,KAAK,GAAG,GAAG;EACxH;EACA,OAAO;CACT;CAEA,OAAO;EACL,UAAU,WAAW;GAAE;GAAc;EAAU,CAAC;EAChD,WAAW,YAAY,OAAO;EAE9B,WAAW;GACT,MAAM,YAAY,IAAI;IACpB,MAAM,OAAO,MAAM,QAAQ,KAAK,EAAE;IAClC,OAAO,QAAQ,MAAM,IAAI,IAAI;GAC/B;GACA,MAAM,aAAa,IAAI,MAAM;IAC3B,MAAM,UAAU,MAAM,QAAQ,KAAK,EAAE;IACrC,IAAI,CAAC,SAAS;IACd,MAAM,WAAW,OAAO;IACxB,SAAS,SAAS,WAAW,MAAM,EAAE,YAAY,MAAM,CAAC;IACxD,MAAM,OAAO,kBAAkB,QAAQ;IACvC,MAAM,WAAW,gBAAgB,iBAAiB,QAAQ,QAAQ,CAAC,CAAC,aAAa,QAAQ,GAAG,KAAK,GAAG;IACpG,IAAI,aAAa,QAAQ,UAAU;IACnC,MAAM,QAAQ,MAAM,IAAI,QAAQ;IAChC,MAAM,QAAQ,YAAY,EAAE;GAC9B;GACA,MAAM,eAAe,IAAI;IACvB,QAAQ,MAAM,QAAQ,KAAK,EAAE,EAAA,EAAI,WAAW;GAC9C;GACA,MAAM,eAAe;IAKnB,QAAO,MAJe,QAAQ,KAAK,MAAM,QAAQ,OAAO,KAAK,CAAC,EAAA,CAAG,IAAI,OAAO,OAAO;KACjF,MAAM,OAAO,MAAM,QAAQ,KAAK,EAAE;KAClC,OAAO,QAAQ;MAAE;MAAI,SAAS,MAAM,IAAI,IAAI;KAAE;IAChD,CAAC,CAAC,EAAA,CACa,QAAQ,UAA8C,UAAU,IAAI;GACrF;EACF;EAEA,aAAa,MAAM;EACnB,QAAQ,MAAM;EAEd,GAAI,MAAM,YAAY,EAAE,UAAU,MAAM,SAAS;EACjD,GAAI,MAAM,UAAU,EAAE,QAAQ,MAAM,OAAO;CAC7C;AACF"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { EditorBackend } from "../core/backend.js";
|
|
2
|
+
import { FetchBackendOptions } from "../core/http-backend.js";
|
|
3
|
+
//#region src/adapters/http.d.ts
|
|
4
|
+
export interface HttpBackendOptions extends FetchBackendOptions {
|
|
5
|
+
/**
|
|
6
|
+
* Ask the server which capabilities it serves (`GET /api/editor/capabilities`, see `serverCapabilities`) once and drop
|
|
7
|
+
* the others from the backend, so a composition pruned by `backend` (`composeEditor`) matches the server. The request
|
|
8
|
+
* settles `backend.ready`, which `createEditorContext` awaits. A failed probe keeps every capability and warns once.
|
|
9
|
+
* Default `false`: no request, every capability assumed (an unserved one answers 404/501 on use).
|
|
10
|
+
*/
|
|
11
|
+
probe?: boolean;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Every backend capability over HTTP. `fetch` sends the requests (default: the platform `fetch`; a Nuxt app passes `useNuxtApp().$fetch`),
|
|
15
|
+
* `base` prefixes every path (`https://api.example.com`; default `''`, same origin). Failed requests reject with
|
|
16
|
+
* `BackendError` (`status`); a missing document loads as `null`.
|
|
17
|
+
*/
|
|
18
|
+
export declare function createHttpBackend(options?: HttpBackendOptions): EditorBackend;
|
|
19
|
+
//#endregion
|
|
20
|
+
//# sourceMappingURL=http.d.ts.map
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { CAPABILITIES_ROUTE, COLLAB_PATH, commentsUrl } from "../core/api-routes.js";
|
|
2
|
+
import { createFetchBackend, createTransport } from "../core/http-backend.js";
|
|
3
|
+
import { BACKEND_CAPABILITIES } from "../core/backend-capability.js";
|
|
4
|
+
import { createRestCommentsModel } from "./comments/rest-model.js";
|
|
5
|
+
import { HocuspocusProvider } from "@hocuspocus/provider";
|
|
6
|
+
import * as Y from "yjs";
|
|
7
|
+
//#region src/adapters/http.ts
|
|
8
|
+
/**
|
|
9
|
+
* Every backend capability over HTTP. `fetch` sends the requests (default: the platform `fetch`; a Nuxt app passes `useNuxtApp().$fetch`),
|
|
10
|
+
* `base` prefixes every path (`https://api.example.com`; default `''`, same origin). Failed requests reject with
|
|
11
|
+
* `BackendError` (`status`); a missing document loads as `null`.
|
|
12
|
+
*/
|
|
13
|
+
function createHttpBackend(options = {}) {
|
|
14
|
+
const { base = "" } = options;
|
|
15
|
+
const transport = createTransport(options.fetch);
|
|
16
|
+
const data = createFetchBackend(options);
|
|
17
|
+
const collabUrl = `${(base || (typeof location === "undefined" ? "" : location.origin)).replace(/^http/, "ws")}${COLLAB_PATH}`;
|
|
18
|
+
const backend = {
|
|
19
|
+
...data,
|
|
20
|
+
collaboration: { connect(id, token) {
|
|
21
|
+
const ydoc = new Y.Doc();
|
|
22
|
+
const provider = new HocuspocusProvider({
|
|
23
|
+
url: `${collabUrl}/${encodeURIComponent(id)}`,
|
|
24
|
+
name: id,
|
|
25
|
+
document: ydoc,
|
|
26
|
+
...token !== void 0 && { token }
|
|
27
|
+
});
|
|
28
|
+
return {
|
|
29
|
+
ydoc,
|
|
30
|
+
provider,
|
|
31
|
+
dispose() {
|
|
32
|
+
provider.destroy();
|
|
33
|
+
ydoc.destroy();
|
|
34
|
+
}
|
|
35
|
+
};
|
|
36
|
+
} },
|
|
37
|
+
comments: (documentId, { user, canComment, getEditor, onError }) => createRestCommentsModel({
|
|
38
|
+
fetch: async (url, init) => {
|
|
39
|
+
const response = await transport.send(`${base}${url}`, init);
|
|
40
|
+
return {
|
|
41
|
+
ok: response.ok,
|
|
42
|
+
status: response.status,
|
|
43
|
+
json: () => response.json()
|
|
44
|
+
};
|
|
45
|
+
},
|
|
46
|
+
documentId,
|
|
47
|
+
endpoint: commentsUrl(documentId),
|
|
48
|
+
user,
|
|
49
|
+
canComment,
|
|
50
|
+
getEditor,
|
|
51
|
+
...onError && { onError }
|
|
52
|
+
}),
|
|
53
|
+
...options.probe && { ready: Promise.resolve().then(async () => {
|
|
54
|
+
try {
|
|
55
|
+
const served = await (await transport.request(`${base}${CAPABILITIES_ROUTE}`)).json();
|
|
56
|
+
if (!Array.isArray(served)) throw new TypeError("the answer is not a list of capabilities");
|
|
57
|
+
for (const capability of BACKEND_CAPABILITIES) if (!served.includes(capability)) delete backend[capability];
|
|
58
|
+
} catch (error) {
|
|
59
|
+
console.warn("@ecsplico/editor: the capability probe of the \"http\" backend failed; every capability is kept", error);
|
|
60
|
+
}
|
|
61
|
+
}) }
|
|
62
|
+
};
|
|
63
|
+
return backend;
|
|
64
|
+
}
|
|
65
|
+
//#endregion
|
|
66
|
+
export { createHttpBackend };
|
|
67
|
+
|
|
68
|
+
//# sourceMappingURL=http.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"http.js","names":[],"sources":["../../src/adapters/http.ts"],"sourcesContent":["import { HocuspocusProvider } from '@hocuspocus/provider'\nimport * as Y from 'yjs'\nimport type { EditorBackend } from '../core/backend'\nimport { BACKEND_CAPABILITIES } from '../core/backend-capability'\nimport { createFetchBackend, createTransport, type FetchBackendOptions } from '../core/http-backend'\nimport { CAPABILITIES_ROUTE, COLLAB_PATH, commentsUrl } from '../core/api-routes'\nimport { createRestCommentsModel } from './comments/rest-model'\n\n// The HTTP adapter of `EditorBackend`: the `/api/editor` and `/api/ai` routes that the Nuxt module (`@ecsplico/editor/nuxt`)\n// and `installEditorServer` (`@ecsplico/editor/server/nitro`) serve, the collaboration websocket and the comments endpoint.\n\nexport interface HttpBackendOptions extends FetchBackendOptions {\n /**\n * Ask the server which capabilities it serves (`GET /api/editor/capabilities`, see `serverCapabilities`) once and drop\n * the others from the backend, so a composition pruned by `backend` (`composeEditor`) matches the server. The request\n * settles `backend.ready`, which `createEditorContext` awaits. A failed probe keeps every capability and warns once.\n * Default `false`: no request, every capability assumed (an unserved one answers 404/501 on use).\n */\n probe?: boolean\n}\n\n/**\n * Every backend capability over HTTP. `fetch` sends the requests (default: the platform `fetch`; a Nuxt app passes `useNuxtApp().$fetch`),\n * `base` prefixes every path (`https://api.example.com`; default `''`, same origin). Failed requests reject with\n * `BackendError` (`status`); a missing document loads as `null`.\n */\nexport function createHttpBackend(options: HttpBackendOptions = {}): EditorBackend {\n const { base = '' } = options\n const transport = createTransport(options.fetch)\n const data = createFetchBackend(options)\n // The websocket lives next to the API: `http(s)://host` → `ws(s)://host`; without a base, the page's own origin.\n const origin = base || (typeof location === 'undefined' ? '' : location.origin)\n const collabUrl = `${origin.replace(/^http/, 'ws')}${COLLAB_PATH}`\n\n const backend: EditorBackend = {\n ...data,\n collaboration: {\n connect(id, token) {\n const ydoc = new Y.Doc()\n const provider = new HocuspocusProvider({ url: `${collabUrl}/${encodeURIComponent(id)}`, name: id, document: ydoc, ...(token !== undefined && { token }) })\n return {\n ydoc,\n provider,\n dispose() {\n provider.destroy()\n ydoc.destroy()\n },\n }\n },\n },\n comments: (documentId, { user, canComment, getEditor, onError }) => createRestCommentsModel({\n // The model reads `ok`, `status` and the parsed JSON body; a refusal is a result here, not an exception.\n fetch: async (url, init) => {\n const response = await transport.send(`${base}${url}`, init)\n return { ok: response.ok, status: response.status, json: () => response.json() as Promise<unknown> }\n },\n documentId,\n endpoint: commentsUrl(documentId),\n user,\n canComment,\n getEditor,\n ...(onError && { onError }),\n }),\n ...(options.probe && {\n // Runs after the object is built (the microtask): it prunes `backend` itself, the one the context holds.\n ready: Promise.resolve().then(async () => {\n try {\n const served: unknown = await (await transport.request(`${base}${CAPABILITIES_ROUTE}`)).json()\n if (!Array.isArray(served)) throw new TypeError('the answer is not a list of capabilities')\n for (const capability of BACKEND_CAPABILITIES) {\n if (!served.includes(capability)) delete backend[capability]\n }\n }\n catch (error) {\n console.warn('@ecsplico/editor: the capability probe of the \"http\" backend failed; every capability is kept', error)\n }\n }),\n }),\n }\n return backend\n}\n"],"mappings":";;;;;;;;;;;;AA0BA,SAAgB,kBAAkB,UAA8B,CAAC,GAAkB;CACjF,MAAM,EAAE,OAAO,OAAO;CACtB,MAAM,YAAY,gBAAgB,QAAQ,KAAK;CAC/C,MAAM,OAAO,mBAAmB,OAAO;CAGvC,MAAM,YAAY,IADH,SAAS,OAAO,aAAa,cAAc,KAAK,SAAS,QAAA,CAC5C,QAAQ,SAAS,IAAI,IAAI;CAErD,MAAM,UAAyB;EAC7B,GAAG;EACH,eAAe,EACb,QAAQ,IAAI,OAAO;GACjB,MAAM,OAAO,IAAI,EAAE,IAAI;GACvB,MAAM,WAAW,IAAI,mBAAmB;IAAE,KAAK,GAAG,UAAU,GAAG,mBAAmB,EAAE;IAAK,MAAM;IAAI,UAAU;IAAM,GAAI,UAAU,KAAA,KAAa,EAAE,MAAM;GAAG,CAAC;GAC1J,OAAO;IACL;IACA;IACA,UAAU;KACR,SAAS,QAAQ;KACjB,KAAK,QAAQ;IACf;GACF;EACF,EACF;EACA,WAAW,YAAY,EAAE,MAAM,YAAY,WAAW,cAAc,wBAAwB;GAE1F,OAAO,OAAO,KAAK,SAAS;IAC1B,MAAM,WAAW,MAAM,UAAU,KAAK,GAAG,OAAO,OAAO,IAAI;IAC3D,OAAO;KAAE,IAAI,SAAS;KAAI,QAAQ,SAAS;KAAQ,YAAY,SAAS,KAAK;IAAsB;GACrG;GACA;GACA,UAAU,YAAY,UAAU;GAChC;GACA;GACA;GACA,GAAI,WAAW,EAAE,QAAQ;EAC3B,CAAC;EACD,GAAI,QAAQ,SAAS,EAEnB,OAAO,QAAQ,QAAQ,CAAC,CAAC,KAAK,YAAY;GACxC,IAAI;IACF,MAAM,SAAkB,OAAO,MAAM,UAAU,QAAQ,GAAG,OAAO,oBAAoB,EAAA,CAAG,KAAK;IAC7F,IAAI,CAAC,MAAM,QAAQ,MAAM,GAAG,MAAM,IAAI,UAAU,0CAA0C;IAC1F,KAAK,MAAM,cAAc,sBACvB,IAAI,CAAC,OAAO,SAAS,UAAU,GAAG,OAAO,QAAQ;GAErD,SACO,OAAO;IACZ,QAAQ,KAAK,mGAAiG,KAAK;GACrH;EACF,CAAC,EACH;CACF;CACA,OAAO;AACT"}
|
package/dist/adapters/index.d.ts
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import { AnchorSource, AnchorTransaction, DocRange, OrphanedAnchor, PointAnchor, PortableAnchor, RangeAnchor } from "./anchors.js";
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
2
|
+
import { AuthenticateRequest } from "../server/auth.js";
|
|
3
|
+
import { Annotation, Comment, CommentAction, CommentStore, CommentThread, CreateThreadInput, Discussion, NewThread, ThreadStatus } from "./comments/types.js";
|
|
4
|
+
import { DocumentAdmin, EditorPorts } from "../server/ports.js";
|
|
4
5
|
import "../server/index.js";
|
|
5
|
-
import { AdapterHooks,
|
|
6
|
+
import { AdapterHooks, StoredPorts } from "./shared.js";
|
|
6
7
|
import { DrizzleAdapterOptions, EditorDb, EditorTables } from "./drizzle.js";
|
|
7
|
-
import { Annotation, Comment, CommentAction, CommentStore, CommentThread, CreateThreadInput, Discussion, NewThread, ThreadStatus } from "./comments/types.js";
|
|
8
8
|
import { CommentTables, DrizzleCommentStoreOptions } from "./comments/drizzle.js";
|
|
9
9
|
import { JsonCommentStoreOptions } from "./comments/json.js";
|
|
10
10
|
import { CommentsRequest, CommentsResponse } from "./comments/server.js";
|
|
11
11
|
import { ForgeAdapterOptions, ForgeContent, ForgeFile, ForgeState } from "./forge.js";
|
|
12
12
|
import { JsonAdapterOptions } from "./json.js";
|
|
13
|
-
export type { AdapterHooks, AnchorSource, AnchorTransaction, Annotation, AuthenticateRequest, Comment, CommentAction, CommentStore, CommentTables, CommentThread,
|
|
13
|
+
export type { AdapterHooks, AnchorSource, AnchorTransaction, Annotation, AuthenticateRequest, Comment, CommentAction, CommentStore, CommentTables, CommentThread, CommentsRequest, CommentsResponse, CreateThreadInput, Discussion, DocRange, DocumentAdmin, DrizzleAdapterOptions, DrizzleCommentStoreOptions, EditorDb, EditorPorts, EditorTables, ForgeAdapterOptions, ForgeContent, ForgeFile, ForgeState, JsonAdapterOptions, JsonCommentStoreOptions, NewThread, OrphanedAnchor, PointAnchor, PortableAnchor, RangeAnchor, StoredPorts, ThreadStatus };
|
package/dist/adapters/json.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { AdapterHooks,
|
|
1
|
+
import { AdapterHooks, StoredPorts } from "./shared.js";
|
|
2
2
|
//#region src/adapters/json.d.ts
|
|
3
3
|
export interface JsonAdapterOptions extends AdapterHooks {
|
|
4
4
|
/** Directory the adapter owns; created on demand. Single node only: the files are not coordinated across processes. */
|
|
@@ -17,8 +17,8 @@ export interface JsonAdapterOptions extends AdapterHooks {
|
|
|
17
17
|
* A missing file reads as `null`; every write goes through a temp file and a rename. `contentVersion` is the content
|
|
18
18
|
* file's modification time (nanoseconds) and size, read after every write the editor makes, so a document edited by
|
|
19
19
|
* hand or by another tool invalidates the stored Yjs state. `storeContent` only updates existing documents: create
|
|
20
|
-
* them with `putDocument`. The adapter has no theme library (the themes routes
|
|
20
|
+
* them with `putDocument`. The adapter has no theme library (the themes routes are not mounted).
|
|
21
21
|
*/
|
|
22
|
-
export declare function createJsonAdapter(options: JsonAdapterOptions):
|
|
22
|
+
export declare function createJsonAdapter(options: JsonAdapterOptions): StoredPorts;
|
|
23
23
|
//#endregion
|
|
24
24
|
//# sourceMappingURL=json.d.ts.map
|
package/dist/adapters/json.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { bytesOf,
|
|
1
|
+
import { bytesOf, directoryOf, identityOf, settingsKey } from "./shared.js";
|
|
2
2
|
import { isMissing, readOrNull, writeAtomic } from "./files.js";
|
|
3
3
|
import { promises } from "node:fs";
|
|
4
4
|
import path from "node:path";
|
|
@@ -47,7 +47,7 @@ function keyedLock() {
|
|
|
47
47
|
* A missing file reads as `null`; every write goes through a temp file and a rename. `contentVersion` is the content
|
|
48
48
|
* file's modification time (nanoseconds) and size, read after every write the editor makes, so a document edited by
|
|
49
49
|
* hand or by another tool invalidates the stored Yjs state. `storeContent` only updates existing documents: create
|
|
50
|
-
* them with `putDocument`. The adapter has no theme library (the themes routes
|
|
50
|
+
* them with `putDocument`. The adapter has no theme library (the themes routes are not mounted).
|
|
51
51
|
*/
|
|
52
52
|
function createJsonAdapter(options) {
|
|
53
53
|
const root = path.resolve(options.dir);
|
|
@@ -70,56 +70,65 @@ function createJsonAdapter(options) {
|
|
|
70
70
|
}
|
|
71
71
|
const loadContent = async (id) => readJson(contentFile(id));
|
|
72
72
|
return {
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
73
|
+
identity: identityOf(options),
|
|
74
|
+
directory: directoryOf(options),
|
|
75
|
+
documents: {
|
|
76
|
+
loadContent,
|
|
77
|
+
storeContent: (id, content) => locked(id, async () => {
|
|
78
|
+
if (!await promises.stat(contentFile(id)).then(() => true, () => false)) return;
|
|
79
|
+
await writeAtomic(contentFile(id), JSON.stringify(content));
|
|
80
|
+
}),
|
|
81
|
+
async contentVersion(id) {
|
|
82
|
+
try {
|
|
83
|
+
const { mtimeNs, size } = await promises.stat(contentFile(id), { bigint: true });
|
|
84
|
+
return `${mtimeNs}:${size}`;
|
|
85
|
+
} catch (error) {
|
|
86
|
+
if (isMissing(error)) return null;
|
|
87
|
+
throw error;
|
|
88
|
+
}
|
|
89
|
+
},
|
|
90
|
+
async listContents() {
|
|
91
|
+
return (await Promise.all((await listDocumentIds()).map(async (id) => ({
|
|
92
|
+
id,
|
|
93
|
+
content: await loadContent(id)
|
|
94
|
+
})))).filter((entry) => entry.content !== null);
|
|
95
|
+
},
|
|
96
|
+
putDocument: (id, content) => locked(id, () => writeAtomic(contentFile(id), JSON.stringify(content))),
|
|
97
|
+
deleteDocument: (id) => locked(id, async () => {
|
|
98
|
+
await promises.rm(contentFile(id), { force: true });
|
|
99
|
+
await promises.rm(stateFile(id), { force: true });
|
|
100
|
+
await promises.rm(assetDir(id), {
|
|
101
|
+
recursive: true,
|
|
102
|
+
force: true
|
|
103
|
+
});
|
|
104
|
+
}),
|
|
105
|
+
listDocumentIds
|
|
97
106
|
},
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
107
|
+
collabState: {
|
|
108
|
+
async loadState(id) {
|
|
109
|
+
const data = await readOrNull(stateFile(id));
|
|
110
|
+
return data && bytesOf(data);
|
|
111
|
+
},
|
|
112
|
+
storeState: async (id, state) => writeAtomic(stateFile(id), state),
|
|
113
|
+
removeState: async (id) => promises.rm(stateFile(id), { force: true })
|
|
103
114
|
},
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
record,
|
|
108
|
-
|
|
109
|
-
|
|
115
|
+
assets: {
|
|
116
|
+
async storeAsset(id, { data, ...record }) {
|
|
117
|
+
await writeAtomic(assetFile(id, record.name), data);
|
|
118
|
+
await writeAtomic(recordFile(id, record.name), JSON.stringify(record));
|
|
119
|
+
},
|
|
120
|
+
async loadAsset(id, name) {
|
|
121
|
+
const [record, data] = await Promise.all([readJson(recordFile(id, name)), readOrNull(assetFile(id, name))]);
|
|
122
|
+
return record && data ? {
|
|
123
|
+
record,
|
|
124
|
+
data
|
|
125
|
+
} : null;
|
|
126
|
+
}
|
|
110
127
|
},
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
await promises.rm(contentFile(id), { force: true });
|
|
116
|
-
await promises.rm(stateFile(id), { force: true });
|
|
117
|
-
await promises.rm(assetDir(id), {
|
|
118
|
-
recursive: true,
|
|
119
|
-
force: true
|
|
120
|
-
});
|
|
121
|
-
}),
|
|
122
|
-
listDocumentIds
|
|
128
|
+
settings: {
|
|
129
|
+
loadSettings: async (user) => readJson(settingsFile(user)),
|
|
130
|
+
storeSettings: async (user, settings) => writeAtomic(settingsFile(user), JSON.stringify(settings))
|
|
131
|
+
}
|
|
123
132
|
};
|
|
124
133
|
}
|
|
125
134
|
//#endregion
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"json.js","names":["fs"],"sources":["../../src/adapters/json.ts"],"sourcesContent":["import { type Dirent, promises as fs } from 'node:fs'\nimport path from 'node:path'\nimport type { JSONContent } from '@tiptap/core'\nimport type { AssetRecord } from '../features/media/schema'\nimport { isMissing, readOrNull, writeAtomic } from './files'\nimport { type AdapterHooks, bytesOf,
|
|
1
|
+
{"version":3,"file":"json.js","names":["fs"],"sources":["../../src/adapters/json.ts"],"sourcesContent":["import { type Dirent, promises as fs } from 'node:fs'\nimport path from 'node:path'\nimport type { JSONContent } from '@tiptap/core'\nimport type { AssetRecord } from '../features/media/schema'\nimport { isMissing, readOrNull, writeAtomic } from './files'\nimport { type AdapterHooks, bytesOf, directoryOf, identityOf, settingsKey, type StoredPorts } from './shared'\n\nexport interface JsonAdapterOptions extends AdapterHooks {\n /** Directory the adapter owns; created on demand. Single node only: the files are not coordinated across processes. */\n dir: string\n}\n\nconst CONTENT_EXT = '.json'\nconst STATE_EXT = '.ystate'\nconst SETTINGS_DIR = 'settings'\nconst ASSETS_DIR = 'assets'\nconst RECORDS_DIR = '.records'\n\n/**\n * A file name for `value`: percent-encoded (reversible, no separators, no `.`/`..`), and a leading dot escaped so no\n * key ever collides with the dot-named temp files and the `.records` directory.\n */\nfunction fileKey(value: string): string {\n if (value === '') throw new TypeError('@ecsplico/editor: empty id')\n const encoded = encodeURIComponent(value)\n return encoded.startsWith('.') ? `%2E${encoded.slice(1)}` : encoded\n}\n\nasync function readJson<T>(file: string): Promise<T | null> {\n const data = await readOrNull(file)\n return data === null ? null : JSON.parse(data.toString('utf8')) as T\n}\n\n/** Runs the actions of one key one after another, so a delete cannot interleave with an update of the same document. */\nfunction keyedLock() {\n const tails = new Map<string, Promise<unknown>>()\n return <T>(key: string, action: () => Promise<T>): Promise<T> => {\n const run = (tails.get(key) ?? Promise.resolve()).then(action, action)\n const tail = run.catch(() => {})\n tails.set(key, tail)\n void tail.then(() => {\n if (tails.get(key) === tail) tails.delete(key)\n })\n return run\n }\n}\n\n/**\n * The editor's adapter on plain files under `dir`:\n *\n * <dir>/<id>.json TipTap JSON of a document\n * <dir>/<id>.ystate the collab server's state bytes\n * <dir>/settings/<user>.json per-user editor settings\n * <dir>/assets/<id>/<name> an uploaded file\n * <dir>/assets/<id>/.records/<name>.json its `AssetRecord`\n *\n * Ids, user keys and asset names are percent-encoded into file names (`a/b` → `a%2Fb.json`), so no input leaves `dir`.\n * A missing file reads as `null`; every write goes through a temp file and a rename. `contentVersion` is the content\n * file's modification time (nanoseconds) and size, read after every write the editor makes, so a document edited by\n * hand or by another tool invalidates the stored Yjs state. `storeContent` only updates existing documents: create\n * them with `putDocument`. The adapter has no theme library (the themes routes are not mounted).\n */\nexport function createJsonAdapter(options: JsonAdapterOptions): StoredPorts {\n const root = path.resolve(options.dir)\n const contentFile = (id: string) => path.join(root, `${fileKey(id)}${CONTENT_EXT}`)\n const stateFile = (id: string) => path.join(root, `${fileKey(id)}${STATE_EXT}`)\n const settingsFile = (user: object) => path.join(root, SETTINGS_DIR, `${fileKey(settingsKey(user))}${CONTENT_EXT}`)\n const assetDir = (id: string) => path.join(root, ASSETS_DIR, fileKey(id))\n const assetFile = (id: string, name: string) => path.join(assetDir(id), fileKey(name))\n const recordFile = (id: string, name: string) => path.join(assetDir(id), RECORDS_DIR, `${fileKey(name)}${CONTENT_EXT}`)\n const locked = keyedLock()\n\n async function listDocumentIds(): Promise<string[]> {\n let entries: Dirent[]\n try {\n entries = await fs.readdir(root, { withFileTypes: true })\n }\n catch (error) {\n if (isMissing(error)) return []\n throw error\n }\n return entries\n .filter(entry => entry.isFile() && !entry.name.startsWith('.') && entry.name.endsWith(CONTENT_EXT))\n .map(entry => decodeURIComponent(entry.name.slice(0, -CONTENT_EXT.length)))\n .sort()\n }\n\n const loadContent = async (id: string) => readJson<JSONContent>(contentFile(id))\n\n return {\n identity: identityOf(options),\n directory: directoryOf(options),\n\n documents: {\n loadContent,\n storeContent: (id, content) => locked(id, async () => {\n // Deleted while a store was pending: writing would resurrect the document.\n if (!await fs.stat(contentFile(id)).then(() => true, () => false)) return\n await writeAtomic(contentFile(id), JSON.stringify(content))\n }),\n async contentVersion(id) {\n try {\n const { mtimeNs, size } = await fs.stat(contentFile(id), { bigint: true })\n return `${mtimeNs}:${size}`\n }\n catch (error) {\n if (isMissing(error)) return null\n throw error\n }\n },\n async listContents() {\n const contents = await Promise.all((await listDocumentIds()).map(async id => ({ id, content: await loadContent(id) })))\n return contents.filter((entry): entry is { id: string, content: JSONContent } => entry.content !== null)\n },\n\n putDocument: (id, content) => locked(id, () => writeAtomic(contentFile(id), JSON.stringify(content))),\n deleteDocument: id => locked(id, async () => {\n await fs.rm(contentFile(id), { force: true })\n await fs.rm(stateFile(id), { force: true })\n await fs.rm(assetDir(id), { recursive: true, force: true })\n }),\n listDocumentIds,\n },\n\n collabState: {\n async loadState(id) {\n const data = await readOrNull(stateFile(id))\n return data && bytesOf(data)\n },\n storeState: async (id, state) => writeAtomic(stateFile(id), state),\n removeState: async id => fs.rm(stateFile(id), { force: true }),\n },\n\n assets: {\n async storeAsset(id, { data, ...record }) {\n await writeAtomic(assetFile(id, record.name), data)\n await writeAtomic(recordFile(id, record.name), JSON.stringify(record))\n },\n async loadAsset(id, name) {\n const [record, data] = await Promise.all([readJson<AssetRecord>(recordFile(id, name)), readOrNull(assetFile(id, name))])\n return record && data ? { record, data } : null\n },\n },\n\n settings: {\n loadSettings: async user => readJson(settingsFile(user)),\n storeSettings: async (user, settings) => writeAtomic(settingsFile(user), JSON.stringify(settings)),\n },\n }\n}\n"],"mappings":";;;;;AAYA,MAAM,cAAc;AACpB,MAAM,YAAY;AAClB,MAAM,eAAe;AACrB,MAAM,aAAa;AACnB,MAAM,cAAc;;;;;AAMpB,SAAS,QAAQ,OAAuB;CACtC,IAAI,UAAU,IAAI,MAAM,IAAI,UAAU,4BAA4B;CAClE,MAAM,UAAU,mBAAmB,KAAK;CACxC,OAAO,QAAQ,WAAW,GAAG,IAAI,MAAM,QAAQ,MAAM,CAAC,MAAM;AAC9D;AAEA,eAAe,SAAY,MAAiC;CAC1D,MAAM,OAAO,MAAM,WAAW,IAAI;CAClC,OAAO,SAAS,OAAO,OAAO,KAAK,MAAM,KAAK,SAAS,MAAM,CAAC;AAChE;;AAGA,SAAS,YAAY;CACnB,MAAM,wBAAQ,IAAI,IAA8B;CAChD,QAAW,KAAa,WAAyC;EAC/D,MAAM,OAAO,MAAM,IAAI,GAAG,KAAK,QAAQ,QAAQ,EAAA,CAAG,KAAK,QAAQ,MAAM;EACrE,MAAM,OAAO,IAAI,YAAY,CAAC,CAAC;EAC/B,MAAM,IAAI,KAAK,IAAI;EACnB,KAAU,WAAW;GACnB,IAAI,MAAM,IAAI,GAAG,MAAM,MAAM,MAAM,OAAO,GAAG;EAC/C,CAAC;EACD,OAAO;CACT;AACF;;;;;;;;;;;;;;;;AAiBA,SAAgB,kBAAkB,SAA0C;CAC1E,MAAM,OAAO,KAAK,QAAQ,QAAQ,GAAG;CACrC,MAAM,eAAe,OAAe,KAAK,KAAK,MAAM,GAAG,QAAQ,EAAE,IAAI,aAAa;CAClF,MAAM,aAAa,OAAe,KAAK,KAAK,MAAM,GAAG,QAAQ,EAAE,IAAI,WAAW;CAC9E,MAAM,gBAAgB,SAAiB,KAAK,KAAK,MAAM,cAAc,GAAG,QAAQ,YAAY,IAAI,CAAC,IAAI,aAAa;CAClH,MAAM,YAAY,OAAe,KAAK,KAAK,MAAM,YAAY,QAAQ,EAAE,CAAC;CACxE,MAAM,aAAa,IAAY,SAAiB,KAAK,KAAK,SAAS,EAAE,GAAG,QAAQ,IAAI,CAAC;CACrF,MAAM,cAAc,IAAY,SAAiB,KAAK,KAAK,SAAS,EAAE,GAAG,aAAa,GAAG,QAAQ,IAAI,IAAI,aAAa;CACtH,MAAM,SAAS,UAAU;CAEzB,eAAe,kBAAqC;EAClD,IAAI;EACJ,IAAI;GACF,UAAU,MAAMA,SAAG,QAAQ,MAAM,EAAE,eAAe,KAAK,CAAC;EAC1D,SACO,OAAO;GACZ,IAAI,UAAU,KAAK,GAAG,OAAO,CAAC;GAC9B,MAAM;EACR;EACA,OAAO,QACJ,QAAO,UAAS,MAAM,OAAO,KAAK,CAAC,MAAM,KAAK,WAAW,GAAG,KAAK,MAAM,KAAK,SAAS,WAAW,CAAC,CAAC,CAClG,KAAI,UAAS,mBAAmB,MAAM,KAAK,MAAM,GAAG,EAAmB,CAAC,CAAC,CAAC,CAC1E,KAAK;CACV;CAEA,MAAM,cAAc,OAAO,OAAe,SAAsB,YAAY,EAAE,CAAC;CAE/E,OAAO;EACL,UAAU,WAAW,OAAO;EAC5B,WAAW,YAAY,OAAO;EAE9B,WAAW;GACT;GACA,eAAe,IAAI,YAAY,OAAO,IAAI,YAAY;IAEpD,IAAI,CAAC,MAAMA,SAAG,KAAK,YAAY,EAAE,CAAC,CAAC,CAAC,WAAW,YAAY,KAAK,GAAG;IACnE,MAAM,YAAY,YAAY,EAAE,GAAG,KAAK,UAAU,OAAO,CAAC;GAC5D,CAAC;GACD,MAAM,eAAe,IAAI;IACvB,IAAI;KACF,MAAM,EAAE,SAAS,SAAS,MAAMA,SAAG,KAAK,YAAY,EAAE,GAAG,EAAE,QAAQ,KAAK,CAAC;KACzE,OAAO,GAAG,QAAQ,GAAG;IACvB,SACO,OAAO;KACZ,IAAI,UAAU,KAAK,GAAG,OAAO;KAC7B,MAAM;IACR;GACF;GACA,MAAM,eAAe;IAEnB,QAAO,MADgB,QAAQ,KAAK,MAAM,gBAAgB,EAAA,CAAG,IAAI,OAAM,QAAO;KAAE;KAAI,SAAS,MAAM,YAAY,EAAE;IAAE,EAAE,CAAC,EAAA,CACtG,QAAQ,UAAyD,MAAM,YAAY,IAAI;GACzG;GAEA,cAAc,IAAI,YAAY,OAAO,UAAU,YAAY,YAAY,EAAE,GAAG,KAAK,UAAU,OAAO,CAAC,CAAC;GACpG,iBAAgB,OAAM,OAAO,IAAI,YAAY;IAC3C,MAAMA,SAAG,GAAG,YAAY,EAAE,GAAG,EAAE,OAAO,KAAK,CAAC;IAC5C,MAAMA,SAAG,GAAG,UAAU,EAAE,GAAG,EAAE,OAAO,KAAK,CAAC;IAC1C,MAAMA,SAAG,GAAG,SAAS,EAAE,GAAG;KAAE,WAAW;KAAM,OAAO;IAAK,CAAC;GAC5D,CAAC;GACD;EACF;EAEA,aAAa;GACX,MAAM,UAAU,IAAI;IAClB,MAAM,OAAO,MAAM,WAAW,UAAU,EAAE,CAAC;IAC3C,OAAO,QAAQ,QAAQ,IAAI;GAC7B;GACA,YAAY,OAAO,IAAI,UAAU,YAAY,UAAU,EAAE,GAAG,KAAK;GACjE,aAAa,OAAM,OAAMA,SAAG,GAAG,UAAU,EAAE,GAAG,EAAE,OAAO,KAAK,CAAC;EAC/D;EAEA,QAAQ;GACN,MAAM,WAAW,IAAI,EAAE,MAAM,GAAG,UAAU;IACxC,MAAM,YAAY,UAAU,IAAI,OAAO,IAAI,GAAG,IAAI;IAClD,MAAM,YAAY,WAAW,IAAI,OAAO,IAAI,GAAG,KAAK,UAAU,MAAM,CAAC;GACvE;GACA,MAAM,UAAU,IAAI,MAAM;IACxB,MAAM,CAAC,QAAQ,QAAQ,MAAM,QAAQ,IAAI,CAAC,SAAsB,WAAW,IAAI,IAAI,CAAC,GAAG,WAAW,UAAU,IAAI,IAAI,CAAC,CAAC,CAAC;IACvH,OAAO,UAAU,OAAO;KAAE;KAAQ;IAAK,IAAI;GAC7C;EACF;EAEA,UAAU;GACR,cAAc,OAAM,SAAQ,SAAS,aAAa,IAAI,CAAC;GACvD,eAAe,OAAO,MAAM,aAAa,YAAY,aAAa,IAAI,GAAG,KAAK,UAAU,QAAQ,CAAC;EACnG;CACF;AACF"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { EditorBackend } from "../core/backend.js";
|
|
2
|
+
import { MentionUser } from "../core/backend-types.js";
|
|
3
|
+
import { JSONContent } from "@tiptap/core";
|
|
4
|
+
//#region src/adapters/memory.d.ts
|
|
5
|
+
export interface MemoryBackendSeed {
|
|
6
|
+
/** Documents by id, as `documents.load` returns them. */
|
|
7
|
+
documents?: Record<string, JSONContent>;
|
|
8
|
+
/** The people `@` offers. */
|
|
9
|
+
users?: readonly MentionUser[];
|
|
10
|
+
/** The tags `#` offers (normalized like the server's). */
|
|
11
|
+
tags?: readonly string[];
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* An `EditorBackend` that keeps everything in memory: `documents` (a Map seeded from `seed.documents`; `load` answers a
|
|
15
|
+
* copy, `null` for an unknown id), `assets` (`upload` answers a `blob:` URL of the file, valid for the page's life),
|
|
16
|
+
* `users` and `tags` (case-insensitive lookups over the seed, prefix matches first) and `settings` (`load` answers
|
|
17
|
+
* `null` until something was saved).
|
|
18
|
+
*/
|
|
19
|
+
export declare function createMemoryBackend(seed?: MemoryBackendSeed): EditorBackend;
|
|
20
|
+
//#endregion
|
|
21
|
+
//# sourceMappingURL=memory.d.ts.map
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { normalizeTagName } from "../core/tag-name.js";
|
|
2
|
+
//#region src/adapters/memory.ts
|
|
3
|
+
/** The most suggestions one lookup returns, as the HTTP routes. */
|
|
4
|
+
const MAX_SUGGESTIONS = 20;
|
|
5
|
+
/** Prefix matches first, then the other substring matches; the order within each group is kept. */
|
|
6
|
+
function prefixFirst(items, needle, text) {
|
|
7
|
+
const matches = items.filter((item) => text(item).includes(needle));
|
|
8
|
+
const prefixed = matches.filter((item) => text(item).startsWith(needle));
|
|
9
|
+
return [...prefixed, ...matches.filter((item) => !prefixed.includes(item))].slice(0, MAX_SUGGESTIONS);
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* An `EditorBackend` that keeps everything in memory: `documents` (a Map seeded from `seed.documents`; `load` answers a
|
|
13
|
+
* copy, `null` for an unknown id), `assets` (`upload` answers a `blob:` URL of the file, valid for the page's life),
|
|
14
|
+
* `users` and `tags` (case-insensitive lookups over the seed, prefix matches first) and `settings` (`load` answers
|
|
15
|
+
* `null` until something was saved).
|
|
16
|
+
*/
|
|
17
|
+
function createMemoryBackend(seed = {}) {
|
|
18
|
+
const documents = new Map(Object.entries(seed.documents ?? {}).map(([id, content]) => [id, structuredClone(content)]));
|
|
19
|
+
const users = [...seed.users ?? []].sort((a, b) => a.username.localeCompare(b.username, "de"));
|
|
20
|
+
const tags = (seed.tags ?? []).map(normalizeTagName).filter(Boolean);
|
|
21
|
+
let settings = null;
|
|
22
|
+
return {
|
|
23
|
+
name: "memory",
|
|
24
|
+
documents: {
|
|
25
|
+
load: (id) => Promise.resolve(documents.has(id) ? structuredClone(documents.get(id)) : null),
|
|
26
|
+
save: (id, content) => {
|
|
27
|
+
documents.set(id, structuredClone(content));
|
|
28
|
+
return Promise.resolve();
|
|
29
|
+
}
|
|
30
|
+
},
|
|
31
|
+
assets: { upload: (_documentId, file) => Promise.resolve({ url: URL.createObjectURL(file) }) },
|
|
32
|
+
users: { search: (query) => {
|
|
33
|
+
const needle = query.trim().toLowerCase();
|
|
34
|
+
return Promise.resolve(prefixFirst(users, needle, (user) => user.username.toLowerCase()).map(({ id, username, color }) => ({
|
|
35
|
+
id,
|
|
36
|
+
username,
|
|
37
|
+
color
|
|
38
|
+
})));
|
|
39
|
+
} },
|
|
40
|
+
tags: { search: (query) => Promise.resolve(prefixFirst(tags, normalizeTagName(query), (tag) => tag)) },
|
|
41
|
+
settings: {
|
|
42
|
+
load: () => Promise.resolve(settings === null ? null : structuredClone(settings)),
|
|
43
|
+
save: (value) => {
|
|
44
|
+
settings = structuredClone(value);
|
|
45
|
+
return Promise.resolve();
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
//#endregion
|
|
51
|
+
export { createMemoryBackend };
|
|
52
|
+
|
|
53
|
+
//# sourceMappingURL=memory.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"memory.js","names":[],"sources":["../../src/adapters/memory.ts"],"sourcesContent":["import type { JSONContent } from '@tiptap/core'\nimport type { EditorBackend } from '../core/backend'\nimport type { MentionUser } from '../core/backend-types'\nimport { normalizeTagName } from '../core/tag-name'\nimport type { EditorSettings } from '../settings'\n\n// The in-memory adapter of `EditorBackend` for hosts without a data layer: documents, assets (blob URLs), seeded\n// mention users and tags, and settings that live as long as the page. No AI, themes, collaboration or comments: a\n// feature that needs one of them fails when its surface mounts (see `EditorFeature.backend`).\n\nexport interface MemoryBackendSeed {\n /** Documents by id, as `documents.load` returns them. */\n documents?: Record<string, JSONContent>\n /** The people `@` offers. */\n users?: readonly MentionUser[]\n /** The tags `#` offers (normalized like the server's). */\n tags?: readonly string[]\n}\n\n/** The most suggestions one lookup returns, as the HTTP routes. */\nconst MAX_SUGGESTIONS = 20\n\n/** Prefix matches first, then the other substring matches; the order within each group is kept. */\nfunction prefixFirst<T>(items: readonly T[], needle: string, text: (item: T) => string): T[] {\n const matches = items.filter(item => text(item).includes(needle))\n const prefixed = matches.filter(item => text(item).startsWith(needle))\n return [...prefixed, ...matches.filter(item => !prefixed.includes(item))].slice(0, MAX_SUGGESTIONS)\n}\n\n/**\n * An `EditorBackend` that keeps everything in memory: `documents` (a Map seeded from `seed.documents`; `load` answers a\n * copy, `null` for an unknown id), `assets` (`upload` answers a `blob:` URL of the file, valid for the page's life),\n * `users` and `tags` (case-insensitive lookups over the seed, prefix matches first) and `settings` (`load` answers\n * `null` until something was saved).\n */\nexport function createMemoryBackend(seed: MemoryBackendSeed = {}): EditorBackend {\n const documents = new Map(Object.entries(seed.documents ?? {}).map(([id, content]) => [id, structuredClone(content)]))\n const users = [...(seed.users ?? [])].sort((a, b) => a.username.localeCompare(b.username, 'de'))\n const tags = (seed.tags ?? []).map(normalizeTagName).filter(Boolean)\n let settings: EditorSettings | null = null\n\n return {\n name: 'memory',\n documents: {\n load: id => Promise.resolve(documents.has(id) ? structuredClone(documents.get(id)!) : null),\n save: (id, content) => {\n documents.set(id, structuredClone(content))\n return Promise.resolve()\n },\n },\n assets: {\n upload: (_documentId, file) => Promise.resolve({ url: URL.createObjectURL(file) }),\n },\n users: {\n search: (query) => {\n const needle = query.trim().toLowerCase()\n return Promise.resolve(prefixFirst(users, needle, user => user.username.toLowerCase()).map(({ id, username, color }) => ({ id, username, color })))\n },\n },\n tags: {\n search: (query) => Promise.resolve(prefixFirst(tags, normalizeTagName(query), tag => tag)),\n },\n settings: {\n load: () => Promise.resolve(settings === null ? null : structuredClone(settings)),\n save: (value) => {\n settings = structuredClone(value)\n return Promise.resolve()\n },\n },\n }\n}\n"],"mappings":";;;AAoBA,MAAM,kBAAkB;;AAGxB,SAAS,YAAe,OAAqB,QAAgB,MAAgC;CAC3F,MAAM,UAAU,MAAM,QAAO,SAAQ,KAAK,IAAI,CAAC,CAAC,SAAS,MAAM,CAAC;CAChE,MAAM,WAAW,QAAQ,QAAO,SAAQ,KAAK,IAAI,CAAC,CAAC,WAAW,MAAM,CAAC;CACrE,OAAO,CAAC,GAAG,UAAU,GAAG,QAAQ,QAAO,SAAQ,CAAC,SAAS,SAAS,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,GAAG,eAAe;AACpG;;;;;;;AAQA,SAAgB,oBAAoB,OAA0B,CAAC,GAAkB;CAC/E,MAAM,YAAY,IAAI,IAAI,OAAO,QAAQ,KAAK,aAAa,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,aAAa,CAAC,IAAI,gBAAgB,OAAO,CAAC,CAAC,CAAC;CACrH,MAAM,QAAQ,CAAC,GAAI,KAAK,SAAS,CAAC,CAAE,CAAC,CAAC,MAAM,GAAG,MAAM,EAAE,SAAS,cAAc,EAAE,UAAU,IAAI,CAAC;CAC/F,MAAM,QAAQ,KAAK,QAAQ,CAAC,EAAA,CAAG,IAAI,gBAAgB,CAAC,CAAC,OAAO,OAAO;CACnE,IAAI,WAAkC;CAEtC,OAAO;EACL,MAAM;EACN,WAAW;GACT,OAAM,OAAM,QAAQ,QAAQ,UAAU,IAAI,EAAE,IAAI,gBAAgB,UAAU,IAAI,EAAE,CAAE,IAAI,IAAI;GAC1F,OAAO,IAAI,YAAY;IACrB,UAAU,IAAI,IAAI,gBAAgB,OAAO,CAAC;IAC1C,OAAO,QAAQ,QAAQ;GACzB;EACF;EACA,QAAQ,EACN,SAAS,aAAa,SAAS,QAAQ,QAAQ,EAAE,KAAK,IAAI,gBAAgB,IAAI,EAAE,CAAC,EACnF;EACA,OAAO,EACL,SAAS,UAAU;GACjB,MAAM,SAAS,MAAM,KAAK,CAAC,CAAC,YAAY;GACxC,OAAO,QAAQ,QAAQ,YAAY,OAAO,SAAQ,SAAQ,KAAK,SAAS,YAAY,CAAC,CAAC,CAAC,KAAK,EAAE,IAAI,UAAU,aAAa;IAAE;IAAI;IAAU;GAAM,EAAE,CAAC;EACpJ,EACF;EACA,MAAM,EACJ,SAAS,UAAU,QAAQ,QAAQ,YAAY,MAAM,iBAAiB,KAAK,IAAG,QAAO,GAAG,CAAC,EAC3F;EACA,UAAU;GACR,YAAY,QAAQ,QAAQ,aAAa,OAAO,OAAO,gBAAgB,QAAQ,CAAC;GAChF,OAAO,UAAU;IACf,WAAW,gBAAgB,KAAK;IAChC,OAAO,QAAQ,QAAQ;GACzB;EACF;CACF;AACF"}
|
package/dist/adapters/nitro.d.ts
CHANGED
|
@@ -1,10 +1,9 @@
|
|
|
1
|
-
import { EditorAdapter } from "../server/adapter.js";
|
|
2
1
|
import { AiModels, AiModelsConfig } from "../server/ai.js";
|
|
2
|
+
import { EditorPorts } from "../server/ports.js";
|
|
3
3
|
import { CollabServer, CollabServerOptions } from "../server/collab.js";
|
|
4
4
|
import { RateLimiterOptions } from "../server/rate-limit.js";
|
|
5
5
|
import "../server/index.js";
|
|
6
|
-
import {
|
|
7
|
-
import { CommentStore } from "./comments/types.js";
|
|
6
|
+
import { AnyExtension } from "@tiptap/core";
|
|
8
7
|
import { Router } from "h3";
|
|
9
8
|
//#region src/adapters/nitro.d.ts
|
|
10
9
|
/** The part of a Nitro app this entry uses; `nitroApp` of a Nitro plugin fits. */
|
|
@@ -15,28 +14,31 @@ export interface NitroHost {
|
|
|
15
14
|
};
|
|
16
15
|
}
|
|
17
16
|
export interface EditorServerOptions {
|
|
18
|
-
/**
|
|
19
|
-
|
|
17
|
+
/** Identity, storage and everything else the backend serves, one port per capability: a route is mounted only when its port is present. A documents port that also manages documents (`json`, `drizzle`) lets `PUT /api/editor/documents/:id` create them; the `comments` port mounts the comments endpoint, `models` the host's language models. */
|
|
18
|
+
ports: EditorPorts;
|
|
20
19
|
/**
|
|
21
|
-
* The collaboration websocket (`/collab/:id`).
|
|
22
|
-
* `{}` takes everything from the
|
|
20
|
+
* The collaboration websocket (`/collab/:id`). Schema, hooks and Hocuspocus configuration of `createCollabServer`;
|
|
21
|
+
* `{}` takes everything from the ports (the `collabState` port is required). `false` mounts no websocket (documents then only load and save over HTTP).
|
|
22
|
+
* `authenticateUpgrade`: authenticate the upgrade request itself (`Identity.authenticate` with its headers; cookies,
|
|
23
|
+
* not the provider's `token`) and refuse it with HTTP 401, instead of closing an unauthenticated socket with 4401
|
|
24
|
+
* after the upgrade; the user then travels with the connection and is not authenticated a second time.
|
|
23
25
|
* Needs `experimental: { websocket: true }` in the Nitro config.
|
|
24
26
|
*/
|
|
25
|
-
collab: Omit<CollabServerOptions, '
|
|
27
|
+
collab: (Omit<CollabServerOptions, 'ports'> & {
|
|
28
|
+
authenticateUpgrade?: boolean;
|
|
29
|
+
}) | false;
|
|
26
30
|
/**
|
|
27
31
|
* Mounts the AI endpoints (`/api/ai/*`): presets, shared key, transcription, slots of `createAiModels`; `languageModel`
|
|
28
|
-
* and `listModels` default to the
|
|
32
|
+
* and `listModels` default to those of the `models` port. Omitted: no AI routes.
|
|
29
33
|
*/
|
|
30
34
|
ai?: Partial<AiModelsConfig>;
|
|
31
|
-
/** Per-user limit of the AI endpoints; default 30 requests per minute. */
|
|
35
|
+
/** Per-user limit of the AI endpoints; default: that of `defineEditorConfig` (30 requests per minute). */
|
|
32
36
|
rateLimit?: RateLimiterOptions;
|
|
33
|
-
/**
|
|
34
|
-
|
|
35
|
-
store: CommentStore;
|
|
36
|
-
};
|
|
37
|
+
/** The collaboration schema (see `CollabServerOptions.schema`); default `advancedSchemaExtensions()`, host nodes: `() => [...advancedSchemaExtensions(), Callout]`. */
|
|
38
|
+
schema?: () => AnyExtension[];
|
|
37
39
|
}
|
|
38
40
|
export interface EditorServer {
|
|
39
|
-
|
|
41
|
+
ports: EditorPorts;
|
|
40
42
|
/** The collaboration server, `undefined` with `collab: false`. */
|
|
41
43
|
collab: CollabServer | undefined;
|
|
42
44
|
/** The AI models, `undefined` without `ai`. */
|
|
@@ -47,14 +49,15 @@ export interface EditorServer {
|
|
|
47
49
|
/**
|
|
48
50
|
* Wires the editor backend into `nitroApp` (call it from a Nitro plugin):
|
|
49
51
|
*
|
|
50
|
-
* /api/editor/{settings,users,tags,assets/…,themes/…} the editor's own endpoints
|
|
52
|
+
* /api/editor/{capabilities,settings,users,tags,assets/…,themes/…} the editor's own endpoints, each with its port; `capabilities` lists what is served
|
|
51
53
|
* /api/editor/documents/:id GET/PUT a document's TipTap JSON (what `useEditorDocument` uses)
|
|
52
|
-
* /api/editor/comments/:id GET/POST comments, with `comments`
|
|
53
|
-
* /api/ai/{models,chat,complete,generate,
|
|
54
|
+
* /api/editor/comments/:id GET/POST comments, with `ports.comments`
|
|
55
|
+
* /api/ai/{models,chat,complete,generate,extract,transcript-cleanup} with `ai`
|
|
54
56
|
* /collab/:id the collaboration websocket, unless `collab: false`
|
|
55
57
|
*
|
|
56
|
-
* Every route authenticates through `
|
|
57
|
-
* hook. The
|
|
58
|
+
* Every route authenticates through `ports.identity.authenticate`. The collaboration server is closed with Nitro's `close`
|
|
59
|
+
* hook. The installed server is also the process-wide one of `@ecsplico/editor/server` (`useCollabServer`, `useAiModels`,
|
|
60
|
+
* `liveContent`, …) until it closes. The paths are the ones the editor's client (`createHttpBackend`) calls.
|
|
58
61
|
*/
|
|
59
62
|
export declare function installEditorServer(nitroApp: NitroHost, options: EditorServerOptions): EditorServer;
|
|
60
63
|
//#endregion
|