@@ -9,7 +9,7 @@ import type {
99 ICustomWidget ,
1010 CanvasPointerEvent ,
1111} from "@comfyorg/frontend" ;
12- import type { ComfyNodeDef } from "typings/comfy.js" ;
12+ import type { ComfyApiFormat , ComfyNodeDef } from "typings/comfy.js" ;
1313import type { RgthreeModelInfo } from "typings/rgthree.js" ;
1414
1515import { app } from "scripts/app.js" ;
@@ -74,17 +74,56 @@ class RgthreePowerLoraLoader extends RgthreeBaseServerNode {
7474
7575 // Prefetch loras list.
7676 rgthreeApi . getLoras ( ) ;
77+
78+ // [🤮] If ComfyUI is loading from API JSON it doesn't pass us the actual information at all
79+ // (like, in a `configure` call) and tries to set the widget data on its own. Unfortunately,
80+ // since Power Lora Loader has dynamic widgets, this fails on ComfyUI's side. We can do so after
81+ // the fact but, unfortuntely, we need to do it after a timeout since we don't have any
82+ // information at this point to be able to tell what data we need (like, even the node id, let
83+ // alone the actual data).
84+ if ( rgthree . loadingApiJson ) {
85+ const fullApiJson = rgthree . loadingApiJson ;
86+ setTimeout ( ( ) => {
87+ this . configureFromApiJson ( fullApiJson ) ;
88+ } , 16 ) ;
89+ }
90+ }
91+
92+ private configureFromApiJson ( fullApiJson : ComfyApiFormat ) {
93+ if ( this . id == null ) {
94+ const [ n , v ] = this . logger . errorParts ( "Cannot load from API JSON without node id." ) ;
95+ console [ n ] ?.( ...v ) ;
96+ return ;
97+ }
98+ const nodeData =
99+ fullApiJson [ this . id ] || fullApiJson [ String ( this . id ) ] || fullApiJson [ Number ( this . id ) ] ;
100+ if ( nodeData == null ) {
101+ const [ n , v ] = this . logger . errorParts ( `No node found in API JSON for node id ${ this . id } .` ) ;
102+ console [ n ] ?.( ...v ) ;
103+ return ;
104+ }
105+ this . configure ( {
106+ widgets_values : Object . values ( nodeData . inputs ) . filter (
107+ ( input ) => typeof ( input as any ) ?. [ "lora" ] === "string" ,
108+ ) ,
109+ } ) ;
77110 }
78111
79112 /**
80113 * Handles configuration from a saved workflow by first removing our default widgets that were
81114 * added in `onNodeCreated`, letting `super.configure` and do nothing, then create our lora
82115 * widgets and, finally, add back in our default widgets.
83116 */
84- override configure ( info : ISerialisedNode ) : void {
117+ override configure (
118+ info : ISerialisedNode | { widgets_values : ISerialisedNode [ "widgets_values" ] } ,
119+ ) : void {
85120 while ( this . widgets ?. length ) this . removeWidget ( 0 ) ;
86121 this . widgetButtonSpacer = null ;
87- super . configure ( info ) ;
122+ // Since we may be calling into configure manually for just widgets_values setting (like, from
123+ // API JSON) we want to only call the parent class's configure with a real ISerialisedNode data.
124+ if ( ( info as ISerialisedNode ) . id != null ) {
125+ super . configure ( info as ISerialisedNode ) ;
126+ }
88127
89128 ( this as any ) . _tempWidth = this . size [ 0 ] ;
90129 ( this as any ) . _tempHeight = this . size [ 1 ] ;
0 commit comments