edgevector-db-sdk
Version:
Official TypeScript/JavaScript SDK for EdgeVector DB - A globally distributed, edge-native database platform combining document storage, vector search, time series, and real-time streaming
1,779 lines (1,770 loc) • 99.9 kB
TypeScript
import { EventEmitter } from 'eventemitter3';
/**
* Core types and interfaces for EdgeVector SDK
*/
interface EdgeVectorConfig {
/** API endpoint URL */
url: string;
/** API key for authentication */
apiKey: string;
/** Default database name */
database?: string;
/** Request timeout in milliseconds */
timeout?: number;
/** Enable retry mechanism */
retry?: RetryConfig;
/** Connection pool configuration */
pool?: PoolConfig;
/** Enable offline queue */
offline?: OfflineConfig;
/** Debug configuration */
debug?: DebugConfig;
/** Caching configuration */
cache?: CacheConfig;
/** Region preference for writes */
region?: string;
}
interface RetryConfig {
/** Maximum number of retries */
maxAttempts?: number;
/** Initial delay in milliseconds */
initialDelay?: number;
/** Maximum delay in milliseconds */
maxDelay?: number;
/** Backoff multiplier */
backoffMultiplier?: number;
/** Jitter to add randomness */
jitter?: boolean;
}
interface PoolConfig {
/** Maximum number of concurrent connections */
maxConnections?: number;
/** Minimum number of idle connections */
minConnections?: number;
/** Connection idle timeout in milliseconds */
idleTimeout?: number;
/** Enable connection pooling */
enabled?: boolean;
}
interface OfflineConfig {
/** Enable offline queue */
enabled?: boolean;
/** Maximum queue size */
maxQueueSize?: number;
/** Storage type for offline queue */
storage?: 'memory' | 'indexeddb' | 'localstorage';
/** Retry failed operations when online */
retryOnReconnect?: boolean;
}
interface DebugConfig {
/** Enable debug mode */
enabled?: boolean;
/** Log level */
level?: 'error' | 'warn' | 'info' | 'debug';
/** Include performance metrics */
metrics?: boolean;
/** Include request/response logging */
requests?: boolean;
}
interface CacheConfig {
/** Enable caching */
enabled?: boolean;
/** Cache TTL in milliseconds */
ttl?: number;
/** Maximum cache size */
maxSize?: number;
/** Cache storage type */
storage?: 'memory' | 'indexeddb';
}
type MongoFilter<T = any> = {
[K in keyof T]?: T[K] | {
$eq?: T[K];
$ne?: T[K];
$gt?: T[K];
$gte?: T[K];
$lt?: T[K];
$lte?: T[K];
$in?: T[K][];
$nin?: T[K][];
$exists?: boolean;
$regex?: string | RegExp;
$options?: string;
$size?: number;
$all?: T[K][];
$elemMatch?: MongoFilter<T[K]>;
};
} & {
$and?: MongoFilter<T>[];
$or?: MongoFilter<T>[];
$nor?: MongoFilter<T>[];
$not?: MongoFilter<T>;
$where?: string | Function;
$text?: {
$search: string;
$language?: string;
$caseSensitive?: boolean;
$diacriticSensitive?: boolean;
};
_id?: string | {
$in?: string[];
$ne?: string;
};
};
interface MongoUpdateOperators<T = any> {
$set?: Partial<T>;
$unset?: {
[K in keyof T]?: 1 | true;
};
$inc?: {
[K in keyof T]?: number;
};
$mul?: {
[K in keyof T]?: number;
};
$push?: {
[K in keyof T]?: any;
};
$pull?: {
[K in keyof T]?: any;
};
$addToSet?: {
[K in keyof T]?: any;
};
$pop?: {
[K in keyof T]?: 1 | -1;
};
$rename?: {
[K in keyof T]?: string;
};
$min?: Partial<T>;
$max?: Partial<T>;
$currentDate?: {
[K in keyof T]?: true | {
$type: 'date' | 'timestamp';
};
};
}
interface FindOptions {
/** Limit number of results */
limit?: number;
/** Skip number of documents */
skip?: number;
/** Sort specification */
sort?: Record<string, 1 | -1>;
/** Field projection */
projection?: Record<string, 1 | 0>;
/** Return only distinct values */
distinct?: string;
/** Collation options */
collation?: CollationOptions;
/** Maximum time to allow query to run */
maxTimeMS?: number;
/** Enable/disable cursor timeout */
noCursorTimeout?: boolean;
}
interface CollationOptions {
locale: string;
caseLevel?: boolean;
caseFirst?: 'upper' | 'lower' | 'off';
strength?: 1 | 2 | 3 | 4 | 5;
numericOrdering?: boolean;
alternate?: 'non-ignorable' | 'shifted';
maxVariable?: 'punct' | 'space';
backwards?: boolean;
}
interface InsertResult {
insertedId: string;
acknowledged: boolean;
}
interface InsertManyResult {
insertedIds: string[];
insertedCount: number;
acknowledged: boolean;
}
interface UpdateResult {
matchedCount: number;
modifiedCount: number;
upsertedId?: string;
upsertedCount: number;
acknowledged: boolean;
}
interface DeleteResult {
deletedCount: number;
acknowledged: boolean;
}
interface BulkWriteResult {
insertedCount: number;
matchedCount: number;
modifiedCount: number;
deletedCount: number;
upsertedCount: number;
upsertedIds: Record<number, string>;
}
interface VectorSearchOptions {
/** Number of results to return */
limit?: number;
/** Minimum similarity threshold */
threshold?: number;
/** Distance metric to use */
metric?: 'cosine' | 'euclidean' | 'dot_product' | 'manhattan';
/** Additional filters to apply */
filter?: MongoFilter;
/** Include similarity scores in results */
includeScores?: boolean;
/** Enable approximate search for better performance */
approximate?: boolean;
/** Search in specific vector field */
vectorField?: string;
}
interface VectorSearchResult<T = any> {
document: T;
score: number;
distance: number;
}
interface VectorIndex {
name: string;
field: string;
dimensions: number;
metric: 'cosine' | 'euclidean' | 'dot_product' | 'manhattan';
approximateSearch: boolean;
createdAt: Date;
}
interface TimeSeriesPoint {
/** Metric name */
metric: string;
/** Unix timestamp (nanosecond precision) */
timestamp: number;
/** Metric value */
value: number | string;
/** Metadata tags */
tags: Record<string, string>;
/** Additional fields */
fields?: Record<string, any>;
}
interface TimeSeriesSchema {
metric: string;
dataType: 'counter' | 'gauge' | 'histogram' | 'summary';
unit: string;
description: string;
retentionDays: number;
downsamplingRules: DownsamplingRule[];
compressionType: 'gorilla' | 'zstd' | 'none';
}
interface DownsamplingRule {
interval: string;
retention: string;
aggregations: AggregationType[];
}
type AggregationType = 'avg' | 'sum' | 'min' | 'max' | 'count' | 'first' | 'last' | 'median' | 'mode' | 'p50' | 'p90' | 'p95' | 'p99' | 'stddev' | 'variance' | 'rate' | 'derivative';
interface TimeSeriesQuery {
/** Metric name or pattern */
metric: string | string[];
/** Time range */
timeRange: {
start: string | number | Date;
end?: string | number | Date;
};
/** Tag filters */
filters?: Record<string, string | string[]>;
/** Aggregation functions */
aggregations?: AggregationSpec[];
/** Group by tags */
groupBy?: string[];
/** Time bucket size */
interval?: string;
/** Fill missing values */
fill?: 'null' | 'previous' | 'linear' | number;
/** Limit results */
limit?: number;
}
interface AggregationSpec {
type: AggregationType;
alias?: string;
value?: number;
}
interface TimeSeriesResult {
metric: string;
tags: Record<string, string>;
values: Array<[number, number | string]>;
aggregations?: Record<string, number>;
}
interface SubscriptionOptions {
/** Event types to subscribe to */
events?: ('insert' | 'update' | 'delete' | 'replace')[];
/** Filter for documents to watch */
filter?: MongoFilter;
/** Include full document in change events */
fullDocument?: 'default' | 'updateLookup' | 'whenAvailable' | 'required';
/** Include full document before change */
fullDocumentBeforeChange?: 'off' | 'whenAvailable' | 'required';
/** Resume token for resuming streams */
resumeAfter?: string;
/** Start from specific time */
startAtOperationTime?: Date;
/** Maximum batch size */
batchSize?: number;
/** Collation options */
collation?: CollationOptions;
}
interface ChangeEvent<T = any> {
_id: string;
operationType: 'insert' | 'update' | 'delete' | 'replace' | 'drop' | 'rename' | 'dropDatabase' | 'invalidate';
fullDocument?: T;
fullDocumentBeforeChange?: T;
ns: {
db: string;
coll: string;
};
to?: {
db: string;
coll: string;
};
documentKey: {
_id: string;
};
updateDescription?: {
updatedFields: Record<string, any>;
removedFields: string[];
truncatedArrays?: Array<{
field: string;
newSize: number;
}>;
};
clusterTime: Date;
txnNumber?: number;
lsid?: {
id: string;
uid: string;
};
}
interface Subscription {
id: string;
close(): Promise<void>;
pause(): Promise<void>;
resume(): Promise<void>;
isClosed: boolean;
isPaused: boolean;
}
interface StreamOptions {
/** Chunk size for reading */
chunkSize?: number;
/** Compression type */
compression?: 'gzip' | 'brotli' | 'none';
/** Format for streaming data */
format?: 'json' | 'ndjson' | 'csv' | 'parquet';
/** Include metadata in stream */
includeMetadata?: boolean;
/** Transform function for each chunk */
transform?: (chunk: any) => any;
}
interface WriteStreamOptions {
/** Batch size for writing */
batchSize?: number;
/** Flush interval in milliseconds */
flushInterval?: number;
/** Compression type */
compression?: 'gzip' | 'brotli' | 'none';
/** Enable ordered writes */
ordered?: boolean;
/** Bypass document validation */
bypassDocumentValidation?: boolean;
}
interface ConnectionInfo {
id: string;
database: string;
collection?: string;
status: 'connected' | 'connecting' | 'disconnected' | 'error';
lastActivity: Date;
region: string;
latency?: number;
}
interface DatabaseStats {
collections: number;
indexes: number;
totalSize: number;
dataSize: number;
indexSize: number;
documentCount: number;
avgDocumentSize: number;
}
interface CollectionStats {
name: string;
documentCount: number;
totalSize: number;
avgDocumentSize: number;
indexCount: number;
indexSize: number;
}
declare class EdgeVectorError extends Error {
code?: string | undefined;
statusCode?: number | undefined;
details?: any | undefined;
constructor(message: string, code?: string | undefined, statusCode?: number | undefined, details?: any | undefined);
}
declare class ConnectionError extends EdgeVectorError {
constructor(message: string, details?: any);
}
declare class ValidationError extends EdgeVectorError {
constructor(message: string, details?: any);
}
declare class TimeoutError extends EdgeVectorError {
constructor(message: string, timeout: number);
}
declare class AuthenticationError extends EdgeVectorError {
constructor(message: string);
}
declare class AuthorizationError extends EdgeVectorError {
constructor(message: string);
}
declare class NotFoundError extends EdgeVectorError {
constructor(message: string);
}
interface SDKEvents {
'connected': (info: ConnectionInfo) => void;
'disconnected': (info: ConnectionInfo) => void;
'error': (error: EdgeVectorError) => void;
'retry': (attempt: number, error: Error) => void;
'offline': () => void;
'online': () => void;
'debug': (message: string, data?: any) => void;
}
type DeepPartial<T> = {
[P in keyof T]?: T[P] extends object ? DeepPartial<T[P]> : T[P];
};
type WithId<T> = T & {
_id: string;
};
type OptionalId<T> = T & {
_id?: string;
};
type Document = Record<string, any>;
type BulkWriteOperation<T = Document> = {
insertOne: {
document: OptionalId<T>;
};
} | {
updateOne: {
filter: MongoFilter<T>;
update: MongoUpdateOperators<T>;
upsert?: boolean;
};
} | {
updateMany: {
filter: MongoFilter<T>;
update: MongoUpdateOperators<T>;
upsert?: boolean;
};
} | {
deleteOne: {
filter: MongoFilter<T>;
};
} | {
deleteMany: {
filter: MongoFilter<T>;
};
} | {
replaceOne: {
filter: MongoFilter<T>;
replacement: OptionalId<T>;
upsert?: boolean;
};
};
interface IndexSpec {
[key: string]: 1 | -1 | 'text' | '2dsphere' | 'hashed';
}
interface IndexOptions {
name?: string;
unique?: boolean;
sparse?: boolean;
background?: boolean;
expireAfterSeconds?: number;
partialFilterExpression?: MongoFilter;
collation?: CollationOptions;
textIndexVersion?: number;
weights?: Record<string, number>;
default_language?: string;
language_override?: string;
textIndexVersion?: number;
}
interface IndexInfo {
name: string;
spec: IndexSpec;
options: IndexOptions;
size: number;
usage: {
ops: number;
since: Date;
};
}
interface PerformanceMetrics {
latency: {
min: number;
max: number;
avg: number;
p50: number;
p95: number;
p99: number;
};
throughput: {
requestsPerSecond: number;
bytesPerSecond: number;
};
connections: {
active: number;
idle: number;
total: number;
};
cache: {
hitRate: number;
missRate: number;
size: number;
};
errors: {
rate: number;
count: number;
types: Record<string, number>;
};
}
interface QueryPlan {
executionTimeMillis: number;
totalKeysExamined: number;
totalDocsExamined: number;
totalDocsReturned: number;
stages: QueryStage[];
indexesUsed: string[];
}
interface QueryStage {
stage: string;
executionTimeMillisEstimate: number;
works: number;
advanced: number;
needTime: number;
needYield: number;
isEOF: boolean;
inputStage?: QueryStage;
}
/**
* Production EdgeVector API URL
*/
declare const PRODUCTION_API_URL = "https://edgevector-db.finhub.workers.dev";
/**
* Default configuration for production use
*/
declare const DEFAULT_CONFIG: {
readonly url: "https://edgevector-db.finhub.workers.dev";
readonly timeout: 30000;
readonly retry: {
readonly maxAttempts: 3;
readonly initialDelay: 1000;
readonly maxDelay: 10000;
readonly backoffMultiplier: 2;
readonly jitter: true;
};
readonly pool: {
readonly maxConnections: 10;
readonly minConnections: 1;
readonly idleTimeout: 30000;
readonly enabled: true;
};
readonly debug: {
readonly enabled: false;
readonly level: "info";
readonly metrics: false;
readonly requests: false;
};
readonly cache: {
readonly enabled: true;
readonly ttl: 300000;
readonly maxSize: 100;
readonly storage: "memory";
};
readonly offline: {
readonly enabled: false;
readonly maxQueueSize: 1000;
readonly storage: "memory";
readonly retryOnReconnect: true;
};
};
/**
* HTTP Client with retry logic, connection pooling, and performance optimizations
*/
interface RequestOptions {
method?: 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH';
headers?: Record<string, string>;
body?: any;
timeout?: number;
retries?: number;
priority?: number;
cache?: boolean;
streaming?: boolean;
}
/**
* High-performance HTTP client with built-in retries, connection pooling, and caching
*/
declare class HttpClient extends EventEmitter {
private config;
private queue;
private cache;
private metrics;
private requestCounter;
private connections;
constructor(config: EdgeVectorConfig);
/**
* Make an HTTP request with automatic retries and connection pooling
*/
request<T = any>(endpoint: string, options?: RequestOptions): Promise<T>;
/**
* Execute the actual HTTP request with retries
*/
private executeRequest;
/**
* Perform the actual HTTP request
*/
private performRequest;
/**
* Build request headers with authentication
*/
private buildHeaders;
/**
* Build full URL from endpoint
*/
private buildUrl;
/**
* Generate cache key for request
*/
private getCacheKey;
/**
* Get data from cache
*/
private getFromCache;
/**
* Set data in cache
*/
private setCache;
/**
* Create appropriate error based on HTTP response
*/
private createHttpError;
/**
* Handle and transform errors
*/
private handleHttpError;
/**
* Get retry configuration
*/
private getRetryConfig;
/**
* Generate unique request ID
*/
private generateRequestId;
/**
* Get response size for metrics
*/
private getResponseSize;
/**
* Sanitize headers for logging (remove sensitive data)
*/
private sanitizeHeaders;
/**
* Update success metrics
*/
private updateSuccessMetrics;
/**
* Update error metrics
*/
private updateErrorMetrics;
/**
* Update cache metrics
*/
private updateCacheMetrics;
/**
* Set up metrics collection
*/
private setupMetricsCollection;
/**
* Collect and emit performance metrics
*/
private collectMetrics;
/**
* Get current performance metrics
*/
getMetrics(): PerformanceMetrics;
/**
* Clear cache
*/
clearCache(): void;
/**
* Close all connections and cleanup
*/
close(): Promise<void>;
}
/**
* Query builder with MongoDB-compatible API and method chaining
*/
/**
* Query builder class providing MongoDB-compatible query operations with method chaining
*
* @example
* ```typescript
* const results = await users
* .find({ age: { $gte: 18 } })
* .sort({ createdAt: -1 })
* .limit(10)
* .skip(20)
* .project({ name: 1, email: 1 })
* .toArray();
* ```
*/
declare class QueryBuilder<TSchema extends Document = Document> {
private httpClient;
private baseUrl;
private filter;
private options;
constructor(httpClient: HttpClient, baseUrl: string, filter?: MongoFilter<TSchema>, options?: FindOptions);
/**
* Set the maximum number of documents to return
*
* @param count - Maximum number of documents
* @returns Query builder for chaining
*
* @example
* ```typescript
* const recent = await posts.find().sort({ createdAt: -1 }).limit(10).toArray();
* ```
*/
limit(count: number): QueryBuilder<TSchema>;
/**
* Set the number of documents to skip
*
* @param count - Number of documents to skip
* @returns Query builder for chaining
*
* @example
* ```typescript
* // Pagination: page 3, 10 items per page
* const page3 = await users.find().skip(20).limit(10).toArray();
* ```
*/
skip(count: number): QueryBuilder<TSchema>;
/**
* Set the sort order for documents
*
* @param sort - Sort specification
* @returns Query builder for chaining
*
* @example
* ```typescript
* // Sort by creation date (newest first)
* const newest = await posts.find().sort({ createdAt: -1 }).toArray();
*
* // Multiple field sort
* const sorted = await users.find()
* .sort({ status: 1, createdAt: -1 })
* .toArray();
* ```
*/
sort(sort: Record<string, 1 | -1>): QueryBuilder<TSchema>;
/**
* Set field projection (which fields to include/exclude)
*
* @param projection - Field projection specification
* @returns Query builder for chaining
*
* @example
* ```typescript
* // Include only specific fields
* const names = await users.find().project({ name: 1, email: 1 }).toArray();
*
* // Exclude specific fields
* const public = await users.find().project({ password: 0, apiKey: 0 }).toArray();
* ```
*/
project(projection: Record<string, 1 | 0>): QueryBuilder<TSchema>;
/**
* Set the maximum execution time for the query
*
* @param ms - Maximum time in milliseconds
* @returns Query builder for chaining
*
* @example
* ```typescript
* const results = await users.find().maxTimeMS(5000).toArray(); // 5 second timeout
* ```
*/
maxTimeMS(ms: number): QueryBuilder<TSchema>;
/**
* Set collation options for string comparison
*
* @param collation - Collation options
* @returns Query builder for chaining
*
* @example
* ```typescript
* const results = await users.find({ name: /john/i })
* .collation({ locale: 'en', strength: 2 })
* .toArray();
* ```
*/
collation(collation: CollationOptions): QueryBuilder<TSchema>;
/**
* Add additional filter conditions with $and logic
*
* @param filter - Additional filter conditions
* @returns Query builder for chaining
*
* @example
* ```typescript
* const results = await users
* .find({ status: 'active' })
* .where({ age: { $gte: 18 } })
* .where({ country: 'US' })
* .toArray();
* ```
*/
where(filter: MongoFilter<TSchema>): QueryBuilder<TSchema>;
/**
* Execute the query and return all matching documents
*
* @returns Array of matching documents
*
* @example
* ```typescript
* const allUsers = await users.find().toArray();
* const activeUsers = await users.find({ status: 'active' }).toArray();
* ```
*/
toArray(): Promise<WithId<TSchema>[]>;
/**
* Execute the query and return the first matching document
*
* @returns First matching document or null
*
* @example
* ```typescript
* const user = await users.find({ email: 'john@example.com' }).first();
* const newest = await posts.find().sort({ createdAt: -1 }).first();
* ```
*/
first(): Promise<WithId<TSchema> | null>;
/**
* Execute the query and return a stream of documents
*
* @param options - Streaming options
* @returns Async iterable stream
*
* @example
* ```typescript
* const stream = users.find({ status: 'active' }).stream();
* for await (const user of stream) {
* console.log('Processing user:', user.name);
* }
* ```
*/
stream(options?: StreamOptions): Promise<AsyncIterable<WithId<TSchema>>>;
/**
* Count the number of documents matching the query
*
* @returns Number of matching documents
*
* @example
* ```typescript
* const activeCount = await users.find({ status: 'active' }).count();
* const totalCount = await users.find().count();
* ```
*/
count(): Promise<number>;
/**
* Get distinct values for a field across matching documents
*
* @param field - Field name
* @returns Array of distinct values
*
* @example
* ```typescript
* const countries = await users.find({ status: 'active' }).distinct('country');
* const tags = await posts.find().distinct('tags');
* ```
*/
distinct<K extends keyof TSchema>(field: K): Promise<TSchema[K][]>;
/**
* Execute an aggregation pipeline
*
* @param pipeline - Aggregation pipeline stages
* @returns Aggregation results
*
* @example
* ```typescript
* const stats = await users.find().aggregate([
* { $match: { status: 'active' } },
* { $group: { _id: '$country', count: { $sum: 1 } } },
* { $sort: { count: -1 } }
* ]);
* ```
*/
aggregate<T = any>(pipeline: Record<string, any>[]): Promise<T[]>;
/**
* Explain the query execution plan
*
* @param verbosity - Explanation verbosity level
* @returns Query execution plan
*
* @example
* ```typescript
* const plan = await users.find({ email: 'john@example.com' }).explain();
* console.log('Execution time:', plan.executionTimeMillis);
* console.log('Indexes used:', plan.indexesUsed);
* ```
*/
explain(verbosity?: 'queryPlanner' | 'executionStats' | 'allPlansExecution'): Promise<any>;
/**
* Create a cursor for iterating through results
*
* @returns Query cursor
*
* @example
* ```typescript
* const cursor = users.find({ status: 'active' }).cursor();
*
* while (await cursor.hasNext()) {
* const user = await cursor.next();
* console.log('Processing:', user.name);
* }
*
* await cursor.close();
* ```
*/
cursor(): QueryCursor<TSchema>;
/**
* Clone the query builder with additional options
*/
private clone;
/**
* Create async iterable from streaming response
*/
private createAsyncIterable;
}
/**
* Query cursor for iterating through large result sets
*/
declare class QueryCursor<TSchema extends Document = Document> {
private httpClient;
private baseUrl;
private filter;
private options;
private cursorId;
private buffer;
private bufferIndex;
private isExhausted;
private batchSize;
constructor(httpClient: HttpClient, baseUrl: string, filter: MongoFilter<TSchema>, options: FindOptions);
/**
* Set cursor batch size
*
* @param size - Batch size
* @returns Cursor for chaining
*/
batchSize(size: number): QueryCursor<TSchema>;
/**
* Check if cursor has more documents
*
* @returns True if more documents available
*/
hasNext(): Promise<boolean>;
/**
* Get the next document from cursor
*
* @returns Next document or null if exhausted
*/
next(): Promise<WithId<TSchema> | null>;
/**
* Get the next batch of documents
*
* @param size - Batch size (optional)
* @returns Array of documents
*/
nextBatch(size?: number): Promise<WithId<TSchema>[]>;
/**
* Convert cursor to array (loads all remaining documents)
*
* @returns Array of all remaining documents
*/
toArray(): Promise<WithId<TSchema>[]>;
/**
* Iterate through cursor with forEach
*
* @param callback - Function to call for each document
*/
forEach(callback: (doc: WithId<TSchema>, index: number) => void | Promise<void>): Promise<void>;
/**
* Map cursor documents to new values
*
* @param mapper - Mapping function
* @returns Array of mapped values
*/
map<U>(mapper: (doc: WithId<TSchema>, index: number) => U | Promise<U>): Promise<U[]>;
/**
* Close the cursor and free resources
*/
close(): Promise<void>;
/**
* Fetch next batch of documents from server
*/
private fetchNextBatch;
/**
* Initialize cursor with first batch
*/
private initializeCursor;
/**
* Get more documents from existing cursor
*/
private getMoreFromCursor;
/**
* Make cursor iterable
*/
[Symbol.asyncIterator](): AsyncIterator<WithId<TSchema>>;
}
/**
* Vector operations for similarity search and vector management
*/
interface VectorInsertOptions {
/** Field name to store the vector (default: '_vector') */
vectorField?: string;
/** Whether to normalize the vector */
normalize?: boolean;
/** Generate embedding from text content */
generateEmbedding?: {
/** Text content to generate embedding from */
content: string;
/** Model to use for embedding generation */
model?: string;
/** Field to store the text content */
contentField?: string;
};
}
interface VectorUpdateOptions extends VectorInsertOptions {
/** Update only the vector without touching other fields */
vectorOnly?: boolean;
}
interface VectorBatchInsertOptions extends VectorInsertOptions {
/** Batch size for processing */
batchSize?: number;
/** Continue processing on individual errors */
continueOnError?: boolean;
}
interface HybridSearchOptions extends VectorSearchOptions {
/** Text query for full-text search */
textQuery?: string;
/** Weight for vector similarity (0-1) */
vectorWeight?: number;
/** Weight for text relevance (0-1) */
textWeight?: number;
/** Weight for metadata filters (0-1) */
metadataWeight?: number;
}
interface VectorAnalytics {
/** Total vectors stored */
totalVectors: number;
/** Average vector similarity within collection */
averageSimilarity: number;
/** Vector distribution by clusters */
clusters: Array<{
centroid: number[];
size: number;
averageDistance: number;
}>;
/** Most similar document pairs */
similarPairs: Array<{
document1: string;
document2: string;
similarity: number;
}>;
}
/**
* Vector operations class providing similarity search and vector management
*
* @example
* ```typescript
* const vectors = collection.vectors();
*
* // Insert document with vector
* await vectors.insertWithVector({
* title: 'Machine Learning Guide',
* content: 'A comprehensive guide to ML...'
* }, [0.1, 0.2, 0.3, ...], { vectorField: 'embedding' });
*
* // Search for similar documents
* const similar = await vectors.search(queryVector, {
* limit: 10,
* threshold: 0.8,
* filter: { category: 'technology' }
* });
* ```
*/
declare class VectorOperations<TSchema extends Document = Document> {
private httpClient;
private baseUrl;
private config;
constructor(httpClient: HttpClient, baseUrl: string, config: EdgeVectorConfig);
/**
* Search for similar vectors using approximate nearest neighbor
*
* @param vector - Query vector
* @param options - Search options
* @returns Array of similar documents with scores
*
* @example
* ```typescript
* const queryVector = [0.1, 0.2, 0.3, ...];
* const results = await vectors.search(queryVector, {
* limit: 10,
* threshold: 0.8,
* metric: 'cosine',
* filter: { category: 'technology' }
* });
*
* results.forEach(result => {
* console.log(`Score: ${result.score}, Title: ${result.document.title}`);
* });
* ```
*/
search(vector: number[], options?: VectorSearchOptions): Promise<VectorSearchResult<WithId<TSchema>>[]>;
/**
* Perform hybrid search combining vector similarity and metadata filters
*
* @param vector - Query vector
* @param options - Hybrid search options
* @returns Array of documents with combined relevance scores
*
* @example
* ```typescript
* const results = await vectors.hybridSearch(queryVector, {
* textQuery: 'machine learning artificial intelligence',
* vectorWeight: 0.7,
* textWeight: 0.3,
* filter: { status: 'published', category: 'ai' },
* limit: 10
* });
* ```
*/
hybridSearch(vector: number[], options?: HybridSearchOptions): Promise<VectorSearchResult<WithId<TSchema>>[]>;
/**
* Find documents within a certain distance of the query vector
*
* @param vector - Query vector
* @param distance - Maximum distance threshold
* @param options - Search options
* @returns Array of documents within distance
*
* @example
* ```typescript
* const nearby = await vectors.searchWithinDistance(queryVector, 0.5, {
* metric: 'euclidean',
* limit: 20
* });
* ```
*/
searchWithinDistance(vector: number[], distance: number, options?: Omit<VectorSearchOptions, 'threshold'>): Promise<VectorSearchResult<WithId<TSchema>>[]>;
/**
* Batch search multiple vectors at once
*
* @param vectors - Array of query vectors
* @param options - Search options
* @returns Array of search results for each query vector
*
* @example
* ```typescript
* const queries = [vector1, vector2, vector3];
* const results = await vectors.batchSearch(queries, {
* limit: 5,
* threshold: 0.8
* });
*
* results.forEach((result, index) => {
* console.log(`Query ${index} found ${result.length} matches`);
* });
* ```
*/
batchSearch(vectors: number[][], options?: VectorSearchOptions): Promise<VectorSearchResult<WithId<TSchema>>[][]>;
/**
* Insert a document with an associated vector
*
* @param document - Document to insert
* @param vector - Vector to associate with document
* @param options - Insert options
* @returns Insert result with document ID
*
* @example
* ```typescript
* const embedding = await generateEmbedding('This is sample text');
* const result = await vectors.insertWithVector({
* title: 'Sample Document',
* content: 'This is sample text',
* category: 'example'
* }, embedding);
* ```
*/
insertWithVector(document: Omit<TSchema, '_id'>, vector: number[], options?: VectorInsertOptions): Promise<{
insertedId: string;
acknowledged: boolean;
}>;
/**
* Insert multiple documents with vectors in batch
*
* @param documents - Array of documents with vectors
* @param options - Batch insert options
* @returns Batch insert result
*
* @example
* ```typescript
* const documentsWithVectors = [
* { document: { title: 'Doc 1' }, vector: [0.1, 0.2, 0.3] },
* { document: { title: 'Doc 2' }, vector: [0.4, 0.5, 0.6] }
* ];
*
* const result = await vectors.batchInsertWithVectors(documentsWithVectors);
* ```
*/
batchInsertWithVectors(documents: Array<{
document: Omit<TSchema, '_id'>;
vector: number[];
}>, options?: VectorBatchInsertOptions): Promise<{
insertedIds: string[];
insertedCount: number;
acknowledged: boolean;
}>;
/**
* Update a document's vector
*
* @param filter - Document filter
* @param vector - New vector
* @param options - Update options
* @returns Update result
*
* @example
* ```typescript
* await vectors.updateVector(
* { _id: 'doc123' },
* newEmbedding,
* { vectorField: 'embedding' }
* );
* ```
*/
updateVector(filter: MongoFilter<TSchema>, vector: number[], options?: VectorUpdateOptions): Promise<{
matchedCount: number;
modifiedCount: number;
acknowledged: boolean;
}>;
/**
* Delete vectors matching a filter
*
* @param filter - Document filter
* @returns Delete result
*
* @example
* ```typescript
* await vectors.deleteVectors({ category: 'outdated' });
* ```
*/
deleteVectors(filter: MongoFilter<TSchema>): Promise<{
deletedCount: number;
acknowledged: boolean;
}>;
/**
* Create a vector index for optimized similarity search
*
* @param options - Index creation options
* @returns Index name
*
* @example
* ```typescript
* const indexName = await vectors.createIndex({
* field: 'embedding',
* dimensions: 1536,
* metric: 'cosine',
* approximate: true
* });
* ```
*/
createIndex(options: {
field?: string;
dimensions: number;
metric?: 'cosine' | 'euclidean' | 'dot_product' | 'manhattan';
approximate?: boolean;
name?: string;
}): Promise<string>;
/**
* List all vector indexes
*
* @returns Array of vector indexes
*
* @example
* ```typescript
* const indexes = await vectors.listIndexes();
* indexes.forEach(index => {
* console.log(`Index: ${index.name}, Dimensions: ${index.dimensions}`);
* });
* ```
*/
listIndexes(): Promise<VectorIndex[]>;
/**
* Drop a vector index
*
* @param indexName - Name of index to drop
*
* @example
* ```typescript
* await vectors.dropIndex('embedding_cosine_idx');
* ```
*/
dropIndex(indexName: string): Promise<void>;
/**
* Get vector analytics for the collection
*
* @param options - Analytics options
* @returns Vector analytics data
*
* @example
* ```typescript
* const analytics = await vectors.getAnalytics({
* includeClusters: true,
* topSimilarPairs: 10
* });
*
* console.log(`Total vectors: ${analytics.totalVectors}`);
* console.log(`Clusters found: ${analytics.clusters.length}`);
* ```
*/
getAnalytics(options?: {
vectorField?: string;
includeClusters?: boolean;
topSimilarPairs?: number;
sampleSize?: number;
}): Promise<VectorAnalytics>;
/**
* Find clusters of similar vectors
*
* @param options - Clustering options
* @returns Array of vector clusters
*
* @example
* ```typescript
* const clusters = await vectors.findClusters({
* numClusters: 10,
* algorithm: 'kmeans',
* minClusterSize: 5
* });
* ```
*/
findClusters(options?: {
numClusters?: number;
algorithm?: 'kmeans' | 'dbscan' | 'hierarchical';
minClusterSize?: number;
vectorField?: string;
}): Promise<Array<{
id: string;
centroid: number[];
members: string[];
averageDistance: number;
}>>;
/**
* Generate embedding from text using AI models
*
* @param text - Text to generate embedding for
* @param model - Model to use for embedding generation
* @returns Generated embedding vector
*
* @example
* ```typescript
* const embedding = await vectors.generateEmbedding(
* 'This is sample text for embedding generation',
* 'text-embedding-ada-002'
* );
* ```
*/
generateEmbedding(text: string, model?: string): Promise<{
vector: number[];
model: string;
tokens: number;
}>;
/**
* Calculate similarity between two vectors
*
* @param vector1 - First vector
* @param vector2 - Second vector
* @param metric - Distance metric to use
* @returns Similarity score
*
* @example
* ```typescript
* const similarity = vectors.calculateSimilarity(vector1, vector2, 'cosine');
* console.log(`Similarity: ${similarity}`);
* ```
*/
calculateSimilarity(vector1: number[], vector2: number[], metric?: 'cosine' | 'euclidean' | 'dot_product' | 'manhattan'): number;
/**
* Normalize a vector to unit length
*
* @param vector - Vector to normalize
* @returns Normalized vector
*
* @example
* ```typescript
* const normalized = vectors.normalizeVector([1, 2, 3, 4]);
* ```
*/
normalizeVector(vector: number[]): number[];
private validateVector;
private cosineSimilarity;
private dotProduct;
private euclideanDistance;
private manhattanDistance;
}
/**
* Time series operations for high-performance metrics and analytics
*/
interface TimeSeriesWriteOptions {
/** Batch size for bulk writes */
batchSize?: number;
/** Flush interval in milliseconds */
flushInterval?: number;
/** Enable compression */
compression?: boolean;
/** Precision for timestamps */
precision?: 'nanosecond' | 'microsecond' | 'millisecond' | 'second';
/** Tags to apply to all points */
defaultTags?: Record<string, string>;
}
interface TimeSeriesStreamOptions$1 {
/** Buffer size for streaming */
bufferSize?: number;
/** Compression type */
compression?: 'gzip' | 'lz4' | 'none';
/** Format for streaming data */
format?: 'json' | 'line-protocol' | 'parquet';
}
interface ContinuousQueryOptions {
/** Query name */
name: string;
/** SQL query to execute */
query: string;
/** Execution interval */
interval: string;
/** Data retention period */
retention?: string;
/** Output collection */
outputCollection?: string;
/** Enable query */
enabled?: boolean;
}
interface TimeSeriesSubscriptionOptions {
/** Metrics to subscribe to */
metrics: string | string[];
/** Tag filters */
filters?: Record<string, string | string[]>;
/** Aggregation window */
window?: string;
/** Aggregation functions */
aggregations?: AggregationType[];
/** Real-time threshold for anomaly detection */
anomalyThreshold?: number;
/** Buffer size for real-time updates */
bufferSize?: number;
}
interface AnomalyDetectionOptions {
/** Detection method */
method: 'isolation_forest' | 'statistical' | 'threshold' | 'seasonal';
/** Sensitivity level (0-1) */
sensitivity?: number;
/** Training window size */
trainingWindow?: string;
/** Minimum anomaly score */
minScore?: number;
/** Context window for comparison */
contextWindow?: string;
}
interface ForecastingOptions {
/** Forecasting method */
method: 'prophet' | 'arima' | 'linear_regression' | 'exponential_smoothing';
/** Forecast horizon */
horizon: string;
/** Include confidence intervals */
includeConfidence?: boolean;
/** Confidence level (0-1) */
confidenceLevel?: number;
/** Seasonal periods to consider */
seasonalPeriods?: string[];
}
/**
* Time series operations class for metrics, analytics, and real-time data processing
*
* @example
* ```typescript
* const ts = db.collection('metrics').timeseries();
*
* // Write time series data
* await ts.write({
* metric: 'cpu_usage',
* timestamp: Date.now(),
* value: 85.2,
* tags: { host: 'server-1', region: 'us-east' }
* });
*
* // Query time series data
* const results = await ts.query({
* metric: 'cpu_usage',
* timeRange: { start: '-1h', end: 'now' },
* aggregations: [{ type: 'avg', alias: 'average_cpu' }],
* interval: '5m'
* });
* ```
*/
declare class TimeSeriesOperations extends EventEmitter {
private httpClient;
private baseUrl;
private config;
private writeBuffer;
private writeTimer;
private writeOptions;
constructor(httpClient: HttpClient, baseUrl: string, config: EdgeVectorConfig);
/**
* Write a single time series point
*
* @param point - Time series data point
* @param options - Write options
*
* @example
* ```typescript
* await ts.write({
* metric: 'temperature',
* timestamp: Date.now(),
* value: 22.5,
* tags: { sensor: 'sensor-1', location: 'warehouse' },
* fields: { humidity: 45.2, pressure: 1013.25 }
* });
* ```
*/
write(point: TimeSeriesPoint, options?: TimeSeriesWriteOptions): Promise<void>;
/**
* Write multiple time series points in batch
*
* @param points - Array of time series points
* @param options - Write options
*
* @example
* ```typescript
* const points = [
* { metric: 'cpu_usage', timestamp: Date.now(), value: 85.2, tags: { host: 'server-1' } },
* { metric: 'memory_usage', timestamp: Date.now(), value: 67.8, tags: { host: 'server-1' } }
* ];
*
* await ts.writeBatch(points);
* ```
*/
writeBatch(points: TimeSeriesPoint[], options?: TimeSeriesWriteOptions): Promise<void>;
/**
* Create a write stream for high-throughput ingestion
*
* @param options - Stream options
* @returns Write stream
*
* @example
* ```typescript
* const stream = await ts.createWriteStream({
* batchSize: 5000,
* flushInterval: 100,
* compression: true
* });
*
* // Write data continuously
* setInterval(() => {
* stream.write({
* metric: 'requests_per_second',
* timestamp: Date.now(),
* value: Math.random() * 100,
* tags: { service: 'api' }
* });
* }, 100);
* ```
*/
createWriteStream(options?: TimeSeriesStreamOptions$1): Promise<TimeSeriesWriteStream>;
/**
* Query time series data with aggregations
*
* @param query - Time series query
* @returns Query results
*
* @example
* ```typescript
* const results = await ts.query({
* metric: 'cpu_usage',
* timeRange: { start: '-24h', end: 'now' },
* filters: { host: 'server-1', region: 'us-east' },
* aggregations: [
* { type: 'avg', alias: 'average' },
* { type: 'p95', alias: 'p95' },
* { type: 'max', alias: 'maximum' }
* ],
* groupBy: ['host'],
* interval: '1h',
* fill: 'linear'
* });
* ```
*/
query(query: TimeSeriesQuery): Promise<TimeSeriesResult[]>;
/**
* Query latest values for metrics
*
* @param metrics - Metric names or patterns
* @param filters - Tag filters
* @returns Latest values
*
* @example
* ```typescript
* const latest = await ts.queryLatest(['cpu_usage', 'memory_usage'], {
* host: 'server-1'
* });
* ```
*/
queryLatest(metrics: string | string[], filters?: Record<string, string | string[]>): Promise<TimeSeriesResult[]>;
/**
* Execute raw SQL query for complex analytics
*
* @param sql - SQL query string
* @param params - Query parameters
* @returns Query results
*
* @example
* ```typescript
* const results = await ts.sql(`
* SELECT
* time_bucket('1 hour', timestamp) as hour,
* avg(value) as avg_cpu,
* max(value) as max_cpu
* FROM timeseries
* WHERE metric = ? AND timestamp >= now() - interval '24 hours'
* GROUP BY hour
* ORDER BY hour DESC
* `, ['cpu_usage']);
* ```
*/
sql(sql: string, params?: any[]): Promise<any[]>;
/**
* Calculate moving averages for a metric
*
* @param metric - Metric name
* @param window - Window size (e.g., '15m', '1h')
* @param options - Additional options
* @returns Moving average results
*
* @example
* ```typescript
* const movingAvg = await ts.movingAverage('cpu_usage', '15m', {
* timeRange: { start: '-24h' },
* filters: { host: 'server-1' }
* });
* ```
*/
movingAverage(metric: string, window: string, options?: {
timeRange?: {
start: string | number | Date;
end?: string | number | Date;
};
filters?: Record<string, string | string[]>;
groupBy?: string[];
}): Promise<TimeSeriesResult[]>;
/**
* Calculate rate of change (derivative) for a metric
*
* @param metric - Metric name
* @param options - Calculation options
* @returns Rate of change results
*
* @example
* ```typescript
* const rates = await ts.rate('requests_total', {
* interval: '1m',
* timeRange: { start: '-1h' }
* });
* ```
*/
rate(metric: string, options?: {
interval?: string;
timeRange?: {
start: string | number | Date;
end?: string | number | Date;
};
filters?: Record<string, string | string[]>;
groupBy?: string[];
}): Promise<TimeSeriesResult[]>;
/**
* Perform aggregation across multiple metrics
*
* @param aggregation - Aggregation specification
* @returns Aggregated results
*
* @example
* ```typescript
* const result = await ts.aggregate({
* metrics: ['cpu_usage', 'memory_usage'],
* timeRange: { start: '-1h', end: 'now' },
* groupBy: ['host', 'region'],
* aggregations: [
* { type: 'avg', alias: 'mean' },
* { type: 'p95', alias: 'p95' }
* ],
* interval: '5m'
* });
* ```
*/
aggregate(aggregation: {
metrics: string | string[];
timeRange: {
start: string | number | Date;
end?: string | number | Date;
};
groupBy?: string[];
aggregations: AggregationSpec[];
interval?: string;
filters?: Record<string, string | string[]>;
having?: Record<string, any>;
}): Promise<TimeSeriesResult[]>;
/**
* Detect anomalies in time series data
*
* @param metric - Metric name
* @param options - Anomaly detection options
* @returns Detected anomalies
*
* @example
* ```typescript
* const anomalies = await ts.detectAnomalies('error_rate', {
* method: 'isolation_forest',
* sensitivity: 0.8,
* trainingWindow: '7d',
* timeRange: { start: '-24h' }
* });
* ```
*/
detectAnomalies(metric: string, options: AnomalyDetectionOptions & {
timeRange?: {
start: string | number | Date;
end?: string | number | Date;
};
filters?: Record<string, string | string[]>;
}): Promise<Array<{
timestamp: number;
value: number;
expected: number;
score: number;
severity: 'low' | 'medium' | 'high' | 'critical';
tags: Record<string, string>;
}>>;
/**
* Generate forecasts for time series data
*
* @param metric - Metric name
* @param options - Forecasting options
* @returns Forecast results
*
* @example
* ```typescri