@tracegraph/graph-engine 0.1.4 → 0.2.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/index.d.mts +6 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.js +68 -1
- package/dist/index.mjs +68 -1
- package/package.json +3 -3
package/dist/index.d.mts
CHANGED
|
@@ -31,6 +31,12 @@ type GraphNode = {
|
|
|
31
31
|
size: number;
|
|
32
32
|
/** The original TraceEvent that produced this node. */
|
|
33
33
|
data: TraceEvent;
|
|
34
|
+
/**
|
|
35
|
+
* Set when this node represents N collapsed siblings of the same type.
|
|
36
|
+
* The label will already include the count; this field allows renderers
|
|
37
|
+
* to display a badge or different visual treatment.
|
|
38
|
+
*/
|
|
39
|
+
collapsedCount?: number;
|
|
34
40
|
};
|
|
35
41
|
type GraphEdgeType = 'parent' | 'parallel_branch';
|
|
36
42
|
type GraphEdge = {
|
package/dist/index.d.ts
CHANGED
|
@@ -31,6 +31,12 @@ type GraphNode = {
|
|
|
31
31
|
size: number;
|
|
32
32
|
/** The original TraceEvent that produced this node. */
|
|
33
33
|
data: TraceEvent;
|
|
34
|
+
/**
|
|
35
|
+
* Set when this node represents N collapsed siblings of the same type.
|
|
36
|
+
* The label will already include the count; this field allows renderers
|
|
37
|
+
* to display a badge or different visual treatment.
|
|
38
|
+
*/
|
|
39
|
+
collapsedCount?: number;
|
|
34
40
|
};
|
|
35
41
|
type GraphEdgeType = 'parent' | 'parallel_branch';
|
|
36
42
|
type GraphEdge = {
|
package/dist/index.js
CHANGED
|
@@ -170,7 +170,74 @@ function traceSessionToGraph(session) {
|
|
|
170
170
|
edges.push({ id: edgeId, source: sourceNodeId, target: targetNodeId, type: edgeType });
|
|
171
171
|
}
|
|
172
172
|
}
|
|
173
|
-
return { nodes, edges, captureLevel: session.captureLevel };
|
|
173
|
+
return collapseSiblings({ nodes, edges, captureLevel: session.captureLevel });
|
|
174
|
+
}
|
|
175
|
+
var SIBLING_COLLAPSE_THRESHOLD = 5;
|
|
176
|
+
function collapseSiblings(graph) {
|
|
177
|
+
const { nodes, edges, captureLevel } = graph;
|
|
178
|
+
if (nodes.length <= SIBLING_COLLAPSE_THRESHOLD * 2) {
|
|
179
|
+
return graph;
|
|
180
|
+
}
|
|
181
|
+
const nodeById = new Map(nodes.map((n) => [n.id, n]));
|
|
182
|
+
const childrenByParent = /* @__PURE__ */ new Map();
|
|
183
|
+
for (const edge of edges) {
|
|
184
|
+
if (!childrenByParent.has(edge.source)) {
|
|
185
|
+
childrenByParent.set(edge.source, /* @__PURE__ */ new Map());
|
|
186
|
+
}
|
|
187
|
+
const target = nodeById.get(edge.target);
|
|
188
|
+
if (!target) continue;
|
|
189
|
+
const typeMap = childrenByParent.get(edge.source);
|
|
190
|
+
if (!typeMap.has(target.type)) typeMap.set(target.type, []);
|
|
191
|
+
typeMap.get(target.type).push(edge.target);
|
|
192
|
+
}
|
|
193
|
+
const willCollapse = /* @__PURE__ */ new Set();
|
|
194
|
+
for (const typeMap of childrenByParent.values()) {
|
|
195
|
+
for (const nodeIds of typeMap.values()) {
|
|
196
|
+
if (nodeIds.length >= SIBLING_COLLAPSE_THRESHOLD) {
|
|
197
|
+
for (const id of nodeIds) willCollapse.add(id);
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
if (willCollapse.size === 0) return graph;
|
|
202
|
+
const summaryNodes = [];
|
|
203
|
+
const summaryEdges = [];
|
|
204
|
+
for (const [parentId, typeMap] of childrenByParent) {
|
|
205
|
+
if (willCollapse.has(parentId)) continue;
|
|
206
|
+
for (const [type, nodeIds] of typeMap) {
|
|
207
|
+
if (nodeIds.length < SIBLING_COLLAPSE_THRESHOLD) continue;
|
|
208
|
+
const first = nodeById.get(nodeIds[0]);
|
|
209
|
+
const typeName = type.replace(/_/g, " ");
|
|
210
|
+
const summaryId = `summary__${parentId}__${type}`;
|
|
211
|
+
summaryNodes.push({
|
|
212
|
+
id: summaryId,
|
|
213
|
+
label: `${typeName} \xD7${nodeIds.length}`,
|
|
214
|
+
type,
|
|
215
|
+
language: first.language,
|
|
216
|
+
framework: first.framework,
|
|
217
|
+
color: first.color,
|
|
218
|
+
size: Math.min(10, Math.ceil(Math.log10(nodeIds.length + 1)) + 3),
|
|
219
|
+
collapsedCount: nodeIds.length,
|
|
220
|
+
data: first.data
|
|
221
|
+
});
|
|
222
|
+
summaryEdges.push({
|
|
223
|
+
id: `${parentId}\u2192${summaryId}`,
|
|
224
|
+
source: parentId,
|
|
225
|
+
target: summaryId,
|
|
226
|
+
type: "parent"
|
|
227
|
+
});
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
return {
|
|
231
|
+
nodes: [
|
|
232
|
+
...nodes.filter((n) => !willCollapse.has(n.id)),
|
|
233
|
+
...summaryNodes
|
|
234
|
+
],
|
|
235
|
+
edges: [
|
|
236
|
+
...edges.filter((e) => !willCollapse.has(e.source) && !willCollapse.has(e.target)),
|
|
237
|
+
...summaryEdges
|
|
238
|
+
],
|
|
239
|
+
captureLevel
|
|
240
|
+
};
|
|
174
241
|
}
|
|
175
242
|
|
|
176
243
|
// src/signature.ts
|
package/dist/index.mjs
CHANGED
|
@@ -132,7 +132,74 @@ function traceSessionToGraph(session) {
|
|
|
132
132
|
edges.push({ id: edgeId, source: sourceNodeId, target: targetNodeId, type: edgeType });
|
|
133
133
|
}
|
|
134
134
|
}
|
|
135
|
-
return { nodes, edges, captureLevel: session.captureLevel };
|
|
135
|
+
return collapseSiblings({ nodes, edges, captureLevel: session.captureLevel });
|
|
136
|
+
}
|
|
137
|
+
var SIBLING_COLLAPSE_THRESHOLD = 5;
|
|
138
|
+
function collapseSiblings(graph) {
|
|
139
|
+
const { nodes, edges, captureLevel } = graph;
|
|
140
|
+
if (nodes.length <= SIBLING_COLLAPSE_THRESHOLD * 2) {
|
|
141
|
+
return graph;
|
|
142
|
+
}
|
|
143
|
+
const nodeById = new Map(nodes.map((n) => [n.id, n]));
|
|
144
|
+
const childrenByParent = /* @__PURE__ */ new Map();
|
|
145
|
+
for (const edge of edges) {
|
|
146
|
+
if (!childrenByParent.has(edge.source)) {
|
|
147
|
+
childrenByParent.set(edge.source, /* @__PURE__ */ new Map());
|
|
148
|
+
}
|
|
149
|
+
const target = nodeById.get(edge.target);
|
|
150
|
+
if (!target) continue;
|
|
151
|
+
const typeMap = childrenByParent.get(edge.source);
|
|
152
|
+
if (!typeMap.has(target.type)) typeMap.set(target.type, []);
|
|
153
|
+
typeMap.get(target.type).push(edge.target);
|
|
154
|
+
}
|
|
155
|
+
const willCollapse = /* @__PURE__ */ new Set();
|
|
156
|
+
for (const typeMap of childrenByParent.values()) {
|
|
157
|
+
for (const nodeIds of typeMap.values()) {
|
|
158
|
+
if (nodeIds.length >= SIBLING_COLLAPSE_THRESHOLD) {
|
|
159
|
+
for (const id of nodeIds) willCollapse.add(id);
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
if (willCollapse.size === 0) return graph;
|
|
164
|
+
const summaryNodes = [];
|
|
165
|
+
const summaryEdges = [];
|
|
166
|
+
for (const [parentId, typeMap] of childrenByParent) {
|
|
167
|
+
if (willCollapse.has(parentId)) continue;
|
|
168
|
+
for (const [type, nodeIds] of typeMap) {
|
|
169
|
+
if (nodeIds.length < SIBLING_COLLAPSE_THRESHOLD) continue;
|
|
170
|
+
const first = nodeById.get(nodeIds[0]);
|
|
171
|
+
const typeName = type.replace(/_/g, " ");
|
|
172
|
+
const summaryId = `summary__${parentId}__${type}`;
|
|
173
|
+
summaryNodes.push({
|
|
174
|
+
id: summaryId,
|
|
175
|
+
label: `${typeName} \xD7${nodeIds.length}`,
|
|
176
|
+
type,
|
|
177
|
+
language: first.language,
|
|
178
|
+
framework: first.framework,
|
|
179
|
+
color: first.color,
|
|
180
|
+
size: Math.min(10, Math.ceil(Math.log10(nodeIds.length + 1)) + 3),
|
|
181
|
+
collapsedCount: nodeIds.length,
|
|
182
|
+
data: first.data
|
|
183
|
+
});
|
|
184
|
+
summaryEdges.push({
|
|
185
|
+
id: `${parentId}\u2192${summaryId}`,
|
|
186
|
+
source: parentId,
|
|
187
|
+
target: summaryId,
|
|
188
|
+
type: "parent"
|
|
189
|
+
});
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
return {
|
|
193
|
+
nodes: [
|
|
194
|
+
...nodes.filter((n) => !willCollapse.has(n.id)),
|
|
195
|
+
...summaryNodes
|
|
196
|
+
],
|
|
197
|
+
edges: [
|
|
198
|
+
...edges.filter((e) => !willCollapse.has(e.source) && !willCollapse.has(e.target)),
|
|
199
|
+
...summaryEdges
|
|
200
|
+
],
|
|
201
|
+
captureLevel
|
|
202
|
+
};
|
|
136
203
|
}
|
|
137
204
|
|
|
138
205
|
// src/signature.ts
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tracegraph/graph-engine",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "Converts TraceSession to a graph structure; produces baselines, diffs, and findings",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"module": "dist/index.mjs",
|
|
@@ -19,8 +19,8 @@
|
|
|
19
19
|
"access": "public"
|
|
20
20
|
},
|
|
21
21
|
"dependencies": {
|
|
22
|
-
"@tracegraph/
|
|
23
|
-
"@tracegraph/
|
|
22
|
+
"@tracegraph/shared-types": "0.2.0",
|
|
23
|
+
"@tracegraph/trace-sanitizer": "0.2.0"
|
|
24
24
|
},
|
|
25
25
|
"scripts": {
|
|
26
26
|
"build": "tsup src/index.ts --format cjs,esm --dts --external '@tracegraph/*'",
|