fix: stop converting defaultInput to forceInput on migration#10706
fix: stop converting defaultInput to forceInput on migration#10706Lidang-Jiang wants to merge 3 commits into
Conversation
The _migrateDefaultInput method set forceInput = true for every optional input with defaultInput, preventing the widget from being created. When users toggled a defaultInput socket back to a widget and saved, the next reload re-applied forceInput, reverting it to a socket-only input. Since frontend 1.16+, widgets and sockets co-exist on every input, so defaultInput no longer needs conversion to forceInput. Remove the assignment while keeping the deprecation warning. Fixes Comfy-Org/ComfyUI#1500
🎭 Playwright: ❌ 1467 passed, 1 failed · 1 flaky❌ Failed Tests📊 Browser Reports
|
📝 WalkthroughWalkthroughPreserve optional input widgets when Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Poem
Caution Pre-merge checks failedPlease resolve all errors before merging. Addressing warnings is optional.
❌ Failed checks (1 error)
✅ Passed checks (6 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (1)
src/schemas/nodeDef/migration.test.ts (1)
541-657: Add one regression test for deprecation warning emission.This suite validates
forceInputmigration behavior well, but it doesn’t lock in the “warning is still emitted” requirement. Adding aconsole.warnspy test would prevent accidental removal of the deprecation signal.Suggested test addition
-import { describe, expect, it } from 'vitest' +import { describe, expect, it, vi } from 'vitest'describe('defaultInput migration', () => { + it('should emit deprecation warning for optional defaultInput', () => { + const warnSpy = vi.spyOn(console, 'warn').mockImplementation(() => {}) + + new ComfyNodeDefImpl({ + name: 'WarnNode', + display_name: 'Warn Node', + category: 'Test', + python_module: 'test_module', + description: 'A test node', + input: { + optional: { + seed_override: ['INT', { defaultInput: true }] + } + }, + output: [], + output_is_list: [], + output_name: [], + output_node: false + } as ComfyNodeDefV1) + + expect(warnSpy).toHaveBeenCalledWith( + expect.stringContaining( + 'Use of defaultInput on optional input test_module:WarnNode:seed_override is deprecated' + ) + ) + + warnSpy.mockRestore() + })🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/schemas/nodeDef/migration.test.ts` around lines 541 - 657, Add a regression test in the "defaultInput migration" suite that verifies a deprecation warning is emitted: spy on console.warn, instantiate a ComfyNodeDefImpl using an input entry with defaultInput: true (e.g. optional.param or required.value as used in other tests), assert console.warn was called (optionally check message includes "defaultInput" or "deprecated"), and restore/clear the spy after the assertion to avoid test bleed. Ensure the test references ComfyNodeDefImpl and the same V1-style input payload as other tests so it exercises the migration path.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@src/stores/nodeDefStore.ts`:
- Around line 132-137: The deprecation warning for defaultInput (inside the loop
over def.input.optional) should not instruct authors to use forceInput because
that reintroduces the old socket-only behavior; update the console.warn in that
block so it removes the "Please use forceInput instead." phrasing and instead
tells authors to migrate to the new preferred pattern (for example: make the
input required where appropriate or handle defaults at runtime) and to consult
the node authoring docs — keep the message concise and reference the node as
currently done via nodeDef.python_module, nodeDef.name, and the input name.
---
Nitpick comments:
In `@src/schemas/nodeDef/migration.test.ts`:
- Around line 541-657: Add a regression test in the "defaultInput migration"
suite that verifies a deprecation warning is emitted: spy on console.warn,
instantiate a ComfyNodeDefImpl using an input entry with defaultInput: true
(e.g. optional.param or required.value as used in other tests), assert
console.warn was called (optionally check message includes "defaultInput" or
"deprecated"), and restore/clear the spy after the assertion to avoid test
bleed. Ensure the test references ComfyNodeDefImpl and the same V1-style input
payload as other tests so it exercises the migration path.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 315415e8-ad61-4c06-beb5-80bf6aae53bc
📒 Files selected for processing (2)
src/schemas/nodeDef/migration.test.tssrc/stores/nodeDefStore.ts
| for (const [name, spec] of Object.entries(def.input.optional ?? {})) { | ||
| const inputOptions = spec[1] | ||
| if (inputOptions && inputOptions.defaultInput) { | ||
| console.warn( | ||
| `Use of defaultInput on optional input ${nodeDef.python_module}:${nodeDef.name}:${name} is deprecated. Please use forceInput instead.` | ||
| ) |
There was a problem hiding this comment.
Update the optional-input deprecation warning to avoid reintroducing the old behavior.
At Line 136, the warning says to use forceInput as a replacement for defaultInput. With this fix, that guidance can push node authors back to socket-only configs and effectively undo the intended UX improvement.
Suggested wording update
- `Use of defaultInput on optional input ${nodeDef.python_module}:${nodeDef.name}:${name} is deprecated. Please use forceInput instead.`
+ `Use of defaultInput on optional input ${nodeDef.python_module}:${nodeDef.name}:${name} is deprecated and ignored. Remove defaultInput. Use forceInput only if you intentionally want a socket-only input.`📝 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.
| for (const [name, spec] of Object.entries(def.input.optional ?? {})) { | |
| const inputOptions = spec[1] | |
| if (inputOptions && inputOptions.defaultInput) { | |
| console.warn( | |
| `Use of defaultInput on optional input ${nodeDef.python_module}:${nodeDef.name}:${name} is deprecated. Please use forceInput instead.` | |
| ) | |
| for (const [name, spec] of Object.entries(def.input.optional ?? {})) { | |
| const inputOptions = spec[1] | |
| if (inputOptions && inputOptions.defaultInput) { | |
| console.warn( | |
| `Use of defaultInput on optional input ${nodeDef.python_module}:${nodeDef.name}:${name} is deprecated and ignored. Remove defaultInput. Use forceInput only if you intentionally want a socket-only input.` | |
| ) |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@src/stores/nodeDefStore.ts` around lines 132 - 137, The deprecation warning
for defaultInput (inside the loop over def.input.optional) should not instruct
authors to use forceInput because that reintroduces the old socket-only
behavior; update the console.warn in that block so it removes the "Please use
forceInput instead." phrasing and instead tells authors to migrate to the new
preferred pattern (for example: make the input required where appropriate or
handle defaults at runtime) and to consult the node authoring docs — keep the
message concise and reference the node as currently done via
nodeDef.python_module, nodeDef.name, and the input name.
There was a problem hiding this comment.
Good catch, fixed in 1f4c20b. Updated the warning to clarify that defaultInput is now ignored and forceInput should only be used intentionally for socket-only inputs.
There was a problem hiding this comment.
@Lidang-Jiang, thanks for the update! The revised warning in the ai_summary matches the suggested wording — it now correctly conveys that defaultInput is deprecated and ignored, and that forceInput is only for intentional socket-only behavior.
🧠 Learnings used
Learnt from: jtydhr88
Repo: Comfy-Org/ComfyUI_frontend PR: 10349
File: src/renderer/glsl/useGLSLPreview.ts:31-34
Timestamp: 2026-03-21T00:15:21.439Z
Learning: In Comfy-Org/ComfyUI_frontend `src/renderer/glsl/useGLSLPreview.ts`, for the direct GLSLShader node branch: when an autogrow uniform input is connected to an upstream node, the corresponding widget is removed from the widget value store (`getWidget()` returns undefined). This makes the "local widget present" and "upstream input connected" code paths mutually exclusive by design. Do not flag the early-continue on widget presence as a precedence bug that prevents upstream values from overriding local defaults.
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-03-29T06:46:23.514Z
Learning: Changes to entity callbacks (`onConnectionsChange`, `onRemoved`, `onAdded`, `onConnectInput/Output`, `onConfigure`, `onWidgetChanged`), `node.widgets` access, `node.serialize`, or `graph._version++` affect 40+ custom node repos and require migration guidance
Learnt from: artokun
Repo: Comfy-Org/ComfyUI_frontend PR: 10286
File: src/renderer/extensions/vueNodes/widgets/composables/useRemoteWidget.ts:0-0
Timestamp: 2026-03-23T02:54:33.758Z
Learning: In Comfy-Org/ComfyUI_frontend, `useRemoteWidget.onFirstLoad()` (in `src/renderer/extensions/vueNodes/widgets/composables/useRemoteWidget.ts`) uses the `widget.configuredByLoad` flag (set by `LGraphNode.configure()` after restoring each widget value from serialized workflow data) to decide whether to skip overwriting `widget.value` with the first remote item. Do NOT suggest value-comparison guards (e.g., `widget.value !== defaultValue`, `widget.value !== ''`) as a substitute — the flag approach is intentional and avoids the ambiguous case where a legitimately saved value equals the default.
Learnt from: jaeone94
Repo: Comfy-Org/ComfyUI_frontend PR: 10309
File: src/platform/missingMedia/composables/useMissingMediaInteractions.ts:56-71
Timestamp: 2026-03-25T15:00:58.823Z
Learning: In `src/platform/missingMedia/composables/useMissingMediaInteractions.ts` (Comfy-Org/ComfyUI_frontend), the `applyValueToNodes` function intentionally omits `node.onWidgetChanged()` and `graph._version++` after setting the combo widget value. This mirrors the identical pattern in `src/platform/missingModel/composables/useMissingModelInteractions.ts` (lines 184-186). Undo/redo has been verified working in both pipelines. Do not flag the absence of `onWidgetChanged` or `_version++` as a bug in either pipeline; any change to add them must be applied consistently to both pipelines together in a dedicated follow-up PR.
Learnt from: jaeone94
Repo: Comfy-Org/ComfyUI_frontend PR: 10395
File: src/core/graph/subgraph/promotedWidgetView.ts:203-213
Timestamp: 2026-03-23T15:06:29.846Z
Learning: In `src/core/graph/subgraph/promotedWidgetView.ts` (Comfy-Org/ComfyUI_frontend), all production `PromotedWidgetView` instances are created exclusively through `SubgraphNode._setWidget()` (line ~1219) and `SubgraphNode._syncPromotions()` (line ~279). Both call sites always bind an `input._subgraphSlot`, so `getBoundSubgraphSlot()` returning `undefined` cannot occur during normal rename/label operations. The `displayName` fallback in the `label` getter and the silent no-op in the `label` setter are intentional defensive patterns for transient state and test-only scenarios only. Do not flag the slotless fallback as a missing rename path for "independently promoted widgets."
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: coderabbit-custom-pre-merge-checks-unique-id-file-non-traceable-F7F2B60C-1728-4C9A-8889-4F2235E186CA.txt:0-0
Timestamp: 2026-03-31T00:52:02.705Z
Learning: Applies to {src/lib/litegraph/**,src/ecs/**} : ADR compliance for entity/litegraph changes: Extension ecosystem compatibility — changes to extension-facing callbacks (onConnectionsChange, onRemoved, onAdded, onConfigure, onConnectInput/Output, onWidgetChanged), node.widgets access, node.serialize overrides, or graph._version++ require migration guidance as these affect 40+ custom node repos.
Learnt from: jtydhr88
Repo: Comfy-Org/ComfyUI_frontend PR: 10349
File: src/renderer/glsl/useGLSLPreview.ts:31-34
Timestamp: 2026-03-21T00:15:21.439Z
Learning: In Comfy-Org/ComfyUI_frontend, the autogrow system in `src/renderer/glsl/useGLSLPreview.ts` (GLSLShader nodes) creates sequential uniform inputs (u_float0, u_float1, …). When an earlier input is disconnected, later inputs contract to fill the gap, so the input array is always dense. Replaying linked uniform values by array position is therefore correct; do not flag this as a sparse-wiring / index-shift bug.
Learnt from: jaeone94
Repo: Comfy-Org/ComfyUI_frontend PR: 10648
File: src/components/rightSidePanel/subgraph/SubgraphEditor.vue:0-0
Timestamp: 2026-03-28T08:51:13.602Z
Learning: In `src/components/rightSidePanel/subgraph/SubgraphEditor.vue` (Comfy-Org/ComfyUI_frontend), `input._widget` on subgraph input slots is WeakRef-backed and non-reactive. A `linkedKeys` computed that reads `input._widget` in a loop cannot reliably trigger Vue reactivity updates. The current approach avoids this by depending on `promotionEntries` (reactive) as the computed dependency and delegating per-call linked checks to `isLinkedPromotion()`.
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7459
File: src/lib/litegraph/src/canvas/LinkConnector.ts:875-881
Timestamp: 2026-02-23T19:49:55.224Z
Learning: ComfyUI_frontend TypeScript review preference: Prefer user-defined type guards (e.g., function isMovingInputLink(x): x is MovingInputLink) over inline type assertions when narrowing union types like RenderLinkUnion in src/lib/litegraph/**/*.ts. Apply especially in LinkConnector and related canvas classes to avoid casts and improve reuse.
Learnt from: dante01yoon
Repo: Comfy-Org/ComfyUI_frontend PR: 9742
File: src/components/input/SingleSelect.vue:70-86
Timestamp: 2026-03-11T09:16:39.665Z
Learning: In `src/components/input/SingleSelect.vue` (Comfy-Org/ComfyUI_frontend), the previous PrimeVue implementation hardcoded `option-label="name"` and `option-value="value"`. There was never an `optionLabel`/`optionValue` prop exposed to consumers. All callers pass `SelectOption[]` (i.e., `{ name: string, value: string }`). The new Reka UI implementation using `SelectItem`/`SelectItemText` with `opt.name`/`opt.value` preserves full API parity. Do not flag the hardcoded `{ name, value }` access as a regression or missing mapping props in code reviews for this component.
Learnt from: viva-jinyi
Repo: Comfy-Org/ComfyUI_frontend PR: 10499
File: src/renderer/extensions/vueNodes/widgets/components/form/dropdown/FormDropdown.vue:146-150
Timestamp: 2026-03-25T03:30:27.889Z
Learning: In `src/renderer/extensions/vueNodes/widgets/components/form/dropdown/FormDropdown.vue` (and similar canvas node widget dropdowns in ComfyUI_frontend), do not flag the absence of focus restoration when the dropdown closes as a blocker issue. The component lives inside a canvas node that is overwhelmingly mouse-driven, and the previous PrimeVue Popover implementation also did not restore focus. Focus-restoration improvements are valid enhancements but should be raised as separate issues/PRs, not blocking the current change.
Learnt from: jaeone94
Repo: Comfy-Org/ComfyUI_frontend PR: 10648
File: src/components/rightSidePanel/subgraph/SubgraphEditor.vue:0-0
Timestamp: 2026-03-28T08:51:13.602Z
Learning: In `src/components/rightSidePanel/subgraph/SubgraphEditor.vue` (Comfy-Org/ComfyUI_frontend PR `#10648`), linked-promotion detection uses direct `isLinkedPromotion(node, sourceNodeId, sourceWidgetName)` calls rather than a `linkedKeys` Set lookup. `isLinkedPromotion` iterates over `node.inputs` and checks `input._widget` per slot; since each slot holds at most one `_widget`, two promoted widgets sharing `sourceNodeId:sourceWidgetName` but differing by `disambiguatingSourceNodeId` occupy separate slots and are matched independently — there is no false-positive collapse risk. Do not flag `linkedKeys` key construction (when it exists as a Set) as a disambiguation collision issue when the actual linked-state check is done via direct `isLinkedPromotion()` calls.
Learnt from: christian-byrne
Repo: Comfy-Org/ComfyUI_frontend PR: 10547
File: browser_tests/tests/workflowPersistence.spec.ts:459-471
Timestamp: 2026-03-27T05:12:16.400Z
Learning: In `browser_tests/tests/workflowPersistence.spec.ts` (Comfy-Org/ComfyUI_frontend PR `#10547`), the G10 test for PR `#8715` (transient blob:/api-view URL serialization) intentionally validates only the static/default workflow export — not an executed/transient widget state. Putting an image widget into its executed state requires actual model inference (image output generation), which is not available in the current E2E test infrastructure. The test still covers the regression if the `widget.serialize` disable path breaks. Do not flag the absence of transient-state setup in this test; full integration coverage is tracked separately.
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: :0-0
Timestamp: 2026-03-20T19:58:37.779Z
Learning: In Comfy-Org/ComfyUI_frontend PR `#10348`, the PR titled "fix: clean up knip config, upgrade to v6, remove unused exports" is a dependency upgrade (knip v5 → v6) + config cleanup, not a bug fix. The appropriate conventional commit type is `chore:` or `build:`, not `fix:`.
Learnt from: pythongosssss
Repo: Comfy-Org/ComfyUI_frontend PR: 10341
File: src/components/builder/AppBuilder.vue:77-85
Timestamp: 2026-03-20T18:53:45.378Z
Learning: In Comfy-Org/ComfyUI_frontend, `widget.callback` should only be triggered when the widget's **value** changes, not when only the widget's **label** is renamed. In `inlineRenameInput` (AppBuilder.vue), the label rename via `renameWidget()` does not change the widget value, so invoking `widget.callback?.(widget.value)` is incorrect and unnecessary.
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.
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.
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.
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7537
File: src/components/ui/button/Button.stories.ts:45-55
Timestamp: 2025-12-17T00:40:09.635Z
Learning: Prefer pure function declarations over function expressions (e.g., use function foo() { ... } instead of const foo = () => { ... }) for pure functions in the repository. Function declarations are more functional-leaning, offer better hoisting clarity, and can improve readability and tooling consistency. Apply this guideline across TypeScript files in Comfy-Org/ComfyUI_frontend, including story and UI component code, except where a function expression is semantically required (e.g., callbacks, higher-order functions with closures).
Learnt from: kaili-yang
Repo: Comfy-Org/ComfyUI_frontend PR: 7805
File: src/composables/useCoreCommands.ts:439-439
Timestamp: 2025-12-30T22:22:33.836Z
Learning: When accessing reactive properties from Pinia stores in TypeScript files, avoid using .value on direct property access (e.g., useStore().isOverlayExpanded). Pinia auto-wraps refs when accessed directly, returning the primitive value. The .value accessor is only needed when destructuring store properties or when using storeToRefs().
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7906
File: src/components/sidebar/tabs/AssetsSidebarTab.vue:545-552
Timestamp: 2026-01-12T17:39:27.738Z
Learning: In Vue/TypeScript files (src/**/*.{ts,tsx,vue}), prefer if/else statements over ternary operators when performing side effects or actions (e.g., mutating state, calling methods with side effects). Ternaries should be reserved for computing and returning values.
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 8248
File: src/platform/assets/schemas/assetSchema.ts:109-118
Timestamp: 2026-01-22T23:44:59.888Z
Learning: Do not export declarations (e.g., schemas, constants, types) unless they are actually used elsewhere in the codebase. Keep the public API surface minimal by exporting only items with concrete usage. This reduces coupling and keeps imports explicit. In src/platform/assets/schemas/assetSchema.ts, ensure only necessary exports are exposed; remove unused exports or switch to non-exported/internal where appropriate.
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 8307
File: src/stores/bootstrapStore.ts:61-78
Timestamp: 2026-01-26T18:39:22.294Z
Learning: Do not expose internal state or error refs from stores unless there is demonstrated active usage elsewhere in the codebase. Keep internal state private by default; only expose what is actively consumed. Applies to all TypeScript files under src/stores (e.g., bootstrapStore.ts and siblings). Ensure exported API only includes properties/methods that are actually used by consumers; avoid leaking implementation details.
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 8722
File: src/composables/maskeditor/useBrushDrawing.ts:5-5
Timestamp: 2026-02-08T03:19:12.009Z
Learning: Treat unresolved import warnings caused by pnpm workspace catalog mappings (pnpm-workspace.yaml) and unplugin-typegpu in vite.config.mts as false positives. Do not flag these in PR reviews; they are expected in sandboxes without node_modules and are not indicative of actual missing dependencies in the TS codebase.
Learnt from: christian-byrne
Repo: Comfy-Org/ComfyUI_frontend PR: 8966
File: src/extensions/core/load3d.ts:427-430
Timestamp: 2026-02-19T02:06:23.468Z
Learning: In TypeScript, you can use typeof SomeClass in type annotation positions (e.g., param: typeof LGraphNode) even when SomeClass is imported with import type. This is a type query that only exists at compile time and is erased in runtime, so it is safe to combine with type-only imports. Apply this pattern to TS files broadly when you need a type that references the shape of a class or constructor function without importing the value at runtime.
Learnt from: christian-byrne
Repo: Comfy-Org/ComfyUI_frontend PR: 8966
File: src/extensions/core/uploadAudio.ts:91-94
Timestamp: 2026-02-19T02:06:38.395Z
Learning: In TypeScript files, you can use a type annotation like 'nodeType: typeof MyClass' even if MyClass is imported via 'import type'. Both the type-only import and 'typeof' operate at the type level and are erased at compile time. This pattern is commonly used for constructor types (e.g., 'nodeType: typeof LGraphNode'). Apply this pattern across TypeScript files in the repository (src/**/*.ts) as appropriate, ensuring the imported symbol is a type-only import when possible for clarity and to avoid runtime imports.
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 8992
File: src/lib/litegraph/src/widgets/GradientSliderWidget.ts:18-18
Timestamp: 2026-02-20T21:08:19.814Z
Learning: When drawing with CanvasRenderingContext2D in TypeScript/JavaScript, wrap the drawing logic with ctx.save() at the start and ctx.restore() at the end to preserve and restore the canvas state. Do not manually destructure and restore individual properties (e.g., fillStyle, strokeStyle); rely on save/restore to manage state changes in a scoped manner. This should be applied to all TS files that perform canvas drawing.
Learnt from: dante01yoon
Repo: Comfy-Org/ComfyUI_frontend PR: 9075
File: src/scripts/api.featureFlags.test.ts:237-268
Timestamp: 2026-02-22T04:27:33.379Z
Learning: In Vite/Vitest, import.meta.env.DEV is true for any mode that is not 'production' (i.e., DEV is the opposite of PROD, and can be true in 'test', 'development', etc.). Do not assume DEV implies only 'development' mode. When reviewing code and tests, treat DEV as a non-production flag and verify environment-specific logic accordingly. Reference: https://vite.dev/guide/env-and-mode#modes
Learnt from: christian-byrne
Repo: Comfy-Org/ComfyUI_frontend PR: 9427
File: src/renderer/extensions/vueNodes/widgets/components/form/dropdown/FormDropdownMenuFilter.vue:33-33
Timestamp: 2026-03-06T00:53:28.835Z
Learning: When reviewing code, note that the enforce-canonical-classes (better-tailwindcss) rule may auto-fix Tailwind v3 !class-name syntax by converting it to v4 class-name! syntax. Do not treat these auto-fixed class-name! instances as newly introduced issues; the perceived change is in syntax placement, not in usage or intent. This guidance applies across all .vue and .ts files in the repository.
Learnt from: sonnybox
Repo: Comfy-Org/ComfyUI_frontend PR: 9446
File: src/renderer/extensions/vueNodes/widgets/components/WidgetTextarea.vue:45-45
Timestamp: 2026-03-06T01:55:00.013Z
Learning: Treat wrap-break-word as a valid Tailwind CSS utility for overflow-wrap: break-word in Tailwind v4+ projects. Do not flag this class as invalid in any Vue (.vue) or TypeScript (.ts/.tsx) files within the repository (e.g., Comfy-Org/ComfyUI_frontend) or other Tailwind v4+ projects. When reviewing, verify that the class is used to enable word breaking in long text content and reference the Tailwind docs: https://tailwindcss.com/docs/overflow-wrap.
If you found this review helpful, would you consider giving us a shout-out on X?
Thank you for using CodeRabbit!
Address CodeRabbit review: - Update defaultInput deprecation message to not recommend forceInput - Add test verifying deprecation warning emission
|
hello, can you update the doc. |
|
Hi @lishunyang12, thanks for the feedback! I've updated the deprecation warning message in commit 1f4c20b to clarify that Could you let me know which specific doc you'd like updated? If you mean the console warning itself, that's already addressed. If you're referring to external documentation (e.g. docs.comfy.org), happy to open a follow-up. |
📦 Bundle: 5.26 MB gzip 🟢 -128 BDetailsSummary
Category Glance App Entry Points — 22.6 kB (baseline 22.6 kB) • ⚪ 0 BMain entry bundles and manifests
Status: 1 added / 1 removed Graph Workspace — 1.24 MB (baseline 1.24 MB) • ⚪ 0 BGraph editor runtime, canvas, workflow orchestration
Status: 1 added / 1 removed Views & Navigation — 82.3 kB (baseline 82.3 kB) • ⚪ 0 BTop-level views, pages, and routed surfaces
Status: 9 added / 9 removed / 2 unchanged Panels & Settings — 489 kB (baseline 489 kB) • ⚪ 0 BConfiguration panels, inspectors, and settings screens
Status: 10 added / 10 removed / 11 unchanged User & Accounts — 17.6 kB (baseline 17.6 kB) • ⚪ 0 BAuthentication, profile, and account management bundles
Status: 5 added / 5 removed / 2 unchanged Editors & Dialogs — 112 kB (baseline 112 kB) • ⚪ 0 BModals, dialogs, drawers, and in-app editors
Status: 4 added / 4 removed UI Components — 62.9 kB (baseline 62.9 kB) • ⚪ 0 BReusable component library chunks
Status: 5 added / 5 removed / 9 unchanged Data & Services — 3.05 MB (baseline 3.05 MB) • 🔴 +463 BStores, services, APIs, and repositories
Status: 13 added / 13 removed / 4 unchanged Utilities & Hooks — 365 kB (baseline 365 kB) • ⚪ 0 BHelpers, composables, and utility bundles
Status: 13 added / 13 removed / 18 unchanged Vendor & Third-Party — 9.94 MB (baseline 9.94 MB) • ⚪ 0 BExternal libraries and shared vendor chunks Status: 16 unchanged Other — 8.82 MB (baseline 8.82 MB) • 🟢 -730 BBundles that do not match a named category
Status: 57 added / 57 removed / 79 unchanged ⚡ Performance Report
All metrics
Historical variance (last 15 runs)
Trend (last 15 commits on main)
Raw data{
"timestamp": "2026-05-04T23:07:57.878Z",
"gitSha": "03471f0e6cf9ad36e6bfadc5c63857d5998d4a5d",
"branch": "fix/default-input-widget-reload",
"measurements": [
{
"name": "canvas-idle",
"durationMs": 2071.302000000003,
"styleRecalcs": 7,
"styleRecalcDurationMs": 5.4209999999999985,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 381.5729999999999,
"heapDeltaBytes": 22804808,
"heapUsedBytes": 71111276,
"domNodes": 14,
"jsHeapTotalBytes": 14942208,
"scriptDurationMs": 16.205,
"eventListeners": 4,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.666666666666668,
"p95FrameDurationMs": 16.800000000000182
},
{
"name": "canvas-idle",
"durationMs": 2028.8419999999974,
"styleRecalcs": 11,
"styleRecalcDurationMs": 8.231999999999998,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 349.732,
"heapDeltaBytes": 23846340,
"heapUsedBytes": 72749940,
"domNodes": 22,
"jsHeapTotalBytes": 15204352,
"scriptDurationMs": 21.505000000000003,
"eventListeners": 6,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.666666666666668,
"p95FrameDurationMs": 16.700000000000728
},
{
"name": "canvas-idle",
"durationMs": 2046.8949999999495,
"styleRecalcs": 8,
"styleRecalcDurationMs": 6.485999999999999,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 386.40000000000003,
"heapDeltaBytes": -5331908,
"heapUsedBytes": 43126208,
"domNodes": -265,
"jsHeapTotalBytes": 14807040,
"scriptDurationMs": 14.923000000000002,
"eventListeners": -133,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.666666666666668,
"p95FrameDurationMs": 16.700000000000728
},
{
"name": "canvas-mouse-sweep",
"durationMs": 1816.0109999999747,
"styleRecalcs": 76,
"styleRecalcDurationMs": 37.382,
"layouts": 12,
"layoutDurationMs": 3.596,
"taskDurationMs": 721.9259999999999,
"heapDeltaBytes": -1509496,
"heapUsedBytes": 67007588,
"domNodes": 61,
"jsHeapTotalBytes": 19398656,
"scriptDurationMs": 113.376,
"eventListeners": 4,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.666666666666668,
"p95FrameDurationMs": 16.800000000000182
},
{
"name": "canvas-mouse-sweep",
"durationMs": 2015.925999999979,
"styleRecalcs": 85,
"styleRecalcDurationMs": 40.166,
"layouts": 12,
"layoutDurationMs": 3.511,
"taskDurationMs": 973.6999999999999,
"heapDeltaBytes": 4739256,
"heapUsedBytes": 52561524,
"domNodes": -260,
"jsHeapTotalBytes": 15331328,
"scriptDurationMs": 117.148,
"eventListeners": -131,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.666666666666668,
"p95FrameDurationMs": 16.700000000000728
},
{
"name": "canvas-mouse-sweep",
"durationMs": 2018.024999999966,
"styleRecalcs": 78,
"styleRecalcDurationMs": 37.183,
"layouts": 12,
"layoutDurationMs": 3.273,
"taskDurationMs": 933.97,
"heapDeltaBytes": -2130240,
"heapUsedBytes": 46757664,
"domNodes": -263,
"jsHeapTotalBytes": 16642048,
"scriptDurationMs": 109.685,
"eventListeners": -131,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.666666666666668,
"p95FrameDurationMs": 16.699999999999818
},
{
"name": "canvas-zoom-sweep",
"durationMs": 1713.5069999999928,
"styleRecalcs": 32,
"styleRecalcDurationMs": 15.154999999999998,
"layouts": 6,
"layoutDurationMs": 0.568,
"taskDurationMs": 280.326,
"heapDeltaBytes": 215820,
"heapUsedBytes": 48478272,
"domNodes": 77,
"jsHeapTotalBytes": 14942208,
"scriptDurationMs": 17.610999999999997,
"eventListeners": 21,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.670000000000012,
"p95FrameDurationMs": 16.800000000000182
},
{
"name": "canvas-zoom-sweep",
"durationMs": 1718.60300000003,
"styleRecalcs": 31,
"styleRecalcDurationMs": 15.043000000000001,
"layouts": 6,
"layoutDurationMs": 0.6329999999999999,
"taskDurationMs": 278.68399999999997,
"heapDeltaBytes": 208804,
"heapUsedBytes": 48838412,
"domNodes": 75,
"jsHeapTotalBytes": 15466496,
"scriptDurationMs": 17.217999999999996,
"eventListeners": 19,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.670000000000012,
"p95FrameDurationMs": 16.700000000000728
},
{
"name": "canvas-zoom-sweep",
"durationMs": 1711.4860000000363,
"styleRecalcs": 32,
"styleRecalcDurationMs": 15.292,
"layouts": 6,
"layoutDurationMs": 0.561,
"taskDurationMs": 292.718,
"heapDeltaBytes": 5103276,
"heapUsedBytes": 70854248,
"domNodes": 76,
"jsHeapTotalBytes": 20541440,
"scriptDurationMs": 17.598999999999997,
"eventListeners": 19,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.66999999999998,
"p95FrameDurationMs": 16.800000000000182
},
{
"name": "dom-widget-clipping",
"durationMs": 583.4479999999758,
"styleRecalcs": 11,
"styleRecalcDurationMs": 7.189000000000001,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 339.555,
"heapDeltaBytes": 8786048,
"heapUsedBytes": 57387356,
"domNodes": 18,
"jsHeapTotalBytes": 15990784,
"scriptDurationMs": 55.602,
"eventListeners": 0,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.666666666666668,
"p95FrameDurationMs": 16.799999999999727
},
{
"name": "dom-widget-clipping",
"durationMs": 569.1739999999754,
"styleRecalcs": 10,
"styleRecalcDurationMs": 7.412999999999999,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 314.538,
"heapDeltaBytes": 9136372,
"heapUsedBytes": 57442396,
"domNodes": 16,
"jsHeapTotalBytes": 14942208,
"scriptDurationMs": 52.468,
"eventListeners": 2,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.666666666666668,
"p95FrameDurationMs": 16.799999999999727
},
{
"name": "dom-widget-clipping",
"durationMs": 519.7660000000042,
"styleRecalcs": 10,
"styleRecalcDurationMs": 6.193999999999998,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 309.23400000000004,
"heapDeltaBytes": 8753816,
"heapUsedBytes": 57151820,
"domNodes": 16,
"jsHeapTotalBytes": 15466496,
"scriptDurationMs": 50.417,
"eventListeners": 0,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.670000000000012,
"p95FrameDurationMs": 16.700000000000273
},
{
"name": "large-graph-idle",
"durationMs": 2033.1189999999992,
"styleRecalcs": 10,
"styleRecalcDurationMs": 7.828000000000001,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 524.2450000000001,
"heapDeltaBytes": 6541700,
"heapUsedBytes": 63658276,
"domNodes": -262,
"jsHeapTotalBytes": 815104,
"scriptDurationMs": 83.76299999999999,
"eventListeners": -129,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.666666666666668,
"p95FrameDurationMs": 16.800000000000182
},
{
"name": "large-graph-idle",
"durationMs": 2024.3679999999813,
"styleRecalcs": 10,
"styleRecalcDurationMs": 7.861,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 525.3939999999999,
"heapDeltaBytes": 4653076,
"heapUsedBytes": 61662904,
"domNodes": -259,
"jsHeapTotalBytes": 28672,
"scriptDurationMs": 83.099,
"eventListeners": -129,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.666666666666668,
"p95FrameDurationMs": 16.700000000000728
},
{
"name": "large-graph-idle",
"durationMs": 2037.6850000000104,
"styleRecalcs": 8,
"styleRecalcDurationMs": 6.584,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 523.766,
"heapDeltaBytes": 8852004,
"heapUsedBytes": 67330908,
"domNodes": -262,
"jsHeapTotalBytes": -233472,
"scriptDurationMs": 78.906,
"eventListeners": -129,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.666666666666668,
"p95FrameDurationMs": 16.700000000000728
},
{
"name": "large-graph-pan",
"durationMs": 2098.774999999989,
"styleRecalcs": 67,
"styleRecalcDurationMs": 16.881000000000004,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 1042.277,
"heapDeltaBytes": 4353112,
"heapUsedBytes": 63716468,
"domNodes": -266,
"jsHeapTotalBytes": 1544192,
"scriptDurationMs": 383.759,
"eventListeners": -129,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.66999999999998,
"p95FrameDurationMs": 16.799999999999272
},
{
"name": "large-graph-pan",
"durationMs": 2114.6850000000086,
"styleRecalcs": 68,
"styleRecalcDurationMs": 17.208000000000006,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 1034.5760000000002,
"heapDeltaBytes": -640492,
"heapUsedBytes": 59153616,
"domNodes": -262,
"jsHeapTotalBytes": 6524928,
"scriptDurationMs": 365.672,
"eventListeners": -127,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.666666666666668,
"p95FrameDurationMs": 16.799999999999272
},
{
"name": "large-graph-pan",
"durationMs": 2143.493000000035,
"styleRecalcs": 69,
"styleRecalcDurationMs": 17.18,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 1022.356,
"heapDeltaBytes": 6807056,
"heapUsedBytes": 66207172,
"domNodes": -264,
"jsHeapTotalBytes": 495616,
"scriptDurationMs": 356.839,
"eventListeners": -127,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.666666666666668,
"p95FrameDurationMs": 16.799999999999272
},
{
"name": "large-graph-zoom",
"durationMs": 3134.5339999999737,
"styleRecalcs": 65,
"styleRecalcDurationMs": 17.868000000000002,
"layouts": 60,
"layoutDurationMs": 7.708000000000001,
"taskDurationMs": 1253.314,
"heapDeltaBytes": 12002516,
"heapUsedBytes": 72721288,
"domNodes": -269,
"jsHeapTotalBytes": 290816,
"scriptDurationMs": 463.87500000000006,
"eventListeners": -125,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.666666666666668,
"p95FrameDurationMs": 16.800000000000182
},
{
"name": "large-graph-zoom",
"durationMs": 3114.215999999999,
"styleRecalcs": 65,
"styleRecalcDurationMs": 18.448000000000004,
"layouts": 60,
"layoutDurationMs": 7.757999999999999,
"taskDurationMs": 1262.336,
"heapDeltaBytes": 18170636,
"heapUsedBytes": 79342720,
"domNodes": -268,
"jsHeapTotalBytes": 1077248,
"scriptDurationMs": 467.13200000000006,
"eventListeners": -125,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.666666666666668,
"p95FrameDurationMs": 16.699999999999818
},
{
"name": "large-graph-zoom",
"durationMs": 3134.488000000033,
"styleRecalcs": 65,
"styleRecalcDurationMs": 17.942999999999998,
"layouts": 60,
"layoutDurationMs": 7.732,
"taskDurationMs": 1268.727,
"heapDeltaBytes": 8965784,
"heapUsedBytes": 69737296,
"domNodes": -268,
"jsHeapTotalBytes": 5533696,
"scriptDurationMs": 467.543,
"eventListeners": -125,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.66333333333335,
"p95FrameDurationMs": 16.699999999999818
},
{
"name": "minimap-idle",
"durationMs": 2009.4290000000115,
"styleRecalcs": 8,
"styleRecalcDurationMs": 6.533999999999998,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 510.7759999999999,
"heapDeltaBytes": 3759716,
"heapUsedBytes": 64181088,
"domNodes": -264,
"jsHeapTotalBytes": 552960,
"scriptDurationMs": 78.24199999999999,
"eventListeners": -129,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.666666666666668,
"p95FrameDurationMs": 16.699999999999818
},
{
"name": "minimap-idle",
"durationMs": 2014.2610000000332,
"styleRecalcs": 6,
"styleRecalcDurationMs": 5.034000000000001,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 504.572,
"heapDeltaBytes": 11965560,
"heapUsedBytes": 71982028,
"domNodes": -269,
"jsHeapTotalBytes": 290816,
"scriptDurationMs": 75.967,
"eventListeners": -129,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.66333333333332,
"p95FrameDurationMs": 16.700000000000728
},
{
"name": "minimap-idle",
"durationMs": 2007.9999999999245,
"styleRecalcs": 8,
"styleRecalcDurationMs": 6.414999999999997,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 514.998,
"heapDeltaBytes": 5280368,
"heapUsedBytes": 66213664,
"domNodes": -265,
"jsHeapTotalBytes": 1077248,
"scriptDurationMs": 78.97099999999999,
"eventListeners": -129,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.666666666666668,
"p95FrameDurationMs": 16.699999999999818
},
{
"name": "subgraph-dom-widget-clipping",
"durationMs": 545.2700000000164,
"styleRecalcs": 48,
"styleRecalcDurationMs": 12.366999999999999,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 361.253,
"heapDeltaBytes": 9605068,
"heapUsedBytes": 57546900,
"domNodes": 22,
"jsHeapTotalBytes": 14942208,
"scriptDurationMs": 130.381,
"eventListeners": 8,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.663333333333338,
"p95FrameDurationMs": 16.700000000000273
},
{
"name": "subgraph-dom-widget-clipping",
"durationMs": 560.5879999999956,
"styleRecalcs": 47,
"styleRecalcDurationMs": 10.475999999999999,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 356.326,
"heapDeltaBytes": 9876472,
"heapUsedBytes": 57822648,
"domNodes": 20,
"jsHeapTotalBytes": 15466496,
"scriptDurationMs": 127.891,
"eventListeners": 8,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.666666666666668,
"p95FrameDurationMs": 16.799999999999727
},
{
"name": "subgraph-dom-widget-clipping",
"durationMs": 579.84399999998,
"styleRecalcs": 46,
"styleRecalcDurationMs": 9.581000000000001,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 345.59299999999996,
"heapDeltaBytes": 9036672,
"heapUsedBytes": 57890380,
"domNodes": 18,
"jsHeapTotalBytes": 15728640,
"scriptDurationMs": 123.002,
"eventListeners": 8,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.66333333333332,
"p95FrameDurationMs": 16.700000000000273
},
{
"name": "subgraph-idle",
"durationMs": 2021.729999999991,
"styleRecalcs": 9,
"styleRecalcDurationMs": 7.118000000000001,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 323.303,
"heapDeltaBytes": 22283324,
"heapUsedBytes": 70664196,
"domNodes": 18,
"jsHeapTotalBytes": 15204352,
"scriptDurationMs": 12.714,
"eventListeners": 4,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.666666666666668,
"p95FrameDurationMs": 16.800000000000182
},
{
"name": "subgraph-idle",
"durationMs": 2003.9750000000254,
"styleRecalcs": 9,
"styleRecalcDurationMs": 6.710000000000001,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 323.44700000000006,
"heapDeltaBytes": 22561640,
"heapUsedBytes": 71250540,
"domNodes": 18,
"jsHeapTotalBytes": 14942208,
"scriptDurationMs": 12.596,
"eventListeners": 4,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.66999999999998,
"p95FrameDurationMs": 16.800000000000182
},
{
"name": "subgraph-idle",
"durationMs": 2007.1430000000419,
"styleRecalcs": 10,
"styleRecalcDurationMs": 6.785000000000001,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 323.741,
"heapDeltaBytes": 22559800,
"heapUsedBytes": 71261036,
"domNodes": 19,
"jsHeapTotalBytes": 14680064,
"scriptDurationMs": 12.584999999999999,
"eventListeners": 4,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.666666666666668,
"p95FrameDurationMs": 16.700000000000728
},
{
"name": "subgraph-mouse-sweep",
"durationMs": 1690.9109999999714,
"styleRecalcs": 75,
"styleRecalcDurationMs": 32.742999999999995,
"layouts": 16,
"layoutDurationMs": 3.796,
"taskDurationMs": 648.518,
"heapDeltaBytes": -3498604,
"heapUsedBytes": 44842008,
"domNodes": -261,
"jsHeapTotalBytes": 15331328,
"scriptDurationMs": 80.839,
"eventListeners": -129,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.66333333333335,
"p95FrameDurationMs": 16.799999999999272
},
{
"name": "subgraph-mouse-sweep",
"durationMs": 1735.5019999999968,
"styleRecalcs": 79,
"styleRecalcDurationMs": 39.626000000000005,
"layouts": 16,
"layoutDurationMs": 4.277,
"taskDurationMs": 643.4009999999998,
"heapDeltaBytes": 14119504,
"heapUsedBytes": 62678880,
"domNodes": 60,
"jsHeapTotalBytes": 15466496,
"scriptDurationMs": 81.656,
"eventListeners": 4,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.666666666666668,
"p95FrameDurationMs": 16.700000000000728
},
{
"name": "subgraph-mouse-sweep",
"durationMs": 1722.0629999999346,
"styleRecalcs": 77,
"styleRecalcDurationMs": 35.034000000000006,
"layouts": 16,
"layoutDurationMs": 4.458,
"taskDurationMs": 611.5710000000001,
"heapDeltaBytes": 14301484,
"heapUsedBytes": 62945220,
"domNodes": 62,
"jsHeapTotalBytes": 14942208,
"scriptDurationMs": 82.586,
"eventListeners": 4,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.666666666666668,
"p95FrameDurationMs": 16.800000000000182
},
{
"name": "viewport-pan-sweep",
"durationMs": 8125.9939999999915,
"styleRecalcs": 249,
"styleRecalcDurationMs": 53.786,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 3387.966,
"heapDeltaBytes": 12520472,
"heapUsedBytes": 71029404,
"domNodes": -261,
"jsHeapTotalBytes": 7573504,
"scriptDurationMs": 1125.88,
"eventListeners": -113,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.670000000000012,
"p95FrameDurationMs": 16.700000000000728
},
{
"name": "viewport-pan-sweep",
"durationMs": 8124.104000000045,
"styleRecalcs": 248,
"styleRecalcDurationMs": 51.99999999999999,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 3457.2960000000003,
"heapDeltaBytes": 13706624,
"heapUsedBytes": 72114172,
"domNodes": -264,
"jsHeapTotalBytes": 2592768,
"scriptDurationMs": 1128.797,
"eventListeners": -113,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.66333333333332,
"p95FrameDurationMs": 16.700000000000728
},
{
"name": "viewport-pan-sweep",
"durationMs": 8162.454000000025,
"styleRecalcs": 249,
"styleRecalcDurationMs": 53.456,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 3419.3379999999997,
"heapDeltaBytes": 15205164,
"heapUsedBytes": 74153976,
"domNodes": -263,
"jsHeapTotalBytes": 6815744,
"scriptDurationMs": 1142.4299999999998,
"eventListeners": -113,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.666666666666668,
"p95FrameDurationMs": 16.80000000000109
},
{
"name": "vue-large-graph-idle",
"durationMs": 12574.239999999974,
"styleRecalcs": 0,
"styleRecalcDurationMs": 0,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 12508.316,
"heapDeltaBytes": -43128312,
"heapUsedBytes": 171693128,
"domNodes": -8362,
"jsHeapTotalBytes": 26275840,
"scriptDurationMs": 638.6619999999999,
"eventListeners": -16466,
"totalBlockingTimeMs": 0,
"frameDurationMs": 17.223333333333358,
"p95FrameDurationMs": 16.799999999999272
},
{
"name": "vue-large-graph-idle",
"durationMs": 12224.909000000025,
"styleRecalcs": 0,
"styleRecalcDurationMs": 0,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 12214.551999999998,
"heapDeltaBytes": -27283288,
"heapUsedBytes": 171626096,
"domNodes": -8331,
"jsHeapTotalBytes": 23654400,
"scriptDurationMs": 540.822,
"eventListeners": -16464,
"totalBlockingTimeMs": 0,
"frameDurationMs": 17.223333333333358,
"p95FrameDurationMs": 16.80000000000291
},
{
"name": "vue-large-graph-idle",
"durationMs": 12268.63000000003,
"styleRecalcs": 0,
"styleRecalcDurationMs": 0,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 12259.164000000002,
"heapDeltaBytes": -34864008,
"heapUsedBytes": 172177008,
"domNodes": -8331,
"jsHeapTotalBytes": 25227264,
"scriptDurationMs": 554.767,
"eventListeners": -16462,
"totalBlockingTimeMs": 0,
"frameDurationMs": 17.223333333333358,
"p95FrameDurationMs": 16.799999999999272
},
{
"name": "vue-large-graph-pan",
"durationMs": 14778.911999999991,
"styleRecalcs": 68,
"styleRecalcDurationMs": 17.737000000000002,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 14748.04,
"heapDeltaBytes": -34137916,
"heapUsedBytes": 165351436,
"domNodes": -8331,
"jsHeapTotalBytes": -4132864,
"scriptDurationMs": 895.048,
"eventListeners": -16460,
"totalBlockingTimeMs": 0,
"frameDurationMs": 17.780000000000047,
"p95FrameDurationMs": 16.700000000000728
},
{
"name": "vue-large-graph-pan",
"durationMs": 14528.998000000001,
"styleRecalcs": 68,
"styleRecalcDurationMs": 19.78800000000003,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 14510.441,
"heapDeltaBytes": -47738256,
"heapUsedBytes": 165414868,
"domNodes": -8331,
"jsHeapTotalBytes": -4218880,
"scriptDurationMs": 853.0609999999999,
"eventListeners": -16460,
"totalBlockingTimeMs": 40,
"frameDurationMs": 17.219999999999953,
"p95FrameDurationMs": 16.799999999999272
},
{
"name": "vue-large-graph-pan",
"durationMs": 14743.533999999954,
"styleRecalcs": 68,
"styleRecalcDurationMs": 17.946999999999992,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 14723.867,
"heapDeltaBytes": -23417184,
"heapUsedBytes": 174109680,
"domNodes": -8329,
"jsHeapTotalBytes": -1597440,
"scriptDurationMs": 845.726,
"eventListeners": -16488,
"totalBlockingTimeMs": 29,
"frameDurationMs": 17.223333333333237,
"p95FrameDurationMs": 16.799999999999272
},
{
"name": "workflow-execution",
"durationMs": 463.9380000000415,
"styleRecalcs": 18,
"styleRecalcDurationMs": 23.294,
"layouts": 5,
"layoutDurationMs": 1.7419999999999998,
"taskDurationMs": 128.102,
"heapDeltaBytes": 5405636,
"heapUsedBytes": 55821412,
"domNodes": 170,
"jsHeapTotalBytes": 0,
"scriptDurationMs": 27.632000000000005,
"eventListeners": 69,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.666666666666668,
"p95FrameDurationMs": 16.799999999999727
},
{
"name": "workflow-execution",
"durationMs": 132.3370000000068,
"styleRecalcs": 13,
"styleRecalcDurationMs": 19.897,
"layouts": 4,
"layoutDurationMs": 1.566,
"taskDurationMs": 96.104,
"heapDeltaBytes": 3466272,
"heapUsedBytes": 53236720,
"domNodes": 146,
"jsHeapTotalBytes": 524288,
"scriptDurationMs": 22.715,
"eventListeners": 37,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.663333333333338,
"p95FrameDurationMs": 16.799999999999727
},
{
"name": "workflow-execution",
"durationMs": 451.2929999999642,
"styleRecalcs": 15,
"styleRecalcDurationMs": 21.125999999999998,
"layouts": 5,
"layoutDurationMs": 1.36,
"taskDurationMs": 114.145,
"heapDeltaBytes": 5034676,
"heapUsedBytes": 55217840,
"domNodes": 153,
"jsHeapTotalBytes": 0,
"scriptDurationMs": 23.241,
"eventListeners": 69,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.666666666666668,
"p95FrameDurationMs": 16.700000000000273
}
]
} |
Codecov Report✅ All modified and coverable lines are covered by tests. @@ Coverage Diff @@
## main #10706 +/- ##
===========================================
- Coverage 71.80% 56.10% -15.71%
===========================================
Files 1494 1385 -109
Lines 84384 70883 -13501
Branches 23265 19759 -3506
===========================================
- Hits 60593 39766 -20827
- Misses 22923 30587 +7664
+ Partials 868 530 -338
Flags with carried forward coverage won't be shown. Click here to find out more.
... and 991 files with indirect coverage changes 🚀 New features to boost your workflow:
|
|
Superseded by #12279 (same changes, but from main repo to avoid fork workflow permission issues). Thank you @Lidang-Jiang for the contribution! |

Summary
Widgets with
defaultInput: truethat are toggled back to widget mode revert to socket-only inputs on reload. The_migrateDefaultInputmethod was settingforceInput = truefor all optional inputs withdefaultInput, which prevented widgets from being created and overrode user preferences on every load.Since frontend 1.16+, widgets and sockets co-exist on every input, so this conversion is no longer needed. This PR removes the
forceInput = trueassignment while keeping the deprecation warning.Changes
inputOptions.forceInput = truefrom_migrateDefaultInputfor optional inputsReview Focus
defaultInputis preserved — only theforceInput = trueassignment is removedforceInput)forceInput: trueare unaffected (their value comes from the node definition, not from migration)Fixes Comfy-Org/ComfyUI#1500
Test output
Test plan
defaultInput: trueoptional input, toggle to widget, save, reload — verify it stays as widget┆Issue is synchronized with this Notion page by Unito