UNPKG

vite-plugin-component-instrumentation

Version:

A professional Vite plugin that automatically adds identifying data attributes to React components for debugging, testing, and analytics

1 lines 41.2 kB
{"version":3,"file":"index.mjs","sources":["../src/index.ts"],"sourcesContent":["import { parse } from \"@babel/parser\";\nimport MagicString from \"magic-string\";\nimport path from \"path\";\nimport { walk } from \"estree-walker\";\n\nimport type { Plugin } from \"vite\";\n\n/**\n * Runtime tracking mode\n */\nexport type TrackStateMode = 'off' | 'events' | 'summary';\n\n/**\n * Configuration options for the component instrumentation plugin\n */\nexport interface ComponentInstrumentationOptions {\n /**\n * Prefix for data attributes\n * @default 'data-ct'\n */\n attributePrefix?: string;\n\n /**\n * File extensions to process\n * @default ['.jsx', '.tsx']\n */\n extensions?: string[];\n\n /**\n * Whether to enable the plugin in production builds\n * @default false\n */\n enableInProduction?: boolean;\n\n /**\n * Patterns to exclude from processing\n * @default ['node_modules']\n */\n excludePatterns?: string[];\n\n /**\n * Whether to include the tag name in attributes\n * @default true\n */\n includeTagName?: boolean;\n\n /**\n * Custom ID generator function\n */\n customIdGenerator?: (fileRelative: string, loc: { line: number; column: number }) => string;\n\n /**\n * Whether to enable debug logging\n * @default false\n */\n debug?: boolean;\n\n /**\n * Dev-only: runtime state tracking mode\n * - 'events': batched CustomEvents with minimal info\n * - 'summary': writes redacted summaries to DOM attributes\n * - 'off': disabled\n * @default 'off'\n */\n trackState?: TrackStateMode;\n\n /** Explicit allowlist of state keys to expose values for */\n allowKeys?: string[];\n\n /** Max attribute length for summaries (default 160) */\n maxAttrLength?: number;\n\n /** Throttle interval for runtime updates in ms (default 120) */\n throttleMs?: number;\n\n /** Show full object contents in dev mode instead of redacted summaries (default false) */\n showFullObjects?: boolean;\n}\n\n/**\n * Default configuration\n */\nconst DEFAULT_OPTIONS: Required<ComponentInstrumentationOptions> = {\n attributePrefix: 'data-ct',\n extensions: ['.jsx', '.tsx'],\n enableInProduction: false,\n excludePatterns: ['node_modules'],\n includeTagName: true,\n customIdGenerator: (fileRelative, loc) => `${fileRelative}:${loc.line}:${loc.column}`,\n debug: false,\n trackState: 'off',\n allowKeys: [],\n maxAttrLength: 160,\n throttleMs: 120,\n showFullObjects: false,\n};\n\n/**\n * Exported function for testing state summarization logic\n */\nexport function buildSummaryDev(state: any, config: {\n allowKeys?: string[];\n maxAttrLength?: number;\n showFullObjects?: boolean;\n}): string {\n if (state == null) return '';\n if (typeof state !== 'object') return String(state);\n\n const showFull = config.showFullObjects || false;\n const maxAttr = config.maxAttrLength || 160;\n const allowSet = new Set(config.allowKeys || []);\n\n // Security filtering\n const SENSITIVE_KEYS = /(password|passwd|pwd|token|secret|key|auth|bearer|session|cookie|ssid|ssn|credit|card|cvv|pin|otp)/i;\n const BAD_KEYS = showFull ? SENSITIVE_KEYS : /(token|pass|secret|auth|email|cookie|session|ssid|ssn|phone|address|credit|card|api[-_]?key|bearer)/i;\n\n function isPrim(v: any): boolean {\n const t = typeof v;\n return v == null || t === 'boolean' || t === 'number' || (t === 'string' && v.length <= 32);\n }\n\n function summarize(v: any, showFullNested: boolean): string {\n const t = typeof v;\n if (v == null || t === 'boolean' || t === 'number') return String(v);\n if (t === 'string') {\n if (showFullNested) return JSON.stringify(v);\n if (v.length <= 32) return v; // Don't quote short strings at top level\n return 'str:' + v.length;\n }\n if (Array.isArray(v)) {\n if (showFullNested && v.length <= 5) {\n const items = v.map(item => summarize(item, false));\n return '[' + items.join(',') + ']';\n }\n return 'arr:' + v.length + 'items';\n }\n if (t === 'object') {\n const allKeys = Object.keys(v || {});\n const safeKeys = allKeys.filter(k => !BAD_KEYS.test(k));\n\n if (showFullNested && safeKeys.length <= 8) {\n const pairs = safeKeys.map(k => {\n const val = v[k];\n const valStr = summarize(val, true); // Pass true for nested objects\n return k + ':' + valStr;\n });\n\n const filteredCount = allKeys.length - safeKeys.length;\n if (filteredCount > 0) {\n pairs.push('...' + filteredCount + 'hidden');\n }\n\n return '{' + pairs.join(',') + '}';\n }\n return 'obj:' + safeKeys.length + 'keys' + (allKeys.length > safeKeys.length ? '+hidden' : '');\n }\n return t;\n }\n\n const out: string[] = [];\n let count = 0;\n let truncated = false;\n const keys = Object.keys(state);\n\n for (const k of keys) {\n const v = state[k];\n\n // Skip only truly sensitive keys (unless explicitly allowed)\n if (BAD_KEYS.test(k) && !allowSet.has(k)) {\n continue;\n }\n\n let val: string;\n if (allowSet.has(k)) {\n // Always show allowed keys in full if requested\n val = showFull ? summarize(v, true) : (isPrim(v) ? String(v) : summarize(v, false));\n } else if (isPrim(v)) {\n val = String(v);\n } else {\n val = summarize(v, showFull);\n }\n\n out.push(k + '=' + val);\n count++;\n\n // Check length more frequently when showing full objects\n const currentStr = out.join(',');\n if (currentStr.length > maxAttr) {\n // Try to fit by removing the last item and mark truncated\n out.pop();\n truncated = true;\n break;\n }\n if (count >= 12) break;\n }\n\n let s = out.join(',');\n if (s.length > maxAttr) {\n // Truncate and add ellipsis\n return s.slice(0, maxAttr - 3) + '...';\n }\n if (truncated) {\n // We dropped items; indicate truncation while respecting limit\n if (s.length + 3 > maxAttr) return s.slice(0, maxAttr - 3) + '...';\n return s + '...';\n }\n return s;\n}\n\n/**\n * Dynamically calculates the correct line number by reading the original source file\n * This eliminates the need for magic number offsets and provides 100% accuracy\n */\nasync function calculateAccurateLineNumber(filePath: string, astLine: number, node: any): Promise<number> {\n try {\n // Use ES module file reading instead of CommonJS require\n const { readFileSync, existsSync } = await import('fs');\n const { resolve } = await import('path');\n \n // Convert the file path to an absolute path\n const absolutePath = resolve(process.cwd(), filePath);\n \n if (!existsSync(absolutePath)) {\n return astLine;\n }\n \n const originalSource = readFileSync(absolutePath, 'utf8');\n const lines = originalSource.split('\\n');\n \n // Strategy 1: Look for the exact JSX tag in the original source\n const tagName = node.name?.name;\n if (tagName) {\n // Search through the entire original source to find the JSX tag\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n // Look for the JSX opening tag\n if (line.includes(`<${tagName}`) || line.includes(`<${tagName} `)) {\n return i + 1; // Convert to 1-based indexing\n }\n }\n }\n \n // Strategy 2: Look for the return statement that contains this JSX\n // Find the function/component that contains this JSX element\n let functionStart = -1;\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n if (line.includes('function') || line.includes('=>') || line.includes('class')) {\n functionStart = i;\n break;\n }\n }\n \n if (functionStart !== -1) {\n // Look for the return statement within this function\n for (let i = functionStart; i < lines.length; i++) {\n const line = lines[i];\n if (line.includes('return') && line.includes('(')) {\n // This is the return statement - the JSX should be on the next line or close\n return i + 1;\n }\n }\n }\n \n // Strategy 3: Look for JSX patterns in the original source\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n if (line.includes('<') && line.includes('>')) {\n return i + 1;\n }\n }\n \n } catch (error) {\n // Silently fallback to AST line number\n }\n \n // Fallback: if all else fails, use the AST line\n return astLine;\n}\n\n// Shared runtime base for both events and summary modes\nconst STATE_RUNTIME_BASE = `\n // Shared utilities and hook management\n var HOOK_NAME_CACHE = typeof WeakMap === 'function' ? new WeakMap() : null;\n var LAST_SUMMARY_CACHE = typeof WeakMap === 'function' ? new WeakMap() : null;\n var LAST_UPDATE_CACHE = typeof WeakMap === 'function' ? new WeakMap() : null;\n\n function isHost(f) {\n return f && (f.tag === 5 || f.tag === 6) && f.stateNode instanceof Element;\n }\n\n function findHostNode(fiber) {\n var f = fiber;\n while (f && !isHost(f)) f = f.child || f.sibling;\n if (isHost(f)) return f.stateNode;\n f = fiber;\n while (f && !isHost(f)) f = f.return;\n return isHost(f) ? f.stateNode : null;\n }\n\n function walk(fiber, visit) {\n try { visit(fiber); } catch(e) {}\n var child = fiber.child;\n while (child) { walk(child, visit); child = child.sibling; }\n }\n\n function setupHookPatch(onCommitHandler) {\n var hook = window.__REACT_DEVTOOLS_GLOBAL_HOOK__;\n if (!hook) {\n hook = window.__REACT_DEVTOOLS_GLOBAL_HOOK__ = {\n renderers: new Map(),\n supportsFiber: true,\n inject: function(renderer) {\n var id = Math.floor(Math.random() * 1e9);\n this.renderers.set(id, renderer);\n return id;\n }\n };\n }\n\n var prev = typeof hook.onCommitFiberRoot === 'function' ? hook.onCommitFiberRoot.bind(hook) : null;\n hook.onCommitFiberRoot = function(rendererID, root) {\n var rest = Array.prototype.slice.call(arguments, 2);\n try {\n var current = root && root.current;\n if (current) {\n onCommitHandler(current);\n }\n } catch(e) {\n console.warn('[component-instrumentation] Error in commit processing:', e);\n }\n return prev ? prev.apply(this, [rendererID, root].concat(rest)) : undefined;\n };\n }\n\n function createScheduler(cfg, flushFn) {\n var pending = [];\n var scheduled = false;\n var throttleMs = (cfg && cfg.throttleMs) || 120;\n\n function scheduleFlush() {\n if (scheduled) return;\n scheduled = true;\n var scheduler = window.requestIdleCallback || function(cb) { return setTimeout(cb, throttleMs); };\n scheduler(flush);\n }\n\n function flush() {\n scheduled = false;\n if (!pending.length) return;\n\n var maxItems = (cfg && cfg.maxItemsPerFlush) || 200;\n var items = pending.splice(0, maxItems);\n flushFn(items);\n\n // Reschedule if more items remain\n if (pending.length > 0) {\n scheduleFlush();\n }\n }\n\n function enqueue(item) {\n pending.push(item);\n scheduleFlush();\n }\n\n return { enqueue: enqueue, flush: flush };\n }\n\n function setupMutationObserver(attrs, enqueueCallback) {\n try {\n var mo = new MutationObserver(function(recs) {\n var now = Date.now();\n for (var i = 0; i < recs.length; i++) {\n var r = recs[i];\n var nodes = [];\n\n if (r.type === 'childList') {\n if (r.addedNodes) {\n for (var j = 0; j < r.addedNodes.length; j++) {\n nodes.push(r.addedNodes[j]);\n }\n }\n nodes.push(r.target);\n } else if (r.type === 'characterData') {\n nodes.push(r.target.parentElement);\n }\n\n for (var k = 0; k < nodes.length; k++) {\n var n = nodes[k];\n var el = (n instanceof Element) ? n : (n && n.parentElement);\n var cur = el;\n\n while (cur && cur instanceof Element) {\n var id = null;\n for (var a = 0; a < attrs.length; a++) {\n var v = cur.getAttribute(attrs[a]);\n if (v) { id = v; break; }\n }\n\n if (id) {\n // Throttle updates per element\n if (!LAST_UPDATE_CACHE || !LAST_UPDATE_CACHE.get(cur) || (now - LAST_UPDATE_CACHE.get(cur)) > 50) {\n if (LAST_UPDATE_CACHE) LAST_UPDATE_CACHE.set(cur, now);\n enqueueCallback(cur, id);\n }\n break;\n }\n cur = cur.parentElement;\n }\n }\n }\n });\n\n mo.observe(document.documentElement, {\n childList: true,\n characterData: true,\n subtree: true\n });\n\n // Cleanup on unload\n try {\n window.addEventListener('unload', function() {\n try { mo.disconnect(); } catch(e) {}\n });\n } catch(e) {}\n\n return mo;\n } catch(e) {\n console.warn('[component-instrumentation] MutationObserver setup failed:', e);\n return null;\n }\n }\n`;\n\n// Dev-only browser code for state events virtual module\nconst STATE_EVENTS_SOURCE = STATE_RUNTIME_BASE + `\nexport function setupStateEvents() {\n var cfg = { throttleMs: 120, maxItemsPerFlush: 200 };\n var seen = new Set();\n\n function flushEvents(items) {\n if (items.length === 0) return;\n window.dispatchEvent(new CustomEvent('ct:state', { detail: { ts: Date.now(), items: items } }));\n }\n\n var scheduler = createScheduler(cfg, flushEvents);\n\n function handleCommit(current) {\n walk(current, function(fiber) {\n var node = findHostNode(fiber);\n if (!node) return;\n var id = node.getAttribute && (node.getAttribute('data-ct-id') || node.getAttribute('data-debug-id'));\n if (!id) return;\n var name = node.getAttribute('data-ct-name') || node.getAttribute('data-debug-name');\n scheduler.enqueue({ id: id, name: name || undefined });\n });\n }\n\n setupHookPatch(handleCommit);\n\n var ATTRS = ['data-ct-id', 'data-debug-id'];\n setupMutationObserver(ATTRS, function(element, id) {\n if (!seen.has(id)) {\n seen.add(id);\n var name = element.getAttribute('data-ct-name') || element.getAttribute('data-debug-name');\n scheduler.enqueue({ id: id, name: name || undefined });\n }\n });\n}`;\n\n\n// Dev-only browser code for summary runtime virtual module\nconst STATE_SUMMARY_SOURCE = STATE_RUNTIME_BASE + `\nexport function setupStateSummary(cfg){\n var MAX_ATTR = (cfg && cfg.maxAttrLength) || 160;\n var ALLOW = new Set((cfg && cfg.allowKeys) || []);\n var SHOW_FULL = (cfg && cfg.showFullObjects) || false;\n\n // Security filtering\n var SENSITIVE_KEYS = /(password|passwd|pwd|token|secret|key|auth|bearer|session|cookie|ssid|ssn|credit|card|cvv|pin|otp)/i;\n var BAD_KEYS = SHOW_FULL ? SENSITIVE_KEYS : /(token|pass|secret|auth|email|cookie|session|ssid|ssn|phone|address|credit|card|api[-_]?key|bearer)/i;\n\n function isPrim(v){ var t=typeof v; return v==null || t==='boolean' || t==='number' || (t==='string' && v.length<=32); }\n\n function summarize(v, showFullNested){\n var t = typeof v;\n if (v==null || t==='boolean' || t==='number') return String(v);\n if (t==='string') {\n if (showFullNested || v.length <= 32) return JSON.stringify(v);\n return 'str:'+v.length;\n }\n if (Array.isArray(v)) {\n if (showFullNested && v.length <= 5) {\n var items = [];\n for (var i = 0; i < v.length; i++) {\n items.push(summarize(v[i], false));\n }\n return '[' + items.join(',') + ']';\n }\n return 'arr:' + v.length + 'items';\n }\n if (t==='object') {\n var allKeys = Object.keys(v||{});\n var safeKeys = allKeys.filter(function(k){ return !BAD_KEYS.test(k); });\n\n if (showFullNested && safeKeys.length <= 8) {\n var pairs = [];\n for (var j = 0; j < safeKeys.length; j++) {\n var k = safeKeys[j];\n var val = v[k];\n var valStr = summarize(val, false);\n pairs.push(k + ':' + valStr);\n }\n\n var filteredCount = allKeys.length - safeKeys.length;\n if (filteredCount > 0) {\n pairs.push('...' + filteredCount + 'hidden');\n }\n\n return '{' + pairs.join(',') + '}';\n }\n return 'obj:' + safeKeys.length + 'keys' + (allKeys.length > safeKeys.length ? '+hidden' : '');\n }\n return t;\n }\n\n function buildSummary(state){\n if (state==null) return '';\n if (typeof state!=='object') return String(state);\n\n var out = [];\n var count = 0;\n var keys = Object.keys(state);\n\n for (var i=0;i<keys.length;i++){\n var k = keys[i];\n var v = state[k];\n var val;\n\n // Skip only truly sensitive keys (unless explicitly allowed)\n if (BAD_KEYS.test(k) && !ALLOW.has(k)) {\n continue;\n }\n\n if (ALLOW.has(k)) {\n // Always show allowed keys in full if requested\n val = SHOW_FULL ? summarize(v, true) : (isPrim(v) ? v : summarize(v, false));\n } else if (isPrim(v)) {\n val = v;\n } else {\n val = summarize(v, SHOW_FULL);\n }\n\n out.push(k+'='+String(val));\n count++;\n\n // Check length more frequently when showing full objects\n var currentStr = out.join(',');\n if (currentStr.length > MAX_ATTR) {\n // Try to fit by removing the last item and truncating\n out.pop();\n break;\n }\n if (count>=12) break;\n }\n\n var s = out.join(',');\n return s.length>MAX_ATTR ? s.slice(0, MAX_ATTR-3) + '...' : s;\n }\n\n function flushSummaries(items) {\n console.log('[component-instrumentation] Flushing', items.length, 'state summaries');\n for (var i = 0; i < items.length; i++) {\n var it = items[i];\n try {\n var attrName = (cfg && cfg.attrName) || 'data-ct-state';\n\n // Skip no-op updates using WeakMap cache\n if (LAST_SUMMARY_CACHE && LAST_SUMMARY_CACHE.get(it.node) === it.summary) {\n continue;\n }\n\n it.node.setAttribute(attrName, it.summary);\n if (LAST_SUMMARY_CACHE) LAST_SUMMARY_CACHE.set(it.node, it.summary);\n console.log('[component-instrumentation] Set', attrName + '=\"' + it.summary + '\"', 'on', it.node);\n } catch(e) {\n console.warn('[component-instrumentation] Failed to set attribute:', e);\n }\n }\n }\n\n var scheduler = createScheduler(cfg, flushSummaries);\n\n function enqueue(node, state) {\n var summary = buildSummary(state);\n if (!summary) return;\n scheduler.enqueue({ node: node, summary: summary });\n console.log('[component-instrumentation] Enqueued state summary:', summary, 'for node:', node);\n }\n\n function fiberState(fiber){\n try {\n if (!fiber) return null;\n\n // Try to extract real variable names using React DevTools/Refresh techniques\n var realNames = extractHookNames(fiber);\n\n // For function components, memoizedState is the hooks chain\n if (fiber.memoizedState && typeof fiber.memoizedState === 'object') {\n var state = {};\n var hook = fiber.memoizedState;\n var index = 0;\n while (hook && index < 10) { // Limit to prevent infinite loops\n if (hook.memoizedState !== undefined) {\n var keyName = realNames[index] || ('state' + index);\n state[keyName] = hook.memoizedState;\n }\n hook = hook.next;\n index++;\n }\n return Object.keys(state).length > 0 ? state : null;\n }\n return null;\n } catch(e){ return null; }\n }\n\n function extractHookNames(fiber) {\n // Use WeakMap cache to avoid repeated parsing\n if (HOOK_NAME_CACHE && fiber.type && HOOK_NAME_CACHE.has(fiber.type)) {\n return HOOK_NAME_CACHE.get(fiber.type);\n }\n\n var names = {};\n try {\n // Method 1: Check React Refresh signature (most reliable)\n if (fiber.type && fiber.type._signature) {\n var sig = fiber.type._signature;\n if (sig.getCustomHooks) {\n var hooks = sig.getCustomHooks();\n if (hooks && hooks.length > 0) {\n for (var i = 0; i < hooks.length; i++) {\n var hookInfo = hooks[i];\n if (hookInfo && hookInfo.key) {\n // Parse \"useState{[count, setCount]}(0)\" format\n var match = hookInfo.key.match(/^([^{]+)\\\\{\\\\[([^,]+)/);\n if (match && match[2]) {\n names[i] = match[2].trim();\n }\n }\n }\n }\n }\n }\n\n // Method 2: Parse component source if available (only when showFullObjects is enabled)\n if (SHOW_FULL && fiber.type && fiber.type.toString) {\n var source = fiber.type.toString();\n var hookMatches = source.match(/const\\\\s*\\\\[\\\\s*([^,\\\\]]+)/g);\n if (hookMatches) {\n for (var j = 0; j < hookMatches.length && j < 5; j++) {\n var varMatch = hookMatches[j].match(/const\\\\s*\\\\[\\\\s*([^,\\\\]]+)/);\n if (varMatch && varMatch[1]) {\n names[j] = names[j] || varMatch[1].trim();\n }\n }\n }\n }\n\n // Method 3: Fallback to smart naming\n var componentName = (fiber.type && fiber.type.name) || '';\n if (componentName === 'Counter') names[0] = names[0] || 'count';\n if (componentName === 'Form') names[0] = names[0] || 'formData';\n\n } catch(e) {\n console.warn('[component-instrumentation] Hook name extraction failed:', e);\n }\n\n // Cache the result\n if (HOOK_NAME_CACHE && fiber.type) {\n HOOK_NAME_CACHE.set(fiber.type, names);\n }\n\n return names;\n }\n\n function handleCommit(current) {\n walk(current, function(fiber) {\n // Only process function components with hooks\n if (fiber.tag !== 0 && fiber.tag !== 1) return; // 0=FunctionComponent, 1=ClassComponent\n\n var node = findHostNode(fiber);\n if (!node) return;\n var hasId = node.getAttribute && (node.getAttribute('data-ct-id') || node.getAttribute('data-debug-id'));\n if (!hasId) return;\n\n var st = fiberState(fiber);\n if (st) enqueue(node, st);\n });\n }\n\n setupHookPatch(handleCommit);\n\n var ATTRS = ['data-ct-id', 'data-debug-id'];\n setupMutationObserver(ATTRS, function(element, id) {\n // Create a simple state placeholder for MutationObserver updates\n enqueue(element, { updated: Date.now() });\n });\n\n console.log('[component-instrumentation] MutationObserver fallback active');\n}`;\n\n\n\n/**\n * Creates a Vite plugin that provides comprehensive React component instrumentation\n * for debugging, testing, analytics, and observability\n */\nexport default function componentInstrumentation(userOptions: ComponentInstrumentationOptions = {}): Plugin {\n const options = { ...DEFAULT_OPTIONS, ...userOptions };\n const validExtensions = new Set(options.extensions);\n\n const log = options.debug\n ? (message: string, ...args: any[]) => console.log(`[component-instrumentation] ${message}`, ...args)\n : () => {};\n\n return {\n name: 'vite-plugin-component-instrumentation',\n apply: options.enableInProduction ? 'build' : 'serve',\n enforce: 'pre',\n\n resolveId(id) {\n if (options.trackState !== 'off') {\n if (\n id === '/__ct_state_events__' || id === '/__ct_state_events_code__' || id === '/__ct_state_events__.js' || id === '/__ct_state_events_code__.js' ||\n id === '/__ct_state_summary__' || id === '/__ct_state_summary_code__' || id === '/__ct_state_summary__.js' || id === '/__ct_state_summary_code__.js'\n ) return id;\n }\n return null;\n },\n\n load(id) {\n if (options.trackState === 'events' && (id === '/__ct_state_events__' || id === '/__ct_state_events__.js')) {\n return `import { setupStateEvents } from '/__ct_state_events_code__.js';\\nsetupStateEvents();`;\n }\n if (options.trackState === 'events' && (id === '/__ct_state_events_code__' || id === '/__ct_state_events_code__.js')) {\n return STATE_EVENTS_SOURCE;\n }\n if (options.trackState === 'summary' && (id === '/__ct_state_summary__' || id === '/__ct_state_summary__.js')) {\n const cfg = { allowKeys: options.allowKeys, maxAttrLength: options.maxAttrLength, throttleMs: options.throttleMs, attrName: `${options.attributePrefix}-state`, showFullObjects: options.showFullObjects };\n return `import { setupStateSummary } from '/__ct_state_summary_code__.js';\\nsetupStateSummary(${JSON.stringify(cfg)});`;\n }\n if (options.trackState === 'summary' && (id === '/__ct_state_summary_code__' || id === '/__ct_state_summary_code__.js')) {\n return STATE_SUMMARY_SOURCE;\n }\n return null;\n },\n\n // Use Vite's HTML transform to inject runtime early\n transformIndexHtml(html: string) {\n if (options.trackState === 'off') return null as any;\n if (options.trackState === 'events') {\n return html.replace(/<head>/i, `<head>\\n <script type=\\\"module\\\">import '/__ct_state_events__.js';</script>`);\n }\n if (options.trackState === 'summary') {\n return html.replace(/<head>/i, `<head>\\n <script type=\\\"module\\\">import '/__ct_state_summary__.js';</script>`);\n }\n return null as any;\n },\n\n async transform(code: string, id: string) {\n try {\n // Skip virtual modules - they're served as-is by the load hook\n if (id.startsWith('/__ct_state_events') || id.startsWith('/__ct_state_summary')) {\n return null;\n }\n\n // Inject dev-only state events runtime as a virtual module import in index.html\n if (options.trackState !== 'off' && /index\\.html$/.test(id)) {\n log('Injecting state-events runtime');\n const injected = code.replace(\n /<head>/i,\n `<head>\\n <script type=\\\"module\\\">import '/__ct_state_events__.js';</script>`\n );\n return { code: injected, map: null };\n }\n\n // Check if file should be processed (strip Vite query/hash)\n const cleanId = id.split('?')[0].split('#')[0];\n if (!validExtensions.has(path.extname(cleanId))) {\n return null;\n }\n\n // Check exclude patterns\n if (options.excludePatterns.some(pattern => cleanId.includes(pattern))) {\n return null;\n }\n\n log(`Processing file: ${id}`);\n\n // Parse the code into an AST\n const ast = parse(code, {\n sourceType: \"module\",\n plugins: [\"jsx\", \"typescript\"],\n });\n\n const ms = new MagicString(code);\n const fileRelative = path.relative(process.cwd(), id);\n let transformCount = 0;\n\n // Walk through the AST looking for JSX elements\n const jsxNodes: any[] = [];\n walk(ast as any, {\n enter(node: any) {\n if (node.type !== \"JSXOpeningElement\") return;\n if (node.name?.type !== \"JSXIdentifier\") return;\n \n const tagName = node.name.name;\n if (!tagName) return;\n \n // Check if already tagged\n const alreadyTagged = node.attributes?.some(\n (attr: any) =>\n attr.type === \"JSXAttribute\" &&\n attr.name?.name?.startsWith(options.attributePrefix)\n );\n \n if (!alreadyTagged) {\n jsxNodes.push(node);\n }\n }\n });\n\n // Process JSX nodes asynchronously\n for (const node of jsxNodes) {\n try {\n const tagName = node.name.name;\n \n // Get location info\n const loc = node.loc?.start;\n if (!loc) continue;\n\n // Calculate accurate line number using original source file analysis\n const correctedLine = await calculateAccurateLineNumber(id, loc.line, node);\n const correctedLoc = {\n line: correctedLine,\n column: loc.column\n };\n\n // Generate ID using custom generator or default\n const componentId = options.customIdGenerator(fileRelative, correctedLoc);\n\n // Build attributes string\n let attributesString = ` ${options.attributePrefix}-id=\"${componentId}\"`;\n if (options.includeTagName) {\n attributesString += ` ${options.attributePrefix}-name=\"${tagName}\"`;\n }\n\n // Insert attributes after the tag name\n if (node.name.end != null) {\n ms.appendLeft(node.name.end, attributesString);\n transformCount++;\n }\n\n } catch (error) {\n console.warn(\n `[component-instrumentation] Warning: Failed to process JSX node in ${id}:`,\n error\n );\n }\n }\n\n // Return transformed code if changes were made\n if (transformCount > 0) {\n log(`Transformed ${transformCount} components in ${fileRelative}`);\n return {\n code: ms.toString(),\n map: ms.generateMap({ hires: true, source: id }),\n };\n }\n\n return null;\n\n } catch (error) {\n console.warn(\n `[component-instrumentation] Warning: Failed to transform ${id}:`,\n error\n );\n return null;\n }\n }\n };\n}"],"names":[],"mappings":"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"}