mirror of
https://github.com/hanzo-docs/docs.git
synced 2026-10-25 04:20:02 +00:00
Core: concentrate search API utils
This commit is contained in:
@@ -0,0 +1,9 @@
|
||||
---
|
||||
'fumadocs-core': minor
|
||||
---
|
||||
|
||||
**Move `SortedResult` and other search-related types to `fumadocs-core/search`**
|
||||
|
||||
This also exposed the search result highlighter API, you may now use it for highlighting results of your own search integration
|
||||
|
||||
Old export will be kept until the next major release.
|
||||
@@ -1,11 +1,12 @@
|
||||
import type * as Breadcrumb from 'fumadocs-core/breadcrumb';
|
||||
import type * as TOC from 'fumadocs-core/toc';
|
||||
import type * as Server from 'fumadocs-core/server';
|
||||
import type * as Search from 'fumadocs-core/search';
|
||||
import type * as Sidebar from 'fumadocs-core/sidebar';
|
||||
import type { ElementType } from 'react';
|
||||
import type * as MDX from 'fumadocs-core/mdx-plugins';
|
||||
|
||||
export type SortedResult = Server.SortedResult;
|
||||
export type SortedResult = Search.SortedResult;
|
||||
|
||||
export type StructureOptions = MDX.StructureOptions;
|
||||
|
||||
|
||||
@@ -32,6 +32,10 @@
|
||||
"import": "./dist/hide-if-empty.js",
|
||||
"types": "./dist/hide-if-empty.d.ts"
|
||||
},
|
||||
"./search": {
|
||||
"import": "./dist/search/index.js",
|
||||
"types": "./dist/search/index.d.ts"
|
||||
},
|
||||
"./search/*": {
|
||||
"import": "./dist/search/*.js",
|
||||
"types": "./dist/search/*.d.ts"
|
||||
|
||||
@@ -6,7 +6,7 @@ import { type StaticOptions } from '@/search/client/static';
|
||||
import { type AlgoliaOptions } from '@/search/client/algolia';
|
||||
import { type OramaCloudOptions } from '@/search/client/orama-cloud';
|
||||
import { type MixedbreadOptions } from '@/search/client/mixedbread';
|
||||
import type { SortedResult } from '@/search/shared';
|
||||
import type { SortedResult } from '@/search';
|
||||
|
||||
interface UseDocsSearch {
|
||||
search: string;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import type { BaseIndex } from '@/search/algolia';
|
||||
import type { Hit, LiteClient, SearchResponse } from 'algoliasearch/lite';
|
||||
import { createContentHighlighter, type SortedResult } from '@/search/shared';
|
||||
import { createContentHighlighter, type SortedResult } from '@/search';
|
||||
|
||||
export interface AlgoliaOptions {
|
||||
indexName: string;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { SortedResult } from '@/server';
|
||||
import type { SortedResult } from '@/search';
|
||||
|
||||
export interface FetchOptions {
|
||||
/**
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { SortedResult } from '@/server';
|
||||
import type { SortedResult } from '@/search';
|
||||
import Mixedbread from '@mixedbread/sdk';
|
||||
import { VectorStoreSearchResponse } from '@mixedbread/sdk/resources/vector-stores';
|
||||
import removeMd from 'remove-markdown';
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
import type { SortedResult } from '@/server';
|
||||
import type { ClientSearchParams, OramaClient } from '@oramacloud/client';
|
||||
import { removeUndefined } from '@/utils/remove-undefined';
|
||||
import type { OramaIndex } from '@/search/orama-cloud';
|
||||
import { createContentHighlighter } from '@/search/shared';
|
||||
import { createContentHighlighter, type SortedResult } from '@/search';
|
||||
|
||||
interface CrawlerIndex {
|
||||
path: string;
|
||||
|
||||
@@ -1,18 +1,27 @@
|
||||
export interface SortedResult {
|
||||
import type { ReactNode } from 'react';
|
||||
|
||||
export interface SortedResult<Content = string> {
|
||||
id: string;
|
||||
url: string;
|
||||
type: 'page' | 'heading' | 'text';
|
||||
content: string;
|
||||
contentWithHighlights?: HighlightedText[];
|
||||
content: Content;
|
||||
|
||||
/**
|
||||
* breadcrumbs to be displayed on UI
|
||||
*/
|
||||
breadcrumbs?: Content[];
|
||||
contentWithHighlights?: HighlightedText<Content>[];
|
||||
}
|
||||
|
||||
export type HighlightedText = {
|
||||
export type ReactSortedResult = SortedResult<ReactNode>;
|
||||
|
||||
export interface HighlightedText<Content = string> {
|
||||
type: 'text';
|
||||
content: string;
|
||||
content: Content;
|
||||
styles?: {
|
||||
highlight?: boolean;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
function escapeRegExp(input: string): string {
|
||||
return input.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
||||
@@ -4,8 +4,7 @@ import {
|
||||
type advancedSchema,
|
||||
} from '@/search/orama/create-db';
|
||||
import { removeUndefined } from '@/utils/remove-undefined';
|
||||
import type { SortedResult } from '@/server';
|
||||
import { createContentHighlighter } from '@/search/shared';
|
||||
import { createContentHighlighter, type SortedResult } from '@/search';
|
||||
|
||||
export async function searchAdvanced(
|
||||
db: Orama<typeof advancedSchema>,
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
import { type Orama, search, type SearchParams } from '@orama/orama';
|
||||
import type { SortedResult } from '@/server';
|
||||
import {
|
||||
type SimpleDocument,
|
||||
type simpleSchema,
|
||||
} from '@/search/orama/create-db';
|
||||
import { createContentHighlighter } from '@/search/shared';
|
||||
import { createContentHighlighter, type SortedResult } from '@/search';
|
||||
|
||||
export async function searchSimple(
|
||||
db: Orama<typeof simpleSchema>,
|
||||
|
||||
@@ -17,7 +17,7 @@ import {
|
||||
} from '@/search/orama/create-db';
|
||||
import { searchSimple } from '@/search/orama/search/simple';
|
||||
import { searchAdvanced } from '@/search/orama/search/advanced';
|
||||
import type { SortedResult } from '@/search/shared';
|
||||
import type { SortedResult } from '@/search';
|
||||
|
||||
type SearchType = 'simple' | 'advanced';
|
||||
|
||||
@@ -181,4 +181,4 @@ export function initAdvancedSearch(options: AdvancedOptions): SearchServer {
|
||||
|
||||
export { createFromSource } from './orama/create-from-source';
|
||||
export { createI18nSearchAPI } from './orama/create-i18n';
|
||||
export * from './shared';
|
||||
export * from './index';
|
||||
|
||||
@@ -4,5 +4,5 @@ export * as PageTree from '../source/page-tree/definitions';
|
||||
export * from './git-api';
|
||||
export * from './metadata';
|
||||
|
||||
// backward compat
|
||||
export type { SortedResult } from '../search/shared';
|
||||
// TODO: replace this with `fumadocs-core/search`
|
||||
export type { SortedResult } from '../search';
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { expect, test } from 'vitest';
|
||||
import { createContentHighlighter } from '@/search/shared';
|
||||
import { createContentHighlighter } from '@/search';
|
||||
|
||||
test('highlight search results', () => {
|
||||
const highlighter = createContentHighlighter('hello world helloworld');
|
||||
|
||||
@@ -12,10 +12,7 @@ export default defineConfig({
|
||||
entry: [
|
||||
'src/{toc,link,breadcrumb,sidebar,dynamic-link,hide-if-empty}.tsx',
|
||||
'src/{server,source,mdx-plugins,content}/index.ts',
|
||||
'src/search/client.ts',
|
||||
'src/search/server.ts',
|
||||
'src/search/algolia.ts',
|
||||
'src/search/orama-cloud.ts',
|
||||
'src/search/{index,client,server,algolia,orama-cloud}.ts',
|
||||
'src/utils/use-on-change.ts',
|
||||
'src/utils/use-effect-event.ts',
|
||||
'src/utils/use-media-query.ts',
|
||||
|
||||
@@ -16,11 +16,11 @@ import {
|
||||
SearchDialogInput,
|
||||
SearchDialogList,
|
||||
SearchDialogOverlay,
|
||||
type SharedProps,
|
||||
TagsList,
|
||||
TagsListItem,
|
||||
type SharedProps,
|
||||
} from './search';
|
||||
import type { SortedResult } from 'fumadocs-core/server';
|
||||
import type { SortedResult } from 'fumadocs-core/search';
|
||||
import type { SearchLink, TagItem } from '@/contexts/search';
|
||||
import { useI18n } from '@/contexts/i18n';
|
||||
|
||||
|
||||
@@ -14,11 +14,11 @@ import {
|
||||
SearchDialogInput,
|
||||
SearchDialogList,
|
||||
SearchDialogOverlay,
|
||||
type SharedProps,
|
||||
TagsList,
|
||||
TagsListItem,
|
||||
type SharedProps,
|
||||
} from './search';
|
||||
import type { SortedResult } from 'fumadocs-core/server';
|
||||
import type { SortedResult } from 'fumadocs-core/search';
|
||||
import type { SearchLink, TagItem } from '@/contexts/search';
|
||||
|
||||
export interface DefaultSearchDialogProps extends SharedProps {
|
||||
|
||||
@@ -16,11 +16,11 @@ import {
|
||||
SearchDialogInput,
|
||||
SearchDialogList,
|
||||
SearchDialogOverlay,
|
||||
type SharedProps,
|
||||
TagsList,
|
||||
TagsListItem,
|
||||
type SharedProps,
|
||||
} from './search';
|
||||
import type { SortedResult } from 'fumadocs-core/server';
|
||||
import type { SortedResult } from 'fumadocs-core/search';
|
||||
import type { SearchLink, TagItem } from '@/contexts/search';
|
||||
import { useI18n } from '@/contexts/i18n';
|
||||
|
||||
|
||||
@@ -21,7 +21,10 @@ import {
|
||||
DialogOverlay,
|
||||
DialogTitle,
|
||||
} from '@radix-ui/react-dialog';
|
||||
import type { SortedResult } from 'fumadocs-core/server';
|
||||
import type {
|
||||
HighlightedText,
|
||||
ReactSortedResult as BaseResultType,
|
||||
} from 'fumadocs-core/search';
|
||||
import { cva } from 'class-variance-authority';
|
||||
import { useEffectEvent } from 'fumadocs-core/utils/use-effect-event';
|
||||
import { useRouter } from 'fumadocs-core/framework';
|
||||
@@ -29,12 +32,10 @@ import type { SharedProps } from '@/contexts/search';
|
||||
import { useOnChange } from 'fumadocs-core/utils/use-on-change';
|
||||
import scrollIntoView from 'scroll-into-view-if-needed';
|
||||
import { buttonVariants } from '@/components/ui/button';
|
||||
import type { HighlightedText } from 'fumadocs-core/search/server';
|
||||
|
||||
type ReactSortedResult = Omit<SortedResult, 'content'> & {
|
||||
interface ReactSortedResult extends BaseResultType {
|
||||
external?: boolean;
|
||||
content: ReactNode;
|
||||
};
|
||||
}
|
||||
|
||||
// needed for backward compatible since some previous guides referenced it
|
||||
export type { SharedProps };
|
||||
@@ -469,7 +470,7 @@ export function TagsListItem({
|
||||
);
|
||||
}
|
||||
|
||||
function renderHighlights(highlights: HighlightedText[]): ReactNode {
|
||||
function renderHighlights(highlights: HighlightedText<ReactNode>[]): ReactNode {
|
||||
return highlights.map((node, i) => {
|
||||
if (node.styles?.highlight) {
|
||||
return (
|
||||
|
||||
Reference in New Issue
Block a user