@ecopages/core 0.2.0-alpha.7 → 0.2.0-alpha.8
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/CHANGELOG.md +31 -0
- package/package.json +212 -92
- package/src/adapters/abstract/application-adapter.d.ts +168 -0
- package/src/adapters/abstract/application-adapter.js +109 -0
- package/src/adapters/abstract/router-adapter.d.ts +26 -0
- package/src/adapters/abstract/router-adapter.js +5 -0
- package/src/adapters/abstract/server-adapter.d.ts +69 -0
- package/src/adapters/abstract/server-adapter.js +15 -0
- package/src/adapters/bun/client-bridge.d.ts +34 -0
- package/src/adapters/bun/client-bridge.js +48 -0
- package/src/adapters/bun/create-app.d.ts +60 -0
- package/src/adapters/bun/create-app.js +117 -0
- package/src/adapters/bun/hmr-manager.d.ts +143 -0
- package/src/adapters/bun/hmr-manager.js +334 -0
- package/src/adapters/bun/index.d.ts +2 -0
- package/src/adapters/bun/index.js +8 -0
- package/src/adapters/bun/server-adapter.d.ts +155 -0
- package/src/adapters/bun/server-adapter.js +373 -0
- package/src/adapters/bun/server-lifecycle.d.ts +63 -0
- package/src/adapters/bun/server-lifecycle.js +92 -0
- package/src/adapters/index.d.ts +6 -0
- package/src/adapters/index.js +14 -0
- package/src/adapters/node/bootstrap-dependency-resolver.d.ts +44 -0
- package/src/adapters/node/bootstrap-dependency-resolver.js +172 -0
- package/src/adapters/node/create-app.d.ts +21 -0
- package/src/adapters/node/create-app.js +143 -0
- package/src/adapters/node/index.d.ts +6 -0
- package/src/adapters/node/index.js +11 -0
- package/src/adapters/node/node-client-bridge.d.ts +26 -0
- package/src/adapters/node/node-client-bridge.js +66 -0
- package/src/adapters/node/node-hmr-manager.d.ts +133 -0
- package/src/adapters/node/node-hmr-manager.js +312 -0
- package/src/adapters/node/runtime-adapter.d.ts +46 -0
- package/src/adapters/node/runtime-adapter.js +306 -0
- package/src/adapters/node/server-adapter.d.ts +161 -0
- package/src/adapters/node/server-adapter.js +358 -0
- package/src/adapters/node/static-content-server.d.ts +60 -0
- package/src/adapters/node/static-content-server.js +194 -0
- package/src/adapters/node/write-runtime-manifest.d.ts +26 -0
- package/src/adapters/node/write-runtime-manifest.js +12 -0
- package/src/adapters/shared/api-response.d.ts +52 -0
- package/src/adapters/shared/api-response.js +96 -0
- package/src/adapters/shared/application-adapter.d.ts +18 -0
- package/src/adapters/shared/application-adapter.js +90 -0
- package/src/adapters/shared/define-api-handler.d.ts +25 -0
- package/src/adapters/shared/define-api-handler.js +15 -0
- package/src/adapters/shared/explicit-static-route-matcher.d.ts +38 -0
- package/src/adapters/shared/explicit-static-route-matcher.js +103 -0
- package/src/adapters/shared/file-route-middleware-pipeline.d.ts +65 -0
- package/src/adapters/shared/file-route-middleware-pipeline.js +99 -0
- package/src/adapters/shared/fs-server-response-factory.d.ts +19 -0
- package/src/adapters/shared/fs-server-response-factory.js +97 -0
- package/src/adapters/shared/fs-server-response-matcher.d.ts +75 -0
- package/src/adapters/shared/fs-server-response-matcher.js +160 -0
- package/src/adapters/shared/hmr-entrypoint-registrar.d.ts +55 -0
- package/src/adapters/shared/hmr-entrypoint-registrar.js +87 -0
- package/src/adapters/shared/hmr-html-response.d.ts +22 -0
- package/src/adapters/shared/hmr-html-response.js +32 -0
- package/src/adapters/shared/render-context.d.ts +14 -0
- package/src/adapters/shared/render-context.js +70 -0
- package/src/adapters/shared/runtime-bootstrap.d.ts +38 -0
- package/src/adapters/shared/runtime-bootstrap.js +43 -0
- package/src/adapters/shared/server-adapter.d.ts +97 -0
- package/src/adapters/shared/server-adapter.js +386 -0
- package/src/adapters/shared/server-route-handler.d.ts +89 -0
- package/src/adapters/shared/server-route-handler.js +111 -0
- package/src/adapters/shared/server-static-builder.d.ts +70 -0
- package/src/adapters/shared/server-static-builder.js +99 -0
- package/src/build/build-adapter.d.ts +186 -0
- package/src/build/build-adapter.js +168 -0
- package/src/build/build-manifest.d.ts +27 -0
- package/src/build/build-manifest.js +30 -0
- package/src/build/build-types.d.ts +57 -0
- package/src/build/build-types.js +0 -0
- package/src/build/dev-build-coordinator.d.ts +74 -0
- package/src/build/dev-build-coordinator.js +161 -0
- package/src/build/esbuild-build-adapter.d.ts +72 -0
- package/src/build/esbuild-build-adapter.js +422 -0
- package/src/build/runtime-build-executor.d.ts +13 -0
- package/src/build/runtime-build-executor.js +20 -0
- package/src/build/runtime-specifier-alias-plugin.d.ts +15 -0
- package/src/build/runtime-specifier-alias-plugin.js +31 -0
- package/src/config/config-builder.d.ts +238 -0
- package/src/config/config-builder.js +565 -0
- package/src/constants.d.ts +45 -0
- package/src/constants.js +25 -0
- package/src/create-app.d.ts +17 -0
- package/src/create-app.js +66 -0
- package/src/dev/sc-server.d.ts +30 -0
- package/src/dev/sc-server.js +111 -0
- package/src/eco/component-render-context.d.ts +105 -0
- package/src/eco/component-render-context.js +87 -0
- package/src/eco/eco.d.ts +9 -0
- package/src/eco/eco.js +114 -0
- package/src/eco/eco.types.d.ts +178 -0
- package/src/eco/eco.types.js +0 -0
- package/src/eco/eco.utils.d.ts +40 -0
- package/src/eco/eco.utils.js +40 -0
- package/src/eco/global-injector-map.d.ts +16 -0
- package/src/eco/global-injector-map.js +80 -0
- package/src/eco/lazy-injector-map.d.ts +8 -0
- package/src/eco/lazy-injector-map.js +70 -0
- package/src/eco/module-dependencies.d.ts +18 -0
- package/src/eco/module-dependencies.js +49 -0
- package/src/errors/http-error.d.ts +31 -0
- package/src/errors/http-error.js +50 -0
- package/src/errors/index.d.ts +2 -0
- package/src/errors/index.js +4 -0
- package/src/errors/locals-access-error.d.ts +4 -0
- package/src/errors/locals-access-error.js +9 -0
- package/src/global/app-logger.d.ts +2 -0
- package/src/global/app-logger.js +6 -0
- package/src/hmr/client/hmr-runtime.d.ts +5 -0
- package/src/hmr/client/hmr-runtime.js +109 -0
- package/src/hmr/hmr-strategy.d.ts +159 -0
- package/src/hmr/hmr-strategy.js +29 -0
- package/src/hmr/hmr.postcss.test.e2e.d.ts +1 -0
- package/src/hmr/hmr.postcss.test.e2e.js +31 -0
- package/src/hmr/hmr.test.e2e.d.ts +1 -0
- package/src/hmr/hmr.test.e2e.js +43 -0
- package/src/hmr/strategies/default-hmr-strategy.d.ts +43 -0
- package/src/hmr/strategies/default-hmr-strategy.js +34 -0
- package/src/hmr/strategies/js-hmr-strategy.d.ts +139 -0
- package/src/hmr/strategies/js-hmr-strategy.js +178 -0
- package/src/index.browser.d.ts +3 -0
- package/src/index.browser.js +4 -0
- package/src/index.d.ts +5 -0
- package/src/index.js +10 -0
- package/src/integrations/ghtml/ghtml-renderer.d.ts +15 -0
- package/src/integrations/ghtml/ghtml-renderer.js +62 -0
- package/src/integrations/ghtml/ghtml.plugin.d.ts +20 -0
- package/src/integrations/ghtml/ghtml.plugin.js +21 -0
- package/src/internal-types.d.ts +221 -0
- package/src/internal-types.js +0 -0
- package/src/plugins/alias-resolver-plugin.d.ts +2 -0
- package/src/plugins/alias-resolver-plugin.js +53 -0
- package/src/plugins/eco-component-meta-plugin.d.ts +97 -0
- package/src/plugins/eco-component-meta-plugin.js +157 -0
- package/src/plugins/integration-plugin.d.ts +136 -0
- package/src/plugins/integration-plugin.js +133 -0
- package/src/plugins/processor.d.ts +95 -0
- package/src/plugins/processor.js +136 -0
- package/src/plugins/runtime-capability.d.ts +9 -0
- package/src/plugins/runtime-capability.js +0 -0
- package/src/public-types.d.ts +1149 -0
- package/src/public-types.js +0 -0
- package/src/route-renderer/component-graph/component-graph-executor.d.ts +32 -0
- package/src/route-renderer/component-graph/component-graph-executor.js +31 -0
- package/src/route-renderer/component-graph/component-graph.d.ts +42 -0
- package/src/route-renderer/component-graph/component-graph.js +72 -0
- package/src/route-renderer/component-graph/component-marker.d.ts +52 -0
- package/src/route-renderer/component-graph/component-marker.js +46 -0
- package/src/route-renderer/component-graph/component-reference.d.ts +10 -0
- package/src/route-renderer/component-graph/component-reference.js +19 -0
- package/src/route-renderer/component-graph/marker-graph-resolver.d.ts +77 -0
- package/src/route-renderer/component-graph/marker-graph-resolver.js +95 -0
- package/src/route-renderer/orchestration/integration-renderer.d.ts +372 -0
- package/src/route-renderer/orchestration/integration-renderer.js +589 -0
- package/src/route-renderer/orchestration/render-execution.service.d.ts +103 -0
- package/src/route-renderer/orchestration/render-execution.service.js +121 -0
- package/src/route-renderer/orchestration/render-preparation.service.d.ts +121 -0
- package/src/route-renderer/orchestration/render-preparation.service.js +332 -0
- package/src/route-renderer/page-loading/dependency-resolver.d.ts +35 -0
- package/src/route-renderer/page-loading/dependency-resolver.js +442 -0
- package/src/route-renderer/page-loading/page-module-loader.d.ts +87 -0
- package/src/route-renderer/page-loading/page-module-loader.js +124 -0
- package/src/route-renderer/route-renderer.d.ts +61 -0
- package/src/route-renderer/route-renderer.js +87 -0
- package/src/router/client/link-intent.js +34 -0
- package/src/router/client/link-intent.test.browser.d.ts +1 -0
- package/src/router/client/link-intent.test.browser.js +43 -0
- package/src/router/client/navigation-coordinator.d.ts +149 -0
- package/src/router/client/navigation-coordinator.js +215 -0
- package/src/router/server/fs-router-scanner.d.ts +41 -0
- package/src/router/server/fs-router-scanner.js +156 -0
- package/src/router/server/fs-router.d.ts +26 -0
- package/src/router/server/fs-router.js +100 -0
- package/src/services/assets/asset-processing-service/asset-processing.service.d.ts +120 -0
- package/src/services/assets/asset-processing-service/asset-processing.service.js +331 -0
- package/src/services/assets/asset-processing-service/asset.factory.d.ts +17 -0
- package/src/services/assets/asset-processing-service/asset.factory.js +82 -0
- package/src/services/assets/asset-processing-service/assets.types.d.ts +89 -0
- package/src/services/assets/asset-processing-service/assets.types.js +0 -0
- package/src/services/assets/asset-processing-service/browser-runtime-asset.factory.d.ts +55 -0
- package/src/services/assets/asset-processing-service/browser-runtime-asset.factory.js +48 -0
- package/src/services/assets/asset-processing-service/browser-runtime-entry.factory.d.ts +20 -0
- package/src/services/assets/asset-processing-service/browser-runtime-entry.factory.js +41 -0
- package/src/services/assets/asset-processing-service/index.d.ts +5 -0
- package/src/services/assets/asset-processing-service/index.js +5 -0
- package/src/services/assets/asset-processing-service/processor.interface.d.ts +22 -0
- package/src/services/assets/asset-processing-service/processor.interface.js +6 -0
- package/src/services/assets/asset-processing-service/processor.registry.d.ts +8 -0
- package/src/services/assets/asset-processing-service/processor.registry.js +15 -0
- package/src/services/assets/asset-processing-service/processors/base/base-processor.d.ts +24 -0
- package/src/services/assets/asset-processing-service/processors/base/base-processor.js +64 -0
- package/src/services/assets/asset-processing-service/processors/base/base-script-processor.d.ts +17 -0
- package/src/services/assets/asset-processing-service/processors/base/base-script-processor.js +72 -0
- package/src/services/assets/asset-processing-service/processors/index.d.ts +5 -0
- package/src/services/assets/asset-processing-service/processors/index.js +5 -0
- package/src/services/assets/asset-processing-service/processors/script/content-script.processor.d.ts +5 -0
- package/src/services/assets/asset-processing-service/processors/script/content-script.processor.js +57 -0
- package/src/services/assets/asset-processing-service/processors/script/file-script.processor.d.ts +8 -0
- package/src/services/assets/asset-processing-service/processors/script/file-script.processor.js +76 -0
- package/src/services/assets/asset-processing-service/processors/script/node-module-script.processor.d.ts +7 -0
- package/src/services/assets/asset-processing-service/processors/script/node-module-script.processor.js +75 -0
- package/src/services/assets/asset-processing-service/processors/stylesheet/content-stylesheet.processor.d.ts +5 -0
- package/src/services/assets/asset-processing-service/processors/stylesheet/content-stylesheet.processor.js +25 -0
- package/src/services/assets/asset-processing-service/processors/stylesheet/file-stylesheet.processor.d.ts +9 -0
- package/src/services/assets/asset-processing-service/processors/stylesheet/file-stylesheet.processor.js +66 -0
- package/src/services/assets/browser-bundle.service.d.ts +32 -0
- package/src/services/assets/browser-bundle.service.js +33 -0
- package/src/services/cache/cache.types.d.ts +107 -0
- package/src/services/cache/cache.types.js +0 -0
- package/src/services/cache/index.d.ts +7 -0
- package/src/services/cache/index.js +7 -0
- package/src/services/cache/memory-cache-store.d.ts +42 -0
- package/src/services/cache/memory-cache-store.js +98 -0
- package/src/services/cache/page-cache-service.d.ts +70 -0
- package/src/services/cache/page-cache-service.js +152 -0
- package/src/services/cache/page-request-cache-coordinator.service.d.ts +75 -0
- package/src/services/cache/page-request-cache-coordinator.service.js +109 -0
- package/src/services/html/html-rewriter-provider.service.d.ts +37 -0
- package/src/services/html/html-rewriter-provider.service.js +65 -0
- package/src/services/html/html-transformer.service.d.ts +77 -0
- package/src/services/html/html-transformer.service.js +221 -0
- package/src/services/invalidation/development-invalidation.service.d.ts +74 -0
- package/src/services/invalidation/development-invalidation.service.js +189 -0
- package/src/services/module-loading/app-server-module-transpiler.service.d.ts +16 -0
- package/src/services/module-loading/app-server-module-transpiler.service.js +34 -0
- package/src/services/module-loading/page-module-import.service.d.ts +71 -0
- package/src/services/module-loading/page-module-import.service.js +132 -0
- package/src/services/module-loading/server-loader.service.d.ts +96 -0
- package/src/services/module-loading/server-loader.service.js +32 -0
- package/src/services/module-loading/server-module-transpiler.service.d.ts +69 -0
- package/src/services/module-loading/server-module-transpiler.service.js +61 -0
- package/src/services/runtime-manifest/node-runtime-manifest.service.d.ts +35 -0
- package/src/services/runtime-manifest/node-runtime-manifest.service.js +60 -0
- package/src/services/runtime-state/dev-graph.service.d.ts +118 -0
- package/src/services/runtime-state/dev-graph.service.js +162 -0
- package/src/services/runtime-state/entrypoint-dependency-graph.service.d.ts +41 -0
- package/src/services/runtime-state/entrypoint-dependency-graph.service.js +85 -0
- package/src/services/runtime-state/runtime-specifier-registry.service.d.ts +69 -0
- package/src/services/runtime-state/runtime-specifier-registry.service.js +37 -0
- package/src/services/runtime-state/server-invalidation-state.service.d.ts +26 -0
- package/src/services/runtime-state/server-invalidation-state.service.js +35 -0
- package/src/services/validation/schema-validation-service.d.ts +122 -0
- package/src/services/validation/schema-validation-service.js +101 -0
- package/src/services/validation/standard-schema.types.d.ts +65 -0
- package/src/services/validation/standard-schema.types.js +0 -0
- package/src/static-site-generator/static-site-generator.d.ts +109 -0
- package/src/static-site-generator/static-site-generator.js +353 -0
- package/src/utils/css.d.ts +1 -0
- package/src/utils/css.js +7 -0
- package/src/utils/deep-merge.d.ts +14 -0
- package/src/utils/deep-merge.js +32 -0
- package/src/utils/hash.d.ts +1 -0
- package/src/utils/hash.js +7 -0
- package/src/utils/html.d.ts +1 -0
- package/src/utils/html.js +4 -0
- package/src/utils/invariant.d.ts +5 -0
- package/src/utils/invariant.js +11 -0
- package/src/utils/locals-utils.d.ts +15 -0
- package/src/utils/locals-utils.js +24 -0
- package/src/utils/parse-cli-args.d.ts +24 -0
- package/src/utils/parse-cli-args.js +47 -0
- package/src/utils/path-utils.module.d.ts +5 -0
- package/src/utils/path-utils.module.js +14 -0
- package/src/utils/resolve-work-dir.d.ts +11 -0
- package/src/utils/resolve-work-dir.js +31 -0
- package/src/utils/runtime.d.ts +11 -0
- package/src/utils/runtime.js +40 -0
- package/src/utils/server-utils.module.d.ts +19 -0
- package/src/utils/server-utils.module.js +56 -0
- package/src/watchers/project-watcher.d.ts +136 -0
- package/src/watchers/project-watcher.js +281 -0
- package/src/watchers/project-watcher.test-helpers.d.ts +4 -0
- package/src/watchers/project-watcher.test-helpers.js +52 -0
- package/src/adapters/bun/hmr-manager.test.ts +0 -267
- package/src/adapters/node/bootstrap-dependency-resolver.test.ts +0 -282
- package/src/adapters/node/node-client-bridge.test.ts +0 -198
- package/src/adapters/node/node-hmr-manager.test.ts +0 -322
- package/src/adapters/node/runtime-adapter.test.ts +0 -868
- package/src/adapters/node/static-content-server.test.ts +0 -60
- package/src/adapters/shared/api-response.test.ts +0 -97
- package/src/adapters/shared/explicit-static-route-matcher.test.ts +0 -381
- package/src/adapters/shared/file-route-middleware-pipeline.test.ts +0 -90
- package/src/adapters/shared/fs-server-response-factory.test.ts +0 -187
- package/src/adapters/shared/fs-server-response-matcher.test.ts +0 -286
- package/src/adapters/shared/hmr-manager.contract.test.ts +0 -196
- package/src/adapters/shared/hmr-manager.dispatch.test.ts +0 -220
- package/src/adapters/shared/render-context.test.ts +0 -146
- package/src/adapters/shared/server-adapter.test.ts +0 -77
- package/src/adapters/shared/server-route-handler.test.ts +0 -110
- package/src/adapters/shared/server-static-builder.test.ts +0 -316
- package/src/build/build-adapter-serialization.test.ts +0 -268
- package/src/build/build-adapter.test.ts +0 -815
- package/src/build/runtime-specifier-alias-plugin.test.ts +0 -43
- package/src/config/config-builder.test.ts +0 -410
- package/src/eco/eco.test.ts +0 -678
- package/src/eco/eco.utils.test.ts +0 -124
- package/src/eco/global-injector-map.test.ts +0 -42
- package/src/eco/lazy-injector-map.test.ts +0 -66
- package/src/eco/module-dependencies.test.ts +0 -30
- package/src/errors/http-error.test.ts +0 -134
- package/src/global/utils.test.ts +0 -12
- package/src/hmr/client/__screenshots__/hmr-runtime.test.browser.ts/HMR-Runtime-HMR-Server-Integration-should-have-HMR-script-injected-in-page-1.png +0 -0
- package/src/hmr/client/__screenshots__/hmr-runtime.test.browser.ts/HMR-Runtime-HMR-Server-Integration-should-load-fixture-app-page-1.png +0 -0
- package/src/hmr/client/__screenshots__/hmr-runtime.test.browser.ts/HMR-Runtime-WebSocket-Connection-should-connect-to-correct-HMR-endpoint-1.png +0 -0
- package/src/hmr/hmr-strategy.test.ts +0 -124
- package/src/hmr/strategies/js-hmr-strategy.test.ts +0 -335
- package/src/integrations/ghtml/ghtml-renderer.test.ts +0 -63
- package/src/plugins/alias-resolver-plugin.test.ts +0 -41
- package/src/plugins/eco-component-meta-plugin.test.ts +0 -380
- package/src/plugins/integration-plugin.test.ts +0 -111
- package/src/plugins/processor.test.ts +0 -148
- package/src/route-renderer/component-graph/component-graph-executor.test.ts +0 -41
- package/src/route-renderer/component-graph/component-graph.test.ts +0 -63
- package/src/route-renderer/component-graph/component-marker.test.ts +0 -73
- package/src/route-renderer/component-graph/marker-graph-resolver.test.ts +0 -135
- package/src/route-renderer/orchestration/integration-renderer.test.ts +0 -936
- package/src/route-renderer/orchestration/render-execution.service.test.ts +0 -97
- package/src/route-renderer/orchestration/render-preparation.service.test.ts +0 -235
- package/src/route-renderer/page-loading/dependency-resolver.test.ts +0 -345
- package/src/route-renderer/page-loading/page-module-loader.test.ts +0 -96
- package/src/router/client/navigation-coordinator.test.ts +0 -237
- package/src/router/server/fs-router-scanner.test.ts +0 -83
- package/src/router/server/fs-router.test.ts +0 -214
- package/src/services/assets/asset-processing-service/asset-processing.service.test.ts +0 -385
- package/src/services/assets/asset-processing-service/asset.factory.test.ts +0 -63
- package/src/services/assets/asset-processing-service/browser-runtime-asset.factory.test.ts +0 -72
- package/src/services/assets/asset-processing-service/browser-runtime-entry.factory.test.ts +0 -67
- package/src/services/assets/asset-processing-service/processors/base/base-processor.test.ts +0 -59
- package/src/services/assets/asset-processing-service/processors/script/file-script.processor.test.ts +0 -286
- package/src/services/assets/asset-processing-service/processors/script/node-module-script.processor.test.ts +0 -227
- package/src/services/assets/asset-processing-service/processors/stylesheet/content-stylesheet.processor.test.ts +0 -199
- package/src/services/assets/browser-bundle.service.test.ts +0 -36
- package/src/services/cache/memory-cache-store.test.ts +0 -225
- package/src/services/cache/page-cache-service.test.ts +0 -175
- package/src/services/cache/page-request-cache-coordinator.service.test.ts +0 -79
- package/src/services/html/html-rewriter-provider.service.test.ts +0 -183
- package/src/services/html/html-transformer.service.test.ts +0 -378
- package/src/services/invalidation/development-invalidation.service.test.ts +0 -77
- package/src/services/module-loading/page-module-import.service.test.ts +0 -253
- package/src/services/module-loading/server-loader.service.test.ts +0 -161
- package/src/services/module-loading/server-module-transpiler.service.test.ts +0 -115
- package/src/services/runtime-manifest/node-runtime-manifest.service.test.ts +0 -95
- package/src/services/validation/schema-validation-service.test.ts +0 -223
- package/src/static-site-generator/static-site-generator.test.ts +0 -307
- package/src/utils/deep-merge.test.ts +0 -114
- package/src/utils/invariant.test.ts +0 -22
- package/src/utils/path-utils.test.ts +0 -15
- package/src/utils/server-utils.test.ts +0 -38
- package/src/watchers/project-watcher.integration.test.ts +0 -337
- package/src/watchers/project-watcher.test.ts +0 -678
|
@@ -0,0 +1,312 @@
|
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { RESOLVED_ASSETS_DIR } from "../../constants.js";
|
|
4
|
+
import { getAppBuildExecutor } from "../../build/build-adapter.js";
|
|
5
|
+
import { fileSystem } from "@ecopages/file-system";
|
|
6
|
+
import { HmrStrategyType } from "../../hmr/hmr-strategy.js";
|
|
7
|
+
import { DefaultHmrStrategy } from "../../hmr/strategies/default-hmr-strategy.js";
|
|
8
|
+
import { JsHmrStrategy } from "../../hmr/strategies/js-hmr-strategy.js";
|
|
9
|
+
import { appLogger } from "../../global/app-logger.js";
|
|
10
|
+
import { HmrEntrypointRegistrar } from "../shared/hmr-entrypoint-registrar.js";
|
|
11
|
+
import { BrowserBundleService } from "../../services/assets/browser-bundle.service.js";
|
|
12
|
+
import { getAppServerModuleTranspiler } from "../../services/module-loading/app-server-module-transpiler.service.js";
|
|
13
|
+
import {
|
|
14
|
+
getAppEntrypointDependencyGraph,
|
|
15
|
+
InMemoryEntrypointDependencyGraph,
|
|
16
|
+
setAppEntrypointDependencyGraph
|
|
17
|
+
} from "../../services/runtime-state/entrypoint-dependency-graph.service.js";
|
|
18
|
+
import { getAppRuntimeSpecifierRegistry } from "../../services/runtime-state/runtime-specifier-registry.service.js";
|
|
19
|
+
import { resolveInternalExecutionDir, resolveInternalWorkDir } from "../../utils/resolve-work-dir.js";
|
|
20
|
+
class NodeHmrManager {
|
|
21
|
+
static entrypointRegistrationTimeoutMs = 4e3;
|
|
22
|
+
appConfig;
|
|
23
|
+
bridge;
|
|
24
|
+
watchers = /* @__PURE__ */ new Map();
|
|
25
|
+
watchedFiles = /* @__PURE__ */ new Map();
|
|
26
|
+
entrypointRegistrations = /* @__PURE__ */ new Map();
|
|
27
|
+
distDir;
|
|
28
|
+
plugins = [];
|
|
29
|
+
enabled = true;
|
|
30
|
+
strategies = [];
|
|
31
|
+
entrypointRegistrar;
|
|
32
|
+
browserBundleService;
|
|
33
|
+
entrypointDependencyGraph;
|
|
34
|
+
runtimeSpecifierRegistry;
|
|
35
|
+
serverModuleTranspiler;
|
|
36
|
+
constructor({ appConfig, bridge }) {
|
|
37
|
+
this.appConfig = appConfig;
|
|
38
|
+
this.bridge = bridge;
|
|
39
|
+
this.distDir = path.join(resolveInternalWorkDir(this.appConfig), RESOLVED_ASSETS_DIR, "_hmr");
|
|
40
|
+
this.entrypointRegistrar = new HmrEntrypointRegistrar({
|
|
41
|
+
srcDir: this.appConfig.absolutePaths.srcDir,
|
|
42
|
+
distDir: this.distDir,
|
|
43
|
+
entrypointRegistrations: this.entrypointRegistrations,
|
|
44
|
+
watchedFiles: this.watchedFiles,
|
|
45
|
+
clearFailedRegistration: (entrypointPath) => this.clearFailedEntrypointRegistration(entrypointPath),
|
|
46
|
+
registrationTimeoutMs: NodeHmrManager.entrypointRegistrationTimeoutMs
|
|
47
|
+
});
|
|
48
|
+
this.browserBundleService = new BrowserBundleService(appConfig);
|
|
49
|
+
const existingEntrypointDependencyGraph = getAppEntrypointDependencyGraph(appConfig);
|
|
50
|
+
this.entrypointDependencyGraph = existingEntrypointDependencyGraph instanceof InMemoryEntrypointDependencyGraph ? existingEntrypointDependencyGraph : new InMemoryEntrypointDependencyGraph();
|
|
51
|
+
setAppEntrypointDependencyGraph(this.appConfig, this.entrypointDependencyGraph);
|
|
52
|
+
this.runtimeSpecifierRegistry = getAppRuntimeSpecifierRegistry(this.appConfig);
|
|
53
|
+
this.serverModuleTranspiler = getAppServerModuleTranspiler(this.appConfig);
|
|
54
|
+
this.cleanDistDir();
|
|
55
|
+
this.initializeStrategies();
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Ensures the HMR output directory exists.
|
|
59
|
+
*
|
|
60
|
+
* This must not remove the directory because multiple app processes
|
|
61
|
+
* can share the same dist path during e2e runs.
|
|
62
|
+
*/
|
|
63
|
+
cleanDistDir() {
|
|
64
|
+
fileSystem.ensureDir(this.distDir);
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Returns whether the generic JS strategy is allowed to rebuild an entrypoint.
|
|
68
|
+
*
|
|
69
|
+
* @remarks
|
|
70
|
+
* Higher-priority integration strategies own framework page entrypoints. When
|
|
71
|
+
* one of them matches, the generic JS strategy must stay out of the way so a
|
|
72
|
+
* shared dependency invalidation does not overwrite framework-specific output.
|
|
73
|
+
*/
|
|
74
|
+
shouldJsStrategyProcessEntrypoint(entrypointPath) {
|
|
75
|
+
return !this.strategies.some((strategy) => {
|
|
76
|
+
if (strategy.type !== HmrStrategyType.INTEGRATION || strategy.priority <= HmrStrategyType.SCRIPT) {
|
|
77
|
+
return false;
|
|
78
|
+
}
|
|
79
|
+
try {
|
|
80
|
+
return strategy.matches(entrypointPath);
|
|
81
|
+
} catch (error) {
|
|
82
|
+
appLogger.error(error);
|
|
83
|
+
return false;
|
|
84
|
+
}
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
initializeStrategies() {
|
|
88
|
+
const jsContext = {
|
|
89
|
+
getWatchedFiles: () => this.watchedFiles,
|
|
90
|
+
getSpecifierMap: () => this.runtimeSpecifierRegistry.getAll(),
|
|
91
|
+
getDistDir: () => this.distDir,
|
|
92
|
+
getPlugins: () => this.plugins,
|
|
93
|
+
getSrcDir: () => this.appConfig.absolutePaths.srcDir,
|
|
94
|
+
getPagesDir: () => this.appConfig.absolutePaths.pagesDir,
|
|
95
|
+
getLayoutsDir: () => this.appConfig.absolutePaths.layoutsDir,
|
|
96
|
+
getTemplateExtensions: () => this.appConfig.templatesExt,
|
|
97
|
+
getBrowserBundleService: () => this.browserBundleService,
|
|
98
|
+
getEntrypointDependencyGraph: () => this.entrypointDependencyGraph,
|
|
99
|
+
shouldProcessEntrypoint: (entrypointPath) => this.shouldJsStrategyProcessEntrypoint(entrypointPath)
|
|
100
|
+
};
|
|
101
|
+
this.strategies = [new JsHmrStrategy(jsContext), new DefaultHmrStrategy()];
|
|
102
|
+
}
|
|
103
|
+
registerStrategy(strategy) {
|
|
104
|
+
this.strategies.push(strategy);
|
|
105
|
+
}
|
|
106
|
+
setPlugins(plugins) {
|
|
107
|
+
this.plugins = [...plugins];
|
|
108
|
+
}
|
|
109
|
+
setEnabled(enabled) {
|
|
110
|
+
this.enabled = enabled;
|
|
111
|
+
}
|
|
112
|
+
isEnabled() {
|
|
113
|
+
return this.enabled;
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Registers runtime bare-specifier mappings exposed by integrations.
|
|
117
|
+
*
|
|
118
|
+
* @remarks
|
|
119
|
+
* These mappings are consumed by framework-owned HMR strategies such as the
|
|
120
|
+
* React integration strategy when they rewrite browser bundles. The registry
|
|
121
|
+
* stays generic so the same mappings can support broader import-map-style
|
|
122
|
+
* runtime features later without moving integration semantics into core.
|
|
123
|
+
*/
|
|
124
|
+
registerSpecifierMap(map) {
|
|
125
|
+
this.runtimeSpecifierRegistry.register(map);
|
|
126
|
+
}
|
|
127
|
+
async buildRuntime() {
|
|
128
|
+
const runtimeSource = path.resolve(import.meta.dirname, "../../hmr/client/hmr-runtime.js");
|
|
129
|
+
try {
|
|
130
|
+
const result = await this.browserBundleService.bundle({
|
|
131
|
+
profile: "hmr-runtime",
|
|
132
|
+
entrypoints: [runtimeSource],
|
|
133
|
+
outdir: this.distDir,
|
|
134
|
+
naming: "_hmr_runtime.js",
|
|
135
|
+
minify: false,
|
|
136
|
+
plugins: this.plugins
|
|
137
|
+
});
|
|
138
|
+
if (!result.success) {
|
|
139
|
+
this.enabled = false;
|
|
140
|
+
appLogger.error("[HMR] Failed to build runtime script; continuing with HMR disabled.", result.logs);
|
|
141
|
+
}
|
|
142
|
+
} catch (error) {
|
|
143
|
+
this.enabled = false;
|
|
144
|
+
appLogger.error("[HMR] Failed to build runtime script; continuing with HMR disabled.", error);
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
getRuntimePath() {
|
|
148
|
+
return path.join(this.distDir, "_hmr_runtime.js");
|
|
149
|
+
}
|
|
150
|
+
broadcast(event) {
|
|
151
|
+
appLogger.debug(
|
|
152
|
+
`[HMR] Broadcasting ${event.type} event, path=${event.path || "all"}, subscribers=${this.bridge.subscriberCount}`
|
|
153
|
+
);
|
|
154
|
+
this.bridge.broadcast(event);
|
|
155
|
+
}
|
|
156
|
+
async handleFileChange(filePath, options = {}) {
|
|
157
|
+
const sorted = [...this.strategies].sort((a, b) => b.priority - a.priority);
|
|
158
|
+
const strategy = sorted.find((s) => {
|
|
159
|
+
try {
|
|
160
|
+
return s.matches(filePath);
|
|
161
|
+
} catch (err) {
|
|
162
|
+
appLogger.error(err);
|
|
163
|
+
return false;
|
|
164
|
+
}
|
|
165
|
+
});
|
|
166
|
+
if (!strategy) {
|
|
167
|
+
appLogger.warn(`[HMR] No strategy found for ${filePath}`);
|
|
168
|
+
return;
|
|
169
|
+
}
|
|
170
|
+
appLogger.debug(`[NodeHmrManager] Selected strategy: ${strategy.constructor.name}`);
|
|
171
|
+
const action = await strategy.process(filePath);
|
|
172
|
+
const shouldBroadcast = options.broadcast ?? true;
|
|
173
|
+
if (shouldBroadcast && action.type === "broadcast") {
|
|
174
|
+
if (action.events) {
|
|
175
|
+
for (const event of action.events) {
|
|
176
|
+
this.broadcast(event);
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
getOutputUrl(entrypointPath) {
|
|
182
|
+
return this.watchedFiles.get(entrypointPath);
|
|
183
|
+
}
|
|
184
|
+
getWatchedFiles() {
|
|
185
|
+
return this.watchedFiles;
|
|
186
|
+
}
|
|
187
|
+
getSpecifierMap() {
|
|
188
|
+
return this.runtimeSpecifierRegistry.getAll();
|
|
189
|
+
}
|
|
190
|
+
getDistDir() {
|
|
191
|
+
return this.distDir;
|
|
192
|
+
}
|
|
193
|
+
getPlugins() {
|
|
194
|
+
return this.plugins;
|
|
195
|
+
}
|
|
196
|
+
getDefaultContext() {
|
|
197
|
+
return {
|
|
198
|
+
getWatchedFiles: () => this.watchedFiles,
|
|
199
|
+
getSpecifierMap: () => this.runtimeSpecifierRegistry.getAll(),
|
|
200
|
+
getDistDir: () => this.distDir,
|
|
201
|
+
getPlugins: () => this.plugins,
|
|
202
|
+
getSrcDir: () => this.appConfig.absolutePaths.srcDir,
|
|
203
|
+
getLayoutsDir: () => this.appConfig.absolutePaths.layoutsDir,
|
|
204
|
+
getPagesDir: () => this.appConfig.absolutePaths.pagesDir,
|
|
205
|
+
getBuildExecutor: () => getAppBuildExecutor(this.appConfig),
|
|
206
|
+
getBrowserBundleService: () => this.browserBundleService,
|
|
207
|
+
importServerModule: async (filePath) => await this.serverModuleTranspiler.importModule({
|
|
208
|
+
filePath,
|
|
209
|
+
outdir: path.join(resolveInternalExecutionDir(this.appConfig), ".server-modules"),
|
|
210
|
+
externalPackages: true
|
|
211
|
+
})
|
|
212
|
+
};
|
|
213
|
+
}
|
|
214
|
+
clearFailedEntrypointRegistration(entrypointPath) {
|
|
215
|
+
this.watchedFiles.delete(entrypointPath);
|
|
216
|
+
this.entrypointDependencyGraph.clearEntrypointDependencies(entrypointPath);
|
|
217
|
+
}
|
|
218
|
+
/**
|
|
219
|
+
* Registers one integration-owned page entrypoint.
|
|
220
|
+
*
|
|
221
|
+
* @remarks
|
|
222
|
+
* Concurrent callers share one in-flight registration. The registration is
|
|
223
|
+
* removed from the dedupe map once it resolves or fails so later requests do
|
|
224
|
+
* not inherit stale state.
|
|
225
|
+
*/
|
|
226
|
+
async registerEntrypoint(entrypointPath) {
|
|
227
|
+
return await this.entrypointRegistrar.registerEntrypoint(entrypointPath, {
|
|
228
|
+
emit: async (normalizedEntrypoint, outputPath) => await this.emitStrictEntrypoint(normalizedEntrypoint, outputPath),
|
|
229
|
+
getMissingOutputError: (normalizedEntrypoint, outputPath) => new Error(
|
|
230
|
+
`[HMR] Integration failed to emit entrypoint ${normalizedEntrypoint} to ${outputPath}. Page entrypoints must be produced by their owning integration.`
|
|
231
|
+
)
|
|
232
|
+
});
|
|
233
|
+
}
|
|
234
|
+
/**
|
|
235
|
+
* Registers one generic script entrypoint.
|
|
236
|
+
*
|
|
237
|
+
* @remarks
|
|
238
|
+
* This path is intentionally separate from page entrypoints so non-framework
|
|
239
|
+
* scripts can still use the generic build fallback without weakening the page
|
|
240
|
+
* ownership contract.
|
|
241
|
+
*/
|
|
242
|
+
async registerScriptEntrypoint(entrypointPath) {
|
|
243
|
+
return await this.entrypointRegistrar.registerEntrypoint(entrypointPath, {
|
|
244
|
+
emit: async (normalizedEntrypoint, outputPath) => await this.emitScriptEntrypoint(normalizedEntrypoint, outputPath),
|
|
245
|
+
getMissingOutputError: (normalizedEntrypoint) => new Error(`[HMR] Failed to register script entrypoint: ${normalizedEntrypoint}`)
|
|
246
|
+
});
|
|
247
|
+
}
|
|
248
|
+
/**
|
|
249
|
+
* Performs strict integration-owned entrypoint registration for one normalized source path.
|
|
250
|
+
*
|
|
251
|
+
* @remarks
|
|
252
|
+
* The flow is:
|
|
253
|
+
* 1. Reserve the output URL in the watched map.
|
|
254
|
+
* 2. Remove any stale emitted file from an earlier process or failed build.
|
|
255
|
+
* 3. Let the strategy chain try to emit the entrypoint without broadcasting.
|
|
256
|
+
* 4. Fail if the owning integration did not emit the expected output.
|
|
257
|
+
*/
|
|
258
|
+
async emitStrictEntrypoint(entrypointPath, _outputPath) {
|
|
259
|
+
await this.handleFileChange(entrypointPath, { broadcast: false });
|
|
260
|
+
}
|
|
261
|
+
/**
|
|
262
|
+
* Performs registration for a generic script asset.
|
|
263
|
+
*
|
|
264
|
+
* @remarks
|
|
265
|
+
* The manager first gives registered strategies a chance to emit the file so
|
|
266
|
+
* processor-owned or integration-owned behavior can still participate. Only
|
|
267
|
+
* when no output exists does it issue the generic build.
|
|
268
|
+
*/
|
|
269
|
+
async emitScriptEntrypoint(entrypointPath, outputPath) {
|
|
270
|
+
const naming = path.relative(this.distDir, outputPath).split(path.sep).join("/");
|
|
271
|
+
await this.handleFileChange(entrypointPath, { broadcast: false });
|
|
272
|
+
if (!fileSystem.exists(outputPath)) {
|
|
273
|
+
const buildResult = await this.browserBundleService.bundle({
|
|
274
|
+
profile: "hmr-entrypoint",
|
|
275
|
+
entrypoints: [entrypointPath],
|
|
276
|
+
outdir: this.distDir,
|
|
277
|
+
naming,
|
|
278
|
+
minify: false,
|
|
279
|
+
plugins: this.plugins
|
|
280
|
+
});
|
|
281
|
+
if (!buildResult.success) {
|
|
282
|
+
appLogger.error(
|
|
283
|
+
`[HMR] Generic script entrypoint build failed for ${entrypointPath}:`,
|
|
284
|
+
buildResult.logs
|
|
285
|
+
);
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
/**
|
|
290
|
+
* Stops active watchers and releases retained registration state.
|
|
291
|
+
*
|
|
292
|
+
* @remarks
|
|
293
|
+
* The manager intentionally does not remove emitted `_hmr` files from disk
|
|
294
|
+
* because multiple app processes may share the same dist directory during test
|
|
295
|
+
* runs. It does clear in-memory indexes so old entrypoints, dependencies, and
|
|
296
|
+
* specifier maps cannot leak across a reused manager instance.
|
|
297
|
+
*/
|
|
298
|
+
stop() {
|
|
299
|
+
this.entrypointRegistrations.clear();
|
|
300
|
+
for (const watcher of this.watchers.values()) {
|
|
301
|
+
watcher.close();
|
|
302
|
+
}
|
|
303
|
+
this.watchers.clear();
|
|
304
|
+
this.watchedFiles.clear();
|
|
305
|
+
this.runtimeSpecifierRegistry.clear();
|
|
306
|
+
this.entrypointDependencyGraph.reset();
|
|
307
|
+
this.plugins = [];
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
export {
|
|
311
|
+
NodeHmrManager
|
|
312
|
+
};
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import type { EcoPagesAppConfig } from '../../internal-types.js';
|
|
2
|
+
import { type NodeRuntimeManifest } from '../../services/runtime-manifest/node-runtime-manifest.service.js';
|
|
3
|
+
/**
|
|
4
|
+
* Host-to-adapter handoff contract for the Node thin-host runtime.
|
|
5
|
+
*
|
|
6
|
+
* @remarks
|
|
7
|
+
* The thin host is responsible only for validating the persisted manifest,
|
|
8
|
+
* capturing process-level launch context, and passing those values into the
|
|
9
|
+
* adapter. All framework bootstrap work begins after this handoff.
|
|
10
|
+
*/
|
|
11
|
+
export interface NodeRuntimeStartOptions {
|
|
12
|
+
manifest: NodeRuntimeManifest;
|
|
13
|
+
workingDirectory: string;
|
|
14
|
+
cliArgs: string[];
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Runtime session state produced after the adapter has loaded the app through
|
|
18
|
+
* the framework-owned loader path.
|
|
19
|
+
*/
|
|
20
|
+
export interface LoadedAppRuntime {
|
|
21
|
+
manifest: NodeRuntimeManifest;
|
|
22
|
+
workingDirectory: string;
|
|
23
|
+
entryModulePath: string;
|
|
24
|
+
appConfig: EcoPagesAppConfig;
|
|
25
|
+
entryModule: unknown;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Live Node thin-host runtime session.
|
|
29
|
+
*/
|
|
30
|
+
export interface NodeRuntimeSession {
|
|
31
|
+
loadApp(): Promise<LoadedAppRuntime>;
|
|
32
|
+
invalidate(changedFiles: string[]): Promise<void>;
|
|
33
|
+
dispose(): Promise<void>;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Adapter boundary created by the thin host after manifest validation.
|
|
37
|
+
*/
|
|
38
|
+
export interface NodeRuntimeAdapter {
|
|
39
|
+
start(options: NodeRuntimeStartOptions): Promise<NodeRuntimeSession>;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Validates and narrows the persisted Node runtime manifest used by the thin
|
|
43
|
+
* host handoff.
|
|
44
|
+
*/
|
|
45
|
+
export declare function assertNodeRuntimeManifest(manifest: unknown): NodeRuntimeManifest;
|
|
46
|
+
export declare function createNodeRuntimeAdapter(): NodeRuntimeAdapter;
|
|
@@ -0,0 +1,306 @@
|
|
|
1
|
+
import path from "node:path";
|
|
2
|
+
import { fileURLToPath } from "node:url";
|
|
3
|
+
import {
|
|
4
|
+
createBuildAdapter,
|
|
5
|
+
getAppBuildExecutor
|
|
6
|
+
} from "../../build/build-adapter.js";
|
|
7
|
+
import { createAppBuildExecutor } from "../../build/dev-build-coordinator.js";
|
|
8
|
+
import { createNodeBootstrapPlugin, getNodeRuntimeNodeModulesDir } from "./bootstrap-dependency-resolver.js";
|
|
9
|
+
import {
|
|
10
|
+
setAppNodeRuntimeManifest
|
|
11
|
+
} from "../../services/runtime-manifest/node-runtime-manifest.service.js";
|
|
12
|
+
import { DevelopmentInvalidationService } from "../../services/invalidation/development-invalidation.service.js";
|
|
13
|
+
import { getAppEntrypointDependencyGraph } from "../../services/runtime-state/entrypoint-dependency-graph.service.js";
|
|
14
|
+
import { createAliasResolverPlugin } from "../../plugins/alias-resolver-plugin.js";
|
|
15
|
+
import {
|
|
16
|
+
TranspilerServerLoader
|
|
17
|
+
} from "../../services/module-loading/server-loader.service.js";
|
|
18
|
+
import { resolveInternalExecutionDir } from "../../utils/resolve-work-dir.js";
|
|
19
|
+
import { installAppRuntimeBuildExecutor } from "../../build/runtime-build-executor.js";
|
|
20
|
+
const NODE_RUNTIME_CONFIG_OUTDIR = ".node-runtime-config";
|
|
21
|
+
const NODE_RUNTIME_ENTRY_OUTDIR = ".node-runtime-entry";
|
|
22
|
+
const NODE_RUNTIME_BOOTSTRAP_SPLITTING = false;
|
|
23
|
+
const NODE_RUNTIME_CONFIG_NAMESPACE = "ecopages-runtime-config";
|
|
24
|
+
const NODE_RUNTIME_CONFIG_GLOBAL_KEY = "__ecopagesNodeRuntimeConfig";
|
|
25
|
+
const NODE_HMR_MANAGER_SOURCE_PATH = fileURLToPath(new URL("./node-hmr-manager.js", import.meta.url));
|
|
26
|
+
function resolveConfigImportPath(importPath, importer) {
|
|
27
|
+
if (!importPath) {
|
|
28
|
+
return void 0;
|
|
29
|
+
}
|
|
30
|
+
if (path.isAbsolute(importPath)) {
|
|
31
|
+
return importPath;
|
|
32
|
+
}
|
|
33
|
+
if (!importPath.startsWith(".")) {
|
|
34
|
+
return void 0;
|
|
35
|
+
}
|
|
36
|
+
if (!importer) {
|
|
37
|
+
return void 0;
|
|
38
|
+
}
|
|
39
|
+
return path.resolve(path.dirname(importer), importPath);
|
|
40
|
+
}
|
|
41
|
+
function doesImportReferenceConfig(args, configModulePath) {
|
|
42
|
+
if (args.path === configModulePath) {
|
|
43
|
+
return true;
|
|
44
|
+
}
|
|
45
|
+
if (args.path === "./eco.config" || args.path === "./eco.config.js") {
|
|
46
|
+
return true;
|
|
47
|
+
}
|
|
48
|
+
const resolvedImportPath = resolveConfigImportPath(args.path, args.importer);
|
|
49
|
+
if (!resolvedImportPath) {
|
|
50
|
+
return false;
|
|
51
|
+
}
|
|
52
|
+
if (resolvedImportPath === configModulePath) {
|
|
53
|
+
return true;
|
|
54
|
+
}
|
|
55
|
+
const configPathWithoutExtension = configModulePath.replace(/\.[cm]?[jt]sx?$/i, "");
|
|
56
|
+
const resolvedPathWithoutExtension = resolvedImportPath.replace(/\.[cm]?[jt]sx?$/i, "");
|
|
57
|
+
return resolvedPathWithoutExtension === configPathWithoutExtension;
|
|
58
|
+
}
|
|
59
|
+
function createRuntimeConfigBridgePlugin(configModulePath) {
|
|
60
|
+
return {
|
|
61
|
+
name: "node-runtime-config-bridge",
|
|
62
|
+
setup(build) {
|
|
63
|
+
build.onResolve({ filter: /.*/ }, (args) => {
|
|
64
|
+
if (!doesImportReferenceConfig(args, configModulePath)) {
|
|
65
|
+
return void 0;
|
|
66
|
+
}
|
|
67
|
+
return {
|
|
68
|
+
path: NODE_RUNTIME_CONFIG_GLOBAL_KEY,
|
|
69
|
+
namespace: NODE_RUNTIME_CONFIG_NAMESPACE
|
|
70
|
+
};
|
|
71
|
+
});
|
|
72
|
+
build.onLoad({ filter: /.*/, namespace: NODE_RUNTIME_CONFIG_NAMESPACE }, () => {
|
|
73
|
+
return {
|
|
74
|
+
loader: "js",
|
|
75
|
+
contents: [
|
|
76
|
+
`const key = ${JSON.stringify(NODE_RUNTIME_CONFIG_GLOBAL_KEY)};`,
|
|
77
|
+
"const appConfig = globalThis[key];",
|
|
78
|
+
"if (!appConfig) {",
|
|
79
|
+
"throw new Error('Node runtime config bridge expected a loaded app config before app-entry evaluation.');",
|
|
80
|
+
"}",
|
|
81
|
+
"export default appConfig;"
|
|
82
|
+
].join("\n")
|
|
83
|
+
};
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
function assertNodeRuntimeManifest(manifest) {
|
|
89
|
+
if (!manifest || typeof manifest !== "object") {
|
|
90
|
+
throw new Error("Invalid Node runtime manifest: expected an object.");
|
|
91
|
+
}
|
|
92
|
+
const candidate = manifest;
|
|
93
|
+
const modulePaths = candidate.modulePaths;
|
|
94
|
+
if (candidate.runtime !== "node") {
|
|
95
|
+
throw new Error('Invalid Node runtime manifest: runtime must be "node".');
|
|
96
|
+
}
|
|
97
|
+
if (typeof candidate.appRootDir !== "string" || typeof candidate.sourceRootDir !== "string" || typeof candidate.distDir !== "string") {
|
|
98
|
+
throw new Error("Invalid Node runtime manifest: root, source, and dist paths must be strings.");
|
|
99
|
+
}
|
|
100
|
+
if (!modulePaths || typeof modulePaths.config !== "string") {
|
|
101
|
+
throw new Error("Invalid Node runtime manifest: modulePaths.config must be present.");
|
|
102
|
+
}
|
|
103
|
+
return candidate;
|
|
104
|
+
}
|
|
105
|
+
function getRuntimeOutdir(manifest, kind) {
|
|
106
|
+
return path.join(
|
|
107
|
+
resolveInternalExecutionDir({
|
|
108
|
+
rootDir: manifest.appRootDir,
|
|
109
|
+
workDir: manifest.workDir,
|
|
110
|
+
absolutePaths: {
|
|
111
|
+
workDir: manifest.workDir,
|
|
112
|
+
distDir: manifest.distDir
|
|
113
|
+
}
|
|
114
|
+
}),
|
|
115
|
+
kind
|
|
116
|
+
);
|
|
117
|
+
}
|
|
118
|
+
class NodeRuntimeAdapterSession {
|
|
119
|
+
options;
|
|
120
|
+
serverLoader;
|
|
121
|
+
bootstrapBundlePlugin;
|
|
122
|
+
bootstrapBuildAdapter;
|
|
123
|
+
bootstrapBuildExecutor;
|
|
124
|
+
invalidationService = null;
|
|
125
|
+
appConfig = null;
|
|
126
|
+
loadedAppRuntime = null;
|
|
127
|
+
constructor(options) {
|
|
128
|
+
this.options = options;
|
|
129
|
+
this.bootstrapBundlePlugin = createNodeBootstrapPlugin({
|
|
130
|
+
projectDir: options.manifest.appRootDir,
|
|
131
|
+
runtimeNodeModulesDir: getNodeRuntimeNodeModulesDir(options.manifest),
|
|
132
|
+
preserveImportMetaPaths: [
|
|
133
|
+
options.manifest.modulePaths.config,
|
|
134
|
+
...options.manifest.modulePaths.entry ? [options.manifest.modulePaths.entry] : [],
|
|
135
|
+
NODE_HMR_MANAGER_SOURCE_PATH
|
|
136
|
+
]
|
|
137
|
+
});
|
|
138
|
+
this.bootstrapBuildAdapter = createBuildAdapter();
|
|
139
|
+
this.bootstrapBuildExecutor = createAppBuildExecutor({
|
|
140
|
+
development: false,
|
|
141
|
+
adapter: this.bootstrapBuildAdapter
|
|
142
|
+
});
|
|
143
|
+
this.serverLoader = new TranspilerServerLoader({
|
|
144
|
+
rootDir: options.manifest.appRootDir,
|
|
145
|
+
getBuildExecutor: () => this.bootstrapBuildExecutor
|
|
146
|
+
});
|
|
147
|
+
}
|
|
148
|
+
isDevelopmentMode() {
|
|
149
|
+
return this.options.cliArgs.includes("--dev") || process.env.NODE_ENV === "development";
|
|
150
|
+
}
|
|
151
|
+
get manifest() {
|
|
152
|
+
return this.options.manifest;
|
|
153
|
+
}
|
|
154
|
+
getEntryModulePath() {
|
|
155
|
+
const entryModulePath = this.manifest.modulePaths.entry;
|
|
156
|
+
if (!entryModulePath) {
|
|
157
|
+
throw new Error(
|
|
158
|
+
"Invalid Node runtime manifest: modulePaths.entry must be present before the Node thin-host adapter can load the app."
|
|
159
|
+
);
|
|
160
|
+
}
|
|
161
|
+
return entryModulePath;
|
|
162
|
+
}
|
|
163
|
+
createAppLoaderContext(appConfig, buildExecutor, invalidationService) {
|
|
164
|
+
return {
|
|
165
|
+
rootDir: appConfig.rootDir,
|
|
166
|
+
getBuildExecutor: () => buildExecutor,
|
|
167
|
+
getInvalidationVersion: () => invalidationService.getServerModuleInvalidationVersion(),
|
|
168
|
+
invalidateModules: (changedFiles) => invalidationService.invalidateServerModules(changedFiles)
|
|
169
|
+
};
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* Installs and returns the app-owned runtime build executor.
|
|
173
|
+
*/
|
|
174
|
+
installAppBuildExecutor(appConfig) {
|
|
175
|
+
const appBuildExecutor = installAppRuntimeBuildExecutor(appConfig, {
|
|
176
|
+
development: this.isDevelopmentMode()
|
|
177
|
+
});
|
|
178
|
+
return appBuildExecutor;
|
|
179
|
+
}
|
|
180
|
+
/**
|
|
181
|
+
* Rebinds app-phase server loading to the installed app-owned executor.
|
|
182
|
+
*/
|
|
183
|
+
bindAppServerLoader(appConfig, buildExecutor) {
|
|
184
|
+
if (!this.invalidationService) {
|
|
185
|
+
throw new Error("Node runtime invalidation service is not initialized.");
|
|
186
|
+
}
|
|
187
|
+
this.serverLoader.rebindAppContext(
|
|
188
|
+
this.createAppLoaderContext(appConfig, buildExecutor, this.invalidationService)
|
|
189
|
+
);
|
|
190
|
+
}
|
|
191
|
+
initializeAppRuntime(appConfig) {
|
|
192
|
+
setAppNodeRuntimeManifest(appConfig, this.manifest);
|
|
193
|
+
this.invalidationService = new DevelopmentInvalidationService(appConfig);
|
|
194
|
+
const appBuildExecutor = this.installAppBuildExecutor(appConfig);
|
|
195
|
+
this.bindAppServerLoader(appConfig, appBuildExecutor);
|
|
196
|
+
this.appConfig = appConfig;
|
|
197
|
+
return appConfig;
|
|
198
|
+
}
|
|
199
|
+
/**
|
|
200
|
+
* Loads and validates the built app config through the framework-owned server
|
|
201
|
+
* loader.
|
|
202
|
+
*/
|
|
203
|
+
async loadAppConfig() {
|
|
204
|
+
if (this.appConfig) {
|
|
205
|
+
return this.appConfig;
|
|
206
|
+
}
|
|
207
|
+
let importedConfigModule;
|
|
208
|
+
try {
|
|
209
|
+
importedConfigModule = await this.serverLoader.loadConfig({
|
|
210
|
+
filePath: this.manifest.modulePaths.config,
|
|
211
|
+
outdir: getRuntimeOutdir(this.manifest, NODE_RUNTIME_CONFIG_OUTDIR),
|
|
212
|
+
splitting: NODE_RUNTIME_BOOTSTRAP_SPLITTING,
|
|
213
|
+
externalPackages: false,
|
|
214
|
+
plugins: [createAliasResolverPlugin(this.manifest.sourceRootDir), this.bootstrapBundlePlugin],
|
|
215
|
+
transpileErrorMessage: (details) => `Failed to transpile Ecopages config module: ${details}`,
|
|
216
|
+
noOutputMessage: (filePath) => `No transpiled output generated for Ecopages config module: ${filePath}`
|
|
217
|
+
});
|
|
218
|
+
} catch (error) {
|
|
219
|
+
throw new Error(
|
|
220
|
+
`Node thin-host runtime config bootstrap failed: ${error instanceof Error ? error.message : String(error)}`
|
|
221
|
+
);
|
|
222
|
+
}
|
|
223
|
+
const exportedConfig = "default" in importedConfigModule ? importedConfigModule.default : importedConfigModule;
|
|
224
|
+
return this.initializeAppRuntime(exportedConfig);
|
|
225
|
+
}
|
|
226
|
+
/**
|
|
227
|
+
* Loads the application entry through the framework-owned server loader after
|
|
228
|
+
* config bootstrap has established app-owned runtime/build services.
|
|
229
|
+
*/
|
|
230
|
+
async loadApp() {
|
|
231
|
+
if (this.loadedAppRuntime) {
|
|
232
|
+
return this.loadedAppRuntime;
|
|
233
|
+
}
|
|
234
|
+
const appConfig = await this.loadAppConfig();
|
|
235
|
+
const entryModulePath = this.getEntryModulePath();
|
|
236
|
+
let loadedEntryModule;
|
|
237
|
+
const runtimeGlobal = globalThis;
|
|
238
|
+
runtimeGlobal[NODE_RUNTIME_CONFIG_GLOBAL_KEY] = appConfig;
|
|
239
|
+
try {
|
|
240
|
+
loadedEntryModule = await this.serverLoader.loadApp({
|
|
241
|
+
filePath: entryModulePath,
|
|
242
|
+
outdir: getRuntimeOutdir(this.manifest, NODE_RUNTIME_ENTRY_OUTDIR),
|
|
243
|
+
splitting: NODE_RUNTIME_BOOTSTRAP_SPLITTING,
|
|
244
|
+
externalPackages: false,
|
|
245
|
+
plugins: [
|
|
246
|
+
createRuntimeConfigBridgePlugin(this.manifest.modulePaths.config),
|
|
247
|
+
createAliasResolverPlugin(appConfig.absolutePaths.srcDir),
|
|
248
|
+
this.bootstrapBundlePlugin
|
|
249
|
+
],
|
|
250
|
+
transpileErrorMessage: (details) => `Failed to transpile Ecopages app entry module: ${details}`,
|
|
251
|
+
noOutputMessage: (filePath) => `No transpiled output generated for Ecopages app entry module: ${filePath}`
|
|
252
|
+
});
|
|
253
|
+
} catch (error) {
|
|
254
|
+
throw new Error(
|
|
255
|
+
`Node thin-host runtime app-entry bootstrap failed: ${error instanceof Error ? error.message : String(error)}`
|
|
256
|
+
);
|
|
257
|
+
} finally {
|
|
258
|
+
delete runtimeGlobal[NODE_RUNTIME_CONFIG_GLOBAL_KEY];
|
|
259
|
+
}
|
|
260
|
+
this.loadedAppRuntime = {
|
|
261
|
+
manifest: this.manifest,
|
|
262
|
+
workingDirectory: this.options.workingDirectory,
|
|
263
|
+
appConfig,
|
|
264
|
+
entryModulePath,
|
|
265
|
+
entryModule: loadedEntryModule
|
|
266
|
+
};
|
|
267
|
+
return this.loadedAppRuntime;
|
|
268
|
+
}
|
|
269
|
+
/**
|
|
270
|
+
* Invalidates server-loader and app dev-graph state before the next bootstrap
|
|
271
|
+
* cycle.
|
|
272
|
+
*/
|
|
273
|
+
async invalidate(_changedFiles) {
|
|
274
|
+
this.serverLoader.invalidate(_changedFiles);
|
|
275
|
+
if (this.invalidationService) {
|
|
276
|
+
this.invalidationService.resetRuntimeState(_changedFiles);
|
|
277
|
+
}
|
|
278
|
+
this.loadedAppRuntime = null;
|
|
279
|
+
if (this.appConfig) {
|
|
280
|
+
this.bindAppServerLoader(this.appConfig, getAppBuildExecutor(this.appConfig));
|
|
281
|
+
return;
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
/**
|
|
285
|
+
* Disposes loader-owned resources for the current runtime session.
|
|
286
|
+
*/
|
|
287
|
+
async dispose() {
|
|
288
|
+
await this.serverLoader.dispose();
|
|
289
|
+
if (this.appConfig) {
|
|
290
|
+
getAppEntrypointDependencyGraph(this.appConfig).reset();
|
|
291
|
+
}
|
|
292
|
+
this.invalidationService = null;
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
class DefaultNodeRuntimeAdapter {
|
|
296
|
+
async start(options) {
|
|
297
|
+
return new NodeRuntimeAdapterSession(options);
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
function createNodeRuntimeAdapter() {
|
|
301
|
+
return new DefaultNodeRuntimeAdapter();
|
|
302
|
+
}
|
|
303
|
+
export {
|
|
304
|
+
assertNodeRuntimeManifest,
|
|
305
|
+
createNodeRuntimeAdapter
|
|
306
|
+
};
|