Fix LoRA folder drops not appearing without weakening engine filters.
Stop empty Comfy blips from freezing the LoRA cache timestamp, and refresh the picker list from Comfy on each poll. Engine tagging (flux/krea) and xaigen platform filtering stay as they were. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -1,7 +1,8 @@
|
||||
import { listStudioLoras } from '~/server/utils/loras'
|
||||
|
||||
export default defineEventHandler(async () => {
|
||||
const listed = await listStudioLoras()
|
||||
export default defineEventHandler(async (event) => {
|
||||
const fresh = String(getQuery(event).fresh || '') === '1'
|
||||
const listed = await listStudioLoras({ fresh })
|
||||
return {
|
||||
image: listed.image,
|
||||
video: listed.video
|
||||
|
||||
+25
-7
@@ -142,10 +142,12 @@ async function discoverFromHost(via: 'video' | 'image') {
|
||||
return { image, video }
|
||||
}
|
||||
|
||||
async function loadLoraCache(): Promise<LoraCache> {
|
||||
async function loadLoraCache(options: { fresh?: boolean } = {}): Promise<LoraCache> {
|
||||
const fresh = options.fresh === true
|
||||
const now = Date.now()
|
||||
if (cache && now - cache.at < CACHE_MS) return cache
|
||||
if (inflight) return inflight
|
||||
if (!fresh && cache && now - cache.at < CACHE_MS) return cache
|
||||
if (inflight && (!fresh || inflightFresh)) return inflight
|
||||
inflightFresh = fresh
|
||||
inflight = (async () => {
|
||||
const videoHost = comfyConfigured() ? getComfyHost() : ''
|
||||
const imageHost = getBeastImageHost()
|
||||
@@ -161,23 +163,39 @@ async function loadLoraCache(): Promise<LoraCache> {
|
||||
image: uniqueNames([...image.image, ...video.image]),
|
||||
video: uniqueNames([...video.video, ...image.video])
|
||||
}
|
||||
// Comfy asleep / unreachable returns empty. Keep the last good list so the picker does not vanish.
|
||||
// Comfy asleep / unreachable returns empty. Keep the last good list so the picker
|
||||
// does not vanish — but do NOT refresh `at`, or a blip freezes new folder drops out.
|
||||
if (!next.image.length && !next.video.length && cache && (cache.image.length || cache.video.length)) {
|
||||
cache = { ...cache, at: Date.now() }
|
||||
return cache
|
||||
}
|
||||
// Prefer the richer list when a partial reply would shrink a known catalog.
|
||||
if (
|
||||
cache
|
||||
&& (next.image.length + next.video.length) < (cache.image.length + cache.video.length)
|
||||
&& next.image.every(name => cache!.image.includes(name) || cache!.video.includes(name))
|
||||
&& next.video.every(name => cache!.image.includes(name) || cache!.video.includes(name))
|
||||
) {
|
||||
const merged: LoraCache = {
|
||||
at: Date.now(),
|
||||
image: uniqueNames([...cache.image, ...next.image]),
|
||||
video: uniqueNames([...cache.video, ...next.video])
|
||||
}
|
||||
cache = merged
|
||||
return merged
|
||||
}
|
||||
cache = next
|
||||
return next
|
||||
})().finally(() => {
|
||||
inflight = null
|
||||
inflightFresh = false
|
||||
})
|
||||
return inflight
|
||||
}
|
||||
|
||||
export async function listStudioLoras() {
|
||||
export async function listStudioLoras(options: { fresh?: boolean } = {}) {
|
||||
const xaigen = isXaigenStudio()
|
||||
try {
|
||||
const listed = await loadLoraCache()
|
||||
const listed = await loadLoraCache(options)
|
||||
return {
|
||||
at: listed.at,
|
||||
image: filterLorasForStudio(listed.image, xaigen),
|
||||
|
||||
Reference in New Issue
Block a user