taladb 0.1.2 → 0.2.0

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.
package/dist/index.d.mts CHANGED
@@ -1,3 +1,21 @@
1
+ /** Similarity metric used for vector search. */
2
+ type VectorMetric = 'cosine' | 'dot' | 'euclidean';
3
+ interface VectorIndexOptions {
4
+ /** Number of dimensions in each stored vector. Enforced on insert and search. */
5
+ dimensions: number;
6
+ /** Similarity metric. Defaults to `"cosine"`. */
7
+ metric?: VectorMetric;
8
+ }
9
+ /** A single result returned by `Collection.findNearest`. */
10
+ interface VectorSearchResult<T extends Document = Document> {
11
+ /** The matched document. */
12
+ document: T;
13
+ /**
14
+ * Similarity score — higher means more similar.
15
+ * Range depends on metric: cosine ∈ [-1,1], dot ∈ ℝ, euclidean ∈ (0,1].
16
+ */
17
+ score: number;
18
+ }
1
19
  type Value = null | boolean | number | string | Uint8Array | Value[] | {
2
20
  [key: string]: Value;
3
21
  };
@@ -54,6 +72,36 @@ interface Collection<T extends Document = Document> {
54
72
  count(filter?: Filter<T>): Promise<number>;
55
73
  createIndex(field: keyof Omit<T, '_id'> & string): Promise<void>;
56
74
  dropIndex(field: keyof Omit<T, '_id'> & string): Promise<void>;
75
+ /**
76
+ * Create a vector index on a numeric-array field.
77
+ *
78
+ * After creation, `findNearest` can search this field and new inserts/updates
79
+ * automatically maintain the index. Existing documents are backfilled.
80
+ *
81
+ * @example
82
+ * await articles.createVectorIndex('embedding', { dimensions: 384 });
83
+ */
84
+ createVectorIndex(field: keyof Omit<T, '_id'> & string, options: VectorIndexOptions): Promise<void>;
85
+ /** Drop a vector index. */
86
+ dropVectorIndex(field: keyof Omit<T, '_id'> & string): Promise<void>;
87
+ /**
88
+ * Find the `topK` most similar documents to `vector` using a vector index.
89
+ *
90
+ * Optionally combine with a metadata `filter` to restrict the search space
91
+ * before ranking — e.g. find the 5 most similar english-language articles.
92
+ *
93
+ * Results are ordered by descending similarity score (highest first).
94
+ *
95
+ * @example
96
+ * const results = await articles.findNearest('embedding', queryVec, 5);
97
+ * // results: Array<{ document: Article, score: number }>
98
+ *
99
+ * @example with pre-filter
100
+ * const results = await articles.findNearest('embedding', queryVec, 5, {
101
+ * locale: 'en',
102
+ * });
103
+ */
104
+ findNearest(field: keyof Omit<T, '_id'> & string, vector: number[], topK: number, filter?: Filter<T>): Promise<VectorSearchResult<T>[]>;
57
105
  /**
58
106
  * Subscribe to live query results. The callback receives a full snapshot of
59
107
  * matching documents immediately and again after every write that could
@@ -88,4 +136,4 @@ interface TalaDB {
88
136
  */
89
137
  declare function openDB(dbName?: string): Promise<TalaDB>;
90
138
 
91
- export { type Collection, type Document, type Filter, type TalaDB, type Update, type Value, openDB };
139
+ export { type Collection, type Document, type Filter, type TalaDB, type Update, type Value, type VectorIndexOptions, type VectorMetric, type VectorSearchResult, openDB };
package/dist/index.d.ts CHANGED
@@ -1,3 +1,21 @@
1
+ /** Similarity metric used for vector search. */
2
+ type VectorMetric = 'cosine' | 'dot' | 'euclidean';
3
+ interface VectorIndexOptions {
4
+ /** Number of dimensions in each stored vector. Enforced on insert and search. */
5
+ dimensions: number;
6
+ /** Similarity metric. Defaults to `"cosine"`. */
7
+ metric?: VectorMetric;
8
+ }
9
+ /** A single result returned by `Collection.findNearest`. */
10
+ interface VectorSearchResult<T extends Document = Document> {
11
+ /** The matched document. */
12
+ document: T;
13
+ /**
14
+ * Similarity score — higher means more similar.
15
+ * Range depends on metric: cosine ∈ [-1,1], dot ∈ ℝ, euclidean ∈ (0,1].
16
+ */
17
+ score: number;
18
+ }
1
19
  type Value = null | boolean | number | string | Uint8Array | Value[] | {
2
20
  [key: string]: Value;
3
21
  };
@@ -54,6 +72,36 @@ interface Collection<T extends Document = Document> {
54
72
  count(filter?: Filter<T>): Promise<number>;
55
73
  createIndex(field: keyof Omit<T, '_id'> & string): Promise<void>;
56
74
  dropIndex(field: keyof Omit<T, '_id'> & string): Promise<void>;
75
+ /**
76
+ * Create a vector index on a numeric-array field.
77
+ *
78
+ * After creation, `findNearest` can search this field and new inserts/updates
79
+ * automatically maintain the index. Existing documents are backfilled.
80
+ *
81
+ * @example
82
+ * await articles.createVectorIndex('embedding', { dimensions: 384 });
83
+ */
84
+ createVectorIndex(field: keyof Omit<T, '_id'> & string, options: VectorIndexOptions): Promise<void>;
85
+ /** Drop a vector index. */
86
+ dropVectorIndex(field: keyof Omit<T, '_id'> & string): Promise<void>;
87
+ /**
88
+ * Find the `topK` most similar documents to `vector` using a vector index.
89
+ *
90
+ * Optionally combine with a metadata `filter` to restrict the search space
91
+ * before ranking — e.g. find the 5 most similar english-language articles.
92
+ *
93
+ * Results are ordered by descending similarity score (highest first).
94
+ *
95
+ * @example
96
+ * const results = await articles.findNearest('embedding', queryVec, 5);
97
+ * // results: Array<{ document: Article, score: number }>
98
+ *
99
+ * @example with pre-filter
100
+ * const results = await articles.findNearest('embedding', queryVec, 5, {
101
+ * locale: 'en',
102
+ * });
103
+ */
104
+ findNearest(field: keyof Omit<T, '_id'> & string, vector: number[], topK: number, filter?: Filter<T>): Promise<VectorSearchResult<T>[]>;
57
105
  /**
58
106
  * Subscribe to live query results. The callback receives a full snapshot of
59
107
  * matching documents immediately and again after every write that could
@@ -88,4 +136,4 @@ interface TalaDB {
88
136
  */
89
137
  declare function openDB(dbName?: string): Promise<TalaDB>;
90
138
 
91
- export { type Collection, type Document, type Filter, type TalaDB, type Update, type Value, openDB };
139
+ export { type Collection, type Document, type Filter, type TalaDB, type Update, type Value, type VectorIndexOptions, type VectorMetric, type VectorSearchResult, openDB };
package/dist/index.js CHANGED
@@ -89,6 +89,12 @@ async function createInMemoryBrowserDB(_dbName) {
89
89
  count: async (filter) => col.count(filter ?? null),
90
90
  createIndex: async (field) => col.createIndex(field),
91
91
  dropIndex: async (field) => col.dropIndex(field),
92
+ createVectorIndex: async (field, options) => col.createVectorIndex(field, options.dimensions, options.metric ?? null),
93
+ dropVectorIndex: async (field) => col.dropVectorIndex(field),
94
+ findNearest: async (field, vector, topK, filter) => {
95
+ const raw = await col.findNearest(field, vector, topK, filter ?? null);
96
+ return raw;
97
+ },
92
98
  subscribe: (filter, callback) => {
93
99
  let active = true;
94
100
  let lastJson = "";
@@ -169,6 +175,23 @@ async function createBrowserDB(dbName) {
169
175
  }),
170
176
  createIndex: (field) => proxy.send("createIndex", { collection: name, field }),
171
177
  dropIndex: (field) => proxy.send("dropIndex", { collection: name, field }),
178
+ createVectorIndex: (field, options) => proxy.send("createVectorIndex", {
179
+ collection: name,
180
+ field,
181
+ dimensions: options.dimensions,
182
+ metric: options.metric
183
+ }),
184
+ dropVectorIndex: (field) => proxy.send("dropVectorIndex", { collection: name, field }),
185
+ findNearest: async (field, vector, topK, filter) => {
186
+ const json = await proxy.send("findNearest", {
187
+ collection: name,
188
+ field,
189
+ queryJson: JSON.stringify(vector),
190
+ topK,
191
+ filterJson: filter ? JSON.stringify(filter) : "null"
192
+ });
193
+ return JSON.parse(json);
194
+ },
172
195
  subscribe: (filter, callback) => {
173
196
  let active = true;
174
197
  let lastJson = "";
@@ -216,6 +239,12 @@ async function createNodeDB(dbName) {
216
239
  count: async (filter) => col.count(filter ?? null),
217
240
  createIndex: async (field) => col.createIndex(field),
218
241
  dropIndex: async (field) => col.dropIndex(field),
242
+ createVectorIndex: async (field, options) => col.createVectorIndex(field, options.dimensions, options.metric ?? null),
243
+ dropVectorIndex: async (field) => col.dropVectorIndex(field),
244
+ findNearest: async (field, vector, topK, filter) => {
245
+ const raw = await col.findNearest(field, vector, topK, filter ?? null);
246
+ return raw;
247
+ },
219
248
  subscribe: (filter, callback) => {
220
249
  let active = true;
221
250
  let lastJson = "";
@@ -267,6 +296,12 @@ async function createNativeDB(_dbName) {
267
296
  count: async (filter) => col.count(filter ?? {}),
268
297
  createIndex: async (field) => col.createIndex(field),
269
298
  dropIndex: async (field) => col.dropIndex(field),
299
+ createVectorIndex: async (field, options) => col.createVectorIndex(field, options.dimensions, options.metric ?? null),
300
+ dropVectorIndex: async (field) => col.dropVectorIndex(field),
301
+ findNearest: async (field, vector, topK, filter) => {
302
+ const raw = col.findNearest(field, vector, topK, filter ?? null);
303
+ return raw;
304
+ },
270
305
  subscribe: (filter, callback) => {
271
306
  let active = true;
272
307
  let lastJson = "";
package/dist/index.mjs CHANGED
@@ -54,6 +54,12 @@ async function createInMemoryBrowserDB(_dbName) {
54
54
  count: async (filter) => col.count(filter ?? null),
55
55
  createIndex: async (field) => col.createIndex(field),
56
56
  dropIndex: async (field) => col.dropIndex(field),
57
+ createVectorIndex: async (field, options) => col.createVectorIndex(field, options.dimensions, options.metric ?? null),
58
+ dropVectorIndex: async (field) => col.dropVectorIndex(field),
59
+ findNearest: async (field, vector, topK, filter) => {
60
+ const raw = await col.findNearest(field, vector, topK, filter ?? null);
61
+ return raw;
62
+ },
57
63
  subscribe: (filter, callback) => {
58
64
  let active = true;
59
65
  let lastJson = "";
@@ -134,6 +140,23 @@ async function createBrowserDB(dbName) {
134
140
  }),
135
141
  createIndex: (field) => proxy.send("createIndex", { collection: name, field }),
136
142
  dropIndex: (field) => proxy.send("dropIndex", { collection: name, field }),
143
+ createVectorIndex: (field, options) => proxy.send("createVectorIndex", {
144
+ collection: name,
145
+ field,
146
+ dimensions: options.dimensions,
147
+ metric: options.metric
148
+ }),
149
+ dropVectorIndex: (field) => proxy.send("dropVectorIndex", { collection: name, field }),
150
+ findNearest: async (field, vector, topK, filter) => {
151
+ const json = await proxy.send("findNearest", {
152
+ collection: name,
153
+ field,
154
+ queryJson: JSON.stringify(vector),
155
+ topK,
156
+ filterJson: filter ? JSON.stringify(filter) : "null"
157
+ });
158
+ return JSON.parse(json);
159
+ },
137
160
  subscribe: (filter, callback) => {
138
161
  let active = true;
139
162
  let lastJson = "";
@@ -181,6 +204,12 @@ async function createNodeDB(dbName) {
181
204
  count: async (filter) => col.count(filter ?? null),
182
205
  createIndex: async (field) => col.createIndex(field),
183
206
  dropIndex: async (field) => col.dropIndex(field),
207
+ createVectorIndex: async (field, options) => col.createVectorIndex(field, options.dimensions, options.metric ?? null),
208
+ dropVectorIndex: async (field) => col.dropVectorIndex(field),
209
+ findNearest: async (field, vector, topK, filter) => {
210
+ const raw = await col.findNearest(field, vector, topK, filter ?? null);
211
+ return raw;
212
+ },
184
213
  subscribe: (filter, callback) => {
185
214
  let active = true;
186
215
  let lastJson = "";
@@ -232,6 +261,12 @@ async function createNativeDB(_dbName) {
232
261
  count: async (filter) => col.count(filter ?? {}),
233
262
  createIndex: async (field) => col.createIndex(field),
234
263
  dropIndex: async (field) => col.dropIndex(field),
264
+ createVectorIndex: async (field, options) => col.createVectorIndex(field, options.dimensions, options.metric ?? null),
265
+ dropVectorIndex: async (field) => col.dropVectorIndex(field),
266
+ findNearest: async (field, vector, topK, filter) => {
267
+ const raw = col.findNearest(field, vector, topK, filter ?? null);
268
+ return raw;
269
+ },
235
270
  subscribe: (filter, callback) => {
236
271
  let active = true;
237
272
  let lastJson = "";
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "taladb",
3
- "version": "0.1.2",
4
- "description": "Local-first document database for React, React Native, and Node.js",
3
+ "version": "0.2.0",
4
+ "description": "Local-first document and vector database for React, React Native, and Node.js",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",
7
7
  "types": "dist/index.d.ts",
@@ -21,7 +21,13 @@
21
21
  "local-first",
22
22
  "offline",
23
23
  "wasm",
24
- "react-native"
24
+ "react-native",
25
+ "vector",
26
+ "vector-search",
27
+ "embeddings",
28
+ "semantic-search",
29
+ "ai",
30
+ "hybrid-search"
25
31
  ],
26
32
  "license": "MIT",
27
33
  "repository": {
@@ -42,8 +48,8 @@
42
48
  "vitest": "^3.2.0"
43
49
  },
44
50
  "optionalDependencies": {
45
- "@taladb/web": "0.1.2",
46
- "@taladb/node": "0.1.2"
51
+ "@taladb/web": "0.2.0",
52
+ "@taladb/node": "0.2.0"
47
53
  },
48
54
  "scripts": {
49
55
  "build": "tsup src/index.ts --format cjs,esm --dts --out-dir dist --external @taladb/web --external @taladb/node --external @taladb/react-native",