UNPKG

@chittyos/core

Version:

ChittyOS Core - Essential package with ID, auth, verification, beacon tracking, and brand components for all ChittyOS applications

1 lines 32.4 kB
{"version":3,"sources":["../../src/registry/index.ts","../../src/beacon/index.ts"],"sourcesContent":["/**\n * ChittyOS Registry - Service discovery and connection management\n * Manages service endpoints, connections, and health status\n */\n\nimport { EventEmitter } from 'eventemitter3'\nimport { nanoid } from 'nanoid'\nimport { sendBeacon } from '../beacon'\n\nexport interface ServiceEndpoint {\n id: string\n name: string\n type: 'api' | 'websocket' | 'grpc' | 'database' | 'storage' | 'custom'\n url: string\n protocol: string\n host: string\n port?: number\n path?: string\n metadata?: Record<string, any>\n}\n\nexport interface ServiceConnection {\n id: string\n serviceId: string\n chittyId: string\n status: 'connecting' | 'connected' | 'disconnected' | 'error'\n establishedAt?: string\n lastPingAt?: string\n latency?: number\n error?: string\n metadata?: Record<string, any>\n}\n\nexport interface ServiceHealth {\n serviceId: string\n status: 'healthy' | 'degraded' | 'unhealthy' | 'unknown'\n lastCheckAt: string\n uptime?: number\n responseTime?: number\n errorRate?: number\n checks: {\n name: string\n status: 'pass' | 'fail' | 'warn'\n message?: string\n }[]\n}\n\nexport interface RegistryConfig {\n discoveryEndpoint?: string\n healthCheckInterval?: number\n connectionTimeout?: number\n maxRetries?: number\n enableAutoDiscovery?: boolean\n}\n\nexport type RegistryEvents = {\n 'service:registered': (service: ServiceEndpoint) => void\n 'service:unregistered': (serviceId: string) => void\n 'service:healthy': (serviceId: string) => void\n 'service:unhealthy': (serviceId: string, error: string) => void\n 'connection:established': (connection: ServiceConnection) => void\n 'connection:lost': (connection: ServiceConnection) => void\n 'discovery:update': (services: ServiceEndpoint[]) => void\n}\n\nclass ServiceRegistry extends EventEmitter<RegistryEvents> {\n private config: Required<RegistryConfig>\n private services = new Map<string, ServiceEndpoint>()\n private connections = new Map<string, ServiceConnection>()\n private healthStatus = new Map<string, ServiceHealth>()\n private healthCheckTimers = new Map<string, NodeJS.Timeout>()\n private discoveryTimer: NodeJS.Timeout | null = null\n\n constructor(config: RegistryConfig = {}) {\n super()\n\n this.config = {\n discoveryEndpoint: config.discoveryEndpoint || process.env.CHITTY_REGISTRY_ENDPOINT || 'https://registry.chitty.cc',\n healthCheckInterval: config.healthCheckInterval || 30000,\n connectionTimeout: config.connectionTimeout || 10000,\n maxRetries: config.maxRetries || 3,\n enableAutoDiscovery: config.enableAutoDiscovery ?? true\n }\n\n if (this.config.enableAutoDiscovery) {\n this.startAutoDiscovery()\n }\n }\n\n /**\n * Register a service endpoint\n */\n registerService(service: Omit<ServiceEndpoint, 'id'>): ServiceEndpoint {\n const registeredService: ServiceEndpoint = {\n ...service,\n id: service.name + '_' + nanoid(8)\n }\n\n // Parse URL for components\n try {\n const url = new URL(service.url)\n registeredService.protocol = url.protocol.replace(':', '')\n registeredService.host = url.hostname\n registeredService.port = url.port ? parseInt(url.port) : undefined\n registeredService.path = url.pathname !== '/' ? url.pathname : undefined\n } catch (error) {\n console.warn('[Registry] Invalid URL for service:', service.name)\n }\n\n this.services.set(registeredService.id, registeredService)\n this.emit('service:registered', registeredService)\n\n // Start health checks\n this.startHealthCheck(registeredService.id)\n\n // Track registration\n sendBeacon('registry_service_registered', {\n serviceId: registeredService.id,\n name: registeredService.name,\n type: registeredService.type\n })\n\n return registeredService\n }\n\n /**\n * Unregister a service\n */\n unregisterService(serviceId: string): boolean {\n const service = this.services.get(serviceId)\n if (!service) {\n return false\n }\n\n // Stop health checks\n this.stopHealthCheck(serviceId)\n\n // Close connections\n for (const [connId, conn] of this.connections) {\n if (conn.serviceId === serviceId) {\n this.disconnectConnection(connId)\n }\n }\n\n this.services.delete(serviceId)\n this.healthStatus.delete(serviceId)\n this.emit('service:unregistered', serviceId)\n\n return true\n }\n\n /**\n * Get service by ID or name\n */\n getService(idOrName: string): ServiceEndpoint | undefined {\n // Try by ID first\n if (this.services.has(idOrName)) {\n return this.services.get(idOrName)\n }\n\n // Try by name\n for (const service of this.services.values()) {\n if (service.name === idOrName) {\n return service\n }\n }\n\n return undefined\n }\n\n /**\n * Get all services of a specific type\n */\n getServicesByType(type: ServiceEndpoint['type']): ServiceEndpoint[] {\n return Array.from(this.services.values()).filter(s => s.type === type)\n }\n\n /**\n * Establish connection to a service\n */\n async connectToService(\n serviceId: string,\n chittyId: string,\n metadata?: Record<string, any>\n ): Promise<ServiceConnection> {\n const service = this.services.get(serviceId)\n if (!service) {\n throw new Error(`Service ${serviceId} not found`)\n }\n\n const connection: ServiceConnection = {\n id: `conn_${nanoid()}`,\n serviceId,\n chittyId,\n status: 'connecting',\n metadata\n }\n\n this.connections.set(connection.id, connection)\n\n try {\n // Test connection based on service type\n const startTime = Date.now()\n await this.testConnection(service)\n const latency = Date.now() - startTime\n\n // Update connection status\n connection.status = 'connected'\n connection.establishedAt = new Date().toISOString()\n connection.latency = latency\n this.connections.set(connection.id, connection)\n\n this.emit('connection:established', connection)\n\n // Track connection\n sendBeacon('registry_connection_established', {\n serviceId,\n chittyId,\n latency\n })\n\n return connection\n } catch (error) {\n connection.status = 'error'\n connection.error = (error as Error).message\n this.connections.set(connection.id, connection)\n throw error\n }\n }\n\n /**\n * Disconnect a connection\n */\n disconnectConnection(connectionId: string): boolean {\n const connection = this.connections.get(connectionId)\n if (!connection) {\n return false\n }\n\n connection.status = 'disconnected'\n this.emit('connection:lost', connection)\n this.connections.delete(connectionId)\n\n return true\n }\n\n /**\n * Get connection status\n */\n getConnection(connectionId: string): ServiceConnection | undefined {\n return this.connections.get(connectionId)\n }\n\n /**\n * Get all connections for a ChittyID\n */\n getConnectionsByChittyId(chittyId: string): ServiceConnection[] {\n return Array.from(this.connections.values()).filter(c => c.chittyId === chittyId)\n }\n\n /**\n * Test connection to a service\n */\n private async testConnection(service: ServiceEndpoint): Promise<void> {\n const controller = new AbortController()\n const timeout = setTimeout(() => controller.abort(), this.config.connectionTimeout)\n\n try {\n const response = await fetch(service.url, {\n method: 'HEAD',\n signal: controller.signal\n })\n\n if (!response.ok && response.status !== 405) {\n throw new Error(`Service returned ${response.status}`)\n }\n } catch (error: any) {\n if (error.name === 'AbortError') {\n throw new Error('Connection timeout')\n }\n throw error\n } finally {\n clearTimeout(timeout)\n }\n }\n\n /**\n * Perform health check on a service\n */\n private async performHealthCheck(serviceId: string): Promise<void> {\n const service = this.services.get(serviceId)\n if (!service) {\n return\n }\n\n const health: ServiceHealth = {\n serviceId,\n status: 'unknown',\n lastCheckAt: new Date().toISOString(),\n checks: []\n }\n\n try {\n // Basic connectivity check\n const startTime = Date.now()\n await this.testConnection(service)\n const responseTime = Date.now() - startTime\n\n health.responseTime = responseTime\n health.status = responseTime < 1000 ? 'healthy' : 'degraded'\n health.checks.push({\n name: 'connectivity',\n status: 'pass',\n message: `Response time: ${responseTime}ms`\n })\n\n // Try health endpoint if available\n try {\n const healthUrl = new URL(service.url)\n healthUrl.pathname = '/health'\n const healthResponse = await fetch(healthUrl.toString(), {\n signal: AbortSignal.timeout(5000)\n })\n\n if (healthResponse.ok) {\n const healthData = await healthResponse.json() as any\n if (healthData.status) {\n health.status = healthData.status\n }\n if (healthData.checks) {\n health.checks.push(...healthData.checks)\n }\n }\n } catch (error) {\n // Health endpoint not available, that's ok\n }\n\n this.healthStatus.set(serviceId, health)\n\n if (health.status === 'healthy') {\n this.emit('service:healthy', serviceId)\n } else if (health.status === 'unhealthy') {\n this.emit('service:unhealthy', serviceId, 'Health check failed')\n }\n } catch (error) {\n health.status = 'unhealthy'\n health.checks.push({\n name: 'connectivity',\n status: 'fail',\n message: (error as Error).message\n })\n\n this.healthStatus.set(serviceId, health)\n this.emit('service:unhealthy', serviceId, (error as Error).message)\n }\n }\n\n /**\n * Start health checks for a service\n */\n private startHealthCheck(serviceId: string): void {\n // Perform initial check\n this.performHealthCheck(serviceId)\n\n // Schedule periodic checks\n const timer = setInterval(() => {\n this.performHealthCheck(serviceId)\n }, this.config.healthCheckInterval)\n\n this.healthCheckTimers.set(serviceId, timer)\n }\n\n /**\n * Stop health checks for a service\n */\n private stopHealthCheck(serviceId: string): void {\n const timer = this.healthCheckTimers.get(serviceId)\n if (timer) {\n clearInterval(timer)\n this.healthCheckTimers.delete(serviceId)\n }\n }\n\n /**\n * Auto-discover services from registry endpoint\n */\n private async discoverServices(): Promise<void> {\n if (!this.config.discoveryEndpoint) {\n return\n }\n\n try {\n const response = await fetch(`${this.config.discoveryEndpoint}/discover`)\n if (response.ok) {\n const services = await response.json() as ServiceEndpoint[]\n\n // Register discovered services\n for (const service of services) {\n if (!this.getService(service.id)) {\n this.registerService(service)\n }\n }\n\n this.emit('discovery:update', services)\n }\n } catch (error) {\n console.error('[Registry] Discovery failed:', error)\n }\n }\n\n /**\n * Start auto-discovery\n */\n private startAutoDiscovery(): void {\n // Initial discovery\n this.discoverServices()\n\n // Periodic discovery\n this.discoveryTimer = setInterval(() => {\n this.discoverServices()\n }, 60000) // Every minute\n }\n\n /**\n * Stop auto-discovery\n */\n stopAutoDiscovery(): void {\n if (this.discoveryTimer) {\n clearInterval(this.discoveryTimer)\n this.discoveryTimer = null\n }\n }\n\n /**\n * Get service health status\n */\n getHealth(serviceId: string): ServiceHealth | undefined {\n return this.healthStatus.get(serviceId)\n }\n\n /**\n * Get all registered services\n */\n getAllServices(): ServiceEndpoint[] {\n return Array.from(this.services.values())\n }\n\n /**\n * Get all active connections\n */\n getAllConnections(): ServiceConnection[] {\n return Array.from(this.connections.values())\n }\n\n /**\n * Get registry statistics\n */\n getStats(): {\n totalServices: number\n healthyServices: number\n unhealthyServices: number\n totalConnections: number\n activeConnections: number\n } {\n const healthyServices = Array.from(this.healthStatus.values())\n .filter(h => h.status === 'healthy').length\n\n const unhealthyServices = Array.from(this.healthStatus.values())\n .filter(h => h.status === 'unhealthy').length\n\n const activeConnections = Array.from(this.connections.values())\n .filter(c => c.status === 'connected').length\n\n return {\n totalServices: this.services.size,\n healthyServices,\n unhealthyServices,\n totalConnections: this.connections.size,\n activeConnections\n }\n }\n\n /**\n * Cleanup and shutdown\n */\n shutdown(): void {\n // Stop all health checks\n for (const serviceId of this.healthCheckTimers.keys()) {\n this.stopHealthCheck(serviceId)\n }\n\n // Stop auto-discovery\n this.stopAutoDiscovery()\n\n // Clear all data\n this.services.clear()\n this.connections.clear()\n this.healthStatus.clear()\n }\n}\n\n// Create singleton instance\nlet registryInstance: ServiceRegistry | null = null\n\nexport function getRegistry(config?: RegistryConfig): ServiceRegistry {\n if (!registryInstance) {\n registryInstance = new ServiceRegistry(config)\n }\n return registryInstance\n}\n\n// Export commonly used functions\nexport function registerService(service: Omit<ServiceEndpoint, 'id'>): ServiceEndpoint {\n return getRegistry().registerService(service)\n}\n\nexport function connectToService(\n serviceId: string,\n chittyId: string,\n metadata?: Record<string, any>\n): Promise<ServiceConnection> {\n return getRegistry().connectToService(serviceId, chittyId, metadata)\n}\n\nexport function getService(idOrName: string): ServiceEndpoint | undefined {\n return getRegistry().getService(idOrName)\n}\n\nexport function getAllServices(): ServiceEndpoint[] {\n return getRegistry().getAllServices()\n}\n\nexport default {\n getRegistry,\n registerService,\n connectToService,\n getService,\n getAllServices,\n ServiceRegistry\n}","/**\n * ChittyOS Beacon - Application tracking and monitoring\n */\n\nimport { nanoid } from 'nanoid'\nimport * as os from 'os'\nimport * as fs from 'fs'\nimport { execSync } from 'child_process'\n\nexport interface BeaconConfig {\n endpoint?: string\n interval?: number\n enabled?: boolean\n silent?: boolean\n appId?: string\n appName?: string\n}\n\nexport interface AppInfo {\n id: string\n name: string\n version: string\n platform: string\n environment: string\n hostname: string\n nodeVersion: string\n os: string\n hasClaudeCode: boolean\n hasGit: boolean\n startedAt: string\n pid: number\n git?: {\n branch: string\n commit: string\n remote: string\n }\n chittyos?: {\n core: string\n modules: string[]\n }\n}\n\nconst DEFAULT_CONFIG: BeaconConfig = {\n endpoint: process.env.CHITTY_BEACON_ENDPOINT || 'https://beacon.chitty.cc',\n interval: parseInt(process.env.CHITTY_BEACON_INTERVAL || '') || 300000,\n enabled: process.env.CHITTY_BEACON_DISABLED !== 'true',\n silent: process.env.CHITTY_BEACON_VERBOSE !== 'true'\n}\n\nlet config = { ...DEFAULT_CONFIG }\nlet appInfo: AppInfo | null = null\nlet heartbeatInterval: NodeJS.Timeout | null = null\n\nexport function configure(customConfig: BeaconConfig): void {\n config = { ...config, ...customConfig }\n}\n\nexport function detectApp(): AppInfo {\n const app: AppInfo = {\n id: generateAppId(),\n name: detectAppName(),\n version: detectVersion(),\n platform: detectPlatform(),\n environment: process.env.NODE_ENV || 'production',\n hostname: os.hostname(),\n nodeVersion: process.version,\n os: `${os.type()} ${os.release()}`,\n hasClaudeCode: detectClaudeCode(),\n hasGit: fs.existsSync('.git'),\n startedAt: new Date().toISOString(),\n pid: process.pid,\n chittyos: {\n core: '1.0.0',\n modules: detectChittyModules()\n }\n }\n\n // Add git info if available\n if (app.hasGit) {\n try {\n app.git = {\n branch: execSync('git branch --show-current', { encoding: 'utf8' }).trim(),\n commit: execSync('git rev-parse --short HEAD', { encoding: 'utf8' }).trim(),\n remote: execSync('git remote get-url origin', { encoding: 'utf8' }).trim()\n }\n } catch (e) {\n // Ignore git errors\n }\n }\n\n return app\n}\n\nfunction generateAppId(): string {\n if (config.appId) return config.appId\n\n // Platform-specific IDs\n if (process.env.REPL_ID) return `replit-${process.env.REPL_ID}`\n if (process.env.GITHUB_REPOSITORY) return `github-${process.env.GITHUB_REPOSITORY.replace('/', '-')}`\n if (process.env.VERCEL_URL) return `vercel-${process.env.VERCEL_URL}`\n if (process.env.HEROKU_APP_NAME) return `heroku-${process.env.HEROKU_APP_NAME}`\n\n // Generate from package.json or create unique ID\n try {\n const pkg = JSON.parse(fs.readFileSync('./package.json', 'utf8'))\n return `npm-${pkg.name}-${nanoid(8)}`\n } catch (e) {\n return `chitty-${nanoid()}`\n }\n}\n\nfunction detectAppName(): string {\n if (config.appName) return config.appName\n\n return process.env.CHITTY_APP_NAME ||\n process.env.REPL_SLUG ||\n process.env.GITHUB_REPOSITORY ||\n process.env.VERCEL_URL ||\n process.env.HEROKU_APP_NAME ||\n process.env.npm_package_name ||\n (() => {\n try {\n const pkg = JSON.parse(fs.readFileSync('./package.json', 'utf8'))\n return pkg.name\n } catch (e) {\n return 'chittyos-app'\n }\n })()\n}\n\nfunction detectVersion(): string {\n try {\n const pkg = JSON.parse(fs.readFileSync('./package.json', 'utf8'))\n return pkg.version\n } catch (e) {\n return '0.0.0'\n }\n}\n\nfunction detectPlatform(): string {\n if (process.env.REPL_ID) return 'replit'\n if (process.env.GITHUB_ACTIONS) return 'github-actions'\n if (process.env.VERCEL) return 'vercel'\n if (process.env.NETLIFY) return 'netlify'\n if (process.env.RENDER) return 'render'\n if (process.env.HEROKU_APP_NAME) return 'heroku'\n if (process.env.AWS_LAMBDA_FUNCTION_NAME) return 'aws-lambda'\n if (process.env.GOOGLE_CLOUD_PROJECT) return 'google-cloud'\n if (process.env.WEBSITE_INSTANCE_ID) return 'azure'\n if (process.env.CF_PAGES) return 'cloudflare-pages'\n if (process.env.CLOUDFLARE_ACCOUNT_ID) return 'cloudflare-workers'\n return 'unknown'\n}\n\nfunction detectClaudeCode(): boolean {\n return process.env.CLAUDE_CODE === 'true' ||\n fs.existsSync('.claude') ||\n fs.existsSync('CLAUDE.md') ||\n fs.existsSync('claude.json')\n}\n\nfunction detectChittyModules(): string[] {\n const modules: string[] = []\n\n try {\n const pkg = JSON.parse(fs.readFileSync('./package.json', 'utf8'))\n const deps = { ...pkg.dependencies, ...pkg.devDependencies }\n\n for (const dep of Object.keys(deps)) {\n if (dep.startsWith('@chittyos/') || dep.startsWith('@chittycorp/')) {\n modules.push(dep)\n }\n }\n } catch (e) {\n // Ignore errors\n }\n\n return modules\n}\n\nexport async function sendBeacon(event: string, data?: any): Promise<void> {\n if (!config.enabled) return\n\n const payload = {\n ...appInfo,\n event,\n timestamp: new Date().toISOString(),\n uptime: process.uptime(),\n ...data\n }\n\n try {\n const response = await fetch(`${config.endpoint}/track`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'User-Agent': '@chittyos/core/1.0.0'\n },\n body: JSON.stringify(payload)\n })\n\n if (!config.silent && !response.ok) {\n console.log(`[ChittyBeacon] Response: ${response.status}`)\n }\n } catch (error) {\n if (!config.silent) {\n console.log(`[ChittyBeacon] Error: ${(error as Error).message}`)\n }\n }\n}\n\nexport function init(customConfig?: BeaconConfig): void {\n if (customConfig) {\n configure(customConfig)\n }\n\n if (!config.enabled) {\n if (!config.silent) {\n console.log('[ChittyBeacon] Disabled')\n }\n return\n }\n\n appInfo = detectApp()\n\n // Send startup beacon\n sendBeacon('startup')\n\n // Send periodic heartbeats\n heartbeatInterval = setInterval(() => {\n sendBeacon('heartbeat')\n }, config.interval!)\n\n // Don't keep process alive just for beacon\n heartbeatInterval.unref()\n\n // Send shutdown beacon\n const shutdown = () => {\n sendBeacon('shutdown')\n }\n\n process.once('exit', shutdown)\n process.once('SIGINT', shutdown)\n process.once('SIGTERM', shutdown)\n\n if (!config.silent) {\n console.log(`[ChittyBeacon] Tracking ${appInfo.name} on ${appInfo.platform}`)\n }\n}\n\nexport function stop(): void {\n if (heartbeatInterval) {\n clearInterval(heartbeatInterval)\n heartbeatInterval = null\n }\n sendBeacon('stopped')\n}\n\n// Auto-init if not in test environment\nif (process.env.NODE_ENV !== 'test') {\n init()\n}"],"mappings":"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","names":["nanoid","config","nanoid","type"]}