@lvce-editor/extension-management-worker 4.27.0 → 4.28.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.
@@ -2328,6 +2328,73 @@ const executeExtensionCommand = async (extensionsState, id, ...args) => {
2328
2328
  };
2329
2329
  };
2330
2330
 
2331
+ const hasUriScheme = value => {
2332
+ return /^[a-z][a-z\d+.-]*:/i.test(value);
2333
+ };
2334
+ const toExtensionBaseUri = extensionPath => {
2335
+ if (hasUriScheme(extensionPath)) {
2336
+ return extensionPath.endsWith('/') ? extensionPath : `${extensionPath}/`;
2337
+ }
2338
+ if (extensionPath.startsWith('/')) {
2339
+ return `file://${extensionPath}/`;
2340
+ }
2341
+ throw new Error(`Language server extension path must be an absolute path or URI`);
2342
+ };
2343
+ const resolveLanguageServerUri = (extension, languageServerUri) => {
2344
+ if (languageServerUri.startsWith('/')) {
2345
+ return `file://${languageServerUri}`;
2346
+ }
2347
+ if (hasUriScheme(languageServerUri)) {
2348
+ return languageServerUri;
2349
+ }
2350
+ const extensionPath = extension.uri || extension.path || '';
2351
+ return new URL(languageServerUri, toExtensionBaseUri(extensionPath)).href;
2352
+ };
2353
+ const getContribution = (extension, languageId) => {
2354
+ return extension.languageServers?.find(contribution => contribution.languageId === languageId);
2355
+ };
2356
+ const getRegisteredLanguageServer = (snapshot, contribution, languageId) => {
2357
+ const languageServer = snapshot.languageServers.find(registered => registered.id === contribution.id && registered.languageId === languageId);
2358
+ if (!languageServer) {
2359
+ throw new Error(`language server ${contribution.id || '<unknown>'} is contributed in extension.json but not registered`);
2360
+ }
2361
+ return languageServer;
2362
+ };
2363
+ const sanitizeCompletionItem = item => {
2364
+ if (!item || typeof item !== 'object' || typeof item.label !== 'string') {
2365
+ return undefined;
2366
+ }
2367
+ const snippet = item.insertText || item.textEdit?.newText || item.label;
2368
+ return {
2369
+ ...item,
2370
+ flags: 0,
2371
+ kind: typeof item.kind === 'number' ? item.kind : 0,
2372
+ label: item.label,
2373
+ matches: [],
2374
+ snippet
2375
+ };
2376
+ };
2377
+ const executeLanguageServerCompletion = async (rpc, extension, textDocument, offset) => {
2378
+ if (typeof textDocument.text !== 'string' || typeof textDocument.uri !== 'string') {
2379
+ return [];
2380
+ }
2381
+ const contribution = getContribution(extension, textDocument.languageId);
2382
+ if (!contribution) {
2383
+ return [];
2384
+ }
2385
+ const snapshot = await rpc.invoke('ExtensionApi.getLanguageServerRegistrySnapshot');
2386
+ const languageServer = getRegisteredLanguageServer(snapshot, contribution, textDocument.languageId);
2387
+ const uri = resolveLanguageServerUri(extension, languageServer.uri);
2388
+ const result = await invoke$1('LanguageServer.complete', {
2389
+ argv: languageServer.argv,
2390
+ id: `${extension.id || extension.uri || extension.path || 'extension'}.${languageServer.id}`,
2391
+ offset,
2392
+ textDocument,
2393
+ uri
2394
+ });
2395
+ return result.map(sanitizeCompletionItem).filter(item => item !== undefined);
2396
+ };
2397
+
2331
2398
  const getOrigin = () => {
2332
2399
  return globalThis.location?.origin || 'http://localhost';
2333
2400
  };
@@ -2353,13 +2420,23 @@ const getRpc$1 = async (extension, assetDir, platform) => {
2353
2420
  const contributesCompletionProvider = (extension, languageId) => {
2354
2421
  return Array.isArray(extension.completionProviders) && extension.completionProviders.some(provider => provider.languageId === languageId);
2355
2422
  };
2423
+ const contributesLanguageServer = (extension, languageId) => {
2424
+ return Array.isArray(extension.languageServers) && extension.languageServers.some(languageServer => languageServer.languageId === languageId);
2425
+ };
2356
2426
  const getMatchingExtensions$4 = async (extensionsState, textDocument, assetDir, platform) => {
2357
2427
  const extensions = await getAllExtensionsWithState(extensionsState, assetDir, platform);
2358
- return extensions.filter(extension => isExtensionIsolated(extension) && contributesCompletionProvider(extension, textDocument.languageId));
2428
+ return extensions.filter(extension => isExtensionIsolated(extension) && (contributesCompletionProvider(extension, textDocument.languageId) || contributesLanguageServer(extension, textDocument.languageId)));
2359
2429
  };
2360
2430
  const executeRpcCompletionProvider = async (rpc, textDocument, args) => {
2361
2431
  return rpc.invoke('ExtensionApi.executeCompletionProvider', textDocument, ...args);
2362
2432
  };
2433
+ const executeExtensionCompletionProvider = async (rpc, extension, textDocument, args) => {
2434
+ if (contributesLanguageServer(extension, textDocument.languageId)) {
2435
+ const offset = typeof args[0] === 'number' ? args[0] : 0;
2436
+ return executeLanguageServerCompletion(rpc, extension, textDocument, offset);
2437
+ }
2438
+ return executeRpcCompletionProvider(rpc, textDocument, args);
2439
+ };
2363
2440
  const executeRpcResolveCompletionItemProvider = async (rpc, textDocument, args) => {
2364
2441
  return rpc.invoke('ExtensionApi.executeResolveCompletionItemProvider', textDocument, ...args);
2365
2442
  };
@@ -2370,7 +2447,7 @@ const executeCompletionProvider = async (extensionsState, textDocument, ...args)
2370
2447
  } = await getRuntimeContext('', extensionsState.platform);
2371
2448
  const extensions = await getMatchingExtensions$4(extensionsState, textDocument, assetDir, platform);
2372
2449
  const rpcs = await Promise.all(extensions.map(extension => getRpc$1(extension, assetDir, platform)));
2373
- const results = await Promise.all(rpcs.map(rpc => executeRpcCompletionProvider(rpc, textDocument, args)));
2450
+ const results = await Promise.all(rpcs.map((rpc, index) => executeExtensionCompletionProvider(rpc, extensions[index], textDocument, args)));
2374
2451
  return results[0] || [];
2375
2452
  };
2376
2453
  const executeResolveCompletionItemProvider = async (extensionsState, textDocument, ...args) => {
@@ -2378,7 +2455,8 @@ const executeResolveCompletionItemProvider = async (extensionsState, textDocumen
2378
2455
  assetDir,
2379
2456
  platform
2380
2457
  } = await getRuntimeContext('', extensionsState.platform);
2381
- const extensions = await getMatchingExtensions$4(extensionsState, textDocument, assetDir, platform);
2458
+ const matchingExtensions = await getMatchingExtensions$4(extensionsState, textDocument, assetDir, platform);
2459
+ const extensions = matchingExtensions.filter(extension => contributesCompletionProvider(extension, textDocument.languageId));
2382
2460
  const rpcs = await Promise.all(extensions.map(extension => getRpc$1(extension, assetDir, platform)));
2383
2461
  const results = await Promise.all(rpcs.map(rpc => executeRpcResolveCompletionItemProvider(rpc, textDocument, args)));
2384
2462
  return results[0];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lvce-editor/extension-management-worker",
3
- "version": "4.27.0",
3
+ "version": "4.28.0",
4
4
  "description": "Webworker for the Extension Management functionality in Lvce Editor.",
5
5
  "keywords": [
6
6
  "web-worker"