diff --git a/.husky/pre-commit b/.husky/pre-commit.backup similarity index 100% rename from .husky/pre-commit rename to .husky/pre-commit.backup diff --git a/DEMO_READY_IMPLEMENTATION_PLAN.md b/DEMO_READY_IMPLEMENTATION_PLAN.md new file mode 100644 index 000000000..63339716b --- /dev/null +++ b/DEMO_READY_IMPLEMENTATION_PLAN.md @@ -0,0 +1,128 @@ +# Demo-Ready Vue Nodes Implementation Plan + +## Overview +Prepare the Vue node system for demo and developer handoff by implementing essential developer ergonomics and basic robustness. + +## Implementation Tasks + +### ✅ 1. Widget Component Integration (30 min) +**Goal**: Vue nodes render functional widgets +**Files**: +- `src/components/graph/vueNodes/LGraphNode.vue` (modify) +- `src/composables/graph/useWidgetRenderer.ts` (new) + +**Implementation**: +```typescript +// Add widget rendering to VueGraphNode component +
+ +
+``` + +### ✅ 2. Widget Registry Integration (45 min) +**Goal**: Connect existing Vue widgets to node system +**Files**: +- `src/composables/graph/useWidgetRenderer.ts` (new) +- Update widget registry mappings + +**Implementation**: +```typescript +// Map LiteGraph widget types to Vue components +const typeMap = { + 'number': 'WidgetSlider', + 'slider': 'WidgetSlider', + 'combo': 'WidgetSelect', + 'text': 'WidgetInputText', + 'toggle': 'WidgetToggleSwitch' +} +``` + +### ⏸️ 3. Feature Toggle System (20 min) +**Goal**: Production-safe feature flags +**Files**: +- `src/composables/useFeatureFlags.ts` (new) +- `src/constants/coreSettings.ts` (modify) + +### ⏸️ 4. Basic Error Boundaries +**Status**: Out of scope - already planned in Phase 5 +**Original Plan**: Comprehensive error boundaries with per-node error tracking in VUE_NODE_LIFECYCLE_DESIGN.md Phase 5 + +### ✅ 5. Developer Documentation (15 min) +**Goal**: Clear guide for developers +**Files**: `README_VUE_NODES.md` (new) + +### ✅ 6. Widget Value Synchronization (30 min) +**Goal**: Widget changes update LiteGraph +**Files**: `src/components/graph/vueNodes/LGraphNode.vue` (modify) + +**Implementation**: +```typescript +const handleWidgetChange = (widget: any, value: any) => { + widget.value = value + if (widget.callback) widget.callback(value, widget, node) + node.setDirtyCanvas(true, true) +} +``` + +### ✅ 7. Node Selection Sync (20 min) +**Goal**: Vue node selection syncs with LiteGraph +**Files**: `src/components/graph/vueNodes/LGraphNode.vue` (modify) + +### ✅ 8. Settings Integration (20 min) +**Goal**: Proper settings for Vue nodes +**Files**: `src/constants/coreSettings.ts` (modify) + +## Success Criteria + +### Demo Requirements +- [ ] Vue nodes render with functional widgets +- [ ] Widget interactions work (toggle, slider, text input) +- [ ] Node selection syncs between Vue and canvas +- [ ] Feature can be safely enabled/disabled +- [ ] Clear documentation for developers + +### Developer Handoff Requirements +- [ ] Widget components ready to use +- [ ] Clear patterns and examples +- [ ] Integration points documented +- [ ] Debug tools available +- [ ] Safe defaults (feature flagged off) + +## Implementation Order +1. Commit current progress (checkpoint) +2. Widget component integration + registry +3. Feature flags and settings +4. Developer documentation +5. Widget value synchronization +6. Node selection sync +7. Final testing and demo script + +## Timeline +**Target**: 3 hours total implementation time +**Demo Ready**: After items 1-2, 5-8 complete +**Production Ready**: After all items + Phase 3-5 from main plan + +## Files to Create/Modify + +### New Files +- `src/composables/graph/useWidgetRenderer.ts` +- `src/composables/useFeatureFlags.ts` +- `README_VUE_NODES.md` + +### Modified Files +- `src/components/graph/vueNodes/LGraphNode.vue` +- `src/constants/coreSettings.ts` +- `src/components/graph/GraphCanvas.vue` (feature flags) + +## Notes +- Error boundaries moved to Phase 5 (already planned) +- Focus on developer ergonomics over advanced features +- Maintain backward compatibility +- All changes feature-flagged for safety \ No newline at end of file diff --git a/src/components/graph/GraphCanvas.vue b/src/components/graph/GraphCanvas.vue index 8ef41fb34..1983fc16e 100644 --- a/src/components/graph/GraphCanvas.vue +++ b/src/components/graph/GraphCanvas.vue @@ -29,6 +29,109 @@ class="w-full h-full touch-none" /> + + + + + + + +
+

TransformPane Debug

+
+
+ +
+ + +
+

Canvas State

+

Status: {{ canvasStore.canvas ? 'Ready' : 'Not Ready' }}

+

Viewport: {{ Math.round(canvasViewport.width) }}x{{ Math.round(canvasViewport.height) }}

+ +
+ + +
+

Graph Metrics

+

Total Nodes: {{ comfyApp.graph?.nodes?.length || 0 }}

+

Selected Nodes: {{ canvasStore.canvas?.selectedItems?.size || 0 }}

+

Vue Nodes Rendered: {{ vueNodesCount }}

+

Nodes in Viewport: {{ nodesInViewport }}

+

Culled Nodes: {{ performanceMetrics.culledCount }}

+

Cull Percentage: {{ Math.round(((vueNodesCount - nodesInViewport) / Math.max(vueNodesCount, 1)) * 100) }}%

+
+ + +
+

Performance

+

FPS: {{ currentFPS }}

+

Transform Update: {{ Math.round(lastTransformTime) }}ms

+

Lifecycle Update: {{ Math.round(performanceMetrics.updateTime) }}ms

+

RAF Active: {{ rafActive ? 'Yes' : 'No' }}

+

Adaptive Quality: {{ performanceMetrics.adaptiveQuality ? 'On' : 'Off' }}

+
+ + +
+

Rendering Options

+ + +
+ + +
+ +
+
+
+ @@ -46,7 +149,7 @@ diff --git a/src/components/graph/TestTransformPane.vue b/src/components/graph/TestTransformPane.vue deleted file mode 100644 index 637550b05..000000000 --- a/src/components/graph/TestTransformPane.vue +++ /dev/null @@ -1,128 +0,0 @@ - - - diff --git a/src/components/graph/TransformPane.vue b/src/components/graph/TransformPane.vue index c294f35f9..a02ff07c9 100644 --- a/src/components/graph/TransformPane.vue +++ b/src/components/graph/TransformPane.vue @@ -18,7 +18,7 @@ import { useTransformState } from '@/composables/element/useTransformState' interface TransformPaneProps { canvas?: LGraphCanvas - viewport?: DOMRect + viewport?: { width: number; height: number } } const props = defineProps() @@ -76,10 +76,19 @@ const handlePointerDown = (event: PointerEvent) => { // Sync with canvas on RAF let rafId: number | null = null +const emit = defineEmits<{ + rafStatusChange: [active: boolean] + transformUpdate: [time: number] +}>() + const startSync = () => { + emit('rafStatusChange', true) const sync = () => { if (props.canvas) { + const startTime = performance.now() syncWithCanvas(props.canvas) + const endTime = performance.now() + emit('transformUpdate', endTime - startTime) } rafId = requestAnimationFrame(sync) } @@ -90,6 +99,7 @@ const stopSync = () => { if (rafId !== null) { cancelAnimationFrame(rafId) rafId = null + emit('rafStatusChange', false) } } diff --git a/src/components/graph/vueNodes/LGraphNode.vue b/src/components/graph/vueNodes/LGraphNode.vue index a5bd3031b..e37be696a 100644 --- a/src/components/graph/vueNodes/LGraphNode.vue +++ b/src/components/graph/vueNodes/LGraphNode.vue @@ -5,20 +5,21 @@
@@ -43,16 +44,18 @@ + + +
+ No widgets +
@@ -66,7 +69,7 @@ diff --git a/src/components/graph/vueNodes/NodeWidgets.vue b/src/components/graph/vueNodes/NodeWidgets.vue index b53b5c4e9..98e2b51dd 100644 --- a/src/components/graph/vueNodes/NodeWidgets.vue +++ b/src/components/graph/vueNodes/NodeWidgets.vue @@ -3,22 +3,23 @@ ⚠️ Node Widgets Error
- + class="widget-stub" + > +
{{ widget.name }}
+
+ {{ widget.type }}: {{ getWidgetValue(widget) }} +
+