/**
 * @beignet/core/search
 *
 * Provider-neutral search primitives for Beignet applications.
 */
/**
 * Primitive values accepted in indexed documents and provider-neutral filters.
 */
export type SearchPrimitive = null | boolean | number | string;
/**
 * JSON-like values accepted in indexed documents.
 */
export type SearchValue = SearchPrimitive | readonly SearchValue[] | {
    readonly [key: string]: SearchValue;
};
/**
 * Minimal document shape accepted by search indexes.
 */
export type SearchDocumentBase = {
    id: string;
};
/**
 * General search document shape.
 */
export type SearchDocument = SearchDocumentBase & {
    readonly [field: string]: SearchValue | undefined;
};
type SearchField<TDocument extends SearchDocumentBase> = Extract<keyof TDocument, string>;
/**
 * Provider-neutral index definition.
 */
export type SearchIndexDef<TDocument extends SearchDocumentBase = SearchDocument> = {
    kind: "search-index";
    name: string;
    primaryKey: SearchField<TDocument>;
    searchableAttributes?: readonly SearchField<TDocument>[];
    filterableAttributes?: readonly SearchField<TDocument>[];
    sortableAttributes?: readonly SearchField<TDocument>[];
    displayedAttributes?: readonly SearchField<TDocument>[];
    metadata?: Record<string, unknown>;
};
/**
 * Options accepted when defining a search index.
 */
export type DefineSearchIndexOptions<TDocument extends SearchDocumentBase> = Omit<SearchIndexDef<TDocument>, "kind" | "name" | "primaryKey"> & {
    primaryKey?: SearchField<TDocument>;
};
/**
 * Provider-neutral filter values.
 */
export type SearchFilterValue = SearchPrimitive | readonly Exclude<SearchPrimitive, null>[];
/**
 * Provider-neutral exact-match filters.
 */
export type SearchFilters = Record<string, SearchFilterValue>;
/**
 * Provider-neutral sort expression. Use `field:asc` or `field:desc`.
 */
export type SearchSort = `${string}:asc` | `${string}:desc` | (string & {});
/**
 * Query accepted by search providers.
 */
export type SearchQuery = {
    query?: string;
    filters?: SearchFilters;
    sort?: readonly SearchSort[];
    facets?: readonly string[];
    limit?: number;
    offset?: number;
};
/**
 * Page metadata returned from search providers.
 */
export type SearchResultPage = {
    kind: "offset";
    limit: number;
    offset: number;
    total?: number;
    hasMore: boolean;
};
/**
 * Search result payload.
 */
export type SearchResults<TDocument extends SearchDocumentBase> = {
    hits: TDocument[];
    query: string;
    page: SearchResultPage;
    processingTimeMs?: number;
    facets?: Record<string, Record<string, number>>;
};
/**
 * Result returned after indexing documents.
 */
export type SearchIndexResult = {
    indexed: number;
    taskId?: string | number;
};
/**
 * Result returned after deleting indexed documents.
 */
export type SearchDeleteResult = {
    deleted: number;
    taskId?: string | number;
};
/**
 * App-facing search port.
 */
export type SearchPort = {
    configureIndex<TDocument extends SearchDocumentBase>(index: SearchIndexDef<TDocument>): Promise<void>;
    indexDocuments<TDocument extends SearchDocumentBase>(index: SearchIndexDef<TDocument>, documents: TDocument | readonly TDocument[]): Promise<SearchIndexResult>;
    deleteDocuments<TDocument extends SearchDocumentBase>(index: SearchIndexDef<TDocument>, ids: string | readonly string[]): Promise<SearchDeleteResult>;
    clearIndex<TDocument extends SearchDocumentBase>(index: SearchIndexDef<TDocument>): Promise<SearchDeleteResult>;
    search<TDocument extends SearchDocumentBase>(index: SearchIndexDef<TDocument>, query: SearchQuery): Promise<SearchResults<TDocument>>;
};
/**
 * Captured memory index state exposed for tests.
 */
export type MemorySearchIndexState<TDocument extends SearchDocumentBase = SearchDocument> = {
    definition?: SearchIndexDef<TDocument>;
    documents: Map<string, TDocument>;
};
/**
 * In-memory search port exposed for assertions in tests.
 */
export type MemorySearchPort = SearchPort & {
    indexes: Map<string, MemorySearchIndexState>;
    reset(index?: SearchIndexDef): void;
};
/**
 * Options for the in-memory search adapter.
 */
export type CreateMemorySearchOptions = {
    now?: () => Date;
};
/**
 * Options for the in-memory search provider.
 */
export type MemorySearchProviderOptions = CreateMemorySearchOptions & {
    name?: string;
};
/**
 * Ports contributed by the memory search provider.
 */
export interface MemorySearchProviderPorts {
    search: SearchPort;
}
/**
 * Error thrown when search inputs are invalid.
 */
export declare class SearchOptionsError extends Error {
    constructor(message: string);
}
/**
 * Define a typed search index.
 */
export declare function defineSearchIndex<TDocument extends SearchDocumentBase = SearchDocument>(name: string, options?: DefineSearchIndexOptions<TDocument>): SearchIndexDef<TDocument>;
/**
 * Index documents through any `SearchPort`.
 */
export declare function indexSearchDocuments<TDocument extends SearchDocumentBase>(search: SearchPort, index: SearchIndexDef<TDocument>, documents: TDocument | readonly TDocument[]): Promise<SearchIndexResult>;
/**
 * Query documents through any `SearchPort`.
 */
export declare function searchDocuments<TDocument extends SearchDocumentBase>(search: SearchPort, index: SearchIndexDef<TDocument>, query: SearchQuery): Promise<SearchResults<TDocument>>;
/**
 * Create an in-memory search port for tests and single-process development.
 */
export declare function createMemorySearch(_options?: CreateMemorySearchOptions): MemorySearchPort;
/**
 * Create a provider that contributes an in-memory search port.
 */
export declare function createMemorySearchProvider(options?: MemorySearchProviderOptions): import("../providers/provider.js").ServiceProvider<unknown, import("@standard-schema/spec").StandardSchemaV1<void, void>, {
    search: SearchPort;
}, unknown, void>;
export {};
//# sourceMappingURL=index.d.ts.map