@nocturnium/svelte-ide 1.1.1 → 1.2.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.
Files changed (33) hide show
  1. package/dist/components/editor/CognitiveLoadMeter.svelte +27 -0
  2. package/dist/components/editor/ComplexityHeatLayer.svelte +157 -0
  3. package/dist/components/editor/ComplexityHeatLayer.svelte.d.ts +24 -0
  4. package/dist/components/editor/ComplexityLayer.svelte +325 -109
  5. package/dist/components/editor/ComplexityLayer.svelte.d.ts +13 -0
  6. package/dist/components/editor/ConflictZoneLayer.svelte +22 -15
  7. package/dist/components/editor/CustomEditor.svelte +80 -1
  8. package/dist/components/editor/CustomEditor.svelte.d.ts +3 -1
  9. package/dist/components/editor/EchoCursorLayer.svelte +60 -0
  10. package/dist/components/editor/PluginPreviewSandbox.svelte +43 -9
  11. package/dist/components/editor/PluginPreviewSandbox.svelte.d.ts +4 -4
  12. package/dist/components/editor/core/complexity-analyzer.d.ts +31 -0
  13. package/dist/components/editor/core/complexity-analyzer.js +479 -29
  14. package/dist/components/editor/core/conflict-predictor.d.ts +32 -0
  15. package/dist/components/editor/core/conflict-predictor.js +55 -0
  16. package/dist/components/editor/core/crdt-binding.d.ts +4 -0
  17. package/dist/components/editor/core/crdt-binding.js +34 -9
  18. package/dist/components/editor/core/echo-cursor.d.ts +18 -1
  19. package/dist/components/editor/core/echo-cursor.js +117 -6
  20. package/dist/components/editor/core/extract-function.d.ts +27 -0
  21. package/dist/components/editor/core/extract-function.js +865 -0
  22. package/dist/components/editor/core/index.d.ts +1 -0
  23. package/dist/components/editor/core/index.js +1 -0
  24. package/dist/components/editor/core/state.d.ts +38 -5
  25. package/dist/components/editor/core/state.js +175 -98
  26. package/dist/components/editor/core/timeline.js +6 -1
  27. package/dist/components/editor/editor-find.js +15 -3
  28. package/dist/components/editor/theme.d.ts +8 -0
  29. package/dist/components/editor/theme.js +52 -0
  30. package/dist/services/lsp-client.d.ts +3 -0
  31. package/dist/services/lsp-client.js +86 -14
  32. package/dist/styles/theme.css +4 -1
  33. package/package.json +1 -1
@@ -20,8 +20,10 @@ export const tokenColors = {
20
20
  // Keywords
21
21
  keyword: 'var(--color-nocturnium-aurora-purple)',
22
22
  keywordControl: 'var(--color-nocturnium-aurora-purple)',
23
+ keywordOperator: 'var(--color-nocturnium-aurora-purple)',
23
24
  keywordDefinition: 'var(--color-nocturnium-aurora-purple)',
24
25
  keywordModule: 'var(--color-nocturnium-aurora-purple)',
26
+ keywordStorage: 'var(--color-nocturnium-aurora-purple)',
25
27
  // Operators
26
28
  operator: 'var(--ide-text-primary)',
27
29
  // Variables
@@ -34,20 +36,26 @@ export const tokenColors = {
34
36
  functionDefinition: 'var(--color-nocturnium-aurora-blue)',
35
37
  // Properties
36
38
  property: 'var(--color-nocturnium-wave)',
39
+ propertyDefinition: 'var(--color-nocturnium-wave)',
37
40
  // Types (distinct teal hue so types read differently from numbers/constants)
38
41
  type: 'var(--color-nocturnium-teal)',
39
42
  typeClass: 'var(--color-nocturnium-teal)',
43
+ typeInterface: 'var(--color-nocturnium-teal)',
44
+ typeNamespace: 'var(--color-nocturnium-teal)',
40
45
  typeBuiltin: 'var(--color-nocturnium-teal)',
41
46
  // Constants
42
47
  constant: 'var(--color-nocturnium-aurora-yellow)',
43
48
  constantBoolean: 'var(--color-nocturnium-aurora-yellow)',
44
49
  constantNull: 'var(--color-nocturnium-aurora-yellow)',
50
+ constantBuiltin: 'var(--color-nocturnium-aurora-yellow)',
45
51
  // Punctuation
46
52
  punctuation: 'var(--ide-text-secondary)',
53
+ punctuationBrace: 'var(--color-nocturnium-aurora-yellow)',
47
54
  // Tags (HTML/XML)
48
55
  tag: 'var(--color-nocturnium-aurora-pink)',
49
56
  tagAttribute: 'var(--color-nocturnium-aurora-yellow)',
50
57
  tagAttributeValue: 'var(--color-nocturnium-aurora-green)',
58
+ tagPunctuation: 'var(--ide-text-secondary)',
51
59
  // Markup (Markdown)
52
60
  markupHeading: 'var(--color-nocturnium-aurora-blue)',
53
61
  markupLink: 'var(--color-nocturnium-wave)',
@@ -107,18 +115,62 @@ export function getThemeCSS(theme = nocturniumTheme) {
107
115
  /* Token Colors */
108
116
  --editor-token-comment: ${theme.tokenColors.comment};
109
117
  --editor-token-string: ${theme.tokenColors.string};
118
+ --editor-token-string-template: ${theme.tokenColors.stringTemplate};
119
+ --editor-token-string-regex: ${theme.tokenColors.stringRegex};
120
+ --editor-token-string-escape: ${theme.tokenColors.stringEscape};
110
121
  --editor-token-number: ${theme.tokenColors.number};
111
122
  --editor-token-keyword: ${theme.tokenColors.keyword};
123
+ --editor-token-keyword-control: ${theme.tokenColors.keywordControl};
124
+ --editor-token-keyword-operator: ${theme.tokenColors.keywordOperator};
125
+ --editor-token-keyword-definition: ${theme.tokenColors.keywordDefinition};
126
+ --editor-token-keyword-module: ${theme.tokenColors.keywordModule};
127
+ --editor-token-keyword-storage: ${theme.tokenColors.keywordStorage};
112
128
  --editor-token-operator: ${theme.tokenColors.operator};
113
129
  --editor-token-variable: ${theme.tokenColors.variable};
130
+ --editor-token-variable-definition: ${theme.tokenColors.variableDefinition};
131
+ --editor-token-variable-parameter: ${theme.tokenColors.variableParameter};
114
132
  --editor-token-function: ${theme.tokenColors.function};
133
+ --editor-token-function-call: ${theme.tokenColors.functionCall};
134
+ --editor-token-function-definition: ${theme.tokenColors.functionDefinition};
115
135
  --editor-token-property: ${theme.tokenColors.property};
136
+ --editor-token-property-definition: ${theme.tokenColors.propertyDefinition};
116
137
  --editor-token-type: ${theme.tokenColors.type};
138
+ --editor-token-type-class: ${theme.tokenColors.typeClass};
139
+ --editor-token-type-interface: ${theme.tokenColors.typeInterface};
140
+ --editor-token-type-namespace: ${theme.tokenColors.typeNamespace};
141
+ --editor-token-type-builtin: ${theme.tokenColors.typeBuiltin};
117
142
  --editor-token-constant: ${theme.tokenColors.constant};
143
+ --editor-token-constant-boolean: ${theme.tokenColors.constantBoolean};
144
+ --editor-token-constant-null: ${theme.tokenColors.constantNull};
145
+ --editor-token-constant-builtin: ${theme.tokenColors.constantBuiltin};
118
146
  --editor-token-punctuation: ${theme.tokenColors.punctuation};
147
+ --editor-token-punctuation-brace: ${theme.tokenColors.punctuationBrace};
119
148
  --editor-token-tag: ${theme.tokenColors.tag};
149
+ --editor-token-tag-attribute: ${theme.tokenColors.tagAttribute};
150
+ --editor-token-tag-attribute-value: ${theme.tokenColors.tagAttributeValue};
151
+ --editor-token-tag-punctuation: ${theme.tokenColors.tagPunctuation};
152
+ --editor-token-markup-heading: ${theme.tokenColors.markupHeading};
153
+ --editor-token-markup-link: ${theme.tokenColors.markupLink};
154
+ --editor-token-markup-code: ${theme.tokenColors.markupCode};
155
+ --editor-token-markup-quote: ${theme.tokenColors.markupQuote};
156
+ --editor-token-markup-list: ${theme.tokenColors.markupList};
120
157
  --editor-token-invalid: ${theme.tokenColors.invalid};
121
158
 
159
+ /* Syntax aliases used by editor/code surfaces */
160
+ --ide-syntax-comment: ${theme.tokenColors.comment};
161
+ --ide-syntax-string: ${theme.tokenColors.string};
162
+ --ide-syntax-number: ${theme.tokenColors.number};
163
+ --ide-syntax-keyword: ${theme.tokenColors.keyword};
164
+ --ide-syntax-operator: ${theme.tokenColors.operator};
165
+ --ide-syntax-variable: ${theme.tokenColors.variable};
166
+ --ide-syntax-function: ${theme.tokenColors.function};
167
+ --ide-syntax-property: ${theme.tokenColors.property};
168
+ --ide-syntax-type: ${theme.tokenColors.type};
169
+ --ide-syntax-constant: ${theme.tokenColors.constant};
170
+ --ide-syntax-punctuation: ${theme.tokenColors.punctuation};
171
+ --ide-syntax-tag: ${theme.tokenColors.tag};
172
+ --ide-syntax-attribute: ${theme.tokenColors.tagAttribute};
173
+
122
174
  /* Editor Colors */
123
175
  --editor-bg: ${theme.editorColors.background};
124
176
  --editor-bg-secondary: ${theme.editorColors.backgroundSecondary};
@@ -14,6 +14,7 @@ export declare class LSPClient {
14
14
  private reconnectAttempts;
15
15
  private reconnectTimeout;
16
16
  private intentionalDisconnect;
17
+ private incomingBuffer;
17
18
  private openDocuments;
18
19
  private diagnosticsCache;
19
20
  private eventHandlers;
@@ -35,6 +36,8 @@ export declare class LSPClient {
35
36
  disconnect(): Promise<void>;
36
37
  private initialize;
37
38
  private handleMessage;
39
+ private extractCompleteMessages;
40
+ private dispatchMessage;
38
41
  private sendRequest;
39
42
  private sendNotification;
40
43
  onNotification(method: string, handler: (params: unknown) => void): () => void;
@@ -110,6 +110,7 @@ export class LSPClient {
110
110
  reconnectAttempts = 0;
111
111
  reconnectTimeout = null;
112
112
  intentionalDisconnect = false;
113
+ incomingBuffer = '';
113
114
  // Document tracking
114
115
  openDocuments = new Map();
115
116
  diagnosticsCache = new Map();
@@ -242,6 +243,7 @@ export class LSPClient {
242
243
  }
243
244
  if (socket === this.ws) {
244
245
  this.ws = null;
246
+ this.incomingBuffer = '';
245
247
  }
246
248
  }
247
249
  getReconnectDelay(attempt) {
@@ -331,49 +333,119 @@ export class LSPClient {
331
333
  // JSON-RPC Transport
332
334
  // ============================================================================
333
335
  handleMessage(data) {
336
+ this.incomingBuffer += data;
337
+ for (const rawMessage of this.extractCompleteMessages()) {
338
+ try {
339
+ const message = JSON.parse(rawMessage);
340
+ this.dispatchMessage(message);
341
+ }
342
+ catch (err) {
343
+ if (this.config.debug) {
344
+ console.error('[LSP] Failed to parse message:', err);
345
+ }
346
+ }
347
+ }
348
+ }
349
+ extractCompleteMessages() {
350
+ const messages = [];
351
+ let start = -1;
352
+ let depth = 0;
353
+ let inString = false;
354
+ let escaped = false;
355
+ let consumedUntil = 0;
356
+ for (let i = 0; i < this.incomingBuffer.length; i++) {
357
+ const char = this.incomingBuffer[i];
358
+ if (start === -1) {
359
+ if (/\s/.test(char)) {
360
+ consumedUntil = i + 1;
361
+ continue;
362
+ }
363
+ if (char !== '{') {
364
+ consumedUntil = i + 1;
365
+ continue;
366
+ }
367
+ start = i;
368
+ depth = 1;
369
+ continue;
370
+ }
371
+ if (escaped) {
372
+ escaped = false;
373
+ continue;
374
+ }
375
+ if (char === '\\' && inString) {
376
+ escaped = true;
377
+ continue;
378
+ }
379
+ if (char === '"') {
380
+ inString = !inString;
381
+ continue;
382
+ }
383
+ if (inString) {
384
+ continue;
385
+ }
386
+ if (char === '{') {
387
+ depth++;
388
+ }
389
+ else if (char === '}') {
390
+ depth--;
391
+ if (depth === 0) {
392
+ messages.push(this.incomingBuffer.slice(start, i + 1));
393
+ start = -1;
394
+ consumedUntil = i + 1;
395
+ }
396
+ }
397
+ }
398
+ this.incomingBuffer =
399
+ start === -1 ? this.incomingBuffer.slice(consumedUntil) : this.incomingBuffer.slice(start);
400
+ return messages;
401
+ }
402
+ dispatchMessage(message) {
334
403
  try {
335
- const message = JSON.parse(data);
404
+ if (!message || typeof message !== 'object') {
405
+ return;
406
+ }
407
+ const rpcMessage = message;
336
408
  if (this.config.debug) {
337
- console.log('[LSP] Received:', message);
409
+ console.log('[LSP] Received:', rpcMessage);
338
410
  }
339
- if ('id' in message && message.id !== null) {
411
+ if ('id' in rpcMessage && rpcMessage.id !== null) {
340
412
  // Response to a request
341
- const pending = this.pendingRequests.get(message.id);
413
+ const pending = typeof rpcMessage.id === 'number' ? this.pendingRequests.get(rpcMessage.id) : undefined;
342
414
  if (pending) {
343
415
  clearTimeout(pending.timeout);
344
- this.pendingRequests.delete(message.id);
345
- if ('error' in message) {
346
- pending.reject(new Error(message.error.message));
416
+ this.pendingRequests.delete(rpcMessage.id);
417
+ if (rpcMessage.error) {
418
+ pending.reject(new Error(rpcMessage.error.message));
347
419
  }
348
420
  else {
349
- pending.resolve(message.result);
421
+ pending.resolve(rpcMessage.result);
350
422
  }
351
423
  }
352
424
  }
353
- else if ('method' in message) {
425
+ else if (rpcMessage.method) {
354
426
  // Server notification or request — dispatch to every subscriber.
355
- const handlers = this.notificationHandlers.get(message.method);
427
+ const handlers = this.notificationHandlers.get(rpcMessage.method);
356
428
  if (handlers && handlers.size > 0) {
357
429
  // Iterate a copy so a handler can unsubscribe during dispatch.
358
430
  for (const handler of [...handlers]) {
359
431
  try {
360
- handler(message.params);
432
+ handler(rpcMessage.params);
361
433
  }
362
434
  catch (err) {
363
435
  if (this.config.debug) {
364
- console.error(`[LSP] Notification handler for "${message.method}" threw:`, err);
436
+ console.error(`[LSP] Notification handler for "${rpcMessage.method}" threw:`, err);
365
437
  }
366
438
  }
367
439
  }
368
440
  }
369
441
  else if (this.config.debug) {
370
- console.log(`[LSP] Unhandled notification: ${message.method}`);
442
+ console.log(`[LSP] Unhandled notification: ${rpcMessage.method}`);
371
443
  }
372
444
  }
373
445
  }
374
446
  catch (err) {
375
447
  if (this.config.debug) {
376
- console.error('[LSP] Failed to parse message:', err);
448
+ console.error('[LSP] Failed to handle message:', err);
377
449
  }
378
450
  }
379
451
  }
@@ -79,7 +79,10 @@
79
79
  /* IDE Semantic Colors */
80
80
  --ide-success: var(--color-nocturnium-aurora-green);
81
81
  --ide-warning: var(--color-nocturnium-aurora-yellow);
82
- --ide-error: #ef4444;
82
+ /* Lightened from #ef4444 (~4.1:1 on the secondary panel #1a2744, below AA)
83
+ to ~5.5:1 so the critical band is AA-safe as small text, not only as the
84
+ large/bold score numerals. */
85
+ --ide-error: #f87171;
83
86
  --ide-info: var(--color-nocturnium-aurora-blue);
84
87
 
85
88
  /* AI Panel Colors */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nocturnium/svelte-ide",
3
- "version": "1.1.1",
3
+ "version": "1.2.0",
4
4
  "description": "Svelte 5 code editor and IDE building blocks — custom editor, syntax highlighting, code folding, multi-cursor, LSP client, and optional realtime collaboration.",
5
5
  "author": "Nocturnium & Jordan Dziat <hello@nocturnium.ai> (https://nocturnium.ai)",
6
6
  "license": "MIT",