Skip to content

Conversation

@AustinMroz
Copy link
Collaborator

@AustinMroz AustinMroz commented Dec 16, 2025

Piecemeal fix pulled out from #7095

┆Issue is synchronized with this Notion page by Unito

@AustinMroz AustinMroz requested a review from a team as a code owner December 16, 2025 04:35
@dosubot dosubot bot added the size:S This PR changes 10-29 lines, ignoring generated files. label Dec 16, 2025
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 16, 2025

📝 Walkthrough

Walkthrough

The change introduces reactive input handling for graph nodes by wrapping node.inputs in a shallow reactive proxy with custom getter and setter methods. This ensures Vue can track and propagate input array mutations through the component state system.

Changes

Cohort / File(s) Change Summary
Reactive node inputs implementation
src/composables/graph/useGraphNodeManager.ts
Added shallowReactive wrapper for node inputs with custom getter/setter for mutation tracking; exposed reactiveInputs in GraphNode data construction to enable Vue state synchronization for input array changes

Possibly related PRs

  • Fix widget reactivity #7539: Both PRs address Vue reactivity for node state—this PR adds reactiveInputs handling in useGraphNodeManager while the related PR updates widget binding with v-model in NodeWidgets.vue.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch austin/vue-reactive-inputs

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@github-actions
Copy link

github-actions bot commented Dec 16, 2025

🎭 Playwright Test Results

⚠️ Tests passed with flaky tests

⏰ Completed at: 12/16/2025, 04:45:32 AM UTC

📈 Summary

  • Total Tests: 506
  • Passed: 495 ✅
  • Failed: 0
  • Flaky: 2 ⚠️
  • Skipped: 9 ⏭️

📊 Test Reports by Browser

  • chromium: View Report • ✅ 483 / ❌ 0 / ⚠️ 2 / ⏭️ 9
  • 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

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

@github-actions
Copy link

github-actions bot commented Dec 16, 2025

🎨 Storybook Build Status

Build completed successfully!

⏰ Completed at: 12/16/2025, 04:36:51 AM UTC

🔗 Links


🎉 Your Storybook is ready for review!

@github-actions
Copy link

Bundle Size Report

Summary

  • Raw size: 17.1 MB baseline 17.1 MB — 🔴 +230 B
  • Gzip: 3.38 MB baseline 3.38 MB — 🔴 +75 B
  • Brotli: 2.6 MB baseline 2.6 MB — 🔴 +142 B
  • Bundles: 98 current • 98 baseline • 40 added / 40 removed

Category Glance
Graph Workspace 🔴 +230 B (990 kB) · Vendor & Third-Party ⚪ 0 B (8.56 MB) · Other ⚪ 0 B (3.75 MB) · App Entry Points ⚪ 0 B (3.25 MB) · Panels & Settings ⚪ 0 B (298 kB) · UI Components ⚪ 0 B (184 kB) · + 3 more

Per-category breakdown
App Entry Points — 3.25 MB (baseline 3.25 MB) • ⚪ 0 B

Main entry bundles and manifests

File Before After Δ Raw Δ Gzip Δ Brotli
assets/index-CX2EeRDg.js (removed) 3.02 MB 🟢 -3.02 MB 🟢 -628 kB 🟢 -478 kB
assets/index-DjYiSAKG.js (new) 3.02 MB 🔴 +3.02 MB 🔴 +628 kB 🔴 +478 kB
assets/index-BHv9Uaw-.js (removed) 227 kB 🟢 -227 kB 🟢 -48.6 kB 🟢 -39.9 kB
assets/index-DIhdCM6j.js (new) 227 kB 🔴 +227 kB 🔴 +48.6 kB 🔴 +39.8 kB
assets/index-6mGyQttU.js (removed) 345 B 🟢 -345 B 🟢 -246 B 🟢 -230 B
assets/index-IKIUD1XJ.js (new) 345 B 🔴 +345 B 🔴 +246 B 🔴 +234 B

Status: 3 added / 3 removed

Graph Workspace — 990 kB (baseline 990 kB) • 🔴 +230 B

Graph editor runtime, canvas, workflow orchestration

File Before After Δ Raw Δ Gzip Δ Brotli
assets/GraphView-Bxrpz9wa.js (new) 990 kB 🔴 +990 kB 🔴 +191 kB 🔴 +146 kB
assets/GraphView-TW5sZCW4.js (removed) 990 kB 🟢 -990 kB 🟢 -191 kB 🟢 -146 kB

Status: 1 added / 1 removed

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

Top-level views, pages, and routed surfaces

File Before After Δ Raw Δ Gzip Δ Brotli
assets/UserSelectView-BNB7zbT7.js (removed) 6.54 kB 🟢 -6.54 kB 🟢 -2.14 kB 🟢 -1.89 kB
assets/UserSelectView-DuEgzTB3.js (new) 6.54 kB 🔴 +6.54 kB 🔴 +2.14 kB 🔴 +1.89 kB

Status: 1 added / 1 removed

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

Configuration panels, inspectors, and settings screens

File Before After Δ Raw Δ Gzip Δ Brotli
assets/LegacyCreditsPanel-BqHI9CEY.js (new) 21.4 kB 🔴 +21.4 kB 🔴 +5.15 kB 🔴 +4.51 kB
assets/LegacyCreditsPanel-Dod1LC3J.js (removed) 21.4 kB 🟢 -21.4 kB 🟢 -5.15 kB 🟢 -4.5 kB
assets/KeybindingPanel-DLGDRPVq.js (removed) 13.6 kB 🟢 -13.6 kB 🟢 -3.42 kB 🟢 -3.02 kB
assets/KeybindingPanel-TaQ7dfZ7.js (new) 13.6 kB 🔴 +13.6 kB 🔴 +3.42 kB 🔴 +3.01 kB
assets/ExtensionPanel-BrmFrsUD.js (removed) 10.8 kB 🟢 -10.8 kB 🟢 -2.57 kB 🟢 -2.26 kB
assets/ExtensionPanel-CmnOhRVG.js (new) 10.8 kB 🔴 +10.8 kB 🔴 +2.57 kB 🔴 +2.25 kB
assets/AboutPanel-BL9NrSjd.js (new) 9.16 kB 🔴 +9.16 kB 🔴 +2.46 kB 🔴 +2.21 kB
assets/AboutPanel-C67Z2J5b.js (removed) 9.16 kB 🟢 -9.16 kB 🟢 -2.46 kB 🟢 -2.21 kB
assets/ServerConfigPanel-BvWSq-WJ.js (new) 6.56 kB 🔴 +6.56 kB 🔴 +1.83 kB 🔴 +1.63 kB
assets/ServerConfigPanel-UnHvXSM0.js (removed) 6.56 kB 🟢 -6.56 kB 🟢 -1.83 kB 🟢 -1.63 kB
assets/UserPanel-Bz7XB-0I.js (new) 6.23 kB 🔴 +6.23 kB 🔴 +1.72 kB 🔴 +1.51 kB
assets/UserPanel-CNEbtf26.js (removed) 6.23 kB 🟢 -6.23 kB 🟢 -1.72 kB 🟢 -1.51 kB
assets/settings-B_sqawkt.js 27.3 kB 27.3 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-BhbWhsRg.js 101 B 101 B ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-BlDXT7wp.js 21.7 kB 21.7 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-Bz8HAvJu.js 21.1 kB 21.1 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-C2vW8UNv.js 24.2 kB 24.2 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-C9vsDM17.js 25.1 kB 25.1 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-DWD49kQp.js 33.3 kB 33.3 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-DZE27_Iz.js 25.9 kB 25.9 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-OXaZPcZF.js 26.6 kB 26.6 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-RbkKsnDG.js 25.2 kB 25.2 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B

Status: 6 added / 6 removed

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

Reusable component library chunks

File Before After Δ Raw Δ Gzip Δ Brotli
assets/Load3D.vue_vue_type_script_setup_true_lang-Bpo-5pwL.js (new) 53.7 kB 🔴 +53.7 kB 🔴 +8.49 kB 🔴 +7.29 kB
assets/Load3D.vue_vue_type_script_setup_true_lang-d0LE2vib.js (removed) 53.7 kB 🟢 -53.7 kB 🟢 -8.48 kB 🟢 -7.29 kB
assets/WidgetSelect.vue_vue_type_script_setup_true_lang-BLH1oCgX.js (new) 48 kB 🔴 +48 kB 🔴 +10.4 kB 🔴 +8.99 kB
assets/WidgetSelect.vue_vue_type_script_setup_true_lang-Bv7vM7eL.js (removed) 48 kB 🟢 -48 kB 🟢 -10.3 kB 🟢 -8.97 kB
assets/LazyImage.vue_vue_type_script_setup_true_lang-ChpTTBZD.js (new) 48 kB 🔴 +48 kB 🔴 +10.7 kB 🔴 +9.32 kB
assets/LazyImage.vue_vue_type_script_setup_true_lang-CmpZA0J6.js (removed) 48 kB 🟢 -48 kB 🟢 -10.7 kB 🟢 -9.32 kB
assets/WidgetInputNumber.vue_vue_type_script_setup_true_lang-BuunoKqM.js (removed) 19.5 kB 🟢 -19.5 kB 🟢 -5.04 kB 🟢 -4.47 kB
assets/WidgetInputNumber.vue_vue_type_script_setup_true_lang-s7Vg-1Z9.js (new) 19.5 kB 🔴 +19.5 kB 🔴 +5.05 kB 🔴 +4.48 kB
assets/ComfyQueueButton-Bhi-CRoa.js (removed) 8.44 kB 🟢 -8.44 kB 🟢 -2.48 kB 🟢 -2.21 kB
assets/ComfyQueueButton-duVjT6rE.js (new) 8.44 kB 🔴 +8.44 kB 🔴 +2.48 kB 🔴 +2.22 kB
assets/WidgetLayoutField.vue_vue_type_script_setup_true_lang-qCsXeZ9Z.js (removed) 2.14 kB 🟢 -2.14 kB 🟢 -889 B 🟢 -765 B
assets/WidgetLayoutField.vue_vue_type_script_setup_true_lang-UVIGyICZ.js (new) 2.14 kB 🔴 +2.14 kB 🔴 +891 B 🔴 +768 B
assets/MediaTitle.vue_vue_type_script_setup_true_lang-BCCMCU1S.js (new) 897 B 🔴 +897 B 🔴 +502 B 🔴 +435 B
assets/MediaTitle.vue_vue_type_script_setup_true_lang-WSVLl_ZV.js (removed) 897 B 🟢 -897 B 🟢 -501 B 🟢 -443 B
assets/UserAvatar.vue_vue_type_script_setup_true_lang-CiSnQExp.js 1.34 kB 1.34 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/WidgetButton-CUWIT83D.js 2.04 kB 2.04 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B

Status: 7 added / 7 removed

Data & Services — 12.5 kB (baseline 12.5 kB) • ⚪ 0 B

Stores, services, APIs, and repositories

File Before After Δ Raw Δ Gzip Δ Brotli
assets/keybindingService-C62TmCOD.js (new) 7.51 kB 🔴 +7.51 kB 🔴 +1.83 kB 🔴 +1.58 kB
assets/keybindingService-CaD648sL.js (removed) 7.51 kB 🟢 -7.51 kB 🟢 -1.84 kB 🟢 -1.58 kB
assets/audioService-BhCNJmmw.js (new) 2.2 kB 🔴 +2.2 kB 🔴 +961 B 🔴 +821 B
assets/audioService-DeIumDCU.js (removed) 2.2 kB 🟢 -2.2 kB 🟢 -959 B 🟢 -830 B
assets/serverConfigStore-Bwn3ENCR.js 2.83 kB 2.83 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B

Status: 2 added / 2 removed

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

Helpers, composables, and utility bundles

File Before After Δ Raw Δ Gzip Δ Brotli
assets/audioUtils-Bh_e5zz4.js (new) 1.41 kB 🔴 +1.41 kB 🔴 +653 B 🔴 +553 B
assets/audioUtils-T2UjDRq9.js (removed) 1.41 kB 🟢 -1.41 kB 🟢 -652 B 🟢 -547 B
assets/mathUtil-CD4DsosH.js 1.32 kB 1.32 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeFilterUtil-CXKCRJ-m.js 460 B 460 B ⚪ 0 B ⚪ 0 B ⚪ 0 B

Status: 1 added / 1 removed

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

External libraries and shared vendor chunks

File Before After Δ Raw Δ Gzip Δ Brotli
assets/vendor-chart-Cqf0KagN.js 452 kB 452 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/vendor-other-S7nymsLT.js 3.98 MB 3.98 MB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/vendor-primevue-BzWEaXhK.js 1.96 MB 1.96 MB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/vendor-three-aR6ntw5X.js 1.37 MB 1.37 MB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/vendor-tiptap-BIIubbA1.js 232 kB 232 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/vendor-vue-BPEtaHlw.js 160 kB 160 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/vendor-xterm-BZLod3g9.js 407 kB 407 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
Other — 3.75 MB (baseline 3.75 MB) • ⚪ 0 B

Bundles that do not match a named category

File Before After Δ Raw Δ Gzip Δ Brotli
assets/WidgetRecordAudio-BVuDfrLP.js (new) 20.4 kB 🔴 +20.4 kB 🔴 +5.23 kB 🔴 +4.62 kB
assets/WidgetRecordAudio-CO71vYus.js (removed) 20.4 kB 🟢 -20.4 kB 🟢 -5.23 kB 🟢 -4.63 kB
assets/AudioPreviewPlayer-_9u8bfb4.js (new) 13.4 kB 🔴 +13.4 kB 🔴 +3.37 kB 🔴 +3 kB
assets/AudioPreviewPlayer-vHkhDVtB.js (removed) 13.4 kB 🟢 -13.4 kB 🟢 -3.37 kB 🟢 -3.01 kB
assets/NumberControlPopover-CQP1rk8R.js (new) 6.31 kB 🔴 +6.31 kB 🔴 +1.93 kB 🔴 +1.71 kB
assets/NumberControlPopover-DUpiyWpm.js (removed) 6.31 kB 🟢 -6.31 kB 🟢 -1.93 kB 🟢 -1.71 kB
assets/WidgetGalleria-Be1Atsd6.js (new) 4.1 kB 🔴 +4.1 kB 🔴 +1.44 kB 🔴 +1.3 kB
assets/WidgetGalleria-BNU4IUbg.js (removed) 4.1 kB 🟢 -4.1 kB 🟢 -1.44 kB 🟢 -1.3 kB
assets/WidgetColorPicker-BsGH1tRU.js (removed) 3.41 kB 🟢 -3.41 kB 🟢 -1.38 kB 🟢 -1.23 kB
assets/WidgetColorPicker-Cps7yA3Q.js (new) 3.41 kB 🔴 +3.41 kB 🔴 +1.38 kB 🔴 +1.23 kB
assets/WidgetTextarea-BuHJCnxp.js (new) 3.08 kB 🔴 +3.08 kB 🔴 +1.21 kB 🔴 +1.08 kB
assets/WidgetTextarea-DTv99XUR.js (removed) 3.08 kB 🟢 -3.08 kB 🟢 -1.21 kB 🟢 -1.08 kB
assets/WidgetMarkdown-A-wMQg0O.js (removed) 3.08 kB 🟢 -3.08 kB 🟢 -1.28 kB 🟢 -1.12 kB
assets/WidgetMarkdown-DDbNumLs.js (new) 3.08 kB 🔴 +3.08 kB 🔴 +1.28 kB 🔴 +1.12 kB
assets/WidgetAudioUI-Brwl5JPB.js (new) 2.86 kB 🔴 +2.86 kB 🔴 +1.17 kB 🔴 +1.05 kB
assets/WidgetAudioUI-snJWitA0.js (removed) 2.86 kB 🟢 -2.86 kB 🟢 -1.17 kB 🟢 -1.06 kB
assets/WidgetInputText-Co7oyXND.js (new) 1.99 kB 🔴 +1.99 kB 🔴 +920 B 🔴 +851 B
assets/WidgetInputText-CXcYa6ij.js (removed) 1.99 kB 🟢 -1.99 kB 🟢 -918 B 🟢 -852 B
assets/WidgetToggleSwitch-Cv-ZMUzN.js (removed) 1.76 kB 🟢 -1.76 kB 🟢 -833 B 🟢 -735 B
assets/WidgetToggleSwitch-D3GEQKAJ.js (new) 1.76 kB 🔴 +1.76 kB 🔴 +835 B 🔴 +734 B
assets/MediaImageBottom-BKUqs1jY.js (new) 1.55 kB 🔴 +1.55 kB 🔴 +737 B 🔴 +640 B
assets/MediaImageBottom-CANTB5AZ.js (removed) 1.55 kB 🟢 -1.55 kB 🟢 -735 B 🟢 -641 B
assets/MediaAudioBottom-BTlFY4zc.js (removed) 1.51 kB 🟢 -1.51 kB 🟢 -733 B 🟢 -650 B
assets/MediaAudioBottom-C55f0dXR.js (new) 1.51 kB 🔴 +1.51 kB 🔴 +735 B 🔴 +650 B
assets/Media3DBottom-BrnM9z5P.js (removed) 1.5 kB 🟢 -1.5 kB 🟢 -732 B 🟢 -650 B
assets/Media3DBottom-DYbdDLEP.js (new) 1.5 kB 🔴 +1.5 kB 🔴 +732 B 🔴 +650 B
assets/MediaVideoBottom-CH_1iTE-.js (new) 1.5 kB 🔴 +1.5 kB 🔴 +731 B 🔴 +649 B
assets/MediaVideoBottom-nog9B3Xd.js (removed) 1.5 kB 🟢 -1.5 kB 🟢 -730 B 🟢 -649 B
assets/Media3DTop-BqSVjHt4.js (removed) 1.49 kB 🟢 -1.49 kB 🟢 -765 B 🟢 -653 B
assets/Media3DTop-DK7nqzyC.js (new) 1.49 kB 🔴 +1.49 kB 🔴 +766 B 🔴 +652 B
assets/WidgetSelect-BY2bSFV-.js (removed) 655 B 🟢 -655 B 🟢 -342 B 🟢 -291 B
assets/WidgetSelect-CCoDhkkC.js (new) 655 B 🔴 +655 B 🔴 +346 B 🔴 +292 B
assets/WidgetInputNumber-BM2A1VrU.js (removed) 595 B 🟢 -595 B 🟢 -327 B 🟢 -271 B
assets/WidgetInputNumber-Cx0z8MEF.js (new) 595 B 🔴 +595 B 🔴 +331 B 🔴 +275 B
assets/Load3D-B4wv9k_p.js (removed) 424 B 🟢 -424 B 🟢 -267 B 🟢 -225 B
assets/Load3D-sQxu9rho.js (new) 424 B 🔴 +424 B 🔴 +267 B 🔴 +225 B
assets/WidgetLegacy-9iE38ITx.js (new) 364 B 🔴 +364 B 🔴 +238 B 🔴 +228 B
assets/WidgetLegacy-CAIFqYji.js (removed) 364 B 🟢 -364 B 🟢 -238 B 🟢 -196 B
assets/commands-_s-RvhJR.js 13.6 kB 13.6 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-BuUILW6P.js 13 kB 13 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-BV4R6fLx.js 14.9 kB 14.9 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-BWp4HdfU.js 101 B 101 B ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-CLwPdnT6.js 14.2 kB 14.2 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-CWMchBmd.js 15.9 kB 15.9 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-DazTQhtc.js 12.9 kB 12.9 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-DmWrOe93.js 13.7 kB 13.7 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-DwiH7Kr6.js 13.8 kB 13.8 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-mS3LCNPn.js 14.5 kB 14.5 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-6nlVHpc-.js 73.1 kB 73.1 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-B_3IONzJ.js 113 kB 113 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-BqRsXvrH.js 72.2 kB 72.2 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-BZ-vlW9L.js 94 kB 94 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-C3etCTkn.js 83.4 kB 83.4 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-CG-hMOv1.js 84.2 kB 84.2 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-ChsXwF7G.js 86.5 kB 86.5 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-Cw9RZWRY.js 89 B 89 B ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-DjVXiGQX.js 99 kB 99 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-Xp7hXzT2.js 81.7 kB 81.7 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/MediaAudioTop-FQz4Thvl.js 1.46 kB 1.46 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/MediaImageTop-B3anU6gM.js 1.75 kB 1.75 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/MediaVideoTop-DhI-keBK.js 2.65 kB 2.65 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-B1kKcnvT.js 303 kB 303 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-BoX8ObAh.js 300 kB 300 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-Bw_Jitw_.js 101 B 101 B ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-BZQ0wolS.js 360 kB 360 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-CHUJIOIF.js 310 kB 310 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-DAU0PVOW.js 297 kB 297 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-Db5kOxDZ.js 299 kB 299 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-DgiIrZvP.js 276 kB 276 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-DU4sfqO1.js 334 kB 334 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-Dw-Pdf3f.js 279 kB 279 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/WidgetChart-CtDKuluF.js 2.48 kB 2.48 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/WidgetImageCompare-DDdUO9Q8.js 2.21 kB 2.21 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/widgetPropFilter-BIbGSUAt.js 1.28 kB 1.28 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B

Status: 19 added / 19 removed

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: 2

📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 4e257be and 9e588d4.

📒 Files selected for processing (1)
  • src/composables/graph/useGraphNodeManager.ts (2 hunks)
🧰 Additional context used
📓 Path-based instructions (10)
src/**/*.{vue,ts}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

src/**/*.{vue,ts}: Leverage VueUse functions for performance-enhancing styles
Implement proper error handling
Use vue-i18n in composition API for any string literals. Place new translation entries in src/locales/en/main.json

Files:

  • src/composables/graph/useGraphNodeManager.ts
src/**/*.ts

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

src/**/*.ts: Use es-toolkit for utility functions
Use TypeScript for type safety

Minimize the surface area (exported values) of each module and composable

Files:

  • src/composables/graph/useGraphNodeManager.ts
src/**/{services,composables}/**/*.{ts,tsx}

📄 CodeRabbit inference engine (src/CLAUDE.md)

src/**/{services,composables}/**/*.{ts,tsx}: Use api.apiURL() for backend endpoints instead of constructing URLs directly
Use api.fileURL() for static file access instead of constructing URLs directly

Files:

  • src/composables/graph/useGraphNodeManager.ts
src/**/*.{ts,tsx,vue}

📄 CodeRabbit inference engine (src/CLAUDE.md)

src/**/*.{ts,tsx,vue}: Sanitize HTML with DOMPurify to prevent XSS attacks
Avoid using @ts-expect-error; use proper TypeScript types instead
Use es-toolkit for utility functions instead of other utility libraries
Implement proper TypeScript types throughout the codebase

Files:

  • src/composables/graph/useGraphNodeManager.ts
src/**/{composables,components}/**/*.{ts,tsx,vue}

📄 CodeRabbit inference engine (src/CLAUDE.md)

Clean up subscriptions in state management to prevent memory leaks

Files:

  • src/composables/graph/useGraphNodeManager.ts
src/**/*.{vue,ts,tsx}

📄 CodeRabbit inference engine (src/CLAUDE.md)

Follow Vue 3 composition API style guide

Files:

  • src/composables/graph/useGraphNodeManager.ts
src/**/{components,composables}/**/*.{ts,tsx,vue}

📄 CodeRabbit inference engine (src/CLAUDE.md)

Use vue-i18n for ALL user-facing strings by adding them to src/locales/en/main.json

Files:

  • src/composables/graph/useGraphNodeManager.ts
src/composables/**/*.ts

📄 CodeRabbit inference engine (AGENTS.md)

Composable files must follow the naming pattern useXyz.ts

Files:

  • src/composables/graph/useGraphNodeManager.ts
**/*.{ts,tsx,js,jsx,vue,json}

📄 CodeRabbit inference engine (AGENTS.md)

Code style: Use 2-space indentation, single quotes, no trailing semicolons, and 80-character line width (see .prettierrc)

Files:

  • src/composables/graph/useGraphNodeManager.ts
**/*.{ts,tsx,vue}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{ts,tsx,vue}: Imports must be sorted and grouped by plugin; run pnpm format before committing
Use TypeScript for type safety; never use any type - use proper TypeScript types
Never use as any type assertions; fix the underlying type issue instead
Use es-toolkit for utility functions
Write code that is expressive and self-documenting; avoid comments unless absolutely necessary; do not add or retain redundant comments
Keep functions short and functional
Minimize nesting in code (e.g., deeply nested if or for statements); apply the Arrow Anti-Pattern principle
Avoid mutable state; prefer immutability and assignment at point of declaration
Favor pure functions, especially testable ones

Files:

  • src/composables/graph/useGraphNodeManager.ts
🧠 Learnings (9)
📓 Common learnings
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T19:47:02.860Z
Learning: Applies to src/**/*.vue : Utilize ref and reactive for reactive state
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-09T20:22:23.620Z
Learning: Applies to **/*.vue : Use `ref` for reactive state in Vue Composition API components
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Use ref/reactive for state management in Vue 3 Composition API
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Replace PrimeVue InputSwitch component with ToggleSwitch
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-09T20:22:23.620Z
Learning: Applies to **/*.vue : Use Vue 3.5 TypeScript style for default prop declaration with reactive props destructuring; do not use `withDefaults` or runtime props declaration
Learnt from: simula-r
Repo: Comfy-Org/ComfyUI_frontend PR: 7252
File: src/renderer/extensions/vueNodes/components/ImagePreview.vue:151-158
Timestamp: 2025-12-11T03:55:57.926Z
Learning: In src/renderer/extensions/vueNodes/components/ImagePreview.vue and LGraphNode.vue, keyboard navigation for image galleries should respond to node-level focus (via keyEvent injection from LGraphNode), not require focus within the image preview wrapper itself. This allows users to navigate the gallery with arrow keys immediately when the node is focused/selected.
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7137
File: src/components/rightSidePanel/parameters/TabParameters.vue:10-0
Timestamp: 2025-12-04T21:43:49.363Z
Learning: Vue 3.5+ supports reactive props destructure in <script setup>. Destructuring props directly (e.g., `const { nodes } = defineProps<{ nodes: LGraphNode[] }>()`) maintains reactivity through compiler transformation. This is the recommended modern approach and does not require using `props.x` or `toRef`/`toRefs`.
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Prefer emit/event-name for state changes over other communication patterns
📚 Learning: 2025-12-04T21:43:49.363Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7137
File: src/components/rightSidePanel/parameters/TabParameters.vue:10-0
Timestamp: 2025-12-04T21:43:49.363Z
Learning: Vue 3.5+ supports reactive props destructure in <script setup>. Destructuring props directly (e.g., `const { nodes } = defineProps<{ nodes: LGraphNode[] }>()`) maintains reactivity through compiler transformation. This is the recommended modern approach and does not require using `props.x` or `toRef`/`toRefs`.

Applied to files:

  • src/composables/graph/useGraphNodeManager.ts
📚 Learning: 2025-11-24T19:47:02.860Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T19:47:02.860Z
Learning: Applies to src/**/*.vue : Utilize ref and reactive for reactive state

Applied to files:

  • src/composables/graph/useGraphNodeManager.ts
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Use ref/reactive for state management in Vue 3 Composition API

Applied to files:

  • src/composables/graph/useGraphNodeManager.ts
📚 Learning: 2025-12-09T20:22:23.620Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-09T20:22:23.620Z
Learning: Applies to **/*.vue : Use `ref` for reactive state in Vue Composition API components

Applied to files:

  • src/composables/graph/useGraphNodeManager.ts
📚 Learning: 2025-12-11T03:55:57.926Z
Learnt from: simula-r
Repo: Comfy-Org/ComfyUI_frontend PR: 7252
File: src/renderer/extensions/vueNodes/components/ImagePreview.vue:151-158
Timestamp: 2025-12-11T03:55:57.926Z
Learning: In src/renderer/extensions/vueNodes/components/ImagePreview.vue and LGraphNode.vue, keyboard navigation for image galleries should respond to node-level focus (via keyEvent injection from LGraphNode), not require focus within the image preview wrapper itself. This allows users to navigate the gallery with arrow keys immediately when the node is focused/selected.

Applied to files:

  • src/composables/graph/useGraphNodeManager.ts
📚 Learning: 2025-12-09T03:39:54.501Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7169
File: src/platform/remote/comfyui/jobs/jobTypes.ts:1-107
Timestamp: 2025-12-09T03:39:54.501Z
Learning: In the ComfyUI_frontend project, Zod is on v3.x. Do not suggest Zod v4 standalone validators (z.uuid, z.ulid, z.cuid2, z.nanoid) until an upgrade to Zod 4 is performed. When reviewing TypeScript files (e.g., src/platform/remote/comfyui/jobs/jobTypes.ts) validate against Zod 3 capabilities and avoid introducing v4-specific features; flag any proposal to upgrade or incorporate v4-only validators and propose staying with compatible 3.x patterns.

Applied to files:

  • src/composables/graph/useGraphNodeManager.ts
📚 Learning: 2025-12-13T11:03:11.264Z
Learnt from: christian-byrne
Repo: Comfy-Org/ComfyUI_frontend PR: 7416
File: src/stores/imagePreviewStore.ts:5-7
Timestamp: 2025-12-13T11:03:11.264Z
Learning: In the ComfyUI_frontend repository, lint rules require keeping 'import type' statements separate from non-type imports, even if importing from the same module. Do not suggest consolidating them into a single import statement. Ensure type imports remain on their own line (import type { ... } from 'module') and regular imports stay on separate lines.

Applied to files:

  • src/composables/graph/useGraphNodeManager.ts
📚 Learning: 2025-12-11T12:25:15.470Z
Learnt from: christian-byrne
Repo: Comfy-Org/ComfyUI_frontend PR: 7358
File: src/components/dialog/content/signin/SignUpForm.vue:45-54
Timestamp: 2025-12-11T12:25:15.470Z
Learning: This repository uses CI automation to format code (pnpm format). Do not include manual formatting suggestions in code reviews for Comfy-Org/ComfyUI_frontend. If formatting issues are detected, rely on the CI formatter or re-run pnpm format. Focus reviews on correctness, readability, performance, accessibility, and maintainability rather than style formatting.

Applied to files:

  • src/composables/graph/useGraphNodeManager.ts
🧬 Code graph analysis (1)
src/composables/graph/useGraphNodeManager.ts (1)
src/lib/litegraph/src/interfaces.ts (1)
  • INodeInputSlot (343-352)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
  • GitHub Check: lint-and-format
  • GitHub Check: setup
  • GitHub Check: collect
  • GitHub Check: test

Comment on lines +221 to +229
const reactiveInputs = shallowReactive<INodeInputSlot[]>(node.inputs ?? [])
Object.defineProperty(node, 'inputs', {
get() {
return reactiveInputs
},
set(v) {
reactiveInputs.splice(0, reactiveInputs.length, ...v)
}
})
Copy link
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick | 🔵 Trivial

🧩 Analysis chain

🏁 Script executed:

cat -n src/composables/graph/useGraphNodeManager.ts | head -250 | tail -50

Repository: Comfy-Org/ComfyUI_frontend

Length of output: 2020


🏁 Script executed:

cat -n src/composables/graph/useGraphNodeManager.ts | head -230 | tail -30

Repository: Comfy-Org/ComfyUI_frontend

Length of output: 1265


🏁 Script executed:

rg -n 'node\.inputs' --type=ts --type=vue -A 2 -B 2 | head -100

Repository: Comfy-Org/ComfyUI_frontend

Length of output: 97


🏁 Script executed:

rg -n 'Object\.defineProperty' --type=ts --type=vue -A 5 | head -150

Repository: Comfy-Org/ComfyUI_frontend

Length of output: 97


🏁 Script executed:

rg -n 'this\.inputs' src/lib/litegraph/ --type=ts -A 2 -B 2 | head -80

Repository: Comfy-Org/ComfyUI_frontend

Length of output: 5581


🏁 Script executed:

rg -n 'Object\.keys|Object\.entries|Object\.getOwnProperty' --type=ts src/composables/ src/components/ | grep -i node

Repository: Comfy-Org/ComfyUI_frontend

Length of output: 281


🏁 Script executed:

rg -n 'for.*in.*node|for.*in.*this' --type=ts src/lib/litegraph/ | head -30

Repository: Comfy-Org/ComfyUI_frontend

Length of output: 3572


🏁 Script executed:

rg -n 'Object\.defineProperty.*node.*inputs|Object\.defineProperty.*node.*widgets' --type=ts

Repository: Comfy-Org/ComfyUI_frontend

Length of output: 256


🏁 Script executed:

rg -n 'node\.inputs' src/composables/ --type=ts -B 2 -A 2 | head -50

Repository: Comfy-Org/ComfyUI_frontend

Length of output: 2597


🏁 Script executed:

fd useGraphNodeManager -type f

Repository: Comfy-Org/ComfyUI_frontend

Length of output: 240


🏁 Script executed:

node << 'EOF'
const obj = {};
Object.defineProperty(obj, 'test', {
  get() { return 42; }
});
const descriptor = Object.getOwnPropertyDescriptor(obj, 'test');
console.log('Default descriptor:', descriptor);
console.log('Can iterate with for...of:', [...Object.keys(obj), 'N/A']);
// Test for...of on array with property
const arr = [1, 2, 3];
Object.defineProperty(arr, 'custom', { get() { return 99; } });
for (const item of arr) {
  console.log('for...of item:', item);
}
console.log('custom property in for...of:', 'custom' in arr ? arr.custom : 'not iterated');
EOF

Repository: Comfy-Org/ComfyUI_frontend

Length of output: 298


🏁 Script executed:

rg -n 'shallowReactive' src/composables/graph/ --type=ts -B 2 -A 8 | head -80

Repository: Comfy-Org/ComfyUI_frontend

Length of output: 2476


🏁 Script executed:

find . -name "*.test.ts" -o -name "*.spec.ts" | xargs grep -l "useGraphNodeManager\|extractVueNodeData" 2>/dev/null

Repository: Comfy-Org/ComfyUI_frontend

Length of output: 682


🏁 Script executed:

rg -n 'Object\.defineProperty' src/ --type=ts -B 3 -A 3 | head -60

Repository: Comfy-Org/ComfyUI_frontend

Length of output: 5533


🏁 Script executed:

rg -n 'node\.inputs\s*=' --type=ts src/composables/ src/components/

Repository: Comfy-Org/ComfyUI_frontend

Length of output: 52


🏁 Script executed:

rg -n 'node\.widgets\s*=' --type=ts src/composables/ src/components/

Repository: Comfy-Org/ComfyUI_frontend

Length of output: 52


🏁 Script executed:

grep -r "configurable\|enumerable" src/composables/ src/components/ --include="*.ts" 2>/dev/null | head -20

Repository: Comfy-Org/ComfyUI_frontend

Length of output: 207


The reactive properties for inputs and widgets are correctly implemented without explicit descriptor flags. While adding configurable: true and enumerable: true would be defensive best-practice for future-proofing (similar to patterns in Storybook code), the current implementation poses no actual compatibility issues:

  • for...of iteration (used throughout the codebase) works on arrays regardless of enumerable flag
  • No code attempts to reassign node.inputs or node.widgets after initial setup
  • Default flags (enumerable: false, configurable: false) do not prevent the current usage patterns

Adding descriptor flags is optional, but if you want to follow defensive coding practices, apply this diff:

 const reactiveInputs = shallowReactive<INodeInputSlot[]>(node.inputs ?? [])
 Object.defineProperty(node, 'inputs', {
+  configurable: true,
+  enumerable: true,
   get() {
     return reactiveInputs
   },
   set(v) {
     reactiveInputs.splice(0, reactiveInputs.length, ...v)
   }
 })

And similarly for widgets at lines 212–220.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const reactiveInputs = shallowReactive<INodeInputSlot[]>(node.inputs ?? [])
Object.defineProperty(node, 'inputs', {
get() {
return reactiveInputs
},
set(v) {
reactiveInputs.splice(0, reactiveInputs.length, ...v)
}
})
const reactiveInputs = shallowReactive<INodeInputSlot[]>(node.inputs ?? [])
Object.defineProperty(node, 'inputs', {
configurable: true,
enumerable: true,
get() {
return reactiveInputs
},
set(v) {
reactiveInputs.splice(0, reactiveInputs.length, ...v)
}
})
🤖 Prompt for AI Agents
In src/composables/graph/useGraphNodeManager.ts around lines 212–220 (widgets)
and 221–229 (inputs), the Object.defineProperty calls omit descriptor flags;
update both property descriptors to include configurable: true and enumerable:
true so the properties are defensively reusable—i.e., augment the existing
defineProperty options for node.widgets and node.inputs to explicitly set
configurable: true and enumerable: true while keeping the same getter and setter
logic.

Comment on lines +264 to 265
inputs: reactiveInputs,
outputs: node.outputs ? [...node.outputs] : undefined,
Copy link
Contributor

@coderabbitai coderabbitai bot Dec 16, 2025

Choose a reason for hiding this comment

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

🧹 Nitpick | 🔵 Trivial

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Get context around lines 264-265 in the target file
echo "=== File context around lines 264-265 ==="
wc -l src/composables/graph/useGraphNodeManager.ts

Repository: Comfy-Org/ComfyUI_frontend

Length of output: 160


🏁 Script executed:

#!/bin/bash
# Read the relevant section of the file
sed -n '240,290p' src/composables/graph/useGraphNodeManager.ts

Repository: Comfy-Org/ComfyUI_frontend

Length of output: 1502


🏁 Script executed:

#!/bin/bash
# Check if outputs are mutated dynamically like inputs
echo "=== Checking for node.outputs mutations ==="
rg -n -C3 --type=ts --type=vue 'node\.outputs\s*=|\.outputs\s*\[.*\]\s*=' || echo "No direct mutations found"

echo -e "\n=== Checking for outputs array mutations (push/pop/splice/etc) ==="
rg -n -C3 --type=ts --type=vue '\.outputs\.(push|pop|splice|shift|unshift)' || echo "No array method mutations found"

echo -e "\n=== Checking for outputs property access/mutation ==="
rg -n --type=ts --type=vue 'outputs' src/composables/graph/useGraphNodeManager.ts | head -20

Repository: Comfy-Org/ComfyUI_frontend

Length of output: 395


🏁 Script executed:

#!/bin/bash
# Find where reactiveInputs is created in the file
sed -n '200,270p' src/composables/graph/useGraphNodeManager.ts

Repository: Comfy-Org/ComfyUI_frontend

Length of output: 2316


🏁 Script executed:

#!/bin/bash
# Search for reactiveInputs definition in the entire file
rg -n 'reactiveInputs' src/composables/graph/useGraphNodeManager.ts -B5 -A5

Repository: Comfy-Org/ComfyUI_frontend

Length of output: 1034


🏁 Script executed:

#!/bin/bash
# Check broader usage of outputs in the codebase to see if it's modified anywhere
rg -n 'outputs' src/composables/graph/ --type=ts -A2 -B2 | head -80

Repository: Comfy-Org/ComfyUI_frontend

Length of output: 1312


🏁 Script executed:

#!/bin/bash
# Search across entire src directory for outputs mutations/modifications
echo "=== Searching for outputs property assignments ==="
rg '\bnode\.outputs\s*=' src/ --type=ts -A2 -B2 || echo "No node.outputs assignments"

echo -e "\n=== Searching for outputs in returned data being modified ==="
rg 'vueNode\.outputs|nodeData\.outputs' src/ --type=ts -A2 -B2 | head -40

echo -e "\n=== Check if outputs are used in reactiveComputed like inputs ==="
rg 'node\.outputs' src/composables/graph/useGraphNodeManager.ts -B2 -A2

Repository: Comfy-Org/ComfyUI_frontend

Length of output: 1577


🏁 Script executed:

#!/bin/bash
# Check how VueNodeData outputs are used in components
echo "=== Search for outputs usage in Vue components ==="
rg 'outputs' src/components/ --type=ts -l | head -10

Repository: Comfy-Org/ComfyUI_frontend

Length of output: 313


🏁 Script executed:

#!/bin/bash
# Get the exact pattern used for reactiveInputs to verify the suggested diff
sed -n '221,229p' src/composables/graph/useGraphNodeManager.ts

Repository: Comfy-Org/ComfyUI_frontend

Length of output: 338


🏁 Script executed:

#!/bin/bash
# Check for any comments or TODOs about outputs handling
rg -n 'outputs|TODO|FIXME' src/composables/graph/useGraphNodeManager.ts | grep -i 'output' | head -10

Repository: Comfy-Org/ComfyUI_frontend

Length of output: 237


🏁 Script executed:

#!/bin/bash
# Verify the VueNodeData type definition to see outputs type
rg -n 'interface VueNodeData|type VueNodeData' src/composables/graph/useGraphNodeManager.ts -A20

Repository: Comfy-Org/ComfyUI_frontend

Length of output: 584


Apply the same reactive pattern to outputs for consistency with inputs.

Outputs are currently returned as a shallow copy ([...node.outputs]) while inputs use a shallowReactive wrapper with property interception. This creates an inconsistency in reactivity tracking. Additionally, outputs are mutated dynamically in the codebase (e.g., in src/utils/linkFixer.ts), so they should be reactive to ensure proper Vue tracking.

Apply the same reactive pattern used for inputs:

 const reactiveInputs = shallowReactive<INodeInputSlot[]>(node.inputs ?? [])
 Object.defineProperty(node, 'inputs', {
   get() {
     return reactiveInputs
   },
   set(v) {
     reactiveInputs.splice(0, reactiveInputs.length, ...v)
   }
 })
+const reactiveOutputs = shallowReactive<INodeOutputSlot[]>(node.outputs ?? [])
+Object.defineProperty(node, 'outputs', {
+  get() {
+    return reactiveOutputs
+  },
+  set(v) {
+    reactiveOutputs.splice(0, reactiveOutputs.length, ...v)
+  }
+})

Update line 265:

-  outputs: node.outputs ? [...node.outputs] : undefined,
+  outputs: reactiveOutputs,
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
inputs: reactiveInputs,
outputs: node.outputs ? [...node.outputs] : undefined,
inputs: reactiveInputs,
outputs: reactiveOutputs,
🤖 Prompt for AI Agents
In src/composables/graph/useGraphNodeManager.ts around lines 264-265, outputs
are returned as a plain shallow copy while inputs use a shallowReactive wrapper
with property interception; change the outputs handling to mirror inputs by
creating a shallow copy of node.outputs and wrapping it with shallowReactive
plus the same property interception logic used for reactiveInputs so mutations
to the outputs array are tracked by Vue (replace the [...node.outputs] return
with the same pattern used for inputs: copy the array, wrap it in
shallowReactive, and apply the property's getter/setter interception).

Copy link
Contributor

Choose a reason for hiding this comment

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

@coderabbitai this would be good to do on its own as a dedicated follow-up PR to keep this one focused.

Copy link
Contributor

Choose a reason for hiding this comment

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

@DrJKL, that makes sense! Keeping this PR focused on inputs is a good call.

Would you like me to create a GitHub issue to track the outputs reactivity work as a follow-up? I can include the context from this discussion and the suggested implementation approach.


🧠 Learnings used
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T19:47:02.860Z
Learning: Applies to src/**/*.vue : Utilize ref and reactive for reactive state

Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7137
File: src/components/rightSidePanel/parameters/TabParameters.vue:10-0
Timestamp: 2025-12-04T21:43:49.363Z
Learning: Vue 3.5+ supports reactive props destructure in <script setup>. Destructuring props directly (e.g., `const { nodes } = defineProps<{ nodes: LGraphNode[] }>()`) maintains reactivity through compiler transformation. This is the recommended modern approach and does not require using `props.x` or `toRef`/`toRefs`.

Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/lib/litegraph/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:56.371Z
Learning: Applies to src/lib/litegraph/**/*.{js,ts,jsx,tsx} : Do not replace `&&=` or `||=` with `=` when there is no reason to do so. If you do find a reason to remove either `&&=` or `||=`, leave a comment explaining why the removal occurred

Learnt from: simula-r
Repo: Comfy-Org/ComfyUI_frontend PR: 7252
File: src/renderer/extensions/vueNodes/components/ImagePreview.vue:151-158
Timestamp: 2025-12-11T03:55:57.926Z
Learning: In src/renderer/extensions/vueNodes/components/ImagePreview.vue and LGraphNode.vue, keyboard navigation for image galleries should respond to node-level focus (via keyEvent injection from LGraphNode), not require focus within the image preview wrapper itself. This allows users to navigate the gallery with arrow keys immediately when the node is focused/selected.

Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-09T20:22:23.620Z
Learning: Applies to **/*.vue : Use `ref` for reactive state in Vue Composition API components

Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Use ref/reactive for state management in Vue 3 Composition API

Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Replace PrimeVue InputSwitch component with ToggleSwitch

Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-09T20:22:23.620Z
Learning: Applies to **/*.vue : Use Vue 3.5 TypeScript style for default prop declaration with reactive props destructuring; do not use `withDefaults` or runtime props declaration

Copy link
Contributor

Choose a reason for hiding this comment

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

Yes, and assign it to @AustinMroz

Copy link
Contributor

Choose a reason for hiding this comment

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

Seems like the humans are having a chat. I'll hop back into my burrow for now. If you need me again, just tag @coderabbitai in a new comment, and I'll come hopping out!

Copy link
Contributor

Choose a reason for hiding this comment

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

@coderabbitai make that issue

Copy link
Contributor

Choose a reason for hiding this comment

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

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Create a GitHub issue for outputs reactivity follow-up

gh issue create \
  --title "Make node outputs reactive in Vue" \
  --body "## Context

Follow-up from PR #7546 which made node inputs reactive.

Currently, outputs are returned as a shallow copy (\`[...node.outputs]\`) while inputs use a \`shallowReactive\` wrapper with property interception. This creates an inconsistency in reactivity tracking.

## What needs to be done

Apply the same reactive pattern to outputs that was implemented for inputs in PR #7546:

1. Create \`reactiveOutputs\` using \`shallowReactive<INodeOutputSlot[]>(node.outputs ?? [])\`
2. Define a property on the node with getter/setter that intercepts mutations
3. Update the VueNodeData return to use \`reactiveOutputs\` instead of the shallow copy

This ensures mutations to the outputs array are properly tracked by Vue, maintaining consistency with how inputs are handled.

## Related

- PR: https://github.com/Comfy-Org/ComfyUI_frontend/pull/7546
- Discussion: https://github.com/Comfy-Org/ComfyUI_frontend/pull/7546#discussion_r2621739275
- File: \`src/composables/graph/useGraphNodeManager.ts\`
- Requested by: @DrJKL" \
  --assignee "AustinMroz"

Length of output: 57


@DrJKL, I've created issue #7547 for making node outputs reactive and assigned it to @AustinMroz.

🔗 #7547

The issue includes the technical context about applying the same shallowReactive pattern used for inputs, along with backlinks to this PR and discussion.


🧠 Learnings used
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T19:47:02.860Z
Learning: Applies to src/**/*.vue : Utilize ref and reactive for reactive state

Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7137
File: src/components/rightSidePanel/parameters/TabParameters.vue:10-0
Timestamp: 2025-12-04T21:43:49.363Z
Learning: Vue 3.5+ supports reactive props destructure in <script setup>. Destructuring props directly (e.g., `const { nodes } = defineProps<{ nodes: LGraphNode[] }>()`) maintains reactivity through compiler transformation. This is the recommended modern approach and does not require using `props.x` or `toRef`/`toRefs`.

Learnt from: simula-r
Repo: Comfy-Org/ComfyUI_frontend PR: 7252
File: src/renderer/extensions/vueNodes/components/ImagePreview.vue:151-158
Timestamp: 2025-12-11T03:55:57.926Z
Learning: In src/renderer/extensions/vueNodes/components/ImagePreview.vue and LGraphNode.vue, keyboard navigation for image galleries should respond to node-level focus (via keyEvent injection from LGraphNode), not require focus within the image preview wrapper itself. This allows users to navigate the gallery with arrow keys immediately when the node is focused/selected.

Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-09T20:22:23.620Z
Learning: Applies to **/*.vue : Use `ref` for reactive state in Vue Composition API components

Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Use ref/reactive for state management in Vue 3 Composition API

Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Replace PrimeVue InputSwitch component with ToggleSwitch

Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-09T20:22:23.620Z
Learning: Applies to **/*.vue : Use Vue 3.5 TypeScript style for default prop declaration with reactive props destructuring; do not use `withDefaults` or runtime props declaration

Comment on lines +226 to +227
set(v) {
reactiveInputs.splice(0, reactiveInputs.length, ...v)
Copy link
Contributor

Choose a reason for hiding this comment

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

Very nit, but I'd love a more descriptive parameter name.

@AustinMroz AustinMroz merged commit 3ee6d53 into main Dec 16, 2025
32 checks passed
@AustinMroz AustinMroz deleted the austin/vue-reactive-inputs branch December 16, 2025 04:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:S This PR changes 10-29 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants