lint: change folder names
This commit is contained in:
98
frontend/src/lib/graph/nodeLifecycle.ts
Normal file
98
frontend/src/lib/graph/nodeLifecycle.ts
Normal file
@@ -0,0 +1,98 @@
|
||||
/**
|
||||
* Node lifecycle: contract that nodes implement so the graph can show the right
|
||||
* connection status (edge colors) and path animation.
|
||||
*
|
||||
* ## Lifecycle phases (conceptual)
|
||||
*
|
||||
* - **Idle** – Node is not on an active path; edges to/from it use default style.
|
||||
* - **Trigger** – Node's output changed (e.g. config content, variable value). Reported
|
||||
* automatically when the node calls `updateData()` from useAbstractNode. Downstream
|
||||
* path is computed from triggers + updating nodes.
|
||||
* - **Updating** – Node is doing async work (e.g. agent running, renderer loading).
|
||||
* Report `updating: true` at start, `updating: false` when done. Incoming/outgoing
|
||||
* edges on the path show "updating" (blue).
|
||||
* - **Paused** – Node is on hold (e.g. agent waiting for Run after inputs changed).
|
||||
* Report `paused: true` when waiting, `paused: false` when not. Edges in the paused
|
||||
* segment show "paused" (yellow).
|
||||
* - **Error** – Node has an error to show. Report `error: true` when error is set,
|
||||
* `error: false` when cleared. Incoming edges to this node show "error" (red).
|
||||
*
|
||||
* ## Connection status integration
|
||||
*
|
||||
* Edge status is derived in getConnectionStatus() from the sets that this lifecycle
|
||||
* feeds: connectionPathUpdatingNodeIds, connectionPathPausedNodeIds,
|
||||
* connectionPathErrorNodeIds (plus path/paused segment from graphPath). Priority:
|
||||
* error > paused > updating > default.
|
||||
*
|
||||
* Nodes that can be updating, paused, or in error should call useSyncConnectionStatus()
|
||||
* with their current state so edges update correctly.
|
||||
*/
|
||||
|
||||
import { useContext, useEffect, useRef } from 'react'
|
||||
import FlowContext from './flowContext'
|
||||
|
||||
export type NodeLifecyclePhase = 'idle' | 'trigger' | 'updating' | 'paused' | 'error'
|
||||
|
||||
/**
|
||||
* State that drives connection status for this node.
|
||||
* Pass the current values from your node; the hook syncs them to FlowContext.
|
||||
*/
|
||||
export type NodeConnectionStatusState = {
|
||||
/** Node is doing async work (e.g. loading, running). Incoming/outgoing path edges show blue. */
|
||||
updating?: boolean
|
||||
/** Node has an error. Incoming edges to this node show red. */
|
||||
error?: boolean
|
||||
/** Node is on hold (e.g. agent waiting for Run). Path edges in paused segment show yellow. */
|
||||
paused?: boolean
|
||||
}
|
||||
|
||||
/**
|
||||
* Syncs this node's lifecycle state to FlowContext so connection status (edge colors)
|
||||
* and path animation are correct. Call once per node with the current updating/error/paused
|
||||
* state; the hook will add/remove this node from the appropriate sets.
|
||||
*
|
||||
* Use in any node that can be updating, in error, or paused:
|
||||
*
|
||||
* const [loading, setLoading] = useState(false)
|
||||
* const [error, setError] = useState(null)
|
||||
* const hasPendingInputs = ...
|
||||
* useSyncConnectionStatus(id, { updating: loading, error: !!error, paused: hasPendingInputs })
|
||||
*/
|
||||
export function useSyncConnectionStatus(
|
||||
nodeId: string,
|
||||
state: NodeConnectionStatusState
|
||||
): void {
|
||||
const ctx = useContext(FlowContext)
|
||||
const { updating, error, paused } = state
|
||||
const prevRef = useRef({ updating: false, error: false, paused: false })
|
||||
|
||||
useEffect(() => {
|
||||
const prev = prevRef.current
|
||||
const nowUpdating = Boolean(updating)
|
||||
const nowError = Boolean(error)
|
||||
const nowPaused = Boolean(paused)
|
||||
|
||||
if (prev.updating !== nowUpdating) {
|
||||
if (nowUpdating) ctx?.startConnectionPathUpdate?.(nodeId)
|
||||
else ctx?.endConnectionPathUpdate?.(nodeId)
|
||||
prev.updating = nowUpdating
|
||||
}
|
||||
if (prev.error !== nowError) {
|
||||
if (nowError) ctx?.addConnectionPathError?.(nodeId)
|
||||
else ctx?.removeConnectionPathError?.(nodeId)
|
||||
prev.error = nowError
|
||||
}
|
||||
if (prev.paused !== nowPaused) {
|
||||
if (nowPaused) ctx?.addConnectionPathPausedNode?.(nodeId)
|
||||
else ctx?.removeConnectionPathPausedNode?.(nodeId)
|
||||
prev.paused = nowPaused
|
||||
}
|
||||
|
||||
return () => {
|
||||
if (prevRef.current.updating) ctx?.endConnectionPathUpdate?.(nodeId)
|
||||
if (prevRef.current.error) ctx?.removeConnectionPathError?.(nodeId)
|
||||
if (prevRef.current.paused) ctx?.removeConnectionPathPausedNode?.(nodeId)
|
||||
prevRef.current = { updating: false, error: false, paused: false }
|
||||
}
|
||||
}, [nodeId, updating, error, paused, ctx])
|
||||
}
|
||||
Reference in New Issue
Block a user