@ecopages/core 0.2.0-alpha.5 → 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 +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,267 @@
|
|
|
1
|
+
import assert from 'node:assert/strict';
|
|
2
|
+
import fs from 'node:fs';
|
|
3
|
+
import os from 'node:os';
|
|
4
|
+
import path from 'node:path';
|
|
5
|
+
import { afterEach, test, vi } from 'vitest';
|
|
6
|
+
import { ConfigBuilder } from '../../config/config-builder.ts';
|
|
7
|
+
import { resolveInternalExecutionDir, resolveInternalWorkDir } from '../../utils/resolve-work-dir.ts';
|
|
8
|
+
import { HmrManager } from './hmr-manager.ts';
|
|
9
|
+
|
|
10
|
+
const tempRoots: string[] = [];
|
|
11
|
+
|
|
12
|
+
function createTempRoot(prefix: string): string {
|
|
13
|
+
const root = fs.mkdtempSync(path.join(os.tmpdir(), `${prefix}-`));
|
|
14
|
+
tempRoots.push(root);
|
|
15
|
+
return root;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
afterEach(() => {
|
|
19
|
+
for (const root of tempRoots.splice(0)) {
|
|
20
|
+
fs.rmSync(root, { recursive: true, force: true });
|
|
21
|
+
}
|
|
22
|
+
vi.restoreAllMocks();
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
test('HmrManager shares one in-flight entrypoint registration across concurrent callers', async () => {
|
|
26
|
+
const rootDir = createTempRoot('ecopages-bun-hmr-register');
|
|
27
|
+
const srcDir = path.join(rootDir, 'src');
|
|
28
|
+
const pagesDir = path.join(srcDir, 'pages');
|
|
29
|
+
fs.mkdirSync(pagesDir, { recursive: true });
|
|
30
|
+
|
|
31
|
+
const entrypointPath = path.join(pagesDir, 'react-lab.tsx');
|
|
32
|
+
fs.writeFileSync(entrypointPath, 'export default function Page() { return null; }', 'utf8');
|
|
33
|
+
|
|
34
|
+
const config = await new ConfigBuilder().setRootDir(rootDir).build();
|
|
35
|
+
const manager = new HmrManager({
|
|
36
|
+
appConfig: config,
|
|
37
|
+
bridge: {
|
|
38
|
+
subscriberCount: 0,
|
|
39
|
+
broadcast: () => {},
|
|
40
|
+
subscribe: () => {},
|
|
41
|
+
unsubscribe: () => {},
|
|
42
|
+
} as any,
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
const relativePathJs = path
|
|
46
|
+
.relative(config.absolutePaths.srcDir, entrypointPath)
|
|
47
|
+
.replace(/\.(tsx?|jsx?|mdx?)$/, '.js');
|
|
48
|
+
const encodedPathJs = relativePathJs.replace(/\[([^\]]+)\]/g, '_$1_');
|
|
49
|
+
const outputPath = path.join(resolveInternalWorkDir(config), 'assets', '_hmr', encodedPathJs);
|
|
50
|
+
|
|
51
|
+
const handleFileChange = vi.spyOn(manager, 'handleFileChange').mockImplementation(async () => {
|
|
52
|
+
await new Promise((resolve) => setTimeout(resolve, 25));
|
|
53
|
+
fs.mkdirSync(path.dirname(outputPath), { recursive: true });
|
|
54
|
+
fs.writeFileSync(outputPath, 'export default 1;', 'utf8');
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
const [firstUrl, secondUrl] = await Promise.all([
|
|
58
|
+
manager.registerEntrypoint(entrypointPath),
|
|
59
|
+
manager.registerEntrypoint(entrypointPath),
|
|
60
|
+
]);
|
|
61
|
+
|
|
62
|
+
assert.equal(firstUrl, '/assets/_hmr/pages/react-lab.js');
|
|
63
|
+
assert.equal(secondUrl, '/assets/_hmr/pages/react-lab.js');
|
|
64
|
+
assert.equal(handleFileChange.mock.calls.length, 1);
|
|
65
|
+
assert.equal(fs.existsSync(outputPath), true);
|
|
66
|
+
|
|
67
|
+
manager.stop();
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
test('HmrManager clears timed-out entrypoint registrations so later requests can retry', async () => {
|
|
71
|
+
const rootDir = createTempRoot('ecopages-bun-hmr-timeout-register');
|
|
72
|
+
const srcDir = path.join(rootDir, 'src');
|
|
73
|
+
const pagesDir = path.join(srcDir, 'pages');
|
|
74
|
+
fs.mkdirSync(pagesDir, { recursive: true });
|
|
75
|
+
|
|
76
|
+
const entrypointPath = path.join(pagesDir, 'stuck-page.tsx');
|
|
77
|
+
fs.writeFileSync(entrypointPath, 'export default function Page() { return null; }', 'utf8');
|
|
78
|
+
|
|
79
|
+
const config = await new ConfigBuilder().setRootDir(rootDir).build();
|
|
80
|
+
const manager = new HmrManager({
|
|
81
|
+
appConfig: config,
|
|
82
|
+
bridge: {
|
|
83
|
+
subscriberCount: 0,
|
|
84
|
+
broadcast: () => {},
|
|
85
|
+
subscribe: () => {},
|
|
86
|
+
unsubscribe: () => {},
|
|
87
|
+
} as any,
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
const previousNodeEnv = process.env.NODE_ENV;
|
|
91
|
+
process.env.NODE_ENV = 'development';
|
|
92
|
+
|
|
93
|
+
const handleFileChange = vi.spyOn(manager, 'handleFileChange').mockImplementation(async () => {
|
|
94
|
+
await new Promise(() => undefined);
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
try {
|
|
98
|
+
await assert.rejects(() => manager.registerEntrypoint(entrypointPath), /Timed out registering entrypoint/);
|
|
99
|
+
|
|
100
|
+
const registrations = (manager as unknown as { entrypointRegistrations: Map<string, Promise<string>> })
|
|
101
|
+
.entrypointRegistrations;
|
|
102
|
+
const watchedFiles = manager.getWatchedFiles();
|
|
103
|
+
assert.equal(registrations.size, 0);
|
|
104
|
+
assert.equal(watchedFiles.has(entrypointPath), false);
|
|
105
|
+
|
|
106
|
+
handleFileChange.mockImplementationOnce(async () => {
|
|
107
|
+
const relativePathJs = path
|
|
108
|
+
.relative(config.absolutePaths.srcDir, entrypointPath)
|
|
109
|
+
.replace(/\.(tsx?|jsx?|mdx?)$/, '.js');
|
|
110
|
+
const encodedPathJs = relativePathJs.replace(/\[([^\]]+)\]/g, '_$1_');
|
|
111
|
+
const outputPath = path.join(resolveInternalWorkDir(config), 'assets', '_hmr', encodedPathJs);
|
|
112
|
+
fs.mkdirSync(path.dirname(outputPath), { recursive: true });
|
|
113
|
+
fs.writeFileSync(outputPath, 'export default 2;', 'utf8');
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
const retriedUrl = await manager.registerEntrypoint(entrypointPath);
|
|
117
|
+
assert.equal(retriedUrl, '/assets/_hmr/pages/stuck-page.js');
|
|
118
|
+
assert.equal(watchedFiles.get(entrypointPath), retriedUrl);
|
|
119
|
+
} finally {
|
|
120
|
+
process.env.NODE_ENV = previousNodeEnv;
|
|
121
|
+
manager.stop();
|
|
122
|
+
}
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
test('HmrManager fails strict entrypoint registration when the owning integration emits no output', async () => {
|
|
126
|
+
const rootDir = createTempRoot('ecopages-bun-hmr-strict-fail');
|
|
127
|
+
const srcDir = path.join(rootDir, 'src');
|
|
128
|
+
const pagesDir = path.join(srcDir, 'pages');
|
|
129
|
+
fs.mkdirSync(pagesDir, { recursive: true });
|
|
130
|
+
|
|
131
|
+
const entrypointPath = path.join(pagesDir, 'react-content.mdx');
|
|
132
|
+
fs.writeFileSync(entrypointPath, '# Hello', 'utf8');
|
|
133
|
+
|
|
134
|
+
const config = await new ConfigBuilder().setRootDir(rootDir).build();
|
|
135
|
+
const manager = new HmrManager({
|
|
136
|
+
appConfig: config,
|
|
137
|
+
bridge: {
|
|
138
|
+
subscriberCount: 0,
|
|
139
|
+
broadcast: () => {},
|
|
140
|
+
subscribe: () => {},
|
|
141
|
+
unsubscribe: () => {},
|
|
142
|
+
} as any,
|
|
143
|
+
});
|
|
144
|
+
|
|
145
|
+
vi.spyOn(manager, 'handleFileChange').mockImplementation(async () => {});
|
|
146
|
+
|
|
147
|
+
await assert.rejects(() => manager.registerEntrypoint(entrypointPath), /Integration failed to emit entrypoint/);
|
|
148
|
+
assert.equal(manager.getWatchedFiles().has(path.resolve(entrypointPath)), false);
|
|
149
|
+
|
|
150
|
+
manager.stop();
|
|
151
|
+
});
|
|
152
|
+
|
|
153
|
+
test('HmrManager uses the generic build path for script entrypoints when no strategy emits output', async () => {
|
|
154
|
+
const rootDir = createTempRoot('ecopages-bun-hmr-script-fallback');
|
|
155
|
+
const srcDir = path.join(rootDir, 'src');
|
|
156
|
+
fs.mkdirSync(srcDir, { recursive: true });
|
|
157
|
+
|
|
158
|
+
const entrypointPath = path.join(srcDir, 'script.ts');
|
|
159
|
+
fs.writeFileSync(entrypointPath, 'console.log("hello");', 'utf8');
|
|
160
|
+
|
|
161
|
+
const config = await new ConfigBuilder().setRootDir(rootDir).build();
|
|
162
|
+
const manager = new HmrManager({
|
|
163
|
+
appConfig: config,
|
|
164
|
+
bridge: {
|
|
165
|
+
subscriberCount: 0,
|
|
166
|
+
broadcast: () => {},
|
|
167
|
+
subscribe: () => {},
|
|
168
|
+
unsubscribe: () => {},
|
|
169
|
+
} as any,
|
|
170
|
+
});
|
|
171
|
+
|
|
172
|
+
const outputPath = path.join(resolveInternalWorkDir(config), 'assets', '_hmr', 'script.js');
|
|
173
|
+
const buildCalls: string[] = [];
|
|
174
|
+
config.runtime!.buildExecutor = {
|
|
175
|
+
build: vi.fn(async (options) => {
|
|
176
|
+
buildCalls.push(options.entrypoints[0] as string);
|
|
177
|
+
fs.mkdirSync(path.dirname(outputPath), { recursive: true });
|
|
178
|
+
fs.writeFileSync(outputPath, 'fresh-output', 'utf8');
|
|
179
|
+
|
|
180
|
+
return {
|
|
181
|
+
success: true,
|
|
182
|
+
logs: [],
|
|
183
|
+
outputs: [{ path: outputPath }],
|
|
184
|
+
};
|
|
185
|
+
}),
|
|
186
|
+
};
|
|
187
|
+
|
|
188
|
+
vi.spyOn(manager, 'handleFileChange').mockImplementation(async () => {});
|
|
189
|
+
|
|
190
|
+
const outputUrl = await manager.registerScriptEntrypoint(entrypointPath);
|
|
191
|
+
|
|
192
|
+
assert.equal(outputUrl, '/assets/_hmr/script.js');
|
|
193
|
+
assert.deepEqual(buildCalls, [entrypointPath]);
|
|
194
|
+
assert.equal(fs.readFileSync(outputPath, 'utf8'), 'fresh-output');
|
|
195
|
+
|
|
196
|
+
manager.stop();
|
|
197
|
+
});
|
|
198
|
+
|
|
199
|
+
test('HmrManager stop clears retained registration state', async () => {
|
|
200
|
+
const rootDir = createTempRoot('ecopages-bun-hmr-stop-cleanup');
|
|
201
|
+
const srcDir = path.join(rootDir, 'src');
|
|
202
|
+
const pagesDir = path.join(srcDir, 'pages');
|
|
203
|
+
fs.mkdirSync(pagesDir, { recursive: true });
|
|
204
|
+
|
|
205
|
+
const entrypointPath = path.join(pagesDir, 'react-content.tsx');
|
|
206
|
+
fs.writeFileSync(entrypointPath, 'export default function Page() { return null; }', 'utf8');
|
|
207
|
+
|
|
208
|
+
const config = await new ConfigBuilder().setRootDir(rootDir).build();
|
|
209
|
+
const manager = new HmrManager({
|
|
210
|
+
appConfig: config,
|
|
211
|
+
bridge: {
|
|
212
|
+
subscriberCount: 0,
|
|
213
|
+
broadcast: () => {},
|
|
214
|
+
subscribe: () => {},
|
|
215
|
+
unsubscribe: () => {},
|
|
216
|
+
} as any,
|
|
217
|
+
});
|
|
218
|
+
|
|
219
|
+
const relativePathJs = path
|
|
220
|
+
.relative(config.absolutePaths.srcDir, entrypointPath)
|
|
221
|
+
.replace(/\.(tsx?|jsx?|mdx?)$/, '.js');
|
|
222
|
+
const encodedPathJs = relativePathJs.replace(/\[([^\]]+)\]/g, '_$1_');
|
|
223
|
+
const outputPath = path.join(resolveInternalWorkDir(config), 'assets', '_hmr', encodedPathJs);
|
|
224
|
+
|
|
225
|
+
vi.spyOn(manager, 'handleFileChange').mockImplementation(async () => {
|
|
226
|
+
fs.mkdirSync(path.dirname(outputPath), { recursive: true });
|
|
227
|
+
fs.writeFileSync(outputPath, 'export default 1;', 'utf8');
|
|
228
|
+
});
|
|
229
|
+
|
|
230
|
+
manager.registerSpecifierMap({ react: '/assets/vendors/react.js' });
|
|
231
|
+
await manager.registerEntrypoint(entrypointPath);
|
|
232
|
+
|
|
233
|
+
manager.stop();
|
|
234
|
+
|
|
235
|
+
assert.equal(manager.getWatchedFiles().size, 0);
|
|
236
|
+
assert.equal(manager.getSpecifierMap().size, 0);
|
|
237
|
+
});
|
|
238
|
+
|
|
239
|
+
test('HmrManager keeps internal browser and server-module outputs out of distDir', async () => {
|
|
240
|
+
const rootDir = createTempRoot('ecopages-bun-hmr-internal-paths');
|
|
241
|
+
const config = await new ConfigBuilder().setRootDir(rootDir).build();
|
|
242
|
+
const manager = new HmrManager({
|
|
243
|
+
appConfig: config,
|
|
244
|
+
bridge: {
|
|
245
|
+
subscriberCount: 0,
|
|
246
|
+
broadcast: () => {},
|
|
247
|
+
subscribe: () => {},
|
|
248
|
+
unsubscribe: () => {},
|
|
249
|
+
} as any,
|
|
250
|
+
});
|
|
251
|
+
|
|
252
|
+
assert.equal(manager.getDistDir(), path.join(resolveInternalWorkDir(config), 'assets', '_hmr'));
|
|
253
|
+
|
|
254
|
+
const importModule = vi.fn(async (_options: { outdir: string }) => ({}));
|
|
255
|
+
(manager as unknown as { serverModuleTranspiler: { importModule: typeof importModule } }).serverModuleTranspiler = {
|
|
256
|
+
importModule,
|
|
257
|
+
};
|
|
258
|
+
|
|
259
|
+
await manager.getDefaultContext().importServerModule(path.join(config.absolutePaths.srcDir, 'pages', 'index.tsx'));
|
|
260
|
+
|
|
261
|
+
assert.equal(
|
|
262
|
+
importModule.mock.calls[0]?.[0]?.outdir,
|
|
263
|
+
path.join(resolveInternalExecutionDir(config), '.server-modules'),
|
|
264
|
+
);
|
|
265
|
+
|
|
266
|
+
manager.stop();
|
|
267
|
+
});
|
|
@@ -2,16 +2,27 @@ import fs from 'node:fs';
|
|
|
2
2
|
import path from 'node:path';
|
|
3
3
|
import type { ServerWebSocket, WebSocketHandler } from 'bun';
|
|
4
4
|
import { RESOLVED_ASSETS_DIR } from '../../constants';
|
|
5
|
-
import {
|
|
5
|
+
import { getAppBuildExecutor } from '../../build/build-adapter.ts';
|
|
6
6
|
import type { DefaultHmrContext, EcoPagesAppConfig, IHmrManager } from '../../internal-types';
|
|
7
7
|
import type { EcoBuildPlugin } from '../../build/build-types.ts';
|
|
8
8
|
import { fileSystem } from '@ecopages/file-system';
|
|
9
|
-
import type
|
|
9
|
+
import { HmrStrategyType, type HmrStrategy } from '../../hmr/hmr-strategy';
|
|
10
10
|
import { DefaultHmrStrategy } from '../../hmr/strategies/default-hmr-strategy';
|
|
11
11
|
import { JsHmrStrategy } from '../../hmr/strategies/js-hmr-strategy';
|
|
12
12
|
import { appLogger } from '../../global/app-logger';
|
|
13
13
|
import type { ClientBridge } from './client-bridge';
|
|
14
14
|
import type { ClientBridgeEvent } from '../../public-types';
|
|
15
|
+
import { HmrEntrypointRegistrar } from '../shared/hmr-entrypoint-registrar.ts';
|
|
16
|
+
import { BrowserBundleService } from '../../services/assets/browser-bundle.service.ts';
|
|
17
|
+
import { getAppServerModuleTranspiler } from '../../services/module-loading/app-server-module-transpiler.service';
|
|
18
|
+
import {
|
|
19
|
+
getAppEntrypointDependencyGraph,
|
|
20
|
+
NoopEntrypointDependencyGraph,
|
|
21
|
+
setAppEntrypointDependencyGraph,
|
|
22
|
+
} from '../../services/runtime-state/entrypoint-dependency-graph.service.ts';
|
|
23
|
+
import { getAppRuntimeSpecifierRegistry } from '../../services/runtime-state/runtime-specifier-registry.service.ts';
|
|
24
|
+
import type { ServerModuleTranspiler } from '../../services/module-loading/server-module-transpiler.service';
|
|
25
|
+
import { resolveInternalExecutionDir, resolveInternalWorkDir } from '../../utils/resolve-work-dir.ts';
|
|
15
26
|
|
|
16
27
|
type BunSocket = ServerWebSocket<unknown>;
|
|
17
28
|
type BunSocketHandler = WebSocketHandler<unknown>;
|
|
@@ -21,19 +32,36 @@ export interface HmrManagerParams {
|
|
|
21
32
|
bridge: ClientBridge;
|
|
22
33
|
}
|
|
23
34
|
|
|
35
|
+
type HandleFileChangeOptions = {
|
|
36
|
+
broadcast?: boolean;
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Bun development HMR manager.
|
|
41
|
+
*
|
|
42
|
+
* @remarks
|
|
43
|
+
* Bun shares the same public contract as the Node manager: page entrypoints are
|
|
44
|
+
* strict integration-owned registrations, while generic script assets use their
|
|
45
|
+
* own explicit registration path.
|
|
46
|
+
*/
|
|
24
47
|
export class HmrManager implements IHmrManager {
|
|
48
|
+
private static readonly entrypointRegistrationTimeoutMs = 4000;
|
|
25
49
|
public readonly appConfig: EcoPagesAppConfig;
|
|
26
50
|
private readonly bridge: ClientBridge;
|
|
27
51
|
/** Keep track of watchers */
|
|
28
52
|
private watchers = new Map<string, fs.FSWatcher>();
|
|
29
53
|
/** entrypoint -> output path */
|
|
30
54
|
private watchedFiles = new Map<string, string>();
|
|
31
|
-
|
|
32
|
-
private specifierMap = new Map<string, string>();
|
|
55
|
+
private entrypointRegistrations = new Map<string, Promise<string>>();
|
|
33
56
|
private distDir: string;
|
|
34
57
|
private plugins: EcoBuildPlugin[] = [];
|
|
35
58
|
private enabled = true;
|
|
36
59
|
private strategies: HmrStrategy[] = [];
|
|
60
|
+
private readonly entrypointRegistrar: HmrEntrypointRegistrar;
|
|
61
|
+
private readonly browserBundleService: BrowserBundleService;
|
|
62
|
+
private readonly entrypointDependencyGraph: ReturnType<typeof getAppEntrypointDependencyGraph>;
|
|
63
|
+
private readonly runtimeSpecifierRegistry: ReturnType<typeof getAppRuntimeSpecifierRegistry>;
|
|
64
|
+
private readonly serverModuleTranspiler: ServerModuleTranspiler;
|
|
37
65
|
private wsHandler!: {
|
|
38
66
|
open: (ws: BunSocket) => void;
|
|
39
67
|
close: (ws: BunSocket) => void;
|
|
@@ -42,7 +70,24 @@ export class HmrManager implements IHmrManager {
|
|
|
42
70
|
constructor({ appConfig, bridge }: HmrManagerParams) {
|
|
43
71
|
this.appConfig = appConfig;
|
|
44
72
|
this.bridge = bridge;
|
|
45
|
-
this.distDir = path.join(this.appConfig
|
|
73
|
+
this.distDir = path.join(resolveInternalWorkDir(this.appConfig), RESOLVED_ASSETS_DIR, '_hmr');
|
|
74
|
+
this.entrypointRegistrar = new HmrEntrypointRegistrar({
|
|
75
|
+
srcDir: this.appConfig.absolutePaths.srcDir,
|
|
76
|
+
distDir: this.distDir,
|
|
77
|
+
entrypointRegistrations: this.entrypointRegistrations,
|
|
78
|
+
watchedFiles: this.watchedFiles,
|
|
79
|
+
clearFailedRegistration: (entrypointPath) => this.clearFailedEntrypointRegistration(entrypointPath),
|
|
80
|
+
registrationTimeoutMs: HmrManager.entrypointRegistrationTimeoutMs,
|
|
81
|
+
});
|
|
82
|
+
this.browserBundleService = new BrowserBundleService(appConfig);
|
|
83
|
+
const existingEntrypointDependencyGraph = getAppEntrypointDependencyGraph(appConfig);
|
|
84
|
+
this.entrypointDependencyGraph =
|
|
85
|
+
existingEntrypointDependencyGraph instanceof NoopEntrypointDependencyGraph
|
|
86
|
+
? existingEntrypointDependencyGraph
|
|
87
|
+
: new NoopEntrypointDependencyGraph();
|
|
88
|
+
setAppEntrypointDependencyGraph(this.appConfig, this.entrypointDependencyGraph);
|
|
89
|
+
this.runtimeSpecifierRegistry = getAppRuntimeSpecifierRegistry(this.appConfig);
|
|
90
|
+
this.serverModuleTranspiler = getAppServerModuleTranspiler(this.appConfig);
|
|
46
91
|
this.cleanDistDir();
|
|
47
92
|
this.initializeStrategies();
|
|
48
93
|
}
|
|
@@ -57,6 +102,29 @@ export class HmrManager implements IHmrManager {
|
|
|
57
102
|
fileSystem.ensureDir(this.distDir);
|
|
58
103
|
}
|
|
59
104
|
|
|
105
|
+
/**
|
|
106
|
+
* Returns whether the generic JS strategy may rebuild an entrypoint.
|
|
107
|
+
*
|
|
108
|
+
* @remarks
|
|
109
|
+
* Integration-owned page entrypoints are excluded so a shared dependency
|
|
110
|
+
* invalidation cannot replace framework-owned browser output with a generic JS
|
|
111
|
+
* rebuild.
|
|
112
|
+
*/
|
|
113
|
+
private shouldJsStrategyProcessEntrypoint(entrypointPath: string): boolean {
|
|
114
|
+
return !this.strategies.some((strategy) => {
|
|
115
|
+
if (strategy.type !== HmrStrategyType.INTEGRATION || strategy.priority <= HmrStrategyType.SCRIPT) {
|
|
116
|
+
return false;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
try {
|
|
120
|
+
return strategy.matches(entrypointPath);
|
|
121
|
+
} catch (error) {
|
|
122
|
+
appLogger.error(error);
|
|
123
|
+
return false;
|
|
124
|
+
}
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
|
|
60
128
|
/**
|
|
61
129
|
* Initializes core HMR strategies.
|
|
62
130
|
* Strategies are evaluated in priority order (highest first).
|
|
@@ -64,10 +132,16 @@ export class HmrManager implements IHmrManager {
|
|
|
64
132
|
private initializeStrategies(): void {
|
|
65
133
|
const jsContext = {
|
|
66
134
|
getWatchedFiles: () => this.watchedFiles,
|
|
67
|
-
getSpecifierMap: () => this.
|
|
135
|
+
getSpecifierMap: () => this.runtimeSpecifierRegistry.getAll(),
|
|
68
136
|
getDistDir: () => this.distDir,
|
|
69
137
|
getPlugins: () => this.plugins,
|
|
70
138
|
getSrcDir: () => this.appConfig.absolutePaths.srcDir,
|
|
139
|
+
getPagesDir: () => this.appConfig.absolutePaths.pagesDir,
|
|
140
|
+
getLayoutsDir: () => this.appConfig.absolutePaths.layoutsDir,
|
|
141
|
+
getTemplateExtensions: () => this.appConfig.templatesExt,
|
|
142
|
+
getBrowserBundleService: () => this.browserBundleService,
|
|
143
|
+
getEntrypointDependencyGraph: () => this.entrypointDependencyGraph,
|
|
144
|
+
shouldProcessEntrypoint: (entrypointPath: string) => this.shouldJsStrategyProcessEntrypoint(entrypointPath),
|
|
71
145
|
};
|
|
72
146
|
|
|
73
147
|
this.strategies = [new JsHmrStrategy(jsContext), new DefaultHmrStrategy()];
|
|
@@ -95,14 +169,16 @@ export class HmrManager implements IHmrManager {
|
|
|
95
169
|
}
|
|
96
170
|
|
|
97
171
|
/**
|
|
98
|
-
* Registers
|
|
99
|
-
*
|
|
100
|
-
* @
|
|
172
|
+
* Registers runtime bare-specifier mappings exposed by integrations.
|
|
173
|
+
*
|
|
174
|
+
* @remarks
|
|
175
|
+
* These mappings are consumed by framework-owned HMR strategies that preserve
|
|
176
|
+
* shared runtime imports in browser bundles. The registry stays generic so
|
|
177
|
+
* these mappings can later support broader import-map-style runtime features
|
|
178
|
+
* without moving integration semantics into core.
|
|
101
179
|
*/
|
|
102
180
|
public registerSpecifierMap(map: Record<string, string>): void {
|
|
103
|
-
|
|
104
|
-
this.specifierMap.set(specifier, url);
|
|
105
|
-
}
|
|
181
|
+
this.runtimeSpecifierRegistry.register(map);
|
|
106
182
|
}
|
|
107
183
|
|
|
108
184
|
public getWebSocketHandler(): BunSocketHandler {
|
|
@@ -133,12 +209,12 @@ export class HmrManager implements IHmrManager {
|
|
|
133
209
|
public async buildRuntime(): Promise<void> {
|
|
134
210
|
const runtimeSource = path.resolve(import.meta.dirname, '../../hmr/client/hmr-runtime.ts');
|
|
135
211
|
|
|
136
|
-
const result = await
|
|
212
|
+
const result = await this.browserBundleService.bundle({
|
|
213
|
+
profile: 'hmr-runtime',
|
|
137
214
|
entrypoints: [runtimeSource],
|
|
138
215
|
outdir: this.distDir,
|
|
139
216
|
naming: '_hmr_runtime.js',
|
|
140
217
|
minify: false,
|
|
141
|
-
...defaultBuildAdapter.getTranspileOptions('hmr-runtime'),
|
|
142
218
|
plugins: this.plugins,
|
|
143
219
|
});
|
|
144
220
|
|
|
@@ -158,7 +234,7 @@ export class HmrManager implements IHmrManager {
|
|
|
158
234
|
this.bridge.broadcast(event);
|
|
159
235
|
}
|
|
160
236
|
|
|
161
|
-
public async handleFileChange(filePath: string): Promise<void> {
|
|
237
|
+
public async handleFileChange(filePath: string, options: HandleFileChangeOptions = {}): Promise<void> {
|
|
162
238
|
const sorted = [...this.strategies].sort((a, b) => b.priority - a.priority);
|
|
163
239
|
const strategy = sorted.find((s) => {
|
|
164
240
|
try {
|
|
@@ -177,8 +253,9 @@ export class HmrManager implements IHmrManager {
|
|
|
177
253
|
appLogger.debug(`[HmrManager] Selected strategy: ${strategy.constructor.name}`);
|
|
178
254
|
|
|
179
255
|
const action = await strategy.process(filePath);
|
|
256
|
+
const shouldBroadcast = options.broadcast ?? true;
|
|
180
257
|
|
|
181
|
-
if (action.type === 'broadcast') {
|
|
258
|
+
if (shouldBroadcast && action.type === 'broadcast') {
|
|
182
259
|
if (action.events) {
|
|
183
260
|
for (const event of action.events) {
|
|
184
261
|
this.broadcast(event);
|
|
@@ -187,9 +264,6 @@ export class HmrManager implements IHmrManager {
|
|
|
187
264
|
}
|
|
188
265
|
}
|
|
189
266
|
|
|
190
|
-
/**
|
|
191
|
-
* Registers a client entrypoint to be built and watched by Bun.
|
|
192
|
-
*/
|
|
193
267
|
public getOutputUrl(entrypointPath: string): string | undefined {
|
|
194
268
|
return this.watchedFiles.get(entrypointPath);
|
|
195
269
|
}
|
|
@@ -199,7 +273,7 @@ export class HmrManager implements IHmrManager {
|
|
|
199
273
|
}
|
|
200
274
|
|
|
201
275
|
public getSpecifierMap(): Map<string, string> {
|
|
202
|
-
return this.
|
|
276
|
+
return this.runtimeSpecifierRegistry.getAll();
|
|
203
277
|
}
|
|
204
278
|
|
|
205
279
|
public getDistDir(): string {
|
|
@@ -213,64 +287,123 @@ export class HmrManager implements IHmrManager {
|
|
|
213
287
|
public getDefaultContext(): DefaultHmrContext {
|
|
214
288
|
return {
|
|
215
289
|
getWatchedFiles: () => this.watchedFiles,
|
|
216
|
-
getSpecifierMap: () => this.
|
|
290
|
+
getSpecifierMap: () => this.runtimeSpecifierRegistry.getAll(),
|
|
217
291
|
getDistDir: () => this.distDir,
|
|
218
292
|
getPlugins: () => this.plugins,
|
|
219
293
|
getSrcDir: () => this.appConfig.absolutePaths.srcDir,
|
|
220
294
|
getLayoutsDir: () => this.appConfig.absolutePaths.layoutsDir,
|
|
221
295
|
getPagesDir: () => this.appConfig.absolutePaths.pagesDir,
|
|
296
|
+
getBuildExecutor: () => getAppBuildExecutor(this.appConfig),
|
|
297
|
+
getBrowserBundleService: () => this.browserBundleService,
|
|
298
|
+
importServerModule: async <T>(filePath: string) =>
|
|
299
|
+
await this.serverModuleTranspiler.importModule<T>({
|
|
300
|
+
filePath,
|
|
301
|
+
outdir: path.join(resolveInternalExecutionDir(this.appConfig), '.server-modules'),
|
|
302
|
+
externalPackages: true,
|
|
303
|
+
}),
|
|
222
304
|
};
|
|
223
305
|
}
|
|
224
306
|
|
|
307
|
+
private clearFailedEntrypointRegistration(entrypointPath: string): void {
|
|
308
|
+
this.watchedFiles.delete(entrypointPath);
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
/**
|
|
312
|
+
* Registers one integration-owned page entrypoint.
|
|
313
|
+
*
|
|
314
|
+
* @remarks
|
|
315
|
+
* Concurrent callers share one in-flight registration. The registration is
|
|
316
|
+
* cleared from the dedupe map when it settles so later callers cannot inherit a
|
|
317
|
+
* stale promise.
|
|
318
|
+
*/
|
|
225
319
|
public async registerEntrypoint(entrypointPath: string): Promise<string> {
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
320
|
+
return await this.entrypointRegistrar.registerEntrypoint(entrypointPath, {
|
|
321
|
+
emit: async (normalizedEntrypoint, outputPath) =>
|
|
322
|
+
await this.emitStrictEntrypoint(normalizedEntrypoint, outputPath),
|
|
323
|
+
getMissingOutputError: (normalizedEntrypoint, outputPath) =>
|
|
324
|
+
new Error(
|
|
325
|
+
`[HMR] Integration failed to emit entrypoint ${normalizedEntrypoint} to ${outputPath}. Page entrypoints must be produced by their owning integration.`,
|
|
326
|
+
),
|
|
327
|
+
});
|
|
328
|
+
}
|
|
229
329
|
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
330
|
+
/**
|
|
331
|
+
* Registers one generic script entrypoint.
|
|
332
|
+
*
|
|
333
|
+
* @remarks
|
|
334
|
+
* This explicit path keeps the page-entrypoint contract strict while still
|
|
335
|
+
* allowing generic script assets to use the fallback build path.
|
|
336
|
+
*/
|
|
337
|
+
public async registerScriptEntrypoint(entrypointPath: string): Promise<string> {
|
|
338
|
+
return await this.entrypointRegistrar.registerEntrypoint(entrypointPath, {
|
|
339
|
+
emit: async (normalizedEntrypoint, outputPath) =>
|
|
340
|
+
await this.emitScriptEntrypoint(normalizedEntrypoint, outputPath),
|
|
341
|
+
getMissingOutputError: (normalizedEntrypoint) =>
|
|
342
|
+
new Error(`[HMR] Failed to register script entrypoint: ${normalizedEntrypoint}`),
|
|
343
|
+
});
|
|
344
|
+
}
|
|
234
345
|
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
346
|
+
/**
|
|
347
|
+
* Performs strict integration-owned registration for one normalized path.
|
|
348
|
+
*
|
|
349
|
+
* @remarks
|
|
350
|
+
* The manager reserves the output URL, removes any stale emitted file, runs
|
|
351
|
+
* strategy processing without broadcasting, and then verifies that the owning
|
|
352
|
+
* integration emitted the expected file.
|
|
353
|
+
*/
|
|
354
|
+
private async emitStrictEntrypoint(entrypointPath: string, _outputPath: string): Promise<void> {
|
|
355
|
+
await this.handleFileChange(entrypointPath, { broadcast: false });
|
|
356
|
+
}
|
|
238
357
|
|
|
239
|
-
|
|
358
|
+
/**
|
|
359
|
+
* Performs registration for a generic script asset.
|
|
360
|
+
*
|
|
361
|
+
* @remarks
|
|
362
|
+
* Strategies get the first chance to emit output. If no output exists after
|
|
363
|
+
* that pass, Bun falls back to the generic browser build for this explicit
|
|
364
|
+
* script-only path.
|
|
365
|
+
*/
|
|
366
|
+
private async emitScriptEntrypoint(entrypointPath: string, outputPath: string): Promise<void> {
|
|
367
|
+
const naming = path.relative(this.distDir, outputPath).split(path.sep).join('/');
|
|
240
368
|
|
|
241
|
-
await this.handleFileChange(entrypointPath);
|
|
369
|
+
await this.handleFileChange(entrypointPath, { broadcast: false });
|
|
242
370
|
|
|
243
371
|
if (!fileSystem.exists(outputPath)) {
|
|
244
|
-
const
|
|
372
|
+
const buildResult = await this.browserBundleService.bundle({
|
|
373
|
+
profile: 'hmr-entrypoint',
|
|
245
374
|
entrypoints: [entrypointPath],
|
|
246
375
|
outdir: this.distDir,
|
|
247
|
-
naming
|
|
376
|
+
naming,
|
|
248
377
|
minify: false,
|
|
249
|
-
external: Array.from(this.specifierMap.keys()),
|
|
250
|
-
...defaultBuildAdapter.getTranspileOptions('hmr-entrypoint'),
|
|
251
378
|
plugins: this.plugins,
|
|
252
379
|
});
|
|
253
380
|
|
|
254
|
-
if (!
|
|
255
|
-
appLogger.error(
|
|
381
|
+
if (!buildResult.success) {
|
|
382
|
+
appLogger.error(
|
|
383
|
+
`[HMR] Generic script entrypoint build failed for ${entrypointPath}:`,
|
|
384
|
+
buildResult.logs,
|
|
385
|
+
);
|
|
256
386
|
}
|
|
257
387
|
}
|
|
258
|
-
|
|
259
|
-
return outputUrl;
|
|
260
388
|
}
|
|
261
389
|
|
|
262
390
|
/**
|
|
263
|
-
*
|
|
264
|
-
*
|
|
391
|
+
* Stops active watchers and releases retained registration state.
|
|
392
|
+
*
|
|
393
|
+
* @remarks
|
|
394
|
+
* Emitted `_hmr` files remain on disk because parallel app processes may share
|
|
395
|
+
* the same dist directory. The in-memory indexes are cleared so stale
|
|
396
|
+
* entrypoints and specifier maps cannot leak through a reused manager object.
|
|
265
397
|
*/
|
|
266
|
-
private encodeDynamicSegments(filepath: string): string {
|
|
267
|
-
return filepath.replace(/\[([^\]]+)\]/g, '_$1_');
|
|
268
|
-
}
|
|
269
|
-
|
|
270
398
|
public stop() {
|
|
399
|
+
this.entrypointRegistrations.clear();
|
|
271
400
|
for (const watcher of this.watchers.values()) {
|
|
272
401
|
watcher.close();
|
|
273
402
|
}
|
|
274
403
|
this.watchers.clear();
|
|
404
|
+
this.watchedFiles.clear();
|
|
405
|
+
this.runtimeSpecifierRegistry.clear();
|
|
406
|
+
this.entrypointDependencyGraph.reset();
|
|
407
|
+
this.plugins = [];
|
|
275
408
|
}
|
|
276
409
|
}
|
|
@@ -1,3 +1,2 @@
|
|
|
1
1
|
export { EcopagesApp, createApp } from './create-app.ts';
|
|
2
|
-
export { defineApiHandler, defineGroupHandler } from '
|
|
3
|
-
export type { GroupHandler } from './define-api-handler.ts';
|
|
2
|
+
export { defineApiHandler, defineGroupHandler, type GroupHandler } from '../shared/define-api-handler.ts';
|