From d592a6ba122950d99da1d5ce4bcb6b4acf06f73f Mon Sep 17 00:00:00 2001 From: bennykok Date: Mon, 22 Apr 2024 00:07:13 +0800 Subject: [PATCH] feat: refactor deployment code --- web-plugin/index.js | 543 +++++++++++++++++++++++--------------------- 1 file changed, 283 insertions(+), 260 deletions(-) diff --git a/web-plugin/index.js b/web-plugin/index.js index c475108..0e78330 100644 --- a/web-plugin/index.js +++ b/web-plugin/index.js @@ -5,6 +5,14 @@ import { generateDependencyGraph } from "https://esm.sh/comfyui-json@0.1.23"; const loadingIcon = ``; +function sendEventToCD(event, data) { + const message = { + type: event, + data: data, + }; + window.parent.postMessage(JSON.stringify(message), "*"); +} + /** @typedef {import('../../../web/types/comfy.js').ComfyExtension} ComfyExtension*/ /** @type {ComfyExtension} */ const ext = { @@ -169,9 +177,11 @@ const ext = { if (comfyUIWorkflow && app && app.loadGraphData) { app.loadGraphData(comfyUIWorkflow); } + } else if (message.type === "deploy") { + deployWorkflow(); } } catch (error) { - console.error("Error processing message:", error); + // console.error("Error processing message:", error); } // if (!event.data.flow || Object.entries(event.data.flow).length <= 0) @@ -189,10 +199,16 @@ const ext = { // } }); - const message = { - type: "cd_plugin_setup", - }; - window.parent.postMessage(JSON.stringify(message), "*"); + app.graph.onAfterChange = ((originalFunction) => async function () { + const prompt = await app.graphToPrompt(); + sendEventToCD("cd_plugin_onAfterChange", prompt); + + if (typeof originalFunction === "function") { + originalFunction.apply(this, arguments); + } + })(app.graph.onAfterChange); + + sendEventToCD("cd_plugin_setup"); }, }; @@ -293,294 +309,301 @@ function createDynamicUIHtml(data) { return html; } -function addButton() { - const menu = document.querySelector(".comfy-menu"); +async function deployWorkflow() { + const deploy = document.getElementById("deploy-button"); - const deploy = document.createElement("button"); - deploy.style.position = "relative"; - deploy.style.display = "block"; - deploy.innerHTML = "
Deploy
"; - deploy.onclick = async () => { - /** @type {LGraph} */ - const graph = app.graph; + /** @type {LGraph} */ + const graph = app.graph; - let { endpoint, apiKey, displayName } = getData(); + let { endpoint, apiKey, displayName } = getData(); - if (!endpoint || !apiKey || apiKey === "" || endpoint === "") { - configDialog.show(); - return; - } + if (!endpoint || !apiKey || apiKey === "" || endpoint === "") { + configDialog.show(); + return; + } - let deployMeta = graph.findNodesByType("ComfyDeploy"); + let deployMeta = graph.findNodesByType("ComfyDeploy"); - if (deployMeta.length == 0) { - const text = await inputDialog.input( - "Create your deployment", - "Workflow name", - ); - if (!text) return; - console.log(text); - app.graph.beforeChange(); - var node = LiteGraph.createNode("ComfyDeploy"); - node.configure({ - widgets_values: [text], - }); - node.pos = [0, 0]; - app.graph.add(node); - app.graph.afterChange(); - deployMeta = [node]; - } - - const deployMetaNode = deployMeta[0]; - - const workflow_name = deployMetaNode.widgets[0].value; - const workflow_id = deployMetaNode.widgets[1].value; - - const ok = await confirmDialog.confirm( - `Confirm deployment`, - ` -
- - A new version of will be deployed, do you confirm? -

- - -
- - -

- -
- -
- `, + if (deployMeta.length == 0) { + const text = await inputDialog.input( + "Create your deployment", + "Workflow name", ); - if (!ok) return; + if (!text) return; + console.log(text); + app.graph.beforeChange(); + var node = LiteGraph.createNode("ComfyDeploy"); + node.configure({ + widgets_values: [text], + }); + node.pos = [0, 0]; + app.graph.add(node); + app.graph.afterChange(); + deployMeta = [node]; + } - const includeDeps = document.getElementById("include-deps").checked; - const reuseHash = document.getElementById("reuse-hash").checked; + const deployMetaNode = deployMeta[0]; - if (endpoint.endsWith("/")) { - endpoint = endpoint.slice(0, -1); - } - loadingDialog.showLoading("Generating snapshot"); + const workflow_name = deployMetaNode.widgets[0].value; + const workflow_id = deployMetaNode.widgets[1].value; - const snapshot = await fetch("/snapshot/get_current").then((x) => x.json()); - // console.log(snapshot); - loadingDialog.close(); + const ok = await confirmDialog.confirm( + `Confirm deployment`, + ` +
- if (!snapshot) { - showError( - "Error when deploying", - "Unable to generate snapshot, please install ComfyUI Manager", - ); - return; - } + A new version of will be deployed, do you confirm? +

- const title = deploy.querySelector("#button-title"); + +
+ - const prompt = await app.graphToPrompt(); - let deps = undefined; +

+ +
+ +
+ `, + ); + if (!ok) return; - if (includeDeps) { - loadingDialog.showLoading("Fetching existing version"); + const includeDeps = document.getElementById("include-deps").checked; + const reuseHash = document.getElementById("reuse-hash").checked; - const existing_workflow = await fetch( - endpoint + "/api/workflow/" + workflow_id, - { - method: "GET", - headers: { - "Content-Type": "application/json", - Authorization: "Bearer " + apiKey, - }, - }, - ) - .then((x) => x.json()) - .catch(() => { - return {}; - }); + if (endpoint.endsWith("/")) { + endpoint = endpoint.slice(0, -1); + } + loadingDialog.showLoading("Generating snapshot"); - loadingDialog.close(); + const snapshot = await fetch("/snapshot/get_current").then((x) => x.json()); + // console.log(snapshot); + loadingDialog.close(); - loadingDialog.showLoading("Generating dependency graph"); - deps = await generateDependencyGraph({ - workflow_api: prompt.output, - snapshot: snapshot, - computeFileHash: async (file) => { - console.log(existing_workflow?.dependencies?.models); + if (!snapshot) { + showError( + "Error when deploying", + "Unable to generate snapshot, please install ComfyUI Manager", + ); + return; + } - // Match previous hash for models - if (reuseHash && existing_workflow?.dependencies?.models) { - const previousModelHash = Object.entries( - existing_workflow?.dependencies?.models, - ).flatMap(([key, value]) => { - return Object.values(value).map((x) => ({ - ...x, - name: "models/" + key + "/" + x.name, - })); - }); - console.log(previousModelHash); + const title = deploy.querySelector("#button-title"); - const match = previousModelHash.find((x) => { - console.log(file, x.name); - return file == x.name; - }); - console.log(match); - if (match && match.hash) { - console.log("cached hash used"); - return match.hash; - } - } - console.log(file); - loadingDialog.showLoading("Generating hash", file); - const hash = await fetch( - `/comfyui-deploy/get-file-hash?file_path=${encodeURIComponent( - file, - )}`, - ).then((x) => x.json()); - loadingDialog.showLoading("Generating hash", file); - console.log(hash); - return hash.file_hash; - }, - handleFileUpload: async (file, hash, prevhash) => { - console.log("Uploading ", file); - loadingDialog.showLoading("Uploading file", file); - try { - const { download_url } = await fetch( - `/comfyui-deploy/upload-file`, - { - method: "POST", - body: JSON.stringify({ - file_path: file, - token: apiKey, - url: endpoint + "/api/upload-url", - }), - }, - ) - .then((x) => x.json()) - .catch(() => { - loadingDialog.close(); - confirmDialog.confirm("Error", "Unable to upload file " + file); - }); - loadingDialog.showLoading("Uploaded file", file); - console.log(download_url); - return download_url; - } catch (error) { - return undefined; - } - }, - existingDependencies: existing_workflow.dependencies, - }); + const prompt = await app.graphToPrompt(); + let deps = undefined; - // Need to find a way to include this if this is not included in comfyui-json level - if ( - !deps.custom_nodes["https://github.com/BennyKok/comfyui-deploy"] && - !deps.custom_nodes["https://github.com/BennyKok/comfyui-deploy.git"] - ) - deps.custom_nodes["https://github.com/BennyKok/comfyui-deploy"] = { - url: "https://github.com/BennyKok/comfyui-deploy", - install_type: "git-clone", - hash: - snapshot?.git_custom_nodes?.[ - "https://github.com/BennyKok/comfyui-deploy" - ]?.hash ?? "HEAD", - name: "ComfyUI Deploy", - }; + if (includeDeps) { + loadingDialog.showLoading("Fetching existing version"); - loadingDialog.close(); - - const depsOk = await confirmDialog.confirm( - "Check dependencies", - // JSON.stringify(deps, null, 2), - ` -
${loadingIcon}
-