mirror of
https://github.com/hanzo-docs/docs.git
synced 2026-10-26 23:49:51 +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 {
|
function serverI18n(options: I18nOptions): SearchServer {
|
||||||
return createEndpoint(server(options));
|
|
||||||
}
|
|
||||||
|
|
||||||
export function flexsearchI18n(options: I18nOptions): SearchAPI {
|
|
||||||
const { indexes: inputIndexes, localeMap } = options;
|
const { indexes: inputIndexes, localeMap } = options;
|
||||||
|
|
||||||
async function initSearchServers() {
|
async function initSearchServers() {
|
||||||
@@ -109,7 +105,7 @@ export function flexsearchI18n(options: I18nOptions): SearchAPI {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const get = initSearchServers();
|
const get = initSearchServers();
|
||||||
return createEndpoint({
|
return {
|
||||||
async export(): Promise<ExportedData> {
|
async export(): Promise<ExportedData> {
|
||||||
const map = await get;
|
const map = await get;
|
||||||
const entries = Array.from(map.entries()).map(async ([k, v]) => {
|
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);
|
if (handler) return handler.search(query, searchOptions);
|
||||||
return [];
|
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<
|
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>;
|
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>(
|
export function flexsearchFromSource<C extends LoaderConfig>(
|
||||||
loader: LoaderOutput<C>,
|
loader: LoaderOutput<C> | (() => Awaitable<LoaderOutput<C>>),
|
||||||
options: FromSourceOptions<NoInfer<C>> = {},
|
options: FromSourceOptions<NoInfer<C>> = {},
|
||||||
) {
|
) {
|
||||||
|
const cache = new WeakMap<LoaderOutput<C>, Promise<SearchServer>>();
|
||||||
const { buildIndex = buildIndexDefault, ...rest } = options;
|
const { buildIndex = buildIndexDefault, ...rest } = options;
|
||||||
function indexes(): Promise<IndexWithLocale[]> {
|
|
||||||
return Promise.all(
|
async function initServer(loader: LoaderOutput<C>): Promise<SearchServer> {
|
||||||
loader.getPages().map(async (page) => {
|
const indexes = await Promise.all(
|
||||||
|
loader.getPages().map(async (page): Promise<IndexWithLocale> => {
|
||||||
const index = await buildIndex(page);
|
const index = await buildIndex(page);
|
||||||
return {
|
return {
|
||||||
...index,
|
...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) {
|
async function getCurrentServer() {
|
||||||
return flexsearchI18n({
|
const l = typeof loader === 'function' ? await loader() : loader;
|
||||||
indexes,
|
let server = cache.get(l);
|
||||||
i18n: loader._i18n,
|
if (!server) {
|
||||||
...rest,
|
server = initServer(l);
|
||||||
});
|
cache.set(l, server);
|
||||||
|
}
|
||||||
|
return await server;
|
||||||
}
|
}
|
||||||
|
|
||||||
return flexsearch({
|
return createEndpoint({
|
||||||
indexes,
|
async export() {
|
||||||
...rest,
|
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>;
|
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>(
|
export function createFromSource<C extends LoaderConfig>(
|
||||||
source: LoaderOutput<C>,
|
loader: LoaderOutput<C> | (() => Awaitable<LoaderOutput<C>>),
|
||||||
options?: Options<C>,
|
|
||||||
): SearchAPI<OramaQueryOptions>;
|
|
||||||
|
|
||||||
export function createFromSource<C extends LoaderConfig>(
|
|
||||||
source: LoaderOutput<C>,
|
|
||||||
options: Options<C> = {},
|
options: Options<C> = {},
|
||||||
): SearchAPI<OramaQueryOptions> {
|
): SearchAPI<OramaQueryOptions> {
|
||||||
const { buildIndex = buildIndexDefault } = options;
|
const { buildIndex = buildIndexDefault } = options;
|
||||||
|
const cache = new WeakMap<LoaderOutput<C>, Promise<SearchServer<OramaQueryOptions>>>();
|
||||||
|
|
||||||
if (source._i18n) {
|
async function initServer(loader: LoaderOutput<C>) {
|
||||||
return createI18nSearchAPI('advanced', {
|
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,
|
...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(
|
async function getCurrentServer() {
|
||||||
initAdvancedSearch({
|
const l = typeof loader === 'function' ? await loader() : loader;
|
||||||
...options,
|
let server = cache.get(l);
|
||||||
async indexes() {
|
if (!server) {
|
||||||
const indexes = source.getPages().map(async (page) => {
|
server = initServer(l);
|
||||||
const index = await buildIndex(page);
|
cache.set(l, server);
|
||||||
if (index.breadcrumbs) return index;
|
}
|
||||||
return { ...index, breadcrumbs: buildBreadcrumbs(source, page) };
|
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> {
|
function toAPI(server: SearchServer<OramaQueryOptions>): SearchAPI<OramaQueryOptions> {
|
||||||
|
|||||||
Reference in New Issue
Block a user