@stable-canvas/comfyui-client
Version:
api Client for ComfyUI that supports both NodeJS and Browser environments. It provides full support for all RESTful / WebSocket APIs.
3 lines (2 loc) • 35.5 kB
JavaScript
function t(){return t=Object.assign?Object.assign.bind():function(t){for(var e=1;e<arguments.length;e++){var s=arguments[e];for(var n in s)({}).hasOwnProperty.call(s,n)&&(t[n]=s[n])}return t},t.apply(null,arguments)}var e,s,n=(e=function(t){var e=Object.prototype.hasOwnProperty,s="~";function n(){}function i(t,e,s){this.fn=t,this.context=e,this.once=s||!1}function r(t,e,n,r,o){if("function"!=typeof n)throw new TypeError("The listener must be a function");var a=new i(n,r||t,o),c=s?s+e:e;return t._events[c]?t._events[c].fn?t._events[c]=[t._events[c],a]:t._events[c].push(a):(t._events[c]=a,t._eventsCount++),t}function o(t,e){0===--t._eventsCount?t._events=new n:delete t._events[e]}function a(){this._events=new n,this._eventsCount=0}Object.create&&(n.prototype=Object.create(null),(new n).__proto__||(s=!1)),a.prototype.eventNames=function(){var t,n,i=[];if(0===this._eventsCount)return i;for(n in t=this._events)e.call(t,n)&&i.push(s?n.slice(1):n);return Object.getOwnPropertySymbols?i.concat(Object.getOwnPropertySymbols(t)):i},a.prototype.listeners=function(t){var e=this._events[s?s+t:t];if(!e)return[];if(e.fn)return[e.fn];for(var n=0,i=e.length,r=new Array(i);n<i;n++)r[n]=e[n].fn;return r},a.prototype.listenerCount=function(t){var e=this._events[s?s+t:t];return e?e.fn?1:e.length:0},a.prototype.emit=function(t,e,n,i,r,o){var a=s?s+t:t;if(!this._events[a])return!1;var c,l,u=this._events[a],d=arguments.length;if(u.fn){switch(u.once&&this.removeListener(t,u.fn,void 0,!0),d){case 1:return u.fn.call(u.context),!0;case 2:return u.fn.call(u.context,e),!0;case 3:return u.fn.call(u.context,e,n),!0;case 4:return u.fn.call(u.context,e,n,i),!0;case 5:return u.fn.call(u.context,e,n,i,r),!0;case 6:return u.fn.call(u.context,e,n,i,r,o),!0}for(l=1,c=new Array(d-1);l<d;l++)c[l-1]=arguments[l];u.fn.apply(u.context,c)}else{var h,p=u.length;for(l=0;l<p;l++)switch(u[l].once&&this.removeListener(t,u[l].fn,void 0,!0),d){case 1:u[l].fn.call(u[l].context);break;case 2:u[l].fn.call(u[l].context,e);break;case 3:u[l].fn.call(u[l].context,e,n);break;case 4:u[l].fn.call(u[l].context,e,n,i);break;default:if(!c)for(h=1,c=new Array(d-1);h<d;h++)c[h-1]=arguments[h];u[l].fn.apply(u[l].context,c)}}return!0},a.prototype.on=function(t,e,s){return r(this,t,e,s,!1)},a.prototype.once=function(t,e,s){return r(this,t,e,s,!0)},a.prototype.removeListener=function(t,e,n,i){var r=s?s+t:t;if(!this._events[r])return this;if(!e)return o(this,r),this;var a=this._events[r];if(a.fn)a.fn!==e||i&&!a.once||n&&a.context!==n||o(this,r);else{for(var c=0,l=[],u=a.length;c<u;c++)(a[c].fn!==e||i&&!a[c].once||n&&a[c].context!==n)&&l.push(a[c]);l.length?this._events[r]=1===l.length?l[0]:l:o(this,r)}return this},a.prototype.removeAllListeners=function(t){var e;return t?this._events[e=s?s+t:t]&&o(this,e):(this._events=new n,this._eventsCount=0),this},a.prototype.off=a.prototype.removeListener,a.prototype.addListener=a.prototype.on,a.prefixed=s,a.EventEmitter=a,t.exports=a},e(s={exports:{}}),s.exports);const i=t=>null==t;class r extends Error{constructor(t){super(t)}}class o extends r{constructor(t,e){super(`Prompt ${t} timed out after ${e} ms`)}}class a extends r{constructor(t){var e;const{error:s,node_errors:n}=t;super(`Failed to enqueue prompt: ${"string"==typeof s?s:null==(e=s.errors)?void 0:e[0].message}, details: ${n?JSON.stringify(n):""}`)}}class c extends r{constructor(t){super(`Client enqueue error: ${t}`)}}class l extends r{constructor(t){super(`Prompt [${t}] not found in history`)}}class u extends r{constructor(t){super(`Task data type error, please try updating comfyui version: ${JSON.stringify(t)}`)}}class d extends r{constructor(t,e){super(`Prompt ${t} execution failed with status: ${e}`)}}class h extends r{constructor(t){super(`Client request error: ${t}`)}}class p extends r{constructor(t){super(`Polling timed out after ${t} ms`)}}class _ extends r{constructor(t){super(`WebSocket timed out after ${t} ms`)}}class m extends r{constructor(t){super(`Connect error: ${t}`)}}class w extends r{constructor(t){super(`WebSocket parse error: ${t}`)}}class g extends Error{constructor(t,e,s){super(t),this.status=void 0,this.json=void 0,this.name="HttpError",this.status=e,this.json=s}}class f{static readBinaryData(t){const e=new DataView(t),s=e.getUint32(0),n=e.getUint32(1);switch(s){case 3:{const s=new TextDecoder,n=t.slice(4),i=e.getUint32(4);return[{type:"progress_text",data:{nodeId:s.decode(n.slice(4,4+i)),text:s.decode(n.slice(4+i))}}]}case 1:{const e={1:"image/jpeg",2:"image/png"}[n]||"image/png",s=t.slice(8);return[{type:"b_preview",data:new Blob([s],{type:e})}]}case 4:{const s=new TextDecoder,n=e.getUint32(4),i=t.slice(8,8+n),r=JSON.parse(s.decode(i)),o=t.slice(8+n),a=new Blob([o],{type:r.image_type});return[{type:"b_preview_with_metadata",data:{blob:a,nodeId:r.node_id,displayNodeId:r.display_node_id,parentNodeId:r.parent_node_id,realNodeId:r.real_node_id,promptId:r.prompt_id}},{type:"b_preview",data:a}]}default:throw new w(`Unknown binary websocket message of type ${s}`)}}get registered(){return this.events.eventNames()}constructor(t){var e,s,i,r,o,a,c;if(this.api_host=void 0,this.api_base=void 0,this.clientId=void 0,this.socket=void 0,this.WebSocket=void 0,this.ssl=void 0,this.user=void 0,this.fetch=void 0,this.events=new n,this.socket_callbacks={},this._polling_timer=null,this._polling_interval=1e3,this.closed=!1,this.api_host=null!=(e=t.api_host)?e:f.DEFAULT_API_HOST,this.api_base=null!=(s=t.api_base)?s:f.DEFAULT_API_BASE,this.clientId=null!=(i=t.clientId)?i:"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,t=>{const e=16*Math.random()|0;return("x"===t?e:3&e|8).toString(16)}),this.WebSocket=null!=(r=t.WebSocket)?r:globalThis.WebSocket,this.ssl=null!=(o=t.ssl)&&o,this.user=null!=(a=t.user)?a:f.DEFAULT_USER,!globalThis.fetch)throw new m("fetch is not defined");this.fetch=null!=(c=t.fetch)?c:globalThis.fetch.bind(globalThis),this.WebSocket||console.warn("No WebSocket implementation available, WebSocket disabled")}apiHeaders(e){var s;return t({},this.user?{"Comfy-User":this.user}:{},{Accept:"*/*"},null!=(s=null==e?void 0:e.headers)?s:{})}apiURL(t){const e=new URL(`http${this.ssl?"s":""}://${this.api_host}`);let[s,n]=(this.api_base+t).split("?");return e.pathname=s,e.pathname=e.pathname.replace(/\/+/g,"/"),n&&(e.search=n),this.clientId&&e.searchParams.set("clientId",this.clientId),e.toString()}internalURL(t){return this.apiURL(`/internal${t}`)}viewURL(t,e,s){const n=new URLSearchParams({filename:t,subfolder:e,type:s}).toString();return`http${this.ssl?"s":""}://${this.api_host}${this.api_base}/view?${n}`}wsURL(){const t=new URL(`ws${this.ssl?"s":""}://${this.api_host}`);return t.pathname="/ws",this.clientId&&t.searchParams.set("clientId",this.clientId),t.toString()}async fetchApi(e,s){const n=this.apiURL(e),i=await this.fetch(n,t({},s,{headers:this.apiHeaders(s)})),{status:r,statusText:o}=i;if(r<200||r>=400)throw new g(`Endpoint Bad Request (${r} ${o}): ${n}`,r,await i.json());return i}addEventListener(t,e,s){return this.events.on(t,e,s),()=>{this.events.off(t,e)}}on(t,e,s){return this.addEventListener(t,e,s)}once(t,e,s){return this.events.once(t,e,s),()=>{this.events.off(t,e)}}startPollingQueue(){var t=this;this._polling_timer||(this._polling_timer=setInterval(async function(){try{const e=await t.fetchApi("/prompt"),s=await e.json();t.events.emit("status",s)}catch(e){t.events.emit("status",null)}},this._polling_interval))}addSocketCallback(t,e,s,n){return this.socket_callbacks[e]=s,t.addEventListener(e,s,n),()=>{delete this.socket_callbacks[e],t.removeEventListener(e,s,n)}}removeSocketCallbacks(){if(this.socket)for(const t in this.socket_callbacks)this.socket.removeEventListener(t,this.socket_callbacks[t]);this.socket_callbacks={}}createSocket(t=!1){var e=this;if(this.socket)return;if(!this.WebSocket)throw new m("WebSocket is not defined, please provide a WebSocket implementation");if(this.closed)return;let s=!1;this.socket=new this.WebSocket(this.wsURL()),this.socket.binaryType="arraybuffer",this.addSocketCallback(this.socket,"open",()=>{s=!0,this.events.emit(t?"reconnected":"connected")}),this.addSocketCallback(this.socket,"error",e=>{var n;const i=e,r=null==(n=i.message)?void 0:n.includes("404");this.events.emit("connection_error",{type:"404",message:i.message}),this.socket&&this.socket.close(),r||t||s||this.startPollingQueue()}),this.addSocketCallback(this.socket,"close",()=>{setTimeout(()=>{this.socket=null,this.createSocket(!0)},300),s&&(this.events.emit("status",null),this.events.emit("reconnecting"))}),this.addSocketCallback(this.socket,"message",async function(t){if(e.events.emit("message",t),(t=>!("string"==typeof t.data||!(ArrayBuffer&&t.data instanceof ArrayBuffer||Buffer&&Buffer.isBuffer(t.data))))(t)){const s=f.readBinaryData(t.data);for(const t of s)switch(t.type){case"b_preview":e.events.emit("b_preview",t.data),e.events.emit("image_data",{image:await t.data.arrayBuffer(),mime:t.data.type});break;case"b_preview_with_metadata":e.events.emit("b_preview_with_metadata",t.data),e.events.emit("image_data",{image:await t.data.blob.arrayBuffer(),mime:t.data.blob.type});break;case"progress_text":e.events.emit("progress_text",t.data);break;default:return}}else{const s=JSON.parse(t.data);switch(s.type){case"status":s.data.sid&&(e.clientId=s.data.sid),e.events.emit("status",s.data.status);break;case"progress":e.events.emit("progress",s.data);break;case"executing":e.events.emit("executing",s.data);break;case"executed":e.events.emit("executed",s.data);break;case"execution_start":e.events.emit("execution_start",s.data);break;case"execution_error":e.events.emit("execution_error",s.data);break;case"execution_cached":e.events.emit("execution_cached",s.data);break;case"execution_interrupted":e.events.emit("execution_interrupted",s.data);break;default:e.events.emit(s.type,s.data)}"message"!==s.type&&!1===e.registered.includes(s.type)&&e.events.emit("unhandled",s)}})}init(){this.createSocket()}close(){this.closed||(this.closed=!0,this.events.emit("close"),this.disconnect(),this.events.removeAllListeners())}connect({polling:t={enabled:!1},websocket:e={enabled:!0},timeout_ms:s=15e3}={}){var n,i=this;if(null!=t&&t.enabled)return this._polling_interval=null!=(n=t.interval)?n:this._polling_interval,this.startPollingQueue(),new Promise(async function(t,e){const n=setTimeout(()=>{e(new p(s))},s),r=await i.fetchApi("/system_stats");t(r.ok&&200===r.status),clearTimeout(n)});if(null!=e&&e.enabled)return this.createSocket(),new Promise((t,e)=>{const n=setTimeout(()=>{e(new _(s))},s);this.once("connected",()=>{t(!0),clearTimeout(n)})});throw new m("You must enable either polling or websocket")}disconnect(){this.socket?this._disconnectSocket():process.nextTick(this._disconnectPolling.bind(this)),this._disconnectPolling()}_disconnectSocket(){const{socket:t}=this;if(t){this.socket=null;try{t.readyState===t.OPEN&&t.close(1e3,"Client closed")}catch(t){}this.removeSocketCallbacks(),"removeAllListeners"in t&&(null==t.removeAllListeners||t.removeAllListeners())}}_disconnectPolling(){null!==this._polling_timer&&(clearInterval(this._polling_timer),this._polling_timer=null)}}f.DEFAULT_API_HOST="127.0.0.1:8188",f.DEFAULT_API_BASE="",f.DEFAULT_USER="",f.IS_BROWSER="undefined"!=typeof window;const v={image:(e,s,{client:n})=>{if(null==s)return e;const r=((null==s?void 0:s.images)||[]).map(t=>{const{filename:e,subfolder:s,type:r}=t;return i(e)||i(s)||!["output","temp"].includes(r)?null:n.viewURL(e,s,r)}).filter(Boolean).map(t=>({type:"url",data:t}));return t({},e,{images:[...e.images,...r]})}};var k={__proto__:null,RESOLVERS:v};class y extends Error{constructor(t,e,s,n){super(t),this.task_id=void 0,this.workflow=void 0,this.invoked=void 0,this.task_id=e,this.workflow=s,this.invoked=n}}class b extends y{constructor(t,e,s,n){const{exception_message:i,exception_type:r}=t;super(`Execution error: ${i} (${r})`,e,s,n),this.payload=void 0,this.payload=t}}class x extends Error{constructor(t,e){super(`Client connection error (${t}): ${e}`)}}class S extends Error{constructor(t,e){super(t),this.invoked=void 0,this.workflow=void 0,this.invoked=e,this.workflow=e.workflow}}class P extends S{constructor(t){super("This workflow is already enqueued",t)}}class E extends S{constructor(t){super("This workflow is not enqueued and the execution status cannot be interrupted",t)}}class A extends S{constructor(t){const{is_done:e}=t;super(e?"This workflow has already finished":"This workflow has been disposed",t)}}class L extends S{constructor(t){super("WebSocket is not connected",t)}}class C extends S{constructor(t){const{task_id:e}=t;super(e?`Cannot get task status for task ${e}`:"Cannot get task status",t)}}class N extends S{constructor(t){super("Execution has been interrupted",t)}}class T extends S{constructor(t,e){super(e,t)}}class ${constructor(){this._disposed=!1,this._disposed_cbs=[]}dispose(){this._disposed||(this._disposed=!0,this._disposed_cbs.forEach(t=>{"function"==typeof t&&t()}))}_connect(t){this._disposed?t():this._disposed_cbs.push(t)}}class O extends f{constructor(t){super(t),this._plugins=[]}use(t){t.install(this),this._plugins.push(t)}async getExtensions(){var t=this;return async function(){const e=await t.fetchApi("/extensions",{cache:"no-store"});return await e.json()}()}async getEmbeddings(){var t=this;return async function(){const e=await t.fetchApi("/embeddings",{cache:"no-store"});return await e.json()}()}async getNodeDefs(){var t=this;return async function(){const e=await t.fetchApi("/object_info",{cache:"no-store"});return await e.json()}()}async queuePrompt(t,{prompt:e,workflow:s}){const n={client_id:this.clientId,prompt:e,extra_data:{extra_pnginfo:{workflow:s}}};-1===t?n.front=!0:0!==t&&(n.number=t);const i=await this.fetchApi("/prompt",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(n)});if(200!==i.status){const t=await i.text();try{const e=JSON.parse(t);throw new a(e)}catch(e){throw new a({error:t,node_errors:{}})}}return await i.json()}async getItems(t){return"queue"===t?this.getQueue():this.getHistory()}async getQueue(){try{const t=await this.fetchApi("/queue"),e=await t.json();return{Running:e.queue_running,Pending:e.queue_pending}}catch(t){return console.error(t),{Running:[],Pending:[]}}}async getHistory(t=200,e){const{offset:s}=e||{};if(void 0!==s&&(s<0||!Number.isInteger(s)))throw new Error(`Invalid offset parameter: ${s}. Must be a non-negative integer.`);const n=new URLSearchParams({max_items:t.toString()});void 0!==s&&n.set("offset",s.toString());try{const t=await this.fetchApi(`/history?${n.toString()}`);return{History:Object.values(await t.json())}}catch(t){return console.error(t),{History:[]}}}async getSystemStats(){return(await this.fetchApi("/system_stats")).json()}async postApi(t,e){await this.fetchApi("/"+t,{method:"POST",headers:{"Content-Type":"application/json"},body:e?JSON.stringify(e):void 0})}async deleteItem(t,e){await this.postApi(t,{delete:[e]})}async clearItems(t){await this.postApi(t,{clear:!0})}async interrupt(t=null){await this.postApi("interrupt",t?{prompt_id:t}:void 0)}async free(t){await this.postApi("free",t)}async getUserConfig(){return(await this.fetchApi("/users")).json()}async createUser(t){return this.fetchApi("/users",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({username:t})})}async getSettings(){return(await this.fetchApi("/settings")).json()}async getSetting(t){return(await this.fetchApi(`/settings/${encodeURIComponent(t)}`)).json()}async storeSettings(t){return this.fetchApi("/settings",{method:"POST",body:JSON.stringify(t)})}async storeSetting(t,e){return this.fetchApi(`/settings/${encodeURIComponent(t)}`,{method:"POST",body:JSON.stringify(e)})}async getUserData(t,e){return this.fetchApi(`/userdata/${encodeURIComponent(t)}`,e)}async storeUserData(e,s,n){const i=await this.fetchApi(`/userdata/${encodeURIComponent(e)}`,t({method:"POST",body:null!=n&&n.stringify?JSON.stringify(s):s},n));if(200!==i.status){const t=await i.text();throw new h(`Error storing user data file '${e}': ${i.status} ${t}`)}}async getModelFolders(){const t=await this.fetchApi("/experiment/models");if(404===t.status)return[];const e=["configs","custom_nodes"];return(await t.json()).filter(t=>!e.includes(t.name))}async getModels(t){const e=await this.fetchApi(`/experiment/models/${t}`);return 404===e.status?[]:await e.json()}async viewMetadata(t,e){const s=await this.fetchApi(`/view_metadata/${t}?filename=${encodeURIComponent(e)}`),n=await s.text();if(!n)return null;try{return JSON.parse(n)}catch(t){return console.error("Error viewing metadata",s.status,s.statusText,n,t),null}}async getLogs(){const t=await this.fetchApi(this.internalURL("/logs"));return await t.json()}async getRawLogs(){const t=await this.fetchApi(this.internalURL("/logs/raw"));return await t.json()}async getSamplers(){var t;const e=(await this.getNodeDefs()).KSampler;return(null==e||null==(t=e.input)||null==(t=t.required)||null==(t=t.sampler_name)?void 0:t[0])||[]}async getSchedulers(){var t;const e=(await this.getNodeDefs()).KSampler;return(null==e||null==(t=e.input)||null==(t=t.required)||null==(t=t.scheduler)?void 0:t[0])||[]}async getSDModels(){var t;const e=(await this.getNodeDefs()).CheckpointLoaderSimple;return(null==e||null==(t=e.input)||null==(t=t.required)||null==(t=t.ckpt_name)?void 0:t[0])||[]}async getCNetModels(){var t;const e=(await this.getNodeDefs()).ControlNetLoader;return(null==e||null==(t=e.input)||null==(t=t.required)||null==(t=t.control_net_name)?void 0:t[0])||[]}async getUpscaleModels(){var t;const e=(await this.getNodeDefs()).UpscaleModelLoader;return(null==e||null==(t=e.input)||null==(t=t.required)||null==(t=t.model_name)?void 0:t[0])||[]}async getHyperNetworks(){var t;const e=(await this.getNodeDefs()).HypernetworkLoader;return(null==e||null==(t=e.input)||null==(t=t.required)||null==(t=t.hypernetwork_name)?void 0:t[0])||[]}async getLoRAs(){var t;const e=(await this.getNodeDefs()).LoraLoader;return(null==e||null==(t=e.input)||null==(t=t.required)||null==(t=t.lora_name)?void 0:t[0])||[]}async getVAEs(){var t;const e=(await this.getNodeDefs()).VAELoader;return(null==e||null==(t=e.input)||null==(t=t.required)||null==(t=t.vae_name)?void 0:t[0])||[]}async getPromptStatus(t){const{Running:e,Pending:s}=await this.getQueue(),n=t=>{var e;if(!t)return null;if("prompt"in t)return null==(e=t.prompt)?void 0:e[1];if(Array.isArray(t))return t[1];throw new u(t)},i=e.some(e=>n(e)===t),r=s.some(e=>n(e)===t);return{running:i,pending:r,done:!i&&!r}}async getPromptOutputs(t){var e,s;const{History:n}=await this.getHistory(),i=n.find(e=>e.prompt[1]===t);if(!i)throw new l(t);const r=null!=(e=null==(s=i.status)?void 0:s.status_str)?e:"error";if("error"===r)throw new d(t,null!=r?r:"error");return i.outputs}async getPromptResult(t,e){const s=await this.getPromptOutputs(t);return"function"!=typeof e&&(e=v.image),Object.entries(s).reduce((s,[n,i])=>e(s,i,{client:this,prompt_id:t,node_id:n}),{images:[],prompt_id:t,data:null})}async waitForPrompt(t,e=1e3,s=3e5){const n=Date.now();let i=await this.getPromptStatus(t);for(;!i.done;){if(s>=0&&Date.now()-n>s)throw new o(t,s);await new Promise(t=>setTimeout(t,e)),i=await this.getPromptStatus(t)}}async waitForPromptWebSocket(t,e,s=3e5){const n={images:[],prompt_id:t,data:null},i=new $;return new Promise((r,a)=>{let c=!1;i._connect(this.on("executing",e=>{c=(null==e?void 0:e.prompt_id)===t})),i._connect(this.on("image_data",t=>{c&&n.images.push({type:"buff",data:t.image,mime:t.mime})})),i._connect(this.on("executed",s=>{const{prompt_id:i,output:o,node:a}=s;if(i!==t)return;const c=e(n,o,{client:this,prompt_id:t,node_id:a});r(c)})),i._connect(this.on("execution_error",e=>{a(new b(e,t))}));const l=setTimeout(()=>{a(new o(t,s))},s);i._connect(()=>clearTimeout(l))}).finally(()=>{i.dispose()})}async _enqueue_prompt(t,e){const s=await this.queuePrompt(0,{prompt:t,workflow:null==e?void 0:e.workflow});if("error"in s)throw new a(s);return s}async runPrompt(t,e){const s=(await this._enqueue_prompt(t,e)).prompt_id;return await this.waitForPrompt(s,null==e?void 0:e.polling_ms,null==e?void 0:e.timeout_ms),await this.getPromptResult(s,v.image)}async enqueue_polling(t,e){var s;if("function"==typeof(null==e?void 0:e.progress))throw new c("progress option is not supported in polling mode");const n=(await this._enqueue_prompt(t,e)).prompt_id;return await this.waitForPrompt(n,null==e?void 0:e.polling_ms,null==e?void 0:e.timeout_ms),await this.getPromptResult(n,null!=(s=null==e?void 0:e.resolver)?s:v.image)}async enqueue(t,e){const s=(await this._enqueue_prompt(t,e)).prompt_id,n=this.on_progress(null==e?void 0:e.progress,s);try{var i;return await this.waitForPromptWebSocket(s,null!=(i=null==e?void 0:e.resolver)?i:v.image,null==e?void 0:e.timeout_ms)}finally{n()}}on_progress(e,s){return e?this.on("progress",n=>{const i=t({},"progress"in n?t({},n.progress):{},n);i.prompt_id===s&&e(i)}):()=>{}}}class I extends ${constructor(t){super(),this.options=void 0,this._task_id=void 0,this._result={images:[],prompt_id:""},this.is_done=!1,this.enqueued=!1,this.workflow=void 0,this.client=void 0,this.resolver=void 0,this.delay_done_ms=500,this.is_current_ws_executing=!1,this.options=t;const{workflow:e,client:s,resolver:n}=t;this.workflow=e,this.client=s,this.resolver=n||v.image}get is_disposed(){return this._disposed}get task_id(){return this._task_id}_enqueue_guard(){if(this.enqueued)throw new P(this);this.enqueued=!0}_task_id_guard(){if(!this._task_id)throw new E(this);return this._task_id}_done_guard(){if(this._disposed||this.is_done)throw new A(this)}_ws_guard(){if(this.client.closed)throw new m("The WebSocket connection has been closed. Please ensure that the client is connected.");if(null===this.client.socket)throw new L(this)}is_owner_event(...t){const[e]=t||[],{_task_id:s}=this;return!!s&&"object"==typeof e&&null!==e&&"prompt_id"in e&&e.prompt_id===s}on(t,e,s){this._done_guard();const{client:n}=this,i=n.on(t,(...s)=>{if("image_data"===t||"b_preview"===t){if(!this.is_current_ws_executing)return}else if(!this.is_owner_event(...s))return;e(...s)});return this._connect(i),i}once(t,e,s){this._done_guard();const{client:n}=this,i=n.on(t,(...s)=>{if("image_data"===t||"b_preview"===t){if(!this.is_current_ws_executing)return}else if(!this.is_owner_event(...s))return;e(...s),i()});return this._connect(i),i}async enqueue(){this._enqueue_guard();const{client:t,workflow:e}=this,{prompt:s,workflow:n}=e,{prompt_id:i}=await t._enqueue_prompt(s,{workflow:n});this._task_id=i,this.hook_progress(),this.hook_image_data(),this.hook_executing()}async hook_progress(){const{progress:t}=this.options,{_task_id:e}=this;if(!t)return;if("function"!=typeof t)throw new T(this,"options.progress hook must be a function");if("string"!=typeof e)throw new E(this);const s=this.client.on_progress(t,e);this._connect(s)}async hook_executing(){const{client:t}=this,e=this._task_id_guard();this._connect(t.on("executing",t=>{this.is_current_ws_executing=(null==t?void 0:t.prompt_id)===e}))}async hook_image_data(){const{client:t}=this;this._connect(t.on("image_data",t=>{!1!==this.is_current_ws_executing&&this._result.images.push({type:"buff",data:t.image,mime:t.mime})}))}resolve_to_result(t){const{client:e,resolver:s}=this,{output:n,prompt_id:i,node:r}=t;this._result=s(this._result,n,{client:e,prompt_id:i,node_id:r})}async query(){const t=this._task_id_guard();return this.client.getPromptStatus(t)}async interrupt(){const t=this._task_id_guard(),{pending:e,running:s,done:n}=await this.query();if(!n){if(!e){if(s)return this.client.interrupt(t);throw new C(this)}this.client.deleteItem("queue",t)}}async collect_result(){var t;const{client:e,resolver:s}=this,n=this._task_id_guard(),i=await e.getPromptResult(n,null!=s?s:v.image);return this._result.images=[...this._result.images,...i.images],this._result.data=null!=(t=this._result.data)?t:i.data,this._result}when_interrupted(t){const e=this._task_id_guard();this._connect(this.client.on("execution_interrupted",s=>{s.prompt_id===e&&t(s)}))}when_execution_error(t){const e=this._task_id_guard();this._connect(this.client.on("execution_error",s=>{s.prompt_id===e&&t(s)}))}on_start(t){const e=this._task_id_guard();return this._connect(this.client.on("execution_start",s=>{s.prompt_id===e&&t()}))}async wait_polling({polling_ms:t}={}){var e=this;this._done_guard();const s=this._task_id_guard(),{client:n}=this;return new Promise(async function(i,r){const o=()=>{e.is_done=!0,e.dispose()};e.when_interrupted(t=>{r(new N(e)),o()}),e.when_execution_error(t=>{r(new b(t,s,e.workflow,e)),o()});try{await n.waitForPrompt(s,null!=t?t:1e3),i(await e.collect_result())}catch(t){r(t)}finally{o()}}).catch(t=>{var e,s;return null==(e=(s=this.options).on_error)||e.call(s,t),Promise.reject(t)})}async wait(){var t=this;this._done_guard(),this._ws_guard();const e=this._task_id_guard();return new Promise((s,n)=>{const i=()=>{this.is_done=!0,this.dispose()},r=((e,r)=>{let o=null;return(...e)=>{o&&clearTimeout(o),o=setTimeout(()=>async function(){if(!t.is_done)try{if(!(await t.query()).done)return;s(t._result),i()}catch(t){n(t),i()}}(...e),r)}})(0,this.delay_done_ms);this.when_interrupted(t=>{n(new N(this)),i()}),this.when_execution_error(t=>{n(new b(t,e,this.workflow,this)),i()}),this._connect(r),this._connect(this.client.on("executed",async function(s){s.prompt_id===e&&(t.resolve_to_result(s),r())})),this._connect(this.client.on("execution_success",async function(t){t.prompt_id===e&&r()}))}).catch(t=>{var e,s;return null==(e=(s=this.options).on_error)||e.call(s,t),Promise.reject(t)})}}const U=globalThis.structuredClone?globalThis.structuredClone:t=>JSON.parse(JSON.stringify(t));class q{constructor(){this._workflow={prompt:{}},this._last_node_id=0,this.classes=this._createClassesProxy()}_createClassesProxy(){return new Proxy({},{get:(t,e,s)=>e in t?t[e]:t=>this.node(e,t)})}node(t,e){const s={class_type:t,inputs:e},n=(++this._last_node_id).toString();this._workflow.prompt[n]=s;const i=function*(){let t=0;for(;;)yield[n,t++]}();for(let t=0;t<24;t++)i[t]=[n,t];return i}reset(){this._workflow.prompt={},this._workflow.workflow=void 0,this._last_node_id=0}end(){return this.workflow()}workflow(){return U(this._workflow)}_ws_connected_guard(t){if(!t.socket||t.socket.readyState!==t.WebSocket.OPEN){var e,s;const n={[t.WebSocket.CLOSED]:"CLOSED",[t.WebSocket.CONNECTING]:"CONNECTING",[t.WebSocket.OPEN]:"OPEN",[t.WebSocket.CLOSING]:"CLOSING",[-1]:"UNKNOWN"}[null!=(e=null==(s=t.socket)?void 0:s.readyState)?e:-1];throw new Error(`WebSocket is not connected, cannot invoke workflow. readyState=${n}`)}}async invoke(t,e){this._ws_connected_guard(t);const s=this.instance(t,e);return await s.enqueue(),s.wait()}instance(t,e){const s=this.workflow();return new I({workflow:s,client:t,resolver:null==e?void 0:e.resolver,progress:null==e?void 0:e.progress})}invoke_polling(t,e){if("function"==typeof(null==e?void 0:e.progress))throw new Error("progress option is not supported in polling mode");const{prompt:s,workflow:n}=this.workflow();return t.enqueue_polling(s,{workflow:n,resolver:null==e?void 0:e.resolver,polling_ms:null==e?void 0:e.polling_ms})}}class R{constructor(){this.hooks=[]}install(t){for(const e of this.hooks){const s=t,n=s[e.name].bind(t);s[e.name]=(...s)=>e.fn.bind(t)(n,...s)}}addHook(t){this.hooks.push(t)}}var j,D={__proto__:null,LoginAuthPlugin:class extends R{constructor(t){super(),this.options=void 0,this.options=t,this.addHook({type:"function",name:"apiURL",fn:(t,...e)=>{const s=t(...e),n=new URL(s);return n.searchParams.set("token",this.options.token),n.toString()}}),this.addHook({type:"function",name:"wsURL",fn:(t,...e)=>{const s=t(...e),n=new URL(s);return n.searchParams.set("token",this.options.token),n.toString()}})}}};!function(t){t.samplers=["euler","euler_cfg_pp","euler_ancestral","euler_ancestral_cfg_pp","heun","heunpp2","exp_heun_2_x0","exp_heun_2_x0_sde","dpm_2","dpm_2_ancestral","lms","dpm_fast","dpm_adaptive","dpmpp_2s_ancestral","dpmpp_2s_ancestral_cfg_pp","dpmpp_sde","dpmpp_sde_gpu","dpmpp_2m","dpmpp_2m_cfg_pp","dpmpp_2m_sde","dpmpp_2m_sde_gpu","dpmpp_2m_sde_heun","dpmpp_2m_sde_heun_gpu","dpmpp_3m_sde","dpmpp_3m_sde_gpu","ddpm","lcm","ipndm","ipndm_v","deis","res_multistep","res_multistep_cfg_pp","res_multistep_ancestral","res_multistep_ancestral_cfg_pp","gradient_estimation","gradient_estimation_cfg_pp","er_sde","seeds_2","seeds_3","sa_solver","sa_solver_pece","ddim","uni_pc","uni_pc_bh2"],t.schedulers=["simple","sgm_uniform","karras","exponential","ddim_uniform","beta","normal","linear_quadratic","kl_optimal"]}(j||(j={}));class W extends ${static nextSeed(){return Math.floor(Math.random()*Number.MAX_SAFE_INTEGER)}constructor(e){super(),this.context=void 0,this._workflow=new q,this._invoked=void 0,this.context=t({},W.defaultContext,e)}update(t){Object.assign(this.context,t)}image(t){return this.update({input_image:t}),this}mask(t){return this.update({input_mask:t}),this}model(t){return this.update({ckpt_name:t}),this}size(t,e){return this.update({width:t,height:e}),this}prompt(t){return this.update({positive:t}),this}negative(t){return this.update({negative:t}),this}steps(t){return this.update({steps:t}),this}cfg(t){return this.update({cfg:t}),this}seed(t=W.nextSeed()){return this.update({seed:t}),this}denoise(t){return this.update({denoise:t}),this}scheduler(t){return this.update({scheduler:t}),this}sampler(t){return this.update({sampler_name:t}),this}batch_size(t){return this.update({batch_size:t}),this}with(t){return this.update({client:t}),this}on(t,e,s){const{_invoked:n}=this;if(!n)throw new Error("workflow not invoked");return n.then(n=>{n.on(t,e,s)}),this}once(t,e,s){const{_invoked:n}=this;if(!n)throw new Error("workflow not invoked");return n.then(n=>{n.once(t,e,s)}),this}build_latent(t){const{context:e,_workflow:s}=this,n=s.classes,{width:i,height:r,batch_size:o}=e,{input_image:a,input_mask:c,grow_mask_by:l}=this.context;if(!a)return n.EmptyLatentImage({width:i,height:r,batch_size:o})[0];const u=n.ETN_LoadImageBase64({image:a.toString("base64")})[0];if(!c)return n.VAEEncode({pixels:u,vae:t})[0];const d=n.ETN_LoadMaskBase64({mask:c.toString("base64")})[0];return n.VAEEncodeForInpaint({pixels:u,vae:t,mask:d,grow_mask_by:l})[0]}build(){const{context:t,_workflow:e}=this,s=e.classes,{seed:n,steps:i,cfg:r,scheduler:o,denoise:a,ckpt_name:c,positive:l,negative:u,sampler_name:d}=t,[h,p,_]=s.CheckpointLoaderSimple({ckpt_name:c}),m=t=>s.CLIPTextEncode({text:t,clip:p})[0],[w]=s.KSampler({seed:n,steps:i,cfg:r,sampler_name:d,scheduler:o,denoise:a,model:h,positive:m(l),negative:m(u),latent_image:this.build_latent(_)});return{samples:w,vae:_,cls:s}}_save(t){const{samples:e,vae:s,cls:n}=this.build(),i=n.VAEDecode({samples:e,vae:s})[0];t?n.SaveImage({filename_prefix:t,images:i}):n.SaveImageWebsocket({images:i})}async read_response(t){const e=[];for(const n of t.images)switch(n.type){case"buff":e.push({data:n.data,mime:n.mime});break;case"url":{var s;const{data:t}=n,i=await fetch(t),r=null!=(s=i.headers.get("content-type"))?s:"image/png",o=await i.blob();e.push({data:await o.arrayBuffer(),mime:r});break}}return e}save(t){var e=this;const{context:{client:s},_workflow:n}=this;if(!s)throw new Error("client is not defined");return this._save(t),this._invoked=async function(){const t=n.instance(s);return t._connect(()=>e.dispose()),await t.enqueue(),t}(),this}async wait(){const{_invoked:t}=this;if(!t)throw new Error("workflow not invoked");const e=await(await t).wait();return{result:e,images:await this.read_response(e)}}async wait_polling(){const{_invoked:t}=this;if(!t)throw new Error("workflow not invoked");const e=await(await t).wait_polling();return{result:e,images:await this.read_response(e)}}}W.defaultContext={seed:W.nextSeed(),steps:35,cfg:4,sampler_name:"dpmpp_2m_sde_gpu",scheduler:"karras",denoise:1,width:512,height:512,batch_size:1,ckpt_name:"",input_image:null,input_mask:null,grow_mask_by:6,positive:"",negative:"",client:null};class B extends W{constructor(e){super(),this.context=t({},B.defaultContext,e)}lora(t,{weight:e=1,strength:s=1,clip_strength:n=1}={}){return this.context.loras.push({name:t,weight:e,model_strength:s,clip_strength:n}),this}cnet(t,e,{strength:s=1,start:n=0,end:i=1}={}){return this.context.control_net_blocks.push({image:e,name:t,strength:s,start:n,end:i}),this}build_lora_stack(){const{loras:e}=this.context;if(0===e.length)return;const{_workflow:s}=this,n=s.classes,i={lora_count:e.length};for(let t=0;t<50;t++){const s=e[t];if(!s){i[`lora_name_${t}`]="None",i[`lora_wt_${t}`]=1,i[`model_str_${t}`]=1,i[`clip_str_${t}`]=1;continue}const{name:n,weight:r,model_strength:o,clip_strength:a}=s;i[`lora_name_${t}`]=n,i[`lora_wt_${t}`]=r,i[`model_str_${t}`]=o,i[`clip_str_${t}`]=a}const[r]=n["LoRA Stacker"](t({input_mode:"advanced"},i));return r}build_cnet_block({image:t,name:e,strength:s,start:n,end:i},r){const{_workflow:o}=this,{ControlNetLoader:a,ETN_LoadImageBase64:c}=o.classes,l=o.classes,[u]=a({control_net_name:e}),[d]=c({image:t.toString("base64")}),[h]=l["Control Net Stacker"]({control_net:u,image:d,strength:s,start_percent:n,end_percent:i,cnet_stack:r});return h}build_cnet_stack(){const{control_net_blocks:t}=this.context;if(0===t.length)return;let e;for(const s of t)e=this.build_cnet_block(s,e);return e}build(){const{context:t,_workflow:e}=this,s=e.classes,{seed:n,steps:i,cfg:r,scheduler:o,denoise:a,ckpt_name:c,positive:l,negative:u,sampler_name:d,vae_name:h,clip_skip:p,token_normalization:_,weight_interpretation:m,width:w,height:g,batch_size:f}=t,[v,k,y,b,x,S,P]=s["Efficient Loader"]({ckpt_name:c,vae_name:h,clip_skip:p,token_normalization:_,weight_interpretation:m,empty_latent_height:g,empty_latent_width:w,batch_size:f,positive:l,negative:u,lora_stack:this.build_lora_stack(),cnet_stack:this.build_cnet_stack(),lora_name:"None",lora_model_strength:1,lora_clip_strength:1}),[E]=s.KSampler({seed:n,steps:i,cfg:r,sampler_name:d,scheduler:o,denoise:a,model:v,positive:k,negative:y,latent_image:this.build_latent(x)});return{samples:E,vae:x,cls:s}}}B.defaultContext=t({},W.defaultContext,{vae_name:"Baked VAE",clip_skip:-2,token_normalization:"none",weight_interpretation:"A1111",loras:[],control_net_blocks:[]});const F=t=>{const e=new Uint8Array(t);let s="";for(let t=0;t<e.byteLength;t++)s+=String.fromCharCode(e[t]);return globalThis.btoa(s)},H=(t,e)=>`data:${e};base64,${t}`,J=(t,{fetch:e=globalThis.fetch}={})=>Promise.all(t.images.map(t=>{switch(t.type){case"buff":return H(F(t.data),t.mime||"image/png");case"url":return e(t.data).then(t=>t.blob()).then(async e=>H(F(await e.arrayBuffer()),t.data.toLowerCase().endsWith(".png")?"image/png":"image/jpeg"));default:throw new Error(`Unknown image type: ${t.type}`)}})),M=O,z=f,V=q,Q=R;export{W as BasePipe,O as Client,x as ClientConnectionError,c as ClientEnqueueError,r as ClientError,Q as ClientPlugin,h as ClientRequestError,M as ComfyUIApiClient,V as ComfyUIWorkflow,z as ComfyUIWsClient,m as ConnectError,B as EfficientPipe,g as HttpError,j as NSPipeline,R as Plugin,p as PollingTimeoutError,a as PromptEnqueueError,d as PromptExecutionFailedError,l as PromptNotFoundError,o as PromptTimeoutError,u as TaskDataTypeError,w as WebSocketParseError,_ as WebSocketTimeoutError,q as Workflow,T as WorkflowArgumentError,A as WorkflowDoneError,P as WorkflowEnqueuedError,y as WorkflowError,b as WorkflowExecutionError,S as WorkflowGuardError,N as WorkflowInterruptedError,E as WorkflowTaskIdError,C as WorkflowTaskStatusError,L as WorkflowWsError,f as WsClient,k as builtins,J as outToB64Urls,D as plugins};
//# sourceMappingURL=main.modern.mjs.map