@getvision/server 0.4.3-d4c761e-develop → 0.4.4-44d79d9-develop

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.
Files changed (45) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/dist/event-bus.d.ts +87 -0
  3. package/dist/event-bus.d.ts.map +1 -0
  4. package/dist/event-bus.js +265 -0
  5. package/dist/event-bus.js.map +10 -0
  6. package/dist/event-registry.d.ts +79 -0
  7. package/dist/event-registry.d.ts.map +1 -0
  8. package/dist/event-registry.js +93 -0
  9. package/dist/event-registry.js.map +10 -0
  10. package/{src/index.ts → dist/index.d.ts} +14 -28
  11. package/dist/index.d.ts.map +1 -0
  12. package/dist/index.js +33 -0
  13. package/dist/index.js.map +10 -0
  14. package/dist/router.d.ts +16 -0
  15. package/dist/router.d.ts.map +1 -0
  16. package/dist/router.js +117 -0
  17. package/dist/router.js.map +10 -0
  18. package/dist/service.d.ts +151 -0
  19. package/dist/service.d.ts.map +1 -0
  20. package/dist/service.js +341 -0
  21. package/dist/service.js.map +10 -0
  22. package/dist/types.d.ts +71 -0
  23. package/dist/types.d.ts.map +1 -0
  24. package/dist/types.js +2 -0
  25. package/dist/types.js.map +9 -0
  26. package/dist/vision-app.d.ts +166 -0
  27. package/dist/vision-app.d.ts.map +1 -0
  28. package/dist/vision-app.js +611 -0
  29. package/dist/vision-app.js.map +10 -0
  30. package/dist/vision.d.ts +63 -0
  31. package/dist/vision.d.ts.map +1 -0
  32. package/dist/vision.js +223 -0
  33. package/dist/vision.js.map +10 -0
  34. package/package.json +13 -3
  35. package/.env.example +0 -3
  36. package/.eslintrc.cjs +0 -7
  37. package/.turbo/turbo-build.log +0 -1
  38. package/src/event-bus.ts +0 -409
  39. package/src/event-registry.ts +0 -158
  40. package/src/router.ts +0 -118
  41. package/src/service.ts +0 -618
  42. package/src/types.ts +0 -93
  43. package/src/vision-app.ts +0 -880
  44. package/src/vision.ts +0 -319
  45. package/tsconfig.json +0 -9
@@ -0,0 +1,10 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/vision-app.ts"],
4
+ "sourcesContent": [
5
+ "import { Hono } from 'hono'\nimport type { Env, Schema } from 'hono'\nimport { VisionCore, runInTraceContext } from '@getvision/core'\nimport type { RouteMetadata } from '@getvision/core'\nimport { AsyncLocalStorage } from 'async_hooks'\nimport { existsSync } from 'fs'\nimport { spawn, spawnSync, type ChildProcess } from 'child_process'\nimport { ServiceBuilder } from './service'\nimport { EventBus } from './event-bus'\nimport { eventRegistry } from './event-registry'\nimport type { serve as honoServe } from '@hono/node-server'\nimport type { QueueEventsOptions, QueueOptions, WorkerOptions } from \"bullmq\";\n\nexport interface VisionALSContext {\n vision: VisionCore\n traceId: string\n rootSpanId: string\n}\n\nconst visionContext = new AsyncLocalStorage<VisionALSContext>()\n\n// Global instance tracking for hot-reload cleanup\n// Must attach to globalThis because module-scoped variables are reset when the module is reloaded\nconst GLOBAL_VISION_KEY = '__vision_instance_state'\ninterface VisionGlobalState {\n instance: Vision<any, any, any> | null\n drizzleProcess: ChildProcess | null\n}\n\n// Initialize global state if needed\nif (!(globalThis as any)[GLOBAL_VISION_KEY]) {\n (globalThis as any)[GLOBAL_VISION_KEY] = {\n instance: null,\n drizzleProcess: null\n }\n}\n\nfunction getGlobalState(): VisionGlobalState {\n return (globalThis as any)[GLOBAL_VISION_KEY]\n}\n\nasync function cleanupVisionInstance(instance: Vision<any, any, any>): Promise<void> {\n const existing = (instance as any)._cleanupPromise as Promise<void> | undefined\n if (existing) return existing;\n\n (instance as any)._cleanupPromise = (async () => {\n const server = (instance as any).bunServer\n const hasBunServer = server && typeof server.stop === 'function'\n\n try {\n if (hasBunServer) {\n server.stop()\n }\n if ((globalThis as any).__vision_bun_server === server) {\n (globalThis as any).__vision_bun_server = undefined\n }\n } catch {}\n\n try { stopDrizzleStudio({ log: false }) } catch {}\n try { await (instance as any).eventBus?.close() } catch {}\n })()\n\n return (instance as any)._cleanupPromise\n}\n\ntype BunServeOptions = Parameters<typeof Bun['serve']>[0]\ntype NodeServeOptions = Parameters<typeof honoServe>[0]\n\ntype VisionStartOptions = Omit<Partial<BunServeOptions>, 'fetch' | 'port'> &\n Omit<Partial<NodeServeOptions>, 'fetch' | 'port'>\n\n// Simple deep merge utility (objects only, arrays are overwritten by source)\nfunction deepMerge<T extends Record<string, any>>(target: T, source: Partial<T>): T {\n const output: any = { ...target }\n if (source && typeof source === 'object') {\n for (const key of Object.keys(source)) {\n const srcVal = source[key]\n const tgtVal = output[key]\n if (\n srcVal &&\n typeof srcVal === 'object' &&\n !Array.isArray(srcVal) &&\n tgtVal &&\n typeof tgtVal === 'object' &&\n !Array.isArray(tgtVal)\n ) {\n output[key] = deepMerge(tgtVal, srcVal)\n } else {\n output[key] = srcVal\n }\n }\n }\n return output as T\n}\n\n/**\n * Vision Server configuration\n */\nexport interface VisionConfig {\n service: {\n name: string\n version?: string\n description?: string\n integrations?: Record<string, string>\n drizzle?: {\n autoStart?: boolean\n port?: number\n }\n }\n vision?: {\n enabled?: boolean\n port?: number\n maxTraces?: number\n maxLogs?: number\n logging?: boolean\n apiUrl?: string // URL of the API server (for frontend to make HTTP requests)\n }\n routes?: {\n autodiscover?: boolean\n dirs?: string[]\n }\n pubsub?: {\n redis?: {\n host?: string\n port?: number\n password?: string\n /**\n * Enable keepalive to prevent connection timeouts (default: 30000ms)\n */\n keepAlive?: number\n /**\n * Max retry attempts for failed commands (default: 20)\n */\n maxRetriesPerRequest?: number\n /**\n * Enable ready check before executing commands (default: true)\n */\n enableReadyCheck?: boolean\n /**\n * Connection timeout in ms (default: 10000)\n */\n connectTimeout?: number\n /**\n * Enable offline queue (default: true)\n */\n enableOfflineQueue?: boolean\n }\n devMode?: boolean // Use in-memory event bus (no Redis required)\n eventBus?: EventBus // Share EventBus instance across apps (for sub-apps)\n /**\n * Default BullMQ worker concurrency for all handlers (overridable per handler)\n */\n workerConcurrency?: number\n queue?: Omit<QueueOptions, 'connection'>\n worker?: Omit<WorkerOptions, 'connection'>\n queueEvents?: Omit<QueueEventsOptions, 'connection'>\n }\n}\n\n/**\n * Vision - Meta-framework built on Hono with observability\n * \n * @example\n * ```ts\n * const app = new Vision({\n * service: {\n * name: 'My API',\n * version: '1.0.0'\n * }\n * })\n * \n * const userService = app.service('users')\n * .on('user/created', handler)\n * .endpoint('GET', '/users/:id', schema, handler)\n *\n * app.start(3000)\n * ```\n */\nexport class Vision<\n E extends Env = Env,\n S extends Schema = {},\n BasePath extends string = '/'\n> extends Hono<E, S, BasePath> {\n private visionCore: VisionCore\n private eventBus: EventBus\n private config: VisionConfig\n private serviceBuilders: ServiceBuilder<any, E>[] = []\n private bunServer?: any\n private signalHandler?: () => Promise<void>\n\n constructor(config?: VisionConfig) {\n super()\n \n const defaultConfig: VisionConfig = {\n service: {\n name: 'Vision SubApp',\n },\n vision: {\n enabled: false,\n port: 9500,\n },\n // Do not set a default devMode here; let EventBus derive from Redis presence\n pubsub: {},\n routes: {\n autodiscover: true,\n dirs: ['app/routes'],\n },\n }\n\n // Deep merge to respect nested overrides\n this.config = deepMerge(defaultConfig, config || {})\n \n // Initialize Vision Core\n const visionEnabled = this.config.vision?.enabled !== false\n const visionPort = this.config.vision?.port ?? 9500\n \n if (visionEnabled) {\n this.visionCore = new VisionCore({\n port: visionPort,\n maxTraces: this.config.vision?.maxTraces ?? 1000,\n maxLogs: this.config.vision?.maxLogs ?? 10000,\n apiUrl: this.config.vision?.apiUrl,\n })\n\n // Detect and optionally start Drizzle Studio\n const drizzleInfo = detectDrizzle()\n let drizzleStudioUrl: string | undefined\n \n if (drizzleInfo.detected) {\n console.log(`🗄️ Drizzle detected (${drizzleInfo.configPath})`)\n \n if (this.config.service.drizzle?.autoStart) {\n const drizzlePort = this.config.service.drizzle.port || 4983\n const started = startDrizzleStudio(drizzlePort)\n if (started) {\n drizzleStudioUrl = 'https://local.drizzle.studio'\n }\n } else {\n console.log('💡 Tip: Enable Drizzle Studio auto-start with drizzle: { autoStart: true }')\n drizzleStudioUrl = 'https://local.drizzle.studio'\n }\n }\n\n // Clean integrations (remove undefined values)\n const cleanIntegrations = Object.fromEntries(\n Object.entries(this.config.service.integrations || {}).filter(([_, v]) => v !== undefined)\n )\n\n // Set app status\n this.visionCore.setAppStatus({\n name: this.config.service.name,\n version: this.config.service.version ?? '0.0.0',\n description: this.config.service.description,\n running: true,\n pid: process.pid,\n metadata: {\n framework: 'vision-server',\n integrations: Object.keys(cleanIntegrations).length > 0 ? cleanIntegrations : undefined,\n drizzle: drizzleInfo.detected\n ? {\n detected: true,\n configPath: drizzleInfo.configPath,\n studioUrl: drizzleStudioUrl,\n autoStarted: this.config.service.drizzle?.autoStart || false,\n }\n : {\n detected: false,\n configPath: undefined,\n studioUrl: undefined,\n autoStarted: false,\n },\n },\n })\n } else {\n // Create dummy Vision Core that does nothing\n this.visionCore = null as any\n }\n \n // Use provided EventBus or create a new one\n // Root app creates EventBus, sub-apps can share it via config.pubsub.eventBus\n this.eventBus = this.config.pubsub?.eventBus || new EventBus({\n redis: this.config.pubsub?.redis,\n devMode: this.config.pubsub?.devMode,\n workerConcurrency: this.config.pubsub?.workerConcurrency,\n queue: this.config.pubsub?.queue,\n worker: this.config.pubsub?.worker,\n queueEvents: this.config.pubsub?.queueEvents,\n })\n \n // Register JSON-RPC methods for events/cron\n if (visionEnabled) {\n this.registerEventMethods()\n }\n \n // Install Vision middleware automatically\n if (visionEnabled) {\n this.installVisionMiddleware()\n }\n }\n\n /**\n * Register JSON-RPC methods for events and cron jobs\n */\n private registerEventMethods() {\n const server = this.visionCore.getServer()\n \n // List all events\n server.registerMethod('events/list', async () => {\n const events = eventRegistry.getAllEvents()\n return events.map(event => ({\n name: event.name,\n description: event.description,\n icon: event.icon,\n tags: event.tags,\n handlers: event.handlers.length,\n lastTriggered: event.lastTriggered,\n totalCount: event.totalCount,\n failedCount: event.failedCount,\n }))\n })\n \n // List all cron jobs\n server.registerMethod('cron/list', async () => {\n const crons = eventRegistry.getAllCrons()\n return crons.map(cron => ({\n name: cron.name,\n schedule: cron.schedule,\n description: cron.description,\n icon: cron.icon,\n tags: cron.tags,\n lastRun: cron.lastRun,\n nextRun: cron.nextRun,\n totalRuns: cron.totalRuns,\n failedRuns: cron.failedRuns,\n }))\n })\n }\n\n /**\n * Install Vision tracing middleware\n */\n private installVisionMiddleware() {\n const logging = this.config.vision?.logging !== false\n \n this.use('*', async (c, next) => {\n // Skip OPTIONS requests\n if (c.req.method === 'OPTIONS') {\n return next()\n }\n\n const startTime = Date.now()\n \n // Create trace\n const trace = this.visionCore.createTrace(c.req.method, c.req.path)\n \n // Run request in AsyncLocalStorage context\n return visionContext.run(\n {\n vision: this.visionCore,\n traceId: trace.id,\n rootSpanId: ''\n },\n async () => {\n // Also set core trace context so VisionCore.addContext() works\n return runInTraceContext(trace.id, async () => {\n // Start main span\n const tracer = this.visionCore.getTracer()\n const rootSpan = tracer.startSpan('http.request', trace.id)\n \n // Update context with rootSpanId\n const ctx = visionContext.getStore()\n if (ctx) {\n ctx.rootSpanId = rootSpan.id\n }\n\n // Provide c.span and c.addContext globally for all downstream handlers (Vision/Hono sub-apps)\n if (!(c as any).span) {\n (c as any).addContext = (context: Record<string, unknown>) => {\n const current = visionContext.getStore()\n const currentTraceId = current?.traceId || trace.id\n \n // Add context to trace metadata via VisionCore\n const visionTrace = this.visionCore.getTraceStore().getTrace(currentTraceId)\n if (visionTrace) {\n visionTrace.metadata = { ...(visionTrace.metadata || {}), ...context }\n }\n }\n\n (c as any).span = <T>(\n name: string,\n attributes: Record<string, any> = {},\n fn?: () => T\n ): T => {\n const current = visionContext.getStore()\n const currentTraceId = current?.traceId || trace.id\n const currentRootSpanId = current?.rootSpanId || rootSpan.id\n const s = tracer.startSpan(name, currentTraceId, currentRootSpanId)\n for (const [k, v] of Object.entries(attributes)) tracer.setAttribute(s.id, k, v)\n try {\n const result = fn ? fn() : (undefined as any)\n const completed = tracer.endSpan(s.id)\n if (completed) this.visionCore.getTraceStore().addSpan(currentTraceId, completed)\n return result\n } catch (err) {\n tracer.setAttribute(s.id, 'error', true)\n tracer.setAttribute(s.id, 'error.message', err instanceof Error ? err.message : String(err))\n const completed = tracer.endSpan(s.id)\n if (completed) this.visionCore.getTraceStore().addSpan(currentTraceId, completed)\n throw err\n }\n }\n }\n \n // Add request attributes\n tracer.setAttribute(rootSpan.id, 'http.method', c.req.method)\n tracer.setAttribute(rootSpan.id, 'http.path', c.req.path)\n tracer.setAttribute(rootSpan.id, 'http.url', c.req.url)\n\n // Add query params if any\n const url = new URL(c.req.url)\n if (url.search) {\n tracer.setAttribute(rootSpan.id, 'http.query', url.search)\n }\n\n // Capture request metadata\n try {\n const rawReq = c.req.raw\n const headers: Record<string, string> = {}\n rawReq.headers.forEach((v, k) => { headers[k] = v })\n\n const urlObj = new URL(c.req.url)\n const query: Record<string, string> = {}\n urlObj.searchParams.forEach((v, k) => { query[k] = v })\n\n let body: unknown = undefined\n const ct = headers['content-type'] || headers['Content-Type']\n if (ct && ct.includes('application/json')) {\n try {\n body = await rawReq.clone().json()\n } catch {}\n }\n\n const sessionId = headers['x-vision-session']\n if (sessionId) {\n tracer.setAttribute(rootSpan.id, 'session.id', sessionId)\n trace.metadata = { ...(trace.metadata || {}), sessionId }\n }\n\n const requestMeta = {\n method: c.req.method,\n url: urlObj.pathname + (urlObj.search || ''),\n headers,\n query: Object.keys(query).length ? query : undefined,\n body,\n }\n tracer.setAttribute(rootSpan.id, 'http.request', requestMeta)\n trace.metadata = { ...(trace.metadata || {}), request: requestMeta }\n\n // Emit start log\n if (logging) {\n const parts = [\n `method=${c.req.method}`,\n `path=${c.req.path}`,\n ]\n if (sessionId) parts.push(`sessionId=${sessionId}`)\n parts.push(`traceId=${trace.id}`)\n console.info(`INF starting request ${parts.join(' ')}`)\n }\n\n // Execute request\n await next()\n\n // Add response attributes\n tracer.setAttribute(rootSpan.id, 'http.status_code', c.res.status)\n const resHeaders: Record<string, string> = {}\n c.res.headers?.forEach((v, k) => { resHeaders[k] = v as unknown as string })\n\n let respBody: unknown = undefined\n const resCt = c.res.headers?.get('content-type') || ''\n try {\n const clone = c.res.clone()\n if (resCt.includes('application/json')) {\n const txt = await clone.text()\n if (txt && txt.length <= 65536) {\n try { respBody = JSON.parse(txt) } catch { respBody = txt }\n }\n }\n } catch {}\n\n const responseMeta = {\n status: c.res.status,\n headers: Object.keys(resHeaders).length ? resHeaders : undefined,\n body: respBody,\n }\n tracer.setAttribute(rootSpan.id, 'http.response', responseMeta)\n trace.metadata = { ...(trace.metadata || {}), response: responseMeta }\n\n } catch (error) {\n // Track error\n tracer.addEvent(rootSpan.id, 'error', {\n message: error instanceof Error ? error.message : 'Unknown error',\n stack: error instanceof Error ? error.stack : undefined,\n })\n\n tracer.setAttribute(rootSpan.id, 'error', true)\n throw error\n\n } finally {\n // End span and add it to trace\n const completedSpan = tracer.endSpan(rootSpan.id)\n if (completedSpan) {\n this.visionCore.getTraceStore().addSpan(trace.id, completedSpan)\n }\n\n // Complete trace\n const duration = Date.now() - startTime\n this.visionCore.completeTrace(trace.id, c.res.status, duration)\n\n // Add trace ID to response headers\n c.header('X-Vision-Trace-Id', trace.id)\n\n // Emit completion log\n if (logging) {\n console.info(\n `INF request completed code=${c.res.status} duration=${duration}ms method=${c.req.method} path=${c.req.path} traceId=${trace.id}`\n )\n }\n }\n })\n }\n )\n })\n }\n\n\n /**\n * Create a new service with builder pattern\n * \n * @example\n * ```ts\n * const userService = app.service('users')\n * .endpoint('GET', '/users/:id', schema, handler)\n * .on('user/created', handler)\n * ```\n */\n service<E2 extends Env = E, TEvents extends Record<string, any> = {}>(name: string) {\n const builder = new ServiceBuilder<TEvents, E2>(name, this.eventBus, this.visionCore)\n \n // Preserve builder for registration in start()\n this.serviceBuilders.push(builder as unknown as ServiceBuilder<any, E>)\n \n return builder\n }\n\n /**\n * Get services and routes metadata without registering to this VisionCore\n */\n public getServiceSummaries(): Array<{ name: string; routes: RouteMetadata[] }> {\n const summaries: Array<{ name: string; routes: RouteMetadata[] }> = []\n for (const builder of this.serviceBuilders) {\n const name = (builder as any).getDisplayName?.() ?? 'Service'\n const rawRoutes = (builder as any).getRoutesMetadata?.()\n if (!rawRoutes || !Array.isArray(rawRoutes)) continue\n const routes: RouteMetadata[] = rawRoutes.map((r: any) => ({\n method: r.method,\n path: r.path,\n handler: name,\n queryParams: r.queryParams,\n requestBody: r.requestBody,\n responseBody: r.responseBody,\n }))\n summaries.push({ name, routes })\n }\n return summaries\n }\n\n /**\n * Build all service builders\n */\n public buildAllServices() {\n const allServices: Array<{ name: string; routes: RouteMetadata[] }> = []\n \n // Build all services (this populates allServices via builder.build)\n for (const builder of this.serviceBuilders) {\n builder.build(this as any, allServices)\n }\n \n // Don't register to VisionCore here - let start() handle it after sub-apps are loaded\n // Just return allServices so they can be registered later\n return allServices\n }\n\n /**\n * Get Vision Core instance\n */\n getVision(): VisionCore {\n return this.visionCore\n }\n\n /**\n * Get EventBus instance\n */\n getEventBus(): EventBus {\n return this.eventBus\n }\n\n\n /**\n * Autoload Vision/Hono sub-apps from configured directories\n */\n private async autoloadRoutes(): Promise<Array<{ name: string; routes: any[] }>> {\n const enabled = this.config.routes?.autodiscover !== false\n const dirs = this.config.routes?.dirs ?? ['app/routes']\n if (!enabled) return []\n\n const existing: string[] = []\n for (const d of dirs) {\n try { if (existsSync(d)) existing.push(d) } catch {}\n }\n if (existing.length === 0) return []\n\n const { loadSubApps } = await import('./router')\n let allSubAppSummaries: Array<{ name: string; routes: any[] }> = []\n for (const d of existing) {\n try {\n // Pass EventBus to sub-apps so they share the same instance\n const summaries = await loadSubApps(this as any, d, this.eventBus)\n allSubAppSummaries = allSubAppSummaries.concat(summaries)\n } catch (e) {\n console.error(`❌ Failed to load sub-apps from ${d}:`, (e as any)?.message || e)\n if (e instanceof Error && e.stack) {\n console.error('Stack:', e.stack)\n }\n }\n }\n return allSubAppSummaries\n }\n\n /**\n * Start the server (convenience method)\n */\n async start(port: number = 3000, options?: VisionStartOptions) {\n const { hostname, ...restOptions } = options || {}\n const { fetch: _bf, port: _bp, ...bunRest } = restOptions as Partial<BunServeOptions>\n const { fetch: _nf, port: _np, ...nodeRest } = restOptions as Partial<NodeServeOptions>\n\n // Build all services WITHOUT registering to VisionCore yet\n const rootSummaries = this.buildAllServices()\n // Autoload file-based Vision/Hono sub-apps if enabled (returns merged sub-app summaries)\n const subAppSummaries = await this.autoloadRoutes()\n \n // Merge root and sub-app services by name\n const allServices = new Map<string, { name: string; routes: any[] }>()\n \n // Add root services first\n for (const summary of rootSummaries || []) {\n allServices.set(summary.name, { name: summary.name, routes: [...summary.routes] })\n }\n \n // Merge sub-app services (combine routes if service name already exists)\n for (const summary of subAppSummaries || []) {\n if (allServices.has(summary.name)) {\n const existing = allServices.get(summary.name)!\n existing.routes.push(...summary.routes)\n } else {\n allServices.set(summary.name, { name: summary.name, routes: [...summary.routes] })\n }\n }\n \n // Register all services in one call\n if (this.visionCore && allServices.size > 0) {\n const servicesToRegister = Array.from(allServices.values())\n this.visionCore.registerServices(servicesToRegister)\n const flatRoutes = servicesToRegister.flatMap(s => s.routes)\n this.visionCore.registerRoutes(flatRoutes)\n console.log(`✅ Registered ${servicesToRegister.length} total services (${flatRoutes.length} routes)`)\n }\n \n // Cleanup previous instance before starting new one (hot-reload)\n const state = getGlobalState()\n if (state.instance && state.instance !== this) {\n await cleanupVisionInstance(state.instance)\n }\n state.instance = this\n\n console.log(`🚀 Starting ${this.config.service.name}...`)\n console.log(`📡 API Server: http://localhost:${port}`)\n \n // Register signal handlers (cleaned up on dispose)\n if (!this.signalHandler) {\n this.signalHandler = async () => {\n const s = getGlobalState()\n if (s.instance) {\n await cleanupVisionInstance(s.instance)\n }\n try { process.exit(0) } catch {}\n }\n }\n\n const handleSignal = this.signalHandler\n\n process.removeListener('SIGINT', handleSignal)\n process.removeListener('SIGTERM', handleSignal)\n try { process.removeListener('SIGQUIT', handleSignal) } catch {}\n\n process.on('SIGINT', handleSignal)\n process.on('SIGTERM', handleSignal)\n try { process.on('SIGQUIT', handleSignal) } catch {}\n \n // Bun hot-reload: register dispose callback\n try {\n const hot = (import.meta as any)?.hot\n if (hot && typeof hot.dispose === 'function') {\n hot.dispose(async () => {\n console.log('♻️ Hot reload: reloading...')\n\n // 1. Remove signal listeners to prevent accumulation\n process.off('SIGINT', handleSignal)\n process.off('SIGTERM', handleSignal)\n try { process.off('SIGQUIT', handleSignal) } catch {}\n\n // 2. Cleanup this instance\n const s = getGlobalState()\n await cleanupVisionInstance(this)\n if (s.instance === this) {\n s.instance = null\n }\n })\n }\n } catch {}\n \n // Prefer Bun if available, then Node.js; otherwise instruct the user to serve manually\n if (typeof process !== 'undefined' && process.versions?.bun) {\n const BunServe = (globalThis as any).Bun?.serve\n if (typeof BunServe === 'function') {\n try {\n const existing = (globalThis as any).__vision_bun_server\n if (existing && typeof existing.stop === 'function') {\n try { existing.stop() } catch {}\n }\n } catch {}\n this.bunServer = BunServe({\n ...bunRest,\n fetch: this.fetch.bind(this),\n port,\n hostname\n })\n try { (globalThis as any).__vision_bun_server = this.bunServer } catch {}\n } else {\n console.warn('Bun detected but Bun.serve is unavailable')\n return this\n }\n } else if (typeof process !== 'undefined' && process.versions?.node) {\n const { serve } = await import('@hono/node-server')\n serve({\n ...nodeRest,\n fetch: this.fetch.bind(this),\n port,\n hostname\n })\n } else {\n // For other runtimes, just return the app\n console.log('⚠️ Use your runtime\\'s serve function')\n return this\n }\n }\n\n /**\n * Set the EventBus instance (used internally by router to inject shared EventBus)\n */\n setEventBus(eventBus: EventBus): void {\n this.eventBus = eventBus\n }\n}\n\n/**\n * Get Vision context (internal use)\n */\nexport function getVisionContext(): VisionALSContext | undefined {\n return visionContext.getStore()\n}\n\n// ============================================================================\n// Drizzle Studio Integration\n// ============================================================================\n\n/**\n * Detect Drizzle configuration\n */\nfunction detectDrizzle(): { detected: boolean; configPath?: string } {\n const possiblePaths = [\n 'drizzle.config.ts',\n 'drizzle.config.js',\n 'drizzle.config.mjs',\n ]\n\n for (const path of possiblePaths) {\n if (existsSync(path)) {\n return { detected: true, configPath: path }\n }\n }\n return { detected: false }\n}\n\n/**\n * Start Drizzle Studio\n */\nfunction startDrizzleStudio(port: number): boolean {\n const state = getGlobalState()\n if (state.drizzleProcess) {\n console.log('⚠️ Drizzle Studio is already running')\n return false\n }\n\n // If Drizzle Studio is already listening on this port, skip spawning but report available\n try {\n if (process.platform === 'win32') {\n const res = spawnSync('powershell', ['-NoProfile', '-Command', `netstat -ano | Select-String -Pattern \"LISTENING\\\\s+.*:${port}\\\\s\"`], { encoding: 'utf-8' })\n if ((res.stdout || '').trim().length > 0) {\n console.log(`⚠️ Drizzle Studio port ${port} already in use; assuming it is running. Skipping auto-start.`)\n return true\n }\n } else {\n const res = spawnSync('lsof', ['-i', `tcp:${port}`, '-sTCP:LISTEN'], { encoding: 'utf-8' })\n if ((res.stdout || '').trim().length > 0) {\n console.log(`⚠️ Drizzle Studio port ${port} already in use; assuming it is running. Skipping auto-start.`)\n return true\n }\n }\n } catch {}\n\n try {\n const proc = spawn('npx', ['drizzle-kit', 'studio', '--port', String(port), '--host', '0.0.0.0'], {\n stdio: 'inherit',\n detached: false,\n shell: process.platform === 'win32',\n })\n \n state.drizzleProcess = proc\n\n proc.on('error', (error) => {\n console.error('❌ Failed to start Drizzle Studio:', error.message)\n })\n\n proc.on('exit', (code) => {\n if (code !== 0 && code !== null) {\n console.error(`❌ Drizzle Studio exited with code ${code}`)\n }\n // Clear global state if it matches this process\n const s = getGlobalState()\n if (s.drizzleProcess === proc) {\n s.drizzleProcess = null\n }\n })\n\n console.log(`✅ Drizzle Studio: https://local.drizzle.studio`)\n return true\n } catch (error) {\n console.error('❌ Failed to start Drizzle Studio:', error)\n return false\n }\n}\n\n/**\n * Stop Drizzle Studio\n */\nfunction stopDrizzleStudio(options?: { log?: boolean }): boolean {\n const state = getGlobalState()\n if (state.drizzleProcess) {\n // Remove all event listeners to prevent memory leaks\n state.drizzleProcess.removeAllListeners()\n state.drizzleProcess.kill()\n state.drizzleProcess = null\n if (options?.log !== false) {\n console.log('🛑 Drizzle Studio stopped')\n }\n return true\n }\n return false\n}\n"
6
+ ],
7
+ "mappings": "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",
8
+ "debugId": "030980C43D326B6264756E2164756E21",
9
+ "names": []
10
+ }
@@ -0,0 +1,63 @@
1
+ import type { MiddlewareHandler } from 'hono';
2
+ import { VisionCore } from '@getvision/core';
3
+ /**
4
+ * Vision context available in request handlers
5
+ */
6
+ interface VisionContext {
7
+ vision: VisionCore;
8
+ traceId: string;
9
+ rootSpanId: string;
10
+ }
11
+ /**
12
+ * Get Vision context (available in route handlers)
13
+ *
14
+ * @example
15
+ * ```ts
16
+ * const { vision, traceId } = getVisionContext()
17
+ * const withSpan = vision.createSpanHelper(traceId)
18
+ * ```
19
+ */
20
+ export declare function getVisionContext(): VisionContext;
21
+ /**
22
+ * Create span helper using current trace context
23
+ *
24
+ * @example
25
+ * ```ts
26
+ * const withSpan = useVisionSpan()
27
+ * const users = withSpan('db.select', { 'db.table': 'users' }, () => {
28
+ * return db.select().from(users).all()
29
+ * })
30
+ * ```
31
+ */
32
+ export declare function useVisionSpan(): <T>(name: string, attributes: Record<string, any> | undefined, fn: () => T) => T;
33
+ /**
34
+ * Vision middleware options
35
+ */
36
+ export interface VisionOptions {
37
+ enabled?: boolean;
38
+ port?: number;
39
+ maxTraces?: number;
40
+ maxLogs?: number;
41
+ logging?: boolean;
42
+ service?: {
43
+ name?: string;
44
+ version?: string;
45
+ description?: string;
46
+ };
47
+ }
48
+ /**
49
+ * Get Vision instance
50
+ */
51
+ export declare function getVisionInstance(): VisionCore | null;
52
+ /**
53
+ * Create Vision middleware for Hono
54
+ *
55
+ * This middleware automatically:
56
+ * - Creates traces for all requests
57
+ * - Adds request/response metadata
58
+ * - Provides Vision context to handlers
59
+ * - Broadcasts events to Vision Dashboard
60
+ */
61
+ export declare function createVisionMiddleware(options?: VisionOptions): MiddlewareHandler;
62
+ export {};
63
+ //# sourceMappingURL=vision.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"vision.d.ts","sourceRoot":"","sources":["../src/vision.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAiB,iBAAiB,EAAE,MAAM,MAAM,CAAA;AAC5D,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAA;AAK5C;;GAEG;AACH,UAAU,aAAa;IACrB,MAAM,EAAE,UAAU,CAAA;IAClB,OAAO,EAAE,MAAM,CAAA;IACf,UAAU,EAAE,MAAM,CAAA;CACnB;AAID;;;;;;;;GAQG;AACH,wBAAgB,gBAAgB,IAAI,aAAa,CAMhD;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,aAAa,KAInB,CAAC,EACP,MAAM,MAAM,EACZ,YAAY,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,YAAK,EACpC,IAAI,MAAM,CAAC,KACV,CAAC,CAgCL;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,OAAO,CAAC,EAAE;QACR,IAAI,CAAC,EAAE,MAAM,CAAA;QACb,OAAO,CAAC,EAAE,MAAM,CAAA;QAChB,WAAW,CAAC,EAAE,MAAM,CAAA;KACrB,CAAA;CACF;AAID;;GAEG;AACH,wBAAgB,iBAAiB,IAAI,UAAU,GAAG,IAAI,CAErD;AAqBD;;;;;;;;GAQG;AACH,wBAAgB,sBAAsB,CAAC,OAAO,GAAE,aAAkB,GAAG,iBAAiB,CAkLrF"}
package/dist/vision.js ADDED
@@ -0,0 +1,223 @@
1
+ import { createRequire } from "node:module";
2
+ var __create = Object.create;
3
+ var __getProtoOf = Object.getPrototypeOf;
4
+ var __defProp = Object.defineProperty;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
7
+ var __toESM = (mod, isNodeMode, target) => {
8
+ target = mod != null ? __create(__getProtoOf(mod)) : {};
9
+ const to = isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target;
10
+ for (let key of __getOwnPropNames(mod))
11
+ if (!__hasOwnProp.call(to, key))
12
+ __defProp(to, key, {
13
+ get: () => mod[key],
14
+ enumerable: true
15
+ });
16
+ return to;
17
+ };
18
+ var __require = /* @__PURE__ */ createRequire(import.meta.url);
19
+
20
+ // src/vision.ts
21
+ import { VisionCore } from "@getvision/core";
22
+ import { AsyncLocalStorage } from "async_hooks";
23
+ import { readFileSync, existsSync } from "fs";
24
+ import { join } from "path";
25
+ var visionContext = new AsyncLocalStorage;
26
+ function getVisionContext() {
27
+ const context = visionContext.getStore();
28
+ if (!context) {
29
+ throw new Error("Vision context not available. Make sure Vision is enabled.");
30
+ }
31
+ return context;
32
+ }
33
+ function useVisionSpan() {
34
+ const { vision, traceId, rootSpanId } = getVisionContext();
35
+ const tracer = vision.getTracer();
36
+ return (name, attributes = {}, fn) => {
37
+ const span = tracer.startSpan(name, traceId, rootSpanId);
38
+ for (const [key, value] of Object.entries(attributes)) {
39
+ tracer.setAttribute(span.id, key, value);
40
+ }
41
+ try {
42
+ const result = fn();
43
+ const completedSpan = tracer.endSpan(span.id);
44
+ if (completedSpan) {
45
+ vision.getTraceStore().addSpan(traceId, completedSpan);
46
+ }
47
+ return result;
48
+ } catch (error) {
49
+ tracer.setAttribute(span.id, "error", true);
50
+ tracer.setAttribute(span.id, "error.message", error instanceof Error ? error.message : String(error));
51
+ const completedSpan = tracer.endSpan(span.id);
52
+ if (completedSpan) {
53
+ vision.getTraceStore().addSpan(traceId, completedSpan);
54
+ }
55
+ throw error;
56
+ }
57
+ };
58
+ }
59
+ var visionInstance = null;
60
+ function getVisionInstance() {
61
+ return visionInstance;
62
+ }
63
+ function autoDetectPackageInfo() {
64
+ try {
65
+ const pkgPath = join(process.cwd(), "package.json");
66
+ if (existsSync(pkgPath)) {
67
+ const pkg = JSON.parse(readFileSync(pkgPath, "utf-8"));
68
+ return {
69
+ name: pkg.name || "unknown",
70
+ version: pkg.version || "0.0.0"
71
+ };
72
+ }
73
+ } catch (error) {}
74
+ return { name: "unknown", version: "0.0.0" };
75
+ }
76
+ function createVisionMiddleware(options = {}) {
77
+ const {
78
+ enabled = true,
79
+ port = 9500,
80
+ maxTraces = 1000,
81
+ maxLogs = 1e4,
82
+ logging = true
83
+ } = options;
84
+ if (!enabled) {
85
+ return async (c, next) => await next();
86
+ }
87
+ if (!visionInstance) {
88
+ visionInstance = new VisionCore({ port, maxTraces, maxLogs });
89
+ const pkgInfo = autoDetectPackageInfo();
90
+ const serviceName = options.service?.name || pkgInfo.name;
91
+ const serviceVersion = options.service?.version || pkgInfo.version;
92
+ visionInstance.setAppStatus({
93
+ name: serviceName,
94
+ version: serviceVersion,
95
+ description: options.service?.description,
96
+ running: true,
97
+ pid: process.pid,
98
+ metadata: {
99
+ framework: "vision-sdk"
100
+ }
101
+ });
102
+ }
103
+ const vision = visionInstance;
104
+ return async (c, next) => {
105
+ if (c.req.method === "OPTIONS") {
106
+ return next();
107
+ }
108
+ const startTime = Date.now();
109
+ const trace = vision.createTrace(c.req.method, c.req.path);
110
+ return visionContext.run({ vision, traceId: trace.id, rootSpanId: "" }, async () => {
111
+ const tracer = vision.getTracer();
112
+ const rootSpan = tracer.startSpan("http.request", trace.id);
113
+ const ctx = visionContext.getStore();
114
+ if (ctx) {
115
+ ctx.rootSpanId = rootSpan.id;
116
+ }
117
+ tracer.setAttribute(rootSpan.id, "http.method", c.req.method);
118
+ tracer.setAttribute(rootSpan.id, "http.path", c.req.path);
119
+ tracer.setAttribute(rootSpan.id, "http.url", c.req.url);
120
+ const url = new URL(c.req.url);
121
+ if (url.search) {
122
+ tracer.setAttribute(rootSpan.id, "http.query", url.search);
123
+ }
124
+ try {
125
+ const rawReq = c.req.raw;
126
+ const headers = {};
127
+ rawReq.headers.forEach((v, k) => {
128
+ headers[k] = v;
129
+ });
130
+ const urlObj = new URL(c.req.url);
131
+ const query = {};
132
+ urlObj.searchParams.forEach((v, k) => {
133
+ query[k] = v;
134
+ });
135
+ let body = undefined;
136
+ const ct = headers["content-type"] || headers["Content-Type"];
137
+ if (ct && ct.includes("application/json")) {
138
+ try {
139
+ body = await rawReq.clone().json();
140
+ } catch {}
141
+ }
142
+ const sessionId = headers["x-vision-session"];
143
+ if (sessionId) {
144
+ tracer.setAttribute(rootSpan.id, "session.id", sessionId);
145
+ trace.metadata = { ...trace.metadata || {}, sessionId };
146
+ }
147
+ const requestMeta = {
148
+ method: c.req.method,
149
+ url: urlObj.pathname + (urlObj.search || ""),
150
+ headers,
151
+ query: Object.keys(query).length ? query : undefined,
152
+ body
153
+ };
154
+ tracer.setAttribute(rootSpan.id, "http.request", requestMeta);
155
+ trace.metadata = { ...trace.metadata || {}, request: requestMeta };
156
+ if (logging) {
157
+ const parts = [
158
+ `method=${c.req.method}`,
159
+ `path=${c.req.path}`
160
+ ];
161
+ if (sessionId)
162
+ parts.push(`sessionId=${sessionId}`);
163
+ parts.push(`traceId=${trace.id}`);
164
+ console.info(`INF starting request ${parts.join(" ")}`);
165
+ }
166
+ await next();
167
+ tracer.setAttribute(rootSpan.id, "http.status_code", c.res.status);
168
+ const resHeaders = {};
169
+ c.res.headers?.forEach((v, k) => {
170
+ resHeaders[k] = v;
171
+ });
172
+ let respBody = undefined;
173
+ const resCt = c.res.headers?.get("content-type") || "";
174
+ try {
175
+ const clone = c.res.clone();
176
+ if (resCt.includes("application/json")) {
177
+ const txt = await clone.text();
178
+ if (txt && txt.length <= 65536) {
179
+ try {
180
+ respBody = JSON.parse(txt);
181
+ } catch {
182
+ respBody = txt;
183
+ }
184
+ }
185
+ }
186
+ } catch {}
187
+ const responseMeta = {
188
+ status: c.res.status,
189
+ headers: Object.keys(resHeaders).length ? resHeaders : undefined,
190
+ body: respBody
191
+ };
192
+ tracer.setAttribute(rootSpan.id, "http.response", responseMeta);
193
+ trace.metadata = { ...trace.metadata || {}, response: responseMeta };
194
+ } catch (error) {
195
+ tracer.addEvent(rootSpan.id, "error", {
196
+ message: error instanceof Error ? error.message : "Unknown error",
197
+ stack: error instanceof Error ? error.stack : undefined
198
+ });
199
+ tracer.setAttribute(rootSpan.id, "error", true);
200
+ throw error;
201
+ } finally {
202
+ const completedSpan = tracer.endSpan(rootSpan.id);
203
+ if (completedSpan) {
204
+ vision.getTraceStore().addSpan(trace.id, completedSpan);
205
+ }
206
+ const duration = Date.now() - startTime;
207
+ vision.completeTrace(trace.id, c.res.status, duration);
208
+ c.header("X-Vision-Trace-Id", trace.id);
209
+ if (logging) {
210
+ console.info(`INF request completed code=${c.res.status} duration=${duration}ms method=${c.req.method} path=${c.req.path} traceId=${trace.id}`);
211
+ }
212
+ }
213
+ });
214
+ };
215
+ }
216
+ export {
217
+ useVisionSpan,
218
+ getVisionInstance,
219
+ getVisionContext,
220
+ createVisionMiddleware
221
+ };
222
+
223
+ //# debugId=569C5FECEB6F355164756E2164756E21
@@ -0,0 +1,10 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/vision.ts"],
4
+ "sourcesContent": [
5
+ "import type { Hono, Context, MiddlewareHandler } from 'hono'\nimport { VisionCore } from '@getvision/core'\nimport { AsyncLocalStorage } from 'async_hooks'\nimport { readFileSync, existsSync } from 'fs'\nimport { join } from 'path'\n\n/**\n * Vision context available in request handlers\n */\ninterface VisionContext {\n vision: VisionCore\n traceId: string\n rootSpanId: string\n}\n\nconst visionContext = new AsyncLocalStorage<VisionContext>()\n\n/**\n * Get Vision context (available in route handlers)\n * \n * @example\n * ```ts\n * const { vision, traceId } = getVisionContext()\n * const withSpan = vision.createSpanHelper(traceId)\n * ```\n */\nexport function getVisionContext(): VisionContext {\n const context = visionContext.getStore()\n if (!context) {\n throw new Error('Vision context not available. Make sure Vision is enabled.')\n }\n return context\n}\n\n/**\n * Create span helper using current trace context\n * \n * @example\n * ```ts\n * const withSpan = useVisionSpan()\n * const users = withSpan('db.select', { 'db.table': 'users' }, () => {\n * return db.select().from(users).all()\n * })\n * ```\n */\nexport function useVisionSpan() {\n const { vision, traceId, rootSpanId } = getVisionContext()\n const tracer = vision.getTracer()\n \n return <T>(\n name: string,\n attributes: Record<string, any> = {},\n fn: () => T\n ): T => {\n const span = tracer.startSpan(name, traceId, rootSpanId)\n \n for (const [key, value] of Object.entries(attributes)) {\n tracer.setAttribute(span.id, key, value)\n }\n \n try {\n const result = fn()\n const completedSpan = tracer.endSpan(span.id)\n \n if (completedSpan) {\n vision.getTraceStore().addSpan(traceId, completedSpan)\n }\n \n return result\n } catch (error) {\n tracer.setAttribute(span.id, 'error', true)\n tracer.setAttribute(\n span.id,\n 'error.message',\n error instanceof Error ? error.message : String(error)\n )\n const completedSpan = tracer.endSpan(span.id)\n \n if (completedSpan) {\n vision.getTraceStore().addSpan(traceId, completedSpan)\n }\n \n throw error\n }\n }\n}\n\n/**\n * Vision middleware options\n */\nexport interface VisionOptions {\n enabled?: boolean\n port?: number\n maxTraces?: number\n maxLogs?: number\n logging?: boolean\n service?: {\n name?: string\n version?: string\n description?: string\n }\n}\n\nlet visionInstance: VisionCore | null = null\n\n/**\n * Get Vision instance\n */\nexport function getVisionInstance(): VisionCore | null {\n return visionInstance\n}\n\n/**\n * Auto-detect package.json info\n */\nfunction autoDetectPackageInfo(): { name: string; version: string } {\n try {\n const pkgPath = join(process.cwd(), 'package.json')\n if (existsSync(pkgPath)) {\n const pkg = JSON.parse(readFileSync(pkgPath, 'utf-8'))\n return {\n name: pkg.name || 'unknown',\n version: pkg.version || '0.0.0',\n }\n }\n } catch (error) {\n // Ignore errors\n }\n return { name: 'unknown', version: '0.0.0' }\n}\n\n/**\n * Create Vision middleware for Hono\n * \n * This middleware automatically:\n * - Creates traces for all requests\n * - Adds request/response metadata\n * - Provides Vision context to handlers\n * - Broadcasts events to Vision Dashboard\n */\nexport function createVisionMiddleware(options: VisionOptions = {}): MiddlewareHandler {\n const { \n enabled = true, \n port = 9500, \n maxTraces = 1000,\n maxLogs = 10000,\n logging = true \n } = options\n\n if (!enabled) {\n return async (c, next) => await next()\n }\n\n // Initialize Vision Core once\n if (!visionInstance) {\n visionInstance = new VisionCore({ port, maxTraces, maxLogs })\n\n // Auto-detect service info\n const pkgInfo = autoDetectPackageInfo()\n const serviceName = options.service?.name || pkgInfo.name\n const serviceVersion = options.service?.version || pkgInfo.version\n\n // Set app status\n visionInstance.setAppStatus({\n name: serviceName,\n version: serviceVersion,\n description: options.service?.description,\n running: true,\n pid: process.pid,\n metadata: {\n framework: 'vision-sdk',\n },\n })\n }\n\n const vision = visionInstance\n\n // Middleware to trace requests\n return async (c: Context, next) => {\n // Skip OPTIONS requests\n if (c.req.method === 'OPTIONS') {\n return next()\n }\n\n const startTime = Date.now()\n \n // Create trace\n const trace = vision.createTrace(c.req.method, c.req.path)\n \n // Run request in AsyncLocalStorage context\n return visionContext.run({ vision, traceId: trace.id, rootSpanId: '' }, async () => {\n // Start main span\n const tracer = vision.getTracer()\n const rootSpan = tracer.startSpan('http.request', trace.id)\n \n // Update context with rootSpanId\n const ctx = visionContext.getStore()\n if (ctx) {\n ctx.rootSpanId = rootSpan.id\n }\n \n // Add request attributes\n tracer.setAttribute(rootSpan.id, 'http.method', c.req.method)\n tracer.setAttribute(rootSpan.id, 'http.path', c.req.path)\n tracer.setAttribute(rootSpan.id, 'http.url', c.req.url)\n \n // Add query params if any\n const url = new URL(c.req.url)\n if (url.search) {\n tracer.setAttribute(rootSpan.id, 'http.query', url.search)\n }\n\n // Capture request metadata\n try {\n const rawReq = c.req.raw\n const headers: Record<string, string> = {}\n rawReq.headers.forEach((v, k) => { headers[k] = v })\n \n const urlObj = new URL(c.req.url)\n const query: Record<string, string> = {}\n urlObj.searchParams.forEach((v, k) => { query[k] = v })\n\n let body: unknown = undefined\n const ct = headers['content-type'] || headers['Content-Type']\n if (ct && ct.includes('application/json')) {\n try {\n body = await rawReq.clone().json()\n } catch {}\n }\n\n const sessionId = headers['x-vision-session']\n if (sessionId) {\n tracer.setAttribute(rootSpan.id, 'session.id', sessionId)\n trace.metadata = { ...(trace.metadata || {}), sessionId }\n }\n\n const requestMeta = {\n method: c.req.method,\n url: urlObj.pathname + (urlObj.search || ''),\n headers,\n query: Object.keys(query).length ? query : undefined,\n body,\n }\n tracer.setAttribute(rootSpan.id, 'http.request', requestMeta)\n trace.metadata = { ...(trace.metadata || {}), request: requestMeta }\n\n // Emit start log\n if (logging) {\n const parts = [\n `method=${c.req.method}`,\n `path=${c.req.path}`,\n ]\n if (sessionId) parts.push(`sessionId=${sessionId}`)\n parts.push(`traceId=${trace.id}`)\n console.info(`INF starting request ${parts.join(' ')}`)\n }\n\n // Execute request\n await next()\n \n // Add response attributes\n tracer.setAttribute(rootSpan.id, 'http.status_code', c.res.status)\n const resHeaders: Record<string, string> = {}\n c.res.headers?.forEach((v, k) => { resHeaders[k] = v as unknown as string })\n\n let respBody: unknown = undefined\n const resCt = c.res.headers?.get('content-type') || ''\n try {\n const clone = c.res.clone()\n if (resCt.includes('application/json')) {\n const txt = await clone.text()\n if (txt && txt.length <= 65536) {\n try { respBody = JSON.parse(txt) } catch { respBody = txt }\n }\n }\n } catch {}\n\n const responseMeta = {\n status: c.res.status,\n headers: Object.keys(resHeaders).length ? resHeaders : undefined,\n body: respBody,\n }\n tracer.setAttribute(rootSpan.id, 'http.response', responseMeta)\n trace.metadata = { ...(trace.metadata || {}), response: responseMeta }\n \n } catch (error) {\n // Track error\n tracer.addEvent(rootSpan.id, 'error', {\n message: error instanceof Error ? error.message : 'Unknown error',\n stack: error instanceof Error ? error.stack : undefined,\n })\n \n tracer.setAttribute(rootSpan.id, 'error', true)\n throw error\n \n } finally {\n // End span and add it to trace\n const completedSpan = tracer.endSpan(rootSpan.id)\n if (completedSpan) {\n vision.getTraceStore().addSpan(trace.id, completedSpan)\n }\n \n // Complete trace\n const duration = Date.now() - startTime\n vision.completeTrace(trace.id, c.res.status, duration)\n \n // Add trace ID to response headers\n c.header('X-Vision-Trace-Id', trace.id)\n\n // Emit completion log\n if (logging) {\n console.info(\n `INF request completed code=${c.res.status} duration=${duration}ms method=${c.req.method} path=${c.req.path} traceId=${trace.id}`\n )\n }\n }\n })\n }\n}\n"
6
+ ],
7
+ "mappings": ";;;;;;;;;;;;;;;;;;;;AACA;AACA;AACA;AACA;AAWA,IAAM,gBAAgB,IAAI;AAWnB,SAAS,gBAAgB,GAAkB;AAAA,EAChD,MAAM,UAAU,cAAc,SAAS;AAAA,EACvC,IAAI,CAAC,SAAS;AAAA,IACZ,MAAM,IAAI,MAAM,4DAA4D;AAAA,EAC9E;AAAA,EACA,OAAO;AAAA;AAcF,SAAS,aAAa,GAAG;AAAA,EAC9B,QAAQ,QAAQ,SAAS,eAAe,iBAAiB;AAAA,EACzD,MAAM,SAAS,OAAO,UAAU;AAAA,EAEhC,OAAO,CACL,MACA,aAAkC,CAAC,GACnC,OACM;AAAA,IACN,MAAM,OAAO,OAAO,UAAU,MAAM,SAAS,UAAU;AAAA,IAEvD,YAAY,KAAK,UAAU,OAAO,QAAQ,UAAU,GAAG;AAAA,MACrD,OAAO,aAAa,KAAK,IAAI,KAAK,KAAK;AAAA,IACzC;AAAA,IAEA,IAAI;AAAA,MACF,MAAM,SAAS,GAAG;AAAA,MAClB,MAAM,gBAAgB,OAAO,QAAQ,KAAK,EAAE;AAAA,MAE5C,IAAI,eAAe;AAAA,QACjB,OAAO,cAAc,EAAE,QAAQ,SAAS,aAAa;AAAA,MACvD;AAAA,MAEA,OAAO;AAAA,MACP,OAAO,OAAO;AAAA,MACd,OAAO,aAAa,KAAK,IAAI,SAAS,IAAI;AAAA,MAC1C,OAAO,aACL,KAAK,IACL,iBACA,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CACvD;AAAA,MACA,MAAM,gBAAgB,OAAO,QAAQ,KAAK,EAAE;AAAA,MAE5C,IAAI,eAAe;AAAA,QACjB,OAAO,cAAc,EAAE,QAAQ,SAAS,aAAa;AAAA,MACvD;AAAA,MAEA,MAAM;AAAA;AAAA;AAAA;AAqBZ,IAAI,iBAAoC;AAKjC,SAAS,iBAAiB,GAAsB;AAAA,EACrD,OAAO;AAAA;AAMT,SAAS,qBAAqB,GAAsC;AAAA,EAClE,IAAI;AAAA,IACF,MAAM,UAAU,KAAK,QAAQ,IAAI,GAAG,cAAc;AAAA,IAClD,IAAI,WAAW,OAAO,GAAG;AAAA,MACvB,MAAM,MAAM,KAAK,MAAM,aAAa,SAAS,OAAO,CAAC;AAAA,MACrD,OAAO;AAAA,QACL,MAAM,IAAI,QAAQ;AAAA,QAClB,SAAS,IAAI,WAAW;AAAA,MAC1B;AAAA,IACF;AAAA,IACA,OAAO,OAAO;AAAA,EAGhB,OAAO,EAAE,MAAM,WAAW,SAAS,QAAQ;AAAA;AAYtC,SAAS,sBAAsB,CAAC,UAAyB,CAAC,GAAsB;AAAA,EACrF;AAAA,IACE,UAAU;AAAA,IACV,OAAO;AAAA,IACP,YAAY;AAAA,IACZ,UAAU;AAAA,IACV,UAAU;AAAA,MACR;AAAA,EAEJ,IAAI,CAAC,SAAS;AAAA,IACZ,OAAO,OAAO,GAAG,SAAS,MAAM,KAAK;AAAA,EACvC;AAAA,EAGA,IAAI,CAAC,gBAAgB;AAAA,IACnB,iBAAiB,IAAI,WAAW,EAAE,MAAM,WAAW,QAAQ,CAAC;AAAA,IAG5D,MAAM,UAAU,sBAAsB;AAAA,IACtC,MAAM,cAAc,QAAQ,SAAS,QAAQ,QAAQ;AAAA,IACrD,MAAM,iBAAiB,QAAQ,SAAS,WAAW,QAAQ;AAAA,IAG3D,eAAe,aAAa;AAAA,MAC1B,MAAM;AAAA,MACN,SAAS;AAAA,MACT,aAAa,QAAQ,SAAS;AAAA,MAC9B,SAAS;AAAA,MACT,KAAK,QAAQ;AAAA,MACb,UAAU;AAAA,QACR,WAAW;AAAA,MACb;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,SAAS;AAAA,EAGf,OAAO,OAAO,GAAY,SAAS;AAAA,IAEjC,IAAI,EAAE,IAAI,WAAW,WAAW;AAAA,MAC9B,OAAO,KAAK;AAAA,IACd;AAAA,IAEA,MAAM,YAAY,KAAK,IAAI;AAAA,IAG3B,MAAM,QAAQ,OAAO,YAAY,EAAE,IAAI,QAAQ,EAAE,IAAI,IAAI;AAAA,IAGzD,OAAO,cAAc,IAAI,EAAE,QAAQ,SAAS,MAAM,IAAI,YAAY,GAAG,GAAG,YAAY;AAAA,MAElF,MAAM,SAAS,OAAO,UAAU;AAAA,MAChC,MAAM,WAAW,OAAO,UAAU,gBAAgB,MAAM,EAAE;AAAA,MAG1D,MAAM,MAAM,cAAc,SAAS;AAAA,MACnC,IAAI,KAAK;AAAA,QACP,IAAI,aAAa,SAAS;AAAA,MAC5B;AAAA,MAGA,OAAO,aAAa,SAAS,IAAI,eAAe,EAAE,IAAI,MAAM;AAAA,MAC5D,OAAO,aAAa,SAAS,IAAI,aAAa,EAAE,IAAI,IAAI;AAAA,MACxD,OAAO,aAAa,SAAS,IAAI,YAAY,EAAE,IAAI,GAAG;AAAA,MAGtD,MAAM,MAAM,IAAI,IAAI,EAAE,IAAI,GAAG;AAAA,MAC7B,IAAI,IAAI,QAAQ;AAAA,QACd,OAAO,aAAa,SAAS,IAAI,cAAc,IAAI,MAAM;AAAA,MAC3D;AAAA,MAGA,IAAI;AAAA,QACF,MAAM,SAAS,EAAE,IAAI;AAAA,QACrB,MAAM,UAAkC,CAAC;AAAA,QACzC,OAAO,QAAQ,QAAQ,CAAC,GAAG,MAAM;AAAA,UAAE,QAAQ,KAAK;AAAA,SAAG;AAAA,QAEnD,MAAM,SAAS,IAAI,IAAI,EAAE,IAAI,GAAG;AAAA,QAChC,MAAM,QAAgC,CAAC;AAAA,QACvC,OAAO,aAAa,QAAQ,CAAC,GAAG,MAAM;AAAA,UAAE,MAAM,KAAK;AAAA,SAAG;AAAA,QAEtD,IAAI,OAAgB;AAAA,QACpB,MAAM,KAAK,QAAQ,mBAAmB,QAAQ;AAAA,QAC9C,IAAI,MAAM,GAAG,SAAS,kBAAkB,GAAG;AAAA,UACzC,IAAI;AAAA,YACF,OAAO,MAAM,OAAO,MAAM,EAAE,KAAK;AAAA,YACjC,MAAM;AAAA,QACV;AAAA,QAEA,MAAM,YAAY,QAAQ;AAAA,QAC1B,IAAI,WAAW;AAAA,UACb,OAAO,aAAa,SAAS,IAAI,cAAc,SAAS;AAAA,UACxD,MAAM,WAAW,KAAM,MAAM,YAAY,CAAC,GAAI,UAAU;AAAA,QAC1D;AAAA,QAEA,MAAM,cAAc;AAAA,UAClB,QAAQ,EAAE,IAAI;AAAA,UACd,KAAK,OAAO,YAAY,OAAO,UAAU;AAAA,UACzC;AAAA,UACA,OAAO,OAAO,KAAK,KAAK,EAAE,SAAS,QAAQ;AAAA,UAC3C;AAAA,QACF;AAAA,QACA,OAAO,aAAa,SAAS,IAAI,gBAAgB,WAAW;AAAA,QAC5D,MAAM,WAAW,KAAM,MAAM,YAAY,CAAC,GAAI,SAAS,YAAY;AAAA,QAGnE,IAAI,SAAS;AAAA,UACX,MAAM,QAAQ;AAAA,YACZ,UAAU,EAAE,IAAI;AAAA,YAChB,QAAQ,EAAE,IAAI;AAAA,UAChB;AAAA,UACA,IAAI;AAAA,YAAW,MAAM,KAAK,aAAa,WAAW;AAAA,UAClD,MAAM,KAAK,WAAW,MAAM,IAAI;AAAA,UAChC,QAAQ,KAAK,wBAAwB,MAAM,KAAK,GAAG,GAAG;AAAA,QACxD;AAAA,QAGA,MAAM,KAAK;AAAA,QAGX,OAAO,aAAa,SAAS,IAAI,oBAAoB,EAAE,IAAI,MAAM;AAAA,QACjE,MAAM,aAAqC,CAAC;AAAA,QAC5C,EAAE,IAAI,SAAS,QAAQ,CAAC,GAAG,MAAM;AAAA,UAAE,WAAW,KAAK;AAAA,SAAwB;AAAA,QAE3E,IAAI,WAAoB;AAAA,QACxB,MAAM,QAAQ,EAAE,IAAI,SAAS,IAAI,cAAc,KAAK;AAAA,QACpD,IAAI;AAAA,UACF,MAAM,QAAQ,EAAE,IAAI,MAAM;AAAA,UAC1B,IAAI,MAAM,SAAS,kBAAkB,GAAG;AAAA,YACtC,MAAM,MAAM,MAAM,MAAM,KAAK;AAAA,YAC7B,IAAI,OAAO,IAAI,UAAU,OAAO;AAAA,cAC9B,IAAI;AAAA,gBAAE,WAAW,KAAK,MAAM,GAAG;AAAA,gBAAI,MAAM;AAAA,gBAAE,WAAW;AAAA;AAAA,YACxD;AAAA,UACF;AAAA,UACA,MAAM;AAAA,QAER,MAAM,eAAe;AAAA,UACnB,QAAQ,EAAE,IAAI;AAAA,UACd,SAAS,OAAO,KAAK,UAAU,EAAE,SAAS,aAAa;AAAA,UACvD,MAAM;AAAA,QACR;AAAA,QACA,OAAO,aAAa,SAAS,IAAI,iBAAiB,YAAY;AAAA,QAC9D,MAAM,WAAW,KAAM,MAAM,YAAY,CAAC,GAAI,UAAU,aAAa;AAAA,QAErE,OAAO,OAAO;AAAA,QAEd,OAAO,SAAS,SAAS,IAAI,SAAS;AAAA,UACpC,SAAS,iBAAiB,QAAQ,MAAM,UAAU;AAAA,UAClD,OAAO,iBAAiB,QAAQ,MAAM,QAAQ;AAAA,QAChD,CAAC;AAAA,QAED,OAAO,aAAa,SAAS,IAAI,SAAS,IAAI;AAAA,QAC9C,MAAM;AAAA,gBAEN;AAAA,QAEA,MAAM,gBAAgB,OAAO,QAAQ,SAAS,EAAE;AAAA,QAChD,IAAI,eAAe;AAAA,UACjB,OAAO,cAAc,EAAE,QAAQ,MAAM,IAAI,aAAa;AAAA,QACxD;AAAA,QAGA,MAAM,WAAW,KAAK,IAAI,IAAI;AAAA,QAC9B,OAAO,cAAc,MAAM,IAAI,EAAE,IAAI,QAAQ,QAAQ;AAAA,QAGrD,EAAE,OAAO,qBAAqB,MAAM,EAAE;AAAA,QAGtC,IAAI,SAAS;AAAA,UACX,QAAQ,KACN,8BAA8B,EAAE,IAAI,mBAAmB,qBAAqB,EAAE,IAAI,eAAe,EAAE,IAAI,gBAAgB,MAAM,IAC/H;AAAA,QACF;AAAA;AAAA,KAEH;AAAA;AAAA;",
8
+ "debugId": "569C5FECEB6F355164756E2164756E21",
9
+ "names": []
10
+ }
package/package.json CHANGED
@@ -1,14 +1,24 @@
1
1
  {
2
2
  "name": "@getvision/server",
3
- "version": "0.4.3-d4c761e-develop",
3
+ "version": "0.4.4-44d79d9-develop",
4
4
  "type": "module",
5
5
  "description": "Vision Server - Meta-framework with built-in observability, pub/sub, and type-safe APIs",
6
+ "main": "./dist/index.js",
7
+ "types": "./dist/index.d.ts",
6
8
  "exports": {
7
- ".": "./src/index.ts"
9
+ ".": {
10
+ "types": "./dist/index.d.ts",
11
+ "default": "./dist/index.js"
12
+ }
8
13
  },
14
+ "files": [
15
+ "dist",
16
+ "README.md",
17
+ "CHANGELOG.md"
18
+ ],
9
19
  "scripts": {
10
20
  "dev": "tsc --watch",
11
- "build": "tsc --noEmit",
21
+ "build": "tsc --emitDeclarationOnly && bun build ./src/*.ts --outdir ./dist --target node --format esm --external '*' --sourcemap=external",
12
22
  "lint": "eslint . --max-warnings 0"
13
23
  },
14
24
  "license": "MIT",
package/.env.example DELETED
@@ -1,3 +0,0 @@
1
- # Vision Server
2
- VISION_PORT=9500
3
- NODE_ENV=development
package/.eslintrc.cjs DELETED
@@ -1,7 +0,0 @@
1
- module.exports = {
2
- extends: ['@repo/eslint-config/library.js'],
3
- parser: '@typescript-eslint/parser',
4
- parserOptions: {
5
- project: true,
6
- },
7
- }
@@ -1 +0,0 @@
1
- $ tsc --noEmit