wiki-graph-core 0.4.0 → 0.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/library/query.ts"],"sourcesContent":["import type { ReadonlyDocument } from \"../document/index.js\";\nimport {\n listArchiveEvidence,\n listRelatedArchiveObjects,\n packArchiveContext,\n readArchivePage,\n} from \"../retrieval/query/archive-view/index.js\";\nimport {\n createCollectionResult,\n createFindResult,\n} from \"../retrieval/query/archive-view/helper/results.js\";\nimport {\n findWikiGraphLibraryObjectsBucketed,\n shouldUseLibraryBucketedSearch,\n} from \"./search-query.js\";\nimport { hydrateSearchIndexHits } from \"../retrieval/query/archive-view/search/hydration.js\";\nimport type {\n ArchiveCollectionOptions,\n ArchiveCollectionResult,\n ArchiveEvidence,\n ArchiveEvidenceItem,\n ArchiveEvidenceOptions,\n ArchiveFindEvidencePreview,\n ArchiveFindHit,\n ArchiveFindOptions,\n ArchiveFindOrder,\n ArchiveFindResult,\n ArchiveLibrarySource,\n ArchiveListItem,\n ArchivePack,\n ArchivePage,\n ArchiveRelatedOptions,\n ArchiveRelatedResult,\n} from \"../retrieval/query/archive-view/types.js\";\nimport {\n getWikiGraphLibraryArchiveById,\n listWikiGraphLibraryArchives,\n type WikiGraphLibraryArchiveRecord,\n} from \"./membership.js\";\nimport {\n createLibrarySource,\n createSortedArchiveIds,\n isReadableLibraryArchive,\n readLibraryArchiveDocument,\n resolveReadableIndexedArchive,\n} from \"./query-helpers.js\";\nimport {\n parseWikiGraphLibraryUri,\n resolveWikiGraphLibrary,\n resolveWikiGraphLibraryById,\n type ParsedWikiGraphLibraryUri,\n} from \"./registry.js\";\nimport {\n assertWikiGraphLibraryIndexReady,\n listWikiGraphLibraryIndexArchiveIdsForObject,\n listWikiGraphLibrarySearchIndex,\n queryWikiGraphLibrarySearchIndex,\n} from \"./search-index.js\";\n\nconst DEFAULT_LIBRARY_PAGE_LIMIT = 20;\nconst LIBRARY_QUERY_INDEX_LIMIT_MULTIPLIER = 20;\nconst LIBRARY_QUERY_INDEX_MIN_LIMIT = 100;\n\nexport async function findWikiGraphLibraryObjects(\n target: ParsedWikiGraphLibraryUri,\n query: string,\n options: ArchiveFindOptions = {},\n): Promise<ArchiveFindResult> {\n if (shouldUseLibraryBucketedSearch(options)) {\n return await findWikiGraphLibraryObjectsBucketed(target, query, options);\n }\n\n const indexHitLimit = createLibraryQueryIndexHitLimit(options);\n const result = await queryWikiGraphLibrarySearchIndex(target, query, {\n objectHitLimit: indexHitLimit,\n textHitLimit: indexHitLimit,\n });\n\n if (result === undefined) {\n return createFindResult(query, [], options);\n }\n\n const hits: ArchiveFindHit[] = [];\n for (const archiveId of createSortedArchiveIds(result)) {\n const archive = await resolveReadableIndexedArchive(target, archiveId, {\n operation: \"searching library objects\",\n });\n const source = createLibrarySource(archive);\n const hydrated = await readLibraryArchiveDocument(\n archive,\n async (document) =>\n await hydrateSearchIndexHits(document, {\n objectHits: result.objectHits.filter(\n (hit) => hit.archiveId === archive.id,\n ),\n terms: result.terms,\n textHits: result.textHits.filter(\n (hit) => hit.archiveId === archive.id,\n ),\n }),\n );\n\n hits.push(...hydrated.map((hit) => ({ ...hit, ...source })));\n }\n\n return createFindResult(query, hits, options, result.terms);\n}\n\nfunction createLibraryQueryIndexHitLimit(options: ArchiveFindOptions): number {\n return Math.max(\n (options.limit ?? DEFAULT_LIBRARY_PAGE_LIMIT) *\n LIBRARY_QUERY_INDEX_LIMIT_MULTIPLIER,\n LIBRARY_QUERY_INDEX_MIN_LIMIT,\n );\n}\n\nexport async function listWikiGraphLibraryObjects(\n target: ParsedWikiGraphLibraryUri,\n options: ArchiveCollectionOptions = {},\n): Promise<ArchiveCollectionResult> {\n const hits: ArchiveFindHit[] = [];\n const result = await listWikiGraphLibrarySearchIndex(target, {\n includeText: shouldListTextStreams(options),\n });\n const archiveIds = createSortedArchiveIds(result);\n for (const archiveId of archiveIds) {\n const archive = await resolveReadableIndexedArchive(target, archiveId, {\n operation: \"listing library objects\",\n });\n const source = createLibrarySource(archive);\n const hydrated = await readLibraryArchiveDocument(\n archive,\n async (document) =>\n await hydrateSearchIndexHits(document, {\n objectHits: result.objectHits.filter(\n (hit) => hit.archiveId === archive.id,\n ),\n terms: result.terms,\n textHits: result.textHits.filter(\n (hit) => hit.archiveId === archive.id,\n ),\n }),\n );\n\n hits.push(...hydrated.map((hit) => ({ ...hit, ...source })));\n }\n\n return createCollectionResult(hits, options);\n}\n\nexport async function readWikiGraphLibraryPage(\n target: ParsedWikiGraphLibraryUri,\n objectUri: string,\n options: Parameters<typeof readArchivePage>[2] = {},\n): Promise<ArchivePage> {\n const pages = await readIndexedArchiveResults(\n target,\n objectUri,\n async (document, archive) => ({\n ...(await readArchivePage(document, objectUri, options)),\n ...createLibrarySource(archive),\n }),\n );\n\n const page = createMultiArchivePage(pages);\n if ((page.type === \"entity\" || page.type === \"triple\") && pages.length > 1) {\n return {\n ...page,\n evidence: combinePageEvidencePreviews(\n pages,\n options.evidenceLimit ?? 3,\n options.order ?? \"doc-asc\",\n ),\n };\n }\n\n return page;\n}\n\nexport async function listWikiGraphLibraryEvidence(\n target: ParsedWikiGraphLibraryUri,\n objectUri: string,\n options: ArchiveEvidenceOptions = {},\n): Promise<ArchiveEvidence> {\n const limit = options.limit ?? DEFAULT_LIBRARY_PAGE_LIMIT;\n const offset = parseLibraryObjectCursor(options.cursor, \"evidence\");\n const archiveWindowLimit = offset + limit;\n const results = await readIndexedArchiveResults(\n target,\n objectUri,\n async (document, archive) => {\n const { cursor: _cursor, ...archiveOptions } = options;\n const result = await listArchiveEvidence(document, objectUri, {\n ...archiveOptions,\n limit: archiveWindowLimit,\n });\n const source = createLibrarySource(archive);\n\n return {\n ...result,\n items: result.items.map(\n (item): ArchiveEvidenceItem => ({\n ...item,\n ...source,\n }),\n ),\n };\n },\n );\n\n return createEvidenceResult(\n results.flatMap((result) => result.items),\n options,\n );\n}\n\nexport async function listRelatedWikiGraphLibraryObjects(\n target: ParsedWikiGraphLibraryUri,\n objectUri: string,\n options: ArchiveRelatedOptions = {},\n): Promise<ArchiveRelatedResult> {\n const limit = options.limit ?? DEFAULT_LIBRARY_PAGE_LIMIT;\n const offset = parseLibraryObjectCursor(options.cursor, \"related\");\n const archiveWindowLimit = offset + limit;\n const results = await readIndexedArchiveResults(\n target,\n objectUri,\n async (document, archive) => {\n const { cursor: _cursor, ...archiveOptions } = options;\n const result = await listRelatedArchiveObjects(document, objectUri, {\n ...archiveOptions,\n limit: archiveWindowLimit,\n });\n const source = createLibrarySource(archive);\n\n return {\n ...result,\n items: result.items.map(\n (item): ArchiveListItem => ({\n ...item,\n ...source,\n }),\n ),\n };\n },\n );\n\n return createRelatedResult(\n results.flatMap((result) => result.items),\n options,\n );\n}\n\nexport async function packWikiGraphLibraryContext(\n target: ParsedWikiGraphLibraryUri,\n objectUri: string,\n budget: number,\n): Promise<ArchivePack> {\n const packs = await readIndexedArchiveResults(\n target,\n objectUri,\n async (document, archive) => {\n const pack = await packArchiveContext(document, objectUri, budget);\n const source = createLibrarySource(archive);\n\n return {\n ...pack,\n anchor: { ...pack.anchor, ...source },\n related: pack.related.map((item) => ({ ...item, ...source })),\n };\n },\n );\n const [first] = packs;\n\n if (first === undefined) {\n throw new Error(`Wiki Graph library object was not found: ${objectUri}`);\n }\n\n return {\n anchor: createMultiArchivePage(packs.map((pack) => pack.anchor)),\n budget,\n related: packs.flatMap((pack) => pack.related),\n };\n}\n\nexport async function resolveWikiGraphLibraryQueryTargetById(\n libraryId: number,\n): Promise<ParsedWikiGraphLibraryUri> {\n const library = await resolveWikiGraphLibraryById(libraryId);\n return (\n parseWikiGraphLibraryUri(library.uri) ?? {\n isDefault: library.isDefault,\n kind: \"scope\",\n publicId: library.publicId,\n }\n );\n}\n\nasync function readIndexedArchiveResults<T>(\n target: ParsedWikiGraphLibraryUri,\n objectUri: string,\n operation: (\n document: ReadonlyDocument,\n archive: WikiGraphLibraryArchiveRecord,\n ) => Promise<T>,\n): Promise<T[]> {\n const library = await resolveWikiGraphLibrary(target);\n const archiveIds = await listWikiGraphLibraryIndexArchiveIdsForObject(\n target,\n objectUri,\n );\n\n if (archiveIds.length === 0) {\n if (!isTripleObjectUri(objectUri)) {\n throw new Error(`Wiki Graph library object was not found: ${objectUri}`);\n }\n\n // Library v1 cannot project every triple occurrence into the index yet.\n // Keep the archive scan explicit and restricted to triples so entity/chunk\n // lookups remain index-backed and do not silently regress to full scans.\n return await readUnindexedArchiveResults(target, objectUri, operation);\n }\n\n const results: T[] = [];\n for (const archiveId of archiveIds) {\n const archive = await getWikiGraphLibraryArchiveById(library, archiveId);\n if (!isReadableLibraryArchive(archive)) {\n throw new Error(\n `Wiki Graph library archive ${archiveId} is not readable while reading ${objectUri}.`,\n );\n }\n\n try {\n results.push(\n await readLibraryArchiveDocument(\n archive,\n async (document) => await operation(document, archive),\n ),\n );\n } catch (error) {\n throw new Error(\n `Failed to read Wiki Graph library archive ${archiveId} (${archive.uri}) for ${objectUri}: ${formatErrorMessage(error)}`,\n { cause: error },\n );\n }\n }\n\n if (results.length === 0) {\n throw new Error(`Wiki Graph library object was not found: ${objectUri}`);\n }\n return results;\n}\n\nasync function readUnindexedArchiveResults<T>(\n target: ParsedWikiGraphLibraryUri,\n objectUri: string,\n operation: (\n document: ReadonlyDocument,\n archive: WikiGraphLibraryArchiveRecord,\n ) => Promise<T>,\n): Promise<T[]> {\n const results: T[] = [];\n\n for (const archive of await listReadyLibraryArchives(target)) {\n try {\n results.push(\n await readLibraryArchiveDocument(\n archive,\n async (document) => await operation(document, archive),\n ),\n );\n } catch (error) {\n if (isArchiveObjectNotFoundError(error)) {\n continue;\n }\n throw new Error(\n `Failed to read Wiki Graph library archive ${archive.id} (${archive.uri}) for ${objectUri}: ${formatErrorMessage(error)}`,\n { cause: error },\n );\n }\n }\n\n if (results.length === 0) {\n throw new Error(`Wiki Graph library object was not found: ${objectUri}`);\n }\n return results;\n}\n\nfunction createMultiArchivePage(pages: readonly ArchivePage[]): ArchivePage {\n const [first] = pages;\n if (first === undefined) {\n throw new Error(\n \"Internal error: cannot merge an empty library page result.\",\n );\n }\n\n const sources = createLibrarySources(pages);\n if (sources.length === 1) {\n return first;\n }\n\n const {\n archiveId: _archiveId,\n libraryArchiveUri: _libraryArchiveUri,\n ...page\n } = first;\n\n return { ...page, sources };\n}\n\nfunction combinePageEvidencePreviews(\n pages: readonly ArchivePage[],\n limit: number,\n order: ArchiveFindOrder,\n): ArchiveFindEvidencePreview {\n const evidencePages = pages.flatMap((page) =>\n page.type === \"entity\" || page.type === \"triple\" ? [page] : [],\n );\n const orderedPages =\n order === \"doc-desc\" ? evidencePages.slice().reverse() : evidencePages;\n const sources = orderedPages.flatMap((page) =>\n page.evidence.sources.map((source) => ({\n ...source,\n ...(page.archiveId === undefined ? {} : { archiveId: page.archiveId }),\n ...(page.libraryArchiveUri === undefined\n ? {}\n : { libraryArchiveUri: page.libraryArchiveUri }),\n })),\n );\n const total = evidencePages.reduce(\n (sum, page) => sum + page.evidence.total,\n 0,\n );\n const pageSources = sources.slice(0, limit);\n const shown = pageSources.length;\n\n return {\n nextCursor: limit < total ? String(limit) : null,\n shown,\n sources: pageSources,\n total,\n };\n}\n\nfunction createEvidenceResult(\n items: readonly ArchiveEvidenceItem[],\n options: ArchiveEvidenceOptions,\n): ArchiveEvidence {\n const limit = options.limit ?? DEFAULT_LIBRARY_PAGE_LIMIT;\n const offset = parseLibraryObjectCursor(options.cursor, \"evidence\");\n const sorted = [...items].sort((left, right) =>\n compareLibraryEvidenceItems(left, right, options.order ?? \"doc-asc\"),\n );\n const pageItems = sorted.slice(offset, offset + limit);\n const nextOffset = offset + pageItems.length;\n\n return {\n items: pageItems,\n limit,\n nextCursor: nextOffset < sorted.length ? String(nextOffset) : null,\n };\n}\n\nfunction createRelatedResult(\n items: readonly ArchiveListItem[],\n options: ArchiveRelatedOptions,\n): ArchiveRelatedResult {\n const limit = options.limit ?? DEFAULT_LIBRARY_PAGE_LIMIT;\n const offset = parseLibraryObjectCursor(options.cursor, \"related\");\n const sorted = [...items].sort((left, right) =>\n compareLibraryListItems(left, right, options.order ?? \"doc-asc\"),\n );\n const pageItems = sorted.slice(offset, offset + limit);\n const nextOffset = offset + pageItems.length;\n\n return {\n items: pageItems,\n limit,\n nextCursor: nextOffset < sorted.length ? String(nextOffset) : null,\n };\n}\n\nexport function createLibrarySources(\n values: readonly {\n readonly archiveId?: number;\n readonly libraryArchiveUri?: string;\n }[],\n): readonly ArchiveLibrarySource[] {\n const sources = new Map<number, ArchiveLibrarySource>();\n for (const value of values) {\n if (\n value.archiveId === undefined ||\n value.libraryArchiveUri === undefined\n ) {\n continue;\n }\n sources.set(value.archiveId, {\n archiveId: value.archiveId,\n libraryArchiveUri: value.libraryArchiveUri,\n });\n }\n return [...sources.values()].sort(\n (left, right) => left.archiveId - right.archiveId,\n );\n}\n\nfunction compareLibraryEvidenceItems(\n left: ArchiveEvidenceItem,\n right: ArchiveEvidenceItem,\n order: \"doc-asc\" | \"doc-desc\",\n): number {\n const direction = order === \"doc-asc\" ? 1 : -1;\n return (\n (compareOptionalNumbers(left.archiveId, right.archiveId) ||\n left.chapterId - right.chapterId ||\n left.startSentenceIndex - right.startSentenceIndex ||\n left.endSentenceIndex - right.endSentenceIndex ||\n left.id.localeCompare(right.id)) * direction\n );\n}\n\nfunction compareLibraryListItems(\n left: ArchiveListItem,\n right: ArchiveListItem,\n order: \"doc-asc\" | \"doc-desc\",\n): number {\n const direction = order === \"doc-asc\" ? 1 : -1;\n return (\n (compareOptionalNumbers(left.archiveId, right.archiveId) ||\n left.id.localeCompare(right.id)) * direction\n );\n}\n\nfunction compareOptionalNumbers(\n left: number | undefined,\n right: number | undefined,\n): number {\n return (left ?? Number.MAX_SAFE_INTEGER) - (right ?? Number.MAX_SAFE_INTEGER);\n}\n\nfunction parseLibraryObjectCursor(\n cursor: string | undefined,\n kind: \"evidence\" | \"related\",\n): number {\n if (cursor === undefined) {\n return 0;\n }\n if (!/^(0|[1-9][0-9]*)$/u.test(cursor)) {\n throw new Error(`Invalid library ${kind} cursor: ${cursor}`);\n }\n return Number(cursor);\n}\n\nasync function listReadyLibraryArchives(\n target: ParsedWikiGraphLibraryUri,\n): Promise<readonly WikiGraphLibraryArchiveRecord[]> {\n await assertWikiGraphLibraryIndexReady(target);\n return (await listWikiGraphLibraryArchives(target)).filter(\n isReadableLibraryArchive,\n );\n}\n\nfunction shouldListTextStreams(options: ArchiveCollectionOptions): boolean {\n return (\n options.types !== undefined &&\n options.types.some((type) => type === \"source\" || type === \"summary\")\n );\n}\n\nfunction formatErrorMessage(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n\nfunction isArchiveObjectNotFoundError(error: unknown): boolean {\n return (\n error instanceof Error &&\n error.message.includes(\" was not found in this archive.\")\n );\n}\n\nfunction isTripleObjectUri(objectUri: string): boolean {\n return /^wikg:\\/\\/(?:chapter\\/[1-9][0-9]*\\/)?triple\\/Q[1-9][0-9]*\\/[^/]+\\/Q[1-9][0-9]*\\/?$/u.test(\n objectUri,\n );\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../src/library/query.ts"],"sourcesContent":["import type { ReadonlyDocument } from \"../document/index.js\";\nimport {\n listArchiveEvidence,\n listRelatedArchiveObjects,\n packArchiveContext,\n readArchivePage,\n} from \"../retrieval/query/archive-view/index.js\";\nimport {\n createCollectionResult,\n createFindResult,\n} from \"../retrieval/query/archive-view/helper/results.js\";\nimport {\n findWikiGraphLibraryObjectsBucketed,\n shouldUseLibraryBucketedSearch,\n} from \"./search-query.js\";\nimport { hydrateSearchIndexHits } from \"../retrieval/query/archive-view/search/hydration.js\";\nimport type {\n ArchiveCollectionOptions,\n ArchiveCollectionResult,\n ArchiveEvidence,\n ArchiveEvidenceItem,\n ArchiveEvidenceOptions,\n ArchiveFindEvidencePreview,\n ArchiveFindHit,\n ArchiveFindOptions,\n ArchiveFindOrder,\n ArchiveFindResult,\n ArchiveLibrarySource,\n ArchiveListItem,\n ArchivePack,\n ArchivePage,\n ArchiveRelatedOptions,\n ArchiveRelatedResult,\n} from \"../retrieval/query/archive-view/types.js\";\nimport {\n getWikiGraphLibraryArchiveById,\n listWikiGraphLibraryArchives,\n type WikiGraphLibraryArchiveRecord,\n} from \"./membership.js\";\nimport {\n createLibrarySource,\n createSortedArchiveIds,\n isReadableLibraryArchive,\n readLibraryArchiveDocument,\n resolveReadableIndexedArchive,\n} from \"./query-helpers.js\";\nimport {\n parseWikiGraphLibraryUri,\n resolveWikiGraphLibrary,\n resolveWikiGraphLibraryById,\n type ParsedWikiGraphLibraryUri,\n} from \"./registry.js\";\nimport {\n assertWikiGraphLibraryIndexReady,\n listWikiGraphLibraryIndexArchiveIdsForObject,\n listWikiGraphLibrarySearchIndex,\n queryWikiGraphLibrarySearchIndex,\n} from \"./search-index.js\";\n\nconst DEFAULT_LIBRARY_PAGE_LIMIT = 20;\nconst LIBRARY_QUERY_INDEX_LIMIT_MULTIPLIER = 20;\nconst LIBRARY_QUERY_INDEX_MIN_LIMIT = 100;\n\nexport async function findWikiGraphLibraryObjects(\n target: ParsedWikiGraphLibraryUri,\n query: string,\n options: ArchiveFindOptions = {},\n): Promise<ArchiveFindResult> {\n if (shouldUseLibraryBucketedSearch(options)) {\n return await findWikiGraphLibraryObjectsBucketed(target, query, options);\n }\n\n const indexHitLimit = createLibraryQueryIndexHitLimit(options);\n const result = await queryWikiGraphLibrarySearchIndex(target, query, {\n objectHitLimit: indexHitLimit,\n textHitLimit: indexHitLimit,\n });\n\n if (result === undefined) {\n return createFindResult(query, [], options);\n }\n\n const hits: ArchiveFindHit[] = [];\n for (const archiveId of createSortedArchiveIds(result)) {\n const archive = await resolveReadableIndexedArchive(target, archiveId, {\n operation: \"searching library objects\",\n });\n const source = createLibrarySource(archive);\n const hydrated = await readLibraryArchiveDocument(\n archive,\n async (document) =>\n await hydrateSearchIndexHits(document, {\n objectHits: result.objectHits.filter(\n (hit) => hit.archiveId === archive.id,\n ),\n terms: result.terms,\n textHits: result.textHits.filter(\n (hit) => hit.archiveId === archive.id,\n ),\n }),\n );\n\n hits.push(...hydrated.map((hit) => ({ ...hit, ...source })));\n }\n\n return createFindResult(query, hits, options, result.terms);\n}\n\nexport async function findWikiGraphLibraryArchiveMembers(\n target: ParsedWikiGraphLibraryUri,\n query: string,\n options: ArchiveFindOptions = {},\n): Promise<ArchiveFindResult> {\n const terms = createLibraryArchiveMemberSearchTerms(query);\n const archives = await listWikiGraphLibraryArchives(target);\n const hits = archives\n .map(formatLibraryArchiveMemberHit)\n .filter((hit) => matchesLibraryArchiveMemberSearch(hit, terms));\n\n return createFindResult(query, hits, options, terms, \"typed\");\n}\n\nfunction createLibraryQueryIndexHitLimit(options: ArchiveFindOptions): number {\n return Math.max(\n (options.limit ?? DEFAULT_LIBRARY_PAGE_LIMIT) *\n LIBRARY_QUERY_INDEX_LIMIT_MULTIPLIER,\n LIBRARY_QUERY_INDEX_MIN_LIMIT,\n );\n}\n\nfunction createLibraryArchiveMemberSearchTerms(\n query: string,\n): readonly string[] {\n return query\n .trim()\n .toLocaleLowerCase()\n .split(/\\s+/u)\n .filter((term) => term !== \"\");\n}\n\nfunction matchesLibraryArchiveMemberSearch(\n hit: ArchiveFindHit,\n terms: readonly string[],\n): boolean {\n if (terms.length === 0) {\n return true;\n }\n const haystack =\n `${hit.id}\\n${hit.title}\\n${hit.snippet}`.toLocaleLowerCase();\n\n return terms.every((term) => haystack.includes(term));\n}\n\nfunction formatLibraryArchiveMemberHit(\n archive: WikiGraphLibraryArchiveRecord,\n): ArchiveFindHit {\n const details = [\n archive.relativePath,\n archive.status,\n archive.exists ? \"exists\" : \"missing-file\",\n ].join(\" \");\n\n return {\n archiveId: archive.id,\n field: \"metadata\",\n id: archive.uri,\n libraryArchiveUri: archive.uri,\n snippet: details,\n title: archive.relativePath,\n type: \"meta\",\n };\n}\n\nexport async function listWikiGraphLibraryObjects(\n target: ParsedWikiGraphLibraryUri,\n options: ArchiveCollectionOptions = {},\n): Promise<ArchiveCollectionResult> {\n const hits: ArchiveFindHit[] = [];\n const result = await listWikiGraphLibrarySearchIndex(target, {\n includeText: shouldListTextStreams(options),\n });\n const archiveIds = createSortedArchiveIds(result);\n for (const archiveId of archiveIds) {\n const archive = await resolveReadableIndexedArchive(target, archiveId, {\n operation: \"listing library objects\",\n });\n const source = createLibrarySource(archive);\n const hydrated = await readLibraryArchiveDocument(\n archive,\n async (document) =>\n await hydrateSearchIndexHits(document, {\n objectHits: result.objectHits.filter(\n (hit) => hit.archiveId === archive.id,\n ),\n terms: result.terms,\n textHits: result.textHits.filter(\n (hit) => hit.archiveId === archive.id,\n ),\n }),\n );\n\n hits.push(...hydrated.map((hit) => ({ ...hit, ...source })));\n }\n\n return createCollectionResult(hits, options);\n}\n\nexport async function listWikiGraphLibraryArchiveMembers(\n target: ParsedWikiGraphLibraryUri,\n options: ArchiveCollectionOptions = {},\n): Promise<ArchiveCollectionResult> {\n return createCollectionResult(\n (await listWikiGraphLibraryArchives(target)).map(\n formatLibraryArchiveMemberHit,\n ),\n options,\n );\n}\n\nexport async function readWikiGraphLibraryPage(\n target: ParsedWikiGraphLibraryUri,\n objectUri: string,\n options: Parameters<typeof readArchivePage>[2] = {},\n): Promise<ArchivePage> {\n const pages = await readIndexedArchiveResults(\n target,\n objectUri,\n async (document, archive) => ({\n ...(await readArchivePage(document, objectUri, options)),\n ...createLibrarySource(archive),\n }),\n );\n\n const page = createMultiArchivePage(pages);\n if ((page.type === \"entity\" || page.type === \"triple\") && pages.length > 1) {\n return {\n ...page,\n evidence: combinePageEvidencePreviews(\n pages,\n options.evidenceLimit ?? 3,\n options.order ?? \"doc-asc\",\n ),\n };\n }\n\n return page;\n}\n\nexport async function listWikiGraphLibraryEvidence(\n target: ParsedWikiGraphLibraryUri,\n objectUri: string,\n options: ArchiveEvidenceOptions = {},\n): Promise<ArchiveEvidence> {\n const limit = options.limit ?? DEFAULT_LIBRARY_PAGE_LIMIT;\n const offset = parseLibraryObjectCursor(options.cursor, \"evidence\");\n const archiveWindowLimit = offset + limit;\n const results = await readIndexedArchiveResults(\n target,\n objectUri,\n async (document, archive) => {\n const { cursor: _cursor, ...archiveOptions } = options;\n const result = await listArchiveEvidence(document, objectUri, {\n ...archiveOptions,\n limit: archiveWindowLimit,\n });\n const source = createLibrarySource(archive);\n\n return {\n ...result,\n items: result.items.map(\n (item): ArchiveEvidenceItem => ({\n ...item,\n ...source,\n }),\n ),\n };\n },\n );\n\n return createEvidenceResult(\n results.flatMap((result) => result.items),\n options,\n );\n}\n\nexport async function listRelatedWikiGraphLibraryObjects(\n target: ParsedWikiGraphLibraryUri,\n objectUri: string,\n options: ArchiveRelatedOptions = {},\n): Promise<ArchiveRelatedResult> {\n const limit = options.limit ?? DEFAULT_LIBRARY_PAGE_LIMIT;\n const offset = parseLibraryObjectCursor(options.cursor, \"related\");\n const archiveWindowLimit = offset + limit;\n const results = await readIndexedArchiveResults(\n target,\n objectUri,\n async (document, archive) => {\n const { cursor: _cursor, ...archiveOptions } = options;\n const result = await listRelatedArchiveObjects(document, objectUri, {\n ...archiveOptions,\n limit: archiveWindowLimit,\n });\n const source = createLibrarySource(archive);\n\n return {\n ...result,\n items: result.items.map(\n (item): ArchiveListItem => ({\n ...item,\n ...source,\n }),\n ),\n };\n },\n );\n\n return createRelatedResult(\n results.flatMap((result) => result.items),\n options,\n );\n}\n\nexport async function packWikiGraphLibraryContext(\n target: ParsedWikiGraphLibraryUri,\n objectUri: string,\n budget: number,\n): Promise<ArchivePack> {\n const packs = await readIndexedArchiveResults(\n target,\n objectUri,\n async (document, archive) => {\n const pack = await packArchiveContext(document, objectUri, budget);\n const source = createLibrarySource(archive);\n\n return {\n ...pack,\n anchor: { ...pack.anchor, ...source },\n related: pack.related.map((item) => ({ ...item, ...source })),\n };\n },\n );\n const [first] = packs;\n\n if (first === undefined) {\n throw new Error(`Wiki Graph library object was not found: ${objectUri}`);\n }\n\n return {\n anchor: createMultiArchivePage(packs.map((pack) => pack.anchor)),\n budget,\n related: packs.flatMap((pack) => pack.related),\n };\n}\n\nexport async function resolveWikiGraphLibraryQueryTargetById(\n libraryId: number,\n): Promise<ParsedWikiGraphLibraryUri> {\n const library = await resolveWikiGraphLibraryById(libraryId);\n return (\n parseWikiGraphLibraryUri(library.uri) ?? {\n isDefault: library.isDefault,\n kind: \"scope\",\n publicId: library.publicId,\n }\n );\n}\n\nasync function readIndexedArchiveResults<T>(\n target: ParsedWikiGraphLibraryUri,\n objectUri: string,\n operation: (\n document: ReadonlyDocument,\n archive: WikiGraphLibraryArchiveRecord,\n ) => Promise<T>,\n): Promise<T[]> {\n const library = await resolveWikiGraphLibrary(target);\n const archiveIds = await listWikiGraphLibraryIndexArchiveIdsForObject(\n target,\n objectUri,\n );\n\n if (archiveIds.length === 0) {\n if (!isTripleObjectUri(objectUri)) {\n throw new Error(`Wiki Graph library object was not found: ${objectUri}`);\n }\n\n // Library v1 cannot project every triple occurrence into the index yet.\n // Keep the archive scan explicit and restricted to triples so entity/chunk\n // lookups remain index-backed and do not silently regress to full scans.\n return await readUnindexedArchiveResults(target, objectUri, operation);\n }\n\n const results: T[] = [];\n for (const archiveId of archiveIds) {\n const archive = await getWikiGraphLibraryArchiveById(library, archiveId);\n if (!isReadableLibraryArchive(archive)) {\n throw new Error(\n `Wiki Graph library archive ${archiveId} is not readable while reading ${objectUri}.`,\n );\n }\n\n try {\n results.push(\n await readLibraryArchiveDocument(\n archive,\n async (document) => await operation(document, archive),\n ),\n );\n } catch (error) {\n throw new Error(\n `Failed to read Wiki Graph library archive ${archiveId} (${archive.uri}) for ${objectUri}: ${formatErrorMessage(error)}`,\n { cause: error },\n );\n }\n }\n\n if (results.length === 0) {\n throw new Error(`Wiki Graph library object was not found: ${objectUri}`);\n }\n return results;\n}\n\nasync function readUnindexedArchiveResults<T>(\n target: ParsedWikiGraphLibraryUri,\n objectUri: string,\n operation: (\n document: ReadonlyDocument,\n archive: WikiGraphLibraryArchiveRecord,\n ) => Promise<T>,\n): Promise<T[]> {\n const results: T[] = [];\n\n for (const archive of await listReadyLibraryArchives(target)) {\n try {\n results.push(\n await readLibraryArchiveDocument(\n archive,\n async (document) => await operation(document, archive),\n ),\n );\n } catch (error) {\n if (isArchiveObjectNotFoundError(error)) {\n continue;\n }\n throw new Error(\n `Failed to read Wiki Graph library archive ${archive.id} (${archive.uri}) for ${objectUri}: ${formatErrorMessage(error)}`,\n { cause: error },\n );\n }\n }\n\n if (results.length === 0) {\n throw new Error(`Wiki Graph library object was not found: ${objectUri}`);\n }\n return results;\n}\n\nfunction createMultiArchivePage(pages: readonly ArchivePage[]): ArchivePage {\n const [first] = pages;\n if (first === undefined) {\n throw new Error(\n \"Internal error: cannot merge an empty library page result.\",\n );\n }\n\n const sources = createLibrarySources(pages);\n if (sources.length === 1) {\n return first;\n }\n\n const {\n archiveId: _archiveId,\n libraryArchiveUri: _libraryArchiveUri,\n ...page\n } = first;\n\n return { ...page, sources };\n}\n\nfunction combinePageEvidencePreviews(\n pages: readonly ArchivePage[],\n limit: number,\n order: ArchiveFindOrder,\n): ArchiveFindEvidencePreview {\n const evidencePages = pages.flatMap((page) =>\n page.type === \"entity\" || page.type === \"triple\" ? [page] : [],\n );\n const orderedPages =\n order === \"doc-desc\" ? evidencePages.slice().reverse() : evidencePages;\n const sources = orderedPages.flatMap((page) =>\n page.evidence.sources.map((source) => ({\n ...source,\n ...(page.archiveId === undefined ? {} : { archiveId: page.archiveId }),\n ...(page.libraryArchiveUri === undefined\n ? {}\n : { libraryArchiveUri: page.libraryArchiveUri }),\n })),\n );\n const total = evidencePages.reduce(\n (sum, page) => sum + page.evidence.total,\n 0,\n );\n const pageSources = sources.slice(0, limit);\n const shown = pageSources.length;\n\n return {\n nextCursor: limit < total ? String(limit) : null,\n shown,\n sources: pageSources,\n total,\n };\n}\n\nfunction createEvidenceResult(\n items: readonly ArchiveEvidenceItem[],\n options: ArchiveEvidenceOptions,\n): ArchiveEvidence {\n const limit = options.limit ?? DEFAULT_LIBRARY_PAGE_LIMIT;\n const offset = parseLibraryObjectCursor(options.cursor, \"evidence\");\n const sorted = [...items].sort((left, right) =>\n compareLibraryEvidenceItems(left, right, options.order ?? \"doc-asc\"),\n );\n const pageItems = sorted.slice(offset, offset + limit);\n const nextOffset = offset + pageItems.length;\n\n return {\n items: pageItems,\n limit,\n nextCursor: nextOffset < sorted.length ? String(nextOffset) : null,\n };\n}\n\nfunction createRelatedResult(\n items: readonly ArchiveListItem[],\n options: ArchiveRelatedOptions,\n): ArchiveRelatedResult {\n const limit = options.limit ?? DEFAULT_LIBRARY_PAGE_LIMIT;\n const offset = parseLibraryObjectCursor(options.cursor, \"related\");\n const sorted = [...items].sort((left, right) =>\n compareLibraryListItems(left, right, options.order ?? \"doc-asc\"),\n );\n const pageItems = sorted.slice(offset, offset + limit);\n const nextOffset = offset + pageItems.length;\n\n return {\n items: pageItems,\n limit,\n nextCursor: nextOffset < sorted.length ? String(nextOffset) : null,\n };\n}\n\nexport function createLibrarySources(\n values: readonly {\n readonly archiveId?: number;\n readonly libraryArchiveUri?: string;\n }[],\n): readonly ArchiveLibrarySource[] {\n const sources = new Map<number, ArchiveLibrarySource>();\n for (const value of values) {\n if (\n value.archiveId === undefined ||\n value.libraryArchiveUri === undefined\n ) {\n continue;\n }\n sources.set(value.archiveId, {\n archiveId: value.archiveId,\n libraryArchiveUri: value.libraryArchiveUri,\n });\n }\n return [...sources.values()].sort(\n (left, right) => left.archiveId - right.archiveId,\n );\n}\n\nfunction compareLibraryEvidenceItems(\n left: ArchiveEvidenceItem,\n right: ArchiveEvidenceItem,\n order: \"doc-asc\" | \"doc-desc\",\n): number {\n const direction = order === \"doc-asc\" ? 1 : -1;\n return (\n (compareOptionalNumbers(left.archiveId, right.archiveId) ||\n left.chapterId - right.chapterId ||\n left.startSentenceIndex - right.startSentenceIndex ||\n left.endSentenceIndex - right.endSentenceIndex ||\n left.id.localeCompare(right.id)) * direction\n );\n}\n\nfunction compareLibraryListItems(\n left: ArchiveListItem,\n right: ArchiveListItem,\n order: \"doc-asc\" | \"doc-desc\",\n): number {\n const direction = order === \"doc-asc\" ? 1 : -1;\n return (\n (compareOptionalNumbers(left.archiveId, right.archiveId) ||\n left.id.localeCompare(right.id)) * direction\n );\n}\n\nfunction compareOptionalNumbers(\n left: number | undefined,\n right: number | undefined,\n): number {\n return (left ?? Number.MAX_SAFE_INTEGER) - (right ?? Number.MAX_SAFE_INTEGER);\n}\n\nfunction parseLibraryObjectCursor(\n cursor: string | undefined,\n kind: \"evidence\" | \"related\",\n): number {\n if (cursor === undefined) {\n return 0;\n }\n if (!/^(0|[1-9][0-9]*)$/u.test(cursor)) {\n throw new Error(`Invalid library ${kind} cursor: ${cursor}`);\n }\n return Number(cursor);\n}\n\nasync function listReadyLibraryArchives(\n target: ParsedWikiGraphLibraryUri,\n): Promise<readonly WikiGraphLibraryArchiveRecord[]> {\n await assertWikiGraphLibraryIndexReady(target);\n return (await listWikiGraphLibraryArchives(target)).filter(\n isReadableLibraryArchive,\n );\n}\n\nfunction shouldListTextStreams(options: ArchiveCollectionOptions): boolean {\n return (\n options.types !== undefined &&\n options.types.some((type) => type === \"source\" || type === \"summary\")\n );\n}\n\nfunction formatErrorMessage(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n\nfunction isArchiveObjectNotFoundError(error: unknown): boolean {\n return (\n error instanceof Error &&\n error.message.includes(\" was not found in this archive.\")\n );\n}\n\nfunction isTripleObjectUri(objectUri: string): boolean {\n return /^wikg:\\/\\/(?:chapter\\/[1-9][0-9]*\\/)?triple\\/Q[1-9][0-9]*\\/[^/]+\\/Q[1-9][0-9]*\\/?$/u.test(\n objectUri,\n );\n}\n"],"mappings":"AACA;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP;AAAA,EACE;AAAA,EACA;AAAA,OACK;AACP;AAAA,EACE;AAAA,EACA;AAAA,OACK;AACP,SAAS,8BAA8B;AAmBvC;AAAA,EACE;AAAA,EACA;AAAA,OAEK;AACP;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,OAEK;AACP;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAEP,MAAM,6BAA6B;AACnC,MAAM,uCAAuC;AAC7C,MAAM,gCAAgC;AAEtC,eAAsB,4BACpB,QACA,OACA,UAA8B,CAAC,GACH;AAC5B,MAAI,+BAA+B,OAAO,GAAG;AAC3C,WAAO,MAAM,oCAAoC,QAAQ,OAAO,OAAO;AAAA,EACzE;AAEA,QAAM,gBAAgB,gCAAgC,OAAO;AAC7D,QAAM,SAAS,MAAM,iCAAiC,QAAQ,OAAO;AAAA,IACnE,gBAAgB;AAAA,IAChB,cAAc;AAAA,EAChB,CAAC;AAED,MAAI,WAAW,QAAW;AACxB,WAAO,iBAAiB,OAAO,CAAC,GAAG,OAAO;AAAA,EAC5C;AAEA,QAAM,OAAyB,CAAC;AAChC,aAAW,aAAa,uBAAuB,MAAM,GAAG;AACtD,UAAM,UAAU,MAAM,8BAA8B,QAAQ,WAAW;AAAA,MACrE,WAAW;AAAA,IACb,CAAC;AACD,UAAM,SAAS,oBAAoB,OAAO;AAC1C,UAAM,WAAW,MAAM;AAAA,MACrB;AAAA,MACA,OAAO,aACL,MAAM,uBAAuB,UAAU;AAAA,QACrC,YAAY,OAAO,WAAW;AAAA,UAC5B,CAAC,QAAQ,IAAI,cAAc,QAAQ;AAAA,QACrC;AAAA,QACA,OAAO,OAAO;AAAA,QACd,UAAU,OAAO,SAAS;AAAA,UACxB,CAAC,QAAQ,IAAI,cAAc,QAAQ;AAAA,QACrC;AAAA,MACF,CAAC;AAAA,IACL;AAEA,SAAK,KAAK,GAAG,SAAS,IAAI,CAAC,SAAS,EAAE,GAAG,KAAK,GAAG,OAAO,EAAE,CAAC;AAAA,EAC7D;AAEA,SAAO,iBAAiB,OAAO,MAAM,SAAS,OAAO,KAAK;AAC5D;AAEA,eAAsB,mCACpB,QACA,OACA,UAA8B,CAAC,GACH;AAC5B,QAAM,QAAQ,sCAAsC,KAAK;AACzD,QAAM,WAAW,MAAM,6BAA6B,MAAM;AAC1D,QAAM,OAAO,SACV,IAAI,6BAA6B,EACjC,OAAO,CAAC,QAAQ,kCAAkC,KAAK,KAAK,CAAC;AAEhE,SAAO,iBAAiB,OAAO,MAAM,SAAS,OAAO,OAAO;AAC9D;AAEA,SAAS,gCAAgC,SAAqC;AAC5E,SAAO,KAAK;AAAA,KACT,QAAQ,SAAS,8BAChB;AAAA,IACF;AAAA,EACF;AACF;AAEA,SAAS,sCACP,OACmB;AACnB,SAAO,MACJ,KAAK,EACL,kBAAkB,EAClB,MAAM,MAAM,EACZ,OAAO,CAAC,SAAS,SAAS,EAAE;AACjC;AAEA,SAAS,kCACP,KACA,OACS;AACT,MAAI,MAAM,WAAW,GAAG;AACtB,WAAO;AAAA,EACT;AACA,QAAM,WACJ,GAAG,IAAI,EAAE;AAAA,EAAK,IAAI,KAAK;AAAA,EAAK,IAAI,OAAO,GAAG,kBAAkB;AAE9D,SAAO,MAAM,MAAM,CAAC,SAAS,SAAS,SAAS,IAAI,CAAC;AACtD;AAEA,SAAS,8BACP,SACgB;AAChB,QAAM,UAAU;AAAA,IACd,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,QAAQ,SAAS,WAAW;AAAA,EAC9B,EAAE,KAAK,IAAI;AAEX,SAAO;AAAA,IACL,WAAW,QAAQ;AAAA,IACnB,OAAO;AAAA,IACP,IAAI,QAAQ;AAAA,IACZ,mBAAmB,QAAQ;AAAA,IAC3B,SAAS;AAAA,IACT,OAAO,QAAQ;AAAA,IACf,MAAM;AAAA,EACR;AACF;AAEA,eAAsB,4BACpB,QACA,UAAoC,CAAC,GACH;AAClC,QAAM,OAAyB,CAAC;AAChC,QAAM,SAAS,MAAM,gCAAgC,QAAQ;AAAA,IAC3D,aAAa,sBAAsB,OAAO;AAAA,EAC5C,CAAC;AACD,QAAM,aAAa,uBAAuB,MAAM;AAChD,aAAW,aAAa,YAAY;AAClC,UAAM,UAAU,MAAM,8BAA8B,QAAQ,WAAW;AAAA,MACrE,WAAW;AAAA,IACb,CAAC;AACD,UAAM,SAAS,oBAAoB,OAAO;AAC1C,UAAM,WAAW,MAAM;AAAA,MACrB;AAAA,MACA,OAAO,aACL,MAAM,uBAAuB,UAAU;AAAA,QACrC,YAAY,OAAO,WAAW;AAAA,UAC5B,CAAC,QAAQ,IAAI,cAAc,QAAQ;AAAA,QACrC;AAAA,QACA,OAAO,OAAO;AAAA,QACd,UAAU,OAAO,SAAS;AAAA,UACxB,CAAC,QAAQ,IAAI,cAAc,QAAQ;AAAA,QACrC;AAAA,MACF,CAAC;AAAA,IACL;AAEA,SAAK,KAAK,GAAG,SAAS,IAAI,CAAC,SAAS,EAAE,GAAG,KAAK,GAAG,OAAO,EAAE,CAAC;AAAA,EAC7D;AAEA,SAAO,uBAAuB,MAAM,OAAO;AAC7C;AAEA,eAAsB,mCACpB,QACA,UAAoC,CAAC,GACH;AAClC,SAAO;AAAA,KACJ,MAAM,6BAA6B,MAAM,GAAG;AAAA,MAC3C;AAAA,IACF;AAAA,IACA;AAAA,EACF;AACF;AAEA,eAAsB,yBACpB,QACA,WACA,UAAiD,CAAC,GAC5B;AACtB,QAAM,QAAQ,MAAM;AAAA,IAClB;AAAA,IACA;AAAA,IACA,OAAO,UAAU,aAAa;AAAA,MAC5B,GAAI,MAAM,gBAAgB,UAAU,WAAW,OAAO;AAAA,MACtD,GAAG,oBAAoB,OAAO;AAAA,IAChC;AAAA,EACF;AAEA,QAAM,OAAO,uBAAuB,KAAK;AACzC,OAAK,KAAK,SAAS,YAAY,KAAK,SAAS,aAAa,MAAM,SAAS,GAAG;AAC1E,WAAO;AAAA,MACL,GAAG;AAAA,MACH,UAAU;AAAA,QACR;AAAA,QACA,QAAQ,iBAAiB;AAAA,QACzB,QAAQ,SAAS;AAAA,MACnB;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AACT;AAEA,eAAsB,6BACpB,QACA,WACA,UAAkC,CAAC,GACT;AAC1B,QAAM,QAAQ,QAAQ,SAAS;AAC/B,QAAM,SAAS,yBAAyB,QAAQ,QAAQ,UAAU;AAClE,QAAM,qBAAqB,SAAS;AACpC,QAAM,UAAU,MAAM;AAAA,IACpB;AAAA,IACA;AAAA,IACA,OAAO,UAAU,YAAY;AAC3B,YAAM,EAAE,QAAQ,SAAS,GAAG,eAAe,IAAI;AAC/C,YAAM,SAAS,MAAM,oBAAoB,UAAU,WAAW;AAAA,QAC5D,GAAG;AAAA,QACH,OAAO;AAAA,MACT,CAAC;AACD,YAAM,SAAS,oBAAoB,OAAO;AAE1C,aAAO;AAAA,QACL,GAAG;AAAA,QACH,OAAO,OAAO,MAAM;AAAA,UAClB,CAAC,UAA+B;AAAA,YAC9B,GAAG;AAAA,YACH,GAAG;AAAA,UACL;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AAAA,IACL,QAAQ,QAAQ,CAAC,WAAW,OAAO,KAAK;AAAA,IACxC;AAAA,EACF;AACF;AAEA,eAAsB,mCACpB,QACA,WACA,UAAiC,CAAC,GACH;AAC/B,QAAM,QAAQ,QAAQ,SAAS;AAC/B,QAAM,SAAS,yBAAyB,QAAQ,QAAQ,SAAS;AACjE,QAAM,qBAAqB,SAAS;AACpC,QAAM,UAAU,MAAM;AAAA,IACpB;AAAA,IACA;AAAA,IACA,OAAO,UAAU,YAAY;AAC3B,YAAM,EAAE,QAAQ,SAAS,GAAG,eAAe,IAAI;AAC/C,YAAM,SAAS,MAAM,0BAA0B,UAAU,WAAW;AAAA,QAClE,GAAG;AAAA,QACH,OAAO;AAAA,MACT,CAAC;AACD,YAAM,SAAS,oBAAoB,OAAO;AAE1C,aAAO;AAAA,QACL,GAAG;AAAA,QACH,OAAO,OAAO,MAAM;AAAA,UAClB,CAAC,UAA2B;AAAA,YAC1B,GAAG;AAAA,YACH,GAAG;AAAA,UACL;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AAAA,IACL,QAAQ,QAAQ,CAAC,WAAW,OAAO,KAAK;AAAA,IACxC;AAAA,EACF;AACF;AAEA,eAAsB,4BACpB,QACA,WACA,QACsB;AACtB,QAAM,QAAQ,MAAM;AAAA,IAClB;AAAA,IACA;AAAA,IACA,OAAO,UAAU,YAAY;AAC3B,YAAM,OAAO,MAAM,mBAAmB,UAAU,WAAW,MAAM;AACjE,YAAM,SAAS,oBAAoB,OAAO;AAE1C,aAAO;AAAA,QACL,GAAG;AAAA,QACH,QAAQ,EAAE,GAAG,KAAK,QAAQ,GAAG,OAAO;AAAA,QACpC,SAAS,KAAK,QAAQ,IAAI,CAAC,UAAU,EAAE,GAAG,MAAM,GAAG,OAAO,EAAE;AAAA,MAC9D;AAAA,IACF;AAAA,EACF;AACA,QAAM,CAAC,KAAK,IAAI;AAEhB,MAAI,UAAU,QAAW;AACvB,UAAM,IAAI,MAAM,4CAA4C,SAAS,EAAE;AAAA,EACzE;AAEA,SAAO;AAAA,IACL,QAAQ,uBAAuB,MAAM,IAAI,CAAC,SAAS,KAAK,MAAM,CAAC;AAAA,IAC/D;AAAA,IACA,SAAS,MAAM,QAAQ,CAAC,SAAS,KAAK,OAAO;AAAA,EAC/C;AACF;AAEA,eAAsB,uCACpB,WACoC;AACpC,QAAM,UAAU,MAAM,4BAA4B,SAAS;AAC3D,SACE,yBAAyB,QAAQ,GAAG,KAAK;AAAA,IACvC,WAAW,QAAQ;AAAA,IACnB,MAAM;AAAA,IACN,UAAU,QAAQ;AAAA,EACpB;AAEJ;AAEA,eAAe,0BACb,QACA,WACA,WAIc;AACd,QAAM,UAAU,MAAM,wBAAwB,MAAM;AACpD,QAAM,aAAa,MAAM;AAAA,IACvB;AAAA,IACA;AAAA,EACF;AAEA,MAAI,WAAW,WAAW,GAAG;AAC3B,QAAI,CAAC,kBAAkB,SAAS,GAAG;AACjC,YAAM,IAAI,MAAM,4CAA4C,SAAS,EAAE;AAAA,IACzE;AAKA,WAAO,MAAM,4BAA4B,QAAQ,WAAW,SAAS;AAAA,EACvE;AAEA,QAAM,UAAe,CAAC;AACtB,aAAW,aAAa,YAAY;AAClC,UAAM,UAAU,MAAM,+BAA+B,SAAS,SAAS;AACvE,QAAI,CAAC,yBAAyB,OAAO,GAAG;AACtC,YAAM,IAAI;AAAA,QACR,8BAA8B,SAAS,kCAAkC,SAAS;AAAA,MACpF;AAAA,IACF;AAEA,QAAI;AACF,cAAQ;AAAA,QACN,MAAM;AAAA,UACJ;AAAA,UACA,OAAO,aAAa,MAAM,UAAU,UAAU,OAAO;AAAA,QACvD;AAAA,MACF;AAAA,IACF,SAAS,OAAO;AACd,YAAM,IAAI;AAAA,QACR,6CAA6C,SAAS,KAAK,QAAQ,GAAG,SAAS,SAAS,KAAK,mBAAmB,KAAK,CAAC;AAAA,QACtH,EAAE,OAAO,MAAM;AAAA,MACjB;AAAA,IACF;AAAA,EACF;AAEA,MAAI,QAAQ,WAAW,GAAG;AACxB,UAAM,IAAI,MAAM,4CAA4C,SAAS,EAAE;AAAA,EACzE;AACA,SAAO;AACT;AAEA,eAAe,4BACb,QACA,WACA,WAIc;AACd,QAAM,UAAe,CAAC;AAEtB,aAAW,WAAW,MAAM,yBAAyB,MAAM,GAAG;AAC5D,QAAI;AACF,cAAQ;AAAA,QACN,MAAM;AAAA,UACJ;AAAA,UACA,OAAO,aAAa,MAAM,UAAU,UAAU,OAAO;AAAA,QACvD;AAAA,MACF;AAAA,IACF,SAAS,OAAO;AACd,UAAI,6BAA6B,KAAK,GAAG;AACvC;AAAA,MACF;AACA,YAAM,IAAI;AAAA,QACR,6CAA6C,QAAQ,EAAE,KAAK,QAAQ,GAAG,SAAS,SAAS,KAAK,mBAAmB,KAAK,CAAC;AAAA,QACvH,EAAE,OAAO,MAAM;AAAA,MACjB;AAAA,IACF;AAAA,EACF;AAEA,MAAI,QAAQ,WAAW,GAAG;AACxB,UAAM,IAAI,MAAM,4CAA4C,SAAS,EAAE;AAAA,EACzE;AACA,SAAO;AACT;AAEA,SAAS,uBAAuB,OAA4C;AAC1E,QAAM,CAAC,KAAK,IAAI;AAChB,MAAI,UAAU,QAAW;AACvB,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AAEA,QAAM,UAAU,qBAAqB,KAAK;AAC1C,MAAI,QAAQ,WAAW,GAAG;AACxB,WAAO;AAAA,EACT;AAEA,QAAM;AAAA,IACJ,WAAW;AAAA,IACX,mBAAmB;AAAA,IACnB,GAAG;AAAA,EACL,IAAI;AAEJ,SAAO,EAAE,GAAG,MAAM,QAAQ;AAC5B;AAEA,SAAS,4BACP,OACA,OACA,OAC4B;AAC5B,QAAM,gBAAgB,MAAM;AAAA,IAAQ,CAAC,SACnC,KAAK,SAAS,YAAY,KAAK,SAAS,WAAW,CAAC,IAAI,IAAI,CAAC;AAAA,EAC/D;AACA,QAAM,eACJ,UAAU,aAAa,cAAc,MAAM,EAAE,QAAQ,IAAI;AAC3D,QAAM,UAAU,aAAa;AAAA,IAAQ,CAAC,SACpC,KAAK,SAAS,QAAQ,IAAI,CAAC,YAAY;AAAA,MACrC,GAAG;AAAA,MACH,GAAI,KAAK,cAAc,SAAY,CAAC,IAAI,EAAE,WAAW,KAAK,UAAU;AAAA,MACpE,GAAI,KAAK,sBAAsB,SAC3B,CAAC,IACD,EAAE,mBAAmB,KAAK,kBAAkB;AAAA,IAClD,EAAE;AAAA,EACJ;AACA,QAAM,QAAQ,cAAc;AAAA,IAC1B,CAAC,KAAK,SAAS,MAAM,KAAK,SAAS;AAAA,IACnC;AAAA,EACF;AACA,QAAM,cAAc,QAAQ,MAAM,GAAG,KAAK;AAC1C,QAAM,QAAQ,YAAY;AAE1B,SAAO;AAAA,IACL,YAAY,QAAQ,QAAQ,OAAO,KAAK,IAAI;AAAA,IAC5C;AAAA,IACA,SAAS;AAAA,IACT;AAAA,EACF;AACF;AAEA,SAAS,qBACP,OACA,SACiB;AACjB,QAAM,QAAQ,QAAQ,SAAS;AAC/B,QAAM,SAAS,yBAAyB,QAAQ,QAAQ,UAAU;AAClE,QAAM,SAAS,CAAC,GAAG,KAAK,EAAE;AAAA,IAAK,CAAC,MAAM,UACpC,4BAA4B,MAAM,OAAO,QAAQ,SAAS,SAAS;AAAA,EACrE;AACA,QAAM,YAAY,OAAO,MAAM,QAAQ,SAAS,KAAK;AACrD,QAAM,aAAa,SAAS,UAAU;AAEtC,SAAO;AAAA,IACL,OAAO;AAAA,IACP;AAAA,IACA,YAAY,aAAa,OAAO,SAAS,OAAO,UAAU,IAAI;AAAA,EAChE;AACF;AAEA,SAAS,oBACP,OACA,SACsB;AACtB,QAAM,QAAQ,QAAQ,SAAS;AAC/B,QAAM,SAAS,yBAAyB,QAAQ,QAAQ,SAAS;AACjE,QAAM,SAAS,CAAC,GAAG,KAAK,EAAE;AAAA,IAAK,CAAC,MAAM,UACpC,wBAAwB,MAAM,OAAO,QAAQ,SAAS,SAAS;AAAA,EACjE;AACA,QAAM,YAAY,OAAO,MAAM,QAAQ,SAAS,KAAK;AACrD,QAAM,aAAa,SAAS,UAAU;AAEtC,SAAO;AAAA,IACL,OAAO;AAAA,IACP;AAAA,IACA,YAAY,aAAa,OAAO,SAAS,OAAO,UAAU,IAAI;AAAA,EAChE;AACF;AAEO,SAAS,qBACd,QAIiC;AACjC,QAAM,UAAU,oBAAI,IAAkC;AACtD,aAAW,SAAS,QAAQ;AAC1B,QACE,MAAM,cAAc,UACpB,MAAM,sBAAsB,QAC5B;AACA;AAAA,IACF;AACA,YAAQ,IAAI,MAAM,WAAW;AAAA,MAC3B,WAAW,MAAM;AAAA,MACjB,mBAAmB,MAAM;AAAA,IAC3B,CAAC;AAAA,EACH;AACA,SAAO,CAAC,GAAG,QAAQ,OAAO,CAAC,EAAE;AAAA,IAC3B,CAAC,MAAM,UAAU,KAAK,YAAY,MAAM;AAAA,EAC1C;AACF;AAEA,SAAS,4BACP,MACA,OACA,OACQ;AACR,QAAM,YAAY,UAAU,YAAY,IAAI;AAC5C,UACG,uBAAuB,KAAK,WAAW,MAAM,SAAS,KACrD,KAAK,YAAY,MAAM,aACvB,KAAK,qBAAqB,MAAM,sBAChC,KAAK,mBAAmB,MAAM,oBAC9B,KAAK,GAAG,cAAc,MAAM,EAAE,KAAK;AAEzC;AAEA,SAAS,wBACP,MACA,OACA,OACQ;AACR,QAAM,YAAY,UAAU,YAAY,IAAI;AAC5C,UACG,uBAAuB,KAAK,WAAW,MAAM,SAAS,KACrD,KAAK,GAAG,cAAc,MAAM,EAAE,KAAK;AAEzC;AAEA,SAAS,uBACP,MACA,OACQ;AACR,UAAQ,QAAQ,OAAO,qBAAqB,SAAS,OAAO;AAC9D;AAEA,SAAS,yBACP,QACA,MACQ;AACR,MAAI,WAAW,QAAW;AACxB,WAAO;AAAA,EACT;AACA,MAAI,CAAC,qBAAqB,KAAK,MAAM,GAAG;AACtC,UAAM,IAAI,MAAM,mBAAmB,IAAI,YAAY,MAAM,EAAE;AAAA,EAC7D;AACA,SAAO,OAAO,MAAM;AACtB;AAEA,eAAe,yBACb,QACmD;AACnD,QAAM,iCAAiC,MAAM;AAC7C,UAAQ,MAAM,6BAA6B,MAAM,GAAG;AAAA,IAClD;AAAA,EACF;AACF;AAEA,SAAS,sBAAsB,SAA4C;AACzE,SACE,QAAQ,UAAU,UAClB,QAAQ,MAAM,KAAK,CAAC,SAAS,SAAS,YAAY,SAAS,SAAS;AAExE;AAEA,SAAS,mBAAmB,OAAwB;AAClD,SAAO,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAC9D;AAEA,SAAS,6BAA6B,OAAyB;AAC7D,SACE,iBAAiB,SACjB,MAAM,QAAQ,SAAS,iCAAiC;AAE5D;AAEA,SAAS,kBAAkB,WAA4B;AACrD,SAAO,sFAAsF;AAAA,IAC3F;AAAA,EACF;AACF;","names":[]}
@@ -26,6 +26,7 @@ declare function createWikiGraphLibrary(input: {
26
26
  }): Promise<WikiGraphLibraryRecord>;
27
27
  declare function listWikiGraphLibraries(): Promise<readonly WikiGraphLibraryRecord[]>;
28
28
  declare function resolveWikiGraphLibrary(target: ParsedWikiGraphLibraryUri): Promise<WikiGraphLibraryRecord>;
29
+ declare function resolveWikiGraphLibraryForScan(target: ParsedWikiGraphLibraryUri): Promise<WikiGraphLibraryRecord>;
29
30
  declare function resolveWikiGraphLibraryById(id: number): Promise<WikiGraphLibraryRecord>;
30
31
  declare function listWikiGraphLibraryScope(target: ParsedWikiGraphLibraryUri): Promise<readonly []>;
31
32
  declare function removeWikiGraphLibrary(target: ParsedWikiGraphLibraryUri): Promise<WikiGraphLibraryRecord>;
@@ -36,4 +37,4 @@ declare function putWikiGraphLibraryMetadata(target: ParsedWikiGraphLibraryUri,
36
37
  declare function deleteWikiGraphLibraryMetadataKey(target: ParsedWikiGraphLibraryUri, key: string): Promise<Readonly<Record<string, unknown>>>;
37
38
  declare function clearWikiGraphLibraryMetadata(target: ParsedWikiGraphLibraryUri): Promise<Readonly<Record<string, unknown>>>;
38
39
 
39
- export { type ParsedWikiGraphLibraryUri, type WikiGraphLibraryRecord, clearWikiGraphLibraryMetadata, createWikiGraphLibrary, deleteWikiGraphLibraryMetadataKey, ensureDefaultWikiGraphLibrary, formatWikiGraphLibraryUri, getWikiGraphLibraryMetadata, isWikiGraphLibraryUri, listWikiGraphLibraries, listWikiGraphLibraryScope, parseWikiGraphLibraryUri, putWikiGraphLibraryMetadata, removeWikiGraphLibrary, replaceWikiGraphLibraryMetadata, resolveDefaultWikiGraphLibraryDirectoryPath, resolveWikiGraphLibrary, resolveWikiGraphLibraryById, resolveWikiGraphLibraryStagingDirectoryPath, updateWikiGraphLibraryFolderPathForRebind };
40
+ export { type ParsedWikiGraphLibraryUri, type WikiGraphLibraryRecord, clearWikiGraphLibraryMetadata, createWikiGraphLibrary, deleteWikiGraphLibraryMetadataKey, ensureDefaultWikiGraphLibrary, formatWikiGraphLibraryUri, getWikiGraphLibraryMetadata, isWikiGraphLibraryUri, listWikiGraphLibraries, listWikiGraphLibraryScope, parseWikiGraphLibraryUri, putWikiGraphLibraryMetadata, removeWikiGraphLibrary, replaceWikiGraphLibraryMetadata, resolveDefaultWikiGraphLibraryDirectoryPath, resolveWikiGraphLibrary, resolveWikiGraphLibraryById, resolveWikiGraphLibraryForScan, resolveWikiGraphLibraryStagingDirectoryPath, updateWikiGraphLibraryFolderPathForRebind };
@@ -308,6 +308,15 @@ async function resolveWikiGraphLibrary(target) {
308
308
  async (database) => await requireLibraryRecordByPublicId(database, target.publicId)
309
309
  );
310
310
  }
311
+ async function resolveWikiGraphLibraryForScan(target) {
312
+ if (!target.isDefault) {
313
+ return await resolveWikiGraphLibrary(target);
314
+ }
315
+ const existing = await withLibraryRegistryDatabase(
316
+ async (database) => await readDefaultLibraryRecord(database)
317
+ );
318
+ return existing ?? await ensureDefaultWikiGraphLibrary();
319
+ }
311
320
  async function resolveWikiGraphLibraryById(id) {
312
321
  return await withLibraryRegistryDatabase(
313
322
  async (database) => await requireLibraryRecordById(database, id)
@@ -585,6 +594,7 @@ export {
585
594
  resolveDefaultWikiGraphLibraryDirectoryPath,
586
595
  resolveWikiGraphLibrary,
587
596
  resolveWikiGraphLibraryById,
597
+ resolveWikiGraphLibraryForScan,
588
598
  resolveWikiGraphLibraryStagingDirectoryPath,
589
599
  updateWikiGraphLibraryFolderPathForRebind
590
600
  };
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/library/registry.ts"],"sourcesContent":["import { randomBytes } from \"crypto\";\nimport { constants } from \"fs\";\nimport { access, mkdir, stat } from \"fs/promises\";\nimport { join, resolve } from \"path\";\n\nimport {\n getNumber,\n getString,\n type Database,\n type SqlRow,\n} from \"../document/database.js\";\nimport { openSharedStateDatabase } from \"../document/index.js\";\nimport {\n resolveWikiGraphCoreDatabasePath,\n resolveWikiGraphHomeDirectoryPath,\n resolveWikiGraphStagingDirectoryPath,\n} from \"../runtime/common/wiki-graph/dir.js\";\nimport {\n parseWikiGraphUriSyntax,\n WIKI_GRAPH_ARCHIVE_EXTENSION,\n} from \"../runtime/common/wiki-graph/uri.js\";\nimport { isNodeError } from \"../utils/node-error.js\";\nimport { withWikiGraphLibraryLock } from \"./lock.js\";\nimport { RESERVED_LIBRARY_URI_SEGMENTS } from \"./segments.js\";\n\nconst DEFAULT_LIBRARY_FOLDER_NAME = \"default-library\";\nconst PUBLIC_ID_BYTES = 6;\n\nconst RESERVED_METADATA_KEYS = new Set([\n \"id\",\n \"public_id\",\n \"publicId\",\n \"folder_path\",\n \"folderPath\",\n \"is_default\",\n \"isDefault\",\n \"staging_path\",\n \"stagingPath\",\n \"created_at\",\n \"createdAt\",\n \"updated_at\",\n \"updatedAt\",\n \"uri\",\n]);\n\nconst LIBRARY_REGISTRY_SCHEMA_SQL = `\n PRAGMA journal_mode = WAL;\n\n CREATE TABLE IF NOT EXISTS libraries (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n public_id TEXT NOT NULL UNIQUE,\n folder_path TEXT NOT NULL UNIQUE,\n is_default INTEGER NOT NULL DEFAULT 0 CHECK (is_default IN (0, 1)),\n created_at TEXT NOT NULL,\n updated_at TEXT NOT NULL\n );\n\n CREATE UNIQUE INDEX IF NOT EXISTS idx_libraries_single_default\n ON libraries(is_default)\n WHERE is_default = 1;\n\n CREATE TABLE IF NOT EXISTS library_metadata (\n library_id INTEGER NOT NULL,\n key TEXT NOT NULL,\n value_json TEXT NOT NULL,\n updated_at TEXT NOT NULL,\n PRIMARY KEY (library_id, key)\n );\n\n CREATE INDEX IF NOT EXISTS idx_library_metadata_library\n ON library_metadata(library_id);\n`;\n\nexport interface WikiGraphLibraryRecord {\n readonly id: number;\n readonly publicId: string;\n readonly uri: string;\n readonly folderPath: string;\n readonly isDefault: boolean;\n readonly stagingPath: string;\n readonly createdAt: string;\n readonly updatedAt: string;\n}\n\nexport interface ParsedWikiGraphLibraryUri {\n readonly archivePublicId?: string;\n readonly kind:\n | \"archive\"\n | \"archive-collection\"\n | \"archive-path\"\n | \"archive-tree\"\n | \"metadata\"\n | \"path\"\n | \"registry\"\n | \"scope\";\n readonly objectUri?: string;\n readonly publicId?: string;\n readonly isDefault: boolean;\n}\n\nexport function isWikiGraphLibraryUri(uri: string | undefined): uri is string {\n if (uri === undefined) {\n return false;\n }\n try {\n const syntax = parseWikiGraphUriSyntax(uri);\n if (syntax.protocol !== \"wikg\" || syntax.path[0] !== \"lib\") {\n return false;\n }\n if (syntax.path.some((segment) => segment.endsWith(\".lib\"))) {\n return true;\n }\n const target = parseWikiGraphLibraryUri(uri);\n return (\n target !== undefined &&\n (target.kind !== \"archive\" || target.objectUri === undefined)\n );\n } catch {\n return false;\n }\n}\n\nexport function parseWikiGraphLibraryUri(\n uri: string,\n): ParsedWikiGraphLibraryUri | undefined {\n if (!uri.includes(\"://\")) {\n return undefined;\n }\n const parsed = parseWikiGraphUriSyntax(uri);\n if (parsed.protocol !== \"wikg\" || parsed.path[0] !== \"lib\") {\n return undefined;\n }\n\n const segments = parsed.path.slice(1);\n const fragment = formatWikiGraphUriFragment(parsed.fragment);\n\n if (segments.length === 0) {\n rejectLibraryStructureFragment(uri, fragment);\n return { isDefault: true, kind: \"scope\" };\n }\n if (segments.some((part) => part.endsWith(WIKI_GRAPH_ARCHIVE_EXTENSION))) {\n return undefined;\n }\n\n if (segments.some((segment) => segment.endsWith(\".lib\"))) {\n throw new Error(\n `Invalid Wiki Graph library URI: ${uri}. Use wikg://lib/<lib-id> and wikg://lib/<lib-id>/arc/<arc-id>; .lib suffixes are no longer supported.`,\n );\n }\n\n const [first, second, third, ...rest] = segments;\n if (first === \"registry\" && second === undefined) {\n rejectLibraryStructureFragment(uri, fragment);\n return { isDefault: true, kind: \"registry\" };\n }\n if (first === \"meta\" && second === undefined) {\n rejectLibraryStructureFragment(uri, fragment);\n return { isDefault: true, kind: \"metadata\" };\n }\n if (first === \"path\" && second === undefined) {\n rejectLibraryStructureFragment(uri, fragment);\n return { isDefault: true, kind: \"path\" };\n }\n\n const defaultLibraryScopeMatch =\n /^(index|chapter|chunk|entity|triple)$/u.exec(first ?? \"\");\n if (defaultLibraryScopeMatch?.[1] !== undefined) {\n return {\n isDefault: true,\n kind: \"scope\",\n objectUri: formatWikiGraphLibraryObjectUri(\n [first, second, third, ...rest].filter(Boolean).join(\"/\"),\n fragment,\n ),\n };\n }\n\n if (first === \"arc\") {\n return parseLibraryArcUri(uri, undefined, segments.slice(1), fragment);\n }\n\n if (first === undefined || RESERVED_LIBRARY_URI_SEGMENTS.has(first)) {\n throw new Error(\n `Invalid Wiki Graph library URI: ${uri}. Reserved library URI segment: ${first ?? \"\"}.`,\n );\n }\n if (second === undefined) {\n rejectLibraryStructureFragment(uri, fragment);\n return { isDefault: false, kind: \"scope\", publicId: first };\n }\n if (second === \"meta\" && third === undefined) {\n rejectLibraryStructureFragment(uri, fragment);\n return { isDefault: false, kind: \"metadata\", publicId: first };\n }\n if (second === \"path\" && third === undefined) {\n rejectLibraryStructureFragment(uri, fragment);\n return { isDefault: false, kind: \"path\", publicId: first };\n }\n if (/^(index|chapter|chunk|entity|triple)$/u.test(second)) {\n return {\n isDefault: false,\n kind: \"scope\",\n objectUri: formatWikiGraphLibraryObjectUri(\n [second, third, ...rest].filter(Boolean).join(\"/\"),\n fragment,\n ),\n publicId: first,\n };\n }\n if (second === \"arc\") {\n return parseLibraryArcUri(uri, first, segments.slice(2), fragment);\n }\n\n throw new Error(\n `Invalid Wiki Graph library URI: ${uri}. Expected wikg://lib, wikg://lib/registry, wikg://lib/<lib-id>, or <lib-scope>/arc/<arc-id>.`,\n );\n}\n\nfunction parseLibraryArcUri(\n uri: string,\n publicId: string | undefined,\n segments: readonly string[],\n fragment: string | undefined,\n): ParsedWikiGraphLibraryUri {\n const isDefault = publicId === undefined;\n const [first, second, ...rest] = segments;\n const base = { isDefault, ...(publicId === undefined ? {} : { publicId }) };\n if (first === undefined) {\n rejectLibraryStructureFragment(uri, fragment);\n return { ...base, kind: \"archive-collection\" };\n }\n if (/^(chapter|chunk|entity|triple)$/u.test(first)) {\n return {\n ...base,\n kind: \"scope\",\n objectUri: formatWikiGraphLibraryObjectUri(\n [first, second, ...rest].filter(Boolean).join(\"/\"),\n fragment,\n ),\n };\n }\n if (first === \"tree\" && second === undefined) {\n rejectLibraryStructureFragment(uri, fragment);\n return { ...base, kind: \"archive-tree\" };\n }\n if (RESERVED_LIBRARY_URI_SEGMENTS.has(first)) {\n throw new Error(\n `Invalid Wiki Graph library URI: ${uri}. Reserved archive member URI segment: ${first}.`,\n );\n }\n if (second === undefined) {\n rejectLibraryStructureFragment(uri, fragment);\n return { ...base, archivePublicId: first, kind: \"archive\" };\n }\n if (second === \"path\" && rest.length === 0) {\n rejectLibraryStructureFragment(uri, fragment);\n return { ...base, archivePublicId: first, kind: \"archive-path\" };\n }\n return {\n ...base,\n archivePublicId: first,\n kind: \"archive\",\n objectUri: formatWikiGraphLibraryObjectUri(\n [second, ...rest].join(\"/\"),\n fragment,\n ),\n };\n}\n\nfunction rejectLibraryStructureFragment(\n uri: string,\n fragment: string | undefined,\n): void {\n if (fragment !== undefined) {\n throw new Error(\n `Invalid Wiki Graph library URI: ${uri}. This library URI target does not support fragments.`,\n );\n }\n}\n\nfunction formatWikiGraphLibraryObjectUri(\n path: string,\n fragment?: string,\n): string {\n return `wikg://${path.replace(/^\\/+|\\/+$/gu, \"\")}${\n fragment === undefined ? \"\" : `#${fragment}`\n }`;\n}\n\nfunction formatWikiGraphUriFragment(\n fragment:\n | number\n | { readonly begin: number; readonly end: number }\n | undefined,\n): string | undefined {\n if (fragment === undefined) {\n return undefined;\n }\n if (typeof fragment === \"number\") {\n return String(fragment);\n }\n\n return `${fragment.begin}..${fragment.end}`;\n}\n\nexport function formatWikiGraphLibraryUri(publicId?: string): string {\n return publicId === undefined ? \"wikg://lib\" : `wikg://lib/${publicId}`;\n}\n\nexport function resolveDefaultWikiGraphLibraryDirectoryPath(): string {\n return join(resolveWikiGraphHomeDirectoryPath(), DEFAULT_LIBRARY_FOLDER_NAME);\n}\n\nexport function resolveWikiGraphLibraryStagingDirectoryPath(\n id: number,\n): string {\n return join(resolveWikiGraphStagingDirectoryPath(), \"library\", String(id));\n}\n\nexport async function ensureDefaultWikiGraphLibrary(): Promise<WikiGraphLibraryRecord> {\n return await withLibraryRegistryDatabase(async (database) => {\n const library = await database.transaction(async () => {\n const existing = await readDefaultLibraryRecord(database);\n if (existing !== undefined) {\n return existing;\n }\n\n const now = new Date().toISOString();\n const publicId = await createUniqueLibraryPublicId(database);\n const folderPath = resolveDefaultWikiGraphLibraryDirectoryPath();\n\n await database.run(\n `\n INSERT INTO libraries (public_id, folder_path, is_default, created_at, updated_at)\n VALUES (?, ?, 1, ?, ?)\n `,\n [publicId, folderPath, now, now],\n );\n\n return await requireDefaultLibraryRecord(database);\n });\n\n await mkdir(library.folderPath, { recursive: true });\n return library;\n });\n}\n\nexport async function createWikiGraphLibrary(input: {\n readonly folderPath: string;\n}): Promise<WikiGraphLibraryRecord> {\n const folderPath = resolve(input.folderPath);\n if (await pathExists(folderPath)) {\n throw new Error(`Library folder already exists: ${folderPath}`);\n }\n\n return await withLibraryRegistryDatabase(async (database) => {\n return await database.transaction(async () => {\n const now = new Date().toISOString();\n const publicId = await createUniqueLibraryPublicId(database);\n\n await database.run(\n `\n INSERT INTO libraries (public_id, folder_path, is_default, created_at, updated_at)\n VALUES (?, ?, 0, ?, ?)\n `,\n [publicId, folderPath, now, now],\n );\n await mkdir(folderPath);\n\n return await requireLibraryRecordByPublicId(database, publicId);\n });\n });\n}\n\nexport async function listWikiGraphLibraries(): Promise<\n readonly WikiGraphLibraryRecord[]\n> {\n await ensureDefaultWikiGraphLibrary();\n return await withLibraryRegistryDatabase(\n async (database) =>\n await database.queryAll(\n `\n SELECT id, public_id, folder_path, is_default, created_at, updated_at\n FROM libraries\n ORDER BY is_default DESC, public_id\n `,\n undefined,\n mapLibraryRecord,\n ),\n );\n}\n\nexport async function resolveWikiGraphLibrary(\n target: ParsedWikiGraphLibraryUri,\n): Promise<WikiGraphLibraryRecord> {\n if (target.isDefault) {\n return await ensureDefaultWikiGraphLibrary();\n }\n if (target.publicId === undefined) {\n throw new Error(\"Missing library id.\");\n }\n\n return await withLibraryRegistryDatabase(\n async (database) =>\n await requireLibraryRecordByPublicId(database, target.publicId!),\n );\n}\n\nexport async function resolveWikiGraphLibraryById(\n id: number,\n): Promise<WikiGraphLibraryRecord> {\n return await withLibraryRegistryDatabase(\n async (database) => await requireLibraryRecordById(database, id),\n );\n}\n\nexport async function listWikiGraphLibraryScope(\n target: ParsedWikiGraphLibraryUri,\n): Promise<readonly []> {\n await resolveWikiGraphLibrary(target);\n return [];\n}\n\nexport async function removeWikiGraphLibrary(\n target: ParsedWikiGraphLibraryUri,\n): Promise<WikiGraphLibraryRecord> {\n const library = await resolveWikiGraphLibrary(target);\n if (library.isDefault) {\n throw new Error(\n \"The default library is managed by the system and cannot be removed.\",\n );\n }\n\n await withWikiGraphLibraryLock(library.id, \"write\", async () => {\n await withLibraryRegistryDatabase(async (database) => {\n await database.transaction(async () => {\n await database.run(\n \"DELETE FROM library_metadata WHERE library_id = ?\",\n [library.id],\n );\n await database.run(\"DELETE FROM libraries WHERE id = ?\", [library.id]);\n });\n });\n });\n\n return library;\n}\n\nexport async function updateWikiGraphLibraryFolderPathForRebind(\n library: WikiGraphLibraryRecord,\n inputFolderPath: string,\n): Promise<WikiGraphLibraryRecord> {\n const folderPath = resolve(inputFolderPath);\n let folderStats;\n try {\n folderStats = await stat(folderPath);\n } catch (error) {\n if (isNodeError(error) && error.code === \"ENOENT\") {\n throw new Error(`Library path set does not exist: ${folderPath}`);\n }\n throw new Error(\n `Library path set is not accessible: ${folderPath}: ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n if (!folderStats.isDirectory()) {\n throw new Error(\n `Library path set must be an existing directory: ${folderPath}`,\n );\n }\n try {\n await access(folderPath, constants.R_OK);\n } catch (error) {\n throw new Error(\n `Library path set is not accessible: ${folderPath}: ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n\n return await withLibraryRegistryDatabase(async (database) => {\n return await database.transaction(async () => {\n const existing = await database.queryOne(\n \"SELECT id FROM libraries WHERE folder_path = ?\",\n [folderPath],\n (row) => getNumber(row, \"id\"),\n );\n if (existing !== undefined && existing !== library.id) {\n throw new Error(\n `Library path set is already bound to another library: ${folderPath}`,\n );\n }\n\n await database.run(\n \"UPDATE libraries SET folder_path = ?, updated_at = ? WHERE id = ?\",\n [folderPath, new Date().toISOString(), library.id],\n );\n return await requireLibraryRecordById(database, library.id);\n });\n });\n}\n\nexport async function getWikiGraphLibraryMetadata(\n target: ParsedWikiGraphLibraryUri,\n): Promise<Readonly<Record<string, unknown>>> {\n const library = await resolveWikiGraphLibrary(target);\n\n return await withLibraryRegistryDatabase(\n async (database) => await readLibraryMetadataMap(database, library.id),\n );\n}\n\nexport async function replaceWikiGraphLibraryMetadata(\n target: ParsedWikiGraphLibraryUri,\n map: Readonly<Record<string, unknown>>,\n): Promise<Readonly<Record<string, unknown>>> {\n rejectReservedMetadataKeys(Object.keys(map));\n const library = await resolveWikiGraphLibrary(target);\n\n return await withLibraryRegistryDatabase(async (database) => {\n await database.transaction(async () => {\n await database.run(\"DELETE FROM library_metadata WHERE library_id = ?\", [\n library.id,\n ]);\n for (const [key, value] of Object.entries(map)) {\n await putLibraryMetadata(database, library.id, key, value);\n }\n });\n return await readLibraryMetadataMap(database, library.id);\n });\n}\n\nexport async function putWikiGraphLibraryMetadata(\n target: ParsedWikiGraphLibraryUri,\n key: string,\n value: unknown,\n): Promise<Readonly<Record<string, unknown>>> {\n rejectReservedMetadataKeys([key]);\n const library = await resolveWikiGraphLibrary(target);\n\n return await withLibraryRegistryDatabase(async (database) => {\n await putLibraryMetadata(database, library.id, key, value);\n return await readLibraryMetadataMap(database, library.id);\n });\n}\n\nexport async function deleteWikiGraphLibraryMetadataKey(\n target: ParsedWikiGraphLibraryUri,\n key: string,\n): Promise<Readonly<Record<string, unknown>>> {\n const library = await resolveWikiGraphLibrary(target);\n\n return await withLibraryRegistryDatabase(async (database) => {\n await database.run(\n \"DELETE FROM library_metadata WHERE library_id = ? AND key = ?\",\n [library.id, key],\n );\n return await readLibraryMetadataMap(database, library.id);\n });\n}\n\nexport async function clearWikiGraphLibraryMetadata(\n target: ParsedWikiGraphLibraryUri,\n): Promise<Readonly<Record<string, unknown>>> {\n const library = await resolveWikiGraphLibrary(target);\n\n return await withLibraryRegistryDatabase(async (database) => {\n await database.run(\"DELETE FROM library_metadata WHERE library_id = ?\", [\n library.id,\n ]);\n return await readLibraryMetadataMap(database, library.id);\n });\n}\n\nasync function withLibraryRegistryDatabase<T>(\n operation: (database: Database) => Promise<T>,\n): Promise<T> {\n const database = await openSharedStateDatabase(\n resolveWikiGraphCoreDatabasePath(),\n LIBRARY_REGISTRY_SCHEMA_SQL,\n );\n\n try {\n return await operation(database);\n } finally {\n await database.close();\n }\n}\n\nasync function readDefaultLibraryRecord(\n database: Database,\n): Promise<WikiGraphLibraryRecord | undefined> {\n return await database.queryOne(\n `\n SELECT id, public_id, folder_path, is_default, created_at, updated_at\n FROM libraries\n WHERE is_default = 1\n `,\n undefined,\n mapLibraryRecord,\n );\n}\n\nasync function requireDefaultLibraryRecord(\n database: Database,\n): Promise<WikiGraphLibraryRecord> {\n const record = await readDefaultLibraryRecord(database);\n if (record === undefined) {\n throw new Error(\"Default library registry record is missing.\");\n }\n return record;\n}\n\nasync function requireLibraryRecordByPublicId(\n database: Database,\n publicId: string,\n): Promise<WikiGraphLibraryRecord> {\n const record = await database.queryOne(\n `\n SELECT id, public_id, folder_path, is_default, created_at, updated_at\n FROM libraries\n WHERE public_id = ?\n `,\n [publicId],\n mapLibraryRecord,\n );\n\n if (record === undefined) {\n throw new Error(`Unknown Wiki Graph library: ${publicId}`);\n }\n return record;\n}\n\nasync function requireLibraryRecordById(\n database: Database,\n id: number,\n): Promise<WikiGraphLibraryRecord> {\n const record = await database.queryOne(\n `\n SELECT id, public_id, folder_path, is_default, created_at, updated_at\n FROM libraries\n WHERE id = ?\n `,\n [id],\n mapLibraryRecord,\n );\n\n if (record === undefined) {\n throw new Error(`Unknown Wiki Graph library: ${id}`);\n }\n\n return record;\n}\n\nfunction mapLibraryRecord(row: SqlRow): WikiGraphLibraryRecord {\n const id = getNumber(row, \"id\");\n const publicId = getString(row, \"public_id\");\n return {\n createdAt: getString(row, \"created_at\"),\n folderPath: getString(row, \"folder_path\"),\n id,\n isDefault: getNumber(row, \"is_default\") === 1,\n publicId,\n stagingPath: resolveWikiGraphLibraryStagingDirectoryPath(id),\n updatedAt: getString(row, \"updated_at\"),\n uri: formatWikiGraphLibraryUri(\n getNumber(row, \"is_default\") === 1 ? undefined : publicId,\n ),\n };\n}\n\nasync function readLibraryMetadataMap(\n database: Database,\n libraryId: number,\n): Promise<Readonly<Record<string, unknown>>> {\n const rows = await database.queryAll(\n `\n SELECT key, value_json\n FROM library_metadata\n WHERE library_id = ?\n ORDER BY key\n `,\n [libraryId],\n (row) => ({\n key: getString(row, \"key\"),\n value: JSON.parse(getString(row, \"value_json\")) as unknown,\n }),\n );\n const map: Record<string, unknown> = {};\n for (const row of rows) {\n map[row.key] = row.value;\n }\n return map;\n}\n\nasync function putLibraryMetadata(\n database: Database,\n libraryId: number,\n key: string,\n value: unknown,\n): Promise<void> {\n await database.run(\n `\n INSERT INTO library_metadata (library_id, key, value_json, updated_at)\n VALUES (?, ?, ?, ?)\n ON CONFLICT(library_id, key) DO UPDATE SET\n value_json = excluded.value_json,\n updated_at = excluded.updated_at\n `,\n [libraryId, key, JSON.stringify(value), new Date().toISOString()],\n );\n}\n\nasync function createUniqueLibraryPublicId(\n database: Database,\n): Promise<string> {\n for (let attempt = 0; attempt < 20; attempt += 1) {\n const publicId = randomBytes(PUBLIC_ID_BYTES).toString(\"hex\");\n const existing = await database.queryOne(\n \"SELECT public_id FROM libraries WHERE public_id = ?\",\n [publicId],\n (row) => getString(row, \"public_id\"),\n );\n if (existing === undefined) {\n return publicId;\n }\n }\n throw new Error(\"Could not generate a unique library id.\");\n}\n\nasync function pathExists(path: string): Promise<boolean> {\n try {\n await stat(path);\n return true;\n } catch (error) {\n if (isNodeError(error) && error.code === \"ENOENT\") {\n return false;\n }\n throw error;\n }\n}\n\nfunction rejectReservedMetadataKeys(keys: readonly string[]): void {\n const reserved = keys.find((key) => RESERVED_METADATA_KEYS.has(key));\n if (reserved !== undefined) {\n throw new Error(`Library metadata cannot modify system field: ${reserved}`);\n }\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../src/library/registry.ts"],"sourcesContent":["import { randomBytes } from \"crypto\";\nimport { constants } from \"fs\";\nimport { access, mkdir, stat } from \"fs/promises\";\nimport { join, resolve } from \"path\";\n\nimport {\n getNumber,\n getString,\n type Database,\n type SqlRow,\n} from \"../document/database.js\";\nimport { openSharedStateDatabase } from \"../document/index.js\";\nimport {\n resolveWikiGraphCoreDatabasePath,\n resolveWikiGraphHomeDirectoryPath,\n resolveWikiGraphStagingDirectoryPath,\n} from \"../runtime/common/wiki-graph/dir.js\";\nimport {\n parseWikiGraphUriSyntax,\n WIKI_GRAPH_ARCHIVE_EXTENSION,\n} from \"../runtime/common/wiki-graph/uri.js\";\nimport { isNodeError } from \"../utils/node-error.js\";\nimport { withWikiGraphLibraryLock } from \"./lock.js\";\nimport { RESERVED_LIBRARY_URI_SEGMENTS } from \"./segments.js\";\n\nconst DEFAULT_LIBRARY_FOLDER_NAME = \"default-library\";\nconst PUBLIC_ID_BYTES = 6;\n\nconst RESERVED_METADATA_KEYS = new Set([\n \"id\",\n \"public_id\",\n \"publicId\",\n \"folder_path\",\n \"folderPath\",\n \"is_default\",\n \"isDefault\",\n \"staging_path\",\n \"stagingPath\",\n \"created_at\",\n \"createdAt\",\n \"updated_at\",\n \"updatedAt\",\n \"uri\",\n]);\n\nconst LIBRARY_REGISTRY_SCHEMA_SQL = `\n PRAGMA journal_mode = WAL;\n\n CREATE TABLE IF NOT EXISTS libraries (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n public_id TEXT NOT NULL UNIQUE,\n folder_path TEXT NOT NULL UNIQUE,\n is_default INTEGER NOT NULL DEFAULT 0 CHECK (is_default IN (0, 1)),\n created_at TEXT NOT NULL,\n updated_at TEXT NOT NULL\n );\n\n CREATE UNIQUE INDEX IF NOT EXISTS idx_libraries_single_default\n ON libraries(is_default)\n WHERE is_default = 1;\n\n CREATE TABLE IF NOT EXISTS library_metadata (\n library_id INTEGER NOT NULL,\n key TEXT NOT NULL,\n value_json TEXT NOT NULL,\n updated_at TEXT NOT NULL,\n PRIMARY KEY (library_id, key)\n );\n\n CREATE INDEX IF NOT EXISTS idx_library_metadata_library\n ON library_metadata(library_id);\n`;\n\nexport interface WikiGraphLibraryRecord {\n readonly id: number;\n readonly publicId: string;\n readonly uri: string;\n readonly folderPath: string;\n readonly isDefault: boolean;\n readonly stagingPath: string;\n readonly createdAt: string;\n readonly updatedAt: string;\n}\n\nexport interface ParsedWikiGraphLibraryUri {\n readonly archivePublicId?: string;\n readonly kind:\n | \"archive\"\n | \"archive-collection\"\n | \"archive-path\"\n | \"archive-tree\"\n | \"metadata\"\n | \"path\"\n | \"registry\"\n | \"scope\";\n readonly objectUri?: string;\n readonly publicId?: string;\n readonly isDefault: boolean;\n}\n\nexport function isWikiGraphLibraryUri(uri: string | undefined): uri is string {\n if (uri === undefined) {\n return false;\n }\n try {\n const syntax = parseWikiGraphUriSyntax(uri);\n if (syntax.protocol !== \"wikg\" || syntax.path[0] !== \"lib\") {\n return false;\n }\n if (syntax.path.some((segment) => segment.endsWith(\".lib\"))) {\n return true;\n }\n const target = parseWikiGraphLibraryUri(uri);\n return (\n target !== undefined &&\n (target.kind !== \"archive\" || target.objectUri === undefined)\n );\n } catch {\n return false;\n }\n}\n\nexport function parseWikiGraphLibraryUri(\n uri: string,\n): ParsedWikiGraphLibraryUri | undefined {\n if (!uri.includes(\"://\")) {\n return undefined;\n }\n const parsed = parseWikiGraphUriSyntax(uri);\n if (parsed.protocol !== \"wikg\" || parsed.path[0] !== \"lib\") {\n return undefined;\n }\n\n const segments = parsed.path.slice(1);\n const fragment = formatWikiGraphUriFragment(parsed.fragment);\n\n if (segments.length === 0) {\n rejectLibraryStructureFragment(uri, fragment);\n return { isDefault: true, kind: \"scope\" };\n }\n if (segments.some((part) => part.endsWith(WIKI_GRAPH_ARCHIVE_EXTENSION))) {\n return undefined;\n }\n\n if (segments.some((segment) => segment.endsWith(\".lib\"))) {\n throw new Error(\n `Invalid Wiki Graph library URI: ${uri}. Use wikg://lib/<lib-id> and wikg://lib/<lib-id>/arc/<arc-id>; .lib suffixes are no longer supported.`,\n );\n }\n\n const [first, second, third, ...rest] = segments;\n if (first === \"registry\" && second === undefined) {\n rejectLibraryStructureFragment(uri, fragment);\n return { isDefault: true, kind: \"registry\" };\n }\n if (first === \"meta\" && second === undefined) {\n rejectLibraryStructureFragment(uri, fragment);\n return { isDefault: true, kind: \"metadata\" };\n }\n if (first === \"path\" && second === undefined) {\n rejectLibraryStructureFragment(uri, fragment);\n return { isDefault: true, kind: \"path\" };\n }\n\n const defaultLibraryScopeMatch =\n /^(index|chapter|chunk|entity|triple)$/u.exec(first ?? \"\");\n if (defaultLibraryScopeMatch?.[1] !== undefined) {\n return {\n isDefault: true,\n kind: \"scope\",\n objectUri: formatWikiGraphLibraryObjectUri(\n [first, second, third, ...rest].filter(Boolean).join(\"/\"),\n fragment,\n ),\n };\n }\n\n if (first === \"arc\") {\n return parseLibraryArcUri(uri, undefined, segments.slice(1), fragment);\n }\n\n if (first === undefined || RESERVED_LIBRARY_URI_SEGMENTS.has(first)) {\n throw new Error(\n `Invalid Wiki Graph library URI: ${uri}. Reserved library URI segment: ${first ?? \"\"}.`,\n );\n }\n if (second === undefined) {\n rejectLibraryStructureFragment(uri, fragment);\n return { isDefault: false, kind: \"scope\", publicId: first };\n }\n if (second === \"meta\" && third === undefined) {\n rejectLibraryStructureFragment(uri, fragment);\n return { isDefault: false, kind: \"metadata\", publicId: first };\n }\n if (second === \"path\" && third === undefined) {\n rejectLibraryStructureFragment(uri, fragment);\n return { isDefault: false, kind: \"path\", publicId: first };\n }\n if (/^(index|chapter|chunk|entity|triple)$/u.test(second)) {\n return {\n isDefault: false,\n kind: \"scope\",\n objectUri: formatWikiGraphLibraryObjectUri(\n [second, third, ...rest].filter(Boolean).join(\"/\"),\n fragment,\n ),\n publicId: first,\n };\n }\n if (second === \"arc\") {\n return parseLibraryArcUri(uri, first, segments.slice(2), fragment);\n }\n\n throw new Error(\n `Invalid Wiki Graph library URI: ${uri}. Expected wikg://lib, wikg://lib/registry, wikg://lib/<lib-id>, or <lib-scope>/arc/<arc-id>.`,\n );\n}\n\nfunction parseLibraryArcUri(\n uri: string,\n publicId: string | undefined,\n segments: readonly string[],\n fragment: string | undefined,\n): ParsedWikiGraphLibraryUri {\n const isDefault = publicId === undefined;\n const [first, second, ...rest] = segments;\n const base = { isDefault, ...(publicId === undefined ? {} : { publicId }) };\n if (first === undefined) {\n rejectLibraryStructureFragment(uri, fragment);\n return { ...base, kind: \"archive-collection\" };\n }\n if (/^(chapter|chunk|entity|triple)$/u.test(first)) {\n return {\n ...base,\n kind: \"scope\",\n objectUri: formatWikiGraphLibraryObjectUri(\n [first, second, ...rest].filter(Boolean).join(\"/\"),\n fragment,\n ),\n };\n }\n if (first === \"tree\" && second === undefined) {\n rejectLibraryStructureFragment(uri, fragment);\n return { ...base, kind: \"archive-tree\" };\n }\n if (RESERVED_LIBRARY_URI_SEGMENTS.has(first)) {\n throw new Error(\n `Invalid Wiki Graph library URI: ${uri}. Reserved archive member URI segment: ${first}.`,\n );\n }\n if (second === undefined) {\n rejectLibraryStructureFragment(uri, fragment);\n return { ...base, archivePublicId: first, kind: \"archive\" };\n }\n if (second === \"path\" && rest.length === 0) {\n rejectLibraryStructureFragment(uri, fragment);\n return { ...base, archivePublicId: first, kind: \"archive-path\" };\n }\n return {\n ...base,\n archivePublicId: first,\n kind: \"archive\",\n objectUri: formatWikiGraphLibraryObjectUri(\n [second, ...rest].join(\"/\"),\n fragment,\n ),\n };\n}\n\nfunction rejectLibraryStructureFragment(\n uri: string,\n fragment: string | undefined,\n): void {\n if (fragment !== undefined) {\n throw new Error(\n `Invalid Wiki Graph library URI: ${uri}. This library URI target does not support fragments.`,\n );\n }\n}\n\nfunction formatWikiGraphLibraryObjectUri(\n path: string,\n fragment?: string,\n): string {\n return `wikg://${path.replace(/^\\/+|\\/+$/gu, \"\")}${\n fragment === undefined ? \"\" : `#${fragment}`\n }`;\n}\n\nfunction formatWikiGraphUriFragment(\n fragment:\n | number\n | { readonly begin: number; readonly end: number }\n | undefined,\n): string | undefined {\n if (fragment === undefined) {\n return undefined;\n }\n if (typeof fragment === \"number\") {\n return String(fragment);\n }\n\n return `${fragment.begin}..${fragment.end}`;\n}\n\nexport function formatWikiGraphLibraryUri(publicId?: string): string {\n return publicId === undefined ? \"wikg://lib\" : `wikg://lib/${publicId}`;\n}\n\nexport function resolveDefaultWikiGraphLibraryDirectoryPath(): string {\n return join(resolveWikiGraphHomeDirectoryPath(), DEFAULT_LIBRARY_FOLDER_NAME);\n}\n\nexport function resolveWikiGraphLibraryStagingDirectoryPath(\n id: number,\n): string {\n return join(resolveWikiGraphStagingDirectoryPath(), \"library\", String(id));\n}\n\nexport async function ensureDefaultWikiGraphLibrary(): Promise<WikiGraphLibraryRecord> {\n return await withLibraryRegistryDatabase(async (database) => {\n const library = await database.transaction(async () => {\n const existing = await readDefaultLibraryRecord(database);\n if (existing !== undefined) {\n return existing;\n }\n\n const now = new Date().toISOString();\n const publicId = await createUniqueLibraryPublicId(database);\n const folderPath = resolveDefaultWikiGraphLibraryDirectoryPath();\n\n await database.run(\n `\n INSERT INTO libraries (public_id, folder_path, is_default, created_at, updated_at)\n VALUES (?, ?, 1, ?, ?)\n `,\n [publicId, folderPath, now, now],\n );\n\n return await requireDefaultLibraryRecord(database);\n });\n\n await mkdir(library.folderPath, { recursive: true });\n return library;\n });\n}\n\nexport async function createWikiGraphLibrary(input: {\n readonly folderPath: string;\n}): Promise<WikiGraphLibraryRecord> {\n const folderPath = resolve(input.folderPath);\n if (await pathExists(folderPath)) {\n throw new Error(`Library folder already exists: ${folderPath}`);\n }\n\n return await withLibraryRegistryDatabase(async (database) => {\n return await database.transaction(async () => {\n const now = new Date().toISOString();\n const publicId = await createUniqueLibraryPublicId(database);\n\n await database.run(\n `\n INSERT INTO libraries (public_id, folder_path, is_default, created_at, updated_at)\n VALUES (?, ?, 0, ?, ?)\n `,\n [publicId, folderPath, now, now],\n );\n await mkdir(folderPath);\n\n return await requireLibraryRecordByPublicId(database, publicId);\n });\n });\n}\n\nexport async function listWikiGraphLibraries(): Promise<\n readonly WikiGraphLibraryRecord[]\n> {\n await ensureDefaultWikiGraphLibrary();\n return await withLibraryRegistryDatabase(\n async (database) =>\n await database.queryAll(\n `\n SELECT id, public_id, folder_path, is_default, created_at, updated_at\n FROM libraries\n ORDER BY is_default DESC, public_id\n `,\n undefined,\n mapLibraryRecord,\n ),\n );\n}\n\nexport async function resolveWikiGraphLibrary(\n target: ParsedWikiGraphLibraryUri,\n): Promise<WikiGraphLibraryRecord> {\n if (target.isDefault) {\n return await ensureDefaultWikiGraphLibrary();\n }\n if (target.publicId === undefined) {\n throw new Error(\"Missing library id.\");\n }\n\n return await withLibraryRegistryDatabase(\n async (database) =>\n await requireLibraryRecordByPublicId(database, target.publicId!),\n );\n}\n\nexport async function resolveWikiGraphLibraryForScan(\n target: ParsedWikiGraphLibraryUri,\n): Promise<WikiGraphLibraryRecord> {\n if (!target.isDefault) {\n return await resolveWikiGraphLibrary(target);\n }\n\n const existing = await withLibraryRegistryDatabase(\n async (database) => await readDefaultLibraryRecord(database),\n );\n return existing ?? (await ensureDefaultWikiGraphLibrary());\n}\n\nexport async function resolveWikiGraphLibraryById(\n id: number,\n): Promise<WikiGraphLibraryRecord> {\n return await withLibraryRegistryDatabase(\n async (database) => await requireLibraryRecordById(database, id),\n );\n}\n\nexport async function listWikiGraphLibraryScope(\n target: ParsedWikiGraphLibraryUri,\n): Promise<readonly []> {\n await resolveWikiGraphLibrary(target);\n return [];\n}\n\nexport async function removeWikiGraphLibrary(\n target: ParsedWikiGraphLibraryUri,\n): Promise<WikiGraphLibraryRecord> {\n const library = await resolveWikiGraphLibrary(target);\n if (library.isDefault) {\n throw new Error(\n \"The default library is managed by the system and cannot be removed.\",\n );\n }\n\n await withWikiGraphLibraryLock(library.id, \"write\", async () => {\n await withLibraryRegistryDatabase(async (database) => {\n await database.transaction(async () => {\n await database.run(\n \"DELETE FROM library_metadata WHERE library_id = ?\",\n [library.id],\n );\n await database.run(\"DELETE FROM libraries WHERE id = ?\", [library.id]);\n });\n });\n });\n\n return library;\n}\n\nexport async function updateWikiGraphLibraryFolderPathForRebind(\n library: WikiGraphLibraryRecord,\n inputFolderPath: string,\n): Promise<WikiGraphLibraryRecord> {\n const folderPath = resolve(inputFolderPath);\n let folderStats;\n try {\n folderStats = await stat(folderPath);\n } catch (error) {\n if (isNodeError(error) && error.code === \"ENOENT\") {\n throw new Error(`Library path set does not exist: ${folderPath}`);\n }\n throw new Error(\n `Library path set is not accessible: ${folderPath}: ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n if (!folderStats.isDirectory()) {\n throw new Error(\n `Library path set must be an existing directory: ${folderPath}`,\n );\n }\n try {\n await access(folderPath, constants.R_OK);\n } catch (error) {\n throw new Error(\n `Library path set is not accessible: ${folderPath}: ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n\n return await withLibraryRegistryDatabase(async (database) => {\n return await database.transaction(async () => {\n const existing = await database.queryOne(\n \"SELECT id FROM libraries WHERE folder_path = ?\",\n [folderPath],\n (row) => getNumber(row, \"id\"),\n );\n if (existing !== undefined && existing !== library.id) {\n throw new Error(\n `Library path set is already bound to another library: ${folderPath}`,\n );\n }\n\n await database.run(\n \"UPDATE libraries SET folder_path = ?, updated_at = ? WHERE id = ?\",\n [folderPath, new Date().toISOString(), library.id],\n );\n return await requireLibraryRecordById(database, library.id);\n });\n });\n}\n\nexport async function getWikiGraphLibraryMetadata(\n target: ParsedWikiGraphLibraryUri,\n): Promise<Readonly<Record<string, unknown>>> {\n const library = await resolveWikiGraphLibrary(target);\n\n return await withLibraryRegistryDatabase(\n async (database) => await readLibraryMetadataMap(database, library.id),\n );\n}\n\nexport async function replaceWikiGraphLibraryMetadata(\n target: ParsedWikiGraphLibraryUri,\n map: Readonly<Record<string, unknown>>,\n): Promise<Readonly<Record<string, unknown>>> {\n rejectReservedMetadataKeys(Object.keys(map));\n const library = await resolveWikiGraphLibrary(target);\n\n return await withLibraryRegistryDatabase(async (database) => {\n await database.transaction(async () => {\n await database.run(\"DELETE FROM library_metadata WHERE library_id = ?\", [\n library.id,\n ]);\n for (const [key, value] of Object.entries(map)) {\n await putLibraryMetadata(database, library.id, key, value);\n }\n });\n return await readLibraryMetadataMap(database, library.id);\n });\n}\n\nexport async function putWikiGraphLibraryMetadata(\n target: ParsedWikiGraphLibraryUri,\n key: string,\n value: unknown,\n): Promise<Readonly<Record<string, unknown>>> {\n rejectReservedMetadataKeys([key]);\n const library = await resolveWikiGraphLibrary(target);\n\n return await withLibraryRegistryDatabase(async (database) => {\n await putLibraryMetadata(database, library.id, key, value);\n return await readLibraryMetadataMap(database, library.id);\n });\n}\n\nexport async function deleteWikiGraphLibraryMetadataKey(\n target: ParsedWikiGraphLibraryUri,\n key: string,\n): Promise<Readonly<Record<string, unknown>>> {\n const library = await resolveWikiGraphLibrary(target);\n\n return await withLibraryRegistryDatabase(async (database) => {\n await database.run(\n \"DELETE FROM library_metadata WHERE library_id = ? AND key = ?\",\n [library.id, key],\n );\n return await readLibraryMetadataMap(database, library.id);\n });\n}\n\nexport async function clearWikiGraphLibraryMetadata(\n target: ParsedWikiGraphLibraryUri,\n): Promise<Readonly<Record<string, unknown>>> {\n const library = await resolveWikiGraphLibrary(target);\n\n return await withLibraryRegistryDatabase(async (database) => {\n await database.run(\"DELETE FROM library_metadata WHERE library_id = ?\", [\n library.id,\n ]);\n return await readLibraryMetadataMap(database, library.id);\n });\n}\n\nasync function withLibraryRegistryDatabase<T>(\n operation: (database: Database) => Promise<T>,\n): Promise<T> {\n const database = await openSharedStateDatabase(\n resolveWikiGraphCoreDatabasePath(),\n LIBRARY_REGISTRY_SCHEMA_SQL,\n );\n\n try {\n return await operation(database);\n } finally {\n await database.close();\n }\n}\n\nasync function readDefaultLibraryRecord(\n database: Database,\n): Promise<WikiGraphLibraryRecord | undefined> {\n return await database.queryOne(\n `\n SELECT id, public_id, folder_path, is_default, created_at, updated_at\n FROM libraries\n WHERE is_default = 1\n `,\n undefined,\n mapLibraryRecord,\n );\n}\n\nasync function requireDefaultLibraryRecord(\n database: Database,\n): Promise<WikiGraphLibraryRecord> {\n const record = await readDefaultLibraryRecord(database);\n if (record === undefined) {\n throw new Error(\"Default library registry record is missing.\");\n }\n return record;\n}\n\nasync function requireLibraryRecordByPublicId(\n database: Database,\n publicId: string,\n): Promise<WikiGraphLibraryRecord> {\n const record = await database.queryOne(\n `\n SELECT id, public_id, folder_path, is_default, created_at, updated_at\n FROM libraries\n WHERE public_id = ?\n `,\n [publicId],\n mapLibraryRecord,\n );\n\n if (record === undefined) {\n throw new Error(`Unknown Wiki Graph library: ${publicId}`);\n }\n return record;\n}\n\nasync function requireLibraryRecordById(\n database: Database,\n id: number,\n): Promise<WikiGraphLibraryRecord> {\n const record = await database.queryOne(\n `\n SELECT id, public_id, folder_path, is_default, created_at, updated_at\n FROM libraries\n WHERE id = ?\n `,\n [id],\n mapLibraryRecord,\n );\n\n if (record === undefined) {\n throw new Error(`Unknown Wiki Graph library: ${id}`);\n }\n\n return record;\n}\n\nfunction mapLibraryRecord(row: SqlRow): WikiGraphLibraryRecord {\n const id = getNumber(row, \"id\");\n const publicId = getString(row, \"public_id\");\n return {\n createdAt: getString(row, \"created_at\"),\n folderPath: getString(row, \"folder_path\"),\n id,\n isDefault: getNumber(row, \"is_default\") === 1,\n publicId,\n stagingPath: resolveWikiGraphLibraryStagingDirectoryPath(id),\n updatedAt: getString(row, \"updated_at\"),\n uri: formatWikiGraphLibraryUri(\n getNumber(row, \"is_default\") === 1 ? undefined : publicId,\n ),\n };\n}\n\nasync function readLibraryMetadataMap(\n database: Database,\n libraryId: number,\n): Promise<Readonly<Record<string, unknown>>> {\n const rows = await database.queryAll(\n `\n SELECT key, value_json\n FROM library_metadata\n WHERE library_id = ?\n ORDER BY key\n `,\n [libraryId],\n (row) => ({\n key: getString(row, \"key\"),\n value: JSON.parse(getString(row, \"value_json\")) as unknown,\n }),\n );\n const map: Record<string, unknown> = {};\n for (const row of rows) {\n map[row.key] = row.value;\n }\n return map;\n}\n\nasync function putLibraryMetadata(\n database: Database,\n libraryId: number,\n key: string,\n value: unknown,\n): Promise<void> {\n await database.run(\n `\n INSERT INTO library_metadata (library_id, key, value_json, updated_at)\n VALUES (?, ?, ?, ?)\n ON CONFLICT(library_id, key) DO UPDATE SET\n value_json = excluded.value_json,\n updated_at = excluded.updated_at\n `,\n [libraryId, key, JSON.stringify(value), new Date().toISOString()],\n );\n}\n\nasync function createUniqueLibraryPublicId(\n database: Database,\n): Promise<string> {\n for (let attempt = 0; attempt < 20; attempt += 1) {\n const publicId = randomBytes(PUBLIC_ID_BYTES).toString(\"hex\");\n const existing = await database.queryOne(\n \"SELECT public_id FROM libraries WHERE public_id = ?\",\n [publicId],\n (row) => getString(row, \"public_id\"),\n );\n if (existing === undefined) {\n return publicId;\n }\n }\n throw new Error(\"Could not generate a unique library id.\");\n}\n\nasync function pathExists(path: string): Promise<boolean> {\n try {\n await stat(path);\n return true;\n } catch (error) {\n if (isNodeError(error) && error.code === \"ENOENT\") {\n return false;\n }\n throw error;\n }\n}\n\nfunction rejectReservedMetadataKeys(keys: readonly string[]): void {\n const reserved = keys.find((key) => RESERVED_METADATA_KEYS.has(key));\n if (reserved !== undefined) {\n throw new Error(`Library metadata cannot modify system field: ${reserved}`);\n }\n}\n"],"mappings":"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","names":[]}
@@ -57,14 +57,14 @@ async function upgradeWikiGraphMaintenanceTarget(target, options = {}) {
57
57
  }
58
58
  const archivePath = resolveArchiveUpgradeTarget(target);
59
59
  const schemaVersionBefore = await readWikiGraphArchiveSchemaVersion(archivePath);
60
- await upgradeWikiGraphArchiveSchema(archivePath);
60
+ const upgradeResult = await upgradeWikiGraphArchiveSchema(archivePath);
61
61
  const schemaVersionAfter = await readWikiGraphArchiveSchemaVersion(archivePath);
62
62
  return {
63
63
  kind: "archive",
64
64
  path: archivePath,
65
65
  schemaVersionBefore,
66
66
  schemaVersionAfter,
67
- status: schemaVersionBefore === schemaVersionAfter ? "already-current" : "upgraded"
67
+ status: upgradeResult.changed ? "upgraded" : "already-current"
68
68
  };
69
69
  }
70
70
  async function assertWikiGraphLibrarySchemaCurrent(target) {
@@ -103,18 +103,23 @@ async function upgradeWikiGraphLibrarySchema(target) {
103
103
  const schemaVersionBefore = await readWikiGraphArchiveSchemaVersion(
104
104
  archive.path
105
105
  );
106
- if (schemaVersionBefore === CURRENT_ARCHIVE_SCHEMA_VERSION) {
107
- skipped.push({
106
+ try {
107
+ const upgradeResult = await upgradeWikiGraphArchiveSchema(archive.path);
108
+ const schemaVersionAfter = await readWikiGraphArchiveSchemaVersion(
109
+ archive.path
110
+ );
111
+ const item = {
108
112
  path: archive.path,
109
113
  publicId: archive.publicId,
110
- schemaVersionAfter: schemaVersionBefore,
114
+ schemaVersionAfter,
111
115
  schemaVersionBefore,
112
116
  uri: archive.uri
113
- });
114
- continue;
115
- }
116
- try {
117
- await upgradeWikiGraphArchiveSchema(archive.path);
117
+ };
118
+ if (upgradeResult.changed) {
119
+ upgraded.push(item);
120
+ } else {
121
+ skipped.push(item);
122
+ }
118
123
  } catch (error) {
119
124
  return {
120
125
  failed: {
@@ -130,15 +135,6 @@ async function upgradeWikiGraphLibrarySchema(target) {
130
135
  upgraded
131
136
  };
132
137
  }
133
- upgraded.push({
134
- path: archive.path,
135
- publicId: archive.publicId,
136
- schemaVersionAfter: await readWikiGraphArchiveSchemaVersion(
137
- archive.path
138
- ),
139
- schemaVersionBefore,
140
- uri: archive.uri
141
- });
142
138
  }
143
139
  return {
144
140
  kind: "lib",
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/maintenance/upgrade.ts"],"sourcesContent":["import { rm } from \"fs/promises\";\nimport { homedir } from \"os\";\nimport { resolve } from \"path\";\n\nimport {\n listWikiGraphLibraryArchives,\n parseWikiGraphLibraryUri,\n resolveWikiGraphLibrary,\n withWikiGraphLibraryLock,\n type ParsedWikiGraphLibraryUri,\n type WikiGraphLibraryArchiveRecord,\n type WikiGraphLibraryRecord,\n} from \"../library/index.js\";\nimport { resolveWikiGraphHomeDirectoryPath } from \"../runtime/common/wiki-graph/dir.js\";\nimport { migrateLegacySdpubToWikg } from \"../storage/migration/legacy-sdpub/upgrade/index.js\";\nimport { requireArchiveUri } from \"../storage/wikg/index.js\";\nimport {\n CURRENT_ARCHIVE_SCHEMA_VERSION,\n ensureWikiGraphHomeSchemaCurrent,\n readWikiGraphArchiveSchemaVersion,\n readWikiGraphHomeSchemaVersion,\n upgradeWikiGraphArchiveSchema,\n} from \"../storage/schema-upgrade/index.js\";\n\nexport type WikiGraphMaintenanceUpgradeResult =\n | {\n readonly kind: \"home\";\n readonly path: string;\n readonly schemaVersionBefore: number;\n readonly schemaVersionAfter: number;\n readonly status: \"already-current\" | \"upgraded\";\n }\n | {\n readonly kind: \"archive\";\n readonly path: string;\n readonly schemaVersionBefore: number;\n readonly schemaVersionAfter: number;\n readonly status: \"already-current\" | \"upgraded\";\n }\n | {\n readonly kind: \"sdpub\";\n readonly inputPath: string;\n readonly outputPath: string;\n readonly status: \"migrated\";\n }\n | WikiGraphLibraryUpgradeResult;\n\nexport interface WikiGraphLibraryUpgradeResult {\n readonly kind: \"lib\";\n readonly library: {\n readonly id: number;\n readonly publicId: string;\n readonly uri: string;\n readonly folderPath: string;\n readonly stagingPath: string;\n };\n readonly upgraded: readonly WikiGraphLibraryArchiveUpgradeItem[];\n readonly skipped: readonly WikiGraphLibraryArchiveUpgradeItem[];\n readonly failed?: WikiGraphLibraryArchiveFailure | undefined;\n readonly status: \"already-current\" | \"partial\" | \"upgraded\";\n}\n\nexport interface WikiGraphLibraryArchiveUpgradeItem {\n readonly publicId: string;\n readonly uri: string;\n readonly path: string;\n readonly schemaVersionBefore: number;\n readonly schemaVersionAfter: number;\n}\n\nexport interface WikiGraphLibraryArchiveFailure {\n readonly publicId: string;\n readonly uri: string;\n readonly path: string;\n readonly message: string;\n}\n\nexport async function upgradeWikiGraphMaintenanceTarget(\n target: string,\n options: { readonly outputPath?: string } = {},\n): Promise<WikiGraphMaintenanceUpgradeResult> {\n if (isLegacySdpubTarget(target)) {\n const result = await migrateLegacySdpubToWikg(target, options.outputPath);\n return {\n kind: \"sdpub\",\n inputPath: result.inputPath,\n outputPath: result.outputPath,\n status: \"migrated\",\n };\n }\n\n if (options.outputPath !== undefined) {\n throw new Error(\"Only sdpub maintenance upgrade supports --output.\");\n }\n\n if (isHomeTarget(target)) {\n const path = resolveWikiGraphHomeDirectoryPath();\n const schemaVersionBefore = await readWikiGraphHomeSchemaVersion();\n await ensureWikiGraphHomeSchemaCurrent();\n const schemaVersionAfter = await readWikiGraphHomeSchemaVersion();\n return {\n kind: \"home\",\n path,\n schemaVersionBefore,\n schemaVersionAfter,\n status:\n schemaVersionBefore === schemaVersionAfter\n ? \"already-current\"\n : \"upgraded\",\n };\n }\n\n if (target.startsWith(\"wikg://lib\")) {\n const parsed = parseWikiGraphLibraryUri(target);\n if (parsed === undefined) {\n throw new Error(`Invalid Wiki Graph library upgrade target: ${target}`);\n }\n if (parsed.kind === \"archive\") {\n throw new Error(\n `Library archive URIs cannot be upgraded individually. Run: wg maintenance upgrade ${formatLibraryScopeUpgradeTarget(parsed)}`,\n );\n }\n return await upgradeWikiGraphLibrarySchema(parsed);\n }\n\n const archivePath = resolveArchiveUpgradeTarget(target);\n const schemaVersionBefore =\n await readWikiGraphArchiveSchemaVersion(archivePath);\n await upgradeWikiGraphArchiveSchema(archivePath);\n const schemaVersionAfter =\n await readWikiGraphArchiveSchemaVersion(archivePath);\n return {\n kind: \"archive\",\n path: archivePath,\n schemaVersionBefore,\n schemaVersionAfter,\n status:\n schemaVersionBefore === schemaVersionAfter\n ? \"already-current\"\n : \"upgraded\",\n };\n}\n\nexport async function assertWikiGraphLibrarySchemaCurrent(\n target: ParsedWikiGraphLibraryUri,\n): Promise<void> {\n const library = await resolveWikiGraphLibrary(target);\n const archives = await listWikiGraphLibraryArchives({\n isDefault: library.isDefault,\n kind: \"scope\",\n ...(library.isDefault ? {} : { publicId: library.publicId }),\n });\n for (const archive of archives) {\n if (!isUpgradeableLibraryArchive(archive)) {\n continue;\n }\n const schemaVersion = await readWikiGraphArchiveSchemaVersion(archive.path);\n if (schemaVersion < CURRENT_ARCHIVE_SCHEMA_VERSION) {\n throw new Error(\n `This Wiki Graph library must be upgraded before use.\\nRun: wg maintenance upgrade ${library.uri}`,\n );\n }\n }\n}\n\nexport async function upgradeWikiGraphLibrarySchema(\n target: ParsedWikiGraphLibraryUri,\n): Promise<WikiGraphLibraryUpgradeResult> {\n await ensureWikiGraphHomeSchemaCurrent();\n const library = await resolveWikiGraphLibrary(target);\n return await withWikiGraphLibraryLock(library.id, \"write\", async () => {\n await clearLibraryDerivedData(library);\n const archives = (\n await listWikiGraphLibraryArchives({\n isDefault: library.isDefault,\n kind: \"scope\",\n ...(library.isDefault ? {} : { publicId: library.publicId }),\n })\n ).filter(isUpgradeableLibraryArchive);\n\n const upgraded: WikiGraphLibraryArchiveUpgradeItem[] = [];\n const skipped: WikiGraphLibraryArchiveUpgradeItem[] = [];\n\n for (const archive of archives) {\n const schemaVersionBefore = await readWikiGraphArchiveSchemaVersion(\n archive.path,\n );\n if (schemaVersionBefore === CURRENT_ARCHIVE_SCHEMA_VERSION) {\n skipped.push({\n path: archive.path,\n publicId: archive.publicId,\n schemaVersionAfter: schemaVersionBefore,\n schemaVersionBefore,\n uri: archive.uri,\n });\n continue;\n }\n try {\n await upgradeWikiGraphArchiveSchema(archive.path);\n } catch (error) {\n return {\n failed: {\n message: formatErrorMessage(error),\n path: archive.path,\n publicId: archive.publicId,\n uri: archive.uri,\n },\n kind: \"lib\",\n library: formatLibraryResult(library),\n skipped,\n status: \"partial\",\n upgraded,\n };\n }\n upgraded.push({\n path: archive.path,\n publicId: archive.publicId,\n schemaVersionAfter: await readWikiGraphArchiveSchemaVersion(\n archive.path,\n ),\n schemaVersionBefore,\n uri: archive.uri,\n });\n }\n\n return {\n kind: \"lib\",\n library: formatLibraryResult(library),\n skipped,\n status: upgraded.length === 0 ? \"already-current\" : \"upgraded\",\n upgraded,\n };\n });\n}\n\nfunction resolveArchiveUpgradeTarget(target: string): string {\n if (target.startsWith(\"wikg://\")) {\n return requireArchiveUri(target);\n }\n if (!target.endsWith(\".wikg\")) {\n throw new Error(\n `Unsupported maintenance upgrade target: ${target}. Expected home, a .wikg archive, a .sdpub archive, or wikg://lib.`,\n );\n }\n return resolveHomeShorthand(target);\n}\n\nfunction isLegacySdpubTarget(target: string): boolean {\n return target.toLowerCase().endsWith(\".sdpub\");\n}\n\nfunction isHomeTarget(target: string): boolean {\n const resolved = resolveHomeShorthand(target).replace(/[\\\\/]+$/u, \"\");\n return (\n target === \"home\" ||\n target === \"~/.wikigraph\" ||\n resolved === resolveWikiGraphHomeDirectoryPath().replace(/[\\\\/]+$/u, \"\")\n );\n}\n\nfunction resolveHomeShorthand(path: string): string {\n return path.startsWith(\"~/\")\n ? resolve(homedir(), path.slice(2))\n : resolve(path);\n}\n\nfunction isUpgradeableLibraryArchive(\n archive: WikiGraphLibraryArchiveRecord,\n): boolean {\n return archive.exists && archive.status === \"present\";\n}\n\nasync function clearLibraryDerivedData(\n library: WikiGraphLibraryRecord,\n): Promise<void> {\n await rm(library.stagingPath, { force: true, recursive: true });\n}\n\nfunction formatLibraryScopeUpgradeTarget(\n target: ParsedWikiGraphLibraryUri,\n): string {\n return target.isDefault\n ? \"wikg://lib\"\n : `wikg://lib/${target.publicId ?? \"<lib-id>\"}`;\n}\n\nfunction formatLibraryResult(library: WikiGraphLibraryRecord): {\n readonly id: number;\n readonly publicId: string;\n readonly uri: string;\n readonly folderPath: string;\n readonly stagingPath: string;\n} {\n return {\n folderPath: library.folderPath,\n id: library.id,\n publicId: library.publicId,\n stagingPath: library.stagingPath,\n uri: library.uri,\n };\n}\n\nfunction formatErrorMessage(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n"],"mappings":"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","names":["schemaVersionBefore","schemaVersionAfter"]}
1
+ {"version":3,"sources":["../../src/maintenance/upgrade.ts"],"sourcesContent":["import { rm } from \"fs/promises\";\nimport { homedir } from \"os\";\nimport { resolve } from \"path\";\n\nimport {\n listWikiGraphLibraryArchives,\n parseWikiGraphLibraryUri,\n resolveWikiGraphLibrary,\n withWikiGraphLibraryLock,\n type ParsedWikiGraphLibraryUri,\n type WikiGraphLibraryArchiveRecord,\n type WikiGraphLibraryRecord,\n} from \"../library/index.js\";\nimport { resolveWikiGraphHomeDirectoryPath } from \"../runtime/common/wiki-graph/dir.js\";\nimport { migrateLegacySdpubToWikg } from \"../storage/migration/legacy-sdpub/upgrade/index.js\";\nimport { requireArchiveUri } from \"../storage/wikg/index.js\";\nimport {\n CURRENT_ARCHIVE_SCHEMA_VERSION,\n ensureWikiGraphHomeSchemaCurrent,\n readWikiGraphArchiveSchemaVersion,\n readWikiGraphHomeSchemaVersion,\n upgradeWikiGraphArchiveSchema,\n} from \"../storage/schema-upgrade/index.js\";\n\nexport type WikiGraphMaintenanceUpgradeResult =\n | {\n readonly kind: \"home\";\n readonly path: string;\n readonly schemaVersionBefore: number;\n readonly schemaVersionAfter: number;\n readonly status: \"already-current\" | \"upgraded\";\n }\n | {\n readonly kind: \"archive\";\n readonly path: string;\n readonly schemaVersionBefore: number;\n readonly schemaVersionAfter: number;\n readonly status: \"already-current\" | \"upgraded\";\n }\n | {\n readonly kind: \"sdpub\";\n readonly inputPath: string;\n readonly outputPath: string;\n readonly status: \"migrated\";\n }\n | WikiGraphLibraryUpgradeResult;\n\nexport interface WikiGraphLibraryUpgradeResult {\n readonly kind: \"lib\";\n readonly library: {\n readonly id: number;\n readonly publicId: string;\n readonly uri: string;\n readonly folderPath: string;\n readonly stagingPath: string;\n };\n readonly upgraded: readonly WikiGraphLibraryArchiveUpgradeItem[];\n readonly skipped: readonly WikiGraphLibraryArchiveUpgradeItem[];\n readonly failed?: WikiGraphLibraryArchiveFailure | undefined;\n readonly status: \"already-current\" | \"partial\" | \"upgraded\";\n}\n\nexport interface WikiGraphLibraryArchiveUpgradeItem {\n readonly publicId: string;\n readonly uri: string;\n readonly path: string;\n readonly schemaVersionBefore: number;\n readonly schemaVersionAfter: number;\n}\n\nexport interface WikiGraphLibraryArchiveFailure {\n readonly publicId: string;\n readonly uri: string;\n readonly path: string;\n readonly message: string;\n}\n\nexport async function upgradeWikiGraphMaintenanceTarget(\n target: string,\n options: { readonly outputPath?: string } = {},\n): Promise<WikiGraphMaintenanceUpgradeResult> {\n if (isLegacySdpubTarget(target)) {\n const result = await migrateLegacySdpubToWikg(target, options.outputPath);\n return {\n kind: \"sdpub\",\n inputPath: result.inputPath,\n outputPath: result.outputPath,\n status: \"migrated\",\n };\n }\n\n if (options.outputPath !== undefined) {\n throw new Error(\"Only sdpub maintenance upgrade supports --output.\");\n }\n\n if (isHomeTarget(target)) {\n const path = resolveWikiGraphHomeDirectoryPath();\n const schemaVersionBefore = await readWikiGraphHomeSchemaVersion();\n await ensureWikiGraphHomeSchemaCurrent();\n const schemaVersionAfter = await readWikiGraphHomeSchemaVersion();\n return {\n kind: \"home\",\n path,\n schemaVersionBefore,\n schemaVersionAfter,\n status:\n schemaVersionBefore === schemaVersionAfter\n ? \"already-current\"\n : \"upgraded\",\n };\n }\n\n if (target.startsWith(\"wikg://lib\")) {\n const parsed = parseWikiGraphLibraryUri(target);\n if (parsed === undefined) {\n throw new Error(`Invalid Wiki Graph library upgrade target: ${target}`);\n }\n if (parsed.kind === \"archive\") {\n throw new Error(\n `Library archive URIs cannot be upgraded individually. Run: wg maintenance upgrade ${formatLibraryScopeUpgradeTarget(parsed)}`,\n );\n }\n return await upgradeWikiGraphLibrarySchema(parsed);\n }\n\n const archivePath = resolveArchiveUpgradeTarget(target);\n const schemaVersionBefore =\n await readWikiGraphArchiveSchemaVersion(archivePath);\n const upgradeResult = await upgradeWikiGraphArchiveSchema(archivePath);\n const schemaVersionAfter =\n await readWikiGraphArchiveSchemaVersion(archivePath);\n return {\n kind: \"archive\",\n path: archivePath,\n schemaVersionBefore,\n schemaVersionAfter,\n status: upgradeResult.changed ? \"upgraded\" : \"already-current\",\n };\n}\n\nexport async function assertWikiGraphLibrarySchemaCurrent(\n target: ParsedWikiGraphLibraryUri,\n): Promise<void> {\n const library = await resolveWikiGraphLibrary(target);\n const archives = await listWikiGraphLibraryArchives({\n isDefault: library.isDefault,\n kind: \"scope\",\n ...(library.isDefault ? {} : { publicId: library.publicId }),\n });\n for (const archive of archives) {\n if (!isUpgradeableLibraryArchive(archive)) {\n continue;\n }\n const schemaVersion = await readWikiGraphArchiveSchemaVersion(archive.path);\n if (schemaVersion < CURRENT_ARCHIVE_SCHEMA_VERSION) {\n throw new Error(\n `This Wiki Graph library must be upgraded before use.\\nRun: wg maintenance upgrade ${library.uri}`,\n );\n }\n }\n}\n\nexport async function upgradeWikiGraphLibrarySchema(\n target: ParsedWikiGraphLibraryUri,\n): Promise<WikiGraphLibraryUpgradeResult> {\n await ensureWikiGraphHomeSchemaCurrent();\n const library = await resolveWikiGraphLibrary(target);\n return await withWikiGraphLibraryLock(library.id, \"write\", async () => {\n await clearLibraryDerivedData(library);\n const archives = (\n await listWikiGraphLibraryArchives({\n isDefault: library.isDefault,\n kind: \"scope\",\n ...(library.isDefault ? {} : { publicId: library.publicId }),\n })\n ).filter(isUpgradeableLibraryArchive);\n\n const upgraded: WikiGraphLibraryArchiveUpgradeItem[] = [];\n const skipped: WikiGraphLibraryArchiveUpgradeItem[] = [];\n\n for (const archive of archives) {\n const schemaVersionBefore = await readWikiGraphArchiveSchemaVersion(\n archive.path,\n );\n try {\n const upgradeResult = await upgradeWikiGraphArchiveSchema(archive.path);\n const schemaVersionAfter = await readWikiGraphArchiveSchemaVersion(\n archive.path,\n );\n const item = {\n path: archive.path,\n publicId: archive.publicId,\n schemaVersionAfter,\n schemaVersionBefore,\n uri: archive.uri,\n };\n\n if (upgradeResult.changed) {\n upgraded.push(item);\n } else {\n skipped.push(item);\n }\n } catch (error) {\n return {\n failed: {\n message: formatErrorMessage(error),\n path: archive.path,\n publicId: archive.publicId,\n uri: archive.uri,\n },\n kind: \"lib\",\n library: formatLibraryResult(library),\n skipped,\n status: \"partial\",\n upgraded,\n };\n }\n }\n\n return {\n kind: \"lib\",\n library: formatLibraryResult(library),\n skipped,\n status: upgraded.length === 0 ? \"already-current\" : \"upgraded\",\n upgraded,\n };\n });\n}\n\nfunction resolveArchiveUpgradeTarget(target: string): string {\n if (target.startsWith(\"wikg://\")) {\n return requireArchiveUri(target);\n }\n if (!target.endsWith(\".wikg\")) {\n throw new Error(\n `Unsupported maintenance upgrade target: ${target}. Expected home, a .wikg archive, a .sdpub archive, or wikg://lib.`,\n );\n }\n return resolveHomeShorthand(target);\n}\n\nfunction isLegacySdpubTarget(target: string): boolean {\n return target.toLowerCase().endsWith(\".sdpub\");\n}\n\nfunction isHomeTarget(target: string): boolean {\n const resolved = resolveHomeShorthand(target).replace(/[\\\\/]+$/u, \"\");\n return (\n target === \"home\" ||\n target === \"~/.wikigraph\" ||\n resolved === resolveWikiGraphHomeDirectoryPath().replace(/[\\\\/]+$/u, \"\")\n );\n}\n\nfunction resolveHomeShorthand(path: string): string {\n return path.startsWith(\"~/\")\n ? resolve(homedir(), path.slice(2))\n : resolve(path);\n}\n\nfunction isUpgradeableLibraryArchive(\n archive: WikiGraphLibraryArchiveRecord,\n): boolean {\n return archive.exists && archive.status === \"present\";\n}\n\nasync function clearLibraryDerivedData(\n library: WikiGraphLibraryRecord,\n): Promise<void> {\n await rm(library.stagingPath, { force: true, recursive: true });\n}\n\nfunction formatLibraryScopeUpgradeTarget(\n target: ParsedWikiGraphLibraryUri,\n): string {\n return target.isDefault\n ? \"wikg://lib\"\n : `wikg://lib/${target.publicId ?? \"<lib-id>\"}`;\n}\n\nfunction formatLibraryResult(library: WikiGraphLibraryRecord): {\n readonly id: number;\n readonly publicId: string;\n readonly uri: string;\n readonly folderPath: string;\n readonly stagingPath: string;\n} {\n return {\n folderPath: library.folderPath,\n id: library.id,\n publicId: library.publicId,\n stagingPath: library.stagingPath,\n uri: library.uri,\n };\n}\n\nfunction formatErrorMessage(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n"],"mappings":"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","names":["schemaVersionBefore","schemaVersionAfter"]}
@@ -74,7 +74,7 @@ function getSearchBucket(type) {
74
74
  case "chapter-tree":
75
75
  case "meta":
76
76
  case "fragment":
77
- throw new Error(`Unsupported search result bucket type: ${type}`);
77
+ return 4;
78
78
  }
79
79
  }
80
80
  export {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../src/retrieval/query/archive-view/helper/sort.ts"],"sourcesContent":["import type {\n ArchiveFindHit,\n ArchiveFindObjectType,\n ArchiveFindOrder,\n} from \"../types.js\";\nimport {\n compareNumbers,\n getPositionChapter,\n getPositionDocumentOrder,\n getPositionFragment,\n getPositionSentence,\n getTypeOrder,\n} from \"./position.js\";\n\nexport function compareSearchHits(\n left: ArchiveFindHit,\n right: ArchiveFindHit,\n order: ArchiveFindOrder,\n): number {\n const direction = order === \"doc-asc\" ? 1 : -1;\n const relevance =\n compareNumbers(getSearchBucket(left.type), getSearchBucket(right.type)) ||\n compareNumbers(right.score ?? 0, left.score ?? 0) ||\n compareNumbers(right.matchCount ?? 0, left.matchCount ?? 0);\n const position =\n compareNumbers(\n getPositionDocumentOrder(left),\n getPositionDocumentOrder(right),\n ) ||\n compareNumbers(getPositionChapter(left), getPositionChapter(right)) ||\n compareNumbers(getPositionFragment(left), getPositionFragment(right)) ||\n compareNumbers(getPositionSentence(left), getPositionSentence(right)) ||\n compareNumbers(getTypeOrder(left.type), getTypeOrder(right.type)) ||\n left.id.localeCompare(right.id);\n\n return relevance || position * direction;\n}\n\nexport function compareListHits(\n left: ArchiveFindHit,\n right: ArchiveFindHit,\n order: ArchiveFindOrder,\n): number {\n const direction = order === \"doc-asc\" ? 1 : -1;\n const bucketComparison =\n compareNumbers(getListBucket(left.type), getListBucket(right.type)) ||\n compareListBucketItems(left, right);\n\n if (bucketComparison !== 0) {\n return bucketComparison;\n }\n\n return compareListPosition(left, right) * direction;\n}\n\nexport function compareListBucketItems(\n left: ArchiveFindHit,\n right: ArchiveFindHit,\n): number {\n const leftBucket = getListBucket(left.type);\n\n if (leftBucket !== getListBucket(right.type)) {\n return 0;\n }\n if (leftBucket === 0) {\n return compareNumbers(right.score ?? 0, left.score ?? 0);\n }\n\n return 0;\n}\n\nexport function compareListPosition(\n left: ArchiveFindHit,\n right: ArchiveFindHit,\n): number {\n return (\n compareNumbers(\n getPositionDocumentOrder(left),\n getPositionDocumentOrder(right),\n ) ||\n compareNumbers(getPositionChapter(left), getPositionChapter(right)) ||\n compareNumbers(getPositionFragment(left), getPositionFragment(right)) ||\n compareNumbers(getPositionSentence(left), getPositionSentence(right)) ||\n compareNumbers(getTypeOrder(left.type), getTypeOrder(right.type)) ||\n compareNumbers(left.archiveId ?? 0, right.archiveId ?? 0) ||\n left.id.localeCompare(right.id)\n );\n}\n\nexport function getListBucket(type: ArchiveFindObjectType): number {\n switch (type) {\n case \"entity\":\n case \"triple\":\n return 0;\n case \"node\":\n return 1;\n case \"summary\":\n return 2;\n case \"source\":\n case \"fragment\":\n return 3;\n case \"chapter-title\":\n case \"chapter\":\n case \"chapter-tree\":\n case \"meta\":\n return 4;\n }\n}\n\nexport function getSearchBucket(type: ArchiveFindObjectType): number {\n switch (type) {\n case \"chapter-title\":\n return 0;\n case \"entity\":\n case \"triple\":\n return 1;\n case \"node\":\n return 2;\n case \"source\":\n case \"summary\":\n return 3;\n case \"chapter\":\n case \"chapter-tree\":\n case \"meta\":\n case \"fragment\":\n throw new Error(`Unsupported search result bucket type: ${type}`);\n }\n}\n"],"mappings":"AAKA;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAEA,SAAS,kBACd,MACA,OACA,OACQ;AACR,QAAM,YAAY,UAAU,YAAY,IAAI;AAC5C,QAAM,YACJ,eAAe,gBAAgB,KAAK,IAAI,GAAG,gBAAgB,MAAM,IAAI,CAAC,KACtE,eAAe,MAAM,SAAS,GAAG,KAAK,SAAS,CAAC,KAChD,eAAe,MAAM,cAAc,GAAG,KAAK,cAAc,CAAC;AAC5D,QAAM,WACJ;AAAA,IACE,yBAAyB,IAAI;AAAA,IAC7B,yBAAyB,KAAK;AAAA,EAChC,KACA,eAAe,mBAAmB,IAAI,GAAG,mBAAmB,KAAK,CAAC,KAClE,eAAe,oBAAoB,IAAI,GAAG,oBAAoB,KAAK,CAAC,KACpE,eAAe,oBAAoB,IAAI,GAAG,oBAAoB,KAAK,CAAC,KACpE,eAAe,aAAa,KAAK,IAAI,GAAG,aAAa,MAAM,IAAI,CAAC,KAChE,KAAK,GAAG,cAAc,MAAM,EAAE;AAEhC,SAAO,aAAa,WAAW;AACjC;AAEO,SAAS,gBACd,MACA,OACA,OACQ;AACR,QAAM,YAAY,UAAU,YAAY,IAAI;AAC5C,QAAM,mBACJ,eAAe,cAAc,KAAK,IAAI,GAAG,cAAc,MAAM,IAAI,CAAC,KAClE,uBAAuB,MAAM,KAAK;AAEpC,MAAI,qBAAqB,GAAG;AAC1B,WAAO;AAAA,EACT;AAEA,SAAO,oBAAoB,MAAM,KAAK,IAAI;AAC5C;AAEO,SAAS,uBACd,MACA,OACQ;AACR,QAAM,aAAa,cAAc,KAAK,IAAI;AAE1C,MAAI,eAAe,cAAc,MAAM,IAAI,GAAG;AAC5C,WAAO;AAAA,EACT;AACA,MAAI,eAAe,GAAG;AACpB,WAAO,eAAe,MAAM,SAAS,GAAG,KAAK,SAAS,CAAC;AAAA,EACzD;AAEA,SAAO;AACT;AAEO,SAAS,oBACd,MACA,OACQ;AACR,SACE;AAAA,IACE,yBAAyB,IAAI;AAAA,IAC7B,yBAAyB,KAAK;AAAA,EAChC,KACA,eAAe,mBAAmB,IAAI,GAAG,mBAAmB,KAAK,CAAC,KAClE,eAAe,oBAAoB,IAAI,GAAG,oBAAoB,KAAK,CAAC,KACpE,eAAe,oBAAoB,IAAI,GAAG,oBAAoB,KAAK,CAAC,KACpE,eAAe,aAAa,KAAK,IAAI,GAAG,aAAa,MAAM,IAAI,CAAC,KAChE,eAAe,KAAK,aAAa,GAAG,MAAM,aAAa,CAAC,KACxD,KAAK,GAAG,cAAc,MAAM,EAAE;AAElC;AAEO,SAAS,cAAc,MAAqC;AACjE,UAAQ,MAAM;AAAA,IACZ,KAAK;AAAA,IACL,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AAAA,IACL,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AACH,aAAO;AAAA,EACX;AACF;AAEO,SAAS,gBAAgB,MAAqC;AACnE,UAAQ,MAAM;AAAA,IACZ,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AAAA,IACL,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AAAA,IACL,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AACH,YAAM,IAAI,MAAM,0CAA0C,IAAI,EAAE;AAAA,EACpE;AACF;","names":[]}
1
+ {"version":3,"sources":["../../../../../src/retrieval/query/archive-view/helper/sort.ts"],"sourcesContent":["import type {\n ArchiveFindHit,\n ArchiveFindObjectType,\n ArchiveFindOrder,\n} from \"../types.js\";\nimport {\n compareNumbers,\n getPositionChapter,\n getPositionDocumentOrder,\n getPositionFragment,\n getPositionSentence,\n getTypeOrder,\n} from \"./position.js\";\n\nexport function compareSearchHits(\n left: ArchiveFindHit,\n right: ArchiveFindHit,\n order: ArchiveFindOrder,\n): number {\n const direction = order === \"doc-asc\" ? 1 : -1;\n const relevance =\n compareNumbers(getSearchBucket(left.type), getSearchBucket(right.type)) ||\n compareNumbers(right.score ?? 0, left.score ?? 0) ||\n compareNumbers(right.matchCount ?? 0, left.matchCount ?? 0);\n const position =\n compareNumbers(\n getPositionDocumentOrder(left),\n getPositionDocumentOrder(right),\n ) ||\n compareNumbers(getPositionChapter(left), getPositionChapter(right)) ||\n compareNumbers(getPositionFragment(left), getPositionFragment(right)) ||\n compareNumbers(getPositionSentence(left), getPositionSentence(right)) ||\n compareNumbers(getTypeOrder(left.type), getTypeOrder(right.type)) ||\n left.id.localeCompare(right.id);\n\n return relevance || position * direction;\n}\n\nexport function compareListHits(\n left: ArchiveFindHit,\n right: ArchiveFindHit,\n order: ArchiveFindOrder,\n): number {\n const direction = order === \"doc-asc\" ? 1 : -1;\n const bucketComparison =\n compareNumbers(getListBucket(left.type), getListBucket(right.type)) ||\n compareListBucketItems(left, right);\n\n if (bucketComparison !== 0) {\n return bucketComparison;\n }\n\n return compareListPosition(left, right) * direction;\n}\n\nexport function compareListBucketItems(\n left: ArchiveFindHit,\n right: ArchiveFindHit,\n): number {\n const leftBucket = getListBucket(left.type);\n\n if (leftBucket !== getListBucket(right.type)) {\n return 0;\n }\n if (leftBucket === 0) {\n return compareNumbers(right.score ?? 0, left.score ?? 0);\n }\n\n return 0;\n}\n\nexport function compareListPosition(\n left: ArchiveFindHit,\n right: ArchiveFindHit,\n): number {\n return (\n compareNumbers(\n getPositionDocumentOrder(left),\n getPositionDocumentOrder(right),\n ) ||\n compareNumbers(getPositionChapter(left), getPositionChapter(right)) ||\n compareNumbers(getPositionFragment(left), getPositionFragment(right)) ||\n compareNumbers(getPositionSentence(left), getPositionSentence(right)) ||\n compareNumbers(getTypeOrder(left.type), getTypeOrder(right.type)) ||\n compareNumbers(left.archiveId ?? 0, right.archiveId ?? 0) ||\n left.id.localeCompare(right.id)\n );\n}\n\nexport function getListBucket(type: ArchiveFindObjectType): number {\n switch (type) {\n case \"entity\":\n case \"triple\":\n return 0;\n case \"node\":\n return 1;\n case \"summary\":\n return 2;\n case \"source\":\n case \"fragment\":\n return 3;\n case \"chapter-title\":\n case \"chapter\":\n case \"chapter-tree\":\n case \"meta\":\n return 4;\n }\n}\n\nexport function getSearchBucket(type: ArchiveFindObjectType): number {\n switch (type) {\n case \"chapter-title\":\n return 0;\n case \"entity\":\n case \"triple\":\n return 1;\n case \"node\":\n return 2;\n case \"source\":\n case \"summary\":\n return 3;\n case \"chapter\":\n case \"chapter-tree\":\n case \"meta\":\n case \"fragment\":\n return 4;\n }\n}\n"],"mappings":"AAKA;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAEA,SAAS,kBACd,MACA,OACA,OACQ;AACR,QAAM,YAAY,UAAU,YAAY,IAAI;AAC5C,QAAM,YACJ,eAAe,gBAAgB,KAAK,IAAI,GAAG,gBAAgB,MAAM,IAAI,CAAC,KACtE,eAAe,MAAM,SAAS,GAAG,KAAK,SAAS,CAAC,KAChD,eAAe,MAAM,cAAc,GAAG,KAAK,cAAc,CAAC;AAC5D,QAAM,WACJ;AAAA,IACE,yBAAyB,IAAI;AAAA,IAC7B,yBAAyB,KAAK;AAAA,EAChC,KACA,eAAe,mBAAmB,IAAI,GAAG,mBAAmB,KAAK,CAAC,KAClE,eAAe,oBAAoB,IAAI,GAAG,oBAAoB,KAAK,CAAC,KACpE,eAAe,oBAAoB,IAAI,GAAG,oBAAoB,KAAK,CAAC,KACpE,eAAe,aAAa,KAAK,IAAI,GAAG,aAAa,MAAM,IAAI,CAAC,KAChE,KAAK,GAAG,cAAc,MAAM,EAAE;AAEhC,SAAO,aAAa,WAAW;AACjC;AAEO,SAAS,gBACd,MACA,OACA,OACQ;AACR,QAAM,YAAY,UAAU,YAAY,IAAI;AAC5C,QAAM,mBACJ,eAAe,cAAc,KAAK,IAAI,GAAG,cAAc,MAAM,IAAI,CAAC,KAClE,uBAAuB,MAAM,KAAK;AAEpC,MAAI,qBAAqB,GAAG;AAC1B,WAAO;AAAA,EACT;AAEA,SAAO,oBAAoB,MAAM,KAAK,IAAI;AAC5C;AAEO,SAAS,uBACd,MACA,OACQ;AACR,QAAM,aAAa,cAAc,KAAK,IAAI;AAE1C,MAAI,eAAe,cAAc,MAAM,IAAI,GAAG;AAC5C,WAAO;AAAA,EACT;AACA,MAAI,eAAe,GAAG;AACpB,WAAO,eAAe,MAAM,SAAS,GAAG,KAAK,SAAS,CAAC;AAAA,EACzD;AAEA,SAAO;AACT;AAEO,SAAS,oBACd,MACA,OACQ;AACR,SACE;AAAA,IACE,yBAAyB,IAAI;AAAA,IAC7B,yBAAyB,KAAK;AAAA,EAChC,KACA,eAAe,mBAAmB,IAAI,GAAG,mBAAmB,KAAK,CAAC,KAClE,eAAe,oBAAoB,IAAI,GAAG,oBAAoB,KAAK,CAAC,KACpE,eAAe,oBAAoB,IAAI,GAAG,oBAAoB,KAAK,CAAC,KACpE,eAAe,aAAa,KAAK,IAAI,GAAG,aAAa,MAAM,IAAI,CAAC,KAChE,eAAe,KAAK,aAAa,GAAG,MAAM,aAAa,CAAC,KACxD,KAAK,GAAG,cAAc,MAAM,EAAE;AAElC;AAEO,SAAS,cAAc,MAAqC;AACjE,UAAQ,MAAM;AAAA,IACZ,KAAK;AAAA,IACL,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AAAA,IACL,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AACH,aAAO;AAAA,EACX;AACF;AAEO,SAAS,gBAAgB,MAAqC;AACnE,UAAQ,MAAM;AAAA,IACZ,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AAAA,IACL,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AAAA,IACL,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AACH,aAAO;AAAA,EACX;AACF;","names":[]}
@@ -1,8 +1,13 @@
1
1
  export { ensureWikiGraphHomeSchemaCurrent, readWikiGraphHomeSchemaVersion } from '../../document/home-schema-upgrade.js';
2
2
 
3
3
  declare const CURRENT_ARCHIVE_SCHEMA_VERSION = 2;
4
+ interface WikiGraphArchiveSchemaUpgradeResult {
5
+ readonly changed: boolean;
6
+ readonly repairedToc: boolean;
7
+ readonly schemaChanged: boolean;
8
+ }
4
9
  declare function ensureWikiGraphArchiveSchemaCurrent(archivePath: string): Promise<void>;
5
10
  declare function readWikiGraphArchiveSchemaVersion(archivePath: string): Promise<number>;
6
- declare function upgradeWikiGraphArchiveSchema(archivePath: string): Promise<void>;
11
+ declare function upgradeWikiGraphArchiveSchema(archivePath: string): Promise<WikiGraphArchiveSchemaUpgradeResult>;
7
12
 
8
- export { CURRENT_ARCHIVE_SCHEMA_VERSION, ensureWikiGraphArchiveSchemaCurrent, readWikiGraphArchiveSchemaVersion, upgradeWikiGraphArchiveSchema };
13
+ export { CURRENT_ARCHIVE_SCHEMA_VERSION, type WikiGraphArchiveSchemaUpgradeResult, ensureWikiGraphArchiveSchemaCurrent, readWikiGraphArchiveSchemaVersion, upgradeWikiGraphArchiveSchema };
@@ -61,41 +61,53 @@ async function readWikiGraphArchiveSchemaVersion(archivePath) {
61
61
  async function upgradeWikiGraphArchiveSchema(archivePath) {
62
62
  const resolvedArchivePath = resolve(archivePath);
63
63
  const schemaVersion = await readWikiGraphArchiveSchemaVersion(resolvedArchivePath);
64
- if (schemaVersion === CURRENT_ARCHIVE_SCHEMA_VERSION) {
65
- return;
66
- }
67
64
  if (schemaVersion > CURRENT_ARCHIVE_SCHEMA_VERSION) {
68
65
  throw new Error(
69
66
  `Unsupported Wiki Graph archive schema version: ${schemaVersion}.`
70
67
  );
71
68
  }
72
- await ensureWikiGraphHomeSchemaCurrent();
73
- const archiveKey = createArchiveKey(resolvedArchivePath);
74
- await assertArchiveUpgradeSafe(archiveKey);
75
- const temporaryPath = join(
76
- dirname(resolvedArchivePath),
77
- `.${getArchiveBasename(resolvedArchivePath)}.${process.pid}.${randomUUID()}.upgrade.tmp`
78
- );
79
69
  const temporaryDirectories = [];
80
70
  try {
81
71
  const tocOverlay = await createChapterTocUpgradeOverlay(
82
72
  resolvedArchivePath,
83
73
  temporaryDirectories
84
74
  );
75
+ const schemaChanged = schemaVersion < CURRENT_ARCHIVE_SCHEMA_VERSION;
76
+ if (!schemaChanged && tocOverlay === void 0) {
77
+ return {
78
+ changed: false,
79
+ repairedToc: false,
80
+ schemaChanged: false
81
+ };
82
+ }
83
+ await ensureWikiGraphHomeSchemaCurrent();
84
+ const archiveKey = createArchiveKey(resolvedArchivePath);
85
+ await assertArchiveUpgradeSafe(archiveKey);
86
+ const temporaryPath = join(
87
+ dirname(resolvedArchivePath),
88
+ `.${getArchiveBasename(resolvedArchivePath)}.${process.pid}.${randomUUID()}.upgrade.tmp`
89
+ );
85
90
  await writeWikgArchiveWithOverlays(
86
91
  resolvedArchivePath,
87
92
  temporaryPath,
88
93
  [
89
- {
90
- entryPath: SEARCH_INDEX_DATABASE_PATH,
91
- kind: "deleted"
92
- },
94
+ ...schemaChanged ? [
95
+ {
96
+ entryPath: SEARCH_INDEX_DATABASE_PATH,
97
+ kind: "deleted"
98
+ }
99
+ ] : [],
93
100
  ...tocOverlay === void 0 ? [] : [tocOverlay]
94
101
  ],
95
102
  { preserveMutationToken: true }
96
103
  );
97
104
  await rename(temporaryPath, resolvedArchivePath);
98
105
  await cleanupArchiveDerivedData(archiveKey);
106
+ return {
107
+ changed: true,
108
+ repairedToc: tocOverlay !== void 0,
109
+ schemaChanged
110
+ };
99
111
  } finally {
100
112
  await Promise.all(
101
113
  temporaryDirectories.map(async (path) => {