code-kg 0.1.1 → 0.1.2
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/server/ui.js +188 -12
- package/dist/server/ui.js.map +1 -1
- package/package.json +1 -1
package/dist/server/ui.js
CHANGED
|
@@ -572,14 +572,22 @@ function renderUiHtml() {
|
|
|
572
572
|
extremeEdges: ${graph_performance_1.GRAPH_PERFORMANCE_THRESHOLDS.extremeEdges}
|
|
573
573
|
};
|
|
574
574
|
const SEARCH_DEBOUNCE_MS = 150;
|
|
575
|
+
const RENDER_BUDGETS = {
|
|
576
|
+
normal: { nodes: Number.POSITIVE_INFINITY, edges: Number.POSITIVE_INFINITY },
|
|
577
|
+
degraded: { nodes: 18000, edges: 40000 },
|
|
578
|
+
extreme: { nodes: 9000, edges: 16000 }
|
|
579
|
+
};
|
|
580
|
+
const STATIC_LAYOUT_SPACING = 8.4;
|
|
575
581
|
|
|
576
582
|
const state = {
|
|
577
583
|
view: 'fileDeps',
|
|
578
584
|
graph: null,
|
|
579
|
-
graphData: { nodes: [], links: [] },
|
|
585
|
+
graphData: { nodes: [], links: [], nodeById: new Map() },
|
|
580
586
|
graphMeta: null,
|
|
581
587
|
perfMode: 'normal',
|
|
582
588
|
lastAppliedPerfMode: '',
|
|
589
|
+
defaultChargeForce: null,
|
|
590
|
+
staticLayoutApplied: false,
|
|
583
591
|
selectedNodeId: '',
|
|
584
592
|
searchTerm: '',
|
|
585
593
|
searchTimer: null,
|
|
@@ -693,6 +701,116 @@ function renderUiHtml() {
|
|
|
693
701
|
return 1;
|
|
694
702
|
}
|
|
695
703
|
|
|
704
|
+
function stableHash(value) {
|
|
705
|
+
const text = String(value || '');
|
|
706
|
+
let hash = 2166136261;
|
|
707
|
+
for (let index = 0; index < text.length; index += 1) {
|
|
708
|
+
hash ^= text.charCodeAt(index);
|
|
709
|
+
hash = Math.imul(hash, 16777619);
|
|
710
|
+
}
|
|
711
|
+
return hash >>> 0;
|
|
712
|
+
}
|
|
713
|
+
|
|
714
|
+
function shouldRenderByBudget(id, limit, total) {
|
|
715
|
+
if (!Number.isFinite(limit) || limit >= total) {
|
|
716
|
+
return true;
|
|
717
|
+
}
|
|
718
|
+
if (limit <= 0 || total <= 0) {
|
|
719
|
+
return false;
|
|
720
|
+
}
|
|
721
|
+
const sampleRatio = limit / total;
|
|
722
|
+
const threshold = Math.max(1, Math.floor(sampleRatio * 1000000));
|
|
723
|
+
return (stableHash(id) % 1000000) < threshold;
|
|
724
|
+
}
|
|
725
|
+
|
|
726
|
+
function applyStaticLayout() {
|
|
727
|
+
if (state.staticLayoutApplied || !state.graphData || !Array.isArray(state.graphData.nodes)) {
|
|
728
|
+
return;
|
|
729
|
+
}
|
|
730
|
+
const nodes = state.graphData.nodes;
|
|
731
|
+
for (let index = 0; index < nodes.length; index += 1) {
|
|
732
|
+
const node = nodes[index];
|
|
733
|
+
const radius = Math.sqrt(index + 1) * STATIC_LAYOUT_SPACING;
|
|
734
|
+
const angle = index * 2.399963229728653;
|
|
735
|
+
const x = Math.cos(angle) * radius;
|
|
736
|
+
const y = Math.sin(angle) * radius;
|
|
737
|
+
const z = ((index % 27) - 13) * (STATIC_LAYOUT_SPACING * 0.28);
|
|
738
|
+
node.x = x;
|
|
739
|
+
node.y = y;
|
|
740
|
+
node.z = z;
|
|
741
|
+
node.fx = x;
|
|
742
|
+
node.fy = y;
|
|
743
|
+
node.fz = z;
|
|
744
|
+
}
|
|
745
|
+
state.staticLayoutApplied = true;
|
|
746
|
+
}
|
|
747
|
+
|
|
748
|
+
function clearStaticLayout() {
|
|
749
|
+
if (!state.staticLayoutApplied || !state.graphData || !Array.isArray(state.graphData.nodes)) {
|
|
750
|
+
return;
|
|
751
|
+
}
|
|
752
|
+
for (const node of state.graphData.nodes) {
|
|
753
|
+
delete node.fx;
|
|
754
|
+
delete node.fy;
|
|
755
|
+
delete node.fz;
|
|
756
|
+
}
|
|
757
|
+
state.staticLayoutApplied = false;
|
|
758
|
+
}
|
|
759
|
+
|
|
760
|
+
function applyRenderBudget() {
|
|
761
|
+
if (!state.graphData || !Array.isArray(state.graphData.nodes) || !Array.isArray(state.graphData.links)) {
|
|
762
|
+
return;
|
|
763
|
+
}
|
|
764
|
+
|
|
765
|
+
const mode = state.perfMode;
|
|
766
|
+
const budget = RENDER_BUDGETS[mode] || RENDER_BUDGETS.normal;
|
|
767
|
+
const totalNodes = state.graphData.nodes.length;
|
|
768
|
+
const totalEdges = state.graphData.links.length;
|
|
769
|
+
const nodeById = state.graphData.nodeById instanceof Map ? state.graphData.nodeById : new Map();
|
|
770
|
+
|
|
771
|
+
for (const node of state.graphData.nodes) {
|
|
772
|
+
const pinned = Boolean(node.__selected || node.__matched);
|
|
773
|
+
const sampled = shouldRenderByBudget(node.id, budget.nodes, totalNodes);
|
|
774
|
+
node.__renderVisible = pinned || sampled;
|
|
775
|
+
}
|
|
776
|
+
|
|
777
|
+
for (const link of state.graphData.links) {
|
|
778
|
+
const sourceId = String(link.__sourceId || '');
|
|
779
|
+
const targetId = String(link.__targetId || '');
|
|
780
|
+
const sourceNode = nodeById.get(sourceId);
|
|
781
|
+
const targetNode = nodeById.get(targetId);
|
|
782
|
+
const forceVisible = Boolean(
|
|
783
|
+
link.__highlight ||
|
|
784
|
+
sourceId === state.selectedNodeId ||
|
|
785
|
+
targetId === state.selectedNodeId
|
|
786
|
+
);
|
|
787
|
+
|
|
788
|
+
if (forceVisible) {
|
|
789
|
+
if (sourceNode) {
|
|
790
|
+
sourceNode.__renderVisible = true;
|
|
791
|
+
}
|
|
792
|
+
if (targetNode) {
|
|
793
|
+
targetNode.__renderVisible = true;
|
|
794
|
+
}
|
|
795
|
+
}
|
|
796
|
+
}
|
|
797
|
+
|
|
798
|
+
for (const link of state.graphData.links) {
|
|
799
|
+
const sourceId = String(link.__sourceId || '');
|
|
800
|
+
const targetId = String(link.__targetId || '');
|
|
801
|
+
const sourceNode = nodeById.get(sourceId);
|
|
802
|
+
const targetNode = nodeById.get(targetId);
|
|
803
|
+
const forceVisible = Boolean(
|
|
804
|
+
link.__highlight ||
|
|
805
|
+
sourceId === state.selectedNodeId ||
|
|
806
|
+
targetId === state.selectedNodeId
|
|
807
|
+
);
|
|
808
|
+
const sampled = shouldRenderByBudget(link.id || (sourceId + ':' + targetId), budget.edges, totalEdges);
|
|
809
|
+
const endpointsVisible = Boolean(sourceNode && targetNode && sourceNode.__renderVisible && targetNode.__renderVisible);
|
|
810
|
+
link.__renderVisible = forceVisible || (sampled && endpointsVisible);
|
|
811
|
+
}
|
|
812
|
+
}
|
|
813
|
+
|
|
696
814
|
function setStatus(text, tone) {
|
|
697
815
|
els.status.textContent = text;
|
|
698
816
|
if (tone === 'error') {
|
|
@@ -737,18 +855,47 @@ function renderUiHtml() {
|
|
|
737
855
|
|
|
738
856
|
const mode = state.perfMode;
|
|
739
857
|
const graph = state.graph;
|
|
858
|
+
if (mode === 'extreme') {
|
|
859
|
+
applyStaticLayout();
|
|
860
|
+
} else {
|
|
861
|
+
clearStaticLayout();
|
|
862
|
+
}
|
|
863
|
+
|
|
864
|
+
if (typeof graph.numDimensions === 'function') {
|
|
865
|
+
graph.numDimensions(mode === 'normal' ? 3 : 2);
|
|
866
|
+
}
|
|
740
867
|
if (typeof graph.cooldownTicks === 'function') {
|
|
741
|
-
graph.cooldownTicks(mode === 'normal' ? 240 : mode === 'degraded' ?
|
|
868
|
+
graph.cooldownTicks(mode === 'normal' ? 240 : mode === 'degraded' ? 40 : 2);
|
|
742
869
|
}
|
|
743
870
|
if (typeof graph.cooldownTime === 'function') {
|
|
744
|
-
graph.cooldownTime(mode === 'normal' ? 15000 : mode === 'degraded' ?
|
|
871
|
+
graph.cooldownTime(mode === 'normal' ? 15000 : mode === 'degraded' ? 1800 : 100);
|
|
872
|
+
}
|
|
873
|
+
if (typeof graph.warmupTicks === 'function') {
|
|
874
|
+
graph.warmupTicks(mode === 'normal' ? 90 : mode === 'degraded' ? 20 : 0);
|
|
745
875
|
}
|
|
746
876
|
if (typeof graph.d3VelocityDecay === 'function') {
|
|
747
|
-
graph.d3VelocityDecay(mode === 'normal' ? 0.25 : mode === 'degraded' ? 0.
|
|
877
|
+
graph.d3VelocityDecay(mode === 'normal' ? 0.25 : mode === 'degraded' ? 0.52 : 0.9);
|
|
878
|
+
}
|
|
879
|
+
if (typeof graph.nodeResolution === 'function') {
|
|
880
|
+
graph.nodeResolution(mode === 'normal' ? 8 : mode === 'degraded' ? 5 : 3);
|
|
748
881
|
}
|
|
882
|
+
if (typeof graph.linkResolution === 'function') {
|
|
883
|
+
graph.linkResolution(mode === 'normal' ? 6 : mode === 'degraded' ? 2 : 1);
|
|
884
|
+
}
|
|
885
|
+
|
|
886
|
+
graph.linkOpacity(mode === 'normal' ? 0.66 : mode === 'degraded' ? 0.38 : 0.26);
|
|
887
|
+
graph.nodeRelSize(mode === 'normal' ? 3.2 : mode === 'degraded' ? 2.45 : 2.1);
|
|
749
888
|
|
|
750
|
-
|
|
751
|
-
|
|
889
|
+
if (typeof graph.d3Force === 'function') {
|
|
890
|
+
const currentCharge = graph.d3Force('charge');
|
|
891
|
+
if (mode === 'normal') {
|
|
892
|
+
if (state.defaultChargeForce && currentCharge == null) {
|
|
893
|
+
graph.d3Force('charge', state.defaultChargeForce);
|
|
894
|
+
}
|
|
895
|
+
} else if (currentCharge != null) {
|
|
896
|
+
graph.d3Force('charge', null);
|
|
897
|
+
}
|
|
898
|
+
}
|
|
752
899
|
|
|
753
900
|
try {
|
|
754
901
|
const renderer = typeof graph.renderer === 'function' ? graph.renderer() : null;
|
|
@@ -814,7 +961,8 @@ function renderUiHtml() {
|
|
|
814
961
|
__targetId: target,
|
|
815
962
|
type: edge.type,
|
|
816
963
|
__color: colorForEdge(edge.type),
|
|
817
|
-
__highlight: false
|
|
964
|
+
__highlight: false,
|
|
965
|
+
__renderVisible: true
|
|
818
966
|
};
|
|
819
967
|
}
|
|
820
968
|
|
|
@@ -836,11 +984,17 @@ function renderUiHtml() {
|
|
|
836
984
|
__color: colorForNode(type),
|
|
837
985
|
__searchText: (String(name) + ' ' + String(path) + ' ' + String(type)).toLowerCase(),
|
|
838
986
|
__matched: false,
|
|
839
|
-
__selected: false
|
|
987
|
+
__selected: false,
|
|
988
|
+
__renderVisible: true
|
|
840
989
|
};
|
|
841
990
|
}
|
|
842
991
|
|
|
843
|
-
|
|
992
|
+
const nodeById = new Map();
|
|
993
|
+
for (const node of nodes) {
|
|
994
|
+
nodeById.set(node.id, node);
|
|
995
|
+
}
|
|
996
|
+
|
|
997
|
+
return { nodes, links, nodeById };
|
|
844
998
|
}
|
|
845
999
|
|
|
846
1000
|
function ensureGraph() {
|
|
@@ -858,6 +1012,7 @@ function renderUiHtml() {
|
|
|
858
1012
|
.backgroundColor('#05060f')
|
|
859
1013
|
.showNavInfo(false)
|
|
860
1014
|
.nodeOpacity(0.95)
|
|
1015
|
+
.nodeVisibility((node) => node.__renderVisible !== false)
|
|
861
1016
|
.nodeLabel((node) => {
|
|
862
1017
|
if (state.perfMode === 'extreme' && !node.__selected) {
|
|
863
1018
|
return '';
|
|
@@ -892,8 +1047,9 @@ function renderUiHtml() {
|
|
|
892
1047
|
.linkWidth((link) => {
|
|
893
1048
|
const base = state.perfMode === 'normal' ? 0.75 : state.perfMode === 'degraded' ? 0.46 : 0.34;
|
|
894
1049
|
const highlight = state.perfMode === 'normal' ? 2.2 : state.perfMode === 'degraded' ? 1.35 : 1.05;
|
|
895
|
-
|
|
896
|
-
|
|
1050
|
+
return link.__highlight ? highlight : base;
|
|
1051
|
+
})
|
|
1052
|
+
.linkVisibility((link) => link.__renderVisible !== false)
|
|
897
1053
|
.linkDirectionalParticles((link) => {
|
|
898
1054
|
if (state.perfMode !== 'normal') {
|
|
899
1055
|
return 0;
|
|
@@ -916,6 +1072,9 @@ function renderUiHtml() {
|
|
|
916
1072
|
});
|
|
917
1073
|
|
|
918
1074
|
state.graph = graph;
|
|
1075
|
+
if (typeof graph.d3Force === 'function') {
|
|
1076
|
+
state.defaultChargeForce = graph.d3Force('charge');
|
|
1077
|
+
}
|
|
919
1078
|
applyGraphQualitySettings();
|
|
920
1079
|
state.lastAppliedPerfMode = state.perfMode;
|
|
921
1080
|
|
|
@@ -968,9 +1127,24 @@ function renderUiHtml() {
|
|
|
968
1127
|
state.lastAppliedPerfMode = state.perfMode;
|
|
969
1128
|
clearSearchTimer();
|
|
970
1129
|
}
|
|
1130
|
+
applyRenderBudget();
|
|
971
1131
|
|
|
1132
|
+
let visibleNodes = 0;
|
|
1133
|
+
for (const node of state.graphData.nodes) {
|
|
1134
|
+
if (node.__renderVisible !== false) {
|
|
1135
|
+
visibleNodes += 1;
|
|
1136
|
+
}
|
|
1137
|
+
}
|
|
1138
|
+
let visibleEdges = 0;
|
|
1139
|
+
for (const link of state.graphData.links) {
|
|
1140
|
+
if (link.__renderVisible !== false) {
|
|
1141
|
+
visibleEdges += 1;
|
|
1142
|
+
}
|
|
1143
|
+
}
|
|
972
1144
|
els.graphCounts.textContent =
|
|
973
|
-
'nodes: ' +
|
|
1145
|
+
'nodes: ' + visibleNodes + '/' + nodeCount +
|
|
1146
|
+
' | edges: ' + visibleEdges + '/' + edgeCount +
|
|
1147
|
+
' | mode: ' + String(state.perfMode).toUpperCase();
|
|
974
1148
|
|
|
975
1149
|
if (nodeCount === 0) {
|
|
976
1150
|
els.graphEmpty.style.display = 'grid';
|
|
@@ -1040,6 +1214,7 @@ function renderUiHtml() {
|
|
|
1040
1214
|
const view = state.view === 'all' ? 'all' : state.view;
|
|
1041
1215
|
const data = await readEnvelope('/api/graph?view=' + encodeURIComponent(view));
|
|
1042
1216
|
state.graphData = toGraphData(data);
|
|
1217
|
+
state.staticLayoutApplied = false;
|
|
1043
1218
|
state.graphMeta = normalizeGraphMeta(
|
|
1044
1219
|
data && data.meta ? data.meta : null,
|
|
1045
1220
|
state.graphData.nodes.length,
|
|
@@ -1239,6 +1414,7 @@ function renderUiHtml() {
|
|
|
1239
1414
|
'&direction=both'
|
|
1240
1415
|
);
|
|
1241
1416
|
state.graphData = toGraphData(data);
|
|
1417
|
+
state.staticLayoutApplied = false;
|
|
1242
1418
|
state.graphMeta = normalizeGraphMeta(
|
|
1243
1419
|
data && data.meta ? data.meta : null,
|
|
1244
1420
|
state.graphData.nodes.length,
|
package/dist/server/ui.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ui.js","sourceRoot":"","sources":["../../src/server/ui.ts"],"names":[],"mappings":";;AAEA,
|
|
1
|
+
{"version":3,"file":"ui.js","sourceRoot":"","sources":["../../src/server/ui.ts"],"names":[],"mappings":";;AAEA,oCAihDC;AAnhDD,2DAAmE;AAEnE,SAAgB,YAAY;IAC1B,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2BAmjBkB,gDAA4B,CAAC,aAAa;2BAC1C,gDAA4B,CAAC,aAAa;0BAC3C,gDAA4B,CAAC,YAAY;0BACzC,gDAA4B,CAAC,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;QAy9B3D,CAAC;AACT,CAAC"}
|