fix: route missing-node replacement updates through pendingWarnings - #15141
fix: route missing-node replacement updates through pendingWarnings#15141jaeone94 wants to merge 4 commits into
Conversation
🎨 Storybook: ✅ Built — View Storybook🎭 Playwright: ✅ 1832 passed, 0 failed · 1 flaky📊 Browser Reports
📦 Bundle: 8.85 MB gzip 🔴 +228 BDetailsSummary
Category Glance App Entry Points — 3.71 kB (baseline 3.71 kB) • ⚪ 0 BMain entry bundles and manifests
Status: 1 added / 1 removed Graph Workspace — 1.37 MB (baseline 1.37 MB) • 🔴 +398 BGraph editor runtime, canvas, workflow orchestration
Status: 2 added / 2 removed / 1 unchanged Views & Navigation — 124 kB (baseline 124 kB) • ⚪ 0 BTop-level views, pages, and routed surfaces
Status: 13 added / 13 removed / 4 unchanged Panels & Settings — 566 kB (baseline 566 kB) • ⚪ 0 BConfiguration panels, inspectors, and settings screens
Status: 10 added / 10 removed / 16 unchanged User & Accounts — 27.7 kB (baseline 27.7 kB) • ⚪ 0 BAuthentication, profile, and account management bundles
Status: 6 added / 6 removed / 5 unchanged Editors & Dialogs — 125 kB (baseline 125 kB) • ⚪ 0 BModals, dialogs, drawers, and in-app editors
Status: 7 added / 7 removed / 1 unchanged UI Components — 67.1 kB (baseline 67.1 kB) • ⚪ 0 BReusable component library chunks
Status: 6 added / 6 removed / 8 unchanged Data & Services — 3.52 MB (baseline 3.52 MB) • 🔴 +551 BStores, services, APIs, and repositories
Status: 14 added / 14 removed / 3 unchanged Utilities & Hooks — 550 kB (baseline 550 kB) • ⚪ 0 BHelpers, composables, and utility bundles
Status: 18 added / 18 removed / 20 unchanged Vendor & Third-Party — 16.8 MB (baseline 16.8 MB) • ⚪ 0 BExternal libraries and shared vendor chunks Status: 18 unchanged Other — 14.2 MB (baseline 14.2 MB) • ⚪ 0 BBundles that do not match a named category
Status: 68 added / 68 removed / 217 unchanged ⚡ Performance Report
✅ No regressions detected. All metrics
Historical variance (last 15 runs)
Trend (last 15 commits on main)
Raw data{
"timestamp": "2026-08-18T04:27:29.127Z",
"gitSha": "462cb55a97110f1da660a82e287c02e2b9d7d860",
"branch": "jaeone94/p2-missing-node-single-writer-14653",
"measurements": [
{
"name": "canvas-idle",
"durationMs": 2016.1300000000324,
"styleRecalcs": 10,
"styleRecalcDurationMs": 4.498,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 349.173,
"heapDeltaBytes": 803108,
"heapUsedBytes": 61549996,
"domNodes": -280,
"jsHeapTotalBytes": 4972544,
"scriptDurationMs": 4.558000000000002,
"eventListeners": -149,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.666666666666668,
"p95FrameDurationMs": 16.800000000000182
},
{
"name": "canvas-idle",
"durationMs": 2007.1689999999762,
"styleRecalcs": 10,
"styleRecalcDurationMs": 4.603999999999998,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 346.462,
"heapDeltaBytes": 9048532,
"heapUsedBytes": 70203712,
"domNodes": -280,
"jsHeapTotalBytes": 4710400,
"scriptDurationMs": 4.529999999999999,
"eventListeners": -179,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.66333333333335,
"p95FrameDurationMs": 16.700000000000728
},
{
"name": "canvas-mouse-sweep",
"durationMs": 1724.4029999999952,
"styleRecalcs": 71,
"styleRecalcDurationMs": 22.712000000000003,
"layouts": 12,
"layoutDurationMs": 2.115,
"taskDurationMs": 627.3199999999999,
"heapDeltaBytes": 14259740,
"heapUsedBytes": 74794136,
"domNodes": -282,
"jsHeapTotalBytes": 5496832,
"scriptDurationMs": 67.66999999999999,
"eventListeners": -181,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.66333333333332,
"p95FrameDurationMs": 16.700000000000728
},
{
"name": "canvas-mouse-sweep",
"durationMs": 1701.6079999999647,
"styleRecalcs": 71,
"styleRecalcDurationMs": 20.750999999999998,
"layouts": 12,
"layoutDurationMs": 2.3690000000000007,
"taskDurationMs": 559.275,
"heapDeltaBytes": 1227388,
"heapUsedBytes": 61537840,
"domNodes": -282,
"jsHeapTotalBytes": 4186112,
"scriptDurationMs": 63.59200000000001,
"eventListeners": -147,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.666666666666668,
"p95FrameDurationMs": 16.699999999999818
},
{
"name": "canvas-zoom-sweep",
"durationMs": 1710.5409999999779,
"styleRecalcs": 30,
"styleRecalcDurationMs": 10.073,
"layouts": 6,
"layoutDurationMs": 0.4189999999999999,
"taskDurationMs": 229.87099999999998,
"heapDeltaBytes": 2338504,
"heapUsedBytes": 63315948,
"domNodes": 77,
"jsHeapTotalBytes": 4456448,
"scriptDurationMs": 5.817000000000001,
"eventListeners": 19,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.666666666666668,
"p95FrameDurationMs": 16.699999999999818
},
{
"name": "canvas-zoom-sweep",
"durationMs": 1717.104000000063,
"styleRecalcs": 31,
"styleRecalcDurationMs": 9.988999999999999,
"layouts": 6,
"layoutDurationMs": 0.49700000000000005,
"taskDurationMs": 235.37199999999996,
"heapDeltaBytes": 2769484,
"heapUsedBytes": 63254708,
"domNodes": 76,
"jsHeapTotalBytes": 5242880,
"scriptDurationMs": 5.747999999999999,
"eventListeners": 21,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.666666666666668,
"p95FrameDurationMs": 16.700000000000728
},
{
"name": "dom-widget-clipping",
"durationMs": 393.7999999999988,
"styleRecalcs": 12,
"styleRecalcDurationMs": 4.659,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 223.68699999999998,
"heapDeltaBytes": 10024648,
"heapUsedBytes": 70839536,
"domNodes": 20,
"jsHeapTotalBytes": 4980736,
"scriptDurationMs": 30.102999999999998,
"eventListeners": 0,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.666666666666668,
"p95FrameDurationMs": 16.700000000000273
},
{
"name": "dom-widget-clipping",
"durationMs": 397.8620000000319,
"styleRecalcs": 12,
"styleRecalcDurationMs": 5.153,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 231.09000000000003,
"heapDeltaBytes": 9881304,
"heapUsedBytes": 70642992,
"domNodes": 20,
"jsHeapTotalBytes": 5242880,
"scriptDurationMs": 32.12,
"eventListeners": 2,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.666666666666668,
"p95FrameDurationMs": 16.700000000000273
},
{
"name": "large-graph-idle",
"durationMs": 2012.9489999999919,
"styleRecalcs": 10,
"styleRecalcDurationMs": 4.783,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 434.571,
"heapDeltaBytes": -8296988,
"heapUsedBytes": 65028356,
"domNodes": -280,
"jsHeapTotalBytes": -1314816,
"scriptDurationMs": 8.038,
"eventListeners": -179,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.666666666666668,
"p95FrameDurationMs": 16.699999999999818
},
{
"name": "large-graph-idle",
"durationMs": 2011.527000000001,
"styleRecalcs": 11,
"styleRecalcDurationMs": 7.266000000000002,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 423.89199999999994,
"heapDeltaBytes": 2118372,
"heapUsedBytes": 76314836,
"domNodes": -256,
"jsHeapTotalBytes": -1576960,
"scriptDurationMs": 6.804000000000001,
"eventListeners": -149,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.666666666666668,
"p95FrameDurationMs": 16.699999999999818
},
{
"name": "large-graph-pan",
"durationMs": 2071.341000000018,
"styleRecalcs": 69,
"styleRecalcDurationMs": 9.006,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 749.568,
"heapDeltaBytes": 539584,
"heapUsedBytes": 75472600,
"domNodes": -264,
"jsHeapTotalBytes": -1613824,
"scriptDurationMs": 197.03199999999998,
"eventListeners": -149,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.666666666666668,
"p95FrameDurationMs": 16.800000000000182
},
{
"name": "large-graph-pan",
"durationMs": 2050.9700000000066,
"styleRecalcs": 68,
"styleRecalcDurationMs": 7.418999999999999,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 701.93,
"heapDeltaBytes": 14080884,
"heapUsedBytes": 74860892,
"domNodes": -265,
"jsHeapTotalBytes": 225280,
"scriptDurationMs": 192.555,
"eventListeners": 4,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.660000000000007,
"p95FrameDurationMs": 16.700000000000728
},
{
"name": "large-graph-zoom",
"durationMs": 3083.7209999999686,
"styleRecalcs": 67,
"styleRecalcDurationMs": 9.589000000000002,
"layouts": 60,
"layoutDurationMs": 4.645,
"taskDurationMs": 819.572,
"heapDeltaBytes": 1414072,
"heapUsedBytes": 77555812,
"domNodes": -265,
"jsHeapTotalBytes": -1839104,
"scriptDurationMs": 211.156,
"eventListeners": -145,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.666666666666668,
"p95FrameDurationMs": 16.800000000000182
},
{
"name": "large-graph-zoom",
"durationMs": 3041.9239999999945,
"styleRecalcs": 65,
"styleRecalcDurationMs": 10.092,
"layouts": 60,
"layoutDurationMs": 5.64,
"taskDurationMs": 895.5569999999999,
"heapDeltaBytes": 15357824,
"heapUsedBytes": 77262552,
"domNodes": 12,
"jsHeapTotalBytes": 0,
"scriptDurationMs": 248.132,
"eventListeners": 6,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.666666666666668,
"p95FrameDurationMs": 16.800000000000182
},
{
"name": "legacy-node-drag",
"durationMs": 2057.1730000000343,
"styleRecalcs": 50,
"styleRecalcDurationMs": 7.219000000000001,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 853.163,
"heapDeltaBytes": 11386092,
"heapUsedBytes": 94118356,
"domNodes": 20,
"jsHeapTotalBytes": 7794688,
"scriptDurationMs": 257.60900000000004,
"eventListeners": 184,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.666666666666668,
"p95FrameDurationMs": 16.700000000000728
},
{
"name": "legacy-node-drag",
"durationMs": 2053.421000000071,
"styleRecalcs": 46,
"styleRecalcDurationMs": 4.923000000000002,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 865.9219999999999,
"heapDeltaBytes": 433312,
"heapUsedBytes": 62703524,
"domNodes": 12,
"jsHeapTotalBytes": 10747904,
"scriptDurationMs": 266.61400000000003,
"eventListeners": 184,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.66333333333332,
"p95FrameDurationMs": 16.700000000000728
},
{
"name": "minimap-idle",
"durationMs": 2028.7340000000427,
"styleRecalcs": 11,
"styleRecalcDurationMs": 5.325,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 427.44000000000005,
"heapDeltaBytes": -12247040,
"heapUsedBytes": 68551476,
"domNodes": -274,
"jsHeapTotalBytes": 3211264,
"scriptDurationMs": 8.884,
"eventListeners": -177,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.666666666666668,
"p95FrameDurationMs": 16.699999999999818
},
{
"name": "minimap-idle",
"durationMs": 2034.4689999999446,
"styleRecalcs": 9,
"styleRecalcDurationMs": 4.452000000000001,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 416.7939999999999,
"heapDeltaBytes": -12385224,
"heapUsedBytes": 68577336,
"domNodes": -280,
"jsHeapTotalBytes": 3211264,
"scriptDurationMs": 6.752999999999998,
"eventListeners": -149,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.666666666666668,
"p95FrameDurationMs": 16.799999999999272
},
{
"name": "subgraph-dom-widget-clipping",
"durationMs": 393.5290000000009,
"styleRecalcs": 48,
"styleRecalcDurationMs": 6.704,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 246.77500000000003,
"heapDeltaBytes": 10628648,
"heapUsedBytes": 71557424,
"domNodes": 22,
"jsHeapTotalBytes": 5242880,
"scriptDurationMs": 71.928,
"eventListeners": 8,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.663333333333338,
"p95FrameDurationMs": 16.700000000000273
},
{
"name": "subgraph-dom-widget-clipping",
"durationMs": 407.2279999999182,
"styleRecalcs": 49,
"styleRecalcDurationMs": 7.0089999999999995,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 239.46499999999997,
"heapDeltaBytes": 10588984,
"heapUsedBytes": 71537848,
"domNodes": 24,
"jsHeapTotalBytes": 5242880,
"scriptDurationMs": 65.011,
"eventListeners": 6,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.669999999999998,
"p95FrameDurationMs": 16.799999999999727
},
{
"name": "subgraph-idle",
"durationMs": 2001.4869999999974,
"styleRecalcs": 12,
"styleRecalcDurationMs": 5.217,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 343.25600000000003,
"heapDeltaBytes": 11696576,
"heapUsedBytes": 72608976,
"domNodes": -278,
"jsHeapTotalBytes": 3661824,
"scriptDurationMs": 4.685,
"eventListeners": -179,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.666666666666668,
"p95FrameDurationMs": 16.699999999999818
},
{
"name": "subgraph-idle",
"durationMs": 2002.1530000000212,
"styleRecalcs": 12,
"styleRecalcDurationMs": 6.697,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 352.777,
"heapDeltaBytes": 8737484,
"heapUsedBytes": 69796564,
"domNodes": -277,
"jsHeapTotalBytes": 4186112,
"scriptDurationMs": 4.628,
"eventListeners": -179,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.66333333333332,
"p95FrameDurationMs": 16.800000000000182
},
{
"name": "subgraph-mouse-sweep",
"durationMs": 1702.7879999999982,
"styleRecalcs": 78,
"styleRecalcDurationMs": 21.357,
"layouts": 16,
"layoutDurationMs": 2.4939999999999998,
"taskDurationMs": 544.42,
"heapDeltaBytes": 12119540,
"heapUsedBytes": 72992760,
"domNodes": -278,
"jsHeapTotalBytes": 4710400,
"scriptDurationMs": 48.244,
"eventListeners": -179,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.66333333333335,
"p95FrameDurationMs": 16.800000000000182
},
{
"name": "subgraph-mouse-sweep",
"durationMs": 1695.0489999999263,
"styleRecalcs": 75,
"styleRecalcDurationMs": 19.738,
"layouts": 16,
"layoutDurationMs": 2.237,
"taskDurationMs": 517.417,
"heapDeltaBytes": -2333496,
"heapUsedBytes": 58401888,
"domNodes": -280,
"jsHeapTotalBytes": 5496832,
"scriptDurationMs": 43.873999999999995,
"eventListeners": -149,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.666666666666668,
"p95FrameDurationMs": 16.699999999999818
},
{
"name": "subgraph-transition-enter",
"durationMs": 849.57600000007,
"styleRecalcs": 20,
"styleRecalcDurationMs": 20.299000000000003,
"layouts": 15,
"layoutDurationMs": 8.221,
"taskDurationMs": 613.0959999999999,
"heapDeltaBytes": -317208,
"heapUsedBytes": 96579560,
"domNodes": 13673,
"jsHeapTotalBytes": 11534336,
"scriptDurationMs": 10.324,
"eventListeners": 2373,
"totalBlockingTimeMs": 81,
"frameDurationMs": 16.666666666666668,
"p95FrameDurationMs": 16.700000000000728
},
{
"name": "viewport-pan-sweep",
"durationMs": 8080.444999999998,
"styleRecalcs": 251,
"styleRecalcDurationMs": 22.222,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 2556.5950000000003,
"heapDeltaBytes": 16172920,
"heapUsedBytes": 89320392,
"domNodes": -274,
"jsHeapTotalBytes": 4939776,
"scriptDurationMs": 589.129,
"eventListeners": -161,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.666666666666668,
"p95FrameDurationMs": 16.700000000000728
},
{
"name": "viewport-pan-sweep",
"durationMs": 8085.823000000005,
"styleRecalcs": 250,
"styleRecalcDurationMs": 20.409000000000002,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 2521.537,
"heapDeltaBytes": 8039948,
"heapUsedBytes": 82371020,
"domNodes": -262,
"jsHeapTotalBytes": -1351680,
"scriptDurationMs": 591.314,
"eventListeners": -133,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.66333333333332,
"p95FrameDurationMs": 16.700000000000728
},
{
"name": "vue-large-graph-idle",
"durationMs": 9555.520999999999,
"styleRecalcs": 0,
"styleRecalcDurationMs": 0,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 8586.233,
"heapDeltaBytes": -40734136,
"heapUsedBytes": 181315040,
"domNodes": -8312,
"jsHeapTotalBytes": -7544832,
"scriptDurationMs": 40.836,
"eventListeners": -16391,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.66333333333332,
"p95FrameDurationMs": 16.80000000000109
},
{
"name": "vue-large-graph-idle",
"durationMs": 10053.348000000027,
"styleRecalcs": 0,
"styleRecalcDurationMs": 0,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 8876.356999999998,
"heapDeltaBytes": -24559416,
"heapUsedBytes": 180822232,
"domNodes": -8312,
"jsHeapTotalBytes": -5443584,
"scriptDurationMs": 43.97300000000001,
"eventListeners": -16393,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.66333333333332,
"p95FrameDurationMs": 16.700000000000728
},
{
"name": "vue-large-graph-pan",
"durationMs": 11641.014999999981,
"styleRecalcs": 67,
"styleRecalcDurationMs": 11.50000000000001,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 10862.792000000001,
"heapDeltaBytes": -28604500,
"heapUsedBytes": 178563152,
"domNodes": -8312,
"jsHeapTotalBytes": -4395008,
"scriptDurationMs": 284.82,
"eventListeners": -16387,
"totalBlockingTimeMs": 2,
"frameDurationMs": 17.226666666666762,
"p95FrameDurationMs": 16.799999999999272
},
{
"name": "vue-large-graph-pan",
"durationMs": 12776.442999999972,
"styleRecalcs": 66,
"styleRecalcDurationMs": 12.557999999999986,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 11956.332,
"heapDeltaBytes": -10256788,
"heapUsedBytes": 195028488,
"domNodes": -8312,
"jsHeapTotalBytes": -8613888,
"scriptDurationMs": 359.71799999999996,
"eventListeners": -16387,
"totalBlockingTimeMs": 36,
"frameDurationMs": 17.776666666666763,
"p95FrameDurationMs": 16.799999999999272
},
{
"name": "workflow-execution",
"durationMs": 464.2830000000231,
"styleRecalcs": 18,
"styleRecalcDurationMs": 14.200000000000001,
"layouts": 3,
"layoutDurationMs": 1.199,
"taskDurationMs": 109.057,
"heapDeltaBytes": 5245708,
"heapUsedBytes": 65856248,
"domNodes": 148,
"jsHeapTotalBytes": 262144,
"scriptDurationMs": 7.693000000000001,
"eventListeners": 99,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.666666666666668,
"p95FrameDurationMs": 16.700000000000273
},
{
"name": "workflow-execution",
"durationMs": 436.219000000051,
"styleRecalcs": 15,
"styleRecalcDurationMs": 11.913,
"layouts": 2,
"layoutDurationMs": 0.3039999999999999,
"taskDurationMs": 76.209,
"heapDeltaBytes": 4979576,
"heapUsedBytes": 66304924,
"domNodes": 125,
"jsHeapTotalBytes": 262144,
"scriptDurationMs": 5.741000000000001,
"eventListeners": 97,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.66333333333332,
"p95FrameDurationMs": 16.700000000000273
}
]
} |
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: ASSERTIVE Plan: Pro Plus Run ID: 📒 Files selected for processing (2)
Included review availability: Your plan includes up to 4 reviews per rolling hour; 0 remain after this review. 📝 WalkthroughWalkthroughNode replacement now removes resolved missing-node types from both workflow pending warnings and the rendered missing-node store. Shared utilities provide deduplication and removal by type, node ID, and execution-ID prefix. ChangesMissing-node warning synchronization
Estimated code review effort: 3 (Moderate) | ~25 minutes Merge Risk: ⚪ Minimal · up to The PR localizes missing-node replacement updates to the workflow warning cache while preserving the no-workflow fallback, with no actionable merge-blocking risk remaining after normal checks and review. Sequence Diagram(s)sequenceDiagram
participant NodeReplacement
participant PendingWarnings
participant WorkflowService
participant MissingNodesErrorStore
NodeReplacement->>PendingWarnings: remove replaced missing-node types
NodeReplacement->>WorkflowService: refresh pending warnings
WorkflowService->>MissingNodesErrorStore: synchronize rendered warning state
NodeReplacement->>MissingNodesErrorStore: fallback without an active workflow
Possibly related PRs
Suggested reviewers: Important Pre-merge checks failedPlease resolve all errors before merging. Addressing warnings is optional. ❌ Failed checks (1 inconclusive)
✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 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: 4
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/platform/nodeReplacement/useNodeReplacement.test.ts`:
- Around line 10-20: Update the vi.mock factory around importOriginal to use
typeof import('`@/lib/litegraph/src/litegraph`') as its generic module type, then
remove the Record<string, unknown> and LiteGraph type assertions while
preserving the existing mocked createNode and registered_node_types overrides.
- Around line 48-62: Define a named type for the active workflow mock, including
pendingWarnings and changeTracker, and use it to type activeWorkflow as that
type or null. Initialize activeWorkflow as null in the vi.hoisted mock; keep the
existing beforeEach population behavior unchanged and remove the duplicated
inline type assertion.
In `@src/platform/nodeReplacement/useNodeReplacement.ts`:
- Around line 234-248: Add a regression test for removeReplacedMissingNodeTypes
that initializes an active workflow with exactly one missing node type, removes
that type, and verifies showPendingWarnings is called synchronously with the
updated workflow and { silent: true }, including the empty missing-node result.
Ensure the test covers the pendingWarnings-null path where
surfaceMissingNodes([]) is invoked.
In `@src/platform/workflow/core/utils/pendingWarnings.ts`:
- Around line 16-26: Update dedupeMissingNodeTypes to replace the manual
Set/filter deduplication with es-toolkit’s uniqBy, returning uniqBy(types,
getMissingNodeKey) so the first item for each key is preserved.
🪄 Autofix
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: ASSERTIVE
Plan: Pro Plus
Run ID: e12684f3-e8ce-42c4-ba37-6f57599ff72e
📒 Files selected for processing (6)
src/platform/nodeReplacement/missingNodesErrorStore.test.tssrc/platform/nodeReplacement/missingNodesErrorStore.tssrc/platform/nodeReplacement/useNodeReplacement.test.tssrc/platform/nodeReplacement/useNodeReplacement.tssrc/platform/workflow/core/utils/pendingWarnings.test.tssrc/platform/workflow/core/utils/pendingWarnings.ts
Codecov Report✅ All modified and coverable lines are covered by tests. @@ Coverage Diff @@
## main #15141 +/- ##
==========================================
- Coverage 81.35% 80.69% -0.67%
==========================================
Files 1882 1882
Lines 107949 111775 +3826
Branches 33953 34520 +567
==========================================
+ Hits 87822 90192 +2370
- Misses 19748 21139 +1391
- Partials 379 444 +65
Flags with carried forward coverage won't be shown. Click here to find out more.
... and 102 files with indirect coverage changes 🚀 New features to boost your workflow:
|
Re-projecting the cache into the store wiped entries that were surfaced outside the load path (missing_node_type rescan writes the store only), so replacing one type could erase every other still-missing row.
|
Follow-ups from the importer-contract RFC review, now open alongside this PR:
All are independent of this PR and of each other. |
ELI5
Replacing a missing node now updates the same per-workflow warnings cache that tab switching restores from, so a replacement can no longer silently disagree with what the Errors panel shows after switching tabs.
Motivation
#14653 — the node-replacement path wrote the missing-node display store directly, while other producers write
workflow.pendingWarningsand letshowPendingWarnings()project it. The two agree only because of the current read path. An earlier draft of this PR also migrated the live hooks and the queue-error rescan to cache-first; an adversarial review round showed that collides with two lifecycle windows (graph teardown firesonNodeRemovedfor every node while the outgoing workflow is still active; several producers can run with no active workflow), so the scope retreated to the issue's own suggested fix: the replacement path only.Provenance
interactive sessionpnpm test:unit(15,935 passed; 12 pre-existing host-only bash-3.2 failures inscripts/cicdreproduced identically on the unchanged baseline);pnpm typecheck,pnpm lint,pnpm knip,pnpm format:checkpassed. Coverage proof: reverting the cache write fails the replacement-path test.Summary
pendingWarningsgains pure missing-node helpers (dedupeMissingNodeTypes, remove by type/nodeId/prefix) shared with the display store, so dedup semantics cannot drift — and fixes a latentstring | numbernodeId strict-comparison bug the old store mutator carried.pendingWarningsand re-projects silently; with no active workflow it falls back to the store, so behavior is never worse than before.Not in scope
True single-writer requires migrating the model/media candidates off store-first writes and a teardown-safe hook design first; deferred deliberately (tracked as an RFC follow-up), not forgotten.
Review Focus
The null-workflow fallback in the replacement path, and helper-vs-deleted-store-mutator semantics parity in
pendingWarnings.ts.Test plan
Fixes #14653