/** * db4ai Type Definitions * * Type definitions for the db4ai client, including configuration options, * collection interfaces, and document types. * * @packageDocumentation */ /** * Remote endpoint configuration for connecting to db4 service. * * @example * ```typescript * const config: RemoteConfig = { * endpoint: 'https://api.db4.dev', * apiKey: 'sk_live_xxxx', * timeout: 5000, * retries: 3 * }; * ``` */ export interface RemoteConfig { /** The endpoint URL for the db4 service (must be https://) */ endpoint: string; /** API key for authentication */ apiKey: string; /** Optional request timeout in milliseconds (default: 30000) */ timeout?: number; /** Optional number of retry attempts for transient failures (default: 3) */ retries?: number; } /** * Service binding configuration for Cloudflare Workers. * Uses zero-latency internal communication. * * @example * ```typescript * // In a Cloudflare Worker * const config: BindingConfig = { * binding: env.DB4_SERVICE, * timeout: 5000 * }; * ``` */ export interface BindingConfig { /** Cloudflare service binding for direct RPC communication */ binding: Fetcher; /** Optional request timeout in milliseconds */ timeout?: number; } /** * Combined configuration type - either remote or binding. * * @example Remote configuration * ```typescript * const config: DB4Config = { * endpoint: 'https://api.db4.dev', * apiKey: 'sk_live_xxxx' * }; * ``` * * @example Binding configuration * ```typescript * const config: DB4Config = { * binding: env.DB4_SERVICE * }; * ``` */ export type DB4Config = RemoteConfig | BindingConfig; /** * Type guard to check if config is for remote endpoint. * * @param config - The configuration to check * @returns True if the config is a RemoteConfig * * @example * ```typescript * if (isRemoteConfig(config)) { * console.log('Using remote endpoint:', config.endpoint); * } * ``` */ export declare function isRemoteConfig(config: DB4Config): config is RemoteConfig; /** * Type guard to check if config is for service binding. * * @param config - The configuration to check * @returns True if the config is a BindingConfig * * @example * ```typescript * if (isBindingConfig(config)) { * console.log('Using zero-latency service binding'); * } * ``` */ export declare function isBindingConfig(config: DB4Config): config is BindingConfig; /** * Base document interface with optional id. * Extend this interface for your document types. * * @example * ```typescript * interface User extends Document { * name: string; * email: string; * } * ``` */ export interface Document { id?: string; [key: string]: unknown; } /** * Document with required id field. * Used for documents returned from the database. * * @typeParam T - The base document type * * @example * ```typescript * type UserWithId = WithId; * // { id: string; name: string; email: string; } * ``` */ export type WithId = T & { id: string; }; /** * Document without id field for creation. * Used when creating new documents. * * @typeParam T - The base document type * * @example * ```typescript * type NewUser = WithoutId; * // { name: string; email: string; } (id is omitted) * ``` */ export type WithoutId = Omit; /** * Partial document for updates. * All fields become optional. * * @typeParam T - The base document type */ export type PartialDoc = Partial>; /** * Deep partial type for nested updates. * * @typeParam T - The base type */ export type DeepPartial = { [P in keyof T]?: T[P] extends object ? DeepPartial : T[P]; }; /** * Filter condition for a single field. * * @typeParam T - The field value type */ export type FilterCondition = T | { $eq?: T; $ne?: T; $gt?: T; $gte?: T; $lt?: T; $lte?: T; $in?: T[]; $nin?: T[]; $contains?: string; $startsWith?: string; $endsWith?: string; $exists?: boolean; $regex?: string; }; /** * Filter query for documents. * * @typeParam T - The document type * * @example * ```typescript * const filter: Filter = { * status: { $eq: 'active' }, * age: { $gte: 18 } * }; * ``` */ export type Filter = { [K in keyof T]?: FilterCondition; } & { $and?: Filter[]; $or?: Filter[]; $not?: Filter; }; /** * Sort direction for ordering. */ export type SortDirection = 'asc' | 'desc' | 1 | -1; /** * Sort specification for documents. * * @typeParam T - The document type */ export type Sort = { [K in keyof T]?: SortDirection; }; /** * Projection for selecting fields. * * @typeParam T - The document type */ export type Projection = { [K in keyof T]?: boolean | 0 | 1; }; /** * Result of updateMany operation. */ export interface UpdateManyResult { /** Number of documents modified */ modifiedCount: number; /** Whether the operation was acknowledged */ acknowledged?: boolean; } /** * Result of deleteMany operation. */ export interface DeleteManyResult { /** Number of documents deleted */ deletedCount: number; /** Whether the operation was acknowledged */ acknowledged?: boolean; } /** * Result of insertMany operation. * * @typeParam T - The document type */ export interface InsertManyResult { /** Number of documents inserted */ insertedCount: number; /** The inserted documents with their ids */ insertedDocs: WithId[]; } /** * Result of a find operation with metadata. * * @typeParam T - The document type */ export interface FindResult { /** The matching documents */ docs: WithId[]; /** Total count of matching documents (if countTotal was requested) */ totalCount?: number; /** Whether there are more results available */ hasMore?: boolean; /** Cursor for pagination */ cursor?: string; } /** * Options for find operations. * * @typeParam T - The document type */ export interface FindOptions { /** Filter conditions */ filter?: Filter; /** Fields to include/exclude */ projection?: Projection; /** Sort order */ sort?: Sort; /** Maximum number of results */ limit?: number; /** Number of results to skip */ skip?: number; /** Count total matching documents */ countTotal?: boolean; } /** * Collection interface for CRUD operations on documents. * Provides a fluent API for interacting with document collections. * * @typeParam T - The document type for this collection * * @example * ```typescript * interface User { * name: string; * email: string; * age: number; * } * * const users: Collection = db.users; * * // Create * const user = await users.create({ name: 'Alice', email: 'alice@example.com', age: 30 }); * * // Read * const found = await users.get(user.id); * const admins = await users.find({ role: 'admin' }); * * // Update * await users.update(user.id, { age: 31 }); * * // Delete * await users.delete(user.id); * ``` */ export interface Collection { /** * Create a single document. * * @param doc - Document data without id * @returns Created document with generated id * * @example * ```typescript * const user = await users.create({ * name: 'Alice', * email: 'alice@example.com' * }); * console.log(user.id); // Generated id * ``` */ create(doc: WithoutId): Promise>; /** * Create multiple documents in batch. * More efficient than multiple individual creates. * * @param docs - Array of document data without ids * @returns Array of created documents with generated ids * * @example * ```typescript * const users = await collection.createMany([ * { name: 'Alice', email: 'alice@example.com' }, * { name: 'Bob', email: 'bob@example.com' } * ]); * ``` */ createMany(docs: WithoutId[]): Promise[]>; /** * Alias for createMany - insert multiple documents. * * @param docs - Array of document data without ids * @returns Array of created documents with generated ids */ insertMany?(docs: WithoutId[]): Promise[]>; /** * Get a document by id. * * @param id - Document id * @returns Document if found, null otherwise * * @example * ```typescript * const user = await users.get('user_123'); * if (user) { * console.log(user.name); * } * ``` */ get(id: string): Promise | null>; /** * Alias for get - find a document by id. * * @param id - Document id * @returns Document if found, null otherwise */ findById?(id: string): Promise | null>; /** * Find documents matching a query. * * @param query - Optional query object for filtering * @returns Array of matching documents * * @example * ```typescript * // Find all documents * const all = await users.find(); * * // Find with filter * const admins = await users.find({ role: 'admin' }); * * // Find with operators * const adults = await users.find({ age: { $gte: 18 } }); * ``` */ find(query?: Record): Promise[]>; /** * Find the first document matching a query. * * @param query - Query object for filtering * @returns First matching document or null * * @example * ```typescript * const admin = await users.findOne({ role: 'admin' }); * ``` */ findOne(query: Record): Promise | null>; /** * Find the first document matching a query, or throw if not found. * * @param query - Query object for filtering * @returns First matching document * @throws Error if no document matches * * @example * ```typescript * const user = await users.findOneOrThrow({ email: 'alice@example.com' }); * ``` */ findOneOrThrow?(query: Record): Promise>; /** * Check if a document exists matching the query. * * @param query - Query object for filtering * @returns True if a matching document exists * * @example * ```typescript * const exists = await users.exists({ email: 'alice@example.com' }); * ``` */ exists?(query: Record): Promise; /** * Count documents matching a query. * * @param query - Optional query object for filtering * @returns Number of matching documents * * @example * ```typescript * const totalUsers = await users.count(); * const adminCount = await users.count({ role: 'admin' }); * ``` */ count(query?: Record): Promise; /** * Update a document by id. * * @param id - Document id * @param changes - Partial document with fields to update * @returns Updated document * * @example * ```typescript * const updated = await users.update(user.id, { age: 31 }); * ``` */ update(id: string, changes: Partial): Promise>; /** * Update multiple documents matching a query. * * @param query - Query object for filtering * @param changes - Partial document with fields to update * @returns Result with count of modified documents * * @example * ```typescript * const result = await users.updateMany( * { status: 'pending' }, * { status: 'active' } * ); * console.log(`Updated ${result.modifiedCount} users`); * ``` */ updateMany(query: Record, changes: Partial): Promise; /** * Upsert a document - update if exists, create if not. * * @param query - Query to find existing document * @param doc - Document data for create/update * @returns The upserted document * * @example * ```typescript * const user = await users.upsert( * { email: 'alice@example.com' }, * { name: 'Alice', email: 'alice@example.com', role: 'user' } * ); * ``` */ upsert(query: Record, doc: WithoutId): Promise>; /** * Replace a document entirely by id. * * @param id - Document id * @param doc - New document data * @returns Replaced document */ replace?(id: string, doc: WithoutId): Promise>; /** * Delete a document by id. * * @param id - Document id * @returns True if document was deleted, false if not found * * @example * ```typescript * const deleted = await users.delete(user.id); * if (deleted) { * console.log('User deleted'); * } * ``` */ delete(id: string): Promise; /** * Delete multiple documents matching a query. * * @param query - Query object for filtering * @returns Result with count of deleted documents * * @example * ```typescript * const result = await users.deleteMany({ status: 'inactive' }); * console.log(`Deleted ${result.deletedCount} users`); * ``` */ deleteMany(query: Record): Promise; /** * Alias for delete - remove a document by id. * * @param id - Document id * @returns True if document was deleted */ remove?(id: string): Promise; /** * Alias for deleteMany - remove multiple documents. * * @param query - Query object for filtering * @returns Result with count of deleted documents */ removeMany?(query: Record): Promise; } /** * DB4 Client interface with typed collections. * Access collections as properties on the client. * * @typeParam TSchema - Schema type mapping collection names to document types * * @example * ```typescript * interface User { * name: string; * email: string; * } * * interface Post { * title: string; * content: string; * authorId: string; * } * * type Schema = { * users: User; * posts: Post; * }; * * const db = db4({ endpoint: '...', apiKey: '...' }); * * // Access typed collections * const user = await db.users.create({ name: 'Alice', email: 'alice@example.com' }); * const posts = await db.posts.find({ authorId: user.id }); * ``` */ export type DB4Client> = { [K in keyof TSchema]: Collection; } & { /** Close the client connection and clean up resources */ close(): Promise; /** * Get a collection by name. * Useful when the collection name is dynamic. * * @param name - Collection name * @returns The collection */ collection?(name: K): Collection; /** * Get client statistics for monitoring performance. * @returns Cache and pool statistics */ stats?(): ClientStats; }; /** * Client performance options for caching, pooling, and initialization. * * @example * ```typescript * const options: ClientOptions = { * enableCache: true, * cacheConfig: { * maxEntries: 2000, * defaultTtl: 60000, * evictionPolicy: 'lru' * }, * enablePooling: true, * poolConfig: { * maxConnections: 20, * idleTimeout: 120000 * }, * lazyInit: true * }; * ``` */ export interface ClientOptions { /** Enable query caching (default: true) */ enableCache?: boolean; /** Cache configuration */ cacheConfig?: { /** Maximum number of cached entries (default: 1000) */ maxEntries?: number; /** Default TTL in milliseconds (default: 30000) */ defaultTtl?: number; /** Eviction policy: 'lru' (least recently used), 'lfu' (least frequently used), 'fifo' */ evictionPolicy?: 'lru' | 'lfu' | 'fifo'; }; /** Enable connection pooling (default: true for remote config) */ enablePooling?: boolean; /** Connection pool configuration */ poolConfig?: { /** Minimum connections to maintain (default: 0) */ minConnections?: number; /** Maximum connections allowed (default: 10) */ maxConnections?: number; /** Maximum idle time before closing connection in ms (default: 60000) */ idleTimeout?: number; }; /** Use lazy initialization - resources are created on first use (default: true) */ lazyInit?: boolean; } /** * Client statistics for monitoring and debugging. * * @example * ```typescript * const stats = client.stats?.(); * if (stats?.cache) { * console.log(`Cache hit ratio: ${(stats.cache.hitRatio * 100).toFixed(1)}%`); * } * if (stats?.pool) { * console.log(`Pool utilization: ${stats.pool.active}/${stats.pool.active + stats.pool.idle}`); * } * ``` */ export interface ClientStats { /** Cache statistics */ cache?: CacheStats; /** Connection pool statistics */ pool?: PoolStats; } /** * Cache performance statistics. */ export interface CacheStats { /** Total number of cache hits */ hits: number; /** Total number of cache misses */ misses: number; /** Hit ratio (0-1), higher is better */ hitRatio: number; /** Current number of cached entries */ entries: number; /** Current cache size in bytes */ size: number; /** Number of entries evicted due to capacity */ evictions: number; /** Number of entries expired due to TTL */ expirations: number; } /** * Connection pool statistics. */ export interface PoolStats { /** Total connections ever created */ totalCreated: number; /** Currently active connections */ active: number; /** Currently idle connections */ idle: number; /** Total requests served */ totalRequests: number; /** Average number of times each connection was reused */ averageReuse: number; /** Peak concurrent connections seen */ peakConcurrent: number; } //# sourceMappingURL=types.d.ts.map