Skip to content

Conversation

@LittleSound
Copy link
Collaborator

@LittleSound LittleSound commented Nov 18, 2025

related #5827 (comment)

┆Issue is synchronized with this Notion page by Unito

@dosubot dosubot bot added the size:L This PR changes 100-499 lines, ignoring generated files. label Nov 18, 2025
@github-actions
Copy link

github-actions bot commented Nov 18, 2025

🎭 Playwright Test Results

⚠️ Tests passed with flaky tests

⏰ Completed at: 11/18/2025, 11:27:08 AM UTC

📈 Summary

  • Total Tests: 494
  • Passed: 459 ✅
  • Failed: 0
  • Flaky: 5 ⚠️
  • Skipped: 30 ⏭️

📊 Test Reports by Browser

  • chromium: View Report • ✅ 450 / ❌ 0 / ⚠️ 5 / ⏭️ 30
  • chromium-2x: View Report • ✅ 2 / ❌ 0 / ⚠️ 0 / ⏭️ 0
  • chromium-0.5x: View Report • ✅ 1 / ❌ 0 / ⚠️ 0 / ⏭️ 0
  • mobile-chrome: View Report • ✅ 6 / ❌ 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 Nov 18, 2025

🎨 Storybook Build Status

Build completed successfully!

⏰ Completed at: 11/18/2025, 11:17:32 AM UTC

🔗 Links


🎉 Your Storybook is ready for review!

@github-actions
Copy link

Bundle Size Report

Summary

  • Raw size: 13.7 MB baseline 13.7 MB — 🔴 +1.97 kB
  • Gzip: 2.75 MB baseline 2.75 MB — 🔴 +363 B
  • Brotli: 2.16 MB baseline 2.16 MB — 🔴 +209 B
  • Bundles: 97 current • 97 baseline • 40 added / 40 removed

Category Glance
UI Components 🔴 +1.97 kB (138 kB) · Vendor & Third-Party ⚪ 0 B (5.32 MB) · Other ⚪ 0 B (3.94 MB) · App Entry Points ⚪ 0 B (3.14 MB) · Graph Workspace ⚪ 0 B (789 kB) · Panels & Settings ⚪ 0 B (307 kB) · + 3 more

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

Main entry bundles and manifests

File Before After Δ Raw Δ Gzip Δ Brotli
assets/index-B_bT-d7H.js (removed) 2.77 MB 🟢 -2.77 MB 🟢 -577 kB 🟢 -438 kB
assets/index-D92FBikW.js (new) 2.77 MB 🔴 +2.77 MB 🔴 +577 kB 🔴 +438 kB
assets/index-B2O5V-Sa.js (removed) 364 kB 🟢 -364 kB 🟢 -75.2 kB 🟢 -61.3 kB
assets/index-DUeSB8-f.js (new) 364 kB 🔴 +364 kB 🔴 +75.2 kB 🔴 +61.3 kB
assets/index-CJRCR493.js (removed) 345 B 🟢 -345 B 🟢 -245 B 🟢 -236 B
assets/index-Dhu-wqNw.js (new) 345 B 🔴 +345 B 🔴 +245 B 🔴 +209 B

Status: 3 added / 3 removed

Graph Workspace — 789 kB (baseline 789 kB) • ⚪ 0 B

Graph editor runtime, canvas, workflow orchestration

File Before After Δ Raw Δ Gzip Δ Brotli
assets/GraphView-D917mKqU.js (removed) 789 kB 🟢 -789 kB 🟢 -155 kB 🟢 -119 kB
assets/GraphView-ryXreplQ.js (new) 789 kB 🔴 +789 kB 🔴 +155 kB 🔴 +119 kB

Status: 1 added / 1 removed

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

Top-level views, pages, and routed surfaces

File Before After Δ Raw Δ Gzip Δ Brotli
assets/UserSelectView-D7jgTDNT.js (removed) 8.03 kB 🟢 -8.03 kB 🟢 -2.45 kB 🟢 -2.16 kB
assets/UserSelectView-DLePTgiW.js (new) 8.03 kB 🔴 +8.03 kB 🔴 +2.45 kB 🔴 +2.15 kB

Status: 1 added / 1 removed

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

Configuration panels, inspectors, and settings screens

File Before After Δ Raw Δ Gzip Δ Brotli
assets/CreditsPanel-BPnKeZeS.js (removed) 23 kB 🟢 -23 kB 🟢 -5.47 kB 🟢 -4.79 kB
assets/CreditsPanel-BpRvre0L.js (new) 23 kB 🔴 +23 kB 🔴 +5.47 kB 🔴 +4.79 kB
assets/KeybindingPanel-BvjzStrB.js (new) 15.1 kB 🔴 +15.1 kB 🔴 +3.74 kB 🔴 +3.3 kB
assets/KeybindingPanel-w7Iu3FWG.js (removed) 15.1 kB 🟢 -15.1 kB 🟢 -3.75 kB 🟢 -3.3 kB
assets/ExtensionPanel-CghJTSYT.js (new) 12 kB 🔴 +12 kB 🔴 +2.81 kB 🔴 +2.46 kB
assets/ExtensionPanel-HXBHbJNT.js (removed) 12 kB 🟢 -12 kB 🟢 -2.81 kB 🟢 -2.46 kB
assets/AboutPanel-BakC2in7.js (new) 10.2 kB 🔴 +10.2 kB 🔴 +2.64 kB 🔴 +2.32 kB
assets/AboutPanel-BZv7bCxw.js (removed) 10.2 kB 🟢 -10.2 kB 🟢 -2.64 kB 🟢 -2.31 kB
assets/ServerConfigPanel-2JM8C0fM.js (new) 8.09 kB 🔴 +8.09 kB 🔴 +2.14 kB 🔴 +1.89 kB
assets/ServerConfigPanel-Dm_686eP.js (removed) 8.09 kB 🟢 -8.09 kB 🟢 -2.14 kB 🟢 -1.89 kB
assets/UserPanel-BtgKe6hx.js (new) 7.8 kB 🔴 +7.8 kB 🔴 +2.04 kB 🔴 +1.78 kB
assets/UserPanel-Du7H9GJp.js (removed) 7.8 kB 🟢 -7.8 kB 🟢 -2.04 kB 🟢 -1.78 kB
assets/settings-BXTtSH4O.js 33.3 kB 33.3 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-C9Pzn-NG.js 25.2 kB 25.2 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-CCy2fA_h.js 27.3 kB 27.3 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-CQpqEFfl.js 26.6 kB 26.6 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-DHcnxypw.js 21.7 kB 21.7 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-DhFTK9fY.js 25.1 kB 25.1 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-DlT4t_ui.js 25.9 kB 25.9 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-DRgSrIdD.js 24.2 kB 24.2 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-tjkeqiZq.js 21.1 kB 21.1 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B

Status: 6 added / 6 removed

UI Components — 138 kB (baseline 136 kB) • 🔴 +1.97 kB

Reusable component library chunks

File Before After Δ Raw Δ Gzip Δ Brotli
assets/Load3D.vue_vue_type_script_setup_true_lang-CaWUSzOY.js (new) 53.9 kB 🔴 +53.9 kB 🔴 +8.43 kB 🔴 +7.24 kB
assets/Load3D.vue_vue_type_script_setup_true_lang-Du2IUmRC.js (removed) 53.9 kB 🟢 -53.9 kB 🟢 -8.43 kB 🟢 -7.23 kB
assets/WidgetSelect.vue_vue_type_script_setup_true_lang-CjmcwThW.js (new) 50.1 kB 🔴 +50.1 kB 🔴 +10.8 kB 🔴 +9.34 kB
assets/WidgetSelect.vue_vue_type_script_setup_true_lang-nSA6PUEE.js (removed) 48.1 kB 🟢 -48.1 kB 🟢 -10.4 kB 🟢 -9 kB
assets/ComfyQueueButton-BEiyMZd7.js (removed) 11.2 kB 🟢 -11.2 kB 🟢 -2.8 kB 🟢 -2.47 kB
assets/ComfyQueueButton-pb9g_fqV.js (new) 11.2 kB 🔴 +11.2 kB 🔴 +2.8 kB 🔴 +2.47 kB
assets/WidgetSelectButton-Cb8I6dMH.js (new) 6.59 kB 🔴 +6.59 kB 🔴 +1.95 kB 🔴 +1.72 kB
assets/WidgetSelectButton-DoJdf7ZP.js (removed) 6.59 kB 🟢 -6.59 kB 🟢 -1.96 kB 🟢 -1.72 kB
assets/WidgetLayoutField.vue_vue_type_script_setup_true_lang-GnDALPn5.js (new) 2.16 kB 🔴 +2.16 kB 🔴 +811 B 🔴 +705 B
assets/WidgetLayoutField.vue_vue_type_script_setup_true_lang-yr35ztCL.js (removed) 2.16 kB 🟢 -2.16 kB 🟢 -810 B 🟢 -706 B
assets/MediaTitle.vue_vue_type_script_setup_true_lang-BmC0C226.js (removed) 848 B 🟢 -848 B 🟢 -475 B 🟢 -417 B
assets/MediaTitle.vue_vue_type_script_setup_true_lang-DpXOGAck.js (new) 848 B 🔴 +848 B 🔴 +475 B 🔴 +414 B
assets/LazyImage.vue_vue_type_script_setup_true_lang-Wi-CcgaU.js 10.7 kB 10.7 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/UserAvatar.vue_vue_type_script_setup_true_lang-D2s8tnS2.js 1.26 kB 1.26 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/WidgetButton-ByrPd5jr.js 1.62 kB 1.62 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B

Status: 6 added / 6 removed

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

Stores, services, APIs, and repositories

File Before After Δ Raw Δ Gzip Δ Brotli
assets/keybindingService-CTvyxVLB.js (removed) 7.6 kB 🟢 -7.6 kB 🟢 -1.84 kB 🟢 -1.59 kB
assets/keybindingService-DIYEoBW6.js (new) 7.6 kB 🔴 +7.6 kB 🔴 +1.85 kB 🔴 +1.59 kB
assets/audioService-CQI8EDMx.js (removed) 2.2 kB 🟢 -2.2 kB 🟢 -963 B 🟢 -823 B
assets/audioService-DIys_xUG.js (new) 2.2 kB 🔴 +2.2 kB 🔴 +962 B 🔴 +822 B
assets/serverConfigStore-B-x6001d.js 2.79 kB 2.79 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B

Status: 2 added / 2 removed

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

Helpers, composables, and utility bundles

File Before After Δ Raw Δ Gzip Δ Brotli
assets/audioUtils-Cg3oxwc8.js (removed) 1.41 kB 🟢 -1.41 kB 🟢 -650 B 🟢 -549 B
assets/audioUtils-CP3vM8fY.js (new) 1.41 kB 🔴 +1.41 kB 🔴 +652 B 🔴 +547 B
assets/mathUtil-CTARWQ-l.js 1.07 kB 1.07 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeFilterUtil-CXKCRJ-m.js 460 B 460 B ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/useTransformCompatOverlayProps-YaCpDdzr.js 486 B 486 B ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/useWidgetValue-IC6pgigJ.js 2.45 kB 2.45 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B

Status: 1 added / 1 removed

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

External libraries and shared vendor chunks

File Before After Δ Raw Δ Gzip Δ Brotli
assets/vendor-other-6R86j2Wt.js 3.22 MB 3.22 MB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/vendor-primevue-PESgPnbc.js 517 B 517 B ⚪ 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-CSqz1Oiv.js 232 kB 232 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/vendor-vue-Cp6hwTh6.js 92.6 kB 92.6 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/vendor-xterm-BZLod3g9.js 407 kB 407 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
Other — 3.94 MB (baseline 3.94 MB) • ⚪ 0 B

Bundles that do not match a named category

File Before After Δ Raw Δ Gzip Δ Brotli
assets/WidgetRecordAudio-BW2ADNjU.js (removed) 22.1 kB 🟢 -22.1 kB 🟢 -5.57 kB 🟢 -4.92 kB
assets/WidgetRecordAudio-Ivqzjji4.js (new) 22.1 kB 🔴 +22.1 kB 🔴 +5.57 kB 🔴 +4.92 kB
assets/AudioPreviewPlayer-D9KPNVG6.js (removed) 15 kB 🟢 -15 kB 🟢 -3.7 kB 🟢 -3.31 kB
assets/AudioPreviewPlayer-Dbr-s5ji.js (new) 15 kB 🔴 +15 kB 🔴 +3.7 kB 🔴 +3.31 kB
assets/WidgetInputNumber-DqLnHd6q.js (removed) 14.6 kB 🟢 -14.6 kB 🟢 -3.79 kB 🟢 -3.37 kB
assets/WidgetInputNumber-F6gOT_Ri.js (new) 14.6 kB 🔴 +14.6 kB 🔴 +3.79 kB 🔴 +3.35 kB
assets/WidgetGalleria-B6XyzbTB.js (removed) 5.62 kB 🟢 -5.62 kB 🟢 -1.76 kB 🟢 -1.55 kB
assets/WidgetGalleria-C5FWGw2R.js (new) 5.62 kB 🔴 +5.62 kB 🔴 +1.76 kB 🔴 +1.55 kB
assets/WidgetColorPicker-BcuDqYA3.js (new) 4.91 kB 🔴 +4.91 kB 🔴 +1.69 kB 🔴 +1.47 kB
assets/WidgetColorPicker-BHty04e9.js (removed) 4.91 kB 🟢 -4.91 kB 🟢 -1.69 kB 🟢 -1.47 kB
assets/WidgetMarkdown-CIRYUk6o.js (removed) 4.88 kB 🟢 -4.88 kB 🟢 -1.7 kB 🟢 -1.47 kB
assets/WidgetMarkdown-tqlCP_ME.js (new) 4.88 kB 🔴 +4.88 kB 🔴 +1.7 kB 🔴 +1.47 kB
assets/WidgetAudioUI-B8wEgKN-.js (removed) 4.49 kB 🟢 -4.49 kB 🟢 -1.5 kB 🟢 -1.34 kB
assets/WidgetAudioUI-BRW6b8DP.js (new) 4.49 kB 🔴 +4.49 kB 🔴 +1.5 kB 🔴 +1.34 kB
assets/WidgetMultiSelect-BFzqshso.js (removed) 4.3 kB 🟢 -4.3 kB 🟢 -1.46 kB 🟢 -1.27 kB
assets/WidgetMultiSelect-Bh_vv6K3.js (new) 4.3 kB 🔴 +4.3 kB 🔴 +1.46 kB 🔴 +1.27 kB
assets/WidgetTreeSelect-DpyISpw1.js (new) 4.03 kB 🔴 +4.03 kB 🔴 +1.38 kB 🔴 +1.21 kB
assets/WidgetTreeSelect-DQeX0Vzd.js (removed) 4.03 kB 🟢 -4.03 kB 🟢 -1.38 kB 🟢 -1.21 kB
assets/WidgetTextarea-DrDwEy1q.js (new) 3.74 kB 🔴 +3.74 kB 🔴 +1.3 kB 🔴 +1.13 kB
assets/WidgetTextarea-DZpr2Yz6.js (removed) 3.74 kB 🟢 -3.74 kB 🟢 -1.3 kB 🟢 -1.14 kB
assets/WidgetInputText-Bl84owLo.js (removed) 3.66 kB 🟢 -3.66 kB 🟢 -1.28 kB 🟢 -1.13 kB
assets/WidgetInputText-DuOJIJ5w.js (new) 3.66 kB 🔴 +3.66 kB 🔴 +1.28 kB 🔴 +1.13 kB
assets/WidgetToggleSwitch-0DgETHYw.js (removed) 3.52 kB 🟢 -3.52 kB 🟢 -1.23 kB 🟢 -1.07 kB
assets/WidgetToggleSwitch-BOVKr7Q_.js (new) 3.52 kB 🔴 +3.52 kB 🔴 +1.23 kB 🔴 +1.1 kB
assets/MediaImageBottom-BOiJl5FN.js (new) 3.11 kB 🔴 +3.11 kB 🔴 +1.07 kB 🔴 +924 B
assets/MediaImageBottom-G8kNSrnp.js (removed) 3.11 kB 🟢 -3.11 kB 🟢 -1.06 kB 🟢 -915 B
assets/MediaAudioBottom-B-HSkwjk.js (removed) 3.06 kB 🟢 -3.06 kB 🟢 -1.06 kB 🟢 -922 B
assets/MediaAudioBottom-Mvh8PoPv.js (new) 3.06 kB 🔴 +3.06 kB 🔴 +1.06 kB 🔴 +934 B
assets/MediaVideoBottom-BU5M54o7.js (new) 3.06 kB 🔴 +3.06 kB 🔴 +1.06 kB 🔴 +959 B
assets/MediaVideoBottom-CZz_jhdj.js (removed) 3.06 kB 🟢 -3.06 kB 🟢 -1.06 kB 🟢 -921 B
assets/Media3DTop-CR46gllV.js (removed) 3.05 kB 🟢 -3.05 kB 🟢 -1.09 kB 🟢 -918 B
assets/Media3DTop-Ct6Mts8d.js (new) 3.05 kB 🔴 +3.05 kB 🔴 +1.09 kB 🔴 +920 B
assets/Media3DBottom-BWGBIKIi.js (removed) 3.04 kB 🟢 -3.04 kB 🟢 -1.06 kB 🟢 -931 B
assets/Media3DBottom-CGa5IgnO.js (new) 3.04 kB 🔴 +3.04 kB 🔴 +1.06 kB 🔴 +940 B
assets/WidgetSelect-D_Bolvxh.js (new) 2.33 kB 🔴 +2.33 kB 🔴 +732 B 🔴 +621 B
assets/WidgetSelect-DCEuS0HU.js (removed) 2.33 kB 🟢 -2.33 kB 🟢 -735 B 🟢 -627 B
assets/Load3D-CdkAyX1B.js (removed) 2.01 kB 🟢 -2.01 kB 🟢 -613 B 🟢 -546 B
assets/Load3D-yxo6c-MG.js (new) 2.01 kB 🔴 +2.01 kB 🔴 +612 B 🔴 +543 B
assets/WidgetLegacy--OuJBzMV.js (new) 1.95 kB 🔴 +1.95 kB 🔴 +577 B 🔴 +516 B
assets/WidgetLegacy-DDtJPQmI.js (removed) 1.95 kB 🟢 -1.95 kB 🟢 -577 B 🟢 -516 B
assets/commands-_6uSNVYB.js 14.9 kB 14.9 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-BaAvtVOT.js 14.7 kB 14.7 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-BRKOlMPq.js 15.4 kB 15.4 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-C1kmJUO0.js 14.9 kB 14.9 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-CHLkz7NH.js 17.4 kB 17.4 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-cLsDwHMQ.js 14 kB 14 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-Ct50VUT9.js 16.2 kB 16.2 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-DOEnM922.js 14.1 kB 14.1 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-Ds4Sq2CW.js 15.7 kB 15.7 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-BjHbZI-o.js 97.5 kB 97.5 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-BsmSUEg9.js 75.9 kB 75.9 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-C1dqVsBC.js 103 kB 103 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-CTcPPkuZ.js 87.4 kB 87.4 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-CwX98cQA.js 89.7 kB 89.7 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-DFyT7zKX.js 84.8 kB 84.8 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-DHvyJYQT.js 74.9 kB 74.9 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-ruI2u5eb.js 118 kB 118 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-UdMyOcTd.js 86.4 kB 86.4 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/MediaAudioTop-RTI8pWy9.js 1.42 kB 1.42 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/MediaImageTop-B4svUc3L.js 1.68 kB 1.68 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/MediaVideoTop-BB0lT7C5.js 2.7 kB 2.7 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-_Px5dSNW.js 306 kB 306 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-7z21KPoS.js 285 kB 285 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-BWKZzBPK.js 346 kB 346 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-CGbgH4Yl.js 320 kB 320 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-CjjjdWkV.js 313 kB 313 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-CVrNtxvj.js 288 kB 288 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-DLRSA0IK.js 309 kB 309 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-DQV2gnwA.js 372 kB 372 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-ofqLG5vz.js 310 kB 310 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/WidgetChart-rDmYEWg5.js 2.39 kB 2.39 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/WidgetFileUpload-Cx6dGznS.js 11.9 kB 11.9 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/WidgetImageCompare-Ds3K3ULR.js 2.15 kB 2.15 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/widgetPropFilter-BIbGSUAt.js 1.28 kB 1.28 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B

Status: 20 added / 20 removed

@christian-byrne christian-byrne added preview area:widgets area:assets claude-review Add to trigger a PR code review from Claude Code labels Nov 19, 2025
})

if (!response.ok) {
console.error('Failed to fetch output files:', response.statusText)
Copy link

Choose a reason for hiding this comment

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

[architecture] medium Priority

Issue: Missing error handling for API failures - store returns empty array on error
Context: Users won't know when output file fetching fails, and dropdown will appear empty
Suggestion: Add error state tracking and user notification for fetch failures


const outputImages = computed(() => {
return outputs.value.filter((filename) => {
const ext = filename.toLowerCase().split('.').pop() || ''
Copy link

Choose a reason for hiding this comment

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

[performance] low Priority

Issue: Inefficient file extension parsing with repeated split operations
Context: Each computed property calls split('.').pop() for every file, causing O(n*m) complexity
Suggestion: Pre-process file extensions once or use more efficient parsing like filename.lastIndexOf('.')

return ['png', 'jpg', 'jpeg', 'webp', 'gif', 'bmp', 'tiff'].includes(ext)
})
})
const outputVideos = computed(() => {
Copy link

Choose a reason for hiding this comment

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

[quality] medium Priority

Issue: Code duplication across outputImages, outputVideos, and outputAudios computed properties
Context: Same filtering logic repeated three times, violating DRY principle
Suggestion: Extract to a helper function: getFilesByExtensions(extensions) or use a shared utility

}
}

const fetchOutputFiles = async () => {
Copy link

Choose a reason for hiding this comment

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

[architecture] high Priority

Issue: Potential race condition with promise caching mechanism
Context: If multiple components call fetchOutputFiles() while promise is resolving, they all get the same promise but thePromise.value is set to null in finally block
Suggestion: Consider using a more robust caching mechanism or ensure promise is cleared only after all consumers are notified

}
// Fetch output files on component mount
onMounted(() => {
Copy link

Choose a reason for hiding this comment

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

[performance] medium Priority

Issue: Unconditional output files fetch on component mount regardless of widget type
Context: Every dropdown widget will fetch output files even if not needed (non-media widgets)
Suggestion: Only fetch output files when assetKind indicates media types (image/video/audio)

import { api } from '@/scripts/api'
import { useAssetsStore } from '@/stores/assetsStore'
import { useQueueStore } from '@/stores/queueStore'
import { useOutputsStore } from '@/stores/outputsStore'
Copy link

Choose a reason for hiding this comment

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

[architecture] critical Priority

Issue: Breaking change - removed queue store dependency without data migration
Context: Old implementation extracted outputs from queueStore.historyTasks but new implementation uses fresh API calls, potentially losing user data
Suggestion: Add migration path or ensure existing workflows aren't broken

}
})()
return outputFiles.map((filename, index) => {
Copy link

Choose a reason for hiding this comment

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

[architecture] medium Priority

Issue: Simplified output handling may not preserve subfolder structure from original queue-based implementation
Context: Old code constructed paths with subfolder info, new code uses direct filenames from API
Suggestion: Verify API returns files with full path or add subfolder handling

class="icon-[lucide--circle-off] size-30 text-zinc-500/20"
/>
</div>
<template v-if="items.length === 0">
Copy link

Choose a reason for hiding this comment

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

[quality] low Priority

Issue: Template structure change from div to template is good but missing semantic improvement
Context: Using template wrapper is more performant than div for conditional rendering
Suggestion: Consider adding proper ARIA attributes or role for better accessibility

Copy link

@claude claude bot left a comment

Choose a reason for hiding this comment

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

Comprehensive PR Review

This review is generated by Claude. It may not always be accurate, as with human reviewers. If you believe that any of the comments are invalid or incorrect, please state why for each. For others, please implement the changes in one way or another.

Review Summary

PR: fix: dropdown widget fetching output files (#6734)
Impact: 113 additions, 38 deletions across 3 files
Focus: Refactoring dropdown widget to use dedicated outputs store instead of queue store

Issue Distribution

  • Critical: 1
  • High: 1
  • Medium: 4
  • Low: 2

Category Breakdown

  • Architecture: 5 issues
  • Code Quality: 2 issues
  • Performance: 1 issues
  • Security: 0 issues

Key Findings

Architecture & Design

Critical: The migration from queue store to outputs store represents a breaking change that may lose existing user data or functionality. The old implementation extracted outputs from queue history with subfolder structure, while the new approach uses direct API calls.

High Priority: Race condition potential in the outputs store promise caching mechanism could lead to inconsistent state when multiple components fetch simultaneously.

Medium Priority: The new outputs store lacks proper error handling, which means users won't be notified when API calls fail, resulting in empty dropdowns without explanation.

Performance Impact

The unconditional fetching of output files on component mount for all dropdown widgets is inefficient - this should only happen for media-type widgets. The file extension filtering also uses inefficient string operations that could be optimized.

Code Quality

Several areas need improvement: code duplication in file type filtering logic, inconsistent type handling between string/number widget values and string-only output files, and missing proper error states.

Positive Observations

  • Good architectural direction separating concerns with dedicated outputs store
  • Improved template structure using template instead of div for conditional rendering
  • Clean separation of file types with computed properties
  • Proper TypeScript usage with explicit type definitions

References

  • ComfyUI Frontend Repository Guide
  • Vue 3 Best Practices
  • Pinia Store Patterns

Next Steps

  1. Critical: Address the breaking change concern - ensure data migration path exists
  2. High: Fix race condition in outputs store promise handling
  3. Medium: Add proper error handling and user feedback for API failures
  4. Medium: Optimize performance by conditional fetching based on widget type
  5. Add tests to verify output file fetching behavior
  6. Consider backward compatibility implications

Testing Recommendations

  • Test dropdown behavior with and without existing output files
  • Verify subfolder structure preservation
  • Test error scenarios (API failures, network issues)
  • Verify performance with large numbers of output files
  • Test concurrent widget mounting scenarios

This is a comprehensive automated review. For architectural decisions requiring human judgment, please request additional manual review.

@github-actions github-actions bot removed the claude-review Add to trigger a PR code review from Claude Code label Nov 19, 2025
Comment on lines +71 to +76
<div class="absolute inset-0 flex items-center justify-center">
<i
title="No items"
class="icon-[lucide--circle-off] size-30 text-zinc-500/20"
/>
</div>
Copy link
Contributor

Choose a reason for hiding this comment

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

note: We also have this

(not blocking this PR).

Comment on lines +10 to +27
const outputImages = computed(() => {
return outputs.value.filter((filename) => {
const ext = filename.toLowerCase().split('.').pop() || ''
return ['png', 'jpg', 'jpeg', 'webp', 'gif', 'bmp', 'tiff'].includes(ext)
})
})
const outputVideos = computed(() => {
return outputs.value.filter((filename) => {
const ext = filename.toLowerCase().split('.').pop() || ''
return ['mp4', 'webm', 'mov', 'avi', 'mkv'].includes(ext)
})
})
const outputAudios = computed(() => {
return outputs.value.filter((filename) => {
const ext = filename.toLowerCase().split('.').pop() || ''
return ['mp3', 'ogg', 'wav', 'flac'].includes(ext)
})
})
Copy link
Contributor

Choose a reason for hiding this comment

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

Do you think it could be optimized to only need a single traversal?

import { defineStore } from 'pinia'
import { computed, ref } from 'vue'

export const useOutputsStore = defineStore('outputs', () => {
Copy link
Member

Choose a reason for hiding this comment

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

https://github.com/Comfy-Org/ComfyUI_frontend/blob/main/src/platform/assets/composables/media/useMediaAssets.ts
const outputAssets = useMediaAssets('output')
It looks like most of the code in src/stores/outputsStore.ts could be replaced with something like const outputAssets = useMediaAssets('output'). I think it would be better to use the existing store. What do you think?

outputs.add(annotatedPath)
}
})
const outputFiles = ((): string[] => {
Copy link
Member

Choose a reason for hiding this comment

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

Copy link
Member

@viva-jinyi viva-jinyi left a comment

Choose a reason for hiding this comment

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

It doesn’t seem to cover both Cloud and OSS. Since internal/files can only fetch output files in the OSS environment, I think it would be better to use useMediaAssets.ts. It’s already implemented to work for both OSS and Cloud, and we can update it later when the new API becomes available.

@LittleSound
Copy link
Collaborator Author

I tried this API, but it doesn't work. I don't know why. you can see this image, so I use the fetch to get the list

However, I still did it according to your request. You can see it here #6809, and you can actually run the code to compare their differences.

CleanShot 2025-11-22 at 00 12 31@2x

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area:assets area:widgets preview size:L This PR changes 100-499 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants