@nocturnium/svelte-ide 1.0.0-rc.1
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/LICENSE +21 -0
- package/README.md +251 -0
- package/dist/components/agents/AgentActivityPanel.svelte +565 -0
- package/dist/components/agents/AgentActivityPanel.svelte.d.ts +24 -0
- package/dist/components/agents/AgentAvatar.svelte +417 -0
- package/dist/components/agents/AgentAvatar.svelte.d.ts +23 -0
- package/dist/components/agents/AgentCursor.svelte +224 -0
- package/dist/components/agents/AgentCursor.svelte.d.ts +35 -0
- package/dist/components/agents/AgentPresenceBar.svelte +261 -0
- package/dist/components/agents/AgentPresenceBar.svelte.d.ts +20 -0
- package/dist/components/agents/index.d.ts +4 -0
- package/dist/components/agents/index.js +5 -0
- package/dist/components/ai/AIConversationList.svelte +524 -0
- package/dist/components/ai/AIConversationList.svelte.d.ts +17 -0
- package/dist/components/ai/AIEditPreview.svelte +132 -0
- package/dist/components/ai/AIEditPreview.svelte.d.ts +8 -0
- package/dist/components/ai/AIInlineEdit.svelte +155 -0
- package/dist/components/ai/AIInlineEdit.svelte.d.ts +10 -0
- package/dist/components/ai/AIMessage.svelte +239 -0
- package/dist/components/ai/AIMessage.svelte.d.ts +13 -0
- package/dist/components/ai/AIMessageActions.svelte +176 -0
- package/dist/components/ai/AIMessageActions.svelte.d.ts +12 -0
- package/dist/components/ai/AIMessageContent.svelte +355 -0
- package/dist/components/ai/AIMessageContent.svelte.d.ts +7 -0
- package/dist/components/ai/AIPanel.svelte +561 -0
- package/dist/components/ai/AIPanel.svelte.d.ts +7 -0
- package/dist/components/ai/AISuggestionWidget.svelte +132 -0
- package/dist/components/ai/AISuggestionWidget.svelte.d.ts +10 -0
- package/dist/components/ai/AIToolCallDisplay.svelte +317 -0
- package/dist/components/ai/AIToolCallDisplay.svelte.d.ts +12 -0
- package/dist/components/ai/index.d.ts +9 -0
- package/dist/components/ai/index.js +10 -0
- package/dist/components/core/Avatar.svelte +110 -0
- package/dist/components/core/Avatar.svelte.d.ts +12 -0
- package/dist/components/core/Badge.svelte +98 -0
- package/dist/components/core/Badge.svelte.d.ts +11 -0
- package/dist/components/core/Button.svelte +175 -0
- package/dist/components/core/Button.svelte.d.ts +18 -0
- package/dist/components/core/ConnectionStatus.svelte +294 -0
- package/dist/components/core/ConnectionStatus.svelte.d.ts +20 -0
- package/dist/components/core/ContextMenu.svelte +176 -0
- package/dist/components/core/ContextMenu.svelte.d.ts +19 -0
- package/dist/components/core/ErrorBoundary.svelte +277 -0
- package/dist/components/core/ErrorBoundary.svelte.d.ts +23 -0
- package/dist/components/core/Icon.svelte +107 -0
- package/dist/components/core/Icon.svelte.d.ts +8 -0
- package/dist/components/core/Input.svelte +138 -0
- package/dist/components/core/Input.svelte.d.ts +20 -0
- package/dist/components/core/Kbd.svelte +34 -0
- package/dist/components/core/Kbd.svelte.d.ts +7 -0
- package/dist/components/core/ResizeHandle.svelte +200 -0
- package/dist/components/core/ResizeHandle.svelte.d.ts +23 -0
- package/dist/components/core/Spinner.svelte +35 -0
- package/dist/components/core/Spinner.svelte.d.ts +7 -0
- package/dist/components/core/Textarea.svelte +112 -0
- package/dist/components/core/Textarea.svelte.d.ts +18 -0
- package/dist/components/core/Tooltip.svelte +103 -0
- package/dist/components/core/Tooltip.svelte.d.ts +11 -0
- package/dist/components/core/index.d.ts +13 -0
- package/dist/components/core/index.js +14 -0
- package/dist/components/editor/AIFocusLayer.svelte +430 -0
- package/dist/components/editor/AIFocusLayer.svelte.d.ts +32 -0
- package/dist/components/editor/Breadcrumbs.svelte +435 -0
- package/dist/components/editor/Breadcrumbs.svelte.d.ts +33 -0
- package/dist/components/editor/BreakpointLayer.svelte +642 -0
- package/dist/components/editor/BreakpointLayer.svelte.d.ts +20 -0
- package/dist/components/editor/CognitiveLoadMeter.svelte +324 -0
- package/dist/components/editor/CognitiveLoadMeter.svelte.d.ts +18 -0
- package/dist/components/editor/CollaborativeEditor.svelte +218 -0
- package/dist/components/editor/CollaborativeEditor.svelte.d.ts +32 -0
- package/dist/components/editor/CommandPalette.svelte +434 -0
- package/dist/components/editor/CommandPalette.svelte.d.ts +11 -0
- package/dist/components/editor/ComplexityLayer.svelte +293 -0
- package/dist/components/editor/ComplexityLayer.svelte.d.ts +23 -0
- package/dist/components/editor/ConflictZoneLayer.svelte +441 -0
- package/dist/components/editor/ConflictZoneLayer.svelte.d.ts +25 -0
- package/dist/components/editor/ContextLens.svelte +262 -0
- package/dist/components/editor/ContextLens.svelte.d.ts +27 -0
- package/dist/components/editor/CustomEditor.svelte +1242 -0
- package/dist/components/editor/CustomEditor.svelte.d.ts +37 -0
- package/dist/components/editor/DebugConsole.svelte +646 -0
- package/dist/components/editor/DebugConsole.svelte.d.ts +41 -0
- package/dist/components/editor/EchoCursorLayer.svelte +363 -0
- package/dist/components/editor/EchoCursorLayer.svelte.d.ts +24 -0
- package/dist/components/editor/Editor.svelte +61 -0
- package/dist/components/editor/Editor.svelte.d.ts +22 -0
- package/dist/components/editor/EditorGutter.svelte +119 -0
- package/dist/components/editor/EditorGutter.svelte.d.ts +19 -0
- package/dist/components/editor/EditorLines.svelte +182 -0
- package/dist/components/editor/EditorLines.svelte.d.ts +43 -0
- package/dist/components/editor/EditorPane.svelte +134 -0
- package/dist/components/editor/EditorPane.svelte.d.ts +9 -0
- package/dist/components/editor/EditorSelections.svelte +186 -0
- package/dist/components/editor/EditorSelections.svelte.d.ts +25 -0
- package/dist/components/editor/EditorTabs.svelte +170 -0
- package/dist/components/editor/EditorTabs.svelte.d.ts +12 -0
- package/dist/components/editor/FileExplorer.svelte +811 -0
- package/dist/components/editor/FileExplorer.svelte.d.ts +67 -0
- package/dist/components/editor/FileIcon.svelte +110 -0
- package/dist/components/editor/FileIcon.svelte.d.ts +10 -0
- package/dist/components/editor/FindReplace.svelte +448 -0
- package/dist/components/editor/FindReplace.svelte.d.ts +40 -0
- package/dist/components/editor/GhostBracketLayer.svelte +391 -0
- package/dist/components/editor/GhostBracketLayer.svelte.d.ts +24 -0
- package/dist/components/editor/GitBlameLayer.svelte +436 -0
- package/dist/components/editor/GitBlameLayer.svelte.d.ts +18 -0
- package/dist/components/editor/InlineDiagnosticsLayer.svelte +540 -0
- package/dist/components/editor/InlineDiagnosticsLayer.svelte.d.ts +35 -0
- package/dist/components/editor/InlineDiffLayer.svelte +337 -0
- package/dist/components/editor/InlineDiffLayer.svelte.d.ts +31 -0
- package/dist/components/editor/MinimalEditor.svelte +75 -0
- package/dist/components/editor/MinimalEditor.svelte.d.ts +6 -0
- package/dist/components/editor/MinimalEditor2.svelte +84 -0
- package/dist/components/editor/MinimalEditor2.svelte.d.ts +6 -0
- package/dist/components/editor/Minimap.svelte +327 -0
- package/dist/components/editor/Minimap.svelte.d.ts +34 -0
- package/dist/components/editor/PluginPreviewSandbox.svelte +793 -0
- package/dist/components/editor/PluginPreviewSandbox.svelte.d.ts +49 -0
- package/dist/components/editor/ProblemsPanel.svelte +628 -0
- package/dist/components/editor/ProblemsPanel.svelte.d.ts +25 -0
- package/dist/components/editor/QuickActionsMenu.svelte +403 -0
- package/dist/components/editor/QuickActionsMenu.svelte.d.ts +18 -0
- package/dist/components/editor/SnippetPalette.svelte +530 -0
- package/dist/components/editor/SnippetPalette.svelte.d.ts +16 -0
- package/dist/components/editor/StructureMap.svelte +431 -0
- package/dist/components/editor/StructureMap.svelte.d.ts +37 -0
- package/dist/components/editor/SymbolOutline.svelte +722 -0
- package/dist/components/editor/SymbolOutline.svelte.d.ts +44 -0
- package/dist/components/editor/TimelineScrubber.svelte +470 -0
- package/dist/components/editor/TimelineScrubber.svelte.d.ts +40 -0
- package/dist/components/editor/TokenRenderer.svelte +69 -0
- package/dist/components/editor/TokenRenderer.svelte.d.ts +15 -0
- package/dist/components/editor/constants.d.ts +32 -0
- package/dist/components/editor/constants.js +36 -0
- package/dist/components/editor/core/ai-awareness.d.ts +176 -0
- package/dist/components/editor/core/ai-awareness.js +210 -0
- package/dist/components/editor/core/bracket-healer.d.ts +189 -0
- package/dist/components/editor/core/bracket-healer.js +406 -0
- package/dist/components/editor/core/breakpoints.d.ts +203 -0
- package/dist/components/editor/core/breakpoints.js +414 -0
- package/dist/components/editor/core/commands.d.ts +108 -0
- package/dist/components/editor/core/commands.js +246 -0
- package/dist/components/editor/core/complexity-analyzer.d.ts +123 -0
- package/dist/components/editor/core/complexity-analyzer.js +376 -0
- package/dist/components/editor/core/conflict-predictor.d.ts +135 -0
- package/dist/components/editor/core/conflict-predictor.js +316 -0
- package/dist/components/editor/core/crdt-binding.d.ts +118 -0
- package/dist/components/editor/core/crdt-binding.js +286 -0
- package/dist/components/editor/core/diagnostics.d.ts +210 -0
- package/dist/components/editor/core/diagnostics.js +335 -0
- package/dist/components/editor/core/echo-cursor.d.ts +201 -0
- package/dist/components/editor/core/echo-cursor.js +267 -0
- package/dist/components/editor/core/folding.d.ts +124 -0
- package/dist/components/editor/core/folding.js +672 -0
- package/dist/components/editor/core/ghost-pair.d.ts +122 -0
- package/dist/components/editor/core/ghost-pair.js +221 -0
- package/dist/components/editor/core/git-blame.d.ts +170 -0
- package/dist/components/editor/core/git-blame.js +324 -0
- package/dist/components/editor/core/index.d.ts +26 -0
- package/dist/components/editor/core/index.js +24 -0
- package/dist/components/editor/core/keybindings.d.ts +79 -0
- package/dist/components/editor/core/keybindings.js +357 -0
- package/dist/components/editor/core/multi-cursor.d.ts +196 -0
- package/dist/components/editor/core/multi-cursor.js +521 -0
- package/dist/components/editor/core/navigation.d.ts +107 -0
- package/dist/components/editor/core/navigation.js +408 -0
- package/dist/components/editor/core/quick-actions.d.ts +189 -0
- package/dist/components/editor/core/quick-actions.js +427 -0
- package/dist/components/editor/core/search.d.ts +88 -0
- package/dist/components/editor/core/search.js +192 -0
- package/dist/components/editor/core/semantic-analyzer.d.ts +77 -0
- package/dist/components/editor/core/semantic-analyzer.js +424 -0
- package/dist/components/editor/core/snippet-manager.d.ts +202 -0
- package/dist/components/editor/core/snippet-manager.js +565 -0
- package/dist/components/editor/core/state.d.ts +367 -0
- package/dist/components/editor/core/state.js +900 -0
- package/dist/components/editor/core/timeline.d.ts +204 -0
- package/dist/components/editor/core/timeline.js +349 -0
- package/dist/components/editor/editor-find.d.ts +56 -0
- package/dist/components/editor/editor-find.js +148 -0
- package/dist/components/editor/editor-input.d.ts +77 -0
- package/dist/components/editor/editor-input.js +445 -0
- package/dist/components/editor/editor-multicursor.d.ts +21 -0
- package/dist/components/editor/editor-multicursor.js +196 -0
- package/dist/components/editor/editor-scroll.d.ts +14 -0
- package/dist/components/editor/editor-scroll.js +34 -0
- package/dist/components/editor/index.d.ts +15 -0
- package/dist/components/editor/index.js +21 -0
- package/dist/components/editor/languages.d.ts +62 -0
- package/dist/components/editor/languages.js +285 -0
- package/dist/components/editor/theme.d.ts +88 -0
- package/dist/components/editor/theme.js +139 -0
- package/dist/components/editor/tokenizer/base.d.ts +40 -0
- package/dist/components/editor/tokenizer/base.js +203 -0
- package/dist/components/editor/tokenizer/index.d.ts +56 -0
- package/dist/components/editor/tokenizer/index.js +215 -0
- package/dist/components/editor/tokenizer/languages/css.d.ts +17 -0
- package/dist/components/editor/tokenizer/languages/css.js +194 -0
- package/dist/components/editor/tokenizer/languages/go.d.ts +17 -0
- package/dist/components/editor/tokenizer/languages/go.js +220 -0
- package/dist/components/editor/tokenizer/languages/html.d.ts +24 -0
- package/dist/components/editor/tokenizer/languages/html.js +145 -0
- package/dist/components/editor/tokenizer/languages/javascript.d.ts +56 -0
- package/dist/components/editor/tokenizer/languages/javascript.js +452 -0
- package/dist/components/editor/tokenizer/languages/json.d.ts +12 -0
- package/dist/components/editor/tokenizer/languages/json.js +91 -0
- package/dist/components/editor/tokenizer/languages/markdown.d.ts +16 -0
- package/dist/components/editor/tokenizer/languages/markdown.js +156 -0
- package/dist/components/editor/tokenizer/languages/python.d.ts +20 -0
- package/dist/components/editor/tokenizer/languages/python.js +227 -0
- package/dist/components/editor/tokenizer/languages/svelte.d.ts +40 -0
- package/dist/components/editor/tokenizer/languages/svelte.js +326 -0
- package/dist/components/editor/tokenizer/types.d.ts +86 -0
- package/dist/components/editor/tokenizer/types.js +4 -0
- package/dist/components/layout/IDELayout.svelte +274 -0
- package/dist/components/layout/IDELayout.svelte.d.ts +29 -0
- package/dist/components/layout/StatusBar.svelte +511 -0
- package/dist/components/layout/StatusBar.svelte.d.ts +47 -0
- package/dist/components/layout/index.d.ts +2 -0
- package/dist/components/layout/index.js +3 -0
- package/dist/components/lsp/AutocompleteWidget.svelte +364 -0
- package/dist/components/lsp/AutocompleteWidget.svelte.d.ts +33 -0
- package/dist/components/lsp/DiagnosticMarker.svelte +166 -0
- package/dist/components/lsp/DiagnosticMarker.svelte.d.ts +19 -0
- package/dist/components/lsp/DiagnosticsPanel.svelte +388 -0
- package/dist/components/lsp/DiagnosticsPanel.svelte.d.ts +21 -0
- package/dist/components/lsp/HoverTooltip.svelte +274 -0
- package/dist/components/lsp/HoverTooltip.svelte.d.ts +24 -0
- package/dist/components/lsp/LSPEditor.svelte +486 -0
- package/dist/components/lsp/LSPEditor.svelte.d.ts +39 -0
- package/dist/components/lsp/SignatureHelpWidget.svelte +216 -0
- package/dist/components/lsp/SignatureHelpWidget.svelte.d.ts +22 -0
- package/dist/components/lsp/index.d.ts +6 -0
- package/dist/components/lsp/index.js +7 -0
- package/dist/components/plugins/PluginCard.svelte +153 -0
- package/dist/components/plugins/PluginCard.svelte.d.ts +19 -0
- package/dist/components/plugins/PluginPanel.svelte +280 -0
- package/dist/components/plugins/PluginPanel.svelte.d.ts +8 -0
- package/dist/components/plugins/PluginProposalForm.svelte +250 -0
- package/dist/components/plugins/PluginProposalForm.svelte.d.ts +6 -0
- package/dist/components/plugins/PluginStatusBadge.svelte +14 -0
- package/dist/components/plugins/PluginStatusBadge.svelte.d.ts +8 -0
- package/dist/components/plugins/index.d.ts +4 -0
- package/dist/components/plugins/index.js +5 -0
- package/dist/components/vfs/LockConflictDialog.svelte +705 -0
- package/dist/components/vfs/LockConflictDialog.svelte.d.ts +21 -0
- package/dist/components/vfs/LockIndicator.svelte +194 -0
- package/dist/components/vfs/LockIndicator.svelte.d.ts +29 -0
- package/dist/components/vfs/LockOverlay.svelte +344 -0
- package/dist/components/vfs/LockOverlay.svelte.d.ts +17 -0
- package/dist/components/vfs/VersionConflictDialog.svelte +549 -0
- package/dist/components/vfs/VersionConflictDialog.svelte.d.ts +24 -0
- package/dist/components/vfs/index.d.ts +4 -0
- package/dist/components/vfs/index.js +5 -0
- package/dist/crdt/awareness.d.ts +42 -0
- package/dist/crdt/awareness.js +109 -0
- package/dist/crdt/document.d.ts +101 -0
- package/dist/crdt/document.js +187 -0
- package/dist/crdt/index.d.ts +9 -0
- package/dist/crdt/index.js +8 -0
- package/dist/crdt/provider.d.ts +85 -0
- package/dist/crdt/provider.js +150 -0
- package/dist/crdt/types.d.ts +61 -0
- package/dist/crdt/types.js +4 -0
- package/dist/crdt/undo.d.ts +34 -0
- package/dist/crdt/undo.js +70 -0
- package/dist/index.d.ts +277 -0
- package/dist/index.js +280 -0
- package/dist/plugins/index.d.ts +103 -0
- package/dist/plugins/index.js +153 -0
- package/dist/services/error-handling.d.ts +95 -0
- package/dist/services/error-handling.js +413 -0
- package/dist/services/ide-integration.d.ts +83 -0
- package/dist/services/ide-integration.js +367 -0
- package/dist/services/lsp-client.d.ts +69 -0
- package/dist/services/lsp-client.js +667 -0
- package/dist/services/mock-ai.d.ts +37 -0
- package/dist/services/mock-ai.js +318 -0
- package/dist/services/optimistic.d.ts +141 -0
- package/dist/services/optimistic.js +367 -0
- package/dist/services/vfs-client.d.ts +81 -0
- package/dist/services/vfs-client.js +348 -0
- package/dist/stores/agents.svelte.d.ts +85 -0
- package/dist/stores/agents.svelte.js +459 -0
- package/dist/stores/ai-persistence.svelte.d.ts +76 -0
- package/dist/stores/ai-persistence.svelte.js +334 -0
- package/dist/stores/ai.svelte.d.ts +140 -0
- package/dist/stores/ai.svelte.js +383 -0
- package/dist/stores/collaboration.svelte.d.ts +164 -0
- package/dist/stores/collaboration.svelte.js +334 -0
- package/dist/stores/editor.svelte.d.ts +131 -0
- package/dist/stores/editor.svelte.js +250 -0
- package/dist/stores/index.d.ts +10 -0
- package/dist/stores/index.js +29 -0
- package/dist/stores/layout.svelte.d.ts +171 -0
- package/dist/stores/layout.svelte.js +351 -0
- package/dist/stores/plugin.svelte.d.ts +121 -0
- package/dist/stores/plugin.svelte.js +410 -0
- package/dist/stores/vfs.svelte.d.ts +123 -0
- package/dist/stores/vfs.svelte.js +680 -0
- package/dist/styles/theme.css +623 -0
- package/dist/types/agents.d.ts +127 -0
- package/dist/types/agents.js +5 -0
- package/dist/types/ai.d.ts +137 -0
- package/dist/types/ai.js +4 -0
- package/dist/types/crdt.d.ts +222 -0
- package/dist/types/crdt.js +5 -0
- package/dist/types/editor.d.ts +52 -0
- package/dist/types/editor.js +18 -0
- package/dist/types/events.d.ts +133 -0
- package/dist/types/events.js +4 -0
- package/dist/types/filesystem.d.ts +77 -0
- package/dist/types/filesystem.js +4 -0
- package/dist/types/index.d.ts +9 -0
- package/dist/types/index.js +12 -0
- package/dist/types/lsp.d.ts +691 -0
- package/dist/types/lsp.js +108 -0
- package/dist/types/plugin.d.ts +239 -0
- package/dist/types/plugin.js +5 -0
- package/dist/types/vfs.d.ts +191 -0
- package/dist/types/vfs.js +18 -0
- package/dist/utils/format.d.ts +55 -0
- package/dist/utils/format.js +152 -0
- package/dist/utils/index.d.ts +3 -0
- package/dist/utils/index.js +4 -0
- package/dist/utils/keybindings.d.ts +33 -0
- package/dist/utils/keybindings.js +171 -0
- package/dist/utils/language.d.ts +27 -0
- package/dist/utils/language.js +222 -0
- package/package.json +178 -0
|
@@ -0,0 +1,286 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CRDT binding for the custom editor
|
|
3
|
+
*
|
|
4
|
+
* This module provides integration between the custom editor state
|
|
5
|
+
* and Yjs CRDT for real-time collaborative editing.
|
|
6
|
+
*/
|
|
7
|
+
import * as Y from 'yjs';
|
|
8
|
+
/**
|
|
9
|
+
* CRDT binding class that syncs editor state with Yjs
|
|
10
|
+
*/
|
|
11
|
+
export class CRDTBinding {
|
|
12
|
+
doc;
|
|
13
|
+
text;
|
|
14
|
+
editorState;
|
|
15
|
+
isUpdating = false;
|
|
16
|
+
isDestroyed = false;
|
|
17
|
+
cleanupFns = [];
|
|
18
|
+
// Store observer reference for guaranteed cleanup
|
|
19
|
+
textObserver = null;
|
|
20
|
+
constructor(config) {
|
|
21
|
+
this.doc = config.doc;
|
|
22
|
+
this.text = config.doc.getText(config.textName ?? 'content');
|
|
23
|
+
this.editorState = config.editorState;
|
|
24
|
+
this.setupBindings();
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Set up bidirectional bindings
|
|
28
|
+
*/
|
|
29
|
+
setupBindings() {
|
|
30
|
+
// Sync initial content
|
|
31
|
+
this.syncFromCRDT();
|
|
32
|
+
// Listen for CRDT changes - use bound method for reliable cleanup
|
|
33
|
+
this.textObserver = (event) => {
|
|
34
|
+
if (this.isDestroyed || this.isUpdating)
|
|
35
|
+
return;
|
|
36
|
+
this.handleCRDTChange(event);
|
|
37
|
+
};
|
|
38
|
+
this.text.observe(this.textObserver);
|
|
39
|
+
this.cleanupFns.push(() => {
|
|
40
|
+
if (this.textObserver) {
|
|
41
|
+
this.text.unobserve(this.textObserver);
|
|
42
|
+
this.textObserver = null;
|
|
43
|
+
}
|
|
44
|
+
});
|
|
45
|
+
// Listen for local editor changes
|
|
46
|
+
const unsubscribe = this.editorState.onContentChange((event) => {
|
|
47
|
+
if (this.isDestroyed || this.isUpdating)
|
|
48
|
+
return;
|
|
49
|
+
this.handleLocalChange(event);
|
|
50
|
+
});
|
|
51
|
+
this.cleanupFns.push(unsubscribe);
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Sync content from CRDT to editor
|
|
55
|
+
*/
|
|
56
|
+
syncFromCRDT() {
|
|
57
|
+
this.isUpdating = true;
|
|
58
|
+
try {
|
|
59
|
+
const content = this.text.toString();
|
|
60
|
+
this.editorState.setContent(content);
|
|
61
|
+
}
|
|
62
|
+
finally {
|
|
63
|
+
this.isUpdating = false;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Handle changes from CRDT
|
|
68
|
+
* Uses Yjs relative positions for accurate cursor preservation during concurrent edits
|
|
69
|
+
*/
|
|
70
|
+
handleCRDTChange(event) {
|
|
71
|
+
this.isUpdating = true;
|
|
72
|
+
try {
|
|
73
|
+
// Capture current selection as relative positions BEFORE applying changes
|
|
74
|
+
// Relative positions survive structural changes to the document
|
|
75
|
+
const currentSelection = this.editorState.selection;
|
|
76
|
+
const anchorIndex = this.positionToIndex(currentSelection.anchor);
|
|
77
|
+
const headIndex = this.positionToIndex(currentSelection.head);
|
|
78
|
+
// Create Yjs relative positions (these track position relative to surrounding content)
|
|
79
|
+
const anchorRelPos = Y.createRelativePositionFromTypeIndex(this.text, anchorIndex);
|
|
80
|
+
const headRelPos = Y.createRelativePositionFromTypeIndex(this.text, headIndex);
|
|
81
|
+
// Get new content
|
|
82
|
+
const content = this.text.toString();
|
|
83
|
+
// Resolve relative positions back to absolute positions
|
|
84
|
+
// This correctly handles insertions/deletions around the cursor
|
|
85
|
+
const anchorAbsPos = Y.createAbsolutePositionFromRelativePosition(anchorRelPos, this.doc);
|
|
86
|
+
const headAbsPos = Y.createAbsolutePositionFromRelativePosition(headRelPos, this.doc);
|
|
87
|
+
// Convert back to editor positions with bounds checking
|
|
88
|
+
const maxIndex = content.length;
|
|
89
|
+
const newAnchorIndex = anchorAbsPos ? Math.min(anchorAbsPos.index, maxIndex) : 0;
|
|
90
|
+
const newHeadIndex = headAbsPos ? Math.min(headAbsPos.index, maxIndex) : 0;
|
|
91
|
+
const newAnchor = this.indexToPosition(newAnchorIndex);
|
|
92
|
+
const newHead = this.indexToPosition(newHeadIndex);
|
|
93
|
+
// Apply content and selection atomically without triggering intermediate events
|
|
94
|
+
// This prevents race conditions where selection listeners modify state during update
|
|
95
|
+
this.editorState.runWithoutNotifications(() => {
|
|
96
|
+
this.editorState.setContent(content);
|
|
97
|
+
this.editorState.setSelection(newAnchor, newHead);
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
finally {
|
|
101
|
+
this.isUpdating = false;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Convert position to index using provided lines (for atomic operations)
|
|
106
|
+
*/
|
|
107
|
+
positionToIndexWithLines(position, lines) {
|
|
108
|
+
let index = 0;
|
|
109
|
+
// Clamp line to valid range
|
|
110
|
+
const lineNum = Math.min(position.line, lines.length - 1);
|
|
111
|
+
if (lineNum < 0)
|
|
112
|
+
return 0;
|
|
113
|
+
for (let i = 0; i < lineNum; i++) {
|
|
114
|
+
index += (lines[i]?.text.length ?? 0) + 1; // +1 for newline
|
|
115
|
+
}
|
|
116
|
+
// Clamp column to valid range for this line
|
|
117
|
+
const lineLength = lines[lineNum]?.text.length ?? 0;
|
|
118
|
+
index += Math.min(position.column, lineLength);
|
|
119
|
+
return index;
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Handle local editor changes
|
|
123
|
+
*/
|
|
124
|
+
handleLocalChange(event) {
|
|
125
|
+
this.isUpdating = true;
|
|
126
|
+
try {
|
|
127
|
+
this.doc.transact(() => {
|
|
128
|
+
switch (event.type) {
|
|
129
|
+
case 'insert':
|
|
130
|
+
if (event.text) {
|
|
131
|
+
const index = this.positionToIndex(event.from);
|
|
132
|
+
this.text.insert(index, event.text);
|
|
133
|
+
}
|
|
134
|
+
break;
|
|
135
|
+
case 'delete':
|
|
136
|
+
if (event.to) {
|
|
137
|
+
const fromIndex = this.positionToIndex(event.from);
|
|
138
|
+
const toIndex = this.positionToIndex(event.to);
|
|
139
|
+
this.text.delete(fromIndex, toIndex - fromIndex);
|
|
140
|
+
}
|
|
141
|
+
break;
|
|
142
|
+
case 'replace': {
|
|
143
|
+
// A `replace` rewrites the whole document (setContent, undo/redo,
|
|
144
|
+
// replace-all, external load). The event's from/to are computed
|
|
145
|
+
// against the POST-change line array, but the Yjs text still holds
|
|
146
|
+
// the OLD content here, so deriving a delete range from them would
|
|
147
|
+
// target the wrong span and corrupt the shared doc.
|
|
148
|
+
//
|
|
149
|
+
// Make replace robust: delete the entire current Yjs range and
|
|
150
|
+
// insert the full new content. This is correct regardless of the
|
|
151
|
+
// from/to positions carried on the event.
|
|
152
|
+
const currentLength = this.text.length;
|
|
153
|
+
if (currentLength > 0) {
|
|
154
|
+
this.text.delete(0, currentLength);
|
|
155
|
+
}
|
|
156
|
+
if (event.text) {
|
|
157
|
+
this.text.insert(0, event.text);
|
|
158
|
+
}
|
|
159
|
+
break;
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
});
|
|
163
|
+
}
|
|
164
|
+
finally {
|
|
165
|
+
this.isUpdating = false;
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
169
|
+
* Convert editor position to CRDT index
|
|
170
|
+
*/
|
|
171
|
+
positionToIndex(position) {
|
|
172
|
+
return this.positionToIndexWithLines(position, this.editorState.lines);
|
|
173
|
+
}
|
|
174
|
+
/**
|
|
175
|
+
* Convert CRDT index to editor position
|
|
176
|
+
*/
|
|
177
|
+
indexToPosition(index) {
|
|
178
|
+
const lines = this.editorState.lines;
|
|
179
|
+
// Handle edge cases
|
|
180
|
+
if (lines.length === 0)
|
|
181
|
+
return { line: 0, column: 0 };
|
|
182
|
+
if (index <= 0)
|
|
183
|
+
return { line: 0, column: 0 };
|
|
184
|
+
let remaining = index;
|
|
185
|
+
let line = 0;
|
|
186
|
+
while (line < lines.length) {
|
|
187
|
+
const lineText = lines[line]?.text ?? '';
|
|
188
|
+
const lineLength = lineText.length + 1; // +1 for newline
|
|
189
|
+
// For the last line, don't add newline to length calculation
|
|
190
|
+
const isLastLine = line === lines.length - 1;
|
|
191
|
+
const effectiveLength = isLastLine ? lineText.length : lineLength;
|
|
192
|
+
if (remaining <= effectiveLength) {
|
|
193
|
+
return { line, column: Math.min(remaining, lineText.length) };
|
|
194
|
+
}
|
|
195
|
+
remaining -= lineLength;
|
|
196
|
+
line++;
|
|
197
|
+
}
|
|
198
|
+
// At end of document - clamp to last valid position
|
|
199
|
+
const lastLine = lines.length - 1;
|
|
200
|
+
return {
|
|
201
|
+
line: lastLine,
|
|
202
|
+
column: lines[lastLine]?.text.length ?? 0
|
|
203
|
+
};
|
|
204
|
+
}
|
|
205
|
+
/**
|
|
206
|
+
* Apply a full local content replacement into the bound editor state,
|
|
207
|
+
* which propagates to the CRDT / Yjs text via the local-change listener.
|
|
208
|
+
*
|
|
209
|
+
* Use this for edits that originate outside the bound EditorState (e.g. an
|
|
210
|
+
* inner editor component that maintains its own state) so that local typing
|
|
211
|
+
* reaches collaborators. No-op while a remote update is being applied, which
|
|
212
|
+
* also prevents a remote -> local -> remote echo loop.
|
|
213
|
+
*
|
|
214
|
+
* @returns `true` if the content changed and was propagated, `false` otherwise.
|
|
215
|
+
*/
|
|
216
|
+
setContent(content) {
|
|
217
|
+
// Guard against echoing a remote update back into the CRDT.
|
|
218
|
+
if (this.isDestroyed || this.isUpdating)
|
|
219
|
+
return false;
|
|
220
|
+
// Skip no-op writes (content already matches the editor state).
|
|
221
|
+
if (this.editorState.getContent() === content)
|
|
222
|
+
return false;
|
|
223
|
+
this.editorState.setContent(content);
|
|
224
|
+
return true;
|
|
225
|
+
}
|
|
226
|
+
/**
|
|
227
|
+
* Whether a remote (CRDT-originated) update is currently being applied.
|
|
228
|
+
* Callers can use this to suppress re-sending an echoed local change.
|
|
229
|
+
*/
|
|
230
|
+
get isApplyingRemoteChange() {
|
|
231
|
+
return this.isUpdating;
|
|
232
|
+
}
|
|
233
|
+
/**
|
|
234
|
+
* Get the Yjs text type
|
|
235
|
+
*/
|
|
236
|
+
getText() {
|
|
237
|
+
return this.text;
|
|
238
|
+
}
|
|
239
|
+
/**
|
|
240
|
+
* Get the Yjs document
|
|
241
|
+
*/
|
|
242
|
+
getDoc() {
|
|
243
|
+
return this.doc;
|
|
244
|
+
}
|
|
245
|
+
/**
|
|
246
|
+
* Clean up bindings
|
|
247
|
+
*/
|
|
248
|
+
destroy() {
|
|
249
|
+
// Prevent further operations
|
|
250
|
+
this.isDestroyed = true;
|
|
251
|
+
// Run all cleanup functions
|
|
252
|
+
for (const cleanup of this.cleanupFns) {
|
|
253
|
+
try {
|
|
254
|
+
cleanup();
|
|
255
|
+
}
|
|
256
|
+
catch {
|
|
257
|
+
// Ignore cleanup errors to ensure all cleanups run
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
this.cleanupFns = [];
|
|
261
|
+
this.textObserver = null;
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
/**
|
|
265
|
+
* Create a CRDT binding
|
|
266
|
+
*/
|
|
267
|
+
export function createCRDTBinding(config) {
|
|
268
|
+
return new CRDTBinding(config);
|
|
269
|
+
}
|
|
270
|
+
/**
|
|
271
|
+
* Create a relative position from an editor position
|
|
272
|
+
*/
|
|
273
|
+
export function createRelativePosition(text, binding, position) {
|
|
274
|
+
const index = binding.positionToIndex(position);
|
|
275
|
+
const yRelPos = Y.createRelativePositionFromTypeIndex(text, index);
|
|
276
|
+
return { yRelPos };
|
|
277
|
+
}
|
|
278
|
+
/**
|
|
279
|
+
* Resolve a relative position to an editor position
|
|
280
|
+
*/
|
|
281
|
+
export function resolveRelativePosition(doc, binding, relPos) {
|
|
282
|
+
const absPos = Y.createAbsolutePositionFromRelativePosition(relPos.yRelPos, doc);
|
|
283
|
+
if (!absPos)
|
|
284
|
+
return null;
|
|
285
|
+
return binding.indexToPosition(absPos.index);
|
|
286
|
+
}
|
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Diagnostics Manager
|
|
3
|
+
*
|
|
4
|
+
* Manages code diagnostics including:
|
|
5
|
+
* - Errors, warnings, info, hints
|
|
6
|
+
* - Quick fixes and code actions
|
|
7
|
+
* - Diagnostic sources (TypeScript, ESLint, etc.)
|
|
8
|
+
*/
|
|
9
|
+
export interface Position {
|
|
10
|
+
line: number;
|
|
11
|
+
column: number;
|
|
12
|
+
}
|
|
13
|
+
export interface Range {
|
|
14
|
+
start: Position;
|
|
15
|
+
end: Position;
|
|
16
|
+
}
|
|
17
|
+
export type DiagnosticSeverity = 'error' | 'warning' | 'info' | 'hint';
|
|
18
|
+
export interface DiagnosticRelatedInfo {
|
|
19
|
+
/** Location of related info */
|
|
20
|
+
range: Range;
|
|
21
|
+
/** Message */
|
|
22
|
+
message: string;
|
|
23
|
+
/** File path if different from main diagnostic */
|
|
24
|
+
filePath?: string;
|
|
25
|
+
}
|
|
26
|
+
export interface DiagnosticTag {
|
|
27
|
+
/** Deprecated code */
|
|
28
|
+
deprecated?: boolean;
|
|
29
|
+
/** Unnecessary code (e.g., unused imports) */
|
|
30
|
+
unnecessary?: boolean;
|
|
31
|
+
}
|
|
32
|
+
export interface Diagnostic {
|
|
33
|
+
/** Unique identifier */
|
|
34
|
+
id: string;
|
|
35
|
+
/** Range of the diagnostic */
|
|
36
|
+
range: Range;
|
|
37
|
+
/** Severity level */
|
|
38
|
+
severity: DiagnosticSeverity;
|
|
39
|
+
/** Main message */
|
|
40
|
+
message: string;
|
|
41
|
+
/** Source of the diagnostic (e.g., "typescript", "eslint") */
|
|
42
|
+
source: string;
|
|
43
|
+
/** Error/warning code */
|
|
44
|
+
code?: string | number;
|
|
45
|
+
/** URL for more information */
|
|
46
|
+
codeUrl?: string;
|
|
47
|
+
/** Related information */
|
|
48
|
+
relatedInfo?: DiagnosticRelatedInfo[];
|
|
49
|
+
/** Tags for special rendering */
|
|
50
|
+
tags?: DiagnosticTag;
|
|
51
|
+
/** Suggested fixes */
|
|
52
|
+
fixes?: DiagnosticFix[];
|
|
53
|
+
}
|
|
54
|
+
export interface DiagnosticFix {
|
|
55
|
+
/** Fix title */
|
|
56
|
+
title: string;
|
|
57
|
+
/** Whether this is the preferred fix */
|
|
58
|
+
isPreferred?: boolean;
|
|
59
|
+
/** Text edits to apply */
|
|
60
|
+
edits: TextEdit[];
|
|
61
|
+
}
|
|
62
|
+
export interface TextEdit {
|
|
63
|
+
/** Range to replace */
|
|
64
|
+
range: Range;
|
|
65
|
+
/** New text */
|
|
66
|
+
newText: string;
|
|
67
|
+
}
|
|
68
|
+
export interface DiagnosticFilter {
|
|
69
|
+
/** Filter by severity */
|
|
70
|
+
severity?: DiagnosticSeverity[];
|
|
71
|
+
/** Filter by source */
|
|
72
|
+
source?: string[];
|
|
73
|
+
/** Filter by file path */
|
|
74
|
+
filePath?: string;
|
|
75
|
+
/** Search text in messages */
|
|
76
|
+
searchText?: string;
|
|
77
|
+
}
|
|
78
|
+
export interface DiagnosticsConfig {
|
|
79
|
+
/** Whether diagnostics are enabled */
|
|
80
|
+
enabled: boolean;
|
|
81
|
+
/** Show inline decorations */
|
|
82
|
+
showInline: boolean;
|
|
83
|
+
/** Show gutter icons */
|
|
84
|
+
showGutterIcons: boolean;
|
|
85
|
+
/** Delay before showing diagnostics (ms) */
|
|
86
|
+
showDelay: number;
|
|
87
|
+
/** Maximum diagnostics per file */
|
|
88
|
+
maxPerFile: number;
|
|
89
|
+
/** Severity to show (filter) */
|
|
90
|
+
severityFilter: DiagnosticSeverity[];
|
|
91
|
+
}
|
|
92
|
+
type Listener = () => void;
|
|
93
|
+
/**
|
|
94
|
+
* Diagnostics Manager
|
|
95
|
+
*/
|
|
96
|
+
export declare class DiagnosticsManager {
|
|
97
|
+
private _config;
|
|
98
|
+
private _diagnostics;
|
|
99
|
+
private _listeners;
|
|
100
|
+
private _idCounter;
|
|
101
|
+
/**
|
|
102
|
+
* Set diagnostics for a file
|
|
103
|
+
*/
|
|
104
|
+
setDiagnostics(filePath: string, diagnostics: Omit<Diagnostic, 'id'>[]): void;
|
|
105
|
+
/**
|
|
106
|
+
* Add diagnostics to a file
|
|
107
|
+
*/
|
|
108
|
+
addDiagnostics(filePath: string, diagnostics: Omit<Diagnostic, 'id'>[]): void;
|
|
109
|
+
/**
|
|
110
|
+
* Clear diagnostics for a file
|
|
111
|
+
*/
|
|
112
|
+
clearDiagnostics(filePath: string): void;
|
|
113
|
+
/**
|
|
114
|
+
* Clear all diagnostics
|
|
115
|
+
*/
|
|
116
|
+
clearAll(): void;
|
|
117
|
+
/**
|
|
118
|
+
* Get diagnostics for a file
|
|
119
|
+
*/
|
|
120
|
+
getDiagnostics(filePath: string): Diagnostic[];
|
|
121
|
+
/**
|
|
122
|
+
* Get all diagnostics
|
|
123
|
+
*/
|
|
124
|
+
getAllDiagnostics(): Map<string, Diagnostic[]>;
|
|
125
|
+
/**
|
|
126
|
+
* Get diagnostics at a specific position
|
|
127
|
+
*/
|
|
128
|
+
getDiagnosticsAtPosition(filePath: string, position: Position): Diagnostic[];
|
|
129
|
+
/**
|
|
130
|
+
* Get diagnostics for a line
|
|
131
|
+
*/
|
|
132
|
+
getDiagnosticsForLine(filePath: string, line: number): Diagnostic[];
|
|
133
|
+
/**
|
|
134
|
+
* Get counts by severity
|
|
135
|
+
*/
|
|
136
|
+
getCounts(filePath?: string): Record<DiagnosticSeverity, number>;
|
|
137
|
+
/**
|
|
138
|
+
* Get total count
|
|
139
|
+
*/
|
|
140
|
+
getTotalCount(filePath?: string): number;
|
|
141
|
+
/**
|
|
142
|
+
* Check if position is in range
|
|
143
|
+
*/
|
|
144
|
+
private positionInRange;
|
|
145
|
+
/**
|
|
146
|
+
* Filter diagnostics by config
|
|
147
|
+
*/
|
|
148
|
+
private filterDiagnostics;
|
|
149
|
+
/**
|
|
150
|
+
* Apply a fix
|
|
151
|
+
*/
|
|
152
|
+
applyFix(diagnostic: Diagnostic, fix: DiagnosticFix): TextEdit[];
|
|
153
|
+
/**
|
|
154
|
+
* Get config
|
|
155
|
+
*/
|
|
156
|
+
get config(): DiagnosticsConfig;
|
|
157
|
+
/**
|
|
158
|
+
* Update config
|
|
159
|
+
*/
|
|
160
|
+
setConfig(config: Partial<DiagnosticsConfig>): void;
|
|
161
|
+
/**
|
|
162
|
+
* Enable/disable
|
|
163
|
+
*/
|
|
164
|
+
setEnabled(enabled: boolean): void;
|
|
165
|
+
/**
|
|
166
|
+
* Check if enabled
|
|
167
|
+
*/
|
|
168
|
+
isEnabled(): boolean;
|
|
169
|
+
/**
|
|
170
|
+
* Set severity filter
|
|
171
|
+
*/
|
|
172
|
+
setSeverityFilter(severities: DiagnosticSeverity[]): void;
|
|
173
|
+
/**
|
|
174
|
+
* Subscribe to changes
|
|
175
|
+
*/
|
|
176
|
+
subscribe(listener: Listener): () => void;
|
|
177
|
+
/**
|
|
178
|
+
* Notify listeners
|
|
179
|
+
*/
|
|
180
|
+
private notify;
|
|
181
|
+
/**
|
|
182
|
+
* Clean up
|
|
183
|
+
*/
|
|
184
|
+
destroy(): void;
|
|
185
|
+
}
|
|
186
|
+
/**
|
|
187
|
+
* Create a new DiagnosticsManager instance
|
|
188
|
+
*/
|
|
189
|
+
export declare function createDiagnosticsManager(): DiagnosticsManager;
|
|
190
|
+
/**
|
|
191
|
+
* Get severity icon
|
|
192
|
+
*/
|
|
193
|
+
export declare function getSeverityIcon(severity: DiagnosticSeverity): string;
|
|
194
|
+
/**
|
|
195
|
+
* Get severity color
|
|
196
|
+
*/
|
|
197
|
+
export declare function getSeverityColor(severity: DiagnosticSeverity): string;
|
|
198
|
+
/**
|
|
199
|
+
* Get severity label
|
|
200
|
+
*/
|
|
201
|
+
export declare function getSeverityLabel(severity: DiagnosticSeverity): string;
|
|
202
|
+
/**
|
|
203
|
+
* Sort diagnostics by severity then line
|
|
204
|
+
*/
|
|
205
|
+
export declare function sortDiagnostics(diagnostics: Diagnostic[]): Diagnostic[];
|
|
206
|
+
/**
|
|
207
|
+
* Generate mock diagnostics for testing
|
|
208
|
+
*/
|
|
209
|
+
export declare function generateMockDiagnostics(lineCount: number): Diagnostic[];
|
|
210
|
+
export {};
|