@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.
- package/dist/components/editor/CognitiveLoadMeter.svelte +27 -0
- package/dist/components/editor/ComplexityHeatLayer.svelte +157 -0
- package/dist/components/editor/ComplexityHeatLayer.svelte.d.ts +24 -0
- package/dist/components/editor/ComplexityLayer.svelte +325 -109
- package/dist/components/editor/ComplexityLayer.svelte.d.ts +13 -0
- package/dist/components/editor/ConflictZoneLayer.svelte +22 -15
- package/dist/components/editor/CustomEditor.svelte +80 -1
- package/dist/components/editor/CustomEditor.svelte.d.ts +3 -1
- package/dist/components/editor/EchoCursorLayer.svelte +60 -0
- package/dist/components/editor/PluginPreviewSandbox.svelte +43 -9
- package/dist/components/editor/PluginPreviewSandbox.svelte.d.ts +4 -4
- package/dist/components/editor/core/complexity-analyzer.d.ts +31 -0
- package/dist/components/editor/core/complexity-analyzer.js +479 -29
- package/dist/components/editor/core/conflict-predictor.d.ts +32 -0
- package/dist/components/editor/core/conflict-predictor.js +55 -0
- package/dist/components/editor/core/crdt-binding.d.ts +4 -0
- package/dist/components/editor/core/crdt-binding.js +34 -9
- package/dist/components/editor/core/echo-cursor.d.ts +18 -1
- package/dist/components/editor/core/echo-cursor.js +117 -6
- package/dist/components/editor/core/extract-function.d.ts +27 -0
- package/dist/components/editor/core/extract-function.js +865 -0
- package/dist/components/editor/core/index.d.ts +1 -0
- package/dist/components/editor/core/index.js +1 -0
- package/dist/components/editor/core/state.d.ts +38 -5
- package/dist/components/editor/core/state.js +175 -98
- package/dist/components/editor/core/timeline.js +6 -1
- package/dist/components/editor/editor-find.js +15 -3
- package/dist/components/editor/theme.d.ts +8 -0
- package/dist/components/editor/theme.js +52 -0
- package/dist/services/lsp-client.d.ts +3 -0
- package/dist/services/lsp-client.js +86 -14
- package/dist/styles/theme.css +4 -1
- 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
|
-
|
|
404
|
+
if (!message || typeof message !== 'object') {
|
|
405
|
+
return;
|
|
406
|
+
}
|
|
407
|
+
const rpcMessage = message;
|
|
336
408
|
if (this.config.debug) {
|
|
337
|
-
console.log('[LSP] Received:',
|
|
409
|
+
console.log('[LSP] Received:', rpcMessage);
|
|
338
410
|
}
|
|
339
|
-
if ('id' in
|
|
411
|
+
if ('id' in rpcMessage && rpcMessage.id !== null) {
|
|
340
412
|
// Response to a request
|
|
341
|
-
const pending = this.pendingRequests.get(
|
|
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(
|
|
345
|
-
if (
|
|
346
|
-
pending.reject(new Error(
|
|
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(
|
|
421
|
+
pending.resolve(rpcMessage.result);
|
|
350
422
|
}
|
|
351
423
|
}
|
|
352
424
|
}
|
|
353
|
-
else if (
|
|
425
|
+
else if (rpcMessage.method) {
|
|
354
426
|
// Server notification or request — dispatch to every subscriber.
|
|
355
|
-
const handlers = this.notificationHandlers.get(
|
|
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(
|
|
432
|
+
handler(rpcMessage.params);
|
|
361
433
|
}
|
|
362
434
|
catch (err) {
|
|
363
435
|
if (this.config.debug) {
|
|
364
|
-
console.error(`[LSP] Notification handler for "${
|
|
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: ${
|
|
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
|
|
448
|
+
console.error('[LSP] Failed to handle message:', err);
|
|
377
449
|
}
|
|
378
450
|
}
|
|
379
451
|
}
|
package/dist/styles/theme.css
CHANGED
|
@@ -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
|
-
|
|
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.
|
|
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",
|