cli-node-graph 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (180) hide show
  1. package/README.md +69 -0
  2. package/dist/analysis/CircularDependencyAnalyzer.d.ts +13 -0
  3. package/dist/analysis/CircularDependencyAnalyzer.d.ts.map +1 -0
  4. package/dist/analysis/CircularDependencyAnalyzer.js +15 -0
  5. package/dist/analysis/CircularDependencyAnalyzer.js.map +1 -0
  6. package/dist/analysis/DeadCodeAnalyzer.d.ts +13 -0
  7. package/dist/analysis/DeadCodeAnalyzer.d.ts.map +1 -0
  8. package/dist/analysis/DeadCodeAnalyzer.js +37 -0
  9. package/dist/analysis/DeadCodeAnalyzer.js.map +1 -0
  10. package/dist/analysis/DependencyAnalyzer.d.ts +16 -0
  11. package/dist/analysis/DependencyAnalyzer.d.ts.map +1 -0
  12. package/dist/analysis/DependencyAnalyzer.js +26 -0
  13. package/dist/analysis/DependencyAnalyzer.js.map +1 -0
  14. package/dist/analysis/ImpactAnalyzer.d.ts +16 -0
  15. package/dist/analysis/ImpactAnalyzer.d.ts.map +1 -0
  16. package/dist/analysis/ImpactAnalyzer.js +26 -0
  17. package/dist/analysis/ImpactAnalyzer.js.map +1 -0
  18. package/dist/analysis/LayerViolationAnalyzer.d.ts +31 -0
  19. package/dist/analysis/LayerViolationAnalyzer.d.ts.map +1 -0
  20. package/dist/analysis/LayerViolationAnalyzer.js +71 -0
  21. package/dist/analysis/LayerViolationAnalyzer.js.map +1 -0
  22. package/dist/cli/ProjectLoader.d.ts +13 -0
  23. package/dist/cli/ProjectLoader.d.ts.map +1 -0
  24. package/dist/cli/ProjectLoader.js +48 -0
  25. package/dist/cli/ProjectLoader.js.map +1 -0
  26. package/dist/cli/index.d.ts +3 -0
  27. package/dist/cli/index.d.ts.map +1 -0
  28. package/dist/cli/index.js +139 -0
  29. package/dist/cli/index.js.map +1 -0
  30. package/dist/config/AnalysisConfig.d.ts +22 -0
  31. package/dist/config/AnalysisConfig.d.ts.map +1 -0
  32. package/dist/config/AnalysisConfig.js +6 -0
  33. package/dist/config/AnalysisConfig.js.map +1 -0
  34. package/dist/exporters/CytoscapeExporter.d.ts +18 -0
  35. package/dist/exporters/CytoscapeExporter.d.ts.map +1 -0
  36. package/dist/exporters/CytoscapeExporter.js +85 -0
  37. package/dist/exporters/CytoscapeExporter.js.map +1 -0
  38. package/dist/exporters/DotExporter.d.ts +13 -0
  39. package/dist/exporters/DotExporter.d.ts.map +1 -0
  40. package/dist/exporters/DotExporter.js +38 -0
  41. package/dist/exporters/DotExporter.js.map +1 -0
  42. package/dist/exporters/GraphExporter.d.ts +7 -0
  43. package/dist/exporters/GraphExporter.d.ts.map +1 -0
  44. package/dist/exporters/GraphExporter.js +2 -0
  45. package/dist/exporters/GraphExporter.js.map +1 -0
  46. package/dist/exporters/GraphMLExporter.d.ts +8 -0
  47. package/dist/exporters/GraphMLExporter.d.ts.map +1 -0
  48. package/dist/exporters/GraphMLExporter.js +30 -0
  49. package/dist/exporters/GraphMLExporter.js.map +1 -0
  50. package/dist/exporters/JsonExporter.d.ts +8 -0
  51. package/dist/exporters/JsonExporter.d.ts.map +1 -0
  52. package/dist/exporters/JsonExporter.js +16 -0
  53. package/dist/exporters/JsonExporter.js.map +1 -0
  54. package/dist/graph/EdgeFactory.d.ts +13 -0
  55. package/dist/graph/EdgeFactory.d.ts.map +1 -0
  56. package/dist/graph/EdgeFactory.js +15 -0
  57. package/dist/graph/EdgeFactory.js.map +1 -0
  58. package/dist/graph/Graph.d.ts +37 -0
  59. package/dist/graph/Graph.d.ts.map +1 -0
  60. package/dist/graph/Graph.js +137 -0
  61. package/dist/graph/Graph.js.map +1 -0
  62. package/dist/graph/GraphAlgorithms.d.ts +28 -0
  63. package/dist/graph/GraphAlgorithms.d.ts.map +1 -0
  64. package/dist/graph/GraphAlgorithms.js +233 -0
  65. package/dist/graph/GraphAlgorithms.js.map +1 -0
  66. package/dist/graph/GraphBuilder.d.ts +10 -0
  67. package/dist/graph/GraphBuilder.d.ts.map +1 -0
  68. package/dist/graph/GraphBuilder.js +71 -0
  69. package/dist/graph/GraphBuilder.js.map +1 -0
  70. package/dist/graph/NodeFactory.d.ts +21 -0
  71. package/dist/graph/NodeFactory.d.ts.map +1 -0
  72. package/dist/graph/NodeFactory.js +53 -0
  73. package/dist/graph/NodeFactory.js.map +1 -0
  74. package/dist/index.d.ts +35 -0
  75. package/dist/index.d.ts.map +1 -0
  76. package/dist/index.js +24 -0
  77. package/dist/index.js.map +1 -0
  78. package/dist/model/EdgeKind.d.ts +22 -0
  79. package/dist/model/EdgeKind.d.ts.map +1 -0
  80. package/dist/model/EdgeKind.js +23 -0
  81. package/dist/model/EdgeKind.js.map +1 -0
  82. package/dist/model/GraphEdge.d.ts +22 -0
  83. package/dist/model/GraphEdge.d.ts.map +1 -0
  84. package/dist/model/GraphEdge.js +2 -0
  85. package/dist/model/GraphEdge.js.map +1 -0
  86. package/dist/model/GraphNode.d.ts +22 -0
  87. package/dist/model/GraphNode.d.ts.map +1 -0
  88. package/dist/model/GraphNode.js +2 -0
  89. package/dist/model/GraphNode.js.map +1 -0
  90. package/dist/model/NodeKind.d.ts +21 -0
  91. package/dist/model/NodeKind.d.ts.map +1 -0
  92. package/dist/model/NodeKind.js +22 -0
  93. package/dist/model/NodeKind.js.map +1 -0
  94. package/dist/parser/ASTWalker.d.ts +21 -0
  95. package/dist/parser/ASTWalker.d.ts.map +1 -0
  96. package/dist/parser/ASTWalker.js +23 -0
  97. package/dist/parser/ASTWalker.js.map +1 -0
  98. package/dist/parser/ProgramFactory.d.ts +15 -0
  99. package/dist/parser/ProgramFactory.d.ts.map +1 -0
  100. package/dist/parser/ProgramFactory.js +65 -0
  101. package/dist/parser/ProgramFactory.js.map +1 -0
  102. package/dist/parser/visitors/CallVisitor.d.ts +17 -0
  103. package/dist/parser/visitors/CallVisitor.d.ts.map +1 -0
  104. package/dist/parser/visitors/CallVisitor.js +111 -0
  105. package/dist/parser/visitors/CallVisitor.js.map +1 -0
  106. package/dist/parser/visitors/ClassVisitor.d.ts +14 -0
  107. package/dist/parser/visitors/ClassVisitor.d.ts.map +1 -0
  108. package/dist/parser/visitors/ClassVisitor.js +87 -0
  109. package/dist/parser/visitors/ClassVisitor.js.map +1 -0
  110. package/dist/parser/visitors/DecoratorVisitor.d.ts +13 -0
  111. package/dist/parser/visitors/DecoratorVisitor.d.ts.map +1 -0
  112. package/dist/parser/visitors/DecoratorVisitor.js +65 -0
  113. package/dist/parser/visitors/DecoratorVisitor.js.map +1 -0
  114. package/dist/parser/visitors/EnumVisitor.d.ts +11 -0
  115. package/dist/parser/visitors/EnumVisitor.d.ts.map +1 -0
  116. package/dist/parser/visitors/EnumVisitor.js +26 -0
  117. package/dist/parser/visitors/EnumVisitor.js.map +1 -0
  118. package/dist/parser/visitors/ExportVisitor.d.ts +16 -0
  119. package/dist/parser/visitors/ExportVisitor.d.ts.map +1 -0
  120. package/dist/parser/visitors/ExportVisitor.js +95 -0
  121. package/dist/parser/visitors/ExportVisitor.js.map +1 -0
  122. package/dist/parser/visitors/FunctionVisitor.d.ts +14 -0
  123. package/dist/parser/visitors/FunctionVisitor.d.ts.map +1 -0
  124. package/dist/parser/visitors/FunctionVisitor.js +74 -0
  125. package/dist/parser/visitors/FunctionVisitor.js.map +1 -0
  126. package/dist/parser/visitors/HeritageVisitor.d.ts +14 -0
  127. package/dist/parser/visitors/HeritageVisitor.d.ts.map +1 -0
  128. package/dist/parser/visitors/HeritageVisitor.js +87 -0
  129. package/dist/parser/visitors/HeritageVisitor.js.map +1 -0
  130. package/dist/parser/visitors/ImportVisitor.d.ts +14 -0
  131. package/dist/parser/visitors/ImportVisitor.d.ts.map +1 -0
  132. package/dist/parser/visitors/ImportVisitor.js +96 -0
  133. package/dist/parser/visitors/ImportVisitor.js.map +1 -0
  134. package/dist/parser/visitors/InterfaceVisitor.d.ts +11 -0
  135. package/dist/parser/visitors/InterfaceVisitor.d.ts.map +1 -0
  136. package/dist/parser/visitors/InterfaceVisitor.js +28 -0
  137. package/dist/parser/visitors/InterfaceVisitor.js.map +1 -0
  138. package/dist/parser/visitors/MethodVisitor.d.ts +11 -0
  139. package/dist/parser/visitors/MethodVisitor.d.ts.map +1 -0
  140. package/dist/parser/visitors/MethodVisitor.js +30 -0
  141. package/dist/parser/visitors/MethodVisitor.js.map +1 -0
  142. package/dist/parser/visitors/TypeReferenceVisitor.d.ts +15 -0
  143. package/dist/parser/visitors/TypeReferenceVisitor.d.ts.map +1 -0
  144. package/dist/parser/visitors/TypeReferenceVisitor.js +85 -0
  145. package/dist/parser/visitors/TypeReferenceVisitor.js.map +1 -0
  146. package/dist/parser/visitors/VariableVisitor.d.ts +11 -0
  147. package/dist/parser/visitors/VariableVisitor.d.ts.map +1 -0
  148. package/dist/parser/visitors/VariableVisitor.js +27 -0
  149. package/dist/parser/visitors/VariableVisitor.js.map +1 -0
  150. package/dist/parser/visitors/context.d.ts +54 -0
  151. package/dist/parser/visitors/context.d.ts.map +1 -0
  152. package/dist/parser/visitors/context.js +117 -0
  153. package/dist/parser/visitors/context.js.map +1 -0
  154. package/dist/resolver/ModuleResolver.d.ts +16 -0
  155. package/dist/resolver/ModuleResolver.d.ts.map +1 -0
  156. package/dist/resolver/ModuleResolver.js +40 -0
  157. package/dist/resolver/ModuleResolver.js.map +1 -0
  158. package/dist/resolver/SymbolResolver.d.ts +15 -0
  159. package/dist/resolver/SymbolResolver.d.ts.map +1 -0
  160. package/dist/resolver/SymbolResolver.js +62 -0
  161. package/dist/resolver/SymbolResolver.js.map +1 -0
  162. package/dist/resolver/TypeResolver.d.ts +13 -0
  163. package/dist/resolver/TypeResolver.d.ts.map +1 -0
  164. package/dist/resolver/TypeResolver.js +32 -0
  165. package/dist/resolver/TypeResolver.js.map +1 -0
  166. package/dist/utils/cache.d.ts +12 -0
  167. package/dist/utils/cache.d.ts.map +1 -0
  168. package/dist/utils/cache.js +38 -0
  169. package/dist/utils/cache.js.map +1 -0
  170. package/dist/utils/id.d.ts +7 -0
  171. package/dist/utils/id.d.ts.map +1 -0
  172. package/dist/utils/id.js +15 -0
  173. package/dist/utils/id.js.map +1 -0
  174. package/dist/utils/path.d.ts +9 -0
  175. package/dist/utils/path.d.ts.map +1 -0
  176. package/dist/utils/path.js +18 -0
  177. package/dist/utils/path.js.map +1 -0
  178. package/docs/ARCHITECTURE.md +100 -0
  179. package/docs/CLI.md +62 -0
  180. package/package.json +58 -0
@@ -0,0 +1,22 @@
1
+ /** Analysis configuration options. */
2
+ export interface AnalysisConfig {
3
+ /** Root path of the project to analyze. */
4
+ projectRoot: string;
5
+ /** Path to tsconfig.json (relative to project root or absolute). */
6
+ tsconfigPath?: string;
7
+ /** Exclude patterns for source files. */
8
+ exclude?: string[];
9
+ /** Layer rules for layer violation analysis. */
10
+ layers?: LayerRule[];
11
+ /** Enable worker thread analysis (future). */
12
+ useWorkers?: boolean;
13
+ }
14
+ /** A layer rule defining allowed dependency direction. */
15
+ export interface LayerRule {
16
+ name: string;
17
+ pattern: string;
18
+ allowedImports?: string[];
19
+ }
20
+ /** Default analysis configuration. */
21
+ export declare const DEFAULT_CONFIG: Partial<AnalysisConfig>;
22
+ //# sourceMappingURL=AnalysisConfig.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AnalysisConfig.d.ts","sourceRoot":"","sources":["../../src/config/AnalysisConfig.ts"],"names":[],"mappings":"AAAA,sCAAsC;AACtC,MAAM,WAAW,cAAc;IAC7B,2CAA2C;IAC3C,WAAW,EAAE,MAAM,CAAC;IACpB,oEAAoE;IACpE,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,yCAAyC;IACzC,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,gDAAgD;IAChD,MAAM,CAAC,EAAE,SAAS,EAAE,CAAC;IACrB,8CAA8C;IAC9C,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,0DAA0D;AAC1D,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;CAC3B;AAED,sCAAsC;AACtC,eAAO,MAAM,cAAc,EAAE,OAAO,CAAC,cAAc,CAGlD,CAAC"}
@@ -0,0 +1,6 @@
1
+ /** Default analysis configuration. */
2
+ export const DEFAULT_CONFIG = {
3
+ tsconfigPath: 'tsconfig.json',
4
+ exclude: ['**/node_modules/**', '**/dist/**', '**/*.d.ts'],
5
+ };
6
+ //# sourceMappingURL=AnalysisConfig.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AnalysisConfig.js","sourceRoot":"","sources":["../../src/config/AnalysisConfig.ts"],"names":[],"mappings":"AAqBA,sCAAsC;AACtC,MAAM,CAAC,MAAM,cAAc,GAA4B;IACrD,YAAY,EAAE,eAAe;IAC7B,OAAO,EAAE,CAAC,oBAAoB,EAAE,YAAY,EAAE,WAAW,CAAC;CAC3D,CAAC"}
@@ -0,0 +1,18 @@
1
+ import type { Graph } from '../graph/Graph.js';
2
+ import type { GraphExporter } from './GraphExporter.js';
3
+ /** Exports graph as Cytoscape.js JSON. */
4
+ export declare class CytoscapeExporter implements GraphExporter {
5
+ readonly format = "cytoscape";
6
+ export(graph: Graph): string;
7
+ }
8
+ /** Exports graph as React Flow JSON. */
9
+ export declare class ReactFlowExporter implements GraphExporter {
10
+ readonly format = "reactflow";
11
+ export(graph: Graph): string;
12
+ }
13
+ /** Exports graph as Neo4j CSV (nodes + relationships). */
14
+ export declare class Neo4jExporter implements GraphExporter {
15
+ readonly format = "neo4j";
16
+ export(graph: Graph): string;
17
+ }
18
+ //# sourceMappingURL=CytoscapeExporter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CytoscapeExporter.d.ts","sourceRoot":"","sources":["../../src/exporters/CytoscapeExporter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAExD,0CAA0C;AAC1C,qBAAa,iBAAkB,YAAW,aAAa;IACrD,QAAQ,CAAC,MAAM,eAAe;IAE9B,MAAM,CAAC,KAAK,EAAE,KAAK,GAAG,MAAM;CAkC7B;AAED,wCAAwC;AACxC,qBAAa,iBAAkB,YAAW,aAAa;IACrD,QAAQ,CAAC,MAAM,eAAe;IAE9B,MAAM,CAAC,KAAK,EAAE,KAAK,GAAG,MAAM;CAwB7B;AAED,0DAA0D;AAC1D,qBAAa,aAAc,YAAW,aAAa;IACjD,QAAQ,CAAC,MAAM,WAAW;IAE1B,MAAM,CAAC,KAAK,EAAE,KAAK,GAAG,MAAM;CAkB7B"}
@@ -0,0 +1,85 @@
1
+ /** Exports graph as Cytoscape.js JSON. */
2
+ export class CytoscapeExporter {
3
+ format = 'cytoscape';
4
+ export(graph) {
5
+ const elements = [
6
+ {
7
+ data: {
8
+ id: '__graph__',
9
+ label: 'cli-node-graph',
10
+ kind: 'Graph',
11
+ },
12
+ group: 'nodes',
13
+ },
14
+ ...graph.getNodes().map((node) => ({
15
+ data: {
16
+ id: node.id,
17
+ label: node.label,
18
+ kind: node.kind,
19
+ file: node.file,
20
+ ...node.metadata,
21
+ },
22
+ group: 'nodes',
23
+ })),
24
+ ...graph.getEdges().map((edge) => ({
25
+ data: {
26
+ id: edge.id,
27
+ source: edge.source,
28
+ target: edge.target,
29
+ kind: edge.kind,
30
+ ...edge.metadata,
31
+ },
32
+ group: 'edges',
33
+ })),
34
+ ];
35
+ return JSON.stringify({ elements }, null, 2);
36
+ }
37
+ }
38
+ /** Exports graph as React Flow JSON. */
39
+ export class ReactFlowExporter {
40
+ format = 'reactflow';
41
+ export(graph) {
42
+ const nodes = graph.getNodes().map((node, index) => ({
43
+ id: node.id,
44
+ type: 'default',
45
+ position: { x: (index % 20) * 200, y: Math.floor(index / 20) * 100 },
46
+ data: {
47
+ label: node.label,
48
+ kind: node.kind,
49
+ file: node.file,
50
+ line: node.line,
51
+ metadata: node.metadata,
52
+ },
53
+ }));
54
+ const edges = graph.getEdges().map((edge) => ({
55
+ id: edge.id,
56
+ source: edge.source,
57
+ target: edge.target,
58
+ label: edge.kind,
59
+ data: edge.metadata,
60
+ }));
61
+ return JSON.stringify({ nodes, edges }, null, 2);
62
+ }
63
+ }
64
+ /** Exports graph as Neo4j CSV (nodes + relationships). */
65
+ export class Neo4jExporter {
66
+ format = 'neo4j';
67
+ export(graph) {
68
+ const nodeLines = [
69
+ 'id:ID,label,kind,file,line,:LABEL',
70
+ ...graph.getNodes().map((n) => `${csvEscape(n.id)},${csvEscape(n.label)},${csvEscape(n.kind)},${csvEscape(n.file ?? '')},${n.line ?? ''},Node`),
71
+ ];
72
+ const edgeLines = [
73
+ ':START_ID,:END_ID,kind,:TYPE',
74
+ ...graph.getEdges().map((e) => `${csvEscape(e.source)},${csvEscape(e.target)},${csvEscape(e.kind)},${e.kind}`),
75
+ ];
76
+ return `# Nodes\n${nodeLines.join('\n')}\n\n# Relationships\n${edgeLines.join('\n')}`;
77
+ }
78
+ }
79
+ function csvEscape(value) {
80
+ if (value.includes(',') || value.includes('"')) {
81
+ return `"${value.replace(/"/g, '""')}"`;
82
+ }
83
+ return value;
84
+ }
85
+ //# sourceMappingURL=CytoscapeExporter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CytoscapeExporter.js","sourceRoot":"","sources":["../../src/exporters/CytoscapeExporter.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ import type { Graph } from '../graph/Graph.js';
2
+ import type { GraphExporter } from './GraphExporter.js';
3
+ /** Exports graph as Graphviz DOT format. */
4
+ export declare class DotExporter implements GraphExporter {
5
+ readonly format = "dot";
6
+ export(graph: Graph): string;
7
+ }
8
+ /** Exports graph as Mermaid diagram. */
9
+ export declare class MermaidExporter implements GraphExporter {
10
+ readonly format = "mermaid";
11
+ export(graph: Graph): string;
12
+ }
13
+ //# sourceMappingURL=DotExporter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DotExporter.d.ts","sourceRoot":"","sources":["../../src/exporters/DotExporter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAExD,4CAA4C;AAC5C,qBAAa,WAAY,YAAW,aAAa;IAC/C,QAAQ,CAAC,MAAM,SAAS;IAExB,MAAM,CAAC,KAAK,EAAE,KAAK,GAAG,MAAM;CAe7B;AAED,wCAAwC;AACxC,qBAAa,eAAgB,YAAW,aAAa;IACnD,QAAQ,CAAC,MAAM,aAAa;IAE5B,MAAM,CAAC,KAAK,EAAE,KAAK,GAAG,MAAM;CAoB7B"}
@@ -0,0 +1,38 @@
1
+ /** Exports graph as Graphviz DOT format. */
2
+ export class DotExporter {
3
+ format = 'dot';
4
+ export(graph) {
5
+ const lines = ['digraph cli-node-graph {', ' rankdir=LR;', ' node [shape=box];'];
6
+ for (const node of graph.getNodes()) {
7
+ const label = `${node.label}\\n(${node.kind})`;
8
+ lines.push(` "${node.id}" [label="${label}"];`);
9
+ }
10
+ for (const edge of graph.getEdges()) {
11
+ lines.push(` "${edge.source}" -> "${edge.target}" [label="${edge.kind}"];`);
12
+ }
13
+ lines.push('}');
14
+ return lines.join('\n');
15
+ }
16
+ }
17
+ /** Exports graph as Mermaid diagram. */
18
+ export class MermaidExporter {
19
+ format = 'mermaid';
20
+ export(graph) {
21
+ const lines = ['graph LR'];
22
+ const nodeIds = new Map();
23
+ graph.getNodes().forEach((node, i) => {
24
+ const shortId = `N${String(i)}`;
25
+ nodeIds.set(node.id, shortId);
26
+ lines.push(` ${shortId}["${node.label}<br/>${node.kind}"]`);
27
+ });
28
+ for (const edge of graph.getEdges()) {
29
+ const src = nodeIds.get(edge.source);
30
+ const tgt = nodeIds.get(edge.target);
31
+ if (src && tgt) {
32
+ lines.push(` ${src} -->|${edge.kind}| ${tgt}`);
33
+ }
34
+ }
35
+ return lines.join('\n');
36
+ }
37
+ }
38
+ //# sourceMappingURL=DotExporter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DotExporter.js","sourceRoot":"","sources":["../../src/exporters/DotExporter.ts"],"names":[],"mappings":"AAGA,4CAA4C;AAC5C,MAAM,OAAO,WAAW;IACb,MAAM,GAAG,KAAK,CAAC;IAExB,MAAM,CAAC,KAAY;QACjB,MAAM,KAAK,GAAa,CAAC,0BAA0B,EAAE,eAAe,EAAE,qBAAqB,CAAC,CAAC;QAE7F,KAAK,MAAM,IAAI,IAAI,KAAK,CAAC,QAAQ,EAAE,EAAE,CAAC;YACpC,MAAM,KAAK,GAAG,GAAG,IAAI,CAAC,KAAK,OAAO,IAAI,CAAC,IAAI,GAAG,CAAC;YAC/C,KAAK,CAAC,IAAI,CAAC,MAAM,IAAI,CAAC,EAAE,aAAa,KAAK,KAAK,CAAC,CAAC;QACnD,CAAC;QAED,KAAK,MAAM,IAAI,IAAI,KAAK,CAAC,QAAQ,EAAE,EAAE,CAAC;YACpC,KAAK,CAAC,IAAI,CAAC,MAAM,IAAI,CAAC,MAAM,SAAS,IAAI,CAAC,MAAM,aAAa,IAAI,CAAC,IAAI,KAAK,CAAC,CAAC;QAC/E,CAAC;QAED,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAChB,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC1B,CAAC;CACF;AAED,wCAAwC;AACxC,MAAM,OAAO,eAAe;IACjB,MAAM,GAAG,SAAS,CAAC;IAE5B,MAAM,CAAC,KAAY;QACjB,MAAM,KAAK,GAAa,CAAC,UAAU,CAAC,CAAC;QACrC,MAAM,OAAO,GAAG,IAAI,GAAG,EAAkB,CAAC;QAE1C,KAAK,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE,EAAE;YACnC,MAAM,OAAO,GAAG,IAAI,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC;YAChC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,EAAE,OAAO,CAAC,CAAC;YAC9B,KAAK,CAAC,IAAI,CAAC,KAAK,OAAO,KAAK,IAAI,CAAC,KAAK,QAAQ,IAAI,CAAC,IAAI,IAAI,CAAC,CAAC;QAC/D,CAAC,CAAC,CAAC;QAEH,KAAK,MAAM,IAAI,IAAI,KAAK,CAAC,QAAQ,EAAE,EAAE,CAAC;YACpC,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YACrC,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YACrC,IAAI,GAAG,IAAI,GAAG,EAAE,CAAC;gBACf,KAAK,CAAC,IAAI,CAAC,KAAK,GAAG,QAAQ,IAAI,CAAC,IAAI,KAAK,GAAG,EAAE,CAAC,CAAC;YAClD,CAAC;QACH,CAAC;QAED,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC1B,CAAC;CACF"}
@@ -0,0 +1,7 @@
1
+ import type { Graph } from '../graph/Graph.js';
2
+ /** Exports a graph to a specific format. */
3
+ export interface GraphExporter {
4
+ readonly format: string;
5
+ export(graph: Graph): string;
6
+ }
7
+ //# sourceMappingURL=GraphExporter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"GraphExporter.d.ts","sourceRoot":"","sources":["../../src/exporters/GraphExporter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAE/C,4CAA4C;AAC5C,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,MAAM,CAAC,KAAK,EAAE,KAAK,GAAG,MAAM,CAAC;CAC9B"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=GraphExporter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"GraphExporter.js","sourceRoot":"","sources":["../../src/exporters/GraphExporter.ts"],"names":[],"mappings":""}
@@ -0,0 +1,8 @@
1
+ import type { Graph } from '../graph/Graph.js';
2
+ import type { GraphExporter } from './GraphExporter.js';
3
+ /** Exports graph as GraphML XML. */
4
+ export declare class GraphMLExporter implements GraphExporter {
5
+ readonly format = "graphml";
6
+ export(graph: Graph): string;
7
+ }
8
+ //# sourceMappingURL=GraphMLExporter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"GraphMLExporter.d.ts","sourceRoot":"","sources":["../../src/exporters/GraphMLExporter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAExD,oCAAoC;AACpC,qBAAa,eAAgB,YAAW,aAAa;IACnD,QAAQ,CAAC,MAAM,aAAa;IAE5B,MAAM,CAAC,KAAK,EAAE,KAAK,GAAG,MAAM;CA8B7B"}
@@ -0,0 +1,30 @@
1
+ /** Exports graph as GraphML XML. */
2
+ export class GraphMLExporter {
3
+ format = 'graphml';
4
+ export(graph) {
5
+ const lines = [
6
+ '<?xml version="1.0" encoding="UTF-8"?>',
7
+ '<graphml xmlns="http://graphml.graphdrawing.org/xmlns">',
8
+ ' <key id="label" for="node" attr.name="label" attr.type="string"/>',
9
+ ' <key id="kind" for="node" attr.name="kind" attr.type="string"/>',
10
+ ' <key id="edgeKind" for="edge" attr.name="kind" attr.type="string"/>',
11
+ ' <graph id="G" edgedefault="directed">',
12
+ ];
13
+ for (const node of graph.getNodes()) {
14
+ lines.push(` <node id="${escapeXml(node.id)}">`, ` <data key="label">${escapeXml(node.label)}</data>`, ` <data key="kind">${escapeXml(node.kind)}</data>`, ' </node>');
15
+ }
16
+ for (const edge of graph.getEdges()) {
17
+ lines.push(` <edge source="${escapeXml(edge.source)}" target="${escapeXml(edge.target)}">`, ` <data key="edgeKind">${escapeXml(edge.kind)}</data>`, ' </edge>');
18
+ }
19
+ lines.push(' </graph>', '</graphml>');
20
+ return lines.join('\n');
21
+ }
22
+ }
23
+ function escapeXml(str) {
24
+ return str
25
+ .replace(/&/g, '&amp;')
26
+ .replace(/</g, '&lt;')
27
+ .replace(/>/g, '&gt;')
28
+ .replace(/"/g, '&quot;');
29
+ }
30
+ //# sourceMappingURL=GraphMLExporter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"GraphMLExporter.js","sourceRoot":"","sources":["../../src/exporters/GraphMLExporter.ts"],"names":[],"mappings":"AAGA,oCAAoC;AACpC,MAAM,OAAO,eAAe;IACjB,MAAM,GAAG,SAAS,CAAC;IAE5B,MAAM,CAAC,KAAY;QACjB,MAAM,KAAK,GAAa;YACtB,wCAAwC;YACxC,yDAAyD;YACzD,qEAAqE;YACrE,mEAAmE;YACnE,uEAAuE;YACvE,yCAAyC;SAC1C,CAAC;QAEF,KAAK,MAAM,IAAI,IAAI,KAAK,CAAC,QAAQ,EAAE,EAAE,CAAC;YACpC,KAAK,CAAC,IAAI,CACR,iBAAiB,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,EACvC,2BAA2B,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,SAAS,EACzD,0BAA0B,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,EACvD,aAAa,CACd,CAAC;QACJ,CAAC;QAED,KAAK,MAAM,IAAI,IAAI,KAAK,CAAC,QAAQ,EAAE,EAAE,CAAC;YACpC,KAAK,CAAC,IAAI,CACR,qBAAqB,SAAS,CAAC,IAAI,CAAC,MAAM,CAAC,aAAa,SAAS,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,EAClF,8BAA8B,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,EAC3D,aAAa,CACd,CAAC;QACJ,CAAC;QAED,KAAK,CAAC,IAAI,CAAC,YAAY,EAAE,YAAY,CAAC,CAAC;QACvC,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC1B,CAAC;CACF;AAED,SAAS,SAAS,CAAC,GAAW;IAC5B,OAAO,GAAG;SACP,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC;SACtB,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC;SACrB,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC;SACrB,OAAO,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;AAC7B,CAAC"}
@@ -0,0 +1,8 @@
1
+ import type { Graph } from '../graph/Graph.js';
2
+ import type { GraphExporter } from './GraphExporter.js';
3
+ /** Exports graph as JSON. */
4
+ export declare class JsonExporter implements GraphExporter {
5
+ readonly format = "json";
6
+ export(graph: Graph): string;
7
+ }
8
+ //# sourceMappingURL=JsonExporter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"JsonExporter.d.ts","sourceRoot":"","sources":["../../src/exporters/JsonExporter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAExD,6BAA6B;AAC7B,qBAAa,YAAa,YAAW,aAAa;IAChD,QAAQ,CAAC,MAAM,UAAU;IAEzB,MAAM,CAAC,KAAK,EAAE,KAAK,GAAG,MAAM;CAe7B"}
@@ -0,0 +1,16 @@
1
+ /** Exports graph as JSON. */
2
+ export class JsonExporter {
3
+ format = 'json';
4
+ export(graph) {
5
+ return JSON.stringify({
6
+ nodes: graph.getNodes(),
7
+ edges: graph.getEdges(),
8
+ meta: {
9
+ nodeCount: graph.nodeCount,
10
+ edgeCount: graph.edgeCount,
11
+ exportedAt: new Date().toISOString(),
12
+ },
13
+ }, null, 2);
14
+ }
15
+ }
16
+ //# sourceMappingURL=JsonExporter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"JsonExporter.js","sourceRoot":"","sources":["../../src/exporters/JsonExporter.ts"],"names":[],"mappings":"AAGA,6BAA6B;AAC7B,MAAM,OAAO,YAAY;IACd,MAAM,GAAG,MAAM,CAAC;IAEzB,MAAM,CAAC,KAAY;QACjB,OAAO,IAAI,CAAC,SAAS,CACnB;YACE,KAAK,EAAE,KAAK,CAAC,QAAQ,EAAE;YACvB,KAAK,EAAE,KAAK,CAAC,QAAQ,EAAE;YACvB,IAAI,EAAE;gBACJ,SAAS,EAAE,KAAK,CAAC,SAAS;gBAC1B,SAAS,EAAE,KAAK,CAAC,SAAS;gBAC1B,UAAU,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;aACrC;SACF,EACD,IAAI,EACJ,CAAC,CACF,CAAC;IACJ,CAAC;CACF"}
@@ -0,0 +1,13 @@
1
+ import type { EdgeKind } from '../model/EdgeKind.js';
2
+ import type { EdgeMetadata, GraphEdge } from '../model/GraphEdge.js';
3
+ /** Factory for creating consistently structured graph edges. */
4
+ export declare class EdgeFactory {
5
+ create(params: {
6
+ source: string;
7
+ target: string;
8
+ kind: EdgeKind;
9
+ metadata?: EdgeMetadata;
10
+ idOverride?: string;
11
+ }): GraphEdge;
12
+ }
13
+ //# sourceMappingURL=EdgeFactory.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"EdgeFactory.d.ts","sourceRoot":"","sources":["../../src/graph/EdgeFactory.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,KAAK,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAGrE,gEAAgE;AAChE,qBAAa,WAAW;IACtB,MAAM,CAAC,MAAM,EAAE;QACb,MAAM,EAAE,MAAM,CAAC;QACf,MAAM,EAAE,MAAM,CAAC;QACf,IAAI,EAAE,QAAQ,CAAC;QACf,QAAQ,CAAC,EAAE,YAAY,CAAC;QACxB,UAAU,CAAC,EAAE,MAAM,CAAC;KACrB,GAAG,SAAS;CAYd"}
@@ -0,0 +1,15 @@
1
+ import { edgeId } from '../utils/id.js';
2
+ /** Factory for creating consistently structured graph edges. */
3
+ export class EdgeFactory {
4
+ create(params) {
5
+ const id = params.idOverride ?? edgeId(params.source, params.target, params.kind);
6
+ return {
7
+ id,
8
+ source: params.source,
9
+ target: params.target,
10
+ kind: params.kind,
11
+ metadata: params.metadata ?? {},
12
+ };
13
+ }
14
+ }
15
+ //# sourceMappingURL=EdgeFactory.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"EdgeFactory.js","sourceRoot":"","sources":["../../src/graph/EdgeFactory.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAC;AAExC,gEAAgE;AAChE,MAAM,OAAO,WAAW;IACtB,MAAM,CAAC,MAMN;QACC,MAAM,EAAE,GACN,MAAM,CAAC,UAAU,IAAI,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC;QAEzE,OAAO;YACL,EAAE;YACF,MAAM,EAAE,MAAM,CAAC,MAAM;YACrB,MAAM,EAAE,MAAM,CAAC,MAAM;YACrB,IAAI,EAAE,MAAM,CAAC,IAAI;YACjB,QAAQ,EAAE,MAAM,CAAC,QAAQ,IAAI,EAAE;SAChC,CAAC;IACJ,CAAC;CACF"}
@@ -0,0 +1,37 @@
1
+ import type { GraphEdge } from '../model/GraphEdge.js';
2
+ import type { GraphNode } from '../model/GraphNode.js';
3
+ import type { EdgeKind } from '../model/EdgeKind.js';
4
+ import type { NodeKind } from '../model/NodeKind.js';
5
+ /** In-memory graph database with indexed lookups. */
6
+ export declare class Graph {
7
+ private readonly nodes;
8
+ private readonly edges;
9
+ private readonly nodesByKind;
10
+ private readonly edgesByKind;
11
+ private readonly outgoing;
12
+ private readonly incoming;
13
+ private readonly nodesByFile;
14
+ /** Add or replace a node. */
15
+ addNode(node: GraphNode): void;
16
+ /** Add an edge if it does not already exist. */
17
+ addEdge(edge: GraphEdge): void;
18
+ getNode(id: string): GraphNode | undefined;
19
+ getEdge(id: string): GraphEdge | undefined;
20
+ getNodes(): GraphNode[];
21
+ getEdges(): GraphEdge[];
22
+ getNodesByKind(kind: NodeKind): GraphNode[];
23
+ getEdgesByKind(kind: EdgeKind): GraphEdge[];
24
+ getNodesByFile(file: string): GraphNode[];
25
+ getOutgoingEdges(nodeId: string): GraphEdge[];
26
+ getIncomingEdges(nodeId: string): GraphEdge[];
27
+ get nodeCount(): number;
28
+ get edgeCount(): number;
29
+ /** Create a shallow copy of the graph. */
30
+ clone(): Graph;
31
+ /** Filter graph to a subset of nodes and their connecting edges. */
32
+ filter(nodeIds: Set<string>): Graph;
33
+ private indexNodeByKind;
34
+ private indexEdgeByKind;
35
+ private indexAdjacency;
36
+ }
37
+ //# sourceMappingURL=Graph.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Graph.d.ts","sourceRoot":"","sources":["../../src/graph/Graph.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAErD,qDAAqD;AACrD,qBAAa,KAAK;IAChB,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAgC;IACtD,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAgC;IACtD,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAoC;IAChE,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAoC;IAChE,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAkC;IAC3D,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAkC;IAC3D,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAkC;IAE9D,6BAA6B;IAC7B,OAAO,CAAC,IAAI,EAAE,SAAS,GAAG,IAAI;IAa9B,gDAAgD;IAChD,OAAO,CAAC,IAAI,EAAE,SAAS,GAAG,IAAI;IAS9B,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,SAAS,GAAG,SAAS;IAI1C,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,SAAS,GAAG,SAAS;IAI1C,QAAQ,IAAI,SAAS,EAAE;IAIvB,QAAQ,IAAI,SAAS,EAAE;IAIvB,cAAc,CAAC,IAAI,EAAE,QAAQ,GAAG,SAAS,EAAE;IAM3C,cAAc,CAAC,IAAI,EAAE,QAAQ,GAAG,SAAS,EAAE;IAM3C,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,EAAE;IAMzC,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,EAAE;IAM7C,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,EAAE;IAM7C,IAAI,SAAS,IAAI,MAAM,CAEtB;IAED,IAAI,SAAS,IAAI,MAAM,CAEtB;IAED,0CAA0C;IAC1C,KAAK,IAAI,KAAK;IAWd,oEAAoE;IACpE,MAAM,CAAC,OAAO,EAAE,GAAG,CAAC,MAAM,CAAC,GAAG,KAAK;IAcnC,OAAO,CAAC,eAAe;IASvB,OAAO,CAAC,eAAe;IASvB,OAAO,CAAC,cAAc;CAevB"}
@@ -0,0 +1,137 @@
1
+ /** In-memory graph database with indexed lookups. */
2
+ export class Graph {
3
+ nodes = new Map();
4
+ edges = new Map();
5
+ nodesByKind = new Map();
6
+ edgesByKind = new Map();
7
+ outgoing = new Map();
8
+ incoming = new Map();
9
+ nodesByFile = new Map();
10
+ /** Add or replace a node. */
11
+ addNode(node) {
12
+ this.nodes.set(node.id, node);
13
+ this.indexNodeByKind(node);
14
+ if (node.file) {
15
+ let fileSet = this.nodesByFile.get(node.file);
16
+ if (!fileSet) {
17
+ fileSet = new Set();
18
+ this.nodesByFile.set(node.file, fileSet);
19
+ }
20
+ fileSet.add(node.id);
21
+ }
22
+ }
23
+ /** Add an edge if it does not already exist. */
24
+ addEdge(edge) {
25
+ if (this.edges.has(edge.id)) {
26
+ return;
27
+ }
28
+ this.edges.set(edge.id, edge);
29
+ this.indexEdgeByKind(edge);
30
+ this.indexAdjacency(edge);
31
+ }
32
+ getNode(id) {
33
+ return this.nodes.get(id);
34
+ }
35
+ getEdge(id) {
36
+ return this.edges.get(id);
37
+ }
38
+ getNodes() {
39
+ return [...this.nodes.values()];
40
+ }
41
+ getEdges() {
42
+ return [...this.edges.values()];
43
+ }
44
+ getNodesByKind(kind) {
45
+ const ids = this.nodesByKind.get(kind);
46
+ if (!ids)
47
+ return [];
48
+ return [...ids].map((id) => this.nodes.get(id)).filter((n) => n !== undefined);
49
+ }
50
+ getEdgesByKind(kind) {
51
+ const ids = this.edgesByKind.get(kind);
52
+ if (!ids)
53
+ return [];
54
+ return [...ids].map((id) => this.edges.get(id)).filter((e) => e !== undefined);
55
+ }
56
+ getNodesByFile(file) {
57
+ const ids = this.nodesByFile.get(file);
58
+ if (!ids)
59
+ return [];
60
+ return [...ids].map((id) => this.nodes.get(id)).filter((n) => n !== undefined);
61
+ }
62
+ getOutgoingEdges(nodeId) {
63
+ const ids = this.outgoing.get(nodeId);
64
+ if (!ids)
65
+ return [];
66
+ return [...ids].map((id) => this.edges.get(id)).filter((e) => e !== undefined);
67
+ }
68
+ getIncomingEdges(nodeId) {
69
+ const ids = this.incoming.get(nodeId);
70
+ if (!ids)
71
+ return [];
72
+ return [...ids].map((id) => this.edges.get(id)).filter((e) => e !== undefined);
73
+ }
74
+ get nodeCount() {
75
+ return this.nodes.size;
76
+ }
77
+ get edgeCount() {
78
+ return this.edges.size;
79
+ }
80
+ /** Create a shallow copy of the graph. */
81
+ clone() {
82
+ const copy = new Graph();
83
+ for (const node of this.nodes.values()) {
84
+ copy.addNode({ ...node, metadata: { ...node.metadata } });
85
+ }
86
+ for (const edge of this.edges.values()) {
87
+ copy.addEdge({ ...edge, metadata: { ...edge.metadata } });
88
+ }
89
+ return copy;
90
+ }
91
+ /** Filter graph to a subset of nodes and their connecting edges. */
92
+ filter(nodeIds) {
93
+ const filtered = new Graph();
94
+ for (const id of nodeIds) {
95
+ const node = this.nodes.get(id);
96
+ if (node)
97
+ filtered.addNode(node);
98
+ }
99
+ for (const edge of this.edges.values()) {
100
+ if (nodeIds.has(edge.source) && nodeIds.has(edge.target)) {
101
+ filtered.addEdge(edge);
102
+ }
103
+ }
104
+ return filtered;
105
+ }
106
+ indexNodeByKind(node) {
107
+ let set = this.nodesByKind.get(node.kind);
108
+ if (!set) {
109
+ set = new Set();
110
+ this.nodesByKind.set(node.kind, set);
111
+ }
112
+ set.add(node.id);
113
+ }
114
+ indexEdgeByKind(edge) {
115
+ let set = this.edgesByKind.get(edge.kind);
116
+ if (!set) {
117
+ set = new Set();
118
+ this.edgesByKind.set(edge.kind, set);
119
+ }
120
+ set.add(edge.id);
121
+ }
122
+ indexAdjacency(edge) {
123
+ let outSet = this.outgoing.get(edge.source);
124
+ if (!outSet) {
125
+ outSet = new Set();
126
+ this.outgoing.set(edge.source, outSet);
127
+ }
128
+ outSet.add(edge.id);
129
+ let inSet = this.incoming.get(edge.target);
130
+ if (!inSet) {
131
+ inSet = new Set();
132
+ this.incoming.set(edge.target, inSet);
133
+ }
134
+ inSet.add(edge.id);
135
+ }
136
+ }
137
+ //# sourceMappingURL=Graph.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Graph.js","sourceRoot":"","sources":["../../src/graph/Graph.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,28 @@
1
+ import type { Graph } from './Graph.js';
2
+ /** Graph algorithms for dependency analysis. */
3
+ export declare class GraphAlgorithms {
4
+ private readonly graph;
5
+ constructor(graph: Graph);
6
+ /** Kahn's algorithm topological sort. Returns empty if cycles exist. */
7
+ topologicalSort(nodeIds?: string[]): string[];
8
+ /** Tarjan's algorithm for strongly connected components. */
9
+ stronglyConnectedComponents(nodeIds?: string[]): string[][];
10
+ /** Detect all cycles (SCCs with more than one node or self-loops). */
11
+ detectCycles(): string[][];
12
+ /** BFS shortest path between two nodes. */
13
+ shortestPath(from: string, to: string): string[] | null;
14
+ /** Maximum dependency depth from a node. */
15
+ dependencyDepth(nodeId: string): number;
16
+ /** Get all nodes reachable downstream from a starting node. */
17
+ downstream(nodeId: string): Set<string>;
18
+ /** Get all nodes that depend on a given node (reverse lookup). */
19
+ reverseDependencies(nodeId: string): Set<string>;
20
+ /** Expand neighborhood to N hops. */
21
+ neighborhood(nodeId: string, hops: number): Set<string>;
22
+ /** Compute transitive closure for dependency edges. */
23
+ transitiveClosure(nodeIds: string[]): Set<string>;
24
+ private downstreamFromAdjacency;
25
+ private buildAdjacencyList;
26
+ private isDependencyEdge;
27
+ }
28
+ //# sourceMappingURL=GraphAlgorithms.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"GraphAlgorithms.d.ts","sourceRoot":"","sources":["../../src/graph/GraphAlgorithms.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAGxC,gDAAgD;AAChD,qBAAa,eAAe;IACd,OAAO,CAAC,QAAQ,CAAC,KAAK;gBAAL,KAAK,EAAE,KAAK;IAEzC,wEAAwE;IACxE,eAAe,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE;IAmC7C,4DAA4D;IAC5D,2BAA2B,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,EAAE;IA8C3D,sEAAsE;IACtE,YAAY,IAAI,MAAM,EAAE,EAAE;IAU1B,2CAA2C;IAC3C,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,IAAI;IAmBvD,4CAA4C;IAC5C,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM;IAoBvC,+DAA+D;IAC/D,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC;IAiBvC,kEAAkE;IAClE,mBAAmB,CAAC,MAAM,EAAE,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC;IAiBhD,qCAAqC;IACrC,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC;IAoBvD,uDAAuD;IACvD,iBAAiB,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,GAAG,CAAC,MAAM,CAAC;IAcjD,OAAO,CAAC,uBAAuB;IAe/B,OAAO,CAAC,kBAAkB;IAe1B,OAAO,CAAC,gBAAgB;CASzB"}