From 7b866f6fc14fcda722bb777e7c7e85f5d9b7db8e Mon Sep 17 00:00:00 2001 From: ArnavK-09 Date: Tue, 28 Jan 2025 13:49:29 +0000 Subject: [PATCH] implement filesystemtypeshandler --- cli/dev/DevServer.ts | 59 ++-------------- .../FilesystemTypesHandler.ts | 68 +++++++++++++++++++ 2 files changed, 73 insertions(+), 54 deletions(-) create mode 100644 lib/dependency-analysis/FilesystemTypesHandler.ts diff --git a/cli/dev/DevServer.ts b/cli/dev/DevServer.ts index b2d0596..88af477 100644 --- a/cli/dev/DevServer.ts +++ b/cli/dev/DevServer.ts @@ -8,8 +8,7 @@ import path from "node:path" import fs from "node:fs" import type { FileUpdatedEvent } from "lib/file-server/FileServerEvent" import * as chokidar from "chokidar" -import { installNodeModuleTypesForSnippet } from "lib/dependency-analysis/installNodeModuleTypesForSnippet" -import { findImportsInSnippet } from "lib/dependency-analysis/findImportsInSnippet" +import { FilesystemTypesHandler } from "lib/dependency-analysis/FilesystemTypesHandler" export class DevServer { port: number @@ -39,6 +38,8 @@ export class DevServer { */ filesystemWatcher?: chokidar.FSWatcher + private typesHandler?: FilesystemTypesHandler + constructor({ port, componentFilePath, @@ -80,7 +81,7 @@ export class DevServer { this.upsertInitialFiles() - await this.handleTypeDependencies(this.componentFilePath) + this.typesHandler = new FilesystemTypesHandler(this.projectDir) } async addEntrypoint() { @@ -123,14 +124,7 @@ circuit.add() // because it can be edited by the browser if (relativeFilePath.includes("manual-edits.json")) return - try { - if (!this.areTypesInstalled(absoluteFilePath)) { - console.log("Types outdated, installing...") - await installNodeModuleTypesForSnippet(absoluteFilePath) - } - } catch (error) { - console.warn("Failed to verify types:", error) - } + await this.typesHandler?.handleFileTypeDependencies(absoluteFilePath) console.log(`${relativeFilePath} saved. Applying changes...`) await this.fsKy @@ -168,47 +162,4 @@ circuit.add() this.httpServer?.close() this.eventsWatcher?.stop() } - - private async handleTypeDependencies(absoluteFilePath: string) { - console.log("Checking type dependencies...") - try { - const needsInstallation = !this.areTypesInstalled(absoluteFilePath) - if (needsInstallation) { - console.log("Installing missing types...") - await installNodeModuleTypesForSnippet(absoluteFilePath) - } - } catch (error) { - console.warn("Error handling type dependencies:", error) - } - } - - private areTypesInstalled(absoluteFilePath: string): boolean { - const imports = findImportsInSnippet(absoluteFilePath) - return imports.every((imp) => this.checkTypeExists(imp)) - } - - private checkTypeExists(importPath: string): boolean { - if (!importPath.startsWith("@tsci/")) return true - - let projectRoot = this.projectDir - while (projectRoot !== path.parse(projectRoot).root) { - if (fs.existsSync(path.join(projectRoot, "package.json"))) { - break - } - projectRoot = path.dirname(projectRoot) - } - - const pathWithoutPrefix = importPath.replace("@tsci/", "") - const [owner, name] = pathWithoutPrefix.split(".") - - const typePath = path.join( - projectRoot, - "node_modules", - "@tsci", - `${owner}.${name}`, - "index.d.ts", - ) - - return fs.existsSync(typePath) - } } diff --git a/lib/dependency-analysis/FilesystemTypesHandler.ts b/lib/dependency-analysis/FilesystemTypesHandler.ts new file mode 100644 index 0000000..badf4dc --- /dev/null +++ b/lib/dependency-analysis/FilesystemTypesHandler.ts @@ -0,0 +1,68 @@ +import * as fs from "node:fs" +import * as path from "node:path" +import { findImportsInSnippet } from "./findImportsInSnippet" +import { installNodeModuleTypesForSnippet } from "./installNodeModuleTypesForSnippet" + +export class FilesystemTypesHandler { + private projectRoot: string + + constructor(initialDir: string) { + this.projectRoot = this.findProjectRoot(initialDir) + } + + async handleInitialTypeDependencies(filePath: string) { + console.log("Checking initial type dependencies...") + try { + if (!this.areTypesInstalled(filePath)) { + console.log("Installing missing initial types...") + await installNodeModuleTypesForSnippet(filePath) + } + } catch (error) { + console.warn("Error handling initial type dependencies:", error) + } + } + + async handleFileTypeDependencies(filePath: string) { + try { + if (!this.areTypesInstalled(filePath)) { + console.log("Installing missing file types...") + await installNodeModuleTypesForSnippet(filePath) + } + } catch (error) { + console.warn("Failed to verify types:", error) + } + } + + private areTypesInstalled(filePath: string): boolean { + const imports = findImportsInSnippet(filePath) + return imports.every((imp) => this.checkTypeExists(imp)) + } + + private checkTypeExists(importPath: string): boolean { + if (!importPath.startsWith("@tsci/")) return true + + const pathWithoutPrefix = importPath.replace("@tsci/", "") + const [owner, name] = pathWithoutPrefix.split(".") + + const typePath = path.join( + this.projectRoot, + "node_modules", + "@tsci", + `${owner}.${name}`, + "index.d.ts", + ) + + return fs.existsSync(typePath) + } + + private findProjectRoot(startDir: string): string { + let root = path.resolve(startDir) + while (root !== path.parse(root).root) { + if (fs.existsSync(path.join(root, "package.json"))) { + return root + } + root = path.dirname(root) + } + return startDir + } +}