@ecopages/core 0.2.0-alpha.5 → 0.2.0-alpha.7
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 +213 -12
- package/package.json +100 -188
- package/src/adapters/README.md +39 -0
- package/src/adapters/bun/hmr-manager.test.ts +267 -0
- package/src/adapters/bun/hmr-manager.ts +180 -47
- package/src/adapters/bun/index.ts +1 -2
- package/src/adapters/bun/server-adapter.ts +41 -34
- package/src/adapters/bun/server-lifecycle.ts +40 -70
- package/src/adapters/index.ts +1 -1
- package/src/adapters/node/bootstrap-dependency-resolver.test.ts +282 -0
- package/src/adapters/node/bootstrap-dependency-resolver.ts +301 -0
- package/src/adapters/node/index.ts +7 -0
- package/src/adapters/node/node-client-bridge.test.ts +198 -0
- package/src/adapters/node/node-hmr-manager.test.ts +322 -0
- package/src/adapters/node/node-hmr-manager.ts +207 -97
- package/src/adapters/node/runtime-adapter.test.ts +868 -0
- package/src/adapters/node/runtime-adapter.ts +439 -0
- package/src/adapters/node/server-adapter.ts +31 -104
- package/src/adapters/node/static-content-server.test.ts +60 -0
- package/src/adapters/node/static-content-server.ts +36 -0
- package/src/adapters/node/write-runtime-manifest.ts +38 -0
- package/src/adapters/shared/api-response.test.ts +97 -0
- package/src/{define-api-handler.ts → adapters/shared/define-api-handler.ts} +1 -1
- package/src/adapters/shared/explicit-static-route-matcher.test.ts +381 -0
- package/src/adapters/shared/explicit-static-route-matcher.ts +7 -1
- package/src/adapters/shared/file-route-middleware-pipeline.test.ts +90 -0
- package/src/adapters/shared/file-route-middleware-pipeline.ts +6 -2
- package/src/adapters/shared/fs-server-response-factory.test.ts +187 -0
- package/src/adapters/shared/fs-server-response-matcher.test.ts +286 -0
- package/src/adapters/shared/fs-server-response-matcher.ts +17 -10
- package/src/adapters/shared/hmr-entrypoint-registrar.ts +149 -0
- package/src/adapters/shared/hmr-html-response.ts +52 -0
- package/src/adapters/shared/hmr-manager.contract.test.ts +196 -0
- package/src/adapters/shared/hmr-manager.dispatch.test.ts +220 -0
- package/src/adapters/shared/render-context.test.ts +146 -0
- package/src/adapters/shared/render-context.ts +21 -6
- package/src/adapters/shared/runtime-bootstrap.ts +79 -0
- package/src/adapters/shared/server-adapter.test.ts +77 -0
- package/src/adapters/shared/server-adapter.ts +51 -4
- package/src/adapters/shared/server-route-handler.test.ts +110 -0
- package/src/adapters/shared/server-route-handler.ts +5 -18
- package/src/adapters/shared/server-static-builder.test.ts +316 -0
- package/src/adapters/shared/server-static-builder.ts +92 -8
- package/src/build/README.md +101 -0
- package/src/build/build-adapter-serialization.test.ts +268 -0
- package/src/build/build-adapter.test.ts +815 -0
- package/src/build/build-adapter.ts +234 -6
- package/src/build/build-manifest.ts +54 -0
- package/src/build/dev-build-coordinator.ts +221 -0
- package/src/build/esbuild-build-adapter.ts +132 -84
- package/src/build/runtime-build-executor.ts +34 -0
- package/src/build/runtime-specifier-alias-plugin.test.ts +43 -0
- package/src/build/runtime-specifier-alias-plugin.ts +58 -0
- package/src/config/README.md +33 -0
- package/src/config/config-builder.test.ts +410 -0
- package/src/config/config-builder.ts +281 -49
- package/src/constants.ts +15 -0
- package/src/declarations.d.ts +18 -13
- package/src/eco/README.md +70 -16
- package/src/eco/component-render-context.ts +39 -17
- package/src/eco/eco.test.ts +678 -0
- package/src/eco/eco.ts +29 -8
- package/src/eco/eco.types.ts +20 -1
- package/src/eco/eco.utils.test.ts +124 -0
- package/src/eco/global-injector-map.test.ts +42 -0
- package/src/eco/lazy-injector-map.test.ts +66 -0
- package/src/eco/module-dependencies.test.ts +30 -0
- package/src/errors/http-error.test.ts +134 -0
- package/src/global/utils.test.ts +12 -0
- package/src/hmr/README.md +26 -0
- 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/client/hmr-runtime.ts +38 -7
- package/src/hmr/hmr-strategy.test.ts +124 -0
- package/src/hmr/hmr.postcss.test.e2e.ts +41 -0
- package/src/hmr/hmr.test.e2e.ts +29 -38
- package/src/hmr/strategies/js-hmr-strategy.test.ts +335 -0
- package/src/hmr/strategies/js-hmr-strategy.ts +71 -78
- package/src/index.ts +1 -1
- package/src/integrations/ghtml/ghtml-renderer.test.ts +63 -0
- package/src/integrations/ghtml/ghtml-renderer.ts +4 -1
- package/src/internal-types.ts +39 -19
- package/src/plugins/README.md +34 -0
- package/src/plugins/alias-resolver-plugin.test.ts +41 -0
- package/src/plugins/alias-resolver-plugin.ts +21 -3
- package/src/plugins/eco-component-meta-plugin.test.ts +380 -0
- package/src/plugins/eco-component-meta-plugin.ts +10 -3
- package/src/plugins/integration-plugin.test.ts +111 -0
- package/src/plugins/integration-plugin.ts +45 -3
- package/src/plugins/processor.test.ts +148 -0
- package/src/plugins/processor.ts +22 -2
- package/src/plugins/runtime-capability.ts +14 -0
- package/src/public-types.ts +73 -11
- package/src/route-renderer/GRAPH.md +16 -20
- package/src/route-renderer/README.md +8 -21
- package/src/route-renderer/component-graph/component-graph-executor.test.ts +41 -0
- package/src/route-renderer/component-graph/component-graph.test.ts +63 -0
- package/src/route-renderer/component-graph/component-marker.test.ts +73 -0
- package/src/route-renderer/component-graph/component-reference.ts +29 -0
- package/src/route-renderer/component-graph/marker-graph-resolver.test.ts +135 -0
- package/src/route-renderer/{marker-graph-resolver.ts → component-graph/marker-graph-resolver.ts} +11 -9
- package/src/route-renderer/orchestration/integration-renderer.test.ts +936 -0
- package/src/route-renderer/{integration-renderer.ts → orchestration/integration-renderer.ts} +113 -19
- package/src/route-renderer/orchestration/render-execution.service.test.ts +97 -0
- package/src/route-renderer/{render-execution.service.ts → orchestration/render-execution.service.ts} +109 -37
- package/src/route-renderer/orchestration/render-preparation.service.test.ts +235 -0
- package/src/route-renderer/{render-preparation.service.ts → orchestration/render-preparation.service.ts} +127 -9
- package/src/route-renderer/page-loading/dependency-resolver.test.ts +345 -0
- package/src/route-renderer/{dependency-resolver.ts → page-loading/dependency-resolver.ts} +28 -12
- package/src/route-renderer/page-loading/page-module-loader.test.ts +96 -0
- package/src/route-renderer/{page-module-loader.ts → page-loading/page-module-loader.ts} +49 -21
- package/src/route-renderer/route-renderer.ts +36 -1
- package/src/router/README.md +26 -0
- package/src/router/client/link-intent.d.ts +53 -0
- package/src/router/client/link-intent.test.browser.ts +51 -0
- package/src/router/client/link-intent.ts +92 -0
- package/src/router/client/navigation-coordinator.test.ts +237 -0
- package/src/router/client/navigation-coordinator.ts +433 -0
- package/src/router/server/fs-router-scanner.test.ts +83 -0
- package/src/router/{fs-router-scanner.ts → server/fs-router-scanner.ts} +12 -10
- package/src/router/server/fs-router.test.ts +214 -0
- package/src/router/{fs-router.ts → server/fs-router.ts} +2 -2
- package/src/services/README.md +29 -0
- package/src/services/assets/asset-processing-service/asset-processing.service.test.ts +385 -0
- package/src/services/{asset-processing-service → assets/asset-processing-service}/asset-processing.service.ts +101 -6
- package/src/services/assets/asset-processing-service/asset.factory.test.ts +63 -0
- package/src/services/{asset-processing-service → assets/asset-processing-service}/asset.factory.ts +2 -2
- package/src/services/{asset-processing-service → assets/asset-processing-service}/assets.types.ts +2 -1
- package/src/services/assets/asset-processing-service/browser-runtime-asset.factory.test.ts +72 -0
- package/src/services/assets/asset-processing-service/browser-runtime-asset.factory.ts +95 -0
- package/src/services/assets/asset-processing-service/browser-runtime-entry.factory.test.ts +67 -0
- package/src/services/assets/asset-processing-service/browser-runtime-entry.factory.ts +78 -0
- package/src/services/{asset-processing-service → assets/asset-processing-service}/index.ts +2 -0
- package/src/services/{asset-processing-service → assets/asset-processing-service}/processor.interface.ts +1 -1
- package/src/services/assets/asset-processing-service/processors/base/base-processor.test.ts +59 -0
- package/src/services/{asset-processing-service → assets/asset-processing-service}/processors/base/base-processor.ts +11 -5
- package/src/services/{asset-processing-service → assets/asset-processing-service}/processors/base/base-script-processor.ts +17 -27
- package/src/services/assets/asset-processing-service/processors/script/file-script.processor.test.ts +286 -0
- package/src/services/{asset-processing-service → assets/asset-processing-service}/processors/script/file-script.processor.ts +3 -3
- package/src/services/assets/asset-processing-service/processors/script/node-module-script.processor.test.ts +227 -0
- package/src/services/{asset-processing-service → assets/asset-processing-service}/processors/script/node-module-script.processor.ts +5 -4
- package/src/services/assets/asset-processing-service/processors/stylesheet/content-stylesheet.processor.test.ts +199 -0
- package/src/services/{asset-processing-service → assets/asset-processing-service}/processors/stylesheet/file-stylesheet.processor.ts +4 -1
- package/src/services/assets/browser-bundle.service.test.ts +36 -0
- package/src/services/assets/browser-bundle.service.ts +53 -0
- package/src/services/cache/index.ts +3 -3
- package/src/services/cache/memory-cache-store.test.ts +225 -0
- package/src/services/cache/memory-cache-store.ts +1 -1
- package/src/services/cache/page-cache-service.test.ts +175 -0
- package/src/services/cache/page-cache-service.ts +3 -3
- package/src/services/cache/page-request-cache-coordinator.service.test.ts +79 -0
- package/src/services/{page-request-cache-coordinator.service.ts → cache/page-request-cache-coordinator.service.ts} +9 -6
- package/src/services/html/html-rewriter-provider.service.test.ts +183 -0
- package/src/services/html/html-rewriter-provider.service.ts +103 -0
- package/src/services/html/html-transformer.service.test.ts +378 -0
- package/src/services/html/html-transformer.service.ts +279 -0
- package/src/services/invalidation/development-invalidation.service.test.ts +77 -0
- package/src/services/invalidation/development-invalidation.service.ts +261 -0
- package/src/services/module-loading/app-server-module-transpiler.service.ts +52 -0
- package/src/services/module-loading/page-module-import.service.test.ts +253 -0
- package/src/services/module-loading/page-module-import.service.ts +200 -0
- package/src/services/module-loading/server-loader.service.test.ts +161 -0
- package/src/services/module-loading/server-loader.service.ts +130 -0
- package/src/services/module-loading/server-module-transpiler.service.test.ts +115 -0
- package/src/services/module-loading/server-module-transpiler.service.ts +105 -0
- package/src/services/runtime-manifest/node-runtime-manifest.service.test.ts +95 -0
- package/src/services/runtime-manifest/node-runtime-manifest.service.ts +101 -0
- package/src/services/runtime-state/dev-graph.service.ts +217 -0
- package/src/services/runtime-state/entrypoint-dependency-graph.service.ts +136 -0
- package/src/services/runtime-state/runtime-specifier-registry.service.ts +96 -0
- package/src/services/runtime-state/server-invalidation-state.service.ts +68 -0
- package/src/services/validation/schema-validation-service.test.ts +223 -0
- package/src/services/{schema-validation-service.ts → validation/schema-validation-service.ts} +1 -1
- package/src/static-site-generator/README.md +26 -0
- package/src/static-site-generator/static-site-generator.test.ts +307 -0
- package/src/static-site-generator/static-site-generator.ts +109 -6
- package/src/utils/deep-merge.test.ts +114 -0
- package/src/utils/invariant.test.ts +22 -0
- package/src/utils/path-utils.test.ts +15 -0
- package/src/utils/resolve-work-dir.ts +45 -0
- package/src/utils/server-utils.test.ts +38 -0
- package/src/watchers/project-watcher.integration.test.ts +337 -0
- package/src/watchers/project-watcher.test-helpers.ts +1 -0
- package/src/watchers/project-watcher.test.ts +678 -0
- package/src/watchers/project-watcher.ts +49 -50
- package/CHANGELOG.md +0 -94
- package/src/adapters/abstract/application-adapter.d.ts +0 -168
- package/src/adapters/abstract/application-adapter.js +0 -109
- package/src/adapters/abstract/router-adapter.d.ts +0 -26
- package/src/adapters/abstract/router-adapter.js +0 -5
- package/src/adapters/abstract/server-adapter.d.ts +0 -69
- package/src/adapters/abstract/server-adapter.js +0 -15
- package/src/adapters/bun/client-bridge.d.ts +0 -34
- package/src/adapters/bun/client-bridge.js +0 -48
- package/src/adapters/bun/create-app.d.ts +0 -60
- package/src/adapters/bun/create-app.js +0 -117
- package/src/adapters/bun/define-api-handler.d.ts +0 -61
- package/src/adapters/bun/define-api-handler.js +0 -15
- package/src/adapters/bun/define-api-handler.ts +0 -114
- package/src/adapters/bun/hmr-manager.d.ts +0 -79
- package/src/adapters/bun/hmr-manager.js +0 -222
- package/src/adapters/bun/index.d.ts +0 -3
- package/src/adapters/bun/index.js +0 -8
- package/src/adapters/bun/server-adapter.d.ts +0 -155
- package/src/adapters/bun/server-adapter.js +0 -368
- package/src/adapters/bun/server-lifecycle.d.ts +0 -52
- package/src/adapters/bun/server-lifecycle.js +0 -120
- package/src/adapters/index.d.ts +0 -6
- package/src/adapters/index.js +0 -14
- package/src/adapters/node/create-app.d.ts +0 -21
- package/src/adapters/node/create-app.js +0 -143
- package/src/adapters/node/index.d.ts +0 -4
- package/src/adapters/node/index.js +0 -8
- package/src/adapters/node/node-client-bridge.d.ts +0 -26
- package/src/adapters/node/node-client-bridge.js +0 -66
- package/src/adapters/node/node-hmr-manager.d.ts +0 -62
- package/src/adapters/node/node-hmr-manager.js +0 -221
- package/src/adapters/node/server-adapter.d.ts +0 -190
- package/src/adapters/node/server-adapter.js +0 -420
- package/src/adapters/node/static-content-server.d.ts +0 -24
- package/src/adapters/node/static-content-server.js +0 -166
- package/src/adapters/shared/api-response.d.ts +0 -52
- package/src/adapters/shared/api-response.js +0 -96
- package/src/adapters/shared/application-adapter.d.ts +0 -18
- package/src/adapters/shared/application-adapter.js +0 -90
- package/src/adapters/shared/explicit-static-route-matcher.d.ts +0 -38
- package/src/adapters/shared/explicit-static-route-matcher.js +0 -100
- package/src/adapters/shared/file-route-middleware-pipeline.d.ts +0 -65
- package/src/adapters/shared/file-route-middleware-pipeline.js +0 -98
- package/src/adapters/shared/fs-server-response-factory.d.ts +0 -19
- package/src/adapters/shared/fs-server-response-factory.js +0 -97
- package/src/adapters/shared/fs-server-response-matcher.d.ts +0 -71
- package/src/adapters/shared/fs-server-response-matcher.js +0 -155
- package/src/adapters/shared/render-context.d.ts +0 -14
- package/src/adapters/shared/render-context.js +0 -69
- package/src/adapters/shared/server-adapter.d.ts +0 -87
- package/src/adapters/shared/server-adapter.js +0 -353
- package/src/adapters/shared/server-route-handler.d.ts +0 -89
- package/src/adapters/shared/server-route-handler.js +0 -120
- package/src/adapters/shared/server-static-builder.d.ts +0 -38
- package/src/adapters/shared/server-static-builder.js +0 -46
- package/src/build/build-adapter.d.ts +0 -75
- package/src/build/build-adapter.js +0 -54
- package/src/build/build-types.d.ts +0 -57
- package/src/build/build-types.js +0 -0
- package/src/build/esbuild-build-adapter.d.ts +0 -69
- package/src/build/esbuild-build-adapter.js +0 -391
- package/src/config/config-builder.d.ts +0 -227
- package/src/config/config-builder.js +0 -392
- package/src/constants.d.ts +0 -32
- package/src/constants.js +0 -21
- package/src/create-app.d.ts +0 -17
- package/src/create-app.js +0 -66
- package/src/define-api-handler.d.ts +0 -25
- package/src/define-api-handler.js +0 -15
- package/src/dev/sc-server.d.ts +0 -30
- package/src/dev/sc-server.js +0 -111
- package/src/eco/component-render-context.d.ts +0 -105
- package/src/eco/component-render-context.js +0 -77
- package/src/eco/eco.d.ts +0 -9
- package/src/eco/eco.js +0 -110
- package/src/eco/eco.types.d.ts +0 -170
- package/src/eco/eco.types.js +0 -0
- package/src/eco/eco.utils.d.ts +0 -40
- package/src/eco/eco.utils.js +0 -40
- package/src/eco/global-injector-map.d.ts +0 -16
- package/src/eco/global-injector-map.js +0 -80
- package/src/eco/lazy-injector-map.d.ts +0 -8
- package/src/eco/lazy-injector-map.js +0 -70
- package/src/eco/module-dependencies.d.ts +0 -18
- package/src/eco/module-dependencies.js +0 -49
- package/src/errors/http-error.d.ts +0 -31
- package/src/errors/http-error.js +0 -50
- package/src/errors/index.d.ts +0 -2
- package/src/errors/index.js +0 -4
- package/src/errors/locals-access-error.d.ts +0 -4
- package/src/errors/locals-access-error.js +0 -9
- package/src/global/app-logger.d.ts +0 -2
- package/src/global/app-logger.js +0 -6
- package/src/hmr/client/hmr-runtime.d.ts +0 -10
- package/src/hmr/client/hmr-runtime.js +0 -86
- package/src/hmr/hmr-strategy.d.ts +0 -159
- package/src/hmr/hmr-strategy.js +0 -29
- package/src/hmr/hmr.test.e2e.d.ts +0 -1
- package/src/hmr/hmr.test.e2e.js +0 -50
- package/src/hmr/strategies/default-hmr-strategy.d.ts +0 -43
- package/src/hmr/strategies/default-hmr-strategy.js +0 -34
- package/src/hmr/strategies/js-hmr-strategy.d.ts +0 -136
- package/src/hmr/strategies/js-hmr-strategy.js +0 -192
- package/src/index.browser.d.ts +0 -3
- package/src/index.browser.js +0 -4
- package/src/index.d.ts +0 -5
- package/src/index.js +0 -10
- package/src/integrations/ghtml/ghtml-renderer.d.ts +0 -15
- package/src/integrations/ghtml/ghtml-renderer.js +0 -60
- package/src/integrations/ghtml/ghtml.plugin.d.ts +0 -20
- package/src/integrations/ghtml/ghtml.plugin.js +0 -21
- package/src/internal-types.d.ts +0 -200
- package/src/internal-types.js +0 -0
- package/src/plugins/alias-resolver-plugin.d.ts +0 -2
- package/src/plugins/alias-resolver-plugin.js +0 -39
- package/src/plugins/eco-component-meta-plugin.d.ts +0 -95
- package/src/plugins/eco-component-meta-plugin.js +0 -157
- package/src/plugins/integration-plugin.d.ts +0 -102
- package/src/plugins/integration-plugin.js +0 -100
- package/src/plugins/processor.d.ts +0 -82
- package/src/plugins/processor.js +0 -122
- package/src/public-types.d.ts +0 -1094
- package/src/public-types.js +0 -0
- package/src/route-renderer/component-graph-executor.d.ts +0 -32
- package/src/route-renderer/component-graph-executor.js +0 -31
- package/src/route-renderer/component-graph.d.ts +0 -42
- package/src/route-renderer/component-graph.js +0 -72
- package/src/route-renderer/component-marker.d.ts +0 -52
- package/src/route-renderer/component-marker.js +0 -46
- package/src/route-renderer/dependency-resolver.d.ts +0 -24
- package/src/route-renderer/dependency-resolver.js +0 -428
- package/src/route-renderer/html-post-processing.service.d.ts +0 -40
- package/src/route-renderer/html-post-processing.service.js +0 -86
- package/src/route-renderer/html-post-processing.service.ts +0 -103
- package/src/route-renderer/integration-renderer.d.ts +0 -339
- package/src/route-renderer/integration-renderer.js +0 -526
- package/src/route-renderer/marker-graph-resolver.d.ts +0 -76
- package/src/route-renderer/marker-graph-resolver.js +0 -93
- package/src/route-renderer/page-module-loader.d.ts +0 -61
- package/src/route-renderer/page-module-loader.js +0 -102
- package/src/route-renderer/render-execution.service.d.ts +0 -69
- package/src/route-renderer/render-execution.service.js +0 -91
- package/src/route-renderer/render-preparation.service.d.ts +0 -112
- package/src/route-renderer/render-preparation.service.js +0 -243
- package/src/route-renderer/route-renderer.d.ts +0 -26
- package/src/route-renderer/route-renderer.js +0 -68
- package/src/router/fs-router-scanner.d.ts +0 -41
- package/src/router/fs-router-scanner.js +0 -155
- package/src/router/fs-router.d.ts +0 -26
- package/src/router/fs-router.js +0 -100
- package/src/services/asset-processing-service/asset-processing.service.d.ts +0 -41
- package/src/services/asset-processing-service/asset-processing.service.js +0 -250
- package/src/services/asset-processing-service/asset.factory.d.ts +0 -17
- package/src/services/asset-processing-service/asset.factory.js +0 -82
- package/src/services/asset-processing-service/assets.types.d.ts +0 -88
- package/src/services/asset-processing-service/assets.types.js +0 -0
- package/src/services/asset-processing-service/index.d.ts +0 -3
- package/src/services/asset-processing-service/index.js +0 -3
- package/src/services/asset-processing-service/processor.interface.d.ts +0 -22
- package/src/services/asset-processing-service/processor.interface.js +0 -6
- package/src/services/asset-processing-service/processor.registry.d.ts +0 -8
- package/src/services/asset-processing-service/processor.registry.js +0 -15
- package/src/services/asset-processing-service/processors/base/base-processor.d.ts +0 -24
- package/src/services/asset-processing-service/processors/base/base-processor.js +0 -59
- package/src/services/asset-processing-service/processors/base/base-script-processor.d.ts +0 -16
- package/src/services/asset-processing-service/processors/base/base-script-processor.js +0 -80
- package/src/services/asset-processing-service/processors/index.d.ts +0 -5
- package/src/services/asset-processing-service/processors/index.js +0 -5
- package/src/services/asset-processing-service/processors/script/content-script.processor.d.ts +0 -5
- package/src/services/asset-processing-service/processors/script/content-script.processor.js +0 -57
- package/src/services/asset-processing-service/processors/script/file-script.processor.d.ts +0 -8
- package/src/services/asset-processing-service/processors/script/file-script.processor.js +0 -76
- package/src/services/asset-processing-service/processors/script/node-module-script.processor.d.ts +0 -7
- package/src/services/asset-processing-service/processors/script/node-module-script.processor.js +0 -74
- package/src/services/asset-processing-service/processors/stylesheet/content-stylesheet.processor.d.ts +0 -5
- package/src/services/asset-processing-service/processors/stylesheet/content-stylesheet.processor.js +0 -25
- package/src/services/asset-processing-service/processors/stylesheet/file-stylesheet.processor.d.ts +0 -9
- package/src/services/asset-processing-service/processors/stylesheet/file-stylesheet.processor.js +0 -63
- package/src/services/cache/cache.types.d.ts +0 -107
- package/src/services/cache/cache.types.js +0 -0
- package/src/services/cache/index.d.ts +0 -7
- package/src/services/cache/index.js +0 -7
- package/src/services/cache/memory-cache-store.d.ts +0 -42
- package/src/services/cache/memory-cache-store.js +0 -98
- package/src/services/cache/page-cache-service.d.ts +0 -70
- package/src/services/cache/page-cache-service.js +0 -152
- package/src/services/html-transformer.service.d.ts +0 -50
- package/src/services/html-transformer.service.js +0 -163
- package/src/services/html-transformer.service.ts +0 -217
- package/src/services/page-module-import.service.d.ts +0 -37
- package/src/services/page-module-import.service.js +0 -88
- package/src/services/page-module-import.service.ts +0 -129
- package/src/services/page-request-cache-coordinator.service.d.ts +0 -75
- package/src/services/page-request-cache-coordinator.service.js +0 -107
- package/src/services/schema-validation-service.d.ts +0 -122
- package/src/services/schema-validation-service.js +0 -101
- package/src/services/validation/standard-schema.types.d.ts +0 -65
- package/src/services/validation/standard-schema.types.js +0 -0
- package/src/static-site-generator/static-site-generator.d.ts +0 -57
- package/src/static-site-generator/static-site-generator.js +0 -272
- package/src/utils/css.d.ts +0 -1
- package/src/utils/css.js +0 -7
- package/src/utils/deep-merge.d.ts +0 -14
- package/src/utils/deep-merge.js +0 -32
- package/src/utils/hash.d.ts +0 -1
- package/src/utils/hash.js +0 -7
- package/src/utils/html.d.ts +0 -1
- package/src/utils/html.js +0 -4
- package/src/utils/invariant.d.ts +0 -5
- package/src/utils/invariant.js +0 -11
- package/src/utils/locals-utils.d.ts +0 -15
- package/src/utils/locals-utils.js +0 -24
- package/src/utils/parse-cli-args.d.ts +0 -24
- package/src/utils/parse-cli-args.js +0 -47
- package/src/utils/path-utils.module.d.ts +0 -5
- package/src/utils/path-utils.module.js +0 -14
- package/src/utils/runtime.d.ts +0 -11
- package/src/utils/runtime.js +0 -40
- package/src/utils/server-utils.module.d.ts +0 -19
- package/src/utils/server-utils.module.js +0 -56
- package/src/watchers/project-watcher.d.ts +0 -132
- package/src/watchers/project-watcher.js +0 -281
- package/src/watchers/project-watcher.test-helpers.d.ts +0 -4
- package/src/watchers/project-watcher.test-helpers.js +0 -51
- /package/src/route-renderer/{component-graph-executor.ts → component-graph/component-graph-executor.ts} +0 -0
- /package/src/route-renderer/{component-graph.ts → component-graph/component-graph.ts} +0 -0
- /package/src/route-renderer/{component-marker.ts → component-graph/component-marker.ts} +0 -0
- /package/src/services/{asset-processing-service → assets/asset-processing-service}/processor.registry.ts +0 -0
- /package/src/services/{asset-processing-service → assets/asset-processing-service}/processors/index.ts +0 -0
- /package/src/services/{asset-processing-service → assets/asset-processing-service}/processors/script/content-script.processor.ts +0 -0
- /package/src/services/{asset-processing-service → assets/asset-processing-service}/processors/stylesheet/content-stylesheet.processor.ts +0 -0
|
@@ -0,0 +1,345 @@
|
|
|
1
|
+
import { describe, expect, it, vi } from 'vitest';
|
|
2
|
+
import { join } from 'node:path';
|
|
3
|
+
import { tmpdir } from 'node:os';
|
|
4
|
+
import { mkdtempSync, rmSync, writeFileSync } from 'node:fs';
|
|
5
|
+
import { DEPENDENCY_ERRORS, DependencyResolverService } from './dependency-resolver.ts';
|
|
6
|
+
import type { EcoPagesAppConfig } from '../../internal-types.ts';
|
|
7
|
+
import type {
|
|
8
|
+
AssetDefinition,
|
|
9
|
+
AssetProcessingService,
|
|
10
|
+
ProcessedAsset,
|
|
11
|
+
ContentScriptAsset,
|
|
12
|
+
} from '../../services/assets/asset-processing-service/index.ts';
|
|
13
|
+
import type { EcoComponent } from '../../public-types.ts';
|
|
14
|
+
|
|
15
|
+
describe('DependencyResolverService', () => {
|
|
16
|
+
const appConfig = {
|
|
17
|
+
srcDir: '/app',
|
|
18
|
+
} as EcoPagesAppConfig;
|
|
19
|
+
|
|
20
|
+
it('should resolve dependency and lazy script paths', () => {
|
|
21
|
+
const assetProcessingService = {
|
|
22
|
+
processDependencies: vi.fn(async () => []),
|
|
23
|
+
} as unknown as AssetProcessingService;
|
|
24
|
+
const service = new DependencyResolverService(appConfig, assetProcessingService);
|
|
25
|
+
|
|
26
|
+
expect(service.resolveDependencyPath('/app/components/card', './style.css')).toBe(
|
|
27
|
+
'/app/components/card/style.css',
|
|
28
|
+
);
|
|
29
|
+
expect(service.resolveLazyScripts('/app/components/card', ['./client.ts', './widget.tsx'])).toBe(
|
|
30
|
+
'/assets/components/card/client.js,/assets/components/card/widget.js',
|
|
31
|
+
);
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
it('should emit module dependencies as content scripts and resolve lazy triggers by default', async () => {
|
|
35
|
+
let capturedDeps: AssetDefinition[] = [];
|
|
36
|
+
const assetProcessingService = {
|
|
37
|
+
processDependencies: vi.fn(async (deps: AssetDefinition[]) => {
|
|
38
|
+
capturedDeps = deps;
|
|
39
|
+
return [
|
|
40
|
+
{
|
|
41
|
+
kind: 'script',
|
|
42
|
+
filepath: '/app/components/table/table.client.ts',
|
|
43
|
+
srcUrl: '/assets/components/table/table.client.js',
|
|
44
|
+
},
|
|
45
|
+
] as ProcessedAsset[];
|
|
46
|
+
}),
|
|
47
|
+
} as unknown as AssetProcessingService;
|
|
48
|
+
const service = new DependencyResolverService(appConfig, assetProcessingService);
|
|
49
|
+
|
|
50
|
+
const component = ((_) => '<table></table>') as EcoComponent<Record<string, unknown>>;
|
|
51
|
+
component.config = {
|
|
52
|
+
__eco: {
|
|
53
|
+
id: 'table',
|
|
54
|
+
integration: 'react',
|
|
55
|
+
file: '/app/components/table/table.tsx',
|
|
56
|
+
},
|
|
57
|
+
dependencies: {
|
|
58
|
+
modules: ['react-aria-components{Table,Button}', './client-utils'],
|
|
59
|
+
scripts: [{ src: './table.client.ts', lazy: { 'on:interaction': 'click' } }],
|
|
60
|
+
},
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
await service.processComponentDependencies([component], 'react');
|
|
64
|
+
|
|
65
|
+
const contentScripts = capturedDeps.filter(
|
|
66
|
+
(dep): dep is ContentScriptAsset => dep.kind === 'script' && dep.source === 'content',
|
|
67
|
+
);
|
|
68
|
+
|
|
69
|
+
expect(
|
|
70
|
+
contentScripts.some((script) =>
|
|
71
|
+
script.content.includes("export { Table, Button } from 'react-aria-components';"),
|
|
72
|
+
),
|
|
73
|
+
).toBe(true);
|
|
74
|
+
expect(contentScripts.some((script) => script.content.includes("export * from './client-utils';"))).toBe(true);
|
|
75
|
+
expect(contentScripts.every((script) => /^module-[a-f0-9]+$/.test(script.name ?? ''))).toBe(true);
|
|
76
|
+
|
|
77
|
+
const hasInjector = capturedDeps.some(
|
|
78
|
+
(dep) =>
|
|
79
|
+
dep.kind === 'script' &&
|
|
80
|
+
dep.source === 'node-module' &&
|
|
81
|
+
dep.importPath === '@ecopages/scripts-injector',
|
|
82
|
+
);
|
|
83
|
+
expect(hasInjector).toBe(false);
|
|
84
|
+
|
|
85
|
+
expect(component.config._resolvedLazyScripts).toBeUndefined();
|
|
86
|
+
expect(component.config._resolvedLazyTriggers).toHaveLength(1);
|
|
87
|
+
expect(component.config._resolvedLazyTriggers?.[0]?.rules).toEqual([
|
|
88
|
+
{
|
|
89
|
+
'on:interaction': {
|
|
90
|
+
value: 'click',
|
|
91
|
+
scripts: ['/assets/components/table/table.client.js'],
|
|
92
|
+
},
|
|
93
|
+
},
|
|
94
|
+
]);
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
it('should detect ecopages virtual imports via parser', async () => {
|
|
98
|
+
const tempDir = mkdtempSync(join(tmpdir(), 'ecopages-dependency-resolver-'));
|
|
99
|
+
const componentFile = join(tempDir, 'component.tsx');
|
|
100
|
+
|
|
101
|
+
writeFileSync(
|
|
102
|
+
componentFile,
|
|
103
|
+
"import { heroImage as imageAsset } from 'ecopages:images';\nexport const ok = imageAsset.src;\n",
|
|
104
|
+
'utf-8',
|
|
105
|
+
);
|
|
106
|
+
|
|
107
|
+
let capturedDeps: AssetDefinition[] = [];
|
|
108
|
+
const assetProcessingService = {
|
|
109
|
+
processDependencies: vi.fn(async (deps: AssetDefinition[]) => {
|
|
110
|
+
capturedDeps = deps;
|
|
111
|
+
return [] as ProcessedAsset[];
|
|
112
|
+
}),
|
|
113
|
+
} as unknown as AssetProcessingService;
|
|
114
|
+
|
|
115
|
+
const service = new DependencyResolverService(appConfig, assetProcessingService);
|
|
116
|
+
const component = ((_) => '<div></div>') as EcoComponent<Record<string, unknown>>;
|
|
117
|
+
component.config = {
|
|
118
|
+
__eco: {
|
|
119
|
+
id: 'component',
|
|
120
|
+
integration: 'react',
|
|
121
|
+
file: componentFile,
|
|
122
|
+
},
|
|
123
|
+
};
|
|
124
|
+
|
|
125
|
+
try {
|
|
126
|
+
await service.processComponentDependencies([component], 'react');
|
|
127
|
+
|
|
128
|
+
const contentScripts = capturedDeps.filter(
|
|
129
|
+
(dep): dep is ContentScriptAsset => dep.kind === 'script' && dep.source === 'content',
|
|
130
|
+
);
|
|
131
|
+
|
|
132
|
+
expect(contentScripts.some((script) => script.content.includes("from 'ecopages:images';"))).toBe(true);
|
|
133
|
+
} finally {
|
|
134
|
+
rmSync(tempDir, { recursive: true, force: true });
|
|
135
|
+
}
|
|
136
|
+
});
|
|
137
|
+
|
|
138
|
+
it('should pass entry attributes and support inline stylesheet content', async () => {
|
|
139
|
+
let capturedDeps: AssetDefinition[] = [];
|
|
140
|
+
const assetProcessingService = {
|
|
141
|
+
processDependencies: vi.fn(async (deps: AssetDefinition[]) => {
|
|
142
|
+
capturedDeps = deps;
|
|
143
|
+
return [] as ProcessedAsset[];
|
|
144
|
+
}),
|
|
145
|
+
} as unknown as AssetProcessingService;
|
|
146
|
+
|
|
147
|
+
const service = new DependencyResolverService(appConfig, assetProcessingService);
|
|
148
|
+
const component = ((_) => '<div></div>') as EcoComponent<Record<string, unknown>>;
|
|
149
|
+
component.config = {
|
|
150
|
+
__eco: {
|
|
151
|
+
id: 'attrs-inline',
|
|
152
|
+
integration: 'react',
|
|
153
|
+
file: '/app/components/attrs-inline/component.tsx',
|
|
154
|
+
},
|
|
155
|
+
dependencies: {
|
|
156
|
+
scripts: [
|
|
157
|
+
{
|
|
158
|
+
src: './client.ts',
|
|
159
|
+
attributes: {
|
|
160
|
+
async: '',
|
|
161
|
+
'data-script-id': 'main-client',
|
|
162
|
+
},
|
|
163
|
+
},
|
|
164
|
+
],
|
|
165
|
+
stylesheets: [
|
|
166
|
+
{
|
|
167
|
+
src: './styles.css',
|
|
168
|
+
attributes: {
|
|
169
|
+
media: 'print',
|
|
170
|
+
},
|
|
171
|
+
},
|
|
172
|
+
{
|
|
173
|
+
content: 'body { background: red; }',
|
|
174
|
+
attributes: {
|
|
175
|
+
media: 'screen',
|
|
176
|
+
},
|
|
177
|
+
},
|
|
178
|
+
],
|
|
179
|
+
},
|
|
180
|
+
};
|
|
181
|
+
|
|
182
|
+
await service.processComponentDependencies([component], 'react');
|
|
183
|
+
|
|
184
|
+
expect(
|
|
185
|
+
capturedDeps.some((dep) => {
|
|
186
|
+
if (dep.kind !== 'script' || dep.source !== 'file') return false;
|
|
187
|
+
return (
|
|
188
|
+
dep.filepath === '/app/components/attrs-inline/client.ts' &&
|
|
189
|
+
dep.attributes?.type === 'module' &&
|
|
190
|
+
dep.attributes?.defer === '' &&
|
|
191
|
+
dep.attributes?.async === '' &&
|
|
192
|
+
dep.attributes?.['data-script-id'] === 'main-client'
|
|
193
|
+
);
|
|
194
|
+
}),
|
|
195
|
+
).toBe(true);
|
|
196
|
+
|
|
197
|
+
expect(
|
|
198
|
+
capturedDeps.some((dep) => {
|
|
199
|
+
if (dep.kind !== 'stylesheet' || dep.source !== 'file') return false;
|
|
200
|
+
return (
|
|
201
|
+
dep.filepath === '/app/components/attrs-inline/styles.css' &&
|
|
202
|
+
dep.attributes?.rel === 'stylesheet' &&
|
|
203
|
+
dep.attributes?.media === 'print'
|
|
204
|
+
);
|
|
205
|
+
}),
|
|
206
|
+
).toBe(true);
|
|
207
|
+
|
|
208
|
+
expect(
|
|
209
|
+
capturedDeps.some((dep) => {
|
|
210
|
+
if (dep.kind !== 'stylesheet' || dep.source !== 'content') return false;
|
|
211
|
+
return dep.content === 'body { background: red; }' && dep.attributes?.media === 'screen';
|
|
212
|
+
}),
|
|
213
|
+
).toBe(true);
|
|
214
|
+
});
|
|
215
|
+
|
|
216
|
+
it('should reject lazy script entry without src or content', async () => {
|
|
217
|
+
const assetProcessingService = {
|
|
218
|
+
processDependencies: vi.fn(async () => [] as ProcessedAsset[]),
|
|
219
|
+
} as unknown as AssetProcessingService;
|
|
220
|
+
|
|
221
|
+
const service = new DependencyResolverService(appConfig, assetProcessingService);
|
|
222
|
+
const component = ((_) => '<div></div>') as EcoComponent<Record<string, unknown>>;
|
|
223
|
+
component.config = {
|
|
224
|
+
__eco: {
|
|
225
|
+
id: 'invalid-lazy-entry',
|
|
226
|
+
integration: 'react',
|
|
227
|
+
file: '/app/components/invalid-lazy-entry/component.tsx',
|
|
228
|
+
},
|
|
229
|
+
dependencies: {
|
|
230
|
+
scripts: [
|
|
231
|
+
{
|
|
232
|
+
lazy: { 'on:idle': true },
|
|
233
|
+
},
|
|
234
|
+
],
|
|
235
|
+
},
|
|
236
|
+
};
|
|
237
|
+
|
|
238
|
+
await expect(service.processComponentDependencies([component], 'react')).rejects.toThrow(
|
|
239
|
+
DEPENDENCY_ERRORS.LAZY_SCRIPT_MISSING_SRC,
|
|
240
|
+
);
|
|
241
|
+
});
|
|
242
|
+
|
|
243
|
+
it('should resolve lazy triggers by group, including lazy content entries', async () => {
|
|
244
|
+
const assetProcessingService = {
|
|
245
|
+
processDependencies: vi.fn(async (deps: AssetDefinition[]) => {
|
|
246
|
+
return deps.map((dep, index) => {
|
|
247
|
+
const lazyKey = dep.attributes?.['data-eco-lazy-key'];
|
|
248
|
+
const hasContent = dep.source === 'content' && typeof (dep as any).content === 'string';
|
|
249
|
+
const isLazyScript = dep.kind === 'script' && Boolean(lazyKey);
|
|
250
|
+
const srcUrl = isLazyScript
|
|
251
|
+
? hasContent
|
|
252
|
+
? `/assets/lazy/content-${index}.js`
|
|
253
|
+
: `/assets/lazy/file-${index}.js`
|
|
254
|
+
: undefined;
|
|
255
|
+
|
|
256
|
+
return {
|
|
257
|
+
kind: dep.kind ?? 'script',
|
|
258
|
+
filepath: (dep as Record<string, any>).filepath,
|
|
259
|
+
attributes: dep.attributes,
|
|
260
|
+
srcUrl,
|
|
261
|
+
} as ProcessedAsset;
|
|
262
|
+
});
|
|
263
|
+
}),
|
|
264
|
+
} as unknown as AssetProcessingService;
|
|
265
|
+
|
|
266
|
+
const service = new DependencyResolverService(appConfig, assetProcessingService);
|
|
267
|
+
const component = ((_) => '<div></div>') as EcoComponent<Record<string, unknown>>;
|
|
268
|
+
component.config = {
|
|
269
|
+
__eco: {
|
|
270
|
+
id: 'multi-lazy-groups',
|
|
271
|
+
integration: 'lit',
|
|
272
|
+
file: '/app/components/multi-lazy-groups/component.tsx',
|
|
273
|
+
},
|
|
274
|
+
dependencies: {
|
|
275
|
+
scripts: [
|
|
276
|
+
{ src: './idle.ts', lazy: { 'on:idle': true } },
|
|
277
|
+
{ content: 'console.log("visible")', lazy: { 'on:visible': '0.25' } },
|
|
278
|
+
],
|
|
279
|
+
},
|
|
280
|
+
};
|
|
281
|
+
|
|
282
|
+
await service.processComponentDependencies([component], 'lit');
|
|
283
|
+
|
|
284
|
+
expect(component.config._resolvedLazyScripts).toBeUndefined();
|
|
285
|
+
expect(component.config._resolvedLazyTriggers).toHaveLength(1);
|
|
286
|
+
|
|
287
|
+
const rules = component.config._resolvedLazyTriggers?.[0]?.rules ?? [];
|
|
288
|
+
const idleRule = rules.find((rule) => 'on:idle' in rule);
|
|
289
|
+
const visibleRule = rules.find((rule) => 'on:visible' in rule);
|
|
290
|
+
|
|
291
|
+
expect(idleRule && 'on:idle' in idleRule ? idleRule['on:idle'].scripts[0] : undefined).toMatch(
|
|
292
|
+
/^\/assets\/lazy\/file-\d+\.js$/,
|
|
293
|
+
);
|
|
294
|
+
expect(visibleRule && 'on:visible' in visibleRule ? visibleRule['on:visible'].scripts[0] : undefined).toMatch(
|
|
295
|
+
/^\/assets\/lazy\/content-\d+\.js$/,
|
|
296
|
+
);
|
|
297
|
+
});
|
|
298
|
+
|
|
299
|
+
it('should ignore undefined component entries when collecting nested dependencies', async () => {
|
|
300
|
+
let capturedDeps: AssetDefinition[] = [];
|
|
301
|
+
const assetProcessingService = {
|
|
302
|
+
processDependencies: vi.fn(async (deps: AssetDefinition[]) => {
|
|
303
|
+
capturedDeps = deps;
|
|
304
|
+
return [] as ProcessedAsset[];
|
|
305
|
+
}),
|
|
306
|
+
} as unknown as AssetProcessingService;
|
|
307
|
+
|
|
308
|
+
const service = new DependencyResolverService(appConfig, assetProcessingService);
|
|
309
|
+
const nestedComponent = ((_) => '<button></button>') as EcoComponent<Record<string, unknown>>;
|
|
310
|
+
nestedComponent.config = {
|
|
311
|
+
__eco: {
|
|
312
|
+
id: 'theme-toggle',
|
|
313
|
+
integration: 'react',
|
|
314
|
+
file: '/app/components/theme-toggle.tsx',
|
|
315
|
+
},
|
|
316
|
+
dependencies: {
|
|
317
|
+
scripts: ['./theme-toggle.client.ts'],
|
|
318
|
+
},
|
|
319
|
+
};
|
|
320
|
+
|
|
321
|
+
const component = ((_) => '<div></div>') as EcoComponent<Record<string, unknown>>;
|
|
322
|
+
component.config = {
|
|
323
|
+
__eco: {
|
|
324
|
+
id: 'page',
|
|
325
|
+
integration: 'kitajs',
|
|
326
|
+
file: '/app/views/page.tsx',
|
|
327
|
+
},
|
|
328
|
+
dependencies: {
|
|
329
|
+
components: [undefined, nestedComponent] as unknown as EcoComponent[],
|
|
330
|
+
},
|
|
331
|
+
};
|
|
332
|
+
|
|
333
|
+
await expect(
|
|
334
|
+
service.processComponentDependencies([undefined as unknown as EcoComponent, component], 'kitajs'),
|
|
335
|
+
).resolves.toEqual([]);
|
|
336
|
+
|
|
337
|
+
expect(capturedDeps).toEqual([
|
|
338
|
+
expect.objectContaining({
|
|
339
|
+
kind: 'script',
|
|
340
|
+
source: 'file',
|
|
341
|
+
filepath: '/app/components/theme-toggle.client.ts',
|
|
342
|
+
}),
|
|
343
|
+
]);
|
|
344
|
+
});
|
|
345
|
+
});
|
|
@@ -6,16 +6,16 @@ import type {
|
|
|
6
6
|
EcoComponentScriptEntry,
|
|
7
7
|
LazyTriggerRule,
|
|
8
8
|
ResolvedLazyTrigger,
|
|
9
|
-
} from '
|
|
10
|
-
import type { EcoPagesAppConfig } from '
|
|
9
|
+
} from '../../public-types.ts';
|
|
10
|
+
import type { EcoPagesAppConfig } from '../../internal-types.ts';
|
|
11
11
|
import type {
|
|
12
12
|
AssetDefinition,
|
|
13
13
|
AssetProcessingService,
|
|
14
14
|
ProcessedAsset,
|
|
15
|
-
} from '
|
|
16
|
-
import { rapidhash } from '
|
|
17
|
-
import { AssetFactory } from '
|
|
18
|
-
import { normalizeModuleDeclarations } from '
|
|
15
|
+
} from '../../services/assets/asset-processing-service/index.ts';
|
|
16
|
+
import { rapidhash } from '../../utils/hash.ts';
|
|
17
|
+
import { AssetFactory } from '../../services/assets/asset-processing-service/index.ts';
|
|
18
|
+
import { normalizeModuleDeclarations } from '../../eco/module-dependencies.ts';
|
|
19
19
|
import { parseSync } from 'oxc-parser';
|
|
20
20
|
|
|
21
21
|
export const DEPENDENCY_ERRORS = {
|
|
@@ -243,11 +243,25 @@ function buildResolvedLazyTriggers(
|
|
|
243
243
|
}
|
|
244
244
|
|
|
245
245
|
export class DependencyResolverService {
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
private assetProcessingService: AssetProcessingService,
|
|
249
|
-
) {}
|
|
246
|
+
private appConfig: EcoPagesAppConfig;
|
|
247
|
+
private assetProcessingService: AssetProcessingService;
|
|
250
248
|
|
|
249
|
+
/**
|
|
250
|
+
* Creates the dependency resolver used by route and component rendering.
|
|
251
|
+
*
|
|
252
|
+
* @remarks
|
|
253
|
+
* The resolver stays intentionally separate from HTML rendering so component
|
|
254
|
+
* dependency collection, lazy trigger grouping, and processed-asset generation
|
|
255
|
+
* can evolve without changing renderer implementations.
|
|
256
|
+
*/
|
|
257
|
+
constructor(appConfig: EcoPagesAppConfig, assetProcessingService: AssetProcessingService) {
|
|
258
|
+
this.appConfig = appConfig;
|
|
259
|
+
this.assetProcessingService = assetProcessingService;
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
/**
|
|
263
|
+
* Resolves one dependency path relative to the component that declared it.
|
|
264
|
+
*/
|
|
251
265
|
resolveDependencyPath(componentDir: string, pathUrl: string): string {
|
|
252
266
|
return resolveDependencyPath(componentDir, pathUrl);
|
|
253
267
|
}
|
|
@@ -265,7 +279,7 @@ export class DependencyResolverService {
|
|
|
265
279
|
* Lazy dependencies are always resolved into global-injector trigger maps.
|
|
266
280
|
*/
|
|
267
281
|
async processComponentDependencies(
|
|
268
|
-
components:
|
|
282
|
+
components: Array<EcoComponent | Partial<EcoComponent> | undefined | null>,
|
|
269
283
|
integrationName: string,
|
|
270
284
|
): Promise<ProcessedAsset[]> {
|
|
271
285
|
if (!this.assetProcessingService?.processDependencies) return [];
|
|
@@ -282,6 +296,8 @@ export class DependencyResolverService {
|
|
|
282
296
|
const lazyDependencyKeys = new Set<string>();
|
|
283
297
|
|
|
284
298
|
for (const component of components) {
|
|
299
|
+
if (!component) continue;
|
|
300
|
+
|
|
285
301
|
const componentFile = component.config?.__eco?.file;
|
|
286
302
|
if (!componentFile) continue;
|
|
287
303
|
|
|
@@ -511,7 +527,7 @@ export class DependencyResolverService {
|
|
|
511
527
|
|
|
512
528
|
if (dependenciesConfig?.components) {
|
|
513
529
|
for (const nestedComponent of dependenciesConfig.components) {
|
|
514
|
-
if (nestedComponent
|
|
530
|
+
if (nestedComponent?.config) {
|
|
515
531
|
collect(nestedComponent.config);
|
|
516
532
|
}
|
|
517
533
|
}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import { describe, expect, it } from 'vitest';
|
|
2
|
+
import { PageModuleLoaderService } from './page-module-loader.ts';
|
|
3
|
+
import type { EcoPagesAppConfig } from '../../internal-types.ts';
|
|
4
|
+
import type { EcoPageFile } from '../../public-types.ts';
|
|
5
|
+
import type { EcoPageComponent } from '../../eco/eco.types.ts';
|
|
6
|
+
|
|
7
|
+
describe('PageModuleLoaderService', () => {
|
|
8
|
+
const appConfig = {
|
|
9
|
+
defaultMetadata: {
|
|
10
|
+
title: 'Default title',
|
|
11
|
+
description: 'Default description',
|
|
12
|
+
},
|
|
13
|
+
} as EcoPagesAppConfig;
|
|
14
|
+
|
|
15
|
+
it('should resolve static props via getStaticPropsForPage', async () => {
|
|
16
|
+
const service = new PageModuleLoaderService(appConfig, 'http://localhost:3000');
|
|
17
|
+
const result = await service.getStaticPropsForPage({
|
|
18
|
+
getStaticProps: async () => ({
|
|
19
|
+
props: { title: 'Page title' },
|
|
20
|
+
}),
|
|
21
|
+
params: { slug: 'a' },
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
expect(result.props).toEqual({ title: 'Page title' });
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
it('should merge default and dynamic metadata', async () => {
|
|
28
|
+
const service = new PageModuleLoaderService(appConfig, 'http://localhost:3000');
|
|
29
|
+
const metadata = await service.getMetadataPropsForPage({
|
|
30
|
+
getMetadata: async ({ props }) => ({
|
|
31
|
+
title: String(props.title),
|
|
32
|
+
description: 'Dynamic description',
|
|
33
|
+
}),
|
|
34
|
+
context: {
|
|
35
|
+
props: { title: 'Dynamic title' },
|
|
36
|
+
appConfig,
|
|
37
|
+
params: {},
|
|
38
|
+
query: {},
|
|
39
|
+
},
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
expect(metadata).toEqual({
|
|
43
|
+
title: 'Dynamic title',
|
|
44
|
+
description: 'Dynamic description',
|
|
45
|
+
});
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
it('should resolve page module using provided importer and prefer component static exports', async () => {
|
|
49
|
+
const service = new PageModuleLoaderService(appConfig, 'http://localhost:3000');
|
|
50
|
+
const Page = (() => 'ok') as EcoPageComponent<any>;
|
|
51
|
+
Page.staticProps = async () => ({ props: { from: 'component-static' } });
|
|
52
|
+
Page.metadata = async () => ({
|
|
53
|
+
title: 'component-metadata',
|
|
54
|
+
description: 'component-description',
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
const module = {
|
|
58
|
+
default: Page,
|
|
59
|
+
getStaticProps: async () => ({ props: { from: 'module-static' } }),
|
|
60
|
+
getMetadata: async () => ({ title: 'module-metadata' }),
|
|
61
|
+
extra: 'integration-value',
|
|
62
|
+
} as unknown as EcoPageFile;
|
|
63
|
+
|
|
64
|
+
const result = await service.resolvePageModule({
|
|
65
|
+
file: '/app/pages/index.tsx',
|
|
66
|
+
importPageFileFn: async () => module,
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
expect(result.getStaticProps).toBe(Page.staticProps);
|
|
70
|
+
expect(result.getMetadata).toBe(Page.metadata);
|
|
71
|
+
expect(result.integrationSpecificProps).toEqual({ extra: 'integration-value' });
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
it('should resolve page data end-to-end', async () => {
|
|
75
|
+
const service = new PageModuleLoaderService(appConfig, 'http://localhost:3000');
|
|
76
|
+
const result = await service.resolvePageData({
|
|
77
|
+
pageModule: {
|
|
78
|
+
getStaticProps: async () => ({ props: { title: 'From props' } }),
|
|
79
|
+
getMetadata: async ({ props }) => ({
|
|
80
|
+
title: String(props.title),
|
|
81
|
+
description: 'From metadata',
|
|
82
|
+
}),
|
|
83
|
+
},
|
|
84
|
+
routeOptions: {
|
|
85
|
+
file: '/app/pages/index.tsx',
|
|
86
|
+
params: {},
|
|
87
|
+
query: {},
|
|
88
|
+
},
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
expect(result).toEqual({
|
|
92
|
+
props: { title: 'From props' },
|
|
93
|
+
metadata: { title: 'From props', description: 'From metadata' },
|
|
94
|
+
});
|
|
95
|
+
});
|
|
96
|
+
});
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { invariant } from '
|
|
1
|
+
import { invariant } from '../../utils/invariant.ts';
|
|
2
2
|
import type {
|
|
3
3
|
EcoPageFile,
|
|
4
4
|
GetMetadata,
|
|
@@ -7,33 +7,50 @@ import type {
|
|
|
7
7
|
PageMetadataProps,
|
|
8
8
|
RouteRendererOptions,
|
|
9
9
|
EcoPageComponent,
|
|
10
|
-
} from '
|
|
11
|
-
import type { EcoPagesAppConfig } from '
|
|
12
|
-
import {
|
|
10
|
+
} from '../../public-types.ts';
|
|
11
|
+
import type { EcoPagesAppConfig } from '../../internal-types.ts';
|
|
12
|
+
import { getAppServerModuleTranspiler } from '../../services/module-loading/app-server-module-transpiler.service.ts';
|
|
13
|
+
import type { ServerModuleTranspiler } from '../../services/module-loading/server-module-transpiler.service.ts';
|
|
14
|
+
import { resolveInternalExecutionDir } from '../../utils/resolve-work-dir.ts';
|
|
13
15
|
|
|
14
16
|
/**
|
|
15
|
-
*
|
|
17
|
+
* Loads route page modules and normalizes their data hooks for rendering.
|
|
18
|
+
*
|
|
19
|
+
* @remarks
|
|
20
|
+
* This service keeps the render pipeline from depending directly on raw module
|
|
21
|
+
* imports. It owns the shared server-module transpiler setup, the precedence
|
|
22
|
+
* rules between component statics and module exports, and the normalization of
|
|
23
|
+
* page props and metadata into one renderer-facing shape.
|
|
16
24
|
*/
|
|
17
25
|
export class PageModuleLoaderService {
|
|
18
|
-
private
|
|
26
|
+
private serverModuleTranspiler: ServerModuleTranspiler;
|
|
27
|
+
private appConfig: EcoPagesAppConfig;
|
|
28
|
+
private runtimeOrigin: string;
|
|
19
29
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
30
|
+
/**
|
|
31
|
+
* Creates the page-module loader for one app/runtime instance.
|
|
32
|
+
*
|
|
33
|
+
* @param appConfig Finalized app config that owns build and invalidation state.
|
|
34
|
+
* @param runtimeOrigin Runtime origin exposed to page data hooks.
|
|
35
|
+
*/
|
|
36
|
+
constructor(appConfig: EcoPagesAppConfig, runtimeOrigin: string) {
|
|
37
|
+
this.appConfig = appConfig;
|
|
38
|
+
this.runtimeOrigin = runtimeOrigin;
|
|
39
|
+
this.serverModuleTranspiler = getAppServerModuleTranspiler(appConfig);
|
|
25
40
|
}
|
|
26
41
|
|
|
27
42
|
/**
|
|
28
|
-
* Imports
|
|
29
|
-
*
|
|
43
|
+
* Imports one page module through the shared server-side module loading path.
|
|
44
|
+
*
|
|
45
|
+
* @remarks
|
|
46
|
+
* The underlying transpiler keeps Bun and Node aligned on one framework-owned
|
|
47
|
+
* loading contract even though the runtime-specific execution transport differs.
|
|
30
48
|
*/
|
|
31
49
|
async importPageFile(file: string): Promise<EcoPageFile> {
|
|
32
50
|
try {
|
|
33
|
-
return await this.
|
|
51
|
+
return await this.serverModuleTranspiler.importModule<EcoPageFile>({
|
|
34
52
|
filePath: file,
|
|
35
|
-
|
|
36
|
-
outdir: `${this.appConfig.absolutePaths.distDir}/.server-modules`,
|
|
53
|
+
outdir: `${resolveInternalExecutionDir(this.appConfig)}/.server-modules`,
|
|
37
54
|
transpileErrorMessage: (details) => `Error transpiling page file: ${details}`,
|
|
38
55
|
noOutputMessage: (targetFilePath) => `No transpiled output generated for page: ${targetFilePath}`,
|
|
39
56
|
});
|
|
@@ -43,8 +60,11 @@ export class PageModuleLoaderService {
|
|
|
43
60
|
}
|
|
44
61
|
|
|
45
62
|
/**
|
|
46
|
-
* Executes
|
|
47
|
-
*
|
|
63
|
+
* Executes the page's static-props hook with Ecopages runtime context.
|
|
64
|
+
*
|
|
65
|
+
* @remarks
|
|
66
|
+
* Pages without a static-props hook still return a normalized empty props
|
|
67
|
+
* object so downstream render preparation does not branch on hook presence.
|
|
48
68
|
*/
|
|
49
69
|
async getStaticPropsForPage(options: {
|
|
50
70
|
getStaticProps?: GetStaticProps<Record<string, unknown>>;
|
|
@@ -71,8 +91,11 @@ export class PageModuleLoaderService {
|
|
|
71
91
|
}
|
|
72
92
|
|
|
73
93
|
/**
|
|
74
|
-
* Builds final page metadata
|
|
75
|
-
*
|
|
94
|
+
* Builds the final page metadata object for one render request.
|
|
95
|
+
*
|
|
96
|
+
* @remarks
|
|
97
|
+
* App-level default metadata forms the baseline, then page-level metadata is
|
|
98
|
+
* overlaid so route-specific fields win without dropping global defaults.
|
|
76
99
|
*/
|
|
77
100
|
async getMetadataPropsForPage(options: {
|
|
78
101
|
getMetadata: GetMetadata | undefined;
|
|
@@ -122,7 +145,12 @@ export class PageModuleLoaderService {
|
|
|
122
145
|
}
|
|
123
146
|
|
|
124
147
|
/**
|
|
125
|
-
* Resolves
|
|
148
|
+
* Resolves the page data needed by the render pipeline.
|
|
149
|
+
*
|
|
150
|
+
* @remarks
|
|
151
|
+
* Static props are resolved first because page metadata may depend on those
|
|
152
|
+
* props. This preserves the same ordering whether data hooks are declared as
|
|
153
|
+
* component statics or module exports.
|
|
126
154
|
*/
|
|
127
155
|
async resolvePageData(options: {
|
|
128
156
|
pageModule: {
|