@vue/typescript-plugin 2.0.26 → 2.0.28

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/index.js CHANGED
@@ -6,21 +6,17 @@ const server_1 = require("./lib/server");
6
6
  const windowsPathReg = /\\/g;
7
7
  const plugin = (0, createLanguageServicePlugin_1.createLanguageServicePlugin)((ts, info) => {
8
8
  const vueOptions = getVueCompilerOptions();
9
- const languagePlugin = vue.createVueLanguagePlugin(ts, id => id, () => info.languageServiceHost.getProjectVersion?.() ?? '', info.project.projectKind === ts.server.ProjectKind.Inferred
9
+ const languagePlugin = vue.createVueLanguagePlugin2(ts, id => id, info.project.projectKind === ts.server.ProjectKind.Inferred
10
10
  ? () => true
11
- : fileName => {
12
- const fileMap = new vue.FileMap(info.languageServiceHost.useCaseSensitiveFileNames?.() ?? false);
13
- for (const vueFileName of createLanguageServicePlugin_1.externalFiles.get(info.project) ?? []) {
14
- fileMap.set(vueFileName, undefined);
15
- }
16
- return fileMap.has(fileName);
17
- }, info.languageServiceHost.getCompilationSettings(), vueOptions);
11
+ : vue.createRootFileChecker(info.languageServiceHost.getProjectVersion ? () => info.languageServiceHost.getProjectVersion() : undefined, () => createLanguageServicePlugin_1.externalFiles.get(info.project) ?? [], info.languageServiceHost.useCaseSensitiveFileNames?.() ?? false), info.languageServiceHost.getCompilationSettings(), vueOptions);
18
12
  return {
19
13
  languagePlugins: [languagePlugin],
20
14
  setup: language => {
21
- server_1.projects.set(info.project, { info, language, vueOptions });
22
15
  info.languageService = (0, common_1.proxyLanguageServiceForVue)(ts, language, info.languageService, vueOptions, fileName => fileName);
23
- (0, server_1.startNamedPipeServer)(ts, info.project.projectKind, info.project.getCurrentDirectory());
16
+ if (info.project.projectKind === ts.server.ProjectKind.Configured
17
+ || info.project.projectKind === ts.server.ProjectKind.Inferred) {
18
+ (0, server_1.startNamedPipeServer)(ts, info, language, info.project.projectKind);
19
+ }
24
20
  // #3963
25
21
  const timer = setInterval(() => {
26
22
  if (info.project['program']) {
package/lib/client.js CHANGED
@@ -66,16 +66,13 @@ function getElementAttrs(...args) {
66
66
  });
67
67
  }
68
68
  async function sendRequest(request) {
69
- const server = (await (0, utils_1.searchNamedPipeServerForFile)(request.args[0]))?.server;
69
+ const server = (await (0, utils_1.searchNamedPipeServerForFile)(request.args[0]));
70
70
  if (!server) {
71
71
  console.warn('[Vue Named Pipe Client] No server found for', request.args[0]);
72
72
  return;
73
73
  }
74
- const client = await (0, utils_1.connect)(server.path);
75
- if (!client) {
76
- console.warn('[Vue Named Pipe Client] Failed to connect to', server.path);
77
- return;
78
- }
79
- return await (0, utils_1.sendRequestWorker)(request, client);
74
+ const res = await (0, utils_1.sendRequestWorker)(request, server.socket);
75
+ server.socket.end();
76
+ return res;
80
77
  }
81
78
  //# sourceMappingURL=client.js.map
package/lib/server.d.ts CHANGED
@@ -1,12 +1,12 @@
1
- import type { Language, VueCompilerOptions } from '@vue/language-core';
1
+ import type { Language } from '@vue/language-core';
2
2
  import type * as ts from 'typescript';
3
3
  export interface Request {
4
- type: 'projectInfoForFile' | 'collectExtractProps' | 'getImportPathForFile' | 'getPropertiesAtLocation' | 'getQuickInfoAtPosition' | 'getComponentProps' | 'getComponentEvents' | 'getTemplateContextProps' | 'getComponentNames' | 'getElementAttrs';
4
+ type: 'containsFile' | 'projectInfo' | 'collectExtractProps' | 'getImportPathForFile' | 'getPropertiesAtLocation' | 'getQuickInfoAtPosition' | 'getComponentProps' | 'getComponentEvents' | 'getTemplateContextProps' | 'getComponentNames' | 'getElementAttrs';
5
5
  args: [fileName: string, ...rest: any];
6
6
  }
7
- export declare function startNamedPipeServer(ts: typeof import('typescript'), serverKind: ts.server.ProjectKind, currentDirectory: string): void;
8
- export declare const projects: Map<ts.server.Project, {
9
- info: ts.server.PluginCreateInfo;
10
- language: Language<string>;
11
- vueOptions: VueCompilerOptions;
12
- }>;
7
+ export interface ProjectInfo {
8
+ name: string;
9
+ kind: ts.server.ProjectKind;
10
+ currentDirectory: string;
11
+ }
12
+ export declare function startNamedPipeServer(ts: typeof import('typescript'), info: ts.server.PluginCreateInfo, language: Language<string>, projectKind: ts.server.ProjectKind.Inferred | ts.server.ProjectKind.Configured): Promise<void>;
package/lib/server.js CHANGED
@@ -1,6 +1,5 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.projects = void 0;
4
3
  exports.startNamedPipeServer = startNamedPipeServer;
5
4
  const fs = require("fs");
6
5
  const net = require("net");
@@ -10,120 +9,116 @@ const getImportPathForFile_1 = require("./requests/getImportPathForFile");
10
9
  const getPropertiesAtLocation_1 = require("./requests/getPropertiesAtLocation");
11
10
  const getQuickInfoAtPosition_1 = require("./requests/getQuickInfoAtPosition");
12
11
  const utils_1 = require("./utils");
13
- let started = false;
14
- function startNamedPipeServer(ts, serverKind, currentDirectory) {
15
- if (started) {
16
- return;
17
- }
18
- started = true;
19
- const pipeFile = process.platform === 'win32'
20
- ? `\\\\.\\pipe\\vue-tsp-${process.pid}`
21
- : `/tmp/vue-tsp-${process.pid}`;
12
+ async function startNamedPipeServer(ts, info, language, projectKind) {
22
13
  const server = net.createServer(connection => {
23
14
  connection.on('data', data => {
24
15
  const text = data.toString();
16
+ if (text === 'ping') {
17
+ connection.write('pong');
18
+ return;
19
+ }
25
20
  const request = JSON.parse(text);
26
21
  const fileName = request.args[0];
27
- const project = getProject(ts.server.toNormalizedPath(fileName));
28
- if (request.type === 'projectInfoForFile') {
29
- connection.write(JSON.stringify(project
30
- ? {
31
- name: project.info.project.getProjectName(),
32
- kind: project.info.project.projectKind,
33
- }
34
- : null));
22
+ if (request.type === 'containsFile') {
23
+ sendResponse(info.project.containsFile(ts.server.toNormalizedPath(fileName)));
35
24
  }
36
- else if (project) {
37
- const requestContext = {
38
- typescript: ts,
39
- languageService: project.info.languageService,
40
- languageServiceHost: project.info.languageServiceHost,
41
- language: project.language,
42
- isTsPlugin: true,
43
- getFileId: (fileName) => fileName,
44
- };
45
- if (request.type === 'collectExtractProps') {
46
- const result = collectExtractProps_1.collectExtractProps.apply(requestContext, request.args);
47
- connection.write(JSON.stringify(result ?? null));
48
- }
49
- else if (request.type === 'getImportPathForFile') {
50
- const result = getImportPathForFile_1.getImportPathForFile.apply(requestContext, request.args);
51
- connection.write(JSON.stringify(result ?? null));
52
- }
53
- else if (request.type === 'getPropertiesAtLocation') {
54
- const result = getPropertiesAtLocation_1.getPropertiesAtLocation.apply(requestContext, request.args);
55
- connection.write(JSON.stringify(result ?? null));
56
- }
57
- else if (request.type === 'getQuickInfoAtPosition') {
58
- const result = getQuickInfoAtPosition_1.getQuickInfoAtPosition.apply(requestContext, request.args);
59
- connection.write(JSON.stringify(result ?? null));
60
- }
61
- // Component Infos
62
- else if (request.type === 'getComponentProps') {
63
- const result = componentInfos_1.getComponentProps.apply(requestContext, request.args);
64
- connection.write(JSON.stringify(result ?? null));
65
- }
66
- else if (request.type === 'getComponentEvents') {
67
- const result = componentInfos_1.getComponentEvents.apply(requestContext, request.args);
68
- connection.write(JSON.stringify(result ?? null));
69
- }
70
- else if (request.type === 'getTemplateContextProps') {
71
- const result = componentInfos_1.getTemplateContextProps.apply(requestContext, request.args);
72
- connection.write(JSON.stringify(result ?? null));
73
- }
74
- else if (request.type === 'getComponentNames') {
75
- const result = componentInfos_1.getComponentNames.apply(requestContext, request.args);
76
- connection.write(JSON.stringify(result ?? null));
77
- }
78
- else if (request.type === 'getElementAttrs') {
79
- const result = componentInfos_1.getElementAttrs.apply(requestContext, request.args);
80
- connection.write(JSON.stringify(result ?? null));
81
- }
82
- else {
83
- console.warn('[Vue Named Pipe Server] Unknown request type:', request.type);
84
- }
25
+ if (request.type === 'projectInfo') {
26
+ sendResponse({
27
+ name: info.project.getProjectName(),
28
+ kind: info.project.projectKind,
29
+ currentDirectory: info.project.getCurrentDirectory(),
30
+ });
31
+ }
32
+ const requestContext = {
33
+ typescript: ts,
34
+ languageService: info.languageService,
35
+ languageServiceHost: info.languageServiceHost,
36
+ language: language,
37
+ isTsPlugin: true,
38
+ getFileId: (fileName) => fileName,
39
+ };
40
+ if (request.type === 'collectExtractProps') {
41
+ const result = collectExtractProps_1.collectExtractProps.apply(requestContext, request.args);
42
+ sendResponse(result);
43
+ }
44
+ else if (request.type === 'getImportPathForFile') {
45
+ const result = getImportPathForFile_1.getImportPathForFile.apply(requestContext, request.args);
46
+ sendResponse(result);
47
+ }
48
+ else if (request.type === 'getPropertiesAtLocation') {
49
+ const result = getPropertiesAtLocation_1.getPropertiesAtLocation.apply(requestContext, request.args);
50
+ sendResponse(result);
51
+ }
52
+ else if (request.type === 'getQuickInfoAtPosition') {
53
+ const result = getQuickInfoAtPosition_1.getQuickInfoAtPosition.apply(requestContext, request.args);
54
+ sendResponse(result);
55
+ }
56
+ // Component Infos
57
+ else if (request.type === 'getComponentProps') {
58
+ const result = componentInfos_1.getComponentProps.apply(requestContext, request.args);
59
+ sendResponse(result);
60
+ }
61
+ else if (request.type === 'getComponentEvents') {
62
+ const result = componentInfos_1.getComponentEvents.apply(requestContext, request.args);
63
+ sendResponse(result);
64
+ }
65
+ else if (request.type === 'getTemplateContextProps') {
66
+ const result = componentInfos_1.getTemplateContextProps.apply(requestContext, request.args);
67
+ sendResponse(result);
68
+ }
69
+ else if (request.type === 'getComponentNames') {
70
+ const result = componentInfos_1.getComponentNames.apply(requestContext, request.args);
71
+ sendResponse(result);
72
+ }
73
+ else if (request.type === 'getElementAttrs') {
74
+ const result = componentInfos_1.getElementAttrs.apply(requestContext, request.args);
75
+ sendResponse(result);
85
76
  }
86
77
  else {
87
- console.warn('[Vue Named Pipe Server] No project found for:', fileName);
78
+ console.warn('[Vue Named Pipe Server] Unknown request type:', request.type);
88
79
  }
89
- connection.end();
90
80
  });
91
81
  connection.on('error', err => console.error('[Vue Named Pipe Server]', err.message));
82
+ function sendResponse(data) {
83
+ connection.write(JSON.stringify(data ?? null) + '\n\n');
84
+ }
92
85
  });
93
- cleanupPipeTable();
94
- const table = (0, utils_1.readPipeTable)();
95
- table.push({
96
- path: pipeFile,
97
- serverKind,
98
- currentDirectory,
99
- });
100
- (0, utils_1.updatePipeTable)(table);
101
- try {
102
- fs.unlinkSync(pipeFile);
86
+ for (let i = 0; i < 20; i++) {
87
+ const path = (0, utils_1.getNamedPipePath)(projectKind, i);
88
+ const socket = await (0, utils_1.connect)(path, 100);
89
+ if (typeof socket === 'object') {
90
+ socket.end();
91
+ }
92
+ const namedPipeOccupied = typeof socket === 'object' || socket === 'timeout';
93
+ if (namedPipeOccupied) {
94
+ continue;
95
+ }
96
+ const success = await tryListen(server, path);
97
+ if (success) {
98
+ break;
99
+ }
103
100
  }
104
- catch { }
105
- server.listen(pipeFile);
106
101
  }
107
- function cleanupPipeTable() {
108
- for (const server of (0, utils_1.readPipeTable)()) {
109
- (0, utils_1.connect)(server.path).then(client => {
110
- if (client) {
111
- client.end();
112
- }
113
- else {
114
- let table = (0, utils_1.readPipeTable)();
115
- table = table.filter(item => item.path !== server.path);
116
- (0, utils_1.updatePipeTable)(table);
102
+ function tryListen(server, namedPipePath) {
103
+ return new Promise(resolve => {
104
+ const onSuccess = () => {
105
+ server.off('error', onError);
106
+ resolve(true);
107
+ };
108
+ const onError = (err) => {
109
+ if (err.code === 'ECONNREFUSED') {
110
+ try {
111
+ console.log('[Vue Named Pipe Client] Deleting:', namedPipePath);
112
+ fs.promises.unlink(namedPipePath);
113
+ }
114
+ catch { }
117
115
  }
118
- });
119
- }
120
- }
121
- exports.projects = new Map();
122
- function getProject(filename) {
123
- for (const [project, data] of exports.projects) {
124
- if (project.containsFile(filename)) {
125
- return data;
126
- }
127
- }
116
+ server.off('error', onError);
117
+ server.close();
118
+ resolve(false);
119
+ };
120
+ server.listen(namedPipePath, onSuccess);
121
+ server.on('error', onError);
122
+ });
128
123
  }
129
124
  //# sourceMappingURL=server.js.map
package/lib/utils.d.ts CHANGED
@@ -1,23 +1,16 @@
1
1
  import * as net from 'net';
2
2
  import type * as ts from 'typescript';
3
- import type { Request } from './server';
3
+ import type { ProjectInfo, Request } from './server';
4
4
  export { TypeScriptProjectHost } from '@volar/typescript';
5
- export interface NamedPipeServer {
6
- path: string;
7
- serverKind: ts.server.ProjectKind;
8
- currentDirectory: string;
9
- }
10
- export declare function readPipeTable(): NamedPipeServer[];
11
- export declare function updatePipeTable(servers: NamedPipeServer[]): void;
12
- export declare function connect(path: string): Promise<net.Socket | undefined>;
5
+ export declare const onSomePipeReadyCallbacks: (() => void)[];
6
+ export declare function getNamedPipePath(projectKind: ts.server.ProjectKind.Configured | ts.server.ProjectKind.Inferred, key: number): string;
7
+ export declare function getReadyNamedPipePaths(): {
8
+ configured: string[];
9
+ inferred: string[];
10
+ };
11
+ export declare function connect(namedPipePath: string, timeout?: number): Promise<net.Socket | "error" | "timeout">;
13
12
  export declare function searchNamedPipeServerForFile(fileName: string): Promise<{
14
- server: NamedPipeServer;
15
- projectInfo: {
16
- name: string;
17
- kind: ts.server.ProjectKind;
18
- };
19
- } | {
20
- server: NamedPipeServer;
21
- projectInfo: undefined;
13
+ socket: net.Socket;
14
+ projectInfo: ProjectInfo;
22
15
  } | undefined>;
23
- export declare function sendRequestWorker<T>(request: Request, client: net.Socket): Promise<T | null | undefined>;
16
+ export declare function sendRequestWorker<T>(request: Request, socket: net.Socket): Promise<T | null | undefined>;
package/lib/utils.js CHANGED
@@ -1,81 +1,189 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.readPipeTable = readPipeTable;
4
- exports.updatePipeTable = updatePipeTable;
3
+ exports.onSomePipeReadyCallbacks = void 0;
4
+ exports.getNamedPipePath = getNamedPipePath;
5
+ exports.getReadyNamedPipePaths = getReadyNamedPipePaths;
5
6
  exports.connect = connect;
6
7
  exports.searchNamedPipeServerForFile = searchNamedPipeServerForFile;
7
8
  exports.sendRequestWorker = sendRequestWorker;
8
- const os = require("os");
9
+ const fs = require("fs");
9
10
  const net = require("net");
11
+ const os = require("os");
10
12
  const path = require("path");
11
- const fs = require("fs");
12
13
  const { version } = require('../package.json');
13
- const pipeTableFile = path.join(os.tmpdir(), `vue-tsp-table-${version}.json`);
14
- function readPipeTable() {
15
- if (!fs.existsSync(pipeTableFile)) {
16
- return [];
17
- }
18
- try {
19
- const servers = JSON.parse(fs.readFileSync(pipeTableFile, 'utf8'));
20
- return servers;
14
+ const platform = os.platform();
15
+ const pipeDir = platform === 'win32'
16
+ ? `\\\\.\\pipe`
17
+ : `/tmp`;
18
+ const toFullPath = (file) => {
19
+ if (platform === 'win32') {
20
+ return pipeDir + '\\' + file;
21
21
  }
22
- catch {
23
- fs.unlinkSync(pipeTableFile);
24
- return [];
22
+ else {
23
+ return pipeDir + '/' + file;
25
24
  }
25
+ };
26
+ const configuredNamedPipePathPrefix = toFullPath(`vue-named-pipe-${version}-configured-`);
27
+ const inferredNamedPipePathPrefix = toFullPath(`vue-named-pipe-${version}-inferred-`);
28
+ const pipes = new Map();
29
+ exports.onSomePipeReadyCallbacks = [];
30
+ function watchNamedPipeReady(namedPipePath) {
31
+ const socket = net.connect(namedPipePath);
32
+ const start = Date.now();
33
+ socket.on('connect', () => {
34
+ console.log('[Vue Named Pipe Client] Connected:', namedPipePath, 'in', (Date.now() - start) + 'ms');
35
+ socket.write('ping');
36
+ });
37
+ socket.on('data', () => {
38
+ console.log('[Vue Named Pipe Client] Ready:', namedPipePath, 'in', (Date.now() - start) + 'ms');
39
+ pipes.set(namedPipePath, 'ready');
40
+ socket.end();
41
+ exports.onSomePipeReadyCallbacks.forEach(cb => cb());
42
+ });
43
+ socket.on('error', err => {
44
+ if (err.code === 'ECONNREFUSED') {
45
+ try {
46
+ console.log('[Vue Named Pipe Client] Deleting:', namedPipePath);
47
+ fs.promises.unlink(namedPipePath);
48
+ }
49
+ catch { }
50
+ }
51
+ pipes.delete(namedPipePath);
52
+ socket.end();
53
+ });
26
54
  }
27
- function updatePipeTable(servers) {
28
- if (servers.length === 0) {
29
- fs.unlinkSync(pipeTableFile);
30
- }
31
- else {
32
- fs.writeFileSync(pipeTableFile, JSON.stringify(servers, undefined, 2));
55
+ function getNamedPipePath(projectKind, key) {
56
+ return projectKind === 1
57
+ ? `${configuredNamedPipePathPrefix}${key}`
58
+ : `${inferredNamedPipePathPrefix}${key}`;
59
+ }
60
+ function getReadyNamedPipePaths() {
61
+ const configuredPipes = [];
62
+ const inferredPipes = [];
63
+ for (let i = 0; i < 20; i++) {
64
+ const configuredPipe = getNamedPipePath(1, i);
65
+ const inferredPipe = getNamedPipePath(0, i);
66
+ if (pipes.get(configuredPipe) === 'ready') {
67
+ configuredPipes.push(configuredPipe);
68
+ }
69
+ else if (!pipes.has(configuredPipe)) {
70
+ pipes.set(configuredPipe, 'unknown');
71
+ watchNamedPipeReady(configuredPipe);
72
+ }
73
+ if (pipes.get(inferredPipe) === 'ready') {
74
+ inferredPipes.push(inferredPipe);
75
+ }
76
+ else if (!pipes.has(inferredPipe)) {
77
+ pipes.set(inferredPipe, 'unknown');
78
+ watchNamedPipeReady(inferredPipe);
79
+ }
33
80
  }
81
+ return {
82
+ configured: configuredPipes,
83
+ inferred: inferredPipes,
84
+ };
34
85
  }
35
- function connect(path) {
86
+ function connect(namedPipePath, timeout) {
36
87
  return new Promise(resolve => {
37
- const client = net.connect(path);
38
- client.setTimeout(1000);
39
- client.on('connect', () => {
40
- resolve(client);
41
- });
42
- client.on('error', () => {
43
- return resolve(undefined);
44
- });
45
- client.on('timeout', () => {
46
- return resolve(undefined);
47
- });
88
+ const socket = net.connect(namedPipePath);
89
+ if (timeout) {
90
+ socket.setTimeout(timeout);
91
+ }
92
+ const onConnect = () => {
93
+ cleanup();
94
+ resolve(socket);
95
+ };
96
+ const onError = (err) => {
97
+ if (err.code === 'ECONNREFUSED') {
98
+ try {
99
+ console.log('[Vue Named Pipe Client] Deleting:', namedPipePath);
100
+ fs.promises.unlink(namedPipePath);
101
+ }
102
+ catch { }
103
+ }
104
+ pipes.delete(namedPipePath);
105
+ cleanup();
106
+ resolve('error');
107
+ };
108
+ const onTimeout = () => {
109
+ cleanup();
110
+ resolve('timeout');
111
+ };
112
+ const cleanup = () => {
113
+ socket.off('connect', onConnect);
114
+ socket.off('error', onError);
115
+ socket.off('timeout', onTimeout);
116
+ };
117
+ socket.on('connect', onConnect);
118
+ socket.on('error', onError);
119
+ socket.on('timeout', onTimeout);
48
120
  });
49
121
  }
50
122
  async function searchNamedPipeServerForFile(fileName) {
51
- const servers = readPipeTable();
52
- const configuredServers = servers
53
- .filter(item => item.serverKind === 1);
54
- const inferredServers = servers
55
- .filter(item => item.serverKind === 0)
56
- .sort((a, b) => b.currentDirectory.length - a.currentDirectory.length);
57
- for (const server of configuredServers.sort((a, b) => sortTSConfigs(fileName, a.currentDirectory, b.currentDirectory))) {
58
- const client = await connect(server.path);
59
- if (client) {
60
- const projectInfo = await sendRequestWorker({ type: 'projectInfoForFile', args: [fileName] }, client);
61
- if (projectInfo) {
62
- return {
63
- server,
64
- projectInfo,
65
- };
66
- }
123
+ const paths = await getReadyNamedPipePaths();
124
+ const configuredServers = (await Promise.all(paths.configured.map(async (path) => {
125
+ // Find existing servers
126
+ const socket = await connect(path);
127
+ if (typeof socket !== 'object') {
128
+ return;
129
+ }
130
+ // Find servers containing the current file
131
+ const containsFile = await sendRequestWorker({ type: 'containsFile', args: [fileName] }, socket);
132
+ if (!containsFile) {
133
+ socket.end();
134
+ return;
135
+ }
136
+ // Get project info for each server
137
+ const projectInfo = await sendRequestWorker({ type: 'projectInfo', args: [fileName] }, socket);
138
+ if (!projectInfo) {
139
+ socket.end();
140
+ return;
141
+ }
142
+ return {
143
+ socket,
144
+ projectInfo,
145
+ };
146
+ }))).filter(server => !!server);
147
+ // Sort servers by tsconfig
148
+ configuredServers.sort((a, b) => sortTSConfigs(fileName, a.projectInfo.name, b.projectInfo.name));
149
+ if (configuredServers.length) {
150
+ // Close all but the first server
151
+ for (let i = 1; i < configuredServers.length; i++) {
152
+ configuredServers[i].socket.end();
67
153
  }
154
+ // Return the first server
155
+ return configuredServers[0];
68
156
  }
69
- for (const server of inferredServers) {
70
- if (!path.relative(server.currentDirectory, fileName).startsWith('..')) {
71
- const client = await connect(server.path);
72
- if (client) {
73
- return {
74
- server,
75
- projectInfo: undefined,
76
- };
77
- }
157
+ const inferredServers = (await Promise.all(paths.inferred.map(async (namedPipePath) => {
158
+ // Find existing servers
159
+ const socket = await connect(namedPipePath);
160
+ if (typeof socket !== 'object') {
161
+ return;
162
+ }
163
+ // Get project info for each server
164
+ const projectInfo = await sendRequestWorker({ type: 'projectInfo', args: [fileName] }, socket);
165
+ if (!projectInfo) {
166
+ socket.end();
167
+ return;
168
+ }
169
+ // Check if the file is in the project's directory
170
+ if (!path.relative(projectInfo.currentDirectory, fileName).startsWith('..')) {
171
+ return {
172
+ socket,
173
+ projectInfo,
174
+ };
175
+ }
176
+ }))).filter(server => !!server);
177
+ // Sort servers by directory
178
+ inferredServers.sort((a, b) => b.projectInfo.currentDirectory.replace(/\\/g, '/').split('/').length
179
+ - a.projectInfo.currentDirectory.replace(/\\/g, '/').split('/').length);
180
+ if (inferredServers.length) {
181
+ // Close all but the first server
182
+ for (let i = 1; i < inferredServers.length; i++) {
183
+ inferredServers[i].socket.end();
78
184
  }
185
+ // Return the first server
186
+ return inferredServers[0];
79
187
  }
80
188
  }
81
189
  function sortTSConfigs(file, a, b) {
@@ -94,41 +202,37 @@ function isFileInDir(fileName, dir) {
94
202
  const relative = path.relative(dir, fileName);
95
203
  return !!relative && !relative.startsWith('..') && !path.isAbsolute(relative);
96
204
  }
97
- function sendRequestWorker(request, client) {
205
+ function sendRequestWorker(request, socket) {
98
206
  return new Promise(resolve => {
99
207
  let dataChunks = [];
100
- client.setTimeout(5000);
101
- client.on('data', chunk => {
208
+ const onData = (chunk) => {
102
209
  dataChunks.push(chunk);
103
- });
104
- client.on('end', () => {
105
- if (!dataChunks.length) {
106
- console.warn('[Vue Named Pipe Client] No response from server for request:', request.type);
107
- resolve(undefined);
108
- return;
109
- }
110
210
  const data = Buffer.concat(dataChunks);
111
211
  const text = data.toString();
112
- let json = null;
113
- try {
114
- json = JSON.parse(text);
212
+ if (text.endsWith('\n\n')) {
213
+ let json = null;
214
+ try {
215
+ json = JSON.parse(text);
216
+ }
217
+ catch (e) {
218
+ console.error('[Vue Named Pipe Client] Failed to parse response:', text);
219
+ }
220
+ cleanup();
221
+ resolve(json);
115
222
  }
116
- catch (e) {
117
- console.error('[Vue Named Pipe Client] Failed to parse response:', text);
118
- resolve(undefined);
119
- return;
120
- }
121
- resolve(json);
122
- });
123
- client.on('error', err => {
223
+ };
224
+ const onError = (err) => {
124
225
  console.error('[Vue Named Pipe Client] Error:', err.message);
226
+ cleanup();
125
227
  resolve(undefined);
126
- });
127
- client.on('timeout', () => {
128
- console.error('[Vue Named Pipe Client] Timeout');
129
- resolve(undefined);
130
- });
131
- client.write(JSON.stringify(request));
228
+ };
229
+ const cleanup = () => {
230
+ socket.off('data', onData);
231
+ socket.off('error', onError);
232
+ };
233
+ socket.on('data', onData);
234
+ socket.on('error', onError);
235
+ socket.write(JSON.stringify(request));
132
236
  });
133
237
  }
134
238
  //# sourceMappingURL=utils.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vue/typescript-plugin",
3
- "version": "2.0.26",
3
+ "version": "2.0.28",
4
4
  "license": "MIT",
5
5
  "files": [
6
6
  "**/*.js",
@@ -12,12 +12,12 @@
12
12
  "directory": "packages/typescript-plugin"
13
13
  },
14
14
  "dependencies": {
15
- "@volar/typescript": "~2.4.0-alpha.15",
16
- "@vue/language-core": "2.0.26",
15
+ "@volar/typescript": "~2.4.0-alpha.18",
16
+ "@vue/language-core": "2.0.28",
17
17
  "@vue/shared": "^3.4.0"
18
18
  },
19
19
  "devDependencies": {
20
20
  "@types/node": "latest"
21
21
  },
22
- "gitHead": "47924f61e9409501d11ab04e9d3417cc5c86232c"
22
+ "gitHead": "0cdbd70996f4fc7ac8d511b0d9fdbe20b7a4f6a3"
23
23
  }