Always live-scan Studio 2 LoRAs on load and Refresh like Settings.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Towsty
2026-09-18 12:59:06 -05:00
co-authored by Cursor
parent 7221b6a8cf
commit b194b3cefa
4 changed files with 36 additions and 27 deletions
+15 -9
View File
@@ -34,26 +34,32 @@ test('hidden xAIGen canvas and family render no image or video elements',async()
test('cached LoRAs survive sleeping GPU and failed explicit refresh',async()=>{
const cache={image:['Klein/portrait.safetensors'],video:['motion.safetensors']};let queried=0
const opts={read:()=>cache,write:()=>assert.fail('Do not erase cache'),live:async()=>{queried++;throw Error('Comfy asleep')}}
assert.deepEqual(await cachedLoras(opts),cache);assert.equal(queried,0);assert.deepEqual(await cachedLoras({...opts,fresh:true}),cache);assert.equal(queried,1)
assert.deepEqual(await cachedLoras(opts),cache);assert.equal(queried,1)
assert.deepEqual(await cachedLoras({...opts,fresh:true}),cache);assert.equal(queried,2)
})
test('fresh LoRA refresh replaces disk cache so new Comfy names appear',async()=>{
test('bench load and Refresh always live-scan and replace disk so new Comfy names appear',async()=>{
let store={image:['old.safetensors'],video:['old-vid.safetensors']}
const next=await cachedLoras({
read:()=>store,
write:value=>{store=value},
live:async()=>({image:['old.safetensors','new-drop.safetensors'],video:['old-vid.safetensors']}),
fresh:true
live:async()=>({image:['old.safetensors','klein-pokemon_anime_style_klein9b.safetensors'],video:['old-vid.safetensors']}),
fresh:false
})
assert.deepEqual(next.image,['old.safetensors','new-drop.safetensors'])
assert.deepEqual(store.image,['old.safetensors','new-drop.safetensors'])
assert.ok(next.image.includes('klein-pokemon_anime_style_klein9b.safetensors'))
assert.deepEqual(store.image,next.image)
const removed=await cachedLoras({
read:()=>store,
write:value=>{store=value},
live:async()=>({image:['new-drop.safetensors'],video:[]}),
live:async()=>({image:['klein-pokemon_anime_style_klein9b.safetensors'],video:[]}),
fresh:true
})
assert.deepEqual(removed,{image:['new-drop.safetensors'],video:[]})
assert.deepEqual(store,{image:['new-drop.safetensors'],video:[]})
assert.deepEqual(removed,{image:['klein-pokemon_anime_style_klein9b.safetensors'],video:[]})
})
test('bench mounts and Refresh LoRAs request a live scan',()=>{
const src=readFileSync(new URL('../components/studio2/Bench.vue',import.meta.url),'utf8')
assert.match(src,/void loadLoras\(true\)/)
assert.match(src,/loadLoras\(true\)/)
assert.match(src,/\/api\/studio-2\/loras'\+\(fresh\?'\?fresh=1':''\)/)
})
test('source/hero actions are independent and full input restores structured settings',()=>{
const form={identityStillId:'hero',imageAId:'source',promptSections:{action:'old'},settings:{}}