fIx: smaller nits

This commit is contained in:
2026-03-20 00:04:46 +01:00
parent bc67d01bc2
commit c3cbe35883
21 changed files with 2093 additions and 116 deletions

View File

@@ -26,5 +26,19 @@ export {
selectRenamingNodeId,
selectFullscreenNodeId,
selectConnectionFrom,
// Fine-grained selectors
selectNodeById,
selectNodesById,
selectNodesByType,
selectNodeIdsByType,
selectEdgesBySource,
selectEdgesByTarget,
selectEdgesForNode,
selectNodeCount,
selectEdgeCount,
selectHasNode,
selectHasEdge,
// SVG detection
isSvgContent,
} from './canvasStore.selectors'
export type { ConnectionPathRole } from './canvasStore.selectors'

View File

@@ -10,10 +10,19 @@ import {
} from '@/lib/graph/graphologyPath'
import { getConnectionStatus, type ConnectionStatus } from '@/lib/graph/connectionStatus'
import type { CanvasStore } from './canvasStore.types'
import type { AppNode } from '@/lib/graph/nodeTypes'
import type { AppNode, AppEdge } from '@/lib/graph/nodeTypes'
export type ConnectionPathRole = 'trigger' | 'on-path' | null
// ---------------------------------------------------------------------------
// SVG Detection - Centralized logic for detecting SVG content
// ---------------------------------------------------------------------------
/** Check if a string contains SVG content. */
export function isSvgContent(content: string | null | undefined): boolean {
return Boolean(content?.trim() && /<svg[\s>]/i.test(content.trim()))
}
// ---------------------------------------------------------------------------
// Raw slices
// ---------------------------------------------------------------------------
@@ -38,6 +47,65 @@ export function selectEdges(state: CanvasStore) {
return state.graph.edges
}
// ---------------------------------------------------------------------------
// Fine-grained selectors for optimal re-rendering
// ---------------------------------------------------------------------------
/** Get a specific node by ID. */
export function selectNodeById(state: CanvasStore, nodeId: string): AppNode | undefined {
return state.graph.nodes.find((n) => n.id === nodeId)
}
/** Get multiple nodes by IDs. */
export function selectNodesById(state: CanvasStore, nodeIds: string[]): AppNode[] {
return state.graph.nodes.filter((n) => nodeIds.includes(n.id))
}
/** Get nodes by type. */
export function selectNodesByType(state: CanvasStore, nodeType: string): AppNode[] {
return state.graph.nodes.filter((n) => n.type === nodeType)
}
/** Get node IDs by type. */
export function selectNodeIdsByType(state: CanvasStore, nodeType: string): string[] {
return state.graph.nodes.filter((n) => n.type === nodeType).map((n) => n.id)
}
/** Get edges by source node ID. */
export function selectEdgesBySource(state: CanvasStore, sourceId: string): AppEdge[] {
return state.graph.edges.filter((e) => e.source === sourceId)
}
/** Get edges by target node ID. */
export function selectEdgesByTarget(state: CanvasStore, targetId: string): AppEdge[] {
return state.graph.edges.filter((e) => e.target === targetId)
}
/** Get all edges connected to a node (source or target). */
export function selectEdgesForNode(state: CanvasStore, nodeId: string): AppEdge[] {
return state.graph.edges.filter((e) => e.source === nodeId || e.target === nodeId)
}
/** Get node count. */
export function selectNodeCount(state: CanvasStore): number {
return state.graph.nodes.length
}
/** Get edge count. */
export function selectEdgeCount(state: CanvasStore): number {
return state.graph.edges.length
}
/** Check if a node exists. */
export function selectHasNode(state: CanvasStore, nodeId: string): boolean {
return state.graph.nodes.some((n) => n.id === nodeId)
}
/** Check if an edge exists. */
export function selectHasEdge(state: CanvasStore, source: string, target: string): boolean {
return state.graph.edges.some((e) => e.source === source && e.target === target)
}
// ---------------------------------------------------------------------------
// Derived path (Sets) depend on graph.edges + path primitive arrays
// ---------------------------------------------------------------------------