@ecopages/core 0.2.0-beta.26 → 0.2.0-beta.28

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (177) hide show
  1. package/README.md +1 -1
  2. package/package.json +98 -74
  3. package/src/adapters/bun/server-adapter.js +2 -2
  4. package/src/adapters/node/server-adapter.js +2 -2
  5. package/src/adapters/shared/hmr-entrypoint-registrar.d.ts +10 -0
  6. package/src/adapters/shared/hmr-entrypoint-registrar.js +34 -10
  7. package/src/adapters/shared/runtime-server-lifecycle.js +1 -1
  8. package/src/adapters/shared/server-static-builder.d.ts +2 -1
  9. package/src/adapters/shared/server-static-builder.js +16 -14
  10. package/src/adapters/shared/shared-hmr-manager.d.ts +11 -4
  11. package/src/adapters/shared/shared-hmr-manager.js +22 -3
  12. package/src/build/README.md +92 -46
  13. package/src/build/app-build-manifest-runtime.d.ts +28 -2
  14. package/src/build/app-build-manifest-runtime.js +26 -10
  15. package/src/build/{browser-runtime-plugin.d.ts → browser/browser-runtime-plugin.d.ts} +1 -1
  16. package/src/build/{browser-runtime-plugin.js → browser/browser-runtime-plugin.js} +1 -1
  17. package/src/build/{jsx-ownership-plugins.d.ts → browser/jsx-ownership-plugins.d.ts} +2 -2
  18. package/src/build/{jsx-ownership-plugins.js → browser/jsx-ownership-plugins.js} +2 -2
  19. package/src/build/build-adapter.d.ts +18 -21
  20. package/src/build/build-adapter.js +8 -43
  21. package/src/build/{build-input-fingerprint.d.ts → cache/build-input-fingerprint.d.ts} +3 -3
  22. package/src/build/cache/cache-constants.d.ts +4 -0
  23. package/src/build/cache/cache-constants.js +6 -0
  24. package/src/build/cache/cache-keys.d.ts +22 -0
  25. package/src/build/cache/cache-keys.js +63 -0
  26. package/src/build/{dev-browser-script-cache.d.ts → cache/dev-browser-script-cache.d.ts} +2 -2
  27. package/src/build/{dev-browser-script-cache.js → cache/dev-browser-script-cache.js} +4 -4
  28. package/src/build/{pages-unified-graph-build.d.ts → cache/pages-unified-graph-build.d.ts} +1 -1
  29. package/src/build/{pages-unified-graph-build.js → cache/pages-unified-graph-build.js} +18 -26
  30. package/src/build/{production-build-cache.d.ts → cache/production-build-cache.d.ts} +1 -1
  31. package/src/build/{production-build-cache.js → cache/production-build-cache.js} +2 -2
  32. package/src/build/{server-entry-build-cache.d.ts → cache/server-entry-build-cache.d.ts} +3 -4
  33. package/src/build/{server-entry-build-cache.js → cache/server-entry-build-cache.js} +16 -12
  34. package/src/build/{build-contracts.d.ts → contracts/build-contracts.d.ts} +1 -2
  35. package/src/build/contracts/build-manifest.d.ts +90 -0
  36. package/src/build/{build-manifest.js → contracts/build-manifest.js} +2 -2
  37. package/src/build/{rolldown-adapter-helpers.d.ts → rolldown/rolldown-adapter-helpers.d.ts} +20 -3
  38. package/src/build/{rolldown-adapter-helpers.js → rolldown/rolldown-adapter-helpers.js} +26 -6
  39. package/src/build/{rolldown-build-adapter.d.ts → rolldown/rolldown-build-adapter.d.ts} +1 -1
  40. package/src/build/{rolldown-plugin-bridge.d.ts → rolldown/rolldown-plugin-bridge.d.ts} +2 -2
  41. package/src/build/{rolldown-plugin-bridge.js → rolldown/rolldown-plugin-bridge.js} +1 -1
  42. package/src/build/{rolldown-source-transform-pass.d.ts → rolldown/rolldown-source-transform-pass.d.ts} +1 -1
  43. package/src/build/{rolldown-source-transform-pass.js → rolldown/rolldown-source-transform-pass.js} +4 -1
  44. package/src/build/{runtime-build-output-normalizer.js → rolldown/runtime-build-output-normalizer.js} +2 -2
  45. package/src/build/{build-profile-options.d.ts → runtime/build-profile-options.d.ts} +2 -2
  46. package/src/build/runtime/build-request-identity.d.ts +17 -0
  47. package/src/build/runtime/build-request-identity.js +54 -0
  48. package/src/build/runtime/build-request-policy.d.ts +59 -0
  49. package/src/build/runtime/build-request-policy.js +46 -0
  50. package/src/build/{build-runtime.d.ts → runtime/build-runtime.d.ts} +8 -4
  51. package/src/build/{build-runtime.js → runtime/build-runtime.js} +11 -11
  52. package/src/build/{deduping-build-executor.d.ts → runtime/deduping-build-executor.d.ts} +2 -9
  53. package/src/build/runtime/deduping-build-executor.js +34 -0
  54. package/src/build/{parallel-build-executor.d.ts → runtime/parallel-build-executor.d.ts} +1 -1
  55. package/src/build/{serialized-build-executor.d.ts → runtime/serialized-build-executor.d.ts} +1 -1
  56. package/src/config/config-builder.d.ts +1 -1
  57. package/src/diagnostics/startup-trace.d.ts +49 -2
  58. package/src/diagnostics/startup-trace.js +140 -8
  59. package/src/eco/eco.js +2 -2
  60. package/src/eco/eco.utils.d.ts +1 -1
  61. package/src/eco/eco.utils.js +1 -1
  62. package/src/hmr/client/hmr-runtime.js +2 -2
  63. package/src/hmr/hmr-file-change-prep.d.ts +10 -0
  64. package/src/hmr/hmr-file-change-prep.js +17 -0
  65. package/src/plugins/alias-resolver-plugin.d.ts +1 -1
  66. package/src/plugins/eco-component-meta-plugin.d.ts +1 -1
  67. package/src/plugins/foreign-jsx-override-plugin.d.ts +1 -1
  68. package/src/plugins/integration-plugin.d.ts +16 -5
  69. package/src/plugins/integration-plugin.js +11 -1
  70. package/src/plugins/processor.d.ts +36 -8
  71. package/src/plugins/source-transform.d.ts +1 -1
  72. package/src/route-renderer/GRAPH.md +22 -28
  73. package/src/route-renderer/README.md +12 -7
  74. package/src/route-renderer/orchestration/{document-shell-render.service.d.ts → document-shell/document-shell-render.service.d.ts} +19 -2
  75. package/src/route-renderer/orchestration/{document-shell-render.service.js → document-shell/document-shell-render.service.js} +28 -0
  76. package/src/route-renderer/orchestration/{layout-shell-props.service.d.ts → document-shell/layout-shell-props.service.d.ts} +1 -1
  77. package/src/route-renderer/orchestration/{component-render-context.d.ts → foreign-child/component-render-context.d.ts} +5 -5
  78. package/src/route-renderer/orchestration/{component-render-context.js → foreign-child/component-render-context.js} +1 -1
  79. package/src/route-renderer/orchestration/{render-output.utils.d.ts → foreign-child/foreign-child-output.utils.d.ts} +15 -7
  80. package/src/route-renderer/orchestration/{render-output.utils.js → foreign-child/foreign-child-output.utils.js} +31 -26
  81. package/src/route-renderer/orchestration/{foreign-subtree-execution.service.d.ts → foreign-child/foreign-subtree-execution.service.d.ts} +5 -5
  82. package/src/route-renderer/orchestration/{foreign-subtree-execution.service.js → foreign-child/foreign-subtree-execution.service.js} +7 -3
  83. package/src/route-renderer/orchestration/foreign-child/owning-renderer-resolution.d.ts +19 -0
  84. package/src/route-renderer/orchestration/foreign-child/owning-renderer-resolution.js +35 -0
  85. package/src/route-renderer/orchestration/integration-renderer.d.ts +14 -97
  86. package/src/route-renderer/orchestration/integration-renderer.js +90 -247
  87. package/src/route-renderer/orchestration/integration-renderer.test-fixtures.d.ts +75 -0
  88. package/src/route-renderer/orchestration/integration-renderer.test-fixtures.js +177 -0
  89. package/src/route-renderer/orchestration/{component-graph-collectors.d.ts → ownership-graph/component-graph-collectors.d.ts} +4 -4
  90. package/src/route-renderer/orchestration/{component-graph-collectors.js → ownership-graph/component-graph-collectors.js} +1 -1
  91. package/src/route-renderer/orchestration/{component-graph.d.ts → ownership-graph/component-graph.d.ts} +1 -3
  92. package/src/route-renderer/orchestration/{component-graph.js → ownership-graph/component-graph.js} +0 -2
  93. package/src/route-renderer/orchestration/{ownership-validation.service.d.ts → ownership-graph/ownership-validation.service.d.ts} +2 -2
  94. package/src/route-renderer/orchestration/{ownership-validation.service.js → ownership-graph/ownership-validation.service.js} +3 -4
  95. package/src/route-renderer/orchestration/{global-injector-assets.service.d.ts → page-browser-graph/global-injector-assets.service.d.ts} +3 -3
  96. package/src/route-renderer/orchestration/{global-injector-assets.service.js → page-browser-graph/global-injector-assets.service.js} +2 -2
  97. package/src/route-renderer/orchestration/{page-browser-graph-contribution.loader.d.ts → page-browser-graph/page-browser-graph-contribution.loader.d.ts} +1 -1
  98. package/src/route-renderer/orchestration/page-browser-graph/page-browser-graph-merge.utils.d.ts +12 -0
  99. package/src/route-renderer/orchestration/page-browser-graph/page-browser-graph-merge.utils.js +29 -0
  100. package/src/route-renderer/orchestration/page-browser-graph/page-browser-graph-session.d.ts +106 -0
  101. package/src/route-renderer/orchestration/page-browser-graph/page-browser-graph-session.js +436 -0
  102. package/src/route-renderer/orchestration/{page-browser-graph.service.d.ts → page-browser-graph/page-browser-graph.service.d.ts} +12 -6
  103. package/src/route-renderer/orchestration/{page-browser-graph.service.js → page-browser-graph/page-browser-graph.service.js} +91 -42
  104. package/src/route-renderer/orchestration/{processed-asset-dedupe.d.ts → page-browser-graph/processed-asset-dedupe.d.ts} +1 -1
  105. package/src/route-renderer/orchestration/{integration-route-render-adapter.d.ts → route-pipeline/integration-route-render-adapter.d.ts} +3 -10
  106. package/src/route-renderer/orchestration/{integration-route-render-adapter.js → route-pipeline/integration-route-render-adapter.js} +1 -3
  107. package/src/route-renderer/orchestration/route-pipeline/marker-artifact.utils.d.ts +6 -0
  108. package/src/route-renderer/orchestration/route-pipeline/marker-artifact.utils.js +27 -0
  109. package/src/route-renderer/orchestration/{route-html-finalization.service.d.ts → route-pipeline/route-html-finalization.service.d.ts} +2 -3
  110. package/src/route-renderer/orchestration/route-pipeline/route-html-finalization.service.js +21 -0
  111. package/src/route-renderer/orchestration/{route-prepared-options.builder.d.ts → route-pipeline/route-prepared-options.builder.d.ts} +3 -4
  112. package/src/route-renderer/orchestration/{route-prepared-options.builder.js → route-pipeline/route-prepared-options.builder.js} +3 -12
  113. package/src/route-renderer/orchestration/{route-prepared-options.utils.js → route-pipeline/route-prepared-options.utils.js} +1 -1
  114. package/src/route-renderer/orchestration/{route-render-orchestrator.d.ts → route-pipeline/route-render-orchestrator.d.ts} +8 -17
  115. package/src/route-renderer/orchestration/{route-render-orchestrator.js → route-pipeline/route-render-orchestrator.js} +12 -19
  116. package/src/route-renderer/orchestration/string-markup-renderer.js +1 -1
  117. package/src/services/assets/asset-processing-service/asset-processing.service.js +1 -1
  118. package/src/services/assets/asset-processing-service/assets.types.d.ts +1 -1
  119. package/src/services/assets/asset-processing-service/browser-runtime-asset.factory.d.ts +1 -1
  120. package/src/services/assets/asset-processing-service/processors/base/base-script-processor.d.ts +0 -2
  121. package/src/services/assets/asset-processing-service/processors/base/base-script-processor.js +2 -15
  122. package/src/services/assets/asset-processing-service/processors/script/content-script.processor.js +1 -1
  123. package/src/services/assets/browser-bundle.service.d.ts +27 -31
  124. package/src/services/assets/browser-bundle.service.js +12 -23
  125. package/src/services/html/html-transformer.service.js +1 -1
  126. package/src/services/invalidation/development-invalidation.service.d.ts +5 -0
  127. package/src/services/invalidation/development-invalidation.service.js +8 -9
  128. package/src/services/module-loading/app-server-module-transpiler.service.d.ts +8 -0
  129. package/src/services/module-loading/app-server-module-transpiler.service.js +1 -7
  130. package/src/services/module-loading/page-module-import.service.d.ts +1 -1
  131. package/src/services/module-loading/page-module-import.service.js +40 -28
  132. package/src/services/module-loading/route-module-build-cache.store.js +1 -1
  133. package/src/services/module-loading/route-module-build-manifest.d.ts +2 -9
  134. package/src/services/module-loading/route-module-build-manifest.js +12 -43
  135. package/src/services/module-loading/server-module-transpiler.service.d.ts +1 -1
  136. package/src/static-site-generator/README.md +1 -1
  137. package/src/static-site-generator/production-page-browser-graph-prebuild.d.ts +28 -0
  138. package/src/static-site-generator/production-page-browser-graph-prebuild.js +22 -0
  139. package/src/static-site-generator/static-build-invalidation.d.ts +2 -2
  140. package/src/static-site-generator/static-build-invalidation.js +3 -3
  141. package/src/static-site-generator/static-site-generator.js +23 -1
  142. package/src/types/internal-types.d.ts +10 -4
  143. package/src/types/public-types.d.ts +59 -10
  144. package/src/watchers/project-watcher.d.ts +3 -3
  145. package/src/watchers/project-watcher.js +15 -5
  146. package/src/build/build-manifest.d.ts +0 -33
  147. package/src/build/deduping-build-executor.js +0 -56
  148. package/src/build/runtime-build-executor.d.ts +0 -14
  149. package/src/build/runtime-build-executor.js +0 -16
  150. package/src/route-renderer/orchestration/declared-ownership-graph.d.ts +0 -1
  151. package/src/route-renderer/orchestration/declared-ownership-graph.js +0 -8
  152. package/src/route-renderer/orchestration/route-html-finalization.service.js +0 -26
  153. package/src/route-renderer/orchestration/template-serialization.d.ts +0 -38
  154. package/src/route-renderer/orchestration/template-serialization.js +0 -45
  155. /package/src/build/{browser-runtime-manifest.d.ts → browser/browser-runtime-manifest.d.ts} +0 -0
  156. /package/src/build/{browser-runtime-manifest.js → browser/browser-runtime-manifest.js} +0 -0
  157. /package/src/build/{browser-runtime-plugin-helpers.d.ts → browser/browser-runtime-plugin-helpers.d.ts} +0 -0
  158. /package/src/build/{browser-runtime-plugin-helpers.js → browser/browser-runtime-plugin-helpers.js} +0 -0
  159. /package/src/build/{lit-static-render-worker-context.d.ts → browser/lit-static-render-worker-context.d.ts} +0 -0
  160. /package/src/build/{lit-static-render-worker-context.js → browser/lit-static-render-worker-context.js} +0 -0
  161. /package/src/build/{build-input-fingerprint.js → cache/build-input-fingerprint.js} +0 -0
  162. /package/src/build/{build-contracts.js → contracts/build-contracts.js} +0 -0
  163. /package/src/build/{build-types.d.ts → contracts/build-types.d.ts} +0 -0
  164. /package/src/build/{build-types.js → contracts/build-types.js} +0 -0
  165. /package/src/build/{rolldown-build-adapter.js → rolldown/rolldown-build-adapter.js} +0 -0
  166. /package/src/build/{rolldown-build-invocation-metrics.d.ts → rolldown/rolldown-build-invocation-metrics.d.ts} +0 -0
  167. /package/src/build/{rolldown-build-invocation-metrics.js → rolldown/rolldown-build-invocation-metrics.js} +0 -0
  168. /package/src/build/{runtime-build-output-normalizer.d.ts → rolldown/runtime-build-output-normalizer.d.ts} +0 -0
  169. /package/src/build/{server-side-css-shim-plugin.d.ts → rolldown/server-side-css-shim-plugin.d.ts} +0 -0
  170. /package/src/build/{server-side-css-shim-plugin.js → rolldown/server-side-css-shim-plugin.js} +0 -0
  171. /package/src/build/{build-profile-options.js → runtime/build-profile-options.js} +0 -0
  172. /package/src/build/{parallel-build-executor.js → runtime/parallel-build-executor.js} +0 -0
  173. /package/src/build/{serialized-build-executor.js → runtime/serialized-build-executor.js} +0 -0
  174. /package/src/route-renderer/orchestration/{layout-shell-props.service.js → document-shell/layout-shell-props.service.js} +0 -0
  175. /package/src/route-renderer/orchestration/{page-browser-graph-contribution.loader.js → page-browser-graph/page-browser-graph-contribution.loader.js} +0 -0
  176. /package/src/route-renderer/orchestration/{processed-asset-dedupe.js → page-browser-graph/processed-asset-dedupe.js} +0 -0
  177. /package/src/route-renderer/orchestration/{route-prepared-options.utils.d.ts → route-pipeline/route-prepared-options.utils.d.ts} +0 -0
@@ -4,49 +4,94 @@ The build layer is the bundler contract for Ecopages. One bundled adapter is the
4
4
 
5
5
  ## Mental Model
6
6
 
7
- Three concentric shapes, plus profile executors and a plugin injector:
8
-
9
- | Shape | Lives in | Purpose |
10
- | -------------------------- | ------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
11
- | `BuildAdapter` | `build-adapter.ts` | Low-level backend. Two implementations: the bundled adapter (the real bundler) and `ViteHostBuildAdapter` (a host-owned boundary marker that throws on direct use). |
12
- | `BuildRuntime` | `build-runtime.ts` | Profile-based executor registry. Single entry point on `appConfig.runtime.buildRuntime`. |
13
- | `BuildExecutor` | `build-contracts.ts` | Narrower runtime facade. Only `build` is exposed. Retrieved via `buildRuntime.getProfile(...)`. |
14
- | `SerializedBuildExecutor` | `serialized-build-executor.ts` | FIFO queue around any `BuildExecutor`. Used for server-entry single-flight ordering. |
15
- | `ParallelBuildExecutor` | `parallel-build-executor.ts` | Concurrency-limited wrapper for independent route-module and HMR browser builds. |
16
- | `withBuildExecutorPlugins` | `build-adapter.ts` | Merges app-owned plugins into every `build` call. The single point of plugin injection. |
7
+ Three concentric shapes, plus profile executors and request policy:
8
+
9
+ | Shape | Lives in | Purpose |
10
+ | --------------------------- | -------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
11
+ | `BuildAdapter` | `build-adapter.ts` | Low-level backend. Two implementations: the bundled adapter (the real bundler) and `ViteHostBuildAdapter` (a host-owned boundary marker that throws on direct use). |
12
+ | `BuildRuntime` | `runtime/build-runtime.ts` | Profile-based executor registry. Scheduling, concurrency, and dedupe only. |
13
+ | `BuildExecutor` | `contracts/build-contracts.ts` | Narrower runtime facade. Only `build` is exposed. Retrieved via `buildRuntime.getProfile(...)`. |
14
+ | `build-request-policy.ts` | `runtime/build-request-policy.ts` | Assembles complete `BuildOptions` before scheduling. Server: plugins + JSX ownership. Browser: plugins + source transforms + transpile overlay. |
15
+ | `build-request-identity.ts` | `runtime/build-request-identity.ts` | Canonical request identity for in-flight and request-scope dedupe. |
16
+ | `SerializedBuildExecutor` | `runtime/serialized-build-executor.ts` | FIFO queue around any `BuildExecutor`. Used for server-entry single-flight ordering. |
17
+ | `ParallelBuildExecutor` | `runtime/parallel-build-executor.ts` | Concurrency-limited wrapper for independent route-module and HMR browser builds. |
17
18
 
18
19
  Plus one translation bridge:
19
20
 
20
- - `rolldown-plugin-bridge.ts` — converts the runtime-agnostic `EcoBuildPlugin[]` array (the contract integrations and processors register) into the bundler's native `Plugin` array. Each `EcoBuildPlugin` becomes its own plugin entry to preserve plugin-priority order.
21
+ - `rolldown/rolldown-plugin-bridge.ts` — converts the runtime-agnostic `EcoBuildPlugin[]` array (the contract integrations and processors register) into the bundler's native `Plugin` array. Each `EcoBuildPlugin` becomes its own plugin entry to preserve plugin-priority order.
21
22
 
22
23
  ## Files
23
24
 
24
- - `build-adapter.ts`: types, factories, app-owned helpers, `withBuildExecutorPlugins`.
25
- - `build-runtime.ts`: profile-based executor installation (`server-entry`, `route-module`, `browser-hmr`).
26
- - `build-types.ts`: the `EcoBuildPlugin` contract used by integrations and processors.
27
- - `rolldown-build-adapter.ts`: the production `BuildAdapter`. Wraps the bundler and exposes a normalized `BuildResult` (outputs, dependency graph, logs).
28
- - `rolldown-plugin-bridge.ts`: `EcoBuildPlugin[]` bundler-plugin translation.
29
- - `serialized-build-executor.ts`: FIFO queue primitive.
30
- - `runtime-build-executor.ts`: server-adapter entrypoint that installs `BuildRuntime` via `installAppRuntimeBuildExecutor()`.
31
- - `server-entry-build-cache.ts`: production server-entry bundle cache (`.eco/.server-entry/.build-cache.json` + `dist/.server/manifest.json`).
32
- - `*.test.ts`: regression coverage.
25
+ ```
26
+ build/
27
+ build-adapter.ts app-owned adapter/manifest wiring
28
+ app-build-manifest-runtime.ts contributor collection at startup
29
+ contracts/ EcoBuildPlugin, BuildOptions, AppBuildManifest
30
+ runtime/ profiles, executors, request policy/identity
31
+ rolldown/ bundler adapter, plugin bridge, output normalization
32
+ cache/ persisted caches, fingerprints, unified pages graph
33
+ browser/ client runtime rewrites, JSX ownership, Lit worker guard
34
+ ```
35
+
36
+ - `contracts/build-manifest.ts` + `app-build-manifest-runtime.ts`: sealed `AppBuildManifest` buckets and contributor collection.
37
+ - `build-adapter.ts`: types, factories, and app-owned adapter/manifest helpers.
38
+ - `runtime/build-runtime.ts`: profile-based executor installation (`server-entry`, `route-module`, `browser-hmr`).
39
+ - `runtime/build-request-policy.ts`: server/browser request constructors and plugin collision rules.
40
+ - `runtime/build-request-identity.ts` / `cache/cache-keys.ts`: canonical request identity and shared cache fingerprints.
41
+ - `contracts/build-types.ts`: the `EcoBuildPlugin` contract used by integrations and processors.
42
+ - `rolldown/rolldown-build-adapter.ts`: the production `BuildAdapter`. Wraps the bundler, normalizes Node output imports, and exposes a normalized `BuildResult`.
43
+ - `rolldown/rolldown-plugin-bridge.ts`: `EcoBuildPlugin[]` → bundler-plugin translation.
44
+ - `runtime/serialized-build-executor.ts`: FIFO queue primitive.
45
+ - `cache/server-entry-build-cache.ts`: production server-entry bundle cache (`.eco/.server-entry/.build-cache.json` + `dist/.server/manifest.json`).
46
+ - `cache/cache-constants.ts`: shared `.build-cache.json` filename for persisted production caches.
47
+ - `*.test.ts`: regression coverage colocated with each module.
33
48
 
34
49
  ## Default Flow
35
50
 
36
- `ConfigBuilder.build()` creates one app-owned adapter and manifest. When a server adapter initializes, it calls `installAppRuntimeBuildExecutor(appConfig)`, which installs `BuildRuntime`:
51
+ `ConfigBuilder.build()` creates one app-owned adapter and manifest. When a server adapter initializes, it calls `installBuildRuntime(appConfig)`:
52
+
53
+ ## App build manifest
54
+
55
+ `AppBuildManifest` is the sealed registry of build plugins and browser runtime assets on `appConfig.runtime.buildManifest`. Integrations and processors declare contributions through getters; core maps them into manifest buckets during `ConfigBuilder.build()`.
56
+
57
+ | Integration getter | Processor getter | Manifest bucket | Used in |
58
+ | ------------------------ | ---------------- | ------------------------ | ---------------------------------------------------------------- |
59
+ | — (loaders on config) | — | `loaderPlugins` | Server and browser |
60
+ | `plugins` | `plugins` | `runtimePlugins` | Server and browser |
61
+ | `browserBuildPlugins` | `buildPlugins` | `browserBundlePlugins` | Browser only |
62
+ | `browserRuntimeManifest` | — | `browserRuntimeManifest` | Browser (rewrite map; core synthesizes `browser-runtime-plugin`) |
63
+
64
+ **Sealing flow**
65
+
66
+ 1. `collectConfiguredAppBuildManifestContributions(config)` walks processors and integrations (after `prepareBuildContributions()`).
67
+ 2. `updateAppBuildManifest(config, contributions)` merges loader plugins from `config.loaders` with the collected buckets.
68
+ 3. `createServerBuildRequest` / `createBrowserBuildRequest` read the sealed manifest through `getAppServerBuildPlugins` / `getAppBrowserBuildPlugins`.
69
+
70
+ **Rule of thumb**
71
+
72
+ - Shared transforms (MDX loaders, virtual modules, route-module hooks) → `plugins` / `runtimePlugins`.
73
+ - Client-bundle-only work (vendor aliasing, async production CSS) → `browserBuildPlugins` or `buildPlugins` / `browserBundlePlugins`.
74
+ - Vendor specifier → public URL rewrites → `browserRuntimeManifest` (not a plugin list).
75
+
76
+ Direct `setAppBuildManifest` is for tests and full manifest replacement. Production code should rely on `updateAppBuildManifest` during config build.
37
77
 
38
78
  ```
39
- BuildRuntime.getProfile(...)
40
- ├─ server-entry SerializedBuildExecutor withBuildExecutorPlugins RolldownBuildAdapter
41
- ├─ route-module ParallelBuildExecutor → withBuildExecutorPlugins → RolldownBuildAdapter
42
- └─ browser-hmr ParallelBuildExecutor → withBuildExecutorPlugins → RolldownBuildAdapter
79
+ Caller intent
80
+ createServerBuildRequest / createBrowserBuildRequest (plugins + transforms assembled once)
81
+ BuildRuntime.getProfile(...)
82
+ ├─ server-entry SerializedBuildExecutor → RolldownBuildAdapter
83
+ ├─ route-module → DedupingBuildExecutor → ParallelBuildExecutor → RolldownBuildAdapter
84
+ └─ browser-hmr → DedupingBuildExecutor → ParallelBuildExecutor → RolldownBuildAdapter
85
+ → RolldownBuildAdapter rewrites Node/browser runtime imports in emitted outputs
43
86
  ```
44
87
 
45
- All profiles use one-shot Rolldown in both dev and production. Route-module and browser-HMR builds run in parallel; server-entry stays serialized single-flight.
88
+ For `rolldown` ownership, profiles use one-shot Rolldown in both dev and production. Route-module and browser-HMR builds run in parallel; server-entry stays serialized single-flight. With `vite-host` ownership, the same scheduling wrappers delegate to a boundary marker that rejects framework-owned builds.
46
89
 
47
- Runtime code should call `requireBuildRuntime(appConfig).getProfile('route-module' | 'browser-hmr' | 'server-entry')` instead of reading legacy executor slots.
90
+ Runtime code should call `requireBuildRuntime(appConfig).getProfile('route-module' | 'browser-hmr' | 'server-entry')` with a complete `BuildOptions` object from the request-policy helpers. Profiles are scheduling-only: bare `getProfile(...).build()` does **not** inject app plugins.
48
91
 
49
- The exported `defaultBuildAdapter` and the top-level `build()` / `getTranspileOptions()` helpers are non-app-aware escape hatches. New runtime code should prefer `getAppBuildAdapter()`, `requireBuildRuntime()`, and `getAppTranspileOptions()`.
92
+ The exported `defaultBuildAdapter` and the top-level `build()` / `getTranspileOptions()` helpers are non-app-aware escape hatches. New runtime code should prefer `getAppBuildAdapter()`, `requireBuildRuntime()`, `createServerBuildRequest()`, `createBrowserBuildRequest()`, and `getAppTranspileOptions()`.
93
+
94
+ `BuildTranspileProfile` (`browser-script` | `hmr-runtime` | `hmr-entrypoint`) selects transpile settings only. `BuildProfile` (`server-entry` | `route-module` | `browser-hmr`) selects the concurrency/dedupe wrapper. `BrowserBundleService` maps `hmr` + (`hmr-entrypoint` | `hmr-runtime`) to the `browser-hmr` profile; all other browser work (including `browser-script`) uses `route-module`.
50
95
 
51
96
  ## Vite-Host Boundary
52
97
 
@@ -71,9 +116,7 @@ Vite-based apps (or any future host runtime) should:
71
116
  - `onLoad({ filter, namespace? }, callback)` — the bundler's `load` mapped the same way.
72
117
  - `module(specifier, callback)` — declares a virtual module by name, with bundler-side namespace encoding.
73
118
 
74
- Namespace handling: the shared plugin contract scopes handlers with a `namespace` string; the bundler encodes namespaces into the module id. The bridge prepends `<namespace>:` to resolved ids and matches filters against that prefix, then strips it before forwarding back to callbacks. Plugin code keeps the same `path` shape it had on the shared contract.
75
-
76
- Plugin ordering: the bundler's `resolveId` and `load` are "first" hooks. The bridge translates each `EcoBuildPlugin` into its own plugin and preserves the array order, so position determines priority: index 0 wins first, the last index is the lowest priority. Security-critical plugins (e.g. `ecopages-client-graph-boundary`) should be placed before general-purpose loaders in the array.
119
+ App-manifest plugins keep canonical registration order and cannot be silently replaced by caller plugins. Use `excludeAppBuildPlugins` on browser requests to omit app-owned plugins explicitly.
77
120
 
78
121
  ## BuildOptions Caveats
79
122
 
@@ -87,7 +130,7 @@ These fields are kept in the type so existing call-sites compile. The proper fix
87
130
 
88
131
  ## Dev / watch path
89
132
 
90
- `installBuildRuntime` (via `installAppRuntimeBuildExecutor`) installs profile-based executors:
133
+ `installBuildRuntime` installs profile-based executors:
91
134
 
92
135
  | Profile | Backend | Concurrency |
93
136
  | -------------- | ----------------- | -------------------- |
@@ -95,7 +138,9 @@ These fields are kept in the type so existing call-sites compile. The proper fix
95
138
  | `route-module` | Rolldown one-shot | Parallel |
96
139
  | `browser-hmr` | Rolldown one-shot | Parallel (limit ≤ 3) |
97
140
 
98
- `hmr-entrypoint` rebuilds use the `browser-hmr` profile. Other browser builds (`browser-script`, `hmr-runtime`) use `route-module`.
141
+ `hmr-entrypoint` and `hmr-runtime` rebuilds with `executor: 'hmr'` use the `browser-hmr` profile. Other browser builds (`browser-script`, and any build with `executor: 'build'`) use `route-module`.
142
+
143
+ The table describes `rolldown` ownership. With `vite-host` ownership, profiles wrap `ViteHostBuildAdapter`, which rejects framework-owned builds so the host must run its own pipeline.
99
144
 
100
145
  `ProjectWatcher` deduplicates watch roots, ignores `.eco/` and `dist/`, and coalesces duplicate chokidar events within 150ms.
101
146
 
@@ -107,12 +152,12 @@ Set `ECOPAGES_ROLLDOWN_BUILD_METRICS=1` to log Rolldown invocation counts during
107
152
 
108
153
  Two persisted cache layers accelerate production builds. Both use `.build-cache.json` manifests keyed by dependency hashes and a build-inputs fingerprint.
109
154
 
110
- | Cache | On-disk location | Module |
111
- | -------------------------------------- | --------------------------------------------------- | ----------------------------------- |
112
- | Server-entry bundle | `.eco/.server-entry/.build-cache.json` | `server-entry-build-cache.ts` |
113
- | Route-module transpile + static render | `<server-outdir>/.server-modules/.build-cache.json` | `route-module-build-cache.store.ts` |
155
+ | Cache | On-disk location | Module |
156
+ | -------------------------------------- | --------------------------------------------------- | ---------------------------------------------------- |
157
+ | Server-entry bundle | `.eco/.server-entry/.build-cache.json` | `cache/server-entry-build-cache.ts` |
158
+ | Route-module transpile + static render | `<server-outdir>/.server-modules/.build-cache.json` | `route-module-build-cache.store.ts` (module-loading) |
114
159
 
115
- `getInstalledServerEntryBuildExecutor()` returns the `server-entry` profile from `BuildRuntime`. `clearProductionBuildCaches()` wipes both manifest trees, resets in-memory route-module state, and clears `buildRuntime`.
160
+ `requireBuildRuntime(appConfig).getProfile('server-entry')` serves server-entry bundling. `clearProductionBuildCaches()` wipes both manifest trees, resets in-memory route-module state, and clears `buildRuntime`.
116
161
 
117
162
  The route-module registry (`route-module-build-cache-registry.ts`) shares one `RouteModuleBuildCache` per `(app, outdir)` pair. Legacy `.server-route-modules` outdirs are still read for migration but new writes go to `.server-modules`.
118
163
 
@@ -125,11 +170,11 @@ Production static exports compile all template pages in one Rolldown invocation
125
170
  | Graph manifest | `.eco/.server-pages-graph/.build-cache.json` |
126
171
  | Chunk outputs | `.eco/.server-modules/` (shared with per-route cache) |
127
172
 
128
- `StaticSiteGenerator` calls `ensurePagesUnifiedGraphBuilt()` before the export loop. `PageModuleImportService` imports prebuilt chunks via `importPagesUnifiedGraphModule()` and falls back to per-page Rolldown on miss.
173
+ `StaticSiteGenerator` calls `ensurePagesUnifiedGraphBuilt()` before the export loop. `PageModuleImportService` imports prebuilt chunks via `importPagesUnifiedGraphModule()` and falls back to per-page Rolldown on miss. This is separate from production Page Browser Graph prebuild (`production-page-browser-graph-prebuild.ts`), which warms browser assets in `page-browser-graph-session`.
129
174
 
130
- `ECOPAGES_ROLLDOWN_BUILD_METRICS=1` enables `rolldown-build-invocation-metrics.ts` counters used by bench and parity tests.
175
+ `ECOPAGES_ROLLDOWN_BUILD_METRICS=1` enables `rolldown/rolldown-build-invocation-metrics.ts` counters used by bench and parity tests.
131
176
 
132
- Build-input fingerprinting lives in `build-input-fingerprint.ts` and is shared with server-entry cache, unified pages graph, and static-render invalidation.
177
+ Build-input fingerprinting lives in `cache/build-input-fingerprint.ts` and is shared with server-entry cache, unified pages graph, and static-render invalidation.
133
178
 
134
179
  ## JSX Ownership Plugins
135
180
 
@@ -145,10 +190,11 @@ Mixed-integration apps need explicit `@jsxImportSource` handling in two differen
145
190
 
146
191
  ## Testing Strategy
147
192
 
148
- - `rolldown-build-adapter.test.ts` covers the adapter's `build`, `resolve`, `getTranspileOptions`, and dependency-graph extraction end-to-end.
149
- - `rolldown-plugin-bridge.test.ts` covers the `EcoBuildPlugin[]` → plugin translation in isolation.
150
- - `build-adapter.test.ts` covers the app-owned helpers, the `BuildOwnership` routing, the `withBuildExecutorPlugins` injection, and the default-fallback behaviour.
151
- - `build-runtime.test.ts` covers profile executor installation and parallelism.
152
- - `runtime-build-executor.test.ts` covers the runtime wrapper: plugin injection and the Vite-host rejection path.
193
+ - `rolldown/rolldown-build-adapter.test.ts` covers the adapter's `build`, `resolve`, `getTranspileOptions`, and dependency-graph extraction end-to-end.
194
+ - `rolldown/rolldown-plugin-bridge.test.ts` covers the `EcoBuildPlugin[]` → plugin translation in isolation.
195
+ - `build-adapter.test.ts` covers the app-owned helpers, the `BuildOwnership` routing, and the default-fallback behaviour.
196
+ - `runtime/build-runtime.test.ts` covers profile executor installation and parallelism.
197
+ - `runtime/build-request-policy.test.ts` and `runtime/build-request-identity.test.ts` cover request assembly and dedupe identity.
198
+ - `rolldown/runtime-build-output-normalizer.test.ts` covers Node output finalization.
153
199
 
154
200
  If you change option mapping or plugin-bridge semantics, update the adapter and bridge tests first. If you change the app-owned helper contracts, update `build-adapter.test.ts` first.
@@ -1,9 +1,35 @@
1
- import type { EcoBuildPlugin } from './build-types.js';
2
- import type { AppBuildManifest } from './build-manifest.js';
1
+ import type { EcoBuildPlugin } from './contracts/build-types.js';
2
+ import type { AppBuildManifest } from './contracts/build-manifest.js';
3
3
  import type { EcoPagesAppConfig } from '../types/internal-types.js';
4
+ /**
5
+ * Collects integration and processor contributions before the app build manifest is sealed.
6
+ *
7
+ * @remarks
8
+ * Called from {@link ConfigBuilder.build} via {@link updateAppBuildManifest}. Walks
9
+ * processors first, then integrations, invoking {@link Processor.prepareBuildContributions}
10
+ * and {@link IntegrationPlugin.prepareBuildContributions} so dynamic plugin lists can be
11
+ * materialized before sealing.
12
+ *
13
+ * Maps contributor getters to manifest buckets:
14
+ * - `processor.plugins` / `integration.plugins` → `runtimePlugins`
15
+ * - `processor.buildPlugins` / `integration.browserBuildPlugins` → `browserBundlePlugins`
16
+ * - `integration.browserRuntimeManifest` → merged `browserRuntimeManifest`
17
+ *
18
+ * Loaders are not collected here; {@link createConfiguredAppBuildManifest} always takes
19
+ * them from `appConfig.loaders`.
20
+ */
4
21
  export declare function collectConfiguredAppBuildManifestContributions(appConfig: EcoPagesAppConfig): Promise<Pick<AppBuildManifest, 'runtimePlugins' | 'browserBundlePlugins' | 'browserRuntimeManifest'>>;
5
22
  export declare function setupAppRuntimePlugins(options: {
6
23
  appConfig: EcoPagesAppConfig;
7
24
  runtimeOrigin: string;
8
25
  onRuntimePlugin?: (plugin: EcoBuildPlugin) => void;
9
26
  }): Promise<void>;
27
+ /**
28
+ * Activates one integration's runtime setup on first use.
29
+ */
30
+ export declare function ensureIntegrationRuntimeReady(options: {
31
+ appConfig: EcoPagesAppConfig;
32
+ integrationName: string;
33
+ runtimeOrigin: string;
34
+ onRuntimePlugin?: (plugin: EcoBuildPlugin) => void;
35
+ }): Promise<void>;
@@ -1,7 +1,7 @@
1
- import { mergeBrowserRuntimeManifests } from "./browser-runtime-manifest.js";
1
+ import { mergeBrowserRuntimeManifests } from "./browser/browser-runtime-manifest.js";
2
2
  import { appLogger } from "../global/app-logger.js";
3
3
  import { startupTrace } from "../diagnostics/startup-trace.js";
4
- import { isLitStaticRenderWorkerThread } from "./lit-static-render-worker-context.js";
4
+ import { isLitStaticRenderWorkerThread } from "./browser/lit-static-render-worker-context.js";
5
5
  function patchAppRuntime(appConfig, patch) {
6
6
  appConfig.runtime = {
7
7
  ...appConfig.runtime ?? {},
@@ -64,6 +64,9 @@ async function setupAppRuntimePlugins(options) {
64
64
  }
65
65
  appLogger.debugTime("setupAppRuntimePlugins");
66
66
  try {
67
+ if (options.onRuntimePlugin) {
68
+ patchAppRuntime(options.appConfig, { onRuntimePlugin: options.onRuntimePlugin });
69
+ }
67
70
  for (const loader of options.appConfig.loaders.values()) {
68
71
  options.onRuntimePlugin?.(loader);
69
72
  }
@@ -78,21 +81,34 @@ async function setupAppRuntimePlugins(options) {
78
81
  }
79
82
  }
80
83
  }
81
- for (const integration of options.appConfig.integrations) {
82
- integration.setConfig(options.appConfig);
83
- integration.setRuntimeOrigin(options.runtimeOrigin);
84
- await integration.setup();
85
- for (const plugin of integration.plugins) {
86
- options.onRuntimePlugin?.(plugin);
87
- }
88
- }
89
84
  patchAppRuntime(options.appConfig, { runtimeAssetsPrepared: true });
90
85
  } finally {
91
86
  appLogger.debugTimeEnd("setupAppRuntimePlugins");
92
87
  startupTrace.markPhaseEnd("setupAppRuntimePlugins");
93
88
  }
94
89
  }
90
+ async function ensureIntegrationRuntimeReady(options) {
91
+ const runtime = options.appConfig.runtime ?? {};
92
+ options.appConfig.runtime = runtime;
93
+ runtime.activatedIntegrations ??= /* @__PURE__ */ new Set();
94
+ if (runtime.activatedIntegrations.has(options.integrationName)) {
95
+ return;
96
+ }
97
+ const integration = options.appConfig.integrations.find((plugin) => plugin.name === options.integrationName);
98
+ if (!integration) {
99
+ return;
100
+ }
101
+ integration.setConfig(options.appConfig);
102
+ integration.setRuntimeOrigin(options.runtimeOrigin);
103
+ await integration.setup();
104
+ const onRuntimePlugin = options.onRuntimePlugin ?? options.appConfig.runtime?.onRuntimePlugin;
105
+ for (const plugin of integration.plugins ?? []) {
106
+ onRuntimePlugin?.(plugin);
107
+ }
108
+ runtime.activatedIntegrations.add(options.integrationName);
109
+ }
95
110
  export {
96
111
  collectConfiguredAppBuildManifestContributions,
112
+ ensureIntegrationRuntimeReady,
97
113
  setupAppRuntimePlugins
98
114
  };
@@ -19,7 +19,7 @@
19
19
  * This is the single source of truth for browser-runtime plugin behavior.
20
20
  * Per-bundler bridges can treat it as a single plugin.
21
21
  */
22
- import type { EcoBuildPlugin } from './build-types.js';
22
+ import type { EcoBuildPlugin } from '../contracts/build-types.js';
23
23
  import { type BrowserRuntimeManifest } from './browser-runtime-manifest.js';
24
24
  /**
25
25
  * Symbol used to attach the manifest's `specifier → publicPath` map to a
@@ -1,6 +1,6 @@
1
1
  import path from "node:path";
2
2
  import { existsSync, readFileSync } from "node:fs";
3
- import { cachedParseSync } from "../cache/module-parse-cache.js";
3
+ import { cachedParseSync } from "../../cache/module-parse-cache.js";
4
4
  import { getBrowserRuntimeSpecifierMap } from "./browser-runtime-manifest.js";
5
5
  import { buildSpecifierFilter } from "./browser-runtime-plugin-helpers.js";
6
6
  const BROWSER_RUNTIME_IMPORT_REWRITE_MAP = /* @__PURE__ */ Symbol.for("ecopages.browserRuntimeImportRewriteMap");
@@ -1,5 +1,5 @@
1
- import type { EcoBuildPlugin } from './build-types.js';
2
- import type { EcoPagesAppConfig } from '../types/internal-types.js';
1
+ import type { EcoBuildPlugin } from '../contracts/build-types.js';
2
+ import type { EcoPagesAppConfig } from '../../types/internal-types.js';
3
3
  /**
4
4
  * Foreign JSX override plugins for mixed-integration app builds.
5
5
  *
@@ -1,5 +1,5 @@
1
- import { createForeignJsxOverridePlugin } from "../plugins/foreign-jsx-override-plugin.js";
2
- import { collectJsxExtensions, filterJsxSourceExtensions } from "../plugins/jsx-import-source.utils.js";
1
+ import { createForeignJsxOverridePlugin } from "../../plugins/foreign-jsx-override-plugin.js";
2
+ import { collectJsxExtensions, filterJsxSourceExtensions } from "../../plugins/jsx-import-source.utils.js";
3
3
  function collectJsxExtensionEntries(appConfig) {
4
4
  return (appConfig.integrations ?? []).filter((integration) => integration.jsxImportSource).flatMap(
5
5
  (integration) => filterJsxSourceExtensions(integration.extensions).map((extension) => ({ integration, extension }))
@@ -15,26 +15,11 @@
15
15
  * per `EcoPagesAppConfig`. Profile executors live on
16
16
  * `appConfig.runtime.buildRuntime`.
17
17
  */
18
- import type { EcoBuildPlugin } from './build-types.js';
19
- import { type BuildAdapter, type BuildExecutor, type BuildOptions, type BuildOwnership, type BuildResult, type BuildTranspileOptions, type BuildTranspileProfile } from './build-contracts.js';
20
- export type { BuildAdapter, BuildDependencyGraph, BuildExecutor, BuildLog, BuildOptions, BuildOutput, BuildOwnership, BuildResult, BuildTranspileOptions, BuildTranspileProfile, } from './build-contracts.js';
21
- import { type AppBuildManifest } from './build-manifest.js';
18
+ import type { EcoBuildPlugin } from './contracts/build-types.js';
19
+ import { type BuildAdapter, type BuildExecutor, type BuildOptions, type BuildOwnership, type BuildResult, type BuildTranspileOptions, type BuildTranspileProfile } from './contracts/build-contracts.js';
20
+ export type { BuildAdapter, BuildDependencyGraph, BuildExecutor, BuildLog, BuildOptions, BuildOutput, BuildOwnership, BuildResult, BuildTranspileOptions, BuildTranspileProfile, } from './contracts/build-contracts.js';
21
+ import { type AppBuildManifest } from './contracts/build-manifest.js';
22
22
  import type { EcoPagesAppConfig } from '../types/internal-types.js';
23
- /**
24
- * Wraps a {@link BuildExecutor} so each call to `build` receives the
25
- * union of the caller's `options.plugins` and the plugins sourced
26
- * from `getPlugins()`.
27
- *
28
- * @remarks
29
- * The single point of plugin injection in the runtime path: the
30
- * `ConfigBuilder` stores a raw adapter on
31
- * `appConfig.runtime.buildAdapter` and the
32
- * `installAppRuntimeBuildExecutor` step wraps that adapter with this
33
- * helper. Callers that issue builds through
34
- * `requireBuildRuntime(appConfig).getProfile(...)` get the merged plugin set
35
- * without further ceremony.
36
- */
37
- export declare function withBuildExecutorPlugins(executor: BuildExecutor, getPlugins: () => EcoBuildPlugin[]): BuildExecutor;
38
23
  /**
39
24
  * Boundary-marker adapter for Vite-host ownership.
40
25
  *
@@ -140,7 +125,14 @@ export declare function setAppBuildAdapter(appConfig: EcoPagesAppConfig, buildAd
140
125
  * services.
141
126
  */
142
127
  export declare function getAppBuildManifest(appConfig: EcoPagesAppConfig): AppBuildManifest;
143
- /** Installs the build manifest that should be visible to one app instance. */
128
+ /** Installs the build manifest that should be visible to one app instance.
129
+ *
130
+ * @remarks
131
+ * Production apps are sealed via {@link updateAppBuildManifest} during
132
+ * {@link ConfigBuilder.build}. Call `setAppBuildManifest` directly only in tests or
133
+ * when replacing the entire manifest object; partial updates should use
134
+ * {@link updateAppBuildManifest}.
135
+ */
144
136
  export declare function setAppBuildManifest(appConfig: EcoPagesAppConfig, buildManifest: AppBuildManifest): void;
145
137
  /**
146
138
  * Builds a fresh app manifest from the config's loaders plus optional
@@ -156,9 +148,14 @@ export declare function createConfiguredAppBuildManifest(appConfig: EcoPagesAppC
156
148
  /**
157
149
  * Replaces the app-owned manifest using config-owned loaders and the
158
150
  * caller-supplied contribution input.
151
+ *
152
+ * @remarks
153
+ * Primary production entry: `ConfigBuilder.build()` passes the return value of
154
+ * {@link collectConfiguredAppBuildManifestContributions} here to seal
155
+ * `appConfig.runtime.buildManifest` before startup.
159
156
  */
160
157
  export declare function updateAppBuildManifest(appConfig: EcoPagesAppConfig, input?: Partial<AppBuildManifest>): void;
161
- export { collectConfiguredAppBuildManifestContributions, setupAppRuntimePlugins, } from './app-build-manifest-runtime.js';
158
+ export { collectConfiguredAppBuildManifestContributions, ensureIntegrationRuntimeReady, setupAppRuntimePlugins, } from './app-build-manifest-runtime.js';
162
159
  /**
163
160
  * Returns the server-bundle plugin list for one app/runtime instance.
164
161
  *
@@ -1,42 +1,14 @@
1
- import { normalizeNodeRuntimeBuildOutputs } from "./runtime-build-output-normalizer.js";
2
1
  import {
3
- } from "./build-contracts.js";
2
+ } from "./contracts/build-contracts.js";
4
3
  import {
5
4
  createAppBuildManifest,
6
5
  getBrowserBuildPlugins,
7
6
  getServerBuildPlugins
8
- } from "./build-manifest.js";
7
+ } from "./contracts/build-manifest.js";
9
8
  import { getAppSourceTransforms } from "../plugins/source-transform.js";
10
9
  import { createAliasResolverPlugin } from "../plugins/alias-resolver-plugin.js";
11
- import { getJsxOwnershipPlugins } from "./jsx-ownership-plugins.js";
12
- import { createRolldownBuildAdapter } from "./rolldown-build-adapter.js";
13
- function mergeBuildExecutorPlugins(existing, appPlugins) {
14
- if (!existing || existing.length === 0) {
15
- return appPlugins;
16
- }
17
- const byName = /* @__PURE__ */ new Map();
18
- for (const plugin of existing) {
19
- byName.set(plugin.name, plugin);
20
- }
21
- for (const plugin of appPlugins) {
22
- byName.set(plugin.name, plugin);
23
- }
24
- return Array.from(byName.values());
25
- }
26
- function withBuildExecutorPlugins(executor, getPlugins) {
27
- return {
28
- async build(options) {
29
- const appPlugins = getPlugins();
30
- if (appPlugins.length === 0) {
31
- return executor.build(options);
32
- }
33
- return executor.build({
34
- ...options,
35
- plugins: mergeBuildExecutorPlugins(options.plugins, appPlugins)
36
- });
37
- }
38
- };
39
- }
10
+ import { getJsxOwnershipPlugins } from "./browser/jsx-ownership-plugins.js";
11
+ import { createRolldownBuildAdapter } from "./rolldown/rolldown-build-adapter.js";
40
12
  function patchAppRuntime(appConfig, patch) {
41
13
  appConfig.runtime = {
42
14
  ...appConfig.runtime ?? {},
@@ -117,6 +89,7 @@ function updateAppBuildManifest(appConfig, input) {
117
89
  }
118
90
  import {
119
91
  collectConfiguredAppBuildManifestContributions,
92
+ ensureIntegrationRuntimeReady,
120
93
  setupAppRuntimePlugins
121
94
  } from "./app-build-manifest-runtime.js";
122
95
  function getAppServerBuildPlugins(appConfig) {
@@ -133,15 +106,7 @@ function getAppBrowserBuildPlugins(appConfig) {
133
106
  return [...aliasPlugin, ...browserPlugins, ...getJsxOwnershipPlugins(appConfig)];
134
107
  }
135
108
  function build(options, executor = defaultRolldownBuildAdapter) {
136
- return executor.build(options).then((result) => {
137
- if (result.success) {
138
- normalizeNodeRuntimeBuildOutputs(
139
- result.outputs.map((output) => output.path),
140
- options.root ?? process.cwd()
141
- );
142
- }
143
- return result;
144
- });
109
+ return executor.build(options);
145
110
  }
146
111
  function getTranspileOptions(profile) {
147
112
  return defaultRolldownBuildAdapter.getTranspileOptions(profile);
@@ -159,6 +124,7 @@ export {
159
124
  defaultBuildAdapter,
160
125
  defaultRolldownBuildAdapter,
161
126
  defaultViteHostBuildAdapter,
127
+ ensureIntegrationRuntimeReady,
162
128
  getAppBrowserBuildPlugins,
163
129
  getAppBuildAdapter,
164
130
  getAppBuildManifest,
@@ -172,6 +138,5 @@ export {
172
138
  setAppBuildManifest,
173
139
  setAppBuildOwnership,
174
140
  setupAppRuntimePlugins,
175
- updateAppBuildManifest,
176
- withBuildExecutorPlugins
141
+ updateAppBuildManifest
177
142
  };
@@ -1,6 +1,6 @@
1
- import type { IntegrationPlugin } from '../plugins/integration-plugin.js';
2
- import type { Processor } from '../plugins/processor.js';
3
- import type { EcoPagesAppConfig } from '../types/internal-types.js';
1
+ import type { IntegrationPlugin } from '../../plugins/integration-plugin.js';
2
+ import type { Processor } from '../../plugins/processor.js';
3
+ import type { EcoPagesAppConfig } from '../../types/internal-types.js';
4
4
  /**
5
5
  * Optional contributor surface for build-time cache invalidation.
6
6
  *
@@ -0,0 +1,4 @@
1
+ /** Filename written beside persisted production build artifacts that store incremental metadata. */
2
+ export declare const ROUTE_MODULE_BUILD_CACHE_FILENAME = ".build-cache.json";
3
+ /** @deprecated Use {@link ROUTE_MODULE_BUILD_CACHE_FILENAME}; server-entry caches share the same filename. */
4
+ export declare const SERVER_ENTRY_BUILD_CACHE_FILENAME = ".build-cache.json";
@@ -0,0 +1,6 @@
1
+ const ROUTE_MODULE_BUILD_CACHE_FILENAME = ".build-cache.json";
2
+ const SERVER_ENTRY_BUILD_CACHE_FILENAME = ROUTE_MODULE_BUILD_CACHE_FILENAME;
3
+ export {
4
+ ROUTE_MODULE_BUILD_CACHE_FILENAME,
5
+ SERVER_ENTRY_BUILD_CACHE_FILENAME
6
+ };
@@ -0,0 +1,22 @@
1
+ import type { EcoBuildPlugin } from '../contracts/build-types.js';
2
+ import type { BuildOptions } from '../contracts/build-contracts.js';
3
+ /**
4
+ * Returns the installed `@ecopages/core` package version for cache invalidation.
5
+ */
6
+ export declare function getCorePackageVersion(): string;
7
+ /** Stable fingerprint for JSX options used in build and disk cache keys. */
8
+ export declare function createJsxCacheKey(jsx: BuildOptions['jsx']): string;
9
+ /** Stable fingerprint for ordered build plugins. */
10
+ export declare function createPluginCacheKey(plugins?: EcoBuildPlugin[]): string;
11
+ /** Stable fingerprint for ordered source transforms. */
12
+ export declare function createSourceTransformCacheKey(sourceTransforms: BuildOptions['sourceTransforms']): string;
13
+ /**
14
+ * Stable fingerprint of a function body for cache and request identity keys.
15
+ *
16
+ * @remarks
17
+ * Hashes `fn.toString()`. Suitable for in-process and persisted keys that must
18
+ * agree within one install; not stable across minifiers or renames.
19
+ */
20
+ export declare function hashFunctionIdentity(fn: (...args: never[]) => unknown): string;
21
+ /** @deprecated Use {@link hashFunctionIdentity}. */
22
+ export declare const hashPluginSetup: typeof hashFunctionIdentity;
@@ -0,0 +1,63 @@
1
+ import { readFileSync } from "node:fs";
2
+ let cachedCorePackageVersion;
3
+ function getCorePackageVersion() {
4
+ if (cachedCorePackageVersion) {
5
+ return cachedCorePackageVersion;
6
+ }
7
+ const packageJsonPath = new URL("../../../package.json", import.meta.url);
8
+ const packageJson = JSON.parse(readFileSync(packageJsonPath, "utf-8"));
9
+ cachedCorePackageVersion = packageJson.version ?? "0.0.0";
10
+ return cachedCorePackageVersion;
11
+ }
12
+ function createJsxCacheKey(jsx) {
13
+ if (!jsx) {
14
+ return "jsx:default";
15
+ }
16
+ return JSON.stringify({
17
+ development: jsx.development ?? false,
18
+ factory: jsx.factory ?? null,
19
+ fragment: jsx.fragment ?? null,
20
+ importSource: jsx.importSource ?? null,
21
+ runtime: jsx.runtime ?? null,
22
+ sideEffects: jsx.sideEffects ?? null
23
+ });
24
+ }
25
+ function createPluginCacheKey(plugins) {
26
+ if (!plugins || plugins.length === 0) {
27
+ return "plugins:default";
28
+ }
29
+ return `plugins:${plugins.map((plugin) => `${plugin.name}:${hashFunctionIdentity(plugin.setup)}`).join(",")}`;
30
+ }
31
+ function createSourceTransformCacheKey(sourceTransforms) {
32
+ if (!sourceTransforms || sourceTransforms.length === 0) {
33
+ return "sourceTransforms:default";
34
+ }
35
+ return `sourceTransforms:${sourceTransforms.map((transform) => {
36
+ const filterSource = transform.filter.source;
37
+ const filterFlags = transform.filter.flags;
38
+ return [
39
+ transform.name,
40
+ transform.enforce ?? "default",
41
+ filterSource,
42
+ filterFlags,
43
+ hashFunctionIdentity(transform.transform)
44
+ ].join(":");
45
+ }).join(",")}`;
46
+ }
47
+ function hashFunctionIdentity(fn) {
48
+ let hash = 0;
49
+ const source = fn.toString();
50
+ for (let index = 0; index < source.length; index += 1) {
51
+ hash = hash * 31 + source.charCodeAt(index) | 0;
52
+ }
53
+ return (hash >>> 0).toString(36);
54
+ }
55
+ const hashPluginSetup = hashFunctionIdentity;
56
+ export {
57
+ createJsxCacheKey,
58
+ createPluginCacheKey,
59
+ createSourceTransformCacheKey,
60
+ getCorePackageVersion,
61
+ hashFunctionIdentity,
62
+ hashPluginSetup
63
+ };
@@ -1,5 +1,5 @@
1
- import type { EcoPagesAppConfig } from '../types/internal-types.js';
2
- import type { ProcessedAsset } from '../services/assets/asset-processing-service/assets.types.js';
1
+ import type { EcoPagesAppConfig } from '../../types/internal-types.js';
2
+ import type { ProcessedAsset } from '../../services/assets/asset-processing-service/assets.types.js';
3
3
  export declare const DEV_BROWSER_SCRIPT_CACHE_DIR = ".browser-script-bundles";
4
4
  export declare const DEV_BROWSER_SCRIPT_CACHE_FILENAME = ".build-cache.json";
5
5
  /** Output path restored from the dev disk cache before dependency metadata is merged. */