File size: 8,803 Bytes
40d7073 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 | "use strict";
/**
* ruvector - High-performance vector database for Node.js
*
* This package automatically detects and uses the best available implementation:
* 1. Native (Rust-based, fastest) - if available for your platform
* 2. RVF (persistent store) - if @ruvector/rvf is installed
* 3. Stub (testing fallback) - limited functionality
*
* Also provides safe wrappers for GNN and Attention modules that handle
* array type conversions automatically.
*/
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __exportStar = (this && this.__exportStar) || function(m, exports) {
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.NativeVectorDb = exports.VectorDB = exports.VectorDb = void 0;
exports.getImplementationType = getImplementationType;
exports.isNative = isNative;
exports.isRvf = isRvf;
exports.isWasm = isWasm;
exports.getVersion = getVersion;
__exportStar(require("./types"), exports);
// Export core wrappers (safe interfaces with automatic type conversion)
__exportStar(require("./core"), exports);
__exportStar(require("./services"), exports);
let implementation;
let implementationType = 'wasm';
// Check for explicit --backend rvf flag or RUVECTOR_BACKEND env var
const rvfRequested = process.env.RUVECTOR_BACKEND === 'rvf' ||
process.argv.includes('--backend') && process.argv[process.argv.indexOf('--backend') + 1] === 'rvf';
if (rvfRequested) {
// Explicit rvf backend requested - fail hard if not available
try {
implementation = require('@ruvector/rvf');
implementationType = 'rvf';
}
catch (e) {
throw new Error('@ruvector/rvf is not installed.\n' +
' Run: npm install @ruvector/rvf\n' +
' The --backend rvf flag requires this package.');
}
}
else {
try {
// Try to load native module first
implementation = require('@ruvector/core');
implementationType = 'native';
// Verify it's actually working (native module exports VectorDb, not VectorDB)
if (typeof implementation.VectorDb !== 'function') {
throw new Error('Native module loaded but VectorDb class not found');
}
}
catch (e) {
// Try rvf (persistent store) as second fallback
try {
implementation = require('@ruvector/rvf');
implementationType = 'rvf';
}
catch (rvfErr) {
// Graceful fallback - don't crash, just warn
console.warn('[RuVector] Native module not available:', e.message);
console.warn('[RuVector] RVF module not available:', rvfErr.message);
console.warn('[RuVector] Vector operations will be limited. Install @ruvector/core or @ruvector/rvf for full functionality.');
// Create a stub implementation that provides basic functionality
implementation = {
VectorDb: class StubVectorDb {
constructor() {
console.warn('[RuVector] Using stub VectorDb - install @ruvector/core for native performance');
}
async insert() { return 'stub-id-' + Date.now(); }
async insertBatch(entries) { return entries.map(() => 'stub-id-' + Date.now()); }
async search() { return []; }
async delete() { return true; }
async get() { return null; }
async len() { return 0; }
async isEmpty() { return true; }
}
};
implementationType = 'wasm'; // Mark as fallback mode
}
}
}
/**
* Get the current implementation type
*/
function getImplementationType() {
return implementationType;
}
/**
* Check if native implementation is being used
*/
function isNative() {
return implementationType === 'native';
}
/**
* Check if RVF implementation is being used
*/
function isRvf() {
return implementationType === 'rvf';
}
/**
* Check if stub/fallback implementation is being used
*/
function isWasm() {
return implementationType === 'wasm';
}
/**
* Get version information
*/
function getVersion() {
const pkg = require('../package.json');
return {
version: pkg.version,
implementation: implementationType
};
}
/**
* Wrapper class that automatically handles metadata JSON conversion
*/
class VectorDBWrapper {
constructor(options) {
// Normalize: accept both 'dimension' (singular) and 'dimensions' (plural)
if (options && options.dimension && !options.dimensions) {
options = { ...options, dimensions: options.dimension };
delete options.dimension;
}
this.db = new implementation.VectorDb(options);
}
/**
* Insert a vector with optional metadata (objects are auto-converted to JSON)
*/
async insert(entryOrVector, metadata) {
// Support positional args: insert(vector, metadata) as well as insert({vector, metadata})
let entry;
if (entryOrVector instanceof Float32Array || Array.isArray(entryOrVector)) {
entry = { vector: entryOrVector, metadata: metadata };
} else {
entry = entryOrVector;
}
const nativeEntry = {
id: entry.id,
vector: entry.vector instanceof Float32Array ? entry.vector : new Float32Array(entry.vector),
};
// Auto-convert metadata object to JSON string
if (entry.metadata) {
nativeEntry.metadata = JSON.stringify(entry.metadata);
}
return this.db.insert(nativeEntry);
}
/**
* Insert multiple vectors in batch
*/
async insertBatch(entries) {
const nativeEntries = entries.map(entry => ({
id: entry.id,
vector: entry.vector instanceof Float32Array ? entry.vector : new Float32Array(entry.vector),
metadata: entry.metadata ? JSON.stringify(entry.metadata) : undefined,
}));
return this.db.insertBatch(nativeEntries);
}
/**
* Search for similar vectors (metadata is auto-parsed from JSON)
*/
async search(queryOrVector, k, efSearch) {
// Support positional args: search(vector, k) as well as search({vector, k})
let query;
if (queryOrVector instanceof Float32Array || Array.isArray(queryOrVector)) {
query = { vector: queryOrVector, k: k || 10, efSearch: efSearch };
} else {
query = queryOrVector;
}
const nativeQuery = {
vector: query.vector instanceof Float32Array ? query.vector : new Float32Array(query.vector),
k: query.k,
efSearch: query.efSearch,
};
// Auto-convert filter object to JSON string
if (query.filter) {
nativeQuery.filter = JSON.stringify(query.filter);
}
const results = await this.db.search(nativeQuery);
// Auto-parse metadata JSON strings back to objects
return results.map((r) => ({
id: r.id,
score: r.score,
vector: r.vector,
metadata: r.metadata ? JSON.parse(r.metadata) : undefined,
}));
}
/**
* Get a vector by ID (metadata is auto-parsed from JSON)
*/
async get(id) {
const entry = await this.db.get(id);
if (!entry)
return null;
return {
id: entry.id,
vector: entry.vector,
metadata: entry.metadata ? JSON.parse(entry.metadata) : undefined,
};
}
/**
* Delete a vector by ID
*/
async delete(id) {
return this.db.delete(id);
}
/**
* Get the number of vectors in the database
*/
async len() {
return this.db.len();
}
/**
* Check if the database is empty
*/
async isEmpty() {
return this.db.isEmpty();
}
}
// Export the wrapper class (aliased as VectorDB for backwards compatibility)
exports.VectorDb = VectorDBWrapper;
exports.VectorDB = VectorDBWrapper;
// Also export the raw native implementation for advanced users
exports.NativeVectorDb = implementation.VectorDb;
// Export everything from the implementation
exports.default = implementation;
|