/** * Bundler plugin bridge. * * @remarks * Translates an array of `EcoBuildPlugin` instances (the runtime-agnostic * plugin contract used by Ecopages processors and integrations) into * the bundler's native `Plugin` array. The bridge exposes the same * three hooks (`onResolve`, `onLoad`, `module`) the `EcoBuildPlugin` * contract uses, but maps them to the bundler's `resolveId`/`load` * hooks. * * The shared `EcoBuildPlugin` contract stays the boundary between * integrations and bundler backends. * * **Namespace handling.** * * The shared `EcoBuildPlugin` contract scopes `onResolve`/`onLoad` * handlers with a `namespace` string. The bundler encodes namespaces * into the module id (no separate field). The bridge prepends * `:` to the resolved id when the result includes a * namespace, and matches `onLoad`/`onResolve` filters against that * prefix. The bridge strips the prefix before forwarding the id back * to the callback so plugin code keeps seeing the same `path` shape * it did on the historical contract. * * **Plugin ordering is semantically significant.** * * The bundler's `resolveId` and `load` are "first" hooks: the first * plugin that returns a non-null value wins. Because the bridge * translates each `EcoBuildPlugin` into its own bundler plugin and * preserves the array order, the position of each plugin in the * `plugins` array determines its priority: * * - **Index 0** has the highest priority. * - **Last index** has the lowest priority. * * When adding new integrations or processors, ensure security-critical * plugins (e.g. `ecopages-client-graph-boundary`) are placed **before** * general-purpose loaders in the array so they always get first refusal * on every source file. */ import type { Plugin } from 'rolldown'; import type { EcoSourceTransform } from '../../plugins/source-transform.js'; import type { EcoBuildPlugin } from '../contracts/build-types.js'; /** * Creates a Rolldown `Plugin` array that drives the supplied * `EcoBuildPlugin` instances. * * All eco plugins are merged into a single Rolldown plugin to minimize * Rust→JS FFI overhead. Rolldown calls every hook for every module when * there is no static filter, so N separate plugins would cause N * `resolveId` + N `load` calls per module. Consolidating into one * plugin reduces that to 1 call each, with JavaScript-side filtering * routing to the correct eco plugin callback. * * Plugin ordering is preserved: registrations from earlier eco plugins * are checked before registrations from later ones, matching the * original per-plugin priority semantics. * * @remarks * Rolldown re-fires `buildStart` on each build, so registrations and the * virtual-module counter are cleared before every `setup` pass — otherwise * handlers accumulate when bridge plugins are reused. * * @param plugins - `EcoBuildPlugin` instances registered for this build. * @param contextRoot - Project root used to resolve relative load paths. * @param sourceTransforms - Optional app-owned transforms applied after a matching * `onLoad` handler returns module contents. Browser builds pass * {@link getAppSourceTransforms | app source transforms} here so metadata injection * still runs on output rewritten by boundary/runtime plugins. Virtual modules, * CSS, and asset loads are skipped. */ export declare function createRolldownPluginBridge(plugins: EcoBuildPlugin[], contextRoot: string, sourceTransforms?: readonly EcoSourceTransform[]): Plugin[];