mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-02-09 01:20:09 +00:00
feat: create IComfyApp interface for type-only imports
- Create appInterface.ts with IComfyApp interface - Update ComfyExtension to use IComfyApp instead of ComfyApp - Update ComfyWidgetConstructor to use IComfyApp - ComfyApp now implements IComfyApp - Breaks ~300 circular dependency cycles through type imports Amp-Thread-ID: https://ampcode.com/threads/T-019bfe73-6a29-7638-8160-8de515af8707 Co-authored-by: Amp <amp@ampcode.com>
This commit is contained in:
@@ -20,7 +20,7 @@ import {
|
||||
} from '@/schemas/nodeDefSchema'
|
||||
import { useLitegraphService } from '@/services/litegraphService'
|
||||
import { app } from '@/scripts/app'
|
||||
import type { ComfyApp } from '@/scripts/app'
|
||||
import type { IComfyApp } from '@/types/appInterface'
|
||||
|
||||
const INLINE_INPUTS = false
|
||||
|
||||
@@ -69,7 +69,7 @@ function dynamicComboWidget(
|
||||
node: LGraphNode,
|
||||
inputName: string,
|
||||
untypedInputData: InputSpec,
|
||||
appArg: ComfyApp,
|
||||
appArg: IComfyApp,
|
||||
widgetName?: string
|
||||
) {
|
||||
const { addNodeInput } = useLitegraphService()
|
||||
|
||||
@@ -187,8 +187,9 @@ export class ClipspaceDialog extends ComfyDialog {
|
||||
|
||||
app.registerExtension({
|
||||
name: 'Comfy.Clipspace',
|
||||
init(app) {
|
||||
app.openClipspace = function () {
|
||||
init(appArg) {
|
||||
const comfyApp = appArg as ComfyApp
|
||||
comfyApp.openClipspace = function () {
|
||||
if (!ClipspaceDialog.instance) {
|
||||
ClipspaceDialog.instance = new ClipspaceDialog()
|
||||
ComfyApp.clipspace_invalidate_handler = ClipspaceDialog.invalidate
|
||||
@@ -196,7 +197,7 @@ app.registerExtension({
|
||||
|
||||
if (ComfyApp.clipspace) {
|
||||
ClipspaceDialog.instance.show()
|
||||
} else app.ui.dialog.show('Clipspace is Empty!')
|
||||
} else comfyApp.ui.dialog.show('Clipspace is Empty!')
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
@@ -65,6 +65,7 @@ import { SYSTEM_NODE_DEFS, useNodeDefStore } from '@/stores/nodeDefStore'
|
||||
import { useSubgraphStore } from '@/stores/subgraphStore'
|
||||
import { useWidgetStore } from '@/stores/widgetStore'
|
||||
import { useWorkspaceStore } from '@/stores/workspaceStore'
|
||||
import type { IComfyApp } from '@/types/appInterface'
|
||||
import type { ComfyExtension, MissingNodeType } from '@/types/comfy'
|
||||
import { type ExtensionManager } from '@/types/extensionTypes'
|
||||
import type { NodeExecutionId } from '@/types/nodeIdentification'
|
||||
@@ -127,7 +128,7 @@ type Clipspace = {
|
||||
combinedIndex: number
|
||||
}
|
||||
|
||||
export class ComfyApp {
|
||||
export class ComfyApp implements IComfyApp {
|
||||
/**
|
||||
* List of entries to queue
|
||||
*/
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { ComfyApp } from '@/scripts/app'
|
||||
import type { IComfyApp } from '@/types/appInterface'
|
||||
|
||||
import { $el } from '../../ui'
|
||||
import { ComfyButtonGroup } from '../components/buttonGroup'
|
||||
@@ -13,13 +13,13 @@ export { DraggableList } from '@/scripts/ui/draggableList'
|
||||
export { applyTextReplacements, addStylesheet } from '@/scripts/utils'
|
||||
|
||||
export class ComfyAppMenu {
|
||||
app: ComfyApp
|
||||
app: IComfyApp
|
||||
actionsGroup: ComfyButtonGroup
|
||||
settingsGroup: ComfyButtonGroup
|
||||
viewGroup: ComfyButtonGroup
|
||||
element: HTMLElement
|
||||
|
||||
constructor(app: ComfyApp) {
|
||||
constructor(app: IComfyApp) {
|
||||
this.app = app
|
||||
|
||||
// Keep the group as there are custom scripts attaching extra
|
||||
|
||||
@@ -3,14 +3,14 @@ import { useSettingStore } from '@/platform/settings/settingStore'
|
||||
import type { SettingParams } from '@/platform/settings/types'
|
||||
import { useToastStore } from '@/platform/updates/common/toastStore'
|
||||
import type { Settings } from '@/schemas/apiSchema'
|
||||
import type { ComfyApp } from '@/scripts/app'
|
||||
import type { IComfyApp } from '@/types/appInterface'
|
||||
|
||||
import { ComfyDialog } from './dialog'
|
||||
|
||||
export class ComfySettingsDialog extends ComfyDialog<HTMLDialogElement> {
|
||||
app: ComfyApp
|
||||
app: IComfyApp
|
||||
|
||||
constructor(app: ComfyApp) {
|
||||
constructor(app: IComfyApp) {
|
||||
super()
|
||||
this.app = app
|
||||
}
|
||||
|
||||
@@ -24,7 +24,7 @@ import { transformInputSpecV1ToV2 } from '@/schemas/nodeDef/migration'
|
||||
import type { InputSpec as InputSpecV2 } from '@/schemas/nodeDef/nodeDefSchemaV2'
|
||||
import type { InputSpec } from '@/schemas/nodeDefSchema'
|
||||
|
||||
import type { ComfyApp } from './app'
|
||||
import type { IComfyApp } from '@/types/appInterface'
|
||||
import './domWidget'
|
||||
import './errorNodeWidgets'
|
||||
|
||||
@@ -37,7 +37,7 @@ export type ComfyWidgetConstructor = (
|
||||
node: LGraphNode,
|
||||
inputName: string,
|
||||
inputData: InputSpec,
|
||||
app: ComfyApp,
|
||||
app: IComfyApp,
|
||||
widgetName?: string
|
||||
) => { widget: IBaseWidget; minWidth?: number; minHeight?: number }
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@ import type {
|
||||
TaskOutput
|
||||
} from '@/schemas/apiSchema'
|
||||
import { api } from '@/scripts/api'
|
||||
import type { ComfyApp } from '@/scripts/app'
|
||||
import type { IComfyApp } from '@/types/appInterface'
|
||||
import { useExtensionService } from '@/services/extensionService'
|
||||
import { getJobDetail } from '@/services/jobOutputCache'
|
||||
import { useNodeOutputStore } from '@/stores/imagePreviewStore'
|
||||
@@ -408,7 +408,7 @@ export class TaskItemImpl {
|
||||
return new TaskItemImpl(this.job, jobDetail.outputs)
|
||||
}
|
||||
|
||||
public async loadWorkflow(app: ComfyApp) {
|
||||
public async loadWorkflow(app: IComfyApp) {
|
||||
if (!this.isHistory) {
|
||||
return
|
||||
}
|
||||
|
||||
60
src/types/appInterface.ts
Normal file
60
src/types/appInterface.ts
Normal file
@@ -0,0 +1,60 @@
|
||||
import type { LGraph, LGraphCanvas } from '@/lib/litegraph/src/litegraph'
|
||||
import type { NodeExecutionOutput } from '@/schemas/apiSchema'
|
||||
import type { ComfyWorkflow } from '@/platform/workflow/management/stores/workflowStore'
|
||||
import type { WorkflowOpenSource } from '@/platform/telemetry/types'
|
||||
import type { ComfyWorkflowJSON } from '@/platform/workflow/validation/schemas/workflowSchema'
|
||||
import type { ComfyNodeDef } from '@/schemas/nodeDefSchema'
|
||||
import type { ComfyExtension } from '@/types/comfy'
|
||||
|
||||
import type { ComfyWidgetConstructor } from '@/scripts/widgets'
|
||||
|
||||
export interface IComfyApp {
|
||||
vueAppReady: boolean
|
||||
rootGraph: LGraph
|
||||
canvas: LGraphCanvas
|
||||
configuringGraph: boolean
|
||||
nodeOutputs: Record<string, NodeExecutionOutput>
|
||||
|
||||
/** @deprecated storageLocation is always 'server' */
|
||||
readonly storageLocation: string
|
||||
/** @deprecated storage migration is no longer needed */
|
||||
readonly isNewUserSession: boolean
|
||||
/** @deprecated Use useExecutionStore().lastExecutionError instead */
|
||||
readonly lastExecutionError: unknown
|
||||
/** @deprecated Use useWidgetStore().widgets instead */
|
||||
readonly widgets: Record<string, ComfyWidgetConstructor>
|
||||
|
||||
getPreviewFormatParam(): string
|
||||
|
||||
loadGraphData(
|
||||
graphData?: ComfyWorkflowJSON,
|
||||
clean?: boolean,
|
||||
restore_view?: boolean,
|
||||
workflow?: string | null | ComfyWorkflow,
|
||||
options?: {
|
||||
showMissingNodesDialog?: boolean
|
||||
showMissingModelsDialog?: boolean
|
||||
checkForRerouteMigration?: boolean
|
||||
openSource?: WorkflowOpenSource
|
||||
}
|
||||
): Promise<void>
|
||||
|
||||
graphToPrompt(graph?: LGraph): Promise<{
|
||||
workflow: ComfyWorkflowJSON
|
||||
output: Record<string, unknown>
|
||||
}>
|
||||
|
||||
queuePrompt(
|
||||
number: number,
|
||||
batchCount?: number,
|
||||
queueNodeIds?: string[]
|
||||
): Promise<boolean>
|
||||
|
||||
clean(): void
|
||||
|
||||
handleFile(file: File, openSource?: WorkflowOpenSource): Promise<void>
|
||||
|
||||
registerExtension(extension: ComfyExtension): void
|
||||
|
||||
registerNodeDef(nodeId: string, nodeDef: ComfyNodeDef): Promise<void>
|
||||
}
|
||||
@@ -7,7 +7,7 @@ import type { SettingParams } from '@/platform/settings/types'
|
||||
import type { ComfyWorkflowJSON } from '@/platform/workflow/validation/schemas/workflowSchema'
|
||||
import type { Keybinding } from '@/schemas/keyBindingSchema'
|
||||
import type { ComfyNodeDef } from '@/schemas/nodeDefSchema'
|
||||
import type { ComfyApp } from '@/scripts/app'
|
||||
import type { IComfyApp } from './appInterface'
|
||||
import type { ComfyWidgetConstructor } from '@/scripts/widgets'
|
||||
import type { ComfyCommand } from '@/stores/commandStore'
|
||||
import type { AuthUserInfo } from '@/types/authTypes'
|
||||
@@ -136,12 +136,12 @@ export interface ComfyExtension {
|
||||
* Allows any initialisation, e.g. loading resources. Called after the canvas is created but before nodes are added
|
||||
* @param app The ComfyUI app instance
|
||||
*/
|
||||
init?(app: ComfyApp): Promise<void> | void
|
||||
init?(app: IComfyApp): Promise<void> | void
|
||||
/**
|
||||
* Allows any additional setup, called after the application is fully set up and running
|
||||
* @param app The ComfyUI app instance
|
||||
*/
|
||||
setup?(app: ComfyApp): Promise<void> | void
|
||||
setup?(app: IComfyApp): Promise<void> | void
|
||||
/**
|
||||
* Called before nodes are registered with the graph
|
||||
* @param defs The collection of node definitions, add custom ones or edit existing ones
|
||||
@@ -149,7 +149,7 @@ export interface ComfyExtension {
|
||||
*/
|
||||
addCustomNodeDefs?(
|
||||
defs: Record<string, ComfyNodeDef>,
|
||||
app: ComfyApp
|
||||
app: IComfyApp
|
||||
): Promise<void> | void
|
||||
// TODO(huchenlei): We should deprecate the async return value of
|
||||
// getCustomWidgets.
|
||||
@@ -158,7 +158,7 @@ export interface ComfyExtension {
|
||||
* @param app The ComfyUI app instance
|
||||
* @returns An array of {[widget name]: widget data}
|
||||
*/
|
||||
getCustomWidgets?(app: ComfyApp): Promise<Widgets> | Widgets
|
||||
getCustomWidgets?(app: IComfyApp): Promise<Widgets> | Widgets
|
||||
|
||||
/**
|
||||
* Allows the extension to add additional commands to the selection toolbox
|
||||
@@ -190,7 +190,7 @@ export interface ComfyExtension {
|
||||
beforeRegisterNodeDef?(
|
||||
nodeType: typeof LGraphNode,
|
||||
nodeData: ComfyNodeDef,
|
||||
app: ComfyApp
|
||||
app: IComfyApp
|
||||
): Promise<void> | void
|
||||
|
||||
/**
|
||||
@@ -200,7 +200,7 @@ export interface ComfyExtension {
|
||||
* @param defs The node definitions
|
||||
* @param app The ComfyUI app instance
|
||||
*/
|
||||
beforeRegisterVueAppNodeDefs?(defs: ComfyNodeDef[], app: ComfyApp): void
|
||||
beforeRegisterVueAppNodeDefs?(defs: ComfyNodeDef[], app: IComfyApp): void
|
||||
|
||||
/**
|
||||
* Allows the extension to register additional nodes with LGraph after standard nodes are added.
|
||||
@@ -208,7 +208,7 @@ export interface ComfyExtension {
|
||||
*
|
||||
* @param app The ComfyUI app instance
|
||||
*/
|
||||
registerCustomNodes?(app: ComfyApp): Promise<void> | void
|
||||
registerCustomNodes?(app: IComfyApp): Promise<void> | void
|
||||
/**
|
||||
* Allows the extension to modify a node that has been reloaded onto the graph.
|
||||
* If you break something in the backend and want to patch workflows in the frontend
|
||||
@@ -216,13 +216,13 @@ export interface ComfyExtension {
|
||||
* @param node The node that has been loaded
|
||||
* @param app The ComfyUI app instance
|
||||
*/
|
||||
loadedGraphNode?(node: LGraphNode, app: ComfyApp): void
|
||||
loadedGraphNode?(node: LGraphNode, app: IComfyApp): void
|
||||
/**
|
||||
* Allows the extension to run code after the constructor of the node
|
||||
* @param node The node that has been created
|
||||
* @param app The ComfyUI app instance
|
||||
*/
|
||||
nodeCreated?(node: LGraphNode, app: ComfyApp): void
|
||||
nodeCreated?(node: LGraphNode, app: IComfyApp): void
|
||||
|
||||
/**
|
||||
* Allows the extension to modify the graph data before it is configured.
|
||||
@@ -247,7 +247,7 @@ export interface ComfyExtension {
|
||||
* Extensions can register at any time and will receive the latest value immediately.
|
||||
* This is an experimental API and may be changed or removed in the future.
|
||||
*/
|
||||
onAuthUserResolved?(user: AuthUserInfo, app: ComfyApp): Promise<void> | void
|
||||
onAuthUserResolved?(user: AuthUserInfo, app: IComfyApp): Promise<void> | void
|
||||
|
||||
/**
|
||||
* Fired whenever the auth token is refreshed.
|
||||
|
||||
@@ -13,7 +13,7 @@ import type {
|
||||
UserData,
|
||||
UserDataFullInfo
|
||||
} from '@/schemas/apiSchema'
|
||||
import type { ComfyApp } from '@/scripts/app'
|
||||
import type { IComfyApp } from './appInterface'
|
||||
|
||||
import type {
|
||||
BottomPanelExtension,
|
||||
@@ -27,6 +27,7 @@ import type {
|
||||
export type { ComfyExtension } from './comfy'
|
||||
export type { ComfyApi } from '@/scripts/api'
|
||||
export type { ComfyApp } from '@/scripts/app'
|
||||
export type { IComfyApp } from './appInterface'
|
||||
export type { ComfyNodeDef } from '@/schemas/nodeDefSchema'
|
||||
export type { InputSpec } from '@/schemas/nodeDefSchema'
|
||||
export type {
|
||||
@@ -78,7 +79,7 @@ interface AppReadiness {
|
||||
declare global {
|
||||
interface Window {
|
||||
/** For use by extensions and in the browser console. Where possible, import `app` from '@/scripts/app' instead. */
|
||||
app?: ComfyApp
|
||||
app?: IComfyApp
|
||||
|
||||
/** For use by extensions and in the browser console. Where possible, import `app` and access via `app.graph` instead. */
|
||||
graph?: unknown
|
||||
|
||||
Reference in New Issue
Block a user