Skip to content

Conversation

christian-byrne
Copy link
Contributor

@christian-byrne christian-byrne commented Oct 6, 2025

Summary

Fixes issue where node size changes are not serialized by routing DOM-driven node bounds updates through a single CRDT operation so Vue node geometry stays synchronized with LiteGraph.

Changes

  • What: Added BatchUpdateBoundsOperation to the layout store, applied it via the existing Yjs pipeline, notified link sync to recompute touched nodes, and covered the path with a regression test

Review Focus

Correctness of the new batch operation when multiple nodes update simultaneously, especially remote replay/undo scenarios and link geometry recomputation.

┆Issue is synchronized with this Notion page by Unito

Copy link

github-actions bot commented Oct 6, 2025

🎭 Playwright Test Results

⚠️ Tests passed with flaky tests

⏰ Completed at: 10/07/2025, 05:58:46 PM UTC

📈 Summary

  • Total Tests: 489
  • Passed: 457 ✅
  • Failed: 0
  • Flaky: 2 ⚠️
  • Skipped: 30 ⏭️

📊 Test Reports by Browser

  • chromium: View Report • ✅ 448 / ❌ 0 / ⚠️ 2 / ⏭️ 30
  • chromium-2x: View Report • ✅ 2 / ❌ 0 / ⚠️ 0 / ⏭️ 0
  • chromium-0.5x: View Report • ✅ 1 / ❌ 0 / ⚠️ 0 / ⏭️ 0
  • mobile-chrome: View Report • ✅ 6 / ❌ 0 / ⚠️ 0 / ⏭️ 0

🎉 Click on the links above to view detailed test results for each browser configuration.

Copy link

github-actions bot commented Oct 6, 2025

🎨 Storybook Build Status

Build completed successfully!

⏰ Completed at: 10/07/2025, 05:48:51 PM UTC

🔗 Links


🎉 Your Storybook is ready for review!

@christian-byrne christian-byrne force-pushed the vue-node/fix-layout-mutation branch from 5f682ef to 1a14c1c Compare October 7, 2025 17:46
@christian-byrne christian-byrne added the claude-review Add to trigger a PR code review from Claude Code label Oct 7, 2025
operation: BatchUpdateBoundsOperation,
change: LayoutChange
): void {
for (const nodeId of operation.nodeIds) {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[quality] medium Priority\n\nIssue: Missing null check for operation.nodeIds could cause runtime error\nContext: If nodeIds is undefined or null, the for loop will throw TypeError\nSuggestion: Add validation: if (!operation.nodeIds?.length) return at the start of the method

const ynode = this.ynodes.get(nodeId)
if (!ynode || !data) continue

this.spatialIndex.update(nodeId, data.bounds)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[performance] medium Priority\n\nIssue: Spatial index updates in loop may cause performance degradation for large batch operations\nContext: Each spatialIndex.update() call in the loop could trigger expensive rebalancing operations\nSuggestion: Consider batching spatial index updates or adding a batch update method to the spatial index if available

change.nodeIds.push(nodeId)
}

if (change.nodeIds.length) {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[quality] low Priority\n\nIssue: Change type is only set when nodes exist, but change object is still passed to observers\nContext: If all nodes are invalid/missing, change.type remains undefined but still gets processed\nSuggestion: Set change.type = 'batch' unconditionally at the start, or return early if no valid nodes


boundsRecord[nodeId] = {
bounds,
previousBounds: currentLayout.bounds
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[performance] low Priority\n\nIssue: Storing previousBounds for every node in batch operations increases memory footprint\nContext: For large batch operations (hundreds of nodes), this could create significant temporary memory usage\nSuggestion: Consider if previousBounds is actually needed for operation replay/undo, or if it can be computed on-demand

type: 'batchUpdate'
updates: Partial<NodeLayout>
previousValues: Partial<NodeLayout>
export interface BatchUpdateBoundsOperation extends OperationMeta {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[quality] medium Priority\n\nIssue: Interface extends OperationMeta but adds duplicate fields that may already exist\nContext: OperationMeta likely contains timestamp, source, actor fields that are being redefined here\nSuggestion: Verify OperationMeta interface and remove duplicate fields, or use intersection types properly

const newBounds = { x: 40, y: 60, width: 220, height: 120 }
layoutStore.batchUpdateNodeBounds([{ nodeId, bounds: newBounds }])

await new Promise((resolve) => setTimeout(resolve, 50))
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[quality] low Priority\n\nIssue: Test uses arbitrary timeout without proper synchronization\nContext: setTimeout(50) is brittle and may cause flaky tests on slower systems\nSuggestion: Use waitFor() or proper async synchronization instead of arbitrary timeouts

Copy link

@claude claude bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comprehensive PR Review

This review is generated by Claude. It may not always be accurate, as with human reviewers. If you believe that any of the comments are invalid or incorrect, please state why for each. For others, please implement the changes in one way or another.

Review Summary

PR: fix: emit layout change for batch node bounds (#5939)
Impact: 113 additions, 16 deletions across 4 files

Issue Distribution

  • Critical: 0
  • High: 0
  • Medium: 3
  • Low: 3

Category Breakdown

  • Architecture: 0 issues
  • Security: 0 issues
  • Performance: 2 issues
  • Code Quality: 4 issues

Key Findings

Architecture & Design

The implementation follows good CRDT patterns by routing DOM-driven node bounds updates through a single operation type. The new BatchUpdateBoundsOperation properly integrates with the existing Yjs-based layout store architecture and maintains consistency with other operation handlers.

Security Considerations

No security issues identified. The implementation properly validates node existence and doesn't expose any attack vectors.

Performance Impact

Two performance considerations:

  1. Spatial index updates in loops may cause performance degradation for large batch operations
  2. Storing previousBounds increases memory footprint during batch operations

Integration Points

The integration with useLinkLayoutSync correctly handles link recomputation for updated nodes. The test coverage adequately validates the new functionality.

Positive Observations

  • Good separation of concerns with dedicated operation type
  • Proper integration with existing CRDT pipeline
  • Comprehensive test coverage for the new functionality
  • Consistent error handling patterns with existing codebase
  • Clean type definitions for the new operation

Next Steps

  1. Address medium priority quality issues (null checks, type safety)
  2. Consider performance optimizations for large batch operations
  3. Replace arbitrary timeout in test with proper synchronization
  4. Validate OperationMeta interface usage in type definitions

This is a comprehensive automated review. For architectural decisions requiring human judgment, please request additional manual review.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area:vue-migration claude-review Add to trigger a PR code review from Claude Code
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant