sicua
Version:
A tool for analyzing project structure and dependencies
162 lines (161 loc) • 5.63 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.ComponentLookupService = void 0;
const analysisUtils_1 = require("../utils/common/analysisUtils");
const path_1 = __importDefault(require("path"));
/**
* High-performance lookup service for component relations
* Pre-builds hash maps for O(1) component lookups instead of O(n) array searches
*/
class ComponentLookupService {
constructor(components) {
this.lookupMaps = this.buildLookupMaps(components);
}
/**
* Find component by unique ID - O(1)
*/
getComponentById(id) {
return this.lookupMaps.byId.get(id);
}
/**
* Find components by name - O(1)
*/
getComponentsByName(name) {
return this.lookupMaps.byName.get(name) || [];
}
/**
* Find component by full path - O(1)
*/
getComponentByPath(fullPath) {
return this.lookupMaps.byPath.get(fullPath);
}
/**
* Find components in directory - O(1)
*/
getComponentsByDirectory(directory) {
return this.lookupMaps.byDirectory.get(directory) || [];
}
/**
* Find components by normalized import path - O(1)
*/
getComponentsByNormalizedImport(normalizedImport) {
return this.lookupMaps.byNormalizedImport.get(normalizedImport) || [];
}
/**
* Get all component IDs - O(1)
*/
getAllComponentIds() {
return Array.from(this.lookupMaps.byId.keys());
}
/**
* Get all components - O(1)
*/
getAllComponents() {
return Array.from(this.lookupMaps.byId.values());
}
/**
* Check if component exists by ID - O(1)
*/
hasComponentById(id) {
return this.lookupMaps.byId.has(id);
}
/**
* Check if component exists by name - O(1)
*/
hasComponentByName(name) {
return this.lookupMaps.byName.has(name);
}
/**
* Get component count - O(1)
*/
getComponentCount() {
return this.lookupMaps.byId.size;
}
/**
* Find target component IDs for an import path
*/
resolveImportToComponentIds(importPath) {
const normalizedImport = this.normalizeImportPath(importPath);
const matchingComponents = this.getComponentsByNormalizedImport(normalizedImport);
return matchingComponents.map((comp) => (0, analysisUtils_1.generateComponentId)(comp));
}
/**
* Build all lookup maps during initialization - O(n) operation done once
*/
buildLookupMaps(components) {
const byId = new Map();
const byName = new Map();
const byPath = new Map();
const byDirectory = new Map();
const byNormalizedImport = new Map();
for (const component of components) {
const componentId = (0, analysisUtils_1.generateComponentId)(component);
// Index by unique ID
byId.set(componentId, component);
// Index by name (can have multiple components with same name in different directories)
if (!byName.has(component.name)) {
byName.set(component.name, []);
}
byName.get(component.name).push(component);
// Index by full path (should be unique)
byPath.set(component.fullPath, component);
// Index by directory
if (!byDirectory.has(component.directory)) {
byDirectory.set(component.directory, []);
}
byDirectory.get(component.directory).push(component);
// Index by normalized import patterns
const normalizedPatterns = this.generateNormalizedImportPatterns(component);
for (const pattern of normalizedPatterns) {
if (!byNormalizedImport.has(pattern)) {
byNormalizedImport.set(pattern, []);
}
byNormalizedImport.get(pattern).push(component);
}
}
return {
byId,
byName,
byPath,
byDirectory,
byNormalizedImport,
};
}
/**
* Generate all possible normalized import patterns for a component
*/
generateNormalizedImportPatterns(component) {
const patterns = new Set();
// Add component name
patterns.add(component.name);
// Add variations of the file path
const fileName = path_1.default.basename(component.fullPath, path_1.default.extname(component.fullPath));
patterns.add(fileName);
// Add relative path variations
const relativePath = component.fullPath;
if (relativePath) {
patterns.add(relativePath.replace(/\.(js|jsx|ts|tsx)$/, ""));
patterns.add(relativePath);
// Add path without extension
const withoutExt = relativePath.replace(/\.(js|jsx|ts|tsx)$/, "");
patterns.add(withoutExt);
// Add just the directory + filename
const dirAndFile = path_1.default.join(component.directory, fileName);
patterns.add(dirAndFile);
}
return Array.from(patterns).filter((pattern) => pattern.length > 0);
}
/**
* Normalize import path for consistent lookups
*/
normalizeImportPath(importPath) {
return importPath
.replace(/\.(js|jsx|ts|tsx)$/, "")
.replace(/^\.\//, "")
.replace(/^\//, "");
}
}
exports.ComponentLookupService = ComponentLookupService;