Endee TypeScript Vector Database Client

raw JSON →
1.7.0 verified Thu Apr 23 auth: no javascript

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.

error Error: connect ECONNREFUSED 127.0.0.1:8080
cause The Endee client could not establish a connection to the Endee Local server, typically because the server is not running or is listening on a different address/port.
fix
Start the Endee Local server. If the server is running on a non-default address or port, configure the client using client.setBaseUrl('http://your-server:port/api/v1');.
error Error: Authentication failed.
cause The Endee Local server is configured with an authentication token, but the client either provided an incorrect token or no token at all.
fix
Initialize the Endee client with the correct authentication token string, e.g., 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.
cause An attempt was made to create an index using a name that is already in use by an existing index within the Endee database.
fix
Choose a unique name for the new index, or explicitly delete the existing index (await client.deleteIndex('my_index_name');) before attempting to recreate it.
error TypeError: Cannot read properties of undefined (reading 'upsert')
cause This usually indicates that the `index` variable is `undefined`. This happens if `await client.getIndex('non_existent_index')` failed to retrieve an index, or if `client.createIndex` did not complete successfully before `getIndex` was called.
fix
Add robust error handling around client.createIndex and client.getIndex calls to ensure an index object is successfully retrieved before attempting operations like upsert() or query().
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.
fix Ensure the Endee Local server process is running. Verify the client's base URL configuration (`client.setBaseUrl()`) matches the server's listening address and port.
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.
fix Update your Node.js environment to version 18.0.0 or a newer LTS release. Tools like `nvm` (Node Version Manager) can simplify this process.
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.
fix When initializing the client, pass the correct `NDD_AUTH_TOKEN` string: `new Endee('your-secret-token')`. Ensure any environment variable (`process.env.NDD_AUTH_TOKEN`) is correctly set if you are relying on that.
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.
fix Always confirm that the `dimension` parameter (and `sparseDimension` if applicable) during index creation exactly corresponds to the output dimension of your embedding model or vector source.
npm install endee
yarn add endee
pnpm add endee

This quickstart demonstrates how to initialize the Endee client, create a new vector index with specified parameters, upsert multiple vectors along with their metadata, and perform a filtered similarity search on the index.

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);
});