typescript-language-server 5.1.1 → 5.1.2

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/CHANGELOG.md CHANGED
@@ -1,6 +1,13 @@
1
1
  # Changelog
2
2
  All notable changes to this project will be documented in this file.
3
3
 
4
+ ## [5.1.2](https://github.com/typescript-language-server/typescript-language-server/compare/v5.1.1...v5.1.2) (2025-11-18)
5
+
6
+
7
+ ### Refactors
8
+
9
+ * cache file formatting configuration requests ([#1048](https://github.com/typescript-language-server/typescript-language-server/issues/1048)) ([9a366df](https://github.com/typescript-language-server/typescript-language-server/commit/9a366dfc7a989829f4b9e53017c298b565a307fd))
10
+
4
11
  ## [5.1.1](https://github.com/typescript-language-server/typescript-language-server/compare/v5.1.0...v5.1.1) (2025-11-05)
5
12
 
6
13
 
package/README.md CHANGED
@@ -305,7 +305,7 @@ The `$/typescriptVersion` notification params include two properties:
305
305
 
306
306
  ### Workspace Configuration request for formatting settings
307
307
 
308
- Server asks the client for file-specific configuration options (`tabSize` and `insertSpaces`) that are required by `tsserver` to properly format file edits when for example using "Organize imports" or performing other file modifications. Those options have to be dynamically provided by the client/editor since the values can differ for each file. For this reason server sends a `workspace/configuration` request with `scopeUri` equal to file's URI and `section` equal to `formattingOptions`. The client is expected to return a configuration that includes the following properties:
308
+ Server asks the client (provided client supports `workspace/configuration` capability) for file-specific configuration options (`tabSize` and `insertSpaces`) that are required by `tsserver` to properly format file edits when for example using "Organize imports" or performing other file modifications. Those options have to be dynamically provided by the client/editor since the values can differ for each file. For this reason server sends a `workspace/configuration` request with `scopeUri` equal to file's URI and `section` equal to `formattingOptions`. The client is expected to return a configuration that includes the following properties:
309
309
 
310
310
  ```js
311
311
  {
package/lib/cli.mjs CHANGED
@@ -21442,17 +21442,32 @@ function areFileConfigurationsEqual(a, b) {
21442
21442
  }
21443
21443
 
21444
21444
  class FileConfigurationManager {
21445
- constructor(client, lspClient, onCaseInsensitiveFileSystem) {
21445
+ constructor(client, lspClient, features, onCaseInsensitiveFileSystem) {
21446
21446
  this.client = client;
21447
21447
  this.lspClient = lspClient;
21448
+ this.features = features;
21448
21449
  this.tsPreferences = deepmerge({}, DEFAULT_TSSERVER_PREFERENCES);
21449
21450
  this.workspaceConfiguration = deepmerge({}, DEFAULT_WORKSPACE_CONFIGURATION);
21450
- this.formatOptions = new ResourceMap(undefined, {
21451
+ this.fileOptionsCache = new ResourceMap(undefined, {
21452
+ onCaseInsensitiveFileSystem: onCaseInsensitiveFileSystem
21453
+ });
21454
+ this.formatOptionsCache = new ResourceMap(undefined, {
21455
+ onCaseInsensitiveFileSystem: onCaseInsensitiveFileSystem
21456
+ });
21457
+ this.initialConfigurationRequestsMap = new ResourceMap(undefined, {
21451
21458
  onCaseInsensitiveFileSystem: onCaseInsensitiveFileSystem
21452
21459
  });
21453
21460
  }
21461
+ onDidOpenTextDocument(document) {
21462
+ const cancellation = new lsp$1.CancellationTokenSource;
21463
+ this.initialConfigurationRequestsMap.set(document.uri, cancellation);
21464
+ this.ensureConfigurationForDocument(document, cancellation.token).then(() => {
21465
+ this.initialConfigurationRequestsMap.delete(document.uri);
21466
+ }).catch(() => {});
21467
+ }
21454
21468
  onDidCloseTextDocument(documentUri) {
21455
- this.formatOptions.delete(documentUri);
21469
+ this.fileOptionsCache.delete(documentUri);
21470
+ this.initialConfigurationRequestsMap.get(documentUri)?.cancel();
21456
21471
  }
21457
21472
  mergeTsPreferences(preferences) {
21458
21473
  this.tsPreferences = deepmerge(this.tsPreferences, preferences);
@@ -21493,7 +21508,11 @@ class FileConfigurationManager {
21493
21508
  return this.ensureConfigurationOptions(document, formattingOptions, token);
21494
21509
  }
21495
21510
  async getFormattingOptions(document) {
21496
- const formatConfiguration = await this.lspClient.getWorkspaceConfiguration(document.uri.toString(), 'formattingOptions') || {};
21511
+ const formatOptionsCached = this.formatOptionsCache.get(document.uri);
21512
+ if (formatOptionsCached) {
21513
+ return formatOptionsCached;
21514
+ }
21515
+ const formatConfiguration = this.features.workspaceConfigurationSuppport ? await this.lspClient.getWorkspaceConfiguration(document.uri.toString(), 'formattingOptions') || {} : {};
21497
21516
  const options = {};
21498
21517
  if (typeof formatConfiguration.tabSize === 'number') {
21499
21518
  options.tabSize = formatConfiguration.tabSize;
@@ -21501,11 +21520,12 @@ class FileConfigurationManager {
21501
21520
  if (typeof formatConfiguration.insertSpaces === 'boolean') {
21502
21521
  options.insertSpaces = formatConfiguration.insertSpaces;
21503
21522
  }
21523
+ this.formatOptionsCache.set(document.uri, options);
21504
21524
  return options;
21505
21525
  }
21506
21526
  async ensureConfigurationOptions(document, options, token) {
21507
21527
  const currentOptions = this.getFileOptions(document, options);
21508
- const cachedOptions = this.formatOptions.get(document.uri);
21528
+ const cachedOptions = this.fileOptionsCache.get(document.uri);
21509
21529
  if (cachedOptions) {
21510
21530
  const cachedOptionsValue = await cachedOptions;
21511
21531
  if (token?.isCancellationRequested) {
@@ -21526,7 +21546,7 @@ class FileConfigurationManager {
21526
21546
  return undefined;
21527
21547
  }
21528
21548
  })();
21529
- this.formatOptions.set(document.uri, task);
21549
+ this.fileOptionsCache.set(document.uri, task);
21530
21550
  await task;
21531
21551
  }
21532
21552
  async setGlobalConfigurationFromDocument(document, token) {
@@ -21537,7 +21557,9 @@ class FileConfigurationManager {
21537
21557
  await this.client.execute(CommandTypes.Configure, args, token);
21538
21558
  }
21539
21559
  reset() {
21540
- this.formatOptions.clear();
21560
+ this.fileOptionsCache.clear();
21561
+ this.formatOptionsCache.clear();
21562
+ this.initialConfigurationRequestsMap.clear();
21541
21563
  }
21542
21564
  getFileOptions(document, options) {
21543
21565
  return {
@@ -23173,7 +23195,7 @@ class LspServer {
23173
23195
  this.referencesCodeLensProvider = null;
23174
23196
  this.logger = new PrefixingLogger(options.logger, '[lspserver]');
23175
23197
  this.tsClient = new TsClient(onCaseInsensitiveFileSystem(), this.logger, options.lspClient);
23176
- this.fileConfigurationManager = new FileConfigurationManager(this.tsClient, this.options.lspClient, onCaseInsensitiveFileSystem());
23198
+ this.fileConfigurationManager = new FileConfigurationManager(this.tsClient, this.options.lspClient, this.features, onCaseInsensitiveFileSystem());
23177
23199
  this.commandManager = new CommandManager;
23178
23200
  this.diagnosticsManager = new DiagnosticsManager(diagnostics => this.options.lspClient.publishDiagnostics(diagnostics), this.tsClient, this.features, this.logger);
23179
23201
  this.codeActionsManager = new CodeActionManager(this.tsClient, this.fileConfigurationManager, this.commandManager, this.diagnosticsManager, this.features);
@@ -23211,7 +23233,7 @@ class LspServer {
23211
23233
  this.fileConfigurationManager.mergeTsPreferences(userInitializationOptions.preferences || {});
23212
23234
  this.features.completionDisableFilterText = userInitializationOptions.completionDisableFilterText ?? false;
23213
23235
  this.features.moveToFileCodeActionSupport = userInitializationOptions.supportsMoveToFileCodeAction && typescriptVersion.version?.gte(API.v520);
23214
- const {textDocument: textDocument} = clientCapabilities;
23236
+ const {textDocument: textDocument, workspace: workspace} = clientCapabilities;
23215
23237
  if (textDocument) {
23216
23238
  const {codeAction: codeAction, completion: completion, definition: definition, publishDiagnostics: publishDiagnostics} = textDocument;
23217
23239
  if (codeAction) {
@@ -23234,6 +23256,9 @@ class LspServer {
23234
23256
  this.features.diagnosticsSupport = Boolean(publishDiagnostics);
23235
23257
  this.features.diagnosticsTagSupport = Boolean(publishDiagnostics?.tagSupport);
23236
23258
  }
23259
+ if (workspace?.configuration) {
23260
+ this.features.workspaceConfigurationSuppport = true;
23261
+ }
23237
23262
  this.fileConfigurationManager.mergeTsPreferences({
23238
23263
  useLabelDetailsInCompletionEntries: this.features.completionLabelDetails
23239
23264
  });
@@ -23409,13 +23434,18 @@ class LspServer {
23409
23434
  this.tsClient.interruptGetErr(() => this.diagnosticsManager.updateIgnoredDiagnosticCodes(ignoredDiagnosticCodes));
23410
23435
  }
23411
23436
  didOpenTextDocument(params) {
23412
- if (this.tsClient.toOpenDocument(params.textDocument.uri, {
23437
+ const {uri: uri, languageId: languageId} = params.textDocument;
23438
+ if (this.tsClient.toOpenDocument(uri, {
23413
23439
  suppressAlertOnFailure: true
23414
23440
  })) {
23415
- throw new Error(`Can't open already open document: ${params.textDocument.uri}`);
23441
+ throw new Error(`Can't open already open document: ${uri}`);
23416
23442
  }
23417
23443
  if (!this.tsClient.openTextDocument(params.textDocument)) {
23418
- throw new Error(`Cannot open document '${params.textDocument.uri}' (languageId: ${params.textDocument.languageId}).`);
23444
+ throw new Error(`Cannot open document '${uri}' (languageId: ${languageId}).`);
23445
+ }
23446
+ const document = this.tsClient.toOpenDocument(uri);
23447
+ if (document) {
23448
+ this.fileConfigurationManager.onDidOpenTextDocument(document);
23419
23449
  }
23420
23450
  }
23421
23451
  didCloseTextDocument(params) {