Update public API syntax of remote (lazy) widgets (#2477)

Co-authored-by: huchenlei <huchenlei@proton.me>
This commit is contained in:
bymyself
2025-02-09 10:41:14 -07:00
committed by GitHub
parent 83cc49a42b
commit eeb1c34ada
6 changed files with 30 additions and 28 deletions

View File

@@ -17,7 +17,7 @@ jobs:
steps:
- uses: Comfy-Org/ComfyUI_frontend_setup_action@v2.2
with:
devtools_ref: a9c49e4c57464da41ec346deb4a9eeeb00a52c9a
devtools_ref: 8ff192366066cd44bfc2a25713c9957ccf665938
- name: Run Jest tests
run: |
npm run test:generate
@@ -29,7 +29,7 @@ jobs:
steps:
- uses: Comfy-Org/ComfyUI_frontend_setup_action@v2.2
with:
devtools_ref: a9c49e4c57464da41ec346deb4a9eeeb00a52c9a
devtools_ref: 8ff192366066cd44bfc2a25713c9957ccf665938
- name: Install Playwright Browsers
run: npx playwright install chromium --with-deps
working-directory: ComfyUI_frontend
@@ -48,7 +48,7 @@ jobs:
steps:
- uses: Comfy-Org/ComfyUI_frontend_setup_action@v2.2
with:
devtools_ref: a9c49e4c57464da41ec346deb4a9eeeb00a52c9a
devtools_ref: 8ff192366066cd44bfc2a25713c9957ccf665938
- name: Install Playwright Browsers
run: npx playwright install chromium --with-deps
working-directory: ComfyUI_frontend
@@ -67,7 +67,7 @@ jobs:
steps:
- uses: Comfy-Org/ComfyUI_frontend_setup_action@v2.2
with:
devtools_ref: a9c49e4c57464da41ec346deb4a9eeeb00a52c9a
devtools_ref: 8ff192366066cd44bfc2a25713c9957ccf665938
- name: Install Playwright Browsers
run: npx playwright install chromium --with-deps
working-directory: ComfyUI_frontend

View File

@@ -1,7 +1,7 @@
import axios from 'axios'
import { useWidgetStore } from '@/stores/widgetStore'
import type { InputSpec } from '@/types/apiTypes'
import type { InputSpec, RemoteWidgetConfig } from '@/types/apiTypes'
export interface CacheEntry<T> {
data: T[]
@@ -16,8 +16,8 @@ export interface CacheEntry<T> {
const dataCache = new Map<string, CacheEntry<any>>()
const createCacheKey = (inputData: InputSpec): string => {
const { route, query_params = {}, refresh = 0 } = inputData[1]
const createCacheKey = (config: RemoteWidgetConfig): string => {
const { route, query_params = {}, refresh = 0 } = config
const paramsKey = Object.entries(query_params)
.sort(([a], [b]) => a.localeCompare(b))
@@ -32,10 +32,10 @@ const getBackoff = (retryCount: number) => {
}
async function fetchData<T>(
inputData: InputSpec,
config: RemoteWidgetConfig,
controller: AbortController
): Promise<T[]> {
const { route, response_key, query_params } = inputData[1]
const { route, response_key, query_params } = config
const res = await axios.get(route, {
params: query_params,
signal: controller.signal,
@@ -45,9 +45,10 @@ async function fetchData<T>(
}
export function useRemoteWidget<T>(inputData: InputSpec) {
const { refresh = 0 } = inputData[1]
const config: RemoteWidgetConfig = inputData[1].remote
const { refresh = 0 } = config
const isPermanent = refresh <= 0
const cacheKey = createCacheKey(inputData)
const cacheKey = createCacheKey(config)
const defaultValue = useWidgetStore().getDefaultValue(inputData)
const setSuccess = (entry: CacheEntry<T>, data: T[]) => {
@@ -113,10 +114,7 @@ export function useRemoteWidget<T>(inputData: InputSpec) {
currentEntry.error = null
currentEntry.controller = new AbortController()
currentEntry.fetchPromise = fetchData<T>(
inputData,
currentEntry.controller
)
currentEntry.fetchPromise = fetchData<T>(config, currentEntry.controller)
const data = await currentEntry.fetchPromise
setSuccess(currentEntry, data)

View File

@@ -565,8 +565,7 @@ export const ComfyWidgets: Record<string, ComfyWidgetConstructor> = {
},
COMBO(node, inputName, inputData: InputSpec) {
const widgetStore = useWidgetStore()
const { type, options } = inputData[1]
const { remote, options } = inputData[1]
const defaultValue = widgetStore.getDefaultValue(inputData)
const res = {
@@ -575,7 +574,7 @@ export const ComfyWidgets: Record<string, ComfyWidgetConstructor> = {
}) as IComboWidget
}
if (type === 'remote') {
if (remote) {
const remoteWidget = useRemoteWidget(inputData)
const origOptions = res.widget.options

View File

@@ -53,7 +53,7 @@ export const useWidgetStore = defineStore('widget', () => {
if (props.default) return props.default
if (widgetType === 'COMBO' && props.options?.length) return props.options[0]
if (props.type === 'remote') return 'Loading...'
if (props.remote) return 'Loading...'
return undefined
}

View File

@@ -269,6 +269,13 @@ function inputSpec<TType extends ZodType, TSpec extends ZodType>(
])
}
const zRemoteWidgetConfig = z.object({
route: z.string().url().or(z.string().startsWith('/')),
refresh: z.number().gte(128).safe().or(z.number().lte(0).safe()).optional(),
response_key: z.string().optional(),
query_params: z.record(z.string(), z.string()).optional()
})
const zBaseInputSpecValue = z
.object({
default: z.any().optional(),
@@ -332,11 +339,7 @@ const zStringInputSpec = inputSpec([
const zComboInputProps = zBaseInputSpecValue.extend({
control_after_generate: z.boolean().optional(),
image_upload: z.boolean().optional(),
type: z.enum(['remote']).optional(),
route: z.string().url().or(z.string().startsWith('/')).optional(),
refresh: z.number().gte(128).safe().or(z.number().lte(0).safe()).optional(),
response_key: z.string().optional(),
query_params: z.record(z.string(), z.string()).optional()
remote: zRemoteWidgetConfig.optional()
})
// Dropdown Selection.
@@ -594,3 +597,4 @@ export type UserDataFullInfo = z.infer<typeof zUserDataFullInfo>
export type TerminalSize = z.infer<typeof zTerminalSize>
export type LogEntry = z.infer<typeof zLogEntry>
export type LogsRawResponse = z.infer<typeof zLogRawResponse>
export type RemoteWidgetConfig = z.infer<typeof zRemoteWidgetConfig>

View File

@@ -35,10 +35,11 @@ function createMockInputData(overrides = {}): ComboInputSpecV2 {
'COMBO',
{
name: 'test_widget',
type: 'remote',
route: `/api/test/${Date.now()}${Math.random().toString(36).substring(2, 15)}`,
refresh: 0,
...overrides
remote: {
route: `/api/test/${Date.now()}${Math.random().toString(36).substring(2, 15)}`,
refresh: 0,
...overrides
}
}
]
}