{"version":3,"sources":["../src/matchers/index.ts","../src/matchers/type-guards.ts","../src/utils/formatRenderHistory.ts","../src/matchers/async/phase.ts","../src/matchers/async/render-count.ts","../src/matchers/sync/phase.ts","../src/matchers/sync/render-count.ts","../src/registry.ts","../src/auto-setup.ts","../src/profiler/components/createOnRenderCallback.ts","../src/profiler/components/ProfiledComponent.tsx","../src/profiler/api/ProfilerAPI.ts","../src/profiler/core/ProfilerCache.ts","../src/profiler/core/ProfilerData.ts","../src/profiler/core/ProfilerStorage.ts","../src/profiler/components/withProfiler.tsx","../src/hooks/profileHook.tsx","../src/hooks/createHookProfiler.tsx","../src/utils/async.ts","../src/utils/renderProfiled.tsx","../src/index.ts"],"names":["isProfiledComponent","received","__name","getPluralEnding","number","formatRenderHistory","history","maxItems","result","phase","index","paddedPhase","moreText","formatRenderSummary","mounts","updates","nested","parts","toEventuallyReachPhase","options","validPhases","timeout","interval","startTime","resolve","phases","summary","toEventuallyRenderTimes","expected","actual","details","toEventuallyRenderAtLeast","minCount","toHaveMountedOnce","mountCount","pass","mountDetails","toHaveNeverMounted","hasMounted","toHaveOnlyMounted","hasMounts","hasUpdates","toHaveOnlyUpdated","toHaveRendered","renders","toHaveRenderedTimes","expect","ComponentRegistry","component","c","registry","afterEach","createOnRenderCallback","storage","_id","globalInstanceCounter","ProfiledComponentWrapper","props","Component","componentProps","componentName","onRender","idRef","useRef","jsx","Profiler","EMPTY_FROZEN_ARRAY","ProfilerAPI","ProfilerCache","compute","ProfilerData","p","ProfilerStorage","data","globalStorage","globalAPI","withProfiler","displayName","ProfiledComp","apiMethods","clearInternal","profileHook","hook","initialProps","hookResult","HookComponent","hookName","ProfiledHook","propsToUse","rtlRerender","unmount","render","newProps","act","createHookProfiler","rerender","waitForRenders","count","waitFor","waitForMinimumRenders","waitForPhase","renderProfiled","ProfiledComponent","currentProps","rtl","VERSION"],"mappings":"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","file":"index.cjs","sourcesContent":["import { expect } from \"vitest\";\n\nimport { toEventuallyReachPhase } from \"@/matchers/async/phase\";\n\nimport {\n  toEventuallyRenderAtLeast,\n  toEventuallyRenderTimes,\n} from \"./async/render-count\";\nimport {\n  toHaveMountedOnce,\n  toHaveNeverMounted,\n  toHaveOnlyMounted,\n  toHaveOnlyUpdated,\n} from \"./sync/phase\";\nimport { toHaveRendered, toHaveRenderedTimes } from \"./sync/render-count\";\n\n/**\n * Register all custom Vitest matchers for profiled components\n *\n * This combines:\n * -  (toHaveRendered, toHaveRenderedTimes)\n * -  (toHaveMountedOnce, toHaveNeverMounted, toHaveOnlyMounted, toHaveOnlyUpdated)\n * -  (toEventuallyRenderTimes, toEventuallyRenderAtLeast)\n * -  (toEventuallyReachPhase)\n */\nexpect.extend({\n  // Synchronous render count matchers\n  toHaveRendered,\n  toHaveRenderedTimes,\n  // Synchronous phase matchers\n  toHaveMountedOnce,\n  toHaveNeverMounted,\n  toHaveOnlyMounted,\n  toHaveOnlyUpdated,\n  // Asynchronous render count matchers\n  toEventuallyRenderTimes,\n  toEventuallyRenderAtLeast,\n  // Asynchronous phase matchers\n  toEventuallyReachPhase,\n});\n","import type { ProfiledComponent } from \"../types\";\n\n/**\n * Type guard to validate that a value is a profiled component\n */\nexport function isProfiledComponent(\n  received: unknown,\n): received is ProfiledComponent<unknown> {\n  return (\n    received !== null &&\n    typeof received === \"function\" &&\n    \"getRenderCount\" in received &&\n    \"getRenderHistory\" in received &&\n    \"getLastRender\" in received\n  );\n}\n","import type { PhaseType } from \"../types\";\n\nconst getPluralEnding = (number: number): string => {\n  return number === 1 ? \"\" : \"s\";\n};\n\n/**\n * Formats render history into a human-readable string for error messages\n *\n * @param history - Array of render phases\n * @param maxItems - Maximum number of items to display (default: 10)\n * @returns Formatted string with render details\n *\n * @example\n * ```typescript\n * const history = component.getRenderHistory();\n * const formatted = formatRenderHistory(history);\n * // Output:\n * //   #1 [mount        phase]\n * //   #2 [update       phase]\n * //   💡 Tip: Use Component.getRenderHistory() to inspect all render details\n * ```\n */\nexport function formatRenderHistory(\n  history: readonly PhaseType[],\n  maxItems = 10,\n): string {\n  if (history.length === 0) {\n    return \"No renders\";\n  }\n\n  const items = history.slice(0, maxItems).map((phase, index) => {\n    // Format phase with padding for alignment\n    const paddedPhase = phase.padEnd(12);\n\n    return `  #${index + 1} [${paddedPhase} phase]`;\n  });\n\n  const result = items.join(\"\\n\");\n\n  // Add \"and X more\" indicator if there are more items\n  const hasMore = history.length > maxItems;\n  const moreText = hasMore\n    ? `\\n  ... and ${history.length - maxItems} more`\n    : \"\";\n\n  // Add helpful tip at the end\n  const tip =\n    \"\\n\\n  💡 Tip: Use Component.getRenderHistory() to inspect all render details\";\n\n  return result + moreText + tip;\n}\n\n/**\n * Formats a short summary of render statistics\n *\n * @param history - Array of render phases\n * @returns Brief statistics summary\n *\n * @example\n * ```typescript\n * const summary = formatRenderSummary(history);\n * // \"3 renders (1 mount, 2 updates)\"\n * ```\n */\nexport function formatRenderSummary(history: readonly PhaseType[]): string {\n  if (history.length === 0) {\n    return \"0 renders\";\n  }\n\n  const mounts = history.filter((phase) => phase === \"mount\").length;\n  const updates = history.filter((phase) => phase === \"update\").length;\n  const nested = history.filter((phase) => phase === \"nested-update\").length;\n\n  const parts: string[] = [];\n\n  if (mounts > 0) {\n    parts.push(`${mounts} mount${getPluralEnding(mounts)}`);\n  }\n  if (updates > 0) {\n    parts.push(`${updates} update${getPluralEnding(updates)}`);\n  }\n  if (nested > 0) {\n    parts.push(`${nested} nested update${getPluralEnding(nested)}`);\n  }\n\n  return `${history.length} render${getPluralEnding(history.length)} (${parts.join(\", \")})`;\n}\n","import { isProfiledComponent } from \"@/matchers/type-guards\";\nimport { formatRenderSummary } from \"@/utils/formatRenderHistory\";\n\nimport type { WaitOptions, MatcherResult } from \"@/matchers/types\";\nimport type { PhaseType } from \"@/types\";\n\n/**\n * Assert that component eventually reaches specific render phase (async)\n *\n * @param received - The component to check (must be created with withProfiler)\n * @param phase - Expected render phase ('mount', 'update', or 'nested-update')\n * @param options - Wait options\n * @returns Promise with matcher result\n * @example\n * await expect(ProfiledComponent).toEventuallyReachPhase('update')\n * await expect(ProfiledComponent).toEventuallyReachPhase('mount', { timeout: 2000 })\n */\nexport async function toEventuallyReachPhase(\n  received: unknown,\n  phase: PhaseType,\n  options?: WaitOptions,\n): Promise<MatcherResult> {\n  if (!isProfiledComponent(received)) {\n    return {\n      pass: false,\n      message: () =>\n        `Expected a profiled component created with withProfiler(), received ${typeof received}`,\n    };\n  }\n\n  const validPhases = [\"mount\", \"update\", \"nested-update\"];\n\n  if (!validPhases.includes(phase)) {\n    return {\n      pass: false,\n      message: () =>\n        `Phase must be one of: ${validPhases.join(\", \")}, received ${phase}`,\n    };\n  }\n\n  const { timeout = 1000, interval = 50 } = options ?? {};\n  const startTime = Date.now();\n\n  while (Date.now() - startTime < timeout) {\n    const history = received.getRenderHistory();\n    const hasPhase = history.includes(phase);\n\n    if (hasPhase) {\n      return {\n        pass: true,\n        message: () =>\n          `Expected component not to eventually reach phase \"${phase}\" within ${timeout}ms, but it did`,\n      };\n    }\n\n    await new Promise((resolve) => setTimeout(resolve, interval));\n  }\n\n  const history = received.getRenderHistory();\n  const phases = history.join(\", \");\n  const summary = formatRenderSummary(history);\n\n  return {\n    pass: false,\n    message: () =>\n      `Expected component to eventually reach phase \"${phase}\" within ${timeout}ms, but it didn't (${summary}).\\n\\nCurrent phases: [${phases}]`,\n  };\n}\n","import { isProfiledComponent } from \"@/matchers/type-guards\";\nimport {\n  formatRenderHistory,\n  formatRenderSummary,\n} from \"@/utils/formatRenderHistory\";\n\nimport type { WaitOptions, MatcherResult } from \"@/matchers/types\";\n\n/**\n * Assert that component eventually renders exact number of times (async)\n *\n * @param received - The component to check (must be created with withProfiler)\n * @param expected - Expected number of renders\n * @param options - Wait options\n * @returns Promise with matcher result\n * @example\n * await expect(ProfiledComponent).toEventuallyRenderTimes(3)\n * await expect(ProfiledComponent).toEventuallyRenderTimes(5, { timeout: 2000 })\n */\nexport async function toEventuallyRenderTimes(\n  received: unknown,\n  expected: number,\n  options?: WaitOptions,\n): Promise<MatcherResult> {\n  if (!isProfiledComponent(received)) {\n    return {\n      pass: false,\n      message: () =>\n        `Expected a profiled component created with withProfiler(), received ${typeof received}`,\n    };\n  }\n\n  if (!Number.isInteger(expected) || expected < 0) {\n    return {\n      pass: false,\n      message: () =>\n        `Expected render count must be a non-negative integer, received ${expected}`,\n    };\n  }\n\n  const { timeout = 1000, interval = 50 } = options ?? {};\n  const startTime = Date.now();\n\n  while (Date.now() - startTime < timeout) {\n    const actual = received.getRenderCount();\n\n    if (actual === expected) {\n      return {\n        pass: true,\n        message: () =>\n          `Expected component not to eventually render ${expected} times within ${timeout}ms, but it did`,\n        actual,\n        expected,\n      };\n    }\n\n    await new Promise((resolve) => setTimeout(resolve, interval));\n  }\n\n  const actual = received.getRenderCount();\n  const history = received.getRenderHistory();\n  const summary = formatRenderSummary(history);\n  const details = formatRenderHistory(history, 10);\n\n  return {\n    pass: false,\n    message: () =>\n      `Expected component to eventually render ${expected} times within ${timeout}ms, but got ${actual} (${summary})\\n\\n${details}`,\n    actual,\n    expected,\n  };\n}\n\n/**\n * Assert that component eventually renders at least N times (async)\n *\n * @param received - The component to check (must be created with withProfiler)\n * @param minCount - Minimum expected number of renders\n * @param options - Wait options\n * @returns Promise with matcher result\n * @example\n * await expect(ProfiledComponent).toEventuallyRenderAtLeast(2)\n * await expect(ProfiledComponent).toEventuallyRenderAtLeast(3, { timeout: 2000 })\n */\nexport async function toEventuallyRenderAtLeast(\n  received: unknown,\n  minCount: number,\n  options?: WaitOptions,\n): Promise<MatcherResult> {\n  if (!isProfiledComponent(received)) {\n    return {\n      pass: false,\n      message: () =>\n        `Expected a profiled component created with withProfiler(), received ${typeof received}`,\n    };\n  }\n\n  if (!Number.isInteger(minCount) || minCount < 0) {\n    return {\n      pass: false,\n      message: () =>\n        `Minimum render count must be a non-negative integer, received ${minCount}`,\n    };\n  }\n\n  const { timeout = 1000, interval = 50 } = options ?? {};\n  const startTime = Date.now();\n\n  while (Date.now() - startTime < timeout) {\n    const actual = received.getRenderCount();\n\n    if (actual >= minCount) {\n      return {\n        pass: true,\n        message: () =>\n          `Expected component not to eventually render at least ${minCount} times within ${timeout}ms, but it rendered ${actual} times`,\n        actual,\n        expected: minCount,\n      };\n    }\n\n    await new Promise((resolve) => setTimeout(resolve, interval));\n  }\n\n  const actual = received.getRenderCount();\n  const history = received.getRenderHistory();\n  const summary = formatRenderSummary(history);\n  const details = formatRenderHistory(history, 10);\n\n  return {\n    pass: false,\n    message: () =>\n      `Expected component to eventually render at least ${minCount} times within ${timeout}ms, but got ${actual} (${summary})\\n\\n${details}`,\n    actual,\n    expected: minCount,\n  };\n}\n","import { isProfiledComponent } from \"@/matchers/type-guards\";\nimport { formatRenderHistory } from \"@/utils/formatRenderHistory\";\n\nimport type { MatcherResult } from \"@/matchers/types\";\n\n/**\n * Assert that component mounted exactly once\n *\n * @param received - The component to check\n * @returns Matcher result\n * @example\n * expect(ProfiledComponent).toHaveMountedOnce()\n */\nexport function toHaveMountedOnce(received: unknown): MatcherResult {\n  if (!isProfiledComponent(received)) {\n    return {\n      pass: false,\n      message: () =>\n        `Expected a profiled component created with withProfiler(), received ${typeof received}`,\n    };\n  }\n\n  const mounts = received.getRendersByPhase(\"mount\");\n  const mountCount = mounts.length;\n  const pass = mountCount === 1;\n\n  return {\n    pass,\n    message: () => {\n      if (mountCount === 0) {\n        return `Expected component to mount once, but it never mounted`;\n      }\n      if (pass) {\n        return `Expected component not to mount, but it mounted once`;\n      }\n\n      // Show all mount renders\n      const mountDetails = formatRenderHistory(mounts, 10);\n\n      return `Expected component to mount once, but it mounted ${mountCount} times\\n\\nMount renders:\\n${mountDetails}`;\n    },\n    actual: mountCount,\n    expected: 1,\n  };\n}\n\n/**\n * Assert that component never mounted\n *\n * @param received - The component to check\n * @returns Matcher result\n * @example\n * expect(ProfiledComponent).toHaveNeverMounted()\n */\nexport function toHaveNeverMounted(received: unknown): MatcherResult {\n  if (!isProfiledComponent(received)) {\n    return {\n      pass: false,\n      message: () =>\n        `Expected a profiled component created with withProfiler(), received ${typeof received}`,\n    };\n  }\n\n  const hasMounted = received.hasMounted();\n\n  return {\n    pass: !hasMounted,\n    message: () =>\n      hasMounted\n        ? `Expected component never to mount, but it mounted`\n        : `Expected component to mount, but it never did`,\n  };\n}\n\n/**\n * Assert that component only mounted (never updated in current test)\n *\n * @param received - The component to check\n * @returns Matcher result\n * @example\n * expect(ProfiledComponent).toHaveOnlyMounted()\n */\nexport function toHaveOnlyMounted(received: unknown): MatcherResult {\n  if (!isProfiledComponent(received)) {\n    return {\n      pass: false,\n      message: () =>\n        `Expected a profiled component created with withProfiler(), received ${typeof received}`,\n    };\n  }\n\n  const history = received.getRenderHistory();\n  const hasMounts = history.includes(\"mount\");\n  const hasUpdates = history.includes(\"update\");\n  const pass = hasMounts && !hasUpdates;\n\n  return {\n    pass,\n    message: () => {\n      if (history.length === 0) {\n        return `Expected component to have only mounts, but it never rendered`;\n      }\n      if (hasMounts && hasUpdates) {\n        return `Expected component to have only mounts, but it also updated`;\n      }\n      if (!hasMounts && hasUpdates) {\n        return `Expected component to have only mounts, but it only updated`;\n      }\n\n      return `Expected component not to have only mounts, but it did`;\n    },\n  };\n}\n\n/**\n * Assert that component only updated (never mounted in current test)\n *\n * @param received - The component to check\n * @returns Matcher result\n * @example\n * expect(ProfiledComponent).toHaveOnlyUpdated()\n */\nexport function toHaveOnlyUpdated(received: unknown): MatcherResult {\n  if (!isProfiledComponent(received)) {\n    return {\n      pass: false,\n      message: () =>\n        `Expected a profiled component created with withProfiler(), received ${typeof received}`,\n    };\n  }\n\n  const history = received.getRenderHistory();\n  const hasMounts = history.includes(\"mount\");\n  const hasUpdates = history.includes(\"update\");\n  const pass = !hasMounts && hasUpdates;\n\n  return {\n    pass,\n    message: () => {\n      if (history.length === 0) {\n        return `Expected component to have only updates, but it never rendered`;\n      }\n      if (hasMounts && hasUpdates) {\n        return `Expected component to have only updates, but it also mounted`;\n      }\n      if (hasMounts && !hasUpdates) {\n        return `Expected component to have only updates, but it only mounted`;\n      }\n\n      return `Expected component not to have only updates, but it did`;\n    },\n  };\n}\n","import { isProfiledComponent } from \"@/matchers/type-guards\";\nimport {\n  formatRenderHistory,\n  formatRenderSummary,\n} from \"@/utils/formatRenderHistory\";\n\nimport type { MatcherResult } from \"@/matchers/types\";\n\n/**\n * Assert that component has rendered at least once\n *\n * @param received - The component to check\n * @returns Matcher result\n * @example\n * expect(ProfiledComponent).toHaveRendered()\n */\nexport function toHaveRendered(received: unknown): MatcherResult {\n  if (!isProfiledComponent(received)) {\n    return {\n      pass: false,\n      message: () =>\n        `Expected a profiled component created with withProfiler(), received ${typeof received}`,\n    };\n  }\n\n  const renders = received.getRenderCount();\n\n  return {\n    pass: renders > 0,\n    message: () =>\n      renders > 0\n        ? `Expected component not to render, but it rendered ${renders} time(s)`\n        : `Expected component to render at least once, but it never rendered`,\n  };\n}\n\n/**\n * Assert exact number of renders\n *\n * @param received - The component to check (must be created with withProfiler)\n * @param expected - Expected number of renders\n * @returns Matcher result\n * @example\n * expect(ProfiledComponent).toHaveRenderedTimes(3)\n */\nexport function toHaveRenderedTimes(\n  received: unknown,\n  expected: number,\n): MatcherResult {\n  if (!isProfiledComponent(received)) {\n    return {\n      pass: false,\n      message: () =>\n        `Expected a profiled component created with withProfiler(), received ${typeof received}`,\n    };\n  }\n\n  if (!Number.isInteger(expected) || expected < 0) {\n    return {\n      pass: false,\n      message: () =>\n        `Expected render count must be a non-negative integer, received ${expected}`,\n    };\n  }\n\n  const actual = received.getRenderCount();\n  const pass = actual === expected;\n\n  return {\n    message: () => {\n      if (pass) {\n        return `Expected component not to render ${expected} time(s), but it did`;\n      }\n\n      // Show detailed render history on failure\n      const history = received.getRenderHistory();\n      const summary = formatRenderSummary(history);\n      const details = formatRenderHistory(history, 10);\n\n      return `Expected ${expected} renders, but got ${actual} (${summary})\\n\\n${details}`;\n    },\n    pass,\n    actual,\n    expected,\n  };\n}\n","/**\n * Internal registry of all profiled components\n * Automatically cleared between tests via auto-setup\n *\n * Uses WeakSet for automatic garbage collection of components\n * that are no longer referenced elsewhere.\n */\nclass ComponentRegistry {\n  /**\n   * WeakSet allows automatic garbage collection when components\n   * are no longer referenced elsewhere in the application\n   */\n  private readonly components = new WeakSet<{ clear: () => void }>();\n\n  /**\n   * Strong references to active components that need cleanup.\n   * Components are removed from this Set after clearAll() to allow GC.\n   */\n  private readonly activeComponents = new Set<{ clear: () => void }>();\n\n  /**\n   * Register a component for automatic cleanup\n   *\n   * @internal\n   */\n  register(component: { clear: () => void }): void {\n    this.components.add(component);\n    this.activeComponents.add(component);\n  }\n\n  /**\n   * Unregister a component (allows garbage collection)\n   * Call this for components that won't be reused in future tests\n   *\n   * @internal\n   */\n  unregister(component: { clear: () => void }): void {\n    this.activeComponents.delete(component);\n    // WeakSet will allow GC when no other references exist\n  }\n\n  /**\n   * Clear all registered components\n   * Called automatically by afterEach hook\n   *\n   * Clears render data from components but keeps them registered\n   * for reuse in subsequent tests (e.g., components created in describe() blocks).\n   *\n   * Components that are no longer referenced in test code will be\n   * automatically garbage collected via WeakSet.\n   *\n   * @internal\n   */\n  clearAll(): void {\n    // Clear data from all active components\n    for (const c of this.activeComponents) {\n      c.clear();\n    }\n    // Note: We don't clear activeComponents Set itself to allow\n    // components created in describe() blocks to persist and be reused\n  }\n\n  /**\n   * Get count of active registered components\n   * For debugging purposes only\n   *\n   * @internal\n   */\n  /* c8 ignore next 3 */\n  getRegisteredCount(): number {\n    return this.activeComponents.size;\n  }\n}\n\n/**\n * Global singleton registry\n *\n * @internal\n */\nexport const registry = new ComponentRegistry();\n","import { afterEach } from \"vitest\";\n\nimport { registry } from \"./registry\";\n\n/**\n * Automatically registers cleanup hook when imported\n * This ensures test isolation without manual intervention\n *\n * All profiled components are automatically cleared between tests\n * No need for manual clearCounters() calls or afterEach hooks\n */\ntry {\n  if (typeof afterEach === \"function\") {\n    afterEach(() => {\n      registry.clearAll();\n    });\n  }\n  /* c8 ignore next 3 */\n} catch {\n  // Silently ignore if not in test context\n}\n","import type { ProfilerStorage } from \"@/profiler/core/ProfilerStorage\";\nimport type { AnyComponentType } from \"@/types\";\nimport type { ProfilerOnRenderCallback } from \"react\";\n\n/**\n * Create onRender callback for component\n *\n * Captures render phase from React Profiler and stores it directly\n */\nexport function createOnRenderCallback(\n  component: AnyComponentType,\n  storage: ProfilerStorage,\n): ProfilerOnRenderCallback {\n  return (_id, phase) => {\n    const data = storage.getOrCreate(component);\n\n    data.addRender(phase);\n  };\n}\n","import React, { Profiler, useRef } from \"react\";\n\nimport type { ComponentType, ProfilerOnRenderCallback } from \"react\";\n\ninterface ProfiledComponentProps<P> {\n  Component: ComponentType<P>;\n  componentProps: P;\n  componentName: string;\n  onRender: ProfilerOnRenderCallback;\n}\n\n// Global counter for generating unique IDs across all instances\nlet globalInstanceCounter = 0;\n\n/**\n * React component with built-in Profiler\n *\n * Responsibilities:\n * - Wrapping component in <Profiler>\n * - Generating unique ID for each instance\n * - Passing onRender callback\n */\nexport function ProfiledComponentWrapper<P extends object>(\n  props: Readonly<ProfiledComponentProps<P>>,\n): React.ReactElement {\n  const { Component, componentProps, componentName, onRender } = props;\n\n  // Stable ID for this component instance\n  const idRef = useRef<string>(\"\");\n\n  // Generate ID on first render\n  if (!idRef.current) {\n    globalInstanceCounter += 1;\n    idRef.current = `${componentName}-${globalInstanceCounter}`;\n  }\n\n  return (\n    <Profiler id={idRef.current} onRender={onRender}>\n      <Component {...componentProps} />\n    </Profiler>\n  );\n}\n","import type { ProfilerStorage } from \"../core/ProfilerStorage\";\nimport type { AnyComponentType, PhaseType, ProfiledComponent } from \"@/types\";\nimport type { ComponentType } from \"react\";\n\n// Frozen empty array to return when no data exists\nconst EMPTY_FROZEN_ARRAY = Object.freeze<PhaseType[]>([]);\n\n/**\n * Creates public API methods for ProfiledComponent\n *\n * Responsibilities:\n * - Creating methods getRenderCount, getRenderHistory, etc.\n * - Accessing data through ProfilerStorage\n * - Handling cases when data doesn't exist\n */\nexport class ProfilerAPI {\n  private readonly storage: ProfilerStorage;\n\n  constructor(storage: ProfilerStorage) {\n    this.storage = storage;\n  }\n\n  /**\n   * Create getRenderCount method for component\n   */\n  createGetRenderCount(component: AnyComponentType): () => number {\n    return () => {\n      const data = this.storage.get(component);\n\n      return data?.getRenderCount() ?? 0;\n    };\n  }\n\n  /**\n   * Create getRenderHistory method for component\n   */\n  createGetRenderHistory(\n    component: AnyComponentType,\n  ): () => readonly PhaseType[] {\n    return () => {\n      const data = this.storage.get(component);\n\n      return data?.getHistory() ?? EMPTY_FROZEN_ARRAY;\n    };\n  }\n\n  /**\n   * Create getLastRender method for component\n   */\n  createGetLastRender(\n    component: AnyComponentType,\n  ): () => PhaseType | undefined {\n    return () => {\n      const data = this.storage.get(component);\n\n      return data?.getLastRender();\n    };\n  }\n\n  /**\n   * Create getRenderAt method for component\n   */\n  createGetRenderAt(\n    component: AnyComponentType,\n  ): (index: number) => PhaseType | undefined {\n    return (index: number) => {\n      const data = this.storage.get(component);\n\n      return data?.getRenderAt(index);\n    };\n  }\n\n  /**\n   * Create getRendersByPhase method for component\n   */\n  createGetRendersByPhase(\n    component: AnyComponentType,\n  ): (phase: PhaseType) => readonly PhaseType[] {\n    return (phase: PhaseType) => {\n      const data = this.storage.get(component);\n\n      return data?.getRendersByPhase(phase) ?? EMPTY_FROZEN_ARRAY;\n    };\n  }\n\n  /**\n   * Create hasMounted method for component\n   */\n  createHasMounted(component: AnyComponentType): () => boolean {\n    return () => {\n      const data = this.storage.get(component);\n\n      return data?.hasMounted() ?? false;\n    };\n  }\n\n  /**\n   * Create all API methods for component\n   */\n  createAllMethods<P>(\n    component: ComponentType<P>,\n  ): Pick<\n    ProfiledComponent<P>,\n    | \"getRenderCount\"\n    | \"getRenderHistory\"\n    | \"getLastRender\"\n    | \"getRenderAt\"\n    | \"getRendersByPhase\"\n    | \"hasMounted\"\n  > {\n    return {\n      getRenderCount: this.createGetRenderCount(component),\n      getRenderHistory: this.createGetRenderHistory(component),\n      getLastRender: this.createGetLastRender(component),\n      getRenderAt: this.createGetRenderAt(component),\n      getRendersByPhase: this.createGetRendersByPhase(component),\n      hasMounted: this.createHasMounted(component),\n    };\n  }\n}\n","import type { PhaseType } from \"@/types\";\n\n/**\n * Manages all types of caching for profiler data\n *\n * Supports 3 types of cache:\n * 1. frozenHistory - immutable copy of entire history (array of phases)\n * 2. phaseCache - filtered renders by phase (mount/update/nested-update)\n * 3. hasMountedCache - result of checking for mount render\n */\nexport class ProfilerCache {\n  private frozenHistory?: readonly PhaseType[] | undefined;\n  private phaseCache?:\n    | {\n        mount?: readonly PhaseType[];\n        update?: readonly PhaseType[];\n        \"nested-update\"?: readonly PhaseType[];\n      }\n    | undefined;\n  private hasMountedCache?: boolean | undefined;\n\n  /**\n   * Get or compute frozen history\n   *\n   * @param compute - Computation function, called only if cache is invalid\n   */\n  getFrozenHistory(compute: () => readonly PhaseType[]): readonly PhaseType[] {\n    this.frozenHistory ??= compute();\n\n    return this.frozenHistory;\n  }\n\n  /**\n   * Get or compute renders by phase\n   */\n  getPhaseCache(\n    phase: PhaseType,\n    compute: () => readonly PhaseType[],\n  ): readonly PhaseType[] {\n    // Initialize phaseCache as empty object if undefined\n    this.phaseCache ??= {};\n\n    this.phaseCache[phase] ??= compute();\n\n    return this.phaseCache[phase];\n  }\n\n  /**\n   * Get or compute hasMounted\n   */\n  getHasMounted(compute: () => boolean): boolean {\n    this.hasMountedCache ??= compute();\n\n    return this.hasMountedCache;\n  }\n\n  /**\n   * Invalidate all caches (called on new render)\n   */\n  invalidate(): void {\n    this.frozenHistory = undefined;\n    this.phaseCache = undefined;\n    this.hasMountedCache = undefined;\n  }\n\n  /**\n   * Full clear (called on clear)\n   */\n  clear(): void {\n    this.invalidate();\n  }\n}\n","import { ProfilerCache } from \"./ProfilerCache\";\n\nimport type { PhaseType } from \"@/types\";\n\n/**\n * Manages profiling data for a single component\n *\n * Responsibilities:\n * - Storing renderHistory (array of phases)\n * - Adding new renders\n * - Accessing render history\n * - Coordinating with cache\n */\nexport class ProfilerData {\n  private renderHistory: PhaseType[];\n  private readonly cache: ProfilerCache;\n\n  constructor() {\n    this.renderHistory = [];\n    this.cache = new ProfilerCache();\n  }\n\n  /**\n   * Add a new render to history\n   */\n  addRender(phase: PhaseType): void {\n    this.renderHistory.push(phase);\n    this.cache.invalidate();\n  }\n\n  /**\n   * Get the number of renders\n   */\n  getRenderCount(): number {\n    return this.renderHistory.length;\n  }\n\n  /**\n   * Get immutable copy of history (with caching)\n   */\n  getHistory(): readonly PhaseType[] {\n    return this.cache.getFrozenHistory(() => {\n      return Object.freeze([...this.renderHistory]);\n    });\n  }\n\n  /**\n   * Get the last render phase\n   */\n  getLastRender(): PhaseType | undefined {\n    return this.getHistory().at(-1);\n  }\n\n  /**\n   * Get render phase by index\n   */\n  getRenderAt(index: number): PhaseType | undefined {\n    return this.getHistory()[index];\n  }\n\n  /**\n   * Get renders filtered by phase (with caching)\n   */\n  getRendersByPhase(phase: PhaseType): readonly PhaseType[] {\n    return this.cache.getPhaseCache(phase, () => {\n      return Object.freeze(this.renderHistory.filter((p) => p === phase));\n    });\n  }\n\n  /**\n   * Check if component has ever mounted (with caching)\n   */\n  hasMounted(): boolean {\n    return this.cache.getHasMounted(() => {\n      return this.renderHistory.includes(\"mount\");\n    });\n  }\n\n  /**\n   * Clear all history and caches\n   */\n  clear(): void {\n    this.renderHistory = [];\n    this.cache.clear();\n  }\n}\n","import { ProfilerData } from \"./ProfilerData\";\n\nimport type { AnyComponentType } from \"@/types\";\n\n/**\n * Type-safe storage for profiler data\n *\n * Uses WeakMap for automatic garbage collection\n * and data isolation between components\n */\nexport class ProfilerStorage {\n  private readonly storage: WeakMap<AnyComponentType, ProfilerData>;\n\n  constructor() {\n    this.storage = new WeakMap();\n  }\n\n  /**\n   * Get component data\n   */\n  get(component: AnyComponentType): ProfilerData | undefined {\n    return this.storage.get(component);\n  }\n\n  /**\n   * Set component data\n   */\n  set(component: AnyComponentType, data: ProfilerData): void {\n    this.storage.set(component, data);\n  }\n\n  /**\n   * Check if data exists\n   */\n  has(component: AnyComponentType): boolean {\n    return this.storage.has(component);\n  }\n\n  /**\n   * Get or create component data\n   */\n  getOrCreate(component: AnyComponentType): ProfilerData {\n    let data = this.get(component);\n\n    if (data === undefined) {\n      data = new ProfilerData();\n      this.set(component, data);\n    }\n\n    return data;\n  }\n}\n","import { createOnRenderCallback } from \"@/profiler/components/createOnRenderCallback\";\nimport { registry } from \"@/registry\";\n\nimport { ProfiledComponentWrapper } from \"./ProfiledComponent\";\nimport { ProfilerAPI } from \"../api/ProfilerAPI\";\nimport { ProfilerStorage } from \"../core/ProfilerStorage\";\n\nimport type { ProfiledComponentType } from \"@/types\";\nimport type { ComponentType, ReactElement } from \"react\";\n\n// Global singletons - single instance for entire application\nconst globalStorage = new ProfilerStorage();\nconst globalAPI = new ProfilerAPI(globalStorage);\n\n/**\n * Wraps a React component with profiling capabilities for testing\n *\n * @param Component - The component to profile\n * @param displayName - Optional custom display name for debugging\n * @returns A wrapped component with profiling API\n */\nexport function withProfiler<P extends object>(\n  Component: ComponentType<P>,\n  displayName?: string,\n): ProfiledComponentType<P> {\n  // Step 1: Determine component name\n  const componentName =\n    displayName ?? Component.displayName ?? (Component.name || \"Component\");\n\n  // Step 2: Create onRender callback (will initialize storage via getOrCreate)\n  const onRender = createOnRenderCallback(Component, globalStorage);\n\n  // Step 3: Create wrapper component\n  const ProfiledComponentFunc = (props: P): ReactElement => {\n    return (\n      <ProfiledComponentWrapper\n        Component={Component}\n        componentProps={props}\n        componentName={componentName}\n        onRender={onRender}\n      />\n    );\n  };\n\n  // Cast to ProfiledComponent type\n  const ProfiledComp = ProfiledComponentFunc as ProfiledComponentType<P>;\n\n  // Step 4: Set displayName\n  ProfiledComp.displayName = `withProfiler(${componentName})`;\n\n  // Step 5: Add OriginalComponent reference (hidden from enumeration)\n  Object.defineProperty(ProfiledComp, \"OriginalComponent\", {\n    value: Component,\n    writable: false,\n    enumerable: false,\n    configurable: false,\n  });\n\n  // Step 6: Attach API methods\n  const apiMethods = globalAPI.createAllMethods(Component);\n\n  Object.assign(ProfiledComp, apiMethods);\n\n  // Step 7: Register for cleanup\n  const clearInternal = () => {\n    const data = globalStorage.get(Component);\n\n    data?.clear();\n  };\n\n  registry.register({ clear: clearInternal });\n\n  // Step 8: Return wrapped component with full API\n  return ProfiledComp;\n}\n","import { render, act } from \"@testing-library/react\";\n\nimport { withProfiler } from \"../profiler/components/withProfiler\";\n\nimport type { ProfiledComponent } from \"../types\";\n\n/**\n * Profile a React Hook to detect extra renders\n *\n * @param hook - The hook function to profile\n * @param initialProps - Initial props to pass to the hook (required for hooks with parameters)\n * @returns Object with hook result and profiled component\n *\n * @example\n * ```tsx\n * // Hook without parameters\n * const { result, ProfiledHook } = profileHook(() => useMyHook());\n *\n * // Hook with parameters\n * const { result, ProfiledHook } = profileHook(\n *   ({ value }) => useBadHook(value),\n *   { value: 1 }\n * );\n *\n * expect(ProfiledHook).toHaveRenderedTimes(2); // Detected extra render!\n * ```\n */\n\n// Type overload for hooks without parameters\nexport function profileHook<TResult>(hook: () => TResult): {\n  result: { readonly current: TResult };\n  rerender: () => void;\n  unmount: () => void;\n  ProfiledHook: ProfiledComponent<object>;\n};\n\n// Type overload for hooks with parameters\nexport function profileHook<TProps, TResult>(\n  hook: (props: TProps) => TResult,\n  initialProps: TProps,\n): {\n  result: { readonly current: TResult };\n  rerender: (newProps: TProps) => void;\n  unmount: () => void;\n  ProfiledHook: ProfiledComponent<TProps>;\n};\n\n// Implementation\nexport function profileHook<TProps extends object = object, TResult = unknown>(\n  hook: (props: TProps) => TResult,\n  initialProps?: TProps,\n): {\n  result: { readonly current: TResult };\n  rerender: (newProps?: TProps) => void;\n  unmount: () => void;\n  ProfiledHook: ProfiledComponent<TProps>;\n} {\n  let hookResult: TResult;\n\n  // Component wrapper that calls the hook\n  const HookComponent = (props: TProps) => {\n    hookResult = hook(props);\n\n    return null;\n  };\n\n  // Set display name for debugging\n  const hookName = hook.name || \"useHook\";\n\n  HookComponent.displayName = `HookWrapper(${hookName})`;\n\n  // Wrap with profiler\n  const ProfiledHook = withProfiler(HookComponent, hookName);\n\n  // Use empty object for hooks without parameters\n  const propsToUse = (initialProps ?? {}) as TProps;\n\n  // Render the component\n  const { rerender: rtlRerender, unmount } = render(\n    <ProfiledHook {...propsToUse} />,\n  );\n\n  return {\n    // Use getter to return actual current value\n    result: {\n      get current() {\n        return hookResult;\n      },\n    },\n    // Wrap rerender in act() to avoid warnings\n    rerender: (newProps?: TProps) => {\n      act(() => {\n        const props = (newProps ?? {}) as TProps;\n\n        rtlRerender(<ProfiledHook {...props} />);\n      });\n    },\n    unmount,\n    ProfiledHook,\n  };\n}\n","import { profileHook } from \"./profileHook\";\n\nimport type { PhaseType, ProfiledComponent } from \"../types\";\n\n/**\n * Simplified API for hook profiling with built-in assertions\n *\n * @param hook - The hook function to profile\n * @param initialProps - Initial props to pass to the hook (required for hooks with parameters)\n * @returns Profiler object with assertion helpers and metrics\n *\n * @example\n * ```tsx\n * // Simple usage\n * const profiler = createHookProfiler(() => useMyHook());\n * profiler.expectRenderCount(1);\n *\n * // With props\n * const profiler = createHookProfiler(\n *   ({ value }) => useMyHook(value),\n *   { value: 1 }\n * );\n * profiler.rerender({ value: 2 });\n * profiler.expectRenderCount(2);\n * ```\n */\n\n// Type overload for hooks without parameters\nexport function createHookProfiler<TResult>(hook: () => TResult): {\n  result: { readonly current: TResult };\n  rerender: () => void;\n  unmount: () => void;\n  ProfiledHook: ProfiledComponent<object>;\n  expectRenderCount: (expected: number) => void;\n  getRenderCount: () => number;\n  getRenderHistory: () => readonly PhaseType[];\n  getLastRender: () => PhaseType | undefined;\n};\n\n// Type overload for hooks with parameters\nexport function createHookProfiler<TProps, TResult>(\n  hook: (props: TProps) => TResult,\n  initialProps: TProps,\n): {\n  result: { readonly current: TResult };\n  rerender: (newProps: TProps) => void;\n  unmount: () => void;\n  ProfiledHook: ProfiledComponent<TProps>;\n  expectRenderCount: (expected: number) => void;\n  getRenderCount: () => number;\n  getRenderHistory: () => readonly PhaseType[];\n  getLastRender: () => PhaseType | undefined;\n};\n\n// Implementation\n// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types\nexport function createHookProfiler<\n  TProps extends object = object,\n  TResult = unknown,\n>(hook: (props: TProps) => TResult, initialProps?: TProps) {\n  const { result, rerender, unmount, ProfiledHook } = profileHook(\n    hook,\n    initialProps!, // eslint-disable-line @typescript-eslint/no-non-null-assertion\n  );\n\n  return {\n    // Access to hook result\n    result,\n\n    // Lifecycle methods\n    rerender,\n    unmount,\n\n    // Direct access to profiled component\n    ProfiledHook,\n\n    // Assertion helpers\n    expectRenderCount(expected: number): void {\n      const actual = ProfiledHook.getRenderCount();\n\n      if (actual !== expected) {\n        throw new Error(\n          `Expected ${expected} render(s), but got ${actual}. ` +\n            `This hook may be causing unnecessary re-renders.`,\n        );\n      }\n    },\n\n    // Metrics\n    getRenderCount: () => ProfiledHook.getRenderCount(),\n    getRenderHistory: () => ProfiledHook.getRenderHistory(),\n    getLastRender: () => ProfiledHook.getLastRender(),\n  };\n}\n","import { waitFor } from \"@testing-library/react\";\n\nimport type { PhaseType, ProfiledComponent } from \"../types\";\n\n/**\n * Options for async waiting utilities\n */\nexport interface WaitOptions {\n  /**\n   * Maximum time to wait in milliseconds\n   *\n   * @default 1000\n   */\n  timeout?: number;\n\n  /**\n   * Polling interval in milliseconds\n   *\n   * @default 50\n   */\n  interval?: number;\n}\n\n/**\n * Wait for a component to reach a specific render count\n *\n * @param component - The profiled component to wait for\n * @param count - Expected number of renders\n * @param options - Wait options (timeout, interval)\n *\n * @example\n * ```typescript\n * const ProfiledButton = withProfiler(Button);\n * render(<ProfiledButton onClick={() => setState(x => x + 1)} />);\n *\n * // Wait for 3 renders\n * await waitForRenders(ProfiledButton, 3);\n * expect(ProfiledButton).toHaveRenderedTimes(3);\n * ```\n *\n * @throws {Error} If the expected render count is not reached within timeout\n */\nexport async function waitForRenders<P>(\n  component: ProfiledComponent<P>,\n  count: number,\n  options?: WaitOptions,\n): Promise<void> {\n  const { timeout = 1000, interval = 50 } = options ?? {};\n\n  await waitFor(\n    () => {\n      const actual = component.getRenderCount();\n\n      if (actual < count) {\n        throw new Error(\n          `Expected ${count} renders, but got ${actual}. Waiting for ${count - actual} more render(s)...`,\n        );\n      }\n    },\n    { timeout, interval },\n  );\n}\n\n/**\n * Wait for a component to reach at least a minimum render count\n *\n * @param component - The profiled component to wait for\n * @param minCount - Minimum number of renders\n * @param options - Wait options (timeout, interval)\n *\n * @example\n * ```typescript\n * const ProfiledButton = withProfiler(Button);\n * render(<ProfiledButton onClick={() => setState(x => x + 1)} />);\n *\n * // Wait for at least 2 renders (could be more)\n * await waitForMinimumRenders(ProfiledButton, 2);\n * expect(ProfiledButton.getRenderCount()).toBeGreaterThanOrEqual(2);\n * ```\n *\n * @throws {Error} If the minimum render count is not reached within timeout\n */\nexport async function waitForMinimumRenders<P>(\n  component: ProfiledComponent<P>,\n  minCount: number,\n  options?: WaitOptions,\n): Promise<void> {\n  const { timeout = 1000, interval = 50 } = options ?? {};\n\n  await waitFor(\n    () => {\n      const actual = component.getRenderCount();\n\n      if (actual < minCount) {\n        throw new Error(\n          `Expected at least ${minCount} renders, but got ${actual}. Waiting for ${minCount - actual} more render(s)...`,\n        );\n      }\n    },\n    { timeout, interval },\n  );\n}\n\n/**\n * Wait for a component to reach a specific render phase\n *\n * @param component - The profiled component to wait for\n * @param phase - The render phase to wait for ('mount', 'update', or 'nested-update')\n * @param options - Wait options (timeout, interval)\n *\n * @example\n * ```typescript\n * const ProfiledButton = withProfiler(Button);\n * const { rerender } = render(<ProfiledButton value={1} />);\n *\n * // Wait for component to update (not just mount)\n * rerender(<ProfiledButton value={2} />);\n * await waitForPhase(ProfiledButton, 'update');\n *\n * expect(ProfiledButton.getRendersByPhase('update')).toHaveLength(1);\n * ```\n *\n * @throws {Error} If the phase is not reached within timeout\n */\nexport async function waitForPhase<P>(\n  component: ProfiledComponent<P>,\n  phase: PhaseType,\n  options?: WaitOptions,\n): Promise<void> {\n  const { timeout = 1000, interval = 50 } = options ?? {};\n\n  await waitFor(\n    () => {\n      const hasPhase = component.getRenderHistory().includes(phase);\n\n      if (!hasPhase) {\n        throw new Error(\n          `Expected component to reach phase \"${phase}\", but it hasn't yet. Current phases: [${component\n            .getRenderHistory()\n            .join(\", \")}]`,\n        );\n      }\n    },\n    { timeout, interval },\n  );\n}\n","import { render } from \"@testing-library/react\";\n\nimport { withProfiler } from \"../profiler/components/withProfiler\";\n\nimport type { ProfiledComponentType } from \"../types\";\nimport type { RenderOptions, RenderResult } from \"@testing-library/react\";\nimport type { ComponentType } from \"react\";\n\n/**\n * Options for renderProfiled\n */\nexport interface RenderProfiledOptions {\n  /**\n   * Custom display name for the profiled component\n   */\n  displayName?: string;\n\n  /**\n   * React Testing Library render options\n   */\n  renderOptions?: RenderOptions;\n}\n\n/**\n * Result of renderProfiled that includes the profiled component and all RTL utilities\n */\nexport interface RenderProfiledResult<P extends object>\n  extends Omit<RenderResult, \"rerender\"> {\n  /**\n   * The profiled component with profiling API methods\n   */\n  component: ProfiledComponentType<P>;\n\n  /**\n   * Enhanced rerender function that accepts partial props\n   *\n   * @param newProps - Partial props to merge with original props\n   */\n  rerender: (newProps: Partial<P>) => void;\n}\n\n/**\n * Simplified helper for rendering a component with profiling in a single step\n *\n * This is a convenience wrapper that combines `withProfiler()` and `render()` into one call,\n * making it easier to write tests with profiling enabled.\n *\n * @param Component - The React component to profile\n * @param props - Initial props for the component\n * @param options - Optional configuration\n * @returns An object containing the profiled component and all React Testing Library utilities\n *\n * @example\n * ```tsx\n * // Before (manual approach)\n * const ProfiledButton = withProfiler(Button);\n * const { rerender } = render(<ProfiledButton value={1} />);\n * expect(ProfiledButton).toHaveRenderedTimes(1);\n * rerender(<ProfiledButton value={2} />);\n * expect(ProfiledButton).toHaveRenderedTimes(2);\n *\n * // After (with renderProfiled)\n * const { component, rerender } = renderProfiled(Button, { value: 1 });\n * expect(component).toHaveRenderedTimes(1);\n * rerender({ value: 2 }); // automatically merges props\n * expect(component).toHaveRenderedTimes(2);\n * ```\n *\n * @example\n * ```tsx\n * // With custom display name\n * const { component } = renderProfiled(Button, { value: 1 }, {\n *   displayName: 'MyButton'\n * });\n *\n * // With RTL render options\n * const { component } = renderProfiled(Button, { value: 1 }, {\n *   renderOptions: { wrapper: ThemeProvider }\n * });\n * ```\n */\nexport function renderProfiled<P extends object>(\n  Component: ComponentType<P>,\n  props: P,\n  options?: RenderProfiledOptions,\n): RenderProfiledResult<P> {\n  const ProfiledComponent = withProfiler(Component, options?.displayName);\n\n  // Track current props to merge with partial updates\n  let currentProps = props;\n\n  const rtl = render(<ProfiledComponent {...props} />, options?.renderOptions);\n\n  return {\n    component: ProfiledComponent,\n    ...rtl,\n    rerender: (newProps: Partial<P>) => {\n      // Merge current props with new partial props\n      currentProps = { ...currentProps, ...newProps };\n      rtl.rerender(<ProfiledComponent {...currentProps} />);\n    },\n  };\n}\n","/**\n * vitest-react-profiler\n * React component render tracking and performance testing utilities for Vitest\n *\n * @packageDocumentation\n */\n\n// Core functionality\n// Matchers - auto-registered when imported\nimport \"./matchers\";\n\n// Auto-setup - registers afterEach cleanup hook\nimport \"./auto-setup\";\n\nexport { withProfiler } from \"./profiler/components/withProfiler\";\n\n// Hook profiling\nexport { profileHook, createHookProfiler } from \"./hooks\";\n\n// Utilities\nexport {\n  formatRenderHistory,\n  formatRenderSummary,\n} from \"./utils/formatRenderHistory\";\n\n// Async utilities\nexport {\n  waitForRenders,\n  waitForMinimumRenders,\n  waitForPhase,\n} from \"./utils/async\";\n\nexport type { WaitOptions } from \"./utils/async\";\n\n// Rendering utilities\nexport { renderProfiled } from \"./utils/renderProfiled\";\n\nexport type {\n  RenderProfiledOptions,\n  RenderProfiledResult,\n} from \"./utils/renderProfiled\";\n\n// Types\nexport type {\n  PhaseType,\n  ProfiledComponent,\n  ProfiledComponentType,\n} from \"./types\";\n\n// Version info\nexport const VERSION = process.env.npm_package_version ?? \"0.0.0\";\n"]}