@andespindola/brainlink 0.1.0-beta.64 → 0.1.0-beta.66
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.
|
@@ -573,7 +573,7 @@ const nodeBudgetForScale = (scale) => {
|
|
|
573
573
|
const layerFocusForScale = (scale) => {
|
|
574
574
|
const normalized = Math.max(0, Math.min(1, (scale - 0.06) / 0.94))
|
|
575
575
|
const shellCenter = Math.max(0.08, 0.96 - normalized * 0.86)
|
|
576
|
-
const shellWidth = Math.max(0.
|
|
576
|
+
const shellWidth = Math.max(0.24, 0.46 - normalized * 0.16)
|
|
577
577
|
const coreRadius = Math.max(0.06, 0.1 + normalized * 0.22)
|
|
578
578
|
const coreRatio = Math.max(0.2, Math.min(0.72, 0.24 + normalized * 0.48))
|
|
579
579
|
|
|
@@ -604,7 +604,7 @@ const selectLayeredNodesForScale = (sourceNodes, targetCount) => {
|
|
|
604
604
|
...item,
|
|
605
605
|
normalized: item.distance / maxDistance
|
|
606
606
|
}))
|
|
607
|
-
const desired = Math.max(
|
|
607
|
+
const desired = Math.max(260, Math.min(sourceNodes.length, targetCount * 2))
|
|
608
608
|
const coreTarget = Math.max(36, Math.min(desired - 8, Math.floor(desired * focus.coreRatio)))
|
|
609
609
|
const shellTarget = Math.max(12, desired - coreTarget)
|
|
610
610
|
const shellHalf = focus.shellWidth / 2
|
|
@@ -653,6 +653,62 @@ const selectLayeredNodesForScale = (sourceNodes, targetCount) => {
|
|
|
653
653
|
return merged.length > 0 ? merged : sourceNodes
|
|
654
654
|
}
|
|
655
655
|
|
|
656
|
+
const cursorWorldPoint = () => {
|
|
657
|
+
if (!state.cursor.inCanvas) {
|
|
658
|
+
return null
|
|
659
|
+
}
|
|
660
|
+
|
|
661
|
+
const rect = canvas.getBoundingClientRect()
|
|
662
|
+
const screenX = state.cursor.x - rect.left
|
|
663
|
+
const screenY = state.cursor.y - rect.top
|
|
664
|
+
return {
|
|
665
|
+
x: (screenX - state.transform.x) / state.transform.scale,
|
|
666
|
+
y: (screenY - state.transform.y) / state.transform.scale
|
|
667
|
+
}
|
|
668
|
+
}
|
|
669
|
+
|
|
670
|
+
const mergeUniqueNodes = (leftNodes, rightNodes, limit) => {
|
|
671
|
+
const merged = []
|
|
672
|
+
const ids = new Set()
|
|
673
|
+
|
|
674
|
+
const push = (node) => {
|
|
675
|
+
if (!node || ids.has(node.id) || merged.length >= limit) {
|
|
676
|
+
return
|
|
677
|
+
}
|
|
678
|
+
ids.add(node.id)
|
|
679
|
+
merged.push(node)
|
|
680
|
+
}
|
|
681
|
+
|
|
682
|
+
for (let index = 0; index < leftNodes.length && merged.length < limit; index += 1) {
|
|
683
|
+
push(leftNodes[index])
|
|
684
|
+
}
|
|
685
|
+
for (let index = 0; index < rightNodes.length && merged.length < limit; index += 1) {
|
|
686
|
+
push(rightNodes[index])
|
|
687
|
+
}
|
|
688
|
+
|
|
689
|
+
return merged
|
|
690
|
+
}
|
|
691
|
+
|
|
692
|
+
const selectAccessBridgeNodes = (sourceNodes, limit) => {
|
|
693
|
+
if (limit <= 0 || sourceNodes.length === 0) {
|
|
694
|
+
return []
|
|
695
|
+
}
|
|
696
|
+
|
|
697
|
+
const cursor = cursorWorldPoint()
|
|
698
|
+
const anchor = cursor ?? state.primaryHub ?? state.macroCenter ?? { x: 0, y: 0 }
|
|
699
|
+
return [...sourceNodes]
|
|
700
|
+
.sort((left, right) => {
|
|
701
|
+
const leftDistance = Math.hypot(left.x - anchor.x, left.y - anchor.y)
|
|
702
|
+
const rightDistance = Math.hypot(right.x - anchor.x, right.y - anchor.y)
|
|
703
|
+
if (leftDistance !== rightDistance) return leftDistance - rightDistance
|
|
704
|
+
const leftDegree = state.nodeDegrees.get(left.id) ?? 0
|
|
705
|
+
const rightDegree = state.nodeDegrees.get(right.id) ?? 0
|
|
706
|
+
if (leftDegree !== rightDegree) return rightDegree - leftDegree
|
|
707
|
+
return left.id.localeCompare(right.id)
|
|
708
|
+
})
|
|
709
|
+
.slice(0, limit)
|
|
710
|
+
}
|
|
711
|
+
|
|
656
712
|
const edgeIdentityKey = edge => {
|
|
657
713
|
if (!edge.target) return ''
|
|
658
714
|
const pair = edge.source < edge.target
|
|
@@ -1672,9 +1728,15 @@ const computeRenderVisibility = () => {
|
|
|
1672
1728
|
const sourceNodes = viewportNodes.length > 0 ? viewportNodes : state.visibleNodes
|
|
1673
1729
|
const sampleLimit = nodeBudgetForScale(state.transform.scale)
|
|
1674
1730
|
const layeredNodes = selectLayeredNodesForScale(sourceNodes, sampleLimit)
|
|
1675
|
-
const
|
|
1676
|
-
|
|
1677
|
-
|
|
1731
|
+
const bridgeLimit = Math.max(24, Math.min(180, Math.floor(sampleLimit * 0.26)))
|
|
1732
|
+
const bridgedNodes = mergeUniqueNodes(
|
|
1733
|
+
layeredNodes,
|
|
1734
|
+
selectAccessBridgeNodes(sourceNodes, bridgeLimit),
|
|
1735
|
+
Math.min(renderNodeBudget, sampleLimit + bridgeLimit)
|
|
1736
|
+
)
|
|
1737
|
+
const sampled = bridgedNodes.length > sampleLimit
|
|
1738
|
+
? sampleVisibleNodes(Math.min(sampleLimit, renderNodeBudget), bridgedNodes)
|
|
1739
|
+
: bridgedNodes.slice(0, Math.min(bridgedNodes.length, renderNodeBudget))
|
|
1678
1740
|
const sampledIds = new Set(sampled.map((node) => node.id))
|
|
1679
1741
|
let sampledEdges = state.transform.scale >= 0.035 ? collectVisibleEdgesForNodes(sampledIds) : []
|
|
1680
1742
|
let sampledNodes = ensureHubNodesInRenderedSet(sampled)
|
|
@@ -2133,6 +2195,13 @@ const bindEvents = () => {
|
|
|
2133
2195
|
})
|
|
2134
2196
|
canvas.addEventListener('wheel', handleWheelZoom, { passive: false })
|
|
2135
2197
|
canvas.addEventListener('dblclick', event => {
|
|
2198
|
+
const point = worldPoint(event)
|
|
2199
|
+
const node = hitNode(point)
|
|
2200
|
+
if (node) {
|
|
2201
|
+
selectNode(node, { openContent: true })
|
|
2202
|
+
return
|
|
2203
|
+
}
|
|
2204
|
+
|
|
2136
2205
|
const rect = canvas.getBoundingClientRect()
|
|
2137
2206
|
const cursorX = event.clientX - rect.left
|
|
2138
2207
|
const cursorY = event.clientY - rect.top
|
|
@@ -2192,8 +2261,8 @@ const bindEvents = () => {
|
|
|
2192
2261
|
settleNeighborhoodAroundNode(draggedNode)
|
|
2193
2262
|
markRenderDirty()
|
|
2194
2263
|
}
|
|
2195
|
-
if (draggedNode && !state.pointer.moved) selectNode(draggedNode, { openContent:
|
|
2196
|
-
if (!draggedNode && !state.pointer.moved) selectNode(state.hovered, { openContent:
|
|
2264
|
+
if (draggedNode && !state.pointer.moved) selectNode(draggedNode, { openContent: false })
|
|
2265
|
+
if (!draggedNode && !state.pointer.moved) selectNode(state.hovered, { openContent: false })
|
|
2197
2266
|
state.pointer = { x: 0, y: 0, down: false, dragNode: null, moved: false }
|
|
2198
2267
|
canvas.releasePointerCapture(event.pointerId)
|
|
2199
2268
|
})
|
package/package.json
CHANGED