@brainwires/idbvec 0.1.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/README.md +207 -0
- package/package.json +28 -0
- package/wrapper.d.ts +87 -0
- package/wrapper.js +195 -0
package/README.md
ADDED
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
# idbvec - Vector Database (WASM + IndexedDB)
|
|
2
|
+
|
|
3
|
+
A high-performance client-side vector database built with Rust/WebAssembly and IndexedDB for persistence.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- **🚀 WASM-Accelerated**: Near-native performance for vector operations
|
|
8
|
+
- **💾 Persistent**: Automatic IndexedDB persistence
|
|
9
|
+
- **🎯 ANN Search**: HNSW (Hierarchical Navigable Small World) index for approximate nearest neighbor search
|
|
10
|
+
- **📊 Distance Metrics**: Cosine similarity, Euclidean distance, dot product
|
|
11
|
+
- **🔧 Type-Safe**: Full TypeScript support
|
|
12
|
+
- **📦 Zero Dependencies**: Self-contained WASM module
|
|
13
|
+
|
|
14
|
+
## Architecture
|
|
15
|
+
|
|
16
|
+
```
|
|
17
|
+
┌─────────────────────────────────┐
|
|
18
|
+
│ TypeScript API (wrapper.ts) │
|
|
19
|
+
├─────────────────────────────────┤
|
|
20
|
+
│ WASM Module (Rust) │
|
|
21
|
+
│ - HNSW Index │
|
|
22
|
+
│ - Distance Metrics │
|
|
23
|
+
│ - Vector Operations │
|
|
24
|
+
├─────────────────────────────────┤
|
|
25
|
+
│ IndexedDB Storage │
|
|
26
|
+
│ - Persistent State │
|
|
27
|
+
│ - Automatic Serialization │
|
|
28
|
+
└─────────────────────────────────┘
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## Building
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
# Install wasm-pack (if not already installed)
|
|
35
|
+
cargo install wasm-pack
|
|
36
|
+
|
|
37
|
+
# Build WASM modules
|
|
38
|
+
./build-wasm.sh
|
|
39
|
+
|
|
40
|
+
# Outputs:
|
|
41
|
+
# - pkg/bundler (for webpack/rollup/vite)
|
|
42
|
+
# - pkg/nodejs (for Node.js)
|
|
43
|
+
# - pkg/web (for ES modules)
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
## Usage
|
|
47
|
+
|
|
48
|
+
### Basic Example
|
|
49
|
+
|
|
50
|
+
```typescript
|
|
51
|
+
import { VectorDatabase } from './wrapper'
|
|
52
|
+
|
|
53
|
+
// Create database
|
|
54
|
+
const db = new VectorDatabase({
|
|
55
|
+
name: 'my-vectors',
|
|
56
|
+
dimensions: 384, // e.g., for all-MiniLM-L6-v2 embeddings
|
|
57
|
+
m: 16, // max connections per layer
|
|
58
|
+
efConstruction: 200, // construction quality
|
|
59
|
+
})
|
|
60
|
+
|
|
61
|
+
// Initialize
|
|
62
|
+
await db.init()
|
|
63
|
+
|
|
64
|
+
// Insert vectors
|
|
65
|
+
await db.insert(
|
|
66
|
+
'doc1',
|
|
67
|
+
new Float32Array([0.1, 0.2, 0.3, ...]),
|
|
68
|
+
{ title: 'Document 1', category: 'tech' }
|
|
69
|
+
)
|
|
70
|
+
|
|
71
|
+
// Search
|
|
72
|
+
const results = await db.search(
|
|
73
|
+
queryVector,
|
|
74
|
+
{ k: 5, ef: 50 }
|
|
75
|
+
)
|
|
76
|
+
|
|
77
|
+
console.log(results)
|
|
78
|
+
// [
|
|
79
|
+
// { id: 'doc1', score: 0.95, metadata: { title: 'Document 1', ... } },
|
|
80
|
+
// ...
|
|
81
|
+
// ]
|
|
82
|
+
|
|
83
|
+
// Delete
|
|
84
|
+
await db.delete('doc1')
|
|
85
|
+
|
|
86
|
+
// Close
|
|
87
|
+
db.close()
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
### Batch Insert
|
|
91
|
+
|
|
92
|
+
```typescript
|
|
93
|
+
const records = [
|
|
94
|
+
{ id: 'vec1', vector: new Float32Array([...]), metadata: { ... } },
|
|
95
|
+
{ id: 'vec2', vector: new Float32Array([...]), metadata: { ... } },
|
|
96
|
+
// ...
|
|
97
|
+
]
|
|
98
|
+
|
|
99
|
+
await db.insertBatch(records)
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
### Distance Functions
|
|
103
|
+
|
|
104
|
+
```typescript
|
|
105
|
+
import { cosineSimilarity, euclideanDistance, dotProduct } from './wrapper'
|
|
106
|
+
|
|
107
|
+
const a = new Float32Array([1, 0, 0])
|
|
108
|
+
const b = new Float32Array([0, 1, 0])
|
|
109
|
+
|
|
110
|
+
const similarity = await cosineSimilarity(a, b) // 0.0
|
|
111
|
+
const distance = await euclideanDistance(a, b) // 1.414...
|
|
112
|
+
const dot = await dotProduct(a, b) // 0.0
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
## Configuration
|
|
116
|
+
|
|
117
|
+
### VectorDBConfig
|
|
118
|
+
|
|
119
|
+
| Parameter | Type | Default | Description |
|
|
120
|
+
|-----------|------|---------|-------------|
|
|
121
|
+
| `name` | string | - | Database name (IndexedDB key) |
|
|
122
|
+
| `dimensions` | number | - | Vector dimensionality |
|
|
123
|
+
| `m` | number | 16 | Max connections per layer (higher = better recall, more memory) |
|
|
124
|
+
| `efConstruction` | number | 200 | Construction quality (higher = better index, slower insert) |
|
|
125
|
+
|
|
126
|
+
### Search Options
|
|
127
|
+
|
|
128
|
+
| Parameter | Type | Default | Description |
|
|
129
|
+
|-----------|------|---------|-------------|
|
|
130
|
+
| `k` | number | 10 | Number of nearest neighbors to return |
|
|
131
|
+
| `ef` | number | 50 | Search quality (higher = better recall, slower search) |
|
|
132
|
+
|
|
133
|
+
## HNSW Parameters Guide
|
|
134
|
+
|
|
135
|
+
### M (Max Connections)
|
|
136
|
+
- **8-12**: Low memory, faster search, lower recall
|
|
137
|
+
- **16-32**: Balanced (recommended)
|
|
138
|
+
- **32+**: High recall, more memory
|
|
139
|
+
|
|
140
|
+
### ef_construction
|
|
141
|
+
- **100**: Fast build, lower quality
|
|
142
|
+
- **200**: Balanced (recommended)
|
|
143
|
+
- **400+**: Slow build, high quality
|
|
144
|
+
|
|
145
|
+
### ef (search)
|
|
146
|
+
- **k**: Minimum (fast, lower recall)
|
|
147
|
+
- **k * 2-5**: Balanced
|
|
148
|
+
- **k * 10+**: High recall (slower)
|
|
149
|
+
|
|
150
|
+
## Performance
|
|
151
|
+
|
|
152
|
+
Typical performance on modern hardware:
|
|
153
|
+
|
|
154
|
+
- **Insert**: ~1-10ms per vector (depends on ef_construction)
|
|
155
|
+
- **Search**: ~1-5ms for k=10 (depends on ef and database size)
|
|
156
|
+
- **Memory**: ~(dimensions * 4 + M * 8) bytes per vector
|
|
157
|
+
|
|
158
|
+
## Integration with Next.js
|
|
159
|
+
|
|
160
|
+
1. Copy WASM build to `public/`:
|
|
161
|
+
|
|
162
|
+
```bash
|
|
163
|
+
cp -r rust/idbvec/pkg/bundler public/idbvec-wasm
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
2. Use in a client component:
|
|
167
|
+
|
|
168
|
+
```tsx
|
|
169
|
+
'use client'
|
|
170
|
+
|
|
171
|
+
import { VectorDatabase } from '@/rust/idbvec/wrapper'
|
|
172
|
+
import { useEffect, useState } from 'react'
|
|
173
|
+
|
|
174
|
+
export function VectorSearch() {
|
|
175
|
+
const [db, setDb] = useState<VectorDatabase | null>(null)
|
|
176
|
+
|
|
177
|
+
useEffect(() => {
|
|
178
|
+
const initDB = async () => {
|
|
179
|
+
const vectorDB = new VectorDatabase({
|
|
180
|
+
name: 'app-vectors',
|
|
181
|
+
dimensions: 384,
|
|
182
|
+
})
|
|
183
|
+
await vectorDB.init()
|
|
184
|
+
setDb(vectorDB)
|
|
185
|
+
}
|
|
186
|
+
initDB()
|
|
187
|
+
}, [])
|
|
188
|
+
|
|
189
|
+
// Use db for search, insert, etc.
|
|
190
|
+
}
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
## Browser Compatibility
|
|
194
|
+
|
|
195
|
+
- ✅ Chrome 90+
|
|
196
|
+
- ✅ Firefox 88+
|
|
197
|
+
- ✅ Safari 15+
|
|
198
|
+
- ✅ Edge 90+
|
|
199
|
+
|
|
200
|
+
Requires:
|
|
201
|
+
- WebAssembly support
|
|
202
|
+
- IndexedDB support
|
|
203
|
+
- ES modules
|
|
204
|
+
|
|
205
|
+
## License
|
|
206
|
+
|
|
207
|
+
MIT OR Apache-2.0
|
package/package.json
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@brainwires/idbvec",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Client-side vector database built on IndexedDB with WASM",
|
|
5
|
+
"main": "wrapper.js",
|
|
6
|
+
"types": "wrapper.d.ts",
|
|
7
|
+
"files": [
|
|
8
|
+
"wrapper.js",
|
|
9
|
+
"wrapper.d.ts",
|
|
10
|
+
"pkg/bundler/"
|
|
11
|
+
],
|
|
12
|
+
"keywords": [
|
|
13
|
+
"vector",
|
|
14
|
+
"database",
|
|
15
|
+
"wasm",
|
|
16
|
+
"indexeddb",
|
|
17
|
+
"hnsw",
|
|
18
|
+
"ann"
|
|
19
|
+
],
|
|
20
|
+
"license": "MIT OR Apache-2.0",
|
|
21
|
+
"repository": {
|
|
22
|
+
"type": "git",
|
|
23
|
+
"url": "https://github.com/Brainwires/idbvec.git"
|
|
24
|
+
},
|
|
25
|
+
"devDependencies": {
|
|
26
|
+
"typescript": "^5.9.3"
|
|
27
|
+
}
|
|
28
|
+
}
|
package/wrapper.d.ts
ADDED
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TypeScript wrapper for Vector Database with IndexedDB persistence
|
|
3
|
+
*
|
|
4
|
+
* This provides a high-level API for vector operations with:
|
|
5
|
+
* - WASM-accelerated similarity search
|
|
6
|
+
* - IndexedDB persistence
|
|
7
|
+
* - Automatic serialization/deserialization
|
|
8
|
+
*/
|
|
9
|
+
export interface SearchResult {
|
|
10
|
+
id: string;
|
|
11
|
+
score: number;
|
|
12
|
+
metadata?: Record<string, string>;
|
|
13
|
+
}
|
|
14
|
+
export interface VectorRecord {
|
|
15
|
+
id: string;
|
|
16
|
+
vector: Float32Array;
|
|
17
|
+
metadata?: Record<string, string>;
|
|
18
|
+
}
|
|
19
|
+
export interface SearchOptions {
|
|
20
|
+
k?: number;
|
|
21
|
+
ef?: number;
|
|
22
|
+
}
|
|
23
|
+
export interface VectorDBConfig {
|
|
24
|
+
name: string;
|
|
25
|
+
dimensions: number;
|
|
26
|
+
m?: number;
|
|
27
|
+
efConstruction?: number;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Vector Database with IndexedDB persistence
|
|
31
|
+
*/
|
|
32
|
+
export declare class VectorDatabase {
|
|
33
|
+
private wasmDB;
|
|
34
|
+
private idb;
|
|
35
|
+
private config;
|
|
36
|
+
constructor(config: VectorDBConfig);
|
|
37
|
+
/**
|
|
38
|
+
* Initialize the database (load WASM + IndexedDB)
|
|
39
|
+
*/
|
|
40
|
+
init(): Promise<void>;
|
|
41
|
+
/**
|
|
42
|
+
* Insert a vector into the database
|
|
43
|
+
*/
|
|
44
|
+
insert(id: string, vector: Float32Array, metadata?: Record<string, string>): Promise<void>;
|
|
45
|
+
/**
|
|
46
|
+
* Batch insert multiple vectors
|
|
47
|
+
*/
|
|
48
|
+
insertBatch(records: VectorRecord[]): Promise<void>;
|
|
49
|
+
/**
|
|
50
|
+
* Search for nearest neighbors
|
|
51
|
+
*/
|
|
52
|
+
search(query: Float32Array, options?: SearchOptions): Promise<SearchResult[]>;
|
|
53
|
+
/**
|
|
54
|
+
* Delete a vector by ID
|
|
55
|
+
*/
|
|
56
|
+
delete(id: string): Promise<boolean>;
|
|
57
|
+
/**
|
|
58
|
+
* Get total number of vectors
|
|
59
|
+
*/
|
|
60
|
+
size(): number;
|
|
61
|
+
/**
|
|
62
|
+
* Clear all data
|
|
63
|
+
*/
|
|
64
|
+
clear(): Promise<void>;
|
|
65
|
+
/**
|
|
66
|
+
* Open IndexedDB connection
|
|
67
|
+
*/
|
|
68
|
+
private openIndexedDB;
|
|
69
|
+
/**
|
|
70
|
+
* Save WASM state to IndexedDB
|
|
71
|
+
*/
|
|
72
|
+
private saveToIndexedDB;
|
|
73
|
+
/**
|
|
74
|
+
* Load WASM state from IndexedDB
|
|
75
|
+
*/
|
|
76
|
+
private loadFromIndexedDB;
|
|
77
|
+
/**
|
|
78
|
+
* Close the database
|
|
79
|
+
*/
|
|
80
|
+
close(): void;
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Standalone distance functions
|
|
84
|
+
*/
|
|
85
|
+
export declare function cosineSimilarity(a: Float32Array, b: Float32Array): Promise<number>;
|
|
86
|
+
export declare function euclideanDistance(a: Float32Array, b: Float32Array): Promise<number>;
|
|
87
|
+
export declare function dotProduct(a: Float32Array, b: Float32Array): Promise<number>;
|
package/wrapper.js
ADDED
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TypeScript wrapper for Vector Database with IndexedDB persistence
|
|
3
|
+
*
|
|
4
|
+
* This provides a high-level API for vector operations with:
|
|
5
|
+
* - WASM-accelerated similarity search
|
|
6
|
+
* - IndexedDB persistence
|
|
7
|
+
* - Automatic serialization/deserialization
|
|
8
|
+
*/
|
|
9
|
+
/**
|
|
10
|
+
* Vector Database with IndexedDB persistence
|
|
11
|
+
*/
|
|
12
|
+
export class VectorDatabase {
|
|
13
|
+
wasmDB = null;
|
|
14
|
+
idb = null;
|
|
15
|
+
config;
|
|
16
|
+
constructor(config) {
|
|
17
|
+
this.config = {
|
|
18
|
+
name: config.name,
|
|
19
|
+
dimensions: config.dimensions,
|
|
20
|
+
m: config.m ?? 16,
|
|
21
|
+
efConstruction: config.efConstruction ?? 200,
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Initialize the database (load WASM + IndexedDB)
|
|
26
|
+
*/
|
|
27
|
+
async init() {
|
|
28
|
+
// Load WASM module (auto-initializes on import for bundler target)
|
|
29
|
+
const wasmModule = await import('./pkg/bundler/idbvec');
|
|
30
|
+
// Open IndexedDB
|
|
31
|
+
this.idb = await this.openIndexedDB();
|
|
32
|
+
// Try to restore from IndexedDB
|
|
33
|
+
const saved = await this.loadFromIndexedDB();
|
|
34
|
+
if (saved) {
|
|
35
|
+
this.wasmDB = wasmModule.VectorDB.deserialize(saved);
|
|
36
|
+
// console.log('Restored VectorDB from IndexedDB')
|
|
37
|
+
}
|
|
38
|
+
else {
|
|
39
|
+
this.wasmDB = new wasmModule.VectorDB(this.config.dimensions, this.config.m, this.config.efConstruction);
|
|
40
|
+
// console.log('Created new VectorDB')
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Insert a vector into the database
|
|
45
|
+
*/
|
|
46
|
+
async insert(id, vector, metadata) {
|
|
47
|
+
if (!this.wasmDB)
|
|
48
|
+
throw new Error('Database not initialized');
|
|
49
|
+
this.wasmDB.insert(id, vector, metadata ?? null);
|
|
50
|
+
// Persist to IndexedDB
|
|
51
|
+
await this.saveToIndexedDB();
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Batch insert multiple vectors
|
|
55
|
+
*/
|
|
56
|
+
async insertBatch(records) {
|
|
57
|
+
if (!this.wasmDB)
|
|
58
|
+
throw new Error('Database not initialized');
|
|
59
|
+
for (const record of records) {
|
|
60
|
+
// console.log('🔍 Inserting to WASM:', {
|
|
61
|
+
// id: record.id,
|
|
62
|
+
// vectorLength: record.vector.length,
|
|
63
|
+
// metadata: record.metadata,
|
|
64
|
+
// metadataType: typeof record.metadata,
|
|
65
|
+
// metadataKeys: record.metadata ? Object.keys(record.metadata) : null
|
|
66
|
+
// })
|
|
67
|
+
this.wasmDB.insert(record.id, record.vector, record.metadata ?? null);
|
|
68
|
+
}
|
|
69
|
+
await this.saveToIndexedDB();
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Search for nearest neighbors
|
|
73
|
+
*/
|
|
74
|
+
async search(query, options = {}) {
|
|
75
|
+
if (!this.wasmDB)
|
|
76
|
+
throw new Error('Database not initialized');
|
|
77
|
+
const k = options.k ?? 10;
|
|
78
|
+
const ef = options.ef ?? 50;
|
|
79
|
+
const results = this.wasmDB.search(query, k, ef);
|
|
80
|
+
return results;
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Delete a vector by ID
|
|
84
|
+
*/
|
|
85
|
+
async delete(id) {
|
|
86
|
+
if (!this.wasmDB)
|
|
87
|
+
throw new Error('Database not initialized');
|
|
88
|
+
const deleted = this.wasmDB.delete(id);
|
|
89
|
+
if (deleted) {
|
|
90
|
+
await this.saveToIndexedDB();
|
|
91
|
+
}
|
|
92
|
+
return deleted;
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Get total number of vectors
|
|
96
|
+
*/
|
|
97
|
+
size() {
|
|
98
|
+
if (!this.wasmDB)
|
|
99
|
+
throw new Error('Database not initialized');
|
|
100
|
+
return this.wasmDB.size();
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Clear all data
|
|
104
|
+
*/
|
|
105
|
+
async clear() {
|
|
106
|
+
if (!this.wasmDB)
|
|
107
|
+
throw new Error('Database not initialized');
|
|
108
|
+
const wasmModule = await import('./pkg/bundler/idbvec');
|
|
109
|
+
this.wasmDB = new wasmModule.VectorDB(this.config.dimensions, this.config.m, this.config.efConstruction);
|
|
110
|
+
await this.saveToIndexedDB();
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Open IndexedDB connection
|
|
114
|
+
*/
|
|
115
|
+
openIndexedDB() {
|
|
116
|
+
return new Promise((resolve, reject) => {
|
|
117
|
+
const request = indexedDB.open(this.config.name, 1);
|
|
118
|
+
request.onerror = () => reject(request.error);
|
|
119
|
+
request.onsuccess = () => {
|
|
120
|
+
const db = request.result;
|
|
121
|
+
// CRITICAL: Handle versionchange event to auto-close when database is being deleted
|
|
122
|
+
// This prevents "blocked" errors when trying to delete the database
|
|
123
|
+
db.onversionchange = () => {
|
|
124
|
+
// console.log(`🔒 VectorDB "${this.config.name}" received versionchange event - closing connection`)
|
|
125
|
+
db.close();
|
|
126
|
+
this.idb = null;
|
|
127
|
+
};
|
|
128
|
+
resolve(db);
|
|
129
|
+
};
|
|
130
|
+
request.onupgradeneeded = (event) => {
|
|
131
|
+
const db = event.target.result;
|
|
132
|
+
if (!db.objectStoreNames.contains('vectordb')) {
|
|
133
|
+
db.createObjectStore('vectordb');
|
|
134
|
+
}
|
|
135
|
+
};
|
|
136
|
+
});
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* Save WASM state to IndexedDB
|
|
140
|
+
*/
|
|
141
|
+
async saveToIndexedDB() {
|
|
142
|
+
if (!this.idb || !this.wasmDB)
|
|
143
|
+
return;
|
|
144
|
+
const serialized = this.wasmDB.serialize();
|
|
145
|
+
return new Promise((resolve, reject) => {
|
|
146
|
+
const tx = this.idb.transaction('vectordb', 'readwrite');
|
|
147
|
+
const store = tx.objectStore('vectordb');
|
|
148
|
+
const request = store.put(serialized, 'state');
|
|
149
|
+
request.onerror = () => reject(request.error);
|
|
150
|
+
request.onsuccess = () => resolve();
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* Load WASM state from IndexedDB
|
|
155
|
+
*/
|
|
156
|
+
async loadFromIndexedDB() {
|
|
157
|
+
if (!this.idb)
|
|
158
|
+
return null;
|
|
159
|
+
return new Promise((resolve, reject) => {
|
|
160
|
+
const tx = this.idb.transaction('vectordb', 'readonly');
|
|
161
|
+
const store = tx.objectStore('vectordb');
|
|
162
|
+
const request = store.get('state');
|
|
163
|
+
request.onerror = () => reject(request.error);
|
|
164
|
+
request.onsuccess = () => {
|
|
165
|
+
const result = request.result;
|
|
166
|
+
resolve(result ?? null);
|
|
167
|
+
};
|
|
168
|
+
});
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* Close the database
|
|
172
|
+
*/
|
|
173
|
+
close() {
|
|
174
|
+
if (this.idb) {
|
|
175
|
+
this.idb.close();
|
|
176
|
+
this.idb = null;
|
|
177
|
+
}
|
|
178
|
+
this.wasmDB = null;
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
/**
|
|
182
|
+
* Standalone distance functions
|
|
183
|
+
*/
|
|
184
|
+
export async function cosineSimilarity(a, b) {
|
|
185
|
+
const wasmModule = await import('./pkg/bundler/idbvec');
|
|
186
|
+
return wasmModule.cosine_similarity(a, b);
|
|
187
|
+
}
|
|
188
|
+
export async function euclideanDistance(a, b) {
|
|
189
|
+
const wasmModule = await import('./pkg/bundler/idbvec');
|
|
190
|
+
return wasmModule.euclidean_distance(a, b);
|
|
191
|
+
}
|
|
192
|
+
export async function dotProduct(a, b) {
|
|
193
|
+
const wasmModule = await import('./pkg/bundler/idbvec');
|
|
194
|
+
return wasmModule.dot_product(a, b);
|
|
195
|
+
}
|