refactoring: graph state
This commit is contained in:
87
frontend/src/lib/graph/state.ts
Normal file
87
frontend/src/lib/graph/state.ts
Normal file
@@ -0,0 +1,87 @@
|
||||
/**
|
||||
* Central state contracts for the graph: in-memory graph, connection path (edge visuals),
|
||||
* and node display status. Use these types to keep state flow predictable and readable.
|
||||
*
|
||||
* ## State flow (high level)
|
||||
*
|
||||
* 1. **Graph state** (nodes, edges) – Owned by useGraphStateWithHistory, persisted by useCanvasGraph.
|
||||
* Updates via setNodes/setEdges (with undo) or setNodesSilent/setEdgesSilent (no history).
|
||||
*
|
||||
* 2. **Connection path state** – Owned by useCanvasConnectionPath, provided via FlowContext.
|
||||
* Nodes report lifecycle (updating / error / paused) via useSyncConnectionStatus; the hook
|
||||
* updates context sets. Edges read those sets and getConnectionStatus() to decide color (default / updating / paused / error).
|
||||
*
|
||||
* 3. **Node display state** – Each node type derives its own UI state (e.g. loading, success, error, initial).
|
||||
* Rendering node uses displayStatus from useRenderingNodeState; other nodes can use getNodeDisplayStatus().
|
||||
*/
|
||||
|
||||
import type { AppNode, AppEdge } from './nodeTypes'
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Graph state (in-memory)
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
/** In-memory graph: nodes and edges. Updated via setNodes/setEdges; history in useGraphStateWithHistory. */
|
||||
export type GraphState = {
|
||||
nodes: AppNode[]
|
||||
edges: AppEdge[]
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Connection path state (edge visuals and path animation)
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Slice of FlowContext that drives edge status and path animation.
|
||||
* Nodes report updating/error/paused via useSyncConnectionStatus; this state is derived from those reports.
|
||||
* Edges use pathNodeIds, pausedSegmentNodeIds, activeSegmentNodeIds, errorTargetNodeIds in getConnectionStatus().
|
||||
*/
|
||||
export type ConnectionPathState = {
|
||||
/** Node ids currently doing async work (e.g. render loading). Path edges show "updating" (blue). */
|
||||
connectionPathUpdatingNodeIds: string[]
|
||||
/** Node ids that triggered the update (e.g. config changed). Path = downstream(trigger) ∩ upstream(updating). */
|
||||
connectionPathTriggerNodeIds: string[]
|
||||
/** All node ids on the path. Edges with both endpoints here animate. */
|
||||
connectionPathNodeIds: Set<string>
|
||||
/** Path nodes in the paused segment (yellow edges). */
|
||||
connectionPathPausedSegmentNodeIds: Set<string>
|
||||
/** Path nodes in the active segment (blue edges). */
|
||||
connectionPathActiveSegmentNodeIds: Set<string>
|
||||
/** Node ids on hold (e.g. render in manual mode). */
|
||||
connectionPathPausedNodeIds: string[]
|
||||
/** Node ids with error (incoming edges show red). */
|
||||
connectionPathErrorNodeIds: string[]
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Node display status (for UI: status indicator, empty state)
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
/** Status for node UI: what to show in NodeStatusIndicator and empty/error states. */
|
||||
export type NodeDisplayStatus = 'initial' | 'loading' | 'success' | 'error'
|
||||
|
||||
/**
|
||||
* Derive display status from node state. Use in nodes to drive NodeStatusIndicator and empty/error UI.
|
||||
* Priority: loading > error > hasContent (success) > initial.
|
||||
*/
|
||||
export function getNodeDisplayStatus(state: {
|
||||
loading: boolean
|
||||
error: unknown
|
||||
hasContent: boolean
|
||||
}): NodeDisplayStatus {
|
||||
if (state.loading) return 'loading'
|
||||
if (state.error != null) return 'error'
|
||||
if (state.hasContent) return 'success'
|
||||
return 'initial'
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Stored graph state (persistence)
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
/** Shape of graph state when saved/loaded (e.g. localStorage). version for future migrations. */
|
||||
export type StoredGraphState = {
|
||||
version: number
|
||||
nodes: unknown[]
|
||||
edges: unknown[]
|
||||
}
|
||||
Reference in New Issue
Block a user