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

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 (135) hide show
  1. package/package.json +58 -50
  2. package/src/adapters/bun/server-adapter.js +2 -2
  3. package/src/adapters/node/server-adapter.js +2 -2
  4. package/src/adapters/shared/hmr-entrypoint-registrar.d.ts +10 -0
  5. package/src/adapters/shared/hmr-entrypoint-registrar.js +34 -10
  6. package/src/adapters/shared/runtime-server-lifecycle.js +1 -1
  7. package/src/adapters/shared/server-static-builder.d.ts +2 -1
  8. package/src/adapters/shared/server-static-builder.js +16 -14
  9. package/src/adapters/shared/shared-hmr-manager.d.ts +11 -4
  10. package/src/adapters/shared/shared-hmr-manager.js +22 -3
  11. package/src/build/README.md +92 -46
  12. package/src/build/app-build-manifest-runtime.d.ts +28 -2
  13. package/src/build/app-build-manifest-runtime.js +26 -10
  14. package/src/build/{browser-runtime-plugin.d.ts → browser/browser-runtime-plugin.d.ts} +1 -1
  15. package/src/build/{browser-runtime-plugin.js → browser/browser-runtime-plugin.js} +1 -1
  16. package/src/build/{jsx-ownership-plugins.d.ts → browser/jsx-ownership-plugins.d.ts} +2 -2
  17. package/src/build/{jsx-ownership-plugins.js → browser/jsx-ownership-plugins.js} +2 -2
  18. package/src/build/build-adapter.d.ts +18 -21
  19. package/src/build/build-adapter.js +8 -43
  20. package/src/build/{build-input-fingerprint.d.ts → cache/build-input-fingerprint.d.ts} +3 -3
  21. package/src/build/cache/cache-constants.d.ts +4 -0
  22. package/src/build/cache/cache-constants.js +6 -0
  23. package/src/build/cache/cache-keys.d.ts +22 -0
  24. package/src/build/cache/cache-keys.js +63 -0
  25. package/src/build/{dev-browser-script-cache.d.ts → cache/dev-browser-script-cache.d.ts} +2 -2
  26. package/src/build/{dev-browser-script-cache.js → cache/dev-browser-script-cache.js} +4 -4
  27. package/src/build/{pages-unified-graph-build.d.ts → cache/pages-unified-graph-build.d.ts} +1 -1
  28. package/src/build/{pages-unified-graph-build.js → cache/pages-unified-graph-build.js} +18 -26
  29. package/src/build/{production-build-cache.d.ts → cache/production-build-cache.d.ts} +1 -1
  30. package/src/build/{production-build-cache.js → cache/production-build-cache.js} +2 -2
  31. package/src/build/{server-entry-build-cache.d.ts → cache/server-entry-build-cache.d.ts} +3 -4
  32. package/src/build/{server-entry-build-cache.js → cache/server-entry-build-cache.js} +16 -12
  33. package/src/build/{build-contracts.d.ts → contracts/build-contracts.d.ts} +1 -2
  34. package/src/build/contracts/build-manifest.d.ts +90 -0
  35. package/src/build/{build-manifest.js → contracts/build-manifest.js} +2 -2
  36. package/src/build/{rolldown-adapter-helpers.d.ts → rolldown/rolldown-adapter-helpers.d.ts} +20 -3
  37. package/src/build/{rolldown-adapter-helpers.js → rolldown/rolldown-adapter-helpers.js} +26 -6
  38. package/src/build/{rolldown-build-adapter.d.ts → rolldown/rolldown-build-adapter.d.ts} +1 -1
  39. package/src/build/{rolldown-plugin-bridge.d.ts → rolldown/rolldown-plugin-bridge.d.ts} +2 -2
  40. package/src/build/{rolldown-plugin-bridge.js → rolldown/rolldown-plugin-bridge.js} +1 -1
  41. package/src/build/{rolldown-source-transform-pass.d.ts → rolldown/rolldown-source-transform-pass.d.ts} +1 -1
  42. package/src/build/{rolldown-source-transform-pass.js → rolldown/rolldown-source-transform-pass.js} +4 -1
  43. package/src/build/{runtime-build-output-normalizer.js → rolldown/runtime-build-output-normalizer.js} +2 -2
  44. package/src/build/{build-profile-options.d.ts → runtime/build-profile-options.d.ts} +2 -2
  45. package/src/build/runtime/build-request-identity.d.ts +17 -0
  46. package/src/build/runtime/build-request-identity.js +54 -0
  47. package/src/build/runtime/build-request-policy.d.ts +59 -0
  48. package/src/build/runtime/build-request-policy.js +46 -0
  49. package/src/build/{build-runtime.d.ts → runtime/build-runtime.d.ts} +8 -4
  50. package/src/build/{build-runtime.js → runtime/build-runtime.js} +11 -11
  51. package/src/build/{deduping-build-executor.d.ts → runtime/deduping-build-executor.d.ts} +2 -9
  52. package/src/build/runtime/deduping-build-executor.js +34 -0
  53. package/src/build/{parallel-build-executor.d.ts → runtime/parallel-build-executor.d.ts} +1 -1
  54. package/src/build/{serialized-build-executor.d.ts → runtime/serialized-build-executor.d.ts} +1 -1
  55. package/src/config/config-builder.d.ts +1 -1
  56. package/src/diagnostics/startup-trace.d.ts +49 -2
  57. package/src/diagnostics/startup-trace.js +140 -8
  58. package/src/hmr/client/hmr-runtime.js +1 -1
  59. package/src/hmr/hmr-file-change-prep.d.ts +10 -0
  60. package/src/hmr/hmr-file-change-prep.js +17 -0
  61. package/src/plugins/alias-resolver-plugin.d.ts +1 -1
  62. package/src/plugins/eco-component-meta-plugin.d.ts +1 -1
  63. package/src/plugins/foreign-jsx-override-plugin.d.ts +1 -1
  64. package/src/plugins/integration-plugin.d.ts +16 -5
  65. package/src/plugins/integration-plugin.js +11 -1
  66. package/src/plugins/processor.d.ts +28 -8
  67. package/src/plugins/source-transform.d.ts +1 -1
  68. package/src/route-renderer/GRAPH.md +13 -19
  69. package/src/route-renderer/README.md +1 -1
  70. package/src/route-renderer/orchestration/component-render-context.d.ts +4 -4
  71. package/src/route-renderer/orchestration/foreign-subtree-execution.service.js +6 -2
  72. package/src/route-renderer/orchestration/integration-renderer.d.ts +11 -52
  73. package/src/route-renderer/orchestration/integration-renderer.js +38 -91
  74. package/src/route-renderer/orchestration/integration-route-render-adapter.d.ts +1 -8
  75. package/src/route-renderer/orchestration/integration-route-render-adapter.js +0 -2
  76. package/src/route-renderer/orchestration/page-browser-graph-session.d.ts +106 -0
  77. package/src/route-renderer/orchestration/page-browser-graph-session.js +436 -0
  78. package/src/route-renderer/orchestration/page-browser-graph.service.d.ts +9 -3
  79. package/src/route-renderer/orchestration/page-browser-graph.service.js +89 -40
  80. package/src/route-renderer/orchestration/render-output.utils.d.ts +14 -0
  81. package/src/route-renderer/orchestration/render-output.utils.js +30 -0
  82. package/src/route-renderer/orchestration/route-html-finalization.service.d.ts +0 -1
  83. package/src/route-renderer/orchestration/route-html-finalization.service.js +4 -9
  84. package/src/route-renderer/orchestration/route-prepared-options.builder.d.ts +1 -2
  85. package/src/route-renderer/orchestration/route-prepared-options.builder.js +1 -10
  86. package/src/route-renderer/orchestration/route-render-orchestrator.d.ts +3 -12
  87. package/src/route-renderer/orchestration/route-render-orchestrator.js +4 -14
  88. package/src/services/assets/asset-processing-service/asset-processing.service.js +1 -1
  89. package/src/services/assets/asset-processing-service/assets.types.d.ts +1 -1
  90. package/src/services/assets/asset-processing-service/browser-runtime-asset.factory.d.ts +1 -1
  91. package/src/services/assets/asset-processing-service/processors/base/base-script-processor.d.ts +0 -2
  92. package/src/services/assets/asset-processing-service/processors/base/base-script-processor.js +2 -15
  93. package/src/services/assets/asset-processing-service/processors/script/content-script.processor.js +1 -1
  94. package/src/services/assets/browser-bundle.service.d.ts +27 -31
  95. package/src/services/assets/browser-bundle.service.js +12 -23
  96. package/src/services/module-loading/app-server-module-transpiler.service.d.ts +8 -0
  97. package/src/services/module-loading/app-server-module-transpiler.service.js +1 -7
  98. package/src/services/module-loading/page-module-import.service.d.ts +1 -1
  99. package/src/services/module-loading/page-module-import.service.js +40 -28
  100. package/src/services/module-loading/route-module-build-cache.store.js +1 -1
  101. package/src/services/module-loading/route-module-build-manifest.d.ts +2 -9
  102. package/src/services/module-loading/route-module-build-manifest.js +12 -43
  103. package/src/services/module-loading/server-module-transpiler.service.d.ts +1 -1
  104. package/src/static-site-generator/README.md +1 -1
  105. package/src/static-site-generator/production-page-browser-graph-prebuild.d.ts +28 -0
  106. package/src/static-site-generator/production-page-browser-graph-prebuild.js +22 -0
  107. package/src/static-site-generator/static-build-invalidation.d.ts +2 -2
  108. package/src/static-site-generator/static-build-invalidation.js +3 -3
  109. package/src/static-site-generator/static-site-generator.js +23 -1
  110. package/src/types/internal-types.d.ts +10 -4
  111. package/src/types/public-types.d.ts +58 -9
  112. package/src/watchers/project-watcher.js +12 -2
  113. package/src/build/build-manifest.d.ts +0 -33
  114. package/src/build/deduping-build-executor.js +0 -56
  115. package/src/build/runtime-build-executor.d.ts +0 -14
  116. package/src/build/runtime-build-executor.js +0 -16
  117. /package/src/build/{browser-runtime-manifest.d.ts → browser/browser-runtime-manifest.d.ts} +0 -0
  118. /package/src/build/{browser-runtime-manifest.js → browser/browser-runtime-manifest.js} +0 -0
  119. /package/src/build/{browser-runtime-plugin-helpers.d.ts → browser/browser-runtime-plugin-helpers.d.ts} +0 -0
  120. /package/src/build/{browser-runtime-plugin-helpers.js → browser/browser-runtime-plugin-helpers.js} +0 -0
  121. /package/src/build/{lit-static-render-worker-context.d.ts → browser/lit-static-render-worker-context.d.ts} +0 -0
  122. /package/src/build/{lit-static-render-worker-context.js → browser/lit-static-render-worker-context.js} +0 -0
  123. /package/src/build/{build-input-fingerprint.js → cache/build-input-fingerprint.js} +0 -0
  124. /package/src/build/{build-contracts.js → contracts/build-contracts.js} +0 -0
  125. /package/src/build/{build-types.d.ts → contracts/build-types.d.ts} +0 -0
  126. /package/src/build/{build-types.js → contracts/build-types.js} +0 -0
  127. /package/src/build/{rolldown-build-adapter.js → rolldown/rolldown-build-adapter.js} +0 -0
  128. /package/src/build/{rolldown-build-invocation-metrics.d.ts → rolldown/rolldown-build-invocation-metrics.d.ts} +0 -0
  129. /package/src/build/{rolldown-build-invocation-metrics.js → rolldown/rolldown-build-invocation-metrics.js} +0 -0
  130. /package/src/build/{runtime-build-output-normalizer.d.ts → rolldown/runtime-build-output-normalizer.d.ts} +0 -0
  131. /package/src/build/{server-side-css-shim-plugin.d.ts → rolldown/server-side-css-shim-plugin.d.ts} +0 -0
  132. /package/src/build/{server-side-css-shim-plugin.js → rolldown/server-side-css-shim-plugin.js} +0 -0
  133. /package/src/build/{build-profile-options.js → runtime/build-profile-options.js} +0 -0
  134. /package/src/build/{parallel-build-executor.js → runtime/parallel-build-executor.js} +0 -0
  135. /package/src/build/{serialized-build-executor.js → runtime/serialized-build-executor.js} +0 -0
@@ -1,10 +1,8 @@
1
- import { getAppBrowserBuildPlugins, getAppTranspileOptions } from "../../build/build-adapter.js";
2
- import { requireBuildRuntime } from "../../build/build-runtime.js";
3
- import { mergeEcoBuildPlugins } from "../../build/build-manifest.js";
4
- import { getAppSourceTransforms } from "../../plugins/source-transform.js";
1
+ import { createBrowserBuildRequest } from "../../build/runtime/build-request-policy.js";
2
+ import { requireBuildRuntime } from "../../build/runtime/build-runtime.js";
5
3
  import { startupTrace } from "../../diagnostics/startup-trace.js";
6
4
  import { requestBuildDedupe } from "../../diagnostics/request-build-dedupe.js";
7
- import { createBuildOptionsDedupeKey } from "../../build/deduping-build-executor.js";
5
+ import { createBuildRequestIdentity } from "../../build/runtime/build-request-identity.js";
8
6
  function resolveBrowserBundleExecutor(appConfig, profile, executor) {
9
7
  const buildRuntime = requireBuildRuntime(appConfig);
10
8
  if (executor === "hmr" && (profile === "hmr-entrypoint" || profile === "hmr-runtime")) {
@@ -14,9 +12,6 @@ function resolveBrowserBundleExecutor(appConfig, profile, executor) {
14
12
  }
15
13
  class BrowserBundleService {
16
14
  appConfig;
17
- /**
18
- * Creates the browser bundle boundary for one finalized app instance.
19
- */
20
15
  constructor(appConfig) {
21
16
  this.appConfig = appConfig;
22
17
  }
@@ -24,24 +19,18 @@ class BrowserBundleService {
24
19
  * Runs one browser-targeted build through the app-owned executor.
25
20
  *
26
21
  * @remarks
27
- * Browser defaults and app-owned browser build plugins are applied here so HMR
28
- * and runtime asset generation do not have to recreate that policy at each call
29
- * site. Also forwards {@link getAppSourceTransforms | app source transforms} so
30
- * metadata injection runs after boundary/runtime `onLoad` rewrites.
22
+ * Browser defaults, app-owned browser plugins, and
23
+ * {@link getAppSourceTransforms | app source transforms} are applied here
24
+ * so HMR and asset generation do not recreate that policy at each call site.
31
25
  */
32
26
  async bundle(options) {
33
- const { profile, excludeAppBuildPlugins, plugins, executor = "hmr", ...rawBuildOptions } = options;
34
- const appBrowserPlugins = getAppBrowserBuildPlugins(this.appConfig);
35
- const filteredAppBrowserPlugins = excludeAppBuildPlugins && excludeAppBuildPlugins.length > 0 ? appBrowserPlugins.filter((plugin) => !excludeAppBuildPlugins.includes(plugin.name)) : appBrowserPlugins;
36
- const request = {
37
- ...rawBuildOptions,
38
- entrypoints: options.entrypoints,
39
- ...getAppTranspileOptions(this.appConfig, profile),
40
- plugins: mergeEcoBuildPlugins(plugins, filteredAppBrowserPlugins),
41
- sourceTransforms: getAppSourceTransforms(this.appConfig)
42
- };
27
+ const { profile, executor = "hmr", ...requestInput } = options;
28
+ const request = createBrowserBuildRequest(this.appConfig, {
29
+ ...requestInput,
30
+ profile
31
+ });
43
32
  const buildExecutor = resolveBrowserBundleExecutor(this.appConfig, profile, executor);
44
- const dedupeKey = createBuildOptionsDedupeKey(request);
33
+ const dedupeKey = createBuildRequestIdentity(request);
45
34
  return requestBuildDedupe.dedupeBuild(dedupeKey, async () => {
46
35
  const result = await buildExecutor.build(request);
47
36
  startupTrace.recordBrowserBundle(result.outputs);
@@ -5,6 +5,14 @@ import { ServerModuleTranspiler } from './server-module-transpiler.service.js';
5
5
  export declare function shouldAppUseHostModuleLoader(appConfig: EcoPagesAppConfig, filePath: string): boolean;
6
6
  export declare function getAppHostModuleLoader(appConfig: EcoPagesAppConfig): SourceModuleLoader | undefined;
7
7
  export declare function setAppHostModuleLoader(appConfig: EcoPagesAppConfig, hostModuleLoader?: SourceModuleLoader): void;
8
+ /**
9
+ * Creates the app module loader that imports route modules through the build pipeline.
10
+ *
11
+ * @remarks
12
+ * Caller `plugins` are treated as contributions only.
13
+ * {@link PageModuleImportService} assembles the complete server request via
14
+ * {@link createServerBuildRequest}; this loader does not merge app plugins.
15
+ */
8
16
  export declare function createAppModuleLoader(appConfig: EcoPagesAppConfig): AppModuleLoader;
9
17
  export declare function getAppModuleLoader(appConfig: EcoPagesAppConfig): AppModuleLoader;
10
18
  export declare function setAppModuleLoader(appConfig: EcoPagesAppConfig, appModuleLoader: AppModuleLoader): void;
@@ -1,6 +1,4 @@
1
- import { getAppServerBuildPlugins } from "../../build/build-adapter.js";
2
- import { requireBuildRuntime } from "../../build/build-runtime.js";
3
- import { getJsxOwnershipPlugins } from "../../build/jsx-ownership-plugins.js";
1
+ import { requireBuildRuntime } from "../../build/runtime/build-runtime.js";
4
2
  import path from "node:path";
5
3
  import { DevelopmentInvalidationService } from "../invalidation/development-invalidation.service.js";
6
4
  import {} from "./app-module-loader.service.js";
@@ -44,8 +42,6 @@ function createAppModuleLoader(appConfig) {
44
42
  canLoadSourceModuleFromHost: (filePath) => shouldAppUseHostModuleLoader(appConfig, filePath),
45
43
  getHostModuleLoader: () => getAppHostModuleLoader(appConfig)
46
44
  });
47
- const appServerBuildPlugins = appConfig.runtime?.buildManifest ? getAppServerBuildPlugins(appConfig) : Array.from(appConfig.loaders?.values() ?? []);
48
- const jsxOwnershipPlugins = getJsxOwnershipPlugins(appConfig);
49
45
  const appModuleLoader = {
50
46
  get owner() {
51
47
  return getAppModuleLoaderOwner(appConfig);
@@ -53,10 +49,8 @@ function createAppModuleLoader(appConfig) {
53
49
  pageModuleImportService,
54
50
  async importModule(options) {
55
51
  const invalidationVersion = options.invalidationVersion ?? invalidationService.getServerModuleInvalidationVersion();
56
- const mergedPlugins = [...appServerBuildPlugins, ...jsxOwnershipPlugins, ...options.plugins ?? []];
57
52
  return await pageModuleImportService.importModule({
58
53
  ...options,
59
- ...mergedPlugins.length > 0 ? { plugins: mergedPlugins } : {},
60
54
  buildExecutor: options.buildExecutor ?? requireBuildRuntime(appConfig).getProfile("route-module"),
61
55
  invalidationVersion
62
56
  });
@@ -1,5 +1,5 @@
1
1
  import { build, type BuildExecutor, type BuildResult } from '../../build/build-adapter.js';
2
- import type { EcoBuildPlugin } from '../../build/build-types.js';
2
+ import type { EcoBuildPlugin } from '../../build/contracts/build-types.js';
3
3
  import type { EcoPagesAppConfig } from '../../types/internal-types.js';
4
4
  import type { SourceModuleLoaderFactory } from './module-loading-types.js';
5
5
  interface PageModuleImportBaseOptions {
@@ -2,19 +2,16 @@ import path from "node:path";
2
2
  import { pathToFileURL } from "node:url";
3
3
  import { fileSystem } from "@ecopages/file-system";
4
4
  import { build } from "../../build/build-adapter.js";
5
- import { resolveBuildProfileOptions } from "../../build/build-profile-options.js";
6
- import { normalizeNodeRuntimeBuildOutputFile } from "../../build/runtime-build-output-normalizer.js";
5
+ import { createServerBuildRequest } from "../../build/runtime/build-request-policy.js";
6
+ import { resolveBuildProfileOptions } from "../../build/runtime/build-profile-options.js";
7
7
  import {
8
8
  importPagesUnifiedGraphModule,
9
9
  isPagesUnifiedGraphPage,
10
10
  shouldBuildPagesUnifiedGraph
11
- } from "../../build/pages-unified-graph-build.js";
12
- import { recordPageModuleBuildInvocation } from "../../build/rolldown-build-invocation-metrics.js";
13
- import {
14
- resolvePageModuleOutputFileName,
15
- createPluginCacheKey,
16
- createJsxCacheKey
17
- } from "./route-module-build-cache.js";
11
+ } from "../../build/cache/pages-unified-graph-build.js";
12
+ import { recordPageModuleBuildInvocation } from "../../build/rolldown/rolldown-build-invocation-metrics.js";
13
+ import { resolvePageModuleOutputFileName } from "./route-module-build-cache.js";
14
+ import { createPluginCacheKey, createJsxCacheKey } from "../../build/cache/cache-keys.js";
18
15
  import { getSharedRouteModuleBuildCache } from "./route-module-build-cache-registry.js";
19
16
  import {
20
17
  RouteModuleDependencyHasher,
@@ -151,11 +148,41 @@ class PageModuleImportService {
151
148
  });
152
149
  const outputNamingTemplate = outputFileName.replace(/\.mjs$/u, ".[ext]");
153
150
  const preferredOutputPath = path.join(outdir, outputFileName);
154
- const routeModuleBuildCache = this.getRouteModuleBuildCache(outdir);
155
- const cachedBuild = routeModuleBuildCache.lookup({
151
+ const buildOptions = this.appConfig ? createServerBuildRequest(this.appConfig, {
152
+ profile: "route-module",
153
+ entrypoints: [filePath],
154
+ outdir,
155
+ naming: outputNamingTemplate,
156
+ splitting: splitting ?? true,
157
+ jsx: options.jsx,
158
+ plugins: options.plugins,
159
+ root: rootDir,
160
+ ...externalPackages !== void 0 ? { externalPackages } : {}
161
+ }) : {
162
+ ...resolveBuildProfileOptions("route-module", { rootDir }, {
163
+ entrypoints: [filePath],
164
+ outdir,
165
+ naming: outputNamingTemplate,
166
+ splitting: splitting ?? true,
167
+ jsx: options.jsx,
168
+ plugins: options.plugins,
169
+ ...externalPackages !== void 0 ? { externalPackages } : {}
170
+ }),
171
+ root: rootDir,
172
+ entrypoints: [filePath]
173
+ };
174
+ const cacheBuildOptions = {
156
175
  ...options,
176
+ rootDir: buildOptions.root ?? rootDir,
177
+ outdir: buildOptions.outdir ?? outdir,
178
+ splitting: buildOptions.splitting,
179
+ externalPackages: buildOptions.externalPackages,
180
+ jsx: buildOptions.jsx,
181
+ plugins: buildOptions.plugins,
157
182
  fileHash
158
- });
183
+ };
184
+ const routeModuleBuildCache = this.getRouteModuleBuildCache(outdir);
185
+ const cachedBuild = routeModuleBuildCache.lookup(cacheBuildOptions);
159
186
  if (cachedBuild) {
160
187
  return await import(
161
188
  /* @vite-ignore */
@@ -169,19 +196,6 @@ class PageModuleImportService {
169
196
  }
170
197
  }
171
198
  recordPageModuleBuildInvocation();
172
- const buildOptions = {
173
- ...resolveBuildProfileOptions("route-module", this.appConfig ?? { rootDir }, {
174
- entrypoints: [filePath],
175
- outdir,
176
- naming: outputNamingTemplate,
177
- splitting: splitting ?? true,
178
- jsx: options.jsx,
179
- plugins: options.plugins,
180
- ...externalPackages !== void 0 ? { externalPackages } : {}
181
- }),
182
- root: rootDir,
183
- entrypoints: [filePath]
184
- };
185
199
  const buildResult = await this.dependencies.buildModule(buildOptions, options.buildExecutor);
186
200
  if (!buildResult.success) {
187
201
  const details = buildResult.logs.map((log) => log.message).join(" | ");
@@ -191,7 +205,6 @@ class PageModuleImportService {
191
205
  if (!compiledOutput) {
192
206
  throw new Error(noOutputMessage(filePath));
193
207
  }
194
- normalizeNodeRuntimeBuildOutputFile(compiledOutput, rootDir);
195
208
  const dependencyModulePaths = resolveRouteModuleDependencyPaths(buildResult, filePath, rootDir);
196
209
  const dependencyHashes = this.dependencyHasher.createDependencyHashes(dependencyModulePaths);
197
210
  dependencyHashes[path.normalize(filePath)] = fileHash;
@@ -202,8 +215,7 @@ class PageModuleImportService {
202
215
  }
203
216
  }
204
217
  routeModuleBuildCache.recordBuild({
205
- ...options,
206
- fileHash,
218
+ ...cacheBuildOptions,
207
219
  outputPath: compiledOutput,
208
220
  dependencyModulePaths
209
221
  });
@@ -14,7 +14,7 @@ import {
14
14
  import {
15
15
  isProductionCacheManifestCurrent,
16
16
  matchesProductionCacheFingerprint
17
- } from "../../build/production-build-cache.js";
17
+ } from "../../build/cache/production-build-cache.js";
18
18
  class RouteModuleBuildCache {
19
19
  manifestPath;
20
20
  dependencies;
@@ -1,8 +1,7 @@
1
- import type { EcoBuildPlugin } from '../../build/build-types.js';
2
1
  import type { PageModuleBuildImportOptions } from './page-module-import.service.js';
3
2
  import type { RouteModuleDependencyHashes } from './route-module-dependency-hasher.js';
4
- /** Filename written beside transpiled server modules that stores incremental build metadata. */
5
- export declare const ROUTE_MODULE_BUILD_CACHE_FILENAME = ".build-cache.json";
3
+ export { createJsxCacheKey, createPluginCacheKey, getCorePackageVersion, hashPluginSetup, } from '../../build/cache/cache-keys.js';
4
+ export { ROUTE_MODULE_BUILD_CACHE_FILENAME } from '../../build/cache/cache-constants.js';
6
5
  /** One persisted route-module build entry in {@link ROUTE_MODULE_BUILD_CACHE_FILENAME}. */
7
6
  export interface RouteModuleBuildCacheEntry {
8
7
  sourceHash: string;
@@ -37,8 +36,6 @@ export interface RouteModuleStaticRenderCacheContext {
37
36
  }
38
37
  export type RouteModuleBuildCacheManifestReader = (manifestPath: string) => RouteModuleBuildCacheManifest | undefined;
39
38
  export type RouteModuleBuildCacheManifestWriter = (manifestPath: string, manifest: RouteModuleBuildCacheManifest) => void;
40
- /** Returns the installed `@ecopages/core` package version used to invalidate persisted caches. */
41
- export declare function getCorePackageVersion(): string;
42
39
  /** Normalizes filesystem paths used as manifest keys and build-key inputs. */
43
40
  export declare function normalizeRouteModuleCachePath(filePath: string): string;
44
41
  /** Returns whether route-module disk caching should run for the current import. */
@@ -55,7 +52,3 @@ export declare function createPersistedRouteModuleBuildKey(options: PageModuleBu
55
52
  export declare function createEmptyRouteModuleBuildCacheManifest(): RouteModuleBuildCacheManifest;
56
53
  export declare function readRouteModuleBuildCacheManifest(manifestPath: string): RouteModuleBuildCacheManifest | undefined;
57
54
  export declare function writeRouteModuleBuildCacheManifest(manifestPath: string, manifest: RouteModuleBuildCacheManifest): void;
58
- export declare function createJsxCacheKey(jsx: PageModuleBuildImportOptions['jsx']): string;
59
- export declare function createPluginCacheKey(plugins?: EcoBuildPlugin[]): string;
60
- /** Exported for in-process import caches that must match persisted build keys. */
61
- export declare function hashPluginSetup(setup: EcoBuildPlugin['setup']): string;
@@ -1,17 +1,13 @@
1
- import { readFileSync } from "node:fs";
2
1
  import path from "node:path";
3
- import { readProductionCacheManifest, writeProductionCacheManifest } from "../../build/production-build-cache.js";
4
- const ROUTE_MODULE_BUILD_CACHE_FILENAME = ".build-cache.json";
5
- let cachedCorePackageVersion;
6
- function getCorePackageVersion() {
7
- if (cachedCorePackageVersion) {
8
- return cachedCorePackageVersion;
9
- }
10
- const packageJsonPath = new URL("../../../package.json", import.meta.url);
11
- const packageJson = JSON.parse(readFileSync(packageJsonPath, "utf-8"));
12
- cachedCorePackageVersion = packageJson.version ?? "0.0.0";
13
- return cachedCorePackageVersion;
14
- }
2
+ import { readProductionCacheManifest, writeProductionCacheManifest } from "../../build/cache/production-build-cache.js";
3
+ import { createJsxCacheKey, createPluginCacheKey, getCorePackageVersion } from "../../build/cache/cache-keys.js";
4
+ import {
5
+ createJsxCacheKey as createJsxCacheKey2,
6
+ createPluginCacheKey as createPluginCacheKey2,
7
+ getCorePackageVersion as getCorePackageVersion2,
8
+ hashPluginSetup
9
+ } from "../../build/cache/cache-keys.js";
10
+ import { ROUTE_MODULE_BUILD_CACHE_FILENAME } from "../../build/cache/cache-constants.js";
15
11
  function normalizeRouteModuleCachePath(filePath) {
16
12
  return path.resolve(filePath);
17
13
  }
@@ -73,40 +69,13 @@ function shouldVersionBuildOutputPath(invalidationVersion) {
73
69
  function sanitizeCacheScope(cacheScope) {
74
70
  return cacheScope.replace(/[^a-zA-Z0-9_-]+/g, "-");
75
71
  }
76
- function createJsxCacheKey(jsx) {
77
- if (!jsx) {
78
- return "jsx:default";
79
- }
80
- return JSON.stringify({
81
- development: jsx.development ?? false,
82
- factory: jsx.factory ?? null,
83
- fragment: jsx.fragment ?? null,
84
- importSource: jsx.importSource ?? null,
85
- runtime: jsx.runtime ?? null,
86
- sideEffects: jsx.sideEffects ?? null
87
- });
88
- }
89
- function createPluginCacheKey(plugins) {
90
- if (!plugins || plugins.length === 0) {
91
- return "plugins:default";
92
- }
93
- return `plugins:${plugins.map((plugin) => `${plugin.name}:${hashPluginSetup(plugin.setup)}`).join(",")}`;
94
- }
95
- function hashPluginSetup(setup) {
96
- let hash = 0;
97
- const source = setup.toString();
98
- for (let index = 0; index < source.length; index += 1) {
99
- hash = hash * 31 + source.charCodeAt(index) | 0;
100
- }
101
- return (hash >>> 0).toString(36);
102
- }
103
72
  export {
104
73
  ROUTE_MODULE_BUILD_CACHE_FILENAME,
105
74
  createEmptyRouteModuleBuildCacheManifest,
106
- createJsxCacheKey,
75
+ createJsxCacheKey2 as createJsxCacheKey,
107
76
  createPersistedRouteModuleBuildKey,
108
- createPluginCacheKey,
109
- getCorePackageVersion,
77
+ createPluginCacheKey2 as createPluginCacheKey,
78
+ getCorePackageVersion2 as getCorePackageVersion,
110
79
  hashPluginSetup,
111
80
  normalizeRouteModuleCachePath,
112
81
  readRouteModuleBuildCacheManifest,
@@ -1,5 +1,5 @@
1
1
  import type { BuildExecutor } from '../../build/build-adapter.js';
2
- import type { EcoBuildPlugin } from '../../build/build-types.js';
2
+ import type { EcoBuildPlugin } from '../../build/contracts/build-types.js';
3
3
  import type { AppModuleLoader } from './app-module-loader.service.js';
4
4
  import { type PageModuleBuildImportOptions } from './page-module-import.service.js';
5
5
  import type { SourceModuleLoaderFactory } from './module-loading-types.js';
@@ -33,7 +33,7 @@ It should not invent a parallel rendering stack just for build mode.
33
33
  | `static-export-context.ts` | Hook context type for `beforeStaticExport` / `afterStaticExport` |
34
34
  | `static-build-invalidation.ts` | `dist/` reset policy, production cache clearing, static-render cache context |
35
35
 
36
- Build-input fingerprinting (`hashAppConfigFile`, `createBuildInputsFingerprint`) lives in `packages/core/src/build/build-input-fingerprint.ts` and is shared with server-entry and unified-graph caches.
36
+ Build-input fingerprinting (`hashAppConfigFile`, `createBuildInputsFingerprint`) lives in `packages/core/src/build/cache/build-input-fingerprint.ts` and is shared with server-entry and unified-graph caches.
37
37
 
38
38
  ## Incremental static export
39
39
 
@@ -0,0 +1,28 @@
1
+ import type { EcoPagesAppConfig } from '../types/internal-types.js';
2
+ import type { PageRendererResolver } from '../route-renderer/route-renderer.js';
3
+ /**
4
+ * Returns whether production static export should warm Page Browser Graphs before rendering.
5
+ *
6
+ * @remarks
7
+ * True only when `NODE_ENV === 'production'`. Independent of `force` and of
8
+ * unified pages-graph env flags. Does not persist a disk manifest.
9
+ */
10
+ export declare function shouldPrebuildProductionPageBrowserGraphs(): boolean;
11
+ /**
12
+ * Clears in-memory production Page Browser Graph session records.
13
+ *
14
+ * @remarks
15
+ * Clears only the `'production'` policy so a failed or force export cannot
16
+ * reuse staged graph output. Development session records are left intact.
17
+ */
18
+ export declare function clearProductionPageBrowserGraphSession(appConfig: EcoPagesAppConfig): void;
19
+ /**
20
+ * Warms production Page Browser Graphs for the supplied static route files.
21
+ *
22
+ * @remarks
23
+ * Deduplicates and lexicographically sorts absolute route paths, then calls
24
+ * each integration renderer's `prebuildProductionPageBrowserGraph` sequentially
25
+ * (activates integration runtime, then resolves into
26
+ * `page-browser-graph-session`). Does not persist a disk manifest.
27
+ */
28
+ export declare function prebuildProductionPageBrowserGraphs(routeFiles: readonly string[], routeRendererFactory: PageRendererResolver): Promise<void>;
@@ -0,0 +1,22 @@
1
+ import path from "node:path";
2
+ import { getAppPageBrowserGraphSession } from "../route-renderer/orchestration/page-browser-graph-session.js";
3
+ function shouldPrebuildProductionPageBrowserGraphs() {
4
+ return process.env.NODE_ENV === "production";
5
+ }
6
+ function clearProductionPageBrowserGraphSession(appConfig) {
7
+ getAppPageBrowserGraphSession(appConfig).clearPolicyRecords("production");
8
+ }
9
+ async function prebuildProductionPageBrowserGraphs(routeFiles, routeRendererFactory) {
10
+ const uniqueRouteFiles = [...new Set(routeFiles.map((routeFile) => path.resolve(routeFile)))].sort(
11
+ (left, right) => left.localeCompare(right)
12
+ );
13
+ for (const routeFile of uniqueRouteFiles) {
14
+ const renderer = routeRendererFactory.getPageRenderer(routeFile);
15
+ await renderer.prebuildProductionPageBrowserGraph(routeFile);
16
+ }
17
+ }
18
+ export {
19
+ clearProductionPageBrowserGraphSession,
20
+ prebuildProductionPageBrowserGraphs,
21
+ shouldPrebuildProductionPageBrowserGraphs
22
+ };
@@ -1,7 +1,7 @@
1
1
  import type { EcoPagesAppConfig } from '../types/internal-types.js';
2
2
  import { type RouteModuleStaticRenderCacheContext } from '../services/module-loading/route-module-build-manifest.js';
3
- export type { BuildInputChangeContributor, IntegrationPlugin, Processor } from '../build/build-input-fingerprint.js';
4
- export { collectBuildInputContributors, createBuildInputsFingerprint, didBuildInputContributorChange, hashAppConfigFile, haveBuildInputsChanged, } from '../build/build-input-fingerprint.js';
3
+ export type { BuildInputChangeContributor, IntegrationPlugin, Processor, } from '../build/cache/build-input-fingerprint.js';
4
+ export { collectBuildInputContributors, createBuildInputsFingerprint, didBuildInputContributorChange, hashAppConfigFile, haveBuildInputsChanged, } from '../build/cache/build-input-fingerprint.js';
5
5
  /** Builds the static-render invalidation context for one app config. */
6
6
  export declare function createRouteModuleStaticRenderCacheContext(appConfig: EcoPagesAppConfig): RouteModuleStaticRenderCacheContext;
7
7
  /** Returns whether `dist/` should be wiped before the next static export. */
@@ -2,8 +2,8 @@ import {
2
2
  createBuildInputsFingerprint,
3
3
  hashAppConfigFile,
4
4
  haveBuildInputsChanged
5
- } from "../build/build-input-fingerprint.js";
6
- import { clearPersistedProductionBuildCacheManifests } from "../build/production-build-cache.js";
5
+ } from "../build/cache/build-input-fingerprint.js";
6
+ import { clearPersistedProductionBuildCacheManifests } from "../build/cache/production-build-cache.js";
7
7
  import {} from "../services/module-loading/route-module-build-manifest.js";
8
8
  import {
9
9
  getSharedRouteModuleBuildCache,
@@ -15,7 +15,7 @@ import {
15
15
  didBuildInputContributorChange,
16
16
  hashAppConfigFile as hashAppConfigFile2,
17
17
  haveBuildInputsChanged as haveBuildInputsChanged2
18
- } from "../build/build-input-fingerprint.js";
18
+ } from "../build/cache/build-input-fingerprint.js";
19
19
  function createRouteModuleStaticRenderCacheContext(appConfig) {
20
20
  return {
21
21
  configHash: hashAppConfigFile(appConfig),
@@ -8,7 +8,15 @@ import {
8
8
  getServerModuleBuildCacheOutdir,
9
9
  getSharedRouteModuleBuildCache
10
10
  } from "../services/module-loading/route-module-build-cache-registry.js";
11
- import { ensurePagesUnifiedGraphBuilt, shouldBuildPagesUnifiedGraph } from "../build/pages-unified-graph-build.js";
11
+ import {
12
+ ensurePagesUnifiedGraphBuilt,
13
+ shouldBuildPagesUnifiedGraph
14
+ } from "../build/cache/pages-unified-graph-build.js";
15
+ import {
16
+ clearProductionPageBrowserGraphSession,
17
+ prebuildProductionPageBrowserGraphs,
18
+ shouldPrebuildProductionPageBrowserGraphs
19
+ } from "./production-page-browser-graph-prebuild.js";
12
20
  const STATIC_SITE_GENERATOR_ERRORS = {
13
21
  ROUTE_RENDERER_FACTORY_REQUIRED: "RouteRendererFactory is required for render strategy",
14
22
  unsupportedBodyType: (bodyType) => `Unsupported body type for static generation: ${bodyType}`,
@@ -241,6 +249,9 @@ class StaticSiteGenerator {
241
249
  if (!force) {
242
250
  this.getRouteModuleBuildCache().ensureIncrementalStaticGenerationContext(this.staticRenderCacheContext);
243
251
  }
252
+ if (shouldPrebuildProductionPageBrowserGraphs() && force) {
253
+ clearProductionPageBrowserGraphSession(this.appConfig);
254
+ }
244
255
  const routes = await router.listStaticGenerationRoutes({ runtimeOrigin: baseUrl });
245
256
  if (shouldBuildPagesUnifiedGraph()) {
246
257
  await ensurePagesUnifiedGraphBuilt({
@@ -260,6 +271,12 @@ class StaticSiteGenerator {
260
271
  });
261
272
  await this.invokeStaticExportHook("beforeStaticExport", staticExportContext);
262
273
  try {
274
+ if (shouldPrebuildProductionPageBrowserGraphs() && routeRendererFactory) {
275
+ await prebuildProductionPageBrowserGraphs(
276
+ routes.map((route) => route.templateRoute.filePath),
277
+ routeRendererFactory
278
+ );
279
+ }
263
280
  this.generateRobotsTxt();
264
281
  await this.generateStaticPages(
265
282
  router,
@@ -280,6 +297,11 @@ class StaticSiteGenerator {
280
297
  if (preserveExportDirectory) {
281
298
  this.pruneStaleStaticOutputs(activeStaticPathnames);
282
299
  }
300
+ } catch (error) {
301
+ if (shouldPrebuildProductionPageBrowserGraphs()) {
302
+ clearProductionPageBrowserGraphSession(this.appConfig);
303
+ }
304
+ throw error;
283
305
  } finally {
284
306
  await this.invokeStaticExportHook("afterStaticExport", staticExportContext);
285
307
  }
@@ -1,7 +1,7 @@
1
- import type { EcoBuildPlugin } from '../build/build-types.js';
2
- import type { AppBuildManifest } from '../build/build-manifest.js';
1
+ import type { EcoBuildPlugin } from '../build/contracts/build-types.js';
2
+ import type { AppBuildManifest } from '../build/contracts/build-manifest.js';
3
3
  import type { BuildAdapter, BuildOwnership } from '../build/build-adapter.js';
4
- import type { BuildRuntime } from '../build/build-runtime.js';
4
+ import type { BuildRuntime } from '../build/runtime/build-runtime.js';
5
5
  import type { AnyIntegrationPlugin } from '../plugins/integration-plugin.js';
6
6
  import type { Processor } from '../plugins/processor.js';
7
7
  import type { EcoSourceTransform } from '../plugins/source-transform.js';
@@ -12,6 +12,7 @@ import type { DevGraphService } from '../services/runtime-state/dev-graph.servic
12
12
  import type { AppModuleLoader } from '../services/module-loading/app-module-loader.service.js';
13
13
  import type { SourceModuleLoader } from '../services/module-loading/module-loading-types.js';
14
14
  import type { EntrypointDependencyGraph } from '../services/runtime-state/entrypoint-dependency-graph.service.js';
15
+ import type { SessionPageBrowserGraphCache } from '../route-renderer/orchestration/page-browser-graph-session.js';
15
16
  import type { ServerInvalidationState } from '../services/runtime-state/server-invalidation-state.service.js';
16
17
  import type { ServerModuleTranspiler } from '../services/module-loading/server-module-transpiler.service.js';
17
18
  import type { RouteModuleBuildCache } from '../services/module-loading/route-module-build-cache.store.js';
@@ -155,6 +156,7 @@ export type EcoPagesAppConfig = {
155
156
  buildManifest?: AppBuildManifest;
156
157
  devGraphService?: DevGraphService;
157
158
  entrypointDependencyGraph?: EntrypointDependencyGraph;
159
+ pageBrowserGraphSession?: SessionPageBrowserGraphCache;
158
160
  hostModuleLoader?: SourceModuleLoader;
159
161
  rendererModuleContext?: unknown;
160
162
  serverInvalidationState?: ServerInvalidationState;
@@ -164,6 +166,10 @@ export type EcoPagesAppConfig = {
164
166
  buildRuntime?: BuildRuntime;
165
167
  /** Set after {@link setupAppRuntimePlugins} runs processor/integration setup once per process. */
166
168
  runtimeAssetsPrepared?: boolean;
169
+ /** Registers integration runtime plugins when lazy activation completes. */
170
+ onRuntimePlugin?: (plugin: import('../build/contracts/build-types.js').EcoBuildPlugin) => void;
171
+ /** Integration names that completed lazy runtime activation. */
172
+ activatedIntegrations?: Set<string>;
167
173
  /** When `'host'`, the embedded dev server owns browser dev-client bootstrap. */
168
174
  devClientOwner?: 'core' | 'host';
169
175
  /** Integration hooks run when a registered `dependencies.scripts` entrypoint changes. */
@@ -236,4 +242,4 @@ export interface EcoPagesFileSystemServerAdapter<ServerInstanceOptions = unknown
236
242
  server: unknown;
237
243
  }>;
238
244
  }
239
- export type { ClientBridgeEvent, DefaultHmrContext, IHmrManager, IClientBridge } from './public-types.js';
245
+ export type { ClientBridgeEvent, DefaultHmrContext, HmrFileChangeOptions, IHmrManager, IClientBridge, } from './public-types.js';