@samveys/search
Searchable models on FTS5, tsvector or FULLTEXT, with an outbox for index updates
This list was read from version 1.0.2; run pnpm sync to refresh it.
import { databaseSearchDriver, searchable, terms } from '@samveys/search'
Function (3)
databaseSearchDriver
Function
The built-in `database` driver, one shadow table per index: - SQLite: an FTS5 virtual table ranked with `bm25()` and field weights (built into `node:sqlite`); - PostgreSQL: a `tsvector` column with `setweight()` per field, a GIN index, `ts_rank`; - MySQL / MariaDB: a `FULLTEXT` index per field, scores combined with the field weights. Filters are plain columns. Every query uses bindings; the text is reduced to words first.
function databaseSearchDriver(database: () => Database): SearchDriver;
Exported from packages/search/src/database-driver.ts
searchable
Function
Makes a model searchable. Index updates go through an outbox table: `queue()` writes the update in the same transaction as the model, `flushOutbox()` applies it. A crash after commit therefore never leaves the index behind; a rollback never indexes a row that does not exist.
function searchable<M extends ModelCtor>(model: M, options: SearchableOptions<keyof InstanceType<M> & string>, setup: SearchableSetup): Searchable<M>;
Exported from packages/search/src/searchable.ts
terms
Function
Words of the query: letters and digits only, so no engine sees query syntax from users.
function terms(text: string): string[];
Exported from packages/search/src/database-driver.ts
Interface (11)
Searchable
Interface
What `searchable(Model, options)` returns.
interface Searchable<M extends ModelCtor> {
readonly model: M;
readonly index: SearchIndexDefinition;
search(text: string): SearchBuilder<InstanceType<M>>;
/**
* Records an index update in the outbox (`samveys_search_outbox`). Pass the transaction that
* saved the model, so the update commits with the data and is never lost (#3).
*/
queue(record: InstanceType<M>, operation: 'upsert' | 'remove', client?: Pick<Database, 'from' | 'rawQuery' | 'dialect'>): Promise<void>;
/** Applies pending outbox rows for this model. Idempotent; safe to run from several workers. */
…
Show the whole declaration (16 lines)
interface Searchable<M extends ModelCtor> {
readonly model: M;
readonly index: SearchIndexDefinition;
search(text: string): SearchBuilder<InstanceType<M>>;
/**
* Records an index update in the outbox (`samveys_search_outbox`). Pass the transaction that
* saved the model, so the update commits with the data and is never lost (#3).
*/
queue(record: InstanceType<M>, operation: 'upsert' | 'remove', client?: Pick<Database, 'from' | 'rawQuery' | 'dialect'>): Promise<void>;
/** Applies pending outbox rows for this model. Idempotent; safe to run from several workers. */
…interface Searchable<M extends ModelCtor> {
readonly model: M;
readonly index: SearchIndexDefinition;
search(text: string): SearchBuilder<InstanceType<M>>;
/**
* Records an index update in the outbox (`samveys_search_outbox`). Pass the transaction that
* saved the model, so the update commits with the data and is never lost (#3).
*/
queue(record: InstanceType<M>, operation: 'upsert' | 'remove', client?: Pick<Database, 'from' | 'rawQuery' | 'dialect'>): Promise<void>;
/** Applies pending outbox rows for this model. Idempotent; safe to run from several workers. */
flushOutbox(): Promise<number>;
/** Rebuilds the whole index from the table (`svs search:import`). */
importAll(chunkSize?: number): Promise<number>;
/** Clears the index (`svs search:flush`). */
clear(): Promise<void>;
}
Exported from packages/search/src/contracts.ts
SearchableOptions
Interface
No documentation comment.
interface SearchableOptions<A extends string = string> {
/** Text attributes to index, with weights. */
readonly fields: Readonly<Partial<Record<A, SearchField>>>;
/** Attributes that `where()` can filter on (stored in the index, exact match). */
readonly filters?: readonly A[];
}
Exported from packages/search/src/contracts.ts
SearchableSetup
Interface
No documentation comment.
interface SearchableSetup {
readonly driver: SearchDriver;
/** The database that holds the outbox and the model table. */
readonly database: () => Database;
Exported from packages/search/src/searchable.ts
SearchBuilder
Interface
No documentation comment.
interface SearchBuilder<I> {
where(filter: string, value: DbValue): SearchBuilder<I>;
paginate(page: number, perPage: number): Promise<SearchPage<I>>;
get(limit?: number): Promise<readonly I[]>;
}
Exported from packages/search/src/contracts.ts
SearchDocument
Interface
One indexed record, as handed to a driver.
interface SearchDocument {
readonly id: string;
/** Field name → text. */
readonly fields: Readonly<Record<string, string>>;
/** Filter name → value. */
readonly filters: Readonly<Record<string, DbValue>>;
}
Exported from packages/search/src/contracts.ts
SearchDriver
Interface
A search backend. Third-party drivers implement this and pass `@samveys/search/conformance`.
interface SearchDriver {
readonly name: string;
/** Creates the index if it does not exist. Idempotent. */
ensureIndex(index: SearchIndexDefinition): Promise<void>;
/** Inserts or replaces documents. */
upsert(index: SearchIndexDefinition, documents: readonly SearchDocument[]): Promise<void>;
remove(index: SearchIndexDefinition, ids: readonly string[]): Promise<void>;
/** Removes every document of the index. */
flush(index: SearchIndexDefinition): Promise<void>;
search(index: SearchIndexDefinition, query: SearchQuery): Promise<SearchHits>;
}
Exported from packages/search/src/contracts.ts
SearchField
Interface
Public types of `@samveys/search`. Locked once written: change with an ADR.
interface SearchField {
/** Relative importance; default 1. */
readonly weight?: number;
}
Exported from packages/search/src/contracts.ts
SearchHits
Interface
No documentation comment.
interface SearchHits {
/** Record ids, best match first. */
readonly ids: readonly string[];
readonly total: number;
}
Exported from packages/search/src/contracts.ts
SearchIndexDefinition
Interface
No documentation comment.
interface SearchIndexDefinition {
/** Index name, e.g. `reports`. */
readonly name: string;
readonly fields: Readonly<Record<string, {
readonly weight: number;
}>>;
readonly filters: readonly string[];
}
Exported from packages/search/src/contracts.ts
SearchPage
Interface
Result page of `Model.search(...).paginate()`.
interface SearchPage<I> {
readonly data: readonly I[];
readonly page: number;
readonly perPage: number;
readonly total: number;
}
Exported from packages/search/src/contracts.ts
SearchQuery
Interface
No documentation comment.
interface SearchQuery {
readonly text: string;
readonly filters: Readonly<Record<string, DbValue>>;
readonly limit: number;
readonly offset: number;
}
Exported from packages/search/src/contracts.ts