Stop polling the library catalog and keep the stage on thumbs.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Towsty
2026-09-29 20:15:03 -05:00
co-authored by Cursor
parent cfabfd37ee
commit a465dd68ec
7 changed files with 294 additions and 182 deletions
+9 -17
View File
@@ -3,29 +3,21 @@ import { publicLibrary, publicLibraryPage } from '~/server/utils/library'
export default defineEventHandler((event) => {
const query = getQuery(event)
const light = String(query.light || '') === '1'
const full = String(query.full || '') === '1'
const limitRaw = query.limit
const wantsPage = limitRaw != null && String(limitRaw) !== ''
const hasLimit = limitRaw != null && String(limitRaw) !== ''
// Default GET /api/library → page helper (limit 50). Opt into full catalog with full=1 or legacy light=1.
const wantsFull = full || (light && !hasLimit)
if (wantsPage) {
const page = publicLibraryPage(event, {
limit: Number(limitRaw) || 50,
if (!wantsFull) {
return publicLibraryPage(event, {
limit: hasLimit ? Number(limitRaw) || 50 : 50,
cursor: String(query.cursor || ''),
folderId: String(query.folderId || query.folder || ''),
type: String(query.type || query.filter || 'all')
})
try {
const { owner } = assertLibraryOwner(event)
const folderId = page.folders.find(folder => folder.unlocked)?.id
void maintainLibrary(owner, folderId).catch(() => null)
} catch { /* locked or anonymous */ }
return page
}
const library = publicLibrary(event, { light })
try {
const { owner } = assertLibraryOwner(event)
const folderId = library.folders.find(folder => folder.unlocked)?.id
void maintainLibrary(owner, folderId).catch(() => null)
} catch { /* locked or anonymous — still return what we can */ }
return library
// Full catalog path — no thumb prewarm on the request (thumbs build on /thumb hit)
return publicLibrary(event, { light: true })
})
+11 -4
View File
@@ -25,11 +25,18 @@ export default defineEventHandler(async (event) => {
assertFolderAccess(event, getStill(owner, id).folderId);
if (request.startClipId)
assertFolderAccess(event, getClip(owner, request.startClipId).folderId);
// Header-only size probe — never decode the archive PNG on Generate click
await resolveRequestSize(owner,request);
const id = crypto.randomUUID(), record = { id, owner, request, state: 'waiting', queuedAt: Date.now(), familyId: crypto.randomUUID(), outputs: [], purgeResult: 'Not yet saved' };
saveRecord(record);
const row = await addStudioJob({ ownerKey: owner, kind: ['video', 'extend'].includes(request.mode) ? 'video' : 'edit', familyId: record.familyId, payload: { ...request.settings, studio2Id: id, studio2Request: structuredClone(request), prompt: request.compiledPrompt, folderId: request.folderId, extensions: [], referenceStillIds: [], useIdentityRefs: false, queueAutoRun: true } as StudioJobPayload });
saveRecord({ ...readRecord(owner, id), queueId: row.id });
kickStudioQueue();
return { id, seed:request.settings.seed, width:request.settings.width, height:request.settings.height };
const ack = { id, seed:request.settings.seed, width:request.settings.width, height:request.settings.height };
// Enqueue + kick after the client has the id — do not block the response on the worker wake path
void (async () => {
try {
const row = await addStudioJob({ ownerKey: owner, kind: ['video', 'extend'].includes(request.mode) ? 'video' : 'edit', familyId: record.familyId, payload: { ...request.settings, studio2Id: id, studio2Request: structuredClone(request), prompt: request.compiledPrompt, folderId: request.folderId, extensions: [], referenceStillIds: [], useIdentityRefs: false, queueAutoRun: true } as StudioJobPayload });
saveRecord({ ...readRecord(owner, id), queueId: row.id });
} catch { /* poll / resume will pick up waiting studio2 records */ }
kickStudioQueue();
})();
return ack;
});