diff --git a/.oxlintrc.json b/.oxlintrc.json index 66142ab5ca..268917241d 100644 --- a/.oxlintrc.json +++ b/.oxlintrc.json @@ -28,6 +28,7 @@ ], "rules": { "no-async-promise-executor": "off", + "func-style": ["error", "declaration"], "no-console": [ "error", { @@ -124,6 +125,12 @@ "no-console": "allow" } }, + { + "files": ["src/lib/litegraph/**"], + "rules": { + "func-style": "off" + } + }, { "files": ["browser_tests/**/*.ts"], "jsPlugins": ["eslint-plugin-playwright"], diff --git a/.storybook/preview.ts b/.storybook/preview.ts index 54eca1d76c..4f3c95541f 100644 --- a/.storybook/preview.ts +++ b/.storybook/preview.ts @@ -47,7 +47,7 @@ setup((app) => { }) // Theme and dialog decorator -export const withTheme = (Story: StoryFn, context: StoryContext) => { +export function withTheme(Story: StoryFn, context: StoryContext) { const theme = context.globals.theme || 'light' // Apply theme class to document root diff --git a/apps/desktop-ui/.storybook/preview.ts b/apps/desktop-ui/.storybook/preview.ts index a0ead30cc1..50886fd363 100644 --- a/apps/desktop-ui/.storybook/preview.ts +++ b/apps/desktop-ui/.storybook/preview.ts @@ -40,7 +40,7 @@ setup((app) => { app.use(ToastService) }) -export const withTheme = (Story: StoryFn, context: StoryContext) => { +export function withTheme(Story: StoryFn, context: StoryContext) { const theme = context.globals.theme || 'light' if (theme === 'dark') { document.documentElement.classList.add('dark-theme') diff --git a/apps/desktop-ui/src/components/bottomPanel/tabs/terminal/BaseTerminal.vue b/apps/desktop-ui/src/components/bottomPanel/tabs/terminal/BaseTerminal.vue index 4983dc8917..10d2fb65c4 100644 --- a/apps/desktop-ui/src/components/bottomPanel/tabs/terminal/BaseTerminal.vue +++ b/apps/desktop-ui/src/components/bottomPanel/tabs/terminal/BaseTerminal.vue @@ -58,7 +58,7 @@ const tooltipText = computed(() => { : t('serverStart.copyAllTooltip') }) -const handleCopy = async () => { +async function handleCopy() { const existingSelection = terminal.getSelection() const shouldSelectAll = !existingSelection if (shouldSelectAll) terminal.selectAll() @@ -76,7 +76,7 @@ const handleCopy = async () => { } } -const showContextMenu = (event: MouseEvent) => { +function showContextMenu(event: MouseEvent) { event.preventDefault() electronAPI()?.showContextMenu({ type: 'text' }) } diff --git a/apps/desktop-ui/src/components/common/UrlInput.vue b/apps/desktop-ui/src/components/common/UrlInput.vue index 91f8cfe564..a7c8c16f1e 100644 --- a/apps/desktop-ui/src/components/common/UrlInput.vue +++ b/apps/desktop-ui/src/components/common/UrlInput.vue @@ -44,8 +44,9 @@ const emit = defineEmits<{ const validationState = ref(ValidationState.IDLE) -const cleanInput = (value: string): string => - value ? value.replace(/\s+/g, '') : '' +function cleanInput(value: string): string { + return value ? value.replace(/\s+/g, '') : '' +} // Add internal value state const internalValue = ref(cleanInput(props.modelValue)) @@ -68,14 +69,14 @@ onMounted(async () => { await validateUrl(props.modelValue) }) -const handleInput = (value: string | undefined) => { +function handleInput(value: string | undefined) { // Update internal value without emitting internalValue.value = cleanInput(value ?? '') // Reset validation state when user types validationState.value = ValidationState.IDLE } -const handleBlur = async () => { +async function handleBlur() { const input = cleanInput(internalValue.value) let normalizedUrl = input @@ -91,7 +92,7 @@ const handleBlur = async () => { } // Default validation implementation -const defaultValidateUrl = async (url: string): Promise => { +async function defaultValidateUrl(url: string): Promise { if (!isValidUrl(url)) return false try { return await checkUrlReachable(url) @@ -100,7 +101,7 @@ const defaultValidateUrl = async (url: string): Promise => { } } -const validateUrl = async (value: string) => { +async function validateUrl(value: string) { if (validationState.value === ValidationState.LOADING) return const url = cleanInput(value) diff --git a/apps/desktop-ui/src/components/install/DesktopSettingsConfiguration.vue b/apps/desktop-ui/src/components/install/DesktopSettingsConfiguration.vue index f1caa62faa..a927a4e3d4 100644 --- a/apps/desktop-ui/src/components/install/DesktopSettingsConfiguration.vue +++ b/apps/desktop-ui/src/components/install/DesktopSettingsConfiguration.vue @@ -127,7 +127,7 @@ const showDialog = ref(false) const autoUpdate = defineModel('autoUpdate', { required: true }) const allowMetrics = defineModel('allowMetrics', { required: true }) -const showMetricsInfo = () => { +function showMetricsInfo() { showDialog.value = true } diff --git a/apps/desktop-ui/src/components/install/InstallLocationPicker.vue b/apps/desktop-ui/src/components/install/InstallLocationPicker.vue index e14e9a0468..95c85d60e3 100644 --- a/apps/desktop-ui/src/components/install/InstallLocationPicker.vue +++ b/apps/desktop-ui/src/components/install/InstallLocationPicker.vue @@ -182,10 +182,12 @@ function getTorchMirrorItem(device: TorchDeviceType): UVMirror { } const userIsInChina = ref(false) -const useFallbackMirror = (mirror: UVMirror) => ({ - ...mirror, - mirror: mirror.fallbackMirror -}) +function useFallbackMirror(mirror: UVMirror) { + return { + ...mirror, + mirror: mirror.fallbackMirror + } +} const mirrors = computed<[UVMirror, ModelRef][]>(() => ( @@ -212,7 +214,7 @@ onMounted(async () => { userIsInChina.value = await isInChina() }) -const validatePath = async (path: string | undefined) => { +async function validatePath(path: string | undefined) { try { pathError.value = '' pathExists.value = false @@ -246,7 +248,7 @@ const validatePath = async (path: string | undefined) => { } } -const browsePath = async () => { +async function browsePath() { try { const result = await electron.showDirectoryPicker() if (result) { @@ -258,7 +260,7 @@ const browsePath = async () => { } } -const onFocus = async () => { +async function onFocus() { if (!inputTouched.value) { inputTouched.value = true return diff --git a/apps/desktop-ui/src/components/install/MigrationPicker.vue b/apps/desktop-ui/src/components/install/MigrationPicker.vue index ba542ca697..d26c62cb71 100644 --- a/apps/desktop-ui/src/components/install/MigrationPicker.vue +++ b/apps/desktop-ui/src/components/install/MigrationPicker.vue @@ -92,7 +92,7 @@ const isValidSource = computed( () => sourcePath.value !== '' && pathError.value === '' ) -const validateSource = async (sourcePath: string | undefined) => { +async function validateSource(sourcePath: string | undefined) { if (!sourcePath) { pathError.value = '' return @@ -109,7 +109,7 @@ const validateSource = async (sourcePath: string | undefined) => { } } -const browsePath = async () => { +async function browsePath() { try { const result = await electron.showDirectoryPicker() if (result) { diff --git a/apps/desktop-ui/src/components/maintenance/TaskListItem.vue b/apps/desktop-ui/src/components/maintenance/TaskListItem.vue index 6f893d0496..2765451c1d 100644 --- a/apps/desktop-ui/src/components/maintenance/TaskListItem.vue +++ b/apps/desktop-ui/src/components/maintenance/TaskListItem.vue @@ -82,7 +82,7 @@ const isExecuting = useMinLoadingDurationRef(reactiveExecuting, 250) // Popover const infoPopover = ref | null>(null) -const toggle = (event: Event) => { +function toggle(event: Event) { infoPopover.value?.toggle(event) } diff --git a/apps/desktop-ui/src/components/maintenance/TaskListPanel.vue b/apps/desktop-ui/src/components/maintenance/TaskListPanel.vue index f667cacb11..0cdb81c3ef 100644 --- a/apps/desktop-ui/src/components/maintenance/TaskListPanel.vue +++ b/apps/desktop-ui/src/components/maintenance/TaskListPanel.vue @@ -67,7 +67,7 @@ defineProps<{ filter: MaintenanceFilter }>() -const executeTask = async (task: MaintenanceTask) => { +async function executeTask(task: MaintenanceTask) { let message: string | undefined try { @@ -87,7 +87,7 @@ const executeTask = async (task: MaintenanceTask) => { } // Commands -const confirmButton = async (event: MouseEvent, task: MaintenanceTask) => { +async function confirmButton(event: MouseEvent, task: MaintenanceTask) { if (!task.requireConfirm) { await executeTask(task) return diff --git a/apps/desktop-ui/src/components/maintenance/TerminalOutputDrawer.vue b/apps/desktop-ui/src/components/maintenance/TerminalOutputDrawer.vue index b3cf67cc50..dd61eb6487 100644 --- a/apps/desktop-ui/src/components/maintenance/TerminalOutputDrawer.vue +++ b/apps/desktop-ui/src/components/maintenance/TerminalOutputDrawer.vue @@ -34,10 +34,10 @@ const buffer = useTerminalBuffer() let xterm: Terminal | null = null // Created and destroyed with the Drawer - contents copied from hidden buffer -const terminalCreated = ( +function terminalCreated( { terminal, useAutoSize }: ReturnType, root: Ref -) => { +) { xterm = terminal useAutoSize({ root, autoRows: true, autoCols: true }) terminal.write(props.defaultMessage) @@ -49,7 +49,7 @@ const terminalCreated = ( terminal.options.disableStdin = true } -const terminalUnmounted = () => { +function terminalUnmounted() { xterm = null } diff --git a/apps/desktop-ui/src/composables/bottomPanelTabs/useTerminal.ts b/apps/desktop-ui/src/composables/bottomPanelTabs/useTerminal.ts index d353294f09..678470c904 100644 --- a/apps/desktop-ui/src/composables/bottomPanelTabs/useTerminal.ts +++ b/apps/desktop-ui/src/composables/bottomPanelTabs/useTerminal.ts @@ -55,14 +55,14 @@ export function useTerminal(element: Ref) { minRows?: number onResize?: () => void }) { - const ensureValidRows = (rows: number | undefined): number => { + function ensureValidRows(rows: number | undefined): number { if (rows == null || isNaN(rows)) { return (root.value?.clientHeight ?? 80) / 20 } return rows } - const ensureValidCols = (cols: number | undefined): number => { + function ensureValidCols(cols: number | undefined): number { if (cols == null || isNaN(cols)) { // Sometimes this is NaN if so, estimate. return (root.value?.clientWidth ?? 80) / 8 @@ -70,7 +70,7 @@ export function useTerminal(element: Ref) { return cols } - const resize = () => { + function resize() { const dims = fitAddon.proposeDimensions() // Sometimes propose returns NaN, so we may need to estimate. terminal.resize( diff --git a/apps/desktop-ui/src/composables/bottomPanelTabs/useTerminalBuffer.ts b/apps/desktop-ui/src/composables/bottomPanelTabs/useTerminalBuffer.ts index 5dda8db2ed..fb071cf3bf 100644 --- a/apps/desktop-ui/src/composables/bottomPanelTabs/useTerminalBuffer.ts +++ b/apps/desktop-ui/src/composables/bottomPanelTabs/useTerminalBuffer.ts @@ -6,13 +6,17 @@ export function useTerminalBuffer() { const serializeAddon = new SerializeAddon() const terminal = markRaw(new Terminal({ convertEol: true })) - const copyTo = (destinationTerminal: Terminal) => { + function copyTo(destinationTerminal: Terminal) { destinationTerminal.write(serializeAddon.serialize()) } - const write = (message: string) => terminal.write(message) + function write(message: string) { + return terminal.write(message) + } - const serialize = () => serializeAddon.serialize() + function serialize() { + return serializeAddon.serialize() + } onMounted(() => { terminal.loadAddon(serializeAddon) diff --git a/apps/desktop-ui/src/constants/desktopMaintenanceTasks.ts b/apps/desktop-ui/src/constants/desktopMaintenanceTasks.ts index 9f81ab394e..f7df0e491f 100644 --- a/apps/desktop-ui/src/constants/desktopMaintenanceTasks.ts +++ b/apps/desktop-ui/src/constants/desktopMaintenanceTasks.ts @@ -5,7 +5,7 @@ import { electronAPI } from '@/utils/envUtil' const electron = electronAPI() -const openUrl = (url: string) => { +function openUrl(url: string) { window.open(url, '_blank') return true } diff --git a/apps/desktop-ui/src/stores/maintenanceTaskStore.ts b/apps/desktop-ui/src/stores/maintenanceTaskStore.ts index 235d370ccf..f75064b2fd 100644 --- a/apps/desktop-ui/src/stores/maintenanceTaskStore.ts +++ b/apps/desktop-ui/src/stores/maintenanceTaskStore.ts @@ -124,13 +124,15 @@ export const useMaintenanceTaskStore = defineStore('maintenanceTask', () => { * @param task Task to get the matching state object for * @returns The state object for this task */ - const getRunner = (task: MaintenanceTask) => taskRunners.value.get(task.id)! + function getRunner(task: MaintenanceTask) { + return taskRunners.value.get(task.id)! + } /** * Updates the task list with the latest validation state. * @param validationUpdate Update details passed in by electron */ - const processUpdate = (validationUpdate: InstallValidation) => { + function processUpdate(validationUpdate: InstallValidation) { lastUpdate.value = validationUpdate const update = validationUpdate as IndexedUpdate isRefreshing.value = true @@ -151,19 +153,19 @@ export const useMaintenanceTaskStore = defineStore('maintenanceTask', () => { } /** Clears the resolved status of tasks (when changing filters) */ - const clearResolved = () => { + function clearResolved() { for (const task of tasks.value) { getRunner(task).resolved &&= false } } /** @todo Refreshes Electron tasks only. */ - const refreshDesktopTasks = async () => { + async function refreshDesktopTasks() { isRefreshing.value = true await electron.Validation.validateInstallation(processUpdate) } - const execute = async (task: MaintenanceTask) => { + async function execute(task: MaintenanceTask) { const success = await getRunner(task).execute(task) if (success && task.isInstallationFix) { await refreshDesktopTasks() diff --git a/apps/desktop-ui/src/utils/electronMirrorCheck.ts b/apps/desktop-ui/src/utils/electronMirrorCheck.ts index 31098ae4fd..417291cb9b 100644 --- a/apps/desktop-ui/src/utils/electronMirrorCheck.ts +++ b/apps/desktop-ui/src/utils/electronMirrorCheck.ts @@ -7,7 +7,7 @@ import { electronAPI } from './envUtil' * @param mirror - The mirror to check. * @returns True if the mirror is reachable, false otherwise. */ -export const checkMirrorReachable = async (mirror: string) => { +export async function checkMirrorReachable(mirror: string) { return ( isValidUrl(mirror) && (await electronAPI().NetWork.canAccessUrl(mirror)) ) diff --git a/apps/desktop-ui/src/views/DesktopDialogView.vue b/apps/desktop-ui/src/views/DesktopDialogView.vue index 0bc5e01d9a..e4b5207cb5 100644 --- a/apps/desktop-ui/src/views/DesktopDialogView.vue +++ b/apps/desktop-ui/src/views/DesktopDialogView.vue @@ -36,7 +36,7 @@ import { electronAPI } from '@/utils/envUtil' const route = useRoute() const { id, title, message, buttons } = getDialog(route.params.dialogId) -const handleButtonClick = async (button: DialogAction) => { +async function handleButtonClick(button: DialogAction) { await electronAPI().Dialog.clickButton(button.returnValue) } diff --git a/apps/desktop-ui/src/views/DesktopUpdateView.vue b/apps/desktop-ui/src/views/DesktopUpdateView.vue index e811cd91e3..2a1d28ace2 100644 --- a/apps/desktop-ui/src/views/DesktopUpdateView.vue +++ b/apps/desktop-ui/src/views/DesktopUpdateView.vue @@ -52,7 +52,7 @@ const electron = electronAPI() const terminalVisible = ref(false) -const toggleConsoleDrawer = () => { +function toggleConsoleDrawer() { terminalVisible.value = !terminalVisible.value } diff --git a/apps/desktop-ui/src/views/DownloadGitView.vue b/apps/desktop-ui/src/views/DownloadGitView.vue index 12c116ad83..5e975c6864 100644 --- a/apps/desktop-ui/src/views/DownloadGitView.vue +++ b/apps/desktop-ui/src/views/DownloadGitView.vue @@ -47,11 +47,11 @@ import { useRouter } from 'vue-router' import BaseViewTemplate from '@/views/templates/BaseViewTemplate.vue' -const openGitDownloads = () => { +function openGitDownloads() { window.open('https://git-scm.com/downloads/', '_blank') } -const skipGit = async () => { +async function skipGit() { console.warn('pushing') const router = useRouter() await router.push('install') diff --git a/apps/desktop-ui/src/views/InstallView.stories.ts b/apps/desktop-ui/src/views/InstallView.stories.ts index d7247161b2..d6d0b96b4b 100644 --- a/apps/desktop-ui/src/views/InstallView.stories.ts +++ b/apps/desktop-ui/src/views/InstallView.stories.ts @@ -8,8 +8,8 @@ import { createMemoryHistory, createRouter } from 'vue-router' import InstallView from './InstallView.vue' // Create a mock router for stories -const createMockRouter = () => - createRouter({ +function createMockRouter() { + return createRouter({ history: createMemoryHistory(), routes: [ { path: '/', component: { template: '
Home
' } }, @@ -23,6 +23,7 @@ const createMockRouter = () => } ] }) +} const meta: Meta = { title: 'Desktop/Views/InstallView', diff --git a/apps/desktop-ui/src/views/InstallView.vue b/apps/desktop-ui/src/views/InstallView.vue index d59a44624f..af742e9bc9 100644 --- a/apps/desktop-ui/src/views/InstallView.vue +++ b/apps/desktop-ui/src/views/InstallView.vue @@ -90,7 +90,7 @@ const currentStep = ref('1') /** Forces each install step to be visited at least once. */ const highestStep = ref(0) -const handleStepChange = (value: string | number) => { +function handleStepChange(value: string | number) { setHighestStep(value) electronAPI().Events.trackEvent('install_stepper_change', { @@ -98,7 +98,7 @@ const handleStepChange = (value: string | number) => { }) } -const setHighestStep = (value: string | number) => { +function setHighestStep(value: string | number) { const int = typeof value === 'number' ? value : parseInt(value, 10) if (!isNaN(int) && int > highestStep.value) highestStep.value = int } @@ -123,7 +123,7 @@ const canProceed = computed(() => { }) // Navigation methods -const goToNextStep = () => { +function goToNextStep() { const nextStep = (parseInt(currentStep.value) + 1).toString() currentStep.value = nextStep setHighestStep(nextStep) @@ -132,7 +132,7 @@ const goToNextStep = () => { }) } -const goToPreviousStep = () => { +function goToPreviousStep() { const prevStep = (parseInt(currentStep.value) - 1).toString() currentStep.value = prevStep electronAPI().Events.trackEvent('install_stepper_change', { @@ -142,7 +142,7 @@ const goToPreviousStep = () => { const electron = electronAPI() const router = useRouter() -const install = async () => { +async function install() { if (!device.value) return const options: InstallOptions = { diff --git a/apps/desktop-ui/src/views/MaintenanceView.stories.ts b/apps/desktop-ui/src/views/MaintenanceView.stories.ts index 4a8a4b012f..9eee93e2d7 100644 --- a/apps/desktop-ui/src/views/MaintenanceView.stories.ts +++ b/apps/desktop-ui/src/views/MaintenanceView.stories.ts @@ -35,12 +35,14 @@ const validationState: ValidationState = { upgradePackages: 'OK' } -const createMockElectronAPI = () => { +function createMockElectronAPI() { const logListeners: Array<(message: string) => void> = [] - const getValidationUpdate = () => ({ - ...validationState - }) + function getValidationUpdate() { + return { + ...validationState + } + } return { getPlatform: () => 'darwin', @@ -76,7 +78,7 @@ const createMockElectronAPI = () => { } } -const ensureElectronAPI = () => { +function ensureElectronAPI() { const globalWindow = window as { electronAPI?: unknown } if (!globalWindow.electronAPI) { globalWindow.electronAPI = createMockElectronAPI() diff --git a/apps/desktop-ui/src/views/MaintenanceView.vue b/apps/desktop-ui/src/views/MaintenanceView.vue index 9fdfd906b1..468dc1ceaf 100644 --- a/apps/desktop-ui/src/views/MaintenanceView.vue +++ b/apps/desktop-ui/src/views/MaintenanceView.vue @@ -183,7 +183,7 @@ const unsafeReasonText = computed(() => { }) /** If valid, leave the validation window. */ -const completeValidation = async () => { +async function completeValidation() { const isValid = await electron.Validation.complete() if (!isValid) { toast.add({ @@ -194,7 +194,7 @@ const completeValidation = async () => { } } -const toggleConsoleDrawer = () => { +function toggleConsoleDrawer() { terminalVisible.value = !terminalVisible.value } diff --git a/apps/desktop-ui/src/views/ManualConfigurationView.vue b/apps/desktop-ui/src/views/ManualConfigurationView.vue index 5a79514b85..74d63bf5c6 100644 --- a/apps/desktop-ui/src/views/ManualConfigurationView.vue +++ b/apps/desktop-ui/src/views/ManualConfigurationView.vue @@ -67,7 +67,9 @@ const electron = electronAPI() const basePath = ref(null) const sep = ref<'\\' | '/'>('/') -const restartApp = (message?: string) => electron.restartApp(message) +function restartApp(message?: string) { + return electron.restartApp(message) +} onMounted(async () => { basePath.value = await electron.getBasePath() diff --git a/apps/desktop-ui/src/views/MetricsConsentView.vue b/apps/desktop-ui/src/views/MetricsConsentView.vue index ee6d3d5deb..e109731038 100644 --- a/apps/desktop-ui/src/views/MetricsConsentView.vue +++ b/apps/desktop-ui/src/views/MetricsConsentView.vue @@ -64,7 +64,7 @@ const allowMetrics = ref(true) const router = useRouter() const isUpdating = ref(false) -const updateConsent = async () => { +async function updateConsent() { isUpdating.value = true try { await electronAPI().setMetricsConsent(allowMetrics.value) diff --git a/apps/desktop-ui/src/views/NotSupportedView.vue b/apps/desktop-ui/src/views/NotSupportedView.vue index 3a2ba7f333..6ad1ec2b70 100644 --- a/apps/desktop-ui/src/views/NotSupportedView.vue +++ b/apps/desktop-ui/src/views/NotSupportedView.vue @@ -61,19 +61,19 @@ import { useRouter } from 'vue-router' import BaseViewTemplate from '@/views/templates/BaseViewTemplate.vue' -const openDocs = () => { +function openDocs() { window.open( 'https://github.com/Comfy-Org/desktop#currently-supported-platforms', '_blank' ) } -const reportIssue = () => { +function reportIssue() { window.open('https://forum.comfy.org/c/v1-feedback/', '_blank') } const router = useRouter() -const continueToInstall = async () => { +async function continueToInstall() { await router.push('/install') } diff --git a/apps/desktop-ui/src/views/ServerStartView.vue b/apps/desktop-ui/src/views/ServerStartView.vue index 6849e22b14..15e1aa9a27 100644 --- a/apps/desktop-ui/src/views/ServerStartView.vue +++ b/apps/desktop-ui/src/views/ServerStartView.vue @@ -118,7 +118,7 @@ let xterm: Terminal | undefined /** * Handles installation stage updates from the desktop */ -const updateInstallStage = (stageInfo: InstallStageInfo) => { +function updateInstallStage(stageInfo: InstallStageInfo) { console.warn('[InstallStage.onUpdate] Received:', { stage: stageInfo.stage, progress: stageInfo.progress, @@ -183,17 +183,17 @@ const displayStatusText = computed(() => { return currentStatusLabel.value }) -const updateProgress = ({ status: newStatus }: { status: ProgressStatus }) => { +function updateProgress({ status: newStatus }: { status: ProgressStatus }) { status.value = newStatus // Make critical error screen more obvious. if (newStatus === ProgressStatus.ERROR) terminalVisible.value = false } -const terminalCreated = ( +function terminalCreated( { terminal, useAutoSize }: ReturnType, root: Ref -) => { +) { xterm = terminal useAutoSize({ root, autoRows: true, autoCols: true }) @@ -206,11 +206,15 @@ const terminalCreated = ( terminal.options.cursorInactiveStyle = 'block' } -const troubleshoot = () => electron.startTroubleshooting() -const reportIssue = () => { +function troubleshoot() { + return electron.startTroubleshooting() +} +function reportIssue() { window.open('https://forum.comfy.org/c/v1-feedback/', '_blank') } -const openLogs = () => electron.openLogsFolder() +function openLogs() { + return electron.openLogsFolder() +} let cleanupInstallStageListener: (() => void) | undefined diff --git a/apps/desktop-ui/src/views/WelcomeView.vue b/apps/desktop-ui/src/views/WelcomeView.vue index 07a03f42b0..7920e73139 100644 --- a/apps/desktop-ui/src/views/WelcomeView.vue +++ b/apps/desktop-ui/src/views/WelcomeView.vue @@ -33,7 +33,7 @@ import { useRouter } from 'vue-router' import BaseViewTemplate from '@/views/templates/BaseViewTemplate.vue' const router = useRouter() -const navigateTo = async (path: string) => { +async function navigateTo(path: string) { await router.push(path) } diff --git a/apps/website/e2e/demos.spec.ts b/apps/website/e2e/demos.spec.ts index bbf333e3e6..d9ce494430 100644 --- a/apps/website/e2e/demos.spec.ts +++ b/apps/website/e2e/demos.spec.ts @@ -3,8 +3,9 @@ import { expect, test } from '@playwright/test' import { demos, getNextDemo } from '../src/config/demos' import { t } from '../src/i18n/translations' -const escapeRegExp = (value: string): string => - value.replace(/[.*+?^${}()|[\]\\]/g, '\\$&') +function escapeRegExp(value: string): string { + return value.replace(/[.*+?^${}()|[\]\\]/g, '\\$&') +} test.describe('Demo pages @smoke', () => { for (const demo of demos) { diff --git a/apps/website/e2e/responsive.spec.ts b/apps/website/e2e/responsive.spec.ts index 6488170457..bd97b624be 100644 --- a/apps/website/e2e/responsive.spec.ts +++ b/apps/website/e2e/responsive.spec.ts @@ -111,7 +111,7 @@ async function measureMarqueeLoopGeometry( `Animation on ${sel} has unusable duration: ${String(duration)}` ) } - const setAllTimes = (time: number) => { + function setAllTimes(time: number) { for (const track of tracks) { for (const anim of track.getAnimations()) { anim.currentTime = time @@ -119,7 +119,9 @@ async function measureMarqueeLoopGeometry( } void document.body.offsetWidth } - const readX = () => tracks.map((track) => track.getBoundingClientRect().x) + function readX() { + return tracks.map((track) => track.getBoundingClientRect().x) + } setAllTimes(0) const startPositions = readX() const copyWidths = tracks.map( diff --git a/apps/website/src/components/careers/RolesSection.vue b/apps/website/src/components/careers/RolesSection.vue index f57a400f02..16e4e57860 100644 --- a/apps/website/src/components/careers/RolesSection.vue +++ b/apps/website/src/components/careers/RolesSection.vue @@ -36,7 +36,9 @@ let pendingFrame = 0 const HEADER_OFFSET = -144 const ACTIVATION_OFFSET = 300 -const deptElementId = (key: string) => `careers-dept-${key}` +function deptElementId(key: string) { + return `careers-dept-${key}` +} function pickActiveSection() { pendingFrame = 0 diff --git a/apps/website/src/components/product/local/HeroSection.vue b/apps/website/src/components/product/local/HeroSection.vue index 8a2d5b7019..ad800db9fc 100644 --- a/apps/website/src/components/product/local/HeroSection.vue +++ b/apps/website/src/components/product/local/HeroSection.vue @@ -58,7 +58,7 @@ onMounted(() => { }) raw.sort((a, b) => { - const norm = (v: number) => { + function norm(v: number) { const r = v + Math.PI / 2 return r < 0 ? r + 2 * Math.PI : r } @@ -117,7 +117,7 @@ onMounted(() => { applyToPanel(panels[1], elapsed2) applyToPanel(panels[2], elapsed3) - const wOf = (elapsed: number) => { + function wOf(elapsed: number) { const progress = elapsed < PANEL_DURATION ? elapsed / PANEL_DURATION : 1 return lerp(S.w, E.w, ease(progress)) } diff --git a/apps/website/src/composables/useParallax.ts b/apps/website/src/composables/useParallax.ts index af0b926de8..ba49420fff 100644 --- a/apps/website/src/composables/useParallax.ts +++ b/apps/website/src/composables/useParallax.ts @@ -35,7 +35,7 @@ export function useParallax( const triggerEl = options.trigger?.value - const createAnimations = () => { + function createAnimations() { const els = elements .map((r) => r.value) .filter((el): el is HTMLElement => !!el && el.offsetParent !== null) diff --git a/apps/website/src/composables/usePinScrub.ts b/apps/website/src/composables/usePinScrub.ts index 0eb68904be..46bbc738d3 100644 --- a/apps/website/src/composables/usePinScrub.ts +++ b/apps/website/src/composables/usePinScrub.ts @@ -29,7 +29,7 @@ function interpolateY( contentH: number, vpH: number ) { - const clampedTarget = (i: number) => { + function clampedTarget(i: number) { const center = buttonCenters[i] ?? 0 return Math.max(-(contentH - vpH), Math.min(0, vpH / 2 - center)) } diff --git a/apps/website/src/pages/cloud/supported-nodes/[pack].astro b/apps/website/src/pages/cloud/supported-nodes/[pack].astro index 1b5fa30f94..c75c959336 100644 --- a/apps/website/src/pages/cloud/supported-nodes/[pack].astro +++ b/apps/website/src/pages/cloud/supported-nodes/[pack].astro @@ -9,7 +9,7 @@ import { t } from '../../../i18n/translations' import { loadPacksForBuild } from '../../../utils/cloudNodes.build' import { escapeJsonLd } from '../../../utils/escapeJsonLd' -export const getStaticPaths: GetStaticPaths = async () => { +export async function getStaticPaths() { const packs = await loadPacksForBuild() return packs.map((pack) => ({ params: { pack: pack.id }, diff --git a/apps/website/src/pages/customers/[slug].astro b/apps/website/src/pages/customers/[slug].astro index 9801b70f09..c9264cb94e 100644 --- a/apps/website/src/pages/customers/[slug].astro +++ b/apps/website/src/pages/customers/[slug].astro @@ -7,7 +7,7 @@ import WhatsNextSection from '../../components/customers/WhatsNextSection.vue' import { customerStories, getNextStory, getStoryBySlug } from '../../config/customerStories' import { t } from '../../i18n/translations' -export const getStaticPaths: GetStaticPaths = () => { +export function getStaticPaths() { return customerStories.map((story) => ({ params: { slug: story.slug } })) diff --git a/apps/website/src/pages/demos/[slug].astro b/apps/website/src/pages/demos/[slug].astro index 79f9d7c963..d828c9698d 100644 --- a/apps/website/src/pages/demos/[slug].astro +++ b/apps/website/src/pages/demos/[slug].astro @@ -8,7 +8,7 @@ import DemoNavSection from '../../components/demos/DemoNavSection.vue' import { demos, getDemoBySlug, getNextDemo } from '../../config/demos' import { t } from '../../i18n/translations' -export const getStaticPaths: GetStaticPaths = () => { +export function getStaticPaths() { return demos.map((demo) => ({ params: { slug: demo.slug } })) diff --git a/apps/website/src/pages/p/supported-models/[slug].astro b/apps/website/src/pages/p/supported-models/[slug].astro index 39a8333526..8f23929f44 100644 --- a/apps/website/src/pages/p/supported-models/[slug].astro +++ b/apps/website/src/pages/p/supported-models/[slug].astro @@ -5,7 +5,7 @@ import ModelHeroSection from '../../../components/models/ModelHeroSection.vue' import { models, getModelBySlug } from '../../../config/models' import { t } from '../../../i18n/translations' -export const getStaticPaths: GetStaticPaths = () => { +export function getStaticPaths() { return models.map((model) => ({ params: { slug: model.slug } })) diff --git a/apps/website/src/pages/zh-CN/cloud/supported-nodes/[pack].astro b/apps/website/src/pages/zh-CN/cloud/supported-nodes/[pack].astro index b74d4ebd27..458b046066 100644 --- a/apps/website/src/pages/zh-CN/cloud/supported-nodes/[pack].astro +++ b/apps/website/src/pages/zh-CN/cloud/supported-nodes/[pack].astro @@ -9,7 +9,7 @@ import { t } from '../../../../i18n/translations' import { loadPacksForBuild } from '../../../../utils/cloudNodes.build' import { escapeJsonLd } from '../../../../utils/escapeJsonLd' -export const getStaticPaths: GetStaticPaths = async () => { +export async function getStaticPaths() { const packs = await loadPacksForBuild() return packs.map((pack) => ({ params: { pack: pack.id }, diff --git a/apps/website/src/pages/zh-CN/customers/[slug].astro b/apps/website/src/pages/zh-CN/customers/[slug].astro index 4775239178..f0251125d5 100644 --- a/apps/website/src/pages/zh-CN/customers/[slug].astro +++ b/apps/website/src/pages/zh-CN/customers/[slug].astro @@ -7,7 +7,7 @@ import WhatsNextSection from '../../../components/customers/WhatsNextSection.vue import { customerStories, getNextStory, getStoryBySlug } from '../../../config/customerStories' import { t } from '../../../i18n/translations' -export const getStaticPaths: GetStaticPaths = () => { +export function getStaticPaths() { return customerStories.map((story) => ({ params: { slug: story.slug } })) diff --git a/apps/website/src/pages/zh-CN/demos/[slug].astro b/apps/website/src/pages/zh-CN/demos/[slug].astro index fb31d3a40a..e7d4e10a72 100644 --- a/apps/website/src/pages/zh-CN/demos/[slug].astro +++ b/apps/website/src/pages/zh-CN/demos/[slug].astro @@ -8,7 +8,7 @@ import DemoNavSection from '../../../components/demos/DemoNavSection.vue' import { demos, getDemoBySlug, getNextDemo } from '../../../config/demos' import { t } from '../../../i18n/translations' -export const getStaticPaths: GetStaticPaths = () => { +export function getStaticPaths() { return demos.map((demo) => ({ params: { slug: demo.slug } })) diff --git a/apps/website/src/scripts/snakeGame.ts b/apps/website/src/scripts/snakeGame.ts index 0dd7503198..7ebc8fbc9e 100644 --- a/apps/website/src/scripts/snakeGame.ts +++ b/apps/website/src/scripts/snakeGame.ts @@ -35,8 +35,9 @@ const TICK_MS = 200 function readColors() { const style = getComputedStyle(document.documentElement) - const get = (name: string, fallback: string): string => - style.getPropertyValue(name).trim() || fallback + function get(name: string, fallback: string): string { + return style.getPropertyValue(name).trim() || fallback + } return { bg: get('--color-primary-comfy-ink', '#211927'), @@ -59,9 +60,12 @@ function requireElement( return el } -const isSVGSVG = (el: Element): el is SVGSVGElement => - el instanceof SVGSVGElement -const isSVGG = (el: Element): el is SVGGElement => el instanceof SVGGElement +function isSVGSVG(el: Element): el is SVGSVGElement { + return el instanceof SVGSVGElement +} +function isSVGG(el: Element): el is SVGGElement { + return el instanceof SVGGElement +} function isSVGText(el: Element): el is SVGTextElement { return el instanceof SVGTextElement } @@ -127,8 +131,9 @@ function depth(cell: Cell): number { function roundedPath(pts: [number, number][], radius: number): string { const n = pts.length - const fmt = (p: readonly [number, number]) => - `${p[0].toFixed(2)},${p[1].toFixed(2)}` + function fmt(p: readonly [number, number]) { + return `${p[0].toFixed(2)},${p[1].toFixed(2)}` + } let d = '' for (let i = 0; i < n; i++) { const prev = pts[(i - 1 + n) % n] @@ -206,7 +211,7 @@ function triggerExplosion() { const cx = ((COLS - ROWS) * STEP_X) / 2 const cy = ((COLS + ROWS - 2) * STEP_Y) / 2 - const launchParticle = (i: number, j: number, fill: string): Particle => { + function launchParticle(i: number, j: number, fill: string): Particle { const [sx, sy] = iso(i, j) const baseAngle = Math.atan2(sy - cy, sx - cx) const angle = baseAngle + (Math.random() - 0.5) * 1.2 @@ -239,7 +244,9 @@ function triggerExplosion() { const DROP_DURATION_MS = 450 const DROP_HEIGHT = 600 let foodDropStart = 0 -const easeOutCubic = (t: number) => 1 - Math.pow(1 - t, 3) +function easeOutCubic(t: number) { + return 1 - Math.pow(1 - t, 3) +} function foodDropOffset(now = performance.now()): number { if (!foodDropStart) return 0 @@ -252,7 +259,7 @@ function foodDropOffset(now = performance.now()): number { const REBIRTH_STAGGER_MS = 90 const REBIRTH_GROW_MS = 260 let rebirthStart = 0 -const easeOutBack = (t: number) => { +function easeOutBack(t: number) { const c1 = 1.70158 const c3 = c1 + 1 return 1 + c3 * Math.pow(t - 1, 3) + c1 * Math.pow(t - 1, 2) @@ -271,7 +278,9 @@ function rebirthScaleFor(idx: number, now = performance.now()): number { const CHOMP_DURATION_MS = 220 const CHOMP_PEAK_SCALE = 1.15 let chompStart = 0 -const easeOut = (t: number) => 1 - (1 - t) * (1 - t) +function easeOut(t: number) { + return 1 - (1 - t) * (1 - t) +} function chompScale(now = performance.now()): number { if (!chompStart) return 1 @@ -299,7 +308,7 @@ function isAnimating(): boolean { function ensureAnimationLoop() { if (animationHandle !== null) return - const tick = () => { + function tick() { if ( explodeStart && performance.now() - explodeStart >= EXPLODE_DURATION_MS @@ -411,8 +420,12 @@ function updateScoreDisplay() { scoreBestEl.textContent = String(best) } -const cellsEqual = (a: Cell, b: Cell) => a.i === b.i && a.j === b.j -const inBounds = (c: Cell) => c.i >= 0 && c.j >= 0 && c.i < COLS && c.j < ROWS +function cellsEqual(a: Cell, b: Cell) { + return a.i === b.i && a.j === b.j +} +function inBounds(c: Cell) { + return c.i >= 0 && c.j >= 0 && c.i < COLS && c.j < ROWS +} function reset() { const j0 = Math.floor(ROWS / 2) diff --git a/browser_tests/fixtures/helpers/AssetHelper.ts b/browser_tests/fixtures/helpers/AssetHelper.ts index 6bcfaa14cf..42bd1d03e5 100644 --- a/browser_tests/fixtures/helpers/AssetHelper.ts +++ b/browser_tests/fixtures/helpers/AssetHelper.ts @@ -158,7 +158,7 @@ export class AssetHelper { statusCode: number, error: string = 'Internal Server Error' ): Promise { - const handler = async (route: Route) => { + async function handler(route: Route) { return route.fulfill({ status: statusCode, json: { error } diff --git a/browser_tests/fixtures/helpers/AssetsHelper.ts b/browser_tests/fixtures/helpers/AssetsHelper.ts index 39c5f94336..b692050f5a 100644 --- a/browser_tests/fixtures/helpers/AssetsHelper.ts +++ b/browser_tests/fixtures/helpers/AssetsHelper.ts @@ -325,7 +325,7 @@ export class AssetsHelper { await this.page.unroute(pattern, existingHandler) } - const handler = async (route: Route) => { + async function handler(route: Route) { await route.fulfill({ status: 200, contentType: 'application/json', diff --git a/browser_tests/fixtures/helpers/NodeReplacementHelper.ts b/browser_tests/fixtures/helpers/NodeReplacementHelper.ts index 31584e7bef..9e542a0210 100644 --- a/browser_tests/fixtures/helpers/NodeReplacementHelper.ts +++ b/browser_tests/fixtures/helpers/NodeReplacementHelper.ts @@ -42,7 +42,7 @@ export async function setupNodeReplacement( options?: AddEventListenerOptions | boolean ) { if (type === 'message' && typeof listener === 'function') { - const wrapped = function (this: WebSocket, event: Event) { + function wrapped(this: WebSocket, event: Event) { const msgEvent = event as MessageEvent if (typeof msgEvent.data === 'string') { try { diff --git a/browser_tests/fixtures/helpers/SubgraphHelper.ts b/browser_tests/fixtures/helpers/SubgraphHelper.ts index 7016049166..76e45f6d32 100644 --- a/browser_tests/fixtures/helpers/SubgraphHelper.ts +++ b/browser_tests/fixtures/helpers/SubgraphHelper.ts @@ -606,7 +606,7 @@ export class SubgraphHelper { ] ): { warnings: string[]; dispose: () => void } { const warnings: string[] = [] - const handler = (msg: ConsoleMessage) => { + function handler(msg: ConsoleMessage) { const text = msg.text() if (patterns.some((p) => text.includes(p))) { warnings.push(text) diff --git a/browser_tests/fixtures/helpers/TemplateHelper.ts b/browser_tests/fixtures/helpers/TemplateHelper.ts index 7ae904e890..fcd730292e 100644 --- a/browser_tests/fixtures/helpers/TemplateHelper.ts +++ b/browser_tests/fixtures/helpers/TemplateHelper.ts @@ -150,7 +150,7 @@ export class TemplateHelper { } async mockThumbnails(): Promise { - const thumbnailHandler = async (route: Route) => { + async function thumbnailHandler(route: Route) { await route.fulfill({ status: 200, path: 'browser_tests/assets/example.webp', diff --git a/browser_tests/fixtures/sharedWorkflowImportFixture.ts b/browser_tests/fixtures/sharedWorkflowImportFixture.ts index 6b6c2894fc..03cc8d32b4 100644 --- a/browser_tests/fixtures/sharedWorkflowImportFixture.ts +++ b/browser_tests/fixtures/sharedWorkflowImportFixture.ts @@ -130,10 +130,12 @@ export const sharedWorkflowImportFixture = base.extend<{ async function mockSharedWorkflowImportFlow( page: Page ): Promise { + function noopResolveResponse() {} let isRecording = false let importEndpointCalled = false let importBody: ImportPublishedAssetsRequest | undefined - let resolvePublicInclusiveInputAssetResponseAfterImport: () => void = () => {} + let resolvePublicInclusiveInputAssetResponseAfterImport: () => void = + noopResolveResponse let publicInclusiveInputAssetResponseAfterImport = new Promise( (resolve) => { resolvePublicInclusiveInputAssetResponseAfterImport = resolve diff --git a/browser_tests/fixtures/utils/litegraphUtils.ts b/browser_tests/fixtures/utils/litegraphUtils.ts index 0036526a65..6d592e7862 100644 --- a/browser_tests/fixtures/utils/litegraphUtils.ts +++ b/browser_tests/fixtures/utils/litegraphUtils.ts @@ -7,7 +7,7 @@ import type { ComfyPage } from '@e2e/fixtures/ComfyPage' import type { Position, Size } from '@e2e/fixtures/types' import { VueNodeFixture } from '@e2e/fixtures/utils/vueNodeFixtures' -export const getMiddlePoint = (pos1: Position, pos2: Position) => { +export function getMiddlePoint(pos1: Position, pos2: Position) { return { x: (pos1.x + pos2.x) / 2, y: (pos1.y + pos2.y) / 2 diff --git a/browser_tests/tests/actionbar.spec.ts b/browser_tests/tests/actionbar.spec.ts index 62dd43359b..8cc3460739 100644 --- a/browser_tests/tests/actionbar.spec.ts +++ b/browser_tests/tests/actionbar.spec.ts @@ -45,7 +45,7 @@ test.describe('Actionbar', { tag: '@ui' }, () => { const requestPromise = comfyPage.page.waitForResponse('**/api/prompt') // Find and set the width on the latent node - const triggerChange = async (value: number) => { + async function triggerChange(value: number) { return await comfyPage.page.evaluate((value) => { const node = window.app!.graph!._nodes.find( (n) => n.type === 'EmptyLatentImage' @@ -59,7 +59,7 @@ test.describe('Actionbar', { tag: '@ui' }, () => { } // Trigger a status websocket message - const triggerStatus = (queueSize: number) => { + function triggerStatus(queueSize: number) { ws.send( JSON.stringify({ type: 'status', @@ -75,7 +75,7 @@ test.describe('Actionbar', { tag: '@ui' }, () => { } // Extract the width from the queue response - const getQueuedWidth = async (resp: Promise) => { + async function getQueuedWidth(resp: Promise) { const obj = await (await resp).json() return obj['__request']['prompt']['5']['inputs']['width'] } diff --git a/browser_tests/tests/canvasLayoutSettings.spec.ts b/browser_tests/tests/canvasLayoutSettings.spec.ts index 1996c8ea71..fe28e79c6b 100644 --- a/browser_tests/tests/canvasLayoutSettings.spec.ts +++ b/browser_tests/tests/canvasLayoutSettings.spec.ts @@ -5,16 +5,18 @@ import { import type { ComfyPage } from '@e2e/fixtures/ComfyPage' import type { Size } from '@e2e/fixtures/types' -const expectedGroupSize = ( +function expectedGroupSize( nodeBounds: Size, padding: number, titleHeight: number -): Size => ({ - width: nodeBounds.width + padding * 2, - // Group height adds one title row above the contained node bounds (which - // themselves already include the node's own title), independent of padding. - height: nodeBounds.height + padding * 2 + titleHeight -}) +): Size { + return { + width: nodeBounds.width + padding * 2, + // Group height adds one title row above the contained node bounds (which + // themselves already include the node's own title), independent of padding. + height: nodeBounds.height + padding * 2 + titleHeight + } +} test.describe('Canvas layout settings', { tag: '@canvas' }, () => { test.describe('Comfy.SnapToGrid.GridSize', () => { @@ -24,7 +26,7 @@ test.describe('Canvas layout settings', { tag: '@canvas' }, () => { await comfyPage.nodeOps.clearGraph() }) - const createNode = async (comfyPage: ComfyPage) => { + async function createNode(comfyPage: ComfyPage) { const note = await comfyPage.nodeOps.addNode('Note', undefined, { x: 0, y: 0 @@ -79,10 +81,10 @@ test.describe('Canvas layout settings', { tag: '@canvas' }, () => { await comfyPage.workflow.loadWorkflow('nodes/single_ksampler') }) - const groupAroundAllNodesWithPadding = async ( + async function groupAroundAllNodesWithPadding( comfyPage: ComfyPage, padding: number - ): Promise => { + ): Promise { await comfyPage.settings.setSetting( 'Comfy.GroupSelectedNodes.Padding', padding @@ -126,15 +128,16 @@ test.describe('Canvas layout settings', { tag: '@canvas' }, () => { test.describe('LiteGraph.ContextMenu.Scaling', () => { const ZOOM_SCALE = 2 - const litegraphContextMenu = (comfyPage: ComfyPage) => - comfyPage.page.locator('.litecontextmenu') + function litegraphContextMenu(comfyPage: ComfyPage) { + return comfyPage.page.locator('.litecontextmenu') + } test.beforeEach(async ({ comfyPage }) => { await comfyPage.workflow.loadWorkflow('widgets/load_image_widget') await comfyPage.canvasOps.setScale(ZOOM_SCALE) }) - const openComboMenu = async (comfyPage: ComfyPage) => { + async function openComboMenu(comfyPage: ComfyPage) { const loadImage = ( await comfyPage.nodeOps.getNodeRefsByType('LoadImage') )[0] diff --git a/browser_tests/tests/canvasModeSelector.spec.ts b/browser_tests/tests/canvasModeSelector.spec.ts index 2e770d3ce4..355b7127a2 100644 --- a/browser_tests/tests/canvasModeSelector.spec.ts +++ b/browser_tests/tests/canvasModeSelector.spec.ts @@ -3,12 +3,14 @@ import { expect } from '@playwright/test' import { comfyPageFixture as test } from '@e2e/fixtures/ComfyPage' -const getLocators = (page: Page) => ({ - trigger: page.getByRole('button', { name: 'Canvas Mode' }), - menu: page.getByRole('menu', { name: 'Canvas Mode' }), - selectItem: page.getByRole('menuitemradio', { name: 'Select' }), - handItem: page.getByRole('menuitemradio', { name: 'Hand' }) -}) +function getLocators(page: Page) { + return { + trigger: page.getByRole('button', { name: 'Canvas Mode' }), + menu: page.getByRole('menu', { name: 'Canvas Mode' }), + selectItem: page.getByRole('menuitemradio', { name: 'Select' }), + handItem: page.getByRole('menuitemradio', { name: 'Hand' }) + } +} const MODES = [ { diff --git a/browser_tests/tests/canvasSettings.spec.ts b/browser_tests/tests/canvasSettings.spec.ts index e026edc284..c3fd62a64d 100644 --- a/browser_tests/tests/canvasSettings.spec.ts +++ b/browser_tests/tests/canvasSettings.spec.ts @@ -7,7 +7,7 @@ import { sleep } from '@e2e/fixtures/utils/timing' const CLIP_NODE_COUNT = 2 -const getClipNodesDragBox = async (comfyPage: ComfyPage) => { +async function getClipNodesDragBox(comfyPage: ComfyPage) { const clipNodes = await comfyPage.nodeOps.getNodeRefsByType('CLIPTextEncode') expect( clipNodes, @@ -242,11 +242,11 @@ test.describe('Canvas settings', { tag: '@canvas' }, () => { * hold), nudge by `(dx, dy)` absolute pixels, then release. Spec-local * because it exists only to probe the CanvasPointer timing thresholds. */ - const holdDragAt = async ( + async function holdDragAt( comfyPage: ComfyPage, pos: { x: number; y: number }, opts: { dx: number; dy: number; holdMs: number } - ) => { + ) { const abs = await comfyPage.canvasOps.toAbsolute(pos) await comfyPage.page.mouse.move(abs.x, abs.y) await comfyPage.page.mouse.down() @@ -383,8 +383,9 @@ test.describe('Canvas settings', { tag: '@canvas' }, () => { // (CI jitter, background throttling, canvas-idle behaviour). Assert the // render-loop throttle value instead — that is what actually governs // frame cadence. - const getFrameGap = (comfyPage: ComfyPage) => - comfyPage.page.evaluate(() => window.app!.canvas.maximumFps * 1000) + function getFrameGap(comfyPage: ComfyPage) { + return comfyPage.page.evaluate(() => window.app!.canvas.maximumFps * 1000) + } test('caps the render loop frame gap', async ({ comfyPage }) => { await comfyPage.settings.setSetting('LiteGraph.Canvas.MaximumFps', 30) diff --git a/browser_tests/tests/changeTracker.spec.ts b/browser_tests/tests/changeTracker.spec.ts index c4087888f9..32198a0923 100644 --- a/browser_tests/tests/changeTracker.spec.ts +++ b/browser_tests/tests/changeTracker.spec.ts @@ -219,7 +219,7 @@ test.describe('Change Tracker', { tag: '@workflow' }, () => { comfyPage }) => { const node = (await comfyPage.nodeOps.getFirstNodeRef())! - const bypassAndPin = async () => { + async function bypassAndPin() { await beforeChange(comfyPage) await comfyPage.keyboard.bypass() await expect(node).toBeBypassed() @@ -228,14 +228,14 @@ test.describe('Change Tracker', { tag: '@workflow' }, () => { await afterChange(comfyPage) } - const collapse = async () => { + async function collapse() { await beforeChange(comfyPage) await node.click('collapse', { moveMouseToEmptyArea: true }) await expect(node).toBeCollapsed() await afterChange(comfyPage) } - const multipleChanges = async () => { + async function multipleChanges() { await beforeChange(comfyPage) // Call other actions that uses begin/endChange await node.click('title') diff --git a/browser_tests/tests/defaultKeybindings.spec.ts b/browser_tests/tests/defaultKeybindings.spec.ts index 54ea64f90d..d608637ade 100644 --- a/browser_tests/tests/defaultKeybindings.spec.ts +++ b/browser_tests/tests/defaultKeybindings.spec.ts @@ -133,10 +133,11 @@ test.describe('Default Keybindings', { tag: '@keyboard' }, () => { await node.click('title') // Normal mode is ALWAYS (0) - const getMode = () => - comfyPage.page.evaluate((nodeId) => { + function getMode() { + return comfyPage.page.evaluate((nodeId) => { return window.app!.canvas.graph!.getNodeById(nodeId)!.mode }, node.id) + } await expect.poll(() => getMode()).toBe(0) diff --git a/browser_tests/tests/dialog.spec.ts b/browser_tests/tests/dialog.spec.ts index 9a6889a38b..995af6e1b3 100644 --- a/browser_tests/tests/dialog.spec.ts +++ b/browser_tests/tests/dialog.spec.ts @@ -290,7 +290,7 @@ test('Blueprint overwrite', { tag: ['@subgraph'] }, async ({ comfyPage }) => { const confirmDialog = comfyPage.confirmDialog.root const { incrementButton } = comfyPage.vueNodes.getInputNumberControls(steps) - const dirtyGraphAndSave = async () => { + async function dirtyGraphAndSave() { await incrementButton.click() await comfyPage.page.keyboard.press('Control+s') } diff --git a/browser_tests/tests/groupCopyPaste.spec.ts b/browser_tests/tests/groupCopyPaste.spec.ts index de6e514663..ee1be198e0 100644 --- a/browser_tests/tests/groupCopyPaste.spec.ts +++ b/browser_tests/tests/groupCopyPaste.spec.ts @@ -21,13 +21,14 @@ test.describe('Group Copy Paste', { tag: ['@canvas'] }, () => { await comfyPage.clipboard.paste() await comfyPage.nextFrame() - const getGroupPositions = () => - comfyPage.page.evaluate(() => + function getGroupPositions() { + return comfyPage.page.evaluate(() => window.app!.graph.groups.map((g: { pos: number[] }) => ({ x: g.pos[0], y: g.pos[1] })) ) + } await expect.poll(getGroupPositions).toHaveLength(2) diff --git a/browser_tests/tests/groupNode.spec.ts b/browser_tests/tests/groupNode.spec.ts index d002d83681..90f06a27f2 100644 --- a/browser_tests/tests/groupNode.spec.ts +++ b/browser_tests/tests/groupNode.spec.ts @@ -137,7 +137,7 @@ test.describe('Group Node', { tag: '@node' }, () => { test('Manage group opens with the correct group selected', async ({ comfyPage }) => { - const makeGroup = async (name: string, type1: string, type2: string) => { + async function makeGroup(name: string, type1: string, type2: string) { const node1 = (await comfyPage.nodeOps.getNodeRefsByType(type1))[0] const node2 = (await comfyPage.nodeOps.getNodeRefsByType(type2))[0] await node1.click('title') @@ -204,7 +204,7 @@ test.describe('Group Node', { tag: '@node' }, () => { test('Reconnects inputs after configuration changed via manage dialog save', async ({ comfyPage }) => { - const expectSingleNode = async (type: string) => { + async function expectSingleNode(type: string) { const nodes = await comfyPage.nodeOps.getNodeRefsByType(type) expect(nodes).toHaveLength(1) return nodes[0] @@ -255,13 +255,13 @@ test.describe('Group Node', { tag: '@node' }, () => { const GROUP_NODE_NAME = 'group_node' // Node name in given workflow const GROUP_NODE_TYPE = `${GROUP_NODE_PREFIX}${GROUP_NODE_NAME}` - const isRegisteredLitegraph = async (comfyPage: ComfyPage) => { + async function isRegisteredLitegraph(comfyPage: ComfyPage) { return await comfyPage.page.evaluate((nodeType: string) => { return !!window.LiteGraph!.registered_node_types[nodeType] }, GROUP_NODE_TYPE) } - const isRegisteredNodeDefStore = async (comfyPage: ComfyPage) => { + async function isRegisteredNodeDefStore(comfyPage: ComfyPage) { await comfyPage.menu.nodeLibraryTab.open() const groupNodesFolderCt = await comfyPage.menu.nodeLibraryTab .getFolder(GROUP_NODE_CATEGORY) @@ -269,10 +269,10 @@ test.describe('Group Node', { tag: '@node' }, () => { return groupNodesFolderCt === 1 } - const verifyNodeLoaded = async ( + async function verifyNodeLoaded( comfyPage: ComfyPage, expectedCount: number - ) => { + ) { expect( await comfyPage.nodeOps.getNodeRefsByType(GROUP_NODE_TYPE) ).toHaveLength(expectedCount) diff --git a/browser_tests/tests/imageCompare.spec.ts b/browser_tests/tests/imageCompare.spec.ts index 1f14565822..daf008561d 100644 --- a/browser_tests/tests/imageCompare.spec.ts +++ b/browser_tests/tests/imageCompare.spec.ts @@ -510,7 +510,7 @@ test.describe('Image Compare', { tag: ['@widget', '@vue-nodes'] }, () => { const brokenAfter = 'http://127.0.0.1:1/broken2.png' const pageErrors: Error[] = [] - const onPageError = (err: Error) => { + function onPageError(err: Error) { pageErrors.push(err) } comfyPage.page.on('pageerror', onPageError) diff --git a/browser_tests/tests/interaction.spec.ts b/browser_tests/tests/interaction.spec.ts index b90338ec60..e43d7c80d0 100644 --- a/browser_tests/tests/interaction.spec.ts +++ b/browser_tests/tests/interaction.spec.ts @@ -82,10 +82,10 @@ test.describe('Node Interaction', () => { } ) - const dragSelectNodes = async ( + async function dragSelectNodes( comfyPage: ComfyPage, clipNodes: NodeReference[] - ) => { + ) { const clipNode1Pos = await clipNodes[0].getPosition() const clipNode2Pos = await clipNodes[1].getPosition() const offset = 64 @@ -117,15 +117,16 @@ test.describe('Node Interaction', () => { }) => { const clipNodes = await comfyPage.nodeOps.getNodeRefsByType('CLIPTextEncode') - const getPositions = () => - Promise.all(clipNodes.map((node) => node.getPosition())) - const testDirection = async ({ + function getPositions() { + return Promise.all(clipNodes.map((node) => node.getPosition())) + } + async function testDirection({ direction, expectedPosition }: { direction: string expectedPosition: (originalPosition: Position) => Position - }) => { + }) { const originalPositions = await getPositions() await dragSelectNodes(comfyPage, clipNodes) await comfyPage.command.executeCommand( @@ -671,7 +672,7 @@ test.describe('Canvas Interaction', { tag: '@screenshot' }, () => { }) test('Cursor style changes when panning', async ({ comfyPage }) => { - const getCursorStyle = async () => { + async function getCursorStyle() { return await comfyPage.page.evaluate(() => { return ( document.getElementById('graph-canvas')!.style.cursor || 'default' @@ -703,7 +704,7 @@ test.describe('Canvas Interaction', { tag: '@screenshot' }, () => { test('Properly resets dragging state after pan mode sequence', async ({ comfyPage }) => { - const getCursorStyle = async () => { + async function getCursorStyle() { return await comfyPage.page.evaluate(() => { return ( document.getElementById('graph-canvas')!.style.cursor || 'default' @@ -878,8 +879,9 @@ test.describe('Load workflow', { tag: '@screenshot' }, () => { ) }) - const generateUniqueFilename = (extension = '') => - `${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 8)}${extension}` + function generateUniqueFilename(extension = '') { + return `${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 8)}${extension}` + } test.describe('Restore all open workflows on reload', () => { let workflowA: string @@ -1077,7 +1079,7 @@ test.describe('Viewport settings', () => { comfyPage, comfyMouse }) => { - const changeTab = async (tab: Locator) => { + async function changeTab(tab: Locator) { await tab.click() await comfyPage.nextFrame() await comfyMouse.move(DefaultGraphPositions.emptySpace) @@ -1406,7 +1408,7 @@ test.describe('Canvas Navigation', { tag: '@screenshot' }, () => { test('Cursor changes appropriately in different modes', async ({ comfyPage }) => { - const getCursorStyle = async () => { + async function getCursorStyle() { return await comfyPage.page.evaluate(() => { return ( document.getElementById('graph-canvas')!.style.cursor || 'default' diff --git a/browser_tests/tests/load3d/gizmoControls.spec.ts b/browser_tests/tests/load3d/gizmoControls.spec.ts index fa666cb4aa..5becf01cd9 100644 --- a/browser_tests/tests/load3d/gizmoControls.spec.ts +++ b/browser_tests/tests/load3d/gizmoControls.spec.ts @@ -3,14 +3,15 @@ import type { Page } from '@playwright/test' import { load3dTest as test } from '@e2e/fixtures/helpers/Load3DFixtures' -const getGizmoConfig = (page: Page) => - page.evaluate(() => { +function getGizmoConfig(page: Page) { + return page.evaluate(() => { const n = window.app!.graph.getNodeById(1) const modelConfig = n?.properties?.['Model Config'] as | { gizmo?: { enabled: boolean; mode: string } } | undefined return modelConfig?.gizmo }) +} test.describe('Load3D Gizmo Controls', () => { test( diff --git a/browser_tests/tests/load3d/load3d.spec.ts b/browser_tests/tests/load3d/load3d.spec.ts index f3ec05cbc1..14230a64b8 100644 --- a/browser_tests/tests/load3d/load3d.spec.ts +++ b/browser_tests/tests/load3d/load3d.spec.ts @@ -155,7 +155,7 @@ test.describe('Load3D', () => { async ({ comfyPage, load3d }) => { await expect(load3d.uploadBackgroundImageButton).toBeVisible() const node = await comfyPage.nodeOps.getNodeRefById(1) - const readBackgroundImage = async () => { + async function readBackgroundImage() { const properties = await node.getProperty>( 'properties' @@ -222,7 +222,7 @@ test.describe('Load3D', () => { await expect(load3d.gridToggleButton).toBeVisible() const node = await comfyPage.nodeOps.getNodeRefById(1) - const readShowGrid = async () => { + async function readShowGrid() { const properties = await node.getProperty>( 'properties' diff --git a/browser_tests/tests/nodeHelp.spec.ts b/browser_tests/tests/nodeHelp.spec.ts index 11cd72b1fd..eb3c845207 100644 --- a/browser_tests/tests/nodeHelp.spec.ts +++ b/browser_tests/tests/nodeHelp.spec.ts @@ -55,7 +55,7 @@ async function setLocaleAndWaitForWorkflowReload( const waitForReload = new Promise((resolve, reject) => { const timeoutAt = performance.now() + 5000 - const tick = () => { + function tick() { if (changeTracker.isLoadingGraph) { sawLoading = true } diff --git a/browser_tests/tests/nodeSearchBox.spec.ts b/browser_tests/tests/nodeSearchBox.spec.ts index ad57ae29e3..911e4cba15 100644 --- a/browser_tests/tests/nodeSearchBox.spec.ts +++ b/browser_tests/tests/nodeSearchBox.spec.ts @@ -166,10 +166,10 @@ test.describe('Node search box', { tag: '@node' }, () => { }) test.describe('Filtering', () => { - const expectFilterChips = async ( + async function expectFilterChips( comfyPage: ComfyPage, expectedTexts: string[] - ) => { + ) { const chips = comfyPage.searchBox.filterChips // Check that the number of chips matches the expected count diff --git a/browser_tests/tests/nodeSearchBoxV2.spec.ts b/browser_tests/tests/nodeSearchBoxV2.spec.ts index 7e014a859e..e9edf5969c 100644 --- a/browser_tests/tests/nodeSearchBoxV2.spec.ts +++ b/browser_tests/tests/nodeSearchBoxV2.spec.ts @@ -243,15 +243,18 @@ test.describe('Node search box V2', { tag: '@node' }, () => { comfyPage }) => { const { searchBoxV2 } = comfyPage - const switchToDesktop = () => - comfyPage.page.setViewportSize({ width: 1280, height: 800 }) - const switchToMobile = () => - comfyPage.page.setViewportSize({ width: 360, height: 800 }) - const expectExpanded = (value: 'true' | 'false') => - expect(searchBoxV2.sidebarToggle).toHaveAttribute( + function switchToDesktop() { + return comfyPage.page.setViewportSize({ width: 1280, height: 800 }) + } + function switchToMobile() { + return comfyPage.page.setViewportSize({ width: 360, height: 800 }) + } + function expectExpanded(value: 'true' | 'false') { + return expect(searchBoxV2.sidebarToggle).toHaveAttribute( 'aria-expanded', value ) + } await switchToDesktop() await searchBoxV2.open() diff --git a/browser_tests/tests/nodeSearchBoxV2Extended.spec.ts b/browser_tests/tests/nodeSearchBoxV2Extended.spec.ts index 3a50e4a887..4d3637e47b 100644 --- a/browser_tests/tests/nodeSearchBoxV2Extended.spec.ts +++ b/browser_tests/tests/nodeSearchBoxV2Extended.spec.ts @@ -312,7 +312,9 @@ test.describe('Node search box V2 extended', { tag: '@node' }, () => { test.describe('Search behavior', () => { test('Search narrows results progressively', async ({ comfyPage }) => { const { searchBoxV2 } = comfyPage - const getCount = () => searchBoxV2.results.count() + function getCount() { + return searchBoxV2.results.count() + } await searchBoxV2.open() diff --git a/browser_tests/tests/painter.spec.ts b/browser_tests/tests/painter.spec.ts index a790a956be..908b50c976 100644 --- a/browser_tests/tests/painter.spec.ts +++ b/browser_tests/tests/painter.spec.ts @@ -758,8 +758,8 @@ test.describe('Painter', { tag: ['@widget', '@vue-nodes'] }, () => { await drawStroke(comfyPage.page, canvas, { yPct: 0.75 }) await comfyPage.nextFrame() - const hasContentAtRow = (yFraction: number) => - canvas.evaluate((el: HTMLCanvasElement, y: number) => { + function hasContentAtRow(yFraction: number) { + return canvas.evaluate((el: HTMLCanvasElement, y: number) => { const ctx = el.getContext('2d') if (!ctx) return false const cy = Math.floor(el.height * y) @@ -769,6 +769,7 @@ test.describe('Painter', { tag: ['@widget', '@vue-nodes'] }, () => { } return false }, yFraction) + } await expect .poll(() => hasContentAtRow(0.25), { diff --git a/browser_tests/tests/propertiesPanel/errorsTabMissingMediaRuntime.spec.ts b/browser_tests/tests/propertiesPanel/errorsTabMissingMediaRuntime.spec.ts index 96954139a6..df87a4da90 100644 --- a/browser_tests/tests/propertiesPanel/errorsTabMissingMediaRuntime.spec.ts +++ b/browser_tests/tests/propertiesPanel/errorsTabMissingMediaRuntime.spec.ts @@ -77,7 +77,7 @@ const cloudUploadRaceTest = comfyPageFixture.extend<{ } cloudUploadAssetStateByPage.set(page, state) - const assetsRouteHandler = async (route: Route) => { + async function assetsRouteHandler(route: Route) { const allAssets = [ cloudDefaultGraphInputAsset, ...(state.isUploadedAssetAvailable ? [cloudUploadedVideoAsset] : []) @@ -149,7 +149,7 @@ async function delayNextUpload(comfyPage: ComfyPage) { releaseUpload = resolve }) - const uploadRouteHandler = async (route: Route) => { + async function uploadRouteHandler(route: Route) { resolveUploadStarted() await release await route.continue() diff --git a/browser_tests/tests/queueNotificationBanners.spec.ts b/browser_tests/tests/queueNotificationBanners.spec.ts index ca64919045..3051b5249c 100644 --- a/browser_tests/tests/queueNotificationBanners.spec.ts +++ b/browser_tests/tests/queueNotificationBanners.spec.ts @@ -15,7 +15,9 @@ const REQUEST_ID_SECONDARY = 2 const REQUEST_ID_MISMATCH = 999 let nextRequestId = 1000 -const newRequestId = () => nextRequestId++ +function newRequestId() { + return nextRequestId++ +} function bannerLocator(page: Page) { return page.getByTestId(TestIds.queue.notificationBanner) diff --git a/browser_tests/tests/remoteWidgets.spec.ts b/browser_tests/tests/remoteWidgets.spec.ts index f5eddc115f..4de2d75f20 100644 --- a/browser_tests/tests/remoteWidgets.spec.ts +++ b/browser_tests/tests/remoteWidgets.spec.ts @@ -6,11 +6,11 @@ import { comfyPageFixture as test } from '@e2e/fixtures/ComfyPage' test.describe('Remote COMBO Widget', { tag: '@widget' }, () => { const mockOptions = ['d', 'c', 'b', 'a'] - const addRemoteWidgetNode = async ( + async function addRemoteWidgetNode( comfyPage: ComfyPage, nodeName: string, count: number = 1 - ) => { + ) { const tab = comfyPage.menu.nodeLibraryTab await tab.open() await tab.getFolder('DevTools').click() @@ -21,24 +21,24 @@ test.describe('Remote COMBO Widget', { tag: '@widget' }, () => { } } - const getWidgetOptions = async ( + async function getWidgetOptions( comfyPage: ComfyPage, nodeName: string - ): Promise => { + ): Promise { return await comfyPage.page.evaluate((name) => { const node = window.app!.graph!.nodes.find((node) => node.title === name) return node!.widgets![0].options.values as string[] | undefined }, nodeName) } - const getWidgetValue = async (comfyPage: ComfyPage, nodeName: string) => { + async function getWidgetValue(comfyPage: ComfyPage, nodeName: string) { return await comfyPage.page.evaluate((name) => { const node = window.app!.graph!.nodes.find((node) => node.title === name) return node!.widgets![0].value }, nodeName) } - const clickRefreshButton = (comfyPage: ComfyPage, nodeName: string) => { + function clickRefreshButton(comfyPage: ComfyPage, nodeName: string) { return comfyPage.page.evaluate((name) => { const node = window.app!.graph!.nodes.find((node) => node.title === name) const buttonWidget = node!.widgets!.find((w) => w.name === 'refresh') diff --git a/browser_tests/tests/selectionToolbox.spec.ts b/browser_tests/tests/selectionToolbox.spec.ts index 03ac01ac1e..74079e730b 100644 --- a/browser_tests/tests/selectionToolbox.spec.ts +++ b/browser_tests/tests/selectionToolbox.spec.ts @@ -13,16 +13,21 @@ test.beforeEach(async ({ comfyPage }) => { const BLUE_COLOR = 'rgb(51, 51, 85)' const RED_COLOR = 'rgb(85, 51, 51)' -const getColorPickerButton = (comfyPage: { page: Page }) => - comfyPage.page.getByTestId(TestIds.selectionToolbox.colorPickerButton) +function getColorPickerButton(comfyPage: { page: Page }) { + return comfyPage.page.getByTestId(TestIds.selectionToolbox.colorPickerButton) +} -const getColorPickerCurrentColor = (comfyPage: { page: Page }) => - comfyPage.page.getByTestId(TestIds.selectionToolbox.colorPickerCurrentColor) +function getColorPickerCurrentColor(comfyPage: { page: Page }) { + return comfyPage.page.getByTestId( + TestIds.selectionToolbox.colorPickerCurrentColor + ) +} -const getColorPickerGroup = (comfyPage: { page: Page }) => - comfyPage.page.getByRole('group').filter({ +function getColorPickerGroup(comfyPage: { page: Page }) { + return comfyPage.page.getByRole('group').filter({ has: comfyPage.page.getByTestId(TestIds.selectionToolbox.colorBlue) }) +} test.describe('Selection Toolbox', { tag: ['@screenshot', '@ui'] }, () => { test.beforeEach(async ({ comfyPage }) => { diff --git a/browser_tests/tests/selectionToolboxSubmenus.spec.ts b/browser_tests/tests/selectionToolboxSubmenus.spec.ts index 0aa2515874..d26b55675c 100644 --- a/browser_tests/tests/selectionToolboxSubmenus.spec.ts +++ b/browser_tests/tests/selectionToolboxSubmenus.spec.ts @@ -19,8 +19,9 @@ test.describe( await comfyPage.nextFrame() }) - const openMoreOptions = (comfyPage: ComfyPage) => - openMoreOptionsMenu(comfyPage, 'KSampler') + function openMoreOptions(comfyPage: ComfyPage) { + return openMoreOptionsMenu(comfyPage, 'KSampler') + } test('hides Node Info from More Options menu when the new menu is disabled', async ({ comfyPage diff --git a/browser_tests/tests/sidebar/sidebarSplitterWidth.spec.ts b/browser_tests/tests/sidebar/sidebarSplitterWidth.spec.ts index 6e955335e9..b4993e882b 100644 --- a/browser_tests/tests/sidebar/sidebarSplitterWidth.spec.ts +++ b/browser_tests/tests/sidebar/sidebarSplitterWidth.spec.ts @@ -114,11 +114,12 @@ test.describe('Sidebar splitter width independence', () => { await dragGutter(comfyPage, 80) // Check that saved sizes sum to ~100% - const getSidebarSizes = () => - comfyPage.page.evaluate(() => { + function getSidebarSizes() { + return comfyPage.page.evaluate(() => { const raw = localStorage.getItem('unified-sidebar') return raw ? (JSON.parse(raw) as number[]) : null }) + } await expect .poll(async () => { diff --git a/browser_tests/tests/subgraph/subgraphBreadcrumb.spec.ts b/browser_tests/tests/subgraph/subgraphBreadcrumb.spec.ts index 30ab964d1f..8901512bb3 100644 --- a/browser_tests/tests/subgraph/subgraphBreadcrumb.spec.ts +++ b/browser_tests/tests/subgraph/subgraphBreadcrumb.spec.ts @@ -25,7 +25,7 @@ const MISSING_NODES_SUBGRAPH_NODE_ID = '2' * the root graph, then the inner subgraph node that appears inside. Matches * how a user navigates via the canvas. */ -const enterNestedSubgraphs = async (comfyPage: ComfyPage) => { +async function enterNestedSubgraphs(comfyPage: ComfyPage) { const outerNode = await comfyPage.nodeOps.getNodeRefById( OUTER_SUBGRAPH_NODE_ID_IN_NESTED ) diff --git a/browser_tests/tests/subgraph/subgraphPromotion.spec.ts b/browser_tests/tests/subgraph/subgraphPromotion.spec.ts index f4f271f17a..344ab3dfdc 100644 --- a/browser_tests/tests/subgraph/subgraphPromotion.spec.ts +++ b/browser_tests/tests/subgraph/subgraphPromotion.spec.ts @@ -689,7 +689,9 @@ test('Can intermix linked and proxy @vue-nodes', async ({ comfyPage }) => { const fromSlot = ksampler.getSlot('steps') const toPos = await comfyPage.subgraph.getInputSlot().getOpenSlotPosition() await fromSlot.dragTo(comfyPage.canvas, { targetPosition: toPos }) - const isConnected = () => comfyPage.vueNodes.isSlotConnected(fromSlot) + function isConnected() { + return comfyPage.vueNodes.isSlotConnected(fromSlot) + } await expect.poll(isConnected).toBe(true) await comfyPage.subgraph.exitViaBreadcrumb() @@ -735,7 +737,9 @@ test('Link already promoted widget @vue-nodes', async ({ comfyPage }) => { const fromSlot = ksampler.getSlot('steps') const toPos = await comfyPage.subgraph.getInputSlot().getOpenSlotPosition() await fromSlot.dragTo(comfyPage.canvas, { targetPosition: toPos }) - const isConnected = () => comfyPage.vueNodes.isSlotConnected(fromSlot) + function isConnected() { + return comfyPage.vueNodes.isSlotConnected(fromSlot) + } await expect.poll(isConnected).toBe(true) await comfyPage.subgraph.exitViaBreadcrumb() @@ -812,7 +816,9 @@ test('Linked widgets can not be demoted @vue-nodes', async ({ comfyPage }) => { const fromSlot = ksampler.getSlot('steps') const toPos = await comfyPage.subgraph.getInputSlot().getOpenSlotPosition() await fromSlot.dragTo(comfyPage.canvas, { targetPosition: toPos }) - const isConnected = () => comfyPage.vueNodes.isSlotConnected(fromSlot) + function isConnected() { + return comfyPage.vueNodes.isSlotConnected(fromSlot) + } await expect.poll(isConnected).toBe(true) await comfyPage.subgraph.exitViaBreadcrumb() diff --git a/browser_tests/tests/subgraph/subgraphSerialization.spec.ts b/browser_tests/tests/subgraph/subgraphSerialization.spec.ts index c843317764..cc9e094c41 100644 --- a/browser_tests/tests/subgraph/subgraphSerialization.spec.ts +++ b/browser_tests/tests/subgraph/subgraphSerialization.spec.ts @@ -368,15 +368,16 @@ test.describe('Subgraph Serialization', { tag: ['@subgraph'] }, () => { ] const SENTINEL_IDS = new Set([-1, -10, -20]) - const isSentinelNodeId = (id: number | string): id is number => - typeof id === 'number' && SENTINEL_IDS.has(id) + function isSentinelNodeId(id: number | string): id is number { + return typeof id === 'number' && SENTINEL_IDS.has(id) + } - const checkEndpoint = ( + function checkEndpoint( label: string, kind: 'origin_id' | 'target_id', id: number | string, g: typeof graph - ): string | null => { + ): string | null { if (isSentinelNodeId(id)) return null if (typeof id !== 'number' || !g._nodes_by_id[id]) { return `${label}: ${kind} ${id} invalid or not found` diff --git a/browser_tests/tests/subgraph/subgraphZeroUuid.spec.ts b/browser_tests/tests/subgraph/subgraphZeroUuid.spec.ts index 3d0a0348f7..fa43257d5c 100644 --- a/browser_tests/tests/subgraph/subgraphZeroUuid.spec.ts +++ b/browser_tests/tests/subgraph/subgraphZeroUuid.spec.ts @@ -14,7 +14,7 @@ test.describe( ) await comfyPage.vueNodes.waitForNodes() - const assertInSubgraph = async (inSubgraph: boolean) => { + async function assertInSubgraph(inSubgraph: boolean) { await expect .poll(() => comfyPage.subgraph.isInSubgraph()) .toBe(inSubgraph) diff --git a/browser_tests/tests/versionMismatchWarnings.spec.ts b/browser_tests/tests/versionMismatchWarnings.spec.ts index b24f798c86..4630eff387 100644 --- a/browser_tests/tests/versionMismatchWarnings.spec.ts +++ b/browser_tests/tests/versionMismatchWarnings.spec.ts @@ -7,9 +7,9 @@ test.describe('Version Mismatch Warnings', { tag: '@slow' }, () => { const ALWAYS_AHEAD_OF_INSTALLED_VERSION = '100.100.100' const ALWAYS_BEHIND_INSTALLED_VERSION = '0.0.0' - const createMockSystemStatsRes = ( + function createMockSystemStatsRes( requiredFrontendVersion: string - ): SystemStats => { + ): SystemStats { return { system: { os: 'posix', diff --git a/browser_tests/tests/vueNodes/groups/groups.spec.ts b/browser_tests/tests/vueNodes/groups/groups.spec.ts index e5b8d586e1..5cb574bc01 100644 --- a/browser_tests/tests/vueNodes/groups/groups.spec.ts +++ b/browser_tests/tests/vueNodes/groups/groups.spec.ts @@ -79,7 +79,7 @@ async function getNodeGroupCenteringErrors( const nodeRect = nodeElement.getBoundingClientRect() - const getCenteringError = (group: GraphGroup): NodeGroupCenteringError => { + function getCenteringError(group: GraphGroup): NodeGroupCenteringError { const [groupStartX, groupStartY] = app.canvasPosToClientPos([ group.pos[0], group.pos[1] diff --git a/browser_tests/tests/vueNodes/interactions/links/linkInteraction.spec.ts b/browser_tests/tests/vueNodes/interactions/links/linkInteraction.spec.ts index 6b0e1b752a..aafaae5b6d 100644 --- a/browser_tests/tests/vueNodes/interactions/links/linkInteraction.spec.ts +++ b/browser_tests/tests/vueNodes/interactions/links/linkInteraction.spec.ts @@ -1151,10 +1151,11 @@ test.describe('Vue Node Widget Link Position', { tag: '@vue-nodes' }, () => { const ksampler = await comfyPage.page.evaluate(() => { const node = window.app!.graph.nodes.find((n) => n.type === 'KSampler') if (!node) return null - const findIndex = (name: string) => - node.inputs.findIndex( + function findIndex(name: string) { + return node.inputs.findIndex( (input) => input.name === name || input.widget?.name === name ) + } return { id: node.id, denoiseIndex: findIndex('denoise'), diff --git a/browser_tests/tests/vueNodes/interactions/node/move.spec.ts b/browser_tests/tests/vueNodes/interactions/node/move.spec.ts index af0ce5761c..2aab4870e2 100644 --- a/browser_tests/tests/vueNodes/interactions/node/move.spec.ts +++ b/browser_tests/tests/vueNodes/interactions/node/move.spec.ts @@ -8,10 +8,10 @@ import type { ComfyPage } from '@e2e/fixtures/ComfyPage' import type { Position } from '@e2e/fixtures/types' test.describe('Vue Node Moving', { tag: '@vue-nodes' }, () => { - const getHeaderPos = async ( + async function getHeaderPos( comfyPage: ComfyPage, title: string - ): Promise<{ x: number; y: number; width: number; height: number }> => { + ): Promise<{ x: number; y: number; width: number; height: number }> { const box = await comfyPage.vueNodes .getNodeByTitle(title) .getByTestId('node-title') @@ -21,27 +21,30 @@ test.describe('Vue Node Moving', { tag: '@vue-nodes' }, () => { return box } - const getLoadCheckpointHeaderPos = async (comfyPage: ComfyPage) => - getHeaderPos(comfyPage, 'Load Checkpoint') + async function getLoadCheckpointHeaderPos(comfyPage: ComfyPage) { + return getHeaderPos(comfyPage, 'Load Checkpoint') + } - const expectPosChanged = async (pos1: Position, pos2: Position) => { + async function expectPosChanged(pos1: Position, pos2: Position) { const diffX = Math.abs(pos2.x - pos1.x) const diffY = Math.abs(pos2.y - pos1.y) expect(diffX).toBeGreaterThan(0) expect(diffY).toBeGreaterThan(0) } - const deltaBetween = (before: Position, after: Position) => ({ - x: after.x - before.x, - y: after.y - before.y - }) + function deltaBetween(before: Position, after: Position) { + return { + x: after.x - before.x, + y: after.y - before.y + } + } - const expectSameDelta = (a: Position, b: Position, tol = 2) => { + function expectSameDelta(a: Position, b: Position, tol = 2) { expect(Math.abs(a.x - b.x)).toBeLessThanOrEqual(tol) expect(Math.abs(a.y - b.y)).toBeLessThanOrEqual(tol) } - const dragFromTabButton = async (comfyPage: ComfyPage, button: Locator) => { + async function dragFromTabButton(comfyPage: ComfyPage, button: Locator) { const box = await button.boundingBox() if (!box) throw new Error('Tab button has no bounding box') const start = { @@ -172,7 +175,7 @@ test.describe('Vue Node Moving', { tag: '@vue-nodes' }, () => { const dx = 120 const dy = 80 - const clickNodeTitleWithMeta = async (title: string) => { + async function clickNodeTitleWithMeta(title: string) { await comfyPage.vueNodes .getNodeByTitle(title) .getByTestId('node-title') diff --git a/browser_tests/tests/vueNodes/widgets/legacy.spec.ts b/browser_tests/tests/vueNodes/widgets/legacy.spec.ts index 9b5ac3adf8..8774805091 100644 --- a/browser_tests/tests/vueNodes/widgets/legacy.spec.ts +++ b/browser_tests/tests/vueNodes/widgets/legacy.spec.ts @@ -15,10 +15,11 @@ test('@vue-nodes In App Mode, widget width updates with panel size', async ({ await comfyPage.appMode.enterAppModeWithInputs([['10', 'legacy_widget']]) }) - const getWidth = () => - comfyPage.page.evaluate( + function getWidth() { + return comfyPage.page.evaluate( () => graph!.getNodeById(10)!.widgets![0].width ?? 0 ) + } await test.step('Mouse clicks resolve to button regions', async () => { const legacyWidget = comfyPage.appMode.linearWidgets.locator('canvas') diff --git a/browser_tests/tests/vueNodes/widgets/text/multilineStringWidget.spec.ts b/browser_tests/tests/vueNodes/widgets/text/multilineStringWidget.spec.ts index f44de55aaa..b5458958fe 100644 --- a/browser_tests/tests/vueNodes/widgets/text/multilineStringWidget.spec.ts +++ b/browser_tests/tests/vueNodes/widgets/text/multilineStringWidget.spec.ts @@ -5,11 +5,15 @@ import { import type { ComfyPage } from '@e2e/fixtures/ComfyPage' test.describe('Vue Multiline String Widget', { tag: '@vue-nodes' }, () => { - const getFirstClipNode = (comfyPage: ComfyPage) => - comfyPage.vueNodes.getNodeByTitle('CLIP Text Encode (Prompt)').first() + function getFirstClipNode(comfyPage: ComfyPage) { + return comfyPage.vueNodes + .getNodeByTitle('CLIP Text Encode (Prompt)') + .first() + } - const getFirstMultilineStringWidget = (comfyPage: ComfyPage) => - getFirstClipNode(comfyPage).getByRole('textbox', { name: 'text' }) + function getFirstMultilineStringWidget(comfyPage: ComfyPage) { + return getFirstClipNode(comfyPage).getByRole('textbox', { name: 'text' }) + } test('should allow entering text', async ({ comfyPage }) => { const textarea = getFirstMultilineStringWidget(comfyPage) diff --git a/browser_tests/tests/widget.spec.ts b/browser_tests/tests/widget.spec.ts index ed70f5b4f8..62ac37ac8c 100644 --- a/browser_tests/tests/widget.spec.ts +++ b/browser_tests/tests/widget.spec.ts @@ -56,8 +56,8 @@ test.describe('Combo text widget', { tag: ['@screenshot', '@widget'] }, () => { test('should refresh combo values of optional inputs', async ({ comfyPage }) => { - const getComboValues = async () => - comfyPage.page.evaluate(() => { + async function getComboValues() { + return comfyPage.page.evaluate(() => { return window .app!.graph!.nodes.find( (node) => node.title === 'Node With Optional Combo Input' @@ -65,6 +65,7 @@ test.describe('Combo text widget', { tag: ['@screenshot', '@widget'] }, () => { .widgets!.find((widget) => widget.name === 'optional_combo_input')! .options.values }) + } await comfyPage.workflow.loadWorkflow('inputs/optional_combo_input') const initialComboValues = await getComboValues() @@ -82,8 +83,8 @@ test.describe('Combo text widget', { tag: ['@screenshot', '@widget'] }, () => { test('Should refresh combo values of nodes with v2 combo input spec', async ({ comfyPage }) => { - const getComboValues = async () => - comfyPage.page.evaluate(() => { + async function getComboValues() { + return comfyPage.page.evaluate(() => { return window .app!.graph!.nodes.find( (node) => node.title === 'Node With V2 Combo Input' @@ -91,6 +92,7 @@ test.describe('Combo text widget', { tag: ['@screenshot', '@widget'] }, () => { .widgets!.find((widget) => widget.name === 'combo_input')!.options .values }) + } await comfyPage.workflow.loadWorkflow('inputs/node_with_v2_combo_input') // click canvas to focus diff --git a/browser_tests/tests/workflowPersistence.spec.ts b/browser_tests/tests/workflowPersistence.spec.ts index 614796119d..2ea610d686 100644 --- a/browser_tests/tests/workflowPersistence.spec.ts +++ b/browser_tests/tests/workflowPersistence.spec.ts @@ -213,10 +213,11 @@ test.describe('Workflow Persistence', () => { .poll(() => comfyPage.nodeOps.getNodeCount()) .toBeGreaterThanOrEqual(2) - const getNodeTypes = () => - comfyPage.page.evaluate(() => + function getNodeTypes() { + return comfyPage.page.evaluate(() => window.app!.graph.nodes.map((n: { type: string }) => n.type) ) + } await expect.poll(getNodeTypes).toContain('KSampler') await expect.poll(getNodeTypes).toContain('EmptyLatentImage') await expect @@ -552,11 +553,12 @@ test.describe('Workflow Persistence', () => { await comfyPage.setup({ clearStorage: false }) await comfyPage.nextFrame() - const getSplitterSizes = () => - comfyPage.page.evaluate(() => { + function getSplitterSizes() { + return comfyPage.page.evaluate(() => { const raw = localStorage.getItem('Comfy.Splitter.MainSplitter') return raw ? (JSON.parse(raw) as number[]) : null }) + } await expect .poll(async () => { diff --git a/browser_tests/utils/backupUtils.ts b/browser_tests/utils/backupUtils.ts index 063e42cc4b..2bd689563b 100644 --- a/browser_tests/utils/backupUtils.ts +++ b/browser_tests/utils/backupUtils.ts @@ -3,9 +3,11 @@ import path from 'path' type PathParts = readonly [string, ...string[]] -const getBackupPath = (originalPath: string): string => `${originalPath}.bak` +function getBackupPath(originalPath: string): string { + return `${originalPath}.bak` +} -const resolvePathIfExists = (pathParts: PathParts): string | null => { +function resolvePathIfExists(pathParts: PathParts): string | null { const resolvedPath = path.resolve(...pathParts) if (!fs.pathExistsSync(resolvedPath)) { console.warn(`Path not found: ${resolvedPath}`) @@ -14,7 +16,7 @@ const resolvePathIfExists = (pathParts: PathParts): string | null => { return resolvedPath } -const createScaffoldingCopy = (srcDir: string, destDir: string) => { +function createScaffoldingCopy(srcDir: string, destDir: string) { // Get all items (files and directories) in the source directory const items = fs.readdirSync(srcDir, { withFileTypes: true }) diff --git a/packages/shared-frontend-utils/src/formatUtil.ts b/packages/shared-frontend-utils/src/formatUtil.ts index 01e52cdd4a..d930ed9f2b 100644 --- a/packages/shared-frontend-utils/src/formatUtil.ts +++ b/packages/shared-frontend-utils/src/formatUtil.ts @@ -195,7 +195,7 @@ export function processDynamicPrompt(input: string): string { let result = '' input = stripComments(input) - const handleEscape = () => { + function handleEscape() { const nextChar = input[i++] return '\\' + nextChar } @@ -347,7 +347,7 @@ export function formatDate(text: string, date: Date) { * Generate a cache key from parameters * Sorts the parameters to ensure consistent keys regardless of parameter order */ -export const paramsToCacheKey = (params: unknown): string => { +export function paramsToCacheKey(params: unknown): string { if (typeof params === 'string') return params if (typeof params === 'object' && params !== null) return Object.keys(params) @@ -362,7 +362,7 @@ export const paramsToCacheKey = (params: unknown): string => { * Generates a RFC4122 compliant UUID v4 using the native crypto API when available * @returns A properly formatted UUID string */ -export const generateUUID = (): string => { +export function generateUUID(): string { // Use native crypto.randomUUID() if available (modern browsers) if ( typeof crypto !== 'undefined' && @@ -379,18 +379,21 @@ export const generateUUID = (): string => { }) } -const isCivitaiHost = (hostname: string): boolean => - hostname === 'civitai.com' || - hostname.endsWith('.civitai.com') || - hostname === 'civitai.red' || - hostname.endsWith('.civitai.red') +function isCivitaiHost(hostname: string): boolean { + return ( + hostname === 'civitai.com' || + hostname.endsWith('.civitai.com') || + hostname === 'civitai.red' || + hostname.endsWith('.civitai.red') + ) +} /** * Checks if a URL belongs to any Civitai domain (civitai.com or civitai.red). * Use this for source-name detection; use `isCivitaiModelUrl` when the URL * must also match a specific model API path format. */ -export const isCivitaiUrl = (url: string): boolean => { +export function isCivitaiUrl(url: string): boolean { if (!isValidUrl(url)) return false return isCivitaiHost(new URL(url).hostname.toLowerCase()) } @@ -403,7 +406,7 @@ export const isCivitaiUrl = (url: string): boolean => { * isCivitaiModelUrl('https://civitai.com/api/v1/models-versions/15342') // true * isCivitaiModelUrl('https://example.com/model.safetensors') // false */ -export const isCivitaiModelUrl = (url: string): boolean => { +export function isCivitaiModelUrl(url: string): boolean { if (!isValidUrl(url)) return false const urlObj = new URL(url) @@ -426,7 +429,7 @@ export const isCivitaiModelUrl = (url: string): boolean => { * 'https://huggingface.co/bfl/FLUX.1/resolve/main/flux1-canny-dev.safetensors?download=true' * ) // https://huggingface.co/bfl/FLUX.1 */ -export const downloadUrlToHfRepoUrl = (url: string): string => { +export function downloadUrlToHfRepoUrl(url: string): string { try { const urlObj = new URL(url) const pathname = urlObj.pathname diff --git a/packages/shared-frontend-utils/src/networkUtil.ts b/packages/shared-frontend-utils/src/networkUtil.ts index 7ae5972326..607b93e082 100644 --- a/packages/shared-frontend-utils/src/networkUtil.ts +++ b/packages/shared-frontend-utils/src/networkUtil.ts @@ -1,7 +1,7 @@ import axios from 'axios' const VALID_STATUS_CODES = [200, 201, 301, 302, 307, 308] -export const checkUrlReachable = async (url: string): Promise => { +export async function checkUrlReachable(url: string): Promise { try { const response = await axios.head(url) // Additional check for successful response diff --git a/scripts/check-unused-i18n-keys.ts b/scripts/check-unused-i18n-keys.ts index 5998369d78..010af1c753 100755 --- a/scripts/check-unused-i18n-keys.ts +++ b/scripts/check-unused-i18n-keys.ts @@ -103,8 +103,9 @@ function shouldIgnoreKey(key: string): boolean { // Search for key usage in source files function isKeyUsed(key: string, sourceFiles: string[]): boolean { // Escape special regex characters - const escapeRegex = (str: string) => - str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&') + function escapeRegex(str: string) { + return str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&') + } const escapedKey = escapeRegex(key) const lastPart = key.split('.').pop() const escapedLastPart = lastPart ? escapeRegex(lastPart) : '' diff --git a/scripts/collect-i18n-general.ts b/scripts/collect-i18n-general.ts index 42ca568a8a..b67564a9fd 100644 --- a/scripts/collect-i18n-general.ts +++ b/scripts/collect-i18n-general.ts @@ -18,7 +18,7 @@ const localePath = './src/locales/en/main.json' const commandsPath = './src/locales/en/commands.json' const settingsPath = './src/locales/en/settings.json' -const extractMenuCommandLocaleStrings = (): Set => { +function extractMenuCommandLocaleStrings(): Set { const labels = new Set() for (const [category, _] of CORE_MENU_COMMANDS) { category.forEach((category) => labels.add(category)) diff --git a/scripts/size-report.js b/scripts/size-report.js index 96f334cdb6..a9b14c874a 100644 --- a/scripts/size-report.js +++ b/scripts/size-report.js @@ -93,7 +93,9 @@ async function buildBundleReport() { * @param {string[]} files * @returns {string[]} */ - const filterFiles = (files) => files.filter((file) => file.endsWith('.json')) + function filterFiles(files) { + return files.filter((file) => file.endsWith('.json')) + } const currFiles = filterFiles(await readdir(currDir)) const baselineFiles = existsSync(prevDir) diff --git a/src/App.vue b/src/App.vue index acc8fdb237..c71f7b9ee0 100644 --- a/src/App.vue +++ b/src/App.vue @@ -34,7 +34,7 @@ watch( { flush: 'post' } ) -const showContextMenu = (event: MouseEvent) => { +function showContextMenu(event: MouseEvent) { const { target } = event switch (true) { case target instanceof HTMLTextAreaElement: diff --git a/src/base/common/downloadUtil.ts b/src/base/common/downloadUtil.ts index aac46ad4ce..88da6041a9 100644 --- a/src/base/common/downloadUtil.ts +++ b/src/base/common/downloadUtil.ts @@ -70,7 +70,7 @@ export function downloadBlob(filename: string, blob: Blob): void { * @param url - The URL to extract filename from * @returns The extracted filename or null if not found */ -const extractFilenameFromUrl = (url: string): string | null => { +function extractFilenameFromUrl(url: string): string | null { try { const urlObj = new URL(url, window.location.origin) return urlObj.searchParams.get('filename') diff --git a/src/base/credits/comfyCredits.ts b/src/base/credits/comfyCredits.ts index b49df573f3..bff5841b60 100644 --- a/src/base/credits/comfyCredits.ts +++ b/src/base/credits/comfyCredits.ts @@ -3,7 +3,7 @@ const DEFAULT_NUMBER_FORMAT: Intl.NumberFormatOptions = { maximumFractionDigits: 2 } -const formatNumber = ({ +function formatNumber({ value, locale, options @@ -11,7 +11,7 @@ const formatNumber = ({ value: number locale?: string options?: Intl.NumberFormatOptions -}): string => { +}): string { const merged: Intl.NumberFormatOptions = { ...DEFAULT_NUMBER_FORMAT, ...options @@ -31,19 +31,25 @@ const formatNumber = ({ export const CREDITS_PER_USD = 211 export const COMFY_CREDIT_RATE_CENTS = CREDITS_PER_USD / 100 // credits per cent -export const usdToCents = (usd: number): number => Math.round(usd * 100) +export function usdToCents(usd: number): number { + return Math.round(usd * 100) +} -export const centsToCredits = (cents: number): number => - Math.round(cents * COMFY_CREDIT_RATE_CENTS) +export function centsToCredits(cents: number): number { + return Math.round(cents * COMFY_CREDIT_RATE_CENTS) +} -export const creditsToCents = (credits: number): number => - Math.round(credits / COMFY_CREDIT_RATE_CENTS) +export function creditsToCents(credits: number): number { + return Math.round(credits / COMFY_CREDIT_RATE_CENTS) +} -export const usdToCredits = (usd: number): number => - Math.round(usd * CREDITS_PER_USD) +export function usdToCredits(usd: number): number { + return Math.round(usd * CREDITS_PER_USD) +} -export const creditsToUsd = (credits: number): number => - Math.round((credits / CREDITS_PER_USD) * 100) / 100 +export function creditsToUsd(credits: number): number { + return Math.round((credits / CREDITS_PER_USD) * 100) / 100 +} export type FormatOptions = { value: number @@ -63,63 +69,68 @@ export type FormatFromUsdOptions = { numberOptions?: Intl.NumberFormatOptions } -export const formatCredits = ({ +export function formatCredits({ value, locale, numberOptions -}: FormatOptions): string => - formatNumber({ value, locale, options: numberOptions }) +}: FormatOptions): string { + return formatNumber({ value, locale, options: numberOptions }) +} -export const formatCreditsFromCents = ({ +export function formatCreditsFromCents({ cents, locale, numberOptions -}: FormatFromCentsOptions): string => - formatCredits({ +}: FormatFromCentsOptions): string { + return formatCredits({ value: centsToCredits(cents), locale, numberOptions }) +} -export const formatCreditsFromUsd = ({ +export function formatCreditsFromUsd({ usd, locale, numberOptions -}: FormatFromUsdOptions): string => - formatCredits({ +}: FormatFromUsdOptions): string { + return formatCredits({ value: usdToCredits(usd), locale, numberOptions }) +} -export const formatUsd = ({ +export function formatUsd({ value, locale, numberOptions -}: FormatOptions): string => - formatNumber({ +}: FormatOptions): string { + return formatNumber({ value, locale, options: numberOptions }) +} -export const formatUsdFromCents = ({ +export function formatUsdFromCents({ cents, locale, numberOptions -}: FormatFromCentsOptions): string => - formatUsd({ +}: FormatFromCentsOptions): string { + return formatUsd({ value: cents / 100, locale, numberOptions }) +} /** * Clamps a USD value to the allowed range for credit purchases * @param value - The USD amount to clamp * @returns The clamped value between $1 and $1000, or 0 if NaN */ -export const clampUsd = (value: number): number => { +export function clampUsd(value: number): number { if (Number.isNaN(value)) return 0 return Math.min(1000, Math.max(1, value)) } diff --git a/src/base/wheelGestures.ts b/src/base/wheelGestures.ts index 3e4f952759..3d708b43b9 100644 --- a/src/base/wheelGestures.ts +++ b/src/base/wheelGestures.ts @@ -14,7 +14,10 @@ * Components that intercept wheel events should suppress the default for * these gestures even when they otherwise let the browser scroll natively. */ -export const isCanvasGestureWheel = (event: WheelEvent): boolean => - event.ctrlKey || - event.metaKey || - Math.abs(event.deltaX) > Math.abs(event.deltaY) +export function isCanvasGestureWheel(event: WheelEvent): boolean { + return ( + event.ctrlKey || + event.metaKey || + Math.abs(event.deltaX) > Math.abs(event.deltaY) + ) +} diff --git a/src/components/MenuHamburger.vue b/src/components/MenuHamburger.vue index 5b4103a495..04a6ac966e 100644 --- a/src/components/MenuHamburger.vue +++ b/src/components/MenuHamburger.vue @@ -29,7 +29,7 @@ import { showNativeSystemMenu } from '@/utils/envUtil' const workspaceState = useWorkspaceStore() const settingStore = useSettingStore() -const exitFocusMode = () => { +function exitFocusMode() { workspaceState.focusMode = false } diff --git a/src/components/TopMenuSection.test.ts b/src/components/TopMenuSection.test.ts index 45262b606a..6901d18b17 100644 --- a/src/components/TopMenuSection.test.ts +++ b/src/components/TopMenuSection.test.ts @@ -328,11 +328,11 @@ describe('TopMenuSection', () => { }) describe('inline progress summary', () => { - const configureSettings = ( + function configureSettings( pinia: ReturnType, qpoV2Enabled: boolean, showRunProgressBar = true - ) => { + ) { const settingStore = useSettingStore(pinia) vi.mocked(settingStore.get).mockImplementation((key) => { if (key === 'Comfy.Queue.QPOV2') return qpoV2Enabled @@ -413,10 +413,10 @@ describe('TopMenuSection', () => { }) describe(QueueNotificationBannerHost, () => { - const configureSettings = ( + function configureSettings( pinia: ReturnType, qpoV2Enabled: boolean - ) => { + ) { const settingStore = useSettingStore(pinia) vi.mocked(settingStore.get).mockImplementation((key) => { if (key === 'Comfy.Queue.QPOV2') return qpoV2Enabled diff --git a/src/components/TopMenuSection.vue b/src/components/TopMenuSection.vue index 6dc7bdf9d5..515838a7a5 100644 --- a/src/components/TopMenuSection.vue +++ b/src/components/TopMenuSection.vue @@ -327,7 +327,7 @@ onBeforeUnmount(() => { legacyContentCheckRafId = null }) -const openCustomNodeManager = async () => { +async function openCustomNodeManager() { try { await managerState.openManager({ initialTab: ManagerTab.All, diff --git a/src/components/actionbar/BatchCountEdit.vue b/src/components/actionbar/BatchCountEdit.vue index 318b9caf68..897649b383 100644 --- a/src/components/actionbar/BatchCountEdit.vue +++ b/src/components/actionbar/BatchCountEdit.vue @@ -92,38 +92,39 @@ watch(batchCount, (nextBatchCount) => { } }) -const clampBatchCount = (nextBatchCount: number): number => - Math.min(Math.max(nextBatchCount, minQueueCount), maxQueueCount.value) +function clampBatchCount(nextBatchCount: number): number { + return Math.min(Math.max(nextBatchCount, minQueueCount), maxQueueCount.value) +} -const setBatchCount = (nextBatchCount: number) => { +function setBatchCount(nextBatchCount: number) { batchCount.value = clampBatchCount(nextBatchCount) batchCountInput.value = String(batchCount.value) } -const incrementBatchCount = () => { +function incrementBatchCount() { setBatchCount(batchCount.value * 2) } -const decrementBatchCount = () => { +function decrementBatchCount() { setBatchCount(Math.floor(batchCount.value / 2)) } -const onInputFocus = () => { +function onInputFocus() { isEditing.value = true } -const onInput = (event: Event) => { +function onInput(event: Event) { const input = event.target as HTMLInputElement batchCountInput.value = input.value.replace(/[^0-9]/g, '') } -const onInputBlur = () => { +function onInputBlur() { isEditing.value = false const parsedInput = Number.parseInt(batchCountInput.value, 10) setBatchCount(Number.isNaN(parsedInput) ? minQueueCount : parsedInput) } -const onInputEnter = () => { +function onInputEnter() { batchCountInputRef.value?.blur() } diff --git a/src/components/actionbar/ComfyActionbar.test.ts b/src/components/actionbar/ComfyActionbar.test.ts index 6593f92277..3902f70426 100644 --- a/src/components/actionbar/ComfyActionbar.test.ts +++ b/src/components/actionbar/ComfyActionbar.test.ts @@ -7,10 +7,10 @@ import ComfyActionbar from '@/components/actionbar/ComfyActionbar.vue' import { i18n } from '@/i18n' import { useSettingStore } from '@/platform/settings/settingStore' -const configureSettings = ( +function configureSettings( pinia: ReturnType, showRunProgressBar: boolean -) => { +) { const settingStore = useSettingStore(pinia) vi.mocked(settingStore.get).mockImplementation((key) => { if (key === 'Comfy.UseNewMenu') return 'Top' @@ -20,7 +20,7 @@ const configureSettings = ( }) } -const renderActionbar = (showRunProgressBar: boolean) => { +function renderActionbar(showRunProgressBar: boolean) { const topMenuContainer = document.createElement('div') document.body.appendChild(topMenuContainer) diff --git a/src/components/actionbar/ComfyActionbar.vue b/src/components/actionbar/ComfyActionbar.vue index 29835a3670..030f46f5d6 100644 --- a/src/components/actionbar/ComfyActionbar.vue +++ b/src/components/actionbar/ComfyActionbar.vue @@ -170,7 +170,7 @@ watchDebounced( ) // Set initial position to bottom center -const setInitialPosition = () => { +function setInitialPosition() { const panel = panelElement.value if (panel) { const screenWidth = window.innerWidth @@ -232,7 +232,7 @@ const lastDragState = ref({ windowWidth: window.innerWidth, windowHeight: window.innerHeight }) -const captureLastDragState = () => { +function captureLastDragState() { lastDragState.value = { x: x.value, y: y.value, @@ -251,7 +251,7 @@ watch( { immediate: true } ) -const adjustMenuPosition = () => { +function adjustMenuPosition() { const panel = panelElement.value if (panel) { const screenWidth = window.innerWidth @@ -312,13 +312,13 @@ useEventListener(window, 'resize', adjustMenuPosition) const isMouseOverDropZone = ref(false) // Mouse event handlers for self-contained drop zone -const onMouseEnterDropZone = () => { +function onMouseEnterDropZone() { if (isDragging.value) { isMouseOverDropZone.value = true } } -const onMouseLeaveDropZone = () => { +function onMouseLeaveDropZone() { if (isDragging.value) { isMouseOverDropZone.value = false } @@ -396,21 +396,21 @@ const queueContextMenuItems = computed(() => [ } ]) -const cancelCurrentJob = async () => { +async function cancelCurrentJob() { if (isExecutionIdle.value) return await commandStore.execute('Comfy.Interrupt') } -const toggleQueueOverlay = () => { +function toggleQueueOverlay() { if (isQueuePanelV2Enabled.value) { sidebarTabStore.toggleSidebarTab('job-history') return } commandStore.execute('Comfy.Queue.ToggleOverlay') } -const showQueueContextMenu = (event: MouseEvent) => { +function showQueueContextMenu(event: MouseEvent) { queueContextMenu.value?.show(event) } -const handleClearQueue = async () => { +async function handleClearQueue() { const pendingJobIds = queueStore.pendingTasks .map((task) => task.jobId) .filter((id): id is string => typeof id === 'string' && id.length > 0) diff --git a/src/components/actionbar/ComfyRunButton/ComfyQueueButton.vue b/src/components/actionbar/ComfyRunButton/ComfyQueueButton.vue index d3a79317a0..313f4b6ef2 100644 --- a/src/components/actionbar/ComfyRunButton/ComfyQueueButton.vue +++ b/src/components/actionbar/ComfyRunButton/ComfyQueueButton.vue @@ -220,7 +220,7 @@ const queueButtonTooltip = computed(() => { }) const commandStore = useCommandStore() -const queuePrompt = async (e: Event) => { +async function queuePrompt(e: Event) { if (isStopInstantAction.value) { queueMode.value = 'instant-idle' return diff --git a/src/components/bottomPanel/BottomPanel.vue b/src/components/bottomPanel/BottomPanel.vue index 37567ab7e5..0d679f1566 100644 --- a/src/components/bottomPanel/BottomPanel.vue +++ b/src/components/bottomPanel/BottomPanel.vue @@ -103,20 +103,20 @@ const isShortcutsTabActive = computed(() => { ) }) -const shouldCapitalizeTab = (tabId: string): boolean => { +function shouldCapitalizeTab(tabId: string): boolean { return tabId !== 'shortcuts-essentials' && tabId !== 'shortcuts-view-controls' } -const getTabDisplayTitle = (tab: BottomPanelExtension): string => { +function getTabDisplayTitle(tab: BottomPanelExtension): string { const title = tab.titleKey ? t(tab.titleKey) : tab.title || '' return shouldCapitalizeTab(tab.id) ? title.toUpperCase() : title } -const openKeybindingSettings = async () => { +async function openKeybindingSettings() { settingsDialog.show('keybinding') } -const closeBottomPanel = () => { +function closeBottomPanel() { bottomPanelStore.activePanel = null } diff --git a/src/components/bottomPanel/tabs/shortcuts/ShortcutsList.vue b/src/components/bottomPanel/tabs/shortcuts/ShortcutsList.vue index b9a9ff6894..47f419d19d 100644 --- a/src/components/bottomPanel/tabs/shortcuts/ShortcutsList.vue +++ b/src/components/bottomPanel/tabs/shortcuts/ShortcutsList.vue @@ -71,7 +71,7 @@ const filteredSubcategories = computed(() => { return result }) -const getSubcategoryTitle = (subcategory: string): string => { +function getSubcategoryTitle(subcategory: string): string { const titleMap: Record = { workflow: t('shortcuts.subcategories.workflow'), node: t('shortcuts.subcategories.node'), @@ -83,7 +83,7 @@ const getSubcategoryTitle = (subcategory: string): string => { return titleMap[subcategory] || subcategory } -const formatKey = (key: string): string => { +function formatKey(key: string): string { const keyMap: Record = { Control: 'Ctrl', Meta: 'Cmd', diff --git a/src/components/bottomPanel/tabs/terminal/BaseTerminal.vue b/src/components/bottomPanel/tabs/terminal/BaseTerminal.vue index 982a68f063..fed98e5137 100644 --- a/src/components/bottomPanel/tabs/terminal/BaseTerminal.vue +++ b/src/components/bottomPanel/tabs/terminal/BaseTerminal.vue @@ -69,7 +69,7 @@ const tooltipText = computed(() => { : t('serverStart.copyAllTooltip') }) -const handleCopy = async () => { +async function handleCopy() { const existingSelection = terminal.getSelection() const shouldSelectAll = !existingSelection if (shouldSelectAll) terminal.selectAll() @@ -87,7 +87,7 @@ const handleCopy = async () => { } } -const showContextMenu = (event: MouseEvent) => { +function showContextMenu(event: MouseEvent) { event.preventDefault() electronAPI()?.showContextMenu({ type: 'text' }) } diff --git a/src/components/bottomPanel/tabs/terminal/CommandTerminal.vue b/src/components/bottomPanel/tabs/terminal/CommandTerminal.vue index 1983a4c4c9..b78d7a5ba1 100644 --- a/src/components/bottomPanel/tabs/terminal/CommandTerminal.vue +++ b/src/components/bottomPanel/tabs/terminal/CommandTerminal.vue @@ -12,10 +12,10 @@ import { electronAPI } from '@/utils/envUtil' import BaseTerminal from './BaseTerminal.vue' -const terminalCreated = ( +function terminalCreated( { terminal, useAutoSize }: ReturnType, root: Ref -) => { +) { const terminalApi = electronAPI().Terminal let offData: IDisposable diff --git a/src/components/bottomPanel/tabs/terminal/LogsTerminal.test.ts b/src/components/bottomPanel/tabs/terminal/LogsTerminal.test.ts index ba4707ce14..0c49cd0577 100644 --- a/src/components/bottomPanel/tabs/terminal/LogsTerminal.test.ts +++ b/src/components/bottomPanel/tabs/terminal/LogsTerminal.test.ts @@ -68,8 +68,8 @@ const i18n = createI18n({ } }) -const renderLogsTerminal = () => - render(LogsTerminal, { +function renderLogsTerminal() { + return render(LogsTerminal, { global: { plugins: [ createTestingPinia({ @@ -81,6 +81,7 @@ const renderLogsTerminal = () => ] } }) +} // Silence the production console.error calls in error-path tests. Vitest // isolates this file's module graph so the spy does not affect other files. @@ -88,7 +89,7 @@ vi.spyOn(console, 'error').mockImplementation(() => {}) // Resolve a getRawLogs call manually to drive deterministic timing in tests // that need to observe behavior mid-fetch. -const deferredRawLogs = () => { +function deferredRawLogs() { let resolve!: (value: { entries: { m: string }[] }) => void let reject!: (err: unknown) => void const promise = new Promise<{ entries: { m: string }[] }>((res, rej) => { diff --git a/src/components/bottomPanel/tabs/terminal/LogsTerminal.vue b/src/components/bottomPanel/tabs/terminal/LogsTerminal.vue index 4360888c43..48da3264e4 100644 --- a/src/components/bottomPanel/tabs/terminal/LogsTerminal.vue +++ b/src/components/bottomPanel/tabs/terminal/LogsTerminal.vue @@ -33,10 +33,10 @@ import BaseTerminal from './BaseTerminal.vue' const terminal = shallowRef() const { errorMessage, loading } = useLogsTerminal(terminal) -const terminalCreated = ( +function terminalCreated( { terminal: instance, useAutoSize }: ReturnType, root: Ref -) => { +) { // Auto-size terminal to fill container width. // minCols: 80 ensures minimum width for colab environments. // See https://github.com/comfyanonymous/ComfyUI/issues/6396 diff --git a/src/components/breadcrumb/SubgraphBreadcrumb.vue b/src/components/breadcrumb/SubgraphBreadcrumb.vue index 742ef4e5c6..0dfa4b99e7 100644 --- a/src/components/breadcrumb/SubgraphBreadcrumb.vue +++ b/src/components/breadcrumb/SubgraphBreadcrumb.vue @@ -125,7 +125,7 @@ const items = computed(() => { const activeItemKey = computed(() => items.value.at(-1)?.key) -const handleBackClick = () => { +function handleBackClick() { void useCommandStore().execute('Comfy.Graph.ExitSubgraph') } diff --git a/src/components/breadcrumb/SubgraphBreadcrumbItem.vue b/src/components/breadcrumb/SubgraphBreadcrumbItem.vue index b1e54ae793..7133c74aea 100644 --- a/src/components/breadcrumb/SubgraphBreadcrumbItem.vue +++ b/src/components/breadcrumb/SubgraphBreadcrumbItem.vue @@ -104,10 +104,7 @@ const itemLabel = ref() const itemInputRef = ref<{ $el?: HTMLInputElement }>() const wrapperRef = ref() -const rename = async ( - newName: string | null | undefined, - initialName: string -) => { +async function rename(newName: string | null | undefined, initialName: string) { if (newName && newName !== initialName) { // Synchronize the node titles with the new name item.updateTitle?.(newName) @@ -144,7 +141,7 @@ const tooltipText = computed(() => { return item.label }) -const startRename = async () => { +async function startRename() { // Check if element is hidden (collapsed breadcrumb) // When collapsed, root item is hidden via CSS display:none, so use rename command if (isRoot && wrapperRef.value?.offsetParent === null) { @@ -167,7 +164,7 @@ const startRename = async () => { const { menuItems } = useWorkflowActionsMenu(startRename, { isRoot }) -const handleClick = (event: MouseEvent) => { +function handleClick(event: MouseEvent) { if (isEditing.value) { return } @@ -186,7 +183,7 @@ const handleClick = (event: MouseEvent) => { } } -const inputBlur = async (doRename: boolean) => { +async function inputBlur(doRename: boolean) { if (doRename) { await rename(itemLabel.value, item.label as string) } diff --git a/src/components/builder/AppModeWidgetList.vue b/src/components/builder/AppModeWidgetList.vue index 8ab4e9bc4f..e2ea7da455 100644 --- a/src/components/builder/AppModeWidgetList.vue +++ b/src/components/builder/AppModeWidgetList.vue @@ -122,7 +122,7 @@ function getDropIndicator(node: LGraphNode) { ? parseImageWidgetValue(stringValue) : { filename: '', subfolder: '', type: 'input' } - const buildImageUrl = () => { + function buildImageUrl() { if (!filename) return undefined const params = new URLSearchParams({ filename, subfolder, type }) appendCloudResParam(params, filename) @@ -154,7 +154,7 @@ function nodeToNodeData(node: LGraphNode) { } async function handleDragDrop() { - const onDragDrop = async (e: DragEvent) => { + async function onDragDrop(e: DragEvent) { for (const { nodeData } of mappedSelections.value) if (nodeData?.onDragOver?.(e) && (await nodeData.onDragDrop?.(e))) return true diff --git a/src/components/builder/useAppModeWidgetResizing.ts b/src/components/builder/useAppModeWidgetResizing.ts index f95ee958fe..d0ea56a2e3 100644 --- a/src/components/builder/useAppModeWidgetResizing.ts +++ b/src/components/builder/useAppModeWidgetResizing.ts @@ -34,15 +34,16 @@ export function useAppModeWidgetResizing( return const resizable = target.closest(RESIZABLE_SELECTOR) if (!resizable || !wrapper.contains(resizable)) return + const resizableEl: HTMLElement = resizable clearPendingHandler() - const startHeight = resizable.offsetHeight - const handler = () => { + const startHeight = resizableEl.offsetHeight + function handler() { window.removeEventListener('pointerup', handler) window.removeEventListener('pointercancel', handler) pendingHandler = null - const height = resizable.offsetHeight + const height = resizableEl.offsetHeight if (height === startHeight) return onResize(nodeId, widgetName, { height }) } diff --git a/src/components/card/Card.stories.ts b/src/components/card/Card.stories.ts index 6c2ec30e87..142651f38f 100644 --- a/src/components/card/Card.stories.ts +++ b/src/components/card/Card.stories.ts @@ -166,29 +166,30 @@ const meta: Meta = { export default meta type Story = StoryObj -const createCardTemplate = (args: CardStoryArgs) => ({ - components: { - CardContainer, - CardTop, - CardBottom, - CardTitle, - CardDescription, - Button, - Tag - }, - setup() { - const favorited = ref(false) - const toggleFavorite = () => { - favorited.value = !favorited.value - } +function createCardTemplate(args: CardStoryArgs) { + return { + components: { + CardContainer, + CardTop, + CardBottom, + CardTitle, + CardDescription, + Button, + Tag + }, + setup() { + const favorited = ref(false) + function toggleFavorite() { + favorited.value = !favorited.value + } - return { - args, - favorited, - toggleFavorite - } - }, - template: ` + return { + args, + favorited, + toggleFavorite + } + }, + template: `
({
` -}) + } +} export const Default: Story = { render: (args: CardStoryArgs) => createCardTemplate(args), diff --git a/src/components/common/BackgroundImageUpload.vue b/src/components/common/BackgroundImageUpload.vue index 72f5af1f25..26151d37ad 100644 --- a/src/components/common/BackgroundImageUpload.vue +++ b/src/components/common/BackgroundImageUpload.vue @@ -49,11 +49,11 @@ const modelValue = defineModel() const fileInput = ref(null) const isUploading = ref(false) -const triggerFileInput = () => { +function triggerFileInput() { fileInput.value?.click() } -const uploadFile = async (file: File): Promise => { +async function uploadFile(file: File): Promise { const body = new FormData() body.append('image', file) body.append('subfolder', 'backgrounds') @@ -74,7 +74,7 @@ const uploadFile = async (file: File): Promise => { return data.subfolder ? `${data.subfolder}/${data.name}` : data.name } -const handleFileUpload = async (event: Event) => { +async function handleFileUpload(event: Event) { const target = event.target as HTMLInputElement if (target.files && target.files[0]) { const file = target.files[0] @@ -100,7 +100,7 @@ const handleFileUpload = async (event: Event) => { } } -const clearImage = () => { +function clearImage() { modelValue.value = '' if (fileInput.value) { fileInput.value.value = '' diff --git a/src/components/common/CustomizationDialog.vue b/src/components/common/CustomizationDialog.vue index 12eac61a1d..eb508cc35e 100644 --- a/src/components/common/CustomizationDialog.vue +++ b/src/components/common/CustomizationDialog.vue @@ -136,13 +136,13 @@ const defaultIcon = iconOptions.find( const selectedIcon = ref(defaultIcon ?? iconOptions[0]) const finalColor = ref(initialColor || nodeBookmarkStore.defaultBookmarkColor) -const resetCustomization = () => { +function resetCustomization() { selectedIcon.value = iconOptions.find((option) => option.value === initialIcon) ?? iconOptions[0] finalColor.value = initialColor || nodeBookmarkStore.defaultBookmarkColor } -const confirmCustomization = () => { +function confirmCustomization() { emit('confirm', selectedIcon.value.value, finalColor.value) visible.value = false } diff --git a/src/components/common/DeviceInfo.vue b/src/components/common/DeviceInfo.vue index ab141cfbc0..0a9cda83bb 100644 --- a/src/components/common/DeviceInfo.vue +++ b/src/components/common/DeviceInfo.vue @@ -28,7 +28,7 @@ const deviceColumns: { field: keyof DeviceStats; header: string }[] = [ { field: 'torch_vram_free', header: 'Torch VRAM Free' } ] -const formatValue = (value: string | number, field: string) => { +function formatValue(value: string | number, field: string) { if ( ['vram_total', 'vram_free', 'torch_vram_total', 'torch_vram_free'].includes( field diff --git a/src/components/common/ExtensionSlot.vue b/src/components/common/ExtensionSlot.vue index 6819e494e7..6a01fa051e 100644 --- a/src/components/common/ExtensionSlot.vue +++ b/src/components/common/ExtensionSlot.vue @@ -23,7 +23,7 @@ const props = defineProps<{ extension: VueExtension | CustomExtension }>() -const mountCustomExtension = (extension: CustomExtension, el: HTMLElement) => { +function mountCustomExtension(extension: CustomExtension, el: HTMLElement) { extension.render(el) } diff --git a/src/components/common/FormImageUpload.vue b/src/components/common/FormImageUpload.vue index 479b84e627..4a582c606c 100644 --- a/src/components/common/FormImageUpload.vue +++ b/src/components/common/FormImageUpload.vue @@ -55,11 +55,11 @@ const emit = defineEmits<{ const fileInput = ref(null) -const triggerFileInput = () => { +function triggerFileInput() { fileInput.value?.click() } -const handleFileUpload = (event: Event) => { +function handleFileUpload(event: Event) { const target = event.target as HTMLInputElement if (target.files && target.files[0]) { const file = target.files[0] @@ -71,7 +71,7 @@ const handleFileUpload = (event: Event) => { } } -const clearImage = () => { +function clearImage() { emit('update:modelValue', '') if (fileInput.value) { fileInput.value.value = '' diff --git a/src/components/common/InputKnob.vue b/src/components/common/InputKnob.vue index 1d67449dab..cbf7475cb6 100644 --- a/src/components/common/InputKnob.vue +++ b/src/components/common/InputKnob.vue @@ -53,7 +53,7 @@ watch( } ) -const updateValue = (newValue: number | null) => { +function updateValue(newValue: number | null) { if (newValue === null) { // If the input is cleared, reset to the minimum value or 0 newValue = Number(props.min) || 0 @@ -74,7 +74,7 @@ const updateValue = (newValue: number | null) => { emit('update:modelValue', newValue) } -const displayValue = (value: number): string => { +function displayValue(value: number): string { updateValue(value) const stepString = (props.step ?? 1).toString() const resolution = stepString.includes('.') diff --git a/src/components/common/InputSlider.vue b/src/components/common/InputSlider.vue index 8d04f1fc9c..5d39f83bda 100644 --- a/src/components/common/InputSlider.vue +++ b/src/components/common/InputSlider.vue @@ -51,7 +51,7 @@ watch( } ) -const updateValue = (newValue: number | null) => { +function updateValue(newValue: number | null) { if (newValue === null) { // If the input is cleared, reset to the minimum value or 0 newValue = Number(props.min) || 0 diff --git a/src/components/common/LazyImage.vue b/src/components/common/LazyImage.vue index 6a5ac08290..6b6363b36a 100644 --- a/src/components/common/LazyImage.vue +++ b/src/components/common/LazyImage.vue @@ -115,12 +115,12 @@ watch( { immediate: true } ) -const onImageLoad = () => { +function onImageLoad() { isImageLoaded.value = true hasError.value = false } -const onImageError = () => { +function onImageError() { hasError.value = true isImageLoaded.value = false } diff --git a/src/components/common/TreeExplorer.vue b/src/components/common/TreeExplorer.vue index b7434be697..767e929423 100644 --- a/src/components/common/TreeExplorer.vue +++ b/src/components/common/TreeExplorer.vue @@ -95,7 +95,7 @@ const renderedRoot = computed>(() => { ? combineTrees(renderedRoot, newFolderNode.value) : renderedRoot }) -const getTreeNodeIcon = (node: TreeExplorerNode) => { +function getTreeNodeIcon(node: TreeExplorerNode) { if (node.getIcon) { const icon = node.getIcon() if (icon) { @@ -111,9 +111,7 @@ const getTreeNodeIcon = (node: TreeExplorerNode) => { const isExpanded = expandedKeys.value?.[node.key] ?? false return isExpanded ? 'pi pi-folder-open' : 'pi pi-folder' } -const fillNodeInfo = ( - node: TreeExplorerNode -): RenderedTreeExplorerNode => { +function fillNodeInfo(node: TreeExplorerNode): RenderedTreeExplorerNode { const children = node.children?.map(fillNodeInfo) ?? [] const totalLeaves = node.leaf ? 1 @@ -128,10 +126,10 @@ const fillNodeInfo = ( isEditingLabel: node.key === renameEditingNode.value?.key } } -const onNodeContentClick = async ( +async function onNodeContentClick( e: MouseEvent, node: RenderedTreeExplorerNode -) => { +) { if (!storeSelectionKeys) { selectionKeys.value = {} } @@ -152,10 +150,10 @@ const extraMenuItems = computed(() => { }) const renameEditingNode = shallowRef | null>(null) const errorHandling = useErrorHandling() -const handleNodeLabelEdit = async ( +async function handleNodeLabelEdit( n: RenderedTreeExplorerNode, newName: string -) => { +) { const node = n as RenderedTreeExplorerNode await errorHandling.wrapWithErrorHandlingAsync( async () => { @@ -174,10 +172,10 @@ const handleNodeLabelEdit = async ( provide(InjectKeyHandleEditLabelFunction, handleNodeLabelEdit) const { t } = useI18n() -const renameCommand = (node: RenderedTreeExplorerNode) => { +function renameCommand(node: RenderedTreeExplorerNode) { renameEditingNode.value = node } -const deleteCommand = async (node: RenderedTreeExplorerNode) => { +async function deleteCommand(node: RenderedTreeExplorerNode) { await node.handleDelete?.() emit('nodeDelete', node) } @@ -217,10 +215,7 @@ const menuItems = computed(() => { })) }) -const handleContextMenu = ( - e: MouseEvent, - node: RenderedTreeExplorerNode -) => { +function handleContextMenu(e: MouseEvent, node: RenderedTreeExplorerNode) { menuTargetNode.value = node emit('contextMenu', node, e) if (menuItems.value.filter((item) => item.visible).length > 0) { @@ -228,10 +223,10 @@ const handleContextMenu = ( } } -const wrapCommandWithErrorHandler = ( +function wrapCommandWithErrorHandler( command: (event: MenuItemCommandEvent) => void, { isAsync = false }: { isAsync: boolean } -) => { +) { const node = menuTargetNode.value return isAsync ? errorHandling.wrapWithErrorHandlingAsync( diff --git a/src/components/common/TreeExplorerTreeNode.vue b/src/components/common/TreeExplorerTreeNode.vue index 1982f7d711..22fe115856 100644 --- a/src/components/common/TreeExplorerTreeNode.vue +++ b/src/components/common/TreeExplorerTreeNode.vue @@ -79,15 +79,16 @@ const showNodeBadgeText = computed(() => nodeBadgeText.value !== '') const isEditing = computed(() => props.node.isEditingLabel ?? false) const handleEditLabel = inject(InjectKeyHandleEditLabelFunction) -const handleRename = (newName: string) => { +function handleRename(newName: string) { handleEditLabel?.(props.node as RenderedTreeExplorerNode, newName) } const container = ref(null) const canDrop = ref(false) -const treeNodeElementGetter = () => - container.value?.closest('.p-tree-node-content') as HTMLElement +function treeNodeElementGetter() { + return container.value?.closest('.p-tree-node-content') as HTMLElement +} if (props.node.draggable) { usePragmaticDraggable(treeNodeElementGetter, { diff --git a/src/components/common/TreeExplorerV2Node.vue b/src/components/common/TreeExplorerV2Node.vue index 1104d857fc..0abbbfcc00 100644 --- a/src/components/common/TreeExplorerV2Node.vue +++ b/src/components/common/TreeExplorerV2Node.vue @@ -159,7 +159,7 @@ function deleteBlueprint() { void subgraphStore.deleteBlueprint(nodeDef.value.name) } } -const editBlueprint = async () => { +async function editBlueprint() { if (!nodeDef.value) throw new Error( 'Failed to edit subgraph blueprint lacking backing node data' diff --git a/src/components/common/UrlInput.vue b/src/components/common/UrlInput.vue index df40ba0c40..cc6322de82 100644 --- a/src/components/common/UrlInput.vue +++ b/src/components/common/UrlInput.vue @@ -44,8 +44,9 @@ const emit = defineEmits<{ const validationState = ref(ValidationState.IDLE) -const cleanInput = (value: string): string => - value ? value.replace(/\s+/g, '') : '' +function cleanInput(value: string): string { + return value ? value.replace(/\s+/g, '') : '' +} // Add internal value state const internalValue = ref(cleanInput(props.modelValue)) @@ -68,14 +69,14 @@ onMounted(async () => { await validateUrl(props.modelValue) }) -const handleInput = (value: string | undefined) => { +function handleInput(value: string | undefined) { // Update internal value without emitting internalValue.value = cleanInput(value ?? '') // Reset validation state when user types validationState.value = ValidationState.IDLE } -const handleBlur = async () => { +async function handleBlur() { const input = cleanInput(internalValue.value) let normalizedUrl = input @@ -91,7 +92,7 @@ const handleBlur = async () => { } // Default validation implementation -const defaultValidateUrl = async (url: string): Promise => { +async function defaultValidateUrl(url: string): Promise { if (!isValidUrl(url)) return false try { return await checkUrlReachable(url) @@ -100,7 +101,7 @@ const defaultValidateUrl = async (url: string): Promise => { } } -const validateUrl = async (value: string) => { +async function validateUrl(value: string) { if (validationState.value === ValidationState.LOADING) return const url = cleanInput(value) diff --git a/src/components/common/UserAvatar.vue b/src/components/common/UserAvatar.vue index 48a7add134..0e8bd298da 100644 --- a/src/components/common/UserAvatar.vue +++ b/src/components/common/UserAvatar.vue @@ -25,7 +25,7 @@ const { photoUrl, ariaLabel } = defineProps<{ }>() const imageError = ref(false) -const handleImageError = () => { +function handleImageError() { imageError.value = true } const hasAvatar = computed(() => photoUrl && !imageError.value) diff --git a/src/components/common/UserCredit.test.ts b/src/components/common/UserCredit.test.ts index 352010dfb9..ed5a40190a 100644 --- a/src/components/common/UserCredit.test.ts +++ b/src/components/common/UserCredit.test.ts @@ -50,7 +50,7 @@ describe('UserCredit', () => { mockIsFetchingBalance.value = false }) - const renderComponent = (props = {}) => { + function renderComponent(props = {}) { const i18n = createI18n({ legacy: false, locale: 'en', diff --git a/src/components/custom/widget/WorkflowTemplateSelectorDialog.vue b/src/components/custom/widget/WorkflowTemplateSelectorDialog.vue index 63995bcb6e..ae92a8d81f 100644 --- a/src/components/custom/widget/WorkflowTemplateSelectorDialog.vue +++ b/src/components/custom/widget/WorkflowTemplateSelectorDialog.vue @@ -452,7 +452,7 @@ onMounted(() => { }) // Wrap onClose to track session end -const onClose = () => { +function onClose() { if (isCloud) { const timeSpentSeconds = Math.floor( (Date.now() - sessionStartTime.value) / 1000 @@ -479,23 +479,26 @@ const { getTemplateDescription } = useTemplateWorkflows() -const getEffectiveSourceModule = (template: TemplateInfo) => - template.sourceModule || 'default' +function getEffectiveSourceModule(template: TemplateInfo) { + return template.sourceModule || 'default' +} -const isAppTemplate = (template: TemplateInfo) => template.name.endsWith('.app') +function isAppTemplate(template: TemplateInfo) { + return template.name.endsWith('.app') +} -const getBaseThumbnailSrc = (template: TemplateInfo) => { +function getBaseThumbnailSrc(template: TemplateInfo) { const sm = getEffectiveSourceModule(template) return getTemplateThumbnailUrl(template, sm, sm === 'default' ? '1' : '') } -const getOverlayThumbnailSrc = (template: TemplateInfo) => { +function getOverlayThumbnailSrc(template: TemplateInfo) { const sm = getEffectiveSourceModule(template) return getTemplateThumbnailUrl(template, sm, sm === 'default' ? '2' : '') } // Open tutorial in new tab -const openTutorial = (template: TemplateInfo) => { +function openTutorial(template: TemplateInfo) { if (template.tutorialUrl) { window.open(template.tutorialUrl, '_blank') } @@ -579,7 +582,7 @@ const { */ const searchInput = ref(searchQuery.value) -const applySearchQuery = async (query: string) => { +async function applySearchQuery(query: string) { searchQuery.value = query } @@ -596,7 +599,7 @@ watch(searchQuery, (value) => { * create deterministic, predictable behavior. * @param source The origin of the change ('nav' or 'sort'). */ -const coordinateNavAndSort = (source: 'nav' | 'sort') => { +function coordinateNavAndSort(source: 'nav' | 'sort') { const isPopularNav = selectedNavItem.value === 'popular' const isPopularSort = sortBy.value === 'popular' @@ -810,7 +813,7 @@ watch( ) // Methods -const onLoadWorkflow = async (template: TemplateInfo) => { +async function onLoadWorkflow(template: TemplateInfo) { loadingTemplate.value = template.name try { await loadWorkflowTemplate( diff --git a/src/components/dialog/UnloadWindowConfirmDialog.vue b/src/components/dialog/UnloadWindowConfirmDialog.vue index 32ccedaa9a..9539485fcd 100644 --- a/src/components/dialog/UnloadWindowConfirmDialog.vue +++ b/src/components/dialog/UnloadWindowConfirmDialog.vue @@ -18,7 +18,7 @@ import { useWorkflowStore } from '@/platform/workflow/management/stores/workflow const settingStore = useSettingStore() const workflowStore = useWorkflowStore() -const handleBeforeUnload = (event: BeforeUnloadEvent) => { +function handleBeforeUnload(event: BeforeUnloadEvent) { if ( settingStore.get('Comfy.Window.UnloadConfirmation') && workflowStore.modifiedWorkflows.length > 0 diff --git a/src/components/dialog/content/ApiNodesSignInContent.vue b/src/components/dialog/content/ApiNodesSignInContent.vue index 20ccb38fb6..57bd78b8a9 100644 --- a/src/components/dialog/content/ApiNodesSignInContent.vue +++ b/src/components/dialog/content/ApiNodesSignInContent.vue @@ -45,7 +45,7 @@ const { apiNodeNames, onLogin, onCancel } = defineProps<{ onCancel?: () => void }>() -const handleLearnMoreClick = () => { +function handleLearnMoreClick() { window.open( buildDocsUrl('/tutorials/api-nodes/faq', { includeLocale: true }), '_blank' diff --git a/src/components/dialog/content/ConfirmationDialogContent.vue b/src/components/dialog/content/ConfirmationDialogContent.vue index 683f0b9781..0a5fadd616 100644 --- a/src/components/dialog/content/ConfirmationDialogContent.vue +++ b/src/components/dialog/content/ConfirmationDialogContent.vue @@ -61,14 +61,18 @@ {{ $t('g.cancel') }} - - @@ -94,7 +98,7 @@