@goatlab/typesense
Version:
Modern TypeScript wrapper for Typesense search engine API
457 lines (456 loc) • 12.9 kB
TypeScript
import type { Primitive } from '@goatlab/js-utils';
/**
* Enhanced error class for Typesense API errors with rate limit and response details
*/
export declare class TypesenseError extends Error {
readonly status: number;
readonly statusText: string;
readonly response?: any;
readonly rateLimitRemaining?: number;
readonly rateLimitReset?: Date;
readonly retryAfter?: number;
readonly rateLimitLimit?: number;
constructor(message: string, status: number, response?: any, headers?: Record<string, string>);
/**
* Check if this error is due to rate limiting
*/
isRateLimited(): boolean;
/**
* Get the time until rate limit reset (in milliseconds)
*/
getTimeUntilReset(): number | null;
}
export type TypesenseFieldType = 'string' | 'string[]' | 'int32' | 'int32[]' | 'int64' | 'int64[]' | 'float' | 'float[]' | 'bool' | 'bool[]' | 'geopoint' | 'geopoint[]' | 'string*' | 'auto' | 'object' | 'object[]';
export interface TypesenseCollectionField {
name: string;
type: TypesenseFieldType;
optional?: boolean;
facet?: boolean;
infix?: boolean;
sort?: boolean;
num_dim?: number;
vec_dist?: 'cosine' | 'ip' | 'l2';
store?: boolean;
schema?: TypesenseCollectionField[];
}
export interface TypesenseCollection {
name: string;
alias?: string;
fields: TypesenseCollectionField[];
default_sorting_field?: string;
symbols_to_index?: string[];
enable_nested_fields?: boolean;
}
export type TypesenseCollectionOutput = TypesenseCollection & {
num_documents: number;
};
export type TypesenseDocument<T extends Record<string, any> = Record<string, any>> = {
id: string | number;
} & T;
/**
* Constraint to ensure documents have required id field
*/
export type WithRequiredId<T> = T & {
id: string | number;
};
export interface TypesenseDocumentGeneric {
[key: string]: Primitive | Primitive[];
id: string | number;
}
export interface TypesenseQuery {
q: string;
/**
* String[] should be separated by comma
*/
query_by: string;
filter_by?: string;
prefix?: string;
infix?: string;
split_join_tokens?: string;
pre_segmented_query?: string;
facet_by?: string;
max_facet_values?: number;
facet_query?: string;
facet_query_num_typos?: number;
/**
* Pagination - NOTE: Cannot be used with vector_query
*/
page?: number;
per_page?: number;
group_by?: string;
group_limit?: number;
/**
* Results
*/
include_fields?: string;
exclude_fields?: string;
highlight_fields?: string;
highlight_full_fields?: string;
highlight_affix_num_tokens?: number;
highlight_start_tag?: string;
highlight_end_tag?: string;
vector_query?: string;
text_matches?: number;
vector_weight?: number;
preset?: string;
}
/**
* Type-safe vector search query (cannot use pagination)
*/
export interface TypesenseVectorQuery extends Omit<TypesenseQuery, 'page' | 'per_page'> {
vector_query: string;
vector_weight?: number;
text_matches?: number;
}
/**
* Type-safe text search query (can use pagination)
*/
export interface TypesenseTextQuery extends TypesenseQuery {
vector_query?: never;
vector_weight?: never;
}
export interface TypesenseQueryResults<T> {
facet_counts: [];
found: number;
out_of: number;
page: number;
request_params: {
collection_name: string;
per_page: number;
q: string;
};
search_time_ms: number;
hits: {
document: TypesenseDocument<T>;
text_match: number;
highlights: {
field: string;
snippet: string;
matched_tokens: string[];
}[];
}[];
}
export interface TypesenseImportOptions {
/**
* The import operation to perform
* - create: Fails if a document with the same id already exists
* - upsert: Creates a new document or updates an existing document if one with the same id already exists
* - update: Updates an existing document. Fails if the document doesn't exist
* - emplace: Creates a new document if one with the same id doesn't exist. Does nothing if the document already exists
* @default 'create'
*/
action?: 'create' | 'upsert' | 'update' | 'emplace';
/**
* Number of documents to send in each batch
* @default 40
*/
batch_size?: number;
/**
* If set to true, the response will contain the id of the imported documents
* @default false
*/
return_id?: boolean;
/**
* If set to true, the response will contain the actual imported documents
* @default false
*/
return_doc?: boolean;
/**
* If set to true, skips indexing and stores the documents directly on disk. Indexing is done in background.
* Useful when you have a large number of documents to import and want to reduce memory usage during import.
* @default false
*/
dirty_values?: 'coerce_or_reject' | 'coerce_or_drop' | 'drop' | 'reject';
/**
* The format of the import data
* @default 'jsonl'
*/
format?: TypesenseImportFormat;
}
export interface TypesenseImportResult {
success: boolean;
error?: string;
document?: any;
id?: string | number;
}
export interface TypesenseExportOptions {
/**
* Filter documents by a condition. Uses the same syntax as search filter_by
*/
filter_by?: string;
/**
* List of fields to include in the exported documents
*/
include_fields?: string;
/**
* List of fields to exclude from the exported documents
*/
exclude_fields?: string;
/**
* Compression format for the export
*/
compression?: 'gzip' | 'none';
/**
* Collection override for multi-tenancy
*/
collection?: string;
}
export type TypesenseImportFormat = 'jsonl' | 'json' | 'csv';
export type TypesenseExportFormat = 'jsonl' | 'json' | 'csv';
/**
* Health check response from Typesense
*/
export interface TypesenseHealthResponse {
ok: boolean;
}
/**
* Generic response wrapper for Typesense operations with metadata
*/
export interface TypesenseResponse<T> {
/**
* The actual data returned by the operation
*/
data: T;
/**
* Operation metadata
*/
metadata: {
/**
* Time taken for the operation in milliseconds
*/
operation_time_ms?: number;
/**
* Number of documents found (for search operations)
*/
found?: number;
/**
* Total documents that match without pagination (for search operations)
*/
out_of?: number;
/**
* Search time in milliseconds (for search operations)
*/
search_time_ms?: number;
/**
* Facet counts (for search operations with facets)
*/
facet_counts?: any[];
/**
* Number of documents in collection (for collection operations)
*/
num_documents?: number;
/**
* Request parameters used (for search operations)
*/
request_params?: Record<string, any>;
/**
* Operation type for clarity
*/
operation: 'create' | 'update' | 'delete' | 'upsert' | 'get' | 'search' | 'import' | 'export';
};
}
/**
* Type guard to check if a value is a valid document ID
*/
export declare function isValidDocumentId(id: any): id is string | number;
/**
* Validates text_matches parameter against per_page
*/
export declare function validateTextMatches(textMatches: number, perPage: number): boolean;
/**
* Validates vector search parameters
*/
export declare function validateVectorQuery(query: TypesenseQuery): {
valid: boolean;
errors: string[];
};
/**
* Error thrown when client is destroyed
*/
export declare class ClientDestroyedError extends Error {
constructor();
}
export interface TypesenseMultiSearchQuery {
collection?: string;
q: string;
query_by: string;
filter_by?: string;
prefix?: string;
infix?: string;
split_join_tokens?: string;
pre_segmented_query?: string;
facet_by?: string;
max_facet_values?: number;
facet_query?: string;
facet_query_num_typos?: number;
page?: number;
per_page?: number;
group_by?: string;
group_limit?: number;
include_fields?: string;
exclude_fields?: string;
highlight_fields?: string;
highlight_full_fields?: string;
highlight_affix_num_tokens?: number;
highlight_start_tag?: string;
highlight_end_tag?: string;
}
export interface TypesenseMultiSearchRequest {
searches: TypesenseMultiSearchQuery[];
}
export interface TypesenseMultiSearchResult<T> {
results: Array<TypesenseQueryResults<T> & {
request_params: any;
}>;
}
export interface TypesenseDeleteByFilterOptions {
filter_by: string;
batch_size?: number;
}
export interface TypesenseAlias {
name: string;
collection_name: string;
}
export interface TypesenseAliasCreateRequest {
collection_name: string;
}
export interface TypesenseAliasResponse extends TypesenseAlias {
}
export interface TypesenseAliasListResponse {
aliases: TypesenseAliasResponse[];
}
export interface TypesenseCollectionStats {
collection_name: string;
num_documents: number;
created_at: number;
num_memory_shards: number;
num_documents_indexed: number;
num_documents_queued: number;
field_stats?: {
[fieldName: string]: {
num_values: number;
avg_length?: number;
min?: number;
max?: number;
};
};
}
export interface TypesenseClusterNode {
id: string;
name: string;
state: 'ALIVE' | 'UNAVAILABLE' | 'INACTIVE';
last_contact: number;
}
export interface TypesenseClusterStatus {
state: 'HEALTHY' | 'DEGRADED' | 'UNAVAILABLE';
nodes: TypesenseClusterNode[];
}
export interface TypesenseSynonym {
id?: string;
synonyms: string[];
root?: string;
}
export interface TypesenseSynonymResponse extends TypesenseSynonym {
id: string;
}
export interface TypesenseOverride {
id?: string;
rule: {
query: string;
match: 'exact' | 'contains';
};
includes?: Array<{
id: string;
position: number;
}>;
excludes?: Array<{
id: string;
}>;
filter_by?: string;
remove_matched_tokens?: boolean;
stop_processing?: boolean;
}
export interface TypesenseOverrideResponse extends TypesenseOverride {
id: string;
}
export interface TypesensePreset {
name: string;
value: {
filter_by?: string;
sort_by?: string;
facet_by?: string;
max_facet_values?: number;
group_by?: string;
group_limit?: number;
include_fields?: string;
exclude_fields?: string;
highlight_fields?: string;
};
}
export interface TypesensePresetResponse extends TypesensePreset {
}
export interface TypesenseHealth {
ok: boolean;
}
export interface TypesenseMetrics {
system_cpu_active_percentage: string;
system_disk_total_bytes: string;
system_disk_used_bytes: string;
system_memory_total_bytes: string;
system_memory_used_bytes: string;
system_network_received_bytes: string;
system_network_sent_bytes: string;
typesense_memory_active_bytes: string;
typesense_memory_allocated_bytes: string;
typesense_memory_fragmentation_ratio: string;
typesense_memory_mapped_bytes: string;
typesense_memory_metadata_bytes: string;
typesense_memory_resident_bytes: string;
typesense_memory_retained_bytes: string;
latency_ms?: Record<string, Record<string, number>>;
requests_per_second?: Record<string, number>;
}
export interface TypesenseOperation {
id: number;
name: string;
status: 'success' | 'failure' | 'processing';
resource_id?: string;
resource_type?: string;
started_at: number;
completed_at?: number;
details?: Record<string, any>;
}
export interface TypesenseApiKey {
id?: number;
value?: string;
description: string;
actions: string[];
collections: string[];
expires_at?: number;
}
export interface TypesenseApiKeyResponse extends TypesenseApiKey {
id: number;
value_prefix: string;
}
export interface TypesenseRateLimitInfo {
limit?: number;
remaining?: number;
resetMs?: number;
retryAfter?: number;
}
export interface TypesenseVectorSearchOptions {
vector_query: string;
vector_weight?: number;
text_matches?: number;
}
export interface TypesenseHybridSearchOptions {
vector_weight: number;
text_matches?: number;
}
export interface TypesenseCollectionOptions {
collection?: string;
}
export interface TypesenseSchemaCacheEntry {
schema: TypesenseCollection;
timestamp: number;
}