/**
 * Static-build pipeline driver for `hotstaq build --static`. Orchestrates
 * the stages defined in design/HS090-static-cli.md:
 *
 *   0. reset output dir
 *   1. parse every .hott file (HS090-3)              ← implemented
 *   2. resolve partials (HS090-15)                    ← stubbed
 *   3. prerender staticRender routes (HS090-19)       ← stubbed
 *   4. emit template stash (HS090-5)                  ← basic impl
 *   5. bundle preambles + runtime via esbuild (HS090-6) ← stubbed
 *   6. consolidate CSS (HS090-7)                      ← stubbed
 *   7. emit index.html shell                          ← basic impl
 *   8. copy assets                                    ← basic impl
 *   9. copy config.json (HS090-18)                    ← basic impl
 *  10. write build-manifest.json (HS090-9)            ← basic impl
 *  11. enforce --strict
 *
 * The "stubbed" stages log a note and skip — HS090-5/-6/-7/-15/-19 fill
 * them in. The skeleton is end-to-end walkable today so apps can start
 * trialling the CLI (they'll get a dist/ with the template stash + a
 * placeholder app.js until the bundler lands).
 */
import { HotSite, HotSiteWebRoute } from "../HotSite";
import { HotLog } from "../HotLog";
import { HottModule } from "./types";
export interface StaticBuildOptions {
    /** Output directory. Defaults to "./dist". */
    out?: string;
    /** "production" | "development". Defaults to "production". */
    mode?: "production" | "development";
    /** Escalate warnings to errors. */
    strict?: boolean;
    /** Print per-route size breakdown. */
    verbose?: boolean;
    /** Resolve file: paths in the HotSite relative to this directory. */
    cwd?: string;
    /**
     * Directory served as the site's public root. Defaults to "./public"
     * under cwd. Static assets outside this directory are not copied.
     */
    publicDir?: string;
    /** Optional logger; defaults to stdout. */
    logger?: HotLog;
}
export interface BuildWarning {
    code: string;
    message: string;
    /** Optional HotSite path or source location. */
    where?: string;
}
export interface ManifestEntry {
    path: string;
    size: number;
    sha256: string;
}
/**
 * Build output metadata. Describes what was emitted (file hashes, entry
 * filenames) and embeds the full HotSite that drove the build so
 * downstream deploy tooling has a single source of truth for routes,
 * apiClients, cssFiles, jsFiles etc. — no duplicated/derived fields.
 */
export interface BuildManifest {
    /** Schema version for downstream deploy tooling. Bumped on shape changes. */
    manifestVersion: 1;
    /** ISO timestamp. */
    builtAt: string;
    /** Build mode. */
    mode: "production" | "development";
    /** hotstaq package version that emitted this manifest. */
    hotstaqVersion: string;
    /** Canonical entry filenames relative to the dist root. */
    entry: {
        html: string;
        js: string;
        css: string;
    };
    /** Full list of emitted files with sizes + hashes, sorted by path. */
    files: ManifestEntry[];
    /**
     * The HotSite this build was driven from. Includes app name,
     * version, web.{app}.routes, web.{app}.apiClient, apis.* etc. —
     * consumers that need route or API-client info should walk this
     * rather than reading duplicated derived fields.
     */
    hotSite: HotSite;
}
export interface CompiledRoute {
    route: HotSiteWebRoute;
    absFile: string;
    module: HottModule;
}
/**
 * Resolved API client wiring for one web app. Populated during build if
 * HotSite provides enough info to bundle the generated client.
 */
export interface ResolvedApiClient {
    /** Path the script is served at under dist/ (e.g. "js/freelight_authWeb_AppAPI.js"). */
    distPath: string;
    /** window.{libraryName} set as a side effect of loading the script. */
    libraryName: string;
    /** {libraryName}.{apiName} is the class the runtime instantiates. */
    apiName: string;
    /** Base URL passed to the client constructor. */
    baseUrl: string;
}
/**
 * Orchestrator. Callers: `new HotStaticBuilder(site, opts).build()`.
 */
export declare class HotStaticBuilder {
    readonly site: HotSite;
    readonly opts: Required<Pick<StaticBuildOptions, "out" | "mode" | "strict" | "verbose" | "cwd" | "publicDir">>;
    readonly logger: HotLog;
    readonly warnings: BuildWarning[];
    readonly manifestFiles: ManifestEntry[];
    readonly compiledRoutes: Map<string, CompiledRoute[]>;
    readonly resolvedApiClients: Map<string, ResolvedApiClient>;
    readonly resolvedPartials: Map<string, string>;
    /** HS090-16: per-route chunk entries (relative dist path). */
    readonly routeChunks: Map<string, string>;
    /** HS090-15 build-time expansion: shared across partial expansions. */
    private readonly moduleRegistry;
    /**
     * v0.9.1 runtime-partial-inline: compiled source of each partial
     * reachable from any Hot.include(path, args) call site, keyed by
     * absolute file path. Reused across call sites so identical partials
     * don't recompile.
     */
    private readonly runtimePartialSources;
    /** HS090-15: shell-head-hoisted <link>/<script> references from modules. */
    private readonly shellCss;
    private readonly shellJs;
    private readonly shellComponents;
    constructor(site: HotSite, opts?: StaticBuildOptions);
    build(): Promise<void>;
    resetOutputDir(): Promise<void>;
    parseAllHottFiles(): Promise<void>;
    /**
     * HS090-19: run staticRender: true route preambles in Node against
     * their fixture data and bake the resulting HTML into the route's
     * template. The runtime still re-runs the preamble on mount for
     * hydration — baked HTML exists purely for crawlers that see the
     * first-paint response.
     *
     * MVP supports JSON `fixtures` only. `fixturesApi` and
     * `fixturesScript` are accepted by the schema but will warn and
     * skip prerender (route falls back to eager template mode).
     */
    prerenderStaticRoutes(): Promise<void>;
    private loadFixtureData;
    private runPreambleInNode;
    /**
     * HS090-15: resolve every literal Hot.include() target hoisted by
     * the parser into a compiled partial. Also honours the explicit
     * `web.{appName}.partials` manifest (takes precedence; its `src` is
     * the canonical path for a given `id`). Partials can recursively
     * include other partials — we walk until a fixed point or we hit
     * a cycle (cycles warn and break).
     */
    resolvePartials(): Promise<void>;
    private tryExpand;
    /**
     * Resolve a path used by a nested Hot.include() at build time. The
     * partial's own .hott file location (fromFile) is the primary anchor;
     * we try relative to that first, then fall back to publicDir + cwd.
     */
    private resolveNestedPartialPath;
    /**
     * Scan `<publicDir>/hotstaq_modules/` recursively for every installed
     * module index.js and load it into this.moduleRegistry so partial
     * resolution can use the name → path mappings before any preamble
     * has executed. Errors on a single module are logged and skipped —
     * one bad install shouldn't block the rest.
     */
    private preloadInstalledModules;
    /**
     * Resolve a partial path. Explicit manifest paths are relative to
     * publicDir (matching docs), while Hot.include() literals in .hott
     * preambles use `./relative` form. Try publicDir first, then cwd
     * so node_modules-relative paths still work.
     */
    private buildAssetCollector;
    private resolvePartialPath;
    /**
     * HS090 jsFiles wiring: for each web.{appName}.jsFiles entry, copy
     * the file into dist (preserving a sensible relative layout under
     * `js/`) and queue a shell <script> tag. Apps use this to pull in
     * the legacy HotStaq.min.js client when they need HotStaqWeb-based
     * components (admin-panel and friends).
     */
    resolveJsFiles(): Promise<void>;
    /**
     * HS090-8: for each web app with an apiClient config (or one that can
     * be inferred from HotSite.apis), copy the generated client file into
     * dist/js/ and record how the entry script should wire it up.
     */
    resolveApiClients(): Promise<void>;
    emitTemplateStash(): string;
    /**
     * HS090-5 / HS090-16: emit a separate chunk file for every lazy or
     * never route. The chunk is a plain script that injects the
     * template into the DOM and calls registerRoute() via the runtime
     * global the entry set up (window.__HS090_RT__).
     */
    bundleLazyRouteChunks(): Promise<void>;
    private generateLazyChunkSource;
    /**
     * v0.9.1 runtime-partial-inline: compile every partial referenced
     * by a Hot.include(path, args) call site and cache its HottModule.
     * generateEntrySource() splices these into each caller's preamble
     * as local async functions so the partial body runs at mount with
     * the caller's live variables in scope.
     *
     * Partials with no args (argless Hot.include) continue to use the
     * HS090-15 stash path — this method leaves those alone.
     */
    prepareRuntimePartials(): Promise<void>;
    /**
     * Given a route's compiled preamble source, rewrite every
     * `hotCtx.__includePartial(stashId, argsExpr)` placeholder (emitted
     * by rewrite-preamble when Hot.include has args) into a call to a
     * locally-declared async function. Returns the modified body plus
     * the function declarations to prepend inside the preamble closure.
     */
    private buildRuntimeInlinedPreamble;
    bundleAppJs(): Promise<{
        path: string;
        hash: string;
        size: number;
    }>;
    /**
     * Build the per-app entry source that registers every route's
     * preamble + inline scripts against the runtime, then calls start().
     */
    private generateEntrySource;
    bundleAppCss(): Promise<{
        path: string;
        hash: string;
        size: number;
    }>;
    emitIndexHtml(stash: string, appJs: {
        path: string;
    }, appCss: {
        path: string;
    }): Promise<void>;
    copyAssets(): Promise<void>;
    copyConfig(): Promise<void>;
    writeManifest(entry: {
        html: string;
        js: string;
        css: string;
    }): Promise<void>;
    absOut(): string;
    writeHashedAsset(name: string, ext: string, body: string): Promise<{
        path: string;
        hash: string;
        size: number;
    }>;
    writeOutputFile(relPath: string, body: string): Promise<void>;
    copyTreeSkipping(srcDir: string, dstDir: string, skipExts: string[]): Promise<void>;
    readHotStaqPackageJson(): Promise<{
        version?: string;
    }>;
    printSizeReport(): void;
    private note;
    private fatal;
}
/**
 * Wrap a rewritten preamble source into the `async (hotCtx) => { ... }`
 * form the runtime calls. An empty preamble compiles to a no-op.
 */
export declare function preambleToAsyncFn(src: string): string;
export declare function templateIdForRoute(appName: string, routePath: string): string;
//# sourceMappingURL=HotStaticBuilder.d.ts.map