Merge pull request #91 from ruvnet/cleanup/remove-duplicate-npm-ruvector

chore: remove duplicate npm/ruvector directory
This commit is contained in:
rUv 2025-12-30 14:29:28 -05:00 committed by GitHub
commit 598e2a184c
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
13 changed files with 0 additions and 3047 deletions

View file

@ -1,49 +0,0 @@
# Source files
src/
*.ts
!*.d.ts
# Build config
tsconfig.json
tsconfig.*.json
.tsup/
# Development
node_modules/
.git/
.github/
.gitignore
examples/
# Test files
*.test.js
*.test.ts
*.spec.js
*.spec.ts
test-*.js
coverage/
# Logs and temp files
*.log
*.tmp
.DS_Store
.cache/
*.tsbuildinfo
# CI/CD
.travis.yml
.gitlab-ci.yml
azure-pipelines.yml
.circleci/
# Documentation (keep README.md)
docs/
*.md
!README.md
# Editor
.vscode/
.idea/
*.swp
*.swo
*~

View file

@ -1,707 +0,0 @@
# RuVector
[![MIT License](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT)
[![npm](https://img.shields.io/npm/v/ruvector.svg)](https://www.npmjs.com/package/ruvector)
[![npm downloads](https://img.shields.io/npm/dm/ruvector.svg)](https://www.npmjs.com/package/ruvector)
[![TypeScript](https://img.shields.io/badge/TypeScript-Ready-blue.svg)](https://www.typescriptlang.org/)
[![Node.js](https://img.shields.io/badge/Node.js-16+-green.svg)](https://nodejs.org/)
**A distributed vector database that learns.** Store embeddings, query with Cypher, scale horizontally, and let the index improve itself through Graph Neural Networks.
```bash
npx ruvector
```
> **All-in-One Package**: The `ruvector` package includes everything — vector search, graph queries, GNN layers, AI agent routing, and WASM support. No additional packages needed.
## Why RuVector?
Traditional vector databases just store and search. When you ask "find similar items," they return results but never get smarter. They can't handle complex relationships. They don't optimize your AI costs.
**RuVector is built for the agentic AI era:**
| Challenge | RuVector Solution |
|-----------|-------------------|
| RAG retrieval quality plateaus | **Self-learning GNN** improves results over time |
| Knowledge graphs need separate DB | **Cypher queries** built-in (Neo4j syntax) |
| LLM costs spiral out of control | **AI Router** sends simple queries to cheaper models |
| Memory usage explodes at scale | **Adaptive compression** (2-32x reduction) |
| Can't run AI in the browser | **Full WASM support** for client-side inference |
## Quick Start
### Installation
```bash
# Install the package
npm install ruvector
# Or try instantly without installing
npx ruvector
# With yarn
yarn add ruvector
# With pnpm
pnpm add ruvector
```
### Basic Vector Search
```javascript
const { VectorDB } = require('ruvector');
// Create a vector database (384 = OpenAI ada-002 dimensions)
const db = new VectorDB(384);
// Insert vectors with metadata
await db.insert('doc1', embedding1, {
title: 'Introduction to AI',
category: 'tech',
date: '2024-01-15'
});
// Semantic search
const results = await db.search(queryEmbedding, 10);
// Filter by metadata
const filtered = await db.search(queryEmbedding, 10, {
category: 'tech',
date: { $gte: '2024-01-01' }
});
```
### RAG (Retrieval-Augmented Generation)
```javascript
const { VectorDB } = require('ruvector');
const OpenAI = require('openai');
const db = new VectorDB(1536); // text-embedding-3-small dimensions
const openai = new OpenAI();
// Index your documents
async function indexDocument(doc) {
const embedding = await openai.embeddings.create({
model: 'text-embedding-3-small',
input: doc.content
});
await db.insert(doc.id, embedding.data[0].embedding, {
title: doc.title,
content: doc.content
});
}
// RAG query
async function ragQuery(question) {
// 1. Embed the question
const questionEmb = await openai.embeddings.create({
model: 'text-embedding-3-small',
input: question
});
// 2. Retrieve relevant context
const context = await db.search(questionEmb.data[0].embedding, 5);
// 3. Generate answer with context
const response = await openai.chat.completions.create({
model: 'gpt-4-turbo',
messages: [{
role: 'user',
content: `Context:\n${context.map(c => c.metadata.content).join('\n\n')}
Question: ${question}
Answer based only on the context above:`
}]
});
return response.choices[0].message.content;
}
```
### Knowledge Graphs (Cypher)
```javascript
const { GraphDB } = require('ruvector');
const graph = new GraphDB();
// Create entities and relationships
graph.execute(`
CREATE (alice:Person {name: 'Alice', role: 'Engineer'})
CREATE (bob:Person {name: 'Bob', role: 'Manager'})
CREATE (techcorp:Company {name: 'TechCorp', industry: 'AI'})
CREATE (alice)-[:WORKS_AT {since: 2022}]->(techcorp)
CREATE (bob)-[:WORKS_AT {since: 2020}]->(techcorp)
CREATE (alice)-[:REPORTS_TO]->(bob)
`);
// Query relationships
const team = graph.execute(`
MATCH (p:Person)-[:WORKS_AT]->(c:Company {name: 'TechCorp'})
RETURN p.name, p.role
`);
// Find paths
const chain = graph.execute(`
MATCH path = (a:Person {name: 'Alice'})-[:REPORTS_TO*1..3]->(manager)
RETURN path
`);
// Combine with vector search
const similarPeople = graph.execute(`
MATCH (p:Person)
WHERE vector.similarity(p.embedding, $queryEmbedding) > 0.8
RETURN p ORDER BY vector.similarity(p.embedding, $queryEmbedding) DESC
LIMIT 10
`);
```
### GNN-Enhanced Search (Self-Learning)
```javascript
const { GNNLayer, VectorDB } = require('ruvector');
// Create GNN layer for query enhancement
const gnn = new GNNLayer(384, 512, 4); // input_dim, output_dim, num_heads
// The GNN learns from your search patterns
async function enhancedSearch(query) {
// Get initial results
const neighbors = await db.search(query, 20);
// Compute attention weights based on user clicks/relevance
const weights = computeRelevanceWeights(neighbors);
// GNN enhances the query using graph structure
const enhancedQuery = gnn.forward(query,
neighbors.map(n => n.embedding),
weights
);
// Re-rank with enhanced understanding
return db.search(enhancedQuery, 10);
}
// Train on user feedback
gnn.train({
queries: historicalQueries,
clicks: userClickData,
relevance: expertLabels
}, { epochs: 100 });
```
### AI Agent Routing (Tiny Dancer)
Route queries to the optimal LLM based on complexity — save 60-80% on API costs:
```javascript
const { Router } = require('ruvector');
const router = new Router({
confidenceThreshold: 0.85,
maxUncertainty: 0.15,
enableCircuitBreaker: true
});
// Define your model candidates
const models = [
{ id: 'gpt-4-turbo', embedding: gpt4Emb, cost: 0.03, quality: 0.95 },
{ id: 'gpt-3.5-turbo', embedding: gpt35Emb, cost: 0.002, quality: 0.80 },
{ id: 'claude-3-haiku', embedding: haikuEmb, cost: 0.001, quality: 0.75 },
{ id: 'llama-3-8b', embedding: llamaEmb, cost: 0.0005, quality: 0.70 }
];
async function smartComplete(prompt) {
const promptEmb = await embed(prompt);
// Router decides optimal model
const decision = router.route(promptEmb, models);
console.log(`Routing to ${decision.candidateId} (confidence: ${decision.confidence})`);
// Output: "Routing to gpt-3.5-turbo (confidence: 0.92)"
// Call the selected model
return callModel(decision.candidateId, prompt);
}
```
### Compression (2-32x Memory Savings)
```javascript
const { compress, decompress, CompressionTier } = require('ruvector');
// Automatic tier selection
const auto = compress(embedding, 0.3); // 30% quality threshold
// Explicit tiers
const f16 = compress(embedding, CompressionTier.F16); // 2x compression
const pq8 = compress(embedding, CompressionTier.PQ8); // 8x compression
const pq4 = compress(embedding, CompressionTier.PQ4); // 16x compression
const binary = compress(embedding, CompressionTier.Binary); // 32x compression
// Adaptive tiering based on access frequency
db.enableAdaptiveCompression({
hotThreshold: 0.8, // Keep hot data in f32
warmThreshold: 0.4, // Compress to f16
coldThreshold: 0.1, // Compress to PQ8
archiveThreshold: 0.01 // Compress to binary
});
```
## CLI Usage
```bash
# Show system info and backend status
npx ruvector info
# Initialize a new index
npx ruvector init my-index --dimension 384 --type hnsw
# Insert vectors from JSON/JSONL
npx ruvector insert my-index vectors.json
npx ruvector insert my-index vectors.jsonl --format jsonl
# Search with a query
npx ruvector search my-index --query "[0.1, 0.2, ...]" -k 10
npx ruvector search my-index --text "machine learning" -k 10 # Auto-embed
# Show index statistics
npx ruvector stats my-index
# Run performance benchmarks
npx ruvector benchmark --dimension 384 --num-vectors 10000
# Export/import
npx ruvector export my-index backup.bin
npx ruvector import backup.bin restored-index
```
## Self-Learning Hooks (Claude Code Integration)
RuVector includes a self-learning intelligence layer that improves AI agent decisions over time. These hooks integrate with Claude Code and other AI development tools.
### Setup
```bash
# Initialize hooks in your project
npx ruvector hooks init
```
### Hook Commands
```bash
# Session Management
ruvector hooks session-start # Start session tracking
ruvector hooks session-end # End session with export
# Pre/Post Edit Hooks
ruvector hooks pre-edit <file> # Get agent suggestions before editing
ruvector hooks post-edit <file> --success # Record edit outcomes
# Pre/Post Command Hooks
ruvector hooks pre-command "cargo test" # Analyze command before running
ruvector hooks post-command "cargo test" --success # Record command outcomes
# Intelligence
ruvector hooks stats # Show learning statistics
ruvector hooks route <task> # Get agent routing suggestion
ruvector hooks suggest-context # Get context suggestions
# Memory
ruvector hooks remember <content> -t <type> # Store in vector memory
ruvector hooks recall <query> # Semantic search memory
```
### How It Works
The intelligence system uses:
- **Q-Learning**: Learns optimal agent routing from past successes/failures
- **Vector Memory**: Semantic storage with cosine similarity search
- **File Sequences**: Predicts related files based on edit patterns
- **Error Patterns**: Remembers fixes for common errors
### Example Output
```
🧠 Intelligence Analysis:
📁 ruvector-core/lib.rs
🤖 Recommended: rust-developer (80% confidence)
→ learned from past success
📚 Similar: 3 past edits
📎 Related: mod.rs, tests.rs
💬 ⚡ Core lib: run cargo test --lib after changes
```
### Claude Code Integration
Add to your `.claude/settings.json`:
```json
{
"hooks": {
"PreToolUse": [{ "command": "ruvector hooks pre-edit $file" }],
"PostToolUse": [{ "command": "ruvector hooks post-edit $file --success" }],
"SessionStart": [{ "command": "ruvector hooks session-start" }],
"Stop": [{ "command": "ruvector hooks session-end" }]
}
}
```
### Learning Data
| Storage | Contents |
|---------|----------|
| `.ruvector/intelligence.json` | Q-table, memories, trajectories |
| Patterns | State-action values for agent routing |
| Memories | Vector embeddings for semantic recall |
| Trajectories | Learning history for continuous improvement |
## Integrations
### LangChain
```javascript
const { RuVectorStore } = require('ruvector/langchain');
const { OpenAIEmbeddings } = require('@langchain/openai');
const vectorStore = new RuVectorStore(
new OpenAIEmbeddings(),
{ dimension: 1536 }
);
await vectorStore.addDocuments(documents);
const results = await vectorStore.similaritySearch("query", 5);
```
### LlamaIndex
```javascript
const { RuVectorIndex } = require('ruvector/llamaindex');
const index = new RuVectorIndex({
dimension: 384,
enableGNN: true
});
await index.insert(documents);
const queryEngine = index.asQueryEngine();
const response = await queryEngine.query("What is machine learning?");
```
### OpenAI / Anthropic
```javascript
const { createEmbedder } = require('ruvector');
// OpenAI
const openaiEmbed = createEmbedder('openai', {
model: 'text-embedding-3-small'
});
// Anthropic (via Voyage)
const anthropicEmbed = createEmbedder('voyage', {
model: 'voyage-2'
});
// Cohere
const cohereEmbed = createEmbedder('cohere', {
model: 'embed-english-v3.0'
});
```
## Benchmarks
| Operation | Dimensions | Time | Throughput |
|-----------|------------|------|------------|
| **HNSW Search (k=10)** | 384 | 61µs | 16,400 QPS |
| **HNSW Search (k=100)** | 384 | 164µs | 6,100 QPS |
| **Cosine Similarity** | 1536 | 143ns | 7M ops/sec |
| **Dot Product** | 384 | 33ns | 30M ops/sec |
| **Insert** | 384 | 20µs | 50,000/sec |
| **GNN Forward** | 384→512 | 89µs | 11,200/sec |
| **Compression (PQ8)** | 384 | 12µs | 83,000/sec |
Run your own benchmarks:
```bash
npx ruvector benchmark --dimension 384 --num-vectors 100000
```
## Comparison
| Feature | RuVector | Pinecone | Qdrant | ChromaDB | Milvus | Weaviate |
|---------|----------|----------|--------|----------|--------|----------|
| **Latency (p50)** | **61µs** | ~2ms | ~1ms | ~50ms | ~5ms | ~3ms |
| **Graph Queries** | ✅ Cypher | ❌ | ❌ | ❌ | ❌ | ✅ GraphQL |
| **Self-Learning** | ✅ GNN | ❌ | ❌ | ❌ | ❌ | ❌ |
| **AI Routing** | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ |
| **Browser/WASM** | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ |
| **Compression** | 2-32x | ❌ | ✅ | ❌ | ✅ | ✅ |
| **Hybrid Search** | ✅ | ✅ | ✅ | ❌ | ✅ | ✅ |
| **Multi-tenancy** | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
| **Open Source** | ✅ MIT | ❌ | ✅ Apache | ✅ Apache | ✅ Apache | ✅ BSD |
| **Pricing** | Free | $70+/mo | Free | Free | Free | Free |
## npm Packages
| Package | Description |
|---------|-------------|
| [`ruvector`](https://www.npmjs.com/package/ruvector) | **All-in-one package (recommended)** |
| [`@ruvector/wasm`](https://www.npmjs.com/package/@ruvector/wasm) | Browser/WASM bindings |
| [`@ruvector/graph`](https://www.npmjs.com/package/@ruvector/graph) | Graph database with Cypher |
| [`@ruvector/gnn`](https://www.npmjs.com/package/@ruvector/gnn) | Graph Neural Network layers |
| [`@ruvector/tiny-dancer`](https://www.npmjs.com/package/@ruvector/tiny-dancer) | AI agent routing (FastGRNN) |
| [`@ruvector/router`](https://www.npmjs.com/package/@ruvector/router) | Semantic routing engine |
```bash
# Install all-in-one (recommended)
npm install ruvector
# Or install specific packages
npm install @ruvector/graph @ruvector/gnn
```
## API Reference
### VectorDB
```typescript
class VectorDB {
constructor(dimension: number, options?: VectorDBOptions);
// CRUD operations
insert(id: string, values: number[], metadata?: object): Promise<void>;
insertBatch(vectors: Vector[], options?: BatchOptions): Promise<void>;
get(id: string): Promise<Vector | null>;
update(id: string, values?: number[], metadata?: object): Promise<void>;
delete(id: string): Promise<boolean>;
// Search
search(query: number[], k?: number, filter?: Filter): Promise<SearchResult[]>;
hybridSearch(query: number[], text: string, k?: number): Promise<SearchResult[]>;
// Persistence
save(path: string): Promise<void>;
static load(path: string): Promise<VectorDB>;
// Management
stats(): Promise<IndexStats>;
optimize(): Promise<void>;
clear(): Promise<void>;
}
```
### GraphDB
```typescript
class GraphDB {
constructor(options?: GraphDBOptions);
// Cypher execution
execute(cypher: string, params?: object): QueryResult;
// Direct API
createNode(label: string, properties: object): string;
createRelationship(from: string, to: string, type: string, props?: object): void;
createHyperedge(nodeIds: string[], type: string, props?: object): string;
// Traversal
shortestPath(from: string, to: string): Path | null;
neighbors(nodeId: string, depth?: number): Node[];
}
```
### GNNLayer
```typescript
class GNNLayer {
constructor(inputDim: number, outputDim: number, numHeads: number);
// Inference
forward(query: number[], neighbors: number[][], weights: number[]): number[];
// Training
train(data: TrainingData, config?: TrainingConfig): TrainingMetrics;
save(path: string): void;
static load(path: string): GNNLayer;
}
```
### Router
```typescript
class Router {
constructor(config?: RouterConfig);
// Routing
route(query: number[], candidates: Candidate[]): RoutingDecision;
routeBatch(queries: number[][], candidates: Candidate[]): RoutingDecision[];
// Management
reloadModel(): void;
circuitBreakerStatus(): 'closed' | 'open' | 'half-open';
resetCircuitBreaker(): void;
}
```
## Use Cases
### Agentic AI / Multi-Agent Systems
```javascript
// Route tasks to specialized agents
const agents = [
{ id: 'researcher', embedding: researchEmb, capabilities: ['search', 'summarize'] },
{ id: 'coder', embedding: codeEmb, capabilities: ['code', 'debug'] },
{ id: 'analyst', embedding: analysisEmb, capabilities: ['data', 'visualize'] }
];
const taskEmb = await embed("Write a Python script to analyze sales data");
const decision = router.route(taskEmb, agents);
// Routes to 'coder' agent with high confidence
```
### Recommendation Systems
```javascript
const recommendations = graph.execute(`
MATCH (user:User {id: $userId})-[:VIEWED]->(item:Product)
MATCH (item)-[:SIMILAR_TO]->(rec:Product)
WHERE NOT (user)-[:VIEWED]->(rec)
AND vector.similarity(rec.embedding, $userPreference) > 0.7
RETURN rec
ORDER BY vector.similarity(rec.embedding, $userPreference) DESC
LIMIT 10
`);
```
### Semantic Caching
```javascript
const cache = new VectorDB(1536);
async function cachedLLMCall(prompt) {
const promptEmb = await embed(prompt);
// Check semantic cache
const cached = await cache.search(promptEmb, 1);
if (cached[0]?.score > 0.95) {
return cached[0].metadata.response; // Cache hit
}
// Cache miss - call LLM
const response = await llm.complete(prompt);
await cache.insert(generateId(), promptEmb, { prompt, response });
return response;
}
```
### Document Q&A with Sources
```javascript
async function qaWithSources(question) {
const results = await db.search(await embed(question), 5);
const answer = await llm.complete({
prompt: `Answer based on these sources:\n${results.map(r =>
`[${r.id}] ${r.metadata.content}`
).join('\n')}\n\nQuestion: ${question}`,
});
return {
answer,
sources: results.map(r => ({
id: r.id,
title: r.metadata.title,
relevance: r.score
}))
};
}
```
## Architecture
```
┌──────────────────────────────────────────────────────────────┐
│ ruvector │
│ (All-in-One npm Package) │
├──────────────┬──────────────┬──────────────┬─────────────────┤
│ VectorDB │ GraphDB │ GNNLayer │ Router │
│ (Search) │ (Cypher) │ (ML) │ (AI Routing) │
├──────────────┴──────────────┴──────────────┴─────────────────┤
│ Rust Core Engine │
│ • HNSW Index • Cypher Parser • Attention • FastGRNN │
│ • SIMD Ops • Hyperedges • Training • Uncertainty │
└──────────────────────────────────────────────────────────────┘
┌──────────────────┼──────────────────┐
│ │ │
┌────▼────┐ ┌────▼────┐ ┌────▼────┐
│ Native │ │ WASM │ │ FFI │
│(napi-rs)│ │(wasm32) │ │ (C) │
└─────────┘ └─────────┘ └─────────┘
│ │ │
┌────▼────┐ ┌────▼────┐ ┌────▼────┐
│ Node.js │ │ Browser │ │ Python │
│ Bun │ │ Deno │ │ Go │
└─────────┘ └─────────┘ └─────────┘
```
## Platform Support
| Platform | Backend | Installation |
|----------|---------|--------------|
| **Node.js 16+** | Native (napi-rs) | `npm install ruvector` |
| **Node.js (fallback)** | WASM | Automatic if native fails |
| **Bun** | Native | `bun add ruvector` |
| **Deno** | WASM | `import from "npm:ruvector"` |
| **Browser** | WASM | `npm install @ruvector/wasm` |
| **Cloudflare Workers** | WASM | `npm install @ruvector/wasm` |
| **Vercel Edge** | WASM | `npm install @ruvector/wasm` |
## Documentation
- [Getting Started Guide](https://github.com/ruvnet/ruvector/blob/main/docs/guide/GETTING_STARTED.md)
- [Cypher Reference](https://github.com/ruvnet/ruvector/blob/main/docs/api/CYPHER_REFERENCE.md)
- [GNN Architecture](https://github.com/ruvnet/ruvector/blob/main/docs/gnn-layer-implementation.md)
- [Performance Tuning](https://github.com/ruvnet/ruvector/blob/main/docs/optimization/PERFORMANCE_TUNING_GUIDE.md)
- [API Reference](https://github.com/ruvnet/ruvector/tree/main/docs/api)
## Contributing
```bash
# Clone repository
git clone https://github.com/ruvnet/ruvector.git
cd ruvector
# Install dependencies
npm install
# Run tests
npm test
# Build
npm run build
# Benchmarks
npm run bench
```
See [CONTRIBUTING.md](https://github.com/ruvnet/ruvector/blob/main/docs/development/CONTRIBUTING.md) for guidelines.
## License
MIT License — free for commercial and personal use.
---
<div align="center">
**Built by [rUv](https://ruv.io)** • [GitHub](https://github.com/ruvnet/ruvector) • [npm](https://npmjs.com/package/ruvector)
*Vector search that gets smarter over time.*
**[⭐ Star on GitHub](https://github.com/ruvnet/ruvector)** if RuVector helps your project!
</div>

File diff suppressed because it is too large Load diff

View file

@ -1,77 +0,0 @@
/**
* Advanced search features example
*/
const { VectorIndex, Utils } = require('ruvector');
async function main() {
console.log('🔍 Advanced Search Example\n');
// Create index
const index = new VectorIndex({
dimension: 128,
metric: 'cosine',
indexType: 'hnsw'
});
// Insert vectors with rich metadata
console.log('Inserting documents...');
const documents = [
{ id: 'doc1', category: 'tech', tags: ['ai', 'ml'] },
{ id: 'doc2', category: 'tech', tags: ['web', 'javascript'] },
{ id: 'doc3', category: 'science', tags: ['physics', 'quantum'] },
{ id: 'doc4', category: 'science', tags: ['biology', 'dna'] },
{ id: 'doc5', category: 'business', tags: ['finance', 'stocks'] }
];
const vectors = documents.map(doc => ({
id: doc.id,
values: Utils.randomVector(128),
metadata: doc
}));
await index.insertBatch(vectors);
// Perform different types of searches
const query = Utils.randomVector(128);
console.log('\n1. Basic search (top 3):');
const basic = await index.search(query, { k: 3 });
basic.forEach((r, i) => {
console.log(` ${i + 1}. ${r.id} - ${r.metadata.category} (${r.score.toFixed(4)})`);
});
console.log('\n2. Search with HNSW tuning (higher accuracy):');
const accurate = await index.search(query, { k: 3, ef: 100 });
accurate.forEach((r, i) => {
console.log(` ${i + 1}. ${r.id} - ${r.metadata.category} (${r.score.toFixed(4)})`);
});
// Calculate similarities manually
console.log('\n3. Manual similarity calculation:');
const vec1 = Utils.randomVector(128);
const vec2 = Utils.randomVector(128);
const similarity = Utils.cosineSimilarity(vec1, vec2);
const distance = Utils.euclideanDistance(vec1, vec2);
console.log(` Cosine similarity: ${similarity.toFixed(4)}`);
console.log(` Euclidean distance: ${distance.toFixed(4)}`);
// Get specific vector
console.log('\n4. Get vector by ID:');
const retrieved = await index.get('doc1');
if (retrieved) {
console.log(` Retrieved: ${retrieved.id}`);
console.log(` Metadata:`, retrieved.metadata);
console.log(` Vector dimension: ${retrieved.values.length}`);
}
// Delete and verify
console.log('\n5. Delete operation:');
const deleted = await index.delete('doc5');
console.log(` Deleted doc5: ${deleted}`);
const statsAfter = await index.stats();
console.log(` Vectors remaining: ${statsAfter.vectorCount}`);
}
main().catch(console.error);

View file

@ -1,81 +0,0 @@
/**
* Basic usage example for rUvector
*/
const { VectorIndex, Utils, getBackendInfo } = require('ruvector');
async function main() {
console.log('🚀 rUvector Basic Usage Example\n');
// Show backend info
const info = getBackendInfo();
console.log(`Backend: ${info.type} (${info.version})`);
console.log(`Features: ${info.features.join(', ')}\n`);
// Create a new index
console.log('Creating index...');
const index = new VectorIndex({
dimension: 384,
metric: 'cosine',
indexType: 'hnsw',
hnswConfig: {
m: 16,
efConstruction: 200
}
});
// Insert some vectors
console.log('Inserting vectors...');
const vectors = [];
for (let i = 0; i < 1000; i++) {
vectors.push({
id: `doc_${i}`,
values: Utils.randomVector(384),
metadata: {
title: `Document ${i}`,
category: i % 5 === 0 ? 'important' : 'normal'
}
});
}
await index.insertBatch(vectors, {
batchSize: 100,
progressCallback: (progress) => {
process.stdout.write(`\rProgress: ${(progress * 100).toFixed(1)}%`);
}
});
console.log('\n');
// Get stats
const stats = await index.stats();
console.log('Index stats:', {
vectors: stats.vectorCount,
dimension: stats.dimension,
type: stats.indexType
});
console.log();
// Search
console.log('Searching...');
const query = Utils.randomVector(384);
const results = await index.search(query, { k: 5 });
console.log('\nTop 5 results:');
results.forEach((result, i) => {
console.log(` ${i + 1}. ${result.id} (score: ${result.score.toFixed(4)})`);
console.log(` metadata: ${JSON.stringify(result.metadata)}`);
});
// Save index
console.log('\nSaving index...');
await index.save('my-index.bin');
console.log('✓ Index saved to my-index.bin');
// Load and verify
console.log('\nLoading index...');
const loadedIndex = await VectorIndex.load('my-index.bin');
const loadedStats = await loadedIndex.stats();
console.log('✓ Index loaded, vectors:', loadedStats.vectorCount);
}
main().catch(console.error);

View file

@ -1,123 +0,0 @@
/**
* Performance benchmark example
*/
const { VectorIndex, Utils, getBackendInfo } = require('ruvector');
function formatNumber(num) {
return num.toLocaleString();
}
function formatDuration(ms) {
return ms >= 1000 ? `${(ms / 1000).toFixed(2)}s` : `${ms.toFixed(2)}ms`;
}
async function runBenchmark(dimension, numVectors, numQueries) {
console.log(`\n📊 Benchmark: dim=${dimension}, vectors=${formatNumber(numVectors)}, queries=${numQueries}`);
console.log('─'.repeat(70));
// Create index
const index = new VectorIndex({
dimension,
metric: 'cosine',
indexType: 'hnsw',
hnswConfig: { m: 16, efConstruction: 200 }
});
// Generate vectors
console.log('Generating vectors...');
const vectors = Array.from({ length: numVectors }, (_, i) => ({
id: `vec_${i}`,
values: Utils.randomVector(dimension),
metadata: { index: i }
}));
// Benchmark insertions
console.log('Benchmarking insertions...');
const insertStart = performance.now();
await index.insertBatch(vectors, { batchSize: 1000 });
const insertDuration = performance.now() - insertStart;
const insertThroughput = numVectors / (insertDuration / 1000);
console.log(` ✓ Inserted ${formatNumber(numVectors)} vectors in ${formatDuration(insertDuration)}`);
console.log(` ✓ Throughput: ${formatNumber(Math.round(insertThroughput))} vectors/sec`);
// Benchmark searches
console.log('\nBenchmarking searches...');
const queries = Array.from({ length: numQueries }, () => Utils.randomVector(dimension));
const searchStart = performance.now();
const results = await Promise.all(
queries.map(q => index.search(q, { k: 10 }))
);
const searchDuration = performance.now() - searchStart;
const searchThroughput = numQueries / (searchDuration / 1000);
console.log(` ✓ Executed ${numQueries} searches in ${formatDuration(searchDuration)}`);
console.log(` ✓ Throughput: ${formatNumber(Math.round(searchThroughput))} queries/sec`);
console.log(` ✓ Avg latency: ${formatDuration(searchDuration / numQueries)}`);
// Check recall (verify we get results)
const avgResults = results.reduce((sum, r) => sum + r.length, 0) / results.length;
console.log(` ✓ Avg results per query: ${avgResults.toFixed(2)}`);
// Get memory stats
const stats = await index.stats();
if (stats.memoryUsage) {
const mb = (stats.memoryUsage / 1024 / 1024).toFixed(2);
console.log(` ✓ Memory usage: ${mb} MB`);
}
return {
dimension,
numVectors,
insertDuration,
insertThroughput,
searchDuration,
searchThroughput,
avgLatency: searchDuration / numQueries
};
}
async function main() {
console.log('⚡ rUvector Performance Benchmark\n');
const info = getBackendInfo();
console.log(`Backend: ${info.type}`);
console.log(`Features: ${info.features.join(', ')}`);
// Run benchmarks with different configurations
const configs = [
{ dimension: 128, vectors: 1000, queries: 100 },
{ dimension: 384, vectors: 5000, queries: 100 },
{ dimension: 768, vectors: 10000, queries: 100 },
{ dimension: 1536, vectors: 5000, queries: 100 }
];
const results = [];
for (const config of configs) {
const result = await runBenchmark(config.dimension, config.vectors, config.queries);
results.push(result);
}
// Summary
console.log('\n' + '═'.repeat(70));
console.log('Summary');
console.log('═'.repeat(70));
console.log('\nInsert Throughput:');
results.forEach(r => {
console.log(` dim=${r.dimension}: ${formatNumber(Math.round(r.insertThroughput))} vectors/sec`);
});
console.log('\nSearch Throughput:');
results.forEach(r => {
console.log(` dim=${r.dimension}: ${formatNumber(Math.round(r.searchThroughput))} queries/sec`);
});
console.log('\nSearch Latency:');
results.forEach(r => {
console.log(` dim=${r.dimension}: ${formatDuration(r.avgLatency)}`);
});
}
main().catch(console.error);

View file

@ -1,122 +0,0 @@
{
"name": "ruvector",
"version": "0.1.38",
"description": "High-performance vector database with Graph Neural Networks, Cypher queries, and AI agent routing. Build RAG apps, semantic search, recommendations, and agentic AI systems. Pinecone + Neo4j + PyTorch alternative.",
"main": "./dist/index.js",
"types": "./dist/index.d.ts",
"bin": {
"ruvector": "./bin/ruvector.js"
},
"exports": {
".": {
"types": "./dist/index.d.ts",
"require": "./dist/index.js",
"import": "./dist/index.mjs"
}
},
"files": [
"dist",
"bin",
"README.md"
],
"scripts": {
"build": "tsup src/index.ts --format cjs,esm --dts --clean",
"dev": "tsup src/index.ts --format cjs,esm --dts --watch",
"typecheck": "tsc --noEmit",
"prepublishOnly": "echo 'Ready to publish'"
},
"keywords": [
"vector-database",
"vector-search",
"embeddings",
"similarity-search",
"semantic-search",
"rag",
"retrieval-augmented-generation",
"llm",
"langchain",
"openai",
"gpt",
"claude",
"anthropic",
"ai",
"artificial-intelligence",
"machine-learning",
"deep-learning",
"neural-network",
"gnn",
"graph-neural-network",
"knowledge-graph",
"graph-database",
"cypher",
"neo4j",
"hnsw",
"ann",
"approximate-nearest-neighbor",
"knn",
"cosine-similarity",
"recommendation-system",
"chatbot",
"conversational-ai",
"agentic-ai",
"ai-agents",
"multi-agent",
"agent-routing",
"model-router",
"llm-router",
"rust",
"napi",
"napi-rs",
"wasm",
"webassembly",
"compression",
"quantization",
"product-quantization",
"pinecone-alternative",
"chromadb-alternative",
"milvus-alternative",
"qdrant-alternative",
"weaviate-alternative"
],
"author": {
"name": "rUv",
"url": "https://ruv.io"
},
"license": "MIT",
"homepage": "https://github.com/ruvnet/ruvector#readme",
"repository": {
"type": "git",
"url": "git+https://github.com/ruvnet/ruvector.git",
"directory": "npm/ruvector"
},
"bugs": {
"url": "https://github.com/ruvnet/ruvector/issues"
},
"funding": {
"type": "github",
"url": "https://github.com/sponsors/ruvnet"
},
"dependencies": {
"commander": "^11.1.0",
"chalk": "^4.1.2",
"ora": "^5.4.1",
"cli-table3": "^0.6.3",
"inquirer": "^8.2.6"
},
"optionalDependencies": {
"@ruvector/core": "^0.1.1",
"@ruvector/graph-node": "^0.1.0",
"@ruvector/graph-wasm": "^0.1.0",
"@ruvector/gnn-node": "^0.1.0",
"@ruvector/gnn-wasm": "^0.1.0"
},
"devDependencies": {
"@types/node": "^20.10.0",
"@types/inquirer": "^8.2.10",
"typescript": "^5.3.3",
"tsup": "^8.0.0"
},
"engines": {
"node": ">=16.0.0"
}
}

View file

@ -1,221 +0,0 @@
/**
* rUvector - High-performance vector database
*
* Smart loader that tries native bindings first, falls back to WASM
*/
import type {
Vector,
SearchResult,
IndexStats,
CreateIndexOptions,
SearchOptions,
BatchInsertOptions,
BackendInfo
} from '../types';
let backend: any;
let backendType: 'native' | 'wasm' = 'wasm';
/**
* Try to load the native backend first, fall back to WASM
*/
function loadBackend() {
if (backend) {
return backend;
}
// Try native bindings first
try {
backend = require('@ruvector/core');
backendType = 'native';
console.log('✓ Loaded native rUvector bindings');
return backend;
} catch (e) {
// Native not available, try WASM
try {
backend = require('@ruvector/wasm');
backendType = 'wasm';
console.warn('⚠ Native bindings not available, using WASM fallback');
console.warn(' For better performance, install @ruvector/core');
return backend;
} catch (wasmError) {
throw new Error(
'Failed to load rUvector backend. Please ensure either @ruvector/core or @ruvector/wasm is installed.\n' +
`Native error: ${e}\n` +
`WASM error: ${wasmError}`
);
}
}
}
/**
* VectorIndex class that wraps the backend
*/
export class VectorIndex {
private index: any;
constructor(options: CreateIndexOptions) {
const backend = loadBackend();
this.index = new backend.VectorIndex(options);
}
async insert(vector: Vector): Promise<void> {
return this.index.insert(vector);
}
async insertBatch(vectors: Vector[], options?: BatchInsertOptions): Promise<void> {
if (this.index.insertBatch) {
return this.index.insertBatch(vectors, options);
}
// Fallback for backends without batch support
const batchSize = options?.batchSize || 1000;
const total = vectors.length;
for (let i = 0; i < total; i += batchSize) {
const batch = vectors.slice(i, Math.min(i + batchSize, total));
await Promise.all(batch.map(v => this.insert(v)));
if (options?.progressCallback) {
options.progressCallback(Math.min(i + batchSize, total) / total);
}
}
}
async search(query: number[], options?: SearchOptions): Promise<SearchResult[]> {
return this.index.search(query, options);
}
async get(id: string): Promise<Vector | null> {
return this.index.get(id);
}
async delete(id: string): Promise<boolean> {
return this.index.delete(id);
}
async stats(): Promise<IndexStats> {
return this.index.stats();
}
async save(path: string): Promise<void> {
return this.index.save(path);
}
static async load(path: string): Promise<VectorIndex> {
const backend = loadBackend();
const index = await backend.VectorIndex.load(path);
const wrapper = Object.create(VectorIndex.prototype);
wrapper.index = index;
return wrapper;
}
async clear(): Promise<void> {
return this.index.clear();
}
async optimize(): Promise<void> {
if (this.index.optimize) {
return this.index.optimize();
}
// No-op for backends without optimization
}
}
/**
* Utility functions
*/
export const Utils = {
cosineSimilarity(a: number[], b: number[]): number {
if (a.length !== b.length) {
throw new Error('Vectors must have the same dimension');
}
let dotProduct = 0;
let normA = 0;
let normB = 0;
for (let i = 0; i < a.length; i++) {
dotProduct += a[i] * b[i];
normA += a[i] * a[i];
normB += b[i] * b[i];
}
return dotProduct / (Math.sqrt(normA) * Math.sqrt(normB));
},
euclideanDistance(a: number[], b: number[]): number {
if (a.length !== b.length) {
throw new Error('Vectors must have the same dimension');
}
let sum = 0;
for (let i = 0; i < a.length; i++) {
const diff = a[i] - b[i];
sum += diff * diff;
}
return Math.sqrt(sum);
},
normalize(vector: number[]): number[] {
const norm = Math.sqrt(vector.reduce((sum, val) => sum + val * val, 0));
return vector.map(val => val / norm);
},
randomVector(dimension: number): number[] {
const vector = new Array(dimension);
for (let i = 0; i < dimension; i++) {
vector[i] = Math.random() * 2 - 1;
}
return this.normalize(vector);
}
};
/**
* Get backend information
*/
export function getBackendInfo(): BackendInfo {
loadBackend();
const features: string[] = [];
if (backendType === 'native') {
features.push('SIMD', 'Multi-threading', 'Memory-mapped I/O');
} else {
features.push('Browser-compatible', 'No native dependencies');
}
return {
type: backendType,
version: require('../package.json').version,
features
};
}
/**
* Check if native bindings are available
*/
export function isNativeAvailable(): boolean {
try {
require.resolve('@ruvector/core');
return true;
} catch {
return false;
}
}
// Default export
export default VectorIndex;
// Re-export types
export type {
Vector,
SearchResult,
IndexStats,
CreateIndexOptions,
SearchOptions,
BatchInsertOptions,
BackendInfo
};

View file

@ -1,120 +0,0 @@
/**
* Basic test of ruvector package with mock backend
*/
const path = require('path');
const Module = require('module');
// Mock require to return our mock backend
const originalRequire = Module.prototype.require;
const mockBackend = require('./test-mock-backend.js');
Module.prototype.require = function(id) {
if (id === '@ruvector/core' || id === '@ruvector/wasm') {
return mockBackend;
}
return originalRequire.apply(this, arguments);
};
const { VectorIndex, Utils, getBackendInfo, isNativeAvailable } = require('./dist/index.js');
async function testBasicOperations() {
console.log('🧪 Testing Basic Operations\n');
try {
// Test backend info
console.log('1. Backend Info:');
const info = getBackendInfo();
console.log(` Type: ${info.type}`);
console.log(` Version: ${info.version}`);
console.log(` Native Available: ${isNativeAvailable()}`);
console.log(' ✓ Backend info works\n');
// Test index creation
console.log('2. Creating Index:');
const index = new VectorIndex({
dimension: 128,
metric: 'cosine',
indexType: 'hnsw'
});
console.log(' ✓ Index created\n');
// Test single insert
console.log('3. Single Insert:');
await index.insert({
id: 'vec1',
values: Utils.randomVector(128),
metadata: { test: true }
});
console.log(' ✓ Vector inserted\n');
// Test batch insert
console.log('4. Batch Insert:');
const vectors = [];
for (let i = 0; i < 100; i++) {
vectors.push({
id: `vec${i + 2}`,
values: Utils.randomVector(128),
metadata: { index: i }
});
}
await index.insertBatch(vectors, { batchSize: 10 });
console.log(' ✓ Batch inserted\n');
// Test stats
console.log('5. Stats:');
const stats = await index.stats();
console.log(` Vectors: ${stats.vectorCount}`);
console.log(` Dimension: ${stats.dimension}`);
console.log(` Type: ${stats.indexType}`);
console.log(' ✓ Stats retrieved\n');
// Test search
console.log('6. Search:');
const query = Utils.randomVector(128);
const results = await index.search(query, { k: 5 });
console.log(` Found ${results.length} results`);
results.slice(0, 3).forEach((r, i) => {
console.log(` ${i + 1}. ${r.id} (score: ${r.score.toFixed(4)})`);
});
console.log(' ✓ Search works\n');
// Test get
console.log('7. Get by ID:');
const retrieved = await index.get('vec1');
console.log(` Retrieved: ${retrieved ? retrieved.id : 'null'}`);
console.log(' ✓ Get works\n');
// Test delete
console.log('8. Delete:');
const deleted = await index.delete('vec1');
console.log(` Deleted: ${deleted}`);
const statsAfter = await index.stats();
console.log(` Vectors remaining: ${statsAfter.vectorCount}`);
console.log(' ✓ Delete works\n');
// Test utilities
console.log('9. Utilities:');
const v1 = Utils.randomVector(128);
const v2 = Utils.randomVector(128);
const similarity = Utils.cosineSimilarity(v1, v2);
const distance = Utils.euclideanDistance(v1, v2);
const normalized = Utils.normalize(v1);
console.log(` Cosine similarity: ${similarity.toFixed(4)}`);
console.log(` Euclidean distance: ${distance.toFixed(4)}`);
console.log(` Normalized length: ${Math.sqrt(normalized.reduce((s, v) => s + v * v, 0)).toFixed(4)}`);
console.log(' ✓ Utilities work\n');
console.log('✅ All tests passed!');
return true;
} catch (error) {
console.error('❌ Test failed:', error.message);
console.error(error.stack);
return false;
}
}
// Run tests
testBasicOperations().then(success => {
process.exit(success ? 0 : 1);
});

View file

@ -1,114 +0,0 @@
/**
* Test CLI commands with mock backend
*/
const path = require('path');
const Module = require('module');
const fs = require('fs').promises;
// Mock require
const originalRequire = Module.prototype.require;
const mockBackend = require('./test-mock-backend.js');
Module.prototype.require = function(id) {
if (id === '@ruvector/core' || id === '@ruvector/wasm') {
return mockBackend;
}
return originalRequire.apply(this, arguments);
};
async function testCLI() {
console.log('🧪 Testing CLI Commands\n');
try {
// Test 1: Info command
console.log('1. Testing info command:');
const { getBackendInfo } = require('./dist/index.js');
const info = getBackendInfo();
console.log(` ✓ Backend: ${info.type}`);
console.log(` ✓ Version: ${info.version}\n`);
// Test 2: Create test vectors file
console.log('2. Creating test vectors file:');
const testVectors = [];
const { Utils } = require('./dist/index.js');
for (let i = 0; i < 50; i++) {
testVectors.push({
id: `test_${i}`,
values: Utils.randomVector(128),
metadata: { index: i, category: i % 3 === 0 ? 'A' : 'B' }
});
}
await fs.writeFile('/tmp/test-vectors.json', JSON.stringify(testVectors, null, 2));
console.log(` ✓ Created /tmp/test-vectors.json with ${testVectors.length} vectors\n`);
// Test 3: Index initialization
console.log('3. Testing index operations:');
const { VectorIndex } = require('./dist/index.js');
const index = new VectorIndex({
dimension: 128,
metric: 'cosine',
indexType: 'hnsw'
});
console.log(' ✓ Index created\n');
// Test 4: Insert vectors
console.log('4. Testing insertBatch:');
const startInsert = Date.now();
await index.insertBatch(testVectors, {
batchSize: 10,
progressCallback: (p) => {
if (p === 1) console.log(` Progress: 100%`);
}
});
const insertTime = Date.now() - startInsert;
console.log(` ✓ Inserted ${testVectors.length} vectors in ${insertTime}ms\n`);
// Test 5: Search
console.log('5. Testing search:');
const query = Utils.randomVector(128);
const startSearch = Date.now();
const results = await index.search(query, { k: 5 });
const searchTime = Date.now() - startSearch;
console.log(` ✓ Found ${results.length} results in ${searchTime}ms`);
results.slice(0, 3).forEach((r, i) => {
console.log(` ${i + 1}. ${r.id} (score: ${r.score.toFixed(4)})`);
});
console.log();
// Test 6: Stats
console.log('6. Testing stats:');
const stats = await index.stats();
console.log(` ✓ Vectors: ${stats.vectorCount}`);
console.log(` ✓ Dimension: ${stats.dimension}`);
console.log(` ✓ Type: ${stats.indexType}`);
console.log(` ✓ Memory: ${(stats.memoryUsage / 1024).toFixed(2)} KB\n`);
// Test 7: Save/Load
console.log('7. Testing save/load:');
await index.save('/tmp/test-index.bin');
console.log(' ✓ Saved index');
const loaded = await VectorIndex.load('/tmp/test-index.bin');
console.log(' ✓ Loaded index\n');
// Test 8: Performance
console.log('8. Performance summary:');
const insertThroughput = testVectors.length / (insertTime / 1000);
const searchLatency = searchTime;
console.log(` Insert throughput: ${insertThroughput.toFixed(0)} vectors/sec`);
console.log(` Search latency: ${searchLatency.toFixed(2)}ms`);
console.log();
console.log('✅ All CLI tests passed!');
return true;
} catch (error) {
console.error('❌ CLI test failed:', error.message);
console.error(error.stack);
return false;
}
}
testCLI().then(success => {
process.exit(success ? 0 : 1);
});

View file

@ -1,110 +0,0 @@
/**
* Mock backend for testing the main ruvector package
* Simulates both native and WASM backends
*/
class MockVectorIndex {
constructor(options) {
this.options = options;
this.vectors = new Map();
this._stats = {
vectorCount: 0,
dimension: options.dimension,
indexType: options.indexType || 'hnsw',
memoryUsage: 0
};
}
async insert(vector) {
if (vector.values.length !== this.options.dimension) {
throw new Error(`Vector dimension mismatch: expected ${this.options.dimension}, got ${vector.values.length}`);
}
this.vectors.set(vector.id, vector);
this._stats.vectorCount = this.vectors.size;
this._stats.memoryUsage = this.vectors.size * this.options.dimension * 4; // Rough estimate
}
async insertBatch(vectors, options = {}) {
const batchSize = options.batchSize || 1000;
const total = vectors.length;
for (let i = 0; i < total; i += batchSize) {
const batch = vectors.slice(i, Math.min(i + batchSize, total));
await Promise.all(batch.map(v => this.insert(v)));
if (options.progressCallback) {
options.progressCallback(Math.min(i + batchSize, total) / total);
}
}
}
async search(query, options = {}) {
const k = options.k || 10;
const results = [];
// Simple cosine similarity
for (const [id, vector] of this.vectors.entries()) {
const score = this._cosineSimilarity(query, vector.values);
results.push({ id, score, metadata: vector.metadata });
}
// Sort by score descending and return top k
results.sort((a, b) => b.score - a.score);
return results.slice(0, k);
}
_cosineSimilarity(a, b) {
let dotProduct = 0;
let normA = 0;
let normB = 0;
for (let i = 0; i < a.length; i++) {
dotProduct += a[i] * b[i];
normA += a[i] * a[i];
normB += b[i] * b[i];
}
return dotProduct / (Math.sqrt(normA) * Math.sqrt(normB));
}
async get(id) {
return this.vectors.get(id) || null;
}
async delete(id) {
const result = this.vectors.delete(id);
if (result) {
this._stats.vectorCount = this.vectors.size;
this._stats.memoryUsage = this.vectors.size * this.options.dimension * 4;
}
return result;
}
stats() {
return { ...this._stats };
}
async save(path) {
// Mock save - just log
console.log(`Mock: Saving index to ${path}`);
}
static async load(path) {
// Mock load - create empty index
console.log(`Mock: Loading index from ${path}`);
return new MockVectorIndex({ dimension: 384, indexType: 'hnsw' });
}
async clear() {
this.vectors.clear();
this._stats.vectorCount = 0;
this._stats.memoryUsage = 0;
}
async optimize() {
// Mock optimize
console.log('Mock: Optimizing index');
}
}
module.exports = { VectorIndex: MockVectorIndex };

View file

@ -1,20 +0,0 @@
{
"compilerOptions": {
"target": "ES2020",
"module": "commonjs",
"lib": ["ES2020"],
"declaration": true,
"declarationMap": true,
"outDir": "./dist",
"rootDir": "./src",
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true,
"moduleResolution": "node",
"resolveJsonModule": true,
"allowSyntheticDefaultImports": true
},
"include": ["src/**/*", "types/**/*"],
"exclude": ["node_modules", "dist"]
}

View file

@ -1,153 +0,0 @@
/**
* Vector database types compatible with both NAPI and WASM backends
*/
export interface Vector {
id: string;
values: number[];
metadata?: Record<string, any>;
}
export interface SearchResult {
id: string;
score: number;
metadata?: Record<string, any>;
}
export interface IndexStats {
vectorCount: number;
dimension: number;
indexType: string;
memoryUsage?: number;
}
export interface CreateIndexOptions {
dimension: number;
metric?: 'cosine' | 'euclidean' | 'dot';
indexType?: 'flat' | 'hnsw';
hnswConfig?: {
m?: number;
efConstruction?: number;
};
}
export interface SearchOptions {
k?: number;
ef?: number;
filter?: Record<string, any>;
}
export interface BatchInsertOptions {
batchSize?: number;
progressCallback?: (progress: number) => void;
}
export interface BenchmarkResult {
operation: string;
duration: number;
throughput?: number;
memoryUsage?: number;
}
export class VectorIndex {
constructor(options: CreateIndexOptions);
/**
* Insert a single vector into the index
*/
insert(vector: Vector): Promise<void>;
/**
* Insert multiple vectors in batches
*/
insertBatch(vectors: Vector[], options?: BatchInsertOptions): Promise<void>;
/**
* Search for k nearest neighbors
*/
search(query: number[], options?: SearchOptions): Promise<SearchResult[]>;
/**
* Get vector by ID
*/
get(id: string): Promise<Vector | null>;
/**
* Delete vector by ID
*/
delete(id: string): Promise<boolean>;
/**
* Get index statistics
*/
stats(): Promise<IndexStats>;
/**
* Save index to file
*/
save(path: string): Promise<void>;
/**
* Load index from file
*/
static load(path: string): Promise<VectorIndex>;
/**
* Clear all vectors from index
*/
clear(): Promise<void>;
/**
* Optimize index (rebuild HNSW, etc.)
*/
optimize(): Promise<void>;
}
/**
* Backend information
*/
export interface BackendInfo {
type: 'native' | 'wasm';
version: string;
features: string[];
}
/**
* Get information about the active backend
*/
export function getBackendInfo(): BackendInfo;
/**
* Check if native bindings are available
*/
export function isNativeAvailable(): boolean;
/**
* Utilities
*/
export namespace Utils {
/**
* Calculate cosine similarity between two vectors
*/
export function cosineSimilarity(a: number[], b: number[]): number;
/**
* Calculate euclidean distance between two vectors
*/
export function euclideanDistance(a: number[], b: number[]): number;
/**
* Normalize a vector
*/
export function normalize(vector: number[]): number[];
/**
* Generate random vector for testing
*/
export function randomVector(dimension: number): number[];
}
/**
* Default exports
*/
export { VectorIndex as default };