Skip to content

fix: avoid double initialization of node context menu items#143

Merged
willeastcott merged 1 commit into
mainfrom
fix/structured-clone-context-menu
Apr 29, 2026
Merged

fix: avoid double initialization of node context menu items#143
willeastcott merged 1 commit into
mainfrom
fix/structured-clone-context-menu

Conversation

@willeastcott

@willeastcott willeastcott commented Apr 29, 2026

Copy link
Copy Markdown
Contributor

Summary

Fixes the runtime error thrown when adding a node to a Graph:

Failed to execute 'structuredClone' on 'Window':
() => this._createUnconnectedEdgeForNode(node, item.edgeType) could not be cloned.

This breaks every story in the published Storybook (and any consumer that builds nodes with contextMenuItems in the schema, e.g. the React example).

Root cause

Graph.createNode was initializing context menu items and then handing them to view.addNodeContextMenu, which eventually calls GraphViewNode.addContextMenu — which initializes them again:

  • First call: clones the schema items (no functions yet) and attaches onSelect callbacks.
  • Second call: hits structuredClone on items that now contain onSelect function references → throws.

The regression was exposed by #136, which replaced the custom deepCopyFunction with structuredClone. The previous custom deep-copy iterated with for...in and silently preserved function references, masking this latent double-initialization bug.

The other call site (GraphViewNode.updateNodeType) already passes raw schema items directly, confirming addContextMenu is the correct (single) place to initialize.

Fix

In Graph.createNode, pass nodeSchema.contextMenuItems directly to view.addNodeContextMenu. Initialization now happens exactly once inside GraphViewNode.addContextMenu.

if (nodeSchema.contextMenuItems) {
    this.view.addNodeContextMenu(node.id, nodeSchema.contextMenuItems);
}

No public API changes.

Fixes #141

Test plan

  • npm run lint passes
  • npm run storybook opens without the structuredClone error
  • Right-click a node in Directed Graph and Visual Programming Graph stories → context menu appears, items (e.g. "Delete Node", "Add ... Edge") are functional
  • The React example (https://playcanvas.github.io/pcui-graph/storybook/) renders without errors after release

`Graph.createNode` was calling `_initializeNodeContextMenuItems` and then
passing the result to `view.addNodeContextMenu`, which (via
`GraphViewNode.addContextMenu`) calls `_initializeNodeContextMenuItems`
again. The second invocation runs `structuredClone` on items that now
contain `onSelect` function references attached during the first
invocation, causing:

  Failed to execute 'structuredClone' on 'Window':
  () => this._createUnconnectedEdgeForNode(node, item.edgeType)
  could not be cloned.

This regression was exposed by #136 (replacing `deepCopyFunction` with
`structuredClone`); the previous custom deep-copy silently preserved
function references on objects, masking the latent bug.

Pass the raw schema items straight to `view.addNodeContextMenu` so
initialization happens exactly once inside `GraphViewNode.addContextMenu`,
matching the existing flow used by `updateNodeType`.

Fixed #141

Made-with: Cursor
@willeastcott willeastcott requested a review from Copilot April 29, 2026 14:10
@willeastcott willeastcott self-assigned this Apr 29, 2026
@willeastcott willeastcott added the bug Something isn't working label Apr 29, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Fixes a runtime structuredClone error when creating nodes with contextMenuItems by ensuring node context menu items are initialized exactly once (in GraphViewNode.addContextMenu), restoring Storybook and consumer functionality.

Changes:

  • Stop initializing/cloning nodeSchema.contextMenuItems inside Graph.createNode.
  • Pass raw schema contextMenuItems directly to view.addNodeContextMenu, avoiding double-initialization and cloning functions.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@willeastcott willeastcott merged commit bd5792d into main Apr 29, 2026
6 checks passed
@willeastcott willeastcott deleted the fix/structured-clone-context-menu branch April 29, 2026 14:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

React Example shows error

2 participants