Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 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 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 | 6x 6x 6x 6x 6x 6x 6x 6x 6x 6x 6x 6x 6x 6x 6x 6x 6x | import type {
ContextAnalysisResult,
DependencyGraph,
DependencyNode,
ModuleCluster,
} from './types';
import { calculateEnhancedCohesion } from './metrics';
import { analyzeIssues } from './issue-analyzer';
import {
calculateImportDepth,
getTransitiveDependencies,
calculateContextBudget,
} from './graph-builder';
import {
classifyFile,
adjustCohesionForClassification,
adjustFragmentationForClassification,
} from './classifier';
import { getClassificationRecommendations } from './remediation';
export interface MappingOptions {
maxDepth: number;
maxContextBudget: number;
minCohesion: number;
maxFragmentation: number;
}
/**
* Maps a single dependency node to a comprehensive ContextAnalysisResult.
*
* @param node - The dependency node to map
* @param graph - The full dependency graph
* @param clusters - All identified module clusters
* @param allCircularDeps - All identified circular dependencies
* @param options - Mapping options for detailed analysis
*/
export function mapNodeToResult(
node: DependencyNode,
graph: DependencyGraph,
clusters: ModuleCluster[],
allCircularDeps: string[][],
options: MappingOptions
): ContextAnalysisResult {
const file = node.file;
const tokenCost = node.tokenCost;
const importDepth = calculateImportDepth(file, graph);
const transitiveDeps = getTransitiveDependencies(file, graph);
const contextBudget = calculateContextBudget(file, graph);
const circularDeps = allCircularDeps.filter((cycle) => cycle.includes(file));
// Find cluster for this file
const cluster = clusters.find((c) => c.files.includes(file));
const rawFragmentationScore = cluster ? cluster.fragmentationScore : 0;
// Cohesion
const rawCohesionScore = calculateEnhancedCohesion(
node.exports,
file,
options as any
);
// Initial classification
const fileClassification = classifyFile(node, rawCohesionScore);
// Adjust scores based on classification
const cohesionScore = adjustCohesionForClassification(
rawCohesionScore,
fileClassification
);
const fragmentationScore = adjustFragmentationForClassification(
rawFragmentationScore,
fileClassification
);
const { severity, issues, recommendations, potentialSavings } = analyzeIssues(
{
file,
importDepth,
contextBudget,
cohesionScore,
fragmentationScore,
maxDepth: options.maxDepth,
maxContextBudget: options.maxContextBudget,
minCohesion: options.minCohesion,
maxFragmentation: options.maxFragmentation,
circularDeps,
}
);
// Add classification-specific recommendations
const classRecs = getClassificationRecommendations(
fileClassification,
file,
issues
);
const allRecommendations = Array.from(
new Set([...recommendations, ...classRecs])
);
return {
file,
tokenCost,
linesOfCode: node.linesOfCode,
importDepth,
dependencyCount: transitiveDeps.length,
dependencyList: transitiveDeps,
circularDeps,
cohesionScore,
domains: Array.from(
new Set(
node.exports.flatMap((e) => e.domains?.map((d) => d.domain) || [])
)
),
exportCount: node.exports.length,
contextBudget,
fragmentationScore,
relatedFiles: cluster ? cluster.files : [],
fileClassification,
severity,
issues,
recommendations: allRecommendations,
potentialSavings,
};
}
|