import { sleep } from './sleep' import type { Query, Row } from '@rocicorp/zero' type ServerWithQuery = { query: (cb: (q: any) => any) => Promise } export function createBatchQuery(server: ServerWithQuery) { return async function batchQuery, Item extends Row>( buildQuery: (q: any) => Q, mapper: (items: Item[]) => Promise, { chunk, pause = 0, stopAfter = 100_000, }: { chunk: number pause?: number stopAfter?: number } = { chunk: 20 } ) { let hasMore = true let last: Item | null = null let iterations = 0 while (hasMore) { const results = await server.query((q: any) => { let query = buildQuery(q).limit(chunk) if (last) { query = query.start(last) } return query }) await mapper(results as Item[]) if (results.length < chunk) { hasMore = false } if (iterations > stopAfter) { console.error(`[batchQuery] ‼️ stopping batch, ran ${stopAfter} chunks`) break } if (pause) { await sleep(pause) } } } }