@ecopages/core 0.2.0-beta.2 → 0.2.0-beta.20

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 (273) hide show
  1. package/README.md +1 -1
  2. package/package.json +163 -3
  3. package/src/adapters/abstract/application-adapter.d.ts +104 -5
  4. package/src/adapters/abstract/application-adapter.js +125 -1
  5. package/src/adapters/abstract/server-adapter.d.ts +6 -2
  6. package/src/adapters/abstract/ws-pattern-matcher.d.ts +60 -0
  7. package/src/adapters/abstract/ws-pattern-matcher.js +61 -0
  8. package/src/adapters/bun/client-bridge.d.ts +1 -0
  9. package/src/adapters/bun/client-bridge.js +3 -0
  10. package/src/adapters/bun/create-app.d.ts +6 -4
  11. package/src/adapters/bun/create-app.js +65 -43
  12. package/src/adapters/bun/hmr-manager.d.ts +2 -1
  13. package/src/adapters/bun/hmr-manager.js +2 -2
  14. package/src/adapters/bun/server-adapter.d.ts +90 -22
  15. package/src/adapters/bun/server-adapter.js +265 -84
  16. package/src/adapters/bun/static-preview-host.js +25 -20
  17. package/src/adapters/create-app.d.ts +13 -11
  18. package/src/adapters/create-app.js +2 -51
  19. package/src/adapters/index.d.ts +1 -1
  20. package/src/adapters/index.js +1 -2
  21. package/src/adapters/node/create-app.d.ts +5 -1
  22. package/src/adapters/node/create-app.js +51 -12
  23. package/src/adapters/node/node-client-bridge.d.ts +1 -0
  24. package/src/adapters/node/node-client-bridge.js +3 -0
  25. package/src/adapters/node/node-hmr-manager.d.ts +2 -1
  26. package/src/adapters/node/node-hmr-manager.js +2 -2
  27. package/src/adapters/node/server-adapter-dependencies.js +4 -0
  28. package/src/adapters/node/server-adapter.d.ts +62 -20
  29. package/src/adapters/node/server-adapter.js +161 -131
  30. package/src/adapters/node/static-content-server.d.ts +1 -0
  31. package/src/adapters/node/static-content-server.js +10 -2
  32. package/src/adapters/node/static-preview-host.js +27 -12
  33. package/src/adapters/shared/bun-user-websocket-lifecycle.d.ts +22 -0
  34. package/src/adapters/shared/bun-user-websocket-lifecycle.js +96 -0
  35. package/src/adapters/shared/copy-runtime-public-dir.d.ts +6 -0
  36. package/src/adapters/shared/copy-runtime-public-dir.js +24 -0
  37. package/src/adapters/shared/fs-server-response-matcher.d.ts +2 -0
  38. package/src/adapters/shared/fs-server-response-matcher.js +40 -18
  39. package/src/adapters/shared/hmr-entrypoint-registrar.d.ts +0 -2
  40. package/src/adapters/shared/hmr-entrypoint-registrar.js +3 -26
  41. package/src/adapters/shared/hmr-html-response.d.ts +1 -1
  42. package/src/adapters/shared/hmr-html-response.js +4 -1
  43. package/src/adapters/shared/node-http-websocket-upgrades.d.ts +21 -0
  44. package/src/adapters/shared/node-http-websocket-upgrades.js +100 -0
  45. package/src/adapters/shared/port-manager.d.ts +116 -0
  46. package/src/adapters/shared/port-manager.js +196 -0
  47. package/src/adapters/shared/runtime-app-bootstrap.d.ts +2 -1
  48. package/src/adapters/shared/runtime-app-bootstrap.js +3 -6
  49. package/src/adapters/shared/runtime-server-lifecycle.d.ts +38 -0
  50. package/src/adapters/shared/runtime-server-lifecycle.js +43 -0
  51. package/src/adapters/shared/server-adapter.d.ts +2 -1
  52. package/src/adapters/shared/server-adapter.js +13 -6
  53. package/src/adapters/shared/server-route-handler.d.ts +4 -1
  54. package/src/adapters/shared/server-route-handler.js +5 -2
  55. package/src/adapters/shared/server-static-builder.d.ts +23 -32
  56. package/src/adapters/shared/server-static-builder.js +97 -73
  57. package/src/adapters/shared/shared-hmr-manager.d.ts +28 -0
  58. package/src/adapters/shared/shared-hmr-manager.js +119 -9
  59. package/src/adapters/shared/static-preview-host.d.ts +5 -0
  60. package/src/adapters/shared/websocket-lifecycle.d.ts +24 -0
  61. package/src/adapters/shared/websocket-lifecycle.js +55 -0
  62. package/src/build/README.md +77 -14
  63. package/src/build/app-build-manifest-runtime.d.ts +10 -0
  64. package/src/build/app-build-manifest-runtime.js +90 -0
  65. package/src/build/build-adapter.d.ts +17 -319
  66. package/src/build/build-adapter.js +28 -94
  67. package/src/build/build-contracts.d.ts +97 -0
  68. package/src/build/build-contracts.js +0 -0
  69. package/src/build/build-input-fingerprint.d.ts +28 -0
  70. package/src/build/build-input-fingerprint.js +31 -0
  71. package/src/build/build-profile-options.d.ts +7 -0
  72. package/src/build/build-profile-options.js +37 -0
  73. package/src/build/build-runtime.d.ts +24 -0
  74. package/src/build/build-runtime.js +65 -0
  75. package/src/build/deduping-build-executor.d.ts +28 -0
  76. package/src/build/deduping-build-executor.js +56 -0
  77. package/src/build/jsx-ownership-plugins.d.ts +24 -0
  78. package/src/build/jsx-ownership-plugins.js +41 -0
  79. package/src/build/pages-unified-graph-build.d.ts +31 -0
  80. package/src/build/pages-unified-graph-build.js +206 -0
  81. package/src/build/parallel-build-executor.d.ts +21 -0
  82. package/src/build/parallel-build-executor.js +52 -0
  83. package/src/build/production-build-cache.d.ts +20 -0
  84. package/src/build/production-build-cache.js +63 -0
  85. package/src/build/rolldown-adapter-helpers.d.ts +3 -6
  86. package/src/build/rolldown-adapter-helpers.js +71 -6
  87. package/src/build/rolldown-build-adapter.d.ts +2 -6
  88. package/src/build/rolldown-build-adapter.js +3 -3
  89. package/src/build/rolldown-build-invocation-metrics.d.ts +12 -0
  90. package/src/build/rolldown-build-invocation-metrics.js +43 -0
  91. package/src/build/rolldown-plugin-bridge.d.ts +15 -1
  92. package/src/build/rolldown-plugin-bridge.js +20 -5
  93. package/src/build/rolldown-source-transform-pass.d.ts +15 -0
  94. package/src/build/rolldown-source-transform-pass.js +58 -0
  95. package/src/build/runtime-build-executor.d.ts +8 -15
  96. package/src/build/runtime-build-executor.js +12 -15
  97. package/src/build/runtime-build-output-normalizer.d.ts +7 -0
  98. package/src/build/runtime-build-output-normalizer.js +94 -2
  99. package/src/build/server-entry-build-cache.d.ts +44 -0
  100. package/src/build/server-entry-build-cache.js +161 -0
  101. package/src/client/navigation-scripts/classification.d.ts +16 -0
  102. package/src/client/navigation-scripts/classification.js +41 -0
  103. package/src/client/navigation-scripts/index.d.ts +3 -0
  104. package/src/client/navigation-scripts/index.js +23 -0
  105. package/src/client/navigation-scripts/navigation-scripts.test.browser.js +65 -0
  106. package/src/client/navigation-scripts/registry.d.ts +11 -0
  107. package/src/client/navigation-scripts/registry.js +12 -0
  108. package/src/client/navigation-scripts/rerun-queue.d.ts +37 -0
  109. package/src/client/navigation-scripts/rerun-queue.js +73 -0
  110. package/src/client/scroll.d.ts +17 -0
  111. package/src/client/scroll.js +25 -0
  112. package/src/client/scroll.test.browser.js +37 -0
  113. package/src/client/view-transitions.d.ts +16 -0
  114. package/src/client/view-transitions.js +63 -0
  115. package/src/config/config-builder.d.ts +12 -7
  116. package/src/config/config-builder.js +12 -9
  117. package/src/dev/client-bridge-registry.d.ts +5 -0
  118. package/src/dev/client-bridge-registry.js +15 -0
  119. package/src/dev/dev-client-ownership.d.ts +7 -0
  120. package/src/dev/dev-client-ownership.js +6 -0
  121. package/src/dev/hmr-manager-registry.d.ts +8 -0
  122. package/src/dev/hmr-manager-registry.js +15 -0
  123. package/src/dev/host-runtime.d.ts +3 -0
  124. package/src/dev/host-runtime.js +7 -0
  125. package/src/dev/runtime-server-started-message.d.ts +2 -0
  126. package/src/dev/runtime-server-started-message.js +6 -0
  127. package/src/eco/README.md +11 -0
  128. package/src/eco/eco-declared-component.d.ts +14 -0
  129. package/src/eco/eco-declared-component.js +16 -0
  130. package/src/eco/eco.browser.js +5 -6
  131. package/src/eco/eco.js +5 -6
  132. package/src/eco/eco.types.d.ts +2 -2
  133. package/src/eco/page-layout-normalization.d.ts +21 -0
  134. package/src/eco/page-layout-normalization.js +59 -0
  135. package/src/errors/index.d.ts +1 -0
  136. package/src/errors/index.js +7 -1
  137. package/src/errors/undeclared-component-dependency-error.d.ts +11 -0
  138. package/src/errors/undeclared-component-dependency-error.js +17 -0
  139. package/src/hmr/client/hmr-runtime.js +5 -2
  140. package/src/hmr/hmr-entrypoint-output.d.ts +28 -0
  141. package/src/hmr/hmr-entrypoint-output.js +58 -0
  142. package/src/hmr/strategies/js-hmr-strategy.d.ts +3 -0
  143. package/src/hmr/strategies/js-hmr-strategy.js +68 -18
  144. package/src/hmr/strategies/server-rendered-template-hmr-strategy.d.ts +17 -0
  145. package/src/hmr/strategies/server-rendered-template-hmr-strategy.js +29 -0
  146. package/src/integrations/ghtml/ghtml-renderer.d.ts +2 -6
  147. package/src/integrations/ghtml/ghtml-renderer.js +2 -51
  148. package/src/integrations/ghtml/ghtml.plugin.d.ts +3 -16
  149. package/src/integrations/ghtml/ghtml.plugin.js +7 -14
  150. package/src/plugins/define-integration.d.ts +26 -0
  151. package/src/plugins/define-integration.js +19 -0
  152. package/src/plugins/eco-component-meta-plugin.js +5 -8
  153. package/src/plugins/foreign-jsx-override-plugin.js +4 -6
  154. package/src/plugins/integration-plugin.d.ts +19 -9
  155. package/src/plugins/integration-plugin.js +7 -4
  156. package/src/plugins/jsx-import-source.utils.d.ts +8 -0
  157. package/src/plugins/jsx-import-source.utils.js +26 -0
  158. package/src/plugins/processor.d.ts +19 -4
  159. package/src/plugins/processor.js +22 -4
  160. package/src/plugins/source-transform.d.ts +31 -0
  161. package/src/plugins/source-transform.js +23 -1
  162. package/src/route-renderer/GRAPH.md +8 -8
  163. package/src/route-renderer/README.md +30 -28
  164. package/src/route-renderer/orchestration/component-graph-collectors.d.ts +10 -0
  165. package/src/route-renderer/orchestration/component-graph-collectors.js +143 -0
  166. package/src/route-renderer/orchestration/component-graph.d.ts +36 -0
  167. package/src/route-renderer/orchestration/component-graph.js +98 -0
  168. package/src/route-renderer/orchestration/component-render-context.d.ts +3 -10
  169. package/src/route-renderer/orchestration/component-render-context.js +3 -1
  170. package/src/route-renderer/orchestration/declared-ownership-graph.d.ts +1 -18
  171. package/src/route-renderer/orchestration/declared-ownership-graph.js +5 -31
  172. package/src/route-renderer/orchestration/document-shell-render.service.d.ts +90 -0
  173. package/src/route-renderer/orchestration/document-shell-render.service.js +120 -0
  174. package/src/route-renderer/orchestration/foreign-subtree-execution.service.d.ts +59 -29
  175. package/src/route-renderer/orchestration/foreign-subtree-execution.service.js +164 -35
  176. package/src/route-renderer/orchestration/global-injector-assets.service.d.ts +7 -0
  177. package/src/route-renderer/orchestration/global-injector-assets.service.js +32 -0
  178. package/src/route-renderer/orchestration/integration-renderer.d.ts +18 -54
  179. package/src/route-renderer/orchestration/integration-renderer.js +113 -195
  180. package/src/route-renderer/orchestration/integration-route-render-adapter.d.ts +38 -0
  181. package/src/route-renderer/orchestration/integration-route-render-adapter.js +27 -0
  182. package/src/route-renderer/orchestration/layout-shell-props.service.d.ts +20 -0
  183. package/src/route-renderer/orchestration/layout-shell-props.service.js +31 -0
  184. package/src/route-renderer/orchestration/ownership-validation.service.d.ts +5 -0
  185. package/src/route-renderer/orchestration/ownership-validation.service.js +29 -1
  186. package/src/route-renderer/orchestration/page-browser-graph-contribution.loader.d.ts +9 -0
  187. package/src/route-renderer/orchestration/page-browser-graph-contribution.loader.js +7 -0
  188. package/src/route-renderer/orchestration/page-browser-graph.service.d.ts +25 -0
  189. package/src/route-renderer/orchestration/page-browser-graph.service.js +174 -0
  190. package/src/route-renderer/orchestration/render-output.utils.d.ts +2 -0
  191. package/src/route-renderer/orchestration/render-output.utils.js +4 -0
  192. package/src/route-renderer/orchestration/route-html-finalization.service.d.ts +17 -0
  193. package/src/route-renderer/orchestration/route-html-finalization.service.js +26 -0
  194. package/src/route-renderer/orchestration/route-prepared-options.builder.d.ts +26 -0
  195. package/src/route-renderer/orchestration/route-prepared-options.builder.js +54 -0
  196. package/src/route-renderer/orchestration/route-prepared-options.utils.d.ts +4 -0
  197. package/src/route-renderer/orchestration/route-prepared-options.utils.js +33 -0
  198. package/src/route-renderer/orchestration/route-render-orchestrator.d.ts +8 -39
  199. package/src/route-renderer/orchestration/route-render-orchestrator.js +53 -461
  200. package/src/route-renderer/orchestration/string-markup-renderer.d.ts +14 -0
  201. package/src/route-renderer/orchestration/string-markup-renderer.js +55 -0
  202. package/src/route-renderer/page-loading/component-dependency-collection.js +5 -2
  203. package/src/router/client/link-intent.d.ts +11 -21
  204. package/src/router/client/link-intent.js +10 -0
  205. package/src/router/client/link-intent.test.browser.js +12 -1
  206. package/src/router/client/link-navigation-policy.d.ts +45 -0
  207. package/src/router/client/link-navigation-policy.js +101 -0
  208. package/src/router/client/link-navigation-policy.test.browser.d.ts +1 -0
  209. package/src/router/client/link-navigation-policy.test.browser.js +92 -0
  210. package/src/router/client/navigation-coordinator.d.ts +1 -1
  211. package/src/router/client/navigation-coordinator.js +12 -2
  212. package/src/services/assets/asset-processing-service/browser-runtime-asset.factory.d.ts +1 -0
  213. package/src/services/assets/asset-processing-service/browser-runtime-asset.factory.js +1 -0
  214. package/src/services/assets/asset-processing-service/browser-runtime-entry.factory.d.ts +4 -2
  215. package/src/services/assets/asset-processing-service/browser-runtime-entry.factory.js +27 -7
  216. package/src/services/assets/asset-processing-service/processors/script/file-script.processor.js +36 -14
  217. package/src/services/assets/asset-processing-service/processors/script/node-module-script.processor.js +17 -3
  218. package/src/services/assets/asset-processing-service/processors/stylesheet/content-stylesheet.processor.d.ts +0 -3
  219. package/src/services/assets/asset-processing-service/processors/stylesheet/content-stylesheet.processor.js +2 -31
  220. package/src/services/assets/asset-processing-service/processors/stylesheet/file-stylesheet.processor.d.ts +0 -3
  221. package/src/services/assets/asset-processing-service/processors/stylesheet/file-stylesheet.processor.js +2 -30
  222. package/src/services/assets/asset-processing-service/processors/stylesheet/stylesheet-processor-pipeline.d.ts +2 -0
  223. package/src/services/assets/asset-processing-service/processors/stylesheet/stylesheet-processor-pipeline.js +43 -0
  224. package/src/services/assets/browser-bundle.service.d.ts +3 -1
  225. package/src/services/assets/browser-bundle.service.js +17 -5
  226. package/src/services/html/html-transformer.service.d.ts +1 -1
  227. package/src/services/html/html-transformer.service.js +4 -4
  228. package/src/services/invalidation/development-invalidation.service.d.ts +20 -2
  229. package/src/services/invalidation/development-invalidation.service.js +56 -2
  230. package/src/services/module-loading/README.md +49 -0
  231. package/src/services/module-loading/app-server-module-transpiler.service.js +5 -17
  232. package/src/services/module-loading/page-module-import.service.d.ts +5 -1
  233. package/src/services/module-loading/page-module-import.service.js +97 -45
  234. package/src/services/module-loading/route-module-build-cache-registry.d.ts +24 -0
  235. package/src/services/module-loading/route-module-build-cache-registry.js +37 -0
  236. package/src/services/module-loading/route-module-build-cache.d.ts +4 -0
  237. package/src/services/module-loading/route-module-build-cache.js +38 -0
  238. package/src/services/module-loading/route-module-build-cache.store.d.ts +57 -0
  239. package/src/services/module-loading/route-module-build-cache.store.js +207 -0
  240. package/src/services/module-loading/route-module-build-manifest.d.ts +61 -0
  241. package/src/services/module-loading/route-module-build-manifest.js +116 -0
  242. package/src/services/module-loading/route-module-dependency-hasher.d.ts +81 -0
  243. package/src/services/module-loading/route-module-dependency-hasher.js +121 -0
  244. package/src/services/module-loading/server-module-transpiler.service.js +1 -1
  245. package/src/static-site-generator/README.md +33 -0
  246. package/src/static-site-generator/static-build-invalidation.d.ts +10 -0
  247. package/src/static-site-generator/static-build-invalidation.js +59 -0
  248. package/src/static-site-generator/static-export-context.d.ts +22 -0
  249. package/src/static-site-generator/static-export-context.js +0 -0
  250. package/src/static-site-generator/static-site-generator.d.ts +17 -20
  251. package/src/static-site-generator/static-site-generator.js +188 -85
  252. package/src/types/internal-types.d.ts +16 -9
  253. package/src/types/public-types.d.ts +138 -26
  254. package/src/utils/parse-cli-args.d.ts +2 -0
  255. package/src/utils/parse-cli-args.js +6 -0
  256. package/src/utils/server-utils.module.d.ts +3 -2
  257. package/src/utils/server-utils.module.js +5 -6
  258. package/src/utils/static-file-extensions.d.ts +12 -0
  259. package/src/utils/static-file-extensions.js +48 -0
  260. package/src/watchers/project-watcher-ignore.d.ts +11 -0
  261. package/src/watchers/project-watcher-ignore.js +16 -0
  262. package/src/watchers/project-watcher.d.ts +25 -2
  263. package/src/watchers/project-watcher.js +130 -23
  264. package/src/build/rolldown-dev-build-adapter.d.ts +0 -82
  265. package/src/build/rolldown-dev-build-adapter.js +0 -166
  266. package/src/hmr/hmr.postcss.test.e2e.js +0 -31
  267. package/src/hmr/hmr.test.e2e.js +0 -43
  268. package/src/route-renderer/orchestration/ownership-planning.service.d.ts +0 -24
  269. package/src/route-renderer/orchestration/ownership-planning.service.js +0 -63
  270. package/src/route-renderer/orchestration/queued-foreign-subtree-resolution.service.d.ts +0 -91
  271. package/src/route-renderer/orchestration/queued-foreign-subtree-resolution.service.js +0 -170
  272. /package/src/{hmr/hmr.postcss.test.e2e.d.ts → client/navigation-scripts/navigation-scripts.test.browser.d.ts} +0 -0
  273. /package/src/{hmr/hmr.test.e2e.d.ts → client/scroll.test.browser.d.ts} +0 -0
@@ -0,0 +1,28 @@
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
+ /**
5
+ * Optional contributor surface for build-time cache invalidation.
6
+ *
7
+ * @remarks
8
+ * Processors and integrations may override {@link didChange} to report that
9
+ * their build inputs changed independently of route source files.
10
+ */
11
+ export interface BuildInputChangeContributor {
12
+ /**
13
+ * Returns `true` when this contributor's build inputs changed since the last
14
+ * persisted incremental build metadata was written.
15
+ */
16
+ didChange?(): boolean;
17
+ }
18
+ /** Returns whether a processor or integration signals changed build inputs. */
19
+ export declare function didBuildInputContributorChange(contributor: BuildInputChangeContributor): boolean;
20
+ /** Hashes the app's eco.config.ts file when present. */
21
+ export declare function hashAppConfigFile(appConfig: EcoPagesAppConfig): string;
22
+ /** Fingerprints processor/integration build-input state for cache invalidation. */
23
+ export declare function createBuildInputsFingerprint(appConfig: EcoPagesAppConfig): string;
24
+ /** Returns true when any processor or integration reports changed build inputs. */
25
+ export declare function haveBuildInputsChanged(appConfig: EcoPagesAppConfig): boolean;
26
+ /** Collects every processor and integration that can invalidate incremental builds. */
27
+ export declare function collectBuildInputContributors(appConfig: EcoPagesAppConfig): BuildInputChangeContributor[];
28
+ export type { Processor, IntegrationPlugin };
@@ -0,0 +1,31 @@
1
+ import { fileSystem } from "@ecopages/file-system";
2
+ function didBuildInputContributorChange(contributor) {
3
+ return contributor.didChange?.() === true;
4
+ }
5
+ function hashAppConfigFile(appConfig) {
6
+ const configPath = appConfig.absolutePaths?.config;
7
+ if (!configPath || !fileSystem.exists(configPath)) {
8
+ return "missing";
9
+ }
10
+ return fileSystem.hash(configPath);
11
+ }
12
+ function createBuildInputsFingerprint(appConfig) {
13
+ const changedContributors = [
14
+ ...Array.from(appConfig.processors?.values() ?? []).filter((processor) => didBuildInputContributorChange(processor)).map((processor) => `processor:${processor.getName()}`),
15
+ ...(appConfig.integrations ?? []).filter((integration) => didBuildInputContributorChange(integration)).map((integration) => `integration:${integration.name}`)
16
+ ];
17
+ return changedContributors.length > 0 ? changedContributors.sort().join("|") : "stable";
18
+ }
19
+ function haveBuildInputsChanged(appConfig) {
20
+ return createBuildInputsFingerprint(appConfig) !== "stable";
21
+ }
22
+ function collectBuildInputContributors(appConfig) {
23
+ return [...Array.from(appConfig.processors?.values() ?? []), ...appConfig.integrations ?? []];
24
+ }
25
+ export {
26
+ collectBuildInputContributors,
27
+ createBuildInputsFingerprint,
28
+ didBuildInputContributorChange,
29
+ hashAppConfigFile,
30
+ haveBuildInputsChanged
31
+ };
@@ -0,0 +1,7 @@
1
+ import type { BuildOptions } from './build-adapter.js';
2
+ import type { BuildProfile } from './build-runtime.js';
3
+ import type { EcoPagesAppConfig } from '../types/internal-types.js';
4
+ /**
5
+ * Resolves shared Rolldown options for a build profile.
6
+ */
7
+ export declare function resolveBuildProfileOptions(profile: BuildProfile, appConfig: EcoPagesAppConfig, overrides?: Partial<BuildOptions>): Partial<BuildOptions>;
@@ -0,0 +1,37 @@
1
+ function resolveBuildProfileOptions(profile, appConfig, overrides = {}) {
2
+ const root = appConfig.rootDir;
3
+ switch (profile) {
4
+ case "server-entry":
5
+ return {
6
+ root,
7
+ target: "node",
8
+ format: "esm",
9
+ sourcemap: "none",
10
+ minify: false,
11
+ externalPackages: true,
12
+ ...overrides
13
+ };
14
+ case "route-module":
15
+ return {
16
+ root,
17
+ target: "es2022",
18
+ format: "esm",
19
+ sourcemap: "none",
20
+ minify: false,
21
+ externalPackages: true,
22
+ ...overrides
23
+ };
24
+ case "browser-hmr":
25
+ return {
26
+ root,
27
+ target: "browser",
28
+ format: "esm",
29
+ sourcemap: "none",
30
+ minify: false,
31
+ ...overrides
32
+ };
33
+ }
34
+ }
35
+ export {
36
+ resolveBuildProfileOptions
37
+ };
@@ -0,0 +1,24 @@
1
+ import type { EcoPagesAppConfig } from '../types/internal-types.js';
2
+ import { type BuildExecutor } from './build-adapter.js';
3
+ export type BuildProfile = 'server-entry' | 'route-module' | 'browser-hmr';
4
+ export interface BuildRuntime {
5
+ getProfile(profile: BuildProfile): BuildExecutor;
6
+ dispose(): Promise<void>;
7
+ }
8
+ export declare function getBuildRuntime(appConfig: EcoPagesAppConfig): BuildRuntime | undefined;
9
+ /**
10
+ * Returns the installed build runtime, installing it when missing.
11
+ */
12
+ export declare function requireBuildRuntime(appConfig: EcoPagesAppConfig): BuildRuntime;
13
+ /**
14
+ * Installs profile-based build executors for one app instance.
15
+ *
16
+ * @remarks
17
+ * All profiles use one-shot Rolldown. Server-entry stays serialized
18
+ * single-flight; route-module and browser-HMR run in parallel.
19
+ */
20
+ export declare function installBuildRuntime(appConfig: EcoPagesAppConfig): BuildRuntime;
21
+ /**
22
+ * No-op retained for server teardown call sites.
23
+ */
24
+ export declare function disposeAppBuildRuntime(appConfig: EcoPagesAppConfig): Promise<void>;
@@ -0,0 +1,65 @@
1
+ import { availableParallelism } from "node:os";
2
+ import {
3
+ getAppBrowserBuildPlugins,
4
+ getAppBuildAdapter,
5
+ getAppServerBuildPlugins,
6
+ withBuildExecutorPlugins
7
+ } from "./build-adapter.js";
8
+ import { ParallelBuildExecutor } from "./parallel-build-executor.js";
9
+ import { DedupingBuildExecutor } from "./deduping-build-executor.js";
10
+ import { SerializedBuildExecutor } from "./serialized-build-executor.js";
11
+ function resolveParallelismLimit() {
12
+ return Math.max(1, availableParallelism() - 1);
13
+ }
14
+ function patchAppRuntime(appConfig, patch) {
15
+ appConfig.runtime = {
16
+ ...appConfig.runtime ?? {},
17
+ ...patch
18
+ };
19
+ }
20
+ class AppBuildRuntime {
21
+ serverEntryExecutor;
22
+ routeModuleExecutor;
23
+ hmrExecutor;
24
+ constructor(appConfig) {
25
+ const adapter = getAppBuildAdapter(appConfig);
26
+ const serverPlugins = withBuildExecutorPlugins(adapter, () => getAppServerBuildPlugins(appConfig));
27
+ const browserPlugins = withBuildExecutorPlugins(adapter, () => getAppBrowserBuildPlugins(appConfig));
28
+ const limit = resolveParallelismLimit();
29
+ this.serverEntryExecutor = new SerializedBuildExecutor(serverPlugins);
30
+ this.routeModuleExecutor = new DedupingBuildExecutor(new ParallelBuildExecutor(serverPlugins, limit));
31
+ this.hmrExecutor = new DedupingBuildExecutor(new ParallelBuildExecutor(browserPlugins, Math.min(3, limit)));
32
+ }
33
+ getProfile(profile) {
34
+ switch (profile) {
35
+ case "server-entry":
36
+ return this.serverEntryExecutor;
37
+ case "route-module":
38
+ return this.routeModuleExecutor;
39
+ case "browser-hmr":
40
+ return this.hmrExecutor;
41
+ }
42
+ }
43
+ async dispose() {
44
+ }
45
+ }
46
+ function getBuildRuntime(appConfig) {
47
+ return appConfig.runtime?.buildRuntime;
48
+ }
49
+ function requireBuildRuntime(appConfig) {
50
+ return getBuildRuntime(appConfig) ?? installBuildRuntime(appConfig);
51
+ }
52
+ function installBuildRuntime(appConfig) {
53
+ const buildRuntime = new AppBuildRuntime(appConfig);
54
+ patchAppRuntime(appConfig, { buildRuntime });
55
+ return buildRuntime;
56
+ }
57
+ async function disposeAppBuildRuntime(appConfig) {
58
+ await getBuildRuntime(appConfig)?.dispose();
59
+ }
60
+ export {
61
+ disposeAppBuildRuntime,
62
+ getBuildRuntime,
63
+ installBuildRuntime,
64
+ requireBuildRuntime
65
+ };
@@ -0,0 +1,28 @@
1
+ import type { BuildExecutor, BuildOptions, BuildResult } from './build-adapter.js';
2
+ /**
3
+ * Stable cache key for coalescing concurrent identical build requests.
4
+ *
5
+ * @remarks
6
+ * Reuses the same material as route-module disk cache keys: normalized entrypoints,
7
+ * outdir, splitting, JSX, and plugin setup fingerprints.
8
+ */
9
+ export declare function createBuildOptionsDedupeKey(options: BuildOptions): string;
10
+ /**
11
+ * In-flight build coalescing wrapper.
12
+ *
13
+ * @remarks
14
+ * `ParallelBuildExecutor` allows concurrent builds but does not dedupe identical
15
+ * options. Multiple callers (route import, browser bundles, HMR) can hit the
16
+ * same Rolldown request before disk or import caches warm. This wrapper shares
17
+ * one inner `build()` promise per dedupe key until it settles.
18
+ *
19
+ * Wrap route-module and browser-hmr profiles only; server-entry stays serialized.
20
+ */
21
+ export declare class DedupingBuildExecutor implements BuildExecutor {
22
+ private readonly inner;
23
+ private readonly inFlight;
24
+ constructor(inner: BuildExecutor);
25
+ build(options: BuildOptions): Promise<BuildResult>;
26
+ unwrap(): BuildExecutor;
27
+ getInFlightCountForTests(): number;
28
+ }
@@ -0,0 +1,56 @@
1
+ import path from "node:path";
2
+ import { createJsxCacheKey, createPluginCacheKey } from "../services/module-loading/route-module-build-manifest.js";
3
+ function createBuildOptionsDedupeKey(options) {
4
+ return [
5
+ normalizeEntrypoints(options.entrypoints),
6
+ options.root ? path.resolve(options.root) : "root:default",
7
+ options.outdir ? path.resolve(options.outdir) : "outdir:default",
8
+ options.splitting ?? "splitting:default",
9
+ options.externalPackages ?? "externalPackages:default",
10
+ options.target ?? "target:default",
11
+ options.format ?? "format:default",
12
+ options.sourcemap ?? "sourcemap:default",
13
+ options.minify ?? "minify:default",
14
+ options.treeshaking ?? "treeshaking:default",
15
+ options.naming ?? "naming:default",
16
+ createJsxCacheKey(options.jsx),
17
+ createPluginCacheKey(options.plugins)
18
+ ].join("::");
19
+ }
20
+ function normalizeEntrypoints(entrypoints) {
21
+ if (Array.isArray(entrypoints)) {
22
+ return entrypoints.map((entrypoint) => path.resolve(entrypoint)).sort().join("|");
23
+ }
24
+ return Object.entries(entrypoints).sort(([left], [right]) => left.localeCompare(right)).map(([key, value]) => `${key}:${path.resolve(value)}`).join("|");
25
+ }
26
+ class DedupingBuildExecutor {
27
+ inner;
28
+ inFlight = /* @__PURE__ */ new Map();
29
+ constructor(inner) {
30
+ this.inner = inner;
31
+ }
32
+ build(options) {
33
+ const key = createBuildOptionsDedupeKey(options);
34
+ const existing = this.inFlight.get(key);
35
+ if (existing) {
36
+ return existing;
37
+ }
38
+ const buildPromise = this.inner.build(options).finally(() => {
39
+ if (this.inFlight.get(key) === buildPromise) {
40
+ this.inFlight.delete(key);
41
+ }
42
+ });
43
+ this.inFlight.set(key, buildPromise);
44
+ return buildPromise;
45
+ }
46
+ unwrap() {
47
+ return this.inner;
48
+ }
49
+ getInFlightCountForTests() {
50
+ return this.inFlight.size;
51
+ }
52
+ }
53
+ export {
54
+ DedupingBuildExecutor,
55
+ createBuildOptionsDedupeKey
56
+ };
@@ -0,0 +1,24 @@
1
+ import type { EcoBuildPlugin } from './build-types.js';
2
+ import type { EcoPagesAppConfig } from '../types/internal-types.js';
3
+ /**
4
+ * Foreign JSX override plugins for mixed-integration app builds.
5
+ *
6
+ * Each plugin rewrites files for one `(integration, extension)` pair with that
7
+ * integration's own `@jsxImportSource` so the bundler preserves the owning JSX
8
+ * runtime for native extension ownership.
9
+ *
10
+ * Extensions are sorted longest-first so `.page.react.tsx` wins over `.tsx`.
11
+ */
12
+ export declare function getJsxOwnershipPlugins(appConfig: EcoPagesAppConfig): EcoBuildPlugin[];
13
+ /**
14
+ * Host-scoped JSX override plugins for one integration's client bundle graph.
15
+ *
16
+ * When a host integration (for example React) bundles foreign `.tsx` files, those
17
+ * files must compile with the host JSX runtime instead of the project default.
18
+ * Use this helper for host-owned client bundles. For app-wide transpilation that
19
+ * should preserve each integration's native JSX runtime, use
20
+ * {@link getJsxOwnershipPlugins} instead.
21
+ */
22
+ export declare function getHostScopedJsxOwnershipPlugins(appConfig: EcoPagesAppConfig, hostIntegrationName: string, options?: {
23
+ name?: string;
24
+ }): EcoBuildPlugin[];
@@ -0,0 +1,41 @@
1
+ import { createForeignJsxOverridePlugin } from "../plugins/foreign-jsx-override-plugin.js";
2
+ import { collectJsxExtensions, filterJsxSourceExtensions } from "../plugins/jsx-import-source.utils.js";
3
+ function collectJsxExtensionEntries(appConfig) {
4
+ return (appConfig.integrations ?? []).filter((integration) => integration.jsxImportSource).flatMap(
5
+ (integration) => filterJsxSourceExtensions(integration.extensions).map((extension) => ({ integration, extension }))
6
+ ).sort((left, right) => right.extension.length - left.extension.length);
7
+ }
8
+ function getJsxOwnershipPlugins(appConfig) {
9
+ const jsxExtensions = collectJsxExtensionEntries(appConfig);
10
+ return jsxExtensions.map(
11
+ ({ integration, extension }) => createForeignJsxOverridePlugin({
12
+ hostJsxImportSource: integration.jsxImportSource,
13
+ foreignExtensions: [extension],
14
+ excludeExtensions: jsxExtensions.filter((candidate) => candidate.extension.length > extension.length).filter((candidate) => candidate.extension.endsWith(extension)).map((candidate) => candidate.extension),
15
+ name: `ecopages-jsx-ownership-${integration.name}-${extension.replace(/[^a-zA-Z0-9]+/g, "-")}`
16
+ })
17
+ );
18
+ }
19
+ function getHostScopedJsxOwnershipPlugins(appConfig, hostIntegrationName, options) {
20
+ const hostIntegration = (appConfig.integrations ?? []).find(
21
+ (integration) => integration.name === hostIntegrationName
22
+ );
23
+ const hostJsxImportSource = hostIntegration?.jsxImportSource;
24
+ if (!hostJsxImportSource) {
25
+ return [];
26
+ }
27
+ const foreignExtensions = collectJsxExtensions(appConfig.integrations ?? [], {
28
+ excludeIntegrationName: hostIntegrationName
29
+ });
30
+ return [
31
+ createForeignJsxOverridePlugin({
32
+ name: options?.name ?? `ecopages-jsx-ownership-host-${hostIntegrationName}`,
33
+ hostJsxImportSource,
34
+ foreignExtensions
35
+ })
36
+ ];
37
+ }
38
+ export {
39
+ getHostScopedJsxOwnershipPlugins,
40
+ getJsxOwnershipPlugins
41
+ };
@@ -0,0 +1,31 @@
1
+ /**
2
+ * Unified pages Rolldown graph (Phase A build + Phase C import).
3
+ *
4
+ * Enabled by default in production builds. Opt out with
5
+ * `ECOPAGES_UNIFIED_PAGES_GRAPH=0`. Covers all static page template extensions
6
+ * registered on the app config.
7
+ */
8
+ import type { EcoPagesAppConfig } from '../types/internal-types.js';
9
+ export declare const PAGES_UNIFIED_GRAPH_CACHE_DIR = ".server-pages-graph";
10
+ export declare const PAGES_UNIFIED_GRAPH_CACHE_FILENAME = ".build-cache.json";
11
+ export interface PagesUnifiedGraphCacheManifest {
12
+ invalidationVersion: string;
13
+ buildInputsFingerprint: string;
14
+ buildKey: string;
15
+ builtAt: number;
16
+ outputs: Record<string, string>;
17
+ }
18
+ export declare function isPagesUnifiedGraphEnabled(): boolean;
19
+ /** True when the unified graph should build or serve prebuilt page modules. */
20
+ export declare function shouldBuildPagesUnifiedGraph(): boolean;
21
+ export declare function isPagesUnifiedGraphPage(filePath: string, appConfig: EcoPagesAppConfig): boolean;
22
+ /**
23
+ * Builds eligible static pages in one Rolldown invocation and seeds route-module disk cache.
24
+ */
25
+ export declare function ensurePagesUnifiedGraphBuilt(options: {
26
+ appConfig: EcoPagesAppConfig;
27
+ entryPaths: readonly string[];
28
+ outdir: string;
29
+ force?: boolean;
30
+ }): Promise<PagesUnifiedGraphCacheManifest | undefined>;
31
+ export declare function importPagesUnifiedGraphModule<T>(appConfig: EcoPagesAppConfig, filePath: string): Promise<T | undefined>;
@@ -0,0 +1,206 @@
1
+ import path from "node:path";
2
+ import { pathToFileURL } from "node:url";
3
+ import { fileSystem } from "@ecopages/file-system";
4
+ import { appLogger } from "../global/app-logger.js";
5
+ import { build, getAppServerBuildPlugins } from "./build-adapter.js";
6
+ import { requireBuildRuntime } from "./build-runtime.js";
7
+ import { resolveBuildProfileOptions } from "./build-profile-options.js";
8
+ import { createBuildInputsFingerprint, hashAppConfigFile } from "./build-input-fingerprint.js";
9
+ import {
10
+ isProductionCacheManifestCurrent,
11
+ matchesProductionCacheBuildKey,
12
+ matchesProductionCacheFingerprint,
13
+ readProductionCacheManifest,
14
+ writeProductionCacheManifest
15
+ } from "./production-build-cache.js";
16
+ import { getCorePackageVersion } from "../services/module-loading/route-module-build-manifest.js";
17
+ import { resolveInternalExecutionDir } from "../utils/resolve-work-dir.js";
18
+ import { getSharedRouteModuleBuildCache } from "../services/module-loading/route-module-build-cache-registry.js";
19
+ import { normalizeNodeRuntimeBuildOutputFile } from "./runtime-build-output-normalizer.js";
20
+ import { resolveRouteModuleDependencyPaths } from "../services/module-loading/route-module-dependency-hasher.js";
21
+ import { getJsxOwnershipPlugins } from "./jsx-ownership-plugins.js";
22
+ const PAGES_UNIFIED_GRAPH_CACHE_DIR = ".server-pages-graph";
23
+ const PAGES_UNIFIED_GRAPH_CACHE_FILENAME = ".build-cache.json";
24
+ function isPagesUnifiedGraphEnabled() {
25
+ if (process.env.ECOPAGES_UNIFIED_PAGES_GRAPH === "0") {
26
+ return false;
27
+ }
28
+ if (process.env.ECOPAGES_UNIFIED_PAGES_GRAPH === "1") {
29
+ return true;
30
+ }
31
+ return process.env.NODE_ENV === "production";
32
+ }
33
+ function shouldBuildPagesUnifiedGraph() {
34
+ return isPagesUnifiedGraphEnabled() && process.env.NODE_ENV === "production";
35
+ }
36
+ function isPagesUnifiedGraphPage(filePath, appConfig) {
37
+ const normalizedPath = path.normalize(filePath);
38
+ return appConfig.templatesExt.some((extension) => normalizedPath.endsWith(extension));
39
+ }
40
+ function getPagesUnifiedGraphCachePath(appConfig) {
41
+ return path.join(
42
+ resolveInternalExecutionDir(appConfig),
43
+ PAGES_UNIFIED_GRAPH_CACHE_DIR,
44
+ PAGES_UNIFIED_GRAPH_CACHE_FILENAME
45
+ );
46
+ }
47
+ function createPagesUnifiedGraphBuildKey(appConfig, outdir) {
48
+ const plugins = appConfig.runtime?.buildManifest ? getAppServerBuildPlugins(appConfig) : [];
49
+ const pluginNames = [...plugins, ...getJsxOwnershipPlugins(appConfig)].map((plugin) => plugin.name).sort().join("|");
50
+ const templateExtensions = [...appConfig.templatesExt].sort().join("|");
51
+ return [
52
+ path.resolve(outdir),
53
+ hashAppConfigFile(appConfig),
54
+ templateExtensions,
55
+ pluginNames,
56
+ "es2022",
57
+ "esm",
58
+ "external-packages"
59
+ ].join("::");
60
+ }
61
+ function readPagesUnifiedGraphManifest(appConfig) {
62
+ const manifest = readProductionCacheManifest(
63
+ getPagesUnifiedGraphCachePath(appConfig)
64
+ );
65
+ if (!manifest?.outputs) {
66
+ return void 0;
67
+ }
68
+ return manifest;
69
+ }
70
+ function writePagesUnifiedGraphManifest(appConfig, manifest) {
71
+ writeProductionCacheManifest(getPagesUnifiedGraphCachePath(appConfig), manifest);
72
+ }
73
+ function createSafeGraphEntryKey(entryPath, rootDir) {
74
+ const relativePath = path.relative(rootDir, entryPath).replace(/\.[^.]+$/u, "");
75
+ const safeKey = relativePath.replace(/[^a-zA-Z0-9]+/gu, "-").replace(/^-+|-+$/gu, "");
76
+ return safeKey.length > 0 ? safeKey : "page";
77
+ }
78
+ function resolveOutputForEntrypoint(entryPath, entryKey, buildResult) {
79
+ const exactOutput = buildResult.entryOutputs?.[path.resolve(entryPath)];
80
+ if (exactOutput) {
81
+ return exactOutput;
82
+ }
83
+ for (const { path: outputPath } of buildResult.outputs) {
84
+ const outputBaseName = path.basename(outputPath);
85
+ if (outputBaseName.startsWith(`${entryKey}-`) && /\.(?:m?js)$/u.test(outputBaseName)) {
86
+ return outputPath;
87
+ }
88
+ if (outputBaseName === `${entryKey}.js` || outputBaseName === `${entryKey}.mjs`) {
89
+ return outputPath;
90
+ }
91
+ }
92
+ return void 0;
93
+ }
94
+ function isManifestValidForEntries(manifest, appConfig, outdir, entryPaths) {
95
+ if (!isProductionCacheManifestCurrent(manifest, getCorePackageVersion())) {
96
+ return false;
97
+ }
98
+ if (!matchesProductionCacheFingerprint(manifest, createBuildInputsFingerprint(appConfig))) {
99
+ return false;
100
+ }
101
+ if (!matchesProductionCacheBuildKey(manifest, createPagesUnifiedGraphBuildKey(appConfig, outdir))) {
102
+ return false;
103
+ }
104
+ return entryPaths.every((entryPath) => {
105
+ const resolvedEntryPath = path.resolve(entryPath);
106
+ const outputPath = manifest.outputs[resolvedEntryPath];
107
+ return outputPath ? fileSystem.exists(outputPath) : false;
108
+ });
109
+ }
110
+ async function ensurePagesUnifiedGraphBuilt(options) {
111
+ if (!shouldBuildPagesUnifiedGraph()) {
112
+ return void 0;
113
+ }
114
+ const eligibleEntryPaths = options.entryPaths.map((entryPath) => path.resolve(entryPath)).filter((entryPath) => isPagesUnifiedGraphPage(entryPath, options.appConfig));
115
+ if (eligibleEntryPaths.length === 0) {
116
+ return void 0;
117
+ }
118
+ const outdir = path.resolve(options.outdir);
119
+ const existingManifest = options.force ? void 0 : readPagesUnifiedGraphManifest(options.appConfig);
120
+ if (existingManifest && isManifestValidForEntries(existingManifest, options.appConfig, outdir, eligibleEntryPaths)) {
121
+ appLogger.debug("Reusing pages unified graph cache");
122
+ return existingManifest;
123
+ }
124
+ const plugins = options.appConfig.runtime?.buildManifest ? getAppServerBuildPlugins(options.appConfig) : [];
125
+ const mergedPlugins = [...plugins, ...getJsxOwnershipPlugins(options.appConfig)];
126
+ const routeModuleBuildCache = getSharedRouteModuleBuildCache(outdir, options.appConfig);
127
+ const entryRecord = {};
128
+ const entryKeysByPath = /* @__PURE__ */ new Map();
129
+ for (const entryPath of eligibleEntryPaths) {
130
+ const entryKey = createSafeGraphEntryKey(entryPath, options.appConfig.rootDir);
131
+ entryRecord[entryKey] = entryPath;
132
+ entryKeysByPath.set(entryPath, entryKey);
133
+ }
134
+ appLogger.debugTime("pagesUnifiedGraphBuild");
135
+ const buildOptions = {
136
+ ...resolveBuildProfileOptions("route-module", options.appConfig, {
137
+ entrypoints: entryRecord,
138
+ outdir,
139
+ splitting: true,
140
+ naming: "[name]-[hash].[ext]",
141
+ plugins: mergedPlugins.length > 0 ? mergedPlugins : void 0
142
+ }),
143
+ entrypoints: entryRecord
144
+ };
145
+ const buildResult = await build(buildOptions, requireBuildRuntime(options.appConfig).getProfile("route-module"));
146
+ appLogger.debugTimeEnd("pagesUnifiedGraphBuild");
147
+ if (!buildResult.success) {
148
+ const details = buildResult.logs.map((log) => log.message).join(" | ");
149
+ throw new Error(`Pages unified graph build failed: ${details}`);
150
+ }
151
+ const outputs = {};
152
+ for (const entryPath of eligibleEntryPaths) {
153
+ const fileHash = fileSystem.hash(entryPath);
154
+ const entryKey = entryKeysByPath.get(entryPath);
155
+ const compiledOutput = entryKey ? resolveOutputForEntrypoint(entryPath, entryKey, buildResult) : void 0;
156
+ if (!compiledOutput) {
157
+ throw new Error(`Pages unified graph build produced no output for ${entryPath}`);
158
+ }
159
+ normalizeNodeRuntimeBuildOutputFile(compiledOutput, options.appConfig.rootDir);
160
+ outputs[entryPath] = compiledOutput;
161
+ routeModuleBuildCache.recordBuild({
162
+ filePath: entryPath,
163
+ rootDir: options.appConfig.rootDir,
164
+ outdir,
165
+ fileHash,
166
+ outputPath: compiledOutput,
167
+ dependencyModulePaths: resolveRouteModuleDependencyPaths(buildResult, entryPath, options.appConfig.rootDir),
168
+ externalPackages: true,
169
+ plugins: mergedPlugins
170
+ });
171
+ }
172
+ const manifest = {
173
+ invalidationVersion: getCorePackageVersion(),
174
+ buildInputsFingerprint: createBuildInputsFingerprint(options.appConfig),
175
+ buildKey: createPagesUnifiedGraphBuildKey(options.appConfig, outdir),
176
+ builtAt: Date.now(),
177
+ outputs
178
+ };
179
+ writePagesUnifiedGraphManifest(options.appConfig, manifest);
180
+ appLogger.debug(`Built pages unified graph for ${eligibleEntryPaths.length} entries`);
181
+ return manifest;
182
+ }
183
+ async function importPagesUnifiedGraphModule(appConfig, filePath) {
184
+ const manifest = readPagesUnifiedGraphManifest(appConfig);
185
+ if (!manifest) {
186
+ return void 0;
187
+ }
188
+ const resolvedFilePath = path.resolve(filePath);
189
+ const outputPath = manifest.outputs[resolvedFilePath];
190
+ if (!outputPath || !fileSystem.exists(outputPath)) {
191
+ return void 0;
192
+ }
193
+ return await import(
194
+ /* @vite-ignore */
195
+ pathToFileURL(outputPath).href
196
+ );
197
+ }
198
+ export {
199
+ PAGES_UNIFIED_GRAPH_CACHE_DIR,
200
+ PAGES_UNIFIED_GRAPH_CACHE_FILENAME,
201
+ ensurePagesUnifiedGraphBuilt,
202
+ importPagesUnifiedGraphModule,
203
+ isPagesUnifiedGraphEnabled,
204
+ isPagesUnifiedGraphPage,
205
+ shouldBuildPagesUnifiedGraph
206
+ };
@@ -0,0 +1,21 @@
1
+ import type { BuildExecutor, BuildOptions, BuildResult } from './build-adapter.js';
2
+ /**
3
+ * Concurrency-limited build executor wrapper.
4
+ *
5
+ * @remarks
6
+ * Runs up to `limit` builds concurrently. Use for independent route-module
7
+ * and HMR browser builds where FIFO serialization is unnecessary.
8
+ */
9
+ export declare class ParallelBuildExecutor implements BuildExecutor {
10
+ private readonly inner;
11
+ private readonly limit;
12
+ private activeCount;
13
+ private queue;
14
+ constructor(inner: BuildExecutor, limit: number);
15
+ build(options: BuildOptions): Promise<BuildResult>;
16
+ private drainQueue;
17
+ unwrap(): BuildExecutor;
18
+ getConcurrencyLimitForTests(): number;
19
+ getActiveCountForTests(): number;
20
+ getQueuedCountForTests(): number;
21
+ }
@@ -0,0 +1,52 @@
1
+ class ParallelBuildExecutor {
2
+ inner;
3
+ limit;
4
+ activeCount = 0;
5
+ queue = [];
6
+ constructor(inner, limit) {
7
+ this.inner = inner;
8
+ this.limit = Math.max(1, limit);
9
+ }
10
+ build(options) {
11
+ return new Promise((resolve, reject) => {
12
+ this.queue.push({
13
+ operation: () => this.inner.build(options),
14
+ resolve,
15
+ reject
16
+ });
17
+ this.drainQueue();
18
+ });
19
+ }
20
+ drainQueue() {
21
+ while (this.activeCount < this.limit && this.queue.length > 0) {
22
+ const next = this.queue.shift();
23
+ if (!next) {
24
+ return;
25
+ }
26
+ this.activeCount += 1;
27
+ void next.operation().then((result) => {
28
+ next.resolve(result);
29
+ }).catch((error) => {
30
+ next.reject(error);
31
+ }).finally(() => {
32
+ this.activeCount -= 1;
33
+ this.drainQueue();
34
+ });
35
+ }
36
+ }
37
+ unwrap() {
38
+ return this.inner;
39
+ }
40
+ getConcurrencyLimitForTests() {
41
+ return this.limit;
42
+ }
43
+ getActiveCountForTests() {
44
+ return this.activeCount;
45
+ }
46
+ getQueuedCountForTests() {
47
+ return this.queue.length;
48
+ }
49
+ }
50
+ export {
51
+ ParallelBuildExecutor
52
+ };