Files
docs/src/search-providers.ts
T
2026-06-16 15:13:13 +03:00

78 lines
1.8 KiB
TypeScript

import type {
SearchConfig,
SearchProvider,
SearchResult,
} from '../plugins/docuservix-search/types';
interface RawResult {
score: number;
file: string;
heading: string;
anchor?: string;
content: string;
}
function stripNumericPrefixes(p: string): string {
return p
.split('/')
.map((seg) => seg.replace(/^\d+-/, ''))
.join('/');
}
function resultToUrl(file: string, anchor: string): string {
let p = file.replace(/^docs\//, '').replace(/\.md$/, '');
p = stripNumericPrefixes(p);
return `/docs/${p}#${anchor}`;
}
function resultToDisplayPath(file: string): string {
const p = file.replace(/^docs\//, '').replace(/\.md$/, '');
return stripNumericPrefixes(p);
}
function rawToSearchResult(raw: RawResult): SearchResult {
return {
title: raw.heading,
content: raw.content,
path: resultToDisplayPath(raw.file),
anchor: raw.anchor,
type: 'docs',
relevance: raw.score,
url: resultToUrl(raw.file, raw.anchor),
};
}
const docsProvider: SearchProvider = {
id: 'docs',
name: 'Документация',
timeout: 5000,
async search(query, signal) {
const res = await fetch(
`http://localhost:8080/1vit/more/v1/search?q=${encodeURIComponent(query)}&limit=25`,
{ signal },
);
if (!res.ok) {
throw new Error(`HTTP ${res.status}`);
}
const data: { results: RawResult[] } = await res.json();
return {
results: (data.results ?? []).map(rawToSearchResult),
};
},
};
const searchConfig: SearchConfig = {
timeout: 5000,
providers: [docsProvider],
};
export default searchConfig;
export const chatUrl = 'http://localhost:8080/1vit/more/v1/chat';