UNPKG

@chittyos/chittycontextual-client

Version:

TypeScript client for ChittyContextul cross-source temporal intelligence platform

350 lines (348 loc) 11.2 kB
// src/errors.ts var ChittyContextualError = class _ChittyContextualError extends Error { constructor(message, statusCode, response) { super(message); this.statusCode = statusCode; this.response = response; this.name = "ChittyContextualError"; Object.setPrototypeOf(this, _ChittyContextualError.prototype); } }; var NetworkError = class _NetworkError extends ChittyContextualError { constructor(message, cause) { super(`Network error: ${message}`, 0); this.name = "NetworkError"; this.cause = cause; Object.setPrototypeOf(this, _NetworkError.prototype); } }; var AuthenticationError = class _AuthenticationError extends ChittyContextualError { constructor(message = "Authentication failed") { super(message, 401); this.name = "AuthenticationError"; Object.setPrototypeOf(this, _AuthenticationError.prototype); } }; var ValidationError = class _ValidationError extends ChittyContextualError { constructor(message, errors) { super(message, 400); this.errors = errors; this.name = "ValidationError"; Object.setPrototypeOf(this, _ValidationError.prototype); } }; var NotFoundError = class _NotFoundError extends ChittyContextualError { constructor(resource) { super(`Resource not found: ${resource}`, 404); this.name = "NotFoundError"; Object.setPrototypeOf(this, _NotFoundError.prototype); } }; var RateLimitError = class _RateLimitError extends ChittyContextualError { constructor(retryAfter, message = "Rate limit exceeded") { super(message, 429); this.retryAfter = retryAfter; this.name = "RateLimitError"; Object.setPrototypeOf(this, _RateLimitError.prototype); } }; var ServerError = class _ServerError extends ChittyContextualError { constructor(message = "Internal server error") { super(message, 500); this.name = "ServerError"; Object.setPrototypeOf(this, _ServerError.prototype); } }; var TimeoutError = class _TimeoutError extends ChittyContextualError { constructor(timeoutMs) { super(`Request timeout after ${timeoutMs}ms`, 0); this.name = "TimeoutError"; Object.setPrototypeOf(this, _TimeoutError.prototype); } }; function handleResponseError(response, body) { const message = body?.error || body?.message || response.statusText || "Unknown error"; switch (response.status) { case 401: case 403: throw new AuthenticationError(message); case 404: throw new NotFoundError(message); case 400: throw new ValidationError(message, body?.errors); case 429: const retryAfter = response.headers.get("Retry-After"); throw new RateLimitError( retryAfter ? parseInt(retryAfter, 10) : void 0, message ); case 500: case 502: case 503: case 504: throw new ServerError(message); default: throw new ChittyContextualError(message, response.status, body); } } // src/client.ts var ChittyContextualClient = class { constructor(config = {}) { // Messages API this.messages = { list: async (options) => { const params = new URLSearchParams(); if (options?.limit) params.set("limit", options.limit.toString()); const query = params.toString() ? `?${params.toString()}` : ""; return this.request(`/api/messages${query}`); }, search: async (params) => { const queryParams = new URLSearchParams({ q: params.query }); if (params.timeRange) { queryParams.set("start", this.formatDate(params.timeRange.start)); queryParams.set("end", this.formatDate(params.timeRange.end)); } return this.request( `/api/messages/search?${queryParams.toString()}` ); }, timeline: async (params) => { const queryParams = new URLSearchParams({ start: this.formatDate(params.start), end: this.formatDate(params.end) }); return this.request( `/api/messages/timeline?${queryParams.toString()}` ); } }; // Documents API this.documents = { upload: async (files, onProgress) => { const formData = new FormData(); files.forEach((file) => formData.append("files", file)); return new Promise((resolve, reject) => { const xhr = new XMLHttpRequest(); if (onProgress) { xhr.upload.addEventListener("progress", (e) => { if (e.lengthComputable) { const percentage = e.loaded / e.total * 100; onProgress(percentage, e.loaded, e.total); } }); } xhr.addEventListener("load", () => { if (xhr.status >= 200 && xhr.status < 300) { resolve(JSON.parse(xhr.responseText)); } else { try { const body = JSON.parse(xhr.responseText); handleResponseError( new Response(xhr.responseText, { status: xhr.status }), body ); } catch { reject( new NetworkError(`Upload failed with status ${xhr.status}`) ); } } }); xhr.addEventListener("error", () => { reject(new NetworkError("Upload failed")); }); xhr.addEventListener("timeout", () => { reject(new TimeoutError(this.timeout)); }); xhr.open("POST", `${this.baseUrl}/api/documents/upload`); if (this.apiKey) { xhr.setRequestHeader("Authorization", `Bearer ${this.apiKey}`); } xhr.timeout = this.timeout; xhr.send(formData); }); }, list: async () => { return this.request("/api/documents"); } }; // Topics API this.topics = { list: async () => { return this.request("/api/topics"); }, analysis: async (timeRange) => { const params = new URLSearchParams(); if (timeRange) { params.set("start", this.formatDate(timeRange.start)); params.set("end", this.formatDate(timeRange.end)); } const query = params.toString() ? `?${params.toString()}` : ""; return this.request(`/api/topics/analysis${query}`); }, evolution: async (topicId, timeRange) => { const params = new URLSearchParams({ start: this.formatDate(timeRange.start), end: this.formatDate(timeRange.end) }); return this.request( `/api/topics/${topicId}/evolution?${params.toString()}` ); } }; // Entities API this.entities = { list: async () => { return this.request("/api/entities"); }, extractions: async () => { return this.request("/api/entities/extractions"); } }; // Cross References API this.crossReferences = { list: async () => { return this.request("/api/cross-references"); }, analyze: async (params) => { return this.request( "/api/cross-references/analyze", { method: "POST", body: JSON.stringify({ start: this.formatDate(params.start), end: this.formatDate(params.end) }) } ); } }; // Analytics API this.analytics = { correlations: async () => { return this.request("/api/analytics/correlations"); }, stats: async () => { return this.request("/api/analytics/stats"); } }; // Analysis API this.analyze = { bulk: async (params) => { return this.request("/api/analyze/bulk", { method: "POST", body: JSON.stringify({ start: this.formatDate(params.start), end: this.formatDate(params.end) }) }); }, comprehensive: async (params) => { return this.request( "/api/analyze/comprehensive", { method: "POST", body: JSON.stringify({ start: this.formatDate(params.start), end: this.formatDate(params.end), focusTopics: params.focusTopics, focusParties: params.focusParties }) } ); } }; // Intelligent Search API this.search = { intelligent: async (params) => { const queryParams = new URLSearchParams({ q: params.q }); if (params.party) queryParams.set("party", params.party); if (params.source) queryParams.set("source", params.source); if (params.start) queryParams.set("start", this.formatDate(params.start)); if (params.end) queryParams.set("end", this.formatDate(params.end)); return this.request( `/api/search/intelligent?${queryParams.toString()}` ); } }; // Party Learning API this.parties = { learn: async (params) => { return this.request("/api/parties/learn", { method: "POST", body: JSON.stringify(params) }); } }; this.baseUrl = config.baseUrl || "http://localhost:5000"; this.apiKey = config.apiKey; this.timeout = config.timeout || 3e4; this.retryAttempts = config.retryAttempts || 3; this.retryDelay = config.retryDelay || 1e3; } async request(endpoint, options = {}, attempt = 1) { const url = `${this.baseUrl}${endpoint}`; const headers = { ...options.headers }; if (this.apiKey) { headers["Authorization"] = `Bearer ${this.apiKey}`; } if (options.body && typeof options.body === "string") { headers["Content-Type"] = "application/json"; } const controller = new AbortController(); const timeoutId = setTimeout(() => controller.abort(), this.timeout); try { const response = await fetch(url, { ...options, headers, signal: controller.signal, credentials: "include" }); clearTimeout(timeoutId); if (!response.ok) { let body; try { body = await response.json(); } catch { body = await response.text(); } handleResponseError(response, body); } return await response.json(); } catch (error) { clearTimeout(timeoutId); if (error.name === "AbortError") { throw new TimeoutError(this.timeout); } if (attempt < this.retryAttempts && (error instanceof NetworkError || error.name === "TypeError")) { await new Promise( (resolve) => setTimeout(resolve, this.retryDelay * attempt) ); return this.request(endpoint, options, attempt + 1); } if (error.name === "TypeError") { throw new NetworkError("Failed to fetch", error); } throw error; } } formatDate(date) { if (typeof date === "string") return date; return date.toISOString(); } }; export { AuthenticationError, ChittyContextualClient, ChittyContextualError, NetworkError, NotFoundError, RateLimitError, ServerError, TimeoutError, ValidationError, ChittyContextualClient as default, handleResponseError };