78 lines
5.6 KiB
Markdown
78 lines
5.6 KiB
Markdown
# Codebase simplification and design patterns
|
||
|
||
This doc summarizes recent improvements and suggested next steps for readability, extension, and consistency.
|
||
|
||
## Done
|
||
|
||
### 1. Single place for template/reachability (DRY)
|
||
|
||
- **Added** `lib/graph/templateRefs.ts`: `isReachable`, `resolveExtendsRef`, `getTemplateRefs`.
|
||
- **Refactored** `config/renderingLogic.ts` and `useRenderingNodeState.ts` to use these helpers instead of duplicating the same logic.
|
||
- **Pattern:** Extract shared pure helpers into a small lib module; keep call sites thin and consistent.
|
||
|
||
### 2. Naming and comments
|
||
|
||
- **Renamed** `outputMenuRegistry.tsx` → `outputMenuHandlers.tsx` (no registry, only helpers).
|
||
- **Updated** `rendering.ts` and `sourceRenderingLogic.ts`: output menu is described as coming from the node descriptor (`getOutputMenuContent`), not a separate registry.
|
||
- **Documented** `NodeMenubar`: extra content can come from props or from the descriptor (`getNodeMenuExtraContent`).
|
||
- **Documented** `nodeTypes.ts`: clarifies React Flow types vs node type id (nodeRegistry).
|
||
|
||
### 3. Central pipeline entry
|
||
|
||
- **rendering.ts** documents the 3-step pipeline, how to add a source/output type, and points to `templateRefs.ts` for shared helpers.
|
||
|
||
### 4. Rendering signatures (pure module)
|
||
|
||
- **Added** `lib/graph/renderingSignatures.ts`: `buildConnectedNodeIds`, `buildSourceSignatures` (connectedNodeIds + all five signatures + sourceSignature).
|
||
- **Refactored** `useRenderingNodeState` to call `buildSourceSignatures` in a single useMemo; hook is shorter and signature logic is testable in isolation.
|
||
|
||
### 5. Canvas split
|
||
|
||
- **CanvasContextMenuContent** (`app/canvas/CanvasContextMenuContent.tsx`): context menu content (Create Node grouped by classification, Paste). CanvasPage passes `onCreateNode` and `onPaste`.
|
||
- **useCanvasConnectionPath** (`app/canvas/useCanvasConnectionPath.ts`): all connection-path state and callbacks (updating/trigger/paused/error node ids, path node ids, start/end update, add/remove paused/error). CanvasPage calls the hook with `edges` and passes the result into FlowContext.
|
||
|
||
### 6. useCanvasGraph and canvas graph utils
|
||
|
||
- **canvasGraphUtils.ts**: `getExampleGraph()`, `getInitialGraph(projectId)` (load from storage or return example). Example nodes/edges live here.
|
||
- **useCanvasGraph(projectId)**: wraps `useGraphStateWithHistory` with initial graph from `getInitialGraph(projectId)` and debounced save to storage when `projectId` is set. CanvasPage uses this instead of inline state + persistence.
|
||
|
||
### 7. Config types registry
|
||
|
||
- **configTypes.ts**: `configTypeRegistry` (Map), `registerConfigType(type)`, `getConfigTypes()`, `getConfigTypeIds()`, `registerBuiltinConfigTypes()`. Built-in types are in `BUILTIN_CONFIG_TYPES` and registered at app init. `getConfigType(id)` looks up in the registry; `getConfigTypeId(data)` uses registered ids. ConfigNode uses `getConfigTypes()` instead of `CONFIG_TYPES`. New output types can call `registerConfigType()` without editing the core array.
|
||
|
||
### 8. Consistent NodeLike / EdgeLike
|
||
|
||
- **templateRefs.ts**: `NodeLike` includes `type?: string`; both types documented. Single source of truth for minimal node/edge shape in the graph lib.
|
||
- **sourceRenderingLogic**: context uses `NodeLike[]` and `EdgeLike[]` from templateRefs.
|
||
- **renderingSignatures**: imports and re-exports `NodeLike` / `EdgeLike` from templateRefs; no local duplicate types.
|
||
- **config/renderingLogic**: uses context nodes/edges directly (no casts); `setVarInContext(src: NodeLike)`.
|
||
- **useRenderingNodeState**: casts to `NodeLike[]` / `EdgeLike[]` when calling `buildSourceSignatures` (types from renderingSignatures).
|
||
|
||
### 9. Graph state, connection state, and node display state
|
||
|
||
- **lib/graph/state.ts**: Central state contracts and flow doc.
|
||
- **GraphState** – in-memory nodes + edges (useGraphStateWithHistory, persisted by useCanvasGraph).
|
||
- **ConnectionPathState** – type describing the slice that drives edge status and path animation (trigger/updating/paused/error sets).
|
||
- **NodeDisplayStatus** – `'initial' | 'loading' | 'success' | 'error'` for node UI; **getNodeDisplayStatus({ loading, error, hasContent })**.
|
||
- **StoredGraphState** – shape for save/load (version + nodes + edges).
|
||
- **FlowContext**: Module doc splits value into (1) Graph state, (2) Connection path state, (3) UI state. Same flat props, clearer sections.
|
||
- **useGraphStateWithHistory**: JSDoc explains history (past/future), setNodes vs setNodesSilent, setStateImmediate.
|
||
- **recollectionGraphStorage**: Uses **StoredGraphState** from state.ts; re-exports type. Doc references state flow.
|
||
- **useRenderingNodeState**: Returns **displayStatus** (for NodeStatusIndicator/empty/error UI) and **lifecycle** (updating/error/paused for useSyncConnectionStatus). Hook calls useSyncConnectionStatus(id, state.lifecycle). Type includes RenderingNodeLifecycle.
|
||
- **RenderingNode**: Uses **state.displayStatus** for NodeStatusIndicator instead of computing status locally.
|
||
- **nodeLifecycle** and **connectionStatus**: Docs reference state.ts for overall state flow.
|
||
|
||
## Design patterns in use
|
||
|
||
| Pattern | Where |
|
||
|----------------|--------------------------------------------|
|
||
| **Registry** | nodeRegistry, sourceRenderingLogic |
|
||
| **Builder** | nodeTypeBuilder (descriptor per node type) |
|
||
| **Pipeline** | Resolve → Render → Display (rendering.ts) |
|
||
| **Strategy** | Source logic per node type; output menu per descriptor |
|
||
| **Shared helpers** | templateRefs, outputMenuHandlers, renderingUtils |
|
||
|
||
## Suggested next steps
|
||
|
||
- **CanvasPage**: Optional further split (e.g. move connection validation or node/edge change handlers into a hook) if the file grows again.
|