diff --git a/package-lock.json b/package-lock.json index a3ed4a2..be4b615 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,7 +9,7 @@ "version": "1.5.17", "license": "MIT", "dependencies": { - "@nbtca/docs": "^0.3.3", + "@nbtca/docs": "^0.3.4", "@nbtca/nbtcal": "^0.4.3", "chalk": "^5.6.2", "marked": "^15.0.12" @@ -770,9 +770,9 @@ "license": "MIT" }, "node_modules/@nbtca/docs": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/@nbtca/docs/-/docs-0.3.3.tgz", - "integrity": "sha512-uXxgas3/ymvJ61bYP4R3sfnB4XYC2LyI4ARAEDRnONF+UJX2RL4nHvyCYY9O/xTNklOO/StcZtEV51VKrEMAyA==", + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/@nbtca/docs/-/docs-0.3.4.tgz", + "integrity": "sha512-wvxatkhj+D7/a0iI9O848boJUA43wfXel4tHxQ4A1qnjLsl07VdipI2WJS1MjWe9TNnG7IuHYb6Wzfcbeq57YQ==", "license": "MIT", "engines": { "node": ">=20.12.0" diff --git a/package.json b/package.json index dd21e24..f869bf0 100644 --- a/package.json +++ b/package.json @@ -46,7 +46,7 @@ "interactive" ], "dependencies": { - "@nbtca/docs": "^0.3.3", + "@nbtca/docs": "^0.3.4", "@nbtca/nbtcal": "^0.4.3", "chalk": "^5.6.2", "marked": "^15.0.12" diff --git a/src/features/docs.test.ts b/src/features/docs.test.ts index 3476ed2..4cc7f35 100644 --- a/src/features/docs.test.ts +++ b/src/features/docs.test.ts @@ -24,6 +24,7 @@ import { stripAnsi } from '../core/text.js'; import type { DocItem } from '@nbtca/docs'; import { mkdirSync, writeFileSync } from 'node:fs'; import { join } from 'node:path'; +import { createHash, randomUUID } from 'node:crypto'; import { getWritableStateDir } from '../config/paths.js'; const spawnMock = vi.hoisted(() => vi.fn()); @@ -523,4 +524,35 @@ describe('searchDocuments', () => { expect(results[0]?.excerpt).not.toMatch(/^Alpha Guide/); expect(results[0]?.excerpt).toContain('needle'); }); + + it('loads uncached documents from the mirror bundle before counting', async () => { + const run = randomUUID(); + const files = Array.from({ length: 8 }, (_, index) => { + const content = `# Doc ${String(index)}\n\nneedle ${run}`; + const sha = createHash('sha1') + .update(`blob ${String(content.length)}\0${content}`) + .digest('hex'); + return { path: `guide/${String(index)}.md`, sha, content }; + }); + const fetchMock = vi.fn((input: string) => + Promise.resolve( + input.endsWith('/docs-api/index.json') + ? Response.json({ + tree: files.map(({ path, sha }) => ({ path, type: 'blob', sha })), + truncated: false, + }) + : input.endsWith('/docs-api/bundle.json') + ? Response.json({ files }) + : new Response(null, { status: 404 }), + ), + ); + vi.stubGlobal('fetch', fetchMock); + const progress: [number, number][] = []; + const results = await searchDocuments(run, new AbortController().signal, (done, total) => { + progress.push([done, total]); + }); + expect(progress).toEqual([[8, 8]]); + expect(results).toHaveLength(8); + expect(fetchMock).toHaveBeenCalledTimes(2); + }); }); diff --git a/src/features/docs.ts b/src/features/docs.ts index 2e010bf..22f428c 100644 --- a/src/features/docs.ts +++ b/src/features/docs.ts @@ -786,9 +786,14 @@ export async function searchDocuments( ): Promise { if (onProgress) { const items = await fetchAllDocs(signal); - let done = 0; + let pending = items.filter((item) => !peekDocMetadata(item)); + if (pending.length > METADATA_CONCURRENCY) { + await runDocsClientOperation(signal, (client) => client.prefetch()); + pending = pending.filter((item) => !peekDocMetadata(item)); + } + let done = items.length - pending.length; onProgress(done, items.length); - await fetchDocMetadata(items, signal, () => { + await fetchDocMetadata(pending, signal, () => { done += 1; onProgress(done, items.length); });