@omendb/omendb 0.0.25 → 0.0.27

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (4) hide show
  1. package/README.md +13 -10
  2. package/index.d.ts +144 -137
  3. package/index.js +53 -58
  4. package/package.json +6 -6
package/README.md CHANGED
@@ -5,7 +5,7 @@ Fast embedded vector database with HNSW indexing for Node.js and Bun.
5
5
  ## Installation
6
6
 
7
7
  ```bash
8
- npm install omendb
8
+ npm install @omendb/omendb
9
9
  ```
10
10
 
11
11
  ## Quick Start
@@ -191,28 +191,31 @@ db.setWithText([
191
191
  ]);
192
192
  ```
193
193
 
194
- #### `db.textSearch(query, k)`
194
+ #### `db.searchText(query, k)`
195
195
 
196
196
  BM25 text-only search.
197
197
 
198
198
  ```typescript
199
- const results = db.textSearch("machine learning", 10);
199
+ const results = db.searchText("machine learning", 10);
200
200
  // [{ id, score, metadata }, ...]
201
201
  ```
202
202
 
203
- #### `db.hybridSearch(options)`
203
+ #### `db.searchHybrid(queryVector, queryText, k, options?)`
204
204
 
205
- Combined vector + text search.
205
+ Combined vector + text search using Reciprocal Rank Fusion.
206
206
 
207
207
  ```typescript
208
- const results = db.hybridSearch({
209
- vector: queryVector,
210
- text: "machine learning",
211
- k: 10,
208
+ // Basic
209
+ const results = db.searchHybrid(queryVector, "machine learning", 10);
210
+
211
+ // With options
212
+ const results = db.searchHybrid(queryVector, "machine learning", 10, {
212
213
  alpha: 0.7, // 0=text only, 1=vector only (default: 0.5)
214
+ rrfK: 60, // RRF constant (default: 60)
215
+ filter: { category: "ml" },
213
216
  subscores: true, // Include separate scores
214
217
  });
215
- // [{ id, score, metadata, keyword_score?, semantic_score? }, ...]
218
+ // [{ id, score, metadata, keywordScore?, semanticScore? }, ...]
216
219
  ```
217
220
 
218
221
  ### Collections
package/index.d.ts CHANGED
@@ -1,6 +1,17 @@
1
1
  /* auto-generated by NAPI-RS */
2
2
  /* eslint-disable */
3
3
  export declare class VectorDatabase {
4
+ /**
5
+ * Get or create a named collection.
6
+ *
7
+ * Collection handles share state - changes made through one handle
8
+ * are immediately visible through another (no flush required).
9
+ */
10
+ collection(name: string, embeddingFn?: ((texts: string[]) => Float32Array[]) | undefined): VectorDatabase
11
+ /** List all collections. */
12
+ collections(): Array<string>
13
+ /** Delete a collection. */
14
+ deleteCollection(name: string): void
4
15
  /**
5
16
  * Insert or update vectors.
6
17
  *
@@ -8,48 +19,33 @@ export declare class VectorDatabase {
8
19
  * - Single-vector: items have `vector` field
9
20
  * - Multi-vector: items have `vectors` field (array of vectors)
10
21
  *
11
- * @param items - Array of {id, vector, metadata?} or {id, vectors, metadata?}
12
- * @returns Array of internal indices
13
- */
14
- set(items: Array<SetItem>): Array<number>
15
- /**
16
- * Search for k nearest neighbors.
17
- *
18
- * @param query - Query vector (number[] or Float32Array)
19
- * @param k - Number of results to return
20
- * @param ef - Optional search width override
21
- * @param filter - Optional metadata filter (e.g., {category: "foo"} or {price: {$gt: 10}})
22
- * @param maxDistance - Optional max distance threshold (filter out distant results)
23
- * @returns Array of {id, distance, metadata}
24
- */
25
- search(query: Array<number> | Float32Array, k: number, ef?: number | undefined | null, filter?: Record<string, unknown> | undefined, maxDistance?: number | undefined | null): Array<SearchResult>
26
- /**
27
- * Search multi-vector store with query tokens.
28
- *
29
- * Internal method used by unified search() for multi-vector stores.
30
- *
31
- * @param query - Query tokens (number[][] or Float32Array[])
32
- * @param k - Number of results to return
33
- * @param rerank - Enable MaxSim reranking for better quality (default: true)
34
- * @param rerankFactor - Fetch k*rerankFactor candidates before reranking (default: 32)
35
- * @returns Array of {id, distance, metadata}
36
- */
37
- searchMulti(query: Array<Array<number>> | Array<Float32Array>, k: number, rerank?: boolean | undefined | null, rerankFactor?: number | undefined | null): Array<SearchResult>
38
- /**
39
- * Batch search with parallel execution (async).
22
+ * When any item includes a `text` field, text search is automatically enabled.
23
+ * This allows immediate use of searchHybrid() without calling enableTextSearch().
40
24
  *
41
- * Runs searches in parallel using rayon on a blocking thread pool,
42
- * keeping the Node.js event loop free.
25
+ * @param items - Array of {id, vector, metadata?, text?} or {id, vectors, metadata?}
26
+ * @returns Number of vectors inserted/updated
43
27
  */
44
- searchBatch(queries: Array<Array<number> | Float32Array>, k: number, ef?: number | undefined | null): Promise<Array<Array<SearchResult>>>
28
+ set(items: Array<SetItem>): Promise<number>
45
29
  /** Get a vector by ID. */
46
30
  get(id: string): GetResult | null
47
31
  /**
48
32
  * Delete vectors by ID.
49
33
  *
34
+ * Accepts either a single ID string or an array of IDs.
35
+ *
36
+ * @param ids - Single ID string or array of IDs to delete
50
37
  * @returns Number of vectors deleted
38
+ *
39
+ * @example
40
+ * ```javascript
41
+ * // Delete single
42
+ * db.delete("doc1");
43
+ *
44
+ * // Delete multiple
45
+ * db.delete(["doc1", "doc2", "doc3"]);
46
+ * ```
51
47
  */
52
- delete(ids: Array<string>): number
48
+ delete(ids: string | Array<string>): number
53
49
  /**
54
50
  * Delete vectors matching a metadata filter.
55
51
  *
@@ -94,14 +90,36 @@ export declare class VectorDatabase {
94
90
  * ```
95
91
  */
96
92
  count(filter?: Record<string, unknown> | undefined): number
97
- /** Update a vector's data and/or metadata. */
98
- update(id: string, vector: Array<number> | Float32Array, metadata?: Record<string, unknown> | undefined): void
93
+ /**
94
+ * Update a vector's data, metadata, and/or text.
95
+ *
96
+ * @param id - Vector ID to update
97
+ * @param options - Update options: {vector?, metadata?, text?}
98
+ *
99
+ * @example
100
+ * ```javascript
101
+ * // Update vector only
102
+ * db.update("doc1", { vector: [1, 0, 0, 0] });
103
+ *
104
+ * // Update metadata only
105
+ * db.update("doc1", { metadata: { status: "active" } });
106
+ *
107
+ * // Update text (re-indexed for BM25 search)
108
+ * db.update("doc1", { text: "Updated content for search" });
109
+ *
110
+ * // Update multiple fields
111
+ * db.update("doc1", { vector: [...], metadata: {...}, text: "..." });
112
+ * ```
113
+ */
114
+ update(id: string, options: { vector?: number[] | Float32Array; metadata?: Record<string, unknown>; text?: string }): void
99
115
  /** Get number of vectors in database. */
100
116
  get length(): number
101
117
  /** Get vector dimensions of this database. */
102
118
  get dimensions(): number
103
119
  /** Check if this is a multi-vector store. */
104
120
  get isMultiVector(): boolean
121
+ /** Check if an embedding function is configured. */
122
+ get hasEmbeddingFn(): boolean
105
123
  /** Check if database is empty. */
106
124
  isEmpty(): boolean
107
125
  /** Get database statistics. */
@@ -110,61 +128,6 @@ export declare class VectorDatabase {
110
128
  get efSearch(): number
111
129
  /** Set ef_search value. */
112
130
  set efSearch(efSearch: number)
113
- /**
114
- * Get or create a named collection.
115
- *
116
- * Collection handles share state - changes made through one handle
117
- * are immediately visible through another (no flush required).
118
- */
119
- collection(name: string): VectorDatabase
120
- /** List all collections. */
121
- collections(): Array<string>
122
- /** Delete a collection. */
123
- deleteCollection(name: string): void
124
- /**
125
- * Enable text search for hybrid (vector + text) search.
126
- *
127
- * Must be called before using setWithText() or hybridSearch().
128
- */
129
- enableTextSearch(): void
130
- /** Check if text search is enabled. */
131
- get hasTextSearch(): boolean
132
- /**
133
- * Set vectors with associated text for hybrid search.
134
- *
135
- * @param items - Array of {id, vector, text, metadata?}
136
- * @returns Array of internal indices
137
- */
138
- setWithText(items: Array<VectorItemWithText>): Array<number>
139
- /**
140
- * Search using text only (BM25 scoring).
141
- *
142
- * @param query - Text query
143
- * @param k - Number of results
144
- * @returns Array of {id, score, metadata}
145
- */
146
- textSearch(query: string, k: number): Array<TextSearchResult>
147
- /**
148
- * Hybrid search combining vector similarity and text relevance.
149
- *
150
- * Uses Reciprocal Rank Fusion (RRF) to combine HNSW and BM25 results.
151
- *
152
- * @param queryVector - Query embedding
153
- * @param queryText - Text query for BM25
154
- * @param k - Number of results
155
- * @param filter - Optional metadata filter
156
- * @param alpha - Weight for vector vs text (0.0=text only, 1.0=vector only, default=0.5)
157
- * @param rrfK - RRF constant (default=60, higher reduces rank influence)
158
- * @param subscores - Return separate keyword_score and semantic_score (default: false)
159
- * @returns Array of {id, score, metadata, keyword_score?, semantic_score?}
160
- */
161
- hybridSearch(queryVector: Array<number> | Float32Array, queryText: string, k: number, filter?: Record<string, unknown> | undefined, alpha?: number | undefined | null, rrfK?: number | undefined | null, subscores?: boolean | undefined | null): Array<HybridSearchResult>
162
- /**
163
- * Flush pending changes to disk.
164
- *
165
- * For hybrid search, this commits text index changes.
166
- */
167
- flush(): void
168
131
  /**
169
132
  * Compact the database by removing deleted records and reclaiming space.
170
133
  *
@@ -235,6 +198,90 @@ export declare class VectorDatabase {
235
198
  * @returns Array of results in same order as input, null for missing IDs
236
199
  */
237
200
  getBatch(ids: Array<string>): Array<GetResult | undefined | null>
201
+ /**
202
+ * Check if text search is enabled.
203
+ *
204
+ * Text search is automatically enabled when using set() with text field.
205
+ */
206
+ get hasTextSearch(): boolean
207
+ /**
208
+ * Search using text only (BM25 scoring).
209
+ *
210
+ * @param query - Text query
211
+ * @param k - Number of results
212
+ * @returns Array of {id, score, metadata}
213
+ */
214
+ searchText(query: string, k: number): Array<TextSearchResult>
215
+ /**
216
+ * Hybrid search combining vector similarity and text relevance.
217
+ *
218
+ * Uses Reciprocal Rank Fusion (RRF) to combine HNSW and BM25 results.
219
+ *
220
+ * @param queryVector - Query embedding
221
+ * @param queryText - Text query for BM25
222
+ * @param k - Number of results
223
+ * @param options - Optional: {filter?, alpha?, rrfK?, subscores?}
224
+ * @returns Array of {id, score, metadata, keywordScore?, semanticScore?}
225
+ *
226
+ * @example
227
+ * ```javascript
228
+ * // Basic hybrid search
229
+ * db.searchHybrid([1, 0, 0, 0], "machine learning", 10);
230
+ *
231
+ * // With options
232
+ * db.searchHybrid([1, 0, 0, 0], "query", 10, {
233
+ * filter: { type: "ml" },
234
+ * alpha: 0.7,
235
+ * rrfK: 60,
236
+ * subscores: true
237
+ * });
238
+ * ```
239
+ */
240
+ searchHybrid(queryVector: Array<number> | Float32Array | string, queryText: string | undefined | null, k: number, options?: { filter?: Record<string, unknown>; alpha?: number; rrfK?: number; subscores?: boolean } | undefined): Promise<Array<HybridSearchResult>>
241
+ /**
242
+ * Flush pending changes to disk.
243
+ *
244
+ * For hybrid search, this commits text index changes.
245
+ */
246
+ flush(): void
247
+ /**
248
+ * Search for k nearest neighbors.
249
+ *
250
+ * @param query - Query vector (number[] or Float32Array)
251
+ * @param k - Number of results to return
252
+ * @param options - Optional search options: {filter?, ef?, maxDistance?}
253
+ * @returns Array of {id, distance, score, metadata}
254
+ *
255
+ * @example
256
+ * ```javascript
257
+ * // Basic search
258
+ * db.search([1, 0, 0, 0], 10);
259
+ *
260
+ * // With options
261
+ * db.search([1, 0, 0, 0], 10, { filter: { category: "A" }, ef: 200 });
262
+ * db.search([1, 0, 0, 0], 10, { maxDistance: 0.5 });
263
+ * ```
264
+ */
265
+ search(query: Array<number> | Float32Array | string, k: number, options?: { filter?: Record<string, unknown>; ef?: number; maxDistance?: number } | undefined): Promise<Array<SearchResult>>
266
+ /**
267
+ * Search multi-vector store with query tokens.
268
+ *
269
+ * Internal method used by unified search() for multi-vector stores.
270
+ *
271
+ * @param query - Query tokens (number[][] or Float32Array[])
272
+ * @param k - Number of results to return
273
+ * @param rerank - Enable MaxSim reranking for better quality (default: true)
274
+ * @param rerankFactor - Fetch k*rerankFactor candidates before reranking (default: 32)
275
+ * @returns Array of {id, distance, metadata}
276
+ */
277
+ searchMulti(query: Array<Array<number>> | Array<Float32Array>, k: number, rerank?: boolean | undefined | null, rerankFactor?: number | undefined | null): Array<SearchResult>
278
+ /**
279
+ * Batch search with parallel execution (async).
280
+ *
281
+ * Runs searches in parallel using rayon on a blocking thread pool,
282
+ * keeping the Node.js event loop free.
283
+ */
284
+ searchBatch(queries: Array<Array<number> | Float32Array>, k: number, ef?: number | undefined | null): Promise<Array<Array<SearchResult>>>
238
285
  }
239
286
 
240
287
  export interface GetResult {
@@ -253,14 +300,6 @@ export interface HybridSearchResult {
253
300
  semanticScore?: number
254
301
  }
255
302
 
256
- export interface MultiVectorItem {
257
- id: string
258
- /** Multi-vector data as array of Float32Arrays */
259
- vectors: Float32Array[]
260
- /** Optional metadata */
261
- metadata?: Record<string, unknown> | undefined
262
- }
263
-
264
303
  /**
265
304
  * Open or create a vector database.
266
305
  *
@@ -287,16 +326,9 @@ export interface MultiVectorItem {
287
326
  * quantization: true // or "sq8"
288
327
  * });
289
328
  *
290
- * // Quantization with custom rescore settings
291
- * const db = omendb.open("./mydb", {
292
- * dimensions: 128,
293
- * quantization: true,
294
- * rescore: false, // Disable rescore for max speed
295
- * oversample: 5.0 // Or increase oversample for better recall
296
- * });
297
329
  * ```
298
330
  */
299
- export declare function open(path: string, options?: OpenOptions | undefined | null): VectorDatabase
331
+ export declare function open(path: string, options?: OpenOptions | undefined | null, embeddingFn?: ((texts: string[]) => Float32Array[]) | undefined): VectorDatabase
300
332
 
301
333
  /**
302
334
  * Configuration options for opening a vector database.
@@ -306,9 +338,7 @@ export declare function open(path: string, options?: OpenOptions | undefined | n
306
338
  * - m: 16 (HNSW neighbors per node, higher = better recall, more memory)
307
339
  * - efConstruction: 100 (build quality, higher = better graph, slower build)
308
340
  * - efSearch: 100 (search quality, higher = better recall, slower search)
309
- * - quantization: null (true/"sq8" for 4x compression, ~99% recall)
310
- * - rescore: true when quantization enabled (rerank candidates with exact distance)
311
- * - oversample: 3.0 (fetch k*oversample candidates when rescoring)
341
+ * - quantization: null (true/"sq8" for 4x compression)
312
342
  * - metric: "l2" (distance metric: "l2", "euclidean", "cosine", "dot", "ip")
313
343
  */
314
344
  export interface OpenOptions {
@@ -326,16 +356,6 @@ export interface OpenOptions {
326
356
  * - false/null: Full precision (no quantization)
327
357
  */
328
358
  quantization?: boolean | string | number | null | undefined
329
- /**
330
- * Rescore candidates with exact distance (default: true when quantization enabled)
331
- * Set to false for maximum speed at the cost of ~20% recall
332
- */
333
- rescore?: boolean
334
- /**
335
- * Oversampling factor for rescoring (default: 3.0)
336
- * Fetches k*oversample candidates then reranks to return top k
337
- */
338
- oversample?: number
339
359
  /** Distance metric: "l2"/"euclidean" (default), "cosine", "dot"/"ip" */
340
360
  metric?: string
341
361
  /**
@@ -351,6 +371,8 @@ export interface OpenOptions {
351
371
  export interface SearchResult {
352
372
  id: string
353
373
  distance: number
374
+ /** Normalized similarity score (0-1, higher = more similar) */
375
+ score: number
354
376
  /** Metadata as JSON (using serde-json feature) */
355
377
  metadata: Record<string, unknown>
356
378
  }
@@ -363,7 +385,9 @@ export interface SetItem {
363
385
  vectors?: Float32Array[] | undefined
364
386
  /** Optional metadata */
365
387
  metadata?: Record<string, unknown> | undefined
366
- /** Optional document text (stored in metadata.document) */
388
+ /** Optional text for hybrid search (auto-enables text search, stored in metadata.text) */
389
+ text?: string
390
+ /** Optional document for auto-embedding via embeddingFn */
367
391
  document?: string
368
392
  }
369
393
 
@@ -378,20 +402,3 @@ export interface TextSearchResult {
378
402
  score: number
379
403
  metadata: Record<string, unknown>
380
404
  }
381
-
382
- export interface VectorItem {
383
- id: string
384
- /** Vector data as Float32Array */
385
- vector: Float32Array
386
- /** Optional metadata */
387
- metadata?: Record<string, unknown> | undefined
388
- /** Optional document text (stored in metadata.document) */
389
- document?: string
390
- }
391
-
392
- export interface VectorItemWithText {
393
- id: string
394
- vector: Float32Array
395
- text: string
396
- metadata?: Record<string, unknown> | undefined
397
- }
package/index.js CHANGED
@@ -111,6 +111,10 @@ function toFloat32Array(arr) {
111
111
 
112
112
  // Convert VectorItem to use Float32Array
113
113
  function convertVectorItem(item) {
114
+ // Items with document field are handled by native embedding
115
+ if (item.document !== undefined && item.document !== null) {
116
+ return item;
117
+ }
114
118
  if (item.vector === undefined || item.vector === null) {
115
119
  if (Array.isArray(item.vectors)) {
116
120
  throw new Error(
@@ -141,11 +145,6 @@ function convertMultiVectorItem(item) {
141
145
  };
142
146
  }
143
147
 
144
- // Check if items contain multi-vector data (vectors field must be an array)
145
- function isMultiVectorItem(item) {
146
- return Array.isArray(item.vectors);
147
- }
148
-
149
148
  // Wrap VectorDatabase to handle array conversion
150
149
  const NativeVectorDatabase = nativeBinding.VectorDatabase;
151
150
 
@@ -161,15 +160,17 @@ class VectorDatabase {
161
160
  * - Single-vector: items have `vector` field
162
161
  * - Multi-vector: items have `vectors` field (array of vectors)
163
162
  *
164
- * @param {Array<{id: string, vector?: Float32Array|number[], vectors?: Float32Array[]|number[][], metadata?: object}>} items
165
- * @returns {number[]} Array of internal indices
163
+ * When any item includes a `text` field, text search is automatically enabled.
164
+ *
165
+ * @param {Array<{id: string, vector?: Float32Array|number[], vectors?: Float32Array[]|number[][], metadata?: object, text?: string}>} items
166
+ * @returns {number} Number of vectors inserted/updated
166
167
  */
167
168
  set(items) {
168
169
  if (!Array.isArray(items)) {
169
170
  throw new Error("set() requires an array of items");
170
171
  }
171
172
  if (items.length === 0) {
172
- return [];
173
+ return 0;
173
174
  }
174
175
  // Unified set() handles both single and multi-vector via native set()
175
176
  return this._native.set(items.map(this._native.isMultiVector ? convertMultiVectorItem : convertVectorItem));
@@ -184,13 +185,8 @@ class VectorDatabase {
184
185
  *
185
186
  * @param {number[]|Float32Array|number[][]|Float32Array[]} query - Query vector(s)
186
187
  * @param {number} k - Number of results to return
187
- * @param {object} [options] - Search options
188
- * @param {number} [options.ef] - Search width override (single-vector only)
189
- * @param {object} [options.filter] - Metadata filter (single-vector only)
190
- * @param {number} [options.maxDistance] - Max distance threshold (single-vector only)
191
- * @param {boolean} [options.rerank] - Enable MaxSim reranking (multi-vector, default: true)
192
- * @param {number} [options.rerankFactor] - Rerank candidate multiplier (multi-vector, default: 4)
193
- * @returns {Array<{id: string, distance: number, metadata: object}>}
188
+ * @param {object} [options] - Search options: {filter?, ef?, maxDistance?}
189
+ * @returns {Array<{id: string, distance: number, score: number, metadata: object}>}
194
190
  */
195
191
  search(query, k, options) {
196
192
  if (this._native.isMultiVector) {
@@ -199,23 +195,8 @@ class VectorDatabase {
199
195
  const rerankFactor = options?.rerankFactor;
200
196
  return this._native.searchMulti(query, k, rerank, rerankFactor);
201
197
  } else {
202
- // Single-vector store - support both old positional args and new options object
203
- if (typeof options === "object" && options !== null && !Array.isArray(options)) {
204
- // New options object style
205
- return this._native.search(
206
- query,
207
- k,
208
- options.ef,
209
- options.filter,
210
- options.maxDistance,
211
- );
212
- } else {
213
- // Legacy positional args: search(query, k, ef, filter, maxDistance)
214
- const ef = options; // 3rd arg was ef in old API
215
- const filter = arguments[3];
216
- const maxDistance = arguments[4];
217
- return this._native.search(query, k, ef, filter, maxDistance);
218
- }
198
+ // Single-vector store - pass options object directly to native
199
+ return this._native.search(query, k, options);
219
200
  }
220
201
  }
221
202
 
@@ -239,8 +220,14 @@ class VectorDatabase {
239
220
  return this._native.count(filter);
240
221
  }
241
222
 
242
- update(id, vector, metadata) {
243
- return this._native.update(id, vector, metadata);
223
+ /**
224
+ * Update a vector's data, metadata, and/or text.
225
+ *
226
+ * @param {string} id - Vector ID to update
227
+ * @param {object} options - Update options: {vector?, metadata?, text?}
228
+ */
229
+ update(id, options) {
230
+ return this._native.update(id, options);
244
231
  }
245
232
 
246
233
  get length() {
@@ -255,6 +242,10 @@ class VectorDatabase {
255
242
  return this._native.isMultiVector;
256
243
  }
257
244
 
245
+ get hasEmbeddingFn() {
246
+ return this._native.hasEmbeddingFn;
247
+ }
248
+
258
249
  isEmpty() {
259
250
  return this._native.isEmpty();
260
251
  }
@@ -271,8 +262,8 @@ class VectorDatabase {
271
262
  this._native.efSearch = value;
272
263
  }
273
264
 
274
- collection(name) {
275
- return new VectorDatabase(this._native.collection(name));
265
+ collection(name, embeddingFn) {
266
+ return new VectorDatabase(this._native.collection(name, embeddingFn));
276
267
  }
277
268
 
278
269
  collections() {
@@ -283,32 +274,32 @@ class VectorDatabase {
283
274
  return this._native.deleteCollection(name);
284
275
  }
285
276
 
286
- enableTextSearch() {
287
- return this._native.enableTextSearch();
288
- }
289
-
290
277
  get hasTextSearch() {
291
278
  return this._native.hasTextSearch;
292
279
  }
293
280
 
294
- setWithText(items) {
295
- return this._native.setWithText(items.map(convertVectorItem));
296
- }
297
-
298
- textSearch(query, k) {
299
- return this._native.textSearch(query, k);
281
+ /**
282
+ * Search using text only (BM25 scoring).
283
+ *
284
+ * @param {string} query - Text query
285
+ * @param {number} k - Number of results
286
+ * @returns {Array<{id: string, score: number, metadata: object}>}
287
+ */
288
+ searchText(query, k) {
289
+ return this._native.searchText(query, k);
300
290
  }
301
291
 
302
- hybridSearch(queryVector, queryText, k, filter, alpha, rrfK, subscores) {
303
- return this._native.hybridSearch(
304
- queryVector,
305
- queryText,
306
- k,
307
- filter,
308
- alpha,
309
- rrfK,
310
- subscores,
311
- );
292
+ /**
293
+ * Hybrid search combining vector similarity and text relevance.
294
+ *
295
+ * @param {number[]|Float32Array} queryVector - Query embedding
296
+ * @param {string} queryText - Text query for BM25
297
+ * @param {number} k - Number of results
298
+ * @param {object} [options] - Options: {filter?, alpha?, rrfK?, subscores?}
299
+ * @returns {Array<{id: string, score: number, metadata: object, keywordScore?: number, semanticScore?: number}>}
300
+ */
301
+ searchHybrid(queryVector, queryText, k, options) {
302
+ return this._native.searchHybrid(queryVector, queryText, k, options);
312
303
  }
313
304
 
314
305
  flush() {
@@ -342,10 +333,14 @@ class VectorDatabase {
342
333
  getBatch(ids) {
343
334
  return this._native.getBatch(ids);
344
335
  }
336
+
337
+ compact() {
338
+ return this._native.compact();
339
+ }
345
340
  }
346
341
 
347
- function open(path, options) {
348
- return new VectorDatabase(nativeBinding.open(path, options));
342
+ function open(path, options, embeddingFn) {
343
+ return new VectorDatabase(nativeBinding.open(path, options, embeddingFn));
349
344
  }
350
345
 
351
346
  module.exports.VectorDatabase = VectorDatabase;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@omendb/omendb",
3
- "version": "0.0.25",
3
+ "version": "0.0.27",
4
4
  "description": "Fast embedded vector database with HNSW + ACORN-1 filtered search",
5
5
  "main": "index.js",
6
6
  "types": "index.d.ts",
@@ -50,10 +50,10 @@
50
50
  "omendb.node"
51
51
  ],
52
52
  "optionalDependencies": {
53
- "@omendb/omendb-darwin-x64": "0.0.25",
54
- "@omendb/omendb-darwin-arm64": "0.0.25",
55
- "@omendb/omendb-linux-x64-gnu": "0.0.25",
56
- "@omendb/omendb-linux-arm64-gnu": "0.0.25",
57
- "@omendb/omendb-win32-x64-msvc": "0.0.25"
53
+ "@omendb/omendb-darwin-x64": "0.0.27",
54
+ "@omendb/omendb-darwin-arm64": "0.0.27",
55
+ "@omendb/omendb-linux-x64-gnu": "0.0.27",
56
+ "@omendb/omendb-linux-arm64-gnu": "0.0.27",
57
+ "@omendb/omendb-win32-x64-msvc": "0.0.27"
58
58
  }
59
59
  }