@runtimescope/server-sdk 0.6.2 → 0.7.0

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/transport.ts","../src/utils/id.ts","../src/utils/stack.ts","../src/sampler.ts","../src/utils/sql-parser.ts","../src/utils/log.ts","../src/integrations/prisma.ts","../src/integrations/pg.ts","../src/integrations/knex.ts","../src/integrations/drizzle.ts","../src/integrations/mysql2.ts","../src/integrations/better-sqlite3.ts","../src/utils/serialize.ts","../src/context.ts","../src/interceptors/console.ts","../src/interceptors/errors.ts","../src/interceptors/http.ts","../src/interceptors/perf-metrics.ts","../src/interceptors/middleware.ts","../src/index.ts"],"sourcesContent":["import WebSocket from 'ws';\nimport type { ServerRuntimeEvent, WSMessage } from './types.js';\n\nexport class ServerTransport {\n private ws: WebSocket | null = null;\n private url: string;\n private sessionId: string;\n private appName: string;\n private sdkVersion: string;\n private queue: ServerRuntimeEvent[] = [];\n private maxQueueSize: number;\n private _droppedCount = 0;\n private reconnectTimer: ReturnType<typeof setTimeout> | null = null;\n private connected = false;\n private flushTimer: ReturnType<typeof setInterval> | null = null;\n\n private authToken: string | undefined;\n private authFailed = false;\n\n constructor(options: {\n url: string;\n sessionId: string;\n appName: string;\n sdkVersion: string;\n authToken?: string;\n maxQueueSize?: number;\n }) {\n this.url = options.url;\n this.sessionId = options.sessionId;\n this.appName = options.appName;\n this.sdkVersion = options.sdkVersion;\n this.authToken = options.authToken;\n this.maxQueueSize = options.maxQueueSize ?? 10_000;\n }\n\n get droppedCount(): number {\n return this._droppedCount;\n }\n\n connect(): void {\n if (this.authFailed) return; // Don't reconnect after auth rejection\n\n try {\n this.ws = new WebSocket(this.url);\n\n this.ws.on('open', () => {\n this.connected = true;\n this.sendHandshake();\n this.flushQueue();\n\n // Start periodic flush\n this.flushTimer = setInterval(() => this.flushQueue(), 100);\n });\n\n this.ws.on('message', (data: Buffer) => {\n try {\n const msg = JSON.parse(data.toString());\n if (msg.type === 'error' && msg.payload?.code === 'AUTH_FAILED') {\n console.error('[RuntimeScope] Authentication failed — stopping reconnection');\n this.authFailed = true;\n }\n } catch { /* ignore */ }\n });\n\n this.ws.on('close', () => {\n this.connected = false;\n this.cleanup();\n if (!this.authFailed) this.scheduleReconnect();\n });\n\n this.ws.on('error', () => {\n this.connected = false;\n this.cleanup();\n if (!this.authFailed) this.scheduleReconnect();\n });\n } catch {\n this.scheduleReconnect();\n }\n }\n\n private cleanup(): void {\n if (this.flushTimer) {\n clearInterval(this.flushTimer);\n this.flushTimer = null;\n }\n }\n\n private scheduleReconnect(): void {\n if (this.reconnectTimer) return;\n this.reconnectTimer = setTimeout(() => {\n this.reconnectTimer = null;\n this.connect();\n }, 3000);\n }\n\n private sendHandshake(): void {\n this.send({\n type: 'handshake',\n payload: {\n appName: this.appName,\n sdkVersion: this.sdkVersion,\n sessionId: this.sessionId,\n ...(this.authToken ? { authToken: this.authToken } : {}),\n },\n timestamp: Date.now(),\n sessionId: this.sessionId,\n });\n }\n\n sendEvent(event: ServerRuntimeEvent): void {\n // Enforce queue cap — drop oldest events when full\n if (this.queue.length >= this.maxQueueSize) {\n this.queue.shift();\n this._droppedCount++;\n }\n this.queue.push(event);\n if (this.connected && this.queue.length >= 10) {\n this.flushQueue();\n }\n }\n\n private flushQueue(): void {\n if (!this.connected || this.queue.length === 0) return;\n\n const batch = this.queue.splice(0);\n this.send({\n type: 'event',\n payload: { events: batch },\n timestamp: Date.now(),\n sessionId: this.sessionId,\n });\n }\n\n private send(msg: WSMessage): void {\n if (this.ws?.readyState === WebSocket.OPEN) {\n try {\n this.ws.send(JSON.stringify(msg));\n } catch {\n // Connection may have closed between check and send\n }\n }\n }\n\n disconnect(): void {\n if (this.reconnectTimer) {\n clearTimeout(this.reconnectTimer);\n this.reconnectTimer = null;\n }\n this.cleanup();\n this.flushQueue();\n if (this.ws) {\n this.ws.close();\n this.ws = null;\n }\n this.connected = false;\n }\n}\n","import { randomBytes } from 'node:crypto';\n\nexport function generateId(): string {\n return randomBytes(16).toString('hex');\n}\n\nexport function generateSessionId(): string {\n return `srv-${randomBytes(8).toString('hex')}`;\n}\n","const INTERNAL_FRAMES = [\n 'RuntimeScope',\n 'server-sdk',\n 'captureQuery',\n 'instrumentPrisma',\n 'instrumentDrizzle',\n 'instrumentKnex',\n 'instrumentPg',\n 'instrumentMysql2',\n 'instrumentBetterSqlite3',\n];\n\nexport function captureStack(skipFrames = 3): string {\n const err = new Error();\n const stack = err.stack ?? '';\n const lines = stack.split('\\n').slice(skipFrames);\n\n // Filter out internal frames\n const filtered = lines.filter(\n (line) => !INTERNAL_FRAMES.some((frame) => line.includes(frame))\n );\n\n return filtered.slice(0, 10).join('\\n');\n}\n","import type { ServerRuntimeEvent } from './types.js';\n\nexport interface SamplerConfig {\n /** Probabilistic sample rate: 0.0–1.0 (default: 1.0 = keep all) */\n sampleRate?: number;\n /** Max events per second before dropping (default: unlimited) */\n maxEventsPerSecond?: number;\n}\n\nexport class Sampler {\n private windowCount = 0;\n private windowStart = Date.now();\n private _droppedCount = 0;\n\n constructor(private config: SamplerConfig) {}\n\n get droppedCount(): number {\n return this._droppedCount;\n }\n\n shouldSample(_event: ServerRuntimeEvent): boolean {\n // 1. Probabilistic sampling\n const rate = this.config.sampleRate;\n if (rate !== undefined && rate < 1) {\n if (Math.random() > rate) {\n this._droppedCount++;\n return false;\n }\n }\n\n // 2. Rate limiting (1-second sliding window)\n const maxPerSec = this.config.maxEventsPerSecond;\n if (maxPerSec !== undefined) {\n const now = Date.now();\n if (now - this.windowStart >= 1000) {\n this.windowCount = 0;\n this.windowStart = now;\n }\n if (this.windowCount >= maxPerSec) {\n this._droppedCount++;\n return false;\n }\n this.windowCount++;\n }\n\n return true;\n }\n\n reset(): void {\n this.windowCount = 0;\n this.windowStart = Date.now();\n this._droppedCount = 0;\n }\n}\n","import type { DatabaseOperation } from '../types.js';\n\nconst OPERATION_RE = /^\\s*(SELECT|INSERT|UPDATE|DELETE|CREATE|DROP|ALTER|TRUNCATE|WITH)\\b/i;\nconst TABLE_RE = /\\b(?:FROM|JOIN|INTO|UPDATE|TABLE)\\s+[\"'`]?(\\w+)[\"'`]?/gi;\nconst PARAM_RE = /\\$\\d+|\\?|:\\w+/g;\nconst STRING_LITERAL_RE = /'[^']*'/g;\nconst NUMBER_LITERAL_RE = /\\b\\d+\\.?\\d*\\b/g;\n\nexport function parseOperation(query: string): DatabaseOperation {\n const match = query.match(OPERATION_RE);\n if (!match) return 'OTHER';\n const op = match[1].toUpperCase();\n if (op === 'SELECT' || op === 'WITH') return 'SELECT';\n if (op === 'INSERT') return 'INSERT';\n if (op === 'UPDATE') return 'UPDATE';\n if (op === 'DELETE') return 'DELETE';\n return 'OTHER';\n}\n\nexport function parseTablesAccessed(query: string): string[] {\n const tables = new Set<string>();\n let match: RegExpExecArray | null;\n const re = new RegExp(TABLE_RE.source, TABLE_RE.flags);\n while ((match = re.exec(query)) !== null) {\n const table = match[1].toLowerCase();\n // Skip SQL keywords that might be false positives\n if (!['select', 'where', 'and', 'or', 'not', 'null', 'set', 'values'].includes(table)) {\n tables.add(table);\n }\n }\n return [...tables];\n}\n\nexport function normalizeQuery(query: string): string {\n return query\n .replace(STRING_LITERAL_RE, '?')\n .replace(NUMBER_LITERAL_RE, '?')\n .replace(PARAM_RE, '?')\n .replace(/\\s+/g, ' ')\n .trim();\n}\n\nexport function redactParams(params: unknown[]): string {\n return JSON.stringify(\n params.map((p) => {\n if (p === null) return 'NULL';\n if (typeof p === 'string') return '<string>';\n if (typeof p === 'number') return '<number>';\n if (typeof p === 'boolean') return '<boolean>';\n if (p instanceof Date) return '<date>';\n if (Buffer.isBuffer(p)) return '<buffer>';\n return '<object>';\n })\n );\n}\n","// Save original console methods BEFORE any interceptors patch them.\n// Used for SDK-internal logging to avoid recursion.\nexport const _log = {\n log: console.log.bind(console),\n warn: console.warn.bind(console),\n error: console.error.bind(console),\n debug: console.debug.bind(console),\n};\n","import type { DatabaseEvent, DatabaseSource } from '../types.js';\nimport { generateId } from '../utils/id.js';\nimport { parseOperation, parseTablesAccessed, normalizeQuery, redactParams } from '../utils/sql-parser.js';\nimport { captureStack } from '../utils/stack.js';\nimport { _log } from '../utils/log.js';\n\nexport interface PrismaInstrumentOptions {\n sessionId: string;\n captureStackTraces?: boolean;\n redact?: boolean;\n onEvent: (event: DatabaseEvent) => void;\n}\n\n/**\n * Instrument a Prisma client to capture database queries.\n * Supports both Prisma v4 ($on) and v5+ ($extends).\n * Returns a restore function to remove instrumentation.\n */\nexport function instrumentPrisma(\n client: unknown,\n options: PrismaInstrumentOptions\n): () => void {\n const prisma = client as Record<string, unknown>;\n const source: DatabaseSource = 'prisma';\n\n // Try v5+ $extends approach first\n if (typeof prisma.$extends === 'function') {\n // $extends returns a new client, so we monkey-patch query methods\n // For v5, we use the middleware-like $allOperations\n try {\n const extended = (prisma.$extends as Function)({\n query: {\n $allOperations({ operation, model, args, query }: {\n operation: string;\n model: string;\n args: unknown;\n query: (args: unknown) => Promise<unknown>;\n }) {\n const start = performance.now();\n return (query as Function)(args).then((result: unknown) => {\n const duration = performance.now() - start;\n const queryStr = `prisma.${model}.${operation}(${JSON.stringify(args).slice(0, 200)})`;\n options.onEvent({\n eventId: generateId(),\n sessionId: options.sessionId,\n timestamp: Date.now(),\n eventType: 'database',\n query: queryStr,\n normalizedQuery: `prisma.${model}.${operation}(?)`,\n duration,\n tablesAccessed: model ? [model.toLowerCase()] : [],\n operation: mapPrismaOperation(operation),\n source,\n stackTrace: options.captureStackTraces ? captureStack() : undefined,\n rowsReturned: Array.isArray(result) ? result.length : undefined,\n });\n return result;\n }).catch((err: Error) => {\n const duration = performance.now() - start;\n const queryStr = `prisma.${model}.${operation}(${JSON.stringify(args).slice(0, 200)})`;\n options.onEvent({\n eventId: generateId(),\n sessionId: options.sessionId,\n timestamp: Date.now(),\n eventType: 'database',\n query: queryStr,\n normalizedQuery: `prisma.${model}.${operation}(?)`,\n duration,\n tablesAccessed: model ? [model.toLowerCase()] : [],\n operation: mapPrismaOperation(operation),\n source,\n error: err.message,\n stackTrace: options.captureStackTraces ? captureStack() : undefined,\n });\n throw err;\n });\n },\n },\n });\n // Copy the extended client's methods back (this is a best-effort approach)\n Object.assign(prisma, extended);\n return () => {\n // $extends creates a new client; there's no clean undo for v5\n };\n } catch {\n // Fall through to $on approach\n }\n }\n\n // v4 approach: $on('query')\n if (typeof prisma.$on === 'function') {\n (prisma.$on as Function)('query', (e: {\n query: string;\n params: string;\n duration: number;\n target: string;\n }) => {\n options.onEvent({\n eventId: generateId(),\n sessionId: options.sessionId,\n timestamp: Date.now(),\n eventType: 'database',\n query: e.query,\n normalizedQuery: normalizeQuery(e.query),\n duration: e.duration,\n tablesAccessed: parseTablesAccessed(e.query),\n operation: parseOperation(e.query),\n source,\n params: options.redact !== false ? redactParams(JSON.parse(e.params || '[]')) : e.params,\n stackTrace: options.captureStackTraces ? captureStack() : undefined,\n });\n });\n return () => {\n // $on doesn't provide a clean unsubscribe for v4\n };\n }\n\n _log.warn('[RuntimeScope] Prisma client does not support $on or $extends');\n return () => {};\n}\n\nfunction mapPrismaOperation(op: string): DatabaseEvent['operation'] {\n const lower = op.toLowerCase();\n if (lower.includes('find') || lower === 'aggregate' || lower === 'count' || lower === 'groupby') return 'SELECT';\n if (lower.includes('create') || lower === 'createMany') return 'INSERT';\n if (lower.includes('update') || lower === 'upsert') return 'UPDATE';\n if (lower.includes('delete')) return 'DELETE';\n return 'OTHER';\n}\n","import type { DatabaseEvent } from '../types.js';\nimport { generateId } from '../utils/id.js';\nimport { parseOperation, parseTablesAccessed, normalizeQuery, redactParams } from '../utils/sql-parser.js';\nimport { captureStack } from '../utils/stack.js';\nimport { _log } from '../utils/log.js';\n\nexport interface PgInstrumentOptions {\n sessionId: string;\n captureStackTraces?: boolean;\n redact?: boolean;\n onEvent: (event: DatabaseEvent) => void;\n}\n\n/**\n * Instrument a pg Pool or Client to capture database queries.\n * Wraps the query method to intercept all SQL execution.\n */\nexport function instrumentPg(\n pool: unknown,\n options: PgInstrumentOptions\n): () => void {\n const client = pool as Record<string, unknown>;\n const originalQuery = client.query as Function;\n\n if (typeof originalQuery !== 'function') {\n _log.warn('[RuntimeScope] pg client does not have a query method');\n return () => {};\n }\n\n client.query = function (...args: unknown[]) {\n const start = performance.now();\n let queryText = '';\n let params: unknown[] | undefined;\n\n // pg.query supports multiple signatures\n if (typeof args[0] === 'string') {\n queryText = args[0];\n if (Array.isArray(args[1])) params = args[1];\n } else if (typeof args[0] === 'object' && args[0] !== null) {\n const config = args[0] as Record<string, unknown>;\n queryText = (config.text as string) ?? '';\n params = config.values as unknown[] | undefined;\n }\n\n const result = originalQuery.apply(this, args);\n\n if (result && typeof (result as Promise<unknown>).then === 'function') {\n return (result as Promise<unknown>).then((res: unknown) => {\n const duration = performance.now() - start;\n const pgResult = res as { rowCount?: number; rows?: unknown[] };\n options.onEvent({\n eventId: generateId(),\n sessionId: options.sessionId,\n timestamp: Date.now(),\n eventType: 'database',\n query: queryText,\n normalizedQuery: normalizeQuery(queryText),\n duration,\n rowsReturned: pgResult.rows?.length,\n rowsAffected: pgResult.rowCount ?? undefined,\n tablesAccessed: parseTablesAccessed(queryText),\n operation: parseOperation(queryText),\n source: 'pg',\n params: params && options.redact !== false ? redactParams(params) : undefined,\n stackTrace: options.captureStackTraces ? captureStack() : undefined,\n });\n return res;\n }).catch((err: Error) => {\n const duration = performance.now() - start;\n options.onEvent({\n eventId: generateId(),\n sessionId: options.sessionId,\n timestamp: Date.now(),\n eventType: 'database',\n query: queryText,\n normalizedQuery: normalizeQuery(queryText),\n duration,\n tablesAccessed: parseTablesAccessed(queryText),\n operation: parseOperation(queryText),\n source: 'pg',\n error: err.message,\n params: params && options.redact !== false ? redactParams(params) : undefined,\n stackTrace: options.captureStackTraces ? captureStack() : undefined,\n });\n throw err;\n });\n }\n\n return result;\n };\n\n return () => {\n client.query = originalQuery;\n };\n}\n","import type { DatabaseEvent } from '../types.js';\nimport { generateId } from '../utils/id.js';\nimport { parseOperation, parseTablesAccessed, normalizeQuery, redactParams } from '../utils/sql-parser.js';\nimport { captureStack } from '../utils/stack.js';\n\nexport interface KnexInstrumentOptions {\n sessionId: string;\n captureStackTraces?: boolean;\n redact?: boolean;\n onEvent: (event: DatabaseEvent) => void;\n}\n\n/**\n * Instrument a Knex instance to capture database queries.\n * Uses Knex's built-in event system (query, query-response, query-error).\n */\nexport function instrumentKnex(\n knex: unknown,\n options: KnexInstrumentOptions\n): () => void {\n const instance = knex as {\n on: (event: string, handler: (...args: unknown[]) => void) => void;\n removeListener: (event: string, handler: (...args: unknown[]) => void) => void;\n };\n\n const pendingQueries = new Map<string, { query: string; params: unknown[]; start: number }>();\n\n const onQuery = (data: { __knexQueryUid: string; sql: string; bindings: unknown[] }) => {\n pendingQueries.set(data.__knexQueryUid, {\n query: data.sql,\n params: data.bindings ?? [],\n start: performance.now(),\n });\n };\n\n const onQueryResponse = (_response: unknown, data: { __knexQueryUid: string; sql: string; bindings: unknown[] }, _builder: unknown) => {\n const pending = pendingQueries.get(data.__knexQueryUid);\n pendingQueries.delete(data.__knexQueryUid);\n const duration = pending ? performance.now() - pending.start : 0;\n const queryText = pending?.query ?? data.sql;\n const params = pending?.params ?? data.bindings;\n\n const rows = Array.isArray(_response) ? _response.length : undefined;\n\n options.onEvent({\n eventId: generateId(),\n sessionId: options.sessionId,\n timestamp: Date.now(),\n eventType: 'database',\n query: queryText,\n normalizedQuery: normalizeQuery(queryText),\n duration,\n rowsReturned: rows,\n tablesAccessed: parseTablesAccessed(queryText),\n operation: parseOperation(queryText),\n source: 'knex',\n params: params.length > 0 && options.redact !== false ? redactParams(params) : undefined,\n stackTrace: options.captureStackTraces ? captureStack() : undefined,\n });\n };\n\n const onQueryError = (error: Error, data: { __knexQueryUid: string; sql: string; bindings: unknown[] }) => {\n const pending = pendingQueries.get(data.__knexQueryUid);\n pendingQueries.delete(data.__knexQueryUid);\n const duration = pending ? performance.now() - pending.start : 0;\n const queryText = pending?.query ?? data.sql;\n const params = pending?.params ?? data.bindings;\n\n options.onEvent({\n eventId: generateId(),\n sessionId: options.sessionId,\n timestamp: Date.now(),\n eventType: 'database',\n query: queryText,\n normalizedQuery: normalizeQuery(queryText),\n duration,\n tablesAccessed: parseTablesAccessed(queryText),\n operation: parseOperation(queryText),\n source: 'knex',\n error: error.message,\n params: params.length > 0 && options.redact !== false ? redactParams(params) : undefined,\n stackTrace: options.captureStackTraces ? captureStack() : undefined,\n });\n };\n\n instance.on('query', onQuery as (...args: unknown[]) => void);\n instance.on('query-response', onQueryResponse as (...args: unknown[]) => void);\n instance.on('query-error', onQueryError as (...args: unknown[]) => void);\n\n return () => {\n instance.removeListener('query', onQuery as (...args: unknown[]) => void);\n instance.removeListener('query-response', onQueryResponse as (...args: unknown[]) => void);\n instance.removeListener('query-error', onQueryError as (...args: unknown[]) => void);\n pendingQueries.clear();\n };\n}\n","import type { DatabaseEvent } from '../types.js';\nimport { generateId } from '../utils/id.js';\nimport { parseOperation, parseTablesAccessed, normalizeQuery, redactParams } from '../utils/sql-parser.js';\nimport { captureStack } from '../utils/stack.js';\nimport { _log } from '../utils/log.js';\n\nexport interface DrizzleInstrumentOptions {\n sessionId: string;\n captureStackTraces?: boolean;\n redact?: boolean;\n onEvent: (event: DatabaseEvent) => void;\n}\n\n/**\n * Instrument a Drizzle ORM database instance.\n * Wraps the session's execute method to capture query timing and results.\n * Falls back to wrapping the underlying driver's query method if execute\n * is not available.\n */\nexport function instrumentDrizzle(\n db: unknown,\n options: DrizzleInstrumentOptions\n): () => void {\n const drizzleDb = db as Record<string, unknown>;\n\n // Drizzle stores internals under db._ (session, schema, etc.)\n const internals = drizzleDb._ as Record<string, unknown> | undefined;\n if (!internals) {\n _log.warn('[RuntimeScope] Drizzle db does not have internals (_). Cannot instrument.');\n return () => {};\n }\n\n const session = internals.session as Record<string, unknown> | undefined;\n if (!session) {\n _log.warn('[RuntimeScope] Drizzle db does not have a session. Cannot instrument.');\n return () => {};\n }\n\n // Strategy: wrap session.execute() which runs the actual SQL\n const originalExecute = session.execute as Function | undefined;\n\n if (typeof originalExecute === 'function') {\n session.execute = function (this: unknown, queryOrSql: unknown) {\n const start = performance.now();\n let queryText = '';\n let params: unknown[] | undefined;\n\n // Drizzle passes a query object with sql and params properties\n if (queryOrSql && typeof queryOrSql === 'object') {\n const q = queryOrSql as Record<string, unknown>;\n queryText = (q.sql as string) ?? (q.query as string) ?? String(queryOrSql);\n params = q.params as unknown[] | undefined;\n } else if (typeof queryOrSql === 'string') {\n queryText = queryOrSql;\n }\n\n const stack = options.captureStackTraces ? captureStack() : undefined;\n\n const result = originalExecute.apply(this, arguments);\n\n // Handle promise (async queries)\n if (result && typeof (result as Promise<unknown>).then === 'function') {\n return (result as Promise<unknown>).then((res: unknown) => {\n const duration = performance.now() - start;\n const rows = Array.isArray(res) ? res.length : undefined;\n\n options.onEvent({\n eventId: generateId(),\n sessionId: options.sessionId,\n timestamp: Date.now(),\n eventType: 'database',\n query: queryText,\n normalizedQuery: normalizeQuery(queryText),\n duration,\n rowsReturned: rows,\n tablesAccessed: parseTablesAccessed(queryText),\n operation: parseOperation(queryText),\n source: 'drizzle',\n params: params && options.redact !== false ? redactParams(params) : undefined,\n stackTrace: stack,\n });\n return res;\n }).catch((err: Error) => {\n const duration = performance.now() - start;\n options.onEvent({\n eventId: generateId(),\n sessionId: options.sessionId,\n timestamp: Date.now(),\n eventType: 'database',\n query: queryText,\n normalizedQuery: normalizeQuery(queryText),\n duration,\n tablesAccessed: parseTablesAccessed(queryText),\n operation: parseOperation(queryText),\n source: 'drizzle',\n error: err.message,\n params: params && options.redact !== false ? redactParams(params) : undefined,\n stackTrace: stack,\n });\n throw err;\n });\n }\n\n return result;\n };\n\n return () => {\n session.execute = originalExecute;\n };\n }\n\n // Fallback: instrument the underlying client's query method\n const client = (session as Record<string, unknown>).client as Record<string, unknown> | undefined;\n const originalQuery = client?.query as Function | undefined;\n\n if (client && typeof originalQuery === 'function') {\n client.query = function (this: unknown, ...args: unknown[]) {\n const start = performance.now();\n const queryText = typeof args[0] === 'string' ? args[0] : '';\n const params = Array.isArray(args[1]) ? args[1] : undefined;\n const stack = options.captureStackTraces ? captureStack() : undefined;\n\n const result = originalQuery.apply(this, args);\n\n if (result && typeof (result as Promise<unknown>).then === 'function') {\n return (result as Promise<unknown>).then((res: unknown) => {\n const duration = performance.now() - start;\n options.onEvent({\n eventId: generateId(),\n sessionId: options.sessionId,\n timestamp: Date.now(),\n eventType: 'database',\n query: queryText,\n normalizedQuery: normalizeQuery(queryText),\n duration,\n rowsReturned: Array.isArray(res) ? res.length : undefined,\n tablesAccessed: parseTablesAccessed(queryText),\n operation: parseOperation(queryText),\n source: 'drizzle',\n params: params && options.redact !== false ? redactParams(params) : undefined,\n stackTrace: stack,\n });\n return res;\n }).catch((err: Error) => {\n const duration = performance.now() - start;\n options.onEvent({\n eventId: generateId(),\n sessionId: options.sessionId,\n timestamp: Date.now(),\n eventType: 'database',\n query: queryText,\n normalizedQuery: normalizeQuery(queryText),\n duration,\n tablesAccessed: parseTablesAccessed(queryText),\n operation: parseOperation(queryText),\n source: 'drizzle',\n error: err.message,\n params: params && options.redact !== false ? redactParams(params) : undefined,\n stackTrace: stack,\n });\n throw err;\n });\n }\n\n return result;\n };\n\n return () => {\n client.query = originalQuery;\n };\n }\n\n _log.warn('[RuntimeScope] Drizzle db has no instrumentable execute or query method.');\n return () => {};\n}\n","import type { DatabaseEvent } from '../types.js';\nimport { generateId } from '../utils/id.js';\nimport { parseOperation, parseTablesAccessed, normalizeQuery, redactParams } from '../utils/sql-parser.js';\nimport { captureStack } from '../utils/stack.js';\nimport { _log } from '../utils/log.js';\n\nexport interface Mysql2InstrumentOptions {\n sessionId: string;\n captureStackTraces?: boolean;\n redact?: boolean;\n onEvent: (event: DatabaseEvent) => void;\n}\n\n/**\n * Instrument a mysql2 Pool or Connection to capture database queries.\n * Wraps query() and execute() methods.\n */\nexport function instrumentMysql2(\n pool: unknown,\n options: Mysql2InstrumentOptions\n): () => void {\n const client = pool as Record<string, unknown>;\n const originalQuery = client.query as Function | undefined;\n const originalExecute = client.execute as Function | undefined;\n\n if (typeof originalQuery !== 'function') {\n _log.warn('[RuntimeScope] mysql2 client does not have a query method');\n return () => {};\n }\n\n function wrapMethod(original: Function, methodName: string): Function {\n return function (this: unknown, ...args: unknown[]) {\n const start = performance.now();\n let queryText = '';\n let params: unknown[] | undefined;\n\n // mysql2 supports: query(sql), query(sql, values), query(options), query(options, values)\n if (typeof args[0] === 'string') {\n queryText = args[0];\n if (Array.isArray(args[1])) params = args[1];\n } else if (typeof args[0] === 'object' && args[0] !== null) {\n const config = args[0] as Record<string, unknown>;\n queryText = (config.sql as string) ?? '';\n params = config.values as unknown[] | undefined;\n if (!params && Array.isArray(args[1])) params = args[1];\n }\n\n // Find callback (last function argument)\n const lastArg = args[args.length - 1];\n const hasCallback = typeof lastArg === 'function';\n\n if (hasCallback) {\n // Callback style\n const cb = lastArg as (...cbArgs: unknown[]) => void;\n args[args.length - 1] = function (err: Error | null, results: unknown, fields: unknown) {\n const duration = performance.now() - start;\n const rows = Array.isArray(results) ? results.length : undefined;\n const affectedRows = results && typeof results === 'object'\n ? (results as Record<string, unknown>).affectedRows as number | undefined\n : undefined;\n\n options.onEvent({\n eventId: generateId(),\n sessionId: options.sessionId,\n timestamp: Date.now(),\n eventType: 'database',\n query: queryText,\n normalizedQuery: normalizeQuery(queryText),\n duration,\n rowsReturned: rows,\n rowsAffected: affectedRows,\n tablesAccessed: parseTablesAccessed(queryText),\n operation: parseOperation(queryText),\n source: 'mysql2',\n error: err?.message,\n params: params && options.redact !== false ? redactParams(params) : undefined,\n stackTrace: options.captureStackTraces ? captureStack() : undefined,\n });\n\n cb(err, results, fields);\n };\n return original.apply(this, args);\n }\n\n // Promise style (mysql2/promise)\n const result = original.apply(this, args);\n\n if (result && typeof (result as Promise<unknown>).then === 'function') {\n return (result as Promise<unknown>).then((res: unknown) => {\n const duration = performance.now() - start;\n const resultArr = Array.isArray(res) ? res : [res];\n const rows = Array.isArray(resultArr[0]) ? resultArr[0].length : undefined;\n const affectedRows = resultArr[0] && typeof resultArr[0] === 'object'\n ? (resultArr[0] as Record<string, unknown>).affectedRows as number | undefined\n : undefined;\n\n options.onEvent({\n eventId: generateId(),\n sessionId: options.sessionId,\n timestamp: Date.now(),\n eventType: 'database',\n query: queryText,\n normalizedQuery: normalizeQuery(queryText),\n duration,\n rowsReturned: rows,\n rowsAffected: affectedRows,\n tablesAccessed: parseTablesAccessed(queryText),\n operation: parseOperation(queryText),\n source: 'mysql2',\n params: params && options.redact !== false ? redactParams(params) : undefined,\n stackTrace: options.captureStackTraces ? captureStack() : undefined,\n });\n return res;\n }).catch((err: Error) => {\n const duration = performance.now() - start;\n options.onEvent({\n eventId: generateId(),\n sessionId: options.sessionId,\n timestamp: Date.now(),\n eventType: 'database',\n query: queryText,\n normalizedQuery: normalizeQuery(queryText),\n duration,\n tablesAccessed: parseTablesAccessed(queryText),\n operation: parseOperation(queryText),\n source: 'mysql2',\n error: err.message,\n params: params && options.redact !== false ? redactParams(params) : undefined,\n stackTrace: options.captureStackTraces ? captureStack() : undefined,\n });\n throw err;\n });\n }\n\n return result;\n };\n }\n\n client.query = wrapMethod(originalQuery, 'query');\n if (typeof originalExecute === 'function') {\n client.execute = wrapMethod(originalExecute, 'execute');\n }\n\n return () => {\n client.query = originalQuery;\n if (originalExecute) client.execute = originalExecute;\n };\n}\n","import type { DatabaseEvent } from '../types.js';\nimport { generateId } from '../utils/id.js';\nimport { parseOperation, parseTablesAccessed, normalizeQuery, redactParams } from '../utils/sql-parser.js';\nimport { captureStack } from '../utils/stack.js';\nimport { _log } from '../utils/log.js';\n\nexport interface BetterSqlite3Options {\n sessionId: string;\n captureStackTraces?: boolean;\n redact?: boolean;\n onEvent: (event: DatabaseEvent) => void;\n}\n\n/**\n * Instrument a better-sqlite3 Database instance.\n * Wraps db.prepare() to return instrumented statements whose\n * run(), get(), all(), and iterate() methods emit DatabaseEvents.\n *\n * better-sqlite3 is fully synchronous — no promise handling needed.\n */\nexport function instrumentBetterSqlite3(\n db: unknown,\n options: BetterSqlite3Options\n): () => void {\n const database = db as Record<string, unknown>;\n const originalPrepare = database.prepare as Function | undefined;\n const originalExec = database.exec as Function | undefined;\n\n if (typeof originalPrepare !== 'function') {\n _log.warn('[RuntimeScope] better-sqlite3 db does not have a prepare method');\n return () => {};\n }\n\n function emitQuery(\n queryText: string,\n start: number,\n result?: unknown,\n error?: string,\n params?: unknown[]\n ): void {\n const duration = performance.now() - start;\n const rows = Array.isArray(result) ? result.length : undefined;\n const changes = result && typeof result === 'object'\n ? (result as Record<string, unknown>).changes as number | undefined\n : undefined;\n\n options.onEvent({\n eventId: generateId(),\n sessionId: options.sessionId,\n timestamp: Date.now(),\n eventType: 'database',\n query: queryText,\n normalizedQuery: normalizeQuery(queryText),\n duration,\n rowsReturned: rows,\n rowsAffected: changes,\n tablesAccessed: parseTablesAccessed(queryText),\n operation: parseOperation(queryText),\n source: 'better-sqlite3',\n error,\n params: params && options.redact !== false ? redactParams(params) : undefined,\n stackTrace: options.captureStackTraces ? captureStack() : undefined,\n });\n }\n\n // Wrap db.prepare() to return instrumented statements\n database.prepare = function (sql: string) {\n const stmt = (originalPrepare as Function).call(this, sql);\n const stmtObj = stmt as Record<string, unknown>;\n\n // Wrap run(), get(), all()\n const methods = ['run', 'get', 'all'] as const;\n for (const method of methods) {\n const original = stmtObj[method] as Function;\n if (typeof original !== 'function') continue;\n\n stmtObj[method] = function (...args: unknown[]) {\n const start = performance.now();\n try {\n const result = original.apply(this, args);\n emitQuery(sql, start, result, undefined, args);\n return result;\n } catch (err) {\n emitQuery(sql, start, undefined, (err as Error).message, args);\n throw err;\n }\n };\n }\n\n // Wrap iterate() — returns an iterator\n const originalIterate = stmtObj.iterate as Function | undefined;\n if (typeof originalIterate === 'function') {\n stmtObj.iterate = function (...args: unknown[]) {\n const start = performance.now();\n const iter = originalIterate.apply(this, args);\n let rowCount = 0;\n\n const originalNext = iter.next.bind(iter);\n let emitted = false;\n iter.next = function () {\n const result = originalNext();\n if (!result.done) rowCount++;\n if (result.done && !emitted) {\n emitted = true;\n emitQuery(sql, start, { length: rowCount }, undefined, args);\n }\n return result;\n };\n\n return iter;\n };\n }\n\n return stmt;\n };\n\n // Wrap db.exec() for raw SQL execution\n if (typeof originalExec === 'function') {\n database.exec = function (sql: string) {\n const start = performance.now();\n try {\n const result = (originalExec as Function).call(this, sql);\n emitQuery(sql, start);\n return result;\n } catch (err) {\n emitQuery(sql, start, undefined, (err as Error).message);\n throw err;\n }\n };\n }\n\n return () => {\n database.prepare = originalPrepare;\n if (originalExec) database.exec = originalExec;\n };\n}\n","/** Safely serialize a value, handling circular references, functions, symbols, and errors. */\nexport function safeSerialize(value: unknown, maxDepth = 5): unknown {\n const seen = new WeakSet();\n\n function walk(val: unknown, depth: number): unknown {\n if (depth > maxDepth) return '[max depth]';\n if (val === null || val === undefined) return val;\n if (typeof val === 'function') return `[Function: ${val.name || 'anonymous'}]`;\n if (typeof val === 'symbol') return val.toString();\n if (typeof val === 'bigint') return val.toString();\n if (typeof val !== 'object') return val;\n\n if (val instanceof Error) {\n return { name: val.name, message: val.message, stack: val.stack };\n }\n if (val instanceof Date) {\n return val.toISOString();\n }\n if (val instanceof RegExp) {\n return val.toString();\n }\n\n if (seen.has(val as object)) return '[Circular]';\n seen.add(val as object);\n\n if (Array.isArray(val)) {\n return val.map((v) => walk(v, depth + 1));\n }\n\n const result: Record<string, unknown> = {};\n for (const key of Object.keys(val as Record<string, unknown>)) {\n result[key] = walk((val as Record<string, unknown>)[key], depth + 1);\n }\n return result;\n }\n\n return walk(value, 0);\n}\n","import { AsyncLocalStorage } from 'node:async_hooks';\n\nexport interface RequestContext {\n sessionId: string;\n requestId?: string;\n metadata?: Record<string, unknown>;\n}\n\nconst storage = new AsyncLocalStorage<RequestContext>();\n\n/**\n * Run a function within a request context.\n * All async operations within `fn` will inherit this context.\n */\nexport function runWithContext<T>(ctx: RequestContext, fn: () => T): T {\n return storage.run(ctx, fn);\n}\n\n/**\n * Get the current request context, if any.\n */\nexport function getRequestContext(): RequestContext | undefined {\n return storage.getStore();\n}\n\n/**\n * Get the sessionId from the current request context,\n * falling back to the global sessionId.\n */\nexport function getSessionId(fallback: string): string {\n return storage.getStore()?.sessionId ?? fallback;\n}\n","import { generateId } from '../utils/id.js';\nimport { safeSerialize } from '../utils/serialize.js';\nimport { getSessionId } from '../context.js';\nimport type { ConsoleEvent, ConsoleLevel, ServerRuntimeEvent } from '../types.js';\n\ntype EmitFn = (event: ConsoleEvent) => void;\n\nconst LEVELS: ConsoleLevel[] = ['log', 'warn', 'error', 'info', 'debug', 'trace'];\n\nexport interface ConsoleInterceptorOptions {\n levels?: ConsoleLevel[];\n captureStackTraces?: boolean;\n beforeSend?: (event: ServerRuntimeEvent) => ServerRuntimeEvent | null;\n}\n\nexport function interceptConsole(\n emit: EmitFn,\n sessionId: string,\n options?: ConsoleInterceptorOptions\n): () => void {\n const levels = options?.levels ?? LEVELS;\n const captureStack = options?.captureStackTraces ?? true;\n const originals: Record<string, (...args: unknown[]) => void> = {};\n\n for (const level of levels) {\n originals[level] = console[level].bind(console);\n\n console[level] = (...args: unknown[]) => {\n const message = args\n .map((a) => (typeof a === 'string' ? a : stringifyArg(a)))\n .join(' ');\n\n const event: ConsoleEvent = {\n eventId: generateId(),\n sessionId: getSessionId(sessionId),\n timestamp: Date.now(),\n eventType: 'console',\n level,\n message,\n args: args.map((a) => safeSerialize(a, 3)),\n stackTrace:\n captureStack && (level === 'error' || level === 'trace')\n ? new Error().stack?.split('\\n').slice(2).join('\\n')\n : undefined,\n sourceFile: undefined,\n };\n\n if (options?.beforeSend) {\n const filtered = options.beforeSend(event);\n if (filtered) emit(filtered as ConsoleEvent);\n } else {\n emit(event);\n }\n\n // Call original — MUST come after emit, and MUST use saved reference\n originals[level](...args);\n };\n }\n\n return () => {\n for (const level of levels) {\n console[level] = originals[level];\n }\n };\n}\n\nfunction stringifyArg(arg: unknown): string {\n try {\n return JSON.stringify(arg);\n } catch {\n return String(arg);\n }\n}\n","import { generateId } from '../utils/id.js';\nimport { safeSerialize } from '../utils/serialize.js';\nimport { getSessionId } from '../context.js';\nimport type { ConsoleEvent, ServerRuntimeEvent } from '../types.js';\n\ntype EmitFn = (event: ConsoleEvent) => void;\n\nexport interface ErrorInterceptorOptions {\n beforeSend?: (event: ServerRuntimeEvent) => ServerRuntimeEvent | null;\n}\n\nexport function interceptErrors(\n emit: EmitFn,\n sessionId: string,\n options?: ErrorInterceptorOptions\n): () => void {\n const onUncaughtException = (error: Error) => {\n const event: ConsoleEvent = {\n eventId: generateId(),\n sessionId: getSessionId(sessionId),\n timestamp: Date.now(),\n eventType: 'console',\n level: 'error',\n message: `[Uncaught] ${error.message}`,\n args: [safeSerialize(error, 3)],\n stackTrace: error.stack,\n sourceFile: extractSourceFile(error.stack),\n };\n\n if (options?.beforeSend) {\n const filtered = options.beforeSend(event);\n if (filtered) emit(filtered as ConsoleEvent);\n } else {\n emit(event);\n }\n\n // Preserve Node.js default crash behavior — set exit code so the\n // process still terminates after all listeners have run\n process.exitCode = 1;\n };\n\n const onUnhandledRejection = (reason: unknown) => {\n let message: string;\n let stackTrace: string | undefined;\n\n if (reason instanceof Error) {\n message = reason.message;\n stackTrace = reason.stack;\n } else if (typeof reason === 'string') {\n message = reason;\n } else {\n try {\n message = JSON.stringify(reason);\n } catch {\n message = String(reason);\n }\n }\n\n const event: ConsoleEvent = {\n eventId: generateId(),\n sessionId: getSessionId(sessionId),\n timestamp: Date.now(),\n eventType: 'console',\n level: 'error',\n message: `[Unhandled Rejection] ${message}`,\n args: [safeSerialize(reason, 3)],\n stackTrace,\n sourceFile: undefined,\n };\n\n if (options?.beforeSend) {\n const filtered = options.beforeSend(event);\n if (filtered) emit(filtered as ConsoleEvent);\n } else {\n emit(event);\n }\n };\n\n process.on('uncaughtException', onUncaughtException);\n process.on('unhandledRejection', onUnhandledRejection);\n\n return () => {\n process.removeListener('uncaughtException', onUncaughtException);\n process.removeListener('unhandledRejection', onUnhandledRejection);\n };\n}\n\nfunction extractSourceFile(stack?: string): string | undefined {\n if (!stack) return undefined;\n // Find first non-internal frame\n const lines = stack.split('\\n');\n for (const line of lines.slice(1)) {\n const match = line.match(/at\\s+.*?\\((.+?):(\\d+):(\\d+)\\)/);\n if (match && !match[1].includes('node_modules') && !match[1].includes('node:')) {\n return `${match[1]}:${match[2]}:${match[3]}`;\n }\n }\n return undefined;\n}\n","import http from 'node:http';\nimport https from 'node:https';\nimport { generateId } from '../utils/id.js';\nimport { getSessionId } from '../context.js';\nimport type { NetworkEvent, ServerRuntimeEvent } from '../types.js';\n\ntype EmitFn = (event: NetworkEvent) => void;\n\nexport interface HttpInterceptorOptions {\n captureBody?: boolean;\n maxBodySize?: number;\n redactHeaders?: string[];\n ignoreUrls?: (string | RegExp)[];\n beforeSend?: (event: ServerRuntimeEvent) => ServerRuntimeEvent | null;\n}\n\nconst DEFAULT_REDACT_HEADERS = ['authorization', 'cookie', 'set-cookie', 'x-api-key'];\n\nexport function interceptHttp(\n emit: EmitFn,\n sessionId: string,\n options?: HttpInterceptorOptions\n): () => void {\n const maxBodySize = options?.maxBodySize ?? 65536;\n const redactSet = new Set(\n (options?.redactHeaders ?? DEFAULT_REDACT_HEADERS).map((h) => h.toLowerCase())\n );\n const ignorePatterns = options?.ignoreUrls ?? [];\n\n const originalHttpRequest = http.request;\n const originalHttpsRequest = https.request;\n\n function shouldIgnore(url: string): boolean {\n for (const pattern of ignorePatterns) {\n if (typeof pattern === 'string') {\n if (url.includes(pattern)) return true;\n } else if (pattern.test(url)) {\n return true;\n }\n }\n return false;\n }\n\n function redactHeaders(\n headers: Record<string, string | string[] | number | undefined>\n ): Record<string, string> {\n const result: Record<string, string> = {};\n for (const [key, val] of Object.entries(headers)) {\n if (val === undefined) continue;\n const lk = key.toLowerCase();\n result[lk] = redactSet.has(lk) ? '[REDACTED]' : String(val);\n }\n return result;\n }\n\n function buildUrl(\n input: string | URL | http.RequestOptions,\n protocol: 'http' | 'https'\n ): string {\n if (typeof input === 'string') return input;\n if (input instanceof URL) return input.toString();\n // RequestOptions\n const host = input.hostname ?? input.host ?? 'localhost';\n const port = input.port ? `:${input.port}` : '';\n const path = input.path ?? '/';\n return `${protocol}://${host}${port}${path}`;\n }\n\n function wrapRequest(\n original: typeof http.request,\n protocol: 'http' | 'https'\n ): typeof http.request {\n return function wrappedRequest(\n this: unknown,\n ...args: Parameters<typeof http.request>\n ): http.ClientRequest {\n const url = buildUrl(args[0], protocol);\n\n if (shouldIgnore(url)) {\n return original.apply(this, args as never) as http.ClientRequest;\n }\n\n const startTime = performance.now();\n\n // Extract method from args\n let method = 'GET';\n if (typeof args[0] !== 'string' && !(args[0] instanceof URL)) {\n method = (args[0] as http.RequestOptions).method?.toUpperCase() ?? 'GET';\n } else if (args[1] && typeof args[1] === 'object' && !('on' in args[1])) {\n method = (args[1] as http.RequestOptions).method?.toUpperCase() ?? 'GET';\n }\n\n // Extract request headers\n let reqHeaders: Record<string, string | string[] | number | undefined> = {};\n if (typeof args[0] !== 'string' && !(args[0] instanceof URL)) {\n reqHeaders = (args[0] as http.RequestOptions).headers ?? {};\n } else if (args[1] && typeof args[1] === 'object' && !('on' in args[1])) {\n reqHeaders = (args[1] as http.RequestOptions).headers ?? {};\n }\n\n const req = original.apply(this, args as never) as http.ClientRequest;\n\n // Track request body size\n let requestBodySize = 0;\n let requestBody: string | undefined;\n const requestChunks: Buffer[] = [];\n\n const origWrite = req.write;\n req.write = function (\n chunk: unknown,\n ...rest: unknown[]\n ): boolean {\n if (chunk) {\n const buf = Buffer.isBuffer(chunk) ? chunk : Buffer.from(String(chunk));\n requestBodySize += buf.length;\n if (options?.captureBody) requestChunks.push(buf);\n }\n return origWrite.apply(req, [chunk, ...rest] as never);\n };\n\n const origEnd = req.end;\n req.end = function (\n chunk?: unknown,\n ...rest: unknown[]\n ): http.ClientRequest {\n if (chunk && typeof chunk !== 'function') {\n const buf = Buffer.isBuffer(chunk) ? chunk : Buffer.from(String(chunk));\n requestBodySize += buf.length;\n if (options?.captureBody) requestChunks.push(buf);\n }\n return origEnd.apply(req, [chunk, ...rest] as never) as http.ClientRequest;\n };\n\n // Listen for response\n req.on('response', (res: http.IncomingMessage) => {\n const responseChunks: Buffer[] = [];\n let responseBodySize = 0;\n\n if (options?.captureBody) {\n const origPush = res.push;\n res.push = function (chunk: Buffer | null, ...rest: unknown[]): boolean {\n if (chunk) {\n responseBodySize += chunk.length;\n if (responseBodySize <= maxBodySize) responseChunks.push(chunk);\n }\n return origPush.apply(res, [chunk, ...rest] as never);\n };\n }\n\n res.on('end', () => {\n const duration = performance.now() - startTime;\n\n if (options?.captureBody) {\n requestBody = joinChunks(requestChunks, maxBodySize);\n }\n\n const contentLength = parseInt(\n res.headers['content-length'] ?? '0',\n 10\n );\n\n const event: NetworkEvent = {\n eventId: generateId(),\n sessionId: getSessionId(sessionId),\n timestamp: Date.now(),\n eventType: 'network',\n url,\n method,\n status: res.statusCode ?? 0,\n requestHeaders: redactHeaders(reqHeaders),\n responseHeaders: redactHeaders(\n res.headers as Record<string, string | string[] | undefined>\n ),\n requestBodySize,\n responseBodySize: contentLength || responseBodySize,\n duration: Math.round(duration * 100) / 100,\n ttfb: Math.round(duration * 100) / 100,\n requestBody,\n responseBody: options?.captureBody\n ? joinChunks(responseChunks, maxBodySize)\n : undefined,\n source: protocol === 'https' ? 'node-https' : 'node-http',\n };\n\n if (options?.beforeSend) {\n const filtered = options.beforeSend(event);\n if (filtered) emit(filtered as NetworkEvent);\n } else {\n emit(event);\n }\n });\n });\n\n // Handle request errors\n req.on('error', (err: Error) => {\n const duration = performance.now() - startTime;\n\n const event: NetworkEvent = {\n eventId: generateId(),\n sessionId: getSessionId(sessionId),\n timestamp: Date.now(),\n eventType: 'network',\n url,\n method,\n status: 0,\n requestHeaders: redactHeaders(reqHeaders),\n responseHeaders: {},\n requestBodySize,\n responseBodySize: 0,\n duration: Math.round(duration * 100) / 100,\n ttfb: 0,\n errorPhase: 'error',\n errorMessage: err.message,\n source: protocol === 'https' ? 'node-https' : 'node-http',\n };\n\n if (options?.beforeSend) {\n const filtered = options.beforeSend(event);\n if (filtered) emit(filtered as NetworkEvent);\n } else {\n emit(event);\n }\n });\n\n return req;\n } as typeof http.request;\n }\n\n http.request = wrapRequest(originalHttpRequest, 'http');\n https.request = wrapRequest(originalHttpsRequest, 'https');\n\n // http.get / https.get call through to http.request / https.request,\n // so they are automatically intercepted — no need to patch separately\n\n return () => {\n http.request = originalHttpRequest;\n https.request = originalHttpsRequest;\n };\n}\n\nfunction joinChunks(chunks: Buffer[], maxSize: number): string | undefined {\n if (chunks.length === 0) return undefined;\n const combined = Buffer.concat(chunks);\n if (combined.length === 0) return undefined;\n return combined.toString('utf8', 0, Math.min(combined.length, maxSize));\n}\n","import { monitorEventLoopDelay } from 'node:perf_hooks';\nimport { PerformanceObserver } from 'node:perf_hooks';\nimport { generateId } from '../utils/id.js';\nimport { getSessionId } from '../context.js';\nimport type { PerformanceEvent, ServerMetricName, MetricUnit } from '../types.js';\n\ntype EmitFn = (event: PerformanceEvent) => void;\n\nexport interface PerfMetricsOptions {\n /** Collection interval in ms (default: 5000) */\n intervalMs?: number;\n /** Which metrics to collect (default: all) */\n metrics?: ServerMetricName[];\n}\n\nconst ALL_METRICS: ServerMetricName[] = [\n 'memory.rss', 'memory.heapUsed', 'memory.heapTotal', 'memory.external',\n 'eventloop.lag.mean', 'eventloop.lag.p99', 'eventloop.lag.max',\n 'gc.pause.major', 'gc.pause.minor',\n 'cpu.user', 'cpu.system',\n 'handles.active', 'requests.active',\n];\n\nfunction shouldCollect(metric: ServerMetricName, enabled: ServerMetricName[]): boolean {\n return enabled.includes(metric);\n}\n\nfunction emitMetric(\n emit: EmitFn,\n sessionId: string,\n metricName: ServerMetricName,\n value: number,\n unit: MetricUnit\n): void {\n emit({\n eventId: generateId(),\n sessionId: getSessionId(sessionId),\n timestamp: Date.now(),\n eventType: 'performance',\n metricName,\n value: Math.round(value * 100) / 100,\n unit,\n });\n}\n\nexport function startPerfMetrics(\n emit: EmitFn,\n sessionId: string,\n options?: PerfMetricsOptions\n): () => void {\n const intervalMs = options?.intervalMs ?? 5000;\n const enabled = options?.metrics ?? ALL_METRICS;\n\n // Track CPU usage delta between intervals\n let lastCpuUsage = process.cpuUsage();\n let lastCpuTime = Date.now();\n\n // Event loop delay histogram\n let histogram: ReturnType<typeof monitorEventLoopDelay> | null = null;\n const needsEventLoop = enabled.some((m) => m.startsWith('eventloop.'));\n if (needsEventLoop) {\n histogram = monitorEventLoopDelay({ resolution: 20 });\n histogram.enable();\n }\n\n // GC observer\n let gcObserver: PerformanceObserver | null = null;\n let lastMajorGcMs = 0;\n let lastMinorGcMs = 0;\n const needsGc = enabled.some((m) => m.startsWith('gc.'));\n if (needsGc) {\n gcObserver = new PerformanceObserver((list) => {\n for (const entry of list.getEntries()) {\n const gcEntry = entry as PerformanceEntry & { detail?: { kind?: number } };\n const durationMs = entry.duration;\n // GC kind: 1=Scavenge(minor), 2=MarkSweepCompact(major), 4=IncrementalMarking, 8=WeakPhantom\n const kind = gcEntry.detail?.kind ?? 0;\n if (kind === 2) {\n lastMajorGcMs += durationMs;\n } else if (kind === 1 || kind === 4 || kind === 8) {\n lastMinorGcMs += durationMs;\n }\n }\n });\n gcObserver.observe({ entryTypes: ['gc'] });\n }\n\n const timer = setInterval(() => {\n // Memory metrics\n if (enabled.some((m) => m.startsWith('memory.'))) {\n const mem = process.memoryUsage();\n if (shouldCollect('memory.rss', enabled)) emitMetric(emit, sessionId, 'memory.rss', mem.rss, 'bytes');\n if (shouldCollect('memory.heapUsed', enabled)) emitMetric(emit, sessionId, 'memory.heapUsed', mem.heapUsed, 'bytes');\n if (shouldCollect('memory.heapTotal', enabled)) emitMetric(emit, sessionId, 'memory.heapTotal', mem.heapTotal, 'bytes');\n if (shouldCollect('memory.external', enabled)) emitMetric(emit, sessionId, 'memory.external', mem.external, 'bytes');\n }\n\n // Event loop lag\n if (histogram) {\n if (shouldCollect('eventloop.lag.mean', enabled)) emitMetric(emit, sessionId, 'eventloop.lag.mean', histogram.mean / 1e6, 'ms');\n if (shouldCollect('eventloop.lag.p99', enabled)) emitMetric(emit, sessionId, 'eventloop.lag.p99', histogram.percentile(99) / 1e6, 'ms');\n if (shouldCollect('eventloop.lag.max', enabled)) emitMetric(emit, sessionId, 'eventloop.lag.max', histogram.max / 1e6, 'ms');\n histogram.reset();\n }\n\n // GC pauses (accumulated since last interval)\n if (needsGc) {\n if (shouldCollect('gc.pause.major', enabled)) emitMetric(emit, sessionId, 'gc.pause.major', lastMajorGcMs, 'ms');\n if (shouldCollect('gc.pause.minor', enabled)) emitMetric(emit, sessionId, 'gc.pause.minor', lastMinorGcMs, 'ms');\n lastMajorGcMs = 0;\n lastMinorGcMs = 0;\n }\n\n // CPU usage (percentage of interval)\n if (enabled.some((m) => m.startsWith('cpu.'))) {\n const now = Date.now();\n const elapsed = (now - lastCpuTime) * 1000; // Convert to microseconds\n const cpu = process.cpuUsage(lastCpuUsage);\n lastCpuUsage = process.cpuUsage();\n lastCpuTime = now;\n if (elapsed > 0) {\n if (shouldCollect('cpu.user', enabled)) emitMetric(emit, sessionId, 'cpu.user', (cpu.user / elapsed) * 100, 'percent');\n if (shouldCollect('cpu.system', enabled)) emitMetric(emit, sessionId, 'cpu.system', (cpu.system / elapsed) * 100, 'percent');\n }\n }\n\n // Active handles/requests\n if (shouldCollect('handles.active', enabled)) {\n const handles = (process as unknown as { _getActiveHandles: () => unknown[] })._getActiveHandles?.()?.length ?? 0;\n emitMetric(emit, sessionId, 'handles.active', handles, 'count');\n }\n if (shouldCollect('requests.active', enabled)) {\n const requests = (process as unknown as { _getActiveRequests: () => unknown[] })._getActiveRequests?.()?.length ?? 0;\n emitMetric(emit, sessionId, 'requests.active', requests, 'count');\n }\n }, intervalMs);\n\n // Don't keep the process alive just for metrics\n timer.unref();\n\n return () => {\n clearInterval(timer);\n if (histogram) {\n histogram.disable();\n }\n if (gcObserver) {\n gcObserver.disconnect();\n }\n };\n}\n","import { generateId } from '../utils/id.js';\nimport { runWithContext } from '../context.js';\nimport type { NetworkEvent, ServerRuntimeEvent } from '../types.js';\n\ntype EmitFn = (event: NetworkEvent) => void;\n\nexport interface MiddlewareOptions {\n captureBody?: boolean;\n maxBodySize?: number;\n redactHeaders?: string[];\n ignoreRoutes?: (string | RegExp)[];\n beforeSend?: (event: ServerRuntimeEvent) => ServerRuntimeEvent | null;\n}\n\nconst DEFAULT_REDACT_HEADERS = ['authorization', 'cookie', 'set-cookie', 'x-api-key'];\n\n/**\n * Express/Connect-compatible middleware that captures incoming HTTP requests.\n * Complements the HTTP interceptor (which captures outgoing requests).\n *\n * Usage:\n * app.use(RuntimeScope.middleware());\n */\nexport function runtimeScopeMiddleware(\n emit: EmitFn,\n sessionId: string,\n options?: MiddlewareOptions\n): (req: any, res: any, next: any) => void {\n const maxBodySize = options?.maxBodySize ?? 65536;\n const redactSet = new Set(\n (options?.redactHeaders ?? DEFAULT_REDACT_HEADERS).map((h) => h.toLowerCase())\n );\n const ignorePatterns = options?.ignoreRoutes ?? [];\n\n function shouldIgnore(path: string): boolean {\n for (const pattern of ignorePatterns) {\n if (typeof pattern === 'string') {\n if (path === pattern || path.startsWith(pattern)) return true;\n } else if (pattern.test(path)) {\n return true;\n }\n }\n return false;\n }\n\n function redactHeaders(\n headers: Record<string, string | string[] | number | undefined>\n ): Record<string, string> {\n const result: Record<string, string> = {};\n for (const [key, val] of Object.entries(headers)) {\n if (val === undefined) continue;\n const lk = key.toLowerCase();\n result[lk] = redactSet.has(lk) ? '[REDACTED]' : String(val);\n }\n return result;\n }\n\n return (req: any, res: any, next: any) => {\n const path: string = req.originalUrl ?? req.url ?? '/';\n\n if (shouldIgnore(path)) {\n return next();\n }\n\n const startTime = performance.now();\n\n // Wrap res.end to capture response timing and status\n const originalEnd = res.end.bind(res);\n let responseBody: string | undefined;\n\n res.end = function (chunk?: unknown, ...rest: unknown[]) {\n const duration = performance.now() - startTime;\n\n if (options?.captureBody && chunk) {\n if (Buffer.isBuffer(chunk)) {\n responseBody = chunk.toString('utf8', 0, Math.min(chunk.length, maxBodySize));\n } else if (typeof chunk === 'string') {\n responseBody = chunk.slice(0, maxBodySize);\n }\n }\n\n const proto = req.protocol ?? (req.socket?.encrypted ? 'https' : 'http');\n const host = req.get?.('host') ?? req.headers?.host ?? 'localhost';\n const url = `${proto}://${host}${path}`;\n\n const event: NetworkEvent = {\n eventId: generateId(),\n sessionId,\n timestamp: Date.now(),\n eventType: 'network',\n url,\n method: (req.method ?? 'GET').toUpperCase(),\n status: res.statusCode ?? 200,\n requestHeaders: redactHeaders(req.headers ?? {}),\n responseHeaders: redactHeaders(\n typeof res.getHeaders === 'function' ? res.getHeaders() : {}\n ),\n requestBodySize: parseInt(req.headers?.['content-length'] ?? '0', 10),\n responseBodySize: parseInt(\n (typeof res.getHeader === 'function'\n ? res.getHeader('content-length')\n : undefined\n )?.toString() ?? '0',\n 10\n ),\n duration: Math.round(duration * 100) / 100,\n ttfb: Math.round(duration * 100) / 100,\n responseBody,\n source: 'node-http',\n };\n\n if (options?.beforeSend) {\n const filtered = options.beforeSend(event);\n if (filtered) emit(filtered as NetworkEvent);\n } else {\n emit(event);\n }\n\n return originalEnd(chunk, ...rest);\n };\n\n // Wrap next() in request context so downstream code\n // (database queries, console logs, HTTP calls) inherits per-request sessionId\n const requestId = generateId();\n runWithContext({ sessionId, requestId }, () => next());\n };\n}\n","import { ServerTransport } from './transport.js';\nimport { generateId, generateSessionId } from './utils/id.js';\nimport { parseOperation, parseTablesAccessed, normalizeQuery, redactParams } from './utils/sql-parser.js';\nimport { captureStack } from './utils/stack.js';\nimport { Sampler } from './sampler.js';\nimport { instrumentPrisma } from './integrations/prisma.js';\nimport { instrumentPg } from './integrations/pg.js';\nimport { instrumentKnex } from './integrations/knex.js';\nimport { instrumentDrizzle } from './integrations/drizzle.js';\nimport { instrumentMysql2 } from './integrations/mysql2.js';\nimport { instrumentBetterSqlite3 } from './integrations/better-sqlite3.js';\nimport { interceptConsole } from './interceptors/console.js';\nimport { interceptErrors } from './interceptors/errors.js';\nimport { interceptHttp } from './interceptors/http.js';\nimport { startPerfMetrics } from './interceptors/perf-metrics.js';\nimport { runtimeScopeMiddleware } from './interceptors/middleware.js';\nimport type { DatabaseEvent, ServerSdkConfig, ServerRuntimeEvent } from './types.js';\nimport type { MiddlewareOptions } from './interceptors/middleware.js';\n\n// ============================================================\n// RuntimeScope Server SDK\n// Instruments server-side database queries, console output,\n// errors, HTTP requests, and performance metrics — sends them\n// to the RuntimeScope collector via WebSocket\n// ============================================================\n\nconst SDK_VERSION = '0.6.2';\n\n// Re-export _log for integration modules (lives in utils/log.js to avoid circular deps)\nexport { _log } from './utils/log.js';\n\nclass RuntimeScopeServer {\n private transport: ServerTransport | null = null;\n private sessionId: string = '';\n private config: ServerSdkConfig = {};\n private sampler: Sampler | null = null;\n private restoreFunctions: (() => void)[] = [];\n\n /** Alias for `connect` — mirrors the browser SDK's init() API */\n init(config: ServerSdkConfig = {}): void {\n return this.connect(config);\n }\n\n connect(config: ServerSdkConfig = {}): void {\n this.config = config;\n this.sessionId = config.sessionId ?? generateSessionId();\n\n const serverUrl = config.serverUrl ?? config.endpoint ?? 'ws://127.0.0.1:9090';\n\n this.transport = new ServerTransport({\n url: serverUrl,\n sessionId: this.sessionId,\n appName: config.appName ?? 'server-app',\n sdkVersion: SDK_VERSION,\n authToken: config.authToken,\n maxQueueSize: config.maxQueueSize,\n });\n\n this.transport.connect();\n\n // Set up sampler if rate limiting or sampling is configured\n if (config.sampleRate !== undefined || config.maxEventsPerSecond !== undefined) {\n this.sampler = new Sampler({\n sampleRate: config.sampleRate,\n maxEventsPerSecond: config.maxEventsPerSecond,\n });\n }\n\n const emit = (event: ServerRuntimeEvent) => this.emitEvent(event);\n\n // Console interceptor (default: enabled)\n if (config.captureConsole !== false) {\n try {\n this.restoreFunctions.push(\n interceptConsole(emit, this.sessionId, {\n captureStackTraces: config.captureStackTraces,\n beforeSend: config.beforeSend,\n })\n );\n } catch { /* non-fatal: continue without console capture */ }\n }\n\n // Error interceptor (default: enabled when console is enabled)\n if (config.captureErrors !== false && config.captureConsole !== false) {\n try {\n this.restoreFunctions.push(\n interceptErrors(emit, this.sessionId, {\n beforeSend: config.beforeSend,\n })\n );\n } catch { /* non-fatal: continue without error capture */ }\n }\n\n // HTTP request interceptor (default: enabled)\n if (config.captureHttp !== false) {\n try {\n this.restoreFunctions.push(\n interceptHttp(emit, this.sessionId, {\n captureBody: config.captureBody,\n maxBodySize: config.maxBodySize,\n redactHeaders: config.redactHeaders,\n // Auto-ignore the collector URL to prevent recursion\n ignoreUrls: [serverUrl.replace('ws://', '').replace('wss://', '')],\n beforeSend: config.beforeSend,\n })\n );\n } catch { /* non-fatal: continue without HTTP capture */ }\n }\n\n // Performance metrics (default: enabled)\n if (config.capturePerformance !== false) {\n try {\n this.restoreFunctions.push(\n startPerfMetrics(emit, this.sessionId, {\n intervalMs: config.performanceInterval,\n metrics: config.performanceMetrics,\n })\n );\n } catch { /* non-fatal: continue without performance metrics */ }\n }\n }\n\n disconnect(): void {\n for (const restore of this.restoreFunctions) {\n try { restore(); } catch { /* ignore */ }\n }\n this.restoreFunctions = [];\n this.sampler = null;\n this.transport?.disconnect();\n this.transport = null;\n }\n\n get currentSessionId(): string {\n return this.sessionId;\n }\n\n private emitEvent(event: ServerRuntimeEvent): void {\n // Apply sampling/rate limiting\n if (this.sampler && !this.sampler.shouldSample(event)) return;\n\n if (this.config.beforeSend) {\n const filtered = this.config.beforeSend(event);\n if (!filtered) return;\n this.transport?.sendEvent(filtered);\n } else {\n this.transport?.sendEvent(event);\n }\n }\n\n // --- Express/Connect Middleware ---\n\n middleware(options?: MiddlewareOptions) {\n return runtimeScopeMiddleware(\n (event) => this.emitEvent(event),\n this.sessionId,\n {\n ...options,\n redactHeaders: options?.redactHeaders ?? this.config.redactHeaders,\n beforeSend: options?.beforeSend ?? this.config.beforeSend,\n }\n );\n }\n\n // --- ORM Instrumentation ---\n\n instrumentPrisma(client: unknown): typeof client {\n const restore = instrumentPrisma(client, {\n sessionId: this.sessionId,\n captureStackTraces: this.config.captureStackTraces,\n redact: this.config.redactParams,\n onEvent: (event) => this.emitEvent(event),\n });\n this.restoreFunctions.push(restore);\n return client;\n }\n\n instrumentPg(pool: unknown): typeof pool {\n const restore = instrumentPg(pool, {\n sessionId: this.sessionId,\n captureStackTraces: this.config.captureStackTraces,\n redact: this.config.redactParams,\n onEvent: (event) => this.emitEvent(event),\n });\n this.restoreFunctions.push(restore);\n return pool;\n }\n\n instrumentKnex(knex: unknown): typeof knex {\n const restore = instrumentKnex(knex, {\n sessionId: this.sessionId,\n captureStackTraces: this.config.captureStackTraces,\n redact: this.config.redactParams,\n onEvent: (event) => this.emitEvent(event),\n });\n this.restoreFunctions.push(restore);\n return knex;\n }\n\n instrumentDrizzle(db: unknown): typeof db {\n const restore = instrumentDrizzle(db, {\n sessionId: this.sessionId,\n captureStackTraces: this.config.captureStackTraces,\n redact: this.config.redactParams,\n onEvent: (event) => this.emitEvent(event),\n });\n this.restoreFunctions.push(restore);\n return db;\n }\n\n instrumentMysql2(pool: unknown): typeof pool {\n const restore = instrumentMysql2(pool, {\n sessionId: this.sessionId,\n captureStackTraces: this.config.captureStackTraces,\n redact: this.config.redactParams,\n onEvent: (event) => this.emitEvent(event),\n });\n this.restoreFunctions.push(restore);\n return pool;\n }\n\n instrumentBetterSqlite3(db: unknown): typeof db {\n const restore = instrumentBetterSqlite3(db, {\n sessionId: this.sessionId,\n captureStackTraces: this.config.captureStackTraces,\n redact: this.config.redactParams,\n onEvent: (event) => this.emitEvent(event),\n });\n this.restoreFunctions.push(restore);\n return db;\n }\n\n // --- Generic query capture ---\n\n async captureQuery<T>(\n fn: () => Promise<T>,\n options?: { label?: string }\n ): Promise<T> {\n const start = performance.now();\n try {\n const result = await fn();\n const duration = performance.now() - start;\n this.emitEvent({\n eventId: generateId(),\n sessionId: this.sessionId,\n timestamp: Date.now(),\n eventType: 'database',\n query: options?.label ?? 'custom query',\n normalizedQuery: options?.label ?? 'custom query',\n duration,\n tablesAccessed: [],\n operation: 'OTHER',\n source: 'generic',\n label: options?.label,\n stackTrace: this.config.captureStackTraces ? captureStack() : undefined,\n rowsReturned: Array.isArray(result) ? result.length : undefined,\n });\n return result;\n } catch (err) {\n const duration = performance.now() - start;\n this.emitEvent({\n eventId: generateId(),\n sessionId: this.sessionId,\n timestamp: Date.now(),\n eventType: 'database',\n query: options?.label ?? 'custom query',\n normalizedQuery: options?.label ?? 'custom query',\n duration,\n tablesAccessed: [],\n operation: 'OTHER',\n source: 'generic',\n label: options?.label,\n error: (err as Error).message,\n stackTrace: this.config.captureStackTraces ? captureStack() : undefined,\n });\n throw err;\n }\n }\n}\n\n// Singleton instance\nexport const RuntimeScope = new RuntimeScopeServer();\n\n// Re-export types and utilities\nexport type {\n DatabaseEvent,\n ConsoleEvent,\n NetworkEvent,\n PerformanceEvent,\n ServerRuntimeEvent,\n ServerSdkConfig,\n ServerMetricName,\n MetricUnit,\n} from './types.js';\nexport { generateId, generateSessionId } from './utils/id.js';\nexport { parseOperation, parseTablesAccessed, normalizeQuery, redactParams } from './utils/sql-parser.js';\nexport { runtimeScopeMiddleware } from './interceptors/middleware.js';\nexport { runWithContext, getRequestContext, getSessionId } from './context.js';\nexport { Sampler } from './sampler.js';\n"],"mappings":"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","names":["captureStack","DEFAULT_REDACT_HEADERS"]}
1
+ {"version":3,"sources":["../src/transport.ts","../src/http-transport.ts","../src/utils/id.ts","../src/utils/stack.ts","../src/sampler.ts","../src/utils/sql-parser.ts","../src/utils/log.ts","../src/integrations/prisma.ts","../src/integrations/pg.ts","../src/integrations/knex.ts","../src/integrations/drizzle.ts","../src/integrations/mysql2.ts","../src/integrations/better-sqlite3.ts","../src/utils/serialize.ts","../src/context.ts","../src/interceptors/console.ts","../src/interceptors/errors.ts","../src/interceptors/http.ts","../src/interceptors/perf-metrics.ts","../src/interceptors/middleware.ts","../src/index.ts"],"sourcesContent":["import WebSocket from 'ws';\nimport type { ServerRuntimeEvent, WSMessage } from './types.js';\n\nexport class ServerTransport {\n private ws: WebSocket | null = null;\n private url: string;\n private sessionId: string;\n private appName: string;\n private sdkVersion: string;\n private queue: ServerRuntimeEvent[] = [];\n private maxQueueSize: number;\n private _droppedCount = 0;\n private reconnectTimer: ReturnType<typeof setTimeout> | null = null;\n private connected = false;\n private flushTimer: ReturnType<typeof setInterval> | null = null;\n\n private authToken: string | undefined;\n private authFailed = false;\n\n constructor(options: {\n url: string;\n sessionId: string;\n appName: string;\n sdkVersion: string;\n authToken?: string;\n maxQueueSize?: number;\n }) {\n this.url = options.url;\n this.sessionId = options.sessionId;\n this.appName = options.appName;\n this.sdkVersion = options.sdkVersion;\n this.authToken = options.authToken;\n this.maxQueueSize = options.maxQueueSize ?? 10_000;\n }\n\n get droppedCount(): number {\n return this._droppedCount;\n }\n\n connect(): void {\n if (this.authFailed) return; // Don't reconnect after auth rejection\n\n try {\n this.ws = new WebSocket(this.url);\n\n this.ws.on('open', () => {\n this.connected = true;\n this.sendHandshake();\n this.flushQueue();\n\n // Start periodic flush\n this.flushTimer = setInterval(() => this.flushQueue(), 100);\n });\n\n this.ws.on('message', (data: Buffer) => {\n try {\n const msg = JSON.parse(data.toString());\n if (msg.type === 'error' && msg.payload?.code === 'AUTH_FAILED') {\n console.error('[RuntimeScope] Authentication failed — stopping reconnection');\n this.authFailed = true;\n }\n } catch { /* ignore */ }\n });\n\n this.ws.on('close', () => {\n this.connected = false;\n this.cleanup();\n if (!this.authFailed) this.scheduleReconnect();\n });\n\n this.ws.on('error', () => {\n this.connected = false;\n this.cleanup();\n if (!this.authFailed) this.scheduleReconnect();\n });\n } catch {\n this.scheduleReconnect();\n }\n }\n\n private cleanup(): void {\n if (this.flushTimer) {\n clearInterval(this.flushTimer);\n this.flushTimer = null;\n }\n }\n\n private scheduleReconnect(): void {\n if (this.reconnectTimer) return;\n this.reconnectTimer = setTimeout(() => {\n this.reconnectTimer = null;\n this.connect();\n }, 3000);\n }\n\n private sendHandshake(): void {\n this.send({\n type: 'handshake',\n payload: {\n appName: this.appName,\n sdkVersion: this.sdkVersion,\n sessionId: this.sessionId,\n ...(this.authToken ? { authToken: this.authToken } : {}),\n },\n timestamp: Date.now(),\n sessionId: this.sessionId,\n });\n }\n\n sendEvent(event: ServerRuntimeEvent): void {\n // Enforce queue cap — drop oldest events when full\n if (this.queue.length >= this.maxQueueSize) {\n this.queue.shift();\n this._droppedCount++;\n }\n this.queue.push(event);\n if (this.connected && this.queue.length >= 10) {\n this.flushQueue();\n }\n }\n\n private flushQueue(): void {\n if (!this.connected || this.queue.length === 0) return;\n\n const batch = this.queue.splice(0);\n this.send({\n type: 'event',\n payload: { events: batch },\n timestamp: Date.now(),\n sessionId: this.sessionId,\n });\n }\n\n private send(msg: WSMessage): void {\n if (this.ws?.readyState === WebSocket.OPEN) {\n try {\n this.ws.send(JSON.stringify(msg));\n } catch {\n // Connection may have closed between check and send\n }\n }\n }\n\n disconnect(): void {\n if (this.reconnectTimer) {\n clearTimeout(this.reconnectTimer);\n this.reconnectTimer = null;\n }\n this.cleanup();\n this.flushQueue();\n if (this.ws) {\n this.ws.close();\n this.ws = null;\n }\n this.connected = false;\n }\n}\n","import type { ServerRuntimeEvent } from './types.js';\n\n// ============================================================\n// HTTP Transport for Serverless Environments\n// Fire-and-forget POST to collector's /api/events endpoint.\n// Uses global fetch (Node 20+, Cloudflare Workers, Vercel Edge, Bun).\n// ============================================================\n\nexport interface HttpTransportOptions {\n url: string;\n sessionId: string;\n appName: string;\n sdkVersion: string;\n authToken?: string;\n maxQueueSize?: number;\n flushIntervalMs?: number;\n maxRetries?: number;\n retryDelayMs?: number;\n}\n\nexport class HttpTransport {\n private queue: ServerRuntimeEvent[] = [];\n private url: string;\n private sessionId: string;\n private appName: string;\n private sdkVersion: string;\n private authToken: string | undefined;\n private maxQueueSize: number;\n private maxRetries: number;\n private retryDelayMs: number;\n private flushTimer: ReturnType<typeof setInterval> | null = null;\n private _droppedCount = 0;\n private sessionRegistered = false;\n\n constructor(options: HttpTransportOptions) {\n this.url = options.url;\n this.sessionId = options.sessionId;\n this.appName = options.appName;\n this.sdkVersion = options.sdkVersion;\n this.authToken = options.authToken;\n this.maxQueueSize = options.maxQueueSize ?? 10_000;\n this.maxRetries = options.maxRetries ?? 2;\n this.retryDelayMs = options.retryDelayMs ?? 500;\n\n const intervalMs = options.flushIntervalMs ?? 1000;\n this.flushTimer = setInterval(() => this.flush(), intervalMs);\n // Unref so the timer doesn't keep the process alive in serverless\n if (this.flushTimer && typeof this.flushTimer === 'object' && 'unref' in this.flushTimer) {\n this.flushTimer.unref();\n }\n }\n\n get droppedCount(): number {\n return this._droppedCount;\n }\n\n sendEvent(event: ServerRuntimeEvent): void {\n if (this.queue.length >= this.maxQueueSize) {\n this.queue.shift();\n this._droppedCount++;\n }\n this.queue.push(event);\n }\n\n async flush(): Promise<void> {\n if (this.queue.length === 0) return;\n\n const batch = this.queue.splice(0);\n const payload: Record<string, unknown> = {\n sessionId: this.sessionId,\n events: batch,\n };\n\n // Include appName/sdkVersion on first request to auto-register session\n if (!this.sessionRegistered) {\n payload.appName = this.appName;\n payload.sdkVersion = this.sdkVersion;\n }\n\n const body = JSON.stringify(payload);\n\n for (let attempt = 0; attempt <= this.maxRetries; attempt++) {\n try {\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n };\n if (this.authToken) {\n headers['Authorization'] = `Bearer ${this.authToken}`;\n }\n\n const response = await fetch(this.url, {\n method: 'POST',\n headers,\n body,\n signal: AbortSignal.timeout(5000),\n });\n\n if (response.ok) {\n this.sessionRegistered = true;\n return;\n }\n\n // Non-retryable errors — drop the batch\n if (response.status === 401 || response.status === 400) {\n return;\n }\n } catch {\n // Network error — retry\n }\n\n if (attempt < this.maxRetries) {\n await new Promise(r => setTimeout(r, this.retryDelayMs));\n }\n }\n\n // All retries exhausted — events are lost (fire-and-forget model)\n }\n\n async disconnect(): Promise<void> {\n if (this.flushTimer) {\n clearInterval(this.flushTimer);\n this.flushTimer = null;\n }\n await this.flush();\n }\n}\n","import { randomBytes } from 'node:crypto';\n\nexport function generateId(): string {\n return randomBytes(16).toString('hex');\n}\n\nexport function generateSessionId(): string {\n return `srv-${randomBytes(8).toString('hex')}`;\n}\n","const INTERNAL_FRAMES = [\n 'RuntimeScope',\n 'server-sdk',\n 'captureQuery',\n 'instrumentPrisma',\n 'instrumentDrizzle',\n 'instrumentKnex',\n 'instrumentPg',\n 'instrumentMysql2',\n 'instrumentBetterSqlite3',\n];\n\nexport function captureStack(skipFrames = 3): string {\n const err = new Error();\n const stack = err.stack ?? '';\n const lines = stack.split('\\n').slice(skipFrames);\n\n // Filter out internal frames\n const filtered = lines.filter(\n (line) => !INTERNAL_FRAMES.some((frame) => line.includes(frame))\n );\n\n return filtered.slice(0, 10).join('\\n');\n}\n","import type { ServerRuntimeEvent } from './types.js';\n\nexport interface SamplerConfig {\n /** Probabilistic sample rate: 0.0–1.0 (default: 1.0 = keep all) */\n sampleRate?: number;\n /** Max events per second before dropping (default: unlimited) */\n maxEventsPerSecond?: number;\n}\n\nexport class Sampler {\n private windowCount = 0;\n private windowStart = Date.now();\n private _droppedCount = 0;\n\n constructor(private config: SamplerConfig) {}\n\n get droppedCount(): number {\n return this._droppedCount;\n }\n\n shouldSample(_event: ServerRuntimeEvent): boolean {\n // 1. Probabilistic sampling\n const rate = this.config.sampleRate;\n if (rate !== undefined && rate < 1) {\n if (Math.random() > rate) {\n this._droppedCount++;\n return false;\n }\n }\n\n // 2. Rate limiting (1-second sliding window)\n const maxPerSec = this.config.maxEventsPerSecond;\n if (maxPerSec !== undefined) {\n const now = Date.now();\n if (now - this.windowStart >= 1000) {\n this.windowCount = 0;\n this.windowStart = now;\n }\n if (this.windowCount >= maxPerSec) {\n this._droppedCount++;\n return false;\n }\n this.windowCount++;\n }\n\n return true;\n }\n\n reset(): void {\n this.windowCount = 0;\n this.windowStart = Date.now();\n this._droppedCount = 0;\n }\n}\n","import type { DatabaseOperation } from '../types.js';\n\nconst OPERATION_RE = /^\\s*(SELECT|INSERT|UPDATE|DELETE|CREATE|DROP|ALTER|TRUNCATE|WITH)\\b/i;\nconst TABLE_RE = /\\b(?:FROM|JOIN|INTO|UPDATE|TABLE)\\s+[\"'`]?(\\w+)[\"'`]?/gi;\nconst PARAM_RE = /\\$\\d+|\\?|:\\w+/g;\nconst STRING_LITERAL_RE = /'[^']*'/g;\nconst NUMBER_LITERAL_RE = /\\b\\d+\\.?\\d*\\b/g;\n\nexport function parseOperation(query: string): DatabaseOperation {\n const match = query.match(OPERATION_RE);\n if (!match) return 'OTHER';\n const op = match[1].toUpperCase();\n if (op === 'SELECT' || op === 'WITH') return 'SELECT';\n if (op === 'INSERT') return 'INSERT';\n if (op === 'UPDATE') return 'UPDATE';\n if (op === 'DELETE') return 'DELETE';\n return 'OTHER';\n}\n\nexport function parseTablesAccessed(query: string): string[] {\n const tables = new Set<string>();\n let match: RegExpExecArray | null;\n const re = new RegExp(TABLE_RE.source, TABLE_RE.flags);\n while ((match = re.exec(query)) !== null) {\n const table = match[1].toLowerCase();\n // Skip SQL keywords that might be false positives\n if (!['select', 'where', 'and', 'or', 'not', 'null', 'set', 'values'].includes(table)) {\n tables.add(table);\n }\n }\n return [...tables];\n}\n\nexport function normalizeQuery(query: string): string {\n return query\n .replace(STRING_LITERAL_RE, '?')\n .replace(NUMBER_LITERAL_RE, '?')\n .replace(PARAM_RE, '?')\n .replace(/\\s+/g, ' ')\n .trim();\n}\n\nexport function redactParams(params: unknown[]): string {\n return JSON.stringify(\n params.map((p) => {\n if (p === null) return 'NULL';\n if (typeof p === 'string') return '<string>';\n if (typeof p === 'number') return '<number>';\n if (typeof p === 'boolean') return '<boolean>';\n if (p instanceof Date) return '<date>';\n if (Buffer.isBuffer(p)) return '<buffer>';\n return '<object>';\n })\n );\n}\n","// Save original console methods BEFORE any interceptors patch them.\n// Used for SDK-internal logging to avoid recursion.\nexport const _log = {\n log: console.log.bind(console),\n warn: console.warn.bind(console),\n error: console.error.bind(console),\n debug: console.debug.bind(console),\n};\n","import type { DatabaseEvent, DatabaseSource } from '../types.js';\nimport { generateId } from '../utils/id.js';\nimport { parseOperation, parseTablesAccessed, normalizeQuery, redactParams } from '../utils/sql-parser.js';\nimport { captureStack } from '../utils/stack.js';\nimport { _log } from '../utils/log.js';\n\nexport interface PrismaInstrumentOptions {\n sessionId: string;\n captureStackTraces?: boolean;\n redact?: boolean;\n onEvent: (event: DatabaseEvent) => void;\n}\n\n/**\n * Instrument a Prisma client to capture database queries.\n * Supports both Prisma v4 ($on) and v5+ ($extends).\n * Returns a restore function to remove instrumentation.\n */\nexport function instrumentPrisma(\n client: unknown,\n options: PrismaInstrumentOptions\n): () => void {\n const prisma = client as Record<string, unknown>;\n const source: DatabaseSource = 'prisma';\n\n // Try v5+ $extends approach first\n if (typeof prisma.$extends === 'function') {\n // $extends returns a new client, so we monkey-patch query methods\n // For v5, we use the middleware-like $allOperations\n try {\n const extended = (prisma.$extends as Function)({\n query: {\n $allOperations({ operation, model, args, query }: {\n operation: string;\n model: string;\n args: unknown;\n query: (args: unknown) => Promise<unknown>;\n }) {\n const start = performance.now();\n return (query as Function)(args).then((result: unknown) => {\n const duration = performance.now() - start;\n const queryStr = `prisma.${model}.${operation}(${JSON.stringify(args).slice(0, 200)})`;\n options.onEvent({\n eventId: generateId(),\n sessionId: options.sessionId,\n timestamp: Date.now(),\n eventType: 'database',\n query: queryStr,\n normalizedQuery: `prisma.${model}.${operation}(?)`,\n duration,\n tablesAccessed: model ? [model.toLowerCase()] : [],\n operation: mapPrismaOperation(operation),\n source,\n stackTrace: options.captureStackTraces ? captureStack() : undefined,\n rowsReturned: Array.isArray(result) ? result.length : undefined,\n });\n return result;\n }).catch((err: Error) => {\n const duration = performance.now() - start;\n const queryStr = `prisma.${model}.${operation}(${JSON.stringify(args).slice(0, 200)})`;\n options.onEvent({\n eventId: generateId(),\n sessionId: options.sessionId,\n timestamp: Date.now(),\n eventType: 'database',\n query: queryStr,\n normalizedQuery: `prisma.${model}.${operation}(?)`,\n duration,\n tablesAccessed: model ? [model.toLowerCase()] : [],\n operation: mapPrismaOperation(operation),\n source,\n error: err.message,\n stackTrace: options.captureStackTraces ? captureStack() : undefined,\n });\n throw err;\n });\n },\n },\n });\n // Copy the extended client's methods back (this is a best-effort approach)\n Object.assign(prisma, extended);\n return () => {\n // $extends creates a new client; there's no clean undo for v5\n };\n } catch {\n // Fall through to $on approach\n }\n }\n\n // v4 approach: $on('query')\n if (typeof prisma.$on === 'function') {\n (prisma.$on as Function)('query', (e: {\n query: string;\n params: string;\n duration: number;\n target: string;\n }) => {\n options.onEvent({\n eventId: generateId(),\n sessionId: options.sessionId,\n timestamp: Date.now(),\n eventType: 'database',\n query: e.query,\n normalizedQuery: normalizeQuery(e.query),\n duration: e.duration,\n tablesAccessed: parseTablesAccessed(e.query),\n operation: parseOperation(e.query),\n source,\n params: options.redact !== false ? redactParams(JSON.parse(e.params || '[]')) : e.params,\n stackTrace: options.captureStackTraces ? captureStack() : undefined,\n });\n });\n return () => {\n // $on doesn't provide a clean unsubscribe for v4\n };\n }\n\n _log.warn('[RuntimeScope] Prisma client does not support $on or $extends');\n return () => {};\n}\n\nfunction mapPrismaOperation(op: string): DatabaseEvent['operation'] {\n const lower = op.toLowerCase();\n if (lower.includes('find') || lower === 'aggregate' || lower === 'count' || lower === 'groupby') return 'SELECT';\n if (lower.includes('create') || lower === 'createMany') return 'INSERT';\n if (lower.includes('update') || lower === 'upsert') return 'UPDATE';\n if (lower.includes('delete')) return 'DELETE';\n return 'OTHER';\n}\n","import type { DatabaseEvent } from '../types.js';\nimport { generateId } from '../utils/id.js';\nimport { parseOperation, parseTablesAccessed, normalizeQuery, redactParams } from '../utils/sql-parser.js';\nimport { captureStack } from '../utils/stack.js';\nimport { _log } from '../utils/log.js';\n\nexport interface PgInstrumentOptions {\n sessionId: string;\n captureStackTraces?: boolean;\n redact?: boolean;\n onEvent: (event: DatabaseEvent) => void;\n}\n\n/**\n * Instrument a pg Pool or Client to capture database queries.\n * Wraps the query method to intercept all SQL execution.\n */\nexport function instrumentPg(\n pool: unknown,\n options: PgInstrumentOptions\n): () => void {\n const client = pool as Record<string, unknown>;\n const originalQuery = client.query as Function;\n\n if (typeof originalQuery !== 'function') {\n _log.warn('[RuntimeScope] pg client does not have a query method');\n return () => {};\n }\n\n client.query = function (...args: unknown[]) {\n const start = performance.now();\n let queryText = '';\n let params: unknown[] | undefined;\n\n // pg.query supports multiple signatures\n if (typeof args[0] === 'string') {\n queryText = args[0];\n if (Array.isArray(args[1])) params = args[1];\n } else if (typeof args[0] === 'object' && args[0] !== null) {\n const config = args[0] as Record<string, unknown>;\n queryText = (config.text as string) ?? '';\n params = config.values as unknown[] | undefined;\n }\n\n const result = originalQuery.apply(this, args);\n\n if (result && typeof (result as Promise<unknown>).then === 'function') {\n return (result as Promise<unknown>).then((res: unknown) => {\n const duration = performance.now() - start;\n const pgResult = res as { rowCount?: number; rows?: unknown[] };\n options.onEvent({\n eventId: generateId(),\n sessionId: options.sessionId,\n timestamp: Date.now(),\n eventType: 'database',\n query: queryText,\n normalizedQuery: normalizeQuery(queryText),\n duration,\n rowsReturned: pgResult.rows?.length,\n rowsAffected: pgResult.rowCount ?? undefined,\n tablesAccessed: parseTablesAccessed(queryText),\n operation: parseOperation(queryText),\n source: 'pg',\n params: params && options.redact !== false ? redactParams(params) : undefined,\n stackTrace: options.captureStackTraces ? captureStack() : undefined,\n });\n return res;\n }).catch((err: Error) => {\n const duration = performance.now() - start;\n options.onEvent({\n eventId: generateId(),\n sessionId: options.sessionId,\n timestamp: Date.now(),\n eventType: 'database',\n query: queryText,\n normalizedQuery: normalizeQuery(queryText),\n duration,\n tablesAccessed: parseTablesAccessed(queryText),\n operation: parseOperation(queryText),\n source: 'pg',\n error: err.message,\n params: params && options.redact !== false ? redactParams(params) : undefined,\n stackTrace: options.captureStackTraces ? captureStack() : undefined,\n });\n throw err;\n });\n }\n\n return result;\n };\n\n return () => {\n client.query = originalQuery;\n };\n}\n","import type { DatabaseEvent } from '../types.js';\nimport { generateId } from '../utils/id.js';\nimport { parseOperation, parseTablesAccessed, normalizeQuery, redactParams } from '../utils/sql-parser.js';\nimport { captureStack } from '../utils/stack.js';\n\nexport interface KnexInstrumentOptions {\n sessionId: string;\n captureStackTraces?: boolean;\n redact?: boolean;\n onEvent: (event: DatabaseEvent) => void;\n}\n\n/**\n * Instrument a Knex instance to capture database queries.\n * Uses Knex's built-in event system (query, query-response, query-error).\n */\nexport function instrumentKnex(\n knex: unknown,\n options: KnexInstrumentOptions\n): () => void {\n const instance = knex as {\n on: (event: string, handler: (...args: unknown[]) => void) => void;\n removeListener: (event: string, handler: (...args: unknown[]) => void) => void;\n };\n\n const pendingQueries = new Map<string, { query: string; params: unknown[]; start: number }>();\n\n const onQuery = (data: { __knexQueryUid: string; sql: string; bindings: unknown[] }) => {\n pendingQueries.set(data.__knexQueryUid, {\n query: data.sql,\n params: data.bindings ?? [],\n start: performance.now(),\n });\n };\n\n const onQueryResponse = (_response: unknown, data: { __knexQueryUid: string; sql: string; bindings: unknown[] }, _builder: unknown) => {\n const pending = pendingQueries.get(data.__knexQueryUid);\n pendingQueries.delete(data.__knexQueryUid);\n const duration = pending ? performance.now() - pending.start : 0;\n const queryText = pending?.query ?? data.sql;\n const params = pending?.params ?? data.bindings;\n\n const rows = Array.isArray(_response) ? _response.length : undefined;\n\n options.onEvent({\n eventId: generateId(),\n sessionId: options.sessionId,\n timestamp: Date.now(),\n eventType: 'database',\n query: queryText,\n normalizedQuery: normalizeQuery(queryText),\n duration,\n rowsReturned: rows,\n tablesAccessed: parseTablesAccessed(queryText),\n operation: parseOperation(queryText),\n source: 'knex',\n params: params.length > 0 && options.redact !== false ? redactParams(params) : undefined,\n stackTrace: options.captureStackTraces ? captureStack() : undefined,\n });\n };\n\n const onQueryError = (error: Error, data: { __knexQueryUid: string; sql: string; bindings: unknown[] }) => {\n const pending = pendingQueries.get(data.__knexQueryUid);\n pendingQueries.delete(data.__knexQueryUid);\n const duration = pending ? performance.now() - pending.start : 0;\n const queryText = pending?.query ?? data.sql;\n const params = pending?.params ?? data.bindings;\n\n options.onEvent({\n eventId: generateId(),\n sessionId: options.sessionId,\n timestamp: Date.now(),\n eventType: 'database',\n query: queryText,\n normalizedQuery: normalizeQuery(queryText),\n duration,\n tablesAccessed: parseTablesAccessed(queryText),\n operation: parseOperation(queryText),\n source: 'knex',\n error: error.message,\n params: params.length > 0 && options.redact !== false ? redactParams(params) : undefined,\n stackTrace: options.captureStackTraces ? captureStack() : undefined,\n });\n };\n\n instance.on('query', onQuery as (...args: unknown[]) => void);\n instance.on('query-response', onQueryResponse as (...args: unknown[]) => void);\n instance.on('query-error', onQueryError as (...args: unknown[]) => void);\n\n return () => {\n instance.removeListener('query', onQuery as (...args: unknown[]) => void);\n instance.removeListener('query-response', onQueryResponse as (...args: unknown[]) => void);\n instance.removeListener('query-error', onQueryError as (...args: unknown[]) => void);\n pendingQueries.clear();\n };\n}\n","import type { DatabaseEvent } from '../types.js';\nimport { generateId } from '../utils/id.js';\nimport { parseOperation, parseTablesAccessed, normalizeQuery, redactParams } from '../utils/sql-parser.js';\nimport { captureStack } from '../utils/stack.js';\nimport { _log } from '../utils/log.js';\n\nexport interface DrizzleInstrumentOptions {\n sessionId: string;\n captureStackTraces?: boolean;\n redact?: boolean;\n onEvent: (event: DatabaseEvent) => void;\n}\n\n/**\n * Instrument a Drizzle ORM database instance.\n * Wraps the session's execute method to capture query timing and results.\n * Falls back to wrapping the underlying driver's query method if execute\n * is not available.\n */\nexport function instrumentDrizzle(\n db: unknown,\n options: DrizzleInstrumentOptions\n): () => void {\n const drizzleDb = db as Record<string, unknown>;\n\n // Drizzle stores internals under db._ (session, schema, etc.)\n const internals = drizzleDb._ as Record<string, unknown> | undefined;\n if (!internals) {\n _log.warn('[RuntimeScope] Drizzle db does not have internals (_). Cannot instrument.');\n return () => {};\n }\n\n const session = internals.session as Record<string, unknown> | undefined;\n if (!session) {\n _log.warn('[RuntimeScope] Drizzle db does not have a session. Cannot instrument.');\n return () => {};\n }\n\n // Strategy: wrap session.execute() which runs the actual SQL\n const originalExecute = session.execute as Function | undefined;\n\n if (typeof originalExecute === 'function') {\n session.execute = function (this: unknown, queryOrSql: unknown) {\n const start = performance.now();\n let queryText = '';\n let params: unknown[] | undefined;\n\n // Drizzle passes a query object with sql and params properties\n if (queryOrSql && typeof queryOrSql === 'object') {\n const q = queryOrSql as Record<string, unknown>;\n queryText = (q.sql as string) ?? (q.query as string) ?? String(queryOrSql);\n params = q.params as unknown[] | undefined;\n } else if (typeof queryOrSql === 'string') {\n queryText = queryOrSql;\n }\n\n const stack = options.captureStackTraces ? captureStack() : undefined;\n\n const result = originalExecute.apply(this, arguments);\n\n // Handle promise (async queries)\n if (result && typeof (result as Promise<unknown>).then === 'function') {\n return (result as Promise<unknown>).then((res: unknown) => {\n const duration = performance.now() - start;\n const rows = Array.isArray(res) ? res.length : undefined;\n\n options.onEvent({\n eventId: generateId(),\n sessionId: options.sessionId,\n timestamp: Date.now(),\n eventType: 'database',\n query: queryText,\n normalizedQuery: normalizeQuery(queryText),\n duration,\n rowsReturned: rows,\n tablesAccessed: parseTablesAccessed(queryText),\n operation: parseOperation(queryText),\n source: 'drizzle',\n params: params && options.redact !== false ? redactParams(params) : undefined,\n stackTrace: stack,\n });\n return res;\n }).catch((err: Error) => {\n const duration = performance.now() - start;\n options.onEvent({\n eventId: generateId(),\n sessionId: options.sessionId,\n timestamp: Date.now(),\n eventType: 'database',\n query: queryText,\n normalizedQuery: normalizeQuery(queryText),\n duration,\n tablesAccessed: parseTablesAccessed(queryText),\n operation: parseOperation(queryText),\n source: 'drizzle',\n error: err.message,\n params: params && options.redact !== false ? redactParams(params) : undefined,\n stackTrace: stack,\n });\n throw err;\n });\n }\n\n return result;\n };\n\n return () => {\n session.execute = originalExecute;\n };\n }\n\n // Fallback: instrument the underlying client's query method\n const client = (session as Record<string, unknown>).client as Record<string, unknown> | undefined;\n const originalQuery = client?.query as Function | undefined;\n\n if (client && typeof originalQuery === 'function') {\n client.query = function (this: unknown, ...args: unknown[]) {\n const start = performance.now();\n const queryText = typeof args[0] === 'string' ? args[0] : '';\n const params = Array.isArray(args[1]) ? args[1] : undefined;\n const stack = options.captureStackTraces ? captureStack() : undefined;\n\n const result = originalQuery.apply(this, args);\n\n if (result && typeof (result as Promise<unknown>).then === 'function') {\n return (result as Promise<unknown>).then((res: unknown) => {\n const duration = performance.now() - start;\n options.onEvent({\n eventId: generateId(),\n sessionId: options.sessionId,\n timestamp: Date.now(),\n eventType: 'database',\n query: queryText,\n normalizedQuery: normalizeQuery(queryText),\n duration,\n rowsReturned: Array.isArray(res) ? res.length : undefined,\n tablesAccessed: parseTablesAccessed(queryText),\n operation: parseOperation(queryText),\n source: 'drizzle',\n params: params && options.redact !== false ? redactParams(params) : undefined,\n stackTrace: stack,\n });\n return res;\n }).catch((err: Error) => {\n const duration = performance.now() - start;\n options.onEvent({\n eventId: generateId(),\n sessionId: options.sessionId,\n timestamp: Date.now(),\n eventType: 'database',\n query: queryText,\n normalizedQuery: normalizeQuery(queryText),\n duration,\n tablesAccessed: parseTablesAccessed(queryText),\n operation: parseOperation(queryText),\n source: 'drizzle',\n error: err.message,\n params: params && options.redact !== false ? redactParams(params) : undefined,\n stackTrace: stack,\n });\n throw err;\n });\n }\n\n return result;\n };\n\n return () => {\n client.query = originalQuery;\n };\n }\n\n _log.warn('[RuntimeScope] Drizzle db has no instrumentable execute or query method.');\n return () => {};\n}\n","import type { DatabaseEvent } from '../types.js';\nimport { generateId } from '../utils/id.js';\nimport { parseOperation, parseTablesAccessed, normalizeQuery, redactParams } from '../utils/sql-parser.js';\nimport { captureStack } from '../utils/stack.js';\nimport { _log } from '../utils/log.js';\n\nexport interface Mysql2InstrumentOptions {\n sessionId: string;\n captureStackTraces?: boolean;\n redact?: boolean;\n onEvent: (event: DatabaseEvent) => void;\n}\n\n/**\n * Instrument a mysql2 Pool or Connection to capture database queries.\n * Wraps query() and execute() methods.\n */\nexport function instrumentMysql2(\n pool: unknown,\n options: Mysql2InstrumentOptions\n): () => void {\n const client = pool as Record<string, unknown>;\n const originalQuery = client.query as Function | undefined;\n const originalExecute = client.execute as Function | undefined;\n\n if (typeof originalQuery !== 'function') {\n _log.warn('[RuntimeScope] mysql2 client does not have a query method');\n return () => {};\n }\n\n function wrapMethod(original: Function, methodName: string): Function {\n return function (this: unknown, ...args: unknown[]) {\n const start = performance.now();\n let queryText = '';\n let params: unknown[] | undefined;\n\n // mysql2 supports: query(sql), query(sql, values), query(options), query(options, values)\n if (typeof args[0] === 'string') {\n queryText = args[0];\n if (Array.isArray(args[1])) params = args[1];\n } else if (typeof args[0] === 'object' && args[0] !== null) {\n const config = args[0] as Record<string, unknown>;\n queryText = (config.sql as string) ?? '';\n params = config.values as unknown[] | undefined;\n if (!params && Array.isArray(args[1])) params = args[1];\n }\n\n // Find callback (last function argument)\n const lastArg = args[args.length - 1];\n const hasCallback = typeof lastArg === 'function';\n\n if (hasCallback) {\n // Callback style\n const cb = lastArg as (...cbArgs: unknown[]) => void;\n args[args.length - 1] = function (err: Error | null, results: unknown, fields: unknown) {\n const duration = performance.now() - start;\n const rows = Array.isArray(results) ? results.length : undefined;\n const affectedRows = results && typeof results === 'object'\n ? (results as Record<string, unknown>).affectedRows as number | undefined\n : undefined;\n\n options.onEvent({\n eventId: generateId(),\n sessionId: options.sessionId,\n timestamp: Date.now(),\n eventType: 'database',\n query: queryText,\n normalizedQuery: normalizeQuery(queryText),\n duration,\n rowsReturned: rows,\n rowsAffected: affectedRows,\n tablesAccessed: parseTablesAccessed(queryText),\n operation: parseOperation(queryText),\n source: 'mysql2',\n error: err?.message,\n params: params && options.redact !== false ? redactParams(params) : undefined,\n stackTrace: options.captureStackTraces ? captureStack() : undefined,\n });\n\n cb(err, results, fields);\n };\n return original.apply(this, args);\n }\n\n // Promise style (mysql2/promise)\n const result = original.apply(this, args);\n\n if (result && typeof (result as Promise<unknown>).then === 'function') {\n return (result as Promise<unknown>).then((res: unknown) => {\n const duration = performance.now() - start;\n const resultArr = Array.isArray(res) ? res : [res];\n const rows = Array.isArray(resultArr[0]) ? resultArr[0].length : undefined;\n const affectedRows = resultArr[0] && typeof resultArr[0] === 'object'\n ? (resultArr[0] as Record<string, unknown>).affectedRows as number | undefined\n : undefined;\n\n options.onEvent({\n eventId: generateId(),\n sessionId: options.sessionId,\n timestamp: Date.now(),\n eventType: 'database',\n query: queryText,\n normalizedQuery: normalizeQuery(queryText),\n duration,\n rowsReturned: rows,\n rowsAffected: affectedRows,\n tablesAccessed: parseTablesAccessed(queryText),\n operation: parseOperation(queryText),\n source: 'mysql2',\n params: params && options.redact !== false ? redactParams(params) : undefined,\n stackTrace: options.captureStackTraces ? captureStack() : undefined,\n });\n return res;\n }).catch((err: Error) => {\n const duration = performance.now() - start;\n options.onEvent({\n eventId: generateId(),\n sessionId: options.sessionId,\n timestamp: Date.now(),\n eventType: 'database',\n query: queryText,\n normalizedQuery: normalizeQuery(queryText),\n duration,\n tablesAccessed: parseTablesAccessed(queryText),\n operation: parseOperation(queryText),\n source: 'mysql2',\n error: err.message,\n params: params && options.redact !== false ? redactParams(params) : undefined,\n stackTrace: options.captureStackTraces ? captureStack() : undefined,\n });\n throw err;\n });\n }\n\n return result;\n };\n }\n\n client.query = wrapMethod(originalQuery, 'query');\n if (typeof originalExecute === 'function') {\n client.execute = wrapMethod(originalExecute, 'execute');\n }\n\n return () => {\n client.query = originalQuery;\n if (originalExecute) client.execute = originalExecute;\n };\n}\n","import type { DatabaseEvent } from '../types.js';\nimport { generateId } from '../utils/id.js';\nimport { parseOperation, parseTablesAccessed, normalizeQuery, redactParams } from '../utils/sql-parser.js';\nimport { captureStack } from '../utils/stack.js';\nimport { _log } from '../utils/log.js';\n\nexport interface BetterSqlite3Options {\n sessionId: string;\n captureStackTraces?: boolean;\n redact?: boolean;\n onEvent: (event: DatabaseEvent) => void;\n}\n\n/**\n * Instrument a better-sqlite3 Database instance.\n * Wraps db.prepare() to return instrumented statements whose\n * run(), get(), all(), and iterate() methods emit DatabaseEvents.\n *\n * better-sqlite3 is fully synchronous — no promise handling needed.\n */\nexport function instrumentBetterSqlite3(\n db: unknown,\n options: BetterSqlite3Options\n): () => void {\n const database = db as Record<string, unknown>;\n const originalPrepare = database.prepare as Function | undefined;\n const originalExec = database.exec as Function | undefined;\n\n if (typeof originalPrepare !== 'function') {\n _log.warn('[RuntimeScope] better-sqlite3 db does not have a prepare method');\n return () => {};\n }\n\n function emitQuery(\n queryText: string,\n start: number,\n result?: unknown,\n error?: string,\n params?: unknown[]\n ): void {\n const duration = performance.now() - start;\n const rows = Array.isArray(result) ? result.length : undefined;\n const changes = result && typeof result === 'object'\n ? (result as Record<string, unknown>).changes as number | undefined\n : undefined;\n\n options.onEvent({\n eventId: generateId(),\n sessionId: options.sessionId,\n timestamp: Date.now(),\n eventType: 'database',\n query: queryText,\n normalizedQuery: normalizeQuery(queryText),\n duration,\n rowsReturned: rows,\n rowsAffected: changes,\n tablesAccessed: parseTablesAccessed(queryText),\n operation: parseOperation(queryText),\n source: 'better-sqlite3',\n error,\n params: params && options.redact !== false ? redactParams(params) : undefined,\n stackTrace: options.captureStackTraces ? captureStack() : undefined,\n });\n }\n\n // Wrap db.prepare() to return instrumented statements\n database.prepare = function (sql: string) {\n const stmt = (originalPrepare as Function).call(this, sql);\n const stmtObj = stmt as Record<string, unknown>;\n\n // Wrap run(), get(), all()\n const methods = ['run', 'get', 'all'] as const;\n for (const method of methods) {\n const original = stmtObj[method] as Function;\n if (typeof original !== 'function') continue;\n\n stmtObj[method] = function (...args: unknown[]) {\n const start = performance.now();\n try {\n const result = original.apply(this, args);\n emitQuery(sql, start, result, undefined, args);\n return result;\n } catch (err) {\n emitQuery(sql, start, undefined, (err as Error).message, args);\n throw err;\n }\n };\n }\n\n // Wrap iterate() — returns an iterator\n const originalIterate = stmtObj.iterate as Function | undefined;\n if (typeof originalIterate === 'function') {\n stmtObj.iterate = function (...args: unknown[]) {\n const start = performance.now();\n const iter = originalIterate.apply(this, args);\n let rowCount = 0;\n\n const originalNext = iter.next.bind(iter);\n let emitted = false;\n iter.next = function () {\n const result = originalNext();\n if (!result.done) rowCount++;\n if (result.done && !emitted) {\n emitted = true;\n emitQuery(sql, start, { length: rowCount }, undefined, args);\n }\n return result;\n };\n\n return iter;\n };\n }\n\n return stmt;\n };\n\n // Wrap db.exec() for raw SQL execution\n if (typeof originalExec === 'function') {\n database.exec = function (sql: string) {\n const start = performance.now();\n try {\n const result = (originalExec as Function).call(this, sql);\n emitQuery(sql, start);\n return result;\n } catch (err) {\n emitQuery(sql, start, undefined, (err as Error).message);\n throw err;\n }\n };\n }\n\n return () => {\n database.prepare = originalPrepare;\n if (originalExec) database.exec = originalExec;\n };\n}\n","/** Safely serialize a value, handling circular references, functions, symbols, and errors. */\nexport function safeSerialize(value: unknown, maxDepth = 5): unknown {\n const seen = new WeakSet();\n\n function walk(val: unknown, depth: number): unknown {\n if (depth > maxDepth) return '[max depth]';\n if (val === null || val === undefined) return val;\n if (typeof val === 'function') return `[Function: ${val.name || 'anonymous'}]`;\n if (typeof val === 'symbol') return val.toString();\n if (typeof val === 'bigint') return val.toString();\n if (typeof val !== 'object') return val;\n\n if (val instanceof Error) {\n return { name: val.name, message: val.message, stack: val.stack };\n }\n if (val instanceof Date) {\n return val.toISOString();\n }\n if (val instanceof RegExp) {\n return val.toString();\n }\n\n if (seen.has(val as object)) return '[Circular]';\n seen.add(val as object);\n\n if (Array.isArray(val)) {\n return val.map((v) => walk(v, depth + 1));\n }\n\n const result: Record<string, unknown> = {};\n for (const key of Object.keys(val as Record<string, unknown>)) {\n result[key] = walk((val as Record<string, unknown>)[key], depth + 1);\n }\n return result;\n }\n\n return walk(value, 0);\n}\n","import { AsyncLocalStorage } from 'node:async_hooks';\n\nexport interface RequestContext {\n sessionId: string;\n requestId?: string;\n metadata?: Record<string, unknown>;\n}\n\nconst storage = new AsyncLocalStorage<RequestContext>();\n\n/**\n * Run a function within a request context.\n * All async operations within `fn` will inherit this context.\n */\nexport function runWithContext<T>(ctx: RequestContext, fn: () => T): T {\n return storage.run(ctx, fn);\n}\n\n/**\n * Get the current request context, if any.\n */\nexport function getRequestContext(): RequestContext | undefined {\n return storage.getStore();\n}\n\n/**\n * Get the sessionId from the current request context,\n * falling back to the global sessionId.\n */\nexport function getSessionId(fallback: string): string {\n return storage.getStore()?.sessionId ?? fallback;\n}\n","import { generateId } from '../utils/id.js';\nimport { safeSerialize } from '../utils/serialize.js';\nimport { getSessionId } from '../context.js';\nimport type { ConsoleEvent, ConsoleLevel, ServerRuntimeEvent } from '../types.js';\n\ntype EmitFn = (event: ConsoleEvent) => void;\n\nconst LEVELS: ConsoleLevel[] = ['log', 'warn', 'error', 'info', 'debug', 'trace'];\n\nexport interface ConsoleInterceptorOptions {\n levels?: ConsoleLevel[];\n captureStackTraces?: boolean;\n beforeSend?: (event: ServerRuntimeEvent) => ServerRuntimeEvent | null;\n}\n\nexport function interceptConsole(\n emit: EmitFn,\n sessionId: string,\n options?: ConsoleInterceptorOptions\n): () => void {\n const levels = options?.levels ?? LEVELS;\n const captureStack = options?.captureStackTraces ?? true;\n const originals: Record<string, (...args: unknown[]) => void> = {};\n\n for (const level of levels) {\n originals[level] = console[level].bind(console);\n\n console[level] = (...args: unknown[]) => {\n const message = args\n .map((a) => (typeof a === 'string' ? a : stringifyArg(a)))\n .join(' ');\n\n const event: ConsoleEvent = {\n eventId: generateId(),\n sessionId: getSessionId(sessionId),\n timestamp: Date.now(),\n eventType: 'console',\n level,\n message,\n args: args.map((a) => safeSerialize(a, 3)),\n stackTrace:\n captureStack && (level === 'error' || level === 'trace')\n ? new Error().stack?.split('\\n').slice(2).join('\\n')\n : undefined,\n sourceFile: undefined,\n };\n\n if (options?.beforeSend) {\n const filtered = options.beforeSend(event);\n if (filtered) emit(filtered as ConsoleEvent);\n } else {\n emit(event);\n }\n\n // Call original — MUST come after emit, and MUST use saved reference\n originals[level](...args);\n };\n }\n\n return () => {\n for (const level of levels) {\n console[level] = originals[level];\n }\n };\n}\n\nfunction stringifyArg(arg: unknown): string {\n try {\n return JSON.stringify(arg);\n } catch {\n return String(arg);\n }\n}\n","import { generateId } from '../utils/id.js';\nimport { safeSerialize } from '../utils/serialize.js';\nimport { getSessionId } from '../context.js';\nimport type { ConsoleEvent, ServerRuntimeEvent } from '../types.js';\n\ntype EmitFn = (event: ConsoleEvent) => void;\n\nexport interface ErrorInterceptorOptions {\n beforeSend?: (event: ServerRuntimeEvent) => ServerRuntimeEvent | null;\n}\n\nexport function interceptErrors(\n emit: EmitFn,\n sessionId: string,\n options?: ErrorInterceptorOptions\n): () => void {\n const onUncaughtException = (error: Error) => {\n const event: ConsoleEvent = {\n eventId: generateId(),\n sessionId: getSessionId(sessionId),\n timestamp: Date.now(),\n eventType: 'console',\n level: 'error',\n message: `[Uncaught] ${error.message}`,\n args: [safeSerialize(error, 3)],\n stackTrace: error.stack,\n sourceFile: extractSourceFile(error.stack),\n };\n\n if (options?.beforeSend) {\n const filtered = options.beforeSend(event);\n if (filtered) emit(filtered as ConsoleEvent);\n } else {\n emit(event);\n }\n\n // Preserve Node.js default crash behavior — set exit code so the\n // process still terminates after all listeners have run\n process.exitCode = 1;\n };\n\n const onUnhandledRejection = (reason: unknown) => {\n let message: string;\n let stackTrace: string | undefined;\n\n if (reason instanceof Error) {\n message = reason.message;\n stackTrace = reason.stack;\n } else if (typeof reason === 'string') {\n message = reason;\n } else {\n try {\n message = JSON.stringify(reason);\n } catch {\n message = String(reason);\n }\n }\n\n const event: ConsoleEvent = {\n eventId: generateId(),\n sessionId: getSessionId(sessionId),\n timestamp: Date.now(),\n eventType: 'console',\n level: 'error',\n message: `[Unhandled Rejection] ${message}`,\n args: [safeSerialize(reason, 3)],\n stackTrace,\n sourceFile: undefined,\n };\n\n if (options?.beforeSend) {\n const filtered = options.beforeSend(event);\n if (filtered) emit(filtered as ConsoleEvent);\n } else {\n emit(event);\n }\n };\n\n process.on('uncaughtException', onUncaughtException);\n process.on('unhandledRejection', onUnhandledRejection);\n\n return () => {\n process.removeListener('uncaughtException', onUncaughtException);\n process.removeListener('unhandledRejection', onUnhandledRejection);\n };\n}\n\nfunction extractSourceFile(stack?: string): string | undefined {\n if (!stack) return undefined;\n // Find first non-internal frame\n const lines = stack.split('\\n');\n for (const line of lines.slice(1)) {\n const match = line.match(/at\\s+.*?\\((.+?):(\\d+):(\\d+)\\)/);\n if (match && !match[1].includes('node_modules') && !match[1].includes('node:')) {\n return `${match[1]}:${match[2]}:${match[3]}`;\n }\n }\n return undefined;\n}\n","import http from 'node:http';\nimport https from 'node:https';\nimport { generateId } from '../utils/id.js';\nimport { getSessionId } from '../context.js';\nimport type { NetworkEvent, ServerRuntimeEvent } from '../types.js';\n\ntype EmitFn = (event: NetworkEvent) => void;\n\nexport interface HttpInterceptorOptions {\n captureBody?: boolean;\n maxBodySize?: number;\n redactHeaders?: string[];\n ignoreUrls?: (string | RegExp)[];\n beforeSend?: (event: ServerRuntimeEvent) => ServerRuntimeEvent | null;\n}\n\nconst DEFAULT_REDACT_HEADERS = ['authorization', 'cookie', 'set-cookie', 'x-api-key'];\n\nexport function interceptHttp(\n emit: EmitFn,\n sessionId: string,\n options?: HttpInterceptorOptions\n): () => void {\n const maxBodySize = options?.maxBodySize ?? 65536;\n const redactSet = new Set(\n (options?.redactHeaders ?? DEFAULT_REDACT_HEADERS).map((h) => h.toLowerCase())\n );\n const ignorePatterns = options?.ignoreUrls ?? [];\n\n const originalHttpRequest = http.request;\n const originalHttpsRequest = https.request;\n\n function shouldIgnore(url: string): boolean {\n for (const pattern of ignorePatterns) {\n if (typeof pattern === 'string') {\n if (url.includes(pattern)) return true;\n } else if (pattern.test(url)) {\n return true;\n }\n }\n return false;\n }\n\n function redactHeaders(\n headers: Record<string, string | string[] | number | undefined>\n ): Record<string, string> {\n const result: Record<string, string> = {};\n for (const [key, val] of Object.entries(headers)) {\n if (val === undefined) continue;\n const lk = key.toLowerCase();\n result[lk] = redactSet.has(lk) ? '[REDACTED]' : String(val);\n }\n return result;\n }\n\n function buildUrl(\n input: string | URL | http.RequestOptions,\n protocol: 'http' | 'https'\n ): string {\n if (typeof input === 'string') return input;\n if (input instanceof URL) return input.toString();\n // RequestOptions\n const host = input.hostname ?? input.host ?? 'localhost';\n const port = input.port ? `:${input.port}` : '';\n const path = input.path ?? '/';\n return `${protocol}://${host}${port}${path}`;\n }\n\n function wrapRequest(\n original: typeof http.request,\n protocol: 'http' | 'https'\n ): typeof http.request {\n return function wrappedRequest(\n this: unknown,\n ...args: Parameters<typeof http.request>\n ): http.ClientRequest {\n const url = buildUrl(args[0], protocol);\n\n if (shouldIgnore(url)) {\n return original.apply(this, args as never) as http.ClientRequest;\n }\n\n const startTime = performance.now();\n\n // Extract method from args\n let method = 'GET';\n if (typeof args[0] !== 'string' && !(args[0] instanceof URL)) {\n method = (args[0] as http.RequestOptions).method?.toUpperCase() ?? 'GET';\n } else if (args[1] && typeof args[1] === 'object' && !('on' in args[1])) {\n method = (args[1] as http.RequestOptions).method?.toUpperCase() ?? 'GET';\n }\n\n // Extract request headers\n let reqHeaders: Record<string, string | string[] | number | undefined> = {};\n if (typeof args[0] !== 'string' && !(args[0] instanceof URL)) {\n reqHeaders = (args[0] as http.RequestOptions).headers ?? {};\n } else if (args[1] && typeof args[1] === 'object' && !('on' in args[1])) {\n reqHeaders = (args[1] as http.RequestOptions).headers ?? {};\n }\n\n const req = original.apply(this, args as never) as http.ClientRequest;\n\n // Track request body size\n let requestBodySize = 0;\n let requestBody: string | undefined;\n const requestChunks: Buffer[] = [];\n\n const origWrite = req.write;\n req.write = function (\n chunk: unknown,\n ...rest: unknown[]\n ): boolean {\n if (chunk) {\n const buf = Buffer.isBuffer(chunk) ? chunk : Buffer.from(String(chunk));\n requestBodySize += buf.length;\n if (options?.captureBody) requestChunks.push(buf);\n }\n return origWrite.apply(req, [chunk, ...rest] as never);\n };\n\n const origEnd = req.end;\n req.end = function (\n chunk?: unknown,\n ...rest: unknown[]\n ): http.ClientRequest {\n if (chunk && typeof chunk !== 'function') {\n const buf = Buffer.isBuffer(chunk) ? chunk : Buffer.from(String(chunk));\n requestBodySize += buf.length;\n if (options?.captureBody) requestChunks.push(buf);\n }\n return origEnd.apply(req, [chunk, ...rest] as never) as http.ClientRequest;\n };\n\n // Listen for response\n req.on('response', (res: http.IncomingMessage) => {\n const responseChunks: Buffer[] = [];\n let responseBodySize = 0;\n\n if (options?.captureBody) {\n const origPush = res.push;\n res.push = function (chunk: Buffer | null, ...rest: unknown[]): boolean {\n if (chunk) {\n responseBodySize += chunk.length;\n if (responseBodySize <= maxBodySize) responseChunks.push(chunk);\n }\n return origPush.apply(res, [chunk, ...rest] as never);\n };\n }\n\n res.on('end', () => {\n const duration = performance.now() - startTime;\n\n if (options?.captureBody) {\n requestBody = joinChunks(requestChunks, maxBodySize);\n }\n\n const contentLength = parseInt(\n res.headers['content-length'] ?? '0',\n 10\n );\n\n const event: NetworkEvent = {\n eventId: generateId(),\n sessionId: getSessionId(sessionId),\n timestamp: Date.now(),\n eventType: 'network',\n url,\n method,\n status: res.statusCode ?? 0,\n requestHeaders: redactHeaders(reqHeaders),\n responseHeaders: redactHeaders(\n res.headers as Record<string, string | string[] | undefined>\n ),\n requestBodySize,\n responseBodySize: contentLength || responseBodySize,\n duration: Math.round(duration * 100) / 100,\n ttfb: Math.round(duration * 100) / 100,\n requestBody,\n responseBody: options?.captureBody\n ? joinChunks(responseChunks, maxBodySize)\n : undefined,\n source: protocol === 'https' ? 'node-https' : 'node-http',\n };\n\n if (options?.beforeSend) {\n const filtered = options.beforeSend(event);\n if (filtered) emit(filtered as NetworkEvent);\n } else {\n emit(event);\n }\n });\n });\n\n // Handle request errors\n req.on('error', (err: Error) => {\n const duration = performance.now() - startTime;\n\n const event: NetworkEvent = {\n eventId: generateId(),\n sessionId: getSessionId(sessionId),\n timestamp: Date.now(),\n eventType: 'network',\n url,\n method,\n status: 0,\n requestHeaders: redactHeaders(reqHeaders),\n responseHeaders: {},\n requestBodySize,\n responseBodySize: 0,\n duration: Math.round(duration * 100) / 100,\n ttfb: 0,\n errorPhase: 'error',\n errorMessage: err.message,\n source: protocol === 'https' ? 'node-https' : 'node-http',\n };\n\n if (options?.beforeSend) {\n const filtered = options.beforeSend(event);\n if (filtered) emit(filtered as NetworkEvent);\n } else {\n emit(event);\n }\n });\n\n return req;\n } as typeof http.request;\n }\n\n http.request = wrapRequest(originalHttpRequest, 'http');\n https.request = wrapRequest(originalHttpsRequest, 'https');\n\n // http.get / https.get call through to http.request / https.request,\n // so they are automatically intercepted — no need to patch separately\n\n return () => {\n http.request = originalHttpRequest;\n https.request = originalHttpsRequest;\n };\n}\n\nfunction joinChunks(chunks: Buffer[], maxSize: number): string | undefined {\n if (chunks.length === 0) return undefined;\n const combined = Buffer.concat(chunks);\n if (combined.length === 0) return undefined;\n return combined.toString('utf8', 0, Math.min(combined.length, maxSize));\n}\n","import { monitorEventLoopDelay } from 'node:perf_hooks';\nimport { PerformanceObserver } from 'node:perf_hooks';\nimport { generateId } from '../utils/id.js';\nimport { getSessionId } from '../context.js';\nimport type { PerformanceEvent, ServerMetricName, MetricUnit } from '../types.js';\n\ntype EmitFn = (event: PerformanceEvent) => void;\n\nexport interface PerfMetricsOptions {\n /** Collection interval in ms (default: 5000) */\n intervalMs?: number;\n /** Which metrics to collect (default: all) */\n metrics?: ServerMetricName[];\n}\n\nconst ALL_METRICS: ServerMetricName[] = [\n 'memory.rss', 'memory.heapUsed', 'memory.heapTotal', 'memory.external',\n 'eventloop.lag.mean', 'eventloop.lag.p99', 'eventloop.lag.max',\n 'gc.pause.major', 'gc.pause.minor',\n 'cpu.user', 'cpu.system',\n 'handles.active', 'requests.active',\n];\n\nfunction shouldCollect(metric: ServerMetricName, enabled: ServerMetricName[]): boolean {\n return enabled.includes(metric);\n}\n\nfunction emitMetric(\n emit: EmitFn,\n sessionId: string,\n metricName: ServerMetricName,\n value: number,\n unit: MetricUnit\n): void {\n emit({\n eventId: generateId(),\n sessionId: getSessionId(sessionId),\n timestamp: Date.now(),\n eventType: 'performance',\n metricName,\n value: Math.round(value * 100) / 100,\n unit,\n });\n}\n\nexport function startPerfMetrics(\n emit: EmitFn,\n sessionId: string,\n options?: PerfMetricsOptions\n): () => void {\n const intervalMs = options?.intervalMs ?? 5000;\n const enabled = options?.metrics ?? ALL_METRICS;\n\n // Track CPU usage delta between intervals\n let lastCpuUsage = process.cpuUsage();\n let lastCpuTime = Date.now();\n\n // Event loop delay histogram\n let histogram: ReturnType<typeof monitorEventLoopDelay> | null = null;\n const needsEventLoop = enabled.some((m) => m.startsWith('eventloop.'));\n if (needsEventLoop) {\n histogram = monitorEventLoopDelay({ resolution: 20 });\n histogram.enable();\n }\n\n // GC observer\n let gcObserver: PerformanceObserver | null = null;\n let lastMajorGcMs = 0;\n let lastMinorGcMs = 0;\n const needsGc = enabled.some((m) => m.startsWith('gc.'));\n if (needsGc) {\n gcObserver = new PerformanceObserver((list) => {\n for (const entry of list.getEntries()) {\n const gcEntry = entry as PerformanceEntry & { detail?: { kind?: number } };\n const durationMs = entry.duration;\n // GC kind: 1=Scavenge(minor), 2=MarkSweepCompact(major), 4=IncrementalMarking, 8=WeakPhantom\n const kind = gcEntry.detail?.kind ?? 0;\n if (kind === 2) {\n lastMajorGcMs += durationMs;\n } else if (kind === 1 || kind === 4 || kind === 8) {\n lastMinorGcMs += durationMs;\n }\n }\n });\n gcObserver.observe({ entryTypes: ['gc'] });\n }\n\n const timer = setInterval(() => {\n // Memory metrics\n if (enabled.some((m) => m.startsWith('memory.'))) {\n const mem = process.memoryUsage();\n if (shouldCollect('memory.rss', enabled)) emitMetric(emit, sessionId, 'memory.rss', mem.rss, 'bytes');\n if (shouldCollect('memory.heapUsed', enabled)) emitMetric(emit, sessionId, 'memory.heapUsed', mem.heapUsed, 'bytes');\n if (shouldCollect('memory.heapTotal', enabled)) emitMetric(emit, sessionId, 'memory.heapTotal', mem.heapTotal, 'bytes');\n if (shouldCollect('memory.external', enabled)) emitMetric(emit, sessionId, 'memory.external', mem.external, 'bytes');\n }\n\n // Event loop lag\n if (histogram) {\n if (shouldCollect('eventloop.lag.mean', enabled)) emitMetric(emit, sessionId, 'eventloop.lag.mean', histogram.mean / 1e6, 'ms');\n if (shouldCollect('eventloop.lag.p99', enabled)) emitMetric(emit, sessionId, 'eventloop.lag.p99', histogram.percentile(99) / 1e6, 'ms');\n if (shouldCollect('eventloop.lag.max', enabled)) emitMetric(emit, sessionId, 'eventloop.lag.max', histogram.max / 1e6, 'ms');\n histogram.reset();\n }\n\n // GC pauses (accumulated since last interval)\n if (needsGc) {\n if (shouldCollect('gc.pause.major', enabled)) emitMetric(emit, sessionId, 'gc.pause.major', lastMajorGcMs, 'ms');\n if (shouldCollect('gc.pause.minor', enabled)) emitMetric(emit, sessionId, 'gc.pause.minor', lastMinorGcMs, 'ms');\n lastMajorGcMs = 0;\n lastMinorGcMs = 0;\n }\n\n // CPU usage (percentage of interval)\n if (enabled.some((m) => m.startsWith('cpu.'))) {\n const now = Date.now();\n const elapsed = (now - lastCpuTime) * 1000; // Convert to microseconds\n const cpu = process.cpuUsage(lastCpuUsage);\n lastCpuUsage = process.cpuUsage();\n lastCpuTime = now;\n if (elapsed > 0) {\n if (shouldCollect('cpu.user', enabled)) emitMetric(emit, sessionId, 'cpu.user', (cpu.user / elapsed) * 100, 'percent');\n if (shouldCollect('cpu.system', enabled)) emitMetric(emit, sessionId, 'cpu.system', (cpu.system / elapsed) * 100, 'percent');\n }\n }\n\n // Active handles/requests\n if (shouldCollect('handles.active', enabled)) {\n const handles = (process as unknown as { _getActiveHandles: () => unknown[] })._getActiveHandles?.()?.length ?? 0;\n emitMetric(emit, sessionId, 'handles.active', handles, 'count');\n }\n if (shouldCollect('requests.active', enabled)) {\n const requests = (process as unknown as { _getActiveRequests: () => unknown[] })._getActiveRequests?.()?.length ?? 0;\n emitMetric(emit, sessionId, 'requests.active', requests, 'count');\n }\n }, intervalMs);\n\n // Don't keep the process alive just for metrics\n timer.unref();\n\n return () => {\n clearInterval(timer);\n if (histogram) {\n histogram.disable();\n }\n if (gcObserver) {\n gcObserver.disconnect();\n }\n };\n}\n","import { generateId } from '../utils/id.js';\nimport { runWithContext } from '../context.js';\nimport type { NetworkEvent, ServerRuntimeEvent } from '../types.js';\n\ntype EmitFn = (event: NetworkEvent) => void;\n\nexport interface MiddlewareOptions {\n captureBody?: boolean;\n maxBodySize?: number;\n redactHeaders?: string[];\n ignoreRoutes?: (string | RegExp)[];\n beforeSend?: (event: ServerRuntimeEvent) => ServerRuntimeEvent | null;\n}\n\nconst DEFAULT_REDACT_HEADERS = ['authorization', 'cookie', 'set-cookie', 'x-api-key'];\n\n/**\n * Express/Connect-compatible middleware that captures incoming HTTP requests.\n * Complements the HTTP interceptor (which captures outgoing requests).\n *\n * Usage:\n * app.use(RuntimeScope.middleware());\n */\nexport function runtimeScopeMiddleware(\n emit: EmitFn,\n sessionId: string,\n options?: MiddlewareOptions\n): (req: any, res: any, next: any) => void {\n const maxBodySize = options?.maxBodySize ?? 65536;\n const redactSet = new Set(\n (options?.redactHeaders ?? DEFAULT_REDACT_HEADERS).map((h) => h.toLowerCase())\n );\n const ignorePatterns = options?.ignoreRoutes ?? [];\n\n function shouldIgnore(path: string): boolean {\n for (const pattern of ignorePatterns) {\n if (typeof pattern === 'string') {\n if (path === pattern || path.startsWith(pattern)) return true;\n } else if (pattern.test(path)) {\n return true;\n }\n }\n return false;\n }\n\n function redactHeaders(\n headers: Record<string, string | string[] | number | undefined>\n ): Record<string, string> {\n const result: Record<string, string> = {};\n for (const [key, val] of Object.entries(headers)) {\n if (val === undefined) continue;\n const lk = key.toLowerCase();\n result[lk] = redactSet.has(lk) ? '[REDACTED]' : String(val);\n }\n return result;\n }\n\n return (req: any, res: any, next: any) => {\n const path: string = req.originalUrl ?? req.url ?? '/';\n\n if (shouldIgnore(path)) {\n return next();\n }\n\n const startTime = performance.now();\n\n // Wrap res.end to capture response timing and status\n const originalEnd = res.end.bind(res);\n let responseBody: string | undefined;\n\n res.end = function (chunk?: unknown, ...rest: unknown[]) {\n const duration = performance.now() - startTime;\n\n if (options?.captureBody && chunk) {\n if (Buffer.isBuffer(chunk)) {\n responseBody = chunk.toString('utf8', 0, Math.min(chunk.length, maxBodySize));\n } else if (typeof chunk === 'string') {\n responseBody = chunk.slice(0, maxBodySize);\n }\n }\n\n const proto = req.protocol ?? (req.socket?.encrypted ? 'https' : 'http');\n const host = req.get?.('host') ?? req.headers?.host ?? 'localhost';\n const url = `${proto}://${host}${path}`;\n\n const event: NetworkEvent = {\n eventId: generateId(),\n sessionId,\n timestamp: Date.now(),\n eventType: 'network',\n url,\n method: (req.method ?? 'GET').toUpperCase(),\n status: res.statusCode ?? 200,\n requestHeaders: redactHeaders(req.headers ?? {}),\n responseHeaders: redactHeaders(\n typeof res.getHeaders === 'function' ? res.getHeaders() : {}\n ),\n requestBodySize: parseInt(req.headers?.['content-length'] ?? '0', 10),\n responseBodySize: parseInt(\n (typeof res.getHeader === 'function'\n ? res.getHeader('content-length')\n : undefined\n )?.toString() ?? '0',\n 10\n ),\n duration: Math.round(duration * 100) / 100,\n ttfb: Math.round(duration * 100) / 100,\n responseBody,\n source: 'node-http',\n };\n\n if (options?.beforeSend) {\n const filtered = options.beforeSend(event);\n if (filtered) emit(filtered as NetworkEvent);\n } else {\n emit(event);\n }\n\n return originalEnd(chunk, ...rest);\n };\n\n // Wrap next() in request context so downstream code\n // (database queries, console logs, HTTP calls) inherits per-request sessionId\n const requestId = generateId();\n runWithContext({ sessionId, requestId }, () => next());\n };\n}\n","import { ServerTransport } from './transport.js';\nimport { HttpTransport } from './http-transport.js';\nimport { generateId, generateSessionId } from './utils/id.js';\nimport { parseOperation, parseTablesAccessed, normalizeQuery, redactParams } from './utils/sql-parser.js';\nimport { captureStack } from './utils/stack.js';\nimport { Sampler } from './sampler.js';\nimport { instrumentPrisma } from './integrations/prisma.js';\nimport { instrumentPg } from './integrations/pg.js';\nimport { instrumentKnex } from './integrations/knex.js';\nimport { instrumentDrizzle } from './integrations/drizzle.js';\nimport { instrumentMysql2 } from './integrations/mysql2.js';\nimport { instrumentBetterSqlite3 } from './integrations/better-sqlite3.js';\nimport { interceptConsole } from './interceptors/console.js';\nimport { interceptErrors } from './interceptors/errors.js';\nimport { interceptHttp } from './interceptors/http.js';\nimport { startPerfMetrics } from './interceptors/perf-metrics.js';\nimport { runtimeScopeMiddleware } from './interceptors/middleware.js';\nimport type { DatabaseEvent, ServerSdkConfig, ServerRuntimeEvent } from './types.js';\nimport type { MiddlewareOptions } from './interceptors/middleware.js';\n\n// ============================================================\n// RuntimeScope Server SDK\n// Instruments server-side database queries, console output,\n// errors, HTTP requests, and performance metrics — sends them\n// to the RuntimeScope collector via WebSocket\n// ============================================================\n\nconst SDK_VERSION = '0.7.0';\n\n// Re-export _log for integration modules (lives in utils/log.js to avoid circular deps)\nexport { _log } from './utils/log.js';\n\nclass RuntimeScopeServer {\n private transport: ServerTransport | null = null;\n private httpTransport: HttpTransport | null = null;\n private sessionId: string = '';\n private config: ServerSdkConfig = {};\n private sampler: Sampler | null = null;\n private restoreFunctions: (() => void)[] = [];\n\n /** Alias for `connect` — mirrors the browser SDK's init() API */\n init(config: ServerSdkConfig = {}): void {\n return this.connect(config);\n }\n\n connect(config: ServerSdkConfig = {}): void {\n this.config = config;\n this.sessionId = config.sessionId ?? generateSessionId();\n\n const serverUrl = config.serverUrl ?? config.endpoint ?? 'ws://127.0.0.1:9090';\n\n if (config.transport === 'http') {\n // HTTP transport for serverless environments (Lambda, Vercel, Cloudflare Workers)\n let httpUrl = config.httpEndpoint;\n if (!httpUrl) {\n const wsUrl = new URL(serverUrl);\n wsUrl.protocol = wsUrl.protocol === 'wss:' ? 'https:' : 'http:';\n wsUrl.port = '9091';\n wsUrl.pathname = '/api/events';\n httpUrl = wsUrl.toString();\n }\n\n this.httpTransport = new HttpTransport({\n url: httpUrl,\n sessionId: this.sessionId,\n appName: config.appName ?? 'server-app',\n sdkVersion: SDK_VERSION,\n authToken: config.authToken,\n maxQueueSize: config.maxQueueSize,\n flushIntervalMs: config.httpFlushIntervalMs,\n });\n } else {\n // Default: WebSocket transport\n this.transport = new ServerTransport({\n url: serverUrl,\n sessionId: this.sessionId,\n appName: config.appName ?? 'server-app',\n sdkVersion: SDK_VERSION,\n authToken: config.authToken,\n maxQueueSize: config.maxQueueSize,\n });\n\n this.transport.connect();\n }\n\n // Set up sampler if rate limiting or sampling is configured\n if (config.sampleRate !== undefined || config.maxEventsPerSecond !== undefined) {\n this.sampler = new Sampler({\n sampleRate: config.sampleRate,\n maxEventsPerSecond: config.maxEventsPerSecond,\n });\n }\n\n const emit = (event: ServerRuntimeEvent) => this.emitEvent(event);\n\n // Console interceptor (default: enabled)\n if (config.captureConsole !== false) {\n try {\n this.restoreFunctions.push(\n interceptConsole(emit, this.sessionId, {\n captureStackTraces: config.captureStackTraces,\n beforeSend: config.beforeSend,\n })\n );\n } catch { /* non-fatal: continue without console capture */ }\n }\n\n // Error interceptor (default: enabled when console is enabled)\n if (config.captureErrors !== false && config.captureConsole !== false) {\n try {\n this.restoreFunctions.push(\n interceptErrors(emit, this.sessionId, {\n beforeSend: config.beforeSend,\n })\n );\n } catch { /* non-fatal: continue without error capture */ }\n }\n\n // HTTP request interceptor (default: enabled)\n if (config.captureHttp !== false) {\n try {\n this.restoreFunctions.push(\n interceptHttp(emit, this.sessionId, {\n captureBody: config.captureBody,\n maxBodySize: config.maxBodySize,\n redactHeaders: config.redactHeaders,\n // Auto-ignore the collector URL to prevent recursion\n ignoreUrls: [\n serverUrl.replace('ws://', '').replace('wss://', ''),\n ...(config.httpEndpoint ? [config.httpEndpoint.replace(/^https?:\\/\\//, '')] : []),\n ],\n beforeSend: config.beforeSend,\n })\n );\n } catch { /* non-fatal: continue without HTTP capture */ }\n }\n\n // Performance metrics (default: enabled)\n if (config.capturePerformance !== false) {\n try {\n this.restoreFunctions.push(\n startPerfMetrics(emit, this.sessionId, {\n intervalMs: config.performanceInterval,\n metrics: config.performanceMetrics,\n })\n );\n } catch { /* non-fatal: continue without performance metrics */ }\n }\n }\n\n disconnect(): void {\n for (const restore of this.restoreFunctions) {\n try { restore(); } catch { /* ignore */ }\n }\n this.restoreFunctions = [];\n this.sampler = null;\n if (this.httpTransport) {\n this.httpTransport.disconnect();\n this.httpTransport = null;\n }\n this.transport?.disconnect();\n this.transport = null;\n }\n\n get currentSessionId(): string {\n return this.sessionId;\n }\n\n private emitEvent(event: ServerRuntimeEvent): void {\n // Apply sampling/rate limiting\n if (this.sampler && !this.sampler.shouldSample(event)) return;\n\n const filtered = this.config.beforeSend\n ? this.config.beforeSend(event)\n : event;\n if (!filtered) return;\n\n if (this.httpTransport) {\n this.httpTransport.sendEvent(filtered);\n } else {\n this.transport?.sendEvent(filtered);\n }\n }\n\n // --- Express/Connect Middleware ---\n\n middleware(options?: MiddlewareOptions) {\n return runtimeScopeMiddleware(\n (event) => this.emitEvent(event),\n this.sessionId,\n {\n ...options,\n redactHeaders: options?.redactHeaders ?? this.config.redactHeaders,\n beforeSend: options?.beforeSend ?? this.config.beforeSend,\n }\n );\n }\n\n // --- ORM Instrumentation ---\n\n instrumentPrisma(client: unknown): typeof client {\n const restore = instrumentPrisma(client, {\n sessionId: this.sessionId,\n captureStackTraces: this.config.captureStackTraces,\n redact: this.config.redactParams,\n onEvent: (event) => this.emitEvent(event),\n });\n this.restoreFunctions.push(restore);\n return client;\n }\n\n instrumentPg(pool: unknown): typeof pool {\n const restore = instrumentPg(pool, {\n sessionId: this.sessionId,\n captureStackTraces: this.config.captureStackTraces,\n redact: this.config.redactParams,\n onEvent: (event) => this.emitEvent(event),\n });\n this.restoreFunctions.push(restore);\n return pool;\n }\n\n instrumentKnex(knex: unknown): typeof knex {\n const restore = instrumentKnex(knex, {\n sessionId: this.sessionId,\n captureStackTraces: this.config.captureStackTraces,\n redact: this.config.redactParams,\n onEvent: (event) => this.emitEvent(event),\n });\n this.restoreFunctions.push(restore);\n return knex;\n }\n\n instrumentDrizzle(db: unknown): typeof db {\n const restore = instrumentDrizzle(db, {\n sessionId: this.sessionId,\n captureStackTraces: this.config.captureStackTraces,\n redact: this.config.redactParams,\n onEvent: (event) => this.emitEvent(event),\n });\n this.restoreFunctions.push(restore);\n return db;\n }\n\n instrumentMysql2(pool: unknown): typeof pool {\n const restore = instrumentMysql2(pool, {\n sessionId: this.sessionId,\n captureStackTraces: this.config.captureStackTraces,\n redact: this.config.redactParams,\n onEvent: (event) => this.emitEvent(event),\n });\n this.restoreFunctions.push(restore);\n return pool;\n }\n\n instrumentBetterSqlite3(db: unknown): typeof db {\n const restore = instrumentBetterSqlite3(db, {\n sessionId: this.sessionId,\n captureStackTraces: this.config.captureStackTraces,\n redact: this.config.redactParams,\n onEvent: (event) => this.emitEvent(event),\n });\n this.restoreFunctions.push(restore);\n return db;\n }\n\n // --- Generic query capture ---\n\n async captureQuery<T>(\n fn: () => Promise<T>,\n options?: { label?: string }\n ): Promise<T> {\n const start = performance.now();\n try {\n const result = await fn();\n const duration = performance.now() - start;\n this.emitEvent({\n eventId: generateId(),\n sessionId: this.sessionId,\n timestamp: Date.now(),\n eventType: 'database',\n query: options?.label ?? 'custom query',\n normalizedQuery: options?.label ?? 'custom query',\n duration,\n tablesAccessed: [],\n operation: 'OTHER',\n source: 'generic',\n label: options?.label,\n stackTrace: this.config.captureStackTraces ? captureStack() : undefined,\n rowsReturned: Array.isArray(result) ? result.length : undefined,\n });\n return result;\n } catch (err) {\n const duration = performance.now() - start;\n this.emitEvent({\n eventId: generateId(),\n sessionId: this.sessionId,\n timestamp: Date.now(),\n eventType: 'database',\n query: options?.label ?? 'custom query',\n normalizedQuery: options?.label ?? 'custom query',\n duration,\n tablesAccessed: [],\n operation: 'OTHER',\n source: 'generic',\n label: options?.label,\n error: (err as Error).message,\n stackTrace: this.config.captureStackTraces ? captureStack() : undefined,\n });\n throw err;\n }\n }\n}\n\n// Singleton instance\nexport const RuntimeScope = new RuntimeScopeServer();\n\n// Re-export types and utilities\nexport type {\n DatabaseEvent,\n ConsoleEvent,\n NetworkEvent,\n PerformanceEvent,\n ServerRuntimeEvent,\n ServerSdkConfig,\n ServerMetricName,\n MetricUnit,\n} from './types.js';\nexport { generateId, generateSessionId } from './utils/id.js';\nexport { parseOperation, parseTablesAccessed, normalizeQuery, redactParams } from './utils/sql-parser.js';\nexport { runtimeScopeMiddleware } from './interceptors/middleware.js';\nexport { runWithContext, getRequestContext, getSessionId } from './context.js';\nexport { Sampler } from './sampler.js';\nexport { HttpTransport } from './http-transport.js';\nexport type { HttpTransportOptions } from './http-transport.js';\n"],"mappings":"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","names":["captureStack","DEFAULT_REDACT_HEADERS"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@runtimescope/server-sdk",
3
- "version": "0.6.2",
3
+ "version": "0.7.0",
4
4
  "description": "Server-side SDK for RuntimeScope — instruments database queries, HTTP requests, console output, and performance metrics",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",