@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
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Returns whether a source path is a registered client script HMR entrypoint.
|
|
3
|
+
*
|
|
4
|
+
* @remarks
|
|
5
|
+
* Registration comes from `dependencies.scripts` via `FileScriptProcessor`,
|
|
6
|
+
* not from filename conventions such as `.script.tsx`.
|
|
7
|
+
*/
|
|
8
|
+
export declare function isRegisteredScriptEntrypoint(watchedFiles: ReadonlyMap<string, string>, filePath: string): boolean;
|
|
9
|
+
export declare function encodeHmrDynamicSegments(filepath: string): string;
|
|
10
|
+
/**
|
|
11
|
+
* Resolves the on-disk and browser URL targets for one HMR script entrypoint.
|
|
12
|
+
*/
|
|
13
|
+
export declare function resolveHmrEntrypointOutputPaths(srcDir: string, distDir: string, entrypointPath: string): {
|
|
14
|
+
outputPath: string;
|
|
15
|
+
outputUrl: string;
|
|
16
|
+
};
|
|
17
|
+
/**
|
|
18
|
+
* @remarks
|
|
19
|
+
* Rebuilds must delete the previous artifact so browser-hmr does not reuse a
|
|
20
|
+
* stale bundle when the source file changed.
|
|
21
|
+
*/
|
|
22
|
+
export declare function removeStaleHmrEntrypointOutput(outputPath: string, scope: string): void;
|
|
23
|
+
/**
|
|
24
|
+
* @remarks
|
|
25
|
+
* Guards against broadcasting reload/update before the bundler has flushed a
|
|
26
|
+
* fresher artifact than the edited source file.
|
|
27
|
+
*/
|
|
28
|
+
export declare function isHmrOutputFresh(outputPath: string, sourcePath: string): boolean;
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { fileSystem } from "@ecopages/file-system";
|
|
4
|
+
import { RESOLVED_ASSETS_DIR } from "../config/constants.js";
|
|
5
|
+
import { appLogger } from "../global/app-logger.js";
|
|
6
|
+
function isRegisteredScriptEntrypoint(watchedFiles, filePath) {
|
|
7
|
+
const resolvedPath = path.resolve(filePath);
|
|
8
|
+
if (watchedFiles.has(resolvedPath)) {
|
|
9
|
+
return true;
|
|
10
|
+
}
|
|
11
|
+
for (const entrypointPath of watchedFiles.keys()) {
|
|
12
|
+
if (path.resolve(entrypointPath) === resolvedPath) {
|
|
13
|
+
return true;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
return false;
|
|
17
|
+
}
|
|
18
|
+
function encodeHmrDynamicSegments(filepath) {
|
|
19
|
+
return filepath.replace(/\[([^\]]+)\]/g, "_$1_");
|
|
20
|
+
}
|
|
21
|
+
function resolveHmrEntrypointOutputPaths(srcDir, distDir, entrypointPath) {
|
|
22
|
+
const normalizedEntrypoint = path.resolve(entrypointPath);
|
|
23
|
+
const relativePath = path.relative(srcDir, normalizedEntrypoint);
|
|
24
|
+
const relativePathJs = relativePath.replace(/\.(tsx?|jsx?|mdx?)$/, ".js");
|
|
25
|
+
const encodedPathJs = encodeHmrDynamicSegments(relativePathJs);
|
|
26
|
+
const urlPath = encodedPathJs.split(path.sep).join("/");
|
|
27
|
+
return {
|
|
28
|
+
outputUrl: `/${path.join(RESOLVED_ASSETS_DIR, "_hmr", urlPath).split(path.sep).join("/")}`,
|
|
29
|
+
outputPath: path.join(distDir, urlPath)
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
function removeStaleHmrEntrypointOutput(outputPath, scope) {
|
|
33
|
+
if (!fileSystem.exists(outputPath)) {
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
try {
|
|
37
|
+
fileSystem.remove(outputPath);
|
|
38
|
+
} catch (error) {
|
|
39
|
+
appLogger.warn(
|
|
40
|
+
`[${scope}] Failed to remove stale entrypoint output ${outputPath}: ${error instanceof Error ? error.message : String(error)}`
|
|
41
|
+
);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
function isHmrOutputFresh(outputPath, sourcePath) {
|
|
45
|
+
if (!fileSystem.exists(outputPath) || !fileSystem.exists(sourcePath)) {
|
|
46
|
+
return false;
|
|
47
|
+
}
|
|
48
|
+
const outputMtimeMs = fs.statSync(outputPath).mtimeMs;
|
|
49
|
+
const sourceMtimeMs = fs.statSync(sourcePath).mtimeMs;
|
|
50
|
+
return outputMtimeMs >= sourceMtimeMs;
|
|
51
|
+
}
|
|
52
|
+
export {
|
|
53
|
+
encodeHmrDynamicSegments,
|
|
54
|
+
isHmrOutputFresh,
|
|
55
|
+
isRegisteredScriptEntrypoint,
|
|
56
|
+
removeStaleHmrEntrypointOutput,
|
|
57
|
+
resolveHmrEntrypointOutputPaths
|
|
58
|
+
};
|
|
@@ -98,6 +98,7 @@ export declare class JsHmrStrategy extends HmrStrategy {
|
|
|
98
98
|
* Matches if:
|
|
99
99
|
* 1. There are registered entrypoints to rebuild
|
|
100
100
|
* 2. The changed file is a JS/TS file in the src directory
|
|
101
|
+
* 3. Registered entrypoints always match, even when they share an integration template extension
|
|
101
102
|
*
|
|
102
103
|
* @param filePath - Absolute path to the changed file
|
|
103
104
|
* @returns True if this file should trigger entrypoint rebuilds
|
|
@@ -116,6 +117,8 @@ export declare class JsHmrStrategy extends HmrStrategy {
|
|
|
116
117
|
* @returns Action to broadcast update events
|
|
117
118
|
*/
|
|
118
119
|
process(filePath: string): Promise<HmrAction>;
|
|
120
|
+
private resolveEntrypointOutputPath;
|
|
121
|
+
private removeStaleEntrypointOutput;
|
|
119
122
|
/**
|
|
120
123
|
* Bundles one or more entrypoints in a single build invocation.
|
|
121
124
|
* Uses the source directory as the output base so that the directory structure
|
|
@@ -2,6 +2,12 @@ import path from "node:path";
|
|
|
2
2
|
import { fileSystem } from "@ecopages/file-system";
|
|
3
3
|
import { HmrStrategy, HmrStrategyType } from "../hmr-strategy.js";
|
|
4
4
|
import { appLogger } from "../../global/app-logger.js";
|
|
5
|
+
import {
|
|
6
|
+
removeStaleHmrEntrypointOutput,
|
|
7
|
+
resolveHmrEntrypointOutputPaths,
|
|
8
|
+
isRegisteredScriptEntrypoint,
|
|
9
|
+
isHmrOutputFresh
|
|
10
|
+
} from "../hmr-entrypoint-output.js";
|
|
5
11
|
class JsHmrStrategy extends HmrStrategy {
|
|
6
12
|
type = HmrStrategyType.SCRIPT;
|
|
7
13
|
context;
|
|
@@ -15,27 +21,30 @@ class JsHmrStrategy extends HmrStrategy {
|
|
|
15
21
|
* Matches if:
|
|
16
22
|
* 1. There are registered entrypoints to rebuild
|
|
17
23
|
* 2. The changed file is a JS/TS file in the src directory
|
|
24
|
+
* 3. Registered entrypoints always match, even when they share an integration template extension
|
|
18
25
|
*
|
|
19
26
|
* @param filePath - Absolute path to the changed file
|
|
20
27
|
* @returns True if this file should trigger entrypoint rebuilds
|
|
21
28
|
*/
|
|
22
29
|
matches(filePath) {
|
|
23
30
|
const watchedFiles = this.context.getWatchedFiles();
|
|
24
|
-
const
|
|
25
|
-
const
|
|
26
|
-
const
|
|
31
|
+
const resolvedPath = path.resolve(filePath);
|
|
32
|
+
const isJsTs = /\.(ts|tsx|js|jsx)$/.test(resolvedPath);
|
|
33
|
+
const srcDir = path.resolve(this.context.getSrcDir());
|
|
34
|
+
const isInSrc = resolvedPath.startsWith(`${srcDir}${path.sep}`) || resolvedPath === srcDir;
|
|
35
|
+
const isIntegrationTemplate = this.context.getTemplateExtensions().some((extension) => resolvedPath.endsWith(extension));
|
|
27
36
|
if (watchedFiles.size === 0) {
|
|
28
37
|
return false;
|
|
29
38
|
}
|
|
30
39
|
if (!isJsTs || !isInSrc) {
|
|
31
40
|
return false;
|
|
32
41
|
}
|
|
42
|
+
if (watchedFiles.has(resolvedPath)) {
|
|
43
|
+
return true;
|
|
44
|
+
}
|
|
33
45
|
if (isIntegrationTemplate) {
|
|
34
46
|
return false;
|
|
35
47
|
}
|
|
36
|
-
if (watchedFiles.has(filePath)) {
|
|
37
|
-
return true;
|
|
38
|
-
}
|
|
39
48
|
return true;
|
|
40
49
|
}
|
|
41
50
|
/**
|
|
@@ -53,22 +62,27 @@ class JsHmrStrategy extends HmrStrategy {
|
|
|
53
62
|
async process(filePath) {
|
|
54
63
|
appLogger.debug(`[JsHmrStrategy] Processing ${filePath}`);
|
|
55
64
|
const watchedFiles = this.context.getWatchedFiles();
|
|
65
|
+
const resolvedChanged = path.resolve(filePath);
|
|
66
|
+
const isRegisteredEntrypointEdit = isRegisteredScriptEntrypoint(watchedFiles, resolvedChanged);
|
|
56
67
|
if (watchedFiles.size === 0) {
|
|
57
68
|
appLogger.debug(`[JsHmrStrategy] No watched files to rebuild`);
|
|
58
69
|
return { type: "none" };
|
|
59
70
|
}
|
|
60
71
|
const dependencyHits = this.context.getEntrypointDependencyGraph().getDependencyEntrypoints(filePath);
|
|
61
72
|
const hasDependencyHit = dependencyHits.size > 0;
|
|
62
|
-
const impactedEntrypoints = hasDependencyHit ? Array.from(dependencyHits).filter((entrypoint) => watchedFiles.has(entrypoint)) : Array.from(watchedFiles.keys());
|
|
73
|
+
const impactedEntrypoints = isRegisteredEntrypointEdit ? [resolvedChanged] : hasDependencyHit ? Array.from(dependencyHits).filter((entrypoint) => watchedFiles.has(path.resolve(entrypoint))) : Array.from(watchedFiles.keys());
|
|
63
74
|
const buildableEntrypoints = impactedEntrypoints.filter(
|
|
64
75
|
(entrypoint) => this.context.shouldProcessEntrypoint?.(entrypoint) ?? true
|
|
65
76
|
);
|
|
66
|
-
if (!hasDependencyHit) {
|
|
77
|
+
if (!hasDependencyHit && !isRegisteredEntrypointEdit) {
|
|
67
78
|
appLogger.debug("[JsHmrStrategy] Dependency graph miss, rebuilding all watched entrypoints");
|
|
68
79
|
}
|
|
69
80
|
if (buildableEntrypoints.length === 0) {
|
|
70
81
|
return { type: "none" };
|
|
71
82
|
}
|
|
83
|
+
for (const entrypoint of buildableEntrypoints) {
|
|
84
|
+
this.removeStaleEntrypointOutput(this.resolveEntrypointOutputPath(entrypoint));
|
|
85
|
+
}
|
|
72
86
|
const buildResult = await this.bundleEntrypoints(buildableEntrypoints);
|
|
73
87
|
if (!buildResult.success) {
|
|
74
88
|
return { type: "none" };
|
|
@@ -76,17 +90,19 @@ class JsHmrStrategy extends HmrStrategy {
|
|
|
76
90
|
const updates = [];
|
|
77
91
|
let reloadRequired = false;
|
|
78
92
|
for (const entrypoint of buildableEntrypoints) {
|
|
79
|
-
const
|
|
80
|
-
|
|
93
|
+
const resolvedEntrypoint = path.resolve(entrypoint);
|
|
94
|
+
const derivedOutput = resolveHmrEntrypointOutputPaths(
|
|
95
|
+
this.context.getSrcDir(),
|
|
96
|
+
this.context.getDistDir(),
|
|
97
|
+
resolvedEntrypoint
|
|
98
|
+
);
|
|
99
|
+
const outputUrl = watchedFiles.get(resolvedEntrypoint) ?? derivedOutput.outputUrl;
|
|
100
|
+
const outputPath = this.resolveEntrypointOutputPath(resolvedEntrypoint);
|
|
81
101
|
if (buildResult.dependencies) {
|
|
82
|
-
const entrypointDeps = buildResult.dependencies.get(
|
|
83
|
-
this.context.getEntrypointDependencyGraph().setEntrypointDependencies(
|
|
102
|
+
const entrypointDeps = buildResult.dependencies.get(resolvedEntrypoint) ?? [];
|
|
103
|
+
this.context.getEntrypointDependencyGraph().setEntrypointDependencies(resolvedEntrypoint, entrypointDeps);
|
|
84
104
|
}
|
|
85
|
-
const
|
|
86
|
-
const relativePath = path.relative(srcDir, entrypoint);
|
|
87
|
-
const relativePathJs = relativePath.replace(/\.(tsx?|jsx?|mdx?)$/, ".js");
|
|
88
|
-
const outputPath = path.join(this.context.getDistDir(), relativePathJs);
|
|
89
|
-
const result = await this.processOutput(outputPath, outputUrl);
|
|
105
|
+
const result = await this.processOutput(outputPath, outputUrl, resolvedEntrypoint);
|
|
90
106
|
if (result.success) {
|
|
91
107
|
updates.push(outputUrl);
|
|
92
108
|
if (result.requiresReload) {
|
|
@@ -113,6 +129,12 @@ class JsHmrStrategy extends HmrStrategy {
|
|
|
113
129
|
}
|
|
114
130
|
return { type: "none" };
|
|
115
131
|
}
|
|
132
|
+
resolveEntrypointOutputPath(entrypointPath) {
|
|
133
|
+
return resolveHmrEntrypointOutputPaths(this.context.getSrcDir(), this.context.getDistDir(), entrypointPath).outputPath;
|
|
134
|
+
}
|
|
135
|
+
removeStaleEntrypointOutput(outputPath) {
|
|
136
|
+
removeStaleHmrEntrypointOutput(outputPath, "JsHmrStrategy");
|
|
137
|
+
}
|
|
116
138
|
/**
|
|
117
139
|
* Bundles one or more entrypoints in a single build invocation.
|
|
118
140
|
* Uses the source directory as the output base so that the directory structure
|
|
@@ -120,6 +142,30 @@ class JsHmrStrategy extends HmrStrategy {
|
|
|
120
142
|
*/
|
|
121
143
|
async bundleEntrypoints(entrypoints) {
|
|
122
144
|
try {
|
|
145
|
+
if (entrypoints.length === 1) {
|
|
146
|
+
const entrypoint = entrypoints[0];
|
|
147
|
+
const outputPath = this.resolveEntrypointOutputPath(entrypoint);
|
|
148
|
+
const naming = path.relative(this.context.getDistDir(), outputPath).split(path.sep).join("/");
|
|
149
|
+
const result2 = await this.context.getBrowserBundleService().bundle({
|
|
150
|
+
profile: "hmr-entrypoint",
|
|
151
|
+
entrypoints: [entrypoint],
|
|
152
|
+
outdir: this.context.getDistDir(),
|
|
153
|
+
naming,
|
|
154
|
+
plugins: this.context.getPlugins(),
|
|
155
|
+
minify: false
|
|
156
|
+
});
|
|
157
|
+
if (!result2.success) {
|
|
158
|
+
appLogger.error("[JsHmrStrategy] Entrypoint build failed:", result2.logs);
|
|
159
|
+
return { success: false };
|
|
160
|
+
}
|
|
161
|
+
const dependencies2 = /* @__PURE__ */ new Map();
|
|
162
|
+
if (result2.dependencyGraph?.entrypoints) {
|
|
163
|
+
for (const [resolvedEntrypoint, deps] of Object.entries(result2.dependencyGraph.entrypoints)) {
|
|
164
|
+
dependencies2.set(path.resolve(resolvedEntrypoint), deps);
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
return { success: true, dependencies: dependencies2 };
|
|
168
|
+
}
|
|
123
169
|
const result = await this.context.getBrowserBundleService().bundle({
|
|
124
170
|
profile: "hmr-entrypoint",
|
|
125
171
|
entrypoints,
|
|
@@ -153,8 +199,12 @@ class JsHmrStrategy extends HmrStrategy {
|
|
|
153
199
|
* @param url - URL path for the bundled file
|
|
154
200
|
* @returns True if processing was successful and update should be broadcast
|
|
155
201
|
*/
|
|
156
|
-
async processOutput(filepath, url) {
|
|
202
|
+
async processOutput(filepath, url, sourcePath) {
|
|
157
203
|
try {
|
|
204
|
+
if (sourcePath && !isHmrOutputFresh(filepath, sourcePath)) {
|
|
205
|
+
appLogger.warn(`[JsHmrStrategy] Skipping broadcast for stale HMR output ${url}`);
|
|
206
|
+
return { success: false, requiresReload: false };
|
|
207
|
+
}
|
|
158
208
|
const code = await fileSystem.readFile(filepath);
|
|
159
209
|
if (code.includes("/* [ecopages] hmr */")) {
|
|
160
210
|
return { success: true, requiresReload: !code.includes("import.meta.hot.accept") };
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* HMR strategy for server-rendered include templates and explicit server views.
|
|
3
|
+
*
|
|
4
|
+
* These files affect SSR output (head, layout shell, explicit views) but are not
|
|
5
|
+
* client HMR entrypoints. Broadcast a layout-update so the active navigation
|
|
6
|
+
* runtime can refresh the current page without a full document reload.
|
|
7
|
+
*/
|
|
8
|
+
import { HmrStrategy, type HmrAction } from '../hmr-strategy.js';
|
|
9
|
+
import type { DevelopmentInvalidationService } from '../../services/invalidation/development-invalidation.service.js';
|
|
10
|
+
export declare class ServerRenderedTemplateHmrStrategy extends HmrStrategy {
|
|
11
|
+
private readonly invalidationService;
|
|
12
|
+
readonly type: 100;
|
|
13
|
+
readonly priorityOffset = 50;
|
|
14
|
+
constructor(invalidationService: DevelopmentInvalidationService);
|
|
15
|
+
matches(filePath: string): boolean;
|
|
16
|
+
process(filePath: string): Promise<HmrAction>;
|
|
17
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { HmrStrategy, HmrStrategyType } from "../hmr-strategy.js";
|
|
2
|
+
const SERVER_RENDERED_TEMPLATE_PRIORITY_OFFSET = 50;
|
|
3
|
+
class ServerRenderedTemplateHmrStrategy extends HmrStrategy {
|
|
4
|
+
constructor(invalidationService) {
|
|
5
|
+
super();
|
|
6
|
+
this.invalidationService = invalidationService;
|
|
7
|
+
}
|
|
8
|
+
invalidationService;
|
|
9
|
+
type = HmrStrategyType.INTEGRATION;
|
|
10
|
+
priorityOffset = SERVER_RENDERED_TEMPLATE_PRIORITY_OFFSET;
|
|
11
|
+
matches(filePath) {
|
|
12
|
+
return this.invalidationService.isIncludeSourceFile(filePath) || this.invalidationService.isExplicitServerViewFile(filePath);
|
|
13
|
+
}
|
|
14
|
+
async process(filePath) {
|
|
15
|
+
return {
|
|
16
|
+
type: "broadcast",
|
|
17
|
+
events: [
|
|
18
|
+
{
|
|
19
|
+
type: "layout-update",
|
|
20
|
+
path: filePath,
|
|
21
|
+
timestamp: Date.now()
|
|
22
|
+
}
|
|
23
|
+
]
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
export {
|
|
28
|
+
ServerRenderedTemplateHmrStrategy
|
|
29
|
+
};
|
|
@@ -2,15 +2,11 @@
|
|
|
2
2
|
* This module contains the ghtml renderer
|
|
3
3
|
* @module
|
|
4
4
|
*/
|
|
5
|
-
import
|
|
6
|
-
import { IntegrationRenderer, type RenderToResponseContext } from '../../route-renderer/orchestration/integration-renderer.js';
|
|
5
|
+
import { StringMarkupRenderer } from '../../route-renderer/orchestration/string-markup-renderer.js';
|
|
7
6
|
/**
|
|
8
7
|
* A renderer for the ghtml integration.
|
|
9
8
|
* It renders a page using the HtmlTemplate and Page components.
|
|
10
9
|
*/
|
|
11
|
-
export declare class GhtmlRenderer extends
|
|
10
|
+
export declare class GhtmlRenderer extends StringMarkupRenderer {
|
|
12
11
|
name: string;
|
|
13
|
-
renderComponent(input: ComponentRenderInput): Promise<ComponentRenderResult>;
|
|
14
|
-
render({ params, query, props, locals, pageLocals, metadata, Page, Layout, HtmlTemplate, }: IntegrationRendererRenderOptions): Promise<RouteRendererBody>;
|
|
15
|
-
renderToResponse<P = Record<string, unknown>>(view: EcoComponent<P>, props: P, ctx: RenderToResponseContext): Promise<Response>;
|
|
16
12
|
}
|
|
@@ -1,56 +1,7 @@
|
|
|
1
|
-
import {
|
|
2
|
-
IntegrationRenderer
|
|
3
|
-
} from "../../route-renderer/orchestration/integration-renderer.js";
|
|
1
|
+
import { StringMarkupRenderer } from "../../route-renderer/orchestration/string-markup-renderer.js";
|
|
4
2
|
import { GHTML_PLUGIN_NAME } from "./ghtml.constants.js";
|
|
5
|
-
class GhtmlRenderer extends
|
|
3
|
+
class GhtmlRenderer extends StringMarkupRenderer {
|
|
6
4
|
name = GHTML_PLUGIN_NAME;
|
|
7
|
-
async renderComponent(input) {
|
|
8
|
-
return this.renderStringComponentWithQueuedForeignSubtrees(
|
|
9
|
-
input,
|
|
10
|
-
input.component
|
|
11
|
-
);
|
|
12
|
-
}
|
|
13
|
-
async render({
|
|
14
|
-
params,
|
|
15
|
-
query,
|
|
16
|
-
props,
|
|
17
|
-
locals,
|
|
18
|
-
pageLocals,
|
|
19
|
-
metadata,
|
|
20
|
-
Page,
|
|
21
|
-
Layout,
|
|
22
|
-
HtmlTemplate
|
|
23
|
-
}) {
|
|
24
|
-
try {
|
|
25
|
-
return await this.renderPageWithDocumentShell({
|
|
26
|
-
page: {
|
|
27
|
-
component: Page,
|
|
28
|
-
props: { params, query, ...props, locals: pageLocals }
|
|
29
|
-
},
|
|
30
|
-
layout: Layout ? {
|
|
31
|
-
component: Layout,
|
|
32
|
-
props: locals ? { locals } : {}
|
|
33
|
-
} : void 0,
|
|
34
|
-
htmlTemplate: HtmlTemplate,
|
|
35
|
-
metadata,
|
|
36
|
-
pageProps: props ?? {}
|
|
37
|
-
});
|
|
38
|
-
} catch (error) {
|
|
39
|
-
throw this.createRenderError("Error rendering page", error);
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
async renderToResponse(view, props, ctx) {
|
|
43
|
-
try {
|
|
44
|
-
return await this.renderViewWithDocumentShell({
|
|
45
|
-
view,
|
|
46
|
-
props,
|
|
47
|
-
ctx,
|
|
48
|
-
layout: view.config?.layout
|
|
49
|
-
});
|
|
50
|
-
} catch (error) {
|
|
51
|
-
throw this.createRenderError("Error rendering view", error);
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
5
|
}
|
|
55
6
|
export {
|
|
56
7
|
GhtmlRenderer
|
|
@@ -1,16 +1,3 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
* The Ghtml plugin class
|
|
5
|
-
* This plugin provides support for ghtml components in Ecopages
|
|
6
|
-
*/
|
|
7
|
-
export declare class GhtmlPlugin extends IntegrationPlugin {
|
|
8
|
-
renderer: typeof GhtmlRenderer;
|
|
9
|
-
constructor(options?: Omit<IntegrationPluginConfig, 'name'>);
|
|
10
|
-
}
|
|
11
|
-
/**
|
|
12
|
-
* Factory function to create a Ghtml plugin instance
|
|
13
|
-
* @param options Configuration options for the Ghtml plugin
|
|
14
|
-
* @returns A new GhtmlPlugin instance
|
|
15
|
-
*/
|
|
16
|
-
export declare function ghtmlPlugin(options?: Omit<IntegrationPluginConfig, 'name'>): GhtmlPlugin;
|
|
1
|
+
export declare const ghtmlPlugin: import("../../plugins/define-integration.js").DefinedIntegration<import("../../index.browser.js").EcoPagesElement>;
|
|
2
|
+
/** @deprecated Use {@link ghtmlPlugin.Plugin} or {@link ghtmlPlugin} instead. */
|
|
3
|
+
export declare const GhtmlPlugin: new (options?: Omit<import("../../plugins/integration-plugin.js").IntegrationPluginConfig, "name">) => import("../../plugins/integration-plugin.js").IntegrationPlugin<import("../../index.browser.js").EcoPagesElement>;
|
|
@@ -1,19 +1,12 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { defineIntegration } from "../../plugins/define-integration.js";
|
|
2
2
|
import { GhtmlRenderer } from "./ghtml-renderer.js";
|
|
3
3
|
import { GHTML_PLUGIN_NAME } from "./ghtml.constants.js";
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
...options
|
|
11
|
-
});
|
|
12
|
-
}
|
|
13
|
-
}
|
|
14
|
-
function ghtmlPlugin(options) {
|
|
15
|
-
return new GhtmlPlugin(options);
|
|
16
|
-
}
|
|
4
|
+
const ghtmlPlugin = defineIntegration({
|
|
5
|
+
name: GHTML_PLUGIN_NAME,
|
|
6
|
+
extensions: [".ghtml.ts", ".ghtml.tsx", ".ghtml"],
|
|
7
|
+
renderer: GhtmlRenderer
|
|
8
|
+
});
|
|
9
|
+
const GhtmlPlugin = ghtmlPlugin.Plugin;
|
|
17
10
|
export {
|
|
18
11
|
GhtmlPlugin,
|
|
19
12
|
ghtmlPlugin
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { EcoPagesAppConfig } from '../types/internal-types.js';
|
|
2
|
+
import type { AssetProcessingService } from '../services/assets/asset-processing-service/asset-processing.service.js';
|
|
3
|
+
import type { ProcessedAsset } from '../services/assets/asset-processing-service/assets.types.js';
|
|
4
|
+
import type { EcoPagesElement } from '../types/public-types.js';
|
|
5
|
+
import type { IntegrationRenderer } from '../route-renderer/orchestration/integration-renderer.js';
|
|
6
|
+
import { IntegrationPlugin, type IntegrationPluginConfig } from './integration-plugin.js';
|
|
7
|
+
type RendererClass<C> = new (options: {
|
|
8
|
+
appConfig: EcoPagesAppConfig;
|
|
9
|
+
assetProcessingService: AssetProcessingService;
|
|
10
|
+
resolvedIntegrationDependencies: ProcessedAsset[];
|
|
11
|
+
rendererModules?: unknown;
|
|
12
|
+
runtimeOrigin: string;
|
|
13
|
+
}) => IntegrationRenderer<C>;
|
|
14
|
+
export interface DefineIntegrationDefinition<C = EcoPagesElement> extends IntegrationPluginConfig {
|
|
15
|
+
renderer: RendererClass<C>;
|
|
16
|
+
}
|
|
17
|
+
export interface DefinedIntegration<C = EcoPagesElement> {
|
|
18
|
+
(options?: Omit<IntegrationPluginConfig, 'name'>): IntegrationPlugin<C>;
|
|
19
|
+
Plugin: new (options?: Omit<IntegrationPluginConfig, 'name'>) => IntegrationPlugin<C>;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Creates a typed integration plugin factory for integrations that only need
|
|
23
|
+
* declarative config and a renderer class.
|
|
24
|
+
*/
|
|
25
|
+
export declare function defineIntegration<C = EcoPagesElement>(definition: DefineIntegrationDefinition<C>): DefinedIntegration<C>;
|
|
26
|
+
export {};
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { IntegrationPlugin } from "./integration-plugin.js";
|
|
2
|
+
function defineIntegration(definition) {
|
|
3
|
+
const { renderer, ...defaultConfig } = definition;
|
|
4
|
+
class DefinedIntegrationPlugin extends IntegrationPlugin {
|
|
5
|
+
renderer = renderer;
|
|
6
|
+
constructor(options) {
|
|
7
|
+
super({
|
|
8
|
+
...defaultConfig,
|
|
9
|
+
...options
|
|
10
|
+
});
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
const factory = ((options) => new DefinedIntegrationPlugin(options));
|
|
14
|
+
factory.Plugin = DefinedIntegrationPlugin;
|
|
15
|
+
return factory;
|
|
16
|
+
}
|
|
17
|
+
export {
|
|
18
|
+
defineIntegration
|
|
19
|
+
};
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { cachedParseSync } from "../cache/module-parse-cache.js";
|
|
2
|
+
import { prependJsxImportSourceIfMissing } from "./jsx-import-source.utils.js";
|
|
2
3
|
import { rapidhash } from "../utils/hash.js";
|
|
3
4
|
import {
|
|
4
5
|
createEcoBuildPluginFromSourceTransform,
|
|
@@ -38,13 +39,6 @@ function detectIntegration(filePath, extensionToIntegration) {
|
|
|
38
39
|
}
|
|
39
40
|
return { name: "ghtml" };
|
|
40
41
|
}
|
|
41
|
-
function prependJsxImportSource(code, jsxImportSource) {
|
|
42
|
-
if (!jsxImportSource || code.includes("@jsxImportSource")) {
|
|
43
|
-
return code;
|
|
44
|
-
}
|
|
45
|
-
return `/** @jsxImportSource ${jsxImportSource} */
|
|
46
|
-
${code}`;
|
|
47
|
-
}
|
|
48
42
|
function createExtensionPattern(extensions) {
|
|
49
43
|
if (extensions.length === 0) {
|
|
50
44
|
throw new Error("[eco-component-meta-plugin] No extensions configured. At least one integration is required.");
|
|
@@ -67,7 +61,10 @@ function createEcoComponentMetaTransform(options) {
|
|
|
67
61
|
transform(code, id) {
|
|
68
62
|
const integration = detectIntegration(id, extensionToIntegration);
|
|
69
63
|
return {
|
|
70
|
-
code:
|
|
64
|
+
code: prependJsxImportSourceIfMissing(
|
|
65
|
+
injectEcoMeta(code, id, integration.name),
|
|
66
|
+
integration.jsxImportSource
|
|
67
|
+
)
|
|
71
68
|
};
|
|
72
69
|
}
|
|
73
70
|
};
|
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
import { readFileSync } from "node:fs";
|
|
2
2
|
import path from "node:path";
|
|
3
|
+
import { createJsxImportSourcePragma, filterJsxSourceExtensions } from "./jsx-import-source.utils.js";
|
|
3
4
|
function createForeignJsxOverridePlugin(options) {
|
|
4
|
-
const extensions = options.foreignExtensions
|
|
5
|
-
const excludedExtensions = (options.excludeExtensions ?? [])
|
|
6
|
-
(ext) => ext.endsWith(".tsx") || ext.endsWith(".jsx")
|
|
7
|
-
);
|
|
5
|
+
const extensions = filterJsxSourceExtensions(options.foreignExtensions);
|
|
6
|
+
const excludedExtensions = filterJsxSourceExtensions(options.excludeExtensions ?? []);
|
|
8
7
|
if (extensions.length === 0) {
|
|
9
8
|
return {
|
|
10
9
|
name: options.name ?? "foreign-jsx-override",
|
|
@@ -12,8 +11,7 @@ function createForeignJsxOverridePlugin(options) {
|
|
|
12
11
|
}
|
|
13
12
|
};
|
|
14
13
|
}
|
|
15
|
-
const pragma =
|
|
16
|
-
`;
|
|
14
|
+
const pragma = createJsxImportSourcePragma(options.hostJsxImportSource);
|
|
17
15
|
const filter = new RegExp(`(${extensions.map((e) => e.replace(".", "\\.")).join("|")})$`);
|
|
18
16
|
return {
|
|
19
17
|
name: options.name ?? "foreign-jsx-override",
|
|
@@ -6,10 +6,12 @@ import type { EcoPagesElement } from '../types/public-types.js';
|
|
|
6
6
|
import type { IntegrationRenderer } from '../route-renderer/orchestration/integration-renderer.js';
|
|
7
7
|
import { AssetProcessingService } from '../services/assets/asset-processing-service/asset-processing.service.js';
|
|
8
8
|
import type { AssetDefinition, ProcessedAsset } from '../services/assets/asset-processing-service/assets.types.js';
|
|
9
|
+
import type { StaticExportContext } from '../static-site-generator/static-export-context.js';
|
|
9
10
|
import type { RuntimeCapabilityDeclaration } from './runtime-capability.js';
|
|
10
11
|
export type { RuntimeCapabilityDeclaration, RuntimeCapabilityTag } from './runtime-capability.js';
|
|
11
12
|
export type { EcoBuildLoader, EcoBuildOnLoadArgs, EcoBuildOnLoadResult, EcoBuildOnResolveArgs, EcoBuildOnResolveResult, EcoBuildPlugin, EcoBuildPluginBuilder, } from '../build/build-types.js';
|
|
12
13
|
export type { PageBrowserGraphContribution, PageBrowserGraphContributionContext } from '../types/public-types.js';
|
|
14
|
+
export type { StaticExportContext } from '../static-site-generator/static-export-context.js';
|
|
13
15
|
export type { HtmlDocumentContribution, HtmlDocumentContributionContext, } from '../route-renderer/orchestration/integration-renderer.js';
|
|
14
16
|
/**
|
|
15
17
|
* Type-erased integration plugin stored in app-level registries.
|
|
@@ -47,13 +49,6 @@ export interface IntegrationPluginConfig {
|
|
|
47
49
|
* They are not specific to any particular page or component.
|
|
48
50
|
*/
|
|
49
51
|
integrationDependencies?: AssetDefinition[];
|
|
50
|
-
/**
|
|
51
|
-
* The strategy to use for static building.
|
|
52
|
-
* - 'render': Execute component function directly (faster, efficient).
|
|
53
|
-
* - 'fetch': Start server and fetch URL (slower, needed for some SSR like Lit).
|
|
54
|
-
* @default 'render'
|
|
55
|
-
*/
|
|
56
|
-
staticBuildStep?: 'render' | 'fetch';
|
|
57
52
|
/**
|
|
58
53
|
* Declares runtime-specific requirements that must be satisfied before the
|
|
59
54
|
* app can start with this integration enabled.
|
|
@@ -96,7 +91,6 @@ export declare abstract class IntegrationPlugin<C = EcoPagesElement> {
|
|
|
96
91
|
readonly name: string;
|
|
97
92
|
readonly extensions: string[];
|
|
98
93
|
abstract renderer: RendererClass<C>;
|
|
99
|
-
readonly staticBuildStep: 'render' | 'fetch';
|
|
100
94
|
readonly runtimeCapability?: RuntimeCapabilityDeclaration;
|
|
101
95
|
readonly jsxImportSource?: string;
|
|
102
96
|
protected integrationDependencies: AssetDefinition[];
|
|
@@ -199,7 +193,6 @@ export declare abstract class IntegrationPlugin<C = EcoPagesElement> {
|
|
|
199
193
|
* Renderers are cheap runtime objects. They receive the finalized app config,
|
|
200
194
|
* a fresh asset-processing service, integration-global processed assets, and
|
|
201
195
|
* any renderer module context supplied by the active runtime.
|
|
202
|
-
renderer.name ||= this.name;
|
|
203
196
|
*/
|
|
204
197
|
initializeRenderer(options?: {
|
|
205
198
|
rendererModules?: unknown;
|
|
@@ -213,6 +206,23 @@ export declare abstract class IntegrationPlugin<C = EcoPagesElement> {
|
|
|
213
206
|
* `setup()`.
|
|
214
207
|
*/
|
|
215
208
|
prepareBuildContributions(): Promise<void>;
|
|
209
|
+
/**
|
|
210
|
+
* Reports whether this integration's build inputs changed since the last
|
|
211
|
+
* incremental static build.
|
|
212
|
+
*/
|
|
213
|
+
didChange(): boolean;
|
|
214
|
+
/**
|
|
215
|
+
* Runs integration-specific setup before static page generation begins.
|
|
216
|
+
*
|
|
217
|
+
* @remarks
|
|
218
|
+
* Integrations that need build-scoped SSR preload or worker sessions should
|
|
219
|
+
* start them here rather than per-page inside the renderer.
|
|
220
|
+
*/
|
|
221
|
+
beforeStaticExport?(_context: StaticExportContext): Promise<void>;
|
|
222
|
+
/**
|
|
223
|
+
* Releases resources started in {@link beforeStaticExport}.
|
|
224
|
+
*/
|
|
225
|
+
afterStaticExport?(_context: StaticExportContext): Promise<void>;
|
|
216
226
|
/**
|
|
217
227
|
* Performs runtime-only integration setup after config build has already
|
|
218
228
|
* sealed manifest contributions.
|
|
@@ -15,7 +15,6 @@ function assertIntegrationInvariant(condition, message) {
|
|
|
15
15
|
class IntegrationPlugin {
|
|
16
16
|
name;
|
|
17
17
|
extensions;
|
|
18
|
-
staticBuildStep;
|
|
19
18
|
runtimeCapability;
|
|
20
19
|
jsxImportSource;
|
|
21
20
|
integrationDependencies;
|
|
@@ -60,7 +59,6 @@ class IntegrationPlugin {
|
|
|
60
59
|
this.name = config.name;
|
|
61
60
|
this.extensions = config.extensions;
|
|
62
61
|
this.integrationDependencies = config.integrationDependencies || [];
|
|
63
|
-
this.staticBuildStep = config.staticBuildStep || "render";
|
|
64
62
|
this.runtimeCapability = config.runtimeCapability;
|
|
65
63
|
this.jsxImportSource = config.jsxImportSource;
|
|
66
64
|
}
|
|
@@ -152,7 +150,6 @@ class IntegrationPlugin {
|
|
|
152
150
|
* Renderers are cheap runtime objects. They receive the finalized app config,
|
|
153
151
|
* a fresh asset-processing service, integration-global processed assets, and
|
|
154
152
|
* any renderer module context supplied by the active runtime.
|
|
155
|
-
renderer.name ||= this.name;
|
|
156
153
|
*/
|
|
157
154
|
initializeRenderer(options) {
|
|
158
155
|
const renderer = new this.renderer(this.createRendererOptions(options));
|
|
@@ -169,6 +166,13 @@ class IntegrationPlugin {
|
|
|
169
166
|
*/
|
|
170
167
|
async prepareBuildContributions() {
|
|
171
168
|
}
|
|
169
|
+
/**
|
|
170
|
+
* Reports whether this integration's build inputs changed since the last
|
|
171
|
+
* incremental static build.
|
|
172
|
+
*/
|
|
173
|
+
didChange() {
|
|
174
|
+
return false;
|
|
175
|
+
}
|
|
172
176
|
/**
|
|
173
177
|
* Performs runtime-only integration setup after config build has already
|
|
174
178
|
* sealed manifest contributions.
|
|
@@ -180,7 +184,6 @@ class IntegrationPlugin {
|
|
|
180
184
|
this.integrationDependencies,
|
|
181
185
|
this.name
|
|
182
186
|
);
|
|
183
|
-
this.initializeRenderer();
|
|
184
187
|
}
|
|
185
188
|
/**
|
|
186
189
|
* Releases runtime resources owned by the integration.
|