@nocturnium/svelte-ide 1.0.2 → 1.0.4

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.
Files changed (78) hide show
  1. package/README.md +5 -3
  2. package/dist/components/ai/AIMessageContent.svelte +24 -14
  3. package/dist/components/ai/AIPanel.svelte +22 -0
  4. package/dist/components/editor/CollaborativeEditor.svelte +68 -5
  5. package/dist/components/editor/CollaborativeEditor.svelte.d.ts +14 -0
  6. package/dist/components/editor/ContextLens.svelte +16 -10
  7. package/dist/components/editor/CustomEditor.svelte +52 -33
  8. package/dist/components/editor/CustomEditor.svelte.d.ts +2 -2
  9. package/dist/components/editor/EchoCursorLayer.svelte +43 -11
  10. package/dist/components/editor/Editor.svelte +17 -0
  11. package/dist/components/editor/Editor.svelte.d.ts +9 -0
  12. package/dist/components/editor/EditorPane.svelte +18 -1
  13. package/dist/components/editor/EditorPane.svelte.d.ts +5 -0
  14. package/dist/components/editor/EditorSelections.svelte +27 -11
  15. package/dist/components/editor/EditorSelections.svelte.d.ts +1 -0
  16. package/dist/components/editor/GhostBracketLayer.svelte +38 -25
  17. package/dist/components/editor/core/folding.d.ts +11 -0
  18. package/dist/components/editor/core/folding.js +41 -0
  19. package/dist/components/editor/core/index.d.ts +0 -5
  20. package/dist/components/editor/core/index.js +4 -5
  21. package/dist/components/editor/core/state.d.ts +5 -0
  22. package/dist/components/editor/core/state.js +131 -12
  23. package/dist/components/editor/editor-find.d.ts +1 -0
  24. package/dist/components/editor/editor-find.js +6 -5
  25. package/dist/components/editor/editor-input.d.ts +1 -0
  26. package/dist/components/editor/editor-input.js +4 -1
  27. package/dist/components/editor/editor-scroll.d.ts +1 -0
  28. package/dist/components/editor/editor-scroll.js +2 -1
  29. package/dist/components/editor/index.d.ts +19 -3
  30. package/dist/components/editor/index.js +18 -4
  31. package/dist/components/editor/tokenizer/base.d.ts +1 -25
  32. package/dist/components/editor/tokenizer/base.js +0 -172
  33. package/dist/components/editor/tokenizer/index.d.ts +4 -0
  34. package/dist/components/editor/tokenizer/index.js +1 -1
  35. package/dist/components/editor/tokenizer/languages/html.d.ts +3 -2
  36. package/dist/components/editor/tokenizer/languages/html.js +64 -6
  37. package/dist/components/editor/tokenizer/languages/javascript.d.ts +0 -3
  38. package/dist/components/editor/tokenizer/languages/javascript.js +1 -2
  39. package/dist/components/editor/tokenizer/languages/svelte.d.ts +1 -1
  40. package/dist/components/editor/tokenizer/languages/svelte.js +6 -1
  41. package/dist/components/editor/tokenizer/types.d.ts +0 -28
  42. package/dist/crdt/awareness.d.ts +8 -2
  43. package/dist/crdt/awareness.js +11 -4
  44. package/dist/crdt/document.d.ts +10 -1
  45. package/dist/crdt/document.js +15 -7
  46. package/dist/crdt/index.d.ts +8 -2
  47. package/dist/crdt/index.js +5 -2
  48. package/dist/crdt/undo.d.ts +2 -7
  49. package/dist/crdt/undo.js +1 -8
  50. package/dist/index.d.ts +7 -9
  51. package/dist/index.js +7 -9
  52. package/dist/services/error-handling.d.ts +2 -11
  53. package/dist/services/error-handling.js +15 -4
  54. package/dist/services/lsp-client.d.ts +3 -0
  55. package/dist/services/lsp-client.js +55 -10
  56. package/dist/services/mock-ai.js +1 -1
  57. package/dist/services/optimistic.d.ts +8 -5
  58. package/dist/services/optimistic.js +36 -10
  59. package/dist/services/vfs-client.js +11 -3
  60. package/dist/stores/agents.svelte.js +3 -2
  61. package/dist/stores/ai-persistence.svelte.js +7 -2
  62. package/dist/stores/ai.svelte.js +3 -2
  63. package/dist/stores/collaboration.svelte.d.ts +1 -1
  64. package/dist/stores/collaboration.svelte.js +3 -2
  65. package/dist/stores/editor.svelte.js +29 -5
  66. package/dist/stores/layout.svelte.js +3 -0
  67. package/dist/stores/plugin.svelte.js +9 -3
  68. package/dist/stores/vfs.svelte.js +26 -9
  69. package/dist/styles/theme.css +43 -0
  70. package/dist/types/vfs.d.ts +15 -1
  71. package/dist/types/vfs.js +9 -0
  72. package/dist/utils/language.d.ts +4 -3
  73. package/dist/utils/language.js +8 -18
  74. package/package.json +1 -1
  75. package/dist/components/editor/MinimalEditor.svelte +0 -75
  76. package/dist/components/editor/MinimalEditor.svelte.d.ts +0 -6
  77. package/dist/components/editor/MinimalEditor2.svelte +0 -84
  78. package/dist/components/editor/MinimalEditor2.svelte.d.ts +0 -6
@@ -2,9 +2,13 @@
2
2
  * HTML/XML tokenizer
3
3
  */
4
4
  import { createToken } from '../base';
5
+ import { createCSSTokenizer } from './css';
6
+ import { createJavaScriptTokenizer } from './javascript';
5
7
  export class HTMLTokenizer {
6
8
  language;
7
9
  isXML;
10
+ jsTokenizer = createJavaScriptTokenizer();
11
+ cssTokenizer = createCSSTokenizer();
8
12
  constructor(options = {}) {
9
13
  this.isXML = options.xml ?? false;
10
14
  this.language = this.isXML ? 'xml' : 'html';
@@ -29,6 +33,54 @@ export class HTMLTokenizer {
29
33
  return { lineNumber, tokens, text: line, state };
30
34
  }
31
35
  }
36
+ if (!this.isXML && state.inScript) {
37
+ const closeScriptMatch = line.match(/<\/script>/i);
38
+ if (closeScriptMatch) {
39
+ const scriptPart = line.slice(0, closeScriptMatch.index);
40
+ if (scriptPart) {
41
+ const result = this.jsTokenizer.tokenizeLine(scriptPart, lineNumber, state.innerState ?? this.jsTokenizer.getInitialState());
42
+ tokens.push(...result.tokens);
43
+ state.innerState = result.state;
44
+ }
45
+ state.inScript = false;
46
+ state.innerState = undefined;
47
+ pos = closeScriptMatch.index;
48
+ }
49
+ else {
50
+ const result = this.jsTokenizer.tokenizeLine(line, lineNumber, state.innerState ?? this.jsTokenizer.getInitialState());
51
+ state.innerState = result.state;
52
+ return {
53
+ lineNumber,
54
+ tokens: result.tokens,
55
+ text: line,
56
+ state
57
+ };
58
+ }
59
+ }
60
+ if (!this.isXML && state.inStyle) {
61
+ const closeStyleMatch = line.match(/<\/style>/i);
62
+ if (closeStyleMatch) {
63
+ const stylePart = line.slice(0, closeStyleMatch.index);
64
+ if (stylePart) {
65
+ const result = this.cssTokenizer.tokenizeLine(stylePart, lineNumber, state.innerState ?? this.cssTokenizer.getInitialState());
66
+ tokens.push(...result.tokens);
67
+ state.innerState = result.state;
68
+ }
69
+ state.inStyle = false;
70
+ state.innerState = undefined;
71
+ pos = closeStyleMatch.index;
72
+ }
73
+ else {
74
+ const result = this.cssTokenizer.tokenizeLine(line, lineNumber, state.innerState ?? this.cssTokenizer.getInitialState());
75
+ state.innerState = result.state;
76
+ return {
77
+ lineNumber,
78
+ tokens: result.tokens,
79
+ text: line,
80
+ state
81
+ };
82
+ }
83
+ }
32
84
  while (pos < line.length) {
33
85
  const remaining = line.slice(pos);
34
86
  const token = this.getNextToken(remaining, pos, state, line);
@@ -89,10 +141,14 @@ export class HTMLTokenizer {
89
141
  const closingTagMatch = text.match(/^<\/([a-zA-Z][a-zA-Z0-9:-]*)>/);
90
142
  if (closingTagMatch) {
91
143
  const tagName = closingTagMatch[1].toLowerCase();
92
- if (tagName === 'script')
144
+ if (tagName === 'script') {
93
145
  state.inScript = false;
94
- if (tagName === 'style')
146
+ state.innerState = undefined;
147
+ }
148
+ if (tagName === 'style') {
95
149
  state.inStyle = false;
150
+ state.innerState = undefined;
151
+ }
96
152
  return createToken('tag', closingTagMatch[0], pos);
97
153
  }
98
154
  // Opening tag
@@ -121,17 +177,19 @@ export class HTMLTokenizer {
121
177
  }
122
178
  if (openingMatch) {
123
179
  const tagName = openingMatch[1].toLowerCase();
124
- if (tagName === 'script')
180
+ if (!this.isXML && tagName === 'script') {
125
181
  state.inScript = true;
126
- if (tagName === 'style')
182
+ state.innerState = this.jsTokenizer.getInitialState();
183
+ }
184
+ if (!this.isXML && tagName === 'style') {
127
185
  state.inStyle = true;
186
+ state.innerState = this.cssTokenizer.getInitialState();
187
+ }
128
188
  return createToken('tag', openingMatch[0], pos);
129
189
  }
130
190
  // Partial tag - just match the tag name part
131
191
  const partialMatch = text.match(/^<([a-zA-Z][a-zA-Z0-9:-]*)/);
132
192
  if (partialMatch) {
133
- state.inTag = true;
134
- state.tagName = partialMatch[1];
135
193
  return createToken('tag.name', partialMatch[0], pos);
136
194
  }
137
195
  return createToken('tag.punctuation', '<', pos);
@@ -4,9 +4,6 @@
4
4
  import type { TokenizedLine, TokenizerState } from '../types';
5
5
  interface JSTokenizerState extends TokenizerState {
6
6
  templateDepth?: number;
7
- jsxDepth?: number;
8
- /** Track if regex is valid in current context (for division vs regex ambiguity) */
9
- expectExpression?: boolean;
10
7
  /**
11
8
  * Last significant token text, used for regex/division disambiguation.
12
9
  * Stored per-line in the threaded state (not on the tokenizer instance) so a
@@ -234,8 +234,7 @@ export class JavaScriptTokenizer {
234
234
  }
235
235
  getInitialState() {
236
236
  return {
237
- templateDepth: 0,
238
- jsxDepth: 0
237
+ templateDepth: 0
239
238
  };
240
239
  }
241
240
  tokenizeLine(line, lineNumber, prevState) {
@@ -29,7 +29,7 @@ export declare class SvelteTokenizer implements LanguageTokenizer {
29
29
  private cssTokenizer;
30
30
  constructor();
31
31
  getInitialState(): SvelteTokenizerState;
32
- tokenizeLine(line: string, lineNumber: number, state: SvelteTokenizerState): TokenizedLine;
32
+ tokenizeLine(line: string, lineNumber: number, prevState?: SvelteTokenizerState): TokenizedLine;
33
33
  private tokenizeTemplate;
34
34
  private tokenizeTag;
35
35
  private tokenizeJSExpression;
@@ -65,9 +65,14 @@ export class SvelteTokenizer {
65
65
  tagDepth: 0
66
66
  };
67
67
  }
68
- tokenizeLine(line, lineNumber, state) {
68
+ tokenizeLine(line, lineNumber, prevState) {
69
69
  const tokens = [];
70
70
  let pos = 0;
71
+ const state = {
72
+ ...this.getInitialState(),
73
+ ...prevState,
74
+ innerState: prevState?.innerState ? { ...prevState.innerState } : undefined
75
+ };
71
76
  // Handle script context
72
77
  if (state.context === 'script') {
73
78
  const closeScriptMatch = line.match(/<\/script>/i);
@@ -56,31 +56,3 @@ export interface LanguageTokenizer {
56
56
  /** Get initial state */
57
57
  getInitialState(): TokenizerState;
58
58
  }
59
- /**
60
- * Token rule for regex-based tokenization
61
- */
62
- export interface TokenRule {
63
- /** Token type to assign */
64
- type: TokenType;
65
- /** Regex pattern to match */
66
- pattern: RegExp;
67
- /** Optional: next state after matching */
68
- nextState?: string;
69
- /** Optional: pop state after matching */
70
- popState?: boolean;
71
- }
72
- /**
73
- * Grammar definition for a language
74
- */
75
- export interface LanguageGrammar {
76
- /** Language identifier */
77
- language: string;
78
- /** File extensions */
79
- extensions: string[];
80
- /** Line comment prefix */
81
- lineComment?: string;
82
- /** Block comment start/end */
83
- blockComment?: [string, string];
84
- /** Token rules by state */
85
- rules: Record<string, TokenRule[]>;
86
- }
@@ -28,10 +28,16 @@ export interface AwarenessProtocol {
28
28
  onUsersChange(callback: (users: AwarenessUser[]) => void): () => void;
29
29
  destroy(): void;
30
30
  }
31
+ export interface CreateAwarenessProtocolOptions {
32
+ destroyAwareness?: boolean;
33
+ }
31
34
  /**
32
- * Create an awareness protocol instance
35
+ * Create an awareness protocol instance.
36
+ *
37
+ * Pass a provider-owned Awareness instance to broadcast presence through that
38
+ * provider. Passing a Y.Doc creates a standalone Awareness instance.
33
39
  */
34
- export declare function createAwarenessProtocol(doc: YDoc): AwarenessProtocol;
40
+ export declare function createAwarenessProtocol(source: YDoc | Awareness, options?: CreateAwarenessProtocolOptions): AwarenessProtocol;
35
41
  /**
36
42
  * Generate a random color for a user
37
43
  */
@@ -3,10 +3,15 @@
3
3
  */
4
4
  import { Awareness } from 'y-protocols/awareness';
5
5
  /**
6
- * Create an awareness protocol instance
6
+ * Create an awareness protocol instance.
7
+ *
8
+ * Pass a provider-owned Awareness instance to broadcast presence through that
9
+ * provider. Passing a Y.Doc creates a standalone Awareness instance.
7
10
  */
8
- export function createAwarenessProtocol(doc) {
9
- const awareness = new Awareness(doc);
11
+ export function createAwarenessProtocol(source, options = {}) {
12
+ const ownsAwareness = source instanceof Awareness;
13
+ const awareness = ownsAwareness ? source : new Awareness(source);
14
+ const shouldDestroyAwareness = options.destroyAwareness ?? !ownsAwareness;
10
15
  const userChangeCallbacks = new Set();
11
16
  // Track awareness changes
12
17
  awareness.on('change', () => {
@@ -75,7 +80,9 @@ export function createAwarenessProtocol(doc) {
75
80
  return () => userChangeCallbacks.delete(callback);
76
81
  },
77
82
  destroy() {
78
- awareness.destroy();
83
+ if (shouldDestroyAwareness) {
84
+ awareness.destroy();
85
+ }
79
86
  userChangeCallbacks.clear();
80
87
  }
81
88
  };
@@ -4,6 +4,11 @@
4
4
  */
5
5
  import * as Y from 'yjs';
6
6
  import type { DocumentOptions } from './types';
7
+ export interface CollaborativeUndoManagerOptions {
8
+ captureTimeout?: number;
9
+ trackedOrigins?: Set<unknown>;
10
+ deleteFilter?: (item: Y.Item) => boolean;
11
+ }
7
12
  export declare class CollaborativeDocument {
8
13
  readonly doc: Y.Doc;
9
14
  readonly id: string;
@@ -49,7 +54,11 @@ export declare class CollaborativeDocument {
49
54
  /**
50
55
  * Setup undo manager
51
56
  */
52
- private setupUndoManager;
57
+ getUndoManager(options?: CollaborativeUndoManagerOptions): Y.UndoManager;
58
+ /**
59
+ * Check whether this document currently owns an undo manager.
60
+ */
61
+ hasUndoManager(): boolean;
53
62
  /**
54
63
  * Track additional origins for undo
55
64
  */
@@ -18,7 +18,7 @@ export class CollaborativeDocument {
18
18
  }
19
19
  // Setup undo manager if enabled
20
20
  if (options.enableUndo !== false) {
21
- this.setupUndoManager(options.undoCaptureTimeout);
21
+ this.getUndoManager({ captureTimeout: options.undoCaptureTimeout });
22
22
  }
23
23
  }
24
24
  /**
@@ -97,20 +97,28 @@ export class CollaborativeDocument {
97
97
  /**
98
98
  * Setup undo manager
99
99
  */
100
- setupUndoManager(captureTimeout = 500) {
101
- const trackedOrigins = new Set([null, 'local']);
100
+ getUndoManager(options = {}) {
101
+ if (this.undoManager)
102
+ return this.undoManager;
103
+ const { captureTimeout = 500, trackedOrigins = new Set([null, 'local']), deleteFilter } = options;
102
104
  this.undoManager = new Y.UndoManager(this.getText(), {
103
105
  trackedOrigins,
104
- captureTimeout
106
+ captureTimeout,
107
+ deleteFilter
105
108
  });
109
+ return this.undoManager;
110
+ }
111
+ /**
112
+ * Check whether this document currently owns an undo manager.
113
+ */
114
+ hasUndoManager() {
115
+ return this.undoManager !== null;
106
116
  }
107
117
  /**
108
118
  * Track additional origins for undo
109
119
  */
110
120
  trackOrigin(origin) {
111
- if (this.undoManager) {
112
- this.undoManager.trackedOrigins.add(origin);
113
- }
121
+ this.getUndoManager().trackedOrigins.add(origin);
114
122
  }
115
123
  /**
116
124
  * Undo last change
@@ -4,6 +4,12 @@
4
4
  */
5
5
  export { CollaborativeDocument } from './document';
6
6
  export { CollaborativeProvider } from './provider';
7
- export { createAwarenessProtocol } from './awareness';
8
- export { createUndoManager } from './undo';
7
+ export { createProvider } from './provider';
8
+ export { createAwarenessProtocol, generateUserColor, getInitials } from './awareness';
9
+ export { createUndoManager, createUserUndoManager } from './undo';
10
+ export { default as CollaborativeEditor } from '../components/editor/CollaborativeEditor.svelte';
11
+ export { CRDTBinding, createCRDTBinding, createRelativePosition, resolveRelativePosition } from '../components/editor/core/crdt-binding';
9
12
  export type * from './types';
13
+ export type { AwarenessProtocol, AwarenessUser, CreateAwarenessProtocolOptions } from './awareness';
14
+ export type { UndoManagerInstance, UndoManagerOptions, UndoManagerState } from './undo';
15
+ export type { CRDTBindingConfig, CRDTPosition, RelativePosition } from '../components/editor/core/crdt-binding';
@@ -4,5 +4,8 @@
4
4
  */
5
5
  export { CollaborativeDocument } from './document';
6
6
  export { CollaborativeProvider } from './provider';
7
- export { createAwarenessProtocol } from './awareness';
8
- export { createUndoManager } from './undo';
7
+ export { createProvider } from './provider';
8
+ export { createAwarenessProtocol, generateUserColor, getInitials } from './awareness';
9
+ export { createUndoManager, createUserUndoManager } from './undo';
10
+ export { default as CollaborativeEditor } from '../components/editor/CollaborativeEditor.svelte';
11
+ export { CRDTBinding, createCRDTBinding, createRelativePosition, resolveRelativePosition } from '../components/editor/core/crdt-binding';
@@ -1,13 +1,8 @@
1
1
  /**
2
2
  * Undo manager for CRDT documents
3
3
  */
4
- import * as Y from 'yjs';
5
- import type { CollaborativeDocument } from './document';
6
- export interface UndoManagerOptions {
7
- captureTimeout?: number;
8
- trackedOrigins?: Set<unknown>;
9
- deleteFilter?: (item: Y.Item) => boolean;
10
- }
4
+ import type { CollaborativeDocument, CollaborativeUndoManagerOptions } from './document';
5
+ export type UndoManagerOptions = CollaborativeUndoManagerOptions;
11
6
  export interface UndoManagerState {
12
7
  canUndo: boolean;
13
8
  canRedo: boolean;
package/dist/crdt/undo.js CHANGED
@@ -1,18 +1,11 @@
1
1
  /**
2
2
  * Undo manager for CRDT documents
3
3
  */
4
- import * as Y from 'yjs';
5
4
  /**
6
5
  * Create an undo manager for a collaborative document
7
6
  */
8
7
  export function createUndoManager(document, options = {}) {
9
- const { captureTimeout = 500, trackedOrigins = new Set([null, 'local']), deleteFilter } = options;
10
- const text = document.getText();
11
- const manager = new Y.UndoManager(text, {
12
- captureTimeout,
13
- trackedOrigins,
14
- deleteFilter
15
- });
8
+ const manager = document.getUndoManager(options);
16
9
  const stateCallbacks = new Set();
17
10
  function getState() {
18
11
  return {
package/dist/index.d.ts CHANGED
@@ -8,7 +8,7 @@
8
8
  * - All UI components built from scratch (no UI libraries)
9
9
  * - Native Svelte 5 runes for state management
10
10
  * - Custom code editor (no CodeMirror dependency)
11
- * - Yjs for CRDT collaboration (optional, tree-shakeable)
11
+ * - Yjs for CRDT collaboration (optional via the ./crdt entry)
12
12
  *
13
13
  * ============================================================================
14
14
  * PUBLIC API SURFACE — what belongs in this root barrel
@@ -111,11 +111,6 @@ export { default as Editor } from './components/editor/Editor.svelte';
111
111
  * @public - Stable API
112
112
  */
113
113
  export { default as CustomEditor } from './components/editor/CustomEditor.svelte';
114
- /**
115
- * Collaborative editor with CRDT support
116
- * @experimental - requires the optional yjs peers; API may change in future versions
117
- */
118
- export { default as CollaborativeEditor } from './components/editor/CollaborativeEditor.svelte';
119
114
  /**
120
115
  * Editor tab bar component
121
116
  * @public - Stable API
@@ -142,14 +137,17 @@ export { default as FileExplorer, type FileChangeStatus, type GitFileStatus } fr
142
137
  *
143
138
  * Functions and types marked below:
144
139
  * createEditorState, createNavigation, createKeyboardHandler,
145
- * createDefaultKeybindings, createCRDTBinding,
140
+ * createDefaultKeybindings,
146
141
  * EditorState, Position, Selection, Line, ChangeEvent,
147
- * Navigation, KeyboardHandler, Keybinding, CRDTBinding,
142
+ * Navigation, KeyboardHandler, Keybinding,
148
143
  * Cursor, CursorManager, CursorManagerConfig
149
144
  *
150
145
  * @public - Stable API
151
146
  */
152
- export { createEditorState, createNavigation, createKeyboardHandler, createDefaultKeybindings, createCRDTBinding, type EditorState, type Position, type Selection, type Line, type ChangeEvent, type Navigation, type KeyboardHandler, type Keybinding, type CRDTBinding, type Cursor, type CursorManager, type CursorManagerConfig } from './components/editor/core';
147
+ export { createEditorState, type EditorState, type Position, type Selection, type Line, type ChangeEvent } from './components/editor/core/state';
148
+ export { createNavigation, type Navigation } from './components/editor/core/navigation';
149
+ export { createKeyboardHandler, createDefaultKeybindings, type KeyboardHandler, type Keybinding } from './components/editor/core/keybindings';
150
+ export { type Cursor, type CursorManager, type CursorManagerConfig } from './components/editor/core/multi-cursor';
153
151
  /**
154
152
  * Editor theme utilities and types
155
153
  * @public - Stable API
package/dist/index.js CHANGED
@@ -8,7 +8,7 @@
8
8
  * - All UI components built from scratch (no UI libraries)
9
9
  * - Native Svelte 5 runes for state management
10
10
  * - Custom code editor (no CodeMirror dependency)
11
- * - Yjs for CRDT collaboration (optional, tree-shakeable)
11
+ * - Yjs for CRDT collaboration (optional via the ./crdt entry)
12
12
  *
13
13
  * ============================================================================
14
14
  * PUBLIC API SURFACE — what belongs in this root barrel
@@ -117,11 +117,6 @@ export { default as Editor } from './components/editor/Editor.svelte';
117
117
  * @public - Stable API
118
118
  */
119
119
  export { default as CustomEditor } from './components/editor/CustomEditor.svelte';
120
- /**
121
- * Collaborative editor with CRDT support
122
- * @experimental - requires the optional yjs peers; API may change in future versions
123
- */
124
- export { default as CollaborativeEditor } from './components/editor/CollaborativeEditor.svelte';
125
120
  /**
126
121
  * Editor tab bar component
127
122
  * @public - Stable API
@@ -148,14 +143,17 @@ export { default as FileExplorer } from './components/editor/FileExplorer.svelte
148
143
  *
149
144
  * Functions and types marked below:
150
145
  * createEditorState, createNavigation, createKeyboardHandler,
151
- * createDefaultKeybindings, createCRDTBinding,
146
+ * createDefaultKeybindings,
152
147
  * EditorState, Position, Selection, Line, ChangeEvent,
153
- * Navigation, KeyboardHandler, Keybinding, CRDTBinding,
148
+ * Navigation, KeyboardHandler, Keybinding,
154
149
  * Cursor, CursorManager, CursorManagerConfig
155
150
  *
156
151
  * @public - Stable API
157
152
  */
158
- export { createEditorState, createNavigation, createKeyboardHandler, createDefaultKeybindings, createCRDTBinding } from './components/editor/core';
153
+ export { createEditorState } from './components/editor/core/state';
154
+ export { createNavigation } from './components/editor/core/navigation';
155
+ export { createKeyboardHandler, createDefaultKeybindings } from './components/editor/core/keybindings';
156
+ export {} from './components/editor/core/multi-cursor';
159
157
  /**
160
158
  * Editor theme utilities and types
161
159
  * @public - Stable API
@@ -3,17 +3,8 @@
3
3
  *
4
4
  * Provides structured error types, recovery strategies, and user-friendly error messages.
5
5
  */
6
- export type VFSErrorCode = 'NETWORK_ERROR' | 'CONNECTION_LOST' | 'TIMEOUT' | 'FILE_LOCKED' | 'LOCK_EXPIRED' | 'LOCK_CONFLICT' | 'VERSION_CONFLICT' | 'FILE_NOT_FOUND' | 'PERMISSION_DENIED' | 'WORKSPACE_NOT_FOUND' | 'INVALID_OPERATION' | 'SERVER_ERROR' | 'RATE_LIMITED' | 'UNKNOWN';
7
- export interface VFSError extends Error {
8
- code: VFSErrorCode;
9
- statusCode?: number;
10
- path?: string;
11
- workspaceId?: string;
12
- retryable: boolean;
13
- userMessage: string;
14
- technicalDetails?: string;
15
- recoveryOptions: RecoveryOption[];
16
- }
6
+ import { VFSError, type VFSErrorCode } from '../types/vfs';
7
+ export { VFSError, type VFSErrorCode };
17
8
  export interface RecoveryOption {
18
9
  id: string;
19
10
  label: string;
@@ -3,6 +3,11 @@
3
3
  *
4
4
  * Provides structured error types, recovery strategies, and user-friendly error messages.
5
5
  */
6
+ import { VFSError } from '../types/vfs';
7
+ // ============================================================================
8
+ // Error Types
9
+ // ============================================================================
10
+ export { VFSError };
6
11
  // ============================================================================
7
12
  // Error Factory
8
13
  // ============================================================================
@@ -10,9 +15,7 @@
10
15
  * Create a structured VFS error
11
16
  */
12
17
  export function createVFSError(code, message, options = {}) {
13
- const error = new Error(message);
14
- error.name = 'VFSError';
15
- error.code = code;
18
+ const error = new VFSError(message, code, options.cause);
16
19
  error.statusCode = options.statusCode;
17
20
  error.path = options.path;
18
21
  error.workspaceId = options.workspaceId;
@@ -29,6 +32,14 @@ export function createVFSError(code, message, options = {}) {
29
32
  export function parseError(error, context) {
30
33
  // Already a VFSError
31
34
  if (isVFSError(error)) {
35
+ error.path ??= context?.path;
36
+ error.workspaceId ??= context?.workspaceId;
37
+ error.retryable = isRetryableError(error.code);
38
+ error.userMessage = getUserMessage(error.code, error.path);
39
+ error.technicalDetails ??= error.message;
40
+ if (error.recoveryOptions.length === 0) {
41
+ error.recoveryOptions = getRecoveryOptions(error.code);
42
+ }
32
43
  return error;
33
44
  }
34
45
  // Network/fetch errors
@@ -97,7 +108,7 @@ function parseStatusCode(status, message, context) {
97
108
  * Check if error is a VFSError
98
109
  */
99
110
  export function isVFSError(error) {
100
- return error instanceof Error && 'code' in error && 'retryable' in error;
111
+ return error instanceof VFSError;
101
112
  }
102
113
  /**
103
114
  * Check if error code is retryable
@@ -13,6 +13,7 @@ export declare class LSPClient {
13
13
  private _capabilities;
14
14
  private reconnectAttempts;
15
15
  private reconnectTimeout;
16
+ private intentionalDisconnect;
16
17
  private openDocuments;
17
18
  private diagnosticsCache;
18
19
  private eventHandlers;
@@ -28,6 +29,8 @@ export declare class LSPClient {
28
29
  private emitEvent;
29
30
  private setState;
30
31
  connect(): Promise<void>;
32
+ private cleanupSocket;
33
+ private getReconnectDelay;
31
34
  private handleDisconnect;
32
35
  disconnect(): Promise<void>;
33
36
  private initialize;