eigen-db 1.0.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.
@@ -0,0 +1,443 @@
1
+ import { describe, it, expect, beforeEach } from "vitest";
2
+ import { readFileSync } from "fs";
3
+ import { resolve } from "path";
4
+ import { VectorDB } from "../vector-db";
5
+ import { InMemoryStorageProvider } from "../storage";
6
+ import { VectorCapacityExceededError } from "../errors";
7
+ import { compileWatToWasm } from "../wasm-compute";
8
+
9
+ const watSource = readFileSync(resolve(__dirname, "../simd.wat"), "utf-8");
10
+
11
+ let wasmBinaryPromise: Promise<Uint8Array>;
12
+ function getWasmBinary(): Promise<Uint8Array> {
13
+ if (!wasmBinaryPromise) {
14
+ wasmBinaryPromise = compileWatToWasm(watSource);
15
+ }
16
+ return wasmBinaryPromise;
17
+ }
18
+
19
+ describe("VectorDB", () => {
20
+ let storage: InMemoryStorageProvider;
21
+
22
+ beforeEach(() => {
23
+ storage = new InMemoryStorageProvider();
24
+ });
25
+
26
+ describe("with JS compute", () => {
27
+ runTestSuite(false);
28
+ });
29
+
30
+ describe("with WASM SIMD compute", () => {
31
+ runTestSuite(true);
32
+ });
33
+
34
+ function runTestSuite(useWasm: boolean) {
35
+ let wasmBinary: Uint8Array | null;
36
+
37
+ beforeEach(async () => {
38
+ wasmBinary = useWasm ? await getWasmBinary() : null;
39
+ });
40
+
41
+ // --- open ---
42
+ it("opens with zero records", async () => {
43
+ const db = await VectorDB.open({
44
+ dimensions: 4,
45
+ storage,
46
+ wasmBinary,
47
+ });
48
+
49
+ expect(db.size).toBe(0);
50
+ });
51
+
52
+ // --- set and get ---
53
+ it("stores and retrieves a vector by key", async () => {
54
+ const db = await VectorDB.open({
55
+ dimensions: 4,
56
+ normalize: false,
57
+ storage,
58
+ wasmBinary,
59
+ });
60
+
61
+ db.set("a", new Float32Array([1, 2, 3, 4]));
62
+ expect(db.size).toBe(1);
63
+
64
+ const result = db.get("a");
65
+ expect(result).toBeDefined();
66
+ expect(result![0]).toBeCloseTo(1);
67
+ expect(result![1]).toBeCloseTo(2);
68
+ expect(result![2]).toBeCloseTo(3);
69
+ expect(result![3]).toBeCloseTo(4);
70
+ });
71
+
72
+ it("last write wins when writing different value to the same key", async () => {
73
+ const db = await VectorDB.open({
74
+ dimensions: 4,
75
+ normalize: false,
76
+ storage,
77
+ wasmBinary,
78
+ });
79
+
80
+ db.set("a", new Float32Array([1, 0, 0, 0]));
81
+ db.set("a", new Float32Array([0, 1, 0, 0]));
82
+
83
+ expect(db.size).toBe(1); // only one entry
84
+ const result = db.get("a");
85
+ expect(result![0]).toBeCloseTo(0);
86
+ expect(result![1]).toBeCloseTo(1);
87
+ });
88
+
89
+ it("last write wins with multiple overwrites", async () => {
90
+ const db = await VectorDB.open({
91
+ dimensions: 4,
92
+ normalize: false,
93
+ storage,
94
+ wasmBinary,
95
+ });
96
+
97
+ db.set("key1", new Float32Array([1, 0, 0, 0]));
98
+ db.set("key1", new Float32Array([0, 1, 0, 0]));
99
+ db.set("key1", new Float32Array([0, 0, 1, 0]));
100
+
101
+ expect(db.size).toBe(1);
102
+ const result = db.get("key1");
103
+ expect(result![2]).toBeCloseTo(1);
104
+ });
105
+
106
+ it("returns undefined for non-existent key", async () => {
107
+ const db = await VectorDB.open({
108
+ dimensions: 4,
109
+ storage,
110
+ wasmBinary,
111
+ });
112
+
113
+ expect(db.get("nonexistent")).toBeUndefined();
114
+ });
115
+
116
+ it("validates vector dimensions on set", async () => {
117
+ const db = await VectorDB.open({
118
+ dimensions: 4,
119
+ storage,
120
+ wasmBinary,
121
+ });
122
+
123
+ expect(() => db.set("a", new Float32Array(8))).toThrow("dimension mismatch");
124
+ });
125
+
126
+ // --- setMany and getMany ---
127
+ it("stores and retrieves multiple entries with setMany/getMany", async () => {
128
+ const db = await VectorDB.open({
129
+ dimensions: 4,
130
+ normalize: false,
131
+ storage,
132
+ wasmBinary,
133
+ });
134
+
135
+ db.setMany([
136
+ ["a", new Float32Array([1, 0, 0, 0])],
137
+ ["b", new Float32Array([0, 1, 0, 0])],
138
+ ["c", new Float32Array([0, 0, 1, 0])],
139
+ ]);
140
+
141
+ expect(db.size).toBe(3);
142
+
143
+ const results = db.getMany(["a", "b", "c", "d"]);
144
+ expect(results[0]![0]).toBeCloseTo(1);
145
+ expect(results[1]![1]).toBeCloseTo(1);
146
+ expect(results[2]![2]).toBeCloseTo(1);
147
+ expect(results[3]).toBeUndefined();
148
+ });
149
+
150
+ it("setMany with duplicate keys in batch uses last value", async () => {
151
+ const db = await VectorDB.open({
152
+ dimensions: 4,
153
+ normalize: false,
154
+ storage,
155
+ wasmBinary,
156
+ });
157
+
158
+ db.setMany([
159
+ ["x", new Float32Array([1, 0, 0, 0])],
160
+ ["x", new Float32Array([0, 0, 0, 1])],
161
+ ]);
162
+
163
+ expect(db.size).toBe(1);
164
+ const result = db.get("x");
165
+ expect(result![3]).toBeCloseTo(1);
166
+ });
167
+
168
+ // --- query ---
169
+ it("query returns ranked results by similarity", async () => {
170
+ const db = await VectorDB.open({
171
+ dimensions: 4,
172
+ storage,
173
+ wasmBinary,
174
+ });
175
+
176
+ db.set("x-axis", new Float32Array([1, 0, 0, 0]));
177
+ db.set("y-axis", new Float32Array([0, 1, 0, 0]));
178
+ db.set("xy-axis", new Float32Array([1, 1, 0, 0]));
179
+
180
+ const results = db.query(new Float32Array([1, 0, 0, 0]));
181
+ expect(results.length).toBe(3);
182
+
183
+ // x-axis should be the best match (identical direction)
184
+ expect(results.get(0).key).toBe("x-axis");
185
+ expect(results.get(0).score).toBeCloseTo(1.0, 2);
186
+
187
+ // xy-axis should be second (partially aligned)
188
+ expect(results.get(1).key).toBe("xy-axis");
189
+ expect(results.get(1).score).toBeGreaterThan(0);
190
+
191
+ // y-axis should be last (orthogonal)
192
+ expect(results.get(2).key).toBe("y-axis");
193
+ expect(results.get(2).score).toBeCloseTo(0.0, 2);
194
+ });
195
+
196
+ it("query respects topK option", async () => {
197
+ const db = await VectorDB.open({
198
+ dimensions: 4,
199
+ storage,
200
+ wasmBinary,
201
+ });
202
+
203
+ db.set("a", new Float32Array([1, 0, 0, 0]));
204
+ db.set("b", new Float32Array([0, 1, 0, 0]));
205
+ db.set("c", new Float32Array([0, 0, 1, 0]));
206
+
207
+ const results = db.query(new Float32Array([1, 0, 0, 0]), { topK: 2 });
208
+ expect(results.length).toBe(2);
209
+ });
210
+
211
+ it("query on empty database returns empty result", async () => {
212
+ const db = await VectorDB.open({
213
+ dimensions: 4,
214
+ storage,
215
+ wasmBinary,
216
+ });
217
+
218
+ const results = db.query(new Float32Array([1, 0, 0, 0]));
219
+ expect(results.length).toBe(0);
220
+ });
221
+
222
+ it("query validates vector dimensions", async () => {
223
+ const db = await VectorDB.open({
224
+ dimensions: 4,
225
+ storage,
226
+ wasmBinary,
227
+ });
228
+
229
+ db.set("a", new Float32Array([1, 0, 0, 0]));
230
+ expect(() => db.query(new Float32Array(8))).toThrow("dimension mismatch");
231
+ });
232
+
233
+ it("query results support pagination", async () => {
234
+ const db = await VectorDB.open({
235
+ dimensions: 4,
236
+ normalize: false,
237
+ storage,
238
+ wasmBinary,
239
+ });
240
+
241
+ for (let i = 0; i < 5; i++) {
242
+ const vec = new Float32Array(4);
243
+ vec[0] = 1 - i * 0.2;
244
+ db.set(`t${i}`, vec);
245
+ }
246
+
247
+ const results = db.query(new Float32Array([1, 0, 0, 0]), { normalize: false });
248
+
249
+ const page0 = results.getPage(0, 2);
250
+ expect(page0).toHaveLength(2);
251
+
252
+ const page1 = results.getPage(1, 2);
253
+ expect(page1).toHaveLength(2);
254
+
255
+ const page2 = results.getPage(2, 2);
256
+ expect(page2).toHaveLength(1);
257
+ });
258
+
259
+ it("query after overwrite uses updated vector", async () => {
260
+ const db = await VectorDB.open({
261
+ dimensions: 4,
262
+ storage,
263
+ wasmBinary,
264
+ });
265
+
266
+ db.set("point", new Float32Array([1, 0, 0, 0]));
267
+ db.set("other", new Float32Array([0, 1, 0, 0]));
268
+
269
+ // Overwrite 'point' to be along y-axis
270
+ db.set("point", new Float32Array([0, 1, 0, 0]));
271
+
272
+ const results = db.query(new Float32Array([0, 1, 0, 0]));
273
+ // Both 'point' and 'other' are now along y-axis, so both should score high
274
+ expect(results.get(0).score).toBeCloseTo(1.0, 2);
275
+ expect(results.get(1).score).toBeCloseTo(1.0, 2);
276
+ expect(db.size).toBe(2);
277
+ });
278
+
279
+ // --- flush and persistence ---
280
+ it("flush persists data and reopen loads it", async () => {
281
+ const db1 = await VectorDB.open({
282
+ dimensions: 4,
283
+ normalize: false,
284
+ storage,
285
+ wasmBinary,
286
+ });
287
+
288
+ db1.set("alpha", new Float32Array([1, 0, 0, 0]));
289
+ db1.set("beta", new Float32Array([0, 1, 0, 0]));
290
+ await db1.flush();
291
+
292
+ // Reopen same storage
293
+ const db2 = await VectorDB.open({
294
+ dimensions: 4,
295
+ normalize: false,
296
+ storage,
297
+ wasmBinary,
298
+ });
299
+
300
+ expect(db2.size).toBe(2);
301
+ expect(db2.get("alpha")![0]).toBeCloseTo(1);
302
+ expect(db2.get("beta")![1]).toBeCloseTo(1);
303
+ });
304
+
305
+ it("flush persists overwritten values correctly", async () => {
306
+ const db1 = await VectorDB.open({
307
+ dimensions: 4,
308
+ normalize: false,
309
+ storage,
310
+ wasmBinary,
311
+ });
312
+
313
+ db1.set("key", new Float32Array([1, 0, 0, 0]));
314
+ db1.set("key", new Float32Array([0, 0, 0, 1]));
315
+ await db1.flush();
316
+
317
+ const db2 = await VectorDB.open({
318
+ dimensions: 4,
319
+ normalize: false,
320
+ storage,
321
+ wasmBinary,
322
+ });
323
+
324
+ expect(db2.size).toBe(1);
325
+ expect(db2.get("key")![3]).toBeCloseTo(1);
326
+ });
327
+
328
+ // --- close ---
329
+ it("close flushes and prevents further operations", async () => {
330
+ const db = await VectorDB.open({
331
+ dimensions: 4,
332
+ normalize: false,
333
+ storage,
334
+ wasmBinary,
335
+ });
336
+
337
+ db.set("a", new Float32Array([1, 0, 0, 0]));
338
+ await db.close();
339
+
340
+ // Should be persisted
341
+ const db2 = await VectorDB.open({
342
+ dimensions: 4,
343
+ normalize: false,
344
+ storage,
345
+ wasmBinary,
346
+ });
347
+ expect(db2.size).toBe(1);
348
+
349
+ // Original instance should be closed
350
+ expect(() => db.set("b", new Float32Array(4))).toThrow("closed");
351
+ });
352
+
353
+ it("close is idempotent", async () => {
354
+ const db = await VectorDB.open({
355
+ dimensions: 4,
356
+ storage,
357
+ wasmBinary,
358
+ });
359
+
360
+ await db.close();
361
+ await db.close(); // should not throw
362
+ });
363
+
364
+ // --- clear ---
365
+ it("clear removes all data", async () => {
366
+ const db = await VectorDB.open({
367
+ dimensions: 4,
368
+ storage,
369
+ wasmBinary,
370
+ });
371
+
372
+ db.set("a", new Float32Array([1, 0, 0, 0]));
373
+ db.set("b", new Float32Array([0, 1, 0, 0]));
374
+ expect(db.size).toBe(2);
375
+
376
+ await db.clear();
377
+ expect(db.size).toBe(0);
378
+ expect(db.get("a")).toBeUndefined();
379
+ });
380
+
381
+ it("clear allows reuse of the database", async () => {
382
+ const db = await VectorDB.open({
383
+ dimensions: 4,
384
+ normalize: false,
385
+ storage,
386
+ wasmBinary,
387
+ });
388
+
389
+ db.set("old", new Float32Array([1, 0, 0, 0]));
390
+ await db.clear();
391
+
392
+ db.set("new", new Float32Array([0, 1, 0, 0]));
393
+ expect(db.size).toBe(1);
394
+ expect(db.get("new")![1]).toBeCloseTo(1);
395
+ });
396
+
397
+ // --- normalization ---
398
+ it("normalizes vectors by default", async () => {
399
+ const db = await VectorDB.open({
400
+ dimensions: 4,
401
+ storage,
402
+ wasmBinary,
403
+ });
404
+
405
+ db.set("a", new Float32Array([3, 0, 0, 0]));
406
+ const result = db.get("a");
407
+ // Should be normalized to unit length
408
+ expect(result![0]).toBeCloseTo(1.0);
409
+ });
410
+
411
+ it("skips normalization when normalize is false", async () => {
412
+ const db = await VectorDB.open({
413
+ dimensions: 4,
414
+ normalize: false,
415
+ storage,
416
+ wasmBinary,
417
+ });
418
+
419
+ db.set("a", new Float32Array([3, 0, 0, 0]));
420
+ const result = db.get("a");
421
+ expect(result![0]).toBeCloseTo(3.0);
422
+ });
423
+
424
+ it("per-call normalize option overrides default", async () => {
425
+ const db = await VectorDB.open({
426
+ dimensions: 4,
427
+ normalize: false,
428
+ storage,
429
+ wasmBinary,
430
+ });
431
+
432
+ db.set("a", new Float32Array([3, 0, 0, 0]), { normalize: true });
433
+ const result = db.get("a");
434
+ expect(result![0]).toBeCloseTo(1.0);
435
+ });
436
+ }
437
+
438
+ it("throws VectorCapacityExceededError when full", async () => {
439
+ const err = new VectorCapacityExceededError(100);
440
+ expect(err).toBeInstanceOf(VectorCapacityExceededError);
441
+ expect(err.message).toContain("100");
442
+ });
443
+ });
@@ -0,0 +1,152 @@
1
+ import { describe, it, expect, beforeAll } from "vitest";
2
+ import { readFileSync } from "fs";
3
+ import { resolve } from "path";
4
+ import { compileWatToWasm, instantiateWasm, type WasmExports } from "../wasm-compute";
5
+
6
+ describe("WASM SIMD compute", () => {
7
+ let memory: WebAssembly.Memory;
8
+ let wasm: WasmExports;
9
+
10
+ beforeAll(async () => {
11
+ const watSource = readFileSync(resolve(__dirname, "../simd.wat"), "utf-8");
12
+ const wasmBinary = await compileWatToWasm(watSource);
13
+ memory = new WebAssembly.Memory({ initial: 1 }); // 64KB
14
+ wasm = await instantiateWasm(wasmBinary, memory);
15
+ });
16
+
17
+ function writeFloat32Array(offset: number, data: Float32Array): void {
18
+ new Float32Array(memory.buffer, offset, data.length).set(data);
19
+ }
20
+
21
+ function readFloat32Array(offset: number, length: number): Float32Array {
22
+ return new Float32Array(memory.buffer.slice(offset, offset + length * 4));
23
+ }
24
+
25
+ describe("normalize", () => {
26
+ it("normalizes a vector to unit length", () => {
27
+ const vec = new Float32Array([3, 4, 0, 0]);
28
+ const ptr = 0;
29
+ writeFloat32Array(ptr, vec);
30
+
31
+ wasm.normalize(ptr, 4);
32
+
33
+ const result = readFloat32Array(ptr, 4);
34
+ const mag = Math.sqrt(result[0] ** 2 + result[1] ** 2 + result[2] ** 2 + result[3] ** 2);
35
+ expect(mag).toBeCloseTo(1.0, 4);
36
+ expect(result[0]).toBeCloseTo(0.6, 4);
37
+ expect(result[1]).toBeCloseTo(0.8, 4);
38
+ });
39
+
40
+ it("normalizes a non-multiple-of-4 dimension vector", () => {
41
+ const vec = new Float32Array([1, 2, 3]);
42
+ const ptr = 0;
43
+ writeFloat32Array(ptr, vec);
44
+
45
+ wasm.normalize(ptr, 3);
46
+
47
+ const result = readFloat32Array(ptr, 3);
48
+ let sumSq = 0;
49
+ for (let i = 0; i < 3; i++) sumSq += result[i] * result[i];
50
+ expect(Math.sqrt(sumSq)).toBeCloseTo(1.0, 4);
51
+ });
52
+
53
+ it("handles zero vector", () => {
54
+ const vec = new Float32Array([0, 0, 0, 0]);
55
+ const ptr = 0;
56
+ writeFloat32Array(ptr, vec);
57
+
58
+ wasm.normalize(ptr, 4);
59
+
60
+ const result = readFloat32Array(ptr, 4);
61
+ expect(result[0]).toBe(0);
62
+ expect(result[1]).toBe(0);
63
+ });
64
+ });
65
+
66
+ describe("search_all", () => {
67
+ it("computes dot products correctly", () => {
68
+ const dimensions = 4;
69
+ const dbSize = 2;
70
+ const queryPtr = 0;
71
+ const dbPtr = dimensions * 4; // after query
72
+ const scoresPtr = dbPtr + dbSize * dimensions * 4; // after db
73
+
74
+ const query = new Float32Array([1, 0, 0, 0]);
75
+ const db = new Float32Array([
76
+ 1, 0, 0, 0, // identical to query
77
+ 0, 1, 0, 0, // orthogonal
78
+ ]);
79
+
80
+ writeFloat32Array(queryPtr, query);
81
+ writeFloat32Array(dbPtr, db);
82
+
83
+ wasm.search_all(queryPtr, dbPtr, scoresPtr, dbSize, dimensions);
84
+
85
+ const scores = readFloat32Array(scoresPtr, dbSize);
86
+ expect(scores[0]).toBeCloseTo(1.0, 4);
87
+ expect(scores[1]).toBeCloseTo(0.0, 4);
88
+ });
89
+
90
+ it("computes correct scores for normalized vectors", () => {
91
+ const dimensions = 4;
92
+ const dbSize = 3;
93
+ const queryPtr = 0;
94
+ const dbPtr = dimensions * 4;
95
+ const scoresPtr = dbPtr + dbSize * dimensions * 4;
96
+
97
+ // Create and normalize vectors manually
98
+ const q = new Float32Array([1, 2, 3, 0]);
99
+ const mag = Math.sqrt(q[0] ** 2 + q[1] ** 2 + q[2] ** 2);
100
+ for (let i = 0; i < 3; i++) q[i] /= mag;
101
+
102
+ const v1 = new Float32Array([1, 2, 3, 0]); // same direction
103
+ const v1mag = Math.sqrt(14);
104
+ for (let i = 0; i < 3; i++) v1[i] /= v1mag;
105
+
106
+ const v2 = new Float32Array([-1, -2, -3, 0]); // opposite
107
+ for (let i = 0; i < 3; i++) v2[i] /= v1mag;
108
+
109
+ const v3 = new Float32Array([0, 0, 0, 1]); // orthogonal
110
+
111
+ writeFloat32Array(queryPtr, q);
112
+ writeFloat32Array(dbPtr, new Float32Array([...v1, ...v2, ...v3]));
113
+
114
+ wasm.search_all(queryPtr, dbPtr, scoresPtr, dbSize, dimensions);
115
+
116
+ const scores = readFloat32Array(scoresPtr, dbSize);
117
+ expect(scores[0]).toBeCloseTo(1.0, 3); // same direction
118
+ expect(scores[1]).toBeCloseTo(-1.0, 3); // opposite
119
+ expect(scores[2]).toBeCloseTo(0.0, 3); // orthogonal
120
+ });
121
+
122
+ it("handles non-multiple-of-4 dimensions", () => {
123
+ const dimensions = 3;
124
+ const dbSize = 1;
125
+ const queryPtr = 0;
126
+ const dbPtr = 16; // aligned
127
+ const scoresPtr = dbPtr + dbSize * dimensions * 4 + 4; // extra space
128
+
129
+ const query = new Float32Array([1, 0, 0]);
130
+ const db = new Float32Array([0.5, 0.5, 0]);
131
+
132
+ writeFloat32Array(queryPtr, query);
133
+ writeFloat32Array(dbPtr, db);
134
+
135
+ wasm.search_all(queryPtr, dbPtr, scoresPtr, dbSize, dimensions);
136
+
137
+ const scores = readFloat32Array(scoresPtr, dbSize);
138
+ expect(scores[0]).toBeCloseTo(0.5, 4);
139
+ });
140
+
141
+ it("handles empty database", () => {
142
+ const queryPtr = 0;
143
+ const dbPtr = 16;
144
+ const scoresPtr = 32;
145
+
146
+ writeFloat32Array(queryPtr, new Float32Array([1, 0, 0, 0]));
147
+
148
+ // Should not crash with dbSize=0
149
+ wasm.search_all(queryPtr, dbPtr, scoresPtr, 0, 4);
150
+ });
151
+ });
152
+ });
@@ -0,0 +1,48 @@
1
+ /**
2
+ * Pure JavaScript compute functions for vector operations.
3
+ * These serve as the reference implementation and fallback when WASM SIMD is unavailable.
4
+ */
5
+
6
+ /**
7
+ * Normalizes a vector in-place to unit length.
8
+ * After normalization, cosine similarity reduces to a simple dot product.
9
+ */
10
+ export function normalize(vec: Float32Array): void {
11
+ let sumSq = 0;
12
+ for (let i = 0; i < vec.length; i++) {
13
+ sumSq += vec[i] * vec[i];
14
+ }
15
+ const mag = Math.sqrt(sumSq);
16
+ if (mag === 0) return;
17
+ const invMag = 1 / mag;
18
+ for (let i = 0; i < vec.length; i++) {
19
+ vec[i] *= invMag;
20
+ }
21
+ }
22
+
23
+ /**
24
+ * Computes dot products of query against all vectors in the database.
25
+ * Writes scores to the output array.
26
+ *
27
+ * @param query - Normalized query vector (length = dimensions)
28
+ * @param db - Contiguous flat array of normalized vectors (length = dbSize * dimensions)
29
+ * @param scores - Output array for dot product scores (length = dbSize)
30
+ * @param dbSize - Number of vectors in the database
31
+ * @param dimensions - Dimensionality of each vector
32
+ */
33
+ export function searchAll(
34
+ query: Float32Array,
35
+ db: Float32Array,
36
+ scores: Float32Array,
37
+ dbSize: number,
38
+ dimensions: number,
39
+ ): void {
40
+ for (let i = 0; i < dbSize; i++) {
41
+ let dot = 0;
42
+ const offset = i * dimensions;
43
+ for (let j = 0; j < dimensions; j++) {
44
+ dot += query[j] * db[offset + j];
45
+ }
46
+ scores[i] = dot;
47
+ }
48
+ }
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Thrown when the database exceeds the 4GB WebAssembly 32-bit memory limit,
3
+ * or the browser's available RAM.
4
+ */
5
+ export class VectorCapacityExceededError extends Error {
6
+ constructor(maxVectors: number) {
7
+ super(`Capacity exceeded. Max vectors for this dimension size is ~${maxVectors}.`);
8
+ this.name = "VectorCapacityExceededError";
9
+ }
10
+ }
@@ -0,0 +1,14 @@
1
+ /**
2
+ * web-vector-base: In-Browser Vector Compute Engine
3
+ *
4
+ * High-performance vector search entirely on the client side,
5
+ * utilizing OPFS for persistent storage and WASM SIMD for computation.
6
+ */
7
+
8
+ export { VectorDB } from "./vector-db";
9
+ export { ResultSet } from "./result-set";
10
+ export type { ResultItem } from "./result-set";
11
+ export { VectorCapacityExceededError } from "./errors";
12
+ export type { OpenOptions, OpenOptionsInternal, SetOptions, QueryOptions } from "./types";
13
+ export { InMemoryStorageProvider, OPFSStorageProvider } from "./storage";
14
+ export type { StorageProvider } from "./storage";