import type { Position } from "./useEditable.mjs";
import type { Code, CollapseMap, ControlledCode, Fallbacks, SourceComments, VariantSource } from "../CodeHighlighter/types.mjs";
import type { FallbackNode } from "../CodeHighlighter/fallbackFormat.mjs";
/**
 * Converts a `VariantSource` (string or HAST) to a plain string. Injected into
 * {@link toControlledCode} so this engine chunk never statically imports
 * `stringOrHastToString` (and its `hastDecompress` dependency): the always-loaded
 * `useCode` shell already has it (via `useCopyFunctionality`/`Pre`) and passes it
 * in, keeping it counted in the shell instead of hoisted into its own chunk.
 */
export type StringOrHastToString = (source: VariantSource, fallback?: FallbackNode[]) => string;
interface ShiftResult {
  comments: SourceComments | undefined;
  collapseMap: CollapseMap | undefined;
}
/**
 * Counts the number of lines in a string and records which 1-indexed lines are
 * empty/whitespace-only, in a single pass, without allocating a line array.
 * `emptyLines` is omitted when no blank lines were found to keep the common
 * case allocation-free.
 */
export declare function analyzeSource(source: string): {
  totalLines: number;
  emptyLines?: number[];
};
/**
 * Shifts 1-indexed comment line numbers after a source edit.
 * Accepts a precomputed `lineDelta` (positive = lines added, negative = lines deleted)
 * and the cursor `position` (0-indexed in the new text) to determine which
 * comments move and by how much.
 *
 * When lines are deleted, comments from the deleted range are collapsed
 * onto the edit line and recorded in a collapseMap so they can be restored
 * if the deletion is undone (lines re-added at the same position).
 *
 * Empty/whitespace-only deleted lines are special: since they had no real
 * content that "shifted upward" into editLine, their comments are pushed
 * to editLine + 1 (like `-end` boundary markers) so the highlighted region
 * shrinks instead of shifting onto the previous line.
 */
export declare function shiftComments(comments: SourceComments | undefined, lineDelta: number, position: Position, existingCollapseMap: CollapseMap | undefined, oldEmptyLines?: number[]): ShiftResult;
/**
 * Converts Code to ControlledCode, normalizing sources and extraFiles entries.
 * VariantSource can be HAST nodes; ControlledCode requires plain strings.
 * VariantExtraFiles allows plain string entries; ControlledVariantExtraFiles
 * requires `{ source }` objects. Without this normalization, parseControlledCode
 * reads `.source` on a string and gets `undefined`, dropping file content.
 */
export declare function toControlledCode(code: Code, activeVariantKey: string | undefined, activeFallbacks: Fallbacks | undefined, toString: StringOrHastToString): ControlledCode;
export {};