@andespindola/brainlink 0.1.0-beta.89 → 0.1.0-beta.90
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/README.md +1 -1
- package/dist/application/frontend/client-js.js +59 -3
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -602,7 +602,7 @@ The graph UI shows:
|
|
|
602
602
|
- WebGL node and edge acceleration when supported, falling back to Canvas 2D without changing graph behavior
|
|
603
603
|
- compact macro-to-micro density progression so reset keeps the graph mass oriented and zoom-in separates local neighborhoods progressively
|
|
604
604
|
- graph camera treats hub-centered navigation as structural only when the hub is dominant; diffuse stress graphs reset and zoom around the full graph mass
|
|
605
|
-
- graph LOD progression: graphs up to 1000 notes render directly; larger graphs use a compact memory-hub-centered mesh of connected 1000-note points, zoom-in spreads only focused clusters into 250-note and 60-note subgraphs with aggregated real links, keeps parent points during expansion to avoid visual jumps, then progressively raises the focused node budget so local areas keep nearby notes and links visible
|
|
605
|
+
- graph LOD progression: graphs up to 1000 notes render directly; larger graphs use a compact memory-hub-centered mesh of connected 1000-note points, zoom-in spreads only focused clusters into 250-note and 60-note subgraphs with aggregated real links plus local sibling mesh links, keeps parent points during expansion to avoid visual jumps, then progressively raises the focused node budget so local areas keep nearby notes and links visible
|
|
606
606
|
|
|
607
607
|
The server indexes before starting by default. Use `--no-index` to skip that step:
|
|
608
608
|
|
|
@@ -26,6 +26,7 @@ const ecosystemActivationNodeThreshold = 1000
|
|
|
26
26
|
const ecosystemGroupSizes = [1000, 250, 60]
|
|
27
27
|
const ecosystemClusterEdgeLimit = 520
|
|
28
28
|
const ecosystemHubEdgeLimit = 120
|
|
29
|
+
const ecosystemSiblingEdgeLimit = 180
|
|
29
30
|
const ecosystemClusterScaleThreshold = 0.32
|
|
30
31
|
const ecosystemSubgraphScaleThreshold = 0.18
|
|
31
32
|
const ecosystemMicroScaleThreshold = 0.08
|
|
@@ -979,20 +980,74 @@ const selectHierarchicalEcosystemClusters = viewport => {
|
|
|
979
980
|
]
|
|
980
981
|
}
|
|
981
982
|
|
|
983
|
+
const ecosystemSiblingEdgesForClusters = (clusters, existingEdges) => {
|
|
984
|
+
const byParent = new Map()
|
|
985
|
+
for (let index = 0; index < clusters.length; index += 1) {
|
|
986
|
+
const cluster = clusters[index]
|
|
987
|
+
if (cluster.isHub || !cluster.parentId) {
|
|
988
|
+
continue
|
|
989
|
+
}
|
|
990
|
+
const siblings = byParent.get(cluster.parentId)
|
|
991
|
+
if (siblings) {
|
|
992
|
+
siblings.push(cluster)
|
|
993
|
+
} else {
|
|
994
|
+
byParent.set(cluster.parentId, [cluster])
|
|
995
|
+
}
|
|
996
|
+
}
|
|
997
|
+
|
|
998
|
+
const edges = []
|
|
999
|
+
for (const siblings of byParent.values()) {
|
|
1000
|
+
const ordered = [...siblings]
|
|
1001
|
+
.sort((left, right) => Math.atan2(left.y - (left.parentY ?? 0), left.x - (left.parentX ?? 0)) - Math.atan2(right.y - (right.parentY ?? 0), right.x - (right.parentX ?? 0)))
|
|
1002
|
+
for (let index = 0; index < ordered.length && edges.length < ecosystemSiblingEdgeLimit; index += 1) {
|
|
1003
|
+
const sourceCluster = ordered[index]
|
|
1004
|
+
const targetCluster = ordered[(index + 1) % ordered.length]
|
|
1005
|
+
if (!targetCluster || sourceCluster.id === targetCluster.id) {
|
|
1006
|
+
continue
|
|
1007
|
+
}
|
|
1008
|
+
const orderedIds = sourceCluster.id < targetCluster.id
|
|
1009
|
+
? [sourceCluster.id, targetCluster.id]
|
|
1010
|
+
: [targetCluster.id, sourceCluster.id]
|
|
1011
|
+
const key = orderedIds.join(':')
|
|
1012
|
+
if (existingEdges.has(key)) {
|
|
1013
|
+
continue
|
|
1014
|
+
}
|
|
1015
|
+
const edge = {
|
|
1016
|
+
id: key,
|
|
1017
|
+
sourceCluster,
|
|
1018
|
+
targetCluster,
|
|
1019
|
+
weight: 0.7,
|
|
1020
|
+
inferred: true
|
|
1021
|
+
}
|
|
1022
|
+
existingEdges.set(key, edge)
|
|
1023
|
+
edges.push(edge)
|
|
1024
|
+
}
|
|
1025
|
+
}
|
|
1026
|
+
|
|
1027
|
+
return edges
|
|
1028
|
+
}
|
|
1029
|
+
|
|
982
1030
|
const ecosystemEdgesForClusters = clusters => {
|
|
983
1031
|
const clusterById = new Map(clusters.map(cluster => [cluster.id, cluster]))
|
|
984
1032
|
const clusterIds = new Set(clusterById.keys())
|
|
985
|
-
const
|
|
1033
|
+
const levelsBySize = []
|
|
986
1034
|
for (let index = 0; index < clusters.length; index += 1) {
|
|
987
1035
|
const cluster = clusters[index]
|
|
988
1036
|
if (!cluster.size || cluster.isHub) continue
|
|
989
|
-
|
|
1037
|
+
if (!levelsBySize.some(level => level.size === cluster.size)) {
|
|
1038
|
+
levelsBySize.push({
|
|
1039
|
+
size: cluster.size,
|
|
1040
|
+
lookup: state.ecosystemNodeClusterBySize.get(cluster.size) ?? new Map()
|
|
1041
|
+
})
|
|
1042
|
+
}
|
|
990
1043
|
}
|
|
1044
|
+
levelsBySize.sort((left, right) => left.size - right.size)
|
|
991
1045
|
const resolveClusterForNode = nodeId => {
|
|
992
1046
|
if (state.ecosystemHubCluster?.nodeIds.includes(nodeId) && clusterIds.has(state.ecosystemHubCluster.id)) {
|
|
993
1047
|
return state.ecosystemHubCluster
|
|
994
1048
|
}
|
|
995
|
-
for (
|
|
1049
|
+
for (let index = 0; index < levelsBySize.length; index += 1) {
|
|
1050
|
+
const lookup = levelsBySize[index].lookup
|
|
996
1051
|
const cluster = lookup.get(nodeId)
|
|
997
1052
|
if (cluster && clusterIds.has(cluster.id)) {
|
|
998
1053
|
return clusterById.get(cluster.id) ?? cluster
|
|
@@ -1028,6 +1083,7 @@ const ecosystemEdgesForClusters = clusters => {
|
|
|
1028
1083
|
})
|
|
1029
1084
|
}
|
|
1030
1085
|
|
|
1086
|
+
ecosystemSiblingEdgesForClusters(clusters, edgeByClusterPair)
|
|
1031
1087
|
const edges = Array.from(edgeByClusterPair.values())
|
|
1032
1088
|
.sort((left, right) => right.weight - left.weight)
|
|
1033
1089
|
.slice(0, ecosystemClusterEdgeLimit)
|
package/package.json
CHANGED