Files
2026-01-04 00:17:33 +01:00

11 KiB

VIEW-000: Foundation & Shared Utilities - CHANGELOG

Phases 1-3 Completed

Date: January 3, 2026
Duration: ~2 hours
Status: Core graph analysis utilities complete


Summary

Implemented the foundational graph analysis utilities that all visualization views will depend on. These utilities enable:

  • Connection chain tracing - Follow data flow upstream/downstream through the graph
  • Cross-component resolution - Track how components use each other and resolve component boundaries
  • Node categorization - Semantic grouping of nodes by purpose (visual, data, logic, events, etc.)
  • Duplicate detection - Find potential naming conflicts and issues

Files Created

Core Module Structure

packages/noodl-editor/src/editor/src/utils/graphAnalysis/
├── index.ts                    # Public API exports
├── types.ts                    # TypeScript type definitions
├── traversal.ts                # Connection chain tracing
├── crossComponent.ts           # Cross-component resolution
├── categorization.ts           # Node semantic categorization
└── duplicateDetection.ts       # Duplicate node detection

Phase 1: Core Traversal Utilities

types.ts - Type Definitions

Comprehensive TypeScript interfaces for all graph analysis operations:

  • ConnectionRef - Reference to a connection between ports
  • ConnectionPath - A point in a connection traversal path
  • TraversalResult - Result of tracing a connection chain
  • NodeSummary, ConnectionSummary, ComponentSummary - Data summaries
  • ComponentUsage, ExternalConnection - Cross-component types
  • DuplicateGroup, ConflictAnalysis - Duplicate detection types
  • CategorizedNodes - Node categorization results

traversal.ts - Graph Traversal Functions

Key Functions:

  1. traceConnectionChain() - Trace connections upstream or downstream

    • Follows connection chains through multiple nodes
    • Configurable max depth, branch handling
    • Can stop at specific node types
    • Detects cycles and component boundaries
    • Returns complete path with termination reason
  2. getConnectedNodes() - Get direct neighbors of a node

    • Returns both input and output connections
    • Deduplicated results
  3. getPortConnections() - Get all connections for a specific port

    • Filters by port name and direction
    • Returns ConnectionRef array
  4. buildAdjacencyList() - Build graph representation

    • Returns Map of node IDs to their connections
    • Useful for graph algorithms
  5. getAllConnections() - Get all connections in component

  6. findNodesOfType() - Find all nodes of a specific typename

Example Usage:

import { traceConnectionChain } from '@noodl-utils/graphAnalysis';

// Find what feeds into a Text node's 'text' input
const result = traceConnectionChain(component, textNodeId, 'text', 'upstream');

console.log(
  'Data flows through:',
  result.path.map((p) => p.node.label)
);
// Output: ['Text', 'Expression', 'Variable']

Phase 2: Cross-Component Resolution

crossComponent.ts - Component Boundary Handling

Key Functions:

  1. findComponentUsages() - Find where a component is used

    • Searches entire project
    • Returns component instance locations
    • Includes connected port information
  2. resolveComponentBoundary() - Trace through Component Inputs/Outputs

    • Resolves what connects to a Component Inputs node from parent
    • Resolves what Component Outputs connects to in parent
    • Returns external connection information
  3. buildComponentDependencyGraph() - Project component relationships

    • Returns nodes (components) and edges (usage)
    • Counts how many times each component uses another
  4. isComponentUsed() - Check if component is instantiated anywhere

  5. findUnusedComponents() - Find components not used in project

    • Excludes root component
    • Useful for cleanup
  6. getComponentDepth() - Get hierarchy depth

    • Depth 0 = root component
    • Depth 1 = used by root
    • Returns -1 if unreachable

Example Usage:

import { findComponentUsages, buildComponentDependencyGraph } from '@noodl-utils/graphAnalysis';

// Find all places "UserCard" is used
const usages = findComponentUsages(project, 'UserCard');
usages.forEach((usage) => {
  console.log(`Used in ${usage.usedIn.name}`);
});

// Build project-wide component graph
const graph = buildComponentDependencyGraph(project);
console.log(`Project has ${graph.nodes.length} components`);

Phase 3: Categorization & Duplicate Detection

categorization.ts - Semantic Node Grouping

Categories:

  • visual - Groups, Text, Image, Page Stack, etc.
  • data - Variables, Objects, Arrays
  • logic - Conditions, Expressions, Switches
  • events - Send/Receive Event, Component I/O
  • api - REST, Cloud Functions, JavaScript Function
  • navigation - Page Router, Navigate
  • animation - Value Changed, Did Mount, etc.
  • utility - Everything else

Key Functions:

  1. categorizeNodes() - Categorize all nodes in component

    • Returns nodes grouped by category and by type
    • Includes totals array
  2. getNodeCategory() - Get category for a node type

  3. isVisualNode(), isDataSourceNode(), isLogicNode(), isEventNode() - Type check helpers

  4. getNodeCategorySummary() - Get category counts sorted by frequency

  5. getNodeTypeSummary() - Get type counts with categories

Example Usage:

import { categorizeNodes, getNodeCategorySummary } from '@noodl-utils/graphAnalysis';

const categorized = categorizeNodes(component);
categorized.totals.forEach(({ category, count }) => {
  console.log(`${category}: ${count} nodes`);
});
// Output:
// visual: 45 nodes
// data: 12 nodes
// logic: 8 nodes
// ...

duplicateDetection.ts - Find Potential Issues

Key Functions:

  1. findDuplicatesInComponent() - Find nodes with same name + type

    • Groups by typename and label
    • Assigns severity based on node type:
      • info - General duplicates
      • warning - Data nodes (Variables, Objects, Arrays)
      • error - Event nodes with same channel name
  2. findDuplicatesInProject() - Find duplicates across all components

  3. analyzeDuplicateConflicts() - Detect actual conflicts

    • data-race - Multiple Variables writing to same output
    • name-collision - Multiple Events with same channel
    • state-conflict - Multiple Objects/Arrays with same name
  4. findSimilarlyNamedNodes() - Find typo candidates

    • Uses Levenshtein distance for similarity
    • Configurable threshold (default 0.8)

Example Usage:

import { findDuplicatesInComponent, analyzeDuplicateConflicts } from '@noodl-utils/graphAnalysis';

const duplicates = findDuplicatesInComponent(component);
const conflicts = analyzeDuplicateConflicts(duplicates);

conflicts.forEach((conflict) => {
  console.warn(`${conflict.conflictType}: ${conflict.description}`);
});
// Output:
// data-race: Multiple variables named "userData" connect to the same output node. Last write wins.

Code Quality

  • No TSFixme types used
  • Comprehensive JSDoc comments on all public functions
  • TypeScript strict mode compliance
  • Example code in all JSDoc blocks
  • Defensive null checks throughout
  • Pure functions (no side effects)
  • Clean public API via index.ts

Testing Strategy

Manual Testing Performed

  • All files compile without TypeScript errors
  • Functions can be imported via public API
  • Type definitions properly exported

Integration Testing (Next Steps)

When VIEW-001 is implemented, these utilities should be tested with:

  • Large projects (100+ components, 1000+ nodes)
  • Deep component hierarchies (5+ levels)
  • Complex connection chains (10+ hops)
  • Edge cases (cycles, disconnected graphs, missing components)

Deferred Work

Phase 4: View Infrastructure

Status: Deferred until VIEW-001 requirements are known

The README proposes three UI patterns:

  1. Meta View Tabs - Replace canvas (Topology Map, Trigger Chain)
  2. Sidebar Panels - Alongside canvas (Census, X-Ray)
  3. Canvas Overlays - Enhance canvas (Data Lineage, Semantic Layers)

Decision: Build infrastructure when we know which pattern VIEW-001 needs. This avoids building unused code.

Phase 6: Debug Infrastructure Documentation

Status: Deferred until VIEW-003 (Trigger Chain Debugger) needs it

Tasks to complete later:

  • Document how DebugInspector works
  • Document runtime→canvas highlighting mechanism
  • Document runtime event emission
  • Create dev-docs/reference/DEBUG-INFRASTRUCTURE.md

Usage Example (Complete Workflow)

import {
  // Traversal
  traceConnectionChain,
  getConnectedNodes,
  // Cross-component
  findComponentUsages,
  buildComponentDependencyGraph,
  // Categorization
  categorizeNodes,
  getNodeCategorySummary,
  // Duplicate detection
  findDuplicatesInComponent,
  analyzeDuplicateConflicts
} from '@noodl-utils/graphAnalysis';

// 1. Analyze component structure
const categories = getNodeCategorySummary(component);
console.log('Most common category:', categories[0].category);

// 2. Find data flow paths
const dataFlow = traceConnectionChain(component, textNodeId, 'text', 'upstream', {
  stopAtTypes: ['Variable', 'Object']
});
console.log('Data source:', dataFlow.path[dataFlow.path.length - 1].node.label);

// 3. Check for issues
const duplicates = findDuplicatesInComponent(component);
const conflicts = analyzeDuplicateConflicts(duplicates);
if (conflicts.length > 0) {
  console.warn(`Found ${conflicts.length} potential conflicts`);
}

// 4. Analyze project structure
const usages = findComponentUsages(project, 'UserCard');
console.log(`UserCard used in ${usages.length} places`);

const graph = buildComponentDependencyGraph(project);
console.log(`Project has ${graph.edges.length} component relationships`);

Next Steps

Immediate (VIEW-001)

  1. Review VIEW-001 requirements to determine UI pattern needed
  2. Build view infrastructure based on actual needs
  3. Implement VIEW-001 using these graph analysis utilities

Future Views

  • VIEW-002: Component X-Ray (uses categorizeNodes, getConnectedNodes)
  • VIEW-003: Trigger Chain Debugger (needs Phase 6 debug docs first)
  • VIEW-004: Node Census (uses categorizeNodes, findDuplicatesInComponent)
  • VIEW-005: Data Lineage (uses traceConnectionChain, resolveComponentBoundary)
  • VIEW-006: Impact Radar (uses findComponentUsages, buildComponentDependencyGraph)
  • VIEW-007: Semantic Layers (uses categorizeNodes, canvas overlay pattern)

Success Criteria

  • Traversal functions work on complex graphs
  • Cross-component resolution handles nested components
  • Node categorization covers common node types
  • Duplicate detection identifies potential conflicts
  • All functions properly typed and documented
  • Clean public API established
  • Integration tested with VIEW-001 (pending)

Total Time Invested: ~2 hours
Lines of Code: ~1200
Functions Created: 26
Status: READY FOR VIEW-001