@notjustcoders/ioc-arise
Version:
Arise type-safe IoC containers from your code. Zero overhead, zero coupling.
73 lines • 3.32 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.ModuleDependencyResolver = void 0;
const topological_sorter_1 = require("../utils/topological-sorter");
class ModuleDependencyResolver {
constructor(moduleGroupedClasses) {
this.moduleGroupedClasses = moduleGroupedClasses;
this.interfaceToModuleMap = this.buildInterfaceToModuleMap();
}
resolve() {
const moduleDependencies = this.buildModuleDependencyGraph();
const sortResult = this.topologicalSort(moduleDependencies);
return {
sortedModules: sortResult.sorted,
cycles: sortResult.cycles,
moduleDependencies
};
}
buildInterfaceToModuleMap() {
const interfaceToModuleMap = new Map();
for (const [moduleName, classes] of this.moduleGroupedClasses) {
for (const classInfo of classes) {
// Map both interface names and class names to their modules
if (classInfo.interfaceName) {
interfaceToModuleMap.set(classInfo.interfaceName, moduleName);
}
// Also map class names to their modules for cross-module class dependencies
interfaceToModuleMap.set(classInfo.name, moduleName);
// For concrete classes that extend abstract classes, map the abstract class to this module
if (classInfo.abstractClassName) {
interfaceToModuleMap.set(classInfo.abstractClassName, moduleName);
}
}
}
return interfaceToModuleMap;
}
buildModuleDependencyGraph() {
const moduleDependencies = new Map();
// Initialize all modules with empty dependency sets
for (const moduleName of this.moduleGroupedClasses.keys()) {
moduleDependencies.set(moduleName, new Set());
}
// Analyze dependencies between modules
for (const [moduleName, classes] of this.moduleGroupedClasses) {
const moduleDeps = moduleDependencies.get(moduleName);
for (const classInfo of classes) {
for (const dependency of classInfo.dependencies) {
// Check if this dependency is an interface or class from another module
const dependencyModule = this.interfaceToModuleMap.get(dependency.name);
if (dependencyModule && dependencyModule !== moduleName) {
moduleDeps.add(dependencyModule);
}
}
}
}
return moduleDependencies;
}
topologicalSort(moduleDependencies) {
// Convert Map<string, Set<string>> to Map<string, string[]> for TopologicalSorter
const graphMap = new Map();
for (const [module, deps] of moduleDependencies) {
graphMap.set(module, Array.from(deps));
}
return topological_sorter_1.TopologicalSorter.sort(graphMap, "desc");
}
getModuleDependencies(moduleName) {
const result = this.resolve();
const deps = result.moduleDependencies.get(moduleName);
return deps ? Array.from(deps) : [];
}
}
exports.ModuleDependencyResolver = ModuleDependencyResolver;
//# sourceMappingURL=module-dependency-resolver.js.map