import type { Root, RootData } from 'hast';
import type { Delta } from 'jsondiffpatch';
import type { FallbackNode, CompressedFallback } from "./fallbackFormat.mjs";
export type Components = {
  [key: string]: React.ReactNode;
};
type CodeMeta = {
  /** Name of the file (e.g., 'Button.tsx') */
  fileName?: string;
  /** Language for syntax highlighting (e.g., 'tsx', 'css'). When provided, fileName is not required. */
  language?: string;
  /** Flattened path for the file */
  path?: string;
};
/**
 * Records the transforms available for a source. Each entry can provide a
 * jsondiffpatch `delta` (the patch to apply against the source's parsed hast
 * tree), an optional renamed `fileName`, and an optional `comments` map.
 *
 * When `comments` is present, it represents the post-transform comment map
 * (1-indexed by line number in the transformed source) and is used as-is by
 * `applyCodeTransformWithComments` instead of auto-shifting the caller's
 * comments via the surviving `dataLn` mapping. Source transformers should
 * only emit `comments` when they add or relocate lines; transforms that only
 * wipe lines (replacing them with empty strings) are handled automatically.
 *
 * `hasDelta` indicates whether the entry actually produced a code-level
 * difference. When `false` (or omitted), the entry is rename-only — it
 * carries a renamed `fileName` (and optionally `comments`) but the
 * transformed source is structurally identical to the original. Rename-only
 * entries are excluded from `getAvailableTransforms` (so the toggle stays
 * hidden when nothing meaningful changes) but still apply the rename when
 * the user has the matching transform preference selected.
 *
 * `hasCollapse` indicates whether the inline `delta` (or the embedded delta
 * matching this manifest entry) inserts a `.collapse` placeholder element.
 * The runtime uses this flag to classify a transform swap as
 * layout-affecting (phase 1: coordinated barrier so peers stay in lockstep)
 * versus non-layout (phase 2: deferred until after phase 1 settles) without
 * having to decompress the embedded hast payload on every selection
 * change. Computed once during `splitTransformsForEmbed` and persisted on
 * the manifest entry.
 *
 * `hasCollapseInFocus` is the focus-region-aware counterpart: it is `true`
 * only when at least one `.collapse` placeholder lands inside the source
 * region that is visible when the surrounding code block is *collapsed*
 * (the lines covered by `data-frame-type` ∈ `'highlighted' | 'focus' |
 * 'padding-top' | 'padding-bottom'`, falling back to the first frame when
 * no emphasis frames exist — matching the runtime visibility rule in
 * `<Pre>`). Consumers that opt into `transformLayoutShift: 'focus'` use
 * this flag (instead of `hasCollapse`) while the block is collapsed, so a
 * `.collapse` insertion outside the visible window doesn't force a
 * coordinated barrier swap that the user wouldn't see anyway.
 *
 * After serialization (`output: 'hastJson' | 'hastCompressed'`), the deltas
 * are moved inside the source's `HastRoot.data.transforms` so they ride
 * along inside the compressed payload and never appear as plain JSON in the
 * rendered HTML or in the demo module graph. In that mode the variant-level
 * `transforms` field acts as a manifest — entries keep `fileName`,
 * `comments` (when set), `hasDelta`, `hasCollapse`, and
 * `hasCollapseInFocus` but `delta` is omitted. Consumers that need the
 * delta should look it up inside the decompressed `root.data.transforms`.
 */
export type Transforms = Record<string, {
  delta?: Delta;
  fileName?: string;
  comments?: SourceComments;
  hasDelta?: boolean;
  hasCollapse?: boolean;
  hasCollapseInFocus?: boolean;
}>;
export interface ExternalImportItem {
  name: string;
  type: 'named' | 'default' | 'namespace';
  isType?: boolean;
}
export type Externals = Record<string, ExternalImportItem[]>;
export interface HastRoot extends Root {
  data?: RootData & {
    totalLines?: number;
    /**
     * Number of source lines visible inside the focused window when the code
     * block is collapsed — the sum of frame sizes whose `data-frame-type` is
     * `'highlighted'`, `'focus'`, `'padding-top'`, or `'padding-bottom'`.
     * Equals `totalLines` when no emphasis directives are present (the whole
     * source is the focused window). Set by `enhanceCodeEmphasis`.
     */
    focusedLines?: number;
    collapsible?: boolean;
    frameSize?: number;
    appliedEnhancers?: string[];
    /**
     * Transform deltas embedded in the hast root so they get compressed along
     * with the tree and stay out of the rendered HTML / module graph. The
     * variant-level `transforms` field is a `TransformManifest` (keys only)
     * that mirrors `Object.keys(this.transforms)`. `hast-util-to-jsx-runtime`
     * does not serialize `Root.data` to the DOM.
     */
    transforms?: Transforms;
  };
}
export type VariantSource = string | HastRoot | {
  hastJson: string;
} | {
  hastCompressed: string;
};
/**
 * Additional files associated with a code variant.
 * Can be either simple string content or objects with source and transformation options.
 */
export type VariantExtraFiles = {
  [fileName: string]: string | {
    /** Source content for this file */
    source?: VariantSource;
    /**
     * Compact fallback for this extra file.
     * See `VariantCode.fallback` for details.
     */
    fallback?: FallbackNode[];
    /** Line counts for this file. See `VariantCode.totalLines` / `focusedLines`. */
    totalLines?: number;
    focusedLines?: number;
    collapsible?: boolean;
    /** Language for syntax highlighting (e.g., 'tsx', 'css'). Derived from fileName extension if not provided. */
    language?: string;
    /** Transformations that can be applied to this file */
    transforms?: Transforms;
    /** Skip generating source transformers for this file */
    skipTransforms?: boolean;
    /** Include metadata for this file */
    metadata?: boolean;
    /** File system path for this file */
    path?: string;
    /**
     * Path of this file relative to the variant's `url`. Set when the
     * `extraFiles` key was rewritten (e.g., flattened) and no longer
     * resolves to the file's URL on its own. Consumers derive the file
     * URL via `new URL(relativeUrl, variant.url)`. When omitted, the
     * `extraFiles` key itself resolves to the file URL against
     * `variant.url`.
     *
     * Always normalized to start with `./` or `../`.
     */
    relativeUrl?: string;
    /** Comments extracted from source, stored when parsing is disabled for later use */
    comments?: SourceComments;
  };
};
/**
 * Complete code variant definition with source, metadata, and configuration.
 * Extends CodeMeta with all the information needed to display and process a code example.
 */
export type VariantCode = CodeMeta & {
  /** Source URL where this variant originates */
  url?: string;
  /** Main source content for this variant */
  source?: VariantSource;
  /**
   * Compact fallback (highlighting spans removed) for the main source.
   * Converted from HAST via `hastToFallback` for smaller RSC payloads.
   * Used as the visual fallback before full highlighting loads, and its text
   * content (via `fallbackToText`) serves as the DEFLATE dictionary for
   * decompressing `hastCompressed` payloads.
   */
  fallback?: FallbackNode[];
  /**
   * Staging-only highlighted-visible fallback, stored **sparsely**: a map from frame
   * index to the highlighted `FallbackNode` for ONLY the frames visible on the initial
   * (collapsed, `collapseToEmpty: false`) render. Off-screen frames are omitted — they
   * are byte-identical to `fallback`'s plain output, so storing them would just
   * duplicate `fallback` in the precompute. Computed at load time (where the source is
   * still a live `HastRoot`, so no decompression) and carried in precomputed payloads
   * alongside `fallback`. Under `highlightAt: 'init'` the server/client boundary
   * `promoteCriticalFallback`s it over `fallback` so the first paint is highlighted with
   * no client-side decompression, then deletes it: `fallbackCritical` must NEVER reach
   * the `Content`/`ContentLoading` components. The promoted `fallback` has byte-identical
   * text, so it stays a valid DEFLATE dictionary. See `resolveFallbackCritical`.
   */
  fallbackCritical?: {
    [frameIndex: number]: FallbackNode;
  };
  /**
   * Line counts for this variant's main source — the same for the full (highlighted)
   * source and its `fallback`, since they're the same file. `totalLines` is the whole
   * file; `focusedLines` is the collapsed-window size. The loader surfaces them
   * with `collapsible` (notably for deferred plain-string sources, where the compact
   * `fallback` drops `root.data` and a string can't recompute the metadata) so
   * consumers can size and flag the `<code>` without re-deriving from counts.
   */
  totalLines?: number;
  focusedLines?: number;
  collapsible?: boolean;
  /** Additional files associated with this variant */
  extraFiles?: VariantExtraFiles;
  /** Prefix for metadata keys, e.g. /src */
  metadataPrefix?: string;
  /** External module dependencies */
  externals?: string[];
  /** The name of the export for this variant's entrypoint */
  namedExport?: string;
  /** Order in which files should be displayed */
  filesOrder?: string[];
  /** Transformations that can be applied to the source */
  transforms?: Transforms;
  /** Whether all files in the variant are explicitly listed */
  allFilesListed?: boolean;
  /** Skip generating source transformers for this variant */
  skipTransforms?: boolean;
  /** Comments extracted from source, stored when parsing is disabled for later use */
  comments?: SourceComments;
};
export type Code = {
  [key: string]: undefined | string | VariantCode;
};
/**
 * Tracks comments that were collapsed onto a line when their original lines
 * were deleted. Keyed by the line they collapsed onto; each entry records
 * the original offset from the edit line so the collapse can be reversed.
 */
export type CollapseMap = Record<number, Array<{
  offset: number;
  comments: string[];
  boundary?: true;
}>>;
export type ControlledVariantExtraFiles = {
  [fileName: string]: {
    source: string | null;
    comments?: SourceComments;
    collapseMap?: CollapseMap;
    totalLines?: number;
    emptyLines?: number[];
  };
};
export type ControlledVariantCode = CodeMeta & {
  url?: string;
  source?: string | null;
  extraFiles?: ControlledVariantExtraFiles;
  filesOrder?: string[];
  comments?: SourceComments;
  collapseMap?: CollapseMap;
  totalLines?: number;
  emptyLines?: number[];
};
export type ControlledCode = {
  [key: string]: undefined | null | ControlledVariantCode;
};
/**
 * Base props passed to Content components for rendering code examples.
 * These props provide the necessary data for displaying code, previews, and metadata.
 */
type BaseContentProps = CodeIdentityProps & Pick<CodeContentProps, 'code' | 'components' | 'variantType'> & {
  /**
   * Render-time "collapse to empty": collapse the code block to an empty window so
   * the whole block is hidden until the reader expands it. Runtime-only — it
   * never changes the precomputed HAST, only how it's rendered.
   */
  collapseToEmpty?: boolean;
  /**
   * Whether the (collapsible) code block starts expanded. Runtime-only. Lives
   * on `contentProps` rather than `useCode` opts so the loading fallback can
   * see it too.
   */
  initialExpanded?: boolean;
};
export type ContentProps<T extends {}> = BaseContentProps & T;
/**
 * Record of `fileName → compact fallback` extracted from variants.
 * Used as the DEFLATE dictionary for `hastCompressed` decompression and
 * as the visual fallback before full highlighting loads.
 */
export type Fallbacks = Record<string, FallbackNode[]>;
/**
 * A framed fallback for one file: the compact `source` frames plus the file's
 * loading metadata (`totalLines` whole-file, `focusedLines` collapsed-window,
 * `collapsible` frame state). Carried per extra file so a `ContentLoading` can
 * render the full framed code — with the right collapsed window — for every
 * file/variant passed to the fallback, not just the displayed one. The main
 * file's equivalent metadata lives on the variant as top-level fields alongside
 * its top-level `source`.
 */
export type ContentLoadingFile = {
  source: FallbackNode[];
  totalLines?: number;
  focusedLines?: number;
  collapsible?: boolean;
};
export type ContentLoadingVariant = {
  fileNames?: string[];
  source?: FallbackNode[];
  /** Loading metadata for the main `source` file. See {@link ContentLoadingFile}. */
  totalLines?: number;
  focusedLines?: number;
  collapsible?: boolean;
  /**
   * Language hint for the rendered `source` (e.g. `'tsx'`, `'css'`). Derived
   * from the variant's explicit `language` when set, otherwise from the
   * selected file name's extension. Consumers typically forward this as a
   * `language-{language}` class on the fallback `<code>` element so it picks
   * up the same language-scoped styling as the post-load tree.
   */
  language?: string;
  extraSource?: Record<string, ContentLoadingFile>;
};
export type BaseContentLoadingProps = ContentLoadingVariant & CodeIdentityProps & {
  extraVariants?: Record<string, ContentLoadingVariant>;
};
export type ContentLoadingProps<T extends {}> = BaseContentLoadingProps & T & {
  component: React.ReactNode;
  components?: Record<string, React.ReactNode>;
  initialFilename?: string;
  /**
   * Name of the variant currently selected for the fallback render — the
   * same key passed to `codeToFallbackProps` and used to look up
   * `component` / `components`. Consumers use this when labeling the main
   * variant in the fallback UI or when generating per-file slugs.
   */
  initialVariant?: string;
  /**
   * Set when the surrounding `CodeHighlighter` uses `fallbackCollapsed`: the
   * `source` here is only the collapsed window, and the hidden lines arrive
   * later with the full content. A `ContentLoading` should disable any expand
   * control while this is true — expanding would reveal nothing until the
   * full content swaps in. `useCodeFallback` re-exposes it as `collapsed`.
   */
  fallbackCollapsed?: boolean;
  /**
   * Render-time "collapse to empty": the loading placeholder should paint an empty
   * collapsed window (the whole block hidden until expanded), matching the
   * hydrated render. `useCodeFallback` honors this by demoting collapsed-
   * visible frame types in the returned `source`.
   */
  collapseToEmpty?: boolean;
  /**
   * Whether the block starts expanded. The loading placeholder uses it to
   * paint the full content (not just the collapsed window) when the hydrated
   * block will start expanded.
   */
  initialExpanded?: boolean;
};
export type LoadCodeMeta = (url: string) => Promise<Code>;
export type LoadVariantMeta = (variantName: string, url: string) => Promise<VariantCode>;
export type LoadSource = (url: string) => Promise<{
  source: string;
  extraFiles?: VariantExtraFiles;
  extraDependencies?: string[];
  externals?: Externals;
  /** Comments extracted from the source code, keyed by line number */
  comments?: SourceComments;
}>;
/**
 * Function that transforms a source file into one or more derived sources.
 *
 * @param source - The source code string to transform.
 * @param fileName - File name (used for extension detection / diagnostics).
 * @param comments - Optional comment map for `source`, keyed by 1-indexed
 *   line number (the convention everywhere a `Code` is stored). Transformers
 *   that want to shift comments manually should return a `comments` map
 *   alongside each transformed source, using the same 1-indexed line scheme
 *   relative to the returned source string.
 * @returns A record keyed by transform name. Each entry must contain the
 *   transformed `source` string, optionally a renamed `fileName`, and
 *   optionally a `comments` map (1-indexed). The runtime applies `comments`
 *   verbatim when present; when omitted, surviving lines' comments are
 *   shifted automatically based on which source lines survived the transform.
 *
 *   Transformers that only **remove** lines should replace those lines with
 *   empty strings rather than dropping them — the empty lines collapse
 *   automatically at runtime and the auto-shift correctly maps the
 *   surviving lines' comments. Only transformers that **add lines** or
 *   completely replace the file need to return an explicit `comments` map.
 */
export type TransformSource = (source: string, fileName: string, comments?: SourceComments) => Promise<Record<string, {
  source: string;
  fileName?: string;
  comments?: SourceComments;
}> | undefined>;
/**
 * Parses source code into a HAST tree with syntax highlighting.
 *
 * @param source - The source code to parse and highlight
 * @param fileName - File name used to detect language via file extension
 * @param language - Optional explicit language override (e.g., 'tsx', 'css', 'typescript')
 */
export type ParseSource = (source: string, fileName: string, language?: string) => HastRoot;
export type SourceTransformer = {
  extensions: string[];
  transformer: TransformSource;
};
export type SourceTransformers = Array<SourceTransformer>;
/**
 * Comments extracted from source code, keyed by line number.
 * Each line number maps to an array of comment strings found on that line.
 */
export type SourceComments = Record<number, string[]>;
/**
 * Function that enhances a HAST root node, optionally using source comments for context.
 * Enhancers run after parsing and before transforms are computed.
 *
 * @param root - The HAST root node to enhance
 * @param comments - Comments extracted from the source code, keyed by line number
 * @param fileName - The name of the file being processed
 * @returns The enhanced HAST root node (can be the same object, mutated)
 */
export interface SourceEnhancer {
  (root: HastRoot, comments: SourceComments | undefined, fileName: string): HastRoot | Promise<HastRoot>;
  /**
   * Stable identifier for this enhancer. When set, the enhancer is recorded on
   * the HAST root as `data.appliedEnhancers` after it runs, and subsequent
   * passes (e.g. on the client after a server-side run) skip it instead of
   * re-applying. Anonymous enhancers always run.
   */
  enhancerName?: string;
}
/**
 * Array of source enhancer functions that run in order after parsing.
 */
export type SourceEnhancers = Array<SourceEnhancer>;
/**
 * Options for controlling file loading behavior
 */
export interface LoadFileOptions {
  /** Disable applying source transformers */
  disableTransforms?: boolean;
  /** Disable parsing source strings to AST */
  disableParsing?: boolean;
  /**
   * When parsing is skipped (`disableParsing`/deferred highlight) and the source
   * stays a plain string, still derive a *framed* loading fallback from it —
   * line-guttered plain-text HAST + enhancers → root fallback. Set by the loading
   * fallback loader so the un-highlighted initial paint is framed (rendered code
   * needs frames); left off for lazy variant loads that don't paint a fallback.
   */
  framePlainFallback?: boolean;
  /** Maximum recursion depth for loading nested extra files */
  maxDepth?: number;
  /** Set of already loaded file URLs to prevent circular dependencies */
  loadedFiles?: Set<string>;
  /** Side effects code to inject into extraFiles */
  globalsCode?: Array<VariantCode | string>;
  /** Output format for the loaded file
   * @default 'hast'
   */
  output?: 'hast' | 'hastJson' | 'hastCompressed';
  /**
   * Optional URL-prefix rewrite applied to the loaded variant's `url` and any
   * string-form `extraFiles` entries. Useful for translating local `file://`
   * URLs (e.g. those returned by `loadServerCodeSource`) into hosted URLs (e.g.
   * `https://github.com/owner/repo/tree/<branch>/`) before they reach the
   * client.
   */
  urlPrefix?: {
    from: string;
    to: string;
  };
}
/**
 * Options for the loadIsomorphicCodeVariant function, extending LoadFileOptions with required function dependencies
 */
export interface LoadVariantOptions extends LoadFileOptions, Pick<CodeFunctionProps, 'sourceParser' | 'loadSource' | 'loadVariantMeta' | 'sourceTransformers' | 'sourceEnhancers'> {}
/**
 * Options for loading fallback code with various configuration flags
 */
export interface LoadFallbackCodeOptions extends LoadFileOptions, CodeFunctionProps, Pick<CodeContentProps, 'variants'>, Pick<CodeLoadingProps, 'fallbackUsesExtraFiles' | 'fallbackUsesAllVariants'> {
  /** Flag to indicate if syntax highlighting should be performed */
  shouldHighlight?: boolean;
  /** Specific filename to initially display */
  initialFilename?: string;
  /** Array of global code to include (overrides LoadFileOptions.globalsCode with different type) */
  globalsCode?: Array<Code | string>;
}
/**
 * Basic identification and metadata props for code examples
 */
export interface CodeIdentityProps {
  /** Display name for the code example, used for identification and titles */
  name?: string;
  /** URL-friendly identifier for deep linking and navigation */
  slug?: string;
  /** Source URL where the code content originates from */
  url?: string;
}
/**
 * Core code content and variant management props
 */
export interface CodeContentProps {
  /** Static code content with variants and metadata */
  code?: Code;
  /** React components for live preview alongside code */
  components?: Components;
  /** What type of variants are available (e.g., a type `packageManager` when variants `npm` and `yarn` are available) */
  variantType?: string;
  /** Static variant names that should be fetched at runtime */
  variants?: string[];
  /** Currently selected variant name */
  variant?: string;
  /** Currently selected file name */
  fileName?: string;
  /** Language for syntax highlighting (e.g., 'tsx', 'css'). When provided, fileName is not required for parsing. */
  language?: string;
  /** Default variant to show on first load */
  initialVariant?: string;
  /** Fallback variant when the requested variant is not available */
  defaultVariant?: string;
  /** Global static code snippets to inject, typically for styling or tooling */
  globalsCode?: Array<Code | string>;
}
/**
 * Loading and processing configuration props
 */
export interface CodeLoadingProps {
  /** Pre-computed code data from build-time optimization */
  precompute?: Code;
  /** Whether fallback content should include extra files */
  fallbackUsesExtraFiles?: boolean;
  /** Whether fallback content should include all variants */
  fallbackUsesAllVariants?: boolean;
  /**
   * Paint only the collapsed window in the `ContentLoading` fallback and defer
   * each file's full fallback into the compressed payload. Shrinks the initial
   * HTML of a collapsed block to its on-screen lines, but removes the hidden
   * lines from the server-rendered markup — so it is **only** appropriate for
   * content that will not be crawled (authenticated or internal pages). See the
   * prop-compression pattern's "Splitting the Fallback by Visibility".
   * @default false
   */
  fallbackCollapsed?: boolean;
  /** Enable controlled mode for external code state management */
  controlled?: boolean;
  /**
   * When the live-editing engine loads for an editable block:
   *   - `'eager'` (default): load it as soon as the block is editable, and let
   *     `CodeHighlighter` speculatively preload it on first render.
   *   - `'interaction'`: defer the load until the reader hovers, focuses, or
   *     clicks the code, and suppress the speculative preload — so a block the
   *     reader never engages does not fetch the engine chunk at all.
   *
   * Only meaningful for editable blocks (a `CodeControllerContext` exposing
   * `setCode`); ignored otherwise.
   * @default 'eager'
   */
  editActivation?: 'eager' | 'interaction';
  /** Raw code string for simple use cases */
  children?: string;
  /**
   * When to perform syntax highlighting and code processing
   * @default 'idle'
   */
  highlightAfter?: 'init' | 'stream' | 'hydration' | 'idle';
  /**
   * When to enhance the code display with interactivity
   * @default 'idle'
   */
  enhanceAfter?: 'init' | 'stream' | 'hydration' | 'idle';
  /** Force client-side rendering even when server rendering is available */
  forceClient?: boolean;
  /** Defer parsing and populating the AST into memory until the code is enhanced
   * Applies only in production when RSC loading
   * @default 'gzip'
   */
  deferParsing?: 'none' | 'json' | 'gzip';
}
/**
 * Function props for loading and transforming code
 */
export interface CodeFunctionProps {
  /** Function to load code metadata from a URL */
  loadCodeMeta?: LoadCodeMeta;
  /** Function to load specific variant metadata */
  loadVariantMeta?: LoadVariantMeta;
  /** Function to load raw source code and dependencies */
  loadSource?: LoadSource;
  /** Array of source transformers for code processing (e.g., TypeScript to JavaScript) */
  sourceTransformers?: SourceTransformers;
  /** Promise resolving to a source parser for syntax highlighting */
  sourceParser?: Promise<ParseSource>;
  /** Array of source enhancers that run after parsing to enhance the HAST tree */
  sourceEnhancers?: SourceEnhancers;
  /**
   * Optional URL-prefix rewrite forwarded to {@link LoadFileOptions.urlPrefix}.
   * Lets the demo factory translate local `file://` URLs returned by
   * `loadSource` into hosted URLs before they reach the client.
   */
  urlPrefix?: {
    from: string;
    to: string;
  };
}
/**
 * Component and rendering props
 */
export interface CodeRenderingProps<T extends {}> {
  /** Component to render the code content and preview */
  Content: React.ComponentType<ContentProps<T>>;
  /** Additional props passed to the Content component */
  contentProps?: T;
}
/**
 * Client-specific rendering props
 */
export interface CodeClientRenderingProps {
  /** The CodeContent component that renders the code display and syntax highlighting */
  children: React.ReactNode;
  /** Loading placeholder shown while code is being processed */
  fallback?: React.ReactNode;
  /** Skip showing fallback content entirely */
  skipFallback?: boolean;
}
/**
 * Base props containing essential properties shared across CodeHighlighter components and helper functions.
 * This serves as the foundation for other CodeHighlighter-related interfaces.
 */
export interface CodeHighlighterBaseProps<T extends {}> extends CodeIdentityProps, CodeContentProps, CodeLoadingProps, CodeFunctionProps, CodeRenderingProps<T> {
  /**
   * Render-time "collapse to empty": collapse the code block to an empty window so
   * the whole block is hidden until expanded. Threaded into `contentProps` and
   * consumed by `useCode`/`<Pre>`. Runtime-only — the precomputed HAST is
   * unchanged.
   */
  collapseToEmpty?: boolean;
  /**
   * Whether the (collapsible) code block starts expanded. Threaded into
   * `contentProps` so both `useCode` and the loading fallback honor it.
   */
  initialExpanded?: boolean;
}
/**
 * Props for the client-side CodeHighlighter component.
 * Used when rendering happens in the browser with lazy loading and interactive features.
 */
export interface CodeHighlighterClientProps extends CodeIdentityProps, CodeContentProps, Omit<CodeLoadingProps, 'children'>, CodeClientRenderingProps {
  /**
   * When to perform syntax highlighting for performance optimization
   * @default 'hydration'
   */
  highlightAfter?: 'init' | 'hydration' | 'idle';
  enhanceAfter?: 'init' | 'hydration' | 'idle';
  /**
   * The variant/file fallbacks a `ContentLoading` component never renders,
   * consolidated into a single DEFLATE blob (see `compressResidualFallbacks`).
   * The rendered subset crosses plain on `ContentLoading` props; this carries
   * everything else compressed. Decompressed once on the client — using the
   * hoisted rendered text as its preset dictionary — and scattered back onto
   * `Code` before the content decodes. Absent when there is no residual worth
   * compressing.
   */
  residualFallbacks?: CompressedFallback;
}
/**
 * Main props for the CodeHighlighter component.
 * Supports both build-time precomputation and runtime code loading with extensive customization options.
 * Generic type T allows for custom props to be passed to Content and ContentLoading components.
 */
export interface CodeHighlighterProps<T extends {}> extends CodeHighlighterBaseProps<T> {
  /** Component to show while code is being loaded or processed */
  ContentLoading?: React.ComponentType<ContentLoadingProps<T>>;
}
export {};