@ecopages/core 0.2.0-beta.2 → 0.2.0-beta.20
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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/hmr-manager.d.ts +2 -1
- package/src/adapters/bun/hmr-manager.js +2 -2
- package/src/adapters/bun/server-adapter.d.ts +90 -22
- package/src/adapters/bun/server-adapter.js +265 -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/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 +4 -0
- package/src/adapters/node/server-adapter.d.ts +62 -20
- package/src/adapters/node/server-adapter.js +161 -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 +0 -2
- package/src/adapters/shared/hmr-entrypoint-registrar.js +3 -26
- 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 +43 -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 +97 -73
- package/src/adapters/shared/shared-hmr-manager.d.ts +28 -0
- package/src/adapters/shared/shared-hmr-manager.js +119 -9
- 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/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 +28 -0
- package/src/hmr/hmr-entrypoint-output.js +58 -0
- package/src/hmr/strategies/js-hmr-strategy.d.ts +3 -0
- package/src/hmr/strategies/js-hmr-strategy.js +68 -18
- 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.js +36 -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 +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 +97 -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 +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 +16 -9
- package/src/types/public-types.d.ts +138 -26
- 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 +25 -2
- package/src/watchers/project-watcher.js +130 -23
- 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
|
@@ -2,11 +2,14 @@ import fs from "node:fs";
|
|
|
2
2
|
import path from "node:path";
|
|
3
3
|
import { fileURLToPath } from "node:url";
|
|
4
4
|
import { RESOLVED_ASSETS_DIR } from "../../config/constants.js";
|
|
5
|
-
import {
|
|
5
|
+
import { resolveHmrEntrypointOutputPaths } from "../../hmr/hmr-entrypoint-output.js";
|
|
6
|
+
import { requireBuildRuntime } from "../../build/build-runtime.js";
|
|
6
7
|
import { fileSystem } from "@ecopages/file-system";
|
|
7
8
|
import { HmrStrategyType } from "../../hmr/hmr-strategy.js";
|
|
8
9
|
import { DefaultHmrStrategy } from "../../hmr/strategies/default-hmr-strategy.js";
|
|
9
10
|
import { JsHmrStrategy } from "../../hmr/strategies/js-hmr-strategy.js";
|
|
11
|
+
import { ServerRenderedTemplateHmrStrategy } from "../../hmr/strategies/server-rendered-template-hmr-strategy.js";
|
|
12
|
+
import { DevelopmentInvalidationService } from "../../services/invalidation/development-invalidation.service.js";
|
|
10
13
|
import { appLogger } from "../../global/app-logger.js";
|
|
11
14
|
import { HmrEntrypointRegistrar } from "./hmr-entrypoint-registrar.js";
|
|
12
15
|
import { BrowserBundleService } from "../../services/assets/browser-bundle.service.js";
|
|
@@ -16,6 +19,24 @@ import {
|
|
|
16
19
|
setAppEntrypointDependencyGraph
|
|
17
20
|
} from "../../services/runtime-state/entrypoint-dependency-graph.service.js";
|
|
18
21
|
import { resolveInternalExecutionDir, resolveInternalWorkDir } from "../../utils/resolve-work-dir.js";
|
|
22
|
+
const DEFAULT_HMR_REGISTRATION_TIMEOUT_MS = 4e3;
|
|
23
|
+
const DEVELOPMENT_HMR_REGISTRATION_TIMEOUT_MS = 15e3;
|
|
24
|
+
function resolveHmrRegistrationTimeoutMs(explicitTimeoutMs) {
|
|
25
|
+
if (explicitTimeoutMs !== void 0) {
|
|
26
|
+
return explicitTimeoutMs;
|
|
27
|
+
}
|
|
28
|
+
const envTimeoutMs = process.env.ECOPAGES_HMR_REGISTRATION_TIMEOUT_MS;
|
|
29
|
+
if (envTimeoutMs !== void 0 && envTimeoutMs !== "") {
|
|
30
|
+
const parsedTimeoutMs = Number(envTimeoutMs);
|
|
31
|
+
if (Number.isFinite(parsedTimeoutMs) && parsedTimeoutMs > 0) {
|
|
32
|
+
return parsedTimeoutMs;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
if (process.env.NODE_ENV === "development") {
|
|
36
|
+
return DEVELOPMENT_HMR_REGISTRATION_TIMEOUT_MS;
|
|
37
|
+
}
|
|
38
|
+
return DEFAULT_HMR_REGISTRATION_TIMEOUT_MS;
|
|
39
|
+
}
|
|
19
40
|
class SharedHmrManager {
|
|
20
41
|
appConfig;
|
|
21
42
|
bridge;
|
|
@@ -24,13 +45,14 @@ class SharedHmrManager {
|
|
|
24
45
|
entrypointRegistrations = /* @__PURE__ */ new Map();
|
|
25
46
|
distDir;
|
|
26
47
|
plugins = [];
|
|
27
|
-
enabled =
|
|
48
|
+
enabled = false;
|
|
28
49
|
strategies = [];
|
|
29
50
|
entrypointRegistrar;
|
|
30
51
|
browserBundleService;
|
|
31
52
|
entrypointDependencyGraph;
|
|
32
53
|
serverModuleTranspiler;
|
|
33
|
-
|
|
54
|
+
runtimeBuildPromise = null;
|
|
55
|
+
constructor({ appConfig, bridge, registrationTimeoutMs }) {
|
|
34
56
|
this.appConfig = appConfig;
|
|
35
57
|
this.bridge = bridge;
|
|
36
58
|
this.distDir = path.join(resolveInternalWorkDir(this.appConfig), RESOLVED_ASSETS_DIR, "_hmr");
|
|
@@ -40,7 +62,7 @@ class SharedHmrManager {
|
|
|
40
62
|
entrypointRegistrations: this.entrypointRegistrations,
|
|
41
63
|
watchedFiles: this.watchedFiles,
|
|
42
64
|
clearFailedRegistration: (entrypointPath) => this.clearFailedEntrypointRegistration(entrypointPath),
|
|
43
|
-
registrationTimeoutMs
|
|
65
|
+
registrationTimeoutMs: resolveHmrRegistrationTimeoutMs(registrationTimeoutMs)
|
|
44
66
|
});
|
|
45
67
|
this.browserBundleService = new BrowserBundleService(appConfig);
|
|
46
68
|
this.entrypointDependencyGraph = this.createEntrypointDependencyGraph(
|
|
@@ -86,7 +108,12 @@ class SharedHmrManager {
|
|
|
86
108
|
getEntrypointDependencyGraph: () => this.entrypointDependencyGraph,
|
|
87
109
|
shouldProcessEntrypoint: (entrypointPath) => this.shouldJsStrategyProcessEntrypoint(entrypointPath)
|
|
88
110
|
};
|
|
89
|
-
|
|
111
|
+
const invalidationService = new DevelopmentInvalidationService(this.appConfig);
|
|
112
|
+
this.strategies = [
|
|
113
|
+
new JsHmrStrategy(jsContext),
|
|
114
|
+
new ServerRenderedTemplateHmrStrategy(invalidationService),
|
|
115
|
+
new DefaultHmrStrategy()
|
|
116
|
+
];
|
|
90
117
|
}
|
|
91
118
|
registerStrategy(strategy) {
|
|
92
119
|
this.strategies.push(strategy);
|
|
@@ -100,7 +127,33 @@ class SharedHmrManager {
|
|
|
100
127
|
isEnabled() {
|
|
101
128
|
return this.enabled;
|
|
102
129
|
}
|
|
130
|
+
isRuntimeReady() {
|
|
131
|
+
return fileSystem.exists(this.getRuntimePath());
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* Builds the browser HMR runtime once and reuses the in-flight build for concurrent callers.
|
|
135
|
+
*/
|
|
136
|
+
async ensureRuntimeReady() {
|
|
137
|
+
if (this.isRuntimeReady()) {
|
|
138
|
+
return true;
|
|
139
|
+
}
|
|
140
|
+
if (this.runtimeBuildPromise) {
|
|
141
|
+
return this.runtimeBuildPromise;
|
|
142
|
+
}
|
|
143
|
+
this.runtimeBuildPromise = this.buildRuntimeInternal();
|
|
144
|
+
try {
|
|
145
|
+
return await this.runtimeBuildPromise;
|
|
146
|
+
} finally {
|
|
147
|
+
this.runtimeBuildPromise = null;
|
|
148
|
+
}
|
|
149
|
+
}
|
|
103
150
|
async buildRuntime() {
|
|
151
|
+
await this.ensureRuntimeReady();
|
|
152
|
+
}
|
|
153
|
+
getRuntimePath() {
|
|
154
|
+
return path.join(this.distDir, "_hmr_runtime.js");
|
|
155
|
+
}
|
|
156
|
+
async buildRuntimeInternal() {
|
|
104
157
|
const runtimeSource = fileURLToPath(import.meta.resolve("@ecopages/core/hmr/client/hmr-runtime"));
|
|
105
158
|
try {
|
|
106
159
|
const result = await this.browserBundleService.bundle({
|
|
@@ -113,13 +166,32 @@ class SharedHmrManager {
|
|
|
113
166
|
});
|
|
114
167
|
if (!result.success) {
|
|
115
168
|
this.onRuntimeBundleFailure(result.logs);
|
|
169
|
+
return false;
|
|
116
170
|
}
|
|
171
|
+
this.syncRuntimeOutput(result);
|
|
172
|
+
return this.isRuntimeReady();
|
|
117
173
|
} catch (error) {
|
|
118
174
|
this.onRuntimeBundleFailure(error);
|
|
175
|
+
return false;
|
|
119
176
|
}
|
|
120
177
|
}
|
|
121
|
-
|
|
122
|
-
|
|
178
|
+
/**
|
|
179
|
+
* @remarks
|
|
180
|
+
* Rolldown may emit the runtime bundle under a derived filename when the
|
|
181
|
+
* entrypoint lives outside the app root. The dev server always serves
|
|
182
|
+
* `/_hmr_runtime.js` from a stable path under `.eco/assets/_hmr/`.
|
|
183
|
+
*/
|
|
184
|
+
syncRuntimeOutput(result) {
|
|
185
|
+
const runtimePath = this.getRuntimePath();
|
|
186
|
+
if (fileSystem.exists(runtimePath)) {
|
|
187
|
+
return;
|
|
188
|
+
}
|
|
189
|
+
const emittedRuntime = result.outputs.find((output) => output.path.endsWith(".js"));
|
|
190
|
+
if (!emittedRuntime || emittedRuntime.path === runtimePath) {
|
|
191
|
+
return;
|
|
192
|
+
}
|
|
193
|
+
fileSystem.ensureDir(path.dirname(runtimePath));
|
|
194
|
+
fileSystem.copyFile(emittedRuntime.path, runtimePath);
|
|
123
195
|
}
|
|
124
196
|
broadcast(event) {
|
|
125
197
|
appLogger.debug(
|
|
@@ -158,6 +230,30 @@ class SharedHmrManager {
|
|
|
158
230
|
getOutputUrl(entrypointPath) {
|
|
159
231
|
return this.watchedFiles.get(entrypointPath);
|
|
160
232
|
}
|
|
233
|
+
/**
|
|
234
|
+
* Returns the emitted HMR script output when the entrypoint is already registered
|
|
235
|
+
* and its browser bundle exists on disk.
|
|
236
|
+
*
|
|
237
|
+
* @remarks
|
|
238
|
+
* Disk artifacts alone are not enough: a fresh dev session must still register
|
|
239
|
+
* the entrypoint so file watchers can rebuild it on change.
|
|
240
|
+
*/
|
|
241
|
+
getResolvedScriptOutput(entrypointPath) {
|
|
242
|
+
const normalizedEntrypoint = path.resolve(entrypointPath);
|
|
243
|
+
if (!this.watchedFiles.has(normalizedEntrypoint)) {
|
|
244
|
+
return void 0;
|
|
245
|
+
}
|
|
246
|
+
const { outputPath, outputUrl: derivedOutputUrl } = resolveHmrEntrypointOutputPaths(
|
|
247
|
+
this.appConfig.absolutePaths.srcDir,
|
|
248
|
+
this.distDir,
|
|
249
|
+
normalizedEntrypoint
|
|
250
|
+
);
|
|
251
|
+
if (!fileSystem.exists(outputPath)) {
|
|
252
|
+
return void 0;
|
|
253
|
+
}
|
|
254
|
+
const outputUrl = this.watchedFiles.get(normalizedEntrypoint) ?? derivedOutputUrl;
|
|
255
|
+
return { outputUrl, outputPath };
|
|
256
|
+
}
|
|
161
257
|
getWatchedFiles() {
|
|
162
258
|
return this.watchedFiles;
|
|
163
259
|
}
|
|
@@ -175,7 +271,7 @@ class SharedHmrManager {
|
|
|
175
271
|
getSrcDir: () => this.appConfig.absolutePaths.srcDir,
|
|
176
272
|
getLayoutsDir: () => this.appConfig.absolutePaths.layoutsDir,
|
|
177
273
|
getPagesDir: () => this.appConfig.absolutePaths.pagesDir,
|
|
178
|
-
getBuildExecutor: () =>
|
|
274
|
+
getBuildExecutor: () => requireBuildRuntime(this.appConfig).getProfile("browser-hmr"),
|
|
179
275
|
getBrowserBundleService: () => this.browserBundleService,
|
|
180
276
|
getEntrypointDependencyGraph: () => this.entrypointDependencyGraph,
|
|
181
277
|
importServerModule: async (filePath) => await this.serverModuleTranspiler.importModule({
|
|
@@ -220,6 +316,16 @@ class SharedHmrManager {
|
|
|
220
316
|
appLogger.error(`[HMR] Generic script entrypoint build failed for ${entrypointPath}:`, buildResult.logs);
|
|
221
317
|
return;
|
|
222
318
|
}
|
|
319
|
+
if (!fileSystem.exists(outputPath) && buildResult.outputs.length > 0) {
|
|
320
|
+
const resolvedOutputPath = path.resolve(outputPath);
|
|
321
|
+
const emittedOutput = buildResult.outputs.find((output) => path.resolve(output.path) === resolvedOutputPath)?.path ?? buildResult.outputs.find((output) => path.basename(output.path) === path.basename(outputPath))?.path;
|
|
322
|
+
if (emittedOutput && fileSystem.exists(emittedOutput)) {
|
|
323
|
+
fileSystem.ensureDir(path.dirname(outputPath));
|
|
324
|
+
if (path.resolve(emittedOutput) !== resolvedOutputPath) {
|
|
325
|
+
fileSystem.copyFile(emittedOutput, outputPath);
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
}
|
|
223
329
|
const entrypointDependencies = buildResult.dependencyGraph?.entrypoints?.[entrypointPath];
|
|
224
330
|
if (entrypointDependencies) {
|
|
225
331
|
this.entrypointDependencyGraph.setEntrypointDependencies(entrypointPath, entrypointDependencies);
|
|
@@ -235,7 +341,11 @@ class SharedHmrManager {
|
|
|
235
341
|
this.entrypointDependencyGraph.reset();
|
|
236
342
|
this.plugins = [];
|
|
237
343
|
}
|
|
344
|
+
[Symbol.dispose]() {
|
|
345
|
+
this.stop();
|
|
346
|
+
}
|
|
238
347
|
}
|
|
239
348
|
export {
|
|
240
|
-
SharedHmrManager
|
|
349
|
+
SharedHmrManager,
|
|
350
|
+
resolveHmrRegistrationTimeoutMs
|
|
241
351
|
};
|
|
@@ -7,4 +7,9 @@ export interface StaticPreviewHostStartOptions {
|
|
|
7
7
|
appConfig: EcoPagesAppConfig;
|
|
8
8
|
hostname: string;
|
|
9
9
|
port: number;
|
|
10
|
+
/**
|
|
11
|
+
* When true, bind to the next available port if the preferred one is busy.
|
|
12
|
+
* Should remain false when the port was explicitly configured.
|
|
13
|
+
*/
|
|
14
|
+
allowPortFallback?: boolean;
|
|
10
15
|
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { EcopagesSocket, WebSocketCloseInfo } from '../../types/public-types.js';
|
|
2
|
+
/**
|
|
3
|
+
* @remarks
|
|
4
|
+
* Bun and Node expose different raw socket types but share the same
|
|
5
|
+
* {@link OutgoingWebSocketMessage} contract. Adapters supply only `send`/`close`;
|
|
6
|
+
* {@link createEcopagesSocket} owns message normalization and stream forwarding.
|
|
7
|
+
*/
|
|
8
|
+
export interface WebSocketSendTransport {
|
|
9
|
+
send(data: string | Uint8Array): void;
|
|
10
|
+
close(code?: number, reason?: string): void;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* @remarks
|
|
14
|
+
* Bun and Node adapters previously duplicated outgoing-message dispatch and
|
|
15
|
+
* stream forwarding; this is the shared implementation both transports delegate to.
|
|
16
|
+
*/
|
|
17
|
+
export declare function createEcopagesSocket<TContext, TParams extends Record<string, string>>(transport: WebSocketSendTransport, meta: {
|
|
18
|
+
kind: string;
|
|
19
|
+
params: TParams;
|
|
20
|
+
search: Record<string, string>;
|
|
21
|
+
context: TContext;
|
|
22
|
+
}): EcopagesSocket<TContext, TParams>;
|
|
23
|
+
export declare function toWebSocketCloseInfo(code: number, reason: string): WebSocketCloseInfo;
|
|
24
|
+
export declare function invokeWebSocketHandlerHook(kind: string, hookName: string, result: void | Promise<void>): void;
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { appLogger } from "../../global/app-logger.js";
|
|
2
|
+
function sendOutgoingMessage(transport, message) {
|
|
3
|
+
if (typeof message === "string") {
|
|
4
|
+
transport.send(message);
|
|
5
|
+
} else if (message instanceof Blob) {
|
|
6
|
+
void message.arrayBuffer().then((buffer) => transport.send(new Uint8Array(buffer)));
|
|
7
|
+
} else if (message instanceof ArrayBuffer) {
|
|
8
|
+
transport.send(new Uint8Array(message));
|
|
9
|
+
} else if (ArrayBuffer.isView(message)) {
|
|
10
|
+
transport.send(new Uint8Array(message.buffer, message.byteOffset, message.byteLength));
|
|
11
|
+
} else {
|
|
12
|
+
transport.send(message);
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
function createEcopagesSocket(transport, meta) {
|
|
16
|
+
return {
|
|
17
|
+
kind: meta.kind,
|
|
18
|
+
params: meta.params,
|
|
19
|
+
search: meta.search,
|
|
20
|
+
context: meta.context,
|
|
21
|
+
send: (message) => sendOutgoingMessage(transport, message),
|
|
22
|
+
sendStream: async (stream) => {
|
|
23
|
+
const reader = stream.getReader();
|
|
24
|
+
try {
|
|
25
|
+
while (true) {
|
|
26
|
+
const { value, done } = await reader.read();
|
|
27
|
+
if (done) break;
|
|
28
|
+
if (value) transport.send(value);
|
|
29
|
+
}
|
|
30
|
+
} finally {
|
|
31
|
+
reader.releaseLock();
|
|
32
|
+
}
|
|
33
|
+
},
|
|
34
|
+
close: (code, reason) => transport.close(code, reason)
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
function toWebSocketCloseInfo(code, reason) {
|
|
38
|
+
return {
|
|
39
|
+
code,
|
|
40
|
+
reason,
|
|
41
|
+
wasClean: code === 1e3 || code === 1001
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
function invokeWebSocketHandlerHook(kind, hookName, result) {
|
|
45
|
+
if (result instanceof Promise) {
|
|
46
|
+
result.catch((error) => {
|
|
47
|
+
appLogger.error(`[WS:${kind}] ${hookName} failed:`, error);
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
export {
|
|
52
|
+
createEcopagesSocket,
|
|
53
|
+
invokeWebSocketHandlerHook,
|
|
54
|
+
toWebSocketCloseInfo
|
|
55
|
+
};
|
package/src/build/README.md
CHANGED
|
@@ -4,13 +4,15 @@ The build layer is the bundler contract for Ecopages. One bundled adapter is the
|
|
|
4
4
|
|
|
5
5
|
## Mental Model
|
|
6
6
|
|
|
7
|
-
Three concentric shapes, plus
|
|
7
|
+
Three concentric shapes, plus profile executors and a plugin injector:
|
|
8
8
|
|
|
9
9
|
| Shape | Lives in | Purpose |
|
|
10
10
|
| -------------------------- | ------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
11
11
|
| `BuildAdapter` | `build-adapter.ts` | Low-level backend. Two implementations: the bundled adapter (the real bundler) and `ViteHostBuildAdapter` (a host-owned boundary marker that throws on direct use). |
|
|
12
|
-
| `
|
|
13
|
-
| `
|
|
12
|
+
| `BuildRuntime` | `build-runtime.ts` | Profile-based executor registry. Single entry point on `appConfig.runtime.buildRuntime`. |
|
|
13
|
+
| `BuildExecutor` | `build-contracts.ts` | Narrower runtime facade. Only `build` is exposed. Retrieved via `buildRuntime.getProfile(...)`. |
|
|
14
|
+
| `SerializedBuildExecutor` | `serialized-build-executor.ts` | FIFO queue around any `BuildExecutor`. Used for server-entry single-flight ordering. |
|
|
15
|
+
| `ParallelBuildExecutor` | `parallel-build-executor.ts` | Concurrency-limited wrapper for independent route-module and HMR browser builds. |
|
|
14
16
|
| `withBuildExecutorPlugins` | `build-adapter.ts` | Merges app-owned plugins into every `build` call. The single point of plugin injection. |
|
|
15
17
|
|
|
16
18
|
Plus one translation bridge:
|
|
@@ -20,29 +22,31 @@ Plus one translation bridge:
|
|
|
20
22
|
## Files
|
|
21
23
|
|
|
22
24
|
- `build-adapter.ts`: types, factories, app-owned helpers, `withBuildExecutorPlugins`.
|
|
25
|
+
- `build-runtime.ts`: profile-based executor installation (`server-entry`, `route-module`, `browser-hmr`).
|
|
23
26
|
- `build-types.ts`: the `EcoBuildPlugin` contract used by integrations and processors.
|
|
24
27
|
- `rolldown-build-adapter.ts`: the production `BuildAdapter`. Wraps the bundler and exposes a normalized `BuildResult` (outputs, dependency graph, logs).
|
|
25
28
|
- `rolldown-plugin-bridge.ts`: `EcoBuildPlugin[]` → bundler-plugin translation.
|
|
26
29
|
- `serialized-build-executor.ts`: FIFO queue primitive.
|
|
27
|
-
- `runtime-build-executor.ts`:
|
|
30
|
+
- `runtime-build-executor.ts`: server-adapter entrypoint that installs `BuildRuntime` via `installAppRuntimeBuildExecutor()`.
|
|
31
|
+
- `server-entry-build-cache.ts`: production server-entry bundle cache (`.eco/.server-entry/.build-cache.json` + `dist/.server/manifest.json`).
|
|
28
32
|
- `*.test.ts`: regression coverage.
|
|
29
33
|
|
|
30
34
|
## Default Flow
|
|
31
35
|
|
|
32
|
-
`ConfigBuilder.build()` creates one app-owned adapter
|
|
33
|
-
|
|
34
|
-
When a server adapter initializes, it calls `installAppRuntimeBuildExecutor(appConfig)`. That function reads the existing executor (or falls back to the app-owned adapter) and stores a fresh wrapper:
|
|
36
|
+
`ConfigBuilder.build()` creates one app-owned adapter and manifest. When a server adapter initializes, it calls `installAppRuntimeBuildExecutor(appConfig)`, which installs `BuildRuntime`:
|
|
35
37
|
|
|
36
38
|
```
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
39
|
+
BuildRuntime.getProfile(...)
|
|
40
|
+
├─ server-entry → SerializedBuildExecutor → withBuildExecutorPlugins → RolldownBuildAdapter
|
|
41
|
+
├─ route-module → ParallelBuildExecutor → withBuildExecutorPlugins → RolldownBuildAdapter
|
|
42
|
+
└─ browser-hmr → ParallelBuildExecutor → withBuildExecutorPlugins → RolldownBuildAdapter
|
|
41
43
|
```
|
|
42
44
|
|
|
43
|
-
|
|
45
|
+
All profiles use one-shot Rolldown in both dev and production. Route-module and browser-HMR builds run in parallel; server-entry stays serialized single-flight.
|
|
46
|
+
|
|
47
|
+
Runtime code should call `requireBuildRuntime(appConfig).getProfile('route-module' | 'browser-hmr' | 'server-entry')` instead of reading legacy executor slots.
|
|
44
48
|
|
|
45
|
-
The exported `defaultBuildAdapter` and the top-level `build()` / `getTranspileOptions()` helpers are non-app-aware escape hatches. New runtime code should prefer `getAppBuildAdapter()`, `
|
|
49
|
+
The exported `defaultBuildAdapter` and the top-level `build()` / `getTranspileOptions()` helpers are non-app-aware escape hatches. New runtime code should prefer `getAppBuildAdapter()`, `requireBuildRuntime()`, and `getAppTranspileOptions()`.
|
|
46
50
|
|
|
47
51
|
## Vite-Host Boundary
|
|
48
52
|
|
|
@@ -81,11 +85,70 @@ Plugin ordering: the bundler's `resolveId` and `load` are "first" hooks. The bri
|
|
|
81
85
|
|
|
82
86
|
These fields are kept in the type so existing call-sites compile. The proper fix is a more focused `BuildOptions` schema in a follow-up.
|
|
83
87
|
|
|
88
|
+
## Dev / watch path
|
|
89
|
+
|
|
90
|
+
`installBuildRuntime` (via `installAppRuntimeBuildExecutor`) installs profile-based executors:
|
|
91
|
+
|
|
92
|
+
| Profile | Backend | Concurrency |
|
|
93
|
+
| -------------- | ----------------- | -------------------- |
|
|
94
|
+
| `server-entry` | Rolldown one-shot | Serialized |
|
|
95
|
+
| `route-module` | Rolldown one-shot | Parallel |
|
|
96
|
+
| `browser-hmr` | Rolldown one-shot | Parallel (limit ≤ 3) |
|
|
97
|
+
|
|
98
|
+
`hmr-entrypoint` rebuilds use the `browser-hmr` profile. Other browser builds (`browser-script`, `hmr-runtime`) use `route-module`.
|
|
99
|
+
|
|
100
|
+
`ProjectWatcher` deduplicates watch roots, ignores `.eco/` and `dist/`, and coalesces duplicate chokidar events within 150ms.
|
|
101
|
+
|
|
102
|
+
## Metrics
|
|
103
|
+
|
|
104
|
+
Set `ECOPAGES_ROLLDOWN_BUILD_METRICS=1` to log Rolldown invocation counts during dev and production builds. Compare kitchen-sink dev navigation and `static-build-bench` before/after runtime changes.
|
|
105
|
+
|
|
106
|
+
## Production build caches
|
|
107
|
+
|
|
108
|
+
Two persisted cache layers accelerate production builds. Both use `.build-cache.json` manifests keyed by dependency hashes and a build-inputs fingerprint.
|
|
109
|
+
|
|
110
|
+
| Cache | On-disk location | Module |
|
|
111
|
+
| -------------------------------------- | --------------------------------------------------- | ----------------------------------- |
|
|
112
|
+
| Server-entry bundle | `.eco/.server-entry/.build-cache.json` | `server-entry-build-cache.ts` |
|
|
113
|
+
| Route-module transpile + static render | `<server-outdir>/.server-modules/.build-cache.json` | `route-module-build-cache.store.ts` |
|
|
114
|
+
|
|
115
|
+
`getInstalledServerEntryBuildExecutor()` returns the `server-entry` profile from `BuildRuntime`. `clearProductionBuildCaches()` wipes both manifest trees, resets in-memory route-module state, and clears `buildRuntime`.
|
|
116
|
+
|
|
117
|
+
The route-module registry (`route-module-build-cache-registry.ts`) shares one `RouteModuleBuildCache` per `(app, outdir)` pair. Legacy `.server-route-modules` outdirs are still read for migration but new writes go to `.server-modules`.
|
|
118
|
+
|
|
119
|
+
## Unified pages graph
|
|
120
|
+
|
|
121
|
+
Production static exports compile all template pages in one Rolldown invocation when `shouldBuildPagesUnifiedGraph()` is true (default in production; opt out with `ECOPAGES_UNIFIED_PAGES_GRAPH=0`).
|
|
122
|
+
|
|
123
|
+
| Artifact | Location |
|
|
124
|
+
| -------------- | ----------------------------------------------------- |
|
|
125
|
+
| Graph manifest | `.eco/.server-pages-graph/.build-cache.json` |
|
|
126
|
+
| Chunk outputs | `.eco/.server-modules/` (shared with per-route cache) |
|
|
127
|
+
|
|
128
|
+
`StaticSiteGenerator` calls `ensurePagesUnifiedGraphBuilt()` before the export loop. `PageModuleImportService` imports prebuilt chunks via `importPagesUnifiedGraphModule()` and falls back to per-page Rolldown on miss.
|
|
129
|
+
|
|
130
|
+
`ECOPAGES_ROLLDOWN_BUILD_METRICS=1` enables `rolldown-build-invocation-metrics.ts` counters used by bench and parity tests.
|
|
131
|
+
|
|
132
|
+
Build-input fingerprinting lives in `build-input-fingerprint.ts` and is shared with server-entry cache, unified pages graph, and static-render invalidation.
|
|
133
|
+
|
|
134
|
+
## JSX Ownership Plugins
|
|
135
|
+
|
|
136
|
+
Mixed-integration apps need explicit `@jsxImportSource` handling in two different shapes:
|
|
137
|
+
|
|
138
|
+
| Helper | Use when | Behavior |
|
|
139
|
+
| ------------------------------------ | ----------------------------------------- | ----------------------------------------------------------------------------------------------------------------------- |
|
|
140
|
+
| `getJsxOwnershipPlugins()` | App-wide server/transpile builds | Each JSX integration extension gets its **own** `jsxImportSource` so native files keep their owning runtime. |
|
|
141
|
+
| `getHostScopedJsxOwnershipPlugins()` | One integration's **client** bundle graph | Foreign `.tsx`/`.jsx` files compile with the **host** integration JSX runtime (for example React bundling `.kita.tsx`). |
|
|
142
|
+
| `eco-component-meta-plugin` | Component metadata injection | Prepends the **owning** integration pragma only when injecting `__eco` metadata into native files. |
|
|
143
|
+
|
|
144
|
+
`foreign-jsx-override-plugin.ts` is the shared implementation. Prefer the helpers above instead of calling it directly from integrations.
|
|
145
|
+
|
|
84
146
|
## Testing Strategy
|
|
85
147
|
|
|
86
148
|
- `rolldown-build-adapter.test.ts` covers the adapter's `build`, `resolve`, `getTranspileOptions`, and dependency-graph extraction end-to-end.
|
|
87
149
|
- `rolldown-plugin-bridge.test.ts` covers the `EcoBuildPlugin[]` → plugin translation in isolation.
|
|
88
150
|
- `build-adapter.test.ts` covers the app-owned helpers, the `BuildOwnership` routing, the `withBuildExecutorPlugins` injection, and the default-fallback behaviour.
|
|
89
|
-
- `
|
|
151
|
+
- `build-runtime.test.ts` covers profile executor installation and parallelism.
|
|
152
|
+
- `runtime-build-executor.test.ts` covers the runtime wrapper: plugin injection and the Vite-host rejection path.
|
|
90
153
|
|
|
91
154
|
If you change option mapping or plugin-bridge semantics, update the adapter and bridge tests first. If you change the app-owned helper contracts, update `build-adapter.test.ts` first.
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { EcoBuildPlugin } from './build-types.js';
|
|
2
|
+
import type { AppBuildManifest } from './build-manifest.js';
|
|
3
|
+
import type { EcoPagesAppConfig, IHmrManager } from '../types/internal-types.js';
|
|
4
|
+
export declare function collectConfiguredAppBuildManifestContributions(appConfig: EcoPagesAppConfig): Promise<Pick<AppBuildManifest, 'runtimePlugins' | 'browserBundlePlugins' | 'browserRuntimeManifest'>>;
|
|
5
|
+
export declare function setupAppRuntimePlugins(options: {
|
|
6
|
+
appConfig: EcoPagesAppConfig;
|
|
7
|
+
runtimeOrigin: string;
|
|
8
|
+
hmrManager?: IHmrManager;
|
|
9
|
+
onRuntimePlugin?: (plugin: EcoBuildPlugin) => void;
|
|
10
|
+
}): Promise<void>;
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import { mergeBrowserRuntimeManifests } from "./browser-runtime-manifest.js";
|
|
2
|
+
import { appLogger } from "../global/app-logger.js";
|
|
3
|
+
function patchAppRuntime(appConfig, patch) {
|
|
4
|
+
appConfig.runtime = {
|
|
5
|
+
...appConfig.runtime ?? {},
|
|
6
|
+
...patch
|
|
7
|
+
};
|
|
8
|
+
}
|
|
9
|
+
function registerRuntimePlugins(appConfig, onRuntimePlugin) {
|
|
10
|
+
for (const loader of appConfig.loaders.values()) {
|
|
11
|
+
onRuntimePlugin?.(loader);
|
|
12
|
+
}
|
|
13
|
+
for (const processor of appConfig.processors.values()) {
|
|
14
|
+
if (processor.plugins) {
|
|
15
|
+
for (const plugin of processor.plugins) {
|
|
16
|
+
onRuntimePlugin?.(plugin);
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
for (const integration of appConfig.integrations) {
|
|
21
|
+
for (const plugin of integration.plugins) {
|
|
22
|
+
onRuntimePlugin?.(plugin);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
async function collectConfiguredAppBuildManifestContributions(appConfig) {
|
|
27
|
+
const runtimePlugins = [];
|
|
28
|
+
const browserBundlePlugins = [];
|
|
29
|
+
const browserRuntimeManifests = [];
|
|
30
|
+
for (const processor of appConfig.processors.values()) {
|
|
31
|
+
await processor.prepareBuildContributions();
|
|
32
|
+
if (processor.plugins) {
|
|
33
|
+
runtimePlugins.push(...processor.plugins);
|
|
34
|
+
}
|
|
35
|
+
if (processor.buildPlugins) {
|
|
36
|
+
browserBundlePlugins.push(...processor.buildPlugins);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
for (const integration of appConfig.integrations) {
|
|
40
|
+
integration.setConfig(appConfig);
|
|
41
|
+
await integration.prepareBuildContributions();
|
|
42
|
+
runtimePlugins.push(...integration.plugins ?? []);
|
|
43
|
+
browserBundlePlugins.push(...integration.browserBuildPlugins ?? []);
|
|
44
|
+
browserRuntimeManifests.push(integration.browserRuntimeManifest);
|
|
45
|
+
}
|
|
46
|
+
return {
|
|
47
|
+
runtimePlugins,
|
|
48
|
+
browserBundlePlugins,
|
|
49
|
+
browserRuntimeManifest: mergeBrowserRuntimeManifests(...browserRuntimeManifests)
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
async function setupAppRuntimePlugins(options) {
|
|
53
|
+
if (options.appConfig.runtime?.runtimeAssetsPrepared) {
|
|
54
|
+
appLogger.debug("Skipped setupAppRuntimePlugins: runtime assets already prepared");
|
|
55
|
+
registerRuntimePlugins(options.appConfig, options.onRuntimePlugin);
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
appLogger.debugTime("setupAppRuntimePlugins");
|
|
59
|
+
try {
|
|
60
|
+
for (const loader of options.appConfig.loaders.values()) {
|
|
61
|
+
options.onRuntimePlugin?.(loader);
|
|
62
|
+
}
|
|
63
|
+
for (const processor of options.appConfig.processors.values()) {
|
|
64
|
+
await processor.setup();
|
|
65
|
+
if (processor.plugins) {
|
|
66
|
+
for (const plugin of processor.plugins) {
|
|
67
|
+
options.onRuntimePlugin?.(plugin);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
for (const integration of options.appConfig.integrations) {
|
|
72
|
+
integration.setConfig(options.appConfig);
|
|
73
|
+
integration.setRuntimeOrigin(options.runtimeOrigin);
|
|
74
|
+
if (options.hmrManager) {
|
|
75
|
+
integration.setHmrManager(options.hmrManager);
|
|
76
|
+
}
|
|
77
|
+
await integration.setup();
|
|
78
|
+
for (const plugin of integration.plugins) {
|
|
79
|
+
options.onRuntimePlugin?.(plugin);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
patchAppRuntime(options.appConfig, { runtimeAssetsPrepared: true });
|
|
83
|
+
} finally {
|
|
84
|
+
appLogger.debugTimeEnd("setupAppRuntimePlugins");
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
export {
|
|
88
|
+
collectConfiguredAppBuildManifestContributions,
|
|
89
|
+
setupAppRuntimePlugins
|
|
90
|
+
};
|