JSPM

  • ESM via JSPM
  • ES Module Entrypoint
  • Export Map
  • Keywords
  • License
  • Repository URL
  • TypeScript Types
  • README
  • Created
  • Published
  • Downloads 1
  • Score
    100M100P100Q61570F
  • License MIT

High-performance Node.js client for Antarys vector database with HTTP/2, connection pooling, and intelligent caching

Package Exports

  • antarys

Readme

Antarys Vector Database Node.js Client

High-performance TypeScript/Node.js client for Antarys vector database with HTTP/2, connection pooling, worker thread parallelization, and built in caching.

Installation

Install via npm package

npm install antarys
yarn add antarys
pnpm add antarys

Quick Start

import { createClient } from 'antarys';

async function main() {
    // Initialize client with performance optimizations
    const client = createClient('http://localhost:8080', {
        connectionPoolSize: 100,  // Auto-sized based on CPU count
        compression: true,
        cacheSize: 1000,
        threadPoolSize: 16,
        debug: true
    });

    // Create collection
    await client.createCollection({
        name: 'my_vectors',
        dimensions: 1536,
        enableHnsw: true,
        shards: 16
    });

    const vectors = client.vectorOperations('my_vectors');

    // Upsert vectors
    await vectors.upsert([
        { id: '1', values: Array(1536).fill(0.1), metadata: { category: 'A' } },
        { id: '2', values: Array(1536).fill(0.2), metadata: { category: 'B' } }
    ]);

    // Query similar vectors
    const results = await vectors.query({
        vector: Array(1536).fill(0.1),
        topK: 10,
        includeMetadata: true
    });

    await client.close();
}

main().catch(console.error);

Generate Embeddings

/**
 * Simple example: Generate embeddings from documents
 */

import { createClient, embed } from 'antarys';

async function main() {
    // Create client
    const client = createClient('http://localhost:8080');

    try {
        // Documents to embed
        const documents = [
            'Python is a high-level programming language',
            'JavaScript is used for web development',
            'Machine learning is a subset of AI',
            'Neural networks process data in layers',
            'Deep learning uses multiple neural network layers',
            'Natural language processing analyzes human language'
        ];

        console.log('Generating embeddings for documents...\n');

        // Generate embeddings
        const embeddings = await embed(client, documents) as number[][];

        // Log the responses
        for (let i = 0; i < documents.length; i++) {
            const doc = documents[i];
            const embedding = embeddings[i];

            console.log(`Document ${i + 1}:`);
            console.log(`  Text: ${doc}`);
            console.log(`  Embedding dimensions: ${embedding.length}`);
            console.log(`  First 5 values: ${embedding.slice(0, 5)}`);
            console.log();
        }

    } finally {
        await client.close();
    }
}

main().catch(console.error);

Simple RAG Example

Here's a complete example showing how to build a Retrieval-Augmented Generation (RAG) system with Antarys and OpenAI:

import OpenAI from 'openai';
import { createClient } from "antarys";

class SimpleRAG {
    private openai: OpenAI;
    private antarys: any;
    private vectors: any;

    constructor() {
        this.openai = new OpenAI();
        this.antarys = null;
        this.vectors = null;
    }

    async init(): Promise<void> {
        this.antarys = createClient("http://localhost:8080");

        // Try to create collection, ignore if exists
        try {
            await this.antarys.createCollection({
                name: "docs",
                dimensions: 1536
            });
        } catch (error: any) {
            if (!error.message.includes('already exists')) {
                throw error;
            }
        }

        this.vectors = this.antarys.vectorOperations("docs");
    }

    async embed(text: string): Promise<number[]> {
        const response = await this.openai.embeddings.create({
            model: "text-embedding-3-small",
            input: text
        });
        return response.data[0].embedding;
    }

    async add(docId: string, content: string): Promise<void> {
        const embedding = await this.embed(content);
        await this.vectors.upsert([{
            id: docId,
            values: embedding,
            metadata: { content }
        }]);
    }

    async search(query: string, topK: number = 3): Promise<any[]> {
        const embedding = await this.embed(query);
        const results = await this.vectors.query({
            vector: embedding,
            topK,
            includeMetadata: true
        });
        return results.matches;
    }

    async generate(query: string, docs: any[]): Promise<string> {
        const context = docs.map(doc => doc.metadata.content).join("\n");
        const response = await this.openai.chat.completions.create({
            model: "gpt-4",
            messages: [{
                role: "user",
                content: `Context: ${context}\n\nQuestion: ${query}`
            }]
        });
        return response.choices[0].message.content || '';
    }

    async query(question: string, verbose: boolean = false): Promise<[string, any[]]> {
        const docs = await this.search(question);
        const answer = await this.generate(question, docs);

        if (verbose) {
            console.log(`Q: ${question}`);
            console.log(`A: ${answer}`);
            docs.forEach(doc => {
                console.log(`Source: ${doc.id} (${doc.score.toFixed(3)})`);
            });
        }

        return [answer, docs];
    }

    async close(): Promise<void> {
        if (this.antarys) {
            await this.antarys.close();
        }
    }
}

async function main() {
    const rag = new SimpleRAG();

    await rag.init();

    await rag.add("AHNSW",
        "Unlike traditional sequential HNSW, we are using a different asynchronous approach to HNSW and eliminating thread locks with the help of architectural fine tuning. We will soon release more technical details on the Async HNSW algorithmic approach.");
    await rag.add("Antarys",
        "Antarys is a multi-modal vector database and it uses the AHNSW algorithm to enhance its performance to perform semantic searching based on similarity");

    await rag.query("what is Antarys?", true);

    await rag.close();
}

main().catch(console.error);

Core Concepts

Collections

import { Client, createClient } from 'antarys';

const client = createClient('http://localhost:8080');

// Create collection with optimized parameters
await client.createCollection({
    name: 'vectors',
    dimensions: 1536,        // Required: vector dimensions
    enableHnsw: true,        // Enable HNSW indexing for fast ANN
    shards: 16,              // Parallel processing shards
    m: 16,                   // HNSW connectivity parameter
    efConstruction: 200      // HNSW construction quality
});

// List collections
const collections = await client.listCollections();

// Get collection info
const info = await client.describeCollection('vectors');

// Delete collection
await client.deleteCollection('vectors');

Vector Operations

Single Vector Upsert

const vectors = client.vectorOperations('my_collection');

const record = {
    id: '1',
    values: [0.1, 0.2, 0.3],  // Must match collection dimensions
    metadata: { category: 'example', score: 0.95 }
};

await vectors.upsert([record]);

Batch Vector Upsert

const largeDataset = [
    { id: '1', values: Array(1536).fill(0.1), metadata: { type: 'doc' } },
    { id: '2', values: Array(1536).fill(0.2), metadata: { type: 'image' } },
    // ... thousands more
];

await vectors.upsert(largeDataset, {
    batchSize: 5000,          // Optimal batch size
    parallelWorkers: 8,       // Worker threads for preprocessing
    validateDimensions: true, // Ensure vector dimensions match
    showProgress: true        // Display progress bar
});

Query Similar Vectors

// Basic similarity search
const results = await vectors.query({
    vector: Array(1536).fill(0.1),
    topK: 10,
    includeMetadata: true,
    includeValues: false      // Reduce response size
});

// Advanced search with filtering
const filteredResults = await vectors.query({
    vector: queryVector,
    topK: 20,
    includeMetadata: true,
    filter: { category: 'documents' },  // Metadata filtering
    threshold: 0.8,                     // Minimum similarity score
    useAnn: true,                       // Use approximate search
    efSearch: 200                       // HNSW search quality
});

Batch Query Operations

const queries = [
    { vector: Array(1536).fill(0.1), topK: 5 },
    { vector: Array(1536).fill(0.2), topK: 5 },
    { vector: Array(1536).fill(0.3), topK: 5 }
];

const batchResults = await vectors.batchQuery(queries);

Delete Vectors

// Delete single vector
await vectors.deleteVector('vector_id_1');

// Delete multiple vectors
await vectors.deleteVectors(['id1', 'id2', 'id3']);

// Delete with filtering
await vectors.deleteByFilter({ category: 'outdated' });

Get Vector by ID

const vector = await vectors.getVector('vector_id_1');
if (vector) {
    console.log('Found:', vector.metadata);
}

Memory and Resource Management

// Force commit for persistence
await client.commit();

// Clear client-side caches
await client.clearCache();
await vectors.clearCache();

// Get performance statistics
const stats = client.getStats();
console.log('Cache hit rate:', stats.cache.hitRate);
console.log('Average request time:', stats.requests.avgTime);

// Proper resource cleanup
await client.close();

Advanced Features

Client Configuration

import { createClient } from 'antarys';

const client = createClient('http://localhost:8080', {
    // Connection Pool Optimization
    connectionPoolSize: 100,     // High concurrency (auto: CPU_COUNT * 5)
    timeout: 120,                // Extended timeout for large operations

    // HTTP/2 and Compression
    compression: true,           // Enable response compression

    // Caching Configuration
    cacheSize: 1000,            // Client-side query cache
    cacheTtl: 300,              // Cache TTL in seconds

    // Threading and Parallelism
    threadPoolSize: 16,         // CPU-bound operations (auto: CPU_COUNT * 2)

    // Retry Configuration
    retryAttempts: 5,           // Network resilience

    // Debug Mode
    debug: true                 // Performance monitoring
});

Dimension Validation

// Automatic dimension validation
const isValid = await vectors.validateVectorDimensions([0.1, 0.2, 0.3]);

// Get collection dimensions
const dims = await vectors.getCollectionDimensions();

Cache Performance Monitoring

// Get cache statistics
const stats = vectors.getCacheStats();
console.log(`Cache hit rate: ${(stats.hitRate * 100).toFixed(2)}%`);
console.log(`Cache size: ${stats.cacheSize}`);

Performance Optimization

Small Scale (< 1M vectors)

const client = createClient('http://localhost:8080', {
    connectionPoolSize: 20,
    cacheSize: 500,
    threadPoolSize: 4
});

const batchSize = 1000;
const parallelWorkers = 2;

Medium Scale (1M - 10M vectors)

const client = createClient('http://localhost:8080', {
    connectionPoolSize: 50,
    cacheSize: 2000,
    threadPoolSize: 8
});

const batchSize = 3000;
const parallelWorkers = 4;

Large Scale (10M+ vectors)

const client = createClient('http://localhost:8080', {
    connectionPoolSize: 100,
    cacheSize: 5000,
    threadPoolSize: 16
});

const batchSize = 5000;
const parallelWorkers = 8;

Batch Operation Tuning

// Optimal batch upsert parameters
await vectors.upsert(largeDataset, {
    batchSize: 5000,           // Optimal for network efficiency
    parallelWorkers: 8,        // Match server capability
    validateDimensions: true,  // Prevent dimension errors
    showProgress: true
});

// High-throughput query configuration
const results = await vectors.query({
    vector: queryVector,
    topK: 100,
    includeValues: false,      // Reduce response size
    includeMetadata: true,
    useAnn: true,              // Fast approximate search
    efSearch: 200,             // Higher quality (vs speed)
    skipCache: false           // Leverage cache
});

Server-Side Optimization

HNSW Index Parameters

await client.createCollection({
    name: 'high_performance',
    dimensions: 1536,
    enableHnsw: true,

    // HNSW Tuning
    m: 16,                     // Connectivity (16-64 for high recall)
    efConstruction: 200,       // Graph construction quality (200-800)
    shards: 32                 // Parallel processing (match CPU cores)
});

// Query-time HNSW parameters
const results = await vectors.query({
    vector: queryVector,
    efSearch: 200,             // Search quality (100-800)
    useAnn: true               // Enable HNSW acceleration
});

TypeScript Support

The client is fully typed with TypeScript:

import {
    Client,
    VectorRecord,
    SearchParams,
    SearchResults,
    CreateCollectionParams,
    ClientConfig
} from 'antarys';

// Type-safe vector record
const record: VectorRecord = {
    id: 'example',
    values: [0.1, 0.2, 0.3],
    metadata: { key: 'value' }
};

// Search parameters with full type safety
const params: SearchParams = {
    vector: [0.1, 0.2, 0.3],
    topK: 10,
    includeMetadata: true,
    threshold: 0.8
};

Health Monitoring

// Check server health
const health = await client.health();
console.log('Server status:', health.status);

// Get server information
const info = await client.info();
console.log('Server version:', info.version);

// Collection statistics
const collectionInfo = await client.describeCollection('vectors');
console.log('Vector count:', collectionInfo.vectorCount || 0);

Error Handling

try {
    await vectors.upsert(records);
} catch (error) {
    if (error.message.includes('dimension mismatch')) {
        console.error('Vector dimensions do not match collection schema');
    } else if (error.message.includes('connection')) {
        console.error('Network connectivity issue');
    } else {
        console.error('Unexpected error:', error);
    }
}

License

MIT