Skip to content

Conversation

AustinMroz
Copy link
Collaborator

@AustinMroz AustinMroz commented Sep 17, 2025

Implements proxyWidget support on subgraph nodes.
This registers a special proxyWidgets property on subgraph nodes which is directly mapped to the proxyWidgets displayed on the node with no duplication of state. Each proxyWidget directly maps to a real widget inside the subgraph.

Areas of concern

  • The proxyWidgets property is serialized as a string on every access. Litegraph fully supports leaving this as a list, but this is safer than risking breakage by changing types, is 3-4 orders of magnitude less important than the performance of the proxying code, and provides a chance to slot in validation
  • The code is applied by patching SubgraphNode._internalConfigureAfterSlots. SubgraphNodes are a little jank because they sometimes are configured twice on initialization and this call deletes all widgets on the node each time. As there is no duplication of state, if the code is applied after the first call, all widgets are cleared from the node on the second. setTimeout was previously utilized, but makes for a much uglier workaround.
    • Code now uses the standardised onConfigured callback.
  • The proxying code itself. Don't be fooled by the any cast. Typescript doesn't seem to bother checking types on reflection and the degree of wrapping is rather heavy handed.
  • The location where this code is stored. Placing code in scripts isn't great, but it puts it adjacent to the similar DOMWidget code and is consistent with simple act of importing the code applying side effects. Placing the code inside litegraph itself was originally attempted, but non-viable. The code requires access to multiple stores, including the domWidgetstore in order to manage state.

┆Issue is synchronized with this Notion page by Unito

@AustinMroz AustinMroz requested review from a team as code owners September 17, 2025 03:07
@dosubot dosubot bot added the size:L This PR changes 100-499 lines, ignoring generated files. label Sep 17, 2025
Copy link

github-actions bot commented Sep 17, 2025

🎭 Playwright Test Results

⚠️ Tests passed with flaky tests

⏰ Completed at: 09/25/2025, 01:50:55 AM UTC

📈 Summary

  • Total Tests: 458
  • Passed: 426 ✅
  • Failed: 0
  • Flaky: 3 ⚠️
  • Skipped: 29 ⏭️

📊 Test Reports by Browser

  • chromium: View Report • ✅ 419 / ❌ 0 / ⚠️ 3 / ⏭️ 29
  • chromium-2x: View Report • ✅ 2 / ❌ 0 / ⚠️ 0 / ⏭️ 0
  • chromium-0.5x: View Report • ✅ 1 / ❌ 0 / ⚠️ 0 / ⏭️ 0
  • mobile-chrome: View Report • ✅ 4 / ❌ 0 / ⚠️ 0 / ⏭️ 0

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

christian-byrne

This comment was marked as spam.

christian-byrne

This comment was marked as spam.

christian-byrne

This comment was marked as spam.

Copy link
Contributor

@christian-byrne christian-byrne left a comment

Choose a reason for hiding this comment

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

Could we move all the files to src/core/graph/subgraph

@christian-byrne
Copy link
Contributor

Sorry Claude review went haywire.

@christian-byrne
Copy link
Contributor

The lint staged should pass if you rebase, since the knip config file was added to tsconfig include last week in #5662

Wrap onConfigure instead of _internalConfigureAfterSlots

Use previously set proxyWidgets property instead of calculating

Fix canvas preview image support

Split proxy handlers into individual functions.

Add additional tests
The code to reset display of proxied widgets before adding or removing
wasn't being filtered to just proxy widgets. This would cause other
promoted DOMWidgets to be hidden

Resolves a playwright test
@AustinMroz AustinMroz force-pushed the austin/widget-promotion-impl branch from 286832e to 49bb39d Compare September 24, 2025 20:01
Copy link

🔧 Auto-fixes Applied

This PR has been automatically updated to fix linting and formatting issues.

⚠️ Important: Your local branch is now behind. Run git pull before making additional changes to avoid conflicts.

Changes made:

  • ESLint auto-fixes
  • Prettier formatting

Comment on lines 42 to 45
const w = addProxyWidget(this, `${nodeId}`, widgetName)
if (w instanceof DOMWidgetImpl) {
const widgetState = widgetStates.get(w.id)
if (!widgetState) continue
Copy link
Contributor

@christian-byrne christian-byrne Sep 24, 2025

Choose a reason for hiding this comment

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

question (non-blocking): What would it mean if the condition if (!widgetState) is true?

At this point in the code, we have already called addProxyWidget, so if it turns out w is a DOM widget but isn't in the widgetStates map, what does that mean for us? Do we need some sort of transaction logic or to move the check for this before we create the proxy?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

While the check was added to satisfy type guards and this shouldn't ever come up, it does make a good question. Particularly for the subsequent "set active" code.

A DOMWidget that somehow doesn't exist in the store can't be displayed. Ignoring a widget was fine previously when the getter was calculating from the actual widgets, but now it causes a desync of state. 🤔

Will think on it a bit more, but I'm ever-so-slightly leaning towards throwing an error. If this ever comes up in the future, we'd want to be notified either when testing or through sentry.

Adds additional documentation

Moves modifications to widget state into functions in the
domWidgetStore

Moves types to the start of the file

Throw an error on failed validation of a proxyWidget property
Copy link
Contributor

@arjansingh arjansingh left a comment

Choose a reason for hiding this comment

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

Only got a nit.

Copy link
Contributor

@christian-byrne christian-byrne left a comment

Choose a reason for hiding this comment

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

LGTM

@AustinMroz AustinMroz merged commit 9678a87 into main Sep 26, 2025
21 checks passed
@AustinMroz AustinMroz deleted the austin/widget-promotion-impl branch September 26, 2025 15:24
christian-byrne pushed a commit that referenced this pull request Sep 27, 2025
Implements proxyWidget support on subgraph nodes.  This registers a
special proxyWidgets property on subgraph nodes which is directly mapped
to the proxyWidgets displayed on the node. Each proxyWidget directly
maps to a real widget inside the subgraph.

┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-5617-Subgraph-widget-promotion-Part-2-2716d73d3650813d8621fefdce6ae518)
by [Unito](https://www.unito.io)

---------

Co-authored-by: GitHub Action <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area:subgraph size:L This PR changes 100-499 lines, ignoring generated files.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants