Phase 2 build initial

This commit is contained in:
Claude Code
2025-07-30 09:34:16 +10:00
parent 8f19eaab25
commit a6ee31f237
68 changed files with 18055 additions and 3 deletions

View File

@@ -0,0 +1,77 @@
{
"name": "@hcfs/sdk",
"version": "2.0.0",
"description": "JavaScript/TypeScript SDK for the Context-Aware Hierarchical Context File System",
"main": "dist/index.js",
"module": "dist/index.esm.js",
"types": "dist/index.d.ts",
"files": [
"dist"
],
"scripts": {
"build": "rollup -c",
"dev": "rollup -c -w",
"test": "jest",
"test:watch": "jest --watch",
"test:coverage": "jest --coverage",
"lint": "eslint src --ext .ts,.js",
"lint:fix": "eslint src --ext .ts,.js --fix",
"typecheck": "tsc --noEmit",
"docs": "typedoc src/index.ts",
"prepublishOnly": "npm run build"
},
"keywords": [
"hcfs",
"context",
"ai",
"search",
"embeddings",
"typescript",
"javascript",
"sdk"
],
"author": "HCFS Development Team <dev@hcfs.dev>",
"license": "MIT",
"repository": {
"type": "git",
"url": "https://github.com/hcfs/hcfs.git",
"directory": "sdks/javascript"
},
"bugs": {
"url": "https://github.com/hcfs/hcfs/issues"
},
"homepage": "https://docs.hcfs.dev/sdk/javascript",
"engines": {
"node": ">=14.0.0"
},
"dependencies": {
"axios": "^1.6.0",
"ws": "^8.14.0",
"eventemitter3": "^5.0.1"
},
"devDependencies": {
"@types/jest": "^29.5.0",
"@types/node": "^20.0.0",
"@types/ws": "^8.5.0",
"@typescript-eslint/eslint-plugin": "^6.0.0",
"@typescript-eslint/parser": "^6.0.0",
"eslint": "^8.50.0",
"jest": "^29.7.0",
"rollup": "^4.0.0",
"@rollup/plugin-typescript": "^11.1.0",
"@rollup/plugin-node-resolve": "^15.2.0",
"@rollup/plugin-commonjs": "^25.0.0",
"rollup-plugin-dts": "^6.1.0",
"ts-jest": "^29.1.0",
"typescript": "^5.2.0",
"typedoc": "^0.25.0"
},
"peerDependencies": {
"typescript": ">=4.5.0"
},
"peerDependenciesMeta": {
"typescript": {
"optional": true
}
}
}

View File

@@ -0,0 +1,574 @@
/**
* HCFS JavaScript/TypeScript Client
*
* Main client class for interacting with the HCFS API
*/
import axios, { AxiosInstance, AxiosRequestConfig, AxiosResponse } from 'axios';
import { EventEmitter } from 'eventemitter3';
import {
HCFSConfig,
Context,
ContextCreate,
ContextUpdate,
ContextFilter,
PaginationOptions,
SearchOptions,
SearchResult,
BatchResult,
AnalyticsData,
APIResponse,
ListResponse,
SearchResponse,
HealthResponse,
StatsResponse,
RequestOptions,
HttpMethod
} from './types';
import {
HCFSError,
HCFSConnectionError,
HCFSAuthenticationError,
HCFSNotFoundError,
HCFSValidationError,
HCFSRateLimitError,
HCFSServerError
} from './errors';
import { LRUCache } from './cache';
import { RetryManager } from './retry';
import { validatePath, normalizePath } from './utils';
/**
* Main HCFS client for JavaScript/TypeScript applications
*
* @example
* ```typescript
* const client = new HCFSClient({
* baseUrl: 'https://api.hcfs.dev/v1',
* apiKey: 'your-api-key',
* timeout: 30000,
* cache: { enabled: true, maxSize: 1000 }
* });
*
* // Create a context
* const context = await client.createContext({
* path: '/docs/readme',
* content: 'Hello, HCFS!',
* summary: 'Getting started'
* });
*
* // Search contexts
* const results = await client.searchContexts('hello world', {
* searchType: 'semantic',
* topK: 10
* });
* ```
*/
export class HCFSClient extends EventEmitter {
private readonly config: Required<HCFSConfig>;
private readonly httpClient: AxiosInstance;
private readonly cache?: LRUCache<any>;
private readonly retryManager: RetryManager;
private readonly analytics: AnalyticsData;
constructor(config: HCFSConfig) {
super();
// Merge with defaults
this.config = {
baseUrl: config.baseUrl,
apiKey: config.apiKey,
jwtToken: config.jwtToken,
timeout: config.timeout ?? 30000,
userAgent: config.userAgent ?? `@hcfs/sdk/2.0.0`,
cache: {
enabled: config.cache?.enabled ?? true,
strategy: config.cache?.strategy ?? 'lru',
maxSize: config.cache?.maxSize ?? 1000,
ttl: config.cache?.ttl ?? 3600000,
memoryLimit: config.cache?.memoryLimit ?? 100,
...config.cache
},
retry: {
enabled: config.retry?.enabled ?? true,
maxAttempts: config.retry?.maxAttempts ?? 3,
baseDelay: config.retry?.baseDelay ?? 1000,
maxDelay: config.retry?.maxDelay ?? 30000,
backoffMultiplier: config.retry?.backoffMultiplier ?? 2,
jitter: config.retry?.jitter ?? true,
retryOnStatus: config.retry?.retryOnStatus ?? [429, 500, 502, 503, 504],
retryOnTimeout: config.retry?.retryOnTimeout ?? true,
...config.retry
},
websocket: {
autoReconnect: config.websocket?.autoReconnect ?? true,
reconnectInterval: config.websocket?.reconnectInterval ?? 5000,
maxReconnectAttempts: config.websocket?.maxReconnectAttempts ?? 10,
pingInterval: config.websocket?.pingInterval ?? 30000,
pingTimeout: config.websocket?.pingTimeout ?? 10000,
messageQueueSize: config.websocket?.messageQueueSize ?? 1000,
...config.websocket
},
maxConcurrentRequests: config.maxConcurrentRequests ?? 100,
keepAlive: config.keepAlive ?? true
};
// Initialize HTTP client
this.httpClient = axios.create({
baseURL: this.config.baseUrl,
timeout: this.config.timeout,
headers: {
'User-Agent': this.config.userAgent,
'Content-Type': 'application/json',
...(this.config.apiKey && { 'X-API-Key': this.config.apiKey }),
...(this.config.jwtToken && { 'Authorization': `Bearer ${this.config.jwtToken}` })
}
});
// Initialize cache
if (this.config.cache.enabled) {
this.cache = new LRUCache(this.config.cache.maxSize, this.config.cache.ttl);
}
// Initialize retry manager
this.retryManager = new RetryManager(this.config.retry);
// Initialize analytics
this.analytics = {
operationCount: {},
cacheStats: {},
errorStats: {},
performanceStats: {},
sessionStart: new Date()
};
// Setup request/response interceptors
this.setupInterceptors();
}
/**
* Setup axios interceptors for error handling and monitoring
*/
private setupInterceptors(): void {
// Request interceptor
this.httpClient.interceptors.request.use(
(config) => {
// Track request
const operation = `${config.method?.toUpperCase()} ${config.url}`;
this.updateAnalytics(operation, true);
this.emit('request', { method: config.method, url: config.url });
return config;
},
(error) => {
this.updateAnalytics('request_error', false, error.message);
return Promise.reject(error);
}
);
// Response interceptor
this.httpClient.interceptors.response.use(
(response) => {
this.emit('response', {
status: response.status,
url: response.config.url,
duration: Date.now() - (response.config as any).startTime
});
return response;
},
(error) => {
const operation = `${error.config?.method?.toUpperCase()} ${error.config?.url}`;
this.updateAnalytics(operation, false, error.message);
this.emit('error', {
status: error.response?.status,
message: error.message,
url: error.config?.url
});
return Promise.reject(this.handleApiError(error));
}
);
}
/**
* Handle API errors and convert to appropriate HCFS error types
*/
private handleApiError(error: any): HCFSError {
if (error.code === 'ECONNABORTED' || error.code === 'ENOTFOUND') {
return new HCFSConnectionError(`Connection failed: ${error.message}`);
}
if (!error.response) {
return new HCFSConnectionError(`Network error: ${error.message}`);
}
const { status, data } = error.response;
switch (status) {
case 400:
return new HCFSValidationError(
data.error || 'Validation failed',
data.errorDetails || []
);
case 401:
return new HCFSAuthenticationError(data.error || 'Authentication failed');
case 404:
return new HCFSNotFoundError(data.error || 'Resource not found');
case 429:
const retryAfter = error.response.headers['retry-after'];
return new HCFSRateLimitError(
data.error || 'Rate limit exceeded',
retryAfter ? parseInt(retryAfter) : undefined
);
case 500:
case 502:
case 503:
case 504:
return new HCFSServerError(data.error || 'Server error', status);
default:
return new HCFSError(data.error || `HTTP ${status} error`, status.toString());
}
}
/**
* Make an HTTP request with retry logic and caching
*/
private async request<T>(options: RequestOptions): Promise<T> {
const cacheKey = this.getCacheKey(options);
// Try cache first for GET requests
if (options.method === 'GET' && this.cache && cacheKey) {
const cached = this.cache.get(cacheKey);
if (cached) {
this.analytics.cacheStats.hits = (this.analytics.cacheStats.hits || 0) + 1;
return cached;
}
this.analytics.cacheStats.misses = (this.analytics.cacheStats.misses || 0) + 1;
}
// Make request with retry logic
const response = await this.retryManager.execute(async () => {
const axiosConfig: AxiosRequestConfig = {
method: options.method,
url: options.url,
data: options.data,
params: options.params,
headers: options.headers,
timeout: options.timeout || this.config.timeout,
startTime: Date.now()
} as any;
return this.httpClient.request<APIResponse<T>>(axiosConfig);
});
const result = response.data.data;
// Cache GET responses
if (options.method === 'GET' && this.cache && cacheKey) {
this.cache.set(cacheKey, result);
}
return result;
}
/**
* Generate cache key for request
*/
private getCacheKey(options: RequestOptions): string | null {
if (options.method !== 'GET') return null;
const params = options.params ? JSON.stringify(options.params) : '';
return `${options.url}:${params}`;
}
/**
* Update analytics tracking
*/
private updateAnalytics(operation: string, success: boolean, error?: string): void {
this.analytics.operationCount[operation] = (this.analytics.operationCount[operation] || 0) + 1;
if (!success && error) {
this.analytics.errorStats[error] = (this.analytics.errorStats[error] || 0) + 1;
}
}
/**
* Check API health status
*/
async healthCheck(): Promise<HealthResponse> {
return this.request({
method: 'GET',
url: '/health'
});
}
/**
* Create a new context
*/
async createContext(contextData: ContextCreate): Promise<Context> {
if (!validatePath(contextData.path)) {
throw new HCFSValidationError(`Invalid context path: ${contextData.path}`);
}
const normalizedData = {
...contextData,
path: normalizePath(contextData.path)
};
const context = await this.request<Context>({
method: 'POST',
url: '/api/v1/contexts',
data: normalizedData
});
// Invalidate relevant cache entries
this.invalidateCache('/api/v1/contexts');
return context;
}
/**
* Get a context by ID
*/
async getContext(contextId: number): Promise<Context> {
return this.request<Context>({
method: 'GET',
url: `/api/v1/contexts/${contextId}`
});
}
/**
* List contexts with filtering and pagination
*/
async listContexts(
filter?: ContextFilter,
pagination?: PaginationOptions
): Promise<{ contexts: Context[]; pagination: any }> {
const params: Record<string, any> = {};
// Add filter parameters
if (filter) {
if (filter.pathPrefix) params.path_prefix = filter.pathPrefix;
if (filter.author) params.author = filter.author;
if (filter.status) params.status = filter.status;
if (filter.createdAfter) params.created_after = filter.createdAfter.toISOString();
if (filter.createdBefore) params.created_before = filter.createdBefore.toISOString();
if (filter.contentContains) params.content_contains = filter.contentContains;
if (filter.minContentLength) params.min_content_length = filter.minContentLength;
if (filter.maxContentLength) params.max_content_length = filter.maxContentLength;
}
// Add pagination parameters
if (pagination) {
if (pagination.page) params.page = pagination.page;
if (pagination.pageSize) params.page_size = pagination.pageSize;
if (pagination.sortBy) params.sort_by = pagination.sortBy;
if (pagination.sortOrder) params.sort_order = pagination.sortOrder;
}
const response = await this.httpClient.get<ListResponse<Context>>('/api/v1/contexts', { params });
return {
contexts: response.data.data,
pagination: response.data.pagination
};
}
/**
* Update an existing context
*/
async updateContext(contextId: number, updates: ContextUpdate): Promise<Context> {
const context = await this.request<Context>({
method: 'PUT',
url: `/api/v1/contexts/${contextId}`,
data: updates
});
// Invalidate cache
this.invalidateCache(`/api/v1/contexts/${contextId}`);
this.invalidateCache('/api/v1/contexts');
return context;
}
/**
* Delete a context
*/
async deleteContext(contextId: number): Promise<void> {
await this.request({
method: 'DELETE',
url: `/api/v1/contexts/${contextId}`
});
// Invalidate cache
this.invalidateCache(`/api/v1/contexts/${contextId}`);
this.invalidateCache('/api/v1/contexts');
}
/**
* Search contexts
*/
async searchContexts(
query: string,
options?: SearchOptions
): Promise<SearchResult[]> {
const searchData = {
query,
search_type: options?.searchType || 'semantic',
top_k: options?.topK || 10,
similarity_threshold: options?.similarityThreshold || 0.0,
path_prefix: options?.pathPrefix,
semantic_weight: options?.semanticWeight || 0.7,
include_content: options?.includeContent ?? true,
include_highlights: options?.includeHighlights ?? true,
max_highlights: options?.maxHighlights || 3
};
const response = await this.httpClient.post<SearchResponse>('/api/v1/search', searchData);
return response.data.data;
}
/**
* Create multiple contexts in batch
*/
async batchCreateContexts(contexts: ContextCreate[]): Promise<BatchResult> {
const startTime = Date.now();
// Validate all contexts
for (const context of contexts) {
if (!validatePath(context.path)) {
throw new HCFSValidationError(`Invalid context path: ${context.path}`);
}
}
const normalizedContexts = contexts.map(ctx => ({
...ctx,
path: normalizePath(ctx.path)
}));
const response = await this.httpClient.post('/api/v1/contexts/batch', {
contexts: normalizedContexts
});
const executionTime = Date.now() - startTime;
const result = response.data.data;
// Invalidate cache
this.invalidateCache('/api/v1/contexts');
return {
...result,
executionTime,
successRate: result.success_count / result.total_items
};
}
/**
* Get comprehensive statistics
*/
async getStatistics(): Promise<StatsResponse> {
return this.request<StatsResponse>({
method: 'GET',
url: '/api/v1/stats'
});
}
/**
* Iterate through all contexts with automatic pagination
*/
async *iterateContexts(
filter?: ContextFilter,
pageSize: number = 100
): AsyncIterableIterator<Context> {
let page = 1;
while (true) {
const result = await this.listContexts(filter, { page, pageSize });
if (result.contexts.length === 0) {
break;
}
for (const context of result.contexts) {
yield context;
}
// If we got fewer contexts than requested, we've reached the end
if (result.contexts.length < pageSize) {
break;
}
page++;
}
}
/**
* Clear cache
*/
clearCache(): void {
if (this.cache) {
this.cache.clear();
}
}
/**
* Invalidate cache entries matching a pattern
*/
private invalidateCache(pattern: string): void {
if (!this.cache) return;
// Simple pattern matching - remove entries that start with the pattern
const keys = this.cache.keys();
for (const key of keys) {
if (key.startsWith(pattern)) {
this.cache.delete(key);
}
}
}
/**
* Get cache statistics
*/
getCacheStats(): Record<string, any> {
if (!this.cache) {
return { enabled: false };
}
return {
enabled: true,
size: this.cache.size,
maxSize: this.cache.maxSize,
hitRate: this.analytics.cacheStats.hits /
(this.analytics.cacheStats.hits + this.analytics.cacheStats.misses) || 0,
...this.analytics.cacheStats
};
}
/**
* Get client analytics
*/
getAnalytics(): AnalyticsData {
return {
...this.analytics,
cacheStats: this.getCacheStats()
};
}
/**
* Close the client and cleanup resources
*/
close(): void {
this.removeAllListeners();
if (this.cache) {
this.cache.clear();
}
}
}

View File

@@ -0,0 +1,70 @@
/**
* HCFS JavaScript/TypeScript SDK
*
* A comprehensive SDK for interacting with the HCFS API from JavaScript and TypeScript applications.
* Supports both Node.js and browser environments with full TypeScript support.
*
* @example
* ```typescript
* import { HCFSClient, Context } from '@hcfs/sdk';
*
* const client = new HCFSClient({
* baseUrl: 'https://api.hcfs.dev/v1',
* apiKey: 'your-api-key'
* });
*
* const context = new Context({
* path: '/docs/readme',
* content: 'Hello, HCFS!',
* summary: 'Getting started guide'
* });
*
* const created = await client.createContext(context);
* console.log(`Created context: ${created.id}`);
* ```
*/
export { HCFSClient } from './client';
export { HCFSWebSocketClient } from './websocket';
export {
Context,
SearchResult,
ContextFilter,
PaginationOptions,
SearchOptions,
HCFSConfig,
BatchResult,
AnalyticsData
} from './types';
export {
HCFSError,
HCFSConnectionError,
HCFSAuthenticationError,
HCFSNotFoundError,
HCFSValidationError,
HCFSRateLimitError,
HCFSServerError
} from './errors';
export { Cache, LRUCache } from './cache';
export { RetryManager } from './retry';
export {
validatePath,
normalizePath,
textChunker,
extractKeywords,
contextSimilarity
} from './utils';
// Version info
export const VERSION = '2.0.0';
// Default configuration
export const DEFAULT_CONFIG = {
baseUrl: 'https://api.hcfs.dev/v1',
timeout: 30000,
retryAttempts: 3,
retryDelay: 1000,
cacheEnabled: true,
cacheSize: 1000,
cacheTTL: 3600000, // 1 hour
} as const;

View File

@@ -0,0 +1,449 @@
/**
* TypeScript type definitions for HCFS SDK
*/
/**
* Context status enumeration
*/
export enum ContextStatus {
ACTIVE = 'active',
ARCHIVED = 'archived',
DELETED = 'deleted',
DRAFT = 'draft'
}
/**
* Search type enumeration
*/
export enum SearchType {
SEMANTIC = 'semantic',
KEYWORD = 'keyword',
HYBRID = 'hybrid',
FUZZY = 'fuzzy'
}
/**
* Cache strategy enumeration
*/
export enum CacheStrategy {
LRU = 'lru',
LFU = 'lfu',
TTL = 'ttl',
FIFO = 'fifo'
}
/**
* Represents a context in the HCFS system
*/
export interface Context {
/** Unique context identifier */
id?: number;
/** Hierarchical path of the context */
path: string;
/** Content of the context */
content: string;
/** Brief summary of the context */
summary?: string;
/** Author of the context */
author?: string;
/** Tags associated with the context */
tags?: string[];
/** Additional metadata */
metadata?: Record<string, any>;
/** Context status */
status?: ContextStatus;
/** Creation timestamp */
createdAt?: Date;
/** Last update timestamp */
updatedAt?: Date;
/** Context version number */
version?: number;
/** Similarity score (for search results) */
similarityScore?: number;
}
/**
* Context creation data
*/
export interface ContextCreate {
path: string;
content: string;
summary?: string;
author?: string;
tags?: string[];
metadata?: Record<string, any>;
}
/**
* Context update data
*/
export interface ContextUpdate {
content?: string;
summary?: string;
tags?: string[];
metadata?: Record<string, any>;
status?: ContextStatus;
}
/**
* Search result containing context and relevance information
*/
export interface SearchResult {
/** The context that matched the search */
context: Context;
/** Relevance score (0.0 to 1.0) */
score: number;
/** Explanation of why this result was returned */
explanation?: string;
/** Highlighted text snippets */
highlights?: string[];
}
/**
* Context filtering options
*/
export interface ContextFilter {
/** Filter by path prefix */
pathPrefix?: string;
/** Filter by author */
author?: string;
/** Filter by status */
status?: ContextStatus;
/** Filter by tags */
tags?: string[];
/** Filter by creation date (after) */
createdAfter?: Date;
/** Filter by creation date (before) */
createdBefore?: Date;
/** Filter by content substring */
contentContains?: string;
/** Minimum content length */
minContentLength?: number;
/** Maximum content length */
maxContentLength?: number;
}
/**
* Pagination options
*/
export interface PaginationOptions {
/** Page number (starts from 1) */
page?: number;
/** Number of items per page */
pageSize?: number;
/** Sort field */
sortBy?: string;
/** Sort order */
sortOrder?: 'asc' | 'desc';
}
/**
* Pagination metadata
*/
export interface PaginationMeta {
page: number;
pageSize: number;
totalItems: number;
totalPages: number;
hasNext: boolean;
hasPrevious: boolean;
}
/**
* Search configuration options
*/
export interface SearchOptions {
/** Type of search to perform */
searchType?: SearchType;
/** Maximum number of results */
topK?: number;
/** Minimum similarity score */
similarityThreshold?: number;
/** Search within path prefix */
pathPrefix?: string;
/** Weight for semantic search in hybrid mode */
semanticWeight?: number;
/** Include full content in results */
includeContent?: boolean;
/** Include text highlights */
includeHighlights?: boolean;
/** Maximum highlight snippets */
maxHighlights?: number;
}
/**
* Cache configuration
*/
export interface CacheConfig {
/** Enable caching */
enabled?: boolean;
/** Cache eviction strategy */
strategy?: CacheStrategy;
/** Maximum cache entries */
maxSize?: number;
/** Time-to-live in milliseconds */
ttl?: number;
/** Memory limit in MB */
memoryLimit?: number;
}
/**
* Retry configuration
*/
export interface RetryConfig {
/** Enable retry logic */
enabled?: boolean;
/** Maximum retry attempts */
maxAttempts?: number;
/** Base delay in milliseconds */
baseDelay?: number;
/** Maximum delay in milliseconds */
maxDelay?: number;
/** Backoff multiplier */
backoffMultiplier?: number;
/** Add random jitter to delays */
jitter?: boolean;
/** HTTP status codes to retry on */
retryOnStatus?: number[];
/** Retry on timeout errors */
retryOnTimeout?: boolean;
}
/**
* WebSocket configuration
*/
export interface WebSocketConfig {
/** Automatically reconnect on disconnect */
autoReconnect?: boolean;
/** Reconnect interval in milliseconds */
reconnectInterval?: number;
/** Maximum reconnection attempts */
maxReconnectAttempts?: number;
/** Ping interval in milliseconds */
pingInterval?: number;
/** Ping timeout in milliseconds */
pingTimeout?: number;
/** Maximum queued messages */
messageQueueSize?: number;
}
/**
* Main HCFS client configuration
*/
export interface HCFSConfig {
/** HCFS API base URL */
baseUrl: string;
/** API key for authentication */
apiKey?: string;
/** JWT token for authentication */
jwtToken?: string;
/** Request timeout in milliseconds */
timeout?: number;
/** User agent string */
userAgent?: string;
// Advanced configurations
cache?: CacheConfig;
retry?: RetryConfig;
websocket?: WebSocketConfig;
// HTTP client options
maxConcurrentRequests?: number;
keepAlive?: boolean;
}
/**
* Batch operation result
*/
export interface BatchResult {
/** Number of successful operations */
successCount: number;
/** Number of failed operations */
errorCount: number;
/** Total number of items processed */
totalItems: number;
/** Successfully created item IDs */
successfulItems: any[];
/** Failed items with error details */
failedItems: Array<{
index: number;
item: any;
error: string;
}>;
/** Execution time in milliseconds */
executionTime: number;
/** Success rate (0.0 to 1.0) */
successRate: number;
}
/**
* Stream event from WebSocket
*/
export interface StreamEvent {
/** Event type */
eventType: string;
/** Event data */
data: any;
/** Event timestamp */
timestamp: Date;
/** Related context ID */
contextId?: number;
/** Related context path */
path?: string;
}
/**
* Analytics and usage data
*/
export interface AnalyticsData {
/** Operation counts */
operationCount: Record<string, number>;
/** Cache statistics */
cacheStats: Record<string, any>;
/** Error statistics */
errorStats: Record<string, number>;
/** Performance metrics */
performanceStats: Record<string, number>;
/** Session start time */
sessionStart: Date;
}
/**
* API response wrapper
*/
export interface APIResponse<T> {
success: boolean;
data: T;
timestamp: string;
apiVersion: string;
requestId?: string;
}
/**
* API error response
*/
export interface APIErrorResponse {
success: false;
error: string;
errorDetails?: Array<{
field?: string;
message: string;
code?: string;
}>;
timestamp: string;
requestId?: string;
apiVersion: string;
}
/**
* List response with pagination
*/
export interface ListResponse<T> extends APIResponse<T[]> {
pagination: PaginationMeta;
}
/**
* Search response
*/
export interface SearchResponse {
success: boolean;
data: SearchResult[];
query: string;
searchType: SearchType;
totalResults: number;
searchTimeMs: number;
filtersApplied?: Record<string, any>;
timestamp: string;
apiVersion: string;
}
/**
* Health status
*/
export enum HealthStatus {
HEALTHY = 'healthy',
DEGRADED = 'degraded',
UNHEALTHY = 'unhealthy'
}
/**
* Component health information
*/
export interface ComponentHealth {
name: string;
status: HealthStatus;
responseTimeMs?: number;
errorMessage?: string;
}
/**
* Health check response
*/
export interface HealthResponse {
status: HealthStatus;
version: string;
uptimeSeconds: number;
components: ComponentHealth[];
}
/**
* Statistics response
*/
export interface StatsResponse {
contextStats: {
totalContexts: number;
contextsByStatus: Record<string, number>;
contextsByAuthor: Record<string, number>;
averageContentLength: number;
mostActivePaths: string[];
recentActivity: any[];
};
searchStats: {
totalSearches: number;
searchesByType: Record<string, number>;
averageResponseTimeMs: number;
popularQueries: string[];
searchSuccessRate: number;
};
systemStats: {
uptimeSeconds: number;
memoryUsageMb: number;
activeConnections: number;
cacheHitRate: number;
embeddingModelInfo: string;
databaseSizeMb: number;
};
}
/**
* Event listener function type
*/
export type EventListener<T = any> = (event: T) => void | Promise<void>;
/**
* HTTP method types
*/
export type HttpMethod = 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH';
/**
* Request options
*/
export interface RequestOptions {
method: HttpMethod;
url: string;
data?: any;
params?: Record<string, any>;
headers?: Record<string, string>;
timeout?: number;
}
/**
* Cache entry
*/
export interface CacheEntry<T = any> {
key: string;
value: T;
timestamp: number;
accessCount: number;
ttl?: number;
}