@ecopages/core 0.2.0-alpha.4 → 0.2.0-alpha.6
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 +181 -68
- 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 +208 -116
- 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 +235 -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 -83
- 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 +115 -115
- 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 -16
- 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 -1
- package/src/watchers/project-watcher.test.ts +678 -0
- package/src/watchers/project-watcher.ts +130 -111
- package/CHANGELOG.md +0 -91
- 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 -85
- package/src/adapters/bun/hmr-manager.js +0 -240
- 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 -63
- package/src/adapters/node/node-hmr-manager.js +0 -237
- 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 -74
- 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 -390
- 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 -188
- 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 -1098
- 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 -125
- package/src/watchers/project-watcher.js +0 -265
- package/src/watchers/project-watcher.test-helpers.d.ts +0 -4
- package/src/watchers/project-watcher.test-helpers.js +0 -52
- /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,380 @@
|
|
|
1
|
+
import { describe, expect, it, vi } from 'vitest';
|
|
2
|
+
import { createEcoComponentMetaPlugin } from './eco-component-meta-plugin';
|
|
3
|
+
import type { EcoPagesAppConfig } from '../internal-types';
|
|
4
|
+
import { fileSystem } from '@ecopages/file-system';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Creates a regex pattern to match __eco injection with any id hash.
|
|
8
|
+
* The id is a base36 hash that varies, so we match it with a pattern.
|
|
9
|
+
*/
|
|
10
|
+
function ecoMetaPattern(file: string, integration: string): RegExp {
|
|
11
|
+
const escapedFile = file.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
12
|
+
return new RegExp(`__eco: \\{ id: "[a-z0-9]+", file: "${escapedFile}", integration: "${integration}" \\}`);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
describe('eco-component-meta-plugin', () => {
|
|
16
|
+
const Config = {
|
|
17
|
+
integrations: [
|
|
18
|
+
{
|
|
19
|
+
name: 'kitajs',
|
|
20
|
+
extensions: ['.kita.tsx'],
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
name: 'react',
|
|
24
|
+
extensions: ['.tsx'],
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
name: 'ghtml',
|
|
28
|
+
extensions: ['.ts', '.ghtml.ts'],
|
|
29
|
+
},
|
|
30
|
+
],
|
|
31
|
+
} as EcoPagesAppConfig;
|
|
32
|
+
|
|
33
|
+
const plugin = createEcoComponentMetaPlugin({ config: Config });
|
|
34
|
+
|
|
35
|
+
async function runPluginOnContent(content: string, filePath: string) {
|
|
36
|
+
let regexFilter: RegExp | undefined;
|
|
37
|
+
let onLoadCallback: any;
|
|
38
|
+
|
|
39
|
+
const buildMock = {
|
|
40
|
+
onLoad: (options: { filter: RegExp }, callback: any) => {
|
|
41
|
+
regexFilter = options.filter;
|
|
42
|
+
onLoadCallback = callback;
|
|
43
|
+
},
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
plugin.setup(buildMock as any);
|
|
47
|
+
|
|
48
|
+
if (!onLoadCallback || !regexFilter) {
|
|
49
|
+
throw new Error('Plugin did not register onLoad handler');
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
if (!regexFilter.test(filePath)) {
|
|
53
|
+
throw new Error(`File path ${filePath} does not match plugin filter ${regexFilter}`);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
const fileSpy = vi.spyOn(fileSystem, 'readFileSync').mockImplementation(() => content);
|
|
57
|
+
|
|
58
|
+
try {
|
|
59
|
+
return await onLoadCallback({ path: filePath });
|
|
60
|
+
} finally {
|
|
61
|
+
fileSpy.mockRestore();
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
it('should inject __eco into X.config assignment in TSX files', async () => {
|
|
66
|
+
const content = `
|
|
67
|
+
MyComponent.config = {
|
|
68
|
+
dependencies: {}
|
|
69
|
+
};
|
|
70
|
+
`;
|
|
71
|
+
|
|
72
|
+
const result = await runPluginOnContent(content, '/path/to/component.tsx');
|
|
73
|
+
|
|
74
|
+
expect(result).toBeDefined();
|
|
75
|
+
expect(result.contents).toMatch(ecoMetaPattern('/path/to/component.tsx', 'react'));
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
it('should NOT inject __eco into config patterns in non-EcoComponent files', async () => {
|
|
79
|
+
const content = `
|
|
80
|
+
export const config = {
|
|
81
|
+
apiUrl: 'https://api.example.com',
|
|
82
|
+
theme: 'dark'
|
|
83
|
+
};
|
|
84
|
+
`;
|
|
85
|
+
|
|
86
|
+
const result = await runPluginOnContent(content, '/path/to/settings.tsx');
|
|
87
|
+
|
|
88
|
+
expect(result).toBeDefined();
|
|
89
|
+
expect(result.contents).not.toContain('__eco:');
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
it('should inject __eco into EcoComponent-typed object with config property', async () => {
|
|
93
|
+
const content = `
|
|
94
|
+
import type { EcoComponent } from '@ecopages/core';
|
|
95
|
+
|
|
96
|
+
export const LitCounter: EcoComponent = {
|
|
97
|
+
config: {
|
|
98
|
+
dependencies: {
|
|
99
|
+
scripts: ['lit-counter.script.ts'] } } };
|
|
100
|
+
`;
|
|
101
|
+
|
|
102
|
+
const result = await runPluginOnContent(content, '/path/to/lit-counter.ts');
|
|
103
|
+
|
|
104
|
+
expect(result).toBeDefined();
|
|
105
|
+
expect(result.contents).toMatch(ecoMetaPattern('/path/to/lit-counter.ts', 'ghtml'));
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
it('should inject __eco into eco.component() call', async () => {
|
|
109
|
+
const content = `
|
|
110
|
+
import { eco } from '@ecopages/core';
|
|
111
|
+
export const Counter = eco.component${'<CounterProps>'}({
|
|
112
|
+
dependencies: {
|
|
113
|
+
scripts: ['./counter.ts'] },
|
|
114
|
+
render: () => '${'<div>'}Counter${'</div>'}' });
|
|
115
|
+
`;
|
|
116
|
+
|
|
117
|
+
const result = await runPluginOnContent(content, '/path/to/counter.tsx');
|
|
118
|
+
|
|
119
|
+
expect(result).toBeDefined();
|
|
120
|
+
expect(result.contents).toMatch(ecoMetaPattern('/path/to/counter.tsx', 'react'));
|
|
121
|
+
expect(result.contents).toContain('eco.component' + '<CounterProps>({');
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
it('should inject __eco into eco.page call', async () => {
|
|
125
|
+
const content = `
|
|
126
|
+
import { eco } from '@ecopages/core';
|
|
127
|
+
export default eco.page({
|
|
128
|
+
dependencies: {
|
|
129
|
+
components: [] },
|
|
130
|
+
render: () => '${'<main>'}Page${'</main>'}' });
|
|
131
|
+
`;
|
|
132
|
+
|
|
133
|
+
const result = await runPluginOnContent(content, '/path/to/pages/index.tsx');
|
|
134
|
+
|
|
135
|
+
expect(result).toBeDefined();
|
|
136
|
+
expect(result.contents).toMatch(ecoMetaPattern('/path/to/pages/index.tsx', 'react'));
|
|
137
|
+
});
|
|
138
|
+
|
|
139
|
+
it('should inject __eco into eco.layout call', async () => {
|
|
140
|
+
const content = `
|
|
141
|
+
import { eco } from '@ecopages/core';
|
|
142
|
+
export const MainLayout = eco.layout({
|
|
143
|
+
render: ({ children }) => '${'<main>'}' + children + '${'</main>'}' });
|
|
144
|
+
`;
|
|
145
|
+
|
|
146
|
+
const result = await runPluginOnContent(content, '/path/to/layouts/main-layout.tsx');
|
|
147
|
+
|
|
148
|
+
expect(result).toBeDefined();
|
|
149
|
+
expect(result.contents).toMatch(ecoMetaPattern('/path/to/layouts/main-layout.tsx', 'react'));
|
|
150
|
+
});
|
|
151
|
+
|
|
152
|
+
it('should inject __eco into eco.html call', async () => {
|
|
153
|
+
const content = `
|
|
154
|
+
import { eco } from '@ecopages/core';
|
|
155
|
+
export default eco.html({
|
|
156
|
+
render: ({ children }) => '${'<html><body>'}' + children + '${'</body></html>'}' });
|
|
157
|
+
`;
|
|
158
|
+
|
|
159
|
+
const result = await runPluginOnContent(content, '/path/to/html.tsx');
|
|
160
|
+
|
|
161
|
+
expect(result).toBeDefined();
|
|
162
|
+
expect(result.contents).toMatch(ecoMetaPattern('/path/to/html.tsx', 'react'));
|
|
163
|
+
});
|
|
164
|
+
|
|
165
|
+
it('should inject __eco into eco.component() with lazy dependencies', async () => {
|
|
166
|
+
const content = `
|
|
167
|
+
export const LazyCounter = eco.component({
|
|
168
|
+
dependencies: {
|
|
169
|
+
scripts: [{ src: './counter.ts', lazy: { 'on:interaction': 'click' } }] },
|
|
170
|
+
render: () => '${'<div>'}Lazy${'</div>'}' });
|
|
171
|
+
`;
|
|
172
|
+
|
|
173
|
+
const result = await runPluginOnContent(content, '/path/to/lazy-counter.tsx');
|
|
174
|
+
|
|
175
|
+
expect(result).toBeDefined();
|
|
176
|
+
expect(result.contents).toMatch(ecoMetaPattern('/path/to/lazy-counter.tsx', 'react'));
|
|
177
|
+
});
|
|
178
|
+
|
|
179
|
+
it('should detect kitajs integration from .kita.tsx extension', async () => {
|
|
180
|
+
const content = `import { eco } from '@ecopages/core';
|
|
181
|
+
import type { PageHeadProps } from '@ecopages/core';
|
|
182
|
+
|
|
183
|
+
export const Head = eco.component<PageHeadProps<string>>({
|
|
184
|
+
dependencies: {
|
|
185
|
+
stylesheets: ['../styles/global.css'] },
|
|
186
|
+
render: ({ metadata, children }) => (
|
|
187
|
+
<head>
|
|
188
|
+
<meta charset="UTF-8" />
|
|
189
|
+
{children}
|
|
190
|
+
</head>
|
|
191
|
+
) });`;
|
|
192
|
+
|
|
193
|
+
const result = await runPluginOnContent(content, '/path/to/includes/head.kita.tsx');
|
|
194
|
+
|
|
195
|
+
expect(result).toBeDefined();
|
|
196
|
+
expect(result.contents).toMatch(ecoMetaPattern('/path/to/includes/head.kita.tsx', 'kitajs'));
|
|
197
|
+
});
|
|
198
|
+
|
|
199
|
+
it('should handle eco.page with complex generic types', async () => {
|
|
200
|
+
const content = `
|
|
201
|
+
import { eco } from '@ecopages/core';
|
|
202
|
+
|
|
203
|
+
export default eco.page<{ title: string; callback: (arg: string) => void }>({
|
|
204
|
+
staticProps: async () => ({ props: { title: 'Hello', callback: () => {} } }),
|
|
205
|
+
render: (props) => '<div>' + props.title + '</div>' });
|
|
206
|
+
`;
|
|
207
|
+
|
|
208
|
+
const result = await runPluginOnContent(content, '/path/to/pages/complex.tsx');
|
|
209
|
+
|
|
210
|
+
expect(result).toBeDefined();
|
|
211
|
+
expect(result.contents).toMatch(ecoMetaPattern('/path/to/pages/complex.tsx', 'react'));
|
|
212
|
+
});
|
|
213
|
+
|
|
214
|
+
it('should handle multiple eco.component calls in same file', async () => {
|
|
215
|
+
const content = `
|
|
216
|
+
import { eco } from '@ecopages/core';
|
|
217
|
+
|
|
218
|
+
export const Button = eco.component({
|
|
219
|
+
render: () => '<button>Click</button>' });
|
|
220
|
+
|
|
221
|
+
export const Input = eco.component({
|
|
222
|
+
render: () => '<input type="text" />' });
|
|
223
|
+
`;
|
|
224
|
+
|
|
225
|
+
const result = await runPluginOnContent(content, '/path/to/components.tsx');
|
|
226
|
+
|
|
227
|
+
expect(result).toBeDefined();
|
|
228
|
+
const matches = result.contents.match(
|
|
229
|
+
/__eco: \{ id: "[a-z0-9]+", file: "\/path\/to\/components\.tsx", integration: "react" \},/g,
|
|
230
|
+
);
|
|
231
|
+
expect(matches).toHaveLength(2);
|
|
232
|
+
});
|
|
233
|
+
|
|
234
|
+
it('should handle eco.component with empty config object', async () => {
|
|
235
|
+
const content = `
|
|
236
|
+
import { eco } from '@ecopages/core';
|
|
237
|
+
|
|
238
|
+
export const Simple = eco.component({});
|
|
239
|
+
`;
|
|
240
|
+
|
|
241
|
+
const result = await runPluginOnContent(content, '/path/to/simple.tsx');
|
|
242
|
+
|
|
243
|
+
expect(result).toBeDefined();
|
|
244
|
+
expect(result.contents).toMatch(ecoMetaPattern('/path/to/simple.tsx', 'react'));
|
|
245
|
+
});
|
|
246
|
+
|
|
247
|
+
it('should not inject into non-eco call expressions', async () => {
|
|
248
|
+
const content = `
|
|
249
|
+
import { other } from 'some-lib';
|
|
250
|
+
|
|
251
|
+
export const Thing = other.component({
|
|
252
|
+
render: () => '<div>Thing</div>' });
|
|
253
|
+
`;
|
|
254
|
+
|
|
255
|
+
const result = await runPluginOnContent(content, '/path/to/thing.tsx');
|
|
256
|
+
|
|
257
|
+
expect(result).toBeDefined();
|
|
258
|
+
expect(result.contents).not.toContain('__eco:');
|
|
259
|
+
});
|
|
260
|
+
|
|
261
|
+
it('should not inject into non-config variable declarations', async () => {
|
|
262
|
+
const content = `
|
|
263
|
+
const settings = {
|
|
264
|
+
theme: 'dark',
|
|
265
|
+
locale: 'en' };
|
|
266
|
+
`;
|
|
267
|
+
|
|
268
|
+
const result = await runPluginOnContent(content, '/path/to/settings.ts');
|
|
269
|
+
|
|
270
|
+
expect(result).toBeDefined();
|
|
271
|
+
expect(result.contents).not.toContain('__eco:');
|
|
272
|
+
});
|
|
273
|
+
|
|
274
|
+
it('should handle file paths with special characters in directory', async () => {
|
|
275
|
+
const content = `
|
|
276
|
+
import { eco } from '@ecopages/core';
|
|
277
|
+
|
|
278
|
+
export default eco.page({
|
|
279
|
+
render: () => '<div>Page</div>' });
|
|
280
|
+
`;
|
|
281
|
+
|
|
282
|
+
const result = await runPluginOnContent(content, '/path/to/my-app/pages/index.tsx');
|
|
283
|
+
|
|
284
|
+
expect(result).toBeDefined();
|
|
285
|
+
expect(result.contents).toMatch(ecoMetaPattern('/path/to/my-app/pages/index.tsx', 'react'));
|
|
286
|
+
});
|
|
287
|
+
|
|
288
|
+
it('should handle eco.component with nested object in dependencies', async () => {
|
|
289
|
+
const content = `
|
|
290
|
+
import { eco } from '@ecopages/core';
|
|
291
|
+
|
|
292
|
+
export const LazyComponent = eco.component({
|
|
293
|
+
dependencies: {
|
|
294
|
+
stylesheets: ['./style.css'],
|
|
295
|
+
scripts: [{ src: './script.ts', lazy: { 'on:interaction': 'click' } }],
|
|
296
|
+
components: [] },
|
|
297
|
+
render: () => '<div>Lazy</div>' });
|
|
298
|
+
`;
|
|
299
|
+
|
|
300
|
+
const result = await runPluginOnContent(content, '/path/to/lazy.tsx');
|
|
301
|
+
|
|
302
|
+
expect(result).toBeDefined();
|
|
303
|
+
expect(result.contents).toMatch(ecoMetaPattern('/path/to/lazy.tsx', 'react'));
|
|
304
|
+
});
|
|
305
|
+
|
|
306
|
+
it('should preserve original code structure after injection', async () => {
|
|
307
|
+
const content = `import { eco } from '@ecopages/core';
|
|
308
|
+
|
|
309
|
+
export const Counter = eco.component({
|
|
310
|
+
dependencies: {
|
|
311
|
+
scripts: ['./counter.ts'] },
|
|
312
|
+
render: () => '<button>0</button>' });`;
|
|
313
|
+
|
|
314
|
+
const result = await runPluginOnContent(content, '/path/to/counter.tsx');
|
|
315
|
+
|
|
316
|
+
expect(result).toBeDefined();
|
|
317
|
+
expect(result.contents).toContain("import { eco } from '@ecopages/core';");
|
|
318
|
+
expect(result.contents).toContain("scripts: ['./counter.ts']");
|
|
319
|
+
expect(result.contents).toContain("render: () => '<button>0</button>'");
|
|
320
|
+
});
|
|
321
|
+
|
|
322
|
+
it('should handle query string in file path for cache busting', async () => {
|
|
323
|
+
const content = `
|
|
324
|
+
import { eco } from '@ecopages/core';
|
|
325
|
+
|
|
326
|
+
export default eco.page({
|
|
327
|
+
render: () => '<div>Page</div>' });
|
|
328
|
+
`;
|
|
329
|
+
|
|
330
|
+
const result = await runPluginOnContent(content, '/path/to/pages/index.tsx?update=123456');
|
|
331
|
+
|
|
332
|
+
expect(result).toBeDefined();
|
|
333
|
+
expect(result.contents).toMatch(ecoMetaPattern('/path/to/pages/index.tsx', 'react'));
|
|
334
|
+
});
|
|
335
|
+
|
|
336
|
+
describe('Regression: eco-blog views failure', () => {
|
|
337
|
+
it('should inject __eco into a kitajs page with complex props and no manual __eco', async () => {
|
|
338
|
+
const content = `import { eco } from '@ecopages/core';
|
|
339
|
+
import { MainLayout } from '@/layouts/main-layout.kita';
|
|
340
|
+
import type { Post } from '@/lib/db';
|
|
341
|
+
|
|
342
|
+
export interface BlogListProps {
|
|
343
|
+
posts: Post[];
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
export const BlogList = eco.page<BlogListProps>({
|
|
347
|
+
layout: MainLayout,
|
|
348
|
+
metadata: () => ({
|
|
349
|
+
title: 'EcoBlog | Home',
|
|
350
|
+
description: 'A blog about sustainability and technology' }),
|
|
351
|
+
render: ({ posts }) => {
|
|
352
|
+
return (
|
|
353
|
+
<div class="max-w-3xl mx-auto space-y-12">
|
|
354
|
+
{/* content */}
|
|
355
|
+
</div>
|
|
356
|
+
);
|
|
357
|
+
} });`;
|
|
358
|
+
|
|
359
|
+
const result = await runPluginOnContent(
|
|
360
|
+
content,
|
|
361
|
+
'/path/to/playground/eco-blog/src/views/blog-list.kita.tsx',
|
|
362
|
+
);
|
|
363
|
+
|
|
364
|
+
expect(result).toBeDefined();
|
|
365
|
+
expect(result.contents).toMatch(
|
|
366
|
+
ecoMetaPattern('/path/to/playground/eco-blog/src/views/blog-list.kita.tsx', 'kitajs'),
|
|
367
|
+
);
|
|
368
|
+
});
|
|
369
|
+
|
|
370
|
+
it('should inject __eco even if the eco call is not at the top level', async () => {
|
|
371
|
+
const content = `
|
|
372
|
+
import { eco } from '@ecopages/core';
|
|
373
|
+
const createPage = () => eco.page({ render: () => 'hi' });
|
|
374
|
+
export default createPage();
|
|
375
|
+
`;
|
|
376
|
+
const result = await runPluginOnContent(content, '/path/to/nested.tsx');
|
|
377
|
+
expect(result.contents).toMatch(ecoMetaPattern('/path/to/nested.tsx', 'react'));
|
|
378
|
+
});
|
|
379
|
+
});
|
|
380
|
+
});
|
|
@@ -163,6 +163,8 @@ export interface EcoComponentDirPluginOptions {
|
|
|
163
163
|
* Supported patterns:
|
|
164
164
|
* - `eco.page({ ... })` - Page component declarations
|
|
165
165
|
* - `eco.component({ ... })` - Reusable component declarations
|
|
166
|
+
* - `eco.html({ ... })` - HTML shell declarations
|
|
167
|
+
* - `eco.layout({ ... })` - Layout declarations
|
|
166
168
|
* - `Component.config = { ... }` - Config assignment pattern
|
|
167
169
|
* - `config: { ... }` - Config property in object literals
|
|
168
170
|
* - `export const config = { ... }` - Exported config declarations
|
|
@@ -260,6 +262,8 @@ interface Insertion {
|
|
|
260
262
|
* |---------|---------------|---------|------------|
|
|
261
263
|
* | `eco.page({...})` | CallExpression | `export default eco.page({ render: () => 'hi' })` | All |
|
|
262
264
|
* | `eco.component({...})` | CallExpression | `export const Btn = eco.component({ render: () => '<button/>' })` | All |
|
|
265
|
+
* | `eco.html({...})` | CallExpression | `export default eco.html({ render: () => '<html />' })` | All |
|
|
266
|
+
* | `eco.layout({...})` | CallExpression | `export const MainLayout = eco.layout({ render: () => '<main />' })` | All |
|
|
263
267
|
* | `X.config = {...}` | AssignmentExpression | `MyComponent.config = { dependencies: [] }` | All |
|
|
264
268
|
* | `config: {...}` | ObjectProperty | `const X: EcoComponent = { config: {...} }` | EcoComponent-typed only |
|
|
265
269
|
*
|
|
@@ -289,7 +293,7 @@ function findInjectionPoints(
|
|
|
289
293
|
const n = node as Record<string, unknown>;
|
|
290
294
|
|
|
291
295
|
/**
|
|
292
|
-
* Pattern 1: eco.page({...}) or eco.
|
|
296
|
+
* Pattern 1: eco.page({...}), eco.component({...}), eco.html({...}), or eco.layout({...})
|
|
293
297
|
* AST structure: CallExpression with MemberExpression callee where object is "eco"
|
|
294
298
|
*/
|
|
295
299
|
if (n.type === 'CallExpression') {
|
|
@@ -303,11 +307,14 @@ function findInjectionPoints(
|
|
|
303
307
|
const obj = callee.object as Record<string, unknown> | undefined;
|
|
304
308
|
const prop = callee.property as Record<string, unknown> | undefined;
|
|
305
309
|
|
|
306
|
-
/** Check: is this `eco.page(...)` or `eco.
|
|
310
|
+
/** Check: is this `eco.page(...)`, `eco.component(...)`, `eco.html(...)`, or `eco.layout(...)`? */
|
|
307
311
|
if (
|
|
308
312
|
obj?.type === 'Identifier' &&
|
|
309
313
|
obj?.name === 'eco' &&
|
|
310
|
-
(prop?.name === 'page' ||
|
|
314
|
+
(prop?.name === 'page' ||
|
|
315
|
+
prop?.name === 'component' ||
|
|
316
|
+
prop?.name === 'html' ||
|
|
317
|
+
prop?.name === 'layout')
|
|
311
318
|
) {
|
|
312
319
|
/** Get the first argument - should be an object literal {...} */
|
|
313
320
|
const args = n.arguments as Array<Record<string, unknown>> | undefined;
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import { beforeEach, describe, expect, it, vi } from 'vitest';
|
|
2
|
+
import { IntegrationPlugin, type IntegrationPluginConfig } from './integration-plugin';
|
|
3
|
+
import type { IHmrManager } from '../public-types';
|
|
4
|
+
import type { AssetDefinition } from '../services/assets/asset-processing-service';
|
|
5
|
+
|
|
6
|
+
class TestIntegrationPlugin extends IntegrationPlugin {
|
|
7
|
+
renderer = vi.fn() as any;
|
|
8
|
+
override setup(): Promise<void> {
|
|
9
|
+
return Promise.resolve();
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
override teardown(): Promise<void> {
|
|
13
|
+
return Promise.resolve();
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
describe('IntegrationPlugin', () => {
|
|
18
|
+
let plugin: TestIntegrationPlugin;
|
|
19
|
+
const config: IntegrationPluginConfig = {
|
|
20
|
+
name: 'test-plugin',
|
|
21
|
+
extensions: ['.test'],
|
|
22
|
+
integrationDependencies: [],
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
beforeEach(() => {
|
|
26
|
+
plugin = new TestIntegrationPlugin(config);
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
it('should initialize with correct config values', () => {
|
|
30
|
+
expect(plugin.name).toBe(config.name);
|
|
31
|
+
expect(plugin.extensions).toEqual(config.extensions);
|
|
32
|
+
expect(plugin.runtimeCapability).toBeUndefined();
|
|
33
|
+
expect(plugin.getResolvedIntegrationDependencies()).toEqual(
|
|
34
|
+
config.integrationDependencies as AssetDefinition[],
|
|
35
|
+
);
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
it('should retain runtime capability declarations', () => {
|
|
39
|
+
const pluginWithRuntimeCapability = new TestIntegrationPlugin({
|
|
40
|
+
name: 'runtime-capable',
|
|
41
|
+
extensions: ['.test'],
|
|
42
|
+
runtimeCapability: {
|
|
43
|
+
tags: ['bun-only'],
|
|
44
|
+
minRuntimeVersion: '1.0.0',
|
|
45
|
+
},
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
expect(pluginWithRuntimeCapability.runtimeCapability).toEqual({
|
|
49
|
+
tags: ['bun-only'],
|
|
50
|
+
minRuntimeVersion: '1.0.0',
|
|
51
|
+
});
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
it('should initialize with empty dependencies if not provided', () => {
|
|
55
|
+
const pluginWithoutDeps = new TestIntegrationPlugin({
|
|
56
|
+
name: 'test',
|
|
57
|
+
extensions: [],
|
|
58
|
+
});
|
|
59
|
+
expect(pluginWithoutDeps.getResolvedIntegrationDependencies()).toEqual([]);
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
it('should implement setup and teardown methods', async () => {
|
|
63
|
+
await expect(plugin.setup()).resolves.toBeUndefined();
|
|
64
|
+
await expect(plugin.teardown()).resolves.toBeUndefined();
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
it('should not defer component boundaries by default', () => {
|
|
68
|
+
expect(
|
|
69
|
+
plugin.shouldDeferComponentBoundary({
|
|
70
|
+
currentIntegration: 'ghtml',
|
|
71
|
+
targetIntegration: 'react',
|
|
72
|
+
component: () => '<div></div>',
|
|
73
|
+
}),
|
|
74
|
+
).toBe(false);
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
it('should register runtime specifier maps through the base HMR setup', () => {
|
|
78
|
+
const registerSpecifierMap = vi.fn();
|
|
79
|
+
const hmrManager = {
|
|
80
|
+
registerSpecifierMap,
|
|
81
|
+
registerStrategy: vi.fn(),
|
|
82
|
+
registerEntrypoint: vi.fn(),
|
|
83
|
+
registerScriptEntrypoint: vi.fn(),
|
|
84
|
+
setPlugins: vi.fn(),
|
|
85
|
+
setEnabled: vi.fn(),
|
|
86
|
+
isEnabled: vi.fn(() => true),
|
|
87
|
+
broadcast: vi.fn(),
|
|
88
|
+
getOutputUrl: vi.fn(),
|
|
89
|
+
getWatchedFiles: vi.fn(() => new Map()),
|
|
90
|
+
getSpecifierMap: vi.fn(() => new Map()),
|
|
91
|
+
getDistDir: vi.fn(() => ''),
|
|
92
|
+
getPlugins: vi.fn(() => []),
|
|
93
|
+
getDefaultContext: vi.fn(),
|
|
94
|
+
handleFileChange: vi.fn(),
|
|
95
|
+
} satisfies IHmrManager;
|
|
96
|
+
|
|
97
|
+
const pluginWithRuntimeSpecifiers = new (class extends TestIntegrationPlugin {
|
|
98
|
+
override getRuntimeSpecifierMap(): Record<string, string> {
|
|
99
|
+
return {
|
|
100
|
+
'test-runtime': '/assets/vendors/test-runtime.js',
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
})(config);
|
|
104
|
+
|
|
105
|
+
pluginWithRuntimeSpecifiers.setHmrManager(hmrManager);
|
|
106
|
+
|
|
107
|
+
expect(registerSpecifierMap).toHaveBeenCalledWith({
|
|
108
|
+
'test-runtime': '/assets/vendors/test-runtime.js',
|
|
109
|
+
});
|
|
110
|
+
});
|
|
111
|
+
});
|
|
@@ -2,9 +2,12 @@ import type { EcoBuildPlugin } from '../build/build-types';
|
|
|
2
2
|
import type { EcoPagesAppConfig, IHmrManager } from '../internal-types';
|
|
3
3
|
import type { HmrStrategy } from '../hmr/hmr-strategy';
|
|
4
4
|
import type { EcoComponent, EcoPagesElement } from '../public-types';
|
|
5
|
-
import type { IntegrationRenderer } from '../route-renderer/integration-renderer';
|
|
6
|
-
import { AssetProcessingService } from '../services/asset-processing-service/asset-processing.service';
|
|
7
|
-
import type { AssetDefinition, ProcessedAsset } from '../services/asset-processing-service/assets.types';
|
|
5
|
+
import type { IntegrationRenderer } from '../route-renderer/orchestration/integration-renderer';
|
|
6
|
+
import { AssetProcessingService } from '../services/assets/asset-processing-service/asset-processing.service';
|
|
7
|
+
import type { AssetDefinition, ProcessedAsset } from '../services/assets/asset-processing-service/assets.types';
|
|
8
|
+
import type { RuntimeCapabilityDeclaration } from './runtime-capability.ts';
|
|
9
|
+
|
|
10
|
+
export type { RuntimeCapabilityDeclaration, RuntimeCapabilityTag } from './runtime-capability.ts';
|
|
8
11
|
|
|
9
12
|
export const INTEGRATION_PLUGIN_ERRORS = {
|
|
10
13
|
NOT_INITIALIZED_WITH_APP_CONFIG: 'Plugin not initialized with app config',
|
|
@@ -33,6 +36,11 @@ export interface IntegrationPluginConfig {
|
|
|
33
36
|
* @default 'render'
|
|
34
37
|
*/
|
|
35
38
|
staticBuildStep?: 'render' | 'fetch';
|
|
39
|
+
/**
|
|
40
|
+
* Declares runtime-specific requirements that must be satisfied before the
|
|
41
|
+
* app can start with this integration enabled.
|
|
42
|
+
*/
|
|
43
|
+
runtimeCapability?: RuntimeCapabilityDeclaration;
|
|
36
44
|
}
|
|
37
45
|
|
|
38
46
|
/**
|
|
@@ -59,6 +67,7 @@ export abstract class IntegrationPlugin<C = EcoPagesElement> {
|
|
|
59
67
|
readonly extensions: string[];
|
|
60
68
|
abstract renderer: RendererClass<C>;
|
|
61
69
|
readonly staticBuildStep: 'render' | 'fetch';
|
|
70
|
+
readonly runtimeCapability?: RuntimeCapabilityDeclaration;
|
|
62
71
|
|
|
63
72
|
protected integrationDependencies: AssetDefinition[];
|
|
64
73
|
protected resolvedIntegrationDependencies: ProcessedAsset[] = [];
|
|
@@ -77,6 +86,7 @@ export abstract class IntegrationPlugin<C = EcoPagesElement> {
|
|
|
77
86
|
this.extensions = config.extensions;
|
|
78
87
|
this.integrationDependencies = config.integrationDependencies || [];
|
|
79
88
|
this.staticBuildStep = config.staticBuildStep || 'render';
|
|
89
|
+
this.runtimeCapability = config.runtimeCapability;
|
|
80
90
|
}
|
|
81
91
|
|
|
82
92
|
setConfig(appConfig: EcoPagesAppConfig): void {
|
|
@@ -104,8 +114,26 @@ export abstract class IntegrationPlugin<C = EcoPagesElement> {
|
|
|
104
114
|
*/
|
|
105
115
|
getHmrStrategy?(): HmrStrategy | undefined;
|
|
106
116
|
|
|
117
|
+
/**
|
|
118
|
+
* Returns bare-specifier mappings that should be registered in the active
|
|
119
|
+
* runtime specifier registry.
|
|
120
|
+
*
|
|
121
|
+
* @remarks
|
|
122
|
+
* Override this when the integration owns browser runtime bundles that must
|
|
123
|
+
* be addressable from client-side imports through stable bare specifiers.
|
|
124
|
+
*
|
|
125
|
+
* Today these mappings are consumed by the development runtime and browser
|
|
126
|
+
* bundle aliasing path. They are intentionally generic enough to grow into a
|
|
127
|
+
* broader import-map-style facility later without moving framework-specific
|
|
128
|
+
* map contents into core.
|
|
129
|
+
*/
|
|
130
|
+
getRuntimeSpecifierMap(): Record<string, string> {
|
|
131
|
+
return {};
|
|
132
|
+
}
|
|
133
|
+
|
|
107
134
|
setHmrManager(hmrManager: IHmrManager) {
|
|
108
135
|
this.hmrManager = hmrManager;
|
|
136
|
+
hmrManager.registerSpecifierMap(this.getRuntimeSpecifierMap());
|
|
109
137
|
|
|
110
138
|
const strategy = this.getHmrStrategy?.();
|
|
111
139
|
if (strategy) {
|
|
@@ -169,6 +197,20 @@ export abstract class IntegrationPlugin<C = EcoPagesElement> {
|
|
|
169
197
|
return false;
|
|
170
198
|
}
|
|
171
199
|
|
|
200
|
+
/**
|
|
201
|
+
* Prepares build-facing contributions before the app build manifest is sealed.
|
|
202
|
+
*
|
|
203
|
+
* @remarks
|
|
204
|
+
* Override this when an integration needs to materialize runtime/build plugin
|
|
205
|
+
* declarations ahead of runtime startup. Keep runtime-only side effects out of
|
|
206
|
+
* this hook; they belong in `setup()`.
|
|
207
|
+
*/
|
|
208
|
+
async prepareBuildContributions(): Promise<void> {}
|
|
209
|
+
|
|
210
|
+
/**
|
|
211
|
+
* Performs runtime-only integration setup after config build has already
|
|
212
|
+
* sealed manifest contributions.
|
|
213
|
+
*/
|
|
172
214
|
async setup(): Promise<void> {
|
|
173
215
|
if (this.integrationDependencies.length === 0) return;
|
|
174
216
|
if (!this.assetProcessingService) throw new Error(INTEGRATION_PLUGIN_ERRORS.NOT_INITIALIZED_WITH_ASSET_SERVICE);
|