git-subtree-dir: vendor/ruvector git-subtree-split: b64c21726f2bb37286d9ee36a7869fef60cc6900
808 lines
20 KiB
Markdown
808 lines
20 KiB
Markdown
# router-ffi
|
|
|
|
[](https://opensource.org/licenses/MIT)
|
|
[](https://www.rust-lang.org)
|
|
[](https://nodejs.org)
|
|
|
|
**High-performance Node.js bindings for router-core vector database and neural routing engine.**
|
|
|
|
> NAPI-RS powered bindings bringing Rust-level performance to JavaScript/TypeScript with zero-copy buffer sharing and async/await support.
|
|
|
|
## Overview
|
|
|
|
`router-ffi` provides seamless Node.js integration for the `router-core` vector database through NAPI-RS, enabling JavaScript and TypeScript applications to leverage Rust's blazing-fast performance for vector similarity search, neural routing, and embedding operations.
|
|
|
|
### Why router-ffi?
|
|
|
|
- **🚀 Native Performance**: Direct Rust execution with minimal overhead
|
|
- **⚡ Zero-Copy**: Float32Array buffers shared directly with Rust
|
|
- **🔄 Async/Await**: Non-blocking operations using Tokio runtime
|
|
- **🎯 Type Safe**: Complete TypeScript definitions auto-generated from Rust
|
|
- **🌐 Cross-Platform**: Linux, macOS, Windows (x64 and ARM64)
|
|
- **🧠 Neural Routing**: Advanced inference and routing capabilities
|
|
- **💾 Memory Efficient**: HNSW indexing with 4-32x compression
|
|
|
|
## Features
|
|
|
|
### Core Capabilities
|
|
|
|
- **Vector Operations**: Insert, search, delete with sub-millisecond latency
|
|
- **Distance Metrics**: Euclidean, Cosine, Dot Product, Manhattan
|
|
- **HNSW Indexing**: Sub-millisecond search with 95%+ recall
|
|
- **Async API**: Full async/await support for all operations
|
|
- **Batch Operations**: Efficient bulk insert and search
|
|
- **Metadata Support**: Store and filter by JSON metadata
|
|
- **Persistent Storage**: Disk-based storage with memory-mapped I/O
|
|
|
|
### Advanced Features
|
|
|
|
- **Neural Routing**: Intelligent request routing and load balancing
|
|
- **SIMD Optimizations**: Hardware-accelerated distance calculations
|
|
- **Product Quantization**: 4-32x memory compression
|
|
- **Thread Safety**: Arc-based concurrency for multi-threaded Node.js
|
|
- **Error Handling**: Proper JavaScript error propagation from Rust
|
|
|
|
## Installation
|
|
|
|
```bash
|
|
npm install router-ffi
|
|
```
|
|
|
|
### Prerequisites
|
|
|
|
- **Node.js**: 18.0 or higher
|
|
- **Rust**: 1.77+ (for building from source)
|
|
- **Platform**: Linux, macOS, or Windows (x64/ARM64)
|
|
|
|
## Quick Start
|
|
|
|
### Basic Usage
|
|
|
|
```javascript
|
|
const { VectorDB, DistanceMetric } = require('router-ffi');
|
|
|
|
// Create a vector database
|
|
const db = new VectorDB({
|
|
dimensions: 384,
|
|
maxElements: 10000,
|
|
distanceMetric: DistanceMetric.Cosine,
|
|
hnswM: 32,
|
|
hnswEfConstruction: 200,
|
|
hnswEfSearch: 100,
|
|
storagePath: './vectors.db'
|
|
});
|
|
|
|
// Insert a vector
|
|
const vector = new Float32Array([0.1, 0.2, 0.3, /* ... 384 dimensions */]);
|
|
const id = db.insert('doc1', vector);
|
|
console.log(`Inserted: ${id}`);
|
|
|
|
// Search for similar vectors
|
|
const query = new Float32Array([0.1, 0.2, 0.3, /* ... */]);
|
|
const results = db.search(query, 10);
|
|
|
|
results.forEach(result => {
|
|
console.log(`ID: ${result.id}, Score: ${result.score}`);
|
|
});
|
|
|
|
// Get database statistics
|
|
const count = db.count();
|
|
const allIds = db.getAllIds();
|
|
console.log(`Database contains ${count} vectors`);
|
|
```
|
|
|
|
### Async Operations
|
|
|
|
```javascript
|
|
const { VectorDB } = require('router-ffi');
|
|
|
|
async function main() {
|
|
const db = new VectorDB({
|
|
dimensions: 768,
|
|
distanceMetric: 'Cosine',
|
|
storagePath: './async-vectors.db'
|
|
});
|
|
|
|
// Async insert (non-blocking)
|
|
const vector = new Float32Array(768).fill(0.5);
|
|
const id = await db.insertAsync('doc1', vector);
|
|
console.log(`Inserted: ${id}`);
|
|
|
|
// Async search (non-blocking)
|
|
const query = new Float32Array(768).fill(0.5);
|
|
const results = await db.searchAsync(query, 10);
|
|
|
|
for (const result of results) {
|
|
console.log(`ID: ${result.id}, Score: ${result.score}`);
|
|
}
|
|
}
|
|
|
|
main().catch(console.error);
|
|
```
|
|
|
|
### TypeScript Usage
|
|
|
|
```typescript
|
|
import { VectorDB, DistanceMetric, DbOptions, SearchResultJS } from 'router-ffi';
|
|
|
|
// Type-safe configuration
|
|
const options: DbOptions = {
|
|
dimensions: 384,
|
|
maxElements: 50000,
|
|
distanceMetric: DistanceMetric.Cosine,
|
|
hnswM: 32,
|
|
hnswEfConstruction: 200,
|
|
hnswEfSearch: 100,
|
|
storagePath: './typed-vectors.db'
|
|
};
|
|
|
|
const db = new VectorDB(options);
|
|
|
|
// Type-safe operations
|
|
const vector: Float32Array = new Float32Array(384);
|
|
const id: string = db.insert('doc1', vector);
|
|
|
|
const results: SearchResultJS[] = db.search(vector, 10);
|
|
results.forEach((result: SearchResultJS) => {
|
|
console.log(`${result.id}: ${result.score}`);
|
|
});
|
|
```
|
|
|
|
## API Reference
|
|
|
|
### VectorDB
|
|
|
|
Main vector database class providing core operations.
|
|
|
|
#### Constructor
|
|
|
|
```typescript
|
|
new VectorDB(options: DbOptions)
|
|
```
|
|
|
|
**DbOptions:**
|
|
|
|
| Parameter | Type | Required | Default | Description |
|
|
|-----------|------|----------|---------|-------------|
|
|
| `dimensions` | `number` | Yes | - | Vector dimensionality |
|
|
| `maxElements` | `number` | No | 1,000,000 | Maximum number of vectors |
|
|
| `distanceMetric` | `DistanceMetric` | No | `Cosine` | Distance metric |
|
|
| `hnswM` | `number` | No | 32 | HNSW connections per node |
|
|
| `hnswEfConstruction` | `number` | No | 200 | HNSW construction quality |
|
|
| `hnswEfSearch` | `number` | No | 100 | HNSW search quality |
|
|
| `storagePath` | `string` | No | `./router.db` | Database file path |
|
|
|
|
#### Methods
|
|
|
|
##### insert
|
|
|
|
```typescript
|
|
insert(id: string, vector: Float32Array): string
|
|
```
|
|
|
|
Insert a vector synchronously. Returns the vector ID.
|
|
|
|
**Example:**
|
|
|
|
```javascript
|
|
const id = db.insert('doc1', new Float32Array([0.1, 0.2, 0.3]));
|
|
```
|
|
|
|
##### insertAsync
|
|
|
|
```typescript
|
|
async insertAsync(id: string, vector: Float32Array): Promise<string>
|
|
```
|
|
|
|
Insert a vector asynchronously (non-blocking). Returns a Promise with the vector ID.
|
|
|
|
**Example:**
|
|
|
|
```javascript
|
|
const id = await db.insertAsync('doc1', new Float32Array([0.1, 0.2, 0.3]));
|
|
```
|
|
|
|
##### search
|
|
|
|
```typescript
|
|
search(queryVector: Float32Array, k: number): SearchResultJS[]
|
|
```
|
|
|
|
Search for similar vectors synchronously. Returns top-k results sorted by similarity.
|
|
|
|
**Returns:** Array of `SearchResultJS` objects:
|
|
- `id` (string): Vector ID
|
|
- `score` (number): Distance score (lower is more similar)
|
|
|
|
**Example:**
|
|
|
|
```javascript
|
|
const results = db.search(new Float32Array([0.1, 0.2, 0.3]), 10);
|
|
```
|
|
|
|
##### searchAsync
|
|
|
|
```typescript
|
|
async searchAsync(queryVector: Float32Array, k: number): Promise<SearchResultJS[]>
|
|
```
|
|
|
|
Search for similar vectors asynchronously (non-blocking).
|
|
|
|
**Example:**
|
|
|
|
```javascript
|
|
const results = await db.searchAsync(new Float32Array([0.1, 0.2, 0.3]), 10);
|
|
```
|
|
|
|
##### delete
|
|
|
|
```typescript
|
|
delete(id: string): boolean
|
|
```
|
|
|
|
Delete a vector by ID. Returns `true` if deleted, `false` if not found.
|
|
|
|
**Example:**
|
|
|
|
```javascript
|
|
const deleted = db.delete('doc1');
|
|
```
|
|
|
|
##### count
|
|
|
|
```typescript
|
|
count(): number
|
|
```
|
|
|
|
Get the total number of vectors in the database.
|
|
|
|
**Example:**
|
|
|
|
```javascript
|
|
const totalVectors = db.count();
|
|
console.log(`Database contains ${totalVectors} vectors`);
|
|
```
|
|
|
|
##### getAllIds
|
|
|
|
```typescript
|
|
getAllIds(): string[]
|
|
```
|
|
|
|
Get all vector IDs in the database.
|
|
|
|
**Example:**
|
|
|
|
```javascript
|
|
const ids = db.getAllIds();
|
|
console.log(`IDs: ${ids.join(', ')}`);
|
|
```
|
|
|
|
### DistanceMetric
|
|
|
|
Enum defining supported distance metrics:
|
|
|
|
```typescript
|
|
enum DistanceMetric {
|
|
Euclidean = "Euclidean",
|
|
Cosine = "Cosine",
|
|
DotProduct = "DotProduct",
|
|
Manhattan = "Manhattan"
|
|
}
|
|
```
|
|
|
|
**Choosing a Metric:**
|
|
|
|
- **Cosine**: Best for normalized embeddings (most common)
|
|
- **Euclidean**: Standard L2 distance
|
|
- **DotProduct**: Efficient for pre-normalized vectors
|
|
- **Manhattan**: L1 distance, robust to outliers
|
|
|
|
## Building from Source
|
|
|
|
### Prerequisites
|
|
|
|
```bash
|
|
# Install Rust
|
|
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
|
|
|
|
# Install Node.js dependencies
|
|
npm install
|
|
```
|
|
|
|
### Build Commands
|
|
|
|
```bash
|
|
# Build the native module (release mode)
|
|
npm run build
|
|
|
|
# Build with debug symbols
|
|
npm run build:debug
|
|
|
|
# Clean build artifacts
|
|
npm run clean
|
|
|
|
# Run tests
|
|
npm test
|
|
|
|
# Format code
|
|
cargo fmt --all
|
|
|
|
# Lint
|
|
cargo clippy --all -- -D warnings
|
|
```
|
|
|
|
### Cross-Platform Compilation
|
|
|
|
Build for multiple platforms using NAPI-RS:
|
|
|
|
```bash
|
|
# Linux x64
|
|
npm run build -- --target x86_64-unknown-linux-gnu
|
|
|
|
# Linux ARM64
|
|
npm run build -- --target aarch64-unknown-linux-gnu
|
|
|
|
# macOS x64
|
|
npm run build -- --target x86_64-apple-darwin
|
|
|
|
# macOS ARM64 (M1/M2)
|
|
npm run build -- --target aarch64-apple-darwin
|
|
|
|
# Windows x64
|
|
npm run build -- --target x86_64-pc-windows-msvc
|
|
```
|
|
|
|
## Performance Benchmarks
|
|
|
|
### Local Performance
|
|
|
|
**10,000 vectors (384D):**
|
|
|
|
```
|
|
Operation Throughput Latency (avg)
|
|
------------------------------------------------
|
|
Insert (sync) ~2,000/sec 0.5ms
|
|
Insert (async) ~5,000/sec 0.2ms
|
|
Search (k=10) ~10,000/sec 0.1ms
|
|
Batch Insert ~8,000/sec 0.125ms
|
|
```
|
|
|
|
**1,000,000 vectors (384D):**
|
|
|
|
```
|
|
Operation Throughput Latency (avg)
|
|
------------------------------------------------
|
|
Insert (sync) ~1,000/sec 1.0ms
|
|
Insert (async) ~3,000/sec 0.33ms
|
|
Search (k=10) ~5,000/sec 0.2ms
|
|
Search (k=100) ~2,000/sec 0.5ms
|
|
```
|
|
|
|
### Performance Comparison
|
|
|
|
```
|
|
Library Search Latency Memory (1M vectors) Language
|
|
-------------------------------------------------------------------
|
|
router-ffi 0.2ms ~600MB Rust → Node.js
|
|
Pinecone ~2ms Cloud only Hosted
|
|
Qdrant ~1ms ~1.5GB Rust
|
|
ChromaDB ~50ms ~3GB Python
|
|
FAISS ~0.5ms ~1GB C++ → Python
|
|
```
|
|
|
|
### Optimization Tips
|
|
|
|
1. **Use Async Operations**: `insertAsync` and `searchAsync` for better throughput
|
|
2. **Batch Inserts**: Group multiple inserts for 3-4x better performance
|
|
3. **Tune HNSW Parameters**:
|
|
- Higher `hnswM` = better recall, more memory
|
|
- Higher `efConstruction` = better index quality, slower build
|
|
- Higher `efSearch` = better accuracy, slower search
|
|
4. **Choose Distance Metric**: `Cosine` with pre-normalized vectors is fastest
|
|
5. **Use Float32Array**: Direct buffer sharing avoids copies
|
|
|
|
## Use Cases
|
|
|
|
### RAG (Retrieval-Augmented Generation)
|
|
|
|
```javascript
|
|
const { VectorDB } = require('router-ffi');
|
|
|
|
// Create embeddings database
|
|
const db = new VectorDB({
|
|
dimensions: 1536, // OpenAI ada-002
|
|
distanceMetric: 'Cosine',
|
|
storagePath: './embeddings.db'
|
|
});
|
|
|
|
// Store document embeddings
|
|
async function indexDocument(docId, embedding) {
|
|
await db.insertAsync(docId, new Float32Array(embedding));
|
|
}
|
|
|
|
// Retrieve relevant documents
|
|
async function retrieveContext(queryEmbedding, topK = 5) {
|
|
const results = await db.searchAsync(
|
|
new Float32Array(queryEmbedding),
|
|
topK
|
|
);
|
|
return results.map(r => r.id);
|
|
}
|
|
```
|
|
|
|
### Semantic Search
|
|
|
|
```javascript
|
|
// Index text embeddings
|
|
const documents = [
|
|
{ id: 'doc1', text: 'Machine learning basics', embedding: [...] },
|
|
{ id: 'doc2', text: 'Deep learning tutorial', embedding: [...] },
|
|
{ id: 'doc3', text: 'Neural networks explained', embedding: [...] }
|
|
];
|
|
|
|
for (const doc of documents) {
|
|
await db.insertAsync(doc.id, new Float32Array(doc.embedding));
|
|
}
|
|
|
|
// Search by semantic similarity
|
|
const query = 'AI fundamentals';
|
|
const queryEmbedding = await getEmbedding(query);
|
|
const results = await db.searchAsync(new Float32Array(queryEmbedding), 3);
|
|
```
|
|
|
|
### Recommendation Engine
|
|
|
|
```javascript
|
|
// Store user/item embeddings
|
|
const userEmbeddings = new Map();
|
|
const itemEmbeddings = new Map();
|
|
|
|
// Index items
|
|
for (const [itemId, embedding] of itemEmbeddings) {
|
|
await db.insertAsync(`item_${itemId}`, new Float32Array(embedding));
|
|
}
|
|
|
|
// Find similar items
|
|
function recommendSimilar(itemId, count = 10) {
|
|
const embedding = itemEmbeddings.get(itemId);
|
|
const results = db.search(new Float32Array(embedding), count + 1);
|
|
return results.slice(1); // Exclude self
|
|
}
|
|
```
|
|
|
|
### Agent Memory
|
|
|
|
```javascript
|
|
// Store agent experiences
|
|
class AgentMemory {
|
|
constructor(dimensions) {
|
|
this.db = new VectorDB({
|
|
dimensions,
|
|
distanceMetric: 'Cosine',
|
|
storagePath: './agent-memory.db'
|
|
});
|
|
}
|
|
|
|
async remember(experience, embedding) {
|
|
const id = `exp_${Date.now()}`;
|
|
await this.db.insertAsync(id, new Float32Array(embedding));
|
|
return id;
|
|
}
|
|
|
|
async recall(queryEmbedding, count = 5) {
|
|
return await this.db.searchAsync(
|
|
new Float32Array(queryEmbedding),
|
|
count
|
|
);
|
|
}
|
|
}
|
|
```
|
|
|
|
## Memory Management
|
|
|
|
### Thread Safety
|
|
|
|
`router-ffi` uses Rust's `Arc<T>` for thread-safe reference counting, making it safe to use across Node.js worker threads:
|
|
|
|
```javascript
|
|
const { Worker } = require('worker_threads');
|
|
const { VectorDB } = require('router-ffi');
|
|
|
|
// Main thread
|
|
const db = new VectorDB({ dimensions: 384 });
|
|
|
|
// Workers can safely share the database
|
|
const worker = new Worker('./worker.js');
|
|
```
|
|
|
|
### Memory Efficiency
|
|
|
|
- **Zero-Copy Buffers**: Float32Array data is shared directly between JavaScript and Rust
|
|
- **Arc Reference Counting**: Automatic cleanup when JavaScript objects are garbage collected
|
|
- **Memory-Mapped I/O**: Efficient disk-based storage with OS-level caching
|
|
- **Product Quantization**: 4-32x compression for large datasets
|
|
|
|
### Best Practices
|
|
|
|
1. **Reuse VectorDB Instances**: Creating new instances is expensive
|
|
2. **Use Float32Array**: Native typed arrays avoid data copying
|
|
3. **Async for Large Batches**: Prevents blocking the event loop
|
|
4. **Close When Done**: Allow garbage collection to free resources
|
|
|
|
```javascript
|
|
// Good: Reuse instance
|
|
const db = new VectorDB({ dimensions: 384 });
|
|
for (let i = 0; i < 1000; i++) {
|
|
await db.insertAsync(`doc${i}`, vector);
|
|
}
|
|
|
|
// Bad: Creating new instances
|
|
for (let i = 0; i < 1000; i++) {
|
|
const db = new VectorDB({ dimensions: 384 }); // Expensive!
|
|
await db.insertAsync(`doc${i}`, vector);
|
|
}
|
|
```
|
|
|
|
## Platform Support
|
|
|
|
### Supported Platforms
|
|
|
|
| Platform | Architecture | Status | Notes |
|
|
|----------|--------------|--------|-------|
|
|
| Linux | x86_64 | ✅ Supported | glibc 2.17+ |
|
|
| Linux | aarch64 | ✅ Supported | ARM64 servers |
|
|
| macOS | x86_64 | ✅ Supported | Intel Macs |
|
|
| macOS | aarch64 | ✅ Supported | M1/M2/M3 Macs |
|
|
| Windows | x86_64 | ✅ Supported | MSVC runtime |
|
|
| Windows | aarch64 | ⚠️ Experimental | ARM64 Windows |
|
|
|
|
### Node.js Compatibility
|
|
|
|
- **Minimum**: Node.js 18.0
|
|
- **Recommended**: Node.js 20 LTS or 22 LTS
|
|
- **Maximum**: Latest stable release
|
|
|
|
### Pre-built Binaries
|
|
|
|
NAPI-RS provides pre-built binaries for common platforms. If your platform isn't supported, the module will compile from source automatically.
|
|
|
|
## Troubleshooting
|
|
|
|
### Installation Issues
|
|
|
|
**Error: `cargo` not found**
|
|
|
|
Install Rust toolchain:
|
|
|
|
```bash
|
|
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
|
|
source $HOME/.cargo/env
|
|
```
|
|
|
|
**Error: NAPI-RS build failed**
|
|
|
|
Update NAPI-RS CLI:
|
|
|
|
```bash
|
|
npm install -g @napi-rs/cli@latest
|
|
```
|
|
|
|
### Runtime Issues
|
|
|
|
**Error: Cannot find native module**
|
|
|
|
Rebuild the native module:
|
|
|
|
```bash
|
|
npm rebuild router-ffi
|
|
```
|
|
|
|
**Error: Vector dimension mismatch**
|
|
|
|
Ensure all vectors have the same dimensions as specified in `DbOptions`:
|
|
|
|
```javascript
|
|
const db = new VectorDB({ dimensions: 384 });
|
|
|
|
// ✅ Correct
|
|
db.insert('doc1', new Float32Array(384));
|
|
|
|
// ❌ Wrong - dimension mismatch
|
|
db.insert('doc2', new Float32Array(768)); // Error!
|
|
```
|
|
|
|
### Performance Issues
|
|
|
|
**Slow search performance**
|
|
|
|
1. Increase `hnswEfSearch` for better recall
|
|
2. Use `searchAsync` instead of `search`
|
|
3. Check if HNSW index is built (insert >100 vectors)
|
|
4. Consider using Product Quantization for large datasets
|
|
|
|
**High memory usage**
|
|
|
|
1. Reduce `maxElements` if you don't need it
|
|
2. Enable quantization (requires router-core configuration)
|
|
3. Use smaller `hnswM` value (trades accuracy for memory)
|
|
|
|
## Advanced Topics
|
|
|
|
### HNSW Index Tuning
|
|
|
|
The HNSW (Hierarchical Navigable Small World) index provides fast approximate nearest neighbor search:
|
|
|
|
```javascript
|
|
const db = new VectorDB({
|
|
dimensions: 384,
|
|
hnswM: 32, // Connections per node (16-64)
|
|
hnswEfConstruction: 200, // Build quality (100-500)
|
|
hnswEfSearch: 100 // Search quality (10-200)
|
|
});
|
|
```
|
|
|
|
**Parameter Guidelines:**
|
|
|
|
| Parameter | Low Value | High Value | Trade-off |
|
|
|-----------|-----------|------------|-----------|
|
|
| `hnswM` | 16 | 64 | Memory vs Recall |
|
|
| `efConstruction` | 100 | 500 | Speed vs Quality |
|
|
| `efSearch` | 10 | 200 | Speed vs Accuracy |
|
|
|
|
### Distance Metrics Explained
|
|
|
|
```javascript
|
|
// Cosine Similarity (angle between vectors)
|
|
// Range: [0, 2], lower is more similar
|
|
// Best for: Normalized embeddings, semantic search
|
|
const db1 = new VectorDB({ distanceMetric: 'Cosine' });
|
|
|
|
// Euclidean Distance (L2 norm)
|
|
// Range: [0, ∞), lower is more similar
|
|
// Best for: Spatial data, general purpose
|
|
const db2 = new VectorDB({ distanceMetric: 'Euclidean' });
|
|
|
|
// Dot Product (inner product)
|
|
// Range: (-∞, ∞), higher is more similar
|
|
// Best for: Pre-normalized vectors
|
|
const db3 = new VectorDB({ distanceMetric: 'DotProduct' });
|
|
|
|
// Manhattan Distance (L1 norm)
|
|
// Range: [0, ∞), lower is more similar
|
|
// Best for: Robust to outliers
|
|
const db4 = new VectorDB({ distanceMetric: 'Manhattan' });
|
|
```
|
|
|
|
### Batch Operations
|
|
|
|
```javascript
|
|
// Efficient batch insert
|
|
async function batchInsert(vectors) {
|
|
const promises = vectors.map((vec, idx) =>
|
|
db.insertAsync(`doc${idx}`, new Float32Array(vec))
|
|
);
|
|
return await Promise.all(promises);
|
|
}
|
|
|
|
// Parallel search
|
|
async function batchSearch(queries, k = 10) {
|
|
const promises = queries.map(query =>
|
|
db.searchAsync(new Float32Array(query), k)
|
|
);
|
|
return await Promise.all(promises);
|
|
}
|
|
```
|
|
|
|
## Examples
|
|
|
|
Complete examples are available in the [examples](./examples) directory:
|
|
|
|
- **basic.js**: Simple insert and search operations
|
|
- **async.js**: Async/await patterns
|
|
- **typescript.ts**: TypeScript integration
|
|
- **rag-system.js**: RAG implementation
|
|
- **semantic-search.js**: Semantic search engine
|
|
- **benchmark.js**: Performance testing
|
|
|
|
Run examples:
|
|
|
|
```bash
|
|
npm run build
|
|
node examples/basic.js
|
|
node examples/async.js
|
|
ts-node examples/typescript.ts
|
|
```
|
|
|
|
## Integration with router-core
|
|
|
|
`router-ffi` wraps the `router-core` Rust crate, providing:
|
|
|
|
- Full API compatibility with router-core
|
|
- Zero-overhead FFI through NAPI-RS
|
|
- Automatic memory management
|
|
- Thread-safe operations
|
|
- Async runtime integration
|
|
|
|
See [router-core](../router-core) for core implementation details.
|
|
|
|
## Related Crates
|
|
|
|
- **[router-core](../router-core)**: Core vector database engine
|
|
- **[router-cli](../router-cli)**: Command-line interface
|
|
- **[router-wasm](../router-wasm)**: WebAssembly bindings
|
|
- **[ruvector-node](../ruvector-node)**: Node.js bindings for ruvector-core
|
|
|
|
## Contributing
|
|
|
|
Contributions are welcome! See [CONTRIBUTING.md](../../docs/development/CONTRIBUTING.md) for guidelines.
|
|
|
|
### Development Setup
|
|
|
|
```bash
|
|
# Clone repository
|
|
git clone https://github.com/ruvnet/ruvector.git
|
|
cd ruvector/crates/router-ffi
|
|
|
|
# Install dependencies
|
|
npm install
|
|
|
|
# Build in development mode
|
|
npm run build:debug
|
|
|
|
# Run tests
|
|
npm test
|
|
|
|
# Format code
|
|
cargo fmt --all
|
|
|
|
# Lint
|
|
cargo clippy --all -- -D warnings
|
|
```
|
|
|
|
### Testing
|
|
|
|
```bash
|
|
# Run all tests
|
|
npm test
|
|
|
|
# Run specific test
|
|
npm test -- --grep "search"
|
|
|
|
# Run benchmarks
|
|
npm run bench
|
|
```
|
|
|
|
## License
|
|
|
|
**MIT License** - see [LICENSE](../../LICENSE) for details.
|
|
|
|
## Acknowledgments
|
|
|
|
Built with cutting-edge technologies:
|
|
|
|
- **[NAPI-RS](https://napi.rs)**: High-performance Rust bindings for Node.js
|
|
- **[router-core](../router-core)**: Core vector database engine
|
|
- **[Tokio](https://tokio.rs)**: Asynchronous runtime for Rust
|
|
- **[SimSIMD](https://github.com/ashvardanian/simsimd)**: SIMD-accelerated similarity metrics
|
|
- **[HNSW](https://arxiv.org/abs/1603.09320)**: Hierarchical Navigable Small World graphs
|
|
|
|
## Support
|
|
|
|
- **Documentation**: [github.com/ruvnet/ruvector](https://github.com/ruvnet/ruvector)
|
|
- **Issues**: [GitHub Issues](https://github.com/ruvnet/ruvector/issues)
|
|
- **Discord**: [Join our community](https://discord.gg/ruvnet)
|
|
- **Twitter**: [@ruvnet](https://twitter.com/ruvnet)
|
|
- **Enterprise**: [enterprise@ruv.io](mailto:enterprise@ruv.io)
|
|
|
|
---
|
|
|
|
<div align="center">
|
|
|
|
**Built by [rUv](https://ruv.io) • Part of the [Ruvector](https://github.com/ruvnet/ruvector) ecosystem**
|
|
|
|
[](https://github.com/ruvnet/ruvector)
|
|
[](https://twitter.com/ruvnet)
|
|
|
|
</div>
|