@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,149 +1,147 @@
|
|
|
1
|
-
function normalizeSegmentPath(pathname) {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
}
|
|
5
|
-
return pathname;
|
|
6
|
-
}
|
|
7
|
-
function matchApiPathPattern(pattern, pathname) {
|
|
8
|
-
const normalizedPattern = normalizeSegmentPath(pattern);
|
|
9
|
-
const normalizedPathname = normalizeSegmentPath(pathname);
|
|
10
|
-
const patternSegments = normalizedPattern.split("/").filter(Boolean);
|
|
11
|
-
const pathSegments = normalizedPathname.split("/").filter(Boolean);
|
|
12
|
-
const params = {};
|
|
13
|
-
let patternIndex = 0;
|
|
14
|
-
let pathIndex = 0;
|
|
15
|
-
while (patternIndex < patternSegments.length && pathIndex < pathSegments.length) {
|
|
16
|
-
const patternSegment = patternSegments[patternIndex];
|
|
17
|
-
const pathSegment = pathSegments[pathIndex];
|
|
18
|
-
if (patternSegment === "*") {
|
|
19
|
-
return params;
|
|
20
|
-
}
|
|
21
|
-
if (patternSegment.startsWith("[...") && patternSegment.endsWith("]")) {
|
|
22
|
-
const paramName = patternSegment.slice(4, -1);
|
|
23
|
-
params[paramName] = pathSegments.slice(pathIndex);
|
|
24
|
-
return params;
|
|
25
|
-
}
|
|
26
|
-
if (patternSegment.startsWith(":")) {
|
|
27
|
-
params[patternSegment.slice(1)] = pathSegment;
|
|
28
|
-
patternIndex++;
|
|
29
|
-
pathIndex++;
|
|
30
|
-
continue;
|
|
1
|
+
export function normalizeSegmentPath(pathname) {
|
|
2
|
+
if (pathname.length > 1 && pathname.endsWith('/')) {
|
|
3
|
+
return pathname.slice(0, -1);
|
|
31
4
|
}
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
5
|
+
return pathname;
|
|
6
|
+
}
|
|
7
|
+
export function matchApiPathPattern(pattern, pathname) {
|
|
8
|
+
const normalizedPattern = normalizeSegmentPath(pattern);
|
|
9
|
+
const normalizedPathname = normalizeSegmentPath(pathname);
|
|
10
|
+
const patternSegments = normalizedPattern.split('/').filter(Boolean);
|
|
11
|
+
const pathSegments = normalizedPathname.split('/').filter(Boolean);
|
|
12
|
+
const params = {};
|
|
13
|
+
let patternIndex = 0;
|
|
14
|
+
let pathIndex = 0;
|
|
15
|
+
while (patternIndex < patternSegments.length && pathIndex < pathSegments.length) {
|
|
16
|
+
const patternSegment = patternSegments[patternIndex];
|
|
17
|
+
const pathSegment = pathSegments[pathIndex];
|
|
18
|
+
if (patternSegment === '*') {
|
|
19
|
+
return params;
|
|
20
|
+
}
|
|
21
|
+
if (patternSegment.startsWith('[...') && patternSegment.endsWith(']')) {
|
|
22
|
+
const paramName = patternSegment.slice(4, -1);
|
|
23
|
+
params[paramName] = pathSegments.slice(pathIndex);
|
|
24
|
+
return params;
|
|
25
|
+
}
|
|
26
|
+
if (patternSegment.startsWith(':')) {
|
|
27
|
+
params[patternSegment.slice(1)] = pathSegment;
|
|
28
|
+
patternIndex++;
|
|
29
|
+
pathIndex++;
|
|
30
|
+
continue;
|
|
31
|
+
}
|
|
32
|
+
if (patternSegment.startsWith('[') && patternSegment.endsWith(']')) {
|
|
33
|
+
params[patternSegment.slice(1, -1)] = pathSegment;
|
|
34
|
+
patternIndex++;
|
|
35
|
+
pathIndex++;
|
|
36
|
+
continue;
|
|
37
|
+
}
|
|
38
|
+
if (patternSegment !== pathSegment) {
|
|
39
|
+
return null;
|
|
40
|
+
}
|
|
41
|
+
patternIndex++;
|
|
42
|
+
pathIndex++;
|
|
37
43
|
}
|
|
38
|
-
if (
|
|
39
|
-
|
|
44
|
+
if (patternIndex < patternSegments.length) {
|
|
45
|
+
const remaining = patternSegments.slice(patternIndex);
|
|
46
|
+
const catchAll = remaining[0];
|
|
47
|
+
if (remaining.length === 1 && (catchAll === '*' || (catchAll.startsWith('[...') && catchAll.endsWith(']')))) {
|
|
48
|
+
if (catchAll.startsWith('[...')) {
|
|
49
|
+
const paramName = catchAll.slice(4, -1);
|
|
50
|
+
params[paramName] = [];
|
|
51
|
+
}
|
|
52
|
+
return params;
|
|
53
|
+
}
|
|
54
|
+
return null;
|
|
40
55
|
}
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
}
|
|
44
|
-
if (patternIndex < patternSegments.length) {
|
|
45
|
-
const remaining = patternSegments.slice(patternIndex);
|
|
46
|
-
const catchAll = remaining[0];
|
|
47
|
-
if (remaining.length === 1 && (catchAll === "*" || catchAll.startsWith("[...") && catchAll.endsWith("]"))) {
|
|
48
|
-
if (catchAll.startsWith("[...")) {
|
|
49
|
-
const paramName = catchAll.slice(4, -1);
|
|
50
|
-
params[paramName] = [];
|
|
51
|
-
}
|
|
52
|
-
return params;
|
|
56
|
+
if (pathIndex < pathSegments.length) {
|
|
57
|
+
return null;
|
|
53
58
|
}
|
|
54
|
-
return
|
|
55
|
-
}
|
|
56
|
-
if (pathIndex < pathSegments.length) {
|
|
57
|
-
return null;
|
|
58
|
-
}
|
|
59
|
-
return params;
|
|
59
|
+
return params;
|
|
60
60
|
}
|
|
61
|
-
function scoreApiPathPattern(pattern) {
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
61
|
+
export function scoreApiPathPattern(pattern) {
|
|
62
|
+
const segments = normalizeSegmentPath(pattern).split('/').filter(Boolean);
|
|
63
|
+
let score = 0;
|
|
64
|
+
for (const segment of segments) {
|
|
65
|
+
if (segment === '*' || (segment.startsWith('[...') && segment.endsWith(']'))) {
|
|
66
|
+
score += 10;
|
|
67
|
+
}
|
|
68
|
+
else if (segment.startsWith(':') || (segment.startsWith('[') && segment.endsWith(']'))) {
|
|
69
|
+
score += 50;
|
|
70
|
+
}
|
|
71
|
+
else {
|
|
72
|
+
score += 100;
|
|
73
|
+
}
|
|
71
74
|
}
|
|
72
|
-
|
|
73
|
-
return score;
|
|
75
|
+
return score;
|
|
74
76
|
}
|
|
75
|
-
function matchExplicitStaticPathPattern(pattern, pathname) {
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
}
|
|
85
|
-
const params = {};
|
|
86
|
-
for (let i = 0; i < patternSegments.length; i++) {
|
|
87
|
-
const patternPart = patternSegments[i];
|
|
88
|
-
const pathPart = pathSegments[i];
|
|
89
|
-
if (patternPart.startsWith(":...") || patternPart.startsWith("[...")) {
|
|
90
|
-
const paramName = patternPart.replace(/^(:\.\.\.|\[\.\.\.)/, "").replace(/\]$/, "");
|
|
91
|
-
params[paramName] = pathSegments.slice(i).join("/");
|
|
92
|
-
return params;
|
|
77
|
+
export function matchExplicitStaticPathPattern(pattern, pathname) {
|
|
78
|
+
const patternSegments = normalizeSegmentPath(pattern).split('/').filter(Boolean);
|
|
79
|
+
const pathSegments = normalizeSegmentPath(pathname).split('/').filter(Boolean);
|
|
80
|
+
if (patternSegments.length !== pathSegments.length) {
|
|
81
|
+
const lastPattern = patternSegments[patternSegments.length - 1];
|
|
82
|
+
const isCatchAll = lastPattern?.startsWith('[...') || lastPattern?.startsWith(':...');
|
|
83
|
+
if (!isCatchAll) {
|
|
84
|
+
return null;
|
|
85
|
+
}
|
|
93
86
|
}
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
87
|
+
const params = {};
|
|
88
|
+
for (let i = 0; i < patternSegments.length; i++) {
|
|
89
|
+
const patternPart = patternSegments[i];
|
|
90
|
+
const pathPart = pathSegments[i];
|
|
91
|
+
if (patternPart.startsWith(':...') || patternPart.startsWith('[...')) {
|
|
92
|
+
const paramName = patternPart.replace(/^(:\.\.\.|\[\.\.\.)/, '').replace(/\]$/, '');
|
|
93
|
+
params[paramName] = pathSegments.slice(i).join('/');
|
|
94
|
+
return params;
|
|
95
|
+
}
|
|
96
|
+
if (patternPart.startsWith(':')) {
|
|
97
|
+
params[patternPart.slice(1)] = pathPart;
|
|
98
|
+
}
|
|
99
|
+
else if (patternPart.startsWith('[') && patternPart.endsWith(']')) {
|
|
100
|
+
params[patternPart.slice(1, -1)] = pathPart;
|
|
101
|
+
}
|
|
102
|
+
else if (patternPart !== pathPart) {
|
|
103
|
+
return null;
|
|
104
|
+
}
|
|
100
105
|
}
|
|
101
|
-
|
|
102
|
-
return params;
|
|
106
|
+
return params;
|
|
103
107
|
}
|
|
104
|
-
function matchColonSegmentPath(pattern, pathname) {
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
return null;
|
|
109
|
-
}
|
|
110
|
-
const params = {};
|
|
111
|
-
for (let i = 0; i < patternSegments.length; i++) {
|
|
112
|
-
const patternSegment = patternSegments[i];
|
|
113
|
-
const pathSegment = pathSegments[i];
|
|
114
|
-
if (!patternSegment || !pathSegment) {
|
|
115
|
-
return null;
|
|
116
|
-
}
|
|
117
|
-
if (patternSegment.startsWith(":")) {
|
|
118
|
-
const paramName = patternSegment.slice(1);
|
|
119
|
-
if (!paramName) {
|
|
108
|
+
export function matchColonSegmentPath(pattern, pathname) {
|
|
109
|
+
const patternSegments = pattern.split('/').filter(Boolean);
|
|
110
|
+
const pathSegments = pathname.split('/').filter(Boolean);
|
|
111
|
+
if (patternSegments.length !== pathSegments.length) {
|
|
120
112
|
return null;
|
|
121
|
-
}
|
|
122
|
-
params[paramName] = pathSegment;
|
|
123
|
-
} else if (patternSegment !== pathSegment) {
|
|
124
|
-
return null;
|
|
125
113
|
}
|
|
126
|
-
|
|
127
|
-
|
|
114
|
+
const params = {};
|
|
115
|
+
for (let i = 0; i < patternSegments.length; i++) {
|
|
116
|
+
const patternSegment = patternSegments[i];
|
|
117
|
+
const pathSegment = pathSegments[i];
|
|
118
|
+
if (!patternSegment || !pathSegment) {
|
|
119
|
+
return null;
|
|
120
|
+
}
|
|
121
|
+
if (patternSegment.startsWith(':')) {
|
|
122
|
+
const paramName = patternSegment.slice(1);
|
|
123
|
+
if (!paramName) {
|
|
124
|
+
return null;
|
|
125
|
+
}
|
|
126
|
+
params[paramName] = pathSegment;
|
|
127
|
+
}
|
|
128
|
+
else if (patternSegment !== pathSegment) {
|
|
129
|
+
return null;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
return params;
|
|
128
133
|
}
|
|
129
|
-
function scoreColonSegmentPath(pattern) {
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
134
|
+
export function scoreColonSegmentPath(pattern) {
|
|
135
|
+
const segments = pattern.split('/').filter(Boolean);
|
|
136
|
+
let literals = 0;
|
|
137
|
+
let dynamics = 0;
|
|
138
|
+
for (const segment of segments) {
|
|
139
|
+
if (segment.startsWith(':')) {
|
|
140
|
+
dynamics += 1;
|
|
141
|
+
}
|
|
142
|
+
else {
|
|
143
|
+
literals += 1;
|
|
144
|
+
}
|
|
138
145
|
}
|
|
139
|
-
|
|
140
|
-
return literals * 100 - dynamics * 10 + segments.length;
|
|
146
|
+
return literals * 100 - dynamics * 10 + segments.length;
|
|
141
147
|
}
|
|
142
|
-
export {
|
|
143
|
-
matchApiPathPattern,
|
|
144
|
-
matchColonSegmentPath,
|
|
145
|
-
matchExplicitStaticPathPattern,
|
|
146
|
-
normalizeSegmentPath,
|
|
147
|
-
scoreApiPathPattern,
|
|
148
|
-
scoreColonSegmentPath
|
|
149
|
-
};
|
|
@@ -1,15 +1,23 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
1
|
+
/**
|
|
2
|
+
* This file contains the abstract server adapter class and its related types.
|
|
3
|
+
* It is designed to be extended by specific server adapters for different runtimes.
|
|
4
|
+
* The class provides methods for initializing the server, creating server options,
|
|
5
|
+
* building static files, and handling HTTP requests.
|
|
6
|
+
*
|
|
7
|
+
* @module ServerAdapter
|
|
8
|
+
*/
|
|
9
|
+
/**
|
|
10
|
+
* Abstract base class for server adapters across different runtimes
|
|
11
|
+
*/
|
|
12
|
+
export class AbstractServerAdapter {
|
|
13
|
+
appConfig;
|
|
14
|
+
options;
|
|
15
|
+
serveOptions;
|
|
16
|
+
runtimeOrigin;
|
|
17
|
+
constructor(options) {
|
|
18
|
+
this.appConfig = options.appConfig;
|
|
19
|
+
this.options = options.options || {};
|
|
20
|
+
this.serveOptions = options.serveOptions || {};
|
|
21
|
+
this.runtimeOrigin = options.runtimeOrigin;
|
|
22
|
+
}
|
|
12
23
|
}
|
|
13
|
-
export {
|
|
14
|
-
AbstractServerAdapter
|
|
15
|
-
};
|
|
@@ -1,30 +1,28 @@
|
|
|
1
|
-
import { matchColonSegmentPath, scoreColonSegmentPath } from
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
import { matchColonSegmentPath, scoreColonSegmentPath } from './segment-path-matcher.js';
|
|
2
|
+
/**
|
|
3
|
+
* Pattern matcher for WebSocket route paths.
|
|
4
|
+
*/
|
|
5
|
+
export function matchWebSocketPath(pattern, pathname) {
|
|
6
|
+
return matchColonSegmentPath(pattern, pathname);
|
|
4
7
|
}
|
|
5
|
-
function scoreWebSocketPattern(pattern) {
|
|
6
|
-
|
|
8
|
+
export function scoreWebSocketPattern(pattern) {
|
|
9
|
+
return scoreColonSegmentPath(pattern);
|
|
7
10
|
}
|
|
8
|
-
function findWebSocketRoute(handlers, pathname) {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
11
|
+
export function findWebSocketRoute(handlers, pathname) {
|
|
12
|
+
let best = null;
|
|
13
|
+
let index = 0;
|
|
14
|
+
for (const [pattern, handler] of handlers) {
|
|
15
|
+
const params = matchColonSegmentPath(pattern, pathname);
|
|
16
|
+
if (params === null) {
|
|
17
|
+
index += 1;
|
|
18
|
+
continue;
|
|
19
|
+
}
|
|
20
|
+
const score = scoreColonSegmentPath(pattern);
|
|
21
|
+
const match = { handler, params, kind: pattern };
|
|
22
|
+
if (best === null || score > best.score || (score === best.score && index < best.index)) {
|
|
23
|
+
best = { score, match, index };
|
|
24
|
+
}
|
|
25
|
+
index += 1;
|
|
16
26
|
}
|
|
17
|
-
|
|
18
|
-
const match = { handler, params, kind: pattern };
|
|
19
|
-
if (best === null || score > best.score || score === best.score && index < best.index) {
|
|
20
|
-
best = { score, match, index };
|
|
21
|
-
}
|
|
22
|
-
index += 1;
|
|
23
|
-
}
|
|
24
|
-
return best?.match ?? null;
|
|
27
|
+
return best?.match ?? null;
|
|
25
28
|
}
|
|
26
|
-
export {
|
|
27
|
-
findWebSocketRoute,
|
|
28
|
-
matchWebSocketPath,
|
|
29
|
-
scoreWebSocketPattern
|
|
30
|
-
};
|
|
@@ -1,96 +1,93 @@
|
|
|
1
|
-
import { appLogger } from
|
|
2
|
-
import { invokeWebSocketHandlerHook, toWebSocketCloseInfo } from
|
|
1
|
+
import { appLogger } from '../../global/app-logger.js';
|
|
2
|
+
import { invokeWebSocketHandlerHook, toWebSocketCloseInfo } from '../shared/ws/websocket-lifecycle.js';
|
|
3
3
|
function toUpgradeRequest(ws, runtimeOrigin) {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
4
|
+
const upgradeUrl = ws.data?.upgradeUrl;
|
|
5
|
+
if (upgradeUrl) {
|
|
6
|
+
return new Request(upgradeUrl);
|
|
7
|
+
}
|
|
8
|
+
return new Request(runtimeOrigin);
|
|
9
9
|
}
|
|
10
10
|
async function runUserWebSocketOpen(ws, kind, deps) {
|
|
11
|
-
const handler = deps.userHandlers.get(kind);
|
|
12
|
-
if (!handler) {
|
|
13
|
-
return;
|
|
14
|
-
}
|
|
15
|
-
const params = ws.data?.params ?? {};
|
|
16
|
-
const search = ws.data?.search ?? {};
|
|
17
|
-
const request = toUpgradeRequest(ws, deps.runtimeOrigin);
|
|
18
|
-
let context;
|
|
19
|
-
try {
|
|
20
|
-
context = await deps.resolveContext(request, handler, kind, params, search);
|
|
21
|
-
} catch {
|
|
22
|
-
ws.close(1011, "context initialization failed");
|
|
23
|
-
return;
|
|
24
|
-
}
|
|
25
|
-
ws.data.context = context;
|
|
26
|
-
const socket = deps.adaptSocket(ws, kind, params, search, context);
|
|
27
|
-
try {
|
|
28
|
-
await handler.onConnect?.(socket);
|
|
29
|
-
} catch (error) {
|
|
30
|
-
appLogger.error(`[WS:${kind}] onConnect failed:`, error);
|
|
31
|
-
ws.close(1011, "onConnect failed");
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
function createBunUserWebSocketLifecycle(deps) {
|
|
35
|
-
const resolveSocketForEvent = (ws) => {
|
|
36
|
-
const kind = ws.data?.kind;
|
|
37
|
-
if (!kind) {
|
|
38
|
-
return void 0;
|
|
39
|
-
}
|
|
40
11
|
const handler = deps.userHandlers.get(kind);
|
|
41
12
|
if (!handler) {
|
|
42
|
-
|
|
13
|
+
return;
|
|
43
14
|
}
|
|
44
|
-
const params = ws.data?.params ?? {};
|
|
15
|
+
const params = (ws.data?.params ?? {});
|
|
45
16
|
const search = ws.data?.search ?? {};
|
|
46
|
-
const
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
return;
|
|
54
|
-
}
|
|
55
|
-
void runUserWebSocketOpen(ws, kind, deps).catch((error) => {
|
|
56
|
-
appLogger.error(`[WS:${kind}] open failed:`, error);
|
|
57
|
-
ws.close(1011, "internal error");
|
|
58
|
-
});
|
|
59
|
-
},
|
|
60
|
-
message(ws, msg) {
|
|
61
|
-
const resolved = resolveSocketForEvent(ws);
|
|
62
|
-
if (!resolved) {
|
|
63
|
-
return;
|
|
64
|
-
}
|
|
65
|
-
if (ws.data?.context === void 0 && resolved.handler.context) {
|
|
66
|
-
appLogger.warn(`[WS:${resolved.kind}] message received before context resolved; dropping.`);
|
|
67
|
-
return;
|
|
68
|
-
}
|
|
69
|
-
const message = typeof msg === "string" ? { kind: "text", text: msg } : { kind: "binary", data: new Uint8Array(msg.buffer, msg.byteOffset, msg.byteLength) };
|
|
70
|
-
invokeWebSocketHandlerHook(
|
|
71
|
-
resolved.kind,
|
|
72
|
-
"onMessage",
|
|
73
|
-
resolved.handler.onMessage?.(resolved.socket, message)
|
|
74
|
-
);
|
|
75
|
-
},
|
|
76
|
-
close(ws, code, reason) {
|
|
77
|
-
const resolved = resolveSocketForEvent(ws);
|
|
78
|
-
if (!resolved) {
|
|
79
|
-
return;
|
|
80
|
-
}
|
|
81
|
-
const event = toWebSocketCloseInfo(code, reason);
|
|
82
|
-
invokeWebSocketHandlerHook(resolved.kind, "onClose", resolved.handler.onClose?.(resolved.socket, event));
|
|
83
|
-
},
|
|
84
|
-
error(ws, error) {
|
|
85
|
-
const resolved = resolveSocketForEvent(ws);
|
|
86
|
-
if (!resolved) {
|
|
17
|
+
const request = toUpgradeRequest(ws, deps.runtimeOrigin);
|
|
18
|
+
let context;
|
|
19
|
+
try {
|
|
20
|
+
context = await deps.resolveContext(request, handler, kind, params, search);
|
|
21
|
+
}
|
|
22
|
+
catch {
|
|
23
|
+
ws.close(1011, 'context initialization failed');
|
|
87
24
|
return;
|
|
88
|
-
}
|
|
89
|
-
appLogger.error(`[WS:${resolved.kind}] error:`, error);
|
|
90
|
-
invokeWebSocketHandlerHook(resolved.kind, "onError", resolved.handler.onError?.(resolved.socket, error));
|
|
91
25
|
}
|
|
92
|
-
|
|
26
|
+
ws.data.context = context;
|
|
27
|
+
const socket = deps.adaptSocket(ws, kind, params, search, context);
|
|
28
|
+
try {
|
|
29
|
+
await handler.onConnect?.(socket);
|
|
30
|
+
}
|
|
31
|
+
catch (error) {
|
|
32
|
+
appLogger.error(`[WS:${kind}] onConnect failed:`, error);
|
|
33
|
+
ws.close(1011, 'onConnect failed');
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
export function createBunUserWebSocketLifecycle(deps) {
|
|
37
|
+
const resolveSocketForEvent = (ws) => {
|
|
38
|
+
const kind = ws.data?.kind;
|
|
39
|
+
if (!kind) {
|
|
40
|
+
return undefined;
|
|
41
|
+
}
|
|
42
|
+
const handler = deps.userHandlers.get(kind);
|
|
43
|
+
if (!handler) {
|
|
44
|
+
return undefined;
|
|
45
|
+
}
|
|
46
|
+
const params = (ws.data?.params ?? {});
|
|
47
|
+
const search = ws.data?.search ?? {};
|
|
48
|
+
const socket = deps.adaptSocket(ws, kind, params, search, ws.data?.context);
|
|
49
|
+
return { kind, handler, socket };
|
|
50
|
+
};
|
|
51
|
+
return {
|
|
52
|
+
open(ws) {
|
|
53
|
+
const kind = ws.data?.kind;
|
|
54
|
+
if (!kind) {
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
void runUserWebSocketOpen(ws, kind, deps).catch((error) => {
|
|
58
|
+
appLogger.error(`[WS:${kind}] open failed:`, error);
|
|
59
|
+
ws.close(1011, 'internal error');
|
|
60
|
+
});
|
|
61
|
+
},
|
|
62
|
+
message(ws, msg) {
|
|
63
|
+
const resolved = resolveSocketForEvent(ws);
|
|
64
|
+
if (!resolved) {
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
if (ws.data?.context === undefined && resolved.handler.context) {
|
|
68
|
+
appLogger.warn(`[WS:${resolved.kind}] message received before context resolved; dropping.`);
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
const message = typeof msg === 'string'
|
|
72
|
+
? { kind: 'text', text: msg }
|
|
73
|
+
: { kind: 'binary', data: new Uint8Array(msg.buffer, msg.byteOffset, msg.byteLength) };
|
|
74
|
+
invokeWebSocketHandlerHook(resolved.kind, 'onMessage', resolved.handler.onMessage?.(resolved.socket, message));
|
|
75
|
+
},
|
|
76
|
+
close(ws, code, reason) {
|
|
77
|
+
const resolved = resolveSocketForEvent(ws);
|
|
78
|
+
if (!resolved) {
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
const event = toWebSocketCloseInfo(code, reason);
|
|
82
|
+
invokeWebSocketHandlerHook(resolved.kind, 'onClose', resolved.handler.onClose?.(resolved.socket, event));
|
|
83
|
+
},
|
|
84
|
+
error(ws, error) {
|
|
85
|
+
const resolved = resolveSocketForEvent(ws);
|
|
86
|
+
if (!resolved) {
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
appLogger.error(`[WS:${resolved.kind}] error:`, error);
|
|
90
|
+
invokeWebSocketHandlerHook(resolved.kind, 'onError', resolved.handler.onError?.(resolved.socket, error));
|
|
91
|
+
},
|
|
92
|
+
};
|
|
93
93
|
}
|
|
94
|
-
export {
|
|
95
|
-
createBunUserWebSocketLifecycle
|
|
96
|
-
};
|
|
@@ -1,51 +1,52 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
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
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Manages WebSocket subscribers and broadcasts development events.
|
|
3
|
+
* Bridges the gap between the server and the development client.
|
|
4
|
+
*/
|
|
5
|
+
export class ClientBridge {
|
|
6
|
+
subscribers = new Set();
|
|
7
|
+
subscribe(ws) {
|
|
8
|
+
this.subscribers.add(ws);
|
|
9
|
+
}
|
|
10
|
+
unsubscribe(ws) {
|
|
11
|
+
this.subscribers.delete(ws);
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Broadcast a raw event to all connected clients.
|
|
15
|
+
*/
|
|
16
|
+
broadcast(event) {
|
|
17
|
+
const payload = JSON.stringify(event);
|
|
18
|
+
for (const ws of this.subscribers) {
|
|
19
|
+
ws.send(payload);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Trigger a full page reload on all connected clients.
|
|
24
|
+
*/
|
|
25
|
+
reload() {
|
|
26
|
+
this.broadcast({ type: 'reload' });
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Broadcast a CSS update for hot stylesheet reload.
|
|
30
|
+
*/
|
|
31
|
+
cssUpdate(path) {
|
|
32
|
+
this.broadcast({ type: 'css-update', path, timestamp: Date.now() });
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Broadcast a JS module update for hot module replacement.
|
|
36
|
+
*/
|
|
37
|
+
update(path) {
|
|
38
|
+
this.broadcast({ type: 'update', path, timestamp: Date.now() });
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Broadcast an error message to connected clients.
|
|
42
|
+
*/
|
|
43
|
+
error(message) {
|
|
44
|
+
this.broadcast({ type: 'error', message });
|
|
45
|
+
}
|
|
46
|
+
get subscriberCount() {
|
|
47
|
+
return this.subscribers.size;
|
|
48
|
+
}
|
|
49
|
+
destroy() {
|
|
50
|
+
this.subscribers.clear();
|
|
51
|
+
}
|
|
48
52
|
}
|
|
49
|
-
export {
|
|
50
|
-
ClientBridge
|
|
51
|
-
};
|