import { type ManifestFonts } from "./ssr-fonts"; type Send = (msg: Record) => void; interface BundleClientMessage { type: "bundle_client"; call_id: string; /** * Project-relative directory holding the route tree * (`/**​/page.tsx`). Defaults to `"app"` when the host * doesn't send it (older hosts, or the default single-`app/` * layout). The full-stack app that namespaces its frontend under a * subdir — e.g. `web/app` via `discoverAppRoutes({appDir:"web/app"})` * — sends the same dir here so the client bundler and the SSR * manifest agree on where the routes live. */ app_dir?: string; } /** * Fail the CLIENT bundle when a `server-only` module is resolved — meaning it * was pulled into a page/layout's client graph. Page/layout modules (and their * transitive imports) are bundled for hydration, so a literal secret or server * config in that graph would ship to the browser (the `process.env.*` `define` * only neutralizes env reads). Authors mark such modules with * `import "@pylonsync/functions/server-only"`; this turns an accidental client * import into a loud build failure that names the offending importer. */ export declare function assertNotServerOnly(specifier: string, importer: string): void; /** * Every route-level `loading` module under the app dir, as project-relative * component paths (`app/dashboard/loading`), sorted for a stable build. * * Unlike not-found / error, these get NO client entry of their own — see * `generateLoadingRegistry` for why. */ export declare function discoverLoadingModules(fs: any, path: any, cwd: string, appDirRel: string): string[]; /** * The module the client runtime imports as `./loading-registry`: every * loading.tsx in the app, keyed by component path so the runtime can walk up * from a destination route to its nearest one — the same nearest-ancestor rule * the server's findBoundary applies. * * Statically imported, so these land in the SHARED chunk rather than shipping * as route entries the way not-found / error do. A loading state exists to * acknowledge a click that is already waiting on the network; fetching a chunk * to render it would put it behind the very delay it covers. * * Route groups need no special handling: a page under `app/(dash)/settings` * resolves against `app/(dash)/loading` by path, exactly as it does on the * server. */ export declare function generateLoadingRegistry(components: string[]): string; /** * Manifest schema. One entry per route, indexed by the same * project-relative component path the SSR side passes through. * `file` is the entry chunk, `imports` is the transitive set of * shared chunks the browser needs to load BEFORE the entry runs * — that's the modulepreload list. * * Paths in the manifest are relative to `.pylon/client-build/` so * the Rust host can serve them under `/_pylon/build/` with * no rewriting. */ export interface PylonBundleManifest { /** Build identity — bumps every successful build. */ build_id: string; /** Output root, relative to cwd (always `.pylon/client-build`). */ outdir: string; /** Public URL prefix the Rust host serves chunks under. */ public_prefix: string; /** routeComponentPath → file + imports for that route. */ routes: Record; /** Self-hosted fonts (next/font parity): structured `@font-face`s + the * `:root` CSS variables + the woff2 files to preload. Global (route- * independent); rendered into every SSR `` against `public_prefix`. * Absent when the app declares no `font({...})`. */ fonts?: ManifestFonts; /** Set when the Tailwind compile failed for this build: the pages are * serving WITHOUT styles. Dev surfaces it as an on-page banner (see * pylonDevHud) — a silent unstyled page reads as a CSS bug, not a * build failure, and costs real debugging time. */ css_error?: string; } /** Result of an in-process build — same shape the protocol returns. */ export interface BuildOutput { manifestPath: string; outdir: string; } /** * Run the bundler in-process and return the manifest path + outdir. * Used from `handleBundleClient` (protocol RPC path from Rust) AND * from `getManifest` (in-process SSR path). */ export declare function buildClientBundle(appDirRel?: string): Promise; /** * Compile `app/globals.css` through Tailwind v4 (`@tailwindcss/cli`) * if both are present. Returns the relative output path (under * outdir) when produced, else null. Skipped silently when the * project hasn't opted in to Tailwind — we don't want every SSR * project to need Tailwind installed. */ export declare function buildTailwind(fs: any, path: any, cwd: string, outdir: string, appDirRel: string): Promise; /** * Return the bundle manifest. If a fresh manifest exists on disk, * use it (caching parse output across requests). Otherwise build * the bundle in-process (deduped by `buildClientBundle`) and read. * * Called from `ssr-runtime.ts` per-request, so the disk-stat fast * path matters. Bun's `fs.statSync` is a ~5µs syscall; cheap enough * that we don't gate it on a flag. */ export declare function getManifest(): Promise; /** * Protocol entry. Builds + responds. Rust calls this via the * `bundle_client` RPC; on success the response carries both * the manifest path (so Rust can load it if it wants, today it * doesn't) and the outdir (so `/_pylon/build/` serves the * right tree). */ export declare function handleBundleClient(msg: BundleClientMessage, send: Send): Promise; export {};