Skip to content

[Enhancement] Replace JSON.parse(JSON.stringify()) with structuredClone() for object cloning #4696

@christian-byrne

Description

@christian-byrne

[Enhancement] Replace JSON.parse(JSON.stringify()) with structuredClone() for object cloning

Summary

Replace the current LiteGraph.cloneObject() implementation that uses JSON.parse(JSON.stringify()) with the modern structuredClone() API to fix circular reference bugs and improve type preservation.

Problem

The current cloning implementation has several issues:

  1. Throws on circular references - causes crashes when objects have circular refs
  2. Poor type preservation - Dates become strings, RegExp becomes {}, undefined becomes null
  3. Missing modern API adoption - structuredClone() has been available since 2022

Proposed Solution

Implement a hybrid approach with structuredClone() as primary method and JSON fallback:

cloneObject<T>(obj: T): T {
  if (obj == null) return obj
  
  if (typeof structuredClone !== 'undefined') {
    try {
      return structuredClone(obj)
    } catch (error) {
      console.warn('structuredClone failed, falling back to JSON method:', error)
    }
  }
  
  return JSON.parse(JSON.stringify(obj))
}

Benefits

  • Fixes circular reference crashes
  • Better type preservation (Dates, RegExp, undefined)
  • Improved performance (native implementation)
  • Backward compatibility (fallback for edge cases)

Impact Assessment

Risk Level: LOW

  • Compatibility: Already targeting ES2022/modern browsers
  • Usage sites: 6 locations, all handle plain data objects
  • Breaking changes: None expected (fallback maintains compatibility)
  • Performance: Neutral to positive

Affected Files

  • src/LiteGraphGlobal.ts - Main implementation
  • src/LGraphNode.ts - 4 usage sites (serialize, configure, clone)
  • src/subgraph/subgraphUtils.ts - 1 usage site (multiClone)

Testing Requirements

  • Circular reference handling
  • Date/RegExp preservation
  • undefined value handling
  • Widget value compatibility
  • Fallback behavior
  • Performance regression testing

Implementation Steps

  1. Phase 1: Replace cloneObject() with hybrid implementation
  2. Phase 2: Add comprehensive tests
  3. Phase 3: Monitor for any behavioral changes in production
  4. Phase 4: Consider removing fallback after confidence period

References

Priority

Medium - This fixes real bugs (circular references) and improves robustness, but doesn't block current functionality.


Acceptance Criteria:

  • LiteGraph.cloneObject() uses structuredClone() when available
  • Maintains fallback to JSON method for compatibility
  • All existing tests pass
  • New tests added for circular references and type preservation
  • No regressions in node serialization/deserialization
  • Performance neutral or improved

┆Issue is synchronized with this Notion page by Unito

Metadata

Metadata

Assignees

No one assigned

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions