@beignet/core
Version:
Core framework primitives for Beignet
176 lines • 5.95 kB
TypeScript
/**
* @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