Merge commit 'd803bfe2b1fe7f5e219e50ac20d6801a0a58ac75' as 'vendor/ruvector'
This commit is contained in:
848
vendor/ruvector/crates/ruvector-router-wasm/README.md
vendored
Normal file
848
vendor/ruvector/crates/ruvector-router-wasm/README.md
vendored
Normal file
@@ -0,0 +1,848 @@
|
||||
# Router WASM
|
||||
|
||||
[](https://opensource.org/licenses/MIT)
|
||||
[](https://www.npmjs.com/package/router-wasm)
|
||||
[](https://bundlephobia.com/package/router-wasm)
|
||||
[](https://webassembly.org/)
|
||||
|
||||
**WebAssembly bindings for intelligent neural routing and vector search in the browser.**
|
||||
|
||||
> Bring powerful vector database capabilities to the client-side. Run sub-millisecond vector search entirely in the browser with **zero server dependencies**. Perfect for edge computing, offline AI, and privacy-first applications.
|
||||
|
||||
## 🌟 Why Router WASM?
|
||||
|
||||
Traditional vector databases require backend infrastructure and constant network connectivity. **Router WASM changes that.**
|
||||
|
||||
### The Browser-First Advantage
|
||||
|
||||
- ⚡ **Zero Latency**: No network roundtrips—search happens entirely in the browser
|
||||
- 🔒 **Privacy First**: User data never leaves the device
|
||||
- 🌐 **Offline Capable**: Full functionality without internet connection
|
||||
- 💰 **Cost Effective**: Eliminate backend infrastructure and API costs
|
||||
- 🚀 **Edge Computing**: Deploy intelligent routing to CDN edge nodes
|
||||
- 📦 **Small Bundle**: Optimized WASM binary for fast page loads
|
||||
|
||||
## 🚀 Features
|
||||
|
||||
### Core Capabilities
|
||||
|
||||
- **Client-Side Vector Search**: Sub-millisecond similarity search in the browser
|
||||
- **Neural Routing**: Intelligent request routing and pattern matching
|
||||
- **Multiple Distance Metrics**: Euclidean, Cosine, Dot Product, Manhattan
|
||||
- **HNSW Indexing**: Fast approximate nearest neighbor search
|
||||
- **Memory Efficient**: Optimized for browser memory constraints
|
||||
- **TypeScript Support**: Full type definitions included
|
||||
- **Framework Agnostic**: Works with React, Vue, Svelte, vanilla JS
|
||||
- **Web Worker Ready**: Run computations off the main thread
|
||||
|
||||
### Browser-Specific Optimizations
|
||||
|
||||
- **SIMD Acceleration**: Hardware-accelerated vector operations where available
|
||||
- **Progressive Loading**: Load and initialize asynchronously
|
||||
- **Lazy Initialization**: Initialize only when needed
|
||||
- **Small Footprint**: <100KB gzipped WASM binary
|
||||
- **Memory Pooling**: Efficient memory management for long-running sessions
|
||||
- **IndexedDB Integration**: Persist vector data locally
|
||||
|
||||
## 📦 Installation
|
||||
|
||||
### NPM/Yarn
|
||||
|
||||
```bash
|
||||
# Using npm
|
||||
npm install router-wasm
|
||||
|
||||
# Using yarn
|
||||
yarn add router-wasm
|
||||
|
||||
# Using pnpm
|
||||
pnpm add router-wasm
|
||||
```
|
||||
|
||||
### CDN (Unpkg)
|
||||
|
||||
```html
|
||||
<script type="module">
|
||||
import init, { VectorDB } from 'https://unpkg.com/router-wasm/router_wasm.js';
|
||||
|
||||
await init();
|
||||
const db = new VectorDB(128);
|
||||
</script>
|
||||
```
|
||||
|
||||
## ⚡ Quick Start
|
||||
|
||||
### Basic Usage (ES Modules)
|
||||
|
||||
```javascript
|
||||
import init, { VectorDB, DistanceMetric } from 'router-wasm';
|
||||
|
||||
// Initialize WASM module (only once)
|
||||
await init();
|
||||
|
||||
// Create a vector database with 128 dimensions
|
||||
const db = new VectorDB(128);
|
||||
|
||||
// Insert vectors
|
||||
db.insert('doc1', new Float32Array([0.1, 0.2, 0.3, /* ... 125 more */]));
|
||||
db.insert('doc2', new Float32Array([0.4, 0.5, 0.6, /* ... 125 more */]));
|
||||
db.insert('doc3', new Float32Array([0.7, 0.8, 0.9, /* ... 125 more */]));
|
||||
|
||||
// Search for similar vectors
|
||||
const query = new Float32Array([0.15, 0.25, 0.35, /* ... 125 more */]);
|
||||
const results = db.search(query, 5); // Top 5 results
|
||||
|
||||
// Process results
|
||||
for (const result of results) {
|
||||
console.log(`ID: ${result.id}, Score: ${result.score}`);
|
||||
}
|
||||
|
||||
// Get collection size
|
||||
console.log(`Total vectors: ${db.count()}`);
|
||||
|
||||
// Delete a vector
|
||||
db.delete('doc2');
|
||||
```
|
||||
|
||||
### TypeScript Support
|
||||
|
||||
```typescript
|
||||
import init, { VectorDB, DistanceMetric } from 'router-wasm';
|
||||
|
||||
interface SearchResult {
|
||||
id: string;
|
||||
score: number;
|
||||
}
|
||||
|
||||
async function initializeVectorSearch(): Promise<VectorDB> {
|
||||
// Initialize WASM
|
||||
await init();
|
||||
|
||||
// Create database with 384 dimensions (e.g., for sentence embeddings)
|
||||
const db = new VectorDB(384);
|
||||
|
||||
return db;
|
||||
}
|
||||
|
||||
async function semanticSearch(
|
||||
db: VectorDB,
|
||||
queryEmbedding: Float32Array,
|
||||
topK: number = 10
|
||||
): Promise<SearchResult[]> {
|
||||
const results = db.search(queryEmbedding, topK);
|
||||
return results;
|
||||
}
|
||||
```
|
||||
|
||||
### React Integration
|
||||
|
||||
```jsx
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import init, { VectorDB } from 'router-wasm';
|
||||
|
||||
function VectorSearchApp() {
|
||||
const [db, setDb] = useState(null);
|
||||
const [loading, setLoading] = useState(true);
|
||||
const [results, setResults] = useState([]);
|
||||
|
||||
useEffect(() => {
|
||||
async function initialize() {
|
||||
await init();
|
||||
const vectorDb = new VectorDB(128);
|
||||
|
||||
// Populate with sample data
|
||||
vectorDb.insert('item1', new Float32Array(128).fill(0.1));
|
||||
vectorDb.insert('item2', new Float32Array(128).fill(0.5));
|
||||
|
||||
setDb(vectorDb);
|
||||
setLoading(false);
|
||||
}
|
||||
|
||||
initialize();
|
||||
}, []);
|
||||
|
||||
const handleSearch = async (queryVector) => {
|
||||
if (!db) return;
|
||||
|
||||
const searchResults = db.search(queryVector, 10);
|
||||
setResults(searchResults);
|
||||
};
|
||||
|
||||
if (loading) return <div>Loading vector database...</div>;
|
||||
|
||||
return (
|
||||
<div>
|
||||
<h1>Client-Side Vector Search</h1>
|
||||
<button onClick={() => handleSearch(new Float32Array(128).fill(0.2))}>
|
||||
Search
|
||||
</button>
|
||||
<ul>
|
||||
{results.map(r => (
|
||||
<li key={r.id}>
|
||||
{r.id}: {r.score.toFixed(4)}
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default VectorSearchApp;
|
||||
```
|
||||
|
||||
### Vue 3 Integration
|
||||
|
||||
```vue
|
||||
<template>
|
||||
<div>
|
||||
<h1>Vector Search</h1>
|
||||
<input v-model="searchQuery" @input="handleSearch" placeholder="Search..." />
|
||||
<ul>
|
||||
<li v-for="result in results" :key="result.id">
|
||||
{{ result.id }}: {{ result.score.toFixed(4) }}
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, onMounted } from 'vue';
|
||||
import init, { VectorDB } from 'router-wasm';
|
||||
|
||||
const db = ref(null);
|
||||
const searchQuery = ref('');
|
||||
const results = ref([]);
|
||||
|
||||
onMounted(async () => {
|
||||
await init();
|
||||
db.value = new VectorDB(128);
|
||||
|
||||
// Populate database
|
||||
db.value.insert('doc1', new Float32Array(128).fill(0.1));
|
||||
db.value.insert('doc2', new Float32Array(128).fill(0.5));
|
||||
});
|
||||
|
||||
const handleSearch = () => {
|
||||
if (!db.value || !searchQuery.value) return;
|
||||
|
||||
// Convert query to embedding (simplified example)
|
||||
const queryVector = new Float32Array(128).fill(parseFloat(searchQuery.value) || 0);
|
||||
results.value = db.value.search(queryVector, 5);
|
||||
};
|
||||
</script>
|
||||
```
|
||||
|
||||
## 🎯 Use Cases
|
||||
|
||||
### Client-Side AI Applications
|
||||
|
||||
**Semantic Search in the Browser**
|
||||
```javascript
|
||||
// RAG (Retrieval Augmented Generation) in the browser
|
||||
import init, { VectorDB } from 'router-wasm';
|
||||
import { generateEmbedding } from './embeddings'; // Your embedding model
|
||||
|
||||
await init();
|
||||
const knowledgeBase = new VectorDB(384);
|
||||
|
||||
// Index documents
|
||||
const docs = [
|
||||
{ id: 'doc1', text: 'Rust is a systems programming language' },
|
||||
{ id: 'doc2', text: 'WebAssembly enables near-native performance' },
|
||||
{ id: 'doc3', text: 'Vector databases power semantic search' }
|
||||
];
|
||||
|
||||
for (const doc of docs) {
|
||||
const embedding = await generateEmbedding(doc.text);
|
||||
knowledgeBase.insert(doc.id, embedding);
|
||||
}
|
||||
|
||||
// Query with natural language
|
||||
const queryEmbedding = await generateEmbedding('What is WASM?');
|
||||
const relevantDocs = knowledgeBase.search(queryEmbedding, 3);
|
||||
```
|
||||
|
||||
**Offline Recommender System**
|
||||
```javascript
|
||||
// Product recommendations without backend
|
||||
const productDb = new VectorDB(256);
|
||||
|
||||
// Index product features
|
||||
products.forEach(product => {
|
||||
const featureVector = extractFeatures(product);
|
||||
productDb.insert(product.id, featureVector);
|
||||
});
|
||||
|
||||
// Get recommendations based on user preferences
|
||||
const userPreferences = getUserPreferenceVector();
|
||||
const recommendations = productDb.search(userPreferences, 10);
|
||||
```
|
||||
|
||||
**Privacy-First Search**
|
||||
```javascript
|
||||
// Search user data without sending to server
|
||||
const privateDb = new VectorDB(512);
|
||||
|
||||
// User data stays in browser
|
||||
userDocuments.forEach(doc => {
|
||||
const embedding = embedDocument(doc);
|
||||
privateDb.insert(doc.id, embedding);
|
||||
});
|
||||
|
||||
// All searches happen locally
|
||||
const results = privateDb.search(queryEmbedding, 20);
|
||||
```
|
||||
|
||||
### Edge Computing & CDN
|
||||
|
||||
**Cloudflare Workers**
|
||||
```javascript
|
||||
// Deploy to Cloudflare Workers
|
||||
import init, { VectorDB } from 'router-wasm';
|
||||
|
||||
export default {
|
||||
async fetch(request, env, ctx) {
|
||||
await init();
|
||||
|
||||
const db = new VectorDB(128);
|
||||
// Load pre-computed vectors from KV store
|
||||
const vectors = await env.VECTORS.get('index', 'json');
|
||||
|
||||
for (const [id, vector] of Object.entries(vectors)) {
|
||||
db.insert(id, new Float32Array(vector));
|
||||
}
|
||||
|
||||
// Handle search at edge
|
||||
const { query } = await request.json();
|
||||
const results = db.search(new Float32Array(query), 10);
|
||||
|
||||
return new Response(JSON.stringify(results), {
|
||||
headers: { 'content-type': 'application/json' }
|
||||
});
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
**Deno Deploy**
|
||||
```typescript
|
||||
// Edge function with vector search
|
||||
import init, { VectorDB } from 'https://esm.sh/router-wasm';
|
||||
|
||||
Deno.serve(async (req) => {
|
||||
await init();
|
||||
|
||||
const db = new VectorDB(256);
|
||||
// Your edge routing logic
|
||||
|
||||
return new Response('OK');
|
||||
});
|
||||
```
|
||||
|
||||
### Web Workers
|
||||
|
||||
```javascript
|
||||
// worker.js - Run vector search off main thread
|
||||
import init, { VectorDB } from 'router-wasm';
|
||||
|
||||
let db = null;
|
||||
|
||||
self.addEventListener('message', async (e) => {
|
||||
const { type, payload } = e.data;
|
||||
|
||||
if (type === 'init') {
|
||||
await init();
|
||||
db = new VectorDB(payload.dimensions);
|
||||
self.postMessage({ type: 'ready' });
|
||||
}
|
||||
|
||||
if (type === 'insert') {
|
||||
db.insert(payload.id, new Float32Array(payload.vector));
|
||||
self.postMessage({ type: 'inserted', id: payload.id });
|
||||
}
|
||||
|
||||
if (type === 'search') {
|
||||
const results = db.search(new Float32Array(payload.query), payload.k);
|
||||
self.postMessage({ type: 'results', data: results });
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
```javascript
|
||||
// main.js - Use the worker
|
||||
const worker = new Worker('worker.js', { type: 'module' });
|
||||
|
||||
worker.postMessage({ type: 'init', payload: { dimensions: 128 } });
|
||||
|
||||
worker.addEventListener('message', (e) => {
|
||||
if (e.data.type === 'ready') {
|
||||
console.log('Vector DB ready in worker');
|
||||
|
||||
// Insert data
|
||||
worker.postMessage({
|
||||
type: 'insert',
|
||||
payload: { id: 'doc1', vector: new Array(128).fill(0.1) }
|
||||
});
|
||||
|
||||
// Search
|
||||
worker.postMessage({
|
||||
type: 'search',
|
||||
payload: { query: new Array(128).fill(0.2), k: 5 }
|
||||
});
|
||||
}
|
||||
|
||||
if (e.data.type === 'results') {
|
||||
console.log('Search results:', e.data.data);
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
## 🔧 Advanced Features
|
||||
|
||||
### Persistent Storage (IndexedDB)
|
||||
|
||||
```javascript
|
||||
import init, { VectorDB } from 'router-wasm';
|
||||
|
||||
// Initialize with persistent storage path
|
||||
await init();
|
||||
const db = new VectorDB(128, 'my-vector-store');
|
||||
|
||||
// Data persists across sessions
|
||||
db.insert('doc1', new Float32Array(128));
|
||||
|
||||
// Reload in future session
|
||||
const db2 = new VectorDB(128, 'my-vector-store');
|
||||
console.log(db2.count()); // Previously inserted data is available
|
||||
```
|
||||
|
||||
### Distance Metrics
|
||||
|
||||
```javascript
|
||||
import { VectorDB, DistanceMetric } from 'router-wasm';
|
||||
|
||||
const db = new VectorDB(128);
|
||||
|
||||
// Different similarity measures available:
|
||||
// - DistanceMetric.Euclidean (L2 distance)
|
||||
// - DistanceMetric.Cosine (cosine similarity)
|
||||
// - DistanceMetric.DotProduct (dot product)
|
||||
// - DistanceMetric.Manhattan (L1 distance)
|
||||
|
||||
// Note: Distance metric is set at index build time in router-core
|
||||
```
|
||||
|
||||
### Batch Operations
|
||||
|
||||
```javascript
|
||||
// Efficient bulk insertion
|
||||
const vectors = [
|
||||
{ id: 'doc1', vector: new Float32Array(128).fill(0.1) },
|
||||
{ id: 'doc2', vector: new Float32Array(128).fill(0.2) },
|
||||
{ id: 'doc3', vector: new Float32Array(128).fill(0.3) },
|
||||
];
|
||||
|
||||
vectors.forEach(({ id, vector }) => db.insert(id, vector));
|
||||
|
||||
// Batch search (multiple queries)
|
||||
const queries = [
|
||||
new Float32Array(128).fill(0.15),
|
||||
new Float32Array(128).fill(0.25),
|
||||
];
|
||||
|
||||
const allResults = queries.map(query => db.search(query, 5));
|
||||
```
|
||||
|
||||
### Memory Management
|
||||
|
||||
```javascript
|
||||
// Check collection size
|
||||
const count = db.count();
|
||||
console.log(`Vectors in database: ${count}`);
|
||||
|
||||
// Clean up when done (especially important in SPAs)
|
||||
// Note: Drop the reference and let garbage collector handle it
|
||||
db = null;
|
||||
|
||||
// For explicit cleanup in long-running apps
|
||||
function cleanupVectorDb(db) {
|
||||
const ids = getAllIds(); // Your tracking logic
|
||||
ids.forEach(id => db.delete(id));
|
||||
}
|
||||
```
|
||||
|
||||
## 📊 Performance Optimization
|
||||
|
||||
### Bundle Size Optimization
|
||||
|
||||
**Tree Shaking**
|
||||
```javascript
|
||||
// Import only what you need
|
||||
import init, { VectorDB } from 'router-wasm';
|
||||
// Don't import unused distance metrics or types
|
||||
```
|
||||
|
||||
**Code Splitting**
|
||||
```javascript
|
||||
// Lazy load WASM module
|
||||
const loadVectorDB = async () => {
|
||||
const { default: init, VectorDB } = await import('router-wasm');
|
||||
await init();
|
||||
return VectorDB;
|
||||
};
|
||||
|
||||
// Use when needed
|
||||
button.addEventListener('click', async () => {
|
||||
const VectorDB = await loadVectorDB();
|
||||
const db = new VectorDB(128);
|
||||
});
|
||||
```
|
||||
|
||||
**Webpack Configuration**
|
||||
```javascript
|
||||
// webpack.config.js
|
||||
module.exports = {
|
||||
experiments: {
|
||||
asyncWebAssembly: true,
|
||||
},
|
||||
optimization: {
|
||||
splitChunks: {
|
||||
chunks: 'all',
|
||||
},
|
||||
},
|
||||
};
|
||||
```
|
||||
|
||||
### Runtime Performance
|
||||
|
||||
**Pre-compute Embeddings**
|
||||
```javascript
|
||||
// Generate embeddings server-side or during build
|
||||
// Ship pre-computed vectors to reduce client computation
|
||||
const precomputedVectors = await fetch('/vectors.json').then(r => r.json());
|
||||
|
||||
await init();
|
||||
const db = new VectorDB(128);
|
||||
|
||||
for (const [id, vector] of Object.entries(precomputedVectors)) {
|
||||
db.insert(id, new Float32Array(vector));
|
||||
}
|
||||
```
|
||||
|
||||
**Dimension Reduction**
|
||||
```javascript
|
||||
// Use lower dimensions for faster search
|
||||
// 128 or 256 dimensions often sufficient for many use cases
|
||||
const db = new VectorDB(128); // Instead of 384 or 768
|
||||
|
||||
// Consider PCA or other dimensionality reduction techniques
|
||||
```
|
||||
|
||||
**Limit Result Sets**
|
||||
```javascript
|
||||
// Request only what you need
|
||||
const results = db.search(query, 10); // Top 10, not 100
|
||||
|
||||
// Implement pagination if needed
|
||||
function paginatedSearch(query, page = 0, pageSize = 10) {
|
||||
const allResults = db.search(query, (page + 1) * pageSize);
|
||||
return allResults.slice(page * pageSize, (page + 1) * pageSize);
|
||||
}
|
||||
```
|
||||
|
||||
## 🔨 Building from Source
|
||||
|
||||
### Prerequisites
|
||||
|
||||
- **Rust**: 1.77 or higher
|
||||
- **wasm-pack**: `cargo install wasm-pack`
|
||||
- **Node.js**: 18.0 or higher (for testing)
|
||||
|
||||
### Build Commands
|
||||
|
||||
```bash
|
||||
# Clone repository
|
||||
git clone https://github.com/ruvnet/ruvector.git
|
||||
cd ruvector/crates/router-wasm
|
||||
|
||||
# Build for web (ES modules)
|
||||
wasm-pack build --target web --release
|
||||
|
||||
# Build for Node.js
|
||||
wasm-pack build --target nodejs --release
|
||||
|
||||
# Build for bundlers (webpack, etc.)
|
||||
wasm-pack build --target bundler --release
|
||||
|
||||
# Build with optimizations
|
||||
wasm-pack build --target web --release -- --features simd
|
||||
|
||||
# Run tests
|
||||
wasm-pack test --headless --chrome
|
||||
```
|
||||
|
||||
### Build Output
|
||||
|
||||
After building, the `pkg/` directory contains:
|
||||
|
||||
```
|
||||
pkg/
|
||||
├── router_wasm.js # JavaScript bindings
|
||||
├── router_wasm.d.ts # TypeScript definitions
|
||||
├── router_wasm_bg.wasm # WebAssembly binary
|
||||
├── router_wasm_bg.wasm.d.ts
|
||||
└── package.json # NPM package metadata
|
||||
```
|
||||
|
||||
### Custom Build Profiles
|
||||
|
||||
```toml
|
||||
# Cargo.toml - Already optimized for size
|
||||
[profile.release]
|
||||
opt-level = "z" # Optimize for size
|
||||
lto = true # Link-time optimization
|
||||
codegen-units = 1 # Better optimization
|
||||
panic = "abort" # Smaller binary
|
||||
```
|
||||
|
||||
## 🌐 Browser Compatibility
|
||||
|
||||
| Browser | Version | WASM | SIMD | Notes |
|
||||
|---------|---------|------|------|-------|
|
||||
| **Chrome** | 87+ | ✅ | ✅ | Full support |
|
||||
| **Firefox** | 89+ | ✅ | ✅ | Full support |
|
||||
| **Safari** | 15+ | ✅ | ⚠️ | WASM SIMD in 16.4+ |
|
||||
| **Edge** | 87+ | ✅ | ✅ | Full support |
|
||||
| **Opera** | 73+ | ✅ | ✅ | Full support |
|
||||
| **Mobile Safari** | 15+ | ✅ | ⚠️ | Limited SIMD |
|
||||
| **Mobile Chrome** | 87+ | ✅ | ✅ | Full support |
|
||||
|
||||
**Notes**:
|
||||
- ✅ Full support
|
||||
- ⚠️ Partial support (SIMD acceleration may not be available)
|
||||
- All modern browsers support WebAssembly
|
||||
- SIMD provides 2-4x performance boost where available
|
||||
|
||||
## 🔗 Integration with Ruvector Ecosystem
|
||||
|
||||
### With ruvector-wasm
|
||||
|
||||
```javascript
|
||||
import initRouter, { VectorDB as RouterDB } from 'router-wasm';
|
||||
import initRuvector, { VectorDB } from 'ruvector-wasm';
|
||||
|
||||
// Initialize both modules
|
||||
await Promise.all([initRouter(), initRuvector()]);
|
||||
|
||||
// Router WASM: Intelligent routing and pattern matching
|
||||
const router = new RouterDB(128);
|
||||
|
||||
// Ruvector WASM: Full-featured vector database
|
||||
const vectorDb = new VectorDB(128);
|
||||
|
||||
// Use together for advanced use cases
|
||||
```
|
||||
|
||||
### With Node.js Backend
|
||||
|
||||
```javascript
|
||||
// Frontend (router-wasm)
|
||||
import init, { VectorDB } from 'router-wasm';
|
||||
await init();
|
||||
const clientDb = new VectorDB(128);
|
||||
|
||||
// Backend (ruvector Node.js bindings)
|
||||
const { VectorDB } = require('ruvector');
|
||||
const serverDb = new VectorDB();
|
||||
|
||||
// Hybrid architecture: Local search + server sync
|
||||
```
|
||||
|
||||
## 📚 API Reference
|
||||
|
||||
### VectorDB
|
||||
|
||||
```typescript
|
||||
class VectorDB {
|
||||
/**
|
||||
* Create a new vector database
|
||||
* @param dimensions - Vector dimensionality (e.g., 128, 256, 384, 768)
|
||||
* @param storage_path - Optional persistent storage path
|
||||
*/
|
||||
constructor(dimensions: number, storage_path?: string);
|
||||
|
||||
/**
|
||||
* Insert a vector into the database
|
||||
* @param id - Unique identifier
|
||||
* @param vector - Float32Array of specified dimensions
|
||||
* @returns The inserted ID
|
||||
*/
|
||||
insert(id: string, vector: Float32Array): string;
|
||||
|
||||
/**
|
||||
* Search for similar vectors
|
||||
* @param vector - Query vector
|
||||
* @param k - Number of results to return
|
||||
* @returns Array of search results with id and score
|
||||
*/
|
||||
search(vector: Float32Array, k: number): SearchResult[];
|
||||
|
||||
/**
|
||||
* Delete a vector by ID
|
||||
* @param id - ID to delete
|
||||
* @returns true if deleted, false if not found
|
||||
*/
|
||||
delete(id: string): boolean;
|
||||
|
||||
/**
|
||||
* Get total number of vectors
|
||||
* @returns Vector count
|
||||
*/
|
||||
count(): number;
|
||||
}
|
||||
```
|
||||
|
||||
### Types
|
||||
|
||||
```typescript
|
||||
interface SearchResult {
|
||||
id: string;
|
||||
score: number;
|
||||
}
|
||||
|
||||
enum DistanceMetric {
|
||||
Euclidean,
|
||||
Cosine,
|
||||
DotProduct,
|
||||
Manhattan
|
||||
}
|
||||
```
|
||||
|
||||
## 🎓 Examples
|
||||
|
||||
### Complete RAG Application
|
||||
|
||||
See [examples/browser-rag](../../examples/browser-rag/) for a full-featured Retrieval Augmented Generation application running entirely in the browser.
|
||||
|
||||
### Product Search
|
||||
|
||||
See [examples/product-search](../../examples/product-search/) for an offline product recommendation system.
|
||||
|
||||
### Edge Routing
|
||||
|
||||
See [examples/edge-routing](../../examples/edge-routing/) for Cloudflare Workers integration.
|
||||
|
||||
## 🐛 Troubleshooting
|
||||
|
||||
### WASM Module Not Loading
|
||||
|
||||
```javascript
|
||||
// Ensure init() is called before creating VectorDB
|
||||
import init, { VectorDB } from 'router-wasm';
|
||||
|
||||
// ❌ Wrong
|
||||
const db = new VectorDB(128); // Error: WASM not initialized
|
||||
|
||||
// ✅ Correct
|
||||
await init();
|
||||
const db = new VectorDB(128);
|
||||
```
|
||||
|
||||
### Large Bundle Size
|
||||
|
||||
```javascript
|
||||
// Use dynamic imports for code splitting
|
||||
const { default: init, VectorDB } = await import('router-wasm');
|
||||
await init();
|
||||
```
|
||||
|
||||
### Memory Errors in Browser
|
||||
|
||||
```javascript
|
||||
// Reduce dimensions or limit database size
|
||||
const db = new VectorDB(128); // Instead of 768
|
||||
|
||||
// Clear vectors periodically in long-running apps
|
||||
if (db.count() > 10000) {
|
||||
// Implement your pruning logic
|
||||
oldIds.forEach(id => db.delete(id));
|
||||
}
|
||||
```
|
||||
|
||||
### TypeScript Errors
|
||||
|
||||
```typescript
|
||||
// Ensure TypeScript can find declarations
|
||||
// tsconfig.json
|
||||
{
|
||||
"compilerOptions": {
|
||||
"moduleResolution": "node",
|
||||
"types": ["router-wasm"]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 📖 Documentation
|
||||
|
||||
- **[Quick Start Guide](../../docs/guide/GETTING_STARTED.md)** - Get started in 5 minutes
|
||||
- **[WASM API Reference](../../docs/getting-started/wasm-api.md)** - Complete API documentation
|
||||
- **[Performance Tuning](../../docs/optimization/PERFORMANCE_TUNING_GUIDE.md)** - Optimization strategies
|
||||
- **[Main README](../../README.md)** - Ruvector ecosystem overview
|
||||
|
||||
## 🤝 Contributing
|
||||
|
||||
Contributions are welcome! See [Contributing Guidelines](../../docs/development/CONTRIBUTING.md).
|
||||
|
||||
### Development Setup
|
||||
|
||||
```bash
|
||||
# Clone and setup
|
||||
git clone https://github.com/ruvnet/ruvector.git
|
||||
cd ruvector/crates/router-wasm
|
||||
|
||||
# Build
|
||||
wasm-pack build --target web
|
||||
|
||||
# Test
|
||||
wasm-pack test --headless --chrome --firefox
|
||||
|
||||
# Format
|
||||
cargo fmt
|
||||
|
||||
# Lint
|
||||
cargo clippy -- -D warnings
|
||||
```
|
||||
|
||||
## 📜 License
|
||||
|
||||
**MIT License** - see [LICENSE](../../LICENSE) for details.
|
||||
|
||||
## 🙏 Acknowledgments
|
||||
|
||||
Built with:
|
||||
- **wasm-bindgen**: Rust/JavaScript interop
|
||||
- **router-core**: High-performance vector routing engine
|
||||
- **HNSW**: Fast approximate nearest neighbor search
|
||||
- **SIMD**: Hardware-accelerated vector operations
|
||||
|
||||
## 🌐 Links
|
||||
|
||||
- **GitHub**: [github.com/ruvnet/ruvector](https://github.com/ruvnet/ruvector)
|
||||
- **NPM**: [npmjs.com/package/router-wasm](https://www.npmjs.com/package/router-wasm)
|
||||
- **Documentation**: [ruvector docs](../../docs/README.md)
|
||||
- **Discord**: [Join community](https://discord.gg/ruvnet)
|
||||
- **Website**: [ruv.io](https://ruv.io)
|
||||
|
||||
---
|
||||
|
||||
<div align="center">
|
||||
|
||||
**Built by [rUv](https://ruv.io) • Part of [Ruvector](../../README.md) • MIT Licensed**
|
||||
|
||||
[](https://github.com/ruvnet/ruvector)
|
||||
[](https://twitter.com/ruvnet)
|
||||
|
||||
**Browser-First Vector Search** | **Zero Backend Required** | **Privacy First**
|
||||
|
||||
[Get Started](../../docs/guide/GETTING_STARTED.md) • [Documentation](../../docs/README.md) • [Examples](../../examples/)
|
||||
|
||||
</div>
|
||||
Reference in New Issue
Block a user