mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-01-26 19:09:52 +00:00
Update public API syntax of remote (lazy) widgets (#2477)
Co-authored-by: huchenlei <huchenlei@proton.me>
This commit is contained in:
8
.github/workflows/test-ui.yaml
vendored
8
.github/workflows/test-ui.yaml
vendored
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user