@ecopages/core 0.2.0-beta.2 → 0.2.0-beta.21
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.
- package/README.md +1 -1
- package/package.json +163 -3
- package/src/adapters/abstract/application-adapter.d.ts +104 -5
- package/src/adapters/abstract/application-adapter.js +125 -1
- package/src/adapters/abstract/server-adapter.d.ts +6 -2
- package/src/adapters/abstract/ws-pattern-matcher.d.ts +60 -0
- package/src/adapters/abstract/ws-pattern-matcher.js +61 -0
- package/src/adapters/bun/client-bridge.d.ts +1 -0
- package/src/adapters/bun/client-bridge.js +3 -0
- package/src/adapters/bun/create-app.d.ts +6 -4
- package/src/adapters/bun/create-app.js +65 -43
- package/src/adapters/bun/server-adapter.d.ts +90 -22
- package/src/adapters/bun/server-adapter.js +266 -84
- package/src/adapters/bun/static-preview-host.js +25 -20
- package/src/adapters/create-app.d.ts +13 -11
- package/src/adapters/create-app.js +2 -51
- package/src/adapters/index.d.ts +1 -1
- package/src/adapters/index.js +1 -2
- package/src/adapters/node/create-app.d.ts +5 -1
- package/src/adapters/node/create-app.js +51 -12
- package/src/adapters/node/node-client-bridge.d.ts +1 -0
- package/src/adapters/node/node-client-bridge.js +3 -0
- package/src/adapters/node/server-adapter-dependencies.js +4 -0
- package/src/adapters/node/server-adapter.d.ts +62 -20
- package/src/adapters/node/server-adapter.js +160 -131
- package/src/adapters/node/static-content-server.d.ts +1 -0
- package/src/adapters/node/static-content-server.js +10 -2
- package/src/adapters/node/static-preview-host.js +27 -12
- package/src/adapters/shared/bun-user-websocket-lifecycle.d.ts +22 -0
- package/src/adapters/shared/bun-user-websocket-lifecycle.js +96 -0
- package/src/adapters/shared/copy-runtime-public-dir.d.ts +6 -0
- package/src/adapters/shared/copy-runtime-public-dir.js +24 -0
- package/src/adapters/shared/fs-server-response-matcher.d.ts +2 -0
- package/src/adapters/shared/fs-server-response-matcher.js +40 -18
- package/src/adapters/shared/hmr-entrypoint-registrar.d.ts +21 -30
- package/src/adapters/shared/hmr-entrypoint-registrar.js +49 -54
- package/src/adapters/shared/hmr-html-response.d.ts +1 -1
- package/src/adapters/shared/hmr-html-response.js +4 -1
- package/src/adapters/shared/node-http-websocket-upgrades.d.ts +21 -0
- package/src/adapters/shared/node-http-websocket-upgrades.js +100 -0
- package/src/adapters/shared/port-manager.d.ts +116 -0
- package/src/adapters/shared/port-manager.js +196 -0
- package/src/adapters/shared/runtime-app-bootstrap.d.ts +2 -1
- package/src/adapters/shared/runtime-app-bootstrap.js +3 -6
- package/src/adapters/shared/runtime-server-lifecycle.d.ts +46 -0
- package/src/adapters/shared/runtime-server-lifecycle.js +50 -0
- package/src/adapters/shared/server-adapter.d.ts +2 -1
- package/src/adapters/shared/server-adapter.js +13 -6
- package/src/adapters/shared/server-route-handler.d.ts +4 -1
- package/src/adapters/shared/server-route-handler.js +5 -2
- package/src/adapters/shared/server-static-builder.d.ts +23 -32
- package/src/adapters/shared/server-static-builder.js +100 -73
- package/src/adapters/shared/shared-hmr-manager.d.ts +45 -11
- package/src/adapters/shared/shared-hmr-manager.js +204 -58
- package/src/adapters/shared/static-preview-host.d.ts +5 -0
- package/src/adapters/shared/websocket-lifecycle.d.ts +24 -0
- package/src/adapters/shared/websocket-lifecycle.js +55 -0
- package/src/build/README.md +77 -14
- package/src/build/app-build-manifest-runtime.d.ts +9 -0
- package/src/build/app-build-manifest-runtime.js +87 -0
- package/src/build/build-adapter.d.ts +17 -319
- package/src/build/build-adapter.js +28 -94
- package/src/build/build-contracts.d.ts +97 -0
- package/src/build/build-contracts.js +0 -0
- package/src/build/build-input-fingerprint.d.ts +28 -0
- package/src/build/build-input-fingerprint.js +31 -0
- package/src/build/build-profile-options.d.ts +7 -0
- package/src/build/build-profile-options.js +37 -0
- package/src/build/build-runtime.d.ts +24 -0
- package/src/build/build-runtime.js +65 -0
- package/src/build/deduping-build-executor.d.ts +28 -0
- package/src/build/deduping-build-executor.js +56 -0
- package/src/build/jsx-ownership-plugins.d.ts +24 -0
- package/src/build/jsx-ownership-plugins.js +41 -0
- package/src/build/pages-unified-graph-build.d.ts +31 -0
- package/src/build/pages-unified-graph-build.js +206 -0
- package/src/build/parallel-build-executor.d.ts +21 -0
- package/src/build/parallel-build-executor.js +52 -0
- package/src/build/production-build-cache.d.ts +20 -0
- package/src/build/production-build-cache.js +63 -0
- package/src/build/rolldown-adapter-helpers.d.ts +3 -6
- package/src/build/rolldown-adapter-helpers.js +71 -6
- package/src/build/rolldown-build-adapter.d.ts +2 -6
- package/src/build/rolldown-build-adapter.js +3 -3
- package/src/build/rolldown-build-invocation-metrics.d.ts +12 -0
- package/src/build/rolldown-build-invocation-metrics.js +43 -0
- package/src/build/rolldown-plugin-bridge.d.ts +15 -1
- package/src/build/rolldown-plugin-bridge.js +20 -5
- package/src/build/rolldown-source-transform-pass.d.ts +15 -0
- package/src/build/rolldown-source-transform-pass.js +58 -0
- package/src/build/runtime-build-executor.d.ts +8 -15
- package/src/build/runtime-build-executor.js +12 -15
- package/src/build/runtime-build-output-normalizer.d.ts +7 -0
- package/src/build/runtime-build-output-normalizer.js +94 -2
- package/src/build/server-entry-build-cache.d.ts +44 -0
- package/src/build/server-entry-build-cache.js +161 -0
- package/src/client/navigation-scripts/classification.d.ts +16 -0
- package/src/client/navigation-scripts/classification.js +41 -0
- package/src/client/navigation-scripts/index.d.ts +3 -0
- package/src/client/navigation-scripts/index.js +23 -0
- package/src/client/navigation-scripts/navigation-scripts.test.browser.js +65 -0
- package/src/client/navigation-scripts/registry.d.ts +11 -0
- package/src/client/navigation-scripts/registry.js +12 -0
- package/src/client/navigation-scripts/rerun-queue.d.ts +37 -0
- package/src/client/navigation-scripts/rerun-queue.js +73 -0
- package/src/client/scroll.d.ts +17 -0
- package/src/client/scroll.js +25 -0
- package/src/client/scroll.test.browser.js +37 -0
- package/src/client/view-transitions.d.ts +16 -0
- package/src/client/view-transitions.js +63 -0
- package/src/config/config-builder.d.ts +12 -7
- package/src/config/config-builder.js +12 -9
- package/src/dev/client-bridge-registry.d.ts +5 -0
- package/src/dev/client-bridge-registry.js +15 -0
- package/src/dev/dev-client-ownership.d.ts +7 -0
- package/src/dev/dev-client-ownership.js +6 -0
- package/src/dev/hmr-manager-registry.d.ts +8 -0
- package/src/dev/hmr-manager-registry.js +15 -0
- package/src/dev/host-runtime.d.ts +3 -0
- package/src/dev/host-runtime.js +7 -0
- package/src/dev/runtime-server-started-message.d.ts +2 -0
- package/src/dev/runtime-server-started-message.js +6 -0
- package/src/eco/README.md +11 -0
- package/src/eco/eco-declared-component.d.ts +14 -0
- package/src/eco/eco-declared-component.js +16 -0
- package/src/eco/eco.browser.js +5 -6
- package/src/eco/eco.js +5 -6
- package/src/eco/eco.types.d.ts +2 -2
- package/src/eco/page-layout-normalization.d.ts +21 -0
- package/src/eco/page-layout-normalization.js +59 -0
- package/src/errors/index.d.ts +1 -0
- package/src/errors/index.js +7 -1
- package/src/errors/undeclared-component-dependency-error.d.ts +11 -0
- package/src/errors/undeclared-component-dependency-error.js +17 -0
- package/src/hmr/client/hmr-runtime.js +5 -2
- package/src/hmr/hmr-entrypoint-output.d.ts +43 -0
- package/src/hmr/hmr-entrypoint-output.js +53 -0
- package/src/hmr/hmr-strategy.d.ts +15 -0
- package/src/hmr/hmr-strategy.js +19 -0
- package/src/hmr/strategies/js-hmr-strategy.d.ts +3 -5
- package/src/hmr/strategies/js-hmr-strategy.js +67 -19
- package/src/hmr/strategies/server-rendered-template-hmr-strategy.d.ts +17 -0
- package/src/hmr/strategies/server-rendered-template-hmr-strategy.js +29 -0
- package/src/integrations/ghtml/ghtml-renderer.d.ts +2 -6
- package/src/integrations/ghtml/ghtml-renderer.js +2 -51
- package/src/integrations/ghtml/ghtml.plugin.d.ts +3 -16
- package/src/integrations/ghtml/ghtml.plugin.js +7 -14
- package/src/plugins/define-integration.d.ts +26 -0
- package/src/plugins/define-integration.js +19 -0
- package/src/plugins/eco-component-meta-plugin.js +5 -8
- package/src/plugins/foreign-jsx-override-plugin.js +4 -6
- package/src/plugins/integration-plugin.d.ts +19 -9
- package/src/plugins/integration-plugin.js +7 -4
- package/src/plugins/jsx-import-source.utils.d.ts +8 -0
- package/src/plugins/jsx-import-source.utils.js +26 -0
- package/src/plugins/processor.d.ts +19 -4
- package/src/plugins/processor.js +22 -4
- package/src/plugins/source-transform.d.ts +31 -0
- package/src/plugins/source-transform.js +23 -1
- package/src/route-renderer/GRAPH.md +8 -8
- package/src/route-renderer/README.md +30 -28
- package/src/route-renderer/orchestration/component-graph-collectors.d.ts +10 -0
- package/src/route-renderer/orchestration/component-graph-collectors.js +143 -0
- package/src/route-renderer/orchestration/component-graph.d.ts +36 -0
- package/src/route-renderer/orchestration/component-graph.js +98 -0
- package/src/route-renderer/orchestration/component-render-context.d.ts +3 -10
- package/src/route-renderer/orchestration/component-render-context.js +3 -1
- package/src/route-renderer/orchestration/declared-ownership-graph.d.ts +1 -18
- package/src/route-renderer/orchestration/declared-ownership-graph.js +5 -31
- package/src/route-renderer/orchestration/document-shell-render.service.d.ts +90 -0
- package/src/route-renderer/orchestration/document-shell-render.service.js +120 -0
- package/src/route-renderer/orchestration/foreign-subtree-execution.service.d.ts +59 -29
- package/src/route-renderer/orchestration/foreign-subtree-execution.service.js +164 -35
- package/src/route-renderer/orchestration/global-injector-assets.service.d.ts +7 -0
- package/src/route-renderer/orchestration/global-injector-assets.service.js +32 -0
- package/src/route-renderer/orchestration/integration-renderer.d.ts +18 -54
- package/src/route-renderer/orchestration/integration-renderer.js +113 -195
- package/src/route-renderer/orchestration/integration-route-render-adapter.d.ts +38 -0
- package/src/route-renderer/orchestration/integration-route-render-adapter.js +27 -0
- package/src/route-renderer/orchestration/layout-shell-props.service.d.ts +20 -0
- package/src/route-renderer/orchestration/layout-shell-props.service.js +31 -0
- package/src/route-renderer/orchestration/ownership-validation.service.d.ts +5 -0
- package/src/route-renderer/orchestration/ownership-validation.service.js +29 -1
- package/src/route-renderer/orchestration/page-browser-graph-contribution.loader.d.ts +9 -0
- package/src/route-renderer/orchestration/page-browser-graph-contribution.loader.js +7 -0
- package/src/route-renderer/orchestration/page-browser-graph.service.d.ts +25 -0
- package/src/route-renderer/orchestration/page-browser-graph.service.js +174 -0
- package/src/route-renderer/orchestration/render-output.utils.d.ts +2 -0
- package/src/route-renderer/orchestration/render-output.utils.js +4 -0
- package/src/route-renderer/orchestration/route-html-finalization.service.d.ts +17 -0
- package/src/route-renderer/orchestration/route-html-finalization.service.js +26 -0
- package/src/route-renderer/orchestration/route-prepared-options.builder.d.ts +26 -0
- package/src/route-renderer/orchestration/route-prepared-options.builder.js +54 -0
- package/src/route-renderer/orchestration/route-prepared-options.utils.d.ts +4 -0
- package/src/route-renderer/orchestration/route-prepared-options.utils.js +33 -0
- package/src/route-renderer/orchestration/route-render-orchestrator.d.ts +8 -39
- package/src/route-renderer/orchestration/route-render-orchestrator.js +53 -461
- package/src/route-renderer/orchestration/string-markup-renderer.d.ts +14 -0
- package/src/route-renderer/orchestration/string-markup-renderer.js +55 -0
- package/src/route-renderer/page-loading/component-dependency-collection.js +5 -2
- package/src/router/client/link-intent.d.ts +11 -21
- package/src/router/client/link-intent.js +10 -0
- package/src/router/client/link-intent.test.browser.js +12 -1
- package/src/router/client/link-navigation-policy.d.ts +45 -0
- package/src/router/client/link-navigation-policy.js +101 -0
- package/src/router/client/link-navigation-policy.test.browser.d.ts +1 -0
- package/src/router/client/link-navigation-policy.test.browser.js +92 -0
- package/src/router/client/navigation-coordinator.d.ts +1 -1
- package/src/router/client/navigation-coordinator.js +12 -2
- package/src/services/assets/asset-processing-service/browser-runtime-asset.factory.d.ts +1 -0
- package/src/services/assets/asset-processing-service/browser-runtime-asset.factory.js +1 -0
- package/src/services/assets/asset-processing-service/browser-runtime-entry.factory.d.ts +4 -2
- package/src/services/assets/asset-processing-service/browser-runtime-entry.factory.js +27 -7
- package/src/services/assets/asset-processing-service/processors/script/file-script.processor.d.ts +0 -1
- package/src/services/assets/asset-processing-service/processors/script/file-script.processor.js +18 -15
- package/src/services/assets/asset-processing-service/processors/script/node-module-script.processor.js +17 -3
- package/src/services/assets/asset-processing-service/processors/stylesheet/content-stylesheet.processor.d.ts +0 -3
- package/src/services/assets/asset-processing-service/processors/stylesheet/content-stylesheet.processor.js +2 -31
- package/src/services/assets/asset-processing-service/processors/stylesheet/file-stylesheet.processor.d.ts +0 -3
- package/src/services/assets/asset-processing-service/processors/stylesheet/file-stylesheet.processor.js +2 -30
- package/src/services/assets/asset-processing-service/processors/stylesheet/stylesheet-processor-pipeline.d.ts +2 -0
- package/src/services/assets/asset-processing-service/processors/stylesheet/stylesheet-processor-pipeline.js +43 -0
- package/src/services/assets/browser-bundle.service.d.ts +3 -1
- package/src/services/assets/browser-bundle.service.js +17 -5
- package/src/services/html/html-transformer.service.d.ts +1 -1
- package/src/services/html/html-transformer.service.js +4 -4
- package/src/services/invalidation/development-invalidation.service.d.ts +20 -2
- package/src/services/invalidation/development-invalidation.service.js +56 -2
- package/src/services/module-loading/README.md +49 -0
- package/src/services/module-loading/app-server-module-transpiler.service.js +5 -17
- package/src/services/module-loading/page-module-import.service.d.ts +5 -1
- package/src/services/module-loading/page-module-import.service.js +96 -45
- package/src/services/module-loading/route-module-build-cache-registry.d.ts +24 -0
- package/src/services/module-loading/route-module-build-cache-registry.js +37 -0
- package/src/services/module-loading/route-module-build-cache.d.ts +4 -0
- package/src/services/module-loading/route-module-build-cache.js +38 -0
- package/src/services/module-loading/route-module-build-cache.store.d.ts +57 -0
- package/src/services/module-loading/route-module-build-cache.store.js +207 -0
- package/src/services/module-loading/route-module-build-manifest.d.ts +61 -0
- package/src/services/module-loading/route-module-build-manifest.js +116 -0
- package/src/services/module-loading/route-module-dependency-hasher.d.ts +81 -0
- package/src/services/module-loading/route-module-dependency-hasher.js +122 -0
- package/src/services/module-loading/server-module-transpiler.service.js +1 -1
- package/src/static-site-generator/README.md +33 -0
- package/src/static-site-generator/static-build-invalidation.d.ts +10 -0
- package/src/static-site-generator/static-build-invalidation.js +59 -0
- package/src/static-site-generator/static-export-context.d.ts +22 -0
- package/src/static-site-generator/static-export-context.js +0 -0
- package/src/static-site-generator/static-site-generator.d.ts +17 -20
- package/src/static-site-generator/static-site-generator.js +188 -85
- package/src/types/internal-types.d.ts +16 -9
- package/src/types/public-types.d.ts +144 -40
- package/src/utils/parse-cli-args.d.ts +2 -0
- package/src/utils/parse-cli-args.js +6 -0
- package/src/utils/server-utils.module.d.ts +3 -2
- package/src/utils/server-utils.module.js +5 -6
- package/src/utils/static-file-extensions.d.ts +12 -0
- package/src/utils/static-file-extensions.js +48 -0
- package/src/watchers/project-watcher-ignore.d.ts +11 -0
- package/src/watchers/project-watcher-ignore.js +16 -0
- package/src/watchers/project-watcher.d.ts +26 -3
- package/src/watchers/project-watcher.js +132 -30
- package/src/watchers/project-watcher.test-helpers.js +5 -5
- package/src/build/rolldown-dev-build-adapter.d.ts +0 -82
- package/src/build/rolldown-dev-build-adapter.js +0 -166
- package/src/hmr/hmr.postcss.test.e2e.js +0 -31
- package/src/hmr/hmr.test.e2e.js +0 -43
- package/src/route-renderer/orchestration/ownership-planning.service.d.ts +0 -24
- package/src/route-renderer/orchestration/ownership-planning.service.js +0 -63
- package/src/route-renderer/orchestration/queued-foreign-subtree-resolution.service.d.ts +0 -91
- package/src/route-renderer/orchestration/queued-foreign-subtree-resolution.service.js +0 -170
- /package/src/{hmr/hmr.postcss.test.e2e.d.ts → client/navigation-scripts/navigation-scripts.test.browser.d.ts} +0 -0
- /package/src/{hmr/hmr.test.e2e.d.ts → client/scroll.test.browser.d.ts} +0 -0
|
@@ -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
|
+
};
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { EcoPagesAppConfig } from '../types/internal-types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Shared manifest fields for persisted production build caches.
|
|
4
|
+
*/
|
|
5
|
+
export interface ProductionCacheManifestBase {
|
|
6
|
+
invalidationVersion: string;
|
|
7
|
+
buildInputsFingerprint?: string;
|
|
8
|
+
buildKey?: string;
|
|
9
|
+
builtAt?: number;
|
|
10
|
+
}
|
|
11
|
+
export type ProductionBuildCacheKind = 'server-entry' | 'route-module' | 'pages-graph';
|
|
12
|
+
/** Returns every persisted production cache manifest path for one app. */
|
|
13
|
+
export declare function getProductionBuildCacheManifestPaths(appConfig: EcoPagesAppConfig): string[];
|
|
14
|
+
/** Removes all persisted production cache manifests for one app. */
|
|
15
|
+
export declare function clearPersistedProductionBuildCacheManifests(appConfig: EcoPagesAppConfig): void;
|
|
16
|
+
export declare function readProductionCacheManifest<T extends ProductionCacheManifestBase>(manifestPath: string): T | undefined;
|
|
17
|
+
export declare function writeProductionCacheManifest(manifestPath: string, manifest: unknown): void;
|
|
18
|
+
export declare function isProductionCacheManifestCurrent(manifest: ProductionCacheManifestBase | undefined, invalidationVersion: string): boolean;
|
|
19
|
+
export declare function matchesProductionCacheFingerprint(manifest: ProductionCacheManifestBase | undefined, buildInputsFingerprint: string): boolean;
|
|
20
|
+
export declare function matchesProductionCacheBuildKey(manifest: ProductionCacheManifestBase | undefined, buildKey: string): boolean;
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { fileSystem } from "@ecopages/file-system";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { ROUTE_MODULE_BUILD_CACHE_FILENAME } from "../services/module-loading/route-module-build-manifest.js";
|
|
4
|
+
import { resolveInternalExecutionDir } from "../utils/resolve-work-dir.js";
|
|
5
|
+
const ROUTE_MODULE_CACHE_OUTDIRS = [".server-modules", ".server-route-modules"];
|
|
6
|
+
const PAGES_GRAPH_CACHE_DIR = ".server-pages-graph";
|
|
7
|
+
function getProductionBuildCacheManifestPaths(appConfig) {
|
|
8
|
+
const executionDir = resolveInternalExecutionDir(appConfig);
|
|
9
|
+
const paths = [];
|
|
10
|
+
for (const subdir of ROUTE_MODULE_CACHE_OUTDIRS) {
|
|
11
|
+
paths.push(path.join(executionDir, subdir, ROUTE_MODULE_BUILD_CACHE_FILENAME));
|
|
12
|
+
}
|
|
13
|
+
paths.push(path.join(executionDir, ".server-entry", ROUTE_MODULE_BUILD_CACHE_FILENAME));
|
|
14
|
+
paths.push(path.join(executionDir, PAGES_GRAPH_CACHE_DIR, ROUTE_MODULE_BUILD_CACHE_FILENAME));
|
|
15
|
+
return paths;
|
|
16
|
+
}
|
|
17
|
+
function clearPersistedProductionBuildCacheManifests(appConfig) {
|
|
18
|
+
if (process.env.NODE_ENV !== "production") {
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
for (const manifestPath of getProductionBuildCacheManifestPaths(appConfig)) {
|
|
22
|
+
if (fileSystem.exists(manifestPath)) {
|
|
23
|
+
fileSystem.remove(manifestPath);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
function readProductionCacheManifest(manifestPath) {
|
|
28
|
+
if (!fileSystem.exists(manifestPath)) {
|
|
29
|
+
return void 0;
|
|
30
|
+
}
|
|
31
|
+
try {
|
|
32
|
+
const parsed = JSON.parse(fileSystem.readFileSync(manifestPath));
|
|
33
|
+
if (!parsed || typeof parsed !== "object") {
|
|
34
|
+
return void 0;
|
|
35
|
+
}
|
|
36
|
+
return parsed;
|
|
37
|
+
} catch {
|
|
38
|
+
return void 0;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
function writeProductionCacheManifest(manifestPath, manifest) {
|
|
42
|
+
fileSystem.ensureDir(path.dirname(manifestPath));
|
|
43
|
+
fileSystem.write(manifestPath, `${JSON.stringify(manifest, null, " ")}
|
|
44
|
+
`);
|
|
45
|
+
}
|
|
46
|
+
function isProductionCacheManifestCurrent(manifest, invalidationVersion) {
|
|
47
|
+
return manifest?.invalidationVersion === invalidationVersion;
|
|
48
|
+
}
|
|
49
|
+
function matchesProductionCacheFingerprint(manifest, buildInputsFingerprint) {
|
|
50
|
+
return manifest?.buildInputsFingerprint === buildInputsFingerprint;
|
|
51
|
+
}
|
|
52
|
+
function matchesProductionCacheBuildKey(manifest, buildKey) {
|
|
53
|
+
return manifest?.buildKey === buildKey;
|
|
54
|
+
}
|
|
55
|
+
export {
|
|
56
|
+
clearPersistedProductionBuildCacheManifests,
|
|
57
|
+
getProductionBuildCacheManifestPaths,
|
|
58
|
+
isProductionCacheManifestCurrent,
|
|
59
|
+
matchesProductionCacheBuildKey,
|
|
60
|
+
matchesProductionCacheFingerprint,
|
|
61
|
+
readProductionCacheManifest,
|
|
62
|
+
writeProductionCacheManifest
|
|
63
|
+
};
|
|
@@ -2,12 +2,9 @@
|
|
|
2
2
|
* Shared helpers for the Rolldown-backed build adapters.
|
|
3
3
|
*
|
|
4
4
|
* @remarks
|
|
5
|
-
* The standard {@link RolldownBuildAdapter}
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
* mapping, the same dependency-graph extraction, and the same
|
|
9
|
-
* post-build rewriting pipeline. This module hosts the shared code so
|
|
10
|
-
* the two adapters stay semantically identical.
|
|
5
|
+
* The standard {@link RolldownBuildAdapter} uses these helpers for
|
|
6
|
+
* BuildOptions → Rolldown mapping, dependency-graph extraction, and the
|
|
7
|
+
* post-build rewriting pipeline.
|
|
11
8
|
*
|
|
12
9
|
* @module
|
|
13
10
|
*/
|
|
@@ -1,10 +1,41 @@
|
|
|
1
1
|
import { createRequire } from "node:module";
|
|
2
|
+
import { readFileSync } from "node:fs";
|
|
2
3
|
import path from "node:path";
|
|
3
4
|
import { collectBrowserRuntimeImportRewriteMap, rewriteBrowserRuntimeImports } from "./browser-runtime-plugin.js";
|
|
4
5
|
import { createServerSideCssShimPlugin } from "./server-side-css-shim-plugin.js";
|
|
5
6
|
import { createRolldownPluginBridge } from "./rolldown-plugin-bridge.js";
|
|
6
|
-
import {
|
|
7
|
+
import {
|
|
8
|
+
isDeclaredAppPackageImport,
|
|
9
|
+
isWorkspacePackageImport,
|
|
10
|
+
normalizeNodeRuntimeBuildOutputs
|
|
11
|
+
} from "./runtime-build-output-normalizer.js";
|
|
7
12
|
const corePackageRequire = createRequire(new URL("../../package.json", import.meta.url));
|
|
13
|
+
let corePackageNames;
|
|
14
|
+
function getCorePackageNames() {
|
|
15
|
+
if (corePackageNames) {
|
|
16
|
+
return corePackageNames;
|
|
17
|
+
}
|
|
18
|
+
const packageJsonPath = new URL("../../package.json", import.meta.url);
|
|
19
|
+
corePackageNames = /* @__PURE__ */ new Set();
|
|
20
|
+
try {
|
|
21
|
+
const packageJson = JSON.parse(readFileSync(packageJsonPath, "utf-8"));
|
|
22
|
+
for (const field of ["dependencies", "devDependencies", "peerDependencies", "optionalDependencies"]) {
|
|
23
|
+
const entries = packageJson[field];
|
|
24
|
+
if (!entries || typeof entries !== "object") {
|
|
25
|
+
continue;
|
|
26
|
+
}
|
|
27
|
+
for (const name of Object.keys(entries)) {
|
|
28
|
+
corePackageNames.add(name);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
} catch {
|
|
32
|
+
}
|
|
33
|
+
return corePackageNames;
|
|
34
|
+
}
|
|
35
|
+
function isCoreDeclaredPackageImport(specifier) {
|
|
36
|
+
const name = specifier.startsWith("@") ? specifier.split("/").slice(0, 2).join("/") : specifier.split("/")[0] ?? specifier;
|
|
37
|
+
return getCorePackageNames().has(name);
|
|
38
|
+
}
|
|
8
39
|
function transpileProfileToOptions(profile) {
|
|
9
40
|
switch (profile) {
|
|
10
41
|
case "browser-script":
|
|
@@ -37,13 +68,21 @@ function getAppRootRequire(cache, contextRoot) {
|
|
|
37
68
|
return req;
|
|
38
69
|
}
|
|
39
70
|
function shouldBundlePackageImport(id, contextRoot, appRootRequireCache) {
|
|
71
|
+
if (isWorkspacePackageImport(id, contextRoot)) {
|
|
72
|
+
return true;
|
|
73
|
+
}
|
|
40
74
|
if (isDeclaredAppPackageImport(id, contextRoot)) {
|
|
41
75
|
const appRootRequire = getAppRootRequire(appRootRequireCache, contextRoot);
|
|
42
76
|
const appResolvedPath = tryResolveModule(id, appRootRequire);
|
|
43
77
|
return Boolean(appResolvedPath && /\.(?:[cm]?ts|tsx|jsx)$/u.test(appResolvedPath));
|
|
44
78
|
}
|
|
45
|
-
|
|
46
|
-
|
|
79
|
+
if (isCoreDeclaredPackageImport(id)) {
|
|
80
|
+
const coreResolvedPath = tryResolveModule(id, corePackageRequire);
|
|
81
|
+
if (coreResolvedPath && !/\.(?:[cm]?ts|tsx|jsx)$/u.test(coreResolvedPath)) {
|
|
82
|
+
return false;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
return true;
|
|
47
86
|
}
|
|
48
87
|
function createExternalMatcher(options, appRootRequireCache) {
|
|
49
88
|
const explicitExternals = new Set(options.external ?? []);
|
|
@@ -162,7 +201,8 @@ function resolveRolldownOptions(options, contextRoot, outdir, appRootRequireCach
|
|
|
162
201
|
transformOptions.target = options.target;
|
|
163
202
|
}
|
|
164
203
|
const bundlePlugins = options.plugins ?? [];
|
|
165
|
-
const
|
|
204
|
+
const sourceTransforms = options.target === "browser" ? options.sourceTransforms ?? [] : [];
|
|
205
|
+
const appPlugins = createRolldownPluginBridge(bundlePlugins, contextRoot, sourceTransforms);
|
|
166
206
|
const allPlugins = [...options.target !== "browser" ? [createServerSideCssShimPlugin()] : [], ...appPlugins];
|
|
167
207
|
const inputOptions = {
|
|
168
208
|
input: options.entrypoints,
|
|
@@ -172,6 +212,11 @@ function resolveRolldownOptions(options, contextRoot, outdir, appRootRequireCach
|
|
|
172
212
|
transform: Object.keys(transformOptions).length > 0 ? transformOptions : void 0,
|
|
173
213
|
resolve: options.conditions ? { conditionNames: options.conditions } : void 0,
|
|
174
214
|
treeshake: typeof options.treeshaking === "boolean" ? options.treeshaking : true,
|
|
215
|
+
...process.env.ECOPAGES_PROFILE_BUILD === "1" ? {} : {
|
|
216
|
+
checks: {
|
|
217
|
+
pluginTimings: false
|
|
218
|
+
}
|
|
219
|
+
},
|
|
175
220
|
experimental: {
|
|
176
221
|
nativeMagicString: true
|
|
177
222
|
},
|
|
@@ -215,11 +260,21 @@ function rewriteBrowserRuntimeImportsInOutputs(result, contextRoot, plugins) {
|
|
|
215
260
|
if (rewritten !== code) {
|
|
216
261
|
fs.writeFileSync(output.path, rewritten);
|
|
217
262
|
}
|
|
218
|
-
|
|
263
|
+
rememberRewrite(contentKey);
|
|
219
264
|
}
|
|
220
265
|
return result;
|
|
221
266
|
}
|
|
267
|
+
const REWRITE_CACHE_MAX_ENTRIES = 2048;
|
|
222
268
|
const rewriteCache = /* @__PURE__ */ new Set();
|
|
269
|
+
function rememberRewrite(contentKey) {
|
|
270
|
+
rewriteCache.add(contentKey);
|
|
271
|
+
if (rewriteCache.size > REWRITE_CACHE_MAX_ENTRIES) {
|
|
272
|
+
const oldest = rewriteCache.values().next().value;
|
|
273
|
+
if (oldest !== void 0) {
|
|
274
|
+
rewriteCache.delete(oldest);
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
}
|
|
223
278
|
function djb2(input) {
|
|
224
279
|
let hash = 5381;
|
|
225
280
|
for (let i = 0; i < input.length; i++) {
|
|
@@ -246,11 +301,21 @@ function buildResultFromRolldownOutput(output, outdir, contextRoot) {
|
|
|
246
301
|
}));
|
|
247
302
|
const entryChunks = output.output.filter((entry) => entry.type === "chunk" && entry.isEntry);
|
|
248
303
|
const dependencyGraph = entryChunks.length > 0 ? extractDependencyGraph(entryChunks, contextRoot) : void 0;
|
|
304
|
+
const entryOutputs = {};
|
|
305
|
+
for (const chunk of entryChunks) {
|
|
306
|
+
if (chunk.facadeModuleId) {
|
|
307
|
+
entryOutputs[normalizeModulePath(chunk.facadeModuleId, contextRoot)] = normalizeOutputPath(
|
|
308
|
+
chunk.fileName,
|
|
309
|
+
outdir
|
|
310
|
+
);
|
|
311
|
+
}
|
|
312
|
+
}
|
|
249
313
|
return {
|
|
250
314
|
success: true,
|
|
251
315
|
logs: [],
|
|
252
316
|
outputs,
|
|
253
|
-
dependencyGraph
|
|
317
|
+
dependencyGraph,
|
|
318
|
+
entryOutputs: entryChunks.length > 0 ? entryOutputs : void 0
|
|
254
319
|
};
|
|
255
320
|
}
|
|
256
321
|
export {
|
|
@@ -6,9 +6,7 @@
|
|
|
6
6
|
* default adapter installed by `ConfigBuilder` and the adapter that
|
|
7
7
|
* issues real builds in production.
|
|
8
8
|
*
|
|
9
|
-
* Each `build()` creates a fresh `rolldown()` bundler
|
|
10
|
-
* module-graph reuse across calls. For HMR/watch mode where the same
|
|
11
|
-
* entrypoints are rebuilt repeatedly, see {@link RolldownDevBuildAdapter}.
|
|
9
|
+
* Each `build()` creates a fresh `rolldown()` bundler.
|
|
12
10
|
*/
|
|
13
11
|
import type { BuildAdapter, BuildOptions, BuildResult, BuildTranspileOptions, BuildTranspileProfile } from './build-adapter.js';
|
|
14
12
|
export declare class RolldownBuildAdapter implements BuildAdapter {
|
|
@@ -16,9 +14,7 @@ export declare class RolldownBuildAdapter implements BuildAdapter {
|
|
|
16
14
|
/** Per-adapter require cache, keyed on resolved context root. */
|
|
17
15
|
private readonly appRootRequireCache;
|
|
18
16
|
/**
|
|
19
|
-
* Issues one build. Creates a fresh `rolldown()` bundler per call
|
|
20
|
-
* so no module-graph reuse. For repeated rebuilds on the same
|
|
21
|
-
* entrypoints, use {@link RolldownDevBuildAdapter}.
|
|
17
|
+
* Issues one build. Creates a fresh `rolldown()` bundler per call.
|
|
22
18
|
*/
|
|
23
19
|
buildOrThrow(options: BuildOptions): Promise<BuildResult>;
|
|
24
20
|
build(options: BuildOptions): Promise<BuildResult>;
|
|
@@ -9,17 +9,17 @@ import {
|
|
|
9
9
|
toBuildLogs,
|
|
10
10
|
transpileProfileToOptions
|
|
11
11
|
} from "./rolldown-adapter-helpers.js";
|
|
12
|
+
import { recordRolldownBuildInvocation } from "./rolldown-build-invocation-metrics.js";
|
|
12
13
|
const moduleRequire = createRequire(import.meta.url);
|
|
13
14
|
class RolldownBuildAdapter {
|
|
14
15
|
ownership = "rolldown";
|
|
15
16
|
/** Per-adapter require cache, keyed on resolved context root. */
|
|
16
17
|
appRootRequireCache = /* @__PURE__ */ new Map();
|
|
17
18
|
/**
|
|
18
|
-
* Issues one build. Creates a fresh `rolldown()` bundler per call
|
|
19
|
-
* so no module-graph reuse. For repeated rebuilds on the same
|
|
20
|
-
* entrypoints, use {@link RolldownDevBuildAdapter}.
|
|
19
|
+
* Issues one build. Creates a fresh `rolldown()` bundler per call.
|
|
21
20
|
*/
|
|
22
21
|
async buildOrThrow(options) {
|
|
22
|
+
recordRolldownBuildInvocation("rolldown");
|
|
23
23
|
const contextRoot = options.root ? path.resolve(options.root) : process.cwd();
|
|
24
24
|
const outdir = path.resolve(options.outdir ?? "dist/assets");
|
|
25
25
|
const plugins = options.plugins ?? [];
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Process-wide Rolldown build invocation counters for benchmarks and spikes.
|
|
3
|
+
*
|
|
4
|
+
* Gated behind {@link isRolldownBuildMetricsEnabled} so production paths stay quiet.
|
|
5
|
+
*/
|
|
6
|
+
export declare function isRolldownBuildMetricsEnabled(): boolean;
|
|
7
|
+
export declare function recordRolldownBuildInvocation(adapter?: 'rolldown'): void;
|
|
8
|
+
export declare function getRolldownBuildInvocationCounts(): Readonly<Record<string, number>>;
|
|
9
|
+
export declare function resetRolldownBuildInvocationCounts(): void;
|
|
10
|
+
export declare function recordPageModuleBuildInvocation(): void;
|
|
11
|
+
export declare function getPageModuleRolldownBuildInvocations(): number;
|
|
12
|
+
export declare function getTotalRolldownBuildInvocations(): number;
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
const invocationCounts = /* @__PURE__ */ new Map();
|
|
2
|
+
let pageModuleBuildInvocations = 0;
|
|
3
|
+
function isRolldownBuildMetricsEnabled() {
|
|
4
|
+
return process.env.ECOPAGES_ROLLDOWN_BUILD_METRICS === "1" || process.env.ECOPAGES_LOGGER_DEBUG === "true";
|
|
5
|
+
}
|
|
6
|
+
function recordRolldownBuildInvocation(adapter = "rolldown") {
|
|
7
|
+
if (!isRolldownBuildMetricsEnabled()) {
|
|
8
|
+
return;
|
|
9
|
+
}
|
|
10
|
+
invocationCounts.set(adapter, (invocationCounts.get(adapter) ?? 0) + 1);
|
|
11
|
+
}
|
|
12
|
+
function getRolldownBuildInvocationCounts() {
|
|
13
|
+
return Object.fromEntries(invocationCounts);
|
|
14
|
+
}
|
|
15
|
+
function resetRolldownBuildInvocationCounts() {
|
|
16
|
+
invocationCounts.clear();
|
|
17
|
+
pageModuleBuildInvocations = 0;
|
|
18
|
+
}
|
|
19
|
+
function recordPageModuleBuildInvocation() {
|
|
20
|
+
if (!isRolldownBuildMetricsEnabled()) {
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
pageModuleBuildInvocations += 1;
|
|
24
|
+
}
|
|
25
|
+
function getPageModuleRolldownBuildInvocations() {
|
|
26
|
+
return pageModuleBuildInvocations;
|
|
27
|
+
}
|
|
28
|
+
function getTotalRolldownBuildInvocations() {
|
|
29
|
+
let total = 0;
|
|
30
|
+
for (const count of invocationCounts.values()) {
|
|
31
|
+
total += count;
|
|
32
|
+
}
|
|
33
|
+
return total;
|
|
34
|
+
}
|
|
35
|
+
export {
|
|
36
|
+
getPageModuleRolldownBuildInvocations,
|
|
37
|
+
getRolldownBuildInvocationCounts,
|
|
38
|
+
getTotalRolldownBuildInvocations,
|
|
39
|
+
isRolldownBuildMetricsEnabled,
|
|
40
|
+
recordPageModuleBuildInvocation,
|
|
41
|
+
recordRolldownBuildInvocation,
|
|
42
|
+
resetRolldownBuildInvocationCounts
|
|
43
|
+
};
|
|
@@ -40,6 +40,7 @@
|
|
|
40
40
|
* on every source file.
|
|
41
41
|
*/
|
|
42
42
|
import type { Plugin } from 'rolldown';
|
|
43
|
+
import type { EcoSourceTransform } from '../plugins/source-transform.js';
|
|
43
44
|
import type { EcoBuildPlugin } from './build-types.js';
|
|
44
45
|
/**
|
|
45
46
|
* Creates a Rolldown `Plugin` array that drives the supplied
|
|
@@ -55,5 +56,18 @@ import type { EcoBuildPlugin } from './build-types.js';
|
|
|
55
56
|
* Plugin ordering is preserved: registrations from earlier eco plugins
|
|
56
57
|
* are checked before registrations from later ones, matching the
|
|
57
58
|
* original per-plugin priority semantics.
|
|
59
|
+
*
|
|
60
|
+
* @remarks
|
|
61
|
+
* Rolldown re-fires `buildStart` on each build, so registrations and the
|
|
62
|
+
* virtual-module counter are cleared before every `setup` pass — otherwise
|
|
63
|
+
* handlers accumulate when bridge plugins are reused.
|
|
64
|
+
*
|
|
65
|
+
* @param plugins - `EcoBuildPlugin` instances registered for this build.
|
|
66
|
+
* @param contextRoot - Project root used to resolve relative load paths.
|
|
67
|
+
* @param sourceTransforms - Optional app-owned transforms applied after a matching
|
|
68
|
+
* `onLoad` handler returns module contents. Browser builds pass
|
|
69
|
+
* {@link getAppSourceTransforms | app source transforms} here so metadata injection
|
|
70
|
+
* still runs on output rewritten by boundary/runtime plugins. Virtual modules,
|
|
71
|
+
* CSS, and asset loads are skipped.
|
|
58
72
|
*/
|
|
59
|
-
export declare function createRolldownPluginBridge(plugins: EcoBuildPlugin[], contextRoot: string): Plugin[];
|
|
73
|
+
export declare function createRolldownPluginBridge(plugins: EcoBuildPlugin[], contextRoot: string, sourceTransforms?: readonly EcoSourceTransform[]): Plugin[];
|