@dreamtree-org/graphify 1.4.0 → 1.6.0
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/dist/{chunk-QEB7A5KB.js → chunk-5Q4BCTMF.js} +116 -103
- package/dist/chunk-5Q4BCTMF.js.map +1 -0
- package/dist/{chunk-ZPB37LLQ.js → chunk-FZ23C67J.js} +2 -2
- package/dist/{chunk-6JLEILYF.js → chunk-N3VOEXK3.js} +32 -2
- package/dist/{chunk-6JLEILYF.js.map → chunk-N3VOEXK3.js.map} +1 -1
- package/dist/{chunk-7LTO76UD.js → chunk-OHN5UO6W.js} +2 -2
- package/dist/cli/index.cjs +19 -7
- package/dist/cli/index.cjs.map +1 -1
- package/dist/cli/index.js +4 -4
- package/dist/index.cjs +646 -181
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +229 -17
- package/dist/index.d.ts +229 -17
- package/dist/index.js +424 -4
- package/dist/index.js.map +1 -1
- package/dist/mcp/server.js +2 -2
- package/dist/mysql-DJMXLP3O.js +8 -0
- package/package.json +1 -1
- package/dist/chunk-QEB7A5KB.js.map +0 -1
- package/dist/mysql-EJ6XOWR4.js +0 -8
- /package/dist/{chunk-ZPB37LLQ.js.map → chunk-FZ23C67J.js.map} +0 -0
- /package/dist/{chunk-7LTO76UD.js.map → chunk-OHN5UO6W.js.map} +0 -0
- /package/dist/{mysql-EJ6XOWR4.js.map → mysql-DJMXLP3O.js.map} +0 -0
|
@@ -2,12 +2,12 @@ import {
|
|
|
2
2
|
LocalFileGraphStore,
|
|
3
3
|
affectedBy,
|
|
4
4
|
testsForNode
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-OHN5UO6W.js";
|
|
6
6
|
import {
|
|
7
7
|
escapeHtml,
|
|
8
8
|
sanitizeLabel,
|
|
9
9
|
validateGraphPath
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-N3VOEXK3.js";
|
|
11
11
|
|
|
12
12
|
// src/detect.ts
|
|
13
13
|
import * as fs from "fs";
|
|
@@ -1955,13 +1955,15 @@ var RelationSchema = z.enum([
|
|
|
1955
1955
|
"references",
|
|
1956
1956
|
"contains",
|
|
1957
1957
|
"method",
|
|
1958
|
-
"re_exports"
|
|
1958
|
+
"re_exports",
|
|
1959
|
+
"follows"
|
|
1959
1960
|
]);
|
|
1960
1961
|
var GraphNodeSchema = z.object({
|
|
1961
1962
|
id: z.string().min(1, "node id must be non-empty"),
|
|
1962
1963
|
label: z.string(),
|
|
1963
1964
|
sourceFile: z.string(),
|
|
1964
|
-
sourceLocation: z.string()
|
|
1965
|
+
sourceLocation: z.string(),
|
|
1966
|
+
kind: z.string().optional()
|
|
1965
1967
|
});
|
|
1966
1968
|
var GraphEdgeSchema = z.object({
|
|
1967
1969
|
source: z.string().min(1, "edge source must be non-empty"),
|
|
@@ -2010,16 +2012,27 @@ function buildGraph(extractions) {
|
|
|
2010
2012
|
const validated = extractions.map(
|
|
2011
2013
|
(extraction, index) => validateExtraction(extraction, `extraction #${index}`)
|
|
2012
2014
|
);
|
|
2015
|
+
mergeExtractionsInto(graph, validated);
|
|
2016
|
+
return graph;
|
|
2017
|
+
}
|
|
2018
|
+
function mergeExtractionsInto(graph, validated) {
|
|
2013
2019
|
const allNodes = validated.flatMap((extraction) => extraction.nodes);
|
|
2014
2020
|
const allEdges = validated.flatMap((extraction) => extraction.edges);
|
|
2015
2021
|
const sortedNodes = [...allNodes].sort((a, b) => a.id.localeCompare(b.id));
|
|
2016
2022
|
for (const node of sortedNodes) {
|
|
2017
|
-
|
|
2018
|
-
graph.addNode(node.id, {
|
|
2023
|
+
const attributes = {
|
|
2019
2024
|
label: node.label,
|
|
2020
2025
|
sourceFile: node.sourceFile,
|
|
2021
|
-
sourceLocation: node.sourceLocation
|
|
2022
|
-
|
|
2026
|
+
sourceLocation: node.sourceLocation,
|
|
2027
|
+
...node.kind !== void 0 ? { kind: node.kind } : {}
|
|
2028
|
+
};
|
|
2029
|
+
if (graph.hasNode(node.id)) {
|
|
2030
|
+
if (graph.getNodeAttribute(node.id, "sourceFile") === "<unknown>") {
|
|
2031
|
+
graph.mergeNodeAttributes(node.id, attributes);
|
|
2032
|
+
}
|
|
2033
|
+
continue;
|
|
2034
|
+
}
|
|
2035
|
+
graph.addNode(node.id, attributes);
|
|
2023
2036
|
}
|
|
2024
2037
|
const sortedEdges = [...allEdges].sort(
|
|
2025
2038
|
(a, b) => a.source.localeCompare(b.source) || a.target.localeCompare(b.target) || a.relation.localeCompare(b.relation)
|
|
@@ -2038,6 +2051,98 @@ function buildGraph(extractions) {
|
|
|
2038
2051
|
confidence: edge.confidence
|
|
2039
2052
|
});
|
|
2040
2053
|
}
|
|
2054
|
+
}
|
|
2055
|
+
|
|
2056
|
+
// src/cluster.ts
|
|
2057
|
+
import { createHash } from "crypto";
|
|
2058
|
+
import Graph2 from "graphology";
|
|
2059
|
+
import leiden from "@aflsolutions/graphology-communities-leiden";
|
|
2060
|
+
import louvain from "graphology-communities-louvain";
|
|
2061
|
+
var FIXED_SEED = 1592594996;
|
|
2062
|
+
function mulberry32(seed) {
|
|
2063
|
+
let a = seed >>> 0;
|
|
2064
|
+
return function next() {
|
|
2065
|
+
a = a + 1831565813 | 0;
|
|
2066
|
+
let t = Math.imul(a ^ a >>> 15, 1 | a);
|
|
2067
|
+
t = t + Math.imul(t ^ t >>> 7, 61 | t) ^ t;
|
|
2068
|
+
return ((t ^ t >>> 14) >>> 0) / 4294967296;
|
|
2069
|
+
};
|
|
2070
|
+
}
|
|
2071
|
+
function sortedWorkingCopy(graph) {
|
|
2072
|
+
const copy = new Graph2({ type: graph.type, multi: graph.multi, allowSelfLoops: graph.allowSelfLoops });
|
|
2073
|
+
const nodeIds = graph.nodes().sort((a, b) => a.localeCompare(b));
|
|
2074
|
+
for (const id of nodeIds) {
|
|
2075
|
+
copy.addNode(id, { ...graph.getNodeAttributes(id) });
|
|
2076
|
+
}
|
|
2077
|
+
const edgeEntries = [];
|
|
2078
|
+
graph.forEachEdge((edge, attributes, source, target) => {
|
|
2079
|
+
edgeEntries.push({ key: edge, source, target, attributes });
|
|
2080
|
+
});
|
|
2081
|
+
edgeEntries.sort(
|
|
2082
|
+
(a, b) => a.source.localeCompare(b.source) || a.target.localeCompare(b.target) || String(a.attributes.relation).localeCompare(String(b.attributes.relation))
|
|
2083
|
+
);
|
|
2084
|
+
for (const entry of edgeEntries) {
|
|
2085
|
+
copy.addEdgeWithKey(entry.key, entry.source, entry.target, { ...entry.attributes });
|
|
2086
|
+
}
|
|
2087
|
+
return copy;
|
|
2088
|
+
}
|
|
2089
|
+
function toUndirectedCopy(graph) {
|
|
2090
|
+
const copy = new Graph2({ type: "undirected", multi: true, allowSelfLoops: graph.allowSelfLoops });
|
|
2091
|
+
graph.forEachNode((nodeId, attributes) => copy.addNode(nodeId, { ...attributes }));
|
|
2092
|
+
graph.forEachEdge((edgeKey, attributes, source, target) => {
|
|
2093
|
+
copy.addEdgeWithKey(edgeKey, source, target, { ...attributes });
|
|
2094
|
+
});
|
|
2095
|
+
return copy;
|
|
2096
|
+
}
|
|
2097
|
+
function runAlgorithm(working, options) {
|
|
2098
|
+
const rng = mulberry32(FIXED_SEED);
|
|
2099
|
+
if (options.algorithm === "leiden") {
|
|
2100
|
+
const undirected = toUndirectedCopy(working);
|
|
2101
|
+
leiden.assign(undirected, { rng, maxIterations: options.maxIterations ?? 0 });
|
|
2102
|
+
undirected.forEachNode((nodeId, attributes) => {
|
|
2103
|
+
working.setNodeAttribute(nodeId, "community", attributes.community);
|
|
2104
|
+
});
|
|
2105
|
+
return;
|
|
2106
|
+
}
|
|
2107
|
+
louvain.assign(working, { rng });
|
|
2108
|
+
}
|
|
2109
|
+
function cluster(graph, options = {}) {
|
|
2110
|
+
if (graph.order === 0) return graph;
|
|
2111
|
+
const working = sortedWorkingCopy(graph);
|
|
2112
|
+
runAlgorithm(working, options);
|
|
2113
|
+
const hubs = /* @__PURE__ */ new Map();
|
|
2114
|
+
working.forEachNode((nodeId) => {
|
|
2115
|
+
const community = working.getNodeAttribute(nodeId, "community");
|
|
2116
|
+
const degree = working.degree(nodeId);
|
|
2117
|
+
const current = hubs.get(community);
|
|
2118
|
+
if (!current || degree > current.degree) {
|
|
2119
|
+
hubs.set(community, { id: nodeId, degree });
|
|
2120
|
+
}
|
|
2121
|
+
});
|
|
2122
|
+
const membersByCommunity = /* @__PURE__ */ new Map();
|
|
2123
|
+
working.forEachNode((nodeId) => {
|
|
2124
|
+
const community = working.getNodeAttribute(nodeId, "community");
|
|
2125
|
+
const list = membersByCommunity.get(community);
|
|
2126
|
+
if (list) list.push(nodeId);
|
|
2127
|
+
else membersByCommunity.set(community, [nodeId]);
|
|
2128
|
+
});
|
|
2129
|
+
const labelByCommunity = /* @__PURE__ */ new Map();
|
|
2130
|
+
const hashByCommunity = /* @__PURE__ */ new Map();
|
|
2131
|
+
for (const [community, members] of membersByCommunity) {
|
|
2132
|
+
members.sort((a, b) => a.localeCompare(b));
|
|
2133
|
+
hashByCommunity.set(community, createHash("sha256").update(members.join("\n")).digest("hex"));
|
|
2134
|
+
const hub = hubs.get(community);
|
|
2135
|
+
const hubLabel = hub ? working.getNodeAttribute(hub.id, "label") : void 0;
|
|
2136
|
+
labelByCommunity.set(community, hubLabel && hubLabel.length > 0 ? hubLabel : `community-${community}`);
|
|
2137
|
+
}
|
|
2138
|
+
working.forEachNode((nodeId) => {
|
|
2139
|
+
const community = working.getNodeAttribute(nodeId, "community");
|
|
2140
|
+
graph.mergeNodeAttributes(nodeId, {
|
|
2141
|
+
community,
|
|
2142
|
+
communityLabel: labelByCommunity.get(community),
|
|
2143
|
+
communityHash: hashByCommunity.get(community)
|
|
2144
|
+
});
|
|
2145
|
+
});
|
|
2041
2146
|
return graph;
|
|
2042
2147
|
}
|
|
2043
2148
|
|
|
@@ -2235,99 +2340,6 @@ function resolveCrossFileReferences(extractions, options = {}) {
|
|
|
2235
2340
|
return { resolvedEndpoints, droppedPlaceholders };
|
|
2236
2341
|
}
|
|
2237
2342
|
|
|
2238
|
-
// src/cluster.ts
|
|
2239
|
-
import { createHash } from "crypto";
|
|
2240
|
-
import Graph2 from "graphology";
|
|
2241
|
-
import leiden from "@aflsolutions/graphology-communities-leiden";
|
|
2242
|
-
import louvain from "graphology-communities-louvain";
|
|
2243
|
-
var FIXED_SEED = 1592594996;
|
|
2244
|
-
function mulberry32(seed) {
|
|
2245
|
-
let a = seed >>> 0;
|
|
2246
|
-
return function next() {
|
|
2247
|
-
a = a + 1831565813 | 0;
|
|
2248
|
-
let t = Math.imul(a ^ a >>> 15, 1 | a);
|
|
2249
|
-
t = t + Math.imul(t ^ t >>> 7, 61 | t) ^ t;
|
|
2250
|
-
return ((t ^ t >>> 14) >>> 0) / 4294967296;
|
|
2251
|
-
};
|
|
2252
|
-
}
|
|
2253
|
-
function sortedWorkingCopy(graph) {
|
|
2254
|
-
const copy = new Graph2({ type: graph.type, multi: graph.multi, allowSelfLoops: graph.allowSelfLoops });
|
|
2255
|
-
const nodeIds = graph.nodes().sort((a, b) => a.localeCompare(b));
|
|
2256
|
-
for (const id of nodeIds) {
|
|
2257
|
-
copy.addNode(id, { ...graph.getNodeAttributes(id) });
|
|
2258
|
-
}
|
|
2259
|
-
const edgeEntries = [];
|
|
2260
|
-
graph.forEachEdge((edge, attributes, source, target) => {
|
|
2261
|
-
edgeEntries.push({ key: edge, source, target, attributes });
|
|
2262
|
-
});
|
|
2263
|
-
edgeEntries.sort(
|
|
2264
|
-
(a, b) => a.source.localeCompare(b.source) || a.target.localeCompare(b.target) || String(a.attributes.relation).localeCompare(String(b.attributes.relation))
|
|
2265
|
-
);
|
|
2266
|
-
for (const entry of edgeEntries) {
|
|
2267
|
-
copy.addEdgeWithKey(entry.key, entry.source, entry.target, { ...entry.attributes });
|
|
2268
|
-
}
|
|
2269
|
-
return copy;
|
|
2270
|
-
}
|
|
2271
|
-
function toUndirectedCopy(graph) {
|
|
2272
|
-
const copy = new Graph2({ type: "undirected", multi: true, allowSelfLoops: graph.allowSelfLoops });
|
|
2273
|
-
graph.forEachNode((nodeId, attributes) => copy.addNode(nodeId, { ...attributes }));
|
|
2274
|
-
graph.forEachEdge((edgeKey, attributes, source, target) => {
|
|
2275
|
-
copy.addEdgeWithKey(edgeKey, source, target, { ...attributes });
|
|
2276
|
-
});
|
|
2277
|
-
return copy;
|
|
2278
|
-
}
|
|
2279
|
-
function runAlgorithm(working, options) {
|
|
2280
|
-
const rng = mulberry32(FIXED_SEED);
|
|
2281
|
-
if (options.algorithm === "leiden") {
|
|
2282
|
-
const undirected = toUndirectedCopy(working);
|
|
2283
|
-
leiden.assign(undirected, { rng, maxIterations: options.maxIterations ?? 0 });
|
|
2284
|
-
undirected.forEachNode((nodeId, attributes) => {
|
|
2285
|
-
working.setNodeAttribute(nodeId, "community", attributes.community);
|
|
2286
|
-
});
|
|
2287
|
-
return;
|
|
2288
|
-
}
|
|
2289
|
-
louvain.assign(working, { rng });
|
|
2290
|
-
}
|
|
2291
|
-
function cluster(graph, options = {}) {
|
|
2292
|
-
if (graph.order === 0) return graph;
|
|
2293
|
-
const working = sortedWorkingCopy(graph);
|
|
2294
|
-
runAlgorithm(working, options);
|
|
2295
|
-
const hubs = /* @__PURE__ */ new Map();
|
|
2296
|
-
working.forEachNode((nodeId) => {
|
|
2297
|
-
const community = working.getNodeAttribute(nodeId, "community");
|
|
2298
|
-
const degree = working.degree(nodeId);
|
|
2299
|
-
const current = hubs.get(community);
|
|
2300
|
-
if (!current || degree > current.degree) {
|
|
2301
|
-
hubs.set(community, { id: nodeId, degree });
|
|
2302
|
-
}
|
|
2303
|
-
});
|
|
2304
|
-
const membersByCommunity = /* @__PURE__ */ new Map();
|
|
2305
|
-
working.forEachNode((nodeId) => {
|
|
2306
|
-
const community = working.getNodeAttribute(nodeId, "community");
|
|
2307
|
-
const list = membersByCommunity.get(community);
|
|
2308
|
-
if (list) list.push(nodeId);
|
|
2309
|
-
else membersByCommunity.set(community, [nodeId]);
|
|
2310
|
-
});
|
|
2311
|
-
const labelByCommunity = /* @__PURE__ */ new Map();
|
|
2312
|
-
const hashByCommunity = /* @__PURE__ */ new Map();
|
|
2313
|
-
for (const [community, members] of membersByCommunity) {
|
|
2314
|
-
members.sort((a, b) => a.localeCompare(b));
|
|
2315
|
-
hashByCommunity.set(community, createHash("sha256").update(members.join("\n")).digest("hex"));
|
|
2316
|
-
const hub = hubs.get(community);
|
|
2317
|
-
const hubLabel = hub ? working.getNodeAttribute(hub.id, "label") : void 0;
|
|
2318
|
-
labelByCommunity.set(community, hubLabel && hubLabel.length > 0 ? hubLabel : `community-${community}`);
|
|
2319
|
-
}
|
|
2320
|
-
working.forEachNode((nodeId) => {
|
|
2321
|
-
const community = working.getNodeAttribute(nodeId, "community");
|
|
2322
|
-
graph.mergeNodeAttributes(nodeId, {
|
|
2323
|
-
community,
|
|
2324
|
-
communityLabel: labelByCommunity.get(community),
|
|
2325
|
-
communityHash: hashByCommunity.get(community)
|
|
2326
|
-
});
|
|
2327
|
-
});
|
|
2328
|
-
return graph;
|
|
2329
|
-
}
|
|
2330
|
-
|
|
2331
2343
|
// src/analyze.ts
|
|
2332
2344
|
var ABSOLUTE_DEGREE_FLOOR = 10;
|
|
2333
2345
|
var MEAN_DEGREE_MULTIPLIER = 3;
|
|
@@ -3106,8 +3118,9 @@ export {
|
|
|
3106
3118
|
ExtractionValidationError,
|
|
3107
3119
|
validateExtraction,
|
|
3108
3120
|
buildGraph,
|
|
3109
|
-
|
|
3121
|
+
mergeExtractionsInto,
|
|
3110
3122
|
cluster,
|
|
3123
|
+
resolveCrossFileReferences,
|
|
3111
3124
|
analyze,
|
|
3112
3125
|
renderReport,
|
|
3113
3126
|
exportGraph,
|
|
@@ -3125,4 +3138,4 @@ export {
|
|
|
3125
3138
|
validateRules,
|
|
3126
3139
|
checkRules
|
|
3127
3140
|
};
|
|
3128
|
-
//# sourceMappingURL=chunk-
|
|
3141
|
+
//# sourceMappingURL=chunk-5Q4BCTMF.js.map
|