diff --git a/src/components/helpcenter/HelpCenterMenuContent.vue b/src/components/helpcenter/HelpCenterMenuContent.vue index deb14854c2..93d5398b75 100644 --- a/src/components/helpcenter/HelpCenterMenuContent.vue +++ b/src/components/helpcenter/HelpCenterMenuContent.vue @@ -482,7 +482,7 @@ const calculateSubmenuPosition = (button: HTMLElement): CSSProperties => { } const formatReleaseDate = (dateString?: string): string => { - if (!dateString) return 'date' + if (!dateString) return t('helpCenter.missingDate') const diffMs = Math.abs(Date.now() - new Date(dateString).getTime()) return formatRelativeTime(t, diffMs) } diff --git a/src/locales/en/main.json b/src/locales/en/main.json index 6abb6ce8d9..e9eb837193 100644 --- a/src/locales/en/main.json +++ b/src/locales/en/main.json @@ -1020,7 +1020,8 @@ "updateComfyUIStartedDetail": "ComfyUI update has been queued. Please wait...", "updateComfyUISuccess": "Update Complete", "updateComfyUISuccessDetail": "ComfyUI has been updated. Rebooting...", - "updateComfyUIFailed": "Failed to update ComfyUI. Please try again." + "updateComfyUIFailed": "Failed to update ComfyUI. Please try again.", + "missingDate": "Date unavailable" }, "releaseToast": { "newVersionAvailable": "New update is out!", diff --git a/src/platform/dev/backfillServerDeprecations.test.ts b/src/platform/dev/backfillServerDeprecations.test.ts index 69c9e490e0..139fbdc425 100644 --- a/src/platform/dev/backfillServerDeprecations.test.ts +++ b/src/platform/dev/backfillServerDeprecations.test.ts @@ -136,6 +136,22 @@ describe('backfillServerDeprecations', () => { expect(api.getRawLogs).toHaveBeenCalledTimes(1) }) + it('dedupes concurrent callers to a single fetch', async () => { + const api = mockState.api + api.getRawLogs.mockResolvedValue({ entries: [] }) + + const { backfillServerDeprecations } = + await import('@/platform/dev/backfillServerDeprecations') + + await Promise.all([ + backfillServerDeprecations(), + backfillServerDeprecations(), + backfillServerDeprecations() + ]) + + expect(api.getRawLogs).toHaveBeenCalledTimes(1) + }) + it('retries on a subsequent call after a failure', async () => { const api = mockState.api api.getRawLogs diff --git a/src/platform/dev/backfillServerDeprecations.ts b/src/platform/dev/backfillServerDeprecations.ts index ae2e66d619..899e1d08be 100644 --- a/src/platform/dev/backfillServerDeprecations.ts +++ b/src/platform/dev/backfillServerDeprecations.ts @@ -5,38 +5,50 @@ const PREFIX = '[DEPRECATION WARNING]' const LEGACY_API_PATH_REGEX = /:\s*(\S+?)\.\s+This is likely caused/ let backfilled = false +let backfillInProgress: Promise | null = null /** * Seed the store from the backend's raw log buffer. */ export async function backfillServerDeprecations(): Promise { if (backfilled) return - try { - const logs = await api.getRawLogs() - const store = useDeprecationWarningsStore() - for (const entry of logs.entries) { - if (!entry.m.includes(PREFIX)) continue - const path = LEGACY_API_PATH_REGEX.exec(entry.m)?.[1] - if (path) { - store.report({ - message: `Legacy API import: ${path}`, - suggestion: - 'Update the extension that imports this file, or ask its author to migrate.', - source: 'server' - }) - } else { - console.warn( - 'Server deprecation log did not match legacy-API template; falling back to raw line. Update LEGACY_API_PATH_REGEX:', - entry.m - ) - store.report({ - message: entry.m.trim(), - source: 'server' - }) + if (backfillInProgress) return backfillInProgress + + backfillInProgress = (async () => { + try { + const logs = await api.getRawLogs() + const store = useDeprecationWarningsStore() + for (const entry of logs.entries) { + if (!entry.m.includes(PREFIX)) continue + const path = LEGACY_API_PATH_REGEX.exec(entry.m)?.[1] + if (path) { + store.report({ + message: `Legacy API import: ${path}`, + suggestion: + 'Update the extension that imports this file, or ask its author to migrate.', + source: 'server' + }) + } else { + console.warn( + 'Server deprecation log did not match legacy-API template; falling back to raw line. Update LEGACY_API_PATH_REGEX:', + entry.m + ) + store.report({ + message: entry.m.trim(), + source: 'server' + }) + } } + backfilled = true + } catch (err) { + console.error( + 'Failed to fetch initial server logs for deprecations:', + err + ) + } finally { + backfillInProgress = null } - backfilled = true - } catch (err) { - console.error('Failed to fetch initial server logs for deprecations:', err) - } + })() + + return backfillInProgress }