88 lines
3.9 KiB
TypeScript
88 lines
3.9 KiB
TypeScript
/**
|
||
* 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[]
|
||
}
|