@debros/network-ts-sdk 0.3.4 → 0.4.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/errors.ts","../src/core/http.ts","../src/auth/types.ts","../src/auth/client.ts","../src/db/qb.ts","../src/db/repository.ts","../src/db/client.ts","../src/core/ws.ts","../src/pubsub/client.ts","../src/network/client.ts","../src/cache/client.ts","../src/storage/client.ts","../src/index.ts"],"sourcesContent":["export class SDKError extends Error {\n public readonly httpStatus: number;\n public readonly code: string;\n public readonly details: Record<string, any>;\n\n constructor(\n message: string,\n httpStatus: number = 500,\n code: string = \"SDK_ERROR\",\n details: Record<string, any> = {}\n ) {\n super(message);\n this.name = \"SDKError\";\n this.httpStatus = httpStatus;\n this.code = code;\n this.details = details;\n }\n\n static fromResponse(\n status: number,\n body: any,\n message?: string\n ): SDKError {\n const errorMsg = message || body?.error || `HTTP ${status}`;\n const code = body?.code || `HTTP_${status}`;\n return new SDKError(errorMsg, status, code, body);\n }\n\n toJSON() {\n return {\n name: this.name,\n message: this.message,\n httpStatus: this.httpStatus,\n code: this.code,\n details: this.details,\n };\n }\n}\n","import { SDKError } from \"../errors\";\n\nexport interface HttpClientConfig {\n baseURL: string;\n timeout?: number;\n maxRetries?: number;\n retryDelayMs?: number;\n fetch?: typeof fetch;\n}\n\n/**\n * Create a fetch function with proper TLS configuration for staging certificates\n * In Node.js, we need to configure TLS to accept Let's Encrypt staging certificates\n */\nfunction createFetchWithTLSConfig(): typeof fetch {\n // Check if we're in a Node.js environment\n if (typeof process !== \"undefined\" && process.versions?.node) {\n // For testing/staging/development: allow staging certificates\n // Let's Encrypt staging certificates are self-signed and not trusted by default\n const isDevelopmentOrStaging =\n process.env.NODE_ENV !== \"production\" ||\n process.env.DEBROS_ALLOW_STAGING_CERTS === \"true\" ||\n process.env.DEBROS_USE_HTTPS === \"true\";\n\n if (isDevelopmentOrStaging) {\n // Allow self-signed/staging certificates\n // WARNING: Only use this in development/testing environments\n process.env.NODE_TLS_REJECT_UNAUTHORIZED = \"0\";\n }\n }\n return globalThis.fetch;\n}\n\nexport class HttpClient {\n private baseURL: string;\n private timeout: number;\n private maxRetries: number;\n private retryDelayMs: number;\n private fetch: typeof fetch;\n private apiKey?: string;\n private jwt?: string;\n\n constructor(config: HttpClientConfig) {\n this.baseURL = config.baseURL.replace(/\\/$/, \"\");\n this.timeout = config.timeout ?? 60000; // Increased from 30s to 60s for pub/sub operations\n this.maxRetries = config.maxRetries ?? 3;\n this.retryDelayMs = config.retryDelayMs ?? 1000;\n // Use provided fetch or create one with proper TLS configuration for staging certificates\n this.fetch = config.fetch ?? createFetchWithTLSConfig();\n }\n\n setApiKey(apiKey?: string) {\n this.apiKey = apiKey;\n // Don't clear JWT - allow both to coexist\n }\n\n setJwt(jwt?: string) {\n this.jwt = jwt;\n // Don't clear API key - allow both to coexist\n if (typeof console !== \"undefined\") {\n console.log(\n \"[HttpClient] JWT set:\",\n !!jwt,\n \"API key still present:\",\n !!this.apiKey\n );\n }\n }\n\n private getAuthHeaders(path: string): Record<string, string> {\n const headers: Record<string, string> = {};\n\n // For database, pubsub, proxy, and cache operations, ONLY use API key to avoid JWT user context\n // interfering with namespace-level authorization\n const isDbOperation = path.includes(\"/v1/rqlite/\");\n const isPubSubOperation = path.includes(\"/v1/pubsub/\");\n const isProxyOperation = path.includes(\"/v1/proxy/\");\n const isCacheOperation = path.includes(\"/v1/cache/\");\n\n // For auth operations, prefer API key over JWT to ensure proper authentication\n const isAuthOperation = path.includes(\"/v1/auth/\");\n\n if (\n isDbOperation ||\n isPubSubOperation ||\n isProxyOperation ||\n isCacheOperation\n ) {\n // For database/pubsub/proxy/cache operations: use only API key (preferred for namespace operations)\n if (this.apiKey) {\n headers[\"X-API-Key\"] = this.apiKey;\n } else if (this.jwt) {\n // Fallback to JWT if no API key\n headers[\"Authorization\"] = `Bearer ${this.jwt}`;\n }\n } else if (isAuthOperation) {\n // For auth operations: prefer API key over JWT (auth endpoints should use explicit API key)\n if (this.apiKey) {\n headers[\"X-API-Key\"] = this.apiKey;\n }\n if (this.jwt) {\n headers[\"Authorization\"] = `Bearer ${this.jwt}`;\n }\n } else {\n // For other operations: send both JWT and API key\n if (this.jwt) {\n headers[\"Authorization\"] = `Bearer ${this.jwt}`;\n }\n if (this.apiKey) {\n headers[\"X-API-Key\"] = this.apiKey;\n }\n }\n return headers;\n }\n\n private getAuthToken(): string | undefined {\n return this.jwt || this.apiKey;\n }\n\n getApiKey(): string | undefined {\n return this.apiKey;\n }\n\n async request<T = any>(\n method: \"GET\" | \"POST\" | \"PUT\" | \"DELETE\",\n path: string,\n options: {\n body?: any;\n headers?: Record<string, string>;\n query?: Record<string, string | number | boolean>;\n timeout?: number; // Per-request timeout override\n } = {}\n ): Promise<T> {\n const startTime = performance.now(); // Track request start time\n const url = new URL(this.baseURL + path);\n if (options.query) {\n Object.entries(options.query).forEach(([key, value]) => {\n url.searchParams.append(key, String(value));\n });\n }\n\n const headers: Record<string, string> = {\n \"Content-Type\": \"application/json\",\n ...this.getAuthHeaders(path),\n ...options.headers,\n };\n\n const controller = new AbortController();\n const requestTimeout = options.timeout ?? this.timeout; // Use override or default\n const timeoutId = setTimeout(() => controller.abort(), requestTimeout);\n\n const fetchOptions: RequestInit = {\n method,\n headers,\n signal: controller.signal,\n };\n\n if (options.body !== undefined) {\n fetchOptions.body = JSON.stringify(options.body);\n }\n\n // Extract and log SQL query details for rqlite operations\n const isRqliteOperation = path.includes(\"/v1/rqlite/\");\n let queryDetails: string | null = null;\n if (isRqliteOperation && options.body) {\n try {\n const body =\n typeof options.body === \"string\"\n ? JSON.parse(options.body)\n : options.body;\n\n if (body.sql) {\n // Direct SQL query (query/exec endpoints)\n queryDetails = `SQL: ${body.sql}`;\n if (body.args && body.args.length > 0) {\n queryDetails += ` | Args: [${body.args\n .map((a: any) => (typeof a === \"string\" ? `\"${a}\"` : a))\n .join(\", \")}]`;\n }\n } else if (body.table) {\n // Table-based query (find/find-one/select endpoints)\n queryDetails = `Table: ${body.table}`;\n if (body.criteria && Object.keys(body.criteria).length > 0) {\n queryDetails += ` | Criteria: ${JSON.stringify(body.criteria)}`;\n }\n if (body.options) {\n queryDetails += ` | Options: ${JSON.stringify(body.options)}`;\n }\n if (body.select) {\n queryDetails += ` | Select: ${JSON.stringify(body.select)}`;\n }\n if (body.where) {\n queryDetails += ` | Where: ${JSON.stringify(body.where)}`;\n }\n if (body.limit) {\n queryDetails += ` | Limit: ${body.limit}`;\n }\n if (body.offset) {\n queryDetails += ` | Offset: ${body.offset}`;\n }\n }\n } catch (e) {\n // Failed to parse body, ignore\n }\n }\n\n try {\n const result = await this.requestWithRetry(\n url.toString(),\n fetchOptions,\n 0,\n startTime\n );\n const duration = performance.now() - startTime;\n if (typeof console !== \"undefined\") {\n const logMessage = `[HttpClient] ${method} ${path} completed in ${duration.toFixed(\n 2\n )}ms`;\n if (queryDetails) {\n console.log(logMessage);\n console.log(`[HttpClient] ${queryDetails}`);\n } else {\n console.log(logMessage);\n }\n }\n return result;\n } catch (error) {\n const duration = performance.now() - startTime;\n if (typeof console !== \"undefined\") {\n // For 404 errors on find-one calls, log at warn level (not error) since \"not found\" is expected\n // Application layer handles these cases in try-catch blocks\n const is404FindOne =\n path === \"/v1/rqlite/find-one\" &&\n error instanceof SDKError &&\n error.httpStatus === 404;\n\n if (is404FindOne) {\n // Log as warning for visibility, but not as error since it's expected behavior\n console.warn(\n `[HttpClient] ${method} ${path} returned 404 after ${duration.toFixed(\n 2\n )}ms (expected for optional lookups)`\n );\n } else {\n const errorMessage = `[HttpClient] ${method} ${path} failed after ${duration.toFixed(\n 2\n )}ms:`;\n console.error(errorMessage, error);\n if (queryDetails) {\n console.error(`[HttpClient] ${queryDetails}`);\n }\n }\n }\n throw error;\n } finally {\n clearTimeout(timeoutId);\n }\n }\n\n private async requestWithRetry(\n url: string,\n options: RequestInit,\n attempt: number = 0,\n startTime?: number // Track start time for timing across retries\n ): Promise<any> {\n try {\n const response = await this.fetch(url, options);\n\n if (!response.ok) {\n let body: any;\n try {\n body = await response.json();\n } catch {\n body = { error: response.statusText };\n }\n throw SDKError.fromResponse(response.status, body);\n }\n\n const contentType = response.headers.get(\"content-type\");\n if (contentType?.includes(\"application/json\")) {\n return response.json();\n }\n return response.text();\n } catch (error) {\n if (\n error instanceof SDKError &&\n attempt < this.maxRetries &&\n [408, 429, 500, 502, 503, 504].includes(error.httpStatus)\n ) {\n await new Promise((resolve) =>\n setTimeout(resolve, this.retryDelayMs * (attempt + 1))\n );\n return this.requestWithRetry(url, options, attempt + 1, startTime);\n }\n throw error;\n }\n }\n\n async get<T = any>(\n path: string,\n options?: Omit<Parameters<typeof this.request>[2], \"body\">\n ): Promise<T> {\n return this.request<T>(\"GET\", path, options);\n }\n\n async post<T = any>(\n path: string,\n body?: any,\n options?: Omit<Parameters<typeof this.request>[2], \"body\">\n ): Promise<T> {\n return this.request<T>(\"POST\", path, { ...options, body });\n }\n\n async put<T = any>(\n path: string,\n body?: any,\n options?: Omit<Parameters<typeof this.request>[2], \"body\">\n ): Promise<T> {\n return this.request<T>(\"PUT\", path, { ...options, body });\n }\n\n async delete<T = any>(\n path: string,\n options?: Omit<Parameters<typeof this.request>[2], \"body\">\n ): Promise<T> {\n return this.request<T>(\"DELETE\", path, options);\n }\n\n /**\n * Upload a file using multipart/form-data\n * This is a special method for file uploads that bypasses JSON serialization\n */\n async uploadFile<T = any>(\n path: string,\n formData: FormData,\n options?: {\n timeout?: number;\n }\n ): Promise<T> {\n const startTime = performance.now(); // Track upload start time\n const url = new URL(this.baseURL + path);\n const headers: Record<string, string> = {\n ...this.getAuthHeaders(path),\n // Don't set Content-Type - browser will set it with boundary\n };\n\n const controller = new AbortController();\n const requestTimeout = options?.timeout ?? this.timeout * 5; // 5x timeout for uploads\n const timeoutId = setTimeout(() => controller.abort(), requestTimeout);\n\n const fetchOptions: RequestInit = {\n method: \"POST\",\n headers,\n body: formData,\n signal: controller.signal,\n };\n\n try {\n const result = await this.requestWithRetry(\n url.toString(),\n fetchOptions,\n 0,\n startTime\n );\n const duration = performance.now() - startTime;\n if (typeof console !== \"undefined\") {\n console.log(\n `[HttpClient] POST ${path} (upload) completed in ${duration.toFixed(\n 2\n )}ms`\n );\n }\n return result;\n } catch (error) {\n const duration = performance.now() - startTime;\n if (typeof console !== \"undefined\") {\n console.error(\n `[HttpClient] POST ${path} (upload) failed after ${duration.toFixed(\n 2\n )}ms:`,\n error\n );\n }\n throw error;\n } finally {\n clearTimeout(timeoutId);\n }\n }\n\n /**\n * Get a binary response (returns Response object for streaming)\n */\n async getBinary(path: string): Promise<Response> {\n const url = new URL(this.baseURL + path);\n const headers: Record<string, string> = {\n ...this.getAuthHeaders(path),\n };\n\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), this.timeout * 5); // 5x timeout for downloads\n\n const fetchOptions: RequestInit = {\n method: \"GET\",\n headers,\n signal: controller.signal,\n };\n\n try {\n const response = await this.fetch(url.toString(), fetchOptions);\n if (!response.ok) {\n clearTimeout(timeoutId);\n const error = await response.json().catch(() => ({\n error: response.statusText,\n }));\n throw SDKError.fromResponse(response.status, error);\n }\n return response;\n } catch (error) {\n clearTimeout(timeoutId);\n if (error instanceof SDKError) {\n throw error;\n }\n throw error;\n }\n }\n\n getToken(): string | undefined {\n return this.getAuthToken();\n }\n}\n","export interface AuthConfig {\n apiKey?: string;\n jwt?: string;\n}\n\nexport interface WhoAmI {\n address?: string;\n namespace?: string;\n authenticated: boolean;\n}\n\nexport interface StorageAdapter {\n get(key: string): Promise<string | null>;\n set(key: string, value: string): Promise<void>;\n clear(): Promise<void>;\n}\n\nexport class MemoryStorage implements StorageAdapter {\n private storage: Map<string, string> = new Map();\n\n async get(key: string): Promise<string | null> {\n return this.storage.get(key) ?? null;\n }\n\n async set(key: string, value: string): Promise<void> {\n this.storage.set(key, value);\n }\n\n async clear(): Promise<void> {\n this.storage.clear();\n }\n}\n\nexport class LocalStorageAdapter implements StorageAdapter {\n private prefix = \"@network/sdk:\";\n\n async get(key: string): Promise<string | null> {\n if (typeof globalThis !== \"undefined\" && globalThis.localStorage) {\n return globalThis.localStorage.getItem(this.prefix + key);\n }\n return null;\n }\n\n async set(key: string, value: string): Promise<void> {\n if (typeof globalThis !== \"undefined\" && globalThis.localStorage) {\n globalThis.localStorage.setItem(this.prefix + key, value);\n }\n }\n\n async clear(): Promise<void> {\n if (typeof globalThis !== \"undefined\" && globalThis.localStorage) {\n const keysToDelete: string[] = [];\n for (let i = 0; i < globalThis.localStorage.length; i++) {\n const key = globalThis.localStorage.key(i);\n if (key?.startsWith(this.prefix)) {\n keysToDelete.push(key);\n }\n }\n keysToDelete.forEach((key) => globalThis.localStorage.removeItem(key));\n }\n }\n}\n","import { HttpClient } from \"../core/http\";\nimport { AuthConfig, WhoAmI, StorageAdapter, MemoryStorage } from \"./types\";\n\nexport class AuthClient {\n private httpClient: HttpClient;\n private storage: StorageAdapter;\n private currentApiKey?: string;\n private currentJwt?: string;\n\n constructor(config: {\n httpClient: HttpClient;\n storage?: StorageAdapter;\n apiKey?: string;\n jwt?: string;\n }) {\n this.httpClient = config.httpClient;\n this.storage = config.storage ?? new MemoryStorage();\n this.currentApiKey = config.apiKey;\n this.currentJwt = config.jwt;\n\n if (this.currentApiKey) {\n this.httpClient.setApiKey(this.currentApiKey);\n }\n if (this.currentJwt) {\n this.httpClient.setJwt(this.currentJwt);\n }\n }\n\n setApiKey(apiKey: string) {\n this.currentApiKey = apiKey;\n // Don't clear JWT - it will be cleared explicitly on logout\n this.httpClient.setApiKey(apiKey);\n this.storage.set(\"apiKey\", apiKey);\n }\n\n setJwt(jwt: string) {\n this.currentJwt = jwt;\n // Don't clear API key - keep it as fallback for after logout\n this.httpClient.setJwt(jwt);\n this.storage.set(\"jwt\", jwt);\n }\n\n getToken(): string | undefined {\n return this.httpClient.getToken();\n }\n\n async whoami(): Promise<WhoAmI> {\n try {\n const response = await this.httpClient.get<WhoAmI>(\"/v1/auth/whoami\");\n return response;\n } catch {\n return { authenticated: false };\n }\n }\n\n async refresh(): Promise<string> {\n const response = await this.httpClient.post<{ token: string }>(\n \"/v1/auth/refresh\"\n );\n const token = response.token;\n this.setJwt(token);\n return token;\n }\n\n /**\n * Logout user and clear JWT, but preserve API key\n * Use this for user logout in apps where API key is app-level credential\n */\n async logoutUser(): Promise<void> {\n // Attempt server-side logout if using JWT\n if (this.currentJwt) {\n try {\n await this.httpClient.post(\"/v1/auth/logout\", { all: true });\n } catch (error) {\n // Log warning but don't fail - local cleanup is more important\n console.warn(\n \"Server-side logout failed, continuing with local cleanup:\",\n error\n );\n }\n }\n\n // Clear JWT only, preserve API key\n this.currentJwt = undefined;\n this.httpClient.setJwt(undefined);\n await this.storage.set(\"jwt\", \"\"); // Clear JWT from storage\n\n // Ensure API key is loaded and set as active auth method\n if (!this.currentApiKey) {\n // Try to load from storage\n const storedApiKey = await this.storage.get(\"apiKey\");\n if (storedApiKey) {\n this.currentApiKey = storedApiKey;\n }\n }\n\n // Restore API key as the active auth method\n if (this.currentApiKey) {\n this.httpClient.setApiKey(this.currentApiKey);\n console.log(\"[Auth] API key restored after user logout\");\n } else {\n console.warn(\"[Auth] No API key available after logout\");\n }\n }\n\n /**\n * Full logout - clears both JWT and API key\n * Use this to completely reset authentication state\n */\n async logout(): Promise<void> {\n // Only attempt server-side logout if using JWT\n // API keys don't support server-side logout with all=true\n if (this.currentJwt) {\n try {\n await this.httpClient.post(\"/v1/auth/logout\", { all: true });\n } catch (error) {\n // Log warning but don't fail - local cleanup is more important\n console.warn(\n \"Server-side logout failed, continuing with local cleanup:\",\n error\n );\n }\n }\n\n // Always clear local state\n this.currentApiKey = undefined;\n this.currentJwt = undefined;\n this.httpClient.setApiKey(undefined);\n this.httpClient.setJwt(undefined);\n await this.storage.clear();\n }\n\n async clear(): Promise<void> {\n this.currentApiKey = undefined;\n this.currentJwt = undefined;\n this.httpClient.setApiKey(undefined);\n this.httpClient.setJwt(undefined);\n await this.storage.clear();\n }\n\n /**\n * Request a challenge nonce for wallet authentication\n */\n async challenge(params: {\n wallet: string;\n purpose?: string;\n namespace?: string;\n }): Promise<{\n nonce: string;\n wallet: string;\n namespace: string;\n expires_at: string;\n }> {\n const response = await this.httpClient.post(\"/v1/auth/challenge\", {\n wallet: params.wallet,\n purpose: params.purpose || \"authentication\",\n namespace: params.namespace || \"default\",\n });\n return response;\n }\n\n /**\n * Verify wallet signature and get JWT token\n */\n async verify(params: {\n wallet: string;\n nonce: string;\n signature: string;\n namespace?: string;\n chain_type?: \"ETH\" | \"SOL\";\n }): Promise<{\n access_token: string;\n refresh_token?: string;\n subject: string;\n namespace: string;\n api_key?: string;\n expires_in?: number;\n token_type?: string;\n }> {\n const response = await this.httpClient.post(\"/v1/auth/verify\", {\n wallet: params.wallet,\n nonce: params.nonce,\n signature: params.signature,\n namespace: params.namespace || \"default\",\n chain_type: params.chain_type || \"ETH\",\n });\n\n // Persist JWT\n this.setJwt(response.access_token);\n\n // Persist API key if server provided it (created in verifyHandler)\n if ((response as any).api_key) {\n this.setApiKey((response as any).api_key);\n }\n\n // Persist refresh token if present (optional, for silent renewal)\n if ((response as any).refresh_token) {\n await this.storage.set(\"refreshToken\", (response as any).refresh_token);\n }\n\n return response as any;\n }\n\n /**\n * Get API key for wallet (creates namespace ownership)\n */\n async getApiKey(params: {\n wallet: string;\n nonce: string;\n signature: string;\n namespace?: string;\n chain_type?: \"ETH\" | \"SOL\";\n }): Promise<{\n api_key: string;\n namespace: string;\n wallet: string;\n }> {\n const response = await this.httpClient.post(\"/v1/auth/api-key\", {\n wallet: params.wallet,\n nonce: params.nonce,\n signature: params.signature,\n namespace: params.namespace || \"default\",\n chain_type: params.chain_type || \"ETH\",\n });\n\n // Automatically set the API key\n this.setApiKey(response.api_key);\n\n return response;\n }\n}\n","import { HttpClient } from \"../core/http\";\nimport { SelectOptions, QueryResponse } from \"./types\";\n\nexport class QueryBuilder {\n private httpClient: HttpClient;\n private table: string;\n private options: SelectOptions = {};\n\n constructor(httpClient: HttpClient, table: string) {\n this.httpClient = httpClient;\n this.table = table;\n }\n\n select(...columns: string[]): this {\n this.options.select = columns;\n return this;\n }\n\n innerJoin(table: string, on: string): this {\n if (!this.options.joins) this.options.joins = [];\n this.options.joins.push({ kind: \"INNER\", table, on });\n return this;\n }\n\n leftJoin(table: string, on: string): this {\n if (!this.options.joins) this.options.joins = [];\n this.options.joins.push({ kind: \"LEFT\", table, on });\n return this;\n }\n\n rightJoin(table: string, on: string): this {\n if (!this.options.joins) this.options.joins = [];\n this.options.joins.push({ kind: \"RIGHT\", table, on });\n return this;\n }\n\n where(expr: string, args?: any[]): this {\n if (!this.options.where) this.options.where = [];\n this.options.where.push({ conj: \"AND\", expr, args });\n return this;\n }\n\n andWhere(expr: string, args?: any[]): this {\n return this.where(expr, args);\n }\n\n orWhere(expr: string, args?: any[]): this {\n if (!this.options.where) this.options.where = [];\n this.options.where.push({ conj: \"OR\", expr, args });\n return this;\n }\n\n groupBy(...columns: string[]): this {\n this.options.group_by = columns;\n return this;\n }\n\n orderBy(...columns: string[]): this {\n this.options.order_by = columns;\n return this;\n }\n\n limit(n: number): this {\n this.options.limit = n;\n return this;\n }\n\n offset(n: number): this {\n this.options.offset = n;\n return this;\n }\n\n async getMany<T = any>(ctx?: any): Promise<T[]> {\n const response = await this.httpClient.post<QueryResponse>(\n \"/v1/rqlite/select\",\n {\n table: this.table,\n ...this.options,\n }\n );\n return response.items || [];\n }\n\n async getOne<T = any>(ctx?: any): Promise<T | null> {\n const response = await this.httpClient.post<QueryResponse>(\n \"/v1/rqlite/select\",\n {\n table: this.table,\n ...this.options,\n one: true,\n limit: 1,\n }\n );\n const items = response.items || [];\n return items.length > 0 ? items[0] : null;\n }\n\n async count(): Promise<number> {\n const response = await this.httpClient.post<QueryResponse>(\n \"/v1/rqlite/select\",\n {\n table: this.table,\n select: [\"COUNT(*) AS count\"],\n where: this.options.where,\n one: true,\n }\n );\n const items = response.items || [];\n return items.length > 0 ? items[0].count : 0;\n }\n}\n","import { HttpClient } from \"../core/http\";\nimport { QueryBuilder } from \"./qb\";\nimport { QueryResponse, FindOptions } from \"./types\";\nimport { SDKError } from \"../errors\";\n\nexport class Repository<T extends Record<string, any>> {\n private httpClient: HttpClient;\n private tableName: string;\n private primaryKey: string;\n\n constructor(httpClient: HttpClient, tableName: string, primaryKey = \"id\") {\n this.httpClient = httpClient;\n this.tableName = tableName;\n this.primaryKey = primaryKey;\n }\n\n createQueryBuilder(): QueryBuilder {\n return new QueryBuilder(this.httpClient, this.tableName);\n }\n\n async find(\n criteria: Record<string, any> = {},\n options: FindOptions = {}\n ): Promise<T[]> {\n const response = await this.httpClient.post<QueryResponse>(\n \"/v1/rqlite/find\",\n {\n table: this.tableName,\n criteria,\n options,\n }\n );\n return response.items || [];\n }\n\n async findOne(criteria: Record<string, any>): Promise<T | null> {\n try {\n const response = await this.httpClient.post<T | null>(\n \"/v1/rqlite/find-one\",\n {\n table: this.tableName,\n criteria,\n }\n );\n return response;\n } catch (error) {\n // Return null if not found instead of throwing\n if (error instanceof SDKError && error.httpStatus === 404) {\n return null;\n }\n throw error;\n }\n }\n\n async save(entity: T): Promise<T> {\n const pkValue = entity[this.primaryKey];\n\n if (!pkValue) {\n // INSERT\n const response = await this.httpClient.post<{\n rows_affected: number;\n last_insert_id: number;\n }>(\"/v1/rqlite/exec\", {\n sql: this.buildInsertSql(entity),\n args: this.buildInsertArgs(entity),\n });\n\n if (response.last_insert_id) {\n (entity as any)[this.primaryKey] = response.last_insert_id;\n }\n return entity;\n } else {\n // UPDATE\n await this.httpClient.post(\"/v1/rqlite/exec\", {\n sql: this.buildUpdateSql(entity),\n args: this.buildUpdateArgs(entity),\n });\n return entity;\n }\n }\n\n async remove(entity: T | Record<string, any>): Promise<void> {\n const pkValue = entity[this.primaryKey];\n if (!pkValue) {\n throw new SDKError(\n `Primary key \"${this.primaryKey}\" is required for remove`,\n 400,\n \"MISSING_PK\"\n );\n }\n\n await this.httpClient.post(\"/v1/rqlite/exec\", {\n sql: `DELETE FROM ${this.tableName} WHERE ${this.primaryKey} = ?`,\n args: [pkValue],\n });\n }\n\n private buildInsertSql(entity: T): string {\n const columns = Object.keys(entity).filter((k) => entity[k] !== undefined);\n const placeholders = columns.map(() => \"?\").join(\", \");\n return `INSERT INTO ${this.tableName} (${columns.join(\n \", \"\n )}) VALUES (${placeholders})`;\n }\n\n private buildInsertArgs(entity: T): any[] {\n return Object.entries(entity)\n .filter(([, v]) => v !== undefined)\n .map(([, v]) => v);\n }\n\n private buildUpdateSql(entity: T): string {\n const columns = Object.keys(entity)\n .filter((k) => entity[k] !== undefined && k !== this.primaryKey)\n .map((k) => `${k} = ?`);\n return `UPDATE ${this.tableName} SET ${columns.join(\", \")} WHERE ${\n this.primaryKey\n } = ?`;\n }\n\n private buildUpdateArgs(entity: T): any[] {\n const args = Object.entries(entity)\n .filter(([k, v]) => v !== undefined && k !== this.primaryKey)\n .map(([, v]) => v);\n args.push(entity[this.primaryKey]);\n return args;\n }\n}\n","import { HttpClient } from \"../core/http\";\nimport { QueryBuilder } from \"./qb\";\nimport { Repository } from \"./repository\";\nimport {\n QueryResponse,\n TransactionOp,\n TransactionRequest,\n Entity,\n FindOptions,\n} from \"./types\";\n\nexport class DBClient {\n private httpClient: HttpClient;\n\n constructor(httpClient: HttpClient) {\n this.httpClient = httpClient;\n }\n\n /**\n * Execute a write/DDL SQL statement.\n */\n async exec(\n sql: string,\n args: any[] = []\n ): Promise<{ rows_affected: number; last_insert_id?: number }> {\n return this.httpClient.post(\"/v1/rqlite/exec\", { sql, args });\n }\n\n /**\n * Execute a SELECT query.\n */\n async query<T = any>(sql: string, args: any[] = []): Promise<T[]> {\n const response = await this.httpClient.post<QueryResponse>(\n \"/v1/rqlite/query\",\n { sql, args }\n );\n return response.items || [];\n }\n\n /**\n * Find rows with map-based criteria.\n */\n async find<T = any>(\n table: string,\n criteria: Record<string, any> = {},\n options: FindOptions = {}\n ): Promise<T[]> {\n const response = await this.httpClient.post<QueryResponse>(\n \"/v1/rqlite/find\",\n {\n table,\n criteria,\n options,\n }\n );\n return response.items || [];\n }\n\n /**\n * Find a single row with map-based criteria.\n */\n async findOne<T = any>(\n table: string,\n criteria: Record<string, any>\n ): Promise<T | null> {\n return this.httpClient.post<T | null>(\"/v1/rqlite/find-one\", {\n table,\n criteria,\n });\n }\n\n /**\n * Create a fluent QueryBuilder for complex SELECT queries.\n */\n createQueryBuilder(table: string): QueryBuilder {\n return new QueryBuilder(this.httpClient, table);\n }\n\n /**\n * Create a Repository for entity-based operations.\n */\n repository<T extends Record<string, any>>(\n tableName: string,\n primaryKey = \"id\"\n ): Repository<T> {\n return new Repository(this.httpClient, tableName, primaryKey);\n }\n\n /**\n * Execute multiple operations atomically.\n */\n async transaction(\n ops: TransactionOp[],\n returnResults = true\n ): Promise<any[]> {\n const response = await this.httpClient.post<{ results?: any[] }>(\n \"/v1/rqlite/transaction\",\n {\n ops,\n return_results: returnResults,\n }\n );\n return response.results || [];\n }\n\n /**\n * Create a table from DDL SQL.\n */\n async createTable(schema: string): Promise<void> {\n await this.httpClient.post(\"/v1/rqlite/create-table\", { schema });\n }\n\n /**\n * Drop a table.\n */\n async dropTable(table: string): Promise<void> {\n await this.httpClient.post(\"/v1/rqlite/drop-table\", { table });\n }\n\n /**\n * Get current database schema.\n */\n async getSchema(): Promise<any> {\n return this.httpClient.get(\"/v1/rqlite/schema\");\n }\n}\n","import WebSocket from \"isomorphic-ws\";\nimport { SDKError } from \"../errors\";\n\nexport interface WSClientConfig {\n wsURL: string;\n timeout?: number;\n authToken?: string;\n WebSocket?: typeof WebSocket;\n}\n\nexport type WSMessageHandler = (data: string) => void;\nexport type WSErrorHandler = (error: Error) => void;\nexport type WSCloseHandler = () => void;\nexport type WSOpenHandler = () => void;\n\n/**\n * Simple WebSocket client with minimal abstractions\n * No complex reconnection, no heartbeats - keep it simple\n */\nexport class WSClient {\n private url: string;\n private timeout: number;\n private authToken?: string;\n private WebSocketClass: typeof WebSocket;\n\n private ws?: WebSocket;\n private messageHandlers: Set<WSMessageHandler> = new Set();\n private errorHandlers: Set<WSErrorHandler> = new Set();\n private closeHandlers: Set<WSCloseHandler> = new Set();\n private openHandlers: Set<WSOpenHandler> = new Set();\n private isClosed = false;\n\n constructor(config: WSClientConfig) {\n this.url = config.wsURL;\n this.timeout = config.timeout ?? 30000;\n this.authToken = config.authToken;\n this.WebSocketClass = config.WebSocket ?? WebSocket;\n }\n\n /**\n * Connect to WebSocket server\n */\n connect(): Promise<void> {\n return new Promise((resolve, reject) => {\n try {\n const wsUrl = this.buildWSUrl();\n this.ws = new this.WebSocketClass(wsUrl);\n this.isClosed = false;\n\n const timeout = setTimeout(() => {\n this.ws?.close();\n reject(\n new SDKError(\"WebSocket connection timeout\", 408, \"WS_TIMEOUT\")\n );\n }, this.timeout);\n\n this.ws.addEventListener(\"open\", () => {\n clearTimeout(timeout);\n console.log(\"[WSClient] Connected to\", this.url);\n this.openHandlers.forEach((handler) => handler());\n resolve();\n });\n\n this.ws.addEventListener(\"message\", (event: Event) => {\n const msgEvent = event as MessageEvent;\n this.messageHandlers.forEach((handler) => handler(msgEvent.data));\n });\n\n this.ws.addEventListener(\"error\", (event: Event) => {\n console.error(\"[WSClient] WebSocket error:\", event);\n clearTimeout(timeout);\n const error = new SDKError(\"WebSocket error\", 500, \"WS_ERROR\", event);\n this.errorHandlers.forEach((handler) => handler(error));\n });\n\n this.ws.addEventListener(\"close\", () => {\n clearTimeout(timeout);\n console.log(\"[WSClient] Connection closed\");\n this.closeHandlers.forEach((handler) => handler());\n });\n } catch (error) {\n reject(error);\n }\n });\n }\n\n /**\n * Build WebSocket URL with auth token\n */\n private buildWSUrl(): string {\n let url = this.url;\n\n if (this.authToken) {\n const separator = url.includes(\"?\") ? \"&\" : \"?\";\n const paramName = this.authToken.startsWith(\"ak_\") ? \"api_key\" : \"token\";\n url += `${separator}${paramName}=${encodeURIComponent(this.authToken)}`;\n }\n\n return url;\n }\n\n /**\n * Register message handler\n */\n onMessage(handler: WSMessageHandler): () => void {\n this.messageHandlers.add(handler);\n return () => this.messageHandlers.delete(handler);\n }\n\n /**\n * Unregister message handler\n */\n offMessage(handler: WSMessageHandler): void {\n this.messageHandlers.delete(handler);\n }\n\n /**\n * Register error handler\n */\n onError(handler: WSErrorHandler): () => void {\n this.errorHandlers.add(handler);\n return () => this.errorHandlers.delete(handler);\n }\n\n /**\n * Unregister error handler\n */\n offError(handler: WSErrorHandler): void {\n this.errorHandlers.delete(handler);\n }\n\n /**\n * Register close handler\n */\n onClose(handler: WSCloseHandler): () => void {\n this.closeHandlers.add(handler);\n return () => this.closeHandlers.delete(handler);\n }\n\n /**\n * Unregister close handler\n */\n offClose(handler: WSCloseHandler): void {\n this.closeHandlers.delete(handler);\n }\n\n /**\n * Register open handler\n */\n onOpen(handler: WSOpenHandler): () => void {\n this.openHandlers.add(handler);\n return () => this.openHandlers.delete(handler);\n }\n\n /**\n * Send data through WebSocket\n */\n send(data: string): void {\n if (this.ws?.readyState !== WebSocket.OPEN) {\n throw new SDKError(\"WebSocket is not connected\", 500, \"WS_NOT_CONNECTED\");\n }\n this.ws.send(data);\n }\n\n /**\n * Close WebSocket connection\n */\n close(): void {\n if (this.isClosed) {\n return;\n }\n this.isClosed = true;\n this.ws?.close();\n }\n\n /**\n * Check if WebSocket is connected\n */\n isConnected(): boolean {\n return !this.isClosed && this.ws?.readyState === WebSocket.OPEN;\n }\n\n /**\n * Update auth token\n */\n setAuthToken(token?: string): void {\n this.authToken = token;\n }\n}\n","import { HttpClient } from \"../core/http\";\nimport { WSClient, WSClientConfig } from \"../core/ws\";\n\nexport interface Message {\n data: string;\n topic: string;\n timestamp: number;\n}\n\nexport interface RawEnvelope {\n data: string; // base64-encoded\n timestamp: number;\n topic: string;\n}\n\n// Cross-platform base64 encoding/decoding utilities\nfunction base64Encode(str: string): string {\n if (typeof Buffer !== \"undefined\") {\n return Buffer.from(str).toString(\"base64\");\n } else if (typeof btoa !== \"undefined\") {\n return btoa(\n encodeURIComponent(str).replace(/%([0-9A-F]{2})/g, (match, p1) =>\n String.fromCharCode(parseInt(p1, 16))\n )\n );\n }\n throw new Error(\"No base64 encoding method available\");\n}\n\nfunction base64EncodeBytes(bytes: Uint8Array): string {\n if (typeof Buffer !== \"undefined\") {\n return Buffer.from(bytes).toString(\"base64\");\n } else if (typeof btoa !== \"undefined\") {\n let binary = \"\";\n for (let i = 0; i < bytes.length; i++) {\n binary += String.fromCharCode(bytes[i]);\n }\n return btoa(binary);\n }\n throw new Error(\"No base64 encoding method available\");\n}\n\nfunction base64Decode(b64: string): string {\n if (typeof Buffer !== \"undefined\") {\n return Buffer.from(b64, \"base64\").toString(\"utf-8\");\n } else if (typeof atob !== \"undefined\") {\n const binary = atob(b64);\n const bytes = new Uint8Array(binary.length);\n for (let i = 0; i < binary.length; i++) {\n bytes[i] = binary.charCodeAt(i);\n }\n return new TextDecoder().decode(bytes);\n }\n throw new Error(\"No base64 decoding method available\");\n}\n\nexport type MessageHandler = (message: Message) => void;\nexport type ErrorHandler = (error: Error) => void;\nexport type CloseHandler = () => void;\n\n/**\n * Simple PubSub client - one WebSocket connection per topic\n * No connection pooling, no reference counting - keep it simple\n */\nexport class PubSubClient {\n private httpClient: HttpClient;\n private wsConfig: Partial<WSClientConfig>;\n\n constructor(httpClient: HttpClient, wsConfig: Partial<WSClientConfig> = {}) {\n this.httpClient = httpClient;\n this.wsConfig = wsConfig;\n }\n\n /**\n * Publish a message to a topic via HTTP\n */\n async publish(topic: string, data: string | Uint8Array): Promise<void> {\n let dataBase64: string;\n if (typeof data === \"string\") {\n dataBase64 = base64Encode(data);\n } else {\n dataBase64 = base64EncodeBytes(data);\n }\n\n await this.httpClient.post(\n \"/v1/pubsub/publish\",\n {\n topic,\n data_base64: dataBase64,\n },\n {\n timeout: 30000,\n }\n );\n }\n\n /**\n * List active topics in the current namespace\n */\n async topics(): Promise<string[]> {\n const response = await this.httpClient.get<{ topics: string[] }>(\n \"/v1/pubsub/topics\"\n );\n return response.topics || [];\n }\n\n /**\n * Subscribe to a topic via WebSocket\n * Creates one WebSocket connection per topic\n */\n async subscribe(\n topic: string,\n handlers: {\n onMessage?: MessageHandler;\n onError?: ErrorHandler;\n onClose?: CloseHandler;\n } = {}\n ): Promise<Subscription> {\n // Build WebSocket URL for this topic\n const wsUrl = new URL(this.wsConfig.wsURL || \"ws://127.0.0.1:6001\");\n wsUrl.pathname = \"/v1/pubsub/ws\";\n wsUrl.searchParams.set(\"topic\", topic);\n\n const authToken = this.httpClient.getApiKey() ?? this.httpClient.getToken();\n\n // Create WebSocket client\n const wsClient = new WSClient({\n ...this.wsConfig,\n wsURL: wsUrl.toString(),\n authToken,\n });\n\n await wsClient.connect();\n\n // Create subscription wrapper\n const subscription = new Subscription(wsClient, topic);\n\n if (handlers.onMessage) {\n subscription.onMessage(handlers.onMessage);\n }\n if (handlers.onError) {\n subscription.onError(handlers.onError);\n }\n if (handlers.onClose) {\n subscription.onClose(handlers.onClose);\n }\n\n return subscription;\n }\n}\n\n/**\n * Subscription represents an active WebSocket subscription to a topic\n */\nexport class Subscription {\n private wsClient: WSClient;\n private topic: string;\n private messageHandlers: Set<MessageHandler> = new Set();\n private errorHandlers: Set<ErrorHandler> = new Set();\n private closeHandlers: Set<CloseHandler> = new Set();\n private isClosed = false;\n private wsMessageHandler: ((data: string) => void) | null = null;\n private wsErrorHandler: ((error: Error) => void) | null = null;\n private wsCloseHandler: (() => void) | null = null;\n\n constructor(wsClient: WSClient, topic: string) {\n this.wsClient = wsClient;\n this.topic = topic;\n\n // Register message handler\n this.wsMessageHandler = (data) => {\n try {\n // Parse gateway JSON envelope: {data: base64String, timestamp, topic}\n const envelope: RawEnvelope = JSON.parse(data);\n\n // Validate envelope structure\n if (!envelope || typeof envelope !== \"object\") {\n throw new Error(\"Invalid envelope: not an object\");\n }\n if (!envelope.data || typeof envelope.data !== \"string\") {\n throw new Error(\"Invalid envelope: missing or invalid data field\");\n }\n if (!envelope.topic || typeof envelope.topic !== \"string\") {\n throw new Error(\"Invalid envelope: missing or invalid topic field\");\n }\n if (typeof envelope.timestamp !== \"number\") {\n throw new Error(\n \"Invalid envelope: missing or invalid timestamp field\"\n );\n }\n\n // Decode base64 data\n const messageData = base64Decode(envelope.data);\n\n const message: Message = {\n topic: envelope.topic,\n data: messageData,\n timestamp: envelope.timestamp,\n };\n\n console.log(\"[Subscription] Received message on topic:\", this.topic);\n this.messageHandlers.forEach((handler) => handler(message));\n } catch (error) {\n console.error(\"[Subscription] Error processing message:\", error);\n this.errorHandlers.forEach((handler) =>\n handler(error instanceof Error ? error : new Error(String(error)))\n );\n }\n };\n\n this.wsClient.onMessage(this.wsMessageHandler);\n\n // Register error handler\n this.wsErrorHandler = (error) => {\n this.errorHandlers.forEach((handler) => handler(error));\n };\n this.wsClient.onError(this.wsErrorHandler);\n\n // Register close handler\n this.wsCloseHandler = () => {\n this.closeHandlers.forEach((handler) => handler());\n };\n this.wsClient.onClose(this.wsCloseHandler);\n }\n\n /**\n * Register message handler\n */\n onMessage(handler: MessageHandler): () => void {\n this.messageHandlers.add(handler);\n return () => this.messageHandlers.delete(handler);\n }\n\n /**\n * Register error handler\n */\n onError(handler: ErrorHandler): () => void {\n this.errorHandlers.add(handler);\n return () => this.errorHandlers.delete(handler);\n }\n\n /**\n * Register close handler\n */\n onClose(handler: CloseHandler): () => void {\n this.closeHandlers.add(handler);\n return () => this.closeHandlers.delete(handler);\n }\n\n /**\n * Close subscription and underlying WebSocket\n */\n close(): void {\n if (this.isClosed) {\n return;\n }\n this.isClosed = true;\n\n // Remove handlers from WSClient\n if (this.wsMessageHandler) {\n this.wsClient.offMessage(this.wsMessageHandler);\n this.wsMessageHandler = null;\n }\n if (this.wsErrorHandler) {\n this.wsClient.offError(this.wsErrorHandler);\n this.wsErrorHandler = null;\n }\n if (this.wsCloseHandler) {\n this.wsClient.offClose(this.wsCloseHandler);\n this.wsCloseHandler = null;\n }\n\n // Clear all local handlers\n this.messageHandlers.clear();\n this.errorHandlers.clear();\n this.closeHandlers.clear();\n\n // Close WebSocket connection\n this.wsClient.close();\n }\n\n /**\n * Check if subscription is active\n */\n isConnected(): boolean {\n return !this.isClosed && this.wsClient.isConnected();\n }\n}\n","import { HttpClient } from \"../core/http\";\n\nexport interface PeerInfo {\n id: string;\n addresses: string[];\n lastSeen?: string;\n}\n\nexport interface NetworkStatus {\n node_id: string;\n connected: boolean;\n peer_count: number;\n database_size: number;\n uptime: number;\n}\n\nexport interface ProxyRequest {\n url: string;\n method: string;\n headers?: Record<string, string>;\n body?: string;\n}\n\nexport interface ProxyResponse {\n status_code: number;\n headers: Record<string, string>;\n body: string;\n error?: string;\n}\n\nexport class NetworkClient {\n private httpClient: HttpClient;\n\n constructor(httpClient: HttpClient) {\n this.httpClient = httpClient;\n }\n\n /**\n * Check gateway health.\n */\n async health(): Promise<boolean> {\n try {\n await this.httpClient.get(\"/v1/health\");\n return true;\n } catch {\n return false;\n }\n }\n\n /**\n * Get network status.\n */\n async status(): Promise<NetworkStatus> {\n const response = await this.httpClient.get<NetworkStatus>(\n \"/v1/network/status\"\n );\n return response;\n }\n\n /**\n * Get connected peers.\n */\n async peers(): Promise<PeerInfo[]> {\n const response = await this.httpClient.get<{ peers: PeerInfo[] }>(\n \"/v1/network/peers\"\n );\n return response.peers || [];\n }\n\n /**\n * Connect to a peer.\n */\n async connect(peerAddr: string): Promise<void> {\n await this.httpClient.post(\"/v1/network/connect\", { peer_addr: peerAddr });\n }\n\n /**\n * Disconnect from a peer.\n */\n async disconnect(peerId: string): Promise<void> {\n await this.httpClient.post(\"/v1/network/disconnect\", { peer_id: peerId });\n }\n\n /**\n * Proxy an HTTP request through the Anyone network.\n * Requires authentication (API key or JWT).\n *\n * @param request - The proxy request configuration\n * @returns The proxied response\n * @throws {SDKError} If the Anyone proxy is not available or the request fails\n *\n * @example\n * ```ts\n * const response = await client.network.proxyAnon({\n * url: 'https://api.example.com/data',\n * method: 'GET',\n * headers: {\n * 'Accept': 'application/json'\n * }\n * });\n *\n * console.log(response.status_code); // 200\n * console.log(response.body); // Response data\n * ```\n */\n async proxyAnon(request: ProxyRequest): Promise<ProxyResponse> {\n const response = await this.httpClient.post<ProxyResponse>(\n \"/v1/proxy/anon\",\n request\n );\n\n // Check if the response contains an error\n if (response.error) {\n throw new Error(`Proxy request failed: ${response.error}`);\n }\n\n return response;\n }\n}\n","import { HttpClient } from \"../core/http\";\nimport { SDKError } from \"../errors\";\n\nexport interface CacheGetRequest {\n dmap: string;\n key: string;\n}\n\nexport interface CacheGetResponse {\n key: string;\n value: any;\n dmap: string;\n}\n\nexport interface CachePutRequest {\n dmap: string;\n key: string;\n value: any;\n ttl?: string; // Duration string like \"1h\", \"30m\"\n}\n\nexport interface CachePutResponse {\n status: string;\n key: string;\n dmap: string;\n}\n\nexport interface CacheDeleteRequest {\n dmap: string;\n key: string;\n}\n\nexport interface CacheDeleteResponse {\n status: string;\n key: string;\n dmap: string;\n}\n\nexport interface CacheMultiGetRequest {\n dmap: string;\n keys: string[];\n}\n\nexport interface CacheMultiGetResponse {\n results: Array<{\n key: string;\n value: any;\n }>;\n dmap: string;\n}\n\nexport interface CacheScanRequest {\n dmap: string;\n match?: string; // Optional regex pattern\n}\n\nexport interface CacheScanResponse {\n keys: string[];\n count: number;\n dmap: string;\n}\n\nexport interface CacheHealthResponse {\n status: string;\n service: string;\n}\n\nexport class CacheClient {\n private httpClient: HttpClient;\n\n constructor(httpClient: HttpClient) {\n this.httpClient = httpClient;\n }\n\n /**\n * Check cache service health\n */\n async health(): Promise<CacheHealthResponse> {\n return this.httpClient.get(\"/v1/cache/health\");\n }\n\n /**\n * Get a value from cache\n * Returns null if the key is not found (cache miss/expired), which is normal behavior\n */\n async get(dmap: string, key: string): Promise<CacheGetResponse | null> {\n try {\n return await this.httpClient.post<CacheGetResponse>(\"/v1/cache/get\", {\n dmap,\n key,\n });\n } catch (error) {\n // Cache misses (404 or \"key not found\" messages) are normal behavior - return null instead of throwing\n if (\n error instanceof SDKError &&\n (error.httpStatus === 404 ||\n (error.httpStatus === 500 &&\n error.message?.toLowerCase().includes(\"key not found\")))\n ) {\n return null;\n }\n // Re-throw other errors (network issues, server errors, etc.)\n throw error;\n }\n }\n\n /**\n * Put a value into cache\n */\n async put(\n dmap: string,\n key: string,\n value: any,\n ttl?: string\n ): Promise<CachePutResponse> {\n return this.httpClient.post<CachePutResponse>(\"/v1/cache/put\", {\n dmap,\n key,\n value,\n ttl,\n });\n }\n\n /**\n * Delete a value from cache\n */\n async delete(dmap: string, key: string): Promise<CacheDeleteResponse> {\n return this.httpClient.post<CacheDeleteResponse>(\"/v1/cache/delete\", {\n dmap,\n key,\n });\n }\n\n /**\n * Get multiple values from cache in a single request\n * Returns a map of key -> value (or null if not found)\n * Gracefully handles 404 errors (endpoint not implemented) by returning empty results\n */\n async multiGet(\n dmap: string,\n keys: string[]\n ): Promise<Map<string, any | null>> {\n try {\n if (keys.length === 0) {\n return new Map();\n }\n\n const response = await this.httpClient.post<CacheMultiGetResponse>(\n \"/v1/cache/mget\",\n {\n dmap,\n keys,\n }\n );\n\n // Convert array to Map\n const resultMap = new Map<string, any | null>();\n\n // First, mark all keys as null (cache miss)\n keys.forEach((key) => {\n resultMap.set(key, null);\n });\n\n // Then, update with found values\n if (response.results) {\n response.results.forEach(({ key, value }) => {\n resultMap.set(key, value);\n });\n }\n\n return resultMap;\n } catch (error) {\n // Handle 404 errors silently (endpoint not implemented on backend)\n // This is expected behavior when the backend doesn't support multiGet yet\n if (error instanceof SDKError && error.httpStatus === 404) {\n // Return map with all nulls silently - caller can fall back to individual gets\n const resultMap = new Map<string, any | null>();\n keys.forEach((key) => {\n resultMap.set(key, null);\n });\n return resultMap;\n }\n\n // Log and return empty results for other errors\n const resultMap = new Map<string, any | null>();\n keys.forEach((key) => {\n resultMap.set(key, null);\n });\n console.error(`[CacheClient] Error in multiGet for ${dmap}:`, error);\n return resultMap;\n }\n }\n\n /**\n * Scan keys in a distributed map, optionally matching a regex pattern\n */\n async scan(dmap: string, match?: string): Promise<CacheScanResponse> {\n return this.httpClient.post<CacheScanResponse>(\"/v1/cache/scan\", {\n dmap,\n match,\n });\n }\n}\n","import { HttpClient } from \"../core/http\";\n\nexport interface StorageUploadResponse {\n cid: string;\n name: string;\n size: number;\n}\n\nexport interface StoragePinRequest {\n cid: string;\n name?: string;\n}\n\nexport interface StoragePinResponse {\n cid: string;\n name: string;\n}\n\nexport interface StorageStatus {\n cid: string;\n name: string;\n status: string; // \"pinned\", \"pinning\", \"queued\", \"unpinned\", \"error\"\n replication_min: number;\n replication_max: number;\n replication_factor: number;\n peers: string[];\n error?: string;\n}\n\nexport class StorageClient {\n private httpClient: HttpClient;\n\n constructor(httpClient: HttpClient) {\n this.httpClient = httpClient;\n }\n\n /**\n * Upload content to IPFS and optionally pin it.\n * Supports both File objects (browser) and Buffer/ReadableStream (Node.js).\n *\n * @param file - File to upload (File, Blob, or Buffer)\n * @param name - Optional filename\n * @param options - Optional upload options\n * @param options.pin - Whether to pin the content (default: true). Pinning happens asynchronously on the backend.\n * @returns Upload result with CID\n *\n * @example\n * ```ts\n * // Browser\n * const fileInput = document.querySelector('input[type=\"file\"]');\n * const file = fileInput.files[0];\n * const result = await client.storage.upload(file, file.name);\n * console.log(result.cid);\n *\n * // Node.js\n * const fs = require('fs');\n * const fileBuffer = fs.readFileSync('image.jpg');\n * const result = await client.storage.upload(fileBuffer, 'image.jpg', { pin: true });\n * ```\n */\n async upload(\n file: File | Blob | ArrayBuffer | Uint8Array | ReadableStream<Uint8Array>,\n name?: string,\n options?: {\n pin?: boolean;\n }\n ): Promise<StorageUploadResponse> {\n // Create FormData for multipart upload\n const formData = new FormData();\n\n // Handle different input types\n if (file instanceof File) {\n formData.append(\"file\", file);\n } else if (file instanceof Blob) {\n formData.append(\"file\", file, name);\n } else if (file instanceof ArrayBuffer) {\n const blob = new Blob([file]);\n formData.append(\"file\", blob, name);\n } else if (file instanceof Uint8Array) {\n // Convert Uint8Array to ArrayBuffer for Blob constructor\n const buffer = file.buffer.slice(\n file.byteOffset,\n file.byteOffset + file.byteLength\n ) as ArrayBuffer;\n const blob = new Blob([buffer], { type: \"application/octet-stream\" });\n formData.append(\"file\", blob, name);\n } else if (file instanceof ReadableStream) {\n // For ReadableStream, we need to read it into a blob first\n // This is a limitation - in practice, pass File/Blob/Buffer\n const chunks: ArrayBuffer[] = [];\n const reader = file.getReader();\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n const buffer = value.buffer.slice(\n value.byteOffset,\n value.byteOffset + value.byteLength\n ) as ArrayBuffer;\n chunks.push(buffer);\n }\n const blob = new Blob(chunks);\n formData.append(\"file\", blob, name);\n } else {\n throw new Error(\n \"Unsupported file type. Use File, Blob, ArrayBuffer, Uint8Array, or ReadableStream.\"\n );\n }\n\n // Add pin flag (default: true)\n const shouldPin = options?.pin !== false; // Default to true\n formData.append(\"pin\", shouldPin ? \"true\" : \"false\");\n\n return this.httpClient.uploadFile<StorageUploadResponse>(\n \"/v1/storage/upload\",\n formData,\n { timeout: 300000 } // 5 minute timeout for large files\n );\n }\n\n /**\n * Pin an existing CID\n *\n * @param cid - Content ID to pin\n * @param name - Optional name for the pin\n * @returns Pin result\n */\n async pin(cid: string, name?: string): Promise<StoragePinResponse> {\n return this.httpClient.post<StoragePinResponse>(\"/v1/storage/pin\", {\n cid,\n name,\n });\n }\n\n /**\n * Get the pin status for a CID\n *\n * @param cid - Content ID to check\n * @returns Pin status information\n */\n async status(cid: string): Promise<StorageStatus> {\n return this.httpClient.get<StorageStatus>(`/v1/storage/status/${cid}`);\n }\n\n /**\n * Retrieve content from IPFS by CID\n *\n * @param cid - Content ID to retrieve\n * @returns ReadableStream of the content\n *\n * @example\n * ```ts\n * const stream = await client.storage.get(cid);\n * const reader = stream.getReader();\n * while (true) {\n * const { done, value } = await reader.read();\n * if (done) break;\n * // Process chunk\n * }\n * ```\n */\n async get(cid: string): Promise<ReadableStream<Uint8Array>> {\n // Retry logic for content retrieval - content may not be immediately available\n // after upload due to eventual consistency in IPFS Cluster\n // IPFS Cluster pins can take 2-3+ seconds to complete across all nodes\n const maxAttempts = 8;\n let lastError: Error | null = null;\n\n for (let attempt = 1; attempt <= maxAttempts; attempt++) {\n try {\n const response = await this.httpClient.getBinary(\n `/v1/storage/get/${cid}`\n );\n\n if (!response.body) {\n throw new Error(\"Response body is null\");\n }\n\n return response.body;\n } catch (error: any) {\n lastError = error;\n\n // Check if this is a 404 error (content not found)\n const isNotFound =\n error?.httpStatus === 404 ||\n error?.message?.includes(\"not found\") ||\n error?.message?.includes(\"404\");\n\n // If it's not a 404 error, or this is the last attempt, give up\n if (!isNotFound || attempt === maxAttempts) {\n throw error;\n }\n\n // Wait before retrying (exponential backoff: 400ms, 800ms, 1200ms, etc.)\n // This gives up to ~12 seconds total wait time, covering typical pin completion\n const backoffMs = attempt * 2500;\n await new Promise((resolve) => setTimeout(resolve, backoffMs));\n }\n }\n\n // This should never be reached, but TypeScript needs it\n throw lastError || new Error(\"Failed to retrieve content\");\n }\n\n /**\n * Retrieve content from IPFS by CID and return the full Response object\n * Useful when you need access to response headers (e.g., content-length)\n *\n * @param cid - Content ID to retrieve\n * @returns Response object with body stream and headers\n *\n * @example\n * ```ts\n * const response = await client.storage.getBinary(cid);\n * const contentLength = response.headers.get('content-length');\n * const reader = response.body.getReader();\n * // ... read stream\n * ```\n */\n async getBinary(cid: string): Promise<Response> {\n // Retry logic for content retrieval - content may not be immediately available\n // after upload due to eventual consistency in IPFS Cluster\n // IPFS Cluster pins can take 2-3+ seconds to complete across all nodes\n const maxAttempts = 8;\n let lastError: Error | null = null;\n\n for (let attempt = 1; attempt <= maxAttempts; attempt++) {\n try {\n const response = await this.httpClient.getBinary(\n `/v1/storage/get/${cid}`\n );\n\n if (!response) {\n throw new Error(\"Response is null\");\n }\n\n return response;\n } catch (error: any) {\n lastError = error;\n\n // Check if this is a 404 error (content not found)\n const isNotFound =\n error?.httpStatus === 404 ||\n error?.message?.includes(\"not found\") ||\n error?.message?.includes(\"404\");\n\n // If it's not a 404 error, or this is the last attempt, give up\n if (!isNotFound || attempt === maxAttempts) {\n throw error;\n }\n\n // Wait before retrying (exponential backoff: 400ms, 800ms, 1200ms, etc.)\n // This gives up to ~12 seconds total wait time, covering typical pin completion\n const backoffMs = attempt * 2500;\n await new Promise((resolve) => setTimeout(resolve, backoffMs));\n }\n }\n\n // This should never be reached, but TypeScript needs it\n throw lastError || new Error(\"Failed to retrieve content\");\n }\n\n /**\n * Unpin a CID\n *\n * @param cid - Content ID to unpin\n */\n async unpin(cid: string): Promise<void> {\n await this.httpClient.delete(`/v1/storage/unpin/${cid}`);\n }\n}\n","import { HttpClient, HttpClientConfig } from \"./core/http\";\nimport { AuthClient } from \"./auth/client\";\nimport { DBClient } from \"./db/client\";\nimport { PubSubClient } from \"./pubsub/client\";\nimport { NetworkClient } from \"./network/client\";\nimport { CacheClient } from \"./cache/client\";\nimport { StorageClient } from \"./storage/client\";\nimport { WSClientConfig } from \"./core/ws\";\nimport {\n StorageAdapter,\n MemoryStorage,\n LocalStorageAdapter,\n} from \"./auth/types\";\n\nexport interface ClientConfig extends Omit<HttpClientConfig, \"fetch\"> {\n apiKey?: string;\n jwt?: string;\n storage?: StorageAdapter;\n wsConfig?: Partial<WSClientConfig>;\n fetch?: typeof fetch;\n}\n\nexport interface Client {\n auth: AuthClient;\n db: DBClient;\n pubsub: PubSubClient;\n network: NetworkClient;\n cache: CacheClient;\n storage: StorageClient;\n}\n\nexport function createClient(config: ClientConfig): Client {\n const httpClient = new HttpClient({\n baseURL: config.baseURL,\n timeout: config.timeout,\n maxRetries: config.maxRetries,\n retryDelayMs: config.retryDelayMs,\n fetch: config.fetch,\n });\n\n const auth = new AuthClient({\n httpClient,\n storage: config.storage,\n apiKey: config.apiKey,\n jwt: config.jwt,\n });\n\n // Derive WebSocket URL from baseURL if not explicitly provided\n const wsURL =\n config.wsConfig?.wsURL ??\n config.baseURL.replace(/^http/, \"ws\").replace(/\\/$/, \"\");\n\n const db = new DBClient(httpClient);\n const pubsub = new PubSubClient(httpClient, {\n ...config.wsConfig,\n wsURL,\n });\n const network = new NetworkClient(httpClient);\n const cache = new CacheClient(httpClient);\n const storage = new StorageClient(httpClient);\n\n return {\n auth,\n db,\n pubsub,\n network,\n cache,\n storage,\n };\n}\n\nexport { HttpClient } from \"./core/http\";\nexport { WSClient } from \"./core/ws\";\nexport { AuthClient } from \"./auth/client\";\nexport { DBClient } from \"./db/client\";\nexport { QueryBuilder } from \"./db/qb\";\nexport { Repository } from \"./db/repository\";\nexport { PubSubClient, Subscription } from \"./pubsub/client\";\nexport { NetworkClient } from \"./network/client\";\nexport { CacheClient } from \"./cache/client\";\nexport { StorageClient } from \"./storage/client\";\nexport { SDKError } from \"./errors\";\nexport { MemoryStorage, LocalStorageAdapter } from \"./auth/types\";\nexport type { StorageAdapter, AuthConfig, WhoAmI } from \"./auth/types\";\nexport type * from \"./db/types\";\nexport type {\n Message,\n MessageHandler,\n ErrorHandler,\n CloseHandler,\n} from \"./pubsub/client\";\nexport type {\n PeerInfo,\n NetworkStatus,\n ProxyRequest,\n ProxyResponse,\n} from \"./network/client\";\nexport type {\n CacheGetRequest,\n CacheGetResponse,\n CachePutRequest,\n CachePutResponse,\n CacheDeleteRequest,\n CacheDeleteResponse,\n CacheMultiGetRequest,\n CacheMultiGetResponse,\n CacheScanRequest,\n CacheScanResponse,\n CacheHealthResponse,\n} from \"./cache/client\";\nexport type {\n StorageUploadResponse,\n StoragePinRequest,\n StoragePinResponse,\n StorageStatus,\n} from \"./storage/client\";\n"],"mappings":"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","names":["resultMap"]}
1
+ {"version":3,"sources":["../src/errors.ts","../src/core/http.ts","../src/auth/types.ts","../src/auth/client.ts","../src/db/qb.ts","../src/db/repository.ts","../src/db/client.ts","../src/core/ws.ts","../src/pubsub/client.ts","../src/network/client.ts","../src/cache/client.ts","../src/storage/client.ts","../src/functions/client.ts","../src/index.ts"],"sourcesContent":["export class SDKError extends Error {\n public readonly httpStatus: number;\n public readonly code: string;\n public readonly details: Record<string, any>;\n\n constructor(\n message: string,\n httpStatus: number = 500,\n code: string = \"SDK_ERROR\",\n details: Record<string, any> = {}\n ) {\n super(message);\n this.name = \"SDKError\";\n this.httpStatus = httpStatus;\n this.code = code;\n this.details = details;\n }\n\n static fromResponse(\n status: number,\n body: any,\n message?: string\n ): SDKError {\n const errorMsg = message || body?.error || `HTTP ${status}`;\n const code = body?.code || `HTTP_${status}`;\n return new SDKError(errorMsg, status, code, body);\n }\n\n toJSON() {\n return {\n name: this.name,\n message: this.message,\n httpStatus: this.httpStatus,\n code: this.code,\n details: this.details,\n };\n }\n}\n","import { SDKError } from \"../errors\";\n\nexport interface HttpClientConfig {\n baseURL: string;\n timeout?: number;\n maxRetries?: number;\n retryDelayMs?: number;\n fetch?: typeof fetch;\n}\n\n/**\n * Create a fetch function with proper TLS configuration for staging certificates\n * In Node.js, we need to configure TLS to accept Let's Encrypt staging certificates\n */\nfunction createFetchWithTLSConfig(): typeof fetch {\n // Check if we're in a Node.js environment\n if (typeof process !== \"undefined\" && process.versions?.node) {\n // For testing/staging/development: allow staging certificates\n // Let's Encrypt staging certificates are self-signed and not trusted by default\n const isDevelopmentOrStaging =\n process.env.NODE_ENV !== \"production\" ||\n process.env.DEBROS_ALLOW_STAGING_CERTS === \"true\" ||\n process.env.DEBROS_USE_HTTPS === \"true\";\n\n if (isDevelopmentOrStaging) {\n // Allow self-signed/staging certificates\n // WARNING: Only use this in development/testing environments\n process.env.NODE_TLS_REJECT_UNAUTHORIZED = \"0\";\n }\n }\n return globalThis.fetch;\n}\n\nexport class HttpClient {\n private baseURL: string;\n private timeout: number;\n private maxRetries: number;\n private retryDelayMs: number;\n private fetch: typeof fetch;\n private apiKey?: string;\n private jwt?: string;\n\n constructor(config: HttpClientConfig) {\n this.baseURL = config.baseURL.replace(/\\/$/, \"\");\n this.timeout = config.timeout ?? 60000;\n this.maxRetries = config.maxRetries ?? 3;\n this.retryDelayMs = config.retryDelayMs ?? 1000;\n // Use provided fetch or create one with proper TLS configuration for staging certificates\n this.fetch = config.fetch ?? createFetchWithTLSConfig();\n }\n\n setApiKey(apiKey?: string) {\n this.apiKey = apiKey;\n // Don't clear JWT - allow both to coexist\n }\n\n setJwt(jwt?: string) {\n this.jwt = jwt;\n // Don't clear API key - allow both to coexist\n if (typeof console !== \"undefined\") {\n console.log(\n \"[HttpClient] JWT set:\",\n !!jwt,\n \"API key still present:\",\n !!this.apiKey\n );\n }\n }\n\n private getAuthHeaders(path: string): Record<string, string> {\n const headers: Record<string, string> = {};\n\n // For database, pubsub, proxy, and cache operations, ONLY use API key to avoid JWT user context\n // interfering with namespace-level authorization\n const isDbOperation = path.includes(\"/v1/rqlite/\");\n const isPubSubOperation = path.includes(\"/v1/pubsub/\");\n const isProxyOperation = path.includes(\"/v1/proxy/\");\n const isCacheOperation = path.includes(\"/v1/cache/\");\n\n // For auth operations, prefer API key over JWT to ensure proper authentication\n const isAuthOperation = path.includes(\"/v1/auth/\");\n\n if (\n isDbOperation ||\n isPubSubOperation ||\n isProxyOperation ||\n isCacheOperation\n ) {\n // For database/pubsub/proxy/cache operations: use only API key (preferred for namespace operations)\n if (this.apiKey) {\n headers[\"X-API-Key\"] = this.apiKey;\n } else if (this.jwt) {\n // Fallback to JWT if no API key\n headers[\"Authorization\"] = `Bearer ${this.jwt}`;\n }\n } else if (isAuthOperation) {\n // For auth operations: prefer API key over JWT (auth endpoints should use explicit API key)\n if (this.apiKey) {\n headers[\"X-API-Key\"] = this.apiKey;\n }\n if (this.jwt) {\n headers[\"Authorization\"] = `Bearer ${this.jwt}`;\n }\n } else {\n // For other operations: send both JWT and API key\n if (this.jwt) {\n headers[\"Authorization\"] = `Bearer ${this.jwt}`;\n }\n if (this.apiKey) {\n headers[\"X-API-Key\"] = this.apiKey;\n }\n }\n return headers;\n }\n\n private getAuthToken(): string | undefined {\n return this.jwt || this.apiKey;\n }\n\n getApiKey(): string | undefined {\n return this.apiKey;\n }\n\n /**\n * Get the base URL\n */\n getBaseURL(): string {\n return this.baseURL;\n }\n\n async request<T = any>(\n method: \"GET\" | \"POST\" | \"PUT\" | \"DELETE\",\n path: string,\n options: {\n body?: any;\n headers?: Record<string, string>;\n query?: Record<string, string | number | boolean>;\n timeout?: number; // Per-request timeout override\n } = {}\n ): Promise<T> {\n const startTime = performance.now(); // Track request start time\n const url = new URL(this.baseURL + path);\n if (options.query) {\n Object.entries(options.query).forEach(([key, value]) => {\n url.searchParams.append(key, String(value));\n });\n }\n\n const headers: Record<string, string> = {\n \"Content-Type\": \"application/json\",\n ...this.getAuthHeaders(path),\n ...options.headers,\n };\n\n const controller = new AbortController();\n const requestTimeout = options.timeout ?? this.timeout; // Use override or default\n const timeoutId = setTimeout(() => controller.abort(), requestTimeout);\n\n const fetchOptions: RequestInit = {\n method,\n headers,\n signal: controller.signal,\n };\n\n if (options.body !== undefined) {\n fetchOptions.body = JSON.stringify(options.body);\n }\n\n // Extract and log SQL query details for rqlite operations\n const isRqliteOperation = path.includes(\"/v1/rqlite/\");\n let queryDetails: string | null = null;\n if (isRqliteOperation && options.body) {\n try {\n const body =\n typeof options.body === \"string\"\n ? JSON.parse(options.body)\n : options.body;\n\n if (body.sql) {\n // Direct SQL query (query/exec endpoints)\n queryDetails = `SQL: ${body.sql}`;\n if (body.args && body.args.length > 0) {\n queryDetails += ` | Args: [${body.args\n .map((a: any) => (typeof a === \"string\" ? `\"${a}\"` : a))\n .join(\", \")}]`;\n }\n } else if (body.table) {\n // Table-based query (find/find-one/select endpoints)\n queryDetails = `Table: ${body.table}`;\n if (body.criteria && Object.keys(body.criteria).length > 0) {\n queryDetails += ` | Criteria: ${JSON.stringify(body.criteria)}`;\n }\n if (body.options) {\n queryDetails += ` | Options: ${JSON.stringify(body.options)}`;\n }\n if (body.select) {\n queryDetails += ` | Select: ${JSON.stringify(body.select)}`;\n }\n if (body.where) {\n queryDetails += ` | Where: ${JSON.stringify(body.where)}`;\n }\n if (body.limit) {\n queryDetails += ` | Limit: ${body.limit}`;\n }\n if (body.offset) {\n queryDetails += ` | Offset: ${body.offset}`;\n }\n }\n } catch (e) {\n // Failed to parse body, ignore\n }\n }\n\n try {\n const result = await this.requestWithRetry(\n url.toString(),\n fetchOptions,\n 0,\n startTime\n );\n const duration = performance.now() - startTime;\n if (typeof console !== \"undefined\") {\n const logMessage = `[HttpClient] ${method} ${path} completed in ${duration.toFixed(\n 2\n )}ms`;\n if (queryDetails) {\n console.log(logMessage);\n console.log(`[HttpClient] ${queryDetails}`);\n } else {\n console.log(logMessage);\n }\n }\n return result;\n } catch (error) {\n const duration = performance.now() - startTime;\n if (typeof console !== \"undefined\") {\n // For 404 errors on find-one calls, log at warn level (not error) since \"not found\" is expected\n // Application layer handles these cases in try-catch blocks\n const is404FindOne =\n path === \"/v1/rqlite/find-one\" &&\n error instanceof SDKError &&\n error.httpStatus === 404;\n\n if (is404FindOne) {\n // Log as warning for visibility, but not as error since it's expected behavior\n console.warn(\n `[HttpClient] ${method} ${path} returned 404 after ${duration.toFixed(\n 2\n )}ms (expected for optional lookups)`\n );\n } else {\n const errorMessage = `[HttpClient] ${method} ${path} failed after ${duration.toFixed(\n 2\n )}ms:`;\n console.error(errorMessage, error);\n if (queryDetails) {\n console.error(`[HttpClient] ${queryDetails}`);\n }\n }\n }\n throw error;\n } finally {\n clearTimeout(timeoutId);\n }\n }\n\n private async requestWithRetry(\n url: string,\n options: RequestInit,\n attempt: number = 0,\n startTime?: number // Track start time for timing across retries\n ): Promise<any> {\n try {\n const response = await this.fetch(url, options);\n\n if (!response.ok) {\n let body: any;\n try {\n body = await response.json();\n } catch {\n body = { error: response.statusText };\n }\n throw SDKError.fromResponse(response.status, body);\n }\n\n // Request succeeded - return response\n const contentType = response.headers.get(\"content-type\");\n if (contentType?.includes(\"application/json\")) {\n return response.json();\n }\n return response.text();\n } catch (error) {\n const isRetryableError =\n error instanceof SDKError &&\n [408, 429, 500, 502, 503, 504].includes(error.httpStatus);\n\n // Retry on same gateway for retryable HTTP errors\n if (isRetryableError && attempt < this.maxRetries) {\n if (typeof console !== \"undefined\") {\n console.warn(\n `[HttpClient] Retrying request (attempt ${attempt + 1}/${this.maxRetries})`\n );\n }\n await new Promise((resolve) =>\n setTimeout(resolve, this.retryDelayMs * (attempt + 1))\n );\n return this.requestWithRetry(url, options, attempt + 1, startTime);\n }\n\n // All retries exhausted - throw error for app to handle\n throw error;\n }\n }\n\n async get<T = any>(\n path: string,\n options?: Omit<Parameters<typeof this.request>[2], \"body\">\n ): Promise<T> {\n return this.request<T>(\"GET\", path, options);\n }\n\n async post<T = any>(\n path: string,\n body?: any,\n options?: Omit<Parameters<typeof this.request>[2], \"body\">\n ): Promise<T> {\n return this.request<T>(\"POST\", path, { ...options, body });\n }\n\n async put<T = any>(\n path: string,\n body?: any,\n options?: Omit<Parameters<typeof this.request>[2], \"body\">\n ): Promise<T> {\n return this.request<T>(\"PUT\", path, { ...options, body });\n }\n\n async delete<T = any>(\n path: string,\n options?: Omit<Parameters<typeof this.request>[2], \"body\">\n ): Promise<T> {\n return this.request<T>(\"DELETE\", path, options);\n }\n\n /**\n * Upload a file using multipart/form-data\n * This is a special method for file uploads that bypasses JSON serialization\n */\n async uploadFile<T = any>(\n path: string,\n formData: FormData,\n options?: {\n timeout?: number;\n }\n ): Promise<T> {\n const startTime = performance.now(); // Track upload start time\n const url = new URL(this.baseURL + path);\n const headers: Record<string, string> = {\n ...this.getAuthHeaders(path),\n // Don't set Content-Type - browser will set it with boundary\n };\n\n const controller = new AbortController();\n const requestTimeout = options?.timeout ?? this.timeout * 5; // 5x timeout for uploads\n const timeoutId = setTimeout(() => controller.abort(), requestTimeout);\n\n const fetchOptions: RequestInit = {\n method: \"POST\",\n headers,\n body: formData,\n signal: controller.signal,\n };\n\n try {\n const result = await this.requestWithRetry(\n url.toString(),\n fetchOptions,\n 0,\n startTime\n );\n const duration = performance.now() - startTime;\n if (typeof console !== \"undefined\") {\n console.log(\n `[HttpClient] POST ${path} (upload) completed in ${duration.toFixed(\n 2\n )}ms`\n );\n }\n return result;\n } catch (error) {\n const duration = performance.now() - startTime;\n if (typeof console !== \"undefined\") {\n console.error(\n `[HttpClient] POST ${path} (upload) failed after ${duration.toFixed(\n 2\n )}ms:`,\n error\n );\n }\n throw error;\n } finally {\n clearTimeout(timeoutId);\n }\n }\n\n /**\n * Get a binary response (returns Response object for streaming)\n */\n async getBinary(path: string): Promise<Response> {\n const url = new URL(this.baseURL + path);\n const headers: Record<string, string> = {\n ...this.getAuthHeaders(path),\n };\n\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), this.timeout * 5); // 5x timeout for downloads\n\n const fetchOptions: RequestInit = {\n method: \"GET\",\n headers,\n signal: controller.signal,\n };\n\n try {\n const response = await this.fetch(url.toString(), fetchOptions);\n if (!response.ok) {\n clearTimeout(timeoutId);\n const error = await response.json().catch(() => ({\n error: response.statusText,\n }));\n throw SDKError.fromResponse(response.status, error);\n }\n return response;\n } catch (error) {\n clearTimeout(timeoutId);\n if (error instanceof SDKError) {\n throw error;\n }\n throw error;\n }\n }\n\n getToken(): string | undefined {\n return this.getAuthToken();\n }\n}\n","export interface AuthConfig {\n apiKey?: string;\n jwt?: string;\n}\n\nexport interface WhoAmI {\n address?: string;\n namespace?: string;\n authenticated: boolean;\n}\n\nexport interface StorageAdapter {\n get(key: string): Promise<string | null>;\n set(key: string, value: string): Promise<void>;\n clear(): Promise<void>;\n}\n\nexport class MemoryStorage implements StorageAdapter {\n private storage: Map<string, string> = new Map();\n\n async get(key: string): Promise<string | null> {\n return this.storage.get(key) ?? null;\n }\n\n async set(key: string, value: string): Promise<void> {\n this.storage.set(key, value);\n }\n\n async clear(): Promise<void> {\n this.storage.clear();\n }\n}\n\nexport class LocalStorageAdapter implements StorageAdapter {\n private prefix = \"@network/sdk:\";\n\n async get(key: string): Promise<string | null> {\n if (typeof globalThis !== \"undefined\" && globalThis.localStorage) {\n return globalThis.localStorage.getItem(this.prefix + key);\n }\n return null;\n }\n\n async set(key: string, value: string): Promise<void> {\n if (typeof globalThis !== \"undefined\" && globalThis.localStorage) {\n globalThis.localStorage.setItem(this.prefix + key, value);\n }\n }\n\n async clear(): Promise<void> {\n if (typeof globalThis !== \"undefined\" && globalThis.localStorage) {\n const keysToDelete: string[] = [];\n for (let i = 0; i < globalThis.localStorage.length; i++) {\n const key = globalThis.localStorage.key(i);\n if (key?.startsWith(this.prefix)) {\n keysToDelete.push(key);\n }\n }\n keysToDelete.forEach((key) => globalThis.localStorage.removeItem(key));\n }\n }\n}\n","import { HttpClient } from \"../core/http\";\nimport { AuthConfig, WhoAmI, StorageAdapter, MemoryStorage } from \"./types\";\n\nexport class AuthClient {\n private httpClient: HttpClient;\n private storage: StorageAdapter;\n private currentApiKey?: string;\n private currentJwt?: string;\n\n constructor(config: {\n httpClient: HttpClient;\n storage?: StorageAdapter;\n apiKey?: string;\n jwt?: string;\n }) {\n this.httpClient = config.httpClient;\n this.storage = config.storage ?? new MemoryStorage();\n this.currentApiKey = config.apiKey;\n this.currentJwt = config.jwt;\n\n if (this.currentApiKey) {\n this.httpClient.setApiKey(this.currentApiKey);\n }\n if (this.currentJwt) {\n this.httpClient.setJwt(this.currentJwt);\n }\n }\n\n setApiKey(apiKey: string) {\n this.currentApiKey = apiKey;\n // Don't clear JWT - it will be cleared explicitly on logout\n this.httpClient.setApiKey(apiKey);\n this.storage.set(\"apiKey\", apiKey);\n }\n\n setJwt(jwt: string) {\n this.currentJwt = jwt;\n // Don't clear API key - keep it as fallback for after logout\n this.httpClient.setJwt(jwt);\n this.storage.set(\"jwt\", jwt);\n }\n\n getToken(): string | undefined {\n return this.httpClient.getToken();\n }\n\n async whoami(): Promise<WhoAmI> {\n try {\n const response = await this.httpClient.get<WhoAmI>(\"/v1/auth/whoami\");\n return response;\n } catch {\n return { authenticated: false };\n }\n }\n\n async refresh(): Promise<string> {\n const response = await this.httpClient.post<{ token: string }>(\n \"/v1/auth/refresh\"\n );\n const token = response.token;\n this.setJwt(token);\n return token;\n }\n\n /**\n * Logout user and clear JWT, but preserve API key\n * Use this for user logout in apps where API key is app-level credential\n */\n async logoutUser(): Promise<void> {\n // Attempt server-side logout if using JWT\n if (this.currentJwt) {\n try {\n await this.httpClient.post(\"/v1/auth/logout\", { all: true });\n } catch (error) {\n // Log warning but don't fail - local cleanup is more important\n console.warn(\n \"Server-side logout failed, continuing with local cleanup:\",\n error\n );\n }\n }\n\n // Clear JWT only, preserve API key\n this.currentJwt = undefined;\n this.httpClient.setJwt(undefined);\n await this.storage.set(\"jwt\", \"\"); // Clear JWT from storage\n\n // Ensure API key is loaded and set as active auth method\n if (!this.currentApiKey) {\n // Try to load from storage\n const storedApiKey = await this.storage.get(\"apiKey\");\n if (storedApiKey) {\n this.currentApiKey = storedApiKey;\n }\n }\n\n // Restore API key as the active auth method\n if (this.currentApiKey) {\n this.httpClient.setApiKey(this.currentApiKey);\n console.log(\"[Auth] API key restored after user logout\");\n } else {\n console.warn(\"[Auth] No API key available after logout\");\n }\n }\n\n /**\n * Full logout - clears both JWT and API key\n * Use this to completely reset authentication state\n */\n async logout(): Promise<void> {\n // Only attempt server-side logout if using JWT\n // API keys don't support server-side logout with all=true\n if (this.currentJwt) {\n try {\n await this.httpClient.post(\"/v1/auth/logout\", { all: true });\n } catch (error) {\n // Log warning but don't fail - local cleanup is more important\n console.warn(\n \"Server-side logout failed, continuing with local cleanup:\",\n error\n );\n }\n }\n\n // Always clear local state\n this.currentApiKey = undefined;\n this.currentJwt = undefined;\n this.httpClient.setApiKey(undefined);\n this.httpClient.setJwt(undefined);\n await this.storage.clear();\n }\n\n async clear(): Promise<void> {\n this.currentApiKey = undefined;\n this.currentJwt = undefined;\n this.httpClient.setApiKey(undefined);\n this.httpClient.setJwt(undefined);\n await this.storage.clear();\n }\n\n /**\n * Request a challenge nonce for wallet authentication\n */\n async challenge(params: {\n wallet: string;\n purpose?: string;\n namespace?: string;\n }): Promise<{\n nonce: string;\n wallet: string;\n namespace: string;\n expires_at: string;\n }> {\n const response = await this.httpClient.post(\"/v1/auth/challenge\", {\n wallet: params.wallet,\n purpose: params.purpose || \"authentication\",\n namespace: params.namespace || \"default\",\n });\n return response;\n }\n\n /**\n * Verify wallet signature and get JWT token\n */\n async verify(params: {\n wallet: string;\n nonce: string;\n signature: string;\n namespace?: string;\n chain_type?: \"ETH\" | \"SOL\";\n }): Promise<{\n access_token: string;\n refresh_token?: string;\n subject: string;\n namespace: string;\n api_key?: string;\n expires_in?: number;\n token_type?: string;\n }> {\n const response = await this.httpClient.post(\"/v1/auth/verify\", {\n wallet: params.wallet,\n nonce: params.nonce,\n signature: params.signature,\n namespace: params.namespace || \"default\",\n chain_type: params.chain_type || \"ETH\",\n });\n\n // Persist JWT\n this.setJwt(response.access_token);\n\n // Persist API key if server provided it (created in verifyHandler)\n if ((response as any).api_key) {\n this.setApiKey((response as any).api_key);\n }\n\n // Persist refresh token if present (optional, for silent renewal)\n if ((response as any).refresh_token) {\n await this.storage.set(\"refreshToken\", (response as any).refresh_token);\n }\n\n return response as any;\n }\n\n /**\n * Get API key for wallet (creates namespace ownership)\n */\n async getApiKey(params: {\n wallet: string;\n nonce: string;\n signature: string;\n namespace?: string;\n chain_type?: \"ETH\" | \"SOL\";\n }): Promise<{\n api_key: string;\n namespace: string;\n wallet: string;\n }> {\n const response = await this.httpClient.post(\"/v1/auth/api-key\", {\n wallet: params.wallet,\n nonce: params.nonce,\n signature: params.signature,\n namespace: params.namespace || \"default\",\n chain_type: params.chain_type || \"ETH\",\n });\n\n // Automatically set the API key\n this.setApiKey(response.api_key);\n\n return response;\n }\n}\n","import { HttpClient } from \"../core/http\";\nimport { SelectOptions, QueryResponse } from \"./types\";\n\nexport class QueryBuilder {\n private httpClient: HttpClient;\n private table: string;\n private options: SelectOptions = {};\n\n constructor(httpClient: HttpClient, table: string) {\n this.httpClient = httpClient;\n this.table = table;\n }\n\n select(...columns: string[]): this {\n this.options.select = columns;\n return this;\n }\n\n innerJoin(table: string, on: string): this {\n if (!this.options.joins) this.options.joins = [];\n this.options.joins.push({ kind: \"INNER\", table, on });\n return this;\n }\n\n leftJoin(table: string, on: string): this {\n if (!this.options.joins) this.options.joins = [];\n this.options.joins.push({ kind: \"LEFT\", table, on });\n return this;\n }\n\n rightJoin(table: string, on: string): this {\n if (!this.options.joins) this.options.joins = [];\n this.options.joins.push({ kind: \"RIGHT\", table, on });\n return this;\n }\n\n where(expr: string, args?: any[]): this {\n if (!this.options.where) this.options.where = [];\n this.options.where.push({ conj: \"AND\", expr, args });\n return this;\n }\n\n andWhere(expr: string, args?: any[]): this {\n return this.where(expr, args);\n }\n\n orWhere(expr: string, args?: any[]): this {\n if (!this.options.where) this.options.where = [];\n this.options.where.push({ conj: \"OR\", expr, args });\n return this;\n }\n\n groupBy(...columns: string[]): this {\n this.options.group_by = columns;\n return this;\n }\n\n orderBy(...columns: string[]): this {\n this.options.order_by = columns;\n return this;\n }\n\n limit(n: number): this {\n this.options.limit = n;\n return this;\n }\n\n offset(n: number): this {\n this.options.offset = n;\n return this;\n }\n\n async getMany<T = any>(ctx?: any): Promise<T[]> {\n const response = await this.httpClient.post<QueryResponse>(\n \"/v1/rqlite/select\",\n {\n table: this.table,\n ...this.options,\n }\n );\n return response.items || [];\n }\n\n async getOne<T = any>(ctx?: any): Promise<T | null> {\n const response = await this.httpClient.post<QueryResponse>(\n \"/v1/rqlite/select\",\n {\n table: this.table,\n ...this.options,\n one: true,\n limit: 1,\n }\n );\n const items = response.items || [];\n return items.length > 0 ? items[0] : null;\n }\n\n async count(): Promise<number> {\n const response = await this.httpClient.post<QueryResponse>(\n \"/v1/rqlite/select\",\n {\n table: this.table,\n select: [\"COUNT(*) AS count\"],\n where: this.options.where,\n one: true,\n }\n );\n const items = response.items || [];\n return items.length > 0 ? items[0].count : 0;\n }\n}\n","import { HttpClient } from \"../core/http\";\nimport { QueryBuilder } from \"./qb\";\nimport { QueryResponse, FindOptions } from \"./types\";\nimport { SDKError } from \"../errors\";\n\nexport class Repository<T extends Record<string, any>> {\n private httpClient: HttpClient;\n private tableName: string;\n private primaryKey: string;\n\n constructor(httpClient: HttpClient, tableName: string, primaryKey = \"id\") {\n this.httpClient = httpClient;\n this.tableName = tableName;\n this.primaryKey = primaryKey;\n }\n\n createQueryBuilder(): QueryBuilder {\n return new QueryBuilder(this.httpClient, this.tableName);\n }\n\n async find(\n criteria: Record<string, any> = {},\n options: FindOptions = {}\n ): Promise<T[]> {\n const response = await this.httpClient.post<QueryResponse>(\n \"/v1/rqlite/find\",\n {\n table: this.tableName,\n criteria,\n options,\n }\n );\n return response.items || [];\n }\n\n async findOne(criteria: Record<string, any>): Promise<T | null> {\n try {\n const response = await this.httpClient.post<T | null>(\n \"/v1/rqlite/find-one\",\n {\n table: this.tableName,\n criteria,\n }\n );\n return response;\n } catch (error) {\n // Return null if not found instead of throwing\n if (error instanceof SDKError && error.httpStatus === 404) {\n return null;\n }\n throw error;\n }\n }\n\n async save(entity: T): Promise<T> {\n const pkValue = entity[this.primaryKey];\n\n if (!pkValue) {\n // INSERT\n const response = await this.httpClient.post<{\n rows_affected: number;\n last_insert_id: number;\n }>(\"/v1/rqlite/exec\", {\n sql: this.buildInsertSql(entity),\n args: this.buildInsertArgs(entity),\n });\n\n if (response.last_insert_id) {\n (entity as any)[this.primaryKey] = response.last_insert_id;\n }\n return entity;\n } else {\n // UPDATE\n await this.httpClient.post(\"/v1/rqlite/exec\", {\n sql: this.buildUpdateSql(entity),\n args: this.buildUpdateArgs(entity),\n });\n return entity;\n }\n }\n\n async remove(entity: T | Record<string, any>): Promise<void> {\n const pkValue = entity[this.primaryKey];\n if (!pkValue) {\n throw new SDKError(\n `Primary key \"${this.primaryKey}\" is required for remove`,\n 400,\n \"MISSING_PK\"\n );\n }\n\n await this.httpClient.post(\"/v1/rqlite/exec\", {\n sql: `DELETE FROM ${this.tableName} WHERE ${this.primaryKey} = ?`,\n args: [pkValue],\n });\n }\n\n private buildInsertSql(entity: T): string {\n const columns = Object.keys(entity).filter((k) => entity[k] !== undefined);\n const placeholders = columns.map(() => \"?\").join(\", \");\n return `INSERT INTO ${this.tableName} (${columns.join(\n \", \"\n )}) VALUES (${placeholders})`;\n }\n\n private buildInsertArgs(entity: T): any[] {\n return Object.entries(entity)\n .filter(([, v]) => v !== undefined)\n .map(([, v]) => v);\n }\n\n private buildUpdateSql(entity: T): string {\n const columns = Object.keys(entity)\n .filter((k) => entity[k] !== undefined && k !== this.primaryKey)\n .map((k) => `${k} = ?`);\n return `UPDATE ${this.tableName} SET ${columns.join(\", \")} WHERE ${\n this.primaryKey\n } = ?`;\n }\n\n private buildUpdateArgs(entity: T): any[] {\n const args = Object.entries(entity)\n .filter(([k, v]) => v !== undefined && k !== this.primaryKey)\n .map(([, v]) => v);\n args.push(entity[this.primaryKey]);\n return args;\n }\n}\n","import { HttpClient } from \"../core/http\";\nimport { QueryBuilder } from \"./qb\";\nimport { Repository } from \"./repository\";\nimport {\n QueryResponse,\n TransactionOp,\n TransactionRequest,\n Entity,\n FindOptions,\n} from \"./types\";\n\nexport class DBClient {\n private httpClient: HttpClient;\n\n constructor(httpClient: HttpClient) {\n this.httpClient = httpClient;\n }\n\n /**\n * Execute a write/DDL SQL statement.\n */\n async exec(\n sql: string,\n args: any[] = []\n ): Promise<{ rows_affected: number; last_insert_id?: number }> {\n return this.httpClient.post(\"/v1/rqlite/exec\", { sql, args });\n }\n\n /**\n * Execute a SELECT query.\n */\n async query<T = any>(sql: string, args: any[] = []): Promise<T[]> {\n const response = await this.httpClient.post<QueryResponse>(\n \"/v1/rqlite/query\",\n { sql, args }\n );\n return response.items || [];\n }\n\n /**\n * Find rows with map-based criteria.\n */\n async find<T = any>(\n table: string,\n criteria: Record<string, any> = {},\n options: FindOptions = {}\n ): Promise<T[]> {\n const response = await this.httpClient.post<QueryResponse>(\n \"/v1/rqlite/find\",\n {\n table,\n criteria,\n options,\n }\n );\n return response.items || [];\n }\n\n /**\n * Find a single row with map-based criteria.\n */\n async findOne<T = any>(\n table: string,\n criteria: Record<string, any>\n ): Promise<T | null> {\n return this.httpClient.post<T | null>(\"/v1/rqlite/find-one\", {\n table,\n criteria,\n });\n }\n\n /**\n * Create a fluent QueryBuilder for complex SELECT queries.\n */\n createQueryBuilder(table: string): QueryBuilder {\n return new QueryBuilder(this.httpClient, table);\n }\n\n /**\n * Create a Repository for entity-based operations.\n */\n repository<T extends Record<string, any>>(\n tableName: string,\n primaryKey = \"id\"\n ): Repository<T> {\n return new Repository(this.httpClient, tableName, primaryKey);\n }\n\n /**\n * Execute multiple operations atomically.\n */\n async transaction(\n ops: TransactionOp[],\n returnResults = true\n ): Promise<any[]> {\n const response = await this.httpClient.post<{ results?: any[] }>(\n \"/v1/rqlite/transaction\",\n {\n ops,\n return_results: returnResults,\n }\n );\n return response.results || [];\n }\n\n /**\n * Create a table from DDL SQL.\n */\n async createTable(schema: string): Promise<void> {\n await this.httpClient.post(\"/v1/rqlite/create-table\", { schema });\n }\n\n /**\n * Drop a table.\n */\n async dropTable(table: string): Promise<void> {\n await this.httpClient.post(\"/v1/rqlite/drop-table\", { table });\n }\n\n /**\n * Get current database schema.\n */\n async getSchema(): Promise<any> {\n return this.httpClient.get(\"/v1/rqlite/schema\");\n }\n}\n","import WebSocket from \"isomorphic-ws\";\nimport { SDKError } from \"../errors\";\n\nexport interface WSClientConfig {\n wsURL: string;\n timeout?: number;\n authToken?: string;\n WebSocket?: typeof WebSocket;\n}\n\nexport type WSMessageHandler = (data: string) => void;\nexport type WSErrorHandler = (error: Error) => void;\nexport type WSCloseHandler = () => void;\nexport type WSOpenHandler = () => void;\n\n/**\n * Simple WebSocket client with minimal abstractions\n * No complex reconnection, no failover - keep it simple\n * Gateway failover is handled at the application layer\n */\nexport class WSClient {\n private wsURL: string;\n private timeout: number;\n private authToken?: string;\n private WebSocketClass: typeof WebSocket;\n\n private ws?: WebSocket;\n private messageHandlers: Set<WSMessageHandler> = new Set();\n private errorHandlers: Set<WSErrorHandler> = new Set();\n private closeHandlers: Set<WSCloseHandler> = new Set();\n private openHandlers: Set<WSOpenHandler> = new Set();\n private isClosed = false;\n\n constructor(config: WSClientConfig) {\n this.wsURL = config.wsURL;\n this.timeout = config.timeout ?? 30000;\n this.authToken = config.authToken;\n this.WebSocketClass = config.WebSocket ?? WebSocket;\n }\n\n /**\n * Get the current WebSocket URL\n */\n get url(): string {\n return this.wsURL;\n }\n\n /**\n * Connect to WebSocket server\n */\n connect(): Promise<void> {\n return new Promise((resolve, reject) => {\n try {\n const wsUrl = this.buildWSUrl();\n this.ws = new this.WebSocketClass(wsUrl);\n this.isClosed = false;\n\n const timeout = setTimeout(() => {\n this.ws?.close();\n reject(\n new SDKError(\"WebSocket connection timeout\", 408, \"WS_TIMEOUT\")\n );\n }, this.timeout);\n\n this.ws.addEventListener(\"open\", () => {\n clearTimeout(timeout);\n console.log(\"[WSClient] Connected to\", this.wsURL);\n this.openHandlers.forEach((handler) => handler());\n resolve();\n });\n\n this.ws.addEventListener(\"message\", (event: Event) => {\n const msgEvent = event as MessageEvent;\n this.messageHandlers.forEach((handler) => handler(msgEvent.data));\n });\n\n this.ws.addEventListener(\"error\", (event: Event) => {\n console.error(\"[WSClient] WebSocket error:\", event);\n clearTimeout(timeout);\n const error = new SDKError(\"WebSocket error\", 500, \"WS_ERROR\", event);\n this.errorHandlers.forEach((handler) => handler(error));\n reject(error);\n });\n\n this.ws.addEventListener(\"close\", () => {\n clearTimeout(timeout);\n console.log(\"[WSClient] Connection closed\");\n this.closeHandlers.forEach((handler) => handler());\n });\n } catch (error) {\n reject(error);\n }\n });\n }\n\n /**\n * Build WebSocket URL with auth token\n */\n private buildWSUrl(): string {\n let url = this.wsURL;\n\n if (this.authToken) {\n const separator = url.includes(\"?\") ? \"&\" : \"?\";\n const paramName = this.authToken.startsWith(\"ak_\") ? \"api_key\" : \"token\";\n url += `${separator}${paramName}=${encodeURIComponent(this.authToken)}`;\n }\n\n return url;\n }\n\n /**\n * Register message handler\n */\n onMessage(handler: WSMessageHandler): () => void {\n this.messageHandlers.add(handler);\n return () => this.messageHandlers.delete(handler);\n }\n\n /**\n * Unregister message handler\n */\n offMessage(handler: WSMessageHandler): void {\n this.messageHandlers.delete(handler);\n }\n\n /**\n * Register error handler\n */\n onError(handler: WSErrorHandler): () => void {\n this.errorHandlers.add(handler);\n return () => this.errorHandlers.delete(handler);\n }\n\n /**\n * Unregister error handler\n */\n offError(handler: WSErrorHandler): void {\n this.errorHandlers.delete(handler);\n }\n\n /**\n * Register close handler\n */\n onClose(handler: WSCloseHandler): () => void {\n this.closeHandlers.add(handler);\n return () => this.closeHandlers.delete(handler);\n }\n\n /**\n * Unregister close handler\n */\n offClose(handler: WSCloseHandler): void {\n this.closeHandlers.delete(handler);\n }\n\n /**\n * Register open handler\n */\n onOpen(handler: WSOpenHandler): () => void {\n this.openHandlers.add(handler);\n return () => this.openHandlers.delete(handler);\n }\n\n /**\n * Send data through WebSocket\n */\n send(data: string): void {\n if (this.ws?.readyState !== WebSocket.OPEN) {\n throw new SDKError(\"WebSocket is not connected\", 500, \"WS_NOT_CONNECTED\");\n }\n this.ws.send(data);\n }\n\n /**\n * Close WebSocket connection\n */\n close(): void {\n if (this.isClosed) {\n return;\n }\n this.isClosed = true;\n this.ws?.close();\n }\n\n /**\n * Check if WebSocket is connected\n */\n isConnected(): boolean {\n return !this.isClosed && this.ws?.readyState === WebSocket.OPEN;\n }\n\n /**\n * Update auth token\n */\n setAuthToken(token?: string): void {\n this.authToken = token;\n }\n}\n","import { HttpClient } from \"../core/http\";\nimport { WSClient, WSClientConfig } from \"../core/ws\";\nimport {\n PubSubMessage,\n RawEnvelope,\n MessageHandler,\n ErrorHandler,\n CloseHandler,\n SubscribeOptions,\n PresenceResponse,\n PresenceMember,\n PresenceOptions,\n} from \"./types\";\n\n// Cross-platform base64 encoding/decoding utilities\nfunction base64Encode(str: string): string {\n if (typeof Buffer !== \"undefined\") {\n return Buffer.from(str).toString(\"base64\");\n } else if (typeof btoa !== \"undefined\") {\n return btoa(\n encodeURIComponent(str).replace(/%([0-9A-F]{2})/g, (match, p1) =>\n String.fromCharCode(parseInt(p1, 16))\n )\n );\n }\n throw new Error(\"No base64 encoding method available\");\n}\n\nfunction base64EncodeBytes(bytes: Uint8Array): string {\n if (typeof Buffer !== \"undefined\") {\n return Buffer.from(bytes).toString(\"base64\");\n } else if (typeof btoa !== \"undefined\") {\n let binary = \"\";\n for (let i = 0; i < bytes.length; i++) {\n binary += String.fromCharCode(bytes[i]);\n }\n return btoa(binary);\n }\n throw new Error(\"No base64 encoding method available\");\n}\n\nfunction base64Decode(b64: string): string {\n if (typeof Buffer !== \"undefined\") {\n return Buffer.from(b64, \"base64\").toString(\"utf-8\");\n } else if (typeof atob !== \"undefined\") {\n const binary = atob(b64);\n const bytes = new Uint8Array(binary.length);\n for (let i = 0; i < binary.length; i++) {\n bytes[i] = binary.charCodeAt(i);\n }\n return new TextDecoder().decode(bytes);\n }\n throw new Error(\"No base64 decoding method available\");\n}\n\n/**\n * Simple PubSub client - one WebSocket connection per topic\n * Gateway failover is handled at the application layer\n */\nexport class PubSubClient {\n private httpClient: HttpClient;\n private wsConfig: Partial<WSClientConfig>;\n\n constructor(httpClient: HttpClient, wsConfig: Partial<WSClientConfig> = {}) {\n this.httpClient = httpClient;\n this.wsConfig = wsConfig;\n }\n\n /**\n * Publish a message to a topic via HTTP\n */\n async publish(topic: string, data: string | Uint8Array): Promise<void> {\n let dataBase64: string;\n if (typeof data === \"string\") {\n dataBase64 = base64Encode(data);\n } else {\n dataBase64 = base64EncodeBytes(data);\n }\n\n await this.httpClient.post(\n \"/v1/pubsub/publish\",\n {\n topic,\n data_base64: dataBase64,\n },\n {\n timeout: 30000,\n }\n );\n }\n\n /**\n * List active topics in the current namespace\n */\n async topics(): Promise<string[]> {\n const response = await this.httpClient.get<{ topics: string[] }>(\n \"/v1/pubsub/topics\"\n );\n return response.topics || [];\n }\n\n /**\n * Get current presence for a topic without subscribing\n */\n async getPresence(topic: string): Promise<PresenceResponse> {\n const response = await this.httpClient.get<PresenceResponse>(\n `/v1/pubsub/presence?topic=${encodeURIComponent(topic)}`\n );\n return response;\n }\n\n /**\n * Subscribe to a topic via WebSocket\n * Creates one WebSocket connection per topic\n */\n async subscribe(\n topic: string,\n options: SubscribeOptions = {}\n ): Promise<Subscription> {\n // Build WebSocket URL for this topic\n const wsUrl = new URL(this.wsConfig.wsURL || \"ws://127.0.0.1:6001\");\n wsUrl.pathname = \"/v1/pubsub/ws\";\n wsUrl.searchParams.set(\"topic\", topic);\n\n // Handle presence options\n let presence: PresenceOptions | undefined;\n if (options.presence?.enabled) {\n presence = options.presence;\n wsUrl.searchParams.set(\"presence\", \"true\");\n wsUrl.searchParams.set(\"member_id\", presence.memberId);\n if (presence.meta) {\n wsUrl.searchParams.set(\"member_meta\", JSON.stringify(presence.meta));\n }\n }\n\n const authToken = this.httpClient.getApiKey() ?? this.httpClient.getToken();\n\n // Create WebSocket client\n const wsClient = new WSClient({\n ...this.wsConfig,\n wsURL: wsUrl.toString(),\n authToken,\n });\n\n await wsClient.connect();\n\n // Create subscription wrapper\n const subscription = new Subscription(wsClient, topic, presence, () =>\n this.getPresence(topic)\n );\n\n if (options.onMessage) {\n subscription.onMessage(options.onMessage);\n }\n if (options.onError) {\n subscription.onError(options.onError);\n }\n if (options.onClose) {\n subscription.onClose(options.onClose);\n }\n\n return subscription;\n }\n}\n\n/**\n * Subscription represents an active WebSocket subscription to a topic\n */\nexport class Subscription {\n private wsClient: WSClient;\n private topic: string;\n private presenceOptions?: PresenceOptions;\n private messageHandlers: Set<MessageHandler> = new Set();\n private errorHandlers: Set<ErrorHandler> = new Set();\n private closeHandlers: Set<CloseHandler> = new Set();\n private isClosed = false;\n private wsMessageHandler: ((data: string) => void) | null = null;\n private wsErrorHandler: ((error: Error) => void) | null = null;\n private wsCloseHandler: (() => void) | null = null;\n private getPresenceFn: () => Promise<PresenceResponse>;\n\n constructor(\n wsClient: WSClient,\n topic: string,\n presenceOptions: PresenceOptions | undefined,\n getPresenceFn: () => Promise<PresenceResponse>\n ) {\n this.wsClient = wsClient;\n this.topic = topic;\n this.presenceOptions = presenceOptions;\n this.getPresenceFn = getPresenceFn;\n\n // Register message handler\n this.wsMessageHandler = (data) => {\n try {\n // Parse gateway JSON envelope: {data: base64String, timestamp, topic}\n const envelope: RawEnvelope = JSON.parse(data);\n\n // Validate envelope structure\n if (!envelope || typeof envelope !== \"object\") {\n throw new Error(\"Invalid envelope: not an object\");\n }\n\n // Handle presence events\n if (\n envelope.type === \"presence.join\" ||\n envelope.type === \"presence.leave\"\n ) {\n if (!envelope.member_id) {\n console.warn(\"[Subscription] Presence event missing member_id\");\n return;\n }\n\n const presenceMember: PresenceMember = {\n memberId: envelope.member_id,\n joinedAt: envelope.timestamp,\n meta: envelope.meta,\n };\n\n if (\n envelope.type === \"presence.join\" &&\n this.presenceOptions?.onJoin\n ) {\n this.presenceOptions.onJoin(presenceMember);\n } else if (\n envelope.type === \"presence.leave\" &&\n this.presenceOptions?.onLeave\n ) {\n this.presenceOptions.onLeave(presenceMember);\n }\n return; // Don't call regular onMessage for presence events\n }\n\n if (!envelope.data || typeof envelope.data !== \"string\") {\n throw new Error(\"Invalid envelope: missing or invalid data field\");\n }\n if (!envelope.topic || typeof envelope.topic !== \"string\") {\n throw new Error(\"Invalid envelope: missing or invalid topic field\");\n }\n if (typeof envelope.timestamp !== \"number\") {\n throw new Error(\n \"Invalid envelope: missing or invalid timestamp field\"\n );\n }\n\n // Decode base64 data\n const messageData = base64Decode(envelope.data);\n\n const message: PubSubMessage = {\n topic: envelope.topic,\n data: messageData,\n timestamp: envelope.timestamp,\n };\n\n console.log(\"[Subscription] Received message on topic:\", this.topic);\n this.messageHandlers.forEach((handler) => handler(message));\n } catch (error) {\n console.error(\"[Subscription] Error processing message:\", error);\n this.errorHandlers.forEach((handler) =>\n handler(error instanceof Error ? error : new Error(String(error)))\n );\n }\n };\n\n this.wsClient.onMessage(this.wsMessageHandler);\n\n // Register error handler\n this.wsErrorHandler = (error) => {\n this.errorHandlers.forEach((handler) => handler(error));\n };\n this.wsClient.onError(this.wsErrorHandler);\n\n // Register close handler\n this.wsCloseHandler = () => {\n this.closeHandlers.forEach((handler) => handler());\n };\n this.wsClient.onClose(this.wsCloseHandler);\n }\n\n /**\n * Get current presence (requires presence.enabled on subscribe)\n */\n async getPresence(): Promise<PresenceMember[]> {\n if (!this.presenceOptions?.enabled) {\n throw new Error(\"Presence is not enabled for this subscription\");\n }\n\n const response = await this.getPresenceFn();\n return response.members;\n }\n\n /**\n * Check if presence is enabled for this subscription\n */\n hasPresence(): boolean {\n return !!this.presenceOptions?.enabled;\n }\n\n /**\n * Register message handler\n */\n onMessage(handler: MessageHandler): () => void {\n this.messageHandlers.add(handler);\n return () => this.messageHandlers.delete(handler);\n }\n\n /**\n * Register error handler\n */\n onError(handler: ErrorHandler): () => void {\n this.errorHandlers.add(handler);\n return () => this.errorHandlers.delete(handler);\n }\n\n /**\n * Register close handler\n */\n onClose(handler: CloseHandler): () => void {\n this.closeHandlers.add(handler);\n return () => this.closeHandlers.delete(handler);\n }\n\n /**\n * Close subscription and underlying WebSocket\n */\n close(): void {\n if (this.isClosed) {\n return;\n }\n this.isClosed = true;\n\n // Remove handlers from WSClient\n if (this.wsMessageHandler) {\n this.wsClient.offMessage(this.wsMessageHandler);\n this.wsMessageHandler = null;\n }\n if (this.wsErrorHandler) {\n this.wsClient.offError(this.wsErrorHandler);\n this.wsErrorHandler = null;\n }\n if (this.wsCloseHandler) {\n this.wsClient.offClose(this.wsCloseHandler);\n this.wsCloseHandler = null;\n }\n\n // Clear all local handlers\n this.messageHandlers.clear();\n this.errorHandlers.clear();\n this.closeHandlers.clear();\n\n // Close WebSocket connection\n this.wsClient.close();\n }\n\n /**\n * Check if subscription is active\n */\n isConnected(): boolean {\n return !this.isClosed && this.wsClient.isConnected();\n }\n}\n","import { HttpClient } from \"../core/http\";\n\nexport interface PeerInfo {\n id: string;\n addresses: string[];\n lastSeen?: string;\n}\n\nexport interface NetworkStatus {\n node_id: string;\n connected: boolean;\n peer_count: number;\n database_size: number;\n uptime: number;\n}\n\nexport interface ProxyRequest {\n url: string;\n method: string;\n headers?: Record<string, string>;\n body?: string;\n}\n\nexport interface ProxyResponse {\n status_code: number;\n headers: Record<string, string>;\n body: string;\n error?: string;\n}\n\nexport class NetworkClient {\n private httpClient: HttpClient;\n\n constructor(httpClient: HttpClient) {\n this.httpClient = httpClient;\n }\n\n /**\n * Check gateway health.\n */\n async health(): Promise<boolean> {\n try {\n await this.httpClient.get(\"/v1/health\");\n return true;\n } catch {\n return false;\n }\n }\n\n /**\n * Get network status.\n */\n async status(): Promise<NetworkStatus> {\n const response = await this.httpClient.get<NetworkStatus>(\n \"/v1/network/status\"\n );\n return response;\n }\n\n /**\n * Get connected peers.\n */\n async peers(): Promise<PeerInfo[]> {\n const response = await this.httpClient.get<{ peers: PeerInfo[] }>(\n \"/v1/network/peers\"\n );\n return response.peers || [];\n }\n\n /**\n * Connect to a peer.\n */\n async connect(peerAddr: string): Promise<void> {\n await this.httpClient.post(\"/v1/network/connect\", { peer_addr: peerAddr });\n }\n\n /**\n * Disconnect from a peer.\n */\n async disconnect(peerId: string): Promise<void> {\n await this.httpClient.post(\"/v1/network/disconnect\", { peer_id: peerId });\n }\n\n /**\n * Proxy an HTTP request through the Anyone network.\n * Requires authentication (API key or JWT).\n *\n * @param request - The proxy request configuration\n * @returns The proxied response\n * @throws {SDKError} If the Anyone proxy is not available or the request fails\n *\n * @example\n * ```ts\n * const response = await client.network.proxyAnon({\n * url: 'https://api.example.com/data',\n * method: 'GET',\n * headers: {\n * 'Accept': 'application/json'\n * }\n * });\n *\n * console.log(response.status_code); // 200\n * console.log(response.body); // Response data\n * ```\n */\n async proxyAnon(request: ProxyRequest): Promise<ProxyResponse> {\n const response = await this.httpClient.post<ProxyResponse>(\n \"/v1/proxy/anon\",\n request\n );\n\n // Check if the response contains an error\n if (response.error) {\n throw new Error(`Proxy request failed: ${response.error}`);\n }\n\n return response;\n }\n}\n","import { HttpClient } from \"../core/http\";\nimport { SDKError } from \"../errors\";\n\nexport interface CacheGetRequest {\n dmap: string;\n key: string;\n}\n\nexport interface CacheGetResponse {\n key: string;\n value: any;\n dmap: string;\n}\n\nexport interface CachePutRequest {\n dmap: string;\n key: string;\n value: any;\n ttl?: string; // Duration string like \"1h\", \"30m\"\n}\n\nexport interface CachePutResponse {\n status: string;\n key: string;\n dmap: string;\n}\n\nexport interface CacheDeleteRequest {\n dmap: string;\n key: string;\n}\n\nexport interface CacheDeleteResponse {\n status: string;\n key: string;\n dmap: string;\n}\n\nexport interface CacheMultiGetRequest {\n dmap: string;\n keys: string[];\n}\n\nexport interface CacheMultiGetResponse {\n results: Array<{\n key: string;\n value: any;\n }>;\n dmap: string;\n}\n\nexport interface CacheScanRequest {\n dmap: string;\n match?: string; // Optional regex pattern\n}\n\nexport interface CacheScanResponse {\n keys: string[];\n count: number;\n dmap: string;\n}\n\nexport interface CacheHealthResponse {\n status: string;\n service: string;\n}\n\nexport class CacheClient {\n private httpClient: HttpClient;\n\n constructor(httpClient: HttpClient) {\n this.httpClient = httpClient;\n }\n\n /**\n * Check cache service health\n */\n async health(): Promise<CacheHealthResponse> {\n return this.httpClient.get(\"/v1/cache/health\");\n }\n\n /**\n * Get a value from cache\n * Returns null if the key is not found (cache miss/expired), which is normal behavior\n */\n async get(dmap: string, key: string): Promise<CacheGetResponse | null> {\n try {\n return await this.httpClient.post<CacheGetResponse>(\"/v1/cache/get\", {\n dmap,\n key,\n });\n } catch (error) {\n // Cache misses (404 or \"key not found\" messages) are normal behavior - return null instead of throwing\n if (\n error instanceof SDKError &&\n (error.httpStatus === 404 ||\n (error.httpStatus === 500 &&\n error.message?.toLowerCase().includes(\"key not found\")))\n ) {\n return null;\n }\n // Re-throw other errors (network issues, server errors, etc.)\n throw error;\n }\n }\n\n /**\n * Put a value into cache\n */\n async put(\n dmap: string,\n key: string,\n value: any,\n ttl?: string\n ): Promise<CachePutResponse> {\n return this.httpClient.post<CachePutResponse>(\"/v1/cache/put\", {\n dmap,\n key,\n value,\n ttl,\n });\n }\n\n /**\n * Delete a value from cache\n */\n async delete(dmap: string, key: string): Promise<CacheDeleteResponse> {\n return this.httpClient.post<CacheDeleteResponse>(\"/v1/cache/delete\", {\n dmap,\n key,\n });\n }\n\n /**\n * Get multiple values from cache in a single request\n * Returns a map of key -> value (or null if not found)\n * Gracefully handles 404 errors (endpoint not implemented) by returning empty results\n */\n async multiGet(\n dmap: string,\n keys: string[]\n ): Promise<Map<string, any | null>> {\n try {\n if (keys.length === 0) {\n return new Map();\n }\n\n const response = await this.httpClient.post<CacheMultiGetResponse>(\n \"/v1/cache/mget\",\n {\n dmap,\n keys,\n }\n );\n\n // Convert array to Map\n const resultMap = new Map<string, any | null>();\n\n // First, mark all keys as null (cache miss)\n keys.forEach((key) => {\n resultMap.set(key, null);\n });\n\n // Then, update with found values\n if (response.results) {\n response.results.forEach(({ key, value }) => {\n resultMap.set(key, value);\n });\n }\n\n return resultMap;\n } catch (error) {\n // Handle 404 errors silently (endpoint not implemented on backend)\n // This is expected behavior when the backend doesn't support multiGet yet\n if (error instanceof SDKError && error.httpStatus === 404) {\n // Return map with all nulls silently - caller can fall back to individual gets\n const resultMap = new Map<string, any | null>();\n keys.forEach((key) => {\n resultMap.set(key, null);\n });\n return resultMap;\n }\n\n // Log and return empty results for other errors\n const resultMap = new Map<string, any | null>();\n keys.forEach((key) => {\n resultMap.set(key, null);\n });\n console.error(`[CacheClient] Error in multiGet for ${dmap}:`, error);\n return resultMap;\n }\n }\n\n /**\n * Scan keys in a distributed map, optionally matching a regex pattern\n */\n async scan(dmap: string, match?: string): Promise<CacheScanResponse> {\n return this.httpClient.post<CacheScanResponse>(\"/v1/cache/scan\", {\n dmap,\n match,\n });\n }\n}\n","import { HttpClient } from \"../core/http\";\n\nexport interface StorageUploadResponse {\n cid: string;\n name: string;\n size: number;\n}\n\nexport interface StoragePinRequest {\n cid: string;\n name?: string;\n}\n\nexport interface StoragePinResponse {\n cid: string;\n name: string;\n}\n\nexport interface StorageStatus {\n cid: string;\n name: string;\n status: string; // \"pinned\", \"pinning\", \"queued\", \"unpinned\", \"error\"\n replication_min: number;\n replication_max: number;\n replication_factor: number;\n peers: string[];\n error?: string;\n}\n\nexport class StorageClient {\n private httpClient: HttpClient;\n\n constructor(httpClient: HttpClient) {\n this.httpClient = httpClient;\n }\n\n /**\n * Upload content to IPFS and optionally pin it.\n * Supports both File objects (browser) and Buffer/ReadableStream (Node.js).\n *\n * @param file - File to upload (File, Blob, or Buffer)\n * @param name - Optional filename\n * @param options - Optional upload options\n * @param options.pin - Whether to pin the content (default: true). Pinning happens asynchronously on the backend.\n * @returns Upload result with CID\n *\n * @example\n * ```ts\n * // Browser\n * const fileInput = document.querySelector('input[type=\"file\"]');\n * const file = fileInput.files[0];\n * const result = await client.storage.upload(file, file.name);\n * console.log(result.cid);\n *\n * // Node.js\n * const fs = require('fs');\n * const fileBuffer = fs.readFileSync('image.jpg');\n * const result = await client.storage.upload(fileBuffer, 'image.jpg', { pin: true });\n * ```\n */\n async upload(\n file: File | Blob | ArrayBuffer | Uint8Array | ReadableStream<Uint8Array>,\n name?: string,\n options?: {\n pin?: boolean;\n }\n ): Promise<StorageUploadResponse> {\n // Create FormData for multipart upload\n const formData = new FormData();\n\n // Handle different input types\n if (file instanceof File) {\n formData.append(\"file\", file);\n } else if (file instanceof Blob) {\n formData.append(\"file\", file, name);\n } else if (file instanceof ArrayBuffer) {\n const blob = new Blob([file]);\n formData.append(\"file\", blob, name);\n } else if (file instanceof Uint8Array) {\n // Convert Uint8Array to ArrayBuffer for Blob constructor\n const buffer = file.buffer.slice(\n file.byteOffset,\n file.byteOffset + file.byteLength\n ) as ArrayBuffer;\n const blob = new Blob([buffer], { type: \"application/octet-stream\" });\n formData.append(\"file\", blob, name);\n } else if (file instanceof ReadableStream) {\n // For ReadableStream, we need to read it into a blob first\n // This is a limitation - in practice, pass File/Blob/Buffer\n const chunks: ArrayBuffer[] = [];\n const reader = file.getReader();\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n const buffer = value.buffer.slice(\n value.byteOffset,\n value.byteOffset + value.byteLength\n ) as ArrayBuffer;\n chunks.push(buffer);\n }\n const blob = new Blob(chunks);\n formData.append(\"file\", blob, name);\n } else {\n throw new Error(\n \"Unsupported file type. Use File, Blob, ArrayBuffer, Uint8Array, or ReadableStream.\"\n );\n }\n\n // Add pin flag (default: true)\n const shouldPin = options?.pin !== false; // Default to true\n formData.append(\"pin\", shouldPin ? \"true\" : \"false\");\n\n return this.httpClient.uploadFile<StorageUploadResponse>(\n \"/v1/storage/upload\",\n formData,\n { timeout: 300000 } // 5 minute timeout for large files\n );\n }\n\n /**\n * Pin an existing CID\n *\n * @param cid - Content ID to pin\n * @param name - Optional name for the pin\n * @returns Pin result\n */\n async pin(cid: string, name?: string): Promise<StoragePinResponse> {\n return this.httpClient.post<StoragePinResponse>(\"/v1/storage/pin\", {\n cid,\n name,\n });\n }\n\n /**\n * Get the pin status for a CID\n *\n * @param cid - Content ID to check\n * @returns Pin status information\n */\n async status(cid: string): Promise<StorageStatus> {\n return this.httpClient.get<StorageStatus>(`/v1/storage/status/${cid}`);\n }\n\n /**\n * Retrieve content from IPFS by CID\n *\n * @param cid - Content ID to retrieve\n * @returns ReadableStream of the content\n *\n * @example\n * ```ts\n * const stream = await client.storage.get(cid);\n * const reader = stream.getReader();\n * while (true) {\n * const { done, value } = await reader.read();\n * if (done) break;\n * // Process chunk\n * }\n * ```\n */\n async get(cid: string): Promise<ReadableStream<Uint8Array>> {\n // Retry logic for content retrieval - content may not be immediately available\n // after upload due to eventual consistency in IPFS Cluster\n // IPFS Cluster pins can take 2-3+ seconds to complete across all nodes\n const maxAttempts = 8;\n let lastError: Error | null = null;\n\n for (let attempt = 1; attempt <= maxAttempts; attempt++) {\n try {\n const response = await this.httpClient.getBinary(\n `/v1/storage/get/${cid}`\n );\n\n if (!response.body) {\n throw new Error(\"Response body is null\");\n }\n\n return response.body;\n } catch (error: any) {\n lastError = error;\n\n // Check if this is a 404 error (content not found)\n const isNotFound =\n error?.httpStatus === 404 ||\n error?.message?.includes(\"not found\") ||\n error?.message?.includes(\"404\");\n\n // If it's not a 404 error, or this is the last attempt, give up\n if (!isNotFound || attempt === maxAttempts) {\n throw error;\n }\n\n // Wait before retrying (exponential backoff: 400ms, 800ms, 1200ms, etc.)\n // This gives up to ~12 seconds total wait time, covering typical pin completion\n const backoffMs = attempt * 2500;\n await new Promise((resolve) => setTimeout(resolve, backoffMs));\n }\n }\n\n // This should never be reached, but TypeScript needs it\n throw lastError || new Error(\"Failed to retrieve content\");\n }\n\n /**\n * Retrieve content from IPFS by CID and return the full Response object\n * Useful when you need access to response headers (e.g., content-length)\n *\n * @param cid - Content ID to retrieve\n * @returns Response object with body stream and headers\n *\n * @example\n * ```ts\n * const response = await client.storage.getBinary(cid);\n * const contentLength = response.headers.get('content-length');\n * const reader = response.body.getReader();\n * // ... read stream\n * ```\n */\n async getBinary(cid: string): Promise<Response> {\n // Retry logic for content retrieval - content may not be immediately available\n // after upload due to eventual consistency in IPFS Cluster\n // IPFS Cluster pins can take 2-3+ seconds to complete across all nodes\n const maxAttempts = 8;\n let lastError: Error | null = null;\n\n for (let attempt = 1; attempt <= maxAttempts; attempt++) {\n try {\n const response = await this.httpClient.getBinary(\n `/v1/storage/get/${cid}`\n );\n\n if (!response) {\n throw new Error(\"Response is null\");\n }\n\n return response;\n } catch (error: any) {\n lastError = error;\n\n // Check if this is a 404 error (content not found)\n const isNotFound =\n error?.httpStatus === 404 ||\n error?.message?.includes(\"not found\") ||\n error?.message?.includes(\"404\");\n\n // If it's not a 404 error, or this is the last attempt, give up\n if (!isNotFound || attempt === maxAttempts) {\n throw error;\n }\n\n // Wait before retrying (exponential backoff: 400ms, 800ms, 1200ms, etc.)\n // This gives up to ~12 seconds total wait time, covering typical pin completion\n const backoffMs = attempt * 2500;\n await new Promise((resolve) => setTimeout(resolve, backoffMs));\n }\n }\n\n // This should never be reached, but TypeScript needs it\n throw lastError || new Error(\"Failed to retrieve content\");\n }\n\n /**\n * Unpin a CID\n *\n * @param cid - Content ID to unpin\n */\n async unpin(cid: string): Promise<void> {\n await this.httpClient.delete(`/v1/storage/unpin/${cid}`);\n }\n}\n","/**\n * Functions Client\n * Client for calling serverless functions on the Orama Network\n */\n\nimport { HttpClient } from \"../core/http\";\nimport { SDKError } from \"../errors\";\n\nexport interface FunctionsClientConfig {\n /**\n * Base URL for the functions gateway\n * Defaults to using the same baseURL as the HTTP client\n */\n gatewayURL?: string;\n \n /**\n * Namespace for the functions\n */\n namespace: string;\n}\n\nexport class FunctionsClient {\n private httpClient: HttpClient;\n private gatewayURL?: string;\n private namespace: string;\n\n constructor(httpClient: HttpClient, config?: FunctionsClientConfig) {\n this.httpClient = httpClient;\n this.gatewayURL = config?.gatewayURL;\n this.namespace = config?.namespace ?? \"default\";\n }\n\n /**\n * Invoke a serverless function by name\n * \n * @param functionName - Name of the function to invoke\n * @param input - Input payload for the function\n * @returns The function response\n */\n async invoke<TInput = any, TOutput = any>(\n functionName: string,\n input: TInput\n ): Promise<TOutput> {\n const url = this.gatewayURL\n ? `${this.gatewayURL}/v1/invoke/${this.namespace}/${functionName}`\n : `/v1/invoke/${this.namespace}/${functionName}`;\n\n try {\n const response = await this.httpClient.post<TOutput>(url, input);\n return response;\n } catch (error) {\n if (error instanceof SDKError) {\n throw error;\n }\n throw new SDKError(\n `Function ${functionName} failed`,\n 500,\n error instanceof Error ? error.message : String(error)\n );\n }\n }\n}\n","import { HttpClient, HttpClientConfig } from \"./core/http\";\nimport { AuthClient } from \"./auth/client\";\nimport { DBClient } from \"./db/client\";\nimport { PubSubClient } from \"./pubsub/client\";\nimport { NetworkClient } from \"./network/client\";\nimport { CacheClient } from \"./cache/client\";\nimport { StorageClient } from \"./storage/client\";\nimport { FunctionsClient, FunctionsClientConfig } from \"./functions/client\";\nimport { WSClientConfig } from \"./core/ws\";\nimport {\n StorageAdapter,\n MemoryStorage,\n LocalStorageAdapter,\n} from \"./auth/types\";\n\nexport interface ClientConfig extends Omit<HttpClientConfig, \"fetch\"> {\n apiKey?: string;\n jwt?: string;\n storage?: StorageAdapter;\n wsConfig?: Partial<Omit<WSClientConfig, \"wsURL\">>;\n functionsConfig?: FunctionsClientConfig;\n fetch?: typeof fetch;\n}\n\nexport interface Client {\n auth: AuthClient;\n db: DBClient;\n pubsub: PubSubClient;\n network: NetworkClient;\n cache: CacheClient;\n storage: StorageClient;\n functions: FunctionsClient;\n}\n\nexport function createClient(config: ClientConfig): Client {\n const httpClient = new HttpClient({\n baseURL: config.baseURL,\n timeout: config.timeout,\n maxRetries: config.maxRetries,\n retryDelayMs: config.retryDelayMs,\n fetch: config.fetch,\n });\n\n const auth = new AuthClient({\n httpClient,\n storage: config.storage,\n apiKey: config.apiKey,\n jwt: config.jwt,\n });\n\n // Derive WebSocket URL from baseURL\n const wsURL = config.baseURL.replace(/^http/, \"ws\").replace(/\\/$/, \"\");\n\n const db = new DBClient(httpClient);\n const pubsub = new PubSubClient(httpClient, {\n ...config.wsConfig,\n wsURL,\n });\n const network = new NetworkClient(httpClient);\n const cache = new CacheClient(httpClient);\n const storage = new StorageClient(httpClient);\n const functions = new FunctionsClient(httpClient, config.functionsConfig);\n\n return {\n auth,\n db,\n pubsub,\n network,\n cache,\n storage,\n functions,\n };\n}\n\nexport { HttpClient } from \"./core/http\";\nexport { WSClient } from \"./core/ws\";\nexport { AuthClient } from \"./auth/client\";\nexport { DBClient } from \"./db/client\";\nexport { QueryBuilder } from \"./db/qb\";\nexport { Repository } from \"./db/repository\";\nexport { PubSubClient, Subscription } from \"./pubsub/client\";\nexport { NetworkClient } from \"./network/client\";\nexport { CacheClient } from \"./cache/client\";\nexport { StorageClient } from \"./storage/client\";\nexport { FunctionsClient } from \"./functions/client\";\nexport { SDKError } from \"./errors\";\nexport { MemoryStorage, LocalStorageAdapter } from \"./auth/types\";\nexport type { StorageAdapter, AuthConfig, WhoAmI } from \"./auth/types\";\nexport type * from \"./db/types\";\nexport type {\n MessageHandler,\n ErrorHandler,\n CloseHandler,\n PresenceMember,\n PresenceResponse,\n PresenceOptions,\n SubscribeOptions,\n} from \"./pubsub/types\";\nexport { type PubSubMessage } from \"./pubsub/types\";\nexport type {\n PeerInfo,\n NetworkStatus,\n ProxyRequest,\n ProxyResponse,\n} from \"./network/client\";\nexport type {\n CacheGetRequest,\n CacheGetResponse,\n CachePutRequest,\n CachePutResponse,\n CacheDeleteRequest,\n CacheDeleteResponse,\n CacheMultiGetRequest,\n CacheMultiGetResponse,\n CacheScanRequest,\n CacheScanResponse,\n CacheHealthResponse,\n} from \"./cache/client\";\nexport type {\n StorageUploadResponse,\n StoragePinRequest,\n StoragePinResponse,\n StorageStatus,\n} from \"./storage/client\";\nexport type { FunctionsClientConfig } from \"./functions/client\";\nexport type * from \"./functions/types\";\n"],"mappings":"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","names":["resultMap"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@debros/network-ts-sdk",
3
- "version": "0.3.4",
3
+ "version": "0.4.2",
4
4
  "description": "TypeScript SDK for DeBros Network Gateway",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
package/src/core/http.ts CHANGED
@@ -42,7 +42,7 @@ export class HttpClient {
42
42
 
43
43
  constructor(config: HttpClientConfig) {
44
44
  this.baseURL = config.baseURL.replace(/\/$/, "");
45
- this.timeout = config.timeout ?? 60000; // Increased from 30s to 60s for pub/sub operations
45
+ this.timeout = config.timeout ?? 60000;
46
46
  this.maxRetries = config.maxRetries ?? 3;
47
47
  this.retryDelayMs = config.retryDelayMs ?? 1000;
48
48
  // Use provided fetch or create one with proper TLS configuration for staging certificates
@@ -121,6 +121,13 @@ export class HttpClient {
121
121
  return this.apiKey;
122
122
  }
123
123
 
124
+ /**
125
+ * Get the base URL
126
+ */
127
+ getBaseURL(): string {
128
+ return this.baseURL;
129
+ }
130
+
124
131
  async request<T = any>(
125
132
  method: "GET" | "POST" | "PUT" | "DELETE",
126
133
  path: string,
@@ -276,22 +283,31 @@ export class HttpClient {
276
283
  throw SDKError.fromResponse(response.status, body);
277
284
  }
278
285
 
286
+ // Request succeeded - return response
279
287
  const contentType = response.headers.get("content-type");
280
288
  if (contentType?.includes("application/json")) {
281
289
  return response.json();
282
290
  }
283
291
  return response.text();
284
292
  } catch (error) {
285
- if (
293
+ const isRetryableError =
286
294
  error instanceof SDKError &&
287
- attempt < this.maxRetries &&
288
- [408, 429, 500, 502, 503, 504].includes(error.httpStatus)
289
- ) {
295
+ [408, 429, 500, 502, 503, 504].includes(error.httpStatus);
296
+
297
+ // Retry on same gateway for retryable HTTP errors
298
+ if (isRetryableError && attempt < this.maxRetries) {
299
+ if (typeof console !== "undefined") {
300
+ console.warn(
301
+ `[HttpClient] Retrying request (attempt ${attempt + 1}/${this.maxRetries})`
302
+ );
303
+ }
290
304
  await new Promise((resolve) =>
291
305
  setTimeout(resolve, this.retryDelayMs * (attempt + 1))
292
306
  );
293
307
  return this.requestWithRetry(url, options, attempt + 1, startTime);
294
308
  }
309
+
310
+ // All retries exhausted - throw error for app to handle
295
311
  throw error;
296
312
  }
297
313
  }