@teambit/graph 0.0.0-351b8797f220d8d6c242cfc30d4ecebaee07da45
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.
- package/component-graph/component-graph.ts +118 -0
- package/component-graph/index.ts +2 -0
- package/dist/component-graph/component-graph.d.ts +22 -0
- package/dist/component-graph/component-graph.js +125 -0
- package/dist/component-graph/component-graph.js.map +1 -0
- package/dist/component-graph/index.d.ts +1 -0
- package/dist/component-graph/index.js +20 -0
- package/dist/component-graph/index.js.map +1 -0
- package/dist/component-id-graph.d.ts +49 -0
- package/dist/component-id-graph.js +252 -0
- package/dist/component-id-graph.js.map +1 -0
- package/dist/duplicate-dependency.d.ts +11 -0
- package/dist/duplicate-dependency.js +22 -0
- package/dist/duplicate-dependency.js.map +1 -0
- package/dist/edge-type.d.ts +5 -0
- package/dist/edge-type.js +14 -0
- package/dist/edge-type.js.map +1 -0
- package/dist/esm.mjs +29 -0
- package/dist/graph-builder.d.ts +16 -0
- package/dist/graph-builder.js +71 -0
- package/dist/graph-builder.js.map +1 -0
- package/dist/graph-cmd.d.ts +28 -0
- package/dist/graph-cmd.js +147 -0
- package/dist/graph-cmd.js.map +1 -0
- package/dist/graph.aspect.d.ts +3 -0
- package/dist/graph.aspect.js +21 -0
- package/dist/graph.aspect.js.map +1 -0
- package/dist/graph.compare.section.d.ts +20 -0
- package/dist/graph.compare.section.js +50 -0
- package/dist/graph.compare.section.js.map +1 -0
- package/dist/graph.composition.d.ts +1 -0
- package/dist/graph.composition.js +29 -0
- package/dist/graph.composition.js.map +1 -0
- package/dist/graph.docs.md +4 -0
- package/dist/graph.graphql.d.ts +4 -0
- package/dist/graph.graphql.js +95 -0
- package/dist/graph.graphql.js.map +1 -0
- package/dist/graph.main.runtime.d.ts +34 -0
- package/dist/graph.main.runtime.js +158 -0
- package/dist/graph.main.runtime.js.map +1 -0
- package/dist/graph.ui.runtime.d.ts +33 -0
- package/dist/graph.ui.runtime.js +104 -0
- package/dist/graph.ui.runtime.js.map +1 -0
- package/dist/index.d.ts +17 -0
- package/dist/index.js +214 -0
- package/dist/index.js.map +1 -0
- package/dist/model/dependency/dependency.d.ts +6 -0
- package/dist/model/dependency/dependency.js +21 -0
- package/dist/model/dependency/dependency.js.map +1 -0
- package/dist/model/dependency/index.d.ts +1 -0
- package/dist/model/dependency/index.js +26 -0
- package/dist/model/dependency/index.js.map +1 -0
- package/dist/model/graph-filters/graph-filters.d.ts +1 -0
- package/dist/model/graph-filters/graph-filters.js +3 -0
- package/dist/model/graph-filters/graph-filters.js.map +1 -0
- package/dist/model/graph-filters/index.d.ts +1 -0
- package/dist/model/graph-filters/index.js +3 -0
- package/dist/model/graph-filters/index.js.map +1 -0
- package/dist/preview-1752263259534.js +7 -0
- package/dist/ui/component-node/component-node.d.ts +7 -0
- package/dist/ui/component-node/component-node.js +158 -0
- package/dist/ui/component-node/component-node.js.map +1 -0
- package/dist/ui/component-node/component-node.module.scss +73 -0
- package/dist/ui/component-node/index.d.ts +13 -0
- package/dist/ui/component-node/index.js +94 -0
- package/dist/ui/component-node/index.js.map +1 -0
- package/dist/ui/component-node/variants.d.ts +2 -0
- package/dist/ui/component-node/variants.js +30 -0
- package/dist/ui/component-node/variants.js.map +1 -0
- package/dist/ui/component-node/variants.module.scss +45 -0
- package/dist/ui/dependencies-compare/compare-graph-model.d.ts +7 -0
- package/dist/ui/dependencies-compare/compare-graph-model.js +23 -0
- package/dist/ui/dependencies-compare/compare-graph-model.js.map +1 -0
- package/dist/ui/dependencies-compare/compare-node-model.d.ts +9 -0
- package/dist/ui/dependencies-compare/compare-node-model.js +28 -0
- package/dist/ui/dependencies-compare/compare-node-model.js.map +1 -0
- package/dist/ui/dependencies-compare/dependencies-compare.d.ts +1 -0
- package/dist/ui/dependencies-compare/dependencies-compare.js +202 -0
- package/dist/ui/dependencies-compare/dependencies-compare.js.map +1 -0
- package/dist/ui/dependencies-compare/dependencies-compare.module.scss +14 -0
- package/dist/ui/dependencies-compare/dependency-compare-node.d.ts +6 -0
- package/dist/ui/dependencies-compare/dependency-compare-node.js +208 -0
- package/dist/ui/dependencies-compare/dependency-compare-node.js.map +1 -0
- package/dist/ui/dependencies-compare/dependency-compare-node.module.scss +21 -0
- package/dist/ui/dependencies-compare/dependency-compare-variants.module.scss +23 -0
- package/dist/ui/dependencies-compare/diff-graph.d.ts +4 -0
- package/dist/ui/dependencies-compare/diff-graph.js +65 -0
- package/dist/ui/dependencies-compare/diff-graph.js.map +1 -0
- package/dist/ui/dependencies-compare/index.d.ts +1 -0
- package/dist/ui/dependencies-compare/index.js +20 -0
- package/dist/ui/dependencies-compare/index.js.map +1 -0
- package/dist/ui/dependencies-graph/calc-elements.d.ts +14 -0
- package/dist/ui/dependencies-graph/calc-elements.js +83 -0
- package/dist/ui/dependencies-graph/calc-elements.js.map +1 -0
- package/dist/ui/dependencies-graph/calc-layout.d.ts +8 -0
- package/dist/ui/dependencies-graph/calc-layout.js +59 -0
- package/dist/ui/dependencies-graph/calc-layout.js.map +1 -0
- package/dist/ui/dependencies-graph/dep-edge/dep-edge.d.ts +3 -0
- package/dist/ui/dependencies-graph/dep-edge/dep-edge.js +48 -0
- package/dist/ui/dependencies-graph/dep-edge/dep-edge.js.map +1 -0
- package/dist/ui/dependencies-graph/dep-edge/edge.module.scss +10 -0
- package/dist/ui/dependencies-graph/dep-edge/index.d.ts +1 -0
- package/dist/ui/dependencies-graph/dep-edge/index.js +26 -0
- package/dist/ui/dependencies-graph/dep-edge/index.js.map +1 -0
- package/dist/ui/dependencies-graph/dependencies-graph.d.ts +13 -0
- package/dist/ui/dependencies-graph/dependencies-graph.js +183 -0
- package/dist/ui/dependencies-graph/dependencies-graph.js.map +1 -0
- package/dist/ui/dependencies-graph/dependencies-graph.module.scss +93 -0
- package/dist/ui/dependencies-graph/graph-context.d.ts +6 -0
- package/dist/ui/dependencies-graph/graph-context.js +18 -0
- package/dist/ui/dependencies-graph/graph-context.js.map +1 -0
- package/dist/ui/dependencies-graph/index.d.ts +12 -0
- package/dist/ui/dependencies-graph/index.js +116 -0
- package/dist/ui/dependencies-graph/index.js.map +1 -0
- package/dist/ui/dependencies-graph/minimap.d.ts +2 -0
- package/dist/ui/dependencies-graph/minimap.js +26 -0
- package/dist/ui/dependencies-graph/minimap.js.map +1 -0
- package/dist/ui/graph-page/graph-filters.d.ts +9 -0
- package/dist/ui/graph-page/graph-filters.js +46 -0
- package/dist/ui/graph-page/graph-filters.js.map +1 -0
- package/dist/ui/graph-page/graph-page.d.ts +6 -0
- package/dist/ui/graph-page/graph-page.js +111 -0
- package/dist/ui/graph-page/graph-page.js.map +1 -0
- package/dist/ui/graph-page/graph-page.module.scss +37 -0
- package/dist/ui/graph-page/index.d.ts +6 -0
- package/dist/ui/graph-page/index.js +50 -0
- package/dist/ui/graph-page/index.js.map +1 -0
- package/dist/ui/graph.section.d.ts +15 -0
- package/dist/ui/graph.section.js +43 -0
- package/dist/ui/graph.section.js.map +1 -0
- package/dist/ui/query/edge-model.d.ts +8 -0
- package/dist/ui/query/edge-model.js +26 -0
- package/dist/ui/query/edge-model.js.map +1 -0
- package/dist/ui/query/get-graph.query.d.ts +33 -0
- package/dist/ui/query/get-graph.query.js +60 -0
- package/dist/ui/query/get-graph.query.js.map +1 -0
- package/dist/ui/query/graph-model.d.ts +9 -0
- package/dist/ui/query/graph-model.js +34 -0
- package/dist/ui/query/graph-model.js.map +1 -0
- package/dist/ui/query/index.d.ts +6 -0
- package/dist/ui/query/index.js +85 -0
- package/dist/ui/query/index.js.map +1 -0
- package/dist/ui/query/node-model.d.ts +8 -0
- package/dist/ui/query/node-model.js +35 -0
- package/dist/ui/query/node-model.js.map +1 -0
- package/dist/ui/query/use-graph-query.d.ts +9 -0
- package/dist/ui/query/use-graph-query.js +96 -0
- package/dist/ui/query/use-graph-query.js.map +1 -0
- package/dist/ui/query/use-graph.d.ts +7 -0
- package/dist/ui/query/use-graph.js +26 -0
- package/dist/ui/query/use-graph.js.map +1 -0
- package/esm.mjs +29 -0
- package/graph.compare.section.tsx +23 -0
- package/graph.composition.tsx +7 -0
- package/graph.docs.md +4 -0
- package/graph.ui.runtime.tsx +61 -0
- package/model/dependency/dependency.ts +11 -0
- package/model/dependency/index.ts +1 -0
- package/model/graph-filters/graph-filters.ts +1 -0
- package/model/graph-filters/index.ts +1 -0
- package/package.json +94 -0
- package/types/asset.d.ts +41 -0
- package/types/style.d.ts +42 -0
- package/ui/component-node/component-node.module.scss +73 -0
- package/ui/component-node/component-node.tsx +66 -0
- package/ui/component-node/index.ts +8 -0
- package/ui/component-node/variants.module.scss +45 -0
- package/ui/component-node/variants.ts +5 -0
- package/ui/dependencies-compare/compare-graph-model.ts +11 -0
- package/ui/dependencies-compare/compare-node-model.ts +11 -0
- package/ui/dependencies-compare/dependencies-compare.module.scss +14 -0
- package/ui/dependencies-compare/dependencies-compare.tsx +140 -0
- package/ui/dependencies-compare/dependency-compare-node.module.scss +21 -0
- package/ui/dependencies-compare/dependency-compare-node.tsx +100 -0
- package/ui/dependencies-compare/dependency-compare-variants.module.scss +23 -0
- package/ui/dependencies-compare/diff-graph.ts +70 -0
- package/ui/dependencies-compare/index.ts +1 -0
- package/ui/dependencies-graph/calc-elements.tsx +53 -0
- package/ui/dependencies-graph/calc-layout.tsx +43 -0
- package/ui/dependencies-graph/dep-edge/dep-edge.tsx +28 -0
- package/ui/dependencies-graph/dep-edge/edge.module.scss +10 -0
- package/ui/dependencies-graph/dep-edge/index.ts +1 -0
- package/ui/dependencies-graph/dependencies-graph.module.scss +93 -0
- package/ui/dependencies-graph/dependencies-graph.tsx +139 -0
- package/ui/dependencies-graph/graph-context.ts +9 -0
- package/ui/dependencies-graph/index.ts +12 -0
- package/ui/dependencies-graph/minimap.ts +15 -0
- package/ui/graph-page/graph-filters.tsx +28 -0
- package/ui/graph-page/graph-page.module.scss +37 -0
- package/ui/graph-page/graph-page.tsx +56 -0
- package/ui/graph-page/index.ts +7 -0
- package/ui/graph.section.tsx +19 -0
- package/ui/query/edge-model.ts +16 -0
- package/ui/query/get-graph.query.ts +83 -0
- package/ui/query/graph-model.ts +16 -0
- package/ui/query/index.ts +7 -0
- package/ui/query/node-model.ts +18 -0
- package/ui/query/use-graph-query.ts +72 -0
- package/ui/query/use-graph.tsx +8 -0
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
import { Component, ComponentID } from '@teambit/component';
|
|
2
|
+
import { Graph, Node, Edge } from '@teambit/graph.cleargraph';
|
|
3
|
+
|
|
4
|
+
import { Dependency } from '../model/dependency';
|
|
5
|
+
import { DuplicateDependency, VersionSubgraph } from '../duplicate-dependency';
|
|
6
|
+
|
|
7
|
+
export const DEPENDENCIES_TYPES = ['dependencies', 'devDependencies'];
|
|
8
|
+
|
|
9
|
+
type ComponentNode = Node<Component>;
|
|
10
|
+
type DependencyEdge = Edge<Dependency>;
|
|
11
|
+
|
|
12
|
+
export class ComponentGraph extends Graph<Component, Dependency> {
|
|
13
|
+
seederIds: ComponentID[] = []; // component IDs that started the graph. (if from workspace, the .bitmap ids normally)
|
|
14
|
+
constructor(nodes: ComponentNode[] = [], edges: DependencyEdge[] = []) {
|
|
15
|
+
super(nodes, edges);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
protected create(nodes: ComponentNode[] = [], edges: DependencyEdge[] = []): this {
|
|
19
|
+
return new ComponentGraph(nodes, edges) as this;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* @deprecate use graph.getGraphIds().findCycles()
|
|
24
|
+
*/
|
|
25
|
+
findCycles(graph?: this): string[][] {
|
|
26
|
+
const cycles = super.findCycles(graph);
|
|
27
|
+
if (!this.shouldLimitToSeedersOnly()) {
|
|
28
|
+
return cycles;
|
|
29
|
+
}
|
|
30
|
+
const seederIdsStr = this.seederIds.map((id) => id.toString());
|
|
31
|
+
const cyclesWithSeeders = cycles.filter((cycle) => {
|
|
32
|
+
return cycle.some((cycleIdStr) => seederIdsStr.includes(cycleIdStr));
|
|
33
|
+
});
|
|
34
|
+
return cyclesWithSeeders;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
findDuplicateDependencies(): Map<string, DuplicateDependency> {
|
|
38
|
+
const versionMap = this.calculateVersionMap();
|
|
39
|
+
const seederIdsNoVersions = this.seederIds.map((id) => id.toStringWithoutVersion());
|
|
40
|
+
const duplicateDependencies: Map<string, DuplicateDependency> = new Map();
|
|
41
|
+
for (const [compFullName, versions] of versionMap) {
|
|
42
|
+
if (versions.allVersionNodes.length > 1) {
|
|
43
|
+
const versionSubgraphs: VersionSubgraph[] = [];
|
|
44
|
+
const notLatestVersions = versions.allVersionNodes.filter((version) => version !== versions.latestVersionNode);
|
|
45
|
+
notLatestVersions.forEach((version) => {
|
|
46
|
+
const predecessors = this.predecessorsSubgraph(version);
|
|
47
|
+
const immediatePredecessors = this.predecessors(version).map((predecessor) => predecessor.id);
|
|
48
|
+
const subGraph = this.buildFromCleargraph(predecessors);
|
|
49
|
+
const versionSubgraph: VersionSubgraph = {
|
|
50
|
+
versionId: version,
|
|
51
|
+
subGraph,
|
|
52
|
+
// TODO: validate that this is working correctly
|
|
53
|
+
immediateDependents: immediatePredecessors,
|
|
54
|
+
};
|
|
55
|
+
versionSubgraphs.push(versionSubgraph);
|
|
56
|
+
});
|
|
57
|
+
const isSeeder = seederIdsNoVersions.includes(compFullName);
|
|
58
|
+
const shouldDisplayDueToBeingSeeder = !this.shouldLimitToSeedersOnly() || isSeeder;
|
|
59
|
+
if (shouldDisplayDueToBeingSeeder && versionSubgraphs.length > 0) {
|
|
60
|
+
const duplicateDep = new DuplicateDependency(versions.latestVersionNode, versionSubgraphs);
|
|
61
|
+
duplicateDependencies.set(compFullName, duplicateDep);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
return duplicateDependencies;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
buildFromCleargraph(graph: Graph<Component, Dependency>): ComponentGraph {
|
|
69
|
+
return this.create(graph.nodes, graph.edges);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
runtimeOnly(componentIds: string[]) {
|
|
73
|
+
return this.successorsSubgraph(componentIds, {
|
|
74
|
+
edgeFilter: (edge: DependencyEdge) => edge.attr.type === 'runtime',
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
private shouldLimitToSeedersOnly() {
|
|
79
|
+
return this.seederIds.length;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
private calculateVersionMap(): Map<string, { allVersionNodes: string[]; latestVersionNode: string }> {
|
|
83
|
+
const versionMap: Map<string, { allVersionNodes: string[]; latestVersionNode: string }> = new Map();
|
|
84
|
+
for (const node of this.nodes) {
|
|
85
|
+
const comp = node.attr;
|
|
86
|
+
const compKey = node.id;
|
|
87
|
+
const compFullName = comp.id.toStringWithoutVersion();
|
|
88
|
+
if (!versionMap.has(compFullName)) {
|
|
89
|
+
versionMap.set(compFullName, {
|
|
90
|
+
allVersionNodes: [compKey],
|
|
91
|
+
latestVersionNode: compKey,
|
|
92
|
+
});
|
|
93
|
+
} else {
|
|
94
|
+
const value = versionMap.get(compFullName);
|
|
95
|
+
if (value) {
|
|
96
|
+
if (Object.prototype.hasOwnProperty.call(value, 'allVersionNodes')) {
|
|
97
|
+
value.allVersionNodes.push(compKey);
|
|
98
|
+
}
|
|
99
|
+
const currentComp = comp;
|
|
100
|
+
const latestComp = this.node(value.latestVersionNode)?.attr;
|
|
101
|
+
// @todo: this check won't work when the component doesn't have head.
|
|
102
|
+
// it happens when a dependency is needed in an old version (not head). which Bit doesn't fetch the head
|
|
103
|
+
// Version object, and as a result, the `Component.head` is empty.
|
|
104
|
+
// for now it's probably good enough because it's used only for `findDuplicateDependencies`, which only
|
|
105
|
+
// checks the components on the workspace.
|
|
106
|
+
if (
|
|
107
|
+
currentComp.head &&
|
|
108
|
+
latestComp?.head &&
|
|
109
|
+
new Date(currentComp.head.timestamp) > new Date(latestComp.head.timestamp)
|
|
110
|
+
) {
|
|
111
|
+
value.latestVersionNode = compKey;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
return versionMap;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { Component, ComponentID } from '@teambit/component';
|
|
2
|
+
import { Graph, Node, Edge } from '@teambit/graph.cleargraph';
|
|
3
|
+
import { Dependency } from '../model/dependency';
|
|
4
|
+
import { DuplicateDependency } from '../duplicate-dependency';
|
|
5
|
+
export declare const DEPENDENCIES_TYPES: string[];
|
|
6
|
+
type ComponentNode = Node<Component>;
|
|
7
|
+
type DependencyEdge = Edge<Dependency>;
|
|
8
|
+
export declare class ComponentGraph extends Graph<Component, Dependency> {
|
|
9
|
+
seederIds: ComponentID[];
|
|
10
|
+
constructor(nodes?: ComponentNode[], edges?: DependencyEdge[]);
|
|
11
|
+
protected create(nodes?: ComponentNode[], edges?: DependencyEdge[]): this;
|
|
12
|
+
/**
|
|
13
|
+
* @deprecate use graph.getGraphIds().findCycles()
|
|
14
|
+
*/
|
|
15
|
+
findCycles(graph?: this): string[][];
|
|
16
|
+
findDuplicateDependencies(): Map<string, DuplicateDependency>;
|
|
17
|
+
buildFromCleargraph(graph: Graph<Component, Dependency>): ComponentGraph;
|
|
18
|
+
runtimeOnly(componentIds: string[]): this;
|
|
19
|
+
private shouldLimitToSeedersOnly;
|
|
20
|
+
private calculateVersionMap;
|
|
21
|
+
}
|
|
22
|
+
export {};
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.DEPENDENCIES_TYPES = exports.ComponentGraph = void 0;
|
|
7
|
+
function _graph() {
|
|
8
|
+
const data = require("@teambit/graph.cleargraph");
|
|
9
|
+
_graph = function () {
|
|
10
|
+
return data;
|
|
11
|
+
};
|
|
12
|
+
return data;
|
|
13
|
+
}
|
|
14
|
+
function _duplicateDependency() {
|
|
15
|
+
const data = require("../duplicate-dependency");
|
|
16
|
+
_duplicateDependency = function () {
|
|
17
|
+
return data;
|
|
18
|
+
};
|
|
19
|
+
return data;
|
|
20
|
+
}
|
|
21
|
+
function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
|
|
22
|
+
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
|
|
23
|
+
function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
|
|
24
|
+
const DEPENDENCIES_TYPES = exports.DEPENDENCIES_TYPES = ['dependencies', 'devDependencies'];
|
|
25
|
+
class ComponentGraph extends _graph().Graph {
|
|
26
|
+
// component IDs that started the graph. (if from workspace, the .bitmap ids normally)
|
|
27
|
+
constructor(nodes = [], edges = []) {
|
|
28
|
+
super(nodes, edges);
|
|
29
|
+
_defineProperty(this, "seederIds", []);
|
|
30
|
+
}
|
|
31
|
+
create(nodes = [], edges = []) {
|
|
32
|
+
return new ComponentGraph(nodes, edges);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* @deprecate use graph.getGraphIds().findCycles()
|
|
37
|
+
*/
|
|
38
|
+
findCycles(graph) {
|
|
39
|
+
const cycles = super.findCycles(graph);
|
|
40
|
+
if (!this.shouldLimitToSeedersOnly()) {
|
|
41
|
+
return cycles;
|
|
42
|
+
}
|
|
43
|
+
const seederIdsStr = this.seederIds.map(id => id.toString());
|
|
44
|
+
const cyclesWithSeeders = cycles.filter(cycle => {
|
|
45
|
+
return cycle.some(cycleIdStr => seederIdsStr.includes(cycleIdStr));
|
|
46
|
+
});
|
|
47
|
+
return cyclesWithSeeders;
|
|
48
|
+
}
|
|
49
|
+
findDuplicateDependencies() {
|
|
50
|
+
const versionMap = this.calculateVersionMap();
|
|
51
|
+
const seederIdsNoVersions = this.seederIds.map(id => id.toStringWithoutVersion());
|
|
52
|
+
const duplicateDependencies = new Map();
|
|
53
|
+
for (const [compFullName, versions] of versionMap) {
|
|
54
|
+
if (versions.allVersionNodes.length > 1) {
|
|
55
|
+
const versionSubgraphs = [];
|
|
56
|
+
const notLatestVersions = versions.allVersionNodes.filter(version => version !== versions.latestVersionNode);
|
|
57
|
+
notLatestVersions.forEach(version => {
|
|
58
|
+
const predecessors = this.predecessorsSubgraph(version);
|
|
59
|
+
const immediatePredecessors = this.predecessors(version).map(predecessor => predecessor.id);
|
|
60
|
+
const subGraph = this.buildFromCleargraph(predecessors);
|
|
61
|
+
const versionSubgraph = {
|
|
62
|
+
versionId: version,
|
|
63
|
+
subGraph,
|
|
64
|
+
// TODO: validate that this is working correctly
|
|
65
|
+
immediateDependents: immediatePredecessors
|
|
66
|
+
};
|
|
67
|
+
versionSubgraphs.push(versionSubgraph);
|
|
68
|
+
});
|
|
69
|
+
const isSeeder = seederIdsNoVersions.includes(compFullName);
|
|
70
|
+
const shouldDisplayDueToBeingSeeder = !this.shouldLimitToSeedersOnly() || isSeeder;
|
|
71
|
+
if (shouldDisplayDueToBeingSeeder && versionSubgraphs.length > 0) {
|
|
72
|
+
const duplicateDep = new (_duplicateDependency().DuplicateDependency)(versions.latestVersionNode, versionSubgraphs);
|
|
73
|
+
duplicateDependencies.set(compFullName, duplicateDep);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
return duplicateDependencies;
|
|
78
|
+
}
|
|
79
|
+
buildFromCleargraph(graph) {
|
|
80
|
+
return this.create(graph.nodes, graph.edges);
|
|
81
|
+
}
|
|
82
|
+
runtimeOnly(componentIds) {
|
|
83
|
+
return this.successorsSubgraph(componentIds, {
|
|
84
|
+
edgeFilter: edge => edge.attr.type === 'runtime'
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
shouldLimitToSeedersOnly() {
|
|
88
|
+
return this.seederIds.length;
|
|
89
|
+
}
|
|
90
|
+
calculateVersionMap() {
|
|
91
|
+
const versionMap = new Map();
|
|
92
|
+
for (const node of this.nodes) {
|
|
93
|
+
const comp = node.attr;
|
|
94
|
+
const compKey = node.id;
|
|
95
|
+
const compFullName = comp.id.toStringWithoutVersion();
|
|
96
|
+
if (!versionMap.has(compFullName)) {
|
|
97
|
+
versionMap.set(compFullName, {
|
|
98
|
+
allVersionNodes: [compKey],
|
|
99
|
+
latestVersionNode: compKey
|
|
100
|
+
});
|
|
101
|
+
} else {
|
|
102
|
+
const value = versionMap.get(compFullName);
|
|
103
|
+
if (value) {
|
|
104
|
+
if (Object.prototype.hasOwnProperty.call(value, 'allVersionNodes')) {
|
|
105
|
+
value.allVersionNodes.push(compKey);
|
|
106
|
+
}
|
|
107
|
+
const currentComp = comp;
|
|
108
|
+
const latestComp = this.node(value.latestVersionNode)?.attr;
|
|
109
|
+
// @todo: this check won't work when the component doesn't have head.
|
|
110
|
+
// it happens when a dependency is needed in an old version (not head). which Bit doesn't fetch the head
|
|
111
|
+
// Version object, and as a result, the `Component.head` is empty.
|
|
112
|
+
// for now it's probably good enough because it's used only for `findDuplicateDependencies`, which only
|
|
113
|
+
// checks the components on the workspace.
|
|
114
|
+
if (currentComp.head && latestComp?.head && new Date(currentComp.head.timestamp) > new Date(latestComp.head.timestamp)) {
|
|
115
|
+
value.latestVersionNode = compKey;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
return versionMap;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
exports.ComponentGraph = ComponentGraph;
|
|
124
|
+
|
|
125
|
+
//# sourceMappingURL=component-graph.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["_graph","data","require","_duplicateDependency","_defineProperty","e","r","t","_toPropertyKey","Object","defineProperty","value","enumerable","configurable","writable","i","_toPrimitive","Symbol","toPrimitive","call","TypeError","String","Number","DEPENDENCIES_TYPES","exports","ComponentGraph","Graph","constructor","nodes","edges","create","findCycles","graph","cycles","shouldLimitToSeedersOnly","seederIdsStr","seederIds","map","id","toString","cyclesWithSeeders","filter","cycle","some","cycleIdStr","includes","findDuplicateDependencies","versionMap","calculateVersionMap","seederIdsNoVersions","toStringWithoutVersion","duplicateDependencies","Map","compFullName","versions","allVersionNodes","length","versionSubgraphs","notLatestVersions","version","latestVersionNode","forEach","predecessors","predecessorsSubgraph","immediatePredecessors","predecessor","subGraph","buildFromCleargraph","versionSubgraph","versionId","immediateDependents","push","isSeeder","shouldDisplayDueToBeingSeeder","duplicateDep","DuplicateDependency","set","runtimeOnly","componentIds","successorsSubgraph","edgeFilter","edge","attr","type","node","comp","compKey","has","get","prototype","hasOwnProperty","currentComp","latestComp","head","Date","timestamp"],"sources":["component-graph.ts"],"sourcesContent":["import { Component, ComponentID } from '@teambit/component';\nimport { Graph, Node, Edge } from '@teambit/graph.cleargraph';\n\nimport { Dependency } from '../model/dependency';\nimport { DuplicateDependency, VersionSubgraph } from '../duplicate-dependency';\n\nexport const DEPENDENCIES_TYPES = ['dependencies', 'devDependencies'];\n\ntype ComponentNode = Node<Component>;\ntype DependencyEdge = Edge<Dependency>;\n\nexport class ComponentGraph extends Graph<Component, Dependency> {\n seederIds: ComponentID[] = []; // component IDs that started the graph. (if from workspace, the .bitmap ids normally)\n constructor(nodes: ComponentNode[] = [], edges: DependencyEdge[] = []) {\n super(nodes, edges);\n }\n\n protected create(nodes: ComponentNode[] = [], edges: DependencyEdge[] = []): this {\n return new ComponentGraph(nodes, edges) as this;\n }\n\n /**\n * @deprecate use graph.getGraphIds().findCycles()\n */\n findCycles(graph?: this): string[][] {\n const cycles = super.findCycles(graph);\n if (!this.shouldLimitToSeedersOnly()) {\n return cycles;\n }\n const seederIdsStr = this.seederIds.map((id) => id.toString());\n const cyclesWithSeeders = cycles.filter((cycle) => {\n return cycle.some((cycleIdStr) => seederIdsStr.includes(cycleIdStr));\n });\n return cyclesWithSeeders;\n }\n\n findDuplicateDependencies(): Map<string, DuplicateDependency> {\n const versionMap = this.calculateVersionMap();\n const seederIdsNoVersions = this.seederIds.map((id) => id.toStringWithoutVersion());\n const duplicateDependencies: Map<string, DuplicateDependency> = new Map();\n for (const [compFullName, versions] of versionMap) {\n if (versions.allVersionNodes.length > 1) {\n const versionSubgraphs: VersionSubgraph[] = [];\n const notLatestVersions = versions.allVersionNodes.filter((version) => version !== versions.latestVersionNode);\n notLatestVersions.forEach((version) => {\n const predecessors = this.predecessorsSubgraph(version);\n const immediatePredecessors = this.predecessors(version).map((predecessor) => predecessor.id);\n const subGraph = this.buildFromCleargraph(predecessors);\n const versionSubgraph: VersionSubgraph = {\n versionId: version,\n subGraph,\n // TODO: validate that this is working correctly\n immediateDependents: immediatePredecessors,\n };\n versionSubgraphs.push(versionSubgraph);\n });\n const isSeeder = seederIdsNoVersions.includes(compFullName);\n const shouldDisplayDueToBeingSeeder = !this.shouldLimitToSeedersOnly() || isSeeder;\n if (shouldDisplayDueToBeingSeeder && versionSubgraphs.length > 0) {\n const duplicateDep = new DuplicateDependency(versions.latestVersionNode, versionSubgraphs);\n duplicateDependencies.set(compFullName, duplicateDep);\n }\n }\n }\n return duplicateDependencies;\n }\n\n buildFromCleargraph(graph: Graph<Component, Dependency>): ComponentGraph {\n return this.create(graph.nodes, graph.edges);\n }\n\n runtimeOnly(componentIds: string[]) {\n return this.successorsSubgraph(componentIds, {\n edgeFilter: (edge: DependencyEdge) => edge.attr.type === 'runtime',\n });\n }\n\n private shouldLimitToSeedersOnly() {\n return this.seederIds.length;\n }\n\n private calculateVersionMap(): Map<string, { allVersionNodes: string[]; latestVersionNode: string }> {\n const versionMap: Map<string, { allVersionNodes: string[]; latestVersionNode: string }> = new Map();\n for (const node of this.nodes) {\n const comp = node.attr;\n const compKey = node.id;\n const compFullName = comp.id.toStringWithoutVersion();\n if (!versionMap.has(compFullName)) {\n versionMap.set(compFullName, {\n allVersionNodes: [compKey],\n latestVersionNode: compKey,\n });\n } else {\n const value = versionMap.get(compFullName);\n if (value) {\n if (Object.prototype.hasOwnProperty.call(value, 'allVersionNodes')) {\n value.allVersionNodes.push(compKey);\n }\n const currentComp = comp;\n const latestComp = this.node(value.latestVersionNode)?.attr;\n // @todo: this check won't work when the component doesn't have head.\n // it happens when a dependency is needed in an old version (not head). which Bit doesn't fetch the head\n // Version object, and as a result, the `Component.head` is empty.\n // for now it's probably good enough because it's used only for `findDuplicateDependencies`, which only\n // checks the components on the workspace.\n if (\n currentComp.head &&\n latestComp?.head &&\n new Date(currentComp.head.timestamp) > new Date(latestComp.head.timestamp)\n ) {\n value.latestVersionNode = compKey;\n }\n }\n }\n }\n return versionMap;\n }\n}\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { ComponentGraph } from './component-graph';
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
Object.defineProperty(exports, "ComponentGraph", {
|
|
7
|
+
enumerable: true,
|
|
8
|
+
get: function () {
|
|
9
|
+
return _componentGraph().ComponentGraph;
|
|
10
|
+
}
|
|
11
|
+
});
|
|
12
|
+
function _componentGraph() {
|
|
13
|
+
const data = require("./component-graph");
|
|
14
|
+
_componentGraph = function () {
|
|
15
|
+
return data;
|
|
16
|
+
};
|
|
17
|
+
return data;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["_componentGraph","data","require"],"sources":["index.ts"],"sourcesContent":["// eslint-disable-next-line import/no-cycle\nexport { ComponentGraph } from './component-graph';\n"],"mappings":";;;;;;;;;;;AACA,SAAAA,gBAAA;EAAA,MAAAC,IAAA,GAAAC,OAAA;EAAAF,eAAA,YAAAA,CAAA;IAAA,OAAAC,IAAA;EAAA;EAAA,OAAAA,IAAA;AAAA","ignoreList":[]}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { ComponentID } from '@teambit/component-id';
|
|
2
|
+
import { Graph, Node, Edge } from '@teambit/graph.cleargraph';
|
|
3
|
+
import type { DependenciesInfo } from '@teambit/legacy.dependency-graph';
|
|
4
|
+
import GraphLib from 'graphlib';
|
|
5
|
+
export type DepEdgeType = 'prod' | 'dev' | 'ext' | 'peer';
|
|
6
|
+
type ComponentIdNode = Node<ComponentID>;
|
|
7
|
+
type DependencyEdge = Edge<DepEdgeType>;
|
|
8
|
+
export type CompIdGraph = Graph<ComponentID, DepEdgeType>;
|
|
9
|
+
export declare class ComponentIdGraph extends Graph<ComponentID, DepEdgeType> {
|
|
10
|
+
private _graphLib;
|
|
11
|
+
seederIds: ComponentID[];
|
|
12
|
+
constructor(nodes?: ComponentIdNode[], edges?: DependencyEdge[]);
|
|
13
|
+
get graphLib(): GraphLib.Graph;
|
|
14
|
+
protected create(nodes?: ComponentIdNode[], edges?: DependencyEdge[]): this;
|
|
15
|
+
/**
|
|
16
|
+
* check all the routes from the sources to targets and return the components found during this traversal.
|
|
17
|
+
* e.g.
|
|
18
|
+
* A -> B -> C -> N.
|
|
19
|
+
* A -> E -> N.
|
|
20
|
+
* B -> F -> G.
|
|
21
|
+
* given source: A, targets: N. The results will be: [B, C, E].
|
|
22
|
+
*
|
|
23
|
+
* if through is provided, it will only return the components that are connected to the through components.
|
|
24
|
+
* with the example above, if through is B, the results will be: [B, C].
|
|
25
|
+
*/
|
|
26
|
+
findIdsFromSourcesToTargets(sources: ComponentID[], targets: ComponentID[], through?: ComponentID[]): ComponentID[];
|
|
27
|
+
/**
|
|
28
|
+
* check all the routes from the sources to targets and return the components found during this traversal.
|
|
29
|
+
* e.g.
|
|
30
|
+
* A -> B -> C -> N.
|
|
31
|
+
* A -> E -> N.
|
|
32
|
+
* B -> F -> G.
|
|
33
|
+
* given source: A, targets: N. The results will be: [B, C, E].
|
|
34
|
+
*
|
|
35
|
+
* if through is provided, it will only return the components that are connected to the through components.
|
|
36
|
+
* with the example above, if through is B, the results will be: [B, C].
|
|
37
|
+
*/
|
|
38
|
+
findAllPathsFromSourcesToTargets(sources: ComponentID[], targets: ComponentID[], through?: ComponentID[]): string[][];
|
|
39
|
+
/**
|
|
40
|
+
* overrides the super class to eliminate non-seeders components
|
|
41
|
+
*/
|
|
42
|
+
findCycles(graph?: this, includeDeps?: boolean): string[][];
|
|
43
|
+
buildFromCleargraph(graph: Graph<ComponentID, DepEdgeType>): ComponentIdGraph;
|
|
44
|
+
runtimeOnly(componentIds: string[]): this;
|
|
45
|
+
getDependenciesInfo(id: ComponentID): DependenciesInfo[];
|
|
46
|
+
getDependenciesAsObjectTree(idStr: string): Record<string, any>;
|
|
47
|
+
private shouldLimitToSeedersOnly;
|
|
48
|
+
}
|
|
49
|
+
export {};
|
|
@@ -0,0 +1,252 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.ComponentIdGraph = void 0;
|
|
7
|
+
function _componentId() {
|
|
8
|
+
const data = require("@teambit/component-id");
|
|
9
|
+
_componentId = function () {
|
|
10
|
+
return data;
|
|
11
|
+
};
|
|
12
|
+
return data;
|
|
13
|
+
}
|
|
14
|
+
function _graph() {
|
|
15
|
+
const data = require("@teambit/graph.cleargraph");
|
|
16
|
+
_graph = function () {
|
|
17
|
+
return data;
|
|
18
|
+
};
|
|
19
|
+
return data;
|
|
20
|
+
}
|
|
21
|
+
function _graphlib() {
|
|
22
|
+
const data = _interopRequireDefault(require("graphlib"));
|
|
23
|
+
_graphlib = function () {
|
|
24
|
+
return data;
|
|
25
|
+
};
|
|
26
|
+
return data;
|
|
27
|
+
}
|
|
28
|
+
function _lodash() {
|
|
29
|
+
const data = require("lodash");
|
|
30
|
+
_lodash = function () {
|
|
31
|
+
return data;
|
|
32
|
+
};
|
|
33
|
+
return data;
|
|
34
|
+
}
|
|
35
|
+
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
36
|
+
function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
|
|
37
|
+
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
|
|
38
|
+
function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
|
|
39
|
+
class ComponentIdGraph extends _graph().Graph {
|
|
40
|
+
// component IDs that started the graph. (if from workspace, the .bitmap ids normally)
|
|
41
|
+
constructor(nodes = [], edges = []) {
|
|
42
|
+
super(nodes, edges);
|
|
43
|
+
_defineProperty(this, "_graphLib", void 0);
|
|
44
|
+
_defineProperty(this, "seederIds", []);
|
|
45
|
+
}
|
|
46
|
+
get graphLib() {
|
|
47
|
+
if (!this._graphLib) {
|
|
48
|
+
// convert clearGraph to graphLib
|
|
49
|
+
this._graphLib = new (_graphlib().default.Graph)();
|
|
50
|
+
this.nodes.forEach(node => {
|
|
51
|
+
this._graphLib.setNode(node.id.toString());
|
|
52
|
+
});
|
|
53
|
+
this.edges.forEach(edge => {
|
|
54
|
+
this._graphLib.setEdge(edge.sourceId.toString(), edge.targetId.toString(), edge.attr);
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
return this._graphLib;
|
|
58
|
+
}
|
|
59
|
+
create(nodes = [], edges = []) {
|
|
60
|
+
return new ComponentIdGraph(nodes, edges);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* check all the routes from the sources to targets and return the components found during this traversal.
|
|
65
|
+
* e.g.
|
|
66
|
+
* A -> B -> C -> N.
|
|
67
|
+
* A -> E -> N.
|
|
68
|
+
* B -> F -> G.
|
|
69
|
+
* given source: A, targets: N. The results will be: [B, C, E].
|
|
70
|
+
*
|
|
71
|
+
* if through is provided, it will only return the components that are connected to the through components.
|
|
72
|
+
* with the example above, if through is B, the results will be: [B, C].
|
|
73
|
+
*/
|
|
74
|
+
findIdsFromSourcesToTargets(sources, targets, through) {
|
|
75
|
+
const removeVerFromIdStr = idStr => idStr.split('@')[0];
|
|
76
|
+
const sourcesStr = sources.map(s => s.toStringWithoutVersion());
|
|
77
|
+
const targetsStr = targets.map(t => t.toStringWithoutVersion());
|
|
78
|
+
const allFlattened = sources.map(source => this.successors(source.toString())).flat();
|
|
79
|
+
const allFlattenedIds = (0, _lodash().uniq)(allFlattened.map(f => f.id));
|
|
80
|
+
const results = [];
|
|
81
|
+
allFlattenedIds.forEach(id => {
|
|
82
|
+
const idWithNoVer = removeVerFromIdStr(id);
|
|
83
|
+
if (sourcesStr.includes(idWithNoVer) || targetsStr.includes(idWithNoVer)) return;
|
|
84
|
+
const allSuccessors = this.successors(id);
|
|
85
|
+
const allSuccessorsWithNoVersion = allSuccessors.map(s => removeVerFromIdStr(s.id));
|
|
86
|
+
if (allSuccessorsWithNoVersion.find(s => targetsStr.includes(s))) results.push(id);
|
|
87
|
+
});
|
|
88
|
+
const componentIds = this.getNodes(results).map(n => n.attr);
|
|
89
|
+
if (!through?.length) {
|
|
90
|
+
return componentIds;
|
|
91
|
+
}
|
|
92
|
+
const resultsWithThrough = [];
|
|
93
|
+
const throughStr = through.map(t => t.toStringWithoutVersion());
|
|
94
|
+
componentIds.forEach(id => {
|
|
95
|
+
const allGraph = this.subgraph(id.toString()).nodes.map(n => n.id); // successors and predecessors
|
|
96
|
+
const allGraphWithNoVersion = allGraph.map(s => removeVerFromIdStr(s));
|
|
97
|
+
if (throughStr.every(t => allGraphWithNoVersion.includes(t))) resultsWithThrough.push(id);
|
|
98
|
+
});
|
|
99
|
+
return resultsWithThrough;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* check all the routes from the sources to targets and return the components found during this traversal.
|
|
104
|
+
* e.g.
|
|
105
|
+
* A -> B -> C -> N.
|
|
106
|
+
* A -> E -> N.
|
|
107
|
+
* B -> F -> G.
|
|
108
|
+
* given source: A, targets: N. The results will be: [B, C, E].
|
|
109
|
+
*
|
|
110
|
+
* if through is provided, it will only return the components that are connected to the through components.
|
|
111
|
+
* with the example above, if through is B, the results will be: [B, C].
|
|
112
|
+
*/
|
|
113
|
+
findAllPathsFromSourcesToTargets(sources, targets, through) {
|
|
114
|
+
const removeVerFromIdStr = idStr => idStr.split('@')[0];
|
|
115
|
+
const findAllPathsBFS = (start, end) => {
|
|
116
|
+
const paths = [];
|
|
117
|
+
const visited = new Set();
|
|
118
|
+
const queue = [];
|
|
119
|
+
start.forEach(s => queue.push({
|
|
120
|
+
node: s,
|
|
121
|
+
path: [s]
|
|
122
|
+
}));
|
|
123
|
+
while (queue.length) {
|
|
124
|
+
const {
|
|
125
|
+
node,
|
|
126
|
+
path
|
|
127
|
+
} = queue.shift();
|
|
128
|
+
if (end.includes(removeVerFromIdStr(node))) {
|
|
129
|
+
paths.push([...path]);
|
|
130
|
+
} else {
|
|
131
|
+
visited.add(node);
|
|
132
|
+
const successors = this.outEdges(node).map(e => e.targetId);
|
|
133
|
+
for (const successor of successors) {
|
|
134
|
+
if (!visited.has(successor)) {
|
|
135
|
+
queue.push({
|
|
136
|
+
node: successor,
|
|
137
|
+
path: [...path, successor]
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
return paths;
|
|
144
|
+
};
|
|
145
|
+
const targetsStr = targets.map(t => t.toStringWithoutVersion());
|
|
146
|
+
const sourcesStr = sources.map(s => s.toString());
|
|
147
|
+
let allPaths = findAllPathsBFS(sourcesStr, targetsStr);
|
|
148
|
+
if (through?.length) {
|
|
149
|
+
allPaths = allPaths.filter(pathWithVer => {
|
|
150
|
+
const pathWithoutVer = pathWithVer.map(p => removeVerFromIdStr(p));
|
|
151
|
+
return through.every(t => pathWithoutVer.includes(t.toStringWithoutVersion()));
|
|
152
|
+
});
|
|
153
|
+
}
|
|
154
|
+
const filtered = allPaths.filter(path => {
|
|
155
|
+
if (path.length < 3) {
|
|
156
|
+
// if length is 1, the source and target are the same.
|
|
157
|
+
// if length is 2, the target is a direct dependency of the source. we don't care about it.
|
|
158
|
+
return false;
|
|
159
|
+
}
|
|
160
|
+
const [, firstDep] = path;
|
|
161
|
+
if (sourcesStr.includes(firstDep)) {
|
|
162
|
+
// the first item is the source. the second item "firstDep" can be a direct dependency of one of the sources.
|
|
163
|
+
// if this is the case, we have already an exact path without this firstDep.
|
|
164
|
+
return true;
|
|
165
|
+
}
|
|
166
|
+
return true;
|
|
167
|
+
});
|
|
168
|
+
return filtered.sort((a, b) => a.length - b.length);
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
/**
|
|
172
|
+
* overrides the super class to eliminate non-seeders components
|
|
173
|
+
*/
|
|
174
|
+
findCycles(graph = this, includeDeps = false) {
|
|
175
|
+
const cycles = super.findCycles(graph);
|
|
176
|
+
// reverse the order to show a more intuitive cycle order. from the dependent to the dependency.
|
|
177
|
+
cycles.forEach(cycle => cycle.reverse());
|
|
178
|
+
if (!this.shouldLimitToSeedersOnly() || includeDeps) {
|
|
179
|
+
return cycles;
|
|
180
|
+
}
|
|
181
|
+
const seederIdsStr = this.seederIds.map(id => id.toString());
|
|
182
|
+
const cyclesWithSeeders = cycles.filter(cycle => {
|
|
183
|
+
return cycle.some(cycleIdStr => seederIdsStr.includes(cycleIdStr));
|
|
184
|
+
});
|
|
185
|
+
return cyclesWithSeeders;
|
|
186
|
+
}
|
|
187
|
+
buildFromCleargraph(graph) {
|
|
188
|
+
return this.create(graph.nodes, graph.edges);
|
|
189
|
+
}
|
|
190
|
+
runtimeOnly(componentIds) {
|
|
191
|
+
return this.successorsSubgraph(componentIds, {
|
|
192
|
+
edgeFilter: edge => edge.attr === 'prod'
|
|
193
|
+
});
|
|
194
|
+
}
|
|
195
|
+
getDependenciesInfo(id) {
|
|
196
|
+
const dijkstraResults = _graphlib().default.alg.dijkstra(this.graphLib, id.toString());
|
|
197
|
+
const dependencies = [];
|
|
198
|
+
Object.keys(dijkstraResults).forEach(idStr => {
|
|
199
|
+
const distance = dijkstraResults[idStr].distance;
|
|
200
|
+
if (distance === Infinity || distance === 0) {
|
|
201
|
+
// there is no dependency or it's the same component (distance zero)
|
|
202
|
+
return;
|
|
203
|
+
}
|
|
204
|
+
const predecessor = dijkstraResults[idStr].predecessor;
|
|
205
|
+
const dependencyType = this.edge(predecessor, idStr);
|
|
206
|
+
dependencies.push({
|
|
207
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
208
|
+
id: this.node(idStr).attr,
|
|
209
|
+
depth: distance,
|
|
210
|
+
parent: predecessor,
|
|
211
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
212
|
+
dependencyType: dependencyType.attr
|
|
213
|
+
});
|
|
214
|
+
});
|
|
215
|
+
dependencies.sort((a, b) => a.depth - b.depth);
|
|
216
|
+
return dependencies;
|
|
217
|
+
}
|
|
218
|
+
getDependenciesAsObjectTree(idStr) {
|
|
219
|
+
const depsInfo = this.getDependenciesInfo(_componentId().ComponentID.fromString(idStr));
|
|
220
|
+
const populateTreeItems = (id, treeItems) => {
|
|
221
|
+
const children = depsInfo.filter(depInfo => depInfo.parent === id);
|
|
222
|
+
if (!children || children.length === 0) {
|
|
223
|
+
return;
|
|
224
|
+
}
|
|
225
|
+
children.forEach(child => {
|
|
226
|
+
const {
|
|
227
|
+
id: compId
|
|
228
|
+
} = child;
|
|
229
|
+
const label = compId.toString();
|
|
230
|
+
const currentNodes = [];
|
|
231
|
+
treeItems.push({
|
|
232
|
+
label,
|
|
233
|
+
nodes: currentNodes
|
|
234
|
+
});
|
|
235
|
+
populateTreeItems(label, currentNodes);
|
|
236
|
+
});
|
|
237
|
+
};
|
|
238
|
+
const currentNodes = [];
|
|
239
|
+
const tree = {
|
|
240
|
+
label: idStr,
|
|
241
|
+
nodes: currentNodes
|
|
242
|
+
};
|
|
243
|
+
populateTreeItems(idStr, currentNodes);
|
|
244
|
+
return tree;
|
|
245
|
+
}
|
|
246
|
+
shouldLimitToSeedersOnly() {
|
|
247
|
+
return this.seederIds.length;
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
exports.ComponentIdGraph = ComponentIdGraph;
|
|
251
|
+
|
|
252
|
+
//# sourceMappingURL=component-id-graph.js.map
|