Endee TypeScript Vector Database Client
raw JSON →Endee is a TypeScript client library for interacting with the local Endee vector database server. It provides full type safety, modern ES module support, and optimized utilities for performing Approximate Nearest Neighbor (ANN) searches on vector data. Currently at version 1.7.0, it supports various distance metrics (cosine, L2, inner product), hybrid indexes combining dense and sparse vectors, and allows attaching metadata for filtering queries. The library prioritizes high performance and efficient similarity searches, offering a robust interface for vector database operations like index creation, vector upsertion, and querying. While there isn't a specified release cadence, client updates typically align with server capabilities, ensuring compatibility and leveraging new features, especially regarding its encrypted vector database capabilities.
Common errors
error Error: connect ECONNREFUSED 127.0.0.1:8080 ↓
client.setBaseUrl('http://your-server:port/api/v1');. error Error: Authentication failed. ↓
new Endee(process.env.NDD_AUTH_TOKEN || 'your-auth-token');. Ensure the token matches the server's NDD_AUTH_TOKEN setting. error Error: Index 'my_index_name' already exists. ↓
await client.deleteIndex('my_index_name');) before attempting to recreate it. error TypeError: Cannot read properties of undefined (reading 'upsert') ↓
client.createIndex and client.getIndex calls to ensure an index object is successfully retrieved before attempting operations like upsert() or query(). Warnings
gotcha The Endee client library requires a separate, running Endee Local server. All operations will fail with connection-related errors (e.g., `ECONNREFUSED`) if the server is not active or is unreachable. ↓
breaking Endee client versions 1.0.0 and above mandate Node.js 18.0.0 or higher. This requirement is due to the adoption of modern JavaScript features and native ES module support. ↓
gotcha If your Endee Local server is secured with an `NDD_AUTH_TOKEN`, the client *must* be initialized with the identical token. Mismatched or absent tokens will lead to 'Authentication failed' errors. ↓
gotcha The `dimension` (and `sparseDimension` for hybrid indexes) specified during `createIndex` must precisely match the dimensionality of the vectors you intend to upsert. Inconsistent dimensions will cause upsert and query failures. ↓
Install
npm install endee yarn add endee pnpm add endee Imports
- Endee wrong
const Endee = require('endee');correctimport { Endee } from 'endee'; - Precision wrong
import * as endee from 'endee'; const p = endee.Precision;correctimport { Precision } from 'endee'; - VectorData wrong
import { VectorData } from 'endee';correctimport type { VectorData } from 'endee';
Quickstart
import { Endee, Precision } from 'endee';
const authToken = process.env.NDD_AUTH_TOKEN ?? ''; // Use environment variable for auth token if set
const client = new Endee(authToken);
// Optionally set a custom base URL if your server is not on the default host/port
// client.setBaseUrl('http://0.0.0.0:8081/api/v1');
async function runEndeeDemo() {
const indexName = 'my_test_vectors';
const vectorDimension = 384; // Matches common embedding models like mini-LM
try {
// Attempt to delete the index first for idempotency, ignore if it doesn't exist
await client.deleteIndex(indexName);
console.log(`Successfully deleted existing index: ${indexName}`);
} catch (error: any) {
if (error.message.includes('not found')) {
console.log(`Index ${indexName} does not exist, proceeding to create.`);
} else {
console.error(`Error deleting index ${indexName}:`, error.message);
}
}
console.log(`Creating a new index: ${indexName}`);
await client.createIndex({
name: indexName,
dimension: vectorDimension,
spaceType: 'cosine',
precision: Precision.INT16,
});
console.log(`Index '${indexName}' created successfully.`);
const index = await client.getIndex(indexName);
console.log('Upserting example vectors...');
await index.upsert([
{
id: 'doc1',
vector: Array.from({ length: vectorDimension }, () => Math.random() * 2 - 1),
meta: { title: 'First Document', author: 'Alice' },
filter: { category: 'technology' },
},
{
id: 'doc2',
vector: Array.from({ length: vectorDimension }, () => Math.random() * 2 - 1),
meta: { title: 'Second Document', author: 'Bob' },
filter: { category: 'science' },
},
{
id: 'doc3',
vector: Array.from({ length: vectorDimension }, () => Math.random() * 2 - 1),
meta: { title: 'Third Document', author: 'Charlie' },
filter: { category: 'technology' },
},
]);
console.log('Vectors upserted successfully.');
console.log('Querying the index for similar vectors...');
const queryVector = Array.from({ length: vectorDimension }, () => Math.random() * 2 - 1);
const queryResults = await index.query({
vector: queryVector,
topK: 2,
includeMetadata: true,
filter: { category: 'technology' } // Example filter
});
console.log('Query Results:', JSON.stringify(queryResults, null, 2));
console.log('Endee client demo finished.');
}
runEndeeDemo().catch(error => {
console.error('An error occurred during the Endee demo:', error);
process.exit(1);
});