This commit is contained in:
@@ -0,0 +1,40 @@
|
||||
// The status a page reads: the module flag, the search service's readiness (separate from the
|
||||
// indexing indicator, which is the per-document rows), and the document counts by progress state.
|
||||
|
||||
import { type DocumentStatus, documents } from "../contract/index.js"
|
||||
import { type KnowledgeDeps, type KnowledgeScope, knowledgeEnabled } from "./ports.js"
|
||||
|
||||
const PAGE = 200
|
||||
|
||||
export interface KnowledgeStatus {
|
||||
enabled: boolean
|
||||
service: { state: "registered" | "indexing" | "ready" | "degraded" | "disabled" | "unavailable"; reasons: string[] }
|
||||
documents: Record<DocumentStatus, number>
|
||||
}
|
||||
|
||||
export async function knowledgeStatusOf(deps: KnowledgeDeps, scope: KnowledgeScope): Promise<KnowledgeStatus> {
|
||||
const counts: Record<DocumentStatus, number> = { queued: 0, indexing: 0, indexed: 0, failed: 0, cancelled: 0 }
|
||||
let cursor: string | undefined
|
||||
for (;;) {
|
||||
const page = await deps.data
|
||||
.forScope(scope)
|
||||
.of(documents)
|
||||
.list({ limit: PAGE, ...(cursor === undefined ? {} : { cursor }) })
|
||||
for (const row of page.items) counts[row.status as DocumentStatus] += 1
|
||||
if (!page.hasMore) break
|
||||
cursor = page.cursor
|
||||
}
|
||||
const enabled = await knowledgeEnabled(deps, scope)
|
||||
const readiness =
|
||||
deps.search === undefined
|
||||
? { state: "unavailable" as const, reasons: ["the knowledge search service is not bound in this process"] }
|
||||
: await deps.search.readiness(scope).catch((error: unknown) => ({
|
||||
state: "unavailable" as const,
|
||||
reasons: [
|
||||
error instanceof Error
|
||||
? (error.message.split("\n")[0] ?? error.message)
|
||||
: "the search service did not answer",
|
||||
],
|
||||
}))
|
||||
return { enabled, service: readiness, documents: counts }
|
||||
}
|
||||
Reference in New Issue
Block a user