@ecopages/core 0.2.0-beta.30 → 0.2.0-beta.32
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -0
- package/package.json +82 -3
- package/src/adapters/abstract/application-adapter.d.ts +0 -8
- package/src/adapters/abstract/application-adapter.js +252 -261
- package/src/adapters/abstract/router-adapter.js +12 -4
- package/src/adapters/abstract/segment-path-matcher.js +132 -134
- package/src/adapters/abstract/server-adapter.js +22 -14
- package/src/adapters/abstract/ws-pattern-matcher.js +24 -26
- package/src/adapters/bun/bun-user-websocket-lifecycle.js +83 -86
- package/src/adapters/bun/client-bridge.js +51 -50
- package/src/adapters/bun/create-app.js +171 -161
- package/src/adapters/bun/hmr-manager.js +62 -57
- package/src/adapters/bun/index.js +2 -31
- package/src/adapters/bun/runtime-host.js +61 -54
- package/src/adapters/bun/server-adapter.d.ts +0 -1
- package/src/adapters/bun/server-adapter.js +561 -561
- package/src/adapters/bun/static-preview-host.js +43 -46
- package/src/adapters/create-app.js +11 -14
- package/src/adapters/index.js +2 -30
- package/src/adapters/node/create-app.js +123 -129
- package/src/adapters/node/http-request-bridge.js +147 -106
- package/src/adapters/node/node-client-bridge.js +62 -64
- package/src/adapters/node/node-hmr-manager.js +58 -48
- package/src/adapters/node/runtime-host.js +96 -89
- package/src/adapters/node/server-adapter-dependencies.js +18 -21
- package/src/adapters/node/server-adapter.d.ts +0 -1
- package/src/adapters/node/server-adapter.js +347 -326
- package/src/adapters/node/static-content-server.js +172 -191
- package/src/adapters/node/static-preview-host.js +87 -78
- package/src/adapters/shared/hmr/dev-transform-entrypoint-registry.d.ts +16 -0
- package/src/adapters/shared/hmr/dev-transform-entrypoint-registry.js +32 -0
- package/src/adapters/shared/hmr/hmr-html-response.js +46 -32
- package/src/adapters/shared/hmr/shared-hmr-manager.d.ts +29 -38
- package/src/adapters/shared/hmr/shared-hmr-manager.js +439 -425
- package/src/adapters/shared/http/api-request-pipeline.js +122 -119
- package/src/adapters/shared/http/api-response.js +77 -77
- package/src/adapters/shared/http/create-body-response.js +22 -19
- package/src/adapters/shared/http/define-api-handler.js +41 -55
- package/src/adapters/shared/http/explicit-static-render-preparation.js +26 -23
- package/src/adapters/shared/http/explicit-static-route-matcher.js +55 -62
- package/src/adapters/shared/http/file-route-middleware-pipeline.js +81 -75
- package/src/adapters/shared/http/fs-server-response-factory.js +101 -96
- package/src/adapters/shared/http/fs-server-response-matcher.js +239 -257
- package/src/adapters/shared/http/run-middleware-chain.js +15 -15
- package/src/adapters/shared/runtime/application-adapter.js +72 -87
- package/src/adapters/shared/runtime/copy-runtime-public-dir.js +25 -22
- package/src/adapters/shared/runtime/port-manager.js +207 -177
- package/src/adapters/shared/runtime/render-context.js +94 -79
- package/src/adapters/shared/runtime/runtime-app-bootstrap.js +33 -38
- package/src/adapters/shared/runtime/runtime-host.js +1 -0
- package/src/adapters/shared/runtime/runtime-server-lifecycle.d.ts +2 -3
- package/src/adapters/shared/runtime/runtime-server-lifecycle.js +65 -51
- package/src/adapters/shared/runtime/server-adapter.d.ts +1 -0
- package/src/adapters/shared/runtime/server-adapter.js +233 -217
- package/src/adapters/shared/runtime/server-route-handler.js +74 -70
- package/src/adapters/shared/runtime/server-static-builder.js +165 -184
- package/src/adapters/shared/runtime/static-preview-host.js +1 -0
- package/src/adapters/shared/ws/node-http-websocket-upgrades.js +97 -88
- package/src/adapters/shared/ws/websocket-lifecycle.js +57 -50
- package/src/build/README.md +52 -1
- package/src/build/app-build-manifest-runtime.js +129 -108
- package/src/build/browser/browser-runtime-manifest.js +47 -50
- package/src/build/browser/browser-runtime-plugin-helpers.js +32 -12
- package/src/build/browser/browser-runtime-plugin.js +206 -160
- package/src/build/browser/jsx-ownership-plugins.js +51 -37
- package/src/build/browser/lit-static-render-worker-context.js +3 -5
- package/src/build/build-adapter.js +276 -139
- package/src/build/cache/build-input-fingerprint.js +28 -26
- package/src/build/cache/cache-constants.js +4 -6
- package/src/build/cache/cache-keys.js +64 -56
- package/src/build/cache/pages-unified-graph-build.js +179 -178
- package/src/build/cache/production-build-cache.js +47 -54
- package/src/build/cache/server-entry-build-cache.js +134 -146
- package/src/build/contracts/build-contracts.d.ts +4 -4
- package/src/build/contracts/build-contracts.js +1 -0
- package/src/build/contracts/build-manifest.js +58 -43
- package/src/build/contracts/build-types.js +1 -0
- package/src/build/rolldown/rolldown-adapter-helpers.d.ts +9 -0
- package/src/build/rolldown/rolldown-adapter-helpers.js +405 -298
- package/src/build/rolldown/rolldown-build-adapter.js +53 -61
- package/src/build/rolldown/rolldown-build-invocation-metrics.js +31 -35
- package/src/build/rolldown/rolldown-plugin-bridge.js +264 -194
- package/src/build/rolldown/rolldown-source-transform-pass.js +59 -50
- package/src/build/rolldown/runtime-build-output-normalizer.js +227 -175
- package/src/build/rolldown/server-side-css-shim-plugin.js +54 -31
- package/src/build/runtime/build-profile-options.js +36 -36
- package/src/build/runtime/build-request-identity.js +70 -45
- package/src/build/runtime/build-request-policy.js +80 -42
- package/src/build/runtime/build-runtime.js +64 -54
- package/src/build/runtime/deduping-build-executor.js +38 -32
- package/src/build/runtime/parallel-build-executor.js +58 -50
- package/src/build/runtime/serialized-build-executor.js +78 -62
- package/src/cache/index.js +6 -6
- package/src/cache/module-parse-cache.js +99 -68
- package/src/client/navigation-scripts/classification.js +45 -37
- package/src/client/navigation-scripts/index.js +3 -23
- package/src/client/navigation-scripts/navigation-scripts.test.browser.js +58 -62
- package/src/client/navigation-scripts/registry.js +15 -11
- package/src/client/navigation-scripts/rerun-queue.js +81 -64
- package/src/client/scroll.js +32 -24
- package/src/client/scroll.test.browser.js +27 -33
- package/src/client/view-transitions.js +68 -55
- package/src/config/config-builder.d.ts +8 -0
- package/src/config/config-builder.js +637 -642
- package/src/config/constants.js +44 -24
- package/src/declarations.d.ts +1 -0
- package/src/dev/README.md +24 -0
- package/src/dev/client-bridge-registry.js +7 -12
- package/src/dev/dev-client-ownership.js +7 -5
- package/src/dev/hmr-manager-registry.js +7 -12
- package/src/dev/host-runtime.js +25 -30
- package/src/dev/runtime-server-started-message.js +2 -5
- package/src/dev/sc-server.js +106 -103
- package/src/dev/transform-server/dev-transform-bundler.d.ts +24 -0
- package/src/dev/transform-server/dev-transform-bundler.js +79 -0
- package/src/dev/transform-server/dev-transform-externalize-plugin.d.ts +12 -0
- package/src/dev/transform-server/dev-transform-externalize-plugin.js +29 -0
- package/src/dev/transform-server/dev-transform-import-rewriter.d.ts +16 -0
- package/src/dev/transform-server/dev-transform-import-rewriter.js +110 -0
- package/src/dev/transform-server/dev-transform-module-kind.d.ts +13 -0
- package/src/dev/transform-server/dev-transform-module-kind.js +17 -0
- package/src/dev/transform-server/dev-transform-runtime-specifiers.d.ts +5 -0
- package/src/dev/transform-server/dev-transform-runtime-specifiers.js +16 -0
- package/src/dev/transform-server/dev-transform-server.d.ts +41 -0
- package/src/dev/transform-server/dev-transform-server.js +191 -0
- package/src/dev/transform-server/dev-transform-url.d.ts +13 -0
- package/src/dev/transform-server/dev-transform-url.js +58 -0
- package/src/dev/transform-server/dev-transform-vendor-registry.d.ts +27 -0
- package/src/dev/transform-server/dev-transform-vendor-registry.js +145 -0
- package/src/dev/transform-server/index.d.ts +6 -0
- package/src/dev/transform-server/index.js +4 -0
- package/src/dev/transform-server/types.d.ts +15 -0
- package/src/dev/transform-server/types.js +1 -0
- package/src/dev-toolbar/README.md +51 -0
- package/src/dev-toolbar/define-dev-tool.d.ts +21 -0
- package/src/dev-toolbar/define-dev-tool.js +9 -0
- package/src/dev-toolbar/dev-toolbar-config.d.ts +25 -0
- package/src/dev-toolbar/dev-toolbar-config.js +19 -0
- package/src/dev-toolbar/dev-toolbar-host.d.ts +49 -0
- package/src/dev-toolbar/dev-toolbar-host.js +117 -0
- package/src/dev-toolbar/dev-toolbar-html-response.d.ts +11 -0
- package/src/dev-toolbar/dev-toolbar-html-response.js +14 -0
- package/src/dev-toolbar/dev-toolbar-manifest.d.ts +15 -0
- package/src/dev-toolbar/dev-toolbar-manifest.js +52 -0
- package/src/dev-toolbar/dev-toolbar-package.d.ts +31 -0
- package/src/dev-toolbar/dev-toolbar-package.js +72 -0
- package/src/dev-toolbar/dev-toolbar-runtime-paths.d.ts +10 -0
- package/src/dev-toolbar/dev-toolbar-runtime-paths.js +13 -0
- package/src/diagnostics/request-build-dedupe.js +34 -28
- package/src/diagnostics/startup-trace.d.ts +10 -1
- package/src/diagnostics/startup-trace.js +269 -241
- package/src/eco/README.md +6 -0
- package/src/eco/eco-declared-component.js +19 -14
- package/src/eco/eco.browser.js +56 -69
- package/src/eco/eco.js +156 -96
- package/src/eco/eco.types.js +5 -0
- package/src/eco/eco.utils.js +1 -10
- package/src/eco/global-injector-map.js +55 -41
- package/src/eco/lazy-injector-map.js +90 -60
- package/src/eco/module-dependencies.js +52 -44
- package/src/eco/page-layout-normalization.js +59 -49
- package/src/errors/http-error.js +50 -49
- package/src/errors/index.js +3 -12
- package/src/errors/locals-access-error.js +5 -8
- package/src/errors/undeclared-component-dependency-error.js +15 -15
- package/src/global/app-logger.js +3 -6
- package/src/hmr/README.md +10 -0
- package/src/hmr/client/hmr-runtime.js +117 -113
- package/src/hmr/client/module-update.d.ts +13 -0
- package/src/hmr/client/module-update.js +39 -0
- package/src/hmr/hmr-asset-paths.d.ts +14 -0
- package/src/hmr/hmr-asset-paths.js +22 -0
- package/src/hmr/hmr-entrypoint-output.d.ts +11 -39
- package/src/hmr/hmr-entrypoint-output.js +28 -54
- package/src/hmr/hmr-file-change-prep.js +13 -16
- package/src/hmr/hmr-registered-entrypoints-context.d.ts +7 -0
- package/src/hmr/hmr-registered-entrypoints-context.js +1 -0
- package/src/hmr/hmr-runtime-paths.d.ts +10 -0
- package/src/hmr/hmr-runtime-paths.js +13 -0
- package/src/hmr/hmr-strategy.d.ts +5 -11
- package/src/hmr/hmr-strategy.js +113 -61
- package/src/hmr/strategies/default-hmr-strategy.js +55 -33
- package/src/hmr/strategies/js-hmr-strategy.d.ts +6 -95
- package/src/hmr/strategies/js-hmr-strategy.js +104 -217
- package/src/hmr/strategies/server-rendered-template-hmr-strategy.js +33 -27
- package/src/index.browser.js +1 -4
- package/src/index.d.ts +1 -0
- package/src/index.js +6 -47
- package/src/integrations/ghtml/ghtml-renderer.js +12 -7
- package/src/integrations/ghtml/ghtml.constants.js +1 -4
- package/src/integrations/ghtml/ghtml.plugin.js +9 -12
- package/src/islands/README.md +25 -0
- package/src/islands/island-host.d.ts +37 -0
- package/src/islands/island-host.js +55 -0
- package/src/plugins/alias-resolver-cache.js +114 -97
- package/src/plugins/alias-resolver-plugin.js +33 -47
- package/src/plugins/define-integration.js +18 -17
- package/src/plugins/eco-component-meta-plugin.js +387 -145
- package/src/plugins/foreign-jsx-override-plugin.js +49 -35
- package/src/plugins/integration-plugin.js +212 -203
- package/src/plugins/jsx-import-source.utils.js +16 -21
- package/src/plugins/processor.js +159 -149
- package/src/plugins/runtime-capability.js +1 -0
- package/src/plugins/source-transform.js +109 -79
- package/src/plugins/tsconfig-import-resolver.d.ts +17 -0
- package/src/plugins/tsconfig-import-resolver.js +218 -142
- package/src/route-renderer/README.md +12 -1
- package/src/route-renderer/orchestration/document-shell/document-shell-render.service.js +143 -136
- package/src/route-renderer/orchestration/document-shell/layout-shell-props.service.js +33 -27
- package/src/route-renderer/orchestration/foreign-child/component-render-context.js +173 -126
- package/src/route-renderer/orchestration/foreign-child/foreign-child-output.utils.js +165 -154
- package/src/route-renderer/orchestration/foreign-child/foreign-subtree-execution.service.js +329 -341
- package/src/route-renderer/orchestration/foreign-child/owning-renderer-resolution.js +33 -32
- package/src/route-renderer/orchestration/integration-renderer.d.ts +1 -0
- package/src/route-renderer/orchestration/integration-renderer.js +731 -750
- package/src/route-renderer/orchestration/integration-renderer.test-fixtures.js +168 -172
- package/src/route-renderer/orchestration/ownership-graph/component-graph-collectors.js +119 -131
- package/src/route-renderer/orchestration/ownership-graph/component-graph.js +82 -91
- package/src/route-renderer/orchestration/ownership-graph/ownership-validation.service.js +82 -76
- package/src/route-renderer/orchestration/page-browser-graph/global-injector-assets.service.js +29 -31
- package/src/route-renderer/orchestration/page-browser-graph/page-browser-graph-contribution.loader.js +10 -6
- package/src/route-renderer/orchestration/page-browser-graph/page-browser-graph-merge.utils.js +31 -28
- package/src/route-renderer/orchestration/page-browser-graph/page-browser-graph-session.d.ts +3 -0
- package/src/route-renderer/orchestration/page-browser-graph/page-browser-graph-session.js +430 -413
- package/src/route-renderer/orchestration/page-browser-graph/page-browser-graph.service.js +191 -212
- package/src/route-renderer/orchestration/page-browser-graph/processed-asset-dedupe.js +20 -24
- package/src/route-renderer/orchestration/route-pipeline/integration-route-render-adapter.d.ts +4 -0
- package/src/route-renderer/orchestration/route-pipeline/integration-route-render-adapter.js +24 -24
- package/src/route-renderer/orchestration/route-pipeline/marker-artifact.utils.js +22 -24
- package/src/route-renderer/orchestration/route-pipeline/robots-meta.contribution.js +41 -34
- package/src/route-renderer/orchestration/route-pipeline/route-html-finalization.service.d.ts +5 -0
- package/src/route-renderer/orchestration/route-pipeline/route-html-finalization.service.js +42 -22
- package/src/route-renderer/orchestration/route-pipeline/route-prepared-options.builder.js +50 -48
- package/src/route-renderer/orchestration/route-pipeline/route-prepared-options.utils.js +29 -32
- package/src/route-renderer/orchestration/route-pipeline/route-render-orchestrator.js +150 -156
- package/src/route-renderer/orchestration/string-markup-renderer.js +48 -51
- package/src/route-renderer/page-loading/component-dependency-collection.js +120 -124
- package/src/route-renderer/page-loading/declared-asset-collection.js +66 -94
- package/src/route-renderer/page-loading/dependency-resolver.js +101 -104
- package/src/route-renderer/page-loading/ecopages-virtual-imports.js +68 -54
- package/src/route-renderer/page-loading/lazy-entry-collection.js +75 -98
- package/src/route-renderer/page-loading/lazy-trigger-planning.js +46 -36
- package/src/route-renderer/page-loading/module-declaration-aggregation.js +38 -31
- package/src/route-renderer/page-loading/module-declaration-scripts.js +10 -15
- package/src/route-renderer/page-loading/page-dependency-bundling.js +156 -113
- package/src/route-renderer/page-loading/page-module-loader.js +130 -124
- package/src/route-renderer/route-renderer.js +74 -76
- package/src/router/client/link-intent.js +55 -39
- package/src/router/client/link-intent.test.browser.js +49 -49
- package/src/router/client/link-navigation-policy.js +114 -93
- package/src/router/client/link-navigation-policy.test.browser.js +70 -80
- package/src/router/client/navigation-coordinator.js +235 -211
- package/src/router/server/route-registry.js +237 -242
- package/src/services/assets/asset-processing-service/asset-dependency-keys.js +64 -53
- package/src/services/assets/asset-processing-service/asset-processing.service.js +287 -303
- package/src/services/assets/asset-processing-service/asset.factory.js +78 -81
- package/src/services/assets/asset-processing-service/assets.types.js +1 -0
- package/src/services/assets/asset-processing-service/browser-runtime-asset.factory.js +57 -46
- package/src/services/assets/asset-processing-service/browser-runtime-entry-resolution.js +106 -69
- package/src/services/assets/asset-processing-service/browser-runtime-entry.factory.js +53 -53
- package/src/services/assets/asset-processing-service/finalize-processed-asset.js +4 -6
- package/src/services/assets/asset-processing-service/grouped-content-bundles.js +79 -80
- package/src/services/assets/asset-processing-service/index.js +8 -8
- package/src/services/assets/asset-processing-service/inline-content-script-body.js +22 -16
- package/src/services/assets/asset-processing-service/materialize-content-script-asset.js +21 -17
- package/src/services/assets/asset-processing-service/page-package.js +70 -72
- package/src/services/assets/asset-processing-service/processor.interface.js +7 -5
- package/src/services/assets/asset-processing-service/processor.registry.js +11 -14
- package/src/services/assets/asset-processing-service/processors/base/base-processor.js +59 -62
- package/src/services/assets/asset-processing-service/processors/base/base-script-processor.js +102 -117
- package/src/services/assets/asset-processing-service/processors/index.js +5 -5
- package/src/services/assets/asset-processing-service/processors/script/content-script.processor.js +110 -115
- package/src/services/assets/asset-processing-service/processors/script/file-script.processor.js +95 -97
- package/src/services/assets/asset-processing-service/processors/script/node-module-script.processor.js +136 -135
- package/src/services/assets/asset-processing-service/processors/stylesheet/content-stylesheet.processor.js +27 -29
- package/src/services/assets/asset-processing-service/processors/stylesheet/file-stylesheet.processor.js +34 -40
- package/src/services/assets/asset-processing-service/processors/stylesheet/stylesheet-processor-pipeline.js +36 -35
- package/src/services/assets/asset-processing-service/resolve-integration-plugin.js +14 -16
- package/src/services/assets/asset-processing-service/ungrouped-dependency-processing.js +27 -39
- package/src/services/assets/browser-bundle.service.js +52 -47
- package/src/services/cache/cache.types.js +5 -0
- package/src/services/cache/index.js +6 -7
- package/src/services/cache/memory-cache-store.js +101 -89
- package/src/services/cache/page-cache-service.js +156 -145
- package/src/services/cache/page-request-cache-coordinator.service.js +102 -102
- package/src/services/html/html-rewriter-provider.service.js +61 -61
- package/src/services/html/html-transformer.service.js +249 -266
- package/src/services/invalidation/development-invalidation.service.js +252 -241
- package/src/services/module-loading/app-module-loader.service.js +1 -0
- package/src/services/module-loading/app-server-module-transpiler.service.js +107 -101
- package/src/services/module-loading/host-module-loader-registry.js +6 -11
- package/src/services/module-loading/module-loading-types.js +1 -0
- package/src/services/module-loading/page-module-import.service.js +235 -243
- package/src/services/module-loading/route-module-build-cache-registry.js +47 -33
- package/src/services/module-loading/route-module-build-cache.js +3 -38
- package/src/services/module-loading/route-module-build-cache.store.js +195 -200
- package/src/services/module-loading/route-module-build-manifest.js +61 -74
- package/src/services/module-loading/route-module-dependency-hasher.js +136 -110
- package/src/services/module-loading/server-module-transpiler.service.js +68 -62
- package/src/services/module-loading/source-module-support.js +15 -7
- package/src/services/runtime-state/dev-graph.service.js +165 -157
- package/src/services/runtime-state/entrypoint-dependency-graph.service.js +85 -76
- package/src/services/runtime-state/server-invalidation-state.service.js +38 -30
- package/src/services/validation/schema-validation-service.js +157 -95
- package/src/services/validation/standard-schema.types.js +1 -0
- package/src/services/validation/validate-standard-schema.js +13 -13
- package/src/static-site-generator/production-page-browser-graph-prebuild.js +35 -19
- package/src/static-site-generator/sitemap-routes.js +33 -28
- package/src/static-site-generator/sitemap.js +38 -29
- package/src/static-site-generator/static-build-invalidation.js +34 -56
- package/src/static-site-generator/static-export-context.js +1 -0
- package/src/static-site-generator/static-site-generator.js +517 -553
- package/src/types/internal-types.d.ts +19 -3
- package/src/types/internal-types.js +1 -0
- package/src/types/public-types.d.ts +16 -46
- package/src/types/public-types.js +1 -0
- package/src/utils/deep-merge.js +39 -26
- package/src/utils/ecopages-route-info.js +27 -23
- package/src/utils/hash.js +3 -6
- package/src/utils/html-escaping.js +21 -8
- package/src/utils/html.js +1 -4
- package/src/utils/invariant.js +11 -10
- package/src/utils/locals-utils.js +32 -22
- package/src/utils/parse-cli-args.js +73 -65
- package/src/utils/path-pattern.js +38 -23
- package/src/utils/path-utils.module.js +8 -11
- package/src/utils/resolve-entry-file.js +70 -38
- package/src/utils/resolve-work-dir.js +23 -27
- package/src/utils/runtime.js +24 -33
- package/src/utils/server-utils.module.js +60 -52
- package/src/utils/static-file-extensions.js +52 -46
- package/src/watchers/project-watcher-ignore.js +16 -15
- package/src/watchers/project-watcher.js +385 -366
- package/src/watchers/project-watcher.test-helpers.js +45 -50
- package/src/adapters/shared/hmr/hmr-entrypoint-registrar.d.ts +0 -56
- package/src/adapters/shared/hmr/hmr-entrypoint-registrar.js +0 -106
- package/src/build/cache/dev-browser-script-cache.d.ts +0 -34
- package/src/build/cache/dev-browser-script-cache.js +0 -90
|
@@ -1,340 +1,361 @@
|
|
|
1
|
-
import {} from
|
|
2
|
-
import path from
|
|
3
|
-
import { fileSystem } from
|
|
4
|
-
import { setupAppRuntimePlugins } from
|
|
5
|
-
import { installBuildRuntime } from
|
|
6
|
-
import { appLogger } from
|
|
7
|
-
import { NodeClientBridge } from
|
|
8
|
-
import { NodeHmrManager } from
|
|
9
|
-
import { ProjectWatcher } from
|
|
10
|
-
import {
|
|
11
|
-
|
|
12
|
-
} from
|
|
13
|
-
import {
|
|
14
|
-
import {
|
|
15
|
-
import {
|
|
16
|
-
import {
|
|
17
|
-
import {
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
* they are mandatory by the time the concrete adapter is constructed —
|
|
77
|
-
* {@link createNodeServerAdapter} fills in Node-specific defaults first. The
|
|
78
|
-
* constructor signature makes that invariant explicit instead of relying on
|
|
79
|
-
* non-null assertions.
|
|
80
|
-
*/
|
|
81
|
-
constructor(options) {
|
|
82
|
-
super(options);
|
|
83
|
-
this.deferRuntimeAssetSetup = options.deferRuntimeAssetSetup === true;
|
|
84
|
-
this.allowPortFallback = options.allowPortFallback !== false;
|
|
85
|
-
this.apiHandlers = options.apiHandlers || [];
|
|
86
|
-
this.staticRoutes = options.staticRoutes || [];
|
|
87
|
-
this.errorHandler = options.errorHandler;
|
|
88
|
-
this.previewHost = options.previewHost;
|
|
89
|
-
this.requestBridge = options.requestBridge;
|
|
90
|
-
this.devRuntimeFactory = options.devRuntimeFactory;
|
|
91
|
-
if (options.websocketHandlers) {
|
|
92
|
-
this.websocketHandlers = options.websocketHandlers;
|
|
93
|
-
}
|
|
94
|
-
this.hostOwnsDevClient = options.hostOwnsDevClient === true;
|
|
95
|
-
}
|
|
96
|
-
/**
|
|
97
|
-
* Prepares the adapter for use.
|
|
98
|
-
*
|
|
99
|
-
* Order is intentional:
|
|
100
|
-
* 1. **Loaders** are registered first so processors and integrations can
|
|
101
|
-
* reference loader-provided file types in their own plugins.
|
|
102
|
-
* 2. **Public dir** is copied before any build so static assets are in `distDir`
|
|
103
|
-
* before the first request arrives.
|
|
104
|
-
* 3. **Plugins** (processors, then integrations) are set up after the public dir
|
|
105
|
-
* is in place so they can safely reference dist-relative paths.
|
|
106
|
-
* 4. **Router** is initialised last because it may depend on files written by
|
|
107
|
-
* processors during their `setup()` calls.
|
|
108
|
-
*/
|
|
109
|
-
async initialize() {
|
|
110
|
-
installBuildRuntime(this.appConfig);
|
|
111
|
-
prepareRuntimePublicDir(this.appConfig);
|
|
112
|
-
if (!this.deferRuntimeAssetSetup) {
|
|
113
|
-
await setupAppRuntimePlugins({
|
|
114
|
-
appConfig: this.appConfig,
|
|
115
|
-
runtimeOrigin: this.runtimeOrigin
|
|
116
|
-
});
|
|
1
|
+
import {} from 'node:http';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import { fileSystem } from '@ecopages/file-system';
|
|
4
|
+
import { setupAppRuntimePlugins } from '../../build/build-adapter.js';
|
|
5
|
+
import { installBuildRuntime } from '../../build/runtime/build-runtime.js';
|
|
6
|
+
import { appLogger } from '../../global/app-logger.js';
|
|
7
|
+
import { NodeClientBridge } from './node-client-bridge.js';
|
|
8
|
+
import { NodeHmrManager } from './node-hmr-manager.js';
|
|
9
|
+
import { ProjectWatcher } from '../../watchers/project-watcher.js';
|
|
10
|
+
import { attachNodeHttpWebSocketUpgrades, } from '../shared/ws/node-http-websocket-upgrades.js';
|
|
11
|
+
import { StaticSiteGenerator } from '../../static-site-generator/static-site-generator.js';
|
|
12
|
+
import { SharedServerAdapter } from '../shared/runtime/server-adapter.js';
|
|
13
|
+
import { ServerStaticBuilder } from '../shared/runtime/server-static-builder.js';
|
|
14
|
+
import { DEFAULT_ECOPAGES_HOSTNAME, DEFAULT_ECOPAGES_PORT } from '../../config/constants.js';
|
|
15
|
+
import { attachHmrToIntegrations, disposeDevResources, prepareRuntimePublicDir, startDevWarmup, } from '../shared/runtime/runtime-server-lifecycle.js';
|
|
16
|
+
import { resolveServeRuntimeOrigin } from '../shared/runtime/runtime-app-bootstrap.js';
|
|
17
|
+
import { NodeClientAbortError, NodeHttpRequestBridge } from './http-request-bridge.js';
|
|
18
|
+
import { NodeStaticPreviewHost } from './static-preview-host.js';
|
|
19
|
+
import { DefaultNodeServerDevRuntimeFactory } from './server-adapter-dependencies.js';
|
|
20
|
+
/**
|
|
21
|
+
* Node.js HTTP server adapter for the Ecopages runtime.
|
|
22
|
+
*
|
|
23
|
+
* `NodeServerAdapter` bridges the Node.js `http` module and the Ecopages
|
|
24
|
+
* `SharedServerAdapter` abstraction, translating between Node's
|
|
25
|
+
* `IncomingMessage`/`ServerResponse` API and the platform-agnostic Web
|
|
26
|
+
* `Request`/`Response` model.
|
|
27
|
+
*
|
|
28
|
+
* Lifecycle:
|
|
29
|
+
* 1. `createAdapter()` — calls `initialize()` and returns the public adapter result.
|
|
30
|
+
* 2. `completeInitialization(server)` — called once the HTTP server is listening.
|
|
31
|
+
* Conditionally wires HMR, WebSocket upgrades, and the file watcher when
|
|
32
|
+
* `options.watch` is `true`.
|
|
33
|
+
* 3. `handleRequest(request)` — delegates to `handleSharedRequest` for routing;
|
|
34
|
+
* intercepts `ClientAbortError` to return 499 instead of 500.
|
|
35
|
+
* 4. `buildStatic()` — spins up an ephemeral runtime server, generates all static
|
|
36
|
+
* pages against it, then tears it down.
|
|
37
|
+
*
|
|
38
|
+
* @see SharedServerAdapter for routing, caching and response handler logic.
|
|
39
|
+
*/
|
|
40
|
+
export class NodeServerAdapter extends SharedServerAdapter {
|
|
41
|
+
serverInstance = null;
|
|
42
|
+
initialized = false;
|
|
43
|
+
apiHandlers;
|
|
44
|
+
staticRoutes;
|
|
45
|
+
errorHandler;
|
|
46
|
+
bridge = null;
|
|
47
|
+
hmrManager = null;
|
|
48
|
+
projectWatcher = null;
|
|
49
|
+
adapterDisposed = false;
|
|
50
|
+
deferRuntimeAssetSetup;
|
|
51
|
+
allowPortFallback;
|
|
52
|
+
previewHost;
|
|
53
|
+
requestBridge;
|
|
54
|
+
devRuntimeFactory;
|
|
55
|
+
/**
|
|
56
|
+
* Reference to the application-level WebSocket handlers map.
|
|
57
|
+
*
|
|
58
|
+
* @remarks
|
|
59
|
+
* This is a reference to the map owned by `AbstractApplicationAdapter`,
|
|
60
|
+
* passed in via the constructor. The Node adapter reads from it to wire
|
|
61
|
+
* WebSocket upgrades for user-registered patterns.
|
|
62
|
+
*/
|
|
63
|
+
websocketHandlers = new Map();
|
|
64
|
+
/**
|
|
65
|
+
* Wires user WebSocket routes onto a foreign Node HTTP server.
|
|
66
|
+
*
|
|
67
|
+
* Host integrations such as the Vite plugin call this so `app.websocket()`
|
|
68
|
+
* handlers work while HTTP is still served by the host dev server.
|
|
69
|
+
*/
|
|
70
|
+
attachUserWebSocketUpgrades(server, options) {
|
|
71
|
+
attachNodeHttpWebSocketUpgrades(server, {
|
|
72
|
+
runtimeOrigin: this.runtimeOrigin,
|
|
73
|
+
websocketHandlers: this.websocketHandlers,
|
|
74
|
+
passthroughUnmatched: options?.passthroughUnmatched,
|
|
75
|
+
});
|
|
117
76
|
}
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
staticSiteGenerator: this.staticSiteGenerator,
|
|
126
|
-
serveOptions: this.serveOptions,
|
|
127
|
-
runtimeOrigin: this.runtimeOrigin,
|
|
128
|
-
needsServerBundle: this.apiHandlers.length > 0 || this.websocketHandlers.size > 0,
|
|
129
|
-
hmrManager: this.hmrManager ?? void 0
|
|
130
|
-
});
|
|
131
|
-
this.initialized = true;
|
|
132
|
-
}
|
|
133
|
-
getServerOptions() {
|
|
134
|
-
return {
|
|
135
|
-
...this.serveOptions
|
|
136
|
-
};
|
|
137
|
-
}
|
|
138
|
-
async buildStatic(options) {
|
|
139
|
-
if (!this.initialized) {
|
|
140
|
-
await this.initialize();
|
|
77
|
+
wireUserWebSocketUpgrades(server, preflight) {
|
|
78
|
+
attachNodeHttpWebSocketUpgrades(server, {
|
|
79
|
+
runtimeOrigin: this.runtimeOrigin,
|
|
80
|
+
websocketHandlers: this.websocketHandlers,
|
|
81
|
+
passthroughUnmatched: false,
|
|
82
|
+
preflight,
|
|
83
|
+
});
|
|
141
84
|
}
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
85
|
+
/**
|
|
86
|
+
* @remarks
|
|
87
|
+
* `previewHost`, `requestBridge`, and `devRuntimeFactory` are optional on the
|
|
88
|
+
* public {@link NodeServerAdapterParams} so factory callers can omit them, but
|
|
89
|
+
* they are mandatory by the time the concrete adapter is constructed —
|
|
90
|
+
* {@link createNodeServerAdapter} fills in Node-specific defaults first. The
|
|
91
|
+
* constructor signature makes that invariant explicit instead of relying on
|
|
92
|
+
* non-null assertions.
|
|
93
|
+
*/
|
|
94
|
+
constructor(options) {
|
|
95
|
+
super(options);
|
|
96
|
+
this.deferRuntimeAssetSetup = options.deferRuntimeAssetSetup === true;
|
|
97
|
+
this.allowPortFallback = options.allowPortFallback !== false;
|
|
98
|
+
this.apiHandlers = options.apiHandlers || [];
|
|
99
|
+
this.staticRoutes = options.staticRoutes || [];
|
|
100
|
+
this.errorHandler = options.errorHandler;
|
|
101
|
+
this.previewHost = options.previewHost;
|
|
102
|
+
this.requestBridge = options.requestBridge;
|
|
103
|
+
this.devRuntimeFactory = options.devRuntimeFactory;
|
|
104
|
+
if (options.websocketHandlers) {
|
|
105
|
+
this.websocketHandlers = options.websocketHandlers;
|
|
106
|
+
}
|
|
107
|
+
this.hostOwnsDevClient = options.hostOwnsDevClient === true;
|
|
153
108
|
}
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
109
|
+
/**
|
|
110
|
+
* Prepares the adapter for use.
|
|
111
|
+
*
|
|
112
|
+
* Order is intentional:
|
|
113
|
+
* 1. **Loaders** are registered first so processors and integrations can
|
|
114
|
+
* reference loader-provided file types in their own plugins.
|
|
115
|
+
* 2. **Public dir** is copied before any build so static assets are in `distDir`
|
|
116
|
+
* before the first request arrives.
|
|
117
|
+
* 3. **Plugins** (processors, then integrations) are set up after the public dir
|
|
118
|
+
* is in place so they can safely reference dist-relative paths.
|
|
119
|
+
* 4. **Router** is initialised last because it may depend on files written by
|
|
120
|
+
* processors during their `setup()` calls.
|
|
121
|
+
*/
|
|
122
|
+
async initialize() {
|
|
123
|
+
installBuildRuntime(this.appConfig);
|
|
124
|
+
prepareRuntimePublicDir(this.appConfig);
|
|
125
|
+
if (!this.deferRuntimeAssetSetup) {
|
|
126
|
+
await setupAppRuntimePlugins({
|
|
127
|
+
appConfig: this.appConfig,
|
|
128
|
+
runtimeOrigin: this.runtimeOrigin,
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
await this.initializeSharedRouteHandling({
|
|
132
|
+
staticRoutes: this.staticRoutes,
|
|
133
|
+
hmrManager: this.hmrManager ?? undefined,
|
|
134
|
+
});
|
|
135
|
+
this.staticSiteGenerator = new StaticSiteGenerator({ appConfig: this.appConfig });
|
|
136
|
+
this.staticBuilder = new ServerStaticBuilder({
|
|
137
|
+
appConfig: this.appConfig,
|
|
138
|
+
staticSiteGenerator: this.staticSiteGenerator,
|
|
139
|
+
serveOptions: this.serveOptions,
|
|
140
|
+
runtimeOrigin: this.runtimeOrigin,
|
|
141
|
+
needsServerBundle: this.apiHandlers.length > 0 || this.websocketHandlers.size > 0,
|
|
142
|
+
hmrManager: this.hmrManager ?? undefined,
|
|
143
|
+
});
|
|
144
|
+
this.initialized = true;
|
|
163
145
|
}
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
);
|
|
146
|
+
getServerOptions() {
|
|
147
|
+
return {
|
|
148
|
+
...this.serveOptions,
|
|
149
|
+
};
|
|
169
150
|
}
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
151
|
+
async buildStatic(options) {
|
|
152
|
+
if (!this.initialized) {
|
|
153
|
+
await this.initialize();
|
|
154
|
+
}
|
|
155
|
+
const baseUrl = resolveServeRuntimeOrigin(this.serveOptions);
|
|
156
|
+
await this.staticBuilder.build({ baseUrl, force: options?.force }, {
|
|
157
|
+
router: this.router,
|
|
158
|
+
routeRendererFactory: this.routeRendererFactory,
|
|
159
|
+
staticRoutes: this.staticRoutes,
|
|
160
|
+
});
|
|
161
|
+
if (!options?.preview) {
|
|
162
|
+
return undefined;
|
|
163
|
+
}
|
|
164
|
+
return this.startPreviewServer();
|
|
181
165
|
}
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
dispose: this.dispose.bind(this)
|
|
196
|
-
};
|
|
197
|
-
}
|
|
198
|
-
/**
|
|
199
|
-
* Releases dev-time resources owned by the adapter.
|
|
200
|
-
*
|
|
201
|
-
* @remarks
|
|
202
|
-
* Safe to call multiple times. Does not stop the bound HTTP server — callers
|
|
203
|
-
* should shut down transport through the runtime host before disposing.
|
|
204
|
-
*/
|
|
205
|
-
async dispose() {
|
|
206
|
-
if (this.adapterDisposed) {
|
|
207
|
-
return;
|
|
166
|
+
/**
|
|
167
|
+
* Serves an existing static export without running SSG. Used by e2e preview
|
|
168
|
+
* launchers after a shared prewarm build.
|
|
169
|
+
*/
|
|
170
|
+
async servePreviewOnly() {
|
|
171
|
+
if (!this.initialized) {
|
|
172
|
+
await this.initialize();
|
|
173
|
+
}
|
|
174
|
+
const distPath = path.join(this.appConfig.rootDir, this.appConfig.distDir);
|
|
175
|
+
if (!fileSystem.exists(distPath)) {
|
|
176
|
+
throw new Error(`Cannot serve preview without building first: dist directory "${this.appConfig.distDir}" not found in "${this.appConfig.rootDir}".`);
|
|
177
|
+
}
|
|
178
|
+
return this.startPreviewServer();
|
|
208
179
|
}
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
/**
|
|
222
|
-
* Handles a single incoming Web `Request` and returns a Web `Response`.
|
|
223
|
-
*
|
|
224
|
-
* Delegates to `handleSharedRequest` for all routing, caching, and response
|
|
225
|
-
* handler logic. The only Node-specific concern here is translating a
|
|
226
|
-
* `ClientAbortError` — which the body `ReadableStream` raises when the
|
|
227
|
-
* underlying socket closes early — into a 499 response so it does not
|
|
228
|
-
* incorrectly surface as a 500 in application logs.
|
|
229
|
-
*/
|
|
230
|
-
async handleRequest(request) {
|
|
231
|
-
if (!this.initialized) {
|
|
232
|
-
throw new Error("Node server adapter is not initialized. Call createAdapter() first.");
|
|
180
|
+
async startPreviewServer() {
|
|
181
|
+
const activePreviewPort = await this.previewHost.start({
|
|
182
|
+
appConfig: this.appConfig,
|
|
183
|
+
hostname: String(this.serveOptions.hostname || DEFAULT_ECOPAGES_HOSTNAME),
|
|
184
|
+
port: Number(this.serveOptions.port || DEFAULT_ECOPAGES_PORT),
|
|
185
|
+
allowPortFallback: this.allowPortFallback,
|
|
186
|
+
});
|
|
187
|
+
if (!activePreviewPort) {
|
|
188
|
+
return undefined;
|
|
189
|
+
}
|
|
190
|
+
const previewHostname = this.serveOptions.hostname || DEFAULT_ECOPAGES_HOSTNAME;
|
|
191
|
+
return `http://${previewHostname}:${activePreviewPort}`;
|
|
233
192
|
}
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
throw error;
|
|
193
|
+
async createAdapter() {
|
|
194
|
+
await this.initialize();
|
|
195
|
+
return {
|
|
196
|
+
getServerOptions: this.getServerOptions.bind(this),
|
|
197
|
+
buildStatic: this.buildStatic.bind(this),
|
|
198
|
+
servePreviewOnly: this.servePreviewOnly.bind(this),
|
|
199
|
+
completeInitialization: this.completeInitialization.bind(this),
|
|
200
|
+
handleRequest: this.handleRequest.bind(this),
|
|
201
|
+
attachUserWebSocketUpgrades: this.attachUserWebSocketUpgrades.bind(this),
|
|
202
|
+
listStaticGenerationRoutes: (input) => this.router.listStaticGenerationRoutes(input),
|
|
203
|
+
dispose: this.dispose.bind(this),
|
|
204
|
+
};
|
|
247
205
|
}
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
this.serverInstance = server;
|
|
267
|
-
const hasUserWs = this.websocketHandlers.size > 0;
|
|
268
|
-
if (this.options?.watch) {
|
|
269
|
-
const devRuntime = this.devRuntimeFactory.create({ appConfig: this.appConfig });
|
|
270
|
-
const wss = devRuntime.websocketServer;
|
|
271
|
-
this.bridge = devRuntime.bridge;
|
|
272
|
-
this.hmrManager = devRuntime.hmrManager;
|
|
273
|
-
this.hmrManager.setEnabled(true);
|
|
274
|
-
await this.hmrManager.ensureRuntimeReady();
|
|
275
|
-
const hmrPreflight = (req, socket, head) => {
|
|
276
|
-
const url = new URL(req.url ?? "/", this.runtimeOrigin);
|
|
277
|
-
if (url.pathname !== "/_hmr") return false;
|
|
278
|
-
wss.handleUpgrade(req, socket, head, (ws) => {
|
|
279
|
-
this.bridge.subscribe(ws);
|
|
280
|
-
ws.on("close", () => this.bridge.unsubscribe(ws));
|
|
281
|
-
ws.on("error", (err) => appLogger.error("[HMR] WebSocket error:", err));
|
|
206
|
+
/**
|
|
207
|
+
* Releases dev-time resources owned by the adapter.
|
|
208
|
+
*
|
|
209
|
+
* @remarks
|
|
210
|
+
* Safe to call multiple times. Does not stop the bound HTTP server — callers
|
|
211
|
+
* should shut down transport through the runtime host before disposing.
|
|
212
|
+
*/
|
|
213
|
+
async dispose() {
|
|
214
|
+
if (this.adapterDisposed) {
|
|
215
|
+
return;
|
|
216
|
+
}
|
|
217
|
+
this.adapterDisposed = true;
|
|
218
|
+
await disposeDevResources({
|
|
219
|
+
projectWatcher: this.projectWatcher,
|
|
220
|
+
appConfig: this.appConfig,
|
|
221
|
+
hmrManager: this.hmrManager,
|
|
222
|
+
bridge: this.bridge,
|
|
223
|
+
previewHost: this.previewHost,
|
|
282
224
|
});
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
225
|
+
this.projectWatcher = null;
|
|
226
|
+
this.hmrManager = null;
|
|
227
|
+
this.bridge = null;
|
|
228
|
+
}
|
|
229
|
+
/**
|
|
230
|
+
* Handles a single incoming Web `Request` and returns a Web `Response`.
|
|
231
|
+
*
|
|
232
|
+
* Delegates to `handleSharedRequest` for all routing, caching, and response
|
|
233
|
+
* handler logic. The only Node-specific concern here is translating a
|
|
234
|
+
* `ClientAbortError` — which the body `ReadableStream` raises when the
|
|
235
|
+
* underlying socket closes early — into a 499 response so it does not
|
|
236
|
+
* incorrectly surface as a 500 in application logs.
|
|
237
|
+
*/
|
|
238
|
+
async handleRequest(request) {
|
|
239
|
+
if (!this.initialized) {
|
|
240
|
+
throw new Error('Node server adapter is not initialized. Call createAdapter() first.');
|
|
241
|
+
}
|
|
242
|
+
try {
|
|
243
|
+
const response = await this.handleSharedRequest(request, {
|
|
244
|
+
apiHandlers: this.apiHandlers,
|
|
245
|
+
errorHandler: this.errorHandler,
|
|
246
|
+
serverInstance: this.serverInstance,
|
|
247
|
+
hmrManager: this.hmrManager ?? undefined,
|
|
248
|
+
});
|
|
249
|
+
return response;
|
|
250
|
+
}
|
|
251
|
+
catch (error) {
|
|
252
|
+
if (error instanceof NodeClientAbortError) {
|
|
253
|
+
/**
|
|
254
|
+
* The client disconnected before the response was sent (killed tab,
|
|
255
|
+
* network drop, or programmatic abort). This is a normal browser behaviour,
|
|
256
|
+
* not a server fault. Return 499 (Client Closed Request) silently so the
|
|
257
|
+
* error does not surface in application logs as a 500.
|
|
258
|
+
*/
|
|
259
|
+
return new Response(null, { status: 499 });
|
|
260
|
+
}
|
|
261
|
+
throw error;
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
/**
|
|
265
|
+
* Called once the HTTP server is bound and listening.
|
|
266
|
+
*
|
|
267
|
+
* When `options.watch` is `true` this method wires the full HMR pipeline:
|
|
268
|
+
* - A `WebSocketServer` is attached to the existing HTTP server via the
|
|
269
|
+
* `upgrade` event (no separate port needed).
|
|
270
|
+
* - `NodeClientBridge` tracks active WebSocket connections and handles
|
|
271
|
+
* broadcast + heartbeat cleanup.
|
|
272
|
+
* - `NodeHmrManager` watches the filesystem and triggers incremental
|
|
273
|
+
* rebuilds, notifying connected clients via the bridge.
|
|
274
|
+
* - Shared watcher bootstrapping listens for route-level file changes and
|
|
275
|
+
* refreshes the router and response handlers when pages are added or removed.
|
|
276
|
+
*
|
|
277
|
+
* WebSocket upgrade requests that do not match a known path are rejected with an
|
|
278
|
+
* immediate socket destroy to prevent unhandled upgrade leaks.
|
|
279
|
+
*/
|
|
280
|
+
async completeInitialization(server) {
|
|
281
|
+
this.serverInstance = server;
|
|
282
|
+
const hasUserWs = this.websocketHandlers.size > 0;
|
|
283
|
+
if (this.options?.watch) {
|
|
284
|
+
const devRuntime = this.devRuntimeFactory.create({ appConfig: this.appConfig });
|
|
285
|
+
const wss = devRuntime.websocketServer;
|
|
286
|
+
this.bridge = devRuntime.bridge;
|
|
287
|
+
this.hmrManager = devRuntime.hmrManager;
|
|
288
|
+
this.hmrManager.setEnabled(true);
|
|
289
|
+
await this.hmrManager.ensureRuntimeReady();
|
|
290
|
+
const hmrPreflight = (req, socket, head) => {
|
|
291
|
+
const url = new URL(req.url ?? '/', this.runtimeOrigin);
|
|
292
|
+
if (url.pathname !== '/_hmr')
|
|
293
|
+
return false;
|
|
294
|
+
wss.handleUpgrade(req, socket, head, (ws) => {
|
|
295
|
+
this.bridge.subscribe(ws);
|
|
296
|
+
ws.on('close', () => this.bridge.unsubscribe(ws));
|
|
297
|
+
ws.on('error', (err) => appLogger.error('[HMR] WebSocket error:', err));
|
|
298
|
+
});
|
|
299
|
+
return true;
|
|
300
|
+
};
|
|
301
|
+
if (hasUserWs) {
|
|
302
|
+
this.wireUserWebSocketUpgrades(server, hmrPreflight);
|
|
303
|
+
}
|
|
304
|
+
else {
|
|
305
|
+
server.on('upgrade', (req, socket, head) => {
|
|
306
|
+
if (!hmrPreflight(req, socket, head)) {
|
|
307
|
+
socket.destroy();
|
|
308
|
+
}
|
|
309
|
+
});
|
|
310
|
+
}
|
|
311
|
+
attachHmrToIntegrations(this.appConfig, this.hmrManager);
|
|
312
|
+
startDevWarmup({
|
|
313
|
+
appConfig: this.appConfig,
|
|
314
|
+
runtimeOrigin: this.runtimeOrigin,
|
|
315
|
+
});
|
|
316
|
+
this.configureSharedResponseHandlers(this.staticRoutes, this.hmrManager);
|
|
317
|
+
const watcher = new ProjectWatcher({
|
|
318
|
+
config: this.appConfig,
|
|
319
|
+
refreshRouterRoutesCallback: this.createSharedWatchRefreshCallback({
|
|
320
|
+
staticRoutes: this.staticRoutes,
|
|
321
|
+
hmrManager: this.hmrManager ?? undefined,
|
|
322
|
+
}),
|
|
323
|
+
hmrManager: this.hmrManager ?? undefined,
|
|
324
|
+
bridge: this.bridge,
|
|
325
|
+
hostOwnsDevClient: this.hostOwnsDevClient,
|
|
326
|
+
});
|
|
327
|
+
this.projectWatcher = watcher;
|
|
328
|
+
await watcher.createWatcherSubscription();
|
|
329
|
+
}
|
|
330
|
+
else if (hasUserWs) {
|
|
331
|
+
this.wireUserWebSocketUpgrades(server);
|
|
332
|
+
}
|
|
333
|
+
appLogger.debug('Node server adapter initialization completed', {
|
|
334
|
+
apiHandlers: this.apiHandlers.length,
|
|
335
|
+
staticRoutes: this.staticRoutes.length,
|
|
336
|
+
hasErrorHandler: !!this.errorHandler,
|
|
337
|
+
hmrEnabled: !!this.hmrManager?.isEnabled(),
|
|
292
338
|
});
|
|
293
|
-
}
|
|
294
|
-
attachHmrToIntegrations(this.appConfig, this.hmrManager);
|
|
295
|
-
startConfiguredIntegrationRuntimePrewarm({
|
|
296
|
-
appConfig: this.appConfig,
|
|
297
|
-
runtimeOrigin: this.runtimeOrigin
|
|
298
|
-
});
|
|
299
|
-
this.configureSharedResponseHandlers(this.staticRoutes, this.hmrManager);
|
|
300
|
-
const watcher = new ProjectWatcher({
|
|
301
|
-
config: this.appConfig,
|
|
302
|
-
refreshRouterRoutesCallback: this.createSharedWatchRefreshCallback({
|
|
303
|
-
staticRoutes: this.staticRoutes,
|
|
304
|
-
hmrManager: this.hmrManager ?? void 0
|
|
305
|
-
}),
|
|
306
|
-
hmrManager: this.hmrManager ?? void 0,
|
|
307
|
-
bridge: this.bridge,
|
|
308
|
-
hostOwnsDevClient: this.hostOwnsDevClient
|
|
309
|
-
});
|
|
310
|
-
this.projectWatcher = watcher;
|
|
311
|
-
await watcher.createWatcherSubscription();
|
|
312
|
-
} else if (hasUserWs) {
|
|
313
|
-
this.wireUserWebSocketUpgrades(server);
|
|
314
339
|
}
|
|
315
|
-
appLogger.debug("Node server adapter initialization completed", {
|
|
316
|
-
apiHandlers: this.apiHandlers.length,
|
|
317
|
-
staticRoutes: this.staticRoutes.length,
|
|
318
|
-
hasErrorHandler: !!this.errorHandler,
|
|
319
|
-
hmrEnabled: !!this.hmrManager?.isEnabled()
|
|
320
|
-
});
|
|
321
|
-
}
|
|
322
340
|
}
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
341
|
+
/**
|
|
342
|
+
* Factory function that creates and fully initialises a `NodeServerAdapter`.
|
|
343
|
+
*
|
|
344
|
+
* `runtimeOrigin` is derived from `serveOptions` when not explicitly provided,
|
|
345
|
+
* so callers only need to set it when the server is behind a reverse proxy that
|
|
346
|
+
* changes the effective host or port.
|
|
347
|
+
*/
|
|
348
|
+
export async function createNodeServerAdapter(params) {
|
|
349
|
+
const runtimeOrigin = params.runtimeOrigin ?? resolveServeRuntimeOrigin(params.serveOptions);
|
|
350
|
+
const previewHost = params.previewHost ?? new NodeStaticPreviewHost();
|
|
351
|
+
const requestBridge = params.requestBridge ?? new NodeHttpRequestBridge();
|
|
352
|
+
const devRuntimeFactory = params.devRuntimeFactory ?? new DefaultNodeServerDevRuntimeFactory();
|
|
353
|
+
const adapter = new NodeServerAdapter({
|
|
354
|
+
...params,
|
|
355
|
+
runtimeOrigin,
|
|
356
|
+
previewHost,
|
|
357
|
+
requestBridge,
|
|
358
|
+
devRuntimeFactory,
|
|
359
|
+
});
|
|
360
|
+
return adapter.createAdapter();
|
|
336
361
|
}
|
|
337
|
-
export {
|
|
338
|
-
NodeServerAdapter,
|
|
339
|
-
createNodeServerAdapter
|
|
340
|
-
};
|