Documenting methods
This commit is contained in:
parent
72cdd83c06
commit
2e52d01cdc
|
@ -3,6 +3,9 @@ class ComfyApi extends EventTarget {
|
|||
super();
|
||||
}
|
||||
|
||||
/**
|
||||
* Poll status for colab and other things that don't support websockets.
|
||||
*/
|
||||
#pollQueue() {
|
||||
setInterval(async () => {
|
||||
try {
|
||||
|
@ -15,6 +18,10 @@ class ComfyApi extends EventTarget {
|
|||
}, 1000);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates and connects a WebSocket for realtime updates
|
||||
* @param {boolean} isReconnect If the socket is connection is a reconnect attempt
|
||||
*/
|
||||
#createSocket(isReconnect) {
|
||||
if (this.socket) {
|
||||
return;
|
||||
|
@ -74,15 +81,27 @@ class ComfyApi extends EventTarget {
|
|||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialises sockets and realtime updates
|
||||
*/
|
||||
init() {
|
||||
this.#createSocket();
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads node object definitions for the graph
|
||||
* @returns The node definitions
|
||||
*/
|
||||
async getNodeDefs() {
|
||||
const resp = await fetch("object_info", { cache: "no-store" });
|
||||
return await resp.json();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {number} number The index at which to queue the prompt, passing -1 will insert the prompt at the front of the queue
|
||||
* @param {object} prompt The prompt data to queue
|
||||
*/
|
||||
async queuePrompt(number, { output, workflow }) {
|
||||
const body = {
|
||||
client_id: this.clientId,
|
||||
|
@ -111,6 +130,11 @@ class ComfyApi extends EventTarget {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads a list of items (queue or history)
|
||||
* @param {string} type The type of items to load, queue or history
|
||||
* @returns The items of the specified type grouped by their status
|
||||
*/
|
||||
async getItems(type) {
|
||||
if (type === "queue") {
|
||||
return this.getQueue();
|
||||
|
@ -118,13 +142,20 @@ class ComfyApi extends EventTarget {
|
|||
return this.getHistory();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the current state of the queue
|
||||
* @returns The currently running and queued items
|
||||
*/
|
||||
async getQueue() {
|
||||
try {
|
||||
const res = await fetch("/queue");
|
||||
const data = await res.json();
|
||||
return {
|
||||
// Running action uses a different endpoint for cancelling
|
||||
Running: data.queue_running.map((prompt) => ({ prompt, remove: { name: "Cancel", cb: () => api.interrupt() } })),
|
||||
Running: data.queue_running.map((prompt) => ({
|
||||
prompt,
|
||||
remove: { name: "Cancel", cb: () => api.interrupt() },
|
||||
})),
|
||||
Pending: data.queue_pending.map((prompt) => ({ prompt })),
|
||||
};
|
||||
} catch (error) {
|
||||
|
@ -133,6 +164,10 @@ class ComfyApi extends EventTarget {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the prompt execution history
|
||||
* @returns Prompt history including node outputs
|
||||
*/
|
||||
async getHistory() {
|
||||
try {
|
||||
const res = await fetch("/history");
|
||||
|
@ -143,6 +178,11 @@ class ComfyApi extends EventTarget {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a POST request to the API
|
||||
* @param {*} type The endpoint to post to
|
||||
* @param {*} body Optional POST data
|
||||
*/
|
||||
async #postItem(type, body) {
|
||||
try {
|
||||
await fetch("/" + type, {
|
||||
|
@ -157,14 +197,26 @@ class ComfyApi extends EventTarget {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes an item from the specified list
|
||||
* @param {string} type The type of item to delete, queue or history
|
||||
* @param {number} id The id of the item to delete
|
||||
*/
|
||||
async deleteItem(type, id) {
|
||||
await this.#postItem(type, { delete: [id] });
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears the specified list
|
||||
* @param {string} type The type of list to clear, queue or history
|
||||
*/
|
||||
async clearItems(type) {
|
||||
await this.#postItem(type, { clear: true });
|
||||
}
|
||||
|
||||
/**
|
||||
* Interrupts the execution of the running prompt
|
||||
*/
|
||||
async interrupt() {
|
||||
await this.#postItem("interrupt", null);
|
||||
}
|
||||
|
|
|
@ -45,6 +45,12 @@ class ComfyApp {
|
|||
console.error("[comfy]", message, ...other);
|
||||
}
|
||||
|
||||
/**
|
||||
* Invoke an extension callback
|
||||
* @param {string} method The extension callback to execute
|
||||
* @param {...any} args Any arguments to pass to the callback
|
||||
* @returns
|
||||
*/
|
||||
#invokeExtensions(method, ...args) {
|
||||
let results = [];
|
||||
for (const ext of this.extensions) {
|
||||
|
@ -64,6 +70,13 @@ class ComfyApp {
|
|||
return results;
|
||||
}
|
||||
|
||||
/**
|
||||
* Invoke an async extension callback
|
||||
* Each callback will be invoked concurrently
|
||||
* @param {string} method The extension callback to execute
|
||||
* @param {...any} args Any arguments to pass to the callback
|
||||
* @returns
|
||||
*/
|
||||
async #invokeExtensionsAsync(method, ...args) {
|
||||
return await Promise.all(
|
||||
this.extensions.map(async (ext) => {
|
||||
|
@ -83,6 +96,11 @@ class ComfyApp {
|
|||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds special context menu handling for nodes
|
||||
* e.g. this adds Open Image functionality for nodes that show images
|
||||
* @param {*} node The node to add the menu handler
|
||||
*/
|
||||
#addNodeContextMenuHandler(node) {
|
||||
node.prototype.getExtraMenuOptions = function (_, options) {
|
||||
if (this.imgs) {
|
||||
|
@ -105,6 +123,11 @@ class ComfyApp {
|
|||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds Custom drawing logic for nodes
|
||||
* e.g. Draws images and handles thumbnail navigation on nodes that output images
|
||||
* @param {*} node The node to add the draw handler
|
||||
*/
|
||||
#addDrawBackgroundHandler(node) {
|
||||
const app = this;
|
||||
node.prototype.onDrawBackground = function (ctx) {
|
||||
|
@ -294,6 +317,9 @@ class ComfyApp {
|
|||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a handler allowing drag+drop of files onto the window to load workflows
|
||||
*/
|
||||
#addDropHandler() {
|
||||
// Get prompt from dropped PNG or json
|
||||
document.addEventListener("drop", async (event) => {
|
||||
|
@ -304,6 +330,9 @@ class ComfyApp {
|
|||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a handler on paste that extracts and loads workflows from pasted JSON data
|
||||
*/
|
||||
#addPasteHandler() {
|
||||
document.addEventListener("paste", (e) => {
|
||||
let data = (e.clipboardData || window.clipboardData).getData("text/plain");
|
||||
|
@ -325,6 +354,9 @@ class ComfyApp {
|
|||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Draws currently executing node highlight and progress bar
|
||||
*/
|
||||
#addDrawNodeProgressHandler() {
|
||||
const orig = LGraphCanvas.prototype.drawNodeShape;
|
||||
const self = this;
|
||||
|
@ -373,6 +405,9 @@ class ComfyApp {
|
|||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles updates from the API socket
|
||||
*/
|
||||
#addApiUpdateHandlers() {
|
||||
api.addEventListener("status", ({ detail }) => {
|
||||
this.ui.setStatus(detail);
|
||||
|
@ -458,6 +493,9 @@ class ComfyApp {
|
|||
await this.#invokeExtensionsAsync("setup");
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers nodes with the graph
|
||||
*/
|
||||
async registerNodes() {
|
||||
const app = this;
|
||||
// Load node definitions from the backend
|
||||
|
@ -555,6 +593,10 @@ class ComfyApp {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the current graph workflow for sending to the API
|
||||
* @returns The workflow and node links
|
||||
*/
|
||||
graphToPrompt() {
|
||||
// TODO: Implement dynamic prompts
|
||||
const workflow = this.graph.serialize();
|
||||
|
@ -619,6 +661,10 @@ class ComfyApp {
|
|||
await this.ui.queue.update();
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads workflow data from the specified file
|
||||
* @param {File} file
|
||||
*/
|
||||
async handleFile(file) {
|
||||
if (file.type === "image/png") {
|
||||
const pngInfo = await getPngMetadata(file);
|
||||
|
|
Loading…
Reference in New Issue