Something went wrong. Try again.
Monorepo for the nibling.run platform
Something went wrong. Try again.
1234567891011121314151617181920212223242526272829/** How many pages a listing reads before it stops. At 100 records a page, that is 10,000 records. */export const MAX_PAGES = 100;
export interface Page<T> { items: readonly T[]; cursor?: string | null;}
/** * Yields every item across pages. Stops at an empty page, a missing cursor, a cursor the server already * sent, or after `maxPages`, so a server that repeats or cycles its cursor cannot keep the caller looping. * With `pageSize`, a page shorter than it is the last one: a PDS sends a cursor with every page that has * records, so without this every listing costs one more round trip for an empty page. */export async function* paginate<T>( fetchPage: (cursor: string | undefined) => Promise<Page<T>>, { maxPages = MAX_PAGES, pageSize }: { maxPages?: number; pageSize?: number } = {},): AsyncGenerator<T> { const seen = new Set<string>(); let cursor: string | undefined; for (let page = 0; page < maxPages; page++) { const { items, cursor: next } = await fetchPage(cursor); yield* items; if (items.length === 0 || (pageSize !== undefined && items.length < pageSize) || !next || seen.has(next)) return; seen.add(next); cursor = next; }}