@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 +6 -10
- package/lib/client.js +4 -7
- package/lib/server.d.ts +8 -8
- package/lib/server.js +96 -101
- package/lib/utils.d.ts +11 -18
- package/lib/utils.js +189 -85
- package/package.json +4 -4
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.
|
|
9
|
+
const languagePlugin = vue.createVueLanguagePlugin2(ts, id => id, info.project.projectKind === ts.server.ProjectKind.Inferred
|
|
10
10
|
? () => true
|
|
11
|
-
:
|
|
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
|
-
|
|
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]))
|
|
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
|
|
75
|
-
|
|
76
|
-
|
|
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
|
|
1
|
+
import type { Language } from '@vue/language-core';
|
|
2
2
|
import type * as ts from 'typescript';
|
|
3
3
|
export interface Request {
|
|
4
|
-
type: '
|
|
4
|
+
type: 'containsFile' | 'projectInfo' | 'collectExtractProps' | 'getImportPathForFile' | 'getPropertiesAtLocation' | 'getQuickInfoAtPosition' | 'getComponentProps' | 'getComponentEvents' | 'getTemplateContextProps' | 'getComponentNames' | 'getElementAttrs';
|
|
5
5
|
args: [fileName: string, ...rest: any];
|
|
6
6
|
}
|
|
7
|
-
export
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
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
|
-
|
|
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
|
-
|
|
28
|
-
|
|
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
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
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]
|
|
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
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
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
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
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
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
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
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
export declare function
|
|
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
|
-
|
|
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,
|
|
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.
|
|
4
|
-
exports.
|
|
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
|
|
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
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
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
|
-
|
|
23
|
-
|
|
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
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
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(
|
|
86
|
+
function connect(namedPipePath, timeout) {
|
|
36
87
|
return new Promise(resolve => {
|
|
37
|
-
const
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
|
|
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
|
|
52
|
-
const configuredServers =
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
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
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
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,
|
|
205
|
+
function sendRequestWorker(request, socket) {
|
|
98
206
|
return new Promise(resolve => {
|
|
99
207
|
let dataChunks = [];
|
|
100
|
-
|
|
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
|
-
|
|
113
|
-
|
|
114
|
-
|
|
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
|
-
|
|
117
|
-
|
|
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
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
}
|
|
131
|
-
|
|
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.
|
|
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.
|
|
16
|
-
"@vue/language-core": "2.0.
|
|
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": "
|
|
22
|
+
"gitHead": "0cdbd70996f4fc7ac8d511b0d9fdbe20b7a4f6a3"
|
|
23
23
|
}
|