@runtimescope/workers-sdk 0.9.0 → 0.9.1
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 +1 -1
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/handler.ts","../src/utils.ts","../src/transport.ts","../src/sampler.ts","../src/interceptors/console.ts","../src/bindings/d1.ts","../src/bindings/kv.ts","../src/bindings/r2.ts","../src/index.ts"],"sourcesContent":["import { AsyncLocalStorage } from 'node:async_hooks';\nimport type {\n WorkersConfig,\n WorkersRuntimeEvent,\n NetworkEvent,\n ConsoleEvent,\n UserContext,\n} from './types.js';\nimport { WorkersTransport } from './transport.js';\nimport { Sampler } from './sampler.js';\nimport { interceptConsole } from './interceptors/console.js';\nimport { generateId } from './utils.js';\n\n// ============================================================\n// withRuntimeScope — wraps a Workers fetch handler\n// Captures request/response metrics, errors, console output.\n// Flushes all events via ctx.waitUntil() at end of request.\n// ============================================================\n\n/** Internal context exposed to binding wrappers */\nexport interface RuntimeScopeContext {\n transport: WorkersTransport;\n sessionId: string;\n config: WorkersConfig;\n emit: (event: WorkersRuntimeEvent) => void;\n}\n\n// Per-request context — AsyncLocalStorage ensures isolation under concurrent requests.\n// Available in Workers runtime with nodejs_compat flag and in Node.js 16+.\nconst _contextStorage = new AsyncLocalStorage<RuntimeScopeContext>();\n\n/** Get the active RuntimeScope context (used by binding wrappers) */\nexport function getActiveContext(): RuntimeScopeContext | null {\n return _contextStorage.getStore() ?? null;\n}\n\nconst DEFAULT_REDACT_HEADERS = ['authorization', 'cookie', 'set-cookie'];\n\nexport interface WorkersFetchHandler {\n fetch(\n request: Request,\n env: unknown,\n ctx: ExecutionContext,\n ): Response | Promise<Response>;\n}\n\n/**\n * Wrap a Workers fetch handler to capture request/response metrics,\n * errors, and console output. Events are flushed via ctx.waitUntil().\n *\n * @example\n * ```ts\n * import { withRuntimeScope } from '@runtimescope/workers-sdk';\n *\n * export default withRuntimeScope({\n * async fetch(request, env, ctx) {\n * return new Response('Hello!');\n * },\n * }, { appName: 'my-worker' });\n * ```\n */\nexport function withRuntimeScope(\n handler: WorkersFetchHandler,\n config: WorkersConfig,\n): WorkersFetchHandler {\n const transport = new WorkersTransport(config);\n const sampler = config.sampleRate !== undefined && config.sampleRate < 1\n ? new Sampler({ sampleRate: config.sampleRate })\n : null;\n\n const redactHeaders = config.redactHeaders ?? DEFAULT_REDACT_HEADERS;\n const redactSet = new Set(redactHeaders.map((h) => h.toLowerCase()));\n\n function emit(event: WorkersRuntimeEvent): void {\n if (sampler && !sampler.shouldSample(event)) return;\n if (config.beforeSend) {\n const filtered = config.beforeSend(event);\n if (!filtered) return;\n transport.queue(filtered);\n } else {\n transport.queue(event);\n }\n }\n\n // Set up console interceptor (persistent across requests)\n let restoreConsole: (() => void) | null = null;\n if (config.captureConsole !== false) {\n restoreConsole = interceptConsole(emit, {\n sessionId: transport.sessionId,\n });\n }\n\n function extractHeaders(headers: Headers): Record<string, string> {\n if (!config.captureHeaders) return {};\n const result: Record<string, string> = {};\n headers.forEach((value, key) => {\n result[key] = redactSet.has(key.toLowerCase()) ? '[REDACTED]' : value;\n });\n return result;\n }\n\n return {\n async fetch(\n request: Request,\n env: unknown,\n ctx: ExecutionContext,\n ): Promise<Response> {\n const start = Date.now();\n const url = new URL(request.url);\n\n // Run handler inside AsyncLocalStorage so binding wrappers\n // get the correct per-request context even under concurrency\n const rsContext: RuntimeScopeContext = {\n transport,\n sessionId: transport.sessionId,\n config,\n emit,\n };\n\n return _contextStorage.run(rsContext, async () => {\n try {\n const response = await handler.fetch(request, env, ctx);\n const duration = Date.now() - start;\n\n const networkEvent: NetworkEvent = {\n eventId: generateId(),\n sessionId: transport.sessionId,\n timestamp: start,\n eventType: 'network',\n url: url.pathname + url.search,\n method: request.method,\n status: response.status,\n duration,\n requestHeaders: extractHeaders(request.headers),\n responseHeaders: extractHeaders(response.headers),\n requestBodySize: 0,\n responseBodySize: 0,\n ttfb: duration,\n source: 'workers',\n direction: 'incoming',\n cfProperties: extractCfProperties(request),\n };\n\n emit(networkEvent);\n ctx.waitUntil(transport.flush());\n return response;\n } catch (error) {\n const duration = Date.now() - start;\n\n // Capture the error as a console error event\n const errorEvent: ConsoleEvent = {\n eventId: generateId(),\n sessionId: transport.sessionId,\n timestamp: Date.now(),\n eventType: 'console',\n level: 'error',\n message: error instanceof Error ? error.message : String(error),\n args: [error instanceof Error ? { name: error.name, message: error.message, stack: error.stack } : String(error)],\n stackTrace: error instanceof Error ? error.stack : undefined,\n };\n\n emit(errorEvent);\n\n // Also capture the failed request\n const networkEvent: NetworkEvent = {\n eventId: generateId(),\n sessionId: transport.sessionId,\n timestamp: start,\n eventType: 'network',\n url: url.pathname + url.search,\n method: request.method,\n status: 500,\n duration,\n requestHeaders: extractHeaders(request.headers),\n responseHeaders: {},\n requestBodySize: 0,\n responseBodySize: 0,\n ttfb: duration,\n source: 'workers',\n direction: 'incoming',\n cfProperties: extractCfProperties(request),\n errorMessage: error instanceof Error ? error.message : String(error),\n };\n\n emit(networkEvent);\n ctx.waitUntil(transport.flush());\n throw error;\n }\n });\n },\n };\n}\n\nfunction extractCfProperties(request: Request): NetworkEvent['cfProperties'] | undefined {\n // request.cf is Cloudflare-specific — may not exist in non-CF environments\n const cf = (request as unknown as { cf?: Record<string, unknown> }).cf;\n if (!cf) return undefined;\n\n return {\n colo: cf.colo as string | undefined,\n country: cf.country as string | undefined,\n city: cf.city as string | undefined,\n region: cf.region as string | undefined,\n asn: cf.asn as number | undefined,\n httpProtocol: cf.httpProtocol as string | undefined,\n tlsVersion: cf.tlsVersion as string | undefined,\n };\n}\n","// ============================================================\n// Utility functions — no Node.js APIs, Workers-safe\n// ============================================================\n\n/** Generate a random event ID using Web Crypto API (available in Workers) */\nexport function generateId(): string {\n return crypto.randomUUID();\n}\n\n/** Generate a session ID with worker prefix */\nexport function generateSessionId(): string {\n return `wk-${crypto.randomUUID().slice(0, 16)}`;\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 type { WorkersRuntimeEvent, WorkersConfig, UserContext } from './types.js';\nimport { generateSessionId } from './utils.js';\n\n// ============================================================\n// Workers Transport\n// Flush events via ctx.waitUntil(fetch(...)) — no timers, no intervals.\n// Matches collector's POST /api/events endpoint.\n// ============================================================\n\nconst SDK_VERSION = '0.9.0';\nconst DEFAULT_ENDPOINT = 'http://localhost:9091/api/events';\n\nexport class WorkersTransport {\n private buffer: WorkersRuntimeEvent[] = [];\n private maxQueueSize: number;\n private url: string;\n private authToken: string | undefined;\n private appName: string;\n private projectId?: string;\n private sessionRegistered = false;\n private _droppedCount = 0;\n\n readonly sessionId: string;\n\n constructor(config: WorkersConfig) {\n this.sessionId = generateSessionId();\n this.url = config.httpEndpoint ?? DEFAULT_ENDPOINT;\n this.appName = config.appName;\n this.projectId = config.projectId;\n this.authToken = config.authToken;\n this.maxQueueSize = config.maxQueueSize ?? 500;\n }\n\n get droppedCount(): number {\n return this._droppedCount;\n }\n\n queue(event: WorkersRuntimeEvent): void {\n if (this.buffer.length >= this.maxQueueSize) {\n this.buffer.shift();\n this._droppedCount++;\n }\n this.buffer.push(event);\n }\n\n /**\n * Flush all buffered events to the collector.\n * Call via ctx.waitUntil(transport.flush()) at the end of each request.\n * Retries once on failure with a short delay.\n */\n async flush(): Promise<void> {\n if (this.buffer.length === 0) return;\n\n const events = this.buffer.splice(0);\n const payload: Record<string, unknown> = {\n sessionId: this.sessionId,\n events,\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 = SDK_VERSION;\n if (this.projectId) payload.projectId = this.projectId;\n }\n\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 body = JSON.stringify(payload);\n\n for (let attempt = 0; attempt < 2; attempt++) {\n try {\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), 5_000);\n\n const response = await fetch(this.url, {\n method: 'POST',\n headers,\n body,\n signal: controller.signal,\n });\n\n clearTimeout(timeoutId);\n\n if (response.ok) {\n this.sessionRegistered = true;\n return;\n }\n\n // Server error (5xx) — retry once\n if (response.status >= 500 && attempt === 0) continue;\n // Client error (4xx) — don't retry\n return;\n } catch {\n // Network error or timeout — retry once\n if (attempt === 0) {\n await new Promise((r) => setTimeout(r, 200));\n continue;\n }\n // Second attempt failed — events are lost (acceptable for edge observability)\n }\n }\n }\n}\n","import type { WorkersRuntimeEvent } from './types.js';\n\n// ============================================================\n// Sampler — probabilistic + rate limiting\n// Adapted from server-sdk, no Node.js APIs.\n// ============================================================\n\nexport interface SamplerConfig {\n /** Probabilistic sample rate: 0.0–1.0 (default: 1.0 = keep all) */\n sampleRate?: number;\n}\n\nexport class Sampler {\n private _droppedCount = 0;\n\n constructor(private config: SamplerConfig) {}\n\n get droppedCount(): number {\n return this._droppedCount;\n }\n\n shouldSample(_event: WorkersRuntimeEvent): boolean {\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 return true;\n }\n}\n","import type { ConsoleEvent, ConsoleLevel } from '../types.js';\nimport { generateId, safeSerialize } from '../utils.js';\n\n// ============================================================\n// Console Interceptor — Workers-safe\n// Patches console.log/warn/error/info/debug/trace.\n// Returns a restore function for cleanup.\n// ============================================================\n\ntype EmitFn = (event: ConsoleEvent) => void;\n\nconst LEVELS: ConsoleLevel[] = ['log', 'warn', 'error', 'info', 'debug', 'trace'];\n\nexport interface ConsoleInterceptorOptions {\n levels?: ConsoleLevel[];\n sessionId: string;\n}\n\nexport function interceptConsole(\n emit: EmitFn,\n options: ConsoleInterceptorOptions\n): () => void {\n const levels = options.levels ?? LEVELS;\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: options.sessionId,\n timestamp: Date.now(),\n eventType: 'console',\n level,\n message,\n args: args.map((a) => safeSerialize(a, 3)),\n stackTrace:\n level === 'error' || level === 'trace'\n ? new Error().stack?.split('\\n').slice(2).join('\\n')\n : undefined,\n };\n\n // emit() already applies beforeSend — don't double-filter\n emit(event);\n\n // Call original — 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 type {\n D1DatabaseBinding,\n D1PreparedStatementBinding,\n D1Result,\n D1ExecResult,\n DatabaseEvent,\n} from '../types.js';\nimport { generateId } from '../utils.js';\n\n// ============================================================\n// D1 Binding Wrapper\n// Wraps a D1Database to capture SQL queries, timing, and results.\n// Events emitted as 'database' type with source: 'd1'.\n// ============================================================\n\ntype EmitFn = (event: DatabaseEvent) => void;\n\ninterface D1InstrumentOptions {\n sessionId: string;\n}\n\n/**\n * Wrap a D1 database binding to capture queries.\n *\n * @example\n * ```ts\n * const db = instrumentD1(env.DB, transport.sessionId);\n * const results = await db.prepare('SELECT * FROM users').all();\n * ```\n */\nexport function instrumentD1(\n db: D1DatabaseBinding,\n emit: EmitFn,\n options: D1InstrumentOptions,\n): D1DatabaseBinding {\n return {\n prepare(query: string): D1PreparedStatementBinding {\n const stmt = db.prepare(query);\n return instrumentStatement(stmt, query, emit, options);\n },\n\n async batch<T = unknown>(statements: D1PreparedStatementBinding[]): Promise<D1Result<T>[]> {\n const start = Date.now();\n try {\n const results = await db.batch<T>(statements);\n const duration = Date.now() - start;\n emit({\n eventId: generateId(),\n sessionId: options.sessionId,\n timestamp: start,\n eventType: 'database',\n query: `BATCH (${statements.length} statements)`,\n normalizedQuery: 'BATCH',\n duration,\n tablesAccessed: [],\n operation: 'OTHER',\n source: 'd1',\n rowsReturned: results.reduce((sum, r) => sum + (r.results?.length ?? 0), 0),\n });\n return results;\n } catch (err) {\n const duration = Date.now() - start;\n emit({\n eventId: generateId(),\n sessionId: options.sessionId,\n timestamp: start,\n eventType: 'database',\n query: `BATCH (${statements.length} statements)`,\n normalizedQuery: 'BATCH',\n duration,\n tablesAccessed: [],\n operation: 'OTHER',\n source: 'd1',\n error: (err as Error).message,\n });\n throw err;\n }\n },\n\n async exec(query: string): Promise<D1ExecResult> {\n const start = Date.now();\n try {\n const result = await db.exec(query);\n emit({\n eventId: generateId(),\n sessionId: options.sessionId,\n timestamp: start,\n eventType: 'database',\n query,\n normalizedQuery: normalizeD1Query(query),\n duration: result.duration,\n tablesAccessed: extractTables(query),\n operation: parseOp(query),\n source: 'd1',\n rowsAffected: result.count,\n });\n return result;\n } catch (err) {\n const duration = Date.now() - start;\n emit({\n eventId: generateId(),\n sessionId: options.sessionId,\n timestamp: start,\n eventType: 'database',\n query,\n normalizedQuery: normalizeD1Query(query),\n duration,\n tablesAccessed: extractTables(query),\n operation: parseOp(query),\n source: 'd1',\n error: (err as Error).message,\n });\n throw err;\n }\n },\n\n dump(): Promise<ArrayBuffer> {\n return db.dump();\n },\n };\n}\n\nfunction instrumentStatement(\n stmt: D1PreparedStatementBinding,\n query: string,\n emit: EmitFn,\n options: D1InstrumentOptions,\n): D1PreparedStatementBinding {\n const op = parseOp(query);\n const tables = extractTables(query);\n const normalized = normalizeD1Query(query);\n\n function makeEvent(start: number, duration: number, extra: Partial<DatabaseEvent> = {}): DatabaseEvent {\n return {\n eventId: generateId(),\n sessionId: options.sessionId,\n timestamp: start,\n eventType: 'database',\n query,\n normalizedQuery: normalized,\n duration,\n tablesAccessed: tables,\n operation: op,\n source: 'd1',\n ...extra,\n };\n }\n\n async function wrapAsync<T>(fn: () => Promise<T>, start: number, getExtra?: (result: T) => Partial<DatabaseEvent>): Promise<T> {\n try {\n const result = await fn();\n const duration = Date.now() - start;\n emit(makeEvent(start, duration, getExtra?.(result)));\n return result;\n } catch (err) {\n const duration = Date.now() - start;\n emit(makeEvent(start, duration, { error: (err as Error).message }));\n throw err;\n }\n }\n\n return {\n bind(...values: unknown[]): D1PreparedStatementBinding {\n const bound = stmt.bind(...values);\n return instrumentStatement(bound, query, emit, options);\n },\n\n first<T = unknown>(colName?: string): Promise<T | null> {\n const start = Date.now();\n return wrapAsync(\n () => stmt.first<T>(colName),\n start,\n (result) => ({ rowsReturned: result !== null ? 1 : 0 }),\n );\n },\n\n run<T = unknown>(): Promise<D1Result<T>> {\n const start = Date.now();\n return wrapAsync(\n () => stmt.run<T>(),\n start,\n (result) => ({\n rowsAffected: result.meta?.changes,\n duration: result.meta?.duration ?? (Date.now() - start),\n }),\n );\n },\n\n all<T = unknown>(): Promise<D1Result<T>> {\n const start = Date.now();\n return wrapAsync(\n () => stmt.all<T>(),\n start,\n (result) => ({\n rowsReturned: result.results?.length ?? 0,\n duration: result.meta?.duration ?? (Date.now() - start),\n }),\n );\n },\n\n raw<T = unknown>(rawOptions?: { columnNames?: boolean }): Promise<T[]> {\n const start = Date.now();\n return wrapAsync(\n () => stmt.raw<T>(rawOptions),\n start,\n (result) => ({ rowsReturned: result.length }),\n );\n },\n };\n}\n\n// --- SQL Parsing Helpers (lightweight, no dependencies) ---\n\nfunction parseOp(query: string): DatabaseEvent['operation'] {\n const trimmed = query.trimStart().toUpperCase();\n if (trimmed.startsWith('SELECT')) return 'SELECT';\n if (trimmed.startsWith('INSERT')) return 'INSERT';\n if (trimmed.startsWith('UPDATE')) return 'UPDATE';\n if (trimmed.startsWith('DELETE')) return 'DELETE';\n return 'OTHER';\n}\n\nfunction extractTables(query: string): string[] {\n const tables: string[] = [];\n const fromMatch = query.match(/\\bFROM\\s+(\\w+)/i);\n if (fromMatch) tables.push(fromMatch[1]);\n const intoMatch = query.match(/\\bINTO\\s+(\\w+)/i);\n if (intoMatch) tables.push(intoMatch[1]);\n const updateMatch = query.match(/\\bUPDATE\\s+(\\w+)/i);\n if (updateMatch) tables.push(updateMatch[1]);\n const joinMatches = query.matchAll(/\\bJOIN\\s+(\\w+)/gi);\n for (const m of joinMatches) tables.push(m[1]);\n return [...new Set(tables)];\n}\n\nfunction normalizeD1Query(query: string): string {\n return query\n .replace(/'[^']*'/g, '?')\n .replace(/\\b\\d+\\b/g, '?')\n .replace(/\\s+/g, ' ')\n .trim();\n}\n","import type { KVNamespaceBinding, DatabaseEvent } from '../types.js';\nimport { generateId } from '../utils.js';\n\n// ============================================================\n// KV Namespace Wrapper\n// Wraps a KVNamespace to capture get/put/delete/list operations.\n// Events emitted as 'database' type with source: 'kv'.\n// ============================================================\n\ntype EmitFn = (event: DatabaseEvent) => void;\n\ninterface KVInstrumentOptions {\n sessionId: string;\n}\n\n/**\n * Wrap a KV namespace binding to capture operations.\n *\n * @example\n * ```ts\n * const kv = instrumentKV(env.MY_KV, emit, { sessionId });\n * await kv.put('key', 'value');\n * ```\n */\nexport function instrumentKV(\n kv: KVNamespaceBinding,\n emit: EmitFn,\n options: KVInstrumentOptions,\n): KVNamespaceBinding {\n function sanitizeKey(key: string): string {\n // Truncate and escape quotes/newlines to prevent malformed query strings\n const safe = key.length > 200 ? key.slice(0, 200) + '…' : key;\n return safe.replace(/\\\\/g, '\\\\\\\\').replace(/\"/g, '\\\\\"').replace(/\\n/g, '\\\\n');\n }\n\n function emitOp(op: string, key: string, start: number, duration: number, extra: Partial<DatabaseEvent> = {}): void {\n emit({\n eventId: generateId(),\n sessionId: options.sessionId,\n timestamp: start,\n eventType: 'database',\n query: `KV.${op}(\"${sanitizeKey(key)}\")`,\n normalizedQuery: `KV.${op}(?)`,\n duration,\n tablesAccessed: [],\n operation: op === 'get' || op === 'getWithMetadata' || op === 'list' ? 'SELECT' : op === 'put' ? 'INSERT' : op === 'delete' ? 'DELETE' : 'OTHER',\n source: 'kv',\n ...extra,\n });\n }\n\n return {\n async get(key: string, kvOptions?: unknown): Promise<string | null> {\n const start = Date.now();\n try {\n const result = await kv.get(key, kvOptions);\n emitOp('get', key, start, Date.now() - start, { rowsReturned: result !== null ? 1 : 0 });\n return result;\n } catch (err) {\n emitOp('get', key, start, Date.now() - start, { error: (err as Error).message });\n throw err;\n }\n },\n\n async getWithMetadata<M = unknown>(key: string, kvOptions?: unknown): Promise<{ value: string | null; metadata: M | null }> {\n const start = Date.now();\n try {\n const result = await kv.getWithMetadata<M>(key, kvOptions);\n emitOp('getWithMetadata', key, start, Date.now() - start, { rowsReturned: result.value !== null ? 1 : 0 });\n return result;\n } catch (err) {\n emitOp('getWithMetadata', key, start, Date.now() - start, { error: (err as Error).message });\n throw err;\n }\n },\n\n async put(key: string, value: string | ReadableStream | ArrayBuffer, kvOptions?: unknown): Promise<void> {\n const start = Date.now();\n try {\n await kv.put(key, value, kvOptions);\n emitOp('put', key, start, Date.now() - start, { rowsAffected: 1 });\n } catch (err) {\n emitOp('put', key, start, Date.now() - start, { error: (err as Error).message });\n throw err;\n }\n },\n\n async delete(key: string): Promise<void> {\n const start = Date.now();\n try {\n await kv.delete(key);\n emitOp('delete', key, start, Date.now() - start, { rowsAffected: 1 });\n } catch (err) {\n emitOp('delete', key, start, Date.now() - start, { error: (err as Error).message });\n throw err;\n }\n },\n\n async list(kvOptions?: unknown): Promise<{ keys: { name: string }[]; list_complete: boolean; cursor?: string }> {\n const start = Date.now();\n try {\n const result = await kv.list(kvOptions);\n emitOp('list', '*', start, Date.now() - start, { rowsReturned: result.keys.length });\n return result;\n } catch (err) {\n emitOp('list', '*', start, Date.now() - start, { error: (err as Error).message });\n throw err;\n }\n },\n };\n}\n","import type { R2BucketBinding, R2Object, R2ObjectBody, R2Objects, DatabaseEvent } from '../types.js';\nimport { generateId } from '../utils.js';\n\n// ============================================================\n// R2 Bucket Wrapper\n// Wraps an R2Bucket to capture get/put/delete/list/head operations.\n// Events emitted as 'database' type with source: 'r2'.\n// ============================================================\n\ntype EmitFn = (event: DatabaseEvent) => void;\n\ninterface R2InstrumentOptions {\n sessionId: string;\n}\n\n/**\n * Wrap an R2 bucket binding to capture operations.\n *\n * @example\n * ```ts\n * const bucket = instrumentR2(env.MY_BUCKET, emit, { sessionId });\n * await bucket.put('file.txt', 'contents');\n * ```\n */\nexport function instrumentR2(\n bucket: R2BucketBinding,\n emit: EmitFn,\n options: R2InstrumentOptions,\n): R2BucketBinding {\n function sanitizeKey(key: string): string {\n const safe = key.length > 200 ? key.slice(0, 200) + '…' : key;\n return safe.replace(/\\\\/g, '\\\\\\\\').replace(/\"/g, '\\\\\"').replace(/\\n/g, '\\\\n');\n }\n\n function emitOp(op: string, key: string, start: number, duration: number, extra: Partial<DatabaseEvent> = {}): void {\n emit({\n eventId: generateId(),\n sessionId: options.sessionId,\n timestamp: start,\n eventType: 'database',\n query: `R2.${op}(\"${sanitizeKey(key)}\")`,\n normalizedQuery: `R2.${op}(?)`,\n duration,\n tablesAccessed: [],\n operation: op === 'get' || op === 'list' || op === 'head' ? 'SELECT' : op === 'put' ? 'INSERT' : op === 'delete' ? 'DELETE' : 'OTHER',\n source: 'r2',\n ...extra,\n });\n }\n\n return {\n async get(key: string, r2Options?: unknown): Promise<R2ObjectBody | null> {\n const start = Date.now();\n try {\n const result = await bucket.get(key, r2Options);\n emitOp('get', key, start, Date.now() - start, {\n rowsReturned: result !== null ? 1 : 0,\n label: result ? `${result.size} bytes` : undefined,\n });\n return result;\n } catch (err) {\n emitOp('get', key, start, Date.now() - start, { error: (err as Error).message });\n throw err;\n }\n },\n\n async put(\n key: string,\n value: ReadableStream | ArrayBuffer | ArrayBufferView | string | null | Blob,\n r2Options?: unknown,\n ): Promise<R2Object | null> {\n const start = Date.now();\n try {\n const result = await bucket.put(key, value, r2Options);\n emitOp('put', key, start, Date.now() - start, {\n rowsAffected: 1,\n label: result ? `${result.size} bytes` : undefined,\n });\n return result;\n } catch (err) {\n emitOp('put', key, start, Date.now() - start, { error: (err as Error).message });\n throw err;\n }\n },\n\n async delete(keys: string | string[]): Promise<void> {\n const keyList = Array.isArray(keys) ? keys : [keys];\n const keyLabel = keyList.length === 1 ? keyList[0] : `${keyList.length} keys`;\n const start = Date.now();\n try {\n await bucket.delete(keys);\n emitOp('delete', keyLabel, start, Date.now() - start, { rowsAffected: keyList.length });\n } catch (err) {\n emitOp('delete', keyLabel, start, Date.now() - start, { error: (err as Error).message });\n throw err;\n }\n },\n\n async list(r2Options?: unknown): Promise<R2Objects> {\n const start = Date.now();\n try {\n const result = await bucket.list(r2Options);\n emitOp('list', '*', start, Date.now() - start, { rowsReturned: result.objects.length });\n return result;\n } catch (err) {\n emitOp('list', '*', start, Date.now() - start, { error: (err as Error).message });\n throw err;\n }\n },\n\n async head(key: string): Promise<R2Object | null> {\n const start = Date.now();\n try {\n const result = await bucket.head(key);\n emitOp('head', key, start, Date.now() - start, {\n rowsReturned: result !== null ? 1 : 0,\n label: result ? `${result.size} bytes` : undefined,\n });\n return result;\n } catch (err) {\n emitOp('head', key, start, Date.now() - start, { error: (err as Error).message });\n throw err;\n }\n },\n };\n}\n","// ============================================================\n// @runtimescope/workers-sdk\n// Zero-dependency SDK for Cloudflare Workers.\n// Captures requests, D1 queries, KV/R2 ops, console, errors.\n// ============================================================\n\nexport { withRuntimeScope } from './handler.js';\nexport { getActiveContext } from './handler.js';\nexport type { WorkersFetchHandler, RuntimeScopeContext } from './handler.js';\n\nexport { instrumentD1 } from './bindings/d1.js';\nexport { instrumentKV } from './bindings/kv.js';\nexport { instrumentR2 } from './bindings/r2.js';\n\nexport { WorkersTransport } from './transport.js';\nexport { Sampler } from './sampler.js';\nexport { generateId, generateSessionId } from './utils.js';\n\nexport type {\n WorkersConfig,\n WorkersRuntimeEvent,\n ConsoleEvent,\n DatabaseEvent,\n NetworkEvent,\n CustomEvent,\n UIInteractionEvent,\n UserContext,\n ConsoleLevel,\n DatabaseOperation,\n DatabaseSource,\n D1DatabaseBinding,\n D1PreparedStatementBinding,\n D1Result,\n KVNamespaceBinding,\n R2BucketBinding,\n R2Object,\n R2ObjectBody,\n R2Objects,\n} from './types.js';\n\n// ============================================================\n// Convenience: instrument bindings using the active request context\n// These are shortcuts that automatically use the current request's\n// transport and session ID — no manual wiring needed.\n// ============================================================\n\nimport { getActiveContext } from './handler.js';\nimport { instrumentD1 as _instrumentD1 } from './bindings/d1.js';\nimport { instrumentKV as _instrumentKV } from './bindings/kv.js';\nimport { instrumentR2 as _instrumentR2 } from './bindings/r2.js';\nimport { generateId } from './utils.js';\nimport type {\n D1DatabaseBinding,\n KVNamespaceBinding,\n R2BucketBinding,\n CustomEvent,\n UIInteractionEvent,\n} from './types.js';\n\n/**\n * Instrument a D1 database using the active request context.\n * Must be called inside a withRuntimeScope handler.\n *\n * @example\n * ```ts\n * import { withRuntimeScope, scopeD1 } from '@runtimescope/workers-sdk';\n *\n * export default withRuntimeScope({\n * async fetch(request, env, ctx) {\n * const db = scopeD1(env.DB);\n * const users = await db.prepare('SELECT * FROM users').all();\n * return Response.json(users);\n * },\n * }, { appName: 'my-worker' });\n * ```\n */\nexport function scopeD1(db: D1DatabaseBinding): D1DatabaseBinding {\n const ctx = getActiveContext();\n if (!ctx) return db; // No active context — return unwrapped (safe for non-instrumented calls)\n return _instrumentD1(db, ctx.emit, { sessionId: ctx.sessionId });\n}\n\n/** Instrument a KV namespace using the active request context. */\nexport function scopeKV(kv: KVNamespaceBinding): KVNamespaceBinding {\n const ctx = getActiveContext();\n if (!ctx) return kv;\n return _instrumentKV(kv, ctx.emit, { sessionId: ctx.sessionId });\n}\n\n/** Instrument an R2 bucket using the active request context. */\nexport function scopeR2(bucket: R2BucketBinding): R2BucketBinding {\n const ctx = getActiveContext();\n if (!ctx) return bucket;\n return _instrumentR2(bucket, ctx.emit, { sessionId: ctx.sessionId });\n}\n\n// ============================================================\n// Custom event tracking & breadcrumbs\n// Must be called inside a withRuntimeScope handler.\n// ============================================================\n\n/**\n * Track a custom business event (e.g., user signup, payment processed).\n * Must be called inside a withRuntimeScope handler.\n *\n * @example\n * ```ts\n * import { withRuntimeScope, track } from '@runtimescope/workers-sdk';\n *\n * export default withRuntimeScope({\n * async fetch(request, env, ctx) {\n * track('payment.processed', { amount: 99.99, currency: 'USD' });\n * return new Response('OK');\n * },\n * }, { appName: 'payments-worker' });\n * ```\n */\nexport function track(name: string, properties?: Record<string, unknown>): void {\n const ctx = getActiveContext();\n if (!ctx) return;\n const event: CustomEvent = {\n eventId: generateId(),\n sessionId: ctx.sessionId,\n timestamp: Date.now(),\n eventType: 'custom',\n name,\n ...(properties && { properties }),\n };\n ctx.emit(event);\n}\n\n/**\n * Add a breadcrumb to the current request's event trail.\n * Useful for marking key points in request processing.\n *\n * @example\n * ```ts\n * import { withRuntimeScope, addBreadcrumb } from '@runtimescope/workers-sdk';\n *\n * export default withRuntimeScope({\n * async fetch(request, env, ctx) {\n * addBreadcrumb('auth check passed', { userId: '123' });\n * // ... process request\n * addBreadcrumb('cache miss, fetching from origin');\n * return new Response('OK');\n * },\n * }, { appName: 'api-worker' });\n * ```\n */\nexport function addBreadcrumb(message: string, data?: Record<string, unknown>): void {\n const ctx = getActiveContext();\n if (!ctx) return;\n const event: UIInteractionEvent = {\n eventId: generateId(),\n sessionId: ctx.sessionId,\n timestamp: Date.now(),\n eventType: 'ui',\n action: 'breadcrumb',\n target: 'manual',\n text: message,\n ...(data && { data }),\n };\n ctx.emit(event);\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/handler.ts","../src/utils.ts","../src/transport.ts","../src/sampler.ts","../src/interceptors/console.ts","../src/bindings/d1.ts","../src/bindings/kv.ts","../src/bindings/r2.ts","../src/index.ts"],"sourcesContent":["import { AsyncLocalStorage } from 'node:async_hooks';\nimport type {\n WorkersConfig,\n WorkersRuntimeEvent,\n NetworkEvent,\n ConsoleEvent,\n UserContext,\n} from './types.js';\nimport { WorkersTransport } from './transport.js';\nimport { Sampler } from './sampler.js';\nimport { interceptConsole } from './interceptors/console.js';\nimport { generateId } from './utils.js';\n\n// ============================================================\n// withRuntimeScope — wraps a Workers fetch handler\n// Captures request/response metrics, errors, console output.\n// Flushes all events via ctx.waitUntil() at end of request.\n// ============================================================\n\n/** Internal context exposed to binding wrappers */\nexport interface RuntimeScopeContext {\n transport: WorkersTransport;\n sessionId: string;\n config: WorkersConfig;\n emit: (event: WorkersRuntimeEvent) => void;\n}\n\n// Per-request context — AsyncLocalStorage ensures isolation under concurrent requests.\n// Available in Workers runtime with nodejs_compat flag and in Node.js 16+.\nconst _contextStorage = new AsyncLocalStorage<RuntimeScopeContext>();\n\n/** Get the active RuntimeScope context (used by binding wrappers) */\nexport function getActiveContext(): RuntimeScopeContext | null {\n return _contextStorage.getStore() ?? null;\n}\n\nconst DEFAULT_REDACT_HEADERS = ['authorization', 'cookie', 'set-cookie'];\n\nexport interface WorkersFetchHandler {\n fetch(\n request: Request,\n env: unknown,\n ctx: ExecutionContext,\n ): Response | Promise<Response>;\n}\n\n/**\n * Wrap a Workers fetch handler to capture request/response metrics,\n * errors, and console output. Events are flushed via ctx.waitUntil().\n *\n * @example\n * ```ts\n * import { withRuntimeScope } from '@runtimescope/workers-sdk';\n *\n * export default withRuntimeScope({\n * async fetch(request, env, ctx) {\n * return new Response('Hello!');\n * },\n * }, { appName: 'my-worker' });\n * ```\n */\nexport function withRuntimeScope(\n handler: WorkersFetchHandler,\n config: WorkersConfig,\n): WorkersFetchHandler {\n const transport = new WorkersTransport(config);\n const sampler = config.sampleRate !== undefined && config.sampleRate < 1\n ? new Sampler({ sampleRate: config.sampleRate })\n : null;\n\n const redactHeaders = config.redactHeaders ?? DEFAULT_REDACT_HEADERS;\n const redactSet = new Set(redactHeaders.map((h) => h.toLowerCase()));\n\n function emit(event: WorkersRuntimeEvent): void {\n if (sampler && !sampler.shouldSample(event)) return;\n if (config.beforeSend) {\n const filtered = config.beforeSend(event);\n if (!filtered) return;\n transport.queue(filtered);\n } else {\n transport.queue(event);\n }\n }\n\n // Set up console interceptor (persistent across requests)\n let restoreConsole: (() => void) | null = null;\n if (config.captureConsole !== false) {\n restoreConsole = interceptConsole(emit, {\n sessionId: transport.sessionId,\n });\n }\n\n function extractHeaders(headers: Headers): Record<string, string> {\n if (!config.captureHeaders) return {};\n const result: Record<string, string> = {};\n headers.forEach((value, key) => {\n result[key] = redactSet.has(key.toLowerCase()) ? '[REDACTED]' : value;\n });\n return result;\n }\n\n return {\n async fetch(\n request: Request,\n env: unknown,\n ctx: ExecutionContext,\n ): Promise<Response> {\n const start = Date.now();\n const url = new URL(request.url);\n\n // Run handler inside AsyncLocalStorage so binding wrappers\n // get the correct per-request context even under concurrency\n const rsContext: RuntimeScopeContext = {\n transport,\n sessionId: transport.sessionId,\n config,\n emit,\n };\n\n return _contextStorage.run(rsContext, async () => {\n try {\n const response = await handler.fetch(request, env, ctx);\n const duration = Date.now() - start;\n\n const networkEvent: NetworkEvent = {\n eventId: generateId(),\n sessionId: transport.sessionId,\n timestamp: start,\n eventType: 'network',\n url: url.pathname + url.search,\n method: request.method,\n status: response.status,\n duration,\n requestHeaders: extractHeaders(request.headers),\n responseHeaders: extractHeaders(response.headers),\n requestBodySize: 0,\n responseBodySize: 0,\n ttfb: duration,\n source: 'workers',\n direction: 'incoming',\n cfProperties: extractCfProperties(request),\n };\n\n emit(networkEvent);\n ctx.waitUntil(transport.flush());\n return response;\n } catch (error) {\n const duration = Date.now() - start;\n\n // Capture the error as a console error event\n const errorEvent: ConsoleEvent = {\n eventId: generateId(),\n sessionId: transport.sessionId,\n timestamp: Date.now(),\n eventType: 'console',\n level: 'error',\n message: error instanceof Error ? error.message : String(error),\n args: [error instanceof Error ? { name: error.name, message: error.message, stack: error.stack } : String(error)],\n stackTrace: error instanceof Error ? error.stack : undefined,\n };\n\n emit(errorEvent);\n\n // Also capture the failed request\n const networkEvent: NetworkEvent = {\n eventId: generateId(),\n sessionId: transport.sessionId,\n timestamp: start,\n eventType: 'network',\n url: url.pathname + url.search,\n method: request.method,\n status: 500,\n duration,\n requestHeaders: extractHeaders(request.headers),\n responseHeaders: {},\n requestBodySize: 0,\n responseBodySize: 0,\n ttfb: duration,\n source: 'workers',\n direction: 'incoming',\n cfProperties: extractCfProperties(request),\n errorMessage: error instanceof Error ? error.message : String(error),\n };\n\n emit(networkEvent);\n ctx.waitUntil(transport.flush());\n throw error;\n }\n });\n },\n };\n}\n\nfunction extractCfProperties(request: Request): NetworkEvent['cfProperties'] | undefined {\n // request.cf is Cloudflare-specific — may not exist in non-CF environments\n const cf = (request as unknown as { cf?: Record<string, unknown> }).cf;\n if (!cf) return undefined;\n\n return {\n colo: cf.colo as string | undefined,\n country: cf.country as string | undefined,\n city: cf.city as string | undefined,\n region: cf.region as string | undefined,\n asn: cf.asn as number | undefined,\n httpProtocol: cf.httpProtocol as string | undefined,\n tlsVersion: cf.tlsVersion as string | undefined,\n };\n}\n","// ============================================================\n// Utility functions — no Node.js APIs, Workers-safe\n// ============================================================\n\n/** Generate a random event ID using Web Crypto API (available in Workers) */\nexport function generateId(): string {\n return crypto.randomUUID();\n}\n\n/** Generate a session ID with worker prefix */\nexport function generateSessionId(): string {\n return `wk-${crypto.randomUUID().slice(0, 16)}`;\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 type { WorkersRuntimeEvent, WorkersConfig, UserContext } from './types.js';\nimport { generateSessionId } from './utils.js';\n\n// ============================================================\n// Workers Transport\n// Flush events via ctx.waitUntil(fetch(...)) — no timers, no intervals.\n// Matches collector's POST /api/events endpoint.\n// ============================================================\n\nconst SDK_VERSION = '0.9.1';\nconst DEFAULT_ENDPOINT = 'http://localhost:9091/api/events';\n\nexport class WorkersTransport {\n private buffer: WorkersRuntimeEvent[] = [];\n private maxQueueSize: number;\n private url: string;\n private authToken: string | undefined;\n private appName: string;\n private projectId?: string;\n private sessionRegistered = false;\n private _droppedCount = 0;\n\n readonly sessionId: string;\n\n constructor(config: WorkersConfig) {\n this.sessionId = generateSessionId();\n this.url = config.httpEndpoint ?? DEFAULT_ENDPOINT;\n this.appName = config.appName;\n this.projectId = config.projectId;\n this.authToken = config.authToken;\n this.maxQueueSize = config.maxQueueSize ?? 500;\n }\n\n get droppedCount(): number {\n return this._droppedCount;\n }\n\n queue(event: WorkersRuntimeEvent): void {\n if (this.buffer.length >= this.maxQueueSize) {\n this.buffer.shift();\n this._droppedCount++;\n }\n this.buffer.push(event);\n }\n\n /**\n * Flush all buffered events to the collector.\n * Call via ctx.waitUntil(transport.flush()) at the end of each request.\n * Retries once on failure with a short delay.\n */\n async flush(): Promise<void> {\n if (this.buffer.length === 0) return;\n\n const events = this.buffer.splice(0);\n const payload: Record<string, unknown> = {\n sessionId: this.sessionId,\n events,\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 = SDK_VERSION;\n if (this.projectId) payload.projectId = this.projectId;\n }\n\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 body = JSON.stringify(payload);\n\n for (let attempt = 0; attempt < 2; attempt++) {\n try {\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), 5_000);\n\n const response = await fetch(this.url, {\n method: 'POST',\n headers,\n body,\n signal: controller.signal,\n });\n\n clearTimeout(timeoutId);\n\n if (response.ok) {\n this.sessionRegistered = true;\n return;\n }\n\n // Server error (5xx) — retry once\n if (response.status >= 500 && attempt === 0) continue;\n // Client error (4xx) — don't retry\n return;\n } catch {\n // Network error or timeout — retry once\n if (attempt === 0) {\n await new Promise((r) => setTimeout(r, 200));\n continue;\n }\n // Second attempt failed — events are lost (acceptable for edge observability)\n }\n }\n }\n}\n","import type { WorkersRuntimeEvent } from './types.js';\n\n// ============================================================\n// Sampler — probabilistic + rate limiting\n// Adapted from server-sdk, no Node.js APIs.\n// ============================================================\n\nexport interface SamplerConfig {\n /** Probabilistic sample rate: 0.0–1.0 (default: 1.0 = keep all) */\n sampleRate?: number;\n}\n\nexport class Sampler {\n private _droppedCount = 0;\n\n constructor(private config: SamplerConfig) {}\n\n get droppedCount(): number {\n return this._droppedCount;\n }\n\n shouldSample(_event: WorkersRuntimeEvent): boolean {\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 return true;\n }\n}\n","import type { ConsoleEvent, ConsoleLevel } from '../types.js';\nimport { generateId, safeSerialize } from '../utils.js';\n\n// ============================================================\n// Console Interceptor — Workers-safe\n// Patches console.log/warn/error/info/debug/trace.\n// Returns a restore function for cleanup.\n// ============================================================\n\ntype EmitFn = (event: ConsoleEvent) => void;\n\nconst LEVELS: ConsoleLevel[] = ['log', 'warn', 'error', 'info', 'debug', 'trace'];\n\nexport interface ConsoleInterceptorOptions {\n levels?: ConsoleLevel[];\n sessionId: string;\n}\n\nexport function interceptConsole(\n emit: EmitFn,\n options: ConsoleInterceptorOptions\n): () => void {\n const levels = options.levels ?? LEVELS;\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: options.sessionId,\n timestamp: Date.now(),\n eventType: 'console',\n level,\n message,\n args: args.map((a) => safeSerialize(a, 3)),\n stackTrace:\n level === 'error' || level === 'trace'\n ? new Error().stack?.split('\\n').slice(2).join('\\n')\n : undefined,\n };\n\n // emit() already applies beforeSend — don't double-filter\n emit(event);\n\n // Call original — 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 type {\n D1DatabaseBinding,\n D1PreparedStatementBinding,\n D1Result,\n D1ExecResult,\n DatabaseEvent,\n} from '../types.js';\nimport { generateId } from '../utils.js';\n\n// ============================================================\n// D1 Binding Wrapper\n// Wraps a D1Database to capture SQL queries, timing, and results.\n// Events emitted as 'database' type with source: 'd1'.\n// ============================================================\n\ntype EmitFn = (event: DatabaseEvent) => void;\n\ninterface D1InstrumentOptions {\n sessionId: string;\n}\n\n/**\n * Wrap a D1 database binding to capture queries.\n *\n * @example\n * ```ts\n * const db = instrumentD1(env.DB, transport.sessionId);\n * const results = await db.prepare('SELECT * FROM users').all();\n * ```\n */\nexport function instrumentD1(\n db: D1DatabaseBinding,\n emit: EmitFn,\n options: D1InstrumentOptions,\n): D1DatabaseBinding {\n return {\n prepare(query: string): D1PreparedStatementBinding {\n const stmt = db.prepare(query);\n return instrumentStatement(stmt, query, emit, options);\n },\n\n async batch<T = unknown>(statements: D1PreparedStatementBinding[]): Promise<D1Result<T>[]> {\n const start = Date.now();\n try {\n const results = await db.batch<T>(statements);\n const duration = Date.now() - start;\n emit({\n eventId: generateId(),\n sessionId: options.sessionId,\n timestamp: start,\n eventType: 'database',\n query: `BATCH (${statements.length} statements)`,\n normalizedQuery: 'BATCH',\n duration,\n tablesAccessed: [],\n operation: 'OTHER',\n source: 'd1',\n rowsReturned: results.reduce((sum, r) => sum + (r.results?.length ?? 0), 0),\n });\n return results;\n } catch (err) {\n const duration = Date.now() - start;\n emit({\n eventId: generateId(),\n sessionId: options.sessionId,\n timestamp: start,\n eventType: 'database',\n query: `BATCH (${statements.length} statements)`,\n normalizedQuery: 'BATCH',\n duration,\n tablesAccessed: [],\n operation: 'OTHER',\n source: 'd1',\n error: (err as Error).message,\n });\n throw err;\n }\n },\n\n async exec(query: string): Promise<D1ExecResult> {\n const start = Date.now();\n try {\n const result = await db.exec(query);\n emit({\n eventId: generateId(),\n sessionId: options.sessionId,\n timestamp: start,\n eventType: 'database',\n query,\n normalizedQuery: normalizeD1Query(query),\n duration: result.duration,\n tablesAccessed: extractTables(query),\n operation: parseOp(query),\n source: 'd1',\n rowsAffected: result.count,\n });\n return result;\n } catch (err) {\n const duration = Date.now() - start;\n emit({\n eventId: generateId(),\n sessionId: options.sessionId,\n timestamp: start,\n eventType: 'database',\n query,\n normalizedQuery: normalizeD1Query(query),\n duration,\n tablesAccessed: extractTables(query),\n operation: parseOp(query),\n source: 'd1',\n error: (err as Error).message,\n });\n throw err;\n }\n },\n\n dump(): Promise<ArrayBuffer> {\n return db.dump();\n },\n };\n}\n\nfunction instrumentStatement(\n stmt: D1PreparedStatementBinding,\n query: string,\n emit: EmitFn,\n options: D1InstrumentOptions,\n): D1PreparedStatementBinding {\n const op = parseOp(query);\n const tables = extractTables(query);\n const normalized = normalizeD1Query(query);\n\n function makeEvent(start: number, duration: number, extra: Partial<DatabaseEvent> = {}): DatabaseEvent {\n return {\n eventId: generateId(),\n sessionId: options.sessionId,\n timestamp: start,\n eventType: 'database',\n query,\n normalizedQuery: normalized,\n duration,\n tablesAccessed: tables,\n operation: op,\n source: 'd1',\n ...extra,\n };\n }\n\n async function wrapAsync<T>(fn: () => Promise<T>, start: number, getExtra?: (result: T) => Partial<DatabaseEvent>): Promise<T> {\n try {\n const result = await fn();\n const duration = Date.now() - start;\n emit(makeEvent(start, duration, getExtra?.(result)));\n return result;\n } catch (err) {\n const duration = Date.now() - start;\n emit(makeEvent(start, duration, { error: (err as Error).message }));\n throw err;\n }\n }\n\n return {\n bind(...values: unknown[]): D1PreparedStatementBinding {\n const bound = stmt.bind(...values);\n return instrumentStatement(bound, query, emit, options);\n },\n\n first<T = unknown>(colName?: string): Promise<T | null> {\n const start = Date.now();\n return wrapAsync(\n () => stmt.first<T>(colName),\n start,\n (result) => ({ rowsReturned: result !== null ? 1 : 0 }),\n );\n },\n\n run<T = unknown>(): Promise<D1Result<T>> {\n const start = Date.now();\n return wrapAsync(\n () => stmt.run<T>(),\n start,\n (result) => ({\n rowsAffected: result.meta?.changes,\n duration: result.meta?.duration ?? (Date.now() - start),\n }),\n );\n },\n\n all<T = unknown>(): Promise<D1Result<T>> {\n const start = Date.now();\n return wrapAsync(\n () => stmt.all<T>(),\n start,\n (result) => ({\n rowsReturned: result.results?.length ?? 0,\n duration: result.meta?.duration ?? (Date.now() - start),\n }),\n );\n },\n\n raw<T = unknown>(rawOptions?: { columnNames?: boolean }): Promise<T[]> {\n const start = Date.now();\n return wrapAsync(\n () => stmt.raw<T>(rawOptions),\n start,\n (result) => ({ rowsReturned: result.length }),\n );\n },\n };\n}\n\n// --- SQL Parsing Helpers (lightweight, no dependencies) ---\n\nfunction parseOp(query: string): DatabaseEvent['operation'] {\n const trimmed = query.trimStart().toUpperCase();\n if (trimmed.startsWith('SELECT')) return 'SELECT';\n if (trimmed.startsWith('INSERT')) return 'INSERT';\n if (trimmed.startsWith('UPDATE')) return 'UPDATE';\n if (trimmed.startsWith('DELETE')) return 'DELETE';\n return 'OTHER';\n}\n\nfunction extractTables(query: string): string[] {\n const tables: string[] = [];\n const fromMatch = query.match(/\\bFROM\\s+(\\w+)/i);\n if (fromMatch) tables.push(fromMatch[1]);\n const intoMatch = query.match(/\\bINTO\\s+(\\w+)/i);\n if (intoMatch) tables.push(intoMatch[1]);\n const updateMatch = query.match(/\\bUPDATE\\s+(\\w+)/i);\n if (updateMatch) tables.push(updateMatch[1]);\n const joinMatches = query.matchAll(/\\bJOIN\\s+(\\w+)/gi);\n for (const m of joinMatches) tables.push(m[1]);\n return [...new Set(tables)];\n}\n\nfunction normalizeD1Query(query: string): string {\n return query\n .replace(/'[^']*'/g, '?')\n .replace(/\\b\\d+\\b/g, '?')\n .replace(/\\s+/g, ' ')\n .trim();\n}\n","import type { KVNamespaceBinding, DatabaseEvent } from '../types.js';\nimport { generateId } from '../utils.js';\n\n// ============================================================\n// KV Namespace Wrapper\n// Wraps a KVNamespace to capture get/put/delete/list operations.\n// Events emitted as 'database' type with source: 'kv'.\n// ============================================================\n\ntype EmitFn = (event: DatabaseEvent) => void;\n\ninterface KVInstrumentOptions {\n sessionId: string;\n}\n\n/**\n * Wrap a KV namespace binding to capture operations.\n *\n * @example\n * ```ts\n * const kv = instrumentKV(env.MY_KV, emit, { sessionId });\n * await kv.put('key', 'value');\n * ```\n */\nexport function instrumentKV(\n kv: KVNamespaceBinding,\n emit: EmitFn,\n options: KVInstrumentOptions,\n): KVNamespaceBinding {\n function sanitizeKey(key: string): string {\n // Truncate and escape quotes/newlines to prevent malformed query strings\n const safe = key.length > 200 ? key.slice(0, 200) + '…' : key;\n return safe.replace(/\\\\/g, '\\\\\\\\').replace(/\"/g, '\\\\\"').replace(/\\n/g, '\\\\n');\n }\n\n function emitOp(op: string, key: string, start: number, duration: number, extra: Partial<DatabaseEvent> = {}): void {\n emit({\n eventId: generateId(),\n sessionId: options.sessionId,\n timestamp: start,\n eventType: 'database',\n query: `KV.${op}(\"${sanitizeKey(key)}\")`,\n normalizedQuery: `KV.${op}(?)`,\n duration,\n tablesAccessed: [],\n operation: op === 'get' || op === 'getWithMetadata' || op === 'list' ? 'SELECT' : op === 'put' ? 'INSERT' : op === 'delete' ? 'DELETE' : 'OTHER',\n source: 'kv',\n ...extra,\n });\n }\n\n return {\n async get(key: string, kvOptions?: unknown): Promise<string | null> {\n const start = Date.now();\n try {\n const result = await kv.get(key, kvOptions);\n emitOp('get', key, start, Date.now() - start, { rowsReturned: result !== null ? 1 : 0 });\n return result;\n } catch (err) {\n emitOp('get', key, start, Date.now() - start, { error: (err as Error).message });\n throw err;\n }\n },\n\n async getWithMetadata<M = unknown>(key: string, kvOptions?: unknown): Promise<{ value: string | null; metadata: M | null }> {\n const start = Date.now();\n try {\n const result = await kv.getWithMetadata<M>(key, kvOptions);\n emitOp('getWithMetadata', key, start, Date.now() - start, { rowsReturned: result.value !== null ? 1 : 0 });\n return result;\n } catch (err) {\n emitOp('getWithMetadata', key, start, Date.now() - start, { error: (err as Error).message });\n throw err;\n }\n },\n\n async put(key: string, value: string | ReadableStream | ArrayBuffer, kvOptions?: unknown): Promise<void> {\n const start = Date.now();\n try {\n await kv.put(key, value, kvOptions);\n emitOp('put', key, start, Date.now() - start, { rowsAffected: 1 });\n } catch (err) {\n emitOp('put', key, start, Date.now() - start, { error: (err as Error).message });\n throw err;\n }\n },\n\n async delete(key: string): Promise<void> {\n const start = Date.now();\n try {\n await kv.delete(key);\n emitOp('delete', key, start, Date.now() - start, { rowsAffected: 1 });\n } catch (err) {\n emitOp('delete', key, start, Date.now() - start, { error: (err as Error).message });\n throw err;\n }\n },\n\n async list(kvOptions?: unknown): Promise<{ keys: { name: string }[]; list_complete: boolean; cursor?: string }> {\n const start = Date.now();\n try {\n const result = await kv.list(kvOptions);\n emitOp('list', '*', start, Date.now() - start, { rowsReturned: result.keys.length });\n return result;\n } catch (err) {\n emitOp('list', '*', start, Date.now() - start, { error: (err as Error).message });\n throw err;\n }\n },\n };\n}\n","import type { R2BucketBinding, R2Object, R2ObjectBody, R2Objects, DatabaseEvent } from '../types.js';\nimport { generateId } from '../utils.js';\n\n// ============================================================\n// R2 Bucket Wrapper\n// Wraps an R2Bucket to capture get/put/delete/list/head operations.\n// Events emitted as 'database' type with source: 'r2'.\n// ============================================================\n\ntype EmitFn = (event: DatabaseEvent) => void;\n\ninterface R2InstrumentOptions {\n sessionId: string;\n}\n\n/**\n * Wrap an R2 bucket binding to capture operations.\n *\n * @example\n * ```ts\n * const bucket = instrumentR2(env.MY_BUCKET, emit, { sessionId });\n * await bucket.put('file.txt', 'contents');\n * ```\n */\nexport function instrumentR2(\n bucket: R2BucketBinding,\n emit: EmitFn,\n options: R2InstrumentOptions,\n): R2BucketBinding {\n function sanitizeKey(key: string): string {\n const safe = key.length > 200 ? key.slice(0, 200) + '…' : key;\n return safe.replace(/\\\\/g, '\\\\\\\\').replace(/\"/g, '\\\\\"').replace(/\\n/g, '\\\\n');\n }\n\n function emitOp(op: string, key: string, start: number, duration: number, extra: Partial<DatabaseEvent> = {}): void {\n emit({\n eventId: generateId(),\n sessionId: options.sessionId,\n timestamp: start,\n eventType: 'database',\n query: `R2.${op}(\"${sanitizeKey(key)}\")`,\n normalizedQuery: `R2.${op}(?)`,\n duration,\n tablesAccessed: [],\n operation: op === 'get' || op === 'list' || op === 'head' ? 'SELECT' : op === 'put' ? 'INSERT' : op === 'delete' ? 'DELETE' : 'OTHER',\n source: 'r2',\n ...extra,\n });\n }\n\n return {\n async get(key: string, r2Options?: unknown): Promise<R2ObjectBody | null> {\n const start = Date.now();\n try {\n const result = await bucket.get(key, r2Options);\n emitOp('get', key, start, Date.now() - start, {\n rowsReturned: result !== null ? 1 : 0,\n label: result ? `${result.size} bytes` : undefined,\n });\n return result;\n } catch (err) {\n emitOp('get', key, start, Date.now() - start, { error: (err as Error).message });\n throw err;\n }\n },\n\n async put(\n key: string,\n value: ReadableStream | ArrayBuffer | ArrayBufferView | string | null | Blob,\n r2Options?: unknown,\n ): Promise<R2Object | null> {\n const start = Date.now();\n try {\n const result = await bucket.put(key, value, r2Options);\n emitOp('put', key, start, Date.now() - start, {\n rowsAffected: 1,\n label: result ? `${result.size} bytes` : undefined,\n });\n return result;\n } catch (err) {\n emitOp('put', key, start, Date.now() - start, { error: (err as Error).message });\n throw err;\n }\n },\n\n async delete(keys: string | string[]): Promise<void> {\n const keyList = Array.isArray(keys) ? keys : [keys];\n const keyLabel = keyList.length === 1 ? keyList[0] : `${keyList.length} keys`;\n const start = Date.now();\n try {\n await bucket.delete(keys);\n emitOp('delete', keyLabel, start, Date.now() - start, { rowsAffected: keyList.length });\n } catch (err) {\n emitOp('delete', keyLabel, start, Date.now() - start, { error: (err as Error).message });\n throw err;\n }\n },\n\n async list(r2Options?: unknown): Promise<R2Objects> {\n const start = Date.now();\n try {\n const result = await bucket.list(r2Options);\n emitOp('list', '*', start, Date.now() - start, { rowsReturned: result.objects.length });\n return result;\n } catch (err) {\n emitOp('list', '*', start, Date.now() - start, { error: (err as Error).message });\n throw err;\n }\n },\n\n async head(key: string): Promise<R2Object | null> {\n const start = Date.now();\n try {\n const result = await bucket.head(key);\n emitOp('head', key, start, Date.now() - start, {\n rowsReturned: result !== null ? 1 : 0,\n label: result ? `${result.size} bytes` : undefined,\n });\n return result;\n } catch (err) {\n emitOp('head', key, start, Date.now() - start, { error: (err as Error).message });\n throw err;\n }\n },\n };\n}\n","// ============================================================\n// @runtimescope/workers-sdk\n// Zero-dependency SDK for Cloudflare Workers.\n// Captures requests, D1 queries, KV/R2 ops, console, errors.\n// ============================================================\n\nexport { withRuntimeScope } from './handler.js';\nexport { getActiveContext } from './handler.js';\nexport type { WorkersFetchHandler, RuntimeScopeContext } from './handler.js';\n\nexport { instrumentD1 } from './bindings/d1.js';\nexport { instrumentKV } from './bindings/kv.js';\nexport { instrumentR2 } from './bindings/r2.js';\n\nexport { WorkersTransport } from './transport.js';\nexport { Sampler } from './sampler.js';\nexport { generateId, generateSessionId } from './utils.js';\n\nexport type {\n WorkersConfig,\n WorkersRuntimeEvent,\n ConsoleEvent,\n DatabaseEvent,\n NetworkEvent,\n CustomEvent,\n UIInteractionEvent,\n UserContext,\n ConsoleLevel,\n DatabaseOperation,\n DatabaseSource,\n D1DatabaseBinding,\n D1PreparedStatementBinding,\n D1Result,\n KVNamespaceBinding,\n R2BucketBinding,\n R2Object,\n R2ObjectBody,\n R2Objects,\n} from './types.js';\n\n// ============================================================\n// Convenience: instrument bindings using the active request context\n// These are shortcuts that automatically use the current request's\n// transport and session ID — no manual wiring needed.\n// ============================================================\n\nimport { getActiveContext } from './handler.js';\nimport { instrumentD1 as _instrumentD1 } from './bindings/d1.js';\nimport { instrumentKV as _instrumentKV } from './bindings/kv.js';\nimport { instrumentR2 as _instrumentR2 } from './bindings/r2.js';\nimport { generateId } from './utils.js';\nimport type {\n D1DatabaseBinding,\n KVNamespaceBinding,\n R2BucketBinding,\n CustomEvent,\n UIInteractionEvent,\n} from './types.js';\n\n/**\n * Instrument a D1 database using the active request context.\n * Must be called inside a withRuntimeScope handler.\n *\n * @example\n * ```ts\n * import { withRuntimeScope, scopeD1 } from '@runtimescope/workers-sdk';\n *\n * export default withRuntimeScope({\n * async fetch(request, env, ctx) {\n * const db = scopeD1(env.DB);\n * const users = await db.prepare('SELECT * FROM users').all();\n * return Response.json(users);\n * },\n * }, { appName: 'my-worker' });\n * ```\n */\nexport function scopeD1(db: D1DatabaseBinding): D1DatabaseBinding {\n const ctx = getActiveContext();\n if (!ctx) return db; // No active context — return unwrapped (safe for non-instrumented calls)\n return _instrumentD1(db, ctx.emit, { sessionId: ctx.sessionId });\n}\n\n/** Instrument a KV namespace using the active request context. */\nexport function scopeKV(kv: KVNamespaceBinding): KVNamespaceBinding {\n const ctx = getActiveContext();\n if (!ctx) return kv;\n return _instrumentKV(kv, ctx.emit, { sessionId: ctx.sessionId });\n}\n\n/** Instrument an R2 bucket using the active request context. */\nexport function scopeR2(bucket: R2BucketBinding): R2BucketBinding {\n const ctx = getActiveContext();\n if (!ctx) return bucket;\n return _instrumentR2(bucket, ctx.emit, { sessionId: ctx.sessionId });\n}\n\n// ============================================================\n// Custom event tracking & breadcrumbs\n// Must be called inside a withRuntimeScope handler.\n// ============================================================\n\n/**\n * Track a custom business event (e.g., user signup, payment processed).\n * Must be called inside a withRuntimeScope handler.\n *\n * @example\n * ```ts\n * import { withRuntimeScope, track } from '@runtimescope/workers-sdk';\n *\n * export default withRuntimeScope({\n * async fetch(request, env, ctx) {\n * track('payment.processed', { amount: 99.99, currency: 'USD' });\n * return new Response('OK');\n * },\n * }, { appName: 'payments-worker' });\n * ```\n */\nexport function track(name: string, properties?: Record<string, unknown>): void {\n const ctx = getActiveContext();\n if (!ctx) return;\n const event: CustomEvent = {\n eventId: generateId(),\n sessionId: ctx.sessionId,\n timestamp: Date.now(),\n eventType: 'custom',\n name,\n ...(properties && { properties }),\n };\n ctx.emit(event);\n}\n\n/**\n * Add a breadcrumb to the current request's event trail.\n * Useful for marking key points in request processing.\n *\n * @example\n * ```ts\n * import { withRuntimeScope, addBreadcrumb } from '@runtimescope/workers-sdk';\n *\n * export default withRuntimeScope({\n * async fetch(request, env, ctx) {\n * addBreadcrumb('auth check passed', { userId: '123' });\n * // ... process request\n * addBreadcrumb('cache miss, fetching from origin');\n * return new Response('OK');\n * },\n * }, { appName: 'api-worker' });\n * ```\n */\nexport function addBreadcrumb(message: string, data?: Record<string, unknown>): void {\n const ctx = getActiveContext();\n if (!ctx) return;\n const event: UIInteractionEvent = {\n eventId: generateId(),\n sessionId: ctx.sessionId,\n timestamp: Date.now(),\n eventType: 'ui',\n action: 'breadcrumb',\n target: 'manual',\n text: message,\n ...(data && { data }),\n };\n ctx.emit(event);\n}\n"],"mappings":"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","names":[]}
|
package/package.json
CHANGED