@ecopages/core 0.2.0-alpha.4 → 0.2.0-alpha.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +213 -12
- package/package.json +100 -188
- package/src/adapters/README.md +39 -0
- package/src/adapters/bun/hmr-manager.test.ts +267 -0
- package/src/adapters/bun/hmr-manager.ts +181 -68
- package/src/adapters/bun/index.ts +1 -2
- package/src/adapters/bun/server-adapter.ts +41 -34
- package/src/adapters/bun/server-lifecycle.ts +40 -70
- package/src/adapters/index.ts +1 -1
- package/src/adapters/node/bootstrap-dependency-resolver.test.ts +282 -0
- package/src/adapters/node/bootstrap-dependency-resolver.ts +301 -0
- package/src/adapters/node/index.ts +7 -0
- package/src/adapters/node/node-client-bridge.test.ts +198 -0
- package/src/adapters/node/node-hmr-manager.test.ts +322 -0
- package/src/adapters/node/node-hmr-manager.ts +208 -116
- package/src/adapters/node/runtime-adapter.test.ts +868 -0
- package/src/adapters/node/runtime-adapter.ts +439 -0
- package/src/adapters/node/server-adapter.ts +31 -104
- package/src/adapters/node/static-content-server.test.ts +60 -0
- package/src/adapters/node/static-content-server.ts +36 -0
- package/src/adapters/node/write-runtime-manifest.ts +38 -0
- package/src/adapters/shared/api-response.test.ts +97 -0
- package/src/{define-api-handler.ts → adapters/shared/define-api-handler.ts} +1 -1
- package/src/adapters/shared/explicit-static-route-matcher.test.ts +381 -0
- package/src/adapters/shared/explicit-static-route-matcher.ts +7 -1
- package/src/adapters/shared/file-route-middleware-pipeline.test.ts +90 -0
- package/src/adapters/shared/file-route-middleware-pipeline.ts +6 -2
- package/src/adapters/shared/fs-server-response-factory.test.ts +187 -0
- package/src/adapters/shared/fs-server-response-matcher.test.ts +286 -0
- package/src/adapters/shared/fs-server-response-matcher.ts +17 -10
- package/src/adapters/shared/hmr-entrypoint-registrar.ts +149 -0
- package/src/adapters/shared/hmr-html-response.ts +52 -0
- package/src/adapters/shared/hmr-manager.contract.test.ts +196 -0
- package/src/adapters/shared/hmr-manager.dispatch.test.ts +220 -0
- package/src/adapters/shared/render-context.test.ts +146 -0
- package/src/adapters/shared/render-context.ts +21 -6
- package/src/adapters/shared/runtime-bootstrap.ts +79 -0
- package/src/adapters/shared/server-adapter.test.ts +77 -0
- package/src/adapters/shared/server-adapter.ts +51 -4
- package/src/adapters/shared/server-route-handler.test.ts +110 -0
- package/src/adapters/shared/server-route-handler.ts +5 -18
- package/src/adapters/shared/server-static-builder.test.ts +316 -0
- package/src/adapters/shared/server-static-builder.ts +92 -8
- package/src/build/README.md +101 -0
- package/src/build/build-adapter-serialization.test.ts +268 -0
- package/src/build/build-adapter.test.ts +815 -0
- package/src/build/build-adapter.ts +235 -6
- package/src/build/build-manifest.ts +54 -0
- package/src/build/dev-build-coordinator.ts +221 -0
- package/src/build/esbuild-build-adapter.ts +132 -83
- package/src/build/runtime-build-executor.ts +34 -0
- package/src/build/runtime-specifier-alias-plugin.test.ts +43 -0
- package/src/build/runtime-specifier-alias-plugin.ts +58 -0
- package/src/config/README.md +33 -0
- package/src/config/config-builder.test.ts +410 -0
- package/src/config/config-builder.ts +281 -49
- package/src/constants.ts +15 -0
- package/src/declarations.d.ts +18 -13
- package/src/eco/README.md +70 -16
- package/src/eco/component-render-context.ts +39 -17
- package/src/eco/eco.test.ts +678 -0
- package/src/eco/eco.ts +29 -8
- package/src/eco/eco.types.ts +20 -1
- package/src/eco/eco.utils.test.ts +124 -0
- package/src/eco/global-injector-map.test.ts +42 -0
- package/src/eco/lazy-injector-map.test.ts +66 -0
- package/src/eco/module-dependencies.test.ts +30 -0
- package/src/errors/http-error.test.ts +134 -0
- package/src/global/utils.test.ts +12 -0
- package/src/hmr/README.md +26 -0
- package/src/hmr/client/__screenshots__/hmr-runtime.test.browser.ts/HMR-Runtime-HMR-Server-Integration-should-have-HMR-script-injected-in-page-1.png +0 -0
- package/src/hmr/client/__screenshots__/hmr-runtime.test.browser.ts/HMR-Runtime-HMR-Server-Integration-should-load-fixture-app-page-1.png +0 -0
- package/src/hmr/client/__screenshots__/hmr-runtime.test.browser.ts/HMR-Runtime-WebSocket-Connection-should-connect-to-correct-HMR-endpoint-1.png +0 -0
- package/src/hmr/client/hmr-runtime.ts +38 -7
- package/src/hmr/hmr-strategy.test.ts +124 -0
- package/src/hmr/hmr.postcss.test.e2e.ts +41 -0
- package/src/hmr/hmr.test.e2e.ts +29 -38
- package/src/hmr/strategies/js-hmr-strategy.test.ts +335 -0
- package/src/hmr/strategies/js-hmr-strategy.ts +115 -115
- package/src/index.ts +1 -1
- package/src/integrations/ghtml/ghtml-renderer.test.ts +63 -0
- package/src/integrations/ghtml/ghtml-renderer.ts +4 -1
- package/src/internal-types.ts +39 -19
- package/src/plugins/README.md +34 -0
- package/src/plugins/alias-resolver-plugin.test.ts +41 -0
- package/src/plugins/alias-resolver-plugin.ts +21 -3
- package/src/plugins/eco-component-meta-plugin.test.ts +380 -0
- package/src/plugins/eco-component-meta-plugin.ts +10 -3
- package/src/plugins/integration-plugin.test.ts +111 -0
- package/src/plugins/integration-plugin.ts +45 -3
- package/src/plugins/processor.test.ts +148 -0
- package/src/plugins/processor.ts +22 -2
- package/src/plugins/runtime-capability.ts +14 -0
- package/src/public-types.ts +73 -16
- package/src/route-renderer/GRAPH.md +16 -20
- package/src/route-renderer/README.md +8 -21
- package/src/route-renderer/component-graph/component-graph-executor.test.ts +41 -0
- package/src/route-renderer/component-graph/component-graph.test.ts +63 -0
- package/src/route-renderer/component-graph/component-marker.test.ts +73 -0
- package/src/route-renderer/component-graph/component-reference.ts +29 -0
- package/src/route-renderer/component-graph/marker-graph-resolver.test.ts +135 -0
- package/src/route-renderer/{marker-graph-resolver.ts → component-graph/marker-graph-resolver.ts} +11 -9
- package/src/route-renderer/orchestration/integration-renderer.test.ts +936 -0
- package/src/route-renderer/{integration-renderer.ts → orchestration/integration-renderer.ts} +113 -19
- package/src/route-renderer/orchestration/render-execution.service.test.ts +97 -0
- package/src/route-renderer/{render-execution.service.ts → orchestration/render-execution.service.ts} +109 -37
- package/src/route-renderer/orchestration/render-preparation.service.test.ts +235 -0
- package/src/route-renderer/{render-preparation.service.ts → orchestration/render-preparation.service.ts} +127 -9
- package/src/route-renderer/page-loading/dependency-resolver.test.ts +345 -0
- package/src/route-renderer/{dependency-resolver.ts → page-loading/dependency-resolver.ts} +28 -12
- package/src/route-renderer/page-loading/page-module-loader.test.ts +96 -0
- package/src/route-renderer/{page-module-loader.ts → page-loading/page-module-loader.ts} +49 -21
- package/src/route-renderer/route-renderer.ts +36 -1
- package/src/router/README.md +26 -0
- package/src/router/client/link-intent.d.ts +53 -0
- package/src/router/client/link-intent.test.browser.ts +51 -0
- package/src/router/client/link-intent.ts +92 -0
- package/src/router/client/navigation-coordinator.test.ts +237 -0
- package/src/router/client/navigation-coordinator.ts +433 -0
- package/src/router/server/fs-router-scanner.test.ts +83 -0
- package/src/router/{fs-router-scanner.ts → server/fs-router-scanner.ts} +12 -10
- package/src/router/server/fs-router.test.ts +214 -0
- package/src/router/{fs-router.ts → server/fs-router.ts} +2 -2
- package/src/services/README.md +29 -0
- package/src/services/assets/asset-processing-service/asset-processing.service.test.ts +385 -0
- package/src/services/{asset-processing-service → assets/asset-processing-service}/asset-processing.service.ts +101 -6
- package/src/services/assets/asset-processing-service/asset.factory.test.ts +63 -0
- package/src/services/{asset-processing-service → assets/asset-processing-service}/asset.factory.ts +2 -2
- package/src/services/{asset-processing-service → assets/asset-processing-service}/assets.types.ts +2 -1
- package/src/services/assets/asset-processing-service/browser-runtime-asset.factory.test.ts +72 -0
- package/src/services/assets/asset-processing-service/browser-runtime-asset.factory.ts +95 -0
- package/src/services/assets/asset-processing-service/browser-runtime-entry.factory.test.ts +67 -0
- package/src/services/assets/asset-processing-service/browser-runtime-entry.factory.ts +78 -0
- package/src/services/{asset-processing-service → assets/asset-processing-service}/index.ts +2 -0
- package/src/services/{asset-processing-service → assets/asset-processing-service}/processor.interface.ts +1 -1
- package/src/services/assets/asset-processing-service/processors/base/base-processor.test.ts +59 -0
- package/src/services/{asset-processing-service → assets/asset-processing-service}/processors/base/base-processor.ts +11 -5
- package/src/services/{asset-processing-service → assets/asset-processing-service}/processors/base/base-script-processor.ts +17 -27
- package/src/services/assets/asset-processing-service/processors/script/file-script.processor.test.ts +286 -0
- package/src/services/{asset-processing-service → assets/asset-processing-service}/processors/script/file-script.processor.ts +3 -3
- package/src/services/assets/asset-processing-service/processors/script/node-module-script.processor.test.ts +227 -0
- package/src/services/{asset-processing-service → assets/asset-processing-service}/processors/script/node-module-script.processor.ts +5 -4
- package/src/services/assets/asset-processing-service/processors/stylesheet/content-stylesheet.processor.test.ts +199 -0
- package/src/services/{asset-processing-service → assets/asset-processing-service}/processors/stylesheet/file-stylesheet.processor.ts +4 -1
- package/src/services/assets/browser-bundle.service.test.ts +36 -0
- package/src/services/assets/browser-bundle.service.ts +53 -0
- package/src/services/cache/index.ts +3 -3
- package/src/services/cache/memory-cache-store.test.ts +225 -0
- package/src/services/cache/memory-cache-store.ts +1 -1
- package/src/services/cache/page-cache-service.test.ts +175 -0
- package/src/services/cache/page-cache-service.ts +3 -3
- package/src/services/cache/page-request-cache-coordinator.service.test.ts +79 -0
- package/src/services/{page-request-cache-coordinator.service.ts → cache/page-request-cache-coordinator.service.ts} +9 -6
- package/src/services/html/html-rewriter-provider.service.test.ts +183 -0
- package/src/services/html/html-rewriter-provider.service.ts +103 -0
- package/src/services/html/html-transformer.service.test.ts +378 -0
- package/src/services/html/html-transformer.service.ts +279 -0
- package/src/services/invalidation/development-invalidation.service.test.ts +77 -0
- package/src/services/invalidation/development-invalidation.service.ts +261 -0
- package/src/services/module-loading/app-server-module-transpiler.service.ts +52 -0
- package/src/services/module-loading/page-module-import.service.test.ts +253 -0
- package/src/services/module-loading/page-module-import.service.ts +200 -0
- package/src/services/module-loading/server-loader.service.test.ts +161 -0
- package/src/services/module-loading/server-loader.service.ts +130 -0
- package/src/services/module-loading/server-module-transpiler.service.test.ts +115 -0
- package/src/services/module-loading/server-module-transpiler.service.ts +105 -0
- package/src/services/runtime-manifest/node-runtime-manifest.service.test.ts +95 -0
- package/src/services/runtime-manifest/node-runtime-manifest.service.ts +101 -0
- package/src/services/runtime-state/dev-graph.service.ts +217 -0
- package/src/services/runtime-state/entrypoint-dependency-graph.service.ts +136 -0
- package/src/services/runtime-state/runtime-specifier-registry.service.ts +96 -0
- package/src/services/runtime-state/server-invalidation-state.service.ts +68 -0
- package/src/services/validation/schema-validation-service.test.ts +223 -0
- package/src/services/{schema-validation-service.ts → validation/schema-validation-service.ts} +1 -1
- package/src/static-site-generator/README.md +26 -0
- package/src/static-site-generator/static-site-generator.test.ts +307 -0
- package/src/static-site-generator/static-site-generator.ts +109 -6
- package/src/utils/deep-merge.test.ts +114 -0
- package/src/utils/invariant.test.ts +22 -0
- package/src/utils/path-utils.test.ts +15 -0
- package/src/utils/resolve-work-dir.ts +45 -0
- package/src/utils/server-utils.test.ts +38 -0
- package/src/watchers/project-watcher.integration.test.ts +337 -0
- package/src/watchers/project-watcher.test-helpers.ts +1 -1
- package/src/watchers/project-watcher.test.ts +678 -0
- package/src/watchers/project-watcher.ts +130 -111
- package/CHANGELOG.md +0 -91
- package/src/adapters/abstract/application-adapter.d.ts +0 -168
- package/src/adapters/abstract/application-adapter.js +0 -109
- package/src/adapters/abstract/router-adapter.d.ts +0 -26
- package/src/adapters/abstract/router-adapter.js +0 -5
- package/src/adapters/abstract/server-adapter.d.ts +0 -69
- package/src/adapters/abstract/server-adapter.js +0 -15
- package/src/adapters/bun/client-bridge.d.ts +0 -34
- package/src/adapters/bun/client-bridge.js +0 -48
- package/src/adapters/bun/create-app.d.ts +0 -60
- package/src/adapters/bun/create-app.js +0 -117
- package/src/adapters/bun/define-api-handler.d.ts +0 -61
- package/src/adapters/bun/define-api-handler.js +0 -15
- package/src/adapters/bun/define-api-handler.ts +0 -114
- package/src/adapters/bun/hmr-manager.d.ts +0 -85
- package/src/adapters/bun/hmr-manager.js +0 -240
- package/src/adapters/bun/index.d.ts +0 -3
- package/src/adapters/bun/index.js +0 -8
- package/src/adapters/bun/server-adapter.d.ts +0 -155
- package/src/adapters/bun/server-adapter.js +0 -368
- package/src/adapters/bun/server-lifecycle.d.ts +0 -52
- package/src/adapters/bun/server-lifecycle.js +0 -120
- package/src/adapters/index.d.ts +0 -6
- package/src/adapters/index.js +0 -14
- package/src/adapters/node/create-app.d.ts +0 -21
- package/src/adapters/node/create-app.js +0 -143
- package/src/adapters/node/index.d.ts +0 -4
- package/src/adapters/node/index.js +0 -8
- package/src/adapters/node/node-client-bridge.d.ts +0 -26
- package/src/adapters/node/node-client-bridge.js +0 -66
- package/src/adapters/node/node-hmr-manager.d.ts +0 -63
- package/src/adapters/node/node-hmr-manager.js +0 -237
- package/src/adapters/node/server-adapter.d.ts +0 -190
- package/src/adapters/node/server-adapter.js +0 -420
- package/src/adapters/node/static-content-server.d.ts +0 -24
- package/src/adapters/node/static-content-server.js +0 -166
- package/src/adapters/shared/api-response.d.ts +0 -52
- package/src/adapters/shared/api-response.js +0 -96
- package/src/adapters/shared/application-adapter.d.ts +0 -18
- package/src/adapters/shared/application-adapter.js +0 -90
- package/src/adapters/shared/explicit-static-route-matcher.d.ts +0 -38
- package/src/adapters/shared/explicit-static-route-matcher.js +0 -100
- package/src/adapters/shared/file-route-middleware-pipeline.d.ts +0 -65
- package/src/adapters/shared/file-route-middleware-pipeline.js +0 -98
- package/src/adapters/shared/fs-server-response-factory.d.ts +0 -19
- package/src/adapters/shared/fs-server-response-factory.js +0 -97
- package/src/adapters/shared/fs-server-response-matcher.d.ts +0 -71
- package/src/adapters/shared/fs-server-response-matcher.js +0 -155
- package/src/adapters/shared/render-context.d.ts +0 -14
- package/src/adapters/shared/render-context.js +0 -69
- package/src/adapters/shared/server-adapter.d.ts +0 -87
- package/src/adapters/shared/server-adapter.js +0 -353
- package/src/adapters/shared/server-route-handler.d.ts +0 -89
- package/src/adapters/shared/server-route-handler.js +0 -120
- package/src/adapters/shared/server-static-builder.d.ts +0 -38
- package/src/adapters/shared/server-static-builder.js +0 -46
- package/src/build/build-adapter.d.ts +0 -74
- package/src/build/build-adapter.js +0 -54
- package/src/build/build-types.d.ts +0 -57
- package/src/build/build-types.js +0 -0
- package/src/build/esbuild-build-adapter.d.ts +0 -69
- package/src/build/esbuild-build-adapter.js +0 -390
- package/src/config/config-builder.d.ts +0 -227
- package/src/config/config-builder.js +0 -392
- package/src/constants.d.ts +0 -32
- package/src/constants.js +0 -21
- package/src/create-app.d.ts +0 -17
- package/src/create-app.js +0 -66
- package/src/define-api-handler.d.ts +0 -25
- package/src/define-api-handler.js +0 -15
- package/src/dev/sc-server.d.ts +0 -30
- package/src/dev/sc-server.js +0 -111
- package/src/eco/component-render-context.d.ts +0 -105
- package/src/eco/component-render-context.js +0 -77
- package/src/eco/eco.d.ts +0 -9
- package/src/eco/eco.js +0 -110
- package/src/eco/eco.types.d.ts +0 -170
- package/src/eco/eco.types.js +0 -0
- package/src/eco/eco.utils.d.ts +0 -40
- package/src/eco/eco.utils.js +0 -40
- package/src/eco/global-injector-map.d.ts +0 -16
- package/src/eco/global-injector-map.js +0 -80
- package/src/eco/lazy-injector-map.d.ts +0 -8
- package/src/eco/lazy-injector-map.js +0 -70
- package/src/eco/module-dependencies.d.ts +0 -18
- package/src/eco/module-dependencies.js +0 -49
- package/src/errors/http-error.d.ts +0 -31
- package/src/errors/http-error.js +0 -50
- package/src/errors/index.d.ts +0 -2
- package/src/errors/index.js +0 -4
- package/src/errors/locals-access-error.d.ts +0 -4
- package/src/errors/locals-access-error.js +0 -9
- package/src/global/app-logger.d.ts +0 -2
- package/src/global/app-logger.js +0 -6
- package/src/hmr/client/hmr-runtime.d.ts +0 -10
- package/src/hmr/client/hmr-runtime.js +0 -86
- package/src/hmr/hmr-strategy.d.ts +0 -159
- package/src/hmr/hmr-strategy.js +0 -29
- package/src/hmr/hmr.test.e2e.d.ts +0 -1
- package/src/hmr/hmr.test.e2e.js +0 -50
- package/src/hmr/strategies/default-hmr-strategy.d.ts +0 -43
- package/src/hmr/strategies/default-hmr-strategy.js +0 -34
- package/src/hmr/strategies/js-hmr-strategy.d.ts +0 -136
- package/src/hmr/strategies/js-hmr-strategy.js +0 -188
- package/src/index.browser.d.ts +0 -3
- package/src/index.browser.js +0 -4
- package/src/index.d.ts +0 -5
- package/src/index.js +0 -10
- package/src/integrations/ghtml/ghtml-renderer.d.ts +0 -15
- package/src/integrations/ghtml/ghtml-renderer.js +0 -60
- package/src/integrations/ghtml/ghtml.plugin.d.ts +0 -20
- package/src/integrations/ghtml/ghtml.plugin.js +0 -21
- package/src/internal-types.d.ts +0 -200
- package/src/internal-types.js +0 -0
- package/src/plugins/alias-resolver-plugin.d.ts +0 -2
- package/src/plugins/alias-resolver-plugin.js +0 -39
- package/src/plugins/eco-component-meta-plugin.d.ts +0 -95
- package/src/plugins/eco-component-meta-plugin.js +0 -157
- package/src/plugins/integration-plugin.d.ts +0 -102
- package/src/plugins/integration-plugin.js +0 -100
- package/src/plugins/processor.d.ts +0 -82
- package/src/plugins/processor.js +0 -122
- package/src/public-types.d.ts +0 -1098
- package/src/public-types.js +0 -0
- package/src/route-renderer/component-graph-executor.d.ts +0 -32
- package/src/route-renderer/component-graph-executor.js +0 -31
- package/src/route-renderer/component-graph.d.ts +0 -42
- package/src/route-renderer/component-graph.js +0 -72
- package/src/route-renderer/component-marker.d.ts +0 -52
- package/src/route-renderer/component-marker.js +0 -46
- package/src/route-renderer/dependency-resolver.d.ts +0 -24
- package/src/route-renderer/dependency-resolver.js +0 -428
- package/src/route-renderer/html-post-processing.service.d.ts +0 -40
- package/src/route-renderer/html-post-processing.service.js +0 -86
- package/src/route-renderer/html-post-processing.service.ts +0 -103
- package/src/route-renderer/integration-renderer.d.ts +0 -339
- package/src/route-renderer/integration-renderer.js +0 -526
- package/src/route-renderer/marker-graph-resolver.d.ts +0 -76
- package/src/route-renderer/marker-graph-resolver.js +0 -93
- package/src/route-renderer/page-module-loader.d.ts +0 -61
- package/src/route-renderer/page-module-loader.js +0 -102
- package/src/route-renderer/render-execution.service.d.ts +0 -69
- package/src/route-renderer/render-execution.service.js +0 -91
- package/src/route-renderer/render-preparation.service.d.ts +0 -112
- package/src/route-renderer/render-preparation.service.js +0 -243
- package/src/route-renderer/route-renderer.d.ts +0 -26
- package/src/route-renderer/route-renderer.js +0 -68
- package/src/router/fs-router-scanner.d.ts +0 -41
- package/src/router/fs-router-scanner.js +0 -155
- package/src/router/fs-router.d.ts +0 -26
- package/src/router/fs-router.js +0 -100
- package/src/services/asset-processing-service/asset-processing.service.d.ts +0 -41
- package/src/services/asset-processing-service/asset-processing.service.js +0 -250
- package/src/services/asset-processing-service/asset.factory.d.ts +0 -17
- package/src/services/asset-processing-service/asset.factory.js +0 -82
- package/src/services/asset-processing-service/assets.types.d.ts +0 -88
- package/src/services/asset-processing-service/assets.types.js +0 -0
- package/src/services/asset-processing-service/index.d.ts +0 -3
- package/src/services/asset-processing-service/index.js +0 -3
- package/src/services/asset-processing-service/processor.interface.d.ts +0 -22
- package/src/services/asset-processing-service/processor.interface.js +0 -6
- package/src/services/asset-processing-service/processor.registry.d.ts +0 -8
- package/src/services/asset-processing-service/processor.registry.js +0 -15
- package/src/services/asset-processing-service/processors/base/base-processor.d.ts +0 -24
- package/src/services/asset-processing-service/processors/base/base-processor.js +0 -59
- package/src/services/asset-processing-service/processors/base/base-script-processor.d.ts +0 -16
- package/src/services/asset-processing-service/processors/base/base-script-processor.js +0 -80
- package/src/services/asset-processing-service/processors/index.d.ts +0 -5
- package/src/services/asset-processing-service/processors/index.js +0 -5
- package/src/services/asset-processing-service/processors/script/content-script.processor.d.ts +0 -5
- package/src/services/asset-processing-service/processors/script/content-script.processor.js +0 -57
- package/src/services/asset-processing-service/processors/script/file-script.processor.d.ts +0 -8
- package/src/services/asset-processing-service/processors/script/file-script.processor.js +0 -76
- package/src/services/asset-processing-service/processors/script/node-module-script.processor.d.ts +0 -7
- package/src/services/asset-processing-service/processors/script/node-module-script.processor.js +0 -74
- package/src/services/asset-processing-service/processors/stylesheet/content-stylesheet.processor.d.ts +0 -5
- package/src/services/asset-processing-service/processors/stylesheet/content-stylesheet.processor.js +0 -25
- package/src/services/asset-processing-service/processors/stylesheet/file-stylesheet.processor.d.ts +0 -9
- package/src/services/asset-processing-service/processors/stylesheet/file-stylesheet.processor.js +0 -63
- package/src/services/cache/cache.types.d.ts +0 -107
- package/src/services/cache/cache.types.js +0 -0
- package/src/services/cache/index.d.ts +0 -7
- package/src/services/cache/index.js +0 -7
- package/src/services/cache/memory-cache-store.d.ts +0 -42
- package/src/services/cache/memory-cache-store.js +0 -98
- package/src/services/cache/page-cache-service.d.ts +0 -70
- package/src/services/cache/page-cache-service.js +0 -152
- package/src/services/html-transformer.service.d.ts +0 -50
- package/src/services/html-transformer.service.js +0 -163
- package/src/services/html-transformer.service.ts +0 -217
- package/src/services/page-module-import.service.d.ts +0 -37
- package/src/services/page-module-import.service.js +0 -88
- package/src/services/page-module-import.service.ts +0 -129
- package/src/services/page-request-cache-coordinator.service.d.ts +0 -75
- package/src/services/page-request-cache-coordinator.service.js +0 -107
- package/src/services/schema-validation-service.d.ts +0 -122
- package/src/services/schema-validation-service.js +0 -101
- package/src/services/validation/standard-schema.types.d.ts +0 -65
- package/src/services/validation/standard-schema.types.js +0 -0
- package/src/static-site-generator/static-site-generator.d.ts +0 -57
- package/src/static-site-generator/static-site-generator.js +0 -272
- package/src/utils/css.d.ts +0 -1
- package/src/utils/css.js +0 -7
- package/src/utils/deep-merge.d.ts +0 -14
- package/src/utils/deep-merge.js +0 -32
- package/src/utils/hash.d.ts +0 -1
- package/src/utils/hash.js +0 -7
- package/src/utils/html.d.ts +0 -1
- package/src/utils/html.js +0 -4
- package/src/utils/invariant.d.ts +0 -5
- package/src/utils/invariant.js +0 -11
- package/src/utils/locals-utils.d.ts +0 -15
- package/src/utils/locals-utils.js +0 -24
- package/src/utils/parse-cli-args.d.ts +0 -24
- package/src/utils/parse-cli-args.js +0 -47
- package/src/utils/path-utils.module.d.ts +0 -5
- package/src/utils/path-utils.module.js +0 -14
- package/src/utils/runtime.d.ts +0 -11
- package/src/utils/runtime.js +0 -40
- package/src/utils/server-utils.module.d.ts +0 -19
- package/src/utils/server-utils.module.js +0 -56
- package/src/watchers/project-watcher.d.ts +0 -125
- package/src/watchers/project-watcher.js +0 -265
- package/src/watchers/project-watcher.test-helpers.d.ts +0 -4
- package/src/watchers/project-watcher.test-helpers.js +0 -52
- /package/src/route-renderer/{component-graph-executor.ts → component-graph/component-graph-executor.ts} +0 -0
- /package/src/route-renderer/{component-graph.ts → component-graph/component-graph.ts} +0 -0
- /package/src/route-renderer/{component-marker.ts → component-graph/component-marker.ts} +0 -0
- /package/src/services/{asset-processing-service → assets/asset-processing-service}/processor.registry.ts +0 -0
- /package/src/services/{asset-processing-service → assets/asset-processing-service}/processors/index.ts +0 -0
- /package/src/services/{asset-processing-service → assets/asset-processing-service}/processors/script/content-script.processor.ts +0 -0
- /package/src/services/{asset-processing-service → assets/asset-processing-service}/processors/stylesheet/content-stylesheet.processor.ts +0 -0
|
@@ -3,30 +3,58 @@ import type { IntegrationPlugin } from '../plugins/integration-plugin.ts';
|
|
|
3
3
|
import type { RouteRenderResult, RouteRendererOptions } from '../public-types.ts';
|
|
4
4
|
import { invariant } from '../utils/invariant.ts';
|
|
5
5
|
import { PathUtils } from '../utils/path-utils.module.ts';
|
|
6
|
-
import type { IntegrationRenderer } from './integration-renderer.ts';
|
|
6
|
+
import type { IntegrationRenderer } from './orchestration/integration-renderer.ts';
|
|
7
7
|
|
|
8
|
+
/**
|
|
9
|
+
* Thin wrapper around one initialized integration renderer.
|
|
10
|
+
*
|
|
11
|
+
* @remarks
|
|
12
|
+
* This type exists so higher-level routing code can ask for a route renderer
|
|
13
|
+
* without depending on the full integration plugin lifecycle. It delegates all
|
|
14
|
+
* real work to the integration-specific renderer selected by the factory.
|
|
15
|
+
*/
|
|
8
16
|
export class RouteRenderer {
|
|
9
17
|
private renderer: IntegrationRenderer;
|
|
10
18
|
|
|
19
|
+
/**
|
|
20
|
+
* Creates a route renderer bound to one integration renderer instance.
|
|
21
|
+
*/
|
|
11
22
|
constructor(renderer: IntegrationRenderer) {
|
|
12
23
|
this.renderer = renderer;
|
|
13
24
|
}
|
|
14
25
|
|
|
26
|
+
/**
|
|
27
|
+
* Executes the render pipeline for one matched route.
|
|
28
|
+
*/
|
|
15
29
|
async createRoute(options: RouteRendererOptions): Promise<RouteRenderResult> {
|
|
16
30
|
return this.renderer.execute(options);
|
|
17
31
|
}
|
|
18
32
|
}
|
|
19
33
|
|
|
34
|
+
/**
|
|
35
|
+
* Selects and caches integration renderers for route files and explicit views.
|
|
36
|
+
*
|
|
37
|
+
* @remarks
|
|
38
|
+
* The factory owns the policy that maps a route file or explicit integration
|
|
39
|
+
* name to one initialized integration renderer. Renderer instances are cached by
|
|
40
|
+
* integration name so repeated requests do not rebuild renderer state.
|
|
41
|
+
*/
|
|
20
42
|
export class RouteRendererFactory {
|
|
21
43
|
private appConfig: EcoPagesAppConfig;
|
|
22
44
|
runtimeOrigin: string;
|
|
23
45
|
private rendererCache = new Map<string, IntegrationRenderer>();
|
|
24
46
|
|
|
47
|
+
/**
|
|
48
|
+
* Creates the route-renderer factory for one app/runtime instance.
|
|
49
|
+
*/
|
|
25
50
|
constructor({ appConfig, runtimeOrigin }: { appConfig: EcoPagesAppConfig; runtimeOrigin: string }) {
|
|
26
51
|
this.appConfig = appConfig;
|
|
27
52
|
this.runtimeOrigin = runtimeOrigin;
|
|
28
53
|
}
|
|
29
54
|
|
|
55
|
+
/**
|
|
56
|
+
* Returns a route renderer for the supplied route file.
|
|
57
|
+
*/
|
|
30
58
|
createRenderer(filePath: string): RouteRenderer {
|
|
31
59
|
const integrationRenderer = this.getRouteRendererEngine(filePath);
|
|
32
60
|
invariant(!!integrationRenderer, `No integration renderer found for file: ${filePath}`);
|
|
@@ -53,6 +81,9 @@ export class RouteRendererFactory {
|
|
|
53
81
|
return renderer;
|
|
54
82
|
}
|
|
55
83
|
|
|
84
|
+
/**
|
|
85
|
+
* Resolves the integration plugin that owns a given route file.
|
|
86
|
+
*/
|
|
56
87
|
getIntegrationPlugin(filePath: string): IntegrationPlugin {
|
|
57
88
|
const templateExtension = PathUtils.getEcoTemplateExtension(filePath);
|
|
58
89
|
const isIntegrationPlugin = (plugin: IntegrationPlugin): boolean => {
|
|
@@ -66,6 +97,10 @@ export class RouteRendererFactory {
|
|
|
66
97
|
return integrationPlugin as IntegrationPlugin;
|
|
67
98
|
}
|
|
68
99
|
|
|
100
|
+
/**
|
|
101
|
+
* Returns the cached renderer engine for the file's owning integration,
|
|
102
|
+
* creating it on first use.
|
|
103
|
+
*/
|
|
69
104
|
private getRouteRendererEngine(filePath: string): IntegrationRenderer {
|
|
70
105
|
const integrationPlugin = this.getIntegrationPlugin(filePath);
|
|
71
106
|
const cached = this.rendererCache.get(integrationPlugin.name);
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# Router Layer
|
|
2
|
+
|
|
3
|
+
This directory contains route discovery, matching, and browser-side navigation infrastructure.
|
|
4
|
+
|
|
5
|
+
## Purpose
|
|
6
|
+
|
|
7
|
+
The router layer determines what route is being handled and how the client runtime coordinates navigation.
|
|
8
|
+
|
|
9
|
+
It is responsible for:
|
|
10
|
+
|
|
11
|
+
- filesystem route scanning and matching
|
|
12
|
+
- explicit-route support and response matching
|
|
13
|
+
- client-side navigation coordination and ownership handoff
|
|
14
|
+
- keeping route discovery separate from rendering execution
|
|
15
|
+
|
|
16
|
+
## Main Areas
|
|
17
|
+
|
|
18
|
+
- server-side route discovery and matchers used by adapters
|
|
19
|
+
- `client/`: shared browser-side navigation coordination
|
|
20
|
+
|
|
21
|
+
## Relationship To Rendering
|
|
22
|
+
|
|
23
|
+
The router layer answers which route should run.
|
|
24
|
+
The route-renderer layer answers how that route gets rendered.
|
|
25
|
+
|
|
26
|
+
Keeping those seams separate avoids mixing route ownership, module loading, and component orchestration into one service.
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared client-side navigation intent helpers.
|
|
3
|
+
*
|
|
4
|
+
* Browser runtimes use the same low-level mechanics to:
|
|
5
|
+
* - locate the anchor associated with a click, pointer, or hover event,
|
|
6
|
+
* - persist the last valid pointer or hover target while a navigation is in flight,
|
|
7
|
+
* - recover the final intended href when the DOM changes before the click lands.
|
|
8
|
+
*
|
|
9
|
+
* Keeping those mechanics here lets browser-router and react-router share one
|
|
10
|
+
* implementation while preserving their router-specific interception rules.
|
|
11
|
+
*
|
|
12
|
+
* @module
|
|
13
|
+
*/
|
|
14
|
+
/**
|
|
15
|
+
* Timestamped navigation intent captured from pointer or hover activity.
|
|
16
|
+
*/
|
|
17
|
+
export type EcoPendingNavigationIntent = {
|
|
18
|
+
href: string;
|
|
19
|
+
timestamp: number;
|
|
20
|
+
};
|
|
21
|
+
/**
|
|
22
|
+
* Finds the nearest matching anchor within an event's composed path.
|
|
23
|
+
*
|
|
24
|
+
* This works across Shadow DOM boundaries, which is required for delegated
|
|
25
|
+
* navigation handling when links are rendered inside custom elements.
|
|
26
|
+
*
|
|
27
|
+
* @param event - Pointer or mouse event being inspected.
|
|
28
|
+
* @param linkSelector - Selector that identifies navigable anchors.
|
|
29
|
+
* @returns The matched anchor element, or `null` when no matching anchor exists.
|
|
30
|
+
*/
|
|
31
|
+
export declare function getAnchorFromNavigationEvent(
|
|
32
|
+
event: MouseEvent | PointerEvent,
|
|
33
|
+
linkSelector: string,
|
|
34
|
+
): HTMLAnchorElement | null;
|
|
35
|
+
/**
|
|
36
|
+
* Resolves a previously captured intent while a navigation is still in flight.
|
|
37
|
+
*
|
|
38
|
+
* Pending intents expire quickly because they are only meant to bridge the gap
|
|
39
|
+
* between pointer or hover capture and the later click event when the DOM or
|
|
40
|
+
* active runtime changes during a rapid navigation sequence.
|
|
41
|
+
*
|
|
42
|
+
* @param intent - Previously captured pointer or hover intent.
|
|
43
|
+
* @param hasInFlightNavigation - Whether a router navigation is still active.
|
|
44
|
+
* @param now - Current monotonic timestamp, usually from `performance.now()`.
|
|
45
|
+
* @param maxAgeMs - Maximum allowed age for the recovered intent.
|
|
46
|
+
* @returns The intended href when still valid, otherwise `null`.
|
|
47
|
+
*/
|
|
48
|
+
export declare function recoverPendingNavigationHref(
|
|
49
|
+
intent: EcoPendingNavigationIntent | null,
|
|
50
|
+
hasInFlightNavigation: boolean,
|
|
51
|
+
now: number,
|
|
52
|
+
maxAgeMs?: number,
|
|
53
|
+
): string | null;
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { describe, expect, it } from 'vitest';
|
|
2
|
+
import { getAnchorFromNavigationEvent, recoverPendingNavigationHref } from './link-intent.ts';
|
|
3
|
+
|
|
4
|
+
describe('getAnchorFromNavigationEvent', () => {
|
|
5
|
+
it('returns the anchor when the event target is a text node inside it', () => {
|
|
6
|
+
const anchor = document.createElement('a');
|
|
7
|
+
anchor.href = '/fast';
|
|
8
|
+
anchor.setAttribute('data-eco-link', 'true');
|
|
9
|
+
const textNode = document.createTextNode('fast-link');
|
|
10
|
+
anchor.append(textNode);
|
|
11
|
+
document.body.append(anchor);
|
|
12
|
+
|
|
13
|
+
const event = new MouseEvent('click', { bubbles: true, cancelable: true, composed: true });
|
|
14
|
+
Object.defineProperty(event, 'target', {
|
|
15
|
+
configurable: true,
|
|
16
|
+
value: textNode,
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
expect(getAnchorFromNavigationEvent(event, 'a[data-eco-link]')).toBe(anchor);
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
it('returns the closest matching anchor for nested element targets', () => {
|
|
23
|
+
const anchor = document.createElement('a');
|
|
24
|
+
anchor.href = '/fast';
|
|
25
|
+
anchor.setAttribute('data-eco-link', 'true');
|
|
26
|
+
const span = document.createElement('span');
|
|
27
|
+
span.textContent = 'fast-link';
|
|
28
|
+
anchor.append(span);
|
|
29
|
+
document.body.append(anchor);
|
|
30
|
+
|
|
31
|
+
const event = new MouseEvent('click', { bubbles: true, cancelable: true, composed: true });
|
|
32
|
+
Object.defineProperty(event, 'target', {
|
|
33
|
+
configurable: true,
|
|
34
|
+
value: span,
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
expect(getAnchorFromNavigationEvent(event, 'a[data-eco-link]')).toBe(anchor);
|
|
38
|
+
});
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
describe('recoverPendingNavigationHref', () => {
|
|
42
|
+
it('returns null for stale or missing pending intent state', () => {
|
|
43
|
+
expect(recoverPendingNavigationHref(null, true, 10)).toBeNull();
|
|
44
|
+
expect(recoverPendingNavigationHref({ href: '/fast', timestamp: 0 }, false, 10)).toBeNull();
|
|
45
|
+
expect(recoverPendingNavigationHref({ href: '/fast', timestamp: 0 }, true, 2000, 1000)).toBeNull();
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
it('returns the captured href while a navigation is still in flight', () => {
|
|
49
|
+
expect(recoverPendingNavigationHref({ href: '/fast', timestamp: 10 }, true, 20, 1000)).toBe('/fast');
|
|
50
|
+
});
|
|
51
|
+
});
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared client-side navigation intent helpers.
|
|
3
|
+
*
|
|
4
|
+
* Browser runtimes use the same low-level mechanics to:
|
|
5
|
+
* - locate the anchor associated with a click, pointer, or hover event,
|
|
6
|
+
* - persist the last valid pointer or hover target while a navigation is in flight,
|
|
7
|
+
* - recover the final intended href when the DOM changes before the click lands.
|
|
8
|
+
*
|
|
9
|
+
* Keeping those mechanics here lets browser-router and react-router share one
|
|
10
|
+
* implementation while preserving their router-specific interception rules.
|
|
11
|
+
*
|
|
12
|
+
* @module
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Timestamped navigation intent captured from pointer or hover activity.
|
|
17
|
+
*/
|
|
18
|
+
export type EcoPendingNavigationIntent = {
|
|
19
|
+
href: string;
|
|
20
|
+
timestamp: number;
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Finds the nearest matching anchor within an event's composed path.
|
|
25
|
+
*
|
|
26
|
+
* This works across Shadow DOM boundaries, which is required for delegated
|
|
27
|
+
* navigation handling when links are rendered inside custom elements.
|
|
28
|
+
*
|
|
29
|
+
* @param event - Pointer or mouse event being inspected.
|
|
30
|
+
* @param linkSelector - Selector that identifies navigable anchors.
|
|
31
|
+
* @returns The matched anchor element, or `null` when no matching anchor exists.
|
|
32
|
+
*/
|
|
33
|
+
export function getAnchorFromNavigationEvent(
|
|
34
|
+
event: MouseEvent | PointerEvent,
|
|
35
|
+
linkSelector: string,
|
|
36
|
+
): HTMLAnchorElement | null {
|
|
37
|
+
const eventTarget = event.target;
|
|
38
|
+
|
|
39
|
+
if (eventTarget instanceof HTMLAnchorElement && eventTarget.matches(linkSelector)) {
|
|
40
|
+
return eventTarget;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
if (eventTarget instanceof Element) {
|
|
44
|
+
const closestAnchor = eventTarget.closest(linkSelector);
|
|
45
|
+
if (closestAnchor instanceof HTMLAnchorElement) {
|
|
46
|
+
return closestAnchor;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
if (eventTarget instanceof Text) {
|
|
51
|
+
const parentAnchor = eventTarget.parentElement?.closest(linkSelector);
|
|
52
|
+
if (parentAnchor instanceof HTMLAnchorElement) {
|
|
53
|
+
return parentAnchor;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
return event
|
|
58
|
+
.composedPath()
|
|
59
|
+
.find(
|
|
60
|
+
(target) => target instanceof HTMLAnchorElement && target.matches(linkSelector),
|
|
61
|
+
) as HTMLAnchorElement | null;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Resolves a previously captured intent while a navigation is still in flight.
|
|
66
|
+
*
|
|
67
|
+
* Pending intents expire quickly because they are only meant to bridge the gap
|
|
68
|
+
* between pointer or hover capture and the later click event when the DOM or
|
|
69
|
+
* active runtime changes during a rapid navigation sequence.
|
|
70
|
+
*
|
|
71
|
+
* @param intent - Previously captured pointer or hover intent.
|
|
72
|
+
* @param hasInFlightNavigation - Whether a router navigation is still active.
|
|
73
|
+
* @param now - Current monotonic timestamp, usually from `performance.now()`.
|
|
74
|
+
* @param maxAgeMs - Maximum allowed age for the recovered intent.
|
|
75
|
+
* @returns The intended href when still valid, otherwise `null`.
|
|
76
|
+
*/
|
|
77
|
+
export function recoverPendingNavigationHref(
|
|
78
|
+
intent: EcoPendingNavigationIntent | null,
|
|
79
|
+
hasInFlightNavigation: boolean,
|
|
80
|
+
now: number,
|
|
81
|
+
maxAgeMs = 1000,
|
|
82
|
+
): string | null {
|
|
83
|
+
if (!intent || !hasInFlightNavigation) {
|
|
84
|
+
return null;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
if (now - intent.timestamp > maxAgeMs) {
|
|
88
|
+
return null;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
return intent.href;
|
|
92
|
+
}
|
|
@@ -0,0 +1,237 @@
|
|
|
1
|
+
import { describe, expect, it, vi } from 'vitest';
|
|
2
|
+
import { getEcoNavigationRuntime } from './navigation-coordinator.ts';
|
|
3
|
+
|
|
4
|
+
function createWindowLike() {
|
|
5
|
+
return {} as Window &
|
|
6
|
+
typeof globalThis & {
|
|
7
|
+
__ECO_PAGES__?: { navigation?: ReturnType<typeof getEcoNavigationRuntime> };
|
|
8
|
+
};
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
describe('getEcoNavigationRuntime', () => {
|
|
12
|
+
it('returns the same coordinator instance for the same window', () => {
|
|
13
|
+
const windowLike = createWindowLike();
|
|
14
|
+
const first = getEcoNavigationRuntime(windowLike);
|
|
15
|
+
const second = getEcoNavigationRuntime(windowLike);
|
|
16
|
+
|
|
17
|
+
expect(first).toBe(second);
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
it('tracks explicit ownership claims', () => {
|
|
21
|
+
const windowLike = createWindowLike();
|
|
22
|
+
const runtime = getEcoNavigationRuntime(windowLike);
|
|
23
|
+
|
|
24
|
+
runtime.claimOwnership('react-router');
|
|
25
|
+
|
|
26
|
+
expect(runtime.getOwnerState()).toEqual({
|
|
27
|
+
owner: 'react-router',
|
|
28
|
+
canHandleSpaNavigation: false,
|
|
29
|
+
});
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
it('shares one navigation transaction sequence across runtimes', () => {
|
|
33
|
+
const windowLike = createWindowLike();
|
|
34
|
+
const runtime = getEcoNavigationRuntime(windowLike);
|
|
35
|
+
|
|
36
|
+
const first = runtime.beginNavigationTransaction();
|
|
37
|
+
expect(runtime.hasPendingNavigationTransaction()).toBe(true);
|
|
38
|
+
expect(first.isCurrent()).toBe(true);
|
|
39
|
+
expect(first.signal.aborted).toBe(false);
|
|
40
|
+
|
|
41
|
+
const second = runtime.beginNavigationTransaction();
|
|
42
|
+
|
|
43
|
+
expect(first.isCurrent()).toBe(false);
|
|
44
|
+
expect(first.signal.aborted).toBe(true);
|
|
45
|
+
expect(second.isCurrent()).toBe(true);
|
|
46
|
+
expect(second.signal.aborted).toBe(false);
|
|
47
|
+
second.complete();
|
|
48
|
+
expect(runtime.hasPendingNavigationTransaction()).toBe(false);
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
it('cancels only the current navigation transaction', () => {
|
|
52
|
+
const windowLike = createWindowLike();
|
|
53
|
+
const runtime = getEcoNavigationRuntime(windowLike);
|
|
54
|
+
|
|
55
|
+
const first = runtime.beginNavigationTransaction();
|
|
56
|
+
const second = runtime.beginNavigationTransaction();
|
|
57
|
+
|
|
58
|
+
first.cancel();
|
|
59
|
+
expect(second.isCurrent()).toBe(true);
|
|
60
|
+
expect(second.signal.aborted).toBe(false);
|
|
61
|
+
|
|
62
|
+
second.cancel();
|
|
63
|
+
expect(second.isCurrent()).toBe(false);
|
|
64
|
+
expect(second.signal.aborted).toBe(true);
|
|
65
|
+
expect(runtime.hasPendingNavigationTransaction()).toBe(false);
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
it('adopts ownership from the rendered document marker', () => {
|
|
69
|
+
const windowLike = createWindowLike();
|
|
70
|
+
const runtime = getEcoNavigationRuntime(windowLike);
|
|
71
|
+
const documentLike = {
|
|
72
|
+
documentElement: {
|
|
73
|
+
getAttribute: vi.fn(() => 'custom-router'),
|
|
74
|
+
},
|
|
75
|
+
} as unknown as Document;
|
|
76
|
+
|
|
77
|
+
expect(runtime.adoptDocumentOwner(documentLike, 'browser-router')).toBe('custom-router');
|
|
78
|
+
expect(runtime.getOwnerState().owner).toBe('custom-router');
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
it('delegates navigation to another registered runtime when the source cannot handle it', async () => {
|
|
82
|
+
const windowLike = createWindowLike();
|
|
83
|
+
const runtime = getEcoNavigationRuntime(windowLike);
|
|
84
|
+
const navigateSpy = vi.fn(async () => true);
|
|
85
|
+
|
|
86
|
+
runtime.register({ owner: 'browser-router', navigate: navigateSpy });
|
|
87
|
+
runtime.register({ owner: 'react-router', navigate: vi.fn(async () => true) });
|
|
88
|
+
runtime.claimOwnership('react-router');
|
|
89
|
+
|
|
90
|
+
const handled = await runtime.requestNavigation({
|
|
91
|
+
href: '/docs',
|
|
92
|
+
direction: 'forward',
|
|
93
|
+
source: 'react-router',
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
expect(handled).toBe(true);
|
|
97
|
+
expect(navigateSpy).toHaveBeenCalledWith({
|
|
98
|
+
href: '/docs',
|
|
99
|
+
direction: 'forward',
|
|
100
|
+
source: 'react-router',
|
|
101
|
+
});
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
it('delegates a fetched document handoff to the targeted runtime without forcing source cleanup first', async () => {
|
|
105
|
+
const windowLike = createWindowLike();
|
|
106
|
+
const runtime = getEcoNavigationRuntime(windowLike);
|
|
107
|
+
const cleanupSpy = vi.fn(async () => undefined);
|
|
108
|
+
const handoffSpy = vi.fn(async () => true);
|
|
109
|
+
const documentLike = {
|
|
110
|
+
documentElement: {
|
|
111
|
+
getAttribute: vi.fn(() => null),
|
|
112
|
+
},
|
|
113
|
+
} as unknown as Document;
|
|
114
|
+
|
|
115
|
+
runtime.register({ owner: 'react-router', cleanupBeforeHandoff: cleanupSpy });
|
|
116
|
+
runtime.register({ owner: 'browser-router', handoffNavigation: handoffSpy });
|
|
117
|
+
runtime.claimOwnership('react-router');
|
|
118
|
+
|
|
119
|
+
const handled = await runtime.requestHandoff({
|
|
120
|
+
href: '/docs',
|
|
121
|
+
finalHref: '/docs',
|
|
122
|
+
direction: 'forward',
|
|
123
|
+
source: 'react-router',
|
|
124
|
+
targetOwner: 'browser-router',
|
|
125
|
+
document: documentLike,
|
|
126
|
+
});
|
|
127
|
+
|
|
128
|
+
expect(handled).toBe(true);
|
|
129
|
+
expect(cleanupSpy).not.toHaveBeenCalled();
|
|
130
|
+
expect(handoffSpy).toHaveBeenCalledWith({
|
|
131
|
+
href: '/docs',
|
|
132
|
+
finalHref: '/docs',
|
|
133
|
+
direction: 'forward',
|
|
134
|
+
source: 'react-router',
|
|
135
|
+
targetOwner: 'browser-router',
|
|
136
|
+
document: documentLike,
|
|
137
|
+
});
|
|
138
|
+
});
|
|
139
|
+
|
|
140
|
+
it('ignores stale handoff requests before cleaning up the active owner', async () => {
|
|
141
|
+
const windowLike = createWindowLike();
|
|
142
|
+
const runtime = getEcoNavigationRuntime(windowLike);
|
|
143
|
+
const cleanupSpy = vi.fn(async () => undefined);
|
|
144
|
+
const handoffSpy = vi.fn(async () => true);
|
|
145
|
+
const documentLike = {
|
|
146
|
+
documentElement: {
|
|
147
|
+
getAttribute: vi.fn(() => null),
|
|
148
|
+
},
|
|
149
|
+
} as unknown as Document;
|
|
150
|
+
|
|
151
|
+
runtime.register({ owner: 'react-router', cleanupBeforeHandoff: cleanupSpy });
|
|
152
|
+
runtime.register({ owner: 'browser-router', handoffNavigation: handoffSpy });
|
|
153
|
+
runtime.claimOwnership('react-router');
|
|
154
|
+
|
|
155
|
+
const handled = await runtime.requestHandoff({
|
|
156
|
+
href: '/docs',
|
|
157
|
+
finalHref: '/docs',
|
|
158
|
+
direction: 'forward',
|
|
159
|
+
source: 'react-router',
|
|
160
|
+
targetOwner: 'browser-router',
|
|
161
|
+
document: documentLike,
|
|
162
|
+
isStaleSourceNavigation: () => true,
|
|
163
|
+
});
|
|
164
|
+
|
|
165
|
+
expect(handled).toBe(true);
|
|
166
|
+
expect(cleanupSpy).not.toHaveBeenCalled();
|
|
167
|
+
expect(handoffSpy).not.toHaveBeenCalled();
|
|
168
|
+
expect(runtime.getOwnerState().owner).toBe('react-router');
|
|
169
|
+
});
|
|
170
|
+
|
|
171
|
+
it('reloads the current owner through its registration', async () => {
|
|
172
|
+
const windowLike = createWindowLike();
|
|
173
|
+
const runtime = getEcoNavigationRuntime(windowLike);
|
|
174
|
+
const reloadSpy = vi.fn(async () => undefined);
|
|
175
|
+
|
|
176
|
+
runtime.register({ owner: 'react-router', reloadCurrentPage: reloadSpy });
|
|
177
|
+
runtime.claimOwnership('react-router');
|
|
178
|
+
|
|
179
|
+
const handled = await runtime.reloadCurrentPage({ clearCache: true, source: 'browser-router' });
|
|
180
|
+
|
|
181
|
+
expect(handled).toBe(true);
|
|
182
|
+
expect(reloadSpy).toHaveBeenCalledWith({ clearCache: true, source: 'browser-router' });
|
|
183
|
+
});
|
|
184
|
+
|
|
185
|
+
it('reloads the current owner even when the request source matches that owner', async () => {
|
|
186
|
+
const windowLike = createWindowLike();
|
|
187
|
+
const runtime = getEcoNavigationRuntime(windowLike);
|
|
188
|
+
const reloadSpy = vi.fn(async () => undefined);
|
|
189
|
+
|
|
190
|
+
runtime.register({ owner: 'react-router', reloadCurrentPage: reloadSpy });
|
|
191
|
+
runtime.claimOwnership('react-router');
|
|
192
|
+
|
|
193
|
+
const handled = await runtime.reloadCurrentPage({ clearCache: false, source: 'react-router' });
|
|
194
|
+
|
|
195
|
+
expect(handled).toBe(true);
|
|
196
|
+
expect(reloadSpy).toHaveBeenCalledWith({ clearCache: false, source: 'react-router' });
|
|
197
|
+
});
|
|
198
|
+
|
|
199
|
+
it('cleans up an explicit owner via its registration', async () => {
|
|
200
|
+
const windowLike = createWindowLike();
|
|
201
|
+
const runtime = getEcoNavigationRuntime(windowLike);
|
|
202
|
+
const cleanupSpy = vi.fn();
|
|
203
|
+
|
|
204
|
+
runtime.register({ owner: 'react-router', cleanupBeforeHandoff: cleanupSpy });
|
|
205
|
+
runtime.claimOwnership('react-router');
|
|
206
|
+
|
|
207
|
+
await runtime.cleanupOwner('react-router');
|
|
208
|
+
|
|
209
|
+
expect(cleanupSpy).toHaveBeenCalledTimes(1);
|
|
210
|
+
expect(runtime.getOwnerState().owner).toBe('none');
|
|
211
|
+
});
|
|
212
|
+
|
|
213
|
+
it('emits events for registrations and ownership changes', () => {
|
|
214
|
+
const windowLike = createWindowLike();
|
|
215
|
+
const runtime = getEcoNavigationRuntime(windowLike);
|
|
216
|
+
const listener = vi.fn();
|
|
217
|
+
const unsubscribe = runtime.subscribe(listener);
|
|
218
|
+
|
|
219
|
+
const unregister = runtime.register({ owner: 'custom-router' });
|
|
220
|
+
runtime.claimOwnership('custom-router');
|
|
221
|
+
runtime.releaseOwnership('custom-router');
|
|
222
|
+
unregister();
|
|
223
|
+
unsubscribe();
|
|
224
|
+
|
|
225
|
+
expect(listener).toHaveBeenCalledWith({
|
|
226
|
+
type: 'registration-change',
|
|
227
|
+
owner: 'custom-router',
|
|
228
|
+
status: 'registered',
|
|
229
|
+
});
|
|
230
|
+
expect(listener).toHaveBeenCalledWith({
|
|
231
|
+
type: 'owner-change',
|
|
232
|
+
owner: 'custom-router',
|
|
233
|
+
previousOwner: 'none',
|
|
234
|
+
reason: 'claim',
|
|
235
|
+
});
|
|
236
|
+
});
|
|
237
|
+
});
|