Documenting methods

This commit is contained in:
pythongosssss 2023-03-03 15:47:33 +00:00
parent 72cdd83c06
commit 2e52d01cdc
2 changed files with 99 additions and 1 deletions

View File

@ -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);
}

View File

@ -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);