import { type CompressedFallback } from "./fallbackFormat.mjs";
import type { Code, Fallbacks } from "./types.mjs";
/**
 * The residual fallbacks a `ContentLoading` component never renders, grouped
 * `variant → fileName → FallbackNode[]`. They exist only as the DEFLATE
 * dictionary for decompressing `hastCompressed`, so they ride across the
 * boundary as a single compressed blob rather than inline plain text.
 */
export type ResidualFallbacks = Record<string, Fallbacks>;
/**
 * Residual blobs whose JSON is below this many bytes are left uncompressed —
 * the DEFLATE + base64 framing would only grow such a small payload.
 */
export declare const FALLBACK_COMPRESSION_MIN_BYTES = 128;
/**
 * Build the preset-dictionary text for the residual blob from the *rendered*
 * fallbacks (the subset `ContentLoading` paints, already on the client as plain
 * text). Priming the residual with this text lets DEFLATE backreference the
 * rendered file — most valuable for a near-duplicate sibling like a TypeScript
 * variant of a rendered JavaScript file.
 *
 * Deterministic across server and client: variants and files are visited in
 * sorted key order so both sides build byte-identical dictionaries (a mismatch
 * would otherwise fail the embedded checksum on decode).
 */
export declare function residualDictionaryText(rendered: ResidualFallbacks): string;
/**
 * Compress the residual fallbacks into a single self-describing blob. A single
 * DEFLATE stream deduplicates text shared across the residual files and
 * variants — and against the rendered subset too when `dictionaryText` is
 * supplied (see `residualDictionaryText`).
 *
 * Returns `undefined` when there is nothing worth compressing (no residual, or
 * a residual below the byte threshold), signalling the caller to keep the plain
 * fallbacks inline.
 */
export declare function compressResidualFallbacks(residual: ResidualFallbacks, dictionaryText?: string): CompressedFallback | undefined;
/**
 * Reverse {@link compressResidualFallbacks}. `dictionaryText` must match what
 * was used to compress; the embedded checksum throws on a mismatch rather than
 * yielding a corrupt dictionary.
 */
export declare function decompressResidualFallbacks(blob: CompressedFallback, dictionaryText?: string): ResidualFallbacks;
/**
 * Pull every `fallback` off a (post-strip) `Code` into a `ResidualFallbacks`
 * map, returning a `Code` with those fallbacks removed. After
 * `stripFallbackHastsFromCode` has hoisted the rendered subset, every fallback
 * still on `Code` is residual — so this needs no scope flags.
 *
 * Pure: the input is left untouched; only the variants that lose a fallback are
 * shallow-cloned.
 */
export declare function extractResidualFallbacks(code: Code): {
  wireCode: Code;
  residual: ResidualFallbacks;
};
/**
 * Scatter a decompressed `ResidualFallbacks` map back onto `Code`, restoring
 * each `fallback` to the variant or extra file it came from — the inverse of
 * {@link extractResidualFallbacks}. Reconstructs exactly the in-memory layout a
 * non-consolidated payload would have had, so downstream consumers are unaware
 * the residual ever travelled compressed.
 *
 * `preserveExisting` keeps any `fallback` already on the variant/extra file
 * instead of overwriting it. The hoisted-fallback scatter passes `true`: the
 * hoist is an *initial-paint* dictionary that, for an un-highlighted load, is a
 * raw-string fallback whose text keeps a trailing newline that `buildRootFallback`
 * drops — so it's the WRONG DEFLATE dictionary for a fully-loaded `hastCompressed`
 * source, which already carries its own source-paired (structured) `fallback`.
 * Overwriting that with the hoist makes `decodeHastSource` throw a dictionary
 * mismatch. The hoist is only the dictionary when the variant's own was stripped,
 * so apply it only where one isn't already present. The residual-blob scatter
 * keeps the default (`false`): it always writes onto server-stripped, fallback-less
 * variants, so there is nothing to preserve.
 *
 * Pure: only the variants that regain a fallback are shallow-cloned.
 */
export declare function scatterResidualFallbacks(code: Code, residual: ResidualFallbacks, preserveExisting?: boolean): Code;
/**
 * Reduce every fallback in a rendered-subset map to its collapsed window (see
 * `collapsedVisibleFallback`). Used by `fallbackCollapsed` to hand
 * `ContentLoading` only the on-screen lines while the full fallbacks ride along
 * in the residual blob.
 *
 * `collapsesToEmpty(variantName, fileName)` reports the `oversizedFocus: 'hide'`
 * collapse-to-nothing case (the source's `focusedLines === 0`): such files get
 * an empty collapsed window so the loading UI matches the hydrated render
 * instead of briefly painting the first frame.
 */
export declare function collapseRenderedFallbacks(rendered: ResidualFallbacks, collapsesToEmpty?: (variantName: string, fileName: string) => boolean): ResidualFallbacks;
/**
 * Deep-merge two residual maps (`variant → fileName → fallback`), with `b`
 * winning on conflicts. Used to fold the rendered files' full fallbacks into
 * the residual when `fallbackCollapsed` defers them.
 */
export declare function mergeResidualFallbacks(first: ResidualFallbacks, second: ResidualFallbacks): ResidualFallbacks;