@ecopages/core 0.2.0-beta.0 → 0.2.0-beta.10
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/package.json +117 -3
- package/src/adapters/abstract/application-adapter.d.ts +73 -1
- package/src/adapters/abstract/application-adapter.js +89 -0
- package/src/adapters/abstract/server-adapter.d.ts +3 -0
- 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 +5 -3
- package/src/adapters/bun/create-app.js +44 -39
- package/src/adapters/bun/hmr-manager.d.ts +2 -1
- package/src/adapters/bun/hmr-manager.js +2 -2
- package/src/adapters/bun/server-adapter.d.ts +81 -20
- package/src/adapters/bun/server-adapter.js +220 -78
- package/src/adapters/bun/static-preview-host.js +25 -20
- package/src/adapters/create-app.d.ts +13 -0
- package/src/adapters/create-app.js +10 -1
- package/src/adapters/node/create-app.d.ts +4 -0
- package/src/adapters/node/create-app.js +38 -9
- 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/node-hmr-manager.d.ts +2 -1
- package/src/adapters/node/node-hmr-manager.js +2 -2
- package/src/adapters/node/server-adapter-dependencies.js +2 -0
- package/src/adapters/node/server-adapter.d.ts +55 -19
- package/src/adapters/node/server-adapter.js +140 -132
- 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/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 +38 -0
- package/src/adapters/shared/runtime-server-lifecycle.js +39 -0
- package/src/adapters/shared/server-adapter.d.ts +2 -1
- package/src/adapters/shared/server-adapter.js +12 -4
- 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 +31 -23
- package/src/adapters/shared/server-static-builder.js +126 -43
- package/src/adapters/shared/shared-hmr-manager.d.ts +12 -0
- package/src/adapters/shared/shared-hmr-manager.js +64 -7
- 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 +10 -0
- package/src/build/app-build-manifest-runtime.js +90 -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/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/host-runtime.d.ts +3 -0
- package/src/dev/host-runtime.js +7 -0
- package/src/hmr/client/hmr-runtime.js +5 -2
- 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 +90 -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 +54 -0
- package/src/route-renderer/orchestration/document-shell-render.service.js +54 -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 +108 -194
- 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/ownership-validation.service.d.ts +4 -0
- package/src/route-renderer/orchestration/ownership-validation.service.js +11 -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 +24 -0
- package/src/route-renderer/orchestration/route-prepared-options.builder.js +52 -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 +5 -38
- package/src/route-renderer/orchestration/route-render-orchestrator.js +51 -459
- package/src/route-renderer/orchestration/string-markup-renderer.d.ts +14 -0
- package/src/route-renderer/orchestration/string-markup-renderer.js +54 -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.js +32 -14
- 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 +10 -1
- package/src/services/invalidation/development-invalidation.service.js +31 -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 +4 -1
- package/src/services/module-loading/page-module-import.service.js +61 -41
- 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 +121 -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 +12 -9
- package/src/types/public-types.d.ts +87 -22
- package/src/utils/parse-cli-args.d.ts +1 -0
- package/src/utils/parse-cli-args.js +3 -0
- package/src/utils/resolve-entry-file.d.ts +72 -0
- package/src/utils/resolve-entry-file.js +41 -0
- package/src/watchers/project-watcher.d.ts +14 -2
- package/src/watchers/project-watcher.js +50 -20
- 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.d.ts +0 -1
- package/src/hmr/hmr.postcss.test.e2e.js +0 -31
- package/src/hmr/hmr.test.e2e.d.ts +0 -1
- 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
|
@@ -1,8 +1,14 @@
|
|
|
1
1
|
import path from "node:path";
|
|
2
|
+
import { availableParallelism } from "node:os";
|
|
2
3
|
import { appLogger } from "../global/app-logger.js";
|
|
3
4
|
import { fileSystem } from "@ecopages/file-system";
|
|
4
|
-
import { PathUtils } from "../utils/path-utils.module.js";
|
|
5
5
|
import { prepareExplicitStaticRender } from "../adapters/shared/explicit-static-render-preparation.js";
|
|
6
|
+
import { createRouteModuleStaticRenderCacheContext } from "./static-build-invalidation.js";
|
|
7
|
+
import {
|
|
8
|
+
getServerModuleBuildCacheOutdir,
|
|
9
|
+
getSharedRouteModuleBuildCache
|
|
10
|
+
} from "../services/module-loading/route-module-build-cache-registry.js";
|
|
11
|
+
import { ensurePagesUnifiedGraphBuilt, shouldBuildPagesUnifiedGraph } from "../build/pages-unified-graph-build.js";
|
|
6
12
|
const STATIC_SITE_GENERATOR_ERRORS = {
|
|
7
13
|
ROUTE_RENDERER_FACTORY_REQUIRED: "RouteRendererFactory is required for render strategy",
|
|
8
14
|
unsupportedBodyType: (bodyType) => `Unsupported body type for static generation: ${bodyType}`,
|
|
@@ -10,50 +16,51 @@ const STATIC_SITE_GENERATOR_ERRORS = {
|
|
|
10
16
|
noRendererForIntegration: (integrationName) => `No renderer found for integration: ${integrationName}`,
|
|
11
17
|
dynamicRouteRequiresStaticPaths: (routePath) => `Dynamic route ${routePath} requires staticPaths to be defined on the view.`
|
|
12
18
|
};
|
|
19
|
+
function resolveStaticPageConcurrency() {
|
|
20
|
+
return Math.max(1, availableParallelism() - 1);
|
|
21
|
+
}
|
|
22
|
+
async function runWithConcurrency(items, concurrency, worker) {
|
|
23
|
+
if (items.length === 0) {
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
const limit = Math.max(1, concurrency);
|
|
27
|
+
let nextIndex = 0;
|
|
28
|
+
const runners = Array.from({ length: Math.min(limit, items.length) }, async () => {
|
|
29
|
+
while (nextIndex < items.length) {
|
|
30
|
+
const currentIndex = nextIndex++;
|
|
31
|
+
await worker(items[currentIndex]);
|
|
32
|
+
}
|
|
33
|
+
});
|
|
34
|
+
await Promise.all(runners);
|
|
35
|
+
}
|
|
13
36
|
class StaticSiteGenerator {
|
|
14
37
|
appConfig;
|
|
38
|
+
routeModuleBuildCacheOverride;
|
|
39
|
+
staticRenderCacheContext;
|
|
40
|
+
forceFullStaticGeneration = false;
|
|
15
41
|
/**
|
|
16
42
|
* Creates the static-site generator for one app config.
|
|
17
43
|
*/
|
|
18
|
-
constructor({
|
|
44
|
+
constructor({
|
|
45
|
+
appConfig,
|
|
46
|
+
routeModuleBuildCache
|
|
47
|
+
}) {
|
|
19
48
|
this.appConfig = appConfig;
|
|
49
|
+
this.routeModuleBuildCacheOverride = routeModuleBuildCache;
|
|
50
|
+
this.staticRenderCacheContext = createRouteModuleStaticRenderCacheContext(appConfig);
|
|
51
|
+
}
|
|
52
|
+
getRouteModuleBuildCache() {
|
|
53
|
+
return this.routeModuleBuildCacheOverride ?? getSharedRouteModuleBuildCache(getServerModuleBuildCacheOutdir(this.appConfig), this.appConfig);
|
|
20
54
|
}
|
|
21
55
|
getExportDir() {
|
|
22
56
|
return this.appConfig.absolutePaths?.distDir ?? path.join(this.appConfig.rootDir, this.appConfig.distDir);
|
|
23
57
|
}
|
|
24
|
-
/**
|
|
25
|
-
* Logs the standardized warning emitted when a dynamic-cache page is skipped.
|
|
26
|
-
*/
|
|
27
|
-
warnDynamicPageSkipped(filePath) {
|
|
28
|
-
appLogger.warn(
|
|
29
|
-
"Pages with cache: 'dynamic' are not supported in static generation or preview, so they will be skipped\n",
|
|
30
|
-
`\u27A4 ${filePath}`
|
|
31
|
-
);
|
|
32
|
-
}
|
|
33
|
-
/**
|
|
34
|
-
* Determines whether one filesystem-discovered page should be excluded from
|
|
35
|
-
* static generation.
|
|
36
|
-
*/
|
|
37
58
|
async shouldSkipStaticPageFile(filePath, routeRendererFactory) {
|
|
38
|
-
const module = await routeRendererFactory.getPageRenderer(filePath).loadPageModule(filePath
|
|
39
|
-
|
|
40
|
-
});
|
|
41
|
-
if (module.default?.cache !== "dynamic") {
|
|
42
|
-
return false;
|
|
43
|
-
}
|
|
44
|
-
this.warnDynamicPageSkipped(filePath);
|
|
45
|
-
return true;
|
|
59
|
+
const module = await routeRendererFactory.getPageRenderer(filePath).loadPageModule(filePath);
|
|
60
|
+
return module.default?.cache === "dynamic";
|
|
46
61
|
}
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
* static generation.
|
|
50
|
-
*/
|
|
51
|
-
shouldSkipStaticView(routePath, view) {
|
|
52
|
-
if (view.cache !== "dynamic") {
|
|
53
|
-
return false;
|
|
54
|
-
}
|
|
55
|
-
this.warnDynamicPageSkipped(routePath);
|
|
56
|
-
return true;
|
|
62
|
+
shouldSkipStaticView(_routePath, view) {
|
|
63
|
+
return view.cache === "dynamic";
|
|
57
64
|
}
|
|
58
65
|
/**
|
|
59
66
|
* Writes the robots.txt file declared by the app config.
|
|
@@ -100,29 +107,56 @@ class StaticSiteGenerator {
|
|
|
100
107
|
fileSystem.write(outputPath, contents);
|
|
101
108
|
return outputPath;
|
|
102
109
|
}
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
const
|
|
106
|
-
|
|
110
|
+
async writeStaticPageArtifact(options) {
|
|
111
|
+
options.activeStaticPathnames?.add(options.pathname);
|
|
112
|
+
const directories = options.directories ?? this.getDirectories([options.pathname]);
|
|
113
|
+
const renderedOutputPath = this.getOutputPath(options.pathname, directories);
|
|
114
|
+
const routeModuleBuildCache = this.getRouteModuleBuildCache();
|
|
115
|
+
if (options.reuseRenderedOutput !== false && options.sourceFile && routeModuleBuildCache.canReuseStaticRender({
|
|
116
|
+
sourceFile: options.sourceFile,
|
|
117
|
+
pathname: options.pathname,
|
|
118
|
+
renderedOutputPath,
|
|
119
|
+
context: this.staticRenderCacheContext,
|
|
120
|
+
force: this.forceFullStaticGeneration
|
|
121
|
+
})) {
|
|
122
|
+
appLogger.debug(`Skipped unchanged static page: ${options.debugLabel ?? options.pathname}`);
|
|
123
|
+
return;
|
|
124
|
+
}
|
|
125
|
+
const contents = await options.createContents();
|
|
126
|
+
if (contents === null) {
|
|
127
|
+
return;
|
|
128
|
+
}
|
|
129
|
+
const outputPath = this.writeStaticOutput(options.pathname, contents, directories);
|
|
130
|
+
if (options.sourceFile) {
|
|
131
|
+
routeModuleBuildCache.recordStaticRender({
|
|
132
|
+
filePath: options.sourceFile,
|
|
133
|
+
pathname: options.pathname,
|
|
134
|
+
sourceHash: fileSystem.hash(options.sourceFile),
|
|
135
|
+
renderedOutputPath: outputPath,
|
|
136
|
+
context: this.staticRenderCacheContext
|
|
137
|
+
});
|
|
138
|
+
}
|
|
107
139
|
}
|
|
108
|
-
|
|
140
|
+
pruneStaleStaticOutputs(activeStaticPathnames) {
|
|
141
|
+
const removedOutputPaths = this.getRouteModuleBuildCache().pruneStaleRenderedOutputs(activeStaticPathnames);
|
|
142
|
+
for (const outputPath of removedOutputPaths) {
|
|
143
|
+
const resolvedOutputPath = path.isAbsolute(outputPath) ? outputPath : path.resolve(outputPath);
|
|
144
|
+
if (fileSystem.exists(resolvedOutputPath)) {
|
|
145
|
+
fileSystem.remove(resolvedOutputPath);
|
|
146
|
+
appLogger.debug(`Removed stale static output: ${resolvedOutputPath}`);
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
async createFilesystemStaticContents(route, _baseUrl, routeRendererFactory, skipped) {
|
|
109
151
|
const {
|
|
110
152
|
templateRoute: { filePath },
|
|
111
153
|
params
|
|
112
154
|
} = route;
|
|
113
|
-
if (this.getStaticBuildStrategy(filePath) === "fetch") {
|
|
114
|
-
const fetchUrl = this.resolveStaticFetchUrl(route.requestUrl, baseUrl);
|
|
115
|
-
const response = await fetch(fetchUrl);
|
|
116
|
-
if (!response.ok) {
|
|
117
|
-
appLogger.error(`Failed to fetch ${fetchUrl}. Status: ${response.status}`);
|
|
118
|
-
return null;
|
|
119
|
-
}
|
|
120
|
-
return response.text();
|
|
121
|
-
}
|
|
122
155
|
if (!routeRendererFactory) {
|
|
123
156
|
throw new Error(STATIC_SITE_GENERATOR_ERRORS.ROUTE_RENDERER_FACTORY_REQUIRED);
|
|
124
157
|
}
|
|
125
158
|
if (await this.shouldSkipStaticPageFile(filePath, routeRendererFactory)) {
|
|
159
|
+
skipped?.push(filePath);
|
|
126
160
|
return null;
|
|
127
161
|
}
|
|
128
162
|
const renderer = routeRendererFactory.getPageRenderer(filePath);
|
|
@@ -143,42 +177,51 @@ class StaticSiteGenerator {
|
|
|
143
177
|
* Generates static output for all filesystem-discovered routes.
|
|
144
178
|
*
|
|
145
179
|
* @remarks
|
|
146
|
-
* Routes
|
|
147
|
-
* issuing a request against the running server origin. Render-strategy routes
|
|
148
|
-
* go through the normal route renderer directly.
|
|
180
|
+
* Routes are rendered through the normal route renderer directly.
|
|
149
181
|
*/
|
|
150
|
-
async generateStaticPages(router, baseUrl, routeRendererFactory) {
|
|
151
|
-
const routes = await router.listStaticGenerationRoutes({ runtimeOrigin: baseUrl });
|
|
182
|
+
async generateStaticPages(router, baseUrl, routeRendererFactory, skipped, activeStaticPathnames, preloadedRoutes) {
|
|
183
|
+
const routes = preloadedRoutes ?? await router.listStaticGenerationRoutes({ runtimeOrigin: baseUrl });
|
|
152
184
|
appLogger.debug(
|
|
153
185
|
"Static Pages",
|
|
154
186
|
routes.map((route) => route.requestUrl)
|
|
155
187
|
);
|
|
156
188
|
const directories = this.getDirectories(routes.map((route) => route.requestUrl));
|
|
157
|
-
|
|
189
|
+
await runWithConcurrency(routes, resolveStaticPageConcurrency(), async (route) => {
|
|
158
190
|
try {
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
191
|
+
await this.writeStaticPageArtifact({
|
|
192
|
+
pathname: route.pathname,
|
|
193
|
+
sourceFile: route.templateRoute.filePath,
|
|
194
|
+
directories,
|
|
195
|
+
debugLabel: route.requestUrl,
|
|
196
|
+
activeStaticPathnames,
|
|
197
|
+
createContents: () => this.createFilesystemStaticContents(route, baseUrl, routeRendererFactory, skipped)
|
|
198
|
+
});
|
|
164
199
|
} catch (error) {
|
|
165
200
|
appLogger.error(
|
|
166
201
|
`Error generating static page for ${route.requestUrl}:`,
|
|
167
202
|
error instanceof Error ? error : String(error)
|
|
168
203
|
);
|
|
169
204
|
}
|
|
170
|
-
}
|
|
205
|
+
});
|
|
171
206
|
}
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
207
|
+
createStaticExportContext(input) {
|
|
208
|
+
return {
|
|
209
|
+
appConfig: this.appConfig,
|
|
210
|
+
router: input.router,
|
|
211
|
+
baseUrl: input.baseUrl,
|
|
212
|
+
routeRendererFactory: input.routeRendererFactory,
|
|
213
|
+
staticRoutes: input.staticRoutes,
|
|
214
|
+
force: input.force,
|
|
215
|
+
preserveExportDirectory: input.preserveExportDirectory
|
|
216
|
+
};
|
|
217
|
+
}
|
|
218
|
+
async invokeStaticExportHook(hook, context) {
|
|
219
|
+
for (const integration of this.appConfig.integrations) {
|
|
220
|
+
const handler = integration[hook];
|
|
221
|
+
if (typeof handler === "function") {
|
|
222
|
+
await handler.call(integration, context);
|
|
223
|
+
}
|
|
175
224
|
}
|
|
176
|
-
const targetUrl = new URL(route);
|
|
177
|
-
const buildUrl = new URL(baseUrl);
|
|
178
|
-
buildUrl.pathname = targetUrl.pathname;
|
|
179
|
-
buildUrl.search = targetUrl.search;
|
|
180
|
-
buildUrl.hash = targetUrl.hash;
|
|
181
|
-
return buildUrl.href;
|
|
182
225
|
}
|
|
183
226
|
/**
|
|
184
227
|
* Executes the full static-generation workflow for one app run.
|
|
@@ -187,19 +230,71 @@ class StaticSiteGenerator {
|
|
|
187
230
|
router,
|
|
188
231
|
baseUrl,
|
|
189
232
|
routeRendererFactory,
|
|
190
|
-
staticRoutes
|
|
233
|
+
staticRoutes,
|
|
234
|
+
force = false,
|
|
235
|
+
preserveExportDirectory = false
|
|
191
236
|
}) {
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
237
|
+
const skippedDynamicPages = [];
|
|
238
|
+
const activeStaticPathnames = /* @__PURE__ */ new Set();
|
|
239
|
+
this.forceFullStaticGeneration = force;
|
|
240
|
+
this.staticRenderCacheContext = createRouteModuleStaticRenderCacheContext(this.appConfig);
|
|
241
|
+
if (!force) {
|
|
242
|
+
this.getRouteModuleBuildCache().ensureIncrementalStaticGenerationContext(this.staticRenderCacheContext);
|
|
243
|
+
}
|
|
244
|
+
const routes = await router.listStaticGenerationRoutes({ runtimeOrigin: baseUrl });
|
|
245
|
+
if (shouldBuildPagesUnifiedGraph()) {
|
|
246
|
+
await ensurePagesUnifiedGraphBuilt({
|
|
247
|
+
appConfig: this.appConfig,
|
|
248
|
+
entryPaths: routes.map((route) => route.templateRoute.filePath),
|
|
249
|
+
outdir: getServerModuleBuildCacheOutdir(this.appConfig),
|
|
250
|
+
force
|
|
251
|
+
});
|
|
252
|
+
}
|
|
253
|
+
const staticExportContext = this.createStaticExportContext({
|
|
254
|
+
router,
|
|
255
|
+
baseUrl,
|
|
256
|
+
routeRendererFactory,
|
|
257
|
+
staticRoutes,
|
|
258
|
+
force,
|
|
259
|
+
preserveExportDirectory
|
|
260
|
+
});
|
|
261
|
+
await this.invokeStaticExportHook("beforeStaticExport", staticExportContext);
|
|
262
|
+
try {
|
|
263
|
+
this.generateRobotsTxt();
|
|
264
|
+
await this.generateStaticPages(
|
|
265
|
+
router,
|
|
266
|
+
baseUrl,
|
|
267
|
+
routeRendererFactory,
|
|
268
|
+
skippedDynamicPages,
|
|
269
|
+
activeStaticPathnames,
|
|
270
|
+
routes
|
|
271
|
+
);
|
|
272
|
+
if (staticRoutes && staticRoutes.length > 0 && routeRendererFactory) {
|
|
273
|
+
await this.generateExplicitStaticPages(
|
|
274
|
+
staticRoutes,
|
|
275
|
+
routeRendererFactory,
|
|
276
|
+
skippedDynamicPages,
|
|
277
|
+
activeStaticPathnames
|
|
278
|
+
);
|
|
279
|
+
}
|
|
280
|
+
if (preserveExportDirectory) {
|
|
281
|
+
this.pruneStaleStaticOutputs(activeStaticPathnames);
|
|
282
|
+
}
|
|
283
|
+
} finally {
|
|
284
|
+
await this.invokeStaticExportHook("afterStaticExport", staticExportContext);
|
|
285
|
+
}
|
|
286
|
+
if (skippedDynamicPages.length > 0) {
|
|
287
|
+
appLogger.debug(
|
|
288
|
+
`Skipped ${skippedDynamicPages.length} page(s) with cache: 'dynamic' (not supported in static generation)`,
|
|
289
|
+
skippedDynamicPages
|
|
290
|
+
);
|
|
196
291
|
}
|
|
197
292
|
}
|
|
198
293
|
/**
|
|
199
294
|
* Generates static pages from explicit static routes registered via app.static().
|
|
200
295
|
* These routes use eco.page views via loader functions for HMR support.
|
|
201
296
|
*/
|
|
202
|
-
async generateExplicitStaticPages(staticRoutes, routeRendererFactory) {
|
|
297
|
+
async generateExplicitStaticPages(staticRoutes, routeRendererFactory, skipped, activeStaticPathnames) {
|
|
203
298
|
appLogger.debug(
|
|
204
299
|
"Generating explicit static routes",
|
|
205
300
|
staticRoutes.map((r) => r.path)
|
|
@@ -209,9 +304,10 @@ class StaticSiteGenerator {
|
|
|
209
304
|
const mod = await route.loader();
|
|
210
305
|
const view = mod.default;
|
|
211
306
|
if (this.shouldSkipStaticView(route.path, view)) {
|
|
307
|
+
skipped?.push(route.path);
|
|
212
308
|
continue;
|
|
213
309
|
}
|
|
214
|
-
await this.generateExplicitStaticRoute(route.path, view, routeRendererFactory);
|
|
310
|
+
await this.generateExplicitStaticRoute(route.path, view, routeRendererFactory, activeStaticPathnames);
|
|
215
311
|
} catch (error) {
|
|
216
312
|
appLogger.error(
|
|
217
313
|
`Error generating explicit static page for ${route.path}:`,
|
|
@@ -220,18 +316,25 @@ class StaticSiteGenerator {
|
|
|
220
316
|
}
|
|
221
317
|
}
|
|
222
318
|
}
|
|
223
|
-
|
|
319
|
+
resolveExplicitViewSourceFile(view) {
|
|
320
|
+
const sourceFile = view.config?.__eco?.file;
|
|
321
|
+
if (!sourceFile) {
|
|
322
|
+
return void 0;
|
|
323
|
+
}
|
|
324
|
+
return path.isAbsolute(sourceFile) ? sourceFile : path.join(this.appConfig.rootDir, sourceFile);
|
|
325
|
+
}
|
|
326
|
+
async generateExplicitStaticRoute(routePath, view, routeRendererFactory, activeStaticPathnames) {
|
|
224
327
|
const { renderer, routeEntries } = await this.planExplicitStaticRoute(routePath, view, routeRendererFactory);
|
|
328
|
+
const sourceFile = this.resolveExplicitViewSourceFile(view);
|
|
225
329
|
for (const { pathname, params } of routeEntries) {
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
renderer
|
|
232
|
-
);
|
|
233
|
-
|
|
234
|
-
appLogger.debug(`Generated static page: ${pathname} -> ${outputPath}`);
|
|
330
|
+
await this.writeStaticPageArtifact({
|
|
331
|
+
pathname,
|
|
332
|
+
sourceFile,
|
|
333
|
+
debugLabel: pathname,
|
|
334
|
+
activeStaticPathnames,
|
|
335
|
+
createContents: () => this.createExplicitStaticContents(routePath, view, params, routeRendererFactory, renderer)
|
|
336
|
+
});
|
|
337
|
+
appLogger.debug(`Generated static page: ${pathname}`);
|
|
235
338
|
}
|
|
236
339
|
}
|
|
237
340
|
async planExplicitStaticRoute(routePath, view, routeRendererFactory) {
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { EcoBuildPlugin } from '../build/build-types.js';
|
|
2
2
|
import type { AppBuildManifest } from '../build/build-manifest.js';
|
|
3
|
-
import type { BuildAdapter,
|
|
3
|
+
import type { BuildAdapter, BuildOwnership } from '../build/build-adapter.js';
|
|
4
|
+
import type { BuildRuntime } from '../build/build-runtime.js';
|
|
4
5
|
import type { AnyIntegrationPlugin } from '../plugins/integration-plugin.js';
|
|
5
6
|
import type { Processor } from '../plugins/processor.js';
|
|
6
7
|
import type { EcoSourceTransform } from '../plugins/source-transform.js';
|
|
@@ -13,6 +14,7 @@ import type { SourceModuleLoader } from '../services/module-loading/module-loadi
|
|
|
13
14
|
import type { EntrypointDependencyGraph } from '../services/runtime-state/entrypoint-dependency-graph.service.js';
|
|
14
15
|
import type { ServerInvalidationState } from '../services/runtime-state/server-invalidation-state.service.js';
|
|
15
16
|
import type { ServerModuleTranspiler } from '../services/module-loading/server-module-transpiler.service.js';
|
|
17
|
+
import type { RouteModuleBuildCache } from '../services/module-loading/route-module-build-cache.store.js';
|
|
16
18
|
export interface RobotsPreference {
|
|
17
19
|
/**
|
|
18
20
|
* The user agent
|
|
@@ -149,13 +151,21 @@ export type EcoPagesAppConfig = {
|
|
|
149
151
|
buildOwnership?: BuildOwnership;
|
|
150
152
|
buildAdapter?: BuildAdapter;
|
|
151
153
|
buildManifest?: AppBuildManifest;
|
|
152
|
-
buildExecutor?: BuildExecutor;
|
|
153
154
|
devGraphService?: DevGraphService;
|
|
154
155
|
entrypointDependencyGraph?: EntrypointDependencyGraph;
|
|
155
156
|
hostModuleLoader?: SourceModuleLoader;
|
|
156
157
|
rendererModuleContext?: unknown;
|
|
157
158
|
serverInvalidationState?: ServerInvalidationState;
|
|
158
159
|
serverModuleTranspiler?: ServerModuleTranspiler;
|
|
160
|
+
routeModuleBuildCaches?: Map<string, RouteModuleBuildCache>;
|
|
161
|
+
/** Profile-based build runtime installed by {@link installBuildRuntime}. */
|
|
162
|
+
buildRuntime?: BuildRuntime;
|
|
163
|
+
/** Set after {@link setupAppRuntimePlugins} runs processor/integration setup once per process. */
|
|
164
|
+
runtimeAssetsPrepared?: boolean;
|
|
165
|
+
/** When `'host'`, the embedded dev server owns browser dev-client bootstrap. */
|
|
166
|
+
devClientOwner?: 'core' | 'host';
|
|
167
|
+
/** @deprecated Prefer {@link devClientOwner}: `'host'`. */
|
|
168
|
+
delegateBrowserReloadToHost?: boolean;
|
|
159
169
|
};
|
|
160
170
|
/**
|
|
161
171
|
* Experimental features.
|
|
@@ -222,11 +232,4 @@ export interface EcoPagesFileSystemServerAdapter<ServerInstanceOptions = unknown
|
|
|
222
232
|
server: unknown;
|
|
223
233
|
}>;
|
|
224
234
|
}
|
|
225
|
-
export interface ProcessorPlugin {
|
|
226
|
-
name: string;
|
|
227
|
-
description?: string;
|
|
228
|
-
setup(): Promise<void>;
|
|
229
|
-
process<T = unknown>(input: T): Promise<T>;
|
|
230
|
-
teardown?(): Promise<void>;
|
|
231
|
-
}
|
|
232
235
|
export type { ClientBridgeEvent, DefaultHmrContext, IHmrManager, IClientBridge } from './public-types.js';
|
|
@@ -14,6 +14,82 @@ import type { EntrypointDependencyGraph } from '../services/runtime-state/entryp
|
|
|
14
14
|
export type { EcoPagesAppConfig } from './internal-types.js';
|
|
15
15
|
export type { EcoPageComponent } from '../eco/eco.types.js';
|
|
16
16
|
export type { ProcessedAsset } from '../services/assets/asset-processing-service/assets.types.js';
|
|
17
|
+
/**
|
|
18
|
+
* Runtime-agnostic incoming WebSocket frame.
|
|
19
|
+
*
|
|
20
|
+
* Both Bun and Node `ws` deliver text and binary frames; this discriminated
|
|
21
|
+
* union lets handlers deal with both without runtime-specific casts.
|
|
22
|
+
*/
|
|
23
|
+
export type IncomingWebSocketMessage = {
|
|
24
|
+
readonly kind: 'text';
|
|
25
|
+
readonly text: string;
|
|
26
|
+
} | {
|
|
27
|
+
readonly kind: 'binary';
|
|
28
|
+
readonly data: Uint8Array;
|
|
29
|
+
};
|
|
30
|
+
/**
|
|
31
|
+
* Runtime-agnostic outgoing WebSocket payload.
|
|
32
|
+
*
|
|
33
|
+
* Strings are sent as text frames. Anything binary-shaped is sent as binary
|
|
34
|
+
* frames. `Blob` is included for cross-runtime parity and is normalized to a
|
|
35
|
+
* binary frame by each adapter.
|
|
36
|
+
*/
|
|
37
|
+
export type OutgoingWebSocketMessage = string | Uint8Array | ArrayBuffer | ArrayBufferView | Blob;
|
|
38
|
+
/**
|
|
39
|
+
* Close event delivered to `onClose` after a connection terminates.
|
|
40
|
+
*/
|
|
41
|
+
export interface WebSocketCloseInfo {
|
|
42
|
+
readonly code: number;
|
|
43
|
+
readonly reason: string;
|
|
44
|
+
readonly wasClean: boolean;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Input passed to a WebSocket handler's `context()` factory.
|
|
48
|
+
*
|
|
49
|
+
* Adapters call `context()` exactly once per accepted upgrade. The returned
|
|
50
|
+
* value becomes `socket.context` and is shared by all lifecycle hooks.
|
|
51
|
+
*/
|
|
52
|
+
export interface WebSocketContextFactoryInput<TParams extends Record<string, string> = Record<string, string>> {
|
|
53
|
+
readonly request: Request;
|
|
54
|
+
readonly kind: string;
|
|
55
|
+
readonly params: TParams;
|
|
56
|
+
readonly search: Readonly<Record<string, string>>;
|
|
57
|
+
readonly locals?: RequestLocals;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Runtime-agnostic WebSocket socket view exposed to handlers.
|
|
61
|
+
*
|
|
62
|
+
* Framework-owned fields:
|
|
63
|
+
* - `kind`: the registered route pattern (e.g. '/ws/chat/:roomId')
|
|
64
|
+
* - `params`: dynamic segments captured at match time
|
|
65
|
+
* - `search`: query string, always string-typed
|
|
66
|
+
*
|
|
67
|
+
* App-owned field:
|
|
68
|
+
* - `context`: returned by the handler's `context()` factory
|
|
69
|
+
*/
|
|
70
|
+
export interface EcopagesSocket<TContext = unknown, TParams extends Record<string, string> = Record<string, string>> {
|
|
71
|
+
readonly kind: string;
|
|
72
|
+
readonly params: TParams;
|
|
73
|
+
readonly search: Readonly<Record<string, string>>;
|
|
74
|
+
readonly context: TContext;
|
|
75
|
+
send(message: OutgoingWebSocketMessage): void;
|
|
76
|
+
sendStream(stream: ReadableStream<Uint8Array>): Promise<void>;
|
|
77
|
+
close(code?: number, reason?: string): void;
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Connection-lifecycle handler object.
|
|
81
|
+
*
|
|
82
|
+
* All hooks are optional. `context()` is the one-time initializer that
|
|
83
|
+
* produces the per-connection state shared by the lifecycle hooks. Returning
|
|
84
|
+
* a rejected promise from `context()` aborts the upgrade.
|
|
85
|
+
*/
|
|
86
|
+
export interface EcopagesWebSocketHandler<TContext = unknown, TParams extends Record<string, string> = Record<string, string>> {
|
|
87
|
+
context?(input: WebSocketContextFactoryInput<TParams>): TContext | Promise<TContext>;
|
|
88
|
+
onConnect?(socket: EcopagesSocket<TContext, TParams>): void | Promise<void>;
|
|
89
|
+
onMessage?(socket: EcopagesSocket<TContext, TParams>, message: IncomingWebSocketMessage): void | Promise<void>;
|
|
90
|
+
onClose?(socket: EcopagesSocket<TContext, TParams>, event: WebSocketCloseInfo): void | Promise<void>;
|
|
91
|
+
onError?(socket: EcopagesSocket<TContext, TParams>, error: unknown): void | Promise<void>;
|
|
92
|
+
}
|
|
17
93
|
import type { StandardSchema, StandardSchemaResult, StandardSchemaSuccessResult, StandardSchemaFailureResult, StandardSchemaIssue, InferOutput } from '../services/validation/standard-schema.types.js';
|
|
18
94
|
export type { StandardSchema, StandardSchemaResult, StandardSchemaSuccessResult, StandardSchemaFailureResult, StandardSchemaIssue, InferOutput, ForeignChildRuntime, };
|
|
19
95
|
export type InteractionEventsString = ScriptsInjectorInteractionEventsString;
|
|
@@ -201,6 +277,10 @@ export interface IHmrManager {
|
|
|
201
277
|
* Enables or disables HMR.
|
|
202
278
|
*/
|
|
203
279
|
setEnabled(enabled: boolean): void;
|
|
280
|
+
/**
|
|
281
|
+
* Stops active HMR watchers and releases dev-time resources.
|
|
282
|
+
*/
|
|
283
|
+
stop(): void;
|
|
204
284
|
/**
|
|
205
285
|
* Returns whether HMR is enabled.
|
|
206
286
|
*/
|
|
@@ -213,6 +293,13 @@ export interface IHmrManager {
|
|
|
213
293
|
* Gets the output URL for a registered entrypoint.
|
|
214
294
|
*/
|
|
215
295
|
getOutputUrl(entrypointPath: string): string | undefined;
|
|
296
|
+
/**
|
|
297
|
+
* Returns an existing emitted HMR script artifact without registering it.
|
|
298
|
+
*/
|
|
299
|
+
getResolvedScriptOutput?(entrypointPath: string): {
|
|
300
|
+
outputUrl: string;
|
|
301
|
+
outputPath: string;
|
|
302
|
+
} | undefined;
|
|
216
303
|
/**
|
|
217
304
|
* Gets the map of watched files.
|
|
218
305
|
*/
|
|
@@ -667,7 +754,6 @@ export type IntegrationRendererRenderOptions<C = EcoPagesElement> = RouteRendere
|
|
|
667
754
|
pageProps?: Record<string, unknown>;
|
|
668
755
|
cacheStrategy?: CacheStrategy;
|
|
669
756
|
pageLocals?: RequestLocals;
|
|
670
|
-
ownershipPlan?: OwnershipPlan;
|
|
671
757
|
};
|
|
672
758
|
/**
|
|
673
759
|
* Structured page asset package produced after dependency resolution.
|
|
@@ -746,27 +832,6 @@ export interface OwnershipValidationError {
|
|
|
746
832
|
integrationName?: string;
|
|
747
833
|
}
|
|
748
834
|
export type OwnershipPlanNodeSource = 'route' | 'page' | 'layout' | 'html-template' | 'dependency';
|
|
749
|
-
export interface IntegrationOwnership {
|
|
750
|
-
integrationName: string;
|
|
751
|
-
componentId: string;
|
|
752
|
-
componentFile?: string;
|
|
753
|
-
isPageEntry: boolean;
|
|
754
|
-
isForeignToParent: boolean;
|
|
755
|
-
}
|
|
756
|
-
export interface OwnershipPlanNode {
|
|
757
|
-
id: string;
|
|
758
|
-
source: OwnershipPlanNodeSource;
|
|
759
|
-
ownership: IntegrationOwnership;
|
|
760
|
-
children: OwnershipPlanNode[];
|
|
761
|
-
declaredDependenciesValid: boolean;
|
|
762
|
-
}
|
|
763
|
-
export interface OwnershipPlan {
|
|
764
|
-
root: OwnershipPlanNode;
|
|
765
|
-
rendererNames: string[];
|
|
766
|
-
foreignEdgeCount: number;
|
|
767
|
-
hasValidationErrors: boolean;
|
|
768
|
-
validationErrors: OwnershipValidationError[];
|
|
769
|
-
}
|
|
770
835
|
export type ForeignSubtreeAttachmentPolicy = {
|
|
771
836
|
kind: 'none';
|
|
772
837
|
} | {
|
|
@@ -7,6 +7,7 @@ function getEmbeddedRuntimeCommandOptions() {
|
|
|
7
7
|
build: false,
|
|
8
8
|
start: !isDevelopment,
|
|
9
9
|
dev: isDevelopment,
|
|
10
|
+
force: false,
|
|
10
11
|
port: void 0,
|
|
11
12
|
hostname: void 0,
|
|
12
13
|
reactFastRefresh: void 0
|
|
@@ -25,6 +26,7 @@ function parseCliArgs(options = {}) {
|
|
|
25
26
|
dev: { type: "boolean" },
|
|
26
27
|
preview: { type: "boolean" },
|
|
27
28
|
build: { type: "boolean" },
|
|
29
|
+
force: { type: "boolean" },
|
|
28
30
|
port: { type: "string" },
|
|
29
31
|
hostname: { type: "string" },
|
|
30
32
|
"react-fast-refresh": { type: "boolean" }
|
|
@@ -48,6 +50,7 @@ function parseCliArgs(options = {}) {
|
|
|
48
50
|
build: isBuildCommand,
|
|
49
51
|
start: isStartCommand,
|
|
50
52
|
dev: isDevCommand,
|
|
53
|
+
force: !!values.force,
|
|
51
54
|
port: values.port ? Number(values.port) : void 0,
|
|
52
55
|
hostname: values.hostname,
|
|
53
56
|
reactFastRefresh: values["react-fast-refresh"]
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The default entry file name when no other source provides a value.
|
|
3
|
+
*/
|
|
4
|
+
export declare const DEFAULT_ENTRY_FILE = "app.ts";
|
|
5
|
+
/**
|
|
6
|
+
* The environment variable used to override the entry file path.
|
|
7
|
+
*/
|
|
8
|
+
export declare const ENTRY_FILE_ENV = "ECOPAGES_ENTRY_FILE";
|
|
9
|
+
/**
|
|
10
|
+
* Centralized definition of the entry-file CLI argument.
|
|
11
|
+
*
|
|
12
|
+
* Exported so callers (CLI, tests, docs) reference a single source of truth
|
|
13
|
+
* for the flag name, short alias, and type. Keep this in sync with
|
|
14
|
+
* `resolveEntryFile` below.
|
|
15
|
+
*/
|
|
16
|
+
export declare const entryFileOptions: {
|
|
17
|
+
readonly 'entry-file': {
|
|
18
|
+
readonly type: "string";
|
|
19
|
+
readonly short: "e";
|
|
20
|
+
};
|
|
21
|
+
};
|
|
22
|
+
/**
|
|
23
|
+
* The long flag name for the entry file option. Re-exported as a
|
|
24
|
+
* constant so consumers don't hardcode the string.
|
|
25
|
+
*/
|
|
26
|
+
export declare const ENTRY_FILE_FLAG = "entry-file";
|
|
27
|
+
/**
|
|
28
|
+
* Resolved sources for the entry file, in precedence order (highest first):
|
|
29
|
+
*
|
|
30
|
+
* 1. `entryFile` argument — explicit caller override (e.g. constructor)
|
|
31
|
+
* 2. `ECOPAGES_ENTRY_FILE` env var — set by the CLI when spawning
|
|
32
|
+
* 3. `--entry-file` / `-e` CLI flag — read from `process.argv` via `parseArgs`
|
|
33
|
+
* 4. `app.ts` — the framework default
|
|
34
|
+
*/
|
|
35
|
+
export interface ResolveEntryFileOptions {
|
|
36
|
+
/** Explicit override (e.g. constructor param or test fixture). */
|
|
37
|
+
entryFile?: string;
|
|
38
|
+
/** Environment to read `ECOPAGES_ENTRY_FILE` from. Defaults to `process.env`. */
|
|
39
|
+
env?: Record<string, string | undefined>;
|
|
40
|
+
/** Argv to parse. Defaults to `process.argv`. */
|
|
41
|
+
argv?: string[];
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Resolves the entry file path using standard precedence.
|
|
45
|
+
*
|
|
46
|
+
* This is the single source of truth for entry-file resolution across
|
|
47
|
+
* the CLI, build pipeline, and runtime. Both the CLI layer and the
|
|
48
|
+
* runtime builders call into this function instead of reimplementing
|
|
49
|
+
* the precedence chain.
|
|
50
|
+
*
|
|
51
|
+
* @example
|
|
52
|
+
* resolveEntryFile(); // 'app.ts' (or env/argv)
|
|
53
|
+
* resolveEntryFile({ entryFile: 'src/server.ts' }); // 'src/server.ts'
|
|
54
|
+
* resolveEntryFile({ env: { ECOPAGES_ENTRY_FILE: 'x' }}); // 'x'
|
|
55
|
+
* resolveEntryFile({ argv: ['node', '-e', 'flag.ts'] }); // 'flag.ts'
|
|
56
|
+
*/
|
|
57
|
+
export declare function resolveEntryFile({ entryFile, env, argv, }?: ResolveEntryFileOptions): string;
|
|
58
|
+
/**
|
|
59
|
+
* Parses argv for the entry-file flag using the shared `parseArgs` config.
|
|
60
|
+
*
|
|
61
|
+
* Exposed for callers that need the raw flag value without the full
|
|
62
|
+
* precedence chain (e.g. CLI help text, validation).
|
|
63
|
+
*/
|
|
64
|
+
export declare function readEntryFileFlag(argv?: string[]): string | undefined;
|
|
65
|
+
/**
|
|
66
|
+
* The subdirectory inside `dist/` where the bundled server entry is placed.
|
|
67
|
+
*/
|
|
68
|
+
export declare const SERVER_BUNDLE_DIR = ".server";
|
|
69
|
+
/**
|
|
70
|
+
* The filename of the bundled server entry.
|
|
71
|
+
*/
|
|
72
|
+
export declare const SERVER_BUNDLE_FILENAME = "app.mjs";
|