mirror of
https://github.com/hanzo-docs/docs.git
synced 2026-10-26 10:55:57 +00:00
Core: Support function for loader option in Search API
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'fumadocs-core': patch
|
||||
---
|
||||
|
||||
Support function for loader option in Search API
|
||||
@@ -69,11 +69,7 @@ function server(options: Options): SearchServer {
|
||||
};
|
||||
}
|
||||
|
||||
export function flexsearch(options: Options): SearchAPI {
|
||||
return createEndpoint(server(options));
|
||||
}
|
||||
|
||||
export function flexsearchI18n(options: I18nOptions): SearchAPI {
|
||||
function serverI18n(options: I18nOptions): SearchServer {
|
||||
const { indexes: inputIndexes, localeMap } = options;
|
||||
|
||||
async function initSearchServers() {
|
||||
@@ -109,7 +105,7 @@ export function flexsearchI18n(options: I18nOptions): SearchAPI {
|
||||
}
|
||||
|
||||
const get = initSearchServers();
|
||||
return createEndpoint({
|
||||
return {
|
||||
async export(): Promise<ExportedData> {
|
||||
const map = await get;
|
||||
const entries = Array.from(map.entries()).map(async ([k, v]) => {
|
||||
@@ -129,7 +125,15 @@ export function flexsearchI18n(options: I18nOptions): SearchAPI {
|
||||
if (handler) return handler.search(query, searchOptions);
|
||||
return [];
|
||||
},
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
export function flexsearch(options: Options): SearchAPI {
|
||||
return createEndpoint(server(options));
|
||||
}
|
||||
|
||||
export function flexsearchI18n(options: I18nOptions): SearchAPI {
|
||||
return createEndpoint(serverI18n(options));
|
||||
}
|
||||
|
||||
export interface FromSourceOptions<C extends LoaderConfig> extends Pick<
|
||||
@@ -139,14 +143,19 @@ export interface FromSourceOptions<C extends LoaderConfig> extends Pick<
|
||||
buildIndex?: (page: Page<C['source']['pageData']>) => Awaitable<Index>;
|
||||
}
|
||||
|
||||
/**
|
||||
* create server from loader, if passed as function, the server will re-index all records once a different instance of loader is returned.
|
||||
*/
|
||||
export function flexsearchFromSource<C extends LoaderConfig>(
|
||||
loader: LoaderOutput<C>,
|
||||
loader: LoaderOutput<C> | (() => Awaitable<LoaderOutput<C>>),
|
||||
options: FromSourceOptions<NoInfer<C>> = {},
|
||||
) {
|
||||
const cache = new WeakMap<LoaderOutput<C>, Promise<SearchServer>>();
|
||||
const { buildIndex = buildIndexDefault, ...rest } = options;
|
||||
function indexes(): Promise<IndexWithLocale[]> {
|
||||
return Promise.all(
|
||||
loader.getPages().map(async (page) => {
|
||||
|
||||
async function initServer(loader: LoaderOutput<C>): Promise<SearchServer> {
|
||||
const indexes = await Promise.all(
|
||||
loader.getPages().map(async (page): Promise<IndexWithLocale> => {
|
||||
const index = await buildIndex(page);
|
||||
return {
|
||||
...index,
|
||||
@@ -155,18 +164,33 @@ export function flexsearchFromSource<C extends LoaderConfig>(
|
||||
};
|
||||
}),
|
||||
);
|
||||
|
||||
if (loader._i18n)
|
||||
return serverI18n({
|
||||
indexes,
|
||||
i18n: loader._i18n,
|
||||
...rest,
|
||||
});
|
||||
|
||||
return server({ indexes, ...rest });
|
||||
}
|
||||
|
||||
if (loader._i18n) {
|
||||
return flexsearchI18n({
|
||||
indexes,
|
||||
i18n: loader._i18n,
|
||||
...rest,
|
||||
});
|
||||
async function getCurrentServer() {
|
||||
const l = typeof loader === 'function' ? await loader() : loader;
|
||||
let server = cache.get(l);
|
||||
if (!server) {
|
||||
server = initServer(l);
|
||||
cache.set(l, server);
|
||||
}
|
||||
return await server;
|
||||
}
|
||||
|
||||
return flexsearch({
|
||||
indexes,
|
||||
...rest,
|
||||
return createEndpoint({
|
||||
async export() {
|
||||
return (await getCurrentServer()).export();
|
||||
},
|
||||
async search(query, options) {
|
||||
return (await getCurrentServer()).search(query, options);
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
@@ -267,52 +267,60 @@ interface Options<C extends LoaderConfig> extends Omit<AdvancedOptions, 'indexes
|
||||
buildIndex?: (page: Page<C['source']['pageData']>) => Awaitable<AdvancedIndex>;
|
||||
}
|
||||
|
||||
/**
|
||||
* create server from loader, if passed as function, the server will re-index all records once a different instance of loader is returned.
|
||||
*/
|
||||
export function createFromSource<C extends LoaderConfig>(
|
||||
source: LoaderOutput<C>,
|
||||
options?: Options<C>,
|
||||
): SearchAPI<OramaQueryOptions>;
|
||||
|
||||
export function createFromSource<C extends LoaderConfig>(
|
||||
source: LoaderOutput<C>,
|
||||
loader: LoaderOutput<C> | (() => Awaitable<LoaderOutput<C>>),
|
||||
options: Options<C> = {},
|
||||
): SearchAPI<OramaQueryOptions> {
|
||||
const { buildIndex = buildIndexDefault } = options;
|
||||
const cache = new WeakMap<LoaderOutput<C>, Promise<SearchServer<OramaQueryOptions>>>();
|
||||
|
||||
if (source._i18n) {
|
||||
return createI18nSearchAPI('advanced', {
|
||||
async function initServer(loader: LoaderOutput<C>) {
|
||||
const indexes = await Promise.all(
|
||||
loader.getPages().map(async (page) => {
|
||||
const index = await buildIndex(page);
|
||||
return {
|
||||
...index,
|
||||
breadcrumbs: index.breadcrumbs ?? buildBreadcrumbs(loader, page),
|
||||
locale: page.locale,
|
||||
};
|
||||
}),
|
||||
);
|
||||
|
||||
if (loader._i18n) {
|
||||
return createI18nSearchAPI('advanced', {
|
||||
...options,
|
||||
indexes: indexes as WithLocale<AdvancedIndex>[],
|
||||
i18n: loader._i18n,
|
||||
});
|
||||
}
|
||||
|
||||
return initAdvancedSearch({
|
||||
indexes,
|
||||
...options,
|
||||
i18n: source._i18n,
|
||||
async indexes() {
|
||||
const indexes = source.getLanguages().flatMap((entry) => {
|
||||
return entry.pages.map(async (page) => {
|
||||
const index = await buildIndex(page);
|
||||
return {
|
||||
...index,
|
||||
breadcrumbs: index.breadcrumbs ?? buildBreadcrumbs(source, page),
|
||||
locale: entry.language,
|
||||
};
|
||||
});
|
||||
});
|
||||
|
||||
return Promise.all(indexes);
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
return toAPI(
|
||||
initAdvancedSearch({
|
||||
...options,
|
||||
async indexes() {
|
||||
const indexes = source.getPages().map(async (page) => {
|
||||
const index = await buildIndex(page);
|
||||
if (index.breadcrumbs) return index;
|
||||
return { ...index, breadcrumbs: buildBreadcrumbs(source, page) };
|
||||
});
|
||||
async function getCurrentServer() {
|
||||
const l = typeof loader === 'function' ? await loader() : loader;
|
||||
let server = cache.get(l);
|
||||
if (!server) {
|
||||
server = initServer(l);
|
||||
cache.set(l, server);
|
||||
}
|
||||
return await server;
|
||||
}
|
||||
|
||||
return Promise.all(indexes);
|
||||
},
|
||||
}),
|
||||
);
|
||||
return toAPI({
|
||||
async export() {
|
||||
return (await getCurrentServer()).export();
|
||||
},
|
||||
async search(query, options) {
|
||||
return (await getCurrentServer()).search(query, options);
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
function toAPI(server: SearchServer<OramaQueryOptions>): SearchAPI<OramaQueryOptions> {
|
||||
|
||||
Reference in New Issue
Block a user