fix: stabilize convex pagination and ci fallback

This commit is contained in:
Esdras Renan 2025-11-17 14:23:46 -03:00
parent a08b0d6d27
commit dbee5c28c8
2 changed files with 80 additions and 34 deletions

View file

@ -200,37 +200,50 @@ type PaginatedResult<T> = {
isDone?: boolean;
};
type QueryBuilder<T> = {
paginate?: (options: { cursor: string | null; numItems: number }) => Promise<PaginatedResult<T>>;
collect?: () => Promise<T[]>;
};
async function paginateTickets<T>(
buildQuery: () => {
paginate: (options: { cursor: string | null; numItems: number }) => Promise<PaginatedResult<T>>;
collect?: () => Promise<T[]>;
},
buildQuery: () => QueryBuilder<T>,
handler: (doc: T) => void | Promise<void>,
pageSize = REPORTS_PAGE_SIZE,
) {
const query = buildQuery();
if (typeof (query as { paginate?: unknown }).paginate !== "function") {
const collectFn = (query as { collect?: (() => Promise<T[]>) | undefined }).collect;
if (typeof collectFn !== "function") {
throw new ConvexError("Query does not support paginate or collect");
}
const docs = await collectFn.call(query);
for (const doc of docs) {
await handler(doc);
}
return;
}
let cursor: string | null = null;
while (true) {
const page = await query.paginate({ cursor, numItems: pageSize });
const query = buildQuery();
const paginateFn:
| ((options: { cursor: string | null; numItems: number }) => Promise<PaginatedResult<T>>)
| undefined = query.paginate;
if (typeof paginateFn !== "function") {
if (cursor !== null) {
throw new ConvexError("Query does not support pagination but cursor was provided");
}
const collectFn = query.collect;
if (typeof collectFn !== "function") {
throw new ConvexError("Query does not support paginate or collect");
}
const docs = await collectFn.call(query);
for (const doc of docs) {
await handler(doc);
}
return;
}
const page: PaginatedResult<T> = await paginateFn.call(query, { cursor, numItems: pageSize });
for (const doc of page.page) {
await handler(doc);
}
const done = page.done ?? page.isDone ?? !page.continueCursor;
const continueCursor = page.continueCursor ?? null;
const done = page.done ?? page.isDone ?? !continueCursor;
if (done) {
break;
}
cursor = page.continueCursor ?? null;
cursor = continueCursor;
}
}