@andespindola/brainlink 0.1.0-beta.51 → 0.1.0-beta.52

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.
@@ -17,7 +17,7 @@ const worldCoordinateLimit = 5_000_000
17
17
  const transformCoordinateLimit = 20_000_000
18
18
  const hoverHitTestIntervalMs = 64
19
19
  const overviewClusterMaxCount = 1400
20
- const zoomRecoveryGuardMs = 560
20
+ const zoomRecoveryGuardMs = 1500
21
21
  const state = {
22
22
  graph: { nodes: [], edges: [] },
23
23
  nodes: [],
@@ -601,6 +601,27 @@ const enrichSampleWithNeighbors = (nodes) => {
601
601
  }
602
602
  }
603
603
 
604
+ const ensureHubNodesInRenderedSet = (nodes) => {
605
+ if (nodes.length === 0) {
606
+ return nodes
607
+ }
608
+
609
+ const maxNodes = Math.max(renderNodeBudget, nodes.length)
610
+ const ids = new Set(nodes.map((node) => node.id))
611
+ const hubs = rankedHubNodes()
612
+ const merged = [...nodes]
613
+
614
+ for (let index = 0; index < hubs.length && merged.length < maxNodes; index += 1) {
615
+ const hub = hubs[index]
616
+ if (!ids.has(hub.id)) {
617
+ merged.push(hub)
618
+ ids.add(hub.id)
619
+ }
620
+ }
621
+
622
+ return merged
623
+ }
624
+
604
625
  const clampScale = value => Math.max(zoomRange.min, Math.min(zoomRange.max, value))
605
626
  const isFiniteNumber = value => Number.isFinite(value)
606
627
  const isReasonableCoordinate = value => isFiniteNumber(value) && Math.abs(value) <= worldCoordinateLimit
@@ -1100,12 +1121,13 @@ const computeRenderVisibility = () => {
1100
1121
  : sourceNodes.slice(0, Math.min(sourceNodes.length, renderNodeBudget))
1101
1122
  const sampledIds = new Set(sampled.map((node) => node.id))
1102
1123
  let sampledEdges = state.transform.scale >= 0.035 ? collectVisibleEdgesForNodes(sampledIds) : []
1103
- let sampledNodes = sampled
1124
+ let sampledNodes = ensureHubNodesInRenderedSet(sampled)
1104
1125
 
1105
1126
  if (state.transform.scale >= 0.035 && sampledEdges.length === 0) {
1106
- const enriched = enrichSampleWithNeighbors(sampled)
1107
- sampledNodes = enriched.nodes
1108
- sampledEdges = enriched.edges
1127
+ const enriched = enrichSampleWithNeighbors(sampledNodes)
1128
+ sampledNodes = ensureHubNodesInRenderedSet(enriched.nodes)
1129
+ const sampledWithHubsIds = new Set(sampledNodes.map((node) => node.id))
1130
+ sampledEdges = collectVisibleEdgesForNodes(sampledWithHubsIds)
1109
1131
  }
1110
1132
 
1111
1133
  state.renderClusters = []
@@ -1159,10 +1181,11 @@ const computeRenderVisibility = () => {
1159
1181
  return
1160
1182
  }
1161
1183
 
1162
- const nodeIds = new Set(nodes.map((node) => node.id))
1184
+ const normalizedNodes = ensureHubNodesInRenderedSet(nodes)
1185
+ const nodeIds = new Set(normalizedNodes.map((node) => node.id))
1163
1186
  const edges = collectVisibleEdgesForNodes(nodeIds)
1164
1187
 
1165
- state.renderNodes = nodes
1188
+ state.renderNodes = normalizedNodes
1166
1189
  state.renderEdges = edges
1167
1190
 
1168
1191
  if (state.renderNodes.length === 0 && state.visibleNodes.length > 0) {
@@ -1456,17 +1479,19 @@ const selectNodeById = id => {
1456
1479
  }
1457
1480
 
1458
1481
  const zoomAtPoint = (screenX, screenY, factor, source = 'generic') => {
1482
+ if (source === 'wheel') {
1483
+ state.lastManualZoomAt = performance.now()
1484
+ }
1459
1485
  const nextScale = clampScale(state.transform.scale * factor)
1460
- if (nextScale === state.transform.scale) return
1486
+ if (nextScale === state.transform.scale) {
1487
+ return
1488
+ }
1461
1489
  const worldX = (screenX - state.transform.x) / state.transform.scale
1462
1490
  const worldY = (screenY - state.transform.y) / state.transform.scale
1463
1491
  state.transform.scale = clampScale(nextScale)
1464
1492
  state.transform.x = clampTransformCoordinate(screenX - worldX * nextScale)
1465
1493
  state.transform.y = clampTransformCoordinate(screenY - worldY * nextScale)
1466
1494
  state.offscreenFrameCount = 0
1467
- if (source === 'wheel') {
1468
- state.lastManualZoomAt = performance.now()
1469
- }
1470
1495
  markRenderDirty()
1471
1496
  }
1472
1497
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@andespindola/brainlink",
3
- "version": "0.1.0-beta.51",
3
+ "version": "0.1.0-beta.52",
4
4
  "description": "Local-first knowledge memory for agents with Markdown, backlinks, indexing and context retrieval.",
5
5
  "type": "module",
6
6
  "license": "MIT",