Skip to content

Conversation

@DrJKL
Copy link
Contributor

@DrJKL DrJKL commented Feb 3, 2026

Summary

Implements Phase 1 of the Vue-owns-truth pattern for widget values. Widget values are now canonical in a Pinia store; widget.value delegates to the store while preserving full backward compatibility.

Changes

  • New store: src/stores/widgetValueStore.ts - centralized widget value storage with get/set/remove/removeNode API
  • BaseWidget integration: widget.value getter/setter now delegates to store when widget is associated with a node
  • LGraphNode wiring: addCustomWidget() automatically calls widget.setNodeId(this.id) to wire widgets to their nodes
  • Test fixes: Added Pinia setup to test files that use widgets

Why

This foundation enables:

  • Vue components to reactively bind to widget values via computed(() => store.get(...))
  • Future Yjs/CRDT backing for real-time collaboration
  • Cleaner separation between Vue state and LiteGraph rendering

Backward Compatibility

Extension Pattern Status
widget.value = x ✅ Works unchanged
node.widgets[i].value ✅ Works unchanged
widget.callback ✅ Still fires
node.onWidgetChanged ✅ Still fires

Testing

  • ✅ 4252 unit tests pass
  • ✅ Build succeeds

┆Issue is synchronized with this Notion page by Unito

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 3, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Adds a Pinia-backed WidgetValueStore and migrates widget metadata/value access to it; moves advanced/hidden flags to top-level widget fields; updates BaseWidget to register with the store; introduces global ID deduplication in LGraph; many tests updated to use Pinia and store-backed fixtures.

Changes

Cohort / File(s) Summary
Widget value store & tests
src/stores/widgetValueStore.ts, src/stores/widgetValueStore.test.ts
Add useWidgetValueStore (register/get/getNodeWidgets), WidgetState type and comprehensive unit tests for registration, retrieval, mutation and sync.
BaseWidget & widget plumbing
src/lib/litegraph/src/widgets/BaseWidget.ts, src/lib/litegraph/src/widgets/BaseWidget.test.ts, src/renderer/extensions/vueNodes/components/LGraphNodePreview.vue
BaseWidget now uses private _state, exposes getters/setters (label, hidden, disabled, advanced, promoted), value backed by _state, adds setNodeId() to register in store; tests verify store sync; preview adds nodeId per widget.
Renderer components & node widgets
src/renderer/extensions/vueNodes/components/NodeWidgets.vue, src/renderer/extensions/vueNodes/components/NodeWidgets.test.ts, src/renderer/extensions/vueNodes/components/NodeHeader.vue
Components read/write widget metadata and values via useWidgetValueStore; processed widgets include store-driven flags (hidden, advanced, label, value); update handlers persist to store before callbacks; tests/fixtures adjusted.
DOM widgets & composables
src/renderer/extensions/vueNodes/widgets/composables/useStringWidget.ts, src/renderer/extensions/vueNodes/widgets/composables/useMarkdownWidget.ts, src/renderer/extensions/vueNodes/widgets/composables/useWidgetRenderer.test.ts, src/renderer/extensions/vueNodes/widgets/components/WidgetSelectDefault.vue, src/renderer/extensions/vueNodes/widgets/components/WidgetSelectDropdown.vue, src/scripts/domWidget.ts
DOM widgets integrated with widgetValueStore (get/set fallbacks to DOM), some DOM field renamed (inputElelement), isVisible() now uses hidden, select components guard options.values with Array.isArray.
Right-side panel & shared filters
src/components/rightSidePanel/parameters/TabNormalInputs.vue, src/components/rightSidePanel/parameters/WidgetItem.vue, src/components/rightSidePanel/shared.ts
Visibility/filtering now reads w.hidden and w.advanced (still checks w.options?.canvasOnly); removed a side-effect call from a widgetValue getter.
Graph core: ID handling & node helpers
src/lib/litegraph/src/LGraph.ts, src/lib/litegraph/src/LGraph.test.ts, src/lib/litegraph/src/LGraphCanvas.ts, src/lib/litegraph/src/LGraphNode.ts, src/lib/litegraph/src/LGraphNode.test.ts, src/lib/litegraph/src/LGraphNode.widgetOrder.test.ts
LGraph adds private _state accessors, ensureGlobalIdUniqueness() and link remapping; Subgraph proxies root state; nodes register widgets when added; LGraphNode adds getLayoutWidgets() and hasAdvancedWidgets() used for layout and context-menu logic; tests updated for shared state and uniqueness.
Proxy widgets & utilities
src/core/graph/subgraph/proxyWidget.ts, src/core/graph/subgraph/proxyWidgetUtils.ts, src/core/graph/subgraph/proxyWidget.test.ts
Add label to proxy overlay; introduce getWidgetName() to normalize proxy vs non-proxy widget naming in matches/mapping; tests initialize Pinia in setup.
Extensions & feature handlers
src/extensions/core/groupNode.ts, src/extensions/core/uploadAudio.ts, src/extensions/core/previewAny.ts
Replace widget.type='hidden' with widget.hidden=true; uploadAudio and other widgets switched to store-backed accessors; preview widgets renamed to preview_markdown/preview_text and filtering broadened.
Types & utils
src/lib/litegraph/src/types/widgets.ts, src/lib/litegraph/src/utils/type.ts, src/scripts/metadata/png.ts
Add NodeBindable interface and isNodeBindable type guard; simplify IWidgetOptions/IBaseWidget generics; remove a KNIP ignore annotation (non-functional).
Tests & test setup changes
multiple *.test.ts (e.g., src/composables/graph/useGraphNodeManager.test.ts, src/core/graph/subgraph/proxyWidget.test.ts, src/lib/litegraph/.../*.test.ts, ...)
Many tests updated to initialize Pinia (createTestingPinia/setActivePinia), adopt store-backed fixtures, add nodeId to SafeWidgetData mocks, and assert store-backed behavior.
Browser tests & assets
browser_tests/tests/subgraph.spec.ts, browser_tests/tests/subgraph-duplicate-ids.spec.ts, browser_tests/assets/subgraphs/subgraph-nested-duplicate-ids.json
Add Playwright tests validating subgraph ID remapping and navigation; add nested subgraph JSON fixture with duplicate-ID scenario for end-to-end verification.

Sequence Diagram(s)

sequenceDiagram
    participant UI as Vue Component
    participant Store as WidgetValueStore
    participant Node as BaseWidget
    participant DOM as DOM Widget

    UI->>Store: read widgetState(nodeId, widgetName)
    Store-->>UI: reactive widgetState (value,label,hidden,advanced,options)
    UI->>Node: user interaction -> update handler
    Node->>Store: registerWidget(nodeId, widgetName) / set value
    Store-->>DOM: propagate reactive changes
    DOM-->>UI: UI reflects updated store-backed state
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Suggested labels

preview

Suggested reviewers

  • jtydhr88
  • christian-byrne
  • shinshin86

Poem

🐇 I hopped to the store with a jittery hop,

Widgets found a home where their values can stop,
Hidden flags tucked, advanced ones stand tall,
State hums through components — a synchronous ball,
I nibble a carrot and wag my soft tail.

🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 18.52% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarizes the main change: introducing a WidgetValueStore for centralized widget value management, which aligns with the PR's core objective and primary implementation.
Description check ✅ Passed The description is well-structured with a clear Summary, specific Changes section detailing the new store and integration points, a Why section explaining the benefits, comprehensive Backward Compatibility table, and testing confirmation. All required template sections are present and substantive.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch drjkl/widget-store

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions
Copy link

github-actions bot commented Feb 3, 2026

Playwright: ✅ 521 passed, 0 failed · 3 flaky

📊 Browser Reports
  • chromium: View Report (✅ 509 / ❌ 0 / ⚠️ 3 / ⏭️ 8)
  • chromium-2x: View Report (✅ 2 / ❌ 0 / ⚠️ 0 / ⏭️ 0)
  • chromium-0.5x: View Report (✅ 1 / ❌ 0 / ⚠️ 0 / ⏭️ 0)
  • mobile-chrome: View Report (✅ 9 / ❌ 0 / ⚠️ 0 / ⏭️ 0)

@github-actions
Copy link

github-actions bot commented Feb 3, 2026

🎨 Storybook Build Status

Build completed successfully!

⏰ Completed at: 02/11/2026, 02:23:35 AM UTC

🔗 Links


🎉 Your Storybook is ready for review!

@github-actions
Copy link

github-actions bot commented Feb 3, 2026

Bundle Size Report

Summary

  • Raw size: 19.8 MB baseline 19.8 MB — 🔴 +3.49 kB
  • Gzip: 4.23 MB baseline 4.23 MB — 🔴 +688 B
  • Brotli: 3.28 MB baseline 3.28 MB — 🔴 +395 B
  • Bundles: 235 current • 235 baseline • 111 added / 111 removed

Category Glance
Data & Services 🔴 +3.37 kB (2.13 MB) · Other 🔴 +406 B (7.21 MB) · Graph Workspace 🟢 -283 B (854 kB) · Vendor & Third-Party ⚪ 0 B (8.77 MB) · Panels & Settings ⚪ 0 B (451 kB) · Utilities & Hooks ⚪ 0 B (236 kB) · + 5 more

Per-category breakdown
App Entry Points — 22.2 kB (baseline 22.2 kB) • ⚪ 0 B

Main entry bundles and manifests

File Before After Δ Raw Δ Gzip Δ Brotli
assets/index-B1WLngHF.js (removed) 22.2 kB 🟢 -22.2 kB 🟢 -7.2 kB 🟢 -6.26 kB
assets/index-DjbE4rjX.js (new) 22.2 kB 🔴 +22.2 kB 🔴 +7.2 kB 🔴 +6.25 kB

Status: 1 added / 1 removed

Graph Workspace — 854 kB (baseline 855 kB) • 🟢 -283 B

Graph editor runtime, canvas, workflow orchestration

File Before After Δ Raw Δ Gzip Δ Brotli
assets/GraphView-BX6aLGZ5.js (removed) 855 kB 🟢 -855 kB 🟢 -184 kB 🟢 -140 kB
assets/GraphView-DkTDVQpQ.js (new) 854 kB 🔴 +854 kB 🔴 +184 kB 🔴 +140 kB

Status: 1 added / 1 removed

Views & Navigation — 68.8 kB (baseline 68.8 kB) • ⚪ 0 B

Top-level views, pages, and routed surfaces

File Before After Δ Raw Δ Gzip Δ Brotli
assets/CloudSurveyView-B1nutiqk.js (removed) 15.4 kB 🟢 -15.4 kB 🟢 -3.3 kB 🟢 -2.81 kB
assets/CloudSurveyView-ChRUU4O-.js (new) 15.4 kB 🔴 +15.4 kB 🔴 +3.31 kB 🔴 +2.81 kB
assets/CloudLoginView-CMhkMd3D.js (removed) 10.1 kB 🟢 -10.1 kB 🟢 -2.94 kB 🟢 -2.58 kB
assets/CloudLoginView-DY1ESwwp.js (new) 10.1 kB 🔴 +10.1 kB 🔴 +2.94 kB 🔴 +2.59 kB
assets/UserCheckView-B-XpcYwd.js (new) 8.38 kB 🔴 +8.38 kB 🔴 +2.21 kB 🔴 +1.92 kB
assets/UserCheckView-Bi14bR5W.js (removed) 8.38 kB 🟢 -8.38 kB 🟢 -2.21 kB 🟢 -1.92 kB
assets/CloudSignupView-CDdt6SHQ.js (removed) 7.46 kB 🟢 -7.46 kB 🟢 -2.35 kB 🟢 -2.05 kB
assets/CloudSignupView-Tq5GBD-Q.js (new) 7.46 kB 🔴 +7.46 kB 🔴 +2.35 kB 🔴 +2.06 kB
assets/CloudLayoutView-B88sXpZc.js (removed) 6.45 kB 🟢 -6.45 kB 🟢 -2.11 kB 🟢 -1.84 kB
assets/CloudLayoutView-CEXZ-JKC.js (new) 6.45 kB 🔴 +6.45 kB 🔴 +2.11 kB 🔴 +1.84 kB
assets/CloudForgotPasswordView-CNXL78of.js (removed) 5.57 kB 🟢 -5.57 kB 🟢 -1.95 kB 🟢 -1.72 kB
assets/CloudForgotPasswordView-Tii5idVB.js (new) 5.57 kB 🔴 +5.57 kB 🔴 +1.94 kB 🔴 +1.74 kB
assets/CloudAuthTimeoutView-B_9Qwjqu.js (new) 4.92 kB 🔴 +4.92 kB 🔴 +1.78 kB 🔴 +1.56 kB
assets/CloudAuthTimeoutView-BApnlnTq.js (removed) 4.92 kB 🟢 -4.92 kB 🟢 -1.78 kB 🟢 -1.56 kB
assets/CloudSubscriptionRedirectView-BwIhK3MA.js (new) 4.72 kB 🔴 +4.72 kB 🔴 +1.79 kB 🔴 +1.58 kB
assets/CloudSubscriptionRedirectView-Y7ctXSRO.js (removed) 4.72 kB 🟢 -4.72 kB 🟢 -1.79 kB 🟢 -1.58 kB
assets/UserSelectView-D9xEDWk1.js (removed) 4.46 kB 🟢 -4.46 kB 🟢 -1.62 kB 🟢 -1.45 kB
assets/UserSelectView-DmOG-oov.js (new) 4.46 kB 🔴 +4.46 kB 🔴 +1.62 kB 🔴 +1.45 kB
assets/CloudSorryContactSupportView-BDyiwiwq.js 1.02 kB 1.02 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/layout-Cv7zVMF7.js 296 B 296 B ⚪ 0 B ⚪ 0 B ⚪ 0 B

Status: 9 added / 9 removed

Panels & Settings — 451 kB (baseline 451 kB) • ⚪ 0 B

Configuration panels, inspectors, and settings screens

File Before After Δ Raw Δ Gzip Δ Brotli
assets/WorkspacePanel-D-lz59N7.js (new) 26.8 kB 🔴 +26.8 kB 🔴 +5.63 kB 🔴 +4.94 kB
assets/WorkspacePanel-oN32iQ8v.js (removed) 26.8 kB 🟢 -26.8 kB 🟢 -5.63 kB 🟢 -4.95 kB
assets/SecretsPanel-BqAQVVbp.js (new) 21.5 kB 🔴 +21.5 kB 🔴 +5.29 kB 🔴 +4.63 kB
assets/SecretsPanel-C47mXr6F.js (removed) 21.5 kB 🟢 -21.5 kB 🟢 -5.29 kB 🟢 -4.63 kB
assets/LegacyCreditsPanel-BPNT1B9R.js (new) 20.8 kB 🔴 +20.8 kB 🔴 +5.61 kB 🔴 +4.93 kB
assets/LegacyCreditsPanel-mGxBbn1L.js (removed) 20.8 kB 🟢 -20.8 kB 🟢 -5.61 kB 🟢 -4.94 kB
assets/SubscriptionPanel-BBb6WDcc.js (new) 18.7 kB 🔴 +18.7 kB 🔴 +4.76 kB 🔴 +4.21 kB
assets/SubscriptionPanel-CJnG4RR1.js (removed) 18.7 kB 🟢 -18.7 kB 🟢 -4.76 kB 🟢 -4.21 kB
assets/KeybindingPanel-Cs2ayT1G.js (new) 12.6 kB 🔴 +12.6 kB 🔴 +3.63 kB 🔴 +3.22 kB
assets/KeybindingPanel-fFOZytwk.js (removed) 12.6 kB 🟢 -12.6 kB 🟢 -3.63 kB 🟢 -3.21 kB
assets/ExtensionPanel--j_npBtb.js (removed) 9.51 kB 🟢 -9.51 kB 🟢 -2.69 kB 🟢 -2.4 kB
assets/ExtensionPanel-BrNMDeVE.js (new) 9.51 kB 🔴 +9.51 kB 🔴 +2.69 kB 🔴 +2.4 kB
assets/AboutPanel-CHN4WN4j.js (removed) 8.62 kB 🟢 -8.62 kB 🟢 -2.45 kB 🟢 -2.21 kB
assets/AboutPanel-DmWq0nIc.js (new) 8.62 kB 🔴 +8.62 kB 🔴 +2.46 kB 🔴 +2.21 kB
assets/ServerConfigPanel-CiHkb3Es.js (removed) 6.65 kB 🟢 -6.65 kB 🟢 -2.17 kB 🟢 -1.98 kB
assets/ServerConfigPanel-DzekEeKc.js (new) 6.65 kB 🔴 +6.65 kB 🔴 +2.16 kB 🔴 +1.96 kB
assets/UserPanel-COQGRBP2.js (removed) 6.29 kB 🟢 -6.29 kB 🟢 -2.03 kB 🟢 -1.78 kB
assets/UserPanel-i21ahiVm.js (new) 6.29 kB 🔴 +6.29 kB 🔴 +2.03 kB 🔴 +1.79 kB
assets/cloudRemoteConfig-CHsq-XpI.js (removed) 1.45 kB 🟢 -1.45 kB 🟢 -717 B 🟢 -621 B
assets/cloudRemoteConfig-CvFUfSrK.js (new) 1.45 kB 🔴 +1.45 kB 🔴 +716 B 🔴 +620 B
assets/refreshRemoteConfig-Bmaz77FB.js (new) 1.14 kB 🔴 +1.14 kB 🔴 +522 B 🔴 +459 B
assets/refreshRemoteConfig-DbgiFV-e.js (removed) 1.14 kB 🟢 -1.14 kB 🟢 -519 B 🟢 -478 B
assets/config-B7YkIQwB.js 1.01 kB 1.01 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-BFiRprDH.js 31.2 kB 31.2 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-Bkk-nJFW.js 37.1 kB 37.1 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-CYcjX6cS.js 27.7 kB 27.7 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-D4S6euyr.js 23.7 kB 23.7 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-D5H4G8lj.js 29.5 kB 29.5 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-Di62KFUs.js 23 kB 23 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-DP0akR3m.js 27 kB 27 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-jTyPnDBE.js 27.7 kB 27.7 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-paLi_Ryq.js 28.8 kB 28.8 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-rfYpR18m.js 32.8 kB 32.8 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-YKn27p-6.js 26.8 kB 26.8 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B

Status: 11 added / 11 removed

User & Accounts — 16 kB (baseline 16 kB) • ⚪ 0 B

Authentication, profile, and account management bundles

File Before After Δ Raw Δ Gzip Δ Brotli
assets/auth-CMfGD44j.js (new) 3.4 kB 🔴 +3.4 kB 🔴 +1.18 kB 🔴 +992 B
assets/auth-e5TS5rlp.js (removed) 3.4 kB 🟢 -3.4 kB 🟢 -1.18 kB 🟢 -989 B
assets/SignUpForm-Bs66Bm7X.js (removed) 3.01 kB 🟢 -3.01 kB 🟢 -1.23 kB 🟢 -1.1 kB
assets/SignUpForm-DZgU6U3P.js (new) 3.01 kB 🔴 +3.01 kB 🔴 +1.23 kB 🔴 +1.1 kB
assets/UpdatePasswordContent-Dm4cVQ2e.js (removed) 2.38 kB 🟢 -2.38 kB 🟢 -1.08 kB 🟢 -958 B
assets/UpdatePasswordContent-DphO1h2g.js (new) 2.38 kB 🔴 +2.38 kB 🔴 +1.08 kB 🔴 +952 B
assets/firebaseAuthStore-CpHRYLdk.js (new) 803 B 🔴 +803 B 🔴 +397 B 🔴 +359 B
assets/firebaseAuthStore-CVc3fSQ1.js (removed) 803 B 🟢 -803 B 🟢 -399 B 🟢 -363 B
assets/auth-3RRXP9f9.js (removed) 317 B 🟢 -317 B 🟢 -210 B 🟢 -196 B
assets/auth-CBXAmUvb.js (new) 317 B 🔴 +317 B 🔴 +206 B 🔴 +178 B
assets/PasswordFields-KhNVfxGF.js 4.51 kB 4.51 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/WorkspaceProfilePic-Dzy0Q-Jz.js 1.57 kB 1.57 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B

Status: 5 added / 5 removed

Editors & Dialogs — 751 B (baseline 751 B) • ⚪ 0 B

Modals, dialogs, drawers, and in-app editors

File Before After Δ Raw Δ Gzip Δ Brotli
assets/useSubscriptionDialog-DNJ2_55-.js (removed) 751 B 🟢 -751 B 🟢 -392 B 🟢 -337 B
assets/useSubscriptionDialog-ooRhQoaH.js (new) 751 B 🔴 +751 B 🔴 +391 B 🔴 +336 B

Status: 1 added / 1 removed

UI Components — 36.6 kB (baseline 36.6 kB) • ⚪ 0 B

Reusable component library chunks

File Before After Δ Raw Δ Gzip Δ Brotli
assets/useTerminalTabs-C5-nSI_c.js (removed) 9.86 kB 🟢 -9.86 kB 🟢 -3.41 kB 🟢 -3.01 kB
assets/useTerminalTabs-jy8P3SHx.js (new) 9.86 kB 🔴 +9.86 kB 🔴 +3.41 kB 🔴 +3 kB
assets/ComfyQueueButton-204FDRoE.js (removed) 7.17 kB 🟢 -7.17 kB 🟢 -2.32 kB 🟢 -2.08 kB
assets/ComfyQueueButton-BIvYUFmm.js (new) 7.17 kB 🔴 +7.17 kB 🔴 +2.32 kB 🔴 +2.08 kB
assets/SubscribeButton-CiNSdi24.js (removed) 2.35 kB 🟢 -2.35 kB 🟢 -1.02 kB 🟢 -887 B
assets/SubscribeButton-CnV7gtHA.js (new) 2.35 kB 🔴 +2.35 kB 🔴 +1.02 kB 🔴 +883 B
assets/cloudFeedbackTopbarButton-Dmn5WEK1.js (new) 1.61 kB 🔴 +1.61 kB 🔴 +867 B 🔴 +769 B
assets/cloudFeedbackTopbarButton-DmSMdld6.js (removed) 1.61 kB 🟢 -1.61 kB 🟢 -867 B 🟢 -772 B
assets/ComfyQueueButton-DJyr-3jR.js (new) 808 B 🔴 +808 B 🔴 +404 B 🔴 +358 B
assets/ComfyQueueButton-KY-hcko4.js (removed) 808 B 🟢 -808 B 🟢 -406 B 🟢 -360 B
assets/Button-D-JRKour.js 3 kB 3 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/CloudBadge-pw0WcXyY.js 1.24 kB 1.24 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/TopbarBadge-WqzfpwB2.js 7.52 kB 7.52 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/UserAvatar-C0eF2MUp.js 1.17 kB 1.17 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/WidgetButton-4mWh4Pjc.js 1.84 kB 1.84 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B

Status: 5 added / 5 removed

Data & Services — 2.13 MB (baseline 2.12 MB) • 🔴 +3.37 kB

Stores, services, APIs, and repositories

File Before After Δ Raw Δ Gzip Δ Brotli
assets/dialogService-B-ivwClX.js (new) 1.35 MB 🔴 +1.35 MB 🔴 +304 kB 🔴 +235 kB
assets/dialogService-DRPF9OT_.js (removed) 1.35 MB 🟢 -1.35 MB 🟢 -303 kB 🟢 -235 kB
assets/api-D0q7_PFK.js (new) 647 kB 🔴 +647 kB 🔴 +146 kB 🔴 +117 kB
assets/api-Bp0Em-Zq.js (removed) 646 kB 🟢 -646 kB 🟢 -146 kB 🟢 -116 kB
assets/load3dService-DjBgLeJm.js (new) 91.2 kB 🔴 +91.2 kB 🔴 +19.1 kB 🔴 +16.5 kB
assets/load3dService-FJXa-IJy.js (removed) 91.2 kB 🟢 -91.2 kB 🟢 -19.1 kB 🟢 -16.4 kB
assets/systemStatsStore-D_7EQKq0.js (new) 12.2 kB 🔴 +12.2 kB 🔴 +4.27 kB 🔴 +3.74 kB
assets/systemStatsStore-D64O4F4l.js (removed) 12.2 kB 🟢 -12.2 kB 🟢 -4.27 kB 🟢 -3.75 kB
assets/releaseStore-B2Eh01hY.js (removed) 7.99 kB 🟢 -7.99 kB 🟢 -2.23 kB 🟢 -1.96 kB
assets/releaseStore-C_ynvOMt.js (new) 7.99 kB 🔴 +7.99 kB 🔴 +2.23 kB 🔴 +1.96 kB
assets/keybindingService-BjE6R0C4.js (new) 6.57 kB 🔴 +6.57 kB 🔴 +1.72 kB 🔴 +1.49 kB
assets/keybindingService-xHIEwPPt.js (removed) 6.57 kB 🟢 -6.57 kB 🟢 -1.72 kB 🟢 -1.49 kB
assets/bootstrapStore-B1QHU5xH.js (removed) 2.13 kB 🟢 -2.13 kB 🟢 -883 B 🟢 -815 B
assets/bootstrapStore-JE5U-FnP.js (new) 2.13 kB 🔴 +2.13 kB 🔴 +883 B 🔴 +813 B
assets/userStore-BLw5PCK8.js (new) 1.85 kB 🔴 +1.85 kB 🔴 +723 B 🔴 +672 B
assets/userStore-CIh1blwH.js (removed) 1.85 kB 🟢 -1.85 kB 🟢 -719 B 🟢 -671 B
assets/audioService-BaDId7iT.js (new) 1.73 kB 🔴 +1.73 kB 🔴 +846 B 🔴 +724 B
assets/audioService-D2-TWl_Q.js (removed) 1.73 kB 🟢 -1.73 kB 🟢 -848 B 🟢 -725 B
assets/releaseStore-CyFe_6OC.js (new) 775 B 🔴 +775 B 🔴 +394 B 🔴 +344 B
assets/releaseStore-D-TpmRcT.js (removed) 775 B 🟢 -775 B 🟢 -397 B 🟢 -346 B
assets/workflowDraftStore-Dg7kbksy.js (new) 751 B 🔴 +751 B 🔴 +391 B 🔴 +341 B
assets/workflowDraftStore-S3VuzJcW.js (removed) 751 B 🟢 -751 B 🟢 -392 B 🟢 -342 B
assets/dialogService-CmCv_VAj.js (removed) 740 B 🟢 -740 B 🟢 -380 B 🟢 -342 B
assets/dialogService-DMSMD-VG.js (new) 740 B 🔴 +740 B 🔴 +380 B 🔴 +339 B
assets/dialogStore-q7bkx30L.js 4.1 kB 4.1 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/serverConfigStore-CG8z6LWz.js 2.32 kB 2.32 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B

Status: 12 added / 12 removed

Utilities & Hooks — 236 kB (baseline 236 kB) • ⚪ 0 B

Helpers, composables, and utility bundles

File Before After Δ Raw Δ Gzip Δ Brotli
assets/useConflictDetection-DnwivapH.js (removed) 177 kB 🟢 -177 kB 🟢 -38.9 kB 🟢 -32.4 kB
assets/useConflictDetection-ucj5cqwh.js (new) 177 kB 🔴 +177 kB 🔴 +38.9 kB 🔴 +32.4 kB
assets/useLoad3d-Bx8Xj2uD.js (new) 14.7 kB 🔴 +14.7 kB 🔴 +3.64 kB 🔴 +3.21 kB
assets/useLoad3d-C4lAqz_D.js (removed) 14.7 kB 🟢 -14.7 kB 🟢 -3.64 kB 🟢 -3.21 kB
assets/useLoad3dViewer-CBBIo8EG.js (removed) 14.2 kB 🟢 -14.2 kB 🟢 -3.16 kB 🟢 -2.8 kB
assets/useLoad3dViewer-Cp8h_gyj.js (new) 14.2 kB 🔴 +14.2 kB 🔴 +3.15 kB 🔴 +2.8 kB
assets/useFeatureFlags-C2Eys4Wd.js (removed) 3.34 kB 🟢 -3.34 kB 🟢 -1.05 kB 🟢 -907 B
assets/useFeatureFlags-Di1_h9Z2.js (new) 3.34 kB 🔴 +3.34 kB 🔴 +1.05 kB 🔴 +909 B
assets/useWorkspaceUI-BH8iTXJZ.js (new) 3.15 kB 🔴 +3.15 kB 🔴 +890 B 🔴 +767 B
assets/useWorkspaceUI-O_-GdYGa.js (removed) 3.15 kB 🟢 -3.15 kB 🟢 -892 B 🟢 -769 B
assets/useSubscriptionCredits-5XwfxJ-i.js (removed) 2.75 kB 🟢 -2.75 kB 🟢 -1.04 kB 🟢 -902 B
assets/useSubscriptionCredits-CssyLlxl.js (new) 2.75 kB 🔴 +2.75 kB 🔴 +1.04 kB 🔴 +899 B
assets/subscriptionCheckoutUtil-C5P7vhls.js (removed) 2.53 kB 🟢 -2.53 kB 🟢 -1.06 kB 🟢 -962 B
assets/subscriptionCheckoutUtil-D7ehogDh.js (new) 2.53 kB 🔴 +2.53 kB 🔴 +1.06 kB 🔴 +927 B
assets/useErrorHandling-BNxg_N4U.js (new) 1.34 kB 🔴 +1.34 kB 🔴 +557 B 🔴 +508 B
assets/useErrorHandling-Oi3QTZDO.js (removed) 1.34 kB 🟢 -1.34 kB 🟢 -555 B 🟢 -511 B
assets/useLoad3d-B5_u8dxD.js (removed) 874 B 🟢 -874 B 🟢 -439 B 🟢 -394 B
assets/useLoad3d-sHY8UQhu.js (new) 874 B 🔴 +874 B 🔴 +437 B 🔴 +390 B
assets/audioUtils-BKrKQyCr.js (removed) 858 B 🟢 -858 B 🟢 -499 B 🟢 -420 B
assets/audioUtils-EMykFDoq.js (new) 858 B 🔴 +858 B 🔴 +501 B 🔴 +424 B
assets/useLoad3dViewer-DQOWqOf9.js (removed) 853 B 🟢 -853 B 🟢 -424 B 🟢 -378 B
assets/useLoad3dViewer-P4yJuF8w.js (new) 853 B 🔴 +853 B 🔴 +421 B 🔴 +377 B
assets/useCurrentUser-_7Vr2OaP.js (removed) 737 B 🟢 -737 B 🟢 -384 B 🟢 -337 B
assets/useCurrentUser-DgOiYJK8.js (new) 737 B 🔴 +737 B 🔴 +383 B 🔴 +339 B
assets/_plugin-vue_export-helper-D53b894U.js 315 B 315 B ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/colorUtil-BRIBx2PN.js 7 kB 7 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/envUtil-BoEUYO9X.js 466 B 466 B ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/markdownRendererUtil-YzPqYQr3.js 1.56 kB 1.56 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/networkUtil-DSA9UCpE.js 1.07 kB 1.07 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/SkeletonUtils-CWsb-x0f.js 133 B 133 B ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/useCopyToClipboard-DYMUqpMj.js 1.57 kB 1.57 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/useExternalLink-DeeRtxbK.js 1.66 kB 1.66 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B

Status: 12 added / 12 removed

Vendor & Third-Party — 8.77 MB (baseline 8.77 MB) • ⚪ 0 B

External libraries and shared vendor chunks

File Before After Δ Raw Δ Gzip Δ Brotli
assets/vendor-axios-qYA_aG5-.js 71.6 kB 71.6 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/vendor-chart-DPuwexxf.js 399 kB 399 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/vendor-firebase-CLEC0CcJ.js 842 kB 842 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/vendor-i18n-Djj6y3EO.js 132 kB 132 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/vendor-markdown-CLFqBOQ2.js 102 kB 102 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/vendor-other-BjIHN7VK.js 1.55 MB 1.55 MB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/vendor-primevue-DaJr0o4X.js 1.74 MB 1.74 MB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/vendor-reka-ui-BfJUTI-3.js 240 kB 240 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/vendor-sentry-BVA5kbUC.js 183 kB 183 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/vendor-three-Q97wQk05.js 1.8 MB 1.8 MB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/vendor-tiptap-eGUDVAYp.js 632 kB 632 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/vendor-vue-core-DnRx4pHA.js 312 kB 312 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/vendor-vueuse-CfaD9iqz.js 111 kB 111 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/vendor-xterm-0CcpQUK2.js 398 kB 398 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/vendor-yjs-B7dXz571.js 143 kB 143 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/vendor-zod-BTzCBa7h.js 110 kB 110 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
Other — 7.21 MB (baseline 7.21 MB) • 🔴 +406 B

Bundles that do not match a named category

File Before After Δ Raw Δ Gzip Δ Brotli
assets/core-CavsAjPw.js (new) 72.4 kB 🔴 +72.4 kB 🔴 +18.7 kB 🔴 +16 kB
assets/groupNode-BFcdrPSq.js (removed) 72.2 kB 🟢 -72.2 kB 🟢 -17.8 kB 🟢 -15.7 kB
assets/groupNode-DQhHOtf4.js (new) 72.2 kB 🔴 +72.2 kB 🔴 +17.8 kB 🔴 +15.7 kB
assets/core-B8yoBkId.js (removed) 72.1 kB 🟢 -72.1 kB 🟢 -18.6 kB 🟢 -16 kB
assets/WidgetSelect-DIVA1Div.js (new) 57.6 kB 🔴 +57.6 kB 🔴 +12.2 kB 🔴 +10.6 kB
assets/WidgetSelect-TBNqsnAZ.js (removed) 57.5 kB 🟢 -57.5 kB 🟢 -12.2 kB 🟢 -10.6 kB
assets/SubscriptionRequiredDialogContentWorkspace-CJlihyzD.js (removed) 46 kB 🟢 -46 kB 🟢 -8.6 kB 🟢 -7.46 kB
assets/SubscriptionRequiredDialogContentWorkspace-CNNkfrh0.js (new) 46 kB 🔴 +46 kB 🔴 +8.59 kB 🔴 +7.43 kB
assets/SettingDialogContent-CSettbq2.js (new) 31.9 kB 🔴 +31.9 kB 🔴 +8.33 kB 🔴 +7.32 kB
assets/SettingDialogContent-Ry3lLrk6.js (removed) 31.9 kB 🟢 -31.9 kB 🟢 -8.34 kB 🟢 -7.34 kB
assets/Load3DControls-Bblu91Ds.js (removed) 30.9 kB 🟢 -30.9 kB 🟢 -5.34 kB 🟢 -4.64 kB
assets/Load3DControls-D7GUgolV.js (new) 30.9 kB 🔴 +30.9 kB 🔴 +5.34 kB 🔴 +4.63 kB
assets/SubscriptionRequiredDialogContent-Bu8v3PoL.js (new) 26.2 kB 🔴 +26.2 kB 🔴 +6.58 kB 🔴 +5.79 kB
assets/SubscriptionRequiredDialogContent-Cc1k9RTH.js (removed) 26.2 kB 🟢 -26.2 kB 🟢 -6.59 kB 🟢 -5.8 kB
assets/Load3dViewerContent-fAqed9jB.js (removed) 23.1 kB 🟢 -23.1 kB 🟢 -5.2 kB 🟢 -4.51 kB
assets/Load3dViewerContent-L-qwClsI.js (new) 23.1 kB 🔴 +23.1 kB 🔴 +5.2 kB 🔴 +4.51 kB
assets/WidgetImageCrop-DPGIezXc.js (new) 22.3 kB 🔴 +22.3 kB 🔴 +5.52 kB 🔴 +4.85 kB
assets/WidgetImageCrop-Q80pkiBl.js (removed) 22.3 kB 🟢 -22.3 kB 🟢 -5.52 kB 🟢 -4.86 kB
assets/SubscriptionPanelContentWorkspace-4zkqKTpe.js (new) 21.8 kB 🔴 +21.8 kB 🔴 +5.18 kB 🔴 +4.58 kB
assets/SubscriptionPanelContentWorkspace-CIlivyqy.js (removed) 21.8 kB 🟢 -21.8 kB 🟢 -5.18 kB 🟢 -4.58 kB
assets/CurrentUserPopoverWorkspace-CCqOBtKy.js (new) 20.6 kB 🔴 +20.6 kB 🔴 +5.08 kB 🔴 +4.52 kB
assets/CurrentUserPopoverWorkspace-DULP67Wt.js (removed) 20.6 kB 🟢 -20.6 kB 🟢 -5.08 kB 🟢 -4.51 kB
assets/FormItem-B3_uaCYA.js (new) 20.2 kB 🔴 +20.2 kB 🔴 +4.86 kB 🔴 +4.25 kB
assets/FormItem-CvsXLhtF.js (removed) 20.2 kB 🟢 -20.2 kB 🟢 -4.86 kB 🟢 -4.25 kB
assets/SignInContent-8VVMcPYs.js (new) 19 kB 🔴 +19 kB 🔴 +4.82 kB 🔴 +4.21 kB
assets/SignInContent-b-Dnrawu.js (removed) 19 kB 🟢 -19 kB 🟢 -4.82 kB 🟢 -4.21 kB
assets/WidgetRecordAudio-BT2EFMqb.js (removed) 17.3 kB 🟢 -17.3 kB 🟢 -4.96 kB 🟢 -4.42 kB
assets/WidgetRecordAudio-D0SAYt9L.js (new) 17.3 kB 🔴 +17.3 kB 🔴 +4.96 kB 🔴 +4.43 kB
assets/MissingModelsWarning-4cEaQFMk.js (removed) 17.2 kB 🟢 -17.2 kB 🟢 -4.71 kB 🟢 -4.17 kB
assets/MissingModelsWarning-DJXcS7n8.js (new) 17.2 kB 🔴 +17.2 kB 🔴 +4.7 kB 🔴 +4.17 kB
assets/Load3D-BK1e0wkR.js (new) 16.2 kB 🔴 +16.2 kB 🔴 +4.04 kB 🔴 +3.53 kB
assets/Load3D-DI7Pytft.js (removed) 16.2 kB 🟢 -16.2 kB 🟢 -4.04 kB 🟢 -3.52 kB
assets/WidgetInputNumber-CuSxvFAP.js (new) 15.8 kB 🔴 +15.8 kB 🔴 +4.26 kB 🔴 +3.79 kB
assets/WidgetInputNumber-DzjrBMyk.js (removed) 15.8 kB 🟢 -15.8 kB 🟢 -4.26 kB 🟢 -3.8 kB
assets/load3d-BibBQxc5.js (removed) 14.8 kB 🟢 -14.8 kB 🟢 -4.21 kB 🟢 -3.64 kB
assets/load3d-Ce84QrSg.js (new) 14.8 kB 🔴 +14.8 kB 🔴 +4.21 kB 🔴 +3.65 kB
assets/AudioPreviewPlayer-DiQ0TQia.js (new) 10.9 kB 🔴 +10.9 kB 🔴 +3.21 kB 🔴 +2.88 kB
assets/AudioPreviewPlayer-DZ42CllF.js (removed) 10.9 kB 🟢 -10.9 kB 🟢 -3.21 kB 🟢 -2.87 kB
assets/NodeConflictDialogContent-B7jU-J4A.js (new) 10.5 kB 🔴 +10.5 kB 🔴 +2.35 kB 🔴 +2.06 kB
assets/NodeConflictDialogContent-eqvb2VKq.js (removed) 10.5 kB 🟢 -10.5 kB 🟢 -2.36 kB 🟢 -2.08 kB
assets/changeTracker-jfTCedFx.js (removed) 9.4 kB 🟢 -9.4 kB 🟢 -2.9 kB 🟢 -2.56 kB
assets/changeTracker-Rhgt1Z_r.js (new) 9.4 kB 🔴 +9.4 kB 🔴 +2.9 kB 🔴 +2.55 kB
assets/nodeTemplates-C7bUaSHa.js (removed) 9.34 kB 🟢 -9.34 kB 🟢 -3.28 kB 🟢 -2.88 kB
assets/nodeTemplates-T6A56l6j.js (new) 9.34 kB 🔴 +9.34 kB 🔴 +3.28 kB 🔴 +2.89 kB
assets/InviteMemberDialogContent-BTmbRiBk.js (new) 7.92 kB 🔴 +7.92 kB 🔴 +2.56 kB 🔴 +2.24 kB
assets/InviteMemberDialogContent-DQFQFL6X.js (removed) 7.92 kB 🟢 -7.92 kB 🟢 -2.57 kB 🟢 -2.23 kB
assets/WidgetWithControl-BCd4ACV2.js (new) 7.04 kB 🔴 +7.04 kB 🔴 +2.64 kB 🔴 +2.35 kB
assets/WidgetWithControl-BUj89DgT.js (removed) 7.04 kB 🟢 -7.04 kB 🟢 -2.64 kB 🟢 -2.35 kB
assets/MissingNodesFooter-vDbooPs8.js (new) 6.73 kB 🔴 +6.73 kB 🔴 +2.29 kB 🔴 +2.06 kB
assets/MissingNodesFooter-Y_3CwF95.js (removed) 6.73 kB 🟢 -6.73 kB 🟢 -2.29 kB 🟢 -2.06 kB
assets/Load3DConfiguration-DkOj5bRd.js (removed) 6.36 kB 🟢 -6.36 kB 🟢 -1.93 kB 🟢 -1.69 kB
assets/Load3DConfiguration-oTgCf5rs.js (new) 6.36 kB 🔴 +6.36 kB 🔴 +1.93 kB 🔴 +1.69 kB
assets/MissingNodesContent-DBgbT8Z7.js (new) 6.15 kB 🔴 +6.15 kB 🔴 +2.09 kB 🔴 +1.86 kB
assets/MissingNodesContent-neDc6KPT.js (removed) 6.15 kB 🟢 -6.15 kB 🟢 -2.09 kB 🟢 -1.87 kB
assets/CreateWorkspaceDialogContent-DnTD8N05.js (new) 5.55 kB 🔴 +5.55 kB 🔴 +2 kB 🔴 +1.75 kB
assets/CreateWorkspaceDialogContent-o8_qKe2m.js (removed) 5.55 kB 🟢 -5.55 kB 🟢 -2 kB 🟢 -1.74 kB
assets/EditWorkspaceDialogContent-BEpYNuLZ.js (removed) 5.35 kB 🟢 -5.35 kB 🟢 -1.96 kB 🟢 -1.71 kB
assets/EditWorkspaceDialogContent-CVm3FLyS.js (new) 5.35 kB 🔴 +5.35 kB 🔴 +1.95 kB 🔴 +1.71 kB
assets/ValueControlPopover-ajdth_NP.js (new) 4.93 kB 🔴 +4.93 kB 🔴 +1.78 kB 🔴 +1.6 kB
assets/ValueControlPopover-DD8uQE6F.js (removed) 4.93 kB 🟢 -4.93 kB 🟢 -1.78 kB 🟢 -1.59 kB
assets/Preview3d-B3q2VagS.js (new) 4.83 kB 🔴 +4.83 kB 🔴 +1.58 kB 🔴 +1.38 kB
assets/Preview3d-rMXZRRhf.js (removed) 4.83 kB 🟢 -4.83 kB 🟢 -1.58 kB 🟢 -1.38 kB
assets/CancelSubscriptionDialogContent-CBsq88sQ.js (new) 4.81 kB 🔴 +4.81 kB 🔴 +1.79 kB 🔴 +1.57 kB
assets/CancelSubscriptionDialogContent-CE5pnLYr.js (removed) 4.81 kB 🟢 -4.81 kB 🟢 -1.79 kB 🟢 -1.57 kB
assets/DeleteWorkspaceDialogContent-D2w7-GDK.js (new) 4.25 kB 🔴 +4.25 kB 🔴 +1.64 kB 🔴 +1.42 kB
assets/DeleteWorkspaceDialogContent-TnRSU6m1.js (removed) 4.25 kB 🟢 -4.25 kB 🟢 -1.65 kB 🟢 -1.43 kB
assets/LeaveWorkspaceDialogContent-B-N4PjmM.js (removed) 4.08 kB 🟢 -4.08 kB 🟢 -1.59 kB 🟢 -1.38 kB
assets/LeaveWorkspaceDialogContent-DFXY8Ur5.js (new) 4.08 kB 🔴 +4.08 kB 🔴 +1.59 kB 🔴 +1.38 kB
assets/RemoveMemberDialogContent-CBSdvbVo.js (removed) 4.06 kB 🟢 -4.06 kB 🟢 -1.54 kB 🟢 -1.34 kB
assets/RemoveMemberDialogContent-COVJsDha.js (new) 4.06 kB 🔴 +4.06 kB 🔴 +1.54 kB 🔴 +1.34 kB
assets/RevokeInviteDialogContent-BkIHFfBF.js (new) 3.98 kB 🔴 +3.98 kB 🔴 +1.55 kB 🔴 +1.37 kB
assets/RevokeInviteDialogContent-CZWrvgk-.js (removed) 3.98 kB 🟢 -3.98 kB 🟢 -1.55 kB 🟢 -1.36 kB
assets/saveMesh-CamV6o9n.js (new) 3.43 kB 🔴 +3.43 kB 🔴 +1.47 kB 🔴 +1.3 kB
assets/saveMesh-DF4NDZx4.js (removed) 3.43 kB 🟢 -3.43 kB 🟢 -1.48 kB 🟢 -1.33 kB
assets/cloudSessionCookie-BAoTFxta.js (new) 3.12 kB 🔴 +3.12 kB 🔴 +1.1 kB 🔴 +979 B
assets/cloudSessionCookie-IZ3xeurc.js (removed) 3.12 kB 🟢 -3.12 kB 🟢 -1.1 kB 🟢 -974 B
assets/GlobalToast-B66B67KP.js (removed) 2.91 kB 🟢 -2.91 kB 🟢 -1.21 kB 🟢 -1.06 kB
assets/GlobalToast-BLnGPnb9.js (new) 2.91 kB 🔴 +2.91 kB 🔴 +1.21 kB 🔴 +1.03 kB
assets/SubscribeToRun-9oN7_ot6.js (removed) 2.2 kB 🟢 -2.2 kB 🟢 -1.01 kB 🟢 -889 B
assets/SubscribeToRun-OnAmaWSh.js (new) 2.2 kB 🔴 +2.2 kB 🔴 +1.01 kB 🔴 +870 B
assets/SettingDialogHeader-CcSbUFbG.js (removed) 1.8 kB 🟢 -1.8 kB 🟢 -892 B 🟢 -801 B
assets/SettingDialogHeader-tlfk1vRU.js (new) 1.8 kB 🔴 +1.8 kB 🔴 +891 B 🔴 +801 B
assets/CloudRunButtonWrapper-CP65pS3U.js (removed) 1.69 kB 🟢 -1.69 kB 🟢 -797 B 🟢 -727 B
assets/CloudRunButtonWrapper-DrmXsCjJ.js (new) 1.69 kB 🔴 +1.69 kB 🔴 +794 B 🔴 +717 B
assets/cloudBadges-B6W_0R-D.js (new) 1.38 kB 🔴 +1.38 kB 🔴 +714 B 🔴 +624 B
assets/cloudBadges-DZE_Pab_.js (removed) 1.38 kB 🟢 -1.38 kB 🟢 -715 B 🟢 -626 B
assets/cloudSubscription-C8hiLJH7.js (new) 1.34 kB 🔴 +1.34 kB 🔴 +666 B 🔴 +581 B
assets/cloudSubscription-D3HU8f8T.js (removed) 1.34 kB 🟢 -1.34 kB 🟢 -669 B 🟢 -578 B
assets/Load3D-ChgTtjHu.js (new) 1.09 kB 🔴 +1.09 kB 🔴 +509 B 🔴 +449 B
assets/Load3D-DTYjFhiM.js (removed) 1.09 kB 🟢 -1.09 kB 🟢 -511 B 🟢 -452 B
assets/nightlyBadges-Bo6PHCWX.js (new) 1.02 kB 🔴 +1.02 kB 🔴 +543 B 🔴 +479 B
assets/nightlyBadges-CW04Izv5.js (removed) 1.02 kB 🟢 -1.02 kB 🟢 -547 B 🟢 -481 B
assets/Load3dViewerContent-D96yxfOG.js (removed) 1.01 kB 🟢 -1.01 kB 🟢 -482 B 🟢 -426 B
assets/Load3dViewerContent-uMhpmO2O.js (new) 1.01 kB 🔴 +1.01 kB 🔴 +480 B 🔴 +425 B
assets/SubscriptionPanelContentWorkspace-AljBHitx.js (new) 945 B 🔴 +945 B 🔴 +447 B 🔴 +388 B
assets/SubscriptionPanelContentWorkspace-Do3IPgDc.js (removed) 945 B 🟢 -945 B 🟢 -449 B 🟢 -389 B
assets/SettingDialogContent-2iDvwTHr.js (new) 887 B 🔴 +887 B 🔴 +432 B 🔴 +378 B
assets/SettingDialogContent-CLqyakZH.js (removed) 887 B 🟢 -887 B 🟢 -434 B 🟢 -385 B
assets/changeTracker-C0X7TdR0.js (new) 772 B 🔴 +772 B 🔴 +392 B 🔴 +343 B
assets/changeTracker-CaEMAz5v.js (removed) 772 B 🟢 -772 B 🟢 -396 B 🟢 -344 B
assets/graphHasMissingNodes-0NDMT8cL.js (new) 761 B 🔴 +761 B 🔴 +375 B 🔴 +323 B
assets/graphHasMissingNodes-CxsILYfC.js (removed) 761 B 🟢 -761 B 🟢 -373 B 🟢 -325 B
assets/WidgetLegacy-BPSPMOV7.js (new) 760 B 🔴 +760 B 🔴 +397 B 🔴 +347 B
assets/WidgetLegacy-swGJeOU_.js (removed) 760 B 🟢 -760 B 🟢 -399 B 🟢 -346 B
assets/WidgetInputNumber-CUxN3ZCQ.js (removed) 392 B 🟢 -392 B 🟢 -231 B 🟢 -213 B
assets/WidgetInputNumber-qBJbLWtH.js (new) 392 B 🔴 +392 B 🔴 +231 B 🔴 +198 B
assets/SettingDialogHeader-Bl7WWT2I.js (new) 345 B 🔴 +345 B 🔴 +211 B 🔴 +189 B
assets/SettingDialogHeader-C7GKt5uF.js (removed) 345 B 🟢 -345 B 🟢 -209 B 🟢 -198 B
assets/AnimationControls-B7792UyM.js 4.61 kB 4.61 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/ApiNodesSignInContent-mGzlyCuH.js 2.69 kB 2.69 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/auto-zCGpezkl.js 1.7 kB 1.7 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/BaseViewTemplate-XnByb1vt.js 1.78 kB 1.78 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/comfy-logo-single-CzGozBag.js 198 B 198 B ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/ComfyOrgHeader-DiJp3aEW.js 910 B 910 B ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-BaWekgk-.js 14.7 kB 14.7 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-BDDnqSnY.js 15.8 kB 15.8 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-BoYLZfP6.js 15.7 kB 15.7 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-BQBGh0Ya.js 15.5 kB 15.5 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-BRoxhQgK.js 15.8 kB 15.8 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-C_sqX4RY.js 14.9 kB 14.9 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-Cd2uuEbd.js 17.1 kB 17.1 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-CXPUqoOz.js 16.6 kB 16.6 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-ijoJFfEv.js 16.3 kB 16.3 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-UTYbUnOi.js 17.2 kB 17.2 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-YFdvkJDc.js 18.4 kB 18.4 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/constants-BQ60oUwg.js 579 B 579 B ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/i18n-BAbUnUvb.js 199 B 199 B ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/i18n-CR1X9M-8.js 486 kB 486 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/ImportFailedNodeContent-DLHL7-Dp.js 2.48 kB 2.48 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/ImportFailedNodeFooter-DvtwIWpl.js 1.88 kB 1.88 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/ImportFailedNodeHeader-CBKT1iLw.js 1.08 kB 1.08 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/LazyImage-9f6CAdqs.js 12.3 kB 12.3 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-BUf7VGLC.js 185 kB 185 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-CjzUpUX1.js 153 kB 153 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-CkipomGw.js 160 kB 160 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-CsePyJ5r.js 116 kB 116 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-DfAYnku2.js 166 kB 166 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-DMTXZerX.js 132 kB 132 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-DnyQnLJu.js 137 kB 137 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-Do99CjaL.js 135 kB 135 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-DUNVKwSK.js 117 kB 117 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-PNDNfdBt.js 132 kB 132 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-q45wM3mC.js 140 kB 140 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/Media3DTop-BRnZCRYc.js 1.82 kB 1.82 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/MediaAudioTop-o68UYik3.js 1.43 kB 1.43 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/MediaImageTop-C6_liv9g.js 1.75 kB 1.75 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/MediaVideoTop-BXztKli7.js 2.23 kB 2.23 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/MissingNodesHeader-DJHfQF1y.js 1.09 kB 1.09 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/NodeConflictFooter-Diiss9KH.js 2.37 kB 2.37 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/NodeConflictHeader-DXOchtCS.js 1.09 kB 1.09 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-BowH1VL1.js 361 kB 361 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-CdnhWEKS.js 332 kB 332 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-CDV1thn5.js 405 kB 405 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-Cee5fyaK.js 330 kB 330 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-COWMGhrk.js 361 kB 361 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-CY0w_Hvy.js 406 kB 406 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-DdTkBm1y.js 354 kB 354 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-DQZh9C3Z.js 442 kB 442 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-DRM1T2Jx.js 358 kB 358 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-DUz23YQ5.js 375 kB 375 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-Dxn6e0-h.js 365 kB 365 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/OBJLoader2WorkerModule-DTMpvldF.js 109 kB 109 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/PanelTemplate-Co9CIrpq.js 1.2 kB 1.2 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/previousFullPath-D7OXsRO9.js 665 B 665 B ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/rolldown-runtime-Ca2S-reV.js 1.87 kB 1.87 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/SelectValue-Cd45aXPi.js 8.94 kB 8.94 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/signInSchema-B5amhIix.js 1.53 kB 1.53 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/Slider-BpDHOFfi.js 3.52 kB 3.52 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/src-CWktmgrp.js 251 B 251 B ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/telemetry-C9AnI0k5.js 226 B 226 B ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/types-BYdQ-wbS.js 245 B 245 B ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/widget-DZ2L2V2o.js 445 B 445 B ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/WidgetBoundingBox-C24zoQ9e.js 3.95 kB 3.95 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/WidgetBoundingBox-Dlh3X2pa.js 131 B 131 B ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/WidgetChart-Dz-i33ej.js 2.21 kB 2.21 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/WidgetColorPicker-DFKj0CIe.js 2.9 kB 2.9 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/WidgetGalleria-DLvy9VuC.js 3.61 kB 3.61 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/WidgetImageCompare-1sy6l8-0.js 3.1 kB 3.1 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/WidgetInputText-D-efAVZy.js 1.86 kB 1.86 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/WidgetLayoutField-B5nsgfe8.js 1.95 kB 1.95 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/WidgetMarkdown-BP5qyCxZ.js 2.88 kB 2.88 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/widgetPropFilter-DyQHILEf.js 1.1 kB 1.1 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/WidgetTextarea-DKZNqX1s.js 3.14 kB 3.14 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/WidgetToggleSwitch-DyUmrxBZ.js 2.5 kB 2.5 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/widgetTypes-BRoEExOD.js 393 B 393 B ⚪ 0 B ⚪ 0 B ⚪ 0 B

Status: 54 added / 54 removed

@DrJKL DrJKL changed the title feat: add WidgetValueStore for centralized widget value management WIP/feat: add WidgetValueStore for centralized widget value management Feb 4, 2026
@DrJKL DrJKL force-pushed the drjkl/widget-store branch from 7d3ae89 to 474b148 Compare February 5, 2026 02:48
@DrJKL DrJKL self-assigned this Feb 5, 2026
@DrJKL DrJKL requested a review from LittleSound February 5, 2026 03:31
@DrJKL DrJKL added the New Browser Test Expectations New browser test screenshot should be set by github action label Feb 5, 2026
@github-actions
Copy link

github-actions bot commented Feb 5, 2026

Updating Playwright Expectations

tooltip?: string

private _state: WidgetState
Copy link
Contributor Author

Choose a reason for hiding this comment

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

There are likely more properties that we'll want to move into the store.

@DrJKL DrJKL force-pushed the drjkl/widget-store branch from 62b9bbd to f318a7a Compare February 5, 2026 22:16
return String(scopedId).replace(/^(.*:)+/, '') as NodeId
}

export interface WidgetState<
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'm hoping to be able to remove this and instead compose types soon.
This should also let us eliminate some redundant interfaces floating around in various modules.

@DrJKL DrJKL marked this pull request as ready for review February 5, 2026 22:17
@DrJKL DrJKL requested a review from a team as a code owner February 5, 2026 22:17
@dosubot dosubot bot added the size:XL This PR changes 500-999 lines, ignoring generated files. label Feb 5, 2026
@github-actions github-actions bot removed the New Browser Test Expectations New browser test screenshot should be set by github action label Feb 5, 2026
@DrJKL DrJKL assigned AustinMroz and christian-byrne and unassigned DrJKL Feb 5, 2026
DrJKL and others added 8 commits February 5, 2026 14:29
- Add _nodeId field and setNodeId() method

- Delegate value getter/setter to store when node ID set

- Seed store with current value on setNodeId() call

Amp-Thread-ID: https://ampcode.com/threads/T-019c2559-977f-77a2-9633-d8fed5b5a2ad
Co-authored-by: Amp <amp@ampcode.com>
…tivity

- BaseWidget.value getter/setter now delegates to WidgetValueStore when nodeId is set
- Widget registration deferred until node is added to graph (to get valid ID)
- LGraph.add() registers widgets with store after assigning node ID
- Removed vueTrack pattern from useGraphNodeManager - store provides reactivity
- Simplified useReactiveWidgetValue to return widget.value directly

This enables reactive widget values across Vue components without custom
tracking infrastructure. Extensions continue to work unchanged via the
preserved widget.value API.

Amp-Thread-ID: https://ampcode.com/threads/T-019c25f1-e920-70bb-afaf-59366bdab667
Co-authored-by: Amp <amp@ampcode.com>
Add WidgetState interface and widgetStates Map alongside existing values
Map to support full widget lifecycle management:

- WidgetState: nodeId, name, type, value, label, hidden, disabled,
  advanced, promoted, options, serialize
- Registration: registerWidget(), unregisterWidget(), unregisterNode()
- Getters: getWidget(), getNodeWidgets(), getVisibleWidgets(),
  getAdvancedWidgets(), getPromotedWidgets()
- Setters: setHidden(), setDisabled(), setAdvanced(), setPromoted(),
  setLabel()

Existing get/set/remove/removeNode API preserved for backward compat.
set() now syncs value to WidgetState when widget is registered.

Amp-Thread-ID: https://ampcode.com/threads/T-019c2626-df19-75cf-b9c9-11fe9735083d
Co-authored-by: Amp <amp@ampcode.com>
- Convert label/hidden/disabled/advanced/promoted to getter/setter pairs

- Getters read from store when registered, fallback to internal value

- Setters update both internal field and store

- Add BaseWidget.test.ts with 7 tests for store integration

Amp-Thread-ID: https://ampcode.com/threads/T-019c262b-bed5-714e-bfc8-c4d6949e2fed
Co-authored-by: Amp <amp@ampcode.com>
- setNodeId() now calls registerWidget() with all widget metadata

- Updated BaseWidget tests with 3 new tests for automatic registration

- Fixed IWidgetOptions type to use unknown instead of unknown[]

Amp-Thread-ID: https://ampcode.com/threads/T-019c2631-966c-73a0-a399-7fe85bd6d495
Co-authored-by: Amp <amp@ampcode.com>
@DrJKL DrJKL added the preview-gpu Creates a preview ephemeral environment for this PR (GPU available) label Feb 7, 2026
Comment on lines +60 to +65
function getNodeWidgets(nodeId: NodeId): WidgetState[] {
const prefix = `${nodeId}:`
return [...widgetStates.value]
.filter(([key]) => key.startsWith(prefix))
.map(([, state]) => state)
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Are we afraid of derived maps or secondary views that would allow for O(widgets on node) queries rather than O(total widgets in graph). I know this is pretty fundamental to the entire ECS idea.

Copy link
Contributor

Choose a reason for hiding this comment

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

In theory we can leverage reactivity to determine if a sub-map is dirty or not.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Not afraid, no. I would want to see that there was a real performance issue before introducing intermediate state.

Copy link
Contributor

Choose a reason for hiding this comment

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

Would you use "intermediate state" to characterize derived/computed views on the same backing data? If computed's are intermediate state, then a lot of what we do in Vue, a lot of caching/memoization, etc. are all bad. I typically think of "intermediate state" as something that has risk of becoming desynced and/or requires cleanup and manually syncing. If not, then it can't have an inherent negative connotation really.

- Move advanced flag to widget.advanced instead of widget.options.advanced

- Include read_only in render-critical options extraction

- Remove nodeId from error fallback widget shape

Amp-Thread-ID: https://ampcode.com/threads/T-019c3b84-6254-772f-a565-7682d5af55a9
Co-authored-by: Amp <amp@ampcode.com>
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In `@src/services/litegraphService.ts`:
- Around line 218-222: The code assigns hidden to widget.options.hidden which
bypasses BaseWidget's dedicated hidden getter/setter (and its _state.hidden);
change the assignment to use the top-level property like widget.hidden =
inputSpec.hidden (matching widget.advanced = inputSpec.advanced) so the value is
stored via the BaseWidget hidden accessor instead of widget.options.hidden;
update the block where widget.options is assigned (and remove or avoid writing
hidden into widget.options) to ensure consumers/readers that use widget.hidden
see the correct value.

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.

Not done reviewing yet, posting current comments before stepping away. Finished first review.

Copy link
Contributor

@christian-byrne christian-byrne Feb 8, 2026

Choose a reason for hiding this comment

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

nit/suggestion: Consider adding logging to Sentry if node:widget-name is not unique so we can verify that invariant.

Copy link
Contributor

Choose a reason for hiding this comment

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

Do we need to add unregisterWidget(nodeId, name) and unregisterNode(nodeId), calls in LGraph.remove() or the node manager's handleNodeRemoved, or wherever appropriate?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Once we sort out the Nodes' state similarly to this and have a real sense of their removal from the overall workflow as opposed to the currently rendered graph, yes. But right now the node's underlying info is tied to whether we intend to display it which is the cause of several of the subgraph bugs (cleanup hooks being tied to removal that get called when entering or exiting a subgraph)

Comment on lines +82 to +83
private _state: Omit<WidgetState, 'nodeId'> &
Partial<Pick<WidgetState, 'nodeId'>>
Copy link
Contributor

@christian-byrne christian-byrne Feb 8, 2026

Choose a reason for hiding this comment

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

nit: Is this actually a mirrored state or just like a pending state? I am curious how to name/document this better? Also should we document that the _state reference swpas on setNodeId?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It's the pending state until the widget is registered in the store, then it's swapped for the reactive proxy.

Comment on lines 95 to 104
set hidden(value: boolean | undefined) {
this._state.hidden = value ?? false
}

get disabled(): boolean | undefined {
return this._state.disabled
}
set disabled(value: boolean | undefined) {
this._state.disabled = value ?? false
}
Copy link
Contributor

@christian-byrne christian-byrne Feb 8, 2026

Choose a reason for hiding this comment

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

question: should we add additional coercion that wasn't there before (i.e., should we be coercing to false? Worried about downstream effects)?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

We could leave it as undefined. I would hope we're not differentiating between undefined and false anywhere, but I wouldn't be shocked to find out that we were.

Comment on lines 1964 to 1968
if (
this.id !== -1 &&
'setNodeId' in widget &&
typeof widget.setNodeId === 'function'
) {
Copy link
Contributor

@christian-byrne christian-byrne Feb 8, 2026

Choose a reason for hiding this comment

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

nit: this duck type guard is repeated a few times and might be worth extracting

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Looks like it was twice, but I love a type guard 😁

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.

What I might recommend for this PR, but totally optional:

  • Move the LGraph.ensureGloablIdUniqueness, subgraph nested tests/assets/fixtures, subgraph collision ID fix to a separate PR
  • Possible move the LGraph.state get/set and subgraph sharing to above PR or in a stack
  • Move parallelization of node defs to a separate PR and considering merging on next minor version given risk vs. reward

if (node.widgets) {
for (const widget of node.widgets) {
if ('setNodeId' in widget && typeof widget.setNodeId === 'function') {
widget.setNodeId(node.id)
Copy link
Contributor

Choose a reason for hiding this comment

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

This is happening in add, why no cleanup in remove?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Because the lifecycle for nodes is a little silly, especially when packing/unpacking/traversing subgraphs.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

See earlier response 🙂

w.options?.hidden ||
(w.options?.advanced && !includesAdvanced.value)
w.hidden ||
(w.advanced && !includesAdvanced.value)
Copy link
Contributor

@christian-byrne christian-byrne Feb 8, 2026

Choose a reason for hiding this comment

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

note: I think this also will break for old/legacy widgets that are not instanceof BaseWidget

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Removed hidden/advanced, keeping those half in options for now.

Comment on lines +22 to +29
'preview_markdown',
['MARKDOWN', {}],
app
).widget as DOMWidget<HTMLTextAreaElement, string>

const showValueWidgetPlain = ComfyWidgets['STRING'](
this,
'preview',
'preview_text',
Copy link
Contributor

@christian-byrne christian-byrne Feb 8, 2026

Choose a reason for hiding this comment

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

nit (non-blocking): Technically a breaking change for a few extensions: https://cs.comfy.org/search?q=context:global+.name+%3D%3D+preview&patternType=keyword&sm=0

Copy link
Contributor Author

Choose a reason for hiding this comment

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

They depend on the internals of the Preview as Text node?

node.widgets?.forEach((w) => w.triggerDraw?.())
}

// Extract only render-critical options (canvasOnly, advanced, read_only)
Copy link
Contributor

@christian-byrne christian-byrne Feb 8, 2026

Choose a reason for hiding this comment

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

nit/question: Ah, didn't see this when I made previous comment. Wonder if it's the best solution for wiring inputSpec onto the widgets.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Almost certainly not. we'd probably want to compose this with the nodeDef store. Part of that will also be eliminating ProxyWidgets so that we can avoid having to follow the subgraph chain through to the concrete widget.

Extract the repeated setNodeId duck-type check into a NodeBindable interface in types/widgets and an isNodeBindable type guard in utils/type, replacing inline guards in LGraph and LGraphNode.

Amp-Thread-ID: https://ampcode.com/threads/T-019c405e-abb7-770d-97e9-eaa59edfe0a8
Co-authored-by: Amp <amp@ampcode.com>
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In `@src/lib/litegraph/src/LGraph.ts`:
- Around line 2539-2577: In ensureGlobalIdUniqueness, avoid choosing newId =
++state.lastNodeId that may collide with reservedNodeIds/usedNodeIds; instead,
when remapping a duplicate node (use symbols node.id, state.lastNodeId,
usedNodeIds, remappedIds, graph._nodes_by_id), advance state.lastNodeId until it
yields a value not present in usedNodeIds (e.g., increment in a loop), then
assign that newId to node.id, update graph._nodes_by_id, add the newId to
usedNodeIds and remappedIds, and ensure state.lastNodeId is set to the final
newId before calling patchLinkNodeIds on graph._links and
graph.floatingLinksInternal.
🧹 Nitpick comments (1)
src/lib/litegraph/src/widgets/BaseWidget.ts (1)

83-84: Consider extracting the complex type to a named type alias.

The inline type Omit<WidgetState, 'nodeId'> & Partial<Pick<WidgetState, 'nodeId'>> is verbose. Extracting it to a named type would improve readability.

♻️ Suggested refactor
+type WidgetStateWithOptionalNodeId = Omit<WidgetState, 'nodeId'> &
+  Partial<Pick<WidgetState, 'nodeId'>>
+
 export abstract class BaseWidget<TWidget extends IBaseWidget = IBaseWidget>
   implements IBaseWidget, NodeBindable
 {
   // ...
-  private _state: Omit<WidgetState, 'nodeId'> &
-    Partial<Pick<WidgetState, 'nodeId'>>
+  private _state: WidgetStateWithOptionalNodeId

DrJKL and others added 3 commits February 8, 2026 19:58
Advance lastNodeId in a loop until it yields a value not present in usedNodeIds, preventing reassigned IDs from colliding with reserved or already-used IDs.

Amp-Thread-ID: https://ampcode.com/threads/T-019c408a-5cee-7784-9736-4f53f9936ba4
Co-authored-by: Amp <amp@ampcode.com>
@AustinMroz
Copy link
Collaborator

Thoroughly discussed offline. PR has my approval, but will be merged after 1.40.0

@dosubot dosubot bot added size:XL This PR changes 500-999 lines, ignoring generated files. and removed size:XXL This PR changes 1000+ lines, ignoring generated files. labels Feb 10, 2026
DrJKL and others added 3 commits February 10, 2026 11:28
These are input-spec-derived properties set in litegraphService.ts, not widget runtime state. Restored as plain properties on BaseWidget and read from widget.options in the Vue renderer.

Amp-Thread-ID: https://ampcode.com/threads/T-019c48e9-f93f-773b-b6b6-d965b479a0be
Co-authored-by: Amp <amp@ampcode.com>
@Myestery Myestery linked an issue Feb 10, 2026 that may be closed by this pull request
2 tasks
@DrJKL
Copy link
Contributor Author

DrJKL commented Feb 11, 2026

What I might recommend for this PR, but totally optional:

* Move the LGraph.ensureGloablIdUniqueness, subgraph nested tests/assets/fixtures, subgraph collision ID fix to a separate PR

* Possible move the LGraph.state get/set and subgraph sharing to above PR or in a stack

* Move parallelization of node defs to a separate PR and considering merging on next minor version given risk vs. reward

Option exercised 🫡

@DrJKL DrJKL merged commit a7c2115 into main Feb 11, 2026
27 checks passed
@DrJKL DrJKL deleted the drjkl/widget-store branch February 11, 2026 03:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

preview-gpu Creates a preview ephemeral environment for this PR (GPU available) size:XL This PR changes 500-999 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

v1.39.8 - Parameter names dont update

4 participants