@andespindola/brainlink 0.1.0-beta.56 → 0.1.0-beta.58
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.
|
@@ -7,7 +7,7 @@ const renderNodeBudget = 900
|
|
|
7
7
|
const renderEdgeBudget = 2400
|
|
8
8
|
const clusterActivationNodeThreshold = 600
|
|
9
9
|
const clusterZoomThreshold = 0.18
|
|
10
|
-
const macroGalaxyZoomThreshold = 0.
|
|
10
|
+
const macroGalaxyZoomThreshold = 0.012
|
|
11
11
|
const massiveAutoFitMacroScale = 0.006
|
|
12
12
|
const defaultMacroScale = 0.006
|
|
13
13
|
const clusterCellPixelSize = 64
|
|
@@ -235,7 +235,6 @@ const normalizeQuery = value => value.trim().toLowerCase()
|
|
|
235
235
|
const hubNodeRetentionLimit = 2
|
|
236
236
|
const hubNodePattern = /\b(memory\s*hub|knowledge\s*hub|hub|moc|map|memory\s*map|mapa)\b/i
|
|
237
237
|
const memoryHubPathPattern = /\bmemory[-_\s]*hub\b/i
|
|
238
|
-
const isMemoryHubNode = node => node.title.trim().toLowerCase() === 'memory hub'
|
|
239
238
|
|
|
240
239
|
const hubNodeScore = node => {
|
|
241
240
|
const title = node.title.trim().toLowerCase()
|
|
@@ -310,13 +309,14 @@ const resolveMacroRepresentative = (nodes) => {
|
|
|
310
309
|
return null
|
|
311
310
|
}
|
|
312
311
|
|
|
313
|
-
const
|
|
314
|
-
|
|
315
|
-
|
|
312
|
+
const hubCandidate = state.primaryHub && nodes.some(node => node.id === state.primaryHub.id)
|
|
313
|
+
? state.primaryHub
|
|
314
|
+
: null
|
|
315
|
+
let best = hubCandidate ?? nodes[0]
|
|
316
316
|
let bestDegree = state.nodeDegrees.get(best.id) ?? 0
|
|
317
317
|
|
|
318
|
-
for (let index = 1; index <
|
|
319
|
-
const node =
|
|
318
|
+
for (let index = 1; index < nodes.length; index += 1) {
|
|
319
|
+
const node = nodes[index]
|
|
320
320
|
const degree = state.nodeDegrees.get(node.id) ?? 0
|
|
321
321
|
if (degree > bestDegree) {
|
|
322
322
|
best = node
|
|
@@ -710,9 +710,9 @@ const ensureHubNodesInRenderedSet = (nodes) => {
|
|
|
710
710
|
}
|
|
711
711
|
|
|
712
712
|
const zoomCapByNodeCount = (nodeCount) => {
|
|
713
|
-
if (nodeCount > 50000) return
|
|
714
|
-
if (nodeCount > 20000) return
|
|
715
|
-
if (nodeCount > 6000) return 1
|
|
713
|
+
if (nodeCount > 50000) return 2.6
|
|
714
|
+
if (nodeCount > 20000) return 2.35
|
|
715
|
+
if (nodeCount > 6000) return 2.1
|
|
716
716
|
if (nodeCount > 2000) return 2.2
|
|
717
717
|
return zoomRange.max
|
|
718
718
|
}
|
|
@@ -731,7 +731,9 @@ const zoomCapByHubDistance = (distance) => {
|
|
|
731
731
|
|
|
732
732
|
const currentZoomMax = () => {
|
|
733
733
|
const nodeCount = state.visibleNodes.length > 0 ? state.visibleNodes.length : state.nodes.length
|
|
734
|
-
const
|
|
734
|
+
const hubDistanceCap = zoomCapByHubDistance(state.hubNeighborDistance)
|
|
735
|
+
const minimumUsefulCap = nodeCount > massiveGraphNodeThreshold ? 1.9 : nodeCount > largeGraphNodeThreshold ? 1.35 : 0.8
|
|
736
|
+
const capped = Math.min(zoomCapByNodeCount(nodeCount), Math.max(minimumUsefulCap, hubDistanceCap))
|
|
735
737
|
return Math.max(zoomRange.min * 2, capped)
|
|
736
738
|
}
|
|
737
739
|
|
|
@@ -826,7 +828,9 @@ const fitView = (options = { useFiltered: true, macro: false, preferHubCenter: t
|
|
|
826
828
|
const macroScale = nodes.length > massiveGraphNodeThreshold ? massiveAutoFitMacroScale : defaultMacroScale
|
|
827
829
|
const scale = options.macro && nodes.length > 1
|
|
828
830
|
? clampScale(Math.min(baselineScale, macroScale))
|
|
829
|
-
:
|
|
831
|
+
: nodes.length > massiveGraphNodeThreshold
|
|
832
|
+
? clampScale(Math.min(baselineScale, massiveAutoFitMacroScale))
|
|
833
|
+
: baselineScale
|
|
830
834
|
const hubCenter =
|
|
831
835
|
options.preferHubCenter && state.primaryHub && nodes.some((node) => node.id === state.primaryHub.id)
|
|
832
836
|
? state.primaryHub
|
|
@@ -844,7 +848,7 @@ const fitView = (options = { useFiltered: true, macro: false, preferHubCenter: t
|
|
|
844
848
|
markRenderDirty()
|
|
845
849
|
}
|
|
846
850
|
|
|
847
|
-
const resetView = () => fitView({ useFiltered: false, macro:
|
|
851
|
+
const resetView = () => fitView({ useFiltered: false, macro: true, preferHubCenter: true })
|
|
848
852
|
|
|
849
853
|
const createLayout = graph => {
|
|
850
854
|
const nodeRows = Array.isArray(graph.nodes) ? graph.nodes : []
|
|
@@ -1064,7 +1068,12 @@ const hitNode = point => {
|
|
|
1064
1068
|
if (state.renderClusters.length > 0) {
|
|
1065
1069
|
return null
|
|
1066
1070
|
}
|
|
1067
|
-
|
|
1071
|
+
const hitScaleFloor = state.nodes.length > massiveGraphNodeThreshold
|
|
1072
|
+
? 0.2
|
|
1073
|
+
: state.nodes.length > largeGraphNodeThreshold
|
|
1074
|
+
? 0.34
|
|
1075
|
+
: 0
|
|
1076
|
+
if (state.transform.scale < hitScaleFloor) {
|
|
1068
1077
|
return null
|
|
1069
1078
|
}
|
|
1070
1079
|
|
|
@@ -1199,7 +1208,7 @@ const computeRenderVisibility = () => {
|
|
|
1199
1208
|
if (shouldRenderMacroGalaxy) {
|
|
1200
1209
|
const viewportNodes = viewportNodesFromSpatialIndex(viewport)
|
|
1201
1210
|
const sourceNodes = viewportNodes.length > 0 ? viewportNodes : state.visibleNodes
|
|
1202
|
-
const representative = state.macroRepresentative ?? sourceNodes[0] ?? null
|
|
1211
|
+
const representative = state.primaryHub ?? state.macroRepresentative ?? sourceNodes[0] ?? null
|
|
1203
1212
|
if (representative) {
|
|
1204
1213
|
state.renderClusters = [
|
|
1205
1214
|
{
|
|
@@ -1447,6 +1456,13 @@ const render = now => {
|
|
|
1447
1456
|
ctx.lineWidth = 1.4 / safeScale
|
|
1448
1457
|
ctx.strokeStyle = isMacro ? '#ffffff' : graphTheme.nodeStroke
|
|
1449
1458
|
ctx.stroke()
|
|
1459
|
+
if (isMacro && cluster.representative?.title) {
|
|
1460
|
+
ctx.fillStyle = '#edf2f7'
|
|
1461
|
+
ctx.font = 12 / safeScale + 'px Inter, system-ui, sans-serif'
|
|
1462
|
+
ctx.textAlign = 'center'
|
|
1463
|
+
ctx.textBaseline = 'top'
|
|
1464
|
+
ctx.fillText(cluster.representative.title.slice(0, 28), cluster.x, cluster.y + (radiusPx + 9) / safeScale)
|
|
1465
|
+
}
|
|
1450
1466
|
// Keep cluster markers minimal and faster to draw on large graphs.
|
|
1451
1467
|
})
|
|
1452
1468
|
} else {
|
|
@@ -1469,6 +1485,7 @@ const render = now => {
|
|
|
1469
1485
|
const shouldDrawLabels =
|
|
1470
1486
|
isSelected ||
|
|
1471
1487
|
isHovered ||
|
|
1488
|
+
(state.nodes.length > largeGraphNodeThreshold && state.transform.scale >= 0.62 && state.renderNodes.length <= 1200) ||
|
|
1472
1489
|
(state.nodes.length <= largeGraphNodeThreshold && (state.transform.scale > 1.18 || state.nodes.length <= 25))
|
|
1473
1490
|
if (shouldDrawLabels) {
|
|
1474
1491
|
ctx.fillStyle = graphTheme.label
|
|
@@ -1712,7 +1729,7 @@ const bindEvents = () => {
|
|
|
1712
1729
|
const point = worldPoint(event)
|
|
1713
1730
|
const now = performance.now()
|
|
1714
1731
|
const canHoverHitTest =
|
|
1715
|
-
!(state.nodes.length > massiveGraphNodeThreshold && state.transform.scale < 0.
|
|
1732
|
+
!(state.nodes.length > massiveGraphNodeThreshold && state.transform.scale < 0.06)
|
|
1716
1733
|
const shouldHitTest = canHoverHitTest &&
|
|
1717
1734
|
(state.pointer.down || now - state.lastHoverHitAt >= hoverHitTestIntervalMs)
|
|
1718
1735
|
if (shouldHitTest) {
|
package/package.json
CHANGED