@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
|
@@ -1,43 +1,15 @@
|
|
|
1
1
|
import path from "node:path";
|
|
2
2
|
import { fileSystem } from "@ecopages/file-system";
|
|
3
3
|
import { BaseProcessor } from "../base/base-processor.js";
|
|
4
|
+
import { applyStylesheetProcessors } from "./stylesheet-processor-pipeline.js";
|
|
4
5
|
class FileStylesheetProcessor extends BaseProcessor {
|
|
5
|
-
static PROCESSABLE_STYLESHEET_EXTENSIONS = /* @__PURE__ */ new Set([".css", ".scss", ".sass", ".less"]);
|
|
6
6
|
getStyleContent = (srcUrl) => {
|
|
7
7
|
return fileSystem.readFileAsBuffer(srcUrl);
|
|
8
8
|
};
|
|
9
|
-
isProcessableStylesheet(filepath) {
|
|
10
|
-
return FileStylesheetProcessor.PROCESSABLE_STYLESHEET_EXTENSIONS.has(path.extname(filepath));
|
|
11
|
-
}
|
|
12
|
-
async applyStylesheetProcessors(content, filepath) {
|
|
13
|
-
if (!this.isProcessableStylesheet(filepath)) {
|
|
14
|
-
return content;
|
|
15
|
-
}
|
|
16
|
-
let transformedContent = content;
|
|
17
|
-
for (const processor of this.appConfig.processors.values()) {
|
|
18
|
-
const hasCapabilities = processor.getAssetCapabilities().length > 0;
|
|
19
|
-
const canProcessStylesheet = processor.canProcessAsset("stylesheet", filepath);
|
|
20
|
-
if (!canProcessStylesheet && (hasCapabilities || !processor.getName().includes("postcss"))) {
|
|
21
|
-
continue;
|
|
22
|
-
}
|
|
23
|
-
if (!processor.matchesFileFilter(filepath)) {
|
|
24
|
-
continue;
|
|
25
|
-
}
|
|
26
|
-
const result = await processor.process(transformedContent, filepath);
|
|
27
|
-
if (typeof result === "string") {
|
|
28
|
-
transformedContent = result;
|
|
29
|
-
continue;
|
|
30
|
-
}
|
|
31
|
-
if (result instanceof Buffer) {
|
|
32
|
-
transformedContent = result.toString();
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
return transformedContent;
|
|
36
|
-
}
|
|
37
9
|
async process(dep) {
|
|
38
10
|
const buffer = this.getStyleContent(dep.filepath);
|
|
39
11
|
const rawContent = buffer.toString();
|
|
40
|
-
const processedContent = await this.
|
|
12
|
+
const processedContent = await applyStylesheetProcessors(this.appConfig, rawContent, dep.filepath);
|
|
41
13
|
const hash = this.generateHash(processedContent);
|
|
42
14
|
const cachekey = this.buildCacheKey(dep.filepath, hash, dep);
|
|
43
15
|
return this.getOrProcess(cachekey, () => {
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import path from "node:path";
|
|
2
|
+
const PROCESSABLE_STYLESHEET_EXTENSIONS = /* @__PURE__ */ new Set([".css", ".scss", ".sass", ".less"]);
|
|
3
|
+
function isProcessableStylesheet(filepath) {
|
|
4
|
+
return PROCESSABLE_STYLESHEET_EXTENSIONS.has(path.extname(filepath));
|
|
5
|
+
}
|
|
6
|
+
function shouldRunStylesheetProcessor(processor, filepath) {
|
|
7
|
+
const hasCapabilities = processor.getAssetCapabilities().length > 0;
|
|
8
|
+
const canProcessStylesheet = processor.canProcessAsset("stylesheet", filepath);
|
|
9
|
+
if (canProcessStylesheet) {
|
|
10
|
+
return true;
|
|
11
|
+
}
|
|
12
|
+
if (hasCapabilities) {
|
|
13
|
+
return false;
|
|
14
|
+
}
|
|
15
|
+
return processor.getName().includes("postcss");
|
|
16
|
+
}
|
|
17
|
+
async function applyStylesheetProcessors(appConfig, content, filepath) {
|
|
18
|
+
if (!isProcessableStylesheet(filepath)) {
|
|
19
|
+
return content;
|
|
20
|
+
}
|
|
21
|
+
let transformedContent = content;
|
|
22
|
+
const processors = appConfig.processors ? Array.from(appConfig.processors.values()) : [];
|
|
23
|
+
for (const processor of processors) {
|
|
24
|
+
if (!shouldRunStylesheetProcessor(processor, filepath)) {
|
|
25
|
+
continue;
|
|
26
|
+
}
|
|
27
|
+
if (!processor.matchesFileFilter(filepath)) {
|
|
28
|
+
continue;
|
|
29
|
+
}
|
|
30
|
+
const result = await processor.process(transformedContent, filepath);
|
|
31
|
+
if (typeof result === "string") {
|
|
32
|
+
transformedContent = result;
|
|
33
|
+
continue;
|
|
34
|
+
}
|
|
35
|
+
if (result instanceof Buffer) {
|
|
36
|
+
transformedContent = result.toString();
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
return transformedContent;
|
|
40
|
+
}
|
|
41
|
+
export {
|
|
42
|
+
applyStylesheetProcessors
|
|
43
|
+
};
|
|
@@ -16,6 +16,7 @@ export type BrowserBundleOptions = {
|
|
|
16
16
|
externalPackages?: boolean;
|
|
17
17
|
external?: string[];
|
|
18
18
|
plugins?: EcoBuildPlugin[];
|
|
19
|
+
executor?: 'build' | 'hmr';
|
|
19
20
|
[key: string]: unknown;
|
|
20
21
|
profile: BuildTranspileProfile;
|
|
21
22
|
excludeAppBuildPlugins?: string[];
|
|
@@ -65,7 +66,8 @@ export declare class BrowserBundleService implements BrowserBundleExecutor {
|
|
|
65
66
|
* @remarks
|
|
66
67
|
* Browser defaults and app-owned browser build plugins are applied here so HMR
|
|
67
68
|
* and runtime asset generation do not have to recreate that policy at each call
|
|
68
|
-
* site.
|
|
69
|
+
* site. Also forwards {@link getAppSourceTransforms | app source transforms} so
|
|
70
|
+
* metadata injection runs after boundary/runtime `onLoad` rewrites.
|
|
69
71
|
*/
|
|
70
72
|
bundle(options: BrowserBundleOptions): Promise<BuildResult>;
|
|
71
73
|
bundleGroupedEntries(entries: BrowserBundleGroupedEntry[], options: BrowserBundleGroupedOptions): Promise<BuildResult>;
|
|
@@ -1,5 +1,14 @@
|
|
|
1
|
-
import { getAppBrowserBuildPlugins,
|
|
1
|
+
import { getAppBrowserBuildPlugins, getAppTranspileOptions } from "../../build/build-adapter.js";
|
|
2
|
+
import { requireBuildRuntime } from "../../build/build-runtime.js";
|
|
2
3
|
import { mergeEcoBuildPlugins } from "../../build/build-manifest.js";
|
|
4
|
+
import { getAppSourceTransforms } from "../../plugins/source-transform.js";
|
|
5
|
+
function resolveBrowserBundleExecutor(appConfig, profile, executor) {
|
|
6
|
+
const buildRuntime = requireBuildRuntime(appConfig);
|
|
7
|
+
if (executor === "hmr" && profile === "hmr-entrypoint") {
|
|
8
|
+
return buildRuntime.getProfile("browser-hmr");
|
|
9
|
+
}
|
|
10
|
+
return buildRuntime.getProfile("route-module");
|
|
11
|
+
}
|
|
3
12
|
class BrowserBundleService {
|
|
4
13
|
appConfig;
|
|
5
14
|
/**
|
|
@@ -14,19 +23,22 @@ class BrowserBundleService {
|
|
|
14
23
|
* @remarks
|
|
15
24
|
* Browser defaults and app-owned browser build plugins are applied here so HMR
|
|
16
25
|
* and runtime asset generation do not have to recreate that policy at each call
|
|
17
|
-
* site.
|
|
26
|
+
* site. Also forwards {@link getAppSourceTransforms | app source transforms} so
|
|
27
|
+
* metadata injection runs after boundary/runtime `onLoad` rewrites.
|
|
18
28
|
*/
|
|
19
29
|
async bundle(options) {
|
|
20
|
-
const { profile, excludeAppBuildPlugins, plugins, ...rawBuildOptions } = options;
|
|
30
|
+
const { profile, excludeAppBuildPlugins, plugins, executor = "hmr", ...rawBuildOptions } = options;
|
|
21
31
|
const appBrowserPlugins = getAppBrowserBuildPlugins(this.appConfig);
|
|
22
32
|
const filteredAppBrowserPlugins = excludeAppBuildPlugins && excludeAppBuildPlugins.length > 0 ? appBrowserPlugins.filter((plugin) => !excludeAppBuildPlugins.includes(plugin.name)) : appBrowserPlugins;
|
|
23
33
|
const request = {
|
|
24
34
|
...rawBuildOptions,
|
|
25
35
|
entrypoints: options.entrypoints,
|
|
26
36
|
...getAppTranspileOptions(this.appConfig, profile),
|
|
27
|
-
plugins: mergeEcoBuildPlugins(plugins, filteredAppBrowserPlugins)
|
|
37
|
+
plugins: mergeEcoBuildPlugins(plugins, filteredAppBrowserPlugins),
|
|
38
|
+
sourceTransforms: getAppSourceTransforms(this.appConfig)
|
|
28
39
|
};
|
|
29
|
-
|
|
40
|
+
const buildExecutor = resolveBrowserBundleExecutor(this.appConfig, profile, executor);
|
|
41
|
+
return await buildExecutor.build(request);
|
|
30
42
|
}
|
|
31
43
|
async bundleGroupedEntries(entries, options) {
|
|
32
44
|
const request = {
|
|
@@ -83,7 +83,7 @@ export declare class HtmlTransformerService {
|
|
|
83
83
|
* string-based fallback remains in place for runtimes that cannot provide one
|
|
84
84
|
* of those rewriter implementations.
|
|
85
85
|
*/
|
|
86
|
-
transform(res: Response, contributions?: HtmlDocumentContribution[]): Promise<Response>;
|
|
86
|
+
transform(res: Response, contributions?: HtmlDocumentContribution[], pagePackage?: PagePackageResult): Promise<Response>;
|
|
87
87
|
/**
|
|
88
88
|
* Splits processed assets into head and body injection groups.
|
|
89
89
|
*/
|
|
@@ -188,8 +188,8 @@ class HtmlTransformerService {
|
|
|
188
188
|
* string-based fallback remains in place for runtimes that cannot provide one
|
|
189
189
|
* of those rewriter implementations.
|
|
190
190
|
*/
|
|
191
|
-
async transform(res, contributions = []) {
|
|
192
|
-
const { head, body } = this.groupDependenciesByPosition();
|
|
191
|
+
async transform(res, contributions = [], pagePackage) {
|
|
192
|
+
const { head, body } = this.groupDependenciesByPosition(pagePackage);
|
|
193
193
|
const { headPrepend, headAppend, bodyPrepend, bodyAppend } = this.groupContributionsByPlacement(contributions);
|
|
194
194
|
const htmlRewriter = await this.htmlRewriterProvider.createHtmlRewriter();
|
|
195
195
|
if (htmlRewriter) {
|
|
@@ -239,8 +239,8 @@ class HtmlTransformerService {
|
|
|
239
239
|
/**
|
|
240
240
|
* Splits processed assets into head and body injection groups.
|
|
241
241
|
*/
|
|
242
|
-
groupDependenciesByPosition() {
|
|
243
|
-
const dependencies = this.pagePackage ? this.resolvePagePackageHtmlDependencies(this.pagePackage) : this.processedDependencies;
|
|
242
|
+
groupDependenciesByPosition(pagePackageOverride) {
|
|
243
|
+
const dependencies = pagePackageOverride ? this.resolvePagePackageHtmlDependencies(pagePackageOverride) : this.pagePackage ? this.resolvePagePackageHtmlDependencies(this.pagePackage) : this.processedDependencies;
|
|
244
244
|
return dependencies.reduce(
|
|
245
245
|
(acc, dep) => {
|
|
246
246
|
if (dep.kind === "script") {
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import type { EcoPagesAppConfig } from '../../types/internal-types.js';
|
|
2
|
-
export type
|
|
1
|
+
import type { EcoPagesAppConfig, RegisteredScriptEntrypointChangeHandler } from '../../types/internal-types.js';
|
|
2
|
+
export type { RegisteredScriptEntrypointChangeHandler };
|
|
3
|
+
export type DevelopmentInvalidationCategory = 'public-asset' | 'additional-watch' | 'include-source' | 'explicit-server-view' | 'route-source' | 'processor-owned-asset' | 'server-source' | 'other';
|
|
3
4
|
/**
|
|
4
5
|
* Framework-owned invalidation plan for one changed file.
|
|
5
6
|
*
|
|
@@ -38,6 +39,14 @@ export declare class DevelopmentInvalidationService {
|
|
|
38
39
|
* Invalidates the app-owned server-module graph.
|
|
39
40
|
*/
|
|
40
41
|
invalidateServerModules(changedFiles?: string[]): void;
|
|
42
|
+
/**
|
|
43
|
+
* Registers an integration-owned handler for registered script entrypoint edits.
|
|
44
|
+
*/
|
|
45
|
+
registerRegisteredScriptEntrypointChangeHandler(handler: RegisteredScriptEntrypointChangeHandler): void;
|
|
46
|
+
/**
|
|
47
|
+
* Notifies integration handlers that a registered script entrypoint changed.
|
|
48
|
+
*/
|
|
49
|
+
notifyRegisteredScriptEntrypointChange(filePath: string): Promise<void>;
|
|
41
50
|
/**
|
|
42
51
|
* Resets runtime-owned graph state and invalidates server modules.
|
|
43
52
|
*/
|
|
@@ -62,6 +71,15 @@ export declare class DevelopmentInvalidationService {
|
|
|
62
71
|
* Returns whether the file is an include/template source file.
|
|
63
72
|
*/
|
|
64
73
|
isIncludeSourceFile(filePath: string): boolean;
|
|
74
|
+
/**
|
|
75
|
+
* Returns whether the file is an explicit server-rendered view module.
|
|
76
|
+
*
|
|
77
|
+
* @remarks
|
|
78
|
+
* These modules are typically registered through `renderServerModule` in
|
|
79
|
+
* `app.ts` rather than the filesystem router. They need a full browser reload
|
|
80
|
+
* because their HTML is produced on the server, not through client HMR entrypoints.
|
|
81
|
+
*/
|
|
82
|
+
isExplicitServerViewFile(filePath: string): boolean;
|
|
65
83
|
/**
|
|
66
84
|
* Returns whether the file is a server-executed source module outside the
|
|
67
85
|
* special route/include buckets.
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import path from "node:path";
|
|
2
2
|
import { getAppServerInvalidationState } from "../runtime-state/server-invalidation-state.service.js";
|
|
3
|
+
import { appLogger } from "../../global/app-logger.js";
|
|
3
4
|
class DevelopmentInvalidationService {
|
|
4
5
|
appConfig;
|
|
5
6
|
constructor(appConfig) {
|
|
@@ -18,6 +19,30 @@ class DevelopmentInvalidationService {
|
|
|
18
19
|
getAppServerInvalidationState(this.appConfig).invalidateServerModules(changedFiles);
|
|
19
20
|
this.appConfig.runtime?.appModuleLoader?.invalidateDevelopmentGraph();
|
|
20
21
|
}
|
|
22
|
+
/**
|
|
23
|
+
* Registers an integration-owned handler for registered script entrypoint edits.
|
|
24
|
+
*/
|
|
25
|
+
registerRegisteredScriptEntrypointChangeHandler(handler) {
|
|
26
|
+
const runtime = this.appConfig.runtime ?? {};
|
|
27
|
+
this.appConfig.runtime = runtime;
|
|
28
|
+
runtime.registeredScriptEntrypointChangeHandlers ??= [];
|
|
29
|
+
runtime.registeredScriptEntrypointChangeHandlers.push(handler);
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Notifies integration handlers that a registered script entrypoint changed.
|
|
33
|
+
*/
|
|
34
|
+
async notifyRegisteredScriptEntrypointChange(filePath) {
|
|
35
|
+
const handlers = this.appConfig.runtime?.registeredScriptEntrypointChangeHandlers ?? [];
|
|
36
|
+
for (const handler of handlers) {
|
|
37
|
+
try {
|
|
38
|
+
await handler(filePath);
|
|
39
|
+
} catch (error) {
|
|
40
|
+
appLogger.error(
|
|
41
|
+
`Failed to handle registered script entrypoint change for ${filePath}: ${error instanceof Error ? error.message : String(error)}`
|
|
42
|
+
);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
21
46
|
/**
|
|
22
47
|
* Resets runtime-owned graph state and invalidates server modules.
|
|
23
48
|
*/
|
|
@@ -55,8 +80,18 @@ class DevelopmentInvalidationService {
|
|
|
55
80
|
category: "include-source",
|
|
56
81
|
invalidateServerModules: true,
|
|
57
82
|
refreshRoutes: false,
|
|
58
|
-
reloadBrowser:
|
|
59
|
-
delegateToHmr:
|
|
83
|
+
reloadBrowser: false,
|
|
84
|
+
delegateToHmr: true,
|
|
85
|
+
processorHandledAsset: false
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
if (this.isExplicitServerViewFile(filePath)) {
|
|
89
|
+
return {
|
|
90
|
+
category: "explicit-server-view",
|
|
91
|
+
invalidateServerModules: true,
|
|
92
|
+
refreshRoutes: false,
|
|
93
|
+
reloadBrowser: false,
|
|
94
|
+
delegateToHmr: true,
|
|
60
95
|
processorHandledAsset: false
|
|
61
96
|
};
|
|
62
97
|
}
|
|
@@ -148,6 +183,25 @@ class DevelopmentInvalidationService {
|
|
|
148
183
|
}
|
|
149
184
|
return /\.(?:[cm]?ts|[jt]sx?|mdx)$/u.test(resolvedPath);
|
|
150
185
|
}
|
|
186
|
+
/**
|
|
187
|
+
* Returns whether the file is an explicit server-rendered view module.
|
|
188
|
+
*
|
|
189
|
+
* @remarks
|
|
190
|
+
* These modules are typically registered through `renderServerModule` in
|
|
191
|
+
* `app.ts` rather than the filesystem router. They need a full browser reload
|
|
192
|
+
* because their HTML is produced on the server, not through client HMR entrypoints.
|
|
193
|
+
*/
|
|
194
|
+
isExplicitServerViewFile(filePath) {
|
|
195
|
+
const resolvedPath = path.resolve(filePath);
|
|
196
|
+
const viewsDir = path.join(this.appConfig.absolutePaths.srcDir, "views");
|
|
197
|
+
if (resolvedPath !== viewsDir && !resolvedPath.startsWith(`${viewsDir}${path.sep}`)) {
|
|
198
|
+
return false;
|
|
199
|
+
}
|
|
200
|
+
if (this.appConfig.templatesExt.some((extension) => resolvedPath.endsWith(extension))) {
|
|
201
|
+
return true;
|
|
202
|
+
}
|
|
203
|
+
return /\.(?:[cm]?ts|[jt]sx?|mdx)$/u.test(resolvedPath);
|
|
204
|
+
}
|
|
151
205
|
/**
|
|
152
206
|
* Returns whether the file is a server-executed source module outside the
|
|
153
207
|
* special route/include buckets.
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
# Module Loading
|
|
2
|
+
|
|
3
|
+
Server-side source loading for framework-owned page modules, includes, and related templates.
|
|
4
|
+
|
|
5
|
+
## Import stack
|
|
6
|
+
|
|
7
|
+
```
|
|
8
|
+
Call site (route scan, renderer, SSG, API)
|
|
9
|
+
└─ AppModuleLoader.importModule() app-server-module-transpiler.service.ts
|
|
10
|
+
├─ merges server build plugins + JSX ownership plugins
|
|
11
|
+
├─ resolves route-module BuildExecutor
|
|
12
|
+
└─ PageModuleImportService.importModule()
|
|
13
|
+
├─ dev + host loader → host runtime (Node only, when configured)
|
|
14
|
+
├─ production disk cache → route-module build cache
|
|
15
|
+
├─ unified pages graph → prebuilt chunk import
|
|
16
|
+
└─ Rolldown per-page build → dynamic import of transpiled output
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
`ServerModuleTranspiler` is a thin wrapper that injects `rootDir`, optional default plugins, and invalidation version into the same `PageModuleImportService` path. App code should prefer `getAppModuleLoader(appConfig)` or `getAppServerModuleTranspiler(appConfig)`.
|
|
20
|
+
|
|
21
|
+
## Host vs app ownership
|
|
22
|
+
|
|
23
|
+
| Path | When |
|
|
24
|
+
| ----------------------- | -------------------------------------------------------------------------------------------- |
|
|
25
|
+
| Host loader | `appConfig.runtime.hostModuleLoader` set (Vite host) and file supports direct source loading |
|
|
26
|
+
| Ecopages build pipeline | Framework-owned template files under `pages/`, `includes/`, etc. |
|
|
27
|
+
|
|
28
|
+
`shouldAppUseHostModuleLoader()` encodes the directory + extension rules. Bun always uses the build pipeline today.
|
|
29
|
+
|
|
30
|
+
## Caching layers
|
|
31
|
+
|
|
32
|
+
1. **In-memory promise cache** (`PageModuleImportService.importCache`) — keyed by file path, resolved `outdir`, JSX/plugin inputs, file hash, and invalidation version. Cleared by `invalidateDevelopmentGraph()`.
|
|
33
|
+
2. **Disk transpile cache** (`.eco/.server-modules/.build-cache.json`) — production only; see route-module build cache slice.
|
|
34
|
+
3. **Unified graph manifest** — production static export fast path; see build layer docs.
|
|
35
|
+
|
|
36
|
+
## Files
|
|
37
|
+
|
|
38
|
+
| File | Role |
|
|
39
|
+
| ----------------------------------------- | --------------------------------------------------------- |
|
|
40
|
+
| `page-module-import.service.ts` | Core import/cache/build orchestration |
|
|
41
|
+
| `app-module-loader.service.ts` | App-facing loader interface |
|
|
42
|
+
| `app-server-module-transpiler.service.ts` | Factory for app-scoped loader + transpiler |
|
|
43
|
+
| `server-module-transpiler.service.ts` | Injectable transpiler boundary for tests and bootstrap |
|
|
44
|
+
| `host-module-loader-registry.ts` | Process-global host loader fallback for embedded runtimes |
|
|
45
|
+
| `source-module-support.ts` | Extension allowlist for host direct loading |
|
|
46
|
+
|
|
47
|
+
## Development invalidation
|
|
48
|
+
|
|
49
|
+
`DevelopmentInvalidationService.invalidateServerModules()` bumps the app-owned invalidation version and calls `appModuleLoader.invalidateDevelopmentGraph()`, which clears the in-memory import cache and increments the per-service invalidation counter used in cache keys and dev `?update=` query params.
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { getAppServerBuildPlugins } from "../../build/build-adapter.js";
|
|
2
|
+
import { requireBuildRuntime } from "../../build/build-runtime.js";
|
|
3
|
+
import { getJsxOwnershipPlugins } from "../../build/jsx-ownership-plugins.js";
|
|
3
4
|
import path from "node:path";
|
|
4
5
|
import { DevelopmentInvalidationService } from "../invalidation/development-invalidation.service.js";
|
|
5
6
|
import {} from "./app-module-loader.service.js";
|
|
@@ -37,22 +38,9 @@ function setAppHostModuleLoader(appConfig, hostModuleLoader) {
|
|
|
37
38
|
hostModuleLoader
|
|
38
39
|
};
|
|
39
40
|
}
|
|
40
|
-
function getJsxOwnershipPlugins(appConfig) {
|
|
41
|
-
const jsxExtensions = (appConfig.integrations ?? []).filter((integration) => integration.jsxImportSource).flatMap(
|
|
42
|
-
(integration) => integration.extensions.filter((extension) => extension.endsWith(".tsx") || extension.endsWith(".jsx")).map((extension) => ({ integration, extension }))
|
|
43
|
-
).sort((left, right) => right.extension.length - left.extension.length);
|
|
44
|
-
return jsxExtensions.map(
|
|
45
|
-
({ integration, extension }) => createForeignJsxOverridePlugin({
|
|
46
|
-
hostJsxImportSource: integration.jsxImportSource,
|
|
47
|
-
foreignExtensions: [extension],
|
|
48
|
-
excludeExtensions: jsxExtensions.filter((candidate) => candidate.extension.length > extension.length).filter((candidate) => candidate.extension.endsWith(extension)).map((candidate) => candidate.extension),
|
|
49
|
-
name: `ecopages-jsx-ownership-${integration.name}-${extension.replace(/[^a-zA-Z0-9]+/g, "-")}`
|
|
50
|
-
})
|
|
51
|
-
);
|
|
52
|
-
}
|
|
53
41
|
function createAppModuleLoader(appConfig) {
|
|
54
42
|
const invalidationService = new DevelopmentInvalidationService(appConfig);
|
|
55
|
-
const pageModuleImportService = new PageModuleImportService({
|
|
43
|
+
const pageModuleImportService = new PageModuleImportService(appConfig, {
|
|
56
44
|
canLoadSourceModuleFromHost: (filePath) => shouldAppUseHostModuleLoader(appConfig, filePath),
|
|
57
45
|
getHostModuleLoader: () => getAppHostModuleLoader(appConfig)
|
|
58
46
|
});
|
|
@@ -69,7 +57,7 @@ function createAppModuleLoader(appConfig) {
|
|
|
69
57
|
return await pageModuleImportService.importModule({
|
|
70
58
|
...options,
|
|
71
59
|
...mergedPlugins.length > 0 ? { plugins: mergedPlugins } : {},
|
|
72
|
-
buildExecutor: options.buildExecutor ??
|
|
60
|
+
buildExecutor: options.buildExecutor ?? requireBuildRuntime(appConfig).getProfile("route-module"),
|
|
73
61
|
invalidationVersion
|
|
74
62
|
});
|
|
75
63
|
},
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { build, type BuildExecutor, type BuildResult } from '../../build/build-adapter.js';
|
|
2
2
|
import type { EcoBuildPlugin } from '../../build/build-types.js';
|
|
3
|
+
import type { EcoPagesAppConfig } from '../../types/internal-types.js';
|
|
3
4
|
import type { SourceModuleLoaderFactory } from './module-loading-types.js';
|
|
4
5
|
interface PageModuleImportBaseOptions {
|
|
5
6
|
filePath: string;
|
|
@@ -59,10 +60,12 @@ export interface PageModuleImportDependencies {
|
|
|
59
60
|
* transpilation settings, and error semantics across the different callers.
|
|
60
61
|
*/
|
|
61
62
|
export declare class PageModuleImportService {
|
|
63
|
+
private readonly appConfig?;
|
|
62
64
|
private readonly dependencies;
|
|
65
|
+
private readonly dependencyHasher;
|
|
63
66
|
private readonly importCache;
|
|
64
67
|
private developmentInvalidationVersion;
|
|
65
|
-
constructor(dependencies?: Partial<PageModuleImportDependencies>);
|
|
68
|
+
constructor(appConfig?: EcoPagesAppConfig, dependencies?: Partial<PageModuleImportDependencies>);
|
|
66
69
|
/**
|
|
67
70
|
* Clears the shared import cache used by framework-owned page-module loads.
|
|
68
71
|
*/
|
|
@@ -91,5 +94,6 @@ export declare class PageModuleImportService {
|
|
|
91
94
|
*/
|
|
92
95
|
importModule<T = unknown>(options: PageModuleBuildImportOptions): Promise<T>;
|
|
93
96
|
private loadModule;
|
|
97
|
+
private getRouteModuleBuildCache;
|
|
94
98
|
}
|
|
95
99
|
export {};
|
|
@@ -2,19 +2,43 @@ import path from "node:path";
|
|
|
2
2
|
import { pathToFileURL } from "node:url";
|
|
3
3
|
import { fileSystem } from "@ecopages/file-system";
|
|
4
4
|
import { build } from "../../build/build-adapter.js";
|
|
5
|
+
import { resolveBuildProfileOptions } from "../../build/build-profile-options.js";
|
|
5
6
|
import { normalizeNodeRuntimeBuildOutputFile } from "../../build/runtime-build-output-normalizer.js";
|
|
7
|
+
import {
|
|
8
|
+
importPagesUnifiedGraphModule,
|
|
9
|
+
isPagesUnifiedGraphPage,
|
|
10
|
+
shouldBuildPagesUnifiedGraph
|
|
11
|
+
} from "../../build/pages-unified-graph-build.js";
|
|
12
|
+
import { recordPageModuleBuildInvocation } from "../../build/rolldown-build-invocation-metrics.js";
|
|
13
|
+
import {
|
|
14
|
+
resolvePageModuleOutputFileName,
|
|
15
|
+
createPluginCacheKey,
|
|
16
|
+
createJsxCacheKey
|
|
17
|
+
} from "./route-module-build-cache.js";
|
|
18
|
+
import { getSharedRouteModuleBuildCache } from "./route-module-build-cache-registry.js";
|
|
19
|
+
import {
|
|
20
|
+
RouteModuleDependencyHasher,
|
|
21
|
+
resolveRouteModuleDependencyPaths
|
|
22
|
+
} from "./route-module-dependency-hasher.js";
|
|
6
23
|
import { supportsSourceModuleLoading } from "./source-module-support.js";
|
|
7
24
|
class PageModuleImportService {
|
|
25
|
+
appConfig;
|
|
8
26
|
dependencies;
|
|
27
|
+
dependencyHasher;
|
|
9
28
|
importCache = /* @__PURE__ */ new Map();
|
|
10
29
|
developmentInvalidationVersion = 0;
|
|
11
|
-
constructor(dependencies) {
|
|
30
|
+
constructor(appConfig, dependencies) {
|
|
31
|
+
this.appConfig = appConfig;
|
|
12
32
|
this.dependencies = {
|
|
13
33
|
hashFile: dependencies?.hashFile ?? ((filePath) => fileSystem.hash(filePath)),
|
|
14
34
|
buildModule: dependencies?.buildModule ?? ((options, buildExecutor) => build(options, buildExecutor)),
|
|
15
35
|
canLoadSourceModuleFromHost: dependencies?.canLoadSourceModuleFromHost ?? supportsSourceModuleLoading,
|
|
16
36
|
getHostModuleLoader: dependencies?.getHostModuleLoader ?? (() => void 0)
|
|
17
37
|
};
|
|
38
|
+
this.dependencyHasher = new RouteModuleDependencyHasher({
|
|
39
|
+
hashFile: (filePath) => this.dependencies.hashFile(filePath),
|
|
40
|
+
exists: (filePath) => fileSystem.exists(filePath)
|
|
41
|
+
});
|
|
18
42
|
}
|
|
19
43
|
/**
|
|
20
44
|
* Clears the shared import cache used by framework-owned page-module loads.
|
|
@@ -33,6 +57,7 @@ class PageModuleImportService {
|
|
|
33
57
|
*/
|
|
34
58
|
invalidateDevelopmentGraph() {
|
|
35
59
|
this.clearImportCache();
|
|
60
|
+
this.dependencyHasher.clearMemo();
|
|
36
61
|
this.developmentInvalidationVersion += 1;
|
|
37
62
|
}
|
|
38
63
|
/**
|
|
@@ -70,6 +95,7 @@ class PageModuleImportService {
|
|
|
70
95
|
runtime,
|
|
71
96
|
filePath,
|
|
72
97
|
options.rootDir,
|
|
98
|
+
path.resolve(options.outdir),
|
|
73
99
|
splitting ?? "default",
|
|
74
100
|
externalPackages ?? "default",
|
|
75
101
|
options.cacheScope ?? "default",
|
|
@@ -80,13 +106,21 @@ class PageModuleImportService {
|
|
|
80
106
|
].join("::");
|
|
81
107
|
const cachedModule = this.importCache.get(cacheKey);
|
|
82
108
|
if (cachedModule) {
|
|
83
|
-
|
|
109
|
+
if (!cachedModule.dependencyHashes) {
|
|
110
|
+
return await cachedModule.promise;
|
|
111
|
+
}
|
|
112
|
+
this.dependencyHasher.clearMemo();
|
|
113
|
+
if (this.dependencyHasher.matchesStoredHashes(cachedModule.dependencyHashes, filePath, fileHash)) {
|
|
114
|
+
return await cachedModule.promise;
|
|
115
|
+
}
|
|
116
|
+
this.importCache.delete(cacheKey);
|
|
84
117
|
}
|
|
85
118
|
const importPromise = this.loadModule({
|
|
86
119
|
...options,
|
|
87
|
-
fileHash
|
|
120
|
+
fileHash,
|
|
121
|
+
importCacheKey: cacheKey
|
|
88
122
|
});
|
|
89
|
-
this.importCache.set(cacheKey, importPromise);
|
|
123
|
+
this.importCache.set(cacheKey, { promise: importPromise });
|
|
90
124
|
try {
|
|
91
125
|
return await importPromise;
|
|
92
126
|
} catch (error) {
|
|
@@ -95,7 +129,13 @@ class PageModuleImportService {
|
|
|
95
129
|
}
|
|
96
130
|
}
|
|
97
131
|
async loadModule(options) {
|
|
98
|
-
const {
|
|
132
|
+
const {
|
|
133
|
+
filePath,
|
|
134
|
+
invalidationVersion = this.developmentInvalidationVersion,
|
|
135
|
+
cacheScope,
|
|
136
|
+
fileHash,
|
|
137
|
+
importCacheKey
|
|
138
|
+
} = options;
|
|
99
139
|
const {
|
|
100
140
|
rootDir,
|
|
101
141
|
outdir,
|
|
@@ -104,39 +144,70 @@ class PageModuleImportService {
|
|
|
104
144
|
transpileErrorMessage = (details) => `Error transpiling page module: ${details}`,
|
|
105
145
|
noOutputMessage = (targetFilePath) => `No transpiled output generated for page module: ${targetFilePath}`
|
|
106
146
|
} = options;
|
|
107
|
-
const
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
147
|
+
const outputFileName = resolvePageModuleOutputFileName({
|
|
148
|
+
filePath,
|
|
149
|
+
fileHash,
|
|
150
|
+
cacheScope,
|
|
151
|
+
invalidationVersion
|
|
152
|
+
});
|
|
153
|
+
const outputNamingTemplate = outputFileName.replace(/\.mjs$/u, ".[ext]");
|
|
154
|
+
const preferredOutputPath = path.join(outdir, outputFileName);
|
|
155
|
+
const routeModuleBuildCache = this.getRouteModuleBuildCache(outdir);
|
|
156
|
+
const cachedBuild = routeModuleBuildCache.lookup({
|
|
157
|
+
...options,
|
|
158
|
+
fileHash
|
|
159
|
+
});
|
|
160
|
+
if (cachedBuild) {
|
|
161
|
+
return await import(
|
|
162
|
+
/* @vite-ignore */
|
|
163
|
+
pathToFileURL(cachedBuild.outputPath).href
|
|
164
|
+
);
|
|
165
|
+
}
|
|
166
|
+
if (!cacheScope && shouldBuildPagesUnifiedGraph() && this.appConfig && isPagesUnifiedGraphPage(filePath, this.appConfig)) {
|
|
167
|
+
const graphModule = await importPagesUnifiedGraphModule(this.appConfig, filePath);
|
|
168
|
+
if (graphModule !== void 0) {
|
|
169
|
+
return graphModule;
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
recordPageModuleBuildInvocation();
|
|
173
|
+
const buildOptions = {
|
|
174
|
+
...resolveBuildProfileOptions("route-module", this.appConfig ?? { rootDir }, {
|
|
114
175
|
entrypoints: [filePath],
|
|
115
|
-
root: rootDir,
|
|
116
176
|
outdir,
|
|
117
|
-
target: "es2022",
|
|
118
|
-
format: "esm",
|
|
119
|
-
sourcemap: "none",
|
|
120
|
-
splitting: splitting ?? true,
|
|
121
|
-
minify: false,
|
|
122
177
|
naming: outputNamingTemplate,
|
|
123
|
-
|
|
178
|
+
splitting: splitting ?? true,
|
|
124
179
|
jsx: options.jsx,
|
|
125
180
|
plugins: options.plugins,
|
|
126
181
|
...externalPackages !== void 0 ? { externalPackages } : {}
|
|
127
|
-
},
|
|
128
|
-
|
|
129
|
-
|
|
182
|
+
}),
|
|
183
|
+
root: rootDir,
|
|
184
|
+
entrypoints: [filePath]
|
|
185
|
+
};
|
|
186
|
+
const buildResult = await this.dependencies.buildModule(buildOptions, options.buildExecutor);
|
|
130
187
|
if (!buildResult.success) {
|
|
131
188
|
const details = buildResult.logs.map((log) => log.message).join(" | ");
|
|
132
189
|
throw new Error(transpileErrorMessage(details));
|
|
133
190
|
}
|
|
134
|
-
const preferredOutputPath = path.join(outdir, outputFileName);
|
|
135
191
|
const compiledOutput = buildResult.outputs.find((output) => output.path === preferredOutputPath)?.path ?? buildResult.outputs.find((output) => /\.(?:[cm]?js)$/u.test(output.path))?.path;
|
|
136
192
|
if (!compiledOutput) {
|
|
137
193
|
throw new Error(noOutputMessage(filePath));
|
|
138
194
|
}
|
|
139
195
|
normalizeNodeRuntimeBuildOutputFile(compiledOutput, rootDir);
|
|
196
|
+
const dependencyModulePaths = resolveRouteModuleDependencyPaths(buildResult, filePath, rootDir);
|
|
197
|
+
const dependencyHashes = this.dependencyHasher.createDependencyHashes(dependencyModulePaths);
|
|
198
|
+
dependencyHashes[path.normalize(filePath)] = fileHash;
|
|
199
|
+
if (importCacheKey) {
|
|
200
|
+
const cacheEntry = this.importCache.get(importCacheKey);
|
|
201
|
+
if (cacheEntry) {
|
|
202
|
+
cacheEntry.dependencyHashes = dependencyHashes;
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
routeModuleBuildCache.recordBuild({
|
|
206
|
+
...options,
|
|
207
|
+
fileHash,
|
|
208
|
+
outputPath: compiledOutput,
|
|
209
|
+
dependencyModulePaths
|
|
210
|
+
});
|
|
140
211
|
const compiledOutputUrl = pathToFileURL(compiledOutput);
|
|
141
212
|
if (shouldAddRuntimeUpdateQuery(invalidationVersion, cacheScope)) {
|
|
142
213
|
compiledOutputUrl.searchParams.set(
|
|
@@ -149,6 +220,9 @@ class PageModuleImportService {
|
|
|
149
220
|
compiledOutputUrl.href
|
|
150
221
|
);
|
|
151
222
|
}
|
|
223
|
+
getRouteModuleBuildCache(outdir) {
|
|
224
|
+
return getSharedRouteModuleBuildCache(outdir, this.appConfig);
|
|
225
|
+
}
|
|
152
226
|
}
|
|
153
227
|
function createRuntimeModuleUrl(filePath, fileHash, invalidationVersion, cacheScope) {
|
|
154
228
|
const moduleUrl = pathToFileURL(filePath);
|
|
@@ -163,31 +237,9 @@ function createRuntimeModuleUrl(filePath, fileHash, invalidationVersion, cacheSc
|
|
|
163
237
|
function shouldAddRuntimeUpdateQuery(invalidationVersion, cacheScope) {
|
|
164
238
|
return process.env.NODE_ENV === "development" || invalidationVersion > 0 || !!cacheScope;
|
|
165
239
|
}
|
|
166
|
-
function shouldVersionBuildOutputPath(invalidationVersion) {
|
|
167
|
-
return typeof Bun !== "undefined" && invalidationVersion > 0;
|
|
168
|
-
}
|
|
169
240
|
function sanitizeCacheScope(cacheScope) {
|
|
170
241
|
return cacheScope.replace(/[^a-zA-Z0-9_-]+/g, "-");
|
|
171
242
|
}
|
|
172
|
-
function createJsxCacheKey(jsx) {
|
|
173
|
-
if (!jsx) {
|
|
174
|
-
return "jsx:default";
|
|
175
|
-
}
|
|
176
|
-
return JSON.stringify({
|
|
177
|
-
development: jsx.development ?? false,
|
|
178
|
-
factory: jsx.factory ?? null,
|
|
179
|
-
fragment: jsx.fragment ?? null,
|
|
180
|
-
importSource: jsx.importSource ?? null,
|
|
181
|
-
runtime: jsx.runtime ?? null,
|
|
182
|
-
sideEffects: jsx.sideEffects ?? null
|
|
183
|
-
});
|
|
184
|
-
}
|
|
185
|
-
function createPluginCacheKey(plugins) {
|
|
186
|
-
if (!plugins || plugins.length === 0) {
|
|
187
|
-
return "plugins:default";
|
|
188
|
-
}
|
|
189
|
-
return `plugins:${plugins.map((plugin) => plugin.name).join(",")}`;
|
|
190
|
-
}
|
|
191
243
|
export {
|
|
192
244
|
PageModuleImportService
|
|
193
245
|
};
|