@ripple-ts/language-server 0.3.72 → 0.3.76

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.
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- const require_server = require('./server-DYOT_ulV.js');
2
+ const require_server = require('./server-Coiob8an.js');
3
3
 
4
4
  //#region src/language-server.js
5
5
  require_server.createRippleLanguageServer();
@@ -20054,12 +20054,18 @@ function parseCompilationErrorWithDocument(error, virtualCode, sourceMap, docume
20054
20054
  if (mapping) {
20055
20055
  start = document.positionAt(mapping.generatedOffsets[0]);
20056
20056
  end = document.positionAt(mapping.generatedOffsets[0] + mapping.generatedLengths[0]);
20057
- } else if (sourceMap) {
20058
- const result = sourceMap.toGeneratedRange(start_offset, end_offset, true).next().value;
20059
- if (result) {
20060
- const [gen_start_offset, gen_end_offset] = result;
20061
- start = document.positionAt(gen_start_offset);
20062
- end = document.positionAt(gen_end_offset);
20057
+ } else {
20058
+ const generated = virtualCode.findGeneratedRangeBySourceRange(start_offset, end_offset);
20059
+ if (generated) {
20060
+ start = document.positionAt(generated[0]);
20061
+ end = document.positionAt(generated[1]);
20062
+ } else if (sourceMap) {
20063
+ const result = sourceMap.toGeneratedRange(start_offset, end_offset, true).next().value;
20064
+ if (result) {
20065
+ const [gen_start_offset, gen_end_offset] = result;
20066
+ start = document.positionAt(gen_start_offset);
20067
+ end = document.positionAt(gen_end_offset);
20068
+ }
20063
20069
  }
20064
20070
  }
20065
20071
  }
@@ -20149,8 +20155,7 @@ const COMPILER_CANDIDATES = [
20149
20155
  [
20150
20156
  "@tsrx/ripple",
20151
20157
  "ripple",
20152
- "@ripple-ts/vite-plugin",
20153
- "@ripple-ts/compat-react"
20158
+ "@ripple-ts/vite-plugin"
20154
20159
  ]
20155
20160
  ],
20156
20161
  [
@@ -20486,8 +20491,54 @@ var TSRXVirtualCode = class {
20486
20491
  this.#buildMappingCache();
20487
20492
  return this.#mappingSourceToGen.get(`${start}-${end}`) ?? null;
20488
20493
  }
20494
+ /**
20495
+ * Resolve a source range to a generated `[start, end]` offset pair by spanning
20496
+ * the token mappings that overlap it.
20497
+ *
20498
+ * Statement and element source ranges are only ever covered by several
20499
+ * granular token mappings (e.g. `const test = 5;` maps as `const `, `test`,
20500
+ * ` = `, `5`, `;`), and keywords/punctuation are frequently dropped entirely,
20501
+ * so an exact `findMappingBySourceRange` lookup never matches a multi-token
20502
+ * range and the endpoints often fall on unmapped tokens. Callers that have a
20503
+ * range with no exact mapping (such as compile-error diagnostics) use this to
20504
+ * land on the range: the generated start comes from the first overlapping
20505
+ * token and the generated end from the last, so an error pointing at a `const`
20506
+ * keyword still resolves via the `test`/`5` tokens that follow it.
20507
+ *
20508
+ * @param {number} start - Start of the source range
20509
+ * @param {number} end - Exclusive end of the source range
20510
+ * @returns {[number, number] | null} Generated `[start, end]`, or null if no
20511
+ * token overlaps the range
20512
+ */
20513
+ findGeneratedRangeBySourceRange(start, end) {
20514
+ /** @type {CodeMapping | null} */
20515
+ let first = null;
20516
+ /** @type {CodeMapping | null} */
20517
+ let last = null;
20518
+ for (let i = 0; i < this.mappings.length; i++) {
20519
+ const mapping = this.mappings[i];
20520
+ const sourceStart = mapping.sourceOffsets[0];
20521
+ const sourceEnd = sourceStart + mapping.lengths[0];
20522
+ if (sourceEnd <= start || sourceStart >= end) continue;
20523
+ if (!first || sourceStart < first.sourceOffsets[0]) first = mapping;
20524
+ if (!last || sourceEnd > last.sourceOffsets[0] + last.lengths[0]) last = mapping;
20525
+ }
20526
+ if (!first || !last) return null;
20527
+ const generated_start = first.generatedOffsets[0] + clamp_offset(start - first.sourceOffsets[0], first.generatedLengths[0]);
20528
+ const generated_end = last.generatedOffsets[0] + clamp_offset(end - last.sourceOffsets[0], last.generatedLengths[0]);
20529
+ return [generated_start, Math.max(generated_end, generated_start + 1)];
20530
+ }
20489
20531
  };
20490
20532
  /**
20533
+ * Clamp an intra-token offset into `[0, length]`.
20534
+ * @param {number} offset
20535
+ * @param {number} length
20536
+ * @returns {number}
20537
+ */
20538
+ function clamp_offset(offset, length) {
20539
+ return Math.min(Math.max(offset, 0), length);
20540
+ }
20541
+ /**
20491
20542
  * @param {string} file_name
20492
20543
  * @param {ReadonlyArray<unknown>} errors
20493
20544
  */
@@ -21218,7 +21269,7 @@ const RIPPLE_SNIPPETS = [
21218
21269
  kind: import_language_server.CompletionItemKind.Snippet,
21219
21270
  detail: "Ripple component function",
21220
21271
  documentation: "Create a new Ripple component",
21221
- insertText: "function ${1:ComponentName}(${2:props}) {\n return <>\n $0\n </>;\n}",
21272
+ insertText: "function ${1:ComponentName}(${2:props}) @{\n $0\n}",
21222
21273
  insertTextFormat: import_language_server.InsertTextFormat.Snippet,
21223
21274
  sortText: "0-function-component"
21224
21275
  },
@@ -21263,7 +21314,7 @@ const RIPPLE_SNIPPETS = [
21263
21314
  kind: import_language_server.CompletionItemKind.Snippet,
21264
21315
  detail: "for...of loop",
21265
21316
  documentation: "Iterate over items in Ripple template",
21266
- insertText: "for (const ${1:item} of ${2:items}) {\n <${3:li}>{${1:item}}</${3:li}>\n}",
21317
+ insertText: "@for (const ${1:item} of ${2:items}) {\n <${3:li}>{${1:item}}</${3:li}>\n}",
21267
21318
  insertTextFormat: import_language_server.InsertTextFormat.Snippet,
21268
21319
  sortText: "0-for-of"
21269
21320
  },
@@ -21272,7 +21323,7 @@ const RIPPLE_SNIPPETS = [
21272
21323
  kind: import_language_server.CompletionItemKind.Snippet,
21273
21324
  detail: "for...of loop with index",
21274
21325
  documentation: "Iterate with index",
21275
- insertText: "for (const ${1:item} of ${2:items}; index ${3:i}) {\n <${4:li}>{${1:item}}{\" at \"}{${3:i}}</${4:li}>\n}",
21326
+ insertText: "@for (const ${1:item} of ${2:items}; index ${3:i}) {\n <${4:li}>{${1:item}} at {${3}}</${4:li}>\n}",
21276
21327
  insertTextFormat: import_language_server.InsertTextFormat.Snippet,
21277
21328
  sortText: "0-for-index"
21278
21329
  },
@@ -21281,16 +21332,25 @@ const RIPPLE_SNIPPETS = [
21281
21332
  kind: import_language_server.CompletionItemKind.Snippet,
21282
21333
  detail: "for...of loop with key",
21283
21334
  documentation: "Iterate with key for identity",
21284
- insertText: "for (const ${1:item} of ${2:items}; key ${1:item}.${3:id}) {\n <${4:li}>{${1:item}.${5:text}}</${4:li}>\n}",
21335
+ insertText: "@for (const ${1:item} of ${2:items}; key ${1:item}.${3:id}) {\n <${4:li}>{${1:item}.${5:text}}</${4:li}>\n}",
21285
21336
  insertTextFormat: import_language_server.InsertTextFormat.Snippet,
21286
21337
  sortText: "0-for-key"
21287
21338
  },
21339
+ {
21340
+ label: "for-empty",
21341
+ kind: import_language_server.CompletionItemKind.Snippet,
21342
+ detail: "for...of loop with empty fallback",
21343
+ documentation: "Iterate over items with an empty fallback",
21344
+ insertText: "@for (const ${1:item} of ${2:items}; key ${1:item}.${3:id}) {\n <${4:li}>{${1:item}.${5:text}}</${4:li}>\n} @empty {\n <${6:li}>${7:No items}</${6:li}>\n}",
21345
+ insertTextFormat: import_language_server.InsertTextFormat.Snippet,
21346
+ sortText: "0-for-empty"
21347
+ },
21288
21348
  {
21289
21349
  label: "for-index-key",
21290
21350
  kind: import_language_server.CompletionItemKind.Snippet,
21291
21351
  detail: "for...of loop with key",
21292
21352
  documentation: "Iterate with key for identity",
21293
- insertText: "for (const ${1:item} of ${2:items}; index ${3:i}; key ${1:item}.${4:id}) {\n <${5:li}>{${1:item}.${6:text}}{' at index '}{${3}}</${5:li}>\n}",
21353
+ insertText: "@for (const ${1:item} of ${2:items}; index ${3:i}; key ${1:item}.${4:id}) {\n <${5:li}>{${1:item}.${6:text}} at index {${3}}</${5:li}>\n}",
21294
21354
  insertTextFormat: import_language_server.InsertTextFormat.Snippet,
21295
21355
  sortText: "0-for-key-index"
21296
21356
  },
@@ -21299,7 +21359,7 @@ const RIPPLE_SNIPPETS = [
21299
21359
  kind: import_language_server.CompletionItemKind.Snippet,
21300
21360
  detail: "if...else statement",
21301
21361
  documentation: "Conditional rendering",
21302
- insertText: "if (${1:condition}) {\n $2\n} else {\n $3\n}",
21362
+ insertText: "@if (${1:condition}) {\n <>\n $2\n </>\n} else {\n <>\n $3\n </>\n}",
21303
21363
  insertTextFormat: import_language_server.InsertTextFormat.Snippet,
21304
21364
  sortText: "0-if-else"
21305
21365
  },
@@ -21308,7 +21368,7 @@ const RIPPLE_SNIPPETS = [
21308
21368
  kind: import_language_server.CompletionItemKind.Snippet,
21309
21369
  detail: "switch statement",
21310
21370
  documentation: "Switch-based conditional rendering",
21311
- insertText: "switch (${1:value}) {\n case ${2:'case1'}:\n $3\n break;\n case ${4:'case2'}:\n $5\n break;\n default:\n $6\n}",
21371
+ insertText: "@switch (${1:value}) {\n case ${2:'case1'}: {\n <>\n $3\n </>\n }\n case ${4:'case2'}: {\n <>\n $5\n </>\n }\n default: {\n <>\n $6\n </>\n }\n}",
21312
21372
  insertTextFormat: import_language_server.InsertTextFormat.Snippet,
21313
21373
  sortText: "0-switch-case"
21314
21374
  },
@@ -21326,7 +21386,7 @@ const RIPPLE_SNIPPETS = [
21326
21386
  kind: import_language_server.CompletionItemKind.Snippet,
21327
21387
  detail: "try...pending block",
21328
21388
  documentation: "Handle async content with loading fallback",
21329
- insertText: "try {\n $1\n} pending {\n <div>{'Loading...'}</div>\n}",
21389
+ insertText: "@try {\n $1\n} @pending {\n <div>Loading...</div>\n}",
21330
21390
  insertTextFormat: import_language_server.InsertTextFormat.Snippet,
21331
21391
  sortText: "0-try-pending"
21332
21392
  }
@@ -21367,7 +21427,11 @@ function createCompletionPlugin() {
21367
21427
  return {
21368
21428
  name: "ripple-completion-enhancer",
21369
21429
  capabilities: { completionProvider: {
21370
- triggerCharacters: ["<", "{"],
21430
+ triggerCharacters: [
21431
+ "<",
21432
+ "{",
21433
+ "@"
21434
+ ],
21371
21435
  resolveProvider: false
21372
21436
  } },
21373
21437
  create(context) {
@@ -21777,14 +21841,16 @@ function createDocumentSymbolPlugin() {
21777
21841
  if (!is_ripple_document(document.uri)) return [];
21778
21842
  const { virtualCode, sourceMap, sourceUri } = getVirtualCode(document, context);
21779
21843
  const { sourceAst, languageId, originalCode } = virtualCode || {};
21844
+ const fallbackFileName = sourceUri?.fsPath ?? document.uri;
21845
+ if (!virtualCode) return collectFallbackDocumentSymbols(document, fallbackFileName) ?? [];
21780
21846
  if (languageId !== "ripple") {
21781
21847
  log$1(`Skipping symbols in the '${languageId}' context`);
21782
21848
  return [];
21783
21849
  }
21784
21850
  const cacheKey = sourceUri.toString();
21785
21851
  const cachedSymbols = documentSymbolCache.get(cacheKey) ?? [];
21786
- if (virtualCode?.fatalErrors?.length || virtualCode?.isDotCompletionMode) return cachedSymbols;
21787
- if (!sourceMap || !sourceAst) return [];
21852
+ if (virtualCode?.fatalErrors?.length || virtualCode?.isDotCompletionMode) return collectFallbackDocumentSymbols(document, fallbackFileName) ?? cachedSymbols;
21853
+ if (!sourceMap || !sourceAst) return collectFallbackDocumentSymbols(document, fallbackFileName) ?? [];
21788
21854
  const sourceDocument = TextDocument.create(sourceUri.toString(), "ripple", 0, originalCode);
21789
21855
  const symbols = mapDocumentSymbolsToGenerated(collectDocumentSymbols(sourceAst, sourceDocument), virtualCode, sourceDocument, document, sourceMap);
21790
21856
  documentSymbolCache.set(cacheKey, symbols);
@@ -21794,6 +21860,29 @@ function createDocumentSymbolPlugin() {
21794
21860
  };
21795
21861
  }
21796
21862
  /**
21863
+ * @param {TextDocument} document
21864
+ * @param {string} fileName
21865
+ * @returns {DocumentSymbol[] | null}
21866
+ */
21867
+ function collectFallbackDocumentSymbols(document, fileName) {
21868
+ try {
21869
+ return toDocumentSymbols(collectDocumentSymbols((0, _tsrx_core.parseModule)(document.getText(), fileName), document));
21870
+ } catch (error) {
21871
+ logError$1(`Unable to collect fallback document symbols: ${error.message}`);
21872
+ return null;
21873
+ }
21874
+ }
21875
+ /**
21876
+ * @param {SymbolInfo[]} symbols
21877
+ * @returns {DocumentSymbol[]}
21878
+ */
21879
+ function toDocumentSymbols(symbols) {
21880
+ return symbols.map(([symbol]) => ({
21881
+ ...symbol,
21882
+ children: symbol.children?.length ? toDocumentSymbols(symbol.children) : void 0
21883
+ }));
21884
+ }
21885
+ /**
21797
21886
  * @param {SymbolInfo[]} symbols
21798
21887
  * @param {TSRXVirtualCodeInstance} virtualCode
21799
21888
  * @param {TextDocument} sourceDocument
@@ -22050,7 +22139,7 @@ function getReturnedTemplateSymbols(node, document) {
22050
22139
  * @returns {boolean}
22051
22140
  */
22052
22141
  function isTemplateNode(node) {
22053
- return !!node && (node.type === "TsrxFragment" || node.type === "Element" || node.type === "JSXElement" || node.type === "JSXFragment");
22142
+ return !!node && (node.type === "JSXElement" || node.type === "JSXFragment" || node.type === "JSXStyleElement");
22054
22143
  }
22055
22144
  /**
22056
22145
  * @param {AST.Node} node
@@ -22319,4 +22408,4 @@ Object.defineProperty(exports, 'createRippleLanguageServer', {
22319
22408
  return createRippleLanguageServer;
22320
22409
  }
22321
22410
  });
22322
- //# sourceMappingURL=server-DYOT_ulV.js.map
22411
+ //# sourceMappingURL=server-Coiob8an.js.map