From aacd544110c97618ddf6ebbea965de6e27bd2ef3 Mon Sep 17 00:00:00 2001 From: Sheetal Nandi Date: Tue, 21 Feb 2023 15:18:12 -0800 Subject: [PATCH 1/3] Deferred TI creation --- src/typingsInstaller/nodeTypingsInstaller.ts | 99 ++++++++++---------- 1 file changed, 48 insertions(+), 51 deletions(-) diff --git a/src/typingsInstaller/nodeTypingsInstaller.ts b/src/typingsInstaller/nodeTypingsInstaller.ts index 146d392d2553f..5928e9b5c9782 100644 --- a/src/typingsInstaller/nodeTypingsInstaller.ts +++ b/src/typingsInstaller/nodeTypingsInstaller.ts @@ -106,9 +106,9 @@ type ExecSync = (command: string, options: ExecSyncOptions) => string; export class NodeTypingsInstaller extends TypingsInstaller { private readonly nodeExecSync: ExecSync; private readonly npmPath: string; - readonly typesRegistry: Map>; + typesRegistry: Map> = undefined!; - private delayedInitializationError: InitializationFailedResponse | undefined; + delayedInitializationError: InitializationFailedResponse | undefined; constructor(globalTypingsCacheLocation: string, typingSafeListLocation: string, typesMapLocation: string, npmLocation: string | undefined, validateDefaultNpmLocation: boolean, throttleLimit: number, log: Log) { const libDirectory = getDirectoryPath(normalizePath(sys.getExecutingFilePath())); @@ -158,52 +158,7 @@ export class NodeTypingsInstaller extends TypingsInstaller { this.typesRegistry = loadTypesRegistryFile(getTypesRegistryFileLocation(globalTypingsCacheLocation), this.installTypingHost, this.log); } - listen() { - process.on("message", (req: TypingInstallerRequestUnion) => { - if (this.delayedInitializationError) { - // report initializationFailed error - this.sendResponse(this.delayedInitializationError); - this.delayedInitializationError = undefined; - } - switch (req.kind) { - case "discover": - this.install(req); - break; - case "closeProject": - this.closeProject(req); - break; - case "typesRegistry": { - const typesRegistry: { [key: string]: MapLike } = {}; - this.typesRegistry.forEach((value, key) => { - typesRegistry[key] = value; - }); - const response: TypesRegistryResponse = { kind: EventTypesRegistry, typesRegistry }; - this.sendResponse(response); - break; - } - case "installPackage": { - const { fileName, packageName, projectName, projectRootPath } = req; - const cwd = getDirectoryOfPackageJson(fileName, this.installTypingHost) || projectRootPath; - if (cwd) { - this.installWorker(-1, [packageName], cwd, success => { - const message = success ? `Package ${packageName} installed.` : `There was an error installing ${packageName}.`; - const response: PackageInstalledResponse = { kind: ActionPackageInstalled, projectName, success, message }; - this.sendResponse(response); - }); - } - else { - const response: PackageInstalledResponse = { kind: ActionPackageInstalled, projectName, success: false, message: "Could not determine a project root path." }; - this.sendResponse(response); - } - break; - } - default: - Debug.assertNever(req); - } - }); - } - - protected sendResponse(response: TypingInstallerResponseUnion) { + sendResponse(response: TypingInstallerResponseUnion) { if (this.log.isEnabled()) { this.log.writeLine(`Sending response:\n ${JSON.stringify(response)}`); } @@ -213,7 +168,7 @@ export class NodeTypingsInstaller extends TypingsInstaller { } } - protected installWorker(requestId: number, packageNames: string[], cwd: string, onRequestCompleted: RequestCompletedAction): void { + installWorker(requestId: number, packageNames: string[], cwd: string, onRequestCompleted: RequestCompletedAction): void { if (this.log.isEnabled()) { this.log.writeLine(`#${requestId} with arguments'${JSON.stringify(packageNames)}'.`); } @@ -272,8 +227,50 @@ process.on("disconnect", () => { } process.exit(0); }); -const installer = new NodeTypingsInstaller(globalTypingsCacheLocation!, typingSafeListLocation!, typesMapLocation!, npmLocation, validateDefaultNpmLocation, /*throttleLimit*/5, log); // TODO: GH#18217 -installer.listen(); +let installer: NodeTypingsInstaller | undefined; +process.on("message", (req: TypingInstallerRequestUnion) => { + installer ??= new NodeTypingsInstaller(globalTypingsCacheLocation!, typingSafeListLocation!, typesMapLocation!, npmLocation, validateDefaultNpmLocation, /*throttleLimit*/5, log); // TODO: GH#18217 + if (installer.delayedInitializationError) { + // report initializationFailed error + installer.sendResponse(installer.delayedInitializationError); + installer.delayedInitializationError = undefined; + } + switch (req.kind) { + case "discover": + installer.install(req); + break; + case "closeProject": + installer.closeProject(req); + break; + case "typesRegistry": { + const typesRegistry: { [key: string]: MapLike } = {}; + installer.typesRegistry.forEach((value, key) => { + typesRegistry[key] = value; + }); + const response: TypesRegistryResponse = { kind: EventTypesRegistry, typesRegistry }; + installer.sendResponse(response); + break; + } + case "installPackage": { + const { fileName, packageName, projectName, projectRootPath } = req; + const cwd = getDirectoryOfPackageJson(fileName, sys) || projectRootPath; + if (cwd) { + installer.installWorker(-1, [packageName], cwd, success => { + const message = success ? `Package ${packageName} installed.` : `There was an error installing ${packageName}.`; + const response: PackageInstalledResponse = { kind: ActionPackageInstalled, projectName, success, message }; + installer!.sendResponse(response); + }); + } + else { + const response: PackageInstalledResponse = { kind: ActionPackageInstalled, projectName, success: false, message: "Could not determine a project root path." }; + installer.sendResponse(response); + } + break; + } + default: + Debug.assertNever(req); + } +}); function indent(newline: string, str: string | undefined): string { return str && str.length From 541ace3b4770c41e82c1b86534b95e787348d3a5 Mon Sep 17 00:00:00 2001 From: Sheetal Nandi Date: Tue, 21 Feb 2023 15:37:03 -0800 Subject: [PATCH 2/3] fix incorrect pick --- src/typingsInstaller/nodeTypingsInstaller.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/typingsInstaller/nodeTypingsInstaller.ts b/src/typingsInstaller/nodeTypingsInstaller.ts index 5928e9b5c9782..64c7c603db1fd 100644 --- a/src/typingsInstaller/nodeTypingsInstaller.ts +++ b/src/typingsInstaller/nodeTypingsInstaller.ts @@ -106,7 +106,7 @@ type ExecSync = (command: string, options: ExecSyncOptions) => string; export class NodeTypingsInstaller extends TypingsInstaller { private readonly nodeExecSync: ExecSync; private readonly npmPath: string; - typesRegistry: Map> = undefined!; + readonly typesRegistry: Map>; delayedInitializationError: InitializationFailedResponse | undefined; From 278e03b2b751a4a5dd10507dc28d73a347939867 Mon Sep 17 00:00:00 2001 From: Sheetal Nandi Date: Wed, 22 Feb 2023 09:51:10 -0800 Subject: [PATCH 3/3] Make method on installer --- src/typingsInstaller/nodeTypingsInstaller.ts | 90 ++++++++++---------- 1 file changed, 47 insertions(+), 43 deletions(-) diff --git a/src/typingsInstaller/nodeTypingsInstaller.ts b/src/typingsInstaller/nodeTypingsInstaller.ts index 64c7c603db1fd..91be7a4b8c641 100644 --- a/src/typingsInstaller/nodeTypingsInstaller.ts +++ b/src/typingsInstaller/nodeTypingsInstaller.ts @@ -108,7 +108,7 @@ export class NodeTypingsInstaller extends TypingsInstaller { private readonly npmPath: string; readonly typesRegistry: Map>; - delayedInitializationError: InitializationFailedResponse | undefined; + private delayedInitializationError: InitializationFailedResponse | undefined; constructor(globalTypingsCacheLocation: string, typingSafeListLocation: string, typesMapLocation: string, npmLocation: string | undefined, validateDefaultNpmLocation: boolean, throttleLimit: number, log: Log) { const libDirectory = getDirectoryPath(normalizePath(sys.getExecutingFilePath())); @@ -158,7 +158,50 @@ export class NodeTypingsInstaller extends TypingsInstaller { this.typesRegistry = loadTypesRegistryFile(getTypesRegistryFileLocation(globalTypingsCacheLocation), this.installTypingHost, this.log); } - sendResponse(response: TypingInstallerResponseUnion) { + handleRequest(req: TypingInstallerRequestUnion) { + if (this.delayedInitializationError) { + // report initializationFailed error + this.sendResponse(this.delayedInitializationError); + this.delayedInitializationError = undefined; + } + switch (req.kind) { + case "discover": + this.install(req); + break; + case "closeProject": + this.closeProject(req); + break; + case "typesRegistry": { + const typesRegistry: { [key: string]: MapLike } = {}; + this.typesRegistry.forEach((value, key) => { + typesRegistry[key] = value; + }); + const response: TypesRegistryResponse = { kind: EventTypesRegistry, typesRegistry }; + this.sendResponse(response); + break; + } + case "installPackage": { + const { fileName, packageName, projectName, projectRootPath } = req; + const cwd = getDirectoryOfPackageJson(fileName, this.installTypingHost) || projectRootPath; + if (cwd) { + this.installWorker(-1, [packageName], cwd, success => { + const message = success ? `Package ${packageName} installed.` : `There was an error installing ${packageName}.`; + const response: PackageInstalledResponse = { kind: ActionPackageInstalled, projectName, success, message }; + this.sendResponse(response); + }); + } + else { + const response: PackageInstalledResponse = { kind: ActionPackageInstalled, projectName, success: false, message: "Could not determine a project root path." }; + this.sendResponse(response); + } + break; + } + default: + Debug.assertNever(req); + } + } + + protected sendResponse(response: TypingInstallerResponseUnion) { if (this.log.isEnabled()) { this.log.writeLine(`Sending response:\n ${JSON.stringify(response)}`); } @@ -168,7 +211,7 @@ export class NodeTypingsInstaller extends TypingsInstaller { } } - installWorker(requestId: number, packageNames: string[], cwd: string, onRequestCompleted: RequestCompletedAction): void { + protected installWorker(requestId: number, packageNames: string[], cwd: string, onRequestCompleted: RequestCompletedAction): void { if (this.log.isEnabled()) { this.log.writeLine(`#${requestId} with arguments'${JSON.stringify(packageNames)}'.`); } @@ -230,46 +273,7 @@ process.on("disconnect", () => { let installer: NodeTypingsInstaller | undefined; process.on("message", (req: TypingInstallerRequestUnion) => { installer ??= new NodeTypingsInstaller(globalTypingsCacheLocation!, typingSafeListLocation!, typesMapLocation!, npmLocation, validateDefaultNpmLocation, /*throttleLimit*/5, log); // TODO: GH#18217 - if (installer.delayedInitializationError) { - // report initializationFailed error - installer.sendResponse(installer.delayedInitializationError); - installer.delayedInitializationError = undefined; - } - switch (req.kind) { - case "discover": - installer.install(req); - break; - case "closeProject": - installer.closeProject(req); - break; - case "typesRegistry": { - const typesRegistry: { [key: string]: MapLike } = {}; - installer.typesRegistry.forEach((value, key) => { - typesRegistry[key] = value; - }); - const response: TypesRegistryResponse = { kind: EventTypesRegistry, typesRegistry }; - installer.sendResponse(response); - break; - } - case "installPackage": { - const { fileName, packageName, projectName, projectRootPath } = req; - const cwd = getDirectoryOfPackageJson(fileName, sys) || projectRootPath; - if (cwd) { - installer.installWorker(-1, [packageName], cwd, success => { - const message = success ? `Package ${packageName} installed.` : `There was an error installing ${packageName}.`; - const response: PackageInstalledResponse = { kind: ActionPackageInstalled, projectName, success, message }; - installer!.sendResponse(response); - }); - } - else { - const response: PackageInstalledResponse = { kind: ActionPackageInstalled, projectName, success: false, message: "Could not determine a project root path." }; - installer.sendResponse(response); - } - break; - } - default: - Debug.assertNever(req); - } + installer.handleRequest(req); }); function indent(newline: string, str: string | undefined): string {